瀏覽代碼

some small changes

Markus-Rost 3 年之前
父節點
當前提交
9cddfe5609

+ 2 - 2
cmds/eval.js

@@ -1,5 +1,5 @@
 import { inspect } from 'util';
-import cheerio from 'cheerio';
+import { load as cheerioLoad } from 'cheerio';
 import Discord from 'discord.js';
 import { got } from '../util/functions.js';
 import newMessage from '../util/newMessage.js';
@@ -62,7 +62,7 @@ function checkWiki(wiki) {
 	if ( !wiki ) return `Couldn't resolve "${wiki}" into a valid url.`;
 	return got.get( wiki + 'api.php?&action=query&meta=siteinfo&siprop=general&list=recentchanges&rcshow=!bot&rctype=edit|new|log|categorize&rcprop=ids|timestamp&rclimit=100&format=json' ).then( response => {
 		if ( response.statusCode === 404 && typeof response.body === 'string' ) {
-			let api = cheerio.load(response.body)('head link[rel="EditURI"]').prop('href');
+			let api = cheerioLoad(response.body)('head link[rel="EditURI"]').prop('href');
 			if ( api ) {
 				wiki = new Wiki(api.split('api.php?')[0], wiki);
 				return got.get( wiki + 'api.php?action=query&meta=siteinfo&siprop=general&list=recentchanges&rcshow=!bot&rctype=edit|new|log|categorize&rcprop=ids|timestamp&rclimit=100&format=json' );

+ 32 - 2
cmds/get.js

@@ -26,7 +26,7 @@ async function cmd_get(lang, msg, args, line, wiki) {
 			if ( discordClient.guilds.cache.has(evalData.id) ) {
 				var guild = discordClient.guilds.cache.get(evalData.id);
 				return {
-					name: guild.name, id: guild.id, memberCount: guild.memberCount,
+					name: guild.name, id: guild.id, memberCount: guild.approximateMemberCount ?? guild.memberCount,
 					ownerId: guild.ownerId, owner: discordClient.users.cache.get(guild.ownerId)?.tag,
 					channel: guild.publicUpdatesChannelId, icon: guild.iconURL({dynamic:true}),
 					permissions: guild.me.permissions.missing(evalData.defaultPermissions),
@@ -170,7 +170,37 @@ async function cmd_get(lang, msg, args, line, wiki) {
 			return msg.sendChannel( {content: text, embeds: [embed]}, true );
 		}
 		
-		msg.replyMsg( 'I couldn\'t find a result for `' + id + '`', true );
+		return db.query( 'SELECT guild, channel, wiki, lang, role, inline, prefix, patreon, voice FROM discord WHERE guild = $1 OR channel = $1 OR channel = $2 ORDER BY guild, channel DESC NULLS LAST LIMIT 1', [id, '#' + id] ).then( ({rows}) => {
+			if ( !rows.length ) return msg.replyMsg( 'I couldn\'t find a result for `' + id + '`', true );
+			var result = '```json\n' + JSON.stringify( rows, null, '\t' ) + '\n```';
+			if ( msg.showEmbed() ) {
+				var split = Util.splitMessage( result, {char:',\n',maxLength:1000,prepend:'```json\n',append:',\n```'} );
+				if ( split.length > 5 ) {
+					Util.splitMessage( '`' + id + '`: ' + result, {
+						char: ',\n',
+						maxLength: 2000,
+						prepend: '```json\n',
+						append: ',\n```'
+					} ).forEach( textpart => msg.sendChannel( textpart, true ) );
+				}
+				else {
+					var embed = new MessageEmbed();
+					split.forEach( textpart => embed.addField( '`' + id + '`: ', textpart ) );
+					msg.sendChannel( {embeds: [embed]}, true );
+				}
+			}
+			else {
+				Util.splitMessage( '`' + id + '`: ' + result, {
+					char: ',\n',
+					maxLength: 2000,
+					prepend: '```json\n',
+					append: ',\n```'
+				} ).forEach( textpart => msg.sendChannel( textpart, true ) );
+			}
+		}, dberror => {
+			console.log( '- Error while getting the settings: ' + dberror );
+			msg.reactEmoji('error');
+		} );
 	} catch ( error ) {
 		log_error(error);
 		msg.reactEmoji('error');

+ 3 - 3
cmds/rcscript.js

@@ -1,5 +1,5 @@
 import { existsSync } from 'fs';
-import cheerio from 'cheerio';
+import { load as cheerioLoad } from 'cheerio';
 import { Util, MessageActionRow, MessageButton, Permissions } from 'discord.js';
 import help_setup from '../functions/helpsetup.js';
 import { got } from '../util/functions.js';
@@ -76,7 +76,7 @@ function cmd_rcscript(lang, msg, args, line, wiki) {
 				}
 				catch (error) {
 					if ( response.statusCode === 404 && typeof response.body === 'string' ) {
-						let api = cheerio.load(response.body)('head link[rel="EditURI"]').prop('href');
+						let api = cheerioLoad(response.body)('head link[rel="EditURI"]').prop('href');
 						if ( api ) {
 							wikinew = new Wiki(api.split('api.php?')[0], wikinew);
 							return got.get( wikinew + 'api.php?action=query&meta=allmessages|siteinfo&ammessages=custom-RcGcDw|recentchanges&amenableparser=true&siprop=general&titles=Special:RecentChanges&format=json' );
@@ -246,7 +246,7 @@ function cmd_rcscript(lang, msg, args, line, wiki) {
 					}
 					catch (error) {
 						if ( response.statusCode === 404 && typeof response.body === 'string' ) {
-							let api = cheerio.load(response.body)('head link[rel="EditURI"]').prop('href');
+							let api = cheerioLoad(response.body)('head link[rel="EditURI"]').prop('href');
 							if ( api ) {
 								wikinew = new Wiki(api.split('api.php?')[0], wikinew);
 								return got.get( wikinew + 'api.php?action=query&meta=allmessages|siteinfo&ammessages=custom-RcGcDw&amenableparser=true&siprop=general&titles=Special:RecentChanges&format=json' );

+ 2 - 2
cmds/settings.js

@@ -1,4 +1,4 @@
-import cheerio from 'cheerio';
+import { load as cheerioLoad } from 'cheerio';
 import { MessageEmbed, Util, MessageActionRow, MessageButton } from 'discord.js';
 import { got } from '../util/functions.js';
 import Lang from '../util/i18n.js';
@@ -103,7 +103,7 @@ function cmd_settings(lang, msg, args, line, wiki) {
 					}
 					catch (error) {
 						if ( response.statusCode === 404 && typeof response.body === 'string' ) {
-							let api = cheerio.load(response.body)('head link[rel="EditURI"]').prop('href');
+							let api = cheerioLoad(response.body)('head link[rel="EditURI"]').prop('href');
 							if ( api ) {
 								wikinew = new Wiki(api.split('api.php?')[0], wikinew);
 								return got.get( wikinew + 'api.php?action=query&meta=siteinfo&siprop=general&format=json' );

+ 2 - 2
dashboard/guilds.js

@@ -1,5 +1,5 @@
 import { readFileSync } from 'fs';
-import cheerio from 'cheerio';
+import { load as cheerioLoad } from 'cheerio';
 import { forms } from './functions.js';
 import Lang from './i18n.js';
 import { oauth, enabledOAuth2, settingsData, addWidgets, createNotice } from './util.js';
@@ -29,7 +29,7 @@ export default function dashboard_guilds(res, dashboardLang, theme, userSession,
 	}
 	dashboardLang = new Lang(...dashboardLang.fromCookie, settings.user.locale, dashboardLang.lang);
 	res.setHeader('Content-Language', [dashboardLang.lang]);
-	var $ = cheerio.load(file);
+	var $ = cheerioLoad(file);
 	$('html').attr('lang', dashboardLang.lang);
 	if ( theme === 'light' ) $('html').addClass('theme-light');
 	$('<script>').text(`

+ 1 - 1
dashboard/i18n.js

@@ -30,7 +30,7 @@ export default class Lang {
 	 * Get a localized message.
 	 * @param {String} message - Name of the message.
 	 * @param {Boolean} escaped - If the message should be HTML escaped.
-	 * @param {(String|import('cheerio').default)[]} args - Arguments for the message.
+	 * @param {(String|import('cheerio').CheerioAPI)[]} args - Arguments for the message.
 	 * @returns {String}
 	 */
 	get(message = '', escaped = false, ...args) {

+ 3 - 3
dashboard/oauth.js

@@ -1,6 +1,6 @@
 import { readFileSync } from 'fs';
 import { randomBytes } from 'crypto';
-import cheerio from 'cheerio';
+import { load as cheerioLoad } from 'cheerio';
 import Wiki from '../util/wiki.js';
 import { allLangs } from './i18n.js';
 import { got, db, oauth, enabledOAuth2, sessionData, settingsData, oauthVerify, sendMsg, addWidgets, createNotice, hasPerm } from './util.js';
@@ -27,7 +27,7 @@ function dashboard_login(res, dashboardLang, theme, state, action) {
 		}
 		sessionData.delete(state);
 	}
-	var $ = cheerio.load(file);
+	var $ = cheerioLoad(file);
 	$('html').attr('lang', dashboardLang.lang);
 	if ( theme === 'light' ) $('html').addClass('theme-light');
 	$('<script>').text(`
@@ -281,7 +281,7 @@ function dashboard_api(res, input) {
 		}
 		catch (error) {
 			if ( response.statusCode === 404 && typeof response.body === 'string' ) {
-				let api = cheerio.load(response.body)('head link[rel="EditURI"]').prop('href');
+				let api = cheerioLoad(response.body)('head link[rel="EditURI"]').prop('href');
 				if ( api ) {
 					wiki = new Wiki(api.split('api.php?')[0], wiki);
 					return got.get( wiki + 'api.php?action=query&meta=allmessages|siteinfo&ammessages=custom-RcGcDw&amenableparser=true&siprop=general&format=json' );

+ 5 - 5
dashboard/rcscript.js

@@ -1,4 +1,4 @@
-import cheerio from 'cheerio';
+import { load as cheerioLoad } from 'cheerio';
 import Lang from '../util/i18n.js';
 import Wiki from '../util/wiki.js';
 import { got, db, sendMsg, createNotice, hasPerm } from './util.js';
@@ -66,7 +66,7 @@ const fieldset = {
 
 /**
  * Create a settings form
- * @param {import('cheerio').default} $ - The response body
+ * @param {import('cheerio').CheerioAPI} $ - The response body
  * @param {String} header - The form header
  * @param {import('./i18n.js').default} dashboardLang - The user language
  * @param {Object} settings - The current settings
@@ -197,7 +197,7 @@ function createForm($, header, dashboardLang, settings, guildChannels, allWikis)
 /**
  * Let a user change recent changes scripts
  * @param {import('http').ServerResponse} res - The server response
- * @param {import('cheerio').default} $ - The response body
+ * @param {import('cheerio').CheerioAPI} $ - The response body
  * @param {import('./util.js').Guild} guild - The current guild
  * @param {String[]} args - The url parts
  * @param {import('./i18n.js').default} dashboardLang - The user language
@@ -387,7 +387,7 @@ function update_rcscript(res, userSettings, guild, type, settings) {
 				}
 				catch (error) {
 					if ( fresponse.statusCode === 404 && typeof fresponse.body === 'string' ) {
-						let api = cheerio.load(fresponse.body)('head link[rel="EditURI"]').prop('href');
+						let api = cheerioLoad(fresponse.body)('head link[rel="EditURI"]').prop('href');
 						if ( api ) {
 							wiki = new Wiki(api.split('api.php?')[0], wiki);
 							return got.get( wiki + 'api.php?action=query&meta=allmessages|siteinfo&ammessages=custom-RcGcDw|recentchanges&amenableparser=true&siprop=general&titles=Special:RecentChanges&format=json' );
@@ -632,7 +632,7 @@ function update_rcscript(res, userSettings, guild, type, settings) {
 					}
 					catch (error) {
 						if ( fresponse.statusCode === 404 && typeof fresponse.body === 'string' ) {
-							let api = cheerio.load(fresponse.body)('head link[rel="EditURI"]').prop('href');
+							let api = cheerioLoad(fresponse.body)('head link[rel="EditURI"]').prop('href');
 							if ( api ) {
 								wiki = new Wiki(api.split('api.php?')[0], wiki);
 								return got.get( wiki + 'api.php?action=query&meta=allmessages|siteinfo&ammessages=custom-RcGcDw&amenableparser=true&siprop=general&format=json' );

+ 4 - 4
dashboard/settings.js

@@ -1,4 +1,4 @@
-import cheerio from 'cheerio';
+import { load as cheerioLoad } from 'cheerio';
 import Lang from '../util/i18n.js';
 import Wiki from '../util/wiki.js';
 import { got, db, sendMsg, createNotice, hasPerm } from './util.js';
@@ -40,7 +40,7 @@ const fieldset = {
 
 /**
  * Create a settings form
- * @param {import('cheerio').default} $ - The response body
+ * @param {import('cheerio').CheerioAPI} $ - The response body
  * @param {String} header - The form header
  * @param {import('./i18n.js').default} dashboardLang - The user language
  * @param {Object} settings - The current settings
@@ -167,7 +167,7 @@ function createForm($, header, dashboardLang, settings, guildRoles, guildChannel
 /**
  * Let a user change settings
  * @param {import('http').ServerResponse} res - The server response
- * @param {import('cheerio').default} $ - The response body
+ * @param {import('cheerio').CheerioAPI} $ - The response body
  * @param {import('./util.js').Guild} guild - The current guild
  * @param {String[]} args - The url parts
  * @param {import('./i18n.js').default} dashboardLang - The user language
@@ -356,7 +356,7 @@ function update_settings(res, userSettings, guild, type, settings) {
 			}
 			catch (error) {
 				if ( fresponse.statusCode === 404 && typeof fresponse.body === 'string' ) {
-					let api = cheerio.load(fresponse.body)('head link[rel="EditURI"]').prop('href');
+					let api = cheerioLoad(fresponse.body)('head link[rel="EditURI"]').prop('href');
 					if ( api ) {
 						wiki = new Wiki(api.split('api.php?')[0], wiki);
 						return got.get( wiki + 'api.php?action=query&meta=siteinfo&siprop=general&format=json' );

+ 2 - 2
dashboard/slash.js

@@ -22,7 +22,7 @@ const fieldset = {
 
 /**
  * Create a settings form
- * @param {import('cheerio').default} $ - The response body
+ * @param {import('cheerio').CheerioAPI} $ - The response body
  * @param {slashCommands[0]} slashCommand - The slash command
  * @param {import('./i18n.js').default} dashboardLang - The user language
  * @param {Object[]} permissions - The current permissions
@@ -94,7 +94,7 @@ function createForm($, slashCommand, dashboardLang, permissions, guildId, guildR
 /**
  * Let a user change slashs
  * @param {import('http').ServerResponse} res - The server response
- * @param {import('cheerio').default} $ - The response body
+ * @param {import('cheerio').CheerioAPI} $ - The response body
  * @param {import('./util.js').Guild} guild - The current guild
  * @param {String[]} args - The url parts
  * @param {import('./i18n.js').default} dashboardLang - The user language

+ 1 - 1
dashboard/user.js

@@ -3,7 +3,7 @@ import { db, enabledOAuth2 } from './util.js';
 /**
  * Let a user change settings
  * @param {import('http').ServerResponse} res - The server response
- * @param {import('cheerio').default} $ - The response body
+ * @param {import('cheerio').CheerioAPI} $ - The response body
  * @param {import('./util.js').User} user - The current user
  * @param {import('./i18n.js').default} dashboardLang - The user language
  */

+ 4 - 4
dashboard/util.js

@@ -233,9 +233,9 @@ if ( process.env.botlist ) {
 
 /**
  * Add bot list widgets.
- * @param {import('cheerio').default} $ - The cheerio static
+ * @param {import('cheerio').CheerioAPI} $ - The cheerio static
  * @param {import('./i18n.js').default} dashboardLang - The user language
- * @returns {import('cheerio').default}
+ * @returns {import('cheerio').CheerioAPI}
 */
 function addWidgets($, dashboardLang) {
 	if ( !botLists.length ) return;
@@ -248,11 +248,11 @@ function addWidgets($, dashboardLang) {
 
 /**
  * Create a red notice
- * @param {import('cheerio').default} $ - The cheerio static
+ * @param {import('cheerio').CheerioAPI} $ - The cheerio static
  * @param {String} notice - The notice to create
  * @param {import('./i18n.js').default} dashboardLang - The user language
  * @param {String[]} [args] - The arguments for the notice
- * @returns {import('cheerio').default}
+ * @returns {import('cheerio').CheerioAPI}
  */
 function createNotice($, notice, dashboardLang, args = []) {
 	if ( !notice ) return;

+ 2 - 2
dashboard/verification.js

@@ -60,7 +60,7 @@ const fieldset = {
 
 /**
  * Create a settings form
- * @param {import('cheerio').default} $ - The response body
+ * @param {import('cheerio').CheerioAPI} $ - The response body
  * @param {String} header - The form header
  * @param {import('./i18n.js').default} dashboardLang - The user language
  * @param {Object} settings - The current settings
@@ -248,7 +248,7 @@ function createForm($, header, dashboardLang, settings, guildChannels, guildRole
 /**
  * Let a user change verifications
  * @param {import('http').ServerResponse} res - The server response
- * @param {import('cheerio').default} $ - The response body
+ * @param {import('cheerio').CheerioAPI} $ - The response body
  * @param {import('./util.js').Guild} guild - The current guild
  * @param {String[]} args - The url parts
  * @param {import('./i18n.js').default} dashboardLang - The user language

+ 3 - 3
functions/global_block.js

@@ -1,4 +1,4 @@
-import cheerio from 'cheerio';
+import { load as cheerioLoad } from 'cheerio';
 import { got, escapeFormatting } from '../util/functions.js';
 
 /**
@@ -37,7 +37,7 @@ export default function global_block(lang, msg, username, text, embed, wiki, spo
 				console.log( '- ' + response.statusCode + ': Error while getting the global block.' );
 			}
 			else {
-				let $ = cheerio.load(body);
+				let $ = cheerioLoad(body);
 				if ( $('#mw-content-text .errorbox').length ) {
 					if ( embed && msg.showEmbed() ) embed.addField( '\u200b', '**' + lang.get('user.gblock.disabled') + '**' );
 					else text += '\n\n**' + lang.get('user.gblock.disabled') + '**';
@@ -58,7 +58,7 @@ export default function global_block(lang, msg, username, text, embed, wiki, spo
 				console.log( '- ' + gresponse.statusCode + ': Error while getting the global edit count.' );
 			}
 			else {
-				let $ = cheerio.load(gbody);
+				let $ = cheerioLoad(gbody);
 				var wikisedited = $('.curseprofile .rightcolumn .section.stats dd').eq(0).text().replace( /[,\.]/g, '' );
 				if ( wikisedited ) {
 					wikisedited = parseInt(wikisedited, 10).toLocaleString(lang.get('dateformat'));

+ 2 - 2
functions/parse_page.js

@@ -1,4 +1,4 @@
-import cheerio from 'cheerio';
+import { load as cheerioLoad } from 'cheerio';
 import { MessageEmbed } from 'discord.js';
 import { toSection } from '../util/wiki.js';
 import { got, parse_infobox, htmlToPlain, htmlToDiscord, escapeFormatting, limitLength } from '../util/functions.js';
@@ -269,7 +269,7 @@ export default function parse_page(lang, msg, content, embed, wiki, reaction, {n
 				if ( displaytitle.length > 250 ) displaytitle = displaytitle.substring(0, 250) + '\u2026';
 				embed.setTitle( displaytitle );
 			}
-			var $ = cheerio.load(response.body.parse.text['*'].replace( /\n?<br(?: ?\/)?>\n?/g, '<br>' ));
+			var $ = cheerioLoad(response.body.parse.text['*'].replace( /\n?<br(?: ?\/)?>\n?/g, '<br>' ));
 			if ( embed.brokenInfobox && $('aside.portable-infobox').length ) {
 				let infobox = $('aside.portable-infobox');
 				embed.fields.forEach( field => {

+ 2 - 2
functions/verify.js

@@ -1,4 +1,4 @@
-import cheerio from 'cheerio';
+import { load as cheerioLoad } from 'cheerio';
 import { MessageEmbed, MessageActionRow, MessageButton, Permissions } from 'discord.js';
 import db from '../util/database.js';
 import Lang from '../util/i18n.js';
@@ -124,7 +124,7 @@ export default function verify(lang, channel, member, username, wiki, rows, old_
 				comment.push(lang.get('verify.failed_gblock'));
 			}
 			else {
-				let $ = cheerio.load(gbresponse.body);
+				let $ = cheerioLoad(gbresponse.body);
 				if ( $('#mw-content-text .errorbox').length ) {
 					return Promise.reject({
 						desc: lang.get('verify.user_disabled', '[' + escapeFormatting(username) + '](' + pagelink + ')'),

+ 26 - 26
util/default.json

@@ -102,73 +102,73 @@
 	"wikiProjects": [
 		{
 			"name": "fandom.com",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)fandom\\.com(?:/[a-z-]{2,12})?)",
+			"regex": "(([a-z\\d-]{1,50})\\.fandom\\.com(?:/(?!wiki)([a-z-]{2,12}))?)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/"
 		},
 		{
 			"name": "wikipedia.org",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)?(?:m\\.)?wikipedia\\.org)",
+			"regex": "((?:([a-z\\d-]{1,50})\\.)?(?:m\\.)?wikipedia\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},
 		{
 			"name": "mediawiki.org",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)?(?:m\\.)?mediawiki\\.org)",
+			"regex": "((?:([a-z\\d-]{1,50})\\.)?(?:m\\.)?mediawiki\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},
 		{
 			"name": "wikimedia.org",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)?(?:m\\.)?wikimedia\\.org)",
+			"regex": "((?:([a-z\\d-]{1,50})\\.)?(?:m\\.)?wikimedia\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},
 		{
 			"name": "wiktionary.org",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)?(?:m\\.)?wiktionary\\.org)",
+			"regex": "((?:([a-z\\d-]{1,50})\\.)?(?:m\\.)?wiktionary\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},
 		{
 			"name": "wikibooks.org",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)?(?:m\\.)?wikibooks\\.org)",
+			"regex": "((?:([a-z\\d-]{1,50})\\.)?(?:m\\.)?wikibooks\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},
 		{
 			"name": "wikisource.org",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)?(?:m\\.)?wikisource\\.org)",
+			"regex": "((?:([a-z\\d-]{1,50})\\.)?(?:m\\.)?wikisource\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},
 		{
 			"name": "wikidata.org",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)?(?:m\\.)?wikidata\\.org)",
+			"regex": "((?:([a-z\\d-]{1,50})\\.)?(?:m\\.)?wikidata\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},
 		{
 			"name": "wikiversity.org",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)?(?:m\\.)?wikiversity\\.org)",
+			"regex": "((?:([a-z\\d-]{1,50})\\.)?(?:m\\.)?wikiversity\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},
 		{
 			"name": "wikiquote.org",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)?(?:m\\.)?wikiquote\\.org)",
+			"regex": "((?:([a-z\\d-]{1,50})\\.)?(?:m\\.)?wikiquote\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},
 		{
 			"name": "wikinews.org",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)?(?:m\\.)?wikinews\\.org)",
+			"regex": "((?:([a-z\\d-]{1,50})\\.)?(?:m\\.)?wikinews\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},
 		{
 			"name": "wikivoyage.org",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)?(?:m\\.)?wikivoyage\\.org)",
+			"regex": "((?:([a-z\\d-]{1,50})\\.)?(?:m\\.)?wikivoyage\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},
@@ -180,43 +180,43 @@
 		},
 		{
 			"name": "wiki.gg",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)wiki\\.gg(?:/[a-z-]{2,12})?)",
+			"regex": "(([a-z\\d-]{1,50})\\.wiki\\.gg(?:/(?!wiki)([a-z-]{2,12}))?)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/"
 		},
 		{
 			"name": "miraheze.org",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)miraheze\\.org)",
+			"regex": "(([a-z\\d-]{1,50})\\.miraheze\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},
 		{
 			"name": "paradoxwikis.com",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)paradoxwikis\\.com)",
+			"regex": "(([a-z\\d-]{1,50})\\.paradoxwikis\\.com)",
 			"articlePath": "/",
 			"scriptPath": "/"
 		},
 		{
 			"name": "runescape.wiki",
-			"regex": "((?:(?:classic|oldschool|pt|www)\\.)?runescape\\.wiki)",
+			"regex": "((?:(classic|oldschool|pt|www)\\.)?runescape\\.wiki)",
 			"articlePath": "/w/",
 			"scriptPath": "/"
 		},
 		{
 			"name": "wiki.biligame.com",
-			"regex": "(wiki\\.biligame\\.com(?:/[a-z\\d]{1,50}))",
+			"regex": "(wiki\\.biligame\\.com/([a-z\\d]{1,50}))",
 			"articlePath": "/",
 			"scriptPath": "/"
 		},
 		{
 			"name": "metapedia.org",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)metapedia\\.org)",
+			"regex": "(([a-z\\d-]{1,50})\\.metapedia\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/m/"
 		},
 		{
 			"name": "brickimedia.org",
-			"regex": "((?:[a-z\\d-]{1,50}\\.)brickimedia\\.org)",
+			"regex": "(([a-z\\d-]{1,50})\\.brickimedia\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},
@@ -234,7 +234,7 @@
 		},
 		{
 			"name": "stardewvalleywiki.com",
-			"regex": "((?:[a-z-]{2,12}\\.)?stardewvalleywiki\\.com)",
+			"regex": "((?:([a-z-]{2,12})\\.)?stardewvalleywiki\\.com)",
 			"articlePath": "/",
 			"scriptPath": "/mediawiki/"
 		},
@@ -246,7 +246,7 @@
 		},
 		{
 			"name": "metin2.gameforge.com",
-			"regex": "([a-z]{2}-wiki\\.metin2\\.gameforge\\.com)",
+			"regex": "(([a-z]{2})-wiki\\.metin2\\.gameforge\\.com)",
 			"articlePath": "/index.php/",
 			"scriptPath": "/"
 		},
@@ -276,13 +276,13 @@
 		},
 		{
 			"name": "moegirl.org.cn",
-			"regex": "([a-z-]{2,12}\\.moegirl\\.org\\.cn)",
+			"regex": "(([a-z-]{2,12})\\.moegirl\\.org\\.cn)",
 			"articlePath": "/",
 			"scriptPath": "/"
 		},
 		{
 			"name": "wiki-aventurica.de",
-			"regex": "((?:[a-z-]{2,12}\\.)?wiki-aventurica\\.de)",
+			"regex": "((?:([a-z-]{2,12})\\.)?wiki-aventurica\\.de)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/de/"
 		},
@@ -426,7 +426,7 @@
 		},
 		{
 			"name": "splatoonwiki.org",
-			"regex": "((?:(?:fr|www)\\.)?splatoonwiki\\.org)",
+			"regex": "((?:(fr|www)\\.)?splatoonwiki\\.org)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},
@@ -462,7 +462,7 @@
 		},
 		{
 			"name": "ssbwiki.com",
-			"regex": "((?:(?:es|www)\\.)?ssbwiki\\.com)",
+			"regex": "((?:(es|www)\\.)?ssbwiki\\.com)",
 			"articlePath": "/",
 			"scriptPath": "/"
 		},
@@ -510,7 +510,7 @@
 		},
 		{
 			"name": "wikibound.info",
-			"regex": "((?:(?:it|www)\\.)?wikibound\\.info)",
+			"regex": "((?:(it|www)\\.)?wikibound\\.info)",
 			"articlePath": "/wiki/",
 			"scriptPath": "/w/"
 		},

+ 1 - 1
util/newMessage.js

@@ -106,7 +106,7 @@ export default function newMessage(msg, lang, wiki = defaultSettings.wiki, prefi
 		if ( invoke.startsWith( '!!' ) && /^!!(?:[a-z\d-]{1,50}\.)?[a-z\d-]{1,50}\.[a-z\d-]{1,10}$/.test(domainToASCII(invoke.split('/')[0])) ) {
 			let project = wikiProjects.find( project => invoke.split('/')[0].endsWith( project.name ) );
 			if ( project ) {
-				let regex = invoke.match( new RegExp( project.regex ) );
+				let regex = invoke.match( new RegExp( '^' + project.regex + '$' ) );
 				if ( regex && invoke === '!!' + regex[1] ) return cmdmap.LINK(lang, msg, args.join(' '), new Wiki('https://' + regex[1] + project.scriptPath), invoke + ' ');
 			}
 		}