Exemple #1
0
        public void SendVesselMessage(Vessel vessel)
        {
            if (vessel == null)
            {
                return;
            }

            //Update the protovessel definition!
            vessel.BackupVessel();

            //Defend against NaN orbits
            if (VesselHasNaNPosition(vessel.protoVessel))
            {
                LunaLog.Log($"[LMP]: Vessel {vessel.id} has NaN position");
                return;
            }

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

            var vesselNode = new ConfigNode();

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

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

            var vesselBytes = ConfigNodeSerializer.Serialize(vesselNode);

            if (vesselBytes.Length > 0)
            {
                UniverseSyncCache.QueueToCache(vesselBytes);

                SendMessage(new VesselProtoMsgData
                {
                    VesselId   = vessel.id,
                    VesselData = vesselBytes
                });
            }
            else
            {
                LunaLog.LogError($"[LMP]: Failed to create byte[] data for {vessel.id}");
            }
        }
Exemple #2
0
        /// <summary>
        /// Convert a byte array to a ConfigNode and then to a ProgressNode.
        /// If anything goes wrong it will return null.
        /// </summary>
        /// <param name="data">The byte array that represents the configNode</param>
        /// <param name="numBytes">The length of the byte array</param>
        /// <param name="progressNodeId">The Id of the ProgressNode</param>
        /// <returns></returns>
        private static ProgressNode ConvertByteArrayToAchievement(byte[] data, int numBytes, string progressNodeId)
        {
            ConfigNode node;

            try
            {
                node = ConfigNodeSerializer.Deserialize(data, numBytes);
            }
            catch (Exception e)
            {
                LunaLog.LogError($"[LMP]: Error while deserializing achievement configNode: {e}");
                return(null);
            }

            if (node == null)
            {
                LunaLog.LogError("[LMP]: Error, the achievement configNode was null.");
                return(null);
            }

            ProgressNode achievement;

            try
            {
                achievement = new ProgressNode(progressNodeId, false);
                achievement.Load(node);
            }
            catch (Exception e)
            {
                LunaLog.LogError($"[LMP]: Error while deserializing achievement: {e}");
                return(null);
            }

            return(achievement);
        }
        /// <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))
                {
                    LunaLog.Log("Server is in LAN. Skipping NAT punch");
                    NetworkConnection.ConnectToServer(serverInfo.InternalEndpoint, Password);
                }
                else
                {
                    try
                    {
                        var msgData = NetworkMain.CliMsgFactory.CreateNewMessageData <MsIntroductionMsgData>();
                        msgData.Id               = serverId;
                        msgData.Token            = MainSystem.UniqueIdentifier;
                        msgData.InternalEndpoint = new IPEndPoint(LunaNetUtils.GetOwnInternalIpAddress(), NetworkMain.Config.Port);

                        var introduceMsg = NetworkMain.MstSrvMsgFactory.CreateNew <MainMstSrvMsg>(msgData);

                        MainSystem.Singleton.Status = string.Empty;
                        LunaLog.Log($"[LMP]: Sending NAT introduction to server. Token: {MainSystem.UniqueIdentifier}");
                        NetworkSender.QueueOutgoingMessage(introduceMsg);
                    }
                    catch (Exception e)
                    {
                        LunaLog.LogError($"[LMP]: Error connecting to server: {e}");
                    }
                }
            }
        }
