Skip to content

Commit

Permalink
Filter out unwanted messages when sending from Minecraft to Discord
Browse files Browse the repository at this point in the history
  • Loading branch information
Syntro42 committed Jan 1, 2024
1 parent a668953 commit df51c40
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 5 deletions.
54 changes: 54 additions & 0 deletions assets/special_messages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
[
"joined the game",
"left the game",

"has completed the challenge",
"has made the advancement",
"has reached the goal",

"fell off",
"fell while climbing",
"fell from a high place",
"was doomed to fall",
"fell too far and was finished by",
"was struck by lightning",
"went up in flames",
"walked into fire",
"burned to death",
"was burnt to a crisp",
"tried to swim in lava",
"discovered the floor was lava",
"walked into danger zone due to",
"suffocated in a wall",
"was squished too much",
"was squashed by",
"drowned",
"starved to death",
"was pricked to death",
"walked into a cactus",
"died",
"blew up",
"was blown up by",
"withered away",
"was shot by a's skull",
"was slain by",
"was shot by",
"was fireballed by",
"was pummeled by",
"was killed",
"was impaled",
"hit the ground too hard",
"fell out of the world",
"didn't want to live in the same world as",
"was roasted in dragon breath",
"experienced kinetic energy",
"went off with a bang",
"was poked to death by a sweet berry bush",
"was stung to death",
"froze to death",
"was frozen to death by",
"was skewered by",
"was obliterated by a sonically-charged shriek",
"left the confines of this world",
"Actually, message was too long to deliver fully. Sorry! Here's stripped version: %s"
]
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"format": "prettier --write \"**/*.ts\"",
"lint": "eslint .",
"lint-fix": "yarn lint --fix",
"start": "node .",
"start": "node --disable-warning=ExperimentalWarning .",
"test": "jest --config=tests/jest.config.js"
},
"keywords": [
Expand Down
11 changes: 9 additions & 2 deletions src/bridge.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DiscordMessage, MinecraftMessage } from "./lib/messages.js";
import { Message, TextChannel } from "discord.js";
import { IServer } from "./interfaces.js";
import { MinecraftMessage } from "./lib/messages.js";
import { PacketTooBigError } from "./lib/rcon/packet.js";
import { Rcon } from "./lib/rcon/rcon.js";
import { Tail } from "tail";
Expand Down Expand Up @@ -32,14 +32,21 @@ export class Bridge {

const tail = new Tail(this.serverLogPath);
tail.on("line", (line: string) => {
this.channel.send(line);
this.sendToDiscord(line);
});

tail.on("error", (error: any) => {
console.log(`Error while tailing log file (${this.serverLogPath}): ${error}`);
});
}

async sendToDiscord(line: string): Promise<void> {
const message = await DiscordMessage.filter(line, this.channel);
if (!message) return; // Message does not match what we want to send to Discord

this.channel.send({ content: message, allowedMentions: { parse: ["users", "roles"] } });
}

async sendToMinecraft(message: Message): Promise<void> {
// TODO: Handle errors in send
const minecraftMsg = MinecraftMessage.format(message);
Expand Down
1 change: 1 addition & 0 deletions src/endbot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export class Endbot extends Client {
super({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
],
Expand Down
85 changes: 84 additions & 1 deletion src/lib/messages.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,87 @@
import { Message } from "discord.js";
import { Message, TextChannel, escapeMarkdown } from "discord.js";
import specialMessages from "../../assets/special_messages.json" with { type: "json" };

export class DiscordMessage {
static async filter(line: string, channel: TextChannel): Promise<string | void> {
const regex = /\[Server thread\/INFO\]: (.*)/;
const text = line.match(regex);
if (!text) return; // Filter out messages not part of the INFO log

let message = text[1];
// Remove messages of entities dying
if (
(message.startsWith("Villager") && message.endsWith("'")) ||
message.startsWith("Named entity class_")
)
return;

// Remove messages that aren't from players or special
if (message.startsWith("<")) {
message = await this.formatContent(message, channel);
} else if (!this.isSpecial(message)) {
return;
}

return escapeMarkdown(message);
}

private static async formatContent(message: string, channel: TextChannel): Promise<string> {
if (message.includes("@")) message = await this.formatUsersAndRoles(message, channel);
if (message.includes("#")) message = this.formatChannels(message, channel);
return message;
}

private static async formatUsersAndRoles(
message: string,
channel: TextChannel,
): Promise<string> {
// Members need to be fetched as the cache doesn't always contain all members. Not sure why,
// but the cache can be used for roles and channels just fine (as well as members in the
// MinecraftMessage class)
const members = await channel.guild!.members.fetch();
members.forEach((member) => {
const memberId = "<@" + member.id + ">";
const memberName = "@" + member.displayName;
if (message.includes(memberName)) {
message = message.replaceAll(memberName, memberId);
}
});

const roles = channel.guild!.roles.cache;
roles.forEach((role) => {
const roleId = "<@&" + role.id + ">";
const roleName = "@" + role.name;
if (message.includes(roleName)) {
message = message.replaceAll(roleName, roleId);
}
});

return message;
}

private static formatChannels(message: string, channel: TextChannel): string {
const channels = channel.guild!.channels.cache;
channels.forEach((discordChannel) => {
const channelId = "<#" + discordChannel.id + ">";
const channelName = "#" + discordChannel.name;
if (message.includes(channelName)) {
message = message.replaceAll(channelName, channelId);
}
});

return message;
}

private static isSpecial(message: string): boolean {
for (const phrase of specialMessages) {
if (message.includes(phrase)) {
return true;
}
}

return false;
}
}

export class MinecraftMessage {
static format(message: Message): string {
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
"composite": true,
"resolveJsonModule": true
},
"include": ["**/*"],
"include": ["**/*", "assets/*.json"],
"exclude": ["node_modules", "dist"]
}

0 comments on commit df51c40

Please sign in to comment.