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;
        }
Beispiel #2
0
        // 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);
        }
Beispiel #6
0
        /*
         * 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();
            }
        }