ReadByte() public method

1字节读出
public ReadByte ( ) : int
return int
Esempio n. 1
0
        public virtual void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
        {
            if (GameMain.Server != null)
            {
                return;
            }

            switch (type)
            {
            case ServerNetObject.ENTITY_POSITION:
                bool facingRight = AnimController.Dir > 0.0f;

                lastRecvPositionUpdateTime = (float)NetTime.Now;

                AnimController.Frozen = false;
                Enabled = true;

                UInt16 networkUpdateID = 0;
                if (msg.ReadBoolean())
                {
                    networkUpdateID = msg.ReadUInt16();
                }
                else
                {
                    bool aimInput = msg.ReadBoolean();
                    keys[(int)InputType.Aim].Held = aimInput;
                    keys[(int)InputType.Aim].SetState(false, aimInput);

                    bool useInput = msg.ReadBoolean();
                    keys[(int)InputType.Use].Held = useInput;
                    keys[(int)InputType.Use].SetState(false, useInput);

                    bool hasAttackLimb = msg.ReadBoolean();
                    if (hasAttackLimb)
                    {
                        bool attackInput = msg.ReadBoolean();
                        keys[(int)InputType.Attack].Held = attackInput;
                        keys[(int)InputType.Attack].SetState(false, attackInput);
                    }

                    if (aimInput)
                    {
                        double aimAngle = ((double)msg.ReadUInt16() / 65535.0) * 2.0 * Math.PI;
                        cursorPosition = (ViewTarget == null ? AnimController.Collider.Position : ViewTarget.Position)
                                         + new Vector2((float)Math.Cos(aimAngle), (float)Math.Sin(aimAngle)) * 60.0f;

                        TransformCursorPos();
                    }
                    facingRight = msg.ReadBoolean();
                }

                bool   entitySelected = msg.ReadBoolean();
                Entity selectedEntity = null;

                AnimController.Animation animation = AnimController.Animation.None;
                if (entitySelected)
                {
                    ushort entityID = msg.ReadUInt16();
                    selectedEntity = FindEntityByID(entityID);
                    if (selectedEntity is Character)
                    {
                        bool doingCpr = msg.ReadBoolean();
                        if (doingCpr && selectedCharacter != null)
                        {
                            animation = AnimController.Animation.CPR;
                        }
                    }
                }

                Vector2 pos = new Vector2(
                    msg.ReadFloat(),
                    msg.ReadFloat());


                int index = 0;
                if (GameMain.NetworkMember.Character == this && AllowInput)
                {
                    var posInfo = new CharacterStateInfo(pos, networkUpdateID, facingRight ? Direction.Right : Direction.Left, selectedEntity, animation);
                    while (index < memState.Count && NetIdUtils.IdMoreRecent(posInfo.ID, memState[index].ID))
                    {
                        index++;
                    }

                    memState.Insert(index, posInfo);
                }
                else
                {
                    var posInfo = new CharacterStateInfo(pos, sendingTime, facingRight ? Direction.Right : Direction.Left, selectedEntity, animation);
                    while (index < memState.Count && posInfo.Timestamp > memState[index].Timestamp)
                    {
                        index++;
                    }

                    memState.Insert(index, posInfo);
                }

                break;

            case ServerNetObject.ENTITY_EVENT:

                int eventType = msg.ReadRangedInteger(0, 2);
                switch (eventType)
                {
                case 0:
                    inventory.ClientRead(type, msg, sendingTime);
                    break;

                case 1:
                    byte ownerID = msg.ReadByte();
                    ResetNetState();
                    if (ownerID == GameMain.Client.ID)
                    {
                        if (controlled != null)
                        {
                            LastNetworkUpdateID = controlled.LastNetworkUpdateID;
                        }

                        controlled                = this;
                        IsRemotePlayer            = false;
                        GameMain.Client.Character = this;
                    }
                    else if (controlled == this)
                    {
                        controlled     = null;
                        IsRemotePlayer = ownerID > 0;
                    }
                    break;

                case 2:
                    ReadStatus(msg);
                    break;
                }

                break;
            }
        }
        //static because we may need to instantiate the campaign if it hasn't been done yet
        public static void ClientRead(NetBuffer msg)
        {
            byte   campaignID       = msg.ReadByte();
            UInt16 updateID         = msg.ReadUInt16();
            UInt16 saveID           = msg.ReadUInt16();
            string mapSeed          = msg.ReadString();
            UInt16 currentLocIndex  = msg.ReadUInt16();
            UInt16 selectedLocIndex = msg.ReadUInt16();

            int money = msg.ReadInt32();

            UInt16 purchasedItemCount           = msg.ReadUInt16();
            List <PurchasedItem> purchasedItems = new List <PurchasedItem>();

            for (int i = 0; i < purchasedItemCount; i++)
            {
                UInt16 itemPrefabIndex = msg.ReadUInt16();
                UInt16 itemQuantity    = msg.ReadUInt16();
                purchasedItems.Add(new PurchasedItem(MapEntityPrefab.List[itemPrefabIndex] as ItemPrefab, itemQuantity));
            }

            MultiPlayerCampaign campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;

            if (campaign == null || campaignID != campaign.CampaignID)
            {
                string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer);

                GameMain.GameSession = new GameSession(null, savePath, GameModePreset.list.Find(g => g.Name == "Campaign"));

                campaign            = ((MultiPlayerCampaign)GameMain.GameSession.GameMode);
                campaign.CampaignID = campaignID;
                campaign.GenerateMap(mapSeed);
            }

            GameMain.NetLobbyScreen.ToggleCampaignMode(true);
            if (NetIdUtils.IdMoreRecent(campaign.lastUpdateID, updateID))
            {
                return;
            }

            //server has a newer save file
            if (NetIdUtils.IdMoreRecent(saveID, campaign.PendingSaveID))
            {
                /*//stop any active campaign save transfers, they're outdated now
                 * List<FileReceiver.FileTransferIn> saveTransfers =
                 *  GameMain.Client.FileReceiver.ActiveTransfers.FindAll(t => t.FileType == FileTransferType.CampaignSave);
                 *
                 * foreach (var transfer in saveTransfers)
                 * {
                 *  GameMain.Client.FileReceiver.StopTransfer(transfer);
                 * }
                 *
                 * GameMain.Client.RequestFile(FileTransferType.CampaignSave, null, null);*/
                campaign.PendingSaveID = saveID;
            }
            //we've got the latest save file
            else if (!NetIdUtils.IdMoreRecent(saveID, campaign.lastSaveID))
            {
                campaign.Map.SetLocation(currentLocIndex == UInt16.MaxValue ? -1 : currentLocIndex);
                campaign.Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex);

                campaign.Money = money;
                campaign.CargoManager.SetPurchasedItems(purchasedItems);

                campaign.lastUpdateID = updateID;
            }
        }
