This commit is contained in:
@@ -1,92 +1,56 @@
|
|||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import "blazing/logic/service/common"
|
||||||
"blazing/cool"
|
|
||||||
"blazing/logic/service/common"
|
|
||||||
"blazing/modules/player/model"
|
|
||||||
"context"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"hash/crc32"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MAIN_LOGIN_IN 定义请求或响应数据结构。
|
type Login struct {
|
||||||
type MAIN_LOGIN_IN struct {
|
|
||||||
Head common.TomeeHeader `cmd:"1001" struc:"skip"`
|
Head common.TomeeHeader `cmd:"1001" struc:"skip"`
|
||||||
Sid []byte `struc:"[16]byte"`
|
Sid []byte `struc:"[16]byte"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheakSession 处理控制器请求。
|
type HeartBeat struct {
|
||||||
func (l *MAIN_LOGIN_IN) CheakSession() (bool, uint32) {
|
|
||||||
t1 := hex.EncodeToString(l.Sid)
|
|
||||||
r, err := cool.CacheManager.Get(context.Background(), fmt.Sprintf("session:%d", l.Head.UserID))
|
|
||||||
if err != nil {
|
|
||||||
return false, 0
|
|
||||||
}
|
|
||||||
if r.String() != t1 {
|
|
||||||
return false, 0
|
|
||||||
}
|
|
||||||
crc32Table := crc32.MakeTable(crc32.IEEE)
|
|
||||||
crcValue := crc32.Checksum([]byte(l.Sid), crc32Table)
|
|
||||||
cool.CacheManager.Remove(context.Background(), fmt.Sprintf("session:%d", l.Head.UserID))
|
|
||||||
return true, crcValue
|
|
||||||
}
|
|
||||||
|
|
||||||
// SimUserInfoInboundInfo 定义请求或响应数据结构。
|
|
||||||
type SimUserInfoInboundInfo struct {
|
|
||||||
Head common.TomeeHeader `cmd:"2051" struc:"skip"`
|
Head common.TomeeHeader `cmd:"2051" struc:"skip"`
|
||||||
UserId uint32 `fieldDescription:"米米号" uint:"true" codec:"true"`
|
Time uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// MoreUserInfoInboundInfo 定义请求或响应数据结构。
|
type KeepAlive struct {
|
||||||
type MoreUserInfoInboundInfo struct {
|
|
||||||
Head common.TomeeHeader `cmd:"2052" struc:"skip"`
|
Head common.TomeeHeader `cmd:"2052" struc:"skip"`
|
||||||
UserId uint32 `fieldDescription:"米米号" uint:"true" codec:"true"`
|
Time uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// AimatInboundInfo 定义请求或响应数据结构。
|
type UserInfo struct {
|
||||||
type AimatInboundInfo struct {
|
|
||||||
Head common.TomeeHeader `cmd:"2104" struc:"skip"`
|
Head common.TomeeHeader `cmd:"2104" struc:"skip"`
|
||||||
ItemId uint32 `description:"物品id 射击激光 物品id为0" codec:"auto" uint:"true"`
|
UserID uint32
|
||||||
ShootType uint32 `description:"射击类型 未知 给0" codec:"auto" uint:"true"`
|
ShowNono uint8
|
||||||
Point model.Pos `description:"射击的坐标 x y" codec:"auto"`
|
RoomStyle uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChatInboundInfo 定义请求或响应数据结构。
|
type UserTalk struct {
|
||||||
type ChatInboundInfo struct {
|
|
||||||
Head common.TomeeHeader `cmd:"2102" struc:"skip"`
|
Head common.TomeeHeader `cmd:"2102" struc:"skip"`
|
||||||
Reserve uint32 `json:"reserve" fieldDescription:"填充 默认值为0" uint:"true"`
|
ReceiverID uint32
|
||||||
MessageLen uint32 `struc:"sizeof=Message"`
|
MessageLen uint32 `struc:"sizeof=Message"`
|
||||||
Message string `json:"message" fieldDescription:"消息内容, 结束符为utf-8的数字0"`
|
Message []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangeColorInboundInfo 定义请求或响应数据结构。
|
type ChangeTitle struct {
|
||||||
type ChangeColorInboundInfo struct {
|
|
||||||
Head common.TomeeHeader `cmd:"2063" struc:"skip"`
|
Head common.TomeeHeader `cmd:"2063" struc:"skip"`
|
||||||
Color uint32 `codec:"color"`
|
Title uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangeDoodleInboundInfo 定义请求或响应数据结构。
|
type ChangePlayerIcon struct {
|
||||||
type ChangeDoodleInboundInfo struct {
|
|
||||||
Head common.TomeeHeader `cmd:"2062" struc:"skip"`
|
Head common.TomeeHeader `cmd:"2062" struc:"skip"`
|
||||||
Id uint32 `codec:"id"`
|
Icon uint32
|
||||||
Color uint32 `codec:"color"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChangeNONOColorInboundInfo 定义请求或响应数据结构。
|
type GetMotto struct {
|
||||||
type ChangeNONOColorInboundInfo struct {
|
|
||||||
Head common.TomeeHeader `cmd:"9012" struc:"skip"`
|
Head common.TomeeHeader `cmd:"9012" struc:"skip"`
|
||||||
Color uint32 `codec:"color"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// C2SDanceAction 定义请求或响应数据结构。
|
type GetTask struct {
|
||||||
type C2SDanceAction struct {
|
|
||||||
Head common.TomeeHeader `cmd:"2103" struc:"skip"`
|
Head common.TomeeHeader `cmd:"2103" struc:"skip"`
|
||||||
Reserve uint32 `struc:"uint32,big"`
|
TaskLen uint32 `struc:"sizeof=TaskList"`
|
||||||
Type uint32 `struc:"uint32,big"`
|
TaskList []uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// C2SPEOPLE_TRANSFROM 定义请求或响应数据结构。
|
|
||||||
type C2SPEOPLE_TRANSFROM struct {
|
type C2SPEOPLE_TRANSFROM struct {
|
||||||
Head common.TomeeHeader `cmd:"2111" struc:"skip"`
|
Head common.TomeeHeader `cmd:"2111" struc:"skip"`
|
||||||
SuitID uint32 `struc:"uint32,big"`
|
SuitID uint32 `struc:"uint32,big"`
|
||||||
@@ -108,4 +72,11 @@ type ChangeTitleInboundInfo struct {
|
|||||||
type C2S_GET_GIFT_COMPLETE struct {
|
type C2S_GET_GIFT_COMPLETE struct {
|
||||||
Head common.TomeeHeader `cmd:"2801" struc:"skip"`
|
Head common.TomeeHeader `cmd:"2801" struc:"skip"`
|
||||||
PassText string `struc:"[16]byte"`
|
PassText string `struc:"[16]byte"`
|
||||||
|
Type uint32
|
||||||
|
ServerID uint32
|
||||||
|
ServerName string `struc:"[16]byte"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type C2S_GET_DONATION_SERVER_IDS struct {
|
||||||
|
Head common.TomeeHeader `cmd:"2802" struc:"skip"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,21 +2,31 @@ package controller
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"blazing/common/socket/errorcode"
|
"blazing/common/socket/errorcode"
|
||||||
|
"blazing/cool"
|
||||||
logicplayer "blazing/logic/service/player"
|
logicplayer "blazing/logic/service/player"
|
||||||
"blazing/logic/service/user"
|
"blazing/logic/service/user"
|
||||||
configservice "blazing/modules/config/service"
|
configservice "blazing/modules/config/service"
|
||||||
playerservice "blazing/modules/player/service"
|
playerservice "blazing/modules/player/service"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DonationServerIDs 返回当前可用于捐赠冠名的服务器ID列表。
|
||||||
|
func (h Controller) DonationServerIDs(data *C2S_GET_DONATION_SERVER_IDS, player *logicplayer.Player) (result *user.S2C_GET_DONATION_SERVER_IDS, err errorcode.ErrorCode) {
|
||||||
|
return &user.S2C_GET_DONATION_SERVER_IDS{
|
||||||
|
ServerIDs: configservice.NewServerService().GetDonationAvailableServerIDs(),
|
||||||
|
}, 0
|
||||||
|
}
|
||||||
|
|
||||||
// CDK 处理控制器请求。
|
// CDK 处理控制器请求。
|
||||||
func (h Controller) CDK(data *C2S_GET_GIFT_COMPLETE, player *logicplayer.Player) (result *user.S2C_GET_GIFT_COMPLETE, err errorcode.ErrorCode) {
|
func (h Controller) CDK(data *C2S_GET_GIFT_COMPLETE, player *logicplayer.Player) (result *user.S2C_GET_GIFT_COMPLETE, err errorcode.ErrorCode) {
|
||||||
result = &user.S2C_GET_GIFT_COMPLETE{}
|
result = &user.S2C_GET_GIFT_COMPLETE{Type: data.Type}
|
||||||
|
|
||||||
|
cdkCode := strings.Trim(data.PassText, "\x00")
|
||||||
cdkService := configservice.NewCdkService()
|
cdkService := configservice.NewCdkService()
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
||||||
r := cdkService.Get(data.PassText)
|
r := cdkService.Get(cdkCode)
|
||||||
if r == nil {
|
if r == nil {
|
||||||
return nil, errorcode.ErrorCodes.ErrMolecularCodeNotExists
|
return nil, errorcode.ErrorCodes.ErrMolecularCodeNotExists
|
||||||
}
|
}
|
||||||
@@ -29,7 +39,33 @@ func (h Controller) CDK(data *C2S_GET_GIFT_COMPLETE, player *logicplayer.Player)
|
|||||||
if !player.Service.Cdk.CanGet(uint32(r.ID)) {
|
if !player.Service.Cdk.CanGet(uint32(r.ID)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !cdkService.Set(data.PassText) {
|
|
||||||
|
if r.CDKType == configservice.CDKTypeServerNaming {
|
||||||
|
if data.Type != configservice.CDKTypeServerNaming {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrSystemError
|
||||||
|
}
|
||||||
|
|
||||||
|
serverName := cool.Filter.Replace(strings.Trim(data.ServerName, "\x00"), '*')
|
||||||
|
if data.ServerID == 0 || serverName == "" {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrSystemError
|
||||||
|
}
|
||||||
|
|
||||||
|
serverInfo, useErr := cdkService.UseServerNamingCDK(nil, cdkCode, data.Head.UserID, data.ServerID, serverName)
|
||||||
|
if useErr != nil {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrSystemError
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Flag = 1
|
||||||
|
result.ServerID = serverInfo.OnlineID
|
||||||
|
result.ServerName = serverInfo.Name
|
||||||
|
player.Service.Cdk.Log(uint32(r.ID))
|
||||||
|
return result, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.Type == configservice.CDKTypeServerNaming {
|
||||||
|
return nil, errorcode.ErrorCodes.ErrSystemError
|
||||||
|
}
|
||||||
|
if !cdkService.Set(cdkCode) {
|
||||||
return nil, errorcode.ErrorCodes.ErrMolecularCodeGiftsGone
|
return nil, errorcode.ErrorCodes.ErrMolecularCodeGiftsGone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,24 +7,36 @@ import "blazing/logic/service/common"
|
|||||||
type C2S_GET_GIFT_COMPLETE struct {
|
type C2S_GET_GIFT_COMPLETE struct {
|
||||||
Head common.TomeeHeader `cmd:"2801" struc:"skip"`
|
Head common.TomeeHeader `cmd:"2801" struc:"skip"`
|
||||||
PassText string `struc:"[16]byte"`
|
PassText string `struc:"[16]byte"`
|
||||||
|
Type uint32
|
||||||
|
ServerID uint32
|
||||||
|
ServerName string `struc:"[16]byte"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// S2C_GET_GIFT_COMPLETE 礼品兑换完成协议
|
// S2C_GET_GIFT_COMPLETE 礼品兑换完成协议
|
||||||
// 后端到前端
|
// 后端到前端
|
||||||
type S2C_GET_GIFT_COMPLETE struct {
|
type S2C_GET_GIFT_COMPLETE struct {
|
||||||
Flag uint32 `json:"flag"` // 0 代表sdk已被使用 1 表示兑换成功 如果返回0 那么后续数组不需要返回
|
Flag uint32 `json:"flag"`
|
||||||
|
Type uint32 `json:"type"`
|
||||||
Tile uint32 `json:"tile"`
|
Tile uint32 `json:"tile"`
|
||||||
|
ServerID uint32 `json:"server_id"`
|
||||||
|
ServerName string `struc:"[16]byte" json:"server_name"`
|
||||||
GiftListLen uint32 `struc:"sizeof=GiftList"`
|
GiftListLen uint32 `struc:"sizeof=GiftList"`
|
||||||
GiftList []GiftInfo `json:"giftList"` // 物品id数组
|
GiftList []GiftInfo `json:"giftList"`
|
||||||
PetGiftLen uint32 `struc:"sizeof=PetGift"`
|
PetGiftLen uint32 `struc:"sizeof=PetGift"`
|
||||||
PetGift []PetGiftInfo `json:"petGiftList"`
|
PetGift []PetGiftInfo `json:"petGiftList"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type S2C_GET_DONATION_SERVER_IDS struct {
|
||||||
|
ServerIDsLen uint32 `struc:"sizeof=ServerIDs" json:"server_ids_len"`
|
||||||
|
ServerIDs []uint32 `json:"server_ids"`
|
||||||
|
}
|
||||||
|
|
||||||
// GiftInfo 礼品信息
|
// GiftInfo 礼品信息
|
||||||
type GiftInfo struct {
|
type GiftInfo struct {
|
||||||
GiftID int64 `struc:"uint32"`
|
GiftID int64 `struc:"uint32"`
|
||||||
Count int64 `struc:"uint32"`
|
Count int64 `struc:"uint32"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PetGiftInfo struct {
|
type PetGiftInfo struct {
|
||||||
PetID uint32 `json:"petID"`
|
PetID uint32 `json:"petID"`
|
||||||
CacthTime uint32 `json:"catchTime"`
|
CacthTime uint32 `json:"catchTime"`
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ type CDKConfig struct {
|
|||||||
|
|
||||||
// 核心字段
|
// 核心字段
|
||||||
CDKCode string `gorm:"not null;size:16;uniqueIndex;comment:'CDK编号(唯一标识,用于玩家兑换)'" json:"cdk_code" description:"CDK编号"`
|
CDKCode string `gorm:"not null;size:16;uniqueIndex;comment:'CDK编号(唯一标识,用于玩家兑换)'" json:"cdk_code" description:"CDK编号"`
|
||||||
|
CDKType uint32 `gorm:"column:type;not null;default:0;comment:'CDK类型:0普通奖励,1服务器冠名'" json:"type" description:"CDK类型"`
|
||||||
|
|
||||||
//cdk可兑换次数,where不等于0
|
//cdk可兑换次数,where不等于0
|
||||||
ExchangeRemainCount int64 `gorm:"not null;default:1;comment:'CDK剩余可兑换次数(不能为0才允许兑换,支持查询where !=0)'" json:"exchange_remain_count" description:"剩余可兑换次数"`
|
ExchangeRemainCount int64 `gorm:"not null;default:1;comment:'CDK剩余可兑换次数(不能为0才允许兑换,支持查询where !=0)'" json:"exchange_remain_count" description:"剩余可兑换次数"`
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/database/gdb"
|
"github.com/gogf/gf/v2/database/gdb"
|
||||||
"github.com/gogf/gf/v2/errors/gerror"
|
"github.com/gogf/gf/v2/errors/gerror"
|
||||||
@@ -17,6 +18,9 @@ import (
|
|||||||
const charsetWithSymbol = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz"
|
const charsetWithSymbol = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
CDKTypeReward uint32 = 0
|
||||||
|
CDKTypeServerNaming uint32 = 1
|
||||||
|
|
||||||
cdkCodeLength = 16
|
cdkCodeLength = 16
|
||||||
maxBatchGenerateCount = 5000
|
maxBatchGenerateCount = 5000
|
||||||
)
|
)
|
||||||
@@ -156,6 +160,74 @@ func (s *CdkService) Set(id string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *CdkService) UseServerNamingCDK(ctx context.Context, code string, ownerID, serverID uint32, serverName string) (*model.ServerList, error) {
|
||||||
|
if ctx == nil {
|
||||||
|
ctx = context.TODO()
|
||||||
|
}
|
||||||
|
now := time.Now()
|
||||||
|
serverService := NewServerService()
|
||||||
|
var updated model.ServerList
|
||||||
|
|
||||||
|
err := g.DB(s.Model.GroupName()).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
|
||||||
|
var cfg model.CDKConfig
|
||||||
|
if err := tx.Model(s.Model).Where("cdk_code", code).WhereNot("exchange_remain_count", 0).Scan(&cfg); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if cfg.ID == 0 {
|
||||||
|
return gerror.New("cdk不存在")
|
||||||
|
}
|
||||||
|
if cfg.CDKType != CDKTypeServerNaming {
|
||||||
|
return gerror.New("cdk类型不匹配")
|
||||||
|
}
|
||||||
|
if cfg.BindUserId != 0 && cfg.BindUserId != ownerID {
|
||||||
|
return gerror.New("cdk已绑定其他用户")
|
||||||
|
}
|
||||||
|
if !cfg.ValidEndTime.IsZero() && cfg.ValidEndTime.Before(now) {
|
||||||
|
return gerror.New("cdk已过期")
|
||||||
|
}
|
||||||
|
|
||||||
|
var server model.ServerList
|
||||||
|
if err := tx.Model(model.NewServerList()).Where("online_id", serverID).Scan(&server); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !serverService.CanUseDonationName(server, now) {
|
||||||
|
return gerror.New("服务器不可冠名")
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := tx.Model(s.Model).Where("cdk_code", code).WhereNot("exchange_remain_count", 0).Decrement("exchange_remain_count", 1)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rows, _ := res.RowsAffected()
|
||||||
|
if rows == 0 {
|
||||||
|
return gerror.New("cdk已被使用")
|
||||||
|
}
|
||||||
|
|
||||||
|
baseTime := now
|
||||||
|
if server.ExpireTime.After(now) {
|
||||||
|
baseTime = server.ExpireTime
|
||||||
|
}
|
||||||
|
updated = server
|
||||||
|
updated.Name = serverName
|
||||||
|
updated.Owner = ownerID
|
||||||
|
updated.ExpireTime = baseTime.AddDate(0, 1, 0)
|
||||||
|
|
||||||
|
_, err = tx.Model(model.NewServerList()).Where("online_id", serverID).Data(g.Map{
|
||||||
|
"name": updated.Name,
|
||||||
|
"owner": updated.Owner,
|
||||||
|
"expire_time": updated.ExpireTime,
|
||||||
|
}).Update()
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
g.DB(s.Model.GroupName()).GetCore().ClearCache(context.TODO(), s.Model.TableName())
|
||||||
|
g.DB(model.NewServerList().GroupName()).GetCore().ClearCache(context.TODO(), model.NewServerList().TableName())
|
||||||
|
return &updated, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *CdkService) BatchGenerate(ctx context.Context, count int) (interface{}, error) {
|
func (s *CdkService) BatchGenerate(ctx context.Context, count int) (interface{}, error) {
|
||||||
if count <= 0 {
|
if count <= 0 {
|
||||||
return nil, gerror.New("生成数量必须大于0")
|
return nil, gerror.New("生成数量必须大于0")
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"blazing/modules/config/model"
|
"blazing/modules/config/model"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gogf/gf/v2/database/gdb"
|
"github.com/gogf/gf/v2/database/gdb"
|
||||||
"github.com/gogf/gf/v2/frame/g"
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
@@ -130,6 +131,35 @@ func (s *ServerService) GetServerID(OnlineID uint32) model.ServerList {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *ServerService) GetDonationAvailableServerIDs() []uint32 {
|
||||||
|
now := time.Now()
|
||||||
|
builder := dbm_nocache_noenable(s.Model).Builder().Where("owner", 0).WhereOr("expire_time <= ?", now)
|
||||||
|
|
||||||
|
var rows []struct {
|
||||||
|
OnlineID uint32 `json:"online_id"`
|
||||||
|
}
|
||||||
|
dbm_nocache_noenable(s.Model).Fields("online_id").Where(builder).OrderAsc("online_id").Scan(&rows)
|
||||||
|
|
||||||
|
ids := make([]uint32, 0, len(rows))
|
||||||
|
for _, row := range rows {
|
||||||
|
if row.OnlineID == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ids = append(ids, row.OnlineID)
|
||||||
|
}
|
||||||
|
return ids
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServerService) CanUseDonationName(server model.ServerList, now time.Time) bool {
|
||||||
|
if server.OnlineID == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if server.Owner == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return !server.ExpireTime.After(now)
|
||||||
|
}
|
||||||
|
|
||||||
// 保存版本号
|
// 保存版本号
|
||||||
func (s *ServerService) SetServerScreen(id uint32, name string) {
|
func (s *ServerService) SetServerScreen(id uint32, name string) {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user