Exemple #4
0
        private static bool PrefixSetStartupNewVessel()
        {
            if (MainSystem.NetworkState < ClientState.Connected || string.IsNullOrEmpty(FlightDriver.newShipToLoadPath))
            {
                return(true);
            }

            var configNode = ConfigNode.Load(FlightDriver.newShipToLoadPath);
            var shipName   = configNode.GetValue("ship");
            var partNames  = configNode.GetNodes("PART").Select(n => n.GetValue("part").Substring(0, n.GetValue("part").IndexOf('_'))).ToList();
            var partCount  = configNode.GetNodes("PART").Count();

            if (ModSystem.Singleton.ModControl)
            {
                var bannedParts = ModSystem.Singleton.GetBannedPartsFromPartNames(partNames.Distinct()).ToArray();
                if (bannedParts.Any())
                {
                    LunaLog.LogError($"Vessel {shipName} Contains the following banned parts: {string.Join(", ", bannedParts)}");
                    BannedPartsWindow.Singleton.DisplayBannedPartsDialog(shipName, bannedParts);
                    HighLogic.LoadScene(GameScenes.SPACECENTER);
                    return(false);
                }
            }

            if (partCount > SettingsSystem.ServerSettings.MaxVesselParts)
            {
                LunaLog.LogError($"Vessel {shipName} has {partCount} parts and the max allowed in the server is: {SettingsSystem.ServerSettings.MaxVesselParts}");
                BannedPartsWindow.Singleton.DisplayBannedPartsDialog(shipName, partCount);
                HighLogic.LoadScene(GameScenes.SPACECENTER);
                return(false);
            }

            return(true);
        }
        public void HandleMessage(IMessageData messageData)
        {
            var msgData = messageData as VesselBaseMsgData;

            if (msgData == null)
            {
                return;
            }

            switch (msgData.VesselMessageType)
            {
            case VesselMessageType.ListReply:
                HandleVesselList((VesselListReplyMsgData)messageData);
                break;

            case VesselMessageType.VesselsReply:
                HandleVesselResponse((VesselsReplyMsgData)messageData);
                break;

            case VesselMessageType.Proto:
                HandleVesselProto((VesselProtoMsgData)messageData);
                break;

            default:
                LunaLog.LogError($"[LMP]: Cannot handle messages of type: {msgData.VesselMessageType} in VesselProtoMessageHandler");
                break;
            }
        }
Exemple #6
0
        /// <summary>
        /// Call this method to set a new time using the planetarium
        /// </summary>
        public static void StepClock(double targetTick)
        {
            if (HighLogic.LoadedScene == GameScenes.LOADING)
            {
                LunaLog.Log("[LMP] Skipping StepClock in loading screen");
                return;
            }
            if (HighLogic.LoadedSceneIsFlight)
            {
                if (FlightGlobals.fetch.activeVessel == null || !FlightGlobals.ready)
                {
                    LunaLog.Log("[LMP] Skipping StepClock (active vessel is null or not ready)");
                    return;
                }

                try
                {
                    OrbitPhysicsManager.HoldVesselUnpack(5);
                }
                catch
                {
                    LunaLog.LogError("[LMP] Failed to hold vessel unpack");
                    return;
                }

                PutVesselsInPhysicsRangeOnRails(targetTick);
            }
            Planetarium.SetUniversalTime(targetTick);
        }
