示例#1
0
        /// <summary>
        /// Removes a match from the list of games that a particular server is tracking - GamesPerServerMap
        /// </summary>
        /// <param name="serverName">the server to remove this game from</param>
        /// <param name="id">the id of the game to remove</param>
        /// <param name="lockData">if the match data should be thread-synchronized.  set yes, if you know this method is called first in the stack (i.e. when you're calling it as a response to an inbound packet). Using the wrong will value will decrease performance as unnecessary thread Monitors will be set</param>
        public void RemoveGameFromServerTracking(Guid id, bool lockData)
        {
            if (lockData)
            {
                Monitor.Enter(MatchDataLock);
            }

            try
            {
                DB.Instance.Lobby_UntrackGameForServer(id);
                GameServerGame sg = null;
                if (Games.TryGetValue(id, out sg))
                {
                    if (Games.Remove(id))
                    {
                        Log1.Logger("Server").Info("Removed game [" + id.ToString() + "] from server. Now tracking [" + Games.Count.ToString() + " games] on this server.");
                    }

                    m_TotalProjectedPlayerCount -= sg.MaxObservers + sg.MaxPlayers;
                    Log1.Logger("Server").Debug("Padded connection count for server is now [" + m_TotalProjectedPlayerCount + "].");
                }
            }
            catch { }
            finally
            {
                if (lockData)
                {
                    Monitor.Exit(MatchDataLock);
                }
            }
        }
示例#2
0
        protected virtual GameServerGame OnCreateNewGameServerGame(Game game)
        {
            GameServerGame g = new GameServerGame(game);

            game.Decorator = g;
            return(g);
        }
示例#3
0
 /// <summary>
 /// Override HandlePacket because we dont want to incur multiple Hashtable looks for game packets
 /// </summary>
 /// <param name="p"></param>
 protected override void HandlePacket(Packet p)
 {
     if (p.PacketTypeID == (int)LobbyPacketType.GameMessage)
     {
         try
         {
             GameServerGame g = ServerUser.CurrentCharacter.GetCurrentGame();
             if (g == null)
             {
                 // drop the packet
                 return;
             }
             g.AddGamePacketForProcessing(this, p as PacketGameMessage);
         }
         catch
         {
             // something went wrong. drop packet.
             return;
         }
     }
     else
     {
         base.HandlePacket(p);
     }
 }
示例#4
0
        public void OnPlayerLeaveGame(INetworkConnection sender, Packet gmsg)
        {
            PacketGenericMessage msg = gmsg as PacketGenericMessage;
            GameServerGame       g   = ServerUser.CurrentCharacter.GetCurrentGame();

            if (g != null)
            {
                g.RemovePlayer(ServerUser.CurrentCharacter, "left the game.", true);
                g.RemoveObserver(ServerUser.CurrentCharacter);
            }
        }
示例#5
0
        /// <summary>
        /// Adds a match to the GamesPerServerMap list of games that a particular server is tracking
        /// </summary>
        /// <param name="serverName">the name of the server to register this game under</param>
        /// <param name="game">the game to register</param>
        /// <param name="lockData">if the match data should be thread-synchronized.  set yes, if you know this method is called first in the stack (i.e. when you're calling it as a response to an inbound packet). Using the wrong will value will decrease performance as unnecessary thread Monitors will be set</param>
        public bool CreateNewGame(GameServerGame game, bool lockData)
        {
            if (lockData)
            {
                Monitor.Enter(MatchDataLock);
            }

            try
            {
                if (GameCreationRequest != null)
                {
                    if (!GameCreationRequest(game))
                    {
                        return(false);
                    }
                }
                if (Games.ContainsKey(game.GameID))
                {
                    // hm. we already know about that game.  probably not great.
#if DEBUG
                    throw new ArgumentException("Tried AddGameToServerTracking for a game that we alrady knew about.");
#endif
                    return(false);
                }

                Games.Add(game.GameID, game);
                m_TotalProjectedPlayerCount += (game.MaxPlayers + game.MaxObservers);
                Log1.Logger("Server").Debug("Padded connection count for server is now [" + m_TotalProjectedPlayerCount + "].");
                Log1.Logger("Server").Info("After adding this one, we are tracking [" + Games.Count.ToString() + " games] on this server now.");

                if (GameCreated != null)
                {
                    GameCreated(game);
                }
            }
            catch
            {
                return(false);
            }
            finally
            {
                if (lockData)
                {
                    Monitor.Exit(MatchDataLock);
                }
            }

            return(true);
        }
