Initial commit: Shattered Void MMO foundation

- Complete PostgreSQL database schema with 21+ tables
- Express.js server with dual authentication (player/admin)
- WebSocket support for real-time features
- Comprehensive middleware (auth, validation, logging, security)
- Game systems: colonies, resources, fleets, research, factions
- Plugin-based combat architecture
- Admin panel foundation
- Production-ready logging and error handling
- Docker support and CI/CD ready
- Complete project structure following CLAUDE.md patterns

🤖 Generated with Claude Code (https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
MegaProxy 2025-08-02 02:13:05 +00:00
commit 1a60cf55a3
69 changed files with 24471 additions and 0 deletions

View file

@ -0,0 +1,307 @@
/**
* Player Management Controller
* Handles player-specific operations and game-related endpoints
*/
const PlayerService = require('../../services/user/PlayerService');
const { asyncHandler } = require('../../middleware/error.middleware');
const logger = require('../../utils/logger');
const playerService = new PlayerService();
/**
* Get player dashboard data
* GET /api/player/dashboard
*/
const getDashboard = asyncHandler(async (req, res) => {
const correlationId = req.correlationId;
const playerId = req.user.playerId;
logger.info('Player dashboard request received', {
correlationId,
playerId
});
// Get player profile with resources and stats
const profile = await playerService.getPlayerProfile(playerId, correlationId);
// TODO: Add additional dashboard data such as:
// - Recent activities
// - Colony summaries
// - Fleet statuses
// - Research progress
// - Messages/notifications
const dashboardData = {
player: profile,
summary: {
totalColonies: profile.stats.coloniesCount,
totalFleets: profile.stats.fleetsCount,
totalBattles: profile.stats.totalBattles,
winRate: profile.stats.totalBattles > 0
? Math.round((profile.stats.battlesWon / profile.stats.totalBattles) * 100)
: 0
},
// Placeholder for future dashboard sections
recentActivity: [],
notifications: [],
gameStatus: {
online: true,
lastTick: new Date().toISOString()
}
};
logger.info('Player dashboard data retrieved', {
correlationId,
playerId,
username: profile.username
});
res.status(200).json({
success: true,
message: 'Dashboard data retrieved successfully',
data: dashboardData,
correlationId
});
});
/**
* Get player resources
* GET /api/player/resources
*/
const getResources = asyncHandler(async (req, res) => {
const correlationId = req.correlationId;
const playerId = req.user.playerId;
logger.info('Player resources request received', {
correlationId,
playerId
});
const profile = await playerService.getPlayerProfile(playerId, correlationId);
logger.info('Player resources retrieved', {
correlationId,
playerId,
scrap: profile.resources.scrap,
energy: profile.resources.energy
});
res.status(200).json({
success: true,
message: 'Resources retrieved successfully',
data: {
resources: profile.resources,
lastUpdated: new Date().toISOString()
},
correlationId
});
});
/**
* Get player statistics
* GET /api/player/stats
*/
const getStats = asyncHandler(async (req, res) => {
const correlationId = req.correlationId;
const playerId = req.user.playerId;
logger.info('Player statistics request received', {
correlationId,
playerId
});
const profile = await playerService.getPlayerProfile(playerId, correlationId);
const detailedStats = {
...profile.stats,
winRate: profile.stats.totalBattles > 0
? Math.round((profile.stats.battlesWon / profile.stats.totalBattles) * 100)
: 0,
lossRate: profile.stats.totalBattles > 0
? Math.round(((profile.stats.totalBattles - profile.stats.battlesWon) / profile.stats.totalBattles) * 100)
: 0,
accountAge: Math.floor((Date.now() - new Date(profile.createdAt).getTime()) / (1000 * 60 * 60 * 24)) // days
};
logger.info('Player statistics retrieved', {
correlationId,
playerId,
totalBattles: detailedStats.totalBattles,
winRate: detailedStats.winRate
});
res.status(200).json({
success: true,
message: 'Statistics retrieved successfully',
data: {
stats: detailedStats,
lastUpdated: new Date().toISOString()
},
correlationId
});
});
/**
* Update player settings
* PUT /api/player/settings
*/
const updateSettings = asyncHandler(async (req, res) => {
const correlationId = req.correlationId;
const playerId = req.user.playerId;
const settings = req.body;
logger.info('Player settings update request received', {
correlationId,
playerId,
settingsKeys: Object.keys(settings)
});
// TODO: Implement player settings update
// This would involve:
// 1. Validate settings data
// 2. Update player_settings table
// 3. Return updated settings
logger.warn('Player settings update requested but not implemented', {
correlationId,
playerId
});
res.status(501).json({
success: false,
message: 'Player settings update feature not yet implemented',
correlationId
});
});
/**
* Get player activity log
* GET /api/player/activity
*/
const getActivity = asyncHandler(async (req, res) => {
const correlationId = req.correlationId;
const playerId = req.user.playerId;
const { page = 1, limit = 20 } = req.query;
logger.info('Player activity log request received', {
correlationId,
playerId,
page,
limit
});
// TODO: Implement player activity log retrieval
// This would show recent actions like:
// - Colony creations/updates
// - Fleet movements
// - Research completions
// - Battle results
// - Resource transactions
const mockActivity = {
activities: [],
pagination: {
page: parseInt(page),
limit: parseInt(limit),
total: 0,
totalPages: 0,
hasNext: false,
hasPrev: false
}
};
logger.info('Player activity log retrieved', {
correlationId,
playerId,
activitiesCount: mockActivity.activities.length
});
res.status(200).json({
success: true,
message: 'Activity log retrieved successfully',
data: mockActivity,
correlationId
});
});
/**
* Get player notifications
* GET /api/player/notifications
*/
const getNotifications = asyncHandler(async (req, res) => {
const correlationId = req.correlationId;
const playerId = req.user.playerId;
const { unreadOnly = false } = req.query;
logger.info('Player notifications request received', {
correlationId,
playerId,
unreadOnly
});
// TODO: Implement player notifications retrieval
// This would show:
// - System messages
// - Battle results
// - Research completions
// - Fleet arrival notifications
// - Player messages
const mockNotifications = {
notifications: [],
unreadCount: 0,
totalCount: 0
};
logger.info('Player notifications retrieved', {
correlationId,
playerId,
unreadCount: mockNotifications.unreadCount
});
res.status(200).json({
success: true,
message: 'Notifications retrieved successfully',
data: mockNotifications,
correlationId
});
});
/**
* Mark notifications as read
* PUT /api/player/notifications/read
*/
const markNotificationsRead = asyncHandler(async (req, res) => {
const correlationId = req.correlationId;
const playerId = req.user.playerId;
const { notificationIds } = req.body;
logger.info('Mark notifications read request received', {
correlationId,
playerId,
notificationCount: notificationIds?.length || 0
});
// TODO: Implement notification marking as read
logger.warn('Mark notifications read requested but not implemented', {
correlationId,
playerId
});
res.status(501).json({
success: false,
message: 'Mark notifications read feature not yet implemented',
correlationId
});
});
module.exports = {
getDashboard,
getResources,
getStats,
updateSettings,
getActivity,
getNotifications,
markNotificationsRead
};