hxp
8 天以前 a1086e20aaec8beb4453bce68a3b2b30024b1415
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/EventReport.py
@@ -33,60 +33,12 @@
#---------------------------------------------------------------------
import IpyGameDataPY
import IPY_GameWorld
import DataRecordPack
import PlayerControl
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 出错")
## 初始化事件
#  @param None
@@ -122,7 +74,6 @@
    ProductID = ReadChConfig.GetPyMongoConfig("EventReport", "ProductID")
    ReportUrl = ReadChConfig.GetPyMongoConfig("EventReport", "ReportUrl")
    
    playerInfo = ""
    if curPlayer:
@@ -163,429 +114,7 @@
    # 第五个参数0代表get发送  1代表post
    GameWorld.GetGameWorld().EventReport_EventReport("", "", "", "", 0, getUrl)
    return
## 写事件报告文件
#  @param eventClass
#  @return None
def WriteEvent(eventClass):
    return
    if GameWorld.IsCrossServer():
        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
## =================================================================================================
# 每个字段都应该转为字符串,不然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":
@@ -606,452 +135,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
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 GetScribeEvent_chr_level(curPlayer):
    transCnt, showLV = GameWorld.GetClientLV(curPlayer)
    return transCnt * 1000 + showLV
## -------------------------------------- 扩展自定义 ---------------------------------------
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
#------------------------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)