示例#6
0
        public void OnRequestStartGame(INetworkConnection sender, Packet gmsg)
        {
            PacketGenericMessage msg = gmsg as PacketGenericMessage;

            msg.ReplyPacket = CreateStandardReply(msg, ReplyType.Failure, "");
            try
            {
                GameServerGame game = ServerUser.CurrentCharacter.GetCurrentGame();
                if (!game.IsPlayerPartOfGame(ServerUser.CurrentCharacter.ID))
                {
                    KillConnection("Tried to send game packets to game that we're not part of any more.");
                    return;;
                }

                if (!game.GameStartStrategy.CanGameBeStartedManually)
                {
                    game.SendGameInfoMessageToPlayer(ServerUser.CurrentCharacter, "Game will be started automatically when ready.");
                    return;
                }

                if (!game.GameStartStrategy.DoesGameMeetStartConditions)
                {
                    game.SendGameInfoMessageToPlayer(ServerUser.CurrentCharacter, "Game can't be started yet.");
                    return;
                }

                if (game.Owner != ServerUser.CurrentCharacter.ID)
                {
                    // send a nag message
                    game.BroadcastGameInfoMessage(ServerUser.CurrentCharacter.CharacterName + " is requesting that we begin. Leader, please start game if ready.", true);
                    return;
                }

                string tmsg = "";
                if (!OnPlayerRequestStartGame(msg, ref tmsg) || !game.StartGame(ref tmsg, true))
                {
                    msg.ReplyPacket.ReplyMessage = tmsg;
                    return;
                }

                // if it succeeded, no need to send the reply packet as everyone will have received a game started message from game.StartGame()
                msg.NeedsReply = false;
            }
            catch (Exception e)
            {
                msg.ReplyPacket.ReplyMessage = "Unknown error occured OnRequestStartGame.";
                Log.LogMsg("[" + ServerUser.AccountName + "] failed to start game. " + e.Message);
            }
        }
示例#7
0
        protected override void OnSocketKilled(string msg)
        {
            if (ServerUser != null && ServerUser.CurrentCharacter != null)
            {
                GameServerGame gsg = ServerUser.CurrentCharacter.GetCurrentGame();
                if (gsg != null)
                {
                    gsg.RemovePlayer(ServerUser.CurrentCharacter, "Disconnected.", true);
                    gsg.RemoveObserver(ServerUser.CurrentCharacter);
                }

                CharacterCache.UncacheCharacter(ServerUser.CurrentCharacter.ID);
            }

            base.OnSocketKilled(msg);
            DB.Instance.Server_Register(MyServer.ServerUserID, MyServer.ServerAddress, MyServer.ListenOnPort, DateTime.UtcNow, "content", ConnectionManager.PaddedConnectionCount, MyServer.MaxConnections);
        }
示例#8
0
        public void SendMatchChangeNotificationToPlayers(MatchNotificationType kind, GameServerGame theGame, ServerCharacterInfo targetPlayer)
        {
            string text = "";

            switch (kind)
            {
            case MatchNotificationType.PlayerRemoved:
                text = "Goodbye, " + targetPlayer.CharacterName;
                break;

            case MatchNotificationType.PlayerAdded:
                text = "Welcome, " + targetPlayer.CharacterName;
                break;

            case MatchNotificationType.MatchEnded:
                text = "Game '" + theGame.Name + "' ended.";
                break;
            }

            theGame.SendMatchChangeNotificationToPlayers(kind, targetPlayer, text, false);
        }
