diff --git a/common/rpc/client.go b/common/rpc/client.go new file mode 100644 index 000000000..6d220e5a9 --- /dev/null +++ b/common/rpc/client.go @@ -0,0 +1,130 @@ +package rpc + +import ( + "blazing/cool" + "blazing/modules/base/service" + "blazing/modules/blazing/model" + "context" + "sync" + + "github.com/butoften/array" +) + +func GetServerInfoList1() []ServerInfo { + dictInfoModel1 := model.NewServerList() + mType := cool.DBM(dictInfoModel1) + t, _ := mType.All() + //fmt.Println(t) + var ret []model.ServerList + t.Structs(&ret) + //fmt.Println(t) + var ret1 []ServerInfo + ip, _ := service.NewBaseSysParamService().DataByKey(context.Background(), "server_ip") + testip, _ := service.NewBaseSysParamService().DataByKey(context.Background(), "test_ip") + for _, v := range ret { + tt := newServerInfo() + tt.OnlineID = uint32(v.OnlineID) + + tt.IP = ip + if tt.OnlineID == 2 { + tt.UserCnt = 300 + tt.IP = testip + } + tt.Port = v.Port + t, ok := Clientmap[v.Port] + if ok && t != nil { + + // tt.Friends = v.Friends + ret1 = append(ret1, *tt) + } + + } + array.Sort(&ret1, func(a ServerInfo, b ServerInfo) bool { + return a.OnlineID < b.OnlineID + }) + //fmt.Printf("升序 Sort: %v\n", ret1) + return ret1 + +} + +// CommendSvrInfo 初始连接请求信息结构体 +type CommendSvrInfo struct { + //Handler player.TomeeHeader //` struc:"[0]pad"` //消息头 ,这里为传入的头部数据,遍历此头部实现解析CommendSvrInfo + MaxOnlineID uint32 `struc:"sizeof=ServerList"` // 最大连接数 + IsVip uint32 // 建议为0 + ServerInfoLen uint32 `struc:"sizeof=ServerList"` // 服务器信息长度 ServerInfo + ServerList []ServerInfo // 服务器具体信息 + FriendInfoLen uint32 `struc:"sizeof=FriendInfo"` + FriendInfo []FriendInfo // 好友id + BlackInfoLen uint32 `struc:"sizeof=BlackInfo"` + BlackInfo []BlackInfo // 黑名单id +} + +// NewInInfo 创建并返回一个新的 commendSvrInfo 结构体实例 +// 返回的实例包含初始化的 ServerList、FriendInfo 和 BlackInfo 切片 +// IsVip 和 ServerInfoLen 字段被初始化为 0 +func NewInInfo() *CommendSvrInfo { + return &CommendSvrInfo{ + // Handler: player.TomeeHeader{}, + // MaxOnlineID: 100, + IsVip: 0, + ServerInfoLen: 0, + ServerList: make([]ServerInfo, 0), + FriendInfo: make([]FriendInfo, 0), + BlackInfo: make([]BlackInfo, 0), + //Reversed: 0, + } +} + +// ServerInfo 服务器信息结构体 +type ServerInfo struct { + // 连接ID, 即服务器序号 + OnlineID uint32 + // 当前服务器玩家在线数量, 供SWF显示 + UserCnt uint32 + // 服务器IP, 16字节UTF-8, 不足16补齐到16 + IP string `struc:"[16]byte"` // 定长模式:16字节 + // 端口 + Port uint16 + // 好友在线的个数 + Friends uint32 +} + +// NewServerInfo 创建新的服务器信息实例 +func newServerInfo() *ServerInfo { + //getServerInfoList() + return &ServerInfo{ + //OnlineID: 0, + UserCnt: 20, + //IP: "", + // Port: 0, + Friends: 1, + } +} + +type FriendInfo struct { + BlackInfo + TimePoke uint32 +} + +type BlackInfo struct { + Userid uint32 + //TimePoke uint32 +} + +func Refurh() { + l.Lock() + defer l.Unlock() + GetServerInfoList = GetServerInfoList1() + +} + +func GetServer() []ServerInfo { + l.RLock() + defer l.RUnlock() + return GetServerInfoList + +} + +var GetServerInfoList = GetServerInfoList1() +var l sync.RWMutex diff --git a/common/rpc/rpc.go b/common/rpc/rpc.go index 1a1fb12c4..c683a7603 100644 --- a/common/rpc/rpc.go +++ b/common/rpc/rpc.go @@ -3,6 +3,7 @@ package rpc import ( "blazing/common/data/share" "blazing/cool" + "blazing/modules/base/service" "context" "fmt" @@ -17,7 +18,7 @@ import ( var rpcport = gconv.String(cool.Config.RPC) -var clientmap = make(map[uint16]*ClientHandler) //客户端map +var Clientmap = make(map[uint16]*ClientHandler) //客户端map type ClientHandler struct { KickPerson func(uint32) error //踢人,这里是返回具体的logic @@ -36,7 +37,7 @@ func (h *ServerHandler) Kick(ctx context.Context, userid uint32) error { if err != nil { return fmt.Errorf("user not found", err) } - cl, ok := clientmap[useid1] + cl, ok := Clientmap[useid1] if ok { err := cl.KickPerson(userid) //实现指定服务器踢人 if err != nil { @@ -49,18 +50,20 @@ func (h *ServerHandler) Kick(ctx context.Context, userid uint32) error { // 注册logic服务器 func (h *ServerHandler) RegisterLogic(ctx context.Context, id, port uint16) error { cool.Loger.Debug(context.Background(), "注册logic服务器", id, port) + //TODO 待修复滚动更新可能导致的玩家可以同时在旧服务器和新服务器同时在线的bug revClient, ok := jsonrpc.ExtractReverseClient[ClientHandler](ctx) if !ok { return fmt.Errorf("no reverse client") } t, _ := blservice.NewLoginServiceService().GetServerID(id) - aa, ok := clientmap[t] + aa, ok := Clientmap[t] if ok && aa != nil { //如果已经存在且这个端口已经被存过 aa.QuitSelf(0) } - clientmap[port] = &revClient + Clientmap[port] = &revClient + Refurh() return nil } diff --git a/common/socket/ServerEvent.go b/common/socket/ServerEvent.go index 1878bcf4b..04847a09a 100644 --- a/common/socket/ServerEvent.go +++ b/common/socket/ServerEvent.go @@ -83,7 +83,6 @@ func (s *Server) OnOpen(conn gnet.Conn) (out []byte, action gnet.Action) { if s.network != "tcp" { return nil, gnet.Close } - conn.SetReadDeadline(<-time.After(3000)) if conn.Context() == nil { conn.SetContext(player.NewClientData(conn)) //注入data diff --git a/logic/controller/getserver.go b/logic/controller/getserver.go index 4d92be94a..a5b063295 100644 --- a/logic/controller/getserver.go +++ b/logic/controller/getserver.go @@ -1,6 +1,7 @@ package controller import ( + "blazing/common/rpc" "blazing/common/socket/errorcode" "blazing/logic/service/user" @@ -9,14 +10,14 @@ import ( ) // 处理命令: 105 -func (h *Controller) COMMEND_ONLINE(data *user.SidInfo, c gnet.Conn) (result *user.CommendSvrInfo, err errorcode.ErrorCode) { //这个时候player应该是空的 - result = user.NewInInfo() +func (h *Controller) COMMEND_ONLINE(data *user.SidInfo, c gnet.Conn) (result *rpc.CommendSvrInfo, err errorcode.ErrorCode) { //这个时候player应该是空的 + result = rpc.NewInInfo() if data.Head.UserID < 100000 { result.IsVip = 1 } - result.ServerList = user.GetServerInfoList() + result.ServerList = rpc.GetServerInfoList1() //todo 待修改增加缓存 return diff --git a/logic/service/fight/effect/effect_10-16_94_99_114.go b/logic/service/fight/effect/effect_10-16_94_99_114.go index 2cb4335cd..3b6897b70 100644 --- a/logic/service/fight/effect/effect_10-16_94_99_114.go +++ b/logic/service/fight/effect/effect_10-16_94_99_114.go @@ -70,7 +70,7 @@ func (e *EffectStatus) OnSkill(ctx input.Ctx) bool { // 持续回合 if duration == 0 { - duration = int(rand.Int31n(3) + 1) // 默认随机 1~3 回合 + duration = int(rand.Int31n(3) + 10) // 默认随机 1~3 回合 } // 获取状态效果 diff --git a/logic/service/fight/fightc.go b/logic/service/fight/fightc.go index d53e838e0..44d6700d0 100644 --- a/logic/service/fight/fightc.go +++ b/logic/service/fight/fightc.go @@ -286,12 +286,12 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.S }) attacker.DamageZone.Damage = attacker.CalculatePower(defender, a.SkillEntity) //睡眠受击消除 - if a.SkillEntity.Category() != info.Category.STATUS { - t := defender.GetEffect(input.EffectType.Status, int(info.PetStatus.Sleep)) - if t != nil { - t.NotALive() - } - } + // if a.SkillEntity.Category() != info.Category.STATUS { + // t := defender.GetEffect(input.EffectType.Status, int(info.PetStatus.Sleep)) + // if t != nil { + // t.NotALive() + // } + // } if attacker.AttackValue.IsCritical == 1 { //暴击破防 diff --git a/logic/service/fight/input/node.go b/logic/service/fight/input/node.go index 1ca455be6..f5464303a 100644 --- a/logic/service/fight/input/node.go +++ b/logic/service/fight/input/node.go @@ -107,10 +107,10 @@ func (c *Input) AddEffect(e Effect) { // 如果已有同 ID 的效果,尝试叠加 for _, v := range c.Effects { if v.ID() == e.ID() && v.Alive() { - v.NotALive() //取消之前效果 - if v.MaxStack() > 0 { - if v.Stack() < v.MaxStack() { //如果小于最大叠层,状态可以叠层 + if v.MaxStack() > 0 { + v.NotALive() //取消之前效果 + if v.Stack() <= v.MaxStack() { //如果小于最大叠层,状态可以叠层 e.SetArgs(v.GetInput(), v.GetArgs()...) //参数输入 e.Stack(v.Stack() + e.Stack()) //获取到当前叠层数然后叠加 //v.Duration(e.Duration()) //回合数覆盖 diff --git a/logic/service/player/SocketHandler_Tomee.go b/logic/service/player/SocketHandler_Tomee.go index dfb85c849..0fa9fa864 100644 --- a/logic/service/player/SocketHandler_Tomee.go +++ b/logic/service/player/SocketHandler_Tomee.go @@ -221,6 +221,28 @@ func NewClientData(c gnet.Conn) *ClientData { } +func XORDecrypt(encryptedData []byte, keyStr string) []byte { + if len(encryptedData) == 0 || keyStr == "" { + return []byte{} + } + + // 1. 将密钥字符串转换为UTF-8字节数组(对应AS3的writeUTFBytes(_arg_2)) + keyBytes := []byte(keyStr) // Go中string转[]byte默认是UTF-8编码,与AS3的writeUTFBytes一致 + keyLen := len(keyBytes) + if keyLen == 0 { + return encryptedData // 空密钥不加密,直接返回 + } + + // 2. 执行异或操作(与加密逻辑一致,异或两次还原数据) + decrypted := make([]byte, len(encryptedData)) + for i, b := range encryptedData { + // 循环复用密钥字节(索引取模) + keyIndex := i % keyLen + decrypted[i] = b ^ keyBytes[keyIndex] + } + + return decrypted +} func (h *ClientData) OnEvent(v []byte) { header := TomeeHeader{} @@ -233,7 +255,7 @@ func (h *ClientData) OnEvent(v []byte) { header.UserID, _ = tempdata.ReadUInt32() header.Result, _ = tempdata.ReadUInt32() - header.Data = tempdata.BytesAvailable() + header.Data = XORDecrypt(tempdata.BytesAvailable(), "CWF") if header.CMD > 1001 { if h.Conn.Context().(*ClientData).Player == nil { cool.Loger.Error(context.TODO(), header.UserID, "账号未注册") diff --git a/logic/service/user/CommendSvrInfo.go b/logic/service/user/CommendSvrInfo.go index da76c0a26..61f335a08 100644 --- a/logic/service/user/CommendSvrInfo.go +++ b/logic/service/user/CommendSvrInfo.go @@ -1,13 +1,7 @@ package user import ( - "blazing/cool" "blazing/logic/service/player" - baseservice "blazing/modules/base/service" - "blazing/modules/blazing/model" - "context" - - "github.com/butoften/array" ) //var _ entity.Blazingservice = (*SidInfo)(nil) @@ -18,102 +12,3 @@ type SidInfo struct { //这里直接使用组合来实现将传入的原始头 Sid []byte `struc:"[20]byte"` // 登录会话ID,固定长度16字节 // ret []byte `struc:"[0]pad"` } - -// CommendSvrInfo 初始连接请求信息结构体 -type CommendSvrInfo struct { - //Handler player.TomeeHeader //` struc:"[0]pad"` //消息头 ,这里为传入的头部数据,遍历此头部实现解析CommendSvrInfo - MaxOnlineID uint32 `struc:"sizeof=ServerList"` // 最大连接数 - IsVip uint32 // 建议为0 - ServerInfoLen uint32 `struc:"sizeof=ServerList"` // 服务器信息长度 ServerInfo - ServerList []ServerInfo // 服务器具体信息 - FriendInfoLen uint32 `struc:"sizeof=FriendInfo"` - FriendInfo []FriendInfo // 好友id - BlackInfoLen uint32 `struc:"sizeof=BlackInfo"` - BlackInfo []BlackInfo // 黑名单id -} - -// NewInInfo 创建并返回一个新的 commendSvrInfo 结构体实例 -// 返回的实例包含初始化的 ServerList、FriendInfo 和 BlackInfo 切片 -// IsVip 和 ServerInfoLen 字段被初始化为 0 -func NewInInfo() *CommendSvrInfo { - return &CommendSvrInfo{ - // Handler: player.TomeeHeader{}, - // MaxOnlineID: 100, - IsVip: 0, - ServerInfoLen: 0, - ServerList: make([]ServerInfo, 0), - FriendInfo: make([]FriendInfo, 0), - BlackInfo: make([]BlackInfo, 0), - //Reversed: 0, - } -} - -// ServerInfo 服务器信息结构体 -type ServerInfo struct { - // 连接ID, 即服务器序号 - OnlineID uint32 - // 当前服务器玩家在线数量, 供SWF显示 - UserCnt uint32 - // 服务器IP, 16字节UTF-8, 不足16补齐到16 - IP string `struc:"[16]byte"` // 定长模式:16字节 - // 端口 - Port uint16 - // 好友在线的个数 - Friends uint32 -} - -// NewServerInfo 创建新的服务器信息实例 -func newServerInfo() *ServerInfo { - //getServerInfoList() - return &ServerInfo{ - //OnlineID: 0, - UserCnt: 20, - //IP: "", - // Port: 0, - Friends: 1, - } -} - -func GetServerInfoList() []ServerInfo { - dictInfoModel1 := model.NewServerList() - mType := cool.DBM(dictInfoModel1) - t, _ := mType.All() - //fmt.Println(t) - var ret []model.ServerList - t.Structs(&ret) - //fmt.Println(t) - var ret1 []ServerInfo - ip, _ := baseservice.NewBaseSysParamService().DataByKey(context.Background(), "server_ip") - testip, _ := baseservice.NewBaseSysParamService().DataByKey(context.Background(), "test_ip") - for _, v := range ret { - tt := newServerInfo() - tt.OnlineID = uint32(v.OnlineID) - // tt.UserCnt = v.UserCnt - //tt.IP = v.IP - tt.IP = ip - if tt.OnlineID == 2 { - tt.UserCnt = 300 - tt.IP = testip - } - tt.Port = v.Port - // tt.Friends = v.Friends - ret1 = append(ret1, *tt) - - } - array.Sort(&ret1, func(a ServerInfo, b ServerInfo) bool { - return a.OnlineID < b.OnlineID - }) - //fmt.Printf("升序 Sort: %v\n", ret1) - return ret1 - -} - -type FriendInfo struct { - BlackInfo - TimePoke uint32 -} - -type BlackInfo struct { - Userid uint32 - //TimePoke uint32 -}