void IServer.HandleUserReconnect(IServerUser user)
 {
     foreach (var game in _runningGames.Where(game => game.Value.HasUser(user)))
     {
         game.Value.HandleReconnect(user);
     }
 }
        void IServer.HandleUserLeaveQueue(IServerUser user, QueueAction action)
        {
            var matchmaking = GetMatchmaking(user, action);

            if (matchmaking == null)
            {
                return;
            }

            lock (matchmaking)
            {
                var regCount = matchmaking.GetRegisterCount(user);
                if (action.Count >= regCount)
                {
                    matchmaking.LeaveQueueCompletely(user);
                }
                else
                {
                    for (var i = 0; i < action.Count; i++)
                    {
                        matchmaking.LeaveQueue(user);
                    }
                }

                user.Send(Packet.PacketTypeS2C.QueueState, Math.Max(0, regCount - action.Count));
            }
        }
Exemple #3
0
 public GameEnd(long gameIdentifier, IServerUser[] participants, bool youWon, IServerUser winner)
 {
     GameIdentifier = gameIdentifier;
     Participants   = participants;
     YouWon         = youWon;
     Winner         = winner;
 }
        void IServer.HandleUserEnterQueue(IServerUser user, QueueAction action)
        {
            var matchmaking = GetMatchmaking(user, action);

            if (matchmaking == null)
            {
                return;
            }

            lock (matchmaking)
            {
                var regCount = matchmaking.GetRegisterCount(user);
                if (regCount >= _config.MaxQueueCount)
                {
                    user.IllegalAction("Exceeded max queue action: " + _config.MaxQueueCount);
                    return;
                }

                var queueLimitExclusive = Math.Min(_config.MaxQueueCount, regCount + action.Count);
                for (; regCount < queueLimitExclusive; regCount++)
                {
                    matchmaking.EnterQueue(user);
                }

                user.Send(Packet.PacketTypeS2C.QueueState, regCount);
            }
        }
 public bool RemoveUser(IServerUser user)
 {
     using (StoreKeeperServiceProxy proxy = new StoreKeeperServiceProxy(_clientConfiguration))
     {
         return(proxy.RemoveUser(_sessionId, user.UserId));
     }
 }
Exemple #6
0
        public void Should_Use_User_From_Server_If_Direct_Message()
        {
            _message.Channel.IsPrivateMessage.Returns(true);

            _parser.ParseCommand(_message).Returns(new ParsedCommand()
            {
                Success = true,
                Command = "test"
            });

            ICommandHandler commandHandler = Substitute.For <ICommandHandler>();

            commandHandler.CommandName.Returns("test");
            commandHandler.UserFilter.Returns((Func <DiscloseUser, bool>)null);
            commandHandler.ChannelFilter.Returns((Func <DiscloseChannel, bool>)null);

            _discloseClient.Register(commandHandler);

            IServerUser serverUser = Substitute.For <IServerUser>();

            serverUser.Id.Returns((ulong)123);
            serverUser.Name.Returns("foo");

            _server.GetUsersAsync().Returns(Task.FromResult((new[] { serverUser }).AsEnumerable()));

            _discordClient.OnMessageReceived += Raise.EventWith(new object(), new MessageEventArgs(_message));

            commandHandler.Received(1).Handle(Arg.Is <DiscloseMessage>(m => m.User.Name == "foo"), null);
        }
 public bool WouldAuthCollide(Guid login, IServerUser connectingUser, out IServerUser existingUser)
 {
     lock (_connectedUsers)
     {
         existingUser = _connectedUsers.FirstOrDefault(item => item.Key.Login == login && item.Key != connectingUser).Key;
         return(existingUser != null);
     }
 }
