local serverId = skynet.getenv("servId") local server_id = (skynet.getenv("serverType") or "localtest") .. "_" .. serverId local logproxy = require "shared.logproxy" --[[ 100 购买/兑换行为 200 交易行为(与其他玩家) 300 通过关卡产出或消耗 400 通过任务产出或消耗 500 通过公会产出或消耗 600 通过成就产出或消耗 700 通过邮件产出或消耗 1000 其他行为 --]] local ItemReason = { recharge = 100, -- 充值获取 advWheelSurf = 101, -- 资助 advRepayWheelSurf = 102, -- 资助回馈 saleEquip = 103, -- 卖装备 saleRune = 104, -- 卖铭文 drawHero = 105, -- 抽卡 pvpShop = 106, -- pvp商店 saleItem = 107, -- 售卖道具 openItem = 108, -- 打开箱子 openTimeBox = 109, -- 打开时间箱 speedUpBox = 110, -- 速度箱 dailyShop = 111, -- 每日商城 dinershop = 112, -- 餐厅商店 goldBuy = 113, -- 购买金币 buyAdvCount = 114, -- 购买冒险次数 advReSupport = 115, -- 刷新拾荒支援技 advQuickHang = 116, -- 冒险快速挂机 makePotion = 117, -- 制造药剂 equipUp = 118, -- 装备升级 runeUp = 119, -- 符文升级 talentUp = 120, -- 天赋升级 buyBonusCount = 121, -- 购买奖励副本次数 bagField = 122, -- 背包栏位 buyPvpKey = 123, -- 购买pvp钥匙 startPvp = 124, -- 开始pvp unlockStory = 125, -- 解锁剧情 towerCount = 126, -- 电波塔次数 freeGift = 127, -- 免费礼包 exploreCommand = 128, -- 探索指令 drawHeroExtraReward = 129, -- 抽卡阶段奖励 actRecycle = 130, -- 活动道具回收 actExchange = 131, -- 兑换活动 actGachakon = 132, -- 扭蛋活动 totalRecharge = 133, -- 累计充值奖励 actHangDrop = 134, -- 掉落活动奖励 actBattle = 135, -- 活动关卡 actMilestone = 136, -- 活动关卡boss伤害里程碑 worldBossReward = 137, -- 世界boss翻牌奖励 advHang = 301, -- 拾荒挂机 hangBattle = 302, -- 挂机战斗 hangReward = 303, -- 挂机奖励 quickHang = 304, -- 快速挂机 bonusBattle = 305, -- 奖励副本 hangGift = 306, -- 奖励关卡奖励 pvpBattleC = 307, -- pvp战斗普通 pvpBattleH = 308, -- pvp战斗高级 pvpDivisionH = 309, -- pvp高级段位奖励 towerBattle = 310, -- 电波塔战斗 advOver = 311, -- 冒险结算 advUnlock = 312, -- 拾荒解锁 dinerFinishTask = 401, -- 餐厅完成任务 storybookReward = 402, -- 剧情奖励 finishTask = 403, -- 任务 taskActive = 404, -- 完成活跃任务 advMainTask = 405, -- 拾荒主线 chatline = 406, --查看chatline finishAchive = 601, -- 完成成就 advAchiev = 602, -- 拾荒成就 advAchievReward = 603, -- 拾慌成就奖励 draw_attach = 701, -- 邮件奖励 gm = 1000, -- 获取途径:GM -- 活动 sudoku = 1001, -- 九宫格 sudokuR = 1002, -- 九宫格连线奖励 sudokuRP = 1003, -- 九宫格阶段奖励 sign = 1004, -- 签到 friendPoint = 1005, -- 友情 birth = 1006, -- 出生奖励 actSign = 1007, -- 活动签到 actPaySign = 1008, -- 活动付费签到 calendaTask = 1009, -- 英雄帖 actMilecrisis = 1010, -- 物资危机 -- 餐厅 greenHourse = 1101, -- 食材获得 dinerEntrus = 1102, -- 餐厅委托 dinerCollect = 1103, -- 餐厅小人收集 dinerCombo = 1104, -- 小人组合 dinerSkillUp = 1105, -- 餐厅技能升级 dinerReTask = 1106, -- 餐厅刷新任务 addSell = 1107, -- 餐厅贩卖 dinerBuildUp = 1108, -- 建筑升级 removeSell = 1109, -- 移除售卖 dinerSell = 1110, -- 餐饮售卖 dinerShop = 1111, -- 餐厅商店 dinerSellQ = 1112, -- 餐厅快速 -- 英雄 heroLevelUp = 1201, -- 英雄升级 heroBreak = 1202, -- 英雄突破 heroWake = 1203, -- 英雄觉醒 heroTalent = 1204, -- 英雄天赋 createHero = 1205, -- 碎片合成 createHeroRandom = 1206, -- 随机合成 resetHero = 1207, -- 重置养成 unlockPool = 1208, -- 解锁英雄定向抽卡池 downloadCv = 1209, -- 下载 cv包奖励 refer = 1210, -- 穿戴 itemCompose = 1211, -- 天赋道具合成 radioQuest = 1212, -- 电台任务奖励 -- pvp pvpCHead = 1301, -- pvp 跨服竞技场头像 crossPvpBet = 1302, -- 竞猜 --adv chooseEvent = 1351, -- 冒险选择 clickTrader = 1352, -- 冒险商店 } --[[ 100 教学 200 主线 300 日常 400 周常 500 联盟 1000 限时任务 2000 其他 --]] local TaskType = { } local MethodType = { onCreateAccount = {}, -- 创建游戏账号 onCreateRole = {}, -- 创建游戏角色 onLogin = {}, -- 玩家登录 onLogout = { -- 登出 logtime = true, --登录时长 }, setLevel = { -- 设置等级 level_before = true, -- 变动前的等级,可以跳级 level_changemain = true, -- 等级变动原因,副本通关:mission,领取奖励:reward level_changedetail = true, -- 等级变动原因明细,副本通关则记录关卡ID,领取奖励则记录奖励ID level_reward = "json", -- 等级变动奖励,json格式记录,{道具ID1:道具数量,道具ID2:道具数量} }, onGuidePoint = { --游戏引导 guild_type = true, --引导类型,新手引导:0,系统引导:1,弱引导:2 guild_id = true, --节点ID guild_point = true, --步骤ID guild_pass = true, --正常操作:0,自动播放:1,跳过:2 }, setOrder = { --玩家订单记录 order_status = true, -- "订单状态:100 - 开始下单(玩家还未开始付费行为记录)200 - 支付完成并发货(SDK通知可以发货时记录),300 - 订单被取消,1000 - 其他" item_id = true, -- 道具id item_type = true, -- 购买的道具类型,具体见"onItems"方法中道具类型枚举表 item_name = true, -- 购买的道具名 item_number = true, -- 购买的道具数量 item_level = true, -- 购买的道具等级 order_cost = true, -- 此次消费的现金金额(单位:分),如 51800即未518元,对应客户端SDK传入的'total_fee' order_currency = true, -- 货币类型,默认为"CNY"(人民币),遵循ISO 4217规范 order_type = true, -- 订单类型,首充记录为1,否则为0 order_id = true, -- 本条记录的订单号,对应客户端SDK返回的'bs_trade_no' }, onMail = { --玩家邮件操作 mail_action_type = true, -- 操作(1=收,2=领,3=删) mail_receivetime = true, -- 收件时间 mail_textid = true, -- 邮件文本ID mial_title = true, -- 邮件标题参数 mail_content = true, -- 邮件内容参数 mail_attach = true, -- 邮件附件 mail_reason = true, -- 原因 mail_readstatus = true, -- 邮件读取状态 mail_attachstatus = true, -- 邮件附件状态 mail_timeout = true, -- 邮件超时时间 mail_friend_id = true, -- 收件方账号id mail_friend_roleid = true, -- 收件方角色id }, onItems = { --道具流通 item_id = true, -- 道具id item_sequenceid = "ucode", -- 道具变动关联ID,用于关联一次动作产生多条不同类型的日志,如一个礼包多个物品等情形 item_type = true, -- 道具类型,具体见枚举表中道具类型枚举表 item_level = true, -- 道具等级 item_number = true, -- 道具变化数量的绝对值 action_type = true, -- 变化类型(玩家获取:1,玩家消耗:0) item_before = true, -- 道具变化前的数量 item_after = true, -- 道具变化后的数量 item_reason = true, -- 道具流动一级原因,如抽卡、装备强化、副本掉落,可参考道具动作类型枚举表 item_subreason = true, -- 道具流动二级原因,抽卡:卡池ID,装备强化:装备ID,副本掉落:副本ID item_other = true, -- 其他(可包含阶数,强化等级,随机属性) }, mission = { --玩家副本完成情况 mission_threadid = true, -- 大关卡ID mission_id = true, -- 关卡ID mission_type = true, -- 关卡类型,见关卡类型枚举表 mission_sequenceid = "ucode", -- 本次对战ID,用于关联一次动作产生多条不同类型的日志 mission_herolist = "json", -- 英雄ID,排序以玩家出战设置为准,PVP多个队伍则记录多个列表。示例:[[1,2,3],[456]] mission_heroscore = true, -- 编队总评分 mission_enemylist = "json", -- 地方英雄ID,排序以玩家出战设置为准,PVP多个队伍则记录多个列表。示例:[[1,2,3],[456]] mission_damage = "json", -- 英雄输出值。示例:{'heroid1':1000,'heroid2':2000,………..} mission_ultskill = "json", -- 大招使用情况。示例:{'heroid1':1000,'heroid2':2000,………..} mission_reward = "json", -- 获得奖励,建议使用json格式记录。示例:{ "XX": "1", "XXX": "3"} mission_starttime = true, -- 战斗开始时间,格式 unixtime 秒级 mission_roundtime = true, -- 对局时长(秒) mission_result = true, -- 战斗结果(0-无效,1-胜利,2-失败) mission_star = true, -- 战斗完成星数,无星级的话填写0 mission_restriction = true, -- 周期内参与限制(0表示没有上限) mission_difficulty = true, -- 关卡困难度,无难度区分的话填写0 mission_strength = true, -- 消耗的体力或次数 mission_score = true, -- 本局分数,PVP玩法记录为对战后积分,无得分的填0 mission_cleartype = true, -- 1正常通关;2代理拾荒 mission_rank = "auto", -- 对战后排名,适用于PVP玩法和电波塔,其他玩法留空 misson_monsterkill = "json", -- 击杀怪物ID和数量,建议使用json格式记录。示例:{ "XX": "1", "XXX": "3"} misson_teamskill = "json", -- 编队支援技能和技能等级情况,json格式记录,{"teamskill1":1,"teamskill2":2,………..} }, residence_reward = { --玩家挂机或排名奖励 mission_threadid = true, --大关卡ID mission_id = true, --关卡ID mission_type = true, --关卡类型,见关卡类型枚举表 residence_reward_type = true, --领取奖励方式,快速(超前领取)记录为1,正常领取记录为0 residence_time = true, --挂机或排名时长 residence_reward = "json", --获得奖励,建议使用json格式记录。示例:{ "XX": "1", "XXX": "3"} }, hero_rise = { --英雄觉醒 hero_id = true, --英雄ID hero_rise_cost = "json", --英雄觉醒消耗,json格式记录,{道具ID1:消耗数量1,道具ID2:消耗数量2,………...} hero_rise_score = true, --英雄觉醒后评分提升 hero_rise_scoreget = true, -- 提升的评分 hero_rise_result = "json", --英雄觉醒效果,可记录效果ID,或json格式记录提升效果,{攻击:20,闪避:20,……..} }, hero_upgrade = { --英雄升级 hero_id = true, -- 英雄ID hero_upgrade_cost = "json", -- 英雄升级消耗,json格式记录,{道具ID1:消耗数量1,道具ID2:消耗数量2,………...} hero_upgrade_result = "json", -- 英雄升级效果,可记录效果ID,或json格式记录提升效果,{攻击:20,闪避:20,……..} hero_upgrade_type = true, -- 英雄升级方式,连续升级:1,单击升级:0 hero_upgrade_score = true, -- 英雄升级后评分 hero_upgrade_scoreget = true, -- 通过英雄升级提升的评分 }, hero_break = { --英雄突破 hero_id = true, -- 英雄ID hero_break_cost = "json", -- 英雄突破消耗,json格式记录,{道具ID1:消耗数量1,道具ID2:消耗数量2,………...} hero_break_result = "json", -- 英雄突破效果,可记录效果ID,或json格式记录提升效果,{攻击:20,闪避:20,……..} hero_break_level = true, -- 英雄突破后等级上限 }, hero_jewel = { --英雄铭文 hero_id = true, -- 英雄ID hero_jewel_sequence = "ucode", -- 铭文装备编号,用以关联一次装备时产生的多条日志 hero_jewel_id = true, -- 铭文ID hero_jewel_part = true, -- 铭文装备部位 hero_jewel_score = true, -- 铭文装备后的英雄分值 hero_jewel_scorebefore = true, -- 铭文装备前的英雄分值 hero_jewel_result = "json", -- 铭文装备后效果,可记录效果ID,或json格式记录提升效果,{攻击:20,闪避:20,……..} }, hero_note = { --英雄评价 hero_id = true, -- 英雄ID hero_note_action = true, -- 英雄评价界面操作,发布评论:0,点赞:1,反对:2 hero_note_id = true, -- 操作的评价ID hero_note_text = true, -- 操作的评价内容 }, hero_show = { --展示英雄 hero_id = true, -- 英雄ID }, hero_recycle = { --英雄回收 hero_recycle_list = "json", -- 回收的英雄id列表,建议使用json格式记录。示例:{ "XX": "1", "XXX": "3"} hero_recycle_reward = "json", -- 回收后获得的奖励,建议使用json格式记录。示例:{ "XX": "1", "XXX": "3"} hero_recycle_cnt = true, -- 总回收英雄量 }, gacha = { --英雄招募 gacha_id = true, -- 卡池ID gacha_type = true, -- 卡池类型 gacha_up = true, -- 卡池UP角色 gacha_times = true, -- 抽卡次数 gacha_reward = "json", -- 抽卡结果,建议使用json格式记录。示例:{ "XX": "1", "XXX": "3"} gacha_cost = "json", -- 消耗,json格式记录,{道具ID1:消耗数量1,道具ID2:消耗数量2,………...} gacha_cnt = true, -- 保底计数 }, equip_wear = { --装备穿戴与卸载 hero_id = true, --英雄ID equip_id = true, --装备ID equip_wear_action = true, --装备操作类型:装备:0,卸载:1 equip_wear_part = true, --装备部位,记录部位ID equip_wear_scorebef = true, --装备前英雄评分 equip_wear_score = true, --装备后英雄评分 equip_wear_mode = true, --用以区分自动装备还是手动装备,自动记录为0,手动记录为1 equip_wear_seqid = "ucode", --自动穿戴时记录的系列ID,用以关联一次性装备时候产生的多条记录 }, equip_upgrade = { --装备升级 equip_upgrade_part = true, -- 升级部位,记录部位ID equip_id = true, -- 升级后的装备ID equip_upgrade_amount = true, -- 升级获取的装备数量 equip_upgrade_usedid = true, -- 升级消耗的装备ID equip_upgrade_cost = true, -- 升级操作消耗装备数量 equip_upgrade_current = "json", -- 升级操作消耗货币数量 }, carriage_dismantle = { --物资拆解 item_id = true, -- 道具id item_sequenceid = "ucode", -- 道具变动关联ID,用于关联一次动作产生多条不同类型的日志,如一个礼包多个物品等情形 item_type = true, -- 道具类型,具体见枚举表中道具类型枚举表 item_level = true, -- 道具等级 item_number = true, -- 道具变化数量的绝对值 carriage_dismantle_type = true, -- 拆解方式,时间到期:0,钥匙开启:1 carriage_dismantle_time = true, -- 拆解耗时,填写实际耗时 carriage_dismantle_cost = true, -- 拆解花费钥匙数量,未使用填写0 carriage_dismantle_rwd = "json", -- 拆解获得物资,json格式记录,{'itemid1':2,'itemid2':3,…………..} }, carriage_logistics = { --后勤室 carriage_logistics_type = true, -- 后勤室制作类型ID,变异:0,通常:1,魔法:2 carriage_logistics_itemid = true, -- 后勤室升级物品或技能ID carriage_logistics_itemlv = true, -- 升级后物品或技能等级 carriage_logistics_gear = true, -- 后勤室升级花费齿轮数量 carriage_logistics_coin = true, -- 后勤室升级花费美食币数量 }, carriage_decals = { --贴纸拆解 item_id = true, --道具id item_sequenceid = "ucode", --道具变动关联ID,用于关联一次动作产生多条不同类型的日志,如一个礼包多个物品等情形 item_type = true, --道具类型,具体见枚举表中道具类型枚举表 item_level = true, --道具等级 item_number = true, --道具变化数量的绝对值 carriage_decals_rwdid = true, --拆解获得物资ID carriage_decals_rwdnum = true, --拆解获得物资数量 }, carriage_video = { --放映室 carriage_video_type = true, --放映室类型,剧情CG:0, 角色CG:1, 主线剧情:2, 角色剧情:3, 活动剧情:4, 图鉴:5 carriage_video_id = true, --放映室片段ID carriage_video_coinid = true, --放映奖励货币类型,无奖励则填写0 carriage_video_coinnum = true, --放映奖励货币数量,无奖励则填写0 carriage_video_item = "json", --放映奖励其他物品数量,json格式记录,{'itemid1':10,'itemid2':5,…………..},无奖励则填写0 }, carriage_cook = { --调理室 item_id = true, -- 道具id item_level = true, -- 道具等级 item_type = true, -- 道具类型,具体见枚举表中道具类型枚举表 carriage_cook_amount = true, -- 制作总量 carriage_cook_cost = "json", -- 制作消耗道具,json格式记录,{'itemid1':10,'itemid2':5,…………..} }, activity = { --活动或指南奖励 activity_id = true, -- 活动ID(或活动指定任务的ID) activity_type = true, -- 活动类型,见活动类型枚举表 activity_reward = "json", -- 活动奖励,json格式记录,{'itemid1':123,'itemid2':456,………...} }, task_reward = { --任务奖励 task_reward_id = true, --任务奖励ID task_reward_type = true, --任务奖励类型,见 任务奖励类型枚举表 task_reward_detail = "json", --任务奖励,json格式记录,{'itemid1':123,'itemid2':456,………...} }, shop_purchase = { --商店购买行为 item_id = true, -- 道具id item_sequenceid = "ucode", -- 道具变动关联ID,用于关联一次动作产生多条不同类型的日志,如一个购买礼包多个物品等情形 item_type = true, -- 道具类型,具体见枚举表中道具类型枚举表 item_level = true, -- 道具等级 item_cnt = true, -- 购买数量技术 currency_type = true, -- 购买道具消耗的货币类型,记录货币ID shop_purchase_current = true, -- 购买道具消耗的货币数量 shop_id = true, -- 商店ID }, --[[ 100 添加好友 200 删除好友 300 屏蔽/拉黑 1000 其他 --]] friend_opt = { --好友操作 friend_opt_type = true, -- 好友操作类型,见枚举表中 好友操作类型枚举表 friend_roleid = true, -- 好友账户下的角色id friend_cnt = true, -- 操作后好友数量 }, communication = { --玩家发言 publish_type = true, --发言类型,全部:0,公告:1,世界:2,联盟:3,私聊:4 publish_status = true, --发送状态,发送成功:0,发送失败:1,被屏蔽:2,其他:3 publish_receive_roleid = true, --接收者角色ID publish_text = true, --发言内容 }, restaurant_up = { --摊位升级 restaurant_up_type = true, --升级部件类型,店面:0, 接客:1, 满意度:2, 宣传:3, 广告:4, 周边:5 restaurant_up_gear = true, --消耗齿轮数量 restaurant_up_coin = true, --花费美食币数量 restaurant_up_effectbef = true, --升级前加成 restaurant_up_effect = true, --升级后加成 }, restaurant_sale = { --摊位售卖 item_id = true, -- 售卖物品ID restaurant_sale_seat = true, -- 售卖物品所在位置 restaurant_sale_time = true, -- 售卖时长 restaurant_sale_type = true, -- 售卖方式,正常售卖:0, 加速:1,移除售卖:2 restaurant_sale_coin = true, -- 售卖获得美食币 restaurant_sale_gear = true, -- 售卖获得齿轮 }, restaurant_material = { --食材获取 item_id = true, -- 获取物品ID restaurant_material_seqid = "ucode", -- 道具变动关联ID,用于关联一次动作产生多条不同类型的日志,如一次获取两件道具情况 restaurant_material_start = true, -- 申请获取时间 restaurant_material_time = true, -- 申请到领取耗时 restaurant_material_num = true, -- 获取物品数量 }, restaurant_order = { --订单任务 restaurant_order_id = true, -- 订单任务ID restaurant_order_status = true, -- 订单任务状态,接受:0, 拒绝:1, 完成:2 restaurant_order_rwd = "json", -- 订单完成奖励,json格式记录,{"itemid1":123,"itemid2":12,……….} restaurant_order_lv = true, -- 订单品质等级,普通:0, 稀有:1, 顶级:2, 豪华:3 restaurant_order_type = true, -- 订单任务类型,0:特殊顾客,1:特别订单 }, restaurant_collect = { --餐厅顾客图谱 restaurant_collect_id = true, -- 图谱收集ID restaurant_collect_rwd = "json", -- 订单完成奖励,json格式记录,{"itemid1":123,"itemid2":12,……….} restaurant_collect_plan = true, -- 收集进度,即解锁顾客,数字表示 }, achievement = { --成就达成 achievement_id = true, -- 成就id achievement_type = true, -- 成就类型,具体枚举表中成就类型枚举表 achievement_reward = "json", -- 达成成就奖励,json格式记录,{"itemid1":123,"itemid2":12,……….} }, get_gift = { --礼包兑换 gift_id = true, -- 礼包ID gift_key = true, -- 礼包key gift_reward = "json", -- 礼包奖励,json格式记录,{"itemid1":123,"itemid2":12,……….} gift_name = true, -- 礼包名称 gift_reason = true, -- 礼包发放原因,见发放原因枚举表 }, push_gift = { -- 礼包推送 gift_id = true, --礼包ID gift_name = true, --礼包名称 }, mission_pick = { --拾荒玩法 mission_threadid = true, -- 大地图ID mission_threadname = true, -- 大地图名称 mission_id = true, -- 关卡ID mission_herolist = "json", -- 英雄ID列表,[111, 222, 333, 444, 555] 前两个为队长、副队长 mission_heroscore = true, -- 编队总评分 mission_teamlv = true, -- 编队等级 mission_recscore = true, -- 关卡推荐评分 mission_floor_bef = true, -- 进入前关卡层数 mission_floor_aft = true, -- 结束时关卡层数 mission_team_status = "json", -- 队伍状态,{"HP":100, "SP":100, "curse":7} mission_result = true, -- 战斗结果(0-无效,1-胜利,2-血量耗尽退出,3,主动退出) mission_reward = "json", -- 获得奖励,[{"id":101,"num":10},{"id":102,"num":20},{"id":103,"num":30}] mission_integral_bef = true, -- 进入前积分 mission_integral_aft = true, -- 完成后积分 mission_cleartype = true, -- 1正常通关;2代理拾荒 mission_sequenceid = true, -- 本次拾荒ID,用于关联一次拾荒产生多条不同类型的日志 }, mission_pick_achiev = { --拾荒任务 mission_threadid = true, -- 大地图ID mission_threadname = true, -- 大地图名称 mission_id = true, -- 关卡ID mission_pick_achiev_id = true, -- 任务ID mission_pick_achiev_reward = "json", -- 任务奖励,[{"id":101,"num":10},{"id":102,"num":20},{"id":103,"num":30}] mission_sequenceid = true, -- 本次拾荒ID,用于关联一次拾荒产生多条不同类型的日志 }, mission_pick_equip = { -- 拾荒神器装备 mission_threadid = true, --大地图ID mission_threadname = true, --大地图名称 mission_id = true, --关卡ID mission_pick_equip_type = true, --神器操作类型:1:装备,2:卸下 mission_pick_equip_id = true, --神器ID mission_pick_equip_lv = true, --神器等级 mission_sequenceid = true, --本次拾荒ID,用于关联一次拾荒产生多条不同类型的日志 }, mission_pick_reform = { --拾荒神器升级 mission_threadid = true, -- 大地图ID mission_threadname = true, -- 大地图名称 mission_id = true, -- 关卡ID mission_pick_equip_id = true, -- 神器ID mission_pick_reform_beflv = true, -- 神器原等级 mission_pick_reform_aftlv = true, -- 神器现等级 mission_pick_reform_cost = true, -- 消耗探险点数 mission_sequenceid = true, -- 本次拾荒ID,用于关联一次拾荒产生多条不同类型的日志 }, mission_pick_use = { --拾荒任务道具使用 mission_threadid = true, -- 大地图ID mission_threadname = true, -- 大地图名称 mission_id = true, -- 关卡ID item_id = true, -- 道具ID mission_pick_use_num = true, -- 道具使用量 mission_sequenceid = true, -- 本次拾荒ID,用于关联一次拾荒产生多条不同类型的日志 }, mission_pick_fund = { --拾荒资助 item_id = true, -- 资助花费道具ID mission_pick_fund_amount = true, -- 资助花费道具数量 mission_pick_fund_cnt = true, -- 资助花费道具次数,1或者10 mission_pick_fund_reward = "json", -- 资助获得奖励,[{"id":100,"num":10},{"id":101,"num":20},{"id":102,"num":30}] mission_pick_fund_stagereward = "json", -- 资助阶段奖励 mission_pick_fund_beflv = true, -- 资助前资助等级 mission_pick_fund_aftlv = true, -- 资助后资助等级 }, function_open = { -- 功能开启日志 function_id = true, --功能ID }, punitive_action = { -- 讨伐行动 --TODO mission_id = true, --关卡ID mission_herolist = "json", -- 英雄ID,排序以玩家出战设置为准,示例:[111, 222, 333, 444, 555] mission_success_rate = true, -- 大成功几率 mission_reward = "json", -- 获得奖励,建议使用json格式记录。示例:{ itemid1: 1, itemid2: 3, itemid3: 5} mission_result = true, -- 战斗结果(0-无效,1-胜利,2-失败) mission_roundtime = true, -- 完成耗时(秒) mission_cleartype = true, -- 1-开始; 2-完成(领取奖励时) }, hero_talent = { --英雄精进(原英雄天赋升级) TODO hero_id = true, --英雄ID hero_talent_stagebef = true, --英雄精进升级前停留阶段 hero_talent_stage = true, --英雄精进升级后停留阶段 hero_talent_cost = "json", --英雄精进升级消耗,json格式记录,{道具ID1:消耗数量1,道具ID2:消耗数量2,….} hero_talent_subid = true, --升级属性ID,生命、攻击、防御、命中、闪避分别对应(0,1,2,3,4) hero_talent_sublevel = true, --升级属性等级,如生命升级从1到2,则记录2 }, } local function printError(info) print(info) print(debug.traceback()) end local function jsonEncode(tab) local newTab = {} for k , v in pairs(tab) do newTab[tostring(k)] = v end return json.encode(newTab) end local function isIos(self) local sid = self:getProperty("sid") return sid == 2 end local sdkId local AppId = { [1] = 4787, [2] = 4788, [3] = 4789, } local function getBaseLog(self) local uid = self:getProperty("uid") local sid = self:getProperty("sid") if not sdkId then _, sdkId = string.match(uid, "(.*)_(.*)") if not _ then sdkId = uid end end local log = { server_id = server_id, timestamp = skynet.timex(), app_id = AppId[sid] or 0, plat_id = isIos(self) and 0 or 1, sdk_uid = sdkId, account_id = uid, role_id = self:getProperty("id"), role_name = self:getProperty("name"), level = self:getProperty("level"), vip = 0, device_id = self:getProperty("device"), device_model = self:getProperty("dmode"), version = "v2.0.1", client_version = self.clientVersion or "1.0.0", sys_version = self.sysVersion or "unknow", ip = self.ip or "0.0.0.0", network = self.network or "unknow", record_date = os.date("%Y%m%d"), } return log end -- logType local LogType = { create = "common", login = "common", logout = "common", guide = "common", newdevice = "common", cbback = "common", in_item = "common", out_item = "common", in_diamond = "common", out_diamond = "common", in_hero = "common", out_hero = "common", in_equip = "common", out_equip = "common", in_rune = "common", out_rune = "common", player_exp = "common", func_open = "common", in_adv = "common", out_adv = "common", in_artifact = "common", mail_action = "common", role_action = "common", hang_action = "common", hero_action = "common", adv_action = "common", rune_action = "common", pvp_action = "common", diner_action = "common", tower_action = "common", gm_action = "common", act_action = "common", } -- 如要修改 要提前修改 _template mapping -- 对应 mapping 为 gamelog-* local Mapping = { -- 预留一些数据格式 担心integer 范围不够用 将 通用的int* 全部换为long common = { desc = "keyword",--索引的短字符串 ucode = "keyword",--关联日志对应ucode key1 = "keyword", --可索引的短字符串 key2 = "keyword", --可索引的短字符串 -- 几乎不用的长文本 text1 = "text", --长字符串不索引的类型 -- 五个不同类型的数字 基本上满足数量要求 尽量从低到高用 short1 = "short", int1 = "long", int2 = "long", long1 = "long", float1 = "float", -- 底层使用的 一些参数 cint1 = "long", cint2 = "long", cint3 = "long", } } -- 所有的日志都包括的部分 role 里面的信息 -- mapping 信息在 gamelog-role local commonRoleField = { name = "keyword", id = "integer", uid = "keyword", sid = "short", device = "keyword", ctime = "integer", ltime = "integer", level = "short", rmbC = "integer", } local function checkType(logType, field, value, ctype) local typecheckfunc = { keyword = function() --长度不超过256 if type(value) ~= "string" then value = tostring(value) printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [keyword], value : %s", logType, field, value)) else if #value > 256 then printError(string.format("LOG ERROR: logType [%s] field [%s] [keyword] type to long. value : %s", logType, field, value)) end end return value end, text = function() if type(value) ~= "string" then value = tostring(value) printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [text], value : %s", logType, field, value)) end return value end, integer = function() if type(value) ~= "number" then value = tonumber(value) printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [integer], value : %s", logType, field, value)) end if value then if math.type(value) ~= "integer" then local oldValue = value value = math.floor(value) if value ~= oldValue then printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [integer], is float, value : %s", logType, field, value)) end end if -2147483648 > value or value > 2147483647 then printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [integer], too big, value : %s", logType, field, value)) value = nil end end return value end, short = function() if type(value) ~= "number" then value = tonumber(value) printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [short], value : %s", logType, field, value)) end if value then if math.type(value) ~= "integer" then local oldValue = value value = math.floor(value) if value ~= oldValue then printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [short], is float, value : %s", logType, field, value)) end end if -32768 > value or value > 32768 then printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [short], too big, value : %s", logType, field, value)) value = nil end end return value end, long = function() if type(value) ~= "number" then value = tonumber(value) printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [long], value : %s", logType, field, value)) end if value then if math.type(value) ~= "integer" then local oldValue = value value = math.floor(value) if type(value) ~= "integer" then printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [long], too big, value : %s", logType, field, value)) value = nil elseif value ~= oldValue then printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [long], is float, value : %s", logType, field, value)) end end end return value end, float = function() if type(value) ~= "number" then value = tonumber(value) printError(string.format("LOG ERROR: logType [%s] field [%s] isn't [float], value : %s", logType, field, value)) end return value end, } if typecheckfunc[ctype] then return typecheckfunc[ctype]() else printError(string.format("LOG ERROR: logType [%s] field [%s] have a new type [%s] need add check.", logType, field, ctype)) return nil end end local RoleLog = {} function RoleLog.bind(Role) function Role:log(logType, contents) contents = contents or {} local schema = MethodType[logType] if not schema then printError(string.format("LOG ERROR: new logType [%s].", logType)) return end local doc = getBaseLog(self) doc["method"] = logType for field, value in pairs(contents) do if not schema[field] then printError(string.format("LOG ERROR: logType [%s] have new field [%s], call.", logType, field)) else if schema[field] == 'json' then value = jsonEncode(value) end doc[field] = value end end for field, tag in pairs(schema) do if not contents[field] then if tag == "ucode" then doc[field] = self:getActionUcode() elseif tag == "auto" then else printError(string.format("LOG ERROR: logType [%s] lose field [%s].", logType, field)) end end end logproxy:log(doc, "bi") end function Role:logItems(itemId, before, after, log) if not log then print("logItems no log ", debug.traceback()) end local reason = log.desc local subreason = log.int1 or 0 local other = log.int2 or 0 local reasonType = ItemReason[reason] if not reasonType then printError(string.format("LOG ERROR: onItems no reasonType [%s].", reason)) end local itemData = csvdb["itemCsv"][itemId] if not itemData then return end self:log("onItems", { item_id = itemId, -- 道具id item_type = itemData.type, -- 道具类型,具体见枚举表中道具类型枚举表 item_level = 0, -- 道具等级 item_number = math.abs(after - before), -- 道具变化数量的绝对值 action_type = after - before > 0 and 1 or 0, -- 变化类型(玩家获取:1,玩家消耗:0) item_before = before, -- 道具变化前的数量 item_after = after, -- 道具变化后的数量 item_reason = reasonType or 0, -- 道具流动一级原因,如抽卡、装备强化、副本掉落,可参考道具动作类型枚举表 item_subreason = subreason, -- 道具流动二级原因,抽卡:卡池ID,装备强化:装备ID,副本掉落:副本ID item_other = other, -- 其他(可包含阶数,强化等级,随机属性) }) end function Role:mylog(logType, contents) contents = contents or {} local _logType = LogType[logType] if not _logType then printError(string.format("LOG ERROR: new logType [%s] need Add Maping.", logType)) return end local doc = {} for field, ctype in pairs(commonRoleField) do if contents[field] then printError(string.format("LOG ERROR: logType [%s] had field [%s] overwrite default.", logType, field)) end doc[field] = checkType("commonRoleField", field, self:getProperty(field), ctype) end local mapping = Mapping[_logType] if mapping["ucode"] and not contents["ucode"] then contents["ucode"] = self:getActionUcode() end for field, value in pairs(contents) do local ftype = mapping[field] if ftype then doc[field] = checkType(logType, field, value, ftype) else printError(string.format("LOG ERROR: logType [%s] have new field [%s] no type in mapping.", logType, field)) end end doc["@type"] = logType logproxy:log(doc, "log") end function Role:startActionUcode() if not self._uniqueCount then self._uniqueCount = 0 end local action = {self:getProperty("id"), skynet.timex(), self._uniqueCount} self._uniqueCount = self._uniqueCount + 1 self._actionUcode = table.concat(action, "_") end function Role:endActionUcode() self._actionUcode = nil end function Role:getActionUcode() return self._actionUcode end end return RoleLog