Example #1
0
        private void UpdateVessels()
        {
            iterateVessels.Clear();
            iterateVessels.AddRange(loadingFlyingVessels.Keys);
            foreach (Guid vesselID in iterateVessels)
            {
                if (!loadingFlyingVessels.ContainsKey(vesselID))
                {
                    continue;
                }
                HackyFlyingVesselLoad hfvl = loadingFlyingVessels[vesselID];

                if (hfvl.flyingVessel == null || hfvl.flyingVessel.state == Vessel.State.DEAD)
                {
                    DarkLog.Debug("Hacky load failed: Vessel destroyed");
                    loadingFlyingVessels.Remove(vesselID);
                    continue;
                }

                if (!FlightGlobals.fetch.vessels.Contains(hfvl.flyingVessel))
                {
                    DarkLog.Debug("Hacky load failed: Vessel destroyed");
                    loadingFlyingVessels.Remove(vesselID);
                    continue;
                }

                if (!LockSystem.fetch.LockExists("update-" + vesselID) || LockSystem.fetch.LockIsOurs("update-" + vesselID))
                {
                    DarkLog.Debug("Hacky load removed: Vessel stopped being controlled by another player");
                    loadingFlyingVessels.Remove(vesselID);
                    VesselWorker.fetch.KillVessel(hfvl.flyingVessel);
                    continue;
                }

                if (hfvl.flyingVessel.loaded)
                {
                    if ((Client.realtimeSinceStartup - hfvl.lastUnpackTime) > UNPACK_INTERVAL)
                    {
                        DarkLog.Debug("Hacky load attempting to take loaded vessel off rails");
                        hfvl.lastUnpackTime = Client.realtimeSinceStartup;
                        try
                        {
                            hfvl.flyingVessel.GoOffRails();
                        }
                        catch (Exception e)
                        {
                            //Just in case, I don't think this can throw but you never really know with KSP.
                            DarkLog.Debug("Hacky load failed to take vessel of rails: " + e.Message);
                        }
                        continue;
                    }
                }

                if (!hfvl.flyingVessel.packed)
                {
                    DarkLog.Debug("Hacky load successful: Vessel is off rails");
                    loadingFlyingVessels.Remove(vesselID);
                    hfvl.flyingVessel.Landed    = false;
                    hfvl.flyingVessel.Splashed  = false;
                    hfvl.flyingVessel.landedAt  = string.Empty;
                    hfvl.flyingVessel.situation = Vessel.Situations.FLYING;
                    hfvl.flyingVessel.vesselRanges.landed.load   = LANDED_LOAD_DISTANCE_DEFAULT;
                    hfvl.flyingVessel.vesselRanges.landed.unload = LANDED_UNLOAD_DISTANCE_DEFAULT;
                    continue;
                }

                double atmoPressure = hfvl.flyingVessel.mainBody.GetPressure(hfvl.flyingVessel.altitude);
                if (atmoPressure < 0.01d)
                {
                    DarkLog.Debug("Hacky load successful: Vessel is now safe from atmo");
                    loadingFlyingVessels.Remove(vesselID);
                    hfvl.flyingVessel.Landed    = false;
                    hfvl.flyingVessel.Splashed  = false;
                    hfvl.flyingVessel.landedAt  = string.Empty;
                    hfvl.flyingVessel.situation = Vessel.Situations.FLYING;
                    hfvl.flyingVessel.vesselRanges.landed.load   = LANDED_LOAD_DISTANCE_DEFAULT;
                    hfvl.flyingVessel.vesselRanges.landed.unload = LANDED_UNLOAD_DISTANCE_DEFAULT;
                    continue;
                }

                if (hfvl.lastVesselUpdate != null)
                {
                    hfvl.lastVesselUpdate.Apply();
                }
            }
        }
Example #2
0
        public void Awake()
        {
            DarkLog.SetMainThread();

            if (!CompatibilityChecker.IsCompatible() || !InstallChecker.IsCorrectlyInstalled())
            {
                modDisabled = true;
            }
            if (Settings.fetch.disclaimerAccepted != 1)
            {
                modDisabled = true;
                DisclaimerWindow.SpawnDialog();
            }

            Profiler.DMPReferenceTime.Start();
            DontDestroyOnLoad(this);

            // Prevents symlink warning for development.
            SetupDirectoriesIfNeeded();

            // UniverseSyncCache needs to run expiry here
            UniverseSyncCache.fetch.ExpireCache();

            // Register events needed to bootstrap the workers.
            lock (eventLock)
            {
                resetEvent.Add(LockSystem.Reset);
                resetEvent.Add(AdminSystem.Reset);
                resetEvent.Add(AsteroidWorker.Reset);
                resetEvent.Add(ChatWorker.Reset);
                resetEvent.Add(CraftLibraryWorker.Reset);
                resetEvent.Add(DebugWindow.Reset);
                resetEvent.Add(DynamicTickWorker.Reset);
                resetEvent.Add(FlagSyncer.Reset);
                resetEvent.Add(HackyInAtmoLoader.Reset);
                resetEvent.Add(KerbalReassigner.Reset);
                resetEvent.Add(PlayerColorWorker.Reset);
                resetEvent.Add(PlayerStatusWindow.Reset);
                resetEvent.Add(PlayerStatusWorker.Reset);
                resetEvent.Add(PartKiller.Reset);
                resetEvent.Add(ScenarioWorker.Reset);
                resetEvent.Add(ScreenshotWorker.Reset);
                resetEvent.Add(TimeSyncer.Reset);
                resetEvent.Add(ToolbarSupport.Reset);
                resetEvent.Add(VesselWorker.Reset);
                resetEvent.Add(WarpWorker.Reset);
                GameEvents.onHideUI.Add(() =>
                {
                    showGUI = false;
                });
                GameEvents.onShowUI.Add(() =>
                {
                    showGUI = true;
                });
            }
            FireResetEvent();
            HandleCommandLineArgs();
            long testTime = Compression.TestSysIOCompression();

            DarkLog.Debug("System.IO compression works: " + Compression.sysIOCompressionWorks + ", test time: " + testTime + " ms.");
            DarkLog.Debug("DarkMultiPlayer " + Common.PROGRAM_VERSION + ", protocol " + Common.PROTOCOL_VERSION + " Initialized!");
        }
Example #3
0
        public void Update()
        {
            long startClock = Profiler.DMPReferenceTime.ElapsedTicks;

            lastClockTicks           = DateTime.UtcNow.Ticks;
            lastRealTimeSinceStartup = Time.realtimeSinceStartup;
            DarkLog.Update();

            if (modDisabled)
            {
                return;
            }
            try
            {
                if (HighLogic.LoadedScene == GameScenes.MAINMENU)
                {
                    if (!modWorker.dllListBuilt)
                    {
                        modWorker.dllListBuilt = true;
                        modWorker.BuildDllFileList();
                    }
                    if (!dmpSaveChecked)
                    {
                        dmpSaveChecked = true;
                        SetupBlankGameIfNeeded();
                    }
                }

                //Handle GUI events

                if (!connectionWindow.renameEventHandled)
                {
                    dmpSettings.SaveSettings();
                    connectionWindow.renameEventHandled = true;
                }
                if (!connectionWindow.addEventHandled)
                {
                    dmpSettings.servers.Add(connectionWindow.addEntry);
                    connectionWindow.addEntry = null;
                    dmpSettings.SaveSettings();
                    connectionWindow.addingServer    = false;
                    connectionWindow.addEventHandled = true;
                }
                if (!connectionWindow.editEventHandled)
                {
                    dmpSettings.servers[connectionWindow.selected].name    = connectionWindow.editEntry.name;
                    dmpSettings.servers[connectionWindow.selected].address = connectionWindow.editEntry.address;
                    dmpSettings.servers[connectionWindow.selected].port    = connectionWindow.editEntry.port;
                    connectionWindow.editEntry = null;
                    dmpSettings.SaveSettings();
                    connectionWindow.addingServer     = false;
                    connectionWindow.editEventHandled = true;
                }
                if (!connectionWindow.removeEventHandled)
                {
                    dmpSettings.servers.RemoveAt(connectionWindow.selected);
                    connectionWindow.selected = -1;
                    dmpSettings.SaveSettings();
                    connectionWindow.removeEventHandled = true;
                }
                if (!connectionWindow.connectEventHandled)
                {
                    connectionWindow.connectEventHandled = true;
                    dmpGame = new DMPGame(dmpSettings, universeSyncCache, modWorker, connectionWindow, dmpModInterface, toolbarSupport, optionsWindow);
                    dmpGame.networkWorker.ConnectToServer(dmpSettings.servers[connectionWindow.selected].address, dmpSettings.servers[connectionWindow.selected].port);
                }
                if (commandLineConnect != null && HighLogic.LoadedScene == GameScenes.MAINMENU && Time.timeSinceLevelLoad > 1f)
                {
                    dmpGame = new DMPGame(dmpSettings, universeSyncCache, modWorker, connectionWindow, dmpModInterface, toolbarSupport, optionsWindow);
                    dmpGame.networkWorker.ConnectToServer(commandLineConnect.address, commandLineConnect.port);
                    commandLineConnect = null;
                }

                if (!connectionWindow.disconnectEventHandled)
                {
                    connectionWindow.disconnectEventHandled = true;
                    if (dmpGame != null)
                    {
                        if (dmpGame.networkWorker.state == ClientState.CONNECTING)
                        {
                            dmpGame.networkWorker.Disconnect("Cancelled connection to server");
                        }
                        else
                        {
                            dmpGame.networkWorker.SendDisconnect("Quit during initial sync");
                        }
                        dmpGame.Stop();
                        dmpGame = null;
                    }
                }

                connectionWindow.Update();
                modWindow.Update();
                optionsWindow.Update();
                universeConverterWindow.Update();
                dmpModInterface.Update();

                if (dmpGame != null)
                {
                    foreach (Action updateAction in dmpGame.updateEvent)
                    {
                        try
                        {
                            updateAction();
                        }
                        catch (Exception e)
                        {
                            DarkLog.Debug("Threw in UpdateEvent, exception: " + e);
                            if (dmpGame.networkWorker.state != ClientState.RUNNING)
                            {
                                if (dmpGame.networkWorker.state != ClientState.DISCONNECTED)
                                {
                                    dmpGame.networkWorker.SendDisconnect("Unhandled error while syncing!");
                                }
                                else
                                {
                                    dmpGame.networkWorker.Disconnect("Unhandled error while syncing!");
                                }
                            }
                        }
                    }
                }
                //Force quit
                if (dmpGame != null && dmpGame.forceQuit)
                {
                    dmpGame.forceQuit = false;
                    dmpGame.Stop();
                    dmpGame = null;
                    StopGame();
                }


                if (displayDisconnectMessage)
                {
                    if (HighLogic.LoadedScene != GameScenes.MAINMENU)
                    {
                        if ((Client.realtimeSinceStartup - lastDisconnectMessageCheck) > 1f)
                        {
                            lastDisconnectMessageCheck = Client.realtimeSinceStartup;
                            if (disconnectMessage != null)
                            {
                                disconnectMessage.duration = 0;
                            }
                            disconnectMessage = ScreenMessages.PostScreenMessage("You have been disconnected!", 2f, ScreenMessageStyle.UPPER_CENTER);
                        }
                    }
                    else
                    {
                        displayDisconnectMessage = false;
                    }
                }

                //Normal quit
                if (dmpGame != null && dmpGame.running)
                {
                    if (!dmpGame.playerStatusWindow.disconnectEventHandled)
                    {
                        dmpGame.playerStatusWindow.disconnectEventHandled = true;
                        dmpGame.forceQuit = true;
                        dmpGame.scenarioWorker.SendScenarioModules(true); // Send scenario modules before disconnecting
                        dmpGame.networkWorker.SendDisconnect("Quit");
                    }

                    if (dmpGame.screenshotWorker.uploadScreenshot)
                    {
                        dmpGame.screenshotWorker.uploadScreenshot = false;
                        StartCoroutine(UploadScreenshot());
                    }

                    if (HighLogic.CurrentGame.flagURL != dmpSettings.selectedFlag)
                    {
                        DarkLog.Debug("Saving selected flag");
                        dmpSettings.selectedFlag = HighLogic.CurrentGame.flagURL;
                        dmpSettings.SaveSettings();
                        dmpGame.flagSyncer.flagChangeEvent = true;
                    }

                    // save every GeeASL from each body in FlightGlobals
                    if (HighLogic.LoadedScene == GameScenes.FLIGHT && bodiesGees.Count == 0)
                    {
                        foreach (CelestialBody body in FlightGlobals.fetch.bodies)
                        {
                            bodiesGees.Add(body, body.GeeASL);
                        }
                    }

                    //handle use of cheats
                    if (!dmpGame.serverAllowCheats)
                    {
                        CheatOptions.InfinitePropellant             = false;
                        CheatOptions.NoCrashDamage                  = false;
                        CheatOptions.IgnoreAgencyMindsetOnContracts = false;
                        CheatOptions.IgnoreMaxTemperature           = false;
                        CheatOptions.InfiniteElectricity            = false;
                        CheatOptions.NoCrashDamage                  = false;
                        CheatOptions.UnbreakableJoints              = false;

                        foreach (KeyValuePair <CelestialBody, double> gravityEntry in bodiesGees)
                        {
                            gravityEntry.Key.GeeASL = gravityEntry.Value;
                        }
                    }

                    if (HighLogic.LoadedScene == GameScenes.FLIGHT && FlightGlobals.ready)
                    {
                        HighLogic.CurrentGame.Parameters.Flight.CanLeaveToSpaceCenter = !dmpGame.vesselWorker.isSpectating && dmpSettings.revertEnabled || (PauseMenu.canSaveAndExit == ClearToSaveStatus.CLEAR);
                    }
                    else
                    {
                        HighLogic.CurrentGame.Parameters.Flight.CanLeaveToSpaceCenter = true;
                    }

                    if (HighLogic.LoadedScene == GameScenes.MAINMENU)
                    {
                        dmpGame.networkWorker.SendDisconnect("Quit to main menu");
                        dmpGame.Stop();
                        dmpGame = null;
                    }
                }

                if (dmpGame != null && dmpGame.startGame)
                {
                    dmpGame.startGame = false;
                    StartGame();
                }
            }
            catch (Exception e)
            {
                if (dmpGame != null)
                {
                    DarkLog.Debug("Threw in Update, state " + dmpGame.networkWorker.state.ToString() + ", exception: " + e);
                    if (dmpGame.networkWorker.state != ClientState.RUNNING)
                    {
                        if (dmpGame.networkWorker.state != ClientState.DISCONNECTED)
                        {
                            dmpGame.networkWorker.SendDisconnect("Unhandled error while syncing!");
                        }
                        else
                        {
                            dmpGame.networkWorker.Disconnect("Unhandled error while syncing!");
                        }
                    }
                }
                else
                {
                    DarkLog.Debug("Threw in Update, state NO_NETWORKWORKER, exception: " + e);
                }
            }
            Profiler.updateData.ReportTime(startClock);
        }