Esempio n. 3
0
        public virtual void ServerRead(ClientNetObject type, NetBuffer msg, Client c)
        {
            if (GameMain.Server == null)
            {
                return;
            }

            switch (type)
            {
            case ClientNetObject.CHARACTER_INPUT:

                if (c.Character != this)
                {
#if DEBUG
                    DebugConsole.Log("Received a character update message from a client who's not controlling the character");
#endif
                    return;
                }

                UInt16 networkUpdateID = msg.ReadUInt16();
                byte   inputCount      = msg.ReadByte();

                if (AllowInput)
                {
                    Enabled = true;
                }

                for (int i = 0; i < inputCount; i++)
                {
                    InputNetFlags newInput    = (InputNetFlags)msg.ReadRangedInteger(0, (int)InputNetFlags.MaxVal);
                    UInt16        newAim      = 0;
                    UInt16        newInteract = 0;

                    if (newInput.HasFlag(InputNetFlags.Aim))
                    {
                        newAim = msg.ReadUInt16();
                    }
                    if (newInput.HasFlag(InputNetFlags.Select) || newInput.HasFlag(InputNetFlags.Use))
                    {
                        newInteract = msg.ReadUInt16();
                    }

                    if (AllowInput)
                    {
                        if (NetIdUtils.IdMoreRecent((ushort)(networkUpdateID - i), LastNetworkUpdateID) && (i < 60))
                        {
                            NetInputMem newMem = new NetInputMem();
                            newMem.states   = newInput;
                            newMem.intAim   = newAim;
                            newMem.interact = newInteract;

                            newMem.networkUpdateID = (ushort)(networkUpdateID - i);

                            memInput.Insert(i, newMem);
                        }
                    }
                }

                if (NetIdUtils.IdMoreRecent(networkUpdateID, LastNetworkUpdateID))
                {
                    LastNetworkUpdateID = networkUpdateID;
                }
                if (memInput.Count > 60)
                {
                    //deleting inputs from the queue here means the server is way behind and data needs to be dropped
                    //we'll make the server drop down to 30 inputs for good measure
                    memInput.RemoveRange(30, memInput.Count - 30);
                }
                break;

            case ClientNetObject.ENTITY_STATE:
                int eventType = msg.ReadRangedInteger(0, 2);
                switch (eventType)
                {
                case 0:
                    inventory.ServerRead(type, msg, c);
                    break;

                case 1:
                    if (c.Character != this)
                    {
#if DEBUG
                        DebugConsole.Log("Received a character update message from a client who's not controlling the character");
#endif
                        return;
                    }

                    bool doingCPR = msg.ReadBoolean();
                    AnimController.Anim = doingCPR ? AnimController.Animation.CPR : AnimController.Animation.None;
                    break;

                case 2:
                    if (c.Character != this)
                    {
#if DEBUG
                        DebugConsole.Log("Received a character update message from a client who's not controlling the character");
#endif
                        return;
                    }

                    if (IsUnconscious)
                    {
                        Kill(lastAttackCauseOfDeath);
                    }
                    break;
                }

                msg.ReadPadBits();
                break;
            }
        }
