tangled
alpha
login
or
join now
kris.darkworld.download
/
tuxstrap
0
fork
atom
[Linux-only] basically bloxstap for sober
0
fork
atom
overview
issues
pulls
pipelines
update
OCbwoy3
1 year ago
ec50dc1d
cee21af5
+41
-18
6 changed files
expand all
collapse all
unified
split
package.json
src
features
regretevator-notifications.ts
regretevator-waybar.ts
wayland-copy.ts
index.ts
lib
ActivityWatcher.ts
+1
package.json
···
5
5
"main": "src/index.ts",
6
6
"scripts": {
7
7
"dev": "bun src/index.ts --gamemode --use-features \"wayland-copy,regretevator-notifications,hyprland-ipc,regretevator-waybar\"",
8
8
+
"dev-opengl": "bun src/index.ts --gamemode --opengl --use-features \"wayland-copy,regretevator-notifications,hyprland-ipc,regretevator-waybar\"",
8
9
"build": "mkdir -p dist && bun build --minify --compile src/ --outfile dist/tuxstrap"
9
10
},
10
11
"repository": {
+10
-4
src/features/regretevator-notifications.ts
···
3
3
import { exec } from "child_process";
4
4
import { GetPlaceDetails, GetUniverseId } from "../lib/RobloxAPI";
5
5
6
6
+
let regretevator: boolean = false;
7
7
+
6
8
PluginEventEmitter.on("SetRichPresence",async(data: any)=>{
7
7
-
const isRegretevator = (await GetUniverseId(activityWatcher.ActivityPlaceId)) == (await GetUniverseId(4972273297));
9
9
+
const isRegretevator = (await GetUniverseId(activityWatcher.ActivityPlaceId)) === (await GetUniverseId(4972273297));
8
10
// console.log("IsRegretevator",isRegretevator,data)
9
11
if (isRegretevator) {
12
12
+
if (!regretevator) {
13
13
+
regretevator = true;
14
14
+
exec(`notify-send -a "tuxstrap" -u low "Regretevator" "???????"`);
15
15
+
}
10
16
try {
11
17
if (bloxstraprpc._stashedRPCMessage?.largeImage?.hoverText === "THE REGRET ELEVATOR" && bloxstraprpc._stashedRPCMessage?.smallImage?.hoverText === "The Axolotl Sun") {
12
18
if ((data.state as string).match(/^On Floor ([0-9]+)$/)) {
···
15
21
} else if ((data.state as string) === "Going up!") {
16
22
exec(`notify-send -a "tuxstrap" -u low "Regretevator" "Going Up!"`);
17
23
} else if ((data.state as string) === "Lounging in the lobby") {
18
18
-
exec(`notify-send -a "tuxstrap" -u low "Regretevator" "u dead lol"`);
24
24
+
exec(`notify-send -a "tuxstrap" -u low "Regretevator" "cmon, just one more floor pleaseeeeeee :3"`);
19
25
}
20
26
}
21
27
} catch(e_) {}
28
28
+
} else {
29
29
+
regretevator = false;
22
30
}
23
31
})
24
24
-
25
25
-
if (activityWatcher.options.showNotifications) exec(`notify-send -a "tuxstrap" -u low "Roblox" "Loaded: Regretevator Notifications"`);
+19
-7
src/features/regretevator-waybar.ts
···
9
9
writeFileSync(`${homedir()}/.regretevator_state`,data)
10
10
}
11
11
12
12
+
let isInitalLaunch = true;
13
13
+
let lastFloorNum = "0";
14
14
+
12
15
activityWatcher.BloxstrapRPCEvent.on("OnGameLeave",()=>{
16
16
+
isInitalLaunch = true;
17
17
+
lastFloorNum = "0";
13
18
try {
14
19
rmSync(`${homedir()}/.regretevator_state`);
15
20
} catch {};
16
21
})
22
22
+
17
23
18
24
PluginEventEmitter.on("SetRichPresence",async(data: any)=>{
19
25
const isRegretevator = (await GetUniverseId(activityWatcher.ActivityPlaceId)) == (await GetUniverseId(4972273297));
···
23
29
if (bloxstraprpc._stashedRPCMessage?.largeImage?.hoverText === "THE REGRET ELEVATOR" && bloxstraprpc._stashedRPCMessage?.smallImage?.hoverText === "The Axolotl Sun") {
24
30
if ((data.state as string).match(/^On Floor ([0-9]+)$/)) {
25
31
const f = (data.state as string).replace(/[a-zA-Z ]*/g,'');
26
26
-
writeState(`ý ${f}`);
32
32
+
lastFloorNum = f;
33
33
+
writeState(`{"text":"ý ${f}","tooltip":"On Floor ${f}"}`);
27
34
} else if ((data.state as string).match(/^Currently spectating (.*)$/)) {
28
35
const f = (data.state as string).replace(/^Currently spectating /g,'');
29
29
-
writeState(`ý ${f}`);
36
36
+
// let nextFloorNum = "0";
37
37
+
// try { nextFloorNum = Number(lastFloorNum)+1 } catch {};
38
38
+
writeState(`{"text":"ý ${f}","tooltip":"Spectating ${f}"}`);
30
39
} else if ((data.state as string) === "Going up!") {
31
31
-
writeState(`ý `);
40
40
+
writeState(`{"text":"ý ","tooltip":"Floor ${lastFloorNum} ${Number(lastFloorNum)+1}"}`);
32
41
} else if ((data.state as string) === "Lounging in the lobby") {
33
33
-
writeState(`ý `);
42
42
+
writeState(`{"text":"ý ","tooltip":"In Lobby"}`);
34
43
} else {
35
35
-
writeState(`ý`);
44
44
+
if (isInitalLaunch) {
45
45
+
isInitalLaunch = false;
46
46
+
writeState(`{"text":"ý","tooltip":"Playing Regretevator"}`);
47
47
+
} else {
48
48
+
writeState(`{"text":"ý ","tooltip":"Floor ${lastFloorNum} ${Number(lastFloorNum)+1}"}`);
49
49
+
}
36
50
}
37
51
}
38
52
} catch(e_) {}
39
53
}
40
54
})
41
41
-
42
42
-
if (activityWatcher.options.showNotifications) exec(`notify-send -a "tuxstrap" -u low "Roblox" "Loaded: Regretevator Waybar (OCbwoy3's Dotfiles)"`);
-2
src/features/wayland-copy.ts
···
14
14
if (activityWatcher.options.showNotifications) exec(`notify-send -i ${path.join(__dirname,"..","assets/roblox.png")} -u low "Roblox" "${gmfixed} wrote to the Wayland clipboard!"`);
15
15
}
16
16
})
17
17
-
18
18
-
if (activityWatcher.options.showNotifications) exec(`notify-send -a "tuxstrap" -u low "Roblox" "Loaded: Wayland Clipboard"`);
+9
-5
src/index.ts
···
1
1
import { Command } from "commander";
2
2
import { textSync } from "figlet";
3
3
-
import { LAUNCH_COMMAND, setActivityWatcherInstance, setBloxstrapRPCInstance, TUXSTRAP_VERSION } from "./lib/Constants";
3
3
+
import { activityWatcher, LAUNCH_COMMAND, setActivityWatcherInstance, setBloxstrapRPCInstance, TUXSTRAP_VERSION } from "./lib/Constants";
4
4
import { exec, spawn } from "child_process";
5
5
import { ActivityWatcher } from "./lib/ActivityWatcher";
6
6
import { TuxstrapOptions } from "./lib/Types";
···
20
20
.option("-s, --silent", "Disable game join and plugin notifications")
21
21
.option("-v, --verbose", "Shows Roblox's stdout in the log")
22
22
.option("--background", "Runs the process in the background")
23
23
+
.option("--opengl", "Use the OpenGL renderer instead of Vulkan")
23
24
.argument('[url]','A roblox:// URL for launching a specific game or server (optional)')
24
25
25
26
program.addHelpText('after',`
···
57
58
if (options.verbose === true) { opts.verbose = true };
58
59
59
60
const URI = program.args[0] || "roblox://";
60
60
-
const sober_cmd = `${opts.useGamemode ? "gamemoderun " : ""}${LAUNCH_COMMAND}${program.args[0] ? ` "${URI}"` : ""}`
61
61
+
const sober_cmd = `${opts.useGamemode ? "gamemoderun " : ""}${LAUNCH_COMMAND}${program.args[0] ? ` "${URI}"` : ""}${options.opengl ? " --opengl" : ""}`
61
62
62
63
if (options.background) {
63
64
console.log("[INIT]","Process argv:",process.argv.join(" "));
···
73
74
74
75
console.log("[INIT]","Using features:",opts.useFeatures);
75
76
console.log("[INIT]","Sober Launch Command:",sober_cmd);
77
77
+
78
78
+
if (options.opengl) exec(`notify-send -a "tuxstrap" -u low "Roblox" "Using OpenGL renderer"`);
76
79
77
80
const launch_time = Date.now();
78
81
const child = exec(sober_cmd);
79
82
83
83
+
80
84
const watcher = new ActivityWatcher(child,opts);
81
85
setActivityWatcherInstance(watcher);
82
86
···
115
119
})()
116
120
117
121
if (opts.showNotifications) {
118
118
-
setTimeout(() => {
119
119
-
exec(`notify-send -a "tuxstrap" -u low "Roblox" "Hello, World!"`);
120
120
-
}, 1000);
122
122
+
activityWatcher.BloxstrapRPCEvent.on("ObtainLog",()=>{
123
123
+
exec(`notify-send -a tuxstrap -u low "TuxStrap" "Obtained Roblox's logfile"`);
124
124
+
})
121
125
}
122
126
123
127
watcher.stdoutWatcher();
+2
src/lib/ActivityWatcher.ts
···
244
244
const logHandle = await open(robloxLogfile,'r+');
245
245
console.log("[ActivityWatcher]",`Obtained r+ logfile handle: ${robloxLogfile}`)
246
246
247
247
+
this.BloxstrapRPCEvent.emit("ObtainLog")
248
248
+
247
249
try {
248
250
let position = 0;
249
251
let line = ""