rce.js
Version:
A wrapper for Rust Console Edition (RCE) that allows you to use the websocket and API from G-Portal.
427 lines (378 loc) • 11.7 kB
text/typescript
import type { RustServer } from "../servers/interfaces";
import type { PlayerKillData, WSMessage } from "./interfaces";
import {
playerKillData,
PlayerKillType,
QuickChat,
RCEEvent,
RegularExpressions,
} from "../constants";
import type RCEManager from "../Manager";
import CommandHandler from "../servers/CommandHandler";
const EVENTS = {
event_airdrop: {
name: "Airdrop",
special: false,
},
event_cargoship: {
name: "Cargo Ship",
special: false,
},
event_cargoheli: {
name: "Chinook",
special: false,
},
event_helicopter: {
name: "Patrol Helicopter",
special: false,
},
event_halloween: {
name: "Halloween",
special: true,
},
event_xmas: {
name: "Christmas",
special: true,
},
event_easter: {
name: "Easter",
special: true,
},
};
export default class ConsoleMessagesHandler {
public static handle(
manager: RCEManager,
message: WSMessage,
server: RustServer
) {
const messageArray: string[] =
message.payload.data.consoleMessages.message
?.split("\n")
.filter((e) => e !== "") || [];
if (!server.flags.includes("INIT_LOGS")) {
manager.logger.debug(
`[${server.identifier}] Initial Logs Received: ${messageArray.length}`
);
server.flags.push("INIT_LOGS");
return manager.servers.update(server);
}
let currentCommand;
messageArray.forEach((data) => {
const logMatch = data.match(RegularExpressions.Log);
if (!logMatch) return;
const [, date, content] = logMatch;
const log = content.trim();
if (!log) return;
manager.events.emit(RCEEvent.Message, { server, message: log });
// EVENT: COMMAND_EXECUTING
const commandExecutingMatch = log.match(
RegularExpressions.CommandExecuting
);
if (commandExecutingMatch) {
const cmd = commandExecutingMatch[1];
manager.logger.debug(`[${server.identifier}] Executing Match: ${cmd}`);
manager.events.emit(RCEEvent.ExecutingCommand, {
server,
command: cmd,
});
const command = CommandHandler.get(server.identifier, cmd);
if (command && !command.timestamp) {
manager.logger.debug(
`[${server.identifier}] Command In Queue: ${cmd}`
);
command.timestamp = date;
CommandHandler.add(command);
currentCommand = cmd;
return manager.logger.debug(
`[${server.identifier}] Command Timestamp Added: ${cmd}`
);
}
}
// Check for Command Response
const command = CommandHandler.getQueued(server.identifier, date);
if (command && !log.startsWith("[ SAVE ]")) {
manager.logger.debug(
`[${server.identifier}] Command Response Found: ${command.command}`
);
command.resolve({
ok: true,
response: log,
});
clearTimeout(command.timeout);
CommandHandler.remove(command);
} else if (currentCommand) {
manager.logger.debug(
`[${server.identifier}] Command Response Not Found, Using Other Method: ${currentCommand}`
);
const command = CommandHandler.get(server.identifier, currentCommand);
if (command) {
command.resolve({
ok: true,
response: log,
});
clearTimeout(command.timeout);
CommandHandler.remove(command);
currentCommand = null;
}
}
// EVENT: VENDING_MACHINE_NAME
const vendingMachineNameMatch = log.match(
RegularExpressions.VendingMachineName
);
if (vendingMachineNameMatch) {
manager.events.emit(RCEEvent.VendingMachineName, {
server,
ign: vendingMachineNameMatch[1],
oldName: vendingMachineNameMatch[2],
newName: vendingMachineNameMatch[3],
});
}
// EVENT: QUICK_CHAT
const quickChatMatch = log.match(RegularExpressions.QuickChat);
if (quickChatMatch) {
const types = {
"[CHAT TEAM]": "team",
"[CHAT SERVER]": "server",
"[CHAT LOCAL]": "local",
};
manager.events.emit(RCEEvent.QuickChat, {
server,
type: types[quickChatMatch[1]],
ign: quickChatMatch[3],
message: quickChatMatch[4] as QuickChat,
});
}
// EVENT: PLAYER_SUICIDE
if (log.includes("was suicide by Suicide")) {
const ign = log.split(" was suicide by Suicide")[0];
manager.events.emit(RCEEvent.PlayerSuicide, {
server,
ign,
});
}
// EVENT: PLAYER_RESPAWNED
if (log.includes("has entered the game")) {
const ign = log.split(" [")[0];
const platform = log.includes("[xboxone]") ? "XBL" : "PS";
manager.events.emit(RCEEvent.PlayerRespawned, {
server,
ign,
platform,
});
}
// EVENT: CUSTOM_ZONE_CREATED
const customZoneCreatedMatch = log.match(
RegularExpressions.CustomZoneCreated
);
if (customZoneCreatedMatch) {
manager.events.emit(RCEEvent.CustomZoneCreated, {
server,
zone: customZoneCreatedMatch[1],
});
}
// EVENT: CUSTOM_ZONE_REMOVED
const customZoneRemovedMatch = log.match(
RegularExpressions.CustomZoneRemoved
);
if (customZoneRemovedMatch) {
manager.events.emit(RCEEvent.CustomZoneRemoved, {
server,
zone: customZoneRemovedMatch[1],
});
}
// EVENT: PLAYER_ROLE_ADD
if (log.includes("Added")) {
const playerRoleAddMatch = log.match(RegularExpressions.PlayerRoleAdd);
if (playerRoleAddMatch) {
manager.events.emit(RCEEvent.PlayerRoleAdd, {
server,
admin:
playerRoleAddMatch[1] === "SERVER"
? undefined
: playerRoleAddMatch[1],
ign: playerRoleAddMatch[2],
role: playerRoleAddMatch[3],
});
}
}
// EVENT: PLAYER_ROLE_REMOVE
if (log.includes("Removed")) {
const playerRoleRemoveMatch = log.match(
RegularExpressions.PlayerRoleRemove
);
if (playerRoleRemoveMatch) {
manager.events.emit(RCEEvent.PlayerRoleRemove, {
server,
admin:
playerRoleRemoveMatch[1] === "SERVER"
? undefined
: playerRoleRemoveMatch[1],
ign: playerRoleRemoveMatch[2],
role: playerRoleRemoveMatch[3],
});
}
}
// EVENT: ITEM_SPAWN
const itemSpawnMatch = log.match(RegularExpressions.ItemSpawn);
if (itemSpawnMatch) {
manager.events.emit(RCEEvent.ItemSpawn, {
server,
ign: itemSpawnMatch[1],
item: itemSpawnMatch[3],
quantity: parseInt(itemSpawnMatch[2]),
});
}
// EVENT: NOTE_EDIT
const noteEditMatch = log.match(RegularExpressions.NoteEdit);
if (noteEditMatch) {
const oldContent = noteEditMatch[2].trim().split("\\n")[0];
const newContent = noteEditMatch[3].trim().split("\\n")[0];
if (newContent.length > 0 && oldContent !== newContent) {
manager.events.emit(RCEEvent.NoteEdit, {
server,
ign: noteEditMatch[1],
oldContent,
newContent,
});
}
}
// EVENT: TEAM_CREATE
const teamCreateMatch = log.match(RegularExpressions.TeamCreate);
if (teamCreateMatch) {
manager.events.emit(RCEEvent.TeamCreate, {
server,
id: parseInt(teamCreateMatch[2]),
owner: teamCreateMatch[1],
});
}
// EVENT: TEAM_JOIN
const teamJoinMatch = log.match(RegularExpressions.TeamJoin);
if (teamJoinMatch) {
manager.events.emit(RCEEvent.TeamJoin, {
server,
id: parseInt(teamJoinMatch[3]),
owner: teamJoinMatch[2],
ign: teamJoinMatch[1],
});
}
// EVENT: TEAM_INVITE
const teamInviteMatch = log.match(RegularExpressions.TeamInvite);
if (teamInviteMatch) {
manager.events.emit(RCEEvent.TeamInvite, {
server,
id: parseInt(teamInviteMatch[3]),
owner: teamInviteMatch[1],
ign: teamInviteMatch[2],
});
}
// EVENT: TEAM_LEAVE
const teamLeaveMatch = log.match(RegularExpressions.TeamLeave);
if (teamLeaveMatch) {
manager.events.emit(RCEEvent.TeamLeave, {
server,
id: parseInt(teamLeaveMatch[3]),
owner: teamLeaveMatch[2],
ign: teamLeaveMatch[1],
});
}
// EVENT: TEAM_INVITE_CANCEL
const teamInviteCancelMatch = log.match(
RegularExpressions.TeamInviteCancel
);
if (teamInviteCancelMatch) {
manager.events.emit(RCEEvent.TeamInviteCancel, {
server,
id: parseInt(teamInviteCancelMatch[3]),
owner: teamInviteCancelMatch[2],
ign: teamInviteCancelMatch[1],
});
}
// EVENT: TEAM_PROMOTED
const teamPromotedMatch = log.match(RegularExpressions.TeamPromoted);
if (teamPromotedMatch) {
manager.events.emit(RCEEvent.TeamPromoted, {
server,
id: parseInt(teamPromotedMatch[3]),
oldOwner: teamPromotedMatch[1],
newOwner: teamCreateMatch[2],
});
}
// EVENT: KIT_SPAWN
const kitSpawnMatch = log.match(RegularExpressions.KitSpawn);
if (kitSpawnMatch) {
manager.events.emit(RCEEvent.KitSpawn, {
server,
ign: kitSpawnMatch[1],
kit: kitSpawnMatch[2],
});
}
// EVENT: KIT_GIVE
const kitGiveMatch = log.match(RegularExpressions.KitGive);
if (kitGiveMatch) {
manager.events.emit(RCEEvent.KitGive, {
server,
ign: kitGiveMatch[2],
admin: kitGiveMatch[1],
kit: kitGiveMatch[3],
});
}
// EVENT: SPECIAL_EVENT_SET
const specialEventSetMatch = log.match(
RegularExpressions.SpecialEventSet
);
if (specialEventSetMatch) {
manager.events.emit(RCEEvent.SpecialEventSet, {
server,
event: specialEventSetMatch[1] as any,
});
}
// EVENT: EVENT_START
if (log.startsWith("[event]")) {
for (const [key, options] of Object.entries(EVENTS)) {
if (log.includes(key)) {
manager.events.emit(RCEEvent.EventStart, {
server,
event: options.name as any,
special: options.special,
});
}
}
}
// EVENT: PLAYER_KILL
if (log.includes(" was killed by ")) {
const [victim, killer] = log
.split(" was killed by ")
.map((str) => str.trim());
const victimData = this.getKill(victim);
const killerData = this.getKill(killer);
manager.events.emit(RCEEvent.PlayerKill, {
server,
victim: victimData,
killer: killerData,
});
}
});
}
private static getKill(ign: string): PlayerKillData {
const data = playerKillData.find((e) => e.id === ign.toLowerCase());
if (data) {
return {
id: ign,
name: data.name,
type: data.type,
};
}
if (Number(ign)) {
return {
id: ign,
name: "Scientist",
type: PlayerKillType.Npc,
};
}
return {
id: ign,
name: ign,
type: PlayerKillType.Player,
};
}
}