aozhiwei 179636f7e8 ...
2022-12-06 10:22:24 +08:00

185 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const app = require('j7/app');
const utils = require('j7/utils');
const metaFactory = require('../metadata/factory');
const constant = require('../constant');
class Season {
seasonList = [];
async start() {
console.log("season ranking start1");
while (true) {
await this.doRoutine(utils.getUtcTime());
const nowTime = utils.getUtcTime();
const daySeconds = utils.getDaySeconds(nowTime, constant.TIME_ZONE);
const sleepTime = daySeconds + 3600 * 24 - nowTime;
await utils.sleep(sleepTime*1000);
}
}
async doRoutine(nowTime) {
try {
console.log("season ranking start2");
// console.time("season ranking");
this.seasonList = [];
metaFactory.traverseMetaList("RankSeason", (config, idx) => {
this.seasonList.push({
start_time: new Date(config.start_time+" GMT+0000").getTime()/1000,
end_time: new Date(config.end_time+" GMT+0000").getTime()/1000,
id: config.id
});
return true;
});
console.log("season ranking",this.seasonList);
if (this.checkSeasonEnd(nowTime)) {
await this.calcRanking(nowTime);
}
// console.timeLog("season ranking");
// console.timeEnd("season ranking");
console.log("season ranking end");
}
catch(err) {
console.log(err);
}
}
checkSeasonEnd(nowTime) {
let c = this.getCurSeasonId(nowTime);
if (!!c) {
return (nowTime>c.end_time);
}
return false;
}
getCurSeasonId(nowTime) {
let s = this.seasonList[0];
for( let c of this.seasonList) {
if (nowTime >= c.start_time) {
s = c;
}
}
return s;
}
async calcRanking(nowTime) {
console.log("calc ranking...");
const {err, conn} = await app.getDbConn("GameDb20060");
if (err) {
throw err;
}
if (!err && conn) {
// 检查是否本赛季已完成排名
const seasonId = this.getCurSeasonId(nowTime).id;
if (!await this.alreadySorted(conn,seasonId)) {
// 从user表中遍历所有用户每次取1000个用户逐步加入到排序表中
let sorted = [];
let lastIdx = 0;
while(lastIdx>=0) {
const result = await this.getRecords(conn, lastIdx, 1000);
lastIdx = result.lastIdx;
if (lastIdx != -1) {
this.insertNewRecords(sorted, result.records)
}
}
await this.pushRankingResult(conn, sorted, seasonId);
}
else {
console.log("already calc ranking, no need to calc");
}
}
console.log("calc ranking...done");
}
async alreadySorted(conn, seasonId) {
const {err, rows} = await conn.execQuery(
'SELECT idx from t_season_ranking where season=? LIMIT 1',
[
seasonId
]
);
if (err) {
throw err;
}
return rows.length>0;
}
async getRecords(conn, lastIdx, limit) {
const {err, rows} = await conn.execQuery(
'select idx,account_id,channel,rank,score from t_user where idx > ? order by idx LIMIT ?',
[
lastIdx,
limit
]
);
if (err) {
throw err;
}
if (rows.length==0) {
return {
lastIdx: -1,
records: []
};
}
return {
lastIdx: rows[rows.length-1].idx,
records: rows
};
}
insertNewRecords(sorted, records) {
// 根据分数加入到排序表中始终保留钱10000名
// console.time("inserNewRecords");
for (let element of records) {
if (element.score>0) {
sorted.push(element);
sorted.sort(function(a,b) {
return b.score - a.score;
});
}
}
if (sorted.length>10000) {
sorted.length = 10000;
}
// console.timeLog("inserNewRecords");
// console.timeEnd("inserNewRecords");
}
async pushRankingResult(conn, sorted, seasonId) {
// 计算排名并存入数据库
// console.log(sorted);
const nowTime = utils.getUtcTime();
await utils.serial(
sorted,
async (element, index) => {
await conn.insert(
't_season_ranking',
[
['account_id', element['account_id']],
['channel', element['channel']],
['rank', element['rank']],
['score', element['score']],
['ranking', index+1],
['season', seasonId],
['createtime', nowTime],
['modifytime', nowTime],
]
)
}
);
}
}
function init() {
(new Season()).start();
}
exports.init = init;