async Task NewGame_(DiscordChannel channel, List <DisboardPlayer> players, ConcurrentQueue <Func <Task> > messageQueue, bool isDebug = false) { var disboardChannel = new DisboardChannel(channel, messageQueue, STADispatcher); var gameInitializeData = new DisboardGameInitData(isDebug, Client, disboardChannel, players, OnFinish, messageQueue); DisboardGame game = GameFactory.New(gameInitializeData); if (game.IsFinished) { return; } OnFinish(channel.Id); if (game is DisboardGameUsingDM) { var gameUsesDM = game as DisboardGameUsingDM; foreach (var player in players) { if (GamesByUsers.TryGetValue(player.Id, out var existingGame) && existingGame != game) { player.DM("`기존에 진행중이던 게임이 있습니다. 기존 게임에 다시 참여하려면 기존 채널에서 BOT restoredm을 입력하세요.`"); GamesByUsers.Remove(player.Id, out _); } GamesByUsers.TryAdd(player.Id, gameUsesDM !); } } await RunInLockAndProcessMessage(game, () => { Games.TryAdd(channel.Id, game); }, gameIsInGameList : false); }
async Task RunInLockAndProcessMessage(DisboardGame game, Action task, bool gameIsInGameList = true) { using (await game.Semaphore.LockAsync().ConfigureAwait(false)) { if (gameIsInGameList == false || Games.Values.ToList().Contains(game)) { await RunAndProcessMessage(task, game.MessageQueue); } } }
async Task OnGroupReaction(DisboardGame game, DisboardPlayer player, DiscordEmoji emoji) { Action task; if (game.IsDebug) { task = () => game.Channel.Send("`인원을 시뮬레이션 할 때에는 리액션이 지원되지 않습니다.`"); } else { task = () => game.OnGroupReaction(player, emoji); } await RunInLockAndProcessMessage(game, task); }
async Task OnGroup(DisboardGame game, DisboardPlayer player, string content) { var split = content.Split(" ").ToList(); if (game.IsDebug) { if (split.Count > 0 && int.TryParse(split[0], out int playerIndex) && 0 <= playerIndex && playerIndex < game.InitialPlayers.Count) { player = game.InitialPlayers[playerIndex]; content = string.Join(' ', split.Skip(1)); } else { return; } } await RunInLockAndProcessMessage(game, () => game.OnGroup(player, content)); }