Exemplo n.º 1
0
 public void LoadScenarioDataIntoGame()
 {
     lock (scenarioQueue)
     {
         while (scenarioQueue.Count > 0)
         {
             ScenarioEntry scenarioEntry = scenarioQueue.Dequeue();
             if (scenarioEntry.scenarioName == "ProgressTracking")
             {
                 CreateMissingKerbalsInProgressTrackingSoTheGameDoesntBugOut(scenarioEntry.scenarioNode);
             }
             CheckForBlankSceneSoTheGameDoesntBugOut(scenarioEntry);
             ProtoScenarioModule psm = new ProtoScenarioModule(scenarioEntry.scenarioNode);
             if (psm != null)
             {
                 if (IsScenarioModuleAllowed(psm.moduleName))
                 {
                     DarkLog.Debug("Loading " + psm.moduleName + " scenario data");
                     HighLogic.CurrentGame.scenarios.Add(psm);
                     ByteArray scenarioHashBytes = configNodeSerializer.Serialize(scenarioEntry.scenarioNode);
                     checkData[scenarioEntry.scenarioName] = Common.CalculateSHA256Hash(scenarioHashBytes);
                     ByteRecycler.ReleaseObject(scenarioHashBytes);
                 }
                 else
                 {
                     DarkLog.Debug("Skipping " + psm.moduleName + " scenario data in " + dmpGame.gameMode + " mode");
                 }
             }
         }
     }
 }
Exemplo n.º 2
0
 public void ProcessWarpMessages()
 {
     lock (newWarpMessages)
     {
         while (newWarpMessages.Count > 0)
         {
             ByteArray queueByteArray = newWarpMessages.Dequeue();
             HandleWarpMessage(queueByteArray.data);
             ByteRecycler.ReleaseObject(queueByteArray);
         }
     }
 }
Exemplo n.º 3
0
 private void ProcessMessages()
 {
     lock (messageQueue)
     {
         while (messageQueue.Count > 0)
         {
             ByteArray queueByteArray = messageQueue.Dequeue();
             HandleMessage(queueByteArray.data);
             ByteRecycler.ReleaseObject(queueByteArray);
         }
     }
 }
Exemplo n.º 4
0
        private bool DidScenarioChange(ScenarioEntry scenarioEntry)
        {
            string    previousScenarioHash = null;
            ByteArray scenarioBytes        = configNodeSerializer.Serialize(scenarioEntry.scenarioNode);
            string    currentScenarioHash  = Common.CalculateSHA256Hash(scenarioBytes);

            ByteRecycler.ReleaseObject(scenarioBytes);
            if (checkData.TryGetValue(scenarioEntry.scenarioName, out previousScenarioHash))
            {
                return(previousScenarioHash != currentScenarioHash);
            }
            return(true);
        }
 private void ProcessingThreadMain()
 {
     while (true)
     {
         if (incomingQueue.Count == 0)
         {
             incomingEvent.WaitOne(500);
         }
         else
         {
             ByteArray incomingBytes;
             lock (incomingQueue)
             {
                 incomingBytes = incomingQueue.Dequeue();
             }
             SaveToCache(incomingBytes);
             ByteRecycler.ReleaseObject(incomingBytes);
         }
     }
 }
Exemplo n.º 6
0
        public void Update()
        {
            if (playback)
            {
                DisplayUpdateVesselOffset();
                if (Planetarium.GetUniversalTime() > (lastTime))
                {
                    playback = false;
                    ScreenMessages.RemoveMessage(screenMessage);
                    screenMessage = null;
                }
                else
                {
                    int timeLeft = (int)(lastTime - Planetarium.GetUniversalTime());
                    ScreenMessages.RemoveMessage(screenMessage);
                    screenMessage = ScreenMessages.PostScreenMessage("Playback time left: " + timeLeft + " / " + (int)(lastTime - firstTime) + " seconds", float.MaxValue, ScreenMessageStyle.UPPER_CENTER);
                }
            }

            if (active)
            {
                VesselUpdate vu = Recycler <VesselUpdate> .GetObject();

                vu.SetVesselWorker(vesselWorker);
                vu.CopyFromVessel(FlightGlobals.fetch.activeVessel);
                ClientMessage updateBytes = networkWorker.GetVesselUpdateMessage(vu);
                byte[]        lengthBytes = BitConverter.GetBytes(updateBytes.data.Length);
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(lengthBytes);
                }
                recordingVector.Write(lengthBytes, 0, lengthBytes.Length);
                recordingVector.Write(updateBytes.data.data, 0, updateBytes.data.Length);
                ByteRecycler.ReleaseObject(updateBytes.data);
                Recycler <VesselUpdate> .ReleaseObject(vu);
            }
        }