Esempio n. 4
0
        private void ReadStatus(NetBuffer msg)
        {
            bool isDead = msg.ReadBoolean();

            if (isDead)
            {
                causeOfDeath = (CauseOfDeath)msg.ReadByte();
                byte severedLimbCount = msg.ReadByte();
                if (!IsDead)
                {
                    if (causeOfDeath == CauseOfDeath.Pressure)
                    {
                        Implode(true);
                    }
                    else
                    {
                        Kill(causeOfDeath, true);
                    }
                }

                for (int i = 0; i < severedLimbCount; i++)
                {
                    int severedJointIndex = msg.ReadByte();
                    AnimController.SeverLimbJoint(AnimController.LimbJoints[severedJointIndex]);
                }
            }
            else
            {
                this.isDead = false;

                health = msg.ReadRangedSingle(minHealth, maxHealth, 8);

                bool lowOxygen = msg.ReadBoolean();
                if (lowOxygen)
                {
                    Oxygen = msg.ReadRangedSingle(-100.0f, 100.0f, 8);
                }
                else
                {
                    Oxygen = 100.0f;
                }

                bool isBleeding = msg.ReadBoolean();
                if (isBleeding)
                {
                    bleeding = msg.ReadRangedSingle(0.0f, 5.0f, 8);
                }
                else
                {
                    bleeding = 0.0f;
                }

                bool stunned = msg.ReadBoolean();
                if (stunned)
                {
                    float newStunTimer = msg.ReadRangedSingle(0.0f, 60.0f, 8);
                    SetStun(newStunTimer, true, true);
                }
                else
                {
                    SetStun(0.0f, true, true);
                }

                bool ragdolled = msg.ReadBoolean();
                IsRagdolled = ragdolled;

                bool huskInfected = msg.ReadBoolean();
                if (huskInfected)
                {
                    HuskInfectionState = Math.Max(HuskInfectionState, 0.01f);
                }
                else
                {
                    HuskInfectionState = 0.0f;
                }
            }
        }