Example #4
0
        public void GenerateModControlFile(bool whitelistMode)
        {
            string gameDataDir = Client.dmpClient.gameDataDir;

            string[] topLevelFiles  = Directory.GetFiles(gameDataDir);
            string[] modDirectories = Directory.GetDirectories(gameDataDir);

            List <string> requiredFiles = new List <string>();
            List <string> optionalFiles = new List <string>();
            List <string> partsList     = Common.GetStockParts();

            //If whitelisting, add top level dll's to required (It's usually things like modulemanager)
            foreach (string dllFile in topLevelFiles)
            {
                if (Path.GetExtension(dllFile).ToLower() == ".dll")
                {
                    requiredFiles.Add(Path.GetFileName(dllFile));
                }
            }

            foreach (string modDirectory in modDirectories)
            {
                string lowerDirectoryName = modDirectory.Substring(modDirectory.ToLower().IndexOf("gamedata", StringComparison.Ordinal) + 9).ToLower();
                if (lowerDirectoryName.StartsWith("squad", StringComparison.Ordinal))
                {
                    continue;
                }
                if (lowerDirectoryName.StartsWith("nasamission", StringComparison.Ordinal))
                {
                    continue;
                }
                if (lowerDirectoryName.StartsWith("darkmultiplayer", StringComparison.Ordinal))
                {
                    continue;
                }
                bool          modIsRequired   = false;
                string[]      partFiles       = Directory.GetFiles(Path.Combine(gameDataDir, modDirectory), "*", SearchOption.AllDirectories);
                List <string> modDllFiles     = new List <string>();
                List <string> modPartCfgFiles = new List <string>();
                foreach (string partFile in partFiles)
                {
                    bool   fileIsPartFile   = false;
                    string relativeFileName = partFile.Substring(partFile.ToLower().IndexOf("gamedata", StringComparison.Ordinal) + 9).Replace(@"\", "/");
                    if (Path.GetExtension(partFile).ToLower() == ".cfg")
                    {
                        ConfigNode cn = ConfigNode.Load(partFile);
                        if (cn == null)
                        {
                            continue;
                        }
                        foreach (ConfigNode partNode in cn.GetNodes("PART"))
                        {
                            string partName = partNode.GetValue("name");
                            if (partName != null)
                            {
                                DarkLog.Debug("Part detected in " + relativeFileName + " , name: " + partName);
                                partName       = partName.Replace('_', '.');
                                modIsRequired  = true;
                                fileIsPartFile = true;
                                partsList.Add(partName);
                            }
                        }
                    }
                    if (fileIsPartFile)
                    {
                        modPartCfgFiles.Add(relativeFileName);
                    }
                    if (Path.GetExtension(partFile).ToLower() == ".dll")
                    {
                        modDllFiles.Add(relativeFileName);
                    }
                }

                if (modIsRequired)
                {
                    if (modDllFiles.Count > 0)
                    {
                        //If the mod as a plugin, just require that. It's clear enough.
                        requiredFiles.AddRange(modDllFiles);
                    }
                    else
                    {
                        //If the mod does *not* have a plugin (Scoop-o-matic is an example), add the part files to required instead.
                        requiredFiles.AddRange(modPartCfgFiles);
                    }
                }
                else
                {
                    if (whitelistMode)
                    {
                        optionalFiles.AddRange(modDllFiles);
                    }
                }
            }
            string modFileData = Common.GenerateModFileStringData(requiredFiles.ToArray(), optionalFiles.ToArray(), whitelistMode, new string[0], partsList.ToArray());
            string saveModFile = Path.Combine(Client.dmpClient.kspRootPath, "mod-control.txt");

            using (StreamWriter sw = new StreamWriter(saveModFile, false))
            {
                sw.Write(modFileData);
            }
            ScreenMessages.PostScreenMessage("mod-control.txt file generated in your KSP folder\nMove it to DMPServer/Config/", 5f, ScreenMessageStyle.UPPER_CENTER);
        }
 public void ExpireCache()
 {
     DarkLog.Debug("Expiring cache!");
     //No folder, no delete.
     if (!Directory.Exists(Path.Combine(cacheDirectory, "Incoming")))
     {
         DarkLog.Debug("No sync cache folder, skipping expire.");
         return;
     }
     //Delete partial incoming files
     string[] incomingFiles = Directory.GetFiles(Path.Combine(cacheDirectory, "Incoming"));
     foreach (string incomingFile in incomingFiles)
     {
         DarkLog.Debug("Deleting partially cached object " + incomingFile);
         File.Delete(incomingFile);
     }
     //Delete old files
     string[] cacheObjects = GetCachedObjects();
     currentCacheSize = 0;
     foreach (string cacheObject in cacheObjects)
     {
         if (!string.IsNullOrEmpty(cacheObject))
         {
             string cacheFile = Path.Combine(cacheDirectory, cacheObject + ".txt");
             //If the file is older than a week, delete it.
             if (File.GetCreationTime(cacheFile).AddDays(7d) < DateTime.Now)
             {
                 DarkLog.Debug("Deleting cached object " + cacheObject + ", reason: Expired!");
                 File.Delete(cacheFile);
             }
             else
             {
                 FileInfo fi = new FileInfo(cacheFile);
                 fileCreationTimes[cacheObject] = fi.CreationTime;
                 fileLengths[cacheObject]       = fi.Length;
                 currentCacheSize += fi.Length;
             }
         }
     }
     //While the directory is over (cacheSize) MB
     while (currentCacheSize > (dmpSettings.cacheSize * 1024 * 1024))
     {
         string deleteObject = null;
         //Find oldest file
         foreach (KeyValuePair <string, DateTime> testFile in fileCreationTimes)
         {
             if (deleteObject == null)
             {
                 deleteObject = testFile.Key;
             }
             if (testFile.Value < fileCreationTimes[deleteObject])
             {
                 deleteObject = testFile.Key;
             }
         }
         if (deleteObject == null)
         {
             return;
         }
         DarkLog.Debug("Deleting cached object " + deleteObject + ", reason: Cache full!");
         string deleteFile = Path.Combine(cacheDirectory, deleteObject + ".txt");
         File.Delete(deleteFile);
         currentCacheSize -= fileLengths[deleteObject];
         if (fileCreationTimes.ContainsKey(deleteObject))
         {
             fileCreationTimes.Remove(deleteObject);
         }
         if (fileLengths.ContainsKey(deleteObject))
         {
             fileLengths.Remove(deleteObject);
         }
     }
 }
Example #6
0
 private void DeleteAllTheControlLocksSoTheSpaceCentreBugGoesAway()
 {
     DarkLog.Debug("Clearing " + InputLockManager.lockStack.Count + " control locks");
     InputLockManager.ClearControlLocks();
 }
Example #7
0
        public void LoadSettings()
        {
            try
            {
                if (File.Exists(backupOldSettingsFile) || File.Exists(oldSettingsFile))
                {
                    DarkLog.Debug("[Settings]: Loading old settings");
                    LoadOldSettings();
                    SaveSettings();
                    File.Delete(backupOldSettingsFile);
                    File.Delete(oldSettingsFile);
                }

                bool       saveAfterLoad = false;
                ConfigNode mainNode      = new ConfigNode();

                if (File.Exists(backupSettingsFile) && !File.Exists(settingsFile))
                {
                    DarkLog.Debug("[Settings]: Restoring backup file");
                    File.Copy(backupSettingsFile, settingsFile);
                }

                if (!File.Exists(settingsFile))
                {
                    mainNode   = GetDefaultSettings();
                    playerName = DEFAULT_PLAYER_NAME;
                    mainNode.Save(settingsFile);
                }

                if (!File.Exists(backupSettingsFile))
                {
                    DarkLog.Debug("[Settings]: Backing up settings");
                    File.Copy(settingsFile, backupSettingsFile);
                }

                mainNode = ConfigNode.Load(settingsFile);

                ConfigNode settingsNode = mainNode.GetNode("SETTINGS");
                ConfigNode playerNode   = settingsNode.GetNode("PLAYER");
                ConfigNode bindingsNode = settingsNode.GetNode("KEYBINDINGS");

                playerName = playerNode.GetValue("name");

                if (!int.TryParse(settingsNode.GetValue("cacheSize"), out cacheSize))
                {
                    DarkLog.Debug("[Settings]: Adding cache size to settings file");
                    cacheSize     = DEFAULT_CACHE_SIZE;
                    saveAfterLoad = true;
                }

                if (!int.TryParse(settingsNode.GetValue("disclaimer"), out disclaimerAccepted))
                {
                    DarkLog.Debug("[Settings]: Adding disclaimer to settings file");
                    disclaimerAccepted = 0;
                    saveAfterLoad      = true;
                }

                if (!int.TryParse(settingsNode.GetValue("serverlist-mode"), out serverlistMode))
                {
                    DarkLog.Debug("[Settings]: Adding serverlist-mode to settings file");
                    serverlistMode = 0;
                    saveAfterLoad  = true;
                }

                if (!playerNode.TryGetValue("color", ref playerColor))
                {
                    DarkLog.Debug("[Settings]: Adding color to settings file");
                    playerColor   = PlayerColorWorker.GenerateRandomColor();
                    saveAfterLoad = true;
                }

                int chatKey = (int)KeyCode.BackQuote, screenshotKey = (int)KeyCode.F8;
                if (!int.TryParse(bindingsNode.GetValue("chat"), out chatKey))
                {
                    DarkLog.Debug("[Settings]: Adding chat key to settings file");
                    this.chatKey  = KeyCode.BackQuote;
                    saveAfterLoad = true;
                }
                else
                {
                    this.chatKey = (KeyCode)chatKey;
                }

                if (!int.TryParse(bindingsNode.GetValue("screenshot"), out screenshotKey))
                {
                    DarkLog.Debug("[Settings]: Adding screenshot key to settings file");
                    this.screenshotKey = KeyCode.F8;
                    saveAfterLoad      = true;
                }
                else
                {
                    this.screenshotKey = (KeyCode)screenshotKey;
                }

                if (!playerNode.TryGetValue("flag", ref selectedFlag))
                {
                    DarkLog.Debug("[Settings]: Adding selected flag to settings file");
                    selectedFlag  = "Squad/Flags/default";
                    saveAfterLoad = true;
                }

                if (!settingsNode.TryGetValue("compression", ref compressionEnabled))
                {
                    DarkLog.Debug("[Settings]: Adding compression flag to settings file");
                    compressionEnabled = true;
                    saveAfterLoad      = true;
                }

                if (!settingsNode.TryGetValue("revert", ref revertEnabled))
                {
                    DarkLog.Debug("[Settings]: Adding revert flag to settings file");
                    revertEnabled = true;
                    saveAfterLoad = true;
                }

                string interpolatorString = null;
                int    interpolatorInt    = 0;
                try
                {
                    //Make sure we haven't saved to the old int type
                    if (settingsNode.TryGetValue("interpolation", ref interpolatorString) && !int.TryParse(interpolatorString, out interpolatorInt))
                    {
                        interpolatorType = (InterpolatorType)Enum.Parse(typeof(InterpolatorType), interpolatorString);
                    }
                    else
                    {
                        DarkLog.Debug("[Settings]: Adding interpolation flag to settings file");
                        interpolatorType = InterpolatorType.INTERPOLATE1S;
                        saveAfterLoad    = true;
                    }
                }
                catch
                {
                    interpolatorType = InterpolatorType.INTERPOLATE1S;
                    saveAfterLoad    = true;
                }

                int toolbarType;
                if (!int.TryParse(settingsNode.GetValue("toolbar"), out toolbarType))
                {
                    DarkLog.Debug("[Settings]: Adding toolbar flag to settings file");
                    this.toolbarType = DMPToolbarType.BLIZZY_IF_INSTALLED;
                    saveAfterLoad    = true;
                }
                else
                {
                    this.toolbarType = (DMPToolbarType)toolbarType;
                }

                ConfigNode serversNode = settingsNode.GetNode("SERVERS");
                servers.Clear();
                if (serversNode.HasNode("SERVER"))
                {
                    foreach (ConfigNode serverNode in serversNode.GetNodes("SERVER"))
                    {
                        ServerEntry newServer = new ServerEntry();
                        newServer.name    = serverNode.GetValue("name");
                        newServer.address = serverNode.GetValue("address");
                        serverNode.TryGetValue("port", ref newServer.port);
                        servers.Add(newServer);
                    }
                }

                if (saveAfterLoad)
                {
                    SaveSettings();
                }
            }
            catch (Exception e)
            {
                DarkLog.Debug("Error while loading settings:");
                DarkLog.Debug(e.ToString());
            }

            //Read player token
            try
            {
                //Restore backup if needed
                if (File.Exists(backupPublicKeyFile) && File.Exists(backupPrivateKeyFile) && (!File.Exists(publicKeyFile) || !File.Exists(privateKeyFile)))
                {
                    DarkLog.Debug("[Settings]: Restoring backed up keypair!");
                    File.Copy(backupPublicKeyFile, publicKeyFile, true);
                    File.Copy(backupPrivateKeyFile, privateKeyFile, true);
                }
                //Load or create token file
                if (File.Exists(privateKeyFile) && File.Exists(publicKeyFile))
                {
                    playerPublicKey  = File.ReadAllText(publicKeyFile);
                    playerPrivateKey = File.ReadAllText(privateKeyFile);
                }
                else
                {
                    DarkLog.Debug("[Settings]: Creating new keypair!");
                    GenerateNewKeypair();
                }
                //Save backup token file if needed
                if (!File.Exists(backupPublicKeyFile) || !File.Exists(backupPrivateKeyFile))
                {
                    DarkLog.Debug("[Settings]: Backing up keypair");
                    File.Copy(publicKeyFile, backupPublicKeyFile, true);
                    File.Copy(privateKeyFile, backupPrivateKeyFile, true);
                }
            }
            catch
            {
                DarkLog.Debug("Error processing keypair, creating new keypair");
                GenerateNewKeypair();
                DarkLog.Debug("[Settings]: Backing up keypair");
                File.Copy(publicKeyFile, backupPublicKeyFile, true);
                File.Copy(privateKeyFile, backupPrivateKeyFile, true);
            }
        }
Example #8
0
        private void HandleWarpMessage(byte[] messageData)
        {
            using (MessageReader mr = new MessageReader(messageData))
            {
                WarpMessageType messageType = (WarpMessageType)mr.Read <int>();
                switch (messageType)
                {
                case WarpMessageType.REQUEST_VOTE:
                {
                    voteMaster = mr.Read <string>();
                    long expireTime = mr.Read <long>();
                    voteExpireTime = Client.realtimeSinceStartup + ((expireTime - timeSyncer.GetServerClock()) / 10000000d);
                }
                break;

                case WarpMessageType.REPLY_VOTE:
                {
                    int incomingVoteYesCount = mr.Read <int>();
                    int incomingVoteNoCount  = mr.Read <int>();
                    HandleReplyVote(incomingVoteYesCount, incomingVoteNoCount);
                }
                break;

                case WarpMessageType.SET_CONTROLLER:
                {
                    string newController = mr.Read <string>();
                    long   expireTime    = mr.Read <long>();
                    HandleSetController(newController, expireTime);
                }
                break;

                case WarpMessageType.CHANGE_WARP:
                {
                    string fromPlayer  = mr.Read <string>();
                    bool   isPhysWarp  = mr.Read <bool>();
                    int    rateIndex   = mr.Read <int>();
                    long   serverClock = mr.Read <long>();
                    double planetTime  = mr.Read <double>();
                    HandleChangeWarp(fromPlayer, isPhysWarp, rateIndex, serverClock, planetTime);
                }
                break;

                case WarpMessageType.NEW_SUBSPACE:
                {
                    int    newSubspaceID   = mr.Read <int>();
                    long   serverTime      = mr.Read <long>();
                    double planetariumTime = mr.Read <double>();
                    float  gameSpeed       = mr.Read <float>();
                    timeSyncer.AddNewSubspace(newSubspaceID, serverTime, planetariumTime, gameSpeed);
                }
                break;

                case WarpMessageType.CHANGE_SUBSPACE:
                {
                    string fromPlayer = mr.Read <string>();
                    if (fromPlayer != dmpSettings.playerName)
                    {
                        int changeSubspaceID = mr.Read <int>();
                        clientSubspaceList[fromPlayer] = changeSubspaceID;
                        if (changeSubspaceID != -1)
                        {
                            if (clientWarpList.ContainsKey(fromPlayer))
                            {
                                clientWarpList.Remove(fromPlayer);
                            }
                        }
                    }
                }
                break;

                case WarpMessageType.RELOCK_SUBSPACE:
                {
                    int    subspaceID      = mr.Read <int>();
                    long   serverTime      = mr.Read <long>();
                    double planetariumTime = mr.Read <double>();
                    float  gameSpeed       = mr.Read <float>();
                    timeSyncer.RelockSubspace(subspaceID, serverTime, planetariumTime, gameSpeed);
                }
                break;

                case WarpMessageType.REPORT_RATE:
                {
                    string fromPlayer = mr.Read <string>();
                    clientSkewList[fromPlayer] = mr.Read <float>();
                }
                break;

                default:
                {
                    DarkLog.Debug("Unhandled WARP_MESSAGE type: " + messageType);
                    break;
                }
                }
            }
        }
Example #9
0
        private void Update()
        {
            //Switch to new subspace if told to - this needs to be before the workerEnabled check as it fires during the initial sync
            if (newSetSubspace != -1)
            {
                DarkLog.Debug("Sent to subspace: " + newSetSubspace);
                timeSyncer.LockSubspace(newSetSubspace);
                newSetSubspace = -1;
            }

            if (!workerEnabled)
            {
                return;
            }

            //Reset warp if we need to
            CheckWarp();

            //Process new warp messages
            ProcessWarpMessages();

            //Write the screen message if needed
            if ((Client.realtimeSinceStartup - lastScreenMessageCheck) > SCREEN_MESSAGE_UPDATE_INTERVAL)
            {
                lastScreenMessageCheck = Client.realtimeSinceStartup;
                UpdateScreenMessage();
            }

            //Send a CHANGE_WARP message if needed
            if ((warpMode == WarpMode.MCW_FORCE) || (warpMode == WarpMode.MCW_VOTE) || (warpMode == WarpMode.SUBSPACE) || warpMode == WarpMode.SUBSPACE_SIMPLE)
            {
                if (!clientWarpList.ContainsKey(dmpSettings.playerName))
                {
                    clientWarpList[dmpSettings.playerName] = new PlayerWarpRate();
                }
                PlayerWarpRate ourRate = clientWarpList[dmpSettings.playerName];
                if ((ourRate.rateIndex != TimeWarp.CurrentRateIndex) || (ourRate.isPhysWarp != (TimeWarp.WarpMode == TimeWarp.Modes.LOW)))
                {
                    ourRate.isPhysWarp  = (TimeWarp.WarpMode == TimeWarp.Modes.LOW);
                    ourRate.rateIndex   = TimeWarp.CurrentRateIndex;
                    ourRate.serverClock = timeSyncer.GetServerClock();
                    ourRate.planetTime  = Planetarium.GetUniversalTime();
                    using (MessageWriter mw = new MessageWriter())
                    {
                        mw.Write <int>((int)WarpMessageType.CHANGE_WARP);
                        mw.Write <bool>(ourRate.isPhysWarp);
                        mw.Write <int>(ourRate.rateIndex);
                        mw.Write <long>(ourRate.serverClock);
                        mw.Write <double>(ourRate.planetTime);
                        networkWorker.SendWarpMessage(mw.GetMessageBytes());
                    }
                }
            }

            if ((Client.realtimeSinceStartup - lastWarpSet) > WARP_SET_THROTTLE)
            {
                //Follow the warp master into warp if needed (MCW_FORCE/MCW_VOTE)
                if (warpMode == WarpMode.MCW_FORCE || warpMode == WarpMode.MCW_VOTE)
                {
                    if ((warpMaster != "") && (warpMaster != dmpSettings.playerName))
                    {
                        if (clientWarpList.ContainsKey(warpMaster))
                        {
                            //Get master warp rate
                            PlayerWarpRate masterWarpRate = clientWarpList[warpMaster];
                            SetTimeFromWarpEntry(masterWarpRate);
                            lastWarpSet = Client.realtimeSinceStartup;
                        }
                        else
                        {
                            TimeWarp.SetRate(0, true);
                        }
                    }
                }

                if (warpMode == WarpMode.MCW_LOWEST)
                {
                    if ((warpMaster != "") && clientWarpList.ContainsKey(warpMaster))
                    {
                        //Get master warp rate
                        PlayerWarpRate masterWarpRate = clientWarpList[warpMaster];
                        SetTimeFromWarpEntry(masterWarpRate);
                        lastWarpSet = Client.realtimeSinceStartup;
                    }
                }
            }

            //Report our timeSyncer skew
            if ((Client.realtimeSinceStartup - lastReportRate) > REPORT_SKEW_RATE_INTERVAL && timeSyncer.locked)
            {
                lastReportRate = Client.realtimeSinceStartup;
                using (MessageWriter mw = new MessageWriter())
                {
                    mw.Write <int>((int)WarpMessageType.REPORT_RATE);
                    mw.Write <float>(timeSyncer.requestedRate);
                    networkWorker.SendWarpMessage(mw.GetMessageBytes());
                }
            }

            //Handle warp keys
            HandleInput();
        }
Example #10
0
        public void Start()
        {
            //Set buffered UDPMesh
            UDPMeshLib.UdpMeshCommon.USE_BUFFERS = true;
            //Set pool sizes for ByteRecycler
            ByteRecycler.AddPoolSize(SMALL_MESSAGE_SIZE);
            ByteRecycler.AddPoolSize(MEDIUM_MESSAGE_SIZE);
            ByteRecycler.AddPoolSize(LARGE_MESSAGE_SIZE);
            MessageWriter.RegisterType <ByteArray>(WriteByteArrayToStream);
            MessageReader.RegisterType <ByteArray>(ReadByteArrayFromStream);

            //Prevent loads if multiple copies of DMP are installed. KSP will instantate us twice.
            if (dmpClient != null)
            {
                warnDuplicateInstall = true;
                return;
            }

            if (!CompatibilityChecker.IsCompatible() || !InstallChecker.IsCorrectlyInstalled())
            {
                modDisabled = true;
                enabled     = false;
                return;
            }

            TimingManager.FixedUpdateAdd(TimingManager.TimingStage.BetterLateThanNever, TimingManagerFixedUpdate);
            dmpDir      = Path.Combine(Path.Combine(Path.Combine(KSPUtil.ApplicationRootPath, "GameData"), "DarkMultiPlayer"), "Plugins");
            dmpDataDir  = Path.Combine(dmpDir, "Data");
            gameDataDir = Path.Combine(KSPUtil.ApplicationRootPath, "GameData");
            kspRootPath = KSPUtil.ApplicationRootPath;

            //Fix DarkLog time/thread marker in the log during init.
            DarkLog.SetMainThread();
            lastClockTicks           = DateTime.UtcNow.Ticks;
            lastRealTimeSinceStartup = 0f;

            dmpClient = this;
            profiler  = new Profiler();
            kspTime   = profiler.GetCurrentTime;
            kspMemory = profiler.GetCurrentMemory;

            dmpSettings       = new Settings();
            toolbarSupport    = new ToolbarSupport(dmpSettings);
            universeSyncCache = new UniverseSyncCache(dmpSettings);
            modWindow         = new ModWindow();
            modWorker         = new ModWorker(modWindow);
            modWindow.SetDependenices(modWorker);
            universeConverter          = new UniverseConverter(dmpSettings);
            universeConverterWindow    = new UniverseConverterWindow(universeConverter);
            serverListDisclaimerWindow = new ServerListDisclaimerWindow(dmpSettings);
            optionsWindow        = new OptionsWindow(dmpSettings, universeSyncCache, modWorker, universeConverterWindow, toolbarSupport, serverListDisclaimerWindow);
            serverListConnection = new ServerListConnection(dmpSettings);
            serversWindow        = new ServersWindow(dmpSettings, optionsWindow, serverListConnection);
            serverListConnection.SetDependancy(serversWindow);
            connectionWindow = new ConnectionWindow(dmpSettings, optionsWindow, serversWindow, serverListDisclaimerWindow);
            disclaimerWindow = new DisclaimerWindow(dmpSettings);
            dmpModInterface  = new DMPModInterface();
            //SafetyBubble.RegisterDefaultLocations();


            if (dmpSettings.disclaimerAccepted != 1)
            {
                modDisabled = true;
                disclaimerWindow.SpawnDialog();
            }

            Application.wantsToQuit += WantsToQuit;
            DontDestroyOnLoad(this);

            // Prevents symlink warning for development.
            SetupDirectoriesIfNeeded();

            // UniverseSyncCache needs to run expiry here
            universeSyncCache.ExpireCache();

            GameEvents.onHideUI.Add(() =>
            {
                showGUI = false;
            });
            GameEvents.onShowUI.Add(() =>
            {
                showGUI = true;
            });

            HandleCommandLineArgs();
            DarkLog.Debug("DarkMultiPlayer " + Common.PROGRAM_VERSION + ", protocol " + Common.PROTOCOL_VERSION + " Initialized!");
        }
Example #11
0
 private void FixedUpdate()
 {
     if (workerEnabled)
     {
         if (scenarioController == null)
         {
             foreach (ProtoScenarioModule psm in HighLogic.CurrentGame.scenarios)
             {
                 if (psm != null)
                 {
                     if (psm.moduleName == "ScenarioDiscoverableObjects")
                     {
                         if (psm.moduleRef != null)
                         {
                             DarkLog.Debug("Found reference to asteroid spawner");
                             scenarioController = (ScenarioDiscoverableObjects)psm.moduleRef;
                             scenarioController.spawnInterval = float.MaxValue;
                         }
                     }
                 }
             }
         }
     }
     if (workerEnabled && scenarioController != null)
     {
         if ((UnityEngine.Time.realtimeSinceStartup - lastAsteroidCheck) > ASTEROID_CHECK_INTERVAL)
         {
             List <Vessel> asteroidList = GetAsteroidList();
             lastAsteroidCheck = UnityEngine.Time.realtimeSinceStartup;
             //Try to acquire the asteroid-spawning lock if nobody else has it.
             if (!LockSystem.fetch.LockExists("asteroid-spawning"))
             {
                 LockSystem.fetch.AcquireLock("asteroid-spawning", false);
             }
             //We have the spawn lock, lets do stuff.
             if (LockSystem.fetch.LockIsOurs("asteroid-spawning"))
             {
                 if (FlightGlobals.fetch.vessels != null ? FlightGlobals.fetch.vessels.Count > 0 : false)
                 {
                     lock (serverAsteroidListLock)
                     {
                         if (asteroidList.Count < maxNumberOfUntrackedAsteroids)
                         {
                             DarkLog.Debug("Spawning asteroid, have " + asteroidList.Count + ", need " + maxNumberOfUntrackedAsteroids);
                             scenarioController.SpawnAsteroid();
                         }
                         foreach (Vessel asteroid in asteroidList)
                         {
                             if (!serverAsteroids.Contains(asteroid.id.ToString()))
                             {
                                 DarkLog.Debug("Spawned in new server asteroid!");
                                 serverAsteroids.Add(asteroid.id.ToString());
                                 VesselWorker.fetch.RegisterServerVessel(asteroid.id.ToString());
                                 NetworkWorker.fetch.SendVesselProtoMessage(asteroid.protoVessel, false);
                             }
                         }
                     }
                 }
             }
             //Check for changes to tracking
             foreach (Vessel asteroid in asteroidList)
             {
                 if (!serverAsteroidTrackStatus.ContainsKey(asteroid.id.ToString()))
                 {
                     serverAsteroidTrackStatus.Add(asteroid.id.ToString(), asteroid.DiscoveryInfo.trackingStatus.Value);
                 }
                 else
                 {
                     if (asteroid.DiscoveryInfo.trackingStatus.Value != serverAsteroidTrackStatus[asteroid.id.ToString()])
                     {
                         DarkLog.Debug("Sending changed asteroid, new state: " + asteroid.DiscoveryInfo.trackingStatus.Value + "!");
                         serverAsteroidTrackStatus[asteroid.id.ToString()] = asteroid.DiscoveryInfo.trackingStatus.Value;
                         NetworkWorker.fetch.SendVesselProtoMessage(asteroid.protoVessel, false);
                     }
                 }
             }
         }
     }
 }
Example #12
0
        public void OnGUI()
        {
            profiler.Report("KSP", kspTime, kspMemory);
            long profilerStartTime   = profiler.GetCurrentTime;
            long profilerStartMemory = profiler.GetCurrentMemory;

            //Window ID's - Doesn't include "random" offset.
            //Connection window: 6702
            //Status window: 6703
            //Chat window: 6704
            //Debug window: 6705
            //Mod windw: 6706
            //Craft library window: 6707
            //Craft upload window: 6708
            //Screenshot window: 6710
            //Options window: 6711
            //Converter window: 6712
            //Disclaimer window: 6713
            if (showGUI)
            {
                if (connectionWindow != null)
                {
                    connectionWindow.Draw();
                }
                if (modWindow != null)
                {
                    modWindow.Draw();
                }
                if (optionsWindow != null)
                {
                    optionsWindow.Draw();
                }
                if (serversWindow != null)
                {
                    serversWindow.Draw();
                }
                if (universeConverterWindow != null)
                {
                    universeConverterWindow.Draw();
                }
                if (dmpGame != null)
                {
                    foreach (NamedAction drawAction in dmpGame.drawEvent)
                    {
#if !DEBUG
                        try
                        {
#endif
                        // Don't hide the connectionWindow if we disabled DMP GUI
                        if (toolbarShowGUI || (!toolbarShowGUI && drawAction.name == "DarkMultiPlayer.ConnectionWindow.Draw"))
                        {
                            drawAction.action();
                        }
#if !DEBUG
                    }
                    catch (Exception e)
                    {
                        DarkLog.Debug("Threw in OnGUI event, exception: " + e);
                    }
#endif
                    }
                }
            }
            profiler.Report("Draw", profilerStartTime, profilerStartMemory);
            kspTime   = profiler.GetCurrentTime;
            kspMemory = profiler.GetCurrentMemory;
        }
Example #13
0
        public void Update()
        {
            profiler.Report("KSP", kspTime, kspMemory);
            DarkLog.Update();
            ByteRecycler.GarbageCollect(50, 100);
            Recycler <VesselUpdate> .GarbageCollect(50, 100);

            long profilerStartTime   = profiler.GetCurrentTime;
            long profilerStartMemory = profiler.GetCurrentMemory;

            lastClockTicks           = DateTime.UtcNow.Ticks;
            lastRealTimeSinceStartup = Time.realtimeSinceStartup;
            if (warnDuplicateInstall && HighLogic.LoadedScene == GameScenes.MAINMENU)
            {
                warnDuplicateInstall = false;
                string message = "Please remove the duplicate install of DarkMultiPlayer.";
                PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), "InstallChecker", "Incorrect Install Detected", message, "OK", true, HighLogic.UISkin);
            }
            if (modDisabled)
            {
                return;
            }
            try
            {
                if (HighLogic.LoadedScene == GameScenes.MAINMENU)
                {
                    if (!dmpSaveChecked)
                    {
                        dmpSaveChecked = true;
                        SetupBlankGameIfNeeded();
                    }
                }

                if (HighLogic.LoadedScene == GameScenes.SPACECENTER && PSystemSetup.Instance != null && Time.timeSinceLevelLoad > 1f)
                {
                    if (PSystemSetup.Instance.SpaceCenterFacilities.Length != facilitiesAdded)
                    {
                        facilitiesAdded = PSystemSetup.Instance.SpaceCenterFacilities.Length;
                        foreach (PSystemSetup.SpaceCenterFacility spaceCenterFacility in PSystemSetup.Instance.SpaceCenterFacilities)
                        {
                            foreach (PSystemSetup.SpaceCenterFacility.SpawnPoint spawnPoint in spaceCenterFacility.spawnPoints)
                            {
                                if (spawnPoint.latitude != 0 && spawnPoint.longitude != 0 && spawnPoint.altitude != 0)
                                {
                                    DarkLog.Debug("Adding facility spawn point: " + spaceCenterFacility.name + ":" + spawnPoint.name);
                                    SafetyBubble.RegisterLocation(spawnPoint.latitude, spawnPoint.longitude, spawnPoint.altitude, spaceCenterFacility.hostBody.name);
                                    DarkLog.Debug("LLA: [" + spawnPoint.latitude + ", " + spawnPoint.longitude + ", " + spawnPoint.altitude + "]");
                                }
                            }
                        }
                    }
                    if (PSystemSetup.Instance.LaunchSites.Count != modSitesAdded)
                    {
                        modSitesAdded = PSystemSetup.Instance.LaunchSites.Count;
                        foreach (LaunchSite launchSite in PSystemSetup.Instance.LaunchSites)
                        {
                            foreach (LaunchSite.SpawnPoint spawnPoint in launchSite.spawnPoints)
                            {
                                if (spawnPoint.latitude != 0 && spawnPoint.longitude != 0 && spawnPoint.altitude != 0)
                                {
                                    DarkLog.Debug("Adding mod spawn point: " + launchSite.name + ":" + spawnPoint.name);
                                    SafetyBubble.RegisterLocation(spawnPoint.latitude, spawnPoint.longitude, spawnPoint.altitude, launchSite.Body.name);
                                    DarkLog.Debug("LLA: [" + spawnPoint.latitude + ", " + spawnPoint.longitude + ", " + spawnPoint.altitude + "]");
                                }
                            }
                        }
                    }
                    if (PSystemSetup.Instance.StockLaunchSites.Length != stockSitesAdded)
                    {
                        stockSitesAdded = PSystemSetup.Instance.StockLaunchSites.Length;
                        foreach (LaunchSite launchSite in PSystemSetup.Instance.StockLaunchSites)
                        {
                            foreach (LaunchSite.SpawnPoint spawnPoint in launchSite.spawnPoints)
                            {
                                if (spawnPoint.latitude != 0 && spawnPoint.longitude != 0 && spawnPoint.altitude != 0)
                                {
                                    DarkLog.Debug("Adding stock spawn point: " + launchSite.name + ":" + spawnPoint.name);
                                    SafetyBubble.RegisterLocation(spawnPoint.latitude, spawnPoint.longitude, spawnPoint.altitude, launchSite.Body.name);
                                    DarkLog.Debug("LLA: [" + spawnPoint.latitude + ", " + spawnPoint.longitude + ", " + spawnPoint.altitude + "]");
                                }
                            }
                        }
                    }
                }



                //Handle GUI events

                if (!connectionWindow.renameEventHandled)
                {
                    dmpSettings.SaveSettings();
                    connectionWindow.renameEventHandled = true;
                }
                if (!connectionWindow.addEventHandled)
                {
                    dmpSettings.servers.Add(connectionWindow.addEntry);
                    connectionWindow.addEntry = null;
                    dmpSettings.SaveSettings();
                    connectionWindow.addingServer    = false;
                    connectionWindow.addEventHandled = true;
                }
                if (!connectionWindow.editEventHandled)
                {
                    dmpSettings.servers[connectionWindow.selected].name    = connectionWindow.editEntry.name;
                    dmpSettings.servers[connectionWindow.selected].address = connectionWindow.editEntry.address;
                    dmpSettings.servers[connectionWindow.selected].port    = connectionWindow.editEntry.port;
                    connectionWindow.editEntry = null;
                    dmpSettings.SaveSettings();
                    connectionWindow.addingServer     = false;
                    connectionWindow.editEventHandled = true;
                }
                if (!connectionWindow.removeEventHandled)
                {
                    dmpSettings.servers.RemoveAt(connectionWindow.selected);
                    connectionWindow.selected = -1;
                    dmpSettings.SaveSettings();
                    connectionWindow.removeEventHandled = true;
                }
                if (!connectionWindow.connectEventHandled)
                {
                    connectionWindow.connectEventHandled = true;
                    ConnectToServer(dmpSettings.servers[connectionWindow.selected].address, dmpSettings.servers[connectionWindow.selected].port);
                }
                if (commandLineConnect != null && HighLogic.LoadedScene == GameScenes.MAINMENU && Time.timeSinceLevelLoad > 1f)
                {
                    ConnectToServer(commandLineConnect.address, commandLineConnect.port);
                    commandLineConnect = null;
                }

                if (!connectionWindow.disconnectEventHandled)
                {
                    connectionWindow.disconnectEventHandled = true;
                    if (dmpGame != null)
                    {
                        if (dmpGame.networkWorker.state == ClientState.CONNECTING)
                        {
                            dmpGame.networkWorker.Disconnect("Cancelled connection to server");
                        }
                        else
                        {
                            dmpGame.networkWorker.SendDisconnect("Quit during initial sync");
                        }
                        dmpGame.Stop();
                        dmpGame = null;
                    }
                }

                connectionWindow.Update();
                serverListConnection.Update();
                serversWindow.Update();
                modWindow.Update();
                optionsWindow.Update();
                universeConverterWindow.Update();
                profiler.Update();
                dmpModInterface.Update();

                if (dmpGame != null)
                {
                    foreach (NamedAction updateAction in dmpGame.updateEvent)
                    {
#if !DEBUG
                        try
                        {
#endif
                        long profilerUpdateStartTime   = profiler.GetCurrentTime;
                        long profilerUpdateStartMemory = profiler.GetCurrentMemory;
                        updateAction.action();
                        profiler.Report(updateAction.name, profilerUpdateStartTime, profilerUpdateStartMemory);
#if !DEBUG
                    }
                    catch (Exception e)
                    {
                        DarkLog.Debug("Threw in UpdateEvent, exception: " + e);
                        if (dmpGame.networkWorker.state != ClientState.RUNNING)
                        {
                            if (dmpGame.networkWorker.state != ClientState.DISCONNECTED)
                            {
                                dmpGame.networkWorker.SendDisconnect("Unhandled error while syncing!");
                            }
                            else
                            {
                                dmpGame.networkWorker.Disconnect("Unhandled error while syncing!");
                            }
                        }
                    }
#endif
                    }
                }
                //Force quit
                if (dmpGame != null && dmpGame.forceQuit)
                {
                    dmpGame.forceQuit = false;
                    dmpGame.Stop();
                    dmpGame = null;
                    StopGame();
                }


                if (displayDisconnectMessage)
                {
                    if (HighLogic.LoadedScene != GameScenes.MAINMENU)
                    {
                        if ((Client.realtimeSinceStartup - lastDisconnectMessageCheck) > 1f)
                        {
                            lastDisconnectMessageCheck = Client.realtimeSinceStartup;
                            if (disconnectMessage != null)
                            {
                                disconnectMessage.duration = 0;
                            }
                            disconnectMessage = ScreenMessages.PostScreenMessage("You have been disconnected!", 2f, ScreenMessageStyle.UPPER_CENTER);
                        }
                    }
                    else
                    {
                        displayDisconnectMessage = false;
                    }
                }

                //Normal quit
                if (dmpGame != null && dmpGame.running)
                {
                    if (!dmpGame.playerStatusWindow.disconnectEventHandled)
                    {
                        dmpGame.playerStatusWindow.disconnectEventHandled = true;
                        dmpGame.forceQuit = true;
                        dmpGame.scenarioWorker.SendScenarioModules(true); // Send scenario modules before disconnecting
                        dmpGame.networkWorker.SendDisconnect("Quit");
                    }

                    if (dmpGame.screenshotWorker.uploadScreenshot)
                    {
                        dmpGame.screenshotWorker.uploadScreenshot = false;
                        StartCoroutine(UploadScreenshot());
                    }

                    if (HighLogic.CurrentGame.flagURL != dmpSettings.selectedFlag)
                    {
                        DarkLog.Debug("Saving selected flag");
                        dmpSettings.selectedFlag = HighLogic.CurrentGame.flagURL;
                        dmpSettings.SaveSettings();
                        dmpGame.flagSyncer.flagChangeEvent = true;
                    }

                    // save every GeeASL from each body in FlightGlobals
                    if (HighLogic.LoadedScene == GameScenes.FLIGHT && bodiesGees.Count == 0)
                    {
                        foreach (CelestialBody body in FlightGlobals.fetch.bodies)
                        {
                            bodiesGees.Add(body, body.GeeASL);
                        }
                    }

                    //handle use of cheats
                    if (!dmpGame.serverAllowCheats)
                    {
                        CheatOptions.InfinitePropellant             = false;
                        CheatOptions.NoCrashDamage                  = false;
                        CheatOptions.IgnoreAgencyMindsetOnContracts = false;
                        CheatOptions.IgnoreMaxTemperature           = false;
                        CheatOptions.InfiniteElectricity            = false;
                        CheatOptions.NoCrashDamage                  = false;
                        CheatOptions.UnbreakableJoints              = false;

                        foreach (KeyValuePair <CelestialBody, double> gravityEntry in bodiesGees)
                        {
                            gravityEntry.Key.GeeASL = gravityEntry.Value;
                        }
                    }

                    if (HighLogic.LoadedScene == GameScenes.FLIGHT && FlightGlobals.ready)
                    {
                        HighLogic.CurrentGame.Parameters.Flight.CanLeaveToSpaceCenter = !dmpGame.vesselWorker.isSpectating && dmpSettings.revertEnabled || (PauseMenu.canSaveAndExit == ClearToSaveStatus.CLEAR);
                    }
                    else
                    {
                        HighLogic.CurrentGame.Parameters.Flight.CanLeaveToSpaceCenter = true;
                    }

                    if (HighLogic.LoadedScene == GameScenes.MAINMENU)
                    {
                        dmpGame.networkWorker.SendDisconnect("Quit to main menu");
                        dmpGame.Stop();
                        dmpGame = null;
                    }
                }

                if (dmpGame != null && dmpGame.startGame)
                {
                    dmpGame.startGame = false;
                    StartGame();
                }
            }
            catch (Exception e)
            {
                if (dmpGame != null)
                {
                    DarkLog.Debug("Threw in Update, state " + dmpGame.networkWorker.state.ToString() + ", exception: " + e);
                    if (dmpGame.networkWorker.state != ClientState.RUNNING)
                    {
                        if (dmpGame.networkWorker.state != ClientState.DISCONNECTED)
                        {
                            dmpGame.networkWorker.SendDisconnect("Unhandled error while syncing!");
                        }
                        else
                        {
                            dmpGame.networkWorker.Disconnect("Unhandled error while syncing!");
                        }
                    }
                }
                else
                {
                    DarkLog.Debug("Threw in Update, state NO_NETWORKWORKER, exception: " + e);
                }
            }
            DarkLog.Update();
            profiler.Report("Update", profilerStartTime, profilerStartMemory);
            kspTime   = profiler.GetCurrentTime;
            kspMemory = profiler.GetCurrentMemory;
        }
