diff --git a/Commands/general/verify.ts b/Commands/general/verify.ts new file mode 100644 index 0000000..a16deab --- /dev/null +++ b/Commands/general/verify.ts @@ -0,0 +1,56 @@ +import { SlashCommandBuilder, EmbedBuilder, ChatInputCommandInteraction, User, Colors } from 'discord.js'; +import { DiscordClient } from '../../Utils/DiscordClient'; +import fs from 'fs'; +import { whisperChat } from '../../Utils/IngameChat'; +export const data = new SlashCommandBuilder() + .setName('verify') + .setDescription('Yerify yourself with the ingame bot') + .addStringOption((o) => o.setName(`code`).setDescription(`Put the code you recieved here.`).setRequired(true)) + +export function execute(interaction: ChatInputCommandInteraction, client: DiscordClient) { + const code = interaction.options.getString("code") || "null" + let pending = fs.readFileSync(__dirname + "/../../Verification/pendingVerification.json","utf-8"); + let done = fs.readFileSync(__dirname + "/../../Verification/doneVerification.json","utf-8"); + var pendingData = JSON.parse(pending); + var doneData = JSON.parse(done) + var user = `${interaction.user.username}#${interaction.user.discriminator}` + + if (pendingData.hasOwnProperty(code)){ + const embed = new EmbedBuilder() + embed.setColor(Colors.Green) + embed.setTitle(`Ok. The account ${user} is now linked to ${pendingData[code]}`) + interaction.reply({ + embeds: [embed], + ephemeral: true + }) + if (interaction.guild === null){ + return + } + // let verifiedRole =interaction.guild.roles.cache.find(r => r.id === client.config.guild.roles.verified) + // if (verifiedRole === undefined){ + // console.error("The verfied role doesnt exits or is not defined in the config") + // return + // } + // const usr = interaction.guild?.members.cache.find(m => m.id === interaction.user.username); + // usr?.roles.add(verifiedRole).catch(console.error) + + //Ingame Verification Message + const {bot} = client + whisperChat(bot,"Your Verification Process is done. You are now verified as " + user, pendingData[code]) + + doneData[user] = pendingData[code] + delete pendingData[code] + pendingData = JSON.stringify(pendingData) + doneData = JSON.stringify(doneData) + fs.writeFileSync(__dirname + "/../../Verification/pendingVerification.json",pendingData, { encoding: "utf-8" }) + fs.writeFileSync(__dirname + "/../../Verification/doneVerification.json",doneData, { encoding: "utf-8" }) + } else { + const embed = new EmbedBuilder() + embed.setColor(Colors.Red) + embed.setTitle("This code doesnt exist.") + interaction.reply({ + embeds: [embed], + ephemeral: true + }) + } + } \ No newline at end of file diff --git a/Commands/general/whois.ts b/Commands/general/whois.ts new file mode 100644 index 0000000..e62e379 --- /dev/null +++ b/Commands/general/whois.ts @@ -0,0 +1,51 @@ +import { SlashCommandBuilder, EmbedBuilder, ChatInputCommandInteraction, User, Colors } from 'discord.js'; +import { DiscordClient } from '../../Utils/DiscordClient'; +import fs from 'fs'; +function getKeyByValue(object, value) { + return Object.keys(object).find(key => object[key] === value); +} +export const data = new SlashCommandBuilder() + .setName('whois') + .setDescription('Lookup a user by their IGN or Discord Name') + .addStringOption((o) => o.setName(`type`).setDescription(`Lookup by minecraft or discord`).setRequired(true).addChoices({name:"Minecraft",value:"minecraft"},{name:"Discord",value:"discord"})) + .addStringOption((o) => o.setName(`user`).setDescription(`If you chose minecraft: IGN; if you chose discord: Username#Discriminator`).setRequired(true)) +export function execute(interaction: ChatInputCommandInteraction, client: DiscordClient) { + const type = interaction.options.getString("type") || "null" + const user = interaction.options.getString("user") || "null" + let users = fs.readFileSync(__dirname + "/../../Verification/doneVerification.json","utf-8"); + var usersData = JSON.parse(users) + const embed = new EmbedBuilder() + switch (type.toLowerCase()){ + case "minecraft":{ + let discord = getKeyByValue(usersData,user) + if (discord == undefined){ + embed.setColor(Colors.Red) + embed.setTitle(`The Minecraft Account ${user} has not been verified yet or doesnt exist`) + } else { + embed.setColor(Colors.Green) + embed.setTitle(`The Minecraft Account ${user} is linked to ${discord} on Discord.`) + } + break + } + case "discord":{ + if (usersData.hasOwnProperty(user)){ + let ingame = usersData[user] + embed.setColor(Colors.Green) + embed.setTitle(`The Account ${user} is linked to ${ingame} Ingame.`) + } else { + embed.setColor(Colors.Red) + embed.setTitle(`The Account ${user} has not been verified yet or doesnt exist`) + } + break + } + default:{ + embed.setColor(Colors.Red) + embed.setTitle("Please choose between the minecraft or the discord option when defining the type!") + break + } + } + interaction.reply({ + embeds: [embed], + ephemeral: true + }) +} \ No newline at end of file diff --git a/Minecraft/Bot.ts b/Minecraft/Bot.ts index 52f32da..2388d26 100644 --- a/Minecraft/Bot.ts +++ b/Minecraft/Bot.ts @@ -3,6 +3,7 @@ import { DiscordClient } from '../Utils/DiscordClient'; import { handleChat } from './Chat'; import { PlayerManager } from './PlayerManager'; import { ProfileCache } from './ProfileCache'; +import { handleIngameCommands } from './IngameCommands'; export function handleMinecraft(client: DiscordClient) { if (!client.config['in-game-bot'].enabled) return; // Returns if there is no bot config @@ -37,6 +38,7 @@ export function handleMinecraft(client: DiscordClient) { client.bot.on('connect', () => { console.log(`Connected to Server...`); handleChat(client); + handleIngameCommands(client); }); // Sends log message when the bot connects to the server } diff --git a/Minecraft/IngameCommands.ts b/Minecraft/IngameCommands.ts new file mode 100644 index 0000000..d332903 --- /dev/null +++ b/Minecraft/IngameCommands.ts @@ -0,0 +1,29 @@ +import { DiscordClient } from '../Utils/DiscordClient'; +import { makeid } from "../Utils/Hashing" +import { whisperChat } from "../Utils/IngameChat" +import fs from 'fs'; +export function handleIngameCommands(client: DiscordClient) { + const { bot } = client; + bot.on("player_chat", data =>{ + var message = String(data.plainMessage); + if (message.includes("?verify")){ + var username = JSON.parse(data.networkName).text + var code = makeid(10) + whisperChat(bot,"Your verification code is " + code + ". Use the /verify command in the discord to complete the verification.","Techfox") + verification(username,code) + } + + }) +} + + +function verification(username:string,hash:string){ + let datajson = fs.readFileSync(__dirname + "/../Verification/pendingVerification.json","utf-8"); + let data = JSON.parse(datajson); + data[hash] = username + data = JSON.stringify(data) + fs.writeFileSync(__dirname + "/../Verification/pendingVerification.json",data, { encoding: "utf-8" }) +} + + + diff --git a/Utils/Config.d.ts b/Utils/Config.d.ts index d8e8bb0..16a21a8 100644 --- a/Utils/Config.d.ts +++ b/Utils/Config.d.ts @@ -17,7 +17,7 @@ export type Config = { }, roles: { rwx: string, - rw: string + rw: string, } }, "in-game-bot": { diff --git a/Utils/Hashing.ts b/Utils/Hashing.ts new file mode 100644 index 0000000..ec2efe3 --- /dev/null +++ b/Utils/Hashing.ts @@ -0,0 +1,15 @@ +const { createHash } = require('crypto'); + +export function hash(string) { + return createHash('sha256').update(string).digest('hex'); +} + +export function makeid(length) { + var result = ''; + var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + var charactersLength = characters.length; + for ( var i = 0; i < length; i++ ) { + result += characters.charAt(Math.floor(Math.random() * charactersLength)); + } + return result; +} \ No newline at end of file diff --git a/Utils/IngameChat.ts b/Utils/IngameChat.ts new file mode 100644 index 0000000..37098ab --- /dev/null +++ b/Utils/IngameChat.ts @@ -0,0 +1,30 @@ +import { MinecraftClient } from "./MinecraftClient"; + +export function writeChat(bot: MinecraftClient,message:String){ + bot.write('chat_message', { + message: message, + timestamp: BigInt(Date.now()), + salt: 0, + signature: Buffer.alloc(0), + signedPreview: false, + previousMessages: [], + lastMessage: null + }); + + +} +export function whisperChat(bot: MinecraftClient,message:String,user:String){ + const command = `tell ${user} ${message}` + bot.write('chat_command', { + command: command, + timestamp: BigInt(Date.now()), + salt: 0, + argumentSignatures: [ + {argumentName:"targets",signature:Buffer.alloc(0)}, + {argumentName:"message",signature:Buffer.alloc(0)} + ], + signedPreview: false, + previousMessages: [], + lastMessage: null + }); +} \ No newline at end of file diff --git a/Verification/doneVerification.json b/Verification/doneVerification.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/Verification/doneVerification.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/Verification/pendingVerification.json b/Verification/pendingVerification.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/Verification/pendingVerification.json @@ -0,0 +1 @@ +{} \ No newline at end of file