refactor(socket): 优化消息处理逻辑,避免顺序执行问题

将消息处理的循环从协程外部移入协程内部,确保每个消息在独立的 goroutine 中处理,
避免因并发导致的消息顺序错乱问题。同时移除了多余的空行,使代码更简洁。

fix(controller): 为低 ID 用户设置 VIP 标志

在 COMMEND_ONLINE 接口逻辑中,新增对 UserID 小于 10000 的用户设置 IsVip = 1,
用于标识测试或特殊用户身份。

ref
This commit is contained in:
2025-11-03 03:59:59 +08:00
parent 7a8be1c23a
commit 30ed47a30c
17 changed files with 300 additions and 242 deletions

View File

@@ -136,16 +136,13 @@ func (s *Server) OnTraffic(c gnet.Conn) (action gnet.Action) {
return
}
for _, msg := range messages {
t := c.Context().(*player.ClientData)
//client := conn.RemoteAddr().String()
s.workerPool.Submit(func() { //TODO 这里可能存在顺序执行问题,待修复
t := c.Context().(*player.ClientData)
//client := conn.RemoteAddr().String()
s.workerPool.Submit(func() { //TODO 这里可能存在顺序执行问题,待修复
for _, msg := range messages {
t.OnEvent(msg.Payload)
})
}
}
})
return gnet.None
}

View File

@@ -11,7 +11,13 @@ import (
// 处理命令: 105
func (h *Controller) COMMEND_ONLINE(data *user.SidInfo, c gnet.Conn) (result *user.CommendSvrInfo, err errorcode.ErrorCode) { //这个时候player应该是空的
result = user.NewInInfo()
if data.Head.UserID < 100000 {
result.IsVip = 1
}
result.ServerList = user.GetServerInfoList()
return
//return //TODO 这里待实现改成接口调用Ret方法

Binary file not shown.

View File

@@ -4,68 +4,82 @@ import (
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
"math/rand"
)
// -----------------------------------------------------------
// 通用状态效果(例如 麻痹 / 中毒 / 疲惫 / 混乱 等)
// -----------------------------------------------------------
type Effect10 struct {
node.EffectNode
Status info.EnumBattleStatus
Status info.EnumBattleStatus // 要施加的状态类型
FixedDur int // 固定持续回合,为 0 时表示随机
}
func newp(t1 info.EnumBattleStatus) *Effect10 {
t := &Effect10{
Status: t1,
// 工厂函数
func newEffectStatus(status info.EnumBattleStatus) *Effect10 {
return &Effect10{
Status: status,
}
return t
}
func init() {
//n%令对方麻痹
// 批量注册状态类技能
registerStatusEffects()
}
input.InitEffect(input.EffectType.Skill, 10, newp(info.PetStatus.Paralysis))
func registerStatusEffects() {
statusList := map[int]info.EnumBattleStatus{
10: info.PetStatus.Paralysis,
11: info.PetStatus.Poisoned,
12: info.PetStatus.Burned,
14: info.PetStatus.Frozen,
15: info.PetStatus.Fear,
16: info.PetStatus.Sleep,
22: info.PetStatus.Tired,
94: info.PetStatus.Petrified,
99: info.PetStatus.Confused,
114: info.PetStatus.Flammable,
}
// n%令对方中毒
input.InitEffect(input.EffectType.Skill, 11, newp(info.PetStatus.Poisoned))
//n%令对方烧伤
input.InitEffect(input.EffectType.Skill, 12, newp(info.PetStatus.Burned))
//n回合吸取对方最大体力的1/8(草系无效)
//n%令对方冻伤
input.InitEffect(input.EffectType.Skill, 14, newp(info.PetStatus.Frozen))
//n%令对方害怕
input.InitEffect(input.EffectType.Skill, 15, newp(info.PetStatus.Fear))
//n%令对手睡眠
input.InitEffect(input.EffectType.Skill, 16, newp(info.PetStatus.Sleep))
//n%令对方石化
input.InitEffect(input.EffectType.Skill, 94, newp(info.PetStatus.Petrified))
//n%几率令对手混乱
input.InitEffect(input.EffectType.Skill, 99, newp(info.PetStatus.Confused))
//n%几率令对方易燃
input.InitEffect(input.EffectType.Skill, 114, newp(info.PetStatus.Flammable))
for id, status := range statusList {
input.InitEffect(input.EffectType.Skill, id, newEffectStatus(status))
}
}
func (e *Effect10) OnSkill(ctx input.Ctx) bool {
t, _, _ := e.Input.Player.Roll(e.EffectNode.SideEffectArgs[0], 100)
if t {
t1 := e.Input.FightC.GetRand().Int31n(3)
eff := input.Geteffect(input.EffectType.Status, int(e.Status))
if eff.ID() != 0 {
eff.Duration(int(t1))
ctx.AddEffect(eff)
}
// -----------------------------------------------------------
// 技能触发时调用
// -----------------------------------------------------------
func (e *EffectStatus) OnSkill(ctx input.Ctx) bool {
if !e.Hit() {
return true
}
// n% 触发概率(默认 SideEffectArgs[0]
chance := e.EffectNode.SideEffectArgs[0]
success, _, _ := e.Input.Player.Roll(chance, 100)
if !success {
return true
}
var duration int
if len(e.EffectNode.SideEffectArgs) > 1 {
// 持续回合
duration = e.EffectNode.SideEffectArgs[1]
}
// 持续回合
if duration == 0 {
duration = int(rand.Int31n(3) + 1) // 默认随机 1~3 回合
}
// 获取状态效果
eff := input.Geteffect(input.EffectType.Status, int(e.Status))
if eff == nil {
return true
}
eff.Duration(duration)
ctx.AddEffect(eff)
return true
}
func (e *Effect10) OnMiss(opp *input.Input, skill *info.SkillEntity) {
}

View File

@@ -6,52 +6,65 @@ import (
"blazing/logic/service/fight/node"
)
// Effect3能力操作类效果重置/反转/偷取等)
type Effect3 struct {
node.EffectNode
Rev bool
Level int8
Etype info.EnumAbilityOpType
Reverse bool
Level int8
OpType info.EnumAbilityOpType
}
// ----------------------
// 执行时逻辑
// ----------------------
func (e *Effect3) OnSkill(ctx input.Ctx) bool {
if !e.Hit() {
return true
}
for i := 0; i < 6; i++ {
if e.Rev {
ctx.SetProp(e.Input, int8(i), e.Level, e.Etype)
} else {
e.Input.SetProp(ctx.Input, int8(i), e.Level, e.Etype)
}
// 遍历六项能力值(攻击、防御、速度等)
for i := 0; i < 6; i++ {
if e.Reverse {
// 对对手生效
ctx.SetProp(e.Input, int8(i), e.Level, e.OpType)
} else {
// 对自己生效
e.Input.SetProp(ctx.Input, int8(i), e.Level, e.OpType)
}
}
return true
}
func neweffect3(rev bool, level int8, etype info.EnumAbilityOpType) *Effect3 {
ret := &Effect3{
Rev: rev,
Level: level,
Etype: etype,
// ----------------------
// 工厂函数
// ----------------------
func newEffect3(reverse bool, level int8, opType info.EnumAbilityOpType) *Effect3 {
return &Effect3{
Reverse: reverse,
Level: level,
OpType: opType,
}
}
// ----------------------
// 注册所有效果
// ----------------------
func init() {
effects := []struct {
id int
reverse bool
level int8
opType info.EnumAbilityOpType
}{
{3, false, -1, info.AbilityOpType.RESET}, // 解除自身能力下降状态
{33, true, 1, info.AbilityOpType.RESET}, // 消除对手能力提升状态
{63, false, 0, info.AbilityOpType.AbilityOpBounceWeaken}, // 将能力下降反馈给对手
{85, false, -1, info.AbilityOpType.AbilityOpStealStrengthen}, // 将对手提升效果转移到自己
{145, true, 1, info.AbilityOpType.AbilityOpReverse}, // 反转对手能力提升为下降
}
return ret
}
func init() {
//解除能力下降状态
input.InitEffect(input.EffectType.Skill, 3, neweffect3(false, -1, info.AbilityOpType.RESET))
// 消除对手能力提升状态
input.InitEffect(input.EffectType.Skill, 33, neweffect3(true, 1, info.AbilityOpType.RESET))
// 将能力下降状态反馈给对手
input.InitEffect(input.EffectType.Skill, 63, neweffect3(false, 0, info.AbilityOpType.AbilityOpBounceWeaken))
//使对手的能力提升效果转化到自己身上
input.InitEffect(input.EffectType.Skill, 85, neweffect3(false, -1, info.AbilityOpType.AbilityOpStealStrengthen))
// 使对手的能力提升效果反转成能力下降效果
input.InitEffect(input.EffectType.Skill, 145, neweffect3(true, 1, info.AbilityOpType.AbilityOpReverse))
for _, e := range effects {
input.InitEffect(input.EffectType.Skill, e.id, newEffect3(e.reverse, e.level, e.opType))
}
}

View File

@@ -6,57 +6,79 @@ import (
"blazing/logic/service/fight/node"
)
// -----------------------------------------------------------
// 注册
// -----------------------------------------------------------
func init() {
//技能使用成功时m%自身XX等级+/-n
input.InitEffect(input.EffectType.Skill, 4, NewEffectStat(false))
//技能使用成功时m%对方XX等级+/-n
input.InitEffect(input.EffectType.Skill, 5, NewEffectStat(true))
// 自身能力变化
input.InitEffect(input.EffectType.Skill, 4, newEffectStat(false))
// 对方能力变化
input.InitEffect(input.EffectType.Skill, 5, newEffectStat(true))
}
func NewEffectStat(b bool) input.Effect {
ret := &EffectStat{
EffectNode: node.EffectNode{},
Etype: b,
// -----------------------------------------------------------
// 构造
// -----------------------------------------------------------
func newEffectStat(targetOpponent bool) input.Effect {
e := &EffectStat{
Etype: targetOpponent,
}
ret.MaxStack(-1) //无限叠加
return ret
e.MaxStack(-1) // 无限叠加
return e
}
// -----------------------------------------------------------
// 主体结构
// -----------------------------------------------------------
type EffectStat struct {
node.EffectNode
Etype bool
Etype bool // false: 作用自身, true: 作用对方
}
// func (this *EffectStat) GetPet() {
// ff := this.EffectNode.GetOwnerPet()
// offsetC := unsafe.Offsetof(ff.Atk) // c字段的偏移量通常为4+16=20
// // 2. 将结构体指针转换为原始内存地址uintptr
// baseAddr := uintptr(unsafe.Pointer(&offsetC))
// // 3. 计算字段地址并赋值
// // 给a字段赋值通过偏移量
// addrA := unsafe.Pointer(baseAddr + 4) //根据攻击算其他字段
// *(*uint32)(addrA) = 100
// }
// -----------------------------------------------------------
// 技能触发时调用
// -----------------------------------------------------------
func (e *EffectStat) OnSkill(ctx input.Ctx) bool {
if !e.Hit() {
return true
}
t, _, _ := e.Input.Player.Roll(e.SideEffectArgs[1], 100)
if !t { //没触发
// 参数解构 (防止 SideEffectArgs 长度不足)
var (
statIndex int // 哪个属性
chance int // 触发概率
level int // 增减值
)
if len(e.SideEffectArgs) > 0 {
statIndex = e.SideEffectArgs[0]
}
if len(e.SideEffectArgs) > 1 {
chance = e.SideEffectArgs[1]
}
if len(e.SideEffectArgs) > 2 {
level = e.SideEffectArgs[2]
}
// 概率判定
ok, _, _ := e.Input.Player.Roll(chance, 100)
if !ok {
return true
}
ptype := info.AbilityOpType.ADD
if e.EffectNode.SideEffectArgs[2] < 0 {
ptype = info.AbilityOpType.SUB
}
if !e.Etype { //自身
e.Input.SetProp(e.Input, int8(e.SideEffectArgs[0]), int8(e.SideEffectArgs[2]), ptype)
} else { //对方
ctx.SetProp(e.Input, int8(e.SideEffectArgs[0]), int8(e.SideEffectArgs[2]), ptype)
// 判断加减类型
opType := info.AbilityOpType.ADD
if level < 0 {
opType = info.AbilityOpType.SUB
}
// 执行属性变化
if e.Etype {
// 对方属性变化
ctx.SetProp(e.Input, int8(statIndex), int8(level), opType)
} else {
// 自身属性变化
e.Input.SetProp(e.Input, int8(statIndex), int8(level), opType)
}
return true
}

View File

@@ -3,37 +3,55 @@ package effect
import (
"blazing/logic/service/fight/input"
"blazing/logic/service/fight/node"
"math/rand"
)
/**
*威力随机随机范围50~150
*/
type Effect61 struct {
// -----------------------------------------------------------
// 威力随机效果
// -----------------------------------------------------------
// 威力将在 [Min, Max] 区间内随机取值
type EffectRandomPower struct {
node.EffectNode
Min int
Max int
}
// -----------------------------------------------------------
// 初始化注册
// -----------------------------------------------------------
func init() {
input.InitEffect(input.EffectType.Skill, 61, &Effect61{
EffectNode: node.EffectNode{},
Min: 50,
Max: 150,
})
input.InitEffect(input.EffectType.Skill, 70, &Effect61{
EffectNode: node.EffectNode{},
Min: 140,
Max: 220,
})
input.InitEffect(input.EffectType.Skill, 118, &Effect61{
EffectNode: node.EffectNode{},
Min: 140,
Max: 180,
registerRandomPower(61, 50, 150)
registerRandomPower(70, 140, 220)
registerRandomPower(118, 140, 180)
}
// -----------------------------------------------------------
// 工厂函数:注册不同威力范围的技能效果
// -----------------------------------------------------------
func registerRandomPower(effectID, min, max int) {
input.InitEffect(input.EffectType.Skill, effectID, &EffectRandomPower{
Min: min,
Max: max,
})
}
func (e *Effect61) Skill_Hit(ctx input.Ctx) bool {
ctx.SkillEntity.Power = int(e.Input.FightC.GetRand().Int31n(int32(e.Max)-int32(e.Min)+1) + int32(e.Min))
// -----------------------------------------------------------
// 命中时触发
// -----------------------------------------------------------
func (e *EffectRandomPower) Skill_Hit(ctx input.Ctx) bool {
if e.Max <= e.Min {
ctx.SkillEntity.Power = e.Min
return true
}
// 如果 FightC 没提供随机器,使用 math/rand 兜底
var n int
if e.Input != nil && e.Input.FightC != nil {
n = int(e.Input.FightC.GetRand().Int31n(int32(e.Max-e.Min+1))) + e.Min
} else {
n = rand.Intn(e.Max-e.Min+1) + e.Min
}
ctx.SkillEntity.Power = n
return true
}

View File

@@ -6,83 +6,76 @@ import (
"blazing/logic/service/fight/node"
)
func init() {
// ---- 全局函数表自动管理 ----
var statusFuncRegistry = newStatusFuncRegistry()
//对方体力小于1/2时威力加倍
input.InitEffect(input.EffectType.Skill, 2, &Effect96{
EffectNode: node.EffectNode{},
Status: func(i, o *input.Input) bool {
ret := false
if o.CurrentPet.Info.Hp < (o.CurrentPet.Info.MaxHp / 2) {
ret = true
}
return ret
},
})
//后出手的话威力为2倍
input.InitEffect(input.EffectType.Skill, 30, &Effect96{
EffectNode: node.EffectNode{},
Status: func(i, o *input.Input) bool {
return !i.FightC.IsFirst(i.Player)
},
})
//先出手的话威力为2倍
input.InitEffect(input.EffectType.Skill, 40, &Effect96{
EffectNode: node.EffectNode{},
Status: func(i, o *input.Input) bool {
return i.FightC.IsFirst(i.Player)
},
})
//对手处于烧伤状态时,威力翻倍
input.InitEffect(input.EffectType.Skill, 96, &Effect96{
Status: func(i, o *input.Input) bool {
return i.StatEffect_Exist(int(info.PetStatus.Burned))
},
})
//对手处于冻伤状态时,威力翻倍
input.InitEffect(input.EffectType.Skill, 97, &Effect96{
Status: func(i, o *input.Input) bool {
return i.StatEffect_Exist(int(info.PetStatus.Frozen))
},
})
//对手处于麻痹状态时,威力翻倍
input.InitEffect(input.EffectType.Skill, 102, &Effect96{
Status: func(i, o *input.Input) bool {
return i.StatEffect_Exist(int(info.PetStatus.Paralysis))
},
})
//若对手处于睡眠状态,威力翻倍
input.InitEffect(input.EffectType.Skill, 168, &Effect96{
Status: func(i, o *input.Input) bool {
return i.StatEffect_Exist(int(info.PetStatus.Sleep))
},
})
type statusFuncRegistryType struct {
funcs map[int]func(*input.Input, *input.Input) bool
}
func newStatusFuncRegistry() *statusFuncRegistryType {
return &statusFuncRegistryType{funcs: make(map[int]func(*input.Input, *input.Input) bool)}
}
func (r *statusFuncRegistryType) Register(id int, f func(*input.Input, *input.Input) bool) {
r.funcs[id] = f
}
func (r *statusFuncRegistryType) Get(id int) func(*input.Input, *input.Input) bool {
return r.funcs[id]
}
// ---- Effect96 ----
type Effect96 struct {
node.EffectNode
Status func(*input.Input, *input.Input) bool
StatusID int
}
func (e *Effect96) PreSkill(opp *input.Input, skill *info.SkillEntity) {
if e.Status(e.Input, opp) {
if f := statusFuncRegistry.Get(e.StatusID); f != nil && f(e.Input, opp) {
skill.Power *= 2
}
}
// ---- 注册所有效果 ----
func init() {
registerStatusFunc(2, func(i, o *input.Input) bool {
return o.CurrentPet.Info.Hp < (o.CurrentPet.Info.MaxHp / 2)
})
registerStatusFunc(30, func(i, o *input.Input) bool {
return !i.FightC.IsFirst(i.Player)
})
registerStatusFunc(40, func(i, o *input.Input) bool {
return i.FightC.IsFirst(i.Player)
})
registerStatusFunc(64, func(i, o *input.Input) bool {
if i.StatEffect_Exist(int(info.PetStatus.Burned)) {
return true
}
if i.StatEffect_Exist(int(info.PetStatus.Frozen)) {
return true
}
if i.StatEffect_Exist(int(info.PetStatus.Poisoned)) {
return true
}
return false
})
registerStatusFunc(96, func(i, o *input.Input) bool {
return i.StatEffect_Exist(int(info.PetStatus.Burned))
})
registerStatusFunc(97, func(i, o *input.Input) bool {
return i.StatEffect_Exist(int(info.PetStatus.Frozen))
})
registerStatusFunc(102, func(i, o *input.Input) bool {
return i.StatEffect_Exist(int(info.PetStatus.Paralysis))
})
registerStatusFunc(168, func(i, o *input.Input) bool {
return i.StatEffect_Exist(int(info.PetStatus.Sleep))
})
}
// 小助手函数,让注册看起来更自然
func registerStatusFunc(id int, fn func(*input.Input, *input.Input) bool) {
statusFuncRegistry.Register(id, fn)
input.InitEffect(input.EffectType.Skill, id, &Effect96{StatusID: id})
}

View File

@@ -20,20 +20,13 @@ type StatusNotSkill struct {
// 不能出手
func (e *StatusNotSkill) Skill_Hit_Pre(ctx input.Ctx) bool {
if e.EffectStatus.Status == info.PetStatus.Sleep {
// tt := &StatusSleep{}
// tt.SetArgs(e.Input, 0) //睡眠没参数
// tt.ID((- int(info.PetStatus.Sleep))) //添加ID
// ctx.AddEffect(tt)
}
return false
}
type StatusSleep struct { //睡眠不能出手 ,这个挂载到对面来实现对方攻击后解除睡眠效果
node.EffectNode
StatusNotSkill
}
func (e *StatusSleep) Skill_Useed(input.Ctx) bool {

View File

@@ -550,12 +550,12 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
t := f.First.GetEffect(input.EffectType.Status, i)
if len(t) > 0 && t[0].ID() != 0 { //状态都是叠层类的
ret.FAttack.Status[i] = int8(t[0].Duration())
if t != nil { //状态都是叠层类的
ret.FAttack.Status[i] = int8(t.Duration())
}
t = f.Second.GetEffect(input.EffectType.Status, i)
if len(t) > 0 && t[0].ID() != 0 {
ret.SAttack.Status[i] = int8(t[0].Duration())
if t != nil {
ret.SAttack.Status[i] = int8(t.Duration())
}
}

View File

@@ -46,7 +46,7 @@ func (u *Input) UseSkill(opp *Input, skill *action.SelectSkillAction) {
func (u *Input) Heal(ac action.BattleActionI, value decimal.Decimal) {
u.CurrentPet.Info.Hp += uint32(value.IntPart())
u.CurrentPet.Info.Hp = utils.Min(u.CurrentPet.Info.Hp, u.CurrentPet.Info.MaxHp)
}
// 伤害落实 // 血量扣减节点比如触发回神,反弹也在这里实现

View File

@@ -35,7 +35,7 @@ func Geteffect(etype EnumEffectType, id int) Effect {
eff := deep.MustCopy(ret)
return eff.(Effect)
return eff
//todo 获取后GetEffect
}
return nil
@@ -66,10 +66,8 @@ func (c *Input) GetProp(id int, istue bool) int {
return realValue
}
func (c *Input) CountEffect(etype EnumEffectType, id int) int {
return len(c.GetEffect(etype, id))
}
func (c *Input) GetEffect(etype EnumEffectType, id int) []Effect {
func (c *Input) GetEffect(etype EnumEffectType, id int) Effect {
var ret []Effect
for _, v := range c.Effects {
if v.ID() == id {
@@ -77,7 +75,10 @@ func (c *Input) GetEffect(etype EnumEffectType, id int) []Effect {
}
}
return ret
if len(ret) > 0 {
return ret[len(ret)-1]
}
return nil
}
func (c *Input) StatEffect_Exist(id int) bool {
for _, v := range c.Effects {
@@ -106,8 +107,9 @@ func (c *Input) AddEffect(e Effect) {
// 如果已有同 ID 的效果,尝试叠加
for _, v := range c.Effects {
if v.ID() == e.ID() && v.Alive() {
if v.MaxStack() >= 0 {
v.NotALive() //取消之前效果
v.NotALive() //取消之前效果
if v.MaxStack() > 0 {
if v.Stack() < v.MaxStack() { //如果小于最大叠层,状态可以叠层
e.SetArgs(v.GetInput(), v.GetArgs()...) //参数输入
e.Stack(v.Stack() + e.Stack()) //获取到当前叠层数然后叠加

View File

@@ -78,7 +78,7 @@ func (f *FightC) collectPlayerActions(ourID, oppID uint32) map[uint32]action.Bat
}
actions[pid] = paction
fmt.Println("玩家执行动作:", pid, paction.Priority())
//fmt.Println("玩家执行动作:", pid, paction.Priority())
case <-timeout:
f.handleTimeout(ourID, oppID, actions)
@@ -180,10 +180,13 @@ func (f *FightC) handleSkillActions(a1, a2 action.BattleActionI) {
switch {
case s1 == nil || s1.SkillEntity == nil:
f.enterturn(s2, nil)
fmt.Println("1 空过 2玩家执行技能:", s2.PlayerID, s2.Info.ID)
case s2 == nil || s2.SkillEntity == nil:
f.enterturn(s1, nil)
fmt.Println("2 空过 玩家执行技能:", s1.PlayerID, s1.Info.ID)
default:
f.enterturn(s1, s2)
fmt.Println("玩家执行技能:", s1.PlayerID, s1.Info.ID, s2.PlayerID, s2.Info.ID)
}
}

View File

@@ -9,14 +9,11 @@ import (
// 精灵切换相关触发
func (e *EffectNode) OnSwitchIn(ctx input.Ctx) bool {
panic("not implemented") // TODO: Implement
//panic("not implemented") // TODO: Implement
return true
}
func (e *EffectNode) OnSwitchOut(ctx input.Ctx) bool {
//下场默认清除effect
if e.GetInput().UserID == ctx.Player.GetInfo().UserID { //清除对方的我方施加uff
e.NotALive()
}
return true
}

View File

@@ -95,7 +95,6 @@ type SwitchFlyingOutboundInfo struct {
}
type PetCureInboundInfo struct {
Head player.TomeeHeader `cmd:"2306" struc:"[0]pad"`
Type uint32 `description:"开关, 0为取消飞行模式, 大于0为开启飞行模式" codec:"auto" uint:"true"` // 对应@FieldDescription、@UInt、@AutoCodec
}
type PetCureOutboundEmpty struct {
}

View File

@@ -205,7 +205,7 @@ type ClientData struct {
Wsmsg *WsCodec
Conn gnet.Conn
SaveL sync.Once //保存锁
SaveDone chan struct{}
}
func NewClientData(c gnet.Conn) *ClientData {

View File

@@ -92,6 +92,7 @@ func GetServerInfoList() []ServerInfo {
//tt.IP = v.IP
tt.IP = ip
if tt.OnlineID == 2 {
tt.UserCnt = 300
tt.IP = testip
}
tt.Port = v.Port