Exemple #8
0
        internal DiscloseUser(IServerUser user, DiscloseServer server)
        {
            DiscordUser = user;

            IEnumerable <DiscloseRole> roles = server.GetRoles();

            Roles = user.RoleIds.Select(ur => roles.FirstOrDefault(r => ur == r.Id)).Where(r => r != null).ToList().AsReadOnly();
        }
        void IServer.HandleUserEndTurn(IServerUser user, long gameIdentifier)
        {
            ServerGame game;

            if (!_runningGames.TryGetValue(gameIdentifier, out game))
            {
                user.IllegalAction("You can't end your turn in a game you don't even play in: " + gameIdentifier);
                return;
            }
            game.UserRequestsEndTurn(user);
        }
        void IServer.HandleUserAction(IServerUser @from, LiveGameAction action)
        {
            ServerGame game;

            if (!_runningGames.TryGetValue(action.GameIdentifier, out game))
            {
                @from.IllegalAction("You cannot take action in a game you don't even play in!");
                return;
            }

            game.AddGameAction(from, action);
        }
        void IServer.HandleUserResync(IServerUser user, long gameIdentifier)
        {
            ServerGame game;

            if (!_runningGames.TryGetValue(gameIdentifier, out game))
            {
                _logger.LogWarning($"User tried resyncing in an unknown game: {gameIdentifier}");
                user.IllegalAction($"Cannot resync in game: {gameIdentifier}, because it does not exist!");
                return;
            }
            game.HandleReconnect(user);
        }
Exemple #12
0
        /// <summary>
        ///     Replaces the socket with the socket of the given user. This should be used to let a reconnecting user continue
        ///     where he left
        /// </summary>
        /// <param name="user"></param>
        /// <param name="socket"></param>
        public void Inherit(IServerUser user, Socket socket)
        {
            var userImpl = user as User;

            if (userImpl == null)
            {
                throw new NotImplementedException(); // assuming there are no other implementations of IServerUser than User
            }
            _socket.Dispose();                       // Dispose disconnected
            userImpl._socket.StopJobs();             // Discontinue wrapper because the events will call the methods of the new (duplicate) user
            SetupSocket(userImpl._socket.Socket);    // Recreate wrapper
            _packetParser = userImpl._packetParser;
            Username      = user.Username;
            FullGameState = user.FullGameState;
            Authorized    = user.Authorized;
        }
        void IServer.Kick(IServerUser user)
        {
            DateTime connectedTime;

            lock (_connectedUsers)
            {
                _connectedUsers.TryRemove(user, out connectedTime);
            }
            if (user.Connected)
            {
                user.Dispose();
            }

            _logger.LogDebug($"Kicking user: {user}, who connected {connectedTime}");

            // Todo: instead of letting running games wait for the timeout, kick the user and his entities out right away
        }
Exemple #14
0
 /// <summary>
 /// Constructs a game user
 /// </summary>
 /// <param name="serverUser">Server user</param>
 public AGameUser(IServerUser serverUser)
 {
     if (serverUser == null)
     {
         throw new ArgumentNullException(nameof(serverUser));
     }
     if (!serverUser.IsValid)
     {
         throw new ArgumentException("Server user is not valid.", nameof(serverUser));
     }
     ServerUser = serverUser;
     serverUser.OnUsernameUpdated       += () => OnUsernameUpdated?.Invoke();
     serverUser.OnUserLobbyColorUpdated += () => OnUserLobbyColorUpdated?.Invoke();
     serverUser.OnGameLoadingFinished   += () => OnGameLoadingFinished?.Invoke();
     serverUser.OnClientTicked          += (entityDeltas, hits) => OnClientTicked?.Invoke(entityDeltas, hits);
     serverUser.OnServerTicked          += (time, entityDeltas, hits) => OnServerTicked?.Invoke(time, entityDeltas, hits);
 }
        private IMatchmaking GetMatchmaking(IServerUser user, QueueAction action)
        {
            if (action.Count <= 0)
            {
                user.IllegalAction("Invalid queue count");
                return(null);
            }

            IMatchmaking matchmaking;

            if (!_matchmaking.TryGetValue(action.GameMode, out matchmaking))
            {
                user.IllegalAction("There is no such gamemode");
                return(null);
            }
            return(matchmaking);
        }
