package fishing import ( "fmt" "mongo.games.com/game/common" "mongo.games.com/game/gamesrv/base" "mongo.games.com/game/proto" fishing_proto "mongo.games.com/game/protocol/fishing" "mongo.games.com/game/srvdata" "mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/netlib" "strconv" "strings" ) type ErrorString struct { code string } func (this *ErrorString) Error() string { return this.code } // 装载完毕 type CSLoadCompletePacketFactory struct { } type CSLoadCompleteHandler struct { } func (this *CSLoadCompletePacketFactory) CreatePacket() interface{} { pack := &fishing_proto.CSLoadComplete{} return pack } func (this *CSLoadCompleteHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { _, ok := data.(*fishing_proto.CSLoadComplete) if ok == false { return &ErrorString{code: "CSLoadComplete serialize error."} } player := base.PlayerMgrSington.GetPlayer(sid) if player != nil { if player.GetScene() != nil { //fsd := player.GetScene().GetExtraData().(*FishingSceneData) //if fsd != nil { // fsd.SyncFish(player) //} } } return nil } // 捕鱼 type CSFishingOpPacketFactory struct { } type CSFishingOpHandler struct { } func (this *CSFishingOpPacketFactory) CreatePacket() interface{} { pack := &fishing_proto.CSFishingOp{} return pack } func (this *CSFishingOpHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { //logger.Logger.Trace("CSFishingOpHandler Process recv ", data) if msg, ok := data.(*fishing_proto.CSFishingOp); ok { p := base.PlayerMgrSington.GetPlayer(sid) if p == nil { logger.Logger.Warn("CSFishingOpHandler p == nil") return nil } scene := p.GetScene() if scene == nil { logger.Logger.Warn("CSFishingOpHandler p.GetScene() == nil") return nil } if !scene.HasPlayer(p) { return nil } if scene.GetScenePolicy() != nil { scene.GetScenePolicy().OnPlayerOp(scene, p, int(msg.GetOpCode()), msg.GetParams()) } return nil } return nil } // 捕鱼 type CSFishViewPacketFactory struct { } type CSFishViewHandler struct { } func (this *CSFishViewPacketFactory) CreatePacket() interface{} { pack := &fishing_proto.CSFishView{} return pack } func (this *CSFishViewHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { logger.Logger.Trace("CSFishViewHandler Process recv ", data) if msg, ok := data.(*fishing_proto.CSFishView); ok { var player *base.Player snid := msg.GetSnId() if snid == 0 { player = base.PlayerMgrSington.GetPlayer(sid) if player == nil { logger.Logger.Warn("CSFishViewHandler GetPlayer p == nil") return nil } } else { player = base.PlayerMgrSington.GetPlayerBySnId(snid) if player == nil { logger.Logger.Warn("CSFishViewHandler GetPlayerBySnId p == nil") return nil } if !player.IsRob && player != base.PlayerMgrSington.GetPlayer(sid) { logger.Logger.Warn("CSFishViewHandler !player.IsRob && player!=base.PlayerMgrSington.GetPlayer(sid)", player.SnId) return nil } } if player.GetScene() != nil { if fsd, ok := player.GetScene().GetExtraData().(*FishingSceneData); ok && fsd != nil { fp := fsd.players[player.SnId] if fp != nil { fsd.PushEventFish(fp, msg.GetSign(), msg.GetFishs(), msg.GetEventFish()) } } } return nil } return nil } // 瞄准 /*type CSFishTargetPacketFactory struct { } type CSFishTargetHandler struct { } func (this *CSFishTargetPacketFactory) CreatePacket() interface{} { pack := &fishing_proto.CSFishTarget{} return pack }*/ /*func (this *CSFishTargetHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { logger.Logger.Trace("CSFishTargetHandler Process recv ", data) if msg, ok := data.(*fishing_proto.CSFishTarget); ok { var player *base.Player if msg.GetRobotId() != 0 { player = base.PlayerMgrSington.GetPlayerBySnId(msg.GetRobotId()) } if player == nil { logger.Logger.Warn("CSFishViewHandler robot == nil") return nil //player = base.PlayerMgrSington.GetPlayer(sid) } if player == nil { logger.Logger.Warn("CSFishViewHandler p == nil") return nil } if player.GetScene() != nil { if playerEx, ok := player.GetExtraData().(*FishingPlayerData); ok { playerEx.TargetFish = msg.GetFishId() } pack := &fishing_proto.SCFishTarget{ FishId: proto.Int32(msg.GetFishId()), SnId: proto.Int32(player.SnId), } player.GetScene().Broadcast(int(fishing_proto.FIPacketID_FISHING_SC_FISHTARGET), pack, 0) } return nil } return nil }*/ // 查看打死鱼 type CSFishLookLockPacketFactory struct { } type CSFishLookLockHandler struct { } func (this *CSFishLookLockPacketFactory) CreatePacket() interface{} { pack := &fishing_proto.CSLookLockFish{} return pack } func (this *CSFishLookLockHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { logger.Logger.Trace("CSFishLookLockHandler Process recv ", data) if _, ok := data.(*fishing_proto.CSLookLockFish); ok { player := base.PlayerMgrSington.GetPlayer(sid) if player == nil { logger.Logger.Warn("CSFishLookLockHandler p == nil") return nil } if player.GetScene() != nil { if playerEx, ok := player.GetExtraData().(*FishingPlayerData); ok { pack := &fishing_proto.SCLookLockFish{} for id, v := range playerEx.lockFishCount { pack.FishId = append(pack.FishId, id) pack.FishIdNum = append(pack.FishIdNum, v) } logger.Logger.Trace("CSFishLookLockHandler Pb ", pack) playerEx.SendToClient(int(fishing_proto.FIPacketID_FISHING_SC_LOOKLOCKFISH), pack) } } return nil } return nil } // 放炮台 type CSFishReadyPranaPacketFactory struct { } type CSFishReadyPranaHandler struct { } func (this *CSFishReadyPranaPacketFactory) CreatePacket() interface{} { pack := &fishing_proto.CSReadyPrana{} return pack } func (this *CSFishReadyPranaHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { logger.Logger.Trace("CSFishReadyPranaHandler Process recv ", data) if msg, ok := data.(*fishing_proto.CSReadyPrana); ok { player := base.PlayerMgrSington.GetPlayer(sid) if player == nil { logger.Logger.Warn("CSFishReadyPranaHandler p == nil") return nil } if player.GetScene() != nil { if playerEx, ok := player.GetExtraData().(*FishingPlayerData); ok { pack := &fishing_proto.SCReadyPrana{ SnId: proto.Int32(playerEx.SnId), X: proto.Int32(msg.GetX()), Y: proto.Int32(msg.GetY()), } if playerEx.PranaPercent == 100 { pack.OpRetCode = fishing_proto.OpResultCode_OPRC_Sucess } else { pack.OpRetCode = fishing_proto.OpResultCode_OPRC_Error // 操作失败 } logger.Logger.Trace("CSFishReadyPranaHandler Pb ", pack) playerEx.GetScene().Broadcast(int(fishing_proto.FIPacketID_FISHING_SC_REALYPRANA), pack, 0) } } return nil } return nil } // 发射能量炮 type CSFishFirePranaPacketFactory struct { } type CSFishFirePranaHandler struct { } func (this *CSFishFirePranaPacketFactory) CreatePacket() interface{} { pack := &fishing_proto.CSFirePrana{} return pack } /*func (this *CSFishFirePranaHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { logger.Logger.Trace("CSFishFirePranaHandler Process recv ", data) if msg, ok := data.(*fishing_proto.CSFirePrana); ok { player := base.PlayerMgrSington.GetPlayer(sid) if player == nil { logger.Logger.Warn("CSFishFirePranaHandler p == nil") return nil } if player.GetScene() != nil { if sx, ok := player.GetScene().GetExtraData().(*HPFishingSceneData); ok && sx != nil { if playerEx, ok := player.GetExtraData().(*FishingPlayerData); ok { pack := &fishing_proto.SCReadyPrana{ SnId: proto.Int32(playerEx.SnId), X: proto.Int32(msg.GetX()), Y: proto.Int32(msg.GetY()), } if playerEx.PranaPercent == 100 { pack.OpRetCode = fishing_proto.OpResultCode_OPRC_Sucess var fishs []int for _, v := range msg.FishIds { fish := sx.fish_list[v] if fish != nil { fish.OnHit(0) fishs = append(fishs, int(v)) } } // TODO 死鱼操作 sx.firePranaDel(playerEx, fishs, int32(playerEx.Prana)) playerEx.Prana = 0.0 playerEx.PranaPercent = 0 } else { pack.OpRetCode = fishing_proto.OpResultCode_OPRC_Error // 操作失败 } logger.Logger.Trace("CSFishFirePranaHandler Pb ", pack) playerEx.GetScene().Broadcast(int(fishing_proto.FIPacketID_FISHING_SC_FIREPRANA), pack, 0) } } } return nil } return nil }*/ //玩家使用技能 type CSFishSkillUseReqPacketFactory struct { } type CSFishSkillUseReqHandler struct { } func (this *CSFishSkillUseReqPacketFactory) CreatePacket() interface{} { pack := &fishing_proto.CSFishSkillUseReq{} return pack } func (this *CSFishSkillUseReqHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { logger.Logger.Trace("CSFishSkillUseReqHandler Process recv ", data) if msg, ok := data.(*fishing_proto.CSFishSkillUseReq); ok { player := base.PlayerMgrSington.GetPlayer(sid) if player == nil { logger.Logger.Warn("CSFishReadyPranaHandler p == nil") return nil } if player.GetScene() != nil { if playerEx, ok := player.GetExtraData().(*FishingPlayerData); ok { skillId := msg.GetSkillId() pack := &fishing_proto.SCFishSkillUseResp{ Result: 0, SkillId: skillId, Status: fishing_proto.SCFishSkillUseResp_USABLE, } //获取技能配置表 skillTemp := srvdata.PBDB_FishSkillMgr.GetData(skillId) if skillTemp == nil { fishlogger.Errorf("没有找到技能模版 skillId = %v,snid = %v,playerEx = %v", skillId, player.SnId, playerEx) pack.Result = 1 pack.Status = fishing_proto.SCFishSkillUseResp_NOT_EXISTS player.SendToClient(int(fishing_proto.FIPacketID_FISHING_SC_SKILLUSERESP), pack) return nil } //判断技能使用条件 //vip等级限制 if player.VIP < skillTemp.GetVip() { fishlogger.Errorf("VIP等级不足,无法使用此技能!") pack.Result = 1 pack.Status = fishing_proto.SCFishSkillUseResp_VIP_LIMIT player.SendToClient(int(fishing_proto.FIPacketID_FISHING_SC_SKILLUSERESP), pack) return nil } //判断消耗物品 if skillTemp.GetConsume() != 0 { item := skillTemp.Item itemId := item[0] itemNum := item[1] //获取背包道具数量 num, ok := player.Items[item[0]] if !ok || num < int64(item[1]) { fishlogger.Errorf("道具数量不在 itemId = %v,itemNum = %v,背包数量 = %v", item[0], item[1], num) //判断其他消耗其他物品 otherItem := skillTemp.OtherConsumer otherItemId := otherItem[0] otherItemNum := otherItem[1] fishlogger.Tracef("道具不足,转换道具 otherItemId = %v,otherItemNum = %v", otherItemId, otherItemNum) //判断背包道具是否足够 if otherItemId == 0 || otherItemNum == 0 { fishlogger.Tracef("转换道具为0,不支持用其他道具转换!!!!") pack.Result = 1 pack.Status = fishing_proto.SCFishSkillUseResp_TOOL_LIMIT player.SendToClient(int(fishing_proto.FIPacketID_FISHING_SC_SKILLUSERESP), pack) return nil } if otherItemId == common.ItemIDDiamond { if player.Diamond < int64(itemNum) { fishlogger.Tracef("钻石数量不足,无法使用技能!") pack.Result = 1 pack.Status = fishing_proto.SCFishSkillUseResp_TOOL_LIMIT player.SendToClient(int(fishing_proto.FIPacketID_FISHING_SC_SKILLUSERESP), pack) return nil } player.Diamond -= int64(otherItemNum) } else { if player.Items[otherItemId] < int64(otherItemNum) { fishlogger.Tracef("转换物品是其他物品时,物品数量不足!") pack.Result = 1 pack.Status = fishing_proto.SCFishSkillUseResp_TOOL_LIMIT player.SendToClient(int(fishing_proto.FIPacketID_FISHING_SC_SKILLUSERESP), pack) return nil } player.Items[otherItemId] = player.Items[otherItemId] - int64(otherItemNum) } fishlogger.Tracef("玩家使用技能当前道具不足 转化物品消耗 skillid = %v,snid = %v,otherItemId = %v,otherItemNum = %v", skillId, player.SnId, otherItemId, otherItemNum) } else { player.Items[itemId] = player.Items[itemId] - int64(itemNum) //记录道具消耗日志 fishlogger.Tracef("玩家使用技能,消耗道具!snod = %v, skill = %v,itemId =%v,itemNum = %v", player.SnId, skillId, itemId, itemNum) } } if int64(skillTemp.GetMultiple()) > player.UnMaxPower { fishlogger.Trace("解锁炮倍不足,无法使用此技能!") pack.Result = 1 pack.Status = fishing_proto.SCFishSkillUseResp_UN_POWER player.SendToClient(int(fishing_proto.FIPacketID_FISHING_SC_SKILLUSERESP), pack) return nil } //判断当前房间是否可以使用此技能 strSlice := strings.Split(skillTemp.Hidden, ",") status := false for _, s := range strSlice { num, _ := strconv.Atoi(s) if int32(num) == player.GetScene().GetSceneType() { status = true } } if !status { pack.Result = 1 pack.Status = fishing_proto.SCFishSkillUseResp_ROOM_DISALLOW player.SendToClient(int(fishing_proto.FIPacketID_FISHING_SC_SKILLUSERESP), pack) fishlogger.Trace("当前房间不允许使用此技能 skillId = %v,sceneType = %v", skillId, player.GetScene().GetSceneType()) return nil } //判断当前技能在不在CD中 if playerEx, ok := player.GetScene().GetExtraData().(*FishingPlayerData); ok { if !playerEx.GetSkillCD(skillId, skillTemp.SkillGroups) { fishlogger.Tracef("当前技能正在CD中,无法使用此技能!!!!snid = %v,skill = %v", player.SnId, skillId) pack.Result = 1 pack.Status = fishing_proto.SCFishSkillUseResp_CD player.SendToClient(int(fishing_proto.FIPacketID_FISHING_SC_SKILLUSERESP), pack) return nil } } else { return nil } //当前场景存在世界boss是否可用 //获取当前场景中的世界BOSS if skillTemp.GetLimit() == 0 { //判断当前场景中是否存在世界BOSS if fsd, ok := player.GetScene().GetExtraData().(*FishingSceneData); ok && fsd != nil { if fsd.GetWorldBoss() { fishlogger.Tracef("当前场景存在世界BOSS,当前技能无法使用!snid = %v, skillId =%v ", player.SnId, skillId) pack.Result = 1 pack.Status = fishing_proto.SCFishSkillUseResp_WORLD_BOSS player.SendToClient(int(fishing_proto.FIPacketID_FISHING_SC_SKILLUSERESP), pack) return nil } } } //狂暴VIP等级限制 服务端在发炮的时候拦截检测 这里不检测 if skillTemp.Fury > 0 { } fishType := 0 switch skillId { case FishSill_Lock: //锁定 break case FishSkill_Freeze: //冰冻 //scene冰冻 定屏 //获取定屏时间 SkillCDTime := skillTemp.Cooldown //秒 fishlogger.Tracef("玩家使用定屏技能 定屏时间skillCDTime = %v", SkillCDTime) //判断当前屏幕是否定屏 if sceneData, ok := player.GetScene().GetExtraData().(*FishingSceneData); ok && sceneData != nil { if sceneData.frozenTick == 0 { sceneData.Freeze(int64(SkillCDTime)) } else { sceneData.Freeze(int64(SkillCDTime - sceneData.frozenTick)) } sceneData.frozenTick = SkillCDTime } break case FishSkill_Speed: //狂暴 有2倍狂暴 和4倍狂暴 break case FishSkill_MagicLamp: break case FishSkill_MysticalHorn: break } //记录技能CD 和公共CD cd延长1秒 playerEx.AddSkillCD(skillId, skillTemp.SkillGroups, skillTemp.GetCooldown()+1, skillTemp.GCD+1) //客户端返回消息 player.SendToClient(int(fishing_proto.FIPacketID_FISHING_SC_SKILLUSERESP), pack) //广播给其他人 FISHING_SC_SKILLUSEBEGIN pack1 := &fishing_proto.SCFishSkillUseBegin{ SkillId: skillId, SnId: player.SnId, FishID: 0, FishType: int32(fishType), Pos: int32(player.Pos), } player.GetScene().Broadcast(int(fishing_proto.FIPacketID_FISHING_SC_SKILLUSEBEGIN), pack1, 0) } } return nil } return nil } // 获取房间技能列表 type CSSkillListReqPacketFactory struct { } type CSSkillListReqHandler struct { } func (this *CSSkillListReqPacketFactory) CreatePacket() interface{} { pack := &fishing_proto.CSFishSkillUseReq{} return pack } func (this *CSSkillListReqHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { fishlogger.Trace("玩家请求房间技能列表!") player := base.PlayerMgrSington.GetPlayer(sid) if player == nil { logger.Logger.Warn("CSSkillListReqHandler p == nil") return nil } if player.GetScene() == nil { return nil } pack := &fishing_proto.SCSkillListResp{} for _, skill := range srvdata.PBDB_FishSkillMgr.Datas.Arr { //获取房间类型 sceneType := player.GetScene().GetSceneType() str := skill.Hidden num, err := strconv.Atoi(str) status := true if err != nil { //解析错误 是数组 numbers := strings.Split(str, ",") // 将字符串按逗号分割成单独的数字 var arr []int32 // 声明一个空的 []int32 切片 for _, numStr := range numbers { num, err := strconv.ParseInt(numStr, 10, 32) // 将字符串转换为 int32 类型 if err != nil { fmt.Println("转换错误:", err) return nil } arr = append(arr, int32(num)) // 将转换后的 int32 添加到切片中 } for _, value := range arr { if value == int32(sceneType) { status = false break } } } else { if num != 0 { status = false } } if status { skillInfo := &fishing_proto.SkillInfo{ Id: skill.Id, Name: skill.Name, Vip: skill.Vip, Consume: skill.Consume, Item: string(skill.Item), OtherConsumer: string(skill.OtherConsumer), Duration: skill.Duration, SkillGroup: skill.SkillGroups, Gcd: skill.GCD, Cd: skill.Cooldown, HiddenPoses: skill.Hidden, Describe: skill.Describe, OpenCanon: skill.Multiple, SkillType: skill.Type, Fury: skill.Fury, Limit: skill.Limit, } fishlogger.Tracef("skillInfo = %v", skillInfo) pack.Items = append(pack.Items, skillInfo) } } player.SendToClient(int(fishing_proto.FIPacketID_FISHING_SC_SKILLUSERESP), pack) return nil } // 客户端请求帧同步 type CSSyncTimePointPacketFactory struct { } type CSSyncTimePointHandler struct { } func (this *CSSyncTimePointPacketFactory) CreatePacket() interface{} { pack := &fishing_proto.CSSyncTimePoint{} return pack } func (this *CSSyncTimePointHandler) Process(s *netlib.Session, packetid int, data interface{}, sid int64) error { fishlogger.Trace("客户端请求帧同步!!!!") player := base.PlayerMgrSington.GetPlayer(sid) if player == nil { logger.Logger.Warn("CSSyncTimePointHandler p == nil") return nil } if sceneData, ok := player.GetScene().GetExtraData().(*FishingSceneData); ok && sceneData != nil { pack := &fishing_proto.SCSyncTimePoint{ TimePoint: sceneData.TimePoint, } player.SendToClient(int(fishing_proto.FIPacketID_FISHING_SC_SYNCTIMEPOINT), pack) } return nil } func init() { // 装载完毕,同步存活的鱼 common.RegisterHandler(int(fishing_proto.FIPacketID_FISHING_CS_LOADCOMPLETE), &CSLoadCompleteHandler{}) netlib.RegisterFactory(int(fishing_proto.FIPacketID_FISHING_CS_LOADCOMPLETE), &CSLoadCompletePacketFactory{}) // 捕鱼操作 common.RegisterHandler(int(fishing_proto.FIPacketID_FISHING_CS_OP), &CSFishingOpHandler{}) netlib.RegisterFactory(int(fishing_proto.FIPacketID_FISHING_CS_OP), &CSFishingOpPacketFactory{}) // 客户端触发事件 common.RegisterHandler(int(fishing_proto.FIPacketID_FISHING_CS_FISHVIEW), &CSFishViewHandler{}) netlib.RegisterFactory(int(fishing_proto.FIPacketID_FISHING_CS_FISHVIEW), &CSFishViewPacketFactory{}) //瞄准 /* common.RegisterHandler(int(fishing_proto.FIPacketID_FISHING_CS_FISHTARGET), &CSFishTargetHandler{}) netlib.RegisterFactory(int(fishing_proto.FIPacketID_FISHING_CS_FISHTARGET), &CSFishTargetPacketFactory{})*/ //查看打死鱼 common.RegisterHandler(int(fishing_proto.FIPacketID_FISHING_CS_LOOKLOCKFISH), &CSFishLookLockHandler{}) netlib.RegisterFactory(int(fishing_proto.FIPacketID_FISHING_CS_LOOKLOCKFISH), &CSFishLookLockPacketFactory{}) //放置炮台 common.RegisterHandler(int(fishing_proto.FIPacketID_FISHING_CS_REALYPRANA), &CSFishReadyPranaHandler{}) netlib.RegisterFactory(int(fishing_proto.FIPacketID_FISHING_CS_REALYPRANA), &CSFishReadyPranaPacketFactory{}) //发射能量炮 //common.RegisterHandler(int(fishing_proto.FIPacketID_FISHING_CS_FIREPRANA), &CSFishFirePranaHandler{}) //netlib.RegisterFactory(int(fishing_proto.FIPacketID_FISHING_CS_FIREPRANA), &CSFishFirePranaPacketFactory{}) //查询中奖 //common.RegisterHandler(int(fishing_proto.FIPacketID_FISHING_CS_JACKPOTLIST), &CSFishJackpotHandler{}) //netlib.RegisterFactory(int(fishing_proto.FIPacketID_FISHING_CS_JACKPOTLIST), &CSFishJackpotPacketFactory{}) //使用技能 common.RegisterHandler(int(fishing_proto.FIPacketID_FISHING_CS_SKILLUSEREQ), &CSFishSkillUseReqHandler{}) netlib.RegisterFactory(int(fishing_proto.FIPacketID_FISHING_CS_SKILLUSEREQ), &CSFishSkillUseReqPacketFactory{}) //获取房间列表 common.RegisterHandler(int(fishing_proto.FIPacketID_FISHING_CS_SKILLLISTREQ), &CSSkillListReqHandler{}) netlib.RegisterFactory(int(fishing_proto.FIPacketID_FISHING_CS_SKILLLISTREQ), &CSFishSkillUseReqPacketFactory{}) //帧同步 common.RegisterHandler(int(fishing_proto.FIPacketID_FISHING_CS_SYNCTIMEPOINT), &CSSkillListReqHandler{}) netlib.RegisterFactory(int(fishing_proto.FIPacketID_FISHING_CS_SYNCTIMEPOINT), &CSFishSkillUseReqPacketFactory{}) }