Exemplo n.º 1
0
        public void TimingManagerFixedUpdate()
        {
            long startClock = Profiler.DMPReferenceTime.ElapsedTicks;

            if (modDisabled)
            {
                return;
            }

            dmpModInterface.FixedUpdate();

            if (dmpGame != null)
            {
                foreach (Action fixedUpdateAction in dmpGame.fixedUpdateEvent)
                {
                    try
                    {
                        fixedUpdateAction();
                    }
                    catch (Exception e)
                    {
                        DarkLog.Debug("Threw in FixedUpdate event, exception: " + e);
                        if (dmpGame.networkWorker != null)
                        {
                            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!");
                                }
                            }
                        }
                    }
                }
            }
            Profiler.fixedUpdateData.ReportTime(startClock);
        }
Exemplo n.º 2
0
        public Client()
        {
            //Fix DarkLog time/thread marker in the log during init.
            DarkLog.SetMainThread();
            lastClockTicks           = DateTime.UtcNow.Ticks;
            lastRealTimeSinceStartup = Time.realtimeSinceStartup;

            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();
        }
Exemplo n.º 3
0
        public void BuildDllFileList()
        {
            dllList = new Dictionary <string, string>();
            string[] checkList = Directory.GetFiles(Path.Combine(KSPUtil.ApplicationRootPath, "GameData"), "*", SearchOption.AllDirectories);

            foreach (string checkFile in checkList)
            {
                //Only check DLL's
                if (checkFile.ToLower().EndsWith(".dll"))
                {
                    //We want the relative path to check against, example: DarkMultiPlayer/Plugins/DarkMultiPlayer.dll
                    //Strip off everything from GameData
                    //Replace windows backslashes with mac/linux forward slashes.
                    //Make it lowercase so we don't worry about case sensitivity.
                    string relativeFilePath = checkFile.ToLowerInvariant().Substring(checkFile.ToLowerInvariant().IndexOf("gamedata") + 9).Replace('\\', '/');
                    string fileHash         = Common.CalculateSHA256Hash(checkFile);
                    dllList.Add(relativeFilePath, fileHash);
                    DarkLog.Debug("Hashed file: " + relativeFilePath + ", hash: " + fileHash);
                }
            }
        }
Exemplo n.º 4
0
 public void SetVesselRanges(Vessel v)
 {
     if (!workerEnabled)
     {
         return;
     }
     ReportVesselUpdate(v.id);
     if (v != null)
     {
         DarkLog.Debug("Setting vessel " + v.id + " to bumped ranges");
         bumpedVessels[v.id]          = Client.realtimeSinceStartup;
         v.vesselRanges.flying.unpack = BUMP_FLYING_LOAD_DISTANCE;
         v.vesselRanges.flying.load   = BUMP_FLYING_LOAD_DISTANCE + 1000f;
         v.vesselRanges.flying.pack   = BUMP_FLYING_LOAD_DISTANCE + 2000f;
         v.vesselRanges.flying.unload = BUMP_FLYING_LOAD_DISTANCE + 3000f;
         v.vesselRanges.landed.unpack = BUMP_LANDED_LOAD_DISTANCE;
         v.vesselRanges.landed.load   = BUMP_LANDED_LOAD_DISTANCE + 1000f;
         v.vesselRanges.landed.pack   = BUMP_LANDED_LOAD_DISTANCE + 2000f;
         v.vesselRanges.landed.unload = BUMP_LANDED_LOAD_DISTANCE + 3000f;
     }
 }
Exemplo n.º 5
0
 private void JoinChannel(string commandArgs)
 {
     if (commandArgs != "" && commandArgs != "Global" && commandArgs != consoleIdentifier)
     {
         DarkLog.Debug("Joining channel " + commandArgs);
         joinedChannels.Add(commandArgs);
         selectedChannel   = commandArgs;
         selectedPMChannel = null;
         using (MessageWriter mw = new MessageWriter())
         {
             mw.Write <int>((int)ChatMessageType.JOIN);
             mw.Write <string>(Settings.fetch.playerName);
             mw.Write <string>(commandArgs);
             NetworkWorker.fetch.SendChatMessage(mw.GetMessageBytes());
         }
     }
     else
     {
         ScreenMessages.PostScreenMessage("Couln't join '" + commandArgs + "', channel name not valid!");
     }
 }
