public void SendStrategyMessage(Strategy strategy)
        {
            var msgData = NetworkMain.CliMsgFactory.CreateNewMessageData <ShareProgressStrategyMsgData>();

            msgData.Strategy.Name = strategy.Config.Name;

            var configNode = ConvertStrategyToConfigNode(strategy);

            if (configNode == null)
            {
                return;
            }

            var data     = ConfigNodeSerializer.Serialize(configNode);
            var numBytes = data.Length;

            msgData.Strategy.NumBytes = numBytes;
            if (msgData.Strategy.Data.Length < numBytes)
            {
                msgData.Strategy.Data = new byte[numBytes];
            }

            Array.Copy(data, msgData.Strategy.Data, numBytes);

            SendMessage(msgData);
        }
示例#2
0
        public void SendKerbal(ProtoCrewMember pcm)
        {
            if (pcm == null)
            {
                return;
            }

            if (VesselCommon.IsSpectating)
            {
                return;
            }

            if (pcm.type == ProtoCrewMember.KerbalType.Tourist)
            {
                //Don't send tourists
                LunaLog.Log($"[LMP]: Skipping sending of tourist: {pcm.name}");
                return;
            }

            ConfigNode.ClearData();
            pcm.Save(ConfigNode);

            var kerbalBytes = ConfigNodeSerializer.Serialize(ConfigNode);

            if (kerbalBytes == null || kerbalBytes.Length == 0)
            {
                LunaLog.LogError("[LMP]: Error sending kerbal - bytes are null or 0");
                return;
            }

            SendKerbalProtoMessage(pcm.name, kerbalBytes);
        }
示例#3
0
        public void HandleMessage(IServerMessageBase msg)
        {
            if (!(msg.Data is ScenarioBaseMsgData msgData))
            {
                return;
            }

            if (msgData.ScenarioMessageType == ScenarioMessageType.Data)
            {
                var data = (ScenarioDataMsgData)msgData;
                for (var i = 0; i < data.ScenarioCount; i++)
                {
                    var scenarioNode = ConfigNodeSerializer.Deserialize(data.ScenariosData[i].Data, data.ScenariosData[i].NumBytes);
                    if (scenarioNode != null)
                    {
                        var entry = new ScenarioEntry
                        {
                            ScenarioName = data.ScenariosData[i].Module,
                            ScenarioNode = scenarioNode
                        };
                        System.ScenarioQueue.Enqueue(entry);
                    }
                    else
                    {
                        LunaLog.LogError($"[LMP]: Scenario data has been lost for {data.ScenariosData[i].Module}");
                        ScreenMessages.PostScreenMessage($"Scenario data has been lost for {data.ScenariosData[i].Module}", 5f, ScreenMessageStyle.UPPER_CENTER);
                    }
                }
                MainSystem.NetworkState = ClientState.ScenariosSynced;
            }
        }
        /// <summary>
        /// In this method we get the new vessel data and set it to the dictionary of all the player vessels.
        /// We set it as UNLOADED as perhaps vessel data has changed.
        /// </summary>
        public void HandleVesselProtoData(byte[] vesselData, Guid vesselId)
        {
            TaskFactory.StartNew(() =>
            {
                UniverseSyncCache.QueueToCache(vesselData);
                var vesselNode = ConfigNodeSerializer.Deserialize(vesselData);
                if (vesselNode != null && vesselId == Common.ConvertConfigStringToGuid(vesselNode.GetValue("pid")))
                {
                    var vesselProtoUpdate = new VesselProtoUpdate(vesselNode, vesselId);
                    if (vesselProtoUpdate.ProtoVessel == null)
                    {
                        return;
                    }

                    if (!AllPlayerVessels.TryGetValue(vesselId, out var existingProtoData))
                    {
                        AllPlayerVessels.TryAdd(vesselId, vesselProtoUpdate);
                    }
                    else if (VesselCommon.ProtoVesselHasChanges(existingProtoData.ProtoVessel, vesselProtoUpdate.ProtoVessel))
                    {
                        //Vessel exists and contain changes so replace it
                        AllPlayerVessels.TryUpdate(vesselId, vesselProtoUpdate, existingProtoData);
                    }
                }
            });
        }
