Browse Source

Use system messages for user groups

Markus-Rost 4 years ago
parent
commit
83c14b9cd9

+ 1 - 1
RcGcDb

@@ -1 +1 @@
-Subproject commit 8d9c3c01d9fef60c41470ec0d856a945e78d7711
+Subproject commit e1b8327b8960c54f27a58ab329ec8932f7daabc1

+ 2 - 2
cmds/verification.js

@@ -182,9 +182,9 @@ function cmd_verification(lang, msg, args, line, wiki) {
 						if ( wiki.noWiki(response.url) || response.statusCode === 410 ) console.log( '- This wiki doesn\'t exist!' );
 						if ( wiki.noWiki(response.url) || response.statusCode === 410 ) console.log( '- This wiki doesn\'t exist!' );
 						else console.log( '- ' + response.statusCode + ': Error while getting the usergroups: ' + ( body && body.error && body.error.info ) );
 						else console.log( '- ' + response.statusCode + ': Error while getting the usergroups: ' + ( body && body.error && body.error.info ) );
 					}
 					}
-					var groups = body.query.allmessages.filter( group => !['group-all','group-membership-link-with-expiry'].includes( group.name ) && !/\.(?:css|js)$/.test(group.name) ).map( group => {
+					var groups = body.query.allmessages.filter( group => !['group-all','group-membership-link-with-expiry'].includes( group.normalizedname ) && !/\.(?:css|js)$/.test(group.normalizedname) ).map( group => {
 						return {
 						return {
-							name: group.name.replace( /^group-/, '' ).replace( /-member$/, '' ),
+							name: group.normalizedname.replace( /^group-/, '' ).replace( /-member$/, '' ),
 							content: group['*'].replace( / /g, '_' ).toLowerCase()
 							content: group['*'].replace( / /g, '_' ).toLowerCase()
 						};
 						};
 					} );
 					} );

+ 4 - 16
cmds/verify.js

@@ -44,7 +44,7 @@ function cmd_verify(lang, msg, args, line, wiki, old_username = '') {
 			if ( args[0] === 'verification' ) args[0] = ( lang.localNames.verify || 'verify' );
 			if ( args[0] === 'verification' ) args[0] = ( lang.localNames.verify || 'verify' );
 			return this.help(lang, msg, args, line, wiki);
 			return this.help(lang, msg, args, line, wiki);
 		}
 		}