Exemplo n.º 6
0
 /// <summary>
 /// Sends a DMP mod message.
 /// </summary>
 /// <param name="modName">Mod name</param>
 /// <param name="messageData">The message payload (MessageWriter can make this easier)</param>
 /// <param name="relay">If set to <c>true</c>, The server will relay the message to all other authenticated clients</param>
 /// <param name="highPriority">If set to <c>true</c>, DMP will send this in the high priority queue (Which will send before all vessel updates and screenshots)</param>
 public void SendDMPModMessage(string modName, byte[] messageData, bool relay, bool highPriority)
 {
     if (modName == null)
     {
         //Now that's just being silly :)
         return;
     }
     if (messageData == null)
     {
         DarkLog.Debug(modName + " attemped to send a null message");
         return;
     }
     using (MessageWriter mw = new MessageWriter())
     {
         mw.Write <string>(modName);
         mw.Write <bool>(relay);
         mw.Write <bool>(highPriority);
         mw.Write <byte[]>(messageData);
         networkWorker.SendModMessage(mw.GetMessageBytes(), highPriority);
     }
 }
Exemplo n.º 7
0
        private void StartGame()
        {
            //Create new game object for our DMP session.
            HighLogic.CurrentGame = CreateBlankGame();

            //Set the game mode
            SetGameMode();

//             //Found in KSP's files. Makes a crapton of sense :)
//             if (HighLogic.CurrentGame.Mode != Game.Modes.SANDBOX)
//             {
//                 HighLogic.CurrentGame.Parameters.Difficulty.AllowStockVessels = false;
//             }
//             HighLogic.CurrentGame.flightState.universalTime = TimeSyncer.Instance.GetUniverseTime();
//
//             //Load DMP stuff
//             VesselWorker.Instance.LoadKerbalsIntoGame();
//             VesselWorker.Instance.LoadVesselsIntoGame();
//
//             //Load the scenarios from the server
//             ScenarioWorker.Instance.LoadScenarioDataIntoGame();
//
//             //Load the missing scenarios as well (Eg, Contracts and stuff for career mode
//             ScenarioWorker.Instance.LoadMissingScenarioDataIntoGame();
//
//             //This only makes KSP complain
//             HighLogic.CurrentGame.CrewRoster.ValidateAssignments(HighLogic.CurrentGame);
//             DarkLog.Debug("Starting " + gameMode + " game...");
//
//             //Control locks will bug out the space centre sceen, so remove them before starting.
//             DeleteAllTheControlLocksSoTheSpaceCentreBugGoesAway();
//
//             //.Start() seems to stupidly .Load() somewhere - Let's overwrite it so it loads correctly.
//             GamePersistence.SaveGame(HighLogic.CurrentGame, "persistent", HighLogic.SaveFolder, SaveMode.OVERWRITE);
//             HighLogic.CurrentGame.Start();
//             ChatWorker.Instance.display = true;

            throw new NotImplementedException();
            DarkLog.Debug("Started!");
        }
Exemplo n.º 8
0
 private void DeleteCraftEntry(string playerName, CraftType craftType, string craftName)
 {
     if (playerList.ContainsKey(playerName))
     {
         if (playerList[playerName].ContainsKey(craftType))
         {
             if (playerList[playerName][craftType].Contains(craftName))
             {
                 playerList[playerName][craftType].Remove(craftName);
                 if (playerList[playerName][craftType].Count == 0)
                 {
                     playerList[playerName].Remove(craftType);
                 }
                 if (playerList[playerName].Count == 0)
                 {
                     if (playerName != dmpSettings.playerName)
                     {
                         playerList.Remove(playerName);
                         if (playersWithCrafts.Contains(playerName))
                         {
                             playersWithCrafts.Remove(playerName);
                         }
                     }
                 }
             }
             else
             {
                 DarkLog.Debug("Cannot remove craft entry " + craftName + " for player " + playerName + ", craft does not exist");
             }
         }
         else
         {
             DarkLog.Debug("Cannot remove craft entry " + craftName + " for player " + playerName + ", player does not have any " + craftType + " entries");
         }
     }
     else
     {
         DarkLog.Debug("Cannot remove craft entry " + craftName + " for player " + playerName + ", no player entry");
     }
 }
