Skip to content

Commit

Permalink
Client: Improve parser for server message
Browse files Browse the repository at this point in the history
  • Loading branch information
Dirain1700 committed Jul 29, 2023
1 parent 99bda34 commit ee53eff
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 17 deletions.
48 changes: 32 additions & 16 deletions src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ export class Client extends EventEmitter {
this.ws.on("message", (message: ws.MessageEvent) => {
// This should be allowed because message.data is probably Buffer or String
// eslint-disable-next-line @typescript-eslint/no-base-to-string
this.onMessage(message.data.toString());
this.onMessage(message.toString());
});

this.ws.on("close", () => {
Expand Down Expand Up @@ -1060,19 +1060,27 @@ export class Client extends EventEmitter {
case "chat":
case "c": {
if (!isRoomNotEmp(room)) return;
if (!event[0] || !Tools.toId(event[0])) break;
if (!event[0]) break;
room = this.rooms.cache.get(room.id) ?? room;
const author = this.getUser(event[0]!) ?? (await this.fetchUser(event[0]!)),
content = event.slice(1).join("|"),
message = new Message<Room>({
author: author,
content: content,
type: "Room",
target: room,
raw: rawMessage,
time: Date.now(),
client: this,
} as MessageInput<Room>);
const content = event.slice(1).join("|");
if (content.startsWith("/log")) {
const logDetails = Tools.getLogDetails(content);
if (logDetails.staff) event[0] = logDetails.staff;
if (logDetails.room && logDetails.editRoom)
room = await this.fetchRoom(room.id).catch(() => this.getRoom(room!.id)!);
if (logDetails.isPunish || logDetails.action === "promote" || logDetails.action === "demote")
void (await this.fetchUser(logDetails.target));
}
const author = this.getUser(event[0]!) ?? (await this.fetchUser(event[0]!));
const message = new Message<Room>({
author: author,
content: content,
type: "Room",
target: room,
raw: rawMessage,
time: Date.now(),
client: this,
} as MessageInput<Room>);
if (!this.user) return;
for (const element of this.PromisedChat) {
if (element.id === message.target.roomid && this.user.userid === message.author.userid) {
Expand All @@ -1088,11 +1096,19 @@ export class Client extends EventEmitter {
if (!isRoomNotEmp(room)) return;
room = this.rooms.cache.get(room.id);
if (!isRoomNotEmp(room)) return;
const content = event.slice(2).join("|");
if (content.startsWith("/log")) {
const logDetails = Tools.getLogDetails(content);
if (logDetails.staff) event[1] = logDetails.staff;
if (logDetails.room && logDetails.editRoom)
room = await this.fetchRoom(room.id).catch(() => this.getRoom(room!.id)!);
if (logDetails.isPunish || logDetails.action === "promote" || logDetails.action === "demote")
void (await this.fetchUser(logDetails.target));
}
const by = this.getUser(event[1]!) ?? (await this.fetchUser(event[1]!)),
value = event.slice(2).join("|"),
message = new Message<Room>({
author: by,
content: value,
content,
type: "Room",
target: room,
raw: rawMessage,
Expand All @@ -1108,7 +1124,7 @@ export class Client extends EventEmitter {
}
}
this.emit(Events.MESSAGE_CREATE, message);
if (this.options.prefix && value.startsWith(this.options.prefix)) this.emit(Events.COMMAND_EMIT);
if (this.options.prefix && content.startsWith(this.options.prefix)) this.emit(Events.COMMAND_EMIT);
break;
}

Expand Down
125 changes: 124 additions & 1 deletion src/Tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import { cloneDeep } from "lodash";

import type { ModchatLevel } from "../types/Room";
import type { ILogMessageDetails } from "../types/Tools";
import type { AuthLevel, GroupSymbol, GroupNames } from "../types/UserGroups";

const MODCHAT_REGEX =
/<div class="broadcast-red"><strong>Moderated chat was set to (?<level>(unlocked|autoconfirmed|whitelist|trusted|&|#|★|\*|@|%|☆|§|\+|\^))!<\/strong><br \/>Only users of rank (unlocked|autoconfirmed|whitelist|trusted|&|#|★|\*|@|%|☆|§|\+|\^) and higher can talk.<\/div>/;
('<div class="broadcast-red"><strong>Moderated chat was set to ^!</strong><br />Only users of rank ^ and higher can talk.</div>');
const MODCHAT_DISABLE_STRING =
'<div class="broadcast-blue"><strong>Moderated chat was disabled!</strong><br />Anyone may talk now.</div>';

Expand All @@ -19,6 +19,24 @@ const MODJOIN_DISABLE_STRING =
'<div class="broadcast-blue"><strong>This room is no longer invite only!</strong><br />Anyone may now join.</div>';
const MODJOIN_REGEX =
/<div class="broadcast-red"><strong>This room is now invite only!<\/strong><br \/>Users must be rank (?<level>(unlocked|autoconfirmed|whitelist|trusted|&|#|★|\*|@|%|☆|§|\+|\^)) or invited with <code>\/invite<\/code> to join<\/div>/;
const clearTextRegex =
/(?<target>^.{2,20})'s messages were cleared from (?<room>.{2,20}) by (?<staff>.{2,20})\.( \((?<reason>.*)\))?/;
const clearLinesRegex =
/(?<lines>^\d{1,3}) of (?<target>.{2,20})'s messages were cleared from (?<room>.{2,20}) by (?<staff>.{2,20})\.( \((?<reason>.*)\))?/;
const warnRegex = /(?<target>.{2,20}) was warned by (?<staff>.{2,20})\.( \((?<reason>.*)\))?/;
const roomBanRegex =
/(?<target>^.{2,20}) was banned (for (?<duration>a week) )?from (?<room>.{2,20}) by (?<staff>.{2,20})\.( \((?<reason>.*)\))?/;
const blackListRegex =
/(?<target>^.{2,20}) was blacklisted from (?<room>.{2,20}) by (?<staff>.{2,20})(for (?<duration>ten years) )?\.( \((?<reason>.*)\))?/;
const globalBanRegex = /(?<target>^.{2,20}) was globally banned by (?<staff>.{2,20})\.\((?<reason>.*)\)/;
const lockRegex =
/(?<target>^.{2,20}) was locked from talking (for (?<duration>a week|a month) )?by (?<staff>.{2,20})\.( \((?<reason>.*)\))?/;
const muteRegex =
/(?<target>^.{2,20}) was muted by (?<staff>.{2,20}) for (?<duration>(7 minutes|1 hour))\.( \((?<reason>.*)\))?/;
const promoteRegex =
/(?<target>^.{2,20}) was ((promoted to (?<auth>(Room|Global) (Prize Winner|Voice|Bot|Driver|Moderator)))|appointed to Room Owner) by (?<staff>.{2,20})\./;
const demoteRegex =
/\((?<target>.{2,20}) was demoted to (?<auth>(Room|Global) (regular user|Prize Winner|Voice|Bot|Driver|Moderator)) by (?<staff>.{2,20})\.\)/;

const AND = "&";
const LESS_THAN = "<";
Expand Down Expand Up @@ -236,4 +254,109 @@ export class Tools {
static clone<T>(obj: T): T {
return cloneDeep(obj);
}

static getLogDetails(message: string) {
const logDetails: ILogMessageDetails = {
target: "",
staff: "",
action: "",
isPunish: false,
editRoom: false,
};

/* eslint-disable @typescript-eslint/no-non-null-assertion */
if (message.match(clearLinesRegex)) {
logDetails.isPunish = true;
logDetails.editRoom = false;
const { lines, target, room, staff, reason } = message.match(clearLinesRegex)!.groups ?? {};
logDetails.lines = parseInt(this.toId(lines!));
logDetails.target = target!;
logDetails.room = room;
logDetails.staff = staff!;
logDetails.reason = reason;
logDetails.action = "cleartext";
} else if (message.match(clearTextRegex)) {
logDetails.isPunish = true;
logDetails.editRoom = false;
const { target, room, staff, reason } = message.match(clearTextRegex)!.groups ?? {};
logDetails.target = target!;
logDetails.room = room;
logDetails.staff = staff!;
logDetails.reason = reason;
logDetails.action = "cleartext";
} else if (message.match(warnRegex)) {
logDetails.isPunish = true;
logDetails.editRoom = false;
const { target, staff, reason } = message.match(warnRegex)!.groups ?? {};
logDetails.target = target!;
logDetails.staff = staff!;
logDetails.reason = reason;
logDetails.action = "warn";
} else if (message.match(roomBanRegex)) {
logDetails.isPunish = true;
logDetails.editRoom = false;
const { target, duration, room, staff, reason } = message.match(roomBanRegex)!.groups ?? {};
logDetails.target = target!;
logDetails.room = room;
logDetails.duration = duration;
logDetails.staff = staff!;
logDetails.reason = reason;
logDetails.action = "roomban";
} else if (message.match(blackListRegex)) {
logDetails.isPunish = true;
logDetails.editRoom = false;
const { target, duration, room, staff, reason } = message.match(blackListRegex)!.groups ?? {};
logDetails.target = target!;
logDetails.room = room;
logDetails.duration = duration ?? "a year";
logDetails.staff = staff!;
logDetails.reason = reason;
logDetails.action = "blacklist";
} else if (message.match(globalBanRegex)) {
logDetails.isPunish = true;
logDetails.editRoom = false;
const { target, staff, reason } = message.match(lockRegex)!.groups ?? {};
logDetails.target = target!;
logDetails.duration = "7 days";
logDetails.staff = staff!;
logDetails.reason = reason;
logDetails.action = "globalban";
} else if (message.match(lockRegex)) {
logDetails.isPunish = true;
logDetails.editRoom = false;
const { target, duration, staff, reason } = message.match(lockRegex)!.groups ?? {};
logDetails.target = target!;
logDetails.duration = duration ?? "2 days";
logDetails.staff = staff!;
logDetails.reason = reason;
logDetails.action = "lock";
} else if (message.match(muteRegex)) {
logDetails.isPunish = true;
logDetails.editRoom = true;
const { target, duration, staff, reason } = message.match(muteRegex)!.groups ?? {};
logDetails.target = target!;
logDetails.duration = duration;
logDetails.staff = staff!;
logDetails.reason = reason;
logDetails.action = "mute";
} else if (message.match(promoteRegex)) {
logDetails.isPunish = false;
logDetails.editRoom = true;
const { target, auth, staff } = message.match(promoteRegex)!.groups ?? {};
logDetails.target = target!;
logDetails.auth = auth;
logDetails.staff = staff!;
logDetails.action = "promote";
} else if (message.match(demoteRegex)) {
logDetails.isPunish = false;
logDetails.editRoom = true;
const { target, auth, staff } = message.match(demoteRegex)!.groups ?? {};
logDetails.target = target!;
logDetails.auth = auth;
logDetails.staff = staff!;
logDetails.action = "demote";
}
return logDetails;
/* eslint-enable */
}
}
12 changes: 12 additions & 0 deletions types/Tools.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export interface ILogMessageDetails {
target: string;
staff: string;
action: string;
isPunish: boolean;
editRoom: boolean;
lines?: number;
duration?: string;
auth?: string;
room?: string;
reason?: string;
}

0 comments on commit ee53eff

Please sign in to comment.