-		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' ).then( response => {
+		msg.reactEmoji('⏳').then( reaction => got.get( wiki + 'api.php?action=query&meta=siteinfo&siprop=general&list=users&usprop=blockinfo|groups|editcount|registration&ususers=' + encodeURIComponent( username ) + '&format=json' ).then( response => {
 			var body = response.body;
 			var body = response.body;
 			if ( body && body.warnings ) log_warn(body.warnings);
 			if ( body && body.warnings ) log_warn(body.warnings);
 			if ( response.statusCode !== 200 || !body || !body.query || !body.query.users ) {
 			if ( response.statusCode !== 200 || !body || !body.query || !body.query.users ) {
@@ -106,7 +106,7 @@ function cmd_verify(lang, msg, args, line, wiki, old_username = '') {
 			var comment = [];
 			var comment = [];
 			var url = '';
 			var url = '';
 			if ( wiki.isGamepedia() ) {
 			if ( wiki.isGamepedia() ) {
-				url = 'https://wikisandbox.gamepedia.com/Special:GlobalBlockList/' + encodeURIComponent( username ) + '?uselang=qqx&cache=' + Date.now();
+				url = 'https://commons.gamepedia.com/Special:GlobalBlockList/' + encodeURIComponent( username ) + '?uselang=qqx&cache=' + Date.now();
 			}
 			}
 			else if ( wiki.isFandom() ) {
 			else if ( wiki.isFandom() ) {
 				url = 'https://community.fandom.com/Special:Contributions/' + encodeURIComponent( username ) + '?limit=1&cache=' + Date.now();
 				url = 'https://community.fandom.com/Special:Contributions/' + encodeURIComponent( username ) + '?limit=1&cache=' + Date.now();
@@ -211,13 +211,7 @@ function cmd_verify(lang, msg, args, line, wiki, old_username = '') {
 							row.usergroup = row.usergroup.replace( 'AND|', '' );
 							row.usergroup = row.usergroup.replace( 'AND|', '' );
 							and_or = 'every';
 							and_or = 'every';
 						}
 						}
-						if ( queryuser.editcount >= row.editcount && row.usergroup.split('|')[and_or]( usergroup => {
-							if ( !queryuser.groupmemberships ) return queryuser.groups.includes( usergroup );
-							if ( !queryuser.groups.includes( 'global_' + usergroup ) || queryuser.groupmemberships.some( member => member.group === usergroup ) ) {
-								return queryuser.groups.includes( usergroup );
-							}
-							return false;
-						} ) && accountage >= row.accountage && row.role.split('|').some( role => !roles.includes( role ) ) ) {
+						if ( queryuser.editcount >= row.editcount && row.usergroup.split('|')[and_or]( usergroup => queryuser.groups.includes( usergroup ) ) && accountage >= row.accountage && row.role.split('|').some( role => !roles.includes( role ) ) ) {
 							verified = true;
 							verified = true;
 							if ( row.rename ) rename = true;
 							if ( row.rename ) rename = true;
 							row.role.split('|').forEach( role => {
 							row.role.split('|').forEach( role => {
@@ -319,13 +313,7 @@ function cmd_verify(lang, msg, args, line, wiki, old_username = '') {
 						row.usergroup = row.usergroup.replace( 'AND|', '' );
 						row.usergroup = row.usergroup.replace( 'AND|', '' );
 						and_or = 'every';
 						and_or = 'every';
 					}
 					}
-					if ( queryuser.editcount >= row.editcount && row.usergroup.split('|')[and_or]( usergroup => {
-						if ( !queryuser.groupmemberships ) return queryuser.groups.includes( usergroup );
-						if ( !queryuser.groups.includes( 'global_' + usergroup ) || queryuser.groupmemberships.some( member => member.group === usergroup ) ) {
-							return queryuser.groups.includes( usergroup );
-						}
-						return false;
-					} ) && accountage >= row.accountage && row.role.split('|').some( role => !roles.includes( role ) ) ) {
+					if ( queryuser.editcount >= row.editcount && row.usergroup.split('|')[and_or]( usergroup => queryuser.groups.includes( usergroup ) ) && accountage >= row.accountage && row.role.split('|').some( role => !roles.includes( role ) ) ) {
 						verified = true;
 						verified = true;
 						if ( row.rename ) rename = true;
 						if ( row.rename ) rename = true;
 						row.role.split('|').forEach( role => {
 						row.role.split('|').forEach( role => {

+ 12 - 5
cmds/wiki/fandom/user.js

@@ -243,12 +243,19 @@ function fandom_user(lang, msg, namespace, username, wiki, querystring, fragment
 					var editcount = [lang.get('user.info.editcount'), queryuser.editcount];
 					var editcount = [lang.get('user.info.editcount'), queryuser.editcount];
 					var groups = queryuser.groups;
 					var groups = queryuser.groups;
 					var group = [lang.get('user.info.group')];
 					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], queryuser.gender) + '**');
+					for ( var i = 0; i < usergroups.sorted.length; i++ ) {
+						let usergroup = usergroups.sorted[i];
+						if ( usergroup === '__CUSTOM__' ) {
+							let customgroups = groups.filter( customgroup => {
+								return ( !usergroups.sorted.includes( customgroup ) && !usergroups.ignored.includes( customgroup ) );
+							} );
+							group.push(...customgroups);
+						}
+						else if ( groups.includes( usergroup ) && ( group.length === 1 || !['autoconfirmed', 'user'].includes( usergroup ) ) ) {
+							if ( usergroup === 'wiki-manager' && body.query.allmessages[0]['*'] === username ) {
+								group.push('**' + lang.get('user.groups.' + usergroup, queryuser.gender) + '**');
 							}
 							}
-							else group.push(lang.get('user.groups.' + usergroups[i], queryuser.gender));
+							else group.push(lang.get('user.groups.' + usergroup, queryuser.gender));
 						}
 						}
 					}
 					}
 					var isBlocked = false;
 					var isBlocked = false;

+ 413 - 384
cmds/wiki/gamepedia/user.js

@@ -26,422 +26,451 @@ getAllSites.then( sites => allSites = sites );
  */
  */
 function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragment, querypage, contribs, reaction, spoiler) {
 function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragment, querypage, contribs, reaction, spoiler) {
 	if ( !allSites.length ) getAllSites.update();
 	if ( !allSites.length ) getAllSites.update();
-	if ( /^(?:(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{2})?|(?:[\dA-F]{1,4}:){7}[\dA-F]{1,4}(?:\/\d{2,3})?)$/.test(username) ) {
-		got.get( wiki + 'api.php?action=query&meta=siteinfo&siprop=general&list=blocks&bkprop=user|by|timestamp|expiry|reason&bkip=' + encodeURIComponent( username ) + '&format=json' ).then( response => {
-			var body = response.body;
-			if ( body && body.warnings ) log_warn(body.warnings);
-			if ( response.statusCode !== 200 || !body || body.batchcomplete === undefined || !body.query || !body.query.blocks || fragment ) {
-				if ( body && body.error && ( body.error.code === 'param_ip' || body.error.code === 'cidrtoobroad' ) || fragment ) {
-					if ( querypage.missing !== undefined || querypage.ns === -1 ) msg.reactEmoji('error');
-					else {
-						var pagelink = wiki.toLink(querypage.title, querystring, fragment);
-						var embed = new MessageEmbed().setTitle( querypage.title.escapeFormatting() ).setURL( pagelink );
-						if ( body?.query?.general ) {
-							wiki.updateWiki(body.query.general);
-							embed.setAuthor( body.query.general.sitename );
-							embed.setThumbnail( new URL(body.query.general.logo, wiki).href );
-						}
-						if ( querypage.pageprops && querypage.pageprops.displaytitle ) {
-							var displaytitle = htmlToDiscord( querypage.pageprops.displaytitle );
-							if ( displaytitle.length > 250 ) displaytitle = displaytitle.substring(0, 250) + '\u2026';
-							embed.setTitle( displaytitle );
-						}
-						if ( querypage.extract ) {
-							var extract = extract_desc(querypage.extract, fragment);
-							embed.setDescription( extract[0] );
-							if ( extract[2].length ) embed.addField( extract[1], extract[2] );
-						}
-						if ( querypage.pageprops && querypage.pageprops.description ) {
-							var description = htmlToPlain( querypage.pageprops.description );
-							if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
-							embed.setDescription( description );
-						}
-						if ( querypage.pageimage && querypage.original ) {
-							embed.setThumbnail( querypage.original.source );
-						}
-						else if ( querypage.pageprops && querypage.pageprops.page_image_free ) {
-							embed.setThumbnail( wiki.toLink('Special:FilePath/' + querypage.pageprops.page_image_free, {version:Date.now()}) );
-						}
-						
-						msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler, {embed} ).then( message => parse_page(message, querypage.title, embed, wiki, '') );
-					}
-				}
+	if ( /^(?:(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{2})?|(?:[\dA-F]{1,4}:){7}[\dA-F]{1,4}(?:\/\d{2,3})?)$/.test(username) ) return got.get( wiki + 'api.php?action=query&meta=siteinfo&siprop=general&list=blocks&bkprop=user|by|timestamp|expiry|reason&bkip=' + encodeURIComponent( username ) + '&format=json' ).then( response => {
+		var body = response.body;
+		if ( body && body.warnings ) log_warn(body.warnings);
+		if ( response.statusCode !== 200 || !body || body.batchcomplete === undefined || !body.query || !body.query.blocks || fragment ) {
+			if ( body && body.error && ( body.error.code === 'param_ip' || body.error.code === 'cidrtoobroad' ) || fragment ) {
+				if ( querypage.missing !== undefined || querypage.ns === -1 ) msg.reactEmoji('error');
 				else {
 				else {
-					console.log( '- ' + response.statusCode + ': Error while getting the search results: ' + ( body && body.error && body.error.info ) );
-					msg.sendChannelError( spoiler + '<' + wiki.toLink(( querypage.noRedirect ? namespace : contribs ) + username, querystring, fragment) + '>' + spoiler );
-				}
-				
-				if ( reaction ) reaction.removeEmoji();
-			}
-			else {
-				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.get('dateformat'), timeoptions);
-					var blockexpiry = block.expiry;
-					if ( ['infinity', 'infinite'].includes(blockexpiry) ) {
-						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.get('dateformat'), timeoptions);
+					var pagelink = wiki.toLink(querypage.title, querystring, fragment);
+					var embed = new MessageEmbed().setTitle( querypage.title.escapeFormatting() ).setURL( pagelink );
+					if ( body?.query?.general ) {
+						wiki.updateWiki(body.query.general);
+						embed.setAuthor( body.query.general.sitename );
+						embed.setThumbnail( new URL(body.query.general.logo, wiki).href );
 					}
 					}
-					if ( isBlocked ) return {
-						header: lang.get('user.block.header', block.user, 'unknown').escapeFormatting(),
-						text: lang.get('user.block.' + ( block.reason ? 'text' : 'noreason' ), blockedtimestamp, blockexpiry),
-						by: block.by,
-						reason: block.reason
-					};
-				} ).filter( block => block !== undefined );
-				if ( username.includes( '/' ) ) {
-					var rangeprefix = username;
-					if ( username.includes( ':' ) ) {
-						var range = parseInt(username.replace( /^.+\/(\d{2,3})$/, '$1' ), 10);
-						if ( range === 128 ) username = username.replace( /^(.+)\/\d{2,3}$/, '$1' );
-						else if ( range >= 112 ) rangeprefix = username.replace( /^((?:[\dA-F]{1,4}:){7}).+$/, '$1' );
-						else if ( range >= 96 ) rangeprefix = username.replace( /^((?:[\dA-F]{1,4}:){6}).+$/, '$1' );
-						else if ( range >= 80 ) rangeprefix = username.replace( /^((?:[\dA-F]{1,4}:){5}).+$/, '$1' );
-						else if ( range >= 64 ) rangeprefix = username.replace( /^((?:[\dA-F]{1,4}:){4}).+$/, '$1' );
-						else if ( range >= 48 ) rangeprefix = username.replace( /^((?:[\dA-F]{1,4}:){3}).+$/, '$1' );
-						else if ( range >= 32 ) rangeprefix = username.replace( /^((?:[\dA-F]{1,4}:){2}).+$/, '$1' );
-						else if ( range >= 19 ) rangeprefix = username.replace( /^((?:[\dA-F]{1,4}:){1}).+$/, '$1' );
+					if ( querypage.pageprops && querypage.pageprops.displaytitle ) {
+						var displaytitle = htmlToDiscord( querypage.pageprops.displaytitle );
+						if ( displaytitle.length > 250 ) displaytitle = displaytitle.substring(0, 250) + '\u2026';
+						embed.setTitle( displaytitle );
 					}
 					}
-					else {
-						var range = parseInt(username.substring(username.length - 2), 10);
-						if ( range === 32 ) username = username.replace( /^(.+)\/\d{2}$/, '$1' );
-						else if ( range >= 24 ) rangeprefix = username.replace( /^((?:\d{1,3}\.){3}).+$/, '$1' );
-						else if ( range >= 16 ) rangeprefix = username.replace( /^((?:\d{1,3}\.){2}).+$/, '$1' );
+					if ( querypage.extract ) {
+						var extract = extract_desc(querypage.extract, fragment);
+						embed.setDescription( extract[0] );
+						if ( extract[2].length ) embed.addField( extract[1], extract[2] );
 					}
 					}
-				}
-				got.get( wiki.updateWiki(body.query.general) + 'api.php?action=query&list=usercontribs&ucprop=&uclimit=50' + ( username.includes( '/' ) ? '&ucuserprefix=' + encodeURIComponent( rangeprefix ) : '&ucuser=' + encodeURIComponent( username ) ) + '&format=json' ).then( ucresponse => {
-					var ucbody = ucresponse.body;
-					if ( rangeprefix && !username.includes( '/' ) ) username = rangeprefix;
-					if ( ucbody && ucbody.warnings ) log_warn(ucbody.warnings);
-					if ( ucresponse.statusCode !== 200 || !ucbody || ucbody.batchcomplete === undefined || !ucbody.query || !ucbody.query.usercontribs ) {
-						if ( ucbody && ucbody.error && ucbody.error.code === 'baduser_ucuser' ) {
-							msg.reactEmoji('error');
-						}
-						else {
-							console.log( '- ' + ucresponse.statusCode + ': Error while getting the search results: ' + ( ucbody && ucbody.error && ucbody.error.info ) );
-							msg.sendChannelError( spoiler + '<' + wiki.toLink(namespace + username, querystring, fragment) + '>' + spoiler );
-						}
+					if ( querypage.pageprops && querypage.pageprops.description ) {
+						var description = htmlToPlain( querypage.pageprops.description );
+						if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
+						embed.setDescription( description );
 					}
 					}
-					else {
-						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, fragment);
-						if ( msg.showEmbed() ) {
-							var text = '<' + pagelink + '>';
-							var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( username ).setURL( pagelink ).addField( editcount[0], '[' + editcount[1] + '](' + wiki.toLink(contribs + username, '', '', true) + ')' );
-							if ( querypage.pageprops && querypage.pageprops.description ) {
-								var description = htmlToPlain( querypage.pageprops.description );
-								if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
-								embed.setDescription( description );
-							}
-							else if ( querypage.extract ) {
-								var extract = extract_desc(querypage.extract);
-								embed.setDescription( extract[0] );
-							}
-							if ( blocks.length ) blocks.forEach( block => {
-								block.text = block.text.replaceSave( /\$3/g, '[' + block.by.escapeFormatting() + '](' + wiki.toLink('User:' + block.by, '', '', true) + ')' );
-								if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toMarkdown(block.reason, wiki) );
-								embed.addField( block.header, block.text );
-							} );
-						}
-						else {
-							var embed = {};
-							var text = '<' + pagelink + '>\n\n' + editcount.join(' ');
-							if ( blocks.length ) blocks.forEach( block => {
-								block.text = block.text.replaceSave( /\$3/g, block.by.escapeFormatting() );
-								if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toPlaintext(block.reason) );
-								text += '\n\n**' + block.header + '**\n' + block.text;
-							} );
-						}
-						
-						if ( msg.channel.isGuild() && msg.guild.id in patreons && ( wiki.isFandom() || wiki.isGamepedia() ) ) {
-							if ( msg.showEmbed() ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
-							else 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) );
-						}
-						else msg.sendChannel( spoiler + text + spoiler, {embed} );
+					if ( querypage.pageimage && querypage.original ) {
+						embed.setThumbnail( querypage.original.source );
 					}
 					}
-				}, error => {
-					if ( rangeprefix && !username.includes( '/' ) ) username = rangeprefix;
-					console.log( '- Error while getting the search results: ' + error );
+					else if ( querypage.pageprops && querypage.pageprops.page_image_free ) {
+						embed.setThumbnail( wiki.toLink('Special:FilePath/' + querypage.pageprops.page_image_free, {version:Date.now()}) );
+					}
+					
+					msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler, {embed} ).then( message => parse_page(message, querypage.title, embed, wiki, '') );
+				}
+			}
+			else {
+				console.log( '- ' + response.statusCode + ': Error while getting the search results: ' + ( body && body.error && body.error.info ) );
+				msg.sendChannelError( spoiler + '<' + wiki.toLink(( querypage.noRedirect ? namespace : contribs ) + username, querystring, fragment) + '>' + spoiler );
+			}
+			
+			if ( reaction ) reaction.removeEmoji();
+			return;
+		}
+		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.get('dateformat'), timeoptions);
+			var blockexpiry = block.expiry;
+			if ( ['infinity', 'infinite'].includes(blockexpiry) ) {
+				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.get('dateformat'), timeoptions);
+			}
+			if ( isBlocked ) return {
+				header: lang.get('user.block.header', block.user, 'unknown').escapeFormatting(),
+				text: lang.get('user.block.' + ( block.reason ? 'text' : 'noreason' ), blockedtimestamp, blockexpiry),
+				by: block.by,
+				reason: block.reason
+			};
+		} ).filter( block => block !== undefined );
+		if ( username.includes( '/' ) ) {
+			var rangeprefix = username;
+			if ( username.includes( ':' ) ) {
+				var range = parseInt(username.replace( /^.+\/(\d{2,3})$/, '$1' ), 10);
+				if ( range === 128 ) username = username.replace( /^(.+)\/\d{2,3}$/, '$1' );
+				else if ( range >= 112 ) rangeprefix = username.replace( /^((?:[\dA-F]{1,4}:){7}).+$/, '$1' );
+				else if ( range >= 96 ) rangeprefix = username.replace( /^((?:[\dA-F]{1,4}:){6}).+$/, '$1' );
+				else if ( range >= 80 ) rangeprefix = username.replace( /^((?:[\dA-F]{1,4}:){5}).+$/, '$1' );
+				else if ( range >= 64 ) rangeprefix = username.replace( /^((?:[\dA-F]{1,4}:){4}).+$/, '$1' );
+				else if ( range >= 48 ) rangeprefix = username.replace( /^((?:[\dA-F]{1,4}:){3}).+$/, '$1' );
+				else if ( range >= 32 ) rangeprefix = username.replace( /^((?:[\dA-F]{1,4}:){2}).+$/, '$1' );
+				else if ( range >= 19 ) rangeprefix = username.replace( /^((?:[\dA-F]{1,4}:){1}).+$/, '$1' );
+			}
+			else {
+				var range = parseInt(username.substring(username.length - 2), 10);
+				if ( range === 32 ) username = username.replace( /^(.+)\/\d{2}$/, '$1' );
+				else if ( range >= 24 ) rangeprefix = username.replace( /^((?:\d{1,3}\.){3}).+$/, '$1' );
+				else if ( range >= 16 ) rangeprefix = username.replace( /^((?:\d{1,3}\.){2}).+$/, '$1' );
+			}
+		}
+		got.get( wiki.updateWiki(body.query.general) + 'api.php?action=query&list=usercontribs&ucprop=&uclimit=50' + ( username.includes( '/' ) ? '&ucuserprefix=' + encodeURIComponent( rangeprefix ) : '&ucuser=' + encodeURIComponent( username ) ) + '&format=json' ).then( ucresponse => {
+			var ucbody = ucresponse.body;
+			if ( rangeprefix && !username.includes( '/' ) ) username = rangeprefix;
+			if ( ucbody && ucbody.warnings ) log_warn(ucbody.warnings);
+			if ( ucresponse.statusCode !== 200 || !ucbody || ucbody.batchcomplete === undefined || !ucbody.query || !ucbody.query.usercontribs ) {
+				if ( ucbody && ucbody.error && ucbody.error.code === 'baduser_ucuser' ) {
+					msg.reactEmoji('error');
+				}
+				else {
+					console.log( '- ' + ucresponse.statusCode + ': Error while getting the search results: ' + ( ucbody && ucbody.error && ucbody.error.info ) );
 					msg.sendChannelError( spoiler + '<' + wiki.toLink(namespace + username, querystring, fragment) + '>' + spoiler );
 					msg.sendChannelError( spoiler + '<' + wiki.toLink(namespace + username, querystring, fragment) + '>' + spoiler );
-				} ).finally( () => {
-					if ( reaction ) reaction.removeEmoji();
+				}
+				return;
+			}
+			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, fragment);
+			if ( msg.showEmbed() ) {
+				var text = '<' + pagelink + '>';
+				var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( username ).setURL( pagelink ).addField( editcount[0], '[' + editcount[1] + '](' + wiki.toLink(contribs + username, '', '', true) + ')' );
+				if ( querypage.pageprops && querypage.pageprops.description ) {
+					var description = htmlToPlain( querypage.pageprops.description );
+					if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
+					embed.setDescription( description );
+				}
+				else if ( querypage.extract ) {
+					var extract = extract_desc(querypage.extract);
+					embed.setDescription( extract[0] );
+				}
+				if ( blocks.length ) blocks.forEach( block => {
+					block.text = block.text.replaceSave( /\$3/g, '[' + block.by.escapeFormatting() + '](' + wiki.toLink('User:' + block.by, '', '', true) + ')' );
+					if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toMarkdown(block.reason, wiki) );
+					embed.addField( block.header, block.text );
+				} );
+			}
+			else {
+				var embed = {};
+				var text = '<' + pagelink + '>\n\n' + editcount.join(' ');
+				if ( blocks.length ) blocks.forEach( block => {
+					block.text = block.text.replaceSave( /\$3/g, block.by.escapeFormatting() );
+					if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toPlaintext(block.reason) );
+					text += '\n\n**' + block.header + '**\n' + block.text;
 				} );
 				} );
 			}
 			}
+			
+			if ( msg.channel.isGuild() && msg.guild.id in patreons && ( wiki.isFandom() || wiki.isGamepedia() ) ) {
+				if ( msg.showEmbed() ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
+				else 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) );
+			}
+			else msg.sendChannel( spoiler + text + spoiler, {embed} );
 		}, error => {
 		}, error => {
+			if ( rangeprefix && !username.includes( '/' ) ) username = rangeprefix;
 			console.log( '- Error while getting the search results: ' + error );
 			console.log( '- Error while getting the search results: ' + error );
-			msg.sendChannelError( spoiler + '<' + wiki.toLink(( querypage.noRedirect ? namespace : contribs ) + username, querystring, fragment) + '>' + spoiler );
-			
+			msg.sendChannelError( spoiler + '<' + wiki.toLink(namespace + username, querystring, fragment) + '>' + spoiler );
+		} ).finally( () => {
 			if ( reaction ) reaction.removeEmoji();
 			if ( reaction ) reaction.removeEmoji();
 		} );
 		} );
