예제 #1
0
파일: Main.cs 프로젝트: CHazz/DUXDMP
        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);
                    }
                }
            }
        }
예제 #3
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;
        }