Пример #1
0
 public MSCPacket(MenuState s)
 {
     this.ptype = PacketType.MSC;
     this.addHeader(ptype);
     this.addContent(s.getPacketData());
     this.finalize();
 }
        /// <summary>
        /// Event handler for when the Play Game menu entry is selected.
        /// </summary>
        void StartGameMenuEntrySelected(object sender, PlayerInputEventArgs e)
        {
            if (e.MenuAccept) // Handle character selection and game starting
            {
                if (!characterSelectionsLocked[playerId]) // Unlock a player
                {
                    characterSelectionsLocked[playerId] = true;
                    if (multiplayer) // Only broadcast in multiplayer mode
                    {
                        if (host) // Broadcast lock changes to all players
                        {
                            HostBroadcastLocks();
                        }
                        else // Inform the host of a lock change
                        {
                            MenuState lockPacket = new MenuState(MenuState.Type.LockCharacter, playerId, (int)MenuState.LockCharacterDetails.Locked);
                            ((ProjectSkyCrane)ScreenManager.Game).RawClient.sendMSC(lockPacket);
                        }
                    }
                }
                else if (host && AllLocked())
                {
                    if (multiplayer) // Only broadcast in multiplayer mode
                    {
                        HostBroadcastGameStart();
                    }
                    LoadingScreen.Load(ScreenManager, false, new GameplayScreen(host, multiplayer, NumConnectedPlayers(), playerId, characterSelections, playerIdToConnectionHash));
                }
                menuSelectSoundEffect.Play();
            }
            else if (!characterSelectionsLocked[playerId] && e.ToggleDirection != 0) // Do some toggling of character selections
            {
                characterSelections[playerId] += e.ToggleDirection;
                if (characterSelections[playerId] < 0)
                {
                    characterSelections[playerId] = (PlayerCharacter.Type)(characters.Length - 1);
                }
                else if ((int)characterSelections[playerId] >= characters.Length)
                {
                    characterSelections[playerId] = 0;
                }

                if (multiplayer) // Only broadcast in multiplayer mode
                {
                    if (host) // Broadcast sprite changes to all players
                    {
                        HostBroadcastSprites();
                    }
                    else // Inform the host of a sprite change
                    {
                        MenuState spritePacket = new MenuState(MenuState.Type.SelectCharacter, playerId, (int)characterSelections[playerId]);
                        ((ProjectSkyCrane)ScreenManager.Game).RawClient.sendMSC(spritePacket);
                    }
                }

                menuScrollSoundEffect.Play();
            }

            return;
        }
 /// <summary>
 /// Have the host broadcast which characters are and aren't connected.
 /// </summary>
 private void HostBroadcastSprites()
 {
     MenuState spriteBroadcast = new MenuState(MenuState.Type.SelectCharacter);
     for (int i = 0; i < playersConnected.Length; i += 1) // Loop over and broadcast the sprites of all connected players
     {
         if (playersConnected[i])
         {
             spriteBroadcast.PlayerId = i;
             spriteBroadcast.EventDetail = (int)characterSelections[i];
             ((ProjectSkyCrane)ScreenManager.Game).RawServer.broadcastMSC(spriteBroadcast);
         }
     }
     return;
 }
 /// <summary>
 /// Have the host broadcast which characters are and aren't locked.
 /// </summary>
 private void HostBroadcastLocks()
 {
     MenuState lockedBroadcast = new MenuState(MenuState.Type.LockCharacter);
     for (int i = 0; i < playersConnected.Length; i += 1) // Loop over and broadcast the locks of all connected players
     {
         if (playersConnected[i])
         {
             lockedBroadcast.PlayerId = i;
             if (characterSelectionsLocked[i])
             {
                 lockedBroadcast.EventDetail = (int)MenuState.LockCharacterDetails.Locked;
             }
             else
             {
                 lockedBroadcast.EventDetail = (int)MenuState.LockCharacterDetails.Unlocked;
             }
             ((ProjectSkyCrane)ScreenManager.Game).RawServer.broadcastMSC(lockedBroadcast);
         }
     }
     return;
 }
 /// <summary>
 /// Have the host broadcast that the game has started.
 /// </summary>
 private void HostBroadcastGameStart()
 {
     MenuState startBroadcast = new MenuState(MenuState.Type.GameStart);
     for (int i = 0; i < playersConnected.Length; i += 1) // Loop over and inform everyone the game is beginning
     {
         if (playersConnected[i])
         {
             ((ProjectSkyCrane)ScreenManager.Game).RawServer.broadcastMSC(startBroadcast);
         }
     }
     return;
 }
 /// <summary>
 /// Have the host broadcast which players are and aren't connected.
 /// </summary>
 private void HostBroadcastConnected()
 {
     MenuState connectBroadcast = new MenuState(MenuState.Type.Connect);
     for (int i = 0; i < playersConnected.Length; i += 1)
     {
         connectBroadcast.PlayerId = i;
         if (playersConnected[i]) // Broadcast 1 to show connected
         {
             connectBroadcast.EventDetail = (int)MenuState.ConnectionDetails.Connected;
         }
         else // Broadcast -1 to show not connected
         {
             connectBroadcast.EventDetail = (int)MenuState.ConnectionDetails.Disconnected;
         }
         ((ProjectSkyCrane)ScreenManager.Game).RawServer.broadcastMSC(connectBroadcast);
     }
     return;
 }
 /// <summary>
 /// A player has hit cancel while browsing characters.
 /// </summary>
 protected override void OnCancel()
 {
     if (!characterSelectionsLocked[playerId])
     {
         if (multiplayer) // Only broadcast in multiplayer mode
         {
             playersConnected[playerId] = false;
             if (host) // Broadcast disconnect of host to all players
             {
                 HostBroadcastConnected();
             }
             else // Inform the host of a disconnect
             {
                 MenuState disconnectPacket = new MenuState(MenuState.Type.Connect, playerId, (int)MenuState.ConnectionDetails.Disconnected);
                 ((ProjectSkyCrane)ScreenManager.Game).RawClient.sendMSC(disconnectPacket);
             }
         }
         base.OnCancel();
     }
     else // Unlock a character selection
     {
         characterSelectionsLocked[playerId] = false;
         if (multiplayer) // Only broadcast in multiplayer mode
         {
             if (host) // Broadcast lock changes to all players
             {
                 HostBroadcastLocks();
             }
             else // Inform the host of a lock change
             {
                 MenuState unlockPacket = new MenuState(MenuState.Type.LockCharacter, playerId, (int)MenuState.LockCharacterDetails.Unlocked);
                 ((ProjectSkyCrane)ScreenManager.Game).RawClient.sendMSC(unlockPacket);
             }
         }
     }
     return;
 }
 /// <summary>
 /// Run a regular update loop on the menu.
 /// </summary>
 public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
 {
     if (multiplayer) // Don't handle these cases in single player
     {
         if (host) // Have the host search for incoming client packets and respond to them
         {
             List<Tuple<ConnectionID, MenuState>> serverStates = ((ProjectSkyCrane)ScreenManager.Game).RawServer.getMSC();
             for (int i = 0; i < serverStates.Count; i++)
             {
                 switch (serverStates[i].Item2.MenuType)
                 {
                     case MenuState.Type.Connect: // Deal with connection and disconnections from the server
                         if (serverStates[i].Item2.EventDetail == (int)MenuState.ConnectionDetails.IdReqest) // Someone is requesting an id
                         {
                             int newId;
                             if (connectionToPlayerIdHash.ContainsKey(serverStates[i].Item1.ID)) // We've already seen this player and they haven't disconnected, resend their current id
                             {
                                 newId = connectionToPlayerIdHash[serverStates[i].Item1.ID];
                             }
                             else // Send the player a new id
                             {
                                 newId = hostIds.Dequeue();
                                 playersConnected[newId] = true;
                                 connectionToPlayerIdHash.Add(serverStates[i].Item1.ID, newId);
                                 playerIdToConnectionHash.Add(newId, serverStates[i].Item1);
                             }
                             MenuState connectResponse = new MenuState(MenuState.Type.Connect, newId, (int)MenuState.ConnectionDetails.IdReqest); // Inform connector of their Id
                             ((ProjectSkyCrane)ScreenManager.Game).RawServer.signalMSC(connectResponse, serverStates[i].Item1);
                             HostBroadcastConnected();
                             HostBroadcastSprites();
                             HostBroadcastLocks();
                         }
                         else if (serverStates[i].Item2.EventDetail == (int)MenuState.ConnectionDetails.Disconnected) // Someone is disconnecting
                         {
                             if (connectionToPlayerIdHash.ContainsKey(serverStates[i].Item1.ID)) // This is a known player based on their connection
                             {
                                 int requestingId = connectionToPlayerIdHash[serverStates[i].Item1.ID];
                                 if (requestingId == serverStates[i].Item2.PlayerId) // Prevent spoofing and sillyness
                                 {
                                     playersConnected[requestingId] = false;
                                     connectionToPlayerIdHash.Remove(serverStates[i].Item1.ID); // Remove connections from both hashes
                                     playerIdToConnectionHash.Remove(requestingId);
                                     hostIds.Enqueue(requestingId); // Allow the id to be re-used
                                     HostBroadcastConnected();
                                 }
                             }
                         }
                         break;
                     case MenuState.Type.SelectCharacter:
                         if (connectionToPlayerIdHash.ContainsKey(serverStates[i].Item1.ID)) // This is a known player based on their connection
                         {
                             int requestingId = connectionToPlayerIdHash[serverStates[i].Item1.ID];
                             if (requestingId == serverStates[i].Item2.PlayerId) // Prevent spoofing and sillyness
                             {
                                 characterSelections[requestingId] = (PlayerCharacter.Type)serverStates[i].Item2.EventDetail;
                                 HostBroadcastSprites();
                             }
                         }
                         break;
                     case MenuState.Type.LockCharacter:
                         if (connectionToPlayerIdHash.ContainsKey(serverStates[i].Item1.ID)) // Check for a known player based on connection
                         {
                             int requestingId = connectionToPlayerIdHash[serverStates[i].Item1.ID];
                             if (requestingId == serverStates[i].Item2.PlayerId) // Prevent spoofing and sillyness
                             {
                                 if (serverStates[i].Item2.EventDetail == (int)MenuState.LockCharacterDetails.Locked) // Locking a character in
                                 {
                                     characterSelectionsLocked[requestingId] = true;
                                 }
                                 else if (serverStates[i].Item2.EventDetail == (int)MenuState.LockCharacterDetails.Unlocked) // Unlocking a character
                                 {
                                     characterSelectionsLocked[requestingId] = false;
                                 }
                                 HostBroadcastLocks();
                             }
                         }
                         break;
                     case MenuState.Type.GameStart: // Don't do anything in this case, it's clearly a silly request
                         break;
                     default:
                         throw new ArgumentException();
                 }
             }
         }
         else // Handle authoritative updates from the server if we are a client
         {
             List<MenuState> clientStates = ((ProjectSkyCrane)ScreenManager.Game).RawClient.rcvMenuState();
             for (int i = 0; i < clientStates.Count; i++)
             {
                 switch (clientStates[i].MenuType)
                 {
                     case MenuState.Type.Connect: // Handle connection events
                         if (clientStates[i].EventDetail == (int)MenuState.ConnectionDetails.IdReqest) // Assign our own player id
                         {
                             playerId = clientStates[i].PlayerId;
                         }
                         else if (clientStates[i].EventDetail == (int)MenuState.ConnectionDetails.Connected) // Assign a connected player
                         {
                             playersConnected[clientStates[i].PlayerId] = true;
                         }
                         else if (clientStates[i].EventDetail == (int)MenuState.ConnectionDetails.Disconnected) // Note down that a player is no longer in the session
                         {
                             playersConnected[clientStates[i].PlayerId] = false;
                             // TODO: Handle the server disconnecting
                         }
                         break;
                     case MenuState.Type.SelectCharacter: // Handle character selection
                         characterSelections[clientStates[i].PlayerId] = (PlayerCharacter.Type)clientStates[i].EventDetail;
                         break;
                     case MenuState.Type.LockCharacter: // Handle character locking
                         if (clientStates[i].EventDetail == (int)MenuState.LockCharacterDetails.Locked)
                         {
                             characterSelectionsLocked[clientStates[i].PlayerId] = true;
                         }
                         else if (clientStates[i].EventDetail == (int)MenuState.LockCharacterDetails.Unlocked)
                         {
                             characterSelectionsLocked[clientStates[i].PlayerId] = false;
                         }
                         break;
                     case MenuState.Type.GameStart:
                         LoadingScreen.Load(ScreenManager, false, new GameplayScreen(host, multiplayer, NumConnectedPlayers(), playerId, characterSelections, null));
                         break;
                     default:
                         throw new ArgumentException();
                 }
             }
         }
     }
     base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
     return;
 }
        /// <summary>
        /// Loads graphics content for this screen. This uses the shared ContentManager
        /// provided by the Game class, so the content will remain loaded forever.
        /// Whenever a subsequent MessageBoxScreen tries to load this same content,
        /// it will just get back another reference to the already loaded data.
        /// </summary>
        public override void LoadContent()
        {
            if (!host && playerId < 0) // If we're not the host, ask for an id
            {
                MenuState connectPacket = new MenuState(MenuState.Type.Connect, 0, (int)MenuState.ConnectionDetails.IdReqest);
                ((ProjectSkyCrane)ScreenManager.Game).RawClient.sendMSC(connectPacket);
                playerId = -1;
            }

            ContentManager content = ScreenManager.Game.Content;

            // Dynamically load character types based on enum
            Array characterTypes = Enum.GetValues(typeof(PlayerCharacter.Type));
            characters = new Texture2D[characterTypes.Length];
            for (int i = 0; i < characters.Length; i += 1)
            {
                characters[i] = content.Load<Texture2D>("Sprites/" + characterTypes.GetValue(i));
            }

            aButtonTextured2D = content.Load<Texture2D>("XBox Buttons/button_a");
            bButtonTextured2D = content.Load<Texture2D>("XBox Buttons/button_b");
            dPadLeftTexture2D = content.Load<Texture2D>("XBox Buttons/dpad_left");
            dPadRightTexture2D = content.Load<Texture2D>("XBox Buttons/dpad_right");
            base.LoadContent();
            return;
        }
