ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -17,14 +17,11 @@
import PlayerControl
import GameMap
import ChConfig
import EventShell
import BuffSkill
import PlayerEventCounter
import PlayerTeam
import PlayerHorse
import PlayerTruck
import NPCCommon
import PlayerGameEvent
import SkillCommon
import FBLogic
import ChItem
@@ -58,7 +55,6 @@
import PlayerGoldInvest
import PlayerActivity
import FBCommon
import PlayerBindJadeWheel
import BossHurtMng
import PlayerWishingWell
import PlayerAttrFruit
@@ -98,9 +94,6 @@
import PlayerVip
import PlayerRefineStove
import PassiveBuffEffMng
import PlayerDiceEx
import QuestCommon
import PlayerTJG
import GameLogic_XMZZ
import PlayerFlashSale
import PlayerFlashGiftbag
@@ -145,7 +138,6 @@
import PlayerArena
import PyGameData
import PlayerCoin
import PlayerGeTui
import PlayerCharm
import PlayerDogz
import PlayerCoat
@@ -156,7 +148,9 @@
import PlayerShentong
import PlayerCustomAward
import PlayerZhanling
import PlayerTree
import PlayerLianTi
import PlayerTask
import PlayerYinji
import PlayerLove
import GameObj
@@ -175,11 +169,18 @@
import PlayerMail
import DBDataMgr
import GameServerRefresh
import IPY_ServerDefine
import CommFunc
from PyMongoDB import RecvPackToMapDB
import PyMongoMain
import PlayerTalk
import PlayerHero
import datetime
import time
import math
import re
import base64
#---------------------------------------------------------------------
#---------------------------------------------------------------------
@@ -197,34 +198,9 @@
#@return 返回值无意义
#@remarks 玩家登陆游戏初始化
def InitLoginPlayer(curPlayer, tick):
    ##初始化交易列表
    if curPlayer.GetTradeList().GetTradeItemCount() == 0:
        curPlayer.GetTradeList().SetTradeListCount(ChConfig.Def_PlayerTradeMaxItemCount)
    #初始化玩家的时钟个数
    if curPlayer.GetTickTypeCount() == 0:
        curPlayer.SetTickTypeCount(ChConfig.TYPE_Player_Tick_Count)
    #初始化玩家聊天频道
    if curPlayer.GetMaxChannelCount() == 0:
        curPlayer.SetMaxChannelCount(ChConfig.Def_PlayerTalkChannelMaxCount)
#===============================================================================
#    #初始化玩家鉴定管理器物品最大个数
#    identifyItemManager = curPlayer.GetIdentifyManager()
#
#    #设置最大数量
#    if identifyItemManager.GetCount() == 0:
#        identifyItemManager.SetCount(ChConfig.TYPE_Player_identifyManagerCount)
#
#    #初始化宝石挖除管理器最大个数
#    stoneBreakManager = curPlayer.GetStoneBreakManager()
#
#    if stoneBreakManager.GetCount() == 0:
#        stoneBreakManager.SetCount(ChConfig.TYPE_Player_StoneBreakManagerCount)
#===============================================================================
    #初始化物品
    #ChItem.InitPlayerLoginItem(curPlayer, tick)
    return
#---------------------------------------------------------------------
##C++封包GameServer_InitOK 处理
@@ -237,52 +213,9 @@
        #玩家是第一次登录, 并且玩家需要踢回原来地图
        return
    
    #--------------------------------通知客户端任务-------------
    #先发送所有任务, 再刷新日期, 否则会有2个相同的任务在玩家身上
    #把玩家当前的所有任务发送给客户端
    #GameWorld.Log('EventShell.NotifyAllQuestDetail')
    if not GameWorld.IsCrossServer():
        EventShell.NotifyAllQuestDetail(curPlayer, True)
    #刷新人物日期状态
    #GameWorld.Log('PlayerEventCounter.UpdatePlayerLoginTime')
    PlayerEventCounter.UpdatePlayerLoginTime(curPlayer)
    #2010/4/20 这个事件在 EventResponse_OnLogin中触发,这里重复触发了
    #GameWorld.Log('EventShell.PlayerGMEventTrig')
    #EventShell.PlayerGMEventTrig(curPlayer)
    #--------------------------------------------------------
    return
##非同一天二次登陆
# @param curPlayer 玩家实例
# @return None
def NoteOtherDayLogin(curPlayer):
    #记录过或者未登陆过 不记录
    if curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_OtherDayLogin) != 1:
        return
    logoffTimeStr = curPlayer.GetLogoffTime().strip()
    loginTimeStr = curPlayer.GetLoginTime().strip()
    #curTimeStr = GameWorld.GetCurrentDataTimeStr()
    #防范外部逻辑错误,或异常情况
    if logoffTimeStr in ['', '0'] or loginTimeStr in ['', '0']:
        return
    logoffTimeDate = GameWorld.GetDateTimeByStr(logoffTimeStr.split()[0], ChConfig.TYPE_Time_Format_Day)
    #同一天不记录
    if logoffTimeDate == GameWorld.GetDateTimeByStr(loginTimeStr.split()[0], ChConfig.TYPE_Time_Format_Day):
        return
    #GameWorld.Log("OtherDayLogin offtime = %s" % logoffTimeDate)
    DataRecordPack.DR_OtherDayLogin(curPlayer.GetAccID(), curPlayer.GetIP(), curPlayer)
    #标记为已记录
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_OtherDayLogin, 2)
    return
#// A1 20 货币兑换 #tagCMMoneyExchange
@@ -483,52 +416,29 @@
#---------------------------------------------------------------------
'''
旧登录流程 -- 留着对比
登录流程
UserCrtlDB
    onAuthentication  玩家登录 :验证账号-若没有角色则创角-返回角色信息-通知Map C++
    Map C++调用 PlayerLogin
MapServer
    ChPlayer:def PlayerLogin(index, tick)
                    DoPlayerLogin
                        curPlayer.Sync_ClientPlayerLogin()
                        curPlayer.Sync_GameServer_MapID()                #同步GameServer自己的地图ID
                        curPlayer.BalanceServer_PlayerLoginInitOK()
GameServer
    ChPlayer:def PlayerLoadMapState(index, tick)    pack.GetLoadState()=0    此时的  LoadState 为0
                    curPlayer.SetIsLoadMap(True)    设置在加载地图
    ChPlayer:def PlayerLogin(index, tick)
                    curPlayer.MapServer_InitOK()    通知地图自己OK了
MapServer
    PlayerEventCounter:def GameServer_InitOK(index, tick)
        curPlayer.SendToBServerServerInitOK()                #通知BServer自己OK了
        ChPlayer:def OnAllServerInitOK(curPlayer, tick)
        DoPlayerLogin
            curPlayer.Sync_ClientPlayerLogin()  #01 02 玩家初始化#tagCDBPlayer
            curPlayer.BalanceServer_PlayerLoginInitOK() #向route设置玩家在map中的索引
            curPlayer.SendToBServerServerInitOK()   #通知route登录成功 ,route向客户端发送//01 09 服务器准备就绪#tagServerPrepareOK
            ChPlayer:def OnAllServerInitOK(curPlayer, tick)
    ChPlayer:def LoadMapOK(curPlayer, tick)
        curPlayer.GameServer_SetLoadMapState(1)    #通知GameServer切换地图停止
        curPlayer.SetMapLoadOK(True)
        curPlayer.SetInitOK(True)
        curPlayer.EndLoadMap()
GameServer
    ChPlayer:def PlayerLoadMapState(index, tick)    pack.GetLoadState()=1    此时的  LoadState 为1
        PlayerLoginLoadMapOK
            ChPlayer:def __Func_LoadMapOK(curPlayer, tick)  #!!!直接调用不等待客户端封包 //01 07 地图读取OK#tagCInitMapOK
            curPlayer.SetMapLoadOK(True)
            curPlayer.SetInitOK(True)
        curPlayer.MapServer_GameServerRefreshOK()        #通知地图服务器玩家初始化成功
        curPlayer.SetIsLoadMap(False)
MapServer
    GameServerRefresh:GameSever_PlayerInitOK curPlayer.GetGameServerInitOK()=0
        curPlayer.SetGameServerInitOK(True)
后续补充流程
MapServer
    ChPlayer:def DoPlayerRealLoginOK(curPlayer, tick)
                    玩家真正登录成功处理,用于替换  __DoPlayerLoginServer  中的功能登录逻辑
                    通知GameServer地图最终登录成功了
GameServer
    ChPlayer:def DoPlayerRealLoginOK(curPlayer, tick)
                    玩家真正登录成功处理,用于替换  __DoPlayerLoginServer  中的功能登录逻辑
            curPlayer.EndLoadMap()  #通知客户端 04 03 玩家登录数据发送完毕OK#tagPlayerLoginLoadOK
            GameServerRefresh:GameSever_PlayerInitOK
            curPlayer.SetGameServerInitOK(True)
            ChPlayer:def DoPlayerRealLoginOK(curPlayer, tick) 玩家真正登录成功处理,用于替换  __DoPlayerLoginServer  中的功能登录逻辑
'''
##玩家登陆游戏逻辑处理
@@ -539,7 +449,6 @@
def DoPlayerLogin(curPlayer, tick):
    #这里只做初始化逻辑
    curPlayer.SetDict(ChConfig.Def_PlayerKey_LoadMapIsLogin, 1)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_RealLoginOK, 0) # 每次登录重置
    
    #通知时间
    Sync_PyServerDataTimeToClient(curPlayer)
@@ -615,8 +524,6 @@
    
    #通知玩家技能信息
    __Sync_ClientSkill(curPlayer)
    #清除国家答题Buff
    #PlayerExam.DoLogic_ExitExam(curPlayer, tick, needRefresh = False)
    #清除VIPbuff
    #BuffSkill.DelBuffBySkillID(curPlayer, ChConfig.Def_VIPExp_SkillTypeID, tick)
    
@@ -636,14 +543,13 @@
    PlayerPrestigeSys.OnLogin(curPlayer)
    #DataRecordPack.DR_PlayerLogin(curPlayer)
    EventReport.WriteEvent_login(curPlayer)
    __FirstLoginOnEnter(curPlayer)
    # 合服首登处理
    __DoMixServerFirstLogin(curPlayer)
    PlayerBillboard.BillboardOnLogin(curPlayer)
    
    #非同一天二次登陆, 应该放在该函数中的SetLoginTime之后,EventResponse_OnEnter之前
    NoteOtherDayLogin(curPlayer)
    #上线时通知脱机挂时被击杀的离线时间
    __Sync_PlayerOffline(curPlayer, tick)
    
@@ -662,9 +568,6 @@
    #大师
    PlayerGreatMaster.MasterOnLogin(curPlayer)
    
    # 推送提醒
    PlayerGeTui.LoginNotifySetting(curPlayer)
    #֪ͨVIP
    PlayerVip.DoOnLogin(curPlayer, tick)
    
@@ -674,21 +577,6 @@
    #---玩家上线, 宠物逻辑处理---
    PetControl.DoLogic_PetInfo_OnLogin(curPlayer, tick)
    PlayerPet.OnPlayerPetLogin(curPlayer)
    #要在SetCanMove之后做这个事情, 否则OnEnter不会卡住玩家
    EventShell.EventResponse_OnEnter(curPlayer)
    EventShell.EventResponse_OnLogin(curPlayer)
    #通知环奖励记录
    EventShell.NotifyRunEndAward(curPlayer)
    #通知玩家有补偿可以领取
    #curPlayer.DataServer_GetExpiationCount()
    #通知玩家有宠物补偿可以领取
    #curPlayer.DataServer_GetPetExpiationCount()
    #玩家离线邮件通知
    #curPlayer.DataServer_GetMailListReq()
    
    #清空玩家万能背包中的任务物品
    ItemControler.ClearPackEventItem(curPlayer, IPY_GameWorld.rptAnyWhere)
@@ -713,9 +601,6 @@
#    
#    #通知客户端签到信息
    PlayerSignDay.SignDayOnLogin(curPlayer)
#
#    #通知客户端镖车AI模式
#    PlayerTruck.Sync_TruckMode(curPlayer)
    
    #通知玩家死亡时间
    PlayerControl.PlayerControl(curPlayer).NotifyPlayerDeadTime(curPlayer)
@@ -840,8 +725,6 @@
    # 世界boss
    BossHurtMng.OnLogin(curPlayer)
    ChItem.Sync_ItemDayUseCnt(curPlayer)
    # 悬赏登录通知
    #PlayerArrestTask.OnLogin(curPlayer)
    # 符印登录通知
    PlayerRune.PlayerRuneLogin(curPlayer)
    # 仙盟红包登录通知
@@ -853,10 +736,6 @@
    FunctionNPCCommon.ShopItemOnLogin(curPlayer)
    # 通知设置的被动功法
    #PassiveBuffEffMng.OnLoginGFPassive(curPlayer)
    #我要太极
    PlayerDiceEx.DiceExOnLogin(curPlayer)
    # 剧情任务完成状态
    QuestCommon.Sync_StoryMissionState(curPlayer)
    #仙魔之争
    GameLogic_XMZZ.OnXMZZLogin(curPlayer)
    PlayerOnlinePrize.OnPlayerLogin(curPlayer)
@@ -864,8 +743,6 @@
    PlayerEquipDecompose.PlayerLogin(curPlayer)
    #防沉迷
    PlayerGameWallow.DoLogic_CheckWallow(curPlayer, tick)
    # 通知脱机挂信息
    #PlayerTJG.NotifyTJGInfo(curPlayer)
    # 协助
    PlayerAssist.OnPlayerLogin(curPlayer)
    # 极品白拿
@@ -928,8 +805,6 @@
    PlayerDogz.OnPlayerLogin(curPlayer)
    # 骑宠
    FamilyRobBoss.OnPlayerLogin(curPlayer)
    # 绑玉转盘
    PlayerBindJadeWheel.OnLogin(curPlayer)
    # 许愿池
    PlayerWishingWell.OnLogin(curPlayer)
    #幸运鉴宝
@@ -983,10 +858,7 @@
        
    curPlayer.SetState(0)   # 脱机挂恢复为正常上线
    curPlayer.SetCountryLastWeekHornor(0) # 通知数据库是否保存还是下线,做一次恢复,1为保存 0为正常下线
    #tjgTime = PlayerTJG.GetTJGTime(curPlayer)
    #if tjgTime:
    #    PlayerControl.SendGameServerRefreshState(curPlayer, IPY_GameWorld.CDBPlayerRefresh_HappyPoint, tjgTime)
    PlayerControl.DoGMForbidenTalkOnLogin(curPlayer)
    DataRecordPack.DR_PlayerLogin(curPlayer) # 放最后,记录等级、经验等信息
    return
