Example #1
0
        public void HandleHandshakeRequest(ClientStructure client, HandshakeRequestMsgData data)
        {
            var valid = CheckServerFull(client);

            valid &= valid && CheckUsernameLength(client, data.PlayerName);
            valid &= valid && CheckUsernameCharacters(client, data.PlayerName);
            valid &= valid && CheckPlayerIsAlreadyConnected(client, data.PlayerName);
            valid &= valid && CheckUsernameIsReserved(client, data.PlayerName);
            valid &= valid && CheckPlayerIsBanned(client, data.UniqueIdentifier);

            if (!valid)
            {
                LunaLog.Normal($"Client {data.PlayerName} ({data.UniqueIdentifier}) failed to handshake: {Reason}. Disconnecting");
                client.DisconnectClient = true;
                ClientConnectionHandler.DisconnectClient(client, Reason);
            }
            else
            {
                client.PlayerName       = data.PlayerName;
                client.UniqueIdentifier = data.UniqueIdentifier;
                client.Authenticated    = true;

                LmpPluginHandler.FireOnClientAuthenticated(client);

                LunaLog.Normal($"Client {data.PlayerName} ({data.UniqueIdentifier}) handshake successfully, Version: {data.MajorVersion}.{data.MinorVersion}.{data.BuildVersion}");

                HandshakeSystemSender.SendHandshakeReply(client, HandshakeReply.HandshookSuccessfully, "success");

                var msgData = ServerContext.ServerMessageFactory.CreateNewMessageData <PlayerConnectionJoinMsgData>();
                msgData.PlayerName = client.PlayerName;
                MessageQueuer.RelayMessage <PlayerConnectionSrvMsg>(client, msgData);

                LunaLog.Debug($"Online Players: {ServerContext.PlayerCount}, connected: {ClientRetriever.GetClients().Length}");
            }
        }
        public void HandleChangeSubspace(ClientStructure client, WarpChangeSubspaceMsgData message)
        {
            var oldSubspace = client.Subspace;
            var newSubspace = message.Subspace;

            if (oldSubspace != newSubspace)
            {
                MessageQueuer.RelayMessage <WarpSrvMsg>(client, new WarpChangeSubspaceMsgData
                {
                    PlayerName = client.PlayerName,
                    Subspace   = message.Subspace
                });

                if (newSubspace != -1)
                {
                    client.Subspace = newSubspace;

                    if (client.Subspace != -1 && !ServerContext.Clients.Any(c => c.Value.Subspace == oldSubspace))
                    {
                        WarpSystem.RemoveSubspace(oldSubspace);
                        VesselRelaySystem.RemoveSubspace(oldSubspace);
                    }
                }
            }
        }
Example #3
0
        /// <summary>
        /// This method relay the update to players closer than 25km
        /// </summary>
        public static async void RelayToClosePlayers()
        {
            while (ServerContext.ServerRunning)
            {
                try
                {
                    if (IncomingUpdates.TryDequeue(out var vesselUpdate) && VesselsDictionary.ContainsKey(vesselUpdate.Key))
                    {
                        VesselsDictionary.TryUpdate(vesselUpdate.Key, vesselUpdate.Value, VesselsDictionary[vesselUpdate.Key]);

                        IncomingMediumUpdates.Enqueue(vesselUpdate);

                        var closeClients = VesselsDictionary.Where(v => !Equals(v.Key, vesselUpdate.Key) && v.Value != null &&
                                                                   v.Value.BodyIndex == vesselUpdate.Value.BodyIndex &&
                                                                   CalculateDistance(v.Value, vesselUpdate.Value) <=
                                                                   GeneralSettings.SettingsStore.CloseDistanceInMeters)
                                           .Select(v => v.Key);

                        foreach (var closeClient in closeClients.Where(c => ServerContext.Clients.ContainsKey(c.Endpoint)))
                        {
                            MessageQueuer.RelayMessage <VesselSrvMsg>(closeClient, vesselUpdate.Value);
                        }
                    }
                }
                catch (Exception e)
                {
                    LunaLog.Error($"Error in RelayToClosePlayers method! Details: {e}");
                }
                await Task.Delay(GeneralSettings.SettingsStore.CloseDistanceUpdateIntervalMs);
            }
        }
