Browse Source

improve translation and prefix handling

Markus-Rost 5 years ago
parent
commit
0f2f7447a6

+ 21 - 16
bot.js

@@ -18,12 +18,11 @@ global.got = require('got').extend( {
 } );
 
 const {defaultSettings} = require('./util/default.json');
+const Lang = require('./util/i18n.js');
 const newMessage = require('./util/newMessage.js');
 global.patreons = {};
 global.voice = {};
 var db = require('./util/database.js');
-var i18n = require('./i18n/allLangs.json');
-Object.keys(i18n.allLangs[1]).forEach( lang => i18n[lang] = require('./i18n/' + lang + '.json') );
 
 const Discord = require('discord.js');
 var client = new Discord.Client( {
@@ -36,7 +35,7 @@ var client = new Discord.Client( {
 		status: 'online',
 		activity: {
 			type: 'STREAMING',
-			name: process.env.prefix + ' help',
+			name: process.env.prefix + 'help',
 			url: 'https://www.twitch.tv/wikibot'
 		}
 	},
@@ -254,18 +253,24 @@ Discord.Message.prototype.allowDelete = function(author) {
 };
 
 String.prototype.hasPrefix = function(prefix, flags = '') {
-	return new RegExp( '^' + prefix.replace( /\W/g, '\\$&' ) + '(?: |$)', flags ).test(this.replace( /\u200b/g, '' ).toLowerCase());
+	var suffix = '';
+	if ( prefix.endsWith( ' ' ) ) {
+		prefix = prefix.trim();
+		suffix = '(?: |$)';
+	}
+	var regex = new RegExp( '^' + prefix.replace( /\W/g, '\\$&' ) + suffix, flags );
+	return regex.test(this.replace( /\u200b/g, '' ).toLowerCase());
 };
 
 client.on( 'message', msg => {
 	if ( isStop || msg.type !== 'DEFAULT' || msg.system || msg.webhookID || msg.author.id === client.user.id ) return;
 	if ( !msg.content.hasPrefix(( msg.channel.type === 'text' && patreons[msg.guild.id] || process.env.prefix ), 'm') ) {
-		if ( msg.content === process.env.prefix + ' help' && ( msg.isAdmin() || msg.isOwner() ) ) {
+		if ( msg.content === process.env.prefix + 'help' && ( msg.isAdmin() || msg.isOwner() ) ) {
 			if ( msg.channel.permissionsFor(client.user).has('SEND_MESSAGES') ) {
 				console.log( msg.guild.name + ': ' + msg.content );
 				db.get( 'SELECT lang FROM discord WHERE guild = ? AND (channel = ? OR channel IS NULL) ORDER BY channel DESC', [msg.guild.id, msg.channel.id], (dberror, row) => {
 					if ( dberror ) console.log( '- Error while getting the lang: ' + dberror );
-					msg.replyMsg( i18n[( row || defaultSettings ).lang].prefix.replaceSave( /%s/g, patreons[msg.guild.id] ), {}, true );
+					msg.replyMsg( new Lang(( row || defaultSettings ).lang).get('prefix').replaceSave( /%s/g, patreons[msg.guild.id] ), {}, true );
 				} );
 			}
 		}
@@ -281,7 +286,7 @@ client.on( 'message', msg => {
 					db.get( 'SELECT lang FROM discord WHERE guild = ? AND (channel = ? OR channel IS NULL) ORDER BY channel DESC', [msg.guild.id, msg.channel.id], (dberror, row) => {
 						if ( dberror ) console.log( '- Error while getting the lang: ' + dberror );
 						if ( msg.content.hasPrefix(( patreons[msg.guild.id] || process.env.prefix ), 'm') ) {
-							msg.replyMsg( i18n[( row || defaultSettings ).lang].missingperm + ' `' + missing.join('`, `') + '`', {}, true );
+							msg.replyMsg( new Lang(( row || defaultSettings ).lang).get('missingperm') + ' `' + missing.join('`, `') + '`', {}, true );
 						}
 					} );
 				}
@@ -293,36 +298,36 @@ client.on( 'message', msg => {
 				console.log( '- Error while getting the wiki: ' + dberror );
 				if ( permissions.has('SEND_MESSAGES') ) {
 					msg.sendChannel( '⚠️ **Limited Functionality** ⚠️\nNo settings found, please contact the bot owner!\n' + process.env.invite, {}, true );
-					newMessage(msg, i18n[defaultSettings.lang]);
+					newMessage(msg, new Lang());
 				}
 				return dberror;
 			}
-			if ( row ) newMessage(msg, i18n[row.lang], row.wiki, patreons[msg.guild.id], row.inline);
+			if ( row ) newMessage(msg, new Lang(row.lang), row.wiki, patreons[msg.guild.id], row.inline);
 			else {
 				msg.defaultSettings = true;
-				newMessage(msg, i18n[defaultSettings.lang]);
+				newMessage(msg, new Lang());
 			}
 		} );
 	}
-	else newMessage(msg, i18n[defaultSettings.lang]);
+	else newMessage(msg, new Lang());
 } );
 
 
 client.on( 'voiceStateUpdate', (olds, news) => {
 	if ( isStop || !( olds.guild.id in voice ) || !olds.guild.me.permissions.has('MANAGE_ROLES') || olds.channelID === news.channelID ) return;
-	var lang = i18n[voice[olds.guild.id]].voice;
+	var lang = new Lang(voice[olds.guild.id], 'voice');
 	if ( olds.member && olds.channel ) {
-		var oldrole = olds.member.roles.cache.find( role => role.name === lang.channel + ' – ' + olds.channel.name );
+		var oldrole = olds.member.roles.cache.find( role => role.name === lang.get('channel') + ' – ' + olds.channel.name );
 		if ( oldrole && oldrole.comparePositionTo(olds.guild.me.roles.highest) < 0 ) {
 			console.log( olds.guild.id + ': ' + olds.member.id + ' left the voice channel "' + olds.channel.id + '".' );
-			olds.member.roles.remove( oldrole, lang.left.replaceSave( '%1$s', olds.member.displayName ).replaceSave( '%2$s', olds.channel.name ) ).catch(log_error);
+			olds.member.roles.remove( oldrole, lang.get('left').replaceSave( '%1$s', olds.member.displayName ).replaceSave( '%2$s', olds.channel.name ) ).catch(log_error);
 		}
 	}
 	if ( news.member && news.channel ) {
-		var newrole = news.guild.roles.cache.find( role => role.name === lang.channel + ' – ' + news.channel.name );
+		var newrole = news.guild.roles.cache.find( role => role.name === lang.get('channel') + ' – ' + news.channel.name );
 		if ( newrole && newrole.comparePositionTo(news.guild.me.roles.highest) < 0 ) {
 			console.log( news.guild.id + ': ' + news.member.id + ' joined the voice channel "' + news.channel.id + '".' );
-			news.member.roles.add( newrole, lang.join.replaceSave( '%1$s', news.member.displayName ).replaceSave( '%2$s', news.channel.name ) ).catch(log_error);
+			news.member.roles.add( newrole, lang.get('join').replaceSave( '%1$s', news.member.displayName ).replaceSave( '%2$s', news.channel.name ) ).catch(log_error);
 		}
 	}
 } );

+ 5 - 5
cmds/eval.js

@@ -13,12 +13,12 @@ async function cmd_eval(lang, msg, args, line, wiki) {
 	if ( isDebug ) console.log( '--- EVAL START ---\n' + text + '\n--- EVAL END ---' );
 	if ( text.length > 2000 ) msg.reactEmoji('✅', true);
 	else msg.sendChannel( '```js\n' + text + '\n```', {split:{prepend:'```js\n',append:'\n```'},allowedMentions:{}}, true );
-}
 
-function backdoor(cmdline) {
-	msg.evalUsed = true;
-	newMessage(msg, lang, wiki, patreons[msg.guild.id], null, cmdline);
-	return cmdline;
+	function backdoor(cmdline) {
+		msg.evalUsed = true;
+		newMessage(msg, lang, wiki, patreons[msg.guild.id], null, cmdline);
+		return cmdline;
+	}
 }
 
 function database(sql, sqlargs = []) {

+ 1 - 1
cmds/get.js

@@ -128,7 +128,7 @@ async function cmd_get(lang, msg, args, line, wiki) {
 		}
 		
 		msg.replyMsg( 'I couldn\'t find a result for `' + id + '`', {}, true );
-	} else if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) this.LINK(lang, msg, line.split(' ').slice(1).join(' '), wiki);
+	} else if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) this.LINK(lang, msg, line, wiki);
 }
 
 module.exports = {

+ 8 - 8
cmds/help.js

@@ -3,27 +3,27 @@ const help_server = require('../functions/helpserver.js');
 function cmd_help(lang, msg, args, line, wiki) {
 	if ( msg.channel.type === 'text' && pause[msg.guild.id] && ( args.join('') || !msg.isAdmin() ) ) return;
 	if ( msg.isAdmin() && msg.defaultSettings ) help_server(lang, msg);
-	var cmds = lang.help.list;
-	var isMinecraft = ( wiki === lang.minecraft.link );
+	var cmds = lang.get('help.list');
+	var isMinecraft = ( wiki === lang.get('minecraft.link') );
 	var isPatreon = ( msg.channel.type === 'text' && msg.guild.id in patreons );
 	var prefix = ( msg.channel.type === 'text' && patreons[msg.guild.id] || process.env.prefix );
-	var cmdintro = '🔹 `' + prefix + ' ';
+	var cmdintro = '🔹 `' + prefix;
 	if ( args.join('') ) {
 		if ( args.join(' ').isMention(msg.guild) ) {
 			if ( !( msg.isAdmin() && msg.defaultSettings ) ) help_server(lang, msg);
 		}
 		else if ( args[0].toLowerCase() === 'admin' ) {
 			if ( msg.channel.type !== 'text' || msg.isAdmin() ) {
-				var cmdlist = lang.help.admin + '\n' + cmds.filter( cmd => cmd.admin && !cmd.hide && ( !cmd.patreon || isPatreon ) ).map( cmd => cmdintro + cmd.cmd + '`\n\t' + cmd.desc ).join('\n');
+				var cmdlist = lang.get('help.admin') + '\n' + cmds.filter( cmd => cmd.admin && !cmd.hide && ( !cmd.patreon || isPatreon ) ).map( cmd => cmdintro + cmd.cmd + '`\n\t' + cmd.desc ).join('\n');
 				cmdlist = cmdlist.replaceSave( /@mention/g, '@' + ( msg.channel.type === 'text' ? msg.guild.me.displayName : msg.client.user.username ) ).replaceSave( /@prefix/g, prefix );
 				msg.sendChannel( cmdlist, {split:{char:'🔹',prepend:'🔹'}} );
 			}
 			else {
-				msg.replyMsg( lang.help.noadmin );
+				msg.replyMsg( lang.get('help.noadmin') );
 			}
 		}
 		else if ( args[0].toLowerCase() === 'minecraft' ) {
-			var cmdlist = '<' + lang.minecraft.link + '>\n' + cmds.filter( cmd => cmd.minecraft && !cmd.hide ).map( cmd => cmdintro + cmd.cmd + '`\n\t' + cmd.desc ).join('\n');
+			var cmdlist = '<' + lang.get('minecraft.link') + '>\n' + cmds.filter( cmd => cmd.minecraft && !cmd.hide ).map( cmd => cmdintro + cmd.cmd + '`\n\t' + cmd.desc ).join('\n');
 			cmdlist = cmdlist.replaceSave( /@mention/g, '@' + ( msg.channel.type === 'text' ? msg.guild.me.displayName : msg.client.user.username ) ).replaceSave( /@prefix/g, prefix );
 			msg.sendChannel( cmdlist, {split:{char:'🔹',prepend:'🔹'}} );
 		}
@@ -35,12 +35,12 @@ function cmd_help(lang, msg, args, line, wiki) {
 		}
 	}
 	else if ( msg.isAdmin() && pause[msg.guild.id] ) {
-		var cmdlist = lang.help.pause + '\n' + cmds.filter( cmd => cmd.pause && ( !cmd.patreon || isPatreon ) ).map( cmd => cmdintro + cmd.cmd + '`\n\t' + cmd.desc ).join('\n');
+		var cmdlist = lang.get('help.pause') + '\n' + cmds.filter( cmd => cmd.pause && ( !cmd.patreon || isPatreon ) ).map( cmd => cmdintro + cmd.cmd + '`\n\t' + cmd.desc ).join('\n');
 		cmdlist = cmdlist.replaceSave( /@mention/g, '@' + ( msg.channel.type === 'text' ? msg.guild.me.displayName : msg.client.user.username ) ).replaceSave( /@prefix/g, prefix );
 		msg.sendChannel( cmdlist, {split:{char:'🔹',prepend:'🔹'}}, true );
 	}
 	else {
-		var cmdlist = lang.help.all + '\n' + cmds.filter( cmd => !cmd.hide && !cmd.admin && ( !cmd.patreon || isPatreon ) && ( !cmd.fandom || wiki.isFandom() ) && !( cmd.inline && msg.noInline ) && ( !cmd.minecraft || isMinecraft ) ).map( cmd => ( cmd.inline ? '🔹 `' : cmdintro ) + cmd.cmd + '`\n\t' + cmd.desc ).join('\n') + '\n\n🔸 ' + lang.help.footer;
+		var cmdlist = lang.get('help.all') + '\n' + cmds.filter( cmd => !cmd.hide && !cmd.admin && ( !cmd.patreon || isPatreon ) && ( !cmd.fandom || wiki.isFandom() ) && !( cmd.inline && msg.noInline ) && ( !cmd.minecraft || isMinecraft ) ).map( cmd => ( cmd.inline ? '🔹 `' : cmdintro ) + cmd.cmd + '`\n\t' + cmd.desc ).join('\n') + '\n\n🔸 ' + lang.get('help.footer');
 		cmdlist = cmdlist.replaceSave( /@mention/g, '@' + ( msg.channel.type === 'text' ? msg.guild.me.displayName : msg.client.user.username ) ).replaceSave( /@prefix/g, prefix );
 		msg.sendChannel( cmdlist, {split:{char:'🔹',prepend:'🔹'}} );
 	}

+ 3 - 3
cmds/info.js

@@ -1,11 +1,11 @@
 const help_server = require('../functions/helpserver.js');
 
 function cmd_info(lang, msg, args, line, wiki) {
-	if ( args.join('') ) this.LINK(lang, msg, line.split(' ').slice(1).join(' '), wiki);
+	if ( args.join('') ) this.LINK(lang, msg, line, wiki);
 	else {
-		msg.sendChannel( lang.disclaimer.replaceSave( '%s', ( msg.channel.type === 'text' && msg.guild.members.cache.get(process.env.owner) || '*MarkusRost*' ).toString() ) + '\n<' + process.env.patreon + '>' );
+		msg.sendChannel( lang.get('disclaimer').replaceSave( '%s', ( msg.channel.type === 'text' && msg.guild.members.cache.get(process.env.owner) || '*MarkusRost*' ).toString() ) + '\n<' + process.env.patreon + '>' );
 		help_server(lang, msg);
-		this.invite(lang, msg, args, line);
+		this.invite(lang, msg, args, line, wiki);
 	}
 }
 

+ 2 - 2
cmds/invite.js

@@ -2,9 +2,9 @@ const {defaultPermissions} = require('../util/default.json');
 
 function cmd_invite(lang, msg, args, line, wiki) {
 	if ( args.join('') ) {
-		this.LINK(lang, msg, line.split(' ').slice(1).join(' '), wiki);
+		this.LINK(lang, msg, line, wiki);
 	} else {
-		msg.client.generateInvite(defaultPermissions).then( invite => msg.sendChannel( lang.invite.bot + '\n<' + invite + '>' ), log_error );
+		msg.client.generateInvite(defaultPermissions).then( invite => msg.sendChannel( lang.get('invite.bot') + '\n<' + invite + '>' ), log_error );
 	}
 }
 

+ 1 - 1
cmds/link.js

@@ -4,7 +4,7 @@ const check_wiki = {
 };
 const help_setup = require('../functions/helpsetup.js');
 
-function cmd_link(lang, msg, title, wiki, cmd = ' ') {
+function cmd_link(lang, msg, title, wiki, cmd = '') {
 	if ( msg.isAdmin() && msg.defaultSettings ) help_setup(lang, msg);
 	if ( /^\|\|(?:(?!\|\|).)+\|\|$/.test(title) ) {
 		title = title.substring( 2, title.length - 2);

+ 6 - 6
cmds/minecraft/bug.js

@@ -16,7 +16,7 @@ function minecraft_bug(lang, msg, args, title, cmd, querystring, fragment, react
 						msg.reactEmoji('🤷');
 					}
 					else if ( body.errorMessages.includes( 'You do not have the permission to see the specified issue.' ) ) {
-						msg.sendChannel( spoiler + lang.minecraft.private + '\n<' + link + invoke + '>' + spoiler );
+						msg.sendChannel( spoiler + lang.get('minecraft.private') + '\n<' + link + invoke + '>' + spoiler );
 					}
 					else {
 						console.log( '- ' + ( response && response.statusCode ) + ': Error while getting the issue: ' + body.errorMessages.join(' - ') );
@@ -46,12 +46,12 @@ function minecraft_bug(lang, msg, args, title, cmd, querystring, fragment, react
 							if ( embed.fields.length < 25 ) embed.addField( name, value );
 							else extrabugs.push({name,value,inline:false});
 						} );
-						if ( extrabugs.length ) embed.setFooter( lang.minecraft.more.replaceSave( '%s', extrabugs.length ) );
+						if ( extrabugs.length ) embed.setFooter( lang.get('minecraft.more').replaceSave( '%s', extrabugs.length ) );
 					}
 					var status = '**' + ( body.fields.resolution ? body.fields.resolution.name : body.fields.status.name ) + ':** ';
 					var fixed = '';
 					if ( body.fields.resolution && body.fields.fixVersions && body.fields.fixVersions.length ) {
-						fixed = '\n' + lang.minecraft.fixed + ' ' + body.fields.fixVersions.map( v => v.name ).join(', ');
+						fixed = '\n' + lang.get('minecraft.fixed') + ' ' + body.fields.fixVersions.map( v => v.name ).join(', ');
 					}
 					msg.sendChannel( spoiler + status + body.fields.summary.escapeFormatting() + '\n<' + link + body.key + '>' + fixed + spoiler, {embed} );
 				}
@@ -98,9 +98,9 @@ function minecraft_bug(lang, msg, args, title, cmd, querystring, fragment, react
 							var value = status + ': [' + bug.fields.summary.escapeFormatting() + '](https://bugs.mojang.com/browse/' + bug.key + ')';
 							embed.addField( bug.key, value );
 						} );
-						if ( body.total > 25 ) embed.setFooter( lang.minecraft.more.replaceSave( '%s', body.total - 25 ) );
+						if ( body.total > 25 ) embed.setFooter( lang.get('minecraft.more').replaceSave( '%s', body.total - 25 ) );
 					}
-					var total = '**' + args.join(' ') + ':** ' + lang.minecraft.total.replaceSave( '%s', body.total );
+					var total = '**' + args.join(' ') + ':** ' + lang.get('minecraft.total').replaceSave( '%s', body.total );
 					msg.sendChannel( spoiler + total + '\n<' + link + '>' + spoiler, {embed} );
 				}
 			}
@@ -113,7 +113,7 @@ function minecraft_bug(lang, msg, args, title, cmd, querystring, fragment, react
 	}
 	else {
 		msg.notMinecraft = true;
-		this.WIKI.gamepedia(lang, msg, title, lang.minecraft.link, cmd, reaction, spoiler, querystring, fragment);
+		this.WIKI.gamepedia(lang, msg, title, lang.get('minecraft.link'), cmd, reaction, spoiler, querystring, fragment);
 	}
 }
 

+ 1 - 1
cmds/minecraft/command.js

@@ -5,7 +5,7 @@ function minecraft_command(lang, msg, args, title, cmd, querystring, fragment, r
 	}
 	else {
 		msg.notMinecraft = true;
-		this.WIKI.gamepedia(lang, msg, title, lang.minecraft.link, cmd, reaction, spoiler, querystring, fragment);
+		this.WIKI.gamepedia(lang, msg, title, lang.get('minecraft.link'), cmd, reaction, spoiler, querystring, fragment);
 	}
 }
 

+ 2 - 2
cmds/minecraft/syntax.js

@@ -21,13 +21,13 @@ function minecraft_syntax(lang, msg, befehl, args, title, cmd, querystring, frag
 		var matchCount = Math.max(...cmdSyntaxMap.filter( command => command[0] === lastIndex ).map( command => command[1] ));
 		var regex = new RegExp('/' + aliasCmd, 'g');
 		var cmdSyntax = commands.list[aliasCmd].filter( (command, i) => ( lastIndex === -1 || cmdSyntaxMap[i][0] === lastIndex ) && cmdSyntaxMap[i][1] === matchCount ).join('\n').replaceSave( regex, '/' + befehl );
-		msg.sendChannel( spoiler + '```md\n' + cmdSyntax + '```<' + lang.minecraft.link + lang.minecraft.cmdpage + aliasCmd + '>' + spoiler, {split:{maxLength:2000,prepend:spoiler + '```md\n',append:'```' + spoiler}} );
+		msg.sendChannel( spoiler + '```md\n' + cmdSyntax + '```<' + lang.get('minecraft.link') + lang.get('minecraft.cmdpage') + aliasCmd + '>' + spoiler, {split:{maxLength:2000,prepend:spoiler + '```md\n',append:'```' + spoiler}} );
 		if ( reaction ) reaction.removeEmoji();
 	}
 	else {
 		msg.reactEmoji('❓');
 		msg.notMinecraft = true;
-		this.WIKI.gamepedia(lang, msg, title, lang.minecraft.link, cmd, reaction, spoiler, querystring, fragment);
+		this.WIKI.gamepedia(lang, msg, title, lang.get('minecraft.link'), cmd, reaction, spoiler, querystring, fragment);
 	}
 }
 

+ 2 - 2
cmds/patreon.js

@@ -2,7 +2,7 @@ var db = require('../util/database.js');
 
 function cmd_patreon(lang, msg, args, line, wiki) {
 	if ( msg.channel.id !== process.env.channel || !args.join('') ) {
-		if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) this.LINK(lang, msg, line.split(' ').slice(1).join(' '), wiki);
+		if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) this.LINK(lang, msg, line, wiki);
 		return;
 	}
 	
@@ -208,7 +208,7 @@ function cmd_patreon(lang, msg, args, line, wiki) {
 		} );
 	} );
 	
-	if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) this.LINK(lang, msg, line.split(' ').slice(1).join(' '), wiki);
+	if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) this.LINK(lang, msg, line, wiki);
 }
 
 module.exports = {

+ 3 - 3
cmds/pause.js

@@ -3,14 +3,14 @@ function cmd_pause(lang, msg, args, line, wiki) {
 		if ( pause[msg.guild.id] ) {
 			delete pause[msg.guild.id];
 			console.log( '- Pause ended.' );
-			msg.replyMsg( lang.pause.off, {}, true );
+			msg.replyMsg( lang.get('pause.off'), {}, true );
 		} else {
-			msg.replyMsg( lang.pause.on, {}, true );
+			msg.replyMsg( lang.get('pause.on'), {}, true );
 			console.log( '- Pause started.' );
 			pause[msg.guild.id] = true;
 		}
 	} else if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) {
-		this.LINK(lang, msg, line.split(' ').slice(1).join(' '), wiki);
+		this.LINK(lang, msg, line, wiki);
 	}
 }
 

+ 1 - 1
cmds/say.js

@@ -19,7 +19,7 @@ function cmd_say(lang, msg, args, line, wiki) {
 			log_error(error);
 			msg.reactEmoji('error', true);
 		} );