Esempio n. 5
0
            public void Read(NetBuffer msg)
            {
                long   oldPos = msg.Position;
                UInt32 size   = msg.ReadVariableUInt32();

                float x; float y; float z; float w;
                byte  r; byte g; byte b; byte a;
                int   ix; int iy; int width; int height;

                switch (typeString)
                {
                case "float":
                    if (size != 4)
                    {
                        break;
                    }
                    property.SetValue(serverSettings, msg.ReadFloat());
                    return;

                case "vector2":
                    if (size != 8)
                    {
                        break;
                    }
                    x = msg.ReadFloat();
                    y = msg.ReadFloat();
                    property.SetValue(serverSettings, new Vector2(x, y));
                    return;

                case "vector3":
                    if (size != 12)
                    {
                        break;
                    }
                    x = msg.ReadFloat();
                    y = msg.ReadFloat();
                    z = msg.ReadFloat();
                    property.SetValue(serverSettings, new Vector3(x, y, z));
                    return;

                case "vector4":
                    if (size != 16)
                    {
                        break;
                    }
                    x = msg.ReadFloat();
                    y = msg.ReadFloat();
                    z = msg.ReadFloat();
                    w = msg.ReadFloat();
                    property.SetValue(serverSettings, new Vector4(x, y, z, w));
                    return;

                case "color":
                    if (size != 4)
                    {
                        break;
                    }
                    r = msg.ReadByte();
                    g = msg.ReadByte();
                    b = msg.ReadByte();
                    a = msg.ReadByte();
                    property.SetValue(serverSettings, new Color(r, g, b, a));
                    return;

                case "rectangle":
                    if (size != 16)
                    {
                        break;
                    }
                    ix     = msg.ReadInt32();
                    iy     = msg.ReadInt32();
                    width  = msg.ReadInt32();
                    height = msg.ReadInt32();
                    property.SetValue(serverSettings, new Rectangle(ix, iy, width, height));
                    return;

                default:
                    msg.Position = oldPos;     //reset position to properly read the string
                    string incVal = msg.ReadString();
                    property.TrySetValue(serverSettings, incVal);
                    return;
                }

                //size didn't match: skip this
                msg.Position += 8 * size;
            }
Esempio n. 6
0
 public void Deserialize(NetBuffer reader)
 {
     GlobalObjectId.ReadFrom(reader);
     NetworkObjectId = reader.ReadObjectId();
     ObjectRole      = (ObjectRole)reader.ReadByte();
 }
Esempio n. 7
0
        public static Character ReadSpawnData(NetBuffer inc, bool spawn = true)
        {
            DebugConsole.NewMessage("READING CHARACTER SPAWN DATA", Color.Cyan);

            if (GameMain.Server != null)
            {
                return(null);
            }

            bool   noInfo     = inc.ReadBoolean();
            ushort id         = inc.ReadUInt16();
            string configPath = inc.ReadString();

            Vector2 position = new Vector2(inc.ReadFloat(), inc.ReadFloat());

            bool enabled = inc.ReadBoolean();

            DebugConsole.Log("Received spawn data for " + configPath);

            Character character = null;

            if (noInfo)
            {
                if (!spawn)
                {
                    return(null);
                }

                character    = Character.Create(configPath, position, null, true);
                character.ID = id;
            }
            else
            {
                bool hasOwner = inc.ReadBoolean();
                int  ownerId  = hasOwner ? inc.ReadByte() : -1;


                string newName = inc.ReadString();
                byte   teamID  = inc.ReadByte();

                bool   hasAi        = inc.ReadBoolean();
                bool   isFemale     = inc.ReadBoolean();
                int    headSpriteID = inc.ReadByte();
                string jobName      = inc.ReadString();

                JobPrefab jobPrefab = null;
                Dictionary <string, int> skillLevels = new Dictionary <string, int>();
                if (!string.IsNullOrEmpty(jobName))
                {
                    jobPrefab = JobPrefab.List.Find(jp => jp.Name == jobName);
                    int skillCount = inc.ReadByte();
                    for (int i = 0; i < skillCount; i++)
                    {
                        string skillName  = inc.ReadString();
                        int    skillLevel = inc.ReadRangedInteger(0, 100);

                        skillLevels.Add(skillName, skillLevel);
                    }
                }

                if (!spawn)
                {
                    return(null);
                }


                CharacterInfo ch = new CharacterInfo(configPath, newName, isFemale ? Gender.Female : Gender.Male, jobPrefab);
                ch.HeadSpriteId = headSpriteID;

                System.Diagnostics.Debug.Assert(skillLevels.Count == ch.Job.Skills.Count);
                if (ch.Job != null)
                {
                    foreach (KeyValuePair <string, int> skill in skillLevels)
                    {
                        Skill matchingSkill = ch.Job.Skills.Find(s => s.Name == skill.Key);
                        if (matchingSkill == null)
                        {
                            DebugConsole.ThrowError("Skill \"" + skill.Key + "\" not found in character \"" + newName + "\"");
                            continue;
                        }
                        matchingSkill.Level = skill.Value;
                    }
                }

                character        = Create(configPath, position, ch, GameMain.Client.ID != ownerId, hasAi);
                character.ID     = id;
                character.TeamID = teamID;

                if (GameMain.Client.ID == ownerId)
                {
                    GameMain.Client.Character = character;
                    Controlled = character;

                    GameMain.LightManager.LosEnabled = true;

                    character.memInput.Clear();
                    character.memState.Clear();
                    character.memLocalState.Clear();
                }
                else
                {
                    var ownerClient = GameMain.Client.ConnectedClients.Find(c => c.ID == ownerId);
                    if (ownerClient != null)
                    {
                        ownerClient.Character = character;
                    }
                }

                if (configPath == Character.HumanConfigFile)
                {
                    GameMain.GameSession.CrewManager.AddCharacter(character);
                }
            }

            character.Enabled = Controlled == character || enabled;

            return(character);
        }
        public NetworkMasterMessage(NetBuffer buffer)
        {
            stream = new BitStream(buffer, false);

            internCode = (InternalCode)buffer.ReadByte();
        }