Exemple #16
0
        /// <summary>
        /// "ban" console command executed event
        /// </summary>
        /// <param name="arguments">Arguments</param>
        private static void BanConsoleCommmandExecutedEvent(IReadOnlyList <string> arguments)
        {
            IServerUser banned_server_user = null;
            string      user_guid          = arguments[0];

            foreach (ILobby lobby in server.Lobbies.Values)
            {
                if (lobby.Users.ContainsKey(user_guid))
                {
                    banned_server_user = lobby.Users[user_guid] as IServerUser;
                    if (banned_server_user != null)
                    {
                        server.Bans.AddPeer(banned_server_user.Peer, "Banned by admin");
                        banned_server_user.Disconnect(EDisconnectionReason.Banned);
                        server.Bans.WriteToFile(bansJSONFilePath);
                        break;
                    }
                }
            }
            if (banned_server_user == null)
            {
                WriteErrorLogLine($"User with GUID \"{ user_guid }\" does not exist or could not been banned.");
            }
            else
            {
                foreach (ILobby lobby in server.Lobbies.Values)
                {
                    foreach (IUser user in lobby.Users.Values)
                    {
                        if (user is IServerUser server_user)
                        {
                            if ((banned_server_user != server_user) && (server.Bans.IsPeerBanned(server_user.Peer, out _)))
                            {
                                server_user.Disconnect(EDisconnectionReason.Banned);
                            }
                        }
                    }
                }
                WriteOutputLogLine($"User \"{ banned_server_user.Name }\" with GUID \"{ banned_server_user.GUID }\" at \"{ banned_server_user.Peer.Secret }\" has been banned.");
            }
        }
Exemple #17
0
        public void Setup()
        {
            _parser         = Substitute.For <ICommandParser>();
            _discordClient  = Substitute.For <IDiscordClient>();
            _discloseClient = new DiscloseClient(_discordClient, _parser);

            _discloseClient.Init(new DiscloseOptions());

            _message = Substitute.For <IMessage>();
            _server  = Substitute.For <IServer>();

            IServerUser serverUser = Substitute.For <IServerUser>();

            serverUser.Id.Returns((ulong)123);

            _message.User.Returns(serverUser);

            _server.Id.Returns((ulong)1);

            _discordClient.OnServerAvailable += Raise.EventWith(new object(), new ServerEventArgs(_server));
        }
        public void Setup()
        {
            _parser         = Substitute.For <ICommandParser>();
            _discordClient  = Substitute.For <IDiscordClient>();
            _discloseClient = new DiscloseClient(_discordClient, _parser);

            _discloseClient.Init(new DiscloseOptions());

            _user   = Substitute.For <IServerUser>();
            _server = Substitute.For <IServer>();

            _user.Id.Returns((ulong)1);
            _server.Id.Returns((ulong)2);

            _handler1 = Substitute.For <IUserJoinsServerHandler>();
            _handler2 = Substitute.For <IUserJoinsServerHandler>();

            _discloseClient.Register(_handler1);
            _discloseClient.Register(_handler2);

            _discordClient.OnServerAvailable += Raise.EventWith <ServerEventArgs>(new object(), new ServerEventArgs(_server));
        }
