예제 #1
0
 public void DropPlayer(int playerId, int gameId, ClientCode clientCode, Team team)
 {
     lock (_gameLock)
     {
         Player player = getPlayer(playerId);
         if (team != null)
         {
             checkPlayerAccess(player, team);
         }
         else
         {
             checkPlayerAccess(player, clientCode);
         }
         Game game = player.Game;
         if (game == null)
         {
             throw new ApplicationException("Player is not in a game");
         }
         if (gameId > 0 && game.GameId != gameId)
         {
             throw new ApplicationException("Player is not in the specified game");
         }
         game.DropPlayer(player, clientCode.ToString());
     }
 }
예제 #2
0
 private void checkPlayerAccess(Player player, ClientCode clientCode)
 {
     if (player.Name != clientCode.ClientName || player.Team.Name != clientCode.TeamName)
     {
         throw new UnauthorizedAccessException();
     }
 }
예제 #3
0
        public WaitTurnInfo WaitNextTurn(int playerId, int refTurn, ClientCode clientCode, DateTime callTimestamp)
        {
            while (refTurn == 0)
            {
                // Entering the game
                GameInfo gameInfo = WaitGameStart(playerId, clientCode);
                if (gameInfo == null)
                {
                    // Not yet in a game
                    return(new WaitTurnInfo());
                }
                else if (gameInfo.State == GameState.Finish)
                {
                    // In a finished game
                    LeaveGame(playerId, clientCode);
                    continue;
                }
                // In a running game -- fall through
                break;
            }
            GameModel    game = accessLiveGame(playerId, clientCode);
            WaitTurnInfo wi   = game.CompletePlayerTurn(playerId, refTurn, callTimestamp);

            if (wi.TurnComplete == false)
            {
                game.WaitNextTurn(wi);
            }

            if (wi.GameFinished)
            {
                Thread.Sleep(Settings.LastWaitNextTurnSleepMillis);
            }

            return(wi);
        }
예제 #4
0
 public ClientSession(int sessionId, ClientCode clientCode)
 {
     SessionId      = sessionId;
     ClientCode     = clientCode;
     SequenceNumber = 0;
     LastCall       = DateTime.Now;
 }
예제 #5
0
        public ObservedGameInfo ObserveNextTurn(int observerId, int gameId, ClientCode clientCode)
        {
            Observer observer;
            Game     game;

            accessObservedGame(observerId, gameId, clientCode, null, out observer, out game);
            return(game.ObserveNextTurn(observer));
        }
예제 #6
0
        public GameViewInfo StartObserving(int observerId, int gameId, ClientCode clientCode, Team team)
        {
            Observer observer;
            Game     game;

            accessObservedGame(observerId, gameId, clientCode, team, out observer, out game);
            return(game.StartObserving(observer));
        }
예제 #7
0
 public ClientSession(int sessionId, ClientCode clientCode)
 {
     SessionId        = sessionId;
     ClientCode       = clientCode;
     LastCall         = DateTime.Now;
     _oldSessions     = new int[10];
     _oldSessionCount = 0;
 }
예제 #8
0
        public ObservedGameInfo ObserveNextTurn(int observerId, int gameId, ClientCode clientCode, Team team)
        {
            Observer  observer;
            GameModel game;

            accessObservedGame(observerId, gameId, clientCode, team, out observer, out game);
            return(game.ObserveNextTurn(observer));
        }
예제 #9
0
 private void accessObservedGame(int observerId, int gameId, ClientCode clientCode, Team team, out Observer observer, out GameModel game)
 {
     lock (_gameLock)
     {
         observer = getObserver(observerId, clientCode);
         game     = getGame(gameId);
         checkGameAccess(game, team);
         game.CheckRunState();
     }
 }
예제 #10
0
        public override bool Equals(object obj)
        {
            if (!(obj is ClientCode))
            {
                return(false);
            }
            ClientCode other = (ClientCode)obj;

            return(this.TeamName == other.TeamName &&
                   this.ClientName == other.ClientName);
        }