Esempio n. 9
0
        private void ReadStatus(NetBuffer msg)
        {
            if (GameMain.Server != null)
            {
                DebugConsole.ThrowError("Server attempted to read character status from a networked message");
                return;
            }

            bool isDead = msg.ReadBoolean();

            if (isDead)
            {
                causeOfDeath = (CauseOfDeath)msg.ReadByte();
                byte severedLimbCount = msg.ReadByte();
                if (causeOfDeath == CauseOfDeath.Pressure)
                {
                    Implode(true);
                }
                else
                {
                    Kill(causeOfDeath, true);
                }
                for (int i = 0; i < severedLimbCount; i++)
                {
                    int severedJointIndex = msg.ReadByte();
                    AnimController.SeverLimbJoint(AnimController.LimbJoints[severedJointIndex]);
                }
            }
            else
            {
                health = msg.ReadRangedSingle(minHealth, maxHealth, 8);

                bool lowOxygen = msg.ReadBoolean();
                if (lowOxygen)
                {
                    Oxygen = msg.ReadRangedSingle(-100.0f, 100.0f, 8);
                }
                else
                {
                    Oxygen = 100.0f;
                }

                bool isBleeding = msg.ReadBoolean();
                if (isBleeding)
                {
                    bleeding = msg.ReadRangedSingle(0.0f, 5.0f, 8);
                }
                else
                {
                    bleeding = 0.0f;
                }

                bool stunned = msg.ReadBoolean();
                if (stunned)
                {
                    float newStunTimer = msg.ReadRangedSingle(0.0f, 60.0f, 8);
                    SetStun(newStunTimer, true, true);
                }
                else
                {
                    SetStun(0.0f, true, true);
                }

                bool huskInfected = msg.ReadBoolean();
                if (huskInfected)
                {
                    HuskInfectionState = Math.Max(HuskInfectionState, 0.01f);
                }
                else
                {
                    HuskInfectionState = 0.0f;
                }
            }
        }
