// 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); } }
/// <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 })); }
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(); } }
//获取古战场今日游戏时间,并设置定时器(时间到了,要把玩家踢出副本) 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()); }
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"); }
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); } }
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); } }
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); } }
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; } }
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)); }
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); } }
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; } }
private void OnPlayerDisconnect(QueuePlayer queuePlayer, string disconnectMessage) { DebugLog($"Disconnected: {queuePlayer.Name}"); queuePlayer.Status = QueueStatus.Disconnected; queuePlayer.DisconnectTime = DateTime.UtcNow; }
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}"); }
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); }