[Linux-only] basically bloxstap for sober

removed regretevator due to floor number not being displayed in bloxstraprpc

-292
-165
src/features/regretevator-daily-challenge.ts
··· 1 - import { 2 - activityWatcher, 3 - bloxstraprpc, 4 - PluginEventEmitter, 5 - } from "../lib/Constants"; 6 - import path from "path"; 7 - import { exec } from "child_process"; 8 - import { GetUniverseId } from "../lib/RobloxAPI"; 9 - import fs from "fs"; 10 - import os from "os"; 11 - 12 - // TODO: find a way to detect the daily challenge has already been done, to disable this func. 13 - 14 - let regretevator: boolean = false; 15 - let floorNumStart = 999999; 16 - let floorNumEnd = 999999; 17 - let numFloorsGoal = 50; 18 - let numFloorsDeath = 5; 19 - let numFloorsDead = 0; 20 - let challengeDone: boolean = false; 21 - let dead: boolean = false; 22 - let activeFloorCount = 0; 23 - 24 - function writeState(floors: number) { 25 - // write json to ~/.regretevator-challenge-state 26 - // only if: date is not today or the floor count is less than 25 27 - const stateFilePath = path.join( 28 - os.homedir(), 29 - ".regretevator-challenge-state" 30 - ); 31 - 32 - const today = new Date().toISOString().split("T")[0]; 33 - const writeState = (floors2: number, date2: string) => { 34 - if (date2 !== today || floors2 < 25) { 35 - const state = { floors, today }; 36 - console.log( 37 - "[RegretevatorDailyChallenge]", 38 - `Writing challenge state file: ${today} - ${floors} floors` 39 - ); 40 - fs.writeFileSync(stateFilePath, JSON.stringify(state, null, 2)); 41 - } 42 - }; 43 - 44 - if (fs.existsSync(stateFilePath)) { 45 - const state = JSON.parse(fs.readFileSync(stateFilePath, "utf-8")); 46 - const { floors: savedFloors, date: savedDate } = state; 47 - writeState(savedFloors, savedDate); 48 - } else { 49 - writeState(floors, today); 50 - } 51 - } 52 - 53 - function getProgressPercentage(current: number, goal: number): number { 54 - const percentage = (current / goal) * 100; 55 - return Math.min(100, Math.max(0, Number(percentage.toFixed(2)))); 56 - } 57 - 58 - bloxstraprpc.aw!.BloxstrapRPCEvent.on("OnGameJoin", () => { 59 - regretevator = false; 60 - floorNumStart = 999999; 61 - floorNumEnd = 999999; 62 - numFloorsGoal = 50; 63 - numFloorsDead = 0; 64 - challengeDone = false; 65 - dead = false; 66 - activeFloorCount = 0; 67 - (process as any).REGRETEVATOR_DAILY_CHALLENGE_ACTIVE = false; 68 - console.log("[RegretevatorDailyChallenge]", `Detected OnGameJoin`); 69 - }); 70 - 71 - (process as any).REGRETEVATOR_DAILY_CHALLENGE_ACTIVE = false; 72 - 73 - PluginEventEmitter.on("SetRichPresence", async (data: any) => { 74 - const isRegretevator = 75 - (await GetUniverseId(activityWatcher.ActivityPlaceId)) === 76 - (await GetUniverseId(4972273297)); 77 - 78 - if (isRegretevator) { 79 - if (!regretevator) { 80 - regretevator = true; 81 - (process as any).REGRETEVATOR_DAILY_CHALLENGE_ACTIVE = 82 - !challengeDone; 83 - } 84 - if (challengeDone) return; 85 - try { 86 - if ( 87 - bloxstraprpc._stashedRPCMessage?.largeImage?.hoverText === 88 - "THE REGRET ELEVATOR" && 89 - bloxstraprpc._stashedRPCMessage?.smallImage?.hoverText === 90 - "The Axolotl Sun" 91 - ) { 92 - if ((data.state as string).match(/^Floor streak ([0-9]+)$/)) { 93 - const streak = Number( 94 - (data.state as string).replace(/[a-zA-Z ]*/g, "") 95 - ); 96 - if (floorNumStart === 999999) { 97 - floorNumStart = streak; 98 - floorNumEnd = streak + numFloorsGoal; 99 - console.log( 100 - "[RegretevatorDailyChallenge]", 101 - `Detected Regretevator, streak ${floorNumStart}, target streak ${floorNumEnd}` 102 - ); 103 - exec( 104 - `notify-send -a "tuxstrap" -u low -h int:value:0 "Regretevator" "Challenge: Survive ${numFloorsGoal} floors"` 105 - ); 106 - return; 107 - } 108 - activeFloorCount = streak - floorNumStart + 1; 109 - writeState(activeFloorCount); 110 - if (activeFloorCount === numFloorsGoal) { 111 - challengeDone = true; 112 - (process as any).REGRETEVATOR_DAILY_CHALLENGE_ACTIVE = false; 113 - exec( 114 - `notify-send -a "tuxstrap" -u low -h int:value:100 "Regretevator" "You survived ${numFloorsGoal} floors.\nCongrats! :3"` 115 - ); 116 - console.log( 117 - "[RegretevatorDailyChallenge]", 118 - `Finished challenge, floor streak: ${numFloorsGoal}` 119 - ); 120 - return; 121 - } 122 - console.log( 123 - "[RegretevatorDailyChallenge]", 124 - `On streak ${streak}, active streak ${activeFloorCount}/${numFloorsGoal}` 125 - ); 126 - exec( 127 - `notify-send -a "tuxstrap" -u low -h int:value:${getProgressPercentage( 128 - activeFloorCount, 129 - numFloorsGoal 130 - )} "Regretevator" "Streak ${streak} - ${activeFloorCount}/${numFloorsGoal}"` 131 - ); 132 - } else if ((data.state as string) === "Going up!") { 133 - // exec(`notify-send -a "tuxstrap" -u low "Regretevator" "Going Up!"`); 134 - } else if ((data.state as string) === "Lounging in the lobby") { 135 - if (!dead) { 136 - floorNumEnd += numFloorsDeath; 137 - numFloorsDead++; 138 - numFloorsGoal += numFloorsDeath; 139 - console.log("[RegretevatorDailyChallenge]", `Player died`); 140 - exec( 141 - `notify-send -a "tuxstrap" -u low -h int:value:${getProgressPercentage( 142 - activeFloorCount, 143 - numFloorsGoal 144 - )} "Regretevator" "haha im making you do ${numFloorsDeath} more floors >:3"` 145 - ); 146 - } 147 - } else if ((data.state as string) === "In the elevator") { 148 - dead = false; 149 - } 150 - } 151 - } catch (e_) {} 152 - } else { 153 - floorNumStart = 999999; 154 - regretevator = false; 155 - (process as any).REGRETEVATOR_DAILY_CHALLENGE_ACTIVE = false; 156 - /* 157 - exec( 158 - `notify-send -a "tuxstrap" -u low -h int:value:${getProgressPercentage( 159 - activeFloorCount, 160 - numFloorsGoal 161 - )} "Regretevator" "BRO YOU AIN'T EVEN FINISH 25 FLOORS BRUH"` 162 - ); 163 - */ 164 - } 165 - });
-48
src/features/regretevator-notifications.ts
··· 1 - import { 2 - activityWatcher, 3 - bloxstraprpc, 4 - PluginEventEmitter, 5 - } from "../lib/Constants"; 6 - import { exec } from "child_process"; 7 - import { GetUniverseId } from "../lib/RobloxAPI"; 8 - 9 - let regretevator: boolean = false; 10 - 11 - PluginEventEmitter.on("SetRichPresence", async (data: any) => { 12 - const isRegretevator = 13 - (await GetUniverseId(activityWatcher.ActivityPlaceId)) === 14 - (await GetUniverseId(4972273297)); 15 - // console.log("IsRegretevator",isRegretevator,data) 16 - const challengeActive = 17 - (process as any).REGRETEVATOR_DAILY_CHALLENGE_ACTIVE || false; 18 - if (challengeActive === true) return; 19 - if (isRegretevator) { 20 - if (!regretevator) { 21 - regretevator = true; 22 - exec(`notify-send -a "tuxstrap" -u low "Regretevator" "uhmmm...."`); 23 - } 24 - try { 25 - if ( 26 - bloxstraprpc._stashedRPCMessage?.largeImage?.hoverText === 27 - "THE REGRET ELEVATOR" && 28 - bloxstraprpc._stashedRPCMessage?.smallImage?.hoverText === 29 - "The Axolotl Sun" 30 - ) { 31 - if ((data.state as string).match(/^On Floor ([0-9]+)$/)) { 32 - const f = (data.state as string).replace(/[a-zA-Z ]*/g, ""); 33 - exec( 34 - `notify-send -a "tuxstrap" -u low "Regretevator" "On Floor ${f}"` 35 - ); 36 - } else if ((data.state as string) === "Going up!") { 37 - exec( 38 - `notify-send -a "tuxstrap" -u low "Regretevator" "Going Up!"` 39 - ); 40 - } else if ((data.state as string) === "Lounging in the lobby") { 41 - // nothing 42 - } 43 - } 44 - } catch (e_) {} 45 - } else { 46 - regretevator = false; 47 - } 48 - });
-75
src/features/regretevator-waybar.ts
··· 1 - import { 2 - activityWatcher, 3 - bloxstraprpc, 4 - PluginEventEmitter, 5 - } from "../lib/Constants"; 6 - import { GetUniverseId } from "../lib/RobloxAPI"; 7 - import { rmSync, writeFileSync } from "fs"; 8 - import { homedir } from "os"; 9 - 10 - function writeState(data: string) { 11 - writeFileSync(`/tmp/.regretevator_state`, data); 12 - } 13 - 14 - let isInitalLaunch = true; 15 - let lastFloorNum = "0"; 16 - 17 - activityWatcher.BloxstrapRPCEvent.on("OnGameLeave", () => { 18 - isInitalLaunch = true; 19 - lastFloorNum = "0"; 20 - try { 21 - rmSync(`/tmp/.regretevator_state`); 22 - } catch { } 23 - }); 24 - 25 - PluginEventEmitter.on("SetRichPresence", async (data: any) => { 26 - const isRegretevator = 27 - (await GetUniverseId(activityWatcher.ActivityPlaceId)) == 28 - (await GetUniverseId(4972273297)); 29 - // console.log("IsRegretevator",isRegretevator,data) 30 - if (isRegretevator) { 31 - try { 32 - if ( 33 - bloxstraprpc._stashedRPCMessage?.largeImage?.hoverText === 34 - "THE REGRET ELEVATOR" && 35 - bloxstraprpc._stashedRPCMessage?.smallImage?.hoverText === 36 - "The Axolotl Sun" 37 - ) { 38 - if ((data.state as string).match(/^On Floor ([0-9]+)$/)) { 39 - const f = (data.state as string).replace(/[a-zA-Z ]*/g, ""); 40 - lastFloorNum = f; 41 - writeState(`{"text":"ý ${f}","tooltip":"On Floor ${f}"}`); 42 - } else if ( 43 - (data.state as string).match(/^Currently spectating (.*)$/) 44 - ) { 45 - const f = (data.state as string).replace( 46 - /^Currently spectating /g, 47 - "" 48 - ); 49 - // let nextFloorNum = "0"; 50 - // try { nextFloorNum = Number(lastFloorNum)+1 } catch {}; 51 - writeState(`{"text":"ý ${f}","tooltip":"Spectating ${f}"}`); 52 - } else if ((data.state as string) === "Going up!") { 53 - writeState( 54 - `{"text":"ý ","tooltip":"Floor ${lastFloorNum}  ${Number(lastFloorNum) + 1 55 - }"}` 56 - ); 57 - } else if ((data.state as string) === "Lounging in the lobby") { 58 - writeState(`{"text":"ý ","tooltip":"In Lobby"}`); 59 - } else { 60 - if (isInitalLaunch) { 61 - isInitalLaunch = false; 62 - writeState( 63 - `{"text":"ý","tooltip":"Playing Regretevator"}` 64 - ); 65 - } else { 66 - writeState( 67 - `{"text":"ý ","tooltip":"Floor ${lastFloorNum}  ${Number(lastFloorNum) + 1 68 - }"}` 69 - ); 70 - } 71 - } 72 - } 73 - } catch (e_) { } 74 - } 75 - });
-4
src/index.ts
··· 19 19 import { updateSoberConfigWithFeatures } from "./lib/SoberConfigManager"; 20 20 import { runSettingsManager } from "./lib/TuxstrapManager"; 21 21 22 - // Env 23 - 24 - (process as any).REGRETEVATOR_DAILY_CHALLENGE_ACTIVE = false; 25 - 26 22 // console.log(textSync("TuxStrap")); 27 23 const program = new Command("tuxstrap"); 28 24