Пример #10
0
 public void broadcastMSC(MenuState m)
 {
     foreach (KeyValuePair<IPEndPoint, ConnectionID> d in connections)
     {
         //Console.WriteLine("Server - Sent MenuState to: " + d.Value.ID);
         MSCPacket p = new MSCPacket(m);
         p.Dest = d.Key;
         this.nw.commitPacket(p);
     }
     return;
 }
Пример #11
0
        private void runThis()
        {
            Packet p;
            while (this.go)
            {
                p = nw.getNext();
                if (p == null)
                {
                    foreach (IPEndPoint ep in connections.Keys)
                    {
                        SYNCPacket ps = new SYNCPacket();
                        ps.Dest = ep;
                        this.nw.commitPacket(ps);
                    }
                    continue;
                }
                //Console.WriteLine(p.ptype);

                switch (p.ptype)
                {
                    case Packet.PacketType.HANDSHAKE:
                        if (!connections.ContainsKey(p.Dest))
                        {
                            Console.WriteLine("Server - New connection from: " + p.Dest);
                            connections[p.Dest] = new ConnectionID(p.Dest);
                            Console.WriteLine("Server - Added Connection: " + connections[p.Dest].ID);
                            HandshakePacket hs = new HandshakePacket();
                            hs.Dest = p.Dest;
                            nw.commitPacket(hs);
                        }
                        break;

                    case Packet.PacketType.STC:
                        //Console.WriteLine("Server - Receivd State Change from client... who do they think they are?");
                        Environment.Exit(1);
                        break;

                    case Packet.PacketType.SYNC:
                        if (connections.ContainsKey(p.Dest))
                        {
                            //Console.WriteLine("Server - SYNC Reply from: " + connections[p.Dest].ID);
                        }
                        else
                        {
                            Console.WriteLine("Server - ERROR Unregistered SYNC");
                        }
                        break;

                    case Packet.PacketType.PING:
                        if (connections.ContainsKey(p.Dest))
                        {
                            //Console.WriteLine("Server - Ping from connection: " + connections[p.Dest].ID);
                            PingPacket ps = new PingPacket();
                            ps.Dest = p.Dest;
                            nw.commitPacket(ps); //ACK the ping
                        }
                        else
                        {
                            Console.WriteLine("Server ERROR - Unregistered PING");
                        }
                        break;

                    case Packet.PacketType.CMD:
                        //Actually handle this
                        //Console.WriteLine("Server - Got CMD from: " + connections[p.Dest].ID);
                        Command cmd = new Command(p.data);
                        lock (commandQ)
                            this.commandQ.Add(cmd);
                        break;
                    case Packet.PacketType.MSC:
                        //Actually handle this
                        //Console.WriteLine("Server - Got MSC from: " + connections[p.Dest].ID);
                        MenuState msc = new MenuState(p.data);
                        if (connections.ContainsKey(p.Dest))
                        {
                            ConnectionID cid = connections[p.Dest];
                            Tuple<ConnectionID, MenuState> newMQ = new Tuple<ConnectionID, MenuState>(cid, msc);
                            lock (mscQ)
                                this.mscQ.Enqueue(newMQ);
                        }
                        break;
                }
                this.globalStats.rcvdPkts++;
            }
        }