Exemplo n.º 7
0
        public void StartPlayback()
        {
            int       messagesLoaded = 0;
            bool      firstMessage   = true;
            ByteArray headerBytes    = ByteRecycler.GetObject(8);

            using (FileStream fs = new FileStream(recordPath, FileMode.Open))
            {
                while (fs.Position < fs.Length)
                {
                    messagesLoaded++;
                    fs.Read(headerBytes.data, 0, 8);
                    using (MessageReader mr = new MessageReader(headerBytes.data))
                    {
                        ClientMessageType messageType = (ClientMessageType)mr.Read <int>();
                        int       length    = mr.Read <int>();
                        ByteArray dataBytes = ByteRecycler.GetObject(length);
                        fs.Read(dataBytes.data, 0, length);
                        using (MessageReader timeReader = new MessageReader(dataBytes.data))
                        {
                            //Planet time is the first part of the message for the three types we care about here
                            double planetTime = timeReader.Read <double>();
                            lastTime = planetTime;
                            if (firstMessage)
                            {
                                firstTime    = planetTime;
                                firstMessage = false;
                                Planetarium.SetUniversalTime(planetTime - 5d);
                                warpWorker.SendNewSubspace();
                            }
                        }
                        using (MessageReader mrignore = new MessageReader(dataBytes.data))
                        {
                            //Planet time, don't care here
                            mrignore.Read <double>();
                            string vesselID = mrignore.Read <string>();
                            vesselWorker.IgnoreVessel(new Guid(vesselID));
                        }
                        switch (messageType)
                        {
                        case ClientMessageType.VESSEL_PROTO:
                            HandleProtoUpdate(dataBytes);
                            break;

                        case ClientMessageType.VESSEL_UPDATE:
                            HandleVesselUpdate(dataBytes, false);
                            break;

                        case ClientMessageType.VESSEL_REMOVE:
                            HandleVesselRemove(dataBytes);
                            break;

                        default:
                            break;
                        }
                        ByteRecycler.ReleaseObject(dataBytes);
                    }
                }
                ByteRecycler.ReleaseObject(headerBytes);
            }

            playbackQueue = new Queue <VesselUpdate>();
            using (FileStream fs = new FileStream(recordVectorPath, FileMode.Open))
            {
                while (fs.Position < fs.Length)
                {
                    fs.Read(headerBytesInt, 0, 4);
                    if (BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(headerBytesInt);
                    }
                    int       updateLength = BitConverter.ToInt32(headerBytesInt, 0);
                    ByteArray updateBytes  = ByteRecycler.GetObject(updateLength);
                    fs.Read(updateBytes.data, 0, updateLength);
                    VesselUpdate vu = networkWorker.VeselUpdateFromBytes(updateBytes.data, false);
                    playbackQueue.Enqueue(vu);
                    ByteRecycler.ReleaseObject(updateBytes);
                }
            }

            ScreenMessages.PostScreenMessage("Loaded " + messagesLoaded + " saved updates.", 5f, ScreenMessageStyle.UPPER_CENTER);
            screenMessage = ScreenMessages.PostScreenMessage("Playback 0 / " + (int)(lastTime - firstTime) + " seconds.", float.MaxValue, ScreenMessageStyle.UPPER_CENTER);
            playback      = true;
        }