示例#9
0
 /// <summary>
 /// Gets the game, if this server knows about, regardless if it's local or not
 /// </summary>
 /// <param name="game">the id of the game we want to fetch</param>
 /// <param name="sg">the game, if we found it</param>
 /// <returns>true if we know about the game, false otherwise</returns>
 public bool GetGame(Guid game, out GameServerGame sg)
 {
     return(Games.TryGetValue(game, out sg));
 }
示例#10
0
        protected override bool OnPlayerLoginResolved(PacketLoginRequest login, bool result, ref string msg)
        {
            ///.............
            if (!base.OnPlayerLoginResolved(login, result, ref msg))
            {
                return(result);
            }

            if (ServerUser.CurrentCharacter == null)
            {
                msg = "Can't join or create games without an active character.";
                return(false);
            }

            Guid                    gameId = Guid.Empty;
            GameServerGame          sg     = null;
            PacketMatchNotification note   = (PacketMatchNotification)CreatePacket((int)LobbyPacketType.MatchNotification, 0, false, false);

            // Requesting to join as observer?
            bool observeOnly = login.Parms.GetBoolProperty("Observe").GetValueOrDefault(false);

            if (login.Parms.GetBoolProperty("IsNewGame").GetValueOrDefault(false))
            {
                Log1.Logger("Server").Debug("Player [" + ServerUser.AccountName + "] logging in with NEW GAME request.");
                note.Kind       = MatchNotificationType.MatchCreated;
                note.NeedsReply = false;
                note.ReplyCode  = ReplyType.Failure;

                // new game. create it.
                Game g = new Game();
                g.Name         = login.Parms.GetStringProperty((int)PropertyID.Name);
                g.MaxPlayers   = login.Parms.GetIntProperty((int)PropertyID.MaxPlayers).GetValueOrDefault(1);
                g.MaxObservers = login.Parms.GetIntProperty((int)PropertyID.MaxObservers).GetValueOrDefault(0);
                g.Owner        = ServerUser.CurrentCharacter.ID;

                // Create the actual game object, specific to the game type we are serving.
                sg = OnCreateNewGameServerGame(g);
                //sg = null;

                if (sg != null)
                {
                    // Track the new game object on this server
                    if (!GameManager.Instance.CreateNewGame(sg, true))
                    {
                        msg = "Failed to create game on server.  Internal server error.";
                        note.ReplyMessage = msg;
                        Send(note);
                        TransferToLobbyOrDisconnect();
                        return(true);
                    }

                    // Report the new game in the database
                    if (!DB.Instance.Lobby_TrackGameForServer(MyServer.ServerUserID, sg, DateTime.UtcNow, ServerUser))
                    {
                        msg = "Failed to register the game in the database.  Internal server error.";
                        note.ReplyMessage = msg;
                        Send(note);
                        TransferToLobbyOrDisconnect();
                        return(true);
                    }

                    // Update player counts for this server, based on the expected player count for the new game.
                    if (DB.Instance.Server_Register(MyServer.ServerUserID, MyServer.ServerAddress, MyServer.ListenOnPort, DateTime.UtcNow, "content", ConnectionManager.PaddedConnectionCount, MyServer.MaxConnections))
                    {
                        note.ReplyCode = ReplyType.OK;
                    }
                    else
                    {
                        DB.Instance.Lobby_UntrackGameForServer(sg.GameID);
                        note.ReplyMessage = "Failed to register game with master game listing. Internal server error.";
                        Send(note);
                        TransferToLobbyOrDisconnect();
                        return(true);
                    }
                }
                else
                {
                    msg = "Unable to create game at this time.";
                    Log1.Logger("Server").Debug("Failed to create NEW GAME for player [" + ServerUser.AccountName + "].");
                    login.ReplyPacket.Parms.SetProperty("CreateReply", msg);
                    note.ReplyMessage = msg;
                    Send(note);
                    TransferToLobbyOrDisconnect();
                    return(true);
                }
            }
            else // it's a join - get game reference from existing games table
            {
                Log1.Logger("Server").Debug("Player [" + ServerUser.AccountName + "] logging in with request to JOIN EXISTING game. [Observe = " + observeOnly.ToString() + "]");
                note = (PacketMatchNotification)CreatePacket((int)LobbyPacketType.MatchNotification, 0, false, false);

                if (observeOnly)
                {
                    note.Kind = MatchNotificationType.ObserverAdded;
                }
                else
                {
                    note.Kind = MatchNotificationType.PlayerAdded;
                }

                note.TargetPlayer = ServerUser.CurrentCharacter.CharacterInfo;
                note.ReplyCode    = ReplyType.Failure;

                Guid targetGame = login.Parms.GetGuidProperty((int)PropertyID.GameId);
                if (targetGame == Guid.Empty)
                {
                    msg = "Failed to join game. No target game specified.";
                    Log1.Logger("Server").Debug("Player [" + ServerUser.AccountName + "] failed to JOIN EXISTING game.  No target game specified in join request.");
                    note.ReplyMessage = msg;
                    Send(note);
                    TransferToLobbyOrDisconnect();
                    return(true);
                }

                if (!GameManager.Instance.GetGame(targetGame, out sg))
                {
                    Log1.Logger("Server").Debug("Player [" + ServerUser.AccountName + "] failed to JOIN EXISTING game.  Target game specified does not currently exist.");
                    msg = "Failed to join game. Target game [" + targetGame.ToString() + "] does not currently exist on [" + MyServer.ServerUserID + "].";
                    note.ReplyMessage = msg;
                    Send(note);
                    TransferToLobbyOrDisconnect();
                    return(true);
                }
            }

            if (sg == null)
            {
                Log1.Logger("Server").Debug("Player [" + ServerUser.AccountName + "] failed to locate game. Internal Server Error.");
                msg = "Unable to locate game. Internal Server Error."; // should never happen
                note.ReplyMessage = msg;
                Send(note);
                TransferToLobbyOrDisconnect();
                return(true);
            }

            // join game as player or observer
            if (!observeOnly && sg.AddPlayer(ServerUser.CurrentCharacter, ref msg))
            {
                login.ReplyPacket.Parms.SetProperty("TargetGame", (ISerializableWispObject)sg.Game);
                RegisterPacketHandler((int)PacketType.PacketGenericMessage, (int)GenericLobbyMessageType.RequestStartGame, OnRequestStartGame);
            }
            else if (observeOnly && sg.AddObserver(ServerUser.CurrentCharacter, ref msg))
            {
                login.ReplyPacket.Parms.SetProperty("TargetGame", (ISerializableWispObject)sg.Game);
            }
            else
            {
                msg = "Unable to join game.";
                note.ReplyMessage = msg;
                Send(note);
                TransferToLobbyOrDisconnect();
                return(true);
            }

            RegisterPacketHandler((int)PacketType.PacketGenericMessage, (int)GenericLobbyMessageType.LeaveGame, OnPlayerLeaveGame);
            return(result);
        }
 /// <summary>
 /// Sets a reference to the game that the character is currently attached to
 /// </summary>
 /// <param name="toon"></param>
 /// <param name="curGame"></param>
 public static void SetCurrentGame(this ServerCharacterInfo toon, GameServerGame curGame)
 {
     toon.Properties.SetProperty("CurrentGame", curGame);
     toon.Properties.SetLocalFlag("CurrentGame", true);
 }
        /// <summary>
        /// Returns a reference to the game that the character is attached to
        /// </summary>
        /// <param name="toon"></param>
        /// <returns></returns>
        public static GameServerGame GetCurrentGame(this ServerCharacterInfo toon)
        {
            GameServerGame g = toon.Properties.GetComponentProperty("CurrentGame") as GameServerGame;

            return(g);
        }