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); }
/// <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); } }
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 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); }
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); }
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); }
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()); } }
/// <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); } }
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()); } }
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); } }
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)); }
/// <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]); }