Exemple #19
0
        public void EnterQueue(IServerUser user)
        {
            var time = _time.Elapsed.TotalSeconds;

            if (time - _lastQueuerTime > _maxTimeInQueue && _inQueue.All(item => item.IsBot) && _inQueue.Any() && !user.IsBot)
            {
                AddUser(user);

                var bestMatch  = Supervisor.GetBestChoice(user.Login, _inQueue.Where(item => item != user).ToArray().Select(item => item.Login));
                var bestBotBot = _inQueue.FirstOrDefault(bot => bot.Login == bestMatch);

                if (bestBotBot == null)
                {
                    _logger.LogError($"{GetType().Name}: {Supervisor.GetType()} gave me an invalid GUID as best choice!");
                }
                else
                {
                    _logger.LogDebug($"Found a match (Queue very empty for a longer time, matching with bot: {bestBotBot})");
                    OnSuggested?.Invoke(this, new MatchCreatedArgs(this, _gameMode, user, bestBotBot));
                    return;
                }
            }


            if (!user.IsBot)
            {
                _lastQueuerTime = time;
            }

            AddUser(user);
            var autoBestMatch = _inQueue.FirstOrDefault(usr => usr != user && !usr.HasEverPlayedAgainst(user, Supervisor));

            if (autoBestMatch != null)
            {
                _logger.LogDebug($"Found a match (never played against {autoBestMatch})");
                OnSuggested?.Invoke(this, new MatchCreatedArgs(this, _gameMode, autoBestMatch, user));
            }
        }
 public void ForceLogout(IServerUser user) => this.Server.ForceLogout(user);
 /// <summary>
 /// Creates a new game user
 /// </summary>
 /// <param name="serverUser">Server user</param>
 /// <returns>Game user</returns>
 public IGameUser CreateNewGameUser(IServerUser serverUser) => new ExampleGameUser(serverUser);
