public async Task <(CurrencyRaffleGame, JoinErrorType?)> JoinOrCreateGame(ulong channelId, IUser user, long amount, bool mixed, Func <IUser, long, Task> onEnded) { await _locker.WaitAsync().ConfigureAwait(false); try { var newGame = false; if (!Games.TryGetValue(channelId, out var crg)) { newGame = true; crg = new CurrencyRaffleGame(mixed ? CurrencyRaffleGame.Type.Mixed : CurrencyRaffleGame.Type.Normal); Games.Add(channelId, crg); } //remove money, and stop the game if this // user created it and doesn't have the money if (!await _cs.RemoveAsync(user.Id, "Currency Raffle Join", amount).ConfigureAwait(false)) { if (newGame) { Games.Remove(channelId); } return(null, JoinErrorType.NotEnoughCurrency); } if (!crg.AddUser(user, amount)) { await _cs.AddAsync(user.Id, "Curency Raffle Refund", amount).ConfigureAwait(false); return(null, JoinErrorType.AlreadyJoinedOrInvalidAmount); } if (newGame) { var _t = Task.Run(async() => { await Task.Delay(60000).ConfigureAwait(false); await _locker.WaitAsync().ConfigureAwait(false); try { var winner = crg.GetWinner(); var won = crg.Users.Sum(x => x.Amount); await _cs.AddAsync(winner.DiscordUser.Id, "Currency Raffle Win", won).ConfigureAwait(false); Games.Remove(channelId, out _); var oe = onEnded(winner.DiscordUser, won); } catch { } finally { _locker.Release(); } }); } return(crg, null); } finally { _locker.Release(); } }
public async Task <(CurrencyRaffleGame, JoinErrorType?)> JoinOrCreateGame(ulong channelId, IUser user, int amount, Func <IUser, int, Task> onEnded) { await _locker.WaitAsync().ConfigureAwait(false); try { var newGame = false; if (!Games.TryGetValue(channelId, out var crg)) { newGame = true; crg = new CurrencyRaffleGame(amount); } using (var uow = _db.UnitOfWork) { //remove money, and stop the game if this // user created it and doesn't have the money if (!await _cs.RemoveAsync(user.Id, "Currency Raffle Join", amount, uow).ConfigureAwait(false)) { if (newGame) { Games.Remove(channelId); } return(null, JoinErrorType.NotEnoughCurrency); } if (!crg.AddUser(user)) { await _cs.AddAsync(user.Id, "Curency Raffle Refund", amount, uow).ConfigureAwait(false); return(null, JoinErrorType.AlreadyJoined); } } if (newGame) { var _t = new Timer(async state => { await _locker.WaitAsync().ConfigureAwait(false); try { var users = crg.Users.ToArray(); var rng = new NadekoRandom(); var usr = users[rng.Next(0, users.Length)]; using (var uow = _db.UnitOfWork) { await _cs.AddAsync(usr.Id, "Currency Raffle Win", amount * users.Length, uow); } Games.Remove(channelId, out _); var oe = onEnded(usr, users.Length * amount); } catch { } finally { _locker.Release(); } }, null, 30000, Timeout.Infinite); } return(crg, null); } finally { _locker.Release(); } }