5722 【后端】【1.5.100】【1.5】跨服BOSS开发(同步场景灵宠、坐骑变更)
6个文件已修改
185 ■■■■■ 已修改文件
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossPlayerData.py 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PetControl.py 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHorse.py 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
@@ -1097,6 +1097,9 @@
    
    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()]
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/CrossPlayerData.py
@@ -23,6 +23,8 @@
import PyGameData
import PlayerDienstgrad
import IpyGameDataPY
import PlayerHorse
import PlayerPet
import traceback
# 发送格式: 类型+(数量)+数据
@@ -32,7 +34,24 @@
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 = [
@@ -107,6 +126,9 @@
        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())
@@ -117,6 +139,68 @@
## ----------------------------------------------------------------------------------------------
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():
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PetControl.py
@@ -517,7 +517,17 @@
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)
        #刷新宠物信息并通知客户端
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -4791,6 +4791,7 @@
        PlayerBillboard.UpdatePlayerFPTotalBillboard(curPlayer)
        # 记录开服活动数据
        OpenServerCampaign.UpdOpenServerCampaignRecordData(curPlayer, ShareDefine.Def_Campaign_Type_FightPower, totalFightPower)
        if beforeFightPower != totalFightPower:
        CrossPlayerData.OnPlayerFightPowerChange(curPlayer)
        return
    
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerHorse.py
@@ -39,6 +39,7 @@
import SkillCommon
import PlayerMagicWeapon
import PassiveBuffEffMng
import CrossPlayerData
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -98,6 +99,12 @@
    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,
@@ -130,6 +137,15 @@
    
    #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
#---------------------下马逻辑
@@ -280,8 +296,43 @@
    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)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerPet.py
@@ -39,6 +39,7 @@
import PlayerMagicWeapon
import PassiveBuffEffMng
import CalcNoLineEffect
import CrossPlayerData
import CalcLineEffect
import random
@@ -266,8 +267,39 @@
#        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
## 执行宠物出战逻辑