murkmod.js 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. window.mush_ready = false;
  2. if (localStorage.getItem("plugins") === null) {
  3. localStorage.setItem("plugins", JSON.stringify([]));
  4. }
  5. document.addEventListener("DOMContentLoaded", function () {
  6. window.tp = chrome.terminalPrivate;
  7. window.enc = new TextDecoder("utf-8");
  8. window.once_done = function () { };
  9. window.finished = "";
  10. window.use_finished = false;
  11. window.output_handler = function (output) { };
  12. window.exit_string = "";
  13. window.crouton_running = false;
  14. window.crouton_id = "";
  15. window.soft_running = false;
  16. window.soft_id = "";
  17. window.to_enable = [];
  18. window.to_disable = [];
  19. window.bash_id = "";
  20. window.send_fans = false;
  21. window.plugins_propagated = false;
  22. window.propagation_stage = 0;
  23. window.legacy_plugins = [];
  24. window.allow_autoclose = true;
  25. window.no_ext_icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADA0lEQVQ4jX2TvW9bZRjFz/O8773+rBPHju2mbklCTQgIAVWiVpGQkEBsRexMHZgYkfgXYOcPgKFMDEhF6kgHUBCqCKiloq2bpAngOG6+ajvXvve+7/MwJK1g4WxHOsvROT/68savy7VGfYUBBQACyMPDGEMBB0jTVD0AA8ADeJYTgHrd3VVba9RXKuViHaKpqjAEMKHVKErccDjQSqVsjGEWETyXQsEUAFhhAArR1Il458XDsD887PvR3uPXq5nh+9sb9xtJ6px6kTR13qfinYiHaApAGQBEhQggJ5oKm9H6+iYvzDfeunzp1SVJxq2/u0dxKhQTs560BJgZAGABT9Za9PtDfdrdfKVYzBXyZhRH4zgaHI/dTnefZrPZpaNOLzv2Zr05u7AvPmFRIcCTBQTWWuzs9mjp4szKy60XZlPnYK2FF9WPr119OwgsRaMYX3/30/W5MOxRKuydI8CAAYCJNU1iG4Y2AwDWWjgnqiLEbFQUGidpurXV4d9/WysNBpEGYagA1Hz40SdX8rlMfhiNRdPRuT/af0WGiaYmi1kRqKiSKsCGMVMrTy/OT19+0H7Uz5WqT7x3MQOAcw61alVv33l496tvV2/+cnejzURETApARZSgQK1anr5wrj5FXs8fPu2zNQwLCMIg1PbDtrn67vI7H7x3RfP5XEEUGAwjLhRyxEw6PB7J51988+NCq0ljCdvLL5V4GI1OZgSBRIE0ETd/4WyzUZ0s37y19ujTz67f2Hjc2bMMMLOdm2seTp5t3br05ms7lgFxnhg43TOTTw+O+sfPzhZawmQxM6xOTUwwERnLlA0o36iWNJOxooAKG1jAaJIkOD9Tx/17d24/2Px+3zCysZMn83PN+Ief763t7g98NEqO82fObAeBZXECNkwMqAUAeFEOmFqLb6x3entb0TgxtVLRV8pF2e7s/VmqVcxMISPliZIwBMqsRCynTwTBmsCKwmaFL842wAx1TlhFePHFGQgAkRNPbPVfMJHtdQ9WT6l6jin+R//F+WD1H8YOlNy3uSdQAAAAAElFTkSuQmCC";
  26. window.propagate_plugins = function(id, output){
  27. if (window.propagation_stage == 0 && output.includes("> (1-")) {
  28. tp.sendInput(id, "113\n");
  29. window.propagation_stage++;
  30. } else if (window.propagation_stage == 1 && output.includes("[][]")) {
  31. window.plugins_propagated = true;
  32. plugins_raw = output.split("[][]").slice(1); // arbitrary sequence not used in text
  33. plugins = [];
  34. plugins_raw.forEach(plugin=>{
  35. let parsed = plugin.split(",").slice(0, -1);
  36. plugins.push({
  37. name: parsed[1],
  38. function: parsed[0],
  39. desc: parsed[2],
  40. author: parsed[3]
  41. });
  42. });
  43. console.log(plugins);
  44. window.legacy_plugins = plugins;
  45. var html = "";
  46. for (let i in plugins) {
  47. var plugin = plugins[i];
  48. html += `<button id="legacy_plugins_${i}" title="Provided by ${plugin.name}">${plugin.function}</button>\n`
  49. }
  50. html += "<p></p>";
  51. document.querySelector("#legacy_plugins").innerHTML = html;
  52. for (let i in plugins) {
  53. var button = document.querySelector(`#legacy_plugins_${i}`);
  54. button.addEventListener("click", function(){
  55. window.run_task("4\n", "", "> (1-", function (output) {
  56. if (output.includes("> Select a plugin (or q to quit): ")) {
  57. window.send(`${(parseInt(i) + 1).toString()}\n`);
  58. }
  59. }, function () {}, true, "\u0003");
  60. });
  61. }
  62. }
  63. }
  64. tp.onProcessOutput.addListener(function (id, type, buffer) {
  65. if (id == window.process_id) {
  66. var decoded = enc.decode(buffer);
  67. console.log(decoded);
  68. window.term.write(decoded);
  69. window.output_handler(decoded);
  70. if (!window.plugins_propagated) {
  71. window.propagate_plugins(id, decoded);
  72. return;
  73. }
  74. if (decoded.includes("> (1-") || (window.use_finished && decoded.includes(window.finished))) {
  75. console.log("mush is ready!");
  76. window.mush_ready = true;
  77. if (window.allow_autoclose) {
  78. window.hide_term();
  79. }
  80. window.once_done();
  81. window.once_done = function () { };
  82. window.use_finished = false;
  83. }
  84. } else if (id == window.crouton_id) {
  85. var decoded = enc.decode(buffer);
  86. console.log(decoded);
  87. if (window.crouton_running) {
  88. if (decoded.includes("> (1-")) {
  89. window.crouton_running = false;
  90. tp.closeTerminalProcess(window.crouton_id);
  91. window.crouton_id = "";
  92. }
  93. } else {
  94. if (decoded.includes("> (1-")) {
  95. tp.sendInput(window.crouton_id, "15\n");
  96. }
  97. if (decoded.includes("Use Crtl+Shift+Alt+Forward and Ctrl+Shift+Alt+Back to toggle between desktops")) {
  98. window.crouton_running = true;
  99. }
  100. }
  101. } else if (id == window.bash_id) {
  102. var decoded = enc.decode(buffer);
  103. console.log(decoded);
  104. window.bash_term.write(decoded);
  105. if (decoded.includes("> (1-")) {
  106. tp.sendInput(window.bash_id, "1\n");
  107. }
  108. }
  109. });
  110. console.log("starting mush...");
  111. tp.openTerminalProcess("crosh", id => {
  112. window.process_id = id;
  113. });
  114. tp.openTerminalProcess("crosh", id => {
  115. window.bash_id = id;
  116. });
  117. console.log("propagating js plugins...");
  118. window.js_plugins = JSON.parse(localStorage.getItem("plugins"));
  119. var plugin_container = document.querySelector("#plugins");
  120. for (let i in window.js_plugins) {
  121. var plugin = window.js_plugins[i];
  122. eval(plugin.text);
  123. plugin_init();
  124. button = document.createElement("button");
  125. button.addEventListener("click", plugin_main);
  126. button.innerHTML = PLUGIN_FUNCTION;
  127. plugin_container.appendChild(button);
  128. }
  129. window.send = function (text) {
  130. tp.sendInput(window.process_id, text);
  131. }
  132. window.bash = function (cmd) {
  133. tp.sendInput(window.bash_id, cmd);
  134. }
  135. window.show_term = function () {
  136. document.querySelector("#terminal-container").style.display = "block";
  137. document.querySelector("body").className = "terminal_shown";
  138. }
  139. window.hide_term = function () {
  140. document.querySelector("#terminal-container").style.display = "none";
  141. document.getElementsByTagName("body")[0].className = "";
  142. }
  143. window.l337_hax0r = function () {
  144. Swal.fire("pro hacker mode enabled");
  145. document.querySelector("#debug").style.display = "block";
  146. }
  147. window.run_task = function (input, title, finished, output_handler, once_done, allow_exit, exit_string) {
  148. if (!window.mush_ready) {
  149. alert("mush is not ready yet!");
  150. return;
  151. }
  152. window.mush_ready = false;
  153. window.use_finished = true;
  154. window.finished = finished;
  155. window.output_handler = output_handler;
  156. window.exit_string = exit_string;
  157. document.querySelector("#title").innerHTML = title;
  158. if (!allow_exit) {
  159. document.querySelector("#close").display = "none";
  160. } else {
  161. document.querySelector("#close").display = "block";
  162. }
  163. window.show_term();
  164. window.once_done = once_done;
  165. window.send(input);
  166. }
  167. window.run_task_silent = function(input, finished, output_handler, once_done) {
  168. if (!window.mush_ready) {
  169. alert("mush is not ready yet!");
  170. return;
  171. }
  172. window.mush_ready = false;
  173. window.use_finished = true;
  174. window.finished = finished;
  175. window.output_handler = output_handler;
  176. window.once_done = once_done;
  177. window.send(input);
  178. }
  179. window.start_crouton = function () {
  180. if (window.crouton_running) {
  181. alert("Crouton already running!");
  182. return;
  183. }
  184. console.log("starting mush...");
  185. tp.openTerminalProcess("crosh", id => {
  186. window.crouton_id = id;
  187. });
  188. document.querySelector("#start_crouton").style.display = "none";
  189. document.querySelector("#stop_crouton").style.display = "block";
  190. }
  191. window.stop_crouton = function () {
  192. if (!window.crouton_running) {
  193. alert("Crouton not running!");
  194. return;
  195. }
  196. tp.sendInput(window.crouton_id, "\x03");
  197. document.querySelector("#start_crouton").style.display = "block";
  198. document.querySelector("#stop_crouton").style.display = "none";
  199. }
  200. window.hard_enable = function (callback) {
  201. var id = window.to_enable.pop();
  202. if (id) {
  203. window.run_task("111\n", `Enabling ${id}`, "> (1-", function (output) {
  204. if (output.includes("Enter extension ID >")) {
  205. window.send(id + "\n");
  206. }
  207. }, function () {
  208. window.hard_enable(callback);
  209. }, false, "");
  210. return;
  211. }
  212. callback();
  213. }
  214. window.hard_disable = function (callback) {
  215. var id = window.to_disable.pop();
  216. if (id) {
  217. window.run_task("101\n", `Disabling ${id}`, "> (1-", function (output) {
  218. if (output.includes("Enter extension ID >")) {
  219. window.send(id + "\n");
  220. }
  221. }, function () {
  222. window.hard_disable(callback);
  223. }, false, "");
  224. return;
  225. }
  226. callback();
  227. }
  228. window.purge_exts = function () {
  229. window.run_task("112\n", "Purging...", "> (1-", function (output) { }, function () { }, false, "");
  230. }
  231. window.makeRequest = function(method, url) {
  232. return new Promise(function (resolve, reject) {
  233. var xhr = new XMLHttpRequest();
  234. xhr.open(method, url);
  235. xhr.responseType = 'blob';
  236. xhr.onload = function () {
  237. if (xhr.status >= 200 && xhr.status < 300) {
  238. resolve(xhr.response);
  239. } else {
  240. reject({
  241. status: xhr.status,
  242. statusText: xhr.statusText
  243. });
  244. }
  245. };
  246. xhr.onerror = function () {
  247. reject({
  248. status: xhr.status,
  249. statusText: xhr.statusText
  250. });
  251. };
  252. xhr.send();
  253. });
  254. }
  255. window.toDataURL = url => window.makeRequest("GET", url)
  256. .then(blob => new Promise((resolve, reject) => {
  257. const reader = new FileReader()
  258. reader.onloadend = () => resolve(reader.result)
  259. reader.onerror = reject
  260. reader.readAsDataURL(blob)
  261. }))
  262. document.querySelector("#close").addEventListener("click", function () {
  263. window.hide_term();
  264. window.send(window.exit_string);
  265. window.exit_string = "";
  266. });
  267. console.log("initializing xterm.js...");
  268. window.term = new Terminal();
  269. window.bash_term = new Terminal();
  270. term.open(document.getElementById('terminal'));
  271. bash_term.open(document.getElementById('terminal-bash'));
  272. term.onKey(function (v) {
  273. console.log(v);
  274. send(v.key);
  275. });
  276. bash_term.onKey(function (v) {
  277. console.log(v);
  278. tp.sendInput(window.bash_id, v.key);
  279. });
  280. // update murkmod
  281. document.querySelector("#update_murkmod").addEventListener("click", function () {
  282. window.run_task("25\n", "Updating murkmod - please respond to prompts if neccesary.", "key to exit.", function (output) {
  283. if (output.toLowerCase().includes("[y/n]")) {
  284. var lines = output.split('\n');
  285. for (let i in lines) {
  286. if (lines[i].toLowerCase().includes("[y/n]")) {
  287. Swal.fire({
  288. text: lines[i].split(" [")[0],
  289. showCancelButton: true,
  290. confirmButtonColor: '#3085d6',
  291. cancelButtonColor: '#d33',
  292. confirmButtonText: 'Yes',
  293. cancelButtonText: 'No'
  294. }).then((result) => {
  295. if (result.isConfirmed) {
  296. window.send("y\n");
  297. } else {
  298. window.send("n\n")
  299. }
  300. });
  301. }
  302. }
  303. }
  304. },
  305. function () {
  306. console.log("Reloading mush...");
  307. window.mush_ready = false;
  308. tp.openTerminalProcess("crosh", id => {
  309. window.process_id = id;
  310. });
  311. }, false, "");
  312. });
  313. // root shell
  314. document.querySelector("#root_shell").addEventListener("click", function () {
  315. window.run_task("1\n", "", "> (1-", function (output) { }, function () { }, true, "\u0004");
  316. });
  317. // chronos shell
  318. document.querySelector("#chronos_shell").addEventListener("click", function () {
  319. window.run_task("2\n", "", "> (1-", function (output) { }, function () { }, true, "\u0004");
  320. });
  321. // crosh
  322. document.querySelector("#crosh").addEventListener("click", function () {
  323. window.run_task("3\n", "", "> (1-", function (output) { }, function () { }, true, "\u0004");
  324. });
  325. // emergency revert
  326. document.querySelector("#emergency_revert").addEventListener("click", function () {
  327. Swal.fire({
  328. title: 'Are you sure?',
  329. text: "This option will re-enroll your chromebook and restore it to its exact state before fakemurk was run. This is useful if you need to quickly go back to normal. This is *permanent*. You will not be able to use murkmod again unless you re-run everything from the beginning.",
  330. icon: 'warning',
  331. showCancelButton: true,
  332. confirmButtonColor: '#3085d6',
  333. cancelButtonColor: '#d33',
  334. confirmButtonText: 'Yes! Burn it to the ground!'
  335. }).then((result) => {
  336. if (result.isConfirmed) {
  337. window.run_task("8\n", "", "> (1-", function (output) {
  338. if (output.includes("Are you sure - 100% sure - that you want to continue?")) {
  339. window.send("\n");
  340. }
  341. }, function () { }, false, "");
  342. }
  343. });
  344. });
  345. // powerwash
  346. document.querySelector("#powerwash").addEventListener("click", function () {
  347. Swal.fire({
  348. title: 'Are you sure you wanna powerwash?',
  349. text: "This will wipe everything but won't remove murkmod.",
  350. icon: 'warning',
  351. showCancelButton: true,
  352. confirmButtonColor: '#3085d6',
  353. cancelButtonColor: '#d33',
  354. confirmButtonText: 'Yes! Burn it to the ground!'
  355. }).then((result) => {
  356. if (result.isConfirmed) {
  357. window.run_task("14\n", "", "> (1-", function (output) {
  358. if (output.includes("(Press enter to continue, ctrl-c to cancel)")) {
  359. window.send("\n");
  360. }
  361. }, function () { }, false, "");
  362. }
  363. });
  364. });
  365. // install crouton
  366. document.querySelector("#install_crouton").addEventListener("click", function () {
  367. window.run_task("14\n", "", "> (1-", function (output) { }, function () { }, false, "");
  368. });
  369. // start/stop crouton
  370. document.querySelector("#start_crouton").addEventListener("click", window.start_crouton);
  371. document.querySelector("#stop_crouton").addEventListener("click", window.stop_crouton);
  372. // extension controls
  373. document.querySelector("#automagically").addEventListener("click", function () {
  374. window.run_task("12\n", "", "> (1-", function (output) { }, function () { }, false, "");
  375. });
  376. document.querySelector("#closeexts").addEventListener("click", function () {
  377. document.querySelector("#ext-modal").style.display = "none";
  378. });
  379. document.querySelector("#purge_exts").addEventListener("click", window.purge_exts);
  380. document.querySelector("#manage_exts").addEventListener("click", function () {
  381. chrome.management.getAll(exts => {
  382. var modal = document.querySelector("#ext-modal");
  383. var content = document.querySelector("#ext-content");
  384. var html = `<button id="ext-save-changes">Save changes</button>
  385. <br>
  386. <p id="exts-loading">Loading...</p>
  387. <table id="ext-table" style="display: none; width: 100%;">
  388. <tr>
  389. <th>Name</th>
  390. <th>ID</th>
  391. <th>Enabled</th>
  392. </tr>`;
  393. for (let i in exts) {
  394. var ext = exts[i];
  395. html += `<tr><td>${ext.name}</td> <td>${ext.id}</td> <td><input type="checkbox" id="checkbox-exts-${i}"></input></td></div></tr>`;
  396. }
  397. html += `</table>`
  398. content.innerHTML = html;
  399. for (let i in exts) {
  400. var ext = exts[i];
  401. var ext_icon = window.toDataURL(ext.icons[0].url).then(ext_icon=>{
  402. console.log(ext_icon);
  403. var hard_enabled = (ext_icon != window.no_ext_icon);
  404. exts[i].hard_enabled = hard_enabled;
  405. document.querySelector(`#checkbox-exts-${i}`).checked = hard_enabled;
  406. if (i == (exts.length - 1)) {
  407. document.querySelector("#exts-loading").style.display = "none";
  408. document.querySelector("#ext-table").style.display = "block";
  409. }
  410. });
  411. }
  412. document.querySelector("#ext-save-changes").addEventListener("click", function () {
  413. window.to_enable = [];
  414. window.to_disable = [];
  415. for (let i in exts) {
  416. var ext = exts[i];
  417. var checkbox = document.getElementById(`checkbox-exts-${i}`);
  418. let checked = checkbox.checked;
  419. let id = ext.id;
  420. if (ext.hard_enabled != checked) {
  421. if (checked) {
  422. window.to_enable.push(ext.id);
  423. } else {
  424. window.to_disable.push(ext.id);
  425. }
  426. }
  427. }
  428. console.log(window.to_enable);
  429. console.log(window.to_disable);
  430. modal.style.display = "none";
  431. window.hard_enable(function () {
  432. window.hard_disable(function () {
  433. window.purge_exts();
  434. });
  435. });
  436. });
  437. modal.style.display = "block";
  438. });
  439. });
  440. // experiments
  441. document.querySelector("#update_chromeos").addEventListener("click", function () {
  442. window.run_task("20\n", "", "> (1-", function (output) { }, function () { }, false, "");
  443. });
  444. document.querySelector("#update_backup").addEventListener("click", function () {
  445. window.run_task("21\n", "", "> (1-", function (output) { }, function () { }, false, "");
  446. });
  447. document.querySelector("#restore_backup_backup").addEventListener("click", function () {
  448. window.run_task("22\n", "", "> (1-", function (output) { }, function () { }, false, "");
  449. });
  450. document.querySelector("#chromebrew").addEventListener("click", function () {
  451. window.run_task("23\n", "", "> (1-", function (output) { }, function () { }, false, "");
  452. });
  453. document.querySelector("#dev_install").addEventListener("click", function () {
  454. window.run_task("24\n", "", "> (1-", function (output) { }, function () { }, false, "");
  455. });
  456. document.querySelector("#boot_usb_on").addEventListener("click", function () {
  457. window.run_task("16\n", "", "> (1-", function (output) { }, function () { }, false, "");
  458. });
  459. document.querySelector("#boot_usb_off").addEventListener("click", function () {
  460. window.run_task("17\n", "", "> (1-", function (output) { }, function () { }, false, "");
  461. });
  462. //system control
  463. document.querySelector("#fans").addEventListener("input", function () {
  464. document.getElementById('fanprecent').innerHTML = this.value.toString() + '%';
  465. window.send_fans = true;
  466. });
  467. document.querySelector("#reboot").addEventListener("click", function(){
  468. window.bash("reboot\n");
  469. });
  470. setInterval(function () {
  471. if (window.send_fans) {
  472. window.send_fans = false;
  473. window.bash(`ectool fanduty ${document.querySelector("#fans").value.toString()}\n`);
  474. }
  475. }, 1000);
  476. // plugin store
  477. const extractValue = (variable, script) => {
  478. const regex = new RegExp(`${variable}="(.*?)"`);
  479. const match = script.match(regex);
  480. return match ? match[1] : null;
  481. };
  482. document.querySelector("#store").addEventListener("click", function() {
  483. Swal.fire({
  484. title: 'Loading plugin store...',
  485. didOpen: () => {
  486. Swal.showLoading();
  487. },
  488. allowOutsideClick: true,
  489. allowEscapeKey: true,
  490. allowEnterKey: true,
  491. showConfirmButton: false
  492. });
  493. fetch("https://api.github.com/repos/rainestorme/murkmod/contents/plugins")
  494. .then(response => {return response.json()})
  495. .then(json => {
  496. Swal.close();
  497. html = "";
  498. for (let i in json) {
  499. var file = json[i];
  500. if (file.type == "file" && (file.name.endsWith(".sh") || file.name.endsWith(".js"))) {
  501. console.log("generating card for " + file.name);
  502. html += `<div class="card" id="card-${file.name.split(".")[0]}-${file.name.split(".")[1]}">
  503. <div class="card-title">${file.name}</div>
  504. <div class="card-description">loading...</div>
  505. </div>`;
  506. }
  507. }
  508. document.querySelector("#store-content").innerHTML = html;
  509. for (let i in json) {
  510. let file = json[i];
  511. console.log(file);
  512. if (file.type == "file" && (file.name.endsWith(".sh") || file.name.endsWith(".js"))) {
  513. if (file.name.endsWith(".sh")) {
  514. fetch(file.download_url)
  515. .then(response => {return response.text()})
  516. .then(text => {
  517. var card = document.querySelector(`#card-${file.name.split(".")[0]}-${file.name.split(".")[1]}`);
  518. console.log(card);
  519. const PLUGIN_NAME = extractValue("PLUGIN_NAME", text);
  520. const PLUGIN_FUNCTION = extractValue("PLUGIN_FUNCTION", text);
  521. const PLUGIN_DESCRIPTION = extractValue("PLUGIN_DESCRIPTION", text);
  522. const PLUGIN_AUTHOR = extractValue("PLUGIN_AUTHOR", text);
  523. console.log(PLUGIN_NAME, PLUGIN_FUNCTION, PLUGIN_DESCRIPTION, PLUGIN_AUTHOR);
  524. var install_btn = "Install";
  525. var installed = false;
  526. for (let i in window.legacy_plugins) {
  527. if (window.legacy_plugins[i].name === PLUGIN_NAME) {
  528. installed = true;
  529. install_btn = "Uninstall";
  530. }
  531. }
  532. card.innerHTML = `<div class="card-title">${PLUGIN_NAME}<div>
  533. <div class="card-author">By ${PLUGIN_AUTHOR} - Bash</div>
  534. <div class="card-description">${PLUGIN_DESCRIPTION}</div>
  535. <button id="card-${file.name.split(".")[0]}-${file.name.split(".")[1]}-installbtn">${install_btn}</button>`;
  536. if (installed) {
  537. card.innerHTML = card.innerHTML + `<button id="card-${file.name.split(".")[0]}-${file.name.split(".")[1]}-updatebtn">Update</button>`
  538. document.querySelector(`#card-${file.name.split(".")[0]}-${file.name.split(".")[1]}-updatebtn`).addEventListener("click", function(){
  539. window.run_task("115\n", "", "> (1-", function (output) {
  540. if (output.includes("Enter the name of a plugin (including the .sh) to uninstall it (or q to quit):")) {
  541. window.send(`${file.name}\n`);
  542. }
  543. }, function () {
  544. window.run_task("114\n", "", "> (1-", function (output) {
  545. if (output.includes("Enter the name of a plugin (including the .sh) to install it (or q to quit):")) {
  546. window.send(`${file.name}\n`);
  547. }
  548. }, function () {
  549. window.location.reload();
  550. }, false, "");
  551. }, false, "");
  552. });
  553. }
  554. document.querySelector(`#card-${file.name.split(".")[0]}-${file.name.split(".")[1]}-installbtn`).addEventListener("click", function(){
  555. if (document.querySelector(`#card-${file.name.split(".")[0]}-${file.name.split(".")[1]}-installbtn`).innerHTML === "Uninstall") {
  556. window.run_task("115\n", "", "> (1-", function (output) {
  557. if (output.includes("Enter the name of a plugin (including the .sh) to uninstall it (or q to quit):")) {
  558. window.send(`${file.name}\n`);
  559. }
  560. }, function () {
  561. window.location.reload();
  562. }, false, "");
  563. return;
  564. }
  565. window.run_task("114\n", "", "> (1-", function (output) {
  566. if (output.includes("Enter the name of a plugin (including the .sh) to install it (or q to quit):")) {
  567. window.send(`${file.name}\n`);
  568. }
  569. }, function () {
  570. window.location.reload();
  571. }, false, "");
  572. });
  573. });
  574. } else {
  575. var installed_plugins = JSON.parse(localStorage.getItem("plugins"));
  576. var already_installed = false;
  577. for (let i in installed_plugins) {
  578. plugin = installed_plugins[i];
  579. if (plugin.file.name === file.name) {
  580. already_installed = true;
  581. }
  582. }
  583. fetch(file.download_url)
  584. .then(response => {return response.text()})
  585. .then(text => {
  586. var card = document.querySelector(`#card-${file.name.split(".")[0]}-${file.name.split(".")[1]}`);
  587. eval(text);
  588. var install_btn = "Install";
  589. if (already_installed) {
  590. install_btn = "Uninstall";
  591. }
  592. card.innerHTML = `<div class="card-title">${PLUGIN_NAME}<div>
  593. <div class="card-author">By ${PLUGIN_AUTHOR} - JavaScript</div>
  594. <div class="card-description">${PLUGIN_DESCRIPTION}</div>
  595. <button id="card-${file.name.split(".")[0]}-${file.name.split(".")[1]}-installbtn">${install_btn}</button>`;
  596. document.querySelector(`#card-${file.name.split(".")[0]}-${file.name.split(".")[1]}-installbtn`).addEventListener("click", function(){
  597. // uninstall
  598. if (document.querySelector(`#card-${file.name.split(".")[0]}-${file.name.split(".")[1]}-installbtn`).innerHTML === "Uninstall") {
  599. var keep = [];
  600. for (let i in installed_plugins) {
  601. if (installed_plugins[i].file.name !== file.name) {
  602. keep.push(installed_plugins[i]);
  603. }
  604. }
  605. localStorage.setItem("plugins", JSON.stringify(keep));
  606. window.location.reload();
  607. return;
  608. }
  609. // install
  610. installed_plugins.push({
  611. file: file,
  612. text: text
  613. });
  614. localStorage.setItem("plugins", JSON.stringify(installed_plugins));
  615. window.location.reload();
  616. });
  617. });
  618. }
  619. }
  620. }
  621. document.querySelector("#store-modal").style.display = "block";
  622. });
  623. });
  624. document.querySelector("#closestore").addEventListener("click", function(){
  625. document.querySelector("#store-modal").style.display = "none";
  626. });
  627. // plugin builder
  628. // document.querySelector("#builder").addEventListener("click", function() {
  629. // Swal.fire("under construction");
  630. // });
  631. // debug
  632. document.querySelector("#show_mush").addEventListener("click", function() {
  633. show_term();
  634. });
  635. var allowedKeys = {
  636. 37: 'left',
  637. 38: 'up',
  638. 39: 'right',
  639. 40: 'down',
  640. 65: 'a',
  641. 66: 'b'
  642. };
  643. var konamiCode = ['up', 'up', 'down', 'down', 'left', 'right', 'left', 'right', 'b', 'a'];
  644. var konamiCodePosition = 0;
  645. document.addEventListener('keydown', function (e) {
  646. var key = allowedKeys[e.keyCode];
  647. var requiredKey = konamiCode[konamiCodePosition];
  648. if (key == requiredKey) {
  649. konamiCodePosition++;
  650. if (konamiCodePosition == konamiCode.length) {
  651. window.l337_hax0r();
  652. konamiCodePosition = 0;
  653. }
  654. } else {
  655. konamiCodePosition = 0;
  656. }
  657. });
  658. document.querySelector("#close-bash").addEventListener('click', function(){
  659. document.querySelector("#terminal-bash-container").style.display = "none";
  660. });
  661. document.querySelector("#show_bash").addEventListener('click', function(){
  662. document.querySelector("#terminal-bash-container").style.display="block";
  663. });
  664. document.querySelector("#no_term_autoclose").addEventListener('click', function(){
  665. window.allow_autoclose = false;
  666. });
  667. document.querySelector("#do-xss").addEventListener('click', function(){
  668. var F=new Function(prompt("input js or smth"));
  669. F();
  670. });
  671. document.querySelector("#disable_debug").addEventListener('click', function(){
  672. document.querySelector("#debug").style.display = "none";
  673. });
  674. document.querySelector("#point_blank").addEventListener('click', function(){
  675. open();
  676. });
  677. });