Timer overhaul

- Redis-based timers now work
- They should be independent from each other so resetting them shouldn't break parallel rounds.
This commit is contained in:
MaciejkaG 2024-03-08 23:32:55 +01:00
parent bd7229e17b
commit ec036c76d7
2 changed files with 33 additions and 27 deletions

View File

@ -224,7 +224,7 @@ io.on('connection', async (socket) => {
let UTCTs = Math.floor((new Date()).getTime() / 1000 + 90);
io.to(playerGame.id).emit('turn update', { turn: 0, phase: "preparation", timerToUTC: UTCTs });
bships.timer(90, async () => {
GInfo.timer(playerGame.id, 15, async () => {
const playerGame = await GInfo.getPlayerGameData(socket);
for (let i = 0; i < playerGame.data.boards.length; i++) {
const ships = playerGame.data.boards[i].ships;
@ -235,7 +235,7 @@ io.on('connection', async (socket) => {
}
GInfo.endPrepPhase(socket);
bships.timer(30, () => {
GInfo.timer(playerGame.id, 30, () => {
AFKEnd(playerGame.id);
});
});
@ -316,15 +316,15 @@ io.on('connection', async (socket) => {
}
}
bships.resetTimers();
GInfo.resetTimer(playerGame.id);
endGame(playerGame.id);
return;
}
}
await GInfo.passTurn(socket);
bships.resetTimers();
bships.timer(30, () => {
GInfo.resetTimer(playerGame.id);
GInfo.timer(playerGame.id, 30, () => {
AFKEnd(playerGame.id);
});
}

View File

@ -4,6 +4,34 @@ export class GameInfo {
this.io = io;
}
async timer(tId, time, callback) {
await this.redis.set(`timer:${tId}`, new Date().getTime() / 1000);
let localLastUpdate = await this.redis.get(`timer:${tId}`);
let timeout = setTimeout(callback, time * 1000);
let interval = setInterval(async () => {
if (timeout._destroyed) {
// timer is finished, stop monitoring turn changes
clearInterval(interval);
return;
}
let lastUpdate = await this.redis.get(`timer:${tId}`);
if (localLastUpdate != lastUpdate) {
// timer has been reset
clearTimeout(timeout);
clearInterval(interval);
return;
}
}, 200);
}
async resetTimer(tId) {
let lastUpdate = await this.redis.get(`timer:${tId}`);
await this.redis.set(`timer:${tId}`, -lastUpdate);
}
async isPlayerInGame(socket) {
const game = await this.redis.json.get(`game:${socket.session.activeGame}`);
return game != null;
@ -125,28 +153,6 @@ export function isPlayerInRoom(socket) {
var lastTimeChange = new Date().getTime();
export function timer(time, callback) {
let localLastChange = lastTimeChange;
let timeout = setTimeout(callback, time * 1000);
let interval = setInterval(() => {
if (timeout._destroyed) {
// timer is finished, stop monitoring turn changes
clearInterval(interval);
}
if (localLastChange != lastTimeChange) {
// timer has been reset
clearTimeout(timeout);
clearInterval(interval);
}
}, 200);
}
export function resetTimers() {
lastTimeChange = -lastTimeChange;
}
// export function getShipsLeft(data, playerIdx) {
// let shipsLeft = [4, 3, 2, 1];