@@ -996,17 +868,14 @@
        该函数为地图最终登录成功才会执行到,以后一些功能类的登录处理建议均写到这里
        旧的功能先不动( __DoPlayerLoginServer 函数中的功能),如果有登录相关的bug再考虑是否移动到此函数
    '''
    if curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RealLoginOK):
        #切地图的不处理,切地图的也会触发该函数
        return
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_RealLoginOK, 1)
    GameWorld.Log("MapServer->DoPlayerRealLoginOK", curPlayer.GetPlayerID())
    
    if GameWorld.IsCrossServer():
        pass
    
    else:
        PyMongoMain.GetUserCtrlDB().OnPlayerLogin(curPlayer)
        PlayerHero.OnPlayerLogin(curPlayer)
        PlayerMail.OnPlayerLogin(curPlayer)
        PlayerChatBox.OnPlayerLogin(curPlayer)
        PlayerFace.OnPlayerLogin(curPlayer)
@@ -1014,9 +883,12 @@
        PlayerGubao.OnPlayerLogin(curPlayer)
        PlayerShentong.OnPlayerLogin(curPlayer)
        PlayerZhanling.OnPlayerLogin(curPlayer)
        PlayerTask.OnPlayerLogin(curPlayer)
        PlayerTree.OnPlayerLogin(curPlayer)
        PlayerMineArea.OnPlayerLogin(curPlayer)
        PlayerGuaji.OnPlayerLogin(curPlayer)
        PlayerActFamilyGCZ.OnPlayerLogin(curPlayer)
        PlayerTalk.OnPlayerLogin(curPlayer)
        
        # 上线查询一次充值订单
        curPlayer.SendDBQueryRecharge()
@@ -1039,10 +911,49 @@
    NetPackCommon.SendFakePack(curPlayer, playerInfoEx)
    return
## 合服首登处理
#  @param curPlayer
#  @return None
def __FirstLoginOnEnter(curPlayer):
    ## 首登处理
    playerID = curPlayer.GetID()
    if curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FirstLogin):
        return
    GameWorld.Log('玩家是第一次进入游戏', playerID)
    # 特殊说明: 如果地图没有完全初始化好,客户端断开或者异常等情况会触发RunGateGameServerMapServerKickOutPlayerNoSave
    # 那么在DoPlayerLogin 中设置的数据将不会被保存, 如会导致第一个任务重复触发问题,记录多次发送
    EventReport.WriteEvent_Entry(curPlayer, 4)
    #EventReport.EventReport(ShareDefine.Def_UserAction_FirstLogin, "", curPlayer)
    #---补满血满魔---
    GameObj.SetHP(curPlayer, GameObj.GetMaxHP(curPlayer))
    curPlayer.SetMP(curPlayer.GetMaxMP())
    #默认触发一次功能开启
    if curPlayer.GetLV() == 1:
        GameFuncComm.DoFuncOpenLogic(curPlayer)
    #初始化组队状态
    autoJoinReqCheck = IpyGameDataPY.GetFuncCfg("TeamCheckSet", 1)
    autoInviteCheck = IpyGameDataPY.GetFuncCfg("TeamCheckSet", 2)
    PlayerControl.SetTeamCheckStateEx(curPlayer, int(not autoJoinReqCheck), int(not autoInviteCheck))
    #玩家默认恶名值
    curPlayer.SetInfamyValue(ChConfig.Def_FirstLogin_InfamyValue)
    #curPlayer.SetDict("ThunderLogin", 1)
    #记录第一次登陆
    DataRecordPack.DR_FirstLogin(curPlayer.GetAccID(), curPlayer.GetIP(), curPlayer)
    #首登邮件
    mailList = IpyGameDataPY.GetFuncEvalCfg("MailLVAward", 2)
    for mailTypeKey, mailItemList in mailList:
        PlayerControl.SendMailByKey(mailTypeKey, [curPlayer.GetPlayerID()], mailItemList)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_FirstLogin, 1)
    return
def __DoMixServerFirstLogin(curPlayer):
    ## 合服首登处理
    isMixServer = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_IsMixServer)
    if not isMixServer:
        return
@@ -1296,7 +1207,6 @@
    #---等级限制---
    if GameWorld.IsCrossServer():
        return
    #PlayerTJG.TJGDeadOffline(curPlayer)
    
#===============================================================================
#    #---等级限制---
@@ -1351,12 +1261,7 @@
    curPlayer.SetMapLoadOK(False)
    curPlayer.SetVisible(False)
    curPlayer.SetCanAttack(False)
    #退出钓鱼清除渔夫装
    if curPlayer.GetPlayerAction() == IPY_GameWorld.paGameEvent:
        PlayerGameEvent.StopGameEvent(curPlayer, tick)
    else:
        PlayerGameEvent.TakeoffFishermanEquipment(curPlayer)
    #切地图要清除的buff
    __CheckClearBuffOnMapChange(curPlayer, tick)
            
@@ -1473,7 +1378,9 @@
        curPlayer.SendToBServerServerInitOK()   #通知route登录成功 ,route向客户端发送0109包
        OnAllServerInitOK(curPlayer, tick)
        #到此处已经可以保存数据,即使客户端不回包断线
        #后续登录流程等客户端回复 //01 07 地图读取OK#tagCInitMapOK 调用 LoadMapOK
        #原 //01 07 地图读取OK#tagCInitMapOK 逻辑 直接调用
        __Func_LoadMapOK(index, tick)
        GameServerRefresh.GameSever_PlayerInitOK(index, tick)
    except:
        curPlayer.Kick(IPY_GameWorld.disWaitForPlayerLoinError)
        import traceback
@@ -1526,25 +1433,7 @@
#    ------------------------------------------------------
    #玩家切换地图成功, 初始化玩家的附加信息(骠车, 召唤兽)
    curPlayer.InitChangeMapPlayerSummonInfo()
    #通知GameServer骠车现在的地图位置
    curTruck = curPlayer.GetTruck()
    if curTruck != None:
        curTruck.GameServer_Sync_TruckMapID()
        #镖车无敌
        SkillCommon.AddBuffBySkillType_NoRefurbish(curTruck, ChConfig.Def_SkillID_LimitSuperBuff, tick)
    
        #设置镖车等级
        truckLv = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_PawnTruckLV)
        curTruck.SetLV(truckLv)
        #更改镖车记录的部分主人信息
        PlayerTruck.ChangeTruckNoteInfo(curPlayer)
        #更新镖车进排行榜
        PlayerBillboard.UpdateBillboardPlayerTruck(curPlayer.GetPlayerID(), curPlayer.GetName(), curPlayer.GetOperateInfo(),
                                                   curPlayer.GetLV(), truckLv, curPlayer.GetMapID())
    #---初始化自己的召唤兽---
    #===========================================================================
    # for i in range(curPlayer.GetSummonCount()):
@@ -1564,7 +1453,7 @@
    PetControl.Sync_PetInfo_ChangeMap(curPlayer, tick)
    #通知GameServer自己现在的地图
    curPlayer.Sync_GameServer_MapID()
    #curPlayer.Sync_GameServer_MapID()
    
    #如果本地图是副本的话, 则通知GameServer玩家进入副本
    if GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtTeam:
@@ -1593,6 +1482,9 @@
    
    #初始化寻宝背包
    PlayerControl.Init_TreasurePack(curPlayer)
    #初始化英雄背包
    PlayerControl.Init_HeroPack(curPlayer)
    
    #初始化神兽物品背包
    curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptDogzItem)
@@ -1678,17 +1570,6 @@
#@param tick 时间戳
#@return 返回值无意义
#@remarks C++封包触发, 切换地图成功( 目标地图 )
def LoadMapOK(index, tick):
    GameWorld.GetPsycoFunc(__Func_LoadMapOK)(index, tick)
    GameServerRefresh.GameSever_PlayerInitOK(index, tick)
    return
#---------------------------------------------------------------------
##C++封包触发, 切换地图成功( 目标地图 )
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks C++封包触发, 切换地图成功( 目标地图 )
def __Func_LoadMapOK(index, tick):
    #在玩家切换场景/登录的时候, 会调用到这里, 地图读取成功
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
@@ -1730,20 +1611,18 @@
    #将玩家放置在这个地图上
    curPlayer.InitPos(curPlayer.GetPosX(), curPlayer.GetPosY())
    
    firstMission = QuestCommon.GetCommonMission(curPlayer)
    if not (firstMission and firstMission.GetProperty(QuestCommon.Def_NewGuyNoSight) == 1):
        #刷新自己的视野
        if not GameWorld.IsCrossServer() and (PlayerControl.GetCrossMapID(curPlayer) or curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomScene)):
            GameWorld.DebugLog("===本服LoadMapOK时玩家处于跨服或自定义场景状态,不设置可见!", curPlayer.GetPlayerID())
            PlayerControl.SetPlayerSightLevel(curPlayer, curPlayer.GetID())
        elif not GameWorld.IsCrossServer():
            realmDifficulty = PlayerControl.GetMapRealmDifficulty(curPlayer)
            if realmDifficulty:
                GameWorld.DebugLog("===本服LoadMapOK时玩家处于境界难度地图,自动设置难度!realmDifficulty=%s" % realmDifficulty, curPlayer.GetPlayerID())
                PlayerControl.SetRealmDifficulty(curPlayer, realmDifficulty)
        curPlayer.RefreshView()
        curPlayer.SetVisible(True)
    #刷新自己的视野
    if not GameWorld.IsCrossServer() and (PlayerControl.GetCrossMapID(curPlayer) or curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_ClientCustomScene)):
        GameWorld.DebugLog("===本服LoadMapOK时玩家处于跨服或自定义场景状态,不设置可见!", curPlayer.GetPlayerID())
        PlayerControl.SetPlayerSightLevel(curPlayer, curPlayer.GetID())
    elif not GameWorld.IsCrossServer():
        realmDifficulty = PlayerControl.GetMapRealmDifficulty(curPlayer)
        if realmDifficulty:
            GameWorld.DebugLog("===本服LoadMapOK时玩家处于境界难度地图,自动设置难度!realmDifficulty=%s" % realmDifficulty, curPlayer.GetPlayerID())
            PlayerControl.SetRealmDifficulty(curPlayer, realmDifficulty)
    curPlayer.RefreshView()
    curPlayer.SetVisible(True)
        
    #如果玩家hp为0,设置玩家为死亡状态
    if GameObj.GetHP(curPlayer) <= 0:
@@ -1792,12 +1671,6 @@
            #此时已经是下马状态不需要刷状态 但是需要通知客户端下马
            PlayerHorse.PlayerRideHorseDown(curPlayer, False)
        
    elif playerVehicle == IPY_GameWorld.pvTruck:
        #玩家上骠车, 不重置自己的位置, 因为玩家现在还在切换地图中(强制上车,因为有可能被攻击)
        PlayerTruck.PlayerTruckUP(curPlayer, False , False , False)
    InitPlayerTruck(curPlayer, tick)
    PlayerTeam.PlayerLoginSetTeam(curPlayer, tick)
    
    #激活玩家(保证持续性Buff处理间隔)
@@ -1808,12 +1681,6 @@
    
    #如果登录的副本,执行进入副本逻辑, 因为有时间响应, 必须在EndLoadMap之后...
    FBLogic.DoEnterFBLogic(curPlayer, tick)
    #触发玩家进入地图的事件
    EventShell.EventResponse_OnMap(curPlayer)
    #触发玩家进入地图的事件
    EventShell.EventResponse_OnMapEx(curPlayer)
    
    #触发切换地图宠物逻辑
    PetControl.DoLogic_PetLoadMapOK(curPlayer)
@@ -1853,16 +1720,6 @@
    #申请得到奖励物品
    #curPlayer.DataServer_CheckPrizeItem()
    #===========================================================================
    # #if curPlayer.GetDictByKey(ChConfig.Def_PlayerKey_Frist_Lock) == 1 \
    # if PlayerAutoCheckOnline.CheckBeginEvent(curPlayer):
    #    #防外挂锁定
    #    #玩家第一次进入, 触发了OnEnter, OnEnter会锁住玩家
    #    #但是在上面会解锁玩家
    #    #所以在这里强制判定, 如果触发了OnEnter, 那么在这里加锁
    #    curPlayer.BeginEvent()
    #===========================================================================
    
    #防止玩家读取地图时未触发OnDay,读取地图后再次验证(2009.9.11)
    PlayerEventCounter.UpdatePlayerLoginTime(curPlayer)
@@ -1944,76 +1801,6 @@
    curPlayer.Kick(IPY_GameWorld.disGMKick)
    return
#---------------------------------------------------------------------
##初始化玩家镖车
#@param curPlayer 玩家实例
#@param tick 时间戳
#@return 返回值无意义
#@remarks 初始化玩家镖车
def InitPlayerTruck(curPlayer, tick):
    curPlayer.SetTruckCalcStartTime(tick)
    #玩家骠车逻辑:
    #玩家如果有骠车:
    #1. 在本地图找寻自己的骠车
    #2. 如果没有找到, 发给GameServer要求自己骠车
    truckID = curPlayer.GetTruckID()
    GameWorld.Log("初始化骠车 ID = %d ..." % (truckID) , curPlayer.GetPlayerID())
    if truckID == 0:
        #2009.9.24 bug
        #玩家没有镖车ID, 但是有镖车状态, 强制改为0
        if curPlayer.GetTruckState() != 0:
            GameWorld.Log("###Fix Truck State!", curPlayer.GetPlayerID())
            curPlayer.SetTruckState(0)
        return
    #通知gameserver刷新自己的骠车
    curPlayer.GameServer_RefreshTruckReq()
    GameWorld.Log("通知gameserver刷新自己的骠车 id = %d" % (truckID) , curPlayer.GetPlayerID())
    curTruck = GameWorld.GetNPCManager().FindTruckByID(truckID)
    if not curTruck:
        return
    curPlayer.SetTruck(curTruck)
    #这句话一定要加, 用来通知客户端骠车开始, 显示骠车操控面板
    curPlayer.SetTruckID(curTruck.GetID())
    curTruck.SetOwner(curPlayer)
#    GameWorld.Log("玩家已有骠车" , curPlayer.GetPlayerID())
#===============================================================================
# #加经验值
# def AddExp(index, tick):
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#    sendTest = IPY_GameWorld.IPY_CSendTest()
#    addExp = sendTest.GetExp()
#    playerControl = PlayerControl.PlayerControl(curPlayer)
#    playerControl.AddExp(addExp,True)
#===============================================================================
#---------------------------------------------------------------------
#===============================================================================
# //03 01 加属性点#tagCAddPoint
# tagCAddPoint       *   GettagCAddPoint();
#
# class   IPY_CAddPoint
# {
# public:
#    //0:力量 1:精神 2:敏捷 3:体魄 4:智力 5:幸运
#    int      GetType();
#
#    int      GetPoint();
# };
#===============================================================================
##//03 01 加属性点#tagCAddPoint
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks //03 01 加属性点#tagCAddPoint
def AddPoint(index, tick):
    return
#// B2 06 玩家加点 #tagCMAddPoint
#
#struct    tagCMAddPoint
@@ -2052,7 +1839,6 @@
    NotifyPlayerBasePoint(curPlayer, pointAttrIDList)
    playerControl = PlayerControl.PlayerControl(curPlayer)
    playerControl.RefreshPlayerAttrState()
    EventShell.EventRespons_AddPoint(curPlayer)
    PlayerControl.SetLingGenMaxIndex(curPlayer)
    return
@@ -2109,8 +1895,6 @@
        ItemCommon.ReduceItem(curPlayer, itemPack, [delIndex], 1, False, ChConfig.ItemDel_ResetAttrPoint)
    
    Item_ResetAttrPoint.DoResetAttrPoint(curPlayer, 0, 0, 0)
    EventShell.EventRespons_LingGenReset(curPlayer)
    return
def NotifyPlayerBasePoint(curPlayer, syncAttrIDList=[]):
@@ -2303,10 +2087,6 @@
        curPlayer.ResetPos(curPlayer.GetPosX(), curPlayer.GetPosY())
        return
    
    #如果是小游戏中则停止小游戏
    if curPlayer.GetPlayerAction() == IPY_GameWorld.paGameEvent:
        PlayerGameEvent.StopGameEvent(curPlayer, tick)
    #删除有限无敌BUFF
    PlayerControl.DelLimitSuperBuff(curPlayer, tick)
    
@@ -2326,125 +2106,6 @@
    PetControl.FightPetFollowMove(curPlayer, sendPack_StartX, sendPack_StartY)
    
    
    return
#---------------------------------------------------------------------
#===============================================================================
# //05 01玩家移动#tagCPlayerMove
# tagCPlayerMove       *   GettagCPlayerMove();
#
# class   IPY_CPlayerMove
# {
# public:
#
#    int      GetStartX();
#
#    int      GetStartY();
#
#    int      GetDestX();
#
#    int      GetDestY();
#
#    int      GetWorldTick();
# };
#===============================================================================
##客户端封包响应//05 01玩家移动#tagCPlayerMove
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应//05 01玩家移动#tagCPlayerMove
def PlayerMove(index, tick):
    GameWorld.GetPsycoFunc(__Func_PlayerMove)(index, tick)
    return
##客户端封包响应//05 01玩家移动#tagCPlayerMove
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应//05 01玩家移动#tagCPlayerMove
def __Func_PlayerMove(index, tick):
    return
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    #防外挂 不可移动
    if curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_AutoCheckHack_State) \
                                      == ChConfig.Def_AutoCheck_State_Danger:
        return
    #不可移动行为状态, 判断客户端限制
    if not OperControlManager.IsObjCanDoAction(
                                        curPlayer,
                                        ChConfig.Def_Obj_ActState_ServerAct,
                                        IPY_GameWorld.oalMove
                                        ):
        return False
    #玩家移动通用检查
    if not __CheckPlayerCanMove(curPlayer):
        return
    #封包参数
    sendPack = IPY_GameWorld.IPY_CPlayerMove()
    sendPack_StartX = sendPack.GetStartX()
    sendPack_StartY = sendPack.GetStartY()
    sendPack_DestX = sendPack.GetDestX()
    sendPack_DestY = sendPack.GetDestY()
    sendPack_WorldTick = sendPack.GetWorldTick()
    #先验证目标点是否合法
    if not GameWorld.GetMap().CanMove(sendPack_DestX, sendPack_DestY):
        return
    #相同点不移动
    if (sendPack_StartX == sendPack_DestX) and (sendPack_StartY == sendPack_DestY):
        #GameWorld.ErrLog('PlayerMove 相同点不移动', curPlayer.GetID())
        return
    #---副本地图移动检查---
    if GameWorld.GetMap().GetMapFBType() != IPY_GameWorld.fbtNull:
        if not FBLogic.DoFBCanMove(curPlayer, sendPack_DestX, sendPack_DestY, tick):
            return
    #---正常移动---
    vehicle = curPlayer.GetPlayerVehicle()
    if vehicle not in [IPY_GameWorld.pvNull, IPY_GameWorld.pvHorse]:
        #GameWorld.ErrLog("不能移动, 交通工具不明 %d" % (vehicle), curPlayer.GetID())
        return
    #玩家正常移动
    PlayerNormalMove(curPlayer, sendPack_StartX, sendPack_StartY, sendPack_DestX,
                     sendPack_DestY, sendPack_WorldTick, tick)
#===============================================================================
#    attackTime = tick - curPlayer.GetPlayerAttackTick()
#    if attackTime <= curPlayer.GetAtkInterval() / 2:
#        #玩家攻击在僵直时间中, 不能走路
#        #GameWorld.Log("玩家攻击在僵直时间中, 不能走路 %d" %(attackTime) , curPlayer.GetPlayerID())
#        return
#===============================================================================
#===============================================================================
#    #玩家骑乘状态
#    vehicle = curPlayer.GetPlayerVehicle()
#
#    #如果在骑马状态,需要判定特殊坐骑
#    if vehicle == IPY_GameWorld.pvHorse and not __CheckHorseCanMove( curPlayer ):
#        __DoLogic_DropHorse( curPlayer , tick )
#        return
#
#    #玩家正常移动
#    if vehicle == IPY_GameWorld.pvNull or vehicle == IPY_GameWorld.pvHorse:
#        #玩家正常移动
#        PlayerNormalMove(curPlayer , moveData)
#    elif curPlayer.GetPlayerVehicle() == IPY_GameWorld.pvTruck :
#        #人镖合一,玩家移动
#        PlayerMoveByCarryerTruck(curPlayer , moveData)
#    else:
#        GameWorld.Log("不能移动, 交通工具不明 %d"%(vehicle) , curPlayer.GetPlayerID())
#===============================================================================
    return
#---------------------------------------------------------------------
@@ -2499,11 +2160,6 @@
                     client_DestY, clientWorldTick, tick) :
    # 废弃改成PY移动
    return
    #如果玩家事件中, 退出任务
#    if curPlayer.GetPlayerAction() == IPY_GameWorld.paEvent:
#        EventShell.DoExitEvent(curPlayer)
    curMap = GameWorld.GetMap()
    #校验客户端时间
    if not PlayerControl.PlayerMoveCheckClientWorldTick(curPlayer, clientWorldTick, client_StartX, client_StartY):
@@ -2514,14 +2170,6 @@
    if not CheckMovePos(curPlayer, curPlayer, curMap, client_StartX, client_StartY, client_DestX, client_DestY):
        return
    
    #假设客户端都是正确的,可行走障碍点
    #if PlayerControl.DoLogic_PlayerInBarrierPoint(curPlayer):
    #    return
    #如果是小游戏中则停止小游戏
    if curPlayer.GetPlayerAction() == IPY_GameWorld.paGameEvent:
        PlayerGameEvent.StopGameEvent(curPlayer, tick)
    #2010/04/30 移动修改为全C++控制, Python状态机设置为空闲(清空采集等状态)
    PlayerControl.ChangePlayerAction(curPlayer, IPY_GameWorld.paNull)
    #删除有限无敌BUFF
@@ -2536,40 +2184,6 @@
    #PetControl.FightPetFollowMove(curPlayer, client_DestX, client_DestY, client_StartX, client_StartY)
    return
#---------------------------------------------------------------------
##人镖合一,玩家移动
#@param curPlayer 玩家实例
#@param moveData 移动封包
#@return 返回值无意义
#@remarks 人镖合一,玩家移动
#===============================================================================
# def PlayerMoveByCarryerTruck(curPlayer , moveData) :
#    curPlayerTruck = curPlayer.GetTruck()
#    curMap = GameWorld.GetMap()
#
#    #不可移动行为状态, 服务端限制
#    if not OperControlManager.IsObjCanDoAction(curPlayerTruck,
#                                               ChConfig.Def_Obj_ActState_ServerAct,
#                                               IPY_GameWorld.oalMove):
#        return
#
#
#    if curPlayerTruck == None:
#        #离开人镖合一状态
#        GameWorld.Log("离开人镖合一状态" , curPlayer.GetPlayerID())
#        return
#
#    if CheckMovePos(curPlayer, curPlayerTruck, curMap, moveData.GetStartX(), moveData.GetStartY(), moveData.GetDestX(), moveData.GetDestY()) != True :
#        return
#
#    #镖车移动
#    #curPlayer.SetSpeed(curPlayerTruck.GetSpeed())
#    curPlayerTruck.Move(moveData.GetDestX(), moveData.GetDestY())
#    curPlayer.Sync_Move(moveData.GetDestX(), moveData.GetDestY())
#    return
#===============================================================================
#---------------------------------------------------------------------
##移动点检查, checkObj 是移动对象(在人镖合一状态下, 输入为骠车
#@param curPlayer 玩家实例
#@param checkObj 移动对象
@@ -2615,151 +2229,8 @@
            
        return False
    
#===============================================================================
#   考虑到会不同步的问题, 不加这个判定
#    #检查目标点上,是否有对象,有不让移动
#    mapObj = GameWorld.GetMap().GetPosObj(destX, destY)
#
#    if not mapObj:
#        return
#
#    for i in range(0, mapObj.GetObjCount()):
#        curObj = mapObj.GetObjByIndex(i)
#        #只有一种情况特殊:死亡的NPC可以让玩家走过去
#        if curObj.GetGameObjType() == IPY_GameWorld.gotNPC and \
#           GameObj.GetHP(curObj) <= 0 :
#            continue
#        curPlayer.MoveFail()
#        GameWorld.Log("移动失败,目标点有玩家或者NPC")
#        return
#===============================================================================
    #检查玩家到目的地2点之间是否可以直接走
    #===========================================================================
    # if moveDist > 15 and (not curMap.CanLineTo(destX, destY, objPosX, objPosY) \
    #        and not curMap.CanLineTo(objPosX, objPosY, destX, destY)):
    #
    #    #正反方向有一点不可走, 则不可走
    #    #GameWorld.Log("移动失败,检查玩家到目的地2点之间是否可以直接走(%d,%d)->(%d,%d), ClientCurPos:(%d,%d)"%(
    #    #                                            objPosX, objPosY,destX, destY,startX,startY ) , curPlayer.GetPlayerID())
    #    #地方不可走
    #    if sendPlayerMoveFail:
    #        curPlayer.MoveFail()
    #
    #    return False
    #===========================================================================
    return True
#---------------------------------------------------------------------
#===============================================================================
# //05 02 玩家停止移动#tagCPlayerStopMove
# tagCPlayerStopMove       *   GettagCPlayerStopMove();
#
# class   IPY_CPlayerStopMove
# {
# public:
#
#    int      GetPosX();
#
#    int      GetPosY();
#
#    int      GetDir();
#
#    int      GetWorldTick();
# };
#===============================================================================
##客户端封包响应 //05 02 玩家停止移动#tagCPlayerStopMove
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //05 02 玩家停止移动#tagCPlayerStopMove
def PlayerStopMove(index, tick):
    GameWorld.GetPsycoFunc(__Func_PlayerStopMove)(index, tick)
    return
##客户端封包响应 //05 02 玩家停止移动#tagCPlayerStopMove
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //05 02 玩家停止移动#tagCPlayerStopMove
def __Func_PlayerStopMove(index, tick):
    #===========================================================================
    # curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    #
    # #获取封包参数
    # sendPack = IPY_GameWorld.IPY_CPlayerStopMove()
    # sendPack_Tick = sendPack.GetWorldTick()
    # sendPack_PosX = sendPack.GetPosX()
    # sendPack_PosY = sendPack.GetPosY()
    # sendPack_Dir = sendPack.GetDir()
    #
    # #交通工具
    # vehicle = curPlayer.GetPlayerVehicle()
    #
    # #玩家停止移动
    # if curPlayer.GetPlayerVehicle() == IPY_GameWorld.pvNull or vehicle == IPY_GameWorld.pvHorse:
    #    PlayerNormalStopMove(curPlayer, sendPack_Tick, sendPack_PosX, sendPack_PosY, sendPack_Dir)
    #
    # #人镖合一停止移动
    # elif vehicle == IPY_GameWorld.pvTruck :
    #    #人镖合一停止移动
    #    PlayerStopMoveByCarryTruck(curPlayer, sendPack_Tick, sendPack_PosX, sendPack_PosY)
    #
    # else:
    #    GameWorld.Log("不能移动, 交通工具不明%d" % (vehicle) , curPlayer.GetPlayerID())
    #===========================================================================
    return
#---------------------------------------------------------------------
##玩家停止移动
#@param curPlayer 玩家实例
#@param sendPack_Tick 时间戳
#@param sendPack_PosX 目标X坐标
#@param sendPack_PosY 目标Y坐标
#@param sendPack_Dir 面向
#@return 返回值无意义
#@remarks 自定义函数 玩家停止移动
#===============================================================================
# def PlayerNormalStopMove(curPlayer, sendPack_Tick, sendPack_PosX, sendPack_PosY, sendPack_Dir) :
#    #玩家停止移动检查
#    if CheckPlayerStopMove(curPlayer) != True :
#        return
#
#    if not PlayerControl.PlayerMoveCheckClientWorldTick(curPlayer, sendPack_Tick, sendPack_PosX, sendPack_PosY):
#        return
#
#    if PlayerControl.PlayerRefreshPos(curPlayer, curPlayer, sendPack_PosX, sendPack_PosY) != True:
#        return
#
#    #curPlayer.SetFaceDir(sendPack_Dir)
#    curPlayer.StopMove()
#    return True
#
# #---------------------------------------------------------------------
# ##人镖合一停止移动
# #@param curPlayer 玩家实例
# #@param sendPack_Tick 时间戳
# #@return 返回值无意义
# #@remarks 自定义函数 人镖合一停止移动
# def PlayerStopMoveByCarryTruck(curPlayer, clientWorldTick, sendPack_PosX, sendPack_PosY):
#    curPlayerTruck = curPlayer.GetTruck()
#    if curPlayerTruck == None:
#        GameWorld.Log("人镖合一停止移动 -> 没有骠车!" , curPlayer.GetPlayerID())
#        return
#
#    if curPlayerTruck.GetCurAction() != IPY_GameWorld.laNPCMove :
#        return
#
#    if not PlayerControl.PlayerMoveCheckClientWorldTick(curPlayer, clientWorldTick, sendPack_PosX, sendPack_PosY):
#        return
#
#    curPlayerTruck.StopMove()
#    return True
#===============================================================================
#---------------------------------------------------------------------
#===============================================================================
# //03 05主角点击复活#tagCCliectReborn
# tagCCliectReborn       *   GettagCCliectReborn();
@@ -2869,209 +2340,6 @@
    return
#---------------------------------------------------------------------
#===============================================================================
# //04 01 获取区域内对象信息#tagCAreaObjInfo
# tagCAreaObjInfo       *   GettagCAreaObjInfo();
#
# class   IPY_CAreaObjInfo
# {
# public:
#
#    int      GetObjType();
#
#    int      GetObjID();
# };
#===============================================================================
##//04 01 获取区域内对象信息#tagCAreaObjInfo
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks //04 01 获取区域内对象信息#tagCAreaObjInfo
def PlayerNeedSeeOther(index, tick):
    #现在改为, 直接发送信息给客户端, 这个封包不处理了
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#    sendReq = IPY_GameWorld.IPY_CAreaObjInfo()
#    tagObj = GameWorld.GetObj(sendReq.GetObjID(), sendReq.GetObjType())
#
#    if tagObj == None:
#        GameWorld.Log("玩家请求其他玩家的相貌信息失败, 对象不存在")
#        return
#
#    if GameWorld.IsSameObj(curPlayer, tagObj):
#        #自己不能得到自己的信息
#        return
#
#    dist = GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), tagObj.GetPosX(), tagObj.GetPosY())
#    #对象在自己两倍视野外面, 则拒绝
#    if dist > curPlayer.GetSight() * 2:
#        #目标玩家在视野外面
#        GameWorld.Log("玩家请求其他玩家的相貌信息失败,目标玩家在视野外面 %d" % dist)
#        curPlayer.Sync_GetPlayerInfoFail(sendReq.GetObjID())
#        return
#
#    if tagObj.GetGameObjType() != IPY_GameWorld.gotPlayer:
#        return
#    curPlayer.SeeOtherPlayer(tagObj)
    return
#---------------------------------------------------------------------
#===============================================================================
# //04 02 获取鼠标左键点击之后对象的详细信息#tagCClickObjGetInfo
# tagCClickObjGetInfo       *   GettagCClickObjGetInfo();
#
# class   IPY_CClickObjGetInfo
# {
# public:
#
#    int      GetObjID();
#
#    int      GetObjType();
# };
#===============================================================================
##客户端封包响应//04 02 获取鼠标左键点击之后对象的详细信息#tagCClickObjGetInfo
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应//04 02 获取鼠标左键点击之后对象的详细信息#tagCClickObjGetInfo
def PlayerClickOtherPlayerGetInfo(index, tick):
    GameWorld.GetPsycoFunc(__Func_PlayerClickOtherPlayerGetInfo)(index, tick)
    return
##客户端封包响应//04 02 获取鼠标左键点击之后对象的详细信息#tagCClickObjGetInfo
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应//04 02 获取鼠标左键点击之后对象的详细信息#tagCClickObjGetInfo
def __Func_PlayerClickOtherPlayerGetInfo(index, tick):
    #===========================================================================
    # curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    #
    # sendPack = IPY_GameWorld.IPY_CClickObjGetInfo()
    # sendPack_ID = sendPack.GetObjID()
    # sendPack_Type = sendPack.GetObjType()
    #
    # tagObj = GameWorld.GetObj(sendPack_ID, sendPack_Type)
    #
    # if tagObj == None:
    #    #GameWorld.Log("玩家请求其他玩家的相貌信息失败, 对象不存在", curPlayer.GetPlayerID())
    #    return
    #
    # dist = GameWorld.GetDist(curPlayer.GetPosX(), curPlayer.GetPosY(), tagObj.GetPosX(), tagObj.GetPosY())
    # #是否可以目标详细信息
    # canGetDetail = (dist <= curPlayer.GetSight())
    # #目标类型
    # tagObjType = tagObj.GetGameObjType()
    #
    # #仅处理Player和NPC
    # if tagObjType not in [IPY_GameWorld.gotPlayer, IPY_GameWorld.gotNPC]:
    #    return
    #
    # #---玩家处理---
    # if tagObjType == IPY_GameWorld.gotPlayer:
    #    #获取玩家详细信息成功
    #    if canGetDetail:
    #        extendDataDict = {}
    #        extendDataDict['maxHP'] = GameObj.GetMaxHP(tagObj)
    #        extendDataDict['maxMP'] = tagObj.GetMaxMP()
    #        extendDataDict['hit'] = tagObj.GetHit()
    #        extendDataDict['miss'] = tagObj.GetMiss()
    #        extendDataDict['atkSpeed'] = PlayerControl.GetAtkSpeed(tagObj)
    #        extendDataDict['superHitRate'] = tagObj.GetSuperHitRate()
    #        extendDataDict['superHit'] = tagObj.GetSuperHit()
    #        extendDataDict['luckyHitRate'] = tagObj.GetLuckyHitRate()
    #        extendDataDict['greatHitRate'] = tagObj.GetGreatHitRate()
    #        extendDataDict['ignoreDefRate'] = tagObj.GetIgnoreDefRate()
    #        extendDataDict['damageReduceRate'] = tagObj.GetDamageReduceRate()
    #        extendDataDict['damageBackRate'] = tagObj.GetDamageBackRate()
    #
    #        extendData = str(extendDataDict)
    #        extendDataLen = len(extendData)
    #        curPlayer.PlayerClickOtherPlayerDetail(tagObj, extendDataLen, extendData)
    #        return
    #
    #    #获取玩家详细信息失败
    #    curPlayer.Sync_GetPlayerInfoFail(sendPack_ID)
    #    return
    #
    # #---NPC处理---
    #
    # #获取NPC详细信息成功
    # if canGetDetail:
    #    curPlayer.PlayerClickOtherNPCDetail(tagObj)
    #    return
    #
    #===========================================================================
    #获取NPC详细信息失败
    #暂不处理
    return
#---------------------------------------------------------------------
#===============================================================================
# //03 02 玩家坐下/站立#tagCSit
# tagCSit       *   GettagCSit();
#
# class   IPY_CSit
# {
# public:
#    //0:坐下 1:站立
#    int      GetType();
# };
#===============================================================================
##客户端封包响应 //03 02 玩家坐下/站立#tagCSit
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 02 玩家坐下/站立#tagCSit
def PlayerSit(index, tick):
    GameWorld.DebugLog("PlayerSit...")
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    #功能开启判断换成
    #GameFuncComm.GetFuncCanUse(curPlayer, funcID)
    #功能开启判断换成
    #GameFuncComm.GetFuncCanUse(curPlayer, funcID)
    if GameObj.GetHP(curPlayer) <= 0:
        return
    sendPack = IPY_GameWorld.IPY_CSit()
    setType = sendPack.GetType()
    if setType == 1: #手游版 只做站立
        PlayerControl.DoPlayerStand(curPlayer)
    return
    if curPlayer.IsMoving():
        PlayerControl.NotifyCode(curPlayer, "CanNotSitWrongState")
        return
    #在交通工具中, 不可打坐
    if curPlayer.GetPlayerVehicle() != IPY_GameWorld.pvNull:
        return
    #打坐行为,客户端限制
    if not OperControlManager.IsObjCanDoAction(curPlayer,
                                               ChConfig.Def_Obj_ActState_ServerAct,
                                               IPY_GameWorld.oalSit):
        return
    #设置回血/回魔开始标示位
    curPlayer.SetRestoreTime(tick)
    #获得封包
    sendPack = IPY_GameWorld.IPY_CSit()
    setType = sendPack.GetType()
    playAction = curPlayer.GetPlayerAction()
    #---想坐下---
    if setType == 0 and playAction == IPY_GameWorld.paNull:
        PlayerControl.DoPlayerSit(curPlayer, tick)
        return
    #---想站起来---
    PlayerControl.DoPlayerStand(curPlayer)
    return
#---------------------------------------------------------------------
##C++封包触发, 玩家下线
#@param index 玩家索引
#@param tick 时间戳
@@ -3080,28 +2348,6 @@
def PlayerDisconnect(index, tick):
    GameWorld.GetPsycoFunc(__Func_PlayerDisconnect)(index, tick)
    return
#---------------------------------------------------------------------
##记录新增有效登陆玩家,登陆10分钟以上玩家才算有效
# @param curPlayer 玩家实例
# @return None
def NoteLoginValid(curPlayer):
    if curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_LoginValid) == 1:
        #已记录
        return
    #计算时间, 当前减去登陆时间
    diffTime = GameWorld.GetCurrentTime() - GameWorld.GetDateTimeByStr(curPlayer.GetLoginTime().strip())
    #10分钟以上才算有效玩家
    if diffTime.days == 0 and diffTime.seconds < 10 * 60:
        return
    DataRecordPack.DR_LoginValid(curPlayer.GetAccID(), curPlayer.GetIP(), curPlayer)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_LoginValid, 1)
    return
##C++封包触发, 玩家下线
#@param index 玩家索引
@@ -3116,10 +2362,19 @@
    except:
        import traceback
        GameWorld.RaiseException("玩家下线逻辑错误\r\n%s" % traceback.format_exc())
    RecvPackToMapDB.MapCallDB(GetPackSaveData(curPlayer))
    #调用底层使玩家下线
    curPlayer.DoDisconnect(tick)
    
# 简化c++的保存数据封包
def GetPackSaveData(curPlayer):
    roleSaveData = base64.b64decode(curPlayer.GetPackData())  # base64加密了
    allData = ""
    allData = CommFunc.WriteBYTE(allData, IPY_ServerDefine.gstUpdate)
    allData = CommFunc.WriteString(allData, len(roleSaveData), roleSaveData)
    return  allData
##玩家正常下线
#@param curPlayer 玩家索引
#@param tick 时间戳
@@ -3142,9 +2397,6 @@
    #流向记录玩家下线
    DataRecordPack.DR_PlayerDisconnect(curPlayer)
    
    #记录新增有效登陆玩家
    NoteLoginValid(curPlayer)
    #VIP时间
    #PlayerVip.CalcVIPTimeByTick(curPlayer, tick, False)
    #在线时间
@@ -3166,15 +2418,10 @@
    #设置RouteServerInitOK字典
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_RouteServerInitOK, 0)
    
    #取消自动运镖状态
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_AutoTruck, 0)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PlayerKey_CrossRegisterMap, 0)
    
    #下线召回宠物
    PetControl.ReCallFightPet(curPlayer)
    #PlayerTJG.CalcPlayerTJG(curPlayer, tick)
    
    #离线session
    EventReport.WriteEvent_session(curPlayer)
@@ -3314,36 +2561,6 @@
    NetPackCommon.SendFakePack(curPlayer, showGuide)
    return
#---------------------------------------------------------------------
#===============================================================================
# //05 03 玩家跳跃#tagCJump
# tagCJump       *   GettagCJump();
#
# class   IPY_CJump
# {
# public:
#
#    int      GetSkillID();
#
#    int      GetStartPosX();
#
#    int      GetStartPosY();
#
#    int      GetEndPosX();
#
#    int      GetEndPosY();
# };
#===============================================================================
##客户端封包响应 //05 03 玩家跳跃#tagCJump
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //05 03 玩家跳跃#tagCJump
def PlayerJump(index, tick):
    #没这个功能了
    return
## 玩家状态变更
#  @param index 玩家索引
#  @param tick 当前时间
@@ -3359,9 +2576,6 @@
    if lastAction == curAction:
        return
    
    #如果上一个状态是小游戏状态
    if lastAction == IPY_GameWorld.paGameEvent:
        PlayerGameEvent.TakeoffFishermanEquipment(curPlayer)
    return
#---------------------------------------------------------------------
@@ -3427,117 +2641,7 @@
        
    return
#---------------------------------------------------------------------
#===============================================================================
# //03 0B 设置金钱类型#tagCSetMoneyType
# tagCSetMoneyType       *   GettagCSetMoneyType();
#
# class   IPY_CSetMoneyType
# {
# public:
#    //1:金子/金票    2:银子/银票
#    int      GetType();
#    //TMoneyType
#    int      GetMoneyType();
# };
#===============================================================================
##客户端封包响应 //03 0B 设置金钱类型#tagCSetMoneyType
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 0B 设置金钱类型#tagCSetMoneyType
def SetMoneyType(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    sendPack = IPY_GameWorld.IPY_CSetMoneyType()
    curType = sendPack.GetType()
    curMoneyType = sendPack.GetMoneyType()
    if curType == 1 and curMoneyType == IPY_GameWorld.TYPE_Price_Gold_Money :
        curPlayer.SetUseGoldType(IPY_GameWorld.TYPE_Price_Gold_Money)
    elif curType == 1 and curMoneyType == IPY_GameWorld.TYPE_Price_Gold_Paper :
        curPlayer.SetUseGoldType(IPY_GameWorld.TYPE_Price_Gold_Paper)
    elif curType == 2 and curMoneyType == IPY_GameWorld.TYPE_Price_Silver_Money :
        curPlayer.SetUseSilverType(IPY_GameWorld.TYPE_Price_Silver_Money)
    elif curType == 2 and curMoneyType == IPY_GameWorld.TYPE_Price_Silver_Paper :
        curPlayer.SetUseSilverType(IPY_GameWorld.TYPE_Price_Silver_Paper)
    else:
        GameWorld.Log("SetMoneyType = > 金钱类型 = %s错误" % (curType) , curPlayer.GetPlayerID())
        return
    return
#---------------------------------------------------------------------
#===============================================================================
# //03 08 打开大地图#tagCOpenMap
# tagCOpenMap       *   GettagCOpenMap();
#
# class   IPY_COpenMap
# {
# public:
#
#    int      GetType();
# };
#===============================================================================
##客户端封包响应 //03 08 打开大地图#tagCOpenMap
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 08 打开大地图#tagCOpenMap
def PlayerMapInfo(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    if tick - curPlayer.GetPosInfoTick() < ChConfig.Def_GetOtherPosInterval:
        return
    curPlayer.SetPosInfoTick(tick)
    #队伍信息同步
    PlayerTeam.NotifyPosInfoToPlayer(curPlayer, tick)
    #骠车信息同步
    PlayerTruck.NotifyPosInfoToPlayer(curPlayer, tick)
    #通知大地图标记点数量
    OnSendMapSignCnt(curPlayer)
    return
#---------------------------------------------------------------------
#===============================================================================
# //03 0A 更改攻击模式#tagCChangeAttackMode
# tagCChangeAttackMode       *   GettagCChangeAttackMode();
#
# class   IPY_CChangeAttackMode
# {
# public:
#    //TAttackMode
#    int      GetMode();
# };
#===============================================================================
##客户端封包响应 //03 0A 更改攻击模式#tagCChangeAttackMode
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 0A 更改攻击模式#tagCChangeAttackMode
def PlayerChangeAttackMode(index, tick) :
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    sendPack = IPY_GameWorld.IPY_CChangeAttackMode()
    sendPackMode = sendPack.GetMode()
    #不可切换模式的地图
    mapID = GameWorld.GetMap().GetMapID()
    if mapID in ChConfig.Def_CanNotChangeAtkModelMap:
        GameWorld.Log("本地图不可切换PK模式,mapID=%s" % (mapID), curPlayer.GetPlayerID())
        return
    #===============================================================================================
    # #只有amPeace和amAll
    # #if sendPackMode < 0 or sendPackMode > IPY_GameWorld.amAll :
    # if sendPackMode not in [IPY_GameWorld.amPeace, IPY_GameWorld.amAll, IPY_GameWorld.amFamily]:
    #    GameWorld.Log("切换攻击模式封包,类型 = %s错误" % (sendPackMode) , curPlayer.GetPlayerID())
    #    return
    #===============================================================================================
    ChangeAttackMode(curPlayer, sendPackMode)
    return
#//03 0A 更改攻击模式#tagCChangeAttackMode
##改变玩家PK模式
#@param curPlayer 玩家
#@param attackMode
@@ -3566,154 +2670,6 @@
    SyncPKModel(curPlayer)
    return
#---------------------------------------------------------------------
#===============================================================================
# //06 06 取消Buff#tagCCancelBuff
# tagCCancelBuff       *   GettagCCancelBuff();
#
# class   IPY_CCancelBuff
# {
# public:
#
#    int      GetBuffID();
# };
#===============================================================================
##客户端封包响应 //06 06 取消Buff#tagCCancelBuff
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //06 06 取消Buff#tagCCancelBuff
def PlayerCancelBuff(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    sendPack = IPY_GameWorld.IPY_CCancelBuff()
    skillID = sendPack.GetBuffID()
    #---查找取消的技能---
    #---清空Buff---
    #@bug 2607: 持续性技能调用DoBuffDisApper, 导致持续性回血Buff, 一次性将剩余的回复量都加上了
    #===========================================================================
    # if buffSkill.GetSkillType() not in ChConfig.Def_LstBuff_List:
    #    BuffSkill.DoBuffDisApper(curPlayer, curPlayerCancelbuff, tick)
    #===========================================================================
    BuffSkill.DelBuffBySkillID(curPlayer, skillID, tick)
    #刷新人物属性
    playerControl = PlayerControl.PlayerControl(curPlayer)
    #刷新所有状态
    playerControl.RefreshPlayerAttrByBuff()
    #GameWorld.Log("玩家取消buff成功,buffTypeID = %s"%(buffSkillTypeID) , curPlayer.GetPlayerID())
    return
#---------------------------------------------------------------------
#===============================================================================
# //03 0C 开始跳舞/钓鱼#tagCStartGameEvent
# tagCStartGameEvent       *   GettagCStartGameEvent();
#
# class   IPY_CStartGameEvent
# {
# public:
#    //游戏事件 Type = TGameEvent
#    int      GetType();
# };
#===============================================================================
##客户端封包响应 //03 0C 开始跳舞/钓鱼#tagCStartGameEvent
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 0C 开始跳舞/钓鱼#tagCStartGameEvent
def StartGameEvent(index, tick):
    GameWorld.GetPsycoFunc(__Func_StartGameEvent)(index, tick)
    return
##客户端封包响应 //03 0C 开始跳舞/钓鱼#tagCStartGameEvent
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 0C 开始跳舞/钓鱼#tagCStartGameEvent
def __Func_StartGameEvent(index, tick):
    #游戏事件 Type = TGameEvent
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    if GameObj.GetHP(curPlayer) == 0:
        #GameWorld.Log("玩家死亡,没有事件")
        return
    sendPack = IPY_GameWorld.IPY_CStartGameEvent()
    eventType = sendPack.GetType()
    #---停止游戏事件---
    if eventType == IPY_GameWorld.geNull:
        PlayerGameEvent.StopGameEvent(curPlayer, tick)
        return
    #2010-5-26 只开启钓鱼,关闭跳舞
    if eventType != IPY_GameWorld.geFish:
        return
    #通过动作获得相应动作位
    curActBit = OperControlManager.GetActBitByAction(ChConfig.Def_ActBit_GameEvent, eventType)
    if curActBit != None:
        #拉进度条中 状态,客户端限制
        if not OperControlManager.IsObjCanDoAction(curPlayer,
                                                   ChConfig.Def_Obj_ActState_ClientAct,
                                                   curActBit):
            return
    #---验证是否可以开始小游戏事件---
    lastShowEventTick = curPlayer.GetGameEventTick()
    if tick - lastShowEventTick < ChConfig.Def_ShowEventTime:
        #GameWorld.Log("事件播放间隔太短")
        return
    #检查是否可以开始小游戏
    if not PlayerGameEvent.CheckCanBeginGameEvent(curPlayer, tick):
        return
    if not PlayerGameEvent.CanProcessGameEvent(curPlayer, eventType, tick):
        #PlayerGameEvent.StopGameEvent(curPlayer,tick)
        return
    #---开始执行小游戏事件---
    #设置玩家当期为游戏事件状态
    PlayerControl.ChangePlayerAction(curPlayer, IPY_GameWorld.paGameEvent)
    #设定开始游戏事件
    PlayerGameEvent.StartGameEvent(curPlayer, eventType, tick)
    return
#// B0 50 钓鱼收杆 #tagCMDoFish
#
#struct    tagCMDoFish
#
#{
#    tagHead        Head;
#    BYTE        FishNum;        // 钓鱼编号1~N
#    BYTE        PosIndex;    // 停留位置1~N
#};
## 钓鱼收杆
#  @param curPlayer
#  @return None
#===============================================================================
# def OnDoFish(index, clientData, tick):
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#    if not curPlayer:
#        return
#
#    if curPlayer.GetPlayerAction() != IPY_GameWorld.paGameEvent:
#        GameWorld.DebugLog("非小游戏状态下,不可收杆!", curPlayer.GetPlayerID())
#        return
#
#    if curPlayer.GetPlayerGameEvent() != IPY_GameWorld.geFish:
#        GameWorld.DebugLog("非钓鱼状态下,不可收杆!", curPlayer.GetPlayerID())
#        return
#
#    fishType = clientData.PosIndex
#    PlayerGameEvent.DoFishLogic(curPlayer, fishType)
#    return
#===============================================================================
#===============================================================================
# //A1 03 设置是否成年 #tagCMAdult
@@ -3730,59 +2686,6 @@
    curPlayer.ChangeAdult(adult)
    return
#---------------------------------------------------------------------
#===============================================================================
# //03 0D 玩家自定义动作#tagCShowFace
# tagCShowFace       *   GettagCShowFace();
#
# class   IPY_CShowFace
# {
# public:
#    //表情类型, 客户端自定, 服务器广播这个Type
#    int      GetType();
# };
#===============================================================================
##客户端封包响应 //03 0D 玩家自定义动作#tagCShowFace
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 0D 玩家自定义动作#tagCShowFace
def ShowFace(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    if tick - curPlayer.GetShowFaceTick() < ChConfig.Def_ShowEventTime:
        return
    if GameObj.GetHP(curPlayer) <= 0:
        return
    #表情行为, 客户端限制
    if not OperControlManager.IsObjCanDoAction(curPlayer,
                                               ChConfig.Def_Obj_ActState_ClientAct,
                                               IPY_GameWorld.oalLook):
        return
    #移动中不执行此操作
    if curPlayer.IsMoving():
        #PlayerControl.NotifyCode(curPlayer, "GeRen_lhs_0")
        return
    if curPlayer.GetPlayerAction() != IPY_GameWorld.paNull:
        return
    if curPlayer.GetPlayerVehicle() != IPY_GameWorld.pvNull:
        return
    #设置间隔
    curPlayer.SetShowFaceTick(tick)
    sendPack = IPY_GameWorld.IPY_CShowFace()
    PlayerControl.DoPlayerShowPlayerFace(curPlayer, sendPack.GetType())
    return True
#----------------------------自定义方法
#---------------------------------------------------------------------
##检查玩家是否可以停止移动
#@param curPlayer 玩家实例
@@ -3853,321 +2756,6 @@
    NetPackCommon.SendFakePack(curPlayer, sendPack)
    
    GameWorld.Log("地图切换失败", curPlayer.GetID())
    return
#---------------------------------------------------------------------
#===============================================================================
# //01 04 在线回应#tagCOnlineReturn
# tagCOnlineReturn       *   GettagCOnlineReturn();
#
# class   IPY_COnlineReturn
# {
# public:
#
#    int      GetType();
# };
#===============================================================================
##客户端封包响应 //01 04 在线回应#tagCOnlineReturn
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //01 04 在线回应#tagCOnlineReturn
def OnlineReply(index, tick):
    #目前做到RouteServer中去了
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#
#    lastOnlineReplyTick = curPlayer.GetLastOnlineReplyTick()
#
#    #回应次数+1
#    curPlayer.SetLastOnlineReplyTick(tick)
#    curPlayer.SetOnlineReplyCount(curPlayer.GetOnlineReplyCount() + 1)
#    if lastOnlineReplyTick == 0:
#        GameWorld.Log("初始化在线回应")
#        #GameWorld.Log("GetLastOnlineReplyTick %d"%curPlayer.GetLastOnlineReplyTick())
#        return
#
#    #GameWorld.Log("tick %d"%tick)
#    diffTick = tick - lastOnlineReplyTick - ChConfig.Def_PlayerOnLineReply_ClientReply
#    if diffTick < -ChConfig.Def_PlayerOnLineReply_ClientReply:
#        GameWorld.Log("在线回应间隔错误 = %d"%diffTick)
#        curPlayer.Kick(IPY_GameWorld.disOnlineReplyError)
#        return
#
#
##    GameWorld.Log(str(curPlayer.GetTotalOnlineReplyTick()))
##    GameWorld.Log(str(diffTick))
#    curPlayer.SetTotalOnlineReplyTick(curPlayer.GetTotalOnlineReplyTick() + diffTick)
#
#    GameWorld.Log("在线回应次数 = %d  总时间 = %d"%(curPlayer.GetOnlineReplyCount(), curPlayer.GetTotalOnlineReplyTick()))
    return
#---------------------------------------------------------------------
#===============================================================================
# //06 08 召唤兽移动#tagCSummonMove
# tagCSummonMove       *   GettagCSummonMove();
#
# class   IPY_CSummonMove
# {
# public:
#
#    int      GetSummonID();
#
#    int      GetPosX();
#
#    int      GetPosY();
#
#    int      GetDestPosX();
#
#    int      GetDestPosY();
# };
#===============================================================================
##客户端封包响应 //06 08 召唤兽移动#tagCSummonMove
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //06 08 召唤兽移动#tagCSummonMove
def PlayerSummonMove(index, tick):
    #逻辑做服务器端
    return
#===============================================================================
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#    sendPack = IPY_GameWorld.IPY_CSummonMove()
#    summonID = sendPack.GetSummonID()
#    posX = sendPack.GetPosX()
#    posY = sendPack.GetPosY()
#    destX = sendPack.GetDestPosX()
#    destY = sendPack.GetDestPosY()
#    #找到这个召唤兽
#    summonNPC = curPlayer.FindSummonByID(summonID)
#    #无法查找到这个召唤兽
#    if summonNPC == None or GameObj.GetHP(summonNPC) <= 0:
#        GameWorld.Log('无法查找到这个召唤兽 summonID=%d'%summonID)
#        return
#
#    if ChConfig.Def_ClientControlSummonNPCID.count(summonNPC.GetFunctionType()) == 0:
#        #这个召唤兽客户端不能控制
#        #GameWorld.Log('这个召唤兽客户端不能控制')
#        return
#
#
#    #目的地是否可以到达
#    curMap = GameWorld.GetMap()
#    if curMap.CanMove(destX, destY) != True:
#        #地方不可走, 重置玩家的位置
#        GameWorld.Log("召唤兽地方不可走, destX=%s, destY=%s"%(destX, destY))
#        return
# #===============================================================================
# #    curMap = GameWorld.GetMap()
# #    if CheckMovePos(curPlayer, summonNPC,curMap, posX, posY, destX, destY, sendPlayerMoveFail = False) != True :
# #        #封包信息错误
# #        return
# #===============================================================================
#
#
#    #移动点坐标
#    dist = GameWorld.GetDist(posX, posY, destX, destY)
#    if dist > 20 :
#        #瞬移
#        GameWorld.Log('召唤兽瞬移summonID=%d'%summonID)
#        summonNPC.ResetPos(destX, destY)
#        return
#
#    #正常移动
#    summonNPC.Move(destX, destY)
#    return
#===============================================================================
#---------------------------------------------------------------------
#===============================================================================
# //06 09 召唤兽攻击#tagCSummonAttack
# tagCSummonAttack       *   GettagCSummonAttack();
#
# class   IPY_CSummonAttack
# {
# public:
#
#    int      GetSummonID();
#
#    int      GetObjType();
#
#    int      GetObjID();
#
#    int      GetPosX();
#
#    int      GetPosY();
# };
#===============================================================================
##客户端封包响应 //06 09 召唤兽攻击#tagCSummonAttack
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //06 09 召唤兽攻击#tagCSummonAttack
def PlayerSummonAttack(index, tick):
    #逻辑做服务器端
    return
#===============================================================================
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#    sendPack = IPY_GameWorld.IPY_CSummonAttack()
#    summonID = sendPack.GetSummonID()
#    posX = sendPack.GetPosX()
#    posY = sendPack.GetPosY()
#    attackType = sendPack.GetObjType()
#    attackID = sendPack.GetObjID()
#
#    #找到这个召唤兽
#    summonNPC = curPlayer.FindSummonByID(summonID)
#    #无法查找到这个召唤兽
#    if summonNPC == None or GameObj.GetHP(summonNPC) <= 0:
#        GameWorld.Log('找不到召唤兽')
#        return
#
#    if ChConfig.Def_ClientControlSummonNPCID.count(summonNPC.GetFunctionType()) == 0:
#        #这个召唤兽客户端不能控制
#        GameWorld.Log('这个召唤兽客户端不能控制')
#        return
#
#    #判断公共CD
#    if tick - summonNPC.GetAttackTick() < summonNPC.GetAtkInterval():
#        GameWorld.Log("攻击间隔没有到")
#        return
#
#    if PlayerControl.PlayerRefreshPos(curPlayer, summonNPC, posX, posY) != True:
#        #当前位置刷新失败
#        GameWorld.Log("召唤兽攻击当前位置刷新失败")
#        return
#
#    #被攻击者
#    attackTag = None
#    if attackType == IPY_GameWorld.gotPlayer:
#        attackTag = GameWorld.GetPlayerManager().FindPlayerByID(attackID)
#    elif attackType == IPY_GameWorld.gotNPC:
#        attackTag = GameWorld.FindNPCByID(attackID)
#    else:
#        #封包类型错误,或对象无法攻击
#        GameWorld.Log("召唤兽封包攻击类型错误 attackType = %s"%(attackType))
#        return
#
#    #无法查找攻击目标
#    if attackTag == None :
#        GameWorld.Log("无法查找攻击目标,attackID = %s"%(attackID))
#        return
#
#    if not BaseAttack.GetCanAttack(summonNPC, attackTag, None, tick):
#        return
#
#    if not __CheckPlayerSummonAttack(curPlayer , summonNPC , attackTag , tick):
#        return
#
#    #普通攻击
#    BaseAttack.Attack(summonNPC,attackTag, None, 0, 1,tick)
#
#    return
#===============================================================================
#===============================================================================
# def __CheckPlayerSummonAttack(curPlayer , summonNPC , attackTag , tick):
#    #1. 如果主人在战斗状态, 并且攻击对象为封包中的攻击对象, 返回True
#    #这个逻辑,将会导致,如果玩家停止攻击守卫,那么召唤兽将不攻击守卫
#    if curPlayer.IsBattleState() :
#        curOwnerActionObj = curPlayer.GetActionObj()
#        if curOwnerActionObj != None and GameWorld.IsSameObj(curOwnerActionObj, attackTag):
#            return True
#
#    #2. 判定关系
#    #判断是否敌对关系
#    relation = BaseAttack.GetTagRelation(summonNPC, attackTag, None, tick)
#
#    if relation[0] != ChConfig.Type_Relation_Enemy  :
#        GameWorld.Log("Attack Fail : Message = %s"%relation[1])
#        AttackCommon.PlayerAttackFailSysMessanage(curPlayer,relation[1])
#        return False
#
#    return True
#===============================================================================
#---------------------------------------------------------------------
#===============================================================================
# //06 0A 召唤兽停止#tagCSummonStop
# tagCSummonStop       *   GettagCSummonStop();
#
# class   IPY_CSummonStop
# {
# public:
#
#    int      GetSummonID();
#
#    int      GetPosX();
#
#    int      GetPosY();
# };
#===============================================================================
##客户端封包响应 //06 0A 召唤兽停止#tagCSummonStop
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //06 0A 召唤兽停止#tagCSummonStop
def PlayerSummonStop(index , tick):
    #逻辑做服务器端
    return
#===============================================================================
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#    sendPack = IPY_GameWorld.IPY_CSummonStop()
#    summonID = sendPack.GetSummonID()
#    posX = sendPack.GetPosX()
#    posY = sendPack.GetPosY()
#
#    #找到这个召唤兽
#    summonNPC = curPlayer.FindSummonByID(summonID)
#
#    #无法查找到这个召唤兽
#    if summonNPC == None or GameObj.GetHP(summonNPC) <= 0:
#        return
#
#    if ChConfig.Def_ClientControlSummonNPCID.count(summonNPC.GetFunctionType()) == 0:
#        #这个召唤兽客户端不能控制
#        #GameWorld.Log('这个召唤兽客户端不能控制')
#        return
#
#    if PlayerControl.PlayerRefreshPos(curPlayer, summonNPC, posX, posY) != True:
#        #当前位置刷新失败
#        GameWorld.Log("召唤兽攻击当前位置刷新失败")
#        return
#
#    summonNPC.StopMove()
#
#    return
#===============================================================================
#---------------------------------------------------------------------
#===============================================================================
# //03 0F 是否隐藏面具#tagCHideMask
# tagCHideMask       *   GettagCHideMask();
#
# class   IPY_CHideMask
# {
# public:
#    //是否隐藏
#    int      GetIsHide();
# };
#===============================================================================
##客户端封包响应 //03 0F 是否隐藏面具#tagCHideMask
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 0F 是否隐藏面具#tagCHideMask
def HideMask(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    sendPack = IPY_GameWorld.IPY_CHideMask()
    isHide = sendPack.GetIsHide()
    if isHide != 0 and isHide != 1:
        GameWorld.Log("HideMask -> 封包类型错误isHide = %s" % (isHide) , curPlayer.GetPlayerID())
        return
    if curPlayer.GetIsHideMask() == isHide:
        return
    curPlayer.SetIsHideMask(isHide)
    return
#---------------------------------------------------------------------
@@ -4298,56 +2886,12 @@
        #GameWorld.Log("战斗中无法换线")
        return False
    
    #---有镖车---
    if curPlayer.GetTruck() != None:
        #GeRen_liubo_760310   <n color="0,255,0">对不起,您处于押运状态中,无法切换线路!</n> 256 -
        PlayerControl.NotifyCode(curPlayer, "GeRen_liubo_760310")
        return False
    if curPlayer.GetPlayerVehicle() not in ChConfig.Def_PlayerChangLine_Vehicle:
        #GeRen_liubo_760310   <n color="0,255,0">对不起,您处于押运状态中,无法切换线路!</n> 256 -
        PlayerControl.NotifyCode(curPlayer, "GeRen_liubo_760310")
        return False
    return True
#---------------------------------------------------------------------
#===============================================================================
# //01 0C 得到当前服务器线路状态#tagCGetLineState
# tagCGetLineState       *   GettagCGetLineState();
#
# class   IPY_CGetLineState
# {
# public:
#    //无意义
#    int      GetType();
# };
#===============================================================================
##客户端封包响应 //01 0C 得到当前服务器线路状态#tagCGetLineState
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //01 0C 得到当前服务器线路状态#tagCGetLineState
def LineState(index, tick):
    #改为GameServer同步要查询的地图ID
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#    #1. 只有普通地图查看线路
#    gameMap = GameWorld.GetMap()
#
#    if gameMap.GetMapFBType() != IPY_GameWorld.fbtNull:
#        #Line_lose_Examine  <n color="0,255,0">`o对不起,目前该地图没有开放分流,无法查看线路状态!</n>
#        #PlayerControl.NotifyCode(curPlayer, "Line_lose_Examine")
#        return
#
#    if tick - curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_LineState) <= ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_LineState]:
#        #Line_Examinelose_Frequent  <n color="0,255,0">`o对不起,对不起,您查看游戏线路状态过于频繁,请稍后重试!</n>   256
#        #PlayerControl.NotifyCode(curPlayer, "Line_Examinelose_Frequent")
#        return
#
#    curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_LineState, tick)
#    #GameWorld.Log("查看分流成功" , curPlayer.GetPlayerID())
#    curPlayer.GameServer_LineState()
    return
def GetRebronTime(curPlayer, rebornType):
    ''' 死亡状态才验证时间,本服跨服通用
@@ -4528,7 +3072,7 @@
        playerControl.SetToBornPlace()        
    elif rebornType == ChConfig.rebornType_MainCity:
        #直接取db中配置的复活点
        PlayerControl.PlayerResetWorldPos(curPlayer, gameMap.GetRebornMapID(), gameMap.GetRebornMapX(), gameMap.GetRebornMapY(), False)
        PlayerControl.PlayerResetWorldPos(curPlayer, gameMap.GetRebornMapID(), gameMap.GetRebornMapX(), gameMap.GetRebornMapY())
    #重新召唤宠物
    PlayerPet.AutoSummonPet(curPlayer)
    
@@ -4579,243 +3123,6 @@
    
    FBLogic.DoFBOnReborn(curPlayer, rebornType, tick)
    return
#---------------------------------------------------------------------
#===============================================================================
# //03 11 使用锻造炉#tagCUseMakeStove
# tagCUseMakeStove       *   GettagCUseMakeStove();
#
# class   IPY_CUseMakeStove
# {
# public:
#    //无意义
#    int      GetType();
# };
#===============================================================================
##客户端封包响应 //03 11 使用锻造炉#tagCUseMakeStove
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 11 使用锻造炉#tagCUseMakeStove
def PlayerUseMakeStove(index , tick):
    #===============================================================================================
    # curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    #
    # #功能开启判断换成
    # #GameFuncComm.GetFuncCanUse(curPlayer, funcID)
    #
    # #非空闲状态无法使用
    # if curPlayer.GetPlayerAction() not in ChConfig.Def_Player_DoEvent_State:
    #    PlayerControl.NotifyCode(curPlayer, "Factory_Execution_Wrong")
    #    return
    #
    # #移动中不执行此操作
    # if curPlayer.IsMoving():
    #    #PlayerControl.NotifyCode(curPlayer, "GeRen_lhs_0")
    #    return False
    #
    # #开始锻造事件
    # ItemCommon.DoLogic_UseStoveEvent(curPlayer)
    #===============================================================================================
    return
