Esempio n. 1
0
        //
        private void OnExpBattleFieldPlayTimeReset(IEvent ievent)
        {
            if (mIsResetTimerEventHandled)
            {
                return;
            }
            mIsResetTimerEventHandled = true;
            SceneServerControl.Timer.CreateTrigger(DateTime.Now.AddMinutes(1), () => mIsResetTimerEventHandled = false);

            var now  = DateTime.Now;
            var list = PlayerEnterTimes.Keys.ToList();

            foreach (var key in list)
            {
                PlayerEnterTimes[key] = now;
            }

            if (mKickQueue.Count > 0)
            {
                foreach (var queuePlayer in mKickQueue)
                {
                    queuePlayer.DueTime = now.AddSeconds(mMaxTimeOneDaySec);

                    //通知客户端更新倒计时
                    if (null != queuePlayer.Player && null != queuePlayer.Player.Proxy)
                    {
                        queuePlayer.Player.Proxy.NotifyDungeonTime((int)State, (ulong)queuePlayer.DueTime.ToBinary());
                    }
                }

                mMinQueuePlayer = mKickQueue.FindMin();
                SceneServerControl.Timer.ChangeTime(ref mKickTimer, mMinQueuePlayer.DueTime);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Добавляет в очередь нового игрока и ждет пока ему найдут соперника или он выйдет
        /// После выданный BattleToken посылает на клиент
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task <JsonResult> SearchBattleAsync(string token)
        {
            var player = await repository.GetPlayerByToken(token);

            if (player == null)
            {
                return(new JsonResult(new { Success = "bad token" }));
            }

            var queue = new QueuePlayer
            {
                Player             = player,
                BattleToken        = null,
                SearchingForBattle = true
            };

            playerQueue.Add(token, queue);

            while (queue.BattleToken == null && queue.SearchingForBattle)
            {
                await Task.Delay(1000);
            }

            if (!queue.SearchingForBattle)
            {
                playerQueue.Remove(token);
                return(new JsonResult(new { Success = "canceled" }));
            }

            queue.SearchingForBattle = false;

            return(new JsonResult(new { Success = "ok", BattleToken = queue.BattleToken }));
        }
Esempio n. 3
0
        private void OnPlayerConnecting([FromSource] Player player, string name, CallbackDelegate kickReason, ExpandoObject deferrals)
        {
            try
            {
                DebugLog($"Connecting: {player.Name}  {player.Identifiers["steam"]}");
                // Check if in queue
                DebugLog($"Currently in queue: {string.Join(", ", _queue.Select(q => q.SteamId))}");
                QueuePlayer queuePlayer = _queue.FirstOrDefault(p => p.SteamId == player.Identifiers["steam"]);

                if (queuePlayer != null)
                {
                    // Player had a slot in the queue, give them it back.
                    DebugLog($"Player found in queue: {queuePlayer.Name}");
                    queuePlayer.Handle      = int.Parse(player.Handle);
                    queuePlayer.Status      = QueueStatus.Queued;
                    queuePlayer.ConnectTime = new DateTime();
                    queuePlayer.JoinCount++;
                    queuePlayer.Deferrals = deferrals;

                    ((CallbackDelegate)queuePlayer.Deferrals.ToList()[0].Value)();
                    ((CallbackDelegate)queuePlayer.Deferrals.ToList()[2].Value)("Connecting");

                    return;
                }

                // Slot available, don't bother with the queue.
                if (this.Players.Count() < _config.MaxClients && !_config.QueueWhenNotFull)
                {
                    return;
                }

                // Check if the player is in the priority list
                PriorityPlayer priorityPlayer = _config.PriorityPlayers.FirstOrDefault(p => p.SteamId == player.Identifiers["steam"]);

                // Add to queue
                queuePlayer = new QueuePlayer()
                {
                    Handle    = int.Parse(player.Handle),
                    SteamId   = player.Identifiers["steam"],
                    Name      = player.Name,
                    JoinCount = 1,
                    JoinTime  = DateTime.UtcNow,
                    Deferrals = deferrals,
                    Priority  = priorityPlayer?.Priority ?? 100
                };

                AddToQueue(queuePlayer);
            }
            catch (Exception e)
            {
                Log(e.Message);
                API.CancelEvent();
            }
        }
Esempio n. 4
0
        //获取古战场今日游戏时间,并设置定时器(时间到了,要把玩家踢出副本)
        private IEnumerator FetchPlayerExDataCoroutine(Coroutine co, ObjPlayer player)
        {
            var msg = SceneServer.Instance.LogicAgent.SSFetchExdata(player.ObjId, mIdList);

            yield return(msg.SendAndWaitUntilDone(co));

            if (msg.State != MessageState.Reply)
            {
                Logger.Error("In FetchPlayerExDataCoroutine(), SSFetchExdata() not replied! msg.State = {0}", msg.State);
                player.ExitDungeon();
                yield break;
            }
            if (msg.ErrorCode != (int)ErrorCodes.OK)
            {
                Logger.Error("In FetchPlayerExDataCoroutine(), SSFetchExdata() reply with errCode = {0}", msg.ErrorCode);
                player.ExitDungeon();
                yield break;
            }

            var exData        = msg.Response.Items;
            var playedTimeSec = exData[0];
            var enterTime     = PlayerEnterTimes[player.ObjId];
            var dueTime       = enterTime.AddSeconds(mMaxTimeOneDaySec - playedTimeSec);

            //添加queuePlayer
            var queuePlayer = new QueuePlayer();

            queuePlayer.DueTime = dueTime;
            queuePlayer.Player  = player;
            mKickQueue.Add(ref queuePlayer.Handle, queuePlayer);
            mQueuePlayerMap.Add(player.ObjId, queuePlayer);

            //检查并修改踢人的定时器
            mMinQueuePlayer = mKickQueue.FindMin();
            if (mKickTimer == null || mKickTimer.T == null)
            {
                mKickTimer = SceneServerControl.Timer.CreateTrigger(mMinQueuePlayer.DueTime, KickPlayers);
            }
            else
            {
                var trigger = mKickTimer;
                if (trigger.Time != mMinQueuePlayer.DueTime)
                {
                    SceneServerControl.Timer.ChangeTime(ref mKickTimer, mMinQueuePlayer.DueTime);
                }
            }

            //通知客户端倒计时
            player.Proxy.NotifyDungeonTime((int)State, (ulong)dueTime.ToBinary());
        }
Esempio n. 5
0
        private void AddToQueue(QueuePlayer player)
        {
            // Find out where to insert them in the queue.
            int queuePosition = _queue.FindLastIndex(p => p.Priority <= player.Priority) + 1;

            _queue.Insert(queuePosition, player);

            DebugLog($"Added {player.Name} to the queue with priority {player.Priority} [{_queue.IndexOf(player) + 1}/{_queue.Count}]");
            if (player.Deferrals == null)
            {
                return;
            }
            ((CallbackDelegate)player.Deferrals.ToList()[0].Value)();
            ((CallbackDelegate)player.Deferrals.ToList()[2].Value)("Connecting");
        }
Esempio n. 6
0
 private void OnPlayerActive([FromSource] Player player)
 {
     DebugLog($"Player connected, removing from queue: {player.Name}");
     try
     {
         QueuePlayer queuePlayer = _queue.FirstOrDefault(p => p.SteamId == player.Identifiers["steam"]);
         if (queuePlayer != null)
         {
             _queue.Remove(queuePlayer);
         }
     }
     catch (Exception e)
     {
         Log(e.Message);
     }
 }
Esempio n. 7
0
 private void OnPlayerDropped([FromSource] Player player, string disconnectMessage, CallbackDelegate kickReason)
 {
     try
     {
         QueuePlayer queuePlayer = _queue.FirstOrDefault(p => p.SteamId == player.Identifiers["steam"]);
         if (queuePlayer == null)
         {
             return;
         }
         OnPlayerDisconnect(queuePlayer, disconnectMessage);
     }
     catch (Exception e)
     {
         Log(e.Message);
     }
 }
Esempio n. 8
0
 private void OnPlayerDropped([FromSource] Player player, string disconnectMessage, CallbackDelegate kickReason)
 {
     try
     {
         DebugLog($"Disconnected: {player.Name}");
         QueuePlayer queuePlayer = _queue.FirstOrDefault(p => p.SteamId == player.Identifiers["steam"]);
         if (queuePlayer == null)
         {
             return;
         }
         queuePlayer.Status         = QueueStatus.Disconnected;
         queuePlayer.DisconnectTime = DateTime.UtcNow;
     }
     catch (Exception e)
     {
         Log(e.Message);
     }
 }
Esempio n. 9
0
 private void DeleteQueuePlayer(QueuePlayer queuePlayer, bool bChangeTimer = true)
 {
     mKickQueue.Delete(queuePlayer.Handle);
     mQueuePlayerMap.Remove(queuePlayer.Player.ObjId);
     if (!bChangeTimer)
     {
         return;
     }
     if (mKickQueue.Count > 0)
     {
         mMinQueuePlayer = mKickQueue.FindMin();
         SceneServerControl.Timer.ChangeTime(ref mKickTimer, mMinQueuePlayer.DueTime);
     }
     else
     {
         SceneServerControl.Timer.DeleteTrigger(mKickTimer);
         mKickTimer = null;
     }
 }
Esempio n. 10
0
        public void OnSessionCreated(IClient client, Session session, Deferrals deferrals)
        {
            // Check if this is a new or reconnecting queuePlayer
            var queuePlayer = this.queue.Players.SingleOrDefault(p => p.Session.UserId == session.UserId);

            if (queuePlayer == null)
            {
                this.Logger.Debug($"Creating new queuePlayer for {session.User.Name}");
                queuePlayer = new QueuePlayer(client, session, deferrals);

                // Check if the player is in the priorityPlayers list and assign the configured priority
                var priorityPlayer = this.Configuration.PriorityPlayers.FirstOrDefault(p => p.SteamId == session.User.SteamId);
                if (priorityPlayer != null)
                {
                    queuePlayer.Priority = priorityPlayer.Priority;
                }

                this.queue.Players.Add(queuePlayer);
            }
            else
            {
                this.Logger.Debug($"Reassigning queuePlayer to connected player: {session.User.Name}");
                queuePlayer.Client    = client;
                queuePlayer.Session   = session;
                queuePlayer.Deferrals = deferrals;
                var oldThread = this.queue.Threads.SingleOrDefault(t => t.Key.Session.UserId == session.UserId).Key;
                if (oldThread != null)
                {
                    this.Logger.Debug($"Disposing of old thread for player: {session.User.Name}");
                    this.queue.Threads[oldThread].Item2.Cancel();
                    this.queue.Threads[oldThread].Item1.Wait();
                    this.queue.Threads[oldThread].Item2.Dispose();
                    this.queue.Threads[oldThread].Item1.Dispose();
                    this.queue.Threads.Remove(oldThread);
                }
                queuePlayer.Status = QueueStatus.Queued;
            }
            this.Logger.Debug($"Adding new thread for player: {session.User.Name}");
            var cancellationToken = new CancellationTokenSource();

            this.queue.Threads.Add(queuePlayer, new Tuple <Task, CancellationTokenSource>(Task.Factory.StartNew(() => MonitorPlayer(queuePlayer, cancellationToken.Token), cancellationToken.Token), cancellationToken));
        }
Esempio n. 11
0
        public async Task SubstitutePlayerAsync(long queueId, SocketUser subPlayer, SocketUser currentPlayer)
        {
            var author = Context.Message.Author;

            try
            {
                if (subPlayer.Id == currentPlayer.Id)
                {
                    await ReplyAsync($"{author.Mention}, you cannot sub the user for himself!");

                    return;
                }

                if (subPlayer.IsBot || currentPlayer.IsBot)
                {
                    await ReplyAsync($"{author.Mention}, you can't sub a bot into a queue!");

                    return;
                }

                // retrieve the queue data if it exists
                var queue = await Database.GetQueueAsync(queueId);

                if (queue == null)
                {
                    await ReplyAsync($"{author.Mention}, queue {queueId} doesn't exist!");

                    return;
                }

                // check if queue score is not yet set
                if (queue.ScoreTeamA != 0 || queue.ScoreTeamB != 0)
                {
                    await ReplyAsync($"{author.Mention}, the score for queue {queueId} has already been submitted, so players can't be substituted anymore!");

                    return;
                }

                List <QueuePlayer> players = await Database.GetQueuePlayersAsync(queueId);

                if (players.Count == 0)
                {
                    await ReplyAsync($"{author.Mention}, failed to retrieve the players from queue {queueId}, please try again.");

                    return;
                }

                // check if the player to sub out is in the queue and the player to sub in isn't
                QueuePlayer currentInQueue = null;
                foreach (QueuePlayer rec in players)
                {
                    if (rec.UserId == currentPlayer.Id)
                    {
                        currentInQueue = rec;
                    }
                    else if (rec.UserId == subPlayer.Id)
                    {
                        await ReplyAsync($"{author.Mention}, the player {subPlayer}, who is to be subbed in is already in queue {queueId}");

                        return;
                    }
                }

                if (currentInQueue == null)
                {
                    await ReplyAsync($"{author.Mention}, the player {currentPlayer}, who is to be subbed out is not in queue {queueId}");

                    return;
                }

                if (Context.Message.Author.Id != RLBot.APPLICATION_OWNER_ID && players.SingleOrDefault(x => x.UserId == Context.Message.Author.Id).Team != currentInQueue.Team)
                {
                    await ReplyAsync($"{author.Mention}, you can only substitute players from your own team!");

                    return;
                }

                await Database.SubstituteQueuePlayerAsync(queueId, subPlayer.Id, currentPlayer.Id);

                var voiceChannel = Context.Guild.VoiceChannels.SingleOrDefault(x => x.Name.Equals($"Team {(currentInQueue.Team == 0 ? "A" : "B")} #{queueId}"));
                await voiceChannel.AddPermissionOverwriteAsync(subPlayer, teamPerms);

                await voiceChannel.RemovePermissionOverwriteAsync(currentPlayer);

                await ReplyAsync($"Queue {queueId}: {subPlayer} substituted {currentPlayer}!");
            }
            catch (Exception ex)
            {
                await ReplyAsync(ex.Message);
            }
        }
Esempio n. 12
0
        private void OnRconCommand(string command, List <object> objargs)
        {
            if (command.ToLowerInvariant() != "queue")
            {
                return;
            }
            Function.Call(Hash.CANCEL_EVENT);
            List <string> args = objargs.Cast <string>().ToList();

            if (args.Count == 0)
            {
                args.Add("help");
            }
            switch (args.First().ToLowerInvariant())
            {
            case "reload":
                string initServerName = _config.ServerName;
                _config            = Config.Load(_configPath);
                _config.ServerName = initServerName;
                break;

            case "clear":
                foreach (QueuePlayer playerToClear in _queue)
                {
                    ((CallbackDelegate)playerToClear.Deferrals?.ToList()[1].Value)?.Invoke("Queue reset");
                }
                _queue.Clear();
                Log("Queue cleared!");
                break;

            case "add":
                if (args.Count < 2)
                {
                    Log("Please pass a steam ID to add to the queue");
                    return;
                }
                // Check if the player is in the priority list
                PriorityPlayer priorityPlayer = _config.PriorityPlayers.FirstOrDefault(p => p.SteamId == args[1]);
                // Add to queue
                AddToQueue(new QueuePlayer
                {
                    SteamId        = args[1],
                    Name           = $"Manual Player - {args[1]}",
                    JoinCount      = 1,
                    JoinTime       = DateTime.UtcNow,
                    DisconnectTime = DateTime.UtcNow,
                    Status         = QueueStatus.Disconnected,
                    Priority       = priorityPlayer?.Priority ?? 100
                }
                           );
                break;

            case "remove":
                if (args.Count < 2)
                {
                    Log("Please pass a steam ID to remove from the queue");
                    return;
                }
                QueuePlayer playerToRemove = _queue.FirstOrDefault(p => p.SteamId == args[1]);
                if (playerToRemove == null)
                {
                    Log("Player not found in queue");
                    return;
                }

                ((CallbackDelegate)playerToRemove.Deferrals?.ToList()[1].Value)?.Invoke("Force removed from queue.");
                _queue.Remove(playerToRemove);
                Log($"Player {playerToRemove.Name} ({playerToRemove.SteamId}) removed from queue");
                break;

            case "status":
                Log("Queue:");
                foreach (QueuePlayer queuePlayer in _queue)
                {
                    Log($"{_queue.IndexOf(queuePlayer) + 1}: " +
                        $"{queuePlayer.Name} - {queuePlayer.SteamId} " +
                        $"[Priority: {queuePlayer.Priority}] " +
                        $"[Status: {Enum.GetName(typeof(QueueStatus), queuePlayer.Status)}] " +
                        $"[Joined: {queuePlayer.JoinTime.ToLocalTime()}]");
                }
                break;

            case "move":
                if (args.Count < 2)
                {
                    Log("Please pass a steam ID to move");
                    return;
                }

                QueuePlayer playerToMove = _queue.FirstOrDefault(p => p.SteamId == args[1]);
                if (playerToMove == null)
                {
                    Log("Player not found in queue");
                    return;
                }

                if (args.Count < 3)
                {
                    args.Add("1");                     // Default to first in queue
                }
                _queue.Remove(playerToMove);
                _queue.Insert(int.Parse(args[2]) - 1, playerToMove);

                Log($"Moved player {playerToMove.Name} ({playerToMove.SteamId}) to position {args[2]}");

                break;

            case "help":
                Log("IgiCore - Queue: Help" + Environment.NewLine +
                    "                   reload: Reload the queue config file" + Environment.NewLine +
                    "                    clear: Force remove all currently queued players" + Environment.NewLine +
                    "            add <steamid>: Manually insert a steamid into the queue (useful for debugging purposes)" + Environment.NewLine +
                    "         remove <steamid>: Remove a specific steamid from the queue" + Environment.NewLine +
                    "move <steamid> [position]: Move a specific steamid to a position in the queue (defaults to 1st in queue if not passed a position)" + Environment.NewLine +
                    "                   status: Display the current list of players in the queue"
                    );
                break;

            default:
                Log("No such command exists, please type 'queue help' for help.");
                break;
            }
        }
Esempio n. 13
0
 private void OnPlayerDisconnect(QueuePlayer queuePlayer, string disconnectMessage)
 {
     DebugLog($"Disconnected: {queuePlayer.Name}");
     queuePlayer.Status         = QueueStatus.Disconnected;
     queuePlayer.DisconnectTime = DateTime.UtcNow;
 }
Esempio n. 14
0
        public async Task MonitorPlayer(QueuePlayer queuePlayer, CancellationToken cancellationToken)
        {
            this.Logger.Debug($"Starting new thread {Thread.CurrentThread.ManagedThreadId}");
            var serverBootTime = this.Events.Request <DateTime>(BootEvents.GetTime);

            while (!cancellationToken.IsCancellationRequested && queuePlayer.Status == QueueStatus.RestartConnected || queuePlayer.Status == QueueStatus.RestartQueued)
            {
                await BaseScript.Delay((int)this.Configuration.DeferralDelay);

                if (queuePlayer.Status == QueueStatus.RestartConnected && DateTime.UtcNow.Subtract(serverBootTime).TotalMilliseconds < this.Configuration.RestartReconnectGrace)
                {
                    continue;
                }
                if (queuePlayer.Status == QueueStatus.RestartQueued && DateTime.UtcNow.Subtract(serverBootTime).TotalMilliseconds < this.Configuration.RestartRequeueGrace)
                {
                    continue;
                }
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }
                this.Logger.Debug($"Thread({Thread.CurrentThread.ManagedThreadId}): Removing player due to expired restart grace period: {queuePlayer.Session.User.Name}, Status: {queuePlayer.Status}");
                queuePlayer.Status = QueueStatus.Disconnected;
                using (var context = new StorageContext())
                {
                    context.QueuePlayers.AddOrUpdate(new QueuePlayerDto(queuePlayer, Convert.ToInt16(this.queue.Players.IndexOf(queuePlayer))));
                    await context.SaveChangesAsync(cancellationToken);
                }
                this.queue.Players.Remove(queuePlayer);
                this.queue.Threads.Remove(queuePlayer);
                return;
            }

            if (!cancellationToken.IsCancellationRequested)
            {
                queuePlayer.Defer();
            }
            while (!cancellationToken.IsCancellationRequested && queuePlayer.Status == QueueStatus.Queued)
            {
                await BaseScript.Delay((int)this.Configuration.DeferralDelay);

                queuePlayer.Update();
            }
            while (!cancellationToken.IsCancellationRequested && queuePlayer.Status == QueueStatus.Disconnected)
            {
                await BaseScript.Delay((int)this.Configuration.DeferralDelay);

                if (DateTime.UtcNow.Subtract(queuePlayer.Session.Disconnected ?? DateTime.UtcNow).TotalMilliseconds < this.Configuration.DisconnectGrace)
                {
                    continue;
                }
                this.Logger.Debug($"Thread({Thread.CurrentThread.ManagedThreadId}): Removing player due to expired disconnected grace period: {queuePlayer.Session.User.Name}");
                this.queue.Players.Remove(queuePlayer);
                break;
            }
            if (!cancellationToken.IsCancellationRequested)
            {
                this.queue.Threads.Remove(queuePlayer);
            }
            this.Logger.Debug($"Ending thread {Thread.CurrentThread.ManagedThreadId}");
        }
Esempio n. 15
0
        private void OnRconCommand(string command, List <object> objargs)
        {
            if (command.ToLowerInvariant() != "queue")
            {
                return;
            }
            List <string> args = objargs.Cast <string>().ToList();

            switch (args[0].ToLowerInvariant())
            {
            case "reload":
                string initServerName = _config.ServerName;
                _config            = Config.Load(_configPath);
                _config.ServerName = initServerName;
                break;

            case "clear":
                foreach (QueuePlayer playerToClear in _queue)
                {
                    ((CallbackDelegate)playerToClear.Deferrals?.ToList()[1].Value)?.Invoke("Queue reset");
                }
                _queue.Clear();
                Log("Queue cleared!");
                break;

            case "add":
                if (args.Count < 2)
                {
                    Log("Please pass a steam ID to add to the queue");
                    return;
                }
                // Check if the player is in the priority list
                PriorityPlayer priorityPlayer = _config.PriorityPlayers.FirstOrDefault(p => p.SteamId == args[1]);
                // Add to queue
                AddToQueue(new QueuePlayer
                {
                    SteamId        = args[1],
                    Name           = $"Manual Player - {args[1]}",
                    ConnectCount   = 1,
                    ConnectTime    = DateTime.UtcNow,
                    DisconnectTime = DateTime.UtcNow,
                    Status         = QueueStatus.Disconnected,
                    Priority       = priorityPlayer?.Priority ?? 100
                }
                           );
                break;

            case "remove":
                if (args.Count < 2)
                {
                    Log("Please pass a steam ID to remove from the queue");
                    return;
                }
                QueuePlayer playerToRemove = _queue.FirstOrDefault(p => p.SteamId == args[1]);
                if (playerToRemove == null)
                {
                    Log("Player not found in queue");
                    return;
                }

                ((CallbackDelegate)playerToRemove.Deferrals?.ToList()[1].Value)?.Invoke("Force removed from queue.");
                _queue.Remove(playerToRemove);
                Log($"Player {playerToRemove.Name} ({playerToRemove.SteamId}) removed from queue");
                break;

            case "status":
                Log("Queue:");
                foreach (QueuePlayer queuePlayer in _queue)
                {
                    Log($"{_queue.IndexOf(queuePlayer) + 1}: " +
                        $"{queuePlayer.Name} - {queuePlayer.SteamId} " +
                        $"[Priority: {queuePlayer.Priority}] " +
                        $"[Status: {Enum.GetName(typeof(QueueStatus), queuePlayer.Status)}] " +
                        $"[Connected: {queuePlayer.ConnectTime.ToLocalTime()}]");
                }
                break;

            case "move":
                if (args.Count < 2)
                {
                    Log("Please pass a steam ID to move");
                    return;
                }

                QueuePlayer playerToMove = _queue.FirstOrDefault(p => p.SteamId == args[1]);
                if (playerToMove == null)
                {
                    Log("Player not found in queue");
                    return;
                }

                if (args.Count < 3)
                {
                    args.Add("1");                     // Default to first in queue
                }
                _queue.Remove(playerToMove);
                _queue.Insert(int.Parse(args[2]) - 1, playerToMove);

                Log($"Moved player {playerToMove.Name} ({playerToMove.SteamId}) to position {args[2]}");

                break;

            default:
                Log("No such command exists");
                break;
            }

            Function.Call(Hash.CANCEL_EVENT);
        }