Example #14
0
        public void HandleChatInput(string input)
        {
            if (!input.StartsWith("/") || input.StartsWith("//"))
            {
                //Handle chat messages
                if (input.StartsWith("//"))
                {
                    input = input.Substring(1);
                }

                if (selectedChannel == null && selectedPMChannel == null)
                {
                    //Sending a global chat message
                    using (MessageWriter mw = new MessageWriter())
                    {
                        mw.Write <int>((int)ChatMessageType.CHANNEL_MESSAGE);
                        mw.Write <string>(dmpSettings.playerName);
                        //Global channel name is empty string.
                        mw.Write <string>("");
                        mw.Write <string>(input);
                        networkWorker.SendChatMessage(mw.GetMessageBytes());
                    }
                }
                if (selectedChannel != null && selectedChannel != consoleIdentifier)
                {
                    using (MessageWriter mw = new MessageWriter())
                    {
                        mw.Write <int>((int)ChatMessageType.CHANNEL_MESSAGE);
                        mw.Write <string>(dmpSettings.playerName);
                        mw.Write <string>(selectedChannel);
                        mw.Write <string>(input);
                        networkWorker.SendChatMessage(mw.GetMessageBytes());
                    }
                }
                if (selectedChannel == consoleIdentifier)
                {
                    using (MessageWriter mw = new MessageWriter())
                    {
                        mw.Write <int>((int)ChatMessageType.CONSOLE_MESSAGE);
                        mw.Write <string>(dmpSettings.playerName);
                        mw.Write <string>(input);
                        networkWorker.SendChatMessage(mw.GetMessageBytes());
                        DarkLog.Debug("Server Command: " + input);
                    }
                }
                if (selectedPMChannel != null)
                {
                    using (MessageWriter mw = new MessageWriter())
                    {
                        mw.Write <int>((int)ChatMessageType.PRIVATE_MESSAGE);
                        mw.Write <string>(dmpSettings.playerName);
                        mw.Write <string>(selectedPMChannel);
                        mw.Write <string>(input);
                        networkWorker.SendChatMessage(mw.GetMessageBytes());
                    }
                }
            }
            else
            {
                string commandPart  = input.Substring(1);
                string argumentPart = "";
                if (commandPart.Contains(" "))
                {
                    if (commandPart.Length > commandPart.IndexOf(' ') + 1)
                    {
                        argumentPart = commandPart.Substring(commandPart.IndexOf(' ') + 1);
                    }
                    commandPart = commandPart.Substring(0, commandPart.IndexOf(' '));
                }
                if (commandPart.Length > 0)
                {
                    if (registeredChatCommands.ContainsKey(commandPart))
                    {
                        try
                        {
                            DarkLog.Debug("Chat Command: " + input.Substring(1));
                            registeredChatCommands[commandPart].func(argumentPart);
                        }
                        catch (Exception e)
                        {
                            DarkLog.Debug("Error handling chat command " + commandPart + ", Exception " + e);
                            PrintToSelectedChannel("Error handling chat command: " + commandPart);
                        }
                    }
                    else
                    {
                        PrintToSelectedChannel("Unknown chat command: " + commandPart);
                    }
                }
            }
        }
        private void Update()
        {
            safeDisplay = display;

            if (workerEnabled)
            {
                while (newScreenshotNotifiyQueue.Count > 0)
                {
                    string notifyPlayer = newScreenshotNotifiyQueue.Dequeue();
                    if (!display)
                    {
                        screenshotButtonHighlighted = true;
                    }
                    if (selectedPlayer != notifyPlayer)
                    {
                        if (!highlightedPlayers.Contains(notifyPlayer))
                        {
                            highlightedPlayers.Add(notifyPlayer);
                        }
                    }
                    ChatWorker.fetch.QueueChannelMessage("Server", "", notifyPlayer + " shared screenshot");
                }

                //Update highlights
                if (screenshotButtonHighlighted && display)
                {
                    screenshotButtonHighlighted = false;
                }

                if (highlightedPlayers.Contains(selectedPlayer))
                {
                    highlightedPlayers.Remove(selectedPlayer);
                }


                while (newScreenshotQueue.Count > 0)
                {
                    ScreenshotEntry se = newScreenshotQueue.Dequeue();
                    Texture2D       screenshotTexture = new Texture2D(4, 4, TextureFormat.RGB24, false, true);
                    if (screenshotTexture.LoadImage(se.screenshotData))
                    {
                        screenshotTexture.Apply();
                        //Make sure screenshots aren't bigger than 2/3rds of the screen.
                        ResizeTextureIfNeeded(ref screenshotTexture);
                        //Save the texture in memory
                        screenshots[se.fromPlayer] = screenshotTexture;
                        DarkLog.Debug("Loaded screenshot from " + se.fromPlayer);
                    }
                    else
                    {
                        DarkLog.Debug("Error loading screenshot from " + se.fromPlayer);
                    }
                }

                while (newScreenshotWatchQueue.Count > 0)
                {
                    ScreenshotWatchEntry swe = newScreenshotWatchQueue.Dequeue();
                    if (swe.watchPlayer != "")
                    {
                        watchPlayers[swe.fromPlayer] = swe.watchPlayer;
                    }
                    else
                    {
                        if (watchPlayers.ContainsKey(swe.fromPlayer))
                        {
                            watchPlayers.Remove(swe.fromPlayer);
                        }
                    }
                }

                if (safeSelectedPlayer != selectedPlayer)
                {
                    windowRect.height  = 0;
                    windowRect.width   = 0;
                    safeSelectedPlayer = selectedPlayer;
                    WatchPlayer(selectedPlayer);
                }

                if (Input.GetKey(Settings.fetch.screenshotKey))
                {
                    uploadEventHandled = false;
                }

                if (!uploadEventHandled)
                {
                    uploadEventHandled = true;
                    if ((UnityEngine.Time.realtimeSinceStartup - lastScreenshotSend) > MIN_SCREENSHOT_SEND_INTERVAL)
                    {
                        lastScreenshotSend                = UnityEngine.Time.realtimeSinceStartup;
                        screenshotTaken                   = false;
                        finishedUploadingScreenshot       = false;
                        uploadScreenshot                  = true;
                        displayScreenshotUploadingMessage = true;
                    }
                }

                if ((UnityEngine.Time.realtimeSinceStartup - lastScreenshotMessageCheck) > SCREENSHOT_MESSAGE_CHECK_INTERVAL)
                {
                    if (screenshotTaken && displayScreenshotUploadingMessage)
                    {
                        lastScreenshotMessageCheck = UnityEngine.Time.realtimeSinceStartup;
                        if (screenshotUploadMessage != null)
                        {
                            screenshotUploadMessage.duration = 0f;
                        }
                        if (finishedUploadingScreenshot)
                        {
                            displayScreenshotUploadingMessage = false;
                            screenshotUploadMessage           = ScreenMessages.PostScreenMessage("Screenshot uploaded!", 2f, ScreenMessageStyle.UPPER_CENTER);
                        }
                        else
                        {
                            screenshotUploadMessage = ScreenMessages.PostScreenMessage("Uploading screenshot...", 1f, ScreenMessageStyle.UPPER_CENTER);
                        }
                    }

                    if (downloadingScreenshotFromPlayer != null)
                    {
                        if (screenshotDownloadMessage != null)
                        {
                            screenshotDownloadMessage.duration = 0f;
                        }
                        screenshotDownloadMessage = ScreenMessages.PostScreenMessage("Downloading screenshot...", 1f, ScreenMessageStyle.UPPER_CENTER);
                    }
                }

                if (downloadingScreenshotFromPlayer == null && screenshotDownloadMessage != null)
                {
                    screenshotDownloadMessage.duration = 0f;
                    screenshotDownloadMessage          = null;
                }
            }
        }