예제 #11
0
        private Observer getObserver(int observerId, ClientCode clientCode)
        {
            Observer observer;

            if (!_observers.TryGetValue(observerId, out observer))
            {
                throw new ApplicationException("Observer not found");
            }
            if (observer.Name != clientCode.ClientName || observer.Team.Name != clientCode.TeamName)
            {
                throw new UnauthorizedAccessException();
            }
            return(observer);
        }
예제 #12
0
 public void LeaveGame(int playerId, ClientCode clientCode)
 {
     lock (_gameLock)
     {
         Player player = getPlayer(playerId);
         checkPlayerAccess(player, clientCode);
         GameModel game = player.Game;
         if (game == null)
         {
             return;
         }
         game.DropPlayer(player, clientCode.ToString());
     }
 }
예제 #13
0
 public void DropPlayer(int playerId, int gameId, ClientCode clientCode, Team team)
 {
     lock (_gameLock)
     {
         Player    player = getPlayer(playerId);
         GameModel game   = getGame(gameId);
         checkGameChange(game, team);
         if (player.Game != game)
         {
             throw new ApplicationException("Player is not in this game");
         }
         game.DropPlayer(player, clientCode.ToString());
     }
 }
예제 #14
0
        public WaitTurnInfo WaitNextTurn(int playerId, int refTurn, ClientCode clientCode)
        {
            Game         game = accessLiveGame(playerId, clientCode);
            WaitTurnInfo wi   = game.CompletePlayerTurn(playerId, refTurn);

            if (!wi.TurnComplete)
            {
                game.WaitNextTurn(wi);
            }
            if (wi.GameFinished)
            {
                Thread.Sleep(Settings.LastWaitNextTurnSleepMillis);
            }
            return(wi);
        }
예제 #15
0
 private Game accessLiveGame(int playerId, ClientCode clientCode)
 {
     lock (_gameLock)
     {
         Player player = getPlayer(playerId);
         checkPlayerAccess(player, clientCode);
         Game game = player.Game;
         if (game == null)
         {
             throw new ApplicationException("Player is not in a game");
         }
         game.checkRunState();
         return(game);
     }
 }
예제 #16
0
        public void Authenticate(SessionAuth auth, SessionAuthOptions options)
        {
            Team   team     = _teamReg.GetTeam(auth.TeamName);
            string authCode = "";

            if (team.Authenticate)
            {
                authCode = checkAuthCode(team, auth);
                if (!options.IsLoginFlow)
                {
                    lock (_replayDetector)
                    {
                        _replayDetector.CheckAndStore(authCode);
                    }
                }
            }
            ClientCode clientCode = auth.GetClientCode();

            if (options.IsLoginFlow)
            {
                if (auth.SessionId != 0 || auth.SequenceNumber != 0)
                {
                    throw new AuthException("For login calls, SessionId and SequenceNumber must be zero.");
                }
            }
            else
            {
                lock (_sessions)
                {
                    ClientSession session;
                    if (!_sessions.TryGetValue(clientCode, out session))
                    {
                        session = new ClientSession(auth.SessionId, clientCode);
                        _sessions[clientCode] = session;
                    }
                    if (session.SessionId != auth.SessionId)
                    {
                        session.Restart(auth.SessionId);
                    }
                    session.Update();
                }
            }
        }
예제 #17
0
        public SessionChallenge CreateChallenge(ClientCode clientCode)
        {
            clientCode.Validate();
            Team team = _teamReg.GetTeam(clientCode.TeamName);

            lock (_challenges)
            {
                SessionChallenge challenge;
                if (_challenges.TryGetValue(clientCode, out challenge))
                {
                    if (!challenge.IsTimedOut)
                    {
                        throw new AuthException("Previous challenge has not timed out. Complete login or wait for timeout.");
                    }
                }
                challenge = new SessionChallenge(clientCode);
                _challenges[clientCode] = challenge;
                return(challenge);
            }
        }