Exemplo n.º 8
0
        public void LoadScenarioData(ScenarioEntry entry)
        {
            if (!IsScenarioModuleAllowed(entry.scenarioName))
            {
                DarkLog.Debug("Skipped '" + entry.scenarioName + "' scenario data  in " + dmpGame.gameMode + " mode");
                return;
            }
            //Load data from DMP
            if (entry.scenarioNode == null)
            {
                DarkLog.Debug(entry.scenarioName + " scenario data failed to create a ConfigNode!");
                ScreenMessages.PostScreenMessage("Scenario " + entry.scenarioName + " failed to load, blocking scenario uploads.", 10f, ScreenMessageStyle.UPPER_CENTER);
                blockScenarioDataSends = true;
                return;
            }

            //Load data into game
            if (DidScenarioChange(entry))
            {
                bool      loaded        = false;
                ByteArray scenarioBytes = configNodeSerializer.Serialize(entry.scenarioNode);
                checkData[entry.scenarioName] = Common.CalculateSHA256Hash(scenarioBytes);
                ByteRecycler.ReleaseObject(scenarioBytes);
                foreach (ProtoScenarioModule psm in HighLogic.CurrentGame.scenarios)
                {
                    if (psm.moduleName == entry.scenarioName)
                    {
                        DarkLog.Debug("Loading existing " + entry.scenarioName + " scenario module");
                        try
                        {
                            if (psm.moduleRef == null)
                            {
                                DarkLog.Debug("Fixing null scenario module!");
                                psm.moduleRef = new ScenarioModule();
                            }
                            bool skipLoad = false;
                            if (beforeCallback.ContainsKey(psm.moduleName))
                            {
                                skipLoad = beforeCallback[psm.moduleName](entry.scenarioNode);
                            }
                            if (!skipLoad)
                            {
                                psm.moduleRef.Load(entry.scenarioNode);
                            }
                            if (afterCallback.ContainsKey(psm.moduleName))
                            {
                                afterCallback[psm.moduleName](entry.scenarioNode);
                            }
                        }
                        catch (Exception e)
                        {
                            DarkLog.Debug("Error loading " + entry.scenarioName + " scenario module, Exception: " + e);
                            blockScenarioDataSends = true;
                        }
                        loaded = true;
                    }
                }
                if (!loaded)
                {
                    DarkLog.Debug("Loading new " + entry.scenarioName + " scenario module");
                    LoadNewScenarioData(entry.scenarioNode);
                }
            }
        }
Exemplo n.º 9
0
        public void SendScenarioModules(bool highPriority)
        {
            lastScenarioSendTime = Client.realtimeSinceStartup;
            List <string>    scenarioName = new List <string>();
            List <ByteArray> scenarioData = new List <ByteArray>();

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

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

            if (scenarioName.Count > 0)
            {
                if (highPriority)
                {
                    networkWorker.SendScenarioModuleDataHighPriority(scenarioName.ToArray(), scenarioData.ToArray());
                }
                else
                {
                    networkWorker.SendScenarioModuleData(scenarioName.ToArray(), scenarioData.ToArray());
                }
            }
        }