Exemple #7
0
        /// <summary>
        /// Send the definition of our own vessel and the secondary vessels.
        /// </summary>
        private void SendVesselDefinition()
        {
            try
            {
                if (ProtoSystemReady)
                {
                    if (FlightGlobals.ActiveVessel.parts.Count != FlightGlobals.ActiveVessel.protoVessel.protoPartSnapshots.Count)
                    {
                        MessageSender.SendVesselMessage(FlightGlobals.ActiveVessel);
                    }

                    foreach (var vessel in VesselCommon.GetSecondaryVessels())
                    {
                        if (vessel.parts.Count != vessel.protoVessel.protoPartSnapshots.Count)
                        {
                            MessageSender.SendVesselMessage(vessel);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                LunaLog.LogError($"[LMP]: Error in SendVesselDefinition {e}");
            }
        }
        /// <summary>
        /// Check all part modules that inherit from PartModule. Then it gets all the fields of those classes that have the "ispersistent" as true.
        /// </summary>
        public static void ReadLoadedPartModules()
        {
            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                try
                {
                    var partModules = assembly.GetTypes().Where(myType => myType.IsClass && myType.IsSubclassOf(typeof(PartModule)));
                    foreach (var partModule in partModules)
                    {
                        var persistentFields = partModule.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
                                               .Where(f => f.GetCustomAttributes(typeof(KSPField), true).Any(attr => ((KSPField)attr).isPersistant)).ToArray();

                        if (persistentFields.Any())
                        {
                            ModuleFieldsDictionary.Add(partModule.Name, new FieldModuleDefinition(partModule, persistentFields));
                        }

                        InheritanceTypeChain.Add(partModule.Name, GetInheritChain(partModule));
                    }
                }
                catch (Exception ex)
                {
                    LunaLog.LogError($"Exception loading types from assembly {assembly.FullName}: {ex.Message}");
                }
            }

            LunaLog.Log($"Loaded {ModuleFieldsDictionary.Keys.Count} modules and a total of {ModuleFieldsDictionary.Values.Count} fields");
        }
        public ProtoVessel CreateProtoVessel()
        {
            var configNode = ConfigNodeSerializer.Deserialize(RawData, NumBytes);

            if (configNode == null || VesselCommon.VesselHasNaNPosition(configNode))
            {
                LunaLog.LogError($"Received a malformed vessel from SERVER. Id {VesselId}");
                VesselRemoveSystem.Singleton.KillVessel(VesselId, "Malformed vessel");
                VesselRemoveSystem.Singleton.AddToKillList(VesselId, "Malformed vessel");
                return(null);
            }

            var newProto = VesselSerializer.CreateSafeProtoVesselFromConfigNode(configNode, VesselId);

            if (newProto == null)
            {
                LunaLog.LogError($"Received a malformed vessel from SERVER. Id {VesselId}");
                VesselRemoveSystem.Singleton.KillVessel(VesselId, "Malformed vessel");
                VesselRemoveSystem.Singleton.AddToKillList(VesselId, "Malformed vessel");
                return(null);
            }

            if (VesselCommon.ProtoVesselHasInvalidParts(newProto))
            {
                return(null);
            }

            return(newProto);
        }
        /// <summary>
        /// Call this method to apply a vessel update using interpolation
        /// </summary>
        public void ApplyInterpolatedVesselUpdate()
        {
            if (Body == null)
            {
                return;
            }

            if (InterpolationFinished && VesselPositionSystem.TargetVesselUpdateQueue.TryGetValue(VesselId, out var queue) && queue.TryDequeue(out var targetUpdate))
            {
                if (Target == null)
                {
                    //We enter in this clause when it's the first iteration
                    GameTimeStamp = targetUpdate.GameTimeStamp - TimeSpan.FromMilliseconds(SettingsSystem.ServerSettings.SecondaryVesselUpdatesMsInterval).TotalSeconds;
                    PingMs        = 0;

                    CopyFrom(Vessel);
                }
                else
                {
                    CopyFrom(Target);
                }

                CurrentFrame = 0;

                if (Target != null)
                {
                    Target.CopyFrom(targetUpdate);
                    VesselPositionSystem.TargetVesselUpdateQueue[VesselId].Recycle(targetUpdate);
                }
                else
                {
                    Target = targetUpdate;
                }

                AdjustExtraInterpolationTimes();
                if (Vessel)
                {
                    Vessel.protoVessel?.UpdatePositionValues(Target);
                }
                InitializeOrbits();
            }

            if (Target == null)
            {
                return;
            }
            try
            {
                //ALWAYS set the position of the vessel even if we don't have anything in the queue. Otherwise its position will shake
                Vessel.SetVesselPosition(this, Target, LerpPercentage);
            }
            catch (Exception e)
            {
                LunaLog.LogError($"ApplyInterpolations: {e}");
            }
            finally
            {
                CurrentFrame++;
            }
        }
Exemple #11
0
        public void HandleMessage(IServerMessageBase msg)
        {
            if (!(msg.Data is ScenarioBaseMsgData msgData))
            {
                return;
            }

            if (msgData.ScenarioMessageType == ScenarioMessageType.Data)
            {
                var data = (ScenarioDataMsgData)msgData;
                for (var i = 0; i < data.ScenarioCount; i++)
                {
                    var scenarioNode = ConfigNodeSerializer.Deserialize(data.ScenariosData[i].Data, data.ScenariosData[i].NumBytes);
                    if (scenarioNode != null)
                    {
                        var entry = new ScenarioEntry
                        {
                            ScenarioName = data.ScenariosData[i].Module,
                            ScenarioNode = scenarioNode
                        };
                        System.ScenarioQueue.Enqueue(entry);
                    }
                    else
                    {
                        LunaLog.LogError($"[LMP]: Scenario data has been lost for {data.ScenariosData[i].Module}");
                        ScreenMessages.PostScreenMessage($"Scenario data has been lost for {data.ScenariosData[i].Module}", 5f, ScreenMessageStyle.UPPER_CENTER);
                    }
                }
                MainSystem.NetworkState = ClientState.ScenariosSynced;
            }
        }
        public static void IntroduceToServer(long currentEntryId)
        {
            var token       = RandomString(10);
            var ownEndpoint = new IPEndPoint(LunaNetUtils.GetMyAddress(), NetworkMain.Config.Port);

            LunaLog.Log($"[LMP]: Sending NAT introduction to server. Token: {token}");

            var msgData = NetworkMain.CliMsgFactory.CreateNewMessageData <MsIntroductionMsgData>();

            msgData.Id               = currentEntryId;
            msgData.Token            = token;
            msgData.InternalEndpoint = Common.StringFromEndpoint(ownEndpoint);
            var introduceMsg = MstSrvMsgFactory.CreateNew <MainMstSrvMsg>(msgData);

            foreach (var masterServer in MasterServerEndpoints.Values.ToArray())
            {
                try
                {
                    var lidgrenMsg = masterServer.CreateMessage((int)introduceMsg.GetMessageSize());
                    introduceMsg.Serialize(lidgrenMsg);

                    masterServer.SendMessage(lidgrenMsg, introduceMsg.NetDeliveryMethod);
                    masterServer.FlushSendQueue();
                }
                catch (Exception e)
                {
                    LunaLog.LogError($"[LMP]: Error connecting to server: {e}");
                }
            }

            introduceMsg.Recycle();
        }
        private static bool PreSerializationChecks(ProtoVessel protoVessel, out ConfigNode configNode)
        {
            configNode = new ConfigNode();

            if (protoVessel == null)
            {
                LunaLog.LogError("[LMP]: Cannot serialize a null protovessel");
                return(false);
            }

            try
            {
                protoVessel.Save(configNode);
            }
            catch (Exception e)
            {
                LunaLog.LogError($"[LMP]: Error while saving vessel: {e}");
                return(false);
            }

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

            //Defend against NaN orbits
            if (VesselCommon.VesselHasNaNPosition(configNode))
            {
                LunaLog.LogError($"[LMP]: Vessel {vesselId} has NaN position");
                return(false);
            }

            //Do not send the maneuver nodes
            RemoveManeuverNodesFromProtoVessel(configNode);
            return(true);
        }
Exemple #14
0
        public void SendKerbal(ProtoCrewMember pcm)
        {
            if (pcm == null)
            {
                return;
            }

            if (VesselCommon.IsSpectating)
            {
                return;
            }

            if (pcm.type == ProtoCrewMember.KerbalType.Tourist)
            {
                //Don't send tourists
                LunaLog.Log($"[LMP]: Skipping sending of tourist: {pcm.name}");
                return;
            }

            ConfigNode.ClearData();
            pcm.Save(ConfigNode);

            var kerbalBytes = ConfigNodeSerializer.Serialize(ConfigNode);

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

            SendKerbalProtoMessage(pcm.name, kerbalBytes);
        }
        /// <summary>
        /// Send the definition of our own vessel and the secondary vessels. We only send them after an interval specified.
        /// If the other player vessels are far we don't send them very often.
        /// </summary>
        private void SendVesselDefinition()
        {
            try
            {
                if (ProtoSystemReady)
                {
                    if (!VesselCommon.ActiveVesselIsInSafetyBubble())
                    {
                        MessageSender.SendVesselMessage(FlightGlobals.ActiveVessel);
                    }

                    foreach (var vessel in VesselCommon.GetSecondaryVessels())
                    {
                        MessageSender.SendVesselMessage(vessel);
                    }

                    ChangeRoutineExecutionInterval("SendVesselDefinition",
                                                   VesselCommon.PlayerVesselsNearby()
                            ? SettingsSystem.ServerSettings.VesselDefinitionSendMsInterval
                            : SettingsSystem.ServerSettings.VesselDefinitionSendFarMsInterval);
                }
            }
            catch (Exception e)
            {
                LunaLog.LogError($"[LMP]: Error in SendVesselDefinition {e}");
            }
        }
        public void HandleMessage(IMessageData messageData)
        {
            var msgData = messageData as KerbalBaseMsgData;

            if (msgData == null)
            {
                return;
            }

            switch (msgData.KerbalMessageType)
            {
            case KerbalMessageType.Reply:
                HandleKerbalReply(msgData as KerbalReplyMsgData);
                break;

            case KerbalMessageType.Proto:
                //TODO: If a player connects and sends this type of message while still starting the game, the game crashes.
                //There should be a buffer for this messages so they are processed once the system is enabled
                HandleKerbalProto(msgData as KerbalProtoMsgData);
                break;

            default:
                LunaLog.LogError("[LMP]: Invalid Kerbal message type");
                break;
            }
        }
 /// <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}");
     }
 }
