From 46ce93e84e5b616ad3e0a5d69144cf7cf7f49261 Mon Sep 17 00:00:00 2001 From: Quentin Roussel Date: Wed, 17 Apr 2024 18:55:08 +0000 Subject: [PATCH] zone reduction tick working kinda --- traque-back/.vscode/launch.json | 14 +++++++ traque-back/game.js | 2 +- traque-back/index.js | 33 +++++++++------- traque-back/map_utils.js | 2 +- traque-back/zoneManager.js | 68 ++++++++++++++++++++++++--------- 5 files changed, 86 insertions(+), 33 deletions(-) create mode 100644 traque-back/.vscode/launch.json diff --git a/traque-back/.vscode/launch.json b/traque-back/.vscode/launch.json new file mode 100644 index 0000000..32a81da --- /dev/null +++ b/traque-back/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "command": "sudo npm start", + "name": "Run npm start", + "request": "launch", + "type": "node-terminal" + }, + ] +} \ No newline at end of file diff --git a/traque-back/game.js b/traque-back/game.js index cbbe555..e0c2a2f 100644 --- a/traque-back/game.js +++ b/traque-back/game.js @@ -169,6 +169,6 @@ export default class Game { if(this.state == GameState.PLAYING || this.state == GameState.FINISHED) { return false; } - this.zone.udpateSettings(newSettings) + return this.zone.udpateSettings(newSettings) } } \ No newline at end of file diff --git a/traque-back/index.js b/traque-back/index.js index 590d5d7..56cc448 100644 --- a/traque-back/index.js +++ b/traque-back/index.js @@ -33,7 +33,7 @@ const io = new Server(httpsServer, { * @param {String} event The event name * @param {String} data The data to send */ -function secureBroadcast(event, data) { +function secureAdminBroadcast(event, data) { loggedInSockets.forEach(s => { io.of("admin").to(s).emit(event, data); }); @@ -74,13 +74,15 @@ function logoutPlayer(id) { //Zone update broadcast function, called by the game object function onUpdateNewZone(newZone) { + console.log("new_zone", newZone) playersBroadcast("new_zone", newZone) - secureBroadcast("new_zone", newZone) + secureAdminBroadcast("new_zone", newZone) } function onUpdateZone(zone) { + console.log("zone update",zone); playersBroadcast("zone", zone) - secureBroadcast("zone", "zone") + secureAdminBroadcast("zone", zone) } @@ -114,22 +116,27 @@ io.of("admin").on("connection", (socket) => { loggedIn = true; //Send the current state socket.emit("game_state", game.state) + //Other settings that need initialization + socket.emit("zone_settings", game.zone.zoneSettings) + } else { //Attempt unsuccessful socket.emit("login_response", false); } }); - socket.on("set_zone_settings", (zone) => { + socket.on("set_zone_settings", (settings) => { if (!loggedIn) { socket.emit("error", "Not logged in"); return; } - if(!game.setZoneSettings(zone)) { + if(!game.setZoneSettings(settings)) { socket.emit("error", "Error changing zone"); + socket.emit("zone_settings", game.zone.zoneSettings) //Still broadcast the old config to the client who submited an incorrect config to keep the client up to date + }else { + secureAdminBroadcast("zone_settings", game.zone.zoneSettings) } - }) //User is attempting to add a new team @@ -139,7 +146,7 @@ io.of("admin").on("connection", (socket) => { return; } if (game.addTeam(teamName)) { - secureBroadcast("teams", game.teams); + secureAdminBroadcast("teams", game.teams); } else { socket.emit("error", "Error adding team"); } @@ -152,7 +159,7 @@ io.of("admin").on("connection", (socket) => { return; } if (game.removeTeam(teamId)) { - secureBroadcast("teams", game.teams); + secureAdminBroadcast("teams", game.teams); } else { socket.emit("error", "Error removing team"); } @@ -165,7 +172,7 @@ io.of("admin").on("connection", (socket) => { return; } if (game.setState(state)) { - secureBroadcast("game_state", game.state); + secureAdminBroadcast("game_state", game.state); playersBroadcast("game_state", game.state) } else { socket.emit("error", "Error setting state"); @@ -181,7 +188,7 @@ io.of("admin").on("connection", (socket) => { return; } if (game.reorderTeams(newOrder)) { - secureBroadcast("teams", game.teams); + secureAdminBroadcast("teams", game.teams); } else { socket.emit("error", "Error reordering teams"); } @@ -193,7 +200,7 @@ io.of("admin").on("connection", (socket) => { return; } if (game.updateTeam(teamId, newTeam)) { - secureBroadcast("teams", game.teams); + secureAdminBroadcast("teams", game.teams); sendUpdatedTeamInformations(teamId) } }) @@ -266,7 +273,7 @@ io.of("player").on("connection", (socket) => { if (team.sockets.indexOf(socket.id) == 0) { game.updateLocation(teamId, position); teamBroadcast(teamId, "update_team", { currentLocation: team.currentLocation, ready: team.ready }); - secureBroadcast("teams", game.teams); + secureAdminBroadcast("teams", game.teams); } }); @@ -286,7 +293,7 @@ io.of("player").on("connection", (socket) => { if(game.capture(teamId, captureCode)) { sendUpdatedTeamInformations(teamId) sendUpdatedTeamInformations(capturedTeam) - secureBroadcast("teams", game.teams); + secureAdminBroadcast("teams", game.teams); }else { socket.emit("error", "Incorrect code") } diff --git a/traque-back/map_utils.js b/traque-back/map_utils.js index 646cfb3..d085a0c 100644 --- a/traque-back/map_utils.js +++ b/traque-back/map_utils.js @@ -1,4 +1,4 @@ -function getDistanceFromLatLon([lat1, lon1], [lat2, lon2]) { +export function getDistanceFromLatLon({lat: lat1, lng: lon1}, {lat: lat2, lng: lon2}) { var R = 6371; // Radius of the earth in km var dLat = deg2rad(lat2-lat1); // deg2rad below var dLon = deg2rad(lon2-lon1); diff --git a/traque-back/zoneManager.js b/traque-back/zoneManager.js index ee37296..0076c6b 100644 --- a/traque-back/zoneManager.js +++ b/traque-back/zoneManager.js @@ -1,6 +1,6 @@ import randomLocation, { randomCirclePoint } from 'random-location' -import { isInCircle } from './map_utils'; -import { map } from './util'; +import { getDistanceFromLatLon, isInCircle } from './map_utils.js'; +import { map } from './util.js'; export class ZoneManager { constructor(onZoneUpdate, onNextZoneUpdate) { @@ -14,8 +14,8 @@ export class ZoneManager { min: {center: null, radius: null}, max: {center: null, radius: null}, reductionCount: 2, - reductionDuration: 10, - reductionInterval: 10, + reductionDuration: 1, + reductionInterval: 1, updateIntervalSeconds: 10, } this.shrinkFactor = null; @@ -30,7 +30,6 @@ export class ZoneManager { this.currentStartZone = {center: null, radius: null}; this.startDate = null; - this.zoneSettings = zoneSettings; this.started = false; this.updateIntervalId = null; this.nextZoneTimeoutId = null; @@ -39,9 +38,32 @@ export class ZoneManager { this.onNextZoneUpdate = onNextZoneUpdate } + /** + * Update the settings of the zone, this can be done by passing an object containing the settings to change. + * Unless specified, the durations are in minutes + * Default config : + * `this.zoneSettings = { + * min: {center: null, radius: null}, + * max: {center: null, radius: null}, + * reductionCount: 2, + * reductionDuration: 10, + * reductionInterval: 10, + * updateIntervalSeconds: 10, + * }` + * @param {Object} newSettings The fields of the settings to udpate + * @returns + */ udpateSettings(newSettings) { - this.zoneSettings = {newSettings, ...this.zoneSettings}; + //validate settings + if(newSettings.reductionCount &&(typeof newSettings.reductionCount != "number" || newSettings.reductionCount <= 0)) {return false} + if(newSettings.reductionDuration &&(typeof newSettings.reductionDuration != "number" || newSettings.reductionDuration <= 0)) {return false} + if(newSettings.reductionInterval &&(typeof newSettings.reductionInterval != "number" || newSettings.reductionInterval <= 0)) {return false} + if(newSettings.updateIntervalSeconds &&(typeof newSettings.updateIntervalSeconds != "number" || newSettings.updateIntervalSeconds <= 0)) {return false} + if(newSettings.max && (typeof newSettings.max.radius != "number" || typeof newSettings.max.center.lat != "number" || typeof newSettings.max.center.lng != "number")) {return false} + if(newSettings.min && (typeof newSettings.min.radius != "number" || typeof newSettings.min.center.lat != "number" || typeof newSettings.min.center.lng != "number")) {return false} + this.zoneSettings = {...this.zoneSettings, ...newSettings}; this.shrinkFactor = Math.pow(this.zoneSettings.min.radius / this.zoneSettings.max.radius, 1/this.zoneSettings.reductionCount) + return true; } /** @@ -67,7 +89,10 @@ export class ZoneManager { this.started = true; this.startDate = new Date(); //initialize the zone to its max value - this.currentStartZone = this.currentZone = JSON.parse(JSON.stringify(this.zoneSettings.max)); + this.nextZone = JSON.parse(JSON.stringify(this.zoneSettings.max)); + this.currentStartZone = JSON.parse(JSON.stringify(this.zoneSettings.max)); + this.currentZone = JSON.parse(JSON.stringify(this.zoneSettings.max)); + this.setNextZone(); } /** @@ -82,13 +107,13 @@ export class ZoneManager { let res = null //take a random point satisfying both conditions while(!ok) { - res = randomCirclePoint([ this.currentZone.lat, this.currentZone.long], this.currentZone.radius - newRadius); - ok = (isInCircle([res.latitude, res.longitude], this.zoneSettings.min.center, newRadius - this.zoneSettings.min.radius)) + res = randomCirclePoint({latitude: this.currentZone.center.lat, longitude: this.currentZone.center.lng}, this.currentZone.radius - newRadius); + ok = (isInCircle({lat:res.latitude, lng: res.longitude}, this.zoneSettings.min.center, newRadius - this.zoneSettings.min.radius)) + } + return { + lat: res.latitude, + lng: res.longitude } - return [ - res.latitude, - res.longitude - ] } /** @@ -96,22 +121,26 @@ export class ZoneManager { * Wait for the appropriate duration before starting a new zone reduction if needed */ setNextZone() { + console.log("Setting next zone",this.currentZoneCount,this.zoneSettings.reductionCount) //At this point, nextZone == currentZone, we need to update the next zone, the raidus decrement, and start a timer before the next shrink //last zone - if(this.currentZoneCount == this.zoneSettings.currentZoneCount - 1) { - //Copy values + if(this.currentZoneCount == this.zoneSettings.reductionCount - 1) { this.nextZone =JSON.parse(JSON.stringify(this.zoneSettings.min)) this.currentStartZone =JSON.parse(JSON.stringify(this.zoneSettings.min)) - }else { - //TODO : compute next zone + this.nextZoneTimeoutId = setTimeout(() => this.startShrinking(), 1000 * 60 * this.zoneSettings.reductionIntervalMinutes) + this.currentZoneCount++; + }else if(this.currentZoneCount < this.zoneSettings.reductionCount - 1){ this.nextZone.center = this.getRandomNextCenter(this.nextZone.radius * this.shrinkFactor) + console.log(this.nextZone, this.shrinkFactor) this.nextZone.radius *= this.shrinkFactor; + console.log(this.nextZone, this.shrinkFactor) this.currentStartZone = JSON.parse(JSON.stringify(this.currentZone)) this.onNextZoneUpdate({ begin: JSON.parse(JSON.stringify(this.currentStartZone)), - end: JSON.parse(JOSN.stringify()) + end: JSON.parse(JSON.stringify(this.nextZone)) }) this.nextZoneTimeoutId = setTimeout(() => this.startShrinking(), 1000 * 60 * this.zoneSettings.reductionIntervalMinutes) + this.currentZoneCount++; } } @@ -122,8 +151,11 @@ export class ZoneManager { */ startShrinking() { const startTime = new Date(); + console.log("started shrinking") this.updateIntervalId = setInterval(() => { + console.log("Shrink tick") const completed = ((new Date() - startTime) / (1000 * 60)) / this.zoneSettings.reductionDuration; + console.log(completed) this.currentZone.radius = map(completed, 0, 1, this.currentStartZone.radius, this.nextZone.radius) this.onZoneUpdate(JSON.parse(JSON.stringify(this.currentZone))) //Zone shrinking is over