Esempio n. 1
0
        public static async Task Main(string[] args)
        {
            // Get the IP address to bind to as a command line arguement or default
            // to 127.0.0.1.
            var userSuppliedIp = args.Length < 1 ? "127.0.0.1" : args[0];

            // Require the IP address be supplied as a command line argument.
            var localIp       = IPAddress.Parse(userSuppliedIp);
            var localEndPoint = new IPEndPoint(localIp, BspConstants.DefaultPort);

            // Begin listening for clients attempting to discover the server IP
            _ = StartUdpListing(localEndPoint);

            // Create objects used for every connection.
            var generalLogger = new Logger(Console.Out);
            var unparser      = new MessageUnparser();
            var listener      = new BspListener(generalLogger);
            var gameTypeRepo  = CreateGameTypeRepository();
            var userRepo      = CreateUserRepository();
            var matchMaker    = new MatchMaker();

            // The body of this foreach loop is a callback. This body will run for
            // connection our listener accepts. Here we create objects specific for
            // each connection.
            await foreach (var socket in listener.StartListeningAsync(localEndPoint))
            {
                // Create a logger that will log with the client's EndPoint.
                var logger = new EndPointLogger(Console.Out, socket.RemoteEndPoint);

                // Create a disconnecter that can clean up a connection.
                var disconnecter = new ServerDisconnecter(logger, socket, userRepo, matchMaker);

                // Create a sender for sending messages to the client.
                var senderHandler = new MultiMessageHandler();
                var sender        = new BspSender(socket, logger, unparser, senderHandler);

                // Create a container for this connections state.
                var container = new ServerNetworkStateContainer(sender, disconnecter, gameTypeRepo,
                                                                userRepo, matchMaker);

                // Create a context for our state machine.
                var context = new NetworkStateContext(container, disconnecter);

                // Register incoming messages with this context.
                senderHandler.AddHandler(LoggingMessageHandler.ForSending(logger));
                senderHandler.AddHandler(new SentMessageHandler(context));

                // Register outgoing messages with this context.
                var receiverHandler = new MultiMessageHandler();
                receiverHandler.AddHandler(LoggingMessageHandler.ForReceiving(logger));
                receiverHandler.AddHandler(new ReceiveMessageHandler(context));

                // Create a parser for this connection
                var parser = new MessageParser(receiverHandler, gameTypeRepo);

                // Begin asynchronously receiving messages
                var receiver = new BspReceiver(socket, disconnecter, parser, logger);
                _ = receiver.StartReceivingAsync();
            }
        }
Esempio n. 2
0
        public bool TryLogIn(string username, string password, BspSender sender)
        {
            // Check if user exists
            if (!_users.TryGetValue(username, out var user))
            {
                return(false);
            }

            // Validate password
            if (user.Password != password)
            {
                return(false);
            }

            // Check if user is already logged in
            if (_senders.ContainsKey(user.Username))
            {
                return(false);
            }

            // Add their connection to the dict.
            // This also denotes that they are currently logged in.
            _senders.Add(user.Username, sender);
            return(true);
        }
Esempio n. 3
0
 public NotConnected(BspServerState state, BspSender sender,
                     GameTypeRepository gameTypeRepo, UserRepository userRepo)
 {
     _state        = state;
     _sender       = sender;
     _gameTypeRepo = gameTypeRepo;
     _userRepo     = userRepo;
 }
Esempio n. 4
0
 public FoundGame(BspServerState state, BspSender sender, IBspDisconnecter disconnecter,
                  UserRepository userRepo)
 {
     _state        = state;
     _sender       = sender;
     _disconnecter = disconnecter;
     _userRepo     = userRepo;
 }