예제 #18
0
 public GameInfo WaitGameStart(int playerId, ClientCode clientCode)
 {
     lock (_gameLock)
     {
         for (int i = 0; i < 2; i++)
         {
             Player player = getPlayer(playerId);
             checkPlayerAccess(player, clientCode);
             Game game = player.Game;
             if (game != null && game.State != GameState.SETUP)
             {
                 return(new GameInfo(game));
             }
             if (i == 0)
             {
                 Monitor.Wait(_gameLock, Settings.GameStartPollTimeoutMillis);
             }
         }
         return(null);
     }
 }
예제 #19
0
        public void Authenticate(SessionAuth auth, SessionAuthOptions options)
        {
            Team team = _teamReg.GetTeam(auth.TeamName);

            if (team.Authenticate)
            {
                checkAuthCode(team, auth);
            }
            ClientCode clientCode = auth.GetClientCode();

            if (options.IsLoginFlow)
            {
                if (auth.SessionId != 0 || auth.SequenceNumber != 0)
                {
                    throw new AuthException("For login calls, SessionId and SequenceNumber must be zero.");
                }
            }
            else
            {
                lock (_sessions)
                {
                    ClientSession session;
                    if (!_sessions.TryGetValue(clientCode, out session))
                    {
                        throw new AuthException("No active session for this client. Login first.");
                    }
                    if (session.SessionId != auth.SessionId)
                    {
                        throw new AuthException("Stale session id. Relogin or stop.");
                    }
                    if (team.Authenticate)
                    {
                        _replayDetector.CheckAndStore(auth.SessionId, auth.SequenceNumber);
                    }
                    session.Update(auth.SequenceNumber);
                }
            }
        }
예제 #20
0
        public ClientSession CreateSession(ClientCode clientCode, string challengeResponse)
        {
            Team team = _teamReg.GetTeam(clientCode.TeamName);

            lock (_challenges)
            {
                SessionChallenge challenge;
                if (!_challenges.TryGetValue(clientCode, out challenge))
                {
                    throw new AuthException("No outstanding challenge for this client. Init login first.");
                }
                if (challenge.IsTimedOut)
                {
                    throw new AuthException("Challenge timed out. Init login again and complete login with less delay.");
                }
                string correctResponse = getAuthCode(getAuthCode(challenge.Challenge, team.Secret), team.Secret);
                if (team.Authenticate && (challengeResponse != correctResponse))
                {
                    // TODO Log
                    throw new AuthException("Challenge response mismatch.");
                }
                _challenges.Remove(clientCode);
            }
            lock (_sessions)
            {
                ClientSession session;
                if (_sessions.TryGetValue(clientCode, out session))
                {
                    session.Restart(generateSessionId());
                }
                else
                {
                    session = new ClientSession(generateSessionId(), clientCode);
                    _sessions[clientCode] = session;
                }
                return(session);
            }
        }
예제 #21
0
        public GameResultInfo GetTurnResultForPlayer(int playerId, ClientCode clientCode)
        {
            Game game = accessLiveGame(playerId, clientCode);

            return(game.GetTurnResult());
        }
예제 #22
0
 public SessionChallenge(ClientCode clientCode)
 {
     ClientCode = clientCode;
     Challenge  = Guid.NewGuid().ToString();
     TimeStamp  = DateTime.Now;
 }
예제 #23
0
        public GameViewInfo GetPlayerView(int playerId, ClientCode clientCode)
        {
            Game game = accessLiveGame(playerId, clientCode);

            return(game.GetGameView(playerId));
        }
예제 #24
0
        public void PerformMove(int playerId, Point position, ClientCode clientCode)
        {
            Game game = accessLiveGame(playerId, clientCode);

            game.PerformMove(playerId, position);
        }