Skip to content
This repository was archived by the owner on Dec 5, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions src/commands/moderation/forcelink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Message } from "discord.js";
import Client from "../../structures/Client";
import Roles from "../../data/calm/roles.json";
import { ICommand, PermissionsEnum, RunCallback } from "../../structures/Interfaces";
import MojangApi from "../../utils/api/MojangApi";
import Database from "../../utils/database/Database";
import logger from "../../utils/logger/Logger";

function ForceLinkCommand(): ICommand {
const run: RunCallback = (client: Client, message: Message, args: string[]) => {
const calmiesRole = message.guild!!.id === "501501905508237312" ? message.guild?.roles.cache.get(Roles.GENERAL.CALMIES.id) : message.guild?.roles.cache.find((r) => r.name === Roles.GENERAL.CALMIES.name);
if (!calmiesRole) {
message.channel.send(`Could not find the ${Roles.GENERAL.CALMIES.name} role in this server!`);
return;
}

message
.guild!!.members.fetch(args[0]!!)
.then((member) => {
Database.getUser(member.id)
.then((user) => {
message.channel.send(`Discord user is already linked to ${user.id}`);
})
.catch(async () => {
const uuid = await MojangApi.getUUID(args[1]!!);

if (!uuid) {
message.channel.send("Invalid minecraft name.");
return;
}

const inCalm = member.roles.cache.has(calmiesRole.id);
Database.createUser(member.id, uuid, inCalm)
.then((user) => {
message.channel.send(`Created new database entry!\n\`\`\`${user}\`\`\``).catch(logger.error);
})
.catch((err) => {
message.channel.send("An error occurred while running that command! Please contact a developer.");
logger.error(err);
});
});
})
.catch(() => {
message.channel.send("Invalid discord id! (user not in server)");
});
};

return {
run: run,
settings: {
description: "Force link a discord and minecraft account",
usage: "forcelink <discord-id> <minecraft-ign>",
permissions: PermissionsEnum.STAFF,
guildOnly: true,
minimumArgs: 2,
},
};
}

export default ForceLinkCommand();
5 changes: 5 additions & 0 deletions src/data/calm/channels.json
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,11 @@
}
},
"STAFF": {
"STAFF_CHAT": {
"name": "staff-chat",
"id": "547923467522015263",
"public": false
},
"CHALLENGES": {
"name": "challenge-requests",
"id": "787202572032278539",
Expand Down
82 changes: 82 additions & 0 deletions src/events/guildMemberUpdate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { GuildMember } from "discord.js";
import Roles from "../data/calm/roles.json";
import Channels from "../data/calm/channels.json";
import Client from "../structures/Client";
import Database from "../utils/database/Database";
import MojangApi from "../utils/api/MojangApi";
import logger from "../utils/logger/Logger";

export default function guildMemberUpdate(client: Client, oldMember: GuildMember, newMember: GuildMember) {
const isCalmDiscord = newMember.guild.id === "501501905508237312";
const calmMemberRole = isCalmDiscord ? newMember.guild.roles.cache.get(Roles.GENERAL.CALMIES.id) : newMember.guild.roles.cache.find((r) => r.name === Roles.GENERAL.CALMIES.name);
const staffChat = isCalmDiscord ? newMember.guild.channels.cache.get(Channels.STAFF.STAFF_CHAT.id) : newMember.guild.channels.cache.find((c) => c.name === Channels.STAFF.STAFF_CHAT.name);
if (!calmMemberRole) return;

const newRoles = newMember.roles.cache.filter((role) => !oldMember.roles.cache.has(role.id));
const removedRoles = oldMember.roles.cache.filter((role) => !newMember.roles.cache.has(role.id));

// Member was given calmie role
if (newRoles.size > 0 && newRoles.array()[0]?.id === calmMemberRole.id) {
Database.getUser(newMember.id)
.then((user) => {
// User was in the guild before
user.inCalm = true;
user.save();
})
.catch(() => {
// User was not in guild before
let name = newMember.nickname;
if (!name) {
sendErrorToStaffChat();
return;
}

// Get MC name from nickanme
name = name.slice(name.indexOf("]") + 2);
const j = name.indexOf(" ");
if (j !== -1) name = name.slice(0, j);

if (!name) {
sendErrorToStaffChat();
return;
}

// If we were able to get name get uuid of person so we can link their minecraft and discord account
MojangApi.getUUID(name)
.then((uuid) => {
// Name is incorrect
if (!uuid) {
sendErrorToStaffChat();
return;
}

// UUID is correct so we can create the document
Database.createUser(newMember.id, uuid, true).catch(logger.error);
})
.catch((err) => {
logger.error(err);
sendErrorToStaffChat();
});
});
}

// Member was removed from calmie role
else if (removedRoles.size > 0 && removedRoles.array()[0]?.id === calmMemberRole.id) {
Database.getUser(newMember.id)
.then((user) => {
user.inCalm = false;
user.save();
})
.catch(() => {
logger.warn(`User: ${newMember.id} was removed from calmies role but never had an entry in the database`);
});
}

function sendErrorToStaffChat() {
if (staffChat && staffChat.isText()) {
staffChat
.send(`ERROR! ${newMember}'s nickname is not correct and we could not create a database entry for them because we could not fetch their UUID.\n**Please do ${client.prefix}forcelink ${newMember.id} <IGN>** **__ASAP__**`)
.catch(logger.error);
}
}
}
14 changes: 14 additions & 0 deletions src/schemas/User.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Schema, model, Document } from "mongoose";
export interface IUser extends Document {
discordID: string;
uuid: string;
inCalm: boolean;
}

const UserSchema = new Schema({
discordID: { type: String, requried: true, index: true, unique: true },
uuid: { type: String, required: true, unique: true },
inCalm: { type: Boolean, required: true },
});

export default model<IUser>("User", UserSchema);
20 changes: 20 additions & 0 deletions src/utils/api/MojangApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import axios from "axios";
import logger from "../logger/Logger";

const MOJANG_API_URL = "https://api.mojang.com";

export default {
getUUID(name: string): Promise<string> {
return new Promise((resolve, reject) => {
axios
.get(`${MOJANG_API_URL}/users/profiles/minecraft/${name}`)
.then((response) => {
resolve(response.data?.id);
})
.catch((err) => {
logger.error(err);
reject(err);
});
});
},
};
21 changes: 21 additions & 0 deletions src/utils/database/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import GuildSettings from "../../schemas/GuildSettings";
import ChallengeParticipant from "../../schemas/ChallengeParticipant";
import Client from "../../structures/Client";
import logger from "../logger/Logger";
import User, { IUser } from "../../schemas/User";

export default {
initialize: async (url: string, client: Client) => {
Expand Down Expand Up @@ -37,4 +38,24 @@ export default {
}
return participant;
},

getUser: (discordid: string): Promise<IUser> => {
return new Promise(async (resolve, reject) => {
const user = await User.findOne({ discordID: discordid });
if (user) resolve(user);
reject(undefined);
});
},

createUser(discordid: string, uuid: string, inCalm: boolean): Promise<IUser> {
return new Promise((resolve, reject) => {
const user = new User({ discordID: discordid, uuid: uuid, inCalm: inCalm });
user
.save()
.then((savedUser) => {
resolve(savedUser);
})
.catch((err) => reject(err));
});
},
};