Exemplo n.º 9
0
        public void HandlePlayerColorMessage(byte[] messageData)
        {
            using (MessageReader mr = new MessageReader(messageData))
            {
                PlayerColorMessageType messageType = (PlayerColorMessageType)mr.Read <int>();
                switch (messageType)
                {
                case PlayerColorMessageType.LIST:
                {
                    int numOfEntries = mr.Read <int>();
                    lock (playerColorLock)
                    {
                        playerColors = new Dictionary <string, Color>();
                        for (int i = 0; i < numOfEntries; i++)
                        {
                            string playerName  = mr.Read <string>();
                            Color  playerColor = ConvertFloatArrayToColor(mr.Read <float[]>());
                            playerColors.Add(playerName, playerColor);
                            playerStatusWindow.colorEventHandled = false;
                        }
                    }
                }
                break;

                case PlayerColorMessageType.SET:
                {
                    lock (playerColorLock)
                    {
                        string playerName  = mr.Read <string>();
                        Color  playerColor = ConvertFloatArrayToColor(mr.Read <float[]>());
                        DarkLog.Debug("Color message, name: " + playerName + " , color: " + playerColor.ToString());
                        playerColors[playerName] = playerColor;
                        UpdateAllVesselColors();
                        playerStatusWindow.colorEventHandled = false;
                    }
                }
                break;
                }
            }
        }
Exemplo n.º 10
0
        private void UploadCraftFile(CraftType type, string name)
        {
            string uploadPath = "";

            switch (uploadCraftType)
            {
            case CraftType.VAB:
                uploadPath = vabPath;
                break;

            case CraftType.SPH:
                uploadPath = sphPath;
                break;

            case CraftType.SUBASSEMBLY:
                uploadPath = subassemblyPath;
                break;
            }
            string filePath = Path.Combine(uploadPath, name + ".craft");

            if (File.Exists(filePath))
            {
                byte[] fileData = File.ReadAllBytes(filePath);
                using (MessageWriter mw = new MessageWriter())
                {
                    mw.Write <int>((int)CraftMessageType.UPLOAD_FILE);
                    mw.Write <string>(dmpSettings.playerName);
                    mw.Write <int>((int)type);
                    mw.Write <string>(name);
                    mw.Write <byte[]>(fileData);
                    networkWorker.SendCraftLibraryMessage(mw.GetMessageBytes());
                    AddCraftEntry(dmpSettings.playerName, uploadCraftType, uploadCraftName);
                    displayCraftUploadingMessage = true;
                }
            }
            else
            {
                DarkLog.Debug("Cannot upload file, " + filePath + " does not exist!");
            }
        }
Exemplo n.º 11
0
 private void OnVesselCreate(Vessel vessel)
 {
     //Kerbals are put in the vessel *after* OnVesselCreate. Thanks squad!.
     if (vesselToKerbal.ContainsKey(vessel.id))
     {
         OnVesselDestroyed(vessel);
     }
     if (vessel.GetCrewCount() > 0)
     {
         vesselToKerbal.Add(vessel.id, new List <string>());
         foreach (ProtoCrewMember pcm in vessel.GetVesselCrew())
         {
             vesselToKerbal[vessel.id].Add(pcm.name);
             if (kerbalToVessel.ContainsKey(pcm.name) && kerbalToVessel[pcm.name] != vessel.id)
             {
                 DarkLog.Debug("Warning, kerbal double take on " + vessel.id + " ( " + vessel.name + " )");
             }
             kerbalToVessel[pcm.name] = vessel.id;
             DarkLog.Debug("OVC " + pcm.name + " belongs to " + vessel.id);
         }
     }
 }
Exemplo n.º 12
0
        //Defends against bug #172
        private void RemoveKerbalRescueMissionsSoTheGameDoesntBugOut(ConfigNode contractSystemNode)
        {
            ConfigNode        contractsNode     = contractSystemNode.GetNode("CONTRACTS");
            List <ConfigNode> filteredContracts = new List <ConfigNode>();

            foreach (ConfigNode contractNode in contractsNode.GetNodes("CONTRACT"))
            {
                if (contractNode.GetValue("type") != "RescueKerbal")
                {
                    filteredContracts.Add(contractNode);
                }
                else
                {
                    DarkLog.Debug("Skipped RescueKerbal contract - Causes bug #172");
                }
            }
            contractsNode.ClearNodes();
            foreach (ConfigNode contractNode in filteredContracts)
            {
                contractsNode.AddNode(contractNode);
            }
        }