示例#5
0
        public void SendVesselMessage(Vessel vessel)
        {
            if (vessel == null)
            {
                return;
            }

            //Update the protovessel definition!
            vessel.BackupVessel();

            //Defend against NaN orbits
            if (VesselHasNaNPosition(vessel.protoVessel))
            {
                LunaLog.Log($"[LMP]: Vessel {vessel.id} has NaN position");
                return;
            }

            foreach (var pps in vessel.protoVessel.protoPartSnapshots)
            {
                //Remove tourists from the vessel
                //TODO: Probably this can be done in the CleanUpVesselNode method
                foreach (var pcm in
                         pps.protoModuleCrew.Where(pcm => pcm.type == ProtoCrewMember.KerbalType.Tourist).ToArray())
                {
                    pps.protoModuleCrew.Remove(pcm);
                }
            }

            var vesselNode = new ConfigNode();

            try
            {
                vessel.protoVessel.Save(vesselNode);
            }
            catch (Exception)
            {
                LunaLog.LogError("[LMP]: Error while saving vessel");
                return;
            }

            //Clean up the vessel so we send only the important data
            CleanUpVesselNode(vesselNode, vessel.id);

            var vesselBytes = ConfigNodeSerializer.Serialize(vesselNode);

            if (vesselBytes.Length > 0)
            {
                UniverseSyncCache.QueueToCache(vesselBytes);

                SendMessage(new VesselProtoMsgData
                {
                    VesselId   = vessel.id,
                    VesselData = vesselBytes
                });
            }
            else
            {
                LunaLog.LogError($"[LMP]: Failed to create byte[] data for {vessel.id}");
            }
        }
示例#6
0
        public void HandleMessage(IMessageData messageData)
        {
            var msgData = messageData as ScenarioBaseMsgData;

            if (msgData?.ScenarioMessageType == ScenarioMessageType.Data)
            {
                var data = ((ScenarioDataMsgData)messageData).ScenarioNameData;
                foreach (var scenario in data)
                {
                    var scenarioNode = ConfigNodeSerializer.Deserialize(scenario.Value);
                    if (scenarioNode != null)
                    {
                        var entry = new ScenarioEntry
                        {
                            ScenarioName = scenario.Key,
                            ScenarioNode = scenarioNode
                        };
                        System.ScenarioQueue.Enqueue(entry);
                    }
                    else
                    {
                        LunaLog.LogError($"[LMP]: Scenario data has been lost for {scenario.Key}");
                        ScreenMessages.PostScreenMessage($"Scenario data has been lost for {scenario.Key}", 5f, ScreenMessageStyle.UPPER_CENTER);
                    }
                }
                MainSystem.NetworkState = ClientState.ScneariosSynced;
            }
        }
示例#7
0
        /// <summary>
        /// Convert a byte array to a ConfigNode and then to a ProgressNode.
        /// If anything goes wrong it will return null.
        /// </summary>
        /// <param name="data">The byte array that represents the configNode</param>
        /// <param name="numBytes">The length of the byte array</param>
        /// <param name="progressNodeId">The Id of the ProgressNode</param>
        /// <returns></returns>
        private static ProgressNode ConvertByteArrayToAchievement(byte[] data, int numBytes, string progressNodeId)
        {
            ConfigNode node;

            try
            {
                node = ConfigNodeSerializer.Deserialize(data, numBytes);
            }
            catch (Exception e)
            {
                LunaLog.LogError($"[LMP]: Error while deserializing achievement configNode: {e}");
                return(null);
            }

            if (node == null)
            {
                LunaLog.LogError("[LMP]: Error, the achievement configNode was null.");
                return(null);
            }

            ProgressNode achievement;

            try
            {
                achievement = new ProgressNode(progressNodeId, false);
                achievement.Load(node);
            }
            catch (Exception e)
            {
                LunaLog.LogError($"[LMP]: Error while deserializing achievement: {e}");
                return(null);
            }

            return(achievement);
        }