Example #16
0
 private void HandleMCWVoteInput(bool startWarpKey, bool stopWarpKey)
 {
     if (warpMaster == "")
     {
         if (voteMaster == "")
         {
             if (startWarpKey)
             {
                 if (PlayerStatusWorker.fetch.playerStatusList.Count > 0)
                 {
                     //Start a warp vote
                     using (MessageWriter mw = new MessageWriter())
                     {
                         mw.Write <int>((int)WarpMessageType.REQUEST_VOTE);
                         mw.Write <string>(Settings.fetch.playerName);
                         NetworkWorker.fetch.SendWarpMessage(mw.GetMessageBytes());
                     }
                     voteMaster = Settings.fetch.playerName;
                     //To win:
                     //1 other clients = 1 vote needed.
                     //2 other clients = 1 vote needed.
                     //3 other clients = 2 votes neeed.
                     //4 other clients = 2 votes neeed.
                     //5 other clients = 3 votes neeed.
                     //To fail:
                     //1 other clients = 1 vote needed.
                     //2 other clients = 2 vote needed.
                     //3 other clients = 2 votes neeed.
                     //4 other clients = 3 votes neeed.
                     //5 other clients = 3 votes neeed.
                     voteNeededCount = (PlayerStatusWorker.fetch.playerStatusList.Count + 1) / 2;
                     voteFailedCount = voteNeededCount + (1 - (voteNeededCount % 2));
                     DarkLog.Debug("Started warp vote");
                 }
                 else
                 {
                     //Nobody else is online, Let's just take the warp master.
                     warpMasterOwnerTime = UnityEngine.Time.realtimeSinceStartup;
                     warpMaster          = Settings.fetch.playerName;
                     using (MessageWriter mw = new MessageWriter())
                     {
                         mw.Write <int>((int)WarpMessageType.SET_CONTROLLER);
                         mw.Write <string>(Settings.fetch.playerName);
                         mw.Write <string>(Settings.fetch.playerName);
                         NetworkWorker.fetch.SendWarpMessage(mw.GetMessageBytes());
                     }
                 }
             }
         }
         else
         {
             if (voteMaster != Settings.fetch.playerName)
             {
                 //Send a vote if we haven't voted yet
                 if (!voteSent)
                 {
                     using (MessageWriter mw = new MessageWriter())
                     {
                         mw.Write <int>((int)WarpMessageType.REPLY_VOTE);
                         mw.Write <string>(Settings.fetch.playerName);
                         mw.Write <bool>(startWarpKey);
                         NetworkWorker.fetch.SendWarpMessage(mw.GetMessageBytes());
                         voteSent = true;
                     }
                     DarkLog.Debug("Send warp reply with vote of " + startWarpKey);
                 }
             }
             else
             {
                 if (stopWarpKey)
                 {
                     //Cancel our vote
                     ReleaseWarpMaster();
                     DisplayMessage("Cancelled vote!", 2f);
                     DarkLog.Debug("Cancelled warp vote");
                 }
             }
         }
     }
     else
     {
         if (warpMaster == Settings.fetch.playerName)
         {
             if (stopWarpKey && (TimeWarp.CurrentRate < 1.1f))
             {
                 //Release control of the warp master instead of waiting for the timeout
                 ReleaseWarpMaster();
             }
         }
     }
 }
