koishi-plugin-ets2-tools-tmp 2.3.0 → 2.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/lib/api/evmOpenApi.js +138 -1
  2. package/lib/api/truckersMpApi.js +133 -1
  3. package/lib/api/truckersMpMapApi.js +25 -1
  4. package/lib/api/truckyAppApi.js +48 -1
  5. package/lib/command/ets-app/queryPoint.js +96 -1
  6. package/lib/command/ets-app/resetPassword.js +270 -1
  7. package/lib/command/tmpActivityService.js +603 -1
  8. package/lib/command/tmpBind.js +19 -1
  9. package/lib/command/tmpDlcMap.js +33 -1
  10. package/lib/command/tmpFootprint.js +109 -1
  11. package/lib/command/tmpMileageRanking.js +55 -1
  12. package/lib/command/tmpPosition.js +123 -1
  13. package/lib/command/tmpQuery/tmpQuery.js +12 -1
  14. package/lib/command/tmpQuery/tmpQueryImg.js +103 -1
  15. package/lib/command/tmpQuery/tmpQueryText.js +196 -1
  16. package/lib/command/tmpServer.js +41 -1
  17. package/lib/command/tmpTraffic/tmpTraffic.js +15 -1
  18. package/lib/command/tmpTraffic/tmpTrafficMap.js +163 -1
  19. package/lib/command/tmpTraffic/tmpTrafficText.js +60 -1
  20. package/lib/command/tmpVersion.js +14 -1
  21. package/lib/command/tmpVtc.js +29 -1
  22. package/lib/database/guildBind.js +41 -1
  23. package/lib/database/model.js +65 -1
  24. package/lib/database/translateCache.js +31 -1
  25. package/lib/index.js +332 -1
  26. package/lib/resource/dlc.html +1 -1
  27. package/lib/resource/footprint.html +1 -1
  28. package/lib/resource/package/ets-map.js +63 -1
  29. package/lib/resource/package/leaflet/heatmap.min.js +9 -1
  30. package/lib/resource/package/leaflet/leaflet-heatmap.js +246 -1
  31. package/lib/resource/position.html +1 -1
  32. package/lib/resource/traffic.html +1 -1
  33. package/lib/util/baiduTranslate.js +24 -1
  34. package/lib/util/common.js +5 -1
  35. package/lib/util/constant.js +36 -1
  36. package/package.json +1 -1
