Commit e84a98f5 authored by nanahira's avatar nanahira

refa with Pool object

parent 82074b07
...@@ -11,11 +11,58 @@ const config = JSON.parse(fs.readFileSync("./config.json")); ...@@ -11,11 +11,58 @@ const config = JSON.parse(fs.readFileSync("./config.json"));
let athleticUserPool = []; let athleticUserPool = [];
let entertainUserPool = []; let entertainUserPool = [];
let deadUserPool = []; let deadUserPool = [];
let playingPlayerPool = new Map(); class Pool {
let playingPlayerOpponents = new Map(); constructor(config) {
let playingPlayerTimeout = new Map(); this.config = config;
let pendingPlayerPool = new Map(); this.pool = new Map();
let pendingPlayerTimeout = new Map(); this.timeout = new Map();
}
has(user) {
return this.pool.has(user);
}
get(user) {
return this.pool.get(user);
}
set(user, info) {
this.pool.set(user, info);
if (this.timeout.has(user))
clearTimeout(this.timeout.get(user));
this.timeout.set(user, setTimeout(() => this.handleTimeout(user), this.config.timeoutMs));
}
delete(user) {
let hasUser = this.pool.has(user);
let info = hasUser ? this.pool.get(user) : null;
if (hasUser) this.pool.delete(user);
if (this.timeout.has(user)) {
clearTimeout(this.timeout.get(user));
this.timeout.delete(user);
}
return info;
}
handleTimeout(user) {
if (clearUserPools(user))
localLog(this.config.timeoutLogPrefix + user);
}
transferToPool(targetPool, user, logPrefix) {
let info = this.delete(user);
if (!info) {
if (logPrefix) localLog(logPrefix + user);
return null;
}
targetPool.set(user, info);
return info;
}
}
let playingPool = new Pool({ timeoutLogPrefix: "With timeout, user is seen as had left the game: ", timeoutMs: config.match.longestMatchTime });
let pendingPool = new Pool({ timeoutLogPrefix: "Pending room expired for user: ", timeoutMs: 600000 });
let playerOpponents = new Map();
let predictedEntertainTime = 600, predictedAthleticTime = 600; let predictedEntertainTime = 600, predictedAthleticTime = 600;
let entertainRequestCountInTime = 0, athleticRequestCountInTime = 0; let entertainRequestCountInTime = 0, athleticRequestCountInTime = 0;
...@@ -32,20 +79,14 @@ let clearUserPools = function(user) { ...@@ -32,20 +79,14 @@ let clearUserPools = function(user) {
let currentUser = toClear.pop(); let currentUser = toClear.pop();
if (!currentUser || seen.has(currentUser)) continue; if (!currentUser || seen.has(currentUser)) continue;
seen.add(currentUser); seen.add(currentUser);
if (playingPlayerPool.delete(currentUser)) removedFromPlaying = true; let playingRemoval = playingPool.delete(currentUser);
if (pendingPlayerPool.delete(currentUser)) removedFromPending = true; let pendingRemoval = pendingPool.delete(currentUser);
if (playingPlayerTimeout.has(currentUser)) { if (playingRemoval !== null) removedFromPlaying = true;
clearTimeout(playingPlayerTimeout.get(currentUser)); if (pendingRemoval !== null) removedFromPending = true;
playingPlayerTimeout.delete(currentUser); let opponent = playerOpponents.get(currentUser);
} playerOpponents.delete(currentUser);
if (pendingPlayerTimeout.has(currentUser)) {
clearTimeout(pendingPlayerTimeout.get(currentUser));
pendingPlayerTimeout.delete(currentUser);
}
let opponent = playingPlayerOpponents.get(currentUser);
playingPlayerOpponents.delete(currentUser);
if (opponent) { if (opponent) {
playingPlayerOpponents.delete(opponent); playerOpponents.delete(opponent);
toClear.push(opponent); toClear.push(opponent);
} }
} }
...@@ -257,8 +298,8 @@ let pair = function (userARes, userBRes, serverName) { ...@@ -257,8 +298,8 @@ let pair = function (userARes, userBRes, serverName) {
} }
options_buffer.writeUInt8(checksum & 0xFF, 0); options_buffer.writeUInt8(checksum & 0xFF, 0);
localLog(userARes.username + " and " + userBRes.username + " matched on room " + room_id); localLog(userARes.username + " and " + userBRes.username + " matched on room " + room_id);
playingPlayerOpponents.set(userARes.username, userBRes.username); playerOpponents.set(userARes.username, userBRes.username);
playingPlayerOpponents.set(userBRes.username, userARes.username); playerOpponents.set(userBRes.username, userARes.username);
for (let client of [userARes, userBRes]) { for (let client of [userARes, userBRes]) {
let buffer = new Buffer(6); let buffer = new Buffer(6);
let secret = parseInt(client.password) % 65535 + 1; let secret = parseInt(client.password) % 65535 + 1;
...@@ -271,10 +312,7 @@ let pair = function (userARes, userBRes, serverName) { ...@@ -271,10 +312,7 @@ let pair = function (userARes, userBRes, serverName) {
"port": server.port, "port": server.port,
"password": password, "password": password,
}; };
pendingPlayerPool.set(client.username, result); pendingPool.set(client.username, result);
if (pendingPlayerTimeout.has(client.username))
clearTimeout(pendingPlayerTimeout.get(client.username));
pendingPlayerTimeout.set(client.username, setTimeout(timeoutPendingUser, 600000, client.username));
client.writeHead(200, {'Content-Type': 'application/json', 'Cache-Control': 'no-cache'}); client.writeHead(200, {'Content-Type': 'application/json', 'Cache-Control': 'no-cache'});
lookup(result).then(r => lookup(result).then(r =>
client.end(JSON.stringify(r)) client.end(JSON.stringify(r))
...@@ -343,8 +381,8 @@ let finishUser = function (json) { ...@@ -343,8 +381,8 @@ let finishUser = function (json) {
let userA = json.usernameA; let userA = json.usernameA;
let userB = json.usernameB; let userB = json.usernameB;
if (!userA && !userB) return; if (!userA && !userB) return;
if (!userA && playingPlayerOpponents.has(userB)) userA = playingPlayerOpponents.get(userB); if (!userA && playerOpponents.has(userB)) userA = playerOpponents.get(userB);
if (!userB && playingPlayerOpponents.has(userA)) userB = playingPlayerOpponents.get(userA); if (!userB && playerOpponents.has(userA)) userB = playerOpponents.get(userA);
for (let user of [userA, userB]) { for (let user of [userA, userB]) {
if (!user) continue; if (!user) continue;
if (!clearUserPools(user)) if (!clearUserPools(user))
...@@ -361,34 +399,11 @@ let startUser = function (query) { ...@@ -361,34 +399,11 @@ let startUser = function (query) {
if (!userA && !userB) return; if (!userA && !userB) return;
for (let user of [userA, userB]) { for (let user of [userA, userB]) {
if (!user) continue; if (!user) continue;
let roomInfo = pendingPlayerPool.get(user); pendingPool.transferToPool(playingPool, user, "Unknown pending player started the game: ");
if (!roomInfo) {
localLog("Unknown pending player started the game: " + user);
continue;
}
pendingPlayerPool.delete(user);
clearTimeout(pendingPlayerTimeout.get(user));
pendingPlayerTimeout.delete(user);
playingPlayerPool.set(user, roomInfo);
if (playingPlayerTimeout.has(user))
clearTimeout(playingPlayerTimeout.get(user));
playingPlayerTimeout.set(user, setTimeout(timeoutUser, config.match.longestMatchTime, user));
} }
localLog("Player " + userA + " and " + userB + " started the game."); localLog("Player " + userA + " and " + userB + " started the game.");
}; };
// 当超过时间,而 srvpro 从未通知基本服务器游戏已结束时
let timeoutUser = function(user) {
if (clearUserPools(user))
localLog("With timeout, user is seen as had left the game: " + user);
};
// 当房间未开始而超时
let timeoutPendingUser = function(user) {
if (clearUserPools(user))
localLog("Pending room expired for user: " + user);
};
// 计算预期时间 // 计算预期时间
let calculatePredictedTime = function() { let calculatePredictedTime = function() {
if (entertainRequestCountInTime === 0) if (entertainRequestCountInTime === 0)
...@@ -420,11 +435,11 @@ let matchResponse = function(req, res) { ...@@ -420,11 +435,11 @@ let matchResponse = function(req, res) {
res.username = username; res.username = username;
res.password = password; res.password = password;
// 检定是否掉线重连 // 检定是否掉线重连
if (playingPlayerPool.has(username)) { if (playingPool.has(username)) {
switch (config.match.reconnect) { switch (config.match.reconnect) {
case "reconnect": case "reconnect":
res.writeHead(200, {'Content-Type': 'application/json', 'Cache-Control': 'no-cache'}); res.writeHead(200, {'Content-Type': 'application/json', 'Cache-Control': 'no-cache'});
let message = playingPlayerPool.get(username); let message = playingPool.get(username);
localLog(username + " is relining to: " + message); localLog(username + " is relining to: " + message);
lookup(message).then(r => lookup(message).then(r =>
res.end(JSON.stringify(r)) res.end(JSON.stringify(r))
...@@ -509,10 +524,10 @@ let endUserPermit = function(query, res) { ...@@ -509,10 +524,10 @@ let endUserPermit = function(query, res) {
let password = query.password; let password = query.password;
let arena = query.arena; let arena = query.arena;
let info = null; let info = null;
if (pendingPlayerPool.has(username)) { if (pendingPool.has(username)) {
info = pendingPlayerPool.get(username); info = pendingPool.get(username);
} else if (playingPlayerPool.has(username)) { } else if (playingPool.has(username)) {
info = playingPlayerPool.get(username); info = playingPool.get(username);
} }
if (info) { if (info) {
if (password == info.password) { if (password == info.password) {
...@@ -543,7 +558,7 @@ let endClearResponse = function(query, res) { ...@@ -543,7 +558,7 @@ let endClearResponse = function(query, res) {
return notFoundResponse(res); return notFoundResponse(res);
let count = 0; let count = 0;
let clearFromPool = function (pool) { let clearFromPool = function (pool) {
let shadow_pool = new Map(pool); let shadow_pool = new Map(pool.pool);
for (let [iterate_user, iterate_info] of shadow_pool.entries()) { for (let [iterate_user, iterate_info] of shadow_pool.entries()) {
if (iterate_user != "*" && iterate_user != user) continue; if (iterate_user != "*" && iterate_user != user) continue;
if (iterate_info.address == arena_info.address && iterate_info.port == arena_info.port) { if (iterate_info.address == arena_info.address && iterate_info.port == arena_info.port) {
...@@ -552,8 +567,8 @@ let endClearResponse = function(query, res) { ...@@ -552,8 +567,8 @@ let endClearResponse = function(query, res) {
} }
} }
}; };
clearFromPool(playingPlayerPool); clearFromPool(playingPool);
clearFromPool(pendingPlayerPool); clearFromPool(pendingPool);
res.end(`${count} user cleared.`); res.end(`${count} user cleared.`);
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment