This commit is contained in:
hujiabin 2023-10-13 14:57:28 +08:00
parent 74e93a6016
commit 0e59a42078
3 changed files with 340 additions and 327 deletions

View File

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

View File

@ -1,19 +1,19 @@
begin; begin;
CREATE TABLE `t_avatar` ( CREATE TABLE `t_avatar` (
`idx` bigint NOT NULL AUTO_INCREMENT COMMENT '自增id', `idx` bigint NOT NULL AUTO_INCREMENT COMMENT '自增id',
`account_id` varchar(60) NOT NULL DEFAULT '' COMMENT '账号id(channel + "_" + gameid + "_" + openid)', `account_id` varchar(60) NOT NULL DEFAULT '' COMMENT '账号id(channel + "_" + gameid + "_" + openid)',
`token_id` varchar(60) COMMENT 'token_id', `token_id` varchar(60) COMMENT 'token_id',
`item_id` int(11) NOT NULL COMMENT 'item_id', `item_id` int(11) NOT NULL COMMENT 'item_id',
`item_type` int(11) NOT NULL COMMENT 'item类型', `item_type` int(11) NOT NULL COMMENT 'item类型',
`status` int(11) NOT NULL DEFAULT '0' COMMENT '装备状态', `status` int(11) NOT NULL DEFAULT '0' COMMENT '装备状态',
`hero_idx` bigint DEFAULT NULL COMMENT '英雄外键id', `hero_idx` bigint DEFAULT NULL COMMENT '英雄外键id',
`createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
`modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', `modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间',
PRIMARY KEY (`idx`), PRIMARY KEY (`idx`),
UNIQUE KEY `hero_idx_type` (`hero_idx`, `item_type`) UNIQUE KEY `hero_idx_type` (`hero_idx`, `item_type`)
) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
insert into version (version) values(2023092001); insert into version (version) values(2023092001);
commit; commit;

View File

@ -1,103 +1,116 @@
<?php <?php
require_once('models/Hero.php'); require_once('models/Hero.php');
require_once('mt/NftDesc.php'); require_once('models/Nft.php');
require_once('mt/Hero.php'); require_once('mt/NftDesc.php');
require_once('mt/Hero.php');
use models\Hero;
use models\Hero;
class RestApiController extends BaseController { use models\Nft;
public function dispatch() class RestApiController extends BaseController {
{
//REQUEST_URI /api/nft/$netId/$nftType/$tokenId public function dispatch()
$requestUri = $_SERVER['REQUEST_URI']; {
if (!empty($requestUri)) { //REQUEST_URI /api/nft/$netId/$nftType/$tokenId
$idx = strpos($requestUri, '/api/nft/'); $requestUri = $_SERVER['REQUEST_URI'];
if ($idx == 0) { if (!empty($requestUri)) {
$tmpStrs = explode('?', $requestUri); $idx = strpos($requestUri, '/api/nft/');
$requestUri = count($tmpStrs) > 0 ? $tmpStrs[0] : ''; if ($idx == 0) {
$this->nftInfo(explode('/', $requestUri)); $tmpStrs = explode('?', $requestUri);
} $requestUri = count($tmpStrs) > 0 ? $tmpStrs[0] : '';
} $this->nftInfo(explode('/', $requestUri));
} }
}
/* }
https://game2006api.cebggame.com/api/nft/$netId/$nftType/$tokenId
$netId: 链id(网络id) /*
$nftType: 目前就hero https://game2006api.cebggame.com/api/nft/$netId/$nftType/$tokenId
$tokenIdtokenid $netId: 链id(网络id)
*/ $nftType: 目前就hero,planet
private function nftInfo($path) $tokenIdtokenid
{ */
if (count($path) < 5) { private function nftInfo($path)
return; {
} if (count($path) < 5) {
$netId = $path[3]; return;
$nftType = $path[4]; }
$tokenId = $path[5]; $netId = $path[3];
$heroDb = Hero::findByTokenId2($tokenId); $nftType = $path[4];
$tokenId = $path[5];
if (!$heroDb){ $info = array(
echo json_encode(array( "name" => "",
"name" => "", "description" => "",
"description" => "", "image" => "",
"image" => "", "attributes" => array(),
"attributes" => array(), );
)); switch ($nftType){
die; case "hero" :{
} $heroDb = Hero::findByTokenId2($tokenId);
$heroMeta = \mt\Hero::get($heroDb['hero_id']); if (!$heroDb){
$NftMeta = \mt\NftDesc::getByItemId($heroDb['hero_id']); echo json_encode($info);
//https://www.cebg.games/res/nfts/30100.png die;
$info = array( }
"name" => $heroMeta['name'], $heroMeta = \mt\Hero::get($heroDb['hero_id']);
"description" => $NftMeta['desc'], $NftMeta = \mt\NftDesc::getByItemId($heroDb['hero_id']);
"image" => "https://www.cebg.games/res/nfts/".$heroDb['hero_id'].".png", //https://www.cebg.games/res/nfts/30100.png
"attributes" => array(), $info['name'] = $heroMeta['name'];
); $info['description'] = $NftMeta['desc'];
array_push($info['attributes'],array( $info['image'] = "https://www.cebg.games/res/nfts/".$heroDb['hero_id'].".png";
"trait_type" => "level", array_push($info['attributes'],array(
"value" => intval($heroDb['hero_lv']), "trait_type" => "level",
"max_value" => 15, "value" => intval($heroDb['hero_lv']),
)); "max_value" => 15,
$randAttr = emptyReplace(json_decode($heroDb['rand_attr'], true), array()); ));
foreach ($randAttr as $attr){ $randAttr = emptyReplace(json_decode($heroDb['rand_attr'], true), array());
switch ($attr['quality']){ foreach ($randAttr as $attr){
case 1 : $quality = "D";break; switch ($attr['quality']){
case 2 : $quality = "C";break; case 1 : $quality = "D";break;
case 3 : $quality = "B";break; case 2 : $quality = "C";break;
case 4 : $quality = "A";break; case 3 : $quality = "B";break;
case 5 : $quality = "S";break; case 4 : $quality = "A";break;
default : $quality = ""; case 5 : $quality = "S";break;
} default : $quality = "";
switch ($attr['attr_id']){ }
case kHAT_Hp : { switch ($attr['attr_id']){
array_push($info['attributes'],array( case kHAT_Hp : {
"trait_type" => "Hp", array_push($info['attributes'],array(
// "value" => intval($attr['val']), "trait_type" => "Hp",
"value" => $quality, "value" => $quality,
)); ));
} }
break; break;
case kHAT_Atk : { case kHAT_Atk : {
array_push($info['attributes'],array( array_push($info['attributes'],array(
"trait_type" => "Atk", "trait_type" => "Atk",
// "value" => intval($attr['val']), "value" => $quality,
"value" => $quality, ));
)); }
} break;
break; case kHAT_Def : {
case kHAT_Def : { array_push($info['attributes'],array(
array_push($info['attributes'],array( "trait_type" => "Def",
"trait_type" => "Def", "value" => $quality,
// "value" => intval($attr['val']), ));
"value" => $quality, }
)); }
} }
} }
} break;
echo json_encode($info); case "planet" : {
} $planetDb = Nft::getNft($tokenId);
if (!$planetDb){
} echo json_encode($info);
die;
}
$NftMeta = \mt\NftDesc::getByItemId($planetDb['item_id']);
$info['name'] = $NftMeta['name'] ? : "planet";
$info['description'] = $NftMeta['desc'] ? : "planet";
$info['image'] = "https://www.cebg.games/res/nfts/".$planetDb['item_id'].".png";
}
}
echo json_encode($info);
}
}