Files
Server/Config.cs
2026-04-26 12:44:06 +02:00

172 lines
6.4 KiB
C#

namespace GeoSus.Server;
using System.Text.Json;
using System.Text.Json.Serialization;
// Konfigurace serveru - všechny herní konstanty
public class ServerConfig
{
// Síťové
public int TcpPort { get; set; } = 7777;
public int HttpPort { get; set; } = 8088;
public int MaxPacketSizeBytes { get; set; } = 1048576; // 1MB
// Timing
public int TickMs { get; set; } = 200;
public int PositionBroadcastRateMs { get; set; } = 1000;
// Pohyb & Anti-Cheat
public double MaxSpeedMps { get; set; } = 12.0;
public double MovementValidationWindowSec { get; set; } = 5.0;
public double TeleportThresholdMeters { get; set; } = 50.0;
public int CheatScoreWarnThreshold { get; set; } = 10;
public int CheatScoreRestrictThreshold { get; set; } = 25;
public int CheatScoreKickThreshold { get; set; } = 50;
// Zabíjení
public double KillDistanceM { get; set; } = 10.0;
public int KillCooldownMs { get; set; } = 30000;
// Meetingy
public double MeetingArrivalRadiusM { get; set; } = 15.0;
public int ArrivalBaseMs { get; set; } = 30000;
public int ArrivalSafetyMarginMs { get; set; } = 500;
public int AllowedLateMs { get; set; } = 2000;
public int DiscussionPhaseMs { get; set; } = 30000;
public int VotingPhaseMs { get; set; } = 45000;
// Emergency meeting
public int EmergencyMeetingCooldownMs { get; set; } = 60000;
public int MaxEmergencyMeetingsPerPlayer { get; set; } = 1;
public double EmergencyMeetingCallRadiusM { get; set; } = 15.0; // Vzdálenost od středu mapy pro svolání emergency meeting
public double ReportDistanceM { get; set; } = 5.0;
// Tasky
public double TaskStartDistanceM { get; set; } = 3.0;
public int TaskLeaveDebounceMs { get; set; } = 2000;
public int TaskProgressKeepaliveMs { get; set; } = 5000;
// Persistence
public int SnapshotEvents { get; set; } = 200;
public int SnapshotIntervalMs { get; set; } = 300000;
public int WalMaxSizeMb { get; set; } = 10;
public string DataPath { get; set; } = "data";
// Host Migration
public int HostTimeoutMs { get; set; } = 15000;
public int ReconnectWindowMs { get; set; } = 60000;
// Lobby
public int IdleLobbyTtlMs { get; set; } = 3600000;
public int JoinCodeTtlMs { get; set; } = 86400000; // 24h
public int MaxPlayersPerLobby { get; set; } = 15;
public int JoinRateLimitPerMinute { get; set; } = 10;
// Security
public int SessionKeySizeBytes { get; set; } = 32; // AES-256
public int RsaKeySizeBits { get; set; } = 2048;
// Stats API
public int StatsApiRateLimit { get; set; } = 100; // per minute per IP
public string? StatsApiKey { get; set; } = null;
// Hra - výchozí hodnoty pro nové lobby
public int DefaultImpostorCount { get; set; } = 1;
public int DefaultTaskCount { get; set; } = 5;
public TiePolicy DefaultTiePolicy { get; set; } = TiePolicy.NoEject;
// Sabotage system
public int SabotageCooldownMs { get; set; } = 30000; // 30s between sabotages
public int CommsBlackoutDurationMs { get; set; } = 30000; // 30s max duration (or until repaired)
public int CriticalMeltdownDeadlineMs { get; set; } = 45000; // 45s to fix or impostor wins
public double RepairStationDistanceM { get; set; } = 5.0; // Must be within 5m to repair
public int RepairStationHoldMs { get; set; } = 3000; // Must hold for 3s to complete repair
public int SimultaneousRepairWindowMs { get; set; } = 5000; // 5s window for both stations to be repaired
// Overpass API (Map Data)
public string OverpassApiUrl { get; set; } = "https://overpass-api.de/api/interpreter";
public int OverpassTimeoutSec { get; set; } = 30;
public int OverpassCacheMaxEntries { get; set; } = 100;
public bool OverpassEnabled { get; set; } = true;
public double MinTaskSpacingMeters { get; set; } = 20.0; // Minimum spacing between tasks
public static ServerConfig Load(string path)
{
ServerConfig config;
if (File.Exists(path))
{
var json = File.ReadAllText(path);
config = JsonSerializer.Deserialize<ServerConfig>(json, JsonOptions.Default) ?? new ServerConfig();
}
else
{
config = new ServerConfig();
}
// Override z environment variables (pro Docker)
config.ApplyEnvironmentOverrides();
return config;
}
/// <summary>
/// Aplikuje override hodnot z environment variables.
/// Prefix: GEOSUS_
/// Příklady: GEOSUS_TCP_PORT=7777, GEOSUS_HTTP_PORT=8088
/// </summary>
private void ApplyEnvironmentOverrides()
{
// Síťové
if (int.TryParse(Environment.GetEnvironmentVariable("GEOSUS_TCP_PORT"), out var tcpPort))
TcpPort = tcpPort;
if (int.TryParse(Environment.GetEnvironmentVariable("GEOSUS_HTTP_PORT"), out var httpPort))
HttpPort = httpPort;
// Data path
var dataPath = Environment.GetEnvironmentVariable("GEOSUS_DATA_PATH");
if (!string.IsNullOrEmpty(dataPath))
DataPath = dataPath;
// Overpass API
var overpassUrl = Environment.GetEnvironmentVariable("GEOSUS_OVERPASS_URL");
if (!string.IsNullOrEmpty(overpassUrl))
OverpassApiUrl = overpassUrl;
// Stats API key
var apiKey = Environment.GetEnvironmentVariable("GEOSUS_API_KEY");
if (!string.IsNullOrEmpty(apiKey))
StatsApiKey = apiKey;
}
public void Save(string path)
{
var json = JsonSerializer.Serialize(this, JsonOptions.Indented);
File.WriteAllText(path, json);
}
}
public enum TiePolicy
{
NoEject,
Random,
EjectLowestId
}
public static class JsonOptions
{
public static readonly JsonSerializerOptions Default = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters = { new JsonStringEnumConverter() },
WriteIndented = false
};
public static readonly JsonSerializerOptions Indented = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters = { new JsonStringEnumConverter() },
WriteIndented = true
};
}