Example #17
0
        public void Update()
        {
            long startClock = Profiler.DMPReferenceTime.ElapsedTicks;

            DarkLog.Update();
            if (modDisabled)
            {
                return;
            }
            try
            {
                if (HighLogic.LoadedScene == GameScenes.MAINMENU)
                {
                    if (!ModWorker.fetch.dllListBuilt)
                    {
                        ModWorker.fetch.dllListBuilt = true;
                        ModWorker.fetch.BuildDllFileList();
                    }
                    if (!dmpSaveChecked)
                    {
                        dmpSaveChecked = true;
                        SetupBlankGameIfNeeded();
                    }
                }

                //Handle GUI events
                if (!PlayerStatusWindow.fetch.disconnectEventHandled)
                {
                    PlayerStatusWindow.fetch.disconnectEventHandled = true;
                    forceQuit = true;
                    NetworkWorker.fetch.SendDisconnect("Quit");
                }
                if (!ConnectionWindow.fetch.renameEventHandled)
                {
                    PlayerStatusWorker.fetch.myPlayerStatus.playerName = Settings.fetch.playerName;
                    Settings.fetch.SaveSettings();
                    ConnectionWindow.fetch.renameEventHandled = true;
                }
                if (!ConnectionWindow.fetch.addEventHandled)
                {
                    Settings.fetch.servers.Add(ConnectionWindow.fetch.addEntry);
                    ConnectionWindow.fetch.addEntry = null;
                    Settings.fetch.SaveSettings();
                    ConnectionWindow.fetch.addingServer    = false;
                    ConnectionWindow.fetch.addEventHandled = true;
                }
                if (!ConnectionWindow.fetch.editEventHandled)
                {
                    Settings.fetch.servers[ConnectionWindow.fetch.selected].name    = ConnectionWindow.fetch.editEntry.name;
                    Settings.fetch.servers[ConnectionWindow.fetch.selected].address = ConnectionWindow.fetch.editEntry.address;
                    Settings.fetch.servers[ConnectionWindow.fetch.selected].port    = ConnectionWindow.fetch.editEntry.port;
                    ConnectionWindow.fetch.editEntry = null;
                    Settings.fetch.SaveSettings();
                    ConnectionWindow.fetch.addingServer     = false;
                    ConnectionWindow.fetch.editEventHandled = true;
                }
                if (!ConnectionWindow.fetch.removeEventHandled)
                {
                    Settings.fetch.servers.RemoveAt(ConnectionWindow.fetch.selected);
                    ConnectionWindow.fetch.selected = -1;
                    Settings.fetch.SaveSettings();
                    ConnectionWindow.fetch.removeEventHandled = true;
                }
                if (!ConnectionWindow.fetch.connectEventHandled)
                {
                    ConnectionWindow.fetch.connectEventHandled = true;
                    NetworkWorker.fetch.ConnectToServer(Settings.fetch.servers[ConnectionWindow.fetch.selected].address, Settings.fetch.servers[ConnectionWindow.fetch.selected].port);
                }
                if (commandLineConnect != null && HighLogic.LoadedScene == GameScenes.MAINMENU && Time.timeSinceLevelLoad > 1f)
                {
                    NetworkWorker.fetch.ConnectToServer(commandLineConnect.address, commandLineConnect.port);
                    commandLineConnect = null;
                }

                if (!ConnectionWindow.fetch.disconnectEventHandled)
                {
                    ConnectionWindow.fetch.disconnectEventHandled = true;
                    gameRunning = false;
                    fireReset   = true;
                    if (NetworkWorker.fetch.state == ClientState.CONNECTING)
                    {
                        NetworkWorker.fetch.Disconnect("Cancelled connection to server");
                    }
                    else
                    {
                        NetworkWorker.fetch.SendDisconnect("Quit during initial sync");
                    }
                }

                foreach (Action updateAction in updateEvent)
                {
                    try
                    {
                        updateAction();
                    }
                    catch (Exception e)
                    {
                        DarkLog.Debug("Threw in UpdateEvent, exception: " + e);
                        if (NetworkWorker.fetch.state != ClientState.RUNNING)
                        {
                            if (NetworkWorker.fetch.state != ClientState.DISCONNECTED)
                            {
                                NetworkWorker.fetch.SendDisconnect("Unhandled error while syncing!");
                            }
                            else
                            {
                                NetworkWorker.fetch.Disconnect("Unhandled error while syncing!");
                            }
                        }
                    }
                }
                //Force quit
                if (forceQuit)
                {
                    forceQuit   = false;
                    gameRunning = false;
                    fireReset   = true;
                    StopGame();
                }

                if (displayDisconnectMessage)
                {
                    if (HighLogic.LoadedScene != GameScenes.MAINMENU)
                    {
                        if ((UnityEngine.Time.realtimeSinceStartup - lastDisconnectMessageCheck) > 1f)
                        {
                            lastDisconnectMessageCheck = UnityEngine.Time.realtimeSinceStartup;
                            if (disconnectMessage != null)
                            {
                                disconnectMessage.duration = 0;
                            }
                            disconnectMessage = ScreenMessages.PostScreenMessage("You have been disconnected!", 2f, ScreenMessageStyle.UPPER_CENTER);
                        }
                    }
                    else
                    {
                        displayDisconnectMessage = false;
                    }
                }

                //Normal quit
                if (gameRunning)
                {
                    if (HighLogic.LoadedScene == GameScenes.MAINMENU)
                    {
                        gameRunning = false;
                        fireReset   = true;
                        NetworkWorker.fetch.SendDisconnect("Quit to main menu");
                    }

                    if (ScreenshotWorker.fetch.uploadScreenshot)
                    {
                        ScreenshotWorker.fetch.uploadScreenshot = false;
                        StartCoroutine(UploadScreenshot());
                    }

                    if (HighLogic.CurrentGame.flagURL != Settings.fetch.selectedFlag)
                    {
                        DarkLog.Debug("Saving selected flag");
                        Settings.fetch.selectedFlag = HighLogic.CurrentGame.flagURL;
                        Settings.fetch.SaveSettings();
                        FlagSyncer.fetch.flagChangeEvent = true;
                    }

                    // save every GeeASL from each body in FlightGlobals
                    if (HighLogic.LoadedScene == GameScenes.FLIGHT && bodiesGees.Count == 0)
                    {
                        foreach (CelestialBody body in FlightGlobals.fetch.bodies)
                        {
                            bodiesGees.Add(body, body.GeeASL);
                        }
                    }

                    //handle use of cheats
                    if (!serverAllowCheats)
                    {
                        CheatOptions.InfiniteFuel    = false;
                        CheatOptions.InfiniteEVAFuel = false;
                        CheatOptions.InfiniteRCS     = false;
                        CheatOptions.NoCrashDamage   = false;

                        foreach (KeyValuePair <CelestialBody, double> gravityEntry in bodiesGees)
                        {
                            gravityEntry.Key.GeeASL = gravityEntry.Value;
                        }
                    }

                    if (HighLogic.LoadedScene == GameScenes.FLIGHT && FlightGlobals.ready)
                    {
                        HighLogic.CurrentGame.Parameters.Flight.CanLeaveToSpaceCenter = Settings.fetch.revertEnabled || (PauseMenu.canSaveAndExit == ClearToSaveStatus.CLEAR);
                    }
                    else
                    {
                        HighLogic.CurrentGame.Parameters.Flight.CanLeaveToSpaceCenter = true;
                    }
                }

                if (fireReset)
                {
                    fireReset = false;
                    FireResetEvent();
                }

                if (startGame)
                {
                    startGame = false;
                    StartGame();
                }
            }
            catch (Exception e)
            {
                DarkLog.Debug("Threw in Update, state " + NetworkWorker.fetch.state.ToString() + ", exception" + e);
                if (NetworkWorker.fetch.state != ClientState.RUNNING)
                {
                    if (NetworkWorker.fetch.state != ClientState.DISCONNECTED)
                    {
                        NetworkWorker.fetch.SendDisconnect("Unhandled error while syncing!");
                    }
                    else
                    {
                        NetworkWorker.fetch.Disconnect("Unhandled error while syncing!");
                    }
                }
            }
            Profiler.updateData.ReportTime(startClock);
        }
Example #18
0
        private void HandleWarpMessage(byte[] messageData)
        {
            using (MessageReader mr = new MessageReader(messageData, false))
            {
                WarpMessageType messageType = (WarpMessageType)mr.Read <int>();
                string          fromPlayer  = mr.Read <string>();
                switch (messageType)
                {
                case WarpMessageType.REQUEST_VOTE:
                {
                    if (warpMode == WarpMode.MCW_VOTE)
                    {
                        if (voteMaster == "")
                        {
                            voteMaster = fromPlayer;
                        }
                        else
                        {
                            //Freak out and tell everyone to reset their warp votes - This can happen if 2 clients start a vote at the exact same time.
                            ReleaseWarpMaster();
                        }
                    }
                }
                break;

                case WarpMessageType.REPLY_VOTE:
                {
                    if (warpMode == WarpMode.MCW_VOTE)
                    {
                        if (voteMaster == Settings.fetch.playerName && warpMaster == "")
                        {
                            if (!voteList.ContainsKey(fromPlayer))
                            {
                                bool vote = mr.Read <bool>();
                                DarkLog.Debug(fromPlayer + " voted " + vote);
                                voteList.Add(fromPlayer, vote);
                            }
                            voteNoCount  = 0;
                            voteYesCount = 0;
                            foreach (KeyValuePair <string, bool> vote in voteList)
                            {
                                if (vote.Value)
                                {
                                    voteYesCount++;
                                }
                                else
                                {
                                    voteNoCount++;
                                }
                            }

                            //We have enough votes
                            if (voteYesCount >= voteNeededCount)
                            {
                                //Vote has passed.
                                warpMasterOwnerTime = UnityEngine.Time.realtimeSinceStartup;
                                warpMaster          = Settings.fetch.playerName;
                                using (MessageWriter mw = new MessageWriter())
                                {
                                    mw.Write <int>((int)WarpMessageType.SET_CONTROLLER);
                                    mw.Write <string>(Settings.fetch.playerName);
                                    mw.Write <string>(Settings.fetch.playerName);
                                    NetworkWorker.fetch.SendWarpMessage(mw.GetMessageBytes());
                                }
                            }
                            //We have enough votes
                            if (voteNoCount >= voteFailedCount)
                            {
                                //Vote has failed.
                                ReleaseWarpMaster();
                                DisplayMessage("Vote failed!", 5f);
                            }
                        }
                    }
                }
                break;

                case WarpMessageType.SET_CONTROLLER:
                {
                    if (warpMode == WarpMode.MCW_FORCE || warpMode == WarpMode.MCW_VOTE || warpMode == WarpMode.MCW_LOWEST)
                    {
                        string newController = mr.Read <string>();
                        warpMaster = newController;
                        if (warpMode == WarpMode.MCW_FORCE && newController == "")
                        {
                            warpMasterOwnerTime = 0f;
                        }
                        if (warpMode == WarpMode.MCW_VOTE && newController == "")
                        {
                            TimeWarp.SetRate(0, true);
                            CancelVote();
                        }
                    }
                }
                break;

                case WarpMessageType.CHANGE_WARP:
                {
                    if (warpMode == WarpMode.MCW_FORCE || warpMode == WarpMode.MCW_VOTE || warpMode == WarpMode.MCW_LOWEST || warpMode == WarpMode.SUBSPACE)
                    {
                        bool newPhysWarp  = mr.Read <bool>();
                        int  newRateIndex = mr.Read <int>();
                        if (clientWarpList.ContainsKey(fromPlayer))
                        {
                            clientWarpList[fromPlayer].isPhysWarp = newPhysWarp;
                            clientWarpList[fromPlayer].rateIndex  = newRateIndex;
                        }
                        else
                        {
                            PlayerWarpRate newPlayerWarpRate = new PlayerWarpRate();
                            newPlayerWarpRate.isPhysWarp = newPhysWarp;
                            newPlayerWarpRate.rateIndex  = newRateIndex;
                            clientWarpList.Add(fromPlayer, newPlayerWarpRate);
                        }
                        //DarkLog.Debug(fromPlayer + " warp rate changed, Physwarp: " + newPhysWarp + ", Index: " + newRateIndex);
                    }
                }
                break;

                case WarpMessageType.NEW_SUBSPACE:
                {
                    int    newSubspaceID   = mr.Read <int>();
                    long   serverTime      = mr.Read <long>();
                    double planetariumTime = mr.Read <double>();
                    float  gameSpeed       = mr.Read <float>();
                    TimeSyncer.fetch.LockNewSubspace(newSubspaceID, serverTime, planetariumTime, gameSpeed);
                    if (((warpMode == WarpMode.MCW_VOTE) || (warpMode == WarpMode.MCW_FORCE)) && (warpMaster == fromPlayer))
                    {
                        TimeSyncer.fetch.LockSubspace(newSubspaceID);
                    }
                    if (!TimeSyncer.fetch.locked && TimeSyncer.fetch.currentSubspace == newSubspaceID)
                    {
                        TimeSyncer.fetch.LockSubspace(newSubspaceID);
                    }
                }
                break;

                case WarpMessageType.CHANGE_SUBSPACE:
                {
                    int changeSubspaceID = mr.Read <int>();
                    clientSubspaceList[fromPlayer] = changeSubspaceID;
                }
                break;

                case WarpMessageType.RELOCK_SUBSPACE:
                {
                    if (fromPlayer == "Server")
                    {
                        int    subspaceID      = mr.Read <int>();
                        long   serverTime      = mr.Read <long>();
                        double planetariumTime = mr.Read <double>();
                        float  gameSpeed       = mr.Read <float>();
                        TimeSyncer.fetch.RelockSubspace(subspaceID, serverTime, planetariumTime, gameSpeed);
                    }
                }
                break;

                case WarpMessageType.REPORT_RATE:
                {
                    //Not interested in subspace.
                    mr.Read <int>();
                    clientSkewList[fromPlayer] = mr.Read <float>();
                }
                break;

                default:
                {
                    DarkLog.Debug("Unhandled WARP_MESSAGE type: " + messageType);
                    break;
                }
                }
            }
        }