Example #4
0
        private static void HandleVesselDock(ClientStructure client, VesselBaseMsgData message)
        {
            var msgData = (VesselDockMsgData)message;

            LunaLog.Debug($"Docking message received! Dominant vessel: {msgData.DominantVesselId}");

            if (VesselContext.RemovedVessels.Contains(msgData.WeakVesselId))
            {
                return;
            }

            if (VesselStoreSystem.VesselExists(msgData.DominantVesselId))
            {
                LunaLog.Debug($"Saving DOCKED vessel {msgData.DominantVesselId} from {client.PlayerName}. Bytes: {msgData.NumBytes}");
            }
            VesselDataUpdater.RawConfigNodeInsertOrUpdate(msgData.DominantVesselId, Encoding.UTF8.GetString(msgData.FinalVesselData, 0, msgData.NumBytes));

            //Now remove the weak vessel but DO NOT add to the removed vessels as they might undock!!!
            LunaLog.Debug($"Removing weak docked vessel {msgData.WeakVesselId}");
            VesselStoreSystem.RemoveVessel(msgData.WeakVesselId);

            MessageQueuer.RelayMessage <VesselSrvMsg>(client, msgData);

            //Tell all clients to remove the weak vessel
            var removeMsgData = ServerContext.ServerMessageFactory.CreateNewMessageData <VesselRemoveMsgData>();

            removeMsgData.VesselId = msgData.WeakVesselId;

            MessageQueuer.SendToAllClients <VesselSrvMsg>(removeMsgData);
        }
Example #5
0
        public void HandleChangeSubspace(ClientStructure client, WarpChangeSubspaceMsgData message)
        {
            if (message.PlayerName != client.PlayerName)
            {
                return;
            }

            var oldSubspace = client.Subspace;
            var newSubspace = message.Subspace;

            if (oldSubspace != newSubspace)
            {
                var msgData = ServerContext.ServerMessageFactory.CreateNewMessageData <WarpChangeSubspaceMsgData>();
                msgData.PlayerName = client.PlayerName;
                msgData.Subspace   = message.Subspace;

                MessageQueuer.RelayMessage <WarpSrvMsg>(client, msgData);

                if (newSubspace != -1)
                {
                    client.Subspace = newSubspace;

                    //If client stopped warping and there's nobody in that subspace, remove it
                    if (!ServerContext.Clients.Any(c => c.Value.Subspace == oldSubspace))
                    {
                        WarpSystem.RemoveSubspace(oldSubspace);
                        VesselRelaySystem.RemoveSubspace(oldSubspace);
                    }
                }
            }
        }
        private static void HandleVesselProto(ClientStructure client, VesselBaseMsgData message)
        {
            var msgData = (VesselProtoMsgData)message;

            if (VesselContext.RemovedVessels.Contains(msgData.Vessel.VesselId))
            {
                return;
            }

            if (msgData.Vessel.NumBytes == 0)
            {
                LunaLog.Warning($"Received a vessel with 0 bytes ({msgData.Vessel.VesselId}) from {client.PlayerName}.");
                return;
            }

            var path = Path.Combine(ServerContext.UniverseDirectory, "Vessels", $"{msgData.Vessel.VesselId}.txt");

            if (!File.Exists(path))
            {
                LunaLog.Debug($"Saving vessel {msgData.Vessel.VesselId} from {client.PlayerName}. Bytes: {msgData.Vessel.NumBytes}");
            }

            FileHandler.WriteToFile(path, msgData.Vessel.Data, msgData.Vessel.NumBytes);

            MessageQueuer.RelayMessage <VesselSrvMsg>(client, msgData);
        }
        public void HandleUploadFileMessage(ClientStructure client, CraftLibraryUploadMsgData message)
        {
            var playerPath = Path.Combine(Path.Combine(ServerContext.UniverseDirectory, "Crafts"),
                                          message.PlayerName);

            if (!FileHandler.FolderExists(playerPath))
            {
                FileHandler.FolderCreate(playerPath);
            }
            var typePath = Path.Combine(playerPath, message.UploadType.ToString());

            if (!FileHandler.FolderExists(typePath))
            {
                FileHandler.FolderCreate(typePath);
            }
            var craftFile = Path.Combine(typePath, $"{message.UploadName}.craft");

            FileHandler.WriteToFile(craftFile, message.CraftData);
            LunaLog.Debug($"Saving {message.UploadName}, Type: {message.UploadType} from {message.PlayerName}");

            var newMessageData = new CraftLibraryAddMsgData
            {
                PlayerName = message.PlayerName,
                UploadName = message.UploadName,
                UploadType = message.UploadType
            };

            MessageQueuer.RelayMessage <CraftLibrarySrvMsg>(client, newMessageData);
        }
