public static void SendGroupsToAll() { DarkLog.Debug("Sending groups to everyone"); Dictionary <string, List <string> > playerGroups = Groups.fetch.GetGroupsCopy(); Dictionary <string, List <string> > groupAdmins = Groups.fetch.GetAdminsCopy(); using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)GroupMessageType.GROUP_RESET); ServerMessage sm = new ServerMessage(); sm.type = ServerMessageType.GROUP; sm.data = mw.GetMessageBytes(); ClientHandler.SendToAll(null, sm, true); } foreach (KeyValuePair <string, List <string> > kvp in playerGroups) { using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)GroupMessageType.GROUP_INFO); mw.Write <string>(kvp.Key); mw.Write <string[]>(kvp.Value.ToArray()); ServerMessage sm = new ServerMessage(); sm.type = ServerMessageType.GROUP; sm.data = mw.GetMessageBytes();; ClientHandler.SendToAll(null, sm, true); } } foreach (KeyValuePair <string, List <string> > kvp in groupAdmins) { using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)GroupMessageType.ADMIN_INFO); mw.Write <string>(kvp.Key); mw.Write <string[]>(kvp.Value.ToArray()); ServerMessage sm = new ServerMessage(); sm.type = ServerMessageType.GROUP; sm.data = mw.GetMessageBytes();; ClientHandler.SendToAll(null, sm, true); } } }
public static void HandlePlayerStatus(ClientObject client, byte[] messageData) { using (MessageReader mr = new MessageReader(messageData)) { string playerName = mr.Read <string>(); if (playerName != client.playerName) { DarkLog.Debug(client.playerName + " tried to send an update for " + playerName + ", kicking."); Messages.ConnectionEnd.SendConnectionEnd(client, "Kicked for sending an update for another player"); return; } client.playerStatus.vesselText = mr.Read <string>(); client.playerStatus.statusText = mr.Read <string>(); } //Relay the message ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.PLAYER_STATUS; newMessage.data = messageData; ClientHandler.SendToAll(client, newMessage, false); }
private void ConnectToServer() { try { connection = new TcpClient(); connection.Connect(settingsStore.reportingEndpoint); if (connection.Connected) { DarkLog.Debug("Connected to reporting server"); sendMessages.Clear(); ReportData(); connectedStatus = true; sendThread = new Thread(new ThreadStart(SendThreadMain)); sendThread.Start(); } } catch (Exception e) { DarkLog.Debug("Error connecting to reporting server: " + e); } }
public static void HandleKerbalProto(ClientObject client, byte[] messageData) { //Send kerbal using (MessageReader mr = new MessageReader(messageData)) { //Don't care about subspace / send time. mr.Read <double>(); string kerbalName = mr.Read <string>(); DarkLog.Debug("Saving kerbal " + kerbalName + " from " + client.playerName); byte[] kerbalData = mr.Read <byte[]>(); lock (Server.universeSizeLock) { File.WriteAllBytes(Path.Combine(Server.universeDirectory, "Kerbals", kerbalName + ".txt"), kerbalData); } } ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.KERBAL_REPLY; newMessage.data = messageData; ClientHandler.SendToAll(client, newMessage, false); }
public static void CheckHeartBeat(ClientObject client) { long currentTime = Server.serverClock.ElapsedMilliseconds; if ((currentTime - client.lastReceiveTime) > Common.CONNECTION_TIMEOUT) { //Heartbeat timeout DarkLog.Normal("Disconnecting client " + client.playerName + ", endpoint " + client.endpoint + ", Connection timed out"); ClientHandler.DisconnectClient(client); } else { if (client.sendMessageQueueHigh.Count == 0 && client.sendMessageQueueSplit.Count == 0 && client.sendMessageQueueLow.Count == 0) { if ((currentTime - client.lastSendTime) > Common.HEART_BEAT_INTERVAL) { Messages.Heartbeat.Send(client); } } } }
//This is the main function that gets called to load your plugin public void DarkPluginMain() { DarkLog.WriteLine("DarkPluginMain() has been hit in HelloToolkit Plugin Example."); DarkLog.WriteLine("Halo Online Folder: " + DarkSettings.HaloOnlineFolder); DarkLog.WriteLine("DebugMode: " + DebugMode.ToString()); if (!runningForm) { //Change `HelloForm` to the name of your main form //Please check the comment for `runningForm` above. helloForm = new HelloForm(); helloForm.Show(); } else { //If you checked the comment for `runningForm` then this should //be smart enough to just show and hide your plugin instead of killing //it completely, or realoading it and breaking everything... DarkLog.WriteLine("Plugin already running!"); helloForm.Show(); } }
private static void HandleNewSubspace(ClientObject client, long serverClock, double planetTime, float subspaceSpeed) { lock (createLock) { DarkLog.Debug("Create subspace"); //Create subspace Subspace newSubspace = new Subspace(); newSubspace.serverClock = serverClock; newSubspace.planetTime = planetTime; newSubspace.subspaceSpeed = subspaceSpeed; subspaces.Add(freeID, newSubspace); //Create message ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.WARP_CONTROL; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)WarpMessageType.NEW_SUBSPACE); mw.Write <int>(freeID); mw.Write <long>(serverClock); mw.Write <double>(planetTime); mw.Write <float>(subspaceSpeed); newMessage.data = mw.GetMessageBytes(); } //Tell all clients about the new subspace ClientHandler.SendToAll(null, newMessage, true); //Send the client to that subspace if (Settings.settingsStore.warpMode == WarpMode.MCW_FORCE || Settings.settingsStore.warpMode == WarpMode.MCW_VOTE || Settings.settingsStore.warpMode == WarpMode.MCW_LOWEST) { SendSetSubspaceToAll(freeID); } else { SendSetSubspace(client, freeID); } freeID++; //Save to disk SaveLatestSubspace(); } }
public static void HandleKerbalRemoval(ClientObject client, byte[] messageData) { using (MessageReader mr = new MessageReader(messageData)) { //Don't care about the subspace on the server. mr.Read <double>(); string kerbalName = mr.Read <string>(); DarkLog.Debug("Removing kerbal " + kerbalName + " from " + client.playerName); if (File.Exists(Path.Combine(Server.universeDirectory, "Kerbals", kerbalName + ".txt"))) { lock (Server.universeSizeLock) { File.Delete(Path.Combine(Server.universeDirectory, "Kerbals", kerbalName + ".txt")); } } //Relay the message. ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.KERBAL_REMOVE; newMessage.data = messageData; ClientHandler.SendToAll(client, newMessage, false); } }
public static void SendVesselPermissionsToClient(ClientObject client) { DarkLog.Debug("Sending permissions to " + client.playerName); Dictionary <Guid, VesselPermission> vesselPermissions = Permissions.fetch.GetPermissionsCopy(); foreach (KeyValuePair <Guid, VesselPermission> kvp in vesselPermissions) { using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)PermissionMessageType.PERMISSION_INFO); mw.Write <string>(kvp.Key.ToString()); mw.Write <string>(kvp.Value.owner); mw.Write <string>(kvp.Value.protection.ToString()); if (!string.IsNullOrEmpty(kvp.Value.group)) { mw.Write <bool>(true); mw.Write <string>(kvp.Value.group); } else { mw.Write <bool>(false); } ServerMessage sm = new ServerMessage(); sm.type = ServerMessageType.PERMISSION; sm.data = mw.GetMessageBytes(); ClientHandler.SendToClient(client, sm, true); } } ServerMessage sm2 = new ServerMessage(); sm2.type = ServerMessageType.PERMISSION; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)PermissionMessageType.PERMISSION_SYNCED); sm2.data = mw.GetMessageBytes(); } ClientHandler.SendToClient(client, sm2, true); }
// Send a specific scenario module to all clients - only called in shared science mode. public static void SendScenarioModuleToClients(string scenarioName, byte[] scenarioData) { string scenarioFile = Path.Combine(Server.universeDirectory, "Scenarios", "Shared", scenarioName + ".txt"); string[] scenarioNames = new string[1]; byte[][] scenarioDataArray = new byte[1][]; scenarioNames[0] = scenarioName; scenarioDataArray[0] = File.ReadAllBytes(scenarioFile); ServerMessage newMessageComp = new ServerMessage(); newMessageComp.type = ServerMessageType.SCENARIO_DATA; using (MessageWriter mw = new MessageWriter()) { mw.Write <string[]>(scenarioNames); foreach (byte[] thisScenarioData in scenarioDataArray) { mw.Write <byte[]>(Compression.CompressIfNeeded(thisScenarioData)); } newMessageComp.data = mw.GetMessageBytes(); } ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.SCENARIO_DATA; using (MessageWriter mw = new MessageWriter()) { mw.Write <string[]>(scenarioNames); foreach (byte[] thisScenarioData in scenarioDataArray) { mw.Write <byte[]>(Compression.AddCompressionHeader(thisScenarioData, false)); } newMessage.data = mw.GetMessageBytes(); } ClientHandler.SendToAllAutoCompressed(null, newMessageComp, newMessage, true); DarkLog.Debug("Sent " + scenarioName + " to all players."); }
private static void LoadSavedSubspace() { try { string subspaceFile = Path.Combine(Server.universeDirectory, "subspace.txt"); using (StreamReader sr = new StreamReader(subspaceFile)) { //Ignore the comment line. string firstLine = ""; while (firstLine.StartsWith("#", StringComparison.Ordinal) || String.IsNullOrEmpty(firstLine)) { firstLine = sr.ReadLine().Trim(); } Subspace savedSubspace = new Subspace(); int subspaceID = Int32.Parse(firstLine); savedSubspace.serverClock = Int64.Parse(sr.ReadLine().Trim()); savedSubspace.planetTime = Double.Parse(sr.ReadLine().Trim()); savedSubspace.subspaceSpeed = Single.Parse(sr.ReadLine().Trim()); subspaces.Add(subspaceID, savedSubspace); lock (createLock) { freeID = subspaceID + 1; } } } catch { DarkLog.Debug("Creating new subspace lock file"); Subspace newSubspace = new Subspace(); newSubspace.serverClock = DateTime.UtcNow.Ticks; newSubspace.planetTime = 100d; newSubspace.subspaceSpeed = 1f; subspaces.Add(0, newSubspace); SaveSubspace(0, newSubspace); freeID = 1; } }
public static void HandleScenarioModuleData(ClientObject client, byte[] messageData) { string clientPath = GetScenarioPath(client); using (MessageReader mr = new MessageReader(messageData)) { //Don't care about subspace / send time. string[] scenarioName = mr.Read <string[]>(); DarkLog.Debug("Saving " + scenarioName.Length + " scenario modules from " + client.playerName); for (int i = 0; i < scenarioName.Length; i++) { byte[] scenarioData = Compression.DecompressIfNeeded(mr.Read <byte[]>()); lock (Server.universeSizeLock) { File.WriteAllBytes(Path.Combine(clientPath, scenarioName[i] + ".txt"), scenarioData); } if (Settings.settingsStore.sharedScience) { SendScenarioModuleToClients(scenarioName[i], scenarioData); } } } }
public static void HandleVesselRemoval(ClientObject client, byte[] messageData) { using (MessageReader mr = new MessageReader(messageData)) { //Don't care about the subspace on the server. mr.Read <double>(); string vesselID = mr.Read <string>(); Permissions.fetch.SetVesselOwnerIfUnowned(new Guid(vesselID), client.playerName); if (!Permissions.fetch.PlayerHasVesselPermission(client.playerName, new Guid(vesselID))) { Messages.ConnectionEnd.SendConnectionEnd(client, "Kicked from the server, tried to remove protected vessel"); return; } bool isDockingUpdate = mr.Read <bool>(); if (!isDockingUpdate) { DarkLog.Debug("Removing vessel " + vesselID + " from " + client.playerName); } else { DarkLog.Debug("Removing DOCKED vessel " + vesselID + " from " + client.playerName); } if (File.Exists(Path.Combine(Server.universeDirectory, "Vessels", vesselID + ".txt"))) { lock (Server.universeSizeLock) { File.Delete(Path.Combine(Server.universeDirectory, "Vessels", vesselID + ".txt")); } } //Relay the message. ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.VESSEL_REMOVE; newMessage.data = messageData; ClientHandler.SendToAll(client, newMessage, false); } }
public static void HandleKerbalsRequest(ClientObject client) { //The time sensitive SYNC_TIME is over by this point. using (MessageWriter mw = new MessageWriter()) { mw.Write <string>(client.playerName); ServerMessage joinMessage = new ServerMessage(); joinMessage.type = ServerMessageType.PLAYER_JOIN; joinMessage.data = mw.GetMessageBytes(); ClientHandler.SendToAll(client, joinMessage, true); } Messages.ServerSettings.SendServerSettings(client); Messages.WarpControl.SendSetSubspace(client); Messages.WarpControl.SendAllSubspaces(client); Messages.PlayerColor.SendAllPlayerColors(client); Messages.PlayerStatus.SendAllPlayerStatus(client); Messages.ScenarioData.SendScenarioModules(client); Messages.WarpControl.SendAllReportedSkewRates(client); Messages.CraftLibrary.SendCraftList(client); Messages.Chat.SendPlayerChatChannels(client); Messages.LockSystem.SendAllLocks(client); Messages.AdminSystem.SendAllAdmins(client); //Send kerbals lock (Server.universeSizeLock) { string[] kerbalFiles = Directory.GetFiles(Path.Combine(Server.universeDirectory, "Kerbals")); foreach (string kerbalFile in kerbalFiles) { string kerbalName = Path.GetFileNameWithoutExtension(kerbalFile); byte[] kerbalData = File.ReadAllBytes(kerbalFile); SendKerbal(client, kerbalName, kerbalData); } DarkLog.Debug("Sending " + client.playerName + " " + kerbalFiles.Length + " kerbals..."); } SendKerbalsComplete(client); }
public static void SendSetSubspace(ClientObject client) { if (!Settings.settingsStore.keepTickingWhileOffline && ClientHandler.GetClients().Length == 1) { DarkLog.Debug("Reverting server time to last player connection"); long currentTime = DateTime.UtcNow.Ticks; foreach (KeyValuePair <int, Subspace> subspace in subspaces) { subspace.Value.serverClock = currentTime; subspace.Value.subspaceSpeed = 1f; SaveLatestSubspace(); } } int targetSubspace = -1; if (Settings.settingsStore.sendPlayerToLatestSubspace || !playerSubspace.ContainsKey(client.playerName)) { DarkLog.Debug("Sending " + client.playerName + " to the latest subspace " + targetSubspace); targetSubspace = GetLatestSubspace(); } else { DarkLog.Debug("Sending " + client.playerName + " to the previous subspace " + targetSubspace); targetSubspace = playerSubspace[client.playerName]; } client.subspace = targetSubspace; ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.SET_SUBSPACE; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>(targetSubspace); newMessage.data = mw.GetMessageBytes(); } ClientHandler.SendToClient(client, newMessage, true); }
private void LoadSettings() { string tokenFileFullPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), TOKEN_FILE); if (!File.Exists(tokenFileFullPath)) { using (StreamWriter sw = new StreamWriter(tokenFileFullPath)) { sw.WriteLine(Guid.NewGuid().ToString()); } } using (StreamReader sr = new StreamReader(tokenFileFullPath)) { settingsStore.serverHash = CalculateSHA256Hash(sr.ReadLine()); } string settingsFileFullPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), SETTINGS_FILE); if (!File.Exists(settingsFileFullPath)) { using (StreamWriter sw = new StreamWriter(settingsFileFullPath)) { sw.WriteLine("reporting = server.game.api.d-mp.org:9001"); sw.WriteLine("gameAddress = "); sw.WriteLine("banner = "); sw.WriteLine("homepage = "); sw.WriteLine("admin = "); sw.WriteLine("team = "); sw.WriteLine("location = "); sw.WriteLine("fixedIP = false"); sw.WriteLine("description = "); } } bool reloadSettings = false; using (StreamReader sr = new StreamReader(settingsFileFullPath)) { bool readingDescription = false; string currentLine; while ((currentLine = sr.ReadLine()) != null) { if (!readingDescription) { try { string key = currentLine.Substring(0, currentLine.IndexOf("=")).Trim(); string value = currentLine.Substring(currentLine.IndexOf("=") + 1).Trim(); switch (key) { case "reporting": { string address = value.Substring(0, value.LastIndexOf(":")); string port = value.Substring(value.LastIndexOf(":") + 1); IPAddress reportingIP; int reportingPort = 0; if (Int32.TryParse(port, out reportingPort)) { if (reportingPort > 0 && reportingPort < 65535) { //Try parsing the address directly before trying a DNS lookup if (!IPAddress.TryParse(address, out reportingIP)) { IPHostEntry entry = Dns.GetHostEntry(address); reportingIP = entry.AddressList[0]; } settingsStore.reportingEndpoint = new IPEndPoint(reportingIP, reportingPort); } } } break; case "gameAddress": settingsStore.gameAddress = value; break; case "banner": settingsStore.banner = value; break; case "homepage": settingsStore.homepage = value; break; case "admin": settingsStore.admin = value; break; case "team": settingsStore.team = value; break; case "location": settingsStore.location = value; break; case "fixedIP": settingsStore.fixedIP = (value == "true"); break; case "description": readingDescription = true; settingsStore.description = value; break; } } catch (Exception e) { DarkLog.Error("Error reading settings file, Exception " + e); } } else { //Reading description settingsStore.description += "\n" + currentLine; } } } if (reloadSettings) { //Load with the default settings if anything is incorrect. File.Delete(settingsFileFullPath); LoadSettings(); } loadedSettings = true; }
public void ReloadConfig(string input) { DarkLog.Normal("[ModdedVesselPositions] Reloading config..."); Config.SetupConfig(); DarkLog.Normal("[ModdedVesselPositions] Finished."); }
public static void HandleScreenshotLibrary(ClientObject client, byte[] messageData) { string screenshotDirectory = Path.Combine(Server.universeDirectory, "Screenshots"); if (Settings.settingsStore.screenshotDirectory != "") { if (Directory.Exists(Settings.settingsStore.screenshotDirectory)) { screenshotDirectory = Settings.settingsStore.screenshotDirectory; } } if (!Directory.Exists(screenshotDirectory)) { Directory.CreateDirectory(screenshotDirectory); } ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.SCREENSHOT_LIBRARY; using (MessageReader mr = new MessageReader(messageData)) { ScreenshotMessageType messageType = (ScreenshotMessageType)mr.Read <int>(); string fromPlayer = mr.Read <string>(); switch (messageType) { case ScreenshotMessageType.SCREENSHOT: { if (Settings.settingsStore.screenshotsPerPlayer > -1) { string playerScreenshotDirectory = Path.Combine(screenshotDirectory, fromPlayer); if (!Directory.Exists(playerScreenshotDirectory)) { Directory.CreateDirectory(playerScreenshotDirectory); } string screenshotFile = Path.Combine(playerScreenshotDirectory, DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ".png"); DarkLog.Debug("Saving screenshot from " + fromPlayer); byte[] screenshotData = mr.Read <byte[]>(); File.WriteAllBytes(screenshotFile, screenshotData); if (Settings.settingsStore.screenshotsPerPlayer != 0) { while (Directory.GetFiles(playerScreenshotDirectory).Length > Settings.settingsStore.screenshotsPerPlayer) { string[] currentFiles = Directory.GetFiles(playerScreenshotDirectory); string deleteFile = currentFiles[0]; //Find oldest file foreach (string testFile in currentFiles) { if (File.GetCreationTime(testFile) < File.GetCreationTime(deleteFile)) { deleteFile = testFile; } } File.Delete(deleteFile); DarkLog.Debug("Removing old screenshot " + Path.GetFileName(deleteFile)); } } //Notify players that aren't watching that there's a new screenshot availabe. This only works if there's a file available on the server. //The server does not keep the screenshots in memory. ServerMessage notifyMessage = new ServerMessage(); notifyMessage.type = ServerMessageType.SCREENSHOT_LIBRARY; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)ScreenshotMessageType.NOTIFY); mw.Write(fromPlayer); notifyMessage.data = mw.GetMessageBytes(); ClientHandler.SendToAll(client, notifyMessage, false); } } if (!playerUploadedScreenshotIndex.ContainsKey(fromPlayer)) { playerUploadedScreenshotIndex.Add(fromPlayer, 0); } else { playerUploadedScreenshotIndex[fromPlayer]++; } if (!playerDownloadedScreenshotIndex.ContainsKey(fromPlayer)) { playerDownloadedScreenshotIndex.Add(fromPlayer, new Dictionary <string, int>()); } if (!playerDownloadedScreenshotIndex[fromPlayer].ContainsKey(fromPlayer)) { playerDownloadedScreenshotIndex[fromPlayer].Add(fromPlayer, playerUploadedScreenshotIndex[fromPlayer]); } else { playerDownloadedScreenshotIndex[fromPlayer][fromPlayer] = playerUploadedScreenshotIndex[fromPlayer]; } newMessage.data = messageData; foreach (KeyValuePair <string, string> entry in playerWatchScreenshot) { if (entry.Key != fromPlayer) { if (entry.Value == fromPlayer && entry.Key != client.playerName) { ClientObject toClient = ClientHandler.GetClientByName(entry.Key); if (toClient != null && toClient != client) { if (!playerDownloadedScreenshotIndex.ContainsKey(entry.Key)) { playerDownloadedScreenshotIndex.Add(entry.Key, new Dictionary <string, int>()); } if (!playerDownloadedScreenshotIndex[entry.Key].ContainsKey(fromPlayer)) { playerDownloadedScreenshotIndex[entry.Key].Add(fromPlayer, 0); } playerDownloadedScreenshotIndex[entry.Key][fromPlayer] = playerUploadedScreenshotIndex[fromPlayer]; DarkLog.Debug("Sending screenshot from " + fromPlayer + " to " + entry.Key); using (MessageWriter mw = new MessageWriter()) { ServerMessage sendStartMessage = new ServerMessage(); sendStartMessage.type = ServerMessageType.SCREENSHOT_LIBRARY; mw.Write <int>((int)ScreenshotMessageType.SEND_START_NOTIFY); mw.Write <string>(fromPlayer); sendStartMessage.data = mw.GetMessageBytes(); ClientHandler.SendToClient(toClient, sendStartMessage, true); } ClientHandler.SendToClient(toClient, newMessage, false); } } } } } break; case ScreenshotMessageType.WATCH: { newMessage.data = messageData; string watchPlayer = mr.Read <string>(); if (watchPlayer == "") { if (playerWatchScreenshot.ContainsKey(fromPlayer)) { DarkLog.Debug(fromPlayer + " is no longer watching screenshots from " + playerWatchScreenshot[fromPlayer]); playerWatchScreenshot.Remove(fromPlayer); } } else { DarkLog.Debug(fromPlayer + " is watching screenshots from " + watchPlayer); playerWatchScreenshot[fromPlayer] = watchPlayer; if (!playerDownloadedScreenshotIndex.ContainsKey(fromPlayer)) { playerDownloadedScreenshotIndex.Add(fromPlayer, new Dictionary <string, int>()); } string watchPlayerScreenshotDirectory = Path.Combine(screenshotDirectory, watchPlayer); //Find latest screenshot string sendFile = null; if (Directory.Exists(watchPlayerScreenshotDirectory)) { string[] playerScreenshots = Directory.GetFiles(watchPlayerScreenshotDirectory); if (playerScreenshots.Length > 0) { sendFile = playerScreenshots[0]; foreach (string testFile in playerScreenshots) { if (File.GetCreationTime(testFile) > File.GetCreationTime(sendFile)) { sendFile = testFile; } } if (!playerUploadedScreenshotIndex.ContainsKey(watchPlayer)) { playerUploadedScreenshotIndex.Add(watchPlayer, 0); } } } //Send screenshot if needed if (sendFile != null) { bool sendScreenshot = false; if (!playerDownloadedScreenshotIndex[fromPlayer].ContainsKey(watchPlayer)) { playerDownloadedScreenshotIndex[fromPlayer].Add(watchPlayer, playerUploadedScreenshotIndex[watchPlayer]); sendScreenshot = true; } else { if (playerDownloadedScreenshotIndex[fromPlayer][watchPlayer] != playerUploadedScreenshotIndex[watchPlayer]) { sendScreenshot = true; playerDownloadedScreenshotIndex[fromPlayer][watchPlayer] = playerUploadedScreenshotIndex[watchPlayer]; } } if (sendScreenshot) { ServerMessage sendStartMessage = new ServerMessage(); sendStartMessage.type = ServerMessageType.SCREENSHOT_LIBRARY; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)ScreenshotMessageType.SEND_START_NOTIFY); mw.Write <string>(fromPlayer); sendStartMessage.data = mw.GetMessageBytes(); } ServerMessage screenshotMessage = new ServerMessage(); screenshotMessage.type = ServerMessageType.SCREENSHOT_LIBRARY; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)ScreenshotMessageType.SCREENSHOT); mw.Write <string>(watchPlayer); mw.Write <byte[]>(File.ReadAllBytes(sendFile)); screenshotMessage.data = mw.GetMessageBytes(); } ClientObject toClient = ClientHandler.GetClientByName(fromPlayer); if (toClient != null) { DarkLog.Debug("Sending saved screenshot from " + watchPlayer + " to " + fromPlayer); ClientHandler.SendToClient(toClient, sendStartMessage, false); ClientHandler.SendToClient(toClient, screenshotMessage, false); } } } } //Relay the message ClientHandler.SendToAll(client, newMessage, false); } break; } } }
public static void HandleHandshakeResponse(ClientObject client, byte[] messageData) { int protocolVersion; string playerName = ""; string playerPublicKey; byte[] playerChallangeSignature; string clientVersion = ""; string reason = ""; Regex regex = new Regex(@"[\""<>|$]"); // Regex to detect quotation marks, and other illegal characters //0 - Success HandshakeReply handshakeReponse = HandshakeReply.HANDSHOOK_SUCCESSFULLY; try { using (MessageReader mr = new MessageReader(messageData)) { protocolVersion = mr.Read <int>(); playerName = mr.Read <string>(); playerPublicKey = mr.Read <string>(); playerChallangeSignature = mr.Read <byte[]>(); clientVersion = mr.Read <string>(); try { client.compressionEnabled = mr.Read <bool>(); } catch { //This is safe to ignore. We want to tell people about version mismatches still. client.compressionEnabled = false; } } } catch (Exception e) { DarkLog.Debug("Error in HANDSHAKE_REQUEST from " + client.playerName + ": " + e); SendHandshakeReply(client, HandshakeReply.MALFORMED_HANDSHAKE, "Malformed handshake"); return; } if (regex.IsMatch(playerName)) { // Invalid username handshakeReponse = HandshakeReply.INVALID_PLAYERNAME; reason = "Invalid username"; } if (playerName.Contains("/") || playerName.Contains(@"\") || playerName.Contains("\n") || playerName.Contains("\r")) { handshakeReponse = HandshakeReply.INVALID_PLAYERNAME; reason = "Invalid username"; } if (protocolVersion != Common.PROTOCOL_VERSION) { //Protocol mismatch handshakeReponse = HandshakeReply.PROTOCOL_MISMATCH; reason = "Protocol mismatch"; } if (handshakeReponse == HandshakeReply.HANDSHOOK_SUCCESSFULLY) { //Check client isn't already connected ClientObject testClient = ClientHandler.GetClientByName(playerName); if (testClient != null) { Messages.Heartbeat.Send(testClient); Thread.Sleep(1000); } if (ClientHandler.ClientConnected(testClient)) { handshakeReponse = HandshakeReply.ALREADY_CONNECTED; reason = "Client already connected"; } } if (handshakeReponse == HandshakeReply.HANDSHOOK_SUCCESSFULLY) { bool reserveKick = false; //Check the client isn't using a reserved name if (playerName == "Initial") { reserveKick = true; } if (playerName == Settings.settingsStore.consoleIdentifier) { reserveKick = true; } if (reserveKick) { handshakeReponse = HandshakeReply.RESERVED_NAME; reason = "Kicked for using a reserved name"; } } if (handshakeReponse == HandshakeReply.HANDSHOOK_SUCCESSFULLY) { //Check the client matches any database entry string storedPlayerFile = Path.Combine(Server.universeDirectory, "Players", playerName + ".txt"); string storedPlayerPublicKey = ""; if (File.Exists(storedPlayerFile)) { storedPlayerPublicKey = File.ReadAllText(storedPlayerFile); if (playerPublicKey != storedPlayerPublicKey) { handshakeReponse = HandshakeReply.INVALID_KEY; reason = "Invalid key for user"; } else { using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024)) { rsa.PersistKeyInCsp = false; rsa.FromXmlString(playerPublicKey); bool result = rsa.VerifyData(client.challange, CryptoConfig.CreateFromName("SHA256"), playerChallangeSignature); if (!result) { handshakeReponse = HandshakeReply.INVALID_KEY; reason = "Public/private key mismatch"; } } } } else { try { File.WriteAllText(storedPlayerFile, playerPublicKey); DarkLog.Debug("Client " + playerName + " registered!"); } catch { handshakeReponse = HandshakeReply.INVALID_PLAYERNAME; reason = "Invalid username"; } } } client.playerName = playerName; client.publicKey = playerPublicKey; client.clientVersion = clientVersion; if (handshakeReponse == HandshakeReply.HANDSHOOK_SUCCESSFULLY) { if (BanSystem.fetch.IsPlayerNameBanned(client.playerName) || BanSystem.fetch.IsIPBanned(client.ipAddress) || BanSystem.fetch.IsPublicKeyBanned(client.publicKey)) { handshakeReponse = HandshakeReply.PLAYER_BANNED; reason = "You were banned from the server!"; } } if (handshakeReponse == HandshakeReply.HANDSHOOK_SUCCESSFULLY) { if (ClientHandler.GetActiveClientCount() >= Settings.settingsStore.maxPlayers) { handshakeReponse = HandshakeReply.SERVER_FULL; reason = "Server is full"; } } if (handshakeReponse == HandshakeReply.HANDSHOOK_SUCCESSFULLY) { if (Settings.settingsStore.whitelisted && !WhitelistSystem.fetch.IsWhitelisted(client.playerName)) { handshakeReponse = HandshakeReply.NOT_WHITELISTED; reason = "You are not on the whitelist"; } } if (handshakeReponse == HandshakeReply.HANDSHOOK_SUCCESSFULLY) { client.authenticated = true; string devClientVersion = ""; DMPPluginHandler.FireOnClientAuthenticated(client); if (client.clientVersion.Length == 40) { devClientVersion = client.clientVersion.Substring(0, 7); } else { devClientVersion = client.clientVersion; } DarkLog.Normal("Client " + playerName + " handshook successfully, version: " + devClientVersion); if (!Directory.Exists(Path.Combine(Server.universeDirectory, "Scenarios", client.playerName))) { Directory.CreateDirectory(Path.Combine(Server.universeDirectory, "Scenarios", client.playerName)); foreach (string file in Directory.GetFiles(Path.Combine(Server.universeDirectory, "Scenarios", "Initial"))) { File.Copy(file, Path.Combine(Server.universeDirectory, "Scenarios", playerName, Path.GetFileName(file))); } } SendHandshakeReply(client, handshakeReponse, "success"); Server.playerCount = ClientHandler.GetActiveClientCount(); Server.players = ClientHandler.GetActivePlayerNames(); DarkLog.Debug("Online players is now: " + Server.playerCount + ", connected: " + ClientHandler.GetClients().Length); } else { DarkLog.Normal("Client " + playerName + " failed to handshake: " + reason); SendHandshakeReply(client, handshakeReponse, reason); } }
public static void HandleFlagSync(ClientObject client, byte[] messageData) { string flagPath = Path.Combine(Server.universeDirectory, "Flags"); using (MessageReader mr = new MessageReader(messageData)) { FlagMessageType messageType = (FlagMessageType)mr.Read <int>(); string playerName = mr.Read <string>(); if (playerName != client.playerName) { Messages.ConnectionEnd.SendConnectionEnd(client, "Kicked for sending a flag for another player"); return; } switch (messageType) { case FlagMessageType.LIST: { //Send the list back List <string> serverFlagFileNames = new List <string>(); List <string> serverFlagOwners = new List <string>(); List <string> serverFlagShaSums = new List <string>(); string[] clientFlags = mr.Read <string[]>(); string[] clientFlagShas = mr.Read <string[]>(); string[] serverFlags = Directory.GetFiles(flagPath, "*", SearchOption.AllDirectories); foreach (string serverFlag in serverFlags) { string trimmedName = Path.GetFileName(serverFlag); string flagOwnerPath = Path.GetDirectoryName(serverFlag); string flagOwner = flagOwnerPath.Substring(Path.GetDirectoryName(flagOwnerPath).Length + 1); bool isMatched = false; bool shaDifferent = false; for (int i = 0; i < clientFlags.Length; i++) { if (clientFlags[i].ToLower() == trimmedName.ToLower()) { isMatched = true; shaDifferent = (Common.CalculateSHA256Hash(serverFlag) != clientFlagShas[i]); } } if (!isMatched || shaDifferent) { if (flagOwner == client.playerName) { DarkLog.Debug("Deleting flag " + trimmedName); File.Delete(serverFlag); ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.FLAG_SYNC; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)FlagMessageType.DELETE_FILE); mw.Write <string>(trimmedName); newMessage.data = mw.GetMessageBytes(); ClientHandler.SendToAll(client, newMessage, false); } if (Directory.GetFiles(flagOwnerPath).Length == 0) { Directory.Delete(flagOwnerPath); } } else { DarkLog.Debug("Sending flag " + serverFlag + " from " + flagOwner + " to " + client.playerName); ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.FLAG_SYNC; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)FlagMessageType.FLAG_DATA); mw.Write <string>(flagOwner); mw.Write <string>(trimmedName); mw.Write <byte[]>(File.ReadAllBytes(serverFlag)); newMessage.data = mw.GetMessageBytes(); ClientHandler.SendToClient(client, newMessage, false); } } } //Don't tell the client we have a different copy of the flag so it is reuploaded if (File.Exists(serverFlag)) { serverFlagFileNames.Add(trimmedName); serverFlagOwners.Add(flagOwner); serverFlagShaSums.Add(Common.CalculateSHA256Hash(serverFlag)); } } ServerMessage listMessage = new ServerMessage(); listMessage.type = ServerMessageType.FLAG_SYNC; using (MessageWriter mw2 = new MessageWriter()) { mw2.Write <int>((int)FlagMessageType.LIST); mw2.Write <string[]>(serverFlagFileNames.ToArray()); mw2.Write <string[]>(serverFlagOwners.ToArray()); mw2.Write <string[]>(serverFlagShaSums.ToArray()); listMessage.data = mw2.GetMessageBytes(); } ClientHandler.SendToClient(client, listMessage, false); } break; case FlagMessageType.DELETE_FILE: { string flagName = mr.Read <string>(); string playerFlagPath = Path.Combine(flagPath, client.playerName); if (Directory.Exists(playerFlagPath)) { string flagFile = Path.Combine(playerFlagPath, flagName); if (File.Exists(flagFile)) { File.Delete(flagFile); } if (Directory.GetFiles(playerFlagPath).Length == 0) { Directory.Delete(playerFlagPath); } } ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.FLAG_SYNC; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)FlagMessageType.DELETE_FILE); mw.Write <string>(flagName); newMessage.data = mw.GetMessageBytes(); } ClientHandler.SendToAll(client, newMessage, false); } break; case FlagMessageType.UPLOAD_FILE: { string flagName = mr.Read <string>(); byte[] flagData = mr.Read <byte[]>(); string playerFlagPath = Path.Combine(flagPath, client.playerName); if (!Directory.Exists(playerFlagPath)) { Directory.CreateDirectory(playerFlagPath); } DarkLog.Debug("Saving flag " + flagName + " from " + client.playerName); File.WriteAllBytes(Path.Combine(playerFlagPath, flagName), flagData); ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.FLAG_SYNC; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)FlagMessageType.FLAG_DATA); mw.Write <string>(client.playerName); mw.Write <string>(flagName); mw.Write <byte[]>(flagData); } ClientHandler.SendToAll(client, newMessage, false); } break; } } }
public static void HandleModpackMessage(ClientObject client, byte[] messageData) { if (messageData == null || messageData.Length == 0) { ConnectionEnd.SendConnectionEnd(client, "Invalid mod control message from client"); return; } if (!client.authenticated) { ConnectionEnd.SendConnectionEnd(client, "Unauthenticated client tried to send modpack message"); } using (MessageReader mr = new MessageReader(messageData)) { ModpackDataMessageType type = (ModpackDataMessageType)mr.Read <int>(); switch (type) { case ModpackDataMessageType.CKAN: { if (!DarkMultiPlayerServer.AdminSystem.fetch.IsAdmin(client.playerName)) { ConnectionEnd.SendConnectionEnd(client, "Kicked from the server, non admin " + client.playerName + " tried to upload modpack"); return; } if (Settings.settingsStore.modpackMode != ModpackMode.CKAN) { ConnectionEnd.SendConnectionEnd(client, "Please set server modpackMode to CKAN"); return; } byte[] fileBytes = mr.Read <byte[]>(); ModpackSystem.fetch.SaveCKANData(fileBytes); } break; case ModpackDataMessageType.MOD_LIST: { if (!DarkMultiPlayerServer.AdminSystem.fetch.IsAdmin(client.playerName)) { ConnectionEnd.SendConnectionEnd(client, "Kicked from the server, non admin " + client.playerName + " tried to upload modpack"); return; } if (Settings.settingsStore.modpackMode != ModpackMode.GAMEDATA) { ConnectionEnd.SendConnectionEnd(client, "Please set server modpackMode to GAMEDATA"); return; } DarkLog.Normal("Modpack uploaded from " + client.playerName); string[] files = mr.Read <string[]>(); string[] sha = mr.Read <string[]>(); ModpackSystem.fetch.HandleNewGameData(files, sha, client); } break; case ModpackDataMessageType.REQUEST_OBJECT: { string[] sha256sums = mr.Read <string[]>(); ModpackSystem.fetch.HandleSendList(client, sha256sums); } break; case ModpackDataMessageType.RESPONSE_OBJECT: { if (!DarkMultiPlayerServer.AdminSystem.fetch.IsAdmin(client.playerName)) { ConnectionEnd.SendConnectionEnd(client, "Kicked from the server, non admin " + client.playerName + " tried to upload modpack"); return; } string sha256sum = mr.Read <string>(); if (mr.Read <bool>()) { byte[] fileBytes = mr.Read <byte[]>(); DarkLog.Debug("Received object: " + sha256sum); ModpackSystem.fetch.SaveModObject(fileBytes, sha256sum); } else { DarkLog.Normal("Failed to recieve: " + sha256sum); } } break; case ModpackDataMessageType.MOD_DONE: { if (!DarkMultiPlayerServer.AdminSystem.fetch.IsAdmin(client.playerName)) { ConnectionEnd.SendConnectionEnd(client, "Kicked from the server, non admin " + client.playerName + " tried to upload modpack"); return; } //Has gamedata upload if (mr.Read <bool>()) { DarkLog.Debug("Mod control file updated"); byte[] newModControl = mr.Read <byte[]>(); File.WriteAllBytes(Server.modFile, newModControl); } ModpackSystem.fetch.HandleModDone(); } break; } } }
public static void HandleWarpControl(ClientObject client, byte[] messageData) { ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.WARP_CONTROL; newMessage.data = messageData; using (MessageReader mr = new MessageReader(messageData)) { WarpMessageType warpType = (WarpMessageType)mr.Read <int>(); string fromPlayer = mr.Read <string>(); if (fromPlayer == client.playerName) { if (warpType == WarpMessageType.NEW_SUBSPACE) { int newSubspaceID = mr.Read <int>(); if (subspaces.ContainsKey(newSubspaceID)) { DarkLog.Debug("Kicked for trying to create an existing subspace"); Messages.ConnectionEnd.SendConnectionEnd(client, "Kicked for trying to create an existing subspace"); return; } else { Subspace newSubspace = new Subspace(); newSubspace.serverClock = mr.Read <long>(); newSubspace.planetTime = mr.Read <double>(); newSubspace.subspaceSpeed = mr.Read <float>(); subspaces.Add(newSubspaceID, newSubspace); client.subspace = newSubspaceID; SaveLatestSubspace(); } } if (warpType == WarpMessageType.CHANGE_SUBSPACE) { client.subspace = mr.Read <int>(); } if (warpType == WarpMessageType.REPORT_RATE) { int reportedSubspace = mr.Read <int>(); if (client.subspace != reportedSubspace) { DarkLog.Debug("Warning, setting client " + client.playerName + " to subspace " + client.subspace); client.subspace = reportedSubspace; } float newSubspaceRate = mr.Read <float>(); client.subspaceRate = newSubspaceRate; foreach (ClientObject otherClient in ClientHandler.GetClients()) { if (otherClient.authenticated && otherClient.subspace == reportedSubspace) { if (newSubspaceRate > otherClient.subspaceRate) { newSubspaceRate = otherClient.subspaceRate; } } } if (newSubspaceRate < 0.3f) { newSubspaceRate = 0.3f; } if (newSubspaceRate > 1f) { newSubspaceRate = 1f; } //Relock the subspace if the rate is more than 3% out of the average if (Math.Abs(subspaces[reportedSubspace].subspaceSpeed - newSubspaceRate) > 0.03f) { UpdateSubspace(reportedSubspace); subspaces[reportedSubspace].subspaceSpeed = newSubspaceRate; ServerMessage relockMessage = new ServerMessage(); relockMessage.type = ServerMessageType.WARP_CONTROL; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)WarpMessageType.RELOCK_SUBSPACE); mw.Write <string>(Settings.settingsStore.consoleIdentifier); mw.Write <int>(reportedSubspace); mw.Write <long>(subspaces[reportedSubspace].serverClock); mw.Write <double>(subspaces[reportedSubspace].planetTime); mw.Write <float>(subspaces[reportedSubspace].subspaceSpeed); relockMessage.data = mw.GetMessageBytes(); } SaveLatestSubspace(); //DarkLog.Debug("Subspace " + client.subspace + " locked to " + newSubspaceRate + "x speed."); ClientHandler.SendToClient(client, relockMessage, true); ClientHandler.SendToAll(client, relockMessage, true); } } } else { DarkLog.Debug(client.playerName + " tried to send an update for " + fromPlayer + ", kicking."); Messages.ConnectionEnd.SendConnectionEnd(client, "Kicked for sending an update for another player"); return; } } ClientHandler.SendToAll(client, newMessage, true); }
public static void HandleLockSystemMessage(ClientObject client, byte[] messageData) { using (MessageReader mr = new MessageReader(messageData)) { //All of the messages need replies, let's create a message for it. ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.LOCK_SYSTEM; //Read the lock-system message type LockMessageType lockMessageType = (LockMessageType)mr.Read <int>(); switch (lockMessageType) { case LockMessageType.ACQUIRE: { string playerName = mr.Read <string>(); string lockName = mr.Read <string>(); bool force = mr.Read <bool>(); if (playerName != client.playerName) { Messages.ConnectionEnd.SendConnectionEnd(client, "Kicked for sending a lock message for another player"); } bool lockResult = DarkMultiPlayerServer.LockSystem.fetch.AcquireLock(lockName, playerName, force); using (MessageWriter mw = new MessageWriter()) { mw.Write((int)LockMessageType.ACQUIRE); mw.Write(playerName); mw.Write(lockName); mw.Write(lockResult); newMessage.data = mw.GetMessageBytes(); } //Send to all clients ClientHandler.SendToAll(null, newMessage, true); if (lockResult) { DarkLog.Debug(playerName + " acquired lock " + lockName); } else { DarkLog.Debug(playerName + " failed to acquire lock " + lockName); } } break; case LockMessageType.RELEASE: { string playerName = mr.Read <string>(); string lockName = mr.Read <string>(); if (playerName != client.playerName) { Messages.ConnectionEnd.SendConnectionEnd(client, "Kicked for sending a lock message for another player"); } bool lockResult = DarkMultiPlayerServer.LockSystem.fetch.ReleaseLock(lockName, playerName); if (!lockResult) { Messages.ConnectionEnd.SendConnectionEnd(client, "Kicked for releasing a lock you do not own"); } else { using (MessageWriter mw = new MessageWriter()) { mw.Write((int)LockMessageType.RELEASE); mw.Write(playerName); mw.Write(lockName); mw.Write(lockResult); newMessage.data = mw.GetMessageBytes(); } //Send to all clients ClientHandler.SendToAll(null, newMessage, true); } if (lockResult) { DarkLog.Debug(playerName + " released lock " + lockName); } else { DarkLog.Debug(playerName + " failed to release lock " + lockName); } } break; } } }
private void LoadSettings() { string settingsFileFullPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), SETTINGS_FILE); if (!File.Exists(settingsFileFullPath)) { using (StreamWriter sw = new StreamWriter(settingsFileFullPath)) { sw.WriteLine("sqlServer = localhost:3306"); sw.WriteLine("dbName = ksp"); sw.WriteLine("dbUsername = kspgs"); sw.WriteLine("dbPassword = abc123"); sw.WriteLine("tableName = tbl-player-sessions"); } } using (StreamReader sr = new StreamReader(settingsFileFullPath)) { string currentLine; while ((currentLine = sr.ReadLine()) != null) { try { string key = currentLine.Substring(0, currentLine.IndexOf("=")).Trim(); string value = currentLine.Substring(currentLine.IndexOf("=") + 1).Trim(); switch (key) { case "sqlServer": { string address = value.Substring(0, value.LastIndexOf(":")); string port = value.Substring(value.LastIndexOf(":") + 1); settingsStore.sqlIP = address; settingsStore.sqlPort = port; } break; case "dbName": settingsStore.dbName = value; break; case "dbUsername": settingsStore.dbUsername = value; break; case "dbPassword": settingsStore.dbPassword = value; break; case "tableName": settingsStore.tableName = value; break; } } catch (Exception e) { DarkLog.Error("Error reading settings file, Exception " + e); File.Delete(settingsFileFullPath); LoadSettings(); } } } }
public static void HandleCraftLibrary(ClientObject client, byte[] messageData) { using (MessageReader mr = new MessageReader(messageData)) { CraftMessageType craftMessageType = (CraftMessageType)mr.Read <int>(); string fromPlayer = mr.Read <string>(); if (fromPlayer != client.playerName) { Messages.ConnectionEnd.SendConnectionEnd(client, "Kicked for sending an craft library message for another player"); return; } switch (craftMessageType) { case CraftMessageType.UPLOAD_FILE: { CraftType uploadType = (CraftType)mr.Read <int>(); string uploadName = mr.Read <string>(); byte[] uploadData = mr.Read <byte[]>(); string playerPath = Path.Combine(Path.Combine(Server.universeDirectory, "Crafts"), fromPlayer); if (!Directory.Exists(playerPath)) { Directory.CreateDirectory(playerPath); } string typePath = Path.Combine(playerPath, uploadType.ToString()); if (!Directory.Exists(typePath)) { Directory.CreateDirectory(typePath); } string craftFile = Path.Combine(typePath, uploadName + ".craft"); File.WriteAllBytes(craftFile, uploadData); DarkLog.Debug("Saving " + uploadName + ", type: " + uploadType.ToString() + " from " + fromPlayer); using (MessageWriter mw = new MessageWriter()) { ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.CRAFT_LIBRARY; mw.Write <int>((int)CraftMessageType.ADD_FILE); mw.Write <string>(fromPlayer); mw.Write <int>((int)uploadType); mw.Write <string>(uploadName); newMessage.data = mw.GetMessageBytes(); ClientHandler.SendToAll(client, newMessage, false); } } break; case CraftMessageType.REQUEST_FILE: { string craftOwner = mr.Read <string>(); CraftType requestedType = (CraftType)mr.Read <int>(); bool hasCraft = false; string requestedName = mr.Read <string>(); string playerPath = Path.Combine(Path.Combine(Server.universeDirectory, "Crafts"), craftOwner); string typePath = Path.Combine(playerPath, requestedType.ToString()); string craftFile = Path.Combine(typePath, requestedName + ".craft"); if (Directory.Exists(playerPath)) { if (Directory.Exists(typePath)) { if (File.Exists(craftFile)) { hasCraft = true; } } } ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.CRAFT_LIBRARY; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)CraftMessageType.RESPOND_FILE); mw.Write <string>(craftOwner); mw.Write <int>((int)requestedType); mw.Write <string>(requestedName); mw.Write <bool>(hasCraft); if (hasCraft) { mw.Write <byte[]>(File.ReadAllBytes(craftFile)); DarkLog.Debug("Sending " + fromPlayer + " " + requestedName + " from " + craftOwner); } newMessage.data = mw.GetMessageBytes(); } ClientHandler.SendToClient(client, newMessage, false); } break; case CraftMessageType.DELETE_FILE: { CraftType craftType = (CraftType)mr.Read <int>(); string craftName = mr.Read <string>(); string playerPath = Path.Combine(Path.Combine(Server.universeDirectory, "Crafts"), fromPlayer); string typePath = Path.Combine(playerPath, craftType.ToString()); string craftFile = Path.Combine(typePath, craftName + ".craft"); if (Directory.Exists(playerPath)) { if (Directory.Exists(typePath)) { if (File.Exists(craftFile)) { File.Delete(craftFile); DarkLog.Debug("Removing " + craftName + ", type: " + craftType.ToString() + " from " + fromPlayer); } } } if (Directory.Exists(playerPath)) { if (Directory.GetFiles(typePath).Length == 0) { Directory.Delete(typePath); } } if (Directory.GetDirectories(playerPath).Length == 0) { Directory.Delete(playerPath); } //Relay the delete message to other clients ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.CRAFT_LIBRARY; newMessage.data = messageData; ClientHandler.SendToAll(client, newMessage, false); } break; } } }
private void btnGo_Click(object sender, EventArgs e) { DarkLog.WriteLine(txtMessage.Text); }
public static void HandleChatMessage(ClientObject client, byte[] messageData) { ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.CHAT_MESSAGE; newMessage.data = messageData; using (MessageReader mr = new MessageReader(messageData)) { ChatMessageType messageType = (ChatMessageType)mr.Read <int>(); string fromPlayer = mr.Read <string>(); if (fromPlayer != client.playerName) { Messages.ConnectionEnd.SendConnectionEnd(client, "Kicked for sending a chat message for another player"); return; } switch (messageType) { case ChatMessageType.JOIN: { string joinChannel = mr.Read <string>(); if (!playerChatChannels.ContainsKey(fromPlayer)) { playerChatChannels.Add(fromPlayer, new List <string>()); } if (!playerChatChannels[fromPlayer].Contains(joinChannel)) { playerChatChannels[fromPlayer].Add(joinChannel); } DarkLog.Debug(fromPlayer + " joined channel: " + joinChannel); } ClientHandler.SendToAll(client, newMessage, true); break; case ChatMessageType.LEAVE: { string leaveChannel = mr.Read <string>(); if (playerChatChannels.ContainsKey(fromPlayer)) { if (playerChatChannels[fromPlayer].Contains(leaveChannel)) { playerChatChannels[fromPlayer].Remove(leaveChannel); } if (playerChatChannels[fromPlayer].Count == 0) { playerChatChannels.Remove(fromPlayer); } } DarkLog.Debug(fromPlayer + " left channel: " + leaveChannel); } ClientHandler.SendToAll(client, newMessage, true); break; case ChatMessageType.CHANNEL_MESSAGE: { string channel = mr.Read <string>(); string message = mr.Read <string>(); if (channel != "") { foreach (KeyValuePair <string, List <string> > playerEntry in playerChatChannels) { if (playerEntry.Value.Contains(channel)) { ClientObject findClient = ClientHandler.GetClientByName(playerEntry.Key); if (findClient != null) { ClientHandler.SendToClient(findClient, newMessage, true); } } } DarkLog.ChatMessage(fromPlayer + " -> #" + channel + ": " + message); } else { ClientHandler.SendToClient(client, newMessage, true); ClientHandler.SendToAll(client, newMessage, true); DarkLog.ChatMessage(fromPlayer + " -> #Global: " + message); } } break; case ChatMessageType.PRIVATE_MESSAGE: { string toPlayer = mr.Read <string>(); string message = mr.Read <string>(); if (toPlayer != Settings.settingsStore.consoleIdentifier) { ClientObject findClient = ClientHandler.GetClientByName(toPlayer); if (findClient != null) { ClientHandler.SendToClient(client, newMessage, true); ClientHandler.SendToClient(findClient, newMessage, true); DarkLog.ChatMessage(fromPlayer + " -> @" + toPlayer + ": " + message); } { DarkLog.ChatMessage(fromPlayer + " -X-> @" + toPlayer + ": " + message); } } else { ClientHandler.SendToClient(client, newMessage, true); DarkLog.ChatMessage(fromPlayer + " -> @" + toPlayer + ": " + message); } } break; case ChatMessageType.CONSOLE_MESSAGE: { string message = mr.Read <string>(); if (client.authenticated && DarkMultiPlayerServer.AdminSystem.fetch.IsAdmin(client.playerName)) { CommandHandler.HandleServerInput(message); } else { Messages.ConnectionEnd.SendConnectionEnd(client, "Kicked for sending a console command as a non-admin player."); } } break; } } }
public static void SendCraftList(ClientObject client) { int numberOfCrafts = 0; string craftDirectory = Path.Combine(Server.universeDirectory, "Crafts"); if (!Directory.Exists(craftDirectory)) { Directory.CreateDirectory(craftDirectory); } string[] players = Directory.GetDirectories(craftDirectory); for (int i = 0; i < players.Length; i++) { players[i] = players[i].Substring(players[i].LastIndexOf(Path.DirectorySeparatorChar) + 1); } ServerMessage newMessage = new ServerMessage(); newMessage.type = ServerMessageType.CRAFT_LIBRARY; using (MessageWriter mw = new MessageWriter()) { mw.Write <int>((int)CraftMessageType.LIST); mw.Write <string[]>(players); foreach (string player in players) { string playerPath = Path.Combine(craftDirectory, player); string vabPath = Path.Combine(playerPath, "VAB"); string sphPath = Path.Combine(playerPath, "SPH"); string subassemblyPath = Path.Combine(playerPath, "SUBASSEMBLY"); bool vabExists = Directory.Exists(vabPath); bool sphExists = Directory.Exists(sphPath); bool subassemblyExists = Directory.Exists(subassemblyPath); mw.Write <bool>(vabExists); mw.Write <bool>(sphExists); mw.Write <bool>(subassemblyExists); if (vabExists) { string[] vabCraftNames = Directory.GetFiles(vabPath); for (int i = 0; i < vabCraftNames.Length; i++) { //We only want the craft names vabCraftNames[i] = Path.GetFileNameWithoutExtension(vabCraftNames[i]); numberOfCrafts++; } mw.Write <string[]>(vabCraftNames); } if (sphExists) { string[] sphCraftNames = Directory.GetFiles(sphPath); for (int i = 0; i < sphCraftNames.Length; i++) { //We only want the craft names sphCraftNames[i] = Path.GetFileNameWithoutExtension(sphCraftNames[i]); numberOfCrafts++; } mw.Write <string[]>(sphCraftNames); } if (subassemblyExists) { string[] subassemblyCraftNames = Directory.GetFiles(subassemblyPath); for (int i = 0; i < subassemblyCraftNames.Length; i++) { //We only want the craft names subassemblyCraftNames[i] = Path.GetFileNameWithoutExtension(subassemblyCraftNames[i]); numberOfCrafts++; } mw.Write <string[]>(subassemblyCraftNames); } } newMessage.data = mw.GetMessageBytes(); ClientHandler.SendToClient(client, newMessage, true); DarkLog.Debug("Sending " + client.playerName + " " + numberOfCrafts + " craft library entries"); } }
public static void HandleVesselProto(ClientObject client, byte[] messageData) { //TODO: Relay the message as is so we can optimize it //Send vessel using (MessageReader mr = new MessageReader(messageData)) { //Don't care about planet time double planetTime = mr.Read <double>(); string vesselGuid = mr.Read <string>(); bool isDockingUpdate = mr.Read <bool>(); bool isFlyingUpdate = mr.Read <bool>(); byte[] possibleCompressedBytes = mr.Read <byte[]>(); byte[] vesselData = Compression.DecompressIfNeeded(possibleCompressedBytes); if (isFlyingUpdate) { DarkLog.Debug("Relaying FLYING vessel " + vesselGuid + " from " + client.playerName); } else { if (!isDockingUpdate) { DarkLog.Debug("Saving vessel " + vesselGuid + " from " + client.playerName); } else { DarkLog.Debug("Saving DOCKED vessel " + vesselGuid + " from " + client.playerName); } lock (Server.universeSizeLock) { File.WriteAllBytes(Path.Combine(Server.universeDirectory, "Vessels", vesselGuid + ".txt"), vesselData); } } ServerMessage newCompressedMessage = null; ServerMessage newDecompressedMessage = null; if (Compression.BytesAreCompressed(possibleCompressedBytes)) { //Relay compressed message newCompressedMessage = new ServerMessage(); newCompressedMessage.type = ServerMessageType.VESSEL_PROTO; newCompressedMessage.data = messageData; //Build decompressed message. newDecompressedMessage = new ServerMessage(); newDecompressedMessage.type = ServerMessageType.VESSEL_PROTO; using (MessageWriter mw = new MessageWriter()) { mw.Write <double>(planetTime); mw.Write <string>(vesselGuid); mw.Write <bool>(isDockingUpdate); mw.Write <bool>(isFlyingUpdate); mw.Write <byte[]>(Compression.AddCompressionHeader(vesselData, false)); newDecompressedMessage.data = mw.GetMessageBytes(); } } else { //Relay decompressed message newDecompressedMessage = new ServerMessage(); newDecompressedMessage.type = ServerMessageType.VESSEL_PROTO; newDecompressedMessage.data = messageData; //Build compressed message if the message is over the threshold. //This should only happen if the client has disabled compression. if (vesselData.Length > Common.COMPRESSION_THRESHOLD) { newCompressedMessage = new ServerMessage(); newCompressedMessage.type = ServerMessageType.VESSEL_PROTO; using (MessageWriter mw = new MessageWriter()) { mw.Write <double>(planetTime); mw.Write <string>(vesselGuid); mw.Write <bool>(isDockingUpdate); mw.Write <bool>(isFlyingUpdate); mw.Write <byte[]>(Compression.CompressIfNeeded(vesselData)); newCompressedMessage.data = mw.GetMessageBytes(); } } } ClientHandler.SendToAllAutoCompressed(client, newCompressedMessage, newDecompressedMessage, false); } }