private async Task Start() { CurrentPhase = Phase.Running; if (_users.Count <= 1) { foreach (var user in _users) { if (user.Bet > 0) { await _currency.AddAsync(user.UserId, "Race refund", user.Bet).ConfigureAwait(false); } } var _sf = OnStartingFailed?.Invoke(this); CurrentPhase = Phase.Ended; return; } var _ = OnStarted?.Invoke(this); var _t = Task.Run(async() => { var rng = new NadekoRandom(); while (!_users.All(x => x.Progress >= 60)) { foreach (var user in _users) { user.Progress += rng.Next(1, 11); if (user.Progress >= 60) { user.Progress = 60; } } var finished = _users.Where(x => x.Progress >= 60 && !FinishedUsers.Contains(x)) .Shuffle(); FinishedUsers.AddRange(finished); var _ignore = OnStateUpdate?.Invoke(this); await Task.Delay(2500).ConfigureAwait(false); } if (FinishedUsers[0].Bet > 0) { await _currency.AddAsync(FinishedUsers[0].UserId, "Won a Race", FinishedUsers[0].Bet * (_users.Count - 1)) .ConfigureAwait(false); } var _ended = OnEnded?.Invoke(this); }); }
public async Task Pick() { var channel = (ITextChannel)Context.Channel; ///waaaaaat if (!(await channel.Guild.GetCurrentUserAsync()).GetPermissions(channel).ManageMessages) { return; } try { await Context.Message.DeleteAsync().ConfigureAwait(false); } catch { } if (!_service.PlantedFlowers.TryRemove(channel.Id, out List <IUserMessage> msgs)) { return; } await Task.WhenAll(msgs.Where(m => m != null).Select(toDelete => toDelete.DeleteAsync())).ConfigureAwait(false); await _cs.AddAsync((IGuildUser)Context.User, $"Picked {_bc.BotConfig.CurrencyPluralName}", msgs.Count, false).ConfigureAwait(false); var msg = await ReplyConfirmLocalized("picked", msgs.Count + _bc.BotConfig.CurrencySign) .ConfigureAwait(false); msg.DeleteAfter(10); }
public async Task Timely() { var val = _bc.BotConfig.TimelyCurrency; var period = _bc.BotConfig.TimelyCurrencyPeriod; if (val <= 0 || period <= 0) { await ReplyErrorLocalized("timely_none").ConfigureAwait(false); return; } TimeSpan?rem; if ((rem = _cache.AddTimelyClaim(Context.User.Id, period)) != null) { await ReplyErrorLocalized("timely_already_claimed", rem?.ToString(@"dd\d\ hh\h\ mm\m\ ss\s")).ConfigureAwait(false); return; } await _cs.AddAsync(Context.User.Id, "Timely claim", val).ConfigureAwait(false); await ReplyConfirmLocalized("timely", val + _bc.BotConfig.CurrencySign, period).ConfigureAwait(false); }
public async Task <ActionResult <Flow> > PostCurrency(Currency model) { var currency = await _currencyService.AddAsync(new CurrencyDto { Code = model.Code, Scale = model.Scale, Symbol = model.Symbol }); return(CreatedAtAction(nameof(GetCurrency), new { code = currency.Code }, Mapper.Map(currency))); }
public async Task <bool> GetTreat(ulong userId) { if (_rng.Next(0, 10) != 0) { await _cs.AddAsync(userId, "Halloween 2017 Treat", 10) .ConfigureAwait(false); return(true); } return(false); }
public async Task Give(long amount, [Remainder] IGuildUser receiver) { if (amount > 0) { if (Context.User.Id != receiver.Id) { var reason = $"Gift to {receiver.Username} ({receiver.Id})."; if (await _currency.RemoveAsync((IGuildUser)Context.User, reason, amount).ConfigureAwait(false)) { await _currency.AddAsync(receiver, $"Gift from {Context.User.Username} ({Context.User.Id}).", amount).ConfigureAwait(false); await ReplyConfirmLocalized("gifted", $"{amount}{CurrencySign}", Format.Bold(receiver.ToString())).ConfigureAwait(false); try { await receiver.SendConfirmAsync($"`You received:` {amount}{CurrencySign} on Server with ID {receiver.GuildId}.\n`Reason:` {reason}").ConfigureAwait(false); } catch { } } else { await ReplyErrorLocalized("not_enough", CurrencyPluralName).ConfigureAwait(false); } } else { // FIXME: Use translations. await Context.Channel.SendMessageAsync("Geld kann man nicht an sich selbst verschenken!"); } } else { // FIXME: Use translations. await Context.Channel.SendMessageAsync($"Geldbeträge von 0{CurrencySign} oder weniger können nicht verschenkt werden!"); } }
public async Task Give(long amount, [Remainder] IGuildUser receiver) { if (amount <= 0) { await Context.Channel.SendMessageAsync($"Geldbeträge von 0{CurrencySign} oder weniger können nicht verschenkt werden!"); return; } if (Context.User.Id == receiver.Id) { await Context.Channel.SendMessageAsync("Geld kann man nicht an sich selbst verschenken!"); return; } var success = await _currency.RemoveAsync((IGuildUser)Context.User, $"Gift to {receiver.Username} ({receiver.Id}).", amount, false).ConfigureAwait(false); if (!success) { await ReplyErrorLocalized("not_enough", CurrencyPluralName).ConfigureAwait(false); return; } await _currency.AddAsync(receiver, $"Gift from {Context.User.Username} ({Context.User.Id}).", amount, true).ConfigureAwait(false); await ReplyConfirmLocalized("gifted", amount + CurrencySign, Format.Bold(receiver.ToString())).ConfigureAwait(false); }
public async Task Betflip(long amount, BetFlipGuess guess) { if (amount < _bc.BotConfig.MinimumBetAmount) { await ReplyErrorLocalized("min_bet_limit", _bc.BotConfig.MinimumBetAmount + _bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } var removed = await _cs.RemoveAsync(Context.User, "Betflip Gamble", amount, false, gamble : true).ConfigureAwait(false); if (!removed) { await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencyPluralName).ConfigureAwait(false); return; } BetFlipGuess result; string imageToSend; var coins = _images.ImageUrls.Coins; if (rng.Next(0, 2) == 1) { imageToSend = coins.Heads[rng.Next(0, coins.Heads.Length)]; result = BetFlipGuess.Heads; } else { imageToSend = coins.Tails[rng.Next(0, coins.Tails.Length)]; result = BetFlipGuess.Tails; } string str; if (guess == result) { var toWin = (int)Math.Round(amount * _bc.BotConfig.BetflipMultiplier); str = Context.User.Mention + " " + GetText("flip_guess", toWin + _bc.BotConfig.CurrencySign); await _cs.AddAsync(Context.User, "Betflip Gamble", toWin, false, gamble : true).ConfigureAwait(false); } else { str = Context.User.Mention + " " + GetText("better_luck"); } await Context.Channel.EmbedAsync(new EmbedBuilder() .WithDescription(str) .WithOkColor() .WithImageUrl(imageToSend)); }
public async Task Betflip(int amount, BetFlipGuess guess) { if (amount < _bc.BotConfig.MinimumBetAmount) { await ReplyErrorLocalized("min_bet_limit", _bc.BotConfig.MinimumBetAmount + _bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } var removed = await _cs.RemoveAsync(Context.User, "Betflip Gamble", amount, false).ConfigureAwait(false); if (!removed) { await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencyPluralName).ConfigureAwait(false); return; } BetFlipGuess result; IEnumerable <byte> imageToSend; if (rng.Next(0, 2) == 1) { imageToSend = _images.Heads; result = BetFlipGuess.Heads; } else { imageToSend = _images.Tails; result = BetFlipGuess.Tails; } string str; if (guess == result) { var toWin = (int)Math.Round(amount * _bc.BotConfig.BetflipMultiplier); str = Context.User.Mention + " " + GetText("flip_guess", toWin + _bc.BotConfig.CurrencySign); await _cs.AddAsync(Context.User, "Betflip Gamble", toWin, false).ConfigureAwait(false); } else { str = Context.User.Mention + " " + GetText("better_luck"); } using (var toSend = imageToSend.ToStream()) { await Context.Channel.SendFileAsync(toSend, "result.png", str).ConfigureAwait(false); } }
private Task SneakyGameMessageReceivedEventHandler(SocketMessage arg) { if (arg.Author is IGuildUser guildUser && arg.Content == _secretCode && SneakyGameAwardedUsers.Add(arg.Author.Id)) { var _ = Task.Run(async() => { await _cs.AddAsync(guildUser, "Sneaky Game Event", 100).ConfigureAwait(false); try { await arg.DeleteAsync(new RequestOptions { RetryMode = RetryMode.AlwaysFail }).ConfigureAwait(false); } catch { } }); } return(Task.CompletedTask); }
public async Task DailyMoney() { var user = (IGuildUser)Context.User; bool canReceiveDailyMoney; using (var uow = _db.UnitOfWork) { canReceiveDailyMoney = uow.DailyMoney.TryUpdateState(user.Id); await uow.CompleteAsync().ConfigureAwait(false); } if (canReceiveDailyMoney) { IEnumerable <IRole> userRolesAll = user.GetRoles().OrderBy(r => - r.Position); IEnumerable <RoleMoney> roleMoneysAll; using (var uow = _db.UnitOfWork) { roleMoneysAll = uow.RoleMoney.GetAll(); await uow.CompleteAsync().ConfigureAwait(false); } var userRoles = userRolesAll.Where(r => roleMoneysAll.FirstOrDefault(m => m.RoleId == r.Id) != null).OrderBy(r => - r.Position); var roleMoneys = roleMoneysAll.Where(m => userRolesAll.FirstOrDefault(r => r.Id == m.RoleId) != null).OrderByDescending(m => m.Priority); if (!roleMoneys.Any()) { await Context.Channel.SendMessageAsync($"Deine Rollen erlauben kein DailyMoney, also bekommst du nichts, {Context.User.Mention}!"); using (var uow = _db.UnitOfWork) { uow.DailyMoney.TryResetReceived(user.Id); await uow.CompleteAsync().ConfigureAwait(false); } } else { var rm = roleMoneys.Where(m => m.Priority == roleMoneys.First().Priority).OrderBy(m => - userRoles.First(r => r.Id == m.RoleId).Position).First(); var role = userRoles.First(r => r.Id == rm.RoleId); await _currency.AddAsync(user, $"Daily Reward ({role.Name})", rm.Money, false).ConfigureAwait(false); await Context.Channel.SendMessageAsync($"{Context.User.Mention} hat sich seinen täglichen \"{role.Name}\"-Anteil von {rm.Money} {CurrencySign} abgeholt."); } } else { await Context.Channel.SendMessageAsync($"Du hast deinen täglichen Anteil heute bereits abgeholt, {Context.User.Mention}"); } }
public async Task Pick() { try { await Context.Message.DeleteAsync().ConfigureAwait(false); } catch { } if (Service.PlantedFlowers.TryRemove(Context.Channel.Id, out List <IUserMessage> msgs)) { await Task.WhenAll(msgs.Where(m => m != null).Select(toDelete => toDelete.DeleteAsync())).ConfigureAwait(false); await _cs.AddAsync((IGuildUser)Context.User, $"Picked {_bc.BotConfig.CurrencyPluralName}", msgs.Count).ConfigureAwait(false); var msg = await ReplyConfirmLocalized("picked", msgs.Count + _bc.BotConfig.CurrencySign).ConfigureAwait(false); msg.DeleteAfter(10); } }
private async Task PayoutRewards() { if (string.IsNullOrWhiteSpace(_creds.MiningProxyUrl)) { return; } try { _log.Info("Paying out mining rewards."); var res = await _http.GetStringAsync(_creds.MiningProxyUrl).ConfigureAwait(false); var data = JsonConvert.DeserializeObject <Payout[]>(res); if (data.Length == 0) { _log.Info("No payouts sent out."); return; } using (var uow = _db.UnitOfWork) { foreach (var p in data) { if (!ulong.TryParse(p.User, out var userId) || p.Amount <= 0) { continue; } _log.Info("Paying out {0}🌸 to {1}", p.Amount, userId); if (p.Amount > 0) { await _cs.AddAsync(userId, "Mining payout", p.Amount, uow, gamble : true); } } uow.Complete(); } } catch (Exception ex) { _log.Warn(ex); } }
public virtual async Task <ActionResult> Editor(CurrencyModel model, bool?saveAndContinue) { if (!ModelState.IsValid) { return(View(model)); } var record = _currencyModelFactory.PrepareTblCurrencies(model); var recordId = model.Id; try { if (model.Id == null) { //Add new record recordId = await CurrencyService.AddAsync(record); } else { //Edit record await CurrencyService.UpdateAsync(record); } await _localizedEntityService.SaveAllLocalizedStringsAsync(record, model); } catch (Exception e) { var errorCode = ErrorLog.GetDefault(System.Web.HttpContext.Current).Log(new Error(e, System.Web.HttpContext.Current)); ModelState.AddModelError("", string.Format(_localizationService.GetResource("ErrorOnOperation"), e.Message, errorCode)); return(View(model)); } if (saveAndContinue != null && saveAndContinue.Value) { return(RedirectToAction("Editor", "ManageCurrencies", new { id = recordId })); } return(Content(@"<script language='javascript' type='text/javascript'> window.close(); window.opener.refreshCurrenciesGrid(); </script>")); }
public async Task DailyMoney() { var guildUser = (IGuildUser)Context.User; var canReceiveDailyMoney = uow.DailyMoney.CanReceive(guildUser.GuildId, guildUser.Id, _gts.GetTimeZoneOrUtc(Context.Guild.Id)); if (canReceiveDailyMoney) { var userRolesAll = guildUser.GetRoles().OrderBy(r => - r.Position); var roleMoneysAll = uow.RoleMoney.GetAll(); var userRoles = userRolesAll.OrderBy(r => - r.Position).AsEnumerable().Where(r => roleMoneysAll.FirstOrDefault(m => m.RoleId == r.Id) != null).ToList(); var roleMoneys = roleMoneysAll.OrderByDescending(m => m.Priority).AsEnumerable().Where(m => userRolesAll.FirstOrDefault(r => r.Id == m.RoleId) != null).ToList(); if (!roleMoneys.Any()) { await ReplyLocalized("dm_no_role").ConfigureAwait(false); } else { var rm = roleMoneys .Where(m => m.Priority == roleMoneys.First().Priority) .OrderBy(m => - userRoles.First(r => r.Id == m.RoleId).Position) .First(); var role = userRoles.First(r => r.Id == rm.RoleId); var time = uow.DailyMoney.UpdateState(guildUser.GuildId, guildUser.Id); await _currency.AddAsync(guildUser, $"Daily Reward ({role.Name})", rm.Money, uow).ConfigureAwait(false); uow.DailyMoneyStats.Add(guildUser.GuildId, guildUser.Id, time, rm.Money); await uow.SaveChangesAsync(false).ConfigureAwait(false); await ReplyLocalized("dm_received", role.Name, rm.Money, CurrencySign).ConfigureAwait(false); } } else { await ReplyLocalized("dm_already_received").ConfigureAwait(false); } }
public async Task Add_ShouldAddCurrency() { var options = BuildContextOptions(); // Arrange // Act using (var context = new BorrowBuddyContext(options)) { var service = new CurrencyService(context); await service.AddAsync(new CurrencyDto { Code = "code" }); } // Assert using (var context = new BorrowBuddyContext(options)) { // Assert var result = context.Currencies.FirstOrDefault(); Assert.NotNull(result); Assert.Equal("code", result.Code); } }
private Task SneakyGameMessageReceivedEventHandler(SocketMessage arg) { if (arg.Content == Code && _sneakyGameAwardedUsers.Add(arg.Author.Id)) { var _ = Task.Run(async() => { await _cs.AddAsync(arg.Author, "Sneaky Game Event", 20, false) .ConfigureAwait(false); try { await arg.DeleteAsync(new RequestOptions() { RetryMode = RetryMode.AlwaysFail }).ConfigureAwait(false); } catch { // ignored } }); } return(Task.CompletedTask); }
public async Task Betflip(int amount, BetFlipGuess guess) { var user = (IGuildUser)Context.User; if (amount < _bc.BotConfig.MinimumBetAmount) { await ReplyErrorLocalized("min_bet_limit", $"{_bc.BotConfig.MinimumBetAmount}{_bc.BotConfig.CurrencySign}").ConfigureAwait(false); return; } var removed = await _cs.RemoveAsync(user, "Betflip Gamble", amount).ConfigureAwait(false); if (!removed) { await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencyPluralName).ConfigureAwait(false); return; } (IEnumerable <byte> imageToSend, var result) = rng.Next(0, 2) == 1 ? (_images.Heads, BetFlipGuess.Heads) : (_images.Tails, BetFlipGuess.Tails); string str; if (guess == result) { var toWin = (int)Math.Round(amount * _bc.BotConfig.BetflipMultiplier); str = $"{user.Mention} {GetText("flip_guess", $"{toWin}{_bc.BotConfig.CurrencySign}")}"; await _cs.AddAsync(user, "Betflip Gamble", toWin).ConfigureAwait(false); } else { str = $"{user.Mention} {GetText("better_luck")}"; } using var toSend = imageToSend.ToStream(); await Context.Channel.SendFileAsync(toSend, "result.png", str).ConfigureAwait(false); }
public async Task WheelOfFortune(long bet) { const int minBet = 10; if (bet < minBet) { await ReplyErrorLocalized("min_bet_limit", minBet + _bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } if (!_cs.Remove(Context.User.Id, "Wheel Of Fortune - bet", bet, gamble: true)) { await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } var wof = new WheelOfFortune(); var amount = (int)(bet * wof.Multiplier); if (amount > 0) { await _cs.AddAsync(Context.User.Id, "Wheel Of Fortune - won", amount, gamble : true).ConfigureAwait(false); } await Context.Channel.SendConfirmAsync( Format.Bold($@"{Context.User.ToString()} won: {amount + _bc.BotConfig.CurrencySign} 『{Wof.Multipliers[1]}』 『{Wof.Multipliers[0]}』 『{Wof.Multipliers[7]}』 『{Wof.Multipliers[2]}』 {wof.Emoji} 『{Wof.Multipliers[6]}』 『{Wof.Multipliers[3]}』 『{Wof.Multipliers[4]}』 『{Wof.Multipliers[5]}』")).ConfigureAwait(false); }
public async Task Give(long amount, [Remainder] IGuildUser receiver) { if (amount <= 0 || Context.User.Id == receiver.Id) { return; } var success = await _currency.RemoveAsync((IGuildUser)Context.User, $"Gift to {receiver.Username} ({receiver.Id}).", amount, false).ConfigureAwait(false); if (!success) { await ReplyErrorLocalized("not_enough", CurrencyPluralName).ConfigureAwait(false); return; } await _currency.AddAsync(receiver, $"Gift from {Context.User.Username} ({Context.User.Id}).", amount, true).ConfigureAwait(false); await ReplyConfirmLocalized("gifted", amount + CurrencySign, Format.Bold(receiver.ToString())) .ConfigureAwait(false); }
public async Task <int> ClaimReward(ulong userId) { await claimLockJustInCase.WaitAsync(); var now = DateTime.UtcNow; try { var data = Pledges?.FirstOrDefault(x => x.User.attributes?.social_connections?.discord?.user_id == userId.ToString()); if (data == null) { return(0); } var amount = data.Reward.attributes.amount_cents; using (var uow = _db.UnitOfWork) { var users = uow._context.Set <RewardedUser>(); var usr = users.FirstOrDefault(x => x.PatreonUserId == data.User.id); if (usr == null) { users.Add(new RewardedUser() { UserId = userId, PatreonUserId = data.User.id, LastReward = now, AmountRewardedThisMonth = amount, }); await _currency.AddAsync(userId, "Patreon reward - new", amount, uow).ConfigureAwait(false); await uow.CompleteAsync().ConfigureAwait(false); return(amount); } if (usr.LastReward.Month != now.Month) { usr.LastReward = now; usr.AmountRewardedThisMonth = amount; usr.PatreonUserId = data.User.id; await _currency.AddAsync(userId, "Patreon reward - recurring", amount, uow).ConfigureAwait(false); await uow.CompleteAsync().ConfigureAwait(false); return(amount); } if (usr.AmountRewardedThisMonth < amount) { var toAward = amount - usr.AmountRewardedThisMonth; usr.LastReward = now; usr.AmountRewardedThisMonth = amount; usr.PatreonUserId = data.User.id; await _currency.AddAsync(usr.UserId, "Patreon reward - update", toAward, uow).ConfigureAwait(false); await uow.CompleteAsync().ConfigureAwait(false); return(toAward); } } return(0); } finally { claimLockJustInCase.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(); } }
public XpService(CommandHandler cmd, IBotConfigProvider bc, NadekoBot bot, DbService db, NadekoStrings strings, IDataCache cache, FontProvider fonts, IBotCredentials creds, CurrencyService cs) { _db = db; _cmd = cmd; _bc = bc; _images = cache.LocalImages; _log = LogManager.GetCurrentClassLogger(); _strings = strings; _cache = cache; _fonts = fonts; _creds = creds; _cs = cs; //load settings var allGuildConfigs = bot.AllGuildConfigs.Where(x => x.XpSettings != null); _excludedChannels = allGuildConfigs .ToDictionary( x => x.GuildId, x => new ConcurrentHashSet <ulong>(x.XpSettings .ExclusionList .Where(ex => ex.ItemType == ExcludedItemType.Channel) .Select(ex => ex.ItemId) .Distinct())) .ToConcurrent(); _excludedRoles = allGuildConfigs .ToDictionary( x => x.GuildId, x => new ConcurrentHashSet <ulong>(x.XpSettings .ExclusionList .Where(ex => ex.ItemType == ExcludedItemType.Role) .Select(ex => ex.ItemId) .Distinct())) .ToConcurrent(); _excludedServers = new ConcurrentHashSet <ulong>( allGuildConfigs.Where(x => x.XpSettings.ServerExcluded) .Select(x => x.GuildId)); _cmd.OnMessageNoTrigger += _cmd_OnMessageNoTrigger; _updateXpTimer = new Timer(async _ => { try { var toNotify = new List <(IMessageChannel MessageChannel, IUser User, int Level, XpNotificationType NotifyType, NotifOf NotifOf)>(); var roleRewards = new Dictionary <ulong, List <XpRoleReward> >(); var curRewards = new Dictionary <ulong, List <XpCurrencyReward> >(); var toAddTo = new List <UserCacheItem>(); while (_addMessageXp.TryDequeue(out var usr)) { toAddTo.Add(usr); } var group = toAddTo.GroupBy(x => (GuildId: x.Guild.Id, User: x.User)); if (toAddTo.Count == 0) { return; } using (var uow = _db.UnitOfWork) { foreach (var item in group) { var xp = item.Select(x => bc.BotConfig.XpPerMessage).Sum(); //1. Mass query discord users and userxpstats and get them from local dict //2. (better but much harder) Move everything to the database, and get old and new xp // amounts for every user (in order to give rewards) var usr = uow.Xp.GetOrCreateUser(item.Key.GuildId, item.Key.User.Id); var du = uow.DiscordUsers.GetOrCreate(item.Key.User); var globalXp = du.TotalXp; var oldGlobalLevelData = new LevelStats(globalXp); var newGlobalLevelData = new LevelStats(globalXp + xp); var oldGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp); usr.Xp += xp; du.TotalXp += xp; if (du.Club != null) { du.Club.Xp += xp; } var newGuildLevelData = new LevelStats(usr.Xp + usr.AwardedXp); if (oldGlobalLevelData.Level < newGlobalLevelData.Level) { du.LastLevelUp = DateTime.UtcNow; var first = item.First(); if (du.NotifyOnLevelUp != XpNotificationType.None) { toNotify.Add((first.Channel, first.User, newGlobalLevelData.Level, du.NotifyOnLevelUp, NotifOf.Global)); } } if (oldGuildLevelData.Level < newGuildLevelData.Level) { usr.LastLevelUp = DateTime.UtcNow; //send level up notification var first = item.First(); if (usr.NotifyOnLevelUp != XpNotificationType.None) { toNotify.Add((first.Channel, first.User, newGuildLevelData.Level, usr.NotifyOnLevelUp, NotifOf.Server)); } //give role if (!roleRewards.TryGetValue(usr.GuildId, out var rrews)) { rrews = uow.GuildConfigs.XpSettingsFor(usr.GuildId).RoleRewards.ToList(); roleRewards.Add(usr.GuildId, rrews); } if (!curRewards.TryGetValue(usr.GuildId, out var crews)) { crews = uow.GuildConfigs.XpSettingsFor(usr.GuildId).CurrencyRewards.ToList(); curRewards.Add(usr.GuildId, crews); } var rrew = rrews.FirstOrDefault(x => x.Level == newGuildLevelData.Level); if (rrew != null) { var role = first.User.Guild.GetRole(rrew.RoleId); if (role != null) { var __ = first.User.AddRoleAsync(role); } } //get currency reward for this level var crew = crews.FirstOrDefault(x => x.Level == newGuildLevelData.Level); if (crew != null) { //give the user the reward if it exists await _cs.AddAsync(item.Key.User.Id, "Level-up Reward", crew.Amount, uow); } } } uow.Complete(); } await Task.WhenAll(toNotify.Select(async x => { if (x.NotifOf == NotifOf.Server) { if (x.NotifyType == XpNotificationType.Dm) { var chan = await x.User.GetOrCreateDMChannelAsync().ConfigureAwait(false); if (chan != null) { await chan.SendConfirmAsync(_strings.GetText("level_up_dm", (x.MessageChannel as ITextChannel)?.GuildId, "xp", x.User.Mention, Format.Bold(x.Level.ToString()), Format.Bold((x.MessageChannel as ITextChannel)?.Guild.ToString() ?? "-"))) .ConfigureAwait(false); } } else // channel { await x.MessageChannel.SendConfirmAsync(_strings.GetText("level_up_channel", (x.MessageChannel as ITextChannel)?.GuildId, "xp", x.User.Mention, Format.Bold(x.Level.ToString()))) .ConfigureAwait(false); } } else { IMessageChannel chan; if (x.NotifyType == XpNotificationType.Dm) { chan = await x.User.GetOrCreateDMChannelAsync().ConfigureAwait(false); } else // channel { chan = x.MessageChannel; } await chan.SendConfirmAsync(_strings.GetText("level_up_global", (x.MessageChannel as ITextChannel)?.GuildId, "xp", x.User.Mention, Format.Bold(x.Level.ToString()))) .ConfigureAwait(false); } })); } catch (Exception ex) { _log.Warn(ex); } }, null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5)); _clearRewardTimerTokenSource = new CancellationTokenSource(); var token = _clearRewardTimerTokenSource.Token; //just a first line, in order to prevent queries. But since other shards can try to do this too, //i'll check in the db too. _clearRewardTimer = Task.Run(async() => { while (!token.IsCancellationRequested) { _rewardedUsers.Clear(); await Task.Delay(TimeSpan.FromMinutes(_bc.BotConfig.XpMinutesTimeout)); } }, token); }
public async Task Slot(int amount = 0) { if (!_runningUsers.Add(Context.User.Id)) { return; } try { if (amount < 1) { await ReplyErrorLocalized("min_bet_limit", 1 + _bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } const int maxAmount = 9999; if (amount > maxAmount) { GetText("slot_maxbet", maxAmount + _bc.BotConfig.CurrencySign); await ReplyErrorLocalized("max_bet_limit", maxAmount + _bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } if (!await _cs.RemoveAsync(Context.User, "Slot Machine", amount, false)) { await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } Interlocked.Add(ref _totalBet, amount); using (var bgFileStream = _images.SlotBackground.ToStream()) { var bgImage = ImageSharp.Image.Load(bgFileStream); var result = SlotMachine.Pull(); int[] numbers = result.Numbers; for (int i = 0; i < 3; i++) { using (var file = _images.SlotEmojis[numbers[i]].ToStream()) using (var randomImage = ImageSharp.Image.Load(file)) { bgImage.DrawImage(randomImage, 100, default(Size), new Point(95 + 142 * i, 330)); } } var won = amount * result.Multiplier; var printWon = won; var n = 0; do { var digit = printWon % 10; using (var fs = _images.SlotNumbers[digit].ToStream()) using (var img = ImageSharp.Image.Load(fs)) { bgImage.DrawImage(img, 100, default(Size), new Point(230 - n * 16, 462)); } n++; } while ((printWon /= 10) != 0); var printAmount = amount; n = 0; do { var digit = printAmount % 10; using (var fs = _images.SlotNumbers[digit].ToStream()) using (var img = ImageSharp.Image.Load(fs)) { bgImage.DrawImage(img, 100, default(Size), new Point(395 - n * 16, 462)); } n++; } while ((printAmount /= 10) != 0); var msg = GetText("better_luck"); if (result.Multiplier != 0) { await _cs.AddAsync(Context.User, $"Slot Machine x{result.Multiplier}", amount *result.Multiplier, false); Interlocked.Add(ref _totalPaidOut, amount * result.Multiplier); if (result.Multiplier == 1) { msg = GetText("slot_single", _bc.BotConfig.CurrencySign, 1); } else if (result.Multiplier == 4) { msg = GetText("slot_two", _bc.BotConfig.CurrencySign, 4); } else if (result.Multiplier == 10) { msg = GetText("slot_three", 10); } else if (result.Multiplier == 30) { msg = GetText("slot_jackpot", 30); } } await Context.Channel.SendFileAsync(bgImage.ToStream(), "result.png", Context.User.Mention + " " + msg + $"\n`{GetText("slot_bet")}:`{amount} `{GetText("slot_won")}:` {amount * result.Multiplier}{_bc.BotConfig.CurrencySign}").ConfigureAwait(false); } } finally { var _ = Task.Run(async() => { await Task.Delay(1500); _runningUsers.Remove(Context.User.Id); }); } }
public async Task Divorce([Remainder] ulong targetId) { if (targetId == Context.User.Id) { return; } DivorceResult result; var difference = TimeSpan.Zero; var amount = 0; WaifuInfo w = null; using (var uow = _db.UnitOfWork) { w = uow.Waifus.ByWaifuUserId(targetId); var now = DateTime.UtcNow; if (w?.Claimer == null || w.Claimer.UserId != Context.User.Id) { result = DivorceResult.NotYourWife; } else if (_service.DivorceCooldowns.AddOrUpdate(Context.User.Id, now, (key, old) => ((difference = now.Subtract(old)) > _divorceLimit) ? now : old) != now) { result = DivorceResult.Cooldown; } else { amount = w.Price / 2; if (w.Affinity?.UserId == Context.User.Id) { await _cs.AddAsync(w.Waifu.UserId, "Waifu Compensation", amount, uow).ConfigureAwait(false); w.Price = (int)Math.Floor(w.Price * 0.75f); result = DivorceResult.SucessWithPenalty; } else { await _cs.AddAsync(Context.User.Id, "Waifu Refund", amount, uow).ConfigureAwait(false); result = DivorceResult.Success; } var oldClaimer = w.Claimer; w.Claimer = null; uow._context.WaifuUpdates.Add(new WaifuUpdate() { User = w.Waifu, Old = oldClaimer, New = null, UpdateType = WaifuUpdateType.Claimed }); } await uow.CompleteAsync().ConfigureAwait(false); } if (result == DivorceResult.SucessWithPenalty) { await ReplyConfirmLocalized("waifu_divorced_like", Format.Bold(w.Waifu.ToString()), amount + _bc.BotConfig.CurrencySign).ConfigureAwait(false); } else if (result == DivorceResult.Success) { await ReplyConfirmLocalized("waifu_divorced_notlike", amount + _bc.BotConfig.CurrencySign).ConfigureAwait(false); } else if (result == DivorceResult.NotYourWife) { await ReplyErrorLocalized("waifu_not_yours").ConfigureAwait(false); } else { var remaining = _divorceLimit.Subtract(difference); await ReplyErrorLocalized("waifu_recent_divorce", Format.Bold(((int)remaining.TotalHours).ToString()), Format.Bold(remaining.Minutes.ToString())).ConfigureAwait(false); } }
public async Task <(CurrencyRaffleGame, JoinErrorType?)> JoinOrCreateGame(ulong channelId, IUser user, int amount, bool mixed, 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(mixed ? CurrencyRaffleGame.Type.Mixed : CurrencyRaffleGame.Type.Normal); Games.Add(channelId, crg); } using (var uow = _db.UnitOfWork) { //remove money, and stop the game if this // user created it and doesn't have the money if (!_cs.Remove(user.Id, "Currency Raffle Join", amount, uow)) { if (newGame) { Games.Remove(channelId); } return(null, JoinErrorType.NotEnoughCurrency); } if (!crg.AddUser(user, amount)) { await _cs.AddAsync(user.Id, "Curency Raffle Refund", amount, uow).ConfigureAwait(false); return(null, JoinErrorType.AlreadyJoinedOrInvalidAmount); } uow.Complete(); } 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); using (var uow = _db.UnitOfWork) { await _cs.AddAsync(winner.DiscordUser.Id, "Currency Raffle Win", won, uow); uow.Complete(); } Games.Remove(channelId, out _); var oe = onEnded(winner.DiscordUser, won); } catch { } finally { _locker.Release(); } }); } return(crg, null); } finally { _locker.Release(); } }
public async Task Slot(int amount = 0) { if (!RunningUsers.Add(Context.User.Id)) { return; } try { if (amount < 1) { await ReplyErrorLocalized("min_bet_limit", $"{1}{_bc.BotConfig.CurrencySign}").ConfigureAwait(false); return; } const int maxAmount = 9999; if (amount > maxAmount) { GetText("slot_maxbet", $"{maxAmount}{_bc.BotConfig.CurrencySign}"); await ReplyErrorLocalized("max_bet_limit", $"{maxAmount}{_bc.BotConfig.CurrencySign}").ConfigureAwait(false); return; } var guildUser = (IGuildUser)Context.User; if (!await _cs.RemoveAsync(guildUser, "Slot Machine", amount)) { await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } Interlocked.Add(ref _totalBet, amount); var result = SlotMachineResult.Pull(); var numbers = result.Numbers; var won = amount * result.Multiplier; var msg = result.Multiplier != 0 ? "" : GetText("better_luck"); if (result.Multiplier != 0) { await _cs.AddAsync(guildUser, $"Slot Machine x{result.Multiplier}", amount *result.Multiplier); Interlocked.Add(ref _totalPaidOut, amount * result.Multiplier); switch (result.Multiplier) { case 1: msg = GetText("slot_single", _bc.BotConfig.CurrencySign, 1); break; case 4: msg = GetText("slot_two", _bc.BotConfig.CurrencySign, 4); break; case 10: msg = GetText("slot_three", 10); break; case 30: msg = GetText("slot_jackpot", 30); break; } } await Context.Channel.SendMessageAsync($"{Context.User.Mention} {msg}\n`{GetText("slot_bet")}:`{amount} `{GetText("slot_won")}:` {won}{_bc.BotConfig.CurrencySign}\n{_emojis[numbers[0]] + _emojis[numbers[1]] + _emojis[numbers[2]]}").ConfigureAwait(false); } finally { var _ = Task.Run(async() => { await Task.Delay(1500); RunningUsers.Remove(Context.User.Id); }); } }
private async Task DealerMoves() { var hw = Dealer.GetHandValue(); while (hw < 17 || (hw == 17 && Dealer.Cards.Count(x => x.Number == 1) > (Dealer.GetRawHandValue() - 17) / 10))// hit on soft 17 { /* Dealer has * A 6 * That's 17, soft * hw == 17 => true * number of aces = 1 * 1 > 17-17 /10 => true * * AA 5 * That's 17, again soft, since one ace is worth 11, even though another one is 1 * hw == 17 => true * number of aces = 2 * 2 > 27 - 17 / 10 => true * * AA Q 5 * That's 17, but not soft, since both aces are worth 1 * hw == 17 => true * number of aces = 2 * 2 > 37 - 17 / 10 => false * */ Dealer.Cards.Add(Deck.Draw()); hw = Dealer.GetHandValue(); } if (hw > 21) { foreach (var usr in Players) { if (usr.State == User.UserState.Stand || usr.State == User.UserState.Blackjack) { usr.State = User.UserState.Won; } else { usr.State = User.UserState.Lost; } } } else { foreach (var usr in Players) { if (usr.State == User.UserState.Blackjack) { usr.State = User.UserState.Won; } else if (usr.State == User.UserState.Stand) { usr.State = hw < usr.GetHandValue() ? User.UserState.Won : User.UserState.Lost; } else { usr.State = User.UserState.Lost; } } } using (var uow = _db.UnitOfWork) { uow._context.Set <Stake>().RemoveRange(_stakes); foreach (var usr in Players) { if (usr.State == User.UserState.Won || usr.State == User.UserState.Blackjack) { await _cs.AddAsync(usr.DiscordUser.Id, "BlackJack-win", usr.Bet * 2, uow, gamble : true); } } uow.Complete(); } }
public async Task Buy(int index, [Remainder] string message = null) { index -= 1; if (index < 0) { return; } ShopEntry entry; using (var uow = _db.UnitOfWork) { var config = uow.GuildConfigs.For(Context.Guild.Id, set => set .Include(x => x.ShopEntries) .ThenInclude(x => x.Items)); var entries = new IndexedCollection <ShopEntry>(config.ShopEntries); entry = entries.ElementAtOrDefault(index); uow.Complete(); } if (entry == null) { await ReplyErrorLocalized("shop_item_not_found").ConfigureAwait(false); return; } if (entry.Type == ShopEntryType.Role) { var guser = (IGuildUser)Context.User; var role = Context.Guild.GetRole(entry.RoleId); if (role == null) { await ReplyErrorLocalized("shop_role_not_found").ConfigureAwait(false); return; } if (_cs.Remove(Context.User.Id, $"Shop purchase - {entry.Type}", entry.Price)) { try { await guser.AddRoleAsync(role).ConfigureAwait(false); } catch (Exception ex) { _log.Warn(ex); await _cs.AddAsync(Context.User.Id, $"Shop error refund", entry.Price); await ReplyErrorLocalized("shop_role_purchase_error").ConfigureAwait(false); return; } await _cs.AddAsync(entry.AuthorId, $"Shop sell item - {entry.Type}", GetProfitAmount(entry.Price)); await ReplyConfirmLocalized("shop_role_purchase", Format.Bold(role.Name)).ConfigureAwait(false); return; } else { await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } } else if (entry.Type == ShopEntryType.List) { if (entry.Items.Count == 0) { await ReplyErrorLocalized("out_of_stock").ConfigureAwait(false); return; } var item = entry.Items.ToArray()[new NadekoRandom().Next(0, entry.Items.Count)]; if (_cs.Remove(Context.User.Id, $"Shop purchase - {entry.Type}", entry.Price)) { int removed; using (var uow = _db.UnitOfWork) { var x = uow._context.Set <ShopEntryItem>().Remove(item); removed = uow.Complete(); } try { await(await Context.User.GetOrCreateDMChannelAsync()) .EmbedAsync(new EmbedBuilder().WithOkColor() .WithTitle(GetText("shop_purchase", Context.Guild.Name)) .AddField(efb => efb.WithName(GetText("item")).WithValue(item.Text).WithIsInline(false)) .AddField(efb => efb.WithName(GetText("price")).WithValue(entry.Price.ToString()).WithIsInline(true)) .AddField(efb => efb.WithName(GetText("name")).WithValue(entry.Name).WithIsInline(true))) .ConfigureAwait(false); await _cs.AddAsync(entry.AuthorId, $"Shop sell item - {entry.Name}", GetProfitAmount(entry.Price)).ConfigureAwait(false); } catch { using (var uow = _db.UnitOfWork) { uow._context.Set <ShopEntryItem>().Add(item); uow.Complete(); await _cs.AddAsync(Context.User.Id, $"Shop error refund - {entry.Name}", entry.Price, uow).ConfigureAwait(false); } await ReplyErrorLocalized("shop_buy_error").ConfigureAwait(false); return; } await ReplyConfirmLocalized("shop_item_purchase").ConfigureAwait(false); } else { await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } } }