feat(rpc): 优化客户端连接管理,使用 sync.Map 替代普通 map
将 `Clientmap` 从普通 map 改为 `sync.Map`,提升并发安全性。新增 `addClient` 和 `getClient` 方法封装存取逻辑,并在多处调用点进行了替换。 fix(fight): 修复战斗逻辑中技能ID与攻击时间字段引用错误 将 `attacker.AttackValue.SkillID` 和 `attacker.AttackValue.AttackTime` 的访问方式修正为正确的字段路径。 refactor(fight): 调整战斗结束信息处理流程 合并 `FightOverInfo` 结构到 `FightC` 中,简化广播发送逻辑,统一通过 `f.FightOverInfo` 发送战斗结果。 refactor(effect): 修改效果叠加判断逻辑并增强健壮性 更新效果节点比较方法,增加参数匹配检查以支持更精确的效果识别;同时添加 `equalInts` 工具函数用于数组内容对比。
This commit is contained in:
@@ -20,6 +20,7 @@ func GetServerInfoList() []ServerInfo {
|
||||
var ret1 []ServerInfo
|
||||
ip, _ := service.NewBaseSysParamService().DataByKey(context.Background(), "server_ip")
|
||||
testip, _ := service.NewBaseSysParamService().DataByKey(context.Background(), "test_ip")
|
||||
|
||||
for _, v := range ret {
|
||||
tt := newServerInfo()
|
||||
tt.OnlineID = uint32(v.OnlineID)
|
||||
@@ -30,7 +31,8 @@ func GetServerInfoList() []ServerInfo {
|
||||
tt.IP = testip
|
||||
}
|
||||
tt.Port = v.Port
|
||||
t, ok := Clientmap[v.Port]
|
||||
|
||||
t, ok := getClient(v.Port)
|
||||
|
||||
if ok {
|
||||
cool.Loger.Info(context.TODO(), "服务器假踢人")
|
||||
|
||||
@@ -3,6 +3,7 @@ package rpc
|
||||
import (
|
||||
"blazing/common/data/share"
|
||||
"blazing/cool"
|
||||
"sync"
|
||||
|
||||
"blazing/modules/base/service"
|
||||
"context"
|
||||
@@ -18,7 +19,26 @@ import (
|
||||
|
||||
var rpcport = gconv.String(cool.Config.RPC)
|
||||
|
||||
var Clientmap = make(map[uint16]*ClientHandler) //客户端map
|
||||
// 定义改为sync.Map
|
||||
var Clientmap sync.Map
|
||||
|
||||
// 存值示例
|
||||
func addClient(id uint16, client *ClientHandler) {
|
||||
// 普通map:Clientmap[id] = client
|
||||
Clientmap.Store(id, client) // sync.Map存值
|
||||
}
|
||||
|
||||
// 取值示例
|
||||
func getClient(id uint16) (*ClientHandler, bool) {
|
||||
// 普通map:client, ok := Clientmap[id]
|
||||
val, ok := Clientmap.Load(id) // sync.Map取值
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
// 类型断言(确保value是*ClientHandler)
|
||||
client, ok := val.(*ClientHandler)
|
||||
return client, ok
|
||||
}
|
||||
|
||||
type ClientHandler struct {
|
||||
KickPerson func(uint32) error //踢人,这里是返回具体的logic
|
||||
@@ -37,7 +57,8 @@ func (h *ServerHandler) Kick(ctx context.Context, userid uint32) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("user not found", err)
|
||||
}
|
||||
cl, ok := Clientmap[useid1]
|
||||
|
||||
cl, ok := getClient(useid1)
|
||||
if ok {
|
||||
err := cl.KickPerson(userid) //实现指定服务器踢人
|
||||
if err != nil {
|
||||
@@ -57,11 +78,11 @@ func (h *ServerHandler) RegisterLogic(ctx context.Context, id, port uint16) erro
|
||||
return fmt.Errorf("no reverse client")
|
||||
}
|
||||
t, _ := blservice.NewLoginServiceService().GetServerID(id)
|
||||
aa, ok := Clientmap[t]
|
||||
aa, ok := getClient(t)
|
||||
if ok && aa != nil { //如果已经存在且这个端口已经被存过
|
||||
aa.QuitSelf(0)
|
||||
}
|
||||
Clientmap[port] = &revClient
|
||||
addClient(port, &revClient)
|
||||
|
||||
//Refurh()
|
||||
return nil
|
||||
|
||||
@@ -64,9 +64,9 @@ func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *pla
|
||||
-1,
|
||||
0, //野怪没特性
|
||||
0,
|
||||
2)
|
||||
bm.Lv)
|
||||
|
||||
mo.Level = uint32(bm.Lv)
|
||||
// mo.Level = uint32(bm.Lv)
|
||||
mo.CalculatePetPane()
|
||||
mo.Hp = uint32(bm.Hp)
|
||||
mo.MaxHp = uint32(bm.Hp)
|
||||
|
||||
@@ -89,15 +89,11 @@ func (u *UseItemAction) Priority() int {
|
||||
// EscapeAction 逃跑的战斗动作
|
||||
type EscapeAction struct {
|
||||
BaseAction
|
||||
Reason info.FightOverInfo
|
||||
Reason info.EnumBattleOverReason
|
||||
Our common.PlayerI
|
||||
Opp common.PlayerI
|
||||
}
|
||||
|
||||
func (e *EscapeAction) GetInfo() info.FightOverInfo {
|
||||
return e.Reason
|
||||
}
|
||||
|
||||
// Priority 返回动作优先级
|
||||
func (e *EscapeAction) Priority() int {
|
||||
return int(PlayerOperations.Escape)
|
||||
|
||||
@@ -23,7 +23,7 @@ func newEffectStat(targetOpponent bool) input.Effect {
|
||||
e := &EffectStat{
|
||||
Etype: targetOpponent,
|
||||
}
|
||||
e.MaxStack(-1) // 无限叠加
|
||||
//e.MaxStack(-1) // 无限叠加
|
||||
return e
|
||||
}
|
||||
|
||||
|
||||
@@ -11,9 +11,12 @@ import (
|
||||
*/
|
||||
|
||||
func init() {
|
||||
input.InitEffect(input.EffectType.Skill, 9, &Effect9{
|
||||
t := &Effect9{
|
||||
EffectNode: node.EffectNode{},
|
||||
})
|
||||
}
|
||||
t.Duration(-1)
|
||||
t.MaxStack(-1)
|
||||
input.InitEffect(input.EffectType.Skill, 9, t)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ type FightC struct {
|
||||
First *input.Input
|
||||
Second *input.Input
|
||||
closefight bool
|
||||
info.FightOverInfo
|
||||
}
|
||||
|
||||
func (f *FightC) CanEscape() bool {
|
||||
@@ -274,8 +275,8 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *action.S
|
||||
//技能miss+效果生效 这里属于强制改命中效果,但是正常来说,技能miss掉后效果也应该失效
|
||||
//技能失效+效果失效
|
||||
// 记录技能信息
|
||||
attacker.AttackValue.SkillID = uint32(a.ID) //获取技能ID
|
||||
if attacker.AttackValue.AttackTime > 0 { //如果命中
|
||||
attacker.SkillID = uint32(a.ID) //获取技能ID
|
||||
if attacker.AttackTime > 0 { //如果命中
|
||||
|
||||
attacker.UseSkill(defender, a) //暴击计算
|
||||
attacker.AttackValue.IsCritical = a.Crit
|
||||
@@ -366,6 +367,7 @@ func copyskill(t *action.SelectSkillAction) *action.SelectSkillAction {
|
||||
func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
|
||||
|
||||
if f.closefight { //战斗结束
|
||||
|
||||
return
|
||||
}
|
||||
// 伤害值
|
||||
@@ -526,13 +528,8 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) {
|
||||
} else {
|
||||
WinnerId = f.Second.Player.GetInfo().UserID
|
||||
}
|
||||
defer f.Broadcast(func(ff *input.Input) {
|
||||
//todo 将血量和技能pp传回enterturn
|
||||
f.FightOverInfo.WinnerId = WinnerId
|
||||
|
||||
ff.Player.SendFightEndInfo(info.FightOverInfo{
|
||||
WinnerId: WinnerId,
|
||||
})
|
||||
})
|
||||
f.closefight = true
|
||||
|
||||
}
|
||||
|
||||
@@ -261,11 +261,14 @@ type ReadyFightPetInfo struct {
|
||||
|
||||
// FightOverInfo 战斗结束信息结构体 2506
|
||||
type FightOverInfo struct {
|
||||
//0 正常结束
|
||||
//1=isPlayerLost 对方玩家退出
|
||||
// 2=isOvertime 正常对战结束?有质疑
|
||||
// 2=isOvertime 超时
|
||||
// 3=isDraw 双方平手
|
||||
// 4=isSysError 系统错误
|
||||
// 5=isNpcEscape 精灵主动逃跑
|
||||
|
||||
//7 切磋结束
|
||||
Reason EnumBattleOverReason // 固定值0
|
||||
WinnerId uint32 // 胜者的米米号 野怪为0
|
||||
TwoTimes uint32 // 双倍经验剩余次数
|
||||
|
||||
@@ -294,6 +294,9 @@ func (i *Input) GetAction(opp *Input) {
|
||||
allSkills := make([]skillWithDamage, 0, len(skills))
|
||||
|
||||
for _, s := range skills {
|
||||
if s == nil {
|
||||
continue
|
||||
}
|
||||
// 计算技能对对方的伤害(假设CalculatePower返回伤害值,或需从技能中获取)
|
||||
damage := i.CalculatePower(opp, s)
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ func (c *Input) GetProp(id int, istue bool) int {
|
||||
func (c *Input) GetEffect(etype EnumEffectType, id int) Effect {
|
||||
var ret []Effect
|
||||
for _, v := range c.Effects {
|
||||
if v.ID() == id &&v.Alive(){
|
||||
if v.ID() == id+int(etype) && v.Alive() {
|
||||
ret = append(ret, v)
|
||||
}
|
||||
|
||||
@@ -99,6 +99,21 @@ func (c *Input) GetCurrAttr(id int) *model.PetInfo {
|
||||
//todo 获取后GetEffect
|
||||
}
|
||||
|
||||
// 比较两个[]int是否内容相等
|
||||
func equalInts(a, b []int) bool {
|
||||
// 先判断长度是否相等
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
// 逐个比较元素
|
||||
for i := range a {
|
||||
if a[i] != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *Input) AddEffect(e Effect) {
|
||||
|
||||
//todo 免疫
|
||||
@@ -106,19 +121,25 @@ func (c *Input) AddEffect(e Effect) {
|
||||
fmt.Println("产生回合数", e.ID(), e.Duration())
|
||||
// 如果已有同 ID 的效果,尝试叠加
|
||||
for _, v := range c.Effects {
|
||||
if v.ID() == e.ID() && v.Alive() {
|
||||
//如果效果相同,id相同,参数相同,就是同一个,确认是否可以叠加,正常来说本身就可以共存
|
||||
//衰弱本身参数也是相同的,区别只是传入的回合数不一样和层数不一样
|
||||
|
||||
if v.MaxStack() > 0 {
|
||||
e.Alive(false) //取消之前效果
|
||||
if v.Stack() <= v.MaxStack() { //如果小于最大叠层,状态可以叠层
|
||||
e.SetArgs(v.GetInput(), v.GetArgs()...) //参数输入
|
||||
e.Stack(v.Stack() + e.Stack()) //获取到当前叠层数然后叠加
|
||||
//v.Duration(e.Duration()) //回合数覆盖
|
||||
}
|
||||
if v.ID() == e.ID() &&
|
||||
v.Alive() &&
|
||||
equalInts(v.GetArgs(), e.GetArgs()) &&
|
||||
v.MaxStack() != 0 { //如果层数可以叠加或者是无限层数
|
||||
|
||||
///e.Alive(false) //取消之前效果
|
||||
if v.Stack() <= v.MaxStack() { //如果小于最大叠层,状态可以叠层
|
||||
|
||||
e.Stack(v.Stack() + e.Stack()) //获取到当前叠层数然后叠加
|
||||
//这里直接返回,不再继续执行后续效果,因为这里是可以叠加的效果
|
||||
//v.Duration(e.Duration()) //回合数覆盖
|
||||
|
||||
}
|
||||
c.Effects = append(c.Effects, e)
|
||||
return
|
||||
// c.Effects = append(c.Effects, e)
|
||||
//return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,12 @@ func (f *FightC) battleLoop() {
|
||||
|
||||
for {
|
||||
if f.closefight {
|
||||
f.Broadcast(func(ff *input.Input) {
|
||||
//todo 将血量和技能pp传回enterturn
|
||||
|
||||
ff.Player.SendFightEndInfo(f.FightOverInfo)
|
||||
|
||||
})
|
||||
close(f.actionChan)
|
||||
break
|
||||
}
|
||||
@@ -119,9 +125,9 @@ func (f *FightC) resolveRound(p1Action, p2Action action.BattleActionI) {
|
||||
switch a := b1.(type) {
|
||||
|
||||
case *action.EscapeAction:
|
||||
f.Broadcast(func(ff *input.Input) {
|
||||
ff.Player.SendFightEndInfo(a.Reason)
|
||||
})
|
||||
f.FightOverInfo.WinnerId = b2.GetPlayerID() //对方胜利
|
||||
f.FightOverInfo.Reason = a.Reason
|
||||
|
||||
f.closefight = true
|
||||
|
||||
case *action.ActiveSwitchAction:
|
||||
@@ -154,7 +160,9 @@ func (f *FightC) handleItemAction(a *action.UseItemAction, other action.BattleAc
|
||||
CatchTime: uint32(f.Opp.CurrentPet.Info.CatchTime),
|
||||
PetId: uint32(f.Opp.CurrentPet.ID),
|
||||
})
|
||||
our.SendFightEndInfo(info.FightOverInfo{WinnerId: f.ownerID})
|
||||
//f.WinnerId = 0 //捕捉成功不算胜利
|
||||
f.Reason = 6
|
||||
|
||||
f.closefight = true
|
||||
} else {
|
||||
our.CatchPetInfo(info.CatchMonsterOutboundInfo{})
|
||||
|
||||
@@ -31,17 +31,9 @@ func (f *FightC) Compare(a, b action.BattleActionI) (action.BattleActionI, actio
|
||||
func (f *FightC) Over(c common.PlayerI, res info.EnumBattleOverReason) {
|
||||
ret := &action.EscapeAction{
|
||||
BaseAction: action.NewBaseAction(c.GetInfo().UserID),
|
||||
Reason: info.FightOverInfo{
|
||||
|
||||
Reason: res,
|
||||
},
|
||||
Reason: res,
|
||||
}
|
||||
if c.GetInfo().UserID == f.ownerID {
|
||||
ret.Reason.WinnerId = f.Opp.Player.GetInfo().UserID
|
||||
|
||||
} else {
|
||||
ret.Reason.WinnerId = f.Our.Player.GetInfo().UserID
|
||||
}
|
||||
f.actionChan <- ret
|
||||
}
|
||||
|
||||
|
||||
BIN
public/login
BIN
public/login
Binary file not shown.
Reference in New Issue
Block a user