示例#8
0
        /// <summary>
        /// Sends the parsed config nodes to the server after doing basic checks
        /// </summary>
        private void SendModulesConfigNodes()
        {
            ScenarioData.Clear();
            ScenarioName.Clear();

            foreach (var scenarioConfigNode in ScenariosConfigNodes)
            {
                var scenarioBytes = ConfigNodeSerializer.Serialize(scenarioConfigNode.Item2);
                var scenarioHash  = Common.CalculateSha256Hash(scenarioBytes);

                if (scenarioBytes.Length == 0)
                {
                    LunaLog.Log($"[LMP]: Error writing scenario data for {scenarioConfigNode.Item1}");
                    continue;
                }

                //Data is the same since last time - Skip it.
                if (CheckData.ContainsKey(scenarioConfigNode.Item1) && CheckData[scenarioConfigNode.Item1] == scenarioHash)
                {
                    continue;
                }

                CheckData[scenarioConfigNode.Item1] = scenarioHash;

                ScenarioName.Add(scenarioConfigNode.Item1);
                ScenarioData.Add(scenarioBytes);
            }

            if (ScenarioName.Any())
            {
                MessageSender.SendScenarioModuleData(ScenarioName, ScenarioData);
            }
        }
        /// <summary>
        /// Convert a byte array to a ConfigNode.
        /// If anything goes wrong it will return null.
        /// </summary>
        private static ConfigNode ConvertByteArrayToConfigNode(byte[] data, int numBytes)
        {
            ConfigNode node;

            try
            {
                node = ConfigNodeSerializer.Deserialize(data, numBytes);
            }
            catch (Exception e)
            {
                LunaLog.LogError($"[LMP]: Error while deserializing strategy configNode: {e}");
                return(null);
            }

            if (node == null)
            {
                LunaLog.LogError("[LMP]: Error, the strategy configNode was null.");
                return(null);
            }

            if (!node.HasValue("isActive"))
            {
                LunaLog.LogError("[LMP]: Error, the strategy configNode is invalid (isActive missing).");
                return(null);
            }

            return(node);
        }
示例#10
0
        public ProtoVessel CreateProtoVessel()
        {
            var configNode = ConfigNodeSerializer.Deserialize(RawData, NumBytes);

            if (configNode == null || VesselCommon.VesselHasNaNPosition(configNode))
            {
                LunaLog.LogError($"Received a malformed vessel from SERVER. Id {VesselId}");
                VesselRemoveSystem.Singleton.KillVessel(VesselId, "Malformed vessel");
                VesselRemoveSystem.Singleton.AddToKillList(VesselId, "Malformed vessel");
                return(null);
            }

            var newProto = VesselSerializer.CreateSafeProtoVesselFromConfigNode(configNode, VesselId);

            if (newProto == null)
            {
                LunaLog.LogError($"Received a malformed vessel from SERVER. Id {VesselId}");
                VesselRemoveSystem.Singleton.KillVessel(VesselId, "Malformed vessel");
                VesselRemoveSystem.Singleton.AddToKillList(VesselId, "Malformed vessel");
                return(null);
            }

            if (VesselCommon.ProtoVesselHasInvalidParts(newProto))
            {
                return(null);
            }

            return(newProto);
        }
示例#11
0
        public void SendAchievementsMessage(ProgressNode achievement)
        {
            //We only send the ProgressNodes that are CelestialBodySubtree
            var foundNode = ProgressTracking.Instance.FindNode(achievement.Id);

            if (foundNode == null)
            {
                var traverse = new Traverse(achievement).Field <CelestialBody>("body");

                var body = traverse.Value ? traverse.Value.name : null;
                if (body != null)
                {
                    foundNode = ProgressTracking.Instance.FindNode(body);
                }
            }

            if (foundNode != null)
            {
                var configNode = ConvertAchievementToConfigNode(foundNode);
                if (configNode == null)
                {
                    return;
                }

                //Build the packet and send it.
                var msgData = NetworkMain.CliMsgFactory.CreateNewMessageData <ShareProgressAchievementsMsgData>();
                msgData.Id       = foundNode.Id;
                msgData.Data     = ConfigNodeSerializer.Serialize(configNode);
                msgData.NumBytes = msgData.Data.Length;
                System.MessageSender.SendMessage(msgData);
            }
        }
