2021-07-21 09:48:23 -04:00

508 lines
18 KiB
C#

using Discord;
using Discord.Commands;
using Discord.Rest;
using Discord.WebSocket;
using NerdsTeaserBot.Misc;
using NerdsTeaserBot.Modules.Attributes;
using NerdsTeaserBot.Modules.Models;
using Nerd_STF.Extensions;
using Nerd_STF.File.Saving;
using Nerd_STF.Lists;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using static Discord.Format;
using static NerdsTeaserBot.Const;
namespace NerdsTeaserBot.Modules.Commands
{
[Group("level")]
[Name("Level")]
[Summary("Commands about leveling up and levelup message formatting")]
public class LevelModule : ModuleBase<SocketCommandContext>
{
public static List<User> LevelLeaderboard
{
get
{
System.Collections.Generic.List<User> systemL = new(Data.users.Data.FindAll(x => x.level != null).FindAll(x => x.level.TotalXP > 0).ToArray());
systemL.Sort((x, y) => x.level.TotalXP - y.level.TotalXP);
systemL.Reverse();
return new(systemL);
}
}
[Command("give")]
[RequireUserPermission(GuildPermission.ManageGuild)]
[Summary("Gives a certain amount of levels or xp to a user")]
public async Task Give([Summary("The user to give levels/xp to")] SocketGuildUser user, [Summary("The amount of levels/xp to give")] int value, [Summary("The type to give (levels/xp)")] ModifyType type = ModifyType.Levels)
{
User usr = Data.users.Data.FindOrDefault(x => x.userID == user.Id);
if (usr == null)
{
usr = new() { userID = user.Id };
Data.users.Data.Add(usr);
}
Level lvl = usr.level;
if (lvl == null)
{
lvl = new();
usr.level = lvl;
}
EmbedBuilder e = new()
{
Color = Colors.DefaultColor,
Description = user.Mention + " has has their " + Code(type.ToString()) + " added to, from ",
Timestamp = DateTime.Now,
Title = type + " Added",
};
switch (type)
{
case ModifyType.Level or ModifyType.Levels:
e.Description += Code("Level " + lvl.level) + " to " + Code("Level " + (lvl.level + value));
lvl.level += value;
break;
case ModifyType.XP:
e.Description += Code(lvl.xp + " XP") + " to " + Code(lvl.xp + value + " XP");
lvl.xp += value;
while (lvl.xp >= lvl.MaxXP)
{
lvl.xp -= lvl.MaxXP;
lvl.level++;
}
break;
}
await ReplyAsync("", false, e.Build());
}
[Command("leaderboard")]
[Summary("Shows the level stats of anyone who has talked in this server")]
public async Task Leaderboard()
{
List<User> users = LevelLeaderboard;
int countedM = 0, totalM = 0, totalX = 0;
string leaderboard = "";
for (int i = 0; i < users.Length; i++)
{
Level lvl = users[i].level;
countedM += lvl.countedMsgs;
totalM += lvl.msgs;
totalX += lvl.TotalXP;
leaderboard += Code(Nerd_STF.Misc.PlaceMaker(i + 1)) + ": <@" + users[i].userID + ">: " + Code("Level " + lvl.level) + " and " + Code(lvl.xp + "/" + lvl.MaxXP + " XP") + " *(" + lvl.msgs + " Message";
if (lvl.msgs != 1) leaderboard += "s";
leaderboard += ", " + lvl.countedMsgs + " Counted)*\n";
}
EmbedBuilder e = new()
{
Color = Colors.DefaultColor,
Description = "*" + totalM + " Total Message",
Timestamp = DateTime.Now,
Title = "Level Leaderboard for " + Context.Guild.Name,
};
if (totalM != 1) e.Description += "s";
e.Description += " (" + countedM + " Counted)*\n" + Italics(totalX + " Total XP") + "\n\n" + leaderboard;
await ReplyAsync("", false, e.Build());
}
[Command("mention get")]
[Summary("Shows if the bot will mention a user when they level up")]
public async Task MentionGet()
{
EmbedBuilder e = new()
{
Color = Colors.DefaultColor,
Description = "The bot will mention users when they level up: " + Code(Data.misc.Data.levelMention.ToString()),
Timestamp = DateTime.Now,
Title = "Levelup Mention",
};
await ReplyAsync("", false, e.Build());
}
[Command("mention reset")]
[RequireUserPermission(GuildPermission.ManageGuild)]
[Summary("Sets the ability to mention when leveling up back to the default value")]
public async Task MentionReset()
{
Data.misc.Data.levelMention = false;
EmbedBuilder e = new()
{
Color = Colors.DefaultColor,
Description = "Successfully set the ability to mention a user when leveling up to: " + Code("False"),
Timestamp = DateTime.Now,
Title = "Reset Levelup Mention",
};
await ReplyAsync("", false, e.Build());
}
[Command("mention set")]
[RequireUserPermission(GuildPermission.ManageGuild)]
[Summary("Sets the ability to mention when leveling up")]
public async Task MentionSet([Summary("The true/false statement of the ability")] bool mention)
{
bool old = Data.misc.Data.levelMention;
Data.misc.Data.levelMention = mention;
EmbedBuilder e = new()
{
Color = Colors.DefaultColor,
Description = "Successfully set the ability to mention a user when leveling up to: " + Code(mention.ToString()),
Timestamp = DateTime.Now,
Title = "Set Levelup Mention",
};
e.Description += "\n(Previous: " + Code(old.ToString() + ")");
await ReplyAsync("", false, e.Build());
}
[Command("rank")]
[Summary("Shows level info on the user executing the command")]
public async Task Rank() => await Rank(Context.User);
[Command("rank")]
[Summary("Shows level info on a specific user")]
public async Task Rank(SocketUser user)
{
User usr = Data.users.Data.FindOrDefault(x => x.userID == user.Id);
if (usr == null)
{
usr = new() { userID = user.Id };
Data.users.Data.Add(usr);
}
Level lvl = usr.level;
if (lvl == null)
{
lvl = new();
usr.level = lvl;
}
EmbedBuilder e = new()
{
Color = Colors.DefaultColor,
Description = user.Mention + " " + Code(lvl.TotalXP > 0 ? "IS" : "is NOT") + " on the Leaderboard\n\n" +
"Level: " + Code(lvl.level.ToString()) + "\n" +
"XP: " + Code(lvl.xp.ToString()) + "\n" +
"(Total XP): " + Code(lvl.TotalXP.ToString()) + "\n" +
"XP to Level Up: " + Code((lvl.MaxXP - lvl.xp).ToString() + " (" + lvl.MaxXP + " Total)"),
Timestamp = DateTime.Now,
Title = user.Username + "'s Level Stats",
};
if (lvl.TotalXP > 0) e.Description += "\n" + "Leaderboard Rank: " + Code(Nerd_STF.Misc.PlaceMaker(LevelLeaderboard.FindIndex(x => x.userID == user.Id) + 1));
await Context.Channel.SendFileAsync(Data.appPath + "/data/constant/level-imgs/" + Math.Clamp(lvl.level, -1, 101) + ".png", "", false, e.Build());
}
[Command("remove")]
[RequireUserPermission(GuildPermission.ManageGuild)]
[Summary("Removes a certain amount of levels or xp from a user")]
public async Task Remove([Summary("The user to remove levels/xp from")] SocketGuildUser user, [Summary("The amount of levels/xp to remove")] int value, [Summary("The type to remove (levels/xp)")] ModifyType type = ModifyType.Levels)
{
User usr = Data.users.Data.FindOrDefault(x => x.userID == user.Id);
if (usr == null)
{
usr = new() { userID = user.Id };
Data.users.Data.Add(usr);
}
Level lvl = usr.level;
if (lvl == null)
{
lvl = new();
usr.level = lvl;
}
EmbedBuilder e = new()
{
Color = Colors.DefaultColor,
Description = user.Mention + " has has their " + Code(type.ToString()) + " removed, from ",
Timestamp = DateTime.Now,
Title = type + " Removed",
};
switch (type)
{
case ModifyType.Level or ModifyType.Levels:
if (lvl.level < value)
{
LogModule.LogMessage(LogSeverity.Error, "User does not have enough levels to remove");
return;
}
double percent = lvl.xp / lvl.MaxXP;
e.Description += Code("Level " + lvl.level) + " to " + Code("Level " + (lvl.level - value));
lvl.level -= value;
lvl.xp = (int)Math.Round(percent * lvl.MaxXP);
break;
case ModifyType.XP:
if (lvl.TotalXP < value)
{
LogModule.LogMessage(LogSeverity.Error, "User does not have enough xp to remove");
return;
}
e.Description += Code(lvl.xp + " XP") + " to " + Code(lvl.xp - value + " XP");
while (value >= lvl.MaxXP)
{
value -= lvl.MaxXP;
lvl.xp--;
}
lvl.xp -= value;
break;
}
await ReplyAsync("", false, e.Build());
}
[Command("reset")]
[RequireUserPermission(GuildPermission.ManageGuild)]
[Summary("Resets all levels or xp for a user")]
public async Task Reset([Summary("The user to reset levels/xp of")] SocketGuildUser user, [Summary("The type to reset (levels/xp)")] ModifyType type = ModifyType.Levels)
{
User usr = Data.users.Data.FindOrDefault(x => x.userID == user.Id);
if (usr == null)
{
usr = new() { userID = user.Id };
Data.users.Data.Add(usr);
}
Level lvl = usr.level;
if (lvl == null)
{
lvl = new();
usr.level = lvl;
}
EmbedBuilder e = new()
{
Color = Colors.DefaultColor,
Description = user.Mention + " has has their " + Code(type.ToString()) + " reset to " + Code("0"),
Timestamp = DateTime.Now,
Title = type + " Reset",
};
switch (type)
{
case ModifyType.Level or ModifyType.Levels:
double percent = lvl.xp / lvl.MaxXP;
lvl.level = 0;
lvl.xp = (int)Math.Round(percent * 200);
break;
case ModifyType.XP:
lvl.xp = 0;
break;
}
await ReplyAsync("", false, e.Build());
}
[Command("set")]
[RequireUserPermission(GuildPermission.ManageGuild)]
[Summary("Sets a user's level or xp")]
public async Task Set([Summary("The user to set levels/xp of")] SocketGuildUser user, [Summary("The amount of levels/xp to set")] int value, [Summary("The type to set (levels/xp)")] ModifyType type = ModifyType.Levels)
{
User usr = Data.users.Data.FindOrDefault(x => x.userID == user.Id);
if (usr == null)
{
usr = new() { userID = user.Id };
Data.users.Data.Add(usr);
}
Level lvl = usr.level;
if (lvl == null)
{
lvl = new();
usr.level = lvl;
}
EmbedBuilder e = new()
{
Color = Colors.DefaultColor,
Description = user.Mention + " has has their " + Code(type.ToString()) + " set from ",
Timestamp = DateTime.Now,
Title = type + " Changed",
};
switch (type)
{
case ModifyType.Level or ModifyType.Levels:
e.Description += Code("Level " + lvl.level) + " to " + Code("Level " + value);
double xp = lvl.xp;
if (value < lvl.level) xp = lvl.xp / lvl.MaxXP;
lvl.level = value;
if (value < lvl.level) lvl.xp = (int)Math.Round(xp * lvl.MaxXP);
break;
case ModifyType.XP:
e.Description += Code(lvl.xp + " XP") + " to " + Code(value + " XP");
lvl.xp += value;
while (lvl.xp >= lvl.MaxXP)
{
lvl.xp -= lvl.MaxXP;
lvl.level++;
}
break;
}
await ReplyAsync("", false, e.Build());
}
[Command("speed get")]
[Summary("Shows the current xp cooldown")]
public async Task SpeedGet()
{
EmbedBuilder e = new()
{
Color = Colors.DefaultColor,
Description = "The current cooldown between messages is `" + Data.misc.Data.levelCooldown + " Second",
Timestamp = DateTime.Now,
Title = "XP Speed",
};
if (Data.misc.Data.levelCooldown != 1) e.Description += "s";
e.Description += "`";
await ReplyAsync("", false, e.Build());
}
[Command("speed reset")]
[RequireUserPermission(GuildPermission.ManageGuild)]
[Summary("Sets the current xp cooldown to 60 seconds")]
public async Task SpeedReset()
{
Data.misc.Data.levelCooldown = 60;
EmbedBuilder e = new()
{
Color = Colors.DefaultColor,
Description = "Successfully set the current xp cooldown to: " + Code("60 Seconds"),
Timestamp = DateTime.Now,
Title = "Reset xp cooldown",
};
await ReplyAsync("", false, e.Build());
}
[Command("speed set")]
[RequireUserPermission(GuildPermission.ManageGuild)]
[Summary("Sets the current xp cooldown")]
public async Task SpeedSet([Summary("The time in seconds of the xp cooldown")] int seconds)
{
int old = Data.misc.Data.levelCooldown;
Data.misc.Data.levelCooldown = seconds;
EmbedBuilder e = new()
{
Color = Colors.DefaultColor,
Description = "Successfully set changelog channel to: `" + seconds + " Second",
Timestamp = DateTime.Now,
Title = "Set changelog channel",
};
if (seconds != 1) e.Description += "s";
e.Description += "`\n(Previous: `" + old + " Second";
if (old != 1) e.Description += "s";
e.Description += "`)";
await ReplyAsync("", false, e.Build());
}
// end commands
public static async Task LevelHandler(SocketUserMessage msg)
{
User usr = Data.users.Data.FindOrDefault(x => x.userID == msg.Author.Id);
Level level = null;
if (usr == null)
{
level = new();
usr = new()
{
currentMute = new(),
level = level,
tickets = 0,
userID = msg.Author.Id,
warns = new(),
};
Data.users.Data.Add(usr);
}
else
{
if (usr.level == null) usr.level = new();
level = usr.level;
}
level.msgs++;
if (level.lastCountedMsg.AddSeconds(Data.misc.Data.levelCooldown) < msg.Timestamp.DateTime)
{
level.countedMsgs++;
level.lastCountedMsg = msg.Timestamp.DateTime;
level.xp += new Random().Next(15, 26);
if (level.xp >= level.MaxXP)
{
level.xp -= level.MaxXP;
usr.level.level++;
EmbedBuilder e = new()
{
Color = Colors.DefaultColor,
Description = msg.Author.Mention + ", you have leveled up to " + Code("Level " + usr.level.level) + ". You need " + Code(level.MaxXP + " XP") + " to get to the next level",
Timestamp = DateTime.Now,
Title = "Leveled Up!",
};
string send = "";
if (Data.misc.Data.levelMention) send = msg.Author.Mention;
await msg.Channel.SendFileAsync(Data.appPath + "/data/constant/level-imgs/" + Math.Clamp(level.level, -1, 101) + ".png", send, false, e.Build());
}
};
}
// end of methods
public enum ModifyType
{
Level,
Levels,
XP,
}
}
}