-	} else {
-		got.get( wiki + 'api.php?action=query&meta=allmessages|siteinfo&ammessages=custom-Wiki_Manager&amenableparser=true&siprop=general&list=users&usprop=blockinfo|groups|groupmemberships|editcount|registration|gender&ususers=' + encodeURIComponent( username ) + '&format=json' ).then( response => {
-			var body = response.body;
-			if ( body && body.warnings ) log_warn(body.warnings);
-			if ( response.statusCode !== 200 || !body || body.batchcomplete === undefined || !body.query || !body.query.users || !body.query.users[0] ) {
-				console.log( '- ' + response.statusCode + ': Error while getting the search results: ' + ( body && body.error && body.error.info ) );
-				msg.sendChannelError( spoiler + '<' + wiki.toLink(namespace + username, querystring, fragment) + '>' + spoiler );
+	}, error => {
+		console.log( '- Error while getting the search results: ' + error );
+		msg.sendChannelError( spoiler + '<' + wiki.toLink(( querypage.noRedirect ? namespace : contribs ) + username, querystring, fragment) + '>' + spoiler );
+		
+		if ( reaction ) reaction.removeEmoji();
+	} );
+
+	got.get( wiki + 'api.php?action=query&meta=allmessages|siteinfo&ammessages=custom-Wiki_Manager&amenableparser=true&siprop=general&prop=revisions&rvprop=content|user&rvslots=main&titles=User:' + encodeURIComponent( username ) + '/Discord&list=users&usprop=blockinfo|groups|editcount|registration|gender&ususers=' + encodeURIComponent( username ) + '&format=json' ).then( response => {
+		var body = response.body;
+		if ( body && body.warnings ) log_warn(body.warnings);
+		if ( response.statusCode !== 200 || !body || body.batchcomplete === undefined || !body.query || !body.query.users || !body.query.users[0] ) {
+			console.log( '- ' + response.statusCode + ': Error while getting the search results: ' + ( body && body.error && body.error.info ) );
+			msg.sendChannelError( spoiler + '<' + wiki.toLink(namespace + username, querystring, fragment) + '>' + spoiler );
+			
+			if ( reaction ) reaction.removeEmoji();
+		}
+		wiki.updateWiki(body.query.general);
+		var queryuser = body.query.users[0];
+		if ( queryuser.missing !== undefined || queryuser.invalid !== undefined || fragment ) {
+			if ( querypage.missing !== undefined || querypage.ns === -1 ) msg.reactEmoji('🤷');
+			else {
+				var pagelink = wiki.toLink(querypage.title, querystring, fragment);
+				var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( querypage.title.escapeFormatting() ).setURL( pagelink );
+				if ( querypage.pageprops && querypage.pageprops.displaytitle ) {
+					var displaytitle = htmlToDiscord( querypage.pageprops.displaytitle );
+					if ( displaytitle.length > 250 ) displaytitle = displaytitle.substring(0, 250) + '\u2026';
+					embed.setTitle( displaytitle );
+				}
+				if ( querypage.extract ) {
+					var extract = extract_desc(querypage.extract, fragment);
+					embed.setDescription( extract[0] );
+					if ( extract[2].length ) embed.addField( extract[1], extract[2] );
+				}
+				if ( querypage.pageprops && querypage.pageprops.description ) {
+					var description = htmlToPlain( querypage.pageprops.description );
+					if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
+					embed.setDescription( description );
+				}
+				if ( querypage.pageimage && querypage.original ) {
+					embed.setThumbnail( querypage.original.source );
+				}
+				else if ( querypage.pageprops && querypage.pageprops.page_image_free ) {
+					embed.setThumbnail( wiki.toLink('Special:FilePath/' + querypage.pageprops.page_image_free, {version:Date.now()}) );
+				}
+				else embed.setThumbnail( new URL(body.query.general.logo, wiki).href );
 				
 				
-				if ( reaction ) reaction.removeEmoji();
+				msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler, {embed} ).then( message => parse_page(message, querypage.title, embed, wiki, new URL(body.query.general.logo, wiki).href) );
 			}
 			}
-			else {
-				wiki.updateWiki(body.query.general);
-				var queryuser = body.query.users[0];
-				if ( queryuser.missing !== undefined || queryuser.invalid !== undefined || fragment ) {
-					if ( querypage.missing !== undefined || querypage.ns === -1 ) msg.reactEmoji('🤷');
+			
+			if ( reaction ) reaction.removeEmoji();
+			return;
+		}
+		username = queryuser.name;
+		var gender = [lang.get('user.info.gender')];
+		switch (queryuser.gender) {
+			case 'male':
+				gender.push(lang.get('user.gender.male'));
+				break;
+			case 'female':
+				gender.push(lang.get('user.gender.female'));
+				break;
+			case 'unknown':
+			default: 
+				gender.push(lang.get('user.gender.unknown'));
+		}
+		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.filter( group => !usergroups.ignored.includes( group ) );
+		var groupnames = groups;
+		got.get( wiki + 'api.php?action=query&meta=allmessages&amenableparser=true&amincludelocal=true&amargs=' + encodeURIComponent( username ) + '&amlang=' + lang.lang + '&ammessages=' + groups.map( group => `group-${group}|group-${group}-member` ).join('|') + '&format=json' ).then( gresponse => {
+			var gbody = gresponse.body;
+			if ( gbody && gbody.warnings ) log_warn(gbody.warnings);
+			if ( gresponse.statusCode !== 200 || !gbody || gbody.batchcomplete === undefined || !gbody?.query?.allmessages?.length ) {
+				console.log( '- ' + gresponse.statusCode + ': Error while getting the group names: ' + gbody?.error?.info );
+				return;
+			}
+			groupnames = groups.map( group => {
+				return ( gbody.query.allmessages.find( message => message.normalizedname === `group-${group}-member` )['*'] || gbody.query.allmessages.find( message => message.normalizedname === `group-${group}` )['*'] || group );
+			} );
+		}, error => {
+			console.log( '- Error while getting the group names: ' + error );
+		} ).finally( () => {
+			var group = [lang.get('user.info.group')];
+			for ( var i = 0; i < usergroups.sorted.length; i++ ) {
+				let usergroup = usergroups.sorted[i];
+				if ( usergroup === '__CUSTOM__' ) {
+					group.push(...groups.filter( customgroup => {
+						return !usergroups.sorted.includes( customgroup );
+					} ).map( customgroup => {
+						return groupnames[groups.indexOf(customgroup)];
+					} ));
+				}
+				else if ( groups.includes( usergroup ) && ( group.length === 1 || !['autoconfirmed', 'user'].includes( usergroup ) ) ) {
+					let thisSite = allSites.find( site => site.wiki_domain === wiki.hostname );
+					if ( usergroup === 'wiki_manager' && thisSite && thisSite.wiki_managers.includes( username ) ) {
+						group.push('**' + groupnames[groups.indexOf(usergroup)] + '**');
+					}
+					else if ( usergroup === 'wiki-manager' && ( body.query.allmessages[0]['*'] === username || thisSite && thisSite.wiki_managers.includes( username ) ) ) {
+						group.push('**' + groupnames[groups.indexOf(usergroup)] + '**');
+					}
 					else {
 					else {
-						var pagelink = wiki.toLink(querypage.title, querystring, fragment);
-						var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( querypage.title.escapeFormatting() ).setURL( pagelink );
-						if ( querypage.pageprops && querypage.pageprops.displaytitle ) {
-							var displaytitle = htmlToDiscord( querypage.pageprops.displaytitle );
-							if ( displaytitle.length > 250 ) displaytitle = displaytitle.substring(0, 250) + '\u2026';
-							embed.setTitle( displaytitle );
-						}
-						if ( querypage.extract ) {
-							var extract = extract_desc(querypage.extract, fragment);
-							embed.setDescription( extract[0] );
-							if ( extract[2].length ) embed.addField( extract[1], extract[2] );
-						}
-						if ( querypage.pageprops && querypage.pageprops.description ) {
-							var description = htmlToPlain( querypage.pageprops.description );
-							if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
-							embed.setDescription( description );
-						}
-						if ( querypage.pageimage && querypage.original ) {
-							embed.setThumbnail( querypage.original.source );
-						}
-						else if ( querypage.pageprops && querypage.pageprops.page_image_free ) {
-							embed.setThumbnail( wiki.toLink('Special:FilePath/' + querypage.pageprops.page_image_free, {version:Date.now()}) );
-						}
-						else embed.setThumbnail( new URL(body.query.general.logo, wiki).href );
-						
-						msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler, {embed} ).then( message => parse_page(message, querypage.title, embed, wiki, new URL(body.query.general.logo, wiki).href) );
+						group.push(groupnames[groups.indexOf(usergroup)]);
 					}
 					}
+				}
+			}
+			var isBlocked = false;
+			var blockedtimestamp = new Date(queryuser.blockedtimestamp).toLocaleString(lang.get('dateformat'), timeoptions);
+			var blockexpiry = queryuser.blockexpiry;
+			if ( ['infinity', 'infinite'].includes(blockexpiry) ) {
+				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.get('dateformat'), timeoptions);
+				if ( Date.parse(blockexpirydate) > Date.now() ) isBlocked = true;
+			}
+			var blockedby = queryuser.blockedby;
+			var blockreason = queryuser.blockreason;
+			var block = {
+				header: lang.get('user.block.header', username, queryuser.gender).escapeFormatting(),
+				text: lang.get('user.block.' + ( blockreason ? 'text' : 'noreason' ), blockedtimestamp, blockexpiry),
+				by: blockedby,
+				reason: blockreason
+			};
+			
+			var pagelink = wiki.toLink(namespace + username, querystring, fragment);
+			if ( msg.showEmbed() ) {
+				var text = '<' + pagelink + '>';
+				var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( username.escapeFormatting() ).setURL( pagelink ).addField( editcount[0], '[' + editcount[1] + '](' + wiki.toLink(contribs + username, '', '', true) + ')', true ).addField( group[0], group.slice(1).join(',\n'), true ).addField( gender[0], gender[1], true ).addField( registration[0], registration[1], true );
+				
+				if ( querypage.pageprops && querypage.pageprops.description ) {
+					var description = htmlToPlain( querypage.pageprops.description );
+					if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
+					embed.setDescription( description );
+				}
+				else if ( querypage.extract ) {
+					var extract = extract_desc(querypage.extract);
+					embed.setDescription( extract[0] );
+				}
+			}
+			else {
+				var embed = {};
+				var text = '<' + pagelink + '>\n\n' + gender.join(' ') + '\n' + registration.join(' ') + '\n' + editcount.join(' ') + '\n' + group[0] + ' ' + group.slice(1).join(', ');
+			}
+			if ( wiki.isGamepedia() ) return got.get( wiki + 'api.php?action=profile&do=getPublicProfile&user_name=' + encodeURIComponent( username ) + '&format=json&cache=' + Date.now() ).then( presponse => {
+				var pbody = presponse.body;
+				if ( presponse.statusCode !== 200 || !pbody || pbody.error || pbody.errormsg || !pbody.profile ) {
+					console.log( '- ' + presponse.statusCode + ': Error while getting the user profile: ' + ( pbody && ( pbody.error && pbody.error.info || pbody.errormsg ) ) );
+					return;
+				}
+				if ( pbody.profile['link-discord'] ) {
+					if ( pbody.profile['link-discord'].length > 50 ) pbody.profile['link-discord'] = pbody.profile['link-discord'].substring(0, 50) + '\u2026';
+					if ( msg.channel.isGuild() ) 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.get('user.info.discord'),pbody.profile['link-discord'].escapeFormatting()];
+					if ( discordmember ) discordname[1] = discordmember.toString();
 					
 					
-					if ( reaction ) reaction.removeEmoji();
+					if ( msg.showEmbed() ) embed.addField( discordname[0], discordname[1], true );
+					else text += '\n' + discordname.join(' ');
 				}
 				}
-				else {
-					username = queryuser.name;
-					var gender = [lang.get('user.info.gender')];
-					switch (queryuser.gender) {
-						case 'male':
-							gender.push(lang.get('user.gender.male'));
-							break;
-						case 'female':
-							gender.push(lang.get('user.gender.female'));
-							break;
-						case 'unknown':
-						default: 
-							gender.push(lang.get('user.gender.unknown'));
+				if ( 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 + '/>';
 					}
 					}
-					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.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] ) ) ) {
-							let thisSite = allSites.find( site => site.wiki_domain === wiki.hostname );
-							if ( usergroups[i] === 'wiki_manager' && thisSite && thisSite.wiki_managers.includes( username ) ) {
-								group.push('**' + lang.get('user.groups.' + usergroups[i], queryuser.gender) + '**');
-							}
-							else if ( usergroups[i] === 'wiki-manager' && body.query.allmessages[0]['*'] === username ) {
-								group.push('**' + lang.get('user.groups.' + usergroups[i], queryuser.gender) + '**');
-							}
-							else if ( !groups.includes( 'global_' + usergroups[i] ) || queryuser.groupmemberships.some( member => member.group === usergroups[i] ) ) {
-								group.push(lang.get('user.groups.' + usergroups[i], queryuser.gender));
-							}
-						}
+				}
+			}, error => {
+				console.log( '- Error while getting the user profile: ' + error );
+			} ).finally( () => {
+				if ( msg.showEmbed() ) {
+					if ( isBlocked ) {
+						block.text = block.text.replaceSave( /\$3/g, '[' + block.by.escapeFormatting() + '](' + wiki.toLink('User:' + block.by, '', '', true) + ')' );
+						if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toMarkdown(block.reason, wiki) );
+						embed.addField( block.header, block.text );
 					}
 					}
-					var isBlocked = false;
-					var blockedtimestamp = new Date(queryuser.blockedtimestamp).toLocaleString(lang.get('dateformat'), timeoptions);
-					var blockexpiry = queryuser.blockexpiry;
-					if ( ['infinity', 'infinite'].includes(blockexpiry) ) {
-						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.get('dateformat'), timeoptions);
-						if ( Date.parse(blockexpirydate) > Date.now() ) isBlocked = true;
+				}
+				else {
+					if ( isBlocked ) {
+						block.text = block.text.replaceSave( /\$3/g, block.by.escapeFormatting() );
+						if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toPlaintext(block.reason) );
+						text += '\n\n**' + block.header + '**\n' + block.text;
 					}
 					}
