|
|
@@ -15,9 +15,23 @@ const Request = {
|
|
|
|
|
|
const GAMES = {
|
|
|
List: {},
|
|
|
- Relations: {}
|
|
|
+ Relations: {},
|
|
|
+ Solutions: {},
|
|
|
};
|
|
|
|
|
|
+/**
|
|
|
+ * 精确浮点数字
|
|
|
+ * @param {number} number
|
|
|
+ * @param {number} x
|
|
|
+ * @returns {number}
|
|
|
+ */
|
|
|
+const fixFloat = (number, x=2) => {
|
|
|
+ return parseFloat(number.toFixed(x));
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 更新比赛列表
|
|
|
+ */
|
|
|
const updateGamesList = (({ platform, mk, games } = {}) => {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
if (!platform || !games) {
|
|
|
@@ -93,6 +107,9 @@ const updateGamesList = (({ platform, mk, games } = {}) => {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
+/**
|
|
|
+ * 更新比赛盘口
|
|
|
+ */
|
|
|
const updateGamesEvents = ({ platform, mk, games, outrights }) => {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
if (!platform || (!games && !outrights)) {
|
|
|
@@ -135,6 +152,9 @@ const updateGamesEvents = ({ platform, mk, games, outrights }) => {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 获取比赛列表
|
|
|
+ */
|
|
|
const getGamesList = () => {
|
|
|
const gamesListMap = {};
|
|
|
Object.keys(GAMES.List).forEach(platform => {
|
|
|
@@ -154,6 +174,9 @@ const getGamesList = () => {
|
|
|
return gamesListMap;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 更新关联比赛
|
|
|
+ */
|
|
|
const updateGamesRelation = async (relation) => {
|
|
|
const { id, rel } = relation;
|
|
|
return Relation.findOne({ id })
|
|
|
@@ -170,6 +193,9 @@ const updateGamesRelation = async (relation) => {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 删除关联比赛
|
|
|
+ */
|
|
|
const removeGamesRelation = async (id) => {
|
|
|
if (!id) {
|
|
|
return Promise.reject(new Error('ID_INVALID'));
|
|
|
@@ -181,6 +207,9 @@ const removeGamesRelation = async (id) => {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 获取关联比赛
|
|
|
+ */
|
|
|
const getGamesRelation = async (listEvents) => {
|
|
|
const relationIds = Object.keys(GAMES.Relations);
|
|
|
if (listEvents) {
|
|
|
@@ -203,6 +232,9 @@ const getGamesRelation = async (listEvents) => {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 清理关联比赛
|
|
|
+ */
|
|
|
const relationsCleanup = () => {
|
|
|
const expireTime = Date.now() - 1000*60*5;
|
|
|
getGamesRelation()
|
|
|
@@ -221,6 +253,9 @@ const relationsCleanup = () => {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 从数据库中同步关联比赛
|
|
|
+ */
|
|
|
const relationSync = () => {
|
|
|
Relation.find().then(relation => relation.forEach(item => {
|
|
|
const { id, rel } = item.toObject();
|
|
|
@@ -228,6 +263,69 @@ const relationSync = () => {
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 更新中单方案
|
|
|
+ */
|
|
|
+const setSolutions = (solutions) => {
|
|
|
+ if (solutions?.length) {
|
|
|
+ const solutionsHistory = GAMES.Solutions;
|
|
|
+ const updateIds = { add: [], update: [] }
|
|
|
+ solutions.forEach(item => {
|
|
|
+ const { sid, sol: { win_average } } = item;
|
|
|
+
|
|
|
+ if (!solutionsHistory[sid]) {
|
|
|
+ solutionsHistory[sid] = item;
|
|
|
+ updateIds.add.push({ sid, win_average });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const historyWinAverage = solutionsHistory[sid].sol.win_average;
|
|
|
+ if (win_average != historyWinAverage) {
|
|
|
+ solutionsHistory[sid] = item;
|
|
|
+ updateIds.update.push({ sid, win_average, his_average: historyWinAverage, diff: fixFloat(win_average - historyWinAverage) });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const { timestamp } = item;
|
|
|
+ solutionsHistory[sid].timestamp = timestamp;
|
|
|
+
|
|
|
+ });
|
|
|
+ if (updateIds.add.length || updateIds.update.length) {
|
|
|
+ const solutionsList = Object.values(solutionsHistory).sort((a, b) => b.sol.win_average - a.sol.win_average);
|
|
|
+ Logs.outDev('solutions history update', JSON.stringify(solutionsList, null, 2), JSON.stringify(updateIds, null, 2));
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 获取中单方案
|
|
|
+ */
|
|
|
+const getSolutions = () => {
|
|
|
+ return Object.values(GAMES.Solutions).sort((a, b) => b.sol.win_average - a.sol.win_average);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 清理中单方案
|
|
|
+ */
|
|
|
+const solutionsCleanup = () => {
|
|
|
+ const solutionsHistory = GAMES.Solutions;
|
|
|
+ Object.keys(solutionsHistory).forEach(sid => {
|
|
|
+ const { timestamp } = solutionsHistory[sid];
|
|
|
+ const nowTime = Date.now();
|
|
|
+ if (nowTime - timestamp > 1000*60) {
|
|
|
+ delete solutionsHistory[sid];
|
|
|
+ Logs.out('solution history timeout', sid);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const solution = solutionsHistory[sid];
|
|
|
+ const eventTime = solution.info.timestamp;
|
|
|
+ if (nowTime > eventTime) {
|
|
|
+ delete solutionsHistory[sid];
|
|
|
+ Logs.out('solution history expired', sid);
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
const getDataFromChild = (type, callback) => {
|
|
|
const id = ++Request.count;
|
|
|
Request.callbacks[id] = callback;
|
|
|
@@ -248,8 +346,8 @@ events_child.on('message', async (message) => {
|
|
|
events_child.send({ type: 'response', id, data: responseData });
|
|
|
}
|
|
|
else if (method == 'post') {
|
|
|
- if (type == 'setSolution') {
|
|
|
- setSolution(data);
|
|
|
+ if (type == 'setSolutions') {
|
|
|
+ setSolutions(data);
|
|
|
}
|
|
|
}
|
|
|
else if (method == 'response' && id && callbacks[id]) {
|
|
|
@@ -263,7 +361,12 @@ setInterval(() => {
|
|
|
relationsCleanup();
|
|
|
}, 5000);
|
|
|
|
|
|
+setInterval(() => {
|
|
|
+ solutionsCleanup();
|
|
|
+}, 1000*30);
|
|
|
+
|
|
|
module.exports = {
|
|
|
updateGamesList, updateGamesEvents, getGamesList,
|
|
|
updateGamesRelation, getGamesRelation, removeGamesRelation,
|
|
|
+ getSolutions,
|
|
|
}
|