mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-02-04 13:02:26 +08:00
大量优化
This commit is contained in:
@@ -67,8 +67,6 @@ type FightMsg struct {
|
||||
const (
|
||||
ServerAppidBindNotify = iota // 玩家连接绑定的各个服务器appid通知
|
||||
ServerUserOnlineStateChangeNotify // 广播玩家上线和离线状态以及所在GS的appid
|
||||
ServerUserBaseInfoReq // 跨服玩家基础数据请求
|
||||
ServerUserBaseInfoRsp // 跨服玩家基础数据响应
|
||||
ServerUserGsChangeNotify // 跨服玩家迁移通知
|
||||
ServerUserMpReq // 跨服多人世界相关请求
|
||||
ServerUserMpRsp // 跨服多人世界相关响应
|
||||
@@ -80,7 +78,6 @@ type ServerMsg struct {
|
||||
FightServerAppId string `msgpack:"FightServerAppId"`
|
||||
UserId uint32 `msgpack:"UserId"`
|
||||
IsOnline bool `msgpack:"IsOnline"`
|
||||
UserBaseInfo *UserBaseInfo `msgpack:"UserBaseInfo"`
|
||||
GameServerAppId string `msgpack:"GameServerAppId"`
|
||||
JoinHostUserId uint32 `msgpack:"JoinHostUserId"`
|
||||
UserMpInfo *UserMpInfo `msgpack:"UserMpInfo"`
|
||||
@@ -94,17 +91,15 @@ type OriginInfo struct {
|
||||
}
|
||||
|
||||
type UserBaseInfo struct {
|
||||
OriginInfo *OriginInfo `msgpack:"OriginInfo"`
|
||||
UserId uint32 `msgpack:"UserId"`
|
||||
Nickname string `msgpack:"Nickname"`
|
||||
PlayerLevel uint32 `msgpack:"PlayerLevel"`
|
||||
MpSettingType uint8 `msgpack:"MpSettingType"`
|
||||
NameCardId uint32 `msgpack:"NameCardId"`
|
||||
Signature string `msgpack:"Signature"`
|
||||
HeadImageId uint32 `msgpack:"HeadImageId"`
|
||||
WorldPlayerNum uint32 `msgpack:"WorldPlayerNum"`
|
||||
WorldLevel uint32 `msgpack:"WorldLevel"`
|
||||
Birthday []uint8 `msgpack:"Birthday"`
|
||||
UserId uint32 `msgpack:"UserId"`
|
||||
Nickname string `msgpack:"Nickname"`
|
||||
PlayerLevel uint32 `msgpack:"PlayerLevel"`
|
||||
MpSettingType uint8 `msgpack:"MpSettingType"`
|
||||
NameCardId uint32 `msgpack:"NameCardId"`
|
||||
Signature string `msgpack:"Signature"`
|
||||
HeadImageId uint32 `msgpack:"HeadImageId"`
|
||||
WorldPlayerNum uint32 `msgpack:"WorldPlayerNum"`
|
||||
WorldLevel uint32 `msgpack:"WorldLevel"`
|
||||
}
|
||||
|
||||
type UserMpInfo struct {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package api
|
||||
|
||||
type ComboTokenReq struct {
|
||||
AppID int `json:"app_id"`
|
||||
ChannelID int `json:"channel_id"`
|
||||
AppID any `json:"app_id"`
|
||||
ChannelID any `json:"channel_id"`
|
||||
Data string `json:"data"`
|
||||
Device string `json:"device"`
|
||||
Sign string `json:"sign"`
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package api
|
||||
|
||||
type ComboTokenRes struct {
|
||||
type ComboTokenRsp struct {
|
||||
Message string `json:"message"`
|
||||
Retcode int `json:"retcode"`
|
||||
Data LoginData `json:"data"`
|
||||
@@ -16,8 +16,8 @@ type LoginData struct {
|
||||
FatigueRemind any `json:"fatigue_remind"`
|
||||
}
|
||||
|
||||
func NewComboTokenRes() (r *ComboTokenRes) {
|
||||
r = &ComboTokenRes{
|
||||
func NewComboTokenRsp() (r *ComboTokenRsp) {
|
||||
r = &ComboTokenRsp{
|
||||
Message: "",
|
||||
Retcode: 0,
|
||||
Data: LoginData{
|
||||
@@ -44,21 +44,25 @@ func (c *Controller) getClientVersionByName(versionName string) (int, string) {
|
||||
}
|
||||
versionSlice := reg.FindAllString(versionName, -1)
|
||||
version := 0
|
||||
for index := 0; index < len(versionSlice); index++ {
|
||||
v, err := strconv.Atoi(versionSlice[index])
|
||||
for index, value := range versionSlice {
|
||||
v, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
logger.Error("parse client version error: %v", err)
|
||||
return 0, ""
|
||||
}
|
||||
for i := 0; i < len(versionSlice)-1-index; i++ {
|
||||
if v >= 10 {
|
||||
// 测试版本
|
||||
if index != 2 {
|
||||
logger.Error("invalid client version")
|
||||
return 0, ""
|
||||
}
|
||||
v /= 10
|
||||
}
|
||||
for i := 0; i < 2-index; i++ {
|
||||
v *= 10
|
||||
}
|
||||
version += v
|
||||
}
|
||||
if version >= 1000 {
|
||||
// 测试版本
|
||||
version /= 10
|
||||
}
|
||||
return version, strconv.Itoa(version)
|
||||
}
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ func (c *Controller) v2Login(context *gin.Context) {
|
||||
logger.Error("ParseInt uid error: %v", err)
|
||||
return
|
||||
}
|
||||
responseData := api.NewComboTokenRes()
|
||||
responseData := api.NewComboTokenRsp()
|
||||
account, err := c.dao.QueryAccountByField("accountID", uid)
|
||||
if account == nil || account.Token != loginData.Token {
|
||||
responseData.Retcode = -201
|
||||
|
||||
BIN
doc/HK4E登录流程.jpg
BIN
doc/HK4E登录流程.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 220 KiB |
@@ -304,10 +304,16 @@ func initClientCmdProtoMap() {
|
||||
|
||||
func GetClientProtoObjByName(protoObjName string) pb.Message {
|
||||
if !config.CONF.Hk4e.ClientProtoProxyEnable {
|
||||
return &proto.NullMsg{}
|
||||
logger.Error("client proto proxy func not enable")
|
||||
return nil
|
||||
}
|
||||
clientProtoObj := ClientCmdProtoMapRefValue.MethodByName(
|
||||
"GetClientProtoObjByName",
|
||||
).Call([]reflect.Value{reflect.ValueOf(protoObjName)})[0].Interface().(pb.Message)
|
||||
fn := ClientCmdProtoMapRefValue.MethodByName("GetClientProtoObjByName")
|
||||
ret := fn.Call([]reflect.Value{reflect.ValueOf(protoObjName)})
|
||||
obj := ret[0].Interface()
|
||||
if obj == nil {
|
||||
logger.Error("try to get a not exist proto obj, protoObjName: %v", protoObjName)
|
||||
return nil
|
||||
}
|
||||
clientProtoObj := obj.(pb.Message)
|
||||
return clientProtoObj
|
||||
}
|
||||
|
||||
@@ -13,11 +13,14 @@ func TestClientProtoGen(t *testing.T) {
|
||||
}
|
||||
nameList := make([]string, 0)
|
||||
for _, entry := range dir {
|
||||
split := strings.Split(entry.Name(), ".")
|
||||
if len(split) != 2 || split[1] != "proto" {
|
||||
if entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
nameList = append(nameList, split[0])
|
||||
split := strings.Split(entry.Name(), ".")
|
||||
if len(split) < 2 || split[len(split)-1] != "proto" {
|
||||
continue
|
||||
}
|
||||
nameList = append(nameList, split[len(split)-2])
|
||||
}
|
||||
|
||||
fileData := "package client_proto\n"
|
||||
|
||||
@@ -129,6 +129,7 @@ func (k *KcpConnectManager) acceptHandle(listener *kcp.Listener) {
|
||||
pathfindingServerAppId: "",
|
||||
changeGameServer: false,
|
||||
joinHostUserId: 0,
|
||||
useMagicSeed: false,
|
||||
}
|
||||
go k.recvHandle(session)
|
||||
go k.sendHandle(session)
|
||||
@@ -228,6 +229,7 @@ type Session struct {
|
||||
pathfindingServerAppId string
|
||||
changeGameServer bool
|
||||
joinHostUserId uint32
|
||||
useMagicSeed bool
|
||||
}
|
||||
|
||||
// 接收
|
||||
@@ -297,33 +299,15 @@ func (k *KcpConnectManager) sendHandle(session *Session) {
|
||||
break
|
||||
}
|
||||
if session.changeXorKeyFin == false && protoMsg.CmdId == cmd.GetPlayerTokenRsp {
|
||||
// XOR密钥切换
|
||||
logger.Debug("change session xor key, convId: %v", convId)
|
||||
session.changeXorKeyFin = true
|
||||
keyBlock := random.NewKeyBlock(session.seed)
|
||||
keyBlock := random.NewKeyBlock(session.seed, session.useMagicSeed)
|
||||
xorKey := keyBlock.XorKey()
|
||||
key := make([]byte, 4096)
|
||||
copy(key, xorKey[:])
|
||||
session.xorKey = key
|
||||
}
|
||||
if protoMsg.CmdId == cmd.PlayerLoginRsp {
|
||||
logger.Debug("session active, convId: %v", convId)
|
||||
session.connState = ConnActive
|
||||
// 通知GS玩家各个服务器的appid
|
||||
serverMsg := new(mq.ServerMsg)
|
||||
serverMsg.UserId = session.userId
|
||||
if session.changeGameServer {
|
||||
serverMsg.JoinHostUserId = session.joinHostUserId
|
||||
session.changeGameServer = false
|
||||
session.joinHostUserId = 0
|
||||
} else {
|
||||
serverMsg.FightServerAppId = session.fightServerAppId
|
||||
}
|
||||
k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeServer,
|
||||
EventId: mq.ServerAppidBindNotify,
|
||||
ServerMsg: serverMsg,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -295,8 +295,13 @@ func (k *KcpConnectManager) encodeProtoToPayload(protoObj pb.Message) (cmdId uin
|
||||
}
|
||||
|
||||
func (k *KcpConnectManager) getClientProtoObjByName(protoObjName string) pb.Message {
|
||||
clientProtoObj := k.clientCmdProtoMapRefValue.MethodByName(
|
||||
"GetClientProtoObjByName",
|
||||
).Call([]reflect.Value{reflect.ValueOf(protoObjName)})[0].Interface().(pb.Message)
|
||||
fn := k.clientCmdProtoMapRefValue.MethodByName("GetClientProtoObjByName")
|
||||
ret := fn.Call([]reflect.Value{reflect.ValueOf(protoObjName)})
|
||||
obj := ret[0].Interface()
|
||||
if obj == nil {
|
||||
logger.Error("try to get a not exist proto obj, protoObjName: %v", protoObjName)
|
||||
return nil
|
||||
}
|
||||
clientProtoObj := obj.(pb.Message)
|
||||
return clientProtoObj
|
||||
}
|
||||
|
||||
@@ -164,13 +164,32 @@ func (k *KcpConnectManager) sendMsgHandle() {
|
||||
}
|
||||
kcpRawSendChan := session.kcpRawSendChan
|
||||
if kcpRawSendChan == nil {
|
||||
logger.Error("kcpRawSendChan is nil, session: %v", session)
|
||||
logger.Error("kcpRawSendChan is nil, convId: %v", protoMsg.ConvId)
|
||||
return
|
||||
}
|
||||
select {
|
||||
case kcpRawSendChan <- protoMsg:
|
||||
default:
|
||||
logger.Error("kcpRawSendChan is full, session: %v", session)
|
||||
if len(kcpRawSendChan) == 1000 {
|
||||
logger.Error("kcpRawSendChan is full, convId: %v", protoMsg.ConvId)
|
||||
return
|
||||
}
|
||||
kcpRawSendChan <- protoMsg
|
||||
if protoMsg.CmdId == cmd.PlayerLoginRsp {
|
||||
logger.Debug("session active, convId: %v", protoMsg.ConvId)
|
||||
session.connState = ConnActive
|
||||
// 通知GS玩家各个服务器的appid
|
||||
serverMsg := new(mq.ServerMsg)
|
||||
serverMsg.UserId = session.userId
|
||||
if session.changeGameServer {
|
||||
serverMsg.JoinHostUserId = session.joinHostUserId
|
||||
session.changeGameServer = false
|
||||
session.joinHostUserId = 0
|
||||
} else {
|
||||
serverMsg.FightServerAppId = session.fightServerAppId
|
||||
}
|
||||
k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeServer,
|
||||
EventId: mq.ServerAppidBindNotify,
|
||||
ServerMsg: serverMsg,
|
||||
})
|
||||
}
|
||||
}
|
||||
for {
|
||||
@@ -280,7 +299,7 @@ func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session
|
||||
rsp = new(proto.GetPlayerTokenRsp)
|
||||
rsp.Uid = tokenVerifyRsp.PlayerID
|
||||
rsp.IsProficientPlayer = true
|
||||
rsp.Retcode = 21
|
||||
rsp.Retcode = int32(proto.Retcode_RET_BLACK_UID)
|
||||
rsp.Msg = "FORBID_CHEATING_PLUGINS"
|
||||
rsp.BlackUidEndTime = tokenVerifyRsp.ForbidEndTime
|
||||
if rsp.BlackUidEndTime == 0 {
|
||||
@@ -365,8 +384,12 @@ func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session
|
||||
addr := session.conn.RemoteAddr().String()
|
||||
split := strings.Split(addr, ":")
|
||||
rsp.ClientIpStr = split[0]
|
||||
timeRand := random.GetTimeRand()
|
||||
serverSeedUint64 := timeRand.Uint64()
|
||||
session.seed = serverSeedUint64
|
||||
if req.GetKeyId() != 0 {
|
||||
logger.Debug("do hk4e 2.8 rsa logic")
|
||||
session.useMagicSeed = true
|
||||
keyId := strconv.Itoa(int(req.GetKeyId()))
|
||||
encPubPrivKey, exist := k.encRsaKeyMap[keyId]
|
||||
if !exist {
|
||||
@@ -400,9 +423,6 @@ func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session
|
||||
logger.Error("parse client seed to uint64 error: %v", err)
|
||||
return rsp
|
||||
}
|
||||
timeRand := random.GetTimeRand()
|
||||
serverSeedUint64 := timeRand.Uint64()
|
||||
session.seed = serverSeedUint64
|
||||
seedUint64 := serverSeedUint64 ^ clientSeedUint64
|
||||
seedBuf := new(bytes.Buffer)
|
||||
err = binary.Write(seedBuf, binary.BigEndian, seedUint64)
|
||||
@@ -424,6 +444,10 @@ func (k *KcpConnectManager) getPlayerToken(req *proto.GetPlayerTokenReq, session
|
||||
rsp.KeyId = req.KeyId
|
||||
rsp.ServerRandKey = base64.StdEncoding.EncodeToString(seedEnc)
|
||||
rsp.Sign = base64.StdEncoding.EncodeToString(seedSign)
|
||||
} else {
|
||||
session.useMagicSeed = false
|
||||
rsp.SecretKeySeed = serverSeedUint64
|
||||
rsp.SecretKey = fmt.Sprintf("%03x-%012x", data[:3], data[4:16])
|
||||
}
|
||||
return rsp
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"hk4e/gs/model"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"hk4e/gs/model"
|
||||
)
|
||||
|
||||
// HelpCommand 帮助命令
|
||||
|
||||
@@ -60,8 +60,6 @@ func NewGameManager(dao *dao.Dao, messageQueue *mq.MessageQueue, gsId uint32) (r
|
||||
}
|
||||
|
||||
func (g *GameManager) run() {
|
||||
ROUTE_MANAGER.InitRoute()
|
||||
USER_MANAGER.StartAutoSaveUser()
|
||||
go g.gameMainLoopD()
|
||||
}
|
||||
|
||||
@@ -123,7 +121,7 @@ func (g *GameManager) gameMainLoop() {
|
||||
ROUTE_MANAGER.RouteHandle(netMsg)
|
||||
end := time.Now().UnixNano()
|
||||
routeCost += end - start
|
||||
case <-TICK_MANAGER.ticker.C:
|
||||
case <-TICK_MANAGER.globalTick.C:
|
||||
// 游戏服务器定时帧
|
||||
start := time.Now().UnixNano()
|
||||
TICK_MANAGER.OnGameServerTick()
|
||||
@@ -153,13 +151,20 @@ func (g *GameManager) Stop() {
|
||||
}
|
||||
time.Sleep(time.Second * 3)
|
||||
// 保存玩家数据
|
||||
onlinePlayerMap := USER_MANAGER.GetAllOnlineUserList()
|
||||
saveUserIdList := make([]uint32, 0, len(onlinePlayerMap))
|
||||
for userId := range onlinePlayerMap {
|
||||
saveUserIdList = append(saveUserIdList, userId)
|
||||
}
|
||||
LOCAL_EVENT_MANAGER.localEventChan <- &LocalEvent{
|
||||
EventId: RunUserCopyAndSave,
|
||||
Msg: saveUserIdList,
|
||||
}
|
||||
time.Sleep(time.Second * 3)
|
||||
}
|
||||
|
||||
func (g *GameManager) SendMsgEx(cmdId uint16, userId uint32, clientSeq uint32, gateAppId string, payloadMsg pb.Message) {
|
||||
// SendMsgToGate 发送消息给客户端 指定网关
|
||||
func (g *GameManager) SendMsgToGate(cmdId uint16, userId uint32, clientSeq uint32, gateAppId string, payloadMsg pb.Message) {
|
||||
if userId < 100000000 {
|
||||
return
|
||||
}
|
||||
@@ -245,12 +250,14 @@ func (g *GameManager) CommonRetSucc(cmdId uint16, player *model.Player, rsp pb.M
|
||||
g.SendMsg(cmdId, player.PlayerID, player.ClientSeq, rsp)
|
||||
}
|
||||
|
||||
// SendToWorldA 给世界内所有玩家发消息
|
||||
func (g *GameManager) SendToWorldA(world *World, cmdId uint16, seq uint32, msg pb.Message) {
|
||||
for _, v := range world.playerMap {
|
||||
GAME_MANAGER.SendMsg(cmdId, v.PlayerID, seq, msg)
|
||||
}
|
||||
}
|
||||
|
||||
// SendToWorldAEC 给世界内除自己以外的所有玩家发消息
|
||||
func (g *GameManager) SendToWorldAEC(world *World, cmdId uint16, seq uint32, msg pb.Message, uid uint32) {
|
||||
for _, v := range world.playerMap {
|
||||
if uid == v.PlayerID {
|
||||
@@ -260,6 +267,7 @@ func (g *GameManager) SendToWorldAEC(world *World, cmdId uint16, seq uint32, msg
|
||||
}
|
||||
}
|
||||
|
||||
// SendToWorldH 给世界房主发消息
|
||||
func (g *GameManager) SendToWorldH(world *World, cmdId uint16, seq uint32, msg pb.Message) {
|
||||
GAME_MANAGER.SendMsg(cmdId, world.owner.PlayerID, seq, msg)
|
||||
}
|
||||
@@ -286,10 +294,16 @@ func (g *GameManager) DisconnectPlayer(userId uint32, reason uint32) {
|
||||
|
||||
func (g *GameManager) GetClientProtoObjByName(protoObjName string) pb.Message {
|
||||
if !appConfig.CONF.Hk4e.ClientProtoProxyEnable {
|
||||
return &proto.NullMsg{}
|
||||
logger.Error("client proto proxy func not enable")
|
||||
return nil
|
||||
}
|
||||
clientProtoObj := g.clientCmdProtoMapRefValue.MethodByName(
|
||||
"GetClientProtoObjByName",
|
||||
).Call([]reflect.Value{reflect.ValueOf(protoObjName)})[0].Interface().(pb.Message)
|
||||
fn := g.clientCmdProtoMapRefValue.MethodByName("GetClientProtoObjByName")
|
||||
ret := fn.Call([]reflect.Value{reflect.ValueOf(protoObjName)})
|
||||
obj := ret[0].Interface()
|
||||
if obj == nil {
|
||||
logger.Error("try to get a not exist proto obj, protoObjName: %v", protoObjName)
|
||||
return nil
|
||||
}
|
||||
clientProtoObj := obj.(pb.Message)
|
||||
return clientProtoObj
|
||||
}
|
||||
|
||||
@@ -85,10 +85,10 @@ func (g *GCGManager) JoinGame(game *GCGGame, player *model.Player) {
|
||||
game.controllerMap[game.controllerIdCounter] = controller
|
||||
}
|
||||
|
||||
//// CreateGameCardInfo 生成操控者卡牌信息
|
||||
//func (g *GCGManager) CreateGameCardInfo(controller *GCGController, gcgDeck *model.GCGDeck) *GCGCardInfo {
|
||||
// // CreateGameCardInfo 生成操控者卡牌信息
|
||||
// func (g *GCGManager) CreateGameCardInfo(controller *GCGController, gcgDeck *model.GCGDeck) *GCGCardInfo {
|
||||
//
|
||||
//}
|
||||
// }
|
||||
|
||||
// GetGameControllerByUserId 通过玩家Id获取GCGController对象
|
||||
func (g *GCGManager) GetGameControllerByUserId(game *GCGGame, userId uint32) *GCGController {
|
||||
|
||||
@@ -45,11 +45,17 @@ func (l *LocalEventManager) LocalEventHandle(localEvent *LocalEvent) {
|
||||
playerRegInfo := localEvent.Msg.(*PlayerRegInfo)
|
||||
GAME_MANAGER.OnRegOk(playerRegInfo.Exist, playerRegInfo.Req, playerRegInfo.UserId, playerRegInfo.ClientSeq, playerRegInfo.GateAppId)
|
||||
case RunUserCopyAndSave:
|
||||
saveUserIdList := localEvent.Msg.([]uint32)
|
||||
startTime := time.Now().UnixNano()
|
||||
// 拷贝一份数据避免并发访问
|
||||
insertPlayerList := make([]*model.Player, 0)
|
||||
updatePlayerList := make([]*model.Player, 0)
|
||||
for uid, player := range USER_MANAGER.playerMap {
|
||||
for _, uid := range saveUserIdList {
|
||||
player := USER_MANAGER.GetOnlineUser(uid)
|
||||
if player == nil {
|
||||
logger.Error("try to save but user not exist or online, uid: %v", uid)
|
||||
continue
|
||||
}
|
||||
if uid < 100000000 {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ type RouteManager struct {
|
||||
func NewRouteManager() (r *RouteManager) {
|
||||
r = new(RouteManager)
|
||||
r.handlerFuncRouteMap = make(map[uint16]HandlerFunc)
|
||||
r.initRoute()
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -52,7 +53,7 @@ func (r *RouteManager) doRoute(cmdId uint16, userId uint32, clientSeq uint32, pa
|
||||
SELF = nil
|
||||
}
|
||||
|
||||
func (r *RouteManager) InitRoute() {
|
||||
func (r *RouteManager) initRoute() {
|
||||
r.registerRouter(cmd.UnionCmdNotify, GAME_MANAGER.UnionCmdNotify)
|
||||
r.registerRouter(cmd.MassiveEntityElementOpBatchNotify, GAME_MANAGER.MassiveEntityElementOpBatchNotify)
|
||||
r.registerRouter(cmd.ToTheMoonEnterSceneReq, GAME_MANAGER.ToTheMoonEnterSceneReq)
|
||||
@@ -169,10 +170,6 @@ func (r *RouteManager) RouteHandle(netMsg *mq.NetMsg) {
|
||||
USER_MANAGER.SetRemoteUserOnlineState(serverMsg.UserId, serverMsg.IsOnline, netMsg.OriginServerAppId)
|
||||
case mq.ServerAppidBindNotify:
|
||||
GAME_MANAGER.ServerAppidBindNotify(serverMsg.UserId, serverMsg.FightServerAppId, serverMsg.JoinHostUserId)
|
||||
case mq.ServerUserBaseInfoReq:
|
||||
GAME_MANAGER.ServerUserBaseInfoReq(serverMsg.UserBaseInfo, netMsg.OriginServerAppId)
|
||||
case mq.ServerUserBaseInfoRsp:
|
||||
GAME_MANAGER.ServerUserBaseInfoRsp(serverMsg.UserBaseInfo)
|
||||
case mq.ServerUserMpReq:
|
||||
GAME_MANAGER.ServerUserMpReq(serverMsg.UserMpInfo, netMsg.OriginServerAppId)
|
||||
case mq.ServerUserMpRsp:
|
||||
|
||||
@@ -13,49 +13,148 @@ import (
|
||||
|
||||
// 游戏服务器定时帧管理器
|
||||
|
||||
type UserTimer struct {
|
||||
timer *time.Timer
|
||||
action int
|
||||
}
|
||||
|
||||
type UserTick struct {
|
||||
globalTick *time.Ticker
|
||||
globalTickCount uint64
|
||||
timerIdCounter uint64
|
||||
timerMap map[uint64]*UserTimer
|
||||
}
|
||||
|
||||
type TickManager struct {
|
||||
ticker *time.Ticker
|
||||
tickCount uint64
|
||||
globalTick *time.Ticker
|
||||
globalTickCount uint64
|
||||
userTickMap map[uint32]*UserTick
|
||||
}
|
||||
|
||||
func NewTickManager() (r *TickManager) {
|
||||
r = new(TickManager)
|
||||
r.ticker = time.NewTicker(time.Millisecond * 100)
|
||||
r.globalTick = time.NewTicker(time.Millisecond * 100)
|
||||
r.globalTickCount = 0
|
||||
r.userTickMap = make(map[uint32]*UserTick)
|
||||
logger.Info("game server tick start at: %v", time.Now().UnixMilli())
|
||||
return r
|
||||
}
|
||||
|
||||
// 每个玩家自己的tick
|
||||
|
||||
// CreateUserGlobalTick 创建玩家tick对象
|
||||
func (t *TickManager) CreateUserGlobalTick(userId uint32) {
|
||||
t.userTickMap[userId] = &UserTick{
|
||||
globalTick: time.NewTicker(time.Second * 1),
|
||||
globalTickCount: 0,
|
||||
timerIdCounter: 0,
|
||||
timerMap: make(map[uint64]*UserTimer),
|
||||
}
|
||||
}
|
||||
|
||||
// DestroyUserGlobalTick 销毁玩家tick对象
|
||||
func (t *TickManager) DestroyUserGlobalTick(userId uint32) {
|
||||
delete(t.userTickMap, userId)
|
||||
}
|
||||
|
||||
// CreateUserTimer 创建玩家定时任务
|
||||
func (t *TickManager) CreateUserTimer(userId uint32, action int, delay uint32) {
|
||||
userTick, exist := t.userTickMap[userId]
|
||||
if !exist {
|
||||
logger.Error("user not exist, uid: %v", userId)
|
||||
return
|
||||
}
|
||||
userTick.timerIdCounter++
|
||||
userTick.timerMap[userTick.timerIdCounter] = &UserTimer{
|
||||
timer: time.NewTimer(time.Second * time.Duration(delay)),
|
||||
action: action,
|
||||
}
|
||||
logger.Debug("create user timer, uid: %v, action: %v, time: %v",
|
||||
userId, action, time.Now().Add(time.Second*time.Duration(delay)).Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
|
||||
func (t *TickManager) onUserTickSecond(userId uint32, now int64) {
|
||||
// logger.Info("on user tick second, uid: %v, time: %v", userId, now)
|
||||
}
|
||||
|
||||
func (t *TickManager) onUserTickMinute(userId uint32, now int64) {
|
||||
logger.Info("on user tick minute, uid: %v, time: %v", userId, now)
|
||||
// 每分钟保存玩家数据
|
||||
saveUserIdList := []uint32{userId}
|
||||
LOCAL_EVENT_MANAGER.localEventChan <- &LocalEvent{
|
||||
EventId: RunUserCopyAndSave,
|
||||
Msg: saveUserIdList,
|
||||
}
|
||||
}
|
||||
|
||||
// 玩家定时任务常量
|
||||
|
||||
const (
|
||||
UserTimerActionTest = iota
|
||||
)
|
||||
|
||||
func (t *TickManager) userTimerHandle(userId uint32, action int) {
|
||||
switch action {
|
||||
case UserTimerActionTest:
|
||||
logger.Debug("UserTimerActionTest, uid: %v", userId)
|
||||
}
|
||||
}
|
||||
|
||||
// 服务器全局tick
|
||||
|
||||
func (t *TickManager) OnGameServerTick() {
|
||||
t.tickCount++
|
||||
t.globalTickCount++
|
||||
now := time.Now().UnixMilli()
|
||||
t.onTick100MilliSecond(now)
|
||||
if t.tickCount%2 == 0 {
|
||||
if t.globalTickCount%2 == 0 {
|
||||
t.onTick200MilliSecond(now)
|
||||
}
|
||||
if t.tickCount%(10*1) == 0 {
|
||||
if t.globalTickCount%(10*1) == 0 {
|
||||
t.onTickSecond(now)
|
||||
}
|
||||
if t.tickCount%(10*5) == 0 {
|
||||
if t.globalTickCount%(10*5) == 0 {
|
||||
t.onTick5Second(now)
|
||||
}
|
||||
if t.tickCount%(10*10) == 0 {
|
||||
if t.globalTickCount%(10*10) == 0 {
|
||||
t.onTick10Second(now)
|
||||
}
|
||||
if t.tickCount%(10*60) == 0 {
|
||||
if t.globalTickCount%(10*60) == 0 {
|
||||
t.onTickMinute(now)
|
||||
}
|
||||
if t.tickCount%(10*60*10) == 0 {
|
||||
if t.globalTickCount%(10*60*10) == 0 {
|
||||
t.onTick10Minute(now)
|
||||
}
|
||||
if t.tickCount%(10*3600) == 0 {
|
||||
if t.globalTickCount%(10*3600) == 0 {
|
||||
t.onTickHour(now)
|
||||
}
|
||||
if t.tickCount%(10*3600*24) == 0 {
|
||||
if t.globalTickCount%(10*3600*24) == 0 {
|
||||
t.onTickDay(now)
|
||||
}
|
||||
if t.tickCount%(10*3600*24*7) == 0 {
|
||||
if t.globalTickCount%(10*3600*24*7) == 0 {
|
||||
t.onTickWeek(now)
|
||||
}
|
||||
for userId, userTick := range t.userTickMap {
|
||||
if len(userTick.globalTick.C) == 0 {
|
||||
// 跳过还没到时间的定时器
|
||||
continue
|
||||
}
|
||||
userTick.globalTickCount++
|
||||
if userTick.globalTickCount%(10*1) == 0 {
|
||||
t.onUserTickSecond(userId, now)
|
||||
}
|
||||
if userTick.globalTickCount%(10*60) == 0 {
|
||||
t.onUserTickMinute(userId, now)
|
||||
}
|
||||
for timerId, timer := range userTick.timerMap {
|
||||
if len(timer.timer.C) == 0 {
|
||||
// 跳过还没到时间的定时器
|
||||
continue
|
||||
}
|
||||
timer.timer.Stop()
|
||||
delete(userTick.timerMap, timerId)
|
||||
t.userTimerHandle(userId, timer.action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TickManager) onTickWeek(now int64) {
|
||||
@@ -259,7 +358,7 @@ func (t *TickManager) onTickSecond(now int64) {
|
||||
monsterEntityCount++
|
||||
}
|
||||
}
|
||||
if monsterEntityCount < 30 {
|
||||
if monsterEntityCount < 3 {
|
||||
monsterEntityId := t.createMonster(scene)
|
||||
GAME_MANAGER.AddSceneEntityNotify(world.owner, proto.VisionType_VISION_TYPE_BORN, []uint32{monsterEntityId}, true, false)
|
||||
}
|
||||
|
||||
@@ -152,6 +152,7 @@ func (g *GameManager) ServerAppidBindNotify(userId uint32, fightAppId string, jo
|
||||
world.AddPlayer(player, player.SceneId)
|
||||
player.WorldId = world.id
|
||||
// 进入场景
|
||||
player.SceneJump = true
|
||||
player.SceneLoadState = model.SceneNone
|
||||
g.SendMsg(cmd.PlayerEnterSceneNotify, userId, player.ClientSeq, g.PacketPlayerEnterSceneNotifyLogin(player, proto.EnterType_ENTER_TYPE_SELF))
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ func (g *GameManager) ClientAbilityInitFinishNotify(player *model.Player, payloa
|
||||
}
|
||||
invokeHandler := model.NewInvokeHandler[proto.AbilityInvokeEntry]()
|
||||
for _, entry := range req.Invokes {
|
||||
logger.Debug("ClientAbilityInitFinishNotify: %v", entry, player.PlayerID)
|
||||
// logger.Debug("ClientAbilityInitFinishNotify: %v", entry, player.PlayerID)
|
||||
invokeHandler.AddEntry(entry.ForwardType, entry)
|
||||
}
|
||||
DoForward[proto.AbilityInvokeEntry](player, &proto.ClientAbilityInitFinishNotify{}, []string{"EntityId"}, "Invokes", invokeHandler)
|
||||
@@ -236,7 +236,7 @@ func (g *GameManager) ClientAbilityChangeNotify(player *model.Player, payloadMsg
|
||||
}
|
||||
invokeHandler := model.NewInvokeHandler[proto.AbilityInvokeEntry]()
|
||||
for _, entry := range req.Invokes {
|
||||
logger.Debug("ClientAbilityChangeNotify: %v", entry, player.PlayerID)
|
||||
// logger.Debug("ClientAbilityChangeNotify: %v", entry, player.PlayerID)
|
||||
|
||||
invokeHandler.AddEntry(entry.ForwardType, entry)
|
||||
}
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
pb "google.golang.org/protobuf/proto"
|
||||
"hk4e/common/constant"
|
||||
"hk4e/gs/model"
|
||||
"hk4e/protocol/cmd"
|
||||
"hk4e/protocol/proto"
|
||||
|
||||
pb "google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func (g *GameManager) GCGLogin(player *model.Player) {
|
||||
player.SceneId = 1076
|
||||
player.Pos.X = 8.974
|
||||
player.Pos.Y = 0
|
||||
player.Pos.Z = 9.373
|
||||
// player.SceneId = 1076
|
||||
// player.Pos.X = 8.974
|
||||
// player.Pos.Y = 0
|
||||
// player.Pos.Z = 9.373
|
||||
// GCG基础信息
|
||||
g.SendMsg(cmd.GCGBasicDataNotify, player.PlayerID, player.ClientSeq, g.PacketGCGBasicDataNotify(player))
|
||||
// GCG等级挑战解锁
|
||||
@@ -27,28 +28,25 @@ func (g *GameManager) GCGLogin(player *model.Player) {
|
||||
|
||||
// GCGTavernInit GCG酒馆初始化
|
||||
func (g *GameManager) GCGTavernInit(player *model.Player) {
|
||||
//// GCG酒馆信息通知
|
||||
//g.SendMsg(cmd.GCGTCTavernInfoNotify, player.PlayerID, player.ClientSeq, g.PacketGCGTCTavernInfoNotify(player))
|
||||
//// GCG酒馆NPC信息通知
|
||||
//g.SendMsg(cmd.GCGTavernNpcInfoNotify, player.PlayerID, player.ClientSeq, g.PacketGCGTavernNpcInfoNotify(player))
|
||||
// // GCG酒馆信息通知
|
||||
// g.SendMsg(cmd.GCGTCTavernInfoNotify, player.PlayerID, player.ClientSeq, g.PacketGCGTCTavernInfoNotify(player))
|
||||
// // GCG酒馆NPC信息通知
|
||||
// g.SendMsg(cmd.GCGTavernNpcInfoNotify, player.PlayerID, player.ClientSeq, g.PacketGCGTavernNpcInfoNotify(player))
|
||||
// 可能是包没发全导致卡进度条?
|
||||
g.SendMsg(cmd.DungeonWayPointNotify, player.PlayerID, player.ClientSeq, &proto.DungeonWayPointNotify{})
|
||||
g.SendMsg(cmd.DungeonDataNotify, player.PlayerID, player.ClientSeq, &proto.DungeonDataNotify{})
|
||||
g.SendMsg(cmd.Unk3300_DGBNCDEIIFC, player.PlayerID, player.ClientSeq, &proto.Unk3300_DGBNCDEIIFC{})
|
||||
}
|
||||
|
||||
// GCGStartChallenge GCG开始挑战
|
||||
func (g *GameManager) GCGStartChallenge(player *model.Player) {
|
||||
// GCG开始游戏通知
|
||||
//gcgStartChallengeByCheckRewardRsp := &proto.GCGStartChallengeByCheckRewardRsp{
|
||||
// gcgStartChallengeByCheckRewardRsp := &proto.GCGStartChallengeByCheckRewardRsp{
|
||||
// ExceededItemTypeList: make([]uint32, 0, 0),
|
||||
// LevelId: 0,
|
||||
// ExceededItemList: make([]uint32, 0, 0),
|
||||
// LevelType: proto.GCGLevelType_GCG_LEVEL_TYPE_GUIDE_GROUP,
|
||||
// ConfigId: 7066505,
|
||||
// Retcode: 0,
|
||||
//}
|
||||
//g.SendMsg(cmd.GCGStartChallengeByCheckRewardRsp, player.PlayerID, player.ClientSeq, gcgStartChallengeByCheckRewardRsp)
|
||||
// }
|
||||
// g.SendMsg(cmd.GCGStartChallengeByCheckRewardRsp, player.PlayerID, player.ClientSeq, gcgStartChallengeByCheckRewardRsp)
|
||||
|
||||
// GCG游戏简要信息通知
|
||||
GAME_MANAGER.SendMsg(cmd.GCGGameBriefDataNotify, player.PlayerID, player.ClientSeq, g.PacketGCGGameBriefDataNotify(player, proto.GCGGameBusinessType_GCG_GAME_BUSINESS_TYPE_GUIDE_GROUP, 30102))
|
||||
@@ -74,7 +72,7 @@ func (g *GameManager) GCGAskDuelReq(player *model.Player, payloadMsg pb.Message)
|
||||
return
|
||||
}
|
||||
// PacketGCGAskDuelRsp
|
||||
//gcgAskDuelRsp := &proto.GCGAskDuelRsp{
|
||||
// gcgAskDuelRsp := &proto.GCGAskDuelRsp{
|
||||
// Duel: &proto.GCGDuel{
|
||||
// ServerSeq: game.serverSeqCounter,
|
||||
// ShowInfoList: make([]*proto.GCGControllerShowInfo, 0, len(game.controllerMap)),
|
||||
@@ -97,9 +95,9 @@ func (g *GameManager) GCGAskDuelReq(player *model.Player, payloadMsg pb.Message)
|
||||
// Unk3300_JBBMBKGOONO: 0,
|
||||
// Phase: nil,
|
||||
// },
|
||||
//}
|
||||
//// 玩家信息列表
|
||||
//for _, controller := range game.controllerMap {
|
||||
// }
|
||||
// // 玩家信息列表
|
||||
// for _, controller := range game.controllerMap {
|
||||
// gcgControllerShowInfo := &proto.GCGControllerShowInfo{
|
||||
// ControllerId: controller.controllerId,
|
||||
// ProfilePicture: &proto.ProfilePicture{},
|
||||
@@ -110,8 +108,8 @@ func (g *GameManager) GCGAskDuelReq(player *model.Player, payloadMsg pb.Message)
|
||||
// gcgControllerShowInfo.ProfilePicture.AvatarId = player.AvatarMap[player.HeadImage].Costume
|
||||
// }
|
||||
// gcgAskDuelRsp.Duel.ShowInfoList = append(gcgAskDuelRsp.Duel.ShowInfoList)
|
||||
//}
|
||||
//GAME_MANAGER.SendMsg(cmd.GCGAskDuelRsp, player.PlayerID, player.ClientSeq, gcgAskDuelRsp)
|
||||
// }
|
||||
// GAME_MANAGER.SendMsg(cmd.GCGAskDuelRsp, player.PlayerID, player.ClientSeq, gcgAskDuelRsp)
|
||||
// PacketGCGAskDuelRsp
|
||||
gcgAskDuelRsp := new(proto.GCGAskDuelRsp)
|
||||
gcgAskDuelRsp.Duel = &proto.GCGDuel{
|
||||
|
||||
@@ -39,7 +39,7 @@ func (g *GameManager) OnLogin(userId uint32, clientSeq uint32, gateAppId string)
|
||||
|
||||
func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq uint32, gateAppId string) {
|
||||
if player == nil {
|
||||
g.SendMsgEx(cmd.DoSetPlayerBornDataNotify, userId, clientSeq, gateAppId, new(proto.DoSetPlayerBornDataNotify))
|
||||
g.SendMsgToGate(cmd.DoSetPlayerBornDataNotify, userId, clientSeq, gateAppId, new(proto.DoSetPlayerBornDataNotify))
|
||||
return
|
||||
}
|
||||
player.OnlineTime = uint32(time.Now().UnixMilli())
|
||||
@@ -56,6 +56,12 @@ func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq u
|
||||
player.Pos.Y = player.SafePos.Y
|
||||
player.Pos.Z = player.SafePos.Z
|
||||
|
||||
if player.SceneId > 100 {
|
||||
player.SceneId = 3
|
||||
player.Pos = &model.Vector{X: 2747, Y: 194, Z: -1719}
|
||||
player.Rot = &model.Vector{X: 0, Y: 307, Z: 0}
|
||||
}
|
||||
|
||||
player.CombatInvokeHandler = model.NewInvokeHandler[proto.CombatInvokeEntry]()
|
||||
player.AbilityInvokeHandler = model.NewInvokeHandler[proto.AbilityInvokeEntry]()
|
||||
|
||||
@@ -71,6 +77,8 @@ func (g *GameManager) OnLoginOk(userId uint32, player *model.Player, clientSeq u
|
||||
},
|
||||
})
|
||||
}
|
||||
TICK_MANAGER.CreateUserGlobalTick(userId)
|
||||
TICK_MANAGER.CreateUserTimer(userId, UserTimerActionTest, 100)
|
||||
}
|
||||
|
||||
func (g *GameManager) OnReg(userId uint32, clientSeq uint32, gateAppId string, payloadMsg pb.Message) {
|
||||
@@ -104,7 +112,7 @@ func (g *GameManager) OnRegOk(exist bool, req *proto.SetPlayerBornDataReq, userI
|
||||
}
|
||||
USER_MANAGER.AddUser(player)
|
||||
|
||||
g.SendMsgEx(cmd.SetPlayerBornDataRsp, userId, clientSeq, gateAppId, new(proto.SetPlayerBornDataRsp))
|
||||
g.SendMsgToGate(cmd.SetPlayerBornDataRsp, userId, clientSeq, gateAppId, new(proto.SetPlayerBornDataRsp))
|
||||
g.OnLogin(userId, clientSeq, gateAppId)
|
||||
}
|
||||
|
||||
@@ -115,6 +123,7 @@ func (g *GameManager) OnUserOffline(userId uint32, changeGsInfo *ChangeGsInfo) {
|
||||
logger.Error("player is nil, userId: %v", userId)
|
||||
return
|
||||
}
|
||||
TICK_MANAGER.DestroyUserGlobalTick(userId)
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
if world != nil {
|
||||
g.UserWorldRemovePlayer(world, player)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"hk4e/gs/dao"
|
||||
"hk4e/gs/model"
|
||||
"hk4e/pkg/logger"
|
||||
@@ -30,6 +28,7 @@ func NewUserManager(dao *dao.Dao) (r *UserManager) {
|
||||
r.playerMap = make(map[uint32]*model.Player)
|
||||
r.saveUserChan = make(chan *SaveUserData) // 无缓冲区chan 避免主协程在写入时被迫加锁
|
||||
r.remotePlayerMap = make(map[uint32]string)
|
||||
go r.saveUserHandle()
|
||||
return r
|
||||
}
|
||||
|
||||
@@ -356,24 +355,12 @@ type SaveUserData struct {
|
||||
updatePlayerList []*model.Player
|
||||
}
|
||||
|
||||
// StartAutoSaveUser 玩家定时保存
|
||||
func (u *UserManager) StartAutoSaveUser() {
|
||||
go func() {
|
||||
ticker := time.NewTicker(time.Minute * 5)
|
||||
for {
|
||||
LOCAL_EVENT_MANAGER.localEventChan <- &LocalEvent{
|
||||
EventId: RunUserCopyAndSave,
|
||||
}
|
||||
<-ticker.C
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
for {
|
||||
saveUserData := <-u.saveUserChan
|
||||
u.SaveUserListToDbSync(saveUserData)
|
||||
u.SaveUserListToRedisSync(saveUserData)
|
||||
}
|
||||
}()
|
||||
func (u *UserManager) saveUserHandle() {
|
||||
for {
|
||||
saveUserData := <-u.saveUserChan
|
||||
u.SaveUserListToDbSync(saveUserData)
|
||||
u.SaveUserListToRedisSync(saveUserData)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *UserManager) LoadUserFromDbSync(userId uint32) *model.Player {
|
||||
|
||||
@@ -78,6 +78,7 @@ func (g *GameManager) TeleportPlayer(player *model.Player, enterReason uint16, s
|
||||
if newSceneId != oldSceneId {
|
||||
jumpScene = true
|
||||
}
|
||||
player.SceneJump = jumpScene
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
oldScene := world.GetSceneById(oldSceneId)
|
||||
activeAvatarId := world.GetPlayerActiveAvatarId(player)
|
||||
@@ -87,14 +88,14 @@ func (g *GameManager) TeleportPlayer(player *model.Player, enterReason uint16, s
|
||||
g.SendMsg(cmd.DelTeamEntityNotify, player.PlayerID, player.ClientSeq, delTeamEntityNotify)
|
||||
|
||||
oldScene.RemovePlayer(player)
|
||||
player.SceneId = newSceneId
|
||||
newScene := world.GetSceneById(newSceneId)
|
||||
newScene.AddPlayer(player)
|
||||
}
|
||||
player.SceneLoadState = model.SceneNone
|
||||
player.Pos.X = pos.X
|
||||
player.Pos.Y = pos.Y
|
||||
player.Pos.Z = pos.Z
|
||||
player.SceneId = newSceneId
|
||||
player.SceneLoadState = model.SceneNone
|
||||
|
||||
var enterType proto.EnterType
|
||||
switch enterReason {
|
||||
|
||||
@@ -79,15 +79,16 @@ func (g *GameManager) JoinPlayerSceneReq(player *model.Player, payloadMsg pb.Mes
|
||||
func (g *GameManager) JoinOtherWorld(player *model.Player, hostPlayer *model.Player) {
|
||||
hostWorld := WORLD_MANAGER.GetWorldByID(hostPlayer.WorldId)
|
||||
if hostPlayer.SceneLoadState == model.SceneEnterDone {
|
||||
player.SceneJump = true
|
||||
player.SceneId = hostPlayer.SceneId
|
||||
player.SceneLoadState = model.SceneNone
|
||||
player.Pos.X = hostPlayer.Pos.X
|
||||
player.Pos.Y = hostPlayer.Pos.Y
|
||||
player.Pos.Z = hostPlayer.Pos.Z
|
||||
player.Rot.X = hostPlayer.Rot.X
|
||||
player.Rot.Y = hostPlayer.Rot.Y
|
||||
player.Rot.Z = hostPlayer.Rot.Z
|
||||
player.SceneId = hostPlayer.SceneId
|
||||
g.UserWorldAddPlayer(hostWorld, player)
|
||||
player.SceneLoadState = model.SceneNone
|
||||
|
||||
playerEnterSceneNotify := g.PacketPlayerEnterSceneNotifyLogin(player, proto.EnterType_ENTER_TYPE_OTHER)
|
||||
g.SendMsg(cmd.PlayerEnterSceneNotify, player.PlayerID, player.ClientSeq, playerEnterSceneNotify)
|
||||
@@ -318,6 +319,7 @@ func (g *GameManager) HostEnterMpWorld(hostPlayer *model.Player, otherUid uint32
|
||||
}
|
||||
g.SendMsg(cmd.WorldDataNotify, hostPlayer.PlayerID, hostPlayer.ClientSeq, worldDataNotify)
|
||||
|
||||
hostPlayer.SceneJump = true
|
||||
hostPlayer.SceneLoadState = model.SceneNone
|
||||
|
||||
hostPlayerEnterSceneNotify := g.PacketPlayerEnterSceneNotifyMp(
|
||||
|
||||
@@ -45,7 +45,7 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
|
||||
}
|
||||
g.SendMsg(cmd.ServerTimeNotify, player.PlayerID, player.ClientSeq, serverTimeNotify)
|
||||
|
||||
if world.IsPlayerFirstEnter(player) {
|
||||
if player.SceneJump {
|
||||
worldPlayerInfoNotify := &proto.WorldPlayerInfoNotify{
|
||||
PlayerInfoList: make([]*proto.OnlinePlayerInfo, 0),
|
||||
PlayerUidList: make([]uint32, 0),
|
||||
@@ -214,6 +214,9 @@ func (g *GameManager) SceneInitFinishReq(player *model.Player, payloadMsg pb.Mes
|
||||
|
||||
g.GCGTavernInit(player) // GCG酒馆信息通知
|
||||
|
||||
g.SendMsg(cmd.DungeonWayPointNotify, player.PlayerID, player.ClientSeq, &proto.DungeonWayPointNotify{})
|
||||
g.SendMsg(cmd.DungeonDataNotify, player.PlayerID, player.ClientSeq, &proto.DungeonDataNotify{})
|
||||
|
||||
SceneInitFinishRsp := &proto.SceneInitFinishRsp{
|
||||
EnterSceneToken: player.EnterSceneToken,
|
||||
}
|
||||
@@ -234,20 +237,25 @@ func (g *GameManager) EnterSceneDoneReq(player *model.Player, payloadMsg pb.Mess
|
||||
g.SendMsg(cmd.GuestPostEnterSceneNotify, world.owner.PlayerID, world.owner.ClientSeq, guestPostEnterSceneNotify)
|
||||
}
|
||||
|
||||
var visionType = proto.VisionType_VISION_TYPE_TRANSPORT
|
||||
var visionType = proto.VisionType_VISION_TYPE_NONE
|
||||
|
||||
activeAvatarId := world.GetPlayerActiveAvatarId(player)
|
||||
if world.IsPlayerFirstEnter(player) {
|
||||
if player.SceneJump {
|
||||
visionType = proto.VisionType_VISION_TYPE_BORN
|
||||
} else {
|
||||
visionType = proto.VisionType_VISION_TYPE_TRANSPORT
|
||||
}
|
||||
g.AddSceneEntityNotify(player, visionType, []uint32{world.GetPlayerWorldAvatarEntityId(player, activeAvatarId)}, true, false)
|
||||
activeAvatarEntityId := world.GetPlayerWorldAvatarEntityId(player, activeAvatarId)
|
||||
g.AddSceneEntityNotify(player, visionType, []uint32{activeAvatarEntityId}, true, false)
|
||||
|
||||
// 通过aoi获取场景中在自己周围格子里的全部实体id
|
||||
// entityIdList := world.aoiManager.GetEntityIdListByPos(float32(player.Pos.X), float32(player.Pos.Y), float32(player.Pos.Z))
|
||||
entityIdList := world.GetSceneById(player.SceneId).GetEntityIdList()
|
||||
if world.IsPlayerFirstEnter(player) {
|
||||
if player.SceneJump {
|
||||
visionType = proto.VisionType_VISION_TYPE_MEET
|
||||
} else {
|
||||
visionType = proto.VisionType_VISION_TYPE_TRANSPORT
|
||||
}
|
||||
entityIdList := world.GetSceneById(player.SceneId).GetEntityIdList()
|
||||
g.AddSceneEntityNotify(player, visionType, entityIdList, false, false)
|
||||
|
||||
sceneAreaWeatherNotify := &proto.SceneAreaWeatherNotify{
|
||||
@@ -453,7 +461,7 @@ func (g *GameManager) AddSceneEntityNotify(player *model.Player, visionType prot
|
||||
for _, entityId := range entityIdList[begin:end] {
|
||||
entity, ok := scene.entityMap[entityId]
|
||||
if !ok {
|
||||
// logger.Error("get entity is nil, entityId: %v", entityId)
|
||||
logger.Error("get entity is nil, entityId: %v", entityId)
|
||||
continue
|
||||
}
|
||||
switch entity.entityType {
|
||||
|
||||
@@ -21,28 +21,11 @@ func (g *GameManager) GetPlayerSocialDetailReq(player *model.Player, payloadMsg
|
||||
req := payloadMsg.(*proto.GetPlayerSocialDetailReq)
|
||||
targetUid := req.Uid
|
||||
|
||||
targetPlayer, _, remote := USER_MANAGER.LoadGlobalPlayer(targetUid)
|
||||
targetPlayer, _, _ := USER_MANAGER.LoadGlobalPlayer(targetUid)
|
||||
if targetPlayer == nil {
|
||||
g.CommonRetError(cmd.GetPlayerSocialDetailRsp, player, &proto.GetPlayerSocialDetailRsp{}, proto.Retcode_RET_PLAYER_NOT_EXIST)
|
||||
return
|
||||
}
|
||||
if remote {
|
||||
gsAppId := USER_MANAGER.GetRemoteUserGsAppId(targetUid)
|
||||
MESSAGE_QUEUE.SendToGs(gsAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeServer,
|
||||
EventId: mq.ServerUserBaseInfoReq,
|
||||
ServerMsg: &mq.ServerMsg{
|
||||
UserBaseInfo: &mq.UserBaseInfo{
|
||||
OriginInfo: &mq.OriginInfo{
|
||||
CmdName: "GetPlayerSocialDetailReq",
|
||||
UserId: player.PlayerID,
|
||||
},
|
||||
UserId: targetUid,
|
||||
},
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
_, exist := player.FriendList[targetPlayer.PlayerID]
|
||||
socialDetail := &proto.SocialDetail{
|
||||
Uid: targetPlayer.PlayerID,
|
||||
@@ -441,31 +424,16 @@ func (g *GameManager) GetOnlinePlayerInfoReq(player *model.Player, payloadMsg pb
|
||||
return
|
||||
}
|
||||
|
||||
if USER_MANAGER.GetUserOnlineState(targetUid.TargetUid) {
|
||||
g.SendMsg(cmd.GetOnlinePlayerInfoRsp, player.PlayerID, player.ClientSeq, &proto.GetOnlinePlayerInfoRsp{
|
||||
TargetUid: targetUid.TargetUid,
|
||||
TargetPlayerInfo: g.PacketOnlinePlayerInfo(player),
|
||||
})
|
||||
targetPlayer, online, _ := USER_MANAGER.LoadGlobalPlayer(targetUid.TargetUid)
|
||||
if targetPlayer == nil || !online {
|
||||
g.CommonRetError(cmd.GetOnlinePlayerInfoRsp, player, &proto.GetOnlinePlayerInfoRsp{}, proto.Retcode_RET_PLAYER_NOT_ONLINE)
|
||||
return
|
||||
}
|
||||
if USER_MANAGER.GetRemoteUserOnlineState(targetUid.TargetUid) {
|
||||
gsAppId := USER_MANAGER.GetRemoteUserGsAppId(targetUid.TargetUid)
|
||||
MESSAGE_QUEUE.SendToGs(gsAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeServer,
|
||||
EventId: mq.ServerUserBaseInfoReq,
|
||||
ServerMsg: &mq.ServerMsg{
|
||||
UserBaseInfo: &mq.UserBaseInfo{
|
||||
OriginInfo: &mq.OriginInfo{
|
||||
CmdName: "GetOnlinePlayerInfoReq",
|
||||
UserId: player.PlayerID,
|
||||
},
|
||||
UserId: targetUid.TargetUid,
|
||||
},
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
g.CommonRetError(cmd.GetOnlinePlayerInfoRsp, player, &proto.GetOnlinePlayerInfoRsp{}, proto.Retcode_RET_PLAYER_NOT_ONLINE)
|
||||
|
||||
g.SendMsg(cmd.GetOnlinePlayerInfoRsp, player.PlayerID, player.ClientSeq, &proto.GetOnlinePlayerInfoRsp{
|
||||
TargetUid: targetUid.TargetUid,
|
||||
TargetPlayerInfo: g.PacketOnlinePlayerInfo(targetPlayer),
|
||||
})
|
||||
}
|
||||
|
||||
func (g *GameManager) PacketOnlinePlayerInfo(player *model.Player) *proto.OnlinePlayerInfo {
|
||||
@@ -488,89 +456,6 @@ func (g *GameManager) PacketOnlinePlayerInfo(player *model.Player) *proto.Online
|
||||
return onlinePlayerInfo
|
||||
}
|
||||
|
||||
// 跨服玩家基础数据请求
|
||||
|
||||
func (g *GameManager) ServerUserBaseInfoReq(userBaseInfo *mq.UserBaseInfo, gsAppId string) {
|
||||
switch userBaseInfo.OriginInfo.CmdName {
|
||||
case "GetOnlinePlayerInfoReq":
|
||||
fallthrough
|
||||
case "GetPlayerSocialDetailReq":
|
||||
player := USER_MANAGER.GetOnlineUser(userBaseInfo.UserId)
|
||||
if player == nil {
|
||||
logger.Error("player is nil, uid: %v", userBaseInfo.UserId)
|
||||
return
|
||||
}
|
||||
world := WORLD_MANAGER.GetWorldByID(player.WorldId)
|
||||
MESSAGE_QUEUE.SendToGs(gsAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeServer,
|
||||
EventId: mq.ServerUserBaseInfoRsp,
|
||||
ServerMsg: &mq.ServerMsg{
|
||||
UserBaseInfo: &mq.UserBaseInfo{
|
||||
OriginInfo: userBaseInfo.OriginInfo,
|
||||
UserId: player.PlayerID,
|
||||
Nickname: player.NickName,
|
||||
PlayerLevel: player.PropertiesMap[constant.PlayerPropertyConst.PROP_PLAYER_LEVEL],
|
||||
MpSettingType: uint8(player.PropertiesMap[constant.PlayerPropertyConst.PROP_PLAYER_MP_SETTING_TYPE]),
|
||||
NameCardId: player.NameCard,
|
||||
Signature: player.Signature,
|
||||
HeadImageId: player.HeadImage,
|
||||
WorldPlayerNum: uint32(world.GetWorldPlayerNum()),
|
||||
WorldLevel: player.PropertiesMap[constant.PlayerPropertyConst.PROP_PLAYER_WORLD_LEVEL],
|
||||
Birthday: player.Birthday,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GameManager) ServerUserBaseInfoRsp(userBaseInfo *mq.UserBaseInfo) {
|
||||
switch userBaseInfo.OriginInfo.CmdName {
|
||||
case "GetOnlinePlayerInfoReq":
|
||||
player := USER_MANAGER.GetOnlineUser(userBaseInfo.OriginInfo.UserId)
|
||||
if player == nil {
|
||||
logger.Error("player is nil, uid: %v", userBaseInfo.OriginInfo.UserId)
|
||||
return
|
||||
}
|
||||
g.SendMsg(cmd.GetOnlinePlayerInfoRsp, player.PlayerID, player.ClientSeq, &proto.GetOnlinePlayerInfoRsp{
|
||||
TargetUid: userBaseInfo.UserId,
|
||||
TargetPlayerInfo: &proto.OnlinePlayerInfo{
|
||||
Uid: userBaseInfo.UserId,
|
||||
Nickname: userBaseInfo.Nickname,
|
||||
PlayerLevel: userBaseInfo.PlayerLevel,
|
||||
MpSettingType: proto.MpSettingType(userBaseInfo.MpSettingType),
|
||||
NameCardId: userBaseInfo.NameCardId,
|
||||
Signature: userBaseInfo.Signature,
|
||||
ProfilePicture: &proto.ProfilePicture{AvatarId: userBaseInfo.HeadImageId},
|
||||
CurPlayerNumInWorld: userBaseInfo.WorldPlayerNum,
|
||||
},
|
||||
})
|
||||
case "GetPlayerSocialDetailReq":
|
||||
player := USER_MANAGER.GetOnlineUser(userBaseInfo.OriginInfo.UserId)
|
||||
if player == nil {
|
||||
logger.Error("player is nil, uid: %v", userBaseInfo.OriginInfo.UserId)
|
||||
return
|
||||
}
|
||||
_, exist := player.FriendList[userBaseInfo.UserId]
|
||||
socialDetail := &proto.SocialDetail{
|
||||
Uid: userBaseInfo.UserId,
|
||||
ProfilePicture: &proto.ProfilePicture{AvatarId: userBaseInfo.HeadImageId},
|
||||
Nickname: userBaseInfo.Nickname,
|
||||
Signature: userBaseInfo.Signature,
|
||||
Level: userBaseInfo.PlayerLevel,
|
||||
Birthday: &proto.Birthday{Month: uint32(userBaseInfo.Birthday[0]), Day: uint32(userBaseInfo.Birthday[1])},
|
||||
WorldLevel: userBaseInfo.WorldLevel,
|
||||
NameCardId: userBaseInfo.NameCardId,
|
||||
IsShowAvatar: false,
|
||||
FinishAchievementNum: 0,
|
||||
IsFriend: exist,
|
||||
}
|
||||
getPlayerSocialDetailRsp := &proto.GetPlayerSocialDetailRsp{
|
||||
DetailData: socialDetail,
|
||||
}
|
||||
g.SendMsg(cmd.GetPlayerSocialDetailRsp, player.PlayerID, player.ClientSeq, getPlayerSocialDetailRsp)
|
||||
}
|
||||
}
|
||||
|
||||
// 跨服添加好友通知
|
||||
|
||||
func (g *GameManager) ServerAddFriendNotify(addFriendInfo *mq.AddFriendInfo) {
|
||||
|
||||
@@ -5,13 +5,11 @@ import (
|
||||
"time"
|
||||
|
||||
"hk4e/common/constant"
|
||||
"hk4e/protocol/cmd"
|
||||
|
||||
"hk4e/common/mq"
|
||||
"hk4e/gs/game/aoi"
|
||||
"hk4e/gs/model"
|
||||
"hk4e/pkg/alg"
|
||||
"hk4e/pkg/logger"
|
||||
"hk4e/protocol/cmd"
|
||||
"hk4e/protocol/proto"
|
||||
)
|
||||
|
||||
@@ -50,24 +48,24 @@ func (w *WorldManager) CreateWorld(owner *model.Player) *World {
|
||||
multiplayer: false,
|
||||
mpLevelEntityId: 0,
|
||||
chatMsgList: make([]*proto.ChatInfo, 0),
|
||||
// aoi划分
|
||||
// TODO 为减少内存占用暂时去掉Y轴AOI格子划分 原来的Y轴格子数量为80
|
||||
aoiManager: aoi.NewAoiManager(
|
||||
-8000, 4000, 120,
|
||||
-2000, 2000, 1,
|
||||
-5500, 6500, 120,
|
||||
),
|
||||
// // aoi划分
|
||||
// // TODO 为减少内存占用暂时去掉Y轴AOI格子划分 原来的Y轴格子数量为80
|
||||
// aoiManager: aoi.NewAoiManager(
|
||||
// -8000, 4000, 120,
|
||||
// -2000, 2000, 1,
|
||||
// -5500, 6500, 120,
|
||||
// ),
|
||||
playerFirstEnterMap: make(map[uint32]int64),
|
||||
waitEnterPlayerMap: make(map[uint32]int64),
|
||||
multiplayerTeam: CreateMultiplayerTeam(),
|
||||
peerList: make([]*model.Player, 0),
|
||||
}
|
||||
if world.IsBigWorld() {
|
||||
world.aoiManager = aoi.NewAoiManager(
|
||||
-8000, 4000, 800,
|
||||
-2000, 2000, 1,
|
||||
-5500, 6500, 800,
|
||||
)
|
||||
// world.aoiManager = aoi.NewAoiManager(
|
||||
// -8000, 4000, 800,
|
||||
// -2000, 2000, 1,
|
||||
// -5500, 6500, 800,
|
||||
// )
|
||||
}
|
||||
world.mpLevelEntityId = world.GetNextWorldEntityId(constant.EntityIdTypeConst.MPLEVEL)
|
||||
w.worldMap[worldId] = world
|
||||
@@ -101,18 +99,18 @@ func (w *World) IsBigWorld() bool {
|
||||
// 世界数据结构
|
||||
|
||||
type World struct {
|
||||
id uint32
|
||||
owner *model.Player
|
||||
playerMap map[uint32]*model.Player
|
||||
sceneMap map[uint32]*Scene
|
||||
entityIdCounter uint32 // 世界的实体id生成计数器
|
||||
worldLevel uint8 // 世界等级
|
||||
multiplayer bool // 是否多人世界
|
||||
mpLevelEntityId uint32
|
||||
chatMsgList []*proto.ChatInfo // 世界聊天消息列表
|
||||
aoiManager *aoi.AoiManager // 当前世界地图的aoi管理器
|
||||
playerFirstEnterMap map[uint32]int64 // 玩家第一次进入世界的时间 key:uid value:进入时间
|
||||
waitEnterPlayerMap map[uint32]int64 // 进入世界的玩家等待列表 key:uid value:开始时间
|
||||
id uint32
|
||||
owner *model.Player
|
||||
playerMap map[uint32]*model.Player
|
||||
sceneMap map[uint32]*Scene
|
||||
entityIdCounter uint32 // 世界的实体id生成计数器
|
||||
worldLevel uint8 // 世界等级
|
||||
multiplayer bool // 是否多人世界
|
||||
mpLevelEntityId uint32
|
||||
chatMsgList []*proto.ChatInfo // 世界聊天消息列表
|
||||
// aoiManager *aoi.AoiManager // 当前世界地图的aoi管理器
|
||||
playerFirstEnterMap map[uint32]int64 // 玩家第一次进入世界的时间 key:uid value:进入时间
|
||||
waitEnterPlayerMap map[uint32]int64 // 进入世界的玩家等待列表 key:uid value:开始时间
|
||||
multiplayerTeam *MultiplayerTeam
|
||||
peerList []*model.Player // 玩家编号列表
|
||||
}
|
||||
@@ -263,7 +261,7 @@ func (w *World) InitPlayerWorldAvatar(player *model.Player) {
|
||||
if worldAvatar.uid != player.PlayerID {
|
||||
continue
|
||||
}
|
||||
if worldAvatar.avatarEntityId != 0 || worldAvatar.weaponEntityId != 0 {
|
||||
if !player.SceneJump && (worldAvatar.avatarEntityId != 0 || worldAvatar.weaponEntityId != 0) {
|
||||
continue
|
||||
}
|
||||
worldAvatar.avatarEntityId = scene.CreateEntityAvatar(player, worldAvatar.avatarId)
|
||||
@@ -706,9 +704,9 @@ func (s *Scene) CreateEntityAvatar(player *model.Player, avatarId uint32) uint32
|
||||
},
|
||||
}
|
||||
s.entityMap[entity.id] = entity
|
||||
if avatarId == s.world.GetPlayerActiveAvatarId(player) {
|
||||
s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
}
|
||||
// if avatarId == s.world.GetPlayerActiveAvatarId(player) {
|
||||
// s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
// }
|
||||
MESSAGE_QUEUE.SendToFight(s.world.owner.FightAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeFight,
|
||||
EventId: mq.FightRoutineAddEntity,
|
||||
@@ -759,7 +757,7 @@ func (s *Scene) CreateEntityMonster(pos *model.Vector, level uint8, fightProp ma
|
||||
monsterEntity: &MonsterEntity{},
|
||||
}
|
||||
s.entityMap[entity.id] = entity
|
||||
s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
// s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
MESSAGE_QUEUE.SendToFight(s.world.owner.FightAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeFight,
|
||||
EventId: mq.FightRoutineAddEntity,
|
||||
@@ -798,7 +796,7 @@ func (s *Scene) CreateEntityNpc(pos, rot *model.Vector, npcId, roomId, parentQue
|
||||
},
|
||||
}
|
||||
s.entityMap[entity.id] = entity
|
||||
s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
// s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
return entity.id
|
||||
}
|
||||
|
||||
@@ -826,7 +824,7 @@ func (s *Scene) CreateEntityGadgetNormal(pos *model.Vector, gadgetId uint32) uin
|
||||
},
|
||||
}
|
||||
s.entityMap[entity.id] = entity
|
||||
s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
// s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
return entity.id
|
||||
}
|
||||
|
||||
@@ -856,7 +854,7 @@ func (s *Scene) CreateEntityGadgetGather(pos *model.Vector, gatherId uint32) uin
|
||||
},
|
||||
}
|
||||
s.entityMap[entity.id] = entity
|
||||
s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
// s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
return entity.id
|
||||
}
|
||||
|
||||
@@ -890,7 +888,7 @@ func (s *Scene) CreateEntityGadgetClient(pos, rot *model.Vector, entityId uint32
|
||||
},
|
||||
}
|
||||
s.entityMap[entity.id] = entity
|
||||
s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
// s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
}
|
||||
|
||||
func (s *Scene) CreateEntityGadgetVehicle(uid uint32, pos, rot *model.Vector, vehicleId uint32) uint32 {
|
||||
@@ -929,7 +927,7 @@ func (s *Scene) CreateEntityGadgetVehicle(uid uint32, pos, rot *model.Vector, ve
|
||||
},
|
||||
}
|
||||
s.entityMap[entity.id] = entity
|
||||
s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
// s.world.aoiManager.AddEntityIdToGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
return entity.id
|
||||
}
|
||||
|
||||
@@ -938,7 +936,7 @@ func (s *Scene) DestroyEntity(entityId uint32) {
|
||||
if entity == nil {
|
||||
return
|
||||
}
|
||||
s.world.aoiManager.RemoveEntityIdFromGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
// s.world.aoiManager.RemoveEntityIdFromGridByPos(entity.id, float32(entity.pos.X), float32(entity.pos.Y), float32(entity.pos.Z))
|
||||
delete(s.entityMap, entityId)
|
||||
MESSAGE_QUEUE.SendToFight(s.world.owner.FightAppId, &mq.NetMsg{
|
||||
MsgType: mq.MsgTypeFight,
|
||||
|
||||
@@ -65,6 +65,7 @@ type Player struct {
|
||||
GameObjectGuidMap map[uint64]GameObject `bson:"-" msgpack:"-"` // 游戏对象guid映射表
|
||||
Online bool `bson:"-" msgpack:"-"` // 在线状态
|
||||
Pause bool `bson:"-" msgpack:"-"` // 暂停状态
|
||||
SceneJump bool `bson:"-" msgpack:"-"` // 是否场景切换
|
||||
SceneLoadState int `bson:"-" msgpack:"-"` // 场景加载状态
|
||||
CoopApplyMap map[uint32]int64 `bson:"-" msgpack:"-"` // 敲门申请的玩家uid及时间
|
||||
StaminaInfo *StaminaInfo `bson:"-" msgpack:"-"` // 耐力临时数据
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package aoi
|
||||
package alg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"hk4e/pkg/logger"
|
||||
)
|
||||
|
||||
// aoi管理模块
|
||||
// AoiManager aoi管理模块
|
||||
type AoiManager struct {
|
||||
// 区域边界坐标
|
||||
minX int16
|
||||
@@ -21,7 +19,7 @@ type AoiManager struct {
|
||||
gridMap map[uint32]*Grid // 当前区域中都有哪些格子 key:gid value:格子对象
|
||||
}
|
||||
|
||||
// 初始化aoi区域
|
||||
// NewAoiManager 初始化aoi区域
|
||||
func NewAoiManager(minX, maxX, numX, minY, maxY, numY, minZ, maxZ, numZ int16) (r *AoiManager) {
|
||||
r = new(AoiManager)
|
||||
r.minX = minX
|
||||
@@ -56,25 +54,31 @@ func NewAoiManager(minX, maxX, numX, minY, maxY, numY, minZ, maxZ, numZ int16) (
|
||||
}
|
||||
}
|
||||
logger.Info("init aoi area grid finish")
|
||||
logger.Debug("AoiMgr: minX: %d, maxX: %d, numX: %d, minY: %d, maxY: %d, numY: %d, minZ: %d, maxZ: %d, numZ: %d\n",
|
||||
r.minX, r.maxX, r.numX, r.minY, r.maxY, r.numY, r.minZ, r.maxZ, r.numZ)
|
||||
for _, grid := range r.gridMap {
|
||||
logger.Debug("Grid: gid: %d, minX: %d, maxX: %d, minY: %d, maxY: %d, minZ: %d, maxZ: %d, entityIdMap: %v",
|
||||
grid.gid, grid.minX, grid.maxX, grid.minY, grid.maxY, grid.minZ, grid.maxZ, grid.entityIdMap)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// 每个格子在x轴方向的长度
|
||||
// GridXLen 每个格子在x轴方向的长度
|
||||
func (a *AoiManager) GridXLen() int16 {
|
||||
return (a.maxX - a.minX) / a.numX
|
||||
}
|
||||
|
||||
// 每个格子在y轴方向的长度
|
||||
// GridYLen 每个格子在y轴方向的长度
|
||||
func (a *AoiManager) GridYLen() int16 {
|
||||
return (a.maxY - a.minY) / a.numY
|
||||
}
|
||||
|
||||
// 每个格子在z轴方向的长度
|
||||
// GridZLen 每个格子在z轴方向的长度
|
||||
func (a *AoiManager) GridZLen() int16 {
|
||||
return (a.maxZ - a.minZ) / a.numZ
|
||||
}
|
||||
|
||||
// 通过坐标获取对应的格子id
|
||||
// GetGidByPos 通过坐标获取对应的格子id
|
||||
func (a *AoiManager) GetGidByPos(x, y, z float32) uint32 {
|
||||
gx := (int16(x) - a.minX) / a.GridXLen()
|
||||
gy := (int16(y) - a.minY) / a.GridYLen()
|
||||
@@ -82,7 +86,7 @@ func (a *AoiManager) GetGidByPos(x, y, z float32) uint32 {
|
||||
return uint32(gy)*(uint32(a.numX)*uint32(a.numZ)) + uint32(gz)*uint32(a.numX) + uint32(gx)
|
||||
}
|
||||
|
||||
// 判断坐标是否存在于aoi区域内
|
||||
// IsValidAoiPos 判断坐标是否存在于aoi区域内
|
||||
func (a *AoiManager) IsValidAoiPos(x, y, z float32) bool {
|
||||
if (int16(x) > a.minX && int16(x) < a.maxX) &&
|
||||
(int16(y) > a.minY && int16(y) < a.maxY) &&
|
||||
@@ -93,18 +97,7 @@ func (a *AoiManager) IsValidAoiPos(x, y, z float32) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// 打印信息方法
|
||||
func (a *AoiManager) DebugString() string {
|
||||
s := fmt.Sprintf("AoiMgr: minX: %d, maxX: %d, numX: %d, minY: %d, maxY: %d, numY: %d, minZ: %d, maxZ: %d, numZ: %d\n",
|
||||
a.minX, a.maxX, a.numX, a.minY, a.maxY, a.numY, a.minZ, a.maxZ, a.numZ)
|
||||
s += "gridList in AoiMgr:\n"
|
||||
for _, grid := range a.gridMap {
|
||||
s += fmt.Sprintln(grid.DebugString())
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// 根据格子的gid得到当前周边的格子信息
|
||||
// GetSurrGridListByGid 根据格子的gid得到当前周边的格子信息
|
||||
func (a *AoiManager) GetSurrGridListByGid(gid uint32) (gridList []*Grid) {
|
||||
gridList = make([]*Grid, 0)
|
||||
// 判断grid是否存在
|
||||
@@ -165,7 +158,7 @@ func (a *AoiManager) GetSurrGridListByGid(gid uint32) (gridList []*Grid) {
|
||||
return gridList
|
||||
}
|
||||
|
||||
// 通过坐标得到周边格子内的全部entityId
|
||||
// GetEntityIdListByPos 通过坐标得到周边格子内的全部entityId
|
||||
func (a *AoiManager) GetEntityIdListByPos(x, y, z float32) (entityIdList []uint32) {
|
||||
// 根据坐标得到当前坐标属于哪个格子id
|
||||
gid := a.GetGidByPos(x, y, z)
|
||||
@@ -175,37 +168,37 @@ func (a *AoiManager) GetEntityIdListByPos(x, y, z float32) (entityIdList []uint3
|
||||
for _, v := range gridList {
|
||||
tmp := v.GetEntityIdList()
|
||||
entityIdList = append(entityIdList, tmp...)
|
||||
// logger.Debug("Grid: gid: %d, tmp len: %v", v.gid, len(tmp))
|
||||
logger.Debug("Grid: gid: %d, tmp len: %v", v.gid, len(tmp))
|
||||
}
|
||||
return entityIdList
|
||||
}
|
||||
|
||||
// 通过gid获取当前格子的全部entityId
|
||||
// GetEntityIdListByGid 通过gid获取当前格子的全部entityId
|
||||
func (a *AoiManager) GetEntityIdListByGid(gid uint32) (entityIdList []uint32) {
|
||||
grid := a.gridMap[gid]
|
||||
entityIdList = grid.GetEntityIdList()
|
||||
return entityIdList
|
||||
}
|
||||
|
||||
// 添加一个entityId到一个格子中
|
||||
// AddEntityIdToGrid 添加一个entityId到一个格子中
|
||||
func (a *AoiManager) AddEntityIdToGrid(entityId uint32, gid uint32) {
|
||||
grid := a.gridMap[gid]
|
||||
grid.AddEntityId(entityId)
|
||||
}
|
||||
|
||||
// 移除一个格子中的entityId
|
||||
// RemoveEntityIdFromGrid 移除一个格子中的entityId
|
||||
func (a *AoiManager) RemoveEntityIdFromGrid(entityId uint32, gid uint32) {
|
||||
grid := a.gridMap[gid]
|
||||
grid.RemoveEntityId(entityId)
|
||||
}
|
||||
|
||||
// 通过坐标添加一个entityId到一个格子中
|
||||
// AddEntityIdToGridByPos 通过坐标添加一个entityId到一个格子中
|
||||
func (a *AoiManager) AddEntityIdToGridByPos(entityId uint32, x, y, z float32) {
|
||||
gid := a.GetGidByPos(x, y, z)
|
||||
a.AddEntityIdToGrid(entityId, gid)
|
||||
}
|
||||
|
||||
// 通过坐标把一个entityId从对应的格子中删除
|
||||
// RemoveEntityIdFromGridByPos 通过坐标把一个entityId从对应的格子中删除
|
||||
func (a *AoiManager) RemoveEntityIdFromGridByPos(entityId uint32, x, y, z float32) {
|
||||
gid := a.GetGidByPos(x, y, z)
|
||||
a.RemoveEntityIdFromGrid(entityId, gid)
|
||||
@@ -1,12 +1,10 @@
|
||||
package aoi
|
||||
package alg
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"hk4e/pkg/logger"
|
||||
)
|
||||
|
||||
// 地图格子
|
||||
// Grid 地图格子
|
||||
type Grid struct {
|
||||
gid uint32 // 格子id
|
||||
// 格子边界坐标
|
||||
@@ -19,7 +17,7 @@ type Grid struct {
|
||||
entityIdMap map[uint32]bool // k:entityId v:是否存在
|
||||
}
|
||||
|
||||
// 初始化格子
|
||||
// NewGrid 初始化格子
|
||||
func NewGrid(gid uint32, minX, maxX, minY, maxY, minZ, maxZ int16) (r *Grid) {
|
||||
r = new(Grid)
|
||||
r.gid = gid
|
||||
@@ -33,12 +31,12 @@ func NewGrid(gid uint32, minX, maxX, minY, maxY, minZ, maxZ int16) (r *Grid) {
|
||||
return r
|
||||
}
|
||||
|
||||
// 向格子中添加一个实体id
|
||||
// AddEntityId 向格子中添加一个实体id
|
||||
func (g *Grid) AddEntityId(entityId uint32) {
|
||||
g.entityIdMap[entityId] = true
|
||||
}
|
||||
|
||||
// 从格子中删除一个实体id
|
||||
// RemoveEntityId 从格子中删除一个实体id
|
||||
func (g *Grid) RemoveEntityId(entityId uint32) {
|
||||
_, exist := g.entityIdMap[entityId]
|
||||
if exist {
|
||||
@@ -48,7 +46,7 @@ func (g *Grid) RemoveEntityId(entityId uint32) {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取格子中所有实体id
|
||||
// GetEntityIdList 获取格子中所有实体id
|
||||
func (g *Grid) GetEntityIdList() (entityIdList []uint32) {
|
||||
entityIdList = make([]uint32, 0)
|
||||
for k := range g.entityIdMap {
|
||||
@@ -56,9 +54,3 @@ func (g *Grid) GetEntityIdList() (entityIdList []uint32) {
|
||||
}
|
||||
return entityIdList
|
||||
}
|
||||
|
||||
// 打印信息方法
|
||||
func (g *Grid) DebugString() string {
|
||||
return fmt.Sprintf("Grid: gid: %d, minX: %d, maxX: %d, minY: %d, maxY: %d, minZ: %d, maxZ: %d, entityIdMap: %v",
|
||||
g.gid, g.minX, g.maxX, g.minY, g.maxY, g.minZ, g.maxZ, g.entityIdMap)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package aoi
|
||||
package alg
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -16,7 +16,6 @@ func TestAoiManagerGetSurrGridListByGid(t *testing.T) {
|
||||
-150, 150, 3,
|
||||
-150, 150, 3,
|
||||
)
|
||||
logger.Debug("aoiManager: %s", aoiManager.DebugString())
|
||||
for k := range aoiManager.gridMap {
|
||||
// 得到当前格子周边的九宫格
|
||||
gridList := aoiManager.GetSurrGridListByGid(k)
|
||||
@@ -6,7 +6,7 @@ type LinkList struct {
|
||||
nextNode *LinkList
|
||||
}
|
||||
|
||||
// LinkListQueue 无界队列 每个元素可存储不同数据结构
|
||||
// LLQueue LinkListQueue 无界队列 每个元素可存储不同数据结构
|
||||
type LLQueue struct {
|
||||
headPtr *LinkList
|
||||
tailPtr *LinkList
|
||||
@@ -48,7 +48,7 @@ func (q *LLQueue) DeQueue() any {
|
||||
return ret
|
||||
}
|
||||
|
||||
// ArrayListQueue 无界队列 泛型
|
||||
// ALQueue ArrayListQueue 无界队列 泛型
|
||||
type ALQueue[T any] struct {
|
||||
array []T
|
||||
}
|
||||
@@ -77,7 +77,7 @@ func (q *ALQueue[T]) DeQueue() T {
|
||||
return ret
|
||||
}
|
||||
|
||||
// RingArrayQueue 有界队列 性能最好
|
||||
// RAQueue RingArrayQueue 有界队列 性能最好
|
||||
type RAQueue[T any] struct {
|
||||
ringArray []T
|
||||
ringArrayLen uint64
|
||||
|
||||
@@ -26,7 +26,7 @@ func NewSource64() rand.Source64 { return &source{index: N + 1} }
|
||||
func (s *source) Seed(seed int64) {
|
||||
s.array[0] = uint64(seed)
|
||||
for s.index = 1; s.index < N; s.index++ {
|
||||
s.array[s.index] = (0x5851F42D4C957F2D*(s.array[s.index-1]^(s.array[s.index-1]>>62)) + s.index)
|
||||
s.array[s.index] = 0x5851F42D4C957F2D*(s.array[s.index-1]^(s.array[s.index-1]>>62)) + s.index
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ func (s *source) Uint64() uint64 {
|
||||
x ^= (x >> 29) & 0x5555555555555555
|
||||
x ^= (x << 17) & 0x71D67FFFEDA60000
|
||||
x ^= (x << 37) & 0xFFF7EEE000000000
|
||||
x ^= (x >> 43)
|
||||
x ^= x >> 43
|
||||
return x
|
||||
}
|
||||
|
||||
@@ -68,12 +68,15 @@ type KeyBlock struct {
|
||||
data [4096]byte
|
||||
}
|
||||
|
||||
func NewKeyBlock(seed uint64) *KeyBlock {
|
||||
func NewKeyBlock(seed uint64, useMagicSeed bool) *KeyBlock {
|
||||
b := &KeyBlock{seed: seed}
|
||||
r := NewRand()
|
||||
r.Seed(int64(b.seed))
|
||||
r.Seed(int64(r.Uint64()))
|
||||
r.Uint64()
|
||||
if useMagicSeed {
|
||||
// 2.8.0版本后加入的黑魔法 刘慈欣:6
|
||||
r.Seed(int64(r.Uint64()))
|
||||
r.Uint64()
|
||||
}
|
||||
for i := 0; i < 4096>>3; i++ {
|
||||
binary.BigEndian.PutUint64(b.data[i<<3:], r.Uint64())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package random
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
@@ -18,8 +19,11 @@ func TestKey(t *testing.T) {
|
||||
|
||||
gateDispatchXorKey := gateDispatchEc2b.XorKey()
|
||||
|
||||
keyBlock := NewKeyBlock(uint64(11468049314633205968))
|
||||
fmt.Printf("dispatchXorKey: %v\n", hex.EncodeToString(dispatchXorKey))
|
||||
fmt.Printf("gateDispatchXorKey: %v\n", hex.EncodeToString(gateDispatchXorKey))
|
||||
|
||||
keyBlock := NewKeyBlock(uint64(11468049314633205968), false)
|
||||
gateXorKey := keyBlock.XorKey()
|
||||
|
||||
fmt.Println(dispatchXorKey, gateDispatchXorKey, gateXorKey)
|
||||
fmt.Printf("gateXorKey: %v\n", hex.EncodeToString(gateXorKey[:]))
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
5
protocol/cmd/cmd_id_fix.go
Normal file
5
protocol/cmd/cmd_id_fix.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package cmd
|
||||
|
||||
const (
|
||||
GCGDSBanCardNotify uint16 = 65501
|
||||
)
|
||||
@@ -105,6 +105,8 @@ func (c *CmdProtoMap) registerAllMessage() {
|
||||
c.registerMessage(SceneEntityDrownReq, &proto.SceneEntityDrownReq{}) // 场景实体溺水请求
|
||||
c.registerMessage(SceneEntityDrownRsp, &proto.SceneEntityDrownRsp{}) // 场景实体溺水响应
|
||||
c.registerMessage(ObstacleModifyNotify, &proto.ObstacleModifyNotify{}) // 寻路阻挡变动通知
|
||||
c.registerMessage(DungeonWayPointNotify, &proto.DungeonWayPointNotify{}) // 地牢副本相关
|
||||
c.registerMessage(DungeonDataNotify, &proto.DungeonDataNotify{}) // 地牢副本相关
|
||||
|
||||
// 战斗与同步
|
||||
c.registerMessage(AvatarFightPropNotify, &proto.AvatarFightPropNotify{}) // 角色战斗属性通知
|
||||
@@ -261,15 +263,12 @@ func (c *CmdProtoMap) registerAllMessage() {
|
||||
c.registerMessage(GCGAskDuelRsp, &proto.GCGAskDuelRsp{}) // GCG决斗响应
|
||||
c.registerMessage(GCGInitFinishReq, &proto.GCGInitFinishReq{}) // GCG初始化完成请求
|
||||
c.registerMessage(GCGInitFinishRsp, &proto.GCGInitFinishRsp{}) // GCG初始化完成响应
|
||||
c.registerMessage(Unk3300_DGBNCDEIIFC, &proto.Unk3300_DGBNCDEIIFC{}) // GCG
|
||||
c.registerMessage(DungeonWayPointNotify, &proto.DungeonWayPointNotify{}) // GCG
|
||||
c.registerMessage(DungeonDataNotify, &proto.DungeonDataNotify{}) // GCG
|
||||
|
||||
//// TODO 客户端开始GCG游戏
|
||||
//c.registerMessage(GCGStartChallengeByCheckRewardReq, &proto.GCGStartChallengeByCheckRewardReq{}) // GCG开始挑战来自检测奖励请求
|
||||
//c.registerMessage(GCGStartChallengeByCheckRewardRsp, &proto.GCGStartChallengeByCheckRewardRsp{}) // GCG开始挑战来自检测奖励响应
|
||||
//c.registerMessage(GCGStartChallengeReq, &proto.GCGStartChallengeReq{}) // GCG开始挑战请求
|
||||
//c.registerMessage(GCGStartChallengeRsp, &proto.GCGStartChallengeRsp{}) // GCG开始挑战响应
|
||||
// // TODO 客户端开始GCG游戏
|
||||
// c.registerMessage(GCGStartChallengeByCheckRewardReq, &proto.GCGStartChallengeByCheckRewardReq{}) // GCG开始挑战来自检测奖励请求
|
||||
// c.registerMessage(GCGStartChallengeByCheckRewardRsp, &proto.GCGStartChallengeByCheckRewardRsp{}) // GCG开始挑战来自检测奖励响应
|
||||
// c.registerMessage(GCGStartChallengeReq, &proto.GCGStartChallengeReq{}) // GCG开始挑战请求
|
||||
// c.registerMessage(GCGStartChallengeRsp, &proto.GCGStartChallengeRsp{}) // GCG开始挑战响应
|
||||
|
||||
// 乱七八糟
|
||||
c.registerMessage(MarkMapReq, &proto.MarkMapReq{}) // 标记地图请求
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
enum GCGActionType {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGApplyInviteBattleNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGApplyInviteBattleReq {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGApplyInviteBattleRsp {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGAskDuelReq {
|
||||
|
||||
@@ -18,6 +18,7 @@ syntax = "proto3";
|
||||
|
||||
import "GCGDuel.proto";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGAskDuelRsp {
|
||||
|
||||
@@ -18,6 +18,7 @@ syntax = "proto3";
|
||||
|
||||
import "Uint32Pair.proto";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGAttackCostInfo {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGBackToDuelReq {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGBackToDuelRsp {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGBasicDataNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGBossChallengeData {
|
||||
|
||||
@@ -18,6 +18,7 @@ syntax = "proto3";
|
||||
|
||||
import "GCGBossChallengeData.proto";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGBossChallengeUpdateNotify {
|
||||
|
||||
@@ -19,6 +19,7 @@ syntax = "proto3";
|
||||
import "GCGSkillLimitsInfo.proto";
|
||||
import "GCGToken.proto";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGCard {
|
||||
|
||||
@@ -18,6 +18,7 @@ syntax = "proto3";
|
||||
|
||||
import "GCGSkillLimitsInfo.proto";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGCardSkillLimitsInfo {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGChallengeData {
|
||||
|
||||
@@ -18,6 +18,7 @@ syntax = "proto3";
|
||||
|
||||
import "GCGDuelChallenge.proto";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGChallengeUpdateNotify {
|
||||
|
||||
@@ -18,6 +18,7 @@ syntax = "proto3";
|
||||
|
||||
import "GCGSkillPreviewInfo.proto";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGChangeOnstageInfo {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
enum GCGClientPerformType {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGClientSettleReq {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGClientSettleRsp {
|
||||
|
||||
@@ -18,6 +18,7 @@ syntax = "proto3";
|
||||
|
||||
import "ProfilePicture.proto";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGControllerShowInfo {
|
||||
|
||||
@@ -20,6 +20,7 @@ import "GCGAttackCostInfo.proto";
|
||||
import "GCGPlayCardCostInfo.proto";
|
||||
import "GCGSelectOnStageCostInfo.proto";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGCostReviseInfo {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSBanCardNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSCardBackUnlockNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSCardData {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSCardFaceUnlockNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSCardFaceUpdateNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSCardNumChangeNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSCardProficiencyNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSChangeCardBackReq {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSChangeCardBackRsp {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSChangeCardFaceReq {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSChangeCardFaceRsp {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSChangeCurDeckReq {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSChangeCurDeckRsp {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSChangeDeckNameReq {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSChangeDeckNameRsp {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSChangeFieldReq {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSChangeFieldRsp {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSCurDeckChangeNotify {
|
||||
|
||||
@@ -19,6 +19,7 @@ syntax = "proto3";
|
||||
import "GCGDSCardData.proto";
|
||||
import "GCGDSDeckData.proto";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSDataNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSDeckData {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSDeckSaveReq {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSDeckSaveRsp {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSDeckUnlockNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSDeckUpdateNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSDeleteDeckReq {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSDeleteDeckRsp {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSFieldUnlockNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSTakeCardProficiencyRewardReq {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDSTakeCardProficiencyRewardRsp {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDamageDetail {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDebugReplayNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
enum GCGDiceSideType {
|
||||
|
||||
@@ -27,6 +27,7 @@ import "GCGPhase.proto";
|
||||
import "GCGPlayerField.proto";
|
||||
import "Unk3300_ADHENCIFKNI.proto";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDuel {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDuelChallenge {
|
||||
|
||||
@@ -19,6 +19,7 @@ syntax = "proto3";
|
||||
import "GCGChallengeData.proto";
|
||||
import "PlatformType.proto";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGDuelExtra {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
enum GCGEndReason {
|
||||
|
||||
@@ -19,6 +19,7 @@ syntax = "proto3";
|
||||
import "GCGGameBusinessType.proto";
|
||||
import "GCGPlayerBriefData.proto";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGGameBriefData {
|
||||
|
||||
@@ -18,6 +18,7 @@ syntax = "proto3";
|
||||
|
||||
import "GCGGameBriefData.proto";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGGameBriefDataNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
enum GCGGameBusinessType {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGGameCreateFailReasonNotify {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "./;proto";
|
||||
|
||||
message GCGGameMaxNotify {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user