protected override void enqueueTextMessage(InTextMessage message, bool to_plugin = true) { //Dequeue an old text message if there are a lot of messages backed up if (textMessageQueue.Count >= MAX_TEXT_MESSAGE_QUEUE) { InTextMessage old_message; textMessageQueue.TryDequeue(out old_message); } textMessageQueue.Enqueue(message); base.enqueueTextMessage(message, to_plugin); }
protected void handleInteropMessage(KLFCommon.PluginInteropMessageID id, byte[] data) { switch (id) { case KLFCommon.PluginInteropMessageID.CHAT_SEND: if (data != null) { String line = encoder.GetString(data); InTextMessage message = new InTextMessage(); message.fromServer = false; message.message = "[" + clientSettings.username + "] " + line; enqueueTextMessage(message, false); handleChatInput(line); } break; case KLFCommon.PluginInteropMessageID.PLUGIN_DATA: String new_watch_player_name = String.Empty; if (data != null && data.Length >= 9) { UnicodeEncoding encoder = new UnicodeEncoding(); int index = 0; //Read current activity status bool in_flight = data[index] != 0; index++; //Read current game title int current_game_title_length = KLFCommon.intFromBytes(data, index); index += 4; currentGameTitle = encoder.GetString(data, index, current_game_title_length); index += current_game_title_length; //Send the activity status to the server if (in_flight) sendMessageTCP(KLFCommon.ClientMessageID.ACTIVITY_UPDATE_IN_FLIGHT, null); else sendMessageTCP(KLFCommon.ClientMessageID.ACTIVITY_UPDATE_IN_GAME, null); } break; case KLFCommon.PluginInteropMessageID.PRIMARY_PLUGIN_UPDATE: sendPluginUpdate(data, true); break; case KLFCommon.PluginInteropMessageID.SECONDARY_PLUGIN_UPDATE: sendPluginUpdate(data, false); break; case KLFCommon.PluginInteropMessageID.SCREENSHOT_SHARE: if (data != null) { lock (screenshotOutLock) { queuedOutScreenshot = data; } } break; case KLFCommon.PluginInteropMessageID.SCREENSHOT_WATCH_UPDATE: if (data != null && data.Length >= 8) { int index = KLFCommon.intFromBytes(data, 0); int current_index = KLFCommon.intFromBytes(data, 4); String name = encoder.GetString(data, 8, data.Length - 8); if (watchPlayerName != name || watchPlayerIndex != index) { watchPlayerName = name; watchPlayerIndex = index; //Look in the screenshot cache for the requested screenshot Screenshot cached = getCachedScreenshot(watchPlayerIndex, watchPlayerName); if (cached != null) sendClientInteropMessage(KLFCommon.ClientInteropMessageID.SCREENSHOT_RECEIVE, cached.toByteArray()); sendScreenshotWatchPlayerMessage((cached == null), current_index, watchPlayerIndex, watchPlayerName); } } break; } }
protected void handleMessage(KLFCommon.ServerMessageID id, byte[] data) { switch (id) { case KLFCommon.ServerMessageID.HANDSHAKE: Int32 protocol_version = KLFCommon.intFromBytes(data); if (data.Length >= 8) { Int32 server_version_length = KLFCommon.intFromBytes(data, 4); if (data.Length >= 12 + server_version_length) { String server_version = encoder.GetString(data, 8, server_version_length); clientID = KLFCommon.intFromBytes(data, 8 + server_version_length); Console.WriteLine("Handshake received. Server is running version: " + server_version); } } //End the session if the protocol versions don't match if (protocol_version != KLFCommon.NET_PROTOCOL_VERSION) { Console.WriteLine("Server version is incompatible with client version."); endSession = true; intentionalConnectionEnd = true; } else { sendHandshakeMessage(); //Reply to the handshake lock (udpTimestampLock) { lastUDPMessageSendTime = stopwatch.ElapsedMilliseconds; } handshakeCompleted = true; } break; case KLFCommon.ServerMessageID.HANDSHAKE_REFUSAL: String refusal_message = encoder.GetString(data, 0, data.Length); endSession = true; intentionalConnectionEnd = true; enqueuePluginChatMessage("Server refused connection. Reason: " + refusal_message, true); break; case KLFCommon.ServerMessageID.SERVER_MESSAGE: case KLFCommon.ServerMessageID.TEXT_MESSAGE: if (data != null) { InTextMessage in_message = new InTextMessage(); in_message.fromServer = (id == KLFCommon.ServerMessageID.SERVER_MESSAGE); in_message.message = encoder.GetString(data, 0, data.Length); //Queue the message enqueueTextMessage(in_message); } break; case KLFCommon.ServerMessageID.PLUGIN_UPDATE: if (data != null) sendClientInteropMessage(KLFCommon.ClientInteropMessageID.PLUGIN_UPDATE, data); break; case KLFCommon.ServerMessageID.SERVER_SETTINGS: lock (serverSettingsLock) { if (data != null && data.Length >= KLFCommon.SERVER_SETTINGS_LENGTH && handshakeCompleted) { updateInterval = KLFCommon.intFromBytes(data, 0); screenshotInterval = KLFCommon.intFromBytes(data, 4); lock (clientDataLock) { int new_screenshot_height = KLFCommon.intFromBytes(data, 8); if (screenshotSettings.maxHeight != new_screenshot_height) { screenshotSettings.maxHeight = new_screenshot_height; lastClientDataChangeTime = stopwatch.ElapsedMilliseconds; enqueueTextMessage("Screenshot Height has been set to " + screenshotSettings.maxHeight); } if (inactiveShipsPerUpdate != data[12]) { inactiveShipsPerUpdate = data[12]; lastClientDataChangeTime = stopwatch.ElapsedMilliseconds; } } } } break; case KLFCommon.ServerMessageID.SCREENSHOT_SHARE: if (data != null && data.Length > 0 && data.Length < screenshotSettings.maxNumBytes && watchPlayerName.Length > 0) { //Cache the screenshot Screenshot screenshot = new Screenshot(); screenshot.setFromByteArray(data); cacheScreenshot(screenshot); //Send the screenshot to the client sendClientInteropMessage(KLFCommon.ClientInteropMessageID.SCREENSHOT_RECEIVE, data); } break; case KLFCommon.ServerMessageID.CONNECTION_END: if (data != null) { String message = encoder.GetString(data, 0, data.Length); endSession = true; //If the reason is not a timeout, connection end is intentional intentionalConnectionEnd = message.ToLower() != "timeout"; enqueuePluginChatMessage("Server closed the connection: " + message, true); } break; case KLFCommon.ServerMessageID.UDP_ACKNOWLEDGE: lock (udpTimestampLock) { lastUDPAckReceiveTime = stopwatch.ElapsedMilliseconds; } break; case KLFCommon.ServerMessageID.CRAFT_FILE: if (data != null && data.Length > 4) { //Read craft name length byte craft_type = data[0]; int craft_name_length = KLFCommon.intFromBytes(data, 1); if (craft_name_length < data.Length - 5) { //Read craft name String craft_name = encoder.GetString(data, 5, craft_name_length); //Read craft bytes byte[] craft_bytes = new byte[data.Length - craft_name_length - 5]; Array.Copy(data, 5 + craft_name_length, craft_bytes, 0, craft_bytes.Length); //Write the craft to a file String filename = getCraftFilename(craft_name, craft_type); if (filename != null) { try { File.WriteAllBytes(filename, craft_bytes); enqueueTextMessage("Received craft file: " + craft_name); } catch { enqueueTextMessage("Error saving received craft file: " + craft_name); } } else enqueueTextMessage("Unable to save received craft file."); } } break; case KLFCommon.ServerMessageID.PING_REPLY: if (pingStopwatch.IsRunning) { enqueueTextMessage("Ping Reply: " + pingStopwatch.ElapsedMilliseconds + "ms"); pingStopwatch.Stop(); pingStopwatch.Reset(); } break; } }
protected void enqueueTextMessage(String message, bool from_server = false, bool to_plugin = true) { InTextMessage text_message = new InTextMessage(); text_message.message = message; text_message.fromServer = from_server; enqueueTextMessage(text_message, to_plugin); }
protected virtual void enqueueTextMessage(InTextMessage message, bool to_plugin = true) { if (to_plugin) { if (message.fromServer) enqueuePluginChatMessage("[Server] " + message.message, false); else enqueuePluginChatMessage(message.message); } }
static void handleMessage(KMPCommon.ServerMessageID id, byte[] data) { //LogAndShare("Message ID: " + id.ToString() + " data: " + (data == null ? "0" : System.Text.Encoding.ASCII.GetString(data))); switch (id) { case KMPCommon.ServerMessageID.HANDSHAKE: Int32 protocol_version = KMPCommon.intFromBytes(data); if (data.Length >= 8) { Int32 server_version_length = KMPCommon.intFromBytes(data, 4); if (data.Length >= 12 + server_version_length) { String server_version = encoder.GetString(data, 8, server_version_length); clientID = KMPCommon.intFromBytes(data, 8 + server_version_length); gameManager.gameMode = KMPCommon.intFromBytes(data, 12 + server_version_length); int kmpModControl_length = KMPCommon.intFromBytes(data, 16 + server_version_length); kmpModControl_bytes = new byte[kmpModControl_length]; Array.Copy(data, 20 + server_version_length, kmpModControl_bytes, 0, kmpModControl_length); SetMessage("Handshake received. Server version: " + server_version); } } //End the session if the protocol versions don't match if (protocol_version != KMPCommon.NET_PROTOCOL_VERSION) { endSession = true; intentionalConnectionEnd = true; gameManager.disconnect("Your client is incompatible with this server"); } else { if (!modCheck(kmpModControl_bytes)) { endSession = true; intentionalConnectionEnd = true; gameManager.disconnect(modMismatchError); } else { sendHandshakeMessage(); //Reply to the handshake lock (udpTimestampLock) { lastUDPMessageSendTime = stopwatch.ElapsedMilliseconds; } handshakeCompleted = true; } } break; case KMPCommon.ServerMessageID.HANDSHAKE_REFUSAL: String refusal_message = encoder.GetString(data, 0, data.Length); endSession = true; intentionalConnectionEnd = true; enqueuePluginChatMessage("Server refused connection. Reason: " + refusal_message, true); break; case KMPCommon.ServerMessageID.SERVER_MESSAGE: case KMPCommon.ServerMessageID.TEXT_MESSAGE: if (data != null) { InTextMessage in_message = new InTextMessage(); in_message.fromServer = (id == KMPCommon.ServerMessageID.SERVER_MESSAGE); in_message.isMOTD = (id == KMPCommon.ServerMessageID.MOTD_MESSAGE); in_message.message = encoder.GetString(data, 0, data.Length); if (in_message.message.Contains(" has shared a screenshot.")) { int screenshotSharePlayerNameIndex = in_message.message.IndexOf(" has shared a screenshot."); string screenshotSharePlayerName = in_message.message.Substring(0, screenshotSharePlayerNameIndex); if (screenshotSharePlayerName != username) { bool listPlayerNameInScreenshotsWaiting = false; foreach (string listPlayer in screenshotsWaiting) { if (listPlayer == screenshotSharePlayerName) { listPlayerNameInScreenshotsWaiting = true; } } if (listPlayerNameInScreenshotsWaiting == false) { screenshotsWaiting.Add(screenshotSharePlayerName); } } } if (in_message.message.Contains(" has disconnected : ")) { int quitPlayerNameIndex = in_message.message.IndexOf(" has disconnected : "); string quitPlayerName = in_message.message.Substring(0, quitPlayerNameIndex); if (quitPlayerName != username) { bool listPlayerNameInScreenshotsWaiting = false; foreach (string listPlayer in screenshotsWaiting) { if (listPlayer == quitPlayerName) { listPlayerNameInScreenshotsWaiting = true; } } if (listPlayerNameInScreenshotsWaiting) { screenshotsWaiting.Remove(quitPlayerName); } } } //Queue the message enqueueTextMessage(in_message); } break; case KMPCommon.ServerMessageID.MOTD_MESSAGE: if (data != null) { InTextMessage in_message = new InTextMessage(); in_message.fromServer = (id == KMPCommon.ServerMessageID.SERVER_MESSAGE); in_message.isMOTD = (id == KMPCommon.ServerMessageID.MOTD_MESSAGE); in_message.message = encoder.GetString(data, 0, data.Length); enqueueTextMessage(in_message); } break; case KMPCommon.ServerMessageID.PLUGIN_UPDATE: if (data != null) enqueueClientInteropMessage(KMPCommon.ClientInteropMessageID.PLUGIN_UPDATE, data); break; case KMPCommon.ServerMessageID.SCENARIO_UPDATE: if (data != null) enqueueClientInteropMessage(KMPCommon.ClientInteropMessageID.SCENARIO_UPDATE, data); break; case KMPCommon.ServerMessageID.SERVER_SETTINGS: lock (serverSettingsLock) { if (data != null && data.Length >= KMPCommon.SERVER_SETTINGS_LENGTH && handshakeCompleted) { updateInterval = KMPCommon.intFromBytes(data, 0); screenshotInterval = KMPCommon.intFromBytes(data, 4); lock (clientDataLock) { int new_screenshot_height = KMPCommon.intFromBytes(data, 8); if (screenshotSettings.maxHeight != new_screenshot_height) { screenshotSettings.maxHeight = new_screenshot_height; lastClientDataChangeTime = stopwatch.ElapsedMilliseconds; enqueueTextMessage("Screenshot Height has been set to " + screenshotSettings.maxHeight); } gameManager.safetyBubbleRadius = BitConverter.ToDouble(data, 12); if (inactiveShipsPerUpdate != data[20]) { inactiveShipsPerUpdate = data[20]; lastClientDataChangeTime = stopwatch.ElapsedMilliseconds; } gameManager.gameCheatsEnabled = Convert.ToBoolean(data[21]); gameManager.gameArrr = Convert.ToBoolean(data[22]); //partList, requiredModList, shaList, resourceList and resourceControlMode } receivedSettings = true; /* Log.Debug("Update interval: " + updateInterval); Log.Debug("Screenshot interval: " + screenshotInterval); Log.Debug("Inactive ships per update: " + inactiveShipsPerUpdate); */ } } break; case KMPCommon.ServerMessageID.SCREENSHOT_SHARE: if (data != null && data.Length > 0 && data.Length < screenshotSettings.maxNumBytes && watchPlayerName.Length > 0 && watchPlayerName != username) { enqueueClientInteropMessage(KMPCommon.ClientInteropMessageID.SCREENSHOT_RECEIVE, data); } break; case KMPCommon.ServerMessageID.CONNECTION_END: if (data != null) { String message = encoder.GetString(data, 0, data.Length); gameManager.disconnect(message); clearConnectionState(); //If the reason is not a timeout, connection end is intentional intentionalConnectionEnd = message.ToLower() != "timeout"; enqueuePluginChatMessage("Server closed the connection: " + message, true); SetMessage("Disconnected from server: " + message); } else { gameManager.disconnect(); clearConnectionState(); SetMessage("Disconnected from server"); } break; case KMPCommon.ServerMessageID.UDP_ACKNOWLEDGE: lock (udpTimestampLock) { lastUDPAckReceiveTime = stopwatch.ElapsedMilliseconds; } break; case KMPCommon.ServerMessageID.CRAFT_FILE: if (data != null && data.Length > 8) { //Read craft name length KMPCommon.CraftType craft_type = (KMPCommon.CraftType)KMPCommon.intFromBytes(data, 0); int craft_name_length = KMPCommon.intFromBytes(data, 4); if (craft_name_length < data.Length - 8) { //Read craft name String craft_name = encoder.GetString(data, 8, craft_name_length); //Read craft bytes byte[] craft_bytes = new byte[data.Length - craft_name_length - 8]; Array.Copy(data, 8 + craft_name_length, craft_bytes, 0, craft_bytes.Length); //Write the craft to a file String filename = getCraftFilename(craft_name, craft_type); if (filename != null) { try { //KSP.IO.File.WriteAllBytes<KMPClientMain>(craft_bytes, filename); System.IO.File.WriteAllBytes(filename, craft_bytes); enqueueTextMessage("Received craft file: " + craft_name); } catch (Exception e) { Log.Debug("Exception thrown in handleMessage(), catch 1, Exception: {0}", e.ToString()); enqueueTextMessage("Error saving received craft file: " + craft_name); } } else enqueueTextMessage("Unable to save received craft file."); } } break; case KMPCommon.ServerMessageID.PING_REPLY: if (pingStopwatch.IsRunning) { enqueueTextMessage("Ping Reply: " + pingStopwatch.ElapsedMilliseconds + "ms"); lastPing = pingStopwatch.ElapsedMilliseconds; pingStopwatch.Stop(); pingStopwatch.Reset(); } break; case KMPCommon.ServerMessageID.SYNC: if (data != null) gameManager.targetTick = BitConverter.ToDouble(data, 0) + Convert.ToDouble(lastPing); break; case KMPCommon.ServerMessageID.SYNC_COMPLETE: gameManager.HandleSyncCompleted(); break; case KMPCommon.ServerMessageID.SPLIT_MESSAGE: handleSplitMessage(data); break; } }
static void enqueueTextMessage(InTextMessage message, bool to_plugin = true) { //Dequeue an old text message if there are a lot of messages backed up if (textMessageQueue.Count >= MAX_TEXT_MESSAGE_QUEUE) { textMessageQueue.Dequeue(); } textMessageQueue.Enqueue(message); if (to_plugin) { if (message.fromServer) enqueuePluginChatMessage("[Server] " + message.message, false); else if (message.isMOTD) enqueuePluginChatMessage("[MOTD] " + message.message, false); else enqueuePluginChatMessage(message.message); } }
static void handleMessage(KLFCommon.ServerMessageID id, byte[] data) { ASCIIEncoding encoder = new ASCIIEncoding(); switch (id) { case KLFCommon.ServerMessageID.HANDSHAKE: Int32 protocol_version = KLFCommon.intFromBytes(data); String server_version = encoder.GetString(data, 4, data.Length - 4); Console.WriteLine("Handshake received. Server is running version: "+server_version); //End the session if the protocol versions don't match if (protocol_version != KLFCommon.NET_PROTOCOL_VERSION) { Console.WriteLine("Server version is incompatible with client version. Ending session."); endSession = true; } else { tcpSendMutex.WaitOne(); sendHandshakeMessage(); //Reply to the handshake tcpSendMutex.ReleaseMutex(); } break; case KLFCommon.ServerMessageID.HANDSHAKE_REFUSAL: String refusal_message = encoder.GetString(data, 0, data.Length); Console.WriteLine("Server refused connection. Reason: " + refusal_message); endSession = true; break; case KLFCommon.ServerMessageID.SERVER_MESSAGE: InTextMessage in_message = new InTextMessage(); in_message.fromServer = true; in_message.message = encoder.GetString(data, 0, data.Length); //Queue the message textMessageQueueMutex.WaitOne(); enqueueTextMessage(in_message); textMessageQueueMutex.ReleaseMutex(); break; case KLFCommon.ServerMessageID.TEXT_MESSAGE: in_message = new InTextMessage(); in_message.fromServer = false; in_message.message = encoder.GetString(data, 0, data.Length); //Queue the message textMessageQueueMutex.WaitOne(); enqueueTextMessage(in_message); textMessageQueueMutex.ReleaseMutex(); break; case KLFCommon.ServerMessageID.PLUGIN_UPDATE: //Add the update the queue pluginUpdateInMutex.WaitOne(); pluginUpdateInQueue.Enqueue(data); pluginUpdateInMutex.ReleaseMutex(); break; case KLFCommon.ServerMessageID.SERVER_SETTINGS: serverSettingsMutex.WaitOne(); updateInterval = KLFCommon.intFromBytes(data, 0); maxQueuedUpdates = KLFCommon.intFromBytes(data, 4); serverSettingsMutex.ReleaseMutex(); break; } }
static void handleInteropMessage(KMPCommon.PluginInteropMessageID id, byte[] data) { switch (id) { case KMPCommon.PluginInteropMessageID.CHAT_SEND: if (data != null) { String line = encoder.GetString(data); InTextMessage message = new InTextMessage(); message.fromServer = false; message.isMOTD = false; message.message = "[" + username + "] " + line; enqueueTextMessage(message, false); handleChatInput(line); } break; case KMPCommon.PluginInteropMessageID.PLUGIN_DATA: String new_watch_player_name = String.Empty; if (data != null && data.Length >= 9) { UnicodeEncoding encoder = new UnicodeEncoding(); int index = 0; //Read current activity status bool in_flight = data[index] != 0; index++; //Read current game title int current_game_title_length = KMPCommon.intFromBytes(data, index); index += 4; currentGameTitle = encoder.GetString(data, index, current_game_title_length); index += current_game_title_length; //Read the watch player name int watch_player_name_length = KMPCommon.intFromBytes(data, index); index += 4; new_watch_player_name = encoder.GetString(data, index, watch_player_name_length); index += watch_player_name_length; //Send the activity status to the server if (in_flight) queueOutgoingMessage(KMPCommon.ClientMessageID.ACTIVITY_UPDATE_IN_FLIGHT, null); else queueOutgoingMessage(KMPCommon.ClientMessageID.ACTIVITY_UPDATE_IN_GAME, null); } if (watchPlayerName != new_watch_player_name) { watchPlayerName = new_watch_player_name; if (watchPlayerName == username && lastSharedScreenshot != null) enqueueClientInteropMessage(KMPCommon.ClientInteropMessageID.SCREENSHOT_RECEIVE, lastSharedScreenshot); sendScreenshotWatchPlayerMessage(watchPlayerName); } break; case KMPCommon.PluginInteropMessageID.PRIMARY_PLUGIN_UPDATE: sendPluginUpdate(data, true); break; case KMPCommon.PluginInteropMessageID.SECONDARY_PLUGIN_UPDATE: sendPluginUpdate(data, false); break; case KMPCommon.PluginInteropMessageID.SCENARIO_UPDATE: sendScenarioUpdate(data); break; case KMPCommon.PluginInteropMessageID.SCREENSHOT_SHARE: if (data != null) { lock (screenshotOutLock) { queuedOutScreenshot = data; } } break; case KMPCommon.PluginInteropMessageID.WARPING: queueOutgoingMessage(KMPCommon.ClientMessageID.WARPING, data); break; case KMPCommon.PluginInteropMessageID.SSYNC: queueOutgoingMessage(KMPCommon.ClientMessageID.SSYNC, data); break; } }
static void handleMessage(KMPCommon.ServerMessageID id, byte[] data) { //LogAndShare("Message ID: " + id.ToString() + " data: " + (data == null ? "0" : System.Text.Encoding.ASCII.GetString(data))); switch (id) { case KMPCommon.ServerMessageID.HANDSHAKE: Int32 protocol_version = KMPCommon.intFromBytes(data); if (data.Length >= 8) { Int32 server_version_length = KMPCommon.intFromBytes(data, 4); if (data.Length >= 12 + server_version_length) { String server_version = encoder.GetString(data, 8, server_version_length); clientID = KMPCommon.intFromBytes(data, 8 + server_version_length); SetMessage("Handshake received. Server version: " + server_version); } } //End the session if the protocol versions don't match if (protocol_version != KMPCommon.NET_PROTOCOL_VERSION) { endSession = true; intentionalConnectionEnd = true; } else { sendHandshakeMessage(); //Reply to the handshake lock (udpTimestampLock) { lastUDPMessageSendTime = stopwatch.ElapsedMilliseconds; } handshakeCompleted = true; } break; case KMPCommon.ServerMessageID.HANDSHAKE_REFUSAL: String refusal_message = encoder.GetString(data, 0, data.Length); endSession = true; intentionalConnectionEnd = true; enqueuePluginChatMessage("Server refused connection. Reason: " + refusal_message, true); break; case KMPCommon.ServerMessageID.SERVER_MESSAGE: case KMPCommon.ServerMessageID.TEXT_MESSAGE: if (data != null) { InTextMessage in_message = new InTextMessage(); in_message.fromServer = (id == KMPCommon.ServerMessageID.SERVER_MESSAGE); in_message.message = encoder.GetString(data, 0, data.Length); //Queue the message enqueueTextMessage(in_message); } break; case KMPCommon.ServerMessageID.PLUGIN_UPDATE: if (data != null) enqueueClientInteropMessage(KMPCommon.ClientInteropMessageID.PLUGIN_UPDATE, data); break; case KMPCommon.ServerMessageID.SERVER_SETTINGS: lock (serverSettingsLock) { if (data != null && data.Length >= KMPCommon.SERVER_SETTINGS_LENGTH && handshakeCompleted) { updateInterval = KMPCommon.intFromBytes(data, 0); screenshotInterval = KMPCommon.intFromBytes(data, 4); lock (clientDataLock) { int new_screenshot_height = KMPCommon.intFromBytes(data, 8); if (screenshotSettings.maxHeight != new_screenshot_height) { screenshotSettings.maxHeight = new_screenshot_height; lastClientDataChangeTime = stopwatch.ElapsedMilliseconds; enqueueTextMessage("Screenshot Height has been set to " + screenshotSettings.maxHeight); } if (inactiveShipsPerUpdate != data[12]) { inactiveShipsPerUpdate = data[12]; lastClientDataChangeTime = stopwatch.ElapsedMilliseconds; } } receivedSettings = true; /* UnityEngine.Debug.Log("Update interval: " + updateInterval); UnityEngine.Debug.Log("Screenshot interval: " + screenshotInterval); UnityEngine.Debug.Log("Inactive ships per update: " + inactiveShipsPerUpdate); */ } } break; case KMPCommon.ServerMessageID.SCREENSHOT_SHARE: if (data != null && data.Length > 0 && data.Length < screenshotSettings.maxNumBytes && watchPlayerName.Length > 0 && watchPlayerName != username) { enqueueClientInteropMessage(KMPCommon.ClientInteropMessageID.SCREENSHOT_RECEIVE, data); } break; case KMPCommon.ServerMessageID.CONNECTION_END: gameManager.disconnect(); if (data != null) { String message = encoder.GetString(data, 0, data.Length); endSession = true; handshakeCompleted = false; receivedSettings = false; //If the reason is not a timeout, connection end is intentional intentionalConnectionEnd = message.ToLower() != "timeout"; enqueuePluginChatMessage("Server closed the connection: " + message, true); clearConnectionState(); SetMessage("Disconnected from server: " + message); gameManager.disconnect(message); } else { clearConnectionState(); SetMessage("Disconnected from server"); gameManager.disconnect(); } break; case KMPCommon.ServerMessageID.UDP_ACKNOWLEDGE: lock (udpTimestampLock) { lastUDPAckReceiveTime = stopwatch.ElapsedMilliseconds; } break; case KMPCommon.ServerMessageID.CRAFT_FILE: if (data != null && data.Length > 4) { //Read craft name length byte craft_type = data[0]; int craft_name_length = KMPCommon.intFromBytes(data, 1); if (craft_name_length < data.Length - 5) { //Read craft name String craft_name = encoder.GetString(data, 5, craft_name_length); //Read craft bytes byte[] craft_bytes = new byte[data.Length - craft_name_length - 5]; Array.Copy(data, 5 + craft_name_length, craft_bytes, 0, craft_bytes.Length); //Write the craft to a file String filename = getCraftFilename(craft_name, craft_type); if (filename != null) { try { //KSP.IO.File.WriteAllBytes<KMPClientMain>(craft_bytes, filename); System.IO.File.WriteAllBytes(filename,craft_bytes); enqueueTextMessage("Received craft file: " + craft_name); } catch { enqueueTextMessage("Error saving received craft file: " + craft_name); } } else enqueueTextMessage("Unable to save received craft file."); } } break; case KMPCommon.ServerMessageID.PING_REPLY: if (pingStopwatch.IsRunning) { enqueueTextMessage("Ping Reply: " + pingStopwatch.ElapsedMilliseconds + "ms"); lastPing = pingStopwatch.ElapsedMilliseconds; pingStopwatch.Stop(); pingStopwatch.Reset(); } break; case KMPCommon.ServerMessageID.SYNC: if (data != null) gameManager.targetTick = BitConverter.ToDouble(data,0) + Convert.ToDouble(lastPing); break; case KMPCommon.ServerMessageID.SYNC_COMPLETE: gameManager.HandleSyncCompleted(); break; } }
static void enqueueTextMessage(InTextMessage message) { //Dequeue an old text message if there are a lot of messages backed up if (textMessageQueue.Count >= MAX_TEXT_MESSAGE_QUEUE) textMessageQueue.Dequeue(); textMessageQueue.Enqueue(message); }
protected void HandleMessage(KLFCommon.ServerMessageID id, byte[] data) { switch (id) { case KLFCommon.ServerMessageID.Handshake: Int32 protocolVersion = KLFCommon.BytesToInt(data); if (data.Length >= 8) { Int32 server_version_length = KLFCommon.BytesToInt(data, 4); if (data.Length >= 12 + server_version_length) { String server_version = Encoder.GetString(data, 8, server_version_length); ClientID = KLFCommon.BytesToInt(data, 8 + server_version_length); Console.WriteLine("Handshake received. Server is running version: " + server_version); } } //End the session if the protocol versions don't match if (protocolVersion != KLFCommon.NetProtocolVersion) { Console.WriteLine("Server version is incompatible with client version."); EndSession = true; IntentionalConnectionEnd = true; } else { SendHandshakeMessage(); //Reply to the handshake lock (UdpTimestampLock) { LastUdpMessageSendTime = ClientStopwatch.ElapsedMilliseconds; } HandshakeComplete = true; } break; case KLFCommon.ServerMessageID.HandshakeRefusal: String refusal_message = Encoder.GetString(data, 0, data.Length); EndSession = true; IntentionalConnectionEnd = true; EnqueuePluginChatMessage("Server refused connection. Reason: " + refusal_message, true); break; case KLFCommon.ServerMessageID.ServerMessage: case KLFCommon.ServerMessageID.TextMessage: if (data != null) { InTextMessage inMessage = new InTextMessage(); inMessage.FromServer = (id == KLFCommon.ServerMessageID.ServerMessage); inMessage.message = Encoder.GetString(data, 0, data.Length); //Queue the message EnqueueTextMessage(inMessage); } break; case KLFCommon.ServerMessageID.PluginUpdate: if (data != null) SendClientInteropMessage(KLFCommon.ClientInteropMessageID.PluginUpdate, data); break; case KLFCommon.ServerMessageID.ServerSettings: lock (ServerSettingsLock) { if (data != null && data.Length >= KLFCommon.ServerSettingsLength && HandshakeComplete) { UpdateInterval = KLFCommon.BytesToInt(data, 0); ScreenshotInterval = KLFCommon.BytesToInt(data, 4); lock (ClientDataLock) { int new_screenshot_height = KLFCommon.BytesToInt(data, 8); if (ScreenshotConfiguration.MaxHeight != new_screenshot_height) { ScreenshotConfiguration.MaxHeight = new_screenshot_height; LastClientDataChangeTime = ClientStopwatch.ElapsedMilliseconds; EnqueueTextMessage("Screenshot Height has been set to " + ScreenshotConfiguration.MaxHeight); } if (InactiveShipsPerUpdate != data[12]) { InactiveShipsPerUpdate = data[12]; LastClientDataChangeTime = ClientStopwatch.ElapsedMilliseconds; } } } } break; case KLFCommon.ServerMessageID.ScreenshotShare: if (data != null && data.Length > 0 && data.Length < ScreenshotConfiguration.MaxNumBytes && WatchPlayerName.Length > 0) { //Cache the screenshot Screenshot screenshot = new Screenshot(); screenshot.SetFromByteArray(data); CacheScreenshot(screenshot); //Send the screenshot to the client SendClientInteropMessage(KLFCommon.ClientInteropMessageID.ScreenshotReceive, data); } break; case KLFCommon.ServerMessageID.ConnectionEnd: if (data != null) { String message = Encoder.GetString(data, 0, data.Length); EndSession = true; //If the reason is not a timeout, connection end is intentional IntentionalConnectionEnd = message.ToLower() != "timeout"; EnqueuePluginChatMessage("Server closed the connection: " + message, true); } break; case KLFCommon.ServerMessageID.UdpAcknowledge: lock (UdpTimestampLock) { LastUdpAckReceiveTime = ClientStopwatch.ElapsedMilliseconds; } break; case KLFCommon.ServerMessageID.CraftFile: if (data != null && data.Length > 4) { //Read craft name length byte craftType = data[0]; int craftName_length = KLFCommon.BytesToInt(data, 1); if (craftName_length < data.Length - 5) { //Read craft name String craftName = Encoder.GetString(data, 5, craftName_length); //Read craft bytes byte[] craft_bytes = new byte[data.Length - craftName_length - 5]; Array.Copy(data, 5 + craftName_length, craft_bytes, 0, craft_bytes.Length); //Write the craft to a file String filename = GetCraftFilename(craftName, craftType); if (filename != null) { try { File.WriteAllBytes(filename, craft_bytes); EnqueueTextMessage("Received craft file: " + craftName); } catch { EnqueueTextMessage("Error saving received craft file: " + craftName); } } else EnqueueTextMessage("Unable to save received craft file."); } } break; case KLFCommon.ServerMessageID.PingReply: if (PingStopwatch.IsRunning) { EnqueueTextMessage("Ping Reply: " + PingStopwatch.ElapsedMilliseconds + "ms"); PingStopwatch.Stop(); PingStopwatch.Reset(); } break; } }
protected void HandleInteropMessage(KLFCommon.PluginInteropMessageID id, byte[] data) { switch (id) { case KLFCommon.PluginInteropMessageID.ChatSend: if (data != null) { String line = Encoder.GetString(data); InTextMessage message = new InTextMessage(); message.FromServer = false; message.message = "[" + ClientConfiguration.Username + "] " + line; EnqueueTextMessage(message, false); HandleChatInput(line); } break; case KLFCommon.PluginInteropMessageID.PluginData: //String new_watch_player_name = String.Empty; if (data != null && data.Length >= 9) { int index = 0; //Read current activity status bool inFlight = data[index] != 0; index++; //Read current game title int CurrentGameTitleLength = KLFCommon.BytesToInt(data, index); index += 4; CurrentGameTitle = Encoder.GetString(data, index, CurrentGameTitleLength); index += CurrentGameTitleLength; //Send the activity status to the server if (inFlight) SendMessageTcp(KLFCommon.ClientMessageID.ActivityUpdateInFlight, null); else SendMessageTcp(KLFCommon.ClientMessageID.ActivityUpdateInFlight, null); } break; case KLFCommon.PluginInteropMessageID.PrimaryPluginUpdate: SendPluginUpdate(data, true); break; case KLFCommon.PluginInteropMessageID.SecondaryPluginUpdate: SendPluginUpdate(data, false); break; case KLFCommon.PluginInteropMessageID.ScreenshotShare: if (data != null) { lock (ScreenshotOutLock) { QueuedOutScreenshot = data; } } break; case KLFCommon.PluginInteropMessageID.ScreenshotWatchUpdate: if (data != null && data.Length >= 8) { int index = KLFCommon.BytesToInt(data, 0); int currentIndex = KLFCommon.BytesToInt(data, 4); String name = Encoder.GetString(data, 8, data.Length - 8); if (WatchPlayerName != name || WatchPlayerIndex != index) { WatchPlayerName = name; WatchPlayerIndex = index; //Look in the screenshot cache for the requested screenshot Screenshot cached = getCachedScreenshot(WatchPlayerIndex, WatchPlayerName); if (cached != null) SendClientInteropMessage(KLFCommon.ClientInteropMessageID.ScreenshotReceive, cached.ToByteArray()); SendScreenshotWatchPlayerMessage((cached == null), currentIndex, WatchPlayerIndex, WatchPlayerName); } } break; } }
protected virtual void EnqueueTextMessage(InTextMessage message, bool toPlugin = true) { if (toPlugin) if (message.FromServer) EnqueuePluginChatMessage("[Server] " + message.message, false); else EnqueuePluginChatMessage(message.message); }
protected void EnqueueTextMessage(String message, bool FromServer = false, bool toPlugin = true) { InTextMessage textMessage = new InTextMessage(); textMessage.message = message; textMessage.FromServer = FromServer; EnqueueTextMessage(textMessage, toPlugin); }
protected override void EnqueueTextMessage(InTextMessage message, bool toPlugin = true) { //Dequeue an old text message if there are a lot of messages backed up if (TextMessageQueue.Count >= MaxTextMessageQueue) { InTextMessage oldMessage; TextMessageQueue.TryDequeue(out oldMessage); } TextMessageQueue.Enqueue(message); base.EnqueueTextMessage(message, toPlugin); }