[Linux-only] basically bloxstap for sober
1import { $ } from "bun";
2import { isCompiled, isNixOS, SOBER_APPID, tsExecutablePath, TUXSTRAP_VERSION } from "./api/constants";
3import {
4 _libocbwoy3Version,
5 libocbwoy3Greet,
6 setConsoleTitle
7} from "@ocbwoy3/libocbwoy3";
8import { generateConfigFile } from "./api/sober/ConfigManager";
9import { exec } from "child_process";
10import { ActivityWatcher } from "./api/log/ActivityWatcher";
11import {
12 createDesktopEntry,
13 registerXDG,
14 tuxstrapDesktopEntry
15} from "./api/sober/DesktopEntry";
16import { join } from "path";
17import { getPluginInfos, registerPluginsAllFinal } from "./api/Plugin";
18import "./plugins";
19import { eventCollector } from "./api/EventCollector";
20import { handleRoblox700PatchReplacements } from "./api/700-fix/replacements";
21
22(() => {
23 const listPluginsSwitch = process.argv.find((a) => a === "--list-plugins");
24
25 const helpSwitch = process.argv.find((a) => a === "-h" || a === "--help");
26 const debugSwitch = process.argv.find((a) => a === "--debug" );
27
28 if (debugSwitch) {
29 console.log("argv0", process.argv0);
30 console.log("argv", process.argv);
31 console.log("isCompiled", isCompiled);
32 console.log("isNixOS", isNixOS);
33 console.log("isCompiled", tsExecutablePath);
34 process.exit(0);
35 }
36
37 if (helpSwitch) {
38 console.log(
39 `TuxStrap
40
41 List FFlag/Plugin profiles:
42 \\ttuxstrap --list-plugins
43
44 Enable versbose mode for Roblox logs:
45 \\ttuxstrap -v / --verbose
46
47 Enable a plugin:
48 \\ttuxstrap +super
49
50 Disable a plugin:
51 \\ttuxstrap -unstable
52
53 Launch Roblox from a URL:
54 \\ttuxstrap "roblox://placeId=69420"
55
56 You can combine profiles together:
57 \\ttuxstrap +super +unstable -dbus
58
59 Code: https://tangled.sh/@ocbwoy3.dev/tuxstrap
60 `
61 .replaceAll("\t", "")
62 .replaceAll("\\t", "\t")
63 );
64 if (
65 isCompiled
66 ) {
67 console.log(
68 `TuxStrap ${TUXSTRAP_VERSION}, libocbwoy3 ${_libocbwoy3Version}, Bun ${
69 Bun.version_with_sha
70 }, ${
71 isNixOS
72 ? "Nix build"
73 : "compiled"
74 }`
75 );
76 }
77 process.exit(0);
78 }
79
80 if (listPluginsSwitch) {
81 for (const plugin of getPluginInfos()) {
82 console.log(
83 `${plugin.name} (${plugin.id})${
84 plugin.forceEnable ? " [default]" : ""
85 } - ${plugin.description}`
86 );
87 }
88 process.exit(0);
89 }
90})();
91
92eventCollector.on("BLOXSTRAP_RPC", ({ type, data }) => {
93 console.log("[BLOXSTRAPRPC]", type, data);
94});
95
96(async () => {
97 (() => {
98 const firstRobloxURLArg = process.argv.find(
99 (a) => a === "tuxstrap://gendesktoproblox"
100 );
101
102 if (
103 !!firstRobloxURLArg &&
104 process.argv.find(
105 (a) => a.startsWith("roblox:") || a.startsWith("roblox-player:")
106 )
107 ) {
108 console.error("What did you do...");
109 process.exit(1);
110 }
111 if (firstRobloxURLArg) {
112 console.log(
113 createDesktopEntry(
114 tuxstrapDesktopEntry,
115 join(__dirname, process.argv0)
116 .replace(/^\/build\//, "/")
117 .replace(/^\/src\//, "/")
118 ).replaceAll("org.vinegarhq.Sober", "tuxstrap")
119 );
120 process.exit(0);
121 }
122 })();
123
124 const soberCheck = await $`flatpak list | grep ${SOBER_APPID}`
125 .nothrow()
126 .quiet();
127
128 if (soberCheck.exitCode !== 0) {
129 console.error("Install Sober before using TuxStrap!");
130 console.log("https://flathub.org/apps/org.vinegarhq.Sober");
131 console.log(
132 "> flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo"
133 );
134 console.log("> flatpak install flathub org.vinegarhq.Sober");
135 process.exit(1);
136 }
137
138 setConsoleTitle("TuxStrap");
139 libocbwoy3Greet();
140
141 if (
142 isCompiled
143 ) {
144 console.log(
145 `Using ${
146 isNixOS ? "Nix" : "built"
147 } version of TuxStrap!! ${process.argv0}`
148 );
149 }
150
151 // await createWaylandContext(); <-- we need c for this shit
152 // await copyToClipboard("haha funny"); <-- and this
153
154 const pluginsEnable = process.argv
155 .filter(
156 (a) => a.startsWith("+") && !a.includes("-") && !a.includes(" ")
157 )
158 .map((a) => a.replace(/^\+/, ""));
159 const pluginsDisable = process.argv
160 .filter(
161 (a) =>
162 a.startsWith("-") &&
163 !a.startsWith("--") &&
164 !a.includes("+") &&
165 !a.includes(" ")
166 )
167 .map((a) => a.replace(/^\-\-/, ""));
168
169 await registerPluginsAllFinal(pluginsEnable, pluginsDisable);
170
171 if (process.env.NODE_ENV !== "development") {
172 registerXDG("tuxstrap.desktop");
173 }
174
175 generateConfigFile();
176
177 // fuck you roblox
178 handleRoblox700PatchReplacements();
179
180 const firstRobloxURLArg = process.argv.find(
181 (a) => a.startsWith("roblox:") || a.startsWith("roblox-player:")
182 );
183
184 const robloxLaunchURL = firstRobloxURLArg || "roblox://";
185
186 const child = exec(`flatpak run ${SOBER_APPID} "${robloxLaunchURL}"`);
187
188 const isVerbose = process.argv.find(
189 (a) => (a === "-v") || (a === "--verbose")
190 );
191
192 const watcher = new ActivityWatcher(child, {
193 verbose: !!isVerbose,
194 tuxstrapLaunchTime: Date.now()
195 });
196
197 child.on("exit", (code) => {
198 process.exit(code);
199 });
200
201 await watcher.stdoutWatcher();
202})();