diff --git a/common/data/color.go b/common/data/color.go index 61b46cb9d..b48907387 100644 --- a/common/data/color.go +++ b/common/data/color.go @@ -47,6 +47,7 @@ type GlowFilter struct { // Knockout 是否挖空,默认 false Knockout bool `json:"knockout,omitempty"` ColorMatrixFilter [20]float32 `json:"matrix,omitempty"` + Level uint8 `json:"level,omitempty"` //等级 } // ItemInfo diff --git a/common/utils/concurrent-swiss-map/concurrent_swiss_map.go b/common/utils/concurrent-swiss-map/concurrent_swiss_map.go index 8620ece36..d8e4c6627 100644 --- a/common/utils/concurrent-swiss-map/concurrent_swiss_map.go +++ b/common/utils/concurrent-swiss-map/concurrent_swiss_map.go @@ -277,14 +277,22 @@ func (m *CsMap[K, V]) produce(ctx context.Context, ch chan Tuple[K, V]) { func (m *CsMap[K, V]) listen(f func(key K, value V) (stop bool), ch chan Tuple[K, V]) *sync.WaitGroup { var wg sync.WaitGroup wg.Add(1) - m.pool.Submit(func() { + go func() { defer wg.Done() + defer func() { + if err := recover(); err != nil { // 恢复 panic,err 为 panic 错误值 + // 1. 打印错误信息 + + cool.Logger.Error(context.TODO(), "panic 错误:", err) + + } + }() for t := range ch { if stop := f(t.Key, t.Val); stop { return } } - }) + }() return &wg } diff --git a/logic/controller/login_main.go b/logic/controller/login_main.go index 641d57a4f..4553f2b7c 100644 --- a/logic/controller/login_main.go +++ b/logic/controller/login_main.go @@ -45,11 +45,8 @@ func (h Controller) Login(data *user.MAIN_LOGIN_IN, c gnet.Conn) (result *user.L currentPlayer.Info.UserID = data.Head.UserID currentPlayer.Logintime = uint32(time.Now().Unix()) //保存时间戳 - currentPlayer.CompleteLogin() //通知客户端登录成功 + result = user.NewOutInfo(currentPlayer.Info) //设置登录消息 - result = user.NewOutInfo() //设置登录消息 - - result.PlayerInfo = *currentPlayer.Info defer space.GetSpace(currentPlayer.Info.MapID).EnterMap(currentPlayer) return result, 0 diff --git a/logic/controller/pet_fusion.go b/logic/controller/pet_fusion.go index e40a0bf0c..a72606ade 100644 --- a/logic/controller/pet_fusion.go +++ b/logic/controller/pet_fusion.go @@ -49,7 +49,11 @@ func (h Controller) PetFusion(data *pet.C2S_PetFusion, c *player.Player) (result } resid := int(service.NewPetFusionService().Data(Mcatchpetinfo.ID, Auxpetinfo.ID, Mcatchpetinfo.Level+Auxpetinfo.Level)) + effect := int(service.NewPetFusionMaterialService().Data(data.Item1)) + if effect == 0 { + return result, errorcode.ErrorCodes.ErrSpiritOrbNotExists + } for _, v := range data.Item1 { if c.Service.Item.CheakItem(v) == 0 { return &pet.PetFusionInfo{}, 0 @@ -81,12 +85,6 @@ func (h Controller) PetFusion(data *pet.C2S_PetFusion, c *player.Player) (result return &pet.PetFusionInfo{}, 0 } - effect := int(service.NewPetFusionMaterialService().Data(data.Item1)) - - if effect == 0 { - return &pet.PetFusionInfo{}, 0 - } - dv1 := alpacadecimal.NewFromInt(2).Div(alpacadecimal.NewFromInt(3)).Mul(alpacadecimal.NewFromInt(int64(Mcatchpetinfo.Dv))) dv2 := alpacadecimal.NewFromInt(1).Div(alpacadecimal.NewFromInt(3)).Mul(alpacadecimal.NewFromInt(int64(Auxpetinfo.Dv))) dv := dv1.Add(dv2).Add(alpacadecimal.NewFromInt(1)).IntPart() diff --git a/logic/service/fight/boss/NewSeIdx_114.go b/logic/service/fight/boss/NewSeIdx_114.go index e91dbcb00..3d766e668 100644 --- a/logic/service/fight/boss/NewSeIdx_114.go +++ b/logic/service/fight/boss/NewSeIdx_114.go @@ -8,7 +8,7 @@ import ( // 免疫瞬杀 type NewSel114 struct { NewSel0 - v *input.Effect + v []*input.Effect } func (e *NewSel114) TurnStart(fattack *action.SelectSkillAction, sattack *action.SelectSkillAction) { @@ -17,20 +17,22 @@ func (e *NewSel114) TurnStart(fattack *action.SelectSkillAction, sattack *action return } - for _, v := range e.Ctx().Opp.Opp.Effects { + for _, v := range e.Ctx().Opp.Effects { if v.ID().GetEffectType() == input.EffectType.NewSel && v.ID().Suffix() == 32 { - v.Alive() - e.v = &v + v.Alive(false) + e.v = append(e.v, &v) } } } func (e *NewSel114) TurnEnd() { - if e.v != nil { - e.Alive(true) + for _, v := range e.v { + if v != nil { + e.Alive(true) + } } } diff --git a/logic/service/player/Monster.go b/logic/service/player/Monster.go index 92d876f09..722c62aaa 100644 --- a/logic/service/player/Monster.go +++ b/logic/service/player/Monster.go @@ -84,7 +84,7 @@ func (p *Player) GenMonster() { } if cool.Config.ServerInfo.IsVip != 0 { //测试服,百分百异色 - p.OgreInfo.Data[i].RandSHiny() + p.OgreInfo.Data[i].FixSHiny() } if xmlres.PetMAP[int(p.OgreInfo.Data[i].Id)].CatchRate != 0 && grand.Meet(3, 1000) { p.OgreInfo.Data[i].RandSHiny() diff --git a/logic/service/player/player.go b/logic/service/player/player.go index 181cde66a..76277a208 100644 --- a/logic/service/player/player.go +++ b/logic/service/player/player.go @@ -46,6 +46,18 @@ type OgrePetInfo struct { } func (o *OgrePetInfo) RandSHiny() { + var co *data.GlowFilter + if o.Ext == 0 { + + co = config.NewShinyService().RandShiny(o.Id) + } + + if co != nil && len(o.ShinyInfo) == 0 { + o.ShinyInfo = append(o.ShinyInfo, *co) + } + +} +func (o *OgrePetInfo) FixSHiny() { var co *data.GlowFilter if o.Ext == 0 { @@ -222,27 +234,27 @@ func (p *Player) ItemAdd(ItemId, ItemCnt uint32) (result bool) { } func (player1 *Player) Kick(qtype int) { - if player1.IsLogin { - //取成功,否则创建 - //player1.Save() //先保存数据再返回 - head := common.NewTomeeHeader(1001, player1.Info.UserID) - head.Result = uint32(errorcode.ErrorCodes.ErrAccountLoggedInElsewhere) - if qtype == 1 { - head.Result = uint32(errorcode.ErrorCodes.ErrXinPlanSleepMode) - } - //实际上这里有个问题,会造成重复保存问题 + //取成功,否则创建 + //player1.Save() //先保存数据再返回 + head := common.NewTomeeHeader(1001, player1.Info.UserID) - player1.SendPack(head.Pack(nil)) - CloseChan := make(chan struct{}) - - player1.MainConn.CloseWithCallback(func(c gnet.Conn, err error) error { - - close(CloseChan) - return nil - }) - <-CloseChan + head.Result = uint32(errorcode.ErrorCodes.ErrAccountLoggedInElsewhere) + if qtype == 1 { + head.Result = uint32(errorcode.ErrorCodes.ErrXinPlanSleepMode) } + //实际上这里有个问题,会造成重复保存问题 + + player1.SendPack(head.Pack(nil)) + CloseChan := make(chan struct{}) + + player1.MainConn.CloseWithCallback(func(c gnet.Conn, err error) error { + + close(CloseChan) + return nil + }) + <-CloseChan + } func (p *Player) Cheak(b error) { diff --git a/logic/service/player/save.go b/logic/service/player/save.go index edb1dab4e..4ae6d6f29 100644 --- a/logic/service/player/save.go +++ b/logic/service/player/save.go @@ -3,7 +3,7 @@ package player import ( "blazing/common/data/share" "blazing/cool" - "blazing/modules/player/model" + "fmt" "blazing/logic/service/fight/info" "blazing/logic/service/space" @@ -13,6 +13,7 @@ import ( // Save 保存玩家数据 func (p *Player) Save() { + cool.CacheManager.Remove(context.TODO(), fmt.Sprintf("player:%d", p.Info.UserID)) if cool.Config.ServerInfo.IsVip != 0 { cool.Logger.Info(context.TODO(), "测试服不保存玩家数据", p.Info.UserID) @@ -57,10 +58,9 @@ func (p *Player) Save() { p.MapNPC.Stop() //停止刷怪 - p.IsLogin = false - Mainplayer.Delete(p.Info.UserID) share.ShareManager.DeleteUserOnline(p.Info.UserID) //设置用户登录服务器 + } // 是否可以获得经验 @@ -73,47 +73,3 @@ func (p *Player) CanGetExp() bool { return (uint32(time.Now().Unix()) - uint32(p.Logintime)) <= ttt } - -// CompleteLogin 标记登录完成并通知等待者 -func (lw *Player) CompleteLogin() { - - if lw.Info.MapID > 300 || lw.Info.MapID == 0 { //如果位于基地,就重置到传送仓 - lw.Info.MapID = 1 - - } - if lw.IsNewPlayer() { //重置新手地图,放到机械仓 - lw.Info.SetTask(4, model.Completed) //设置新手任务默认完成 - lw.Info.MapID = 8 - if len(lw.Info.PetList) == 0 { - //这个是添加后防止卡死 - rr := lw.Service.Pet.PetInfo(0) - if len(rr) > 0 { - lw.Info.PetList = append(lw.Info.PetList, rr[0].Data) - } - - } - } - if lw.Info.MaxPuniLv < 9 { - - for i := 291; i < 299; i++ { - - if lw.Info.GetTask(i) == model.Completed { - lw.Info.MaxPuniLv = uint32(i) - 290 - - } - } - - } - lw.IsLogin = true -} - -// 定义检查函数:判断84-87索引中是否有任意一个元素不等于3 -func (lw *Player) IsNewPlayer() bool { - // 遍历84到87的索引 - for i := 85; i <= 88; i++ { - if lw.Info.GetTask(i) != model.Completed { - return true // 只要有一个不等于3,就返回true - } - } - return false // 全部等于3则返回false -} diff --git a/logic/service/user/Login.go b/logic/service/user/Login.go index 49843e185..cc6579585 100644 --- a/logic/service/user/Login.go +++ b/logic/service/user/Login.go @@ -41,10 +41,10 @@ type LoginMSInfo struct { model.PlayerInfo } -func NewOutInfo() *LoginMSInfo { +func NewOutInfo(info *model.PlayerInfo) *LoginMSInfo { l := &LoginMSInfo{ - PlayerInfo: model.NewPlayerInfo(), + PlayerInfo: *info, } return l diff --git a/modules/base/controller/admin/base_sys_user.go b/modules/base/controller/admin/base_sys_user.go index b82350c6b..10680c1f6 100644 --- a/modules/base/controller/admin/base_sys_user.go +++ b/modules/base/controller/admin/base_sys_user.go @@ -10,6 +10,7 @@ import ( "blazing/modules/base/service" config "blazing/modules/config/service" + dict "blazing/modules/dict/service" blazing "blazing/modules/player/service" playerservice "blazing/modules/player/service" @@ -66,13 +67,8 @@ func (c *BaseSysUserController) GetSession(ctx context.Context, req *SessionReq) res.IsReg = 1 } - - if cool.Config.ServerInfo.IsDebug != 0 { - res.LoginAddr = "192.168.1.44" + ":" + cool.Config.LoginPort - } else { - res.LoginAddr = cool.Config.File.Domain + ":" + cool.Config.LoginPort - } - res.Server = config.NewServerService().GetPort() + res.PetID = dict.NewDictInfoService().GetShiny() + res.Server = config.NewServerService().GetPort(int(t1.Debug)) // share.ShareManager.DeleteSession(t1) ser := playerservice.NewUserService(uint32(t1.ID)) kickErr := ser.Info.Kick(uint32(t1.ID)) @@ -91,11 +87,12 @@ func (c *BaseSysUserController) GetSession(ctx context.Context, req *SessionReq) } type SessionRes struct { - IsReg int `json:"isreg"` - UserID int `json:"userid"` - Session string `json:"session"` - LoginAddr string `json:"loginaddr"` - Server gdb.List `json:"server"` + IsReg int `json:"isreg"` + UserID int `json:"userid"` + Session string `json:"session"` + + Server gdb.List `json:"server"` + PetID []int `json:"petid"` } type RegReq struct { diff --git a/modules/base/middleware/middleware.go b/modules/base/middleware/middleware.go index ae484df5c..af8317c0a 100644 --- a/modules/base/middleware/middleware.go +++ b/modules/base/middleware/middleware.go @@ -58,11 +58,8 @@ func init() { g.Server().BindHandler("/server/*", func(r *ghttp.Request) { servert := new(ServerHandler) id := gconv.Uint16(r.URL.Query().Get("id")) - servert.isinstall = gconv.Uint32(r.URL.Query().Get("isinstall")) - if servert.isinstall != 0 { - servert.ServerList = service.NewServerService().StartUPdate(id) - } + servert.ServerList = service.NewServerService().StartUPdate(id, int(servert.isinstall)) upgrader := gws.NewUpgrader(servert, &gws.ServerOption{ diff --git a/modules/base/middleware/server.go b/modules/base/middleware/server.go index 0089ed63c..f478315a5 100644 --- a/modules/base/middleware/server.go +++ b/modules/base/middleware/server.go @@ -197,93 +197,11 @@ else command -v screen || { echo "❌ Screen安装失败"; exit 1; } fi + #!/bin/bash # 核心:无任何可能阻塞的命令,全程实时输出,100%不卡住 + 彻底清理所有logic会话 set -euo pipefail -# ===== 仅需配置这1个变量 ===== -SCREEN_NAME="logic" - -# ===== 颜色输出函数(确保能看到输出)===== -red() { echo -e "\033[31m[$(date +%H:%M:%S)] $1\033[0m"; } -green() { echo -e "\033[32m[$(date +%H:%M:%S)] $1\033[0m"; } -yellow() { echo -e "\033[33m[$(date +%H:%M:%S)] $1\033[0m"; } - -# ===== 新增:彻底清理screen会话(核心修复)===== -clean_screen_sessions() { - local sess_id=$1 - # 1. 先优雅关闭screen会话 - screen -S "${sess_id}" -X quit >/dev/null 2>&1 || true - sleep 0.3 - # 2. 提取会话PID并强制杀死 - local sess_pid=$(echo "${sess_id}" | cut -d. -f1) - if [ -n "${sess_pid}" ]; then - kill -9 "${sess_pid}" >/dev/null 2>&1 || true - # 3. 杀死该PID的所有子进程 - pkill -9 -P "${sess_pid}" >/dev/null 2>&1 || true - fi -} - -# ===== 强制关闭所有阻塞的后台进程(先清场)===== -green "【步骤1/5】清理脚本自身可能的阻塞进程" -pkill -f "screen_clean_*" >/dev/null 2>&1 || true -pkill -9 -f "pgrep -f SCREEN -S ${SCREEN_NAME}" >/dev/null 2>&1 || true - -# ===== 非阻塞查找进程+会话(关键:延长超时到1秒,查更全)===== -green "【步骤2/5】查找${SCREEN_NAME}相关进程/会话(非阻塞)" -# 先查screen会话ID(1秒超时,避免漏查) -SCREEN_SESS=$(timeout 1 screen -ls 2>/dev/null | grep -E "[0-9]+\\.${SCREEN_NAME}" | grep -v "Dead" | awk '{print $1}' || true) -# 再查进程PID -SCREEN_PIDS=$(timeout 1 pgrep -f "SCREEN -S ${SCREEN_NAME}" | grep -v $$ || true) - -# 合并需要清理的目标 -if [ -z "${SCREEN_SESS}" ] && [ -z "${SCREEN_PIDS}" ]; then - green "✅ 未找到${SCREEN_NAME}相关进程/会话,无需清理" -else - yellow "⚠️ 找到${SCREEN_NAME}会话:${SCREEN_SESS:-无}" - yellow "⚠️ 找到${SCREEN_NAME}进程:${SCREEN_PIDS:-无}" - - # ===== 非阻塞强制清理(先清会话,再清进程)===== - green "【步骤3/5】强制清理${SCREEN_NAME}进程及会话" - # 1. 清理所有screen会话 - if [ -n "${SCREEN_SESS}" ]; then - for sess in ${SCREEN_SESS}; do - yellow "🔧 清理会话:${sess}" - clean_screen_sessions "${sess}" - done - fi - # 2. 清理剩余进程(兜底) - if [ -n "${SCREEN_PIDS}" ]; then - for pid in ${SCREEN_PIDS}; do - yellow "🔧 清理进程:${pid}" - kill -9 "${pid}" >/dev/null 2>&1 || true - pkill -9 -P "${pid}" >/dev/null 2>&1 || true - done - fi - - # 短暂等待(0.5秒,非阻塞) - sleep 0.5 - - # ===== 验证清理结果(查会话+进程,双重验证)===== - green "【步骤4/5】验证清理结果(会话+进程双重检查)" - FINAL_SESS=$(timeout 1 screen -ls 2>/dev/null | grep -E "[0-9]+\\.${SCREEN_NAME}" | grep -v "Dead" || true) - FINAL_PIDS=$(timeout 1 pgrep -f "SCREEN -S ${SCREEN_NAME}" | grep -v $$ || true) - - if [ -z "${FINAL_SESS}" ] && [ -z "${FINAL_PIDS}" ]; then - green "✅ ${SCREEN_NAME}进程/会话已全部清理完成" - else - red "❌ 仍有残留:会话[${FINAL_SESS}] 进程[${FINAL_PIDS}],再次强制清理" - # 终极兜底:强制杀死所有相关进程 - pkill -9 -f "${SCREEN_NAME}" >/dev/null 2>&1 || true - fi -fi - -# ===== 最终收尾 ===== -green "【步骤5/5】${SCREEN_NAME}会话清理流程结束" -green "✅ 自动化部署后续流程可正常执行" - - - # ===== 准备下载目录 ===== @@ -311,10 +229,8 @@ echo "下载链接:%s{file_url}" echo "目标路径:%s{exe_path}" # 删除旧文件(关键修复:这里要判断目标路径,不是下载链接) -if [ -f "%s{exe_path}" ]; then - echo "删除旧文件:%s{exe_path}" - rm -f "%s{exe_path}" -fi + echo "删除旧文件:%s{exe_path}" +rm -f "%s{exe_path}" echo "开始下载..." DOWNLOAD_SUCCESS=0 diff --git a/modules/base/service/base.bbs.go b/modules/base/service/base.bbs.go index 5f6866db7..ae26a8778 100644 --- a/modules/base/service/base.bbs.go +++ b/modules/base/service/base.bbs.go @@ -98,6 +98,8 @@ type GroupAttributes struct { IsHidden int `json:"isHidden"` } +var bbsurl = "http://43.248.3.21:45632" + // GetUserInfo 输入用户名和密码,返回用户信息结构体 func GetUserInfo(username, password string) (*UserResponse, error) { // 创建带 Cookie 存储的 HTTP 客户端 @@ -108,7 +110,7 @@ func GetUserInfo(username, password string) (*UserResponse, error) { client := &http.Client{Jar: jar} // 1. POST 获取 token - tokenURL := "http://bs.seersun.com/api/token" + tokenURL := bbsurl + "/api/token" formData := url.Values{} formData.Set("identification", username) formData.Set("password", password) @@ -141,7 +143,7 @@ func GetUserInfo(username, password string) (*UserResponse, error) { csrfToken := resp.Header.Get("X-CSRF-Token") // 2. GET 获取该用户的详细信息 - usersURL := fmt.Sprintf("http://bs.seersun.com/api/users/%d", tokenResp.UserID) + usersURL := bbsurl + fmt.Sprintf("/api/users/%d", tokenResp.UserID) req2, err := http.NewRequest("GET", usersURL, nil) if err != nil { return nil, fmt.Errorf("创建请求失败: %w", err) diff --git a/modules/config/service/pet_fusion_material_service.go b/modules/config/service/pet_fusion_material_service.go index 0d14b9e80..1a65e65bd 100644 --- a/modules/config/service/pet_fusion_material_service.go +++ b/modules/config/service/pet_fusion_material_service.go @@ -5,7 +5,6 @@ import ( "blazing/modules/config/model" "blazing/modules/dict/service" - "strings" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/util/gconv" @@ -31,8 +30,6 @@ func NewPetFusionMaterialService() *PetFusionMaterialService { // 获取融合材料的特性,返回两个值,一个是指定的特性,另一个是如果配方没找到的情况下,默认的配置 func (s *PetFusionMaterialService) Data(Material1 [4]uint32) uint32 { - cacheKey := strings.Join(gconv.Strings(Material1[:]), ":") - println(cacheKey, "获取融合id") fusions := service.NewDictInfoService().GetData("fusion") for _, v := range Material1 { diff --git a/modules/config/service/server.go b/modules/config/service/server.go index 5af3a617d..c20c27ff5 100644 --- a/modules/config/service/server.go +++ b/modules/config/service/server.go @@ -71,9 +71,15 @@ func NewServerService() *ServerService { cf.manager = storage.NewBucketManager(mac, &cfg) return cf } -func (s *ServerService) GetPort() gdb.List { +func (s *ServerService) GetPort(isdebug int) gdb.List { + var res gdb.Result + if isdebug == 1 { + res, _ = cool.DBM(s.Model).Where("is_open", 1).Fields("ip", "port", "online_id", "is_vip", "name").All() - res, _ := cool.DBM(s.Model).Where("is_open", 1).Fields("ip", "port", "online_id", "is_vip", "name").All() + } else { + res, _ = cool.DBM(s.Model).Where("is_open", 1).Where("is_debug", 0).Fields("ip", "port", "online_id", "is_vip", "name").All() + + } return res.List() @@ -85,16 +91,17 @@ func (s *ServerService) GetServer() []model.ServerList { return item } -func (s *ServerService) StartUPdate(OnlineID uint16) model.ServerList { +func (s *ServerService) StartUPdate(OnlineID uint16, isinstall int) model.ServerList { m := cool.DBM(s.Model).Where("online_id", OnlineID) var tttt model.ServerList m.Scan(&tttt) + if isinstall == 1 { + tttt.IsOpen = uint8(0) + m.Save(tttt) + } - tttt.IsOpen = 0 - - m.Save(tttt) // s.CleanCache() return tttt diff --git a/modules/dict/service/dict_info.go b/modules/dict/service/dict_info.go index a4cb20005..b2b45e32d 100644 --- a/modules/dict/service/dict_info.go +++ b/modules/dict/service/dict_info.go @@ -88,6 +88,8 @@ func (s *DictInfoService) GetData(types string) (data map[uint32]model.DictInfo) return fusions } + +// 获取物品的最大数限制 func (s *DictInfoService) GetMax(value uint32) (max uint32) { m := cool.DBM(s.Model) @@ -105,6 +107,21 @@ func (s *DictInfoService) GetMax(value uint32) (max uint32) { } +// 获取稀有精灵的光环显示 +func (s *DictInfoService) GetShiny() []int { + //获取精灵的排序作为精灵的数组 + m := cool.DBM(s.Model) + + res, _ := m.Where("typeId", 10).Where("ordernum", 1).Cache(gdb.CacheOption{ + // Duration: time.Hour, + + Force: false, + }).Fields("value").All() + + return res.Array("value").Ints() + +} + // ModifyAfter 修改后 func (s *DictInfoService) ModifyAfter(ctx context.Context, method string, param map[string]interface{}) (err error) { defer s.Service.ModifyAfter(ctx, method, param) diff --git a/modules/player/model/done.go b/modules/player/model/done.go index ea1772074..11ff87dd2 100644 --- a/modules/player/model/done.go +++ b/modules/player/model/done.go @@ -24,13 +24,14 @@ var MilestoneEnum = enum.New[struct { type EnumMilestone int -// var MilestoneMode = enum.New[struct { -// BOSS EnumMilestone //boss类 地图ID->BOSSID ,胜利次数 mapid bossid petid,防止换boss后数据不可用 -// ITEM EnumMilestone //物品类 物品ID 使用精灵 -// Fight EnumMilestone //挑战类 对战模式->对战类型->1是赢,0是总局数 -// Moster EnumMilestone //野怪统计 地图ID->怪物ID -// Task EnumMilestone -// }]() +var MilestoneMode = enum.New[struct { + BOSS EnumMilestone //boss类 地图ID->BOSSID ,胜利次数 mapid bossid petid,防止换boss后数据不可用 + ITEM EnumMilestone //物品类 物品ID 使用精灵 + Fight EnumMilestone //挑战类 对战模式->对战类型->1是赢,0是总局数 + Moster EnumMilestone //野怪统计 地图ID->怪物ID + Task EnumMilestone + Pet EnumMilestone //宠物 属性->属性值->ID +}]() const TableNameMilestone = "player_milestone" @@ -39,10 +40,9 @@ type Milestone struct { Base PlayerID uint64 `gorm:"not null;index:idx_milestone_by_player_id;comment:'所属玩家ID'" json:"player_id"` DoneType EnumMilestone `gorm:"not null;comment:'里程碑类型'" json:"done_type"` - Args string `gorm:"type:text;not null;comment:'里程碑ID'" json:"args"` + Args []int32 `gorm:"type:jsonb;not null;comment:'里程碑ID'" json:"args"` // 注:不单独设置"里程碑ID",通过 PlayerID + DoneType + IDs 组合唯一标识一个里程碑(更灵活) - Results string `gorm:"type:jsonb;not null;comment:'里程碑参数'" json:"results"` - Count uint32 `gorm:"not null;comment:'里程碑完成次数'" json:"count"` + Results []int32 `gorm:"type:jsonb;not null;comment:'里程碑参数'" json:"results"` } // // MilestoneEX 里程碑扩展结构体,用于业务层解析后的数据操作 diff --git a/modules/player/model/info.go b/modules/player/model/info.go index ad9fd2371..f38fdbf09 100644 --- a/modules/player/model/info.go +++ b/modules/player/model/info.go @@ -78,6 +78,17 @@ const ( Reserved TaskStatus = 2 // 预留(AS3 中映射为未接受) ) +// 定义检查函数:判断84-87索引中是否有任意一个元素不等于3 +func (lw *PlayerInfo) IsNewPlayer() bool { + // 遍历84到87的索引 + for i := 85; i <= 88; i++ { + if lw.GetTask(i) != Completed { + return true // 只要有一个不等于3,就返回true + } + } + return false // 全部等于3则返回false +} + // SetTask 设置第 i 个任务的状态(0 ≤ i < 2000) func (m *PlayerInfo) SetTask(i int, status TaskStatus) error { i-- //下标减1 diff --git a/modules/player/service/info.go b/modules/player/service/info.go index 54051db1d..7f88f8c86 100644 --- a/modules/player/service/info.go +++ b/modules/player/service/info.go @@ -80,6 +80,34 @@ func (s *InfoService) SetLogin() *model.PlayerInfo { } tt.Data.AllPetNumber = uint32(NewPetService(s.userid).PetCount(0)) + if tt.Data.MapID > 300 || tt.Data.MapID == 0 { //如果位于基地,就重置到传送仓 + tt.Data.MapID = 1 + + } + if tt.Data.IsNewPlayer() { //重置新手地图,放到机械仓 + tt.Data.SetTask(4, model.Completed) //设置新手任务默认完成 + tt.Data.MapID = 8 + if len(tt.Data.PetList) == 0 { + //这个是添加后防止卡死 + rr := NewPetService(s.userid).PetInfo(0) + if len(rr) > 0 { + tt.Data.PetList = append(tt.Data.PetList, rr[0].Data) + } + + } + } + if tt.Data.MaxPuniLv < 9 { + + for i := 291; i < 299; i++ { + + if tt.Data.GetTask(i) == model.Completed { + tt.Data.MaxPuniLv = uint32(i) - 290 + + } + } + + } + if !IsToday(tt.LastResetTime) { //判断是否是今天 //每天login时候检查重置时间,然后把电池,任务,挖矿重置 diff --git a/public/logic-linux-amd64_1 b/public/logic-linux-amd64_1 new file mode 100644 index 000000000..f95e74e86 Binary files /dev/null and b/public/logic-linux-amd64_1 differ