Example #19
0
        public void Awake()
        {
            Profiler.DMPReferenceTime.Start();
            GameObject.DontDestroyOnLoad(this);
            assemblyPath = new DirectoryInfo(Assembly.GetExecutingAssembly().Location).FullName;
            string kspPath = new DirectoryInfo(KSPUtil.ApplicationRootPath).FullName;

            //I find my abuse of Path.Combine distrubing.
            UnityEngine.Debug.Log("KSP installed at " + kspPath);
            UnityEngine.Debug.Log("DMP installed at " + assemblyPath);
            //Prevents symlink warning for development.
            if (Settings.fetch.disclaimerAccepted != 1)
            {
                modDisabled = true;
                DisclaimerWindow.Enable();
            }
            if (!CompatibilityChecker.IsCompatible())
            {
                modDisabled = true;
            }
            #if !DEBUG
            if (!InstallChecker.IsCorrectlyInstalled())
            {
                modDisabled = true;
            }
            #endif
            SetupDirectoriesIfNeeded();
            //UniverseSyncCache needs to run expiry here
            UniverseSyncCache.fetch.ExpireCache();
            //Register events needed to bootstrap the workers.
            lock (eventLock)
            {
                resetEvent.Add(LockSystem.Reset);
                resetEvent.Add(AdminSystem.Reset);
                resetEvent.Add(AsteroidWorker.Reset);
                resetEvent.Add(ChatWorker.Reset);
                resetEvent.Add(CraftLibraryWorker.Reset);
                resetEvent.Add(DebugWindow.Reset);
                resetEvent.Add(DynamicTickWorker.Reset);
                resetEvent.Add(FlagSyncer.Reset);
                resetEvent.Add(HackyInAtmoLoader.Reset);
                resetEvent.Add(PlayerColorWorker.Reset);
                resetEvent.Add(PlayerStatusWindow.Reset);
                resetEvent.Add(PlayerStatusWorker.Reset);
                resetEvent.Add(PartKiller.Reset);
                resetEvent.Add(ScenarioWorker.Reset);
                resetEvent.Add(ScreenshotWorker.Reset);
                resetEvent.Add(TimeSyncer.Reset);
                resetEvent.Add(ToolbarSupport.Reset);
                resetEvent.Add(VesselWorker.Reset);
                resetEvent.Add(WarpWorker.Reset);
                GameEvents.onHideUI.Add(() =>
                {
                    showGUI = false;
                });
                GameEvents.onShowUI.Add(() =>
                {
                    showGUI = true;
                });
            }
            FireResetEvent();
            HandleCommandLineArgs();
            long testTime = Compression.TestSysIOCompression();
            DarkLog.Debug("System.IO compression works: " + Compression.sysIOCompressionWorks + ", test time: " + testTime + " ms.");
            DarkLog.Debug("DarkMultiPlayer " + Common.PROGRAM_VERSION + ", protocol " + Common.PROTOCOL_VERSION + " Initialized!");
        }
Example #20
0
        public void LoadSettings()
        {
            //Read XML settings
            try
            {
                bool        saveXMLAfterLoad = false;
                XmlDocument xmlDoc           = new XmlDocument();
                if (File.Exists(backupSettingsFile) && !File.Exists(settingsFile))
                {
                    DarkLog.Debug("Restoring player settings file!");
                    File.Copy(backupSettingsFile, settingsFile);
                }
                if (!File.Exists(settingsFile))
                {
                    xmlDoc.LoadXml(newXMLString());
                    playerName = DEFAULT_PLAYER_NAME;
                    xmlDoc.Save(settingsFile);
                }
                if (!File.Exists(backupSettingsFile))
                {
                    DarkLog.Debug("Backing up player token and settings file!");
                    File.Copy(settingsFile, backupSettingsFile);
                }
                xmlDoc.Load(settingsFile);
                playerName = xmlDoc.SelectSingleNode("/settings/global/@username").Value;
                try
                {
                    cacheSize = Int32.Parse(xmlDoc.SelectSingleNode("/settings/global/@cache-size").Value);
                }
                catch
                {
                    DarkLog.Debug("Adding cache size to settings file");
                    saveXMLAfterLoad = true;
                    cacheSize        = DEFAULT_CACHE_SIZE;
                }
                try
                {
                    disclaimerAccepted = Int32.Parse(xmlDoc.SelectSingleNode("/settings/global/@disclaimer").Value);
                }
                catch
                {
                    DarkLog.Debug("Adding disclaimer to settings file");
                    saveXMLAfterLoad = true;
                }
                try
                {
                    string   floatArrayString      = xmlDoc.SelectSingleNode("/settings/global/@player-color").Value;
                    string[] floatArrayStringSplit = floatArrayString.Split(',');
                    float    redColor   = float.Parse(floatArrayStringSplit[0].Trim());
                    float    greenColor = float.Parse(floatArrayStringSplit[1].Trim());
                    float    blueColor  = float.Parse(floatArrayStringSplit[2].Trim());
                    //Bounds checking - Gotta check up on those players :)
                    if (redColor < 0f)
                    {
                        redColor = 0f;
                    }
                    if (redColor > 1f)
                    {
                        redColor = 1f;
                    }
                    if (greenColor < 0f)
                    {
                        greenColor = 0f;
                    }
                    if (greenColor > 1f)
                    {
                        greenColor = 1f;
                    }
                    if (blueColor < 0f)
                    {
                        blueColor = 0f;
                    }
                    if (blueColor > 1f)
                    {
                        blueColor = 1f;
                    }
                    playerColor = new Color(redColor, greenColor, blueColor, 1f);
                }
                catch
                {
                    DarkLog.Debug("Adding player color to settings file");
                    saveXMLAfterLoad = true;
                    playerColor      = PlayerColorWorker.GenerateRandomColor();
                }
                try
                {
                    chatKey = (KeyCode)Int32.Parse(xmlDoc.SelectSingleNode("/settings/global/@chat-key").Value);
                }
                catch
                {
                    DarkLog.Debug("Adding chat key to settings file");
                    saveXMLAfterLoad = true;
                    chatKey          = KeyCode.BackQuote;
                }
                try
                {
                    screenshotKey = (KeyCode)Int32.Parse(xmlDoc.SelectSingleNode("/settings/global/@screenshot-key").Value);
                }
                catch
                {
                    DarkLog.Debug("Adding screenshot key to settings file");
                    saveXMLAfterLoad = true;
                    chatKey          = KeyCode.F8;
                }
                try
                {
                    selectedFlag = xmlDoc.SelectSingleNode("/settings/global/@selected-flag").Value;
                }
                catch
                {
                    DarkLog.Debug("Adding selected flag to settings file");
                    saveXMLAfterLoad = true;
                    selectedFlag     = "Squad/Flags/default";
                }
                try
                {
                    compressionEnabled = Boolean.Parse(xmlDoc.SelectSingleNode("/settings/global/@compression").Value);
                }
                catch
                {
                    DarkLog.Debug("Adding compression flag to settings file");
                    compressionEnabled = true;
                }
                try
                {
                    revertEnabled = Boolean.Parse(xmlDoc.SelectSingleNode("/settings/global/@revert").Value);
                }
                catch
                {
                    DarkLog.Debug("Adding revert flag to settings file");
                    revertEnabled = true;
                }
                try
                {
                    toolbarType = (DMPToolbarType)Int32.Parse(xmlDoc.SelectSingleNode("/settings/global/@toolbar").Value);
                }
                catch
                {
                    DarkLog.Debug("Adding toolbar flag to settings file");
                    toolbarType = DMPToolbarType.BLIZZY_IF_INSTALLED;
                }
                XmlNodeList serverNodeList = xmlDoc.GetElementsByTagName("server");
                servers = new List <ServerEntry>();
                foreach (XmlNode xmlNode in serverNodeList)
                {
                    ServerEntry newServer = new ServerEntry();
                    newServer.name    = xmlNode.Attributes["name"].Value;
                    newServer.address = xmlNode.Attributes["address"].Value;
                    Int32.TryParse(xmlNode.Attributes["port"].Value, out newServer.port);
                    servers.Add(newServer);
                }
                if (saveXMLAfterLoad)
                {
                    SaveSettings();
                }
            }
            catch (Exception e)
            {
                DarkLog.Debug("XML Exception: " + e);
            }

            //Read player token
            try
            {
                //Restore backup if needed
                if (File.Exists(backupPublicKeyFile) && File.Exists(backupPrivateKeyFile) && (!File.Exists(publicKeyFile) || !File.Exists(privateKeyFile)))
                {
                    DarkLog.Debug("Restoring backed up keypair!");
                    File.Copy(backupPublicKeyFile, publicKeyFile, true);
                    File.Copy(backupPrivateKeyFile, privateKeyFile, true);
                }
                //Load or create token file
                if (File.Exists(privateKeyFile) && File.Exists(publicKeyFile))
                {
                    playerPublicKey  = File.ReadAllText(publicKeyFile);
                    playerPrivateKey = File.ReadAllText(privateKeyFile);
                }
                else
                {
                    DarkLog.Debug("Creating new keypair!");
                    GenerateNewKeypair();
                }
                //Save backup token file if needed
                if (!File.Exists(backupPublicKeyFile) || !File.Exists(backupPrivateKeyFile))
                {
                    DarkLog.Debug("Backing up keypair");
                    File.Copy(publicKeyFile, backupPublicKeyFile, true);
                    File.Copy(privateKeyFile, backupPrivateKeyFile, true);
                }
            }
            catch
            {
                DarkLog.Debug("Error processing keypair, creating new keypair");
                GenerateNewKeypair();
                DarkLog.Debug("Backing up keypair");
                File.Copy(publicKeyFile, backupPublicKeyFile, true);
                File.Copy(privateKeyFile, backupPrivateKeyFile, true);
            }
        }
Example #21
0
        public void LoadOldSettings()
        {
            //Read XML settings
            try
            {
                XmlDocument xmlDoc = new XmlDocument();
                if (File.Exists(backupOldSettingsFile) && !File.Exists(oldSettingsFile))
                {
                    DarkLog.Debug("[Settings]: Restoring old player settings file!");
                    File.Move(backupOldSettingsFile, oldSettingsFile);
                }
                xmlDoc.Load(oldSettingsFile);
                playerName         = xmlDoc.SelectSingleNode("/settings/global/@username").Value;
                cacheSize          = int.Parse(xmlDoc.SelectSingleNode("/settings/global/@cache-size").Value);
                disclaimerAccepted = Int32.Parse(xmlDoc.SelectSingleNode("/settings/global/@disclaimer").Value);

                string   floatArrayString      = xmlDoc.SelectSingleNode("/settings/global/@player-color").Value;
                string[] floatArrayStringSplit = floatArrayString.Split(',');
                float    redColor   = float.Parse(floatArrayStringSplit[0].Trim());
                float    greenColor = float.Parse(floatArrayStringSplit[1].Trim());
                float    blueColor  = float.Parse(floatArrayStringSplit[2].Trim());
                //Bounds checking - Gotta check up on those players :)
                if (redColor < 0f)
                {
                    redColor = 0f;
                }
                if (redColor > 1f)
                {
                    redColor = 1f;
                }
                if (greenColor < 0f)
                {
                    greenColor = 0f;
                }
                if (greenColor > 1f)
                {
                    greenColor = 1f;
                }
                if (blueColor < 0f)
                {
                    blueColor = 0f;
                }
                if (blueColor > 1f)
                {
                    blueColor = 1f;
                }
                playerColor = new Color(redColor, greenColor, blueColor, 1f);

                chatKey            = (KeyCode)Int32.Parse(xmlDoc.SelectSingleNode("/settings/global/@chat-key").Value);
                screenshotKey      = (KeyCode)Int32.Parse(xmlDoc.SelectSingleNode("/settings/global/@screenshot-key").Value);
                selectedFlag       = xmlDoc.SelectSingleNode("/settings/global/@selected-flag").Value;
                compressionEnabled = Boolean.Parse(xmlDoc.SelectSingleNode("/settings/global/@compression").Value);
                revertEnabled      = Boolean.Parse(xmlDoc.SelectSingleNode("/settings/global/@revert").Value);
                toolbarType        = (DMPToolbarType)Int32.Parse(xmlDoc.SelectSingleNode("/settings/global/@toolbar").Value);
                XmlNodeList serverNodeList = xmlDoc.GetElementsByTagName("server");
                servers.Clear();
                foreach (XmlNode xmlNode in serverNodeList)
                {
                    ServerEntry newServer = new ServerEntry();
                    newServer.name    = xmlNode.Attributes["name"].Value;
                    newServer.address = xmlNode.Attributes["address"].Value;
                    Int32.TryParse(xmlNode.Attributes["port"].Value, out newServer.port);
                    servers.Add(newServer);
                }

                SaveSettings();
            }
            catch (Exception e)
            {
                DarkLog.Debug("Error loading old settings: " + e);
            }
        }
        private void Update()
        {
            if (!workerEnabled)
            {
                return;
            }
            InitializeScenario();
            if (scenario == null)
            {
                return;
            }

            if (lastAsteroidCheck + ASTEROID_CHECK_INTERVAL > Client.realtimeSinceStartup)
            {
                return;
            }
            lastAsteroidCheck = Client.realtimeSinceStartup;

            //Try to acquire the asteroid-spawning lock if nobody else has it.
            if (!lockSystem.LockExists("asteroid-spawning"))
            {
                lockSystem.AcquireLock("asteroid-spawning", false);
            }

            //We have the spawn lock, lets do stuff.
            if (lockSystem.LockIsOurs("asteroid-spawning"))
            {
                if (HighLogic.LoadedSceneIsFlight && !FlightGlobals.ready)
                {
                    return;
                }
                if (HighLogic.CurrentGame.flightState.protoVessels == null)
                {
                    return;
                }
                if (FlightGlobals.fetch.vessels == null)
                {
                    return;
                }
                if (HighLogic.CurrentGame.flightState.protoVessels.Count == 0)
                {
                    return;
                }
                if (FlightGlobals.fetch.vessels.Count == 0)
                {
                    return;
                }
                int beforeSpawn = GetAsteroidCount();
                if (beforeSpawn < maxNumberOfUntrackedAsteroids)
                {
                    ProtoVessel asty = SpawnAsteroid();
                    DarkLog.Debug("Spawned asteroid " + asty.vesselName + ", have " + (beforeSpawn) + ", need " + maxNumberOfUntrackedAsteroids);
                }
            }

            //Check for changes to tracking
            lock (serverAsteroids)
            {
                foreach (Vessel asteroid in GetCurrentAsteroids())
                {
                    if (asteroid.state != Vessel.State.DEAD)
                    {
                        if (!serverAsteroidTrackStatus.ContainsKey(asteroid.id))
                        {
                            serverAsteroidTrackStatus.Add(asteroid.id, asteroid.DiscoveryInfo.trackingStatus.Value);
                        }
                        else
                        {
                            if (asteroid.DiscoveryInfo.trackingStatus.Value != serverAsteroidTrackStatus[asteroid.id])
                            {
                                ProtoVessel pv = asteroid.BackupVessel();
                                DarkLog.Debug("Sending changed asteroid, new state: " + asteroid.DiscoveryInfo.trackingStatus.Value + "!");
                                serverAsteroidTrackStatus[asteroid.id] = asteroid.DiscoveryInfo.trackingStatus.Value;
                                networkWorker.SendVesselProtoMessage(pv, false, false);
                            }
                        }
                    }
                }
            }
        }