Exemplo n.º 13
0
 private void OnVesselCreate(Vessel checkVessel)
 {
     if (workerEnabled)
     {
         if (VesselIsAsteroid(checkVessel))
         {
             lock (serverAsteroidListLock)
             {
                 if (LockSystem.fetch.LockIsOurs("asteroid-spawning"))
                 {
                     if (!serverAsteroids.Contains(checkVessel.id.ToString()))
                     {
                         if (GetAsteroidCount() <= maxNumberOfUntrackedAsteroids)
                         {
                             DarkLog.Debug("Spawned in new server asteroid!");
                             serverAsteroids.Add(checkVessel.id.ToString());
                             VesselWorker.fetch.RegisterServerVessel(checkVessel.id);
                             NetworkWorker.fetch.SendVesselProtoMessage(checkVessel.protoVessel, false, false);
                             NetworkWorker.fetch.SendVesselPermissions(PermissionsManager.GenerateAsteroidPermissions(checkVessel.protoVessel));
                         }
                         else
                         {
                             DarkLog.Debug("Killing non-server asteroid " + checkVessel.id);
                             checkVessel.Die();
                         }
                     }
                 }
                 else
                 {
                     if (!serverAsteroids.Contains(checkVessel.id.ToString()))
                     {
                         DarkLog.Debug("Killing non-server asteroid " + checkVessel.id + ", we don't own the asteroid-spawning lock");
                         checkVessel.Die();
                     }
                 }
             }
         }
     }
 }
 //Defends against bug #172
 private void CreateMissingKerbalsInProgressTrackingSoTheGameDoesntBugOut(ConfigNode progressTrackingNode)
 {
     foreach (ConfigNode possibleNode in progressTrackingNode.nodes)
     {
         //Recursion (noun): See Recursion.
         CreateMissingKerbalsInProgressTrackingSoTheGameDoesntBugOut(possibleNode);
     }
     //The kerbals are kept in a ConfigNode named 'crew', with 'crews' as a comma space delimited array of names.
     if (progressTrackingNode.name == "crew")
     {
         string kerbalNames = progressTrackingNode.GetValue("crews");
         if (!String.IsNullOrEmpty(kerbalNames))
         {
             string[] kerbalNamesSplit = kerbalNames.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries);
             foreach (string kerbalName in kerbalNamesSplit)
             {
                 if (!HighLogic.CurrentGame.CrewRoster.Exists(kerbalName))
                 {
                     if (AddCrewMemberToRoster == null)
                     {
                         MethodInfo addMemberToCrewRosterMethod = typeof(KerbalRoster).GetMethod("AddCrewMember", BindingFlags.NonPublic | BindingFlags.Instance);
                         AddCrewMemberToRoster = (AddCrewMemberToRosterDelegate)Delegate.CreateDelegate(typeof(AddCrewMemberToRosterDelegate), HighLogic.CurrentGame.CrewRoster, addMemberToCrewRosterMethod);
                     }
                     if (AddCrewMemberToRoster == null)
                     {
                         throw new Exception("Failed to initialize AddCrewMemberToRoster for #172 ProgressTracking fix.");
                     }
                     DarkLog.Debug("Generating missing kerbal from ProgressTracking: " + kerbalName);
                     ProtoCrewMember pcm = CrewGenerator.RandomCrewMemberPrototype(ProtoCrewMember.KerbalType.Crew);
                     pcm.name = kerbalName;
                     AddCrewMemberToRoster(pcm);
                     //Also send it off to the server
                     NetworkWorker.fetch.SendKerbalProtoMessage(pcm);
                 }
             }
         }
     }
 }
Exemplo n.º 15
0
 private void ReleaseWarpMaster()
 {
     if (warpMaster == dmpSettings.playerName)
     {
         SendNewSubspace();
     }
     warpMaster           = "";
     voteSent             = false;
     voteMaster           = "";
     voteYesCount         = 0;
     voteNoCount          = 0;
     controllerExpireTime = double.NegativeInfinity;
     using (MessageWriter mw = new MessageWriter())
     {
         mw.Write <int>((int)WarpMessageType.RELEASE_CONTROLLER);
         networkWorker.SendWarpMessage(mw.GetMessageBytes());
     }
     if (TimeWarp.CurrentRateIndex > 0)
     {
         DarkLog.Debug("Resetting warp rate back to 0");
         TimeWarp.SetRate(0, true);
     }
 }
