```
refactor(logic): 重构服务器启动逻辑与任务状态管理 - 移除了 `gcmd` 包在 controller 中的直接使用,改为通过参数传递端口和服务器类型 - 统一使用 `GetTask` 和 `SetTask` 方法替代直接访问 `TaskList` 数组,提升代码可维护性 - 修改了战斗逻辑中部分调试打印语句,并优化战斗循环结束日志输出 - 调整了新手玩家初始化流程,默认完成新手任务4 - 更新了数据库模型字段及结构定义,如增加 `max_ts` 字段、扩展 `TaskList` 长度等 - 改进了宠物添加逻辑,采用 SQL 方式确保捕捉时间唯一递增 - 清理了无用或注释掉的旧代码块
This commit is contained in:
90
.vscode/launch.json
vendored
90
.vscode/launch.json
vendored
@@ -1,49 +1,45 @@
|
||||
{
|
||||
// 使用 IntelliSense 了解相关属性。
|
||||
// 悬停以查看现有属性的描述。
|
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
// 使用 IntelliSense 了解相关属性。
|
||||
// 悬停以查看现有属性的描述。
|
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch login-http",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"program": "${workspaceFolder}/login"
|
||||
},
|
||||
// {
|
||||
// "name": "Launch logic1",
|
||||
// "type": "go",
|
||||
// "request": "launch",
|
||||
// "mode": "auto",
|
||||
// "cwd": "${workspaceFolder}",
|
||||
// "args": ["-port=1", " -race"],
|
||||
// "program": "${workspaceFolder}/logic",
|
||||
// "console": "integratedTerminal"
|
||||
// },
|
||||
{
|
||||
"name": "Launch test server",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": ["-port=2"],
|
||||
|
||||
{
|
||||
"name": "Launch login-http",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"program": "${workspaceFolder}/login",
|
||||
|
||||
|
||||
},
|
||||
{
|
||||
"name": "Launch logic1",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": ["-port=1"," -race"],
|
||||
"program": "${workspaceFolder}/logic", "console": "integratedTerminal"
|
||||
|
||||
}, {
|
||||
"name": "Launch logic2",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": ["-port=2"],
|
||||
|
||||
"program": "${workspaceFolder}/logic",
|
||||
},
|
||||
{
|
||||
"name": "Launch login-tcp",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"args": ["-port=0"],
|
||||
"program": "${workspaceFolder}/logic",
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
"program": "${workspaceFolder}/logic"
|
||||
}
|
||||
// {
|
||||
// "name": "Launch login-tcp",
|
||||
// "type": "go",
|
||||
// "request": "launch",
|
||||
// "mode": "auto",
|
||||
// "cwd": "${workspaceFolder}",
|
||||
// "args": ["-port=0"],
|
||||
// "program": "${workspaceFolder}/logic",
|
||||
// }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"context"
|
||||
"reflect"
|
||||
|
||||
"github.com/gogf/gf/v2/os/gcmd"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
"github.com/lunixbochs/struc"
|
||||
)
|
||||
@@ -38,9 +37,8 @@ func ParseCmd[T any](a T, data []byte) T {
|
||||
//fmt.Println(data)
|
||||
}
|
||||
|
||||
func init() { //默认初始化扫描
|
||||
// 解析命令行参数
|
||||
cool.Config.PortBL = gcmd.GetOpt("port", "1").Uint16()
|
||||
func Init(isgame bool) { //默认初始化扫描
|
||||
|
||||
// 获取对象的反射值和类型
|
||||
value := reflect.ValueOf(Maincontroller)
|
||||
|
||||
@@ -60,12 +58,12 @@ func init() { //默认初始化扫描
|
||||
continue
|
||||
}
|
||||
|
||||
if cool.Config.PortBL == 0 && func_cmd > 1000 { //判断login服务器
|
||||
if !isgame && func_cmd > 1000 { //判断login服务器
|
||||
continue
|
||||
|
||||
}
|
||||
|
||||
if cool.Config.PortBL != 0 && func_cmd < 1000 { //判断login服务器
|
||||
if isgame && func_cmd < 1000 { //判断login服务器
|
||||
continue
|
||||
|
||||
}
|
||||
|
||||
@@ -121,7 +121,8 @@ func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *pla
|
||||
fight.NewFight(c, ai, func(foi *info.FightOverInfo) {
|
||||
if taskid != 0 {
|
||||
if foi.Reason == 0 && foi.WinnerId == c.Info.UserID {
|
||||
if c.Info.TaskList[taskid-1] != 3 {
|
||||
if c.GetTask(taskid) == player.Unaccepted {
|
||||
c.SetTask(taskid, player.Completed) //设置完成任务
|
||||
c.Info.TaskList[taskid-1] = 3
|
||||
|
||||
moinfo.PetList[0].Downgrade(1)
|
||||
|
||||
@@ -19,8 +19,9 @@ func (h Controller) AcceptTask(data *task.AcceptTaskInboundInfo, c *player.Playe
|
||||
// //isdaliy = true
|
||||
// }
|
||||
|
||||
if c.Info.TaskList[data.TaskId-1] == 0 {
|
||||
c.Info.TaskList[data.TaskId-1] = 1
|
||||
if c.GetTask(int(data.TaskId)) == player.Unaccepted {
|
||||
c.SetTask(int(data.TaskId), player.Accepted)
|
||||
|
||||
}
|
||||
c.Service.Task.Exec(uint32(data.TaskId), func(t *model.TaskEX) bool {
|
||||
t.Data = []uint32{}
|
||||
@@ -54,13 +55,13 @@ func (h Controller) AddTaskBuf(data *task.AddTaskBufInboundInfo, c *player.Playe
|
||||
* 完成任务
|
||||
*/
|
||||
func (h Controller) Complete_Task(data *task.CompleteTaskInboundInfo, c *player.Player) (result *task.CompleteTaskOutboundInfo, err errorcode.ErrorCode) {
|
||||
|
||||
if c.Info.TaskList[data.TaskId-1] != 1 { //如果任务没有接受或者已经完成Complete_Task
|
||||
|
||||
if c.GetTask(int(data.TaskId)) != player.Accepted { //如果任务没有接受或者已经完成Complete_Task
|
||||
return result, 0
|
||||
|
||||
}
|
||||
c.Info.TaskList[data.TaskId-1] = 3
|
||||
|
||||
c.SetTask(int(data.TaskId), player.Completed)
|
||||
|
||||
result = &task.CompleteTaskOutboundInfo{
|
||||
TaskId: data.TaskId,
|
||||
ItemList: make([]model.ItemInfo, 0),
|
||||
@@ -111,10 +112,9 @@ func (h Controller) Get_Task_Buf(data *task.GetTaskBufInboundInfo, c *player.Pla
|
||||
*/
|
||||
func (h Controller) Delete_Task(data *task.DeleteTaskInboundInfo, c *player.Player) (result *task.DeleteTaskOutboundInfo, err errorcode.ErrorCode) {
|
||||
|
||||
if c.Info.TaskList[data.TaskId-1] == 1 {
|
||||
c.Info.TaskList[data.TaskId-1] = 0
|
||||
if c.GetTask(int(data.TaskId)) == player.Accepted {
|
||||
c.SetTask(int(data.TaskId), player.Unaccepted)
|
||||
return &task.DeleteTaskOutboundInfo{TaskId: data.TaskId}, 0
|
||||
|
||||
}
|
||||
|
||||
return &task.DeleteTaskOutboundInfo{}, 0
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
|
||||
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
|
||||
"github.com/gogf/gf/v2/os/gcmd"
|
||||
"github.com/gogf/gf/v2/os/gproc"
|
||||
|
||||
"blazing/logic/service/fight"
|
||||
@@ -19,8 +20,6 @@ import (
|
||||
blservice "blazing/modules/blazing/service"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
)
|
||||
|
||||
func PprofWeb() {
|
||||
@@ -44,10 +43,11 @@ func signalHandlerForMain(sig os.Signal) {
|
||||
|
||||
func main() {
|
||||
//loadAccounts()
|
||||
if cool.IsRedisMode {
|
||||
go cool.ListenFunc(gctx.New())
|
||||
}
|
||||
|
||||
// if cool.IsRedisMode {
|
||||
// go cool.ListenFunc(gctx.New())
|
||||
// }
|
||||
// 解析命令行参数
|
||||
cool.Config.PortBL = gcmd.GetOpt("port", "1").Uint16()
|
||||
go Start(cool.Config.PortBL) //注入service
|
||||
if cool.Config.PortBL == 1 || cool.Config.PortBL == 2 { //只分析1服务器的
|
||||
go PprofWeb()
|
||||
|
||||
@@ -23,15 +23,10 @@ const (
|
||||
maxPortRetryCount = 5
|
||||
)
|
||||
|
||||
var defaultPort = gconv.Int(cool.Config.Port) //读入默认的端口
|
||||
var candidatePorts = cool.Config.GamePort
|
||||
|
||||
// determinePort 确定服务器使用的端口
|
||||
func determinePort(serverid uint16) (int, error) {
|
||||
// 服务器ID为0时使用默认端口
|
||||
if serverid == 0 {
|
||||
return defaultPort, nil
|
||||
}
|
||||
func determinePort() (int, error) {
|
||||
|
||||
// 尝试从指定端口列表中找可用端口,最多尝试maxPortRetryCount轮
|
||||
for i := 0; i < maxPortRetryCount; i++ {
|
||||
@@ -61,35 +56,22 @@ func isPortAvailable(port uint64) bool {
|
||||
|
||||
// 如果id是0,那就是login server
|
||||
func Start(serverid uint16) {
|
||||
|
||||
if serverid != 0 { //logic服务器
|
||||
// 确定端口
|
||||
port, err := determinePort(serverid)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to determine port: %v", err)
|
||||
}
|
||||
ser := socket.NewServer(
|
||||
socket.WithCORS(),
|
||||
socket.WithPort(port),
|
||||
)
|
||||
// go func() {
|
||||
t := rpc.StartClient(serverid, uint16(port), ser)
|
||||
|
||||
controller.Maincontroller.RPCClient = *t //将RPC赋值Start
|
||||
controller.Maincontroller.Port = uint16(port) //赋值服务器ID
|
||||
xmlres.Initfile()
|
||||
blservice.NewLoginServiceService().SetServerID(serverid, gconv.Uint16(port))
|
||||
ser.Boot()
|
||||
|
||||
} else {
|
||||
go rpc.StartServer()
|
||||
|
||||
//go rpcserver() //对login tcp启动
|
||||
//ants.Submit(rpcserver)
|
||||
socket.NewServer(
|
||||
socket.WithCORS(),
|
||||
socket.WithPort(defaultPort),
|
||||
).Boot()
|
||||
// 确定端口
|
||||
port, err := determinePort()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to determine port: %v", err)
|
||||
}
|
||||
ser := socket.NewServer(
|
||||
socket.WithCORS(),
|
||||
socket.WithPort(port),
|
||||
)
|
||||
// go func() {
|
||||
t := rpc.StartClient(serverid, uint16(port), ser)
|
||||
|
||||
controller.Maincontroller.RPCClient = *t //将RPC赋值Start
|
||||
controller.Maincontroller.Port = uint16(port) //赋值服务器ID
|
||||
controller.Init(true)
|
||||
xmlres.Initfile()
|
||||
blservice.NewLoginServiceService().SetServerID(serverid, gconv.Uint16(port))
|
||||
ser.Boot()
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ func (our *Input) AddEffect(in *Input, e Effect) Effect {
|
||||
e.Alive(true) //添加后默认激活
|
||||
//todo 免疫
|
||||
//TODO 先激活
|
||||
fmt.Println("产生回合数", e.ID(), e.Duration())
|
||||
//fmt.Println("产生回合数", e.ID(), e.Duration())
|
||||
// 如果已有同 ID 的效果,尝试叠加
|
||||
for _, v := range our.Effects {
|
||||
if v == e {
|
||||
|
||||
@@ -93,7 +93,6 @@ func (f *FightC) battleLoop() {
|
||||
//<-time.After(1000)
|
||||
f.Broadcast(func(ff *input.Input) {
|
||||
|
||||
fmt.Println("战斗结束信息", ff.UserID)
|
||||
ff.Player.SendPackCmd(2506, &f.FightOverInfo)
|
||||
|
||||
ff.Player.QuitFight()
|
||||
@@ -102,7 +101,7 @@ func (f *FightC) battleLoop() {
|
||||
})
|
||||
|
||||
// close(f.actionChan)
|
||||
fmt.Println("战斗循环结束")
|
||||
fmt.Println(f.ownerID, "战斗循环结束")
|
||||
close(f.over)
|
||||
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ func (lw *Player) CompleteLogin() {
|
||||
|
||||
}
|
||||
if lw.IsNewPlayer() { //重置新手地图,放到机械仓
|
||||
lw.SetTask(4, Completed) //设置新手任务默认完成
|
||||
lw.Info.MapID = 8
|
||||
if len(lw.Info.PetList) == 0 {
|
||||
rr := lw.Service.Pet.PetInfo(0)
|
||||
@@ -87,7 +88,7 @@ func (lw *Player) CompleteLogin() {
|
||||
func (lw *Player) IsNewPlayer() bool {
|
||||
// 遍历84到87的索引
|
||||
for i := 84; i <= 87; i++ {
|
||||
if lw.Info.TaskList[i] != 3 {
|
||||
if lw.GetTask(i) != Completed {
|
||||
return true // 只要有一个不等于3,就返回true
|
||||
}
|
||||
}
|
||||
|
||||
45
logic/service/player/task.go
Normal file
45
logic/service/player/task.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package player
|
||||
|
||||
import "fmt"
|
||||
|
||||
// TaskStatus 任务状态(与 AS3 对应)
|
||||
type TaskStatus uint8
|
||||
|
||||
const (
|
||||
Unaccepted TaskStatus = 0 // 未接受(AS3 中 0 或 2 映射至此)
|
||||
Accepted TaskStatus = 1 // 已接受
|
||||
Completed TaskStatus = 3 // 已完成
|
||||
Reserved TaskStatus = 2 // 预留(AS3 中映射为未接受)
|
||||
)
|
||||
|
||||
// SetTask 设置第 i 个任务的状态(0 ≤ i < 2000)
|
||||
func (m *Player) SetTask(i int, status TaskStatus) error {
|
||||
i-- //下标减1
|
||||
if i < 0 || i >= 4000 {
|
||||
return fmt.Errorf("index out of range: %d (must be 0-1999)", i)
|
||||
}
|
||||
|
||||
byteIdx := i / 4
|
||||
bitOffset := (i % 4) * 2
|
||||
|
||||
// 清除原有 2 位
|
||||
m.Info.TaskList[byteIdx] &^= 0x3 << bitOffset
|
||||
|
||||
// 设置新状态(确保只取低 2 位)
|
||||
m.Info.TaskList[byteIdx] |= byte(status&0x3) << bitOffset
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetTask 获取第 i 个任务的状态
|
||||
func (m *Player) GetTask(i int) TaskStatus {
|
||||
i-- //下标减1
|
||||
// if i < 0 || i >= 2000 {
|
||||
// return 0, fmt.Errorf("index out of range: %d", i)
|
||||
// }
|
||||
|
||||
byteIdx := i / 4
|
||||
bitOffset := (i % 4) * 2
|
||||
|
||||
return TaskStatus((m.Info.TaskList[byteIdx] >> bitOffset) & 0x3)
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
|
||||
"blazing/cool"
|
||||
|
||||
@@ -26,14 +25,15 @@ var (
|
||||
go cool.ListenFunc(ctx)
|
||||
}
|
||||
//go robot()
|
||||
go reg()
|
||||
s := g.Server()
|
||||
s.Use(Limiter, ghttp.MiddlewareHandlerResponse)
|
||||
s.EnableAdmin()
|
||||
s.SetServerAgent(cool.Config.Name)
|
||||
s.BindHookHandler("/*", ghttp.HookBeforeServe, beforeServeHook)
|
||||
runtime.SetMutexProfileFraction(1) // (非必需)开启对锁调用的跟踪
|
||||
runtime.SetBlockProfileRate(1) // (非必需)开启对阻塞操作的跟踪
|
||||
s.EnablePProf()
|
||||
// runtime.SetMutexProfileFraction(1) // (非必需)开启对锁调用的跟踪
|
||||
// runtime.SetBlockProfileRate(1) // (非必需)开启对阻塞操作的跟踪
|
||||
// s.EnablePProf()
|
||||
// 如果存在 data/cool-admin-vue/dist 目录,则设置为主目录
|
||||
if gfile.IsDir("public") {
|
||||
s.SetServerRoot("public")
|
||||
|
||||
23
login/internal/cmd/reg.go
Normal file
23
login/internal/cmd/reg.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"blazing/common/rpc"
|
||||
"blazing/common/socket"
|
||||
"blazing/cool"
|
||||
"blazing/logic/controller"
|
||||
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
var defaultPort = gconv.Int(cool.Config.Port) //读入默认的端口
|
||||
func reg() {
|
||||
go rpc.StartServer()
|
||||
controller.Init(false)
|
||||
//go rpcserver() //对login tcp启动
|
||||
//ants.Submit(rpcserver)
|
||||
socket.NewServer(
|
||||
socket.WithCORS(),
|
||||
socket.WithPort(defaultPort),
|
||||
).Boot()
|
||||
|
||||
}
|
||||
@@ -58,7 +58,10 @@ func main() {
|
||||
//service.TestSendVerificationCode()
|
||||
|
||||
// t := model.GenPetInfo(1, 31, 1, 1, 1, 1)
|
||||
// service.NewUserService(10001).Pet.PetAdd(*t)
|
||||
|
||||
// for i := 0; i < 1000; i++ {
|
||||
// service.NewUserService(10001).Pet.PetAdd(t)
|
||||
// }
|
||||
// service.NewUserService(10001).Pet.PetInfo_One_exec(t.CatchTime, func(pe *model.PetEX) {
|
||||
// fmt.Println(pe.CreateTime)
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ type BaseSysUser struct {
|
||||
Email *string `gorm:"column:email;type:varchar(255)" json:"email"` // 邮箱
|
||||
Status *int32 `gorm:"column:status;not null;default:1" json:"status"` // 状态 0:禁用 1:启用
|
||||
GoldBean float64 `gorm:"column:goldBean;type:decimal;not null;default:0" json:"goldBean"`
|
||||
Remark *string `gorm:"column:remark;type:varchar(255)" json:"remark"` // 备注
|
||||
Debug int32 `gorm:"column:debug;type:int;not null;default:0" json:"debug"` // 是否可以进入2服
|
||||
|
||||
Remark *string `gorm:"column:remark;type:varchar(255)" json:"remark"` // 备注
|
||||
Debug int32 `gorm:"column:debug;type:int;not null;default:0" json:"debug"` // 是否可以进入2服 测试服
|
||||
Maxts uint32 `gorm:"column:max_ts;type:int;not null;default:0" json:"max_ts"` //最后生成的时间记录表
|
||||
}
|
||||
|
||||
// TableName BaseSysUser's table name
|
||||
|
||||
@@ -47,7 +47,7 @@ func (c *BaseSysPermsService) RefreshPerms(ctx context.Context, userId uint) (er
|
||||
)
|
||||
cool.CacheManager.Set(ctx, "admin:perms:"+gconv.String(userId), perms, 0)
|
||||
// 更新部门权限
|
||||
departments := baseSysDepartmentService.GetByRoleIds(roleIds, userId == 1)
|
||||
departments := baseSysDepartmentService.GetByRoleIds(roleIds, userId == 10001)
|
||||
cool.CacheManager.Set(ctx, "admin:department:"+gconv.String(userId), departments, 0)
|
||||
|
||||
return
|
||||
|
||||
22
modules/blazing/controller/admin/talkconfig.go
Normal file
22
modules/blazing/controller/admin/talkconfig.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"blazing/cool"
|
||||
"blazing/modules/blazing/service"
|
||||
)
|
||||
|
||||
type TalkConfigController struct {
|
||||
*cool.Controller
|
||||
}
|
||||
|
||||
func init() {
|
||||
var task_info_controller = &TalkConfigController{
|
||||
&cool.Controller{
|
||||
Prefix: "/admin/sun/talkconfig",
|
||||
Api: []string{"Add", "Delete", "Update", "Info", "List", "Page"},
|
||||
Service: service.NewTalkConfigService(),
|
||||
},
|
||||
}
|
||||
// 注册路由
|
||||
cool.RegisterController(task_info_controller)
|
||||
}
|
||||
@@ -72,38 +72,38 @@ type PlayerInfo struct {
|
||||
//LastResetTime time.Time `struc:"skip" json:"last_reset_time"` // 重置时间,比如电池和每日任务
|
||||
OnlineTime uint32 `struc:"skip" json:"online_time"` //在线分钟数
|
||||
// OutInfo 字段
|
||||
UserID uint32 `struc:"uint32" json:"user_id"` // 米米号 通过sid拿到
|
||||
RegisterTime uint32 `struc:"uint32" json:"register_time"` // 注册时间(秒时间戳)
|
||||
Nick string `struc:"[16]byte" default:"seer" json:"nick"` // 16字节昵称
|
||||
Vip uint16 `struc:"uint16" json:"vip"` // 固定0
|
||||
Viped uint16 `struc:"uint16" default:"15" json:"viped"` // 固定15
|
||||
DSFlag uint32 `struc:"uint32" json:"ds_flag"` // 固定0
|
||||
Color uint32 `struc:"uint32" json:"color"` // 机器人颜色RGB颜色值(uint32,实际为3个uint8)
|
||||
Texture uint32 `struc:"uint32" json:"texture"` // 固定0
|
||||
Energy uint32 `struc:"uint32" default:"3000" json:"energy"` // 固定3000
|
||||
Coins uint32 `struc:"uint32" json:"coins"` // 赛尔豆
|
||||
EVPool uint32 `struc:"uint32" json:"ev_pool"` //累计学习力
|
||||
FightBadge uint32 `struc:"uint32" json:"fight_badge"` // 固定0
|
||||
MapID uint32 `struc:"uint32" default:"1" json:"map_id"` // 上线地图ID
|
||||
Pos Pos `json:"pos"` // 坐标
|
||||
TimeToday uint32 `struc:"uint32" default:"0" json:"time_today"` // 已消耗时间(秒)
|
||||
TimeLimit uint32 `struc:"uint32" default:"43200" json:"time_limit"` // 总电池限制(秒)
|
||||
IsClothHalfDay byte `struc:"byte" json:"is_cloth_half_day"` // 活动标志0/1
|
||||
IsRoomHalfDay byte `struc:"byte" json:"is_room_half_day"` // 活动标志0/1
|
||||
IFortressHalfDay byte `struc:"byte" json:"i_fortress_half_day"` // 活动标志0/1
|
||||
IsHQHalfDay byte `struc:"byte" json:"is_hq_half_day"` // 活动标志0/1
|
||||
LoginCount uint32 `struc:"uint32" json:"login_count"` // 固定0
|
||||
Inviter uint32 `struc:"uint32" json:"inviter"` // 固定0
|
||||
NewInviteeCount uint32 `struc:"uint32" json:"new_invitee_count"` // 固定0
|
||||
VipLevel uint32 `struc:"uint32" default:"8" json:"vip_level"` // 固定8
|
||||
VipValue uint32 `struc:"uint32" default:"80000" json:"vip_value"` // 固定80000
|
||||
VipStage uint32 `struc:"uint32" default:"1" json:"vip_stage"` // 超no的外形等级建议固定1
|
||||
AutoCharge uint32 `struc:"uint32" default:"1" json:"auto_charge"` // nono是否自动充电
|
||||
VipEndTime uint32 `struc:"uint32" default:"4294967295" json:"vip_end_time"` // 超no的结束时间建议尽可能大
|
||||
FreshManBonus uint32 `struc:"uint32" json:"fresh_man_bonus"` // 邀请活动建议先给固定值0
|
||||
NonoChipList [80]byte `struc:"[80]byte" json:"-"` // 超no芯片列表
|
||||
DailyResArr [50]byte `struc:"[50]byte" default:"0" json:"daily_res_arr"` // 每日任务状态 40+是谱尼的
|
||||
Study struct {
|
||||
UserID uint32 `struc:"uint32" json:"user_id"` // 米米号 通过sid拿到
|
||||
RegisterTime uint32 `struc:"uint32" json:"register_time"` // 注册时间(秒时间戳)
|
||||
Nick string `struc:"[16]byte" default:"seer" json:"nick"` // 16字节昵称
|
||||
Vip uint16 `struc:"uint16" json:"vip"` // 固定0
|
||||
Viped uint16 `struc:"uint16" default:"15" json:"viped"` // 固定15
|
||||
DSFlag uint32 `struc:"uint32" json:"ds_flag"` // 固定0
|
||||
Color uint32 `struc:"uint32" json:"color"` // 机器人颜色RGB颜色值(uint32,实际为3个uint8)
|
||||
Texture uint32 `struc:"uint32" json:"texture"` // 固定0
|
||||
Energy uint32 `struc:"uint32" default:"3000" json:"energy"` // 固定3000
|
||||
Coins uint32 `struc:"uint32" json:"coins"` // 赛尔豆
|
||||
EVPool uint32 `struc:"uint32" json:"ev_pool"` //累计学习力
|
||||
FightBadge uint32 `struc:"uint32" json:"fight_badge"` // 固定0
|
||||
MapID uint32 `struc:"uint32" default:"1" json:"map_id"` // 上线地图ID
|
||||
Pos Pos `json:"pos"` // 坐标
|
||||
TimeToday uint32 `struc:"uint32" default:"0" json:"time_today"` // 已消耗时间(秒)
|
||||
TimeLimit uint32 `struc:"uint32" default:"43200" json:"time_limit"` // 总电池限制(秒)
|
||||
IsClothHalfDay byte `struc:"byte" json:"is_cloth_half_day"` // 活动标志0/1
|
||||
IsRoomHalfDay byte `struc:"byte" json:"is_room_half_day"` // 活动标志0/1
|
||||
IFortressHalfDay byte `struc:"byte" json:"i_fortress_half_day"` // 活动标志0/1
|
||||
IsHQHalfDay byte `struc:"byte" json:"is_hq_half_day"` // 活动标志0/1
|
||||
LoginCount uint32 `struc:"uint32" json:"login_count"` // 固定0
|
||||
Inviter uint32 `struc:"uint32" json:"inviter"` // 固定0
|
||||
NewInviteeCount uint32 `struc:"uint32" json:"new_invitee_count"` // 固定0
|
||||
VipLevel uint32 `struc:"uint32" default:"8" json:"vip_level"` // 固定8
|
||||
VipValue uint32 `struc:"uint32" default:"80000" json:"vip_value"` // 固定80000
|
||||
VipStage uint32 `struc:"uint32" default:"1" json:"vip_stage"` // 超no的外形等级建议固定1
|
||||
AutoCharge uint32 `struc:"uint32" default:"1" json:"auto_charge"` // nono是否自动充电
|
||||
VipEndTime uint32 `struc:"uint32" default:"4294967295" json:"vip_end_time"` // 超no的结束时间建议尽可能大
|
||||
FreshManBonus uint32 `struc:"uint32" json:"fresh_man_bonus"` // 邀请活动建议先给固定值0
|
||||
//NonoChipList [80]byte `struc:"[80]byte" json:"-"` // 超no芯片列表
|
||||
DailyResArr [50]byte `struc:"[50]byte" default:"0" json:"daily_res_arr"` // 每日任务状态 40+是谱尼的
|
||||
Study struct {
|
||||
TeacherID uint32 `struc:"uint32" json:"teacher_id"` // 教官id
|
||||
|
||||
StudentID uint32 `struc:"uint32" json:"student_id"` // 学员id
|
||||
@@ -144,16 +144,16 @@ type PlayerInfo struct {
|
||||
Nick string `struc:"[16]byte" default:"nono" json:"nono_nick"` // nono名字(16字节)
|
||||
}
|
||||
|
||||
TeamInfo TeamInfo `struc:"struct" json:"team_info"` // 战队信息24字节
|
||||
TeamPkInfo TeamPKInfo `struc:"struct" json:"team_pk_info"` // 8字节
|
||||
Reserved byte `struc:"byte" json:"reserved"` // 1字节无内容
|
||||
Badge uint32 `struc:"uint32" default:"0" json:"badge"` // 默认0
|
||||
Reserved1 [27]byte `struc:"[27]byte" default:"3" json:"reserved1"` // 27字节默认3
|
||||
TaskList [500]byte `struc:"[500]byte" default:"0" json:"task_list"` // 任务状态数组500字节,默认3
|
||||
PetListCount uint32 `struc:"sizeof=PetList" json:"pet_list_count"` // 精灵列表长度
|
||||
PetList []PetInfo ` json:"pet_list"` // 精灵背包内信息
|
||||
ClothesCount uint32 `struc:"sizeof=Clothes" json:"clothes_count"` // 穿戴装备数量
|
||||
Clothes []PeopleItemInfo ` json:"clothes"` // 穿戴装备
|
||||
TeamInfo TeamInfo `struc:"struct" json:"team_info"` // 战队信息24字节
|
||||
TeamPkInfo TeamPKInfo `struc:"struct" json:"team_pk_info"` // 8字节
|
||||
Reserved byte `struc:"byte" json:"reserved"` // 1字节无内容
|
||||
Badge uint32 `struc:"uint32" default:"0" json:"badge"` // 默认0
|
||||
Reserved1 [27]byte `struc:"[27]byte" default:"3" json:"reserved1"` // 27字节默认3
|
||||
TaskList [1000]byte `struc:"[1000]byte" default:"0" json:"task_list"` // 任务状态数组500字节,默认3
|
||||
PetListCount uint32 `struc:"sizeof=PetList" json:"pet_list_count"` // 精灵列表长度
|
||||
PetList []PetInfo ` json:"pet_list"` // 精灵背包内信息
|
||||
ClothesCount uint32 `struc:"sizeof=Clothes" json:"clothes_count"` // 穿戴装备数量
|
||||
Clothes []PeopleItemInfo ` json:"clothes"` // 穿戴装备
|
||||
}
|
||||
|
||||
// TableName PlayerInfo's table name
|
||||
|
||||
55
modules/blazing/model/talkconfig.go
Normal file
55
modules/blazing/model/talkconfig.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"blazing/cool" // 沿用你项目中已有的基础Model包
|
||||
)
|
||||
|
||||
// 表名常量(遵循项目现有命名规范)
|
||||
const TableNameMineralCollectionConfig = "mineral_collection_config"
|
||||
|
||||
// MineralCollectionConfig 挖矿/采集/采摘矿产配置表Model定义
|
||||
// 字段完全匹配数据表结构,包含最小/最大产出核心字段
|
||||
type MineralCollectionConfig struct {
|
||||
*cool.Model // 嵌入基础Model,包含id(主键)、createTime、updateTime等通用字段
|
||||
|
||||
// MapID 矿产所在地图ID
|
||||
MapID uint32 `gorm:"column:map_id;not null;index:idx_mineral_collection_config_map_id;comment:矿产所在地图ID" json:"map_id"`
|
||||
Type uint32 `gorm:"column:type;not null;index:idx_mineral_collection_config_type;comment:类型" json:"type"`
|
||||
|
||||
// DailyCollectCount 每日可采集次数
|
||||
DailyCollectCount uint32 `gorm:"column:daily_collect_count;not null;comment:每日可采集次数" json:"daily_collect_count"`
|
||||
|
||||
// ItemID 物品编号(对应道具系统ID)
|
||||
ItemID string `gorm:"column:item_id;type:varchar(16);not null;index:idx_mineral_collection_config_item_id;comment:物品编号(对应道具系统ID)" json:"item_id"`
|
||||
// ItemMinCount 单次采集最小产出数量
|
||||
ItemMinCount uint32 `gorm:"column:item_min_count;not null;comment:单次采集最小产出数量" json:"item_min_count"`
|
||||
// ItemMaxCount 单次采集最大产出数量
|
||||
ItemMaxCount uint32 `gorm:"column:item_max_count;not null;comment:单次采集最大产出数量" json:"item_max_count"`
|
||||
// Description 矿产描述
|
||||
Description string `gorm:"column:description;type:varchar(128); comment:矿产描述" json:"description"`
|
||||
}
|
||||
|
||||
// TableName 指定数据表名(必须匹配数据库表名,遵循项目规范)
|
||||
func (*MineralCollectionConfig) TableName() string {
|
||||
return TableNameMineralCollectionConfig
|
||||
}
|
||||
|
||||
// GroupName 指定表分组(与项目现有表保持一致,默认分组)
|
||||
func (*MineralCollectionConfig) GroupName() string {
|
||||
return "default"
|
||||
}
|
||||
|
||||
// NewMineralCollectionConfig 创建挖矿配置表实例(初始化基础Model)
|
||||
// 保证通用字段(createTime/updateTime)被正确初始化
|
||||
func NewMineralCollectionConfig() *MineralCollectionConfig {
|
||||
return &MineralCollectionConfig{
|
||||
Model: cool.NewModel(), // 调用基础Model的初始化方法
|
||||
}
|
||||
}
|
||||
|
||||
// init 程序启动时自动创建数据表(与项目现有表初始化逻辑一致)
|
||||
// 若项目有统一的表初始化入口,可将此逻辑迁移至对应位置
|
||||
func init() {
|
||||
// 自动创建表(不存在则创建,已存在则不操作)
|
||||
cool.CreateTable(&MineralCollectionConfig{})
|
||||
}
|
||||
@@ -37,11 +37,11 @@ func (s *InfoService) Reg(nick string, color uint32) {
|
||||
//设置用户信息
|
||||
t.Data = model.NewPlayerInfo()
|
||||
t.Data.Nick = nick
|
||||
t.Data.TaskList[3] = 3 //新手任务
|
||||
for i := 0; i < 80; i++ { //超NO芯片填充
|
||||
|
||||
t.Data.NonoChipList[i] = 255
|
||||
}
|
||||
// for i := 0; i < 80; i++ { //超NO芯片填充
|
||||
|
||||
// t.Data.NonoChipList[i] = 255
|
||||
// }
|
||||
|
||||
t.Data.Color = color
|
||||
t.Data.RegisterTime = uint32(time.Now().Unix()) //写入注册时间
|
||||
|
||||
@@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"blazing/cool"
|
||||
"blazing/modules/base/service"
|
||||
"blazing/modules/blazing/model"
|
||||
"context"
|
||||
"fmt"
|
||||
@@ -64,24 +65,50 @@ func (s *PetService) Pet_del(cachetime uint32) {
|
||||
cool.DBM(s.Model).Where("player_id", s.userid).Where("catch_time", cachetime).Delete()
|
||||
|
||||
}
|
||||
|
||||
// 精灵真正添加后的捕捉时间才是真正的时间
|
||||
func (s *PetService) PetAdd(y *model.PetInfo) {
|
||||
sql := fmt.Sprintf(`
|
||||
UPDATE %s
|
||||
SET max_ts = CASE
|
||||
WHEN max_ts < EXTRACT(EPOCH FROM NOW())::INT THEN EXTRACT(EPOCH FROM NOW())::INT
|
||||
ELSE max_ts + 1
|
||||
END
|
||||
WHERE id = ? AND deleted_at IS NULL
|
||||
RETURNING max_ts;
|
||||
`, service.NewBaseSysUserService().Model.TableName())
|
||||
|
||||
for {
|
||||
m1 := cool.DBM(s.Model).Where("player_id", s.userid)
|
||||
var player model.PetEX
|
||||
player.PlayerID = s.userid
|
||||
player.Data = *y
|
||||
player.CatchTime = y.CatchTime
|
||||
player.Free = 0
|
||||
// 执行 Raw SQL 并扫描返回值
|
||||
ret, err := cool.DBM(service.NewBaseSysUserService().Model).Raw(sql, s.userid).All()
|
||||
//fmt.Println(ret, err)
|
||||
y.CatchTime = ret.Array()[0].Uint32()
|
||||
m1 := cool.DBM(s.Model).Where("player_id", s.userid)
|
||||
var player model.PetEX
|
||||
player.PlayerID = s.userid
|
||||
player.Data = *y
|
||||
player.CatchTime = y.CatchTime
|
||||
player.Free = 0
|
||||
|
||||
_, err := m1.Insert(player)
|
||||
if err != nil {
|
||||
fmt.Println("添加失败id自增1继续添加")
|
||||
y.CatchTime += 1 //自增保持时间排序
|
||||
continue
|
||||
}
|
||||
break
|
||||
_, err = m1.Insert(player)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// for {
|
||||
// m1 := cool.DBM(s.Model).Where("player_id", s.userid)
|
||||
// var player model.PetEX
|
||||
// player.PlayerID = s.userid
|
||||
// player.Data = *y
|
||||
// player.CatchTime = y.CatchTime
|
||||
// player.Free = 0
|
||||
|
||||
// _, err := m1.Insert(player)
|
||||
// if err != nil {
|
||||
// fmt.Println("添加失败id自增1继续添加")
|
||||
// y.CatchTime += 1 //自增保持时间排序
|
||||
// continue
|
||||
// }
|
||||
// break
|
||||
// }
|
||||
|
||||
}
|
||||
func (s *PetService) ModifyBefore(ctx context.Context, method string, param map[string]interface{}) (err error) {
|
||||
|
||||
@@ -5,6 +5,18 @@ import (
|
||||
"blazing/modules/blazing/model"
|
||||
)
|
||||
|
||||
type TalkConfigService struct {
|
||||
*cool.Service
|
||||
}
|
||||
|
||||
func NewTalkConfigService() *TalkConfigService {
|
||||
return &TalkConfigService{
|
||||
|
||||
Service: &cool.Service{Model: model.NewMineralCollectionConfig()},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type TalkService struct {
|
||||
BaseService
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user