示例#12
0
        public void SendKerbal(ProtoCrewMember pcm)
        {
            if (pcm == null)
            {
                return;
            }

            if (VesselCommon.IsSpectating)
            {
                return;
            }

            ConfigNode.ClearData();
            pcm.Save(ConfigNode);

            var kerbalBytes = ConfigNodeSerializer.Serialize(ConfigNode);

            if (kerbalBytes == null || kerbalBytes.Length == 0)
            {
                LunaLog.LogError("[LMP]: Error sending kerbal - bytes are null or 0");
                return;
            }

            SendKerbalProtoMessage(pcm.name, kerbalBytes);
        }
        public void SendAchievementsMessage(ProgressNode[] achievements)
        {
            //Convert the achievements to AchievementInfo's.
            var achievementInfos = new List <AchievementInfo>();

            foreach (var achievement in achievements)
            {
                var configNode = ConvertAchievementToConfigNode(achievement);
                if (configNode == null)
                {
                    break;
                }

                var data     = ConfigNodeSerializer.Serialize(configNode);
                var numBytes = data.Length;

                achievementInfos.Add(new AchievementInfo
                {
                    Id       = achievement.Id,
                    Data     = data,
                    NumBytes = numBytes
                });
            }

            //Build the packet and send it.
            var msgData = NetworkMain.CliMsgFactory.CreateNewMessageData <ShareProgressAchievementsMsgData>();

            msgData.Achievements      = achievementInfos.ToArray();
            msgData.AchievementsCount = msgData.Achievements.Length;
            System.MessageSender.SendMessage(msgData);
        }
示例#14
0
        public void SendTechnologyMessage(RDTech tech)
        {
            var msgData = NetworkMain.CliMsgFactory.CreateNewMessageData <ShareProgressTechnologyMsgData>();

            msgData.TechNode.Id = tech.techID;

            var configNode = ConvertTechNodeToConfigNode(tech);

            if (configNode == null)
            {
                return;
            }

            var data     = ConfigNodeSerializer.Serialize(configNode);
            var numBytes = data.Length;

            msgData.TechNode.NumBytes = numBytes;
            if (msgData.TechNode.Data.Length < numBytes)
            {
                msgData.TechNode.Data = new byte[numBytes];
            }

            Array.Copy(data, msgData.TechNode.Data, numBytes);

            SendMessage(msgData);
        }
        public void SendScienceSubjectMessage(ScienceSubject subject)
        {
            var msgData = NetworkMain.CliMsgFactory.CreateNewMessageData <ShareProgressScienceSubjectMsgData>();

            msgData.ScienceSubject.Id = subject.id;

            var configNode = ConvertScienceSubjectToConfigNode(subject);

            if (configNode == null)
            {
                return;
            }

            var data     = ConfigNodeSerializer.Serialize(configNode);
            var numBytes = data.Length;

            msgData.ScienceSubject.NumBytes = numBytes;
            if (msgData.ScienceSubject.Data.Length < numBytes)
            {
                msgData.ScienceSubject.Data = new byte[numBytes];
            }

            Array.Copy(data, msgData.ScienceSubject.Data, numBytes);

            SendMessage(msgData);

            LunaLog.Log($"Science experiment \"{subject.id}\" sent");
        }
        public void SendContractMessage(Contract[] contracts)
        {
            //Convert the Contract's to ContractInfo's.
            var contractInfos = new List <ContractInfo>();

            foreach (var contract in contracts)
            {
                var configNode = ConvertContractToConfigNode(contract);
                if (configNode == null)
                {
                    break;
                }

                var data     = ConfigNodeSerializer.Serialize(configNode);
                var numBytes = data.Length;

                contractInfos.Add(new ContractInfo
                {
                    ContractGuid = contract.ContractGuid,
                    Data         = data,
                    NumBytes     = numBytes
                });
            }

            //Build the packet and send it.
            var msgData = NetworkMain.CliMsgFactory.CreateNewMessageData <ShareProgressContractsMsgData>();

            msgData.Contracts     = contractInfos.ToArray();
            msgData.ContractCount = msgData.Contracts.Length;
            System.MessageSender.SendMessage(msgData);
        }
        /// <summary>
        /// In this method we get the new vessel data and set it to the dictionary of all the player vessels.
        /// We set it as UNLOADED as perhaps vessel data has changed.
        /// </summary>
        private static void HandleVesselProtoData(byte[] vesselData, Guid vesselId)
        {
            UniverseSyncCache.QueueToCache(vesselData);
            var vesselNode = ConfigNodeSerializer.Deserialize(vesselData);
            var configGuid = vesselNode?.GetValue("pid");

            if (!string.IsNullOrEmpty(configGuid) && vesselId == Common.ConvertConfigStringToGuid(configGuid))
            {
                var vesselProtoUpdate = new VesselProtoUpdate(vesselNode, vesselId);
                if (vesselProtoUpdate.ProtoVessel == null)
                {
                    return;
                }

                if (System.AllPlayerVessels.ContainsKey(vesselId))
                {
                    //Vessel exists so replace it
                    System.AllPlayerVessels[vesselId] = vesselProtoUpdate;
                }
                else
                {
                    System.AllPlayerVessels.TryAdd(vesselId, vesselProtoUpdate);
                }
            }
        }
