mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-03-01 00:35:36 +08:00
优化
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
|||||||
"hk4e/common/config"
|
"hk4e/common/config"
|
||||||
"hk4e/common/mq"
|
"hk4e/common/mq"
|
||||||
"hk4e/common/rpc"
|
"hk4e/common/rpc"
|
||||||
|
"hk4e/gdconf"
|
||||||
"hk4e/node/api"
|
"hk4e/node/api"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
)
|
)
|
||||||
@@ -61,6 +62,8 @@ func Run(ctx context.Context, configFile string) error {
|
|||||||
logger.CloseLogger()
|
logger.CloseLogger()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
gdconf.InitGameDataConfig()
|
||||||
|
|
||||||
messageQueue := mq.NewMessageQueue(api.ANTICHEAT, APPID, client)
|
messageQueue := mq.NewMessageQueue(api.ANTICHEAT, APPID, client)
|
||||||
defer messageQueue.Close()
|
defer messageQueue.Close()
|
||||||
|
|
||||||
|
|||||||
+102
-29
@@ -7,6 +7,7 @@ import (
|
|||||||
"hk4e/common/constant"
|
"hk4e/common/constant"
|
||||||
"hk4e/common/mq"
|
"hk4e/common/mq"
|
||||||
"hk4e/gate/kcp"
|
"hk4e/gate/kcp"
|
||||||
|
"hk4e/gdconf"
|
||||||
"hk4e/node/api"
|
"hk4e/node/api"
|
||||||
"hk4e/pkg/logger"
|
"hk4e/pkg/logger"
|
||||||
"hk4e/protocol/cmd"
|
"hk4e/protocol/cmd"
|
||||||
@@ -16,8 +17,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MoveVectorCacheNum = 100
|
MoveVectorCacheNum = 10
|
||||||
MaxMoveSpeed = 50.0
|
MaxMoveSpeed = 30.0
|
||||||
|
JumpDistance = 100.0
|
||||||
|
PointDistance = 10.0
|
||||||
)
|
)
|
||||||
|
|
||||||
type MoveVector struct {
|
type MoveVector struct {
|
||||||
@@ -26,15 +29,41 @@ type MoveVector struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type AnticheatContext struct {
|
type AnticheatContext struct {
|
||||||
|
sceneId uint32
|
||||||
moveVectorList []*MoveVector
|
moveVectorList []*MoveVector
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AnticheatContext) Move(pos *proto.Vector) {
|
func (a *AnticheatContext) Move(pos *proto.Vector) bool {
|
||||||
now := time.Now().UnixMilli()
|
now := time.Now().UnixMilli()
|
||||||
if len(a.moveVectorList) > 0 {
|
if len(a.moveVectorList) > 0 {
|
||||||
lastMoveVector := a.moveVectorList[len(a.moveVectorList)-1]
|
lastMoveVector := a.moveVectorList[len(a.moveVectorList)-1]
|
||||||
if now-lastMoveVector.time < 1000 {
|
if now-lastMoveVector.time < 1000 {
|
||||||
return
|
return true
|
||||||
|
}
|
||||||
|
distance := GetDistance(pos, lastMoveVector.pos)
|
||||||
|
if distance > JumpDistance {
|
||||||
|
// 瞬时变化太大 判断是否为传送
|
||||||
|
scenePointMap := gdconf.GetScenePointMapBySceneId(int32(a.sceneId))
|
||||||
|
if scenePointMap == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
isJump := true
|
||||||
|
for _, pointData := range scenePointMap {
|
||||||
|
d := GetDistance(pos, &proto.Vector{
|
||||||
|
X: float32(pointData.TranPos.X),
|
||||||
|
Y: float32(pointData.TranPos.Y),
|
||||||
|
Z: float32(pointData.TranPos.Z),
|
||||||
|
})
|
||||||
|
if d < PointDistance {
|
||||||
|
isJump = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if isJump {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
a.moveVectorList = make([]*MoveVector, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a.moveVectorList = append(a.moveVectorList, &MoveVector{
|
a.moveVectorList = append(a.moveVectorList, &MoveVector{
|
||||||
@@ -44,6 +73,7 @@ func (a *AnticheatContext) Move(pos *proto.Vector) {
|
|||||||
if len(a.moveVectorList) > MoveVectorCacheNum {
|
if len(a.moveVectorList) > MoveVectorCacheNum {
|
||||||
a.moveVectorList = a.moveVectorList[len(a.moveVectorList)-MoveVectorCacheNum:]
|
a.moveVectorList = a.moveVectorList[len(a.moveVectorList)-MoveVectorCacheNum:]
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AnticheatContext) GetMoveSpeed() float32 {
|
func (a *AnticheatContext) GetMoveSpeed() float32 {
|
||||||
@@ -57,11 +87,7 @@ func (a *AnticheatContext) GetMoveSpeed() float32 {
|
|||||||
}
|
}
|
||||||
nextMoveVector := a.moveVectorList[index+1]
|
nextMoveVector := a.moveVectorList[index+1]
|
||||||
beforeMoveVector := a.moveVectorList[index]
|
beforeMoveVector := a.moveVectorList[index]
|
||||||
dx := float32(math.Sqrt(
|
dx := GetDistance(nextMoveVector.pos, beforeMoveVector.pos)
|
||||||
float64((nextMoveVector.pos.X-beforeMoveVector.pos.X)*(nextMoveVector.pos.X-beforeMoveVector.pos.X)) +
|
|
||||||
float64((nextMoveVector.pos.Y-beforeMoveVector.pos.Y)*(nextMoveVector.pos.Y-beforeMoveVector.pos.Y)) +
|
|
||||||
float64((nextMoveVector.pos.Z-beforeMoveVector.pos.Z)*(nextMoveVector.pos.Z-beforeMoveVector.pos.Z)),
|
|
||||||
))
|
|
||||||
dt := float32(nextMoveVector.time-beforeMoveVector.time) / 1000.0
|
dt := float32(nextMoveVector.time-beforeMoveVector.time) / 1000.0
|
||||||
avgMoveSpeed += dx / dt
|
avgMoveSpeed += dx / dt
|
||||||
}
|
}
|
||||||
@@ -71,6 +97,7 @@ func (a *AnticheatContext) GetMoveSpeed() float32 {
|
|||||||
|
|
||||||
func NewAnticheatContext() *AnticheatContext {
|
func NewAnticheatContext() *AnticheatContext {
|
||||||
r := &AnticheatContext{
|
r := &AnticheatContext{
|
||||||
|
sceneId: 0,
|
||||||
moveVectorList: make([]*MoveVector, 0),
|
moveVectorList: make([]*MoveVector, 0),
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
@@ -81,13 +108,16 @@ type Handle struct {
|
|||||||
playerAcCtxMap map[uint32]*AnticheatContext
|
playerAcCtxMap map[uint32]*AnticheatContext
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handle) AddPlayerAcCtx(userId uint32) {
|
||||||
|
h.playerAcCtxMap[userId] = NewAnticheatContext()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handle) DelPlayerAcCtx(userId uint32) {
|
||||||
|
delete(h.playerAcCtxMap, userId)
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handle) GetPlayerAcCtx(userId uint32) *AnticheatContext {
|
func (h *Handle) GetPlayerAcCtx(userId uint32) *AnticheatContext {
|
||||||
ctx, exist := h.playerAcCtxMap[userId]
|
return h.playerAcCtxMap[userId]
|
||||||
if !exist {
|
|
||||||
ctx = NewAnticheatContext()
|
|
||||||
h.playerAcCtxMap[userId] = ctx
|
|
||||||
}
|
|
||||||
return ctx
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandle(messageQueue *mq.MessageQueue) (r *Handle) {
|
func NewHandle(messageQueue *mq.MessageQueue) (r *Handle) {
|
||||||
@@ -102,19 +132,31 @@ func (h *Handle) run() {
|
|||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
netMsg := <-h.messageQueue.GetNetMsg()
|
netMsg := <-h.messageQueue.GetNetMsg()
|
||||||
if netMsg.MsgType != mq.MsgTypeGame {
|
switch netMsg.MsgType {
|
||||||
continue
|
case mq.MsgTypeGame:
|
||||||
}
|
if netMsg.OriginServerType != api.GATE {
|
||||||
if netMsg.EventId != mq.NormalMsg {
|
continue
|
||||||
continue
|
}
|
||||||
}
|
if netMsg.EventId != mq.NormalMsg {
|
||||||
if netMsg.OriginServerType != api.GATE {
|
continue
|
||||||
continue
|
}
|
||||||
}
|
gameMsg := netMsg.GameMsg
|
||||||
gameMsg := netMsg.GameMsg
|
switch gameMsg.CmdId {
|
||||||
switch gameMsg.CmdId {
|
case cmd.CombatInvocationsNotify:
|
||||||
case cmd.CombatInvocationsNotify:
|
h.CombatInvocationsNotify(gameMsg.UserId, netMsg.OriginServerAppId, gameMsg.PayloadMessage)
|
||||||
h.CombatInvocationsNotify(gameMsg.UserId, netMsg.OriginServerAppId, gameMsg.PayloadMessage)
|
case cmd.ToTheMoonEnterSceneReq:
|
||||||
|
h.ToTheMoonEnterSceneReq(gameMsg.UserId, netMsg.OriginServerAppId, gameMsg.PayloadMessage)
|
||||||
|
}
|
||||||
|
case mq.MsgTypeServer:
|
||||||
|
serverMsg := netMsg.ServerMsg
|
||||||
|
switch netMsg.EventId {
|
||||||
|
case mq.ServerUserOnlineStateChangeNotify:
|
||||||
|
if serverMsg.IsOnline {
|
||||||
|
h.AddPlayerAcCtx(serverMsg.UserId)
|
||||||
|
} else {
|
||||||
|
h.DelPlayerAcCtx(serverMsg.UserId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@@ -133,23 +175,54 @@ func (h *Handle) CombatInvocationsNotify(userId uint32, gateAppId string, payloa
|
|||||||
if GetEntityType(entityMoveInfo.EntityId) != constant.ENTITY_TYPE_AVATAR {
|
if GetEntityType(entityMoveInfo.EntityId) != constant.ENTITY_TYPE_AVATAR {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if entityMoveInfo.MotionInfo.Pos != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
// 玩家超速移动检测
|
// 玩家超速移动检测
|
||||||
ctx := h.GetPlayerAcCtx(userId)
|
ctx := h.GetPlayerAcCtx(userId)
|
||||||
ctx.Move(entityMoveInfo.MotionInfo.Pos)
|
if ctx == nil {
|
||||||
|
logger.Error("get player anticheat context is nil, uid: %v", userId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ok := ctx.Move(entityMoveInfo.MotionInfo.Pos)
|
||||||
|
if !ok {
|
||||||
|
logger.Warn("player move jump, pos: %v, uid: %v", entityMoveInfo.MotionInfo.Pos, userId)
|
||||||
|
h.KickPlayer(userId, gateAppId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
moveSpeed := ctx.GetMoveSpeed()
|
moveSpeed := ctx.GetMoveSpeed()
|
||||||
logger.Debug("player move speed: %v, uid: %v", moveSpeed, userId)
|
logger.Debug("player move speed: %v, uid: %v", moveSpeed, userId)
|
||||||
if moveSpeed > MaxMoveSpeed {
|
if moveSpeed > MaxMoveSpeed {
|
||||||
logger.Warn("player move overspeed, speed: %v, uid: %v", moveSpeed, userId)
|
logger.Warn("player move overspeed, speed: %v, uid: %v", moveSpeed, userId)
|
||||||
h.KickPlayer(userId, gateAppId)
|
h.KickPlayer(userId, gateAppId)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handle) ToTheMoonEnterSceneReq(userId uint32, gateAppId string, payloadMsg pb.Message) {
|
||||||
|
req := payloadMsg.(*proto.ToTheMoonEnterSceneReq)
|
||||||
|
ctx := h.GetPlayerAcCtx(userId)
|
||||||
|
if ctx == nil {
|
||||||
|
logger.Error("get player anticheat context is nil, uid: %v", userId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.sceneId = req.SceneId
|
||||||
|
}
|
||||||
|
|
||||||
func GetEntityType(entityId uint32) int {
|
func GetEntityType(entityId uint32) int {
|
||||||
return int(entityId >> 24)
|
return int(entityId >> 24)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetDistance(v1 *proto.Vector, v2 *proto.Vector) float32 {
|
||||||
|
return float32(math.Sqrt(
|
||||||
|
float64((v1.X-v2.X)*(v1.X-v2.X)) +
|
||||||
|
float64((v1.Y-v2.Y)*(v1.Y-v2.Y)) +
|
||||||
|
float64((v1.Z-v2.Z)*(v1.Z-v2.Z)),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Handle) KickPlayer(userId uint32, gateAppId string) {
|
func (h *Handle) KickPlayer(userId uint32, gateAppId string) {
|
||||||
h.messageQueue.SendToGate(gateAppId, &mq.NetMsg{
|
h.messageQueue.SendToGate(gateAppId, &mq.NetMsg{
|
||||||
MsgType: mq.MsgTypeConnCtrl,
|
MsgType: mq.MsgTypeConnCtrl,
|
||||||
|
|||||||
+19
-13
@@ -124,21 +124,27 @@ func (k *KcpConnectManager) recvMsgHandle(protoMsg *ProtoMsg, session *Session)
|
|||||||
k.serverCmdProtoMap.PutProtoObjCache(protoMsg.CmdId, protoMsg.PayloadMessage)
|
k.serverCmdProtoMap.PutProtoObjCache(protoMsg.CmdId, protoMsg.PayloadMessage)
|
||||||
gameMsg.PayloadMessageData = payloadMessageData
|
gameMsg.PayloadMessageData = payloadMessageData
|
||||||
// 转发到寻路服务器
|
// 转发到寻路服务器
|
||||||
if session.pathfindingServerAppId != "" && (protoMsg.CmdId == cmd.QueryPathReq || protoMsg.CmdId == cmd.ObstacleModifyNotify) {
|
if session.pathfindingServerAppId != "" {
|
||||||
k.messageQueue.SendToPathfinding(session.pathfindingServerAppId, &mq.NetMsg{
|
if protoMsg.CmdId == cmd.QueryPathReq ||
|
||||||
MsgType: mq.MsgTypeGame,
|
protoMsg.CmdId == cmd.ObstacleModifyNotify {
|
||||||
EventId: mq.NormalMsg,
|
k.messageQueue.SendToPathfinding(session.pathfindingServerAppId, &mq.NetMsg{
|
||||||
GameMsg: gameMsg,
|
MsgType: mq.MsgTypeGame,
|
||||||
})
|
EventId: mq.NormalMsg,
|
||||||
return
|
GameMsg: gameMsg,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 转发到反作弊服务器
|
// 转发到反作弊服务器
|
||||||
if session.anticheatServerAppId != "" && protoMsg.CmdId == cmd.CombatInvocationsNotify {
|
if session.anticheatServerAppId != "" {
|
||||||
k.messageQueue.SendToAnticheat(session.anticheatServerAppId, &mq.NetMsg{
|
if protoMsg.CmdId == cmd.CombatInvocationsNotify ||
|
||||||
MsgType: mq.MsgTypeGame,
|
protoMsg.CmdId == cmd.ToTheMoonEnterSceneReq {
|
||||||
EventId: mq.NormalMsg,
|
k.messageQueue.SendToAnticheat(session.anticheatServerAppId, &mq.NetMsg{
|
||||||
GameMsg: gameMsg,
|
MsgType: mq.MsgTypeGame,
|
||||||
})
|
EventId: mq.NormalMsg,
|
||||||
|
GameMsg: gameMsg,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 转发到GS
|
// 转发到GS
|
||||||
k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{
|
k.messageQueue.SendToGs(session.gsServerAppId, &mq.NetMsg{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
// ChestDropData 宝箱掉落配置表
|
// ChestDropData 宝箱掉落配置表
|
||||||
type ChestDropData struct {
|
type ChestDropData struct {
|
||||||
Level int32 `csv:"最小等级"`
|
MinLevel int32 `csv:"最小等级"`
|
||||||
DropTag string `csv:"总索引"`
|
DropTag string `csv:"总索引"`
|
||||||
DropId int32 `csv:"掉落ID,omitempty"`
|
DropId int32 `csv:"掉落ID,omitempty"`
|
||||||
DropCount int32 `csv:"掉落次数,omitempty"`
|
DropCount int32 `csv:"掉落次数,omitempty"`
|
||||||
@@ -21,7 +21,7 @@ func (g *GameDataConfig) loadChestDropData() {
|
|||||||
if !exist {
|
if !exist {
|
||||||
g.ChestDropDataMap[chestDropData.DropTag] = make(map[int32]*ChestDropData)
|
g.ChestDropDataMap[chestDropData.DropTag] = make(map[int32]*ChestDropData)
|
||||||
}
|
}
|
||||||
g.ChestDropDataMap[chestDropData.DropTag][chestDropData.Level] = chestDropData
|
g.ChestDropDataMap[chestDropData.DropTag][chestDropData.MinLevel] = chestDropData
|
||||||
}
|
}
|
||||||
logger.Info("ChestDropData count: %v", len(g.ChestDropDataMap))
|
logger.Info("ChestDropData count: %v", len(g.ChestDropDataMap))
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,16 @@ func GetChestDropDataByDropTagAndLevel(dropTag string, level int32) *ChestDropDa
|
|||||||
if !exist {
|
if !exist {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return value[level]
|
resultLevel := int32(0)
|
||||||
|
for minLevel := range value {
|
||||||
|
if level < minLevel {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if minLevel > resultLevel {
|
||||||
|
resultLevel = minLevel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value[resultLevel]
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetChestDropDataMap() map[string]map[int32]*ChestDropData {
|
func GetChestDropDataMap() map[string]map[int32]*ChestDropData {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
// MonsterDropData 怪物掉落配置表
|
// MonsterDropData 怪物掉落配置表
|
||||||
type MonsterDropData struct {
|
type MonsterDropData struct {
|
||||||
Level int32 `csv:"最小等级"`
|
MinLevel int32 `csv:"最小等级"`
|
||||||
DropTag string `csv:"总索引"`
|
DropTag string `csv:"总索引"`
|
||||||
DropId int32 `csv:"掉落ID,omitempty"`
|
DropId int32 `csv:"掉落ID,omitempty"`
|
||||||
DropCount int32 `csv:"掉落次数,omitempty"`
|
DropCount int32 `csv:"掉落次数,omitempty"`
|
||||||
@@ -21,7 +21,7 @@ func (g *GameDataConfig) loadMonsterDropData() {
|
|||||||
if !exist {
|
if !exist {
|
||||||
g.MonsterDropDataMap[monsterDropData.DropTag] = make(map[int32]*MonsterDropData)
|
g.MonsterDropDataMap[monsterDropData.DropTag] = make(map[int32]*MonsterDropData)
|
||||||
}
|
}
|
||||||
g.MonsterDropDataMap[monsterDropData.DropTag][monsterDropData.Level] = monsterDropData
|
g.MonsterDropDataMap[monsterDropData.DropTag][monsterDropData.MinLevel] = monsterDropData
|
||||||
}
|
}
|
||||||
logger.Info("MonsterDropData count: %v", len(g.MonsterDropDataMap))
|
logger.Info("MonsterDropData count: %v", len(g.MonsterDropDataMap))
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,16 @@ func GetMonsterDropDataByDropTagAndLevel(dropTag string, level int32) *MonsterDr
|
|||||||
if !exist {
|
if !exist {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return value[level]
|
resultLevel := int32(0)
|
||||||
|
for minLevel := range value {
|
||||||
|
if level < minLevel {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if minLevel > resultLevel {
|
||||||
|
resultLevel = minLevel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value[resultLevel]
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMonsterDropDataMap() map[string]map[int32]*MonsterDropData {
|
func GetMonsterDropDataMap() map[string]map[int32]*MonsterDropData {
|
||||||
|
|||||||
@@ -432,9 +432,9 @@ func getTempFightPropMap() map[uint32]float32 {
|
|||||||
constant.FIGHT_PROP_CUR_ATTACK: float32(50.0),
|
constant.FIGHT_PROP_CUR_ATTACK: float32(50.0),
|
||||||
constant.FIGHT_PROP_BASE_DEFENSE: float32(500.0),
|
constant.FIGHT_PROP_BASE_DEFENSE: float32(500.0),
|
||||||
constant.FIGHT_PROP_CUR_DEFENSE: float32(500.0),
|
constant.FIGHT_PROP_CUR_DEFENSE: float32(500.0),
|
||||||
constant.FIGHT_PROP_BASE_HP: float32(100000.0),
|
constant.FIGHT_PROP_BASE_HP: float32(10000.0),
|
||||||
constant.FIGHT_PROP_CUR_HP: float32(100000.0),
|
constant.FIGHT_PROP_CUR_HP: float32(10000.0),
|
||||||
constant.FIGHT_PROP_MAX_HP: float32(100000.0),
|
constant.FIGHT_PROP_MAX_HP: float32(10000.0),
|
||||||
constant.FIGHT_PROP_PHYSICAL_SUB_HURT: float32(0.1),
|
constant.FIGHT_PROP_PHYSICAL_SUB_HURT: float32(0.1),
|
||||||
constant.FIGHT_PROP_ICE_SUB_HURT: float32(0.1),
|
constant.FIGHT_PROP_ICE_SUB_HURT: float32(0.1),
|
||||||
constant.FIGHT_PROP_FIRE_SUB_HURT: float32(0.1),
|
constant.FIGHT_PROP_FIRE_SUB_HURT: float32(0.1),
|
||||||
|
|||||||
+1
-22
@@ -553,27 +553,7 @@ func (g *Game) KillEntity(player *model.Player, scene *Scene, entityId uint32, d
|
|||||||
entity.fightProp[constant.FIGHT_PROP_CUR_HP] = 0
|
entity.fightProp[constant.FIGHT_PROP_CUR_HP] = 0
|
||||||
g.EntityFightPropUpdateNotifyBroadcast(scene.world, entity)
|
g.EntityFightPropUpdateNotifyBroadcast(scene.world, entity)
|
||||||
// 随机掉落
|
// 随机掉落
|
||||||
sceneGroupConfig := gdconf.GetSceneGroup(int32(entity.GetGroupId()))
|
g.monsterDrop(player, entity)
|
||||||
monsterConfig := sceneGroupConfig.MonsterMap[int32(entity.GetConfigId())]
|
|
||||||
monsterDropDataConfig := gdconf.GetMonsterDropDataByDropTagAndLevel(monsterConfig.DropTag, monsterConfig.Level)
|
|
||||||
if monsterDropDataConfig == nil {
|
|
||||||
logger.Error("get monster drop data config is nil, monsterConfig: %v, uid: %v", monsterConfig, player.PlayerID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dropDataConfig := gdconf.GetDropDataById(monsterDropDataConfig.DropId)
|
|
||||||
if dropDataConfig == nil {
|
|
||||||
logger.Error("get drop data config is nil, dropId: %v, uid: %v", monsterDropDataConfig.DropId, player.PlayerID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
totalItemMap := g.doRandDropFullTimes(dropDataConfig, int(monsterDropDataConfig.DropCount))
|
|
||||||
for itemId, count := range totalItemMap {
|
|
||||||
itemDataConfig := gdconf.GetItemDataById(int32(itemId))
|
|
||||||
if itemDataConfig == nil {
|
|
||||||
logger.Error("get item data config is nil, itemId: %v, uid: %v", itemId, player.PlayerID)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
g.CreateDropGadget(player, entity.pos, uint32(itemDataConfig.GadgetId), itemId, count)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
entity.lifeState = constant.LIFE_STATE_DEAD
|
entity.lifeState = constant.LIFE_STATE_DEAD
|
||||||
ntf := &proto.LifeStateChangeNotify{
|
ntf := &proto.LifeStateChangeNotify{
|
||||||
@@ -588,7 +568,6 @@ func (g *Game) KillEntity(player *model.Player, scene *Scene, entityId uint32, d
|
|||||||
scene.DestroyEntity(entity.GetId())
|
scene.DestroyEntity(entity.GetId())
|
||||||
group := scene.GetGroupById(entity.groupId)
|
group := scene.GetGroupById(entity.groupId)
|
||||||
if group == nil {
|
if group == nil {
|
||||||
logger.Error("get scene group is nil, groupId: %v, uid: %v", entity.groupId, player.PlayerID)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
group.DestroyEntity(entity.GetId())
|
group.DestroyEntity(entity.GetId())
|
||||||
|
|||||||
+49
-21
@@ -337,27 +337,7 @@ func (g *Game) GadgetInteractReq(player *model.Player, payloadMsg pb.Message) {
|
|||||||
// 宝箱交互结束 开启宝箱
|
// 宝箱交互结束 开启宝箱
|
||||||
if req.OpType == proto.InterOpType_INTER_OP_FINISH {
|
if req.OpType == proto.InterOpType_INTER_OP_FINISH {
|
||||||
// 随机掉落
|
// 随机掉落
|
||||||
sceneGroupConfig := gdconf.GetSceneGroup(int32(entity.GetGroupId()))
|
g.chestDrop(player, entity)
|
||||||
gadgetConfig := sceneGroupConfig.GadgetMap[int32(entity.GetConfigId())]
|
|
||||||
chestDropDataConfig := gdconf.GetChestDropDataByDropTagAndLevel(gadgetConfig.DropTag, gadgetConfig.Level)
|
|
||||||
if chestDropDataConfig == nil {
|
|
||||||
logger.Error("get chest drop data config is nil, gadgetConfig: %v, uid: %v", gadgetConfig, player.PlayerID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dropDataConfig := gdconf.GetDropDataById(chestDropDataConfig.DropId)
|
|
||||||
if dropDataConfig == nil {
|
|
||||||
logger.Error("get drop data config is nil, dropId: %v, uid: %v", chestDropDataConfig.DropId, player.PlayerID)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
totalItemMap := g.doRandDropFullTimes(dropDataConfig, int(chestDropDataConfig.DropCount))
|
|
||||||
for itemId, count := range totalItemMap {
|
|
||||||
itemDataConfig := gdconf.GetItemDataById(int32(itemId))
|
|
||||||
if itemDataConfig == nil {
|
|
||||||
logger.Error("get item data config is nil, itemId: %v, uid: %v", itemId, player.PlayerID)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
g.CreateDropGadget(player, entity.pos, uint32(itemDataConfig.GadgetId), itemId, count)
|
|
||||||
}
|
|
||||||
// 更新宝箱状态
|
// 更新宝箱状态
|
||||||
g.SendMsg(cmd.WorldChestOpenNotify, player.PlayerID, player.ClientSeq, &proto.WorldChestOpenNotify{
|
g.SendMsg(cmd.WorldChestOpenNotify, player.PlayerID, player.ClientSeq, &proto.WorldChestOpenNotify{
|
||||||
GroupId: entity.GetGroupId(),
|
GroupId: entity.GetGroupId(),
|
||||||
@@ -378,6 +358,54 @@ func (g *Game) GadgetInteractReq(player *model.Player, payloadMsg pb.Message) {
|
|||||||
g.SendMsg(cmd.GadgetInteractRsp, player.PlayerID, player.ClientSeq, rsp)
|
g.SendMsg(cmd.GadgetInteractRsp, player.PlayerID, player.ClientSeq, rsp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (g *Game) monsterDrop(player *model.Player, entity *Entity) {
|
||||||
|
sceneGroupConfig := gdconf.GetSceneGroup(int32(entity.GetGroupId()))
|
||||||
|
monsterConfig := sceneGroupConfig.MonsterMap[int32(entity.GetConfigId())]
|
||||||
|
monsterDropDataConfig := gdconf.GetMonsterDropDataByDropTagAndLevel(monsterConfig.DropTag, monsterConfig.Level)
|
||||||
|
if monsterDropDataConfig == nil {
|
||||||
|
logger.Error("get monster drop data config is nil, monsterConfig: %v, uid: %v", monsterConfig, player.PlayerID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dropDataConfig := gdconf.GetDropDataById(monsterDropDataConfig.DropId)
|
||||||
|
if dropDataConfig == nil {
|
||||||
|
logger.Error("get drop data config is nil, dropId: %v, uid: %v", monsterDropDataConfig.DropId, player.PlayerID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
totalItemMap := g.doRandDropFullTimes(dropDataConfig, int(monsterDropDataConfig.DropCount))
|
||||||
|
for itemId, count := range totalItemMap {
|
||||||
|
itemDataConfig := gdconf.GetItemDataById(int32(itemId))
|
||||||
|
if itemDataConfig == nil {
|
||||||
|
logger.Error("get item data config is nil, itemId: %v, uid: %v", itemId, player.PlayerID)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
g.CreateDropGadget(player, entity.pos, uint32(itemDataConfig.GadgetId), itemId, count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Game) chestDrop(player *model.Player, entity *Entity) {
|
||||||
|
sceneGroupConfig := gdconf.GetSceneGroup(int32(entity.GetGroupId()))
|
||||||
|
gadgetConfig := sceneGroupConfig.GadgetMap[int32(entity.GetConfigId())]
|
||||||
|
chestDropDataConfig := gdconf.GetChestDropDataByDropTagAndLevel(gadgetConfig.DropTag, gadgetConfig.Level)
|
||||||
|
if chestDropDataConfig == nil {
|
||||||
|
logger.Error("get chest drop data config is nil, gadgetConfig: %v, uid: %v", gadgetConfig, player.PlayerID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dropDataConfig := gdconf.GetDropDataById(chestDropDataConfig.DropId)
|
||||||
|
if dropDataConfig == nil {
|
||||||
|
logger.Error("get drop data config is nil, dropId: %v, uid: %v", chestDropDataConfig.DropId, player.PlayerID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
totalItemMap := g.doRandDropFullTimes(dropDataConfig, int(chestDropDataConfig.DropCount))
|
||||||
|
for itemId, count := range totalItemMap {
|
||||||
|
itemDataConfig := gdconf.GetItemDataById(int32(itemId))
|
||||||
|
if itemDataConfig == nil {
|
||||||
|
logger.Error("get item data config is nil, itemId: %v, uid: %v", itemId, player.PlayerID)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
g.CreateDropGadget(player, entity.pos, uint32(itemDataConfig.GadgetId), itemId, count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (g *Game) doRandDropFullTimes(dropDataConfig *gdconf.DropData, times int) map[uint32]uint32 {
|
func (g *Game) doRandDropFullTimes(dropDataConfig *gdconf.DropData, times int) map[uint32]uint32 {
|
||||||
totalItemMap := make(map[uint32]uint32)
|
totalItemMap := make(map[uint32]uint32)
|
||||||
for i := 0; i < times; i++ {
|
for i := 0; i < times; i++ {
|
||||||
|
|||||||
Reference in New Issue
Block a user