Пример #12
0
 public void signalMSC(MenuState m, ConnectionID cid)
 {
     MSCPacket p = new MSCPacket(m);
     p.Dest = cid.endpt;
     nw.commitPacket(p);
 }
Пример #13
0
        //Main routine, this does all the processing
        private void ClientstartFunc()
        {
            // Hold here until the server information has been provided
            ready.WaitOne();

            // Event Loop
            // Pull packets out of the network layer and handle them
            while (this.go)
            {
                Packet newPacket = nw.getNext(); // This is a blocking call!

                // Handle timeout
                if (newPacket == null)
                {
                    Console.WriteLine("Timeout on receive");
                    switch (curState)
                    {
                        case cState.TRYCONNECT:
                            // Did not receive the expected HANDSHAKE message
                            // Restart the handshake
                            this.handshake();
                            break;
                        case cState.CONNECTED:
                            // The server may have died, ping the server to find out
                            //this.pingServer();
                   //TODO Should probably not silently ignore this....
                            lock (this)
                            {
                                if (this.sw_ping.IsRunning)
                                {
                                    //this.curState = cState.DISCONNECTED;
                                    this.sw_ping.Stop();
                                    this.lastPing = 501;
                                }
                            }
                            break;
                        case cState.DISCONNECTED:
                        default:
                            // This should not happen, die screaming!
                            Environment.Exit(1);
                            break;
                    }
                }
                else
                {
                    //Console.Write("Received packet of type: ");
                    //Console.WriteLine(newPacket.ptype);

                    // Handle the new packet
                    switch (newPacket.ptype)
                    {
                        case Packet.PacketType.CMD:
                            Console.WriteLine("Should not be getting CMD packets from the server...");
                            Environment.Exit(1);
                            break;
                        case Packet.PacketType.HANDSHAKE:
                            Console.WriteLine("Handshake received from the server");

                            switch (curState)
                            {
                                case cState.TRYCONNECT:
                                    // The connection has succeeded!
                                    this.startPing();
                                    this.curState = cState.CONNECTED;
                                    break;
                                case cState.CONNECTED:
                                    // Repeat? This can be ignored ( I hope...)
                                    break;
                                case cState.DISCONNECTED:
                                default:
                                    // This should not happen, die screaming!
                                    Environment.Exit(1);
                                    break;
                            }

                            break;
                        case Packet.PacketType.STC:
                            //Console.WriteLine("STC received from the server");

                            switch (curState)
                            {
                                case cState.TRYCONNECT:
                                    break;
                                case cState.CONNECTED:
                                    // Marshall the state change packet into an object
                                    StateChange newSTC = new StateChange(newPacket.data);

                                    // Add the state change object to the buffer for the UI
                                    lock (this.buffer)
                                    {
                                        buffer.Enqueue(newSTC);
                                    }

                                    break;
                                case cState.DISCONNECTED:
                                default:
                                    // This should not happen, die screaming!
                                    Environment.Exit(1);
                                    break;
                            }

                            break;
                        case Packet.PacketType.MSC:
                            //Console.WriteLine("MSC received from the server");

                            switch (curState)
                            {
                                case cState.TRYCONNECT:
                                    break;
                                case cState.CONNECTED:
                                    // Marshall the state change packet into an object
                                    MenuState newMSC = new MenuState(newPacket.data);

                                    // Add the state change object to the buffer for the UI
                                    lock (this.menuBuffer)
                                    {
                                        menuBuffer.Enqueue(newMSC);
                                    }

                                    break;
                                case cState.DISCONNECTED:
                                default:
                                    // This should not happen, die screaming!
                                    Environment.Exit(1);
                                    break;
                            }

                            break;
                        case Packet.PacketType.SYNC:
                            //Console.WriteLine("SYNC received from the server");

                            switch (curState)
                            {
                                case cState.TRYCONNECT:
                                    break;
                                case cState.CONNECTED:
                                    syncServer();
                                    break;
                                case cState.DISCONNECTED:
                                default:
                                    // This should not happen, die screaming!
                                    Environment.Exit(1);
                                    break;
                            }

                            break;
                        case Packet.PacketType.PING:
                            //Console.WriteLine("PING received from the server");

                            switch (curState)
                            {
                                case cState.TRYCONNECT:
                                    break;
                                case cState.CONNECTED:
                                    lock (this)
                                    {
                                        sw_ping.Stop();
                                        this.lastPing = sw_ping.ElapsedMilliseconds;
                                    }
                                    //Console.WriteLine("Ping"+lastPing);
                                    break;
                                case cState.DISCONNECTED:
                                default:
                                    // This should not happen, die screaming!
                                    Environment.Exit(1);
                                    break;
                            }

                            break;
                        default:
                            Console.WriteLine("Unknown packet type from the server...");
                            Environment.Exit(1);
                            break;
                    }
                }
            }
        }
Пример #14
0
        public void sendMSC(MenuState m)
        {
            // Create the MSC Packet
            MSCPacket newMSC = new MSCPacket(m);
            newMSC.Dest = server;

            // Add the MSC packe to the network worker's send queue
            this.nw.commitPacket(newMSC);
        }