feat: Implement home position management for turtles with update and retrieval endpoints

This commit is contained in:
MayaTheShy
2026-02-16 02:38:34 -05:00
parent bd758e4c7b
commit 9048d197a8

View File

@@ -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 = [];