@@ -1 +1,603 @@
1
- function _0x1b63(_0x30cfb4,_0x511092){const _0x51e9fd=_0x3b33();return _0x1b63=function(_0x5a38d1,_0x564e25){_0x5a38d1=_0x5a38d1-0x137;let _0xc2c24c=_0x51e9fd[_0x5a38d1];return _0xc2c24c;},_0x1b63(_0x30cfb4,_0x511092);}const _0x37e7cf=_0x1b63;(function(_0x2c939c,_0x56482d){const _0x4dcf70=_0x1b63,_0x5e72e3=_0x2c939c();while(!![]){try{const _0x1aa3a8=-parseInt(_0x4dcf70(0x19e))/0x1+-parseInt(_0x4dcf70(0x205))/0x2+parseInt(_0x4dcf70(0x15a))/0x3*(-parseInt(_0x4dcf70(0x138))/0x4)+parseInt(_0x4dcf70(0x206))/0x5+parseInt(_0x4dcf70(0x23a))/0x6+-parseInt(_0x4dcf70(0x17f))/0x7*(parseInt(_0x4dcf70(0x248))/0x8)+parseInt(_0x4dcf70(0x1da))/0x9;if(_0x1aa3a8===_0x56482d)break;else _0x5e72e3['push'](_0x5e72e3['shift']());}catch(_0x50c303){_0x5e72e3['push'](_0x5e72e3['shift']());}}}(_0x3b33,0x4f7dc));const _0x1733ea=(function(){let _0xf876ce=!![];return function(_0x2a56c7,_0x553abf){const _0x28b321=_0xf876ce?function(){if(_0x553abf){const _0x4e1ce0=_0x553abf['apply'](_0x2a56c7,arguments);return _0x553abf=null,_0x4e1ce0;}}:function(){};return _0xf876ce=![],_0x28b321;};}()),_0x29454e=_0x1733ea(this,function(){const _0x235e9f=_0x1b63;return _0x29454e[_0x235e9f(0x237)]()[_0x235e9f(0x180)]('(((.+)+)+)+$')['toString']()[_0x235e9f(0x1fe)](_0x29454e)[_0x235e9f(0x180)](_0x235e9f(0x18f));});function _0x3b33(){const _0x2fd037=['开始更新活动数据','profileUploaded',',\x20日期:\x20','车队平台API响应耗时:\x20','今日没有活动,跳过档位检查','forEach','sendActivityReminder','活动数据更新完成,耗时:\x20','log','distance','sentReminders','已发送','message','设置每分钟检查定时器','未配置主群组ID\x20(mainGroup.groups为空),活动提醒将无法发送','wechat-official','✅\x20今日活动数据已重置完成!','admin','\x22\x20开始提醒已发送过,跳过','执行今日无活动通知任务\x20(','活动查询','未上传','发送消息到管理群组\x20','warn','all','\x20个活动提醒','主群组','mainGroup','trim','{}.constructor(\x22return\x20this\x22)(\x20)','name','replace','map','sentNoActivityNotification','\x20个\x0aTMP今日参与活动:\x20','add','https://','未知起点','\x20个活动的提醒时间,当前本地日期:\x20','logApiResponses','registerAdminCommands','departure','ms,\x20状态码:\x20','noActivity','console','3199293JvSlwY','day','[TMP-BOT\x20API]\x20','return\x20(function()\x20','\x22\x20剩余时间:\x20','手动测试','未知活动','checkAndSendProfileReminders','本轮未发送任何活动提醒','logActivityMatching','请求车队平台API:\x20','todayActivities','setupDailyTasks','timing','发送无活动通知到管理群组\x20','[活动更新]\x20所有活动日期:',',\x20触发条件:\x20-300\x20<=\x20','sendMessage','检查完成!\x0a车队平台今日活动:\x20','个,\x20TMP:\x20','[TMP活动更新]\x20跳过非今日活动:\x20','检查定时器\x20#','[活动更新]\x20跳过非今日活动:\x20','length','[TMP活动更新]\x20API返回活动总数:\x20','themeName','今日有活动(车队平台:\x20','setupTimer','手动检查今日活动','push','[活动更新]\x20API返回活动总数:\x20','触发活动开始提醒:\x20','处理活动\x20\x22','尝试通过\x20','sendActivityStartReminder','\x20个主群组:\x20','constructor','@全体成员\x0a','startPointSource','→0,\x20无活动通知','padStart','重置数据','table','578750MLGJoU','469700CyUxUx','initLogger','getDate','***','token','发送定时器\x20#','toLocaleString','city','个),不发送无活动通知','开始检查\x20','profileFile','[TMP活动更新]\x20请求TMP\x20API:\x20','执行每日数据重置','&page=1&limit=50&themeName=','now','https://api.truckersmp.com/v2/vtc/','checkAndSendNoActivityNotification','启动时立即更新活动数据','debugMode','timeLeft','[数据重置]\x20重置前数据:\x20活动','\x20分钟前','sendToGroup','所有适配器都无法发送消息到','分钟前提醒','本轮发送了\x20','cfg','活动\x20\x22','ctx','createActivityReplacements','已发送无活动通知到管理群组\x20',',\x20reminderTimeSeconds=','getMonth','response','\x20<=\x20','has','info','action','[TMP-BOT\x20TIMING]\x20','通过\x20',',\x20本地日期:\x20','[活动更新]\x20当前本地日期:\x20','活动档位检查:\x20\x22','没有可用的聊天平台适配器(当前不支持邮件/电报/Discord/QQ/微信公众号)','[数据重置]\x20每日数据已重置:\x20活动','已上传','timers','车队平台API响应详情:','matching','toString','__esModule','[TMP-BOT\x20DEBUG]\x20','2433522tjWXNL','手动重置今日活动数据','\x22\x20提醒失败:','updateActivityData','start','_started','command','platform','banner','\x20个活动的档位状态','code','[TMP活动更新]\x20TMP\x20API请求失败:未配置api.vtcId','toISOString','设置数据重置定时器:\x20','8antMqu','今日已发送过无活动通知,跳过','6708ptAGUi','logger','\x20适配器发送消息失败:\x20','ActivityService','\x22\x20未满足开始提醒条件,当前剩余\x20','到主群组\x20','检测到活动状态变化:之前无活动,现在有活动(车队平台:\x20','bots','检查\x20','floor','find','terminalPoint','serverSource','\x20失败:','已标记今日无活动通知为已发送','endPointSource','\x20个今日活动','sendTimes','tmp',',当前本地日期:\x20','→0,\x20提醒','执行定时检查任务\x20#','profileNotUploaded','time','\x20分\x20','resetDailyData','exception','minute','vtcId','[活动更新]\x20车队平台API返回错误:\x20','split','跳过非今日活动\x20\x22','http','debug','108QkMdGk','[数据重置]\x20重置后数据更新失败:','cleanup','未发送','data','\x20个适配器发送消息到','已配置\x20','ms,\x20错误状态:\x20','trace','→未发送','checkAndSendActivityReminders','\x20(代码:\x20','serverName','个,\x20无活动通知','getFullYear','\x22\x20开始时间格式错误,跳过提醒','server','activityReminderMessage','[数据重置]\x20重置后数据更新完成:\x20活动','活动匹配:\x20\x22','[TMP活动更新]\x20今日活动详情:',',\x20延迟:\x20','list','startingPoint','api','isArray','\x22\x20-\x20找到TMP匹配:\x20','触发活动前提醒:\x20','includes','catch','entries','filter','location','setDate','[TMP活动更新]\x20从TMP找到\x20','get','http://','730261HZgqhe','search','updateTodayActivities','手动执行数据重置命令',',\x20UTC日期:\x20','\x22\x20-\x20','分钟前提醒检查:\x20totalSecondsLeft=','个,\x20TMP','bind',',\x20条件:\x20','activityStartReminderMessage','[活动更新]\x20获取车队平台活动列表失败:','手动执行活动检查命令','url','\x20适配器发送消息到','已发送档位提醒到管理群组\x20','(((.+)+)+)+$','未知错误','logTimingDetails','startTime','groups','arrive','error','未知终点','clear','getNextTime','[TMP-BOT]\x20','[TMP活动更新]\x20获取TMP活动失败:','messages','插件卸载,开始清理资源','/api/activity/info/list?token=','75338rTPXZr','checkTimes','sendToMainGroups','__proto__',',\x20当前日期:\x20','discord','\x20-\x20','dataSource','Time','分钟前提醒已发送过,跳过','updateTodayTMPEvents','todayTMPEvents','个,\x20提醒','defineProperty','getTime'];_0x3b33=function(){return _0x2fd037;};return _0x3b33();}_0x29454e();const _0x564e25=(function(){let _0x61e1b9=!![];return function(_0x3b0cf1,_0x398898){const _0x31c07c=_0x61e1b9?function(){if(_0x398898){const _0x234471=_0x398898['apply'](_0x3b0cf1,arguments);return _0x398898=null,_0x234471;}}:function(){};return _0x61e1b9=![],_0x31c07c;};}()),_0x5a38d1=_0x564e25(this,function(){const _0x32aae4=_0x1b63;let _0x4cc570;try{const _0x446511=Function(_0x32aae4(0x1dd)+_0x32aae4(0x1ca)+');');_0x4cc570=_0x446511();}catch(_0x3dc564){_0x4cc570=window;}const _0x50d9f5=_0x4cc570[_0x32aae4(0x1d9)]=_0x4cc570[_0x32aae4(0x1d9)]||{},_0x3cbd53=[_0x32aae4(0x1b5),_0x32aae4(0x1c4),_0x32aae4(0x22a),_0x32aae4(0x195),_0x32aae4(0x152),_0x32aae4(0x204),_0x32aae4(0x162)];for(let _0x359543=0x0;_0x359543<_0x3cbd53[_0x32aae4(0x1f1)];_0x359543++){const _0x406614=_0x564e25['constructor']['prototype'][_0x32aae4(0x187)](_0x564e25),_0x3e8733=_0x3cbd53[_0x359543],_0x2e554b=_0x50d9f5[_0x3e8733]||_0x406614;_0x406614[_0x32aae4(0x1a1)]=_0x564e25[_0x32aae4(0x187)](_0x564e25),_0x406614['toString']=_0x2e554b['toString'][_0x32aae4(0x187)](_0x2e554b),_0x50d9f5[_0x3e8733]=_0x406614;}});_0x5a38d1();'use strict';Object[_0x37e7cf(0x1ab)](exports,_0x37e7cf(0x238),{'value':!![]}),exports[_0x37e7cf(0x13b)]=void 0x0;const koishi_1=require('koishi');class ActivityService{constructor(_0x32706e,_0x1f745f){const _0x5c45c8=_0x37e7cf;this[_0x5c45c8(0x222)]=_0x32706e,this['cfg']=_0x1f745f,this['todayActivities']=[],this[_0x5c45c8(0x1a9)]=[],this[_0x5c45c8(0x1b7)]=new Set(),this['sentNoActivityNotification']=![],this['timers']=[],this[_0x5c45c8(0x139)]=this[_0x5c45c8(0x207)]();}[_0x37e7cf(0x207)](){return{'debug':(_0x1dd418,..._0x51c9dc)=>{const _0x4405ba=_0x1b63;this[_0x4405ba(0x220)][_0x4405ba(0x218)]&&this[_0x4405ba(0x222)][_0x4405ba(0x139)]['debug'](_0x4405ba(0x239)+_0x1dd418,..._0x51c9dc);},'info':(_0x542167,..._0x241fbd)=>{const _0x20cc94=_0x1b63;this[_0x20cc94(0x222)][_0x20cc94(0x139)][_0x20cc94(0x22a)](_0x20cc94(0x199)+_0x542167,..._0x241fbd);},'warn':(_0x4768b0,..._0x52a4bb)=>{const _0x2262ed=_0x1b63;this[_0x2262ed(0x222)][_0x2262ed(0x139)][_0x2262ed(0x1c4)]('[TMP-BOT\x20WARN]\x20'+_0x4768b0,..._0x52a4bb);},'error':(_0x583589,..._0x468a7f)=>{const _0x309df3=_0x1b63;this[_0x309df3(0x222)][_0x309df3(0x139)][_0x309df3(0x195)]('[TMP-BOT\x20ERROR]\x20'+_0x583589,..._0x468a7f);},'api':(_0x1add58,_0xdbd84d)=>{const _0x64c11f=_0x1b63;this[_0x64c11f(0x220)]['debug']?.[_0x64c11f(0x1d4)]&&this[_0x64c11f(0x222)][_0x64c11f(0x139)]['info'](_0x64c11f(0x1dc)+_0x1add58,_0xdbd84d?JSON['stringify'](_0xdbd84d,null,0x2):'');},'timing':(_0x1ee073,_0xae198e)=>{const _0x5f29ac=_0x1b63;this[_0x5f29ac(0x220)]['debug']?.[_0x5f29ac(0x191)]&&this[_0x5f29ac(0x222)][_0x5f29ac(0x139)][_0x5f29ac(0x22a)](_0x5f29ac(0x22c)+_0x1ee073,_0xae198e||'');},'matching':(_0x30b083,_0x31b41a)=>{const _0x4e922f=_0x1b63;this[_0x4e922f(0x220)][_0x4e922f(0x159)]?.[_0x4e922f(0x1e3)]&&this[_0x4e922f(0x222)][_0x4e922f(0x139)][_0x4e922f(0x22a)]('[TMP-BOT\x20MATCHING]\x20'+_0x30b083,_0x31b41a||'');},'message':(_0x415b37,_0x257f4b)=>{const _0x347210=_0x1b63;this[_0x347210(0x220)][_0x347210(0x159)]?.['logMessageSending']&&this[_0x347210(0x222)][_0x347210(0x139)]['info']('[TMP-BOT\x20MESSAGE]\x20'+_0x415b37,_0x257f4b||'');}};}[_0x37e7cf(0x23e)](){const _0xe91738=_0x37e7cf;this[_0xe91738(0x1e6)](),this[_0xe91738(0x1d5)](),this[_0xe91738(0x222)]['on']('dispose',()=>this[_0xe91738(0x15c)]());}[_0x37e7cf(0x1d5)](){const _0xe549fd=_0x37e7cf;this[_0xe549fd(0x222)][_0xe549fd(0x240)](_0xe549fd(0x1c1),_0xe549fd(0x1f6))['action'](async()=>{const _0x1998b3=_0xe549fd;return this[_0x1998b3(0x139)][_0x1998b3(0x159)](_0x1998b3(0x18b)),await this[_0x1998b3(0x23d)](),_0x1998b3(0x1ec)+this[_0x1998b3(0x1e5)][_0x1998b3(0x1f1)]+_0x1998b3(0x1cf)+this[_0x1998b3(0x1a9)][_0x1998b3(0x1f1)]+'\x20个';}),this[_0xe549fd(0x222)]['command'](_0xe549fd(0x203),_0xe549fd(0x23b))[_0xe549fd(0x22b)](()=>{const _0x331caa=_0xe549fd;return this['logger']['debug'](_0x331caa(0x182)),this['resetDailyData'](),_0x331caa(0x1bd);});}[_0x37e7cf(0x1e6)](){const _0x2fb88b=_0x37e7cf,_0x491909=new Date(),_0x4a6889=_0x491909[_0x2fb88b(0x20c)](),_0x57b4b8=_0x491909[_0x2fb88b(0x168)]()+'-'+(_0x491909[_0x2fb88b(0x226)]()+0x1)[_0x2fb88b(0x237)]()[_0x2fb88b(0x202)](0x2,'0')+'-'+_0x491909['getDate']()[_0x2fb88b(0x237)]()[_0x2fb88b(0x202)](0x2,'0'),_0xefb5f7=_0x491909[_0x2fb88b(0x246)]()['split']('T')[0x0];this[_0x2fb88b(0x139)][_0x2fb88b(0x1e7)]('开始设置每日定时任务,本地时间:\x20'+_0x4a6889+_0x2fb88b(0x22e)+_0x57b4b8+_0x2fb88b(0x183)+_0xefb5f7);const _0x142c76=0x2,_0x3ac486=0x0,_0x299088=this[_0x2fb88b(0x198)](_0x142c76,_0x3ac486),_0x26145d=setTimeout(()=>{const _0x45927c=_0x2fb88b;this[_0x45927c(0x139)][_0x45927c(0x1e7)](_0x45927c(0x212)),this[_0x45927c(0x151)]();const _0x54030b=setInterval(()=>{const _0x1c6f52=_0x45927c;this[_0x1c6f52(0x139)][_0x1c6f52(0x1e7)](_0x1c6f52(0x212)),this['resetDailyData']();},koishi_1[_0x45927c(0x1a6)][_0x45927c(0x1db)]);this['timers']['push'](_0x54030b);},_0x299088);this['timers'][_0x2fb88b(0x1f7)](_0x26145d),this[_0x2fb88b(0x139)][_0x2fb88b(0x1e7)](_0x2fb88b(0x247)+_0x142c76+':'+_0x3ac486[_0x2fb88b(0x237)]()[_0x2fb88b(0x202)](0x2,'0')+_0x2fb88b(0x16f)+_0x299088+'ms'),this['cfg'][_0x2fb88b(0x1be)][_0x2fb88b(0x19f)][_0x2fb88b(0x1b2)]((_0x583baa,_0x1003df)=>{const _0x1ad111=_0x2fb88b,[_0x7f5b34,_0x5982b4]=_0x583baa[_0x1ad111(0x156)](':')[_0x1ad111(0x1cd)](Number);this[_0x1ad111(0x1f5)](_0x7f5b34,_0x5982b4,async()=>{const _0x6cd3cc=_0x1ad111;this[_0x6cd3cc(0x139)][_0x6cd3cc(0x1e7)](_0x6cd3cc(0x14d)+(_0x1003df+0x1)+'\x20('+_0x583baa+')'),await this['updateActivityData'](),await this['checkActivityStatusChange']();},_0x1ad111(0x1ef)+(_0x1003df+0x1)+':\x20'+_0x583baa);}),this['cfg'][_0x2fb88b(0x1be)][_0x2fb88b(0x149)][_0x2fb88b(0x1b2)]((_0x5adc52,_0x277e53)=>{const _0x2fe529=_0x2fb88b,[_0x1c2e4e,_0x4dc32a]=_0x5adc52[_0x2fe529(0x156)](':')[_0x2fe529(0x1cd)](Number);this[_0x2fe529(0x1f5)](_0x1c2e4e,_0x4dc32a,async()=>{const _0x3c8664=_0x2fe529;this[_0x3c8664(0x139)][_0x3c8664(0x1e7)]('执行定时发送任务\x20#'+(_0x277e53+0x1)+'\x20('+_0x5adc52+')'),await this[_0x3c8664(0x1e1)]();},_0x2fe529(0x20b)+(_0x277e53+0x1)+':\x20'+_0x5adc52);});if(this[_0x2fb88b(0x220)]['noActivity']?.['enable']){const [_0x3ab86c,_0x18f55c]=this[_0x2fb88b(0x220)][_0x2fb88b(0x1d8)][_0x2fb88b(0x14f)]['split'](':')[_0x2fb88b(0x1cd)](Number);this[_0x2fb88b(0x1f5)](_0x3ab86c,_0x18f55c,()=>{const _0xfd1342=_0x2fb88b;this[_0xfd1342(0x139)][_0xfd1342(0x1e7)](_0xfd1342(0x1c0)+this[_0xfd1342(0x220)][_0xfd1342(0x1d8)][_0xfd1342(0x14f)]+')'),this[_0xfd1342(0x216)]();},'无活动通知定时器:\x20'+this[_0x2fb88b(0x220)][_0x2fb88b(0x1d8)]['time']);}const _0x3098df=setInterval(async()=>{const _0x33aa71=_0x2fb88b;await this[_0x33aa71(0x164)]();},koishi_1[_0x2fb88b(0x1a6)][_0x2fb88b(0x153)]);this[_0x2fb88b(0x234)]['push'](_0x3098df),this['logger']['timing'](_0x2fb88b(0x1ba)),this[_0x2fb88b(0x139)][_0x2fb88b(0x159)](_0x2fb88b(0x217)),this[_0x2fb88b(0x23d)]();}[_0x37e7cf(0x1f5)](_0x2e5be5,_0x242f1d,_0x25c8c5,_0x1dcafd){const _0x37bcd0=_0x37e7cf,_0x3d17a0=this[_0x37bcd0(0x198)](_0x2e5be5,_0x242f1d),_0x31cd56=setTimeout(()=>{const _0x5c12b9=_0x37bcd0;_0x25c8c5();const _0x33f59e=setInterval(_0x25c8c5,koishi_1['Time'][_0x5c12b9(0x1db)]);this[_0x5c12b9(0x234)][_0x5c12b9(0x1f7)](_0x33f59e);},_0x3d17a0);this['timers']['push'](_0x31cd56),this['logger'][_0x37bcd0(0x1e7)](_0x1dcafd+_0x37bcd0(0x16f)+_0x3d17a0+'ms');}[_0x37e7cf(0x198)](_0x204f10,_0x4caeb8){const _0x3ee113=_0x37e7cf,_0x5e299f=new Date(),_0x1b6e1a=new Date(_0x5e299f['getFullYear'](),_0x5e299f['getMonth'](),_0x5e299f['getDate'](),_0x204f10,_0x4caeb8,0x0,0x0);return _0x1b6e1a[_0x3ee113(0x1ac)]()<=_0x5e299f[_0x3ee113(0x1ac)]()&&_0x1b6e1a[_0x3ee113(0x17b)](_0x1b6e1a['getDate']()+0x1),_0x1b6e1a[_0x3ee113(0x1ac)]()-_0x5e299f['getTime']();}[_0x37e7cf(0x151)](){const _0x78ebf3=_0x37e7cf,_0x2e2d99=new Date(),_0x17bf5e=_0x2e2d99[_0x78ebf3(0x20c)](),_0x65b85f=_0x2e2d99[_0x78ebf3(0x168)]()+'-'+(_0x2e2d99['getMonth']()+0x1)[_0x78ebf3(0x237)]()[_0x78ebf3(0x202)](0x2,'0')+'-'+_0x2e2d99[_0x78ebf3(0x208)]()[_0x78ebf3(0x237)]()['padStart'](0x2,'0'),_0x1d135d=_0x2e2d99['toISOString']()[_0x78ebf3(0x156)]('T')[0x0],_0x34841b=this[_0x78ebf3(0x1e5)][_0x78ebf3(0x1f1)],_0x2de398=this[_0x78ebf3(0x1a9)][_0x78ebf3(0x1f1)],_0x123039=this['sentReminders']['size'],_0x302fed=this['sentNoActivityNotification'];this[_0x78ebf3(0x139)][_0x78ebf3(0x22a)]('[数据重置]\x20开始重置数据,本地时间:\x20'+_0x17bf5e+_0x78ebf3(0x22e)+_0x65b85f+_0x78ebf3(0x183)+_0x1d135d),this[_0x78ebf3(0x139)]['info'](_0x78ebf3(0x21a)+_0x34841b+_0x78ebf3(0x186)+_0x2de398+_0x78ebf3(0x1aa)+_0x123039+_0x78ebf3(0x167)+(_0x302fed?'已发送':'未发送')),this[_0x78ebf3(0x1e5)]=[],this[_0x78ebf3(0x1a9)]=[],this[_0x78ebf3(0x1b7)][_0x78ebf3(0x197)](),this['sentNoActivityNotification']=![],this[_0x78ebf3(0x139)][_0x78ebf3(0x22a)](_0x78ebf3(0x232)+_0x34841b+'→0,\x20TMP'+_0x2de398+_0x78ebf3(0x14c)+_0x123039+_0x78ebf3(0x201)+(_0x302fed?_0x78ebf3(0x1b8):_0x78ebf3(0x15d))+_0x78ebf3(0x163)),this[_0x78ebf3(0x23d)]()['then'](()=>{const _0x2dddae=_0x78ebf3;this[_0x2dddae(0x139)]['info'](_0x2dddae(0x16c)+this[_0x2dddae(0x1e5)][_0x2dddae(0x1f1)]+_0x2dddae(0x186)+this[_0x2dddae(0x1a9)][_0x2dddae(0x1f1)]+'个');})[_0x78ebf3(0x177)](_0x5d54fd=>{const _0x222cc1=_0x78ebf3;this[_0x222cc1(0x139)][_0x222cc1(0x195)](_0x222cc1(0x15b),_0x5d54fd[_0x222cc1(0x1b9)]);});}async[_0x37e7cf(0x23d)](){const _0x511dca=_0x37e7cf;try{this[_0x511dca(0x139)][_0x511dca(0x159)](_0x511dca(0x1ad));const _0x59dbd5=Date[_0x511dca(0x214)]();await Promise[_0x511dca(0x1c5)]([this[_0x511dca(0x181)](),this['updateTodayTMPEvents']()]);const _0x196ba3=Date[_0x511dca(0x214)]()-_0x59dbd5;this[_0x511dca(0x139)][_0x511dca(0x22a)](_0x511dca(0x1b4)+_0x196ba3+'ms'),this[_0x511dca(0x139)][_0x511dca(0x159)]('今日活动数量:\x20'+this['todayActivities']['length']+',\x20TMP活动数量:\x20'+this[_0x511dca(0x1a9)][_0x511dca(0x1f1)]);}catch(_0x160497){this[_0x511dca(0x139)]['error']('更新活动数据失败:',_0x160497['message']);}}async[_0x37e7cf(0x181)](){const _0x1f9e39=_0x37e7cf;try{this[_0x1f9e39(0x1e5)]=[];const _0x258ba8=this['cfg'][_0x1f9e39(0x172)]['useHttps']?_0x1f9e39(0x1d1):_0x1f9e39(0x17e),_0x451496=''+_0x258ba8+this['cfg']['api'][_0x1f9e39(0x18c)]+_0x1f9e39(0x19d)+this[_0x1f9e39(0x220)]['api'][_0x1f9e39(0x20a)]+_0x1f9e39(0x213);this[_0x1f9e39(0x139)][_0x1f9e39(0x172)](_0x1f9e39(0x1e4)+_0x451496[_0x1f9e39(0x1cc)](this[_0x1f9e39(0x220)][_0x1f9e39(0x172)]['token'],_0x1f9e39(0x209)));const _0x456405=Date[_0x1f9e39(0x214)](),_0x3ccabf=await this[_0x1f9e39(0x222)][_0x1f9e39(0x158)][_0x1f9e39(0x17d)](_0x451496,{'timeout':0x2710}),_0x593b9c=Date[_0x1f9e39(0x214)]()-_0x456405;this[_0x1f9e39(0x139)]['api'](_0x1f9e39(0x1b0)+_0x593b9c+_0x1f9e39(0x1d7)+_0x3ccabf[_0x1f9e39(0x244)]);this[_0x1f9e39(0x220)][_0x1f9e39(0x159)]?.[_0x1f9e39(0x1d4)]&&this[_0x1f9e39(0x139)][_0x1f9e39(0x172)](_0x1f9e39(0x235),{'code':_0x3ccabf[_0x1f9e39(0x244)],'totalCount':_0x3ccabf[_0x1f9e39(0x15e)]?.['totalCount'],'listCount':_0x3ccabf['data']?.['list']?.[_0x1f9e39(0x1f1)]});if(_0x3ccabf[_0x1f9e39(0x244)]===0x0&&_0x3ccabf[_0x1f9e39(0x15e)]?.[_0x1f9e39(0x170)]){const _0x3786f6=new Date(),_0x322e42=_0x3786f6['getFullYear']()+'-'+(_0x3786f6['getMonth']()+0x1)[_0x1f9e39(0x237)]()[_0x1f9e39(0x202)](0x2,'0')+'-'+_0x3786f6['getDate']()[_0x1f9e39(0x237)]()[_0x1f9e39(0x202)](0x2,'0');this['logger']['debug'](_0x1f9e39(0x22f)+_0x322e42+_0x1f9e39(0x183)+new Date()[_0x1f9e39(0x246)]()[_0x1f9e39(0x156)]('T')[0x0]);const _0x3c9e58=_0x3ccabf['data']['list'][_0x1f9e39(0x1f1)];this[_0x1f9e39(0x139)][_0x1f9e39(0x159)](_0x1f9e39(0x1f8)+_0x3c9e58);if(this['cfg'][_0x1f9e39(0x159)]?.['debugMode']&&_0x3c9e58>0x0){const _0x5b6fc5=_0x3ccabf[_0x1f9e39(0x15e)][_0x1f9e39(0x170)][_0x1f9e39(0x1cd)](_0x303b8e=>_0x303b8e[_0x1f9e39(0x1f3)]+':\x20'+_0x303b8e['startTime']?.['split']('\x20')[0x0]);this[_0x1f9e39(0x139)]['debug'](_0x1f9e39(0x1e9),_0x5b6fc5);}this['todayActivities']=_0x3ccabf['data'][_0x1f9e39(0x170)]['filter'](_0x4b890b=>{const _0x5157d2=_0x1f9e39,_0xc6184e=_0x4b890b['startTime']?.[_0x5157d2(0x156)]('\x20')[0x0],_0x375a46=_0xc6184e===_0x322e42;return!_0x375a46&&this[_0x5157d2(0x220)][_0x5157d2(0x159)]?.[_0x5157d2(0x218)]&&this[_0x5157d2(0x139)][_0x5157d2(0x159)](_0x5157d2(0x1f0)+_0x4b890b[_0x5157d2(0x1f3)]+_0x5157d2(0x1af)+_0xc6184e+_0x5157d2(0x1a2)+_0x322e42),_0x375a46;}),this[_0x1f9e39(0x139)][_0x1f9e39(0x22a)]('[活动更新]\x20从车队平台找到\x20'+this[_0x1f9e39(0x1e5)][_0x1f9e39(0x1f1)]+'/'+_0x3c9e58+_0x1f9e39(0x148));if(this[_0x1f9e39(0x220)]['debug']?.[_0x1f9e39(0x218)]&&this[_0x1f9e39(0x1e5)][_0x1f9e39(0x1f1)]>0x0){const _0x2bb950=this[_0x1f9e39(0x1e5)][_0x1f9e39(0x1cd)](_0x418b75=>_0x418b75[_0x1f9e39(0x1f3)]+':\x20'+_0x418b75['startTime']);this['logger']['debug']('[活动更新]\x20今日活动详情:',_0x2bb950);}}else this[_0x1f9e39(0x139)][_0x1f9e39(0x195)](_0x1f9e39(0x155)+(_0x3ccabf['msg']||_0x1f9e39(0x190))+_0x1f9e39(0x165)+(_0x3ccabf[_0x1f9e39(0x244)]||'无')+')'),this[_0x1f9e39(0x1e5)]=[];}catch(_0x86a2cc){this[_0x1f9e39(0x139)][_0x1f9e39(0x195)](_0x1f9e39(0x18a),_0x86a2cc['message']),this[_0x1f9e39(0x1e5)]=[];}}async[_0x37e7cf(0x1a8)](){const _0x110808=_0x37e7cf;try{this[_0x110808(0x1a9)]=[];if(!this[_0x110808(0x220)][_0x110808(0x172)][_0x110808(0x154)]){this[_0x110808(0x139)]['warn'](_0x110808(0x245));return;}const _0xb419dc=_0x110808(0x215)+this[_0x110808(0x220)][_0x110808(0x172)][_0x110808(0x154)]+'/events/attending/';this['logger'][_0x110808(0x172)](_0x110808(0x211)+_0xb419dc);const _0x27b88c=Date[_0x110808(0x214)](),_0x284a88=await this[_0x110808(0x222)][_0x110808(0x158)][_0x110808(0x17d)](_0xb419dc,{'timeout':0x2710}),_0x2dfa1c=Date[_0x110808(0x214)]()-_0x27b88c;this[_0x110808(0x139)]['api']('[TMP活动更新]\x20TMP\x20API响应耗时:\x20'+_0x2dfa1c+_0x110808(0x161)+_0x284a88[_0x110808(0x195)]);if(!_0x284a88[_0x110808(0x195)]&&Array[_0x110808(0x173)](_0x284a88[_0x110808(0x227)])){const _0x26ae8c=new Date(),_0x684946=_0x26ae8c['getFullYear']()+'-'+(_0x26ae8c['getMonth']()+0x1)[_0x110808(0x237)]()[_0x110808(0x202)](0x2,'0')+'-'+_0x26ae8c[_0x110808(0x208)]()[_0x110808(0x237)]()[_0x110808(0x202)](0x2,'0');this[_0x110808(0x139)][_0x110808(0x159)]('[TMP活动更新]\x20当前本地日期:\x20'+_0x684946+',\x20UTC日期:\x20'+new Date()[_0x110808(0x246)]()[_0x110808(0x156)]('T')[0x0]);const _0x5c6d1d=_0x284a88[_0x110808(0x227)][_0x110808(0x1f1)];this[_0x110808(0x139)]['debug'](_0x110808(0x1f2)+_0x5c6d1d);if(this[_0x110808(0x220)]['debug']?.[_0x110808(0x218)]&&_0x5c6d1d>0x0){const _0x4ad9a8=_0x284a88[_0x110808(0x227)]['map'](_0x2827fb=>_0x2827fb[_0x110808(0x1cb)]+':\x20'+_0x2827fb['start_at']?.[_0x110808(0x156)]('\x20')[0x0]);this[_0x110808(0x139)][_0x110808(0x159)]('[TMP活动更新]\x20所有活动日期:',_0x4ad9a8);}this[_0x110808(0x1a9)]=_0x284a88[_0x110808(0x227)][_0x110808(0x179)](_0x4912c1=>{const _0x15f51e=_0x110808,_0x4746ec=_0x4912c1['start_at']?.[_0x15f51e(0x156)]('\x20')[0x0],_0x53c192=_0x4746ec===_0x684946;return!_0x53c192&&this[_0x15f51e(0x220)][_0x15f51e(0x159)]?.[_0x15f51e(0x218)]&&this['logger']['debug'](_0x15f51e(0x1ee)+_0x4912c1['name']+_0x15f51e(0x1af)+_0x4746ec+_0x15f51e(0x1a2)+_0x684946),_0x53c192;}),this['logger'][_0x110808(0x22a)](_0x110808(0x17c)+this[_0x110808(0x1a9)][_0x110808(0x1f1)]+'/'+_0x5c6d1d+'\x20个今日活动');if(this[_0x110808(0x220)][_0x110808(0x159)]?.['debugMode']&&this[_0x110808(0x1a9)][_0x110808(0x1f1)]>0x0){const _0x2f6c05=this[_0x110808(0x1a9)][_0x110808(0x1cd)](_0x52f8b2=>_0x52f8b2[_0x110808(0x1cb)]+':\x20'+_0x52f8b2['start_at']);this[_0x110808(0x139)][_0x110808(0x159)](_0x110808(0x16e),_0x2f6c05);}}else this[_0x110808(0x139)][_0x110808(0x195)]('[TMP活动更新]\x20TMP\x20API返回错误:\x20'+(_0x284a88[_0x110808(0x1b9)]||_0x110808(0x190)));}catch(_0x2f3d1c){this[_0x110808(0x139)][_0x110808(0x195)](_0x110808(0x19a),_0x2f3d1c['message']);}}async[_0x37e7cf(0x1e1)](){const _0x141a25=_0x37e7cf;await this['updateActivityData']();if(this['todayActivities'][_0x141a25(0x1f1)]===0x0){this[_0x141a25(0x139)][_0x141a25(0x159)](_0x141a25(0x1b1));return;}this['logger'][_0x141a25(0x159)](_0x141a25(0x20f)+this[_0x141a25(0x1e5)][_0x141a25(0x1f1)]+_0x141a25(0x243));for(const _0x3cde9f of this[_0x141a25(0x1e5)]){const _0x318fb2=!!_0x3cde9f[_0x141a25(0x210)],_0x356bba=_0x318fb2?this[_0x141a25(0x220)][_0x141a25(0x19b)][_0x141a25(0x1ae)]:this[_0x141a25(0x220)][_0x141a25(0x19b)][_0x141a25(0x14e)],_0x172bb2=_0x141a25(0x221)+(_0x3cde9f[_0x141a25(0x1f3)]||_0x141a25(0x1e0))+_0x141a25(0x184)+_0x356bba;this[_0x141a25(0x139)][_0x141a25(0x1b9)](_0x141a25(0x230)+(_0x3cde9f[_0x141a25(0x1f3)]||_0x141a25(0x1e0))+_0x141a25(0x184)+(_0x318fb2?_0x141a25(0x233):_0x141a25(0x1c2)));for(const _0x15b622 of this[_0x141a25(0x220)][_0x141a25(0x1be)][_0x141a25(0x193)]){try{await this[_0x141a25(0x21c)](_0x15b622,_0x172bb2,'管理群组'),this[_0x141a25(0x139)][_0x141a25(0x1b9)](_0x141a25(0x18e)+_0x15b622+':\x20'+(_0x3cde9f[_0x141a25(0x1f3)]||_0x141a25(0x1e0)));}catch(_0x23f931){this[_0x141a25(0x139)][_0x141a25(0x195)](_0x141a25(0x1c3)+_0x15b622+_0x141a25(0x145),_0x23f931['message']);}}}}async[_0x37e7cf(0x216)](_0x43fd6d=![]){const _0x5fe129=_0x37e7cf;if(!_0x43fd6d&&this[_0x5fe129(0x1ce)]){this[_0x5fe129(0x139)][_0x5fe129(0x159)](_0x5fe129(0x137));return;}if(this['todayActivities'][_0x5fe129(0x1f1)]>0x0||this['todayTMPEvents'][_0x5fe129(0x1f1)]>0x0){this[_0x5fe129(0x139)]['debug'](_0x5fe129(0x1f4)+this[_0x5fe129(0x1e5)]['length']+_0x5fe129(0x1ed)+this[_0x5fe129(0x1a9)]['length']+_0x5fe129(0x20e));return;}this[_0x5fe129(0x139)]['info']((_0x43fd6d?_0x5fe129(0x1df):'自动')+'今日无活动,发送通知到管理群');for(const _0x46b8e9 of this['cfg'][_0x5fe129(0x1be)][_0x5fe129(0x193)]){try{await this[_0x5fe129(0x21c)](_0x46b8e9,this[_0x5fe129(0x220)][_0x5fe129(0x1d8)]['message'],'管理群组'),this[_0x5fe129(0x139)][_0x5fe129(0x1b9)](_0x5fe129(0x224)+_0x46b8e9);}catch(_0x2e35f7){this[_0x5fe129(0x139)][_0x5fe129(0x195)](_0x5fe129(0x1e8)+_0x46b8e9+'\x20失败:',_0x2e35f7[_0x5fe129(0x1b9)]);}}!_0x43fd6d&&(this[_0x5fe129(0x1ce)]=!![],this[_0x5fe129(0x139)]['debug'](_0x5fe129(0x146)));}async['checkActivityStatusChange'](){const _0x1e9152=_0x37e7cf;await this[_0x1e9152(0x23d)](),this[_0x1e9152(0x1ce)]&&(this[_0x1e9152(0x1e5)][_0x1e9152(0x1f1)]>0x0||this[_0x1e9152(0x1a9)][_0x1e9152(0x1f1)]>0x0)&&(this[_0x1e9152(0x139)][_0x1e9152(0x22a)](_0x1e9152(0x13e)+this['todayActivities'][_0x1e9152(0x1f1)]+'个,\x20TMP:\x20'+this[_0x1e9152(0x1a9)]['length']+'个)'),this[_0x1e9152(0x1ce)]=![],await this['checkAndSendProfileReminders']());}async[_0x37e7cf(0x164)](){const _0x32181d=_0x37e7cf,_0xa4cfda=new Date(),_0xf6029a=_0xa4cfda[_0x32181d(0x168)]()+'-'+(_0xa4cfda[_0x32181d(0x226)]()+0x1)[_0x32181d(0x237)]()[_0x32181d(0x202)](0x2,'0')+'-'+_0xa4cfda['getDate']()[_0x32181d(0x237)]()[_0x32181d(0x202)](0x2,'0'),_0x26ebef=_0xa4cfda[_0x32181d(0x246)]()[_0x32181d(0x156)]('T')[0x0];let _0x5e6c2e=0x0;this[_0x32181d(0x139)][_0x32181d(0x159)](_0x32181d(0x140)+this[_0x32181d(0x1e5)]['length']+_0x32181d(0x1d3)+_0xf6029a+',\x20UTC日期:\x20'+_0x26ebef);this[_0x32181d(0x220)][_0x32181d(0x1c8)][_0x32181d(0x193)]['length']===0x0?this['logger']['warn'](_0x32181d(0x1bb)):this[_0x32181d(0x139)][_0x32181d(0x159)](_0x32181d(0x160)+this[_0x32181d(0x220)]['mainGroup'][_0x32181d(0x193)][_0x32181d(0x1f1)]+_0x32181d(0x1fd)+this[_0x32181d(0x220)][_0x32181d(0x1c8)]['groups']['join'](',\x20'));for(const _0xeda2b9 of this[_0x32181d(0x1e5)]){try{const _0x3cccab=_0xeda2b9[_0x32181d(0x192)]?.[_0x32181d(0x156)]('\x20')[0x0];if(_0x3cccab!==_0xf6029a){this[_0x32181d(0x139)][_0x32181d(0x159)](_0x32181d(0x157)+_0xeda2b9['themeName']+'\x22,活动日期:\x20'+_0x3cccab+_0x32181d(0x14b)+_0xf6029a);continue;}const _0x80f58b=new Date(_0xeda2b9[_0x32181d(0x192)]);if(isNaN(_0x80f58b['getTime']())){this['logger'][_0x32181d(0x1c4)](_0x32181d(0x221)+_0xeda2b9['themeName']+_0x32181d(0x169));continue;}const _0x511c79=_0x80f58b[_0x32181d(0x1ac)]()-_0xa4cfda['getTime'](),_0xb90a6f=Math[_0x32181d(0x141)](_0x511c79/0x3e8),_0x259cac=Math['floor'](_0xb90a6f/0x3c),_0x5cf026=_0xb90a6f%0x3c;this[_0x32181d(0x139)]['debug'](_0x32181d(0x221)+_0xeda2b9[_0x32181d(0x1f3)]+_0x32181d(0x1de)+_0x259cac+_0x32181d(0x150)+_0x5cf026+'\x20秒'),this[_0x32181d(0x139)][_0x32181d(0x159)](_0x32181d(0x221)+_0xeda2b9[_0x32181d(0x1f3)]+'\x22\x20时间检查:\x20totalSecondsLeft='+_0xb90a6f+_0x32181d(0x1ea)+_0xb90a6f+'\x20<=\x200');if(_0xb90a6f>=-0x12c&&_0xb90a6f<=0x0){const _0x4d485f=_0xeda2b9['id']+_0x32181d(0x23f);!this[_0x32181d(0x1b7)]['has'](_0x4d485f)?(this[_0x32181d(0x139)][_0x32181d(0x22a)](_0x32181d(0x1f9)+_0xeda2b9[_0x32181d(0x1f3)]),await this[_0x32181d(0x1fc)](_0xeda2b9),this[_0x32181d(0x1b7)][_0x32181d(0x1d0)](_0x4d485f),_0x5e6c2e++):this[_0x32181d(0x139)][_0x32181d(0x159)]('活动\x20\x22'+_0xeda2b9[_0x32181d(0x1f3)]+_0x32181d(0x1bf));}else this[_0x32181d(0x139)]['debug'](_0x32181d(0x221)+_0xeda2b9['themeName']+_0x32181d(0x13c)+_0xb90a6f+'\x20秒');if(_0xb90a6f<0x0)continue;for(const _0x2baa45 of this[_0x32181d(0x220)][_0x32181d(0x1c8)]['activityReminderTimes']){const _0x9ea1ef=_0x2baa45*0x3c;this[_0x32181d(0x139)]['debug'](_0x32181d(0x221)+_0xeda2b9['themeName']+'\x22\x20'+_0x2baa45+_0x32181d(0x185)+_0xb90a6f+_0x32181d(0x225)+_0x9ea1ef+_0x32181d(0x188)+(_0x9ea1ef-0x3c)+_0x32181d(0x228)+_0xb90a6f+_0x32181d(0x228)+_0x9ea1ef);if(_0xb90a6f<=_0x9ea1ef&&_0xb90a6f>_0x9ea1ef-0x3c){const _0x4514ce=_0xeda2b9['id']+'_'+_0x2baa45;!this[_0x32181d(0x1b7)][_0x32181d(0x229)](_0x4514ce)?(this[_0x32181d(0x139)]['info'](_0x32181d(0x175)+_0xeda2b9[_0x32181d(0x1f3)]+'\x20-\x20'+_0x2baa45+_0x32181d(0x21b)),await this[_0x32181d(0x1b3)](_0xeda2b9,_0x2baa45),this[_0x32181d(0x1b7)][_0x32181d(0x1d0)](_0x4514ce),_0x5e6c2e++):this[_0x32181d(0x139)]['debug'](_0x32181d(0x221)+_0xeda2b9[_0x32181d(0x1f3)]+'\x22\x20'+_0x2baa45+_0x32181d(0x1a7));}}}catch(_0x27eccb){this[_0x32181d(0x139)]['error'](_0x32181d(0x1fa)+_0xeda2b9[_0x32181d(0x1f3)]+_0x32181d(0x23c),_0x27eccb[_0x32181d(0x1b9)]);}}_0x5e6c2e>0x0?this[_0x32181d(0x139)][_0x32181d(0x22a)](_0x32181d(0x21f)+_0x5e6c2e+_0x32181d(0x1c6)):this[_0x32181d(0x139)][_0x32181d(0x159)](_0x32181d(0x1e2));}[_0x37e7cf(0x223)](_0x55fe5c,_0x23b803,_0x7270d7){const _0x56969e=_0x37e7cf,_0x3e4f4a={'name':_0x55fe5c['themeName']||_0x56969e(0x1e0),'distance':_0x55fe5c[_0x56969e(0x1b6)]?.[_0x56969e(0x237)]()||'未知'};return _0x7270d7!==undefined&&(_0x3e4f4a[_0x56969e(0x219)]=_0x7270d7['toString']()),this[_0x56969e(0x220)][_0x56969e(0x1a5)][_0x56969e(0x144)]===_0x56969e(0x14a)&&_0x23b803?_0x3e4f4a['server']=_0x23b803['server']?.[_0x56969e(0x1cb)]||'未知服务器':_0x3e4f4a[_0x56969e(0x16a)]=_0x55fe5c[_0x56969e(0x166)]||'未知服务器',this['cfg'][_0x56969e(0x1a5)][_0x56969e(0x200)]===_0x56969e(0x14a)&&_0x23b803?_0x3e4f4a[_0x56969e(0x171)]=((_0x23b803[_0x56969e(0x1d6)]?.[_0x56969e(0x17a)]||'')+_0x56969e(0x1a4)+(_0x23b803[_0x56969e(0x1d6)]?.[_0x56969e(0x20d)]||''))[_0x56969e(0x1c9)]()||_0x56969e(0x1d2):_0x3e4f4a[_0x56969e(0x171)]=_0x55fe5c[_0x56969e(0x171)]||_0x56969e(0x1d2),this['cfg'][_0x56969e(0x1a5)][_0x56969e(0x147)]===_0x56969e(0x14a)&&_0x23b803?_0x3e4f4a[_0x56969e(0x143)]=((_0x23b803[_0x56969e(0x194)]?.[_0x56969e(0x17a)]||'')+_0x56969e(0x1a4)+(_0x23b803[_0x56969e(0x194)]?.['city']||''))[_0x56969e(0x1c9)]()||_0x56969e(0x196):_0x3e4f4a[_0x56969e(0x143)]=_0x55fe5c[_0x56969e(0x143)]||_0x56969e(0x196),this['cfg'][_0x56969e(0x1a5)]['showBanner']&&_0x23b803&&_0x23b803['banner']?_0x3e4f4a[_0x56969e(0x242)]=_0x23b803[_0x56969e(0x242)]:_0x3e4f4a['banner']='无',_0x3e4f4a;}async[_0x37e7cf(0x1fc)](_0x425f65){const _0x1feda6=_0x37e7cf;try{const _0x3b0c95=this[_0x1feda6(0x1a9)][_0x1feda6(0x142)](_0x128437=>_0x128437[_0x1feda6(0x1cb)][_0x1feda6(0x176)](_0x425f65['themeName'])||_0x425f65[_0x1feda6(0x1f3)]['includes'](_0x128437['name']));this[_0x1feda6(0x139)][_0x1feda6(0x236)](_0x1feda6(0x16d)+_0x425f65['themeName']+_0x1feda6(0x174)+!!_0x3b0c95);const _0x4ea4ef=this[_0x1feda6(0x223)](_0x425f65,_0x3b0c95);let _0xd82bb1=this[_0x1feda6(0x220)][_0x1feda6(0x1c8)][_0x1feda6(0x189)];for(const [_0x1a620d,_0x5d165a]of Object[_0x1feda6(0x178)](_0x4ea4ef)){_0xd82bb1=_0xd82bb1[_0x1feda6(0x1cc)](new RegExp('{'+_0x1a620d+'}','g'),_0x5d165a);}!this['cfg'][_0x1feda6(0x1a5)]['showBanner']&&(_0xd82bb1=_0xd82bb1[_0x1feda6(0x1cc)](/活动横幅:.*?\n?/,''));_0xd82bb1=_0xd82bb1[_0x1feda6(0x1cc)](/\\n/g,'\x0a')['trim']();const _0x44afb8=_0x1feda6(0x1ff)+_0xd82bb1;await this[_0x1feda6(0x1a0)](_0x44afb8,_0x425f65[_0x1feda6(0x1f3)],'开始提醒');}catch(_0x50da3f){this[_0x1feda6(0x139)][_0x1feda6(0x195)]('发送活动开始提醒失败:',_0x50da3f[_0x1feda6(0x1b9)]);}}async[_0x37e7cf(0x1b3)](_0x4a5e22,_0x5dbb12){const _0x1d85b8=_0x37e7cf;try{const _0x3bc512=this['todayTMPEvents'][_0x1d85b8(0x142)](_0x36361e=>_0x36361e[_0x1d85b8(0x1cb)][_0x1d85b8(0x176)](_0x4a5e22['themeName'])||_0x4a5e22[_0x1d85b8(0x1f3)]['includes'](_0x36361e[_0x1d85b8(0x1cb)]));this[_0x1d85b8(0x139)]['matching'](_0x1d85b8(0x16d)+_0x4a5e22['themeName']+_0x1d85b8(0x174)+!!_0x3bc512);const _0x5a66c0=this[_0x1d85b8(0x223)](_0x4a5e22,_0x3bc512,_0x5dbb12);let _0x350d3e=this[_0x1d85b8(0x220)][_0x1d85b8(0x1c8)][_0x1d85b8(0x16b)];for(const [_0x35a5b9,_0x40fda8]of Object[_0x1d85b8(0x178)](_0x5a66c0)){_0x350d3e=_0x350d3e[_0x1d85b8(0x1cc)](new RegExp('{'+_0x35a5b9+'}','g'),_0x40fda8);}!this[_0x1d85b8(0x220)][_0x1d85b8(0x1a5)]['showBanner']&&(_0x350d3e=_0x350d3e[_0x1d85b8(0x1cc)](/活动横幅:.*?\n?/,''));_0x350d3e=_0x350d3e[_0x1d85b8(0x1cc)](/\\n/g,'\x0a')[_0x1d85b8(0x1c9)]();const _0x4c21fe=_0x1d85b8(0x1ff)+_0x350d3e;await this['sendToMainGroups'](_0x4c21fe,_0x4a5e22['themeName'],_0x5dbb12+_0x1d85b8(0x21e));}catch(_0x5d3b97){this['logger'][_0x1d85b8(0x195)]('发送活动提醒失败:',_0x5d3b97[_0x1d85b8(0x1b9)]);}}async['sendToMainGroups'](_0x17e045,_0x48ba25,_0x2ca155){const _0x518462=_0x37e7cf;for(const _0xdc0202 of this['cfg'][_0x518462(0x1c8)][_0x518462(0x193)]){try{await this['sendToGroup'](_0xdc0202,_0x17e045,_0x518462(0x1c7)),this['logger']['message'](_0x518462(0x1b8)+_0x2ca155+_0x518462(0x13d)+_0xdc0202+':\x20'+_0x48ba25);}catch(_0x3f908c){this['logger'][_0x518462(0x195)]('发送'+_0x2ca155+'到主群组\x20'+_0xdc0202+_0x518462(0x145),_0x3f908c['message']);}}}async[_0x37e7cf(0x21c)](_0x27c27a,_0x52b939,_0x2a1d0c){const _0x2ba6f3=_0x37e7cf,_0x2dda1b=this[_0x2ba6f3(0x222)][_0x2ba6f3(0x13f)][_0x2ba6f3(0x179)](_0x4b22f6=>{const _0xcf275c=_0x2ba6f3,_0x5537d7=['mail','telegram',_0xcf275c(0x1a3),'qq',_0xcf275c(0x1bc)];return!_0x5537d7[_0xcf275c(0x176)](_0x4b22f6[_0xcf275c(0x241)]);});if(_0x2dda1b[_0x2ba6f3(0x1f1)]===0x0)throw new Error(_0x2ba6f3(0x231));let _0x2563fe=null;this['logger'][_0x2ba6f3(0x159)](_0x2ba6f3(0x1fb)+_0x2dda1b[_0x2ba6f3(0x1f1)]+_0x2ba6f3(0x15f)+_0x2a1d0c+'\x20'+_0x27c27a);for(const _0x410d16 of _0x2dda1b){try{await _0x410d16[_0x2ba6f3(0x1eb)](_0x27c27a,_0x52b939),this[_0x2ba6f3(0x139)][_0x2ba6f3(0x159)]('已通过\x20'+_0x410d16['platform']+_0x2ba6f3(0x18d)+_0x2a1d0c+'\x20'+_0x27c27a);return;}catch(_0x467e61){_0x2563fe=_0x467e61,this[_0x2ba6f3(0x139)][_0x2ba6f3(0x1c4)](_0x2ba6f3(0x22d)+_0x410d16['platform']+_0x2ba6f3(0x13a)+_0x467e61['message']);}}throw _0x2563fe||new Error(_0x2ba6f3(0x21d)+_0x2a1d0c+'\x20'+_0x27c27a);}['cleanup'](){const _0x208584=_0x37e7cf;this[_0x208584(0x139)][_0x208584(0x159)](_0x208584(0x19c)),this[_0x208584(0x1e5)]=[],this[_0x208584(0x1a9)]=[],this[_0x208584(0x1b7)]['clear'](),this['timers'][_0x208584(0x1b2)](_0x5b4108=>{clearTimeout(_0x5b4108),clearInterval(_0x5b4108);}),this[_0x208584(0x234)][_0x208584(0x1f1)]=0x0,this['logger'][_0x208584(0x159)]('资源清理完成');}}exports['ActivityService']=ActivityService;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActivityService = void 0;
4
+
5
+ const koishi_1 = require("koishi");
6
+
7
+ class ActivityService {
8
+ constructor(ctx, config) {
9
+ this.ctx = ctx;
10
+ this.cfg = config;
11
+ this.todayActivities = [];
12
+ this.todayTMPEvents = [];
13
+ this.sentReminders = new Set();
14
+ this.sentNoActivityNotification = false;
15
+ this.timers = [];
16
+ this.logger = this.initLogger();
17
+ }
18
+
19
+ initLogger() {
20
+ return {
21
+ debug: (message, ...args) => {
22
+ if (this.cfg.debugMode) {
23
+ this.ctx.logger.debug(`[TMP-BOT DEBUG] ${message}`, ...args);
24
+ }
25
+ },
26
+ info: (message, ...args) => {
27
+ this.ctx.logger.info(`[TMP-BOT] ${message}`, ...args);
28
+ },
29
+ warn: (message, ...args) => {
30
+ this.ctx.logger.warn(`[TMP-BOT WARN] ${message}`, ...args);
31
+ },
32
+ error: (message, ...args) => {
33
+ this.ctx.logger.error(`[TMP-BOT ERROR] ${message}`, ...args);
34
+ },
35
+ api: (message, data) => {
36
+ if (this.cfg.debug?.logApiResponses) {
37
+ this.ctx.logger.info(`[TMP-BOT API] ${message}`, data ? JSON.stringify(data, null, 2) : "");
38
+ }
39
+ },
40
+ timing: (message, data) => {
41
+ if (this.cfg.debug?.logTimingDetails) {
42
+ this.ctx.logger.info(`[TMP-BOT TIMING] ${message}`, data || "");
43
+ }
44
+ },
45
+ matching: (message, data) => {
46
+ if (this.cfg.debug?.logActivityMatching) {
47
+ this.ctx.logger.info(`[TMP-BOT MATCHING] ${message}`, data || "");
48
+ }
49
+ },
50
+ message: (message, data) => {
51
+ if (this.cfg.debug?.logMessageSending) {
52
+ this.ctx.logger.info(`[TMP-BOT MESSAGE] ${message}`, data || "");
53
+ }
54
+ }
55
+ };
56
+ }
57
+
58
+ start() {
59
+ this.setupDailyTasks();
60
+ this.registerAdminCommands();
61
+ this.ctx.on("dispose", () => this.cleanup());
62
+ }
63
+
64
+ registerAdminCommands() {
65
+ this.ctx.command("活动查询", "手动检查今日活动")
66
+ .action(async () => {
67
+ this.logger.debug("手动执行活动检查命令");
68
+ await this.updateActivityData();
69
+ return `检查完成!\n车队平台今日活动: ${this.todayActivities.length} 个\nTMP今日参与活动: ${this.todayTMPEvents.length} 个`;
70
+ });
71
+
72
+ this.ctx.command("重置数据", "手动重置今日活动数据")
73
+ .action(() => {
74
+ this.logger.debug("手动执行数据重置命令");
75
+ this.resetDailyData();
76
+ return "✅ 今日活动数据已重置完成!";
77
+ });
78
+ }
79
+
80
+ setupDailyTasks() {
81
+ const now = new Date();
82
+ const localTime = now.toLocaleString();
83
+ const localDate = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`;
84
+ const utcDate = now.toISOString().split("T")[0];
85
+
86
+ this.logger.timing(`开始设置每日定时任务,本地时间: ${localTime}, 本地日期: ${localDate}, UTC日期: ${utcDate}`);
87
+
88
+ const resetHour = 2;
89
+ const resetMinute = 0;
90
+ const resetDelay = this.getNextTime(resetHour, resetMinute);
91
+ const resetTimer = setTimeout(() => {
92
+ this.logger.timing("执行每日数据重置");
93
+ this.resetDailyData();
94
+ const dailyResetTimer = setInterval(() => {
95
+ this.logger.timing("执行每日数据重置");
96
+ this.resetDailyData();
97
+ }, koishi_1.Time.day);
98
+ this.timers.push(dailyResetTimer);
99
+ }, resetDelay);
100
+ this.timers.push(resetTimer);
101
+ this.logger.timing(`设置数据重置定时器: ${resetHour}:${resetMinute.toString().padStart(2, "0")}, 延迟: ${resetDelay}ms`);
102
+
103
+ this.cfg.admin.checkTimes.forEach((timeStr, index) => {
104
+ const [hours, minutes] = timeStr.split(":").map(Number);
105
+ this.setupTimer(hours, minutes, async () => {
106
+ this.logger.timing(`执行定时检查任务 #${index + 1} (${timeStr})`);
107
+ await this.updateActivityData();
108
+ await this.checkActivityStatusChange();
109
+ }, `检查定时器 #${index + 1}: ${timeStr}`);
110
+ });
111
+
112
+ this.cfg.admin.sendTimes.forEach((timeStr, index) => {
113
+ const [hours, minutes] = timeStr.split(":").map(Number);
114
+ this.setupTimer(hours, minutes, async () => {
115
+ this.logger.timing(`执行定时发送任务 #${index + 1} (${timeStr})`);
116
+ await this.checkAndSendProfileReminders();
117
+ }, `发送定时器 #${index + 1}: ${timeStr}`);
118
+ });
119
+
120
+ if (this.cfg.noActivity?.enable) {
121
+ const [noActivityHours, noActivityMinutes] = this.cfg.noActivity.time.split(":").map(Number);
122
+ this.setupTimer(noActivityHours, noActivityMinutes, () => {
123
+ this.logger.timing(`执行今日无活动通知任务 (${this.cfg.noActivity.time})`);
124
+ this.checkAndSendNoActivityNotification();
125
+ }, `无活动通知定时器: ${this.cfg.noActivity.time}`);
126
+ }
127
+
128
+ const minuteTimer = setInterval(async () => {
129
+ await this.checkAndSendActivityReminders();
130
+ }, koishi_1.Time.minute);
131
+ this.timers.push(minuteTimer);
132
+ this.logger.timing("设置每分钟检查定时器");
133
+ this.logger.debug("启动时立即更新活动数据");
134
+ this.updateActivityData();
135
+ }
136
+
137
+ setupTimer(hours, minutes, callback, name) {
138
+ const delay = this.getNextTime(hours, minutes);
139
+ const timer = setTimeout(() => {
140
+ callback();
141
+ const dailyTimer = setInterval(callback, koishi_1.Time.day);
142
+ this.timers.push(dailyTimer);
143
+ }, delay);
144
+ this.timers.push(timer);
145
+ this.logger.timing(`${name}, 延迟: ${delay}ms`);
146
+ }
147
+
148
+ getNextTime(hours, minutes) {
149
+ const now = new Date();
150
+ const target = new Date(
151
+ now.getFullYear(),
152
+ now.getMonth(),
153
+ now.getDate(),
154
+ hours,
155
+ minutes,
156
+ 0,
157
+ 0
158
+ );
159
+ if (target.getTime() <= now.getTime()) {
160
+ target.setDate(target.getDate() + 1);
161
+ }
162
+ return target.getTime() - now.getTime();
163
+ }
164
+
165
+ resetDailyData() {
166
+ const now = new Date();
167
+ const localTime = now.toLocaleString();
168
+ const localDate = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`;
169
+ const utcDate = now.toISOString().split("T")[0];
170
+
171
+ const previousActivityCount = this.todayActivities.length;
172
+ const previousTMPCount = this.todayTMPEvents.length;
173
+ const previousReminderCount = this.sentReminders.size;
174
+ const previousNoActivityNotification = this.sentNoActivityNotification;
175
+
176
+ this.logger.info(`[数据重置] 开始重置数据,本地时间: ${localTime}, 本地日期: ${localDate}, UTC日期: ${utcDate}`);
177
+ this.logger.info(`[数据重置] 重置前数据: 活动${previousActivityCount}个, TMP${previousTMPCount}个, 提醒${previousReminderCount}个, 无活动通知${previousNoActivityNotification ? "已发送" : "未发送"}`);
178
+
179
+ this.todayActivities = [];
180
+ this.todayTMPEvents = [];
181
+ this.sentReminders.clear();
182
+ this.sentNoActivityNotification = false;
183
+
184
+ this.logger.info(`[数据重置] 每日数据已重置: 活动${previousActivityCount}→0, TMP${previousTMPCount}→0, 提醒${previousReminderCount}→0, 无活动通知${previousNoActivityNotification ? "已发送" : "未发送"}→未发送`);
185
+
186
+ this.updateActivityData().then(() => {
187
+ this.logger.info(`[数据重置] 重置后数据更新完成: 活动${this.todayActivities.length}个, TMP${this.todayTMPEvents.length}个`);
188
+ }).catch(error => {
189
+ this.logger.error(`[数据重置] 重置后数据更新失败:`, error.message);
190
+ });
191
+ }
192
+
193
+ async updateActivityData() {
194
+ try {
195
+ this.logger.debug("开始更新活动数据");
196
+ const startTime = Date.now();
197
+ await Promise.all([
198
+ this.updateTodayActivities(),
199
+ this.updateTodayTMPEvents()
200
+ ]);
201
+
202
+ const duration = Date.now() - startTime;
203
+ this.logger.info(`活动数据更新完成,耗时: ${duration}ms`);
204
+ this.logger.debug(`今日活动数量: ${this.todayActivities.length}, TMP活动数量: ${this.todayTMPEvents.length}`);
205
+ } catch (error) {
206
+ this.logger.error("更新活动数据失败:", error.message);
207
+ }
208
+ }
209
+
210
+ async updateTodayActivities() {
211
+ try {
212
+ this.todayActivities = [];
213
+
214
+ const protocol = this.cfg.api.useHttps ? "https://" : "http://";
215
+ const fullUrl = `${protocol}${this.cfg.api.url}/api/activity/info/list?token=${this.cfg.api.token}&page=1&limit=50&themeName=`;
216
+ this.logger.api(`请求车队平台API: ${fullUrl.replace(this.cfg.api.token, "***")}`);
217
+
218
+ const startTime = Date.now();
219
+ const response = await this.ctx.http.get(fullUrl, { timeout: 10000 });
220
+ const duration = Date.now() - startTime;
221
+ this.logger.api(`车队平台API响应耗时: ${duration}ms, 状态码: ${response.code}`);
222
+
223
+ if (this.cfg.debug?.logApiResponses) {
224
+ this.logger.api("车队平台API响应详情:", {
225
+ code: response.code,
226
+ totalCount: response.data?.totalCount,
227
+ listCount: response.data?.list?.length
228
+ });
229
+ }
230
+
231
+ if (response.code === 0 && response.data?.list) {
232
+ const now = new Date();
233
+ const today = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`;
234
+ this.logger.debug(`[活动更新] 当前本地日期: ${today}, UTC日期: ${new Date().toISOString().split("T")[0]}`);
235
+
236
+ const originalCount = response.data.list.length;
237
+ this.logger.debug(`[活动更新] API返回活动总数: ${originalCount}`);
238
+ if (this.cfg.debug?.debugMode && originalCount > 0) {
239
+ const activityDates = response.data.list.map(a => `${a.themeName}: ${a.startTime?.split(" ")[0]}`);
240
+ this.logger.debug(`[活动更新] 所有活动日期:`, activityDates);
241
+ }
242
+
243
+ this.todayActivities = response.data.list.filter((activity) => {
244
+ const activityDate = activity.startTime?.split(" ")[0];
245
+ const isToday = activityDate === today;
246
+ if (!isToday && this.cfg.debug?.debugMode) {
247
+ this.logger.debug(`[活动更新] 跳过非今日活动: ${activity.themeName}, 日期: ${activityDate}, 当前日期: ${today}`);
248
+ }
249
+ return isToday;
250
+ });
251
+
252
+ this.logger.info(`[活动更新] 从车队平台找到 ${this.todayActivities.length}/${originalCount} 个今日活动`);
253
+ if (this.cfg.debug?.debugMode && this.todayActivities.length > 0) {
254
+ const todayActivityNames = this.todayActivities.map(a => `${a.themeName}: ${a.startTime}`);
255
+ this.logger.debug(`[活动更新] 今日活动详情:`, todayActivityNames);
256
+ }
257
+ } else {
258
+ this.logger.error(`[活动更新] 车队平台API返回错误: ${response.msg || '未知错误'} (代码: ${response.code || '无'})`);
259
+ this.todayActivities = [];
260
+ }
261
+ } catch (error) {
262
+ this.logger.error("[活动更新] 获取车队平台活动列表失败:", error.message);
263
+ this.todayActivities = [];
264
+ }
265
+ }
266
+
267
+ async updateTodayTMPEvents() {
268
+ try {
269
+ this.todayTMPEvents = [];
270
+
271
+ if (!this.cfg.api.vtcId) {
272
+ this.logger.warn("[TMP活动更新] TMP API请求失败:未配置api.vtcId");
273
+ return;
274
+ }
275
+
276
+ const tmpApiUrl = `https://api.truckersmp.com/v2/vtc/${this.cfg.api.vtcId}/events/attending/`;
277
+ this.logger.api(`[TMP活动更新] 请求TMP API: ${tmpApiUrl}`);
278
+
279
+ const startTime = Date.now();
280
+ const response = await this.ctx.http.get(tmpApiUrl, { timeout: 10000 });
281
+ const duration = Date.now() - startTime;
282
+ this.logger.api(`[TMP活动更新] TMP API响应耗时: ${duration}ms, 错误状态: ${response.error}`);
283
+
284
+ if (!response.error && Array.isArray(response.response)) {
285
+ const now = new Date();
286
+ const today = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`;
287
+ this.logger.debug(`[TMP活动更新] 当前本地日期: ${today}, UTC日期: ${new Date().toISOString().split("T")[0]}`);
288
+
289
+ const originalCount = response.response.length;
290
+ this.logger.debug(`[TMP活动更新] API返回活动总数: ${originalCount}`);
291
+
292
+ if (this.cfg.debug?.debugMode && originalCount > 0) {
293
+ const eventDates = response.response.map(e => `${e.name}: ${e.start_at?.split(" ")[0]}`);
294
+ this.logger.debug(`[TMP活动更新] 所有活动日期:`, eventDates);
295
+ }
296
+
297
+ this.todayTMPEvents = response.response.filter((event) => {
298
+ const eventDate = event.start_at?.split(" ")[0];
299
+ const isToday = eventDate === today;
300
+ if (!isToday && this.cfg.debug?.debugMode) {
301
+ this.logger.debug(`[TMP活动更新] 跳过非今日活动: ${event.name}, 日期: ${eventDate}, 当前日期: ${today}`);
302
+ }
303
+ return isToday;
304
+ });
305
+
306
+ this.logger.info(`[TMP活动更新] 从TMP找到 ${this.todayTMPEvents.length}/${originalCount} 个今日活动`);
307
+
308
+ if (this.cfg.debug?.debugMode && this.todayTMPEvents.length > 0) {
309
+ const todayEventNames = this.todayTMPEvents.map(e => `${e.name}: ${e.start_at}`);
310
+ this.logger.debug(`[TMP活动更新] 今日活动详情:`, todayEventNames);
311
+ }
312
+ } else {
313
+ this.logger.error(`[TMP活动更新] TMP API返回错误: ${response.message || '未知错误'}`);
314
+ }
315
+ } catch (error) {
316
+ this.logger.error("[TMP活动更新] 获取TMP活动失败:", error.message);
317
+ }
318
+ }
319
+
320
+ async checkAndSendProfileReminders() {
321
+ await this.updateActivityData();
322
+
323
+ if (this.todayActivities.length === 0) {
324
+ this.logger.debug("今日没有活动,跳过档位检查");
325
+ return;
326
+ }
327
+
328
+ this.logger.debug(`开始检查 ${this.todayActivities.length} 个活动的档位状态`);
329
+
330
+ for (const activity of this.todayActivities) {
331
+ const hasProfile = !!activity.profileFile;
332
+ const message = hasProfile ? this.cfg.messages.profileUploaded : this.cfg.messages.profileNotUploaded;
333
+ const fullMessage = `活动 "${activity.themeName || '未知活动'}" - ${message}`;
334
+ this.logger.message(`活动档位检查: "${activity.themeName || '未知活动'}" - ${hasProfile ? "已上传" : "未上传"}`);
335
+
336
+ for (const groupId of this.cfg.admin.groups) {
337
+ try {
338
+ await this.sendToGroup(groupId, fullMessage, "管理群组");
339
+ this.logger.message(`已发送档位提醒到管理群组 ${groupId}: ${activity.themeName || '未知活动'}`);
340
+ } catch (error) {
341
+ this.logger.error(`发送消息到管理群组 ${groupId} 失败:`, error.message);
342
+ }
343
+ }
344
+ }
345
+ }
346
+
347
+ async checkAndSendNoActivityNotification(manualTest = false) {
348
+ if (!manualTest && this.sentNoActivityNotification) {
349
+ this.logger.debug("今日已发送过无活动通知,跳过");
350
+ return;
351
+ }
352
+
353
+ if (this.todayActivities.length > 0 || this.todayTMPEvents.length > 0) {
354
+ this.logger.debug(`今日有活动(车队平台: ${this.todayActivities.length}个, TMP: ${this.todayTMPEvents.length}个),不发送无活动通知`);
355
+ return;
356
+ }
357
+
358
+ this.logger.info(`${manualTest ? "手动测试" : "自动"}今日无活动,发送通知到管理群`);
359
+
360
+ for (const groupId of this.cfg.admin.groups) {
361
+ try {
362
+ await this.sendToGroup(groupId, this.cfg.noActivity.message, "管理群组");
363
+ this.logger.message(`已发送无活动通知到管理群组 ${groupId}`);
364
+ } catch (error) {
365
+ this.logger.error(`发送无活动通知到管理群组 ${groupId} 失败:`, error.message);
366
+ }
367
+ }
368
+
369
+ if (!manualTest) {
370
+ this.sentNoActivityNotification = true;
371
+ this.logger.debug("已标记今日无活动通知为已发送");
372
+ }
373
+ }
374
+
375
+ async checkActivityStatusChange() {
376
+ await this.updateActivityData();
377
+ if (this.sentNoActivityNotification && (this.todayActivities.length > 0 || this.todayTMPEvents.length > 0)) {
378
+ this.logger.info(`检测到活动状态变化:之前无活动,现在有活动(车队平台: ${this.todayActivities.length}个, TMP: ${this.todayTMPEvents.length}个)`);
379
+ this.sentNoActivityNotification = false;
380
+ await this.checkAndSendProfileReminders();
381
+ }
382
+ }
383
+
384
+ async checkAndSendActivityReminders() {
385
+ const now = new Date();
386
+ const today = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, '0')}-${now.getDate().toString().padStart(2, '0')}`;
387
+ const todayUTC = now.toISOString().split("T")[0];
388
+ let remindersSent = 0;
389
+ this.logger.debug(`检查 ${this.todayActivities.length} 个活动的提醒时间,当前本地日期: ${today}, UTC日期: ${todayUTC}`);
390
+
391
+ if (this.cfg.mainGroup.groups.length === 0) {
392
+ this.logger.warn(`未配置主群组ID (mainGroup.groups为空),活动提醒将无法发送`);
393
+ } else {
394
+ this.logger.debug(`已配置 ${this.cfg.mainGroup.groups.length} 个主群组: ${this.cfg.mainGroup.groups.join(', ')}`);
395
+ }
396
+
397
+ for (const activity of this.todayActivities) {
398
+ try {
399
+ const activityDate = activity.startTime?.split(" ")[0];
400
+ if (activityDate !== today) {
401
+ this.logger.debug(`跳过非今日活动 "${activity.themeName}",活动日期: ${activityDate},当前本地日期: ${today}`);
402
+ continue;
403
+ }
404
+
405
+ const activityStartTime = new Date(activity.startTime);
406
+ if (isNaN(activityStartTime.getTime())) {
407
+ this.logger.warn(`活动 "${activity.themeName}" 开始时间格式错误,跳过提醒`);
408
+ continue;
409
+ }
410
+
411
+ const timeDiff = activityStartTime.getTime() - now.getTime();
412
+ const totalSecondsLeft = Math.floor(timeDiff / 1000);
413
+ const minutesLeft = Math.floor(totalSecondsLeft / 60);
414
+ const secondsLeft = totalSecondsLeft % 60;
415
+ this.logger.debug(`活动 "${activity.themeName}" 剩余时间: ${minutesLeft} 分 ${secondsLeft} 秒`);
416
+ this.logger.debug(`活动 "${activity.themeName}" 时间检查: totalSecondsLeft=${totalSecondsLeft}, 触发条件: -300 <= ${totalSecondsLeft} <= 0`);
417
+
418
+ if (totalSecondsLeft >= -300 && totalSecondsLeft <= 0) {
419
+ const startReminderKey = `${activity.id}_started`;
420
+ if (!this.sentReminders.has(startReminderKey)) {
421
+ this.logger.info(`触发活动开始提醒: ${activity.themeName}`);
422
+ await this.sendActivityStartReminder(activity);
423
+ this.sentReminders.add(startReminderKey);
424
+ remindersSent++;
425
+ } else {
426
+ this.logger.debug(`活动 "${activity.themeName}" 开始提醒已发送过,跳过`);
427
+ }
428
+ } else {
429
+ this.logger.debug(`活动 "${activity.themeName}" 未满足开始提醒条件,当前剩余 ${totalSecondsLeft} 秒`);
430
+ }
431
+
432
+ if (totalSecondsLeft < 0) continue;
433
+ for (const reminderTime of this.cfg.mainGroup.activityReminderTimes) {
434
+ const reminderTimeSeconds = reminderTime * 60;
435
+ this.logger.debug(`活动 "${activity.themeName}" ${reminderTime}分钟前提醒检查: totalSecondsLeft=${totalSecondsLeft}, reminderTimeSeconds=${reminderTimeSeconds}, 条件: ${reminderTimeSeconds - 60} <= ${totalSecondsLeft} <= ${reminderTimeSeconds}`);
436
+ if (totalSecondsLeft <= reminderTimeSeconds && totalSecondsLeft > reminderTimeSeconds - 60) {
437
+ const reminderKey = `${activity.id}_${reminderTime}`;
438
+ if (!this.sentReminders.has(reminderKey)) {
439
+ this.logger.info(`触发活动前提醒: ${activity.themeName} - ${reminderTime} 分钟前`);
440
+ await this.sendActivityReminder(activity, reminderTime);
441
+ this.sentReminders.add(reminderKey);
442
+ remindersSent++;
443
+ } else {
444
+ this.logger.debug(`活动 "${activity.themeName}" ${reminderTime}分钟前提醒已发送过,跳过`);
445
+ }
446
+ }
447
+ }
448
+ } catch (error) {
449
+ this.logger.error(`处理活动 "${activity.themeName}" 提醒失败:`, error.message);
450
+ }
451
+ }
452
+
453
+ if (remindersSent > 0) {
454
+ this.logger.info(`本轮发送了 ${remindersSent} 个活动提醒`);
455
+ } else {
456
+ this.logger.debug(`本轮未发送任何活动提醒`);
457
+ }
458
+ }
459
+
460
+ createActivityReplacements(activity, tmpEvent, minutesLeft) {
461
+ const replacements = {
462
+ name: activity.themeName || '未知活动',
463
+ distance: activity.distance?.toString() || '未知'
464
+ };
465
+
466
+ if (minutesLeft !== undefined) {
467
+ replacements.timeLeft = minutesLeft.toString();
468
+ }
469
+
470
+ if (this.cfg.dataSource.serverSource === "tmp" && tmpEvent) {
471
+ replacements.server = tmpEvent.server?.name || '未知服务器';
472
+ } else {
473
+ replacements.server = activity.serverName || '未知服务器';
474
+ }
475
+
476
+ if (this.cfg.dataSource.startPointSource === "tmp" && tmpEvent) {
477
+ replacements.startingPoint = `${tmpEvent.departure?.location || ''} - ${tmpEvent.departure?.city || ''}`.trim() || '未知起点';
478
+ } else {
479
+ replacements.startingPoint = activity.startingPoint || '未知起点';
480
+ }
481
+
482
+ if (this.cfg.dataSource.endPointSource === "tmp" && tmpEvent) {
483
+ replacements.terminalPoint = `${tmpEvent.arrive?.location || ''} - ${tmpEvent.arrive?.city || ''}`.trim() || '未知终点';
484
+ } else {
485
+ replacements.terminalPoint = activity.terminalPoint || '未知终点';
486
+ }
487
+
488
+ if (this.cfg.dataSource.showBanner && tmpEvent && tmpEvent.banner) {
489
+ replacements.banner = tmpEvent.banner;
490
+ } else {
491
+ replacements.banner = "无";
492
+ }
493
+
494
+ return replacements;
495
+ }
496
+
497
+ async sendActivityStartReminder(activity) {
498
+ try {
499
+ const tmpEvent = this.todayTMPEvents.find(
500
+ (event) => event.name.includes(activity.themeName) || activity.themeName.includes(event.name)
501
+ );
502
+ this.logger.matching(`活动匹配: "${activity.themeName}" - 找到TMP匹配: ${!!tmpEvent}`);
503
+
504
+ const replacements = this.createActivityReplacements(activity, tmpEvent);
505
+
506
+ let message = this.cfg.mainGroup.activityStartReminderMessage;
507
+ for (const [key, value] of Object.entries(replacements)) {
508
+ message = message.replace(new RegExp(`{${key}}`, "g"), value);
509
+ }
510
+
511
+ if (!this.cfg.dataSource.showBanner) {
512
+ message = message.replace(/活动横幅:.*?\n?/, "");
513
+ }
514
+
515
+ message = message.replace(/\\n/g, "\n").trim();
516
+ const fullMessage = `@全体成员\n${message}`;
517
+
518
+ await this.sendToMainGroups(fullMessage, activity.themeName, "开始提醒");
519
+ } catch (error) {
520
+ this.logger.error(`发送活动开始提醒失败:`, error.message);
521
+ }
522
+ }
523
+
524
+ async sendActivityReminder(activity, minutesLeft) {
525
+ try {
526
+ const tmpEvent = this.todayTMPEvents.find(
527
+ (event) => event.name.includes(activity.themeName) || activity.themeName.includes(event.name)
528
+ );
529
+ this.logger.matching(`活动匹配: "${activity.themeName}" - 找到TMP匹配: ${!!tmpEvent}`);
530
+
531
+ const replacements = this.createActivityReplacements(activity, tmpEvent, minutesLeft);
532
+
533
+ let message = this.cfg.mainGroup.activityReminderMessage;
534
+ for (const [key, value] of Object.entries(replacements)) {
535
+ message = message.replace(new RegExp(`{${key}}`, "g"), value);
536
+ }
537
+
538
+ if (!this.cfg.dataSource.showBanner) {
539
+ message = message.replace(/活动横幅:.*?\n?/, "");
540
+ }
541
+
542
+ message = message.replace(/\\n/g, "\n").trim();
543
+ const fullMessage = `@全体成员\n${message}`;
544
+
545
+ await this.sendToMainGroups(fullMessage, activity.themeName, `${minutesLeft}分钟前提醒`);
546
+ } catch (error) {
547
+ this.logger.error(`发送活动提醒失败:`, error.message);
548
+ }
549
+ }
550
+
551
+ async sendToMainGroups(message, activityName, reminderType) {
552
+ for (const groupId of this.cfg.mainGroup.groups) {
553
+ try {
554
+ await this.sendToGroup(groupId, message, "主群组");
555
+ this.logger.message(`已发送${reminderType}到主群组 ${groupId}: ${activityName}`);
556
+ } catch (error) {
557
+ this.logger.error(`发送${reminderType}到主群组 ${groupId} 失败:`, error.message);
558
+ }
559
+ }
560
+ }
561
+
562
+ async sendToGroup(groupId, message, groupType) {
563
+ const availableBots = this.ctx.bots.filter((bot) => {
564
+ const unsupportedPlatforms = ["mail", "telegram", "discord", "qq", "wechat-official"];
565
+ return !unsupportedPlatforms.includes(bot.platform);
566
+ });
567
+
568
+ if (availableBots.length === 0) {
569
+ throw new Error(`没有可用的聊天平台适配器(当前不支持邮件/电报/Discord/QQ/微信公众号)`);
570
+ }
571
+
572
+ let lastError = null;
573
+ this.logger.debug(`尝试通过 ${availableBots.length} 个适配器发送消息到${groupType} ${groupId}`);
574
+
575
+ for (const bot of availableBots) {
576
+ try {
577
+ await bot.sendMessage(groupId, message);
578
+ this.logger.debug(`已通过 ${bot.platform} 适配器发送消息到${groupType} ${groupId}`);
579
+ return;
580
+ } catch (error) {
581
+ lastError = error;
582
+ this.logger.warn(`通过 ${bot.platform} 适配器发送消息失败: ${error.message}`);
583
+ }
584
+ }
585
+
586
+ throw lastError || new Error(`所有适配器都无法发送消息到${groupType} ${groupId}`);
587
+ }
588
+
589
+ cleanup() {
590
+ this.logger.debug("插件卸载,开始清理资源");
591
+ this.todayActivities = [];
592
+ this.todayTMPEvents = [];
593
+ this.sentReminders.clear();
594
+ this.timers.forEach((timer) => {
595
+ clearTimeout(timer);
596
+ clearInterval(timer);
597
+ });
598
+ this.timers.length = 0;
599
+ this.logger.debug("资源清理完成");
600
+ }
601
+ }
602
+
603
+ exports.ActivityService = ActivityService;