Esempio n. 10
0
        private bool ReceiveUserMessage(NetBuffer msg, NetworkMachine originMachine)
        {
            byte            senderId, recipientId;
            SendDataOptions options;
            int             length;
            Packet          packet;

            try
            {
                senderId    = msg.ReadByte();
                recipientId = msg.ReadByte();
                options     = (SendDataOptions)msg.ReadByte();
                length      = msg.ReadInt32();
                packet      = packetPool.Get(length); // Critical TODO: Protect memory
                msg.ReadBytes(packet.data, 0, length);
            }
            catch
            {
                return(false);
            }
            bool sendToAll = recipientId == 255;

            if (senderId == 255)
            {
                return(false);
            }
            var sender = gamerFromId.ContainsKey(senderId) ? gamerFromId[senderId] : null; // Sender can be null if gamer joined not yet received

            if (sender != null && sender.machine != originMachine)
            {
                return(false);
            }
            if (!IsSendDataOptionsValid(options))
            {
                return(false);
            }

            if (sendToAll)
            {
                bool firstGamer = true;
                foreach (var localGamer in localGamers)
                {
                    var uniquePacket = firstGamer ? packet : packetPool.GetAndFillWith(packet.data);
                    if (!localGamer.AddInboundPacket(uniquePacket, senderId, options))
                    {
                        // TODO: Kick machine if host?
                        Debug.WriteLine("MaxDelayedInboundPacketsAllowed reached!");
                        return(false);
                    }
                    firstGamer = false;
                }
                return(true);
            }
            else
            {
                var recipient = FindGamerById(recipientId);
                if (recipient == null)
                {
                    // TODO: Check if recipient is on list of previous gamers, for now assume true
                    bool previousGamer = true;

                    // Message is ok if the recipient was a gamer previously
                    return(previousGamer);
                }

                var localGamer = recipient as LocalNetworkGamer;
                if (localGamer == null)
                {
                    if (isHost)
                    {
                        // The message is meant for someone else (return true so that the message is forwarded)
                        return(true);
                    }
                    else
                    {
                        // The message is meant for us but the local gamer is gone? The host made a mistake or our local gamer left, see above
                        bool previousLocalGamer = true;
                        return(previousLocalGamer);
                    }
                }

                if (!localGamer.AddInboundPacket(packet, senderId, options))
                {
                    // TODO: Kick machine if host?
                    Debug.WriteLine("MaxDelayedInboundPacketsAllowed reached!");
                    return(false);
                }
                return(true);
            }
        }
Esempio n. 11
0
        private bool ReceiveGamerJoined(NetBuffer msg, NetworkMachine originMachine, NetworkMachine recipientMachine)
        {
            byte   id;
            string displayName, gamertag;
            bool   isPrivateSlot, isReady;

            try
            {
                id            = msg.ReadByte();
                displayName   = msg.ReadString();
                gamertag      = msg.ReadString();
                isPrivateSlot = msg.ReadBoolean();
                isReady       = msg.ReadBoolean();
            }
            catch
            {
                return(false);
            }
            if (id == 255)
            {
                return(false);
            }

            if (originMachine.isLocal)
            {
                // Already added local gamer
                return(true);
            }

            if (isHost)
            {
                if (!gamerFromId.ContainsKey(id))
                {
                    // Host must know about all gamers
                    return(false);
                }
                if (id == 0)
                {
                    // Someone is impersonating the host gamer
                    return(false);
                }

                if (recipientMachine == null || recipientMachine == localMachine)
                {
                    // Host already added gamer, just update it and add it to the game
                    var gamer = gamerFromId[id];
                    if (gamer.state != NetworkGamerState.Pending)
                    {
                        return(false);
                    }

                    gamer.DisplayName   = displayName;
                    gamer.Gamertag      = gamertag;
                    gamer.isPrivateSlot = isPrivateSlot;
                    gamer.isReady       = isReady;
                    AddGamer(gamer);
                }
                else
                {
                    // TODO: Make sure client is not spamming recipient
                }
            }
            else
            {
                if (id == 0)
                {
                    // Special case for host gamer
                    if (!originMachine.isHost)
                    {
                        return(false);
                    }

                    // Already added host gamer with id 0, just update it
                    Host.DisplayName   = displayName;
                    Host.Gamertag      = gamertag;
                    Host.isPrivateSlot = isPrivateSlot;
                    Host.isReady       = isReady;
                }
                else
                {
                    AddGamer(new NetworkGamer(originMachine, id, isPrivateSlot, isReady, displayName, gamertag));
                }
            }
            return(true);
        }
