Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        /// <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);
                    }
                }
            }
        }
Пример #4
0
        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);
                    }
                }
            }
        }
Пример #5
0
        /// <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}");
     }
 }
Пример #7
0
        /// <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;
                        }
                    }
                }
            }
        }
Пример #8
0
        /// <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}");
            }
        }
Пример #9
0
        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";
            }
        }
Пример #10
0
 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);
     }
 }
Пример #11
0
        /// <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}");
            }
        }
Пример #12
0
        /// <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);
            }
        }
Пример #13
0
        /// <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));
                    }
                }
            }
        }
Пример #15
0
        /// <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);
                    }
                }
            }
        }
Пример #16
0
        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);
        }
Пример #17
0
        /// <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;
            }
        }
Пример #18
0
        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;
            }
        }
Пример #19
0
        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!");
            }
        }
Пример #20
0
        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!");
        }
Пример #21
0
 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();
 }
Пример #22
0
        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);
                }
            }
        }
Пример #24
0
 private void HandleCraftLibraryEvents()
 {
     if (Enabled && SystemsContainer.Get <MainSystem>().GameRunning)
     {
         CraftLibraryEventHandler.HandleCraftLibraryEvents();
     }
 }
Пример #25
0
        /// <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);
                    }
                }
            }
        }
Пример #26
0
        /// <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));
            }
        }
Пример #27
0
        /// <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();
                }
            }
        }
Пример #28
0
        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();
            }
        }
Пример #29
0
 /// <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);
 }