5722 【后端】【1.5.100】【1.5】跨服BOSS开发(同步场景灵宠、坐骑变更)
| | |
| | |
|
| | | def __CrossServerPutInItem(self, packIndex, tagItem, event=["", False, {}]):
|
| | | ## 跨服获得物品
|
| | | if packIndex not in [IPY_GameWorld.rptItem]:
|
| | | #GameWorld.DebugLog("跨服获得物品不同步, packIndex=%s" % (packIndex))
|
| | | return
|
| | | curPlayer = self.__Player
|
| | | serverGroupID = PlayerControl.GetPlayerServerGroupID(curPlayer)
|
| | | itemData = [tagItem.GetItemTypeID(), tagItem.GetCount(), tagItem.GetIsBind(), tagItem.GetUserData()]
|
| | |
| | | import PyGameData
|
| | | import PlayerDienstgrad
|
| | | import IpyGameDataPY
|
| | | import PlayerHorse
|
| | | import PlayerPet
|
| | | import traceback
|
| | |
|
| | | # 发送格式: 类型+(数量)+数据
|
| | |
| | | MergeData_Item, # 对比处理 只算属性的背包 装备 宠物
|
| | | MergeData_Skill, # 只处理ID
|
| | | MergeData_Buff, # 即时发送
|
| | | ) = range(0, 4)
|
| | | CrossData_PetState, # 即时发送 宠物出战
|
| | | CrossData_HorseChange, # 即时发送 骑乘坐骑变更
|
| | | CrossData_RideHorse, # 即时发送 上下马
|
| | | ) = range(0, 7)
|
| | |
|
| | | ## 写数据类型定义
|
| | | (
|
| | | WDT_BYTE,
|
| | | WDT_WORD,
|
| | | WDT_DWORD,
|
| | | WDT_String,
|
| | | ) = range(4)
|
| | |
|
| | | CrossDataInfo = {
|
| | | CrossData_PetState:[[WDT_DWORD, WDT_BYTE, WDT_BYTE], lambda curObj, valueList:PlayerPet.CrossServer_DoChangePetState(curObj, valueList)],
|
| | | CrossData_HorseChange:[[WDT_DWORD], lambda curObj, valueList:PlayerHorse.CrossServer_ChangeHorse(curObj, valueList)],
|
| | | CrossData_RideHorse:[[WDT_BYTE], lambda curObj, valueList:PlayerHorse.CrossServer_RideHorse(curObj, valueList)],
|
| | | }
|
| | |
|
| | | # 影响跨服战力属性列表
|
| | | CrossFightPowerAttrList = [
|
| | |
| | | elif dataType == MergeData_Player:
|
| | | __ReadMainServerSyncPlayerData(curPlayer, curPlayer.GetMergePlayerData(), pos)
|
| | |
|
| | | else:
|
| | | __ReadCrossData(curPlayer, dataType, curPlayer.GetMergePlayerData(), pos)
|
| | | |
| | | except BaseException:
|
| | | errorMsg = str(traceback.format_exc())
|
| | | GameWorld.ErrLog('接收跨服变更玩家数据错误 - > %s' % errorMsg, curPlayer.GetPlayerID())
|
| | |
| | |
|
| | | ## ----------------------------------------------------------------------------------------------
|
| | |
|
| | | def SendDataToCrossServer(curPlayer, dataType, dataList):
|
| | | ## 通用的根据类型向跨服发送数据
|
| | | if dataType not in CrossDataInfo:
|
| | | return
|
| | | |
| | | if not IsNeedProcessCrossPlayer(curPlayer):
|
| | | return
|
| | | |
| | | dataInfo = CrossDataInfo[dataType][0]
|
| | | if len(dataList) != len(dataInfo):
|
| | | return
|
| | | |
| | | data = ''
|
| | | data = CommFunc.WriteBYTE(data, dataType)
|
| | | for i, wDType in enumerate(dataInfo):
|
| | | value = dataList[i]
|
| | | if wDType == WDT_BYTE:
|
| | | data = CommFunc.WriteBYTE(data, value)
|
| | | elif wDType == WDT_WORD:
|
| | | data = CommFunc.WriteWORD(data, value)
|
| | | elif wDType == WDT_DWORD:
|
| | | data = CommFunc.WriteDWORD(data, value)
|
| | | elif wDType == WDT_String:
|
| | | sLen = len(value)
|
| | | data = CommFunc.WriteBYTE(data, sLen)
|
| | | data = CommFunc.WriteString(data, sLen, value)
|
| | | |
| | | #直接用字节流会报错
|
| | | data = base64.b64encode(data)
|
| | | curPlayer.SendMergePlayerData(data)
|
| | | GameWorld.DebugLog("发送数据到跨服服务器: dataType=%s,dataList=%s" % (dataType, dataList), curPlayer.GetPlayerID())
|
| | | return
|
| | |
|
| | | def __ReadCrossData(curPlayer, dataType, pdata, pos):
|
| | | if dataType not in CrossDataInfo:
|
| | | return
|
| | | dataInfo, callFunc = CrossDataInfo[dataType]
|
| | | |
| | | if not callFunc:
|
| | | return
|
| | | |
| | | dataList = []
|
| | | pdata = base64.b64decode(pdata)
|
| | | |
| | | for wDType in dataInfo:
|
| | | if wDType == WDT_BYTE:
|
| | | value, pos = CommFunc.ReadBYTE(pdata, pos)
|
| | | elif wDType == WDT_WORD:
|
| | | value, pos = CommFunc.ReadWORD(pdata, pos)
|
| | | elif wDType == WDT_DWORD:
|
| | | value, pos = CommFunc.ReadDWORD(pdata, pos)
|
| | | elif wDType == WDT_String:
|
| | | sLen, pos = CommFunc.ReadBYTE(pdata, pos)
|
| | | value, pos = CommFunc.ReadString(pdata, pos, sLen)
|
| | | else:
|
| | | continue
|
| | | dataList.append(value)
|
| | | |
| | | GameWorld.DebugLog("收到主服数据: dataType=%s,dataList=%s" % (dataType, dataList), curPlayer.GetPlayerID())
|
| | | callFunc(curPlayer, dataList)
|
| | | return
|
| | |
|
| | | def IsNeedProcessCrossPlayer(curPlayer):
|
| | | ## 是否需要处理同步跨服中的玩家数据
|
| | | if GameWorld.IsCrossServer():
|
| | |
| | | def DoLogic_PetInfo_OnLogin(curPlayer, tick):
|
| | |
|
| | | petMgr = curPlayer.GetPetMgr()
|
| | |
|
| | | if GameWorld.IsCrossServer():
|
| | | ''' 0435宠物出现包同步的ID是根据宠物的列表位置来的,比如在第2位发的就是2,而地图的可能是1,会导致ID不一致
|
| | | 所以跨服服务器登录时先清除出战宠物列表,确保登录地图成功后都是从1开始的即可
|
| | | '''
|
| | | petList = []
|
| | | for index in range(0, petMgr.PetList_Cnt()):
|
| | | rolePet = petMgr.PetList_At(index)
|
| | | petList.append(rolePet)
|
| | | for rolePet in petList:
|
| | | petMgr.PetList_SetFree(rolePet.GetRolePet().PetID)
|
| | | else:
|
| | | for index in range(0, petMgr.PetList_Cnt()):
|
| | | rolePet = petMgr.PetList_At(index)
|
| | | #刷新宠物信息并通知客户端
|
| | |
| | | PlayerBillboard.UpdatePlayerFPTotalBillboard(curPlayer)
|
| | | # 记录开服活动数据
|
| | | OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_FightPower, totalFightPower)
|
| | | if beforeFightPower != totalFightPower:
|
| | | CrossPlayerData.OnPlayerFightPowerChange(curPlayer)
|
| | | return
|
| | |
|
| | |
| | | import SkillCommon
|
| | | import PlayerMagicWeapon
|
| | | import PassiveBuffEffMng
|
| | | import CrossPlayerData
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | pack = IPY_GameWorld.IPY_CRideHorse()
|
| | | #//1: 骑马 0: 下马
|
| | | curPlayerRideType = pack.GetRide()
|
| | | if PlayerControl.GetCrossMapID(curPlayer):
|
| | | # 暂只处理上马
|
| | | if curPlayerRideType:
|
| | | dataList = [curPlayerRideType]
|
| | | CrossPlayerData.SendDataToCrossServer(curPlayer, CrossPlayerData.CrossData_RideHorse, dataList)
|
| | | return
|
| | | #骑马行为状态, 客户端限制
|
| | | if not OperControlManager.IsObjCanDoAction(curPlayer,
|
| | | ChConfig.Def_Obj_ActState_ClientAct,
|
| | |
| | |
|
| | | #if curPlayer.IsMoving():
|
| | | # curPlayer.Move(curPlayer.GetDestPosX(), curPlayer.GetDestPosY())
|
| | | return
|
| | |
|
| | | def CrossServer_RideHorse(curPlayer, dataList):
|
| | | curPlayerRideType = dataList[0]
|
| | | |
| | | #骑马
|
| | | if curPlayerRideType == 1:
|
| | | PlayerRideHorseUp(curPlayer, True)
|
| | | |
| | | return
|
| | |
|
| | | #---------------------下马逻辑
|
| | |
| | | horseIndex = packData.Index
|
| | |
|
| | | DoChangeHorse(curPlayer, horseIndex, tick)
|
| | | |
| | | if not GameWorld.IsCrossServer():
|
| | | dataList = [horseIndex]
|
| | | CrossPlayerData.SendDataToCrossServer(curPlayer, CrossPlayerData.CrossData_HorseChange, dataList)
|
| | | return
|
| | |
|
| | | def CrossServer_ChangeHorse(curPlayer, dataList):
|
| | | ## 跨服处理 坐骑变更
|
| | | horseIndex = dataList[0]
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("Horse", horseIndex)
|
| | | if not ipyData:
|
| | | return
|
| | | |
| | | horseItemID = ipyData.GetItemID()
|
| | | |
| | | if ItemCommon.FindItemInPackByItemID(curPlayer, horseItemID, IPY_GameWorld.rptEquip):
|
| | | return
|
| | | |
| | | isOK = ItemControler.PutItemInTempSwap(curPlayer, horseItemID)
|
| | | if not isOK:
|
| | | return
|
| | | |
| | | curHorse = ItemCommon.FindItemInPackByItemID(curPlayer, horseItemID, ShareDefine.rptTempSwap)
|
| | | if not curHorse:
|
| | | return
|
| | | |
| | | isRideHorse = curPlayer.GetPlayerVehicle() == IPY_GameWorld.pvHorse
|
| | | if isRideHorse:
|
| | | PlayerRideHorseDown(curPlayer, False)
|
| | | |
| | | #---执行玩家换装逻辑---
|
| | | tick = GameWorld.GetGameWorld().GetTick()
|
| | | if ChEquip.DoPlayerEquipItem(curPlayer, curHorse, ShareDefine.retHorse, tick):
|
| | | if isRideHorse:
|
| | | PlayerRideHorseUp(curPlayer, False)
|
| | | |
| | | return
|
| | |
|
| | | def DoChangeHorse(curPlayer, horseIndex, tick):
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("Horse", horseIndex)
|
| | |
| | | import PlayerMagicWeapon
|
| | | import PassiveBuffEffMng
|
| | | import CalcNoLineEffect
|
| | | import CrossPlayerData
|
| | | import CalcLineEffect
|
| | |
|
| | | import random
|
| | |
| | | # petItem.SetUserAttr(ShareDefine.Def_IudetPet_State, tagState)
|
| | | # GameWorld.DebugLog("切换宠物状态异常防范! curState=%s,tagState=%s" % (curState, tagState))
|
| | |
|
| | | if not GameWorld.IsCrossServer():
|
| | | dataList = [petNPCID, curClasslv, tagState]
|
| | | CrossPlayerData.SendDataToCrossServer(curPlayer, CrossPlayerData.CrossData_PetState, dataList)
|
| | | |
| | | return
|
| | |
|
| | | def CrossServer_DoChangePetState(curPlayer, dataList):
|
| | | ## 跨服处理 宠物战斗状态变更
|
| | | petNPCID, curClasslv, tagState = dataList
|
| | | petItem = GetPetDataItemByNPCID(curPlayer, petNPCID)
|
| | | if not petItem:
|
| | | newPetItem = GetNewPetDataItem(curPlayer, petNPCID)
|
| | | if not newPetItem:
|
| | | return
|
| | | if not ItemControler.PlayerItemControler(curPlayer).PutInItem(ShareDefine.rptPet, newPetItem):
|
| | | return
|
| | | petItem = GetPetDataItemByNPCID(curPlayer, petNPCID)
|
| | | if not petItem:
|
| | | return
|
| | | |
| | | curItemClasslv = petItem.GetUserAttr(ShareDefine.Def_IudetPet_ClassLV)
|
| | | # 处理技能问题,暂不处理
|
| | | if curClasslv > curItemClasslv:
|
| | | pass
|
| | | |
| | | curState = petItem.GetUserAttr(ShareDefine.Def_IudetPet_State) # 当前状态
|
| | | if curState == ShareDefine.Def_PetState_Fight:
|
| | | PetControl.ReCallFightPet(curPlayer)
|
| | | |
| | | if tagState == ShareDefine.Def_PetState_Fight:
|
| | | __DoPetGoOutToFight(curPlayer, petItem)
|
| | | |
| | | return
|
| | |
|
| | |
|
| | | ## 执行宠物出战逻辑
|