Example #8
0
        public static void HandleMessage(ClientStructure client, IClientMessageBase message)
        {
            var messageData = message.Data as PlayerStatusBaseMsgData;

            switch (messageData?.PlayerStatusMessageType)
            {
            case PlayerStatusMessageType.Request:
                SendOtherPlayerStatusesToNewPlayer(client);
                //We don't use this message anymore so we can recycle it
                message.Recycle();
                break;

            case PlayerStatusMessageType.Set:
                var data = (PlayerStatusSetMsgData)messageData;
                if (data.PlayerStatus.PlayerName != client.PlayerName)
                {
                    return;
                }

                client.PlayerStatus.VesselText = data.PlayerStatus.VesselText;
                client.PlayerStatus.StatusText = data.PlayerStatus.StatusText;
                MessageQueuer.RelayMessage <PlayerStatusSrvMsg>(client, data);
                break;
            }
        }
Example #9
0
        public override void HandleMessage(ClientStructure client, IClientMessageBase message)
        {
            var messageData = message.Data as PlayerColorBaseMsgData;

            switch (messageData?.PlayerColorMessageType)
            {
            case PlayerColorMessageType.Request:
                SendAllPlayerColors(client);

                //We don't use this message anymore so we can recycle it
                message.Recycle();
                break;

            case PlayerColorMessageType.Set:
                var data = (PlayerColorSetMsgData)messageData;
                if (data.PlayerColor.PlayerName != client.PlayerName)
                {
                    return;
                }

                Array.Copy(data.PlayerColor.Color, client.PlayerColor, data.PlayerColor.Color.Length);
                MessageQueuer.RelayMessage <PlayerColorSrvMsg>(client, data);
                break;
            }
        }
Example #10
0
        public override void HandleMessage(ClientStructure client, IMessageData messageData)
        {
            var message = messageData as KerbalBaseMsgData;
            switch (message?.KerbalMessageType)
            {
                case KerbalMessageType.Request:
                    var kerbalFiles = FileHandler.GetFilesInPath(Path.Combine(ServerContext.UniverseDirectory, "Kerbals"));
                    var kerbalsData = kerbalFiles.Select(k => new KeyValuePair<string, byte[]>(Path.GetFileNameWithoutExtension(k),
                        FileHandler.ReadFile(k)));

                    LunaLog.Debug($"Sending {client.PlayerName} {kerbalFiles.Length} kerbals...");

                    var newMessageData = new KerbalReplyMsgData
                    {
                        KerbalsData = kerbalsData.ToArray()
                    };

                    MessageQueuer.SendToClient<KerbalSrvMsg>(client, newMessageData);
                    break;
                case KerbalMessageType.Proto:
                    var data = (KerbalProtoMsgData)message;

                    LunaLog.Debug($"Saving kerbal {data.KerbalName} from {client.PlayerName}");

                    var path = Path.Combine(ServerContext.UniverseDirectory, "Kerbals", $"{data.KerbalName}.txt");
                    FileHandler.WriteToFile(path, data.KerbalData);

                    MessageQueuer.RelayMessage<KerbalSrvMsg>(client, data);
                    break;
                default:
                    throw new NotImplementedException("Kerbal type not implemented");
            }
        }
        /// <summary>
        /// This method relay the update to players in the same planet but farther than 25km
        /// </summary>
        public static void RelayToMediumDistancePlayers()
        {
            while (ServerContext.ServerRunning)
            {
                try
                {
                    KeyValuePair <ClientStructure, VesselPositionMsgData> vesselUpdate;
                    if (IncomingMediumUpdates.TryDequeue(out vesselUpdate) && VesselsDictionary.ContainsKey(vesselUpdate.Key))
                    {
                        IncomingFarUpdates.Enqueue(vesselUpdate);

                        var mediumDistanceClients = VesselsDictionary.Where(
                            v => !Equals(v.Key, vesselUpdate.Key) && v.Value != null &&
                            v.Value.BodyName == vesselUpdate.Value.BodyName &&
                            CalculateDistance(v.Value, vesselUpdate.Value) >
                            GeneralSettings.SettingsStore.CloseDistanceInMeters)
                                                    .Select(v => v.Key);

                        foreach (
                            var mediumDistanceClient in
                            mediumDistanceClients.Where(c => ServerContext.Clients.ContainsKey(c.Endpoint)))
                        {
                            MessageQueuer.RelayMessage <VesselSrvMsg>(mediumDistanceClient, vesselUpdate.Value);
                        }
                    }
                }
                catch (Exception e)
                {
                    LunaLog.Error($"Error in RelayToMediumDistancePlayers method! Details: {e}");
                }
                Thread.Sleep(GeneralSettings.SettingsStore.MediumDistanceUpdateIntervalMs);
            }
        }
        private static void HandleVesselDock(ClientStructure client, VesselBaseMsgData message)
        {
            var msgData = (VesselDockMsgData)message;

            LunaLog.Debug($"Docking message received! Dominant vessel: {msgData.DominantVesselId}");

            if (VesselContext.RemovedVessels.Contains(msgData.WeakVesselId))
            {
                return;
            }

            var path = Path.Combine(ServerContext.UniverseDirectory, "Vessels", $"{msgData.DominantVesselId}.txt");

            if (!File.Exists(path))
            {
                LunaLog.Debug($"Saving vessel {msgData.DominantVesselId} from {client.PlayerName}");
            }
            FileHandler.WriteToFile(path, msgData.FinalVesselData, msgData.NumBytes);

            //Now remove the weak vessel
            LunaLog.Debug($"Removing weak docked vessel {msgData.WeakVesselId}");
            Universe.RemoveFromUniverse(Path.Combine(ServerContext.UniverseDirectory, "Vessels",
                                                     $"{msgData.WeakVesselId}.txt"));
            VesselContext.RemovedVessels.Add(msgData.WeakVesselId);

            MessageQueuer.RelayMessage <VesselSrvMsg>(client, msgData);

            //Tell all clients to remove the weak vessel
            var removeMsgData = ServerContext.ServerMessageFactory.CreateNewMessageData <VesselRemoveMsgData>();

            removeMsgData.VesselId = msgData.WeakVesselId;

            MessageQueuer.SendToAllClients <VesselSrvMsg>(removeMsgData);
        }
