123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- package service
- import (
- "context"
- "fmt"
- "github.com/go-nunu/nunu-layout-advanced/internal/model"
- "github.com/go-nunu/nunu-layout-advanced/internal/repository"
- "strconv"
- "strings"
- )
- type GameShieldSdkIpService interface {
- GetGameShieldSdkIp(ctx context.Context, id int64) (*model.GameShieldSdkIp, error)
- GenerateMultipleLoopbackIps(ctx context.Context, uid int, hostId int, count ...int) error
- }
- func NewGameShieldSdkIpService(
- service *Service,
- gameShieldSdkIpRepository repository.GameShieldSdkIpRepository,
- ) GameShieldSdkIpService {
- return &gameShieldSdkIpService{
- Service: service,
- gameShieldSdkIpRepository: gameShieldSdkIpRepository,
- }
- }
- type gameShieldSdkIpService struct {
- *Service
- gameShieldSdkIpRepository repository.GameShieldSdkIpRepository
- }
- func (s *gameShieldSdkIpService) GetGameShieldSdkIp(ctx context.Context, id int64) (*model.GameShieldSdkIp, error) {
- return s.gameShieldSdkIpRepository.GetGameShieldSdkIp(ctx, id)
- }
- // GenerateMultipleLoopbackIps 生成多个唯一127.0.0.0/8范围IP地址
- // count 指定需要生成的IP地址数量,默认为10
- // 返回生成的唯一IP地址数组和可能的错误
- // GenerateMultipleLoopbackIps 生成并保存多个唯一127.0.0.0/8范围IP地址到数据库
- // uid 用户ID
- // hostId 实例ID
- // count 指定需要生成的IP地址数量,默认为10
- // 返回生成并保存的唯一IP地址数组和可能的错误
- func (s *gameShieldSdkIpService) GenerateMultipleLoopbackIps(ctx context.Context, uid int, hostId int, count ...int) error {
- requiredCount := 10
- if len(count) > 0 && count[0] > 0 {
- requiredCount = count[0]
- }
- haveCount, err := s.gameShieldSdkIpRepository.GetGameShieldSdkIpCountByHostId(ctx, hostId)
- if err != nil {
- return err
- }
- if int(haveCount) >= requiredCount {
- return nil
- }
- // 从数据库获取最新的一条IP记录
- latestIp, err := s.gameShieldSdkIpRepository.GetGameShieldSdkIpNewByHostId(ctx, hostId)
- if err != nil {
- // 如果没有记录,默认从127.0.0.2开始(避免使用127.0.0.1)
- latestIp = "127.0.0.1"
- }
- // 解析IP成四个段
- ipParts := strings.Split(latestIp, ".")
- if len(ipParts) != 4 {
- return fmt.Errorf("无效的IP格式: %s", latestIp)
- }
- // 将IP段转换为整数
- a, err1 := strconv.Atoi(ipParts[0])
- b, err2 := strconv.Atoi(ipParts[1])
- c, err3 := strconv.Atoi(ipParts[2])
- d, err4 := strconv.Atoi(ipParts[3])
- if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
- return fmt.Errorf("IP段转换失败: %s", latestIp)
- }
- // 确保第一段是127(保持在回环地址范围内)
- if a != 127 {
- a = 127
- b, c, d = 0, 0, 1 // 重置为127.0.0.1
- }
- // 从最新IP的下一个地址开始
- d++
- if d > 254 {
- d = 0
- c++
- if c > 255 {
- c = 0
- b++
- if b > 255 {
- return fmt.Errorf("IP地址池已耗尽")
- }
- }
- }
- // 收集生成的唯一IP
- result := make([]string, 0, requiredCount)
- attempts := 0
- maxAttempts := 10000 // 防止无限循环
- for len(result) < requiredCount && attempts < maxAttempts {
- currentIp := fmt.Sprintf("127.%d.%d.%d", b, c, d)
- // 尝试将IP保存到数据库
- err := s.gameShieldSdkIpRepository.AddGameShieldSdkIp(ctx, &model.GameShieldSdkIp{
- HostId: hostId,
- Uid: uid,
- SdkIp: currentIp,
- })
- if err == nil {
- // 保存成功,添加到结果列表
- result = append(result, currentIp)
- } else {
- // 如果是因为IP已存在导致的错误,我们忽略并继续
- // 其他错误则返回
- if !strings.Contains(err.Error(), "unique_sdk_ip") {
- return fmt.Errorf("保存IP到数据库失败: %w", err)
- }
- // IP已存在,继续尝试下一个
- }
- // 递增IP地址
- d++
- if d > 255 {
- d = 0
- c++
- if c > 255 {
- c = 0
- b++
- if b > 255 {
- break
- }
- }
- }
- attempts++
- }
- if len(result) < requiredCount {
- return fmt.Errorf("无法生成足够的唯一IP地址,地址池可能已耗尽,仅生成了%d个", len(result))
- }
- return nil
- }
|