huge changes once again
diff --git a/src/commands/categorisationTest.ts b/src/commands/categorisationTest.ts
index 4a28841..a6c7479 100644
--- a/src/commands/categorisationTest.ts
+++ b/src/commands/categorisationTest.ts
@@ -1,21 +1,22 @@
 import { CommandInteraction, MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js";
-import { SelectMenuComponent, SelectMenuOption, SlashCommandBuilder } from "@discordjs/builders";
+import { SlashCommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../utils/generateEmojiEmbed.js";
 import generateKeyValueList, { toCapitals } from "../utils/generateKeyValueList.js";
 import getEmojiByName from "../utils/getEmojiByName.js";
+import client from "../utils/client.js"
 
 const command = new SlashCommandBuilder()
     .setName("categorise")
     .setDescription("Categorises your servers channels")
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
     const { renderChannel } = client.logger
 
     let channels = interaction.guild.channels.cache.filter(c => c.type !== "GUILD_CATEGORY");
     let categorised = {}
 
-    await interaction.reply({embeds: [new generateEmojiEmbed()
+    await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Loading...")
         .setEmoji("NUCLEUS.LOADING")
         .setStatus("Success")
@@ -40,7 +41,7 @@
             }
         }
 
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setTitle("Categorise")
             .setDescription(generateKeyValueList({
                 channel: renderChannel(c),
diff --git a/src/commands/mod/ban.ts b/src/commands/mod/ban.ts
index 8b17db3..4581c0f 100644
--- a/src/commands/mod/ban.ts
+++ b/src/commands/mod/ban.ts
@@ -2,7 +2,7 @@
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
 import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import keyValueList from "../../utils/generateKeyValueList.js";
 import addPlurals from "../../utils/plurals.js";
 import client from "../../utils/client.js";
@@ -18,13 +18,14 @@
     )
     .addIntegerOption(option => option.setName("delete").setDescription("The days of messages to delete | Default 0").setMinValue(0).setMaxValue(7).setRequired(false))
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+    const { renderUser } = client.logger
     // TODO:[Modals] Replace this with a modal
     let confirmation = await new confirmationMessage(interaction)
         .setEmoji("PUNISH.BAN.RED")
         .setTitle("Ban")
         .setDescription(keyValueList({
-            "user": `<@!${(interaction.options.getMember("user") as GuildMember).id}> (${(interaction.options.getMember("user") as GuildMember).user.username})`,
+            "user": renderUser(interaction.options.getUser("user")),
             "reason": `\n> ${interaction.options.getString("reason") ? interaction.options.getString("reason") : "*No reason provided*"}`
         })
         + `The user **will${interaction.options.getString("notify") === "no" ? ' not' : ''}** be notified\n`
@@ -35,11 +36,11 @@
     if (confirmation.success) {
         let dmd = false
         let dm;
-        let config = await client.database.read(interaction.guild.id);
+        let config = await client.database.guilds.read(interaction.guild.id);
         try {
             if (interaction.options.getString("notify") != "no") {
                 dm = await (interaction.options.getMember("user") as GuildMember).send({
-                    embeds: [new generateEmojiEmbed()
+                    embeds: [new EmojiEmbed()
                         .setEmoji("PUNISH.BAN.RED")
                         .setTitle("Banned")
                         .setDescription(`You have been banned in ${interaction.guild.name}` +
@@ -57,13 +58,13 @@
         } catch {}
         try {
             let member = (interaction.options.getMember("user") as GuildMember)
-            let reason = interaction.options.getString("reason") ?? "No reason provided"
+            let reason = interaction.options.getString("reason")
             member.ban({
                 days: Number(interaction.options.getInteger("delete") ?? 0),
-                reason: reason
+                reason: reason ?? "No reason provided"
             })
-            // @ts-ignore
-            const { log, NucleusColors, entry, renderUser, renderDelta } = interaction.user.client.logger
+            try { await client.database.history.create("ban", interaction.guild.id, member.user, interaction.user, reason) } catch {}
+            const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger
             let data = {
                 meta: {
                     type: 'memberBan',
@@ -86,9 +87,9 @@
                     guild: interaction.guild.id
                 }
             }
-            log(data, member.user.client);
+            log(data);
         } catch {
-            await interaction.editReply({embeds: [new generateEmojiEmbed()
+            await interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji("PUNISH.BAN.RED")
                 .setTitle(`Ban`)
                 .setDescription("Something went wrong and the user was not banned")
@@ -98,14 +99,14 @@
             return
         }
         let failed = (dmd == false && interaction.options.getString("notify") != "no")
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji(`PUNISH.BAN.${failed ? "YELLOW" : "GREEN"}`)
             .setTitle(`Ban`)
             .setDescription("The member was banned" + (failed ? ", but could not be notified" : ""))
             .setStatus(failed ? "Warning" : "Success")
         ], components: []})
     } else {
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji("PUNISH.BAN.GREEN")
             .setTitle(`Ban`)
             .setDescription("No changes were made")
@@ -125,13 +126,13 @@
     // Check if Nucleus can ban the member
     if (! (mePos > applyPos)) throw "I do not have a role higher than that member"
     // Check if Nucleus has permission to ban
-    if (! me.permissions.has("BAN_MEMBERS")) throw "I do not have the `ban_members` permission";
+    if (! me.permissions.has("BAN_MEMBERS")) throw "I do not have the Ban members permission";
     // Do not allow banning Nucleus
     if (member.id == interaction.guild.me.id) throw "I cannot ban myself"
     // Allow the owner to ban anyone
     if (member.id == interaction.guild.ownerId) return true
     // Check if the user has ban_members permission
-    if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the `ban_members` permission";
+    if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the Ban members permission";
     // Check if the user is below on the role list
     if (! (memberPos > applyPos)) throw "You do not have a role higher than that member"
     // Allow ban
diff --git a/src/commands/mod/info.ts b/src/commands/mod/info.ts
new file mode 100644
index 0000000..c3a4388
--- /dev/null
+++ b/src/commands/mod/info.ts
@@ -0,0 +1,285 @@
+import { HistorySchema } from '../../utils/database';
+import Discord, { CommandInteraction, GuildMember, MessageActionRow, MessageButton, TextInputComponent } from "discord.js";
+import { SlashCommandSubcommandBuilder, SelectMenuOption } from "@discordjs/builders";
+import { WrappedCheck } from "jshaiku";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import getEmojiByName from "../../utils/getEmojiByName.js";
+import client from "../../utils/client.js";
+import { modalInteractionCollector } from '../../utils/dualCollector.js';
+import pageIndicator from '../../utils/createPageIndicator.js';
+
+const command = (builder: SlashCommandSubcommandBuilder) =>
+    builder
+    .setName("info")
+    .setDescription("Shows moderator information about a user")
+    .addUserOption(option => option.setName("user").setDescription("The user to get information about").setRequired(true))
+
+
+const types = {
+    "warn": {emoji: "PUNISH.WARN.YELLOW", text: "Warned"},
+    "mute": {emoji: "PUNISH.MUTE.YELLOW", text: "Muted"},
+    "join": {emoji: "MEMBER.JOIN", text: "Joined"},
+    "leave": {emoji: "MEMBER.LEAVE", text: "Left"},
+    "kick": {emoji: "MEMBER.KICK", text: "Kicked"},
+    "softban": {emoji: "PUNISH.SOFTBAN", text: "Softbanned"},
+    "ban": {emoji: "MEMBER.BAN", text: "Banned"},
+    "unban": {emoji: "MEMBER.UNBAN", text: "Unbanned"},
+    "purge": {emoji: "PUNISH.CLEARHISTORY", text: "Messages cleared"},
+    "nickname": {emoji: "PUNISH.NICKNAME.YELLOW", text: "Nickname changed"}
+}
+
+function historyToString(history: HistorySchema) {
+    let s = `${getEmojiByName(types[history.type].emoji)} ${
+        history.amount ? (history.amount + " ") : ""
+    }${
+        types[history.type].text
+    } on <t:${Math.round(history.occurredAt.getTime() / 1000)}:F>`;
+    if (history.moderator) { s += ` by <@${history.moderator}>`; }
+    if (history.reason) { s += `\n**Reason:**\n> ${history.reason}`; }
+    if (history.before) { s += `\n**Before:**\n> ${history.before}`; }
+    if (history.after) { s += `\n**After:**\n> ${history.after}`; }
+    return s + "\n";
+}
+
+
+class TimelineSection {
+    name: string;
+    content: {data: HistorySchema, rendered: string}[] = []
+
+    addContent = (content: {data: HistorySchema, rendered: string}) => { this.content.push(content); return this; }
+    contentLength = () => { return this.content.reduce((acc, cur) => acc + cur.rendered.length, 0); };
+    generateName = () => {
+        let first = Math.round(this.content[0].data.occurredAt.getTime() / 1000)
+        let last = Math.round(this.content[this.content.length - 1].data.occurredAt.getTime() / 1000)
+        if (first === last) { return this.name = `<t:${first}:F>`; }
+        return this.name = `<t:${first}:F> - <t:${last}:F>`;
+    }
+}
+
+const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
+
+async function showHistory(member, interaction: CommandInteraction) {
+    let currentYear = new Date().getFullYear();
+    let pageIndex = null;
+    let m, history, current;
+    let refresh = true;
+    let filteredTypes = [];
+    let openFilterPane = false;
+    while (true) {
+        if (refresh) {
+            history = await client.database.history.read(member.guild.id, member.id, currentYear);
+            history = history.sort((a, b) => b.occurredAt.getTime() - a.occurredAt.getTime()).reverse();
+            if (openFilterPane) {
+                let tempFilteredTypes = filteredTypes
+                if (filteredTypes.length === 0) { tempFilteredTypes = Object.keys(types); }
+                history = history.filter(h => tempFilteredTypes.includes(h.type))
+            };
+            refresh = false;
+        }
+        let groups: TimelineSection[] = []
+        if (history.length > 0) {
+            current = new TimelineSection()
+            history.forEach(event => {
+                if (current.contentLength() + historyToString(event).length > 2000 || current.content.length === 5) {
+                    groups.push(current);
+                    current.generateName();
+                    current = new TimelineSection();
+                }
+                current.addContent({data: event, rendered: historyToString(event)});
+            });
+            current.generateName();
+            groups.push(current);
+            if (pageIndex === null) { pageIndex = groups.length - 1; }
+        }
+        let components = (
+            openFilterPane ? [
+            new MessageActionRow().addComponents([new Discord.MessageSelectMenu().setOptions(
+                Object.entries(types).map(([key, value]) => ({
+                        label: value.text,
+                        value: key,
+                        default: filteredTypes.includes(key),
+                        emoji: client.emojis.resolve(getEmojiByName(value.emoji, "id"))
+                }))
+            ).setMinValues(1).setMaxValues(Object.keys(types).length).setCustomId("filter").setPlaceholder("Select at least one event")])
+        ] : []).concat([
+            new MessageActionRow().addComponents([
+                new MessageButton()
+                    .setCustomId("prevYear")
+                    .setLabel((currentYear - 1).toString())
+                    .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+                    .setStyle("SECONDARY"),
+                new MessageButton()
+                    .setCustomId("prevPage")
+                    .setLabel("Previous page")
+                    .setStyle("PRIMARY"),
+                new MessageButton()
+                    .setCustomId("today")
+                    .setLabel("Today")
+                    .setStyle("PRIMARY"),
+                new MessageButton()
+                    .setCustomId("nextPage")
+                    .setLabel("Next page")
+                    .setStyle("PRIMARY")
+                    .setDisabled(pageIndex >= groups.length - 1 && currentYear === new Date().getFullYear()),
+                new MessageButton()
+                    .setCustomId("nextYear")
+                    .setLabel((currentYear + 1).toString())
+                    .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+                    .setStyle("SECONDARY")
+                    .setDisabled(currentYear === new Date().getFullYear()),
+            ]), new MessageActionRow().addComponents([
+                new MessageButton()
+                    .setLabel("Mod notes")
+                    .setCustomId("modNotes")
+                    .setStyle("PRIMARY")
+                    .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
+                new MessageButton()
+                    .setLabel("Filter")
+                    .setCustomId("openFilter")
+                    .setStyle(openFilterPane ? "SUCCESS" : "PRIMARY")
+                    .setEmoji(getEmojiByName("ICONS.FILTER", "id"))
+            ])
+        ])
+        let end = "\n\nJanuary " + currentYear.toString() + pageIndicator(
+            Math.max(groups.length, 1),
+            groups.length === 0 ? 1 : pageIndex
+        ) + (currentYear == new Date().getFullYear() ? monthNames[new Date().getMonth()] : "December"
+        ) + " " + currentYear.toString()
+        if (groups.length > 0) {
+            let toRender = groups[Math.min(pageIndex, groups.length - 1)]
+            m = await interaction.editReply({embeds: [new EmojiEmbed()
+                .setEmoji("MEMBER.JOIN")
+                .setTitle("Moderation history for " + member.user.username)
+                .setDescription(`**${toRender.name}**\n\n` + toRender.content.map(c => c.rendered).join("\n") + end)
+                .setStatus("Success")
+                .setFooter({text: (openFilterPane && filteredTypes.length) ? "Filters are currently enabled" : ""})
+            ], components: components});
+        } else {
+            m = await interaction.editReply({embeds: [new EmojiEmbed()
+                .setEmoji("MEMBER.JOIN")
+                .setTitle("Moderation history for " + member.user.username)
+                .setDescription(`**${currentYear}**\n\n*No events*` + `\n\n` + end)
+                .setStatus("Success")
+                .setFooter({text: (openFilterPane && filteredTypes.length) ? "Filters are currently enabled" : ""})
+            ], components: components});
+        }
+        let i;
+        try {
+            i = await m.awaitMessageComponent({ time: 300000 });
+        } catch (e) {
+            interaction.editReply({embeds: [new EmojiEmbed()
+                .setEmoji("MEMBER.JOIN")
+                .setTitle("Moderation history for " + member.user.username)
+                .setDescription(m.embeds[0].description)
+                .setStatus("Danger")
+                .setFooter({text: "Message timed out"})
+            ]});
+            return 0
+        }
+        i.deferUpdate()
+        if (i.customId === "filter") {
+            filteredTypes = i.values;
+            pageIndex = null;
+            refresh = true;
+        }
+        if (i.customId === "prevYear") { currentYear--; pageIndex = null; refresh = true; }
+        if (i.customId === "nextYear") { currentYear++; pageIndex = null; refresh = true; }
+        if (i.customId === "prevPage") {
+            pageIndex--;
+            if (pageIndex < 0) { pageIndex = null; currentYear--; refresh = true; }
+        }
+        if (i.customId === "nextPage") {
+            pageIndex++;
+            if (pageIndex >= groups.length) { pageIndex = 0; currentYear++; refresh = true; }
+        }
+        if (i.customId === "today") { currentYear = new Date().getFullYear(); pageIndex = null; refresh = true; }
+        if (i.customId === "modNotes") { return 1 }
+        if (i.customId === "openFilter") { openFilterPane = !openFilterPane; refresh = true }
+    }
+}
+
+
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+    let m;
+    let member = (interaction.options.getMember("user")) as Discord.GuildMember;
+    await interaction.reply({embeds: [new EmojiEmbed()
+        .setEmoji("NUCLEUS.LOADING")
+        .setTitle("Downloading data...")
+        .setStatus("Success")
+    ], ephemeral: true, fetchReply: true});
+    let note;
+    let firstLoad = true;
+    while (true) {
+        note = await client.database.notes.read(member.guild.id, member.id);
+        if (firstLoad && !note) { await showHistory(member, interaction); }
+        firstLoad = false;
+        m = await interaction.editReply({embeds: [new EmojiEmbed()
+            .setEmoji("MEMBER.JOIN")
+            .setTitle("Mod notes for " + member.user.username)
+            .setDescription(note ? note : "*No note set*")
+            .setStatus("Success")
+        ], components: [new MessageActionRow().addComponents([
+            new MessageButton()
+                .setLabel(`${note ? "Modify" : "Create"} note`)
+                .setStyle("PRIMARY")
+                .setCustomId("modify")
+                .setEmoji(getEmojiByName("ICONS.EDIT", "id")),
+            new MessageButton()
+                .setLabel("View moderation history")
+                .setStyle("PRIMARY")
+                .setCustomId("history")
+                .setEmoji(getEmojiByName("ICONS.HISTORY", "id"))
+        ])]});
+        let i;
+        try {
+            i = await m.awaitMessageComponent({ time: 300000 });
+        } catch (e) { return }
+        if (i.customId === "modify") {
+            await i.showModal(new Discord.Modal().setCustomId("modal").setTitle(`Editing moderator note`).addComponents(
+                // @ts-ignore
+                new MessageActionRow().addComponents(new TextInputComponent()
+                    .setCustomId("note")
+                    .setLabel("Note")
+                    .setMaxLength(4000)
+                    .setRequired(false)
+                    .setStyle("PARAGRAPH")
+                    .setValue(note ? note : "")
+                )
+            ))
+            await interaction.editReply({
+                embeds: [new EmojiEmbed()
+                    .setTitle("Mod notes for " + member.user.username)
+                    .setDescription("Modal opened. If you can't see it, click back and try again.")
+                    .setStatus("Success")
+                    .setEmoji("GUILD.TICKET.OPEN")
+                ], components: [new MessageActionRow().addComponents([new MessageButton()
+                    .setLabel("Back")
+                    .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+                    .setStyle("PRIMARY")
+                    .setCustomId("back")
+                ])]
+            });
+            let out;
+            try {
+                out = await modalInteractionCollector(m, (m) => m.channel.id == interaction.channel.id, (m) => m.customId == "modify")
+            } catch (e) { continue }
+            if (out.fields) {
+                let toAdd = out.fields.getTextInputValue("note") || null;
+                await client.database.notes.create(member.guild.id, member.id, toAdd);
+            } else { continue }
+        } else if (i.customId === "history") {
+            i.deferUpdate();
+            if (!await showHistory(member, interaction) ) return
+        }
+    }
+}
+
+const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
+    let member = (interaction.member as GuildMember)
+    if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the Moderate members permission";
+    return true
+}
+
+export { command };
+export { callback };
+export { check };
\ No newline at end of file
diff --git a/src/commands/mod/kick.ts b/src/commands/mod/kick.ts
index 20fbc01..97ead7b 100644
--- a/src/commands/mod/kick.ts
+++ b/src/commands/mod/kick.ts
@@ -3,7 +3,7 @@
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
 import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import keyValueList from "../../utils/generateKeyValueList.js";
 import client from "../../utils/client.js";
 
@@ -17,13 +17,14 @@
         .addChoices([["Yes", "yes"], ["No", "no"]])
     )
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+    const { renderUser } = client.logger
     // TODO:[Modals] Replace this with a modal
     let confirmation = await new confirmationMessage(interaction)
         .setEmoji("PUNISH.KICK.RED")
         .setTitle("Kick")
         .setDescription(keyValueList({
-            "user": `<@!${(interaction.options.getMember("user") as GuildMember).id}> (${(interaction.options.getMember("user") as GuildMember).user.username})`,
+            "user": renderUser(interaction.options.getUser("user")),
             "reason": `\n> ${interaction.options.getString("reason") ? interaction.options.getString("reason") : "*No reason provided*"}`
         })
         + `The user **will${interaction.options.getString("notify") === "no" ? ' not' : ''}** be notified\n\n`
@@ -33,11 +34,11 @@
     if (confirmation.success) {
         let dmd = false
         let dm;
-        let config = await client.database.read(interaction.guild.id);
+        let config = await client.database.guilds.read(interaction.guild.id);
         try {
             if (interaction.options.getString("notify") != "no") {
                 dm = await (interaction.options.getMember("user") as GuildMember).send({
-                    embeds: [new generateEmojiEmbed()
+                    embeds: [new EmojiEmbed()
                         .setEmoji("PUNISH.KICK.RED")
                         .setTitle("Kicked")
                         .setDescription(`You have been kicked in ${interaction.guild.name}` +
@@ -57,8 +58,9 @@
             (interaction.options.getMember("user") as GuildMember).kick(interaction.options.getString("reason") ?? "No reason provided.")
             let member = (interaction.options.getMember("user") as GuildMember)
             let reason = interaction.options.getString("reason") ?? null
+            try { await client.database.history.create("kick", interaction.guild.id, member.user, interaction.user, reason) } catch {}
             // @ts-ignore
-            const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger
+            const { log, NucleusColors, entry, renderUser, renderDelta } = member.client.logger
             let data = {
                 meta: {
                     type: 'memberKick',
@@ -83,9 +85,9 @@
                     guild: member.guild.id
                 }
             }
-            log(data, member.client);
+            log(data);
         } catch {
-            await interaction.editReply({embeds: [new generateEmojiEmbed()
+            await interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji("PUNISH.KICK.RED")
                 .setTitle(`Kick`)
                 .setDescription("Something went wrong and the user was not kicked")
@@ -95,14 +97,14 @@
             return
         }
         let failed = (dmd == false && interaction.options.getString("notify") != "no")
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji(`PUNISH.KICK.${failed ? "YELLOW" : "GREEN"}`)
             .setTitle(`Kick`)
             .setDescription("The member was kicked" + (failed ? ", but could not be notified" : ""))
             .setStatus(failed ? "Warning" : "Success")
         ], components: []})
     } else {
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji("PUNISH.KICK.GREEN")
             .setTitle(`Kick`)
             .setDescription("No changes were made")
@@ -122,13 +124,13 @@
     // Check if Nucleus can kick the member
     if (! (mePos > applyPos)) throw "I do not have a role higher than that member"
     // Check if Nucleus has permission to kick
-    if (! me.permissions.has("KICK_MEMBERS")) throw "I do not have the `kick_members` permission";
+    if (! me.permissions.has("KICK_MEMBERS")) throw "I do not have the Kick members permission";
     // Do not allow kicking Nucleus
     if (member.id == interaction.guild.me.id) throw "I cannot kick myself"
     // Allow the owner to kick anyone
     if (member.id == interaction.guild.ownerId) return true
     // Check if the user has kick_members permission
-    if (! member.permissions.has("KICK_MEMBERS")) throw "You do not have the `kick_members` permission";
+    if (! member.permissions.has("KICK_MEMBERS")) throw "You do not have the Kick members permission";
     // Check if the user is below on the role list
     if (! (memberPos > applyPos)) throw "You do not have a role higher than that member"
     // Allow kick
diff --git a/src/commands/mod/mute.ts b/src/commands/mod/mute.ts
index 79beeb3..5f42b27 100644
--- a/src/commands/mod/mute.ts
+++ b/src/commands/mod/mute.ts
@@ -1,7 +1,7 @@
 import Discord, { CommandInteraction, GuildMember, MessageActionRow, MessageButton } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import getEmojiByName from "../../utils/getEmojiByName.js";
 import confirmationMessage from "../../utils/confirmationMessage.js";
 import keyValueList from "../../utils/generateKeyValueList.js";
@@ -31,14 +31,14 @@
         minutes: interaction.options.getInteger("minutes") || 0,
         seconds: interaction.options.getInteger("seconds") || 0
     }
-    let config = await client.database.read(interaction.guild.id)
+    let config = await client.database.guilds.read(interaction.guild.id)
     let serverSettingsDescription = (config.moderation.mute.timeout ? "given a timeout" : "")
     if (config.moderation.mute.role) serverSettingsDescription += (serverSettingsDescription ? " and " : "") + `given the <@&${config.moderation.mute.role}> role`
 
     let muteTime = (time.days * 24 * 60 * 60) + (time.hours * 60 * 60) + (time.minutes * 60) + time.seconds
     if (muteTime == 0) {
         let m = await interaction.reply({embeds: [
-            new generateEmojiEmbed()
+            new EmojiEmbed()
                 .setEmoji("PUNISH.MUTE.GREEN")
                 .setTitle("Mute")
                 .setDescription("How long should the user be muted")
@@ -93,7 +93,7 @@
             component = await (m as Discord.Message).awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 300000});
         } catch { return }
         component.deferUpdate();
-        if (component.customId == "cancel") return interaction.editReply({embeds: [new generateEmojiEmbed()
+        if (component.customId == "cancel") return interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji("PUNISH.MUTE.RED")
             .setTitle("Mute")
             .setDescription("Mute cancelled")
@@ -111,7 +111,7 @@
         }
     } else {
         await interaction.reply({embeds: [
-            new generateEmojiEmbed()
+            new EmojiEmbed()
                 .setEmoji("PUNISH.MUTE.GREEN")
                 .setTitle("Mute")
                 .setDescription("Loading...")
@@ -123,7 +123,7 @@
         .setEmoji("PUNISH.MUTE.RED")
         .setTitle("Mute")
         .setDescription(keyValueList({
-            "user": `<@!${user.id}> (${user.user.username})`,
+            "user": renderUser(user),
             "time": `${humanizeDuration(muteTime * 1000, {round: true})}`,
             "reason": `\n> ${reason ? reason : "*No reason provided*"}`
         })
@@ -135,11 +135,11 @@
     if (confirmation.success) {
         let dmd = false
         let dm;
-        let config = await client.database.read(interaction.guild.id);
+        let config = await client.database.guilds.read(interaction.guild.id);
         try {
             if (interaction.options.getString("notify") != "no") {
                 dm = await (interaction.options.getMember("user") as GuildMember).send({
-                    embeds: [new generateEmojiEmbed()
+                    embeds: [new EmojiEmbed()
                         .setEmoji("PUNISH.MUTE.RED")
                         .setTitle("Muted")
                         .setDescription(`You have been muted in ${interaction.guild.name}` +
@@ -156,15 +156,16 @@
                 dmd = true
             }
         } catch {}
+        let member = (interaction.options.getMember("user") as GuildMember)
         try {
             if (config.moderation.mute.timeout) {
-                (interaction.options.getMember("user") as GuildMember).timeout(muteTime * 1000, interaction.options.getString("reason") || "No reason provided")
+                member.timeout(muteTime * 1000, interaction.options.getString("reason") || "No reason provided")
             }
             if (config.moderation.mute.role) {
-                (interaction.options.getMember("user") as GuildMember).roles.add(config.moderation.mute.role)
+                member.roles.add(config.moderation.mute.role)
             }
         } catch {
-            await interaction.editReply({embeds: [new generateEmojiEmbed()
+            await interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji("PUNISH.MUTE.RED")
                 .setTitle(`Mute`)
                 .setDescription("Something went wrong and the user was not mute")
@@ -173,8 +174,9 @@
             if (dmd) await dm.delete()
             return
         }
+        try { await client.database.history.create("mute", interaction.guild.id, member.user, interaction.user, reason) } catch {}
         let failed = (dmd == false && interaction.options.getString("notify") != "no")
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji(`PUNISH.MUTE.${failed ? "YELLOW" : "GREEN"}`)
             .setTitle(`Mute`)
             .setDescription("The member was muted" + (failed ? ", but could not be notified" : ""))
@@ -190,7 +192,7 @@
                 timestamp: new Date().getTime()
             },
             list: {
-                user: entry((interaction.options.getMember("user") as GuildMember).user.id, renderUser((interaction.options.getMember("user") as GuildMember).user)),
+                user: entry(member.user.id, renderUser(member.user)),
                 mutedBy: entry(interaction.member.user.id, renderUser(interaction.member.user)),
                 time: entry(muteTime, `${humanizeDuration(muteTime * 1000, {round: true})}`),
                 reason: (interaction.options.getString("reason") ? `\n> ${interaction.options.getString("reason")}` : "No reason provided")
@@ -199,9 +201,9 @@
                 guild: interaction.guild.id
             }
         }
-        log(data, client);
+        log(data);
     } else {
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji("PUNISH.MUTE.GREEN")
             .setTitle(`Mute`)
             .setDescription("No changes were made")
@@ -221,7 +223,7 @@
     // Check if Nucleus can mute the member
     if (! (mePos > applyPos)) throw "I do not have a role higher than that member"
     // Check if Nucleus has permission to mute
-    if (! me.permissions.has("MODERATE_MEMBERS")) throw "I do not have the `moderate_members` permission";
+    if (! me.permissions.has("MODERATE_MEMBERS")) throw "I do not have the Moderate members permission";
     // Do not allow the user to have admin or be the owner
     if (apply.permissions.has("ADMINISTRATOR") || (interaction.options.getMember("user") as GuildMember).id == interaction.guild.ownerId) throw "You cannot mute an admin or the owner"
     // Do not allow muting Nucleus
@@ -229,7 +231,7 @@
     // Allow the owner to mute anyone
     if (member.id == interaction.guild.ownerId) return true
     // Check if the user has moderate_members permission
-    if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the `moderate_members` permission";
+    if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the Moderate members permission";
     // Check if the user is below on the role list
     if (! (memberPos > applyPos)) throw "You do not have a role higher than that member"
     // Allow mute
diff --git a/src/commands/mod/nick.ts b/src/commands/mod/nick.ts
index c09e197..e154277 100644
--- a/src/commands/mod/nick.ts
+++ b/src/commands/mod/nick.ts
@@ -2,9 +2,10 @@
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
 import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import keyValueList from "../../utils/generateKeyValueList.js";
 import { create, areTicketsEnabled } from "../../automations/createModActionTicket.js";
+import client from "../../utils/client.js"
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder
@@ -16,13 +17,14 @@
         .addChoices([["Yes", "yes"], ["No", "no"]])
     )
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+    const { renderUser } = client.logger
     // TODO:[Modals] Replace this with a modal
     let confirmation = await new confirmationMessage(interaction)
         .setEmoji("PUNISH.NICKNAME.RED")
         .setTitle("Nickname")
         .setDescription(keyValueList({
-            "user": `<@!${(interaction.options.getMember("user") as GuildMember).id}> (${(interaction.options.getMember("user") as GuildMember).user.username})`,
+            "user": renderUser(interaction.options.getUser("user")),
             "new nickname": `${interaction.options.getString("name") ? interaction.options.getString("name") : "*No nickname*"}`
         })
         + `The user **will${interaction.options.getString("notify") == "yes" ? '' : ' not'}** be notified\n\n`
@@ -39,7 +41,7 @@
         try {
             if (interaction.options.getString("notify") == "yes") {
                 dm = await (interaction.options.getMember("user") as GuildMember).send({
-                    embeds: [new generateEmojiEmbed()
+                    embeds: [new EmojiEmbed()
                         .setEmoji("PUNISH.NICKNAME.RED")
                         .setTitle("Nickname changed")
                         .setDescription(`Your nickname was ${interaction.options.getString("name") ? "changed" : "cleared"} in ${interaction.guild.name}.` +
@@ -56,6 +58,9 @@
             let before = member.nickname
             let nickname = interaction.options.getString("name")
             member.setNickname(nickname ?? null, "Nucleus Nickname command")
+            try { await client.database.history.create(
+                "nickname", interaction.guild.id, member.user, interaction.user,
+                null, before, nickname) } catch {}
             // @ts-ignore
             const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger
             let data = {
@@ -78,9 +83,9 @@
                     guild: interaction.guild.id
                 }
             }
-            log(data, client);
+            log(data);
         } catch {
-            await interaction.editReply({embeds: [new generateEmojiEmbed()
+            await interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji("PUNISH.NICKNAME.RED")
                 .setTitle(`Nickname`)
                 .setDescription("Something went wrong and the users nickname could not be changed.")
@@ -90,14 +95,14 @@
             return
         }
         let failed = (dmd == false && interaction.options.getString("notify") == "yes")
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji(`PUNISH.NICKNAME.${failed ? "YELLOW" : "GREEN"}`)
             .setTitle(`Nickname`)
             .setDescription("The members nickname was changed" + (failed ? ", but was not notified" : "") + (confirmation.response ? ` and an appeal ticket was opened in <#${confirmation.response}>` : ``))
             .setStatus(failed ? "Warning" : "Success")
         ], components: []})
     } else {
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji("PUNISH.NICKNAME.GREEN")
             .setTitle(`Nickname`)
             .setDescription("No changes were made")
@@ -117,11 +122,11 @@
     // Check if Nucleus can change the nickname
     if (! (mePos > applyPos)) throw "I do not have a role higher than that member"
     // Check if Nucleus has permission to change the nickname
-    if (! me.permissions.has("MANAGE_NICKNAMES")) throw "I do not have the `manage_nicknames` permission";
+    if (! me.permissions.has("MANAGE_NICKNAMES")) throw "I do not have the Manage nicknames permission";
     // Allow the owner to change anyone's nickname
     if (member.id == interaction.guild.ownerId) return true
     // Check if the user has manage_nicknames permission
-    if (! member.permissions.has("MANAGE_NICKNAMES")) throw "You do not have the `manage_nicknames` permission";
+    if (! member.permissions.has("MANAGE_NICKNAMES")) throw "You do not have the Manage nicknames permission";
     // Allow changing your own nickname
     if (member == apply) return true
     // Check if the user is below on the role list
diff --git a/src/commands/mod/purge.ts b/src/commands/mod/purge.ts
index c6a44b3..9aab260 100644
--- a/src/commands/mod/purge.ts
+++ b/src/commands/mod/purge.ts
@@ -2,9 +2,10 @@
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
 import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import keyValueList from "../../utils/generateKeyValueList.js";
 import getEmojiByName from "../../utils/getEmojiByName.js";
+import client from "../../utils/client.js";
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder
@@ -25,7 +26,7 @@
     if (!(["GUILD_TEXT", "GUILD_NEWS", "GUILD_NEWS_THREAD", "GUILD_PUBLIC_THREAD", "GUILD_PRIVATE_THREAD"].includes(channel.type.toString()))) {
         return await interaction.reply({
             embeds: [
-                new generateEmojiEmbed()
+                new EmojiEmbed()
                     .setEmoji("CHANNEL.PURGE.RED")
                     .setTitle("Purge")
                     .setDescription("You cannot purge this channel")
@@ -39,7 +40,7 @@
     if ( !interaction.options.getInteger("amount") ) {
         await interaction.reply({
             embeds: [
-                new generateEmojiEmbed()
+                new EmojiEmbed()
                     .setEmoji("CHANNEL.PURGE.RED")
                     .setTitle("Purge")
                     .setDescription("Select how many messages to delete")
@@ -53,7 +54,7 @@
         while (true) {
             let m = await interaction.editReply({
                 embeds: [
-                    new generateEmojiEmbed()
+                    new EmojiEmbed()
                         .setEmoji("CHANNEL.PURGE.RED")
                         .setTitle("Purge")
                         .setDescription("Select how many messages to delete. You can continue clicking until all messages are cleared.")
@@ -118,7 +119,7 @@
         }
         if (deleted.length === 0) return await interaction.editReply({
             embeds: [
-                new generateEmojiEmbed()
+                new EmojiEmbed()
                     .setEmoji("CHANNEL.PURGE.RED")
                     .setTitle("Purge")
                     .setDescription("No messages were deleted")
@@ -126,10 +127,13 @@
             ],
             components: []
         })
+        if (user) {
+            try { await client.database.history.create("purge", interaction.guild.id, user, interaction.options.getString("reason"), null, null, deleted.length) } catch {}
+        }
         let attachmentObject;
         try {
             // @ts-ignore
-            const { log, NucleusColors, entry, renderUser, renderChannel } = interaction.user.client.logger
+            const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger
             let data = {
                 meta: {
                     type: 'channelPurge',
@@ -149,7 +153,7 @@
                     guild: interaction.guild.id
                 }
             }
-            log(data, interaction.user.client);
+            log(data);
             let out = ""
             deleted.reverse().forEach(message => {
                 out += `${message.author.username}#${message.author.discriminator} (${message.author.id}) [${new Date(message.createdTimestamp).toISOString()}]\n`
@@ -163,7 +167,7 @@
                 description: "Purge log"
             }
         } catch {}
-        let m = await interaction.editReply({embeds: [new generateEmojiEmbed()
+        let m = await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji(`CHANNEL.PURGE.GREEN`)
             .setTitle(`Purge`)
             .setDescription("Messages cleared")
@@ -180,14 +184,14 @@
             component = await (m as Discord.Message).awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 300000});
         } catch {}
         if (component && component.customId === "download") {
-            interaction.editReply({embeds: [new generateEmojiEmbed()
+            interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji("CHANNEL.PURGE.GREEN")
                 .setTitle(`Purge`)
                 .setDescription("Uploaded")
                 .setStatus("Success")
             ], components: [], files: [attachmentObject]})
         } else {
-            interaction.editReply({embeds: [new generateEmojiEmbed()
+            interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji("CHANNEL.PURGE.GREEN")
                 .setTitle(`Purge`)
                 .setDescription("Messages cleared")
@@ -218,17 +222,20 @@
                     messages = await (channel as TextChannel).bulkDelete(toDelete, true);
                 }
             } catch(e) {
-                await interaction.editReply({embeds: [new generateEmojiEmbed()
+                await interaction.editReply({embeds: [new EmojiEmbed()
                     .setEmoji("CHANNEL.PURGE.RED")
                     .setTitle(`Purge`)
                     .setDescription("Something went wrong and no messages were deleted")
                     .setStatus("Danger")
                 ], components: []})
             }
+            if (user) {
+                try { await client.database.history.create("purge", interaction.guild.id, user, interaction.options.getString("reason"), null, null, messages.size) } catch {}
+            }
             let attachmentObject;
             try {
                 // @ts-ignore
-                const { log, NucleusColors, entry, renderUser, renderChannel } = interaction.user.client.logger
+                const { log, NucleusColors, entry, renderUser, renderChannel } = client.logger
                 let data = {
                     meta: {
                         type: 'channelPurge',
@@ -248,7 +255,7 @@
                         guild: interaction.guild.id
                     }
                 }
-                log(data, interaction.user.client);
+                log(data);
                 let out = ""
                 messages.reverse().forEach(message => {
                     out += `${message.author.username}#${message.author.discriminator} (${message.author.id}) [${new Date(message.createdTimestamp).toISOString()}]\n`
@@ -262,7 +269,7 @@
                     description: `Purge log`
                 }
             } catch {}
-            let m = await interaction.editReply({embeds: [new generateEmojiEmbed()
+            let m = await interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji(`CHANNEL.PURGE.GREEN`)
                 .setTitle(`Purge`)
                 .setDescription("Messages cleared")
@@ -279,14 +286,14 @@
                 component = await (m as Discord.Message).awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 300000});
             } catch {}
             if (component && component.customId === "download") {
-                interaction.editReply({embeds: [new generateEmojiEmbed()
+                interaction.editReply({embeds: [new EmojiEmbed()
                     .setEmoji("CHANNEL.PURGE.GREEN")
                     .setTitle(`Purge`)
                     .setDescription("Transcript uploaded above")
                     .setStatus("Success")
                 ], components: [], files: [attachmentObject]})
             } else {
-                interaction.editReply({embeds: [new generateEmojiEmbed()
+                interaction.editReply({embeds: [new EmojiEmbed()
                     .setEmoji("CHANNEL.PURGE.GREEN")
                     .setTitle(`Purge`)
                     .setDescription("Messages cleared")
@@ -294,7 +301,7 @@
                 ], components: []})
             }
         } else {
-            await interaction.editReply({embeds: [new generateEmojiEmbed()
+            await interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji("CHANNEL.PURGE.GREEN")
                 .setTitle(`Purge`)
                 .setDescription("No changes were made")
@@ -310,9 +317,9 @@
     // Allow the owner to purge
     if (member.id == interaction.guild.ownerId) return true
     // Check if the user has manage_messages permission
-    if (! member.permissions.has("MANAGE_MESSAGES")) throw "You do not have the `manage_messages` permission";
+    if (! member.permissions.has("MANAGE_MESSAGES")) throw "You do not have the Manage messages permission";
     // Check if nucleus has the manage_messages permission
-    if (! me.permissions.has("MANAGE_MESSAGES")) throw "I do not have the `manage_messages` permission";
+    if (! me.permissions.has("MANAGE_MESSAGES")) throw "I do not have the Manage messages permission";
     // Allow warn
     return true
 }
diff --git a/src/commands/mod/slowmode.ts b/src/commands/mod/slowmode.ts
index 2498746..d9a8421 100644
--- a/src/commands/mod/slowmode.ts
+++ b/src/commands/mod/slowmode.ts
@@ -4,7 +4,8 @@
 import { WrappedCheck } from "jshaiku";
 import keyValueList from "../../utils/generateKeyValueList.js";
 import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
+
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder
@@ -18,11 +19,11 @@
         ["1 hour", "3600"], ["2 hours", "7200"], ["6 hours", "21600"]
     ]))
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
     let time = parseInt(interaction.options.getString("time") ?? "0");
     if (time === 0 && (interaction.channel as TextChannel).rateLimitPerUser === 0) { time = 10 }
     let confirmation = await new confirmationMessage(interaction)
-        .setEmoji("CHANNEL.SLOWMODE.RED")
+        .setEmoji("CHANNEL.SLOWMODE.OFF")
         .setTitle("Slowmode")
         .setDescription(keyValueList({
             "time": time ? humanizeDuration(time * 1000, { round: true }) : "No delay",
@@ -34,22 +35,22 @@
         try {
             (interaction.channel as TextChannel).setRateLimitPerUser(time)
         } catch (e) {
-            await interaction.editReply({embeds: [new generateEmojiEmbed()
-                .setEmoji("CHANNEL.SLOWMODE.RED")
+            await interaction.editReply({embeds: [new EmojiEmbed()
+                .setEmoji("CHANNEL.SLOWMODE.OFF")
                 .setTitle(`Slowmode`)
                 .setDescription("Something went wrong while setting the slowmode")
                 .setStatus("Danger")
             ], components: []})
         }
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
-            .setEmoji(`CHANNEL.SLOWMODE.GREEN`)
+        await interaction.editReply({embeds: [new EmojiEmbed()
+            .setEmoji(`CHANNEL.SLOWMODE.ON`)
             .setTitle(`Slowmode`)
             .setDescription("The channel slowmode was set successfully")
             .setStatus("Success")
         ], components: []})
     } else {
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
-            .setEmoji("CHANNEL.SLOWMODE.GREEN")
+        await interaction.editReply({embeds: [new EmojiEmbed()
+            .setEmoji("CHANNEL.SLOWMODE.ON")
             .setTitle(`Slowmode`)
             .setDescription("No changes were made")
             .setStatus("Success")
@@ -60,9 +61,9 @@
 const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
     let member = (interaction.member as GuildMember)
     // Check if Nucleus can set the slowmode
-    if (! interaction.guild.me.permissions.has("MANAGE_CHANNELS")) throw "I do not have the `manage_channels` permission";
+    if (! interaction.guild.me.permissions.has("MANAGE_CHANNELS")) throw "I do not have the Manage channels permission";
     // Check if the user has manage_channel permission
-    if (! member.permissions.has("MANAGE_CHANNELS")) throw "You do not have the `manage_channels` permission";
+    if (! member.permissions.has("MANAGE_CHANNELS")) throw "You do not have the Manage channels permission";
     // Allow slowmode
     return true
 }
diff --git a/src/commands/mod/softban.ts b/src/commands/mod/softban.ts
index 5a01287..ea4a447 100644
--- a/src/commands/mod/softban.ts
+++ b/src/commands/mod/softban.ts
@@ -2,7 +2,7 @@
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
 import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import keyValueList from "../../utils/generateKeyValueList.js";
 import client from "../../utils/client.js";
 import addPlural from "../../utils/plurals.js";
@@ -18,13 +18,14 @@
     )
     .addIntegerOption(option => option.setName("delete").setDescription("The days of messages to delete | Default 0").setMinValue(0).setMaxValue(7).setRequired(false))
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+    const { renderUser } = client.logger
     // TODO:[Modals] Replace this with a modal
     let confirmation = await new confirmationMessage(interaction)
         .setEmoji("PUNISH.BAN.RED")
         .setTitle("Softban")
         .setDescription(keyValueList({
-            "user": `<@!${(interaction.options.getMember("user") as GuildMember).id}> (${(interaction.options.getMember("user") as GuildMember).user.username})`,
+            "user": renderUser(interaction.options.getUser("user")),
             "reason": `\n> ${interaction.options.getString("reason") ? interaction.options.getString("reason") : "*No reason provided*"}`
         })
         + `The user **will${interaction.options.getString("notify") === "no" ? ' not' : ''}** be notified\n`
@@ -34,11 +35,11 @@
     .send()
     if (confirmation.success) {
         let dmd = false;
-        let config = await client.database.read(interaction.guild.id);
+        let config = await client.database.guilds.read(interaction.guild.id);
         try {
             if (interaction.options.getString("notify") != "no") {
                 await (interaction.options.getMember("user") as GuildMember).send({
-                    embeds: [new generateEmojiEmbed()
+                    embeds: [new EmojiEmbed()
                         .setEmoji("PUNISH.BAN.RED")
                         .setTitle("Softbanned")
                         .setDescription(`You have been softbanned from ${interaction.guild.name}` +
@@ -54,29 +55,31 @@
                 dmd = true
             }
         } catch {}
+        let member = (interaction.options.getMember("user") as GuildMember)
         try {
-            await (interaction.options.getMember("user") as GuildMember).ban({
+            await member.ban({
                 days: Number(interaction.options.getInteger("delete") ?? 0),
                 reason: interaction.options.getString("reason")
             });
-            await interaction.guild.members.unban(interaction.options.getMember("user") as GuildMember, "Softban");
+            await interaction.guild.members.unban(member, "Softban");
         } catch {
-            await interaction.editReply({embeds: [new generateEmojiEmbed()
+            await interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji("PUNISH.BAN.RED")
                 .setTitle(`Softban`)
                 .setDescription("Something went wrong and the user was not softbanned")
                 .setStatus("Danger")
             ], components: []})
         }
+        try { await client.database.history.create("softban", interaction.guild.id, member.user, interaction.options.getString("reason")) } catch {}
         let failed = (dmd == false && interaction.options.getString("notify") != "no")
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji(`PUNISH.BAN.${failed ? "YELLOW" : "GREEN"}`)
             .setTitle(`Softban`)
             .setDescription("The member was softbanned" + (failed ? ", but could not be notified" : ""))
             .setStatus(failed ? "Warning" : "Success")
         ], components: []})
     } else {
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji("PUNISH.BAN.GREEN")
             .setTitle(`Softban`)
             .setDescription("No changes were made")
@@ -96,13 +99,13 @@
     // Check if Nucleus can ban the member
     if (! (mePos > applyPos)) throw "I do not have a role higher than that member"
     // Check if Nucleus has permission to ban
-    if (!me.permissions.has("BAN_MEMBERS")) throw "I do not have the `ban_members` permission";
+    if (!me.permissions.has("BAN_MEMBERS")) throw "I do not have the Ban members permission";
     // Do not allow softbanning Nucleus
     if (member.id == me.id) throw "I cannot softban myself"
     // Allow the owner to ban anyone
     if (member.id == interaction.guild.ownerId) return true
     // Check if the user has ban_members permission
-    if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the `ban_members` permission";
+    if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the Ban members permission";
     // Check if the user is below on the role list
     if (! (memberPos > applyPos)) throw "You do not have a role higher than that member"
     // Allow softban
diff --git a/src/commands/mod/unban.ts b/src/commands/mod/unban.ts
index f7bf74f..7f605d9 100644
--- a/src/commands/mod/unban.ts
+++ b/src/commands/mod/unban.ts
@@ -1,9 +1,10 @@
 import { CommandInteraction, GuildMember, User } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import keyValueList from "../../utils/generateKeyValueList.js";
 import confirmationMessage from "../../utils/confirmationMessage.js";
+import client from "../../utils/client.js";
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder
@@ -11,14 +12,14 @@
     .setDescription("Unbans a user")
     .addStringOption(option => option.setName("user").setDescription("The user to unban (Username or ID)").setRequired(true))
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
     let bans = await interaction.guild.bans.fetch()
     let user = interaction.options.getString("user")
     let resolved = bans.find(ban => ban.user.id == user)
     if (!resolved) resolved = bans.find(ban => ban.user.username.toLowerCase() == user.toLowerCase())
     if (!resolved) resolved = bans.find(ban => ban.user.tag.toLowerCase() == user.toLowerCase())
     if (!resolved) {
-        return interaction.reply({embeds: [new generateEmojiEmbed()
+        return interaction.reply({embeds: [new EmojiEmbed()
             .setTitle("Unban")
             .setDescription(`Could not find any user called \`${user}\``)
             .setEmoji("PUNISH.UNBAN.RED")
@@ -39,8 +40,9 @@
         try {
             await interaction.guild.members.unban(resolved.user as User, "Unban");
             let member = (resolved.user as User)
+            try { await client.database.history.create("unban", interaction.guild.id, member, interaction.user) } catch {}
             // @ts-ignore
-            const { log, NucleusColors, entry, renderUser, renderDelta } = interaction.user.client.logger
+            const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger
             let data = {
                 meta: {
                     type: 'memberUnban',
@@ -61,23 +63,23 @@
                     guild: interaction.guild.id
                 }
             }
-            log(data, member.client);
+            log(data);
         } catch {
-            await interaction.editReply({embeds: [new generateEmojiEmbed()
+            await interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji("PUNISH.UNBAN.RED")
                 .setTitle(`Unban`)
                 .setDescription("Something went wrong and the user was not unbanned")
                 .setStatus("Danger")
             ], components: []})
         }
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji(`PUNISH.UNBAN.GREEN`)
             .setTitle(`Unban`)
             .setDescription("The member was unbanned")
             .setStatus("Success")
         ], components: []})
     } else {
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji("PUNISH.UNBAN.GREEN")
             .setTitle(`Unban`)
             .setDescription("No changes were made")
@@ -90,11 +92,11 @@
     let member = (interaction.member as GuildMember)
     let me = (interaction.guild.me as GuildMember)
     // Check if Nucleus can unban members
-    if (! me.permissions.has("BAN_MEMBERS")) throw "I do not have the `ban_members` permission";
+    if (! me.permissions.has("BAN_MEMBERS")) throw "I do not have the Ban members permission";
     // Allow the owner to unban anyone
     if (member.id == interaction.guild.ownerId) return true
     // Check if the user has ban_members permission
-    if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the `ban_members` permission";
+    if (! member.permissions.has("BAN_MEMBERS")) throw "You do not have the Ban members permission";
     // Allow unban
     return true
 }
diff --git a/src/commands/mod/unmute.ts b/src/commands/mod/unmute.ts
index 2a98c54..5a1b67c 100644
--- a/src/commands/mod/unmute.ts
+++ b/src/commands/mod/unmute.ts
@@ -2,8 +2,9 @@
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
 import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import keyValueList from "../../utils/generateKeyValueList.js";
+import client from "../../utils/client.js";
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder
@@ -15,13 +16,14 @@
         .addChoices([["Yes", "yes"], ["No", "no"]])
     )
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+    const { renderUser } = client.logger
     // TODO:[Modals] Replace this with a modal
     let confirmation =  await new confirmationMessage(interaction)
         .setEmoji("PUNISH.MUTE.RED")
         .setTitle("Unmute")
         .setDescription(keyValueList({
-            "user": `<@!${(interaction.options.getMember("user") as GuildMember).id}> (${(interaction.options.getMember("user") as GuildMember).user.username})`,
+            "user": renderUser(interaction.options.getUser("user")),
             "reason": `\n> ${interaction.options.getString("reason") ? interaction.options.getString("reason") : "*No reason provided*"}`
         })
         + `The user **will${interaction.options.getString("notify") === "yes" ? '' : ' not'}** be notified\n\n`
@@ -34,7 +36,7 @@
         try {
             if (interaction.options.getString("notify") != "no") {
                 dm = await (interaction.options.getMember("user") as GuildMember).send({
-                    embeds: [new generateEmojiEmbed()
+                    embeds: [new EmojiEmbed()
                         .setEmoji("PUNISH.MUTE.GREEN")
                         .setTitle("Unmuted")
                         .setDescription(`You have been unmuted in ${interaction.guild.name}` +
@@ -48,7 +50,7 @@
         try {
             (interaction.options.getMember("user") as GuildMember).timeout(0, interaction.options.getString("reason") || "No reason provided")
         } catch {
-            await interaction.editReply({embeds: [new generateEmojiEmbed()
+            await interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji("PUNISH.MUTE.RED")
                 .setTitle(`Unmute`)
                 .setDescription("Something went wrong and the user was not unmuted")
@@ -57,15 +59,16 @@
             if (dmd) await dm.delete()
             return
         }
+        try { await client.database.history.create("unmute", interaction.guild.id, (interaction.options.getMember("user") as GuildMember).user, interaction.user, interaction.options.getString("reason")) } catch {}
         let failed = (dmd == false && interaction.options.getString("notify") != "no")
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji(`PUNISH.MUTE.${failed ? "YELLOW" : "GREEN"}`)
             .setTitle(`Unmute`)
             .setDescription("The member was unmuted" + (failed ? ", but could not be notified" : ""))
             .setStatus(failed ? "Warning" : "Success")
         ], components: []})
     } else {
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji("PUNISH.MUTE.GREEN")
             .setTitle(`Unmute`)
             .setDescription("No changes were made")
@@ -85,13 +88,13 @@
     // Check if Nucleus can unmute the member
     if (! (mePos > applyPos)) throw "I do not have a role higher than that member"
     // Check if Nucleus has permission to unmute
-    if (! me.permissions.has("MODERATE_MEMBERS")) throw "I do not have the `moderate_members` permission";
+    if (! me.permissions.has("MODERATE_MEMBERS")) throw "I do not have the Moderate members permission";
     // Do not allow the user to have admin or be the owner
     if (apply.permissions.has("ADMINISTRATOR") || apply.id == interaction.guild.ownerId) throw "You cannot unmute an admin or the owner"
     // Allow the owner to unmute anyone
     if (member.id == interaction.guild.ownerId) return true
     // Check if the user has moderate_members permission
-    if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the `moderate_members` permission";
+    if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the Moderate members permission";
     // Check if the user is below on the role list
     if (! (memberPos > applyPos)) throw "You do not have a role higher than that member"
     // Allow unmute
diff --git a/src/commands/mod/viewas.ts b/src/commands/mod/viewas.ts
index 705c04a..b3875a7 100644
--- a/src/commands/mod/viewas.ts
+++ b/src/commands/mod/viewas.ts
@@ -1,8 +1,9 @@
-import Discord, { CategoryChannel, CommandInteraction } from "discord.js";
+import Discord, { CategoryChannel, CommandInteraction, GuildMember, MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import { WrappedCheck } from "jshaiku";
 import getEmojiByName from "../../utils/getEmojiByName.js";
+import pageIndicator from "../../utils/createPageIndicator.js";
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder
@@ -10,8 +11,9 @@
     .setDescription("View the server as a specific member")
     .addUserOption(option => option.setName("member").setDescription("The member to view as").setRequired(true))
 
-const callback = async (interaction: CommandInteraction) => {
-    let channels = []
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+    let channels = [];
+    let m;
     interaction.guild.channels.cache.forEach(channel => {
         if (!channel.parent && channel.type !== "GUILD_CATEGORY") channels.push(channel)
     })
@@ -22,39 +24,83 @@
     )
     let autoSortBelow = ["GUILD_VOICE", "GUILD_STAGE_VOICE"]
     channels = channels.map(c => c.sort((a, b) => {
-        if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.name.localeCompare(b.name)
-        if (autoSortBelow.includes(a.type)) return -1
-        if (autoSortBelow.includes(b.type)) return 1
+        if (autoSortBelow.includes(a.type) && autoSortBelow.includes(b.type)) return a.position - b.position
+        if (autoSortBelow.includes(a.type)) return 1
+        if (autoSortBelow.includes(b.type)) return -1
         return a.position - b.position
     }))
+    // Sort all arrays by the position of the first channels parent position
+    channels = channels.sort((a, b) => {
+        if (!a[0].parent) return -1
+        if (!b[0].parent) return 1
+        return a[0].parent.position - b[0].parent.position
+    })
     let member = interaction.options.getMember("member") as Discord.GuildMember
-    await interaction.reply({embeds: [new generateEmojiEmbed()
+    m = await interaction.reply({embeds: [new EmojiEmbed()
         .setEmoji("MEMBER.JOIN")
         .setTitle("Viewing as " + member.displayName)
         .setStatus("Success")
-    ], ephemeral: true})
+    ], ephemeral: true, fetchReply: true})
     let page = 0;
     while (true) {
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        m = await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji("MEMBER.JOIN")
             .setTitle("Viewing as " + member.displayName)
             .setStatus("Success")
             .setDescription(
-                `${channels[page][0].parent ? channels[page][0].parent.name  : "Uncategorised"}` +
-                "Visible:\n" +
+                `**${channels[page][0].parent ? channels[page][0].parent.name  : "Uncategorised"}**` + "\n" +
                 channels[page].map(c => {
-                    console.log(c)
-                    return (channels[page] as Discord.GuildChannel).permissionsFor(member).has("VIEW_CHANNEL") ?
-                        `${getEmojiByName("ICONS.CHANNEL." + c.type)} ${c.name}\n` : ""
-                }).join("")
+                    let channelType = c.type
+                    if (interaction.guild.rulesChannelId == c.id) channelType = "RULES"
+                    else if ("nsfw" in c && c.nsfw) channelType += "_NSFW"
+                    return c.permissionsFor(member).has("VIEW_CHANNEL") ? (
+                        `${getEmojiByName("ICONS.CHANNEL." + channelType)} ${c.name}\n` + (() => {
+                            if ("threads" in c && c.threads.cache.size > 0) {
+                                return c.threads.cache.map(t => ` ${
+                                    getEmojiByName("ICONS.CHANNEL.THREAD_PIPE") + " " +
+                                    getEmojiByName("ICONS.CHANNEL.THREAD_CHANNEL")} ${t.name}`).join("\n") + "\n"
+                            }return ""
+                        })()) : ""
+                }).join("") + "\n" + pageIndicator(channels.length, page)
             )
+        ], components: [
+            new MessageActionRow().addComponents([new MessageSelectMenu().setOptions(channels.map((c, index) => ({
+                label: c[0].parent ? c[0].parent.name : "Uncategorised",
+                value: index.toString(),
+                default: page === index
+            }))).setCustomId("select").setMaxValues(1).setMinValues(1).setPlaceholder("Select a category")]),
+            new MessageActionRow().addComponents([
+                new MessageButton()
+                    .setLabel(page === 0 ? "" : (channels[page - 1][0].parent ? channels[page - 1][0].parent.name : "Uncategorised"))
+                    .setDisabled(page === 0)
+                    .setEmoji(getEmojiByName("CONTROL.LEFT", "id"))
+                    .setStyle("PRIMARY")
+                    .setCustomId("previous"),
+                new MessageButton()
+                    .setLabel(page === channels.length - 1 ? "" : (channels[page + 1][0].parent ? channels[page + 1][0].parent.name : "Uncategorised"))
+                    .setDisabled(page === channels.length - 1)
+                    .setEmoji(getEmojiByName("CONTROL.RIGHT", "id"))
+                    .setStyle("PRIMARY")
+                    .setCustomId("next")
+            ])
         ]})
-        break
+        let i;
+        try {
+            i = await m.awaitMessageComponent({ time: 300000 });
+        } catch (e) { return }
+        i.deferUpdate()
+        if (i.customId === "next") { page++; }
+        else if (i.customId === "previous") { page--; }
+        else if (i.customId === "select") { page = parseInt(i.values[0]); }
     }
 }
 
+
 const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
-    return true;
+    return true // FIXME FOR RELEASE
+    let member = (interaction.member as GuildMember)
+    if (! member.permissions.has("MANAGE_ROLES")) throw "You do not have the Manage roles permission";
+    return true
 }
 
 export { command, callback, check };
\ No newline at end of file
diff --git a/src/commands/mod/warn.ts b/src/commands/mod/warn.ts
index b8fb98f..370f347 100644
--- a/src/commands/mod/warn.ts
+++ b/src/commands/mod/warn.ts
@@ -2,9 +2,10 @@
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
 import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import keyValueList from "../../utils/generateKeyValueList.js";
 import { create, areTicketsEnabled } from "../../automations/createModActionTicket.js";
+import client from "../../utils/client.js"
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder
@@ -23,7 +24,7 @@
         .setEmoji("PUNISH.WARN.RED")
         .setTitle("Warn")
         .setDescription(keyValueList({
-            "user": `<@!${(interaction.options.getMember("user") as GuildMember).id}> (${(interaction.options.getMember("user") as GuildMember).user.username})`,
+            "user": renderUser(interaction.options.getUser("user")),
             "reason": `\n> ${interaction.options.getString("reason") ? interaction.options.getString("reason") : "*No reason provided*"}`
         })
         + `The user **will${interaction.options.getString("notify") === "no" ? ' not' : ''}** be notified\n\n`
@@ -39,7 +40,7 @@
         try {
             if (interaction.options.getString("notify") != "no") {
                 await (interaction.options.getMember("user") as GuildMember).send({
-                    embeds: [new generateEmojiEmbed()
+                    embeds: [new EmojiEmbed()
                         .setEmoji("PUNISH.WARN.RED")
                         .setTitle("Warned")
                         .setDescription(`You have been warned in ${interaction.guild.name}` +
@@ -51,7 +52,7 @@
                 dmd = true
             }
         } catch {
-            await interaction.editReply({embeds: [new generateEmojiEmbed()
+            await interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji("PUNISH.WARN.RED")
                 .setTitle(`Warn`)
                 .setDescription("Something went wrong and the user was not warned")
@@ -76,10 +77,15 @@
                 guild: interaction.guild.id
             }
         }
-        log(data, client);
+        try { await client.database.history.create(
+            "warn", interaction.guild.id,
+            (interaction.options.getMember("user") as GuildMember).user,
+            interaction.user, interaction.options.getString("reason")
+        )} catch {}
+        log(data);
         let failed = (dmd == false && interaction.options.getString("notify") != "no")
         if (!failed) {
-            await interaction.editReply({embeds: [new generateEmojiEmbed()
+            await interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji(`PUNISH.WARN.GREEN`)
                 .setTitle(`Warn`)
                 .setDescription("The user was warned" + (confirmation.response ? ` and an appeal ticket was opened in <#${confirmation.response}>` : ``))
@@ -87,7 +93,7 @@
             ], components: []})
         } else {
             let m = await interaction.editReply({
-                embeds: [new generateEmojiEmbed()
+                embeds: [new EmojiEmbed()
                     .setEmoji(`PUNISH.WARN.RED`)
                     .setTitle(`Warn`)
                     .setDescription("The user's DMs are not open\n\nWhat would you like to do?")
@@ -110,7 +116,7 @@
             try {
                 component = await (m as Discord.Message).awaitMessageComponent({filter: (m) => m.user.id === interaction.user.id, time: 300000});
             } catch (e) {
-                return await interaction.editReply({embeds: [new generateEmojiEmbed()
+                return await interaction.editReply({embeds: [new EmojiEmbed()
                     .setEmoji(`PUNISH.WARN.GREEN`)
                     .setTitle(`Warn`)
                     .setDescription("No changes were made")
@@ -119,7 +125,7 @@
             }
             if ( component.customId == "here" ) {
                 await interaction.channel.send({
-                    embeds: [new generateEmojiEmbed()
+                    embeds: [new EmojiEmbed()
                         .setEmoji(`PUNISH.WARN.RED`)
                         .setTitle(`Warn`)
                         .setDescription(`You have been warned` +
@@ -129,14 +135,14 @@
                     content: `<@!${(interaction.options.getMember("user") as GuildMember).id}>`,
                     allowedMentions: {users: [(interaction.options.getMember("user") as GuildMember).id]}
                 })
-                return await interaction.editReply({embeds: [new generateEmojiEmbed()
+                return await interaction.editReply({embeds: [new EmojiEmbed()
                     .setEmoji(`PUNISH.WARN.GREEN`)
                     .setTitle(`Warn`)
                     .setDescription("The user was warned" + (confirmation.response ? ` and an appeal ticket was opened in <#${confirmation.response}>` : ``))
                     .setStatus("Success")
                 ], components: []})
             } else {
-                await interaction.editReply({embeds: [new generateEmojiEmbed()
+                await interaction.editReply({embeds: [new EmojiEmbed()
                     .setEmoji(`PUNISH.WARN.GREEN`)
                     .setTitle(`Warn`)
                     .setDescription("The warn was logged")
@@ -145,7 +151,7 @@
             }
         }
     } else {
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji("PUNISH.WARN.GREEN")
             .setTitle(`Warn`)
             .setDescription("No changes were made")
@@ -167,7 +173,7 @@
     // Allow the owner to warn anyone
     if (member.id == interaction.guild.ownerId) return true
     // Check if the user has moderate_members permission
-    if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the `moderate_members` permission";
+    if (! member.permissions.has("MODERATE_MEMBERS")) throw "You do not have the Moderate members permission";
     // Check if the user is below on the role list
     if (! (memberPos > applyPos)) throw "You do not have a role higher than that member"
     // Allow warn
diff --git a/src/commands/nucleus/guide.ts b/src/commands/nucleus/guide.ts
index 814d2f5..eb94de4 100644
--- a/src/commands/nucleus/guide.ts
+++ b/src/commands/nucleus/guide.ts
@@ -2,7 +2,7 @@
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
 import getEmojiByName from "../../utils/getEmojiByName.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import guide from "../../automations/guide.js";
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
diff --git a/src/commands/nucleus/invite.ts b/src/commands/nucleus/invite.ts
index 8b25820..7f7d4b8 100644
--- a/src/commands/nucleus/invite.ts
+++ b/src/commands/nucleus/invite.ts
@@ -1,7 +1,7 @@
 import { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import client from "../../utils/client.js"
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
@@ -10,7 +10,7 @@
     .setDescription("Invites Nucleus to your server")
 
 const callback = (interaction: CommandInteraction) => {
-    interaction.reply({embeds: [new generateEmojiEmbed()
+    interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Invite")
         .setDescription("You can invite Nucleus to your server by clicking the button below")
         .setEmoji("NUCLEUS.LOGO")
diff --git a/src/commands/nucleus/ping.ts b/src/commands/nucleus/ping.ts
index 58413c6..f10dcae 100644
--- a/src/commands/nucleus/ping.ts
+++ b/src/commands/nucleus/ping.ts
@@ -1,6 +1,6 @@
 import { CommandInteraction } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import { WrappedCheck } from "jshaiku";
 import client from "../../utils/client.js"
 
@@ -9,18 +9,18 @@
     .setName("ping")
     .setDescription("Gets the bot's ping time")
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
     // WEBSOCKET | Nucleus -> Discord
     // EDITING   | Nucleus -> discord -> nucleus | edit time / 2
     let initial = new Date().getTime();
-    await interaction.reply({embeds: [new generateEmojiEmbed()
+    await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Ping")
         .setDescription(`Checking ping times...`)
         .setEmoji("NUCLEUS.LOADING")
         .setStatus("Danger")
     ], ephemeral: true});
     let ping = new Date().getTime() - initial;
-    interaction.editReply({embeds: [new generateEmojiEmbed()
+    interaction.editReply({embeds: [new EmojiEmbed()
         .setTitle("Ping")
         .setDescription(
             `**Ping:** \`${ping}ms\`\n` +
diff --git a/src/commands/nucleus/stats.ts b/src/commands/nucleus/stats.ts
index 1a0602e..cb10e7a 100644
--- a/src/commands/nucleus/stats.ts
+++ b/src/commands/nucleus/stats.ts
@@ -1,7 +1,7 @@
 import { CommandInteraction } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import client from "../../utils/client.js"
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
@@ -11,7 +11,7 @@
 
 const callback = (interaction: CommandInteraction) => {
     interaction.reply({
-        embeds: [new generateEmojiEmbed()
+        embeds: [new EmojiEmbed()
             .setTitle("Stats")
             .setDescription(
                 `**Servers:** ${client.guilds.cache.size}\n` +
diff --git a/src/commands/nucleus/suggest.ts b/src/commands/nucleus/suggest.ts
index c07d9b8..4e3a1c8 100644
--- a/src/commands/nucleus/suggest.ts
+++ b/src/commands/nucleus/suggest.ts
@@ -2,7 +2,7 @@
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
 import confirmationMessage from "../../utils/confirmationMessage.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import client from "../../utils/client.js"
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
@@ -11,7 +11,7 @@
     .setDescription("Sends a suggestion to the developers")
     .addStringOption(option => option.setName("suggestion").setDescription("The suggestion to send").setRequired(true))
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
     // @ts-ignore
     const { renderUser } = client.logger
     let suggestion = interaction.options.getString("suggestion");
@@ -26,21 +26,21 @@
     if (confirmation.success) {
         await (client.channels.cache.get('955161206459600976') as Discord.TextChannel).send({
             embeds: [
-                new generateEmojiEmbed()
+                new EmojiEmbed()
                     .setTitle(`Suggestion`)
                     .setDescription(`**From:** ${renderUser(interaction.member.user)}\n**Suggestion:**\n> ${suggestion}`)
                     .setStatus("Danger")
                     .setEmoji("NUCLEUS.LOGO")
             ]
         })
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji("ICONS.ADD")
             .setTitle(`Suggest`)
             .setDescription("Your suggestion was sent successfully")
             .setStatus("Success")
         ], components: []})
     } else {
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji("ICONS.OPP.ADD")
             .setTitle(`Suggest`)
             .setDescription("No changes were made")
diff --git a/src/commands/privacy.ts b/src/commands/privacy.ts
index 3174421..cc6c554 100644
--- a/src/commands/privacy.ts
+++ b/src/commands/privacy.ts
@@ -8,7 +8,7 @@
     .setDescription("we changed the fucking charger again!")
     .addStringOption(option => option.setName("link").setDescription("fuck you").setRequired(false))
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
     console.log(await testLink(interaction.options.getString("link")))
 }
 
diff --git a/src/commands/role/all.ts b/src/commands/role/all.ts
index 44e77fd..d24110b 100644
--- a/src/commands/role/all.ts
+++ b/src/commands/role/all.ts
@@ -1,17 +1,161 @@
-import { CommandInteraction } from "discord.js";
+import Discord, { CommandInteraction, GuildMember, MessageActionRow, MessageButton, MessageSelectMenu } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import getEmojiByName from "../../utils/getEmojiByName.js";
+import addPlural from "../../utils/plurals.js";
+import client from "../../utils/client.js";
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder
     .setName("all")
     .setDescription("Gives or removes a role from everyone")
 
-const callback = (interaction: CommandInteraction) => {
-    interaction.reply("This command is not yet finished [role/all]");
+class Filter {
+    name: string;
+    data: object;
+    checkFunction: (member) => boolean;
+    inverted: boolean = false;
+    constructor(name: (data) => string | string, data: object, check: (member) => boolean) {
+        if (typeof name === "function") { this.name = name(data);
+        } else { this.name = name; }
+        this.data = data;
+        this.checkFunction = check;
+    }
+    flip() { this.inverted = true; return this; }
+    check(member) {
+        if (this.inverted) return !this.checkFunction(member)
+        else return this.checkFunction(member)
+    }
 }
 
-const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
+const filterList = {
+    member: {
+        render: "Member",
+        has: {
+            render: "has",
+            role: (role) => ( new Filter((data) => `Member has role <@&${data.role}>`, {role: role, type: Discord.Role, render: "role"}, (member) => { return member.roles.cache.has(role)}))
+        },
+        joined: {
+            render: "joined",
+            before: (date) => ( new Filter((data) => `Joined server before <t:${Math.round(date.getTime() / 1000)}:F>`, {date: date, type: Date, render: "before"}, (member) => {
+                return member.joinedTimestamp < date.getTime()
+            })),
+            after: (date) => ( new Filter((data) => `Joined server after <t:${Math.round(date.getTime() / 1000)}:F>`, {date: date, type: Date, render: "after"}, (member) => {
+                return member.joinedTimestamp > date.getTime()
+            }).flip())
+        },
+        nickname: {
+            render: "Nickname",
+            set: () => ( new Filter((data) => `Member has a nickname set"`, {render: "set"}, (member) => { return member.nickname !== null})),
+            include: (name) => ( new Filter((data) => `Nickname includes "${name}"`, {nickname: name, type: String, render: "includes"}, (member) => {
+                return member.displayName.includes(name)})),
+            startsWith: (name) => ( new Filter((data) => `Nickname starts with "${name}"`, {nickname: name, type: String, render: "starts with"}, (member) => {
+                return member.displayName.startsWith(name)})),
+            endsWith: (name) => ( new Filter((data) => `Nickname ends with "${name}"`, {nickname: name, type: String, render: "ends with"}, (member) => {
+                return member.displayName.endsWith(name)}))
+        }
+    },
+    account: {
+        render: "Account",
+        created: {
+            render: "created",
+            before: (date) => ( new Filter((data) => `Account created before <t:${Math.round(date.getTime() / 1000)}:D>`, {date: date, type: Date, render: "before"}, (member) => {
+                return member.user.createdTimestamp < date.getTime()
+            })),
+            after: (date) => ( new Filter((data) => `Account created after <t:${Math.round(date.getTime() / 1000)}:D>`, {date: date, type: Date, render: "after"}, (member) => {
+                return member.user.createdTimestamp < date.getTime()
+            }).flip())
+        },
+        is: {
+            render: "is",
+            human: () => ( new Filter((data) => `Member is a human`, {human: true, render: "human"}, (member) => { return !member.bot })),
+        },
+        username: {
+            render: "Username",
+            include: (name) => ( new Filter((data) => `Nickname includes "${name}"`, {nickname: name, type: String, render: "includes"}, (member) => {
+                return member.user.name.includes(name)})),
+            startsWith: (name) => ( new Filter((data) => `Nickname starts with "${name}"`, {nickname: name, type: String, render: "starts with"}, (member) => {
+                return member.user.name.startsWith(name)})),
+            endsWith: (name) => ( new Filter((data) => `Nickname ends with "${name}"`, {nickname: name, type: String, render: "ends with"}, (member) => {
+                return member.user.name.endsWith(name)}))
+        }
+    }
+}
+
+const callback = async (interaction: CommandInteraction) => {
+    await interaction.reply({embeds: [new EmojiEmbed()
+        .setTitle("Role all")
+        .setDescription("Loading...")
+        .setStatus("Danger")
+        .setEmoji("NUCLEUS.LOADING")
+    ], ephemeral: true, fetchReply: true})
+    let filters: Filter[] = [
+        filterList.member.has.role("959901346000154674"),
+        filterList.member.nickname.startsWith("Pinea"),
+        filterList.member.joined.before(new Date(2022, 1)).flip()
+    ]
+    let all = true;
+    while (true) {
+        let count = 0;
+        let affected = []
+        let members = interaction.guild.members.cache
+        if (all) {
+            members.forEach(member => {
+                let applies = true;
+                filters.forEach(filter => { if (!filter.check(member)) { applies = false } })
+                if (applies) { affected.push(member) }
+            })
+        } else {
+            members.forEach(member => {
+                let applies = false;
+                filters.forEach(filter => { if (filter.check(member)) { applies = true } })
+                if (applies) { affected.push(member) }
+            })
+        }
+        await interaction.editReply({embeds: [new EmojiEmbed()
+            .setTitle("Role all")
+            .setDescription((all ? "All of the following must be true:" : "Any of the following must be true") + "\n" +
+                filters.map((f) => {
+                    count ++;
+                    return (count == 1 ? getEmojiByName("ICONS.FILTER") : (all ? "**and** " : "**or** ")) +
+                        (f.inverted ? "**not** " : "") + `${f.name}`
+                }).join("\n") + "\n\n" + `This will affect ${addPlural(affected.length.toString(), "member")}`)
+            .setEmoji("GUILD.ROLES.CREATE")
+            .setStatus("Success")
+        ], components: [
+            new MessageActionRow().addComponents([new MessageSelectMenu().setOptions(filters.map((f, index) => ({
+                label: (f.inverted ? "(Not) " : "") + f.name,
+                value: index.toString()
+            }))).setMinValues(1).setMaxValues(filters.length).setCustomId("select").setPlaceholder("Remove a filter")]),
+            new MessageActionRow().addComponents([
+                new MessageButton()
+                    .setLabel("Apply")
+                    .setStyle("PRIMARY")
+                    .setCustomId("apply")
+                    .setEmoji(client.emojis.cache.get(getEmojiByName("CONTROL.TICK", "id")))
+                    .setDisabled(affected.length === 0),
+                new MessageButton()
+                    .setLabel("Add filter")
+                    .setStyle("PRIMARY")
+                    .setCustomId("add")
+                    .setEmoji(client.emojis.cache.get(getEmojiByName("ICONS.FILTER", "id")))
+                    .setDisabled(filters.length >= 25)
+            ])
+        ]})
+        break
+    }
+}
+
+const check = async (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
+    let member = (interaction.member as GuildMember)
+    let me = (interaction.guild.me as GuildMember)
+    if (!me.permissions.has("MANAGE_ROLES")) throw "I do not have the Manage roles permission";
+    // Allow the owner to role anyone
+    if (member.id == interaction.guild.ownerId) return true
+    // Check if the user has manage_roles permission
+    if (! member.permissions.has("MANAGE_ROLES")) throw "You do not have the Manage roles permission";
+    // Allow role
     return true;
 }
 
diff --git a/src/commands/role/user.ts b/src/commands/role/user.ts
index b45e1d1..bb79098 100644
--- a/src/commands/role/user.ts
+++ b/src/commands/role/user.ts
@@ -1,17 +1,84 @@
-import { CommandInteraction } from "discord.js";
+import { CommandInteraction, GuildMember, Role } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
+import client from "../../utils/client.js";
+import confirmationMessage from "../../utils/confirmationMessage.js";
+import keyValueList from "../../utils/generateKeyValueList.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder
     .setName("user")
     .setDescription("Gives or removes a role from someone")
+    .addUserOption(option => option.setName("user").setDescription("The member to give or remove the role from").setRequired(true))
+    .addRoleOption(option => option.setName("role").setDescription("The role to give or remove").setRequired(true))
+    .addStringOption(option => option.setName("action").setDescription("The action to perform").setRequired(true).addChoices([
+        ["Add", "give"],
+        ["Remove", "remove"]
+    ]))
 
-const callback = (interaction: CommandInteraction) => {
-    interaction.reply("This command is not yet finished [role/user]");
+
+const callback = async (interaction: CommandInteraction): Promise<any>  => {
+    const { renderUser, renderRole } = client.logger
+    let action = interaction.options.getString("action");
+    // TODO:[Modals] Replace this with a modal
+    let confirmation = await new confirmationMessage(interaction)
+        .setEmoji("GUILD.ROLES.DELETE")
+        .setTitle("Role")
+        .setDescription(keyValueList({
+            "user": renderUser(interaction.options.getUser("user")),
+            "role": renderRole(interaction.options.getRole("role"))
+        })
+        + `\nAre you sure you want to ${action == "give" ? "give the role to" : "remove the role from"} ${interaction.options.getUser("user")}?`)
+        .setColor("Danger")
+    .send()
+    if (confirmation.success) {
+        try {
+            let member = interaction.options.getMember("user") as GuildMember
+            let role = interaction.options.getRole("role") as Role
+            if (interaction.options.getString("action") == "give") {
+                member.roles.add(role)
+            } else {
+                member.roles.remove(role)
+            }
+        } catch (e) {
+            return await interaction.editReply({embeds: [new EmojiEmbed()
+                .setTitle("Role")
+                .setDescription("Something went wrong and the role could not be added")
+                .setStatus("Danger")
+                .setEmoji("CONTROL.BLOCKCROSS")
+            ], components: []})
+        }
+        return await interaction.editReply({embeds: [new EmojiEmbed()
+            .setTitle("Role")
+            .setDescription(`The role has been ${action == "give" ? "given" : "removed"} successfully`)
+            .setStatus("Success")
+            .setEmoji("GUILD.ROLES.CREATE")
+        ], components: []})
+    } else {
+        await interaction.editReply({embeds: [new EmojiEmbed()
+            .setEmoji("GUILD.ROLES.CREATE")
+            .setTitle("Role")
+            .setDescription(`You have cancelled the role change.`)
+            .setStatus("Danger")
+        ], components: []})
+    }
 }
 
 const check = (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
+    let member = (interaction.member as GuildMember)
+    let me = (interaction.guild.me as GuildMember)
+    let apply = (interaction.options.getMember("user") as GuildMember)
+    if (member == null || me == null || apply == null) throw "That member is not in the server"
+    // Check if Nucleus has permission to role
+    if (!me.permissions.has("MANAGE_ROLES")) throw "I do not have the Manage roles permission";
+    // Allow the owner to role anyone
+    if (member.id == interaction.guild.ownerId) return true
+    // Check if the user has manage_roles permission
+    if (! member.permissions.has("MANAGE_ROLES")) throw "You do not have the Manage roles permission";
+    // Check if the role is above or equal to the user's highest role
+    if (apply.roles.highest.comparePositionTo(member.roles.highest) >= 0) throw "You cannot give a role higher than your highest role";
+    // Allow role
     return true;
 }
 
diff --git a/src/commands/server/about.ts b/src/commands/server/about.ts
index 895d2cc..28e09aa 100644
--- a/src/commands/server/about.ts
+++ b/src/commands/server/about.ts
@@ -1,7 +1,7 @@
 import Discord, { CommandInteraction, Guild, MessageActionRow, MessageButton } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import getEmojiByName from "../../utils/getEmojiByName.js";
 import generateKeyValueList, { toCapitals } from "../../utils/generateKeyValueList.js";
 import client from "../../utils/client.js"
@@ -10,10 +10,10 @@
     .setName("about")
     .setDescription("Shows info about the server")
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
     let guild = interaction.guild as Guild;
     const { renderUser, renderDelta } = client.logger
-    interaction.reply({embeds: [new generateEmojiEmbed()
+    interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Server Info")
         .setStatus("Success")
         .setEmoji("GUILD.GREEN")
diff --git a/src/commands/settings/logs/channel.ts b/src/commands/settings/logs/channel.ts
index 448f26a..19a389b 100644
--- a/src/commands/settings/logs/channel.ts
+++ b/src/commands/settings/logs/channel.ts
@@ -1,6 +1,6 @@
 import { ChannelType } from 'discord-api-types';
 import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
-import generateEmojiEmbed from "../../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
 import confirmationMessage from "../../../utils/confirmationMessage.js";
 import getEmojiByName from "../../../utils/getEmojiByName.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
@@ -17,7 +17,7 @@
 
 const callback = async (interaction: CommandInteraction): Promise<any> => {
     let m;
-    m = await interaction.reply({embeds: [new generateEmojiEmbed()
+    m = await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Loading")
         .setStatus("Danger")
         .setEmoji("NUCLEUS.LOADING")
@@ -27,7 +27,7 @@
         try {
             channel = interaction.options.getChannel("channel")
         } catch {
-            return await interaction.editReply({embeds: [new generateEmojiEmbed()
+            return await interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji("CHANNEL.TEXT.DELETE")
                 .setTitle("Log Channel")
                 .setDescription("The channel you provided is not a valid channel")
@@ -36,7 +36,7 @@
         }
         channel = channel as Discord.TextChannel
         if (channel.guild.id != interaction.guild.id) {
-            return interaction.editReply({embeds: [new generateEmojiEmbed()
+            return interaction.editReply({embeds: [new EmojiEmbed()
                 .setTitle("Log Channel")
                 .setDescription(`You must choose a channel in this server`)
                 .setStatus("Danger")
@@ -52,10 +52,10 @@
         .send(true)
         if (confirmation.success) {
             try {
-                await client.database.write(interaction.guild.id, {"logging.logs.channel": channel.id})
+                await client.database.guilds.write(interaction.guild.id, {"logging.logs.channel": channel.id})
             } catch (e) {
                 console.log(e)
-                return interaction.editReply({embeds: [new generateEmojiEmbed()
+                return interaction.editReply({embeds: [new EmojiEmbed()
                     .setTitle("Log Channel")
                     .setDescription(`Something went wrong and the log channel could not be set`)
                     .setStatus("Danger")
@@ -63,7 +63,7 @@
                 ], components: []});
             }
         } else {
-            return interaction.editReply({embeds: [new generateEmojiEmbed()
+            return interaction.editReply({embeds: [new EmojiEmbed()
                 .setTitle("Log Channel")
                 .setDescription(`No changes were made`)
                 .setStatus("Success")
@@ -72,10 +72,10 @@
         }
     }
     let clicks = 0;
-    let data = await client.database.read(interaction.guild.id);
+    let data = await client.database.guilds.read(interaction.guild.id);
     let channel = data.logging.logs.channel;
     while (true) {
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setTitle("Log channel")
             .setDescription(channel ? `Your log channel is currently set to <#${channel}>` : "This server does not have a log channel")
             .setStatus("Success")
@@ -96,14 +96,14 @@
             clicks += 1;
             if (clicks == 2) {
                 clicks = 0;
-                await client.database.write(interaction.guild.id, {}, ["logging.logs.channel"])
+                await client.database.guilds.write(interaction.guild.id, {}, ["logging.logs.channel"])
                 channel = undefined;
             }
         } else {
             break
         }
     }
-    await interaction.editReply({embeds: [new generateEmojiEmbed()
+    await interaction.editReply({embeds: [new EmojiEmbed()
         .setTitle("Log channel")
         .setDescription(channel ? `Your log channel is currently set to <#${channel}>` : "This server does not have a log channel")
         .setStatus("Success")
diff --git a/src/commands/settings/logs/ignore.ts b/src/commands/settings/logs/ignore.ts
index 4b66307..12af085 100644
--- a/src/commands/settings/logs/ignore.ts
+++ b/src/commands/settings/logs/ignore.ts
@@ -1,7 +1,7 @@
 import { ChannelType } from 'discord-api-types';
 import Discord, { CommandInteraction } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
-import generateEmojiEmbed from "../../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
 import { WrappedCheck } from "jshaiku";
 import confirmationMessage from '../../../utils/confirmationMessage.js';
 import keyValueList from '../../../utils/generateKeyValueList.js';
@@ -24,7 +24,7 @@
     let channel = interaction.options.getChannel("addchannel")
     let user = interaction.options.getUser("adduser")
     let role = interaction.options.getRole("addrole")
-    await interaction.reply({embeds: [new generateEmojiEmbed()
+    await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Loading")
         .setStatus("Danger")
         .setEmoji("NUCLEUS.LOADING")
@@ -34,7 +34,7 @@
             try {
                 channel = interaction.guild.channels.cache.get(channel.id)
             } catch {
-                return await interaction.editReply({embeds: [new generateEmojiEmbed()
+                return await interaction.editReply({embeds: [new EmojiEmbed()
                     .setEmoji("CHANNEL.TEXT.DELETE")
                     .setTitle("Logs > Ignore")
                     .setDescription("The channel you provided is not a valid channel")
@@ -43,7 +43,7 @@
             }
             channel = channel as Discord.TextChannel
             if (channel.guild.id != interaction.guild.id) {
-                return interaction.editReply({embeds: [new generateEmojiEmbed()
+                return interaction.editReply({embeds: [new EmojiEmbed()
                     .setTitle("Logs > Ignore")
                     .setDescription(`You must choose a channel in this server`)
                     .setStatus("Danger")
@@ -55,7 +55,7 @@
             try {
                 user = interaction.guild.members.cache.get(user.id).user
             } catch {
-                return await interaction.editReply({embeds: [new generateEmojiEmbed()
+                return await interaction.editReply({embeds: [new EmojiEmbed()
                     .setEmoji("USER.DELETE")
                     .setTitle("Logs > Ignore")
                     .setDescription("The user you provided is not a valid user")
@@ -68,7 +68,7 @@
             try {
                 role = interaction.guild.roles.cache.get(role.id)
             } catch {
-                return await interaction.editReply({embeds: [new generateEmojiEmbed()
+                return await interaction.editReply({embeds: [new EmojiEmbed()
                     .setEmoji("ROLE.DELETE")
                     .setTitle("Logs > Ignore")
                     .setDescription("The role you provided is not a valid role")
@@ -77,7 +77,7 @@
             }
             role = role as Discord.Role
             if (role.guild.id != interaction.guild.id) {
-                return interaction.editReply({embeds: [new generateEmojiEmbed()
+                return interaction.editReply({embeds: [new EmojiEmbed()
                     .setTitle("Logs > Ignore")
                     .setDescription(`You must choose a role in this server`)
                     .setStatus("Danger")
@@ -97,12 +97,12 @@
             .setColor("Warning")
         .send(true)
         if (confirmation.success) {
-            let data = client.database.read(interaction.guild.id)
+            let data = client.database.guilds.read(interaction.guild.id)
             if (channel) data.logging.logs.ignore.channels.concat([channel.id])
             if (user) data.logging.logs.ignore.users.concat([user.id])
             if (role) data.logging.logs.ignore.roles.concat([role.id])
             if (interaction.options.getString("action") == "add") {
-                await client.database.append(interaction.guild.id, data)
+                await client.database.guilds.append(interaction.guild.id, data)
             }
         }
     }
diff --git a/src/commands/settings/staff/channel.ts b/src/commands/settings/staff/channel.ts
index 354d7f1..74605cf 100644
--- a/src/commands/settings/staff/channel.ts
+++ b/src/commands/settings/staff/channel.ts
@@ -1,6 +1,6 @@
 import { ChannelType } from 'discord-api-types';
 import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
-import generateEmojiEmbed from "../../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
 import confirmationMessage from "../../../utils/confirmationMessage.js";
 import getEmojiByName from "../../../utils/getEmojiByName.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
@@ -17,7 +17,7 @@
 
 const callback = async (interaction: CommandInteraction): Promise<any> => {
     let m;
-    m = await interaction.reply({embeds: [new generateEmojiEmbed()
+    m = await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Loading")
         .setStatus("Danger")
         .setEmoji("NUCLEUS.LOADING")
@@ -27,7 +27,7 @@
         try {
             channel = interaction.options.getChannel("channel")
         } catch {
-            return await interaction.editReply({embeds: [new generateEmojiEmbed()
+            return await interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji("CHANNEL.TEXT.DELETE")
                 .setTitle("Staff Notifications Channel")
                 .setDescription("The channel you provided is not a valid channel")
@@ -36,7 +36,7 @@
         }
         channel = channel as Discord.TextChannel
         if (channel.guild.id != interaction.guild.id) {
-            return interaction.editReply({embeds: [new generateEmojiEmbed()
+            return interaction.editReply({embeds: [new EmojiEmbed()
                 .setTitle("Staff Notifications Channel")
                 .setDescription(`You must choose a channel in this server`)
                 .setStatus("Danger")
@@ -55,9 +55,9 @@
         .send(true)
         if (confirmation.success) {
             try {
-                await client.database.write(interaction.guild.id, {"logging.staff.channel": channel.id})
+                await client.database.guilds.write(interaction.guild.id, {"logging.staff.channel": channel.id})
             } catch (e) {
-                return interaction.editReply({embeds: [new generateEmojiEmbed()
+                return interaction.editReply({embeds: [new EmojiEmbed()
                     .setTitle("Staff Notifications Channel")
                     .setDescription(`Something went wrong and the staff notifications channel could not be set`)
                     .setStatus("Danger")
@@ -65,7 +65,7 @@
                 ], components: []});
             }
         } else {
-            return interaction.editReply({embeds: [new generateEmojiEmbed()
+            return interaction.editReply({embeds: [new EmojiEmbed()
                 .setTitle("Staff Notifications Channel")
                 .setDescription(`No changes were made`)
                 .setStatus("Success")
@@ -74,10 +74,10 @@
         }
     }
     let clicks = 0;
-    let data = await client.database.read(interaction.guild.id);
+    let data = await client.database.guilds.read(interaction.guild.id);
     let channel = data.logging.staff.channel;
     while (true) {
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setTitle("Staff Notifications channel")
             .setDescription(channel ? `Your staff notifications channel is currently set to <#${channel}>` : "This server does not have a staff notifications channel")
             .setStatus("Success")
@@ -98,14 +98,14 @@
             clicks += 1;
             if (clicks == 2) {
                 clicks = 0;
-                await client.database.write(interaction.guild.id, {}, ["logging.staff.channel"])
+                await client.database.guilds.write(interaction.guild.id, {}, ["logging.staff.channel"])
                 channel = undefined;
             }
         } else {
             break
         }
     }
-    await interaction.editReply({embeds: [new generateEmojiEmbed()
+    await interaction.editReply({embeds: [new EmojiEmbed()
         .setTitle("Staff Notifications channel")
         .setDescription(channel ? `Your staff notifications channel is currently set to <#${channel}>` : "This server does not have a staff notifications channel")
         .setStatus("Success")
diff --git a/src/commands/settings/tickets.ts b/src/commands/settings/tickets.ts
index 670a2f2..b505c5c 100644
--- a/src/commands/settings/tickets.ts
+++ b/src/commands/settings/tickets.ts
@@ -1,5 +1,5 @@
 import getEmojiByName from "../../utils/getEmojiByName.js";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import confirmationMessage from "../../utils/confirmationMessage.js";
 import Discord, { CommandInteraction, MessageActionRow, MessageButton, MessageSelectMenu, TextInputComponent } from "discord.js";
 import { SelectMenuOption, SlashCommandSubcommandBuilder } from "@discordjs/builders";
@@ -22,7 +22,7 @@
 const callback = async (interaction: CommandInteraction): Promise<any> => {
     let m;
     m = await interaction.reply({
-        embeds: [new generateEmojiEmbed()
+        embeds: [new EmojiEmbed()
             .setTitle("Loading")
             .setStatus("Danger")
             .setEmoji("NUCLEUS.LOADING")
@@ -42,7 +42,7 @@
                 channel = interaction.guild.channels.cache.get(options.category.id)
             } catch {
                 return await interaction.editReply({
-                    embeds: [new generateEmojiEmbed()
+                    embeds: [new EmojiEmbed()
                         .setEmoji("CHANNEL.TEXT.DELETE")
                         .setTitle("Tickets > Category")
                         .setDescription("The channel you provided is not a valid category")
@@ -52,7 +52,7 @@
             }
             channel = channel as Discord.CategoryChannel
             if (channel.guild.id != interaction.guild.id) return interaction.editReply({
-                embeds: [new generateEmojiEmbed()
+                embeds: [new EmojiEmbed()
                     .setTitle("Tickets > Category")
                     .setDescription(`You must choose a category in this server`)
                     .setStatus("Danger")
@@ -62,7 +62,7 @@
         }
         if (options.maxtickets) {
             if (options.maxtickets < 1) return interaction.editReply({
-                embeds: [new generateEmojiEmbed()
+                embeds: [new EmojiEmbed()
                     .setTitle("Tickets > Max Tickets")
                     .setDescription(`You must choose a number greater than 0`)
                     .setStatus("Danger")
@@ -76,7 +76,7 @@
                 role = interaction.guild.roles.cache.get(options.supportping.id)
             } catch {
                 return await interaction.editReply({
-                    embeds: [new generateEmojiEmbed()
+                    embeds: [new EmojiEmbed()
                         .setEmoji("GUILD.ROLE.DELETE")
                         .setTitle("Tickets > Support Ping")
                         .setDescription("The role you provided is not a valid role")
@@ -86,7 +86,7 @@
             }
             role = role as Discord.Role
             if (role.guild.id != interaction.guild.id) return interaction.editReply({
-                embeds: [new generateEmojiEmbed()
+                embeds: [new EmojiEmbed()
                     .setTitle("Tickets > Support Ping")
                     .setDescription(`You must choose a role in this server`)
                     .setStatus("Danger")
@@ -116,10 +116,10 @@
             if (options.maxtickets) toUpdate["tickets.maxTickets"] = options.maxtickets
             if (options.supportping) toUpdate["tickets.supportRole"] = options.supportping.id
             try {
-                await client.database.write(interaction.guild.id, toUpdate)
+                await client.database.guilds.write(interaction.guild.id, toUpdate)
             } catch (e) {
                 return interaction.editReply({
-                    embeds: [new generateEmojiEmbed()
+                    embeds: [new EmojiEmbed()
                         .setTitle("Tickets")
                         .setDescription(`Something went wrong and the staff notifications channel could not be set`)
                         .setStatus("Danger")
@@ -129,7 +129,7 @@
             }
         } else {
             return interaction.editReply({
-                embeds: [new generateEmojiEmbed()
+                embeds: [new EmojiEmbed()
                     .setTitle("Tickets")
                     .setDescription(`No changes were made`)
                     .setStatus("Success")
@@ -138,7 +138,7 @@
             });
         }
     }
-    let data = await client.database.read(interaction.guild.id);
+    let data = await client.database.guilds.read(interaction.guild.id);
     data.tickets.customTypes = data.tickets.customTypes.filter((v, i, a) => a.indexOf(v) === i)
     let lastClicked = "";
     let embed;
@@ -152,7 +152,7 @@
         customTypes: data.tickets.customTypes
     }
     while (true) {
-        embed = new generateEmojiEmbed()
+        embed = new EmojiEmbed()
             .setTitle("Tickets")
             .setDescription(
                 `${data.enabled ? "" : getEmojiByName("TICKETS.REPORT")} **Enabled:** ${data.enabled ? `${getEmojiByName("CONTROL.TICK")} Yes` : `${getEmojiByName("CONTROL.CROSS")} No`}\n` +
@@ -206,23 +206,23 @@
         if (i.component.customId == "clearCategory") {
             if (lastClicked == "cat") {
                 lastClicked = "";
-                await client.database.write(interaction.guild.id, {}, ["tickets.category"])
+                await client.database.guilds.write(interaction.guild.id, {}, ["tickets.category"])
                 data.category = undefined;
             } else lastClicked = "cat";
         } else if (i.component.customId == "clearMaxTickets") {
             if (lastClicked == "max") {
                 lastClicked = "";
-                await client.database.write(interaction.guild.id, {}, ["tickets.maxTickets"])
+                await client.database.guilds.write(interaction.guild.id, {}, ["tickets.maxTickets"])
                 data.maxTickets = 5;
             } else lastClicked = "max";
         } else if (i.component.customId == "clearSupportPing") {
             if (lastClicked == "sup") {
                 lastClicked = "";
-                await client.database.write(interaction.guild.id, {}, ["tickets.supportRole"])
+                await client.database.guilds.write(interaction.guild.id, {}, ["tickets.supportRole"])
                 data.supportRole = undefined;
             } else lastClicked = "sup";
         } else if (i.component.customId == "enabled") {
-            await client.database.write(interaction.guild.id, { "tickets.enabled": !data.enabled })
+            await client.database.guilds.write(interaction.guild.id, { "tickets.enabled": !data.enabled })
             data.enabled = !data.enabled;
         } else if (i.component.customId == "manageTypes") {
             data = await manageTypes(interaction, data, m);
@@ -238,7 +238,7 @@
         if (data.useCustom) {
             let customTypes = data.customTypes;
             await interaction.editReply({
-                embeds: [new generateEmojiEmbed()
+                embeds: [new EmojiEmbed()
                     .setTitle("Tickets > Types")
                     .setDescription(
                         "**Custom types enabled**\n\n" +
@@ -299,7 +299,7 @@
                     .setPlaceholder("Select types to use")
             ])
             await interaction.editReply({
-                embeds: [new generateEmojiEmbed()
+                embeds: [new EmojiEmbed()
                     .setTitle("Tickets > Types")
                     .setDescription(
                         "**Default types enabled**\n\n" +
@@ -331,7 +331,7 @@
         if (i.component.customId == "types") {
             i.deferUpdate()
             let types = toHexInteger(i.values, ticketTypes);
-            await client.database.write(interaction.guild.id, { "tickets.types": types })
+            await client.database.guilds.write(interaction.guild.id, { "tickets.types": types })
             data.types = types;
         } else if (i.component.customId == "removeTypes") {
             i.deferUpdate()
@@ -340,7 +340,7 @@
             if (customTypes) {
                 customTypes = customTypes.filter((t) => !types.includes(t));
                 customTypes = customTypes.length > 0 ? customTypes : null;
-                await client.database.write(interaction.guild.id, { "tickets.customTypes": customTypes })
+                await client.database.guilds.write(interaction.guild.id, { "tickets.customTypes": customTypes })
                 data.customTypes = customTypes;
             }
         } else if (i.component.customId == "addType") {
@@ -357,7 +357,7 @@
                 )
             ))
             await interaction.editReply({
-                embeds: [new generateEmojiEmbed()
+                embeds: [new EmojiEmbed()
                     .setTitle("Tickets > Types")
                     .setDescription("Modal opened. If you can't see it, click back and try again.")
                     .setStatus("Success")
@@ -369,15 +369,16 @@
                     .setCustomId("back")
                 ])]
             });
-            let out
+            let out;
             try {
                 out = await modalInteractionCollector(m, (m) => m.channel.id == interaction.channel.id, (m) => m.customId == "addType")
             } catch (e) { continue }
             if (out.fields) {
                 let toAdd = out.fields.getTextInputValue("type");
                 if (!toAdd) { continue }
+                toAdd = toAdd.substring(0, 80)
                 try {
-                    await client.database.append(interaction.guild.id, "tickets.customTypes", toAdd)
+                    await client.database.guilds.append(interaction.guild.id, "tickets.customTypes", toAdd)
                 } catch { continue }
                 data.customTypes = data.customTypes || [];
                 if (!data.customTypes.includes(toAdd)) {
@@ -386,11 +387,11 @@
             } else { continue }
         } else if (i.component.customId == "switchToDefault") {
             i.deferUpdate()
-            await client.database.write(interaction.guild.id, { "tickets.useCustom": false }, [])
+            await client.database.guilds.write(interaction.guild.id, { "tickets.useCustom": false }, [])
             data.useCustom = false;
         } else if (i.component.customId == "switchToCustom") {
             i.deferUpdate()
-            await client.database.write(interaction.guild.id, { "tickets.useCustom": true }, [])
+            await client.database.guilds.write(interaction.guild.id, { "tickets.useCustom": true }, [])
             data.useCustom = true;
         } else {
             i.deferUpdate()
diff --git a/src/commands/settings/verify/role.ts b/src/commands/settings/verify/role.ts
index 68b4bf9..44406e9 100644
--- a/src/commands/settings/verify/role.ts
+++ b/src/commands/settings/verify/role.ts
@@ -1,5 +1,5 @@
 import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
-import generateEmojiEmbed from "../../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../../utils/generateEmojiEmbed.js";
 import confirmationMessage from "../../../utils/confirmationMessage.js";
 import getEmojiByName from "../../../utils/getEmojiByName.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
@@ -14,7 +14,7 @@
 
 const callback = async (interaction: CommandInteraction): Promise<any> => {
     let m;
-    m = await interaction.reply({embeds: [new generateEmojiEmbed()
+    m = await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Loading")
         .setStatus("Danger")
         .setEmoji("NUCLEUS.LOADING")
@@ -24,7 +24,7 @@
         try {
             role = interaction.options.getRole("role")
         } catch {
-            return await interaction.editReply({embeds: [new generateEmojiEmbed()
+            return await interaction.editReply({embeds: [new EmojiEmbed()
                 .setEmoji("GUILD.ROLES.DELETE")
                 .setTitle("Verify Role")
                 .setDescription("The role you provided is not a valid role")
@@ -33,7 +33,7 @@
         }
         role = role as Discord.Role
         if (role.guild.id != interaction.guild.id) {
-            return interaction.editReply({embeds: [new generateEmojiEmbed()
+            return interaction.editReply({embeds: [new EmojiEmbed()
                 .setTitle("Verify Role")
                 .setDescription(`You must choose a role in this server`)
                 .setStatus("Danger")
@@ -49,10 +49,10 @@
         .send(true)
         if (confirmation.success) {
             try {
-                await client.database.write(interaction.guild.id, {"verify.role": role.id, "verify.enabled": true});
+                await client.database.guilds.write(interaction.guild.id, {"verify.role": role.id, "verify.enabled": true});
             } catch (e) {
                 console.log(e)
-                return interaction.editReply({embeds: [new generateEmojiEmbed()
+                return interaction.editReply({embeds: [new EmojiEmbed()
                     .setTitle("Verify Role")
                     .setDescription(`Something went wrong while setting the verify role`)
                     .setStatus("Danger")
@@ -60,7 +60,7 @@
                 ], components: []});
             }
         } else {
-            return interaction.editReply({embeds: [new generateEmojiEmbed()
+            return interaction.editReply({embeds: [new EmojiEmbed()
                 .setTitle("Verify Role")
                 .setDescription(`No changes were made`)
                 .setStatus("Success")
@@ -69,10 +69,10 @@
         }
     }
     let clicks = 0;
-    let data = await client.database.read(interaction.guild.id);
+    let data = await client.database.guilds.read(interaction.guild.id);
     let role = data.verify.role;
     while (true) {
-        await interaction.editReply({embeds: [new generateEmojiEmbed()
+        await interaction.editReply({embeds: [new EmojiEmbed()
             .setTitle("Verify Role")
             .setDescription(role ? `Your verify role is currently set to <@&${role}>` : `You have not set a verify role`)
             .setStatus("Success")
@@ -93,14 +93,14 @@
             clicks += 1;
             if (clicks == 2) {
                 clicks = 0;
-                await client.database.write(interaction.guild.id, {}, ["verify.role", "verify.enabled"])
+                await client.database.guilds.write(interaction.guild.id, {}, ["verify.role", "verify.enabled"])
                 role = undefined;
             }
         } else {
             break
         }
     }
-    await interaction.editReply({embeds: [new generateEmojiEmbed()
+    await interaction.editReply({embeds: [new EmojiEmbed()
         .setTitle("Verify Role")
         .setDescription(role ? `Your verify role is currently set to <@&${role}}>` : `You have not set a verify role`)
         .setStatus("Success")
diff --git a/src/commands/tag.ts b/src/commands/tag.ts
index 80bcbad..a9f0075 100644
--- a/src/commands/tag.ts
+++ b/src/commands/tag.ts
@@ -9,7 +9,6 @@
     .setDescription("Get and manage the servers tags")
 
 const callback = (interaction: CommandInteraction) => {
-    // try { statsChannelAdd(interaction.client, interaction.member); } catch {} // TODO: REMOVE THIS FOR PRODUCTION
     interaction.reply("This command is not yet finished [tag]");
 }
 
diff --git a/src/commands/tags/create.ts b/src/commands/tags/create.ts
index e53f94f..c1ed839 100644
--- a/src/commands/tags/create.ts
+++ b/src/commands/tags/create.ts
@@ -1,7 +1,7 @@
 import Discord, { CommandInteraction } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import confirmationMessage from "../../utils/confirmationMessage.js";
 import keyValueList from "../../utils/generateKeyValueList.js";
 import client from "../../utils/client.js";
@@ -16,26 +16,26 @@
 const callback = async (interaction: CommandInteraction): Promise<any> => {
     let name = interaction.options.getString("name");
     let value = interaction.options.getString("value");
-    if (name.length > 100) return await interaction.reply({embeds: [new generateEmojiEmbed()
+    if (name.length > 100) return await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Tag Create")
         .setDescription("Tag names cannot be longer than 100 characters")
         .setStatus("Danger")
         .setEmoji("PUNISH.NICKNAME.RED")
     ], ephemeral: true});
-    if (value.length > 1000) return await interaction.reply({embeds: [new generateEmojiEmbed()
+    if (value.length > 1000) return await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Tag Create")
         .setDescription("Tag values cannot be longer than 1000 characters")
         .setStatus("Danger")
         .setEmoji("PUNISH.NICKNAME.RED")
     ], ephemeral: true});
-    let data = await client.database.read(interaction.guild.id);
-    if (data.tags.length >= 100) return await interaction.reply({embeds: [new generateEmojiEmbed()
+    let data = await client.database.guilds.read(interaction.guild.id);
+    if (data.tags.length >= 100) return await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Tag Create")
         .setDescription("You cannot have more than 100 tags")
         .setStatus("Danger")
         .setEmoji("PUNISH.NICKNAME.RED")
     ], ephemeral: true});
-    if (data.tags[name]) return await interaction.reply({embeds: [new generateEmojiEmbed()
+    if (data.tags[name]) return await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Tag Create")
         .setDescription("That tag already exists")
         .setStatus("Danger")
@@ -52,23 +52,23 @@
         .setColor("Warning")
         .setInverted(true)
     .send()
-    if (!confirmation) return await interaction.editReply({embeds: [new generateEmojiEmbed()
+    if (!confirmation) return await interaction.editReply({embeds: [new EmojiEmbed()
         .setTitle("Tag Create")
         .setDescription("No changes were made")
         .setStatus("Success")
         .setEmoji("PUNISH.NICKNAME.GREEN")
     ]});
     try {
-        await client.database.write(interaction.guild.id, {[`tags.${name}`]: value});
+        await client.database.guilds.write(interaction.guild.id, {[`tags.${name}`]: value});
     } catch (e) {
-        return await interaction.editReply({embeds: [new generateEmojiEmbed()
+        return await interaction.editReply({embeds: [new EmojiEmbed()
             .setTitle("Tag Create")
             .setDescription("Something went wrong and the tag was not created")
             .setStatus("Danger")
             .setEmoji("PUNISH.NICKNAME.RED")
         ], components: []});
     }
-    return await interaction.editReply({embeds: [new generateEmojiEmbed()
+    return await interaction.editReply({embeds: [new EmojiEmbed()
         .setTitle("Tag Create")
         .setDescription("Tag created")
         .setStatus("Success")
diff --git a/src/commands/tags/delete.ts b/src/commands/tags/delete.ts
index ff54ee5..f24a5fc 100644
--- a/src/commands/tags/delete.ts
+++ b/src/commands/tags/delete.ts
@@ -1,7 +1,7 @@
 import Discord, { CommandInteraction } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import confirmationMessage from "../../utils/confirmationMessage.js";
 import keyValueList from "../../utils/generateKeyValueList.js";
 import client from "../../utils/client.js";
@@ -14,8 +14,8 @@
 
 const callback = async (interaction: CommandInteraction): Promise<any> => {
     let name = interaction.options.getString("name");
-    let data = await client.database.read(interaction.guild.id);
-    if (!data.tags[name]) return await interaction.reply({embeds: [new generateEmojiEmbed()
+    let data = await client.database.guilds.read(interaction.guild.id);
+    if (!data.tags[name]) return await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Tags")
         .setDescription("That tag does not exist")
         .setStatus("Danger")
@@ -32,25 +32,25 @@
         .setColor("Warning")
         .setInverted(true)
     .send()
-    if (!confirmation) return await interaction.editReply({embeds: [new generateEmojiEmbed()
+    if (!confirmation) return await interaction.editReply({embeds: [new EmojiEmbed()
         .setTitle("Tag Delete")
         .setDescription("No changes were made")
         .setStatus("Success")
         .setEmoji("PUNISH.NICKNAME.GREEN")
     ]});
     try {
-        data = await client.database.read(interaction.guild.id);
+        data = await client.database.guilds.read(interaction.guild.id);
         delete data.tags[name];
-        await client.database.write(interaction.guild.id, {tags: data});
+        await client.database.guilds.write(interaction.guild.id, {tags: data});
     } catch (e) {
-        return await interaction.editReply({embeds: [new generateEmojiEmbed()
+        return await interaction.editReply({embeds: [new EmojiEmbed()
             .setTitle("Tag Delete")
             .setDescription("Something went wrong and the tag was not deleted")
             .setStatus("Danger")
             .setEmoji("PUNISH.NICKNAME.RED")
         ], components: []});
     }
-    return await interaction.editReply({embeds: [new generateEmojiEmbed()
+    return await interaction.editReply({embeds: [new EmojiEmbed()
         .setTitle("Tag Delete")
         .setDescription("Tag deleted")
         .setStatus("Success")
diff --git a/src/commands/tags/edit.ts b/src/commands/tags/edit.ts
index 3cf73e5..b0a4835 100644
--- a/src/commands/tags/edit.ts
+++ b/src/commands/tags/edit.ts
@@ -1,7 +1,7 @@
 import Discord, { CommandInteraction } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import confirmationMessage from "../../utils/confirmationMessage.js";
 import keyValueList from "../../utils/generateKeyValueList.js";
 import client from "../../utils/client.js";
@@ -18,32 +18,32 @@
     let name = interaction.options.getString("name");
     let value = interaction.options.getString("value") || "";
     let newname = interaction.options.getString("newname") || "";
-    if (!newname && !value) return await interaction.reply({embeds: [new generateEmojiEmbed()
+    if (!newname && !value) return await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Tag Edit")
         .setDescription("You must specify a value or a new name")
         .setStatus("Danger")
         .setEmoji("PUNISH.NICKNAME.RED")
     ], ephemeral: true});
-    if (newname.length > 100) return await interaction.reply({embeds: [new generateEmojiEmbed()
+    if (newname.length > 100) return await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Tag Edit")
         .setDescription("Tag names cannot be longer than 100 characters")
         .setStatus("Danger")
         .setEmoji("PUNISH.NICKNAME.RED")
     ], ephemeral: true});
-    if (value.length > 2000) return await interaction.reply({embeds: [new generateEmojiEmbed()
+    if (value.length > 2000) return await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Tag Edit")
         .setDescription("Tag values cannot be longer than 2000 characters")
         .setStatus("Danger")
         .setEmoji("PUNISH.NICKNAME.RED")
     ], ephemeral: true});
-    let data = await client.database.read(interaction.guild.id);
-    if (!data.tags[name]) return await interaction.reply({embeds: [new generateEmojiEmbed()
+    let data = await client.database.guilds.read(interaction.guild.id);
+    if (!data.tags[name]) return await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Tag Edit")
         .setDescription("That tag does not exist")
         .setStatus("Danger")
         .setEmoji("PUNISH.NICKNAME.RED")
     ], ephemeral: true});
-    if (newname && newname !== name && data.tags[newname]) return await interaction.reply({embeds: [new generateEmojiEmbed()
+    if (newname && newname !== name && data.tags[newname]) return await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("Tag Edit")
         .setDescription("A tag with that name already exists")
         .setStatus("Danger")
@@ -60,7 +60,7 @@
         .setColor("Warning")
         .setInverted(true)
     .send()
-    if (!confirmation) return await interaction.editReply({embeds: [new generateEmojiEmbed()
+    if (!confirmation) return await interaction.editReply({embeds: [new EmojiEmbed()
         .setTitle("Tag Edit")
         .setDescription("No changes were made")
         .setStatus("Success")
@@ -74,16 +74,16 @@
             toUnset.push(`tags.${name}`);
             toSet[`tags.${newname}`] = data.tags[name];
         }
-        await client.database.write(interaction.guild.id, toSet, toUnset);
+        await client.database.guilds.write(interaction.guild.id, toSet, toUnset);
     } catch (e) {
-        return await interaction.editReply({embeds: [new generateEmojiEmbed()
+        return await interaction.editReply({embeds: [new EmojiEmbed()
             .setTitle("Tag Edit")
             .setDescription("Something went wrong and the tag was not edited")
             .setStatus("Danger")
             .setEmoji("PUNISH.NICKNAME.RED")
         ], components: []});
     }
-    return await interaction.editReply({embeds: [new generateEmojiEmbed()
+    return await interaction.editReply({embeds: [new EmojiEmbed()
         .setTitle("Tags")
         .setDescription("Tag edited successfully")
         .setStatus("Success")
diff --git a/src/commands/tags/list.ts b/src/commands/tags/list.ts
index 5052a6b..a534791 100644
--- a/src/commands/tags/list.ts
+++ b/src/commands/tags/list.ts
@@ -1,8 +1,7 @@
 import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
-import keyValueList from "../../utils/generateKeyValueList.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import client from "../../utils/client.js";
 import { SelectMenuOption } from '@discordjs/builders';
 import getEmojiByName from "../../utils/getEmojiByName.js";
@@ -25,10 +24,9 @@
         .setName("list")
         .setDescription("Lists all tags in the server")
 
-const callback = async (interaction: CommandInteraction) => {
-    let data = await client.database.read(interaction.guild.id);
+const callback = async (interaction: CommandInteraction): Promise<any> => {
+    let data = await client.database.guilds.read(interaction.guild.id);
     let tags = data.getKey("tags");
-    console.log(tags)
     let strings = []
     if (data === {}) strings = ["*No tags exist*"]
     else {
@@ -39,7 +37,6 @@
                 strings.push(string.slice(0, -1))
                 string = ""
             }
-            console.log(string)
             string += proposed
         }
         strings.push(string.slice(0, -1))
@@ -48,7 +45,7 @@
     let pages = []
     for (let string of strings) {
         pages.push(new Embed()
-            .setEmbed(new generateEmojiEmbed()
+            .setEmbed(new EmojiEmbed()
                 .setTitle("Tags")
                 .setDescription(string)
                 .setEmoji("PUNISH.NICKNAME.GREEN")
@@ -58,7 +55,7 @@
     let m;
     m = await interaction.reply({
         embeds: [
-            new generateEmojiEmbed()
+            new EmojiEmbed()
                 .setTitle("Welcome")
                 .setDescription(`One moment...`)
                 .setStatus("Danger")
@@ -128,7 +125,7 @@
             return;
         }
     }
-    let em = new Discord.MessageEmbed(pages[page])
+    let em = new Discord.MessageEmbed(pages[page].embed)
     em.setDescription(em.description + "\n\n" + createPageIndicator(pages.length, page) + " | Message timed out");
     await interaction.editReply({
         embeds: [em],
diff --git a/src/commands/ticket/close.ts b/src/commands/ticket/close.ts
index 237623d..15abb0a 100644
--- a/src/commands/ticket/close.ts
+++ b/src/commands/ticket/close.ts
@@ -8,7 +8,7 @@
     .setName("close")
     .setDescription("Closes a ticket")
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
     await close(interaction);
 }
 
diff --git a/src/commands/ticket/create.ts b/src/commands/ticket/create.ts
index 6567c49..c44e576 100644
--- a/src/commands/ticket/create.ts
+++ b/src/commands/ticket/create.ts
@@ -9,7 +9,7 @@
     .setDescription("Creates a new modmail ticket")
     .addStringOption(option => option.setName("message").setDescription("The content of the ticket").setRequired(false))
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
     await create(interaction)
 }
 
diff --git a/src/commands/user/about.ts b/src/commands/user/about.ts
index 0c7a3eb..8557d15 100644
--- a/src/commands/user/about.ts
+++ b/src/commands/user/about.ts
@@ -1,7 +1,7 @@
 import Discord, { CommandInteraction, MessageActionRow, MessageButton } from "discord.js";
 import { SelectMenuOption, SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import getEmojiByName from "../../utils/getEmojiByName.js";
 import generateKeyValueList from "../../utils/generateKeyValueList.js";
 import createPageIndicator from "../../utils/createPageIndicator.js";
@@ -26,7 +26,7 @@
 }
 
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
     const { renderUser, renderDelta } = client.logger
     let member = (interaction.options.getMember("user") || interaction.member) as Discord.GuildMember;
     let flags: string[] = [];
@@ -105,7 +105,7 @@
 
     let embeds = [
         new Embed()
-            .setEmbed(new generateEmojiEmbed()
+            .setEmbed(new EmojiEmbed()
                 .setTitle("User Info: General")
                 .setStatus("Success")
                 .setEmoji("MEMBER.JOIN")
@@ -129,7 +129,7 @@
                 .setImage((await member.user.fetch()).bannerURL({format: "gif"}))
             ).setTitle("General").setDescription("General information about the user").setPageId(0),
         new Embed()
-            .setEmbed(new generateEmojiEmbed()
+            .setEmbed(new EmojiEmbed()
                 .setTitle("User Info: Roles")
                 .setStatus("Success")
                 .setEmoji("GUILD.ROLES.CREATE")
@@ -144,7 +144,7 @@
                 .setThumbnail(await member.user.displayAvatarURL({dynamic: true}))
             ).setTitle("Roles").setDescription("Roles the user has").setPageId(1),
         new Embed()
-            .setEmbed(new generateEmojiEmbed()
+            .setEmbed(new EmojiEmbed()
                 .setTitle("User Info: Key Permissions")
                 .setStatus("Success")
                 .setEmoji("GUILD.ROLES.CREATE")
@@ -158,7 +158,7 @@
             ).setTitle("Key Permissions").setDescription("Key permissions the user has").setPageId(2),
     ]
     let m
-    m = await interaction.reply({embeds: [new generateEmojiEmbed().setTitle("Loading").setEmoji("NUCLEUS.LOADING").setStatus("Danger")], fetchReply: true, ephemeral: true});
+    m = await interaction.reply({embeds: [new EmojiEmbed().setTitle("Loading").setEmoji("NUCLEUS.LOADING").setStatus("Danger")], fetchReply: true, ephemeral: true});
     let page = 0
     let breakReason = ""
     while (true) {
diff --git a/src/commands/user/avatar.ts b/src/commands/user/avatar.ts
index 9a84118..e72506f 100644
--- a/src/commands/user/avatar.ts
+++ b/src/commands/user/avatar.ts
@@ -1,10 +1,10 @@
 import Discord, { CommandInteraction } from "discord.js";
 import { SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import getEmojiByName from "../../utils/getEmojiByName.js";
 import generateKeyValueList from "../../utils/generateKeyValueList.js";
-import client from "../../client.js"
+import client from "../../utils/client.js"
 
 const command = (builder: SlashCommandSubcommandBuilder) =>
     builder
@@ -12,10 +12,10 @@
     .setDescription("Shows the avatar of a user")
     .addUserOption(option => option.setName("user").setDescription("The user to get the avatar of | Default: Yourself"))
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
     const { renderUser } = client.logger
     let member = (interaction.options.getMember("user") || interaction.member) as Discord.GuildMember;
-    await interaction.reply({embeds: [new generateEmojiEmbed()
+    await interaction.reply({embeds: [new EmojiEmbed()
         .setTitle("User Info")
         .setStatus("Success")
         .setEmoji("MEMBER.JOIN")
diff --git a/src/commands/user/track.ts b/src/commands/user/track.ts
index 0e6fafd..da332da 100644
--- a/src/commands/user/track.ts
+++ b/src/commands/user/track.ts
@@ -1,7 +1,7 @@
 import Discord, { CommandInteraction, GuildMember, Message, MessageActionRow, MessageButton } from "discord.js";
 import { SelectMenuOption, SlashCommandSubcommandBuilder } from "@discordjs/builders";
 import { WrappedCheck } from "jshaiku";
-import generateEmojiEmbed from "../../utils/generateEmojiEmbed.js";
+import EmojiEmbed from "../../utils/generateEmojiEmbed.js";
 import getEmojiByName from "../../utils/getEmojiByName.js";
 import addPlural from "../../utils/plurals.js";
 import client from "../../utils/client.js";
@@ -21,12 +21,12 @@
     return "TRACKS.VERTICAL.MIDDLE." + disabled + active
 }
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
     const { renderUser } = client.logger;
     const member = interaction.options.getMember("user") as GuildMember;
     const guild = interaction.guild;
-    let config = await client.database.read(guild.id);
-    await interaction.reply({embeds: [new generateEmojiEmbed()
+    let config = await client.database.guilds.read(guild.id);
+    await interaction.reply({embeds: [new EmojiEmbed()
         .setEmoji("NUCLEUS.LOADING")
         .setTitle("Loading")
         .setStatus("Danger")
@@ -35,9 +35,11 @@
     let generated;
     const roles = await guild.roles.fetch()
     let memberRoles = await member.roles
+    let managed
     while (true) {
         let data = config.tracks[track]
-        let managed = data.manageableBy.some(element => {return memberRoles.cache.has(element)})
+        if (data.manageableBy !== undefined) managed = data.manageableBy.some(element => {return memberRoles.cache.has(element)})
+        else managed = false
         let dropdown = new Discord.MessageSelectMenu().addOptions(config.tracks.map((option, index) => {
             let hasRoleInTrack = option.track.some(element => {return memberRoles.cache.has(element)})
             return new SelectMenuOption({
@@ -94,7 +96,7 @@
         } else {
             currentRoleIndex = selected.length == 0 ? -1 : data.track.indexOf(selected[0].toString())
         }
-        let m = await interaction.editReply({embeds: [new generateEmojiEmbed()
+        let m = await interaction.editReply({embeds: [new EmojiEmbed()
             .setEmoji("TRACKS.ICON")
             .setTitle("Tracks")
             .setDescription(`${generated}`)
@@ -160,16 +162,19 @@
 }
 
 const check = async (interaction: CommandInteraction, defaultCheck: WrappedCheck) => {
+    let tracks = (await client.database.guilds.read(interaction.guild.id)).tracks
+    if (!tracks) throw "This server does not have any tracks"
     let member = (interaction.member as GuildMember)
     // Allow the owner to promote anyone
     if (member.id == interaction.guild.ownerId) return true
     // Check if the user can manage any of the tracks
-    // @ts-ignore
-    let tracks = (await client.database.get(interaction.guild.id)).tracks
     let managed = false
-    tracks.forEach(element => { if (element.track.manageableBy.some(role => member.roles.cache.has(role))) managed = true });
+    tracks.forEach(element => {
+        if (!element.track.manageableBy) return
+        if (element.track.manageableBy.some(role => member.roles.cache.has(role))) managed = true
+    });
     // Check if the user has manage_roles permission
-    if (!managed && ! member.permissions.has("MANAGE_ROLES")) throw "You do not have the `manage_roles` permission";
+    if (!managed && ! member.permissions.has("MANAGE_ROLES")) throw "You do not have the Manage roles permission";
     // Allow track
     return true;
 }
diff --git a/src/commands/verify.ts b/src/commands/verify.ts
index c9abb77..4ccc807 100644
--- a/src/commands/verify.ts
+++ b/src/commands/verify.ts
@@ -7,7 +7,7 @@
     .setName("verify")
     .setDescription("Get verified in the server")
 
-const callback = async (interaction: CommandInteraction) => {
+const callback = async (interaction: CommandInteraction): Promise<any> => {
     verify(interaction);
 }