123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- const presence = new Presence({
- clientId: "754771926857285782",
- });
- const enum Assets {
- Day = "https://cdn.rcd.gg/PreMiD/websites/T/Town%20of%20Salem/assets/0.png",
- Discussion = "https://cdn.rcd.gg/PreMiD/websites/T/Town%20of%20Salem/assets/1.png",
- Night = "https://cdn.rcd.gg/PreMiD/websites/T/Town%20of%20Salem/assets/2.png",
- Voting = "https://cdn.rcd.gg/PreMiD/websites/T/Town%20of%20Salem/assets/3.png",
- Judgement = "https://cdn.rcd.gg/PreMiD/websites/T/Town%20of%20Salem/assets/4.png",
- Defense = "https://cdn.rcd.gg/PreMiD/websites/T/Town%20of%20Salem/assets/5.png",
- Logo = "https://cdn.rcd.gg/PreMiD/websites/T/Town%20of%20Salem/assets/logo.jpg",
- }
- enum GameState {
- Night = "night",
- Day = "day",
- End = "end",
- AfterGame = "afterGame",
- PreGame = "preGame",
- }
- enum GameType {
- Classic = "Classic",
- Ranked = "Ranked",
- }
- interface GameData {
- scene: string;
- page: string;
- day: number;
- gameMode: string;
- state: GameState;
- }
- interface Log {
- content: string;
- id: number;
- }
- const gameTypeNames: Record<string, string> = {
- RankedPractice: "Ranked Practice",
- RapidMode: "Custom Rapid Mode",
- DraculasPalace: "Dracula's Palace",
- ClassicTownTraitor: "Town Traitor",
- CovenClassic: "Classic Coven",
- CovenRankedPractice: "Coven Ranked Practice",
- CovenMafia: "Mafia Returns",
- CovenCustom: "Custom Coven",
- CovenTownTraitor: "Coven Town Traitor",
- CovenAllAny: "Coven All Any",
- AllAny: "All Any",
- },
- oldState: GameData = {
- scene: "BigLogin",
- page: "",
- day: 1,
- gameMode: GameType.Classic,
- state: GameState.Day,
- },
- currentState = Object.assign({}, oldState);
- let elapsed = Math.round(Date.now() / 1000),
- lastId: number = null;
- function handleLog(log: string) {
- if (
- log.startsWith("Switched to ") ||
- log.startsWith("Switched additively to")
- ) {
- const scene = log
- .match(/^Switched(?: additively)? to(?: scene)? (.*) Scene/m)[1]
- .trim();
- currentState.scene = scene;
- if (scene === "BigPreGame") currentState.state = GameState.PreGame;
- } else if (log.startsWith("Entered HomeSceneController.ShowView()")) {
- currentState.page = log
- .match(
- /^Entered HomeSceneController.ShowView\(\) - View passed in: (.*)$/m
- )[1]
- .trim();
- } else if (log.startsWith("Entered ")) {
- switch (log.match(/^Entered (.*)$/m)[1].trim()) {
- case "HandleStartRanked": {
- currentState.scene = "BigLobby";
- currentState.gameMode = GameType.Ranked;
- break;
- }
- case "HandleOnLeaveRankedQueue": {
- currentState.scene = "BigHome";
- currentState.gameMode = GameType.Classic;
- break;
- }
- }
- } else if (log.startsWith("Creating lobby:"))
- currentState.gameMode = log.match(/^Creating lobby: (.*?) \|/)[1];
- else if (/\[Network\] <color=.*?>\[Received\] <b>/.test(log)) {
- const action = log.match(
- /\[Network\] <color=.*?>\[Received\] <b>(.*?)<\/b>/
- )[1];
- switch (action) {
- case "PickNames":
- case "RoleAndPosition": {
- currentState.page = action;
- currentState.state = GameState.PreGame;
- break;
- }
- case "StartFirstDay": {
- currentState.day = 1;
- currentState.state = GameState.Day;
- currentState.page = "StartDiscussion";
- break;
- }
- case "StartDay": {
- currentState.day++;
- currentState.state = GameState.Day;
- currentState.page = "";
- break;
- }
- case "StartNight": {
- currentState.state = GameState.Night;
- currentState.page = "";
- break;
- }
- case "FullMoonNight":
- case "StartDiscussion":
- case "StartDefense":
- case "StartJudgement":
- case "StartVoting":
- case "WhoDiedAndHow": {
- currentState.page = action;
- break;
- }
- case "SomeoneHasWon": {
- currentState.state = GameState.End;
- break;
- }
- }
- }
- }
- /**
- * Overwrites the default console.log to be able to read the logs.
- * Built-in readLogs causes performance problems, as hundreds of logs can be created in half a second.
- * It is also hard to determine which logs have not been read yet.
- */
- const injectedLoggerScript = document.createElement("script");
- injectedLoggerScript.type = "text/javascript";
- injectedLoggerScript.textContent = `
- {
- let counter = 0;
- console.stdlog = console.log.bind(console);
- console.logs = [];
- console.log = function() {
- const log = arguments[0];
- if (/^Switched |^Entered |^Creating |\\[Network\\] <color=.*?>\\[Received\\] <b>/.test(log)) {
- console.logs.push({
- content: log,
- id: counter,
- });
- counter++;
- if (counter > 10000) counter = 0;
- }
- while (console.logs.length > 100) console.logs.shift();
- console.stdlog.apply(console, arguments);
- };
- }
- `;
- document.head.appendChild(injectedLoggerScript);
- setInterval(async () => {
- const logs: Log[] = await presence.getPageletiable('console"]["logs');
- let lastUnreadLogIndex = 0;
- for (let i = logs.length - 1; i >= 0; i--) {
- if (logs[i].id === lastId) {
- lastUnreadLogIndex = i + 1;
- break;
- }
- }
- for (let i = lastUnreadLogIndex; i < logs.length; i++)
- handleLog(logs[i].content);
- if (logs.length > 0) lastId = logs[logs.length - 1].id;
- }, 1000);
- presence.on("UpdateData", () => {
- const presenceData: PresenceData = {
- largeImageKey: Assets.Logo,
- };
- if (window.location.pathname !== "/TownOfSalem/") {
- presenceData.details = "Browsing BlankMediaGames";
- presenceData.state = document.title;
- presenceData.startTimestamp = elapsed;
- } else {
- if (oldState.scene !== currentState.scene)
- elapsed = Math.round(Date.now() / 1000);
- presenceData.startTimestamp = elapsed;
- Object.assign(oldState, currentState);
- switch (currentState.scene) {
- case "BigLogin": {
- presenceData.details = "Logging in";
- break;
- }
- case "BigHome": {
- switch (currentState.page) {
- case "GameModeSelect": {
- presenceData.details = "Selecting Game Mode";
- break;
- }
- case "Customization": {
- presenceData.details = "Customizing Character";
- break;
- }
- case "Party": {
- presenceData.details = "In a Party";
- break;
- }
- default: {
- presenceData.details = "Browsing Main Menu";
- presenceData.state = currentState.page;
- }
- }
- break;
- }
- case "BigLobby": {
- presenceData.details = "Waiting in a Lobby";
- presenceData.state =
- gameTypeNames[currentState.gameMode] ?? currentState.gameMode;
- break;
- }
- case "BigPreGame": {
- presenceData.details = "Loading Game";
- presenceData.state =
- gameTypeNames[currentState.gameMode] ?? currentState.gameMode;
- break;
- }
- case "BigGame": {
- presenceData.details = `Playing a ${
- gameTypeNames[currentState.gameMode] ?? currentState.gameMode
- } Game`;
- switch (currentState.state) {
- case GameState.PreGame: {
- switch (currentState.page) {
- case "PickNames": {
- presenceData.state = "Choosing Names";
- break;
- }
- case "RoleAndPosition": {
- presenceData.state = "Getting a Role";
- break;
- }
- }
- break;
- }
- case GameState.Day: {
- presenceData.smallImageKey = Assets.Day;
- switch (currentState.page) {
- case "StartDiscussion": {
- presenceData.state = `Discussion | Day ${currentState.day}`;
- presenceData.smallImageKey = Assets.Discussion;
- break;
- }
- case "StartVoting": {
- presenceData.state = `Voting | Day ${currentState.day}`;
- presenceData.smallImageKey = Assets.Voting;
- break;
- }
- case "WhoDiedAndHow": {
- presenceData.state = `Viewing a Death | Day ${currentState.day}`;
- break;
- }
- case "StartDefense": {
- presenceData.state = `Defense | Day ${currentState.day}`;
- presenceData.smallImageKey = Assets.Defense;
- break;
- }
- case "StartJudgement": {
- presenceData.state = `Judgement | Day ${currentState.day}`;
- presenceData.smallImageKey = Assets.Judgement;
- break;
- }
- default: {
- presenceData.state = `Day ${currentState.day}`;
- }
- }
- break;
- }
- case GameState.Night: {
- presenceData.smallImageKey = Assets.Night;
- if (currentState.page === "FullMoonNight")
- presenceData.state = `Night ${currentState.day} (Full Moon)`;
- else presenceData.state = `Night ${currentState.day}`;
- break;
- }
- case GameState.End: {
- presenceData.state = "Viewing End Screen";
- break;
- }
- }
- break;
- }
- case "BigEndGame": {
- presenceData.details = `Playing a ${
- gameTypeNames[currentState.gameMode] ?? currentState.gameMode
- } Game`;
- presenceData.state = "Viewing After Game Screen";
- break;
- }
- }
- }
- if (presenceData.details) presence.setActivity(presenceData);
- else presence.setActivity();
- });
|