diff --git a/traque-back/admin_socket.js b/traque-back/admin_socket.js
index 595ee89..4976cf2 100644
--- a/traque-back/admin_socket.js
+++ b/traque-back/admin_socket.js
@@ -76,9 +76,11 @@ export function initAdminSocketHandler() {
}
if (!game.changeSettings(settings)) {
socket.emit("error", "Invalid settings");
+ socket.emit("game_settings", penaltyController.settings)
+ } else {
+ secureAdminBroadcast("game_settings", game.settings);
+ playersBroadcast("game_settings", game.settings);
}
- secureAdminBroadcast("game_settings", game.settings);
- playersBroadcast("game_settings", game.settings);
})
socket.on("set_zone_settings", (settings) => {
diff --git a/traque-back/game.js b/traque-back/game.js
index 4dafe42..bc6a6af 100644
--- a/traque-back/game.js
+++ b/traque-back/game.js
@@ -297,7 +297,7 @@ export default {
}
this.teams = this.teams.filter(t => t.id !== teamId);
this.updateTeamChasing();
- timeoutHandler.endSendPositionTimeout(team.id);
+ timeoutHandler.endSendPositionTimeout(teamId);
return true;
},
@@ -342,17 +342,23 @@ export default {
* @returns false if failed
*/
setZoneSettings(newSettings) {
- //cannot change zones while playing
+ if ('min' in newSettings || 'max' in newSettings) {
+ const min = newSettings.min ?? zoneManager.zoneSettings.min;
+ const max = newSettings.max ?? zoneManager.zoneSettings.max;
+ // The end zone must be included in the start zone
+ if (!isInCircle(min.center, max.center, max.radius-min.radius)) {
+ return false;
+ }
+ }
+ zoneManager.udpateSettings(newSettings);
if (this.state == GameState.PLAYING || this.state == GameState.FINISHED) {
- return false;
+ zoneManager.reset()
+ if (!zoneManager.start()) {
+ this.setState(GameState.SETUP);
+ return false;
+ }
}
- var min = newSettings.min;
- var max = newSettings.max;
- // The end zone must be included in the start zone
- if (!isInCircle(min.center, max.center, max.radius-min.radius)) {
- return false;
- }
- return zoneManager.udpateSettings(newSettings);
+ return true;
},
/**
diff --git a/traque-back/photo.js b/traque-back/photo.js
index c02df53..d26c20b 100644
--- a/traque-back/photo.js
+++ b/traque-back/photo.js
@@ -59,8 +59,8 @@ export function initPhotoUpload() {
//App handler for serving the photo of a team given its secret ID
app.get("/photo/my", (req, res) => {
let team = game.getTeam(Number(req.query.team));
- const imagePath = path.join(process.cwd(), UPLOAD_DIR, team.id.toString());
if (team) {
+ const imagePath = path.join(process.cwd(), UPLOAD_DIR, team.id.toString());
res.set("Content-Type", "image/png")
res.set("Access-Control-Allow-Origin", "*");
res.sendFile(fs.existsSync(imagePath) ? imagePath : path.join(process.cwd(), "images", "missing_image.jpg"));
@@ -71,8 +71,8 @@ export function initPhotoUpload() {
//App handler for serving the photo of the team chased by the team given by its secret ID
app.get("/photo/enemy", (req, res) => {
let team = game.getTeam(Number(req.query.team));
- const imagePath = path.join(process.cwd(), UPLOAD_DIR, team.chasing.toString());
if (team) {
+ const imagePath = path.join(process.cwd(), UPLOAD_DIR, team.chasing.toString());
res.set("Content-Type", "image/png")
res.set("Access-Control-Allow-Origin", "*");
res.sendFile(fs.existsSync(imagePath) ? imagePath : path.join(process.cwd(), "images", "missing_image.jpg"));
diff --git a/traque-front/app/admin/layout.js b/traque-front/app/admin/layout.js
index 9ff7fa6..b2097d4 100644
--- a/traque-front/app/admin/layout.js
+++ b/traque-front/app/admin/layout.js
@@ -11,6 +11,7 @@ export default function AdminLayout({ children}) {
diff --git a/traque-front/app/admin/page.js b/traque-front/app/admin/page.js
index a12197e..5cab131 100644
--- a/traque-front/app/admin/page.js
+++ b/traque-front/app/admin/page.js
@@ -1,16 +1,12 @@
"use client";
-import { GameSettings } from "@/components/admin/gameSettings";
-import { PenaltySettings } from "@/components/admin/penaltySettings";
import { TeamReady } from "@/components/admin/teamReady";
import BlueButton, { GreenButton, RedButton } from "@/components/util/button";
import { useAdminConnexion } from "@/context/adminConnexionContext";
import useAdmin from "@/hook/useAdmin";
import { GameState } from "@/util/gameState";
import dynamic from "next/dynamic";
+import { TeamListFixed } from '@/components/admin/teamList';
-const ZoneSelector = dynamic(() => import('@/components/admin/zoneSelector').then((mod) => mod.ZoneSelector), {
- ssr: false
-});
const LiveMap = dynamic(() => import('@/components/admin/mapPicker').then((mod) => mod.LiveMap), {
ssr: false
});
@@ -22,7 +18,7 @@ export default function AdminPage() {
-
Game state
+
Game state
Current : {gameState}
changeState(GameState.SETUP)}>Reset game
@@ -30,14 +26,11 @@ export default function AdminPage() {
changeState(GameState.PLAYING)}>Start game
-
+ {gameState == GameState.PLACEMENT &&
}
- {gameState == GameState.PLACEMENT &&
}
- {(gameState == GameState.SETUP || gameState == GameState.PLACEMENT) &&
}
- {(gameState == GameState.SETUP || gameState == GameState.PLACEMENT) &&
}
- {gameState == GameState.PLAYING &&
)
}
\ No newline at end of file
diff --git a/traque-front/app/admin/parameters/page.js b/traque-front/app/admin/parameters/page.js
new file mode 100644
index 0000000..3d5f318
--- /dev/null
+++ b/traque-front/app/admin/parameters/page.js
@@ -0,0 +1,22 @@
+"use client";
+import { GameSettings } from "@/components/admin/gameSettings";
+import { PenaltySettings } from "@/components/admin/penaltySettings";
+import { useAdminConnexion } from "@/context/adminConnexionContext";
+import dynamic from "next/dynamic";
+
+const ZoneSelector = dynamic(() => import('@/components/admin/zoneSelector').then((mod) => mod.ZoneSelector), {
+ ssr: false
+});
+export default function AdminPage() {
+ const { useProtect } = useAdminConnexion();
+ useProtect();
+ return (
+
+ )
+}
\ No newline at end of file
diff --git a/traque-front/components/admin/mapPicker.jsx b/traque-front/components/admin/mapPicker.jsx
index f2af583..31ce085 100644
--- a/traque-front/components/admin/mapPicker.jsx
+++ b/traque-front/components/admin/mapPicker.jsx
@@ -5,6 +5,7 @@ import "leaflet/dist/leaflet.css";
import { Circle, MapContainer, Marker, TileLayer, useMap, Tooltip, Polyline } from "react-leaflet";
import { useMapCircleDraw } from "@/hook/mapDrawing";
import useAdmin from "@/hook/useAdmin";
+import { GameState } from "@/util/gameState";
const positionIcon = new L.Icon({
iconUrl: '/icons/location.png',
@@ -109,7 +110,7 @@ export function ZonePicker({ minZone, setMinZone, maxZone, setMaxZone, editMode,
export function LiveMap() {
const location = useLocation(Infinity);
const [timeLeftNextZone, setTimeLeftNextZone] = useState(null);
- const { zone, zoneExtremities, teams, nextZoneDate, isShrinking , getTeam} = useAdmin();
+ const { zone, zoneExtremities, teams, nextZoneDate, isShrinking , getTeam, gameState } = useAdmin();
// Remaining time before sending position
useEffect(() => {
@@ -143,16 +144,16 @@ export function LiveMap() {
return (
-
{`${isShrinking ? "Fin" : "Début"} du rétrécissement de la zone dans : ${formatTime(timeLeftNextZone)}`}
+ {gameState == GameState.PLAYING &&
{`${isShrinking ? "Fin" : "Début"} du rétrécissement de la zone dans : ${formatTime(timeLeftNextZone)}`}
}
- {zone && }
- {zoneExtremities && }
- {zoneExtremities && }
+ {gameState == GameState.PLAYING && zone && }
+ {gameState == GameState.PLAYING && zoneExtremities && }
+ {gameState == GameState.PLAYING && zoneExtremities && }
{teams.map((team) => team.currentLocation && !team.captured &&
{team.name}
diff --git a/traque-front/components/admin/penaltySettings.jsx b/traque-front/components/admin/penaltySettings.jsx
index f7b832a..b7a8d59 100644
--- a/traque-front/components/admin/penaltySettings.jsx
+++ b/traque-front/components/admin/penaltySettings.jsx
@@ -18,7 +18,14 @@ export const PenaltySettings = () => {
}, [penaltySettings]);
function applySettings() {
- changePenaltySettings({maxPenalties: Number(maxPenalties), allowedTimeOutOfZone: Number(allowedTimeOutOfZone), allowedTimeBetweenPositionUpdate: Number(allowedTimeBetweenUpdates)});
+ const newSettings = {maxPenalties: Number(maxPenalties), allowedTimeOutOfZone: Number(allowedTimeOutOfZone), allowedTimeBetweenPositionUpdate: Number(allowedTimeBetweenUpdates)};
+ const changingSettings = {};
+ for (const key in newSettings) {
+ if (newSettings[key] != penaltySettings[key]) {
+ changingSettings[key] = newSettings[key];
+ }
+ }
+ changePenaltySettings(changingSettings);
}
return (
diff --git a/traque-front/components/admin/teamEdit.jsx b/traque-front/components/admin/teamEdit.jsx
index 0829c88..43ed926 100644
--- a/traque-front/components/admin/teamEdit.jsx
+++ b/traque-front/components/admin/teamEdit.jsx
@@ -70,19 +70,17 @@ export default function TeamEdit({ selectedTeamId, setSelectedTeamId }) {
Team details
-
Secret : {String(team.id).padStart(6, '0')}
-
Name : {team.name}
+
Secret : {String(team.id).padStart(6, '0').replace(/(\d{3})(\d{3})/, '$1 $2')}
+
Capture code : {String(team.captureCode).padStart(4, '0')}
Chasing : {getTeamName(team.chasing)}
Chased by : {getTeamName(team.chased)}
-
Capture code : {String(team.captureCode).padStart(4, '0')}
-
Captured : {team.captured ? "Yes" : "No"}
-
Has to send location before {new Date(team.locationSendDeadline).toTimeString()}
Penalties :
{team.penalties}
+
diff --git a/traque-front/components/admin/teamList.jsx b/traque-front/components/admin/teamList.jsx
index ee6ee41..80c7024 100644
--- a/traque-front/components/admin/teamList.jsx
+++ b/traque-front/components/admin/teamList.jsx
@@ -12,16 +12,9 @@ const reorder = (list, startIndex, endIndex) => {
};
function TeamListItem({ team, index, onSelected, itemSelected }) {
- let bgColor;
- if(itemSelected) {
- bgColor = "bg-blue-400";
- }else if(team.captured) {
- bgColor = "bg-red-400";
- }
- else {
- bgColor = "bg-gray-100";
- }
- const classNames = 'w-full p-3 my-3 shadow ' + (bgColor);
+ const bgColor = team.captured ? " bg-red-400" : " bg-gray-300";
+ const border = " border border-4 " + (itemSelected ? "border-black" : team.captured ? "border-red-400" : "border-gray-300");
+ const classNames = 'w-full p-3 my-3' + (bgColor) + (border);
return (
onSelected(team.id)}>
{provided => (
diff --git a/traque-front/components/admin/teamReady.jsx b/traque-front/components/admin/teamReady.jsx
index 504ed79..ea5cd60 100644
--- a/traque-front/components/admin/teamReady.jsx
+++ b/traque-front/components/admin/teamReady.jsx
@@ -2,7 +2,7 @@ import useAdmin from "@/hook/useAdmin"
export function TeamReady() {
const {teams} = useAdmin();
- return
+ return
Teams ready status
{teams.map((team) => team.ready ? (
diff --git a/traque-front/components/admin/zoneSelector.jsx b/traque-front/components/admin/zoneSelector.jsx
index 5b00205..9c770e7 100644
--- a/traque-front/components/admin/zoneSelector.jsx
+++ b/traque-front/components/admin/zoneSelector.jsx
@@ -24,7 +24,14 @@ export function ZoneSelector() {
}, [zoneSettings]);
function handleSettingsSubmit() {
- changeZoneSettings({min:minZone, max:maxZone, reductionCount: Number(reductionCount), reductionDuration: Number(reductionDuration), reductionInterval: Number(reductionInterval)});
+ const newSettings = {min:minZone, max:maxZone, reductionCount: Number(reductionCount), reductionDuration: Number(reductionDuration), reductionInterval: Number(reductionInterval)};
+ const changingSettings = {};
+ for (const key in newSettings) {
+ if (newSettings[key] != zoneSettings[key]) {
+ changingSettings[key] = newSettings[key];
+ }
+ }
+ changeZoneSettings(changingSettings);
}
//When the user set one zone, switch to the other
@@ -39,8 +46,8 @@ export function ZoneSelector() {
return
Edit zones
- {editMode == EditMode.MIN &&
setEditMode(EditMode.MAX)}>Edit end zone}
- {editMode == EditMode.MAX &&
setEditMode(EditMode.MIN)}>Edit start zone}
+ {editMode == EditMode.MIN &&
setEditMode(EditMode.MAX)}>Click to edit first zone}
+ {editMode == EditMode.MAX &&
setEditMode(EditMode.MIN)}>Click to edit last zone}