Exemplo n.º 16
0
 public void LoadScenarioDataIntoGame()
 {
     while (scenarioQueue.Count > 0)
     {
         LoadScenarioData(scenarioQueue.Dequeue());
     }
     if (!loadedScience && Client.fetch.gameMode == GameMode.CAREER)
     {
         DarkLog.Debug("Creating new science data");
         ConfigNode          newNode   = GetBlankResearchAndDevelopmentNode();
         ProtoScenarioModule newModule = new ProtoScenarioModule(newNode);
         try
         {
             HighLogic.CurrentGame.scenarios.Add(newModule);
             newModule.Load(ScenarioRunner.fetch);
         }
         catch
         {
             DarkLog.Debug("Error loading new science data!");
             blockScenarioDataSends = true;
         }
     }
 }
Exemplo n.º 17
0
        private void HandleCommandLineArgs()
        {
            bool   nextLineIsAddress = false;
            bool   valid             = false;
            string address           = null;
            int    port = 0;

            foreach (string commandLineArg in Environment.GetCommandLineArgs())
            {
                //Supporting IPv6 is FUN!
                if (nextLineIsAddress)
                {
                    valid = CommandLineParser.ParseIp(commandLineArg, out address, out port);
                    if (port == 0)
                    {
                        port = 6702;
                    }
                    nextLineIsAddress = 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);
            }
        }
Exemplo n.º 18
0
 public void EnableToolbar()
 {
     buttonTexture = GameDatabase.Instance.GetTexture("DarkMultiPlayer/Button/DMPButton", false);
     if (registered)
     {
         DarkLog.Debug("Cannot re-register toolbar");
         return;
     }
     registered = true;
     if (dmpSettings.toolbarType == DMPToolbarType.DISABLED)
     {
         //Nothing!
     }
     if (dmpSettings.toolbarType == DMPToolbarType.FORCE_STOCK)
     {
         EnableStockToolbar();
     }
     if (dmpSettings.toolbarType == DMPToolbarType.BLIZZY_IF_INSTALLED)
     {
         if (ToolbarManager.ToolbarAvailable)
         {
             EnableBlizzyToolbar();
         }
         else
         {
             EnableStockToolbar();
         }
     }
     if (dmpSettings.toolbarType == DMPToolbarType.BOTH_IF_INSTALLED)
     {
         if (ToolbarManager.ToolbarAvailable)
         {
             EnableBlizzyToolbar();
         }
         EnableStockToolbar();
     }
 }
Exemplo n.º 19
0
        private void StartGame()
        {
            //Create new game object for our DMP session.
            HighLogic.CurrentGame = CreateBlankGame();

            //Set the game mode
            HighLogic.CurrentGame.Mode = ConvertGameMode(gameMode);

            //Set difficulty
            HighLogic.CurrentGame.Parameters = serverParameters;

            //Set universe time
            HighLogic.CurrentGame.flightState.universalTime = TimeSyncer.fetch.GetUniverseTime();

            //Load DMP stuff
            VesselWorker.fetch.LoadKerbalsIntoGame();
            VesselWorker.fetch.LoadVesselsIntoGame();

            //Load the scenarios from the server
            ScenarioWorker.fetch.LoadScenarioDataIntoGame();

            //Load the missing scenarios as well (Eg, Contracts and stuff for career mode
            ScenarioWorker.fetch.LoadMissingScenarioDataIntoGame();

            //This only makes KSP complain
            HighLogic.CurrentGame.CrewRoster.ValidateAssignments(HighLogic.CurrentGame);
            DarkLog.Debug("Starting " + gameMode + " game...");

            //Control locks will bug out the space centre sceen, so remove them before starting.
            DeleteAllTheControlLocksSoTheSpaceCentreBugGoesAway();

            //.Start() seems to stupidly .Load() somewhere - Let's overwrite it so it loads correctly.
            GamePersistence.SaveGame(HighLogic.CurrentGame, "persistent", HighLogic.SaveFolder, SaveMode.OVERWRITE);
            HighLogic.CurrentGame.Start();
            ChatWorker.fetch.display = true;
            DarkLog.Debug("Started!");
        }
Exemplo n.º 20
0
        public void Start()
        {
            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();
            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!");
        }