示例#18
0
 /// <summary>
 /// Serializes a vessel to a previous preallocated array (avoids garbage generation)
 /// </summary>
 public static void SerializeVesselToArray(ProtoVessel protoVessel, byte[] data, out int numBytes)
 {
     if (PreSerializationChecks(protoVessel, out var configNode))
     {
         ConfigNodeSerializer.SerializeToArray(configNode, data, out numBytes);
     }
     else
     {
         numBytes = 0;
     }
 }
        /// <summary>
        /// This method uses a lot of memory so try to call it as less as possible and only when needed
        /// </summary>
        public void DeserializeVesselBytes()
        {
            lock (_vesselDataSyncLock)
            {
                _needToDeserializeData = false;
                var newVesselNode = ConfigNodeSerializer.Deserialize(_vesselData, _numBytes);
                if (!VesselCommon.VesselHasNaNPosition(newVesselNode))
                {                
                    //In case there's a deserialization error skip it and keep the older node
                    _vesselNode = newVesselNode;
                }
                if (_vesselNode == null)
                {
                    LunaLog.LogError($"Received a malformed vessel from SERVER. Id {VesselId}");
                    VesselRemoveSystem.Singleton.KillVessel(VesselId, "Malformed vessel");
                    VesselRemoveSystem.Singleton.AddToKillList(VesselId, "Malformed vessel");
                    return;
                }

                var newProto = VesselSerializer.CreateSafeProtoVesselFromConfigNode(_vesselNode, VesselId);

                //In case there's a deserialization error skip it and keep the older proto
                if (newProto != null)
                {
                    HasInvalidParts = VesselCommon.ProtoVesselHasInvalidParts(newProto);

                    if (newProto.vesselID != VesselId)
                    {
                        LunaLog.LogError($"Tried to update the Vessel with a proto from a different vessel ID. Proto: {newProto.vesselID} CorrectId: {VesselId}");
                    }
                    else
                    {
                        _deserializedProtoVessel = newProto;
                    }
                }

                //If protovessel is still null then unfortunately we must remove that vessel as the server sent us a bad vessel
                if (_deserializedProtoVessel == null)
                {
                    LunaLog.LogError($"Received a malformed vessel from SERVER. Id {VesselId}");
                    VesselRemoveSystem.Singleton.KillVessel(VesselId, "Malformed vessel");
                    VesselRemoveSystem.Singleton.AddToKillList(VesselId, "Malformed vessel");
                }
                else
                {
                    _vesselParts.Clear();
                    foreach (var protoPart in _deserializedProtoVessel.protoPartSnapshots)
                    {
                        _vesselParts.TryAdd(protoPart.flightID, protoPart);
                    }
                }
            }
        }
        /// <summary>
        /// Check if the scenario has changed and sends it to the server
        /// This method is not optimized and take several ms to run
        /// </summary>
        public void SendScenarioModules()
        {
            if (!Enabled || !SystemsContainer.Get <MainSystem>().GameRunning)
            {
                return;
            }

            var modules = ScenarioRunner.GetLoadedModules().ToArray();

            //I tried to do this method in another thread as it takes a lot of time to run
            //but appear several empty lines in the log... Perhaps we cannot do it :(
            var scenarioName = new List <string>();
            var scenarioData = new List <byte[]>();

            foreach (var scenarioModule in modules)
            {
                var scenarioType = scenarioModule.GetType().Name;

                if (!IsScenarioModuleAllowed(scenarioType))
                {
                    continue;
                }

                var scenarioNode = new ConfigNode();
                scenarioModule.Save(scenarioNode);

                var scenarioBytes = ConfigNodeSerializer.Serialize(scenarioNode);
                var scenarioHash  = Common.CalculateSha256Hash(scenarioBytes);

                if (scenarioBytes.Length == 0)
                {
                    LunaLog.Log($"[LMP]: Error writing scenario data for {scenarioType}");
                    continue;
                }

                //Data is the same since last time - Skip it.
                if (CheckData.ContainsKey(scenarioType) && CheckData[scenarioType] == scenarioHash)
                {
                    continue;
                }

                CheckData[scenarioType] = scenarioHash;

                scenarioName.Add(scenarioType);
                scenarioData.Add(scenarioBytes);
            }

            if (scenarioName.Any())
            {
                MessageSender.SendScenarioModuleData(scenarioName.ToArray(), scenarioData.ToArray());
            }
        }
        /// <summary>
        /// Appends the received kerbal to the dictionary
        /// </summary>
        private static void ProcessKerbal(byte[] kerbalData, int numBytes)
        {
            var kerbalNode = ConfigNodeSerializer.Deserialize(kerbalData, numBytes);

            if (kerbalNode != null)
            {
                System.KerbalsToProcess.Enqueue(kerbalNode);
            }
            else
            {
                LunaLog.LogError("[LMP]: Failed to load kerbal!");
            }
        }
