/// <summary> /// Saves a received craft /// </summary> public static void SaveCraft(ClientStructure client, CraftLibraryDataMsgData data) { Task.Run(() => { var playerFolderType = Path.Combine(CraftPath, client.PlayerName, data.Craft.CraftType.ToString()); if (!Directory.Exists(playerFolderType)) { Directory.CreateDirectory(playerFolderType); } var lastTime = LastRequest.GetOrAdd(client.PlayerName, DateTime.MinValue); if (DateTime.Now - lastTime > TimeSpan.FromMilliseconds(CraftSettings.SettingsStore.MinCraftLibraryRequestIntervalMs)) { LastRequest.AddOrUpdate(client.PlayerName, DateTime.Now, (key, existingVal) => DateTime.Now); var fileName = $"{data.Craft.CraftName}.craft"; var fullPath = Path.Combine(playerFolderType, fileName); if (FileHandler.FileExists(fullPath)) { LunaLog.Normal($"Overwriting craft {data.Craft.CraftName} ({ByteSize.FromBytes(data.Craft.NumBytes).KiloBytes} KB) from: {client.PlayerName}."); //Send a msg to all the players so they remove the old copy var deleteMsg = ServerContext.ServerMessageFactory.CreateNewMessageData <CraftLibraryDeleteRequestMsgData>(); deleteMsg.CraftToDelete.CraftType = data.Craft.CraftType; deleteMsg.CraftToDelete.CraftName = data.Craft.CraftName; deleteMsg.CraftToDelete.FolderName = data.Craft.FolderName; MessageQueuer.SendToAllClients <CraftLibrarySrvMsg>(deleteMsg); } else { LunaLog.Normal($"Saving craft {data.Craft.CraftName} ({ByteSize.FromBytes(data.Craft.NumBytes).KiloBytes} KB) from: {client.PlayerName}."); FileHandler.WriteToFile(fullPath, data.Craft.Data, data.Craft.NumBytes); } SendNotification(client.PlayerName); } else { LunaLog.Warning($"{client.PlayerName} is sending crafts too fast!"); return; } //Remove oldest crafts if the player has too many RemovePlayerOldestCrafts(playerFolderType); //Checks if we are above the max folders limit CheckMaxFolders(); }); }
/// <summary> /// Saves a received screenshot and creates the miniature /// </summary> public static void SaveScreenshot(ClientStructure client, ScreenshotDataMsgData data) { var playerFolder = Path.Combine(ScreenshotPath, client.PlayerName); if (!FileHandler.FolderExists(playerFolder)) { FileHandler.FolderCreate(playerFolder); } var lastTime = LastUploadRequest.GetOrAdd(client.PlayerName, DateTime.MinValue); if (DateTime.Now - lastTime > TimeSpan.FromMilliseconds(ScreenshotSettings.SettingsStore.MinScreenshotIntervalMs)) { LastUploadRequest.AddOrUpdate(client.PlayerName, DateTime.Now, (key, existingVal) => DateTime.Now); if (data.Screenshot.DateTaken == 0) { data.Screenshot.DateTaken = LunaNetworkTime.UtcNow.ToBinary(); } var fileName = $"{data.Screenshot.DateTaken}.png"; var fullPath = Path.Combine(playerFolder, fileName); if (!FileHandler.FileExists(fullPath)) { LunaLog.Normal($"Saving screenshot {fileName} ({ByteSize.FromBytes(data.Screenshot.NumBytes).KiloBytes}{ByteSize.KiloByteSymbol}) from: {client.PlayerName}."); FileHandler.CreateFile(fullPath, data.Screenshot.Data, data.Screenshot.NumBytes); if (Common.PlatformIsWindows()) { CreateMiniature(fullPath); } SendNotification(client); } else { LunaLog.Warning($"{client.PlayerName} tried to overwrite a screnshot!"); return; } } else { LunaLog.Warning($"{client.PlayerName} is sending screenshots too fast!"); return; } //Remove oldest screenshots if the player has too many RemovePlayerOldestScreenshots(playerFolder); //Checks if we are above the max folders limit CheckMaxFolders(); }
/// <summary> /// Saves a received screenshot and creates the miniature /// </summary> public static void SaveScreenshot(ClientStructure client, ScreenshotDataMsgData data) { Task.Run(() => { var playerFolder = Path.Combine(ScreenshotFolder, client.PlayerName); if (!Directory.Exists(playerFolder)) { Directory.CreateDirectory(playerFolder); } var lastTime = LastUploadRequest.GetOrAdd(client.PlayerName, DateTime.MinValue); if (DateTime.Now - lastTime > TimeSpan.FromMilliseconds(GeneralSettings.SettingsStore.MinScreenshotIntervalMs)) { LastUploadRequest.AddOrUpdate(client.PlayerName, DateTime.Now, (key, existingVal) => DateTime.Now); if (data.Screenshot.DateTaken == 0) { data.Screenshot.DateTaken = LunaTime.UtcNow.ToBinary(); } var fileName = $"{data.Screenshot.DateTaken}.png"; if (!File.Exists(fileName)) { var fullPath = Path.Combine(playerFolder, fileName); LunaLog.Normal($"Saving screenshot {fileName} ({data.Screenshot.NumBytes} bytes) from: {client.PlayerName}."); FileHandler.WriteToFile(fullPath, data.Screenshot.Data, data.Screenshot.NumBytes); CreateMiniature(fullPath); SendNotification(client.PlayerName); } else { LunaLog.Warning($"{client.PlayerName} tried to overwrite a screnshot!"); return; } } else { LunaLog.Warning($"{client.PlayerName} is sending screenshots too fast!"); return; } //Remove oldest screenshots if the player has too many RemovePlayerOldestScreenshots(playerFolder); //Checks if we are above the max folders limit CheckMaxFolders(); }); }
public override void HandleMessage(ClientStructure client, IClientMessageBase message) { var messageData = (AdminBaseMsgData)message.Data; if (!string.IsNullOrEmpty(GeneralSettings.SettingsStore.AdminPassword) && GeneralSettings.SettingsStore.AdminPassword == messageData.AdminPassword) { var msgData = ServerContext.ServerMessageFactory.CreateNewMessageData <AdminReplyMsgData>(); switch (messageData.AdminMessageType) { case AdminMessageType.Ban: var banMsg = (AdminBanMsgData)message.Data; LunaLog.Debug($"{client.PlayerName}: Requested a ban against {banMsg.PlayerName}. Reason: {banMsg.Reason}"); msgData.Response = CommandHandler.Commands["ban"].Func($"{banMsg.PlayerName} {banMsg.Reason}") ? AdminResponse.Ok : AdminResponse.Error; break; case AdminMessageType.Kick: var kickMsg = (AdminKickMsgData)message.Data; LunaLog.Debug($"{client.PlayerName}: Requested a kick against {kickMsg.PlayerName}. Reason: {kickMsg.Reason}"); msgData.Response = CommandHandler.Commands["kick"].Func($"{kickMsg.PlayerName} {kickMsg.Reason}") ? AdminResponse.Ok : AdminResponse.Error; break; case AdminMessageType.Dekessler: LunaLog.Debug($"{client.PlayerName}: Requested a dekessler"); CommandHandler.Commands["dekessler"].Func(null); msgData.Response = AdminResponse.Ok; break; case AdminMessageType.Nuke: LunaLog.Debug($"{client.PlayerName}: Requested a nuke"); CommandHandler.Commands["nukeksc"].Func(null); msgData.Response = AdminResponse.Ok; break; default: throw new ArgumentOutOfRangeException(); } MessageQueuer.SendToClient <AdminSrvMsg>(client, msgData); } else { LunaLog.Warning($"{client.PlayerName}: Tried to run an admin command with an invalid password"); var msgData = ServerContext.ServerMessageFactory.CreateNewMessageData <AdminReplyMsgData>(); msgData.Response = AdminResponse.InvalidPassword; MessageQueuer.SendToClient <AdminSrvMsg>(client, msgData); } }
public static void HandleMessage(ClientStructure client, IClientMessageBase message) { var messageData = (ChatMsgData)message.Data; if (messageData.From != client.PlayerName) { return; } if (messageData.Relay) { MessageQueuer.SendToAllClients <ChatSrvMsg>(messageData); LunaLog.ChatMessage($"{messageData.From}: {messageData.Text}"); } else //Is a PM to server msg { LunaLog.Warning($"{messageData.From}: {messageData.Text}"); } }
private static void HandleMessage(IMasterServerMessageBase message, NetIncomingMessage netMsg, NetPeer peer) { if (BannedIpsRetriever.IsBanned(netMsg.SenderEndPoint)) { LunaLog.Debug($"Ignoring BANNED ip: {netMsg.SenderEndPoint}"); return; } try { switch ((message?.Data as MsBaseMsgData)?.MasterServerMessageSubType) { case MasterServerMessageSubType.RegisterServer: RegisterServer(message, netMsg); break; case MasterServerMessageSubType.RequestServers: LunaLog.Normal($"LIST REQUEST from: {netMsg.SenderEndPoint}"); SendServerLists(netMsg, peer); break; case MasterServerMessageSubType.Introduction: var msgData = (MsIntroductionMsgData)message.Data; if (ServerDictionary.TryGetValue(msgData.Id, out var server)) { LunaLog.Normal($"INTRODUCTION request from: {netMsg.SenderEndPoint} to server: {server.ExternalEndpoint}"); peer.Introduce(server.InternalEndpoint, server.ExternalEndpoint, msgData.InternalEndpoint, // client internal netMsg.SenderEndPoint, // client external msgData.Token); // request token } else { LunaLog.Warning($"Client {netMsg.SenderEndPoint} requested introduction to non listed host!"); } break; } } catch (Exception e) { LunaLog.Error($"Error handling message. Details: {e}"); } }
/// <summary> /// Raw updates a vessel in the dictionary and takes care of the locking in case we received another vessel message type /// </summary> public static void RawConfigNodeInsertOrUpdate(Guid vesselId, string vesselDataInConfigNodeFormat) { Task.Run(() => { var vessel = new Classes.Vessel(vesselDataInConfigNodeFormat); if (GeneralSettings.SettingsStore.ModControl) { var vesselParts = vessel.Parts.GetAllValues().Select(p => p.Fields.GetSingle("name").Value); var bannedParts = vesselParts.Except(ModFileSystem.ModControl.AllowedParts); if (bannedParts.Any()) { LunaLog.Warning($"Received a vessel with BANNED parts! {vesselId}"); return; } } lock (Semaphore.GetOrAdd(vesselId, new object())) { VesselStoreSystem.CurrentVessels.AddOrUpdate(vesselId, vessel, (key, existingVal) => vessel); } }); }
public static async void DisplayNewVersionMsg() { while (ServerContext.ServerRunning) { if (LatestVersion > LmpVersioning.CurrentVersion) { LunaLog.Warning($"There is a new version of LMP! Please download it! Current: {LmpVersioning.CurrentVersion} Latest: {LatestVersion}"); if (LmpVersioning.IsCompatible(LatestVersion)) { LunaLog.Debug("Your version is compatible with the latest version so you will still be listed in the master servers."); } else { LunaLog.Warning("Your version is NOT compatible with the latest version. You won't be listed in the master servers!"); } } //Sleep for 30 seconds... await Task.Delay(30 * 1000); } }
public static void HandleFlagDataMessage(ClientStructure client, FlagDataMsgData message) { if (!ValidationRegex.IsMatch(message.Flag.FlagName)) { LunaLog.Warning($"Cannot save flag {message.Flag.FlagName} from {client.PlayerName} as it's flag name has invalid characters"); return; } var playerFlagPath = Path.Combine(FlagPath, client.PlayerName); if (!FileHandler.FolderExists(playerFlagPath)) { FileHandler.FolderCreate(playerFlagPath); } LunaLog.Debug($"Saving flag {message.Flag.FlagName} from {client.PlayerName}"); var newFileName = $"{message.Flag.FlagName.Replace('/', '$')}.png"; FileHandler.WriteToFile(Path.Combine(playerFlagPath, newFileName), message.Flag.FlagData, message.Flag.NumBytes); MessageQueuer.SendToAllClients <FlagSrvMsg>(message); }
private static async Task <NatDevice> DiscoverDevice() { NatDevice device; try { return(await new NatDiscoverer().DiscoverDeviceAsync(PortMapper.Upnp, new CancellationTokenSource(ConnectionSettings.SettingsStore.UpnpMsTimeout))); } catch (Exception e) { LunaLog.Warning("Failed to use UPnP, trying NAT PMP... (" + e.Message + ")"); try { return(await new NatDiscoverer().DiscoverDeviceAsync(PortMapper.Pmp, new CancellationTokenSource(ConnectionSettings.SettingsStore.UpnpMsTimeout))); } catch (Exception ex) { LunaLog.Warning("Failed to use NAT PMP! (" + ex.Message + ")"); return(null); } } }
public static void SaveQuicksave(ClientStructure client, QuicksaveSaveRequestMsgData data) { Task.Run(() => { var quicksaveFile = GetQuicksaveFile(data.Name, data.VesselId); if (File.Exists(quicksaveFile)) { File.Delete(quicksaveFile); } if (!VesselStoreSystem.CurrentVessels.ContainsKey(data.VesselId)) { LunaLog.Warning($"Could save vessel with id {data.VesselId}"); return; } File.WriteAllText(quicksaveFile, VesselStoreSystem.CurrentVessels[data.VesselId].ToString()); SendQuicksaveList(client, data.VesselId); RemoveOldQuicksaves(); }); }
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; } if (!VesselStoreSystem.VesselExists(msgData.Vessel.VesselId)) { LunaLog.Debug($"Saving vessel {msgData.Vessel.VesselId} from {client.PlayerName}. Bytes: {msgData.Vessel.NumBytes}"); } VesselDataUpdater.RawConfigNodeInsertOrUpdate(msgData.Vessel.VesselId, Encoding.UTF8.GetString(msgData.Vessel.Data, 0, msgData.Vessel.NumBytes)); MessageQueuer.RelayMessage <VesselSrvMsg>(client, msgData); }
public static async void StartReceiveingMessages() { try { while (ServerContext.ServerRunning) { var msg = Server.ReadMessage(); if (msg != null) { var client = TryGetClient(msg); switch (msg.MessageType) { case NetIncomingMessageType.ConnectionApproval: if (ServerContext.UsePassword) { var password = msg.ReadString(); if (password != GeneralSettings.SettingsStore.Password) { msg.SenderConnection.Deny("Invalid password"); break; } } msg.SenderConnection.Approve(); break; case NetIncomingMessageType.Data: ClientMessageReceiver.ReceiveCallback(client, msg); break; case NetIncomingMessageType.WarningMessage: LunaLog.Warning(msg.ReadString()); break; case NetIncomingMessageType.DebugMessage: LunaLog.NetworkDebug(msg.ReadString()); break; case NetIncomingMessageType.ConnectionLatencyUpdated: case NetIncomingMessageType.VerboseDebugMessage: LunaLog.NetworkVerboseDebug(msg.ReadString()); break; case NetIncomingMessageType.Error: LunaLog.Error(msg.ReadString()); break; case NetIncomingMessageType.StatusChanged: switch ((NetConnectionStatus)msg.ReadByte()) { case NetConnectionStatus.Connected: var endpoint = msg.SenderConnection.RemoteEndPoint; LunaLog.Normal($"New client Connection from {endpoint.Address}:{endpoint.Port}"); ClientConnectionHandler.ConnectClient(msg.SenderConnection); break; case NetConnectionStatus.Disconnected: var reason = msg.ReadString(); if (client != null) { ClientConnectionHandler.DisconnectClient(client, reason); } break; } break; default: var details = msg.PeekString(); LunaLog.Debug($"Lidgren: {msg.MessageType.ToString().ToUpper()} -- {details}"); break; } } else { await Task.Delay(IntervalSettings.SettingsStore.SendReceiveThreadTickMs); } } } catch (Exception e) { LunaLog.Fatal($"ERROR in thread receive! Details: {e}"); } }
public static void LoadModFile() { try { ModControl = LunaXmlSerializer.ReadXmlFromPath <ModControlStructure>(ServerContext.ModFilePath); } catch (Exception) { LunaLog.Warning("LMPModControl file was either missing or corrupt, a fresh default copy has been regenerated."); GenerateNewModFile(); } string[] DefaultAllowedParts = new string[] { "StandardCtrlSrf", "CanardController", "noseCone", "AdvancedCanard", "airplaneTail", "deltaWing", "noseConeAdapter", "rocketNoseCone", "smallCtrlSrf", "standardNoseCone", "sweptWing", "tailfin", "wingConnector", "winglet", "R8winglet", "winglet3", "Mark1Cockpit", "Mark2Cockpit", "Mark1-2Pod", "advSasModule", "asasmodule1-2", "avionicsNoseCone", "crewCabin", "cupola", "landerCabinSmall", "mark3Cockpit", "mk1pod", "mk2LanderCabin", "probeCoreCube", "probeCoreHex", "probeCoreOcto", "probeCoreOcto2", "probeCoreSphere", "probeStackLarge", "probeStackSmall", "sasModule", "seatExternalCmd", "rtg", "batteryBank", "batteryBankLarge", "batteryBankMini", "batteryPack", "ksp.r.largeBatteryPack", "largeSolarPanel", "solarPanels1", "solarPanels2", "solarPanels3", "solarPanels4", "solarPanels5", "JetEngine", "engineLargeSkipper", "ionEngine", "liquidEngine", "liquidEngine1-2", "liquidEngine2", "liquidEngine2-2", "liquidEngine3", "liquidEngineMini", "microEngine", "nuclearEngine", "radialEngineMini", "radialLiquidEngine1-2", "sepMotor1", "smallRadialEngine", "solidBooster", "solidBooster1-1", "toroidalAerospike", "turboFanEngine", "MK1Fuselage", "Mk1FuselageStructural", "RCSFuelTank", "RCSTank1-2", "rcsTankMini", "rcsTankRadialLong", "fuelTank", "fuelTank1-2", "fuelTank2-2", "fuelTank3-2", "fuelTank4-2", "fuelTankSmall", "fuelTankSmallFlat", "miniFuelTank", "mk2Fuselage", "mk2SpacePlaneAdapter", "mk3Fuselage", "mk3spacePlaneAdapter", "radialRCSTank", "toroidalFuelTank", "xenonTank", "xenonTankRadial", "adapterLargeSmallBi", "adapterLargeSmallQuad", "adapterLargeSmallTri", "adapterSmallMiniShort", "adapterSmallMiniTall", "nacelleBody", "radialEngineBody", "smallHardpoint", "stationHub", "structuralIBeam1", "structuralIBeam2", "structuralIBeam3", "structuralMiniNode", "structuralPanel1", "structuralPanel2", "structuralPylon", "structuralWing", "strutConnector", "strutCube", "strutOcto", "trussAdapter", "trussPiece1x", "trussPiece3x", "CircularIntake", "landingLeg1", "landingLeg1-2", "RCSBlock", "stackDecoupler", "airScoop", "commDish", "decoupler1-2", "dockingPort1", "dockingPort2", "dockingPort3", "dockingPortLarge", "dockingPortLateral", "fuelLine", "ladder1", "largeAdapter", "largeAdapter2", "launchClamp1", "linearRcs", "longAntenna", "miniLandingLeg", "parachuteDrogue", "parachuteLarge", "parachuteRadial", "parachuteSingle", "radialDecoupler", "radialDecoupler1-2", "radialDecoupler2", "ramAirIntake", "roverBody", "sensorAccelerometer", "sensorBarometer", "sensorGravimeter", "sensorThermometer", "spotLight1", "spotLight2", "stackBiCoupler", "stackDecouplerMini", "stackPoint1", "stackQuadCoupler", "stackSeparator", "stackSeparatorBig", "stackSeparatorMini", "stackTriCoupler", "telescopicLadder", "telescopicLadderBay", "SmallGearBay", "roverWheel1", "roverWheel2", "roverWheel3", "wheelMed", "flag", "kerbalEVA", "mediumDishAntenna", "GooExperiment", "science.module", "RAPIER", "Large.Crewed.Lab", "GrapplingDevice", "LaunchEscapeSystem", "MassiveBooster", "PotatoRoid", "Size2LFB", "Size3AdvancedEngine", "size3Decoupler", "Size3EngineCluster", "Size3LargeTank", "Size3MediumTank", "Size3SmallTank", "Size3to2Adapter", "omsEngine", "vernierEngine", "delta.small", "elevon2", "elevon3", "elevon5", "IntakeRadialLong", "MK1IntakeFuselage", "mk2.1m.AdapterLong", "mk2.1m.Bicoupler", "mk2CargoBayL", "mk2CargoBayS", "mk2Cockpit.Inline", "mk2Cockpit.Standard", "mk2CrewCabin", "mk2DockingPort", "mk2DroneCore", "mk2FuselageLongLFO", "mk2FuselageShortLFO", "mk2FuselageShortLiquid", "mk2FuselageShortMono", "shockConeIntake", "structuralWing2", "structuralWing3", "structuralWing4", "sweptWing1", "sweptWing2", "wingConnector2", "wingConnector3", "wingConnector4", "wingConnector5", "wingStrake", "adapterMk3-Mk2", "adapterMk3-Size2", "adapterMk3-Size2Slant", "adapterSize2-Mk2", "adapterSize2-Size1", "adapterSize2-Size1Slant", "adapterSize3-Mk3", "mk3CargoBayL", "mk3CargoBayM", "mk3CargoBayS", "mk3Cockpit.Shuttle", "mk3CrewCabin", "mk3FuselageLF.100", "mk3FuselageLF.25", "mk3FuselageLF.50", "mk3FuselageLFO.100", "mk3FuselageLFO.25", "mk3FuselageLFO.50", "mk3FuselageMONO", "kerbalEVAfemale", "airbrake1", "airlinerCtrlSrf", "airlinerMainWing", "airlinerTailFin", "pointyNoseConeA", "pointyNoseConeB", "airplaneTailB", "fairingSize1", "fairingSize2", "fairingSize3", "HeatShield1", "HeatShield2", "HeatShield3", "wingShuttleDelta", "elevonMk3", "wingShuttleElevon1", "wingShuttleElevon2", "wingShuttleRudder", "wingShuttleStrake", "delta.small", "mk2Cockpit.Inline", "mk2Cockpit.Standard", "mk3Cockpit.Shuttle", "ksp.r.largeBatteryPack", "solidBooster.sm", "fuelTank.long", "mk2.1m.Bicoupler", "mk2.1m.AdapterLong", "mk3FuselageLFO.100", "mk3FuselageLFO.25", "mk3FuselageLFO.50", "mk3FuselageLF.100", "mk3FuselageLF.25", "mk3FuselageLF.50", "xenonTankLarge", "mk3Cockpit.Shuttle", "FuelCell", "FuelCellArray", "ISRU", "LargeTank", "OrbitalScanner", "RadialDrill", "SmallTank", "SurfaceScanner", "SurveyScanner", "sensorAtmosphere", "Large.Crewed.Lab", "science.module", "radialDrogue", "ServiceBay.125", "ServiceBay.250", "GearFixed", "GearFree", "GearLarge", "GearMedium", "basicFin", "foldingRadLarge", "foldingRadMed", "foldingRadSmall", "radPanelLg", "radPanelSm", "turboJet", "turboFanSize2", "miniJetEngine", "SSME", "adapterEngines", "miniFuselage", "miniIntake", "MK1CrewCabin", "MiniISRU", "MiniDrill", "RadialOreTank", "radPanelEdge", "mk3CargoRamp", "InflatableHeatShield", "HECS2.ProbeCore", "HighGainAntenna", "LgRadialSolarPanel", "GearSmall", "ScienceBox", "SurfAntenna", "HighGainAntenna5", "RelayAntenna100", "RelayAntenna5", "RelayAntenna50", "HeatShield0", "InfraredTelescope", "kerbalEVAVintage", "kerbalEVAfemaleVintage", "mk1-3pod", "Decoupler_0", "Decoupler_1", "Decoupler_2", "Decoupler_3", "Separator_0", "Separator_1", "Separator_2", "Separator_3", "externalTankCapsule", "externalTankRound", "externalTankToroid", "Rockomax16_BW", "Rockomax32_BW", "Rockomax64_BW", "Rockomax8BW", "Decoupler.0", "Decoupler.1", "Decoupler.2", "Decoupler.3", "Separator.0", "Separator.1", "Separator.2", "Separator.3", "Rockomax16.BW", "Rockomax32.BW", "Rockomax64.BW", "Decoupler.1p5", "Decoupler.4", "EnginePlate1p5", "EnginePlate2", "EnginePlate3", "EnginePlate4", "InflatableAirlock", "Separator.1p5", "Separator.4", "Size1p5.Strut.Decoupler", "LiquidEngineKE-1", "LiquidEngineLV-T91", "LiquidEngineLV-TX87", "LiquidEngineRE-I2", "LiquidEngineRE-J10", "LiquidEngineRK-7", "LiquidEngineRV-1", "monopropMiniSphere", "Size1p5.Monoprop", "Size1p5.Size0.Adapter.01", "Size1p5.Size1.Adapter.01", "Size1p5.Size1.Adapter.02", "Size1p5.Size2.Adapter.01", "Size1p5.Tank.01", "Size1p5.Tank.02", "Size1p5.Tank.03", "Size1p5.Tank.04", "Size1p5.Tank.05", "Size3.Size4.Adapter.01", "Size4.EngineAdapter.01", "Size4.Tank.01", "Size4.Tank.02", "Size4.Tank.03", "Size4.Tank.04", "roverWheelM1-F", "fairingSize1p5", "fairingSize4", "Size1to0ServiceModule", "ServiceModule18", "ServiceModule25", "kv1Pod", "kv2Pod", "kv3Pod", "Mk2Pod", "MEMLander", "EquiTriangle0", "EquiTriangle1", "EquiTriangle1p5", "EquiTriangle2", "Panel0", "Panel1", "Panel1p5", "Panel2", "Triangle0", "Triangle1", "Triangle1p5", "Triangle2", "Tube1", "Tube1p5", "Tube2", "Tube3", "Tube4", "HeatShield1p5", "mk1pod.v2", "probeCoreHex.v2", "probeCoreOcto2.v2", "probeCoreOcto.v2", "roverBody.v2", "probeCoreSphere.v2", "solidBooster.v2", "solidBooster.sm.v2", "rocketNoseCone.v2", "mk2LanderCabin.v2", "liquidEngineMini.v2", "liquidEngine3.v2", "liquidEngine2-2.v2", "Size3To2Adapter.v2", "stackBiCoupler.v2", "stackTriCoupler.v2", "rocketNoseConeSize3", "smallRadialEngine.v2", "radialEngineMini.v2", "microEngine.v2", "RCSBlock.v2", "kerbalEVAFuture", "kerbalEVAfemaleFuture", "rocketNoseConeSize4", "cargoContainer", "smallCargoContainer", "DeployedCentralStation", "DeployedGoExOb", "DeployedIONExp", "DeployedRTG", "DeployedSatDish", "DeployedSeismicSensor", "DeployedSolarPanel", "DeployedWeatherStn", "hinge.01", "hinge.01.s", "hinge.03", "hinge.03.s", "hinge.04", "piston.01", "piston.02", "piston.03", "piston.04", "rotor.01", "rotor.02", "rotor.03", "rotoServo.00", "rotoServo.02", "rotoServo.03", "rotoServo.04", "controller1000", "RobotArmScanner.S1", "RobotArmScanner.S2", "RobotArmScanner.S3", "noseconeTiny", "noseconeVS", "largeHeliBlade", "largePropeller", "mediumHeliBlade", "mediumPropeller", "smallHeliBlade", "smallPropeller", "RotorEngine.02", "RotorEngine.03", "rotor.01s", "rotor.02s", "rotor.03s", "lGripPad", "lGripStrip", "mGripPad", "sGripPad", "sGripStrip", "Thoroughbred", "Clydesdale", "Shrimp", "Mite", "ServiceBay.125.v2", "ServiceBay.250.v2", "liquidEngineMainsail.v2", "engineLargeSkipper.v2", "ReleaseValve", "Size.1.5.Cone", "Pollux", "FanShroud.01", "FanShroud.02", "FanShroud.03", "largeFanBlade", "mediumFanBlade", "smallFanBlade", "Magnetometer", "MpoProbe", "MtmStage", "PotatoComet", "flagPartFlat", "flagPartSize0", "flagPartSize1", "flagPartSize2", "flagPartSize3", "smallClaw", "evaCylinder", "evaJetpack", "evaChute", "evaRepairKit", "evaScienceKit", "CargoStorageUnit", "ConformalStorageUnit", "Size2LFB.v2", "HighGainAntenna5.v2", "domeLight1", "groundLight1", "groundLight2", "navLight1", "spotLight3", "stripLight1", "RCSblock.01.small", "RCSLinearSmall", "flagPartSize1p5", "flagPartSize4" }; string[] DefaultAllowedResources = new string[] { "LiquidFuel", "Oxidizer", "SolidFuel", "MonoPropellant", "XenonGas", "ElectricCharge", "IntakeAir", "EVA Propellant", "Ore", "Ablator" }; foreach (string part in DefaultAllowedParts) { if (!ModControl.AllowedParts.Contains(part)) { ModControl.AllowedParts.Add(part); } } foreach (string res in DefaultAllowedResources) { if (!ModControl.AllowedResources.Contains(res)) { ModControl.AllowedResources.Add(res); } } }
public static void Main() { try { Console.Title = $"LMPServer {LmpVersioning.CurrentVersion}"; #if DEBUG Console.Title += " DEBUG"; #endif Console.OutputEncoding = Encoding.Unicode; ServerContext.StartTime = LunaTime.UtcNow.Ticks; if (!Common.PlatformIsWindows()) { LunaLog.Warning("Remember! Quit the server by using Control+C so the vessels are saved to the hard drive!"); } if (Common.PlatformIsWindows()) { ExitSignal.Exit += (sender, args) => Exit(); } else { //Register the ctrl+c event and exit signal if we are on linux Console.CancelKeyPress += (sender, args) => Exit(); } //We disable quick edit as otherwise when you select some text for copy/paste then you can't write to the console and server freezes //This just happens on windows.... if (Common.PlatformIsWindows()) { ConsoleUtil.DisableConsoleQuickEdit(); } //We cannot run more than 6 instances ofd servers + clients as otherwise the sync time will fail (30 seconds / 5 seconds = 6) but we use 3 for safety if (GetRunningInstances() > 3) { throw new HandledException("Cannot run more than 3 servers at a time!"); } //Start the server clock ServerContext.ServerClock.Start(); //Set the last player activity time to server start ServerContext.LastPlayerActivity = ServerContext.ServerClock.ElapsedMilliseconds; ServerContext.ServerStarting = true; //Set day for log change ServerContext.Day = LunaTime.Now.Day; LunaLog.Normal($"Luna Server version: {LmpVersioning.CurrentVersion} ({Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)})"); Universe.CheckUniverse(); LoadSettingsAndGroups(); VesselStoreSystem.LoadExistingVessels(); ScenarioSystem.GenerateDefaultScenarios(); ScenarioStoreSystem.LoadExistingScenarios(); LmpPluginHandler.LoadPlugins(); WarpSystem.Reset(); LunaLog.Normal($"Starting '{GeneralSettings.SettingsStore.ServerName}' on Port {ConnectionSettings.SettingsStore.Port}... "); LmpPortMapper.OpenPort().Wait(); ServerContext.ServerRunning = true; LidgrenServer.SetupLidgrenServer(); //Do not add the command handler thread to the TaskContainer as it's a blocking task LongRunTaskFactory.StartNew(() => new CommandHandler().ThreadMain(), CancellationTokenSrc.Token); TaskContainer.Add(LongRunTaskFactory.StartNew(LmpPortMapper.RefreshUpnpPort, CancellationTokenSrc.Token)); TaskContainer.Add(LongRunTaskFactory.StartNew(LogThread.RunLogThread, CancellationTokenSrc.Token)); TaskContainer.Add(LongRunTaskFactory.StartNew(() => new ClientMainThread().ThreadMain(), CancellationTokenSrc.Token)); TaskContainer.Add(LongRunTaskFactory.StartNew(() => BackupSystem.PerformBackups(CancellationTokenSrc.Token), CancellationTokenSrc.Token)); TaskContainer.Add(LongRunTaskFactory.StartNew(LidgrenServer.StartReceiveingMessages, CancellationTokenSrc.Token)); TaskContainer.Add(LongRunTaskFactory.StartNew(LidgrenMasterServer.RefreshMasterServersList, CancellationTokenSrc.Token)); TaskContainer.Add(LongRunTaskFactory.StartNew(LidgrenMasterServer.RegisterWithMasterServer, CancellationTokenSrc.Token)); TaskContainer.Add(LongRunTaskFactory.StartNew(VesselRelaySystem.RelayOldVesselMessages, CancellationTokenSrc.Token)); TaskContainer.Add(LongRunTaskFactory.StartNew(VersionChecker.RefreshLatestVersion, CancellationTokenSrc.Token)); TaskContainer.Add(LongRunTaskFactory.StartNew(VersionChecker.DisplayNewVersionMsg, CancellationTokenSrc.Token)); while (ServerContext.ServerStarting) { Thread.Sleep(500); } LunaLog.Normal("All systems up and running. Поехали!"); LmpPluginHandler.FireOnServerStart(); QuitEvent.WaitOne(); LmpPluginHandler.FireOnServerStop(); LunaLog.Normal("So long and thanks for all the fish!"); } catch (Exception e) { if (e is HandledException) { LunaLog.Fatal(e.Message); } else { LunaLog.Fatal($"Error in main server thread, Exception: {e}"); } Console.ReadLine(); //Avoid closing automatically } }
public static void StartReceivingMessages() { while (ServerContext.ServerRunning) { var msg = Server.WaitMessage(ServerContext.PlayerCount > 0 ? IntervalSettings.SettingsStore.SendReceiveThreadTickMs : int.MaxValue); if (msg != null) { try { ClientStructure client = null; if (msg.SenderConnection != null) { ServerContext.Clients.TryGetValue(msg.SenderConnection.RemoteEndPoint, out client); } switch (msg.MessageType) { case NetIncomingMessageType.ConnectionApproval: if (ServerContext.UsePassword) { if (msg.ReadString() != GeneralSettings.SettingsStore.Password) { msg.SenderConnection.Deny("Invalid password"); break; } } msg.SenderConnection.Approve(); break; case NetIncomingMessageType.Data: MessageReceiver.ReceiveCallback(client, msg); if (client == null) { break; } client.BytesReceived += (uint)msg.LengthBytes; break; case NetIncomingMessageType.WarningMessage: LunaLog.Warning(msg.ReadString()); break; case NetIncomingMessageType.DebugMessage: LunaLog.NetworkDebug(msg.ReadString()); break; case NetIncomingMessageType.ConnectionLatencyUpdated: case NetIncomingMessageType.VerboseDebugMessage: LunaLog.NetworkVerboseDebug(msg.ReadString()); break; case NetIncomingMessageType.ErrorMessage: case NetIncomingMessageType.Error: LunaLog.Error(msg.ReadString()); break; case NetIncomingMessageType.StatusChanged: switch ((NetConnectionStatus)msg.ReadByte()) { case NetConnectionStatus.Connected: var endpoint = msg.SenderConnection.RemoteEndPoint; LunaLog.Normal($"New client Connection from {endpoint.Address}:{endpoint.Port}"); ClientConnectionHandler.ConnectClient(msg.SenderConnection); break; case NetConnectionStatus.Disconnected: if (client != null) { ClientConnectionHandler.DisconnectClient(client, msg.ReadString()); } break; } break; default: LunaLog.Warning($"Unhandled Lidgren Message: {msg.MessageType} -- {msg.ReadString()}"); break; } } catch (Exception e) { LunaLog.Error($"ERROR in networking thread! Details: {e}"); } } } }
private static void HandleMessage(IMasterServerMessageBase message, NetIncomingMessage netMsg, NetPeer peer) { if (BannedIpsRetriever.IsBanned(netMsg.SenderEndPoint)) { LunaLog.Debug($"Ignoring BANNED ip: {netMsg.SenderEndPoint}"); return; } try { switch ((message?.Data as MsBaseMsgData)?.MasterServerMessageSubType) { case MasterServerMessageSubType.RegisterServer: RegisterServer(message, netMsg); break; case MasterServerMessageSubType.RequestServers: LunaLog.Normal($"LIST REQUEST from: {netMsg.SenderEndPoint}"); SendServerLists(netMsg, peer); break; case MasterServerMessageSubType.Introduction: var msgData = (MsIntroductionMsgData)message.Data; if (ServerDictionary.TryGetValue(msgData.Id, out var server)) { _ = Task.Run(() => { if (!server.InternalEndpoint6.Address.Equals(IPAddress.IPv6Loopback) && !server.InternalEndpoint6.Address.Equals(IPAddress.IPv6Loopback)) { // Both client and server are listening on IPv6, try an IPv6 firewall punchthrough // This also triggers a first punchthrough on IPv4 with the public addresses LunaLog.Normal( $"INTRODUCTION request from: {msgData.InternalEndpoint6} to server: {server.InternalEndpoint6}"); peer.Introduce(server.InternalEndpoint6, server.ExternalEndpoint, msgData.InternalEndpoint6, // client internal netMsg.SenderEndPoint, // client external msgData.Token); // request token // Give the first introduction attempt some time Thread.Sleep(50); } LunaLog.Normal( $"INTRODUCTION request from: {netMsg.SenderEndPoint} to server: {server.ExternalEndpoint}"); peer.Introduce(server.InternalEndpoint, server.ExternalEndpoint, msgData.InternalEndpoint, // client internal netMsg.SenderEndPoint, // client external msgData.Token); // request token }); } else { LunaLog.Warning($"Client {netMsg.SenderEndPoint} requested introduction to non listed host!"); } break; } } catch (Exception e) { LunaLog.Error($"Error handling message. Details: {e}"); } }