public async Task <long> PickAsync(ulong gid, ITextChannel ch, ulong uid, string pass) { long amount; ulong[] ids; using (var uow = _db.UnitOfWork) { // this method will sum all plants with that password, // remove them, and get messageids of the removed plants (amount, ids) = uow.PlantedCurrency.RemoveSumAndGetMessageIdsFor(ch.Id, pass); if (amount > 0) { // give the picked currency to the user await _cs.AddAsync(uid, "Picked currency", amount, gamble : false); } uow.Complete(); } try { // delete all of the plant messages which have just been picked var _ = ch.DeleteMessagesAsync(ids); } catch { } // return the amount of currency the user picked return(amount); }
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); var cur = _service.GetUserCurrency(Context.User); await ReplyConfirmLocalized("timely", val + Bc.BotConfig.CurrencySign, cur + Bc.BotConfig.CurrencySign, period).ConfigureAwait(false); }
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(); } }
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); } var win_amount = 0; foreach (var u in FinishedUsers) { win_amount += (int)u.Bet; } if (FinishedUsers[0].Bet > 0) { await _currency.AddAsync(FinishedUsers[0].UserId, "Won a Race", win_amount) .ConfigureAwait(false); } var _ended = OnEnded?.Invoke(this); }); }
public async Task <(WaifuInfo, DivorceResult, long, TimeSpan?)> DivorceWaifuAsync(IUser user, ulong targetId) { DivorceResult result; TimeSpan? remaining = null; long amount = 0; WaifuInfo w = null; using (var uow = _db.GetDbContext()) { w = uow.Waifus.ByWaifuUserId(targetId); var now = DateTime.UtcNow; if (w?.Claimer == null || w.Claimer.UserId != user.Id) { result = DivorceResult.NotYourWife; } else if (!_cache.TryAddDivorceCooldown(user.Id, out remaining)) { result = DivorceResult.Cooldown; } else { amount = w.Price / 2; if (w.Affinity?.UserId == user.Id) { await _cs.AddAsync(w.Waifu.UserId, "Waifu Compensation", amount, gamble : true); w.Price = (int)Math.Floor(w.Price * _gss.Data.Waifu.Multipliers.DivorceNewValue); result = DivorceResult.SucessWithPenalty; } else { await _cs.AddAsync(user.Id, "Waifu Refund", amount, gamble : true); 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.SaveChangesAsync(); } return(w, result, amount, remaining); }
public async Task Pick() { var guild = (SocketGuild)Context.Guild; var channel = (ITextChannel)Context.Channel; if (!guild.CurrentUser.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 WheelOfFortune(long amount) { if (!await CheckBetMandatory(amount)) { return; } if (!await _cs.RemoveAsync(Context.User.Id, "Wheel Of Fortune - bet", amount, gamble: true)) { await ReplyErrorLocalized("not_enough", _bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } var wof = new WheelOfFortune(); amount = (long)(amount * 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 <IActionResult> AddCurrency([FromBody] CurrencyDTO currency) { if (!ModelState.IsValid) { return(BadRequest() as IActionResult); } var info = await service.AddAsync(currency); return(info ? Ok() : StatusCode(400)); }
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 Timely() { var val = _config.Timely.Amount; var period = _config.Timely.Cooldown; if (val <= 0 || period <= 0) { await ReplyErrorLocalizedAsync("timely_none").ConfigureAwait(false); return; } TimeSpan?rem; if ((rem = _cache.AddTimelyClaim(ctx.User.Id, period)) != null) { await ReplyErrorLocalizedAsync("timely_already_claimed", rem?.ToString(@"dd\d\ hh\h\ mm\m\ ss\s")).ConfigureAwait(false); return; } await _cs.AddAsync(ctx.User.Id, "Timely claim", val).ConfigureAwait(false); await ReplyConfirmLocalizedAsync("timely", n(val) + CurrencySign, period).ConfigureAwait(false); }
public async Task Betflip(ShmartNumber amount, BetFlipGuess guess) { if (!await CheckBetMandatory(amount).ConfigureAwait(false) || amount == 1) { 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; Uri imageToSend; var coins = _images.ImageUrls.Coins; if (rng.Next(0, 1000) <= 499) { 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, title; if (guess == result) { var toWin = (long)(amount * Bc.BotConfig.BetflipMultiplier); title = GetText("flip_win"); str = Context.User.Mention + ", " + GetText("flip_guess", toWin + Bc.BotConfig.CurrencySign) + "\n" + GetText("flip_dosame"); await _cs.AddAsync(Context.User, "Betflip Gamble", toWin, false, gamble : true).ConfigureAwait(false); } else { title = GetText("flip_lose"); str = Context.User.Mention + ", " + GetText("flip_positive") + "\n" + GetText("better_luck"); } await Context.Channel.EmbedAsync(new EmbedBuilder() .WithTitle(title) .WithDescription(str) .WithOkColor() .WithThumbnailUrl(imageToSend.ToString())).ConfigureAwait(false); }
public async Task <Result> SpinAsync() { var result = _rng.Next(0, Multipliers.Length); var amount = (long)(_bet * Multipliers[result]); if (amount > 0) { await _cs.AddAsync(_userId, "Wheel Of Fortune - won", amount, gamble : true).ConfigureAwait(false); } return(new Result { Index = result, Amount = amount, }); }
public async Task Betflip(ShmartNumber amount, BetFlipGuess guess) { if (!await CheckBetMandatory(amount).ConfigureAwait(false) || amount == 1) { return; } var removed = await _cs.RemoveAsync(ctx.User, "Betflip Gamble", amount, false, gamble : true).ConfigureAwait(false); if (!removed) { await ReplyErrorLocalizedAsync("not_enough", CurrencySign).ConfigureAwait(false); return; } BetFlipGuess result; Uri imageToSend; var coins = _images.ImageUrls.Coins; if (rng.Next(0, 1000) <= 499) { 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 = (long)(amount * _config.BetFlip.Multiplier); str = Format.Bold(ctx.User.ToString()) + " " + GetText("flip_guess", toWin + CurrencySign); await _cs.AddAsync(ctx.User, "Betflip Gamble", toWin, false, gamble : true).ConfigureAwait(false); } else { str = ctx.User.ToString() + " " + GetText("better_luck"); } await ctx.Channel.EmbedAsync(new EmbedBuilder() .WithDescription(str) .WithOkColor() .WithImageUrl(imageToSend.ToString())).ConfigureAwait(false); }
public async Task Betflip(ShmartNumber amount, BetFlipGuess guess) { if (!await CheckBetMandatory(amount) || amount == 1) { 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 = (long)(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)); }
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", 100, false) .ConfigureAwait(false); try { await arg.DeleteAsync(new RequestOptions() { RetryMode = RetryMode.AlwaysFail }).ConfigureAwait(false); } catch { // ignored } }); } return(Task.CompletedTask); }
public async Task <Result> SpinAsync() { var result = _rng.Next(0, Multipliers.Length); var amount = (long)(_bet * Multipliers[result]); if (amount > 0) { await _cs.AddAsync(_userId, "Wheel Of Fortune - won", amount, gamble : true).ConfigureAwait(false); await _lb.AddAsync(_userId, LeaderboardType.Wheel, LeaderboardTimeType.AllTime, amount); await _lb.AddAsync(_userId, LeaderboardType.Gambling, LeaderboardTimeType.AllTime, amount); await _lb.AddAsync(_userId, LeaderboardType.Gambling, LeaderboardTimeType.Monthly, amount); } return(new Result { Index = result, Amount = amount, }); }
public XpService(DiscordSocketClient client, CommandHandler cmd, IBotConfigProvider bc, NadekoBot bot, DbService db, NadekoStrings strings, IDataCache cache, FontProvider fonts, IBotCredentials creds, ICurrencyService cs, IHttpClientFactory http) { _db = db; _cmd = cmd; _bc = bc; _images = cache.LocalImages; _log = LogManager.GetCurrentClassLogger(); _strings = strings; _cache = cache; _fonts = fonts; _creds = creds; _cs = cs; _httpFactory = http; InternalReloadXpTemplate(); if (client.ShardId == 0) { var sub = _cache.Redis.GetSubscriber(); sub.Subscribe(_creds.RedisKey() + "_reload_xp_template", (ch, val) => InternalReloadXpTemplate()); } //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; updateXpTask = Task.Run(async() => { while (true) { await Task.Delay(TimeSpan.FromSeconds(5)); 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, x.User)); if (toAddTo.Count == 0) { continue; } 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.Complete(); } await Task.WhenAll(toNotify.Select(async x => { if (x.NotifOf == NotifOf.Server) { if (x.NotifyType == XpNotificationType.Dm) { var chan = await x.User.GetOrCreateDMChannelAsync(); 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() ?? "-"))); } } 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()))); } } else { IMessageChannel chan; if (x.NotifyType == XpNotificationType.Dm) { chan = await x.User.GetOrCreateDMChannelAsync(); } 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()))); } })); } catch (Exception ex) { _log.Warn(ex); } } }); }
public async Task <int> ClaimReward(ulong userId) { await claimLockJustInCase.WaitAsync().ConfigureAwait(false); var now = DateTime.UtcNow; try { var datas = _pledges?.Where(x => x.User.attributes?.social_connections?.discord?.user_id == userId.ToString()) ?? Enumerable.Empty <PatreonUserAndReward>(); foreach (var data in datas) { var amount = (int)(data.Reward.attributes.amount_cents * _bc.BotConfig.PatreonCurrencyPerCent); using (var uow = _db.GetDbContext()) { 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 uow.SaveChangesAsync(); await _currency.AddAsync(userId, "Patreon reward - new", amount, gamble : true); return(amount); } if (usr.LastReward.Month != now.Month) { usr.LastReward = now; usr.AmountRewardedThisMonth = amount; usr.UserId = userId; await uow.SaveChangesAsync(); await _currency.AddAsync(userId, "Patreon reward - recurring", amount, gamble : true); return(amount); } if (usr.AmountRewardedThisMonth < amount) { var toAward = amount - usr.AmountRewardedThisMonth; usr.LastReward = now; usr.AmountRewardedThisMonth = amount; usr.UserId = userId; await uow.SaveChangesAsync(); await _currency.AddAsync(usr.UserId, "Patreon reward - update", toAward, gamble : true); return(toAward); } } return(0); } return(0); } finally { claimLockJustInCase.Release(); } }
private async Task UpdateLoop() { while (true) { await Task.Delay(TimeSpan.FromSeconds(5)); try { var toNotify = new List <(IGuild Guild, IMessageChannel MessageChannel, IUser User, int Level, XpNotificationLocation 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, x.User)); if (toAddTo.Count == 0) { continue; } using (var uow = _db.GetDbContext()) { foreach (var item in group) { var xp = item.Sum(x => x.XpAmount); //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 != XpNotificationLocation.None) { toNotify.Add((first.Guild, 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 != XpNotificationLocation.None) { toNotify.Add((first.Guild, 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.SaveChanges(); } await Task.WhenAll(toNotify.Select(async x => { if (x.NotifOf == NotifOf.Server) { if (x.NotifyType == XpNotificationLocation.Dm) { var chan = await x.User.GetOrCreateDMChannelAsync(); if (chan != null) { await chan.SendConfirmAsync(_strings.GetText("level_up_dm", x.Guild.Id, "xp", x.User.Mention, Format.Bold(x.Level.ToString()), Format.Bold(x.Guild.ToString() ?? "-"))); } } else if (x.MessageChannel != null) // channel { await x.MessageChannel.SendConfirmAsync(_strings.GetText("level_up_channel", x.Guild.Id, "xp", x.User.Mention, Format.Bold(x.Level.ToString()))); } } else { IMessageChannel chan; if (x.NotifyType == XpNotificationLocation.Dm) { chan = await x.User.GetOrCreateDMChannelAsync(); } else // channel { chan = x.MessageChannel; } await chan.SendConfirmAsync(_strings.GetText("level_up_global", x.Guild.Id, "xp", x.User.Mention, Format.Bold(x.Level.ToString()))); } })); } catch (Exception ex) { _log.Warn(ex); } } }
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 = (int)(data.Reward.attributes.amount_cents * _bc.BotConfig.PatreonCurrencyPerCent); 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).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).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).ConfigureAwait(false); await uow.CompleteAsync().ConfigureAwait(false); return(toAward); } } return(0); } finally { claimLockJustInCase.Release(); } }
public async Task Slot(ShmartNumber amount) { if (!_runningUsers.Add(Context.User.Id)) { return; } try { if (!await CheckBetMandatory(amount).ConfigureAwait(false)) { return; } const int maxAmount = 9999; if (amount > maxAmount) { await ReplyErrorLocalized("max_bet_limit", maxAmount + Bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } if (!await _cs.RemoveAsync(Context.User, "Slot Machine", amount, false, gamble: true).ConfigureAwait(false)) { await ReplyErrorLocalized("not_enough", Bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } Interlocked.Add(ref _totalBet, amount.Value); using (var bgImage = Image.Load(_images.SlotBackground)) { var result = SlotMachine.Pull(); int[] numbers = result.Numbers; for (int i = 0; i < 3; i++) { using (var randomImage = Image.Load(_images.SlotEmojis[numbers[i]])) { bgImage.Mutate(x => x.DrawImage(GraphicsOptions.Default, randomImage, new Point(95 + 142 * i, 330))); } } var won = amount * result.Multiplier; var printWon = won; var n = 0; do { var digit = (int)(printWon % 10); using (var img = Image.Load(_images.SlotNumbers[digit])) { bgImage.Mutate(x => x.DrawImage(GraphicsOptions.Default, img, new Point(230 - n * 16, 462))); } n++; } while ((printWon /= 10) != 0); var printAmount = amount; n = 0; do { var digit = (int)(printAmount % 10); using (var img = Image.Load(_images.SlotNumbers[digit])) { bgImage.Mutate(x => x.DrawImage(GraphicsOptions.Default, img, 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, gamble : true).ConfigureAwait(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); } } using (var imgStream = bgImage.ToStream()) { await Context.Channel.SendFileAsync(imgStream, "result.png", Context.User.Mention + " " + msg + $"\n`{GetText("slot_bet")}:`{amount} `{GetText("won")}:` {amount * result.Multiplier}{Bc.BotConfig.CurrencySign}").ConfigureAwait(false); } } } finally { var _ = Task.Run(async() => { await Task.Delay(1500).ConfigureAwait(false); _runningUsers.Remove(Context.User.Id); }); } }
public async Task Divorce([Remainder] ulong targetId) { if (targetId == Context.User.Id) { return; } DivorceResult result; TimeSpan? remaining = null; 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 (!_cache.TryAddDivorceCooldown(Context.User.Id, out remaining)) { result = DivorceResult.Cooldown; } else { amount = w.Price / 2; if (w.Affinity?.UserId == Context.User.Id) { await _cs.AddAsync(w.Waifu.UserId, "Waifu Compensation", amount, gamble : true).ConfigureAwait(false); w.Price = (int)Math.Floor(w.Price * 0.75f); result = DivorceResult.SucessWithPenalty; } else { await _cs.AddAsync(Context.User.Id, "Waifu Refund", amount, gamble : true).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 { await ReplyErrorLocalized("waifu_recent_divorce", Format.Bold(((int)remaining?.TotalHours).ToString()), Format.Bold(remaining?.Minutes.ToString())).ConfigureAwait(false); } }
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, gamble : true); } } uow.Complete(); } }
public async Task WheelOfFortune(ShmartNumber amount) { if (!await CheckBetMandatory(amount).ConfigureAwait(false)) { return; } if (!await _cs.RemoveAsync(Context.User.Id, "Wheel Of Fortune - bet", amount, gamble: true).ConfigureAwait(false)) { await ReplyErrorLocalized("not_enough", Bc.BotConfig.CurrencySign).ConfigureAwait(false); return; } var _rng = new NadekoRandom(); var result = _rng.Next(0, _results.Length); var wonAmountTemp = _results[result].Item1 * amount; string commentary = GetText(_results[result].Item2); var rotation = (result * 360) / _results.Length; var mayhem = _rng.Next(0, 100); if (mayhem == 0) { wonAmountTemp = wonAmountTemp * _mayhemMultiplier; await Context.Channel.SendConfirmAsync("Let's spin the " + Format.Bold("Wheel of Mayhem") + " for x" + _mayhemMultiplier + " multiplier, " + Context.User.Mention + "!") .ConfigureAwait(false); System.Threading.Thread.Sleep(2000); await Context.Channel.SendConfirmAsync("Ratatata-ta-ta-ta ta ta...!").ConfigureAwait(false); System.Threading.Thread.Sleep(2000); await Context.Channel.SendConfirmAsync("Ta...!").ConfigureAwait(false); System.Threading.Thread.Sleep(2000); await Context.Channel.SendConfirmAsync("...").ConfigureAwait(false); System.Threading.Thread.Sleep(2000); await Context.Channel.SendConfirmAsync("Ta!").ConfigureAwait(false); System.Threading.Thread.Sleep(200); } long wonAmount = (long)wonAmountTemp; //remove the decimal part if (wonAmount > 0) { await _cs.AddAsync(Context.User.Id, "Wheel Of Fortune - won", wonAmount, gamble : true) .ConfigureAwait(false); } else if (wonAmount < 0) { await _cs.RemoveAsync(Context.User.Id, "Wheel Of Fortune - lost", -wonAmount, gamble : true) .ConfigureAwait(false); } using (var bgImage = Image.Load(_images.Roulette)) { var originalWidth = bgImage.Width; var originalHeight = bgImage.Height; bgImage.Mutate(x => x.Rotate(-rotation)); var widthCrop = (bgImage.Width - originalWidth) / 2; var heightCrop = (bgImage.Height - originalHeight) / 2; bgImage.Mutate(x => x.Crop(new Rectangle(widthCrop, heightCrop, originalWidth, originalHeight))); using (var ptImage = Image.Load(_images.RoulettePointer)) { var resizeOptions = new ResizeOptions(); resizeOptions.Mode = ResizeMode.Pad; resizeOptions.Position = AnchorPositionMode.TopLeft; resizeOptions.Size = new Size(originalWidth + (ptImage.Width / 2), originalHeight); bgImage.Mutate(x => x.Resize(resizeOptions)); var pointerPosX = bgImage.Width - ptImage.Width; var pointerPosY = (bgImage.Height / 2) - (ptImage.Height / 2); bgImage.Mutate(x => x.DrawImage(GraphicsOptions.Default, ptImage, new Point(pointerPosX, pointerPosY))); } using (var imgStream = bgImage.ToStream()) { string outText; long outAmount; if (wonAmount >= 0) { outText = GetText("won"); outAmount = wonAmount; } else { outText = GetText("lost"); outAmount = -wonAmount; } await Context.Channel.SendFileAsync(imgStream, "result.png", $@"{Format.Bold(Context.User.ToString())} {outText}: `{outAmount}`{Bc.BotConfig.CurrencySign}{System.Environment.NewLine}{commentary}") .ConfigureAwait(false); } } }
public async Task <int> ClaimReward(ulong userId) { await claimLockJustInCase.WaitAsync().ConfigureAwait(false); var settings = _gamblingConfigService.Data; var now = DateTime.UtcNow; try { var datas = _pledges?.Where(x => x.User.attributes?.social_connections?.discord?.user_id == userId.ToString()) ?? Enumerable.Empty <PatreonUserAndReward>(); var totalAmount = 0; foreach (var data in datas) { var amount = (int)(data.Reward.attributes.amount_cents * settings.PatreonCurrencyPerCent); using (var uow = _db.GetDbContext()) { var users = uow._context.Set <RewardedUser>(); var usr = users.FirstOrDefault(x => x.PatreonUserId == data.User.id); if (usr == null) { users.Add(new RewardedUser() { PatreonUserId = data.User.id, LastReward = now, AmountRewardedThisMonth = amount, }); await uow.SaveChangesAsync(); await _currency.AddAsync(userId, "Patreon reward - new", amount, gamble : true); totalAmount += amount; Log.Information($"Sending new currency reward to {userId}"); await SendMessageToUser(userId, $"Thank you for your pledge! " + $"You've been awarded **{amount}**{settings.Currency.Sign} !"); continue; } if (usr.LastReward.Month != now.Month) { usr.LastReward = now; usr.AmountRewardedThisMonth = amount; await uow.SaveChangesAsync(); await _currency.AddAsync(userId, "Patreon reward - recurring", amount, gamble : true); totalAmount += amount; Log.Information($"Sending recurring currency reward to {userId}"); await SendMessageToUser(userId, $"Thank you for your continued support! " + $"You've been awarded **{amount}**{settings.Currency.Sign} for this month's support!"); continue; } if (usr.AmountRewardedThisMonth < amount) { var toAward = amount - usr.AmountRewardedThisMonth; usr.LastReward = now; usr.AmountRewardedThisMonth = amount; await uow.SaveChangesAsync(); await _currency.AddAsync(userId, "Patreon reward - update", toAward, gamble : true); totalAmount += toAward; Log.Information($"Sending updated currency reward to {userId}"); await SendMessageToUser(userId, $"Thank you for increasing your pledge! " + $"You've been awarded an additional **{toAward}**{settings.Currency.Sign} !"); continue; } } } return(totalAmount); } finally { claimLockJustInCase.Release(); } }
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 (await _cs.RemoveAsync(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; } var profit = GetProfitAmount(entry.Price); await _cs.AddAsync(entry.AuthorId, $"Shop sell item - {entry.Type}", profit); await _cs.AddAsync(Context.Client.CurrentUser.Id, $"Shop sell item - cut", entry.Price - profit); 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 (await _cs.RemoveAsync(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 { await _cs.AddAsync(Context.User.Id, $"Shop error refund - {entry.Name}", entry.Price).ConfigureAwait(false); using (var uow = _db.UnitOfWork) { uow._context.Set <ShopEntryItem>().Add(item); uow.Complete(); } 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; } } }
private static async Task Award(IUser user, long amount, string reason = "NadekoConnector Award", bool sendMessage = false) { await _cs.AddAsync(user, reason, amount, sendMessage); }