From 9048d197a8f54ede66cbe49d8df7a9df782f857b Mon Sep 17 00:00:00 2001 From: MayaTheShy Date: Mon, 16 Feb 2026 02:38:34 -0500 Subject: [PATCH] feat: Implement home position management for turtles with update and retrieval endpoints --- server/server.js | 70 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/server/server.js b/server/server.js index bf4bc13..94b7074 100644 --- a/server/server.js +++ b/server/server.js @@ -14,6 +14,8 @@ app.use(express.json()); const webClients = new Set(); const turtleData = new Map(); // turtleID -> turtle state const worldBlocks = new Map(); // "x,y,z" -> {name, metadata, discoveredBy, timestamp} +const turtleHomes = new Map(); // turtleID -> {x, y, z} home position +const turtleConfig = new Map(); // turtleID -> {maxDistance, facing, etc} // Timeout for considering turtles offline (30 seconds) const TURTLE_TIMEOUT = 30000; @@ -163,11 +165,23 @@ app.post('/api/turtle/update', (req, res) => { console.log(`✨ New turtle registered: ${turtleID}`); } + // Merge with existing data, keeping server's home position if it exists + const existingData = turtleData.get(turtleID) || {}; + const serverHome = turtleHomes.get(turtleID); + turtleData.set(turtleID, { + ...existingData, ...turtleUpdate, + homePosition: serverHome || turtleUpdate.homePosition, // Server's home takes precedence lastUpdate: Date.now() }); + // If turtle reports a home but server doesn't have one, store it + if (turtleUpdate.homePosition && !serverHome) { + turtleHomes.set(turtleID, turtleUpdate.homePosition); + console.log(` 📍 Stored home position for turtle ${turtleID}:`, turtleUpdate.homePosition); + } + // Store discovered blocks in world map if (turtleUpdate.surroundings && turtleUpdate.position && turtleUpdate.facing !== undefined) { for (const [direction, blockData] of Object.entries(turtleUpdate.surroundings)) { @@ -184,7 +198,12 @@ app.post('/api/turtle/update', (req, res) => { turtle: turtleData.get(turtleID) }); - res.json({ success: true }); + // Send back server-authoritative data + res.json({ + success: true, + homePosition: turtleHomes.get(turtleID), + config: turtleConfig.get(turtleID) || {} + }); } catch (error) { console.error('❌ Error processing turtle update:', error); res.status(500).json({ error: error.message }); @@ -225,6 +244,55 @@ app.get('/api/turtles', (req, res) => { }); }); +// Set home position for a turtle +app.post('/api/turtle/:id/home', (req, res) => { + try { + const turtleID = parseInt(req.params.id); + const { position } = req.body; + + if (!position || !position.x || !position.y || !position.z) { + return res.status(400).json({ error: 'Invalid position' }); + } + + turtleHomes.set(turtleID, position); + console.log(`📍 Set home for turtle ${turtleID}:`, position); + + // Update turtle data + if (turtleData.has(turtleID)) { + const turtle = turtleData.get(turtleID); + turtle.homePosition = position; + turtleData.set(turtleID, turtle); + + // Broadcast update + broadcastToClients({ + type: 'turtle_update', + turtle: turtle + }); + } + + res.json({ success: true, homePosition: position }); + } catch (error) { + console.error('❌ Error setting home:', error); + res.status(500).json({ error: error.message }); + } +}); + +// Get turtle home position +app.get('/api/turtle/:id/home', (req, res) => { + try { + const turtleID = parseInt(req.params.id); + const home = turtleHomes.get(turtleID); + + res.json({ + success: true, + homePosition: home || null + }); + } catch (error) { + console.error('❌ Error getting home:', error); + res.status(500).json({ error: error.message }); + } +}); + // Get world blocks for map visualization app.get('/api/world/blocks', (req, res) => { const blocks = [];