-					var blockedby = queryuser.blockedby;
-					var blockreason = queryuser.blockreason;
-					var block = {
-						header: lang.get('user.block.header', username, queryuser.gender).escapeFormatting(),
-						text: lang.get('user.block.' + ( blockreason ? 'text' : 'noreason' ), blockedtimestamp, blockexpiry),
-						by: blockedby,
-						reason: blockreason
-					};
+				}
+				
+				if ( msg.channel.isGuild() && msg.guild.id in patreons ) {
+					if ( msg.showEmbed() ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
+					else text += '\n\n<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**';
 					
 					
-					var pagelink = wiki.toLink(namespace + username, querystring, fragment);
-					if ( msg.showEmbed() ) {
-						var text = '<' + pagelink + '>';
-						var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( username.escapeFormatting() ).setURL( pagelink ).addField( editcount[0], '[' + editcount[1] + '](' + wiki.toLink(contribs + username, '', '', true) + ')', true ).addField( group[0], group.slice(1).join(',\n'), true ).addField( gender[0], gender[1], true ).addField( registration[0], registration[1], true );
-						
-						if ( querypage.pageprops && querypage.pageprops.description ) {
-							var description = htmlToPlain( querypage.pageprops.description );
-							if ( description.length > 2000 ) description = description.substring(0, 2000) + '\u2026';
-							embed.setDescription( description );
-						}
-						else if ( querypage.extract ) {
-							var extract = extract_desc(querypage.extract);
-							embed.setDescription( extract[0] );
-						}
-					}
+					msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler, queryuser.gender) );
+				}
+				else msg.sendChannel( spoiler + text + spoiler, {embed} );
+				
+				if ( reaction ) reaction.removeEmoji();
+			} );
+			else if ( wiki.isFandom() ) return got.get( wiki + 'wikia.php?controller=UserProfile&method=getUserData&userId=' + queryuser.userid + '&format=json&cache=' + Date.now() ).then( presponse => {
+				var pbody = presponse.body;
+				if ( presponse.statusCode !== 200 || !pbody || !pbody.userData || !pbody.userData.id ) {
+					console.log( '- ' + presponse.statusCode + ': Error while getting the user profile.' );
+					return;
+				}
+				if ( pbody.userData.posts ) {
+					if ( msg.showEmbed() ) embed.spliceFields(1, 0, {
+						name: lang.get('user.info.postcount'),
+						value: '[' + pbody.userData.posts + '](' + wiki + 'f/u/' + queryuser.userid + ')',
+						inline: true
+					});
 					else {
 					else {
-						var embed = {};
-						var text = '<' + pagelink + '>\n\n' + gender.join(' ') + '\n' + registration.join(' ') + '\n' + editcount.join(' ') + '\n' + group[0] + ' ' + group.slice(1).join(', ');
+						let splittext = text.split('\n');
+						splittext.splice(5, 0, lang.get('user.info.postcount') + ' ' + pbody.userData.posts);
+						text = splittext.join('\n');
 					}
 					}
-					if ( wiki.isGamepedia() ) got.get( wiki + 'api.php?action=profile&do=getPublicProfile&user_name=' + encodeURIComponent( username ) + '&format=json&cache=' + Date.now() ).then( presponse => {
-						var pbody = presponse.body;
-						if ( presponse.statusCode !== 200 || !pbody || pbody.error || pbody.errormsg || !pbody.profile ) {
-							console.log( '- ' + presponse.statusCode + ': Error while getting the user profile: ' + ( pbody && ( pbody.error && pbody.error.info || pbody.errormsg ) ) );
-						}
-						else {
-							if ( pbody.profile['link-discord'] ) {
-								if ( pbody.profile['link-discord'].length > 50 ) pbody.profile['link-discord'] = pbody.profile['link-discord'].substring(0, 50) + '\u2026';
-								if ( msg.channel.isGuild() ) 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.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.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 + '/>';
-								}
-							}
-						}
-					}, error => {
-						console.log( '- Error while getting the user profile: ' + error );
-					} ).finally( () => {
-						if ( msg.showEmbed() ) {
-							if ( isBlocked ) {
-								block.text = block.text.replaceSave( /\$3/g, '[' + block.by.escapeFormatting() + '](' + wiki.toLink('User:' + block.by, '', '', true) + ')' );
-								if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toMarkdown(block.reason, wiki) );
-								embed.addField( block.header, block.text );
-							}
-						}
-						else {
-							if ( isBlocked ) {
-								block.text = block.text.replaceSave( /\$3/g, block.by.escapeFormatting() );
-								if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toPlaintext(block.reason) );
-								text += '\n\n**' + block.header + '**\n' + block.text;
-							}
-						}
-						
-						if ( msg.channel.isGuild() && msg.guild.id in patreons ) {
-							if ( msg.showEmbed() ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
-							else 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, queryuser.gender) );
-						}
-						else msg.sendChannel( spoiler + text + spoiler, {embed} );
-						
-						if ( reaction ) reaction.removeEmoji();
-					} );
-					else if ( wiki.isFandom() ) got.get( wiki + 'wikia.php?controller=UserProfile&method=getUserData&userId=' + queryuser.userid + '&format=json&cache=' + Date.now() ).then( presponse => {
-						var pbody = presponse.body;
-						if ( presponse.statusCode !== 200 || !pbody || !pbody.userData || !pbody.userData.id ) console.log( '- ' + presponse.statusCode + ': Error while getting the user profile.' );
-						else {
-							if ( pbody.userData.posts ) {
-								if ( msg.showEmbed() ) embed.spliceFields(1, 0, {
-									name: lang.get('user.info.postcount'),
-									value: '[' + pbody.userData.posts + '](' + wiki + 'f/u/' + queryuser.userid + ')',
-									inline: true
-								});
-								else {
-									let splittext = text.split('\n');
-									splittext.splice(5, 0, lang.get('user.info.postcount') + ' ' + pbody.userData.posts);
-									text = splittext.join('\n');
-								}
-							}
-							if ( pbody.userData.discordHandle ) {
-								let discord = pbody.userData.discordHandle.replace( /^\s*([^@#:]{2,32}?)\s*#(\d{4,6})\s*$/, '$1#$2' );
-								if ( discord.length > 50 ) discord = discord.substring(0, 50) + '\u2026';
-								if ( msg.channel.isGuild() ) var discordmember = msg.guild.members.cache.find( member => {
-									return member.user.tag.escapeFormatting() === discord;
-								} );
-								let discordname = [lang.get('user.info.discord'),discord];
-								if ( discordmember ) discordname[1] = discordmember.toString();
-								
-								if ( msg.showEmbed() ) embed.addField( discordname[0], discordname[1], true );
-								else text += '\n' + discordname.join(' ');
-							}
-							if ( msg.showEmbed() ) {
-								if ( pbody.userData.avatar ) embed.setThumbnail( pbody.userData.avatar.replace( '/thumbnail/width/400/height/400', '' ) );
-								if ( pbody.userData.bio && !embed.description ) {
-									let bio = pbody.userData.bio.escapeFormatting();
-									if ( bio.length > 2000 ) bio = bio.substring(0, 2000) + '\u2026';
-									embed.setDescription( bio );
-								}
-							}
-						}
-					}, error => {
-						console.log( '- Error while getting the user profile: ' + error );
-					} ).finally( () => {
-						if ( msg.showEmbed() ) {
-							if ( isBlocked ) {
-								block.text = block.text.replaceSave( /\$3/g, '[' + block.by.escapeFormatting() + '](' + wiki.toLink('User:' + block.by, '', '', true) + ')' );
-								if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toMarkdown(block.reason, wiki) );
-								embed.addField( block.header, block.text );
-							}
-						}
-						else {
-							if ( isBlocked ) {
-								block.text = block.text.replaceSave( /\$3/g, block.by.escapeFormatting() );
-								if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toPlaintext(block.reason) );
-								text += '\n\n**' + block.header + '**\n' + block.text;
-							}
-						}
-						
-						if ( msg.channel.isGuild() && msg.guild.id in patreons ) {
-							if ( msg.showEmbed() ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
-							else 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, queryuser.gender) );
-						}
-						else msg.sendChannel( spoiler + text + spoiler, {embed} );
-						
-						if ( reaction ) reaction.removeEmoji();
+				}
+				if ( pbody.userData.discordHandle ) {
+					let discord = pbody.userData.discordHandle.replace( /^\s*([^@#:]{2,32}?)\s*#(\d{4,6})\s*$/, '$1#$2' );
+					if ( discord.length > 50 ) discord = discord.substring(0, 50) + '\u2026';
+					if ( msg.channel.isGuild() ) var discordmember = msg.guild.members.cache.find( member => {
+						return member.user.tag.escapeFormatting() === discord;
 					} );
 					} );
-					else {
-						if ( isBlocked ) {
-							if ( msg.showEmbed() ) {
-								block.text = block.text.replaceSave( /\$3/g, '[' + block.by.escapeFormatting() + '](' + wiki.toLink('User:' + block.by, '', '', true) + ')' );
-								if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toMarkdown(block.reason, wiki) );
-								embed.addField( block.header, block.text );
-							}
-							else {
-								block.text = block.text.replaceSave( /\$3/g, block.by.escapeFormatting() );
-								if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toPlaintext(block.reason) );
-								text += '\n\n**' + block.header + '**\n' + block.text;
-							}
-						}
-						
-						msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler, queryuser.gender) );
-						
-						if ( reaction ) reaction.removeEmoji();
+					let discordname = [lang.get('user.info.discord'),discord];
+					if ( discordmember ) discordname[1] = discordmember.toString();
+					
+					if ( msg.showEmbed() ) embed.addField( discordname[0], discordname[1], true );
+					else text += '\n' + discordname.join(' ');
+				}
+				if ( msg.showEmbed() ) {
+					if ( pbody.userData.avatar ) embed.setThumbnail( pbody.userData.avatar.replace( '/thumbnail/width/400/height/400', '' ) );
+					if ( pbody.userData.bio && !embed.description ) {
+						let bio = pbody.userData.bio.escapeFormatting();
+						if ( bio.length > 2000 ) bio = bio.substring(0, 2000) + '\u2026';
+						embed.setDescription( bio );
 					}
 					}
 				}
 				}