Example #23
0
        public bool ParseModFile(string modFileData)
        {
            if (modControl == ModControlMode.DISABLED)
            {
                return(true);
            }
            bool modCheckOk = true;

            //Save mod file so we can recheck it.
            lastModFileData = modFileData;
            //Err...
            string tempModFilePath = Path.Combine(Client.dmpClient.dmpDataDir, "mod-control.txt");

            using (StreamWriter sw = new StreamWriter(tempModFilePath))
            {
                sw.WriteLine("#This file is downloaded from the server during connection. It is saved here for convenience.");
                sw.WriteLine(lastModFileData);
            }

            //Parse
            Dictionary <string, string> parseRequired = new Dictionary <string, string>();
            Dictionary <string, string> parseOptional = new Dictionary <string, string>();
            List <string> parseWhiteBlackList         = new List <string>();
            List <string> parsePartsList = new List <string>();
            bool          isWhiteList    = false;
            string        readMode       = "";

            using (StringReader sr = new StringReader(modFileData))
            {
                while (true)
                {
                    string currentLine = sr.ReadLine();
                    if (currentLine == null)
                    {
                        //Done reading
                        break;
                    }
                    //Remove tabs/spaces from the start & end.
                    string trimmedLine = currentLine.Trim();
                    if (trimmedLine.StartsWith("#", StringComparison.Ordinal) || String.IsNullOrEmpty(trimmedLine))
                    {
                        //Skip comments or empty lines.
                        continue;
                    }
                    if (trimmedLine.StartsWith("!", StringComparison.Ordinal))
                    {
                        //New section
                        switch (trimmedLine.Substring(1))
                        {
                        case "required-files":
                        case "optional-files":
                        case "partslist":
                            readMode = trimmedLine.Substring(1);
                            break;

                        case "resource-blacklist":
                            readMode    = trimmedLine.Substring(1);
                            isWhiteList = false;
                            break;

                        case "resource-whitelist":
                            readMode    = trimmedLine.Substring(1);
                            isWhiteList = true;
                            break;

                        default:
                            break;
                        }
                    }
                    else
                    {
                        switch (readMode)
                        {
                        case "required-files":
                        {
                            string lowerFixedLine = trimmedLine.ToLowerInvariant().Replace('\\', '/');
                            if (lowerFixedLine.Contains("="))
                            {
                                string[] splitLine = lowerFixedLine.Split('=');
                                if (splitLine.Length == 2)
                                {
                                    if (!parseRequired.ContainsKey(splitLine[0]))
                                    {
                                        parseRequired.Add(splitLine[0], splitLine[1].ToLowerInvariant());
                                    }
                                }
                                else
                                {
                                    if (splitLine.Length == 1)
                                    {
                                        if (!parseRequired.ContainsKey(splitLine[0]))
                                        {
                                            parseRequired.Add(splitLine[0], "");
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (!parseRequired.ContainsKey(lowerFixedLine))
                                {
                                    parseRequired.Add(lowerFixedLine, "");
                                }
                            }
                        }
                        break;

                        case "optional-files":
                        {
                            string lowerFixedLine = trimmedLine.ToLowerInvariant().Replace('\\', '/');
                            if (lowerFixedLine.Contains("="))
                            {
                                string[] splitLine = lowerFixedLine.Split('=');
                                if (splitLine.Length == 2)
                                {
                                    if (!parseOptional.ContainsKey(splitLine[0]))
                                    {
                                        parseOptional.Add(splitLine[0], splitLine[1]);
                                    }
                                }
                                else
                                {
                                    if (splitLine.Length == 1)
                                    {
                                        if (!parseOptional.ContainsKey(splitLine[0]))
                                        {
                                            parseOptional.Add(splitLine[0], "");
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (!parseOptional.ContainsKey(lowerFixedLine))
                                {
                                    parseOptional.Add(lowerFixedLine, "");
                                }
                            }
                        }
                        break;

                        case "resource-whitelist":
                        case "resource-blacklist":
                        {
                            string lowerFixedLine = trimmedLine.ToLowerInvariant().Replace('\\', '/');
                            //Resource is dll's only.
                            if (lowerFixedLine.ToLowerInvariant().EndsWith(".dll", StringComparison.Ordinal))
                            {
                                if (parseWhiteBlackList.Contains(lowerFixedLine))
                                {
                                    parseWhiteBlackList.Add(lowerFixedLine);
                                }
                            }
                        }
                        break;

                        case "partslist":
                            if (!parsePartsList.Contains(trimmedLine))
                            {
                                parsePartsList.Add(trimmedLine);
                            }
                            break;

                        default:
                            break;
                        }
                    }
                }
            }

            string[]      currentGameDataFiles       = Directory.GetFiles(Client.dmpClient.gameDataDir, "*", SearchOption.AllDirectories);
            List <string> currentGameDataFilesNormal = new List <string>();
            List <string> currentGameDataFilesLower  = new List <string>();

            foreach (string currentFile in currentGameDataFiles)
            {
                string relativeFilePath = currentFile.Substring(currentFile.ToLowerInvariant().IndexOf("gamedata", StringComparison.Ordinal) + 9).Replace('\\', '/');
                currentGameDataFilesNormal.Add(relativeFilePath);
                currentGameDataFilesLower.Add(relativeFilePath.ToLowerInvariant());
            }
            //Check
            StringBuilder sb = new StringBuilder();

            //Check Required
            foreach (KeyValuePair <string, string> requiredEntry in parseRequired)
            {
                if (!requiredEntry.Key.EndsWith("dll", StringComparison.Ordinal))
                {
                    //Protect against windows-style entries in mod-control.txt. Also use case insensitive matching.
                    if (!currentGameDataFilesLower.Contains(requiredEntry.Key))
                    {
                        modCheckOk = false;
                        DarkLog.Debug("Required file " + requiredEntry.Key + " is missing!");
                        sb.AppendLine("Required file " + requiredEntry.Key + " is missing!");
                        continue;
                    }
                    //If the entry has a SHA sum, we need to check it.
                    if (requiredEntry.Value != "")
                    {
                        string normalCaseFileName = currentGameDataFilesNormal[currentGameDataFilesLower.IndexOf(requiredEntry.Key)];
                        string fullFileName       = Path.Combine(Client.dmpClient.gameDataDir, normalCaseFileName);
                        if (!CheckFile(fullFileName, requiredEntry.Value))
                        {
                            modCheckOk = false;
                            DarkLog.Debug("Required file " + requiredEntry.Key + " does not match hash " + requiredEntry.Value + "!");
                            sb.AppendLine("Required file " + requiredEntry.Key + " does not match hash " + requiredEntry.Value + "!");
                            continue;
                        }
                    }
                }
                else
                {
                    //DLL entries are cached from startup.
                    if (!dllList.ContainsKey(requiredEntry.Key))
                    {
                        modCheckOk = false;
                        DarkLog.Debug("Required file " + requiredEntry.Key + " is missing!");
                        sb.AppendLine("Required file " + requiredEntry.Key + " is missing!");
                        continue;
                    }
                    if (requiredEntry.Value != "")
                    {
                        if (dllList[requiredEntry.Key] != requiredEntry.Value)
                        {
                            modCheckOk = false;
                            DarkLog.Debug("Required file " + requiredEntry.Key + " does not match hash " + requiredEntry.Value + "!");
                            sb.AppendLine("Required file " + requiredEntry.Key + " does not match hash " + requiredEntry.Value + "!");
                            continue;
                        }
                    }
                }
            }
            //Check Optional
            foreach (KeyValuePair <string, string> optionalEntry in parseOptional)
            {
                if (!optionalEntry.Key.EndsWith("dll", StringComparison.Ordinal))
                {
                    //Protect against windows-style entries in mod-control.txt. Also use case insensitive matching.
                    if (!currentGameDataFilesLower.Contains(optionalEntry.Key))
                    {
                        //File is optional, nothing to check if it doesn't exist.
                        continue;
                    }
                    //If the entry has a SHA sum, we need to check it.
                    if (optionalEntry.Value != "")
                    {
                        string normalCaseFileName = currentGameDataFilesNormal[currentGameDataFilesLower.IndexOf(optionalEntry.Key)];
                        string fullFileName       = Path.Combine(Client.dmpClient.gameDataDir, normalCaseFileName);
                        if (!CheckFile(fullFileName, optionalEntry.Value))
                        {
                            modCheckOk = false;
                            DarkLog.Debug("Optional file " + optionalEntry.Key + " does not match hash " + optionalEntry.Value + "!");
                            sb.AppendLine("Optional file " + optionalEntry.Key + " does not match hash " + optionalEntry.Value + "!");
                            continue;
                        }
                    }
                }
                else
                {
                    //DLL entries are cached from startup.
                    if (!dllList.ContainsKey(optionalEntry.Key))
                    {
                        //File is optional, nothing to check if it doesn't exist.
                        continue;
                    }
                    if (optionalEntry.Value != "")
                    {
                        if (dllList[optionalEntry.Key] != optionalEntry.Value)
                        {
                            modCheckOk = false;
                            DarkLog.Debug("Optional file " + optionalEntry.Key + " does not match hash " + optionalEntry.Value + "!");
                            sb.AppendLine("Optional file " + optionalEntry.Key + " does not match hash " + optionalEntry.Value + "!");
                            continue;
                        }
                    }
                }
            }
            if (isWhiteList)
            {
                //Check Resource whitelist
                List <string> autoAllowed = new List <string>();
                autoAllowed.Add("darkmultiplayer/plugins/darkmultiplayer.dll");
                autoAllowed.Add("darkmultiplayer/plugins/darkmultiplayer-common.dll");
                //Leave the old one there if the user forgets to delete it.
                autoAllowed.Add("darkmultiplayer/plugins/messagewriter.dll");
                autoAllowed.Add("darkmultiplayer/plugins/messagewriter2.dll");
                //Compression
                autoAllowed.Add("darkmultiplayer/plugins/icsharpcode.sharpziplib.dll");
                foreach (KeyValuePair <string, string> dllResource in dllList)
                {
                    //Allow DMP files
                    if (autoAllowed.Contains(dllResource.Key))
                    {
                        continue;
                    }
                    //Ignore squad plugins
                    if (dllResource.Key.StartsWith("squad/plugins", StringComparison.Ordinal))
                    {
                        continue;
                    }
                    //Check required (Required implies whitelist)
                    if (parseRequired.ContainsKey(dllResource.Key))
                    {
                        continue;
                    }
                    //Check optional (Optional implies whitelist)
                    if (parseOptional.ContainsKey(dllResource.Key))
                    {
                        continue;
                    }
                    //Check whitelist
                    if (parseWhiteBlackList.Contains(dllResource.Key))
                    {
                        continue;
                    }
                    modCheckOk = false;
                    DarkLog.Debug("Non-whitelisted resource " + dllResource.Key + " exists on client!");
                    sb.AppendLine("Non-whitelisted resource " + dllResource.Key + " exists on client!");
                }
            }
            else
            {
                //Check Resource blacklist
                foreach (string blacklistEntry in parseWhiteBlackList)
                {
                    if (dllList.ContainsKey(blacklistEntry.ToLowerInvariant()))
                    {
                        modCheckOk = false;
                        DarkLog.Debug("Banned resource " + blacklistEntry + " exists on client!");
                        sb.AppendLine("Banned resource " + blacklistEntry + " exists on client!");
                    }
                }
            }
            if (!modCheckOk)
            {
                failText          = sb.ToString();
                modWindow.display = true;
                return(false);
            }
            allowedParts = parsePartsList;
            DarkLog.Debug("Mod check passed!");
            return(true);
        }
Example #24
0
        public void SendScenarioModules(bool highPriority)
        {
            lastScenarioSendTime = Client.realtimeSinceStartup;
            List <string>    scenarioName = new List <string>();
            List <ByteArray> scenarioData = new List <ByteArray>();

            foreach (ScenarioModule sm in ScenarioRunner.GetLoadedModules())
            {
                string scenarioType = sm.GetType().Name;
                if (!IsScenarioModuleAllowed(scenarioType))
                {
                    continue;
                }
                try
                {
                    ConfigNode scenarioNode = new ConfigNode();
                    sm.Save(scenarioNode);

                    ByteArray scenarioBytes = configNodeSerializer.Serialize(scenarioNode);
                    string    scenarioHash  = Common.CalculateSHA256Hash(scenarioBytes);
                    if (scenarioBytes.Length == 0)
                    {
                        DarkLog.Debug("Error writing scenario data for " + scenarioType);
                        ByteRecycler.ReleaseObject(scenarioBytes);
                        continue;
                    }
                    if (checkData.ContainsKey(scenarioType) ? (checkData[scenarioType] == scenarioHash) : false)
                    {
                        //Data is the same since last time - Skip it.
                        ByteRecycler.ReleaseObject(scenarioBytes);
                        continue;
                    }
                    else
                    {
                        checkData[scenarioType] = scenarioHash;
                    }
                    scenarioName.Add(scenarioType);
                    scenarioData.Add(scenarioBytes);
                }
                catch (Exception e)
                {
                    string fullName = sm.GetType().FullName;
                    if (!warnedModules.Contains(fullName))
                    {
                        DarkLog.Debug("Unable to save module data from " + fullName + ", skipping upload of this module. Exception: " + e);
                        warnedModules.Add(fullName);
                        if (!fullName.Contains("Expansions.Serenity.DeployedScience"))
                        {
                            ScreenMessages.PostScreenMessage("DMP was unable to save " + fullName + ", this module data will be lost.", 30f, ScreenMessageStyle.UPPER_CENTER);
                        }
                    }
                }
            }

            if (scenarioName.Count > 0)
            {
                if (highPriority)
                {
                    networkWorker.SendScenarioModuleDataHighPriority(scenarioName.ToArray(), scenarioData.ToArray());
                }
                else
                {
                    networkWorker.SendScenarioModuleData(scenarioName.ToArray(), scenarioData.ToArray());
                }
            }
        }
Example #25
0
        public void HandleSyncTime(long clientSend, long serverReceive, long serverSend)
        {
            long clientReceive = DateTime.UtcNow.Ticks;
            long clientLatency = (clientReceive - clientSend) - (serverSend - serverReceive);
            long clientOffset  = ((serverReceive - clientSend) + (serverSend - clientReceive)) / 2;

            clockOffset[clockOffsetPos] = clientOffset;
            clockOffsetPos++;
            networkLatency[networkLatencyPos] = clientLatency;
            networkLatencyPos++;
            serverLag = serverSend - serverReceive;
            if (clockOffsetPos >= clockOffset.Length)
            {
                clockOffsetPos  = 0;
                clockOffsetFull = true;
            }
            if (networkLatencyPos >= networkLatency.Length)
            {
                networkLatencyPos  = 0;
                networkLatencyFull = true;
            }
            long clockOffsetTotal  = 0;
            int  clockOffsetEndPos = clockOffsetPos;

            if (clockOffsetFull)
            {
                clockOffsetEndPos = clockOffset.Length;
            }
            for (int i = 0; i < clockOffsetEndPos; i++)
            {
                clockOffsetTotal += clockOffset[i];
            }
            clockOffsetAverage = clockOffsetTotal / clockOffsetEndPos;


            long networkLatencyTotal  = 0;
            int  networkLatencyEndPos = clockOffsetPos;

            if (networkLatencyFull)
            {
                networkLatencyEndPos = networkLatency.Length;
            }
            for (int i = 0; i < networkLatencyEndPos; i++)
            {
                networkLatencyTotal += networkLatency[i];
            }
            networkLatencyAverage = networkLatencyTotal / networkLatencyEndPos;

            //Check if we are now synced
            if ((clockOffsetFull || clockOffsetPos > SYNC_TIME_VALID) && !synced)
            {
                synced = true;
                float clockOffsetAverageMs = clockOffsetAverage / 10000f;
                float networkLatencyMs     = networkLatencyAverage / 10000f;
                DarkLog.Debug("Initial clock syncronized, offset " + clockOffsetAverageMs + "ms, latency " + networkLatencyMs + "ms");
            }

            //Ask for another time sync if we aren't synced yet.
            if (!synced)
            {
                lastSyncTime = Client.realtimeSinceStartup;
                networkWorker.SendTimeSync();
            }
        }
Example #26
0
        public void LoadScenarioData(ScenarioEntry entry)
        {
            if (!IsScenarioModuleAllowed(entry.scenarioName))
            {
                DarkLog.Debug("Skipped '" + entry.scenarioName + "' scenario data  in " + dmpGame.gameMode + " mode");
                return;
            }
            //Load data from DMP
            if (entry.scenarioNode == null)
            {
                DarkLog.Debug(entry.scenarioName + " scenario data failed to create a ConfigNode!");
                ScreenMessages.PostScreenMessage("Scenario " + entry.scenarioName + " failed to load, blocking scenario uploads.", 10f, ScreenMessageStyle.UPPER_CENTER);
                blockScenarioDataSends = true;
                return;
            }

            //Load data into game
            if (DidScenarioChange(entry))
            {
                bool      loaded        = false;
                ByteArray scenarioBytes = configNodeSerializer.Serialize(entry.scenarioNode);
                checkData[entry.scenarioName] = Common.CalculateSHA256Hash(scenarioBytes);
                ByteRecycler.ReleaseObject(scenarioBytes);
                foreach (ProtoScenarioModule psm in HighLogic.CurrentGame.scenarios)
                {
                    if (psm.moduleName == entry.scenarioName)
                    {
                        DarkLog.Debug("Loading existing " + entry.scenarioName + " scenario module");
                        try
                        {
                            if (psm.moduleRef == null)
                            {
                                DarkLog.Debug("Fixing null scenario module!");
                                psm.moduleRef = new ScenarioModule();
                            }
                            bool skipLoad = false;
                            if (beforeCallback.ContainsKey(psm.moduleName))
                            {
                                skipLoad = beforeCallback[psm.moduleName](entry.scenarioNode);
                            }
                            if (!skipLoad)
                            {
                                psm.moduleRef.Load(entry.scenarioNode);
                            }
                            if (afterCallback.ContainsKey(psm.moduleName))
                            {
                                afterCallback[psm.moduleName](entry.scenarioNode);
                            }
                        }
                        catch (Exception e)
                        {
                            DarkLog.Debug("Error loading " + entry.scenarioName + " scenario module, Exception: " + e);
                            blockScenarioDataSends = true;
                        }
                        loaded = true;
                    }
                }
                if (!loaded)
                {
                    DarkLog.Debug("Loading new " + entry.scenarioName + " scenario module");
                    LoadNewScenarioData(entry.scenarioNode);
                }
            }
        }
Example #27
0
        private void HandleCommandLineArgs()
        {
            bool   nextLineIsAddress = false;
            bool   valid             = false;
            string address           = null;
            int    port = 6702;

            foreach (string commandLineArg in Environment.GetCommandLineArgs())
            {
                //Supporting IPv6 is FUN!
                if (nextLineIsAddress)
                {
                    valid             = true;
                    nextLineIsAddress = false;
                    if (commandLineArg.Contains("dmp://"))
                    {
                        if (commandLineArg.Contains("[") && commandLineArg.Contains("]"))
                        {
                            //IPv6 literal
                            address = commandLineArg.Substring("dmp://[".Length);
                            address = address.Substring(0, address.LastIndexOf("]"));
                            if (commandLineArg.Contains("]:"))
                            {
                                //With port
                                string portString = commandLineArg.Substring(commandLineArg.LastIndexOf("]:") + 1);
                                if (!Int32.TryParse(portString, out port))
                                {
                                    valid = false;
                                }
                            }
                        }
                        else
                        {
                            //IPv4 literal or hostname
                            if (commandLineArg.Substring("dmp://".Length).Contains(":"))
                            {
                                //With port
                                address = commandLineArg.Substring("dmp://".Length);
                                address = address.Substring(0, address.LastIndexOf(":"));
                                string portString = commandLineArg.Substring(commandLineArg.LastIndexOf(":") + 1);
                                if (!Int32.TryParse(portString, out port))
                                {
                                    valid = false;
                                }
                            }
                            else
                            {
                                //Without port
                                address = commandLineArg.Substring("dmp://".Length);
                            }
                        }
                    }
                    else
                    {
                        valid = false;
                    }
                }

                if (commandLineArg == "-dmp")
                {
                    nextLineIsAddress = true;
                }
            }
            if (valid)
            {
                commandLineConnect         = new ServerEntry();
                commandLineConnect.address = address;
                commandLineConnect.port    = port;
                DarkLog.Debug("Connecting via command line to: " + address + ", port: " + port);
            }
            else
            {
                DarkLog.Debug("Command line address is invalid: " + address + ", port: " + port);
            }
        }
        private void OnContractAccepted(Contract contract)
        {
            DarkLog.Debug("Contract accepted, state: " + contract.ContractState);
            ConfigNode contractNode = new ConfigNode();

            contract.Save(contractNode);

            if (contractNode.GetValue("type") == "RecoverAsset")
            {
                string kerbalName   = contractNode.GetValue("kerbalName").Trim();
                int    kerbalGender = int.Parse(contractNode.GetValue("gender"));
                uint   partID       = uint.Parse(contractNode.GetValue("partID"));

                if (!string.IsNullOrEmpty(kerbalName))
                {
                    ProtoCrewMember rescueKerbal = null;
                    if (!HighLogic.CurrentGame.CrewRoster.Exists(kerbalName))
                    {
                        DarkLog.Debug("Generating missing kerbal " + kerbalName + " for rescue contract");

                        rescueKerbal = HighLogic.CurrentGame.CrewRoster.GetNewKerbal(ProtoCrewMember.KerbalType.Unowned);
                        rescueKerbal.ChangeName(kerbalName);
                        rescueKerbal.gender       = (ProtoCrewMember.Gender)kerbalGender;
                        rescueKerbal.rosterStatus = ProtoCrewMember.RosterStatus.Assigned;
                    }
                    else
                    {
                        rescueKerbal = HighLogic.CurrentGame.CrewRoster[kerbalName];
                        DarkLog.Debug("Kerbal " + kerbalName + " already exists, skipping respawn");
                    }
                    if (rescueKerbal != null)
                    {
                        vesselWorker.SendKerbalIfDifferent(rescueKerbal);
                    }
                }

                if (partID != 0)
                {
                    Vessel contractVessel = FinePrint.Utilities.VesselUtilities.FindVesselWithPartIDs(new List <uint> {
                        partID
                    });
                    if (contractVessel != null)
                    {
                        vesselWorker.SendVesselUpdateIfNeeded(contractVessel);
                    }
                }
            }

            else if (contractNode.GetValue("type") == "TourismContract")
            {
                string tourists = contractNode.GetValue("tourists");
                if (tourists != null)
                {
                    string[] touristsNames = tourists.Split(new char[] { '|' });
                    foreach (string touristName in touristsNames)
                    {
                        ProtoCrewMember pcm = null;
                        if (!HighLogic.CurrentGame.CrewRoster.Exists(touristName))
                        {
                            DarkLog.Debug("Spawning missing tourist " + touristName + " for tourism contract");
                            pcm = HighLogic.CurrentGame.CrewRoster.GetNewKerbal(ProtoCrewMember.KerbalType.Tourist);
                            pcm.rosterStatus = ProtoCrewMember.RosterStatus.Available;
                            pcm.ChangeName(touristName);
                        }
                        else
                        {
                            DarkLog.Debug("Skipped respawn of existing tourist " + touristName);
                            pcm = HighLogic.CurrentGame.CrewRoster[touristName];
                        }
                        if (pcm != null)
                        {
                            vesselWorker.SendKerbalIfDifferent(pcm);
                        }
                    }
                }
            }
        }
        public void GenerateUniverse(string saveName)
        {
            string universeFolder = Path.Combine(Client.dmpClient.kspRootPath, "Universe");

            if (Directory.Exists(universeFolder))
            {
                Directory.Delete(universeFolder, true);
            }

            string saveFolder = Path.Combine(savesFolder, saveName);

            if (!Directory.Exists(saveFolder))
            {
                DarkLog.Debug("Failed to generate a DMP universe for '" + saveName + "', Save directory doesn't exist");
                ScreenMessages.PostScreenMessage("Failed to generate a DMP universe for '" + saveName + "', Save directory doesn't exist", 5f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            string persistentFile = Path.Combine(saveFolder, "persistent.sfs");

            if (!File.Exists(persistentFile))
            {
                DarkLog.Debug("Failed to generate a DMP universe for '" + saveName + "', persistent.sfs doesn't exist");
                ScreenMessages.PostScreenMessage("Failed to generate a DMP universe for '" + saveName + "', persistent.sfs doesn't exist", 5f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            Directory.CreateDirectory(universeFolder);
            string vesselFolder = Path.Combine(universeFolder, "Vessels");

            Directory.CreateDirectory(vesselFolder);
            string scenarioFolder = Path.Combine(universeFolder, "Scenarios");

            Directory.CreateDirectory(scenarioFolder);
            string playerScenarioFolder = Path.Combine(scenarioFolder, dmpSettings.playerName);

            Directory.CreateDirectory(playerScenarioFolder);
            string kerbalFolder = Path.Combine(universeFolder, "Kerbals");

            Directory.CreateDirectory(kerbalFolder);

            //Load game data
            ConfigNode persistentData = ConfigNode.Load(persistentFile);

            if (persistentData == null)
            {
                DarkLog.Debug("Failed to generate a DMP universe for '" + saveName + "', failed to load persistent data");
                ScreenMessages.PostScreenMessage("Failed to generate a DMP universe for '" + saveName + "', failed to load persistent data", 5f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            ConfigNode gameData = persistentData.GetNode("GAME");

            if (gameData == null)
            {
                DarkLog.Debug("Failed to generate a DMP universe for '" + saveName + "', failed to load game data");
                ScreenMessages.PostScreenMessage("Failed to generate a DMP universe for '" + saveName + "', failed to load game data", 5f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            //Save vessels
            ConfigNode flightState = gameData.GetNode("FLIGHTSTATE");

            if (flightState == null)
            {
                DarkLog.Debug("Failed to generate a DMP universe for '" + saveName + "', failed to load flight state data");
                ScreenMessages.PostScreenMessage("Failed to generate a DMP universe for '" + saveName + "', failed to load flight state data", 5f, ScreenMessageStyle.UPPER_CENTER);
                return;
            }

            ConfigNode[] vesselNodes = flightState.GetNodes("VESSEL");
            if (vesselNodes != null)
            {
                foreach (ConfigNode cn in vesselNodes)
                {
                    string vesselID = Common.ConvertConfigStringToGUIDString(cn.GetValue("pid"));
                    DarkLog.Debug("Saving vessel " + vesselID + ", name: " + cn.GetValue("name"));
                    cn.Save(Path.Combine(vesselFolder, vesselID + ".txt"));
                }
            }
            //Save scenario data
            ConfigNode[] scenarioNodes = gameData.GetNodes("SCENARIO");
            if (scenarioNodes != null)
            {
                foreach (ConfigNode cn in scenarioNodes)
                {
                    string scenarioName = cn.GetValue("name");
                    DarkLog.Debug("Saving scenario: " + scenarioName);
                    cn.Save(Path.Combine(playerScenarioFolder, scenarioName + ".txt"));
                }
            }
            //Save kerbal data
            ConfigNode[] kerbalNodes = gameData.GetNode("ROSTER").GetNodes("CREW");
            if (kerbalNodes != null)
            {
                int kerbalIndex = 0;
                foreach (ConfigNode cn in kerbalNodes)
                {
                    DarkLog.Debug("Saving kerbal " + kerbalIndex + ", name: " + cn.GetValue("name"));
                    cn.Save(Path.Combine(kerbalFolder, kerbalIndex + ".txt"));
                    kerbalIndex++;
                }
            }
            DarkLog.Debug("Generated KSP_folder/Universe from " + saveName);
            ScreenMessages.PostScreenMessage("Generated KSP_folder/Universe from " + saveName, 5f, ScreenMessageStyle.UPPER_CENTER);
        }
Example #30
0
        public void DodgeKerbals(ConfigNode inputNode, Guid protovesselID)
        {
            List <string> takenKerbals = new List <string>();

            foreach (ConfigNode partNode in inputNode.GetNodes("PART"))
            {
                int crewIndex = 0;
                foreach (string currentKerbalName in partNode.GetValues("crew"))
                {
                    if (kerbalToVessel.ContainsKey(currentKerbalName) ? kerbalToVessel[currentKerbalName] != protovesselID : false)
                    {
                        ProtoCrewMember        newKerbal       = null;
                        ProtoCrewMember.Gender newKerbalGender = GetKerbalGender(currentKerbalName);
                        string newExperienceTrait = null;
                        if (HighLogic.CurrentGame.CrewRoster.Exists(currentKerbalName))
                        {
                            ProtoCrewMember oldKerbal = HighLogic.CurrentGame.CrewRoster[currentKerbalName];
                            newKerbalGender    = oldKerbal.gender;
                            newExperienceTrait = oldKerbal.experienceTrait.TypeName;
                        }
                        foreach (ProtoCrewMember possibleKerbal in HighLogic.CurrentGame.CrewRoster.Crew)
                        {
                            bool kerbalOk = true;
                            if (kerbalOk && kerbalToVessel.ContainsKey(possibleKerbal.name) && (takenKerbals.Contains(possibleKerbal.name) || kerbalToVessel[possibleKerbal.name] != protovesselID))
                            {
                                kerbalOk = false;
                            }
                            if (kerbalOk && possibleKerbal.gender != newKerbalGender)
                            {
                                kerbalOk = false;
                            }
                            if (kerbalOk && newExperienceTrait != null && possibleKerbal.experienceTrait != null && newExperienceTrait != possibleKerbal.experienceTrait.TypeName)
                            {
                                kerbalOk = false;
                            }
                            if (kerbalOk)
                            {
                                newKerbal = possibleKerbal;
                                break;
                            }
                        }
                        int kerbalTries = 0;
                        while (newKerbal == null)
                        {
                            bool kerbalOk = true;
                            ProtoCrewMember.KerbalType kerbalType = ProtoCrewMember.KerbalType.Crew;
                            if (newExperienceTrait == "Tourist")
                            {
                                kerbalType = ProtoCrewMember.KerbalType.Tourist;
                            }
                            if (newExperienceTrait == "Unowned")
                            {
                                kerbalType = ProtoCrewMember.KerbalType.Unowned;
                            }
                            ProtoCrewMember possibleKerbal = HighLogic.CurrentGame.CrewRoster.GetNewKerbal(kerbalType);
                            if (kerbalTries < 200 && possibleKerbal.gender != newKerbalGender)
                            {
                                kerbalOk = false;
                            }
                            if (kerbalTries < 100 && newExperienceTrait != null && newExperienceTrait != possibleKerbal.experienceTrait.TypeName)
                            {
                                kerbalOk = false;
                            }
                            if (kerbalOk)
                            {
                                newKerbal = possibleKerbal;
                            }
                            kerbalTries++;
                        }
                        DarkLog.Debug("Generated dodged kerbal with " + kerbalTries + " tries");
                        partNode.SetValue("crew", newKerbal.name, crewIndex);
                        newKerbal.seatIdx      = crewIndex;
                        newKerbal.rosterStatus = ProtoCrewMember.RosterStatus.Assigned;
                        takenKerbals.Add(newKerbal.name);
                    }
                    else
                    {
                        takenKerbals.Add(currentKerbalName);
                        CreateKerbalIfMissing(currentKerbalName, protovesselID);
                        HighLogic.CurrentGame.CrewRoster[currentKerbalName].rosterStatus = ProtoCrewMember.RosterStatus.Assigned;
                        HighLogic.CurrentGame.CrewRoster[currentKerbalName].seatIdx      = crewIndex;
                    }
                    crewIndex++;
                }
            }
            vesselToKerbal[protovesselID] = takenKerbals;
            foreach (string name in takenKerbals)
            {
                kerbalToVessel[name] = protovesselID;
            }
        }