Exemple #22
0
 public static bool HasEverPlayedAgainst(this IServerUser me, IServerUser other, IServerSupervisor supervisor)
 {
     return(supervisor.GetWinStatistics(me.Login, other.Login).GetTotalGames() > 0);
 }
        private void LoadInternalCommand()
        {
            /*
             * {"Call":"command","Args":{"command":"cmd arg1 arg2 ..."}}
             */
            this.AddFunction(new Function()
            {
                Name    = "command",
                Comment = null,
                Func    = (args, caller) => {
                    if (caller.Type.In(CallerType.Client))
                    {
                        IServerUser user = (IServerUser)caller;

                        string command = args.GetString("command");
                        if (!string.IsNullOrWhiteSpace(command))
                        {
                            this.HandleCommand(command, caller);
                        }
                    }
                    return(0);
                }
            });

            this.AddFunction(new Function()
            {
                Name = "heartbeat",
                Func = (args, caller) => {
                    return(0);
                }
            });

            this.AddCommand(new Function()
            {
                Name    = "plugin-unload",
                Comment = "Unload plugin",
                Func    = (args, caller) => {
                    string name = args.GetString("0");

                    if (name.IsNullOrWhiteSpace())
                    {
                        caller.Logger.Info($"Missing parameter: [pluginName]");
                        return(-1);
                    }

                    var plugin = this.pluginList.FirstOrDefault(x => x.Key == name).Value;

                    if (plugin == null)
                    {
                        caller.Logger.Info($"Plugin cannot be found: {name}");
                        return(-1);
                    }

                    string pluginName = plugin.Name;

                    if (plugin.UnLoadable)
                    {
                        plugin.Config.Enabled = false;
                        SavePluginConfig(plugin);
                        if (UnLoadPlugin(plugin))
                        {
                            caller.Logger.Info($"Plugin unload successfully: {pluginName}");
                            this.pluginList.Remove(pluginName);
                        }
                        else
                        {
                            caller.Logger.Error($"Plugin unload failed: {pluginName}!");
                        }
                    }
                    else
                    {
                        this.Logger.Error($"Plugin cannot be unloaded: {pluginName}");
                    }

                    return(0);
                }
            });

            this.AddCommand(new Function()
            {
                Name    = "plugin-load",
                Comment = "Load plugin",
                Func    = (args, caller) => {
                    string name = args.GetString("0");

                    if (name.IsNullOrWhiteSpace())
                    {
                        caller.Logger.Info($"Missing parameter: [pluginName]");
                        return(-1);
                    }

                    FileInfo file = new FileInfo(Path.Combine(GetFolderPath(FolderPath.Plugin), name));

                    if (file.Exists)
                    {
                        return(this.LoadPlugin(file.FullName, true) ? 0 : -1);
                    }
                    else
                    {
                        this.Logger.Error($"Plugin cannot be found: {name}");
                        return(-1);
                    }
                }
            });

            this.AddCommand(new Function()
            {
                Name    = "plugin-list",
                Comment = "Show plugin list",
                Func    = (args, caller) => {
                    DirectoryInfo folderPlugin = new DirectoryInfo(GetFolderPath(FolderPath.Plugin));

                    var list = new List <string>();
                    foreach (DirectoryInfo folder in folderPlugin.GetDirectories())
                    {
                        foreach (FileInfo file in folder.GetFiles(PATTERN_DLL))
                        {
                            if (PluginLoader.TryGetPluginName(file.FullName, out string name))
                            {
                                var plugin = this.pluginList.FirstOrDefault(x => x.Value.AssemblyPath == file.FullName).Value;

                                list.Add($"{file.Directory.Name}{Path.DirectorySeparatorChar}{file.Name} (Name: {name}, Status: {(plugin != null ? "Enabled" : "Disabled")})");
                            }
                        }
                    }

                    caller.Logger.Info("- Plugin List");
                    caller.Logger.Info(list);

                    return(0);
                }
            });
Exemple #24
0
 public void LeaveQueueCompletely(IServerUser user)
 {
     _inQueue.RemoveAll(usr => usr == user);
     _logger.LogDebug($"{user} left matchmaking completely");
 }
Exemple #25
0
 public UserEventArgs(IServerUser user, IServer server)
 {
     User   = user;
     Server = server;
 }
Exemple #26
0
 private void AddUser(IServerUser user)
 {
     _inQueue.Add(user);
     _joinedQueueTime[user] = _time.Elapsed.TotalMilliseconds;
     _logger.LogDebug($"{user} entered matchmaking");
 }
 /// <summary>
 /// Constructs an example game user
 /// </summary>
 /// <param name="serverUser"></param>
 public ExampleGameUser(IServerUser serverUser) : base(serverUser)
 {
     // ...
 }
Exemple #28
0
 public int GetRegisterCount(IServerUser user)
 {
     return(_inQueue.Count(usr => usr == user));
 }
Exemple #29
0
        private void HandleMessage(object sender, TcpClient.ReceiveEventArgs e)
        {
            this.Traffic_In += e.Data.Length;

            TcpClient tcpClient = sender as TcpClient;

#if GZIP
            string text = GZip.Decompress(e.Data).GetString();
#else
            string text = e.Data.GetString();
#endif
            DataReceived?.Invoke(this, new DataReceivedEventArgs(tcpClient.RemoteAddress.Address, tcpClient.RemoteAddress.Port, text));

            this.Logger.Debug($"DataReceived: {tcpClient.RemoteAddress}");

            try {
                MessageBody message = this.JsonSerialzation.Deserialize <MessageBody>(text);

                if (message.Flag == MessageFlag.RequestPublicKey)
                {
                    this.Logger.Debug("AKA", $"客户端    : 请求公钥 - {tcpClient.RemoteAddress}");
                    this.SendPublicKey(tcpClient);
                    this.Logger.Debug("AKA", $"发送      : 服务端公钥- {tcpClient.RemoteAddress}");
                }
                else if (message.Flag == MessageFlag.RequestValidate)
                {
                    this.Logger.Debug("AKA", $"客户端    : 请求签名 - {tcpClient.RemoteAddress}");
                    byte[] rawData = RSAHelper.Decrypt(message.Content, this.RSAKey);
                    if (rawData != null)
                    {
                        this.SendSignature(rawData, tcpClient);
                        this.Logger.Debug("AKA", $"发送      : 服务端签名 - {tcpClient.RemoteAddress}");
                    }
                    else
                    {
                        this.RefuseSignature(tcpClient);
                        this.Logger.Debug("AKA", $"解析数据  : 失败 - {tcpClient.RemoteAddress}");
                    }
                }
                else if (message.Flag == MessageFlag.SendClientPublicKey)
                {
                    this.Logger.Debug("AKA", $"接受      : 客户端公钥 - {tcpClient.RemoteAddress}");
                    this.Logger.Debug("AKA", $"生成      : AES密钥 - {tcpClient.RemoteAddress}");
                    this.GenerateAndSendAESKey(message.Content, tcpClient);
                    this.Logger.Debug("AKA", $"发送      : AES密钥 - {tcpClient.RemoteAddress}");
                }
                else if (message.Flag == MessageFlag.Message)
                {
                    if (!string.IsNullOrWhiteSpace(message.Guid) && this.AESKeyList.ContainsKey(message.Guid))
                    {
                        AESKey key = this.AESKeyList[message.Guid];

                        CallBody call = message.Content != null?this.JsonSerialzation.Deserialize <CallBody>(AESHelper.Decrypt(message.Content, key).GetString()) : null;

                        if (this.UserList.ContainsKey(message.Guid))
                        {
                            IServerUser user = this.UserList[message.Guid];
                            user.RefreshHeartBeat();
                            this.Logger.Debug($"RefreshHeartBeat: {user.Name} / {user.Guid}");

                            if (call != null)
                            {
                                ThreadPool.QueueUserWorkItem((x) => {
                                    var tuple = x as Tuple <Server <TConfig>, CallBody, ICaller>;
                                    tuple.Item1.CallFunction(tuple.Item2.Call, tuple.Item2.Args, tuple.Item3);
                                }, new Tuple <Server <TConfig>, CallBody, ICaller>(this, call, user));
                            }
                        }
                        else
                        {
                            //新登录
                            if (call == null)
                            {
                                return;
                            }
                            if (call.Call == "login")
                            {
                                this.Logger.Debug($"尝试登入 - {tcpClient.RemoteAddress.Address}");

                                ServerUser user = new ServerUser()
                                {
                                    Guid       = message.Guid,
                                    Server     = this,
                                    Name       = null,
                                    NetAddress = tcpClient.RemoteAddress,
                                    AESKey     = this.AESKeyList[message.Guid]
                                };

                                if (ClientPreLogin != null)
                                {
                                    ClientPreLoginEventArgs <ServerUser> eventArgs = new ClientPreLoginEventArgs <ServerUser>(ref user, call.Args);
                                    ClientPreLogin?.Invoke(this, eventArgs);
                                    user = eventArgs.User;
                                }

                                if (user != null)
                                {
                                    user._TcpClient = tcpClient;
                                    if (user.Status == UserStatus.Online)
                                    {
                                        user.LoginTime = DateTime.Now;

                                        user.SocketError += (x, y) => {
                                            this.Logger.Error("SocketError", y.Exception.Message);
                                            ForceLogout(this.UserList[y.Guid]);
                                        };

                                        user.RefreshHeartBeat();

                                        this.UserList.Add(user.Guid, user);

                                        Arguments args = new Arguments();
                                        args.Put("status", true);
                                        args.Put("guid", user.Guid);
                                        args.Put("name", user.Name);

                                        user.CallFunction("login", args);

                                        ClientLogin?.Invoke(this, new ClientEventArgs <IServerUser>(user, ClientLoginStatus.Success));

                                        this.Logger.Debug($"登入成功 - {tcpClient.RemoteAddress.Address}");
                                    }
                                    else if (user.Status == UserStatus.Offline)
                                    {
                                        Arguments args = new Arguments();
                                        args.Put("status", false);
                                        ClientLogin?.Invoke(this, new ClientEventArgs <IServerUser>(user, ClientLoginStatus.Fail));
                                        user.CallFunction("login", args);
                                        this.Logger.Error($"登入失败 - {tcpClient.RemoteAddress.Address}");
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                this.Logger.Error(ex.Message);
            }
        }
 /// <summary>
 /// Creates a new game user
 /// </summary>
 /// <param name="serverUser">Server user</param>
 /// <returns>Game user</returns>
 public IGameUser CreateNewGameUser(IServerUser serverUser) => new DeathmatchGameUser(serverUser);