aozhiwei 29a32a5cbf 1
2022-09-21 21:06:32 +08:00

292 lines
8.8 KiB
JavaScript

const app = require('j7/app');
const utils = require('j7/utils');
const constant = require('../constant');
const YESTERDAY_HERO_NUM = 1000;
const YESTERDAY_GUN_NUM = 1000;
const PVP_TYPE = 0;
const PVE_TYPE = 1;
const PVP_RATIO = 0.6;
const PVE_RATIO = 0.4;
const ITEM_PRE = 'item_';
class Fragment {
async start() {
console.log('start');
while (true) {
await this.alloc(utils.getUtcTime());
const nowTime = utils.getUtcTime();
const daySeconds = utils.getDaySeconds(nowTime, constant.TIME_ZONE);
const hourSeconds = utils.getHourSeconds(nowTime, constant.TIME_ZONE);
const sleepTime = 3600 + 10;
await utils.sleep(sleepTime * 1000);
}
}
async alloc(nowTime) {
try {
const daySeconds = utils.getDaySeconds(nowTime, constant.TIME_ZONE);
const hourSeconds = utils.getHourSeconds(nowTime, constant.TIME_ZONE);
const {err, conn} = await app.getDbConn("GameDb20060");
if (err) {
throw err;
}
if (!err && conn) {
const isAlloced = await this.isAlloced(conn, daySeconds, nowTime, hourSeconds);
if (!isAlloced) {
const allocedFragments = await this.fetchAllocedFragments(conn, daySeconds, nowTime);
await this.realloc(conn, daySeconds, hourSeconds, nowTime, allocedFragments);
}
}
} catch (err) {
console.log(err);
}
}
async isAlloced(conn, daySeconds, nowTime, hourSeconds) {
const {err, row} = await conn.execQueryOne(
'SELECT * FROM t_fragment_pool WHERE alloc_time = ?',
[
daySeconds + hourSeconds
]
);
if (err) {
throw err;
return true;
}
return row ? true : false;
}
async fetchAllocedFragments(conn, daySeconds, nowTime) {
const {err, rows} = await conn.execQuery(
'SELECT * FROM t_fragment_pool WHERE alloc_time >= ? AND alloc_time <= ?',
[
daySeconds,
nowTime
]
);
if (err) {
throw err;
return;
}
const allocedFragments = new Map();
allocedFragments.set(PVP_TYPE, new Map());
allocedFragments.set(PVE_TYPE, new Map());
rows.forEach(
(element) => {
if (element['type'] == PVP_TYPE ||
element['type'] == PVE_TYPE) {
const data = allocedFragments.get(element['type']);
if (data) {
const num = Math.max(0, element['alloc_num'] - element['fragment_num']);
if (!data.has(element['fragment_id'])) {
data.set(element['fragment_id'], {
'fragment_id' : element['fragment_id'],
'num' : num
});
} else {
data.get(element['fragment_id'])['num'] += num
}
}
}
}
);
return allocedFragments;
}
async realloc(conn, daySeconds, nowTime, hourSeconds, allocedFragments) {
const hour = Math.floor((hourSeconds - daySeconds) / 3600);
const remainHour = Math.min(24, Math.max(1, 24 - hour));
const allocResult = new Map();
allocResult.set(PVP_TYPE, new Map());
allocResult.set(PVE_TYPE, new Map());
const allocFunc = (allocNode, list, data, num) => {
const items = [];
list.forEach(
(element) => {
items.push(
{
'item_id': element,
'item_num': data.get(ITEM_PRE + element)
}
);
});
for (let i = 0; i < num; ++i) {
const ret = utils.randItemByWeight(items, 'item_num');
if (ret.index >= 0) {
if (items[ret.index]['item_num'] > 0) {
--items[ret.index]['item_num'];
const item = allocNode.get(ret.item.item_id);
if (!item) {
allocNode.set(ret.item.item_id, 1);
} else {
allocNode.set(ret.item.item_id, allocNode.get(ret.item.item_id) + 1);
}
}
}
}
};
const remainData = await this.getRemainData(daySeconds, nowTime, hourSeconds, allocedFragments);
console.log(remainData);
remainData.forEach(
(value, key) => {
const allocNode = allocResult.get(key);
const heroNum = Math.floor(remainData.get(key).get('remainHeroNum') / remainHour);
const gunNum = Math.floor(remainData.get(key).get('remainGunNum') / remainHour);
allocFunc(allocNode, constant.ALL_HERO_FRAGMENT, value, heroNum);
allocFunc(allocNode, constant.ALL_GUN_FRAGMENT, value, gunNum);
});
const items = [];
allocResult.forEach(
(value, key) => {
value.forEach(
(value2, key2) => {
items.push({
'type' : key,
'item_id': key2,
'item_num': value2
});
}
);
}
);
await utils.serial(
items,
(element) => {
await conn.insert(
't_fragment_pool',
['fragment_id', element['item_id']],
['type', element['type']],
//['fragment_type', element['type']],
['fragment_num', element['item_num']],
['alloc_num', element['item_num']],
['alloc_time', hourSeconds],
['createtime', nowTime],
['modifytime', nowTime],
)
}
);
}
async getRemainData(daySeconds, nowTime, hourSeconds, allocedFragments) {
const totalHeroNum = this.getYesterDayHeroNum();
const totalGunNum = this.getYesterDayGunNum();
const normalHeroNum = Math.floor(totalHeroNum * 0.06 * 8);
const specHeroNum = Math.floor(totalHeroNum * 0.02);
const normalGunNum = Math.floor(totalGunNum * 0.06 * 8);
const specGunNum = Math.floor(totalGunNum * 0.02);
const remainData = new Map();
remainData.set(PVP_TYPE, new Map());
remainData.set(PVE_TYPE, new Map());
remainData.forEach(
(value, key) => {
switch (key) {
case PVP_TYPE:
{
value.set('normalHeroNum', Math.floor(normalHeroNum * PVP_RATIO));
value.set('specHeroNum', Math.floor(specHeroNum * PVP_RATIO));
value.set('normalGunNum', Math.floor(normalGunNum * PVP_RATIO));
value.set('specGunNum', Math.floor(specGunNum * PVP_RATIO));
value.set('remainHeroNum', 0);
value.set('remainGunNum', 0);
}
break;
case PVE_TYPE:
{
value.set('normalHeroNum', Math.floor(normalHeroNum * PVE_RATIO));
value.set('specHeroNum', Math.floor(specHeroNum * PVE_RATIO));
value.set('normalGunNum', Math.floor(normalGunNum * PVE_RATIO));
value.set('specGunNum', Math.floor(specGunNum * PVE_RATIO));
value.set('remainHeroNum', 0);
value.set('remainGunNum', 0);
}
break;
default:
{
return;
}
break;
}//end switch
const data = allocedFragments.get(key);
constant.ALL_HERO_FRAGMENT.forEach(
(element) => {
if (element == constant.SPEC_HERO_FRAGMENT) {
const allocedNum = data.get(element);
let remainNum = value.get('specHeroNum');
if (allocedNum) {
remainNum = Math.max(0, remainNum - allocedNum);
}
value.set(ITEM_PRE + element, remainNum);
value.set('remainHeroNum', value.get('remainHeroNum') + remainNum);
} else {
const allocedNum = data.get(element);
let remainNum = Math.floor(value.get('normalHeroNum') / 8);
if (allocedNum) {
remainNum = Math.max(0, remainNum - allocedNum);
}
value.set(ITEM_PRE + element, remainNum);
value.set('remainHeroNum', value.get('remainHeroNum') + remainNum);
}
}
);//end forEach
constant.ALL_GUN_FRAGMENT.forEach(
(element) => {
if (element == constant.SPEC_GUN_FRAGMENT) {
const allocedNum = data.get(element);
let remainNum = value.get('specGunNum');
if (allocedNum) {
remainNum = Math.max(0, remainNum - allocedNum);
}
value.set(ITEM_PRE + element, remainNum);
value.set('remainGunNum', value.get('remainGunNum') + remainNum);
} else {
const allocedNum = data.get(element);
let remainNum = Math.floor(value.get('normalGunNum') / 8);
if (allocedNum) {
remainNum = Math.max(0, remainNum - allocedNum);
}
value.set(ITEM_PRE + element, remainNum);
value.set('remainGunNum', value.get('remainGunNum') + remainNum);
}
}
);//end forEach
}
);//end forEach
return remainData;
}
getYesterDayHeroNum() {
return YESTERDAY_HERO_NUM;
}
getYesterDayGunNum() {
return YESTERDAY_GUN_NUM;
}
}
function init() {
(new Fragment()).start();
}
exports.init = init;