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

View File

@ -4,6 +4,34 @@ export class GameInfo {
this.io = io; 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) { async isPlayerInGame(socket) {
const game = await this.redis.json.get(`game:${socket.session.activeGame}`); const game = await this.redis.json.get(`game:${socket.session.activeGame}`);
return game != null; return game != null;
@ -125,28 +153,6 @@ export function isPlayerInRoom(socket) {
var lastTimeChange = new Date().getTime(); 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) { // export function getShipsLeft(data, playerIdx) {
// let shipsLeft = [4, 3, 2, 1]; // let shipsLeft = [4, 3, 2, 1];