#---------------------------------------------------------------------
#===============================================================================
# //03 12 查看家族战排期#tagCGetFamilyWarTime
# tagCGetFamilyWarTime       *   GettagCGetFamilyWarTime();
#
# class   IPY_CGetFamilyWarTime
# {
# public:
#    //无意义
#    int      GetType();
# };
#===============================================================================
##客户端封包响应 //03 12 查看家族战排期#tagCGetFamilyWarTime
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 12 查看家族战排期#tagCGetFamilyWarTime
def QueryFamilyWarPlan(index, tick):
#===================================================================================================
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#
#    if not GameWorld.SetPlayerTickTime(curPlayer, ChConfig.TYPE_Player_Tick_QueryFamilyWar, tick):
#        #操作过于频繁
#        return
#
#    if curPlayer.GetFamilyID() == 0:
#        #无家族不查询
#        return
#
#    #开始查询
#    curPlayer.GameServer_QueryPlayerByID(ChConfig.queryType_sqtFamilyWar, 0, '', '', 0)
#===================================================================================================
    return
#-------------------------------------------------------------------
#===============================================================================
# //03 13 查询镖车位置#tagCGetTruckPos
# tagCGetTruckPos       *   GettagCGetTruckPos();
#
# class   IPY_CGetTruckPos
# {
# public:
#    //无意义
#    int      GetType();
# };
#===============================================================================
##客户端封包响应 //03 13 查询镖车位置#tagCGetTruckPos
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 13 查询镖车位置#tagCGetTruckPos
def QueryTruckPos(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
 #    GameWorld.Log('进入镖车查询 ID:%s'%curPlayer.GetID())
    if tick - curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_QueryTruckPos) <= ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_QueryTruckPos]:
        #查询过于频繁
        PlayerControl.NotifyCode(curPlayer, "Old_hgg_31379")
        return
    curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_QueryTruckPos, tick)
    #开始查询
    curPlayer.GameServer_QueryPlayerByID(ChConfig.queryType_sqtTruck, curPlayer.GetTruckID(), 'TruckPos', '', 0)
    return
