diff --git a/logic/controller/login_main.go b/logic/controller/login_main.go index 0e9387d8f..8a5b2874c 100644 --- a/logic/controller/login_main.go +++ b/logic/controller/login_main.go @@ -24,7 +24,7 @@ func (h Controller) Login(data *user.MAIN_LOGIN_IN, c gnet.Conn) (result *user.L defer c.Close() return } - isSessionValid := data.CheakSession() + isSessionValid, hashcode := data.CheakSession() if !isSessionValid { defer c.Close() @@ -38,12 +38,14 @@ func (h Controller) Login(data *user.MAIN_LOGIN_IN, c gnet.Conn) (result *user.L return } currentPlayer := player.GetPlayer(c, data.Head.UserID) + if currentPlayer == nil { cool.Logger.Error(context.Background(), "获取玩家失败", data.Head.UserID) defer c.Close() return } + currentPlayer.Hash = hashcode currentPlayer.Service = service.NewUserService(data.Head.UserID) currentPlayer.Info = currentPlayer.Service.Info.SetLogin() diff --git a/logic/service/fight/effect/effect_62.go b/logic/service/fight/effect/effect_62.go index c42a11ef4..59508949d 100644 --- a/logic/service/fight/effect/effect_62.go +++ b/logic/service/fight/effect/effect_62.go @@ -4,7 +4,6 @@ import ( "blazing/logic/service/fight/info" "blazing/logic/service/fight/input" "blazing/logic/service/fight/node" - "fmt" "math" "github.com/alpacahq/alpacadecimal" @@ -38,7 +37,7 @@ func (e *Effect62_sub) TurnEnd() { // 这个实际上在对方回合执行的 func (e *Effect62_sub) OnSkill() bool { - fmt.Println("镇魂歌剩余回合", e.duy) + //fmt.Println("镇魂歌剩余回合", e.duy) //defer e.Alive(false) if e.duy <= 0 { //说明对方没有切换精灵 //直接扣除所有血量OnSkill @@ -60,30 +59,6 @@ func init() { } -// func (e *Effect62) TurnStart() { -// //如果对面还是我方放技能时候的玩家 -// // if ctx.Player != e.opp.Player { -// // return -// // } -// fmt.Println(e.Duration(), "镇魂歌剩余回合") -// if e.Duration() != 0 { //说明还没到生效节点 -// e.Hide = true //隐藏效果 -// } else { -// e.opp.AddEffect(e.e) -// } -// // if !e.Hide { //说明是自身回合//如果还在隐藏,就直接返回 - -// // //t.Duration(e.SideEffectArgs[0]) -// // e.opp.AddEffect(e.e) -// // //defer e.EffectNode.NotALive() //失效 -// // //应该是对方固定伤害等于自身血量 -// // //e.Input.Death() //本只死亡 - -// // //否则触发秒杀 在对面使用技能后 -// // //return true -// // } -// } - // 魂印开局添加,然后切精灵不消失 func (e *Effect62) OnSkill() bool { diff --git a/logic/service/player/pack.go b/logic/service/player/pack.go index 9546b56b8..7d286037f 100644 --- a/logic/service/player/pack.go +++ b/logic/service/player/pack.go @@ -172,6 +172,36 @@ func NewClientData(c gnet.Conn) *ClientData { } +// XORDecrypt 异或解密函数(密钥改为uint32版本) +// 核心逻辑:将uint32密钥拆分为4字节数组(大端序,适配AS3二进制处理习惯),循环与加密数据异或 +// 参数: +// +// encryptedData - 待解密的字节数组 +// key - 32位无符号整数密钥(替代原字符串密钥) +// +// 返回值:解密后的字节数组 +func XORDecryptU(encryptedData []byte, key uint32) []byte { + // 边界条件:待解密数据为空,直接返回空 + if len(encryptedData) == 0 { + return []byte{} + } + + // 1. 将uint32密钥转换为4字节数组(关键步骤) + // 字节序选择:BigEndian(大端)是AS3/Java等语言的默认二进制处理方式,若需小端可改为binary.LittleEndian + keyBytes := make([]byte, 4) // uint32固定占4个字节 + binary.BigEndian.PutUint32(keyBytes, key) + keyLen := len(keyBytes) // 固定为4,无需额外判断长度 + + // 2. 执行异或解密(逻辑与原版本一致,仅密钥来源不同) + decrypted := make([]byte, len(encryptedData)) + for i, b := range encryptedData { + // 循环复用4字节密钥(索引取模,i%4) + keyIndex := i % keyLen + decrypted[i] = b ^ keyBytes[keyIndex] + } + + return decrypted +} func XORDecrypt(encryptedData []byte, keyStr string) []byte { if len(encryptedData) == 0 || keyStr == "" { return []byte{} @@ -211,16 +241,17 @@ func (h *ClientData) OnEvent(v []byte) { // 解析Len(0-3字节) header.Len = binary.BigEndian.Uint32(v[0:4]) // 解析Version(第4字节) - header.Version = v[4] + //header.Version = v[4] // 解析CMD(5-8字节) header.CMD = binary.BigEndian.Uint32(v[5:9]) // 解析UserID(9-12字节) header.UserID = binary.BigEndian.Uint32(v[9:13]) // 解析Result(13-16字节) - header.Result = binary.BigEndian.Uint32(v[13:17]) + //header.Result = binary.BigEndian.Uint32(v[13:17]) // 解析数据部分(17字节之后) if len(v) > 17 { - header.Data = XORDecrypt(v[17:], "CWF") + header.Data = v[17:] + } else { header.Data = []byte{} // 数据部分为空时显式初始化 } @@ -233,6 +264,7 @@ func (h *ClientData) OnEvent(v []byte) { fmt.Println(header.UserID, "未创建角色") return } + header.Data = XORDecryptU(header.Data, t.Player.Hash) } if cool.Config.ServerInfo.IsDebug != 0 { fmt.Println("接收数据", header.UserID, header.CMD) diff --git a/logic/service/player/player.go b/logic/service/player/player.go index eeba4ba51..256eac053 100644 --- a/logic/service/player/player.go +++ b/logic/service/player/player.go @@ -83,6 +83,7 @@ type Player struct { // 0 无,1可以刷怪,2是切换过地图 Canmon uint32 // 可以刷怪 CurDark uint32 + Hash uint32 } type OgrePet struct { diff --git a/logic/service/user/Login.go b/logic/service/user/Login.go index 733e07d31..dd2123d42 100644 --- a/logic/service/user/Login.go +++ b/logic/service/user/Login.go @@ -4,6 +4,7 @@ import ( "blazing/cool" "blazing/logic/service/common" "fmt" + "hash/crc32" "blazing/modules/player/model" "context" @@ -18,21 +19,22 @@ type MAIN_LOGIN_IN struct { //这里直接使用组合来实现将传入的原 } -func (l *MAIN_LOGIN_IN) CheakSession() bool { +func (l *MAIN_LOGIN_IN) CheakSession() (bool, uint32) { // tt, _ := cool.CacheManager.Keys(context.Background()) //g.Dump(tt) t1 := hex.EncodeToString(l.Sid) r, err := cool.CacheManager.Get(context.Background(), fmt.Sprintf("session:%d", l.Head.UserID)) if err != nil { - return false + return false, 0 } if r.String() != t1 { - return false + return false, 0 } - + crc32Table := crc32.MakeTable(crc32.IEEE) + crcValue := crc32.Checksum([]byte(t1), crc32Table) cool.CacheManager.Remove(context.Background(), fmt.Sprintf("session:%d", l.Head.UserID)) //glog.Debug(context.Background(), "后端获取", t1, err) - return true + return true, crcValue } type LoginMSInfo struct { diff --git a/modules/base/controller/admin/base_sys_user.go b/modules/base/controller/admin/base_sys_user.go index b0b803f00..24bc4c57a 100644 --- a/modules/base/controller/admin/base_sys_user.go +++ b/modules/base/controller/admin/base_sys_user.go @@ -14,6 +14,7 @@ import ( blazing "blazing/modules/player/service" playerservice "blazing/modules/player/service" + "github.com/deatil/go-cryptobin/cryptobin/crypto" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/frame/g" ) @@ -70,8 +71,16 @@ func (c *BaseSysUserController) GetSession(ctx context.Context, req *SessionReq) res.PetID = dict.NewDictInfoService().GetShiny() res.Server = config.NewServerService().GetPort(int(t1.Debug)) // share.ShareManager.DeleteSession(t1) - - res.Session = blazing.NewInfoService(uint32(t.UserId)).Gensession() + cypten := crypto. + FromString(blazing.NewInfoService(uint32(t.UserId)).Gensession()). + SetKey("gfertf12dfertf12"). + SetIv("gfertf12dfertf12"). + Aes(). + CBC(). + PKCS7Padding(). + Encrypt(). + ToBase64String() + res.Session = cypten return } diff --git a/modules/base/go.mod b/modules/base/go.mod index c61c9e14d..5e4dcaf99 100644 --- a/modules/base/go.mod +++ b/modules/base/go.mod @@ -1,6 +1,6 @@ module blazing/modules/base -go 1.20 +go 1.24.0 require ( github.com/gogf/gf/v2 v2.8.0 @@ -9,6 +9,7 @@ require ( ) require ( + github.com/deatil/go-cryptobin v1.1.1013 // indirect github.com/dolthub/maphash v0.1.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/ipipdotnet/ipdb-go v1.3.3 // indirect diff --git a/modules/base/go.sum b/modules/base/go.sum index 326d10c5f..025c41e89 100644 --- a/modules/base/go.sum +++ b/modules/base/go.sum @@ -5,6 +5,8 @@ github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deatil/go-cryptobin v1.1.1013 h1:SF4uNijMfuW42Ir8q1YusgSONGbEqlCeXbSbBUkUImE= +github.com/deatil/go-cryptobin v1.1.1013/go.mod h1:x+/+SzyfbxliY2y0Fwe+OoLU0DEt9kWs6OMiwghcfJ0= github.com/dolthub/maphash v0.1.0 h1:bsQ7JsF4FkkWyrP3oCnFJgrCUAFbFf3kOl4L/QxPDyQ= github.com/dolthub/maphash v0.1.0/go.mod h1:gkg4Ch4CdCDu5h6PMriVLawB7koZ+5ijb9puGMV50a4= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= diff --git a/modules/player/service/info.go b/modules/player/service/info.go index 0a7b82456..c44fc5af0 100644 --- a/modules/player/service/info.go +++ b/modules/player/service/info.go @@ -9,8 +9,6 @@ import ( "encoding/hex" "fmt" - "strings" - "time" "github.com/gogf/gf/v2/os/glog" @@ -143,12 +141,10 @@ var User = csmap.New[string, uint32]( // 会话ID由accountID(4字节) + UUID(16字节) + 随机数(4字节)组成,最终编码为十六进制字符串 func (s *InfoService) Gensession() string { uuidV7, _ := uuid.NewV7() - + uuidBytes := uuidV7[:] // UUID 类型底层是 [16]byte,直接切片获取 // 移除UUID中的连字符,便于后续处理 - uuidStr := strings.ReplaceAll(uuidV7.String(), "-", "") - // // 解码UUID字符串为字节数组(32位十六进制字符串对应16字节) - uuidBytes, _ := hex.DecodeString(uuidStr) + // 3. 计算 CRC32-IEEE 校验码(最通用的CRC32标准) sessionID := hex.EncodeToString(uuidBytes)