public void Start() { 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; 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); optionsWindow = new OptionsWindow(dmpSettings, universeSyncCache, modWorker, universeConverterWindow, toolbarSupport); connectionWindow = new ConnectionWindow(dmpSettings, optionsWindow); disclaimerWindow = new DisclaimerWindow(dmpSettings); dmpModInterface = new DMPModInterface(); SafetyBubble.RegisterDefaultLocations(); if (!CompatibilityChecker.IsCompatible() || !InstallChecker.IsCorrectlyInstalled()) { modDisabled = true; } if (dmpSettings.disclaimerAccepted != 1) { modDisabled = true; disclaimerWindow.SpawnDialog(); } Profiler.DMPReferenceTime.Start(); 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!"); }
private void Update() { if (workerEnabled) { if ((Client.realtimeSinceStartup - lastPlayerStatusCheck) > PLAYER_STATUS_CHECK_INTERVAL) { lastPlayerStatusCheck = Client.realtimeSinceStartup; myPlayerStatus.vesselText = ""; myPlayerStatus.statusText = ""; if (HighLogic.LoadedSceneIsFlight) { //Send vessel+status update if (FlightGlobals.ActiveVessel != null) { if (!vesselWorker.isSpectating) { myPlayerStatus.vesselText = FlightGlobals.ActiveVessel.vesselName; string bodyName = FlightGlobals.ActiveVessel.mainBody.bodyName; switch (FlightGlobals.ActiveVessel.situation) { case (Vessel.Situations.DOCKED): myPlayerStatus.statusText = "Docked above " + bodyName; break; case (Vessel.Situations.ESCAPING): if (FlightGlobals.ActiveVessel.orbit.timeToPe < 0) { myPlayerStatus.statusText = "Escaping " + bodyName; } else { myPlayerStatus.statusText = "Encountering " + bodyName; } break; case (Vessel.Situations.FLYING): if (!SafetyBubble.isInSafetyBubble(FlightGlobals.fetch.activeVessel.GetWorldPos3D(), FlightGlobals.fetch.activeVessel.mainBody, vesselWorker.safetyBubbleDistance)) { myPlayerStatus.statusText = "Flying above " + bodyName; } else { myPlayerStatus.statusText = "Flying in safety bubble"; } break; case (Vessel.Situations.LANDED): if (!SafetyBubble.isInSafetyBubble(FlightGlobals.fetch.activeVessel.GetWorldPos3D(), FlightGlobals.fetch.activeVessel.mainBody, vesselWorker.safetyBubbleDistance)) { myPlayerStatus.statusText = "Landed on " + bodyName; } else { myPlayerStatus.statusText = "Landed in safety bubble"; } break; case (Vessel.Situations.ORBITING): myPlayerStatus.statusText = "Orbiting " + bodyName; break; case (Vessel.Situations.PRELAUNCH): if (!SafetyBubble.isInSafetyBubble(FlightGlobals.fetch.activeVessel.GetWorldPos3D(), FlightGlobals.fetch.activeVessel.mainBody, vesselWorker.safetyBubbleDistance)) { myPlayerStatus.statusText = "Launching from " + bodyName; } else { myPlayerStatus.statusText = "Launching from safety bubble"; } break; case (Vessel.Situations.SPLASHED): myPlayerStatus.statusText = "Splashed on " + bodyName; break; case (Vessel.Situations.SUB_ORBITAL): if (FlightGlobals.ActiveVessel.verticalSpeed > 0) { myPlayerStatus.statusText = "Ascending from " + bodyName; } else { myPlayerStatus.statusText = "Descending to " + bodyName; } break; default: break; } } else { if (lockSystem.LockExists("control-" + FlightGlobals.ActiveVessel.id.ToString())) { if (lockSystem.LockIsOurs("control-" + FlightGlobals.ActiveVessel.id.ToString())) { myPlayerStatus.statusText = "Waiting for vessel control"; } else { myPlayerStatus.statusText = "Spectating " + lockSystem.LockOwner("control-" + FlightGlobals.ActiveVessel.id.ToString()); } } else { if (permissions.PlayerHasVesselPermission(myPlayerStatus.playerName, FlightGlobals.ActiveVessel.id)) { myPlayerStatus.statusText = "Spectating future updates"; } else { myPlayerStatus.statusText = "Spectating protected vessel"; } } } } else { myPlayerStatus.statusText = "Loading"; } } else { //Send status update switch (HighLogic.LoadedScene) { case (GameScenes.EDITOR): myPlayerStatus.statusText = "Building"; if (EditorDriver.editorFacility == EditorFacility.VAB) { myPlayerStatus.statusText = "Building in VAB"; } if (EditorDriver.editorFacility == EditorFacility.SPH) { myPlayerStatus.statusText = "Building in SPH"; } break; case (GameScenes.SPACECENTER): myPlayerStatus.statusText = "At Space Center"; break; case (GameScenes.TRACKSTATION): myPlayerStatus.statusText = "At Tracking Station"; break; case (GameScenes.LOADING): myPlayerStatus.statusText = "Loading"; break; default: break; } } } bool statusDifferent = false; statusDifferent = statusDifferent || (myPlayerStatus.vesselText != lastPlayerStatus.vesselText); statusDifferent = statusDifferent || (myPlayerStatus.statusText != lastPlayerStatus.statusText); if (statusDifferent && ((Client.realtimeSinceStartup - lastPlayerStatusSend) > PLAYER_STATUS_SEND_THROTTLE)) { lastPlayerStatusSend = Client.realtimeSinceStartup; lastPlayerStatus.vesselText = myPlayerStatus.vesselText; lastPlayerStatus.statusText = myPlayerStatus.statusText; networkWorker.SendPlayerStatus(myPlayerStatus); } while (addStatusQueue.Count > 0) { PlayerStatus newStatusEntry = addStatusQueue.Dequeue(); bool found = false; foreach (PlayerStatus playerStatusEntry in playerStatusList) { if (playerStatusEntry.playerName == newStatusEntry.playerName) { found = true; playerStatusEntry.vesselText = newStatusEntry.vesselText; playerStatusEntry.statusText = newStatusEntry.statusText; } } if (!found) { playerStatusList.Add(newStatusEntry); DarkLog.Debug("Added " + newStatusEntry.playerName + " to status list"); } } while (removeStatusQueue.Count > 0) { string removeStatusString = removeStatusQueue.Dequeue(); PlayerStatus removeStatus = null; foreach (PlayerStatus currentStatus in playerStatusList) { if (currentStatus.playerName == removeStatusString) { removeStatus = currentStatus; } } if (removeStatus != null) { playerStatusList.Remove(removeStatus); DarkLog.Debug("Removed " + removeStatusString + " from status list"); } else { DarkLog.Debug("Cannot remove non-existant player " + removeStatusString); } } } }
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; }