+			}, error => {
+				console.log( '- Error while getting the user profile: ' + error );
+			} ).finally( () => {
+				if ( msg.showEmbed() ) {
+					if ( isBlocked ) {
+						block.text = block.text.replaceSave( /\$3/g, '[' + block.by.escapeFormatting() + '](' + wiki.toLink('User:' + block.by, '', '', true) + ')' );
+						if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toMarkdown(block.reason, wiki) );
+						embed.addField( block.header, block.text );
+					}
+				}
+				else {
+					if ( isBlocked ) {
+						block.text = block.text.replaceSave( /\$3/g, block.by.escapeFormatting() );
+						if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toPlaintext(block.reason) );
+						text += '\n\n**' + block.header + '**\n' + block.text;
+					}
+				}
+				
+				if ( msg.channel.isGuild() && msg.guild.id in patreons ) {
+					if ( msg.showEmbed() ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
+					else 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, queryuser.gender) );
+				}
+				else msg.sendChannel( spoiler + text + spoiler, {embed} );
+				
+				if ( reaction ) reaction.removeEmoji();
+			} );
+			if ( body.query.pages ) {
+				let revision = Object.values(body.query.pages)[0]?.revisions?.[0];
+				if ( revision?.user === username ) {
+					let discord = ( revision?.slots?.main || revision )['*'].replace( /^\s*([^@#:]{2,32}?)\s*#(\d{4,6})\s*$/, '$1#$2' );
+					if ( discord.length > 50 ) discord = discord.substring(0, 50) + '\u2026';
+					if ( msg.channel.isGuild() ) var discordmember = msg.guild.members.cache.find( member => {
+						return member.user.tag === discord;
+					} );
+					let discordname = [lang.get('user.info.discord'),discord.escapeFormatting()];
+					if ( discordmember ) discordname[1] = discordmember.toString();
+					
+					if ( msg.showEmbed() ) embed.addField( discordname[0], discordname[1], true );
+					else text += '\n' + discordname.join(' ');
+				}
 			}
 			}
-		}, error => {
-			console.log( '- Error while getting the search results: ' + error );
-			msg.sendChannelError( spoiler + '<' + wiki.toLink(namespace + username, querystring, fragment) + '>' + spoiler );
+			if ( isBlocked ) {
+				if ( msg.showEmbed() ) {
+					block.text = block.text.replaceSave( /\$3/g, '[' + block.by.escapeFormatting() + '](' + wiki.toLink('User:' + block.by, '', '', true) + ')' );
+					if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toMarkdown(block.reason, wiki) );
+					embed.addField( block.header, block.text );
+				}
+				else {
+					block.text = block.text.replaceSave( /\$3/g, block.by.escapeFormatting() );
+					if ( block.reason ) block.text = block.text.replaceSave( /\$4/g, toPlaintext(block.reason) );
+					text += '\n\n**' + block.header + '**\n' + block.text;
+				}
+			}
+			
+			msg.sendChannel( spoiler + text + spoiler, {embed} ).then( message => global_block(lang, message, username, text, embed, wiki, spoiler, queryuser.gender) );
 			
 			
 			if ( reaction ) reaction.removeEmoji();
 			if ( reaction ) reaction.removeEmoji();
 		} );
 		} );
