예제 #1
0
        /// <summary>
        /// Adds a packet to the queue for serial processing.
        /// </summary>
        /// <param name="con">the connection which sent the packet</param>
        /// <param name="msg">the packet</param>
        public void AddGamePacketForProcessing(GSLobbyInboundPlayerConnection con, PacketGameMessage msg)
        {
            Action <object> lambda = (state) =>
            {
                Action <ServerUser, PacketGameMessage> handler = m_PacketHandlers.GetHandlerDelegate(msg.PacketSubTypeID);
                if (handler != null && OnBeforeHandleGamePacket(con.ServerUser, msg))
                {
                    try
                    {
                        handler(con.ServerUser, msg);
                    }
                    catch (Exception e)
                    {
                        Log.LogMsg("Exception thrown whilst processing game packet type " + msg.PacketTypeID.ToString() + ", sub-type " + msg.PacketSubTypeID + ". Object = " + this.GetType().ToString() + ", Message: " + e.Message + ". Stack:\r\n " + e.StackTrace);
                    }

                    con.OnAfterPacketProcessed(msg);
                    return;
                }
                con.KillConnection("Did not have a registered game packet handler for game packet. " + msg.PacketTypeID.ToString() + ", SubType " + msg.PacketSubTypeID.ToString() + ". ");
            };

            // if we're not processing packets immediately, then this method (AddGamePacketForProcessing) is being called as part of  a tight networking processing loop
            // which is executed serially, so we need to NOT queue the packet in that case and just run it
            if (!con.ProcessIncomingPacketsImmediately)
            {
                lambda(null);
            }
            else
            {
                Task t = new Task(lambda, "Game [" + GameID.ToString() + "] Process game packet " + msg.PacketSubTypeID.ToString(), TaskCreationOptions.LongRunning);
                m_NetQ.AddTask(t);
            }
        }
예제 #2
0
        /// <summary>
        /// Gets called when a player is removed from the game
        /// </summary>
        /// <param name="character"></param>
        protected virtual void OnPlayerRemoved(ServerCharacterInfo toon, string reason, bool playerInitiated)
        {
            toon.SetCurrentGame(null);

            // Update game stats in game listing DB
            DB.Instance.Lobby_UpdateGameForServer(this);

            // Send notification to player that player left, including game state update. Player is no longer part of "AllPlayers"  list at this point, so we
            // have to manually send this notification to them.
            SendGamePropertiesUpdateToPlayer(toon, this.Properties.ID, this.Properties.AllProperties);
            SendMatchChangeNotificationToPlayer(toon, MatchNotificationType.PlayerRemoved, toon, reason, false);

            // Broadcast to all remaining players
            SendMatchChangeNotificationToPlayers(MatchNotificationType.PlayerRemoved, toon, reason, false);
            SendGamePropertiesUpdateToPlayers(this.Properties.ID, this.Properties.AllProperties);

            // Set new game owner if necessary
            if (Owner == toon.ID)
            {
                if (AllPlayers.Count > 0)
                {
                    Owner = AllPlayers[0].ID;
                    BroadcastGameInfoMessage(AllPlayers[0].CharacterName + " is now the owner of this game.", true);
                    PropertyBag props = new PropertyBag();
                    props.SetProperty("NewOwner", Owner);
                    BroadcastGameMessage((int)LobbyGameMessageSubType.NewOwner, props, true, false, false);
                }
            }

            // when a player leaves the game, they go back to Central
            if (CurrentGameState == GameState.Lobby || CurrentGameState == GameState.Started)
            {
                string address  = "";
                int    port     = 0;
                string serverId = "";
                if (!GSLobbyInboundPlayerConnection.GetCentralHandoffAddress(ref address, ref port, ref serverId))
                {
                    toon.OwningAccount.MyConnection.KillConnection("Unable to host player on this server.  No lobby server found to hand off too after leaving game.");
                    return;
                }
                toon.OwningAccount.TransferToServerUnassisted(address, port, Guid.Empty, "Lobby Server", serverId);
            }
        }
예제 #3
0
        /// <summary>
        /// Override from ServerBase, to make sure we create the proper connection object for inbound connections.
        /// If we don't override this method, a generic InboundConnection class will be instantiated.
        /// </summary>
        protected override InboundConnection CreateInboundConnection(Socket s, ServerBase server, int serviceID, bool isBlocking)
        {
            InboundConnection con = null;

            // ServiceIDs represents the type connection that is being requested.
            // these IDs are set in the App.Config of the initiating server and are any arbitrarily agreed upon integers
            switch (serviceID)
            {
            case 7:
                con           = new ZeusInboundConnection(s, server, isBlocking);
                con.ServiceID = serviceID;
                break;

            case 1:                     // central server
                con           = new GSLobbyInboundCentralConnection(s, server, isBlocking);
                con.ServiceID = serviceID;
                GameManager.Instance.CentralServer = con as GSInboundServerConnection;
                break;

            case 8:     // Beholder Daemon
                con           = new GSLobbyInboundBeholderConnection(s, server, isBlocking);
                con.ServiceID = 8;
                break;

            default:                     // assume player client
                con           = new GSLobbyInboundPlayerConnection(s, server, isBlocking);
                con.ServiceID = serviceID;
                break;
            }

#if DEBUG
            if (con == null)
            {
                throw new ArgumentOutOfRangeException("ServiceID " + serviceID.ToString() + " is unknown to CreateInboundConnection.  Cannot process connection.");
            }
#endif
            return(con);
        }
예제 #4
0
        /// <summary>
        /// Override from ServerBase, to make sure we create the proper connection object for inbound connections.
        /// If we don't override this method, a generic InboundConnection class will be instantiated.
        /// </summary>
        protected override InboundConnection CreateInboundConnection(Socket s, ServerBase server, int serviceID, bool isBlocking)
        {
            InboundConnection con = null;
            // ServiceIDs represents the type connection that is being requested.
            // these IDs are set in the App.Config of the initiating server and are any arbitrarily agreed upon integers
            switch (serviceID)
            {
                case 7:
                    con = new ZeusInboundConnection(s, server, isBlocking);
                    con.ServiceID = serviceID;
                    break;
                case 1: // central server
                    con = new GSLobbyInboundCentralConnection(s, server, isBlocking);
                    con.ServiceID = serviceID;
                    GameManager.Instance.CentralServer = con as GSInboundServerConnection;
                    break;
                case 8: // Beholder Daemon
                    con = new GSLobbyInboundBeholderConnection(s, server, isBlocking);
                    con.ServiceID = 8;
                    break;
                default: // assume player client
                    con = new GSLobbyInboundPlayerConnection(s, server, isBlocking);
                    con.ServiceID = serviceID;
                    break;
            }

            #if DEBUG
            if (con == null)
            {
                throw new ArgumentOutOfRangeException("ServiceID " + serviceID.ToString() + " is unknown to CreateInboundConnection.  Cannot process connection.");
            }
            #endif
            return con;
        }