#---------------------------------------------------------------------
#===============================================================================
# //03 14 传送镖车位置#tagCMoveToTruckPos
# tagCMoveToTruckPos       *   GettagCMoveToTruckPos();
#
# class   IPY_CMoveToTruckPos
# {
# public:
#    //无意义
#    int      GetType();
# };
#===============================================================================
##客户端封包响应 //03 14 传送镖车位置#tagCMoveToTruckPos
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 14 传送镖车位置#tagCMoveToTruckPos
def MoveToTruckPos(index, tick):
#===============================================================================
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#
#    if tick - curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_MoveToTruckPos) <= ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_MoveToTruckPos]:
#        #传送过于频繁
#        PlayerControl.NotifyCode(curPlayer, "Convey_Car_Frequently")
#        return
#
#    curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_MoveToTruckPos, tick)
#
#    #判定玩家状态
#    if not PlayerControl.CheckTransState(curPlayer):
#        return
#
#    #战斗状态不让玩家传送
#    if curPlayer.IsBattleState():
#        PlayerControl.NotifyCode(curPlayer, "CannotAtk09")
#        return
#
#    #开始传送
#    curPlayer.GameServer_QueryPlayerByID(ChConfig.queryType_sqtTruck, curPlayer.GetTruckID(), 'MoveToTruck', '', 0)
#===============================================================================
    return