-	}
+	}, error => {
+		console.log( '- Error while getting the search results: ' + error );
+		msg.sendChannelError( spoiler + '<' + wiki.toLink(namespace + username, querystring, fragment) + '>' + spoiler );
+		
+		if ( reaction ) reaction.removeEmoji();
+	} );
 }
 }
 
 
 /**
 /**

+ 19 - 4
dashboard/rcscript.js

@@ -41,10 +41,10 @@ const fieldset = {
 	+ '<input type="checkbox" id="wb-settings-feeds" name="feeds">'
 	+ '<input type="checkbox" id="wb-settings-feeds" name="feeds">'
 	+ '<div id="wb-settings-feeds-only-hide">'
 	+ '<div id="wb-settings-feeds-only-hide">'
 	+ '<label for="wb-settings-feeds-only">Only feeds based changes:</label>'
 	+ '<label for="wb-settings-feeds-only">Only feeds based changes:</label>'
-	+ '<input type="checkbox" id="wb-settings-feeds-only" name="feeds-only">'
+	+ '<input type="checkbox" id="wb-settings-feeds-only" name="feeds_only">'
 	+ '</div>',
 	+ '</div>',
-	save: '<input type="submit" id="wb-settings-save" name="save-settings">',
-	delete: '<input type="submit" id="wb-settings-delete" name="delete-settings">'
+	save: '<input type="submit" id="wb-settings-save" name="save_settings">',
+	delete: '<input type="submit" id="wb-settings-delete" name="delete_settings">'
 };
 };
 
 
 /**
 /**
@@ -196,7 +196,22 @@ function dashboard_rcscript(res, $, guild, args) {
 	} );
 	} );
 }
 }
 
 
-function update_rcscript() {
+/**
+ * Change recent changes scripts
+ * @param {import('http').ServerResponse} res - The server response
+ * @param {String} user - The id of the user
+ * @param {String} guild - The id of the guild
+ * @param {Object} settings - The new settings
+ * @param {String} settings.channel
+ * @param {String} settings.wiki
+ * @param {String} settings.lang
+ * @param {String} settings.display
+ * @param {String} [settings.feeds]
+ * @param {String} [settings.feeds_only]
+ * @param {String} [settings.save_settings]
+ * @param {String} [settings.delete_settings]
+ */
+function update_rcscript(res, user, guild, settings) {
 	
 	
 }
 }
 
 