Exemple #18
0
        /// <summary>
        /// Patches the methods defined in the XML with the transpiler
        /// </summary>
        public static void PatchFieldsAndMethods(Type partModule)
        {
            //If PartModule does not have any customization skip it
            if (!FieldModuleStore.CustomizedModuleBehaviours.TryGetValue(partModule.Name, out var customizationModule) || !customizationModule.CustomizedFields.Any())
            {
                return;
            }

            foreach (var partModuleMethod in partModule.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
                     .Where(m => m.Name == "OnUpdate" || m.Name == "OnFixedUpdate" || m.Name == "FixedUpdate" || m.Name == "Update" || m.Name == "LateUpdate" ||
                            m.GetCustomAttributes(typeof(KSPAction), false).Any() || m.GetCustomAttributes(typeof(KSPEvent), false).Any(a => ((KSPEvent)a).guiActive)))
            {
                if (partModuleMethod.GetMethodBody() != null)
                {
                    try
                    {
                        LunaLog.Log($"Patching method {partModuleMethod.Name} for field changes in module {partModule.Name} of assembly {partModule.Assembly.GetName().Name}");
                        HarmonyPatcher.HarmonyInstance.Patch(partModuleMethod, null, null, BackupAndCallTranspilerMethod);
                    }
                    catch (Exception ex)
                    {
                        LunaLog.LogError($"Could not patch method {partModuleMethod.Name} for field changes in module {partModule.Name} " +
                                         $"of assembly {partModule.Assembly.GetName().Name}. Details: {ex}");
                        HarmonyPatcher.HarmonyInstance.Patch(partModuleMethod, null, null, RestoreTranspilerMethod);
                    }
                }
            }
        }