示例#22
0
        /// <summary>
        /// Creates a new Kerbal
        /// </summary>
        private void CreateKerbal(ProtoCrewMember protoCrew)
        {
            HighLogic.CurrentGame.CrewRoster.AddCrewMember(protoCrew);
            var kerbalNode = new ConfigNode();

            protoCrew.Save(kerbalNode);
            var kerbalBytes = ConfigNodeSerializer.Serialize(kerbalNode);

            if (kerbalBytes != null && kerbalBytes.Length != 0)
            {
                ServerKerbals[protoCrew.name] = Common.CalculateSha256Hash(kerbalBytes);
            }
        }
        /// <summary>
        /// Just load the received kerbal into game
        /// </summary>
        /// <param name="messageData"></param>
        private static void HandleKerbalProto(KerbalProtoMsgData messageData)
        {
            var kerbalNode = ConfigNodeSerializer.Deserialize(messageData.KerbalData);

            if (kerbalNode != null)
            {
                System.LoadKerbal(kerbalNode);
            }
            else
            {
                LunaLog.LogError("[LMP]: Failed to load kerbal!");
            }
        }
示例#24
0
        /// <summary>
        /// Deserialize a byte array into a protovessel
        /// </summary>
        public static ProtoVessel DeserializeVessel(byte[] data, int numBytes)
        {
            try
            {
                var vesselNode = ConfigNodeSerializer.Deserialize(data, numBytes);
                var configGuid = vesselNode?.GetValue("pid");

                return(CreateSafeProtoVesselFromConfigNode(vesselNode, new Guid(configGuid)));
            }
            catch (Exception e)
            {
                LunaLog.LogError($"[LMP]: Error while deserializing vessel: {e}");
                return(null);
            }
        }
        /// <summary>
        /// Convert a byte array to a ConfigNode and then to a ScienceSubject.
        /// If anything goes wrong it will return null.
        /// </summary>
        private static ScienceSubject ConvertByteArrayToScienceSubject(byte[] data, int numBytes)
        {
            var node = new ConfigNode("Science");

            try
            {
                node.AddData(ConfigNodeSerializer.Deserialize(data, numBytes));
            }
            catch (Exception e)
            {
                LunaLog.LogError($"[LMP]: Error while deserializing science subject configNode: {e}");
                return(null);
            }

            return(new ScienceSubject(node));
        }
        /// <summary>
        /// We store all the kerbals in the KerbalProtoQueue dictionary so later once the game starts we load them
        /// </summary>
        /// <param name="messageData"></param>
        private static void HandleKerbalReply(KerbalReplyMsgData messageData)
        {
            foreach (var kerbal in messageData.KerbalsData)
            {
                var kerbalNode = ConfigNodeSerializer.Deserialize(kerbal.Value);
                if (kerbalNode != null)
                {
                    System.KerbalQueue.Enqueue(kerbalNode);
                }
                else
                {
                    LunaLog.LogError("[LMP]: Failed to load kerbal!");
                }
            }

            LunaLog.Log("[LMP]: Kerbals Synced!");
            MainSystem.NetworkState = ClientState.KerbalsSynced;
        }
