private static void PeriodicBackup() { // Create the backup path if it doesn't exist (new FileInfo(StarMapStateManager.MapFileDirectory)).Directory.Create(); // Save the map var mapToSave = StarMapStateManager.Build(); string mapAsJson = JsonConvert.SerializeObject(mapToSave); logger.Info("Saving StarMap"); WriteBoth(StarMapStateManager.MapFileDirectory, mapAsJson); // Save faction inventories var inventoriesToSave = FactionInventoryStateManager.Build(); string inventoryAsJson = JsonConvert.SerializeObject(inventoriesToSave); logger.Info("Saving Faction Inventories"); WriteBoth(FactionInventoryStateManager.ShopFileDirectory, inventoryAsJson); // Save player histories var historiesToSave = PlayerStateManager.Build(); string historyAsJson = JsonConvert.SerializeObject(historiesToSave); logger.Info("Saving player history"); lastBackupTime = DateTime.UtcNow; }
// TODO: Generates fake user activity for local testing public static List <UserInfo> GenerateFakeActivity() { List <UserInfo> randos = new List <UserInfo>(20); var random = new Random(); int count = random.Next(5, 20); // No more than twenty logger.Info($"Generating {count} companies"); // Ensure that the map has been loaded StarMapStateManager.Build(); int systemCount = Holder.currentMap.systems.Count; int numSystems = random.Next(1, count); List <string> systems = new List <string>(count); for (int i = 0; i < numSystems; i++) { int systemId = random.Next(0, systemCount - 1); logger.Info($"Using systemID {systemId}"); systems.Add(Holder.currentMap.systems.ElementAt(systemId).name); } logger.Info($"Generated {numSystems} systems"); for (int i = 0; i < count; i++) { UserInfo randomUser = new UserInfo { companyName = GenerateFakeCompanyName(random), LastDataSend = DateTime.UtcNow }; int systemId = random.Next(0, systems.Count - 1); randomUser.lastSystemFoughtAt = systems[systemId]; Array values = Enum.GetValues(typeof(Faction)); Faction randomFaction = (Faction)values.GetValue(random.Next(values.Length)); randomUser.lastFactionFoughtForInWar = randomFaction; randos.Add(randomUser); logger.Info($"Adding randomUser - Company {randomUser.companyName} at system {randomUser.lastSystemFoughtAt} working for {randomUser.lastFactionFoughtForInWar}"); } return(randos); }
public override System PostMissionResult(MissionResult mresult, string companyName) { lock (_missionResultLock) { try { // TODO: Update connection data in a cleaner fashion string ip = Helper.MapRequestIP(); string hashedIP = String.Format("{0:X}", ip.GetHashCode()); DateTime reportTime = DateTime.UtcNow; // TODO: For now, use the IP as the playerId. In the future, GUID Helper.RecordPlayerActivity(mresult, ip, companyName, reportTime); int realDifficulty = 0; // Check to see if the post is suspicious if (Helper.LoadSettings().HardCodedDifficulty != 0) { realDifficulty = Helper.LoadSettings().HardCodedDifficulty; } else { realDifficulty = Math.Min(10, mresult.difficulty); } int realPlanets = Math.Min(Helper.LoadSettings().MaxPlanetSupport, mresult.planetSupport); int realRep = Math.Min(Helper.LoadSettings().MaxRep, mresult.awardedRep); if ((Helper.LoadSettings().HalfSkullPercentageForWin *realDifficulty) + realRep + realPlanets > 50) { logger.Info("Suspicious result reported. See console.log for details."); logger.Debug($"Suspicous result for IP:({ip})" + $" normalized difficulty:({realDifficulty}) planetSupport:({realPlanets}) reptuation:({realRep})" + $" for employer:({mresult.employer}) vs target:({mresult.target}) on system: ({mresult.systemName})" + $" with result:({mresult.result})" ); } HistoryResult hresult = new HistoryResult { date = reportTime }; logger.Info($"New Mission Result for ({companyName}) on ({mresult.systemName})"); logger.Debug($"New MissionResult - ({companyName}) fought for ({mresult.employer}) against ({mresult.target})" + $" on ({mresult.systemName}) and achieved ({mresult.result})"); StarMap builtMap = StarMapStateManager.Build(); System system = builtMap.FindSystemByName(mresult.systemName); FactionControl oldOwnerControl = system.FindHighestControl(); Faction oldOwner = Faction.INVALID_UNSET; if (oldOwnerControl != null) { oldOwner = oldOwnerControl.faction; } FactionControl employerControl = system.FindFactionControlByFaction(mresult.employer); FactionControl targetControl = system.FindFactionControlByFaction(mresult.target); logger.Debug($"Real rep - ({realRep}) and real planets ({realPlanets})"); if (mresult.result == BattleTech.MissionResult.Victory) { int gain = (Helper.LoadSettings().HalfSkullPercentageForWin *realDifficulty) + realRep + realPlanets; int realChange = 0; if (employerControl.percentage >= Helper.LoadSettings().LowerFortBorder&& employerControl.percentage <= Helper.LoadSettings().UpperFortBorder) { logger.Debug("Fort Rules"); realChange = Math.Min( Math.Abs(employerControl.percentage - Helper.LoadSettings().UpperFortBorder), Math.Max(1, (int)Math.Round(gain * Helper.LoadSettings().FortPercentage)) ); } else { realChange = Math.Min( Math.Abs(employerControl.percentage - Helper.LoadSettings().LowerFortBorder), Math.Max(1, gain) ); } hresult.winner = employerControl.faction; hresult.loser = targetControl.faction; hresult.pointsTraded = realChange; logger.Debug($"Victory for ({hresult.winner}) over ({hresult.loser})"); int fortLoss = 0; while (targetControl.percentage > Helper.LoadSettings().LowerFortBorder&& realChange > 0) { targetControl.percentage--; realChange--; fortLoss++; } if (fortLoss > 0) { logger.Debug($"Fortification of ({hresult.loser}) lost {fortLoss} points."); } if (realChange > 0) { targetControl.percentage -= realChange; if (targetControl.percentage < 0) { int leftover = Math.Abs(targetControl.percentage); logger.Debug($"{leftover} points could not be removed from ({hresult.loser}) because its below 0."); targetControl.percentage = 0; int totalEnemyControl = 0; foreach (FactionControl control in system.controlList) { if (control.faction != employerControl.faction) { totalEnemyControl += control.percentage; } } if (totalEnemyControl != 0) { realChange -= leftover; } else { logger.Debug($"No other Factions on Planet."); } } employerControl.percentage += realChange; logger.Debug($"{realChange} points were traded."); } } FactionControl afterBattleOwnerControl = system.FindHighestControl(); Faction newOwner = afterBattleOwnerControl.faction; if (oldOwner != newOwner) { hresult.planetSwitched = true; } else { hresult.planetSwitched = false; } hresult.system = mresult.systemName; Holder.resultHistory.Add(hresult); return(system); } catch (Exception e) { logger.Warn(e, "Failed to process mission result!"); return(null); } } }
// Thread-safe; returns copy of starmap. We clone to prevent modification during serialization (due to heavy nesting). public override System GetSystem(string name) { StarMap builtMap = StarMapStateManager.Build(); return(builtMap.FindSystemByName(name)); }
// Thread-safe; returns copy of starmap. We clone to prevent modification during serialization (due to heavy nesting). public override StarMap GetStarmap() { StarMap builtMap = StarMapStateManager.Build(); return(builtMap); }
/* * Application that uses Windows Communications Foundation (WCF) to provide a RESTful API that allows persistence of Morphyum's WarTech. * If you're unfamiliar with WCF, checkout the following: * * http://dotnetmentors.com/wcf/overview-on-wcf-service-architecture.aspx * https://docs.microsoft.com/en-us/dotnet/framework/wcf/extending/extending-dispatchers * * The client is the PersistentMapClient, in this repository. * This PersistentMapServer is the server. * * Note that WCF is no longer the preferred solution for REST endpoints, which has become ASP.NET5 w/ MVC6. * See https://blog.tonysneed.com/2016/01/06/wcf-is-dead-long-live-mvc-6/. */ static void Main(string[] args) { try { // Start a heart-beat monitor to check the server status BackgroundWorker heartbeatWorker = new BackgroundWorker { WorkerSupportsCancellation = true }; heartbeatWorker.DoWork += new DoWorkEventHandler(HeartBeatMonitor.DoWork); heartbeatWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(HeartBeatMonitor.RunWorkerCompleted); heartbeatWorker.RunWorkerAsync(); SettingsFileMonitor monitor = new SettingsFileMonitor(); monitor.enable(); BackgroundWorker playerHistoryPruner = new BackgroundWorker { WorkerSupportsCancellation = true }; playerHistoryPruner.DoWork += new DoWorkEventHandler(PlayerHistoryPruner.DoWork); playerHistoryPruner.RunWorkerCompleted += new RunWorkerCompletedEventHandler(PlayerHistoryPruner.RunWorkerCompleted); playerHistoryPruner.RunWorkerAsync(); BackgroundWorker backupWorker = new BackgroundWorker { WorkerSupportsCancellation = true }; backupWorker.DoWork += new DoWorkEventHandler(BackupWorker.DoWork); backupWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BackupWorker.RunWorkerCompleted); backupWorker.RunWorkerAsync(); // Preload the data to allow any necessary initialization to happen StarMapStateManager.Build(); FactionInventoryStateManager.Build(); PlayerStateManager.Build(); WarServices warServices = new WarServices(); // Create an AOP proxy object that we can hang Castle.DynamicProxies upon. These are useful for operations across the whole // of the service, or for when we need to fail a message in a reasonable way. var proxy = new Castle.DynamicProxy.ProxyGenerator() .CreateClassProxyWithTarget <WarServices>(warServices, new Castle.DynamicProxy.IInterceptor[] { new UserQuotaInterceptor(), new AdminKeyRequiredInterceptor() }); // Create a RESTful service host. The service instance is automatically, through // the WarServiceInstanceProviderBehaviorAttribute. We create the singleton this way to give // us the chance to customize the binding WebServiceHost _serviceHost = new WebServiceHost(typeof(WarServices), new Uri(ServiceUrl)); AddServiceBehaviors(_serviceHost); // Create a binding that wraps the default WebMessageEncodingBindingElement with a BindingElement // that can GZip compress responses when a client requests it. WebMessageEncodingBindingElement innerEncoding = new WebMessageEncodingBindingElement { ContentTypeMapper = new ForceJsonWebContentMapper() }; GZipMessageEncodingBindingElement encodingWrapper = new GZipMessageEncodingBindingElement(innerEncoding); var transport = new HttpTransportBindingElement { ManualAddressing = true, KeepAliveEnabled = false, AllowCookies = false }; var customBinding = new CustomBinding(encodingWrapper, transport); // Create a default endpoint with the JSON/XML behaviors and the behavior to check the incoming headers for GZIP requests var endpoint = _serviceHost.AddServiceEndpoint(typeof(IWarServices), customBinding, ""); endpoint.Behaviors.Add(new WebHttpBehavior()); endpoint.Behaviors.Add(new GZipBehavior()); _serviceHost.Open(); Console.WriteLine("Open Press Key to close"); Console.ReadKey(); _serviceHost.Close(); Console.WriteLine("Connection Closed"); // Cleanup any outstanding processes monitor.disable(); heartbeatWorker.CancelAsync(); playerHistoryPruner.CancelAsync(); PlayerHistoryPruner.PruneOnExit(); backupWorker.CancelAsync(); BackupWorker.BackupOnExit(); } catch (Exception e) { Console.WriteLine(e); Console.ReadKey(); } }