Exemplo n.º 21
0
        private void CheckWarp()
        {
            bool resetWarp = true;

            if ((warpMode == WarpMode.MCW_FORCE) || (warpMode == WarpMode.MCW_VOTE) || (warpMode == WarpMode.MCW_LOWEST))
            {
                if (warpMaster != "")
                {
                    //It could be us or another player. If it's another player it will be controlled from Update() instead.
                    resetWarp = false;
                }
            }
            if (warpMode == WarpMode.SUBSPACE)
            {
                //Never reset warp in SUBSPACE mode.
                resetWarp = false;
            }
            if (warpMode == WarpMode.SUBSPACE_SIMPLE && canSubspaceSimpleWarp)
            {
                resetWarp = false;
            }
            if ((TimeWarp.CurrentRateIndex > 0) && resetWarp)
            {
                //DarkLog.Debug("Resetting warp rate back to 0");
                TimeWarp.SetRate(0, true);
            }
            if ((TimeWarp.CurrentRateIndex > 0) && (TimeWarp.CurrentRate > 1.1f) && !resetWarp && timeSyncer.locked)
            {
                DarkLog.Debug("Unlocking from subspace");
                timeSyncer.UnlockSubspace();
            }
            if ((TimeWarp.CurrentRateIndex == 0) && (TimeWarp.CurrentRate < 1.1f) && !timeSyncer.locked && ((warpMode == WarpMode.SUBSPACE) || (warpMode == WarpMode.SUBSPACE_SIMPLE)) && (timeSyncer.currentSubspace == -1))
            {
                SendNewSubspace();
            }
        }
Exemplo n.º 22
0
        private void OnVesselWillDestroy(Vessel vessel)
        {
            bool pilotedByAnotherPlayer = lockSystem.LockExists("control-" + vessel.id) && !lockSystem.LockIsOurs("control-" + vessel.id);
            bool updatedByAnotherPlayer = lockSystem.LockExists("update-" + vessel.id) && !lockSystem.LockIsOurs("update-" + vessel.id);
            bool updatedInTheFuture     = vesselWorker.VesselUpdatedInFuture(vessel.id);

            //Vessel was packed within the last 5 seconds
            if (lastPackTime.ContainsKey(vessel.id) && (Client.realtimeSinceStartup - lastPackTime[vessel.id]) < 5f)
            {
                lastPackTime.Remove(vessel.id);
                if (vessel.situation == Vessel.Situations.FLYING && (pilotedByAnotherPlayer || updatedByAnotherPlayer || updatedInTheFuture))
                {
                    DarkLog.Debug("Hacky load: Saving player vessel getting packed in atmosphere");
                    ProtoVessel pv        = vessel.BackupVessel();
                    ConfigNode  savedNode = new ConfigNode();
                    pv.Save(savedNode);
                    vesselWorker.LoadVessel(savedNode, vessel.id, true);
                }
            }
            if (lastPackTime.ContainsKey(vessel.id))
            {
                lastPackTime.Remove(vessel.id);
            }
        }
Exemplo n.º 23
0
 //WARNING: Called from NetworkWorker.
 public void StartGame()
 {
     HighLogic.CurrentGame             = new Game();
     HighLogic.CurrentGame.flightState = new FlightState();
     HighLogic.CurrentGame.CrewRoster  = new CrewRoster();
     HighLogic.CurrentGame.scenarios   = new List <ProtoScenarioModule>();
     HighLogic.CurrentGame.startScene  = GameScenes.SPACECENTER;
     HighLogic.CurrentGame.flagURL     = Settings.fetch.selectedFlag;
     HighLogic.CurrentGame.Title       = "DarkMultiPlayer";
     HighLogic.CurrentGame.Parameters.Flight.CanQuickLoad = false;
     HighLogic.SaveFolder = "DarkMultiPlayer";
     HighLogic.CurrentGame.flightState.universalTime = TimeSyncer.fetch.GetUniverseTime();
     SetGameMode();
     ScenarioWorker.fetch.LoadScenarioDataIntoGame();
     AsteroidWorker.fetch.LoadAsteroidScenario();
     VesselWorker.fetch.LoadKerbalsIntoGame();
     VesselWorker.fetch.LoadVesselsIntoGame();
     DarkLog.Debug("Starting " + gameMode + " game...");
     HighLogic.CurrentGame.Start();
     DarkLog.Debug("Started!");
     Planetarium.SetUniversalTime(TimeSyncer.fetch.GetUniverseTime());
     GamePersistence.SaveGame("persistent", HighLogic.SaveFolder, SaveMode.OVERWRITE);
     ChatWorker.fetch.display = true;
 }
