public static bool CanUse(IUser user, CommandInfo command) { //if (user.Id == Information.OwnerId) { // return true; //} var guilduser = user as IGuildUser; switch (command.Module.Name) { case "Admin": case "Clean": if (guilduser == null) { return(false); } else { return(guilduser.GuildPermissions.Administrator); } case "Owner": if (guilduser == null) { return(false); } else { return(user.Id == Information.OwnerId); } case "Votekick": if (Information.AllowVotekick && guilduser != null) { return(true); } else { return(false); } case "Xp": if (guilduser != null) { if (GuildConfigManager.Get(guilduser.GuildId).EnableXpSystem) { return(true); } } return(false); case "Profile": case "Hardware": case "Link": case "Code": return(guilduser != null); } return(true); }
public async Task ToggleScripts() { try { var user = Context.User; if (!Helper.IsOwner(user)) { await ReplyAsync($"Sorry, but only {Information.Owner} can toggle scripts!"); return; } var config = GuildConfigManager.Get(Context.Guild.Id); config.EnableScripts = !config.EnableScripts; GuildConfigManager.Set(config); if (config.EnableScripts) { await ReplyAsync("Scripts are now enabled for this guild! Use `$exec code`."); } else { await ReplyAsync("Scripts are now disabled for this guild!"); } } catch (Exception ex) { await ReplyAsync("Whoops, unfortunately I couldn't toggle scripts.. :confused:"); ConsoleHelper.Log($"Error changing script setting, {ex.Message}!", LogSeverity.Error); } }
public async Task Execute([Summary("The Code to execute")][Remainder] string code) { try { //Requirements to execute C# Roslyn scripts if (!(Context.User is IGuildUser user) || !user.GuildPermissions.Speak) { await ReplyAsync("You're not allowed to execute scripts!"); return; } if (!GuildConfigManager.Get(Context.Guild.Id).EnableScripts) { await ReplyAsync($"C# Roslyn Scripts are disabled via Config. Ask {Information.Owner}."); return; } //Handle exec async - so MessageReceived is not blocking var _ = HandleExecAsync(code, Context.Channel); } catch { await ReplyAsync("Something went wrong, sorry!"); } }
public async Task ChangePrefix([Summary("New prefix")][Remainder] string prefix) { try { if (!(Context.User is IGuildUser user)) { return; } if (!Helper.IsOwner(user) && !user.GuildPermissions.Administrator) { await ReplyAsync("Sorry, but you're not allowed to use that super premium command!"); return; } var config = GuildConfigManager.Get(Context.Guild.Id); string before = config.Prefix; bool disablePrimary = config.EnablePrimaryPrefix; GuildConfigManager.Set(Context.Guild.Id, prefix, disablePrimary); await ReplyAsync($"Prefix changed from `{before}` to `{prefix}`!"); ConsoleHelper.Log( $"{Context.User} changed the prefix on \"{Context.Guild.Name}\" from {before} to {prefix}!", LogSeverity.Info); } catch (Exception ex) { await ReplyAsync("Whoops, unfortunately I couldn't change the prefix.. :confused:"); ConsoleHelper.Log($"Error chaning prefix, {ex.Message}!", LogSeverity.Error); } }
public async Task Info([Summary("The user you want to display XP")] IGuildUser user) { try { if (!GuildConfigManager.Get(Context.Guild.Id).EnableXpSystem) { await ReplyAsync("XP System is disabled for this Guild! An Admin can use `$togglexp`!"); return; } var xp = XpManager.Get(Context.Guild, user); var builder = new EmbedBuilder { Author = new EmbedAuthorBuilder { Name = user.IsBot ? $"{Helper.GetName(user)}'s XP (Bot)" : $"{Helper.GetName(user)}'s XP", IconUrl = user.GetAvatarUrl() }, Color = new Color(50, 125, 0) }; builder.AddInlineField("XP", xp.Xp); builder.AddInlineField("Level", xp.Level); builder.AddInlineField("Next Level", XpManager.GetXp(xp.Level + 1) - xp.Xp); await ReplyAsync("", embed : builder.Build()); } catch { await ReplyAsync($"I couldn't look up any Info about {Helper.GetName(user)}, sorry.."); } }
public async Task Host() { try { string mname = Environment.MachineName; string pre = string.Empty; bool enablePrimary = true; string sPrefix = Information.SecondaryPrefix; if (Context.Guild == null) { // It's DM } else { var config = GuildConfigManager.Get(Context.Guild.Id); enablePrimary = config.EnablePrimaryPrefix; sPrefix = config.Prefix; } if (enablePrimary) { pre += $"`{Information.Prefix}`, "; } pre += $"`{sPrefix}`, {Context.Client.CurrentUser.Mention}"; int cores = Environment.ProcessorCount; var current = Process.GetCurrentProcess(); var builder = new EmbedBuilder { Author = new EmbedAuthorBuilder { Name = "Bot Information", IconUrl = Information.BotIconUrl }, Color = new Color(50, 125, 0), ThumbnailUrl = Information.IconUrl }; builder.AddInlineField("Uptime", GetUptime()); builder.AddInlineField("Machine", mname); builder.AddInlineField("Core #", $"{cores} cores"); builder.AddInlineField("RAM usage", $"{(double) current.WorkingSet64 / 1024 / 1024:#.#} / {(double) current.PeakWorkingSet64 / 1024 / 1024:#.#} MB"); builder.AddInlineField("Prefixes", pre); builder.AddInlineField("Source Code", $"[GitHub]({Information.RepoUrl})"); builder.AddInlineField("My Owner", Information.Owner); builder.AddInlineField("Guilds", $"Online on {Cirilla.Client.Guilds.Count} guilds"); await ReplyAsync("", embed : builder.Build()); ConsoleHelper.Log($"{Context.User} requested Bot/Host Information!", LogSeverity.Info); } catch (Exception ex) { await ReplyAsync("Sorry, I can't send you that information right now!"); ConsoleHelper.Log($"Error retrieving Host information {ex.Message}", LogSeverity.Error); } }
public static void Init() { //get guilds var directories = Directory.GetDirectories(Information.Directory); var xpfiles = new string[directories.Length]; XpInfo = new XpFile(); if (directories.Length > 0) { ConsoleHelper.Log($"Loading {directories.Length} Guild XP Files..", LogSeverity.Info); var sw = Stopwatch.StartNew(); for (int i = 0; i < directories.Length; i++) { string directory = directories[i]; string xpfile = Path.Combine(directory, "userxp.json"); //Regex.Match(directory, "\\\\[0-9]+$").ToString(); string guildidstr = Path.GetFileName(Path.GetDirectoryName(xpfile)); ulong guildid = ulong.Parse(guildidstr); if (!GuildConfigManager.Get(guildid).EnableXpSystem) { continue; } if (!File.Exists(xpfile)) { var guildxp = new GuildXp(); File.WriteAllText(xpfile, JsonConvert.SerializeObject(guildxp)); XpInfo.Guilds.Add(new KeyValuePair <ulong, GuildXp>(guildid, guildxp)); } else { var guildxp = JsonConvert.DeserializeObject <GuildXp>(File.ReadAllText(xpfile)); XpInfo.Guilds.Add(new KeyValuePair <ulong, GuildXp>(guildid, guildxp ?? new GuildXp())); } xpfiles[i] = xpfile; } sw.Stop(); ConsoleHelper.Log( $"Done loading {directories.Length} Guild XP Files! (took {sw.ElapsedMilliseconds}ms)", LogSeverity.Info); } else { ConsoleHelper.Log("No XP Files stored yet.", LogSeverity.Info); } new Thread(TimerLoop).Start(); }
public async Task ToggleXp() { try { if (!(Context.User is IGuildUser user)) { return; } if (!Helper.IsOwner(user) && !user.GuildPermissions.Administrator) { await ReplyAsync("Sorry, only admins can use this command!"); return; } var config = GuildConfigManager.Get(Context.Guild.Id); bool after = !config.EnableXpSystem; config.EnableXpSystem = after; GuildConfigManager.Set(config); if (after) { await ReplyAsync("XP System for this Guild is now enabled!"); ConsoleHelper.Log($"{Context.User} enabled XP System for Guild \"{Context.Guild.Name}\"!", LogSeverity.Info); } else { //string guildDir = Path.Combine(Information.Directory, Context.Guild.Id.ToString()); ////cleanup //if (Directory.Exists(guildDir)) { // Directory.Delete(guildDir, true); //} await ReplyAsync("XP System for this Guild is now disabled!"); ConsoleHelper.Log($"{Context.User} disabled XP System for Guild \"{Context.Guild.Name}\"!", LogSeverity.Info); } } catch (Exception ex) { await ReplyAsync("Whoops, unfortunately I couldn't toggle the XP System.. :confused:"); ConsoleHelper.Log($"Error toggling XP system for guild, {ex.Message}!", LogSeverity.Error); } }
public async Task Info() { try { if (Context.User is IGuildUser user) { string uname = user.Username ?? "?"; string nick = user.Nickname ?? "/"; string createdAt = user.CreatedAt.ToString("d") ?? "/"; var joinedAtDate = user.JoinedAt; string joinedAt = joinedAtDate != null?joinedAtDate.Value.ToString("d") : "/"; string status = user.Status.ToString() ?? "/"; var nullableGame = user.Game; string game = nullableGame != null?nullableGame.Value.ToString() : "/"; string xp = GuildConfigManager.Get(Context.Guild.Id).EnableXpSystem ? XpManager.Get(Context.Guild, user).Xp.ToString() : "[disabled]"; var builder = new EmbedBuilder { Author = new EmbedAuthorBuilder { Name = user.IsBot ? $"{uname} (Bot)" : $"{uname}" //IconUrl = user.GetAvatarUrl() }, Color = new Color(50, 125, 0), ThumbnailUrl = user.GetAvatarUrl() }; builder.AddInlineField("Nickname", nick); builder.AddInlineField("Created At", createdAt); builder.AddInlineField("Joined At", joinedAt); builder.AddInlineField("Status", status); builder.AddInlineField("Game", game); builder.AddInlineField("XP", xp); await ReplyAsync("", embed : builder.Build()); } } catch (Exception ex) { await ReplyAsync($"Error! ({ex.Message})"); } }
public static Embed WrongCommand(IMessage message, CommandService service, ICommandContext context) { string command = message.Content .Replace(Information.Prefix.ToString(), "") .Replace(GuildConfigManager.Get(context.Guild.Id).Prefix, "") .Replace(Cirilla.Client.CurrentUser.Mention, ""); var searchResult = service.Search(context, command); if (searchResult.Commands != null && searchResult.Commands.Count > 0) { string nl = Environment.NewLine; bool multiple = searchResult.Commands.Count > 1; var builder = new EmbedBuilder { Color = new Color(114, 137, 218), Description = multiple ? "Did you mean some of these?" : "Did you mean this?" }; foreach (var match in searchResult.Commands) { var cmd = match.Command; builder.AddField(x => { x.Name = $"{Information.Prefix}{cmd.Aliases.First()} {string.Join(" ", cmd.Parameters)}"; if (cmd.Parameters.Count < 1) { x.Value = $"Summary: {cmd.Summary}"; } else { x.Value = $"Summary: {cmd.Summary}" + nl + $"Parameters: {nl}{string.Join($"{nl}", cmd.Parameters.Select(p => $"\t_{p.Name}_: {p.Summary}"))}"; } x.IsInline = false; }); } return(builder.Build()); } return(null); }
public async Task TogglePrimaryPrefix() { try { if (!(Context.User is IGuildUser user)) { return; } if (!Helper.IsOwner(user) && !user.GuildPermissions.Administrator) { await ReplyAsync("Sorry, but you're not allowed to use that super premium command!"); return; } var config = GuildConfigManager.Get(Context.Guild.Id); bool before = config.EnablePrimaryPrefix; bool after = !config.EnablePrimaryPrefix; config.EnablePrimaryPrefix = after; GuildConfigManager.Set(config.GuildId, config.Prefix, config.EnablePrimaryPrefix); if (after) { await ReplyAsync("Bot is now also listening to primary prefix (`$`)!"); } else { await ReplyAsync("Bot is not listening to primary prefix anymore (`$`)!" + Environment.NewLine + $"Current prefixes: `{config.Prefix}` and \"{Cirilla.Client.CurrentUser.Mention}\""); } ConsoleHelper.Log($"{Context.User} toggled the primary prefix on \"{Context.Guild.Name}\" from " + $"{before} to {after}!", LogSeverity.Info); } catch (Exception ex) { await ReplyAsync("Whoops, unfortunately I couldn't toggle the primary prefix.. :confused:"); ConsoleHelper.Log($"Error toggling primary prefix, {ex.Message}!", LogSeverity.Error); } }
public async Task ShowConfig() { var config = GuildConfigManager.Get(Context.Guild.Id); string prefixes = string.Empty; if (config.EnablePrimaryPrefix) { prefixes += $"{Information.Prefix}, "; } prefixes += $"{config.Prefix}, {Context.Client.CurrentUser.Mention}"; var builder = new EmbedBuilder { Color = new Color(50, 125, 0), Author = new EmbedAuthorBuilder { IconUrl = Information.IconUrl, Name = "Cirilla Config" } }; builder.AddInlineField("Default Text Channel", Information.TextChannel); builder.AddInlineField("Prefixes", prefixes); builder.AddInlineField("Repo URL", $"[GitHub]({Information.RepoUrl})"); builder.AddInlineField("Owner", Information.Owner); builder.AddInlineField("Enable XP System", config.EnableXpSystem); builder.AddInlineField("XP Drop Interval", $"Every {Information.XpGiveInterval / 1000} Seconds"); builder.AddInlineField("Regain gift XP", $"{100 / Information.OwnXp}% XP"); builder.AddInlineField("XP Level Factor", $"Lvl = PreviousLvl * {Information.XpFactor}"); builder.AddInlineField("Random 200XP Chance", $"1 in {Information.GiveRandomXpChance} chance"); builder.AddInlineField("Random Reaction Chance", $"1 in {Information.RandomReactionChance} chance"); builder.AddInlineField("Votekick enabled", Information.AllowVotekick); builder.AddInlineField("Votekick Emojis", $"{Information.VotekickYes} {Information.VotekickNo}"); builder.AddInlineField("Votekick expiration", $"{Information.VotekickExpire / 1000} Seconds"); builder.AddInlineField("News Interval", $"Every {Information.NewsInterval} Hours"); builder.AddInlineField("Allow Scripts", config.EnableScripts); builder.AddInlineField("Scripts Timeout", $"C: {Information.CompileTimeout / 1000}s | X: {Information.ExecutionTimeout / 1000}s"); await ReplyAsync("", embed : builder.Build()); }
public async Task GetPrefix() { if (!(Context.User is IGuildUser)) { await ReplyAsync("Those are my global prefixes: " + $"`{Information.SecondaryPrefix}`, `{Information.Prefix}`, {Cirilla.Client.CurrentUser.Mention}"); return; } var config = GuildConfigManager.Get(Context.Guild.Id); string prefixes = string.Empty; if (config.EnablePrimaryPrefix) { prefixes += $"`{Information.Prefix}` "; } prefixes += $"`{config.Prefix}`, {Cirilla.Client.CurrentUser.Mention}"; await ReplyAsync($"Those are my current prefixes: {prefixes}"); }
public async Task Set([Summary("The user to set XP")] IGuildUser user, [Summary("The amount of XP you want to set")] int xp) { try { if (Context.User is IGuildUser setter) { if (!GuildConfigManager.Get(Context.Guild.Id).EnableXpSystem) { await ReplyAsync("XP System is disabled for this Guild! An Admin can use `$togglexp`!"); return; } if (!Helper.IsOwner(setter) && !setter.GuildPermissions.ManageMessages) { await ReplyAsync("Sorry, but you're not allowed to use that super premium command!"); return; } var userxp = XpManager.Get(Context.Guild, user); XpManager.Update(Context.Guild, user, xp - userxp.Xp); await ReplyAsync($"{Helper.GetName(user)} set {user.Mention}'s XP to {xp}!"); } else { await ReplyAsync("You can't use that command in DM!"); } ConsoleHelper.Log($"{Helper.GetName(Context.User)} set {Helper.GetName(user)}'s XP to {xp}!", LogSeverity.Info); } catch (Exception ex) { ConsoleHelper.Log($"Could not set {Helper.GetName(user)}'s XP! ({ex.Message})", LogSeverity.Error); await ReplyAsync("Whoops, I couldn't give XP to that user!"); } }
public static void Main(string[] args) { while (true) { try { Random = new Random(); if (!Directory.Exists(Information.Directory)) { Directory.CreateDirectory(Information.Directory); } Information.LoadInfo(); ConsoleHelper.Log(">> Starting Cirilla Discord Bot..", LogSeverity.Info); #pragma warning disable 219 bool skipIntro = false; #pragma warning restore 219 foreach (string arg in args) { string cleanArg = arg.ToLower().Replace("-", ""); switch (cleanArg) { case "skip": // ReSharper disable once RedundantAssignment skipIntro = true; break; case "legacy": // Need legacy Sockets (WS4NET) Information.NeedsWs4Net = true; break; } } bool windows = !IsLinux; if (windows) { ConsoleHelper.Set(); Console.Title = "Cirilla Discord Bot"; } #if !DEBUG if (!skipIntro && windows) { ConsoleHelper.Intro(); } #endif GuildConfigManager.Init(); Cirilla = new Cirilla(LogSeverity.Debug); StartTime = DateTime.Now; ConsoleHelper.Log("Initializing services..", LogSeverity.Info); var sw = Stopwatch.StartNew(); XpManager.Init(); NewsService.Init(); ConsoleHelper.Log($"Finished initializing services! ({sw.ElapsedMilliseconds}ms)", LogSeverity.Info); Thread.Sleep(-1); return; } catch (Exception ex) { string nl = Environment.NewLine; File.WriteAllText(Path.Combine(Information.Directory, "error.txt"), $"[{DateTime.Now:dd.MM.yyyy hh:mm:ss}] {ex.Message}:{nl}{ex.Message}{nl}{ex.Source}{nl}{ex.StackTrace}"); } Console.WriteLine("Retrying in 3.."); Thread.Sleep(1000); Console.WriteLine("Retrying in 2.."); Thread.Sleep(1000); Console.WriteLine("Retrying in 1.."); Thread.Sleep(1000); } }
private async Task MessageReceived(SocketMessage messageArg) { // Don't process the command if it was a System Message if (!(messageArg is SocketUserMessage message)) { return; } if (message.Author.ToString() != Client.CurrentUser.ToString()) { string secondaryPrefix; bool enablePrimary = true; string guildname = "private"; if (messageArg.Channel is IGuildChannel guildchannel) { guildname = guildchannel.Guild.Name; var config = GuildConfigManager.Get(guildchannel.Guild.Id); secondaryPrefix = config.Prefix; enablePrimary = config.EnablePrimaryPrefix; } else { secondaryPrefix = Information.SecondaryPrefix; } //Log to console but don't write log to file ConsoleHelper.Log(new LogMessage(LogSeverity.Info, $"{message.Author}@{guildname}", message.Content), false); // Command (after prefix) Begin int argPos = 0; // Determine if the message is a command by checking for all prefixes bool primaryMatch = enablePrimary && message.HasCharPrefix(Information.Prefix, ref argPos); bool secondaryMatch = message.HasStringPrefix(secondaryPrefix, ref argPos); bool mentionMatch = message.HasMentionPrefix(Client.CurrentUser, ref argPos); if (!(primaryMatch || secondaryMatch || mentionMatch)) { return; } CommandLogger.Log(message.Author.ToString(), guildname, message.Content); var context = new CommandContext(Client, message); var result = await Service.ExecuteAsync(context, argPos); if (!result.IsSuccess) { ConsoleHelper.Log($"Command did not execute correctly! {result.ErrorReason}", LogSeverity.Error); //await context.Channel.SendMessageAsync(result.ErrorReason); //Find out what the user probably meant var embed = Helper.WrongCommand(message, Service, context); if (embed != default(Embed)) { await context.Channel.SendMessageAsync("", embed : embed); } } } }
public async Task Stats() { try { if (!GuildConfigManager.Get(Context.Guild.Id).EnableXpSystem) { await ReplyAsync("XP System is disabled for this Guild! An Admin can use `$togglexp`!"); return; } var xps = XpManager.Top10(Context.Guild); if (xps.Count < 1) { await ReplyAsync("I couldn't find any users.."); return; } var builder = new EmbedBuilder { Author = new EmbedAuthorBuilder { Name = $"XP Ranking for {Context.Guild.Name} 🏆" }, ThumbnailUrl = Context.Guild.IconUrl, Color = new Color(255, 163, 50), Footer = new EmbedFooterBuilder { Text = $"..out of {XpManager.Get(Context.Guild).Count} total XP users" } }; int max = xps.Count > 10 ? 10 : xps.Count; for (int i = 0; i < max; i++) { var xp = xps[i]; IUser user = await Context.Guild.GetUserAsync(xp.UserId); string place; switch (i) { case 0: place = ":first_place: 1"; break; case 1: place = ":second_place: 2"; break; case 2: place = ":third_place: 3"; break; default: place = $"{i + 1}"; break; } builder.AddField($"{place}. {Helper.GetName(user)}", $"XP: **{xp.Xp}** | Level: **{xp.Level}**"); } try { var firstXp = xps[0]; IUser firstUser = await Context.Guild.GetUserAsync(firstXp.UserId); await ReplyAsync( $"Good job **{Helper.GetName(firstUser)}** on being first place with **{firstXp.Xp}** XP!", embed : builder.Build()); } catch { await ReplyAsync("", embed : builder.Build()); } } catch { await ReplyAsync("I couldn't do a full ranking for that guild, sorry.. :confused:"); } }
public static async void TimerCallback() { try { ConsoleHelper.Log("Giving away XP to everyone...", LogSeverity.Info); var receivers = new List <string>(); foreach (IGuild guild in Cirilla.Client.Guilds) { if (!GuildConfigManager.Get(guild.Id).EnableXpSystem) { continue; } IEnumerable <IGuildUser> users = await guild.GetUsersAsync(); var rnd = new Random(); foreach (var user in users.Where(u => !u.IsBot && (u.Status == UserStatus.Online || u.Status == UserStatus.DoNotDisturb || u.Status == UserStatus.Invisible) && u.VoiceChannel != null)) { //Update all [interval] seconds +3 XP Update(guild, user, 3); receivers.Add(user.ToString()); //1 in [GiveRandomXpChance] chance to give user XP if (rnd.Next(0, Information.GiveRandomXpChance) == 0) { const int freeXp = 200; Update(guild, user, freeXp); if (await guild.GetChannelAsync(guild.DefaultChannelId) is ITextChannel channel) { ConsoleHelper.Log( $"{user} randomly got {freeXp} free XP (1 in {Information.GiveRandomXpChance} chance)", LogSeverity.Info); await channel.SendMessageAsync( $"Lucky you, {user.Mention}! The gods have decided to give you {freeXp} free XP! :moneybag:"); } } } } if (receivers.Count < 1) { ConsoleHelper.Log( $"{Information.XpGiveInterval / 1000} Second interval - no-one gained XP!", LogSeverity.Info); } else { ConsoleHelper.Log( $"{Information.XpGiveInterval / 1000} Second interval - gave XP to: {string.Join(", ", receivers)}", LogSeverity.Info); } } catch (Exception ex) { ConsoleHelper.Log($"Could not give XP to everyone! ({ex.Message})", LogSeverity.Error); } }
public async Task Give([Summary("The user to give XP")] IGuildUser user, [Summary("The amount of XP you want to give the user")] int xp) { try { if (!GuildConfigManager.Get(Context.Guild.Id).EnableXpSystem) { await ReplyAsync("XP System is disabled for this Guild! An Admin can use `$togglexp`!"); return; } if (user.Id == Context.User.Id) { await ReplyAsync("Nice try, you can't give yourself XP!"); return; } if (xp == 0) { await ReplyAsync("Wow man. How generous. :+1:"); return; } bool canDrain = false; //Is sender Admin? bool drainOwn = true; //False if Admin is draining XP if (Context.User is IGuildUser guilduser && guilduser.GuildPermissions.Administrator) { canDrain = true; } if (xp < 1) { if (!canDrain) { await ReplyAsync("Nice try, you can't drain XP from Users!"); return; } else { drainOwn = false; } } int ownXp = xp / Information.OwnXp; var userxp = XpManager.Get(Context.Guild, Context.User); if (userxp.Xp >= xp) { int lvlBefore = XpManager.Get(Context.Guild, user).Level; XpManager.Update(Context.Guild, user, xp); int lvlAfter = XpManager.Get(Context.Guild, user).Level; //Drain XP from Sender, minus own XP (you get 1/100 from donations) if (drainOwn) { XpManager.Update(Context.Guild, Context.User, -xp + ownXp); } if (xp < 1) { await ReplyAsync( $"{Helper.GetName(Context.User)} drained {Helper.GetName(user)} {-xp} {GetNameForXp()}! :money_with_wings:"); } else { await ReplyAsync( $"{Helper.GetName(Context.User)} gave {Helper.GetName(user)} {xp} {GetNameForXp()}! :money_with_wings:"); } if (lvlAfter > lvlBefore) { await ReplyAsync($":tada: {Helper.GetName(user)} was promoted to level {lvlAfter}! :tada:"); } ConsoleHelper.Log($"{Helper.GetName(Context.User)} gave {Helper.GetName(user)} {xp}XP!", LogSeverity.Info); } else { await ReplyAsync( $"You can't give {xp} XP to {Helper.GetName(user)}, you only have {userxp.Xp} XP!"); } } catch (Exception ex) { ConsoleHelper.Log($"Could not give XP to {Helper.GetName(user)}! ({ex.Message})", LogSeverity.Error); await ReplyAsync("Whoops, I couldn't give XP to that user!"); } }