setFromByteArray() public method

public setFromByteArray ( byte bytes, bool meta_only = false ) : void
bytes byte
meta_only bool
return void
Beispiel #1
0
    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;
        }
    }
        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");
        }