Exemplo n.º 10
0
        private void RealHandleMessage(ByteArray messageData)
        {
            using (MessageReader mr = new MessageReader(messageData.data))
            {
                ModpackDataMessageType type = (ModpackDataMessageType)mr.Read <int>();
                switch (type)
                {
                case ModpackDataMessageType.CKAN:
                {
                    modpackMode = ModpackMode.CKAN;
                    ByteArray receiveData = mr.Read <ByteArray>();
                    ByteArray oldData     = null;
                    if (File.Exists(ckanDataPath))
                    {
                        using (FileStream fs = new FileStream(ckanDataPath, FileMode.Open))
                        {
                            oldData = ByteRecycler.GetObject((int)fs.Length);
                            fs.Read(oldData.data, 0, oldData.Length);
                        }
                    }
                    if (!BytesMatch(oldData, receiveData))
                    {
                        missingWarnFile = true;
                        DarkLog.Debug("Ckan file changed");
                        File.Delete(ckanDataPath);
                        using (FileStream fs = new FileStream(ckanDataPath, FileMode.OpenOrCreate))
                        {
                            fs.Write(receiveData.data, 0, receiveData.Length);
                        }
                    }
                    if (!registeredChatCommand)
                    {
                        registeredChatCommand = true;
                        chatWorker.RegisterChatCommand("upload", UploadCKANToServer, "Upload DarkMultiPlayer.ckan to the server");
                    }
                    if (oldData != null)
                    {
                        ByteRecycler.ReleaseObject(oldData);
                    }
                    ByteRecycler.ReleaseObject(receiveData);
                }
                break;

                case ModpackDataMessageType.MOD_LIST:
                {
                    modFilesToHash    = null;
                    modFilesToHashPos = 0;
                    serverPathCache.Clear();
                    noWarnSha.Clear();
                    modpackMode = ModpackMode.GAMEDATA;
                    string[] files = mr.Read <string[]>();
                    string[] sha   = mr.Read <string[]>();
                    if (File.Exists(gameDataServerCachePath))
                    {
                        File.Delete(gameDataServerCachePath);
                    }
                    using (StreamWriter sw = new StreamWriter(gameDataServerCachePath))
                    {
                        for (int i = 0; i < files.Length; i++)
                        {
                            bool skipFile = false;
                            foreach (string ignoreString in ignoreList)
                            {
                                if (files[i].ToLower().StartsWith(ignoreString, StringComparison.Ordinal))
                                {
                                    skipFile = true;
                                }
                            }
                            foreach (string ignoreString in containsIgnoreList)
                            {
                                if (files[i].ToLower().Contains(ignoreString))
                                {
                                    skipFile = true;
                                }
                            }
                            if (skipFile)
                            {
                                continue;
                            }
                            sw.WriteLine("{0}={1}", files[i], sha[i]);
                            serverPathCache.Add(files[i], sha[i]);
                        }
                    }
                    LoadAuto();
                    if (!registeredChatCommand)
                    {
                        registeredChatCommand = true;
                        chatWorker.RegisterChatCommand("upload", UploadToServer, "Upload GameData to the server");
                    }
                }
                break;

                case ModpackDataMessageType.REQUEST_OBJECT:
                {
                    modFilesToUpload    = mr.Read <string[]>();
                    modFilesToUploadPos = 0;
                    DarkLog.Debug("Server requested " + modFilesToUpload.Length + " files");
                }
                break;

                case ModpackDataMessageType.RESPONSE_OBJECT:
                {
                    string sha256sum = mr.Read <string>();
                    filesDownloaded++;
                    if (mr.Read <bool>())
                    {
                        syncString = "Syncing files " + filesDownloaded + "/" + requestList.Count + " (" + (serverPathCache.Count - requestList.Count) + " cached)";
                        ByteArray fileBytes = mr.Read <ByteArray>();
                        string    filePath  = Path.Combine(cacheDataPath, sha256sum + ".bin");
                        if (!File.Exists(filePath))
                        {
                            using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
                            {
                                fs.Write(fileBytes.data, 0, fileBytes.Length);
                            }
                        }
                        ByteRecycler.ReleaseObject(fileBytes);
                    }
                    else
                    {
                        ScreenMessages.PostScreenMessage("DMP Server has an out of date hash list. Tell the admin to run /reloadmods", float.PositiveInfinity, ScreenMessageStyle.UPPER_CENTER);
                        networkWorker.Disconnect("Syncing files error");
                    }
                    if (filesDownloaded == requestList.Count)
                    {
                        if (missingWarnFile)
                        {
                            networkWorker.Disconnect("Syncing files " + filesDownloaded + "/" + requestList.Count + " (" + (serverPathCache.Count - requestList.Count) + " cached)");
                            ScreenMessages.PostScreenMessage("Please run DMPModpackUpdater or reconnect to ignore", float.PositiveInfinity, ScreenMessageStyle.UPPER_CENTER);
                        }
                        else
                        {
                            synced = true;
                        }
                    }
                }
                break;

                case ModpackDataMessageType.MOD_DONE:
                {
                    if ((!missingWarnFile && requestList.Count == 0) || secondModSync)
                    {
                        synced = true;
                    }
                    else
                    {
                        if (modpackMode == ModpackMode.CKAN)
                        {
                            ScreenMessages.PostScreenMessage("Please install CKAN update at KSP/DarkMultiPlayer.ckan or reconnect to ignore", float.PositiveInfinity, ScreenMessageStyle.UPPER_CENTER);
                            networkWorker.Disconnect("Synced DarkMultiPlayer.ckan");
                        }
                        if (modpackMode == ModpackMode.GAMEDATA && requestList.Count == 0)
                        {
                            ScreenMessages.PostScreenMessage("Please run DMPModpackUpdater or reconnect to ignore", float.PositiveInfinity, ScreenMessageStyle.UPPER_CENTER);
                            syncString = "Synced files (" + serverPathCache.Count + " cached)";
                            networkWorker.Disconnect(syncString);
                        }
                    }
                    secondModSync = true;
                }
                break;
                }
            }
        }
