gameshieldsdkip.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/go-nunu/nunu-layout-advanced/internal/model"
  6. "github.com/go-nunu/nunu-layout-advanced/internal/repository"
  7. "strconv"
  8. "strings"
  9. )
  10. type GameShieldSdkIpService interface {
  11. GetGameShieldSdkIp(ctx context.Context, id int64) (*model.GameShieldSdkIp, error)
  12. GenerateMultipleLoopbackIps(ctx context.Context, uid int, hostId int, count ...int) error
  13. }
  14. func NewGameShieldSdkIpService(
  15. service *Service,
  16. gameShieldSdkIpRepository repository.GameShieldSdkIpRepository,
  17. ) GameShieldSdkIpService {
  18. return &gameShieldSdkIpService{
  19. Service: service,
  20. gameShieldSdkIpRepository: gameShieldSdkIpRepository,
  21. }
  22. }
  23. type gameShieldSdkIpService struct {
  24. *Service
  25. gameShieldSdkIpRepository repository.GameShieldSdkIpRepository
  26. }
  27. func (s *gameShieldSdkIpService) GetGameShieldSdkIp(ctx context.Context, id int64) (*model.GameShieldSdkIp, error) {
  28. return s.gameShieldSdkIpRepository.GetGameShieldSdkIp(ctx, id)
  29. }
  30. // GenerateMultipleLoopbackIps 生成多个唯一127.0.0.0/8范围IP地址
  31. // count 指定需要生成的IP地址数量,默认为10
  32. // 返回生成的唯一IP地址数组和可能的错误
  33. // GenerateMultipleLoopbackIps 生成并保存多个唯一127.0.0.0/8范围IP地址到数据库
  34. // uid 用户ID
  35. // hostId 实例ID
  36. // count 指定需要生成的IP地址数量,默认为10
  37. // 返回生成并保存的唯一IP地址数组和可能的错误
  38. func (s *gameShieldSdkIpService) GenerateMultipleLoopbackIps(ctx context.Context, uid int, hostId int, count ...int) error {
  39. requiredCount := 10
  40. if len(count) > 0 && count[0] > 0 {
  41. requiredCount = count[0]
  42. }
  43. haveCount, err := s.gameShieldSdkIpRepository.GetGameShieldSdkIpCountByHostId(ctx, hostId)
  44. if err != nil {
  45. return err
  46. }
  47. if int(haveCount) >= requiredCount {
  48. return nil
  49. }
  50. // 从数据库获取最新的一条IP记录
  51. latestIp, err := s.gameShieldSdkIpRepository.GetGameShieldSdkIpNewByHostId(ctx, hostId)
  52. if err != nil {
  53. // 如果没有记录,默认从127.0.0.2开始(避免使用127.0.0.1)
  54. latestIp = "127.0.0.1"
  55. }
  56. // 解析IP成四个段
  57. ipParts := strings.Split(latestIp, ".")
  58. if len(ipParts) != 4 {
  59. return fmt.Errorf("无效的IP格式: %s", latestIp)
  60. }
  61. // 将IP段转换为整数
  62. a, err1 := strconv.Atoi(ipParts[0])
  63. b, err2 := strconv.Atoi(ipParts[1])
  64. c, err3 := strconv.Atoi(ipParts[2])
  65. d, err4 := strconv.Atoi(ipParts[3])
  66. if err1 != nil || err2 != nil || err3 != nil || err4 != nil {
  67. return fmt.Errorf("IP段转换失败: %s", latestIp)
  68. }
  69. // 确保第一段是127(保持在回环地址范围内)
  70. if a != 127 {
  71. a = 127
  72. b, c, d = 0, 0, 1 // 重置为127.0.0.1
  73. }
  74. // 从最新IP的下一个地址开始
  75. d++
  76. if d > 255 {
  77. d = 0
  78. c++
  79. if c > 255 {
  80. c = 0
  81. b++
  82. if b > 255 {
  83. return fmt.Errorf("IP地址池已耗尽")
  84. }
  85. }
  86. }
  87. // 收集生成的唯一IP
  88. result := make([]string, 0, requiredCount)
  89. attempts := 0
  90. maxAttempts := 10000 // 防止无限循环
  91. for len(result) < requiredCount && attempts < maxAttempts {
  92. currentIp := fmt.Sprintf("127.%d.%d.%d", b, c, d)
  93. // 尝试将IP保存到数据库
  94. err := s.gameShieldSdkIpRepository.AddGameShieldSdkIp(ctx, &model.GameShieldSdkIp{
  95. HostId: hostId,
  96. Uid: uid,
  97. SdkIp: currentIp,
  98. })
  99. if err == nil {
  100. // 保存成功,添加到结果列表
  101. result = append(result, currentIp)
  102. } else {
  103. // 如果是因为IP已存在导致的错误,我们忽略并继续
  104. // 其他错误则返回
  105. if !strings.Contains(err.Error(), "unique_sdk_ip") {
  106. return fmt.Errorf("保存IP到数据库失败: %w", err)
  107. }
  108. // IP已存在,继续尝试下一个
  109. }
  110. // 递增IP地址
  111. d++
  112. if d > 255 {
  113. d = 0
  114. c++
  115. if c > 255 {
  116. c = 0
  117. b++
  118. if b > 255 {
  119. break
  120. }
  121. }
  122. }
  123. attempts++
  124. }
  125. if len(result) < requiredCount {
  126. return fmt.Errorf("无法生成足够的唯一IP地址,地址池可能已耗尽,仅生成了%d个", len(result))
  127. }
  128. return nil
  129. }