private static void ExperimentalPart(string partName, int count) { System.StartIgnoringEvents(); var partInfo = PartLoader.getPartInfoByName(partName); if (partInfo != null) { var currentExperimentalParts = Traverse.Create(ResearchAndDevelopment.Instance).Field <Dictionary <AvailablePart, int> >("experimentalPartsStock").Value; if (currentExperimentalParts.TryGetValue(partInfo, out var currentCount)) { if (currentCount > count) { ResearchAndDevelopment.RemoveExperimentalPart(partInfo); } else if (currentCount < count) { ResearchAndDevelopment.AddExperimentalPart(partInfo); } } else { ResearchAndDevelopment.AddExperimentalPart(partInfo); } } //Refresh RD nodes in case we are in the RD screen if (RDController.Instance && RDController.Instance.partList) { RDController.Instance.partList.Refresh(); RDController.Instance.UpdatePanel(); } //Refresh the part list in case we are in the VAB/SPH if (EditorPartList.Instance) { EditorPartList.Instance.Refresh(); } System.StopIgnoringEvents(); LunaLog.Log($"Experimental part received part: {partName} count {count}"); }
public void UndockComplete(Part part, DockedVesselInfo dockedInfo, Vessel originalVessel) { if (VesselCommon.IsSpectating || System.IgnoreEvents) { return; } if (!LockSystem.LockQuery.UpdateLockBelongsToPlayer(originalVessel.id, SettingsSystem.CurrentSettings.PlayerName)) { return; } LockSystem.Singleton.AcquireUnloadedUpdateLock(part.vessel.id, true, true); LockSystem.Singleton.AcquireUpdateLock(part.vessel.id, true, true); VesselPositionSystem.Singleton.MessageSender.SendVesselPositionUpdate(part.vessel, true); LunaLog.Log($"Undock complete! Part: {part} Vessel: {originalVessel.id}"); System.MessageSender.SendVesselUndock(originalVessel, part.flightID, dockedInfo, part.vessel.id); }
/// <summary> /// This event is called when the vessel gone BOOM /// If we have the update lock of it we kill it /// It doesn't matter if we own the control lock or not as perhaps we are killing a vessel of a player who disconnected. /// </summary> public void OnVesselDestroyed(Vessel dyingVessel) { if (dyingVessel.state != Vessel.State.DEAD) { return; } //Only remove the vessel if we own the update lock if (LockSystem.LockQuery.UpdateLockBelongsToPlayer(dyingVessel.id, SettingsSystem.CurrentSettings.PlayerName)) { LunaLog.Log($"[LMP]: Removing vessel {dyingVessel.id}, Name: {dyingVessel.vesselName} from the server: Destroyed"); SystemsContainer.Get <KerbalSystem>().MessageSender.SendKerbalsInVessel(dyingVessel); System.MessageSender.SendVesselRemove(dyingVessel.id); //Vessel is dead so remove the locks SystemsContainer.Get <LockSystem>().ReleaseAllVesselLocks(dyingVessel.id); } }
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 HandleMessage(IServerMessageBase msg) { if (!(msg.Data is ShareProgressBaseMsgData msgData)) { return; } if (msgData.ShareProgressMessageType != ShareProgressMessageType.ExperimentalPart) { return; } if (msgData is ShareProgressExperimentalPartMsgData data) { var partName = string.Copy(data.PartName); var count = data.Count; LunaLog.Log($"Queue ExperimentalPart: part {partName} count {count}"); ShareCareerSystem.Singleton.QueueAction(() => ExperimentalPart(partName, count)); } }
/// <summary> /// This event is called when the vessel is recovered /// </summary> public void OnVesselRecovered(ProtoVessel recoveredVessel, bool quick) { //quick == true when you press "space center" from the inflight menu if (!LockSystem.LockQuery.CanRecoverOrTerminateTheVessel(recoveredVessel.vesselID, SettingsSystem.CurrentSettings.PlayerName)) { ScreenMessages.PostScreenMessage("Cannot recover vessel, the vessel is not yours.", 5f, ScreenMessageStyle.UPPER_CENTER); return; } _recoveringTerminatingVesselId = recoveredVessel.vesselID; LunaLog.Log($"[LMP]: Removing vessel {recoveredVessel.vesselID}, Name: {recoveredVessel.vesselName} from the server: Recovered"); SystemsContainer.Get <KerbalSystem>().ProcessKerbalsInVessel(recoveredVessel); System.MessageSender.SendVesselRemove(recoveredVessel.vesselID); //Vessel is recovered so remove the locks SystemsContainer.Get <LockSystem>().ReleaseAllVesselLocks(recoveredVessel.vesselID); }
public static SettingStructure ReadSettings() { CheckDataDirectory(); RestoreBackupIfNoSettings(); if (!File.Exists(SettingsFilePath)) { CreateDefaultSettingsFile(); } if (!File.Exists(BackupSettingsFilePath)) { LunaLog.Log("[LMP]: Backing up player token and settings file!"); File.Copy(SettingsFilePath, BackupSettingsFilePath); } return(LunaXmlSerializer.ReadXmlFromPath <SettingStructure>(SettingsFilePath)); }
/// <summary> /// Here we handle an unloaded flag and we load it into the game /// </summary> private static void HandleFlag(ExtendedFlagInfo flagInfo) { if (HighLogic.CurrentGame.flagURL.Contains("LunaMultiPlayer/Flags/")) { var currentFlagName = HighLogic.CurrentGame.flagURL.Substring("LunaMultiPlayer/Flags/".Length); //If the flag name is the same as ours just skip it as otherwise we would overwrite ours if (currentFlagName == flagInfo.FlagName) { return; } } var flagTexture = new Texture2D(4, 4); if (flagTexture.LoadImage(flagInfo.FlagData)) { //Flags have names like: Squad/Flags/default or LunaMultiplayer/Flags/coolflag flagTexture.name = "LunaMultiPlayer/Flags/" + Path.GetFileNameWithoutExtension(flagInfo.FlagName); File.WriteAllBytes(flagInfo.FlagPath, flagInfo.FlagData); var textureInfo = new GameDatabase.TextureInfo(null, flagTexture, false, true, false) { name = flagTexture.name }; var textureExists = GameDatabase.Instance.databaseTexture.Any(t => t.name == textureInfo.name); if (!textureExists) { GameDatabase.Instance.databaseTexture.Add(textureInfo); } else { GameDatabase.Instance.ReplaceTexture(textureInfo.name, textureInfo); } LunaLog.Log($"[LMP]: Loaded {flagTexture.name}"); } else { LunaLog.LogError($"[LMP]: Failed to load flag {flagInfo.FlagName}"); } }
/// <summary> /// Check vessels that must be loaded /// </summary> private void CheckVesselsToLoad() { try { if (ProtoSystemBasicReady) { //Load vessels that don't exist, are in our subspace and out of safety bubble var vesselsToLoad = VesselsProtoStore.AllPlayerVessels.Where(v => !v.Value.VesselExist && v.Value.ShouldBeLoaded); foreach (var vesselProto in vesselsToLoad) { if (VesselRemoveSystem.VesselWillBeKilled(vesselProto.Key)) { continue; } //Only load vessels that are in safety bubble on the track station if (vesselProto.Value.IsInSafetyBubble && HighLogic.LoadedScene != GameScenes.TRACKSTATION) { continue; } if (VesselCommon.ActiveVesselIsInSafetyBubble() && VesselCommon.IsNearKsc(vesselProto.Value.ProtoVessel, 20000)) { continue; } LunaLog.Log($"[LMP]: Loading vessel {vesselProto.Key}"); CurrentlyUpdatingVesselId = vesselProto.Key; if (VesselLoader.LoadVessel(vesselProto.Value.ProtoVessel)) { LunaLog.Log($"[LMP]: Vessel {vesselProto.Key} loaded"); } CurrentlyUpdatingVesselId = Guid.Empty; } } } catch (Exception e) { LunaLog.LogError($"[LMP]: Error in CheckVesselsToLoad {e}"); } }
public static IEnumerator CheckForUpdates() { using (var www = new WWW(RepoConstants.ApiLatestGithubReleaseUrl)) { while (!www.isDone) { yield return(Wait); } if (www.error == null) { if (!(Json.Deserialize(www.text) is Dictionary <string, object> data)) { yield break; } var latestVersion = new Version(data["tag_name"].ToString()); LunaLog.Log($"Latest version: {latestVersion}"); if (latestVersion > LmpVersioning.CurrentVersion) { using (var www2 = new WWW(data["url"].ToString())) { while (!www2.isDone) { yield return(Wait); } if (www2.error == null) { var changelog = data["body"].ToString(); UpdateWindow.LatestVersion = latestVersion; UpdateWindow.Changelog = changelog; UpdateWindow.Singleton.Display = true; } } } } else { LunaLog.Log($"Could not check for latest version. Error: {www.error}"); } } }
/// <summary> /// Refreshes all the protovessel part modules based on a part. /// Will return true if there's a change in any of the values /// </summary> private static bool RefreshPartModules(Part part) { if (part.protoPartSnapshot.modules.Count != part.Modules.Count) { part.protoPartSnapshot.modules.Clear(); for (var i = 0; i < part.Modules.Count; i++) { part.protoPartSnapshot.modules.Add(new ProtoPartModuleSnapshot(part.Modules[i])); } return(true); } var moduleHaveChanges = false; for (var i = 0; i < part.Modules.Count; i++) { var module = part.Modules[i]; for (var j = 0; j < module.Fields.Count; j++) { var field = module.Fields[j]; var nodeValue = GetConfigNodeVal(field.name, module.snapshot.moduleValues); if (nodeValue?.value != null) { var fieldValueAsString = field.GetStringValue(field.host, false); if (fieldValueAsString != null && nodeValue.value != fieldValueAsString) { if (!ModuleIsIgnored(module.moduleName) && !FieldIsIgnored(module, field)) { LunaLog.Log($"Detected a part module change. Module: {module.moduleName} field: {field.name}"); moduleHaveChanges = true; } nodeValue.value = fieldValueAsString; } } } } return(moduleHaveChanges); }
public void SendFlag(string flagUrl) { //If it's a default flag skip the sending if (DefaultFlags.DefaultFlagList.Contains(flagUrl)) { return; } //If the flag is owned by someone else don't sync it if (ServerFlags.TryGetValue(flagUrl, out var existingFlag) && existingFlag.Owner != SettingsSystem.CurrentSettings.PlayerName) { return; } var textureInfo = GameDatabase.Instance.GetTextureInfo(flagUrl); if (textureInfo != null) { var filePath = CommonUtil.CombinePaths(MainSystem.KspPath, "GameData", $"{flagUrl}.png"); if (!File.Exists(filePath)) { LunaLog.LogError($"Cannot upload flag {Path.GetFileName(flagUrl)} file not found"); return; } var flagData = File.ReadAllBytes(filePath); if (flagData.Length > 1000000) { LunaLog.LogError($"Cannot upload flag {Path.GetFileName(flagUrl)} size is greater than 1Mb!"); return; } //Don't send the flag when the SHA sum already matches as that would mean that the server already has it if (existingFlag != null && existingFlag.ShaSum == Common.CalculateSha256Hash(flagData)) { return; } LunaLog.Log($"[LMP]: Uploading {Path.GetFileName(flagUrl)} flag"); MessageSender.SendMessage(MessageSender.GetFlagMessageData(flagUrl, flagData)); } }
/// <summary> /// Loads the vessel proto into the current game /// </summary> private static bool LoadVesselIntoGame(ProtoVessel currentProto) { if (HighLogic.CurrentGame?.flightState == null) { return(false); } LunaLog.Log($"[LMP]: Loading {currentProto.vesselID}, Name: {currentProto.vesselName}, type: {currentProto.vesselType}"); currentProto.Load(HighLogic.CurrentGame.flightState); if (currentProto.vesselRef == null) { LunaLog.Log($"[LMP]: Protovessel {currentProto.vesselID} failed to create a vessel!"); return(false); } if (currentProto.vesselRef.isEVA) { var evaModule = currentProto.vesselRef.FindPartModuleImplementing <KerbalEVA>(); if (evaModule != null && evaModule.fsm != null && !evaModule.fsm.Started) { evaModule.fsm?.StartFSM("Idle (Grounded)"); } currentProto.vesselRef.GoOnRails(); } currentProto.vesselRef.orbitDriver?.updateFromParameters(); PlayerColorSystem.Singleton.SetVesselOrbitColor(currentProto.vesselRef); if (HighLogic.LoadedScene == GameScenes.TRACKSTATION) { //When in trackstation rebuild the vessels left panel as otherwise the new vessel won't be listed var spaceTracking = Object.FindObjectOfType <SpaceTracking>(); if (spaceTracking != null) { BuildSpaceTrackingVesselList?.Invoke(spaceTracking, null); } } KSCVesselMarkers.fetch?.RefreshMarkers(); return(true); }
public void HandleMessage(IMessageData messageData) { var msgData = messageData as PlayerColorBaseMsgData; if (msgData == null) { return; } switch (msgData.PlayerColorMessageType) { case PlayerColorMessageType.Reply: { var data = (PlayerColorReplyMsgData)messageData; System.PlayerColors.Clear(); for (var i = 0; i < data.Count; i++) { var playerName = data.PlayersColors[i].Key; var playerColor = System.ConvertStringToColor(data.PlayersColors[i].Value); System.PlayerColors.Add(playerName, playerColor); WindowsContainer.Get <StatusWindow>().ColorEventHandled = false; //Refresh colors in status window } SystemsContainer.Get <MainSystem>().NetworkState = ClientState.ColorsSynced; } break; case PlayerColorMessageType.Set: { //Player joined or changed it's color so update his controlled vessel orbit colors var data = (PlayerColorSetMsgData)messageData; var playerName = data.PlayerName; var playerColor = System.ConvertStringToColor(data.Color); LunaLog.Log($"[LMP]: Color Message, Name: {playerName} , color: {playerColor}"); System.PlayerColors[playerName] = playerColor; UpdateVesselColors(playerName); WindowsContainer.Get <StatusWindow>().ColorEventHandled = false; //Refresh colors in status window } break; } }
public static VesselPositionMsgData CreateMessageFromVessel(Vessel vessel) { if (!OrbitParametersAreOk(vessel)) { return(null); } var msgData = MessageFactory.CreateNewMessageData <VesselPositionMsgData>(); msgData.PingMs = NetworkStatistics.PingMs; msgData.SubspaceId = WarpSystem.Singleton.CurrentSubspace; msgData.GameTime = TimeSyncSystem.UniversalTime; try { msgData.VesselId = vessel.id; msgData.BodyIndex = vessel.mainBody.flightGlobalsIndex; msgData.Landed = vessel.Landed; msgData.Splashed = vessel.Splashed; SetSrfRelRotation(vessel, msgData); SetLatLonAlt(vessel, msgData); SetVelocityVector(vessel, msgData); SetNormalVector(vessel, msgData); SetOrbit(vessel, msgData); msgData.HeightFromTerrain = vessel.heightFromTerrain; if (MainSystem.BodiesGees.TryGetValue(vessel.mainBody, out var bodyGee)) { msgData.HackingGravity = Math.Abs(bodyGee - vessel.mainBody.GeeASL) > 0.0001; } msgData.HackingGravity = false; return(msgData); } catch (Exception e) { LunaLog.Log($"[LMP]: Failed to get vessel position update, exception: {e}"); } return(null); }
/// <summary> /// Called when 2 parts couple /// </summary> /// <param name="partAction"></param> public void OnPartCouple(GameEvents.FromToAction <Part, Part> partAction) { if (!VesselCommon.IsSpectating) { if (partAction.from.vessel != null && partAction.to.vessel != null) { var dock = new VesselDockStructure(partAction.from.vessel.id, partAction.to.vessel.id); if (dock.StructureIsOk()) { //We add it to the event so the event is handled AFTER all the docking event in ksp is over and we can //safely remove the weak vessel from the game and save the updated dominant vessel. VesselDockings.Add(dock.DominantVesselId, dock); } } } else { LunaLog.Log("[LMP]: Spectator docking happened. This needs to be fixed later."); } }
/// <summary> /// Kills and unloads a vessel. /// </summary> public void KillVessel(Guid vesselId) { //ALWAYS remove it from the proto store as this dictionary is maintained even if we are in the KSC //This means that while in KSC if we receive a vessel remove msg, our FlightGlobals.Vessels will be empty //But our VesselsProtoStore probably contains that vessel that must be removed. VesselsProtoStore.RemoveVessel(vesselId); var killVessel = FlightGlobals.FindVessel(vesselId); if (killVessel == null || killVessel.state == Vessel.State.DEAD) { return; } LunaLog.Log($"[LMP]: Killing vessel {killVessel.id}"); SwitchVesselIfSpectating(killVessel); UnloadVesselFromGame(killVessel); KillGivenVessel(killVessel); UnloadVesselFromScenario(killVessel); }
/// <summary> /// This event is called when the vessel is recovered /// </summary> public void OnVesselRecovered(ProtoVessel recoveredVessel, bool quick) { //quick == true when you press "space center" from the inflight menu if (!LockSystem.LockQuery.CanRecoverOrTerminateTheVessel(recoveredVessel.vesselID, SettingsSystem.CurrentSettings.PlayerName)) { LunaScreenMsg.PostScreenMessage(LocalizationContainer.ScreenText.CannotRecover, 5f, ScreenMessageStyle.UPPER_CENTER); return; } _recoveringTerminatingVesselId = recoveredVessel.vesselID; LunaLog.Log($"[LMP]: Removing vessel {recoveredVessel.vesselID}, Name: {recoveredVessel.vesselName} from the server: Recovered"); System.MessageSender.SendVesselRemove(recoveredVessel.vesselID); //Vessel is recovered so remove the locks LockSystem.Singleton.ReleaseAllVesselLocks(recoveredVessel.GetVesselCrew().Select(c => c.name), recoveredVessel.vesselID); System.KillVessel(_recoveringTerminatingVesselId, "Recovering vessel"); }
public void OnDockingComplete(GameEvents.FromToAction <Part, Part> data) { LunaLog.Log(_ownDominantVessel ? $"[LMP]: Docking finished! We own the dominant vessel {CurrentDockEvent.DominantVesselId}" : $"[LMP]: Docking finished! We DON'T own the dominant vessel {CurrentDockEvent.DominantVesselId}"); JumpIfVesselOwnerIsInFuture(CurrentDockEvent.DominantVesselId); if (_ownDominantVessel) { System.MessageSender.SendDockInformation(CurrentDockEvent.WeakVesselId, FlightGlobals.ActiveVessel, WarpSystem.Singleton.CurrentSubspace); VesselProtoSystem.Singleton.MessageSender.SendVesselMessage(FlightGlobals.ActiveVessel); } else { CoroutineUtil.StartDelayedRoutine("OnDockingComplete", () => System.MessageSender.SendDockInformation(CurrentDockEvent.WeakVesselId, FlightGlobals.ActiveVessel, WarpSystem.Singleton.CurrentSubspace), 3); } VesselRemoveSystem.Singleton.MessageSender.SendVesselRemove(CurrentDockEvent.WeakVesselId, false); }
/// <summary> /// This event is called when vessel is terminated from track station /// </summary> public void OnVesselTerminated(ProtoVessel terminatedVessel) { if (!LockSystem.LockQuery.CanRecoverOrTerminateTheVessel(terminatedVessel.vesselID, SettingsSystem.CurrentSettings.PlayerName)) { LunaScreenMsg.PostScreenMessage(LocalizationContainer.ScreenText.CannotTerminate, 5f, ScreenMessageStyle.UPPER_CENTER); return; } _recoveringTerminatingVesselId = terminatedVessel.vesselID; LunaLog.Log($"[LMP]: Removing vessel {terminatedVessel.vesselID}, Name: {terminatedVessel.vesselName} from the server: Terminated"); System.MessageSender.SendVesselRemove(terminatedVessel.vesselID); //Vessel is terminated so remove locks Do not remove the kerbal locks as that's done in the Kerbal system LockSystem.Singleton.ReleaseAllVesselLocks(null, terminatedVessel.vesselID, 1000); //We consider this vessel removed but we let KSP do the remove of the vessel System.RemovedVessels.TryAdd(terminatedVessel.vesselID, DateTime.Now); RemoveEvent.onLmpRecoveredVessel.Fire(terminatedVessel); }
/// <summary> /// This event is called when the vessel gone BOOM /// If we have the update lock of it we kill it /// It doesn't matter if we own the control lock or not as perhaps we are killing a vessel of a player who disconnected. /// </summary> public void OnVesselDestroyed(Vessel dyingVessel) { if (dyingVessel.state != Vessel.State.DEAD) { return; } //Only remove the vessel if we own the update lock if (SystemsContainer.Get <LockSystem>().LockIsOurs($"update-{dyingVessel.id}")) { LunaLog.Log($"[LMP]: Removing vessel {dyingVessel.id}, Name: {dyingVessel.vesselName} from the server: Destroyed"); SystemsContainer.Get <KerbalSystem>().MessageSender.SendKerbalsInVessel(dyingVessel); System.MessageSender.SendVesselRemove(dyingVessel.id); //Vessel is dead so remove the locks SystemsContainer.Get <LockSystem>().ReleaseLock($"control-{dyingVessel.id}"); SystemsContainer.Get <LockSystem>().ReleaseLock($"update-{dyingVessel.id}"); } }
private static void CheckNonDllFile(List <string> gameFileRelativePaths, KeyValuePair <string, string> requiredEntry, bool required) { var filePath = gameFileRelativePaths.FirstOrDefault( f => f.Equals(requiredEntry.Key, StringComparison.OrdinalIgnoreCase)); if (string.IsNullOrEmpty(filePath) && required) //Only show error if the file is required { ModCheckOk = false; LunaLog.Log($"[LMP]: Required file {requiredEntry.Key} is missing!"); StringBuilder.AppendLine($"Required file {requiredEntry.Key} is missing!"); return; } //If the entry exists and has a SHA sum, we need to check it. if (!string.IsNullOrEmpty(filePath) && requiredEntry.Value != "") { EvaluateShaSum(filePath, requiredEntry); } }
private static void AddCraftEntry(string playerName, CraftType craftType, string craftName) { if (!System.PlayersWithCrafts.Contains(playerName)) { System.PlayersWithCrafts.Add(playerName); } if (!System.PlayerList.ContainsKey(playerName)) { System.PlayerList.Add(playerName, new Dictionary <CraftType, List <string> >()); } if (!System.PlayerList[playerName].ContainsKey(craftType)) { System.PlayerList[playerName].Add(craftType, new List <string>()); } if (!System.PlayerList[playerName][craftType].Contains(craftName)) { LunaLog.Log($"[LMP]: Adding {craftName}, type: {craftType} from {playerName}"); System.PlayerList[playerName][craftType].Add(craftName); } }
private static void CheckDllFile(KeyValuePair <string, string> requiredEntry, bool required) { var fileExists = SystemsContainer.Get <ModSystem>().DllList.ContainsKey(requiredEntry.Key); if (!fileExists && required) { ModCheckOk = false; LunaLog.Log($"[LMP]: Required file {requiredEntry.Key} is missing!"); StringBuilder.AppendLine($"Required file {requiredEntry.Key} is missing!"); return; } if (fileExists && requiredEntry.Value != "" && SystemsContainer.Get <ModSystem>().DllList[requiredEntry.Key] != requiredEntry.Value) { ModCheckOk = false; LunaLog.Log($"[LMP]: Required file {requiredEntry.Key} does not match hash {requiredEntry.Value}!"); StringBuilder.AppendLine($"Required file {requiredEntry.Key} does not match hash {requiredEntry.Value}!"); } }
public void ExternalSeatBoard(KerbalSeat seat, Guid kerbalVesselId, uint kerbalVesselPersistentId, string kerbalName) { if (VesselCommon.IsSpectating) { return; } if (seat.vessel == null) { return; } LunaLog.Log("Crew-board to an external seat detected!"); VesselRemoveSystem.Singleton.MessageSender.SendVesselRemove(kerbalVesselId); VesselRemoveSystem.Singleton.AddToKillList(kerbalVesselId, "Killing kerbal as it boarded a external seat"); LockSystem.Singleton.ReleaseAllVesselLocks(new[] { kerbalName }, kerbalVesselId); VesselProtoSystem.Singleton.MessageSender.SendVesselMessage(seat.vessel); }
/// <summary> /// Send a request to the master server to introduce us and do the nat punchtrough to the selected server /// </summary> public static void IntroduceToServer(long serverId) { if (Servers.TryGetValue(serverId, out var serverInfo)) { if (ServerIsInLocalLan(serverInfo.ExternalEndpoint) || ServerIsInLocalLan(serverInfo.InternalEndpoint6)) { LunaLog.Log("Server is in LAN. Skipping NAT punch"); var endpoints = new List <IPEndPoint>(); if (!serverInfo.InternalEndpoint6.Address.Equals(IPAddress.IPv6Loopback)) { endpoints.Add(serverInfo.InternalEndpoint6); } if (!serverInfo.InternalEndpoint.Address.Equals(IPAddress.Loopback)) { endpoints.Add(serverInfo.InternalEndpoint); } NetworkConnection.ConnectToServer(endpoints.ToArray(), Password); } else { try { var msgData = NetworkMain.CliMsgFactory.CreateNewMessageData <MsIntroductionMsgData>(); msgData.Id = serverId; msgData.Token = MainSystem.UniqueIdentifier; msgData.InternalEndpoint = new IPEndPoint(LunaNetUtils.GetOwnInternalIPv4Address(), NetworkMain.ClientConnection.Port); msgData.InternalEndpoint6 = new IPEndPoint(LunaNetUtils.GetOwnInternalIPv6Address(), NetworkMain.ClientConnection.Port); var introduceMsg = NetworkMain.MstSrvMsgFactory.CreateNew <MainMstSrvMsg>(msgData); MainSystem.Singleton.Status = string.Empty; LunaLog.Log($"[LMP]: Sending NAT introduction to master servers. Token: {MainSystem.UniqueIdentifier}"); NetworkSender.QueueOutgoingMessage(introduceMsg); } catch (Exception e) { LunaLog.LogError($"[LMP]: Error connecting to server: {e}"); } } } }
public void HandleMessage(IServerMessageBase msg) { if (!(msg.Data is ShareProgressBaseMsgData msgData)) { return; } if (msgData.ShareProgressMessageType != ShareProgressMessageType.FundsUpdate) { return; } if (msgData is ShareProgressFundsMsgData data) { var funds = data.Funds; //create a copy of the funds value so it will not change in the future. LunaLog.Log($"Queue FundsUpdate with: {funds}"); ShareCareerSystem.Singleton.QueueAction(() => { FundsUpdate(funds); }); } }
public void HandleMessage(IServerMessageBase msg) { if (!(msg.Data is ShareProgressBaseMsgData msgData)) { return; } if (msgData.ShareProgressMessageType != ShareProgressMessageType.ScienceSubjectUpdate) { return; } if (msgData is ShareProgressScienceSubjectMsgData data) { var subject = new ScienceSubjectInfo(data.ScienceSubject); //create a copy of the tech value so it will not change in the future. LunaLog.Log($"Queue Science subject: {subject.Id}"); System.QueueAction(() => { NewScienceSubject(subject); }); } }
public void HandleMessage(IServerMessageBase msg) { if (!(msg.Data is ShareProgressBaseMsgData msgData)) { return; } if (msgData.ShareProgressMessageType != ShareProgressMessageType.StrategyUpdate) { return; } if (msgData is ShareProgressStrategyMsgData data) { var strategy = new StrategyInfo(data.Strategy); //create a copy of the strategyInfo object so it will not change in the future. LunaLog.Log($"Queue StrategyUpdate with: {strategy.Name}"); System.QueueAction(() => { StrategyUpdate(strategy); }); } }
public void HandleMessage(IServerMessageBase msg) { if (!(msg.Data is ShareProgressBaseMsgData msgData)) { return; } if (msgData.ShareProgressMessageType != ShareProgressMessageType.ScienceUpdate) { return; } if (msgData is ShareProgressScienceMsgData data) { var science = data.Science; //create a copy of the science value so it will not change in the future. LunaLog.Log($"Queue ScienceUpdate with: {science}"); System.QueueAction(() => { ScienceUpdate(science); }); } }