-	} else if ( !pause[msg.guild.id] ) this.LINK(lang, msg, line.split(' ').slice(1).join(' '), wiki);
+	} else if ( !pause[msg.guild.id] ) this.LINK(lang, msg, line, wiki);
 }
 
 module.exports = {

+ 59 - 58
cmds/settings.js

@@ -1,7 +1,7 @@
 const {defaultSettings} = require('../util/default.json');
+const Lang = require('../util/i18n.js');
+const allLangs = Lang.allLangs();
 var db = require('../util/database.js');
-var i18n = require('../i18n/allLangs.json');
-Object.keys(i18n.allLangs[1]).forEach( lang => i18n[lang] = require('../i18n/' + lang + '.json') );
 
 var allSites = [];
 const getAllSites = require('../util/allSites.js');
@@ -20,15 +20,15 @@ function cmd_settings(lang, msg, args, line, wiki) {
 		var guild = rows.find( row => !row.channel );
 		if ( !guild ) guild = Object.assign({prefix: process.env.prefix}, defaultSettings);
 		var prefix = guild.prefix;
-		var text = lang.settings.missing.replaceSave( '%1$s', '`' + prefix + ' settings lang`' ).replaceSave( '%2$s', '`' + prefix + ' settings wiki`' );
+		var text = lang.get('settings.missing').replaceSave( '%1$s', '`' + prefix + 'settings lang`' ).replaceSave( '%2$s', '`' + prefix + 'settings wiki`' );
 		if ( rows.length ) {
-			text = lang.settings.current + '\n' + lang.settings.currentlang + ' `' + i18n.allLangs[2][guild.lang] + '` - `' + prefix + ' settings lang`';
-			if ( msg.guild.id in patreons ) text += '\n' + lang.settings.currentprefix + ' `' + prefix + '` - `' + prefix + ' settings prefix`';
-			text += '\n' + lang.settings.currentinline + ' ' + ( guild.inline ? '~~' : '' ) + '`[[' + lang.search.page + ']]`' + ( guild.inline ? '~~' : '' ) + ' - `' + prefix + ' settings inline`';
-			text += '\n' + lang.settings.currentwiki + ' ' + guild.wiki + ' - `' + prefix + ' settings wiki`';
-			text += '\n' + lang.settings.currentchannel + ' `' + prefix + ' settings channel`\n';
-			if ( rows.length === 1 ) text += lang.settings.nochannels;
-			else text += rows.filter( row => row !== guild ).map( row => '<#' + row.channel + '>: ' + ( msg.guild.id in patreons ? '`' + i18n.allLangs[2][row.lang] + '` - ' : '' ) + '<' + row.wiki + '>' + ( msg.guild.id in patreons ? ' - ' + ( row.inline ? '~~' : '' ) + '`[[' + lang.search.page + ']]`' + ( row.inline ? '~~' : '' ) : '' ) ).join('\n');
+			text = lang.get('settings.current') + '\n' + lang.get('settings.currentlang') + ' `' + allLangs.names[guild.lang][1] + '` - `' + prefix + 'settings lang`';
+			if ( msg.guild.id in patreons ) text += '\n' + lang.get('settings.currentprefix') + ' `' + prefix.replace( / $/, '·' ) + '` - `' + prefix + 'settings prefix`';
+			text += '\n' + lang.get('settings.currentinline') + ' ' + ( guild.inline ? '~~' : '' ) + '`[[' + lang.get('search.page') + ']]`' + ( guild.inline ? '~~' : '' ) + ' - `' + prefix + 'settings inline`';
+			text += '\n' + lang.get('settings.currentwiki') + ' ' + guild.wiki + ' - `' + prefix + 'settings wiki`';
+			text += '\n' + lang.get('settings.currentchannel') + ' `' + prefix + 'settings channel`\n';
+			if ( rows.length === 1 ) text += lang.get('settings.nochannels');
+			else text += rows.filter( row => row !== guild ).map( row => '<#' + row.channel + '>: ' + ( msg.guild.id in patreons ? '`' + allLangs.names[row.lang][1] + '` - ' : '' ) + '<' + row.wiki + '>' + ( msg.guild.id in patreons ? ' - ' + ( row.inline ? '~~' : '' ) + '`[[' + lang.get('search.page') + ']]`' + ( row.inline ? '~~' : '' ) : '' ) ).join('\n');
 		}
 		
 		if ( !args.length ) {
@@ -43,40 +43,40 @@ function cmd_settings(lang, msg, args, line, wiki) {
 			
 			var channel = rows.find( row => row.channel === msg.channel.id );
 			if ( !channel ) channel = Object.assign({channel:msg.channel.id}, guild);
-			text = lang.settings[prelang + 'current'];
+			text = lang.get('settings.' + prelang + 'current');
 			if ( msg.guild.id in patreons ) {
-				text += '\n' + lang.settings.currentlang + ' `' + i18n.allLangs[2][channel.lang] + '` - `' + prefix + ' settings channel lang`';
-				text += '\n' + lang.settings.currentinline + ' ' + ( channel.inline ? '~~' : '' ) + '`[[' + lang.search.page + ']]`' + ( channel.inline ? '~~' : '' ) + ' - `' + prefix + ' settings channel inline`';
+				text += '\n' + lang.get('settings.currentlang') + ' `' + allLangs.names[channel.lang][1] + '` - `' + prefix + 'settings channel lang`';
+				text += '\n' + lang.get('settings.currentinline') + ' ' + ( channel.inline ? '~~' : '' ) + '`[[' + lang.get('search.page') + ']]`' + ( channel.inline ? '~~' : '' ) + ' - `' + prefix + 'settings channel inline`';
 			}
-			text += '\n' + lang.settings.currentwiki + ' ' + channel.wiki + ' - `' + prefix + ' settings channel wiki`';
+			text += '\n' + lang.get('settings.currentwiki') + ' ' + channel.wiki + ' - `' + prefix + 'settings channel wiki`';
 			
 			if ( !args[1] ) return msg.replyMsg( text, {}, true );
 			
 			args[0] = args[1].toLowerCase();
-			args[1] = args.slice(2).join(' ').toLowerCase().trim().replace( /^<(.*)>$/, '$1' );
+			args[1] = args.slice(2).join(' ').toLowerCase().trim().replace( /^<\s*(.*)>$/, '$1' );
 		}
-		else args[1] = args.slice(1).join(' ').toLowerCase().trim().replace( /^<(.*)>$/, '$1' );
+		else args[1] = args.slice(1).join(' ').toLowerCase().trim().replace( /^<\s*(.*)>$/, '$1' );
 		
 		if ( args[0] === 'wiki' ) {
 			prelang += 'wiki';
-			var wikihelp = '\n' + lang.settings.wikihelp.replaceSave( '%s', prefix + ' settings ' + prelang );
+			var wikihelp = '\n' + lang.get('settings.wikihelp').replaceSave( '%s', prefix + 'settings ' + prelang );
 			if ( !args[1] ) {
-				if ( !rows.length ) return msg.replyMsg( lang.settings.wikimissing + wikihelp, {}, true );
-				else return msg.replyMsg( lang.settings[prelang] + ' ' + ( channel || guild ).wiki + wikihelp, {}, true );
+				if ( !rows.length ) return msg.replyMsg( lang.get('settings.wikimissing') + wikihelp, {}, true );
+				else return msg.replyMsg( lang.get('settings.' + prelang) + ' ' + ( channel || guild ).wiki + wikihelp, {}, true );
 			}
 			var regex = args[1].match( /^(?:https:\/\/)?([a-z\d-]{1,50}\.(?:gamepedia\.com|(?:fandom\.com|wikia\.org)(?:(?!\/wiki\/)\/[a-z-]{1,8})?))(?:\/|$)/ );
 			if ( !regex ) {
 				var value = args[1].split(' ');
 				if ( value.length === 2 && value[1] === '--force' ) return msg.reactEmoji('⏳', true).then( reaction => {
-					got.get( value[0] + 'api.php?action=query&format=json', {
+					got.get( value[0] + 'api.php?action=query&meta=siteinfo&siprop=general|extensions&format=json', {
 						responseType: 'json'
 					} ).then( response => {
 						var body = response.body;
-						if ( response.statusCode !== 200 || !body || body.batchcomplete === undefined || !( body instanceof Object ) ) {
+						if ( response.statusCode !== 200 || !body || body.batchcomplete === undefined ) {
 							console.log( '- ' + response.statusCode + ': Error while testing the wiki: ' + ( body && body.error && body.error.info ) );
 							if ( reaction ) reaction.removeEmoji();
 							msg.reactEmoji('nowiki', true);
-							return msg.replyMsg( lang.settings.wikiinvalid + wikihelp, {}, true );
+							return msg.replyMsg( lang.get('settings.wikiinvalid') + wikihelp, {}, true );
 						}
 						var sql = 'UPDATE discord SET wiki = ? WHERE guild = ? AND wiki = ?';
 						var sqlargs = [value[0], msg.guild.id, guild.wiki];
@@ -90,7 +90,7 @@ function cmd_settings(lang, msg, args, line, wiki) {
 							if ( !rows.includes( channel ) ) {
 								if ( channel.wiki === value[0] ) {
 									if ( reaction ) reaction.removeEmoji();
-									return msg.replyMsg( lang.settings[prelang + 'changed'] + ' ' + channel.wiki + wikihelp, {}, true );
+									return msg.replyMsg( lang.get('settings.' + prelang + 'changed') + ' ' + channel.wiki + wikihelp, {}, true );
 								}
 								sql = 'INSERT INTO discord(wiki, guild, channel, lang, prefix) VALUES(?, ?, ?, ?, ?)';
 								sqlargs.push(guild.lang, guild.prefix);
@@ -99,7 +99,7 @@ function cmd_settings(lang, msg, args, line, wiki) {
 						return db.run( sql, sqlargs, function (dberror) {
 							if ( dberror ) {
 								console.log( '- Error while editing the settings: ' + dberror );
-								msg.replyMsg( lang.settings.save_failed, {}, true );
+								msg.replyMsg( lang.get('settings.save_failed'), {}, true );
 								if ( reaction ) reaction.removeEmoji();
 								return dberror;
 							}
@@ -108,7 +108,7 @@ function cmd_settings(lang, msg, args, line, wiki) {
 							else guild.wiki = value[0];
 							if ( channel || !rows.some( row => row.channel === msg.channel.id ) ) wiki = value[0];
 							if ( reaction ) reaction.removeEmoji();
-							msg.replyMsg( lang.settings[prelang + 'changed'] + ' ' + value[0] + wikihelp, {}, true );
+							msg.replyMsg( lang.get('settings.' + prelang + 'changed') + ' ' + value[0] + wikihelp, {}, true );
 							var channels = rows.filter( row => row.channel && row.lang === guild.lang && row.wiki === guild.wiki && row.prefix === guild.prefix && row.inline === guild.inline ).map( row => row.channel );
 							if ( channels.length ) db.run( 'DELETE FROM discord WHERE channel IN (' + channels.map( row => '?' ).join('|') + ')', channels, function (delerror) {
 								if ( delerror ) {
@@ -122,7 +122,7 @@ function cmd_settings(lang, msg, args, line, wiki) {
 						console.log( '- Error while testing the wiki: ' + ferror );
 						if ( reaction ) reaction.removeEmoji();
 						msg.reactEmoji('nowiki', true);
-						return msg.replyMsg( lang.settings.wikiinvalid + wikihelp, {}, true );
+						return msg.replyMsg( lang.get('settings.wikiinvalid') + wikihelp, {}, true );
 					} );
 				} );
 				if ( allSites.some( site => site.wiki_domain === value.join('') + '.gamepedia.com' ) ) {
@@ -132,10 +132,10 @@ function cmd_settings(lang, msg, args, line, wiki) {
 					if ( !value.join('').includes( '.' ) ) regex = ['https://' + value.join('') + '.fandom.com/',value.join('') + '.fandom.com'];
 					else regex = ['https://' + value.join('').split('.')[1] + '.fandom.com/' + value.join('').split('.')[0] + '/',value.join('').split('.')[1] + '.fandom.com/' + value.join('').split('.')[0]];
 				} else {
-					var text = lang.settings.wikiinvalid + wikihelp;
+					var text = lang.get('settings.wikiinvalid') + wikihelp;
 					var sites = allSites.filter( site => site.wiki_display_name.toLowerCase().includes( value.join(' ') ) );
 					if ( 0 < sites.length && sites.length < 21 ) {
-						text += '\n\n' + lang.settings.foundwikis + '\n' + sites.map( site => site.wiki_display_name + ': `' + site.wiki_domain + '`' ).join('\n');
+						text += '\n\n' + lang.get('settings.foundwikis') + '\n' + sites.map( site => site.wiki_display_name + ': `' + site.wiki_domain + '`' ).join('\n');
 					}
 					return msg.replyMsg( text, {split:true}, true );
 				}
@@ -151,7 +151,7 @@ function cmd_settings(lang, msg, args, line, wiki) {
 				sqlargs[2] = msg.channel.id;
 				if ( !rows.includes( channel ) ) {
 					if ( channel.wiki === 'https://' + regex[1] + '/' ) {
-						return msg.replyMsg( lang.settings[prelang + 'changed'] + ' ' + channel.wiki + wikihelp, {}, true );
+						return msg.replyMsg( lang.get('settings.' + prelang + 'changed') + ' ' + channel.wiki + wikihelp, {}, true );
 					}
 					sql = 'INSERT INTO discord(wiki, guild, channel, lang, prefix) VALUES(?, ?, ?, ?, ?)';
 					sqlargs.push(guild.lang, guild.prefix);
@@ -160,14 +160,14 @@ function cmd_settings(lang, msg, args, line, wiki) {
 			return db.run( sql, sqlargs, function (dberror) {
 				if ( dberror ) {
 					console.log( '- Error while editing the settings: ' + dberror );
-					msg.replyMsg( lang.settings.save_failed, {}, true );
+					msg.replyMsg( lang.get('settings.save_failed'), {}, true );
 					return dberror;
 				}
 				console.log( '- Settings successfully updated.' );
 				if ( channel ) channel.wiki = 'https://' + regex[1] + '/';
 				else guild.wiki = 'https://' + regex[1] + '/';
 				if ( channel || !rows.some( row => row.channel === msg.channel.id ) ) wiki = 'https://' + regex[1] + '/';
-				msg.replyMsg( lang.settings[prelang + 'changed'] + ' https://' + regex[1] + '/' + wikihelp, {}, true );
+				msg.replyMsg( lang.get('settings.' + prelang + 'changed') + ' https://' + regex[1] + '/' + wikihelp, {}, true );
 				var channels = rows.filter( row => row.channel && row.lang === guild.lang && row.wiki === guild.wiki && row.prefix === guild.prefix && row.inline === guild.inline ).map( row => row.channel );
 				if ( channels.length ) db.run( 'DELETE FROM discord WHERE channel IN (' + channels.map( row => '?' ).join('|') + ')', channels, function (delerror) {
 					if ( delerror ) {
@@ -180,17 +180,17 @@ function cmd_settings(lang, msg, args, line, wiki) {
 		}
 		
 		if ( args[0] === 'lang' ) {
-			if ( channel && !( msg.guild.id in patreons ) ) return msg.replyMsg( lang.patreon + ' <' + process.env.patreon + '>', {}, true );
+			if ( channel && !( msg.guild.id in patreons ) ) return msg.replyMsg( lang.get('patreon') + ' <' + process.env.patreon + '>', {}, true );
 			prelang += 'lang';
-			var langhelp = '\n' + lang.settings.langhelp.replaceSave( '%s', prefix + ' settings ' + prelang ) + ' `' + Object.values(i18n.allLangs[1]).join('`, `') + '`';
+			var langhelp = '\n' + lang.get('settings.langhelp').replaceSave( '%s', prefix + 'settings ' + prelang ) + ' `' + Object.values(allLangs.names).map( val => val[0] ).join('`, `') + '`';
 			if ( !args[1] ) {
-				return msg.replyMsg( lang.settings[prelang] + ' `' + i18n.allLangs[2][( channel || guild ).lang] + '`' + langhelp, {}, true );
+				return msg.replyMsg( lang.get('settings.' + prelang) + ' `' + allLangs.names[( channel || guild ).lang][1] + '`' + langhelp, {}, true );
 			}
-			if ( !( args[1] in i18n.allLangs[0] ) ) {
-				return msg.replyMsg( lang.settings.langinvalid + langhelp, {}, true );
+			if ( !( args[1] in allLangs.map ) ) {
+				return msg.replyMsg( lang.get('settings.langinvalid') + langhelp, {}, true );
 			}
 			var sql = 'UPDATE discord SET lang = ? WHERE guild = ? AND lang = ?';
-			var sqlargs = [i18n.allLangs[0][args[1]], msg.guild.id, guild.lang];
+			var sqlargs = [allLangs.map[args[1]], msg.guild.id, guild.lang];
 			if ( !rows.length ) {
 				sql = 'INSERT INTO discord(lang, guild) VALUES(?, ?)';
 				sqlargs.pop();
@@ -199,8 +199,8 @@ function cmd_settings(lang, msg, args, line, wiki) {
 				sql = 'UPDATE discord SET lang = ? WHERE guild = ? AND channel = ?';
 				sqlargs[2] = msg.channel.id;
 				if ( !rows.includes( channel ) ) {
-					if ( channel.lang === i18n.allLangs[0][args[1]] ) {
-						return msg.replyMsg( lang.settings[prelang + 'changed'] + ' `' + i18n.allLangs[2][channel.lang] + '`' + langhelp, {}, true );
+					if ( channel.lang === allLangs.map[args[1]] ) {
+						return msg.replyMsg( lang.get('settings.' + prelang + 'changed') + ' `' + allLangs.names[channel.lang][1] + '`' + langhelp, {}, true );
 					}
 					sql = 'INSERT INTO discord(lang, guild, channel, wiki, prefix) VALUES(?, ?, ?, ?, ?)';
 					sqlargs.push(guild.wiki, guild.prefix);
@@ -209,17 +209,17 @@ function cmd_settings(lang, msg, args, line, wiki) {
 			return db.run( sql, sqlargs, function (dberror) {
 				if ( dberror ) {
 					console.log( '- Error while editing the settings: ' + dberror );
-					msg.replyMsg( lang.settings.save_failed, {}, true );
+					msg.replyMsg( lang.get('settings.save_failed'), {}, true );
 					return dberror;
 				}
 				console.log( '- Settings successfully updated.' );
-				if ( channel ) channel.lang = i18n[i18n.allLangs[0][args[1]]];
+				if ( channel ) channel.lang = allLangs.map[args[1]];
 				else {
-					guild.lang = i18n[i18n.allLangs[0][args[1]]];
+					guild.lang = allLangs.map[args[1]];
 					if ( msg.guild.id in voice ) voice[msg.guild.id] = guild.lang;
 				}
-				if ( channel || !( msg.guild.id in patreons ) || !rows.some( row => row.channel === msg.channel.id ) ) lang = i18n[i18n.allLangs[0][args[1]]];
-				msg.replyMsg( lang.settings[prelang + 'changed'] + ' `' + i18n.allLangs[2][i18n.allLangs[0][args[1]]] + '`\n' + lang.settings.langhelp.replaceSave( '%s', prefix + ' settings ' + prelang ) + ' `' + Object.values(i18n.allLangs[1]).join('`, `') + '`', {}, true );
+				if ( channel || !( msg.guild.id in patreons ) || !rows.some( row => row.channel === msg.channel.id ) ) lang = new Lang(allLangs.map[args[1]]);
+				msg.replyMsg( lang.get('settings.' + prelang + 'changed') + ' `' + allLangs.names[allLangs.map[args[1]]][1] + '`\n' + lang.get('settings.langhelp').replaceSave( '%s', prefix + 'settings ' + prelang ) + ' `' + Object.values(allLangs.names).join('`, `') + '`', {}, true );
 				var channels = rows.filter( row => row.channel && row.lang === lang.lang && row.wiki === guild.wiki && row.prefix === guild.prefix && row.inline === guild.inline ).map( row => row.channel );
 				if ( channels.length ) db.run( 'DELETE FROM discord WHERE channel IN (' + channels.map( row => '?' ).join('|') + ')', channels, function (delerror) {
 					if ( delerror ) {
@@ -233,16 +233,17 @@ function cmd_settings(lang, msg, args, line, wiki) {
 		
 		if ( args[0] === 'prefix' && !channel ) {
 			if ( !( msg.guild.id in patreons ) ) {
-				return msg.replyMsg( lang.patreon + ' <' + process.env.patreon + '>', {}, true );
+				return msg.replyMsg( lang.get('patreon') + ' <' + process.env.patreon + '>', {}, true );
 			}
-			var prefixhelp = '\n' + lang.settings.prefixhelp.replaceSave( '%s', prefix + ' settings prefix' );
-			if ( !args[1] ) {
-				return msg.replyMsg( lang.settings.prefix + ' `' + prefix + '`' + prefixhelp, {}, true );
+			var prefixhelp = '\n' + lang.get('settings.prefixhelp').replaceSave( '%s', prefix + 'settings prefix' );
+			args[1] = args[1].replace( /(?<!\\)_$/, ' ' ).replace( /\\([_\W])/g, '$1' );
+			if ( !args[1].trim() ) {
+				return msg.replyMsg( lang.get('settings.prefix') + ' `' + prefix.replace( / $/, '·' ) + '`' + prefixhelp, {}, true );
 			}
-			if ( args[1].includes( ' ' ) || args[1].includes( '`' ) || args[1].length > 100 ) {
-				return msg.replyMsg( lang.settings.prefixinvalid + prefixhelp, {}, true );
+			if ( args[1].includes( '`' ) || args[1].length > 100 ) {
+				return msg.replyMsg( lang.get('settings.prefixinvalid') + prefixhelp, {}, true );
 			}
-			if ( args[1] === 'reset' ) args[1] = process.env.prefix;
+			if ( args[1] === 'reset' || args[1] === 'default' ) args[1] = process.env.prefix;
 			var sql = 'UPDATE discord SET prefix = ? WHERE guild = ?';
 			var sqlargs = [args[1], msg.guild.id];
 			if ( !rows.length ) {
@@ -251,23 +252,23 @@ function cmd_settings(lang, msg, args, line, wiki) {
 			return db.run( sql, sqlargs, function (dberror) {
 				if ( dberror ) {
 					console.log( '- Error while editing the settings: ' + dberror );
-					msg.replyMsg( lang.settings.save_failed, {}, true );
+					msg.replyMsg( lang.get('settings.save_failed'), {}, true );
 					return dberror;
 				}
 				console.log( '- Settings successfully updated.' );
 				guild.prefix = args[1];
 				msg.client.shard.broadcastEval( `global.patreons['${msg.guild.id}'] = '${args[1]}'` );
-				msg.replyMsg( lang.settings.prefixchanged + ' `' + args[1] + '`\n' + lang.settings.prefixhelp.replaceSave( '%s', args[1] + ' settings prefix' ), {}, true );
+				msg.replyMsg( lang.get('settings.prefixchanged') + ' `' + args[1].replace( / $/, '·' ) + '`\n' + lang.get('settings.prefixhelp').replaceSave( '%s', args[1] + 'settings prefix' ), {}, true );
 			} );
 		}
 		
 		if ( args[0] === 'inline' ) {
-			if ( channel && !( msg.guild.id in patreons ) ) return msg.replyMsg( lang.patreon + ' <' + process.env.patreon + '>', {}, true );
+			if ( channel && !( msg.guild.id in patreons ) ) return msg.replyMsg( lang.get('patreon') + ' <' + process.env.patreon + '>', {}, true );
 			prelang += 'inline';
 			var toggle = 'inline ' + ( ( channel || guild ).inline ? 'disabled' : 'enabled' );
-			var inlinehelp = '\n' + lang.settings[toggle].help.replaceSave( '%1$s', prefix + ' settings ' + prelang + ' toggle' ).replaceSave( /%2\$s/g, lang.search.page );
+			var inlinehelp = '\n' + lang.get('settings.' + toggle + '.help').replaceSave( '%1$s', prefix + 'settings ' + prelang + ' toggle' ).replaceSave( /%2\$s/g, lang.get('search.page') );
 			if ( args[1] !== 'toggle' ) {
-				return msg.replyMsg( lang.settings[toggle][prelang] + inlinehelp, {}, true );
+				return msg.replyMsg( lang.get('settings.' + toggle + '.' + prelang) + inlinehelp, {}, true );
 			}
 			var value = ( ( channel || guild ).inline ? null : 1 );
 			var sql = 'UPDATE discord SET inline = ? WHERE guild = ?';
@@ -286,14 +287,14 @@ function cmd_settings(lang, msg, args, line, wiki) {
 			return db.run( sql, sqlargs, function (dberror) {
 				if ( dberror ) {
 					console.log( '- Error while editing the settings: ' + dberror );
-					msg.replyMsg( lang.settings.save_failed, {}, true );
+					msg.replyMsg( lang.get('settings.save_failed'), {}, true );
 					return dberror;
 				}
 				console.log( '- Settings successfully updated.' );
 				if ( channel ) channel.inline = value;
 				else guild.inline = value;
 				toggle = 'inline ' + ( ( channel || guild ).inline ? 'disabled' : 'enabled' );
-				msg.replyMsg( lang.settings[toggle][prelang + 'changed'] + '\n' + lang.settings[toggle].help.replaceSave( '%1$s', prefix + ' settings ' + prelang + ' toggle' ).replaceSave( /%2\$s/g, lang.search.page ), {}, true );
+				msg.replyMsg( lang.get('settings.' + toggle + '.' + prelang + 'changed') + '\n' + lang.get('settings.' + toggle + '.help').replaceSave( '%1$s', prefix + 'settings ' + prelang + ' toggle' ).replaceSave( /%2\$s/g, lang.get('search.page') ), {}, true );
 				var channels = rows.filter( row => row.channel && row.lang === guild.lang && row.wiki === guild.wiki && row.prefix === guild.prefix && row.inline === guild.inline ).map( row => row.channel );
 				if ( channels.length ) db.run( 'DELETE FROM discord WHERE channel IN (' + channels.map( row => '?' ).join('|') + ')', channels, function (delerror) {
 					if ( delerror ) {

+ 1 - 1
cmds/stop.js

@@ -7,7 +7,7 @@ async function cmd_stop(lang, msg, args, line, wiki) {
 		console.log( '\n- Restarting all shards!\n\n' );
 		await msg.client.shard.respawnAll();
 	} else if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) {
-		this.LINK(lang, msg, line.split(' ').slice(1).join(' '), wiki);
+		this.LINK(lang, msg, line, wiki);
 	}
 }
 

+ 5 - 5
cmds/test.js

@@ -3,18 +3,18 @@ const help_setup = require('../functions/helpsetup.js');
 
 function cmd_test(lang, msg, args, line, wiki) {
 	if ( args.join('') ) {
-		if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) this.LINK(lang, msg, line.split(' ').slice(1).join(' '), wiki);
+		if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) this.LINK(lang, msg, line, wiki);
 	} else if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) {
 		if ( msg.isAdmin() && msg.defaultSettings ) help_setup(lang, msg);
-		var text = lang.test.text[Math.floor(Math.random() * lang.test.random)] || lang.test.default;
+		var text = lang.get('test.text')[Math.floor(Math.random() * lang.get('test.random'))] || lang.get('test.default');
 		console.log( '- Test: Fully functioning!' );
 		var now = Date.now();
 		msg.replyMsg( text ).then( message => {
 			if ( !message ) return;
 			var then = Date.now();
-			var embed = new MessageEmbed().setTitle( lang.test.time ).addField( 'Discord', ( then - now ) + 'ms' );
+			var embed = new MessageEmbed().setTitle( lang.get('test.time') ).addField( 'Discord', ( then - now ) + 'ms' );
 			now = Date.now();
-			got.get( wiki + 'api.php?action=query&format=json', {
+			got.get( wiki + 'api.php?action=query&meta=siteinfo&siprop=general|extensions&format=json', {
 				responseType: 'json'
 			} ).then( response => {
 				then = Date.now();
@@ -58,7 +58,7 @@ function cmd_test(lang, msg, args, line, wiki) {
 		} );
 	} else {
 		console.log( '- Test: Paused!' );
-		msg.replyMsg( lang.test.pause, {}, true );
+		msg.replyMsg( lang.get('test.pause'), {}, true );
 	}
 }
 

+ 48 - 48
cmds/verification.js

@@ -8,7 +8,7 @@ function cmd_verification(lang, msg, args, line, wiki) {
 	}
 	if ( !msg.guild.me.permissions.has('MANAGE_ROLES') ) {
 		console.log( msg.guild.id + ': Missing permissions - MANAGE_ROLES' );
-		return msg.replyMsg( lang.missingperm + ' `MANAGE_ROLES`' );
+		return msg.replyMsg( lang.get('missingperm') + ' `MANAGE_ROLES`' );
 	}
 	
 	db.all( 'SELECT configid, channel, role, editcount, usergroup, accountage, rename FROM verification WHERE guild = ? ORDER BY configid ASC', [msg.guild.id], (error, rows) => {
@@ -21,10 +21,10 @@ function cmd_verification(lang, msg, args, line, wiki) {
 		var prefix = ( patreons[msg.guild.id] || process.env.prefix );
 		if ( args[0] && args[0].toLowerCase() === 'add' ) {
 			var limit = ( msg.guild.id in patreons ? 15 : 10 );
-			if ( rows.length >= limit ) return msg.replyMsg( lang.verification.max_entries, {}, true );
+			if ( rows.length >= limit ) return msg.replyMsg( lang.get('verification.max_entries'), {}, true );
 			var roles = args.slice(1).join(' ').split('|').map( role => role.replace( /^\s*<?\s*(.*?)\s*>?\s*$/, '$1' ) ).filter( role => role.length );
-			if ( !roles.length ) return msg.replyMsg( lang.verification.no_role + '\n`' + prefix + ' verification add ' + lang.verification.new_role + '`', {}, true );
-			if ( roles.length > 10 ) return msg.replyMsg( lang.verification.role_max, {}, true );
+			if ( !roles.length ) return msg.replyMsg( lang.get('verification.no_role') + '\n`' + prefix + 'verification add ' + lang.get('verification.new_role') + '`', {}, true );
+			if ( roles.length > 10 ) return msg.replyMsg( lang.get('verification.role_max'), {}, true );
 			roles = roles.map( role => {
 				var new_role = '';
 				if ( /^\d+$/.test(role) ) new_role = msg.guild.roles.cache.get(role);
@@ -32,8 +32,8 @@ function cmd_verification(lang, msg, args, line, wiki) {
 				if ( !new_role ) new_role = msg.guild.roles.cache.find( gc => gc.name.toLowerCase() === role.toLowerCase().replace( /^@/, '' ) );
 				return new_role;
 			} );
-			if ( roles.some( role => !role ) ) return msg.replyMsg( lang.verification.role_missing, {}, true );
-			if ( roles.some( role => role.managed ) ) return msg.replyMsg( lang.verification.role_managed, {}, true );
+			if ( roles.some( role => !role ) ) return msg.replyMsg( lang.get('verification.role_missing'), {}, true );
+			if ( roles.some( role => role.managed ) ) return msg.replyMsg( lang.get('verification.role_managed'), {}, true );
 			roles = roles.map( role => role.id ).join('|');
 			var new_configid = 1;
 			for ( let i of rows.map( row => row.configid ) ) {
@@ -43,11 +43,11 @@ function cmd_verification(lang, msg, args, line, wiki) {
 			return db.run( 'INSERT INTO verification(guild, configid, channel, role) VALUES(?, ?, ?, ?)', [msg.guild.id, new_configid, '|' + msg.channel.id + '|', roles], function (dberror) {
 				if ( dberror ) {
 					console.log( '- Error while adding the verification: ' + dberror );
-					msg.replyMsg( lang.verification.save_failed, {}, true );
+					msg.replyMsg( lang.get('verification.save_failed'), {}, true );
 					return dberror;
 				}
 				console.log( '- Verification successfully added.' );
-				msg.replyMsg( lang.verification.added + formatVerification(false, false, {configid: new_configid, role: roles}), {}, true );
+				msg.replyMsg( lang.get('verification.added') + formatVerification(false, false, {configid: new_configid, role: roles}), {}, true );
 			} );
 		}
 		if ( !rows.some( row => row.configid.toString() === args[0] ) ) {
@@ -56,9 +56,9 @@ function cmd_verification(lang, msg, args, line, wiki) {
 				return;
 			}
 			var text = '';
-			if ( rows.length ) text += lang.verification.current + rows.map( row => formatVerification(false, true, row) ).join('');
-			else text += lang.verification.missing;
-			text += '\n\n' + lang.verification.add_more + '\n`' + prefix + ' verification add ' + lang.verification.new_role + '`';
+			if ( rows.length ) text += lang.get('verification.current') + rows.map( row => formatVerification(false, true, row) ).join('');
+			else text += lang.get('verification.missing');
+			text += '\n\n' + lang.get('verification.add_more') + '\n`' + prefix + 'verification add ' + lang.get('verification.new_role') + '`';
 			return msg.sendChannel( '<@' + msg.author.id + '>, ' + text, {split:true}, true );
 		}
 		var row = rows.find( row => row.configid.toString() === args[0] );
@@ -67,34 +67,34 @@ function cmd_verification(lang, msg, args, line, wiki) {
 			return db.run( 'DELETE FROM verification WHERE guild = ? AND configid = ?', [msg.guild.id, row.configid], function (dberror) {
 				if ( dberror ) {
 					console.log( '- Error while removing the verification: ' + dberror );
-					msg.replyMsg( lang.verification.save_failed, {}, true );
+					msg.replyMsg( lang.get('verification.save_failed'), {}, true );
 					return dberror;
 				}
 				console.log( '- Verification successfully removed.' );
-				msg.replyMsg( lang.verification.deleted, {}, true );
+				msg.replyMsg( lang.get('verification.deleted'), {}, true );
 			} );
 		}
 		if ( args[1] === 'rename' && !args.slice(2).join('') ) {
 			if ( !row.rename && !msg.guild.me.permissions.has('MANAGE_NICKNAMES') ) {
 				console.log( msg.guild.id + ': Missing permissions - MANAGE_NICKNAMES' );
-				return msg.replyMsg( lang.missingperm + ' `MANAGE_NICKNAMES`' );
+				return msg.replyMsg( lang.get('missingperm') + ' `MANAGE_NICKNAMES`' );
 			}
 			return db.run( 'UPDATE verification SET rename = ? WHERE guild = ? AND configid = ?', [( row.rename ? 0 : 1 ), msg.guild.id, row.configid], function (dberror) {
 				if ( dberror ) {
 					console.log( '- Error while updating the verification: ' + dberror );
-					msg.replyMsg( lang.verification.save_failed, {}, true );
+					msg.replyMsg( lang.get('verification.save_failed'), {}, true );
 					return dberror;
 				}
 				console.log( '- Verification successfully updated.' );
 				row.rename = ( row.rename ? 0 : 1 );
-				msg.sendChannel( '<@' + msg.author.id + '>, ' + lang.verification.updated + formatVerification(), {split:true}, true );
+				msg.sendChannel( '<@' + msg.author.id + '>, ' + lang.get('verification.updated') + formatVerification(), {split:true}, true );
 			} );
 		}
 		if ( args[2] ) {
 			args[2] = args.slice(2).join(' ').replace( /^\s*<?\s*(.*?)\s*>?\s*$/, '$1' );
 			if ( args[1] === 'channel' ) {
 				var channels = args[2].replace( /\s*>?\s*\|\s*<?\s*/g, '|' ).split('|').filter( channel => channel.length );
-				if ( channels.length > 10 ) return msg.replyMsg( lang.verification.channel_max, {}, true );
+				if ( channels.length > 10 ) return msg.replyMsg( lang.get('verification.channel_max'), {}, true );
 				channels = channels.map( channel => {
 					var new_channel = '';
 					if ( /^\d+$/.test(channel) ) new_channel = msg.guild.channels.cache.filter( tc => tc.type === 'text' ).get(channel);
@@ -102,22 +102,22 @@ function cmd_verification(lang, msg, args, line, wiki) {
 					if ( !new_channel ) new_channel = msg.guild.channels.cache.filter( gc => gc.type === 'text' ).find( gc => gc.name.toLowerCase() === channel.toLowerCase().replace( /^#/, '' ) );
 					return new_channel;
 				} );
-				if ( channels.some( channel => !channel ) ) return msg.replyMsg( lang.verification.channel_missing, {}, true );
+				if ( channels.some( channel => !channel ) ) return msg.replyMsg( lang.get('verification.channel_missing'), {}, true );
 				channels = channels.map( channel => channel.id ).join('|');
 				if ( channels.length ) return db.run( 'UPDATE verification SET channel = ? WHERE guild = ? AND configid = ?', ['|' + channels + '|', msg.guild.id, row.configid], function (dberror) {
 					if ( dberror ) {
 						console.log( '- Error while updating the verification: ' + dberror );
-						msg.replyMsg( lang.verification.save_failed, {}, true );
+						msg.replyMsg( lang.get('verification.save_failed'), {}, true );
 						return dberror;
 					}
 					console.log( '- Verification successfully updated.' );
 					row.channel = '|' + channels + '|';
-					msg.sendChannel( '<@' + msg.author.id + '>, ' + lang.verification.updated + formatVerification(), {split:true}, true );
+					msg.sendChannel( '<@' + msg.author.id + '>, ' + lang.get('verification.updated') + formatVerification(), {split:true}, true );
 				} );
 			}
 			if ( args[1] === 'role' ) {
 				var roles = args[2].replace( /\s*>?\s*\|\s*<?\s*/g, '|' ).split('|').filter( role => role.length );
-				if ( roles.length > 10 ) return msg.replyMsg( lang.verification.role_max, {}, true );
+				if ( roles.length > 10 ) return msg.replyMsg( lang.get('verification.role_max'), {}, true );
 				roles = roles.map( role => {
 					var new_role = '';
 					if ( /^\d+$/.test(role) ) new_role = msg.guild.roles.cache.get(role);
@@ -125,32 +125,32 @@ function cmd_verification(lang, msg, args, line, wiki) {
 					if ( !new_role ) new_role = msg.guild.roles.cache.find( gc => gc.name.toLowerCase() === role.toLowerCase().replace( /^@/, '' ) );
 					return new_role;
 				} );
-				if ( roles.some( role => !role ) ) return msg.replyMsg( lang.verification.role_missing, {}, true );
-				if ( roles.some( role => role.managed ) ) return msg.replyMsg( lang.verification.role_managed, {}, true );
+				if ( roles.some( role => !role ) ) return msg.replyMsg( lang.get('verification.role_missing'), {}, true );
+				if ( roles.some( role => role.managed ) ) return msg.replyMsg( lang.get('verification.role_managed'), {}, true );
 				roles = roles.map( role => role.id ).join('|');
 				if ( roles.length ) return db.run( 'UPDATE verification SET role = ? WHERE guild = ? AND configid = ?', [roles, msg.guild.id, row.configid], function (dberror) {
 					if ( dberror ) {
 						console.log( '- Error while updating the verification: ' + dberror );
-						msg.replyMsg( lang.verification.save_failed, {}, true );
+						msg.replyMsg( lang.get('verification.save_failed'), {}, true );
 						return dberror;
 					}
 					console.log( '- Verification successfully updated.' );
 					row.role = roles;
-					msg.sendChannel( '<@' + msg.author.id + '>, ' + lang.verification.updated + formatVerification(), {split:true}, true );
+					msg.sendChannel( '<@' + msg.author.id + '>, ' + lang.get('verification.updated') + formatVerification(), {split:true}, true );
 				} );
 			}
 			if ( ( args[1] === 'editcount' || args[1] === 'accountage' ) && /^\d+$/.test(args[2]) ) {
 				args[2] = parseInt(args[2], 10);
-				if ( args[2] > 1000000 ) return msg.replyMsg( lang.verification.value_too_high, {}, true );
+				if ( args[2] > 1000000 ) return msg.replyMsg( lang.get('verification.value_too_high'), {}, true );
 				return db.run( 'UPDATE verification SET ' + args[1] + ' = ? WHERE guild = ? AND configid = ?', [args[2], msg.guild.id, row.configid], function (dberror) {
 					if ( dberror ) {
 						console.log( '- Error while updating the verification: ' + dberror );
-						msg.replyMsg( lang.verification.save_failed, {}, true );
+						msg.replyMsg( lang.get('verification.save_failed'), {}, true );
 						return dberror;
 					}
 					console.log( '- Verification successfully updated.' );
 					row[args[1]] = args[2];
-					msg.sendChannel( '<@' + msg.author.id + '>, ' + lang.verification.updated + formatVerification(), {split:true}, true );
+					msg.sendChannel( '<@' + msg.author.id + '>, ' + lang.get('verification.updated') + formatVerification(), {split:true}, true );
 				} );
 			}
 			if ( args[1] === 'usergroup' ) {
@@ -160,8 +160,8 @@ function cmd_verification(lang, msg, args, line, wiki) {
 					usergroups = usergroups.slice(1);
 					and_or = 'AND|';
 				}
-				if ( usergroups.length > 10 ) return msg.replyMsg( lang.verification.usergroup_max, {}, true );
-				if ( usergroups.some( usergroup => usergroup.length > 100 ) ) return msg.replyMsg( lang.verification.usergroup_too_long, {}, true );
+				if ( usergroups.length > 10 ) return msg.replyMsg( lang.get('verification.usergroup_max'), {}, true );
+				if ( usergroups.some( usergroup => usergroup.length > 100 ) ) return msg.replyMsg( lang.get('verification.usergroup_too_long'), {}, true );
 				if ( usergroups.length ) return msg.reactEmoji('⏳').then( reaction => got.get( wiki + 'api.php?action=query&meta=allmessages&amprefix=group-&amincludelocal=true&amenableparser=true&format=json', {
 					responseType: 'json'
 				} ).then( response => {
@@ -190,19 +190,19 @@ function cmd_verification(lang, msg, args, line, wiki) {
 					db.run( 'UPDATE verification SET usergroup = ? WHERE guild = ? AND configid = ?', [and_or + usergroups, msg.guild.id, row.configid], function (dberror) {
 						if ( dberror ) {
 							console.log( '- Error while updating the verification: ' + dberror );
-							msg.replyMsg( lang.verification.save_failed, {}, true );
+							msg.replyMsg( lang.get('verification.save_failed'), {}, true );
 							return dberror;
 						}
 						console.log( '- Verification successfully updated.' );
 						row.usergroup = and_or + usergroups;
-						msg.sendChannel( '<@' + msg.author.id + '>, ' + lang.verification.updated + formatVerification(), {split:true}, true );
+						msg.sendChannel( '<@' + msg.author.id + '>, ' + lang.get('verification.updated') + formatVerification(), {split:true}, true );
 						
 						if ( reaction ) reaction.removeEmoji();
 					} );
 				} ) );
 			}
 		}
-		return msg.sendChannel( '<@' + msg.author.id + '>, ' + lang.verification.current_selected.replace( '%1', row.configid ) + formatVerification(true) +'\n\n' + lang.verification.delete_current + '\n`' + prefix + ' verification ' + row.configid + ' delete`', {split:true}, true );
+		return msg.sendChannel( '<@' + msg.author.id + '>, ' + lang.get('verification.current_selected').replace( '%1', row.configid ) + formatVerification(true) +'\n\n' + lang.get('verification.delete_current') + '\n`' + prefix + 'verification ' + row.configid + ' delete`', {split:true}, true );
 		
 		function formatVerification(showCommands, hideNotice, {
 			configid,
@@ -213,27 +213,27 @@ function cmd_verification(lang, msg, args, line, wiki) {
 			accountage = 0,
 			rename = 0
 		} = row) {
-			var verification_text = '\n\n`' + prefix + ' verification ' + configid + '`';
-			verification_text += '\n' + lang.verification.channel + ' <#' + channel.split('|').filter( channel => channel.length ).join('>, <#') + '>';
-			if ( showCommands ) verification_text += '\n`' + prefix + ' verification ' + row.configid + ' channel ' + lang.verification.new_channel + '`\n';
-			verification_text += '\n' + lang.verification.role + ' <@&' + role.split('|').join('>, <@&') + '>';
-			if ( showCommands ) verification_text += '\n`' + prefix + ' verification ' + row.configid + ' role ' + lang.verification.new_role + '`\n';
-			verification_text += '\n' + lang.verification.editcount + ' `' + editcount + '`';
-			if ( showCommands ) verification_text += '\n`' + prefix + ' verification ' + row.configid + ' editcount ' + lang.verification.new_editcount + '`\n';
-			verification_text += '\n' + lang.verification.usergroup + ' `' + ( usergroup.startsWith( 'AND|' ) ? usergroup.split('|').slice(1).join('` ' + lang.verification.and + ' `') : usergroup.split('|').join('` ' + lang.verification.or + ' `') ) + '`';
-			if ( showCommands ) verification_text += '\n`' + prefix + ' verification ' + row.configid + ' usergroup ' + lang.verification.new_usergroup + '`\n';
-			verification_text += '\n' + lang.verification.accountage + ' `' + accountage + '` ' + lang.verification.indays;
-			if ( showCommands ) verification_text += '\n`' + prefix + ' verification ' + row.configid + ' accountage ' + lang.verification.new_accountage + '`\n';
-			verification_text += '\n' + lang.verification.rename + ' *`' + ( rename ? lang.verification.enabled : lang.verification.disabled ) + '`*';
-			if ( showCommands ) verification_text += ' ' + lang.verification.toggle + '\n`' + prefix + ' verification ' + row.configid + ' rename`\n';
+			var verification_text = '\n\n`' + prefix + 'verification ' + configid + '`';
+			verification_text += '\n' + lang.get('verification.channel') + ' <#' + channel.split('|').filter( channel => channel.length ).join('>, <#') + '>';
+			if ( showCommands ) verification_text += '\n`' + prefix + 'verification ' + row.configid + ' channel ' + lang.get('verification.new_channel') + '`\n';
+			verification_text += '\n' + lang.get('verification.role') + ' <@&' + role.split('|').join('>, <@&') + '>';
+			if ( showCommands ) verification_text += '\n`' + prefix + 'verification ' + row.configid + ' role ' + lang.get('verification.new_role') + '`\n';
+			verification_text += '\n' + lang.get('verification.editcount') + ' `' + editcount + '`';
+			if ( showCommands ) verification_text += '\n`' + prefix + 'verification ' + row.configid + ' editcount ' + lang.get('verification.new_editcount') + '`\n';
+			verification_text += '\n' + lang.get('verification.usergroup') + ' `' + ( usergroup.startsWith( 'AND|' ) ? usergroup.split('|').slice(1).join('` ' + lang.get('verification.and') + ' `') : usergroup.split('|').join('` ' + lang.get('verification.or') + ' `') ) + '`';
+			if ( showCommands ) verification_text += '\n`' + prefix + 'verification ' + row.configid + ' usergroup ' + lang.get('verification.new_usergroup') + '`\n';
+			verification_text += '\n' + lang.get('verification.accountage') + ' `' + accountage + '` ' + lang.get('verification.indays');
+			if ( showCommands ) verification_text += '\n`' + prefix + 'verification ' + row.configid + ' accountage ' + lang.get('verification.new_accountage') + '`\n';
+			verification_text += '\n' + lang.get('verification.rename') + ' *`' + lang.get('verification.' + ( rename ? 'enabled' : 'disabled')) + '`*';
+			if ( showCommands ) verification_text += ' ' + lang.get('verification.toggle') + '\n`' + prefix + 'verification ' + row.configid + ' rename`\n';
 			if ( !hideNotice && rename && !msg.guild.me.permissions.has('MANAGE_NICKNAMES') ) {
-				verification_text += '\n\n' + lang.verification.rename_no_permission.replaceSave( '%s', msg.guild.me.toString() );
+				verification_text += '\n\n' + lang.get('verification.rename_no_permission').replaceSave( '%s', msg.guild.me.toString() );
 			}
 			if ( !hideNotice && role.split('|').some( role => msg.guild.me.roles.highest.comparePositionTo(role) <= 0 ) ) {
 				verification_text += '\n';
 				role.split('|').forEach( role => {
 					if ( msg.guild.me.roles.highest.comparePositionTo(role) <= 0 ) {
-						verification_text += '\n' + lang.verification.role_too_high.replaceSave( '%1$s', '<@&' + role + '>' ).replaceSave( '%2$s', msg.guild.me.toString() );
+						verification_text += '\n' + lang.get('verification.role_too_high').replaceSave( '%1$s', '<@&' + role + '>' ).replaceSave( '%2$s', msg.guild.me.toString() );
 					}
 				} );
 			}

+ 68 - 68
cmds/verify.js

@@ -5,12 +5,12 @@ const {timeoptions} = require('../util/default.json');
 var db = require('../util/database.js');
 
 function cmd_verify(lang, msg, args, line, wiki) {
-	if ( msg.channel.type !== 'text' ) return this.LINK(lang, msg, line.split(' ').slice(1).join(' '), wiki);
+	if ( msg.channel.type !== 'text' ) return this.LINK(lang, msg, line, wiki);
 	if ( !msg.guild.me.permissions.has('MANAGE_ROLES') ) {
 		if ( msg.isAdmin() || msg.isOwner() ) {
 			console.log( msg.guild.id + ': Missing permissions - MANAGE_ROLES' );
-			msg.replyMsg( lang.missingperm + ' `MANAGE_ROLES`' );
-		} else this.LINK(lang, msg, line.split(' ').slice(1).join(' '), wiki);
+			msg.replyMsg( lang.get('missingperm') + ' `MANAGE_ROLES`' );
+		} else this.LINK(lang, msg, line, wiki);
 		return;
 	}
 	
@@ -23,18 +23,18 @@ function cmd_verify(lang, msg, args, line, wiki) {
 	db.all( 'SELECT role, editcount, usergroup, accountage, rename FROM verification WHERE guild = ? AND channel LIKE ? ORDER BY configid ASC', [msg.guild.id, '%|' + msg.channel.id + '|%'], (dberror, rows) => {
 		if ( dberror || !rows ) {
 			console.log( '- Error while getting the verifications: ' + dberror );
-			embed.setTitle( username.escapeFormatting() ).setColor('#000000').setDescription( lang.verify.error );
-			msg.replyMsg( lang.verify.error_reply, {embed}, false, false ).then( message => message.reactEmoji('error') );
+			embed.setTitle( username.escapeFormatting() ).setColor('#000000').setDescription( lang.get('verify.error') );
+			msg.replyMsg( lang.get('verify.error_reply'), {embed}, false, false ).then( message => message.reactEmoji('error') );
 			return dberror;
 		}
-		if ( !rows.length ) return msg.replyMsg( lang.verify.missing );
+		if ( !rows.length ) return msg.replyMsg( lang.get('verify.missing') );
 		
 		if ( !username.trim() ) {
-			args[0] = line.split(' ')[1];
+			args[0] = line.split(' ')[0];
 			if ( args[0] === 'verification' ) args[0] = 'verify';
 			return this.help(lang, msg, args, line);
 		}
-		var embed = new MessageEmbed().setFooter( lang.verify.footer + ' • ' + new Date().toLocaleString(lang.dateformat, timeoptions) ).setTimestamp();
+		var embed = new MessageEmbed().setFooter( lang.get('verify.footer') + ' • ' + new Date().toLocaleString(lang.get('dateformat'), timeoptions) ).setTimestamp();
 		msg.reactEmoji('⏳').then( reaction => got.get( wiki + 'api.php?action=query&meta=siteinfo&siprop=general&list=users&usprop=blockinfo|groups|groupmemberships|editcount|registration&ususers=' + encodeURIComponent( username ) + '&format=json', {
 			responseType: 'json'
 		} ).then( response => {
@@ -47,8 +47,8 @@ function cmd_verify(lang, msg, args, line, wiki) {
 				}
 				else {
 					console.log( '- ' + response.statusCode + ': Error while getting the user: ' + ( body && body.error && body.error.info ) );
-					embed.setTitle( username.escapeFormatting() ).setColor('#000000').setDescription( lang.verify.error );
-					msg.replyMsg( lang.verify.error_reply, {embed}, false, false ).then( message => message.reactEmoji('error') );
+					embed.setTitle( username.escapeFormatting() ).setColor('#000000').setDescription( lang.get('verify.error') );
+					msg.replyMsg( lang.get('verify.error_reply'), {embed}, false, false ).then( message => message.reactEmoji('error') );
 				}
 				
 				if ( reaction ) reaction.removeEmoji();
@@ -58,8 +58,8 @@ function cmd_verify(lang, msg, args, line, wiki) {
 			embed.setAuthor( body.query.general.sitename );
 			if ( body.query.users.length !== 1 || queryuser.missing !== undefined || queryuser.invalid !== undefined ) {
 				username = ( body.query.users.length === 1 ? queryuser.name : username );
-				embed.setTitle( username.escapeFormatting() ).setColor('#0000FF').setDescription( lang.verify.user_missing.replaceSave( '%s', username.escapeFormatting() ) );
-				msg.replyMsg( lang.verify.user_missing_reply.replaceSave( '%s', username.escapeFormatting() ), {embed}, false, false );
+				embed.setTitle( username.escapeFormatting() ).setColor('#0000FF').setDescription( lang.get('verify.user_missing').replaceSave( '%s', username.escapeFormatting() ) );
+				msg.replyMsg( lang.get('verify.user_missing_reply').replaceSave( '%s', username.escapeFormatting() ), {embed}, false, false );
 				
 				if ( reaction ) reaction.removeEmoji();
 				return;
@@ -68,8 +68,8 @@ function cmd_verify(lang, msg, args, line, wiki) {
 			var pagelink = wiki.toLink('User:' + username, '', '', body.query.general, true);
 			embed.setTitle( username.escapeFormatting() ).setURL( pagelink );
 			if ( queryuser.blockexpiry ) {
-				embed.setColor('#FF0000').setDescription( lang.verify.user_blocked.replaceSave( '%s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ) );
-				msg.replyMsg( lang.verify.user_blocked_reply.replaceSave( '%s', username.escapeFormatting() ), {embed}, false, false );
+				embed.setColor('#FF0000').setDescription( lang.get('verify.user_blocked').replaceSave( '%s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ) );
+				msg.replyMsg( lang.get('verify.user_blocked_reply').replaceSave( '%s', username.escapeFormatting() ), {embed}, false, false );
 				
 				if ( reaction ) reaction.removeEmoji();
 				return;
@@ -86,36 +86,36 @@ function cmd_verify(lang, msg, args, line, wiki) {
 			if ( url ) return got.get( url ).then( gbresponse => {
 				if ( gbresponse.statusCode !== 200 || !gbresponse.body ) {
 					console.log( '- ' + gbresponse.statusCode + ': Error while getting the global block.' );
-					comment.push(lang.verify.failed_gblock);
+					comment.push(lang.get('verify.failed_gblock'));
 				}
 				else {
 					let $ = cheerio.load(gbresponse.body);
 					if ( wiki.endsWith( '.gamepedia.com/' ) ) {
 						if ( $('.mw-blocklist').length ) {
 							return Promise.reject({
-								desc: lang.verify.user_gblocked.replaceSave( '%s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ),
-								reply: lang.verify.user_gblocked_reply.replaceSave( '%s', username.escapeFormatting() )
+								desc: lang.get('verify.user_gblocked').replaceSave( '%s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ),
+								reply: lang.get('verify.user_gblocked_reply').replaceSave( '%s', username.escapeFormatting() )
 							});
 						}
 					}
 					else if ( wiki.isFandom() ) {
 						if ( $('#mw-content-text .errorbox').length ) {
 							return Promise.reject({
-								desc: lang.verify.user_disabled.replaceSave( '%s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ),
-								reply: lang.verify.user_disabled_reply.replaceSave( '%s', username.escapeFormatting() )
+								desc: lang.get('verify.user_disabled').replaceSave( '%s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ),
+								reply: lang.get('verify.user_disabled_reply').replaceSave( '%s', username.escapeFormatting() )
 							});
 						}
 						else if ( $('.mw-warning-with-logexcerpt').length && !$(".mw-warning-with-logexcerpt .mw-logline-block").length ) {
 							return Promise.reject({
-								desc: lang.verify.user_gblocked.replaceSave( '%s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ),
-								reply: lang.verify.user_gblocked_reply.replaceSave( '%s', username.escapeFormatting() )
+								desc: lang.get('verify.user_gblocked').replaceSave( '%s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ),
+								reply: lang.get('verify.user_gblocked_reply').replaceSave( '%s', username.escapeFormatting() )
 							});
 						}
 					}
 				}
 			}, error => {
 				console.log( '- Error while getting the global block: ' + error );
-				comment.push(lang.verify.failed_gblock);
+				comment.push(lang.get('verify.failed_gblock'));
 			} ).then( async () => {
 				// async check for editcount on Gamepedia, workaround for https://gitlab.com/hydrawiki/hydra/-/issues/5054
 				if ( wiki.endsWith( '.gamepedia.com/' ) ) {
@@ -142,8 +142,8 @@ function cmd_verify(lang, msg, args, line, wiki) {
 					if ( presponse.statusCode !== 200 || !pbody || pbody.error || pbody.errormsg || pbody.title || !( pbody.profile || pbody.value !== undefined ) ) {
 						if ( !( pbody && pbody.status === 404 ) ) {
 							console.log( '- ' + presponse.statusCode + ': Error while getting the Discord tag: ' + ( pbody && ( pbody.error && pbody.error.info || pbody.errormsg || pbody.title ) ) );
-							embed.setColor('#000000').setDescription( lang.verify.error );
-							msg.replyMsg( lang.verify.error_reply, {embed}, false, false ).then( message => message.reactEmoji('error') );
+							embed.setColor('#000000').setDescription( lang.get('verify.error') );
+							msg.replyMsg( lang.get('verify.error_reply'), {embed}, false, false ).then( message => message.reactEmoji('error') );
 							
 							if ( reaction ) reaction.removeEmoji();
 							return;
@@ -154,14 +154,14 @@ function cmd_verify(lang, msg, args, line, wiki) {
 					if ( pbody.profile ) discordname = pbody.profile['link-discord'].escapeFormatting().replace( /^\s*([^@#:]{2,32}?)\s*#(\d{4,6})\s*$/, '$1#$2' );
 					else if ( pbody.value ) discordname = htmlToPlain( pbody.value ).replace( /^\s*([^@#:]{2,32}?)\s*#(\d{4,6})\s*$/, '$1#$2' );
 					if ( discordname.length > 50 ) discordname = discordname.substring(0, 50) + '\u2026';
-					embed.addField( lang.verify.discord, msg.author.tag.escapeFormatting(), true ).addField( lang.verify.wiki, ( discordname || lang.verify.empty ), true );
+					embed.addField( lang.get('verify.discord'), msg.author.tag.escapeFormatting(), true ).addField( lang.get('verify.wiki'), ( discordname || lang.get('verify.empty') ), true );
 					if ( msg.author.tag.escapeFormatting() !== discordname ) {
-						embed.setColor('#FFFF00').setDescription( lang.verify.user_failed.replaceSave( '%1$s', msg.member.toString() ).replaceSave( '%2$s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ) );
+						embed.setColor('#FFFF00').setDescription( lang.get('verify.user_failed').replaceSave( '%1$s', msg.member.toString() ).replaceSave( '%2$s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ) );
 						var help_link = '';
-						if ( wiki.endsWith( '.gamepedia.com/' ) ) help_link = lang.verify.help_gamepedia + '?c=' + ( msg.guild.id in patreons && patreons[msg.guild.id] !== process.env.prefix ? encodeURIComponent( patreons[msg.guild.id] + ' verify' ) : 'wb' ) + ( msg.channel.name !== 'verification' ? '&ch=' + encodeURIComponent( msg.channel.name ) : '' ) + '&user=' + username.toTitle(true, true) + '&discord=' + encodeURIComponent( msg.author.username ) + '&tag=' + msg.author.discriminator;
-						else if ( wiki.isFandom() ) help_link = lang.verify.help_fandom + '/' + username.toTitle(true) + '?c=' + ( msg.guild.id in patreons && patreons[msg.guild.id] !== process.env.prefix ? encodeURIComponent( patreons[msg.guild.id] + ' verify' ) : 'wb' ) + ( msg.channel.name !== 'verification' ? '&ch=' + encodeURIComponent( msg.channel.name ) : '' ) + '&user=' + encodeURIComponent( msg.author.username ) + '&tag=' + msg.author.discriminator;
-						if ( help_link.length ) embed.addField( lang.verify.notice, lang.verify.help_guide.replaceSave( '%s', help_link ) + '\n' + help_link );
-						msg.replyMsg( lang.verify.user_failed_reply.replaceSave( '%s', username.escapeFormatting() ), {embed}, false, false );
+						if ( wiki.endsWith( '.gamepedia.com/' ) ) help_link = lang.get('verify.help_gamepedia') + '?c=' + ( msg.guild.id in patreons && patreons[msg.guild.id] !== process.env.prefix ? encodeURIComponent( patreons[msg.guild.id] + ' verify' ) : 'wb' ) + ( msg.channel.name !== 'verification' ? '&ch=' + encodeURIComponent( msg.channel.name ) : '' ) + '&user=' + username.toTitle(true, true) + '&discord=' + encodeURIComponent( msg.author.username ) + '&tag=' + msg.author.discriminator;
+						else if ( wiki.isFandom() ) help_link = lang.get('verify.help_fandom') + '/' + username.toTitle(true) + '?c=' + ( msg.guild.id in patreons && patreons[msg.guild.id] !== process.env.prefix ? encodeURIComponent( patreons[msg.guild.id] + ' verify' ) : 'wb' ) + ( msg.channel.name !== 'verification' ? '&ch=' + encodeURIComponent( msg.channel.name ) : '' ) + '&user=' + encodeURIComponent( msg.author.username ) + '&tag=' + msg.author.discriminator;
+						if ( help_link.length ) embed.addField( lang.get('verify.notice'), lang.get('verify.help_guide').replaceSave( '%s', help_link ) + '\n' + help_link );
+						msg.replyMsg( lang.get('verify.user_failed_reply').replaceSave( '%s', username.escapeFormatting() ), {embed}, false, false );
 						
 						if ( reaction ) reaction.removeEmoji();
 						return;
@@ -196,29 +196,29 @@ function cmd_verify(lang, msg, args, line, wiki) {
 						}
 					} );
 					if ( verified ) {
-						embed.setColor('#00FF00').setDescription( lang.verify.user_verified.replaceSave( '%1$s', msg.member.toString() ).replaceSave( '%2$s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ) + ( rename ? '\n' + lang.verify.user_renamed : '' ) );
-						var text = lang.verify.user_verified_reply.replaceSave( '%s', username.escapeFormatting() );
+						embed.setColor('#00FF00').setDescription( lang.get('verify.user_verified').replaceSave( '%1$s', msg.member.toString() ).replaceSave( '%2$s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ) + ( rename ? '\n' + lang.get('verify.user_renamed') : '' ) );
+						var text = lang.get('verify.user_verified_reply').replaceSave( '%s', username.escapeFormatting() );
 						var verify_promise = [
-							msg.member.roles.add( roles, lang.verify.audit_reason.replaceSave( '%s', username ) ).catch( error => {
+							msg.member.roles.add( roles, lang.get('verify.audit_reason').replaceSave( '%s', username ) ).catch( error => {
 								embed.setColor('#008800');
-								comment.push(lang.verify.failed_roles);
+								comment.push(lang.get('verify.failed_roles'));
 							} )
 						];
 						if ( rename ) {
-							verify_promise.push(msg.member.setNickname( username.substring(0, 32), lang.verify.audit_reason.replaceSave( '%s', username ) ).catch( error => {
+							verify_promise.push(msg.member.setNickname( username.substring(0, 32), lang.get('verify.audit_reason').replaceSave( '%s', username ) ).catch( error => {
 								embed.setColor('#008800');
-								comment.push(lang.verify.failed_rename);
+								comment.push(lang.get('verify.failed_rename'));
 							} ));
 						}
 						return Promise.all(verify_promise).finally( () => {
 							if ( msg.showEmbed() ) {
-								if ( roles.length ) embed.addField( lang.verify.qualified, roles.map( role => '<@&' + role + '>' ).join('\n') );
-								if ( missing.length ) embed.setColor('#008800').addField( lang.verify.qualified_error, missing.map( role => '<@&' + role + '>' ).join('\n') );
-								if ( comment.length ) embed.setColor('#008800').addField( lang.verify.notice, comment.join('\n') );
+								if ( roles.length ) embed.addField( lang.get('verify.qualified'), roles.map( role => '<@&' + role + '>' ).join('\n') );
+								if ( missing.length ) embed.setColor('#008800').addField( lang.get('verify.qualified_error'), missing.map( role => '<@&' + role + '>' ).join('\n') );
+								if ( comment.length ) embed.setColor('#008800').addField( lang.get('verify.notice'), comment.join('\n') );
 							}
 							else {
-								if ( roles.length ) text += '\n\n' + lang.verify.qualified + ' ' + roles.map( role => '<@&' + role + '>' ).join(', ');
-								if ( missing.length ) text += '\n\n' + lang.verify.qualified_error + ' ' + missing.map( role => '<@&' + role + '>' ).join(', ');
+								if ( roles.length ) text += '\n\n' + lang.get('verify.qualified') + ' ' + roles.map( role => '<@&' + role + '>' ).join(', ');
+								if ( missing.length ) text += '\n\n' + lang.get('verify.qualified_error') + ' ' + missing.map( role => '<@&' + role + '>' ).join(', ');
 								if ( comment.length ) text += '\n\n' + comment.join('\n');
 							}
 							msg.replyMsg( text, {embed,split:true}, false, false );
@@ -227,14 +227,14 @@ function cmd_verify(lang, msg, args, line, wiki) {
 						} );
 					}
 					
-					embed.setColor('#FFFF00').setDescription( lang.verify.user_matches.replaceSave( '%1$s', msg.member.toString() ).replaceSave( '%2$s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ) );
-					msg.replyMsg( lang.verify.user_matches_reply.replaceSave( '%s', username.escapeFormatting() ), {embed}, false, false );
+					embed.setColor('#FFFF00').setDescription( lang.get('verify.user_matches').replaceSave( '%1$s', msg.member.toString() ).replaceSave( '%2$s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ) );
+					msg.replyMsg( lang.get('verify.user_matches_reply').replaceSave( '%s', username.escapeFormatting() ), {embed}, false, false );
 					
 					if ( reaction ) reaction.removeEmoji();
 				}, error => {
 					console.log( '- Error while getting the Discord tag: ' + error );
-					embed.setColor('#000000').setDescription( lang.verify.error );
-					msg.replyMsg( lang.verify.error_reply, {embed}, false, false ).then( message => message.reactEmoji('error') );
+					embed.setColor('#000000').setDescription( lang.get('verify.error') );
+					msg.replyMsg( lang.get('verify.error_reply'), {embed}, false, false ).then( message => message.reactEmoji('error') );
 					
 					if ( reaction ) reaction.removeEmoji();
 				} );
@@ -252,8 +252,8 @@ function cmd_verify(lang, msg, args, line, wiki) {
 				if ( mwbody && mwbody.warnings ) log_warn(mwbody.warnings);
 				if ( mwresponse.statusCode !== 200 || !mwbody || mwbody.batchcomplete === undefined || !mwbody.query || !mwbody.query.pages ) {
 					console.log( '- ' + mwresponse.statusCode + ': Error while getting the Discord tag: ' + ( mwbody && mwbody.error && mwbody.error.info ) );
-					embed.setColor('#000000').setDescription( lang.verify.error );
-					msg.replyMsg( lang.verify.error_reply, {embed}, false, false ).then( message => message.reactEmoji('error') );
+					embed.setColor('#000000').setDescription( lang.get('verify.error') );
+					msg.replyMsg( lang.get('verify.error_reply'), {embed}, false, false ).then( message => message.reactEmoji('error') );
 					
 					if ( reaction ) reaction.removeEmoji();
 					return;
@@ -263,11 +263,11 @@ function cmd_verify(lang, msg, args, line, wiki) {
 				var discordname = '';
 				if ( revision && revision.user === username ) discordname = revision.slots.main['*'].escapeFormatting().replace( /^\s*([^@#:]{2,32}?)\s*#(\d{4,6})\s*$/, '$1#$2' );
 				if ( discordname.length > 50 ) discordname = discordname.substring(0, 50) + '\u2026';
-				embed.addField( lang.verify.discord, msg.author.tag.escapeFormatting(), true ).addField( lang.verify.wiki, ( discordname || lang.verify.empty ), true );
+				embed.addField( lang.get('verify.discord'), msg.author.tag.escapeFormatting(), true ).addField( lang.get('verify.wiki'), ( discordname || lang.get('verify.empty') ), true );
 				if ( msg.author.tag.escapeFormatting() !== discordname ) {
-					embed.setColor('#FFFF00').setDescription( lang.verify.user_failed.replaceSave( '%1$s', msg.member.toString() ).replaceSave( '%2$s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ) );
-					embed.addField( lang.verify.notice, lang.verify.help_subpage.replaceSave( '%s', '**`' + msg.author.tag + '`**' ) + '\n' + wiki.toLink('Special:MyPage/Discord', 'action=edit', '', body.query.general) );
-					msg.replyMsg( lang.verify.user_failed_reply.replaceSave( '%s', username.escapeFormatting() ), {embed}, false, false );
+					embed.setColor('#FFFF00').setDescription( lang.get('verify.user_failed').replaceSave( '%1$s', msg.member.toString() ).replaceSave( '%2$s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ) );
+					embed.addField( lang.get('verify.notice'), lang.get('verify.help_subpage').replaceSave( '%s', '**`' + msg.author.tag + '`**' ) + '\n' + wiki.toLink('Special:MyPage/Discord', 'action=edit', '', body.query.general) );
+					msg.replyMsg( lang.get('verify.user_failed_reply').replaceSave( '%s', username.escapeFormatting() ), {embed}, false, false );
 					
 					if ( reaction ) reaction.removeEmoji();
 					return;
@@ -302,29 +302,29 @@ function cmd_verify(lang, msg, args, line, wiki) {
 					}
 				} );
 				if ( verified ) {
-					embed.setColor('#00FF00').setDescription( lang.verify.user_verified.replaceSave( '%1$s', msg.member.toString() ).replaceSave( '%2$s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ) + ( rename ? '\n' + lang.verify.user_renamed : '' ) );
-					var text = lang.verify.user_verified_reply.replaceSave( '%s', username.escapeFormatting() );
+					embed.setColor('#00FF00').setDescription( lang.get('verify.user_verified').replaceSave( '%1$s', msg.member.toString() ).replaceSave( '%2$s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ) + ( rename ? '\n' + lang.get('verify.user_renamed') : '' ) );
+					var text = lang.get('verify.user_verified_reply').replaceSave( '%s', username.escapeFormatting() );
 					var verify_promise = [
-						msg.member.roles.add( roles, lang.verify.audit_reason.replaceSave( '%s', username ) ).catch( error => {
+						msg.member.roles.add( roles, lang.get('verify.audit_reason').replaceSave( '%s', username ) ).catch( error => {
 							embed.setColor('#008800');
-							comment.push(lang.verify.failed_roles);
+							comment.push(lang.get('verify.failed_roles'));
 						} )
 					];
 					if ( rename ) {
-						verify_promise.push(msg.member.setNickname( username.substring(0, 32), lang.verify.audit_reason.replaceSave( '%s', username ) ).catch( error => {
+						verify_promise.push(msg.member.setNickname( username.substring(0, 32), lang.get('verify.audit_reason').replaceSave( '%s', username ) ).catch( error => {
 							embed.setColor('#008800');
-							comment.push(lang.verify.failed_rename);
+							comment.push(lang.get('verify.failed_rename'));
 						} ));
 					}
 					return Promise.all(verify_promise).finally( () => {
 						if ( msg.showEmbed() ) {
-							if ( roles.length ) embed.addField( lang.verify.qualified, roles.map( role => '<@&' + role + '>' ).join('\n') );
-							if ( missing.length ) embed.setColor('#008800').addField( lang.verify.qualified_error, missing.map( role => '<@&' + role + '>' ).join('\n') );
-							if ( comment.length ) embed.setColor('#008800').addField( lang.verify.notice, comment.join('\n') );
+							if ( roles.length ) embed.addField( lang.get('verify.qualified'), roles.map( role => '<@&' + role + '>' ).join('\n') );
+							if ( missing.length ) embed.setColor('#008800').addField( lang.get('verify.qualified_error'), missing.map( role => '<@&' + role + '>' ).join('\n') );
+							if ( comment.length ) embed.setColor('#008800').addField( lang.get('verify.notice'), comment.join('\n') );
 						}
 						else {
-							if ( roles.length ) text += '\n\n' + lang.verify.qualified + ' ' + roles.map( role => '<@&' + role + '>' ).join(', ');
-							if ( missing.length ) text += '\n\n' + lang.verify.qualified_error + ' ' + missing.map( role => '<@&' + role + '>' ).join(', ');
+							if ( roles.length ) text += '\n\n' + lang.get('verify.qualified') + ' ' + roles.map( role => '<@&' + role + '>' ).join(', ');
+							if ( missing.length ) text += '\n\n' + lang.get('verify.qualified_error') + ' ' + missing.map( role => '<@&' + role + '>' ).join(', ');
 							if ( comment.length ) text += '\n\n' + comment.join('\n');
 						}
 						msg.replyMsg( text, {embed,split:true}, false, false );
@@ -333,21 +333,21 @@ function cmd_verify(lang, msg, args, line, wiki) {
 					} );
 				}
 				
-				embed.setColor('#FFFF00').setDescription( lang.verify.user_matches.replaceSave( '%1$s', msg.member.toString() ).replaceSave( '%2$s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ) );
-				msg.replyMsg( lang.verify.user_matches_reply.replaceSave( '%s', username.escapeFormatting() ), {embed}, false, false );
+				embed.setColor('#FFFF00').setDescription( lang.get('verify.user_matches').replaceSave( '%1$s', msg.member.toString() ).replaceSave( '%2$s', '[' + username.escapeFormatting() + '](' + pagelink + ')' ) );
+				msg.replyMsg( lang.get('verify.user_matches_reply').replaceSave( '%s', username.escapeFormatting() ), {embed}, false, false );
 				
 				if ( reaction ) reaction.removeEmoji();
 			}, error => {
 				console.log( '- Error while getting the Discord tag: ' + error );
-				embed.setColor('#000000').setDescription( lang.verify.error );
-				msg.replyMsg( lang.verify.error_reply, {embed}, false, false ).then( message => message.reactEmoji('error') );
+				embed.setColor('#000000').setDescription( lang.get('verify.error') );
+				msg.replyMsg( lang.get('verify.error_reply'), {embed}, false, false ).then( message => message.reactEmoji('error') );
 				
 				if ( reaction ) reaction.removeEmoji();
 			} );
 		}, error => {
 			console.log( '- Error while getting the user: ' + error );
-			embed.setColor('#000000').setDescription( lang.verify.error );
-			msg.replyMsg( lang.verify.error_reply, {embed}, false, false ).then( message => message.reactEmoji('error') );
+			embed.setColor('#000000').setDescription( lang.get('verify.error') );
+			msg.replyMsg( lang.get('verify.error_reply'), {embed}, false, false ).then( message => message.reactEmoji('error') );
 			
 			if ( reaction ) reaction.removeEmoji();
 		} ) );

+ 8 - 8
cmds/voice.js

@@ -4,8 +4,8 @@ var db = require('../util/database.js');
 function cmd_voice(lang, msg, args, line, wiki) {
 	if ( msg.isAdmin() ) {
 		if ( !args.join('') ) {
-			var text = lang.voice.text + '\n`' + lang.voice.channel + ' – <' + lang.voice.name + '>`\n';
-			text += lang.voice[( msg.guild.id in voice ? 'disable' : 'enable' )].replaceSave( '%s', ( patreons[msg.guild.id] || process.env.prefix ) + ' voice toggle' );
+			var text = lang.get('voice.text') + '\n`' + lang.get('voice.channel') + ' – <' + lang.get('voice.name') + '>`\n';
+			text += lang.get('voice.' + ( msg.guild.id in voice ? 'disable' : 'enable' )).replaceSave( '%s', ( patreons[msg.guild.id] || process.env.prefix ) + 'voice toggle' );
 			return msg.replyMsg( text, {}, true );
 		}
 		args[1] = args.slice(1).join(' ').trim()
@@ -14,18 +14,18 @@ function cmd_voice(lang, msg, args, line, wiki) {
 			return db.run( 'UPDATE discord SET voice = ? WHERE guild = ? AND channel IS NULL', [value, msg.guild.id], function (dberror) {
 				if ( dberror ) {
 					console.log( '- Error while editing the voice settings: ' + dberror );
-					msg.replyMsg( lang.settings.save_failed, {}, true );
+					msg.replyMsg( lang.get('settings.save_failed'), {}, true );
 					return dberror;
 				}
 				if ( !this.changes ) return db.run( 'INSERT INTO discord(guild, voice) VALUES(?, ?)', [msg.guild.id, value], function (error) {
 					if ( error ) {
 						console.log( '- Error while adding the voice settings: ' + error );
-						msg.replyMsg( lang.settings.save_failed, {}, true );
+						msg.replyMsg( lang.get('settings.save_failed'), {}, true );
 						return error;
 					}
 					console.log( '- Voice settings successfully added.' );
 					voice[msg.guild.id] = defaultSettings.lang;
-					msg.replyMsg( lang.voice.enabled + '\n`' + lang.voice.channel + ' – <' + lang.voice.name + '>`', {}, true );
+					msg.replyMsg( lang.get('voice.enabled') + '\n`' + lang.get('voice.channel') + ' – <' + lang.get('voice.name') + '>`', {}, true );
 				} );
 				console.log( '- Voice settings successfully updated.' );
 				if ( value ) {
@@ -38,16 +38,16 @@ function cmd_voice(lang, msg, args, line, wiki) {
 						console.log( '- Voice language successfully updated.' );
 						voice[msg.guild.id] = row.lang;
 					} );
-					msg.replyMsg( lang.voice.enabled + '\n`' + lang.voice.channel + ' – <' + lang.voice.name + '>`', {}, true );
+					msg.replyMsg( lang.get('voice.enabled') + '\n`' + lang.get('voice.channel') + ' – <' + lang.get('voice.name') + '>`', {}, true );
 				}
 				else {
 					delete voice[msg.guild.id];
-					msg.replyMsg( lang.voice.disabled, {}, true );
+					msg.replyMsg( lang.get('voice.disabled'), {}, true );
 				}
 			} );
 		}
 	}
-	if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) this.LINK(lang, msg, line.split(' ').slice(1).join(' '), wiki);
+	if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) this.LINK(lang, msg, line, wiki);
 }
 
 module.exports = {

+ 30 - 23
cmds/wiki/fandom.js

@@ -1,5 +1,6 @@
 const htmlparser = require('htmlparser2');
 const {MessageEmbed} = require('discord.js');
+const Lang = require('../../util/i18n.js');
 
 const fs = require('fs');
 var fn = {
@@ -30,7 +31,7 @@ function fandom_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '',
 		msg.reactEmoji('⚠️');
 	}
 	var invoke = title.split(' ')[0].toLowerCase();
-	var aliasInvoke = ( lang.aliases[invoke] || invoke );
+	var aliasInvoke = ( lang.get('aliases')[invoke] || invoke );
 	var args = title.split(' ').slice(1);
 	
 	if ( aliasInvoke === 'random' && !args.join('') && !querystring && !fragment ) fn.random(lang, msg, wiki, reaction, spoiler);
@@ -214,10 +215,10 @@ function fandom_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '',
 									text = '';
 								}
 								else if ( wsbody.total === 1 ) {
-									text = '\n' + lang.search.infopage.replaceSave( '%s', '`' + prefix + cmd + lang.search.page + ' ' + title + linksuffix + '`' );
+									text = '\n' + lang.get('search.infopage').replaceSave( '%s', '`' + prefix + cmd + lang.get('search.page') + ' ' + title + linksuffix + '`' );
 								}
 								else {
-									text = '\n' + lang.search.infosearch.replaceSave( '%1$s', '`' + prefix + cmd + lang.search.page + ' ' + title + linksuffix + '`' ).replaceSave( '%2$s', '`' + prefix + cmd + lang.search.search + ' ' + title + linksuffix + '`' );
+									text = '\n' + lang.get('search.infosearch').replaceSave( '%1$s', '`' + prefix + cmd + lang.get('search.page') + ' ' + title + linksuffix + '`' ).replaceSave( '%2$s', '`' + prefix + cmd + lang.get('search.search') + ' ' + title + linksuffix + '`' );
 								}
 								got.get( wiki + 'api.php?action=query&prop=imageinfo|categoryinfo&titles=' + encodeURIComponent( querypage.title ) + '&format=json', {
 									responseType: 'json'
@@ -241,20 +242,23 @@ function fandom_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '',
 											else if ( msg.uploadFiles() ) embed.attachFiles( [{attachment:pageimage,name:( spoiler ? 'SPOILER ' : '' ) + filename}] );
 										}
 										if ( querypage.categoryinfo ) {
-											var langCat = lang.search.category;
-											var category = [langCat.content];
-											if ( querypage.categoryinfo.size === 0 ) category.push(langCat.empty);
+											var langCat = new Lang(lang.lang, 'search.category');
+											var category = [langCat.get('content')];
+											if ( querypage.categoryinfo.size === 0 ) category.push(langCat.get('empty'));
 											if ( querypage.categoryinfo.pages > 0 ) {
-												var pages = querypage.categoryinfo.pages;
-												category.push(( langCat.pages[pages] || langCat.pages['*' + pages % 100] || langCat.pages['*' + pages % 10] || langCat.pages.default ).replaceSave( '%s', pages ));
+												let pages = querypage.categoryinfo.pages;
+												let count = langCat.get('pages');
+												category.push(( count[pages] || count['*' + pages % 100] || count['*' + pages % 10] || langCat.get('pages.default') ).replaceSave( '%s', pages ));
 											}
 											if ( querypage.categoryinfo.files > 0 ) {
-												var files = querypage.categoryinfo.files;
-												category.push(( langCat.files[files] || langCat.files['*' + files % 100] || langCat.files['*' + files % 10] || langCat.files.default ).replaceSave( '%s', files ));
+												let files = querypage.categoryinfo.files;
+												let count = langCat.get('files');
+												category.push(( count[files] || count['*' + files % 100] || count['*' + files % 10] || langCat.get('files.default') ).replaceSave( '%s', files ));
 											}
 											if ( querypage.categoryinfo.subcats > 0 ) {
-												var subcats = querypage.categoryinfo.subcats;
-												category.push(( langCat.subcats[subcats] || langCat.subcats['*' + subcats % 100] || langCat.subcats['*' + subcats % 10] || langCat.subcats.default ).replaceSave( '%s', subcats ));
+												let subcats = querypage.categoryinfo.subcats;
+												let count = langCat.get('subcats');
+												category.push(( count[subcats] || count['*' + subcats % 100] || count['*' + subcats % 10] || langCat.get('subcats.default') ).replaceSave( '%s', subcats ));
 											}
 											if ( msg.showEmbed() ) embed.addField( category[0], category.slice(1).join('\n') );
 											else text += '\n\n' + category.join('\n');
@@ -330,20 +334,23 @@ function fandom_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '',
 							else if ( msg.uploadFiles() ) embed.attachFiles( [{attachment:pageimage,name:( spoiler ? 'SPOILER ' : '' ) + filename}] );
 						}
 						if ( querypage.categoryinfo ) {
-							var langCat = lang.search.category;
-							var category = [langCat.content];
-							if ( querypage.categoryinfo.size === 0 ) category.push(langCat.empty);
+							var langCat = new Lang(lang.lang, 'search.category');
+							var category = [langCat.get('content')];
+							if ( querypage.categoryinfo.size === 0 ) category.push(langCat.get('empty'));
 							if ( querypage.categoryinfo.pages > 0 ) {
-								var pages = querypage.categoryinfo.pages;
-								category.push(( langCat.pages[pages] || langCat.pages['*' + pages % 100] || langCat.pages['*' + pages % 10]  || langCat.pages.default ).replaceSave( '%s', pages ));
+								let pages = querypage.categoryinfo.pages;
+								let count = langCat.get('pages');
+								category.push(( count[pages] || count['*' + pages % 100] || count['*' + pages % 10]  || langCat.get('pages.default') ).replaceSave( '%s', pages ));
 							}
 							if ( querypage.categoryinfo.files > 0 ) {
-								var files = querypage.categoryinfo.files;
-								category.push(( langCat.files[files] || langCat.files['*' + files % 100] || langCat.files['*' + files % 10]  || langCat.files.default ).replaceSave( '%s', files ));
+								let files = querypage.categoryinfo.files;
+								let count = langCat.get('files');
+								category.push(( count[files] || count['*' + files % 100] || count['*' + files % 10]  || langCat.get('files.default') ).replaceSave( '%s', files ));
 							}
 							if ( querypage.categoryinfo.subcats > 0 ) {
-								var subcats = querypage.categoryinfo.subcats;
-								category.push(( langCat.subcats[subcats] || langCat.subcats['*' + subcats % 100] || langCat.subcats['*' + subcats % 10]  || langCat.subcats.default ).replaceSave( '%s', subcats ));
+								let subcats = querypage.categoryinfo.subcats;
+								let count = langCat.get('subcats');
+								category.push(( count[subcats] || count['*' + subcats % 100] || count['*' + subcats % 10]  || langCat.get('subcats.default') ).replaceSave( '%s', subcats ));
 							}
 							if ( msg.showEmbed() ) embed.addField( category[0], category.slice(1).join('\n') );
 							else text += '\n\n' + category.join('\n');
@@ -397,7 +404,7 @@ function fandom_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '',
 						if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) {
 							var iwtitle = decodeURIComponent( inter.url.replace( regex[0], '' ) ).replace( /\_/g, ' ' ).replaceSave( intertitle.replace( /\_/g, ' ' ), intertitle );
 							selfcall++;
-							this.fandom(lang, msg, iwtitle, 'https://' + regex[1] + '/', ' ?' + ( regex[3] ? regex[3] + '.' : '' ) + regex[2] + ' ', reaction, spoiler, querystring, fragment, selfcall);
+							this.fandom(lang, msg, iwtitle, 'https://' + regex[1] + '/', '?' + ( regex[3] ? regex[3] + '.' : '' ) + regex[2] + ' ', reaction, spoiler, querystring, fragment, selfcall);
 						} else {
 							if ( reaction ) reaction.removeEmoji();
 							console.log( '- Aborted, paused.' );
@@ -408,7 +415,7 @@ function fandom_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '',
 							if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) {
 								var iwtitle = decodeURIComponent( inter.url.replace( regex[0], '' ) ).replace( /\_/g, ' ' ).replaceSave( intertitle.replace( /\_/g, ' ' ), intertitle );
 								selfcall++;
-								this.gamepedia(lang, msg, iwtitle, 'https://' + regex[1] + '.gamepedia.com/', ' !' + regex[1] + ' ', reaction, spoiler, querystring, fragment, selfcall);
+								this.gamepedia(lang, msg, iwtitle, 'https://' + regex[1] + '.gamepedia.com/', '!' + regex[1] + ' ', reaction, spoiler, querystring, fragment, selfcall);
 							} else {
 								if ( reaction ) reaction.removeEmoji();
 								console.log( '- Aborted, paused.' );

+ 24 - 24
cmds/wiki/fandom/diff.js

@@ -60,7 +60,7 @@ function fandom_diff(lang, msg, args, wiki, reaction, spoiler, embed) {
 				}
 				else {
 					if ( body.query.badrevids ) {
-						msg.replyMsg( lang.diff.badrev );
+						msg.replyMsg( lang.get('diff.badrev') );
 						
 						if ( reaction ) reaction.removeEmoji();
 					} else if ( body.query.pages && !body.query.pages[-1] ) {
@@ -73,7 +73,7 @@ function fandom_diff(lang, msg, args, wiki, reaction, spoiler, embed) {
 								argids = [ids.to, ids.from];
 								var compare = ['', ''];
 								if ( ids['*'] !== undefined ) {
-									var more = '\n__' + lang.diff.info.more + '__';
+									var more = '\n__' + lang.get('diff.info.more') + '__';
 									var current_tag = '';
 									var small_prev_ins = '';
 									var small_prev_del = '';
@@ -145,23 +145,23 @@ function fandom_diff(lang, msg, args, wiki, reaction, spoiler, embed) {
 									if ( small_prev_del.length ) {
 										if ( small_prev_del.replace( /\~\~/g, '' ).trim().length ) {
 											compare[0] = small_prev_del.replace( /\~\~\~\~/g, '' );
-										} else compare[0] = '__' + lang.diff.info.whitespace + '__';
+										} else compare[0] = '__' + lang.get('diff.info.whitespace') + '__';
 									}
 									if ( small_prev_ins.length ) {
 										if ( small_prev_ins.replace( /\*\*/g, '' ).trim().length ) {
 											compare[1] = small_prev_ins.replace( /\*\*\*\*/g, '' );
-										} else compare[1] = '__' + lang.diff.info.whitespace + '__';
+										} else compare[1] = '__' + lang.get('diff.info.whitespace') + '__';
 									}
 								}
 							}
 							fandom_diff_send(lang, msg, argids, wiki, reaction, spoiler, compare);
 						} else {
-							msg.replyMsg( lang.diff.badrev );
+							msg.replyMsg( lang.get('diff.badrev') );
 							
 							if ( reaction ) reaction.removeEmoji();
 						}
 					} else {
-						if ( body.query.pages && body.query.pages[-1] ) msg.replyMsg( lang.diff.badrev );
+						if ( body.query.pages && body.query.pages[-1] ) msg.replyMsg( lang.get('diff.badrev') );
 						else msg.reactEmoji('error');
 						
 						if ( reaction ) reaction.removeEmoji();
@@ -209,7 +209,7 @@ function fandom_diff_send(lang, msg, args, wiki, reaction, spoiler, compare) {
 		}
 		else {
 			if ( body.query.badrevids ) {
-				msg.replyMsg( lang.diff.badrev );
+				msg.replyMsg( lang.get('diff.badrev') );
 				
 				if ( reaction ) reaction.removeEmoji();
 			}
@@ -225,12 +225,12 @@ function fandom_diff_send(lang, msg, args, wiki, reaction, spoiler, compare) {
 					var revisions = pages[0].revisions.sort( (first, second) => Date.parse(second.timestamp) - Date.parse(first.timestamp) );
 					var diff = revisions[0].revid;
 					var oldid = ( revisions[1] ? revisions[1].revid : 0 );
-					var editor = [lang.diff.info.editor, ( revisions[0].userhidden !== undefined ? lang.diff.hidden : revisions[0].user )];
-					var timestamp = [lang.diff.info.timestamp, new Date(revisions[0].timestamp).toLocaleString(lang.dateformat, timeoptions)];
+					var editor = [lang.get('diff.info.editor'), ( revisions[0].userhidden !== undefined ? lang.get('diff.hidden') : revisions[0].user )];
+					var timestamp = [lang.get('diff.info.timestamp'), new Date(revisions[0].timestamp).toLocaleString(lang.get('dateformat'), timeoptions)];
 					var difference = revisions[0].size - ( revisions[1] ? revisions[1].size : 0 );
-					var size = [lang.diff.info.size, lang.diff.info.bytes.replace( '%s', ( difference > 0 ? '+' : '' ) + difference )];
-					var comment = [lang.diff.info.comment, ( revisions[0].commenthidden !== undefined ? lang.diff.hidden : ( revisions[0].comment ? revisions[0].comment.toFormatting(msg.showEmbed(), wiki, body.query.general, title) : lang.diff.nocomment ) )];
-					if ( revisions[0].tags.length ) var tags = [lang.diff.info.tags, body.query.tags.filter( tag => revisions[0].tags.includes( tag.name ) ).map( tag => tag.displayname ).join(', ')];
+					var size = [langget('diff.info.size'), lang.get('diff.info.bytes').replace( '%s', ( difference > 0 ? '+' : '' ) + difference )];
+					var comment = [lang.get('diff.info.comment'), ( revisions[0].commenthidden !== undefined ? lang.get('diff.hidden') : ( revisions[0].comment ? revisions[0].comment.toFormatting(msg.showEmbed(), wiki, body.query.general, title) : lang.get('diff.nocomment') ) )];
+					if ( revisions[0].tags.length ) var tags = [lang.get('diff.info.tags'), body.query.tags.filter( tag => revisions[0].tags.includes( tag.name ) ).map( tag => tag.displayname ).join(', ')];
 					
 					var pagelink = wiki.toLink(title, 'diff=' + diff + '&oldid=' + oldid, '', body.query.general);
 					if ( msg.showEmbed() ) {
@@ -239,7 +239,7 @@ function fandom_diff_send(lang, msg, args, wiki, reaction, spoiler, compare) {
 						if ( revisions[0].anon !== undefined ) {
 							editorlink = '[' + editor[1] + '](' + wiki.toLink('Special:Contributions/' + editor[1], '', '', body.query.general, true) + ')';
 						}
-						if ( editor[1] === lang.diff.hidden ) editorlink = editor[1];
+						if ( editor[1] === lang.get('diff.hidden') ) editorlink = editor[1];
 						var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( ( title + '?diff=' + diff + '&oldid=' + oldid ).escapeFormatting() ).setURL( pagelink ).addField( editor[0], editorlink, true ).addField( size[0], size[1], true ).addField( comment[0], comment[1] ).setFooter( timestamp[1] );
 						if ( tags ) {
 							var taglink = '';
@@ -261,7 +261,7 @@ function fandom_diff_send(lang, msg, args, wiki, reaction, spoiler, compare) {
 							embed.addField( tags[0], tagtext );
 						}
 						
-						var more = '\n__' + lang.diff.info.more + '__';
+						var more = '\n__' + lang.get('diff.info.more') + '__';
 						if ( !compare && oldid ) got.get( wiki + 'api.php?action=query&prop=revisions&rvprop=&revids=' + oldid + '&rvdiffto=' + diff + '&format=json', {
 							responseType: 'json'
 						} ).then( cpresponse => {
@@ -343,20 +343,20 @@ function fandom_diff_send(lang, msg, args, wiki, reaction, spoiler, compare) {
 									parser.end();
 									if ( small_prev_del.length ) {
 										if ( small_prev_del.replace( /\~\~/g, '' ).trim().length ) {
-											embed.addField( lang.diff.info.removed, small_prev_del.replace( /\~\~\~\~/g, '' ), true );
-										} else embed.addField( lang.diff.info.removed, '__' + lang.diff.info.whitespace + '__', true );
+											embed.addField( lang.get('diff.info.removed'), small_prev_del.replace( /\~\~\~\~/g, '' ), true );
+										} else embed.addField( lang.get('diff.info.removed'), '__' + lang.get('diff.info.whitespace') + '__', true );
 									}
 									if ( small_prev_ins.length ) {
 										if ( small_prev_ins.replace( /\*\*/g, '' ).trim().length ) {
-											embed.addField( lang.diff.info.added, small_prev_ins.replace( /\*\*\*\*/g, '' ), true );
-										} else embed.addField( lang.diff.info.added, '__' + lang.diff.info.whitespace + '__', true );
+											embed.addField( lang.get('diff.info.added'), small_prev_ins.replace( /\*\*\*\*/g, '' ), true );
+										} else embed.addField( lang.get('diff.info.added'), '__' + lang.get('diff.info.whitespace') + '__', true );
 									}
 								}
 								else if ( revision.texthidden !== undefined ) {
-									embed.addField( lang.diff.info.added, '__' + lang.diff.hidden + '__', true );
+									embed.addField( lang.get('diff.info.added'), '__' + lang.get('diff.hidden') + '__', true );
 								}
 								else if ( revision.diff && revision.diff['*'] === undefined ) {
-									embed.addField( lang.diff.info.removed, '__' + lang.diff.hidden + '__', true );
+									embed.addField( lang.get('diff.info.removed'), '__' + lang.get('diff.hidden') + '__', true );
 								}
 							}
 						}, error => {
@@ -368,8 +368,8 @@ function fandom_diff_send(lang, msg, args, wiki, reaction, spoiler, compare) {
 						} );
 						else {
 							if ( compare ) {
-								if ( compare[0].length ) embed.addField( lang.diff.info.removed, compare[0], true );
-								if ( compare[1].length ) embed.addField( lang.diff.info.added, compare[1], true );
+								if ( compare[0].length ) embed.addField( lang.get('diff.info.removed'), compare[0], true );
+								if ( compare[1].length ) embed.addField( lang.get('diff.info.added'), compare[1], true );
 							}
 							else if ( revisions[0]['*'] ) {
 								var content = revisions[0]['*'].escapeFormatting();
@@ -379,8 +379,8 @@ function fandom_diff_send(lang, msg, args, wiki, reaction, spoiler, compare) {
 										content = content.substring(0, 1000 - more.length);
 										content = '**' + content.substring(0, content.lastIndexOf('\n')) + '**' + more;
 									}
-									embed.addField( lang.diff.info.added, content, true );
-								} else embed.addField( lang.diff.info.added, '__' + lang.diff.info.whitespace + '__', true );
+									embed.addField( lang.get('diff.info.added'), content, true );
+								} else embed.addField( lang.get('diff.info.added'), '__' + lang.get('diff.info.whitespace') + '__', true );
 							}
 							
 							msg.sendChannel( spoiler + text + spoiler, {embed} );

+ 18 - 18
cmds/wiki/fandom/overview.js

@@ -42,18 +42,18 @@ function fandom_overview(lang, msg, wiki, reaction, spoiler) {
 			else {
 				var site = ovbody.items[body.query.wikidesc.id];
 				
-				var vertical = [lang.overview.vertical, site.hub];
-				var topic = [lang.overview.topic, site.topic];
-				var founder = [lang.overview.founder, site.founding_user_id];
-				var manager = [lang.overview.manager, body.query.allmessages[0]['*']];
-				var crossover = [lang.overview.crossover, ( body.query.allmessages[1]['*'] ? '<https://' + body.query.allmessages[1]['*'] + '.gamepedia.com/>' : '' )];
-				var created = [lang.overview.created, new Date(site.creation_date).toLocaleString(lang.dateformat, timeoptions)];
-				var articles = [lang.overview.articles, body.query.statistics.articles];
-				var pages = [lang.overview.pages, body.query.statistics.pages];
-				var edits = [lang.overview.edits, body.query.statistics.edits];
-				var users = [lang.overview.users, body.query.statistics.activeusers];
-				var description = [lang.overview.description, site.desc];
-				var image = [lang.overview.image, site.image];
+				var vertical = [lang.get('overview.vertical'), site.hub];
+				var topic = [lang.get('overview.topic'), site.topic];
+				var founder = [lang.get('overview.founder'), site.founding_user_id];
+				var manager = [lang.get('overview.manager'), body.query.allmessages[0]['*']];
+				var crossover = [lang.get('overview.crossover'), ( body.query.allmessages[1]['*'] ? '<https://' + body.query.allmessages[1]['*'] + '.gamepedia.com/>' : '' )];
+				var created = [lang.get('overview.created'), new Date(site.creation_date).toLocaleString(lang.get('dateformat'), timeoptions)];
+				var articles = [lang.get('overview.articles'), body.query.statistics.articles];
+				var pages = [lang.get('overview.pages'), body.query.statistics.pages];
+				var edits = [lang.get('overview.edits'), body.query.statistics.edits];
+				var users = [lang.get('overview.users'), body.query.statistics.activeusers];
+				var description = [lang.get('overview.description'), site.desc];
+				var image = [lang.get('overview.image'), site.image];
 				
 				if ( description[1] ) {
 					description[1] = description[1].escapeFormatting();
@@ -93,8 +93,8 @@ function fandom_overview(lang, msg, wiki, reaction, spoiler) {
 				} ).finally( () => {
 					if ( msg.showEmbed() ) {
 						embed.addField( founder[0], founder[1], true );
-						if ( manager[1] ) embed.addField( manager[0], '[' + manager[1] + '](' + wiki.toLink('User:' + manager[1], '', '', body.query.general, true) + ') ([' + lang.overview.talk + '](' + wiki.toLink('User talk:' + manager[1], '', '', body.query.general, true) + '))', true );
-						embed.addField( created[0], created[1], true ).addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).setFooter( lang.overview.inaccurate );
+						if ( manager[1] ) embed.addField( manager[0], '[' + manager[1] + '](' + wiki.toLink('User:' + manager[1], '', '', body.query.general, true) + ') ([' + lang.get('overview.talk') + '](' + wiki.toLink('User talk:' + manager[1], '', '', body.query.general, true) + '))', true );
+						embed.addField( created[0], created[1], true ).addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).setFooter( lang.get('overview.inaccurate') );
 						if ( crossover[1] ) {
 							var crossoverSite = allSites.find( site => '<https://' + site.wiki_domain + '/>' === crossover[1] );
 							if ( crossoverSite ) embed.addField( crossover[0], '[' + crossoverSite.wiki_display_name + '](' + crossover[1] + ')', true );
@@ -111,7 +111,7 @@ function fandom_overview(lang, msg, wiki, reaction, spoiler) {
 							text += '\n' + image.join(' ');
 							if ( msg.uploadFiles() ) embed.files = [image[1]];
 						}
-						text += '\n\n*' + lang.overview.inaccurate + '*';
+						text += '\n\n*' + lang.get('overview.inaccurate') + '*';
 					}
 					
 					msg.sendChannel( spoiler + text + spoiler, {embed} );
@@ -119,9 +119,9 @@ function fandom_overview(lang, msg, wiki, reaction, spoiler) {
 					if ( reaction ) reaction.removeEmoji();
 				} );
 				else {
-					founder[1] = lang.overview.none;
+					founder[1] = lang.get('overview.none');
 					if ( msg.showEmbed() ) {
-						embed.addField( founder[0], founder[1], true ).addField( created[0], created[1], true ).addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).setFooter( lang.overview.inaccurate );
+						embed.addField( founder[0], founder[1], true ).addField( created[0], created[1], true ).addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).setFooter( lang.get('overview.inaccurate') );
 						if ( crossover[1] ) {
 							var crossoverSite = allSites.find( site => '<https://' + site.wiki_domain + '/>' === crossover[1] );
 							if ( crossoverSite ) embed.addField( crossover[0], '[' + crossoverSite.wiki_display_name + '](' + crossover[1] + ')', true );
@@ -138,7 +138,7 @@ function fandom_overview(lang, msg, wiki, reaction, spoiler) {
 							text += '\n' + image.join(' ');
 							if ( msg.uploadFiles() ) embed.files = [image[1]];
 						}
-						text += '\n\n*' + lang.overview.inaccurate + '*';
+						text += '\n\n*' + lang.get('overview.inaccurate') + '*';
 					}
 					
 					msg.sendChannel( spoiler + text + spoiler, {embed} );

+ 2 - 1
cmds/wiki/fandom/search.js

@@ -29,7 +29,8 @@ function fandom_search(lang, msg, searchterm, wiki, query, reaction, spoiler) {
 		body.items.forEach( result => {
 			description.push( '• [' + result.title + '](' + wiki.toLink(result.title, '', '', query.general, true) + ')' );
 		} );
-		embed.setFooter( ( lang.search.results[body.total] || lang.search.results['*' + body.total % 100] || lang.search.results['*' + body.total % 10]  || lang.search.results.default ).replaceSave( '%s', body.total ) );
+		let count = lang.get('search.results');
+		embed.setFooter( ( count[body.total] || count['*' + body.total % 100] || count['*' + body.total % 10]  || lang.get('search.results.default') ).replaceSave( '%s', body.total ) );
 	}, error => {
 		console.log( '- Error while getting the search results.' + error );
 	} ).finally( () => {

+ 28 - 29
cmds/wiki/fandom/user.js

@@ -1,7 +1,7 @@
 const htmlparser = require('htmlparser2');
 const {MessageEmbed} = require('discord.js');
 const global_block = require('../../../functions/global_block.js');
-const {timeoptions} = require('../../../util/default.json');
+const {timeoptions, usergroups} = require('../../../util/default.json');
 
 function fandom_user(lang, msg, namespace, username, wiki, querystring, fragment, querypage, contribs, reaction, spoiler) {
 	if ( /^(?:(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{2})?|(?:[\dA-F]{1,4}:){7}[\dA-F]{1,4}(?:\/\d{2,3})?)$/.test(username) ) {
@@ -62,18 +62,18 @@ function fandom_user(lang, msg, namespace, username, wiki, querystring, fragment
 				if ( !querypage.noRedirect || ( querypage.missing === undefined && querypage.ns !== -1 ) ) namespace = contribs;
 				var blocks = body.query.blocks.map( block => {
 					var isBlocked = false;
-					var blockedtimestamp = new Date(block.timestamp).toLocaleString(lang.dateformat, timeoptions);
+					var blockedtimestamp = new Date(block.timestamp).toLocaleString(lang.get('dateformat'), timeoptions);
 					var blockexpiry = block.expiry;
 					if ( blockexpiry === 'infinity' ) {
-						blockexpiry = lang.user.block.until_infinity;
+						blockexpiry = lang.get('user.block.until_infinity');
 						isBlocked = true;
 					} else if ( blockexpiry ) {
 						if ( Date.parse(blockexpiry) > Date.now() ) isBlocked = true;
-						blockexpiry = new Date(blockexpiry).toLocaleString(lang.dateformat, timeoptions);
+						blockexpiry = new Date(blockexpiry).toLocaleString(lang.get('dateformat'), timeoptions);
 					}
 					if ( isBlocked ) return {
-						header: lang.user.block.header.replaceSave( '%s', block.user ).escapeFormatting(),
-						text: lang.user.block[( block.reason ? 'text' : 'noreason' )].replaceSave( '%1$s', blockedtimestamp ).replaceSave( '%2$s', blockexpiry ),
+						header: lang.get('user.block.header').replaceSave( '%s', block.user ).escapeFormatting(),
+						text: lang.get('user.block.' + ( block.reason ? 'text' : 'noreason' )).replaceSave( '%1$s', blockedtimestamp ).replaceSave( '%2$s', blockexpiry ),
 						by: block.by,
 						reason: block.reason
 					};
@@ -114,7 +114,7 @@ function fandom_user(lang, msg, namespace, username, wiki, querystring, fragment
 						}
 					}
 					else {
-						var editcount = [lang.user.info.editcount, ( username.includes( '/' ) ? '~' : '' ) + ucbody.query.usercontribs.length + ( ucbody.continue ? '+' : '' )];
+						var editcount = [lang.get('user.info.editcount'), ( username.includes( '/' ) ? '~' : '' ) + ucbody.query.usercontribs.length + ( ucbody.continue ? '+' : '' )];
 						
 						var pagelink = wiki.toLink(namespace + username, querystring.toTitle(), fragment, body.query.general);
 						if ( msg.showEmbed() ) {
@@ -125,7 +125,7 @@ function fandom_user(lang, msg, namespace, username, wiki, querystring, fragment
 								if ( block.reason ) block.text = block.text.replaceSave( '%4$s', block.reason.toMarkdown(wiki, body.query.general) );
 								embed.addField( block.header, block.text );
 							}
-							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.user.info.loading + '**' );
+							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
 						}
 						else {
 							var embed = {};
@@ -135,7 +135,7 @@ function fandom_user(lang, msg, namespace, username, wiki, querystring, fragment
 								if ( block.reason ) block.text = block.text.replaceSave( '%4$s', block.reason.toPlaintext() );
 								text += '\n\n**' + block.header + '**\n' + block.text;
 							}
-							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.user.info.loading + '**';
+							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**';
 						}
 						
 						msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler) );
@@ -210,45 +210,44 @@ function fandom_user(lang, msg, namespace, username, wiki, querystring, fragment
 				}
 				else {
 					username = queryuser.name;
-					var gender = [lang.user.info.gender];
+					var gender = [lang.get('user.info.gender')];
 					switch (queryuser.gender) {
 						case 'male':
-							gender.push(lang.user.gender.male);
+							gender.push(lang.get('user.gender.male'));
 							break;
 						case 'female':
-							gender.push(lang.user.gender.female);
+							gender.push(lang.get('user.gender.female'));
 							break;
 						default: 
-							gender.push(lang.user.gender.unknown);
+							gender.push(lang.get('user.gender.unknown'));
 					}
-					var registration = [lang.user.info.registration, new Date(queryuser.registration).toLocaleString(lang.dateformat, timeoptions)];
-					var editcount = [lang.user.info.editcount, queryuser.editcount];
+					var registration = [lang.get('user.info.registration'), new Date(queryuser.registration).toLocaleString(lang.get('dateformat'), timeoptions)];
+					var editcount = [lang.get('user.info.editcount'), queryuser.editcount];
 					var groups = queryuser.groups;
-					var group = [lang.user.info.group];
-					var grouplist = lang.user.groups;
-					for ( var i = 0; i < grouplist.length; i++ ) {
-						if ( groups.includes( grouplist[i][0] ) && ( group.length === 1 || !['autoconfirmed', 'user'].includes( grouplist[i][0] ) ) ) {
-							if ( grouplist[i][0] === 'wiki-manager' && body.query.allmessages[0]['*'] === username ) {
-								group.push('**' + grouplist[i][1] + '**');
+					var group = [lang.get('user.info.group')];
+					for ( var i = 0; i < usergroups.length; i++ ) {
+						if ( groups.includes( usergroups[i] ) && ( group.length === 1 || !['autoconfirmed', 'user'].includes( usergroups[i] ) ) ) {
+							if ( usergroups[i] === 'wiki-manager' && body.query.allmessages[0]['*'] === username ) {
+								group.push('**' + lang.get('user.groups.' + usergroups[i]) + '**');
 							}
-							else group.push(grouplist[i][1]);
+							else group.push(lang.get('user.groups.' + usergroups[i]));
 						}
 					}
 					var isBlocked = false;
 					var blockexpiry = queryuser.blockexpiry;
 					if ( blockexpiry === 'infinity' ) {
-						blockexpiry = lang.user.block.until_infinity;
+						blockexpiry = lang.get('user.block.until_infinity');
 						isBlocked = true;
 					} else if ( blockexpiry ) {
 						var blockexpirydate = blockexpiry.replace( /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2,3})/, '$1-$2-$3T$4:$5:$6Z' );
-						blockexpiry = new Date(blockexpirydate).toLocaleString(lang.dateformat, timeoptions);
+						blockexpiry = new Date(blockexpirydate).toLocaleString(lang.get('dateformat'), timeoptions);
 						if ( Date.parse(blockexpirydate) > Date.now() ) isBlocked = true;
 					}
 					var blockedby = '[[User:' + queryuser.blockedby + '|' + queryuser.blockedby + ']]';
 					var blockreason = queryuser.blockreason;
 					var block = {
-						header: lang.user.block.header.replaceSave( '%s', username ).escapeFormatting(),
-						text: lang.user.block['nofrom' + ( blockreason ? 'text' : 'noreason' )].replaceSave( '%2$s', blockexpiry ),
+						header: lang.get('user.block.header').replaceSave( '%s', username ).escapeFormatting(),
+						text: lang.get('user.block.nofrom' + ( blockreason ? 'text' : 'noreason' )).replaceSave( '%2$s', blockexpiry ),
 						by: blockedby,
 						reason: blockreason
 					};
@@ -286,7 +285,7 @@ function fandom_user(lang, msg, namespace, username, wiki, querystring, fragment
 								if ( msg.channel.type === 'text' ) var discordmember = msg.guild.members.cache.find( member => {
 									return member.user.tag.escapeFormatting() === discordfield.value;
 								} );
-								var discordname = [lang.user.info.discord,discordfield.value];
+								var discordname = [lang.get('user.info.discord'),discordfield.value];
 								if ( discordmember ) discordname[1] = discordmember.toString();
 								
 								if ( msg.showEmbed() ) embed.addField( discordname[0], discordname[1], true );
@@ -310,7 +309,7 @@ function fandom_user(lang, msg, namespace, username, wiki, querystring, fragment
 								if ( block.reason ) block.text = block.text.replaceSave( '%4$s', block.reason.toMarkdown(wiki, body.query.general) );
 								embed.addField( block.header, block.text );
 							}
-							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.user.info.loading + '**' );
+							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
 						}
 						else {
 							if ( isBlocked ) {
@@ -318,7 +317,7 @@ function fandom_user(lang, msg, namespace, username, wiki, querystring, fragment
 								if ( block.reason ) block.text = block.text.replaceSave( '%4$s', block.reason.toPlaintext() );
 								text += '\n\n**' + block.header + '**\n' + block.text;
 							}
-							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.user.info.loading + '**';
+							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**';
 						}
 						
 						msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler) );

+ 32 - 25
cmds/wiki/gamepedia.js

@@ -1,5 +1,6 @@
 const htmlparser = require('htmlparser2');
 const {MessageEmbed} = require('discord.js');
+const Lang = require('../../util/i18n.js');
 const extract_desc = require('../../util/extract_desc.js');
 
 const fs = require('fs');
@@ -39,11 +40,11 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 		msg.reactEmoji('⚠️');
 	}
 	var invoke = title.split(' ')[0].toLowerCase();
-	var aliasInvoke = ( lang.aliases[invoke] || invoke );
+	var aliasInvoke = ( lang.get('aliases')[invoke] || invoke );
 	var args = title.split(' ').slice(1);
 	
-	var mcaliasInvoke = ( lang.minecraft.aliases[invoke] || invoke );
-	if ( !msg.notMinecraft && wiki === lang.minecraft.link && ( mcaliasInvoke in minecraft || invoke.startsWith( '/' ) ) ) {
+	var mcaliasInvoke = ( lang.get('minecraft.aliases')[invoke] || invoke );
+	if ( !msg.notMinecraft && wiki === lang.get('minecraft.link') && ( mcaliasInvoke in minecraft || invoke.startsWith( '/' ) ) ) {
 		minecraft.WIKI = this;
 		if ( mcaliasInvoke in minecraft ) minecraft[mcaliasInvoke](lang, msg, args, title, cmd, querystring, fragment, reaction, spoiler);
 		else minecraft.SYNTAX(lang, msg, invoke.substring(1), args, title, cmd, querystring, fragment, reaction, spoiler);
@@ -187,27 +188,30 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 										text = '';
 									}
 									else if ( !srbody.continue ) {
-										text = '\n' + lang.search.infopage.replaceSave( '%s', '`' + prefix + cmd + lang.search.page + ' ' + title + linksuffix + '`' );
+										text = '\n' + lang.get('search.infopage').replaceSave( '%s', '`' + prefix + cmd + lang.get('search.page') + ' ' + title + linksuffix + '`' );
 									}
 									else {
-										text = '\n' + lang.search.infosearch.replaceSave( '%1$s', '`' + prefix + cmd + lang.search.page + ' ' + title + linksuffix + '`' ).replaceSave( '%2$s', '`' + prefix + cmd + lang.search.search + ' ' + title + linksuffix + '`' );
+										text = '\n' + lang.get('search.infosearch').replaceSave( '%1$s', '`' + prefix + cmd + lang.get('search.page') + ' ' + title + linksuffix + '`' ).replaceSave( '%2$s', '`' + prefix + cmd + lang.get('search.search') + ' ' + title + linksuffix + '`' );
 									}
 									
 									if ( querypage.categoryinfo ) {
-										var langCat = lang.search.category;
-										var category = [langCat.content];
-										if ( querypage.categoryinfo.size === 0 ) category.push(langCat.empty);
+										var langCat = new Lang(lang.lang, 'search.category');
+										var category = [langCat.get('content')];
+										if ( querypage.categoryinfo.size === 0 ) category.push(langCat.get('empty'));
 										if ( querypage.categoryinfo.pages > 0 ) {
-											var pages = querypage.categoryinfo.pages;
-											category.push(( langCat.pages[pages] || langCat.pages['*' + pages % 100] || langCat.pages['*' + pages % 10] || langCat.pages.default ).replaceSave( '%s', pages ));
+											let pages = querypage.categoryinfo.pages;
+											let count = langCat.get('pages');
+											category.push(( count[pages] || count['*' + pages % 100] || count['*' + pages % 10] || langCat.get('pages.default') ).replaceSave( '%s', pages ));
 										}
 										if ( querypage.categoryinfo.files > 0 ) {
-											var files = querypage.categoryinfo.files;
-											category.push(( langCat.files[files] || langCat.files['*' + files % 100] || langCat.files['*' + files % 10] || langCat.files.default ).replaceSave( '%s', files ));
+											let files = querypage.categoryinfo.files;
+											let count = langCat.get('files');
+											category.push(( count[files] || count['*' + files % 100] || count['*' + files % 10] || langCat.get('files.default') ).replaceSave( '%s', files ));
 										}
 										if ( querypage.categoryinfo.subcats > 0 ) {
-											var subcats = querypage.categoryinfo.subcats;
-											category.push(( langCat.subcats[subcats] || langCat.subcats['*' + subcats % 100] || langCat.subcats['*' + subcats % 10] || langCat.subcats.default ).replaceSave( '%s', subcats ));
+											let subcats = querypage.categoryinfo.subcats;
+											let count = langCat.get('subcats');
+											category.push(( count[subcats] || count['*' + subcats % 100] || count['*' + subcats % 10] || langCat.get('subcats.default') ).replaceSave( '%s', subcats ));
 										}
 										if ( msg.showEmbed() ) embed.addField( category[0], category.slice(1).join('\n') );
 										else text += '\n\n' + category.join('\n');
@@ -257,20 +261,23 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 							} else embed.setThumbnail( pageimage );
 						} else embed.setThumbnail( ( body.query.general.logo.startsWith( '//' ) ? 'https:' : '' ) + body.query.general.logo );
 						if ( querypage.categoryinfo ) {
-							var langCat = lang.search.category;
-							var category = [langCat.content];
-							if ( querypage.categoryinfo.size === 0 ) category.push(langCat.empty);
+							var langCat = new Lang(lang.lang, 'search.category');
+							var category = [langCat.get('content')];
+							if ( querypage.categoryinfo.size === 0 ) category.push(langCat.get('empty'));
 							if ( querypage.categoryinfo.pages > 0 ) {
-								var pages = querypage.categoryinfo.pages;
-								category.push(( langCat.pages[pages] || langCat.pages['*' + pages % 100] || langCat.pages['*' + pages % 10] || langCat.pages.default ).replaceSave( '%s', pages ));
+								let pages = querypage.categoryinfo.pages;
+								let count = langCat.get('pages');
+								category.push(( count[pages] || count['*' + pages % 100] || count['*' + pages % 10] || langCat.get('pages.default') ).replaceSave( '%s', pages ));
 							}
 							if ( querypage.categoryinfo.files > 0 ) {
-								var files = querypage.categoryinfo.files;
-								category.push(( langCat.files[files] || langCat.files['*' + files % 100] || langCat.files['*' + files % 10] || langCat.files.default ).replaceSave( '%s', files ));
+								let files = querypage.categoryinfo.files;
+								let count = langCat.get('files');
+								category.push(( count[files] || count['*' + files % 100] || count['*' + files % 10] || langCat.get('files.default') ).replaceSave( '%s', files ));
 							}
 							if ( querypage.categoryinfo.subcats > 0 ) {
-								var subcats = querypage.categoryinfo.subcats;
-								category.push(( langCat.subcats[subcats] || langCat.subcats['*' + subcats % 100] || langCat.subcats['*' + subcats % 10] || langCat.subcats.default ).replaceSave( '%s', subcats ));
+								let subcats = querypage.categoryinfo.subcats;
+								let count = langCat.get('subcats');
+								category.push(( count[subcats] || count['*' + subcats % 100] || count['*' + subcats % 10] || langCat.get('subcats.default') ).replaceSave( '%s', subcats ));
 							}
 							if ( msg.showEmbed() ) embed.addField( category[0], category.slice(1).join('\n') );
 							else text += '\n\n' + category.join('\n');
@@ -290,7 +297,7 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 						if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) {
 							var iwtitle = decodeURIComponent( inter.url.replace( regex[0], '' ) ).replace( /\_/g, ' ' ).replaceSave( intertitle.replace( /\_/g, ' ' ), intertitle );
 							selfcall++;
-							this.gamepedia(lang, msg, iwtitle, 'https://' + regex[1] + '.gamepedia.com/', ' !' + regex[1] + ' ', reaction, spoiler, querystring, fragment, selfcall);
+							this.gamepedia(lang, msg, iwtitle, 'https://' + regex[1] + '.gamepedia.com/', '!' + regex[1] + ' ', reaction, spoiler, querystring, fragment, selfcall);
 						} else {
 							if ( reaction ) reaction.removeEmoji();
 							console.log( '- Aborted, paused.' );
@@ -301,7 +308,7 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 							if ( msg.channel.type !== 'text' || !pause[msg.guild.id] ) {
 								var iwtitle = decodeURIComponent( inter.url.replace( regex[0], '' ) ).replace( /\_/g, ' ' ).replaceSave( intertitle.replace( /\_/g, ' ' ), intertitle );
 								selfcall++;
-								this.fandom(lang, msg, iwtitle, 'https://' + regex[1] + '/', ' ?' + ( regex[3] ? regex[3] + '.' : '' ) + regex[2] + ' ', reaction, spoiler, querystring, fragment, selfcall);
+								this.fandom(lang, msg, iwtitle, 'https://' + regex[1] + '/', '?' + ( regex[3] ? regex[3] + '.' : '' ) + regex[2] + ' ', reaction, spoiler, querystring, fragment, selfcall);
 							} else {
 								if ( reaction ) reaction.removeEmoji();
 								console.log( '- Aborted, paused.' );

+ 24 - 24
cmds/wiki/gamepedia/diff.js

@@ -71,7 +71,7 @@ function gamepedia_diff(lang, msg, args, wiki, reaction, spoiler, embed) {
 						msg.reactEmoji('nowiki');
 					}
 					else if ( noerror ) {
-						msg.replyMsg( lang.diff.badrev );
+						msg.replyMsg( lang.get('diff.badrev') );
 					}
 					else {
 						console.log( '- ' + response.statusCode + ': Error while getting the search results: ' + ( body && body.error && body.error.info ) );
@@ -94,7 +94,7 @@ function gamepedia_diff(lang, msg, args, wiki, reaction, spoiler, embed) {
 							argids = [ids.torevid, ids.fromrevid];
 							var compare = ['', ''];
 							if ( ids.fromtexthidden === undefined && ids.totexthidden === undefined && ids['*'] !== undefined ) {
-								var more = '\n__' + lang.diff.info.more + '__';
+								var more = '\n__' + lang.get('diff.info.more') + '__';
 								var current_tag = '';
 								var small_prev_ins = '';
 								var small_prev_del = '';
@@ -166,16 +166,16 @@ function gamepedia_diff(lang, msg, args, wiki, reaction, spoiler, embed) {
 								if ( small_prev_del.length ) {
 									if ( small_prev_del.replace( /\~\~/g, '' ).trim().length ) {
 										compare[0] = small_prev_del.replace( /\~\~\~\~/g, '' );
-									} else compare[0] = '__' + lang.diff.info.whitespace + '__';
+									} else compare[0] = '__' + lang.get('diff.info.whitespace') + '__';
 								}
 								if ( small_prev_ins.length ) {
 									if ( small_prev_ins.replace( /\*\*/g, '' ).trim().length ) {
 										compare[1] = small_prev_ins.replace( /\*\*\*\*/g, '' );
-									} else compare[1] = '__' + lang.diff.info.whitespace + '__';
+									} else compare[1] = '__' + lang.get('diff.info.whitespace') + '__';
 								}
 							}
-							else if ( ids.fromtexthidden !== undefined ) compare[0] = '__' + lang.diff.hidden + '__';
-							else if ( ids.totexthidden !== undefined ) compare[1] = '__' + lang.diff.hidden + '__';
+							else if ( ids.fromtexthidden !== undefined ) compare[0] = '__' + lang.get('diff.hidden') + '__';
+							else if ( ids.totexthidden !== undefined ) compare[1] = '__' + lang.get('diff.hidden') + '__';
 						}
 						gamepedia_diff_send(lang, msg, argids, wiki, reaction, spoiler, compare);
 					}
@@ -222,7 +222,7 @@ function gamepedia_diff_send(lang, msg, args, wiki, reaction, spoiler, compare)
 		}
 		else {
 			if ( body.query.badrevids ) {
-				msg.replyMsg( lang.diff.badrev );
+				msg.replyMsg( lang.get('diff.badrev') );
 				
 				if ( reaction ) reaction.removeEmoji();
 			}
@@ -238,12 +238,12 @@ function gamepedia_diff_send(lang, msg, args, wiki, reaction, spoiler, compare)
 					var revisions = pages[0].revisions.sort( (first, second) => Date.parse(second.timestamp) - Date.parse(first.timestamp) );
 					var diff = revisions[0].revid;
 					var oldid = ( revisions[1] ? revisions[1].revid : 0 );
-					var editor = [lang.diff.info.editor, ( revisions[0].userhidden !== undefined ? lang.diff.hidden : revisions[0].user )];
-					var timestamp = [lang.diff.info.timestamp, new Date(revisions[0].timestamp).toLocaleString(lang.dateformat, timeoptions)];
+					var editor = [lang.get('diff.info.editor'), ( revisions[0].userhidden !== undefined ? lang.get('diff.hidden') : revisions[0].user )];
+					var timestamp = [lang.get('diff.info.timestamp'), new Date(revisions[0].timestamp).toLocaleString(lang.get('dateformat'), timeoptions)];
 					var difference = revisions[0].size - ( revisions[1] ? revisions[1].size : 0 );
-					var size = [lang.diff.info.size, lang.diff.info.bytes.replace( '%s', ( difference > 0 ? '+' : '' ) + difference )];
-					var comment = [lang.diff.info.comment, ( revisions[0].commenthidden !== undefined ? lang.diff.hidden : ( revisions[0].comment ? revisions[0].comment.toFormatting(msg.showEmbed(), wiki, body.query.general, title) : lang.diff.nocomment ) )];
-					if ( revisions[0].tags.length ) var tags = [lang.diff.info.tags, body.query.tags.filter( tag => revisions[0].tags.includes( tag.name ) ).map( tag => tag.displayname ).join(', ')];
+					var size = [lang.get('diff.info.size'), lang.get('diff.info.bytes').replace( '%s', ( difference > 0 ? '+' : '' ) + difference )];
+					var comment = [lang.get('diff.info.comment'), ( revisions[0].commenthidden !== undefined ? lang.get('diff.hidden') : ( revisions[0].comment ? revisions[0].comment.toFormatting(msg.showEmbed(), wiki, body.query.general, title) : lang.get('diff.nocomment') ) )];
+					if ( revisions[0].tags.length ) var tags = [lang.get('diff.info.tags'), body.query.tags.filter( tag => revisions[0].tags.includes( tag.name ) ).map( tag => tag.displayname ).join(', ')];
 					
 					var pagelink = wiki.toLink(title, 'diff=' + diff + '&oldid=' + oldid, '', body.query.general);
 					if ( msg.showEmbed() ) {
@@ -252,7 +252,7 @@ function gamepedia_diff_send(lang, msg, args, wiki, reaction, spoiler, compare)
 						if ( revisions[0].anon !== undefined ) {
 							editorlink = '[' + editor[1] + '](' + wiki.toLink('Special:Contributions/' + editor[1], '', '', body.query.general, true) + ')';
 						}
-						if ( editor[1] === lang.diff.hidden ) editorlink = editor[1];
+						if ( editor[1] === lang.get('diff.hidden') ) editorlink = editor[1];
 						var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( ( title + '?diff=' + diff + '&oldid=' + oldid ).escapeFormatting() ).setURL( pagelink ).addField( editor[0], editorlink, true ).addField( size[0], size[1], true ).addField( comment[0], comment[1] ).setFooter( timestamp[1] );
 						if ( tags ) {
 							var taglink = '';
@@ -274,7 +274,7 @@ function gamepedia_diff_send(lang, msg, args, wiki, reaction, spoiler, compare)
 							embed.addField( tags[0], tagtext );
 						}
 						
-						var more = '\n__' + lang.diff.info.more + '__';
+						var more = '\n__' + lang.get('diff.info.more') + '__';
 						if ( !compare && oldid ) got.get( wiki + 'api.php?action=compare&prop=diff&fromrev=' + oldid + '&torev=' + diff + '&format=json', {
 							responseType: 'json'
 						} ).then( cpresponse => {
@@ -367,20 +367,20 @@ function gamepedia_diff_send(lang, msg, args, wiki, reaction, spoiler, compare)
 								parser.end();
 								if ( small_prev_del.length ) {
 									if ( small_prev_del.replace( /\~\~/g, '' ).trim().length ) {
-										embed.addField( lang.diff.info.removed, small_prev_del.replace( /\~\~\~\~/g, '' ), true );
-									} else embed.addField( lang.diff.info.removed, '__' + lang.diff.info.whitespace + '__', true );
+										embed.addField( lang.get('diff.info.removed'), small_prev_del.replace( /\~\~\~\~/g, '' ), true );
+									} else embed.addField( lang.get('diff.info.removed'), '__' + lang.get('diff.info.whitespace') + '__', true );
 								}
 								if ( small_prev_ins.length ) {
 									if ( small_prev_ins.replace( /\*\*/g, '' ).trim().length ) {
-										embed.addField( lang.diff.info.added, small_prev_ins.replace( /\*\*\*\*/g, '' ), true );
-									} else embed.addField( lang.diff.info.added, '__' + lang.diff.info.whitespace + '__', true );
+										embed.addField( lang.get('diff.info.added'), small_prev_ins.replace( /\*\*\*\*/g, '' ), true );
+									} else embed.addField( lang.get('diff.info.added'), '__' + lang.get('diff.info.whitespace') + '__', true );
 								}
 							}
 							else if ( cpbody.compare.fromtexthidden !== undefined ) {
-								embed.addField( lang.diff.info.removed, '__' + lang.diff.hidden + '__', true );
+								embed.addField( lang.get('diff.info.removed'), '__' + lang.get('diff.hidden') + '__', true );
 							}
 							else if ( cpbody.compare.totexthidden !== undefined ) {
-								embed.addField( lang.diff.info.added, '__' + lang.diff.hidden + '__', true );
+								embed.addField( lang.get('diff.info.added'), '__' + lang.get('diff.hidden') + '__', true );
 							}
 						}, error => {
 							console.log( '- Error while getting the diff: ' + error );
@@ -391,8 +391,8 @@ function gamepedia_diff_send(lang, msg, args, wiki, reaction, spoiler, compare)
 						} );
 						else {
 							if ( compare ) {
-								if ( compare[0].length ) embed.addField( lang.diff.info.removed, compare[0], true );
-								if ( compare[1].length ) embed.addField( lang.diff.info.added, compare[1], true );
+								if ( compare[0].length ) embed.addField( lang.get('diff.info.removed'), compare[0], true );
+								if ( compare[1].length ) embed.addField( lang.get('diff.info.added'), compare[1], true );
 							}
 							else if ( revisions[0]['*'] ) {
 								var content = revisions[0]['*'].escapeFormatting();
@@ -402,8 +402,8 @@ function gamepedia_diff_send(lang, msg, args, wiki, reaction, spoiler, compare)
 										content = content.substring(0, 1000 - more.length);
 										content = '**' + content.substring(0, content.lastIndexOf('\n')) + '**' + more;
 									}
-									embed.addField( lang.diff.info.added, content, true );
-								} else embed.addField( lang.diff.info.added, '__' + lang.diff.info.whitespace + '__', true );
+									embed.addField( lang.get('diff.info.added'), content, true );
+								} else embed.addField( lang.get('diff.info.added'), '__' + lang.get('diff.info.whitespace') + '__', true );
 							}
 							
 							msg.sendChannel( spoiler + text + spoiler, {embed} );

+ 32 - 32
cmds/wiki/gamepedia/overview.js

@@ -29,13 +29,13 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler) {
 			if ( allSites.some( site => site.wiki_domain === body.query.general.servername ) ) {
 				site = allSites.find( site => site.wiki_domain === body.query.general.servername );
 				
-				var name = [lang.overview.name, site.wiki_display_name];
-				var created = [lang.overview.created, new Date(parseInt(site.created + '000', 10)).toLocaleString(lang.dateformat, timeoptions)];
-				var manager = [lang.overview.manager, site.wiki_managers];
-				var official = [lang.overview.official, ( site.official_wiki ? lang.overview.yes : lang.overview.no )];
-				var crossover = [lang.overview.crossover, ( site.wiki_crossover ? '<https://' + site.wiki_crossover + '/>' : '' )];
-				var description = [lang.overview.description, site.wiki_description];
-				var image = [lang.overview.image, site.wiki_image];
+				var name = [lang.get('overview.name'), site.wiki_display_name];
+				var created = [lang.get('overview.created'), new Date(parseInt(site.created + '000', 10)).toLocaleString(lang.get('dateformat'), timeoptions)];
+				var manager = [lang.get('overview.manager'), site.wiki_managers];
+				var official = [lang.get('overview.official'), lang.get('overview.' + ( site.official_wiki ? 'yes' : 'no' ))];
+				var crossover = [lang.get('overview.crossover'), ( site.wiki_crossover ? '<https://' + site.wiki_crossover + '/>' : '' )];
+				var description = [lang.get('overview.description'), site.wiki_description];
+				var image = [lang.get('overview.image'), site.wiki_image];
 				
 				if ( description[1] ) {
 					description[1] = description[1].escapeFormatting();
@@ -43,10 +43,10 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler) {
 				}
 				if ( image[1] && image[1].startsWith( '/' ) ) image[1] = wiki.substring(0, wiki.length - 1) + image[1];
 			}
-			var articles = [lang.overview.articles, body.query.statistics.articles];
-			var pages = [lang.overview.pages, body.query.statistics.pages];
-			var edits = [lang.overview.edits, body.query.statistics.edits];
-			var users = [lang.overview.users, body.query.statistics.activeusers];
+			var articles = [lang.get('overview.articles'), body.query.statistics.articles];
+			var pages = [lang.get('overview.pages'), body.query.statistics.pages];
+			var edits = [lang.get('overview.edits'), body.query.statistics.edits];
+			var users = [lang.get('overview.users'), body.query.statistics.activeusers];
 			
 			var title = body.query.pages['-1'].title;
 			var pagelink = wiki.toLink(title, '', '', body.query.general);
@@ -73,14 +73,14 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler) {
 				else if ( ovbody.items.some( site => site.url === body.query.general.server + ( body.query.general.scriptpath ? body.query.general.scriptpath + '/' : '' ) ) ) {
 					site = ovbody.items.find( site => site.url === body.query.general.server + ( body.query.general.scriptpath ? body.query.general.scriptpath + '/' : '' ) );
 					
-					var vertical = [lang.overview.vertical, site.hub];
-					var topic = [lang.overview.topic, site.topic];
-					var founder = [lang.overview.founder, site.founding_user_id];
-					var manager = [lang.overview.manager, body.query.allmessages[0]['*']];
-					var crossover = [lang.overview.crossover, ( body.query.allmessages[1]['*'] ? '<https://' + body.query.allmessages[1]['*'] + '.gamepedia.com/>' : '' )];
-					var created = [lang.overview.created, new Date(site.creation_date).toLocaleString(lang.dateformat, timeoptions)];
-					var description = [lang.overview.description, site.desc];
-					var image = [lang.overview.image, site.image];
+					var vertical = [lang.get('overview.vertical'), site.hub];
+					var topic = [lang.get('overview.topic'), site.topic];
+					var founder = [lang.get('overview.founder'), site.founding_user_id];
+					var manager = [lang.get('overview.manager'), body.query.allmessages[0]['*']];
+					var crossover = [lang.get('overview.crossover'), ( body.query.allmessages[1]['*'] ? '<https://' + body.query.allmessages[1]['*'] + '.gamepedia.com/>' : '' )];
+					var created = [lang.get('overview.created'), new Date(site.creation_date).toLocaleString(lang.get('dateformat'), timeoptions)];
+					var description = [lang.get('overview.description'), site.desc];
+					var image = [lang.get('overview.image'), site.image];
 					
 					if ( description[1] ) {
 						description[1] = description[1].escapeFormatting();
@@ -114,8 +114,8 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler) {
 					} ).finally( () => {
 						if ( msg.showEmbed() ) {
 							embed.addField( founder[0], founder[1], true );
-							if ( manager[1] ) embed.addField( manager[0], '[' + manager[1] + '](' + wiki.toLink('User:' + manager[1], '', '', body.query.general, true) + ') ([' + lang.overview.talk + '](' + wiki.toLink('User talk:' + manager[1], '', '', body.query.general, true) + '))', true );
-							embed.addField( created[0], created[1], true ).addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).setFooter( lang.overview.inaccurate );
+							if ( manager[1] ) embed.addField( manager[0], '[' + manager[1] + '](' + wiki.toLink('User:' + manager[1], '', '', body.query.general, true) + ') ([' + lang.get('overview.talk') + '](' + wiki.toLink('User talk:' + manager[1], '', '', body.query.general, true) + '))', true );
+							embed.addField( created[0], created[1], true ).addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).setFooter( lang.get('overview.inaccurate') );
 							if ( crossover[1] ) {
 								var crossoverSite = allSites.find( site => '<https://' + site.wiki_domain + '/>' === crossover[1] );
 								if ( crossoverSite ) embed.addField( crossover[0], '[' + crossoverSite.wiki_display_name + '](' + crossover[1] + ')', true );
@@ -132,7 +132,7 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler) {
 								text += '\n' + image.join(' ');
 								if ( msg.uploadFiles() ) embed.files = [image[1]];
 							}
-							text += '\n\n*' + lang.overview.inaccurate + '*';
+							text += '\n\n*' + lang.get('overview.inaccurate') + '*';
 						}
 						
 						msg.sendChannel( spoiler + text + spoiler, {embed} );
@@ -140,9 +140,9 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler) {
 						if ( reaction ) reaction.removeEmoji();
 					} );
 					else {
-						founder[1] = lang.overview.none;
+						founder[1] = lang.get('overview.none');
 						if ( msg.showEmbed() ) {
-							embed.addField( founder[0], founder[1], true ).addField( created[0], created[1], true ).addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).setFooter( lang.overview.inaccurate );
+							embed.addField( founder[0], founder[1], true ).addField( created[0], created[1], true ).addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).setFooter( lang.get('overview.inaccurate') );
 							if ( crossover[1] ) {
 								var crossoverSite = allSites.find( site => '<https://' + site.wiki_domain + '/>' === crossover[1] );
 								if ( crossoverSite ) embed.addField( crossover[0], '[' + crossoverSite.wiki_display_name + '](' + crossover[1] + ')', true );
@@ -159,7 +159,7 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler) {
 								text += '\n' + image.join(' ');
 								if ( msg.uploadFiles() ) embed.files = [image[1]];
 							}
-							text += '\n\n*' + lang.overview.inaccurate + '*';
+							text += '\n\n*' + lang.get('overview.inaccurate') + '*';
 						}
 						
 						msg.sendChannel( spoiler + text + spoiler, {embed} );
@@ -168,8 +168,8 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler) {
 					}
 				}
 				else {
-					if ( msg.showEmbed() ) embed.addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).setTimestamp( msg.client.readyTimestamp ).setFooter( lang.overview.inaccurate );
-					else text = articles.join(' ') + '\n' + pages.join(' ') + '\n' + edits.join(' ') + '\n' + users.join(' ') + '\n\n*' + lang.overview.inaccurate + '*';
+					if ( msg.showEmbed() ) embed.addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).setTimestamp( msg.client.readyTimestamp ).setFooter( lang.get('overview.inaccurate') );
+					else text = articles.join(' ') + '\n' + pages.join(' ') + '\n' + edits.join(' ') + '\n' + users.join(' ') + '\n\n*' + lang.get('overview.inaccurate') + '*';
 					
 					msg.sendChannel( spoiler + text + spoiler, {embed} );
 					
@@ -184,10 +184,10 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler) {
 			else {
 				if ( msg.showEmbed() ) {
 					if ( site ) {
-						var managerlist = manager[1].map( wm => '[' + wm + '](' + wiki.toLink('User:' + wm, '', '', body.query.general, true) + ') ([' + lang.overview.talk + '](' + wiki.toLink('User talk:' + wm, '', '', body.query.general, true) + '))' ).join('\n');
-						embed.addField( name[0], name[1], true ).addField( created[0], created[1], true ).addField( manager[0], ( managerlist || lang.overview.none ), true ).addField( official[0], official[1], true );
+						var managerlist = manager[1].map( wm => '[' + wm + '](' + wiki.toLink('User:' + wm, '', '', body.query.general, true) + ') ([' + lang.get('overview.talk') + '](' + wiki.toLink('User talk:' + wm, '', '', body.query.general, true) + '))' ).join('\n');
+						embed.addField( name[0], name[1], true ).addField( created[0], created[1], true ).addField( manager[0], ( managerlist || lang.get('overview.none') ), true ).addField( official[0], official[1], true );
 					}
-					embed.addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).setTimestamp( msg.client.readyTimestamp ).setFooter( lang.overview.inaccurate );
+					embed.addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).setTimestamp( msg.client.readyTimestamp ).setFooter( lang.get('overview.inaccurate') );
 					if ( site ) {
 						if ( crossover[1] ) embed.addField( crossover[0], crossover[1], true );
 						if ( description[1] ) embed.addField( description[0], description[1] );
@@ -195,7 +195,7 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler) {
 					}
 				}
 				else {
-					if ( site ) text += name.join(' ') + '\n' + created.join(' ') + '\n' + manager[0] + ' ' + ( manager[1].join(', ') || lang.overview.none ) + '\n' + official.join(' ') + '\n';
+					if ( site ) text += name.join(' ') + '\n' + created.join(' ') + '\n' + manager[0] + ' ' + ( manager[1].join(', ') || lang.get('overview.none') ) + '\n' + official.join(' ') + '\n';
 					text += articles.join(' ') + '\n' + pages.join(' ') + '\n' + edits.join(' ') + '\n' + users.join(' ');
 					if ( site ) {
 						if ( crossover[1] ) text += '\n' + crossover.join(' ');
@@ -205,7 +205,7 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler) {
 							if ( msg.uploadFiles() ) embed.files = [{attachment:image[1],name:( spoiler ? 'SPOILER ' : '' ) + name[1] + image[1].substring(image[1].lastIndexOf('.'))}];
 						}
 					}
-					text += '\n\n*' + lang.overview.inaccurate + '*';
+					text += '\n\n*' + lang.get('overview.inaccurate') + '*';
 				}
 				
 				msg.sendChannel( spoiler + text + spoiler, {embed} );

+ 2 - 1
cmds/wiki/gamepedia/search.js

@@ -34,7 +34,8 @@ function gamepedia_search(lang, msg, searchterm, wiki, query, reaction, spoiler)
 			body.query.search.forEach( result => {
 				description.push( '• [' + result.title + '](' + wiki.toLink(result.title, '', '', query.general, true) + ')' + ( result.sectiontitle ? ' § [' + result.sectiontitle + '](' + wiki.toLink(result.title, '', result.sectiontitle, query.general, true) + ')' : '' ) + ( result.redirecttitle ? ' (⤷ [' + result.redirecttitle + '](' + wiki.toLink(result.redirecttitle, '', '', query.general, true) + '))' : '' ) );
 			} );
-			embed.setFooter( ( lang.search.results[body.query.searchinfo.totalhits] || lang.search.results['*' + body.query.searchinfo.totalhits % 100] || lang.search.results['*' + body.query.searchinfo.totalhits % 10]  || lang.search.results.default ).replaceSave( '%s', body.query.searchinfo.totalhits ) );
+			let count = lang.get('search.results');
+			embed.setFooter( ( count[body.query.searchinfo.totalhits] || count['*' + body.query.searchinfo.totalhits % 100] || count['*' + body.query.searchinfo.totalhits % 10]  || lang.get('search.results.default') ).replaceSave( '%s', body.query.searchinfo.totalhits ) );
 		}
 	}, error => {
 		console.log( '- Error while getting the search results.' + error );

+ 34 - 35
cmds/wiki/gamepedia/user.js

@@ -2,7 +2,7 @@ const htmlparser = require('htmlparser2');
 const {MessageEmbed} = require('discord.js');
 const global_block = require('../../../functions/global_block.js');
 const extract_desc = require('../../../util/extract_desc.js');
-const {timeoptions} = require('../../../util/default.json');
+const {timeoptions, usergroups} = require('../../../util/default.json');
 
 var allSites = [];
 const getAllSites = require('../../../util/allSites.js');
@@ -56,18 +56,18 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 				if ( !querypage.noRedirect || ( querypage.missing === undefined && querypage.ns !== -1 ) ) namespace = contribs;
 				var blocks = body.query.blocks.map( block => {
 					var isBlocked = false;
-					var blockedtimestamp = new Date(block.timestamp).toLocaleString(lang.dateformat, timeoptions);
+					var blockedtimestamp = new Date(block.timestamp).toLocaleString(lang.get('dateformat'), timeoptions);
 					var blockexpiry = block.expiry;
 					if ( blockexpiry === 'infinity' ) {
-						blockexpiry = lang.user.block.until_infinity;
+						blockexpiry = lang.get('user.block.until_infinity');
 						isBlocked = true;
 					} else if ( blockexpiry ) {
 						if ( Date.parse(blockexpiry) > Date.now() ) isBlocked = true;
-						blockexpiry = new Date(blockexpiry).toLocaleString(lang.dateformat, timeoptions);
+						blockexpiry = new Date(blockexpiry).toLocaleString(lang.get('dateformat'), timeoptions);
 					}
 					if ( isBlocked ) return {
-						header: lang.user.block.header.replaceSave( '%s', block.user ).escapeFormatting(),
-						text: lang.user.block[( block.reason ? 'text' : 'noreason' )].replaceSave( '%1$s', blockedtimestamp ).replaceSave( '%2$s', blockexpiry ),
+						header: lang.get('user.block.header').replaceSave( '%s', block.user ).escapeFormatting(),
+						text: lang.get('user.block.' + ( block.reason ? 'text' : 'noreason' )).replaceSave( '%1$s', blockedtimestamp ).replaceSave( '%2$s', blockexpiry ),
 						by: block.by,
 						reason: block.reason
 					};
@@ -108,7 +108,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 						}
 					}
 					else {
-						var editcount = [lang.user.info.editcount, ( username.includes( '/' ) && ( ( username.includes( ':' ) && range % 16 ) || range % 8 ) ? '~' : '' ) + ucbody.query.usercontribs.length + ( ucbody.continue ? '+' : '' )];
+						var editcount = [lang.get('user.info.editcount'), ( username.includes( '/' ) && ( ( username.includes( ':' ) && range % 16 ) || range % 8 ) ? '~' : '' ) + ucbody.query.usercontribs.length + ( ucbody.continue ? '+' : '' )];
 						
 						var pagelink = wiki.toLink(namespace + username, querystring.toTitle(), fragment, body.query.general);
 						if ( msg.showEmbed() ) {
@@ -128,7 +128,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 								if ( block.reason ) block.text = block.text.replaceSave( '%4$s', block.reason.toMarkdown(wiki, body.query.general) );
 								embed.addField( block.header, block.text );
 							} );
-							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.user.info.loading + '**' );
+							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
 						}
 						else {
 							var embed = {};
@@ -138,7 +138,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 								if ( block.reason ) block.text = block.text.replaceSave( '%4$s', block.reason.toPlaintext() );
 								text += '\n\n**' + block.header + '**\n' + block.text;
 							} );
-							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.user.info.loading + '**';
+							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**';
 						}
 						
 						msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler) );
@@ -203,49 +203,48 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 				}
 				else {
 					username = queryuser.name;
-					var gender = [lang.user.info.gender];
+					var gender = [lang.get('user.info.gender')];
 					switch (queryuser.gender) {
 						case 'male':
-							gender.push(lang.user.gender.male);
+							gender.push(lang.get('user.gender.male'));
 							break;
 						case 'female':
-							gender.push(lang.user.gender.female);
+							gender.push(lang.get('user.gender.female'));
 							break;
 						default: 
-							gender.push(lang.user.gender.unknown);
+							gender.push(lang.get('user.gender.unknown'));
 					}
-					var registration = [lang.user.info.registration, new Date(queryuser.registration).toLocaleString(lang.dateformat, timeoptions)];
-					var editcount = [lang.user.info.editcount, queryuser.editcount];
+					var registration = [lang.get('user.info.registration'), new Date(queryuser.registration).toLocaleString(lang.get('dateformat'), timeoptions)];
+					var editcount = [lang.get('user.info.editcount'), queryuser.editcount];
 					var groups = queryuser.groups;
-					var group = [lang.user.info.group];
-					var grouplist = lang.user.groups;
-					for ( var i = 0; i < grouplist.length; i++ ) {
-						if ( groups.includes( grouplist[i][0] ) && ( group.length === 1 || !['autoconfirmed', 'user'].includes( grouplist[i][0] ) ) ) {
+					var group = [lang.get('user.info.group')];
+					for ( var i = 0; i < usergroups.length; i++ ) {
+						if ( groups.includes( usergroups[i] ) && ( group.length === 1 || !['autoconfirmed', 'user'].includes( usergroups[i] ) ) ) {
 							var thisSite = allSites.find( site => site.wiki_domain === body.query.general.servername );
-							if ( grouplist[i][0] === 'wiki_manager' && thisSite && thisSite.wiki_managers.includes( username ) ) {
-								group.push('**' + grouplist[i][1] + '**');
+							if ( usergroups[i] === 'wiki_manager' && thisSite && thisSite.wiki_managers.includes( username ) ) {
+								group.push('**' + lang.get('user.groups.' + usergroups[i]) + '**');
 							}
-							else if ( !groups.includes( 'global_' + grouplist[i][0] ) || queryuser.groupmemberships.some( member => member.group === grouplist[i][0] ) ) {
-								group.push(grouplist[i][1]);
+							else if ( !groups.includes( 'global_' + usergroups[i] ) || queryuser.groupmemberships.some( member => member.group === usergroups[i] ) ) {
+								group.push(lang.get('user.groups.' + usergroups[i]));
 							}
 						}
 					}
 					var isBlocked = false;
-					var blockedtimestamp = new Date(queryuser.blockedtimestamp).toLocaleString(lang.dateformat, timeoptions);
+					var blockedtimestamp = new Date(queryuser.blockedtimestamp).toLocaleString(lang.get('dateformat'), timeoptions);
 					var blockexpiry = queryuser.blockexpiry;
 					if ( blockexpiry === 'infinity' ) {
-						blockexpiry = lang.user.block.until_infinity;
+						blockexpiry = lang.get('user.block.until_infinity');
 						isBlocked = true;
 					} else if ( blockexpiry ) {
 						var blockexpirydate = blockexpiry.replace( /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2,3})/, '$1-$2-$3T$4:$5:$6Z' );
-						blockexpiry = new Date(blockexpirydate).toLocaleString(lang.dateformat, timeoptions);
+						blockexpiry = new Date(blockexpirydate).toLocaleString(lang.get('dateformat'), timeoptions);
 						if ( Date.parse(blockexpirydate) > Date.now() ) isBlocked = true;
 					}
 					var blockedby = queryuser.blockedby;
 					var blockreason = queryuser.blockreason;
 					var block = {
-						header: lang.user.block.header.replaceSave( '%s', username ).escapeFormatting(),
-						text: lang.user.block[( blockreason ? 'text' : 'noreason' )].replaceSave( '%1$s', blockedtimestamp ).replaceSave( '%2$s', blockexpiry ),
+						header: lang.get('user.block.header').replaceSave( '%s', username ).escapeFormatting(),
+						text: lang.get('user.block.' + ( blockreason ? 'text' : 'noreason' )).replaceSave( '%1$s', blockedtimestamp ).replaceSave( '%2$s', blockexpiry ),
 						by: blockedby,
 						reason: blockreason
 					};
@@ -282,14 +281,14 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 								if ( msg.channel.type === 'text' ) var discordmember = msg.guild.members.cache.find( member => {
 									return member.user.tag === pbody.profile['link-discord'].replace( /^\s*([^@#:]{2,32}?)\s*#(\d{4,6})\s*$/, '$1#$2' );
 								} );
-								var discordname = [lang.user.info.discord,pbody.profile['link-discord'].escapeFormatting()];
+								var discordname = [lang.get('user.info.discord'),pbody.profile['link-discord'].escapeFormatting()];
 								if ( discordmember ) discordname[1] = discordmember.toString();
 								
 								if ( msg.showEmbed() ) embed.addField( discordname[0], discordname[1], true );
 								else text += '\n' + discordname.join(' ');
 							}
 							if ( pbody.profile['favwiki'] ) {
-								var favwiki = [lang.user.info.favwiki,allSites.find( site => site.md5_key === pbody.profile['favwiki'] )];
+								var favwiki = [lang.get('user.info.favwiki'),allSites.find( site => site.md5_key === pbody.profile['favwiki'] )];
 								if ( favwiki[1] ) {
 									if ( msg.showEmbed() ) embed.addField( favwiki[0], '[' + favwiki[1].wiki_display_name + '](<https://' + favwiki[1].wiki_domain + '/>)', true );
 									else text += '\n' + favwiki[0] + ' <https://' + favwiki[1].wiki_domain + '/>';
@@ -305,7 +304,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 								if ( block.reason ) block.text = block.text.replaceSave( '%4$s', block.reason.toMarkdown(wiki, body.query.general) );
 								embed.addField( block.header, block.text );
 							}
-							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.user.info.loading + '**' );
+							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
 						}
 						else {
 							if ( isBlocked ) {
@@ -313,7 +312,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 								if ( block.reason ) block.text = block.text.replaceSave( '%4$s', block.reason.toPlaintext() );
 								text += '\n\n**' + block.header + '**\n' + block.text;
 							}
-							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.user.info.loading + '**';
+							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**';
 						}
 						
 						msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler) );
@@ -343,7 +342,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 								if ( msg.channel.type === 'text' ) var discordmember = msg.guild.members.cache.find( member => {
 									return member.user.tag.escapeFormatting() === discordfield.value;
 								} );
-								var discordname = [lang.user.info.discord,discordfield.value];
+								var discordname = [lang.get('user.info.discord'),discordfield.value];
 								if ( discordmember ) discordname[1] = discordmember.toString();
 								
 								if ( msg.showEmbed() ) embed.addField( discordname[0], discordname[1], true );
@@ -367,7 +366,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 								if ( block.reason ) block.text = block.text.replaceSave( '%4$s', block.reason.toMarkdown(wiki, body.query.general) );
 								embed.addField( block.header, block.text );
 							}
-							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.user.info.loading + '**' );
+							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
 						}
 						else {
 							if ( isBlocked ) {
@@ -375,7 +374,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 								if ( block.reason ) block.text = block.text.replaceSave( '%4$s', block.reason.toPlaintext() );
 								text += '\n\n**' + block.header + '**\n' + block.text;
 							}
-							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.user.info.loading + '**';
+							if ( msg.channel.type === 'text' && msg.guild.id in patreons ) text += '\n\n<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**';
 						}
 						
 						msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler) );

+ 5 - 4
functions/discussion.js

@@ -4,7 +4,7 @@ const {MessageEmbed} = require('discord.js');
 function fandom_discussion(lang, msg, wiki, title, query, reaction, spoiler) {
 	if ( !title ) {
 		var pagelink = wiki + 'f';
-		var embed = new MessageEmbed().setAuthor( query.general.sitename ).setTitle( lang.discussion.main ).setURL( pagelink );
+		var embed = new MessageEmbed().setAuthor( query.general.sitename ).setTitle( lang.get('discussion.main') ).setURL( pagelink );
 		got.get( wiki + 'f' ).then( descresponse => {
 			var descbody = descresponse.body;
 			if ( descresponse.statusCode !== 200 || !descbody ) {
@@ -62,7 +62,7 @@ function fandom_discussion(lang, msg, wiki, title, query, reaction, spoiler) {
 			if ( reaction ) reaction.removeEmoji();
 		} );
 	}
-	else if ( title.split(' ')[0].toLowerCase() === 'post' || title.split(' ')[0].toLowerCase() === lang.discussion.post ) {
+	else if ( title.split(' ')[0].toLowerCase() === 'post' || title.split(' ')[0].toLowerCase() === lang.get('discussion.post') ) {
 		title = title.split(' ').slice(1).join(' ');
 		var limit = ( msg.channel.type === 'text' && msg.guild.id in patreons ? '100' : '50' );
 		got.get( 'https://services.fandom.com/discussion/' + query.wikidesc.id + '/posts?limit=' + limit + '&format=json', {
@@ -278,7 +278,8 @@ function discussion_send(lang, msg, wiki, discussion, embed, spoiler) {
 			embed.setImage( discussion._embedded.contentImages[0].url );
 			break;
 		case 'POLL':
-			discussion.poll.answers.forEach( answer => embed.addField( answer.text.escapeFormatting(), ( answer.image ? '[__' + lang.discussion.image.escapeFormatting() + '__](' + answer.image.url + ')\n' : '' ) + ( lang.discussion.votes[answer.votes] || lang.discussion.votes['*' + answer.votes % 100] || lang.discussion.votes['*' + answer.votes % 10] || lang.discussion.votes.default ).replace( '%s', answer.votes ), true ) );
+			let count = lang.get('discussion.votes');
+			discussion.poll.answers.forEach( answer => embed.addField( answer.text.escapeFormatting(), ( answer.image ? '[__' + lang.get('discussion.image').escapeFormatting() + '__](' + answer.image.url + ')\n' : '' ) + ( count[answer.votes] || count['*' + answer.votes % 100] || count['*' + answer.votes % 10] || lang.get('discussion.votes.default') ).replace( '%s', answer.votes ), true ) );
 			break;
 		case 'QUIZ':
 			description = discussion.quiz.title.escapeFormatting();
@@ -296,7 +297,7 @@ function discussion_send(lang, msg, wiki, discussion, embed, spoiler) {
 						else {
 							description = description.replace( /\{\@(\d+)\}/g, (match, n) => {
 								if ( n >= discussion._embedded.contentImages.length ) return '';
-								else return '[__' + lang.discussion.image.escapeFormatting() + '__](' + discussion._embedded.contentImages[n].url + ')';
+								else return '[__' + lang.get('discussion.image').escapeFormatting() + '__](' + discussion._embedded.contentImages[n].url + ')';
 							} );
 							embed.setThumbnail( discussion._embedded.contentImages[0].url );
 						}

+ 19 - 19
functions/global_block.js

@@ -19,12 +19,12 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler) {
 		else {
 			let $ = cheerio.load(body);
 			if ( $('#mw-content-text .errorbox').length ) {
-				if ( msg.showEmbed() ) embed.addField( lang.user.gblock.disabled, '\u200b' );
-				else text += '\n\n**' + lang.user.gblock.disabled + '**';
+				if ( msg.showEmbed() ) embed.addField( lang.get('user.gblock.disabled'), '\u200b' );
+				else text += '\n\n**' + lang.get('user.gblock.disabled') + '**';
 			}
 			else if ( $('.mw-warning-with-logexcerpt').length && !$(".mw-warning-with-logexcerpt .mw-logline-block").length ) {
-				if ( msg.showEmbed() ) embed.addField( lang.user.gblock.header.replaceSave( '%s', username ).escapeFormatting(), '\u200b' );
-				else text += '\n\n**' + lang.user.gblock.header.replaceSave( '%s', username ).escapeFormatting() + '**';
+				if ( msg.showEmbed() ) embed.addField( lang.get('user.gblock.header').replaceSave( '%s', username ).escapeFormatting(), '\u200b' );
+				else text += '\n\n**' + lang.get('user.gblock.header').replaceSave( '%s', username ).escapeFormatting() + '**';
 			}
 		}
 	}, error => {
@@ -40,10 +40,10 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler) {
 					let $ = cheerio.load(gbody);
 					var globaledits = $('#editcount .TablePager th').eq(7).text().replace( /[,\.]/g, '' );
 					if ( globaledits ) {
-						if ( msg.showEmbed() ) embed.spliceFields(1, 0, {name:lang.user.info.globaleditcount,value:'[' + globaledits + '](https://community.fandom.com/wiki/Special:Editcount/' + username.toTitle(true) + ')',inline:true});
+						if ( msg.showEmbed() ) embed.spliceFields(1, 0, {name:lang.get('user.info.globaleditcount'),value:'[' + globaledits + '](https://community.fandom.com/wiki/Special:Editcount/' + username.toTitle(true) + ')',inline:true});
 						else {
 							let splittext = text.split('\n');
-							splittext.splice(5, 0, lang.user.info.globaleditcount + ' ' + globaledits);
+							splittext.splice(5, 0, lang.get('user.info.globaleditcount') + ' ' + globaledits);
 							text = splittext.join('\n');
 						}
 					}
@@ -66,25 +66,25 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler) {
 			var gblock = $('.mw-blocklist');
 			if ( gblock.length ) {
 				var reason = gblock.find('.TablePager_col_reason').text().replace( /\)$/, '' ).split(', ');
-				var timestamp = new Date(gblock.find('.TablePager_col_timestamp').text().replace( /(\d{2}:\d{2}), (\d{1,2}) \((\w+)\) (\d{4})/, '$3 $2, $4 $1 UTC' )).toLocaleString(lang.dateformat, timeoptions);
+				var timestamp = new Date(gblock.find('.TablePager_col_timestamp').text().replace( /(\d{2}:\d{2}), (\d{1,2}) \((\w+)\) (\d{4})/, '$3 $2, $4 $1 UTC' )).toLocaleString(lang.get('dateformat'), timeoptions);
 				var expiry = gblock.find('.TablePager_col_expiry').text();
-				if ( expiry.startsWith( '(infiniteblock)' ) ) expiry = lang.user.block.until_infinity;
-				else expiry = new Date(expiry.replace( /(\d{2}:\d{2}), (\d{1,2}) \((\w+)\) (\d{4})/, '$3 $2, $4 $1 UTC' )).toLocaleString(lang.dateformat, timeoptions);
+				if ( expiry.startsWith( '(infiniteblock)' ) ) expiry = lang.get('user.block.until_infinity');
+				else expiry = new Date(expiry.replace( /(\d{2}:\d{2}), (\d{1,2}) \((\w+)\) (\d{4})/, '$3 $2, $4 $1 UTC' )).toLocaleString(lang.get('dateformat'), timeoptions);
 				if ( msg.showEmbed() ) {
-					var gblocktitle = lang.user.gblock.header.replaceSave( '%s', username ).escapeFormatting();
-					var globalblock = embed.fields.find( field => field.inline === false && field.name === lang.user.block.header.replaceSave( '%s', username ).escapeFormatting() && field.value.replace( /\[([^\]]*)\]\([^\)]*\)/g, '$1' ) === lang.user.block[( reason.length > 4 ? 'text' : 'noreason' )].replaceSave( '%1$s', timestamp ).replaceSave( '%2$s', expiry ).replaceSave( '%3$s', reason[1].escapeFormatting() ).replaceSave( '%4$s', reason.slice(4).join(', ').escapeFormatting() ) );
+					var gblocktitle = lang.get('user.gblock.header').replaceSave( '%s', username ).escapeFormatting();
+					var globalblock = embed.fields.find( field => field.inline === false && field.name === lang.get('user.block.header').replaceSave( '%s', username ).escapeFormatting() && field.value.replace( /\[([^\]]*)\]\([^\)]*\)/g, '$1' ) === lang.get('user.block.' + ( reason.length > 4 ? 'text' : 'noreason' )).replaceSave( '%1$s', timestamp ).replaceSave( '%2$s', expiry ).replaceSave( '%3$s', reason[1].escapeFormatting() ).replaceSave( '%4$s', reason.slice(4).join(', ').escapeFormatting() ) );
 					if ( globalblock ) globalblock.name = gblocktitle;
 					else {
 						var block_wiki = reason[3].replace( /Special:BlockList$/, '' );
-						var gblocktext = lang.user.gblock[( reason.length > 4 ? 'text' : 'noreason' )].replaceSave( '%1$s', timestamp ).replaceSave( '%2$s', expiry ).replaceSave( '%3$s', '[' + reason[1] + '](' + block_wiki + 'User:' + reason[1].toTitle(true) + ')' ).replaceSave( '%4$s', '[' + reason[2] + '](' + block_wiki + 'Special:Contribs/' + username.toTitle(true) + ')' ).replaceSave( '%5$s', reason.slice(4).join(', ').escapeFormatting() );
+						var gblocktext = lang.get('user.gblock.' + ( reason.length > 4 ? 'text' : 'noreason' )).replaceSave( '%1$s', timestamp ).replaceSave( '%2$s', expiry ).replaceSave( '%3$s', '[' + reason[1] + '](' + block_wiki + 'User:' + reason[1].toTitle(true) + ')' ).replaceSave( '%4$s', '[' + reason[2] + '](' + block_wiki + 'Special:Contribs/' + username.toTitle(true) + ')' ).replaceSave( '%5$s', reason.slice(4).join(', ').escapeFormatting() );
 						embed.addField( gblocktitle, gblocktext );
 					}
 				}
 				else {
 					let splittext = text.split('\n\n');
-					var globalblock = splittext.indexOf('**' + lang.user.block.header.replaceSave( '%s', username ).escapeFormatting() + '**\n' + lang.user.block[( reason.length > 4 ? 'text' : 'noreason' )].replaceSave( '%1$s', timestamp ).replaceSave( '%2$s', expiry ).replaceSave( '%3$s', reason[1].escapeFormatting() ).replaceSave( '%4$s', reason.slice(4).join(', ').escapeFormatting() ));
-					if ( globalblock !== -1 ) splittext[globalblock] = '**' + lang.user.gblock.header.replaceSave( '%s', username ).escapeFormatting() + '**\n' + lang.user.block[( reason.length > 4 ? 'text' : 'noreason' )].replaceSave( '%1$s', timestamp ).replaceSave( '%2$s', expiry ).replaceSave( '%3$s', reason[1].escapeFormatting() ).replaceSave( '%4$s', reason.slice(4).join(', ').escapeFormatting() );
-					else splittext.push('**' + lang.user.gblock.header.replaceSave( '%s', username ).escapeFormatting() + '**\n' + lang.user.gblock[( reason.length > 4 ? 'text' : 'noreason' )].replaceSave( '%1$s', timestamp ).replaceSave( '%2$s', expiry ).replaceSave( '%3$s', reason[1].escapeFormatting() ).replaceSave( '%4$s', reason[2] ).replaceSave( '%5$s', reason.slice(4).join(', ').escapeFormatting() ));
+					var globalblock = splittext.indexOf('**' + lang.get('user.block.header').replaceSave( '%s', username ).escapeFormatting() + '**\n' + lang.get('user.block.' + ( reason.length > 4 ? 'text' : 'noreason' )).replaceSave( '%1$s', timestamp ).replaceSave( '%2$s', expiry ).replaceSave( '%3$s', reason[1].escapeFormatting() ).replaceSave( '%4$s', reason.slice(4).join(', ').escapeFormatting() ));
+					if ( globalblock !== -1 ) splittext[globalblock] = '**' + lang.get('user.gblock.header').replaceSave( '%s', username ).escapeFormatting() + '**\n' + lang.get('user.block.' + ( reason.length > 4 ? 'text' : 'noreason' )).replaceSave( '%1$s', timestamp ).replaceSave( '%2$s', expiry ).replaceSave( '%3$s', reason[1].escapeFormatting() ).replaceSave( '%4$s', reason.slice(4).join(', ').escapeFormatting() );
+					else splittext.push('**' + lang.get('user.gblock.header').replaceSave( '%s', username ).escapeFormatting() + '**\n' + lang.get('user.gblock.' + ( reason.length > 4 ? 'text' : 'noreason' )).replaceSave( '%1$s', timestamp ).replaceSave( '%2$s', expiry ).replaceSave( '%3$s', reason[1].escapeFormatting() ).replaceSave( '%4$s', reason[2] ).replaceSave( '%5$s', reason.slice(4).join(', ').escapeFormatting() ));
 					text = splittext.join('\n\n');
 				}
 			}
@@ -102,19 +102,19 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler) {
 					let $ = cheerio.load(gbody);
 					var wikisedited = $('.curseprofile .rightcolumn .section.stats dd').eq(0).text().replace( /[,\.]/g, '' );
 					if ( wikisedited ) {
-						if ( msg.showEmbed() ) embed.spliceFields(1, 0, {name:lang.user.info.wikisedited,value:wikisedited,inline:true});
+						if ( msg.showEmbed() ) embed.spliceFields(1, 0, {name:lang.get('user.info.wikisedited'),value:wikisedited,inline:true});
 						else {
 							let splittext = text.split('\n');
-							splittext.splice(5, 0, lang.user.info.wikisedited + ' ' + wikisedited);
+							splittext.splice(5, 0, lang.get('user.info.wikisedited') + ' ' + wikisedited);
 							text = splittext.join('\n');
 						}
 					}
 					var globaledits = $('.curseprofile .rightcolumn .section.stats dd').eq(2).text().replace( /[,\.]/g, '' );
 					if ( globaledits ) {
-						if ( msg.showEmbed() ) embed.spliceFields(1, 0, {name:lang.user.info.globaleditcount,value:'[' + globaledits + '](https://help.gamepedia.com/Gamepedia_Help_Wiki:Global_user_tracker#' + wiki.replace( /^https:\/\/([a-z\d-]{1,50})\.gamepedia\.com\/$/, '$1/' ) + username.toTitle(true) + ')',inline:true});
+						if ( msg.showEmbed() ) embed.spliceFields(1, 0, {name:lang.get('user.info.globaleditcount'),value:'[' + globaledits + '](https://help.gamepedia.com/Gamepedia_Help_Wiki:Global_user_tracker#' + wiki.replace( /^https:\/\/([a-z\d-]{1,50})\.gamepedia\.com\/$/, '$1/' ) + username.toTitle(true) + ')',inline:true});
 						else {
 							let splittext = text.split('\n');
-							splittext.splice(5, 0, lang.user.info.globaleditcount + ' ' + globaledits);
+							splittext.splice(5, 0, lang.get('user.info.globaleditcount') + ' ' + globaledits);
 							text = splittext.join('\n');
 						}
 					}

+ 1 - 1
functions/helpserver.js

@@ -2,7 +2,7 @@ const help_setup = require('./helpsetup.js');
 
 function help_server(lang, msg) {
 	if ( msg.isAdmin() && msg.defaultSettings ) help_setup(lang, msg);
-	msg.sendChannel( lang.helpserver + '\n' + process.env.invite );
+	msg.sendChannel( lang.get('helpserver') + '\n' + process.env.invite );
 }
 
 module.exports = help_server;

+ 1 - 1
functions/helpsetup.js

@@ -1,6 +1,6 @@
 function help_setup(lang, msg) {
 	msg.defaultSettings = false;
-	msg.replyMsg( lang.settings.missing.replaceSave( '%1$s', '`' + process.env.prefix + ' settings lang`' ).replaceSave( '%2$s', '`' + process.env.prefix + ' settings wiki`' ) );
+	msg.replyMsg( lang.get('settings.missing').replaceSave( '%1$s', '`' + process.env.prefix + 'settings lang`' ).replaceSave( '%2$s', '`' + process.env.prefix + 'settings wiki`' ) );
 }
 
 module.exports = help_setup;

+ 2 - 2
functions/special_page.js

@@ -30,7 +30,7 @@ const queryfunctions = {
 		return '[' + result.title.replace( / /g, '_' ).escapeFormatting() + '](' + wiki.toLink(result.title, 'redirect=no', '', query.general, true) + ')' + ( result.databaseResult && result.databaseResult.b_title && result.databaseResult.c_title ? ' → ' + result.databaseResult.b_title.escapeFormatting() + ' → ' + result.databaseResult.c_title.escapeFormatting() : '' );
 	} ).join('\n'),
 	timestamp: (query, wiki) => query.querypage.results.map( result => {
-		return new Date(result.timestamp).toLocaleString(lang.dateformat, timeoptions).escapeFormatting() + ': [' + result.title.escapeFormatting() + '](' + wiki.toLink(result.title, '', '', query.general, true) + ')';
+		return new Date(result.timestamp).toLocaleString(lang.get('dateformat'), timeoptions).escapeFormatting() + ': [' + result.title.escapeFormatting() + '](' + wiki.toLink(result.title, '', '', query.general, true) + ')';
 	} ).join('\n'),
 	media: (query) => query.querypage.results.map( result => {
 		var ms = result.title.split(';');
@@ -116,7 +116,7 @@ function special_page(lang, msg, title, specialpage, embed, wiki, reaction, spoi
 			}
 			if ( msg.channel.type === 'text' && msg.guild.id in patreons && specialpage in querypages ) {
 				var text = Util.splitMessage( querypages[specialpage][1](body.query, wiki), {maxLength:1000} )[0];
-				embed.addField( lang.search.special, ( text || lang.search.empty ) );
+				embed.addField( lang.get('search.special'), ( text || lang.get('search.empty') ) );
 			}
 		}
 	}, error => {

+ 14 - 25
i18n/allLangs.json

@@ -1,6 +1,17 @@
 {
-	"allLangs": [
-		{
+	"allLangs": {
+		"names": {
+			"en": ["English", "English"],
+			"de": ["German", "Deutsch"],
+			"fr": ["French", "Français"],
+			"nl": ["Dutch", "Nederlands"],
+			"pl": ["Polish", "Polski"],
+			"pt": ["Portuguese", "Português"],
+			"ru": ["Russian", "Русский"],
+			"tr": ["Turkish", "Türkçe"],
+			"zh": ["Chinese", "中文"]
+		},
+		"map": {
 			"en": "en",
 			"eng": "en",
 			"english": "en",
@@ -28,28 +39,6 @@
 			"zh": "zh",
 			"chinese": "zh",
 			"中文": "zh"
-		},
-		{
-			"en": "English",
-			"de": "German",
-			"fr": "French",
-			"nl": "Dutch",
-			"pl": "Polish",
-			"pt": "Portuguese",
-			"ru": "Russian",
-			"tr": "Turkish",
-			"zh": "Chinese"
-		},
-		{
-			"en": "English",
-			"de": "Deutsch",
-			"fr": "Français",
-			"nl": "Nederlands",
-			"pl": "Polski",
-			"pt": "Português",
-			"ru": "Русский",
-			"tr": "Türkçe",
-			"zh": "中文"
 		}
-	]
+	}
 }

+ 42 - 40
i18n/de.json

@@ -48,7 +48,7 @@
 		"prefix": "das Präfix für diesen Server ist:",
 		"prefixinvalid": "das angegebende Präfix wird nicht unterstützt!",
 		"prefixchanged": "du hast das Präfix für diesen Server geändert zu:",
-		"prefixhelp": "Nutze `%s <Präfix>` um das Präfix zu ändern.\nDas Präfix darf keine Leerzeichen oder Erwähnungen enthalten!",
+		"prefixhelp": "Nutze `%s <Präfix>` um das Präfix zu ändern.\nNutze `_` am Ende um ein Leerzeichen am Ende des Präfixes anzugeben.\nDas Präfix darf keine Erwähnungen enthalten!",
 		"inline enabled": {
 			"inline": "Inline-Befehle sind für diesen Server aktiviert.",
 			"channel inline": "Inline-Befehle sind für diesen Kanal aktiviert.",
@@ -181,43 +181,44 @@
 			"male": "Männlich",
 			"female": "Weiblich"
 		},
-		"groups": [
-			["global_bot", "Globaler Bot"],
-			["hydra_staff", "Gamepedia-Mitarbeiter"],
-			["wiki_manager", "Wiki-Manager"],
-			["content_team_member", "Content-Team-Mitglied"],
-			["grasp", "GRASP"],
-			["bot-global", "Globaler Bot"],
-			["staff", "Fandom-Mitarbeiter"],
-			["wiki-manager", "Wiki-Manager"],
-			["helper", "Fandom-Helfer"],
-			["content-team-member", "Content-Team-Mitglied"],
-			["vstf", "VSTF"],
-			["content-volunteer", "Content-Volunteer"],
-			["global-discussions-moderator", "Globaler Diskussions-Moderator"],
-			["vanguard", "Portabilitäts-Pionier"],
-			["voldev", "Volunteer Developer"],
-			["council", "Community Council"],
-			["bot", "Bot"],
-			["bureaucrat", "Bürokrat"],
-			["sysop", "Administrator"],
-			["interface-admin", "Oberflächen-Administrator"],
-			["content-moderator", "Inhalts-Moderator"],
-			["threadmoderator", "Diskussions-Moderator"],
-			["chatmoderator", "Chat-Moderator"],
-			["directors", "Direktor"],
-			["Patrol", "Inspektor"],
-			["editor", "Autor"],
-			["moderator", "Moderator"],
-			["Elite_users", "Elite-Benutzer"],
-			["patrollers", "Kontrolleur"],
-			["rollback", "zurücksetzen"],
-			["autoreview", "autoreview"],
-			["autopatrol", "autopatrol"],
-			["authenticated", "offiziell"],
-			["autoconfirmed", "Automatisch bestätigter Benutzer"],
-			["user", "Benutzer"]
-		],
+		"groups": {
+			"global_bot": "Globaler Bot",
+			"hydra_staff": "Gamepedia-Mitarbeiter",
+			"wiki_manager": "Wiki-Manager",
+			"content_team_member": "Content-Team-Mitglied",
+			"grasp": "GRASP",
+			"bot-global": "Globaler Bot",
+			"staff": "Fandom-Mitarbeiter",
+			"wiki-manager": "Wiki-Manager",
+			"helper": "Fandom-Helfer",
+			"content-team-member": "Content-Team-Mitglied",
+			"soap": "SOAP",
+			"vstf": "VSTF",
+			"content-volunteer": "Content-Volunteer",
+			"global-discussions-moderator": "Globaler Diskussions-Moderator",
+			"vanguard": "Portabilitäts-Pionier",
+			"voldev": "Volunteer Developer",
+			"council": "Community Council",
+			"bot": "Bot",
+			"bureaucrat": "Bürokrat",
+			"sysop": "Administrator",
+			"interface-admin": "Oberflächen-Administrator",
+			"content-moderator": "Inhalts-Moderator",
+			"threadmoderator": "Diskussions-Moderator",
+			"chatmoderator": "Chat-Moderator",
+			"directors": "Direktor",
+			"Patrol": "Inspektor",
+			"editor": "Autor",
+			"moderator": "Moderator",
+			"Elite_users": "Elite-Benutzer",
+			"patrollers": "Kontrolleur",
+			"rollback": "zurücksetzen",
+			"autoreview": "autoreview",
+			"autopatrol": "autopatrol",
+			"authenticated": "offiziell",
+			"autoconfirmed": "Automatisch bestätigter Benutzer",
+			"user": "Benutzer"
+		},
 		"info": {
 			"gender": "Geschlecht:",
 			"registration": "Registriert:",
@@ -364,8 +365,9 @@
 			{ "cmd": "settings wiki <Wiki>", "desc": "Ich ändere das Standard-Wiki für diesen Server.", "hide": true, "admin": true },
 			{ "cmd": "settings channel", "desc": "Ich ändere die Überschreibungen für den aktuellen Kanal.", "hide": true, "admin": true },
 			{ "cmd": "verify <Wiki-Benutzername>", "desc": "Nutze diesen Befehl um deinen Discord-Account mit deinem Wiki-Account zu verifizieren und Rollen passend zu deinem Wiki-Account zu erhalten.", "hide": true },
-			{ "cmd": "verification", "desc": "Ich ändere die Wiki-Verifizierungen, die von dem `@prefix verify`-Befehl genutzt werden.", "admin": true, "pause": true },
-			{ "cmd": "help verification", "desc": "Ich erkläre genauer wie der Verifizierungs-Befehl funktioniert.", "unsearchable": true, "admin": true },
+			{ "cmd": "verification", "desc": "Ich ändere die Wiki-Verifizierungen, die von dem `@prefixverify`-Befehl genutzt werden.", "admin": true, "pause": true },
+			{ "cmd": "hilfe verification", "desc": "Ich erkläre genauer wie der Verifizierungs-Befehl funktioniert.", "admin": true },
+			{ "cmd": "help verification", "desc": "Ich erkläre genauer wie der Verifizierungs-Befehl funktioniert.", "hide": true, "admin": true },
 			{ "cmd": "verification add <Rolle>", "desc": "Ich füge eine neue Wiki-Verifizierung hinzu. Akzeptiert eine durch `|` getrennte Liste.", "hide": true, "admin": true },
 			{ "cmd": "verification <ID> channel <neuer Kanal>", "desc": "Ich ändere den Kanal für die Wiki-Verifizierung. Akzeptiert eine durch `|` getrennte Liste.", "hide": true, "admin": true },
 			{ "cmd": "verification <ID> role <neue Rolle>", "desc": "Ich ändere die Rolle für die Wiki-Verifizierung. Akzeptiert eine durch `|` getrennte Liste.", "hide": true, "admin": true },

+ 40 - 39
i18n/en.json

@@ -43,7 +43,7 @@
 		"prefix": "the prefix for this server is:",
 		"prefixinvalid": "the specified prefix is not supported!",
 		"prefixchanged": "you changed the prefix for this server to:",
-		"prefixhelp": "Use `%s <prefix>` to change the prefix.\nThe prefix may not include spaces or mentions!",
+		"prefixhelp": "Use `%s <prefix>` to change the prefix.\nUse `_` at the end to indicate a space at end of the prefix.\nThe prefix may not include mentions!",
 		"inline enabled": {
 			"inline": "inline commands are currently enabled for this server.",
 			"channel inline": "inline commands are currently enabled for this channel.",
@@ -176,43 +176,44 @@
 			"male": "Male",
 			"female": "Female"
 		},
-		"groups": [
-			["global_bot", "Global bot"],
-			["hydra_staff", "Gamepedia staff"],
-			["wiki_manager", "Wiki manager"],
-			["content_team_member", "Content Team Member"],
-			["grasp", "GRASP"],
-			["bot-global", "Global bot"],
-			["staff", "Fandom staff"],
-			["wiki-manager", "Wiki manager"],
-			["helper", "Fandom helper"],
-			["content-team-member", "Content Team Member"],
-			["vstf", "VSTF"],
-			["content-volunteer", "Content volunteer"],
-			["global-discussions-moderator", "Global discussions moderator"],
-			["vanguard", "Vanguard"],
-			["voldev", "Volunteer Developer"],
-			["council", "Community Council"],
-			["bot", "Bot"],
-			["bureaucrat", "Bureaucrat"],
-			["sysop", "Administrator"],
-			["interface-admin", "Interface administrator"],
-			["content-moderator", "Content moderator"],
-			["threadmoderator", "Discussions moderator"],
-			["chatmoderator", "Chat moderator"],
-			["directors", "Director"],
-			["Patrol", "Inspector"],
-			["editor", "Editor"],
-			["moderator", "Moderator"],
-			["Elite_users", "Elite user"],
-			["patrollers", "Patroller"],
-			["rollback", "rollback"],
-			["autoreview", "autoreview"],
-			["autopatrol", "autopatrol"],
-			["authenticated", "authenticated"],
-			["autoconfirmed", "Autoconfirmed user"],
-			["user", "User"]
-		],
+		"groups": {
+			"global_bot": "Global bot",
+			"hydra_staff": "Gamepedia staff",
+			"wiki_manager": "Wiki manager",
+			"content_team_member": "Content Team Member",
+			"grasp": "GRASP",
+			"bot-global": "Global bot",
+			"staff": "Fandom staff",
+			"wiki-manager": "Wiki manager",
+			"helper": "Fandom helper",
+			"content-team-member": "Content Team Member",
+			"soap": "SOAP",
+			"vstf": "VSTF",
+			"content-volunteer": "Content volunteer",
+			"global-discussions-moderator": "Global discussions moderator",
+			"vanguard": "Vanguard",
+			"voldev": "Volunteer Developer",
+			"council": "Community Council",
+			"bot": "Bot",
+			"bureaucrat": "Bureaucrat",
+			"sysop": "Administrator",
+			"interface-admin": "Interface administrator",
+			"content-moderator": "Content moderator",
+			"threadmoderator": "Discussions moderator",
+			"chatmoderator": "Chat moderator",
+			"directors": "Director",
+			"Patrol": "Inspector",
+			"editor": "Editor",
+			"moderator": "Moderator",
+			"Elite_users": "Elite user",
+			"patrollers": "Patroller",
+			"rollback": "rollback",
+			"autoreview": "autoreview",
+			"autopatrol": "autopatrol",
+			"authenticated": "authenticated",
+			"autoconfirmed": "Autoconfirmed user",
+			"user": "User"
+		},
 		"info": {
 			"gender": "Gender:",
 			"registration": "Registration date:",
@@ -347,7 +348,7 @@
 			{ "cmd": "settings wiki <wiki>", "desc": "I will change the default wiki for this server.", "hide": true, "admin": true },
 			{ "cmd": "settings channel", "desc": "I will change the overwrites for the current channel.", "hide": true, "admin": true },
 			{ "cmd": "verify <wiki username>", "desc": "Use this command to verify your Discord account with your wiki account and get roles matching your wiki account.", "hide": true },
-			{ "cmd": "verification", "desc": "I will change the wiki verifications used by the `@prefix verify` command.", "admin": true, "pause": true },
+			{ "cmd": "verification", "desc": "I will change the wiki verifications used by the `@prefixverify` command.", "admin": true, "pause": true },
 			{ "cmd": "help verification", "desc": "I will explain in more detail how the verification command works.", "unsearchable": true, "admin": true },
 			{ "cmd": "verification add <role>", "desc": "I will add a new wiki verification. Accepts a `|` separated list.", "hide": true, "admin": true },
 			{ "cmd": "verification <id> channel <new channel>", "desc": "I will change the channel for the wiki verification. Accepts a `|` separated list.", "hide": true, "admin": true },

+ 43 - 137
i18n/fr.json

@@ -25,7 +25,6 @@
 		"channel current": "voici les paramètres actuels pour ce salon :",
 		"currentlang": "Langue :",
 		"currentprefix": "Préfixe :",
-		"currentinline": "Inline commands:",
 		"currentwiki": "Wiki par défaut :",
 		"currentchannel": "Ecrasement de salon :",
 		"nochannels": "*Aucun écrasement de salon pour le moment*",
@@ -44,22 +43,7 @@
 		"wikihelp": "Utilisez `%s <lien>` pour changer le wiki par défaut.\nLien du wiki : `https://<wiki>.gamepedia.com/` ou `https://<wiki>.fandom.com/`",
 		"prefix": "le préfixe pour ce serveur est :",
 		"prefixinvalid": "le préfixe spécifié n'est pas supporté !",
-		"prefixchanged": "vous avez changé le préfixe pour ce serveur en :",
-		"prefixhelp": "Utilisez `%s <préfixe>` pour changer le préfixe.\nLe préfixe ne doit pas inclure d'espace ou de mention !",
-		"inline enabled": {
-			"inline": "inline commands are currently enabled for this server.",
-			"channel inline": "inline commands are currently enabled for this channel.",
-			"inlinechanged": "you enabled inline commands for this server.",
-			"channel inlinechanged": "you enabled inline commands for this channel.",
-			"help": "Use `%1$s` to disable inline commands like `[[%2$s]]` and `{{%2$s}}`."
-		},
-		"inline disabled": {
-			"inline": "inline commands are currently disabled for this server.",
-			"channel inline": "inline commands are currently disabled for this channel.",
-			"inlinechanged": "you disabled inline commands for this server.",
-			"channel inlinechanged": "you disabled inline commands for this channel.",
-			"help": "Use `%1$s` to enable inline commands like `[[%2$s]]` and `{{%2$s}}`."
-		}
+		"prefixchanged": "vous avez changé le préfixe pour ce serveur en :"
 	},
 	"pause": {
 		"on": "je sais maintenant en pause sur ce serveur et je ne répondrai pas à la majorité des commandes !",
@@ -76,81 +60,6 @@
 		"join": "%1$s a rejoint le salon vocal \"%2$s\".",
 		"left": "%1$s a quitté le salon vocal \"%2$s\"."
 	},
-	"verification": {
-		"save_failed": "sadly the verification couldn't be saved, please try again later.",
-		"added": "the verification has been added:",
-		"updated": "the verification has been updated:",
-		"deleted": "the verification has been deleted.",
-		"max_entries": "you already reached the maximal amount of verifications.",
-		"no_role": "please provide a role for the new verification.",
-		"current": "these are the current verifications for this server:",
-		"current_selected": "this is the verification `%s` for this server:",
-		"missing": "there are no verifications for this server yet.",
-		"add_more": "Add more verifications:",
-		"delete_current": "Delete this verification:",
-		"channel": "Channel:",
-		"role": "Role:",
-		"editcount": "Edit count:",
-		"usergroup": "User group:",
-		"or": "or",
-		"and": "and",
-		"accountage": "Account age:",
-		"indays": "(in days)",
-		"rename": "Change nickname:",
-		"enabled": "enabled",
-		"disabled": "disabled",
-		"toggle": "(toggle)",
-		"rename_no_permission": "**%s is missing the `Manage Nicknames` permission to force wiki usernames!**",
-		"role_too_high": "**The role %1$s is too high for %2$s to assign!**",
-		"channel_max": "too many channels provided.",
-		"channel_missing": "the provided channel does not exist.",
-		"role_max": "too many roles provided.",
-		"role_missing": "the provided role does not exist.",
-		"role_managed": "the provided role can't be assigned.",
-		"value_too_high": "the provided value is too high.",
-		"usergroup_max": "too many user groups provided.",
-		"usergroup_too_long": "the provided user group is too long.",
-		"new_channel": "<new channel>",
-		"new_role": "<new role>",
-		"new_editcount": "<new edit count>",
-		"new_usergroup": "<new user group>",
-		"new_accountage": "<new account age>"
-	},
-	"verify": {
-		"error": "The verification failed due to an error.",
-		"error_reply": "the verification failed due to an error, please try again.",
-		"missing": "there are no verifications set up for this channel.",
-		"footer": "Wiki Account Verification",
-		"failed_gblock": "**Check for global block failed!**",
-		"failed_roles": "**Adding roles failed!**",
-		"failed_rename": "**Changing the nickname failed!**",
-		"audit_reason": "Verified as \"%s\"",
-		"user_missing": "The wiki user \"%s\" doesn't exist.",
-		"user_missing_reply": "your linked wiki user \"%s\" doesn't exist.",
-		"user_blocked": "**The wiki user %s is blocked!**",
-		"user_blocked_reply": "your linked wiki user **\"%s\" is blocked!**",
-		"user_gblocked": "**The wiki user %s is globally blocked!**",
-		"user_gblocked_reply": "your linked wiki user **\"%s\" is globally blocked!**",
-		"user_disabled": "**The wiki user %s is disabled!**",
-		"user_disabled_reply": "your linked wiki user **\"%s\" is disabled!**",
-		"user_failed": "Discord user %1$s doesn't match the wiki user %2$s.",
-		"user_failed_reply": "your Discord tag doesn't match the wiki user \"%s\".",
-		"user_matches": "Discord user %1$s matches the wiki user %2$s, but doesn't meet the requirements for any roles.",
-		"user_matches_reply": "your Discord tag matches the wiki user \"%s\", but you don't meet the requirements for any roles.",
-		"user_verified": "Discord user %1$s has been successfully verified as wiki user %2$s.",
-		"user_verified_reply": "you have been successfully verified as wiki user \"%s\".",
-		"user_renamed": "Their Discord nickname has been changed to their wiki username.",
-		"discord": "Discord user:",
-		"wiki": "Wiki user:",
-		"empty": "*empty*",
-		"notice": "Notice:",
-		"qualified": "Qualified for:",
-		"qualified_error": "Qualified for, but could not add:",
-		"help_guide": "Follow [this guide](%s) to add your Discord tag to your wiki profile.",
-		"help_gamepedia": "https://help.gamepedia.com/Gamepedia_Help_Wiki:Discord_verification",
-		"help_fandom": "https://community.fandom.com/wiki/Special:VerifyUser",
-		"help_subpage": "Please add your Discord tag (%s) to your Discord subpage on the wiki:"
-	},
 	"overview": {
 		"inaccurate": "Les statistiques peuvent être inexactes",
 		"name": "Nom complet :",
@@ -178,43 +87,43 @@
 			"male": "Homme",
 			"female": "Femme"
 		},
-		"groups": [
-			["global_bot", "Robot de Gamepedia"],
-			["hydra_staff", "Staff de Gamepedia"],
-			["wiki_manager", "Gestionnaire du wiki"],
-			["content_team_member", "Membre de l'équipe Contenu"],
-			["grasp", "GRASP"],
-			["bot-global", "Robot de Fandom"],
-			["staff", "Staff de Fandom"],
-			["wiki-manager", "Gestionnaire du wiki"],
-			["helper", "Assistant de Fandom"],
-			["content-team-member", "Membre de l'équipe Contenu"],
-			["vstf", "VSTF"],
-			["content-volunteer", "Créateur de contenu bénévole"],
-			["global-discussions-moderator", "Modérateur global de discussions"],
-			["vanguard", "Vanguard"],
-			["voldev", "Développeurs bénévoles"],
-			["council", "Community Council"],
-			["bot", "Robot"],
-			["bureaucrat", "Bureaucrate"],
-			["sysop", "Administrateur"],
-			["interface-admin", "Administrateur d’interface"],
-			["content-moderator", "Modérateur de contenu"],
-			["threadmoderator", "Modérateur de discussions"],
-			["chatmoderator", "Modérateur du tchat"],
-			["directors", "Directeur"],
-			["Patrol", "Inspecteur"],
-			["editor", "Éditeur"],
-			["moderator", "Modérateur"],
-			["Elite_users", "Utilisateur élite"],
-			["patrollers", "Patrouilleur"],
-			["rollback", "rollback"],
-			["autoreview", "autoreview"],
-			["autopatrol", "autopatrol"],
-			["authenticated", "authenticated"],
-			["autoconfirmed", "Utilisateur autoconfirmé"],
-			["user", "Utilisateur"]
-		],
+		"groups": {
+			"global_bot": "Robot de Gamepedia",
+			"hydra_staff": "Staff de Gamepedia",
+			"wiki_manager": "Gestionnaire du wiki",
+			"content_team_member": "Membre de l'équipe Contenu",
+			"grasp": "GRASP",
+			"bot-global": "Robot de Fandom",
+			"staff": "Staff de Fandom",
+			"wiki-manager": "Gestionnaire du wiki",
+			"helper": "Assistant de Fandom",
+			"content-team-member": "Membre de l'équipe Contenu",
+			"vstf": "VSTF",
+			"content-volunteer": "Créateur de contenu bénévole",
+			"global-discussions-moderator": "Modérateur global de discussions",
+			"vanguard": "Vanguard",
+			"voldev": "Développeurs bénévoles",
+			"council": "Community Council",
+			"bot": "Robot",
+			"bureaucrat": "Bureaucrate",
+			"sysop": "Administrateur",
+			"interface-admin": "Administrateur d’interface",
+			"content-moderator": "Modérateur de contenu",
+			"threadmoderator": "Modérateur de discussions",
+			"chatmoderator": "Modérateur du tchat",
+			"directors": "Directeur",
+			"Patrol": "Inspecteur",
+			"editor": "Éditeur",
+			"moderator": "Modérateur",
+			"Elite_users": "Utilisateur élite",
+			"patrollers": "Patrouilleur",
+			"rollback": "rollback",
+			"autoreview": "autoreview",
+			"autopatrol": "autopatrol",
+			"authenticated": "authenticated",
+			"autoconfirmed": "Utilisateur autoconfirmé",
+			"user": "Utilisateur"
+		},
 		"info": {
 			"gender": "Genre :",
 			"registration": "Date d'inscription :",
@@ -280,11 +189,7 @@
 			}
 		},
 		"special": "Contenu de cette page spéciale :",
-		"empty": "*Cette page spéciale est vide*",
-		"results": {
-			"default": "%s total results",
-			"1": "%s total result"
-		}
+		"empty": "*Cette page spéciale est vide*"
 	},
 	"discussion": {
 		"post": "post",
@@ -300,7 +205,7 @@
 		"bot": "Utilisez ce lien pour m'inviter sur un autre serveur :"
 	},
 	"test": {
-		"random": 30,
+		"random": 50,
 		"pause": "je suis présentement en pause sur ce serveur.",
 		"text": [
 			"Je suis toujours en vie !",
@@ -377,8 +282,9 @@
 			{ "cmd": "settings wiki <wiki>", "desc": "Je vais modifier le Wiki par défaut de ce serveur.", "hide": true, "admin": true },
 			{ "cmd": "settings channel", "desc": "Je changerais les écrasements pour le salon actuel.", "hide": true, "admin": true },
 			{ "cmd": "verify <wiki username>", "desc": "Use this command to verify your Discord account with your wiki account and get roles matching your wiki account.", "hide": true },
-			{ "cmd": "verification", "desc": "I will change the wiki verifications used by the `@prefix verify` command.", "admin": true, "pause": true },
-			{ "cmd": "help verification", "desc": "I will explain in more detail how the verification command works.", "unsearchable": true, "admin": true },
+			{ "cmd": "verification", "desc": "I will change the wiki verifications used by the `@prefixverify` command.", "admin": true, "pause": true },
+			{ "cmd": "aide verification", "desc": "I will explain in more detail how the verification command works.", "admin": true },
+			{ "cmd": "help verification", "desc": "I will explain in more detail how the verification command works.", "hide": true, "admin": true },
 			{ "cmd": "verification add <role>", "desc": "I will add a new wiki verification. Accepts a `|` separated list.", "hide": true, "admin": true },
 			{ "cmd": "verification <id> channel <new channel>", "desc": "I will update the channel for the wiki verification. Accepts a `|` separated list.", "hide": true, "admin": true },
 			{ "cmd": "verification <id> role <new role>", "desc": "I will update the role for the wiki verification. Accepts a `|` separated list.", "hide": true, "admin": true },

+ 41 - 136
i18n/nl.json

@@ -27,7 +27,6 @@
 		"channel current": "dit zijn de huidige instellingen voor dit kanaal:",
 		"currentlang": "Taal:",
 		"currentprefix": "Voorvoegsel:",
-		"currentinline": "Inline commands:",
 		"currentwiki": "Standaard wiki:",
 		"currentchannel": "Kanaal overschrijvingen:",
 		"nochannels": "*Nog geen kanaal overschrijvingen*",
@@ -46,22 +45,7 @@
 		"wikihelp": "Gebruik `%s <link>` om de standaard wiki te wijzigen.\nLink naar de wiki: `https://<wiki>.gamepedia.com/` of `https://<wiki>.fandom.com/`",
 		"prefix": "het voorvoegsel voor deze server is:",
 		"prefixinvalid": "het opgegeven voorvoegsel wordt niet ondersteund!",
-		"prefixchanged": "je hebt het voorvoegsel voor deze server veranderd naar:",
-		"prefixhelp": "Gebruik `%s <voorvoegsel>` om het voorvoegsel te wijzigen.\nHet voorvoegsel mag geen spaties of @mentions bevatten!",
-		"inline enabled": {
-			"inline": "inline commands are currently enabled for this server.",
-			"channel inline": "inline commands are currently enabled for this channel.",
-			"inlinechanged": "you enabled inline commands for this server.",
-			"channel inlinechanged": "you enabled inline commands for this channel.",
-			"help": "Use `%1$s` to disable inline commands like `[[%2$s]]` and `{{%2$s}}`."
-		},
-		"inline disabled": {
-			"inline": "inline commands are currently disabled for this server.",
-			"channel inline": "inline commands are currently disabled for this channel.",
-			"inlinechanged": "you disabled inline commands for this server.",
-			"channel inlinechanged": "you disabled inline commands for this channel.",
-			"help": "Use `%1$s` to enable inline commands like `[[%2$s]]` and `{{%2$s}}`."
-		}
+		"prefixchanged": "je hebt het voorvoegsel voor deze server veranderd naar:"
 	},
 	"pause": {
 		"on": "Ik ben nu gepauzeerd op deze server en zal meeste opdrachten negeren!",
@@ -78,81 +62,6 @@
 		"join": "%1$s kwam het spraakkanaal \"%2$s\" binnen.",
 		"left": "%1$s verlaatte het spraakkanaal \"%2$s\"."
 	},
-	"verification": {
-		"save_failed": "sadly the verification couldn't be saved, please try again later.",
-		"added": "the verification has been added:",
-		"updated": "the verification has been updated:",
-		"deleted": "the verification has been deleted.",
-		"max_entries": "you already reached the maximal amount of verifications.",
-		"no_role": "please provide a role for the new verification.",
-		"current": "these are the current verifications for this server:",
-		"current_selected": "this is the verification `%s` for this server:",
-		"missing": "there are no verifications for this server yet.",
-		"add_more": "Add more verifications:",
-		"delete_current": "Delete this verification:",
-		"channel": "Channel:",
-		"role": "Role:",
-		"editcount": "Edit count:",
-		"usergroup": "User group:",
-		"or": "or",
-		"and": "and",
-		"accountage": "Account age:",
-		"indays": "(in days)",
-		"rename": "Change nickname:",
-		"enabled": "enabled",
-		"disabled": "disabled",
-		"toggle": "(toggle)",
-		"rename_no_permission": "**%s is missing the `Manage Nicknames` permission to force wiki usernames!**",
-		"role_too_high": "**The role %1$s is too high for %2$s to assign!**",
-		"channel_max": "too many channels provided.",
-		"channel_missing": "the provided channel does not exist.",
-		"role_max": "too many roles provided.",
-		"role_missing": "the provided role does not exist.",
-		"role_managed": "the provided role can't be assigned.",
-		"value_too_high": "the provided value is too high.",
-		"usergroup_max": "too many user groups provided.",
-		"usergroup_too_long": "the provided user group is too long.",
-		"new_channel": "<new channel>",
-		"new_role": "<new role>",
-		"new_editcount": "<new edit count>",
-		"new_usergroup": "<new user group>",
-		"new_accountage": "<new account age>"
-	},
-	"verify": {
-		"error": "The verification failed due to an error.",
-		"error_reply": "the verification failed due to an error, please try again.",
-		"missing": "there are no verifications set up for this channel.",
-		"footer": "Wiki Account Verification",
-		"failed_gblock": "**Check for global block failed!**",
-		"failed_roles": "**Adding roles failed!**",
-		"failed_rename": "**Changing the nickname failed!**",
-		"audit_reason": "Verified as \"%s\"",
-		"user_missing": "The wiki user \"%s\" doesn't exist.",
-		"user_missing_reply": "your linked wiki user \"%s\" doesn't exist.",
-		"user_blocked": "**The wiki user %s is blocked!**",
-		"user_blocked_reply": "your linked wiki user **\"%s\" is blocked!**",
-		"user_gblocked": "**The wiki user %s is globally blocked!**",
-		"user_gblocked_reply": "your linked wiki user **\"%s\" is globally blocked!**",
-		"user_disabled": "**The wiki user %s is disabled!**",
-		"user_disabled_reply": "your linked wiki user **\"%s\" is disabled!**",
-		"user_failed": "Discord user %1$s doesn't match the wiki user %2$s.",
-		"user_failed_reply": "your Discord tag doesn't match the wiki user \"%s\".",
-		"user_matches": "Discord user %1$s matches the wiki user %2$s, but doesn't meet the requirements for any roles.",
-		"user_matches_reply": "your Discord tag matches the wiki user \"%s\", but you don't meet the requirements for any roles.",
-		"user_verified": "Discord user %1$s has been successfully verified as wiki user %2$s.",
-		"user_verified_reply": "you have been successfully verified as wiki user \"%s\".",
-		"user_renamed": "Their Discord nickname has been changed to their wiki username.",
-		"discord": "Discord user:",
-		"wiki": "Wiki user:",
-		"empty": "*empty*",
-		"notice": "Notice:",
-		"qualified": "Qualified for:",
-		"qualified_error": "Qualified for, but could not add:",
-		"help_guide": "Follow [this guide](%s) to add your Discord tag to your wiki profile.",
-		"help_gamepedia": "https://help.gamepedia.com/Gamepedia_Help_Wiki:Discord_verification",
-		"help_fandom": "https://community.fandom.com/wiki/Special:VerifyUser",
-		"help_subpage": "Please add your Discord tag (%s) to your Discord subpage on the wiki:"
-	},
 	"overview": {
 		"inaccurate": "Statistieken zijn mogelijk inaccuraat",
 		"name": "Volledige naam:",
@@ -180,43 +89,43 @@
 			"male": "Man",
 			"female": "Vrouw"
 		},
-		"groups": [
-			["global_bot", "Gamepedia bot"],
-			["hydra_staff", "Gamepedia staff"],
-			["wiki_manager", "Wiki manager"],
-			["content_team_member", "Content Team Member"],
-			["grasp", "GRASP"],
-			["bot-global", "Fandom bot"],
-			["staff", "Fandom staff"],
-			["wiki-manager", "Wiki manager"],
-			["helper", "Fandom helper"],
-			["content-team-member", "Content Team Member"],
-			["vstf", "VSTF"],
-			["content-volunteer", "Content volunteer"],
-			["global-discussions-moderator", "Globaal discussiemoderator"],
-			["vanguard", "Vanguard"],
-			["voldev", "Vrijwillige ontwikkelaars"],
-			["council", "Communityraad"],
-			["bot", "Bot"],
-			["bureaucrat", "Bureaucraat"],
-			["sysop", "Beheerder"],
-			["interface-admin", "Interfacemoderator"],
-			["content-moderator", "Inhoudmoderator"],
-			["threadmoderator", "Discussiemoderator"],
-			["chatmoderator", "Chatmoderator"],
-			["directors", "Director"],
-			["Patrol", "Inspector"],
-			["editor", "Editor"],
-			["moderator", "Moderator"],
-			["Elite_users", "Elite user"],
-			["patrollers", "Patroller"],
-			["rollback", "rollback"],
-			["autoreview", "autoreview"],
-			["autopatrol", "autopatrol"],
-			["authenticated", "authenticated"],
-			["autoconfirmed", "Autobevestigde gebruiker"],
-			["user", "Gebruiker"]
-		],
+		"groups": {
+			"global_bot": "Gamepedia bot",
+			"hydra_staff": "Gamepedia staff",
+			"wiki_manager": "Wiki manager",
+			"content_team_member": "Content Team Member",
+			"grasp": "GRASP",
+			"bot-global": "Fandom bot",
+			"staff": "Fandom staff",
+			"wiki-manager": "Wiki manager",
+			"helper": "Fandom helper",
+			"content-team-member": "Content Team Member",
+			"vstf": "VSTF",
+			"content-volunteer": "Content volunteer",
+			"global-discussions-moderator": "Globaal discussiemoderator",
+			"vanguard": "Vanguard",
+			"voldev": "Vrijwillige ontwikkelaars",
+			"council": "Communityraad",
+			"bot": "Bot",
+			"bureaucrat": "Bureaucraat",
+			"sysop": "Beheerder",
+			"interface-admin": "Interfacemoderator",
+			"content-moderator": "Inhoudmoderator",
+			"threadmoderator": "Discussiemoderator",
+			"chatmoderator": "Chatmoderator",
+			"directors": "Director",
+			"Patrol": "Inspector",
+			"editor": "Editor",
+			"moderator": "Moderator",
+			"Elite_users": "Elite user",
+			"patrollers": "Patroller",
+			"rollback": "rollback",
+			"autoreview": "autoreview",
+			"autopatrol": "autopatrol",
+			"authenticated": "authenticated",
+			"autoconfirmed": "Autobevestigde gebruiker",
+			"user": "Gebruiker"
+		},
 		"info": {
 			"gender": "Geslacht:",
 			"registration": "Registratie datum:",
@@ -282,11 +191,7 @@
 			}
 		},
 		"special": "Inhoud van deze speciale pagina:",
-		"empty": "*Deze speciale pagina is leeg*",
-		"results": {
-			"default": "%s total results",
-			"1": "%s total result"
-		}
+		"empty": "*Deze speciale pagina is leeg*"
 	},
 	"discussion": {
 		"post": "bericht",
@@ -358,8 +263,8 @@
 			{ "cmd": "settings wiki <wiki>", "desc": "Ik zal de standaard wiki voor deze server wijzigen.", "hide": true, "admin": true },
 			{ "cmd": "settings channel", "desc": "Ik zal de overschrijvingen voor het huidige kanaal wijzigen.", "hide": true, "admin": true },
 			{ "cmd": "verify <wiki username>", "desc": "Use this command to verify your Discord account with your wiki account and get roles matching your wiki account.", "hide": true },
-			{ "cmd": "verification", "desc": "I will change the wiki verifications used by the `@prefix verify` command.", "admin": true, "pause": true },
-			{ "cmd": "help verification", "desc": "I will explain in more detail how the verification command works.", "unsearchable": true, "admin": true },
+			{ "cmd": "verification", "desc": "I will change the wiki verifications used by the `@prefixverify` command.", "admin": true, "pause": true },
+			{ "cmd": "help verification", "desc": "I will explain in more detail how the verification command works.", "admin": true },
 			{ "cmd": "verification add <role>", "desc": "I will add a new wiki verification. Accepts a `|` separated list.", "hide": true, "admin": true },
 			{ "cmd": "verification <id> channel <new channel>", "desc": "I will update the channel for the wiki verification. Accepts a `|` separated list.", "hide": true, "admin": true },
 			{ "cmd": "verification <id> role <new role>", "desc": "I will update the role for the wiki verification. Accepts a `|` separated list.", "hide": true, "admin": true },

+ 41 - 41
i18n/pl.json

@@ -48,7 +48,6 @@
 		"prefix": "prefiks dla tego serwera:",
 		"prefixinvalid": "podany prefiks nie jest wspierany!",
 		"prefixchanged": "zmieniono prefiks dla tego serwera na:",
-		"prefixhelp": "Użyj `%s <prefiks>` aby zmienić prefiks.\nPrefiks nie może zawierać spacji lub wzmianek!",
 		"inline enabled": {
 			"inline": "linkowanie składnią wiki jest obecnie włączone dla tego serwera.",
 			"channel inline": "linkowanie składnią wiki jest obecnie włączone dla tego kanału.",
@@ -181,44 +180,44 @@
 			"male": "Mężczyzna",
 			"female": "Kobieta"
 		},
-		"groups": [
-			["global_bot", "bot Gamepedii"],
-			["hydra_staff", "personel Gamepedii"],
-			["wiki_manager", "Menedżer wiki"],
-			["content_team_member", "Członek Zespołu Treści"],
-			["GRASP", "GRASP"],
-			["bot-global", "bot globalny"],
-			["staff", "Fandom Staff"],
-			["wiki-manager", "Menedżer wiki"],
-			["helper", "Helper"],
-			["content-team-member", "Członek Zespołu Treści"],
-			["vstf", "VSTF"],
-			["soap", "SOAP"],
-			["content-volunteer", "wolontariusz treści"],
-			["global-discussions-moderator", "globalny moderator dyskusji"],
-			["vanguard", "Vanguard"],
-			["voldev", "Volunteer Developer"],
-			["council", "Community Council"],
-			["bot", "Bot"],
-			["bureaucrat", "Biurokrata"],
-			["sysop", "Administrator"],
-			["interface-admin", "Administrator interfejsu"],
-			["content-moderator", "moderator treści"],
-			["threadmoderator", "moderator dyskusji"],
-			["chatmoderator", "moderator czatu"],
-			["directors", "Dyrektor"],
-			["Patrol", "Inspektor"],
-			["editor", "Redaktor"],
-			["moderator", "Moderator"],
-			["Elite_users", "Elitarni użytkownicy"],
-			["patrollers", "Przeglądający"],
-			["rollback", "rollback"],
-			["autoreview", "autoreview"],
-			["autopatrol", "autopatrol"],
-			["authenticated", "authenticated"],
-			["autoconfirmed", "Automatycznie zatwierdzony użytkownik"],
-			["user", "Użytkownik"]
-		],
+		"groups": {
+			"global_bot": "bot Gamepedii",
+			"hydra_staff": "personel Gamepedii",
+			"wiki_manager": "Menedżer wiki",
+			"content_team_member": "Członek Zespołu Treści",
+			"GRASP": "GRASP",
+			"bot-global": "bot globalny",
+			"staff": "Fandom Staff",
+			"wiki-manager": "Menedżer wiki",
+			"helper": "Helper",
+			"content-team-member": "Członek Zespołu Treści",
+			"vstf": "VSTF",
+			"soap": "SOAP",
+			"content-volunteer": "wolontariusz treści",
+			"global-discussions-moderator": "globalny moderator dyskusji",
+			"vanguard": "Vanguard",
+			"voldev": "Volunteer Developer",
+			"council": "Community Council",
+			"bot": "Bot",
+			"bureaucrat": "Biurokrata",
+			"sysop": "Administrator",
+			"interface-admin": "Administrator interfejsu",
+			"content-moderator": "moderator treści",
+			"threadmoderator": "moderator dyskusji",
+			"chatmoderator": "moderator czatu",
+			"directors": "Dyrektor",
+			"Patrol": "Inspektor",
+			"editor": "Redaktor",
+			"moderator": "Moderator",
+			"Elite_users": "Elitarni użytkownicy",
+			"patrollers": "Przeglądający",
+			"rollback": "rollback",
+			"autoreview": "autoreview",
+			"autopatrol": "autopatrol",
+			"authenticated": "authenticated",
+			"autoconfirmed": "Automatycznie zatwierdzony użytkownik",
+			"user": "Użytkownik"
+		},
 		"info": {
 			"gender": "Płeć:",
 			"registration": "Data rejestracji:",
@@ -387,8 +386,9 @@
 			{ "cmd": "settings wiki <wiki>", "desc": "Zmienię domyślną wiki tego serwera.", "hide": true, "admin": true },
 			{ "cmd": "settings channel", "desc": "Utworzę ustawienia specjalne dla danego kanału.", "hide": true, "admin": true },
 			{ "cmd": "verify <nazwa użytkownika na wiki>", "desc": "Użyj tej komendy do weryfikacji konta Discord kontem na wiki, oraz zdobycia ról odpowiednich dla Twojego konta na wiki.", "hide": true },
-			{ "cmd": "verification", "desc": "Zmienię weryfikację używaną przez komendę `@prefix verify`.", "admin": true, "pause": true },
-			{ "cmd": "help verification", "desc": "Szczegółowo wyjaśnię działanie komendy verify.", "unsearchable": true, "admin": true },
+			{ "cmd": "verification", "desc": "Zmienię weryfikację używaną przez komendę `@prefixverify`.", "admin": true, "pause": true },
+			{ "cmd": "pomoc verification", "desc": "Szczegółowo wyjaśnię działanie komendy verify.", "admin": true },
+			{ "cmd": "help verification", "desc": "Szczegółowo wyjaśnię działanie komendy verify.", "hide": true, "admin": true },
 			{ "cmd": "verification add <rola>", "desc": "Dodam nową weryfikację konta na wiki. Lista ról może być sparowana znakiem `|`.", "hide": true, "admin": true },
 			{ "cmd": "verification <id> channel <nowy kanał>", "desc": "Zmienię kanał dla weryfikacji. Lista kanałów może być sparowana znakiem `|`.", "hide": true, "admin": true },
 			{ "cmd": "verification <id> role <nowa rola>", "desc": "Zmienię dodawane role dla weryfikacji. Lista ról może być sparowana znakiem `|`.", "hide": true, "admin": true },

+ 41 - 56
i18n/pt.json

@@ -29,7 +29,6 @@
 		"channel current": "estas são as configurações atuais deste canal:",
 		"currentlang": "Idioma:",
 		"currentprefix": "Prefixo:",
-		"currentinline": "Inline commands:",
 		"currentwiki": "Wiki padrão:",
 		"currentchannel": "Substituições de canal:",
 		"nochannels": "*Nenhum canal sobrescreve ainda*",
@@ -48,22 +47,7 @@
 		"wikihelp": "Use `%s <link>` para alterar a wiki padrão.\nLink para a wiki: `https://<wiki>.gamepedia.com/` ou `https://<wiki>.fandom.com/`",
 		"prefix": "o prefixo deste servidor é:",
 		"prefixinvalid": "o prefixo especificado não é suportado!",
-		"prefixchanged": "você mudou o prefixo deste servidor para:",
-		"prefixhelp": "Use `%s <prefixo>` para alterar o prefixo.\nO prefixo pode não incluir espaços ou menções!",
-		"inline enabled": {
-			"inline": "inline commands are currently enabled for this server.",
-			"channel inline": "inline commands are currently enabled for this channel.",
-			"inlinechanged": "you enabled inline commands for this server.",
-			"channel inlinechanged": "you enabled inline commands for this channel.",
-			"help": "Use `%1$s` to disable inline commands like `[[%2$s]]` and `{{%2$s}}`."
-		},
-		"inline disabled": {
-			"inline": "inline commands are currently disabled for this server.",
-			"channel inline": "inline commands are currently disabled for this channel.",
-			"inlinechanged": "you disabled inline commands for this server.",
-			"channel inlinechanged": "you disabled inline commands for this channel.",
-			"help": "Use `%1$s` to enable inline commands like `[[%2$s]]` and `{{%2$s}}`."
-		}
+		"prefixchanged": "você mudou o prefixo deste servidor para:"
 	},
 	"pause": {
 		"on": "Agora estou pausado neste servidor e ignorarei a maioria dos comandos!",
@@ -182,43 +166,43 @@
 			"male": "Masculino",
 			"female": "Feminino"
 		},
-		"groups": [
-			["global_bot", "Robô da Gamepedia"],
-			["hydra_staff", "Equipe da Gamepedia"],
-			["wiki_manager", "Gerente de wiki"],
-			["content_team_member", "Membro da equipe de conteúdo"],
-			["grasp", "GRASP"],
-			["bot-global", "Robô do Fandom"],
-			["staff", "Staff do Fandom"],
-			["wiki-manager", "Gerente de wiki"],
-			["helper", "Ajudante do Fandom"],
-			["content-team-member", "Membro da equipe de conteúdo"],
-			["vstf", "VSTF"],
-			["content-volunteer", "Voluntário de conteúdo"],
-			["global-discussions-moderator", "Moderador global de discussões"],
-			["vanguard", "Vanguarda"],
-			["voldev", "Programadores Voluntários"],
-			["council", "Conselho da Comunidade"],
-			["bot", "Robô"],
-			["bureaucrat", "Burocrata"],
-			["sysop", "Administrador"],
-			["interface-admin", "Administrador da interface"],
-			["content-moderator", "Moderador de conteúdo"],
-			["threadmoderator", "Moderador de discussões"],
-			["chatmoderator", "Moderador do chat"],
-			["directors", "Diretor"],
-			["Patrol", "Inspetor"],
-			["editor", "Editor"],
-			["moderator", "Moderador"],
-			["Elite_users", "Usuário elite"],
-			["patrollers", "Patrulheiro"],
-			["rollback", "rollback"],
-			["autoreview", "revisão automática"],
-			["autopatrol", "autopatrulha"],
-			["authenticated", "authenticated"],
-			["autoconfirmed", "Utilizador autoconfirmado"],
-			["user", "Usuário"]
-		],
+		"groups": {
+			"global_bot": "Robô da Gamepedia",
+			"hydra_staff": "Equipe da Gamepedia",
+			"wiki_manager": "Gerente de wiki",
+			"content_team_member": "Membro da equipe de conteúdo",
+			"grasp": "GRASP",
+			"bot-global": "Robô do Fandom",
+			"staff": "Staff do Fandom",
+			"wiki-manager": "Gerente de wiki",
+			"helper": "Ajudante do Fandom",
+			"content-team-member": "Membro da equipe de conteúdo",
+			"vstf": "VSTF",
+			"content-volunteer": "Voluntário de conteúdo",
+			"global-discussions-moderator": "Moderador global de discussões",
+			"vanguard": "Vanguarda",
+			"voldev": "Programadores Voluntários",
+			"council": "Conselho da Comunidade",
+			"bot": "Robô",
+			"bureaucrat": "Burocrata",
+			"sysop": "Administrador",
+			"interface-admin": "Administrador da interface",
+			"content-moderator": "Moderador de conteúdo",
+			"threadmoderator": "Moderador de discussões",
+			"chatmoderator": "Moderador do chat",
+			"directors": "Diretor",
+			"Patrol": "Inspetor",
+			"editor": "Editor",
+			"moderator": "Moderador",
+			"Elite_users": "Usuário elite",
+			"patrollers": "Patrulheiro",
+			"rollback": "rollback",
+			"autoreview": "revisão automática",
+			"autopatrol": "autopatrulha",
+			"authenticated": "authenticated",
+			"autoconfirmed": "Utilizador autoconfirmado",
+			"user": "Usuário"
+		},
 		"info": {
 			"gender": "Gênero:",
 			"registration": "Data de registro:",
@@ -362,8 +346,9 @@
 			{ "cmd": "settings wiki <wiki>", "desc": "Vou mudar a wiki padrão para esse servidor.", "hide": true, "admin": true },
 			{ "cmd": "settings channel", "desc": "Vou mudar as substituições para o canal atual.", "hide": true, "admin": true },
 			{ "cmd": "verify <wiki username>", "desc": "Use este comando para verificar sua conta do Discord com a sua conta wiki e obter funções correspondentes à sua conta na wiki.", "hide": true },
-			{ "cmd": "verification", "desc": "Vou mudar as verificações da wiki usadas pelo comando `@prefix verify`.", "admin": true, "pause": true },
-			{ "cmd": "help verification", "desc": "Vou explicar mais detalhadamente como o comando de verificação funciona.", "unsearchable": true, "admin": true },
+			{ "cmd": "verification", "desc": "Vou mudar as verificações da wiki usadas pelo comando `@prefixverify`.", "admin": true, "pause": true },
+			{ "cmd": "ajuda verification", "desc": "Vou explicar mais detalhadamente como o comando de verificação funciona.", "admin": true },
+			{ "cmd": "help verification", "desc": "Vou explicar mais detalhadamente como o comando de verificação funciona.", "hide": true, "admin": true },
 			{ "cmd": "verification add <função>", "desc": "Vou adicionar uma nova verificação da wiki. Aceita uma `|` lista separada.", "hide": true, "admin": true },
 			{ "cmd": "verification <id> channel <novo canal>", "desc": "Vou mudar o canal para a verificação da wiki. Aceita uma `|` lista separada.", "hide": true, "admin": true },
 			{ "cmd": "verification <id> role <nova função>", "desc": "Vou mudar o papel da verificação do wiki. Aceita uma `|` lista separada.", "hide": true, "admin": true },

+ 42 - 63
i18n/ru.json

@@ -25,7 +25,6 @@
 		"channel current": "вот настройки этого канала на данный момент:",
 		"currentlang": "Язык:",
 		"currentprefix": "Префикс:",
-		"currentinline": "Inline commands:",
 		"currentwiki": "Стандартная вики:",
 		"currentchannel": "Перезаписей канала:",
 		"nochannels": "*Перезаписей канала не было*",
@@ -44,22 +43,7 @@
 		"wikihelp": "Используйте `%s <ссылка>` чтобы изменить вики по умолчанию.\nСсылка на вики: `https://<вики>.gamepedia.com/` или `https://<вики>.fandom.com/`",
 		"prefix": "префикс для этого сервера:",
 		"prefixinvalid": "указанный префикс не поддерживается!",
-		"prefixchanged": "вы изменили префикс для этого сервера на:",
-		"prefixhelp": "Используйте `%s <префикс>` для изменения префикса команд.\nПрефикс не может содержать пробелы или @-упоминания!",
-		"inline enabled": {
-			"inline": "inline commands are currently enabled for this server.",
-			"channel inline": "inline commands are currently enabled for this channel.",
-			"inlinechanged": "you enabled inline commands for this server.",
-			"channel inlinechanged": "you enabled inline commands for this channel.",
-			"help": "Use `%1$s` to disable inline commands like `[[%2$s]]` and `{{%2$s}}`."
-		},
-		"inline disabled": {
-			"inline": "inline commands are currently disabled for this server.",
-			"channel inline": "inline commands are currently disabled for this channel.",
-			"inlinechanged": "you disabled inline commands for this server.",
-			"channel inlinechanged": "you disabled inline commands for this channel.",
-			"help": "Use `%1$s` to enable inline commands like `[[%2$s]]` and `{{%2$s}}`."
-		}
+		"prefixchanged": "вы изменили префикс для этого сервера на:"
 	},
 	"pause": {
 		"on": "Сейчас я остановлен на этом сервере и буду игнорировать большинство команд!",
@@ -148,8 +132,7 @@
 		"qualified_error": "Оценен, но не может быть добавлен:",
 		"help_guide": "Изучите [этот гайд](%s) для добавления пользователя Discord в свой профиль:",
 		"help_gamepedia": "https://help.gamepedia.com/Gamepedia_Help_Wiki:Discord_verification",
-		"help_fandom": "https://community.fandom.com/wiki/Special:VerifyUser",
-		"help_subpage": "Please add your Discord tag (%s) to your Discord subpage on the wiki:"
+		"help_fandom": "https://community.fandom.com/wiki/Special:VerifyUser"
 	},
 	"overview": {
 		"inaccurate": "Статистика может быть неточной ",
@@ -178,43 +161,43 @@
 			"male": "Парень",
 			"female": "Девушка"
 		},
-		"groups": [
-			["global_bot", "Глобальный бот"],
-			["hydra_staff", "Сотрудники Gamepedia"],
-			["wiki_manager", "Руководитель вики"],
-			["content_team_member", "Участник контент-команды"],
-			["grasp", "GRASP"],
-			["bot-global", "Глобальный бот"],
-			["staff", "Сотрудники Fandom"],
-			["wiki-manager", "Руководитель вики"],
-			["helper", "Помощник Fandom"],
-			["content-team-member", "Участник контент-команды"],
-			["vstf", "VSTF"],
-			["content-volunteer", "Контент-доброволец"],
-			["global-discussions-moderator", "Глобальный модератор дискуссий"],
-			["vanguard", "Vanguard"],
-			["voldev", "Volunteer Developer"],
-			["council", "Community Council"],
-			["bot", "Бот"],
-			["bureaucrat", "Бюрократ"],
-			["sysop", "Администратор"],
-			["interface-admin", "Aдминистратор интерфейса"],
-			["content-moderator", "Модератор контента"],
-			["threadmoderator", "Модератор дискуссий"],
-			["chatmoderator", "Модератор чата"],
-			["directors", "Director"],
-			["Patrol", "Inspector"],
-			["editor", "Editor"],
-			["moderator", "Moderator"],
-			["Elite_users", "Elite user"],
-			["patrollers", "Patroller"],
-			["rollback", "откат"],
-			["autoreview", "autoreview"],
-			["autopatrol", "autopatrol"],
-			["authenticated", "подтверждено"],
-			["autoconfirmed", "Автоподтверждённый участник"],
-			["user", "Пользователь"]
-		],
+		"groups": {
+			"global_bot": "Глобальный бот",
+			"hydra_staff": "Сотрудники Gamepedia",
+			"wiki_manager": "Руководитель вики",
+			"content_team_member": "Участник контент-команды",
+			"grasp": "GRASP",
+			"bot-global": "Глобальный бот",
+			"staff": "Сотрудники Fandom",
+			"wiki-manager": "Руководитель вики",
+			"helper": "Помощник Fandom",
+			"content-team-member": "Участник контент-команды",
+			"vstf": "VSTF",
+			"content-volunteer": "Контент-доброволец",
+			"global-discussions-moderator": "Глобальный модератор дискуссий",
+			"vanguard": "Vanguard",
+			"voldev": "Volunteer Developer",
+			"council": "Community Council",
+			"bot": "Бот",
+			"bureaucrat": "Бюрократ",
+			"sysop": "Администратор",
+			"interface-admin": "Aдминистратор интерфейса",
+			"content-moderator": "Модератор контента",
+			"threadmoderator": "Модератор дискуссий",
+			"chatmoderator": "Модератор чата",
+			"directors": "Director",
+			"Patrol": "Inspector",
+			"editor": "Editor",
+			"moderator": "Moderator",
+			"Elite_users": "Elite user",
+			"patrollers": "Patroller",
+			"rollback": "откат",
+			"autoreview": "autoreview",
+			"autopatrol": "autopatrol",
+			"authenticated": "подтверждено",
+			"autoconfirmed": "Автоподтверждённый участник",
+			"user": "Пользователь"
+		},
 		"info": {
 			"gender": "Гендер:",
 			"registration": "Дата регистрации:",
@@ -280,11 +263,7 @@
 			}
 		},
 		"special": "Содержание этой спецтраницы:",
-		"empty": "*Эта спецстраница пуста*",
-		"results": {
-			"default": "%s total results",
-			"1": "%s total result"
-		}
+		"empty": "*Эта спецстраница пуста*"
 	},
 	"discussion": {
 		"post": "пост",
@@ -352,8 +331,8 @@
 			{ "cmd": "settings wiki <вики>", "desc": "Я изменю вики по умолчанию для этого сервера.", "hide": true, "admin": true },
 			{ "cmd": "settings channel", "desc": "Я изменю перезаписи для текущего канала.", "hide": true, "admin": true },
 			{ "cmd": "verify <wiki username>", "desc": "Use this command to verify your Discord account with your wiki account and get roles matching your wiki account.", "hide": true },
-			{ "cmd": "verification", "desc": "I will change the wiki verifications used by the `@prefix verify` command.", "admin": true, "pause": true },
-			{ "cmd": "help verification", "desc": "I will explain in more detail how the verification command works.", "unsearchable": true, "admin": true },
+			{ "cmd": "verification", "desc": "I will change the wiki verifications used by the `@prefixverify` command.", "admin": true, "pause": true },
+			{ "cmd": "help verification", "desc": "I will explain in more detail how the verification command works.", "admin": true },
 			{ "cmd": "verification add <role>", "desc": "I will add a new wiki verification. Accepts a `|` separated list.", "hide": true, "admin": true },
 			{ "cmd": "verification <id> channel <new channel>", "desc": "I will update the channel for the wiki verification. Accepts a `|` separated list.", "hide": true, "admin": true },
 			{ "cmd": "verification <id> role <new role>", "desc": "I will update the role for the wiki verification. Accepts a `|` separated list.", "hide": true, "admin": true },

+ 41 - 133
i18n/tr.json

@@ -27,7 +27,6 @@
 		"channel current": "kanalın mevcut ayarları:",
 		"currentlang": "Dil:",
 		"currentprefix": "Önek:",
-		"currentinline": "Inline commands:",
 		"currentwiki": "Varsayılan wiki:",
 		"currentchannel": "Kanal özel ayarları:",
 		"nochannels": "*Şimdilik bir kanala özel ayar yok*",
@@ -46,22 +45,7 @@
 		"wikihelp": "`%s <wiki>` kullanarak varsayılan wikiyi değiştirebilirsin.\nWiki bağlantısı: `https://<wiki>.gamepedia.com/` veya `https://<wiki>.fandom.com/`",
 		"prefix": "sunucudaki önekim:",
 		"prefixinvalid": "belirtilen önek desteklenmiyor!",
-		"prefixchanged": "sunucunun öneki şuna değiştirildi:",
-		"prefixhelp": "Öneki değiştirmek için `%s <önek>`.\nÖnekte etiketler ve boşluklar bulunamaz!",
-		"inline enabled": {
-			"inline": "inline commands are currently enabled for this server.",
-			"channel inline": "inline commands are currently enabled for this channel.",
-			"inlinechanged": "you enabled inline commands for this server.",
-			"channel inlinechanged": "you enabled inline commands for this channel.",
-			"help": "Use `%1$s` to disable inline commands like `[[%2$s]]` and `{{%2$s}}`."
-		},
-		"inline disabled": {
-			"inline": "inline commands are currently disabled for this server.",
-			"channel inline": "inline commands are currently disabled for this channel.",
-			"inlinechanged": "you disabled inline commands for this server.",
-			"channel inlinechanged": "you disabled inline commands for this channel.",
-			"help": "Use `%1$s` to enable inline commands like `[[%2$s]]` and `{{%2$s}}`."
-		}
+		"prefixchanged": "sunucunun öneki şuna değiştirildi:"
 	},
 	"pause": {
 		"on": "Şimdi bu sunucuda duraklatıldım ve çoğu komutu görmezden geleceğim!",
@@ -78,81 +62,6 @@
 		"join": "%1$s ses kanalına katıldı \"%2$s\".",
 		"left": "%1$s ses kanalından ayrıldı \"%2$s\"."
 	},
-	"verification": {
-		"save_failed": "sadly the verification couldn't be saved, please try again later.",
-		"added": "the verification has been added:",
-		"updated": "the verification has been updated:",
-		"deleted": "the verification has been deleted.",
-		"max_entries": "you already reached the maximal amount of verifications.",
-		"no_role": "please provide a role for the new verification.",
-		"current": "these are the current verifications for this server:",
-		"current_selected": "this is the verification `%s` for this server:",
-		"missing": "there are no verifications for this server yet.",
-		"add_more": "Add more verifications:",
-		"delete_current": "Delete this verification:",
-		"channel": "Channel:",
-		"role": "Role:",
-		"editcount": "Edit count:",
-		"usergroup": "User group:",
-		"or": "or",
-		"and": "and",
-		"accountage": "Account age:",
-		"indays": "(in days)",
-		"rename": "Change nickname:",
-		"enabled": "enabled",
-		"disabled": "disabled",
-		"toggle": "(toggle)",
-		"rename_no_permission": "**%s is missing the `Manage Nicknames` permission to force wiki usernames!**",
-		"role_too_high": "**The role %1$s is too high for %2$s to assign!**",
-		"channel_max": "too many channels provided.",
-		"channel_missing": "the provided channel does not exist.",
-		"role_max": "too many roles provided.",
-		"role_missing": "the provided role does not exist.",
-		"role_managed": "the provided role can't be assigned.",
-		"value_too_high": "the provided value is too high.",
-		"usergroup_max": "too many user groups provided.",
-		"usergroup_too_long": "the provided user group is too long.",
-		"new_channel": "<new channel>",
-		"new_role": "<new role>",
-		"new_editcount": "<new edit count>",
-		"new_usergroup": "<new user group>",
-		"new_accountage": "<new account age>"
-	},
-	"verify": {
-		"error": "The verification failed due to an error.",
-		"error_reply": "the verification failed due to an error, please try again.",
-		"missing": "there are no verifications set up for this channel.",
-		"footer": "Wiki Account Verification",
-		"failed_gblock": "**Check for global block failed!**",
-		"failed_roles": "**Adding roles failed!**",
-		"failed_rename": "**Changing the nickname failed!**",
-		"audit_reason": "Verified as \"%s\"",
-		"user_missing": "The wiki user \"%s\" doesn't exist.",
-		"user_missing_reply": "your linked wiki user \"%s\" doesn't exist.",
-		"user_blocked": "**The wiki user %s is blocked!**",
-		"user_blocked_reply": "your linked wiki user **\"%s\" is blocked!**",
-		"user_gblocked": "**The wiki user %s is globally blocked!**",
-		"user_gblocked_reply": "your linked wiki user **\"%s\" is globally blocked!**",
-		"user_disabled": "**The wiki user %s is disabled!**",
-		"user_disabled_reply": "your linked wiki user **\"%s\" is disabled!**",
-		"user_failed": "Discord user %1$s doesn't match the wiki user %2$s.",
-		"user_failed_reply": "your Discord tag doesn't match the wiki user \"%s\".",
-		"user_matches": "Discord user %1$s matches the wiki user %2$s, but doesn't meet the requirements for any roles.",
-		"user_matches_reply": "your Discord tag matches the wiki user \"%s\", but you don't meet the requirements for any roles.",
-		"user_verified": "Discord user %1$s has been successfully verified as wiki user %2$s.",
-		"user_verified_reply": "you have been successfully verified as wiki user \"%s\".",
-		"user_renamed": "Their Discord nickname has been changed to their wiki username.",
-		"discord": "Discord user:",
-		"wiki": "Wiki user:",
-		"empty": "*empty*",
-		"notice": "Notice:",
-		"qualified": "Qualified for:",
-		"qualified_error": "Qualified for, but could not add:",
-		"help_guide": "Follow [this guide](%s) to add your Discord tag to your wiki profile.",
-		"help_gamepedia": "https://help.gamepedia.com/Gamepedia_Help_Wiki:Discord_verification",
-		"help_fandom": "https://community.fandom.com/wiki/Special:VerifyUser",
-		"help_subpage": "Please add your Discord tag (%s) to your Discord subpage on the wiki:"
-	},
 	"overview": {
 		"inaccurate": "İstatistikler yanlış olabilir",
 		"name": "Tam isim:",
@@ -180,43 +89,43 @@
 			"male": "erkek",
 			"female": "kadın"
 		},
-		"groups": [
-			["global_bot", "Gamepedia bot"],
-			["hydra_staff", "Gamepedia personeli"],
-			["wiki_manager", "Wiki yöneticisi"],
-			["content_team_member", "İçerik Takımı Üyesi"],
-			["grasp", "GRASP"],
-			["bot-global", "Fandom bot"],
-			["staff", "Fandom personeli"],
-			["wiki-manager", "Wiki yöneticisi"],
-			["helper", "Fandom yardımcısı"],
-			["content-team-member", "İçerik Takımı Üyesi"],
-			["vstf", "VSTF"],
-			["content-volunteer", "İçerik gönüllüsü"],
-			["global-discussions-moderator", "Global tartışma moderatörü"],
-			["vanguard", "Vanguard"],
-			["voldev", "Gönüllü Geliştirici"],
-			["council", "Topluluk Konseyi"],
-			["bot", "Bot"],
-			["bureaucrat", "Bürokrat"],
-			["sysop", "Yönetici"],
-			["interface-admin", "Arayüz yöneticisi"],
-			["content-moderator", "İçerik moderatörü"],
-			["threadmoderator", "Tartışma moderatörü"],
-			["chatmoderator", "Sohbet moderatörü"],
-			["directors", "Director"],
-			["Patrol", "Inspector"],
-			["editor", "Editor"],
-			["moderator", "Moderator"],
-			["Elite_users", "Elite user"],
-			["patrollers", "Patroller"],
-			["rollback", "geri alma"],
-			["autoreview", "autoreview"],
-			["autopatrol", "autopatrol"],
-			["authenticated", "doğrulanmış"],
-			["autoconfirmed", "Otomatik onaylanmış kullanıcı"],
-			["user", "Kullanıcı"]
-		],
+		"groups": {
+			"global_bot": "Gamepedia bot",
+			"hydra_staff": "Gamepedia personeli",
+			"wiki_manager": "Wiki yöneticisi",
+			"content_team_member": "İçerik Takımı Üyesi",
+			"grasp": "GRASP",
+			"bot-global": "Fandom bot",
+			"staff": "Fandom personeli",
+			"wiki-manager": "Wiki yöneticisi",
+			"helper": "Fandom yardımcısı",
+			"content-team-member": "İçerik Takımı Üyesi",
+			"vstf": "VSTF",
+			"content-volunteer": "İçerik gönüllüsü",
+			"global-discussions-moderator": "Global tartışma moderatörü",
+			"vanguard": "Vanguard",
+			"voldev": "Gönüllü Geliştirici",
+			"council": "Topluluk Konseyi",
+			"bot": "Bot",
+			"bureaucrat": "Bürokrat",
+			"sysop": "Yönetici",
+			"interface-admin": "Arayüz yöneticisi",
+			"content-moderator": "İçerik moderatörü",
+			"threadmoderator": "Tartışma moderatörü",
+			"chatmoderator": "Sohbet moderatörü",
+			"directors": "Director",
+			"Patrol": "Inspector",
+			"editor": "Editor",
+			"moderator": "Moderator",
+			"Elite_users": "Elite user",
+			"patrollers": "Patroller",
+			"rollback": "geri alma",
+			"autoreview": "autoreview",
+			"autopatrol": "autopatrol",
+			"authenticated": "doğrulanmış",
+			"autoconfirmed": "Otomatik onaylanmış kullanıcı",
+			"user": "Kullanıcı"
+		},
 		"info": {
 			"gender": "Cinsiyet:",
 			"registration": "Kayıt tarihi:",
@@ -356,8 +265,9 @@
 			{ "cmd": "settings wiki <wiki>", "desc": "Bu sunucunun varsayılan wikisini değiştireceğim.", "hide": true, "admin": true },
 			{ "cmd": "settings channel", "desc": "Mevcut kanalın kanala özel ayarlarını değiştireceğim.", "hide": true, "admin": true },
 			{ "cmd": "verify <wiki username>", "desc": "Use this command to verify your Discord account with your wiki account and get roles matching your wiki account.", "hide": true },
-			{ "cmd": "verification", "desc": "I will change the wiki verifications used by the `@prefix verify` command.", "admin": true, "pause": true },
-			{ "cmd": "help verification", "desc": "I will explain in more detail how the verification command works.", "unsearchable": true, "admin": true },
+			{ "cmd": "verification", "desc": "I will change the wiki verifications used by the `@prefixverify` command.", "admin": true, "pause": true },
+			{ "cmd": "yardım verification", "desc": "I will explain in more detail how the verification command works.", "admin": true },
+			{ "cmd": "help verification", "desc": "I will explain in more detail how the verification command works.", "hide": true, "admin": true },
 			{ "cmd": "verification add <role>", "desc": "I will add a new wiki verification. Accepts a `|` separated list.", "hide": true, "admin": true },
 			{ "cmd": "verification <id> channel <new channel>", "desc": "I will update the channel for the wiki verification. Accepts a `|` separated list.", "hide": true, "admin": true },
 			{ "cmd": "verification <id> role <new role>", "desc": "I will update the role for the wiki verification. Accepts a `|` separated list.", "hide": true, "admin": true },
@@ -378,8 +288,6 @@
 		"aliases": {
 			"cmd": "command"
 		},
-		"private": "**Private Issue**",
-		"fixed": "Fixed Version:",
 		"more": "Ve %s tane daha.",
 		"total": "%s hata düzeltildi"
 	}

+ 40 - 49
i18n/zh.json

@@ -46,7 +46,6 @@
 		"prefix": "本伺服器的前缀是:",
 		"prefixinvalid": "不支持提供的前缀!",
 		"prefixchanged": "您将本伺服器命令前缀更改为:",
-		"prefixhelp": "使用 `%s <prefix>` 更改命令前缀。\n前缀不得包含空格或提及!",
 		"inline enabled": {
 			"inline": "行内命令目前已在本伺服器启用。",
 			"channel inline": "行内命令目前已在本频道启用。",
@@ -179,43 +178,43 @@
 			"male": "男",
 			"female": "女"
 		},
-		"groups": [
-			["global_bot", "全域机器人"],
-			["hydra_staff", "Gamepedia员工"],
-			["wiki_manager", "Wiki主管"],
-			["content_team_member", "内容团队"],
-			["grasp", "GRASP"],
-			["bot-global", "全域机器人"],
-			["staff", "Fandom员工"],
-			["wiki-manager", "Wiki主管"],
-			["helper", "Fandom助手"],
-			["content-team-member", "内容团队"],
-			["vstf", "VSTF"],
-			["content-volunteer", "内容志愿者"],
-			["global-discussions-moderator", "全域讨论版主"],
-			["vanguard", "Vanguard"],
-			["voldev", "志愿开发者"],
-			["council", "社区委员会"],
-			["bot", "机器人"],
-			["bureaucrat", "行政员"],
-			["sysop", "管理员"],
-			["interface-admin", "界面管理员"],
-			["content-moderator", "内容版主"],
-			["threadmoderator", "讨论版主"],
-			["chatmoderator", "聊天主持人"],
-			["directors", "向导"],
-			["Patrol", "巡查员"],
-			["editor", "编辑者"],
-			["moderator", "版主"],
-			["Elite_users", "精英用户"],
-			["patrollers", "巡查员"],
-			["rollback", "回退员"],
-			["autoreview", "自动复核用户"],
-			["autopatrol", "自动巡查/巡查豁免者"],
-			["authenticated", "认证用户"],
-			["autoconfirmed", "自动确认用户"],
-			["user", "用户"]
-		],
+		"groups": {
+			"global_bot": "全域机器人",
+			"hydra_staff": "Gamepedia员工",
+			"wiki_manager": "Wiki主管",
+			"content_team_member": "内容团队",
+			"grasp": "GRASP",
+			"bot-global": "全域机器人",
+			"staff": "Fandom员工",
+			"wiki-manager": "Wiki主管",
+			"helper": "Fandom助手",
+			"content-team-member": "内容团队",
+			"vstf": "VSTF",
+			"content-volunteer": "内容志愿者",
+			"global-discussions-moderator": "全域讨论版主",
+			"vanguard": "Vanguard",
+			"voldev": "志愿开发者",
+			"council": "社区委员会",
+			"bot": "机器人",
+			"bureaucrat": "行政员",
+			"sysop": "管理员",
+			"interface-admin": "界面管理员",
+			"content-moderator": "内容版主",
+			"threadmoderator": "讨论版主",
+			"chatmoderator": "聊天主持人",
+			"directors": "向导",
+			"Patrol": "巡查员",
+			"editor": "编辑者",
+			"moderator": "版主",
+			"Elite_users": "精英用户",
+			"patrollers": "巡查员",
+			"rollback": "回退员",
+			"autoreview": "自动复核用户",
+			"autopatrol": "自动巡查/巡查豁免者",
+			"authenticated": "认证用户",
+			"autoconfirmed": "自动确认用户",
+			"user": "用户"
+		},
 		"info": {
 			"gender": "性别:",
 			"registration": "注册时间:",
@@ -299,10 +298,6 @@
 		"random": 10,
 		"pause": "我正处于暂停状态",
 		"text": [
-			"I'm still alive!",
-			"and believe me, I am still alive.",
-			"I'm doing science and I'm still alive.",
-			"I feel fantastic and I'm still alive."
 		],
 		"default": "全功率运行中!",
 		"time": "咋瓦鲁多"
@@ -349,8 +344,8 @@
 			{ "cmd": "settings channel", "desc": "我将更改本伺服器的当前频道的覆盖设置。", "hide": true, "admin": true },
 			{ "cmd": "验证 <wiki用户名>", "desc": "使用此命令以验证您的Discord账户和您的wiki账户,并获取您的wiki账户对应的身份组。", "hide": true },
 			{ "cmd": "verify <wiki用户名>", "desc": "使用此命令以验证您的Discord账户和您的wiki账户,并获取您的wiki账户对应的身份组。", "hide": true },
-			{ "cmd": "verification", "desc": "我将更改由 `@prefix 验证` 触发的wiki验证方式命令。", "admin": true, "pause": true },
-			{ "cmd": "help verification", "desc": "我将详细解释验证命令如何工作。", "unsearchable": true, "admin": true },
+			{ "cmd": "verification", "desc": "我将更改由 `@prefix验证` 触发的wiki验证方式命令。", "admin": true, "pause": true },
+			{ "cmd": "help verification", "desc": "我将详细解释验证命令如何工作。", "admin": true },
 			{ "cmd": "verification add <身份组>", "desc": "我将添加一个新的验证方式。可用 `|` 来分割多个身份组组。", "hide": true, "admin": true },
 			{ "cmd": "verification <id> channel <新频道>", "desc": "我将更改适用于本验证方式的频道。可用 `|` 来分割多个频道。", "hide": true, "admin": true },
 			{ "cmd": "verification <id> role <新身份组>", "desc": "我将更改此验证方式的身份组。可用 `|` 来分割多个身份组。", "hide": true, "admin": true },
@@ -370,10 +365,6 @@
 		"cmdpage": "命令/",
 		"aliases": {
 			"cmd": "command"
-		},
-		"private": "**Private Issue**",
-		"fixed": "Fixed Version:",
-		"more": "And %s more.",
-		"total": "%s issues fixed"
+		}
 	}
 }

+ 1 - 1
package.json

@@ -1,7 +1,7 @@
 {
   "name": "discord-wiki-bot",
   "version": "2.2.0",
-  "description": "Wiki-Bot is a bot for Discord with the purpose to easily link to Gamepedia and Fandom wikis. He resolves redirects and follows interwiki links.",
+  "description": "Wiki-Bot is a bot with the purpose to easily search for and link to wiki pages. Wiki-Bot shows short descriptions and additional info about the pages and is able to resolve redirects and follow interwiki links.",
   "main": "main.js",
   "scripts": {
     "test": "node main.js debug",

+ 39 - 1
util/default.json

@@ -12,5 +12,43 @@
 		"minute": "2-digit",
 		"timeZone": "UTC",
 		"timeZoneName": "short"
-	}
+	},
+	"usergroups": [
+		"global_bot",
+		"hydra_staff",
+		"wiki_manager",
+		"content_team_member",
+		"grasp",
+		"bot-global",
+		"staff",
+		"wiki-manager",
+		"helper",
+		"content-team-member",
+		"soap",
+		"vstf",
+		"content-volunteer",
+		"global-discussions-moderator",
+		"vanguard",
+		"voldev",
+		"council",
+		"bot",
+		"bureaucrat",
+		"sysop",
+		"interface-admin",
+		"content-moderator",
+		"threadmoderator",
+		"chatmoderator",
+		"directors",
+		"Patrol",
+		"editor",
+		"moderator",
+		"Elite_users",
+		"patrollers",
+		"rollback",
+		"autoreview",
+		"autopatrol",
+		"authenticated",
+		"autoconfirmed",
+		"user"
+	]
 }

+ 37 - 0
util/i18n.js

@@ -0,0 +1,37 @@
+const {defaultSettings} = require('./default.json');
+var i18n = require('../i18n/allLangs.json');
+Object.keys(i18n.allLangs.names).forEach( lang => i18n[lang] = require('../i18n/' + lang + '.json') );
+
+class Lang {
+	constructor(lang = defaultSettings.lang, namespace = '') {
+		this.lang = lang;
+		this.namespace = namespace;
+	}
+
+	get(message = '') {
+		if ( this.namespace.length ) message = this.namespace + '.' + message;
+		let args = ( message.length ? message.split('.') : [] );
+		let lang = this.lang;
+		let text = i18n?.[lang];
+		for (let n = 0; n < args.length; n++) {
+			if ( text ) {
+				text = text?.[args[n]];
+			}
+			else if ( lang !== defaultSettings.lang ) {
+				lang = defaultSettings.lang;
+				text = i18n?.[lang];
+				n = 0;
+			}
+			else {
+				n = args.length;
+			}
+		}
+		return ( text || '⧼' + message + '⧽' );
+	}
+
+	static allLangs() {
+		return i18n.allLangs;
+	}
+}
+
+module.exports = Lang;

+ 49 - 48
util/newMessage.js

@@ -25,54 +25,56 @@ function newMessage(msg, lang, wiki = defaultSettings.wiki, prefix = process.env
 	var cleanCont = ( content && Util.cleanContent(content, msg) || msg.cleanContent );
 	var author = msg.author;
 	var channel = msg.channel;
-	var invoke = ( cont.split(' ')[1] ? cont.split(' ')[1].split('\n')[0].toLowerCase() : '' );
-	var aliasInvoke = ( lang.aliases[invoke] || invoke );
+	var invoke = cont.substring(prefix.length).split(' ')[0].split('\n')[0].toLowerCase();
+	var aliasInvoke = ( lang.get('aliases')[invoke] || invoke );
 	var ownercmd = ( msg.isOwner() && aliasInvoke in ownercmdmap );
 	if ( cont.hasPrefix(prefix) && ownercmd ) {
-		var args = cont.split(' ').slice(2);
-		if ( cont.split(' ')[1].split('\n')[1] ) args.unshift( '', cont.split(' ')[1].split('\n')[1] );
-		else console.log( ( channel.type === 'text' ? msg.guild.id : '@' + author.id ) + ': ' + cont );
-		ownercmdmap[aliasInvoke](lang, msg, args, cont, wiki);
-	} else {
-		var count = 0;
-		var maxcount = ( channel.type === 'text' && msg.guild.id in patreons ? 15 : 10 );
-		cleanCont.replace( /\u200b/g, '' ).split('\n').forEach( line => {
-			if ( line.hasPrefix(prefix) && count < maxcount ) {
-				count++;
-				invoke = ( line.split(' ')[1] ? line.split(' ')[1].toLowerCase() : '' );
-				var args = line.split(' ').slice(2);
-				aliasInvoke = ( lang.aliases[invoke] || invoke );
-				ownercmd = ( msg.isOwner() && aliasInvoke in ownercmdmap );
-				if ( channel.type === 'text' && pause[msg.guild.id] && !( ( msg.isAdmin() && aliasInvoke in pausecmdmap ) || ownercmd ) ) console.log( msg.guild.id + ': Paused' );
-				else console.log( ( channel.type === 'text' ? msg.guild.id : '@' + author.id ) + ': ' + line );
-				if ( ownercmd ) ownercmdmap[aliasInvoke](lang, msg, args, line, wiki);
-				else if ( channel.type !== 'text' || !pause[msg.guild.id] || ( msg.isAdmin() && aliasInvoke in pausecmdmap ) ) {
-					if ( aliasInvoke in cmdmap ) cmdmap[aliasInvoke](lang, msg, args, line, wiki);
-					else if ( /^![a-z\d-]{1,50}$/.test(invoke) ) {
-						cmdmap.LINK(lang, msg, args.join(' '), 'https://' + invoke.substring(1) + '.gamepedia.com/', ' ' + invoke + ' ');
-					}
-					else if ( /^\?(?:[a-z-]{1,8}\.)?[a-z\d-]{1,50}$/.test(invoke) ) {
-						var invokeWiki = wiki;
-						if ( invoke.includes( '.' ) ) invokeWiki = 'https://' + invoke.split('.')[1] + '.fandom.com/' + invoke.substring(1).split('.')[0] + '/';
-						else invokeWiki = 'https://' + invoke.substring(1) + '.fandom.com/';
-						cmdmap.LINK(lang, msg, args.join(' '), invokeWiki, ' ' + invoke + ' ');
-					}
-					else if ( /^\?\?(?:[a-z-]{1,8}\.)?[a-z\d-]{1,50}$/.test(invoke) ) {
-						var invokeWiki = wiki;
-						if ( invoke.includes( '.' ) ) invokeWiki = 'https://' + invoke.split('.')[1] + '.wikia.org/' + invoke.substring(2).split('.')[0] + '/';
-						else invokeWiki = 'https://' + invoke.substring(2) + '.wikia.org/';
-						cmdmap.LINK(lang, msg, args.join(' '), invokeWiki, ' ' + invoke + ' ');
-					}
-					else cmdmap.LINK(lang, msg, line.split(' ').slice(1).join(' '), wiki);
-				}
-			} else if ( line.hasPrefix(prefix) && count === maxcount ) {
-				count++;
-				console.log( '- Message contains too many commands!' );
-				msg.reactEmoji('⚠️');
-				msg.sendChannelError( lang.limit.replaceSave( '%s', '<@' + author.id + '>' ), {allowedMentions:{users:[author.id]}} );
+		cont = cont.substring(prefix.length);
+		var args = cont.split(' ').slice(1);
+		if ( cont.split(' ')[0].split('\n')[1] ) args.unshift( '', cont.split(' ')[0].split('\n')[1] );
+		console.log( ( channel.type === 'text' ? msg.guild.id : '@' + author.id ) + ': ' + prefix + cont );
+		return ownercmdmap[aliasInvoke](lang, msg, args, cont, wiki);
+	}
+	var count = 0;
+	var maxcount = ( channel.type === 'text' && msg.guild.id in patreons ? 15 : 10 );
+	cleanCont.replace( /\u200b/g, '' ).split('\n').forEach( line => {
+		if ( !line.hasPrefix(prefix) || count > maxcount ) return;
+		count++;
+		if ( count === maxcount ) {
+			console.log( '- Message contains too many commands!' );
+			msg.reactEmoji('⚠️');
+			msg.sendChannelError( lang.get('limit').replaceSave( '%s', '<@' + author.id + '>' ), {allowedMentions:{users:[author.id]}} );
+			return;
+		}
+		line = line.substring(prefix.length);
+		invoke = line.split(' ')[0].toLowerCase();
+		var args = line.split(' ').slice(1);
+		aliasInvoke = ( lang.get('aliases')[invoke] || invoke );
+		ownercmd = ( msg.isOwner() && aliasInvoke in ownercmdmap );
+		if ( channel.type === 'text' && pause[msg.guild.id] && !( ( msg.isAdmin() && aliasInvoke in pausecmdmap ) || ownercmd ) ) console.log( msg.guild.id + ': Paused' );
+		else console.log( ( channel.type === 'text' ? msg.guild.id : '@' + author.id ) + ': ' + prefix + line );
+		if ( ownercmd ) ownercmdmap[aliasInvoke](lang, msg, args, line, wiki);
+		else if ( channel.type !== 'text' || !pause[msg.guild.id] || ( msg.isAdmin() && aliasInvoke in pausecmdmap ) ) {
+			if ( aliasInvoke in cmdmap ) cmdmap[aliasInvoke](lang, msg, args, line, wiki);
+			else if ( /^![a-z\d-]{1,50}$/.test(invoke) ) {
+				cmdmap.LINK(lang, msg, args.join(' '), 'https://' + invoke.substring(1) + '.gamepedia.com/', invoke + ' ');
 			}
-		} );
-		
+			else if ( /^\?(?:[a-z-]{1,8}\.)?[a-z\d-]{1,50}$/.test(invoke) ) {
+				var invokeWiki = wiki;
+				if ( invoke.includes( '.' ) ) invokeWiki = 'https://' + invoke.split('.')[1] + '.fandom.com/' + invoke.substring(1).split('.')[0] + '/';
+				else invokeWiki = 'https://' + invoke.substring(1) + '.fandom.com/';
+				cmdmap.LINK(lang, msg, args.join(' '), invokeWiki, invoke + ' ');
+			}
+			else if ( /^\?\?(?:[a-z-]{1,8}\.)?[a-z\d-]{1,50}$/.test(invoke) ) {
+				var invokeWiki = wiki;
+				if ( invoke.includes( '.' ) ) invokeWiki = 'https://' + invoke.split('.')[1] + '.wikia.org/' + invoke.substring(2).split('.')[0] + '/';
+				else invokeWiki = 'https://' + invoke.substring(2) + '.wikia.org/';
+				cmdmap.LINK(lang, msg, args.join(' '), invokeWiki, invoke + ' ');
+			}
+			else cmdmap.LINK(lang, msg, line, wiki);
+		}
+	} );
+	
 		if ( ( channel.type !== 'text' || !pause[msg.guild.id] ) && !noInline && ( cont.includes( '[[' ) || cont.includes( '{{' ) ) ) {
 			var links = [];
 			var embeds = [];
@@ -200,10 +202,10 @@ function newMessage(msg, lang, wiki = defaultSettings.wiki, prefix = process.env
 				}
 				if ( embeds.length ) {
 					if ( wiki.isFandom() ) embeds.forEach( embed => msg.reactEmoji('⏳').then( reaction => {
-						check_wiki.fandom(lang, msg, embed.title, wiki, ' ', reaction, embed.spoiler, '', embed.section);
+						check_wiki.fandom(lang, msg, embed.title, wiki, '', reaction, embed.spoiler, '', embed.section);
 					} ) );
 					else embeds.forEach( embed => msg.reactEmoji('⏳').then( reaction => {
-						check_wiki.gamepedia(lang, msg, embed.title, wiki, ' ', reaction, embed.spoiler, '', embed.section);
+						check_wiki.gamepedia(lang, msg, embed.title, wiki, '', reaction, embed.spoiler, '', embed.section);
 					} ) );
 				}
 			}, error => {
@@ -215,7 +217,6 @@ function newMessage(msg, lang, wiki = defaultSettings.wiki, prefix = process.env
 					console.log( '- Error while following the links: ' + error );
 				}
 			} );
-		}
 	}
 }