Exemple #19
0
        /// <summary>
        /// Loads/reloads a vessel into game
        /// </summary>
        public static bool LoadVessel(ProtoVessel vesselProto)
        {
            try
            {
                if (ProtoVesselValidationsPassed(vesselProto))
                {
                    CurrentlyLoadingVesselId = vesselProto.vesselID;
                    FixProtoVesselFlags(vesselProto);
                    GetLatestProtoVesselPosition(vesselProto);

                    return(LoadVesselIntoGame(vesselProto));
                }

                return(false);
            }
            catch (Exception e)
            {
                LunaLog.LogError($"[LMP]: Error loading vessel: {e}");
                return(false);
            }
            finally
            {
                CurrentlyLoadingVesselId = Guid.Empty;
            }
        }
        public void HandleMessage(IServerMessageBase msg)
        {
            if (!(msg.Data is KerbalBaseMsgData msgData))
            {
                return;
            }

            switch (msgData.KerbalMessageType)
            {
            case KerbalMessageType.Remove:
                System.KerbalsToRemove.Enqueue(((KerbalRemoveMsgData)msgData).KerbalName);
                break;

            case KerbalMessageType.Reply:
                HandleKerbalReply(msgData as KerbalReplyMsgData);
                break;

            case KerbalMessageType.Proto:
                HandleKerbalProto(msgData as KerbalProtoMsgData);
                break;

            default:
                LunaLog.LogError("[LMP]: Invalid Kerbal message type");
                break;
            }
        }
        /// <summary>
        /// Convert a byte array to a ConfigNode.
        /// If anything goes wrong it will return null.
        /// </summary>
        private static ConfigNode ConvertByteArrayToConfigNode(byte[] data, int numBytes)
        {
            ConfigNode node;

            try
            {
                node = ConfigNodeSerializer.Deserialize(data, numBytes);
            }
            catch (Exception e)
            {
                LunaLog.LogError($"[LMP]: Error while deserializing strategy configNode: {e}");
                return(null);
            }

            if (node == null)
            {
                LunaLog.LogError("[LMP]: Error, the strategy configNode was null.");
                return(null);
            }

            if (!node.HasValue("isActive"))
            {
                LunaLog.LogError("[LMP]: Error, the strategy configNode is invalid (isActive missing).");
                return(null);
            }

            return(node);
        }