Exemplo n.º 11
0
 private void Update()
 {
     //Don't process incoming files or MOD_COMPLETE if we are hashing our gamedata folder
     if (hashingThreads == null)
     {
         lock (messageQueue)
         {
             while (messageQueue.Count > 0)
             {
                 ByteArray queueByteArray = messageQueue.Dequeue();
                 RealHandleMessage(queueByteArray);
                 ByteRecycler.ReleaseObject(queueByteArray);
                 //Don't process incoming files or MOD_COMPLETE if we are hashing our gamedata folder
                 if (hashingThreads != null)
                 {
                     syncString = "Hashing 0/" + modFilesToHash.Length + " files";
                     break;
                 }
             }
             if (networkWorker.state == ClientState.RUNNING)
             {
                 while (modFilesToUpload != null && networkWorker.GetStatistics("QueuedOutBytes") < 1000000)
                 {
                     RealSendToServer();
                     if (modFilesToUpload != null)
                     {
                         syncString = "Uploading " + modFilesToUploadPos + "/" + modFilesToUpload.Length + " files";
                         DarkLog.Debug(syncString);
                         if (screenMessage != null && DateTime.UtcNow.Ticks > nextScreenMessageUpdate)
                         {
                             nextScreenMessageUpdate = DateTime.UtcNow.Ticks + (TimeSpan.TicksPerMillisecond * 100);
                             screenMessage.duration  = 0f;
                             screenMessage           = ScreenMessages.PostScreenMessage(syncString);
                         }
                     }
                 }
             }
         }
     }
     else
     {
         long stopTime = DateTime.UtcNow.Ticks + (TimeSpan.TicksPerMillisecond * 100);
         CheckHashingThreads();
         if (hashingThreads == null)
         {
             using (StreamWriter sw = new StreamWriter(gameDataClientCachePath))
             {
                 foreach (KeyValuePair <string, string> kvp in clientPathCache)
                 {
                     sw.WriteLine("{0}={1}", kvp.Key, kvp.Value);
                 }
             }
             syncString = "Hashed " + clientPathCache.Count + " files";
             DarkLog.Debug("Hashed " + clientPathCache.Count + " files");
             if (screenMessage != null && DateTime.UtcNow.Ticks > nextScreenMessageUpdate)
             {
                 nextScreenMessageUpdate = DateTime.UtcNow.Ticks + (TimeSpan.TicksPerMillisecond * 100);
                 screenMessage.duration  = 0f;
                 screenMessage           = ScreenMessages.PostScreenMessage(syncString);
             }
             if (uploadAfterHashing)
             {
                 uploadAfterHashing = false;
                 using (MessageWriter mw = new MessageWriter())
                 {
                     List <string> uploadfiles = new List <string>(clientPathCache.Keys);
                     List <string> uploadsha   = new List <string>(clientPathCache.Values);
                     mw.Write <int>((int)ModpackDataMessageType.MOD_LIST);
                     mw.Write <string[]>(uploadfiles.ToArray());
                     mw.Write <string[]>(uploadsha.ToArray());
                     networkWorker.SendModpackMessage(mw.GetMessageBytes());
                 }
             }
         }
         else
         {
             syncString = "Hashing " + modFilesToHashPos + "/" + modFilesToHash.Length + " files";
             if (screenMessage != null && DateTime.UtcNow.Ticks > nextScreenMessageUpdate)
             {
                 nextScreenMessageUpdate = DateTime.UtcNow.Ticks + (TimeSpan.TicksPerMillisecond * 100);
                 screenMessage.duration  = 0f;
                 screenMessage           = ScreenMessages.PostScreenMessage(syncString);
             }
             DarkLog.Debug("Hashing " + modFilesToHashPos + "/" + modFilesToHash.Length + " files");
         }
     }
 }