public void Receive(udp.UDPToolkit.Packet packet, int playerID)
        {
            if (!m_connectedClients[playerID])
            {
#if DEBUG_LOG
                Debug.Log("Received UDP packet from unconnected client (ID " + playerID + "). Ignoring.");
                return;
#endif //DEBUG_LOG
            }

            InputMessage inputs = IConvertible.CreateFromBytes <InputMessage>(packet.Data.ArraySegment());
            if (inputs != null && m_clients.Contains(playerID))
            {
                lock (m_lock)
                {
                    ClientState       clientState = m_clientStates[playerID];
                    List <InputFrame> inputFrames = inputs.InputFrames.Value;
#if DEBUG_LOG
                    Debug.Log("(NOW = " + m_masterTick + ") Received tick " + inputs.StartTick.Value + " to " + (inputs.StartTick.Value + inputFrames.Count) + " from " + clientState.PlayerGUID);
#endif //DEBUG_LOG

                    int frameIndex = 0;
                    for (int i = 0; i < inputFrames.Count; i++)
                    {
                        frameIndex = (int)inputs.StartTick.Value + i;
                        if (frameIndex >= m_masterTick)
                        {
                            m_clientInputBuffers[clientState][frameIndex] = inputFrames[i];
                        }
                    }
                }
            }
        }
        public void ReceivePacket(TCPToolkit.Packet packet, int playerID)
        {
            IdentificationMessage identification = Serializable.CreateFromBytes <IdentificationMessage>(packet.Data.ArraySegment());

            if (identification != null)
            {
                lock (m_lock)
                {
                    if (!m_clientCharacters.ContainsKey(playerID)) // it's a new player
                    {
                        AddNewPlayer(playerID);
                    }

#if DEBUG_LOG
                    Debug.Log("Received TCP connection request from player (ID  " + playerID + ")");
#endif // DEBUG_LOG

                    ServerSuccessfulConnectMessage serverSuccessPing = new ServerSuccessfulConnectMessage();
                    m_TCPServer.Send(serverSuccessPing.GetBytes(), playerID);
                }
                return;
            }

            OnLobbyEnteredMessage lobbyEnter = Serializable.CreateFromBytes <OnLobbyEnteredMessage>(packet.Data.ArraySegment());
            if (lobbyEnter != null)
            {
                lock (m_lock)
                {
                    if (m_clientCharacters.ContainsKey(playerID))
                    {
                        Debug.Log("Adding character " + lobbyEnter.CharacterID.Value + " to player " + playerID);
                        m_clientCharacters[playerID] = lobbyEnter.CharacterID;
                        BroadcastPlayerList();
                    }
                }
                return;
            }

            ClientReadyMessage ready = IConvertible.CreateFromBytes <ClientReadyMessage>(packet.Data.ArraySegment());
            if (ready != null && m_readyClients.ContainsKey(playerID))
            {
                Debug.Log("Client " + playerID + " is ready to receive world.");
                m_readyClients[playerID] = true;
                return;
            }

            if (m_awaitingClientLoadWorld)
            {
                ClientWorldLoadedMessage clientWorldLoaded = IConvertible.CreateFromBytes <ClientWorldLoadedMessage>(packet.Data.ArraySegment());
                if (clientWorldLoaded != null)
                {
                    m_readyClients.Remove(playerID);
                }
            }
        }