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);
        }
示例#2
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);
            }
        }
示例#3
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);
        }
示例#4
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 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);
        }
示例#6
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);
            }
        }
        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);
        }
示例#8
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);
        }
示例#9
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}");
            }
        }
        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");
        }
        /// <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());
            }
        }
示例#12
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);
            }
        }
示例#13
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());
            }
        }
示例#14
0
        public void SendKerbalIfDifferent(ProtoCrewMember pcm)
        {
            if (pcm.type == ProtoCrewMember.KerbalType.Tourist)
            {
                //Don't send tourists
                LunaLog.Log($"[LMP]: Skipping sending of tourist: {pcm.name}");
                return;
            }

            var kerbalNode = new ConfigNode();

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

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

            var kerbalHash      = Common.CalculateSha256Hash(kerbalBytes);
            var kerbalDifferent = false;

            if (!System.ServerKerbals.ContainsKey(pcm.name))
            {
                //New kerbal
                LunaLog.Log("[LMP]: Found new kerbal, sending...");
                kerbalDifferent = true;
            }
            else if (System.ServerKerbals[pcm.name] != kerbalHash)
            {
                LunaLog.Log($"[LMP]: Found changed kerbal ({pcm.name}), sending...");
                kerbalDifferent = true;
            }
            if (kerbalDifferent)
            {
                System.ServerKerbals[pcm.name] = kerbalHash;
                SendKerbalProtoMessage(pcm.name, kerbalBytes);
            }
        }
示例#15
0
        public static byte[] SerializeVessel(ProtoVessel protoVessel)
        {
            var vesselNode = new ConfigNode();

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

            var vesselId = new Guid(vesselNode.GetValue("pid"));

            //Defend against NaN orbits
            if (VesselHasNaNPosition(vesselNode))
            {
                LunaLog.Log($"[LMP]: Vessel {vesselId} has NaN position");
                return(new byte[0]);
            }

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

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

            return(ConfigNodeSerializer.Serialize(vesselNode));
        }
示例#16
0
 /// <summary>
 /// Serialize a protovessel into a byte array
 /// </summary>
 public static byte[] SerializeVessel(ProtoVessel protoVessel)
 {
     return(PreSerializationChecks(protoVessel, out var configNode) ? ConfigNodeSerializer.Serialize(configNode) : new byte[0]);
 }