public static bool ParseModFile(string modFileData) { if (SystemsContainer.Get <ModSystem>().ModControl == ModControlMode.Disabled) { return(true); } Sb.Length = 0; SystemsContainer.Get <ModSystem>().LastModFileData = modFileData; //Save mod file so we can recheck it. SaveCurrentModConfigurationFile(); var modFileInfo = ModFileParser.ReadModFile(modFileData); if (!CheckFiles(modFileInfo)) { LunaLog.LogError("[LMP]: Mod check failed!"); LunaLog.LogError(Sb.ToString()); SystemsContainer.Get <ModSystem>().FailText = Sb.ToString(); WindowsContainer.Get <ModWindow>().Display = true; return(false); } SystemsContainer.Get <ModSystem>().AllowedParts = modFileInfo.PartList; LunaLog.Log("[LMP]: Mod check passed!"); return(true); }
public static bool ParseModFile(string modFileData) { if (SystemsContainer.Get <ModSystem>().ModControl == ModControlMode.Disabled) { return(true); } SystemsContainer.Get <ModSystem>().LastModFileData = modFileData; //Save mod file so we can recheck it. StringBuilder = new StringBuilder(); ParseRequired.Clear(); ParseOptional.Clear(); WhiteList.Clear(); BlackList.Clear(); PartsList.Clear(); SaveCurrentModConfigurationFile(); ReadModConfigurationFile(modFileData); CheckFiles(); if (!ModCheckOk) { SystemsContainer.Get <ModSystem>().FailText = StringBuilder.ToString(); WindowsContainer.Get <ModWindow>().Display = true; return(false); } SystemsContainer.Get <ModSystem>().AllowedParts = PartsList; LunaLog.Log("[LMP]: Mod check passed!"); return(true); }
/// <summary> /// This routine handles the asteroid track status between clients /// </summary> private void CheckAsteroidsStatus() { if (!Enabled) { return; } //Check for changes to tracking foreach (var asteroid in GetCurrentAsteroids().Where(asteroid => asteroid.state != Vessel.State.DEAD)) { if (!ServerAsteroidTrackStatus.ContainsKey(asteroid.id.ToString())) { ServerAsteroidTrackStatus.Add(asteroid.id.ToString(), asteroid.DiscoveryInfo.trackingStatus.Value); } else { if (asteroid.DiscoveryInfo.trackingStatus.Value != ServerAsteroidTrackStatus[asteroid.id.ToString()]) { LunaLog.Log($"[LMP]: Sending changed asteroid, new state: {asteroid.DiscoveryInfo.trackingStatus.Value}!"); ServerAsteroidTrackStatus[asteroid.id.ToString()] = asteroid.DiscoveryInfo.trackingStatus.Value; SystemsContainer.Get <VesselProtoSystem>().MessageSender.SendVesselMessage(asteroid, true); } } } }
private static void CreateMissingKerbalsInProgressTrackingSoTheGameDoesntBugOut(ConfigNode progressTrackingNode) { foreach (var possibleNode in progressTrackingNode.nodes) { CreateMissingKerbalsInProgressTrackingSoTheGameDoesntBugOut(possibleNode as ConfigNode); } //The kerbals are kept in a ConfigNode named 'crew', with 'crews' as a comma space delimited array of names. if (progressTrackingNode.name == "crew") { var kerbalNames = progressTrackingNode.GetValue("crews"); if (!string.IsNullOrEmpty(kerbalNames)) { var kerbalNamesSplit = kerbalNames.Split(new[] { ", " }, StringSplitOptions.RemoveEmptyEntries); foreach (var kerbalName in kerbalNamesSplit.Where(k => !HighLogic.CurrentGame.CrewRoster.Exists(k))) { LunaLog.Log($"[LMP]: Generating missing kerbal from ProgressTracking: {kerbalName}"); var pcm = CrewGenerator.RandomCrewMemberPrototype(); pcm.ChangeName(kerbalName); HighLogic.CurrentGame.CrewRoster.AddCrewMember(pcm); //Also send it off to the server SystemsContainer.Get <KerbalSystem>().MessageSender.SendKerbal(pcm); } } } }
/// <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); } SystemsContainer.Get <PlayerColorSystem>().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); } } return(true); }
/// <summary> /// Prints the banned parts message /// </summary> private void UpdateBannedPartsMessage() { try { if (ProtoSystemReady && !string.IsNullOrEmpty(BannedPartsStr)) { if (BannedPartsMessage != null) { BannedPartsMessage.duration = 0; } if (SystemsContainer.Get <ModSystem>().ModControl == ModControlMode.EnabledStopInvalidPartSync) { BannedPartsMessage = ScreenMessages.PostScreenMessage($"Active vessel contains the following banned parts, it will not be saved to the server:\n{BannedPartsStr}", 2f, ScreenMessageStyle.UPPER_CENTER); } if (SystemsContainer.Get <ModSystem>().ModControl == ModControlMode.EnabledStopInvalidPartLaunch) { BannedPartsMessage = ScreenMessages.PostScreenMessage($"Active vessel contains the following banned parts, you will be unable to launch on this server:\n{BannedPartsStr}", 2f, ScreenMessageStyle.UPPER_CENTER); } } } catch (Exception e) { LunaLog.LogError($"[LMP]: Error in UpdateBannedPartsMessage {e}"); } }
/// <summary> /// Event called when a part is dead and removed from the game /// </summary> public void OnPartDie(Part data) { if (VesselCommon.IsSpectating || data.vessel == null) { return; } if (data.vessel.id != VesselProtoSystem.CurrentlyUpdatingVesselId && !SystemsContainer.Get <VesselRemoveSystem>().VesselWillBeKilled(data.vessel.id)) { if (VesselsProtoStore.AllPlayerVessels.ContainsKey(data.vessel.id)) { if (!LockSystem.LockQuery.UpdateLockBelongsToPlayer(data.vessel.id, SettingsSystem.CurrentSettings.PlayerName)) { VesselsProtoStore.AllPlayerVessels[data.vessel.id].VesselHasUpdate = true; } } else { //The vessel is NEW as it's not in the store. It might be a debris... var rootPartOrFirstPart = data.vessel.rootPart ?? data.vessel.parts.FirstOrDefault(); if (rootPartOrFirstPart != null) { var originalVessel = VesselsProtoStore.GetVesselByPartId(rootPartOrFirstPart.flightID); if (originalVessel == null) { return; } if (!LockSystem.LockQuery.UpdateLockBelongsToPlayer(originalVessel.id, SettingsSystem.CurrentSettings.PlayerName)) { VesselsProtoStore.AllPlayerVessels[originalVessel.id].VesselHasUpdate = true; } } } } }
/// <summary> /// Check vessels that must be reloaded /// </summary> private void CheckVesselsToReload() { try { if (ProtoSystemBasicReady && !VesselCommon.ActiveVesselIsInSafetyBubble()) { //Reload vessels that exist var vesselsToReLoad = AllPlayerVessels .Where(pv => !pv.Value.Loaded && pv.Value.VesselExist) .ToArray(); foreach (var vesselProto in vesselsToReLoad) { if (SystemsContainer.Get <VesselRemoveSystem>().VesselWillBeKilled(vesselProto.Key)) { continue; } LunaLog.Log($"[LMP]: Reloading vessel {vesselProto.Key}"); if (VesselLoader.ReloadVessel(vesselProto.Value.ProtoVessel)) { vesselProto.Value.Loaded = true; LunaLog.Log($"[LMP]: Vessel {vesselProto.Key} reloaded"); UpdateVesselProtoInDictionary(vesselProto.Value); } } } } catch (Exception e) { LunaLog.LogError($"[LMP]: Error in CheckVesselsToReload {e}"); } }
public override void Update() { SafeDisplay = Display; if (Display && Time.realtimeSinceStartup - LastUpdateTime > DisplayUpdateInterval || DisplayFast) { LastUpdateTime = Time.realtimeSinceStartup; //Vector text if (HighLogic.LoadedScene == GameScenes.FLIGHT && FlightGlobals.ready && FlightGlobals.ActiveVessel != null) { var ourVessel = FlightGlobals.ActiveVessel; VectorText = $"Forward vector: {ourVessel.GetFwdVector()}\n"; VectorText += $"Up vector: {(Vector3)ourVessel.upAxis}\n"; VectorText += $"Srf Rotation: {ourVessel.srfRelRotation}\n"; VectorText += $"Vessel Rotation: {ourVessel.transform.rotation}\n"; VectorText += $"Vessel Local Rotation: {ourVessel.transform.localRotation}\n"; VectorText += $"mainBody Rotation: {(Quaternion)ourVessel.mainBody.rotation}\n"; VectorText += $"mainBody Transform Rotation: {ourVessel.mainBody.bodyTransform.rotation}\n"; VectorText += $"Surface Velocity: {ourVessel.GetSrfVelocity()}, |v|: {ourVessel.GetSrfVelocity().magnitude}\n"; VectorText += $"Orbital Velocity: {ourVessel.GetObtVelocity()}, |v|: {ourVessel.GetObtVelocity().magnitude}\n"; if (ourVessel.orbitDriver != null && ourVessel.orbitDriver.orbit != null) { VectorText += $"Frame Velocity: {(Vector3)ourVessel.orbitDriver.orbit.GetFrameVel()}, |v|: {ourVessel.orbitDriver.orbit.GetFrameVel().magnitude}\n"; } VectorText += $"CoM offset vector: {ourVessel.CoM}\n"; VectorText += $"Angular Velocity: {ourVessel.angularVelocity}, |v|: {ourVessel.angularVelocity.magnitude}\n"; VectorText += $"World Pos: {(Vector3)ourVessel.GetWorldPos3D()}, |pos|: {ourVessel.GetWorldPos3D().magnitude}\n"; } else { VectorText = "You have to be in flight"; } //NTP text NtpText = $"Warp rate: {Math.Round(Time.timeScale, 3)}x.\n"; NtpText += $"Current subspace: {SystemsContainer.Get<WarpSystem>().CurrentSubspace}.\n"; NtpText += $"Current Error: {Math.Round(SystemsContainer.Get<TimeSyncerSystem>().GetCurrentError() * 1000, 0)}ms.\n"; NtpText += $"Current universe time: {Math.Round(Planetarium.GetUniversalTime(), 3)} UT\n"; NtpText += $"Network latency: {Math.Round(SystemsContainer.Get<TimeSyncerSystem>().NetworkLatencyAverage / 10000f, 3)}ms\n"; NtpText += $"Server clock difference: {Math.Round(SystemsContainer.Get<TimeSyncerSystem>().ClockOffsetAverage / 10000f, 3)}ms\n"; NtpText += $"Server lag: {Math.Round(SystemsContainer.Get<TimeSyncerSystem>().ServerLag / 10000f, 3)}ms\n"; //Connection queue text ConnectionText = $"Ping: {NetworkStatistics.GetStatistics("Ping")}ms.\n"; ConnectionText += $"Last send time: {NetworkStatistics.GetStatistics("LastSendTime")}ms ago.\n"; ConnectionText += $"Last receive time: {NetworkStatistics.GetStatistics("LastReceiveTime")}ms ago.\n"; ConnectionText += $"Sent bytes: {NetworkStatistics.GetStatistics("SentBytes")}.\n"; ConnectionText += $"Received bytes: {NetworkStatistics.GetStatistics("ReceivedBytes")}.\n"; ConnectionText += $"Queued out msgs: {NetworkStatistics.GetStatistics("QueuedOutgoingMessages")}.\n"; //Vessel update system VesselUpdateText = $"Queued messages: {SystemsContainer.Get<VesselUpdateSystem>().MessageHandler.IncomingMessages.Count}.\n"; VesselUpdateText += $"Spectating: {VesselCommon.IsSpectating}.\n"; VesselUpdateText += "Active vessel control lock: " + $"{FlightGlobals.ActiveVessel != null && LockSystem.LockQuery.ControlLockBelongsToPlayer(FlightGlobals.ActiveVessel.id, SettingsSystem.CurrentSettings.PlayerName)}.\n"; VesselUpdateText += "Active vessel update lock: " + $"{FlightGlobals.ActiveVessel != null && LockSystem.LockQuery.UpdateLockBelongsToPlayer(FlightGlobals.ActiveVessel.id, SettingsSystem.CurrentSettings.PlayerName)}.\n"; } }
private static void HandleVesselProto(VesselProtoMsgData messageData) { if (!SystemsContainer.Get <VesselRemoveSystem>().VesselWillBeKilled(messageData.Vessel.VesselId) && messageData.Vessel.VesselId != Guid.Empty) { VesselsProtoStore.HandleVesselProtoData(messageData.Vessel.Data, messageData.Vessel.NumBytes, messageData.Vessel.VesselId); } }
/// <summary> /// Check vessels that must be loaded /// </summary> private void CheckVesselsToLoad() { try { if (ProtoSystemBasicReady && !VesselCommon.ActiveVesselIsInSafetyBubble()) { //Load vessels that don't exist and are in our subspace var vesselsToLoad = AllPlayerVessels .Where(v => !v.Value.Loaded && !v.Value.VesselExist && (SettingsSystem.ServerSettings.ShowVesselsInThePast || !VesselCommon.VesselIsControlledAndInPastSubspace(v.Value.VesselId))) .ToArray(); foreach (var vesselProto in vesselsToLoad) { if (SystemsContainer.Get <VesselRemoveSystem>().VesselWillBeKilled(vesselProto.Key)) { continue; } LunaLog.Log($"[LMP]: Loading vessel {vesselProto.Key}"); if (VesselLoader.LoadVessel(vesselProto.Value.ProtoVessel)) { vesselProto.Value.Loaded = true; LunaLog.Log($"[LMP]: Vessel {vesselProto.Key} loaded"); UpdateVesselProtoInDictionary(vesselProto.Value); } } } } catch (Exception e) { LunaLog.LogError($"[LMP]: Error in CheckVesselsToLoad {e}"); } }
/// <summary> /// Here we wait until we fully switched to the dominant vessel and THEN we send the vessel dock information. /// We wait 5 seconds before sending the data to give time to the dominant vessel to detect the dock /// </summary> private static IEnumerator WaitUntilWeSwitchedThenSendDockInfo(VesselDockStructure dockInfo, ProtoVessel finalVesselProto) { var start = DateTime.Now; var currentSubspaceId = SystemsContainer.Get <WarpSystem>().CurrentSubspace; var waitInterval = new WaitForSeconds(0.5f); while (FlightGlobals.ActiveVessel.id != dockInfo.DominantVesselId && DateTime.Now - start < TimeSpan.FromSeconds(30)) { yield return(waitInterval); } if (FlightGlobals.ActiveVessel?.id == dockInfo.DominantVesselId) { /* We are NOT the dominant vessel so wait 5 seconds so the dominant vessel detects the docking. * If we send the vessel definition BEFORE the dominant detects it, then the dominant won't be able * to undock properly as he will think that he is the weak vessel. */ yield return(new WaitForSeconds(5)); LunaLog.Log($"[LMP]: Sending dock info to the server! Final dominant vessel parts {finalVesselProto.protoPartSnapshots.Count} " + $"Current: {dockInfo.DominantVessel?.parts?.Count}"); System.MessageSender.SendDockInformation(dockInfo, currentSubspaceId, finalVesselProto); } }
/// <summary> /// This event is called when the vessel gone BOOM (the Vessel.Die() is called) /// 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 OnVesselWillDestroy(Vessel dyingVessel) { //We are just reloading a vessel and the vessel.Die() was triggered so we should not do anything! if (dyingVessel.id == VesselLoader.ReloadingVesselId) { return; } //Only send the vessel remove msg if we own the unloaded update lock if (LockSystem.LockQuery.UnloadedUpdateLockBelongsToPlayer(dyingVessel.id, SettingsSystem.CurrentSettings.PlayerName) || dyingVessel.id == _recoveringTerminatingVesselId) { var reason = dyingVessel.id == _recoveringTerminatingVesselId ? "Recovered/Terminated" : "Destroyed"; LunaLog.Log($"[LMP]: Removing vessel {dyingVessel.id}, Name: {dyingVessel.vesselName} from the server: {reason}"); //Add to the kill list so it's also removed from the store later on! System.AddToKillList(dyingVessel.id); SystemsContainer.Get <KerbalSystem>().ProcessKerbalsInVessel(dyingVessel); var killingOwnVessel = FlightGlobals.ActiveVessel?.id == dyingVessel.id; //If we are killing our own vessel there's the possibility that the player hits "revert" so in this case //DO NOT keep it in the remove list System.MessageSender.SendVesselRemove(dyingVessel.id, !killingOwnVessel); //Vessel is dead so remove the locks after 1500ms to get the debris locks if any SystemsContainer.Get <LockSystem>().ReleaseAllVesselLocks(dyingVessel.id, 1500); } }
/// <summary> /// When a stage of ANY vessel is separated, try to get the update lock of that debris /// </summary> /// <param name="data"></param> public void OnStageSeparation(EventReport data) { if (!VesselCommon.IsSpectating) { var debrisVessel = FlightGlobals.FindVessel(data.origin.vessel.id); var missionId = data.origin.missionID; if (!SystemsContainer.Get <LockSystem>().LockWithPrefixExists($"debris-{missionId}")) { SystemsContainer.Get <LockSystem>().AcquireLock($"debris-{missionId}_{debrisVessel.id}"); SystemsContainer.Get <VesselPositionSystem>().MessageSender.SendVesselPositionUpdate(new VesselPositionUpdate(debrisVessel)); } else { var debrisLocks = SystemsContainer.Get <LockSystem>().ServerLocks.Where(l => l.Key.StartsWith($"debris-{missionId}")) .Select(l => l.Key.Substring(l.Key.IndexOf('_') + 1)).ToArray(); var otherVesselsWIthSameMissionId = FlightGlobals.Vessels .Where(v => v.Parts.Any() && v.Parts.First().missionID == missionId && v.id != debrisVessel.id) .Select(v => v.id.ToString()).ToArray(); if (debrisLocks.Length == otherVesselsWIthSameMissionId.Length) { debrisVessel.id = new Guid(debrisLocks.Except(otherVesselsWIthSameMissionId).First()); } else { SystemsContainer.Get <LockSystem>().AcquireLock($"debris-{missionId}_{debrisVessel.id}"); SystemsContainer.Get <VesselPositionSystem>().MessageSender.SendVesselPositionUpdate(new VesselPositionUpdate(debrisVessel)); } } } }
/// <summary> /// Set all other controlled vessels as packed so the movement is better. /// Our vessel must be always unpacked /// </summary> private void PackUnpackVessels() { if (Enabled && VesselRangeSystemReady) { var controlledVessels = VesselCommon.GetControlledVessels(); foreach (var vessel in FlightGlobals.Vessels.Where(v => v.id != FlightGlobals.ActiveVessel.id && !SystemsContainer.Get <VesselRemoveSystem>().VesselWillBeKilled(v.id))) { if (controlledVessels.Contains(vessel)) { if (!SettingsSystem.CurrentSettings.PackOtherControlledVessels) { UnPackVessel(vessel); continue; } if (!vessel.packed) { PackVessel(vessel); } } else { UnPackVessel(vessel); } } } }
public void HandleMessage(IMessageData messageData) { var msgData = messageData as VesselDockMsgData; if (msgData == null) { return; } LunaLog.Log("[LMP]: Docking message received!"); if (FlightGlobals.ActiveVessel?.id == msgData.WeakVesselId) { LunaLog.Log("[LMP]: Docking NOT detected. We DON'T OWN the dominant vessel"); SystemsContainer.Get <VesselRemoveSystem>().AddToKillList(FlightGlobals.ActiveVessel, true); SystemsContainer.Get <VesselSwitcherSystem>().SwitchToVessel(msgData.DominantVesselId); } if (FlightGlobals.ActiveVessel?.id == msgData.DominantVesselId && !VesselCommon.IsSpectating) { var newProto = VesselSerializer.DeserializeVessel(msgData.FinalVesselData); if (VesselCommon.ProtoVesselHasChanges(FlightGlobals.ActiveVessel.protoVessel, newProto)) { LunaLog.Log("[LMP]: Docking NOT detected. We OWN the dominant vessel"); //We own the dominant vessel and dind't detected the docking event so we need to reload our OWN vessel //so if we send our own protovessel later, we send the updated definition SystemsContainer.Get <VesselProtoSystem>().VesselLoader.ReloadVessel(newProto); } } //Some other 2 players docked so just remove the weak vessel. SystemsContainer.Get <VesselRemoveSystem>().AddToKillList(FlightGlobals.FindVessel(msgData.WeakVesselId), true); SystemsContainer.Get <VesselProtoSystem>().HandleVesselProtoData(msgData.FinalVesselData, msgData.DominantVesselId); }
/// <summary> /// This event is called after a game scene is changed. /// </summary> public void OnSceneChanged(GameScenes data) { if (data == GameScenes.FLIGHT) { return; } //Always release the update lock and the spectate lock SystemsContainer.Get <LockSystem>().ReleasePlayerLocks(LockType.Update); SystemsContainer.Get <LockSystem>().ReleaseSpectatorLock(); InputLockManager.RemoveControlLock(VesselLockSystem.SpectateLock); switch (data) { case GameScenes.MAINMENU: case GameScenes.SETTINGS: case GameScenes.CREDITS: ReleaseAsteroidLock(); if (SettingsSystem.ServerSettings.DropControlOnExit) { ReleaseAllControlLocks(); } break; case GameScenes.SPACECENTER: case GameScenes.EDITOR: case GameScenes.TRACKSTATION: case GameScenes.PSYSTEM: if (SettingsSystem.ServerSettings.DropControlOnExitFlight) { ReleaseAllControlLocks(); } break; } }
public void HandleMessage(IMessageData messageData) { var msgData = messageData as PlayerConnectionBaseMsgData; if (msgData == null) { return; } var playerName = msgData.PlayerName; switch (msgData.PlayerConnectionMessageType) { case PlayerConnectionMessageType.Join: SystemsContainer.Get <ChatSystem>().Queuer.QueueChannelMessage(SettingsSystem.ServerSettings.ConsoleIdentifier, "", $"{playerName} has joined the server"); break; case PlayerConnectionMessageType.Leave: SystemsContainer.Get <WarpSystem>().RemovePlayer(playerName); SystemsContainer.Get <StatusSystem>().RemovePlayer(playerName); SystemsContainer.Get <ChatSystem>().Queuer.QueueRemovePlayer(playerName); SystemsContainer.Get <ChatSystem>().Queuer.QueueChannelMessage(SettingsSystem.ServerSettings.ConsoleIdentifier, "", $"{playerName} has left the server"); break; } }
public void HandleDocking(Guid from, Guid to) { var fromVessel = FlightGlobals.FindVessel(from); var toVessel = FlightGlobals.FindVessel(to); var finalVessel = fromVessel != null && toVessel != null ? Vessel.GetDominantVessel(fromVessel, toVessel) : fromVessel ?? toVessel; if (finalVessel != null) { var vesselIdToRemove = finalVessel.id == from ? to : from; if (finalVessel == FlightGlobals.ActiveVessel) { LunaLog.Log($"[LMP]: Docking: We own the dominant vessel {finalVessel.id}"); } else { LunaLog.Log($"[LMP]: Docking: We DON'T own the dominant vessel {finalVessel.id}. Switching"); FlightGlobals.SetActiveVessel(finalVessel); } SystemsContainer.Get <VesselProtoSystem>().RemoveVesselFromLoadingSystem(vesselIdToRemove); SystemsContainer.Get <VesselRemoveSystem>().MessageSender.SendVesselRemove(vesselIdToRemove, true); LunaLog.Log("[LMP]: Docking event over!"); } }
private void StartGameNow() { //Create new game object for our LMP session. HighLogic.CurrentGame = CreateBlankGame(); //Set the game mode HighLogic.CurrentGame.Mode = ConvertGameMode(SettingsSystem.ServerSettings.GameMode); //Set difficulty HighLogic.CurrentGame.Parameters = SettingsSystem.ServerSettings.ServerParameters; SetAdvancedAndCommNetParams(HighLogic.CurrentGame); //Set universe time HighLogic.CurrentGame.flightState.universalTime = SystemsContainer.Get <WarpSystem>().GetCurrentSubspaceTime(); //Load LMP stuff SystemsContainer.Get <KerbalSystem>().LoadKerbalsIntoGame(); SystemsContainer.Get <VesselProtoSystem>().VesselLoader.LoadVesselsIntoGame(); //Load the scenarios from the server SystemsContainer.Get <ScenarioSystem>().LoadScenarioDataIntoGame(); //Load the missing scenarios as well (Eg, Contracts and stuff for career mode SystemsContainer.Get <ScenarioSystem>().LoadMissingScenarioDataIntoGame(); //This only makes KSP complain HighLogic.CurrentGame.CrewRoster.ValidateAssignments(HighLogic.CurrentGame); LunaLog.Log($"[LMP]: Starting {SettingsSystem.ServerSettings.GameMode} game..."); //.Start() seems to stupidly .Load() somewhere - Let's overwrite it so it loads correctly. GamePersistence.SaveGame(HighLogic.CurrentGame, "persistent", HighLogic.SaveFolder, SaveMode.OVERWRITE); HighLogic.CurrentGame.Start(); LunaLog.Log("[LMP]: Started!"); }
private void DrawPlayerEntry(PlayerStatus playerStatus) { if (playerStatus == null) { return; } GUILayout.BeginHorizontal(); if (!PlayerNameStyle.ContainsKey(playerStatus.PlayerName)) { PlayerNameStyle[playerStatus.PlayerName] = new GUIStyle(GUI.skin.label) { normal = { textColor = SystemsContainer.Get <PlayerColorSystem>().GetPlayerColor(playerStatus.PlayerName) }, hover = { textColor = SystemsContainer.Get <PlayerColorSystem>().GetPlayerColor(playerStatus.PlayerName) }, active = { textColor = SystemsContainer.Get <PlayerColorSystem>().GetPlayerColor(playerStatus.PlayerName) }, fontStyle = FontStyle.Bold, stretchWidth = true, wordWrap = false }; } GUILayout.Label(playerStatus.PlayerName, PlayerNameStyle[playerStatus.PlayerName]); GUILayout.FlexibleSpace(); GUILayout.Label(playerStatus.StatusText, StateTextStyle); GUILayout.Label(string.IsNullOrEmpty(playerStatus.VesselText) ? string.Empty : StatusTexts.GetPlayerText(playerStatus), VesselNameStyle); GUILayout.EndHorizontal(); }
public void JoinChannel(string commandArgs) { if (commandArgs != "" && commandArgs != "Global" && commandArgs != SettingsSystem.ServerSettings.ConsoleIdentifier && commandArgs != "#Global" && commandArgs != $"#{SettingsSystem.ServerSettings.ConsoleIdentifier}") { if (commandArgs.StartsWith("#")) { commandArgs = commandArgs.Substring(1); } if (!SystemsContainer.Get <ChatSystem>().JoinedChannels.Contains(commandArgs)) { LunaLog.Log($"[LMP]: Joining Channel {commandArgs}"); SystemsContainer.Get <ChatSystem>().JoinedChannels.Add(commandArgs); SystemsContainer.Get <ChatSystem>().SelectedChannel = commandArgs; SystemsContainer.Get <ChatSystem>().SelectedPmChannel = null; var msgData = NetworkMain.CliMsgFactory.CreateNewMessageData <ChatJoinMsgData>(); msgData.From = SettingsSystem.CurrentSettings.PlayerName; msgData.Channel = commandArgs; System.MessageSender.SendMessage(msgData); } } else { ScreenMessages.PostScreenMessage($"Couldn't join '{commandArgs}', Channel Name not valid!"); } }
/// <summary> /// Make the other player vessels inmortal /// </summary> private void MakeOtherPlayerVesselsImmortal() { if (Enabled && VesselImmortalSystemReady) { var ownedVessels = SystemsContainer.Get <LockSystem>().GetOwnedLocksPrefix("control-").Select(LockSystem.TrimLock) .Union(SystemsContainer.Get <LockSystem>().GetLocksWithPrefix("update-").Select(LockSystem.TrimLock)) .Select(i => FlightGlobals.FindVessel(new Guid(i))) .Where(v => v != null) .ToArray(); var othersPeopleVessels = SystemsContainer.Get <LockSystem>().GetLocksWithPrefix("control-").Select(LockSystem.TrimLock) .Union(SystemsContainer.Get <LockSystem>().GetLocksWithPrefix("update-").Select(LockSystem.TrimLock)) .Except(ownedVessels.Select(v => v.id.ToString())) .Select(i => FlightGlobals.FindVessel(new Guid(i))) //Select the vessels and filter out the nulls .Where(v => v != null).ToArray(); foreach (var vessel in ownedVessels) { SetVesselImmortalState(vessel, false); } foreach (var vessel in othersPeopleVessels) { SetVesselImmortalState(vessel, true); } } }
private void HandleCraftLibraryEvents() { if (Enabled && SystemsContainer.Get <MainSystem>().GameRunning) { CraftLibraryEventHandler.HandleCraftLibraryEvents(); } }
/// <summary> /// This method prepares the protovessel class and send the message, it's intended to be run in another thread /// </summary> private void PrepareAndSendProtoVessel(ProtoVessel protoVessel) { //Never send empty vessel id's (it happens with flags...) if (protoVessel.vesselID == Guid.Empty || protoVessel.vesselName == null) { return; } //VesselSerializedBytes is shared so lock it! lock (VesselArraySyncLock) { VesselSerializer.SerializeVesselToArray(protoVessel, VesselSerializedBytes, out var numBytes); if (numBytes > 0) { VesselsProtoStore.RawUpdateVesselProtoData(VesselSerializedBytes, numBytes, protoVessel.vesselID); var msgData = NetworkMain.CliMsgFactory.CreateNewMessageData <VesselProtoMsgData>(); FillAndSendProtoMessageData(protoVessel.vesselID, msgData, VesselSerializedBytes, numBytes); } else { if (protoVessel.vesselType == VesselType.Debris) { LunaLog.Log($"Serialization of debris vessel: {protoVessel.vesselID} name: {protoVessel.vesselName} failed. Adding to kill list"); SystemsContainer.Get <VesselRemoveSystem>().AddToKillList(protoVessel.vesselID); } } } }
/// <summary> /// Updates the list of our vessels and other peoples vessel. /// We do this in another routine to improve performance /// </summary> private void UpdateOwnedAndOtherPeopleVesselList() { if (Enabled && VesselImmortalSystemReady) { OwnedVesselIds.Clear(); OwnedVesselIds.AddRange(LockSystem.LockQuery.GetAllControlLocks(SettingsSystem.CurrentSettings.PlayerName) .Select(l => l.VesselId) .Union(LockSystem.LockQuery.GetAllUpdateLocks(SettingsSystem.CurrentSettings.PlayerName) .Select(l => l.VesselId)) .Where(v => !SystemsContainer.Get <VesselRemoveSystem>().VesselWillBeKilled(v))); OwnedVessels.Clear(); OwnedVessels.AddRange(OwnedVesselIds .Select(FlightGlobals.FindVessel) .Where(v => v != null)); OtherPeopleVessels.Clear(); OtherPeopleVessels.AddRange(LockSystem.LockQuery.GetAllControlLocks() .Union(LockSystem.LockQuery.GetAllUpdateLocks()) .Select(l => l.VesselId) .Except(OwnedVesselIds) .Where(v => !SystemsContainer.Get <VesselRemoveSystem>().VesselWillBeKilled(v)) .Select(FlightGlobals.FindVessel) .Where(v => v != null)); } }
/// <summary> /// Disconnects the network system. You should kill threads ONLY from main thread /// </summary> /// <param name="reason">Reason</param> public static void Disconnect(string reason = "unknown") { lock (DisconnectLock) { if (MainSystem.NetworkState > ClientState.Disconnected) { LunaLog.Log($"[LMP]: Disconnected, reason: {reason}"); if (!HighLogic.LoadedSceneIsEditor && !HighLogic.LoadedSceneIsFlight) { SystemsContainer.Get <MainSystem>().ForceQuit = true; } else { //User is in flight so just display a message but don't force him to main menu... NetworkSystem.DisplayDisconnectMessage = true; } SystemsContainer.Get <MainSystem>().Status = $"Disconnected: {reason}"; //DO NOT set networkstate as disconnected as we are in another thread! MainSystem.NetworkState = ClientState.DisconnectRequested; NetworkMain.ClientConnection.Disconnect(reason); NetworkMain.ClientConnection.Shutdown(reason); NetworkMain.ResetConnectionStaticsAndQueues(); } } }
public override void Update() { SafeDisplay = Display; if (Display && (DisplayFast || Time.realtimeSinceStartup - LastUpdateTime > DisplayUpdateSInterval)) { LastUpdateTime = Time.realtimeSinceStartup; LmpProfilerText = LunaProfiler.GetProfilersData(); AsteroidProfilerText = SystemsContainer.Get <AsteroidSystem>().GetProfilersData(); CraftLibraryProfilerText = SystemsContainer.Get <CraftLibrarySystem>().GetProfilersData(); FlagProfilerText = SystemsContainer.Get <FlagSystem>().GetProfilersData(); ScenarioProfilerText = SystemsContainer.Get <ScenarioSystem>().GetProfilersData(); TimeSyncerProfilerText = SystemsContainer.Get <TimeSyncerSystem>().GetProfilersData(); ModApiProfilerText = SystemsContainer.Get <ModApiSystem>().GetProfilersData(); LockProfilerText = SystemsContainer.Get <LockSystem>().GetProfilersData(); KerbalProfilerText = SystemsContainer.Get <KerbalSystem>().GetProfilersData(); VesselChangeProfilerText = SystemsContainer.Get <VesselChangeSystem>().GetProfilersData(); VesselDockProfilerText = SystemsContainer.Get <VesselDockSystem>().GetProfilersData(); VesselFlightStateProfilerText = SystemsContainer.Get <VesselFlightStateSystem>().GetProfilersData(); VesselImmortalProfilerText = SystemsContainer.Get <VesselImmortalSystem>().GetProfilersData(); VesselLockProfilerText = SystemsContainer.Get <VesselLockSystem>().GetProfilersData(); VesselPositionProfilerText = SystemsContainer.Get <VesselPositionSystem>().GetProfilersData(); VesselPositionAltProfilerText = SystemsContainer.Get <VesselPositionAltSystem>().GetProfilersData(); VesselProtoProfilerText = SystemsContainer.Get <VesselProtoSystem>().GetProfilersData(); VesselRangeProfilerText = SystemsContainer.Get <VesselRangeSystem>().GetProfilersData(); VesselRemoveProfilerText = SystemsContainer.Get <VesselRemoveSystem>().GetProfilersData(); VesselUpdateProfilerText = SystemsContainer.Get <VesselUpdateSystem>().GetProfilersData(); WarpProfilerText = SystemsContainer.Get <WarpSystem>().GetProfilersData(); } }
/// <summary> /// Try to acquire the asteroid-spawning lock if nobody else has it. /// </summary> private static void TryGetAsteroidLock() { if (!LockSystem.LockQuery.AsteroidLockExists() && SystemsContainer.Get <WarpSystem>().CurrentSubspace == 0) { SystemsContainer.Get <LockSystem>().AcquireAsteroidLock(); } }
protected override void OnEnabled() { base.OnEnabled(); GameEvents.onVesselCreate.Add(PlayerColorEvents.SetVesselOrbitColor); SystemsContainer.Get <LockSystem>().RegisterAcquireHook(PlayerColorEvents.OnLockAcquire); SystemsContainer.Get <LockSystem>().RegisterReleaseHook(PlayerColorEvents.OnLockRelease); }