Merge branch 'main' of github.com:quentinrsl/traque

This commit is contained in:
Quentin Roussel
2024-04-26 18:02:44 +02:00
4 changed files with 101 additions and 29 deletions

View File

@@ -1,4 +1,4 @@
import { io, game } from "./index.js"; import { io, game, penaltyController } from "./index.js";
import { playersBroadcast, sendUpdatedTeamInformations } from "./team_socket.js"; import { playersBroadcast, sendUpdatedTeamInformations } from "./team_socket.js";
import { config } from "dotenv"; import { config } from "dotenv";
@@ -45,6 +45,8 @@ export function initAdminSocketHandler() {
//Send the current state //Send the current state
socket.emit("game_state", game.state) socket.emit("game_state", game.state)
//Other settings that need initialization //Other settings that need initialization
socket.emit("penalty_settings", penaltyController.settings)
socket.emit("game_settings", game.settings)
socket.emit("zone_settings", game.zone.zoneSettings) socket.emit("zone_settings", game.zone.zoneSettings)
socket.emit("zone", game.zone.currentZone) socket.emit("zone", game.zone.currentZone)
socket.emit("new_zone", { socket.emit("new_zone", {
@@ -58,6 +60,18 @@ export function initAdminSocketHandler() {
} }
}); });
socket.on("set_game_settings", (settings) => {
if (!loggedIn) {
socket.emit("error", "Not logged in");
return;
}
if(!game.changeSettings(settings)) {
socket.emit("error", "Invalid settings");
}
secureAdminBroadcast("game_settings",game.settings);
playersBroadcast("game_settings", game.settings);
})
socket.on("set_zone_settings", (settings) => { socket.on("set_zone_settings", (settings) => {
if (!loggedIn) { if (!loggedIn) {
socket.emit("error", "Not logged in"); socket.emit("error", "Not logged in");
@@ -72,6 +86,20 @@ export function initAdminSocketHandler() {
}) })
socket.on("set_penalty_settings", (settings) => {
if (!loggedIn) {
socket.emit("error", "Not logged in");
return;
}
if(!penaltyController.updateSettings(settings)) {
socket.emit("error", "Invalid settings");
socket.emit("penalty_settings", penaltyController.settings)
}else {
secureAdminBroadcast("penalty_settings", penaltyController.settings)
}
})
//User is attempting to add a new team //User is attempting to add a new team
socket.on("add_team", (teamName) => { socket.on("add_team", (teamName) => {
if (!loggedIn) { if (!loggedIn) {

View File

@@ -16,6 +16,17 @@ export default class Game {
this.teams = []; this.teams = [];
this.state = GameState.SETUP; this.state = GameState.SETUP;
this.zone = new ZoneManager(onUpdateZone, onUpdateNewZone) this.zone = new ZoneManager(onUpdateZone, onUpdateNewZone)
this.settings = {
loserEndGameMessage: "",
winnerEndGameMessage: "",
capturedMessage: "",
waitingMessage: "Jeu en préparation, veuillez patienter."
}
}
changeSettings(newSettings) {
this.settings = {...this.settings, ...newSettings};
return true;
} }
setState(newState) { setState(newState) {
@@ -45,6 +56,10 @@ export default class Game {
for (let team of this.teams) { for (let team of this.teams) {
team.penalties = 0; team.penalties = 0;
team.captured = false; team.captured = false;
team.enemyLocation = null;
team.enemyName = null;
team.currentLocation = null;
team.lastSentLocation = null;
} }
this.updateTeamChasing(); this.updateTeamChasing();
} }
@@ -143,6 +158,7 @@ export default class Game {
} }
}) })
this.updateTeamChasing(); this.updateTeamChasing();
penaltyController.checkPenalties();
return true; return true;
} }
@@ -164,7 +180,7 @@ export default class Game {
initLastSentLocations() { initLastSentLocations() {
for (let team of this.teams) { for (let team of this.teams) {
team.lastSentLocation = team.currentLocation; team.lastSentLocation = team.currentLocation;
team.locationSendDeadline = Number(new Date()) + process.env.ALLOWED_TIME_BETWEEN_POSITION_UPDATE_IN_MINUTES * 60 * 1000; team.locationSendDeadline = Number(new Date()) + penaltyController.settings.allowedTimeBetweenPositionUpdate * 60 * 1000;
sendUpdatedTeamInformations(team.id); sendUpdatedTeamInformations(team.id);
} }
} }
@@ -174,7 +190,7 @@ export default class Game {
if (team == undefined) { if (team == undefined) {
return false; return false;
} }
team.locationSendDeadline = Number(new Date()) + process.env.ALLOWED_TIME_BETWEEN_POSITION_UPDATE_IN_MINUTES * 60 * 1000; team.locationSendDeadline = Number(new Date()) + penaltyController.settings.allowedTimeBetweenPositionUpdate * 60 * 1000;
team.lastSentLocation = team.currentLocation; team.lastSentLocation = team.currentLocation;
if (this.getTeam(team.chasing) != null) { if (this.getTeam(team.chasing) != null) {
team.enemyLocation = this.getTeam(team.chasing).lastSentLocation; team.enemyLocation = this.getTeam(team.chasing).lastSentLocation;

View File

@@ -1,10 +1,8 @@
import { config } from "dotenv";
import { getDistanceFromLatLon, isInCircle } from "./map_utils.js"; import { getDistanceFromLatLon, isInCircle } from "./map_utils.js";
import { sendUpdatedTeamInformations, teamBroadcast } from "./team_socket.js"; import { sendUpdatedTeamInformations, teamBroadcast } from "./team_socket.js";
import { GameState } from "./game.js"; import { GameState } from "./game.js";
import { secureAdminBroadcast } from "./admin_socket.js"; import { secureAdminBroadcast } from "./admin_socket.js";
import { game } from "./index.js"; import { game } from "./index.js";
config()
export class PenaltyController { export class PenaltyController {
constructor() { constructor() {
@@ -12,6 +10,11 @@ export class PenaltyController {
this.game = game; this.game = game;
this.outOfBoundsSince = {}; this.outOfBoundsSince = {};
this.checkIntervalId = null; this.checkIntervalId = null;
this.settings = {
allowedTimeOutOfZone: 10,
allowedTimeBetweenPositionUpdate: 10,
maxPenalties: 3
}
} }
start() { start() {
@@ -35,6 +38,17 @@ export class PenaltyController {
this.checkIntervalId = null; this.checkIntervalId = null;
} }
} }
updateSettings(newSettings) {
//Sanitize input
if (newSettings.maxPenalties && (isNaN(parseInt(newSettings.maxPenalties)) || newSettings.maxPenalties < 0)) { return false }
if (newSettings.allowedTimeBetweenPositionUpdate && (isNaN(parseFloat(newSettings.allowedTimeBetweenPositionUpdate)) || newSettings.allowedTimeBetweenPositionUpdate < 0)) { return false }
if (newSettings.allowedTimeOutOfZone && (isNaN(parseFloat(newSettings.allowedTimeOutOfZone)) || newSettings.allowedTimeOutOfZone < 0)) { return false }
this.settings = { ...this.settings, ...newSettings };
return true;
}
/** /**
* Increment the penalty score of a team, send a message to the team and eliminated if necessary * Increment the penalty score of a team, send a message to the team and eliminated if necessary
* @param {Number} teamId The team that will recieve a penalty * @param {Number} teamId The team that will recieve a penalty
@@ -48,21 +62,32 @@ export class PenaltyController {
return; return;
} }
team.penalties++; team.penalties++;
if (team.penalties >= process.env.MAX_PENALTIES) { if (team.penalties >= this.settings.maxPenalties) {
this.game.capture(team.id); this.game.capture(team.id);
sendUpdatedTeamInformations(teamId); sendUpdatedTeamInformations(teamId);
sendUpdatedTeamInformations(team.chased); sendUpdatedTeamInformations(team.chased);
teamBroadcast(teamId, "warning", "You have been eliminated (reason: too many penalties)") teamBroadcast(teamId, "warning", "You have been eliminated (reason: too many penalties)")
teamBroadcast(team.chased, "success", "The team you were chasing has been eliminated") teamBroadcast(team.chased, "success", "The team you were chasing has been eliminated")
} else { } else {
teamBroadcast(teamId, "warning", `You recieved a penalty (${team.penalties}/${process.env.MAX_PENALTIES})`) teamBroadcast(teamId, "warning", `You recieved a penalty (${team.penalties}/${this.settings.maxPenalties})`)
sendUpdatedTeamInformations(teamId); sendUpdatedTeamInformations(teamId);
} }
secureAdminBroadcast("teams", this.game.teams) secureAdminBroadcast("teams", this.game.teams)
} }
checkPenalties() {
for (let team of game.teams) {
if (team.penalties >= this.settings.maxPenalties) {
this.game.capture(team.id);
sendUpdatedTeamInformations(teamId);
sendUpdatedTeamInformations(team.chased);
teamBroadcast(teamId, "warning", "You have been eliminated (reason: too many penalties)")
teamBroadcast(team.chased, "success", "The team you were chasing has been eliminated")
}
}
}
watchZone() { watchZone() {
console.log("watching zone")
this.game.teams.forEach((team) => { this.game.teams.forEach((team) => {
if (team.captured) { return } if (team.captured) { return }
//All the informations are not ready yet //All the informations are not ready yet
@@ -70,17 +95,15 @@ export class PenaltyController {
return; return;
} }
if (!isInCircle({ lat: team.currentLocation[0], lng: team.currentLocation[1] }, this.game.zone.currentZone.center, this.game.zone.currentZone.radius)) { if (!isInCircle({ lat: team.currentLocation[0], lng: team.currentLocation[1] }, this.game.zone.currentZone.center, this.game.zone.currentZone.radius)) {
console.log("tema " + team.name + " out of zone")
//The team was not previously out of the zone //The team was not previously out of the zone
if (!this.outOfBoundsSince[team.id]) { if (!this.outOfBoundsSince[team.id]) {
this.outOfBoundsSince[team.id] = new Date(); this.outOfBoundsSince[team.id] = new Date();
console.log("tema " + team.name + " warned") teamBroadcast(team.id, "warning", `You left the zone, you have ${this.settings.allowedTimeOutOfZone} minutes to get back in the marked area.`)
teamBroadcast(team.id, "warning", `You left the zone, you have ${process.env.ALLOWED_TIME_OUT_OF_ZONE_IN_MINUTES} minutes to get back in the marked area.`) } else if (new Date() - this.outOfBoundsSince[team.id] > this.settings.allowedTimeOutOfZone * 60 * 1000) {
} else {
if (new Date() - this.outOfBoundsSince[team.id] > process.env.ALLOWED_TIME_OUT_OF_ZONE_IN_MINUTES * 60 * 1000) {
this.addPenalty(team.id) this.addPenalty(team.id)
this.outOfBoundsSince[team.id] = new Date(); this.outOfBoundsSince[team.id] = new Date();
} } else if (Math.abs(new Date() - this.outOfBoundsSince[team.id] - (this.settings.allowedTimeOutOfZone - 1) * 60 * 1000) < 100) {
teamBroadcast(team.id, "warning", `You left the zone, you have 1 minutes to get back in the marked area.`)
} }
} else { } else {
if (this.outOfBoundsSince[team.id]) { if (this.outOfBoundsSince[team.id]) {
@@ -90,12 +113,13 @@ export class PenaltyController {
}) })
} }
watchPositionUpdate() { watchPositionUpdate() {
this.game.teams.forEach((team) => { this.game.teams.forEach((team) => {
//If the team has not sent their location for more than the allowed period, automatically send it and add a penalty //If the team has not sent their location for more than the allowed period, automatically send it and add a penalty
if (team.captured) { return } if (team.captured) { return }
if (team.locationSendDeadline == null) { if (team.locationSendDeadline == null) {
team.locationSendDeadline = Number(new Date()) + process.env.ALLOWED_TIME_BETWEEN_POSITION_UPDATE_IN_MINUTES * 60 * 1000; team.locationSendDeadline = Number(new Date()) + this.settings.allowedTimeBetweenPositionUpdate * 60 * 1000;
return; return;
} }
if (new Date() > team.locationSendDeadline) { if (new Date() > team.locationSendDeadline) {
@@ -103,6 +127,8 @@ export class PenaltyController {
this.game.sendLocation(team.id); this.game.sendLocation(team.id);
sendUpdatedTeamInformations(team.id); sendUpdatedTeamInformations(team.id);
secureAdminBroadcast("teams", this.game.teams) secureAdminBroadcast("teams", this.game.teams)
}else if(Math.abs(new Date() - team.locationSendDeadline - 60 * 1000) < 100) {
teamBroadcast(team.id, "warning", `You have one minute left to udpate your location.`)
} }
}) })
} }

View File

@@ -75,6 +75,7 @@ export function initTeamSocket() {
sendUpdatedTeamInformations(loginTeamId); sendUpdatedTeamInformations(loginTeamId);
socket.emit("login_response", true); socket.emit("login_response", true);
socket.emit("game_state", game.state) socket.emit("game_state", game.state)
socket.emit("game_settings", game.settings)
socket.emit("zone", game.zone.currentZone) socket.emit("zone", game.zone.currentZone)
socket.emit("new_zone", { socket.emit("new_zone", {
begin: game.zone.currentStartZone, begin: game.zone.currentStartZone,
@@ -111,6 +112,7 @@ export function initTeamSocket() {
} }
game.updateTeamChasing(); game.updateTeamChasing();
teamBroadcast(teamId, "update_team", { enemyLocation: team.enemyLocation,locationSendDeadline: team.locationSendDeadline }); teamBroadcast(teamId, "update_team", { enemyLocation: team.enemyLocation,locationSendDeadline: team.locationSendDeadline });
teamBroadcast(teamId,"success", "Position udpated")
secureAdminBroadcast("teams", game.teams) secureAdminBroadcast("teams", game.teams)
}); });