local EventSystem = require('Event/EventSystem') local select = select local BIManager = { myTVTPlayerId = 0 } local LevelTickCountThreshold = 150 --关卡帧数超过次阈值再上传 local LevelHighJankFrameTime = 0.08 --用来区分高卡顿和低卡顿 local LevelExpectFrameTime = 0.04 --理想帧耗时,>=这个值的都统计下来,因为RealDeltaTime会跳动,所以设置成40,减少误差 local LowJankThreshold = 2 local ForceRecordTriggerLevel = { 1000, 1011, 1022, 1042 } --海外新手关也要记录的关卡,一段时间后关闭 local PlayerOnlineTimeSendLimit = 60 -- 在切换关卡、切后台时,在线时长大于这个值就要进行一次统计(单位秒) local PlayerOnlineTimeSendGap = 120 -- 当在线时长大于这个值时就要统计一次(单位秒)--目的是为了防止异常丢失 local PlayerOnlineTimeDeltaLimit = 5 -- 当后台切换回来后,这个deltaTime会很大。但是在loading时这个值也稍微有点大,故找个合适的 5秒作为临界区分。 local LevelRecordMemoryInterval = 600 --关卡内存记录间隔 600帧 local private = { battleID = nil, --服务器在EnterFuben协议下发的BattleID bossHPCompareDict = nil, -- bossHPInterval = nil, -- boss血量百分比统计间隔 lastClintBITime = 0, -- 上次客户端BI打点时间 BI_SendState = {}, playerOnlineTime = 0, -- 玩家在线时长 playerOnlineTimeIsPause = true, -- 玩家在线时长暂停统计 } local levelData = { sceneTime = 0, --记录场景开始时间 sceneTickCount = 0,-- 记录更新次数 sceneHighJankCount = 0, --记录高卡顿 sceneLowJankCount = 0, --记录低卡顿 sceneLowJankTag = 0, lowMemoryCount = 0, noBattleLevelPlayerCount = 1, --默认值为1,因为主城类关卡中,如果场景内只有自己,S2CRemoveRoleScreenResp不会收到任何回调 levelErrorCount = 0, levelExceptionCount = 0, levelWarningCount = 0, maxMemorySystem = 0, --关卡内最大System Memory --maxMemoryLua = 0, --预留、关卡内最大Lua Memory --maxMemoryGC = 0, --预留、关卡内最大GC Memory } local bi_pb local JSON = require("cjson") local BIEventCfg = require("BI/BIEventCfg") local HttpBIManager = nil local HttpNetMsgManager = nil if not USE_LUA_STANDALONE then HttpBIManager = require("BI/HttpBIManager") HttpNetMsgManager = require("BI/HttpNetMsgManager") end local curBIData = nil local defaultValue = "0" local BIChannelID local HeroAndroidChannelID = "18" BIManager.EventName = BIEventCfg.EventName BIManager.BDCEventParam = BIEventCfg.BDCEventParam BIManager.BDCEventParamValue = BIEventCfg.BDCEventParamValue local EventType = BIEventCfg.EventType local SendType = BIEventCfg.SendType local BIUrlCfg = { --["12"] = "http://121.40.56.162:8301"; ["12"] = "http://185.238.251.18:8301"; } --记录热更时间戳 BIManager.LastUpdateStepTime=os.time() BIManager.BIType = { ChangeHeroStage = 1, --换人阶段 LevelLayout = 2, --关卡布局(元素和事件) BossHPStage = 3, --Boss血量阶段 SyncBattle = 4, -- 同步战斗相关的 LevelAvgFPS = 5, -- 关卡平均fps WorldBossBeKilled = 6, -- 世界boss中玩家被杀死 WorldBossRelive = 7, -- 世界boss中复活相关 OffLine1v1 = 8 , -- 异步1v1 的log PlayerGuide = 9, -- 新手引导的埋点 CutsceneSkip = 10, -- 过场跳过的埋点 SwitchLod =11, --切换lod等级 AppPush = 12, --推送状态 WorldBossFightMode = 13, --世界boss改变战斗模式 ChangAnSiegeChongceArrive = 14, --长安争夺战:冲车到达时间(战斗时间) PlayerOnlineTime = 15, -- 统计玩家在线时长 } local NORMAL_LEVEL_1_1_ID = 1011 BIManager.ViewBIEvent = { UITownTaskGuide_Cell = "UITownTaskGuide_Cell", UITownHome_event_Store = "UITownHome_event_Store", UITownHome_event_DrawCard = "UITownHome_event_DrawCard", UITownHome_event_DivineWeapon = "UITownHome_event_DivineWeapon", UITownHome_event_OfficialPosition = "UITownHome_event_OfficialPosition", UILoginMain_btn_Start = "UILoginMain_btn_Start", UISettingInitial_btn_Confirm = "UISettingInitial_btn_Confirm ", UIVirtualController_Direction = "UIVirtualController_Direction", UIBattleAttackPanel_Slash = "UIBattleAttackPanel_Slash", UIWelfareReservedGift_btn_Get = "UIWelfareReservedGift_btn_Get", UICharacterTeamPanel_btn_AvatarChange = "UICharacterTeamPanel_btn_AvatarChange", CutScene_TimeLine_Skip = "CutScene_TimeLine_Skip", CutScene_Movie_Skip = "CutScene_Movie_Skip", UILevelSelectMainPanel_event_Attack = "UILevelSelectMainPanel_event_Attack", } -- 只发首次 local ViewBIEventToOnceEventName = { [BIManager.ViewBIEvent.UITownHome_event_Store] = BIManager.EventName.FirstClickMall, [BIManager.ViewBIEvent.UITownHome_event_DrawCard] = BIManager.EventName.ClickRecruit, [BIManager.ViewBIEvent.UITownHome_event_DivineWeapon] = BIManager.EventName.ClickWeapon, [BIManager.ViewBIEvent.UIVirtualController_Direction] = BIManager.EventName.FirstClickDirection, [BIManager.ViewBIEvent.UIBattleAttackPanel_Slash] = BIManager.EventName.FirstClickSkills, [BIManager.ViewBIEvent.UIWelfareReservedGift_btn_Get] = BIManager.EventName.CollectedSubReward, } -- 可重复发 local ViewBIEventToEventName = { [BIManager.ViewBIEvent.UILoginMain_btn_Start] = BIManager.EventName.ClickStartButton, [BIManager.ViewBIEvent.UISettingInitial_btn_Confirm] = BIManager.EventName.ChooseVision, [BIManager.ViewBIEvent.CutScene_TimeLine_Skip] = BIManager.EventName.ClickSkipScript, [BIManager.ViewBIEvent.CutScene_Movie_Skip] = BIManager.EventName.ClickSkipScript, } local TeamLevelEvent = { [20] = BIManager.EventName.Level20Reached, [30] = BIManager.EventName.Level30Reached, [40] = BIManager.EventName.Level40Reached, [50] = BIManager.EventName.Level50Reached, [60] = BIManager.EventName.Level60Reached, [70] = BIManager.EventName.Level70Reached, [80] = BIManager.EventName.Level80Reached, [90] = BIManager.EventName.Level90Reached, } local TotalBREvent = { [100000] = BIManager.EventName.TotalBR100000, [210000] = BIManager.EventName.TotalBR210000, [275000] = BIManager.EventName.TotalBR275000, [305000] = BIManager.EventName.TotalBR305000, } local HeroCountEvent = { [10] = BIManager.EventName.Unlock10Hero, [14] = BIManager.EventName.Unlock14Hero } local AttackLevelID = { [10102] = BIManager.EventName.Start0102, -- 开始普通难度主线剧情1-2 曲阳之战 [10201] = BIManager.EventName.Start0201, -- 开始主线剧情2-1 董卓盗国 } local BITaskClickEventID = { [110100] = { [2] = BIManager.EventName.MainLine0101_1,-- 点击主线剧情按钮,开始主线剧情 [3] = BIManager.EventName.MainLine0101_2,-- 点击主线剧情按钮,桃园结义 [4] = BIManager.EventName.MainLine0101_3,-- 点击主线剧情按钮,询问兵曹 }, [200100] = { [1] = BIManager.EventName.Start0201,-- 开始主线剧情2-1 董卓盗国 } } local SpecificBarrierLevelId = { [10102] = BIManager.EventName.Complete0102, --主线1-2 [10103] = BIManager.EventName.Complete0103, --主线1-3 [20101] = BIManager.EventName.CompleteElite0101, --精英1-1 [30101] = BIManager.EventName.CompleteHell0101, --噩梦1-1 [10203] = BIManager.EventName.Complete0203, --主线2-3 [10206] = BIManager.EventName.Complete0206, --主线2-6 [10305] = BIManager.EventName.Complete0305, --主线3-5 } local SmallAPKBarrierLevelId = { [10101] = BIManager.EventName.CompleteLevel101, [10102] = BIManager.EventName.CompleteLevel102, } local CHAPTER_LEVEL_ID_1_1 = 10101 -- 1-1 章节配表id 用来判断是否通关 local CHAPTER_LEVEL_ID_1_2 = 10102 -- 1-2 章节配表id 用来判断是否通关 local LEVEL_ID_1_2 = 1022 local toKeyValueStrTable = {} local function Send() NetManager.SendMessage(MessageEnums.MessageCBILog, curBIData) curBIData = nil end function BIManager.OnUpdate(deltaTime) if LogicUpdateManager.FightBegin then -- 只有在加载完场景、资源并开始战斗后,才统计avgFps if LevelManager._levelLogicData.LogicLoadingStep ~= LuaConst.Enum_LoadingStep.None then -- 当LogicUpdateManager.FightBegin==true时,只有Enum_LoadingStep.None才是补帧完毕的 return end if levelData.sceneTickCount % LevelRecordMemoryInterval == 0 then levelData.maxMemorySystem = math.max(levelData.maxMemorySystem, CTL.Setting.GetEngineSystemUsedMemory()) end levelData.sceneTime = levelData.sceneTime + deltaTime levelData.sceneTickCount = levelData.sceneTickCount + 1 if deltaTime > LevelHighJankFrameTime then levelData.sceneHighJankCount = levelData.sceneHighJankCount + 1 elseif deltaTime >= LevelExpectFrameTime then levelData.sceneLowJankTag = levelData.sceneLowJankTag + 1 else if levelData.sceneLowJankTag >= LowJankThreshold then levelData.sceneLowJankCount = levelData.sceneLowJankCount + levelData.sceneLowJankTag end levelData.sceneLowJankTag = 0 end end -- 统计在线时长 if private.playerOnlineTimeIsPause == false then if deltaTime < PlayerOnlineTimeDeltaLimit then private.playerOnlineTime = private.playerOnlineTime + deltaTime if private.playerOnlineTime >= PlayerOnlineTimeSendGap then private.SendPlayerOnlineTime() end end end end function BIManager.Init() private.InitBIChannelID() HttpBIManager.Init() HttpNetMsgManager.Init() BIManager.SetBIUrl(BIUrlCfg[GameAppInfo.Global_ProductId]) private.bossHPCompareDict = {} private.bossHPInterval = 0.1 private.playerOnlineTime = 0 private.playerOnlineTimeIsPause = true EventSystem.Regist(EventID.BI_SwitchLod, private.SendLevelMessage) EventSystem.Regist(EventID.BI_LevelHigh, private.SendLevelMessage) EventSystem.Regist(EventID.BI_LevelMiddle, private.SendLevelMessage) EventSystem.Regist(EventID.BI_LevelLow, private.SendLevelMessage) EventSystem.Regist(EventID.BI_ClientEvent, private.SendWithDetailEncode) EventSystem.Regist(EventID.BI_OnPaySuccess, private.SendPaySuccessEvent) EventSystem.Regist(EventID.BI_ClientNetState, private.SendNetExceptionBI) EventSystem.Regist(EventID.BI_OnFinishGuide, private.OnFinishGuide) --疑似闪退埋点记录 EventSystem.Regist(EventID.Level_BeginLevel, private.RecordBeginLevel) EventSystem.Regist(EventID.ApplicationPause, private.OnApplicationPause) EventSystem.Regist(EventID.ApplicationQuit, private.OnApplicationQuit) -- 日本新增玩法事件监听 EventSystem.Regist(EventID.BI_ViewClick, private.OnUIViewBtnClick) EventSystem.Regist(EventID.BI_ReachLevel, private.OnReachLevel) EventSystem.Regist(EventID.CharacterTeamGsChange, private.OnReachGSEvent) EventSystem.Regist(EventID.BI_UnlockHero, private.OnUnlockHero) EventSystem.Regist(EventID.BI_UseItem, private.SendItemUseBIEvent) EventSystem.Regist(EventID.BI_FinishFuben, private.OnFinishFubenEvent) EventSystem.Regist(EventID.BI_FirstJoinGuild, private.OnFirstJoinGuildEvent) end function BIManager.DispatchBIClientEvent(...) EventSystem.Dispatch(EventID.BI_ClientEvent, ...) end function BIManager.OnEnterWorldResponse() HttpNetMsgManager.InitBaseField() private.playerOnlineTimeIsPause = false -- 开始计时玩家在线时长 end function BIManager.SetBIUrl(biUrl) if string.isNilOrEmpty(biUrl) then biUrl = BIUrlCfg["12"] logging.error(LTAG.ERROR, "无效的BI地址走一个默认的", biUrl) end HttpBIManager.SetURL(biUrl) HttpNetMsgManager.SetURL(biUrl) end function BIManager.SetBattleID(battleID, battleIDStr) private.battleID = battleID private.battleIdStr = battleIDStr or "" end function BIManager.GetBattleIDStr() return private.battleIdStr end function BIManager.SetABTestMode(mode) HttpBIManager.SetABTestModel(mode) end function BIManager.SetSyncBattleGRoomID(strID, agentInfo) private.syncGRoomId = strID private.syncAgentInfo = agentInfo end function BIManager.GetSyncBattleGRoomID() return private.syncGRoomId end function BIManager.GetBDCDiffTime() local diffSeconds = os.time() - BIManager.LastUpdateStepTime BIManager.LastUpdateStepTime = os.time() return diffSeconds end function BIManager.SendWithEncode(key, ...) if key == BIEventCfg.EventName.StartHotUpdate then private.Send(key, false, "RemoteHotfixCode", AppInfo.hotfixCodeFromServer, ...) else private.Send(key, false, ...) end end function private.SendWithDetailEncode(key, ...) private.Send(key, true, ...) end function private.Send(key, isDetail ,...) local localTime = AuxUtil.GetLocalTimeStampMS() if localTime < private.lastClintBITime then local diff = private.lastClintBITime - localTime logging.error(LTAG.ERROR, "client bi log time error, last = ", private.lastClintBITime, " current = ", localTime, " diff = ", diff) private.LuaSendNTEventByBanned( "ClientTimeChange", private.ToJsonStr("event_name", "ClientTimeChange", "last", private.lastClintBITime, "current", localTime, "diff", diff) ) end private.lastClintBITime = localTime -- 越南地区只要自己的专属埋点 if GameAppInfo.IsVietnamPackage() then private.LuaSendNTEventByWhitListVN(key, ...) local eventType = EventType[key] if eventType == SendType.Http or eventType == SendType.HttpAndNT then HttpBIManager.SendNormalEvent(key, ...) end return end if BIManager.EventName[key] then local eventType = EventType[key] if eventType == SendType.Http then HttpBIManager.SendNormalEvent(key, private.ToKeyValueStr(...)) elseif eventType == SendType.NT then local content = isDetail and private.ToDetailJsonStr("event_name", key, ...) or private.ToJsonStr("event_name", key, ...) private.LuaSendNTEventByBanned(key, content) elseif eventType == SendType.HttpAndNT then HttpBIManager.SendNormalEvent(key, private.ToKeyValueStr(...)) local content = isDetail and private.ToDetailJsonStr("event_name", key, ...) or private.ToJsonStr("event_name", key, ...) private.LuaSendNTEventByBanned(key, content) if key == "GameLaunch" then private.GameLaunch() end elseif eventType == SendType.BDC then local content = isDetail and private.ToDetailJsonStr("event_name", key, ...) or private.ToJsonStr("event_name", key, ...) SDKUtil.SendBDCEvent(BIEventCfg.BDCEvent[key], content) elseif eventType == SendType.Custom then local content = private.ToJsonStr(...) if GameAppInfo.IsVersionGreaterThan18000() then if GameAppInfo.IsChinesePackage() then if GameAppInfo.IsVersionGreaterThan19000() then SDKUtil.SendCustomEvent(content, BIEventCfg.RemoveChannelType[eventName] or 0) else SDKUtil.SendCustomEvent(content) end else SDKUtil.SendCustomEvent(content, BIEventCfg.RemoveChannelType[eventName] or 0) end else SDKUtil.SendCustomEvent(content) end elseif eventType == SendType.Overseas then if GameAppInfo.IsOverseaPackage() or GameAppInfo.IsJapanesePackage() then local content = isDetail and private.ToDetailJsonStr("event_name", key, ...) or private.ToJsonStr("event_name", key, ...) private.ClientSendNTEvent(key, content) end elseif eventType == SendType.Japanese then if GameAppInfo.IsJapanesePackage() then HttpBIManager.SendNormalEvent(key, ...) local content = isDetail and private.ToDetailJsonStr("event_name", key, ...) or private.ToJsonStr("event_name", key, ...) private.ClientSendNTEvent(key, content) end elseif eventType == SendType.OnlyHMT then if GameAppInfo.IsOverseaPackage() then local content = isDetail and private.ToDetailJsonStr("event_name", key, ...) or private.ToJsonStr("event_name", key, ...) private.ClientSendNTEvent(key, content) end elseif eventType == SendType.Vietnamese then --越南暂时在这里不做任何处理 只单纯过滤不报错也不埋点 else logging.error(LTAG.ERROR, "数据埋点的无法解析配置类型",key) end else logging.error(LTAG.ERROR, "打点的key 配置找不到",key) end end private.downloadEventSetting = { [-2] = "AbortDownload", [-1] = "FinishLoginFreeLevel", [0] = "StartDownloadStage1Package", [5] = "Stage1PackagePercent5", [10] = "Stage1PackagePercent10", [20] = "Stage1PackagePercent20", [30] = "Stage1PackagePercent30", [40] = "Stage1PackagePercent40", [80] = "Stage1PackagePercent80", [100] = "EndDownloadStage1Package", ---PAD [101] = "StartDownloadPAD", [102] = "DownloadPADPercent10", [103] = "DownloadPADPercent20", [104] = "DownloadPADPercent40", [105] = "DownloadPADPercent80", [106] = "FinishDownloadPAD", [107] = "StartGetPADProgress", ---PAD ---PreHotfix [201] = "ReportPreHotfix", ---PreHotfix [301] = "ReportPackProgress", -- 下载所有分包进度埋点,stage 放在 extra 里面。 [400] = "ReportStageDownloadInfo", -- 每章节下载完成的埋点 [401] = "ReportPackDownloadCompleted", -- 记录 Stage 开始下载的埋点 [402] = "ReportStartStageDownload", -- 记录开始下载之后的平均下载速度 [403] = "ReportDownloadSpeedHeartbeat", } function private.LuaSendNTEventByBanned(eventName, content) if GameAppInfo.IsJapanesePackage() and BIEventCfg.BannedNTEventJPDic[eventName] then return else private.ClientSendNTEvent(eventName, content) end end function private.LuaSendNTEventByWhitListVN(eventName, content) if GameAppInfo.IsVietnamPackage() and BIEventCfg.WhiteListNTEventVNDic[eventName] then local eventNameStr = string.format("%s%s",eventName, content) private.ClientSendNTEvent(eventName, private.ToDetailJsonStr("event_name", eventNameStr, content)) end end --上报分包下载进度,复用了一个已有参数用于传值,实际含义不同了 function BIManager.ReportPackProgress(packProgress) BIManager.SendDownloadEvent(301, packProgress) end --每个 Stage 下载完带速度的埋点 function BIManager.ReportStageDownloadInfo(speed, ...) BIManager.SendDownloadEvent(400, speed, "Stage", ...) end --每个 Pack 下载完带速度的埋点 function BIManager.ReportPackDownloadCompleted(speed, ...) BIManager.SendDownloadEvent(401, speed, "Pack", ...) end --Stage 开始下载之前的埋点 function BIManager.ReportStartStageDownload() local key = private.downloadEventSetting[402] if key then HttpBIManager.SendNormalEvent(key) end end --越南开始下载之后的心跳检测上报下载速度 function BIManager.ReportDownloadSpeedHeartbeat(speed, ...) BIManager.SendDownloadEvent(403, speed, "Stage", ...) end function BIManager.SendDownloadEvent(step, downloadSpeed, ...) local key = private.downloadEventSetting[step] if key then HttpBIManager.SendDownloadEvent(key, private.ToKeyValueStr(...), downloadSpeed) local content = private.ToJsonStr("event_name", key, ...) private.LuaSendNTEventByBanned(key, content) end end function BIManager.SendSmallPackDownloadEvent(step, package) HttpBIManager.SendDownloadEvent(step, private.ToKeyValueStr("packageStage", package), LoginProxy.GetDownloadSpeed()) logging.crit(LTAG.CRIT,"SendSmallPackDownloadEvent", step, package) local content = private.ToJsonStr("event_name", step, "packageStage", package) private.LuaSendNTEventByBanned(step, content) end function BIManager.SendBDCEvent(key, ...) SDKUtil.SendBDCEvent(tostring(key),private.ToDetailJsonStr(...)) end function BIManager.SendBDCServerEvent(success) local state = success and 1 or 2 --20004 区服状态请求 --1 服务器连接成功 --2 服务器连接失败 SDKUtil.SendBDCEvent("20004", private.ToDetailJsonStr("event_name",BIManager.EventName.BDC_ServiceState,"service_state", state, "sl_server_id", MDL.Login.GetServerId())) end function private.SendPaySuccessEvent(eventName) local content = private.ToJsonStr("event_name", eventName) private.ClientSendNTEvent(eventName, content) end function private.ClientSendNTEvent(eventName, content) if GameAppInfo.IsVersionGreaterThan18000() then if GameAppInfo.IsChinesePackage() then if GameAppInfo.IsVersionGreaterThan19000() then if BIEventCfg.RemoveChannelType[eventName] then SDKUtil.SendCustomEvent(content, BIEventCfg.RemoveChannelType[eventName]) else SDKUtil.SendNTEvent(content) end else SDKUtil.SendNTEvent(content) end else if BIEventCfg.RemoveChannelType[eventName] then SDKUtil.SendCustomEvent(content, BIEventCfg.RemoveChannelType[eventName]) else if GameAppInfo.IsVietnamPackage() then if BIEventCfg.WhiteListNTEventVNDic[eventName] then SDKUtil.SendNTEvent(content) else return end else SDKUtil.SendNTEvent(content) end end end else SDKUtil.SendNTEvent(content) end end function private.SendLevelMessage(type,...) local func = private[type] if func then func(...) end end function private.CreateBIData() local msg = bi_pb.CBIData() msg.ClientTime = tostring(UTL.Time.GetServerTimestamp()) return msg end private[BIManager.BIType.LevelAvgFPS] = function (levelID ,levelName) local isCanUpload = true if LogicUpdateManager.IsInReconnectFastPlay() or LogicUpdateManager.IsReplayOrServerCheck or LevelManager.IsReplayRecordInSwitchLevel() or LevelManager.IsInLevelWatchBattle() or levelData.sceneTickCount < LevelTickCountThreshold then isCanUpload = false end local totalWarningCount, totalExceptionCount, totalErrorCount = 0, 0, 0 if isCanUpload then if curBIData == nil then curBIData = bi_pb.CBILog() TimerUtil.TimeOut(Send) end local msg = private.CreateBIData() local avgfps = levelData.sceneTickCount / levelData.sceneTime --保留小数点后两位 avgfps = math.floor(avgfps * 100) * 0.01 local highJankRatio = levelData.sceneHighJankCount / levelData.sceneTickCount local lowJankRatio = levelData.sceneLowJankCount / levelData.sceneTickCount msg.levelAvgFps.TotalTickCount = levelData.sceneTickCount msg.levelAvgFps.AvgFps = avgfps msg.levelAvgFps.HighJankRatio = highJankRatio msg.levelAvgFps.LowJankRatio = lowJankRatio + highJankRatio msg.levelAvgFps.LevelID = levelID msg.levelAvgFps.LevelName = levelName msg.levelAvgFps.LevelType = LevelManager.GetCurLevelType() msg.levelAvgFps.IsEmulator = tostring(IsEmulator) msg.levelAvgFps.CPU = SystemInfo.graphicsDeviceName msg.levelAvgFps.RAM = SystemInfo.systemMemorySize msg.levelAvgFps.Graphics = SettingAPI.lodLevel msg.levelAvgFps.FirstGraphics = SettingAPI.deviceLevel msg.levelAvgFps.LowMemoryCount = levelData.lowMemoryCount msg.levelAvgFps.FramerateMode = SettingAPI.fpsLevel msg.levelAvgFps.MaxMemorySystem = levelData.maxMemorySystem --单位MB if LevelManager.IsNoBattleLevel() then msg.levelAvgFps.TotalNum = levelData.noBattleLevelPlayerCount else msg.levelAvgFps.TotalNum = LogicUpdateManager.GetPlayerCount() end if GameAppInfo.IsVersionGreaterThan111000() then totalWarningCount, totalExceptionCount, totalErrorCount = logging.getLogStatisticInfo() end msg.levelAvgFps.WarnCount = totalWarningCount - levelData.levelWarningCount msg.levelAvgFps.ExcepCount = totalExceptionCount - levelData.levelExceptionCount msg.levelAvgFps.ErrCount = totalErrorCount - levelData.levelErrorCount table.insert(curBIData.data, msg) end levelData.sceneTime = 0 levelData.sceneTickCount = 0 levelData.sceneHighJankCount = 0 levelData.sceneLowJankCount = 0 levelData.sceneLowJankTag = 0 levelData.lowMemoryCount = 0 levelData.noBattleLevelPlayerCount = 1 levelData.levelWarningCount = totalWarningCount levelData.levelExceptionCount = totalExceptionCount levelData.levelErrorCount = totalErrorCount levelData.maxMemorySystem = 0 end private[BIManager.BIType.SyncBattle] = function (logType , IntParam1 ,IntParam2 ,IntParam3, stringParam1) if LogicUpdateManager.IsReplayOrServerCheck then return end if curBIData == nil then curBIData = bi_pb.CBILog() TimerUtil.TimeOut(Send) end local msg = private.CreateBIData() msg.inBattleCommon.GRoomID = private.syncGRoomId or "" msg.inBattleCommon.MyPlayerId = BIManager.myTVTPlayerId or 0 msg.inBattleCommon.MyHeroId = LogicUpdateManager._curEntity and LogicUpdateManager._curEntity:GetOriginCharacterData().ID or 0 msg.inBattleCommon.LogTyp = logType msg.inBattleCommon.IntParam1 = IntParam1 or -1 msg.inBattleCommon.IntParam2 = IntParam2 or -1 msg.inBattleCommon.IntParam3 = IntParam3 or -1 msg.inBattleCommon.StringParam = tostring(LevelManager.LevelType) msg.inBattleCommon.StringParam1 = stringParam1 or (private.syncAgentInfo or "") msg.inBattleCommon.StringParam2 = MDL.BattleAgent.GetAllPings() msg.inBattleCommon.BattleServerId = BattleDataGetter.GetBattleServerID() local maxPing,minPing,avgPing = BattleExt.GetPingInfo(logType == "[sync]StagePing") msg.inBattleCommon.MaxPing = maxPing msg.inBattleCommon.MinPing = minPing msg.inBattleCommon.AvePing = avgPing table.insert(curBIData.data,msg) end private[BIManager.BIType.WorldBossBeKilled] = function (killerName, decOccupyTime, occupyTime) if LogicUpdateManager.IsInReconnectFastPlay() or LogicUpdateManager.IsReplayOrServerCheck then return end if curBIData == nil then curBIData = bi_pb.CBILog() TimerUtil.TimeOut(Send) end local msg = private.CreateBIData() msg.killedInWorldBoss.RoomID = private.syncGRoomId msg.killedInWorldBoss.FuncID = 12 -- 根据枚举写死的 function 表 msg.killedInWorldBoss.LevelID = LevelManager.GetCurLevelID() msg.killedInWorldBoss.LevelType = LevelManager.GetCurLevelType() msg.killedInWorldBoss.Killer = killerName if decOccupyTime then msg.killedInWorldBoss.DecOccupyTime = decOccupyTime end if occupyTime then msg.killedInWorldBoss.OccupyTime = occupyTime end table.insert(curBIData.data,msg) end private[BIManager.BIType.WorldBossRelive] = function (reliveTimes ,reliveType) if LogicUpdateManager.IsInReconnectFastPlay() or LogicUpdateManager.IsReplayOrServerCheck then return end if curBIData == nil then curBIData = bi_pb.CBILog() TimerUtil.TimeOut(Send) end local reliveTypeIndex = reliveType if reliveType == LuaConst.SpecialCommandType.ServerRevive then reliveTypeIndex = 1 elseif reliveType == LuaConst.SpecialCommandType.ReviveNeerby then reliveTypeIndex = 2 end local msg = private.CreateBIData() msg.worldBossReborn.RoomID = private.syncGRoomId msg.worldBossReborn.FuncID = 12 -- 根据枚举写死的 function 表 msg.worldBossReborn.LevelID = LevelManager.GetCurLevelID() msg.worldBossReborn.LevelType = LevelManager.GetCurLevelType() msg.worldBossReborn.RebornTimes = reliveTimes msg.worldBossReborn.RebornType = reliveTypeIndex table.insert(curBIData.data,msg) end private[BIManager.BIType.OffLine1v1] = function (round, category, lineHeroID,myHeroGS,enemyHeroID ,enemyHeroGS,IsStart,winHerosHP,battleTime ,isWin) if LogicUpdateManager.IsInReconnectFastPlay() or LogicUpdateManager.IsReplayOrServerCheck then return end if curBIData == nil then curBIData = bi_pb.CBILog() TimerUtil.TimeOut(Send) end local msg = private.CreateBIData() msg.offline1v1Log.category = category -- 战斗类型 0:1v1演武,1:群雄演武 msg.offline1v1Log.BattleID = private.battleID or ""; --战斗ID msg.offline1v1Log.Round = round; --局数 for i,v in ipairs(lineHeroID) do table.insert(msg.offline1v1Log.LineHeroID, lineHeroID[i]) --出战武将:主将ID,副将ID,主将ID,副将ID,主将ID,副将ID end msg.offline1v1Log.LineTotalHeroGS = myHeroGS or 0; --主副将总战力 for i,v in ipairs(enemyHeroID) do table.insert(msg.offline1v1Log.EnemyLineHeroID, enemyHeroID[i]) --敌方出战武将:主将ID,副将ID,主将ID,副将ID,主将ID,副将ID end msg.offline1v1Log.EnemyLineTotalHeroGS = enemyHeroGS or 0; --敌方主副将总战力 msg.offline1v1Log.IsStart = IsStart; --小局开始或结束的埋点,true:开始,false:结束 --以下optional字段,结束的点有 msg.offline1v1Log.WinHeroHP = winHerosHP; --胜利方武将剩余血量百分比,百分比用浮点数,保留两位 msg.offline1v1Log.BattleTime = battleTime; --战斗从开始到结束花费的时长 msg.offline1v1Log.IsWin = isWin; --是否胜利,1为胜利,0为失败 table.insert(curBIData.data, msg) end private[BIManager.BIType.ChangeHeroStage] = function (deadChange, beforeEntity, afterEntity) local battleID = private.battleID if BattleDataGetter.IsSyncLevel() then battleID = 0 --联机玩法没有private.battleID, 所以设为0. (不设为battleRoomID是因为battleRoomID是string, 而这里要传int64) end if not battleID then return end local levelID = BattleDataGetter.GetLevelID() local reason = deadChange and "Dead Change" or "Manual Change" local beforeID = beforeEntity._logicInitData.CharacterID local afterID = afterEntity._logicInitData.CharacterID local beforeHP =FP.tonumberV1(beforeEntity.components.attr.hp)/FP.tonumberV1(beforeEntity.components.attr:MaxHP()) local afterHP =FP.tonumberV1(afterEntity.components.attr.hp)/FP.tonumberV1(afterEntity.components.attr:MaxHP()) if curBIData == nil then curBIData = bi_pb.CBILog() TimerUtil.TimeOut(Send) end local msg = private.CreateBIData() msg.changeHeroInBattle.BattleID = battleID msg.changeHeroInBattle.LevelID = levelID msg.changeHeroInBattle.Reason = reason msg.changeHeroInBattle.BefHeroID = beforeID msg.changeHeroInBattle.BefHeroHP = beforeHP msg.changeHeroInBattle.AftHeroID = afterID msg.changeHeroInBattle.AftHeroHP = afterHP table.insert(curBIData.data, msg) end --2022-10-5,客户端为了减少数数压力,hmt关闭,其他区域打开 private[BIManager.BIType.LevelLayout] = function(id, isItem, describe) local levelID = BattleDataGetter.GetLevelID() local forceRecord for i, v in ipairs(ForceRecordTriggerLevel) do if levelID == v then forceRecord = true break end end if forceRecord or not GameAppInfo.IsOverseaPackage() then local battleID = private.battleID if not battleID then return end if curBIData == nil then curBIData = bi_pb.CBILog() TimerUtil.TimeOut(Send) end local msg = private.CreateBIData() msg.triggerFlowInBattle.BattleID = battleID msg.triggerFlowInBattle.LevelID = levelID msg.triggerFlowInBattle.IsItem = isItem msg.triggerFlowInBattle.ItemID = id msg.triggerFlowInBattle.ItemEvent = describe table.insert(curBIData.data, msg) end end --2022-10-5,客户端为了减少数数压力,全大区去掉此打点 private[BIManager.BIType.BossHPStage] = function (bossEntity) -- local battleID = private.battleID -- if not battleID then -- return -- end -- if not private.bossHPInterval then -- return -- end -- local percentCompare = private.bossHPCompareDict[bossEntity._logicInitData.EntityID] or 1 -- local bossID = bossEntity._logicInitData.CharacterID -- local bossHP = FP.tonumberV1(bossEntity.components.attr.hp)/FP.tonumberV1(bossEntity.components.attr:MaxHP()) -- if bossHP > percentCompare then -- return -- end -- while bossHP < percentCompare do -- percentCompare = percentCompare - private.bossHPInterval -- end -- private.bossHPCompareDict[bossEntity] = percentCompare -- local levelID = BattleDataGetter.GetLevelID() -- local heroID1,heroHP1 = 0, 0 -- local heroID2,heroHP2 = 0, 0 -- local heroID3,heroHP3 = 0, 0 -- local heroEntity1 = BattleDataGetter.GetHeroInHeroEntityTableByIndex(LuaConst.STANDALONE_PLAYER_PlayID,1) -- if heroEntity1 then -- heroID1 = heroEntity1._logicInitData.CharacterID -- heroHP1 = FP.tonumberV1(heroEntity1.components.attr.hp)/FP.tonumberV1(heroEntity1.components.attr:MaxHP()) -- end -- local heroEntity2 = BattleDataGetter.GetHeroInHeroEntityTableByIndex(LuaConst.STANDALONE_PLAYER_PlayID,2) -- if heroEntity2 then -- heroID2 = heroEntity2._logicInitData.CharacterID -- heroHP2 = FP.tonumberV1(heroEntity2.components.attr.hp)/FP.tonumberV1(heroEntity2.components.attr:MaxHP()) -- end -- local heroEntity3 = BattleDataGetter.GetHeroInHeroEntityTableByIndex(LuaConst.STANDALONE_PLAYER_PlayID,3) -- if heroEntity3 then -- heroID3 = heroEntity3._logicInitData.CharacterID -- heroHP3 = FP.tonumberV1(heroEntity3.components.attr.hp)/FP.tonumberV1(heroEntity3.components.attr:MaxHP()) -- end -- if curBIData == nil then -- curBIData = bi_pb.CBILog() -- TimerUtil.TimeOut(Send) -- end -- local msg = private.CreateBIData() -- msg.stageEventInBossChallenge.BattleID = battleID -- msg.stageEventInBossChallenge.LevelID = levelID -- msg.stageEventInBossChallenge.BossID = bossID -- msg.stageEventInBossChallenge.BossHP = bossHP -- msg.stageEventInBossChallenge.HeroID1 = heroID1 -- msg.stageEventInBossChallenge.HeroHP1 = heroHP1 -- msg.stageEventInBossChallenge.HeroID2 = heroID2 -- msg.stageEventInBossChallenge.HeroHP2 = heroHP2 -- msg.stageEventInBossChallenge.HeroID3 = heroID3 -- msg.stageEventInBossChallenge.HeroHP3 = heroHP3 -- table.insert(curBIData.data, msg) end private[BIManager.BIType.PlayerGuide] = function (isSkip,flowId,stepId,stepCount) if curBIData == nil then curBIData = bi_pb.CBILog() TimerUtil.TimeOut(Send) end local msg = private.CreateBIData() msg.playerGuide.isSkip = isSkip and 1 or 0 msg.playerGuide.flowId = flowId msg.playerGuide.stepId = stepId msg.playerGuide.stepCount = stepCount table.insert(curBIData.data,msg) end private[BIManager.BIType.CutsceneSkip] = function(cutsceneID, isSkip, isSenior, playTime, duration, realDuration) if curBIData == nil then curBIData = bi_pb.CBILog() TimerUtil.TimeOut(Send) end local msg = private.CreateBIData() msg.timeLine.timeLineId = cutsceneID msg.timeLine.isSkip = isSkip and 1 or 0 msg.timeLine.isMvp = isSenior and 1 or 0 msg.timeLine.playTime = playTime msg.timeLine.totalDuration = duration msg.timeLine.realDuration = realDuration table.insert(curBIData.data,msg) end function private.HttpCutsceneSkip(cutsceneID, isSkip, isSenior, playTime, duration, realDuration) local value = private.ToDetailJsonStr("timeLineId",cutsceneID, "isSkip",isSkip and 1 or 0,"isMvp",isSenior and 1 or 0, "playTime",playTime,"totalDuration",duration,"realDuration",realDuration) private.SendWithDetailEncode(BIManager.EventName.FreeLevelTimeLine,value) end function private.HttpPlayerGuide(isSkip,flowId,stepId,stepCount) local value = private.ToDetailJsonStr("isSkip",isSkip and 1 or 0,"flowId",flowId,"stepId",stepId,"stepCount",stepCount) private.SendWithDetailEncode(BIManager.EventName.FreeLevelPlayerGuide,value) end --lod 等级切换埋点 --isManual 是否为手动,是为手动,否为自动 private[BIManager.BIType.SwitchLod] = function (switchLodType,beforeLodLevel,afterLodLevel) if curBIData == nil then curBIData = bi_pb.CBILog() TimerUtil.TimeOut(Send) end --lod 等级不变的话,不发送 if beforeLodLevel == afterLodLevel then return end local msg = private.CreateBIData() local levelID = BattleDataGetter.GetLevelID() local curInfoData=BattleDataGetter.GetLevelInfoData() local levelName= "" if curInfoData ~= nil then levelName = curInfoData.ScenePath end --测试日志 --logging.error(LTAG.ERROR,"SwitchLod levelID "..levelID.." levelName "..tostring(levelName).." switchLodType "..tostring(switchLodType).." beforeLodLevel "..tostring(beforeLodLevel).." afterLodLevel "..afterLodLevel) if levelID == nil then levelID = 0 end msg.changeLod.LevelID = levelID msg.changeLod.LevelName = levelName msg.changeLod.LevelType = LevelManager.GetCurLevelType() or 0 msg.changeLod.SwitchLodType = switchLodType msg.changeLod.BefGrade = beforeLodLevel msg.changeLod.AftGrade = afterLodLevel msg.changeLod.FirstGraphics = SettingAPI.deviceLevel -- 首次进入默认画面设置 msg.changeLod.IsEmulator = tostring(IsEmulator) -- 是否为模拟器 msg.changeLod.CPU = SystemInfo.graphicsDeviceName -- 设备CPU msg.changeLod.RAM = SystemInfo.systemMemorySize -- 设备内存 table.insert(curBIData.data, msg) end --1开,0关 private[BIManager.BIType.AppPush] = function(pushState) if curBIData == nil then curBIData = bi_pb.CBILog() TimerUtil.TimeOut(Send) end local msg = private.CreateBIData() msg.appPush.switchState = pushState table.insert(curBIData.data, msg) end private[BIManager.BIType.WorldBossFightMode] = function(fightMode) if curBIData == nil then curBIData = bi_pb.CBILog() TimerUtil.TimeOut(Send) end local msg = private.CreateBIData() msg.worldBossSwitchMode.gRoomId = private.syncGRoomId msg.worldBossSwitchMode.levelId = LevelManager.GetCurLevelID() msg.worldBossSwitchMode.mode = fightMode == LuaConst.EFightMode.PEACE and 0 or 1 table.insert(curBIData.data, msg) end private[BIManager.BIType.ChangAnSiegeChongceArrive] = function(arriveFrame) if curBIData == nil then curBIData = bi_pb.CBILog() TimerUtil.TimeOut(Send) end local msg = private.CreateBIData() msg.siegeCityData.arriveTime = math.floor(arriveFrame / 20 + 0.5) table.insert(curBIData.data, msg) end function private.SendPlayerOnlineTime() if private.playerOnlineTime <= PlayerOnlineTimeSendLimit then return end if curBIData == nil then curBIData = bi_pb.CBILog() TimerUtil.TimeOut(Send) end local msg = private.CreateBIData() msg.onlineTimeData.onlineTime = private.playerOnlineTime table.insert(curBIData.data, msg) private.playerOnlineTime = 0 -- 每上传一次就清空下当前统计的时长 end private[BIManager.BIType.PlayerOnlineTime] = private.SendPlayerOnlineTime function BIManager.SendTotalNetMsgStatistics(sendCount, receiveCount, delayCount, timeoutCount) --local context = private.ToDetailJsonStr("event_name", "NetMessageTotalStatistics", "NetSendMsgCount", sendCount, "NetReceiveCount", receiveCount, "NetDelayCount",delayCount, "NetTimeoutCount", timeoutCount) --if GameAppInfo.IsVersionGreaterThan18000() then -- if GameAppInfo.IsChinesePackage() then -- if GameAppInfo.IsVersionGreaterThan19000() then -- SDKUtil.SendCustomEvent(context, 0) -- else -- SDKUtil.SendCustomEvent(context) -- end -- else -- SDKUtil.SendCustomEvent(context, 0) -- end --else -- SDKUtil.SendCustomEvent(context) --end end function BIManager.ReportSingleNetMsgStatistics(msgId, sendCount, receiveCount, delayCount, timeoutCount) -- 这个会埋点到三方后台,越南自己的后台不要这个数据 if GameAppInfo.IsVietnamPackage() then return end local msgIdStr = tostring(msgId) local SDK_SendBatchCustomEvent = SDKUtil.SendBatchCustomEvent if sendCount > 0 then -- local context = private.ToDetailJsonStr("event_name","NetMessageSendStatistics", "SendMsgId", msgIdStr) -- SDK_SendBatchCustomEvent(context, sendCount) end if receiveCount > 0 then -- local context = private.ToDetailJsonStr("event_name","NetMessageReceiveStatistics", "ReceiveMsgId", msgIdStr) -- SDK_SendBatchCustomEvent(context, receiveCount) end if delayCount and delayCount > 0 then -- local context = private.ToDetailJsonStr("event_name","NetMessageDelayStatistics", "DelayMsgId", msgIdStr) -- SDK_SendBatchCustomEvent(context, delayCount) HttpNetMsgManager.SendNetMsgDelayToServer(msgId, delayCount, 1) end if timeoutCount and timeoutCount > 0 then -- local context = private.ToDetailJsonStr("event_name","NetMessageTimeoutStatistics", "TimeOutMsgId", msgIdStr) -- SDK_SendBatchCustomEvent(context, timeoutCount) HttpNetMsgManager.SendNetMsgDelayToServer(msgId, timeoutCount, 2) end end local jsonParamTable = {} local jsonParamHashTable = {} function private.ToJsonStr(...) local nArgs = LuaExt.ResetTable(jsonParamTable,...) if nArgs <= 0 then return "" end table.clear(jsonParamHashTable) for i=1,#jsonParamTable,2 do jsonParamHashTable[jsonParamTable[i]] = jsonParamTable[i+1] end return JSON.encode(jsonParamHashTable) end function private.ToDetailJsonStr(...) local nArgs = LuaExt.ResetTable(jsonParamTable,...) if nArgs <= 0 then return "" end table.clear(jsonParamHashTable) for i=1,#jsonParamTable,2 do jsonParamHashTable[jsonParamTable[i]] = jsonParamTable[i+1] end local defaultValue = "0" if MDL and MDL.Player then jsonParamHashTable["role_id"] = MDL.Player.GetRoleId() or defaultValue jsonParamHashTable["role_key"] = BattleDataGetter.GetAcID() or defaultValue else jsonParamHashTable["role_id"] = defaultValue jsonParamHashTable["role_key"] = defaultValue end if MDL and MDL.Login.GetServerId() then jsonParamHashTable["server_id"] = MDL.Login.GetServerId() or defaultValue else jsonParamHashTable["server_id"] = defaultValue end if UNITY_IOS and GameAppInfo.IsChinesePackage() then jsonParamHashTable["user_id"] = SDKUtil.HeroUserId or defaultValue else jsonParamHashTable["user_id"] = defaultValue end local str = JSON.encode(jsonParamHashTable) return str end function BIManager.RecordNoBattleLevelPlayerCount(playerCount) levelData.noBattleLevelPlayerCount = playerCount end function BIManager.OnLowMemoryCallback() levelData.lowMemoryCount = levelData.lowMemoryCount + 1 end --tcpState 0:正常 1、断开 2、重连 --disConnectCode:NetManager.DisconnectReason function private.SendNetExceptionBI(tcpState, kcpState, disConnectCode) if LevelManager then local levelID = LevelManager.GetCurLevelID() local battleId = private.battleID or "" local battleServerId = BattleDataGetter.GetBattleServerID() HttpBIManager.SendNetExceptionBI("NetException", tcpState, kcpState, disConnectCode, levelID, battleId, battleServerId) else HttpBIManager.SendNetExceptionBI("NetException", tcpState, kcpState, disConnectCode) end end function BIManager.ReInitBIChannelID() private.InitBIChannelID() end function private.InitBIChannelID() local channelID = SDKUtil.ChannelID if HeroAndroidChannelID == channelID then local subChannelID = SDKUtil.SubChannelID if (not string.isNilOrEmpty(subChannelID)) and subChannelID ~= "0" then channelID = subChannelID end end BIChannelID = channelID end function BIManager.GetBIChannelID() return BIChannelID end local BI_SENDSTATE_KEY = "BISENDKEY" function private.SendOnlyOnceBIEvent(BIEventID, eventKey) if string.isNilOrEmpty(eventKey) or string.isNilOrEmpty(BIEventID) then return end local saveTb = PersistentData.PlayerData:Get(BI_SENDSTATE_KEY) or private.BI_SendState if not saveTb[eventKey] then EventSystem.Dispatch(BIEventID, eventKey) saveTb[eventKey] = true PersistentData.PlayerData:Set(BI_SENDSTATE_KEY, saveTb, true) end end local BI_SENDSTATE_VN_KEY = "BI_SENDSTATE_VN_KEY" function private.SendOnlyOnceBIEventVN(BIEventID, eventKey, eventContent) if string.isNilOrEmpty(eventKey) or string.isNilOrEmpty(BIEventID) or string.isNilOrEmpty(eventContent) then return end local saveTb = PersistentData.PlayerData:Get(BI_SENDSTATE_VN_KEY) or private.BI_SendState if not saveTb[eventContent] then EventSystem.Dispatch(BIEventID, eventKey, eventContent) saveTb[eventContent] = true PersistentData.PlayerData:Set(BI_SENDSTATE_VN_KEY, saveTb, true) end end function private.OnUIViewBtnClick(ID, ...) local eventEnum = BIManager.ViewBIEvent if ViewBIEventToOnceEventName[ID] then private.SendOnlyOnceBIEventVN(EventID.BI_ClientEvent, BIManager.EventName.user_like_, "rescue") private.SendOnlyOnceBIEvent(EventID.BI_ClientEvent, ViewBIEventToOnceEventName[ID]) elseif ViewBIEventToEventName[ID] then BIManager.DispatchBIClientEvent(ViewBIEventToEventName[ID]) else if ID == eventEnum.UILevelSelectMainPanel_event_Attack then local levelID = ... private.OnClickStartAttackLevel(levelID) elseif ID == eventEnum.UITownTaskGuide_Cell then local mainID, childID = ... private.StartTaskBIEvent(mainID, childID) end end end function private.StartTaskBIEvent(mainID, childID) --越南新增一个特殊处理,触发首次引导的时候需要埋点 if GameAppInfo.IsVietnamPackage()then if mainID == 110100 and childID == 1 then private.SendOnlyOnceBIEventVN(EventID.BI_ClientEvent, BIManager.EventName.user_like_, "garden") end else if BITaskClickEventID[mainID] and BITaskClickEventID[mainID][childID] then private.SendOnlyOnceBIEvent(EventID.BI_ClientEvent, BITaskClickEventID[mainID][childID]) end end end function private.FinishFubenSmallAPKEvent(curLevelID) if DEF.USE_SMALL_APK then local eventName = SmallAPKBarrierLevelId[curLevelID] if eventName then if curLevelID == CHAPTER_LEVEL_ID_1_1 then local pack_129_isDone if CTL.HotFix.Get_IfAllDownload() then pack_129_isDone = 1 -- 防止 LoginProxy.GetCurStage() 报错 BIManager.DispatchBIClientEvent(eventName, "curStage", LoginProxy.GetCurStage(), "pack_129_isDone", pack_129_isDone) else pack_129_isDone = LoginProxy.GetCurStage() > 129 and 1 or 0 BIManager.DispatchBIClientEvent(eventName, "curStage", LoginProxy.GetCurStage(), "pack_129_isDone", pack_129_isDone) end elseif curLevelID == CHAPTER_LEVEL_ID_1_2 then local pack_199_isDone = LoginProxy.GetCurStage() >= 199 and 1 or 0 BIManager.DispatchBIClientEvent(eventName, "curStage", LoginProxy.GetCurStage(), "pack_199_isDone", pack_199_isDone) end end end end function private.OnFinishFubenEvent(curLevelID, starNum) if BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.NORMAL) then if SpecificBarrierLevelId[curLevelID] and starNum == 0 then BIManager.DispatchBIClientEvent(SpecificBarrierLevelId[curLevelID]) end private.FinishFubenSmallAPKEvent(curLevelID) elseif BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.Biography) then if curLevelID == 101 and starNum == 0 then BIManager.DispatchBIClientEvent(BIManager.EventName.HeroBiographyFinish) end elseif BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.ClimbTower) then BIManager.DispatchBIClientEvent(BIManager.EventName.ClimbTowerFinish) elseif BattleDataGetter.CheckCurLevelType(LuaConst.LevelType.BossChallenge) then BIManager.DispatchBIClientEvent(BIManager.EventName.BossChallengeFinish) end end function private.OnClickStartAttackLevel(levelID) private.SendOnlyOnceBIEvent(EventID.BI_ClientEvent, AttackLevelID[levelID]) end function private.OnReachLevel(level) if level then if GameAppInfo.IsVietnamPackage() then private.SendOnlyOnceBIEventVN(EventID.BI_ClientEvent, BIManager.EventName.user_level_, level) else for targetLv, eventKey in pairs(TeamLevelEvent) do if level >= targetLv then private.SendOnlyOnceBIEvent(EventID.BI_ClientEvent, eventKey) end end end end end function private.OnReachGSEvent() local curGS = MDL.Player.GetLineUpGs() for targetGs, eventKey in pairs(TotalBREvent) do if curGS >= targetGs then private.SendOnlyOnceBIEvent(EventID.BI_ClientEvent, eventKey) end end end function private.OnUnlockHero() local heroTotalCount = MDL.HeroSelect.GetHasHeroCount() -- 武将解锁数量 if HeroCountEvent[heroTotalCount] then private.SendOnlyOnceBIEvent(EventID.BI_ClientEvent, HeroCountEvent[heroTotalCount]) end end function private.SendItemUseBIEvent(cfgID) if cfgID == 100001 or cfgID == 100002 then -- 武将自选礼包 BIManager.DispatchBIClientEvent(BIManager.EventName.CollectHeroReward_0) end end function private.OnFirstJoinGuildEvent() private.SendOnlyOnceBIEvent(EventID.BI_ClientEvent, BIManager.EventName.FirstJoinedGuild) end function private.OnFinishGuide(id) if id == 30012 then BIManager.DispatchBIClientEvent(BIManager.EventName.TutorialEnd) elseif id == 12 then BIManager.DispatchBIClientEvent(BIManager.EventName.Gacha) end end function private.OnApplicationPause(pause) if pause then private.RecordGameRunning(false) else private.RecordGameRunning(true) end if pause then private.SendPlayerOnlineTime() end private.playerOnlineTimeIsPause = pause end function private.OnApplicationQuit() private.RecordGameRunning(false) end function private.RecordGameRunning(gameRunning) if UNITY_EDITOR or USE_LUA_STANDALONE then return end if gameRunning then LuaExt.FileWriteText("IsGameRunning", "") else LuaExt.FileDelete("IsGameRunning") end end function private.GameLaunch() if UNITY_EDITOR or USE_LUA_STANDALONE then return end private.SendSuspectedCrash() --这里不能替换成os.date(UTL.Time.FormatDateEnum.YMDHMS 因为 UTL.Time还没加载初始化 local timeStr = os.date("%Y/%m/%d %H:%M:%S", os.time()) local jsonTable = {["lastSceneName"] = "", ["clienttime"] = timeStr} local str = JSON.encode(jsonTable) LuaExt.FileWriteText("LastSceneInfo", str) private.RecordGameRunning(true) end function private.RecordBeginLevel() if LEVEL_ID_1_2 == BattleDataGetter.GetCurLevelID() and DEF.USE_SMALL_APK then BIManager.DispatchBIClientEvent(BIManager.EventName.StartLevel102, "curStage", LoginProxy.GetCurStage()) end if UNITY_EDITOR or USE_LUA_STANDALONE then return end local levelName = LevelManager ~= nil and LevelManager.GetCurLevelName() or "" local timeStr = os.date(UTL.Time.FormatDateEnum.YMDHMS, os.time()) local jsonTable = {["lastSceneName"] = levelName, ["clienttime"] = timeStr} local str = JSON.encode(jsonTable) LuaExt.FileWriteText("LastSceneInfo", str) end function private.SendSuspectedCrash() if UNITY_EDITOR or USE_LUA_STANDALONE then return end if LuaExt.FileExists("IsGameRunning") then local str = LuaExt.FileReadText("LastSceneInfo") local lastSceneName, clientTime = "", "" if str ~= nil then local jsonTable = JSON.decode(str) lastSceneName = jsonTable["lastSceneName"] clientTime = jsonTable["clienttime"] end private.SendWithDetailEncode(BIManager.EventName.SuspectedCrash, "lastSceneName", lastSceneName, "clienttime", clientTime) end end function BIManager.OnUncompressInternalFinish() bi_pb = require("Proto/bi_pb") end function private.ToKeyValueStr(...) local count = select('#',...) if count >= 2 then table.clear(toKeyValueStrTable) for i = 1, count ,2 do local key = select(i,...) local value = select(i+1,...) if value then table.insert(toKeyValueStrTable, string.format("%s=%s",key, value)) end end return table.concat(toKeyValueStrTable, ", ") elseif count == 1 then logging.error(LTAG.ERROR, "埋点额外参数个数为1") return "" else return "" end end local CriticalReportCount = 10 --达到次数后上报 local CriticalReportInterval = 5 --打点时间间隔 BIManager.CriticalReportType = { AssetNotIncluded = 1, --资源没进包 UpdateFileDownloadFail = 2, --文件下载失败 UpdateFileCheckFail = 3, --下载校验失败 } BIManager.CriticalReportStep = { [BIManager.CriticalReportType.AssetNotIncluded] = "CriticalReport_AssetNotIncluded", [BIManager.CriticalReportType.UpdateFileDownloadFail] = "CriticalReport_UpdateFileDownloadFail", [BIManager.CriticalReportType.UpdateFileCheckFail] = "CriticalReport_UpdateFileCheckFail", } --统计失败次数 private.criticalReportDict = { [BIManager.CriticalReportType.AssetNotIncluded] = {}, [BIManager.CriticalReportType.UpdateFileDownloadFail] = {}, [BIManager.CriticalReportType.UpdateFileCheckFail] = {}, } function BIManager.HandleCriticalReport(type, ...) local filePath, errorCode = ... if errorCode then filePath = filePath .. ":" .. errorCode end local count = private.criticalReportDict[type][filePath] if count then private.criticalReportDict[type][filePath] = count + 1 else private.criticalReportDict[type][filePath] = 1 end if private.timerCriticalReport then TimerUtil.Remove(private.timerCriticalReport) end local sumCount = 0 for _, count in pairs(private.criticalReportDict[type]) do sumCount = sumCount + count end if sumCount >= CriticalReportCount then private.SendCriticalReport(type) else private.timerCriticalReport = TimerUtil.Interval(private.TimeToSendCriticalReport, CriticalReportInterval, 1) end end function private.TimeToSendCriticalReport() for type, v in pairs(private.criticalReportDict) do private.SendCriticalReport(type) end TimerUtil.Remove(private.timerCriticalReport) private.timerCriticalReport = nil end function private.SendCriticalReport(type) local sumCount = 0 table.clear(toKeyValueStrTable) for path, count in pairs(private.criticalReportDict[type]) do sumCount = sumCount + count table.insert(toKeyValueStrTable, string.format("%s=%s", path, count)) end if sumCount > 0 then local content = table.concat(toKeyValueStrTable, ", ") local step = BIManager.CriticalReportStep[type] HttpBIManager.SendDownloadEvent(step, content, sumCount) logging.crit(LTAG.CRIT, "SendCriticalReport", step, content, sumCount) table.clear(private.criticalReportDict[type]) end end return BIManager