Files
rr3-server/RR3CommunityServer/Controllers/ConfigController.cs
Daniel Elliott 182026a32c Wire up real implementations for Tracking & Config controllers
- TrackingController: Added database persistence for analytics events
  * Created AnalyticsEvent entity with user/session tracking
  * Store event type, data (JSON), and timestamp
  * Graceful fallback if DB write fails (game doesn't break)

- ConfigController: Added real player counting
  * Query active sessions from last 15 minutes
  * Return actual player count instead of hardcoded 0
  * Real-time server status with DB metrics

- Added AnalyticsEvents table migration
  * Stores all game telemetry for analytics
  * Indexed by UserId for performance
  * JSON event data for flexibility

Controllers now fully wired to database:
- 11/18 controllers REAL implementation 
- 5/18 controllers STUB (config-based) ⚠️
- 2/18 controllers SERVICE (delegated) ⚠️

Total: 95 endpoints, improving from demo to production

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-23 17:03:36 -08:00

156 lines
6.1 KiB
C#

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using RR3CommunityServer.Data;
using RR3CommunityServer.Models;
namespace RR3CommunityServer.Controllers;
[ApiController]
[Route("config/api/android")]
public class ConfigController : ControllerBase
{
private readonly RR3DbContext _context;
private readonly IConfiguration _configuration;
private readonly ILogger<ConfigController> _logger;
public ConfigController(RR3DbContext context, IConfiguration configuration, ILogger<ConfigController> logger)
{
_context = context;
_configuration = configuration;
_logger = logger;
}
/// <summary>
/// Get game configuration - server time, feature flags, version info
/// </summary>
[HttpGet("getGameConfig")]
public ActionResult<SynergyResponse<GameConfig>> GetGameConfig()
{
_logger.LogInformation("GetGameConfig request");
var config = new GameConfig
{
ServerTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
ServerVersion = _configuration["ServerSettings:Version"] ?? "1.0.0",
GameVersion = _configuration["ServerSettings:GameVersion"] ?? "14.0.1",
MaintenanceMode = bool.Parse(_configuration["ServerSettings:MaintenanceMode"] ?? "false"),
MessageOfTheDay = _configuration["ServerSettings:MessageOfTheDay"] ?? "Welcome to RR3 Community Server!",
FeatureFlags = new FeatureFlags
{
MultiplayerEnabled = bool.Parse(_configuration["FeatureFlags:MultiplayerEnabled"] ?? "false"),
LeaderboardsEnabled = bool.Parse(_configuration["FeatureFlags:LeaderboardsEnabled"] ?? "true"),
DailyRewardsEnabled = bool.Parse(_configuration["FeatureFlags:DailyRewardsEnabled"] ?? "true"),
TimeTrialsEnabled = bool.Parse(_configuration["FeatureFlags:TimeTrialsEnabled"] ?? "true"),
CustomContentEnabled = bool.Parse(_configuration["FeatureFlags:CustomContentEnabled"] ?? "true"),
SpecialEventsEnabled = bool.Parse(_configuration["FeatureFlags:SpecialEventsEnabled"] ?? "true"),
AllItemsFree = bool.Parse(_configuration["FeatureFlags:AllItemsFree"] ?? "true")
},
Urls = new ServerUrls
{
BaseUrl = _configuration["ServerSettings:BaseUrl"] ?? "http://localhost:5001",
AssetsUrl = _configuration["ServerSettings:AssetsUrl"] ?? "http://localhost:5001/content/api",
LeaderboardsUrl = _configuration["ServerSettings:LeaderboardsUrl"] ?? "http://localhost:5001/leaderboards/api",
MultiplayerUrl = _configuration["ServerSettings:MultiplayerUrl"] ?? "http://localhost:5001/multiplayer/api"
}
};
var response = new SynergyResponse<GameConfig>
{
resultCode = 0,
message = "Success",
data = config
};
return Ok(response);
}
/// <summary>
/// Get server time (Unix timestamp)
/// </summary>
[HttpGet("getServerTime")]
public ActionResult<SynergyResponse<ServerTime>> GetServerTime()
{
_logger.LogInformation("GetServerTime request");
var response = new SynergyResponse<ServerTime>
{
resultCode = 0,
message = "Success",
data = new ServerTime
{
ServerTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
ServerTimeMs = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
Timezone = "UTC",
IsDST = false
}
};
return Ok(response);
}
/// <summary>
/// Get feature flags
/// </summary>
[HttpGet("getFeatureFlags")]
public ActionResult<SynergyResponse<FeatureFlags>> GetFeatureFlags()
{
_logger.LogInformation("GetFeatureFlags request");
var flags = new FeatureFlags
{
MultiplayerEnabled = bool.Parse(_configuration["FeatureFlags:MultiplayerEnabled"] ?? "false"),
LeaderboardsEnabled = bool.Parse(_configuration["FeatureFlags:LeaderboardsEnabled"] ?? "true"),
DailyRewardsEnabled = bool.Parse(_configuration["FeatureFlags:DailyRewardsEnabled"] ?? "true"),
TimeTrialsEnabled = bool.Parse(_configuration["FeatureFlags:TimeTrialsEnabled"] ?? "true"),
CustomContentEnabled = bool.Parse(_configuration["FeatureFlags:CustomContentEnabled"] ?? "true"),
SpecialEventsEnabled = bool.Parse(_configuration["FeatureFlags:SpecialEventsEnabled"] ?? "true"),
AllItemsFree = bool.Parse(_configuration["FeatureFlags:AllItemsFree"] ?? "true")
};
var response = new SynergyResponse<FeatureFlags>
{
resultCode = 0,
message = "Success",
data = flags
};
return Ok(response);
}
/// <summary>
/// Check server status and health
/// </summary>
[HttpGet("getServerStatus")]
public async Task<ActionResult<SynergyResponse<ServerStatus>>> GetServerStatus()
{
_logger.LogInformation("GetServerStatus request");
// Get real player count from database (sessions created in last 15 minutes)
var fifteenMinutesAgo = DateTime.UtcNow.AddMinutes(-15);
var playerCount = await _context.Sessions
.Where(s => s.CreatedAt >= fifteenMinutesAgo)
.Select(s => s.UserId)
.Distinct()
.CountAsync();
var status = new ServerStatus
{
Status = "online",
Version = _configuration["ServerSettings:Version"] ?? "1.0.0",
MaintenanceMode = bool.Parse(_configuration["ServerSettings:MaintenanceMode"] ?? "false"),
PlayerCount = playerCount,
Uptime = Environment.TickCount64 / 1000, // Seconds since server start
Message = _configuration["ServerSettings:MessageOfTheDay"] ?? string.Empty
};
var response = new SynergyResponse<ServerStatus>
{
resultCode = 0,
message = "Success",
data = status
};
return Ok(response);
}
}