+ 20 - 4
dashboard/settings.js

@@ -21,13 +21,13 @@ const fieldset = {
 	+ '<input type="text" id="wb-settings-prefix" name="prefix" pattern="^\\s*[^\\s`]+\\s*$" required>'
 	+ '<input type="text" id="wb-settings-prefix" name="prefix" pattern="^\\s*[^\\s`]+\\s*$" required>'
 	+ '<br>'
 	+ '<br>'
 	+ '<label for="wb-settings-prefix-space">Prefix ends with space:</label>'
 	+ '<label for="wb-settings-prefix-space">Prefix ends with space:</label>'
-	+ '<input type="checkbox" id="wb-settings-prefix-space" name="prefix-space">',
+	+ '<input type="checkbox" id="wb-settings-prefix-space" name="prefix_space">',
 	inline: '<label for="wb-settings-inline">Inline commands:</label>'
 	inline: '<label for="wb-settings-inline">Inline commands:</label>'
 	+ '<input type="checkbox" id="wb-settings-inline" name="inline">',
 	+ '<input type="checkbox" id="wb-settings-inline" name="inline">',
 	voice: '<label for="wb-settings-voice">Voice channels:</label>'
 	voice: '<label for="wb-settings-voice">Voice channels:</label>'
 	+ '<input type="checkbox" id="wb-settings-voice" name="voice">',
 	+ '<input type="checkbox" id="wb-settings-voice" name="voice">',
-	save: '<input type="submit" id="wb-settings-save" name="save-settings">',
-	delete: '<input type="submit" id="wb-settings-delete" name="delete-settings">'
+	save: '<input type="submit" id="wb-settings-save" name="save_settings">',
+	delete: '<input type="submit" id="wb-settings-delete" name="delete_settings">'
 };
 };
 
 
 /**
 /**
@@ -188,7 +188,23 @@ function dashboard_settings(res, $, guild, args) {
 	} );
 	} );
 }
 }
 
 
-function update_settings(user, guild, settings) {
+/**
+ * Change settings
+ * @param {import('http').ServerResponse} res - The server response
+ * @param {String} user - The id of the user
+ * @param {String} guild - The id of the guild
+ * @param {Object} settings - The new settings
+ * @param {String} [settings.channel]
+ * @param {String} settings.wiki
+ * @param {String} [settings.lang]
+ * @param {String} [settings.inline]
+ * @param {String} [settings.prefix]
+ * @param {String} [settings.prefix_space]
+ * @param {String} [settings.voice]
+ * @param {String} [settings.save_settings]
+ * @param {String} [settings.delete_settings]
+ */
+function update_settings(res, user, guild, settings) {
 	
 	
 }
 }
 
 

+ 18 - 3
dashboard/verification.js

@@ -16,8 +16,8 @@ const fieldset = {
 	+ '<input type="number" id="wb-settings-accountage" name="accountage" min="0" required>',
 	+ '<input type="number" id="wb-settings-accountage" name="accountage" min="0" required>',
 	rename: '<label for="wb-settings-rename">Rename users:</label>'
 	rename: '<label for="wb-settings-rename">Rename users:</label>'
 	+ '<input type="checkbox" id="wb-settings-rename" name="rename">',
 	+ '<input type="checkbox" id="wb-settings-rename" name="rename">',
-	save: '<input type="submit" id="wb-settings-save" name="save-settings">',
-	delete: '<input type="submit" id="wb-settings-delete" name="delete-settings">'
+	save: '<input type="submit" id="wb-settings-save" name="save_settings">',
+	delete: '<input type="submit" id="wb-settings-delete" name="delete_settings">'
 };
 };
 
 
 /**
 /**
@@ -204,7 +204,22 @@ function dashboard_verification(res, $, guild, args) {
 	} );
 	} );
 }
 }
 
 
-function update_verification() {
+/**
+ * Change verifications
+ * @param {import('http').ServerResponse} res - The server response
+ * @param {String} user - The id of the user
+ * @param {String} guild - The id of the guild
+ * @param {Object} settings - The new settings
+ * @param {String|String[]} settings.channel
+ * @param {String|String[]} settings.role
+ * @param {String|String[]} settings.usergroup
+ * @param {String} settings.editcount
+ * @param {String} settings.accountage
+ * @param {String} [settings.rename]
+ * @param {String} [settings.save_settings]
+ * @param {String} [settings.delete_settings]
+ */
+function update_verification(res, user, guild, settings) {
 	
 	
 }
 }
 
 

+ 4 - 4
functions/global_block.js