Example #13
0
        public override void HandleMessage(ClientStructure client, IMessageData messageData)
        {
            var message = messageData as VesselBaseMsgData;

            switch (message?.VesselMessageType)
            {
            case VesselMessageType.LIST_REQUEST:
                HandleVesselListRequest(client);
                break;

            case VesselMessageType.VESSELS_REQUEST:
                HandleVesselsRequest(client, messageData);
                break;

            case VesselMessageType.PROTO:
                HandleVesselProto(client, message);
                break;

            case VesselMessageType.REMOVE:
                HandleVesselRemove(client, message);
                break;

            case VesselMessageType.CHANGE:
                MessageQueuer.RelayMessage <VesselSrvMsg>(client, message);
                break;

            case VesselMessageType.UPDATE:
                VesselRelaySystem.HandleVesselMessage(client, message);
                break;

            default:
                throw new NotImplementedException("Warp Type not implemented");
            }
        }
Example #14
0
        public override void HandleMessage(ClientStructure client, IMessageData messageData)
        {
            var baseMsg = (FacilityBaseMsgData)messageData;

            switch (baseMsg.FacilityMessageType)
            {
            case FacilityMessageType.Upgrade:
                var upgradeMsg = (FacilityUpgradeMsgData)messageData;
                LunaLog.Normal($"{client.PlayerName} UPGRADED facility {upgradeMsg.ObjectId} to level: {upgradeMsg.Level}");
                break;

            case FacilityMessageType.Repair:
                LunaLog.Normal($"{client.PlayerName} REPAIRED facility {baseMsg.ObjectId}");
                break;

            case FacilityMessageType.Collapse:
                LunaLog.Normal($"{client.PlayerName} DESTROYED facility {baseMsg.ObjectId}");
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            //We don't do anything on the server side with this messages so just relay them.
            MessageQueuer.RelayMessage <FacilitySrvMsg>(client, messageData);
        }
        /// <summary>
        /// This method relay the vessel update to players in other planets
        /// </summary>
        public static void RelayToFarPlayers()
        {
            while (ServerContext.ServerRunning)
            {
                try
                {
                    if (IncomingFarUpdates.TryDequeue(out var vesselUpdate) && VesselsDictionary.ContainsKey(vesselUpdate.Key))
                    {
                        var farClients = VesselsDictionary.Where(v => !Equals(v.Key, vesselUpdate.Key) && v.Value != null &&
                                                                 v.Value.BodyName != vesselUpdate.Value.BodyName)
                                         .Select(v => v.Key);

                        foreach (var farClient in farClients.Where(c => ServerContext.Clients.ContainsKey(c.Endpoint)))
                        {
                            MessageQueuer.RelayMessage <VesselSrvMsg>(farClient, vesselUpdate.Value);
                        }
                    }
                }
                catch (Exception e)
                {
                    LunaLog.Error($"Error in RelayToFarPlayers method! Details: {e}");
                }
                Thread.Sleep(GeneralSettings.SettingsStore.FarDistanceUpdateIntervalMs);
            }
        }
        public override void HandleMessage(ClientStructure client, IClientMessageBase message)
        {
            var messageData = message.Data as VesselBaseMsgData;

            switch (messageData?.VesselMessageType)
            {
            case VesselMessageType.Sync:
                HandleVesselsSync(client, messageData);
                message.Recycle();
                break;

            case VesselMessageType.Proto:
                HandleVesselProto(client, messageData);
                break;

            case VesselMessageType.Dock:
                HandleVesselDock(client, messageData);
                break;

            case VesselMessageType.Remove:
                HandleVesselRemove(client, messageData);
                break;

            case VesselMessageType.Position:
                VesselRelaySystem.HandleVesselMessage(client, messageData);
                if (!GeneralSettings.SettingsStore.ShowVesselsInThePast || client.Subspace == WarpContext.LatestSubspace)
                {
                    VesselDataUpdater.WritePositionDataToFile(messageData);
                }
                break;

            case VesselMessageType.Flightstate:
                VesselRelaySystem.HandleVesselMessage(client, messageData);
                break;

            case VesselMessageType.Update:
                VesselDataUpdater.WriteUpdateDataToFile(messageData);
                MessageQueuer.RelayMessage <VesselSrvMsg>(client, messageData);
                break;

            case VesselMessageType.Resource:
                VesselDataUpdater.WriteResourceDataToFile(messageData);
                MessageQueuer.RelayMessage <VesselSrvMsg>(client, messageData);
                break;

            case VesselMessageType.PartSync:
                VesselDataUpdater.WriteModuleDataToFile(messageData);
                MessageQueuer.RelayMessage <VesselSrvMsg>(client, messageData);
                break;

            case VesselMessageType.Fairing:
                VesselDataUpdater.WriteFairingDataToFile(messageData);
                MessageQueuer.RelayMessage <VesselSrvMsg>(client, messageData);
                break;

            default:
                throw new NotImplementedException("Vessel message type not implemented");
            }
        }
Example #17
0
        public static void FundsReceived(ClientStructure client, ShareProgressFundsMsgData data)
        {
            LunaLog.Debug($"Funds received: {data.Funds} Reason: {data.Reason}");

            //send the funds update to all other clients
            MessageQueuer.RelayMessage <ShareProgressSrvMsg>(client, data);
            ScenarioDataUpdater.WriteFundsDataToFile(data.Funds);
        }
Example #18
0
        public static void ScienceReceived(ClientStructure client, ShareProgressScienceMsgData data)
        {
            LunaLog.Debug($"Science received: {data.Science} Reason: {data.Reason}");

            //send the science update to all other clients
            MessageQueuer.RelayMessage <ShareProgressSrvMsg>(client, data);
            ScenarioDataUpdater.WriteScienceDataToFile(data.Science);
        }
Example #19
0
        public static void PurchaseReceived(ClientStructure client, ShareProgressPartPurchaseMsgData data)
        {
            LunaLog.Debug($"Part purchased: {data.PartName} Tech: {data.TechId}");

            //send the part purchase to all other clients
            MessageQueuer.RelayMessage <ShareProgressSrvMsg>(client, data);
            ScenarioDataUpdater.WritePartPurchaseDataToFile(data);
        }
Example #20
0
        public static void ExperimentalPartReceived(ClientStructure client, ShareProgressExperimentalPartMsgData data)
        {
            LunaLog.Debug($"Experimental part received: {data.PartName} Count: {data.Count}");

            //send the experimental part to all other clients
            MessageQueuer.RelayMessage <ShareProgressSrvMsg>(client, data);
            ScenarioDataUpdater.WriteExperimentalPartDataToFile(data);
        }
        public static void ScienceSubjectReceived(ClientStructure client, ShareProgressScienceSubjectMsgData data)
        {
            LunaLog.Debug($"Science experiment received: {data.ScienceSubject.Id}");

            //send the science subject update to all other clients
            MessageQueuer.RelayMessage <ShareProgressSrvMsg>(client, data);
            ScenarioDataUpdater.WriteScienceSubjectDataToFile(data.ScienceSubject);
        }
        public static void StrategyReceived(ClientStructure client, ShareProgressStrategyMsgData data)
        {
            LunaLog.Debug($"strategy changed: {data.Strategy.Name}");

            //Send the strategy update to all other clients
            MessageQueuer.RelayMessage <ShareProgressSrvMsg>(client, data);
            ScenarioDataUpdater.WriteStrategyDataToFile(data.Strategy);
        }
Example #23
0
        public static void ReputationReceived(ClientStructure client, ShareProgressReputationMsgData data)
        {
            LunaLog.Debug($"Reputation received: {data.Reputation} Reason: {data.Reason}");

            //send the reputation update to all other clients
            MessageQueuer.RelayMessage <ShareProgressSrvMsg>(client, data);
            ScenarioDataUpdater.WriteReputationDataToFile(data.Reputation);
        }
        public static void AchievementsReceived(ClientStructure client, ShareProgressAchievementsMsgData data)
        {
            LunaLog.Debug($"Achievements data received: {data.Id}");

            //send the achievements update to all other clients
            MessageQueuer.RelayMessage <ShareProgressSrvMsg>(client, data);
            ScenarioDataUpdater.WriteAchievementDataToFile(data);
        }
        public static void TechnologyReceived(ClientStructure client, ShareProgressTechnologyMsgData data)
        {
            LunaLog.Debug($"Technology unlocked: {data.TechNode.Id}");

            //Send the technology update to all other clients
            MessageQueuer.RelayMessage <ShareProgressSrvMsg>(client, data);
            ScenarioDataUpdater.WriteTechnologyDataToFile(data);
        }
Example #26
0
        /// <summary>
        /// Sends a notification of new screenshot to all players
        /// </summary>
        private static void SendNotification(ClientStructure client)
        {
            var msgData = ServerContext.ServerMessageFactory.CreateNewMessageData <ScreenshotNotificationMsgData>();

            msgData.FolderName = client.PlayerName;

            MessageQueuer.RelayMessage <ScreenshotSrvMsg>(client, msgData);
        }
        public static void UpgradeReceived(ClientStructure client, ShareProgressFacilityUpgradeMsgData data)
        {
            LunaLog.Debug($"{client.PlayerName} Upgraded facility {data.FacilityId} To level: {data.Level}");

            //send the upgrade facility update to all other clients
            MessageQueuer.RelayMessage <ShareProgressSrvMsg>(client, data);
            ScenarioDataUpdater.WriteFacilityLevelDataToFile(data.FacilityId, data.Level);
        }
Example #28
0
        public static void HandleKerbalRemove(ClientStructure client, KerbalRemoveMsgData message)
        {
            var kerbalToRemove = message.KerbalName;

            LunaLog.Debug($"Removing kerbal {kerbalToRemove} from {client.PlayerName}");
            FileHandler.FileDelete(Path.Combine(KerbalsPath, $"{kerbalToRemove}.txt"));

            MessageQueuer.RelayMessage <KerbalSrvMsg>(client, message);
        }
        public override void HandleMessage(ClientStructure client, IMessageData message)
        {
            var data = (ModMsgData)message;

            if (data.Relay)
            {
                MessageQueuer.RelayMessage <ModSrvMsg>(client, data);
            }
            LmpModInterface.OnModMessageReceived(client, data.ModName, data.Data);
        }
Example #30
0
        public static void HandleKerbalProto(ClientStructure client, KerbalProtoMsgData data)
        {
            LunaLog.Debug($"Saving kerbal {data.Kerbal.KerbalName} from {client.PlayerName}");

            var path = Path.Combine(KerbalsPath, $"{data.Kerbal.KerbalName}.txt");

            FileHandler.WriteToFile(path, data.Kerbal.KerbalData, data.Kerbal.NumBytes);

            MessageQueuer.RelayMessage <KerbalSrvMsg>(client, data);
        }