Exemple #22
0
        /// <summary>
        /// Check vessels that must be loaded
        /// </summary>
        private void CheckVesselsToLoad()
        {
            try
            {
                if (ProtoSystemBasicReady && !VesselCommon.ActiveVesselIsInSafetyBubble())
                {
                    //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 && !v.Value.IsInSafetyBubble);

                    foreach (var vesselProto in vesselsToLoad)
                    {
                        if (VesselRemoveSystem.VesselWillBeKilled(vesselProto.Key))
                        {
                            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}");
            }
        }
Exemple #23
0
        /// <summary>
        /// Call this method to scan all the PartModules and patch the methods
        /// </summary>
        public static void Awake()
        {
            if (_awakeTask != null)
            {
                return;
            }

            _awakeTask = Task.Run(() =>
            {
                var partModules = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()
                                                                                     .Where(myType => myType.IsClass && myType.IsSubclassOf(typeof(PartModule))))
                                  .ToArray();

                Parallel.ForEach(partModules, partModule =>
                {
                    try
                    {
                        PartModulePatcher.PatchFieldsAndMethods(partModule);
                        IncreasePercentage(1d / partModules.Length);
                    }
                    catch (Exception ex)
                    {
                        LunaLog.LogError($"Exception patching module {partModule.Name} from assembly {partModule.Assembly.GetName().Name}: {ex.Message}");
                    }
                });
            });

            _awakeTask.ConfigureAwait(false);
        }
        public bool ParseModFile(ModControlStructure modFileData)
        {
            if (!ModSystem.Singleton.ModControl)
            {
                return(true);
            }

            System.ModControlData = modFileData;
            Sb.Length             = 0;

            SaveCurrentModConfigurationFile();

            SetAllPathsToLowercase(modFileData);
            if (!CheckFilesAndExpansions(modFileData))
            {
                LunaLog.LogError("[LMP]: Mod check failed!");
                LunaLog.LogError(Sb.ToString());
                ModWindow.Singleton.Display = true;
                return(false);
            }

            System.AllowedParts     = modFileData.AllowedParts;
            System.AllowedResources = modFileData.AllowedResources;
            LunaLog.Log("[LMP]: Mod check passed!");
            return(true);
        }
Exemple #25
0
        /// <summary>
        /// Sends a mod Message.
        /// </summary>
        /// <param name="modName">Mod Name</param>
        /// <param name="messageData">The message payload</param>
        /// <param name="numBytes">Number of bytes to take from the array</param>
        /// <param name="relay">If set to <c>true</c>, The server will relay the Message to all other authenticated clients</param>
        public void SendModMessage(string modName, byte[] messageData, int numBytes, bool relay)
        {
            if (modName == null)
            {
                return;
            }
            if (messageData == null)
            {
                LunaLog.LogError($"[LMP]: {modName} attemped to send a null Message");
                return;
            }

            var msgData = NetworkMain.CliMsgFactory.CreateNewMessageData <ModMsgData>();

            if (msgData.Data.Length < numBytes)
            {
                msgData.Data = new byte[numBytes];
            }

            Array.Copy(messageData, msgData.Data, numBytes);

            msgData.NumBytes = numBytes;
            msgData.Relay    = relay;
            msgData.ModName  = modName;

            MessageSender.SendMessage(msgData);
        }
Exemple #26
0
        public void SendKerbal(ProtoCrewMember pcm)
        {
            if (pcm == null)
            {
                return;
            }

            if (VesselCommon.IsSpectating)
            {
                return;
            }

            ConfigNode.ClearData();
            pcm.Save(ConfigNode);

            var kerbalBytes = ConfigNode.Serialize();

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

            SendKerbalProtoMessage(pcm.name, kerbalBytes);
        }
Exemple #27
0
        /// <summary>
        /// Do some basic validations over the protovessel
        /// </summary>
        private static bool ProtoVesselValidationsPassed(ProtoVessel vesselProto)
        {
            if (vesselProto == null)
            {
                LunaLog.LogError("[LMP]: protoVessel is null!");
                return(false);
            }

            if (vesselProto.vesselID == Guid.Empty)
            {
                LunaLog.LogError("[LMP]: protoVessel id is null!");
                return(false);
            }

            if (vesselProto.situation == Vessel.Situations.FLYING)
            {
                if (vesselProto.orbitSnapShot == null)
                {
                    LunaLog.LogWarning("[LMP]: Skipping flying vessel load - Protovessel does not have an orbit snapshot");
                    return(false);
                }
                if (FlightGlobals.Bodies == null || FlightGlobals.Bodies.Count < vesselProto.orbitSnapShot.ReferenceBodyIndex)
                {
                    LunaLog.LogWarning($"[LMP]: Skipping flying vessel load - Could not find celestial body index {vesselProto.orbitSnapShot.ReferenceBodyIndex}");
                    return(false);
                }
            }
            return(true);
        }
Exemple #28
0
        /// <summary>
        /// Here we handle an unloaded flag and we load it into the game
        /// </summary>
        private void HandleFlag(ExtendedFlagInfo flagInfo)
        {
            //We have a flag with the same name!
            if (FlagExists(flagInfo.FlagName))
            {
                return;
            }

            var flagTexture = new Texture2D(4, 4);

            if (flagTexture.LoadImage(flagInfo.FlagData))
            {
                //Flags have names like: Squad/Flags/default
                flagTexture.name = flagInfo.FlagName;
                var textureInfo = new GameDatabase.TextureInfo(null, flagTexture, true, true, false)
                {
                    name = flagInfo.FlagName
                };

                GameDatabase.Instance.databaseTexture.Add(textureInfo);
                LunaLog.Log($"[LMP]: Loaded flag {flagTexture.name}");
            }
            else
            {
                LunaLog.LogError($"[LMP]: Failed to load flag {flagInfo.FlagName}");
            }
        }
Exemple #29
0
        /// <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))
            {
                var serverEndpoint = Common.CreateEndpointFromString(serverInfo.ExternalEndpoint);
                if (ServerIsInLocalLan(serverEndpoint))
                {
                    LunaLog.Log("Server is in LAN. Skipping NAT punch");
                    NetworkConnection.ConnectToServer(serverEndpoint.Address.ToString(), serverEndpoint.Port, Password);
                }
                else
                {
                    try
                    {
                        var token       = RandomString(10);
                        var ownEndpoint = new IPEndPoint(LunaNetUtils.GetMyAddress(), NetworkMain.Config.Port);

                        var msgData = NetworkMain.CliMsgFactory.CreateNewMessageData <MsIntroductionMsgData>();
                        msgData.Id               = serverId;
                        msgData.Token            = token;
                        msgData.InternalEndpoint = Common.StringFromEndpoint(ownEndpoint);

                        var introduceMsg = NetworkMain.MstSrvMsgFactory.CreateNew <MainMstSrvMsg>(msgData);

                        LunaLog.Log($"[LMP]: Sending NAT introduction to server. Token: {token}");
                        NetworkSender.QueueOutgoingMessage(introduceMsg);
                    }
                    catch (Exception e)
                    {
                        LunaLog.LogError($"[LMP]: Error connecting to server: {e}");
                    }
                }
            }
        }
        /// <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}");
            }
        }