feat: Implement home position management for turtles with update and retrieval endpoints
This commit is contained in:
@@ -14,6 +14,8 @@ app.use(express.json());
|
|||||||
const webClients = new Set();
|
const webClients = new Set();
|
||||||
const turtleData = new Map(); // turtleID -> turtle state
|
const turtleData = new Map(); // turtleID -> turtle state
|
||||||
const worldBlocks = new Map(); // "x,y,z" -> {name, metadata, discoveredBy, timestamp}
|
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)
|
// Timeout for considering turtles offline (30 seconds)
|
||||||
const TURTLE_TIMEOUT = 30000;
|
const TURTLE_TIMEOUT = 30000;
|
||||||
@@ -163,11 +165,23 @@ app.post('/api/turtle/update', (req, res) => {
|
|||||||
console.log(`✨ New turtle registered: ${turtleID}`);
|
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, {
|
turtleData.set(turtleID, {
|
||||||
|
...existingData,
|
||||||
...turtleUpdate,
|
...turtleUpdate,
|
||||||
|
homePosition: serverHome || turtleUpdate.homePosition, // Server's home takes precedence
|
||||||
lastUpdate: Date.now()
|
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
|
// Store discovered blocks in world map
|
||||||
if (turtleUpdate.surroundings && turtleUpdate.position && turtleUpdate.facing !== undefined) {
|
if (turtleUpdate.surroundings && turtleUpdate.position && turtleUpdate.facing !== undefined) {
|
||||||
for (const [direction, blockData] of Object.entries(turtleUpdate.surroundings)) {
|
for (const [direction, blockData] of Object.entries(turtleUpdate.surroundings)) {
|
||||||
@@ -184,7 +198,12 @@ app.post('/api/turtle/update', (req, res) => {
|
|||||||
turtle: turtleData.get(turtleID)
|
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) {
|
} catch (error) {
|
||||||
console.error('❌ Error processing turtle update:', error);
|
console.error('❌ Error processing turtle update:', error);
|
||||||
res.status(500).json({ error: error.message });
|
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
|
// Get world blocks for map visualization
|
||||||
app.get('/api/world/blocks', (req, res) => {
|
app.get('/api/world/blocks', (req, res) => {
|
||||||
const blocks = [];
|
const blocks = [];
|
||||||
|
|||||||
Reference in New Issue
Block a user