#---------------------------------------------------------------------
#===============================================================================
# //03 15 开始远程鉴定#tagCRemoteIdentify
# tagCRemoteIdentify       *   GettagCRemoteIdentify();
#
# class   IPY_CRemoteIdentify
# {
# public:
#    //无意义
#    int      GetType();
# };
#===============================================================================
##客户端封包响应 //03 15 开始远程鉴定#tagCRemoteIdentify
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 15 开始远程鉴定#tagCRemoteIdentify
def FarIdentify(index, tick):
    #关闭此功能
    return
#---------------------------------------------------------------------
#===============================================================================
# //03 16 得到副本状态#tagCGetFBState
# tagCGetFBState       *   GettagCGetFBState();
#
# class   IPY_CGetFBState
# {
# public:
#    //无意义
#    int      GetType();
# };
#===============================================================================
##客户端封包响应//03 16 得到副本状态#tagCGetFBState
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应//03 16 得到副本状态#tagCGetFBState
def GetFBState(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    if tick - curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_FBState) < ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_FBState]:
        #查询过于频繁
        return
    curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_FBState, tick)
    if GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtNull:
        #普通地图不查询
        return
    FBLogic.DoGetFBState(curPlayer , tick)
    return
#---------------------------------------------------------------------
#===============================================================================
# //03 19 副本帮助界面#tagCFbHelp
# tagCFbHelp       *   GettagCFbHelp();
#
# class   IPY_CFbHelp
# {
# public:
#    //无意义
#    int      GetType();
# };
#===============================================================================
##客户端封包响应 //03 19 副本帮助界面#tagCFbHelp
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 19 副本帮助界面#tagCFbHelp
#副本帮助界面
def FBHelp(index , tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    if not curPlayer.GetMapLoadOK():
        #玩家未登陆成功副本不处理
        return
    if tick - curPlayer.GetTickByType(ChConfig.TYPE_Player_Tick_FBHelp) < ChConfig.TYPE_Player_Tick_Time[ChConfig.TYPE_Player_Tick_FBHelp]:
        #查询过于频繁
        return
    curPlayer.SetTickByType(ChConfig.TYPE_Player_Tick_FBHelp, tick)
#    if GameWorld.GetMap().GetMapFBType() == IPY_GameWorld.fbtNull:
#        #普通地图不查询
#        return
    FBLogic.DoFBHelp(curPlayer , tick)
    return
#---------------------------------------------------------------------
#---------------------------------------------------------------------
#// C1 05 进入跨服地图 #tagCMEnterCrossServer
@@ -4865,186 +3172,6 @@
    mapID = sendPack.GetMapID()
    clientSendLineID = sendPack.GetLineID()
    PlayerControl.PlayerEnterFB(curPlayer, mapID, clientSendLineID)
    return
#---------------------------------------------------------------------
#===============================================================================
#//07 24 定点传送#tagCDingDianTransport
#tagHead        Head;
#BYTE        ItemIndex;
#WORD        TransportIndex;
## 定点传送
#  @param index 玩家索引
#  @param tick 当前时间
#  @return None
#  @remarks 函数详细说明.
def PointTransport(index, tick):
#===============================================================================
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
# #    if not GameWorld.SetPlayerTickTime(curPlayer, ChConfig.TYPE_Player_Tick_WorldTransport, tick):
# #        #间隔未到
# #        return
#    sendPack = IPY_GameWorld.IPY_CDingDianTransport()
#    lineID = sendPack.GetItemIndex()        #本项目用来指定传送的目标线路, -1为默认
#    sendPack_TransportIndex = sendPack.GetTransportIndex()   #传送点索引
#    lineID = lineID if lineID > 0 else -1
#
#    if not PlayerControl.CheckPlayerTransport(curPlayer):
#        #玩家当前状态不可传送
#        return
#    PointTransportList = ReadChConfig.GetEvalChConfig('PointTransport')
#    PointCount = len(PointTransportList)
#    #索引错误
#    if sendPack_TransportIndex < 0 or sendPack_TransportIndex >= PointCount:
#        return
#    curPointDict = PointTransportList[sendPack_TransportIndex]
#
#    mapID = curPointDict["MapID"]
#    lvLimit = curPointDict["LVLimit"]
#    posX = curPointDict["PosX"]
#    posY = curPointDict["PosY"]
#    money = curPointDict["Money"]
#    moneyType = curPointDict["MoneyType"]
#
#    #职业限制
#    if lvLimit > curPlayer.GetLV():
#        #对不起,该场景需要XX级才能进入!
#        PlayerControl.NotifyCode(curPlayer, "Carry_hwj35_0", [lvLimit])
#        return
#    #金钱限制
#    if not PlayerControl.HaveMoneyEx(curPlayer, moneyType, money):
#        return
#    #目标地图判断(存在否,敌国,副本)
#    if not PlayerControl.CheckTagCountry(curPlayer, mapID):
#        return
#
#    #坐标点判断
#    posX, posY = GetTransportPos(curPlayer, 0, mapID, posX, posY)
#    if (posX, posY) == (0, 0):
#        #04BBF813-7A30-47A8-927DE1ACCC4F378E 目标点为障碍点
#        PlayerControl.NotifyCode(curPlayer, "04BBF813-7A30-47A8-927DE1ACCC4F378E")
#        return
#
#    if BeginTrans(curPlayer, mapID, posX, posY, lineID=lineID):
#        curPlayer.SetDict(ChConfig.Def_PlayerKey_TransMoney, money)
#        curPlayer.SetDict(ChConfig.Def_PlayerKey_TransMoneyType, moneyType)
#        curPlayer.SetDict(ChConfig.Def_PlayerKey_TransType, ChConfig.Def_Transport_Type_FixedPoint)
#    else:
#        #没有进度条,直接扣取
#        infoDict = {ChConfig.Def_Cost_Reason_SonKey:mapID}
#        PlayerControl.PayMoney(curPlayer, moneyType, money, ChConfig.Def_Cost_Transport, infoDict)
#
#===============================================================================
    #PlayerControl.PlayerResetWorldPos(curPlayer, MapID, PosX, PosY, False)
    #PlayerControl.NotifyCode(curPlayer, "Map_Deliver_Succeed", [MapID])
    return
#===============================================================================
# #  04 04 好友传送 #tagCFriendTransport
# #
# #struct    tagCFriendTransport
# #{
# #    tagHead        Head;
# #    DWORD        FriendID;
# #    Byte         ExtField1;
# #};
#===============================================================================
##客户端封包响应 04 04 好友传送 #tagCFriendTransport
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 04 04 好友传送 #tagCFriendTransport
def FriendTransPort(index, tick):
    return
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#
#    if not GameWorld.SetPlayerTickTime(curPlayer, ChConfig.TYPE_Player_Tick_FlyToFriend, tick):
#        #间隔未到
#        return
#
#    sendPack = IPY_GameWorld.IPY_CFriendTransport()
#    sendPack_FriendID = sendPack.GetFriendID()
#    sendPack_IsAutoBuy = sendPack.GetExtField1()
#
#    if not curPlayer.FindFriend(sendPack_FriendID):
#        #确认好友失败
#        return
#
#    if not PlayerControl.CheckPlayerTransport(curPlayer):
#        #玩家当前状态不可传送
#        return
#
#    type = ChConfig.Def_Transport_Type_Friend
#    if not TransportVipLvRestrict(curPlayer, type):
#        #vip等级限制
#        return
#
#    transportPayDict = ReadChConfig.GetEvalChConfig('TransportPay')
#    payInfo = transportPayDict.get(type)
#
#    if payInfo == None:
#        GameWorld.ErrLog("表TransportPay信息错误 没有对应类型 %s" % (type))
#        return
#
#
#    #物品ID, 物品效果值, 付费类型,金额
#    itemID, itemEffectID, moneyType, money = payInfo
#
#    #通知消费方式
#    sendPayType = ChConfig.Def_FriendTransPort_UseItem
#    #使用道具传送
#    useItem = ItemCommon.FindItemInPackByEffectEx(curPlayer, itemEffectID)
#
#    #没有物品
#    if useItem == None:
#        if sendPack_IsAutoBuy:
#            #没有钱
#            if not PlayerControl.HaveMoneyEx(curPlayer, moneyType, money):
#                return
#
#            #金钱消费
#            sendPayType = ChConfig.Def_FriendTransPort_UseMoney
#        else:
#            #物品不足
#            PlayerControl.NotifyCode(curPlayer, "GeRen_pan_861048", [itemID])
#            return
#
#    sendMsg = '%s' % (sendPayType)
#
#    #查询并传送
#    curPlayer.GameServer_QueryPlayerByID(ChConfig.queryType_sqtPlayer, sendPack_FriendID,
#                             'FlytoFriendByID', sendMsg, len(sendMsg))
#---------------------------------------------------------------------
#===============================================================================
#04 05 世界传送tagCWorldTransfer
#
# struct    tagCWorldTransfer
# {
#    tagHead        Head;
#    DWORD        MapID;
#    WORD        PosX;
#    WORD        posY;
#    BYTE        ExtField1;
# };
#===============================================================================
##
##客户端封包响应 04 05 世界传送tagCWorldTransfer
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 04 05 世界传送tagCWorldTransfer
def WorldTransPort(index, tick):
    #---获取封包信息---
    packUseItem = IPY_GameWorld.IPY_CWorldTransfer()
    packTransportType = packUseItem.GetType()
    mapID = packUseItem.GetMapID()
    posX = packUseItem.GetPosX()
    posY = packUseItem.GetPosY()
    lineID = packUseItem.GetExtField1()
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    __Func_WorldTransPort(curPlayer, packTransportType, mapID, posX, posY, tick, lineID)
    return
#// B0 05 开始世界传送 #tagCMWorldTransfer
@@ -5131,12 +3258,11 @@
# @param mapID 地图ID
# @param posX 坐标X
# @param posY 坐标Y
# @param takeTruck 是否携带镖车
# @param lineID 线路ID -1代表当前线
# @param msg 切换地图携带的信息
# @param canLock 是否可以锁定玩家(传送点不可锁定, 因为要跨地图寻路)
#  @return: 是否在拉进度条
def BeginTrans(curPlayer, mapID, posX, posY, takeTruck=False, lineID= -1, msg='', canLock=True, exData1=0):
def BeginTrans(curPlayer, mapID, posX, posY, lineID= -1, msg='', canLock=True, exData1=0):
    #===========================================================================
    # if PlayerControl.IsPlayerInFight(curPlayer):
    #    #记录传送坐标, 用于进度条结束后传送
@@ -5150,7 +3276,7 @@
    #    return True
    #===========================================================================
    
    PlayerControl.PlayerResetWorldPos(curPlayer, mapID, posX, posY, takeTruck, lineID, msg, canLock, exData1)
    PlayerControl.PlayerResetWorldPos(curPlayer, mapID, posX, posY, lineID, msg, canLock, exData1)
    #PlayerControl.NotifyCode(curPlayer, "Map_Deliver_Succeed", [mapID])
    return False
@@ -5201,7 +3327,7 @@
    if not hasEnough:
        #道具不够默认扣钱
        costMoney = IpyGameDataPY.GetFuncCfg('TransportPay', 2)
        if not TransportPayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Paper, costMoney, transportType, ChConfig.GMTool_Offline_WorldTransfer):
        if not TransportPayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Paper, costMoney, transportType):
            GameWorld.DebugLog('    传送消耗处理 传送道具不足 itemID=%s, 钱也不够costMoney=%s'%(itemID, costMoney))
            return False
    else:
@@ -5227,7 +3353,7 @@
#@param noteMark 记录类型
#@return 返回值真, 扣费成功
#@remarks 传送付费记录
def TransportPayMoney(curPlayer, moneyType, money, transportType, noteMark):
def TransportPayMoney(curPlayer, moneyType, money, transportType):
    moneyList = PlayerControl.HaveMoneyEx(curPlayer, moneyType, money)
    if moneyList == []:
        return False
@@ -5240,75 +3366,6 @@
                                              moneyType, money)
        
    return True
#//03 26 手动升级#tagCUserLVUp
#////////////////////////////////////////////////////////////////
#
#class       IPY_CUserLVUp
#{
#private:
#    CUserLVUp      *           m_Instance;
#public:
#    //初始化
#    IPY_CUserLVUp();
#----------------------------
##客户端封包响应 //03 26 玩家升级请求#tagCUserLVUp
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 03 26 玩家升级请求#tagCUserLVUp
def PlayerLvUpRequest(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    #---开始升级---
    playerControl = PlayerControl.PlayerControl(curPlayer)
    #参数填True表示手动升级 在人物达到20级以后会调用一次人物会升一级
    playerControl.PlayerLvUp(True)
    return
#---------------------------------------------------------------------
#===============================================================================
# //03 2B 双倍经验激活/停止/查询#tagCDoubleExp
#
# struct    tagCDoubleExp
# {
#    tagHead        Head;
#    BYTE        Type;        //1-激活;2-停止;3-查询
#
# };
#===============================================================================
##客户端封包响应 //03 2B 双倍经验激活/停止/查询#tagCDoubleExp
#@param index 玩家索引
#@param tick 时间戳
#@return 返回值无意义
#@remarks 客户端封包响应 //03 2B 双倍经验激活/停止/查询#tagCDoubleExp
def DoubleExpState(index, tick):
    return
## 03 31 副本玩家激活特殊技能
#  @param index 玩家索引
#  @param tick 时间戳
#  @return 无返回值
#  @remarks 副本玩家激活特殊技能
def UseFBSpecilSkill(index, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    fbSkillPack = IPY_GameWorld.IPY_CFBSpecilSkill()
    useType = fbSkillPack.GetType()
    useState = fbSkillPack.GetState()
    FBLogic.UseFBSpecilSkill(curPlayer, useType, useState, tick)
#---------------------------------------------------------------------
#===============================================================================
#//A2 05 请求兑换离线经验封包#tagPyCMOfflineExpExchange
#struct tagPyCMOfflineExpExchange
#{
#    tagHead    Head;
#    BYTE    Index;   //经验倍率索引
#    DWORD    ExchangeTime;   //兑换时间
#};
#===============================================================================
##//A2 05 请求兑换离线经验封包#tagPyCMOfflineExpExchange
@@ -5391,63 +3448,6 @@
    curPlayer.Syn_OfflineTimeQueryResult() # 通知客服端离线时间
    return
#------------------------------------------------------------------------------
## //A0 09 购买大地图标记点# tagPyBuyMapSignPoint
#  @param index 玩家索引
#  @param curPackData 封包结构体
#  @param tick 时间戳
#  @return None
def BuyMapSignCount(index, curPackData, tick):
#    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
#    curVipLv = curPlayer.GetVIPLv()
#
#    curMapsignCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_PlayerMapSignCnt)
#
#    #if curMapsignCnt >= min(PlayerVip.GetVipCanBuyTransportPointCnt(curVipLv), ChConfig.Def_Player_MapSignPointMaxCount):
#    #    #已经全部开通或当前vip等级只能买这么多
#    #    return
#    if curMapsignCnt >= ChConfig.Def_Player_MapSignPointMaxCount:
#        #已经全部开通或当前vip等级只能买这么多
#        return
#
#    buyCountIndex = curMapsignCnt + 1
#    buyMoneyCostDict = ReadChConfig.GetEvalChConfig("MapSignCountBuyMoney")
#    buyMoneyList = buyMoneyCostDict.get(buyCountIndex)
#    if buyMoneyList == None:
#        GameWorld.ErrLog("购买大地图标识位置 = %s 在MapSignCountBuyMoney.txt表中找不到购买价格" % buyCountIndex)
#        return
#
#    buyMoney = buyMoneyList[0]  # 金钱数量
#    buyMoneyType = buyMoneyList[1]  # 金钱类型
#
#    #扣钱
#    moneyList = PlayerControl.HaveMoneyEx(curPlayer, buyMoneyType, buyMoney)
#    if moneyList == []:
#        #金钱不足
#        return
#
#    for moneyType, moneyCount in moneyList:
#        PlayerControl.PayMoney(curPlayer, moneyType, moneyCount, 'BuyMapSignCount')
#
#    curMapsignCnt = PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_Player_Dict_PlayerMapSignCnt, buyCountIndex)
#
#    #通知客户端数量
#    OnSendMapSignCnt(curPlayer)
    return
## 通知大地图标记数量
#  @param curPlayer 玩家实例
#  @return None
def OnSendMapSignCnt(curPlayer):
#    curMapsignCnt = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_PlayerMapSignCnt)
#    mapsignCnt = ChConfig.Def_Player_InitMapSignPointCount + curMapsignCnt
#
#    mapSignPointCount = ChPyNetSendPack.tagPyMapSignPointCount()
#    mapSignPointCount.Count = mapsignCnt
#    NetPackCommon.SendFakePack(curPlayer, mapSignPointCount)
    return
#//B0 24 领取家族悬赏奖励 #tagReceiveFamilyArrestAward
#
@@ -5523,28 +3523,6 @@
    awardReceiveState.ReceiveState = state
    NetPackCommon.SendFakePack(curPlayer, awardReceiveState)
    return
## 查询是否还在家族的申请列表中(不在线时被拒绝了)
#  @param curPlayer: 玩家实例
#  @return: None
def QueryIsResFamily(curPlayer):
    familyIDList = []
    for index in range(0, ChConfig.Def_Player_RequestAddFamilyMaxCnt):
        familyID = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_RequestAddFamilyID % index)
        if familyID == 0:
            continue
        familyIDList.append(familyID)
    #向GameServer请求是否还在该家族申请列表中
    sendMsg = str(familyIDList)
    curPlayer.GameServer_QueryPlayerByID(ChConfig.queryType_RequestIsFamily, curPlayer.GetID(),
                                         'RequestIsFamily', sendMsg, len(sendMsg))
    return
#===============================================================================
## 领取奖励表奖励
#  @param None None
@@ -5740,9 +3718,6 @@
    #自定义奖励
    elif rewardType == ChConfig.Def_RewardType_CustomAward:
        PlayerCustomAward.OnGetCustomAward(curPlayer, dataEx)
    #境界修仙之路奖励
    elif rewardType == ChConfig.Def_RewardType_RealmXXZL:
        PlayerPrestigeSys.GetXXZLAward(curPlayer, dataEx)
    #境界渡劫任务条件奖励
    elif rewardType == ChConfig.Def_RewardType_RealmLVUpTask:
        PlayerPrestigeSys.GetRealmLVUpTaskAward(curPlayer, dataEx)
@@ -5752,6 +3727,9 @@
    #打包直购礼包奖励
    elif rewardType == ChConfig.Def_RewardType_DailyPackBuyGift:
        PlayerGoldGift.GetDailyPackBuyGift(curPlayer, dataEx)
    #任务奖励
    elif rewardType == ChConfig.Def_RewardType_Task:
        PlayerTask.GetTaskAward(curPlayer, dataEx)
    #战令奖励
    elif rewardType == ChConfig.Def_RewardType_Zhanling:
        PlayerZhanling.GetZhanlingReward(curPlayer, dataEx, dataExStr)
@@ -6236,10 +4214,6 @@
        #                   % (dist, distSum, speed, needTick, passCalcTick, checkNeedTick), curPlayer.GetID())
        curPlayer.SetDict(MoveDistCalcTick, tick)
        curPlayer.SetDict(MoveDistSum, 0)
    #如果是小游戏中则停止小游戏
    if curPlayer.GetPlayerAction() == IPY_GameWorld.paGameEvent:
        PlayerGameEvent.StopGameEvent(curPlayer, tick)
        
    #2010/04/30 移动修改为全C++控制, Python状态机设置为空闲(清空采集等状态)
    PlayerControl.ChangePlayerAction(curPlayer, IPY_GameWorld.paNull)