Exemplo n.º 24
0
        public void OnGUI()
        {
            //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
            long startClock = Profiler.DMPReferenceTime.ElapsedTicks;

            if (showGUI)
            {
                foreach (Action drawAction in drawEvent)
                {
                    try
                    {
                        // Don't hide the ConnectionWindow if we disabled DMP GUI
                        if (toolbarShowGUI || (!toolbarShowGUI && drawAction.Target.ToString() == "DarkMultiPlayer.ConnectionWindow"))
                        {
                            drawAction();
                        }
                    }
                    catch (Exception e)
                    {
                        DarkLog.Debug("Threw in OnGUI event, exception: " + e);
                    }
                }
            }
            Profiler.guiData.ReportTime(startClock);
        }
Exemplo n.º 25
0
        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);
                    }
                }
            }
        }
Exemplo n.º 26
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();
        }
Exemplo n.º 27
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;
                }
                }
            }
        }
Exemplo n.º 28
0
        public static VesselUpdate CopyFromVessel(VesselWorker vesselWorker, Vessel updateVessel)
        {
            VesselUpdate returnUpdate = new VesselUpdate(vesselWorker);

            try
            {
                returnUpdate.vesselID   = updateVessel.id;
                returnUpdate.planetTime = Planetarium.GetUniversalTime();
                returnUpdate.bodyName   = updateVessel.mainBody.bodyName;

                returnUpdate.rotation    = new float[4];
                returnUpdate.rotation[0] = updateVessel.srfRelRotation.x;
                returnUpdate.rotation[1] = updateVessel.srfRelRotation.y;
                returnUpdate.rotation[2] = updateVessel.srfRelRotation.z;
                returnUpdate.rotation[3] = updateVessel.srfRelRotation.w;

                returnUpdate.angularVelocity    = new float[3];
                returnUpdate.angularVelocity[0] = updateVessel.angularVelocity.x;
                returnUpdate.angularVelocity[1] = updateVessel.angularVelocity.y;
                returnUpdate.angularVelocity[2] = updateVessel.angularVelocity.z;
                //Flight state
                returnUpdate.flightState = new FlightCtrlState();
                returnUpdate.flightState.CopyFrom(updateVessel.ctrlState);
                returnUpdate.actiongroupControls    = new bool[5];
                returnUpdate.actiongroupControls[0] = updateVessel.ActionGroups[KSPActionGroup.Gear];
                returnUpdate.actiongroupControls[1] = updateVessel.ActionGroups[KSPActionGroup.Light];
                returnUpdate.actiongroupControls[2] = updateVessel.ActionGroups[KSPActionGroup.Brakes];
                returnUpdate.actiongroupControls[3] = updateVessel.ActionGroups[KSPActionGroup.SAS];
                returnUpdate.actiongroupControls[4] = updateVessel.ActionGroups[KSPActionGroup.RCS];

                if (updateVessel.altitude < 10000)
                {
                    //Use surface position under 10k
                    returnUpdate.isSurfaceUpdate = true;
                    returnUpdate.position        = new double[4];
                    returnUpdate.position[0]     = updateVessel.latitude;
                    returnUpdate.position[1]     = updateVessel.longitude;
                    returnUpdate.position[2]     = updateVessel.altitude;
                    VesselUtil.DMPRaycastPair groundRaycast = VesselUtil.RaycastGround(updateVessel.latitude, updateVessel.longitude, updateVessel.mainBody);
                    returnUpdate.position[3]      = groundRaycast.altitude;
                    returnUpdate.terrainNormal    = new float[3];
                    returnUpdate.terrainNormal[0] = groundRaycast.terrainNormal.x;
                    returnUpdate.terrainNormal[1] = groundRaycast.terrainNormal.y;
                    returnUpdate.terrainNormal[2] = groundRaycast.terrainNormal.z;
                    returnUpdate.velocity         = new double[3];
                    Vector3d srfVel = Quaternion.Inverse(updateVessel.mainBody.bodyTransform.rotation) * updateVessel.srf_velocity;
                    returnUpdate.velocity[0]  = srfVel.x;
                    returnUpdate.velocity[1]  = srfVel.y;
                    returnUpdate.velocity[2]  = srfVel.z;
                    returnUpdate.acceleration = new double[3];
                    Vector3d srfAcceleration = Quaternion.Inverse(updateVessel.mainBody.bodyTransform.rotation) * updateVessel.acceleration;
                    returnUpdate.acceleration[0] = srfAcceleration.x;
                    returnUpdate.acceleration[1] = srfAcceleration.y;
                    returnUpdate.acceleration[2] = srfAcceleration.z;
                }
                else
                {
                    //Use orbital positioning over 10k
                    returnUpdate.isSurfaceUpdate = false;
                    returnUpdate.orbit           = new double[7];
                    returnUpdate.orbit[0]        = updateVessel.orbit.inclination;
                    returnUpdate.orbit[1]        = updateVessel.orbit.eccentricity;
                    returnUpdate.orbit[2]        = updateVessel.orbit.semiMajorAxis;
                    returnUpdate.orbit[3]        = updateVessel.orbit.LAN;
                    returnUpdate.orbit[4]        = updateVessel.orbit.argumentOfPeriapsis;
                    returnUpdate.orbit[5]        = updateVessel.orbit.meanAnomalyAtEpoch;
                    returnUpdate.orbit[6]        = updateVessel.orbit.epoch;
                }
                returnUpdate.sasEnabled = updateVessel.Autopilot.Enabled;
                if (returnUpdate.sasEnabled)
                {
                    returnUpdate.autopilotMode     = (int)updateVessel.Autopilot.Mode;
                    returnUpdate.lockedRotation    = new float[4];
                    returnUpdate.lockedRotation[0] = updateVessel.Autopilot.SAS.lockedRotation.x;
                    returnUpdate.lockedRotation[1] = updateVessel.Autopilot.SAS.lockedRotation.y;
                    returnUpdate.lockedRotation[2] = updateVessel.Autopilot.SAS.lockedRotation.z;
                    returnUpdate.lockedRotation[3] = updateVessel.Autopilot.SAS.lockedRotation.w;
                }
            }
            catch (Exception e)
            {
                DarkLog.Debug("Failed to get vessel update, exception: " + e);
                returnUpdate = null;
            }
            return(returnUpdate);
        }
