public void enqueuePluginInteropMessage(KLFCommon.PluginInteropMessageID id, byte[] data) { InteropMessage message = new InteropMessage(); message.id = (int)id; message.data = data; interopInQueue.Enqueue(message); }
protected override void SendClientInteropMessage(KLFCommon.ClientInteropMessageID id, byte[] data) { InteropMessage message = new InteropMessage(); message.id = (int)id; message.data = data; InteropOutQueue.Enqueue(message); }
protected override void messageReceived(KLFCommon.ServerMessageID id, byte[] data) { ServerMessage message; message.id = id; message.data = data; lock (serverMessageQueueLock) { serverMessageQueue.Enqueue(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; } }
//Messages private static void sendMessageHeader(KLFCommon.ClientMessageID id, int msg_length) { tcpClient.GetStream().Write(KLFCommon.intToBytes((int)id), 0, 4); tcpClient.GetStream().Write(KLFCommon.intToBytes(msg_length), 0, 4); }
protected abstract void sendClientInteropMessage(KLFCommon.ClientInteropMessageID id, byte[] data);
protected void SendMessageTcp(KLFCommon.ClientMessageID id, byte[] data) { byte[] messageBytes = BuildMessageByteArray(id, data); lock (TcpSendLock) { try { TcpConnection.GetStream().Write(messageBytes, 0, messageBytes.Length); } catch (System.InvalidOperationException) {} catch (System.IO.IOException) {} } LastTcpMessageSendTime = ClientStopwatch.ElapsedMilliseconds; }
public void handleMessage(int client_index, KLFCommon.ClientMessageID id, byte[] data) { if (!clientIsValid(client_index)) return; debugConsoleWriteLine("Message id: " + id.ToString() + " data: " + (data != null ? data.Length.ToString() : "0")); UnicodeEncoding encoder = new UnicodeEncoding(); switch (id) { case KLFCommon.ClientMessageID.HANDSHAKE: if (data != null) { StringBuilder sb = new StringBuilder(); //Read username Int32 username_length = KLFCommon.intFromBytes(data, 0); String username = encoder.GetString(data, 4, username_length); int offset = 4 + username_length; String version = encoder.GetString(data, offset, data.Length - offset); String username_lower = username.ToLower(); bool accepted = true; //Ensure no other players have the same username for (int i = 0; i < clients.Length; i++) { if (i != client_index && clientIsReady(i) && clients[i].username.ToLower() == username_lower) { //Disconnect the player disconnectClient(client_index, "Your username is already in use."); stampedConsoleWriteLine("Rejected client due to duplicate username: "******"Your Client is Outdated Please Update"); stampedConsoleWriteLine("Rejected client due to wrong version : " + version + " New "+ KLFCommon.PROGRAM_VERSION); accepted = false; break; } if (!accepted) break; //Send the active user count to the client if (numClients == 2) { //Get the username of the other user on the server sb.Append("There is currently 1 other user on this server: "); for (int i = 0; i < clients.Length; i++) { if (i != client_index && clientIsReady(i)) { sb.Append(clients[i].username); break; } } } else { sb.Append("There are currently "); sb.Append(numClients - 1); sb.Append(" other users on this server."); if (numClients > 1) { sb.Append(" Enter !list to see them."); } } clients[client_index].username = username; clients[client_index].receivedHandshake = true; sendServerMessage(client_index, sb.ToString()); sendServerSettings(client_index); stampedConsoleWriteLine(username + " ("+getClientIP(client_index).ToString()+") has joined the server using client version " + version); if (!clients[client_index].messagesThrottled) { //Build join message sb.Clear(); sb.Append("User "); sb.Append(username); sb.Append(" has joined the server."); //Send the join message to all other clients sendServerMessageToAll(sb.ToString(), client_index); } messageFloodIncrement(client_index); } break; case KLFCommon.ClientMessageID.PRIMARY_PLUGIN_UPDATE: case KLFCommon.ClientMessageID.SECONDARY_PLUGIN_UPDATE: if (data != null && clientIsReady(client_index)) { #if SEND_UPDATES_TO_SENDER sendPluginUpdateToAll(data, id == KLFCommon.ClientMessageID.SECONDARY_PLUGIN_UPDATE); #else sendPluginUpdateToAll(data, id == KLFCommon.ClientMessageID.SECONDARY_PLUGIN_UPDATE, client_index); #endif } break; case KLFCommon.ClientMessageID.TEXT_MESSAGE: if (data != null && clientIsReady(client_index)) handleClientTextMessage(client_index, encoder.GetString(data, 0, data.Length)); break; case KLFCommon.ClientMessageID.SCREEN_WATCH_PLAYER: if (!clientIsReady(client_index) || data == null || data.Length < 9) break; bool send_screenshot = data[0] != 0; int watch_index = KLFCommon.intFromBytes(data, 1); int current_index = KLFCommon.intFromBytes(data, 5); String watch_name = encoder.GetString(data, 9, data.Length - 9); bool watch_name_changed = false; lock (clients[client_index].watchPlayerNameLock) { if (watch_name != clients[client_index].watchPlayerName || watch_index != clients[client_index].watchPlayerIndex) { //Set the watch player name clients[client_index].watchPlayerIndex = watch_index; clients[client_index].watchPlayerName = watch_name; watch_name_changed = true; } } if (send_screenshot && watch_name_changed && watch_name.Length > 0) { //Try to find the player the client is watching and send that player's current screenshot int watched_index = getClientIndexByName(watch_name); if (clientIsReady(watched_index)) { Screenshot screenshot = null; lock (clients[watched_index].screenshotLock) { screenshot = clients[watched_index].getScreenshot(watch_index); if (screenshot == null && watch_index == -1) screenshot = clients[watched_index].lastScreenshot; } if (screenshot != null && screenshot.index != current_index) { sendScreenshot(client_index, screenshot); } } } break; case KLFCommon.ClientMessageID.SCREENSHOT_SHARE: if (data != null && data.Length <= settings.screenshotSettings.maxNumBytes && clientIsReady(client_index)) { if (!clients[client_index].screenshotsThrottled) { StringBuilder sb = new StringBuilder(); Screenshot screenshot = new Screenshot(); screenshot.setFromByteArray(data); //Set the screenshot for the player lock (clients[client_index].screenshotLock) { clients[client_index].pushScreenshot(screenshot); } sb.Append(clients[client_index].username); sb.Append(" has shared a screenshot."); sendTextMessageToAll(sb.ToString()); stampedConsoleWriteLine(sb.ToString()); //Send the screenshot to every client watching the player sendScreenshotToWatchers(client_index, screenshot); if (settings.saveScreenshots) saveScreenshot(screenshot, clients[client_index].username); SHARED_SCREEN_SHOTS += 1; } bool was_throttled = clients[client_index].screenshotsThrottled; clients[client_index].screenshotFloodIncrement(); if (!was_throttled && clients[client_index].screenshotsThrottled) { long throttle_secs = settings.screenshotFloodThrottleTime / 1000; sendServerMessage(client_index, "You have been restricted from sharing screenshots for " + throttle_secs + " seconds."); stampedConsoleWriteLine(clients[client_index].username + " has been restricted from sharing screenshots for " + throttle_secs + " seconds."); } else if (clients[client_index].throttleState.messageFloodCounter == settings.screenshotFloodLimit - 1) sendServerMessage(client_index, "Warning: You are sharing too many screenshots."); } break; case KLFCommon.ClientMessageID.CONNECTION_END: String message = String.Empty; if (data != null) message = encoder.GetString(data, 0, data.Length); //Decode the message disconnectClient(client_index, message); //Disconnect the client break; case KLFCommon.ClientMessageID.SHARE_CRAFT_FILE: if (clientIsReady(client_index) && data != null && data.Length > 5 && (data.Length - 5) <= KLFCommon.MAX_CRAFT_FILE_BYTES) { if (clients[client_index].messagesThrottled) { messageFloodIncrement(client_index); break; } messageFloodIncrement(client_index); //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); lock (clients[client_index].sharedCraftLock) { clients[client_index].sharedCraftName = craft_name; clients[client_index].sharedCraftFile = craft_bytes; clients[client_index].sharedCraftType = craft_type; } //Send a message to players informing them that a craft has been shared StringBuilder sb = new StringBuilder(); sb.Append(clients[client_index].username); sb.Append(" shared "); sb.Append(craft_name); switch (craft_type) { case KLFCommon.CRAFT_TYPE_VAB: sb.Append(" (VAB)"); break; case KLFCommon.CRAFT_TYPE_SPH: sb.Append(" (SPH)"); break; } stampedConsoleWriteLine(sb.ToString()); sb.Append(" . Enter !getcraft "); sb.Append(clients[client_index].username); sb.Append(" to get it."); sendTextMessageToAll(sb.ToString()); } } break; case KLFCommon.ClientMessageID.ACTIVITY_UPDATE_IN_FLIGHT: clients[client_index].updateActivityLevel(ServerClient.ActivityLevel.IN_FLIGHT); break; case KLFCommon.ClientMessageID.ACTIVITY_UPDATE_IN_GAME: clients[client_index].updateActivityLevel(ServerClient.ActivityLevel.IN_GAME); break; case KLFCommon.ClientMessageID.PING: clients[client_index].queueOutgoingMessage(KLFCommon.ServerMessageID.PING_REPLY, null); break; } debugConsoleWriteLine("Handled message"); }
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 SendMessageUdp(KLFCommon.ClientMessageID id, byte[] data) { if (UdpSocket != null) { try { UdpSocket.Send(BuildMessageByteArray(id, data, KLFCommon.IntToBytes(ClientID))); } catch { } lock (UdpTimestampLock) { LastUdpMessageSendTime = ClientStopwatch.ElapsedMilliseconds; } } }
public void queueOutgoingMessage(KLFCommon.ServerMessageID id, byte[] data) { queueOutgoingMessage(Server.buildMessageArray(id, data)); }
public void HandleMessage(int clientIndex, KLFCommon.ClientMessageID id, byte[] data) { if (!ValidClient(clientIndex)) return; DebugConsoleWriteLine("Message id: " + id.ToString() + " data: " + (data != null ? data.Length.ToString() : "0")); UnicodeEncoding encoder = new UnicodeEncoding(); switch (id) { case KLFCommon.ClientMessageID.Handshake: if (data != null) { StringBuilder sb = new StringBuilder(); //Read username Int32 usernameLength = KLFCommon.BytesToInt(data, 0); String username = encoder.GetString(data, 4, usernameLength); int offset = 4 + usernameLength; String version = encoder.GetString(data, offset, data.Length - offset); String usernameLower = username.ToLower(); bool accepted = true; //Ensure no other players have the same username for (int i = 0; i < Clients.Length; i++) { if (i != clientIndex && ClientIsReady(i) && Clients[i].Username.ToLower() == usernameLower) { //Disconnect the player DisconnectClient(clientIndex, "Your username is already in use."); StampedConsoleWriteLine("Rejected client due to duplicate username: "******"There is currently 1 other user on this server: "); for (int i = 0; i < Clients.Length; i++) { if (i != clientIndex && ClientIsReady(i)) { sb.Append(Clients[i].Username); break; } } } else { sb.Append("There are currently "); sb.Append(NumClients - 1); sb.Append(" other users on this server."); if (NumClients > 1) sb.Append(" Enter /list to see them."); } Clients[clientIndex].Username = username; Clients[clientIndex].ReceivedHandshake = true; SendServerMessage(clientIndex, sb.ToString()); SendServerSettings(clientIndex); StampedConsoleWriteLine(username + " ("+GetClientIP(clientIndex).ToString()+") has joined the server using client version " + version); if (!Clients[clientIndex].MessagesThrottled) {//Build join message sb.Clear(); sb.Append("User "); sb.Append(username); sb.Append(" has joined the server."); //Send the join message to all other Clients SendServerMessageToAll(sb.ToString(), clientIndex); } MessageFloodIncrement(clientIndex); } break; case KLFCommon.ClientMessageID.PrimaryPluginUpdate: case KLFCommon.ClientMessageID.SecondaryPluginUpdate: if (data != null && ClientIsReady(clientIndex)) { #if SEND_UPDATES_TO_SENDER SendPluginUpdateToAll(data, id == KLFCommon.ClientMessageID.SecondaryPluginUpdate); #else SendPluginUpdateToAll(data, id == KLFCommon.ClientMessageID.SecondaryPluginUpdate, clientIndex); #endif } break; case KLFCommon.ClientMessageID.TextMessage: if (data != null && ClientIsReady(clientIndex)) HandleClientTextMessage(clientIndex, encoder.GetString(data, 0, data.Length)); break; case KLFCommon.ClientMessageID.ScreenWatchPlayer: if(!ClientIsReady(clientIndex) || data == null || data.Length < 9) break; bool sendScreenshot = data[0] != 0; int watchIndex = KLFCommon.BytesToInt(data, 1); int currentIndex = KLFCommon.BytesToInt(data, 5); String watchName = encoder.GetString(data, 9, data.Length - 9); bool watchNameChanged = false; lock (Clients[clientIndex].WatchPlayerNameLock) { if(watchName != Clients[clientIndex].WatchPlayerName || watchIndex != Clients[clientIndex].WatchPlayerIndex) {//Set the watch player name Clients[clientIndex].WatchPlayerIndex = watchIndex; Clients[clientIndex].WatchPlayerName = watchName; watchNameChanged = true; } } if (sendScreenshot && watchNameChanged && watchName.Length > 0) {//Try to find the player the client is watching and send that player's current screenshot int watchedIndex = GetClientIndexByName(watchName); if (ClientIsReady(watchedIndex)) { Screenshot screenshot = null; lock (Clients[watchedIndex].ScreenshotLock) { screenshot = Clients[watchedIndex].GetScreenshot(watchIndex); if (screenshot == null && watchIndex == -1) screenshot = Clients[watchedIndex].LastScreenshot; } if(screenshot != null && screenshot.Index != currentIndex) SendScreenshot(clientIndex, screenshot); } } break; case KLFCommon.ClientMessageID.ScreenshotShare: if (data != null && data.Length <= Configuration.ScreenshotSettings.MaxNumBytes && ClientIsReady(clientIndex)) { if (!Clients[clientIndex].ScreenshotsThrottled) { StringBuilder sb = new StringBuilder(); Screenshot screenshot = new Screenshot(); screenshot.SetFromByteArray(data); //Set the screenshot for the player lock (Clients[clientIndex].ScreenshotLock) { Clients[clientIndex].PushScreenshot(screenshot); } sb.Append(Clients[clientIndex].Username); sb.Append(" has shared a screenshot."); SendTextMessageToAll(sb.ToString()); StampedConsoleWriteLine(sb.ToString()); //Send the screenshot to every client watching the player SendScreenshotToWatchers(clientIndex, screenshot); if (Configuration.SaveScreenshots) saveScreenshot(screenshot, Clients[clientIndex].Username); } bool throttled = Clients[clientIndex].ScreenshotsThrottled; Clients[clientIndex].ScreenshotFloodIncrement(); if (!throttled && Clients[clientIndex].ScreenshotsThrottled) { long throttleSeconds = Configuration.ScreenshotFloodThrottleTime / 1000; SendServerMessage(clientIndex, "You have been restricted from sharing screenshots for " + throttleSeconds + " seconds."); StampedConsoleWriteLine(Clients[clientIndex].Username + " has been restricted from sharing screenshots for " + throttleSeconds + " seconds."); } else if (Clients[clientIndex].CurrentThrottle.MessageFloodCounter == Configuration.ScreenshotFloodLimit - 1) SendServerMessage(clientIndex, "Warning: You are sharing too many screenshots."); } break; case KLFCommon.ClientMessageID.ConnectionEnd: String message = String.Empty; if (data != null) message = encoder.GetString(data, 0, data.Length); //Decode the message DisconnectClient(clientIndex, message); //Disconnect the client break; case KLFCommon.ClientMessageID.ShareCraftFile: if(ClientIsReady(clientIndex) && data != null && data.Length > 5 && (data.Length - 5) <= KLFCommon.MaxCraftFileBytes) { if (Clients[clientIndex].MessagesThrottled) { MessageFloodIncrement(clientIndex); break; } MessageFloodIncrement(clientIndex); //Read craft name length byte craftType = data[0]; int craftNameLength = KLFCommon.BytesToInt(data, 1); if (craftNameLength < data.Length - 5) { //Read craft name String craftName = encoder.GetString(data, 5, craftNameLength); //Read craft bytes byte[] craftBytes = new byte[data.Length - craftNameLength - 5]; Array.Copy(data, 5 + craftNameLength, craftBytes, 0, craftBytes.Length); lock (Clients[clientIndex].SharedCraftLock) { Clients[clientIndex].SharedCraftName = craftName; Clients[clientIndex].SharedCraftFile = craftBytes; Clients[clientIndex].SharedCraftType = craftType; } //Send a message to players informing them that a craft has been shared StringBuilder sb = new StringBuilder(); sb.Append(Clients[clientIndex].Username); sb.Append(" shared "); sb.Append(craftName); switch (craftType) { case KLFCommon.CraftTypeVab: sb.Append(" (VAB)"); break; case KLFCommon.CraftTypeSph: sb.Append(" (SPH)"); break; } StampedConsoleWriteLine(sb.ToString()); sb.Append(" . Enter " + KLFCommon.GetCraftCommand); sb.Append(Clients[clientIndex].Username); sb.Append(" to get it."); SendTextMessageToAll(sb.ToString()); } } break; case KLFCommon.ClientMessageID.ActivityUpdateInFlight: Clients[clientIndex].UpdateActivity(ServerClient.Activity.InFlight); break; case KLFCommon.ClientMessageID.ActivityUpdateInGame: Clients[clientIndex].UpdateActivity(ServerClient.Activity.InGame); break; case KLFCommon.ClientMessageID.Ping: Clients[clientIndex].QueueOutgoingMessage(KLFCommon.ServerMessageID.PingReply, null); break; } DebugConsoleWriteLine("Handled message"); }
//Messages public void QueueClientMessage(int clientIndex, KLFCommon.ClientMessageID id, byte[] data) { ClientMessage message = new ClientMessage(); message.ClientIndex = clientIndex; message.ID = id; message.Data = data; ClientMessageQueue.Enqueue(message); }
public static byte[] BuildMessageArray(KLFCommon.ServerMessageID id, byte[] data) { //Construct the byte array for the message int messageDataLength = 0; if (data != null) messageDataLength = data.Length; byte[] messageBytes = new byte[KLFCommon.MessageHeaderLength + messageDataLength]; KLFCommon.IntToBytes((int)id).CopyTo(messageBytes, 0); KLFCommon.IntToBytes(messageDataLength).CopyTo(messageBytes, 4); if (data != null) data.CopyTo(messageBytes, KLFCommon.MessageHeaderLength); return messageBytes; }
private void SendMessageHeaderDirect(TcpClient client, KLFCommon.ServerMessageID id, int msgLength) { client.GetStream().Write(KLFCommon.IntToBytes((int)id), 0, 4); client.GetStream().Write(KLFCommon.IntToBytes(msgLength), 0, 4); DebugConsoleWriteLine("Sending message: " + id.ToString()); }
//Messages public void queueClientMessage(int client_index, KLFCommon.ClientMessageID id, byte[] data) { ClientMessage message = new ClientMessage(); message.clientIndex = client_index; message.id = id; message.data = data; clientMessageQueue.Enqueue(message); }
private void enqueuePluginInteropMessage(KLFCommon.PluginInteropMessageID id, byte[] data) { int msg_data_length = 0; if (data != null) msg_data_length = data.Length; byte[] message_bytes = new byte[KLFCommon.INTEROP_MSG_HEADER_LENGTH + msg_data_length]; KLFCommon.intToBytes((int)id).CopyTo(message_bytes, 0); KLFCommon.intToBytes(msg_data_length).CopyTo(message_bytes, 4); if (data != null) data.CopyTo(message_bytes, KLFCommon.INTEROP_MSG_HEADER_LENGTH); interopOutQueue.Enqueue(message_bytes); //Enforce max queue size while (interopOutQueue.Count > INTEROP_MAX_QUEUE_SIZE) interopOutQueue.Dequeue(); }
protected void sendMessageTCP(KLFCommon.ClientMessageID id, byte[] data) { byte[] message_bytes = buildMessageByteArray(id, data); lock (tcpSendLock) { try { //Send message tcpClient.GetStream().Write(message_bytes, 0, message_bytes.Length); } catch (System.InvalidOperationException) { } catch (System.IO.IOException) { } } lastTCPMessageSendTime = stopwatch.ElapsedMilliseconds; }
private void handleInteropMessage(KLFCommon.ClientInteropMessageID id, byte[] data) { switch (id) { case KLFCommon.ClientInteropMessageID.CHAT_RECEIVE: if (data != null) { KLFChatDisplay.enqueueChatLine(encoder.GetString(data)); } break; case KLFCommon.ClientInteropMessageID.CLIENT_DATA: if (data != null && data.Length > 9) { //Read inactive vessels per update count inactiveVesselsPerUpdate = data[0]; //Read screenshot height KLFScreenshotDisplay.screenshotSettings.maxHeight = KLFCommon.intFromBytes(data, 1); updateInterval = ((float)KLFCommon.intFromBytes(data, 5))/1000.0f; //Read username playerName = encoder.GetString(data, 9, data.Length - 9); } break; case KLFCommon.ClientInteropMessageID.PLUGIN_UPDATE: if (data != null) { //De-serialize and handle the update handleUpdate(KSP.IO.IOUtils.DeserializeFromBinary(data)); } break; case KLFCommon.ClientInteropMessageID.SCREENSHOT_RECEIVE: if (data != null) { Debug.Log("Received screenshot"); KLFScreenshotDisplay.screenshot.setFromByteArray(data); if (KLFScreenshotDisplay.screenshot.image.Length <= KLFScreenshotDisplay.screenshotSettings.maxNumBytes) { if (KLFScreenshotDisplay.texture == null) KLFScreenshotDisplay.texture = new Texture2D(4, 4, TextureFormat.RGB24, false, true); if (KLFScreenshotDisplay.texture.LoadImage(KLFScreenshotDisplay.screenshot.image)) { KLFScreenshotDisplay.texture.Apply(); //Make sure the screenshot texture does not exceed the size limits if (KLFScreenshotDisplay.texture.width > KLFScreenshotDisplay.screenshotSettings.maxWidth || KLFScreenshotDisplay.texture.height > KLFScreenshotDisplay.screenshotSettings.maxHeight) { KLFScreenshotDisplay.screenshot.clear(); } } else { KLFScreenshotDisplay.screenshot.clear(); } KLFScreenshotDisplay.screenshot.image = null; } } break; } }
protected byte[] buildMessageByteArray(KLFCommon.ClientMessageID id, byte[] data, byte[] prefix = null) { int prefix_length = 0; if (prefix != null) prefix_length = prefix.Length; int msg_data_length = 0; if (data != null) msg_data_length = data.Length; byte[] message_bytes = new byte[KLFCommon.MSG_HEADER_LENGTH + msg_data_length + prefix_length]; int index = 0; if (prefix != null) { prefix.CopyTo(message_bytes, index); index += 4; } KLFCommon.intToBytes((int)id).CopyTo(message_bytes, index); index += 4; KLFCommon.intToBytes(msg_data_length).CopyTo(message_bytes, index); index += 4; if (data != null) { data.CopyTo(message_bytes, index); index += data.Length; } return message_bytes; }
//Messages private void messageReceived(KLFCommon.ClientMessageID id, byte[] data) { parent.queueClientMessage(clientIndex, id, data); }
public static byte[] buildMessageArray(KLFCommon.ServerMessageID id, byte[] data) { //Construct the byte array for the message int msg_data_length = 0; if (data != null) msg_data_length = data.Length; byte[] message_bytes = new byte[KLFCommon.MSG_HEADER_LENGTH + msg_data_length]; KLFCommon.intToBytes((int)id).CopyTo(message_bytes, 0); KLFCommon.intToBytes(msg_data_length).CopyTo(message_bytes, 4); if (data != null) data.CopyTo(message_bytes, KLFCommon.MSG_HEADER_LENGTH); return message_bytes; }
protected void sendMessageUDP(KLFCommon.ClientMessageID id, byte[] data) { if (udpSocket != null) { //Send the packet try { udpSocket.Send(buildMessageByteArray(id, data, KLFCommon.intToBytes(clientID))); } catch { } lock (udpTimestampLock) { lastUDPMessageSendTime = stopwatch.ElapsedMilliseconds; } } }
private void handleInteropMessage(KLFCommon.ClientInteropMessageID id, byte[] data) { switch (id) { case KLFCommon.ClientInteropMessageID.CHAT_RECEIVE: if (data != null) { string NNmessage = encoder.GetString(data); if (!KLFGlobalSettings.instance.chatWindowEnabled || !KLFInfoDisplay.infoDisplayActive) { KLF_Button.SetTexture(KLF_button_alert); KLF_button_alert_anim = 1; if (KLFGlobalSettings.instance.SendNotifications) { MessageSystem.Message m = new MessageSystem.Message("Kerbal Live Feed Activity", NNmessage, MessageSystemButton.MessageButtonColor.YELLOW, MessageSystemButton.ButtonIcons.MESSAGE); MessageSystem.Instance.AddMessage(m); } } KLFChatDisplay.enqueueChatLine(NNmessage); } break; case KLFCommon.ClientInteropMessageID.CLIENT_DATA: if (data != null && data.Length > 9) { //Read inactive vessels per update count inactiveVesselsPerUpdate = data[0]; //Read screenshot height KLFScreenshotDisplay.screenshotSettings.maxHeight = KLFCommon.intFromBytes(data, 1); updateInterval = ((float)KLFCommon.intFromBytes(data, 5)) / 1000.0f; //Read username playerName = encoder.GetString(data, 9, data.Length - 9); } break; case KLFCommon.ClientInteropMessageID.PLUGIN_UPDATE: if (data != null) { //De-serialize and handle the update handleUpdate(KSP.IO.IOUtils.DeserializeFromBinary(data)); } break; case KLFCommon.ClientInteropMessageID.SCREENSHOT_RECEIVE: if (data != null) { Debug.Log("Received screenshot"); KLFScreenshotDisplay.screenshot.setFromByteArray(data); if (KLFScreenshotDisplay.screenshot.image.Length <= KLFScreenshotDisplay.screenshotSettings.maxNumBytes) { if (KLFScreenshotDisplay.texture == null) KLFScreenshotDisplay.texture = new Texture2D(4, 4, TextureFormat.RGB24, false, true); if (KLFScreenshotDisplay.texture.LoadImage(KLFScreenshotDisplay.screenshot.image)) { KLFScreenshotDisplay.texture.Apply(); //Make sure the screenshot texture does not exceed the size limits if (KLFScreenshotDisplay.texture.width > KLFScreenshotDisplay.screenshotSettings.maxWidth || KLFScreenshotDisplay.texture.height > KLFScreenshotDisplay.screenshotSettings.maxHeight) { KLFScreenshotDisplay.screenshot.clear(); } else { KLFScreenshotDisplay.watchPlayerIndex = KLFScreenshotDisplay.screenshot.index; } } else { KLFScreenshotDisplay.screenshot.clear(); } KLFScreenshotDisplay.screenshot.image = null; } } break; } }
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; } }
private static void messageReceived(KLFCommon.ServerMessageID id, byte[] data) { ServerMessage message; message.id = id; message.data = data; receivedMessageQueue.Enqueue(message); }
protected abstract void messageReceived(KLFCommon.ServerMessageID id, byte[] data);
static void enqueueClientInteropMessage(KLFCommon.ClientInteropMessageID id, byte[] data) { int msg_data_length = 0; if (data != null) msg_data_length = data.Length; byte[] message_bytes = new byte[KLFCommon.INTEROP_MSG_HEADER_LENGTH + msg_data_length]; KLFCommon.intToBytes((int)id).CopyTo(message_bytes, 0); KLFCommon.intToBytes(msg_data_length).CopyTo(message_bytes, 4); if (data != null) data.CopyTo(message_bytes, KLFCommon.INTEROP_MSG_HEADER_LENGTH); interopOutQueue.Enqueue(message_bytes); //Enforce max queue size while (interopOutQueue.Count > INTEROP_MAX_QUEUE_SIZE) { byte[] bytes; if (!interopOutQueue.TryDequeue(out bytes)) break; } }
protected override void sendClientInteropMessage(KLFCommon.ClientInteropMessageID id, byte[] data) { InteropMessage message = new InteropMessage(); message.id = (int)id; message.data = data; interopOutQueue.Enqueue(message); //Enforce max queue size while (interopOutQueue.Count > INTEROP_MAX_QUEUE_SIZE) { if (!interopOutQueue.TryDequeue(out message)) break; } }
static 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 = "[" + 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; //Read the watch player name int watch_player_name_length = KLFCommon.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) sendMessageTCP(KLFCommon.ClientMessageID.ACTIVITY_UPDATE_IN_FLIGHT, null); else sendMessageTCP(KLFCommon.ClientMessageID.ACTIVITY_UPDATE_IN_GAME, null); } if (watchPlayerName != new_watch_player_name) { watchPlayerName = new_watch_player_name; if (watchPlayerName == username && lastSharedScreenshot != null) enqueueClientInteropMessage(KLFCommon.ClientInteropMessageID.SCREENSHOT_RECEIVE, lastSharedScreenshot); sendScreenshotWatchPlayerMessage(watchPlayerName); } 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; } }