diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..102ab54 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "ms-ceintl.vscode-language-pack-zh-hans" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..3986f4a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "editor.suggest.snippetsPreventQuickSuggestions": false, + "aiXcoder.showTrayIcon": true +} \ No newline at end of file diff --git a/src/api_o2s/hdinfo/Apidetails.ts b/src/api_o2s/hdinfo/Apidetails.ts index 3e26fba..d96e313 100644 --- a/src/api_o2s/hdinfo/Apidetails.ts +++ b/src/api_o2s/hdinfo/Apidetails.ts @@ -32,7 +32,7 @@ export default async function (call: ApiCall) { let _tmp = { ranking: index, participantId: elementUser.uid, - value: await (await PayFun.getPayDaysAllPayNum(elementUser.uid, element.stime, element.rtime)).toString() + value: await (await PayFun.getPayDaysAllPayNum(elementUser.uid, element.stime, element.etime)).toString() } accountingData.push(_tmp) } diff --git a/src/api_s2c/event/leijichongzhi/ApiOpen.ts b/src/api_s2c/event/leijichongzhi/ApiOpen.ts index 801ee88..6796c39 100644 --- a/src/api_s2c/event/leijichongzhi/ApiOpen.ts +++ b/src/api_s2c/event/leijichongzhi/ApiOpen.ts @@ -23,10 +23,10 @@ export default async function (call: ApiCall) { {upsert: true} ); } - db = await checkNextRound(call, db, _hdinfo.data.tasks) + db = await checkNextRound(call, db, _hdinfo) let payNum = (await PayFun.getPayDaysAllPayNum(call.uid, _hdinfo.stime, _hdinfo.rtime)) * 10 - payNum = payNum - (db.round || 0) * R.sort((a, b) => b.total - a.total)(_hdinfo.data.tasks)[0].total + payNum = payNum - (db?.round || 0) * R.sort((a, b) => b.total - a.total)(_hdinfo.data.tasks)[0].total call.succ({ sTime: sTime, diff --git a/src/api_s2c/event/leijichongzhi/ApiRec.ts b/src/api_s2c/event/leijichongzhi/ApiRec.ts index 55f9aef..27d601b 100644 --- a/src/api_s2c/event/leijichongzhi/ApiRec.ts +++ b/src/api_s2c/event/leijichongzhi/ApiRec.ts @@ -20,7 +20,7 @@ export default async function (call: ApiCall) { let db = await G.mongodb.cEvent(_dbType).findOne({uid: call.uid, type: _dbType}); if (db.recIndex.includes(call.req.index)) return call.error('', {code: -2}); - let payNum = (await PayFun.getPayDaysAllPayNum(call.uid, _hdinfo.stime, _hdinfo.rtime)) * 10; + let payNum = (await PayFun.getPayDaysAllPayNum(call.uid, _hdinfo.stime, _hdinfo.etime)) * 10; payNum = payNum - (db.round || 0) * R.sort((a, b) => b.total - a.total)(_hdinfo.data.tasks)[0].total if (payNum < conf.total) return call.error('', {code: -3}); @@ -31,7 +31,7 @@ export default async function (call: ApiCall) { {$push: {recIndex: call.req.index}} ); - await checkNextRound(call, db, _hdinfo.data.tasks) + await checkNextRound(call, db, _hdinfo) HongDianChange.sendChangeKey(call.uid, ['huodonghd']) call.succ({ @@ -39,9 +39,13 @@ export default async function (call: ApiCall) { }); } -export async function checkNextRound(call: ApiCall, event, tasks) { +export async function checkNextRound(call: ApiCall, event, _hdinfo) { + if ((event?.recIndex?.length || 0) < _hdinfo.data.tasks.length) return event + let payNum = (await PayFun.getPayDaysAllPayNum(call.uid, _hdinfo.stime, _hdinfo.etime)) * 10 + payNum = payNum - (event?.round || 0) * R.sort((a, b) => b.total - a.total)(_hdinfo.data.tasks)[0].total + if (payNum < 0) return event + let _dbType: `leijichongzhi${number}` = `leijichongzhi${call.req.hdid}` - if ((event?.recIndex?.length || 0) < tasks.length) return event return (await G.mongodb.cEvent(_dbType).findOneAndUpdate( {uid: call.uid, type: _dbType}, {$set: {recIndex: []}, $inc: {round: 1}}, {returnDocument: 'after'} diff --git a/src/api_s2c/hongdian/fun.ts b/src/api_s2c/hongdian/fun.ts index f8a301b..ec2094a 100644 --- a/src/api_s2c/hongdian/fun.ts +++ b/src/api_s2c/hongdian/fun.ts @@ -656,7 +656,7 @@ export class HuoDongHongDianFun { let _con = hdCon.data.tasks; let db = await G.mongodb.cEvent(_dbType).findOne({uid: call.uid, type: _dbType}); let _mydata = db || {sTime: PublicShared.getToDayZeroTime(G.time), recIndex: []}; - let payNum = await PayFun.getPayDaysAllPayNum(call.uid, hdCon.stime, hdCon.rtime); + let payNum = await PayFun.getPayDaysAllPayNum(call.uid, hdCon.stime, hdCon.etime); for (let index = 0; index < _con.length; index++) { const element = _con[index]; if (_mydata.recIndex.includes(index)) continue; diff --git a/src/api_s2c/xstask/ApiOnekeyReceive.ts b/src/api_s2c/xstask/ApiOnekeyReceive.ts index b8e4981..a776b77 100644 --- a/src/api_s2c/xstask/ApiOnekeyReceive.ts +++ b/src/api_s2c/xstask/ApiOnekeyReceive.ts @@ -44,6 +44,7 @@ export default async function (call: ApiCall if (star < taskConf.needStar) return call.error(globalThis.lng.xstask_8); change[receive._id] = { time: G.time, heros: receive.heroIds }; + XstaskFun.receiveNum(call.uid) } Object.entries(change).forEach(([k, v]) => { diff --git a/src/extends.ts b/src/extends.ts index 1d4b16e..82737d2 100644 --- a/src/extends.ts +++ b/src/extends.ts @@ -256,7 +256,7 @@ BaseConnection.prototype.refreshPower = async function (this: BaseConnection 0) this.conn.refreshPower(); break; case 'msg_s2c/LshdChange': - this.conn.lshd[msgKey] && PublicShared.mergeProperty(this.conn.lshd[msgKey], msg); + this.conn?.lshd?.[msgKey] && PublicShared.mergeProperty(this.conn.lshd[msgKey], msg); break; } }; diff --git a/src/gameLog.ts b/src/gameLog.ts index 9242fb2..6f1ca12 100644 --- a/src/gameLog.ts +++ b/src/gameLog.ts @@ -1,8 +1,8 @@ import { Db, MongoClient } from "mongodb"; import { Logger } from "tsrpc"; -let logDB:Db; -let errorLogDB:Db; +export let logDB:Db; +export let errorLogDB:Db; /** * 是否是G123的测试服 @@ -11,7 +11,7 @@ function isG123stg(){ return G.config.mongodbUrl.indexOf('.stg.')!=-1; } -async function connGameLogDB() { +export async function connGameLogDB() { console.log('connect gamelog mongodb ......'); let logDBUrl:string; if(G.config.isG123){ @@ -73,6 +73,28 @@ async function addErrorLog(errData:any){ } } +export async function addWatchDogLog(data:object[]){ + try{ + //g123测试版连接不上db,不抓取 + if(!data)return; + if(isG123stg())return; + let log = { + serverId : G.config.serverId, + pid : process.pid, + cTime : Math.floor(Date.now()/1000) + } + data.map(item=>{ + Object.assign(item,log) + }) + if(!errorLogDB){ + await connGameLogDB(); + } + errorLogDB.collection('nodeJsErrorLog').insertMany(data); + }catch(e){ + console.error('addWatchDogLog',e); + } +} + /** * 增加游戏日志 * @param uid 玩家uid diff --git a/src/localConfig.ts b/src/localConfig.ts index 5b04b02..0738259 100644 --- a/src/localConfig.ts +++ b/src/localConfig.ts @@ -2,22 +2,22 @@ export default { /**时区偏移量 */ utc: 8, - /**是否开发模式 */ +/**是否开发模式 */ debug: true, /**消息服socket端口*/ msgPort: 7778, /**http端口 msg服专用*/ - // httpPort: 7779, + httpPort: 7779, /**跨服socket端口 */ crossPort: 7780, /**跨服 ws url */ - corssWsUrl: "ws://10.0.1.20:10003", + corssWsUrl: "ws://localhost:7780", /**服务器id */ - serverId: 1001, + serverId: 15, /**redis url */ redisUrl: 'redis://:lyMaple525458@10.0.1.20:6379/0', /**mongodb url */ - mongodbUrl: 'mongodb://root:lyMaple525458@10.0.1.20:27017/heijiao?authSource=admin', + mongodbUrl: 'mongodb://root:lyMaple525458@10.0.1.20:27017/heijiao_cl?authSource=admin', /**cross redis url */ crossRedisUrl: 'redis://:lyMaple525458@10.0.1.20:6379/1', /**cross mongodb url */ @@ -27,11 +27,13 @@ export default { /**服务器时间 */ time: '', /**开服时间 */ - openTime: '2023-12-11 1:0:0', + openTime: '2023-12-05 01:00:00', /**项目名称 */ projectName: 'heijiao', /**加密key */ APIKEY: 'uutown123456', + /**是否已经开区 */ + opened:true, /**wss */ wss: { key: '', diff --git a/src/oss/watchdog.json b/src/oss/watchdog.json new file mode 100644 index 0000000..e60bb3e --- /dev/null +++ b/src/oss/watchdog.json @@ -0,0 +1,72 @@ +[ + { + "key":"jiuba/Lottery", + "limit":300, + "tips":"酒馆抽取次数达到300次" + }, + { + "key":"got_jinbi", + "limit":200000000, + "tips":"jinbi获取达到20亿" + }, + { + "key":"got_rmbmoney", + "limit":30000, + "tips":"钻石获取达到3万" + }, + { + "key":"use_attr_rmbmoney", + "limit":100000, + "tips":"钻石消耗达到10万" + }, + { + "key":"tanxian/FastGuaJi", + "limit":40, + "tips":"快速探险达到40次" + }, + { + "key":"xstask/Receive/Num", + "limit":8, + "tips":"接取悬赏任务超过8个" + }, + { + "key":"dixiaqianzhuang/Qf", + "limit":500, + "tips":"地下钱庄使用次数超过500次" + }, + { + "key":"shop/Buy/2", + "limit":50, + "tips":"势力商店购买某一商品超过50次" + }, + { + "key":"shop/Buy/1", + "limit":10, + "tips":"杂货商店购买某一商品超过10次" + }, + { + "key":"peijiancangku/Jump", + "limit":500, + "tips":"指定高级仓库超过50次" + }, + { + "key":"meirishilian/Fight", + "limit":30, + "tips":"物资缴获挑战和扫荡累计超过30次" + }, + { + "key":"pata/SaoDang", + "limit":5, + "tips":"黑暗塔扫荡次数超过5次" + }, + { + "key":"lingzhulaixi/PkBoss", + "limit":15, + "tips":"讨伐海盗挑战次数超过15次" + }, + { + "key":"gonghui/FbFight", + "limit":5, + "tips":"势力战斗boss超过5次" + } +] \ No newline at end of file diff --git a/src/public/player.ts b/src/public/player.ts index 9237363..2647bce 100644 --- a/src/public/player.ts +++ b/src/public/player.ts @@ -18,6 +18,7 @@ import {getItemByItemId, getItemNum} from './item'; import {getGud, setGud} from './gud'; import {addGameLog} from "../gameLog"; import {PushGiftFun} from "./pushgift"; +import { ActionLog } from './actionLog/actionLog'; export type call = { @@ -178,6 +179,12 @@ export class PlayerFun { G.emit("Class_task_156", 'Class_task_156', call, -atn.n, 0); } } + + if( (atn.t == 'rmbmoney' || atn.t == 'jinbi') && atn.n > 0 ){ + //统计今日获取的金币和钻石 + ActionLog.addDayLog(call.conn.uid, { key: 'got_'+atn.t, val: atn.n }); + } + // 增加vip经验的任务监听 if (atn.t == "payExp" && atn.n > 0) { G.emit("Class_task_157", 'Class_task_157', call, atn.n, 0); diff --git a/src/public/scheduler/scheduler.ts b/src/public/scheduler/scheduler.ts index 438360c..5c0d92f 100644 --- a/src/public/scheduler/scheduler.ts +++ b/src/public/scheduler/scheduler.ts @@ -38,6 +38,7 @@ export type schedulerType = | 'hbzb_zbs_group' | 'wzry_zuanshi16to8' | "cross_email_pull" + | "watch_dog" | "xiaofeijingsai_local_ctor"; export class SchedulerManage { diff --git a/src/public/scheduler/scheduler_watchdog.ts b/src/public/scheduler/scheduler_watchdog.ts new file mode 100644 index 0000000..6ef9bb8 --- /dev/null +++ b/src/public/scheduler/scheduler_watchdog.ts @@ -0,0 +1,105 @@ +import {resolve} from "path"; +import {PublicShared} from "../../shared/public/public"; +import {Scheduler, schedulerType} from "./scheduler"; +import {existsSync, readFileSync} from "fs"; +import {addWatchDogLog, errorLogDB} from "../../gameLog"; + +export class WatchDog extends Scheduler { + id: schedulerType = "watch_dog"; + time = 420; // 监控频率,每x秒一次 + name = "数据看门狗" + type = "" + + async read() { + await this.ctorStartTime(); + this.isReady = false; + this.startTime = this.nextTime; + } + + async start() { + let confFile = resolve(__dirname, '../../oss/watchdog.json'); + if (!existsSync(confFile)) { + //配置文件不存在 + await this.ctorStartTime() + return; + } + let conf; + try { + conf = await JSON.parse(readFileSync(confFile, 'utf-8')); + } catch (e) { + //配置文件不是json + await this.ctorStartTime() + return; + } + //获取今天0点之后在线的玩家 + let users = await G.mongodb.collection("user").find({ + lv: {$gt: 10}, + newonlinetime: {$gte: G.time - 3600, $lte: G.time + 30} + }, { + projection: { + uid: 1, + name: 1, + lv: 1, + vip: 1, + sid: 1 + } + }).toArray(); + + if (!users.length) { + //没有符合的玩家 + await this.ctorStartTime() + return; + } + + let uids = users.map(i => i.uid); + let uinfo = {}; + users.map(i => uinfo[i.uid] = i); + + let actionLogs = await G.mongodb.collection("actionLog").find({ + type: 'day', + uid: {$in: uids}, + }, { + projection: { + uid: 1, + log: 1 + } + }).toArray(); + + let warns = []; + for (let j = 0; j < conf.length; j++) { + for (let i = 0; i < actionLogs.length; i++) { + let key = conf[j].key; + let myval = actionLogs[i]?.log?.[key] || 0 + let uid = actionLogs[i].uid + if (myval > conf[j].limit) { + //触发了警报 + warns.push({ + type: 'watchDog', + uid: uid, + name: uinfo[uid]?.name, + lv: uinfo[uid]?.lv, + vip: uinfo[uid]?.vip, + key: key, + value: myval, + tips: conf[j].tips + }) + } + } + } + + if (warns.length > 0) { + addWatchDogLog(warns); + } + + await this.ctorStartTime() + } + + get nextTime(): number { + return G.time + this.time; + } + + async ctorStartTime() { + this.isStart = false; + this.startTime = this.nextTime; + } +} \ No newline at end of file diff --git a/src/public/wzry.ts b/src/public/wzry.ts index 02e848b..efb036d 100644 --- a/src/public/wzry.ts +++ b/src/public/wzry.ts @@ -40,7 +40,7 @@ export class WangZheRongYaofun { /**获取报名人数 */ static async getBaoMingNum() { let zkey: string = PublicShared.getToWeek(); - let _num = G.mongodb.collection('playerInfo', 'wzry').countDocuments({ isbm: 1 }); + let _num = G.mongodb.collection('playerInfo', 'wzry').countDocuments({ type:'wzry', isbm: 1 }); return _num; } diff --git a/src/public/xstask.ts b/src/public/xstask.ts index ef277a9..cfdce3d 100644 --- a/src/public/xstask.ts +++ b/src/public/xstask.ts @@ -3,6 +3,7 @@ import {ApiCall} from 'tsrpc'; import {playerInfoType} from '../module/collection_palyerInfo'; import {CollectionXstask} from '../module/collection_xstask'; import {PublicShared} from '../shared/public/public'; +import {ActionLog} from "./actionLog/actionLog"; export class XstaskFun { @@ -166,6 +167,7 @@ export class XstaskFun { G.mongodb.cEvent('xstask').updateOne({uid: uid, type: 'xstask'}, {$set: {refreshTime: G.time, receiveNum: 0}}, {upsert: true}); } else { + ActionLog.addDayLog(uid, { key: "xstask/Receive/Num", val: 1 }); G.mongodb.cEvent('xstask').updateOne({uid: uid, type: 'xstask'}, {$inc: {receiveNum: 1}}, {upsert: true}); } diff --git a/src/setStartAfther.ts b/src/setStartAfther.ts index 25c609c..19ebf83 100644 --- a/src/setStartAfther.ts +++ b/src/setStartAfther.ts @@ -29,6 +29,7 @@ import { SchedulerManage } from './public/scheduler/scheduler'; import {CrossEmailPull} from "./public/scheduler/scheduler_cross_email_pull"; import {Scheduler_xfjs_Local_Ctor} from "./public/scheduler/scheduler_xiaofeijingsai"; import { RankKfjs_1, RankKfjs_2, RankKfjs_3, RankKfjs_4, RankKfjs_5, RankKfjs_6, RankKfjs_7 } from './public/rank/rank_kfjs'; +import { WatchDog } from './public/scheduler/scheduler_watchdog'; export async function startAfter() { //事件监听和定时器初始化 @@ -93,6 +94,7 @@ export async function startAfter() { // new SchedulerWzrycrossEmail(); new CrossEmailPull().init() + new WatchDog().init(); }); new SchedulerNewDayLocalCtor().init();