@@ -64,7 +64,7 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler, gender) {
 				if ( globaledits ) {
 				if ( globaledits ) {
 					if ( msg.showEmbed() ) embed.spliceFields(1, 0, {
 					if ( msg.showEmbed() ) embed.spliceFields(1, 0, {
 						name: lang.get('user.info.globaleditcount'),
 						name: lang.get('user.info.globaleditcount'),
-						value: '[' + globaledits + '](https://community.fandom.com/wiki/Special:Editcount/' + toTitle(username) + ')',
+						value: globaledits,
 						inline: true
 						inline: true
 					});
 					});
 					else {
 					else {
@@ -81,7 +81,7 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler, gender) {
 		msg.edit( spoiler + text + spoiler, {embed,allowedMentions:{parse:[]}} ).catch(log_error);
 		msg.edit( spoiler + text + spoiler, {embed,allowedMentions:{parse:[]}} ).catch(log_error);
 	} );
 	} );
 	else if ( wiki.isGamepedia() ) Promise.all([
 	else if ( wiki.isGamepedia() ) Promise.all([
-		got.get( 'https://wikisandbox.gamepedia.com/Special:GlobalBlockList/' + encodeURIComponent( username ) + '?uselang=qqx', {
+		got.get( 'https://commons.gamepedia.com/Special:GlobalBlockList/' + encodeURIComponent( username ) + '?uselang=qqx', {
 			responseType: 'text'
 			responseType: 'text'
 		} ).then( response => {
 		} ).then( response => {
 			var body = response.body;
 			var body = response.body;
@@ -120,7 +120,7 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler, gender) {
 		}, error => {
 		}, error => {
 			console.log( '- Error while getting the global block: ' + error );
 			console.log( '- Error while getting the global block: ' + error );
 		} ),
 		} ),
-		( isUser ? got.get( 'https://wikisandbox.gamepedia.com/UserProfile:' + encodeURIComponent( username ), {
+		( isUser ? got.get( 'https://commons.gamepedia.com/UserProfile:' + encodeURIComponent( username ), {
 			responseType: 'text'
 			responseType: 'text'
 		} ).then( gresponse => {
 		} ).then( gresponse => {
 			var gbody = gresponse.body;
 			var gbody = gresponse.body;
@@ -146,7 +146,7 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler, gender) {
 				if ( globaledits ) {
 				if ( globaledits ) {
 					if ( msg.showEmbed() ) embed.spliceFields(1, 0, {
 					if ( msg.showEmbed() ) embed.spliceFields(1, 0, {
 						name: lang.get('user.info.globaleditcount'),
 						name: lang.get('user.info.globaleditcount'),
-						value: '[' + globaledits + '](https://help.gamepedia.com/Gamepedia_Help_Wiki:Global_user_tracker#' + wiki.hostname.replace( '.gamepedia.com', '/' ) + toTitle(username) + ')',
+						value: globaledits,
 						inline: true
 						inline: true
 					});
 					});
 					else {
 					else {

+ 0 - 20
i18n/en.json

@@ -609,49 +609,29 @@
             "unknown": "Unknown"
             "unknown": "Unknown"
         },
         },
         "groups": {
         "groups": {
-            "Elite_users": "Elite user",
-            "Patrol": "Inspector",
-            "assistant": "Assistant",
-            "authenticated": "authenticated",
             "autoconfirmed": "Autoconfirmed user",
             "autoconfirmed": "Autoconfirmed user",
             "autopatrol": "autopatrol",
             "autopatrol": "autopatrol",
-            "autopatroller": "Auto patroller",
             "autoreview": "autoreview",
             "autoreview": "autoreview",
-            "blogpatrol": "Blog patroller",
             "bot": "Bot",
             "bot": "Bot",
             "bot-global": "Global bot",
             "bot-global": "Global bot",
             "bureaucrat": "Bureaucrat",
             "bureaucrat": "Bureaucrat",
-            "chatmoderator": "Chat moderator",
             "checkuser": "Check user",
             "checkuser": "Check user",
-            "codeeditor": "Code editor",
-            "commentcontrol": "Comment controller",
             "content-moderator": "Content moderator",
             "content-moderator": "Content moderator",
             "content-team-member": "Content Team Member",
             "content-team-member": "Content Team Member",
-            "content-volunteer": "Content volunteer",
-            "custodian": "Custodian",
-            "directors": "Director",
-            "doyen": "Dean",
             "editor": "Editor",
             "editor": "Editor",
             "global-discussions-moderator": "Global discussions moderator",
             "global-discussions-moderator": "Global discussions moderator",
             "global_bot": "Global bot",
             "global_bot": "Global bot",
             "grasp": "GRASP",
             "grasp": "GRASP",
             "helper": "Fandom helper",
             "helper": "Fandom helper",
             "hydra_staff": "Gamepedia staff",
             "hydra_staff": "Gamepedia staff",
-            "imagecontrol": "Image controller",
             "interface-admin": "Interface administrator",
             "interface-admin": "Interface administrator",
-            "junioradmin": "Junior administrator",
-            "moderator": "Moderator",
-            "patroller": "Patroller",
-            "patrollers": "Patroller",
             "rollback": "rollback",
             "rollback": "rollback",
             "soap": "SOAP",
             "soap": "SOAP",
             "staff": "Fandom staff",
             "staff": "Fandom staff",
-            "supmoderator": "Senior moderator",
             "sysop": "Administrator",
             "sysop": "Administrator",
             "threadmoderator": "Discussions moderator",
             "threadmoderator": "Discussions moderator",
             "user": "User",
             "user": "User",
             "vanguard": "Vanguard",
             "vanguard": "Vanguard",
-            "voldev": "Volunteer Developer",
             "widgeteditor": "Widget editor",
             "widgeteditor": "Widget editor",
             "wiki-manager": "Wiki manager",
             "wiki-manager": "Wiki manager",
             "wiki_manager": "Wiki manager"
             "wiki_manager": "Wiki manager"

+ 1 - 1
util/allSites.js

@@ -5,7 +5,7 @@ var allSites = getAllSites();
  * @returns {Promise<Object[]>}
  * @returns {Promise<Object[]>}
  */
  */
 function getAllSites() {
 function getAllSites() {
-	return got.get( 'https://wikisandbox.gamepedia.com/api.php?action=allsites&formatversion=2&do=getSiteStats&filter=wikis|md5_key,wiki_domain,wiki_display_name,wiki_image,wiki_description,wiki_managers,official_wiki,wiki_crossover,created&format=json' ).then( response => {
+	return got.get( 'https://commons.gamepedia.com/api.php?action=allsites&formatversion=2&do=getSiteStats&filter=wikis|md5_key,wiki_domain,wiki_display_name,wiki_image,wiki_description,wiki_managers,official_wiki,wiki_crossover,created&format=json' ).then( response => {
 		var body = response.body;
 		var body = response.body;
 		if ( response.statusCode !== 200 || !body || body.status !== 'okay' || !body.data || !body.data.wikis ) {
 		if ( response.statusCode !== 200 || !body || body.status !== 'okay' || !body.data || !body.data.wikis ) {
 			console.log( '- ' + shardId + ': ' + response.statusCode + ': Error while gettings all sites: ' + ( body && body.error && body.error.info ) );
 			console.log( '- ' + shardId + ': ' + response.statusCode + ': Error while gettings all sites: ' + ( body && body.error && body.error.info ) );

+ 48 - 48
util/default.json

@@ -36,54 +36,54 @@
 		"timeZone": "UTC",
 		"timeZone": "UTC",
 		"timeZoneName": "short"
 		"timeZoneName": "short"
 	},
 	},
-	"usergroups": [
-		"global_bot",
-		"hydra_staff",
-		"wiki_manager",
-		"grasp",
-		"bot-global",
-		"staff",
-		"wiki-manager",
-		"helper",
-		"content-team-member",
-		"soap",
-		"content-volunteer",
-		"global-discussions-moderator",
-		"vanguard",
-		"voldev",
-		"bot",
-		"checkuser",
-		"bureaucrat",
-		"sysop",
-		"interface-admin",
-		"widgeteditor",
-		"content-moderator",
-		"threadmoderator",
-		"chatmoderator",
-		"junioradmin",
-		"directors",
-		"Patrol",
-		"editor",
-		"supmoderator",
-		"moderator",
-		"assistant",
-		"blogpatrol",
-		"imagecontrol",
-		"commentcontrol",
-		"custodian",
-		"doyen",
-		"Elite_users",
-		"codeeditor",
-		"patrollers",
-		"patroller",
-		"rollback",
-		"autoreview",
-		"autopatroller",
-		"autopatrol",
-		"authenticated",
-		"autoconfirmed",
-		"user"
-	],
+	"usergroups": {
+		"ignored": [
+			"hydra_admin",
+			"ads_manager",
+			"report_manager",
+			"promo_manager",
+			"fandom-editor",
+			"request-to-be-forgotten-admin",
+			"util",
+			"content-reviewer",
+			"imagereviewer",
+			"restricted-login",
+			"restricted-login-exempt",
+			"council",
+			"*"
+		],
+		"sorted": [
+			"global_bot",
+			"hydra_staff",
+			"wiki_manager",
+			"grasp",
+			"bot-global",
+			"staff",
+			"wiki-manager",
+			"helper",
+			"content-team-member",
+			"soap",
+			"global-discussions-moderator",
+			"vanguard",
+			"bot",
+			"checkuser",
+			"bureaucrat",
+			"interface-admin",
+			"sysop",
+			"wiki_guardian",
+			"content-moderator",
+			"widgeteditor",
+			"threadmoderator",
+			"reviewer",
+			"editor",
+			"__CUSTOM__",
+			"autoreview",
+			"autopatrol",
+			"rollback",
+			"autoconfirmed",
+			"user"
+		]
+	},
 	"wikiProjects": [
 	"wikiProjects": [
 		{
 		{
 			"name": "wikipedia.org",
 			"name": "wikipedia.org",