hxp
3 天以前 71685e76b8f23242fd3e5ec2a1c934579efafb96
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/EventReport.py
@@ -32,61 +32,17 @@
#"""Version = 2017-07-04 15:00"""
#---------------------------------------------------------------------
import IpyGameDataPY
import IPY_GameWorld
import DataRecordPack
import ChConfig
import TurnAttack
import PlayerControl
import IpyGameDataPY
import ReadChConfig
import ShareDefine
import GameWorld
import ChConfig
import CommFunc
import datetime
import random
import time
import md5
import os
import re
import json
import urllib
EventFilepath = "D:\\EventServer\\PythonScribe\\EventLog\\"
g_wFileName = ""
g_writeHandle = None  # 不可直接调用
Def_Custom_Events_Bug = "Bug" # 游戏Bug
Def_Custom_Events_Suggest = "suggest" # 游戏建议
Def_Custom_Events_Item = "Item" # 物品跟踪
Def_Custom_Events_GetMail = "GetMail" # 邮件领取
Def_Custom_Events_CommonCard = "CommonCard_%s" # 通用新手卡码使用, 参数为通用码卡号
Def_Custom_Events_NewbieCard = "NewbieCard_%s" # 常规新手卡使用, 参数为礼包类型
Def_Custom_Events_MediaCard = "MediaCard_%s" # 新媒体卡使用, 参数为卡类型
g_whStartTime = 0     # 创建文件时间
Def_WriteTime = 2   # 文件持续写入时间:分钟
def OnTimeCloseScribeTxt():
    global g_whStartTime
    global g_writeHandle
    global g_wFileName
    try:
        if g_whStartTime == 0:
            return
        #文件创建超过
        if time.time() - g_whStartTime < 60*(Def_WriteTime + 1):
            return
        if g_writeHandle == None:
            return
        g_writeHandle.close()
        g_wFileName = ""
        g_whStartTime = 0
    except:
        GameWorld.ErrLog("OnTimeCloseScribeTxt 出错")
import json
## 初始化事件
#  @param None
@@ -119,29 +75,37 @@
    
    if not curPlayer and not OperatorID:
        return
    ProductID = ReadChConfig.GetPyMongoConfig("EventReport", "ProductID")
    ReportUrl = ReadChConfig.GetPyMongoConfig("EventReport", "ReportUrl")
    
    playerInfo = ""
    if curPlayer:
        if not GameWorld.IsNormalPlayer(curPlayer):
            return
        #UTF8 需要转成url编码才可用
        playerInfo = urllib.urlencode({"RoleID": curPlayer.GetName(),
                          "AccountID": GameWorld.GetPlatformAccID(curPlayer.GetAccID()),
                          "IP": curPlayer.GetIP(),
                          "Level": curPlayer.GetLV(),
                          "DeviceFlag": curPlayer.GetAccountData().GetDeviceFlag(),
                          "Job": curPlayer.GetJob(),
                          "PlayerID": curPlayer.GetPlayerID(),
                          "CreateRoleTime": curPlayer.GetCreateRoleTime(),
                          })
        playerInfo = {"RoleID": curPlayer.GetName(),
                      "AccountID": GameWorld.GetPlatformAccID(curPlayer.GetAccID()),
                      "IP": curPlayer.GetIP(),
                      "Level": curPlayer.GetLV(),
                      "DeviceFlag": curPlayer.GetAccountData().GetDeviceFlag(),
                      "Job": curPlayer.GetJob(),
                      "PlayerID": curPlayer.GetPlayerID(),
                      "CreateRoleTime": curPlayer.GetCreateRoleTime(),
                      "CTGRealTotal": curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_CTGRealTotal),
                      "FightPower": PlayerControl.GetFightPower(curPlayer),
                      "MainTaskID": PlayerControl.GetMainTaskID(curPlayer),
                      "MainPassLVID": PlayerControl.GetPassMainLevelID(curPlayer),
                      "FamilyName": curPlayer.GetFamilyName(),
                      "ReamlLV":curPlayer.GetOfficialRank(),
                      "TreeLV":curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TreeLV),
                      "LineupHero":GetReportMainLineupInfo(curPlayer),
                      }
        for mapID in ChConfig.ReportCenterMapIDList:
            playerInfo["FBPass%s" % mapID] = curPlayer.NomalDictGetProperty(ChConfig.Def_Player_Dict_FBPassLineID % mapID)
        OperatorID = GameWorld.GetPlayerPlatform(curPlayer)
        RegionName = GameWorld.GetPlayerServerSID(curPlayer)
        playerInfo = "&%s"%playerInfo
        playerInfo = "&%s" % urllib.urlencode(playerInfo) #UTF8 需要转成url编码才可用
        
    else:
        # 合服情况,玩家取自己服发送,非玩家数据按指定平台配置发
@@ -164,429 +128,38 @@
    GameWorld.GetGameWorld().EventReport_EventReport("", "", "", "", 0, getUrl)
    return
## 写事件报告文件
#  @param eventClass
#  @return None
def WriteEvent(eventClass):
    return
    if GameWorld.IsCrossServer():
        return
def GetReportMainLineupInfo(curPlayer):
    lineup = TurnAttack.GetPlayerLineup(curPlayer, ShareDefine.Lineup_Main)
    if lineup.IsEmpty():
        return {}
    
    if eventClass.GetScribeEventName() not in ReadChConfig.GetEvalChConfig("EventReportID"):
        return
    if not os.path.isdir(EventFilepath):
        os.makedirs(EventFilepath)
    #尝试写到同一个文件但是window 会有bug,只能各自程序分开写入
    fp_w = GetWriteIO()
    fp_w.write("%s\t%s\n"%(eventClass.GetScribeEventName(), eventClass.GetCurEventStr()))
    fp_w.flush()
    return
# 分钟准点校准
def FixTime():
    curTime = datetime.datetime.today()
    curTime = curTime + datetime.timedelta(minutes=Def_WriteTime-curTime.minute%Def_WriteTime)
    tmp = str(curTime).split(".")[0][:-3].replace(':', '-')
    return tmp.replace(" ", "_")
def GetLogFileName(fileStr):
    sessionid = md5.md5(str(random.random()) + str(time.time())).hexdigest()
    return EventFilepath + sessionid + fileStr + '.log'
def GetWriteIO():
    global g_wFileName
    global g_writeHandle
    global g_whStartTime
    fileTime = FixTime()
    if g_wFileName and fileTime in g_wFileName:
        #当前文件直接返回
        return g_writeHandle
    curFileName = GetLogFileName(fileTime)
    if g_writeHandle != None:
        #关闭旧文件
        g_writeHandle.close()
    g_wFileName = curFileName
    g_writeHandle = open(g_wFileName, 'a+')
    g_whStartTime = time.time()
    return g_writeHandle
    heroDict = {}
    curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
    for posNum in lineup.GetPosNumList():
        hero = lineup.GetLineupHero(posNum)
        heroID = hero.heroID
        itemIndex = hero.itemIndex
        heroLV = 1
        star = 0
        if itemIndex >= 0 and itemIndex < curPack.GetCount():
            heroItem = curPack.GetAt(itemIndex)
            if heroItem and not heroItem.IsEmpty():
                heroLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroLV)
                star = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
                breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
                awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
        heroDict[str(posNum)] = {
                                 "HeroID":heroID,
                                 "SkinID":hero.skinID,
                                 "LV":heroLV,
                                 "Star":star,
                                 "BreakLV":breakLV,
                                 "AwakeLV":awakeLV,
                                 }
    return json.dumps(heroDict, ensure_ascii=False).replace(" ", "")
## =================================================================================================
# 每个字段都应该转为字符串,不然join会报错
class ScribeEvent(object):
    def __init__(self):
        #必须字段
        self.product_slug = 'yhlz'  # 游戏标志
        self.agent_name = ReadChConfig.GetPyMongoConfig("platform", "PlatformName") # 平台标志
        self.gameserver_no = ReadChConfig.GetPyMongoConfig("platform", "ServerID")[1:] # 区服
        self.time = ""    #GameWorld.GetCurrentDataTimeStr()
    def SetEventAgentInfo(self, accIDPlatform):
        # 设置代理运营商信息
        # @param accIDPlatform: 这里取账号所属平台,支持混服, 如果取不到,则用默认配置的运营商信息
        if not accIDPlatform:
            return
        self.agent_name = accIDPlatform
        self.gameserver_no = str(GameWorld.GetPlayerMainServerID(self.agent_name))
        return
    
    #即使是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
    #避免修改格式的情况,这里统一修改即可
    def GetEventStr(self, tmpList):
        return '\"%s\"'%'","'.join(tmpList)
# 3.3.1. entry(新玩家导入)
class entry(ScribeEvent):
    Def_EntryStep_CreatRole = 3
    Def_EntryStep_FirstLogin = 4
    def __init__(self):
        #必须字段
        super(entry, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.step = 0 # 步骤值
        #非必须字段
        self.ip = "" # IP 地址
        self.account_name = "" # 账号登录名
        self.account_type = 0 # 账号类型
        self.browser = "" # 玩家使用的浏览器
        self.resolution = "" # 玩家的桌面分辨率,格式为「宽*高」
        self.os = "" # 玩家使用的操作系统
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        tmpList = [self.product_slug, self.agent_name, self.ip, self.gameserver_no, self.account_id, self.account_name,
                   str(self.account_type), self.browser, self.resolution, self.os, str(self.step)]
        return super(entry, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_CreateRole
# 3.3.2. login(登录)
class login(ScribeEvent):
    def __init__(self):
        #必须字段
        super(login, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.session_id = "" # 会话ID
        #非必须字段
        self.ip = "" # IP 地址
        self.account_name = "" # 账号登录名
        self.account_type = 0 # 账号类型
        self.browser = "" # 玩家使用的浏览器
        self.resolution = "" # 玩家的桌面分辨率,格式为「宽*高」
        self.os = "" # 玩家使用的操作系统
        self.chr_name = "" # 玩家角色名
        self.chr_level = 0 # 玩家角色等级
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.ip, self.gameserver_no, self.account_id, self.account_name,
                   str(self.account_type), self.browser, self.resolution, self.os, self.time, self.chr_name,
                   str(self.chr_level), self.session_id]
        return super(login, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_Login
# 3.3.3. session(会话记录)
# 玩家登出、离线的数据,配合登录数据数据中心可统计出玩家在线时长
class session(ScribeEvent):
    def __init__(self):
        #必须字段
        super(session, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.session_id = "" # 会话ID
        #非必须字段
        self.ip = "" # IP 地址
        self.account_name = "" # 账号登录名
        self.account_type = 0 # 账号类型
        self.chr_name = "" # 玩家角色名
        self.chr_level = 0 # 玩家角色等级
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.ip, self.gameserver_no, self.account_id, self.account_name,
                   str(self.account_type), self.time, self.chr_name, str(self.chr_level), self.session_id]
        return super(session, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_Session
# 3.3.5. virtual‐cost(虚拟币消费)
# 玩家产生消费记录即收集;
class virtual_cost(ScribeEvent):
    def __init__(self):
        #必须字段
        super(virtual_cost, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.quantity = 0 # 消费数量
        self.price = 0 # 消费点的虚拟币单价
        self.reason_name = "" # 消费点名称
        #非必须字段
        self.ip = "" # IP 地址
        self.account_name = "" # 账号登录名
        self.account_type = 0 # 账号类型
        self.chr_name = "" # 玩家角色名
        self.chr_level = 0 # 玩家角色等级
        self.balance = 0 # 玩家剩余虚拟币
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.ip, self.gameserver_no, self.account_id, self.account_name,
                   str(self.account_type), self.time, self.chr_name, str(self.chr_level), str(self.quantity),
                   str(self.price), str(self.balance), self.reason_name]
        return super(virtual_cost, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_VirtualCost
# 3.3.6. virtual‐reward(虚拟币赠送)
# 玩家获得虚拟币赠送时即收集;
# 除了真实充值订单产生的虚拟币增加都应该计入到虚拟币赠送
class virtual_reward(ScribeEvent):
    def __init__(self):
        #必须字段
        super(virtual_reward, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.virtual_amount = 0 # 增加的虚拟币数量
        #非必须字段
        self.ip = "" # IP 地址
        self.account_name = "" # 账号登录名
        self.account_type = 0 # 账号类型
        self.chr_name = "" # 玩家角色名
        self.chr_level = 0 # 玩家角色等级
        self.balance = 0 # 玩家剩余虚拟币
        self.source = "" # 获得奖励的途径
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.ip, self.gameserver_no, self.account_id, self.account_name,
                   str(self.account_type), self.time, self.chr_name, str(self.chr_level), str(self.virtual_amount),
                   str(self.balance), self.source]
        return super(virtual_reward, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_VirtualReward
# 3.3.12. virtual‐resource(虚拟资源产出与消耗)
# 产生相应虚拟资源的消费、生产记录时即收集。
# 用于统计任何虚拟资源如各类二级货币的产出与消耗
class virtual_resource(ScribeEvent):
    def __init__(self):
        #必须字段
        super(virtual_resource, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.type_name = "" # 虚拟资源类型名称
        self.reason_name = "" # 资源点名称
        self.quantity = 0 # 虚拟资源产出/消耗的次数
        self.price = 0 # 虚拟资源产出/消耗的数量,区分正负,正值为产出,负值为消耗
        #非必须字段
        self.ip = "" # IP 地址
        self.account_name = "" # 账号登录名
        self.account_type = 0 # 账号类型
        self.chr_name = "" # 玩家角色名
        self.chr_level = 0 # 玩家角色等级
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.ip, self.gameserver_no, self.account_id, self.account_name,
                   str(self.account_type), self.time, self.chr_name, str(self.chr_level), self.type_name,
                   self.reason_name, str(self.quantity), str(self.price)]
        return super(virtual_resource, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_VirtualResource
# 3.3.9. custom‐events(自定义事件)
# 用于统计任何期望去跟踪的数据
class custom_events(ScribeEvent):
    def __init__(self):
        #必须字段
        super(custom_events, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.event_name = "" # 事件名称
        self.session_id = "" # 会话ID
        #非必须字段
        self.ip = "" # IP 地址
        self.account_name = "" # 账号登录名
        self.account_type = 0 # 账号类型
        self.chr_name = "" # 玩家角色名
        self.chr_level = 0 # 玩家角色等级
        self.comments = "" # 备注或附加信息 char(255)
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.ip, self.gameserver_no, self.account_id, self.account_name,
                   str(self.account_type), self.time, self.chr_name, str(self.chr_level), self.event_name,
                   self.comments, self.session_id]
        return super(custom_events, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_CustomEvents
# 3.3.10. mission‐log(任务记录)
# 跟踪玩家任务接取、完成、失败情况,以及用于流失玩家的任务分析等统计。
# 任务接取时即收集 type=0 的数据,任务结束且成功时即收集 type=1、mission_result=1 的数据,任务结束且失败时即收集 type=1、mission_result=0 的数据。
class missionlog(ScribeEvent):
    def __init__(self):
        #必须字段
        super(missionlog, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_level = 0 # 玩家角色等级
        self.type = 0 # 0 任务开始 1 任务结束
        self.mission_name = "" # 任务名
        self.session_id = "" # 会话ID
        #非必须字段
        self.ip = "" # IP 地址
        self.account_name = "" # 账号登录名
        self.account_type = 0 # 账号类型
        self.chr_name = "" # 玩家角色名
        self.mission_result = 0 # 当任务结束,任务结果 0:失败 1:成功
        self.mission_reason = "" # 当任务结束且任务失败时的原因
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        self.scribeEventName = ShareDefine.Def_UserAction_MissionLog
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.ip, self.gameserver_no, self.account_id, self.account_name,
                   str(self.account_type), self.time, self.chr_name, str(self.chr_level), str(self.type), self.mission_name,
                   str(self.mission_result), self.mission_reason, self.session_id]
        return super(missionlog, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return self.scribeEventName
# 3.3.11. level‐up(升级记录)
# 用于玩家升级时长等等级相关统计。
# 等级发生变化时即收集;
# 要统计 2 级的升级时长必须要有 1 级的升级数据,因此刚创建完角色时的 1 级的数据也需要收集。
class levelup(ScribeEvent):
    def __init__(self):
        #必须字段
        super(levelup, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_level = 0 # 玩家角色等级
        self.session_id = "" # 会话ID
        #非必须字段
        self.ip = "" # IP 地址
        self.account_name = "" # 账号登录名
        self.account_type = 0 # 账号类型
        self.chr_name = "" # 玩家角色名
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.ip, self.gameserver_no, self.account_id, self.account_name,
                   str(self.account_type), self.time, self.chr_name, str(self.chr_level), self.session_id]
        return super(levelup, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_LVUP
# 3.3.13. chat-log (聊天消息)
# 用于监控玩家聊天
class chat_log(ScribeEvent):
    def __init__(self):
        #必须字段
        super(chat_log, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.content = "" # 聊天内容
        self.cmc_name = "" # 聊天频道标识
        #非必须字段
        self.ip = "" # IP 地址
        self.account_name = "" # 账号登录名
        self.account_type = 0 # 账号类型
        self.chr_level = 0 # 玩家角色等级
        self.object = "" # 私聊对象
        self.addinfo = "" # 额外信息
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.ip, self.gameserver_no, self.account_id, self.account_name,
                   str(self.account_type), self.time, self.chr_name, str(self.chr_level), self.object, self.content,
                   self.addinfo, self.cmc_name]
        return super(chat_log, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_ChatLog
## =================================================================================================
#===============================================================================
# def WriteEvent_entry_firstlogin(curPlayer, browser, resolution, pcOS):
#    entryEvent = entry()
#    entryEvent.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
#    entryEvent.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
#    entryEvent.step = entryEvent.Def_EntryStep_FirstLogin
#    entryEvent.ip = curPlayer.GetIP()
#    entryEvent.account_name = entryEvent.account_id
#    entryEvent.account_type = GameWorld.GetAccountType(curPlayer)
#    entryEvent.browser = browser
#    entryEvent.resolution = resolution
#    entryEvent.os = pcOS
#    WriteEvent(entryEvent)
#    return
#===============================================================================
def WriteEvent_login(curPlayer):
    if curPlayer.GetIP() == "127.0.0.1":
        return
@@ -606,1085 +179,7 @@
        passTimes = GameWorld.GetDateTimeByStr(logoffTimeStr) - GameWorld.GetDateTimeByStr(loginTimeStr)
        seconds = passTimes.seconds
    EventReport(ShareDefine.Def_UserAction_Session, "OnlineTime=%s&SessionID=%s"%(seconds, GameWorld.GetSessionID(curPlayer)), curPlayer)
    #===========================================================================
    # sessionEvent = session()
    # sessionEvent.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # sessionEvent.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # sessionEvent.session_id = GameWorld.GetSessionID(curPlayer)
    # sessionEvent.ip = curPlayer.GetIP()
    # sessionEvent.account_name = sessionEvent.account_id
    # sessionEvent.account_type = GameWorld.GetAccountType(curPlayer)
    # sessionEvent.chr_name = curPlayer.GetPlayerName()
    # sessionEvent.chr_level = GetScribeEvent_chr_level(curPlayer)
    # WriteEvent(sessionEvent)
    #===========================================================================
    return
## 写虚拟元宝消费记录
#  @param quantity: 消费数量
#  @param price: 消费点的虚拟币单价
#  @param reason_name: 消费点名称
def WriteEvent_virtual_cost(curPlayer, quantity, price, reason_name):
    '''
     问:虚拟消费点的粒度几大好?
        答:数据报表对虚拟消费的统计支持两级,即消费点及其父类消费点分组,据此:
       ● 建议是消费途径加上消费对象,比如「商店购买:三尸脑神丹」,而后将该消费点在消费点分组里归为「商店购买」;
       ● 不要加上消费者如「叶孤寒:商店购买:三尸脑神丹」;
       ● 不要加上消费对象等级如「强化:柳叶刀 [9级]」。
    '''
    #===========================================================================
    # virtualCostEvent = virtual_cost()
    # virtualCostEvent.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # virtualCostEvent.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # virtualCostEvent.quantity = quantity
    # virtualCostEvent.price = price
    # virtualCostEvent.balance = curPlayer.GetGold()
    # virtualCostEvent.reason_name = reason_name
    # virtualCostEvent.ip = curPlayer.GetIP()
    # virtualCostEvent.account_name = virtualCostEvent.account_id
    # virtualCostEvent.account_type = GameWorld.GetAccountType(curPlayer)
    # virtualCostEvent.chr_name = curPlayer.GetPlayerName()
    # virtualCostEvent.chr_level = GetScribeEvent_chr_level(curPlayer)
    # WriteEvent(virtualCostEvent)
    #===========================================================================
    return
## 写虚拟元宝赠送获得记录,含充值可查到账兑换成虚拟币时间
#  @param virtual_reward: 增加的虚拟币数量
#  @param source: 获得奖励的途径
def WriteEvent_virtual_reward(curPlayer, virtual_amount, source):
    #===========================================================================
    # virtualRewardEvent = virtual_reward()
    # virtualRewardEvent.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # virtualRewardEvent.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # virtualRewardEvent.virtual_amount = virtual_amount
    # virtualRewardEvent.balance = curPlayer.GetGold()
    # virtualRewardEvent.source = source
    # virtualRewardEvent.ip = curPlayer.GetIP()
    # virtualRewardEvent.account_name = virtualRewardEvent.account_id
    # virtualRewardEvent.account_type = GameWorld.GetAccountType(curPlayer)
    # virtualRewardEvent.chr_name = curPlayer.GetPlayerName()
    # virtualRewardEvent.chr_level = GetScribeEvent_chr_level(curPlayer)
    # WriteEvent(virtualRewardEvent)
    #===========================================================================
    return
## 写二级货币的产出与消耗记录
#  @param type_name: 虚拟资源类型名称, 如金币
#  @param reason_name: 资源点名称, 如刷新荣誉商店
#  @param quantity: 虚拟资源产出/消耗的次数
#  @param price: 虚拟资源产出/消耗的数量单价,区分正负,正值为产出,负值为消耗
#  @param flow  0 代表消费  1 代表产出
def WriteEvent_virtual_resource(curPlayer, type_name, reason_name, quantity, price, flow, extraDict={}):
    #避免记录太多信息
    if type_name in [IPY_GameWorld.TYPE_Price_Silver_Money] and abs(quantity * price) < ChConfig.Def_DRRecord_Min_Silver:
        return
    if type_name not in IpyGameDataPY.GetFuncEvalCfg("EventReport", 2):
        #GameWorld.DebugLog("该货币类型不需要汇报! type_name=%s" % type_name)
        return
    # 标识此货币是否是一级货币(充值)
    Recharged = 1 if type_name == IPY_GameWorld.TYPE_Price_Gold_Money else 0
    #===========================================================================
    # virtualResourceEvent = virtual_resource()
    # virtualResourceEvent.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # virtualResourceEvent.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # virtualResourceEvent.type_name = str(type_name)
    # virtualResourceEvent.reason_name = reason_name
    # virtualResourceEvent.quantity = quantity
    # virtualResourceEvent.price = price
    # virtualResourceEvent.ip = curPlayer.GetIP()
    # virtualResourceEvent.account_name = virtualResourceEvent.account_id
    # virtualResourceEvent.account_type = GameWorld.GetAccountType(curPlayer)
    # virtualResourceEvent.chr_name = curPlayer.GetPlayerName()
    # virtualResourceEvent.chr_level = GetScribeEvent_chr_level(curPlayer)
    # WriteEvent(virtualResourceEvent)
    #===========================================================================
    # OperatorExtra json 格式 消费具体原因
    EventReport(ShareDefine.Def_UserAction_VirtualResource,
                "Price=%s&Quantity=%s&OperateType=%s&CurrencyType=%s&Recharged=%s&Flow=%s&Balance=%s&OperatorExtra=%s"%(
                price, quantity, reason_name, type_name, Recharged, flow,
                PlayerControl.GetMoneyReal(curPlayer, type_name), json.dumps(extraDict, ensure_ascii=False)), curPlayer)
    return
## 写任务事件记录
#  @param startType: 0 任务开始 1 任务结束
#  @param isFinish: 当任务结束,任务结果 0:失败 1:成功
#  @param failReason: 当任务结束且任务失败时的原因
def WriteEvent_mission_log(curPlayer, missionData, startType, isFinish=0, failReason=""):
    if startType not in [0, 1] or isFinish not in [0, 1]:
        return
    if not missionData:
        return
    #missionName = "0%s%s" % (missionData.ID, missionData.Name)
    missionName = missionData.ID
    __WriteEvent_mission_log(curPlayer, startType, missionName, isFinish, failReason)
    return
def WriteFuncCMEAcceptable(curPlayer, funcID):
    return
    if funcID not in ChConfig.FuncCMEDict:
        return
    WriteEvent_custom_mission_log(curPlayer, ChConfig.FuncCMEDict[funcID], ChConfig.CME_Log_Acceptable)
    return True
def WriteEvent_MWSuccess(curPlayer, mwID, succID, logType, isFinish=0):
    '''写自定义任务 - 法宝成就事件, 事件ID格式:  91+法宝ID+至少4位的成就ID
    '''
    cmeType = "91%d%04d" % (mwID, succID)
    WriteEvent_custom_mission_log(curPlayer, cmeType, logType, isFinish)
    return
def WriteEvent_FB(curPlayer, mapID, funcLineID, logType, joinType=0, isFinish=0, failReason=""):
    '''写自定义任务 - 副本事件, 事件ID格式: 90+mapID+joinType+funcLineID
    @param joinType: 0-默认无; 1-单人; 2-多人; 3-助战;   注意单人队伍算单人
    '''
    cmeType = "90%d%d%02d" % (mapID, joinType, funcLineID)
    WriteEvent_custom_mission_log(curPlayer, cmeType, logType, isFinish, failReason=failReason)
    return
## 写自定义任务事件记录
#  @param cmeType: 自定义类型, 对应 ChConfig.CME_Type_List
#  @param logType: 记录类型, 对应 ChConfig.CME_Log_Type_List
#  @param cmeInfoEx: 扩展自定义信息, 一般用于需要分子项记录的类型
#  @param isFinish: 当事件结束时结果 0:失败 1:成功
#  @param failReason: 当事件结束时失败的原因
def WriteEvent_custom_mission_log(curPlayer, cmeType, logType, isFinish=0, failReason="", cmeInfoEx=None):
    #if cmeType not in ChConfig.CME_Type_List:
    #    return
    if logType not in ChConfig.CME_Log_Type_List:
        return
    startType = 1 if logType == ChConfig.CME_Log_End else 0
    #===========================================================================
    # missionName = ChConfig.CME_Type_Dict.get(cmeType, "δ֪")
    # if cmeInfoEx != None:
    #    missionName = "%s:%s" % (missionName, cmeInfoEx)
    # if logType == ChConfig.CME_Log_Acceptable:
    #    missionName = "%s_可挑战" % missionName
    #===========================================================================
    missionName = cmeType
    __WriteEvent_mission_log(curPlayer, startType, missionName, isFinish, failReason, cmeType in ChConfig.CME_Ex_Log_List)
    return
## 写任务事件记录
#  @param startType: 0 任务开始 1 任务结束
#  @param missionName: 任务名
#  @param isFinish: 当任务结束,任务结果 0:失败 1:成功
#  @param failReason: 当任务结束且任务失败时的原因
def __WriteEvent_mission_log(curPlayer, startType, missionName, isFinish, failReason, isExLog=False):
    isFinish = 1 if isFinish else 0
    exDict = {"Fail":failReason}
    resultMsg = json.dumps(exDict, ensure_ascii=False)
    EventReport(ShareDefine.Def_UserAction_MissionLog,
                "MissionStep=%s&MissionID=%s&MissionResult=%s&MissionExtra=%s"%(startType, missionName, isFinish, resultMsg), curPlayer)
    #===========================================================================
    # missionlogEvent = missionlog()
    # missionlogEvent.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # missionlogEvent.scribeEventName = ShareDefine.Def_UserAction_ExMissionLog if isExLog else \
    #                                    ShareDefine.Def_UserAction_MissionLog
    # missionlogEvent.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # missionlogEvent.chr_level = GetScribeEvent_chr_level(curPlayer)
    # missionlogEvent.type = startType
    # missionlogEvent.mission_name = missionName
    # missionlogEvent.session_id = GameWorld.GetSessionID(curPlayer)
    #
    # missionlogEvent.ip = curPlayer.GetIP()
    # missionlogEvent.account_name = missionlogEvent.account_id
    # missionlogEvent.account_type = GameWorld.GetAccountType(curPlayer)
    # missionlogEvent.chr_name = curPlayer.GetPlayerName()
    # missionlogEvent.mission_result = isFinish
    # missionlogEvent.mission_reason = failReason
    # WriteEvent(missionlogEvent)
    #===========================================================================
    return
def WriteEvent_level_up(curPlayer):
    EventReport(ShareDefine.Def_UserAction_LVUP, "", curPlayer)
    #===========================================================================
    # levelupEvent = levelup()
    # levelupEvent.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # levelupEvent.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # levelupEvent.session_id = GameWorld.GetSessionID(curPlayer)
    # levelupEvent.ip = curPlayer.GetIP()
    # levelupEvent.account_name = levelupEvent.account_id
    # levelupEvent.account_type = GameWorld.GetAccountType(curPlayer)
    # levelupEvent.chr_name = curPlayer.GetPlayerName()
    # levelupEvent.chr_level = GetScribeEvent_chr_level(curPlayer)
    # WriteEvent(levelupEvent)
    #===========================================================================
    return
def WriteEvent_chat_log(curPlayer, content, cmc_name, tagName="", addinfo=""):
    return
    #===========================================================================
    # '''
    # @todo: 写聊天监控记录
    # @param content: 聊天内容
    # @param cmc_name: 聊天频道标识
    # @param tagName: 私聊对象
    # @param addinfo: 额外信息
    # '''
    # chatlogEvent = chat_log()
    # chatlogEvent.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # chatlogEvent.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # chatlogEvent.chr_name = curPlayer.GetName()
    # chatlogEvent.content = __GetEventChatContent(content)
    # chatlogEvent.cmc_name = cmc_name
    # chatlogEvent.ip = curPlayer.GetIP()
    # chatlogEvent.account_name = chatlogEvent.account_id
    # chatlogEvent.account_type = GameWorld.GetAccountType(curPlayer)
    # chatlogEvent.chr_level = GetScribeEvent_chr_level(curPlayer)
    # chatlogEvent.object = tagName
    # chatlogEvent.addinfo = addinfo
    # WriteEvent(chatlogEvent)
    #===========================================================================
    return
def __GetEventChatContent(content):
    '''
    <a color="255,255,0" href="GOTO 10000,74,60">[地图:暮光之城(74,60)]</a>
    <A color="205,0,0" onmouseover="ShowInfo ITEM,55986" DATA="07 04 01 00 B2 DA 00 00 00 01 00 01
        28 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 3C 00 00 00 7B 27 32 38 27 3A 5B
        27 31 30 32 33 34 27 5D 2C 27 31 39 27 3A 5B 27 33 35 34 27 2C 27 38 35 36 27 2C 27 33 35
        34 27 2C 27 37 35 38 27 2C 27 39 35 31 27 2C 27 31 30 35 32 27 5D 7D 04 00 00 00 00 00 00
        00 00 00 00 00 00 00 00 00 00 ">[神圣的傲世之弓 +40]</a>
    '''
    tempMatch = re.search("<a color=.*?>.*?</a>", content)
    if tempMatch:
        tempStr = tempMatch.group()
        markIndex = tempStr.index(">") + 1
        repStr = tempStr[markIndex:tempStr.index("<", markIndex)]
        content = content.replace(tempStr, repStr)
    tempMatch = re.search("<A color=.*?>.*?</a>", content)
    if tempMatch:
        tempStr = tempMatch.group()
        markIndex = tempStr.index(">") + 1
        repStr = tempStr[markIndex:tempStr.index("<", markIndex)]
        content = content.replace(tempStr, repStr)
    # 替换换行
    content = content.replace("\r", "")
    content = content.replace("\n", "")
    return content
## 写自定义事件记录
#  @param event_name: 事件名称
#  @param comments: 备注或附加信息
def WriteEvent_custom_events(curPlayer, event_name, comments):
    #===========================================================================
    # customEvent = custom_events()
    # customEvent.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # customEvent.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # customEvent.event_name = event_name
    # customEvent.session_id = GameWorld.GetSessionID(curPlayer)
    #
    # customEvent.ip = curPlayer.GetIP()
    # customEvent.account_name = customEvent.account_id
    # customEvent.account_type = GameWorld.GetAccountType(curPlayer)
    # customEvent.chr_name = curPlayer.GetPlayerName()
    # customEvent.chr_level = GetScribeEvent_chr_level(curPlayer)
    # customEvent.comments = CommFunc.GetStrCutoff(comments, 255)
    # WriteEvent(customEvent)
    #===========================================================================
    return
def GetScribeEvent_chr_level(curPlayer):
    transCnt, showLV = GameWorld.GetClientLV(curPlayer)
    return transCnt * 1000 + showLV
## -------------------------------------- 扩展自定义 ---------------------------------------
class horse_class(ScribeEvent):
    # 坐骑进阶记录
    def __init__(self):
        #必须字段
        super(horse_class, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.bef_class_lv = 0 # 此次进阶操作前的坐骑等阶, 0代表1阶
        self.bef_exp = 0 # 此次进阶操作前的坐骑等阶星数的经验值
        self.cost_item_cnt = 0 # 此次进阶消耗的进阶道具数量
        self.aft_class_lv = 0 # 此次进阶操作后的坐骑等阶, 0代表1阶
        self.aft_exp = 0 # 此次进阶操作后的坐骑等阶星数的经验值
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   str(self.bef_class_lv), str(self.bef_exp), str(self.cost_item_cnt),
                   str(self.aft_class_lv), str(self.aft_exp), self.time]
        return super(horse_class, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_HorseClass
def WriteEvent_horse_class(curPlayer, befClassLV, befExp, costCnt, aftClassLV, aftExp):
    ## 写坐骑进阶记录
    #===========================================================================
    # horseClass = horse_class()
    # horseClass.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # horseClass.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # horseClass.chr_name = curPlayer.GetPlayerName()
    # horseClass.bef_class_lv = befClassLV
    # horseClass.bef_exp = befExp
    # horseClass.cost_item_cnt = costCnt
    # horseClass.aft_class_lv = aftClassLV
    # horseClass.aft_exp = aftExp
    # WriteEvent(horseClass)
    #===========================================================================
    return
class wing_class(ScribeEvent):
    # 翅膀进阶记录
    def __init__(self):
        #必须字段
        super(wing_class, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.bef_class_lv = 0 # 当前翅膀等阶, 0代表1阶
        self.bef_exp = 0 # 进阶操作前的祝福值
        self.cost_item_cnt = 0 # 此次进阶消耗的进阶道具数量
        self.aft_class_lv = 0 # 此次进阶操作后翅膀的等阶, 0代表1阶
        self.aft_exp = 0 # 进阶操作后的祝福值
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   str(self.bef_class_lv), str(self.bef_exp), str(self.cost_item_cnt),
                   str(self.aft_class_lv), str(self.aft_exp), self.time]
        return super(wing_class, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_WingClass
def WriteEvent_wing_class(curPlayer, befClassLV, befExp, costCnt, aftClassLV, aftExp):
    ## 写翅膀进阶记录
    #===========================================================================
    # wingClass = wing_class()
    # wingClass.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # wingClass.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # wingClass.chr_name = curPlayer.GetPlayerName()
    # wingClass.bef_class_lv = befClassLV
    # wingClass.bef_exp = befExp
    # wingClass.cost_item_cnt = costCnt
    # wingClass.aft_class_lv = aftClassLV
    # wingClass.aft_exp = aftExp
    # WriteEvent(wingClass)
    #===========================================================================
    return
class pet_lv(ScribeEvent):
    # 宠物升级记录
    def __init__(self):
        #必须字段
        super(pet_lv, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.bef_lv = 0 # 升级前等级, 0代表1星
        self.aft_lv = 0 # 此次升级操作后等级
        self.bef_exp = 0 ## 此次进阶操作前的经验值
        self.aft_exp = 0 ## 此次进阶操作后的经验值
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   str(self.bef_lv), str(self.aft_lv), str(self.bef_exp), str(self.aft_exp), self.time]
        return super(pet_lv, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_PetLV
def WriteEvent_pet_lv(curPlayer, befLV, aftLV, befExp, aftExp):
    ## 写宠物升级记录
    #===========================================================================
    # petLV = pet_lv()
    # petLV.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # petLV.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # petLV.chr_name = curPlayer.GetPlayerName()
    # petLV.bef_lv = befLV
    # petLV.aft_lv = aftLV
    # petLV.bef_exp = befExp
    # petLV.aft_exp = aftExp
    # WriteEvent(petLV)
    #===========================================================================
    return
class pet_class(ScribeEvent):
    # 宠物进阶记录
    def __init__(self):
        #必须字段
        super(pet_class, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.pet_name = "" # 宠物名称
        self.bef_class_lv = 0 # 操作前的等阶, 0代表1阶
        self.bef_exp = 0 # 操作前的祝福值
        self.aft_class_lv = 0 # 此次进阶操作后的等阶
        self.aft_exp = 0 # 进阶操作后的祝福值
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   self.pet_name, str(self.bef_class_lv), str(self.bef_exp),
                   str(self.aft_class_lv), str(self.aft_exp), self.time]
        return super(pet_class, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_PetClass
def WriteEvent_pet_class(curPlayer, petName, befClassLV, befExp, aftClassLV, aftExp):
    ## 写宠物进阶记录
    #===========================================================================
    # petLV = pet_class()
    # petLV.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # petLV.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # petLV.chr_name = curPlayer.GetPlayerName()
    # petLV.pet_name = petName
    # petLV.bef_class_lv = befClassLV
    # petLV.bef_exp = befExp
    # petLV.aft_class_lv = aftClassLV
    # petLV.aft_exp = aftExp
    # WriteEvent(petLV)
    #===========================================================================
    return
class give_money(ScribeEvent):
    # 货币产出记录
    def __init__(self):
        #必须字段
        super(give_money, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.source = "" # 来源
        self.type_name = "" # 货币名称
        self.addMoney = 0 # 产出数量
        self.total_money = 0 # 剩余货币总量
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   self.source, self.type_name, str(self.addMoney), str(self.total_money), self.time]
        return super(give_money, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_GiveMoney
def WriteEvent_give_money(curPlayer, source, typeName, addMoney, totalMoney):
    ## 写货币产出记录
    #===========================================================================
    # giveMoney = give_money()
    # giveMoney.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # giveMoney.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # giveMoney.chr_name = curPlayer.GetPlayerName()
    # giveMoney.source = source
    # giveMoney.type_name = typeName
    # giveMoney.addMoney = addMoney
    # giveMoney.total_money = totalMoney
    # WriteEvent(giveMoney)
    #===========================================================================
    return
class pay_money(ScribeEvent):
    # 货币消耗记录
    def __init__(self):
        #必须字段
        super(pay_money, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.reason_name = "" # 消费点
        self.type_name = "" # 货币名称
        self.costmoney = 0 # 消耗数量
        self.total_money = 0 # 剩余货币总量
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   self.reason_name, self.type_name, str(self.costmoney), str(self.total_money), self.time]
        return super(pay_money, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_PayMoney
def WriteEvent_pay_money(curPlayer, reasonName, typeName, costMoney, totalMoney):
    ## 写货币消耗记录
    #===========================================================================
    # payMoney = pay_money()
    # payMoney.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # payMoney.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # payMoney.chr_name = curPlayer.GetPlayerName()
    # payMoney.reason_name = reasonName
    # payMoney.type_name = typeName
    # payMoney.costmoney = costMoney
    # payMoney.total_money = totalMoney
    # WriteEvent(payMoney)
    #===========================================================================
    return
class equip_item(ScribeEvent):
    # 玩家装备统计
    def __init__(self):
        #必须字段
        super(equip_item, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.equip_place = 0 # 装备位
        self.class_lv = 0 # 装备阶数, 0新手阶, 1-1阶
        self.item_quality = 0 # 品质
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   str(self.equip_place), str(self.class_lv), str(self.item_quality), self.time]
        return super(equip_item, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_EquipItem
def WriteEvent_orange_equip(curPlayer, place, classLV, quality):
    ## 写玩家装备统计
    #===========================================================================
    # equipItem = equip_item()
    # equipItem.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # equipItem.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # equipItem.chr_name = curPlayer.GetPlayerName()
    # equipItem.equip_place = place
    # equipItem.class_lv = classLV
    # equipItem.item_quality = quality
    # WriteEvent(equipItem)
    #===========================================================================
    return
class item_record(ScribeEvent):
    # 物品流水记录
    def __init__(self):
        #必须字段
        super(item_record, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.rec_type = 0 # 获得、失去
        self.event_name = "" # 事件点名称
        self.item_name = "" # 物品名
        self.item_count = 0 # 物品数量
        self.guid = "" # 物品唯一ID
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   str(self.rec_type), self.event_name, self.item_name, str(self.item_count), self.guid, self.time]
        return super(item_record, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_ItemRecord
def WriteEvent_item_record(curPlayer, recType, operateType, itemData, operatorExtra):
    EventReport(ShareDefine.Def_UserAction_ItemRecord, "Flow=%s&OperateType=%s&ItemData=%s&OperatorExtra=%s"
                % (recType, operateType,
                   json.dumps(itemData, ensure_ascii=False),
                   json.dumps(operatorExtra, ensure_ascii=False)), curPlayer)
    return
    #===============================================================================================
    # ''' @todo: 物品流水记录
    #    @param recType: 1-获得;-1-失去
    # '''
    # itemRecord = item_record()
    # itemRecord.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # itemRecord.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # itemRecord.chr_name = curPlayer.GetPlayerName()
    # itemRecord.rec_type = recType
    # itemRecord.event_name = eventName
    # itemRecord.item_name = itemName
    # itemRecord.item_count = itemCount
    # itemRecord.guid = guid
    # WriteEvent(itemRecord)
    # return
    #===============================================================================================
class coin_to_gold(ScribeEvent):
    # 兑换点券
    def __init__(self):
        #必须字段
        super(coin_to_gold, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.order_id = "" # 订单ID
        self.event_name = "" # 事件点名称
        self.coin = 0 # 兑换点券
        self.coin_prize = 0 # 奖励点券
        self.gold = 0 # 获得钻石
        self.total_gold = 0 # 当前总钻石数
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   self.order_id, self.event_name, str(self.coin), str(self.coin_prize), str(self.gold),
                   str(self.total_gold), self.time]
        return super(coin_to_gold, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_CoinToGold
def WriteEvent_coin_to_gold(curPlayer, orderID, eventName, coin, prizeCoin, addGold):
    return
    #===========================================================================
    # coinToGold = coin_to_gold()
    # coinToGold.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # coinToGold.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # coinToGold.chr_name = curPlayer.GetPlayerName()
    # coinToGold.order_id = orderID
    # coinToGold.event_name = eventName
    # coinToGold.coin = coin
    # coinToGold.coin_prize = prizeCoin
    # coinToGold.gold = addGold
    # coinToGold.total_gold = curPlayer.GetGold()
    # WriteEvent(coinToGold)
    #===========================================================================
    return
class god_weapon_lv(ScribeEvent):
    # 神兵升级记录
    def __init__(self):
        #必须字段
        super(god_weapon_lv, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.god_weapon_name = "" # 神兵名称
        self.bef_lv = 0 # 此次操作前的等级, 0代表0级, 1代表+1级
        self.bef_exp = 0 # 此次操作前的经验值
        self.cost_item_cnt = 0 # 此次消耗的道具数量
        self.aft_lv = 0 # 此次操作后的等级, 0代表0级, 1代表+1级
        self.aft_exp = 0 # 此次进阶操作后的经验值
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   self.god_weapon_name, str(self.bef_lv), str(self.bef_exp), str(self.cost_item_cnt),
                   str(self.aft_lv), str(self.aft_exp), self.time]
        return super(god_weapon_lv, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_GodWeaponLV
def WriteEvent_god_weapon_lv(curPlayer, godWeaponName, befLV, befExp, costCnt, aftLV, aftExp):
    ## 写神兵升级记录
    #===========================================================================
    # godWeaponLV = god_weapon_lv()
    # godWeaponLV.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # godWeaponLV.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # godWeaponLV.chr_name = curPlayer.GetPlayerName()
    # godWeaponLV.god_weapon_name = godWeaponName
    # godWeaponLV.bef_lv = befLV
    # godWeaponLV.bef_exp = befExp
    # godWeaponLV.cost_item_cnt = costCnt
    # godWeaponLV.aft_lv = aftLV
    # godWeaponLV.aft_exp = aftExp
    # WriteEvent(godWeaponLV)
    #===========================================================================
    return
class rune_lv(ScribeEvent):
    # 符印升级记录
    def __init__(self):
        #必须字段
        super(rune_lv, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.rune_name = "" # 符印名称
        self.cost_rune_money = 0 # 此次消耗的符印精华
        self.aft_lv = 0 # 此次操作后的等级, 0代表1级
        self.aft_rune_money = 0 # 此次操作后的符印精华
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   self.rune_name, str(self.cost_rune_money), str(self.aft_lv), str(self.aft_rune_money), self.time]
        return super(rune_lv, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_RuneLV
def WriteEvent_rune_lv(curPlayer, runeName, costruneMoney, aftLV, aftruneMoney):
    ## 写符印升级记录
    #===========================================================================
    # runeLV = rune_lv()
    # runeLV.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # runeLV.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # runeLV.chr_name = curPlayer.GetPlayerName()
    # runeLV.rune_name = runeName
    # runeLV.cost_rune_money = costruneMoney
    # runeLV.aft_lv = aftLV
    # runeLV.aft_rune_money = aftruneMoney
    # WriteEvent(runeLV)
    #===========================================================================
    return
class change_name(ScribeEvent):
    # 改名记录
    def __init__(self):
        #必须字段
        super(change_name, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.old_name = "" # 原来的名字
        self.new_name = "" # 新的名字
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   self.old_name, self.new_name, self.time]
        return super(change_name, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_ChangeName
def WriteEvent_change_name(curPlayer, oldName, newName):
    ## 改名记录
    #===========================================================================
    # changeName = change_name()
    # changeName.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # changeName.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # changeName.chr_name = curPlayer.GetPlayerName()
    # changeName.old_name = oldName
    # changeName.new_name = newName
    # WriteEvent(changeName)
    #===========================================================================
    return
class add_zhenqi(ScribeEvent):
    # 真气产出记录
    def __init__(self):
        #必须字段
        super(add_zhenqi, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.eventName = "" # 来源
        self.eventData = "" # 来源附加信息
        self.addValue = 0 # 产出数量
        self.totalValue = 0 # 剩余总量
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   self.eventName, str(self.eventData), str(self.addValue), str(self.totalValue), self.time]
        return super(add_zhenqi, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_AddZhenqi
def WriteEvent_add_zhenqi(curPlayer, eventName, eventData, addValue, totalValue):
    ## 真气产出记录
    #===========================================================================
    # if eventData:
    #    eventData = str(eventData)
    #    eventData = eventData.replace("\"", "'")
    #    eventData = eventData.replace(",", "|")
    #
    # addZhenQi = add_zhenqi()
    # addZhenQi.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # addZhenQi.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # addZhenQi.chr_name = curPlayer.GetPlayerName()
    # addZhenQi.eventName = eventName
    # addZhenQi.eventData = eventData
    # addZhenQi.addValue = addValue
    # addZhenQi.totalValue = totalValue
    # WriteEvent(addZhenQi)
    #===========================================================================
    return
class lost_zhenqi(ScribeEvent):
    # 真气消耗记录
    def __init__(self):
        #必须字段
        super(lost_zhenqi, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.eventName = "" # 消耗点
        self.eventData = "" # 消耗点附加信息
        self.lostValue = 0 # 消耗数量
        self.totalValue = 0 # 剩余总量
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   self.eventName, str(self.eventData), str(self.lostValue), str(self.totalValue), self.time]
        return super(lost_zhenqi, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_LostZhenqi
def WriteEvent_lost_zhenqi(curPlayer, eventName, eventData, lostValue, totalValue):
    ## 真气消耗记录
    #===========================================================================
    # if eventData:
    #    eventData = str(eventData)
    #    eventData = eventData.replace("\"", "'")
    #    eventData = eventData.replace(",", "|")
    #
    # lostZhenQi = lost_zhenqi()
    # lostZhenQi.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # lostZhenQi.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # lostZhenQi.chr_name = curPlayer.GetPlayerName()
    # lostZhenQi.eventName = eventName
    # lostZhenQi.eventData = eventData
    # lostZhenQi.lostValue = lostValue
    # lostZhenQi.totalValue = totalValue
    # WriteEvent(lostZhenQi)
    #===========================================================================
    return
class coat_lv(ScribeEvent):
    # 时装升级记录
    def __init__(self):
        #必须字段
        super(coat_lv, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.coat_name = "" # 时装名称
        self.bef_lv = 0 # 此次进阶操作前的等级
        self.bef_exp = 0 # 此次进阶操作前的经验值
        self.cost_item_cnt = 0 # 此次消耗的道具数量
        self.aft_lv = 0 # 此次操作后的等级, 0代表0级, 1代表+1级
        self.aft_exp = 0 #此次进阶操作后的经验值
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   self.coat_name, str(self.bef_lv), str(self.bef_exp), str(self.cost_item_cnt), str(self.aft_lv), str(self.aft_exp), self.time]
        return super(coat_lv, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_CoatLV
def WriteEvent_coat_lv(curPlayer, coatName, befLV, befExp, costItemCnt, aftLV, aftExp):
    return
    ## 写时装升级记录
    #===========================================================================
    # coatLV = coat_lv()
    # coatLV.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # coatLV.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # coatLV.chr_name = curPlayer.GetPlayerName()
    # coatLV.coat_name = coatName
    # coatLV.bef_lv = befLV
    # coatLV.bef_exp = befExp
    # coatLV.cost_item_cnt = costItemCnt
    # coatLV.aft_lv = aftLV
    # coatLV.aft_exp = aftExp
    # WriteEvent(coatLV)
    #===========================================================================
class wingskin_lv(ScribeEvent):
    # 时装升级记录
    def __init__(self):
        #必须字段
        super(wingskin_lv, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.skin_name = "" # 幻化翅膀名称
        self.bef_lv = 0 # 此次进阶操作前的等级
        self.bef_exp = 0 # 此次进阶操作前的经验值
        self.cost_item_cnt = 0 # 此次消耗的道具数量
        self.aft_lv = 0 # 此次操作后的等级, 0代表0级, 1代表+1级
        self.aft_exp = 0 #此次进阶操作后的经验值
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   self.skin_name, str(self.bef_lv), str(self.bef_exp), str(self.cost_item_cnt), str(self.aft_lv), str(self.aft_exp), self.time]
        return super(wingskin_lv, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_WingSkinLV
def WriteEvent_wingskin_lv(curPlayer, skinName, befLV, befExp, costItemCnt, aftLV, aftExp):
    ## 写幻化翅膀升级记录
    #===========================================================================
    # wingskinLV = wingskin_lv()
    # wingskinLV.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # wingskinLV.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # wingskinLV.chr_name = curPlayer.GetPlayerName()
    # wingskinLV.skin_name = skinName
    # wingskinLV.bef_lv = befLV
    # wingskinLV.bef_exp = befExp
    # wingskinLV.cost_item_cnt = costItemCnt
    # wingskinLV.aft_lv = aftLV
    # wingskinLV.aft_exp = aftExp
    # WriteEvent(wingskinLV)
    #===========================================================================
    return
class horseskin_lv(ScribeEvent):
    # 时装升级记录
    def __init__(self):
        #必须字段
        super(horseskin_lv, self).__init__()
        self.account_id = "" # 账号 ID,平台下唯一,且终生不变
        self.chr_name = "" # 玩家角色名
        self.skin_name = "" # 幻化坐骑名称
        self.bef_lv = 0 # 此次进阶操作前的等级
        self.bef_exp = 0 # 此次进阶操作前的经验值
        self.cost_item_cnt = 0 # 此次消耗的道具数量
        self.aft_lv = 0 # 此次操作后的等级, 0代表0级, 1代表+1级
        self.aft_exp = 0 #此次进阶操作后的经验值
        #非必须字段
        #即时是非必须字段也应该传送,各字段用,分隔,并且用双引号包含,参考格式'"1","","","12314"'
        return
    def GetCurEventStr(self):
        if not self.time:
            self.time = GameWorld.GetCurrentDataTimeStr()
        tmpList = [self.product_slug, self.agent_name, self.gameserver_no, self.account_id, self.chr_name,
                   self.skin_name, str(self.bef_lv), str(self.bef_exp), str(self.cost_item_cnt), str(self.aft_lv), str(self.aft_exp), self.time]
        return super(horseskin_lv, self).GetEventStr(tmpList)
    def GetScribeEventName(self): return ShareDefine.Def_UserAction_HorseSkinLV
def WriteEvent_horseskin_lv(curPlayer, skinName, befLV, befExp, costItemCnt, aftLV, aftExp):
    ## 写幻化坐骑升级记录
    #===========================================================================
    # horseSkinLV = horseskin_lv()
    # horseSkinLV.SetEventAgentInfo(GameWorld.GetPlayerPlatform(curPlayer.GetAccID()))
    # horseSkinLV.account_id = GameWorld.GetPlatformAccID(curPlayer.GetAccID())
    # horseSkinLV.chr_name = curPlayer.GetPlayerName()
    # horseSkinLV.skin_name = skinName
    # horseSkinLV.bef_lv = befLV
    # horseSkinLV.bef_exp = befExp
    # horseSkinLV.cost_item_cnt = costItemCnt
    # horseSkinLV.aft_lv = aftLV
    # horseSkinLV.aft_exp = aftExp
    # WriteEvent(horseSkinLV)
    #===========================================================================
    return
## ---------------------------------------------------------------------------------------
#------------------------2018-02-09  新的数据统计--------------------------------
def WriteEvent_Entry(curPlayer, step):
    EventReport(ShareDefine.Def_UserAction_LostModel, "Step=%s&Flag=%s"%(step, ShareDefine.Def_UserAction_CreateRole), curPlayer)
def WriteEvent_VIP(curPlayer):
    EventReport(ShareDefine.Def_UserAction_VIPLvUP, "VIPLevel=%s"%curPlayer.GetVIPLv(), curPlayer)
def WriteEvent_FightPower(curPlayer):
    EventReport(ShareDefine.Def_UserAction_FightPower, "FightPower=%s"%PlayerControl.GetFightPower(curPlayer), curPlayer)