public override async Task Process() { if (Device.State == Enums.State.Battle) { if (Device.Player.Battle.Replay.Commands.Count > 0) { var id = await ReplayDb.Save(Device.Player.Battle); if (id > 0) { Device.Player.AddEntry(Device.Player.Battle.GetBattleReportStreamEntry(id)); } } Device.Player.Battle = null; } if (Device.State != Enums.State.Home) { await Resources.Gateway.Send(new OwnHomeDataMessage(Device)); await Resources.Gateway.Send(new AvatarStreamMessage(Device)); } else { Device.Disconnect(); } }
public static void Construct() { Configuration = new Configuration(); Configuration.Initialize(); _logger = new Logger(); Logger.Log($"ENV: {(Utils.IsLinux ? "Linux" : "Windows")}"); Csv = new Csv(); Fingerprint = new Fingerprint(); _playerDb = new PlayerDb(); _replayDb = new ReplayDb(); _allianceDb = new AllianceDb(); _redis = new Redis(); Levels = new Levels(); PlayerCache = new Players(); AllianceCache = new Alliances(); LeaderboardCache = new Leaderboards(); ChatManager = new LogicGlobalChatManager(); Gateway = new Gateway(); StartDateTime = DateTime.UtcNow; Gateway.StartAsync().Wait(); }
public override async Task Process() { var replay = await ReplayDb.Get(ReplayId); if (replay != null) { await Resources.Gateway.Send(new HomeBattleReplayDataMessage(Device) { Replay = replay }); } else { await Resources.Gateway.Send(new HomeBattleReplayFailedMessage(Device)); } }
public void Dispose() { Csv = null; Gateway = null; PlayerCache = null; Configuration = null; Levels = null; Fingerprint = null; _messagefactory = null; _commandfactory = null; _debugcommandfactory = null; _playerDb = null; _replayDb = null; _allianceDb = null; _logger = null; }
public Resources() { Configuration = new Configuration(); Configuration.Initialize(); _logger = new Logger(); Logger.Log($"ENV: {(Utils.IsLinux ? "Linux" : "Windows")}"); Csv = new Csv(); Fingerprint = new Fingerprint(); _playerDb = new PlayerDb(); _replayDb = new ReplayDb(); _allianceDb = new AllianceDb(); if (!string.IsNullOrEmpty(Configuration.RedisPassword) && !string.IsNullOrEmpty(Configuration.RedisServer)) { _redis = new Redis(); } _messagefactory = new LogicMagicMessageFactory(); _commandfactory = new LogicCommandManager(); _debugcommandfactory = new DebugCommandFactory(); Levels = new Levels(); PlayerCache = new PlayerCache(); AllianceCache = new AllianceCache(); LeaderboardCache = new LeaderboardCache(); ChatManager = new LogicGlobalChatManager(); Gateway = new Gateway(); StartDateTime = DateTime.UtcNow; Gateway.StartAsync().Wait(); }
public static async Task StartAsync() { Console.Clear(); Console.Title = $"RetroClash Server v{Configuration.Version}"; Console.ForegroundColor = ConsoleColor.Cyan; Console.WriteLine( "\r\n________ _____ ______________ ______ \r\n___ __ \\______ /_______________ ____/__ /_____ __________ /_ \r\n__ /_/ / _ \\ __/_ ___/ __ \\ / __ /_ __ `/_ ___/_ __ \\\r\n_ _, _// __/ /_ _ / / /_/ / /___ _ / / /_/ /_(__ )_ / / /\r\n/_/ |_| \\___/\\__/ /_/ \\____/\\____/ /_/ \\__,_/ /____/ /_/ /_/ \r\n \r\n"); Console.SetOut(new Prefixed()); Console.WriteLine("Preparing..."); Console.ResetColor(); Resources.Construct(); Console.ResetColor(); while (true) { var key = Console.ReadKey(true).Key; Console.ForegroundColor = ConsoleColor.DarkYellow; switch (key) { case ConsoleKey.D: { Configuration.Debug = !Configuration.Debug; Console.WriteLine("Debugging has been " + (Configuration.Debug ? "enabled." : "disabled.")); break; } case ConsoleKey.E: { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Aborting..."); await Task.Delay(2000); Environment.Exit(0); break; } case ConsoleKey.G: { Console.WriteLine( $"[GATEWAY] TP: {Resources.Gateway.TokenCount}, BP: {Resources.Gateway.BufferCount}, EP: {Resources.Gateway.EventCount}"); break; } case ConsoleKey.H: { Console.WriteLine( "Commands: [D]ebug, [E]xit, [G]ateway, [H]elp, [K]ey, [M]aintenance, [S]tatus"); break; } case ConsoleKey.K: { Console.WriteLine($"Generated RC4 Key: {Utils.GenerateRc4Key}"); break; } case ConsoleKey.M: { try { if (Configuration.Maintenance) { MaintenanceEndTime = DateTime.UtcNow; Console.WriteLine("Maintenance has been disabled."); } else { Console.WriteLine("Please enter the maintenance duration in minutes:"); var time = Convert.ToInt32(Console.ReadLine()); MaintenanceEndTime = DateTime.UtcNow.AddMinutes(time); if (Resources.PlayerCache.Keys.Count > 0) { try { Console.WriteLine("Removing every Player in cache..."); foreach (var player in Resources.PlayerCache.Values) { player.Device.Disconnect(); } Resources.PlayerCache.Clear(); Console.WriteLine("Done!"); } catch (Exception exception) { Logger.Log(exception, Enums.LogType.Error); } } Console.WriteLine("Maintenance has been enabled."); } } catch (Exception exception) { Logger.Log(exception, Enums.LogType.Error); } break; } case ConsoleKey.S: { Console.ResetColor(); Console.WriteLine("Current server stats:\n" + new[] { Tuple.Create("Online Players", Resources.PlayerCache.Count), Tuple.Create("Connected Sockets", Resources.Gateway.ConnectedSockets), Tuple.Create("Players saved", (int)await PlayerDb.PlayerCount()), Tuple.Create("Replays saved", (int)await ReplayDb.ReplayCount()), Tuple.Create("Cached players", Redis.IsConnected ? Redis.CachedPlayers() : 0), Tuple.Create("Active battles", Resources.PlayerCache.CurrentActiveBattles), Tuple.Create("Maintenance sec. left", (int)(MaintenanceEndTime - DateTime.UtcNow).TotalSeconds > 0 ? (int)(MaintenanceEndTime - DateTime.UtcNow).TotalSeconds : 0) }.ToStringTable( new[] { "Name", "Value" }, a => a.Item1, a => a.Item2)); break; } default: { Console.WriteLine("Invalid Key. Press 'H' for help."); break; } } Console.ResetColor(); } }
public override async Task Process() { if (Message.StartsWith("/")) { switch (Message.Split(' ')[0]) { case "/help": { await Resources.Gateway.Send(new GlobalChatLineMessage(Device) { Message = "Available commands:\n\n/stats\n -> View the server stats.\n/clear [obstacles/traps/decorations]\n -> Clear all obstacles.\n/help\n -> List of all commands.\n/rename\n -> Change your name again.\n/replay\n -> Watch a random replay.\n/prebase [level]\n -> Load a premade base from level 1 to 6.\n/reset\n -> Reset your village and start from beginning.\n/wall [level]\n -> Set the level of all walls.", Name = "DebugManager", ExpLevel = 100, League = 16 }); break; } case "/prebase": { var lvl = Convert.ToInt32(Message.Split(' ')[1]); if (lvl > 0 && lvl < 7) { Device.Player.LogicGameObjectManager.Json = Resources.Levels.Prebases[lvl - 1]; Device.Player.HeroManager.Clear(); Device.Player.Units.Troops.Clear(); Device.Player.Units.Spells.Clear(); await Resources.Gateway.Send(new OwnHomeDataMessage(Device)); await Resources.Gateway.Send(new GlobalChatLineMessage(Device) { Message = $"Base {lvl} has been set.", Name = "DebugManager", ExpLevel = 100, League = 16 }); } break; } case "/reset": { Device.Player.LogicGameObjectManager.Json = Resources.Levels.StartingHome; Device.Player.Achievements.Clear(); Device.Player.HeroManager.Clear(); Device.Player.Shield.RemoveShield(); Device.Player.Units.Spells.Clear(); Device.Player.Units.Troops.Clear(); await Resources.Gateway.Send(new OwnHomeDataMessage(Device)); await Resources.Gateway.Send(new GlobalChatLineMessage(Device) { Message = "Village has been set to default.", Name = "DebugManager", ExpLevel = 100, League = 16 }); break; } case "/rename": { Device.Player.TutorialSteps = 10; Device.Player.ExpLevel = 1; await Resources.Gateway.Send(new OwnHomeDataMessage(Device)); break; } /*case "/add": * { * var type = Message.Split(' ')[1]; * * switch (type) * { * case "trophies": * { * Device.Player.Score += Convert.ToInt32(Message.Split(' ')[2]); * break; * } * * default: * { * await Resources.Gateway.Send(new GlobalChatLineMessage(Device) * { * Message = "Invalid type.", * Name = "DebugManager", * ExpLevel = 100, * League = 16 * }); * break; * } * } * * await Resources.Gateway.Send(new OwnHomeDataMessage(Device)); * * break; * }*/ case "/remove": { var type = Message.Split(' ')[1]; switch (type) { case "trophies": { Device.Player.Score -= Convert.ToInt32(Message.Split(' ')[2]); break; } default: { await Resources.Gateway.Send(new GlobalChatLineMessage(Device) { Message = "Invalid type.", Name = "DebugManager", ExpLevel = 100, League = 16 }); break; } } await Resources.Gateway.Send(new OwnHomeDataMessage(Device)); break; } case "/clear": { var type = Message.Split(' ')[1]; switch (type) { case "obstacles": { Device.Player.LogicGameObjectManager.Obstacles.Clear(); break; } case "traps": { Device.Player.LogicGameObjectManager.Traps.Clear(); break; } case "decorations": { Device.Player.LogicGameObjectManager.Decorations.Clear(); break; } default: { await Resources.Gateway.Send(new GlobalChatLineMessage(Device) { Message = "Invalid type.", Name = "DebugManager", ExpLevel = 100, League = 16 }); break; } } await Resources.Gateway.Send(new OwnHomeDataMessage(Device)); break; } case "/replay": { var replay = await ReplayDb.GetRandom(); if (replay != null) { await Resources.Gateway.Send(new HomeBattleReplayDataMessage(Device) { Replay = replay }); } else { await Resources.Gateway.Send(new HomeBattleReplayFailedMessage(Device)); } break; } case "/stats": { var uptime = DateTime.UtcNow - Resources.StartDateTime; await Resources.Gateway.Send(new GlobalChatLineMessage(Device) { Message = $"Players online: {Resources.PlayerCache.Count}\nPlayers cached: {Redis.CachedPlayers()}\nUsed RAM: {GC.GetTotalMemory(false) / 1024 / 1024}MB\nUptime: {uptime.Days}d {uptime.Hours}h {uptime.Minutes}m {uptime.Seconds}s\nServer version: {Configuration.Version}\nFingerprint version: {Resources.Fingerprint.GetMajorVersion}.{Resources.Fingerprint.GetBuildVersion}.{Resources.Fingerprint.GetContentVersion}", Name = "DebugManager", ExpLevel = 100, League = 16 }); break; } case "/wall": { var lvl = Convert.ToInt32(Message.Split(' ')[1]); if (lvl > 0 && lvl < 12) { foreach (var building in Device.Player.LogicGameObjectManager.Buildings) { if (building.Data != 1000010) { continue; } building.Level = lvl - 1; } await Resources.Gateway.Send(new OwnHomeDataMessage(Device)); await Resources.Gateway.Send(new GlobalChatLineMessage(Device) { Message = $"Wall level set to {lvl}.", Name = "DebugManager", ExpLevel = 100, League = 16 }); } break; } default: { await Resources.Gateway.Send(new GlobalChatLineMessage(Device) { Message = "Invalid Command. Type '/help' for a list of all commands.", Name = "DebugManager", ExpLevel = 100, League = 16 }); break; } } } else if ((DateTime.UtcNow - Device.LastChatMessage).TotalSeconds >= 1.0) { if (!string.IsNullOrEmpty(Message)) { await Resources.ChatManager.Process(new GlobalChatEntry { Message = Message, SenderName = Device.Player.Name, SenderId = Device.Player.AccountId, SenderExpLevel = Device.Player.ExpLevel, SenderLeague = LogicUtils.GetLeagueByScore(Device.Player.Score) }); Device.LastChatMessage = DateTime.UtcNow; } } }
public async Task EndBattle() { if (Replay.Commands.Count <= 0) { return; } var random = new Random(); var originalScore = Attacker.Score; var attackerReward = random.Next(10, 25); Attacker.Score += attackerReward; var id = await ReplayDb.Save(GetReplayJson); if (id > 0) { Attacker.AddEntry(new BattleReportStreamEntry { MajorVersion = Resources.Fingerprint.GetMajorVersion, Build = Resources.Fingerprint.GetBuildVersion, ContentVersion = Resources.Fingerprint.GetContentVersion, CreationDateTime = DateTime.UtcNow, IsRevengeUsed = true, // Revenge is not supported atm SenderAvatarId = Defender.AccountId, SenderName = Defender.Name, SenderLevel = Defender.ExpLevel, SenderLeagueType = LogicUtils.GetLeagueByScore(Defender.Score), ShardId = 0, ReplayId = id, BattleLogJson = JsonConvert.SerializeObject(new BattleLog { // Here we use random values Loot = new[] { new[] { 3000001, random.Next(1000, 100000) }, new[] { 3000002, random.Next(1000, 100000) } }, Units = new[] { new[] { 4000000, random.Next(10, 50) }, new[] { 4000001, random.Next(10, 50) }, new[] { 4000002, random.Next(10, 50) }, new[] { 4000003, random.Next(10, 50) }, new[] { 4000004, random.Next(10, 50) }, new[] { 4000005, random.Next(10, 50) }, new[] { 4000006, random.Next(10, 50) }, new[] { 4000007, random.Next(10, 50) }, new[] { 4000008, random.Next(10, 50) }, new[] { 4000009, random.Next(10, 50) } }, Levels = new int[0][], Spells = new int[0][], Stats = new BattleLogStats { TownHallDestroyed = true, DestructionPercentage = random.Next(0, 100), AllianceName = "RetroClash", AllianceUsed = false, AttackerScore = attackerReward, BattleEnded = true, BattleTime = Replay.EndTick, DefenderScore = random.Next(-30, -15), HomeId = new[] { 0, 1 }, OriginalScore = originalScore } }) }); } }
public override async Task Process() { if (Message.StartsWith("/")) { switch (Message.Split(' ')[0]) { case "/help": { await Resources.Gateway.Send(new GlobalChatLineMessage(Device) { Message = "Available commands:\n\n/stats\n -> View the server stats.\n/help\n -> List of all commands.\n/rename\n -> Change your name again.\n/replay\n -> Watch a random replay.\n/prebase [level]\n -> Load a premade base from level 1 to 6.\n/reset\n -> Reset your village and start from beginning.\n/wall [level]\n -> Set the level of all walls.", Name = "DebugManager", ExpLevel = 100, League = 16 }); break; } case "/prebase": { var lvl = Convert.ToInt32(Message.Split(' ')[1]); if (lvl > 0 && lvl < 7) { Device.Player.LogicGameObjectManager.Json = Resources.Levels.Prebases[lvl - 1]; Device.Player.HeroManager.Clear(); Device.Player.Units.Troops.Clear(); Device.Player.Units.Spells.Clear(); await Resources.Gateway.Send(new OwnHomeDataMessage(Device)); await Resources.Gateway.Send(new GlobalChatLineMessage(Device) { Message = $"Base {lvl} has been set.", Name = "DebugManager", ExpLevel = 100, League = 16 }); } break; } case "/reset": { Device.Player.LogicGameObjectManager.Json = Resources.Levels.StartingHome; Device.Player.Achievements.Clear(); Device.Player.HeroManager.Clear(); Device.Player.Shield.RemoveShield(); Device.Player.Units.Spells.Clear(); Device.Player.Units.Troops.Clear(); await Resources.Gateway.Send(new OwnHomeDataMessage(Device)); await Resources.Gateway.Send(new GlobalChatLineMessage(Device) { Message = "Village has been set to default.", Name = "DebugManager", ExpLevel = 100, League = 16 }); break; } case "/rename": { Device.Player.TutorialSteps = 10; Device.Player.ExpLevel = 1; await Resources.Gateway.Send(new OwnHomeDataMessage(Device)); break; } case "/replay": { var replay = await ReplayDb.GetRandom(); if (replay != null) { await Resources.Gateway.Send(new HomeBattleReplayDataMessage(Device) { Replay = replay }); } else { await Resources.Gateway.Send(new HomeBattleReplayFailedMessage(Device)); } break; } case "/stats": { await Resources.Gateway.Send(new GlobalChatLineMessage(Device) { Message = $"Players online: {Resources.PlayerCache.Count}\nPlayers cached: {Redis.CachedPlayers()}\nUsed RAM: {GC.GetTotalMemory(false) / 1024 / 1024}MB\nUptime: {(Resources.StartDateTime - DateTime.UtcNow):hh\\:mm\\:ss}\nServer version: {Configuration.Version}", Name = "DebugManager", ExpLevel = 100, League = 16 }); break; }