Esempio n. 5
0
 public WaitingForBoard(BspServerState state, BspSender sender,
                        GameTypeRepository gameTypeRepo, MatchMaker matchMaker)
 {
     _state        = state;
     _sender       = sender;
     _gameTypeRepo = gameTypeRepo;
     _matchMaker   = matchMaker;
 }
        public ServerNetworkStateContainer(BspSender sender, IBspDisconnecter disconnecter,
                                           GameTypeRepository gameTypeRepo, UserRepository userRepo, MatchMaker matchMaker)
        {
            var state = new BspServerState();

            NotConnected    = new NotConnected(state, sender, gameTypeRepo, userRepo);
            PendingLogOn    = new PendingLogOn();
            WaitingForBoard = new WaitingForBoard(state, sender, gameTypeRepo, matchMaker);
            PendingBoard    = new PendingBoard();
            WaitingForGame  = new WaitingForGame(state, sender, disconnecter, userRepo);
            FoundGame       = new FoundGame(state, sender, disconnecter, userRepo);
            InitialGame     = new InitialGame();
            MyTurn          = new MyTurn(state, sender, disconnecter, userRepo);
            TheirTurn       = new TheirTurn();
            Waiting         = new Waiting();
        }
Esempio n. 7
0
        public static async Task Main(string[] args)
        {
            // Create a logger
            var logger = new Logger(Console.Out);

            // If the user did not supply an IP or hostname, attempt to
            // discover a server on the same subnet.
            IPEndPoint endPoint;

            if (args.Length > 0)
            {
                if (IPAddress.TryParse(args[0], out var ip))
                {
                    endPoint = new IPEndPoint(ip, BspConstants.DefaultPort);
                }
                else
                {
                    // Maybe the user supplied a hostname not an IP
                    var addresses = Dns.GetHostAddresses(args[0]);

                    if (addresses.Length < 1)
                    {
                        Console.WriteLine("Could not find hostname.");
                        return;
                    }

                    endPoint = new IPEndPoint(addresses.Last(), BspConstants.DefaultPort);
                }
            }
            else
            {
                logger.LogInfo("Attempting to discover server end point...");
                endPoint = await DiscoverServerEndPoint(BspConstants.DefaultPort);
            }

            // Attempt to connect to the server.
            var unparser = new MessageUnparser();
            var socket   = new Socket(SocketType.Stream, ProtocolType.Tcp);

            try
            {
                logger.LogInfo($"Attempting to connect to {endPoint}");
                socket.Connect(endPoint);
            }
            catch (SocketException)
            {
                logger.LogError($"Failed to connect to {endPoint}");
            }

            // Create a disconnecter that can clean up a connection.
            var disconnecter = new ClientDisconnecter(logger, socket);

            // Create a sender for sending to the server.
            var senderHandler = new MultiMessageHandler();
            var sender        = new BspSender(socket, logger, unparser, senderHandler);

            // Create a prompter to handle user interaction.
            var prompter = new Prompter(sender);

            // Create a state machine
            var container = new ClientNetworkStateContainer(prompter);
            var context   = new NetworkStateContext(container, disconnecter);

            // Register sending messages with our state machine.
            senderHandler.AddHandler(LoggingMessageHandler.ForSending(logger));
            senderHandler.AddHandler(new SentMessageHandler(context));

            // Register receiving messages with our state machine.
            var receiverHandler = new MultiMessageHandler();

            receiverHandler.AddHandler(LoggingMessageHandler.ForReceiving(logger));
            receiverHandler.AddHandler(new ReceiveMessageHandler(context));

            // Create a parser for our connection with the server
            var parser   = new MessageParser(receiverHandler, new GameTypeRepository());
            var receiver = new BspReceiver(socket, disconnecter, parser, logger);

            // Begin receive messages and start the prompt.
            var receivingTask = receiver.StartReceivingAsync();

            prompter.PromptLogOn();
            await receivingTask;
        }
Esempio n. 8
0
 public Prompter(BspSender sender)
 {
     _sender = sender;
 }
Esempio n. 9
0
 public bool TryGetSender(string username, out BspSender sender)
 {
     return(_senders.TryGetValue(username, out sender));
 }