diff --git a/server/server.js b/server/server.js index e0c4c4a..f032b36 100644 --- a/server/server.js +++ b/server/server.js @@ -554,7 +554,8 @@ app.get('/api/stats', (req, res) => { savedHomes: turtleHomes.size, connectedClients: webClients.size, tasks: db.getAllTasks().length, - miningAreas: db.getMiningAreas().length + miningAreas: db.getMiningAreas().length, + groups: db.getAllGroups().length }; res.json(stats); } catch (error) { @@ -562,6 +563,169 @@ app.get('/api/stats', (req, res) => { } }); +// Get mining statistics +app.get('/api/stats/mining/:turtleId?', (req, res) => { + try { + const turtleId = req.params.turtleId ? parseInt(req.params.turtleId) : null; + const days = parseInt(req.query.days) || 7; + const stats = db.getMiningStats(turtleId, days); + res.json({ stats }); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}); + +// Get top miners leaderboard +app.get('/api/stats/top-miners', (req, res) => { + try { + const limit = parseInt(req.query.limit) || 10; + const topMiners = db.getTopMiners(limit); + res.json({ topMiners }); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}); + +// Record block mined (called by turtles) +app.post('/api/stats/block-mined', (req, res) => { + try { + const { turtleId, blockType } = req.body; + db.recordBlockMined(turtleId, blockType); + res.json({ success: true }); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}); + +// ========== TURTLE GROUPS/TEAMS ENDPOINTS ========== + +// Create a new group +app.post('/api/groups', (req, res) => { + try { + const { groupName, color } = req.body; + const groupId = db.createGroup(groupName, color); + + broadcastToClients({ + type: 'group_created', + groupId, + groupName, + color + }); + + res.json({ success: true, groupId }); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}); + +// Get all groups +app.get('/api/groups', (req, res) => { + try { + const groups = db.getAllGroups(); + // Enhance with member count + const groupsWithMembers = groups.map(group => ({ + ...group, + members: db.getGroupMembers(group.id) + })); + res.json({ groups: groupsWithMembers }); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}); + +// Delete a group +app.delete('/api/groups/:groupId', (req, res) => { + try { + const groupId = parseInt(req.params.groupId); + db.deleteGroup(groupId); + + broadcastToClients({ + type: 'group_deleted', + groupId + }); + + res.json({ success: true }); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}); + +// Add turtle to group +app.post('/api/groups/:groupId/members', (req, res) => { + try { + const groupId = parseInt(req.params.groupId); + const { turtleId } = req.body; + db.addTurtleToGroup(turtleId, groupId); + + broadcastToClients({ + type: 'turtle_added_to_group', + groupId, + turtleId + }); + + res.json({ success: true }); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}); + +// Remove turtle from group +app.delete('/api/groups/:groupId/members/:turtleId', (req, res) => { + try { + const groupId = parseInt(req.params.groupId); + const turtleId = parseInt(req.params.turtleId); + db.removeTurtleFromGroup(turtleId, groupId); + + broadcastToClients({ + type: 'turtle_removed_from_group', + groupId, + turtleId + }); + + res.json({ success: true }); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}); + +// Get turtle's groups +app.get('/api/turtles/:turtleId/groups', (req, res) => { + try { + const turtleId = parseInt(req.params.turtleId); + const groups = db.getTurtleGroups(turtleId); + res.json({ groups }); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}); + +// Send command to all turtles in a group +app.post('/api/groups/:groupId/command', (req, res) => { + try { + const groupId = parseInt(req.params.groupId); + const { command, param } = req.body; + const members = db.getGroupMembers(groupId); + + let successCount = 0; + for (const member of members) { + if (turtleData.has(member.turtle_id)) { + const turtle = turtleData.get(member.turtle_id); + turtle.pendingCommands = turtle.pendingCommands || []; + turtle.pendingCommands.push({ + command, + param, + timestamp: Date.now() + }); + successCount++; + } + } + + res.json({ success: true, sentTo: successCount }); + } catch (error) { + res.status(500).json({ error: error.message }); + } +}); + // Graceful shutdown process.on('SIGINT', () => { console.log('\nšŸ›‘ Shutting down server...');