From 9ac2bbe9781f7ab5a798621cc9dd46b4ff8befda Mon Sep 17 00:00:00 2001 From: destruc7i0n Date: Tue, 4 Feb 2020 00:51:15 -0500 Subject: Refactor and rebuild to TypeScript --- src/Config.ts | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/Config.ts (limited to 'src/Config.ts') diff --git a/src/Config.ts b/src/Config.ts new file mode 100644 index 0000000..036e057 --- /dev/null +++ b/src/Config.ts @@ -0,0 +1,39 @@ +export interface Config { + PORT: number + + USE_WEBHOOKS: boolean + WEBHOOK_URL: string + DISCORD_TOKEN: string + DISCORD_CHANNEL_ID: string + DISCORD_MESSAGE_TEMPLATE: string + + MINECRAFT_SERVER_RCON_IP: string + MINECRAFT_SERVER_RCON_PORT: number + MINECRAFT_SERVER_RCON_PASSWORD: string + MINECRAFT_TELLRAW_TEMPLATE: string + + IS_LOCAL_FILE: boolean + LOCAL_FILE_PATH: string + + SHOW_INIT_MESSAGE: boolean + + ALLOW_USER_MENTIONS: boolean + ALLOW_HERE_EVERYONE_MENTIONS: boolean + ALLOW_SLASH_COMMANDS: boolean + SLASH_COMMAND_ROLES: string[] + + WEBHOOK: string + REGEX_SERVER_PREFIX: string + REGEX_MATCH_CHAT_MC: string + REGEX_IGNORED_CHAT: string + RCON_RECONNECT_DELAY: number + DEBUG: boolean + + SERVER_NAME: string + SERVER_IMAGE: string + SHOW_PLAYER_CONN_STAT: boolean + SHOW_PLAYER_ADVANCEMENT: boolean + SHOW_PLAYER_DEATH: boolean + SHOW_PLAYER_ME: boolean + DEATH_KEY_WORDS: string[] +} -- cgit 1.4.1 From ff4a9fa8b148da00bff9dd7cb447e9d5321ef84e Mon Sep 17 00:00:00 2001 From: destruc7i0n Date: Wed, 5 Feb 2020 19:32:35 -0500 Subject: More config handling --- src/Config.ts | 3 +++ src/MinecraftHandler.ts | 27 +++++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) (limited to 'src/Config.ts') diff --git a/src/Config.ts b/src/Config.ts index 036e057..5688f2e 100644 --- a/src/Config.ts +++ b/src/Config.ts @@ -15,6 +15,9 @@ export interface Config { IS_LOCAL_FILE: boolean LOCAL_FILE_PATH: string + PATH_TO_MINECRAFT_SERVER_INSTALL?: string + YOUR_URL?: string + SHOW_INIT_MESSAGE: boolean ALLOW_USER_MENTIONS: boolean diff --git a/src/MinecraftHandler.ts b/src/MinecraftHandler.ts index 7ed9d86..20bccf5 100644 --- a/src/MinecraftHandler.ts +++ b/src/MinecraftHandler.ts @@ -1,4 +1,5 @@ import fs from 'fs' +import path from 'path' import { Tail } from 'tail' import express from 'express' @@ -21,7 +22,7 @@ class MinecraftHandler { this.config = config } - private fixMinecraftUsername (username: string) { + private static fixMinecraftUsername (username: string) { return username.replace(/(ยง[A-Z-a-z0-9])/g, '') } @@ -66,7 +67,7 @@ class MinecraftHandler { return null } - const username = this.fixMinecraftUsername(matches[1]) + const username = MinecraftHandler.fixMinecraftUsername(matches[1]) const message = matches[2] if (this.config.DEBUG) { console.log('[DEBUG] Username: ' + matches[1]) @@ -146,10 +147,24 @@ class MinecraftHandler { console.log('[INFO] Bot listening on *:' + port) if (!this.config.IS_LOCAL_FILE && this.config.SHOW_INIT_MESSAGE) { - console.log('[INFO] Please enter the following command on your server running the Minecraft server.') - console.log(' Replace "PATH_TO_MINECRAFT_SERVER_INSTALL" with the path to your Minecraft server install') - console.log(' and "YOUR_URL" with the URL/IP of the server running Shulker!') - console.log(` \`tail -F /PATH_TO_MINECRAFT_SERVER_INSTALL/logs/latest.log | grep --line-buffered ": <" | while read x ; do echo -ne $x | curl -X POST -d @- http://YOUR_URL:${port}${this.config.WEBHOOK} ; done\``) + // in case someone inputs the actual path and url in the config here... + let mcPath: string = this.config.PATH_TO_MINECRAFT_SERVER_INSTALL || 'PATH_TO_MINECRAFT_SERVER_INSTALL' + const url: string = this.config.YOUR_URL || 'YOUR_URL' + + const defaultPath = mcPath === 'PATH_TO_MINECRAFT_SERVER_INSTALL' + const defaultUrl = url === 'YOUR_URL' + + console.log('[INFO] Please enter the following command on your server running the Minecraft server:') + if (defaultPath) { + console.log(' Replace "PATH_TO_MINECRAFT_SERVER_INSTALL" with the path to your Minecraft server install') + if (defaultUrl) console.log(' and "YOUR_URL" with the URL/IP of the server running Shulker!') + } else { + if (defaultUrl) console.log(' Replace "YOUR_URL" with the URL/IP of the server running Shulker') + } + + mcPath = (defaultPath ? '/' : '') + path.join(mcPath, '/logs/latest.log') + + console.log(` \`tail -F ${mcPath} | grep --line-buffered ": <" | while read x ; do echo -ne $x | curl -X POST -d @- http://${url}:${port}${this.config.WEBHOOK} ; done\``) } }) } -- cgit 1.4.1 From f99e623f643c0a55dfa27a792fe451ccba64d7ec Mon Sep 17 00:00:00 2001 From: destruc7i0n Date: Wed, 5 Feb 2020 21:23:00 -0500 Subject: Some more cleanup --- LICENSE | 2 +- README.md | 14 +++++++------- config.json | 1 - src/Config.ts | 1 - 4 files changed, 8 insertions(+), 10 deletions(-) (limited to 'src/Config.ts') diff --git a/LICENSE b/LICENSE index 3fde45f..cf96254 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016, destruc7i0n +Copyright (c) 2020, destruc7i0n Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/README.md b/README.md index 0601c79..3cd1a99 100644 --- a/README.md +++ b/README.md @@ -77,13 +77,13 @@ You can also easily Deploy to Heroku and the like, just be sure to edit `YOUR_UR "REGEX_IGNORED_CHAT": "packets too frequently", /* What to ignore, you can put any regex for swear words for example and it will be ignored */ "DEBUG": false, /* Dev debugging */ - "SERVER_NAME" : "Shulker", /* The username used when displaying any server information in chat, e.g., Server - Shulker : Server message here*/ + "SERVER_NAME": "Shulker", /* The username used when displaying any server information in chat, e.g., Server - Shulker : Server message here*/ "SERVER_IMAGE": "", /* Image for the server when sending such messages (if enabled below). Only for WebHooks. */ - "SHOW_PLAYER_CONN_STAT" : false, /* Shows player connection status in chat, e.g., Server - Shulker : TheMachine joined the game */ - "SHOW_PLAYER_ADVANCEMENT" : false, /* Shows when players earn achievements in chat, e.g., Server - Shulker : TheMachine has earned the achievement [MEME - Machine] */ - "SHOW_PLAYER_DEATH" : false, /* Shows when players die in chat, e.g., Server - Shulker : TheMachine was blown up by creeper */ - "SHOW_PLAYER_ME" : false, /* Shows when players use the /me command, e.g. **destruc7i0n** says hello */ - "DEATH_KEY_WORDS" : ["shot", "fell", "etc".] /* Key words to look for when trying to identify a death message. (As of 3/11/2019 this list is up to date) */ + "SHOW_PLAYER_CONN_STAT": false, /* Shows player connection status in chat, e.g., Server - Shulker : TheMachine joined the game */ + "SHOW_PLAYER_ADVANCEMENT": false, /* Shows when players earn advancements in chat, e.g., Server - Shulker : TheMachine has made the advacement [MEME - Machine] */ + "SHOW_PLAYER_DEATH": false, /* Shows when players die in chat, e.g., Server - Shulker : TheMachine was blown up by creeper */ + "SHOW_PLAYER_ME": false, /* Shows when players use the /me command, e.g. **destruc7i0n** says hello */ + "DEATH_KEY_WORDS": ["shot", "fell", "etc".] /* Key words to look for when trying to identify a death message. (As of 3/11/2019 this list is up to date) */ } ``` @@ -93,7 +93,7 @@ You can also easily Deploy to Heroku and the like, just be sure to edit `YOUR_UR * Why can't I send commands even if I have the option enabled? - Make sure that you have a role on the server which is put in the array `SLASH_COMMAND_ROLES` case-sensitive. - - e.g. `"SLASH_COMMAND_ROLES": ["Admin"],` + - e.g. `"SLASH_COMMAND_ROLES": ["Admin"]` ## Upcoming None diff --git a/config.json b/config.json index 60ab378..2179402 100644 --- a/config.json +++ b/config.json @@ -26,7 +26,6 @@ "REGEX_SERVER_PREFIX": "\\[Server thread/INFO\\]:", "REGEX_MATCH_CHAT_MC": "^<([^>]*)> (.*)", "REGEX_IGNORED_CHAT": "packets too frequently", - "RCON_RECONNECT_DELAY": 10, "DEBUG": false, "SERVER_NAME": "Shulker", diff --git a/src/Config.ts b/src/Config.ts index 5688f2e..77fefd2 100644 --- a/src/Config.ts +++ b/src/Config.ts @@ -29,7 +29,6 @@ export interface Config { REGEX_SERVER_PREFIX: string REGEX_MATCH_CHAT_MC: string REGEX_IGNORED_CHAT: string - RCON_RECONNECT_DELAY: number DEBUG: boolean SERVER_NAME: string -- cgit 1.4.1 From 4d08955c59c35bcbe79a8e202fb947551e7470b8 Mon Sep 17 00:00:00 2001 From: destruc7i0n Date: Wed, 5 Feb 2020 22:07:14 -0500 Subject: Allow specification of the channel name rather than id --- README.md | 8 +++++--- config.json | 3 ++- src/Config.ts | 1 + src/Discord.ts | 27 ++++++++++++++++++++++++--- src/MinecraftHandler.ts | 15 ++++++++++++--- 5 files changed, 44 insertions(+), 10 deletions(-) (limited to 'src/Config.ts') diff --git a/README.md b/README.md index 3cd1a99..64abf69 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,15 @@ rcon.password= rcon.port=<1-65535> ``` -Clone repository onto a server, edit ```config.json``` (see below for more info) and change any options, and then, in the repository folder: +Clone repository onto a server, edit ```config.json``` (see below for more info) and change any options. +Then, in the repository folder: ```sh $ yarn $ yarn build && yarn start ``` -If you are running this locally, enable the `IS_LOCAL_FILE` flag and related options below. Otherwise, perform the following command: -On your server hosting (in a screen/tmux session or background process, make sure to replace your `YOUR_URL` with whatever URL you're using (`localhost:8000` if running on the same server and default config) and `PATH_TO_MINECRAFT_SERVER_INSTALL` with the path to the Minecraft server installation, such as `/usr/home/minecraft_server/`): +If you are running this on the same server as the MC server, enable the `IS_LOCAL_FILE` flag and update related options below. +Otherwise, perform the following command on the server hosting (in a screen/tmux session or background process, make sure to replace your `YOUR_URL` with whatever URL you're using (`localhost:8000` if running on the same server and default config) and `PATH_TO_MINECRAFT_SERVER_INSTALL` with the path to the Minecraft server installation, such as `/usr/home/minecraft_server/`): ``` sh tail -F /PATH_TO_MINECRAFT_SERVER_INSTALL/logs/latest.log | grep --line-buffered ": <" | while read x ; do echo -ne $x | curl -X POST -d @- http://YOUR_URL/minecraft/hook ; done @@ -54,6 +55,7 @@ You can also easily Deploy to Heroku and the like, just be sure to edit `YOUR_UR "WEBHOOK_URL": "DISCORD_WEBHOOK_URL_HERE", /* Be sure to create a webhook in the channel settings and place it here! */ "DISCORD_TOKEN": "<12345>", /* Discord bot token. [Click here](https://discordapp.com/developers/applications/me) to create you application and add a bot to it. */ "DISCORD_CHANNEL_ID": "", /* Discord channel ID for for the discord bot. Enable developer mode in your Discord client, then right click channel and select "Copy ID". */ + "DISCORD_CHANNEL_NAME": "#" /* The Discord channel name. It is recommended to use the ID if the bot is in multiple servers. The ID will take precedence. */ "DISCORD_MESSAGE_TEMPLATE": "`%username%`:%message%", /* Message template to display in Discord */ "MINECRAFT_SERVER_RCON_IP": "127.0.0.1", /* Minecraft server IP (make sure you have enabled rcon) */ diff --git a/config.json b/config.json index 2179402..43d7140 100644 --- a/config.json +++ b/config.json @@ -4,7 +4,8 @@ "USE_WEBHOOKS": true, "WEBHOOK_URL": "DISCORD_WEBHOOK_URL_HERE", "DISCORD_TOKEN": "TOKEN_HERE", - "DISCORD_CHANNEL_ID": "1234", + "DISCORD_CHANNEL_ID": "", + "DISCORD_CHANNEL_NAME": "#bot", "DISCORD_MESSAGE_TEMPLATE": "`%username%`: %message%", "MINECRAFT_SERVER_RCON_IP": "127.0.0.1", diff --git a/src/Config.ts b/src/Config.ts index 77fefd2..ce59ed2 100644 --- a/src/Config.ts +++ b/src/Config.ts @@ -5,6 +5,7 @@ export interface Config { WEBHOOK_URL: string DISCORD_TOKEN: string DISCORD_CHANNEL_ID: string + DISCORD_CHANNEL_NAME: string DISCORD_MESSAGE_TEMPLATE: string MINECRAFT_SERVER_RCON_IP: string diff --git a/src/Discord.ts b/src/Discord.ts index a0a3498..97722c2 100644 --- a/src/Discord.ts +++ b/src/Discord.ts @@ -1,4 +1,4 @@ -import { Client, Message, TextChannel } from 'discord.js' +import {Client, Message, Snowflake, TextChannel} from 'discord.js' import emojiStrip from 'emoji-strip' import axios from 'axios' @@ -11,26 +11,47 @@ class Discord { config: Config client: Client + channel: Snowflake + constructor (config: Config, onReady?: () => void) { this.config = config this.client = new Client() if (onReady) this.client.once('ready', () => onReady()) this.client.on('message', (message: Message) => this.onMessage(message)) + + this.channel = config.DISCORD_CHANNEL_ID || '' } - async init () { + public async init () { try { await this.client.login(this.config.DISCORD_TOKEN) + if (this.config.DISCORD_CHANNEL_NAME) this.getChannelIdFromName(this.config.DISCORD_CHANNEL_NAME) } catch (e) { console.log('[ERROR] Could not authenticate with Discord: ' + e) if (this.config.DEBUG) console.error(e) } } + private getChannelIdFromName (name: string) { + // remove the # if there is one + if (name.startsWith('#')) name = name.substring(1, name.length) + // @ts-ignore + const channel: TextChannel = this.client.channels.find((c: TextChannel) => c.type === 'text' && c.name === name && !c.deleted) + if (channel) { + this.channel = channel.id + console.log(`[INFO] Found channel #${channel.name} (id: ${channel.id}) in the server "${channel.guild.name}"`) + } else { + console.log(`[INFO] Could not find channel ${name}! Check that the name is correct or use the ID of the channel instead (DISCORD_CHANNEL_ID)!`) + process.exit(1) + } + } + private async onMessage (message: Message) { + // no channel, done + if (!this.channel) return // don't want to check other channels - if (message.channel.id !== this.config.DISCORD_CHANNEL_ID || message.channel.type !== 'text') return + if (message.channel.id !== this.channel || message.channel.type !== 'text') return // if using webhooks, ignore this! if (this.config.USE_WEBHOOKS && message.webhookID) return // if the same user as the bot, ignore diff --git a/src/MinecraftHandler.ts b/src/MinecraftHandler.ts index 20bccf5..0e4e5d7 100644 --- a/src/MinecraftHandler.ts +++ b/src/MinecraftHandler.ts @@ -44,8 +44,10 @@ class MinecraftHandler { const logLineData = data.match(logLineDataRegex) if (!logLineDataRegex.test(data) || !logLineData) { - console.log('[ERROR] Regex could not match the string! Please verify it is correct!') - console.log('Received: "' + data + '", Regex matches lines that start with: "' + this.config.REGEX_SERVER_PREFIX + '"') + if (this.config.DEBUG) { + console.log('[DEBUG] Regex could not match the string:') + console.log('Received: "' + data + '", Regex matches lines that start with: "' + this.config.REGEX_SERVER_PREFIX + '"') + } return null } @@ -164,7 +166,14 @@ class MinecraftHandler { mcPath = (defaultPath ? '/' : '') + path.join(mcPath, '/logs/latest.log') - console.log(` \`tail -F ${mcPath} | grep --line-buffered ": <" | while read x ; do echo -ne $x | curl -X POST -d @- http://${url}:${port}${this.config.WEBHOOK} ; done\``) + let grepMatch = ': <' + if (this.config.SHOW_PLAYER_DEATH || this.config.SHOW_PLAYER_ME || this.config.SHOW_PLAYER_ADVANCEMENT || this.config.SHOW_PLAYER_CONN_STAT) { + grepMatch = this.config.REGEX_SERVER_PREFIX + } + console.log(` \`tail -F ${mcPath} | grep --line-buffered "${grepMatch}" | while read x ; do echo -ne $x | curl -X POST -d @- http://${url}:${port}${this.config.WEBHOOK} ; done\``) + if (grepMatch !== ': <') { + console.log(' Please note that the above command can send a lot of requests to the server. Disable the non-text messages (such as "SHOW_PLAYER_CONN_STAT") to reduce this if necessary.') + } } }) } -- cgit 1.4.1