Esempio n. 12
0
        private void ReceiveMessage(NetBuffer msg, NetDeliveryMethod deliveryMethod, NetworkMachine senderMachine)
        {
            // Decode header
            if (msg.LengthBytes < 3)
            {
                // TODO: Kick machine?
                Debug.Write("Received empty message from machine " + senderMachine.id);
                return;
            }

            //ushort header0, header1;
            byte headerMsgType, headerRecipientId, headerOriginId;

            try
            {
                headerMsgType     = msg.ReadByte();
                headerRecipientId = msg.ReadByte();
                headerOriginId    = msg.ReadByte();
            }
            catch
            {
                // TODO: Kick machine?
                Debug.WriteLine("Received message with malformed header from machine " + senderMachine.id);
                return;
            }
            if (headerMsgType >= MessageTypeCount)
            {
                // TODO: Kick machine?
                Debug.WriteLine("Received message with malformed header from machine " + senderMachine.id);
                return;
            }

            MessageType msgType   = (MessageType)headerMsgType;
            bool        sendToAll = headerRecipientId == 255;

            if ((!sendToAll && !machineFromId.ContainsKey(headerRecipientId)) || !machineFromId.ContainsKey(headerOriginId))
            {
                if (isHost)
                {
                    // TODO: Kick machine?
                    Debug.WriteLine("Received message with malformed header from machine " + senderMachine.id);
                }
                return;
            }

            var recipientMachine = sendToAll ? null : machineFromId[headerRecipientId];
            var originMachine    = machineFromId[headerOriginId];

            if (isHost && senderMachine != originMachine)
            {
                // TODO: Kick machine?
                Debug.WriteLine("Received message with malformed header from machine " + senderMachine.id);
                return;
            }

            if (msgType != MessageType.User)
            {
                Debug.WriteLine("R " + senderMachine.id + "(" + originMachine.id + ")->" + (recipientMachine != null ? recipientMachine.id.ToString() : "[all]") + " " + msgType);
            }

            // Handle message
            bool success = false;

            switch (msgType)
            {
            case MessageType.SessionStateChanged:
                success = ReceiveSessionStateChanged(msg, originMachine);
                break;

            case MessageType.MachineConnected:
                success = ReceiveMachineConnectedMessage(msg, originMachine);
                break;

            case MessageType.MachineDisconnected:
                success = ReceiveMachineDisconnectedMessage(msg, originMachine);
                break;

            case MessageType.GamerIdRequest:
                success = ReceiveGamerIdRequest(msg, originMachine);
                break;

            case MessageType.GamerIdResponse:
                success = ReceiveGamerIdResponse(msg, originMachine);
                break;

            case MessageType.GamerJoined:
                success = ReceiveGamerJoined(msg, originMachine, recipientMachine);
                break;

            case MessageType.GamerLeft:
                success = ReceiveGamerLeft(msg, originMachine);
                break;

            case MessageType.GamerStateChanged:
                success = ReceiveGamerStateChanged(msg, originMachine);
                break;

            case MessageType.ResetReady:
                success = ReceiveResetReady(msg, originMachine);
                break;

            case MessageType.StartGame:
                success = ReceiveStartGame(msg, originMachine);
                break;

            case MessageType.EndGame:
                success = ReceiveEndGame(msg, originMachine);
                break;

            case MessageType.User:
                success = ReceiveUserMessage(msg, originMachine);
                break;

            default:
                throw new NotImplementedException();
            }

            if (!success)
            {
                // TODO: Kick machine if host and disconnect if client?
                Debug.WriteLine("Failed to parse last message!");
                return;
            }

            // If host, forward message to peers
            if (isHost && senderMachine != localMachine && recipientMachine != localMachine)
            {
                if (msgType != MessageType.User)
                {
                    Debug.WriteLine("Forwarding " + msgType + " message to machine " + (recipientMachine != null ? recipientMachine.id.ToString() : "[all]"));
                }

                SendMessage(CreateMessageFrom(msg), deliveryMethod, ignoreSelf: true);
            }
        }