Exemplo n.º 29
0
        public bool ParseModFile(string modFileData)
        {
            if (!modControl)
            {
                return(true);
            }
            bool modCheckOk = true;

            //Save mod file so we can recheck it.
            lastModFileData = modFileData;
            //Err...
            string tempModFilePath = Path.Combine(Path.Combine(Path.Combine(Path.Combine(Path.Combine(KSPUtil.ApplicationRootPath, "GameData"), "DarkMultiPlayer"), "Plugins"), "Data"), "DMPModControl.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("#") || String.IsNullOrEmpty(trimmedLine))
                    {
                        //Skip comments or empty lines.
                        continue;
                    }
                    if (trimmedLine.StartsWith("!"))
                    {
                        //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;
                        }
                    }
                    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"))
                            {
                                if (parseWhiteBlackList.Contains(lowerFixedLine))
                                {
                                    parseWhiteBlackList.Add(lowerFixedLine);
                                }
                            }
                        }
                        break;

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

            string[]      currentGameDataFiles       = Directory.GetFiles(Path.Combine(KSPUtil.ApplicationRootPath, "GameData"), "*", 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") + 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"))
                {
                    //Protect against windows-style entries in DMPModControl.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(Path.Combine(KSPUtil.ApplicationRootPath, "GameData"), 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"))
                {
                    //Protect against windows-style entries in DMPModControl.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(Path.Combine(KSPUtil.ApplicationRootPath, "GameData"), 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");
                autoAllowed.Add("darkmultiplayer/plugins/messagewriter.dll");
                foreach (KeyValuePair <string, string> dllResource in dllList)
                {
                    //Allow DMP files
                    if (autoAllowed.Contains(dllResource.Key))
                    {
                        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.fetch.display = true;
                return(false);
            }
            allowedParts = parsePartsList;
            DarkLog.Debug("Mod check passed!");
            return(true);
        }
Exemplo n.º 30
0
        public void GenerateModControlFile(bool whitelistMode)
        {
            string gameDataDir = Path.Combine(KSPUtil.ApplicationRootPath, "GameData");

            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") + 9).ToLower();
                if (lowerDirectoryName.StartsWith("squad"))
                {
                    continue;
                }
                if (lowerDirectoryName.StartsWith("nasamission"))
                {
                    continue;
                }
                if (lowerDirectoryName.StartsWith("darkmultiplayer"))
                {
                    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") + 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(KSPUtil.ApplicationRootPath, "DMPModControl.txt");

            using (StreamWriter sw = new StreamWriter(saveModFile, false))
            {
                sw.Write(modFileData);
            }
            ScreenMessages.PostScreenMessage("DMPModFile.txt file generated in your KSP folder", 5f, ScreenMessageStyle.UPPER_CENTER);
        }