示例#27
0
        private static void QueueScenarioBytes(string scenarioModule, byte[] scenarioData, int numBytes)
        {
            var scenarioNode = ConfigNodeSerializer.Deserialize(scenarioData, numBytes);

            if (scenarioNode != null)
            {
                var entry = new ScenarioEntry
                {
                    ScenarioModule = scenarioModule,
                    ScenarioNode   = scenarioNode
                };
                System.ScenarioQueue.Enqueue(entry);
            }
            else
            {
                LunaLog.LogError($"[LMP]: Scenario data has been lost for {scenarioModule}");
            }
        }
示例#28
0
        private void ParseAndSendModules(IEnumerable <ScenarioModule> modules)
        {
            var scenarioName = new List <string>();
            var scenarioData = new List <byte[]>();

            foreach (var scenarioModule in modules)
            {
                var scenarioType = scenarioModule.GetType().Name;

                if (!IsScenarioModuleAllowed(scenarioType))
                {
                    continue;
                }

                var scenarioNode = new ConfigNode();
                scenarioModule.Save(scenarioNode);

                var scenarioBytes = ConfigNodeSerializer.Serialize(scenarioNode);
                var scenarioHash  = Common.CalculateSha256Hash(scenarioBytes);

                if (scenarioBytes.Length == 0)
                {
                    LunaLog.Log($"[LMP]: Error writing scenario data for {scenarioType}");
                    continue;
                }

                //Data is the same since last time - Skip it.
                if (CheckData.ContainsKey(scenarioType) && CheckData[scenarioType] == scenarioHash)
                {
                    continue;
                }

                CheckData[scenarioType] = scenarioHash;

                scenarioName.Add(scenarioType);
                scenarioData.Add(scenarioBytes);
            }

            if (scenarioName.Any())
            {
                MessageSender.SendScenarioModuleData(scenarioName.ToArray(), scenarioData.ToArray());
            }
        }
        /// <summary>
        /// Here we receive the vessel list msg from the server.We rty to get the vessels from the cache and if
        /// it fails or we don't have it in the cache we request that vessel info to the server.
        /// </summary>
        private static void HandleVesselList(VesselListReplyMsgData messageData)
        {
            var serverVessels    = new List <string>(messageData.Vessels);
            var cacheObjects     = new List <string>(UniverseSyncCache.GetCachedObjects());
            var requestedObjects = new List <string>();

            foreach (var serverVessel in serverVessels)
            {
                if (cacheObjects.Contains(serverVessel))
                {
                    //Try to get it from cache...
                    var vesselBytes = UniverseSyncCache.GetFromCache(serverVessel);
                    var vesselNode  = ConfigNodeSerializer.Deserialize(vesselBytes);
                    if (vesselNode != null)
                    {
                        var vesselId = Common.ConvertConfigStringToGuid(vesselNode.GetValue("pid"));
                        if (vesselBytes.Length != 0 && vesselId != Guid.Empty)
                        {
                            var update = new VesselProtoUpdate(vesselNode, vesselId);
                            if (update.ProtoVessel != null)
                            {
                                System.AllPlayerVessels.TryAdd(vesselId, update);
                            }
                        }
                        else
                        {
                            LunaLog.LogError($"[LMP]: Cached object {serverVessel} is damaged");
                            requestedObjects.Add(serverVessel);
                        }
                    }
                }
                else
                {
                    requestedObjects.Add(serverVessel);
                }
            }

            //Request the vessel data that we don't have.
            NetworkSender.QueueOutgoingMessage(MessageFactory.CreateNew <VesselCliMsg>
                                                   (new VesselsRequestMsgData {
                RequestList = requestedObjects.ToArray()
            }));
        }
        /// <summary>
        /// Just load the received kerbal into game
        /// </summary>
        /// <param name="messageData"></param>
        private static void HandleKerbalProto(KerbalProtoMsgData messageData)
        {
            var kerbalNode = ConfigNodeSerializer.Deserialize(messageData.KerbalData);

            if (kerbalNode != null)
            {
                if (MainSystem.NetworkState < ClientState.TimeLocked)
                {
                    System.KerbalQueue.Enqueue(kerbalNode);
                }
                else
                {
                    System.LoadKerbal(kerbalNode);
                }
            }
            else
            {
                LunaLog.LogError("[LMP]: Failed to load kerbal!");
            }
        }