Advertisement
Guest User

Untitled

a guest
Dec 9th, 2019
484
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 59.60 KB | None | 0 0
  1. // ==UserScript==
  2. // @name Panel Dodatków NI
  3. // @namespace http://the-crudness.xaa.pl/NIAddons/panel.user.js
  4. // @version 2.6.5.8
  5. // @description Dodaje do wbudowanego panelu dodatków inne dodatki.
  6. // @author Priweejt
  7. // @include http://*.margonem.com/
  8. // @include http://*.margonem.pl/
  9. // @grant none
  10. // ==/UserScript==
  11. // ==Changelog==
  12. // 2.6 - w sumie to samo co 2.5
  13. // 2.5 - znów pełno zmian w API, kolejny nowy dodatek
  14. // 2.4 - pierdyliard zmian w API, nowy dodatek, usunięte na obecną chwile dodatki darrefulla bo mu hosting padł czy coś
  15. // 2.3 - nowy dodatek, naprawione loader.require
  16. // 2.2 - włączenie dodatku pokazywanie kolizji dla angielskiego margonem, bo działają już tam widgety. Trochę wewnętrznych zmian w tym skrypcie
  17. // 2.1 - dodatek lepsza walka, trochę zmian w tym kodzie żeby łatwiej się robiło dodatki (event emmitery anyone?)
  18. // 2.0.1 - pierwsza nietestowa wersja
  19. // ==/Changelog==
  20. new (function() {
  21. // check if the script was loaded on the new interface
  22. if (typeof Engine == "undefined" || typeof parseClanBB == "undefined" || typeof linkify == "undefined") return;
  23. var addons = this;
  24. window.priwAddons = this;
  25. window.API.priw = this;
  26. var Storage = API.Storage;
  27. var Templates = API.Templates;
  28. this.cursors = {
  29. default: "url(http://aldous.margonem.pl/img/gui/cursor/1.png), auto",
  30. npctalk: "url(http://aldous.margonem.pl/img/gui/cursor/2.png), auto",
  31. fight: "url(http://aldous.margonem.pl/img/gui/cursor/3.png), auto",
  32. grab: "url(http://aldous.margonem.pl/img/gui/cursor/4.png), auto",
  33. pointer: "url(http://aldous.margonem.pl/img/gui/cursor/5.png), auto"
  34. };
  35. this.list = {
  36. priw_bttr: {
  37. namePL: "Polepszacz interfejsu",
  38. nameEN: "Interface enhancer",
  39. descPL: "Zmienia następujące rzeczy:<br>-można potwierdzać alerty spacją<br>-konieczność potwierdzania zamknięcia karty chatu prywatnego<br>-umożliwia napisanie wiadomości prywatnej bez otwierania karty chatu prywatnego przez kliknięcie prawym przyciskiem myszy wiadomości na chacie<br>-automatycznie uzupełnia przedmiot na dolnym pasku jeśli się skończy<br>-w różny sposób poprawia tipy itemów, czyniąc je generalnie ładniejszymi<br>-poprawia wbudowane w interfejs przełączanie między postaciami (brak czekania 5s przy loganiu na inny świat)<br>-napis 'online' w znajomych jest na zielono<br>-zmienia kolory na chacie ogólnym, czyniąc go bardziej czytelnym (przy włączonym pokazywaniu wszystkich wiadomości w zakładce ogólnej)",
  40. descEN: "Changes following things:<br>alerts can be confirmed by pressing the space key<br>-confirmation of closing private chat tab is no longer required<br>-makes it possible to write a private message to another player without opening a new chat tab (right click a message on chat to do that)<br>-automatically refills items in the bottom bar when they run out of uses<br>-makes various changes to item tips, making them look more pretty in general.<br>-makes built in change character function better (it's no longer necessary to wait 5 seconds when logging onto a char that's on a different world than the current one)<br>'online' status in friend list now has green font<br>-changes colors in general chat, making it actually readable (with 'show all messages in general chat' option toggled)",
  41. urlPL: "http://priweejt.ct8.pl/NIAddons/get/littleThingsNI.js?4",
  42. // urlPL: "http://127.0.0.1:1337/littleThingsNI.js?foo",
  43. urlEN: "http://priweejt.ct8.pl/NIAddons/get/littleThingsNI.js?4",
  44. img: "http://aldous.margonem.pl/img/gui/buttony.png?v=4|-468 -12",
  45. author: "Priweejt|3779166"
  46. },
  47. priw_clbl: {
  48. namePL: "Błoga klanowe",
  49. nameEN: "Guild blessings",
  50. descPL: "Dodaje pod torbami panel wyboru błogosławieństwa klanowego, taki skrót. Nie ma sensu instalować na nakładce NI, bo w starym systemie klanów tych błogosławieństw nie ma.",
  51. descEN: "Adds shortcuts to guild blessings in the area under the bags.",
  52. urlPL: "http://priweejt.ct8.pl/NIAddons/get/NIblesspanel.js?",
  53. // urlPL: "http://127.0.0.1:1337/NIblesspanel.js?",
  54. urlEN: "http://priweejt.ct8.pl/NIAddons/get/NIblesspanel.js?",
  55. img: "http://aldous.margonem.pl/img/gui/buttony.png?v=4|-561 -12",
  56. author: "Priweejt|3779166"
  57. },
  58. priw_ntpd: {
  59. namePL: "Notatnik",
  60. nameEN: "Notepad",
  61. descPL: "Dodaje prosty notatnik, dostępny pod torbami.",
  62. descEN: "Adds a simple notepad in the area under the bags.",
  63. urlPL: "http://priweejt.ct8.pl/NIAddons/get/notepadNI.js?",
  64. urlEN: "http://priweejt.ct8.pl/NIAddons/get/notepadNI.js?",
  65. img: "http://aldous.margonem.pl/img/gui/buttony.png?v=4|-437 -12",
  66. author: "Priweejt|3779166"
  67. },
  68. priw_extl: {
  69. namePL: "Instalator zewnętrznych skryptów",
  70. nameEN: "External script loader",
  71. descPL: "Pozwala instalować zewnętrzne dodatki przez wpisanie adresu do skryptu. <a href='https://gyazo.com/42856b0a644881f93b17e27ec02674ac' target='_blank'>Wygląda to tak.</a>",
  72. descEN: "Allows installing external scripts from a given url, as shown <a href='https://gyazo.com/dbdbffca2a65e982293caef243b96981' target='_blank'>here.</a>",
  73. urlPL: "http://priweejt.ct8.pl/NIAddons/get/NIextLoader.js?",
  74. urlEN: "http://priweejt.ct8.pl/NIAddons/get/NIextLoader.js?",
  75. img: "http://aldous.margonem.pl/img/gui/buttony.png?v=4|-282 -12",
  76. author: "Priweejt|3779166",
  77. widget: {
  78. color: "blue",
  79. }
  80. },
  81. priw_obw: {
  82. namePL: "Lepsza walka",
  83. nameEN: "Better battle",
  84. descPL: "Dodaje następujące rzeczy do walki:<br>-animowanie przesuwania się postaci<br>-bardziej widoczne pokazywanie naszej tury<br>-mniejsze odległości między postaciami w walce<br>-ilość życia, many i energii w tipach (dymkach) nad postaciami<br>-wybór umiejętności jak na starym interfejsie (można wyłączyć w dolnej części konfiguracji gry)",
  85. descEN: "Adds following features to the battle window:<br>-characters now move smoothly from place to place, instead of teleporting<br>-better indication of player's turn<br>-distance between characters is smaller<br>-health, energy and mana is shown in tooltips above characters<br>-alternative skill selection method, samilar to how it was on the old interface (this feature can be disabled at the bottom of game config)",
  86. // urlPL: "http://192.168.0.110:1337/NIoldBattle.js",
  87. urlPL: "http://priweejt.ct8.pl/NIAddons/get/NIoldBattle.js?7",
  88. urlEN: "http://priweejt.ct8.pl/NIAddons/get/NIoldBattle.js?7",
  89. img: "http://aldous.margonem.pl/img/gui/addons-icons.png|-4 -34",
  90. author: "Priweejt|3779166"
  91. },
  92. priw_mmp: {
  93. namePL: "miniMap+",
  94. nameEN: "miniMap+",
  95. descPL: "Dodaje do gry wielofunkcyjną minimapę. Domyślnie otwiera sie klawiszem [R]",
  96. descEN: "Adds a multifunctional minimap. Default hotkey to open it is set to [R]. Note that it hasn't been translated to English.",
  97. urlPL: "http://addons2.margonem.pl/get/64/64196public.js?4",
  98. urlEN: "http://addons2.margonem.pl/get/64/64196public.js?4",
  99. img: "http://aldous.margonem.pl/img/gui/buttony.png|-158 -12",
  100. author: "Priweejt|3779166"
  101. },
  102. priw_tth: {
  103. namePL: "Titan Helper+",
  104. nameEN: "Titan Helper+",
  105. descPL: "Opis by się tu nie zmieścił, dlatego jest <a href='https://pastebin.com/raw/4JE8Cunn' target='_blank'>tutaj</a>.<br><br>W razie problemów z wyświetlaniem informacji w oknie walki wynikających z małego ekranu, można się przełączyć na alternatywny sposób pokazywania w ustawieniach dodatku (są w ustawieniach gry).",
  106. descEN: "The description is too long to be put here, so it's on <a href='https://pastebin.com/raw/td5nBRBS' target='_blank'>pastebin</a> instead. <br><br>There may be issues with displaying things on small screens. If that's the case, you can switch to an alternative display method in addon settings (located inside of the game settings).<br><br>Do note that while the addon does work in the English version of the game, displayed strings hasn't been translated to English yet.",
  107. // urlPL: "http://127.0.0.1:1337/titanHelperPlusNI.js",
  108. urlPL: "http://addons2.margonem.pl/get/71/71328public.js",
  109. urlEN: "http://addons2.margonem.pl/get/71/71328public.js",
  110. img: "http://aldous.margonem.pl/img/gui/addons-icons.png|-4 -34",
  111. author: "Priweejt|3779166"
  112. },
  113. priw_sf: {
  114. namePL: "ShopFilter",
  115. nameEN: "ShopFilter",
  116. descPL: "Dodaje do sklepów dodatkowe opcje filtrowania.",
  117. descEN: "Adds additional filters to shops.",
  118. urlPL: "http://priweejt.ct8.pl/NIAddons/get/shopFilterNI.js",
  119. urlEN: "http://priweejt.ct8.pl/NIAddons/get/shopFilterNI.js",
  120. img: "http://aldous.margonem.pl/img/gui/addons-icons.png|-128 -3",
  121. author: "Priweejt|3779166"
  122. },
  123. /*priw_sakwa: {
  124. namePL: "Sakwa",
  125. nameEN: "Pouch",
  126. descPL: "Przywraca funkcjonalną sakwę ze starego interfejsu.",
  127. descEN: "Restores a functional pouch from the old interface.",
  128. urlPL: "http://priweejt.ct8.pl/NIAddons/get/pouch.js",
  129. urlEN: "http://priweejt.ct8.pl/NIAddons/get/pouch.js",
  130. img: "/obrazki/npc/mas/nic32x32.gif",
  131. author: "Priweejt|3779166"
  132. },*/
  133. priw_h2h: {
  134. namePL: "https2http",
  135. nameEN: "https2http",
  136. descPL: "Linki które mają z przodu https nie działają na chacie. Dodatek zamienia w wysyłanych wiadomościach https na http i wtedy działają.",
  137. descEN: "Fixes a bizzare bug that causes links that contain https to not work by replacing https with http in sent messages.",
  138. urlPL: "http://priweejt.ct8.pl/NIAddons/get/https2httpNI.js",
  139. urlEN: "http://priweejt.ct8.pl/NIAddons/get/https2httpNI.js",
  140. img: "http://aldous.margonem.pl/img/gui/buttony.png?v=4|-406 -12",
  141. author: "Priweejt|3779166"
  142. },
  143. groov_gll: {
  144. namePL: "Global lootlog",
  145. descPL: "Jest to dodatek, który umieszcza nasze looty heroiczne i legendarne na stronie, aby później móc je przeglądać. Podczas lootnięcia itemu zawsze mamy możliwość zdecydowania, czy ma on zostać tam dodany, czy też nie.<br><br>Dodatek zapisuje zdobycze ze światów publicznych i prywatnych.<br><br>Strona główna: <a href='http://grooove.pl/lootlog/' target='_blank'>http://grooove.pl/lootlog/</a>",
  146. urlPL: "http://addons2.margonem.pl/get/70/70663dev.js",
  147. img: "http://aldous.margonem.pl/img/gui/buttony.png|-158 -12",
  148. author: "Groove Armada|3088295",
  149. beforeInstall: function() {
  150. if ($("#GLobalLootlogLauncher").length) {
  151. message("Global lootlog jest już zainstalowany z innego źródła.");
  152. return true;
  153. };
  154. },
  155. noEN: true
  156. },
  157. groov_pw: {
  158. namePL: "Panel walk",
  159. nameEN: "Battle panel",
  160. descPL: "Dodatek automatycznie zapisuje walki z graczami na stronie, gdzie później ładnie je wyświetla.<br>Przykład: <a href='http://grooove.pl/battle/id-1' target='_blank'>http://grooove.pl/battle/id-1</a>",
  161. descEN: "This addon automatically saves battles aganist other players on a website, where they are nicely displayed.<br>Example: <a href='http://grooove.pl/battle/id-1' target='_blank'>http://grooove.pl/battle/id-1</a>",
  162. urlPL: "http://addons2.margonem.pl/get/70/70674dev.js",
  163. urlEN: "http://addons2.margonem.pl/get/70/70674dev.js",
  164. img: "http://aldous.margonem.pl/img/gui/addons-icons.png|-4 -34",
  165. author: "Groove Armada|3088295",
  166. beforeInstall: function() {
  167. if ($("#PWLauncher").length) {
  168. message("Panel walk jest już zainstalowany z innego źródła.");
  169. return true;
  170. };
  171. },
  172. },
  173. groov_count: {
  174. namePL: "Licznik ubić",
  175. nameEN: "Kill counter",
  176. descPL: "Liczy ubicia elit, elit II, herosów, tytanów i eventowych potworów.<br><br>Aby zresetować licznik lub usunąć pojedynczy wpis, należy wejść na stronę <a href='http://grooove.pl/licznik/' target='_blank'>http://grooove.pl/licznik/</a> i się zalogować.",
  177. descEN: "Counts how many times you've killed monsters with ranks above elite. To reset the counter or delete a single entry, you have to visit <a href='http://grooove.pl/licznik/' target='_blank'>http://grooove.pl/licznik/</a> and log in.",
  178. urlPL: "http://addons2.margonem.pl/get/70/70632dev.js",
  179. urlEN: "http://addons2.margonem.pl/get/70/70688dev.js",
  180. img: "http://aldous.margonem.pl/img/gui/addons-icons.png|-97 -34",
  181. author: "Groove Armada|3088295",
  182. beforeInstall: function() {
  183. if ($("#GACounterLauncher").length) {
  184. message("Licznik ubić jest już zainstalowany z innego źródła.");
  185. return true;
  186. };
  187. },
  188. },
  189. ake_coll: {
  190. namePL: "Pokazywanie kolizji",
  191. nameEN: "Show collisions",
  192. descPL: "Pokazuje kolizje na mapie.",
  193. descEN: "Shows map collisions.",
  194. urlPL: "http://addons2.margonem.pl/get/76/76788dev.js?3",
  195. urlEN: "http://addons2.margonem.pl/get/76/76788dev.js?3",
  196. img: "http://aldous.margonem.pl/img/gui/buttony.png|-702 -710",
  197. author: "Akechi|229327",
  198. widget: {
  199. color: "blue"
  200. }
  201. },
  202. /*ccar_evo: { [*]
  203. namePL: "Evolution Manager",
  204. nameEN: "Evolution Manager",
  205. descPL: "Wielofunkcyjny manager dodatków. <a target='_blank' href='https://www.margonem.pl/?task=forum&show=posts&id=469794'>Temat na forum</a>.<br>Instaluje się jego osobny userscript.",
  206. descEN: "multifunctional addon manager. <a target='_blank' href='https://www.margonem.pl/?task=forum&show=posts&id=469794'>Polish forum thread</a>.<br>Installs as a separate userscript.",
  207. urlPL: "http://m.ccrr.pl/evo/client/start.user.js",
  208. urlEN: "http://m.ccrr.pl/evo/client/start.user.js",
  209. img: "http://aldous.margonem.pl/img/gui/buttony.png|-437 -12",
  210. author: "Programista CcarderR|2210626",
  211. beforeInstall: function() {
  212. if (typeof (evoStart) != "undefined") {
  213. message("Evolution Manager jest już zainstalowany.");
  214. } else {
  215. window.open("http://m.ccrr.pl/evo/client/start.user.js");
  216. };
  217. return true;
  218. },
  219. },*/
  220. //eeeeeee darrowi padł hosting to na chwilę obecną wywalam z panelu
  221. /*darr_mm: {
  222. namePL: "Margomap",
  223. nameEN: "Margomap",
  224. descPL: "Prosta minimapa, otwiera się przyciskiem [E]",
  225. descEN: "A simple minimap, can be opened with the [E] button.",
  226. urlPL: "http://addons2.margonem.pl/get/77/77011dev.js?3",
  227. urlEN: "http://addons2.margonem.pl/get/77/77011dev.js?3",
  228. data: "http://addons2.darro.eu/js/margomap.js",
  229. img: "http://aldous.margonem.pl/img/gui/buttony.png|-158 -12",
  230. author: "Darrefull|359424",
  231. beforeInstall: function() {
  232. if (typeof window.DMargoMap != "undefined") {
  233. message("Margomap jest już zainstalowany z innego źródła.");
  234. return true;
  235. };
  236. },
  237. },
  238. darr_akh: {
  239. namePL: "Licznik Akh-Mater",
  240. descPL: "Liczy nawróconych i zapytanych do questa Słowo Akh-Mater..",
  241. urlPL: "http://addons2.margonem.pl/get/77/77011dev.js?3",
  242. data: "http://addons2.darro.eu/js/akh-mater.js",
  243. img: "http://aldous.margonem.pl/img/gui/buttony.png|-189 -12",
  244. author: "Darrefull|359424",
  245. beforeInstall: function() {
  246. if ($("div[data-tip*='Licznik do questa <br>Słowo Akh-Mate']").length > 0) {
  247. message("Licznik Akh-Mater jest już zainstalowany z innego źródła.");
  248. return true;
  249. };
  250. },
  251. noEN: true
  252. },
  253. darr_coun: {
  254. namePL: "Licznik ubić by Darrefull",
  255. descPL: "Liczy ubicia elit/e2/herosów/tytanów.",
  256. urlPL: "http://addons2.margonem.pl/get/77/77011dev.js?3",
  257. data: "http://addons2.darro.eu/js/counter.js",
  258. img: "http://aldous.margonem.pl/img/gui/addons-icons.png|-97 -34",
  259. author: "Darrefull|359424",
  260. beforeInstall: function() {
  261. if (typeof window.eCounter != "undefined") {
  262. message("Licznik ubić by Darrefull jest już zainstalowany z innego źródła.");
  263. return true;
  264. };
  265. },
  266. noEN: true
  267. }*/
  268. };
  269. function widgetPath() {
  270. return "hotWidget/"+Engine.interface.getPathToHotWidgetVersion(true);
  271. }
  272. this.addonIds = Object.keys(this.list);
  273. this.storageKey = "priwAddons";
  274. this.getStorage = function() {
  275. if (!this.storageCache) {
  276. this.storageCache = localStorage.getItem(this.storageKey) ? JSON.parse(localStorage.getItem(this.storageKey)) : [];
  277. };
  278. return this.storageCache;
  279. };
  280. this.setStorage = function(storage) {
  281. this.storageCache = storage;
  282. localStorage.setItem(this.storageKey, JSON.stringify(storage));
  283. };
  284. this.fixStorage = function() {
  285. var storage = this.getStorage();
  286. var len = storage.length;
  287. for (var i=0; i<storage.length; i++) {
  288. if (this.addonIds.indexOf(storage[i]) == -1) { //gracz ma nieinstniejący dodatek który zaśmieca storage
  289. //jak dodatek co został wywalony z listy miał widget to go trza wywalić
  290. //if (typeof storage[i] == "number") { //stare wersje dodatku były dziwaczne, tak just in case gdyby ktoś miał stary typ jeszcze. Kiedyś to wywalę
  291. // no i wywalilem, dobrze, ze zostawilem sobie notke dawno temu
  292. //if (API.Storage.get("hotWidget/addon_"+(storage[i]+1000))) API.Storage.remove("hotWidget/addon_"+(storage[i]+1000));
  293. //} else {
  294. if (API.Storage.get(widgetPath()+"/addon_"+storage[i])) API.Storage.remove("hotWidget/addon_"+storage[i]);
  295. //};
  296. storage.splice(i, 1);
  297. i--;
  298. };
  299. };
  300. if (len != storage.length) this.setStorage(storage);
  301. };
  302.  
  303. this.consoleHax = new (function() {
  304. var self = this;
  305. var handler;
  306. var $input = document.createElement("input");
  307. var $content;
  308. this.console = null;
  309.  
  310. this.init = function() {
  311. // as of one 1.23 update, log does not show console automatically
  312. Engine.interface.clickConsole();
  313. log(_l() == "pl" ? "Panel dodatków+ załadowany" : "Addon panel+ loaded");
  314. //teraz jak konsola jest pokazana kradniemy event handler
  315. try {
  316. handler = $._data(document.querySelector(".console-input"), "events").keydown[0].handler;
  317. } catch (e) {
  318. return console.error("consolehax failed");
  319. };
  320. //łapiemy jeszcze console-content
  321. $content = document.querySelector(".console-content");
  322. //i chowamy konsolę
  323. this.evalInConsoleScope("priwAddons.consoleHax.console=self;self.close();");
  324. }
  325. this.evalInConsoleScope = function(str) {
  326. $input.value = str;
  327. handler.call($input, {
  328. keyCode: 13
  329. });
  330. //jeszcze usuwamy widoczny input z konsoli żeby nie zaśmiecać
  331. this.removeLastConsoleMsg();
  332. }
  333. this.removeLastConsoleMsg = function() {
  334. $content.lastElementChild.remove();
  335. var $notif = document.querySelector("#consoleNotif");
  336. if ($notif) $notif.remove();
  337. if (this.console.isOpen) this.console.close();
  338. }
  339. })();
  340. this.consoleHax.init();
  341.  
  342. this.modules = new (function() {
  343. var self = this;
  344. function getFromConsoleHax(path) {
  345. addons.consoleHax.evalInConsoleScope("try{priwAddons.modules.module = require('"+path+"');}catch(e){console.error('Module "+path+" not found!');priwAddons.modules.module=false;}");
  346. return self.module;
  347. };
  348. this.init = function() {
  349. // this.Interface = getFromConsoleHax("core/Interface");
  350. this.Interface = window.Engine.interface; // no dobra, skoro tak zrobili to fajnie
  351.  
  352. this.Console = addons.consoleHax.console;
  353. };
  354. })();
  355. this.modules.init();
  356.  
  357. this.console = new (function() {
  358. var self = this;
  359. var Console = addons.modules.Console;
  360. var $content = Console.wnd.$[0].querySelector(".console-content");
  361. var commandLine = Console.commandLine;
  362. var customCmds = {
  363. "!help": {
  364. handler: () => {
  365. for (var i in customCmds) {
  366. if (customCmds[i].help) log("<b>"+i+"</b> - "+customCmds[i].help);
  367. }
  368. }
  369. }
  370. };
  371.  
  372. this.newCustomCmd = function(cmd) {
  373. /* przykładowe cmd:
  374. cmd = {
  375. name: "nazwa komendy",
  376. handler: n => console.log(n),
  377. [help: "opis co komanda robi"]
  378. }
  379.  
  380. */
  381. customCmds[cmd.name] = cmd;
  382. };
  383. this.cmdExists = function(cmd) {
  384. cmd = cmd.split(" ")[0];
  385. return customCmds[cmd] ? true : false;
  386. }
  387. this.parseCmd = function(cmd) {
  388. var args = cmd.split(" ");
  389. cmd = args.splice(0, 1)[0];
  390. cmd = customCmds[cmd];
  391. cmd.handler.apply(window, args);
  392. }
  393. this.log = function(txt, level) {
  394. switch (level) {
  395. case 1:
  396. txt = "<span style='color: yellow'>Warning: "+txt+"</span>";
  397. break;
  398. case 2:
  399. txt = "<span style='color: #9a6400'>Error: "+txt+"</span>";
  400. break;
  401. case 3:
  402. txt = "<span style='color: red; font-weight: bold;'>Fatal error: "+txt+"</span>";
  403. break;
  404. }
  405. var $log = document.createElement("div");
  406. $log.classList.add("console-message");
  407. $log.innerHTML = txt;
  408. $content.appendChild($log);
  409. if (level) {
  410. Console.showConNotif();
  411. };
  412. if (level == 3) Console.open();
  413. }
  414. this.init = function() {
  415. var _sendMessage = commandLine.sendMessage;
  416. commandLine.sendMessage = function(cmd) {
  417. if (!self.cmdExists(cmd)) {
  418. _sendMessage.apply(this, arguments);
  419. } else {
  420. log("<i style=color:white>> "+cmd+"</i>");
  421. document.querySelector("#console_input").value = "";
  422. self.parseCmd(cmd);
  423. }
  424. }
  425. }
  426. this.init();
  427. })();
  428.  
  429. this.getAddonState = function(id) {
  430. var storage = this.getStorage();
  431. return (storage.indexOf(id) > -1);
  432. };
  433. this.toggleAddon = function(id) {
  434. var storage = this.getStorage();
  435. if (storage.indexOf(id) > -1) {
  436. storage.splice(storage.indexOf(id), 1);
  437. } else {
  438. storage.push(id);
  439. };
  440. this.setStorage(storage);
  441. };
  442. this.fixStorage();
  443. this.loader = new (function(_ajax){
  444. var self = this;
  445. var lastAddonId;
  446. this.addonsLoaded = 0;
  447. this.waitForInterfaceChanger = false; //eliminuje potencjalną możliwość zagryzienia się z dodatkiem SI2NI
  448. if (typeof __bootNI != "undefined" && __bootNI) {
  449. var _reCallInitQueue = Engine.reCallInitQueue;
  450. this.waitForInterfaceChanger = true;
  451. Engine.reCallInitQueue = function() { //funckja ta zostaje uruchomiona przez SI2NI gdy skończy ładować swoje dodatki
  452. self.waitForInterfaceChanger = false;
  453. Engine.reCallInitQueue = _reCallInitQueue;
  454. self.loadAddon();
  455. };
  456. };
  457. $.ajax = function(options) {
  458. if (options.url.indexOf("engine?t=") > -1) addons.parseInput = options.success;
  459. if (self.addonsLoaded < addons.addonIds.length && options.url.indexOf("engine?t=init") > -1) {
  460. self.loadAddon();
  461. return;
  462. } else if (options.url.indexOf("margonem.pl/config.php") > -1) {
  463. var oldsuccess = options.success;
  464. options.success = function(data) {
  465. addons.afterGameBoot();
  466. var ret = oldsuccess.apply(this, arguments);
  467. addons.afterInterfaceLoad();
  468. return ret;
  469. };
  470. } else if (options.url.indexOf("engine?t=") > -1) {
  471. var oldsuccess = options.success;
  472. var url = options.url;
  473. options.success = function(data) {
  474. addons.callbackParser(data, url, true);
  475. var ret = oldsuccess.apply(this, arguments);
  476. addons.callbackParser(data, url);
  477. return ret;
  478. };
  479. };
  480. return _ajax.apply(this, arguments);
  481. };
  482. this.loadAddon = function() {
  483. var id = addons.addonIds[this.addonsLoaded];
  484. lastAddonId = id;
  485. if (addons.getAddonState(id)) {
  486. var addon = addons.list[id];
  487. if (addon.beforeInstall && addon.beforeInstall()) { //failsafe jakby ktoś coś odwalił
  488. addons.toggleAddon(id);
  489. return this.onAddonLoad(true);
  490. };
  491. if (!$.cachedScript) jQuery.cachedScript=function(e,c){return c=$.extend(c||{},{dataType:"script",cache:!0,url:e}),jQuery.ajax(c)};
  492. var url = this.getUrl(addon);
  493. window.__currentAddon = {
  494. id: addons.addonIds[this.addonsLoaded],
  495. data: addon.data
  496. };
  497. if (url.indexOf("?") > -1) url += "&v="+((new Date()).toLocaleDateString());
  498. else url += "?v="+((new Date()).toLocaleDateString());
  499. $.cachedScript(url).done(this.onAddonLoad).fail((xhr) => this.failedAddonLoad(id, xhr));
  500. //$.getScript(url).done(this.onAddonLoad).fail((xhr) => this.failedAddonLoad(id, xhr));
  501. } else {
  502. this.onAddonLoad(true);
  503. };
  504. };
  505. this.onAddonLoad = function(notLoaded) {
  506. if (notLoaded !== true) {
  507. var addon = addons.list[lastAddonId];
  508. addons.console.log("addon '"+ (_l() == "pl" ? addon.namePL : addon.nameEN) + "' loaded succesfully");
  509. };
  510. self.addonsLoaded++;
  511. if (self.addonsLoaded < addons.addonIds.length) {
  512. self.loadAddon();
  513. } else {
  514. self.loadExtraAddons();
  515. };
  516. };
  517. var extraLoadFinished = false;
  518. var extraAddonsLoaded = -1;
  519. this.loadExtraAddons = function(failed) {
  520. if (extraAddonsLoaded >= 0 && !failed) addons.console.log("script from "+extraAddons[extraAddonsLoaded]+" loaded succesfully");
  521. extraAddonsLoaded++;
  522. if (extraAddonsLoaded < extraAddons.length) {
  523. var url = extraAddons[extraAddonsLoaded];
  524. $.cachedScript(url).done(self.loadExtraAddons).fail((xhr) => self.failedExtraAddonLoad(url, xhr));
  525. } else {
  526. if (!self.waitForInterfaceChanger) {
  527. extraLoadFinished = true;
  528. Engine.reCallInitQueue();
  529. };
  530. };
  531. };
  532. this.require = function(url) {
  533. if (!extraLoadFinished) extraAddons.push(url);
  534. else throw "Ładowanie już się zakończyło.";
  535. };
  536. var extraAddons = [];
  537. this.failedAddonLoad = function(id, xhr) {
  538. var addon = addons.list[id];
  539. //if (_l() == "pl") console.warn("Nie udało się załadować dodatku "+addon.namePL+" ["+this.getUrl(addon)+"] ("+xhr.status + " - "+xhr.statusText+")");
  540. //else console.warn("Failed to load addon "+addon.nameEN+" ["+this.getUrl(addon)+"] ("+xhr.status + " - "+xhr.statusText+")");
  541. addons.console.log("failed to load addon '"+(_l() == "pl" ? addon.namePL : addon.nameEN)+"' ("+xhr.status + " - "+xhr.statusText+")", 1);
  542. this.onAddonLoad(true);
  543. };
  544. this.failedExtraAddonLoad = function(url, xhr) {
  545. //if (_l() == "pl") console.warn("Nie udało się załadować skryptu z require "+url);
  546. //else console.warn("Failed to load required script "+url);
  547. addons.console.log("failed to load script from "+url+" ("+xhr.status + " - "+xhr.statusText+")", 1);
  548. this.loadExtraAddons(true);
  549. };
  550. this.getUrl = function(addon) {
  551. return _l() == "pl" ? addon.urlPL : addon.urlEN;
  552. };
  553. })($.ajax);
  554. var __g = _g;
  555. _g = function(url, extra) {
  556. var ret = addons.requestParser(url, extra);
  557. arguments[0] = ret[0];
  558. arguments[1] = ret[1];
  559. return __g.apply(this, arguments);
  560. };
  561. this.requestParser = function(url, extra) {
  562. for (var i=0; i<this.requestParsers.length; i++) {
  563. var ret =this.requestParsers[i](url, extra);
  564. url = ret[0];
  565. extra = ret[1];
  566. };
  567. return [url, extra];
  568. };
  569. this.requestParsers = [];
  570. this.callbackParser = function(data, url, before) {
  571. if (!before) {
  572. for (var i=0; i<this.extraServerCallbacks.length; i++) {
  573. this.extraServerCallbacks[i](data, url);
  574. };
  575. };
  576. for (var i in data) {
  577. this.emmiter.emit((before ? "before-" : "")+i, data[i]);
  578. };
  579. this.emmiter.emit((before ? "before-" : "")+"game-response", data);
  580. };
  581. //idk moja implementacja pewnie nie w 100% taka sama
  582. this.Emmiter = function() {
  583. var on = [];
  584. var once = [];
  585. this.on = function(type, fun) {
  586. on.push(type, fun);
  587. return fun;
  588. };
  589. this.once = function(type, fun) {
  590. once.push(type, fun);
  591. return fun;
  592. };
  593. this.off = function(fun) {
  594. for (var i=1; i<on.length; i+=2) {
  595. if (on[i] == fun) {
  596. return on.splice(i-1, 2);
  597. };
  598. };
  599. };
  600. this.emit = function(type, data) {
  601. for (var i=0; i<once.length; i+=2) {
  602. if (once[i] == type) {
  603. once[i+1](data);
  604. once.splice(i, 2);
  605. i -= 2;
  606. };
  607. };
  608. for (var i=0; i<on.length; i+=2) {
  609. if (on[i] == type) {
  610. on[i+1](data);
  611. }
  612. };
  613. };
  614. };
  615. this.emmiter = new this.Emmiter();
  616. this.extraServerCallbacks = [];
  617. this.checkForMismatch = function() { //jakby coś poszło nie tak
  618. for (var i in this.list) {
  619. if (this.getAddonState(i) != Engine.addonsPanel.getStorageStateOfAddon(i)) {
  620. Engine.addonsPanel.toggleStateAddon(i);
  621. };
  622. };
  623. };
  624. this.addedCustomAddons = false;
  625. this.doAfterGameBoot = [];
  626. this.doAfterInterfaceLoad = [];
  627. this.afterGameBoot = function() {
  628. for (var i in this.list) {
  629. var addon = this.list[i];
  630. if (addon.widget) {
  631. var store = API.Storage.get(widgetPath() + "/addon_"+i);
  632. if (store) Engine.addonsPanel.addKeyToWidgets(i, store, _l() == "pl" ? addon.namePL : addon.nameEN);
  633. };
  634. };
  635. var _addonsShow = Engine.addonsPanel.manageVisible;
  636. Engine.addonsPanel.manageVisible = function() {
  637. var ret = _addonsShow.apply(this, arguments);
  638. if (!addons.addedCustomAddons) {
  639. addons.checkForMismatch();
  640. addons.addCustomAddonsToList();
  641. addons.addedCustomAddons = true;
  642. };
  643. addons.emmiter.emit("addons-toggle");
  644. return ret;
  645. };
  646. var fun = function(id) {
  647. if (addons.isCustomAddon(id)) {
  648. if (addons.addedCustomAddons && !addons.getAddonState(id)) {
  649. message(addons.reloadMsg);
  650. addons.toggleAddon(id);
  651. var addon = addons.list[id];
  652. if (addon.widget && !window["addon_"+id]) {
  653. window["addon_"+id] = {
  654. manageVisible: () => message("Dodatek zacznie działać po odświeżeniu gry")
  655. };
  656. };
  657. };
  658. } else {
  659. _startAddonScript.apply(this, arguments);
  660. };
  661. };
  662. //dziwna różnica iędzy polskim a angielskim margonem
  663. if (Engine.addonsPanel.startAddonScript) {
  664. var _startAddonScript = Engine.addonsPanel.startAddonScript;
  665. Engine.addonsPanel.startAddonScript = fun;
  666. } else {
  667. var _startAddonScript = Engine.addonsPanel.turnOnAddon;
  668. Engine.addonsPanel.turnOnAddon = fun;
  669. };
  670. var _turnOffAddon = Engine.addonsPanel.turnOffAddon;
  671. Engine.addonsPanel.turnOffAddon = function(id) {
  672. if (addons.isCustomAddon(id)) {
  673. if (addons.addedCustomAddons && addons.getAddonState(id)) {
  674. message(addons.reloadMsg);
  675. addons.toggleAddon(id);
  676. if (addons.list[id].widget) {
  677. $(".icon.addon_"+id).parent().remove();
  678. if (API.Storage.get(widgetPath() + "/addon_"+id)) API.Storage.remove(widgetPath()+"/addon_"+id);
  679. };
  680. };
  681. } else {
  682. _turnOffAddon.apply(this, arguments);
  683. };
  684. };
  685. var _setStateAddon = Engine.addonsPanel.setStateAddon;
  686. Engine.addonsPanel.setStateAddon = function(state, id) {
  687. if (addons.isCustomAddon(id) && state && addons.addedCustomAddons) {
  688. var addon = addons.list[id];
  689. if (addon.beforeInstall && addon.beforeInstall()) return;
  690. };
  691. return _setStateAddon.apply(this, arguments);
  692. };
  693. this.initCss();
  694. for (var i=0; i<this.doAfterGameBoot.lenth; i++) {
  695. this.doAfterGameBoot[i]();
  696. };
  697. this.emmiter.emit("game-load");
  698. };
  699. this.afterInterfaceLoad = function() {
  700. for (var i=0; i<this.doAfterInterfaceLoad.length; i++) {
  701. this.doAfterInterfaceLoad[i]();
  702. };
  703. this.emmiter.emit("interface-load");
  704. };
  705. this.isCustomAddon = function(id) {
  706. return (this.addonIds.indexOf(id) > -1);
  707. };
  708. this.addCustomAddonHeader = function() {
  709. var $wnd = Engine.addonsPanel.wnd.$[0];
  710. var $list = $wnd.querySelector(".addon-list");
  711. var $header = document.createElement("div");
  712. $header.classList.add("custom-addon-header");
  713. $header.innerHTML = _l() == "pl" ? "Nieoficjalne dodatki" : "Custom addons";
  714. $list.appendChild($header);
  715. };
  716. this.addCustomAddonsToList = function() {
  717. this.addCustomAddonHeader();
  718. for (let id in this.list) {
  719. const addon = this.list[id];
  720. if (_l() == "en" && addon.noEN) continue;
  721. if (_l() == "pl" && addon.noPL) continue;
  722. const author = addon.author.split("|");
  723. const authorHtml = "<div class='addon-author'>by <a href='http://www.margonem.pl/?task=profile&id="+author[1]+"' target='_blank'>"+author[0]+"</a></div>";
  724. const addonToAdd = {
  725. pl: {
  726. name: addon.namePL,
  727. description: addon.descPL + authorHtml
  728. },
  729. en: {
  730. name: addon.nameEN,
  731. description: addon.descEN + authorHtml
  732. },
  733. image: addon.img,
  734. options: addon.widget ? 1 : 0,
  735. id: id // apparently this is required now
  736. };
  737. Engine.addonsPanel.createOneAddonOnList(addonToAdd, id);
  738. Engine.addonsPanel.createOneAddonDescription(addonToAdd, id);
  739. }
  740. };
  741. this.reloadMsg = _l() == "pl" ? "Zmiany będą widoczne po odświeżeniu gry..." : "Changes will come into effect once the page has been reloaded...";
  742. this.initCss = function() {
  743. var css = `
  744. .addon-author {
  745. font-size: 75%;
  746. text-align: right;
  747. color: #333333;
  748. }
  749. .custom-addon-header {
  750. text-align: center;
  751. border-bottom: 1px solid #4b4949;
  752. font-size: 125%;
  753. color: #777777;
  754. height: 30px;
  755. line-height: 30px;
  756. }
  757. `;
  758. var widgets = {};
  759. for (var i in this.list) {
  760. var addon = this.list[i];
  761. if (!addon.widget) continue;
  762. if (addon.widget !== true) {
  763. widgets[i] = addon.widget;
  764. widgets[i].id = i;
  765. };
  766. css += `
  767. .icon.addon_`+i+` {
  768. background: `+Engine.addonsPanel.createBackgroundString(addon.img)+` !important;
  769. }
  770. `;
  771. };
  772. this.emmiter.once("interface-load", ()=>this.widget.changeWidgetCss(widgets));
  773. $("<style>"+css+"</style>").appendTo("head");
  774. };
  775. //kod z Interface.showPopupMenu
  776. var $aLayer = $(document.getElementsByClassName("alerts-layer")[0]);
  777. this.popupMenu = function(menu, e) {
  778. if (!menu.length) return;
  779. var $m = $('<div class="custom-popup-menu"></div>');
  780. var $btn = API.Templates.get('button').addClass('small');
  781. for (var i in menu) {
  782. (function (i) {
  783. var clone = $('<div class="menu-item">' + menu[i][0] + '</div>');
  784. if (isset(menu[i][2])) {
  785. clone.addClass(menu[i][2].button.cls);
  786. }
  787. $(clone).click(function (e) {
  788. if (menu[i][1]()) e.stopPropagation();
  789. });
  790. $m.append(clone);
  791. })(i);
  792. };
  793. var zIndex = $aLayer.children().length + 1;
  794. $aLayer.append($m);
  795. $m.css({
  796. top: e.clientY - $m.height() / 2,
  797. left: e.clientX - $m.width() / 2,
  798. 'z-index': zIndex
  799. }).addClass('show');
  800.  
  801. e.stopPropagation();
  802. };
  803. document.addEventListener("click", () => {
  804. $('.custom-popup-menu').remove();
  805. })
  806. var $popupStyle = document.createElement("style");
  807. //nie, nie mogę użyć normalnej klasy popup-menu bo gra kasuje element zanim mój eveneListener odpali ._.
  808. //nie rozumiem jakim prawem tak się dzieje, ale niektóre rzeczy trzeba po prostu przyjąć do wiadomości bez rozumienia
  809. $popupStyle.innerHTML = `
  810. .custom-popup-menu {
  811. border: 5px solid;
  812. max-width: 150px;
  813. border-image: url(../img/gui/ramka.png) 6 repeat;
  814. -webkit-transform: scale(0);
  815. -webkit-transition: 0.2s linear;
  816. -webkit-transition-timing-function: cubic-bezier(0.68, 0.77, 0.4, 1.89);
  817. z-index: 1;
  818. background-color: #3F3B3D;
  819. background-clip: padding-box;
  820. pointer-events: auto;
  821. position: absolute;
  822. }
  823. .custom-popup-menu .menu-item {
  824. cursor: url(../img/gui/cursor/5.png), auto;
  825. padding: 2px 5px;
  826. display: block;
  827. margin-bottom: 1px;
  828. font-size: 12px;
  829. text-align: center;
  830. border-radius: 3px;
  831. background-color: #244518;
  832. color: white;
  833. border: 1px solid #396420;
  834. }
  835. .custom-popup-menu .menu-item:last-child {
  836. margin-bottom: 0px;
  837. }
  838. .custom-popup-menu .menu-item.label {
  839. cursor: url(../img/gui/cursor/1.png), auto;
  840. border: 0px;
  841. background-color: transparent;
  842. }
  843. .custom-popup-menu .menu-item:hover:not(.label) {
  844. border: 1px solid #4f7b21;
  845. background-color: #2e4f18;
  846. }
  847. .custom-popup-menu.show {
  848. -webkit-transform: scale(1);
  849. }
  850. .custom-popup-menu .s_cost {
  851. display: inline-block;
  852. margin-left: 5px;
  853. font-weight: bold;
  854. border: 1px solid rgba(0, 0, 0, 0.3);
  855. border-radius: 3px;
  856. background-color: rgba(0, 0, 0, 0.2);
  857. padding: 0px 3px;
  858. color: lightblue;
  859. line-height: 15px;
  860. }
  861. `;
  862. document.head.appendChild($popupStyle);
  863.  
  864.  
  865. this.dictionary = new (function() {
  866. var list = {};
  867. this.get = function(id, data) {
  868. var str = list[id];
  869. if (!str) return "missing["+id+"]";
  870. str = str[_l()];
  871. if (!str) return "nolang["+id+"]";
  872. for (var i in data) {
  873. str = str.replace(i, data[i]);
  874. };
  875. return str;
  876. };
  877. this.add = function(id, txt) {
  878. list[id] = txt; //txt = {en: "txten", pl: "txtpl"}
  879. };
  880. this.addMany = function(data) {
  881. for (var i=0; i<data.length; i++) {
  882. this.add(data[i].id, data[i].txt);
  883. };
  884. };
  885. })();
  886. var _txt = this.dictionary.get;
  887.  
  888. //custom settings for addons
  889. this.settings = new (function() {
  890. var self = this;
  891. var extraSettings = [];
  892. var $extraSettings, $scrollPane;
  893. addons.dictionary.add("addon_settings", {
  894. pl: "Ustawienia dodatków",
  895. en: "Addon settings"
  896. })
  897. if (!Storage.get("addonsettings")) {
  898. Storage.set("addonsettings", {});
  899. };
  900. this.init = function() {
  901. var _old = Engine.settings.toggle;
  902. Engine.settings.toggle = function() {
  903. var ret = _old.apply(this, arguments);
  904. self.manageExtraSettings();
  905. addons.emmiter.emit("settings-toggle");
  906. return ret;
  907. };
  908. };
  909. this.updateSettingTable = function() {
  910. $extraSettings = document.createElement("div");
  911. $extraSettings.classList.add("seccond-c");
  912.  
  913. var $header = document.createElement("h2");
  914. $header.classList.add("settings-addons");
  915. $header.innerHTML = "<span>"+_txt("addon_settings")+"</span>";
  916. $extraSettings.appendChild($header);
  917.  
  918. var $list = document.createElement("ul");
  919. $list.classList.add("hero-options");
  920. var html = "", setting, enabled;
  921. for (var i=0; i<extraSettings.length; i++) {
  922. setting = extraSettings[i];
  923. enabled = Storage.get("addonsettings/"+setting.id) ? " active" : "";
  924. html += "<li data-setting_id='"+setting.id+"'><span class='checkbox"+enabled+"'></span><span class='label'>"+setting.txt+"</span></li>";
  925. };
  926. $list.innerHTML = html;
  927. $list.addEventListener("click", this.toggleSetting);
  928. $extraSettings.appendChild($list);
  929. };
  930. this.toggleSetting = function(e) {
  931. const path = e.composedPath(); // e.path tylko na chrome jest, upsik
  932. for (var i=0; i<path.length; i++) {
  933. if (path[i].dataset["setting_id"]) {
  934. var li = path[i];
  935. var children = li.children;
  936. var enabled = !Storage.get("addonsettings/"+li.dataset["setting_id"]);
  937. Storage.set("addonsettings/"+li.dataset["setting_id"], enabled);
  938. for (var i=0; i<children.length; i++) {
  939. if (children[i].classList.contains("checkbox")) {
  940. if (enabled) children[i].classList.add("active");
  941. else children[i].classList.remove("active");
  942. break;
  943. };
  944. };
  945. addons.emmiter.emit("toggle-addon-"+li.dataset["setting_id"], enabled);
  946. break;
  947. };
  948. };
  949. };
  950. this.manageExtraSettings = function() {
  951. if (!extraSettings.length) return;
  952. var $settings = document.getElementsByClassName("settings-window")[0];
  953. if ($settings) {
  954. //tfw uparłeś się na nieużywanie jquery
  955. var children = $settings.children;
  956. for (var i=0; i<children.length; i++) {
  957. if (children[i].classList.contains("hero-options-config")) {
  958. children = children[i].children[0].children; //xd
  959. break;
  960. };
  961. };
  962. for (var i=0; i<children.length; i++) {
  963. if (children[i].classList.contains("scroll-pane")) {
  964. $scrollPane = children[i];
  965. break;
  966. };
  967. };
  968. if (!$scrollPane) return console.warn("coś się zepsuło");
  969. $scrollPane.appendChild($extraSettings);
  970. };
  971. };
  972. this.add = function(data) {
  973. extraSettings.push(data);
  974. self.updateSettingTable();
  975. if (Storage.get("addonsettings/"+data.id) == null) Storage.set("addonsettings/"+data.id, data.default);
  976. };
  977. this.get = function(id) {
  978. return Storage.get("addonsettings/"+id);
  979. };
  980. //this.add({
  981. // txt: "test",
  982. // id: "test-setting",
  983. // default: true
  984. //});
  985. addons.emmiter.once("interface-load", this.init);
  986. })();
  987.  
  988. //window constructor
  989. this.Window = function(options) {
  990. //zrobiłem to zanim odkryłem że jest API.Window
  991. //także iksde, ale to się chyba łatwiej używa to eeee zostawie, zwłaszcza że już 1 dodatek z tym zrobiłem xDD
  992. /* =OPTIONS=
  993. WYMAGANE:
  994. /Jedno z dwóch:
  995. -txt: zawartość HTML okna
  996. -element: element do podpięcia do zawartości okna (przez $(...).append)
  997. /
  998. -header: nagłówek okna
  999. OPCJONALNE
  1000. -likemAlert: bool, czy okno ma posiadać klasę mAlert (default: false)
  1001. -noClose: bool, czy ma zostać usunięty przycisk zamykania (default: false)
  1002. -callbacks: array, taki sam jak ma mAlert w drugim argumencie (default: [])
  1003. -onClose: f, funkcja jaka wykona się przy zamknięciu okna (default: none)
  1004. -css: style css które będą nadane oknu
  1005. */
  1006. var txt = "this will be hijacked " + new Date().getTime();
  1007. options.callbacks = options.callbacks ? options.callbacks : [];
  1008. mAlert(txt, options.callbacks);
  1009. this.$ = $(".border-window:contains('"+txt+"')"); //dobra użyję jquery bo robienie tego bez przekracza moją cierpliwość
  1010. this.$[0].classList.remove("no-exit-button");
  1011.  
  1012. var $content = this.$.find(".inner-content");
  1013. if (options.txt) $content[0].innerHTML = options.txt;
  1014. else {
  1015. $content[0].innerHTML = "";
  1016. $content.append(options.element);
  1017. };
  1018. if (options.css) {
  1019. Object.assign(this.$[0].style, options.css);
  1020. }
  1021.  
  1022. var $header = this.$.find(".text");
  1023. $header[0].innerHTML = options.header;
  1024.  
  1025. var $close = this.$.find(".close-button");
  1026. var close = $._data($close[0], "events").click[0].handler; //kradniemy funkcję zamykającą okno
  1027. $close[0].removeEventListener("click", close);
  1028. if (options.noClose) $close.parent().remove();
  1029.  
  1030. if (!options.likemAlert) this.$[0].classList.remove("mAlert");
  1031.  
  1032. this.setContent = function(html) {
  1033. $content[0].innerHTML = html;
  1034. };
  1035. this.setHeader = function(html) {
  1036. $header[0].innerHTML = html;
  1037. };
  1038. this.appendContent = function(element) {
  1039. $content.append(element);
  1040. };
  1041. this.clearContent = function() {
  1042. $content[0].innerHTML = "";
  1043. };
  1044. this.close = function() {
  1045. if (options.onClose) options.onClose();
  1046. close();
  1047. };
  1048. $close[0].addEventListener("click", this.close);
  1049. };
  1050.  
  1051. //widget-related functionality
  1052. this.widget = new (function(addons) {
  1053. /*
  1054. stored widget data (in hotWidget/"+Engine.interface.getPathToHotWidgetVersion()+"widgetID/):
  1055. [0] - number of spaces from corner
  1056. [1] - corner (top-left, bottom-right etc, can also be top-left-additional)
  1057.  
  1058. widget instance:
  1059. name: displayed name
  1060. index: stored data[0]
  1061. corner: stored data[1]; if set to FREE empty space for the widget will be found automatically (and index parameter can be ommited)
  1062. id: id to be stored
  1063. icon: bg, in format url|bpos, e.g. http://aldous.margonem.pl/img/gui/buttony.png?v=4|-406 -12
  1064. clb: callback function when widget is clicked
  1065. color (optional): color for the widget. Can be blue, red, violet or green. Defaults to green.
  1066. css (optional): object with css style that will be added to the widget. Set by Object.assign and not $(...).css, so all values must be valid
  1067. */
  1068. var self = this,
  1069. addedWidgets = {},
  1070. loaded = false,
  1071. addedWidgets2 = {};
  1072. var dict = addons.dictionary;
  1073. this.addWidgetData = function() {
  1074. var widgets = self.getCustomAddonList();
  1075. var realID;
  1076. var style = "";
  1077. for (var id in widgets) {
  1078. realID = id.substring(14, id.length);
  1079. if (addedWidgets[realID]) {
  1080. Engine.addonsPanel.addKeyToWidgets("_custom_"+realID, widgets[id], addedWidgets[realID].name);
  1081. style += self.getAddonStyle(addedWidgets[realID].id, addedWidgets[realID].icon);
  1082. } else API.Storage.remove(widgetPath() + "/" +id);
  1083. };
  1084. var $style = document.createElement("style");
  1085. $style.innerHTML = style;
  1086. document.head.appendChild($style);
  1087. loaded = true;
  1088. }
  1089. this.getCustomAddonList = function() {
  1090. var widgets = API.Storage.get(widgetPath());
  1091. var custom = {};
  1092. for (var id in widgets) {
  1093. if (id.indexOf("_custom_") > -1) {
  1094. custom[id] = widgets[id];
  1095. }
  1096. }
  1097. return custom;
  1098. }
  1099. this.add = function(widget) {
  1100. if (!API.Storage.get(widgetPath()+"/addon__custom_"+widget.id)) {
  1101. var pos = this.generateWidgetPos(widget);
  1102. if (pos) API.Storage.set(widgetPath()+"/addon__custom_"+widget.id, pos);
  1103. else return true;
  1104. };
  1105. addedWidgets[widget.id] = widget;
  1106. window["addon__custom_"+widget.id] = {
  1107. manageVisible: widget.clb
  1108. };
  1109. return false;
  1110. }
  1111. this.generateWidgetPos = function(widget) {
  1112. if (widget.corner != "FREE") return [index, corner];
  1113. else return this.findFreeWidgetPosition();
  1114. }
  1115. this.findFreeWidgetPosition = function() {
  1116. var widgets = API.Storage.get("hotWidget");
  1117. for (var i=0; i<2; i++) {
  1118. var pos1 = !i ? "top" : "bottom";
  1119. for (var j=0; j<2; j++) {
  1120. var pos2 = !j ? "left" : "right";
  1121. for (var k=0; k<2; k++) {
  1122. if (pos1 == "top" && k) continue;
  1123. var additional = !k ? "" : "-additional";
  1124. var fullpos = pos1+"-"+pos2+additional;
  1125. for (var l=0; l<7; l++) {
  1126. if (!this.checkIfWidgetExists(l, fullpos, widgets)) return [l, fullpos];
  1127. };
  1128. }
  1129. }
  1130. }
  1131. return false;
  1132. }
  1133. this.checkIfWidgetExists = function(pos, corner, widgets) {
  1134. if (!widgets) widgets = API.Storage.get(widgetPath());
  1135. for (var i in widgets) {
  1136. if (widgets[i][0] == pos && widgets[i][1] == corner) return true;
  1137. }
  1138. return false;
  1139. }
  1140. this.getAddonStyle = function(id, icon) {
  1141. return `
  1142. .icon.addon__custom_${id} {
  1143. background: ${Engine.addonsPanel.createBackgroundString(icon)} !important;
  1144. }
  1145. `;
  1146. }
  1147. this.changeWidgetCss = function(widgets, custom) {
  1148. //cache stuff
  1149. if (!custom) addedWidgets2 = widgets;
  1150. for (var id in widgets) {
  1151. var widget = widgets[id];
  1152. if (widget.color || widget.css) {
  1153. var $widget = document.getElementsByClassName((custom ? "addon__custom_" : "addon_")+widget.id)[0];
  1154. if (!$widget) continue;
  1155. else $widget = $widget.parentElement;
  1156. if (widget.color) {
  1157. $widget.classList.remove("green");
  1158. $widget.classList.add(widget.color);
  1159. }
  1160. if (widget.css) {
  1161. Object.assign($widget.style, widget.css);
  1162. }
  1163. }
  1164. }
  1165. }
  1166. this.init = function() {
  1167. addons.emmiter.once("game-load", this.addWidgetData);
  1168. addons.emmiter.once("interface-load", ()=>{
  1169. this.changeWidgetCss(addedWidgets, true);
  1170. var observer = new MutationObserver(this.onWidgetUpdate);
  1171. for (var i=0; i<2; i++) {
  1172. var pos1 = i ? "top" : "bottom";
  1173. for (var j=0; j<2; j++) {
  1174. var pos2 = j ? "right" : "left";
  1175. observer.observe(document.querySelector("."+pos1+"-"+pos2+".main-buttons-container"), {
  1176. childList: true
  1177. })
  1178. }
  1179. }
  1180. });
  1181. }
  1182. this.onWidgetUpdate = function(mutations, observer) {
  1183. if (mutations.length > 1) {
  1184. addons.emmiter.emit("widget-update");
  1185. //readd css to widgets as they are all reset if this code runs
  1186. self.changeWidgetCss(addedWidgets, true);
  1187. self.changeWidgetCss(addedWidgets2);
  1188. };
  1189. }
  1190. this.init();
  1191. })(this);
  1192.  
  1193. this.addonDisplay = new (function(addons) {
  1194. //TODO
  1195. //zmienić pokazywanie ikonek i nazwy klas bo założenia się trochę zmieniły w trakcie robienia a nazwy zostały
  1196. var self = this,
  1197. list = [],
  1198. movedToWindow = [],
  1199. hidden = true,
  1200. $wrapper,
  1201. $singleWrapper,
  1202. $scrollWrapper,
  1203. $scrollContent,
  1204. $title,
  1205. $bagHide,
  1206. $bag,
  1207. $CLLTable,
  1208. currentDisplay = false,
  1209. loadQueue = [];
  1210. this.add = function(options) {
  1211. if ($wrapper == null) {
  1212. loadQueue.push(options);
  1213. return;
  1214. }
  1215. if (hidden) {
  1216. $wrapper.style["display"] = "block";
  1217. hidden = false;
  1218. }
  1219. var $element = document.createElement("div");
  1220. $element.classList.add("addonDisplay-single-display")
  1221. if (options.noTitle) {
  1222. $element.classList.add("long");
  1223. }
  1224. if (options.noForcedWndHeight) {
  1225. $element.classList.add("noForcedWndHeight");
  1226. }
  1227. if (options.html) {
  1228. $element.innerHTML += options.html;
  1229. } else if (options.element) {
  1230. $element.appendChild(options.element);
  1231. }
  1232. var $shortcut = document.createElement("div");
  1233. if (!options.icon) {
  1234. $shortcut.innerHTML = options.name.charAt(0);
  1235. } else {
  1236. $shortcut.innerHTML = "<img width='25px' height='25px' src='"+options.icon+"'>";
  1237. }
  1238. $shortcut.addEventListener("click", () => {
  1239. this.loadDisplay(options.id);
  1240. });
  1241. $shortcut.addEventListener("contextmenu", e => {
  1242. e.preventDefault();
  1243. this.moveDisplayToWindow(options.id);
  1244. });
  1245. $shortcut.dataset["tip"] = options.name;
  1246. $scrollContent.appendChild($shortcut);
  1247. list.push({
  1248. $: $element,
  1249. $short: $shortcut,
  1250. id: options.id,
  1251. name: options.name,
  1252. wndStyle: options.wndStyle,
  1253. noTitle: options.noTitle,
  1254. noForcedWndHeight: options.noForcedWndHeight
  1255. })
  1256. }
  1257. this.moveDisplayToWindow = function(id) {
  1258. var display = this.getDisplayById(id);
  1259. display.$short.style["display"] = "none";
  1260. if (currentDisplay == display) {
  1261. //display.$.remove();
  1262. //$title.innerHTML = "";
  1263. //currentDisplay = false;
  1264. for (var i=0; i<list.length; i++) {
  1265. var disp = list[i];
  1266. if (disp.id != display.id && movedToWindow.indexOf(disp.id) == -1) {
  1267. this.loadDisplay(disp.id);
  1268. break;
  1269. }
  1270. if (i+1 == list.length) {
  1271. currentDisplay = false;
  1272. }
  1273. }
  1274. }
  1275. if (movedToWindow.indexOf(id) == -1) {
  1276. movedToWindow.push(id);
  1277. Storage.set("addonDisplay/movedToWindow", movedToWindow);
  1278. }
  1279. if (movedToWindow.length == list.length) {
  1280. hidden = true;
  1281. $wrapper.style["display"] = "none";
  1282. }
  1283. this.createDisplayWindow(display);
  1284. }
  1285. this.createDisplayWindows = function() {
  1286. for (var i=0; i<movedToWindow.length; i++) {
  1287. var display = this.getDisplayById(movedToWindow[i]);
  1288. if (display) {
  1289. this.moveDisplayToWindow(display.id);
  1290. } else {
  1291. movedToWindow.splice(i,1);
  1292. i -= 1;
  1293. }
  1294. }
  1295. Storage.set("addonDisplay/movedToWindow", movedToWindow);
  1296. }
  1297. this.createDisplayWindow = function(display) {
  1298. var hwnd = new API.Window({
  1299. onclose: () => {
  1300. var html = display.$.parentElement.innerHTML;
  1301. display.$.remove();
  1302. hwnd.content(html);
  1303. this.removeDisplayWindow(display);
  1304. hwnd.fadeAndRemove();
  1305. }
  1306. });
  1307. hwnd.$[0].style.width = "241px;";
  1308. if (!display.noForcedWndHeight) hwnd.$[0].style.height = display.noTitle ? "290px" : "260px";
  1309. if (display.wndStyle) {
  1310. Object.assign(hwnd.$[0].style, display.wndStyle);
  1311. }
  1312. hwnd.title(display.noTitle ? "" : display.name);
  1313. hwnd.content(display.$);
  1314. console.log(hwnd);
  1315. hwnd.setTransparentWindow();
  1316. hwnd.changeDraggableContainment('.game-window-positioner'); // zmienili z dragable na draggable, ktoś umie angielski
  1317. hwnd.setSavePosWnd("display_"+display.id, {
  1318. x: '251',
  1319. y: '100'
  1320. });
  1321. $('.alerts-layer').append(hwnd.$);
  1322. hwnd.updatePos();
  1323. }
  1324. this.removeDisplayWindow = function(display) {
  1325. if (movedToWindow.length == list.length) {
  1326. hidden = false;
  1327. $wrapper.style["display"] = "block";
  1328. this.loadDisplay(display.id);
  1329. }
  1330. display.$short.style["display"] = "block";
  1331. movedToWindow.splice(movedToWindow.indexOf(display.id),1);
  1332. }
  1333. this.loadDefaultDisplay = function() {
  1334. var lastId = Storage.get("addonDisplay/active");
  1335. if (lastId == null) lastId = list[0].id;
  1336. self.loadDisplay(lastId);
  1337. self.createDisplayWindows();
  1338. }
  1339. this.getDisplayById = function(id) {
  1340. for (var i=0; i<list.length; i++) {
  1341. if (list[i].id == id) return list[i];
  1342. }
  1343. return false;
  1344. }
  1345. this.loadDisplay = function(id) {
  1346. var display = this.getDisplayById(id);
  1347. if (!display) display = list[0];
  1348. if (currentDisplay) {
  1349. $singleWrapper.removeChild(currentDisplay.$);
  1350. currentDisplay.$short.classList.remove("active");
  1351. }
  1352. display.$short.classList.add("active");
  1353. $singleWrapper.appendChild(display.$);
  1354. if (display.noTitle) {
  1355. $title.style["display"] = "none";
  1356. $singleWrapper.classList.add("long");
  1357. } else {
  1358. $title.style["display"] = "block";
  1359. $title.innerHTML = display.name;
  1360. $singleWrapper.classList.remove("long");
  1361. };
  1362. currentDisplay = display;
  1363. Storage.set("addonDisplay/active", id);
  1364. addons.emmiter.emit("display-load-"+id);
  1365. }
  1366. this.tutorial = function() {
  1367. if (Storage.get("addonDisplay/tutorial") || list.length == 0) return;
  1368. new addons.Window({
  1369. header: "Tutorial",
  1370. txt: _l() == "pl" ?
  1371. "Wygląda na to, że zainstalowałeś dodatek wykorzystujący mechanikę pokazywania rzeczy pod torbami. Kilka informacji:<br>-na dole są ikonki dodatków korzystających z tej machaniki. Klikając je można się między nimi przełączać.<br>-kliknięcie ikonki prawym przyciskiem myszy spowoduje przeniesienie dodatku spod toreb do oddzielnego okienka, które można dowolnie przesuwać.<br>-jeżeli masz mały monitor, to w ustawieniach jest opcja włączenia przycisku do ukrywania toreb, który znajduje się obok zestawów eq." :
  1372. "It appears that you've installed an addon that uses the mechanic of showing stuff under the bags. Some information:<br>-on the bottom, there are icons of addons using said mechanic. You can switch between addons by clicking these.<br>-by right clicking an icon you can move addon display to a separate window, which can be moved around freely.<br>-if your screen is too small, you can toggle a button that hides bags in game settings. Said button will be located next to battlesets upon enabling.",
  1373. css: {
  1374. "max-width": "350px"
  1375. }
  1376. })
  1377. Storage.set("addonDisplay/tutorial", true);
  1378. }
  1379. this.catchCLLTable = function() {
  1380. var timers = document.getElementsByClassName("cll-timers");
  1381. if (timers.length) {
  1382. addons.settings.add({
  1383. txt: _l() == "pl" ? "Umieszczaj minutniki klanowe pod torbami" : "Show guild timers under the bags",
  1384. id: "API_clan_timer_display",
  1385. default: false
  1386. });
  1387. addons.emmiter.on("toggle-addon-API_clan_timer_display", () => message(_l() == "pl" ? "Zmiany będą widoczne po odświeżeniu gry" : "Changes will come into effect once the page has been reloaded"));
  1388. if (!addons.settings.get("API_clan_timer_display")) return;
  1389. while(timers.length) {
  1390. var $timer = timers[0];
  1391. $($timer).trigger("mouseenter");
  1392. $($timer).draggable("disable");
  1393. Object.assign($timer.style, {
  1394. "position": "static",
  1395. "margin-top": "3px",
  1396. "margin-left": "1px"
  1397. });
  1398. var css = $timer.getAttribute("style");
  1399. $timer.setAttribute("style", css.replace("static;", "static !important;"));
  1400. var name = $timer.getAttribute("id").split("cll-timers-")[1].replace(/_/g, " ");
  1401. this.add({
  1402. name: _l() == "pl" ? "Minutniki klanowe "+name : "Clan timers "+name,
  1403. element: $timer,
  1404. id: "cll-timer-"+name,
  1405. icon: "http://grooove.pl/favicon.ico",
  1406. noTitle: true
  1407. })
  1408. }
  1409. }
  1410. }
  1411. this.onGameLoad = function() {
  1412. self.catchCLLTable();
  1413. if (list.length > 0) {
  1414. self.loadDefaultDisplay();
  1415. }
  1416. }
  1417. this.initSettings = function() {
  1418. addons.settings.add({
  1419. txt: _l() == "pl" ? "Przycisk ukrycia toreb" : "Bag hide button",
  1420. id: "API_hide_bag",
  1421. default: false
  1422. });
  1423. var buttonState = addons.settings.get("API_hide_bag");
  1424. this.toggleBagHideBtt(buttonState, true);
  1425. addons.emmiter.on("toggle-addon-API_hide_bag", this.toggleBagHideBtt);
  1426.  
  1427. var show = Storage.get("addonDisplay/showBag");
  1428. if (show == null || !buttonState) show = true;
  1429. this.toggleBag(show);
  1430. }
  1431. this.toggleBagHideBtt = function(show, init) {
  1432. $bagHide.style["display"] = show ? "block" : "none";
  1433. if (!init) self.toggleBag(true);
  1434. }
  1435. this.toggleBag = function(show) {
  1436. show = typeof(show) != "object" ? show : $bag.style["display"] == "none";
  1437. $bag.style["display"] = show ? "block" : "none";
  1438. $bagBG.style["display"] = show ? "block" : "none";
  1439.  
  1440. if (show) $wrapper.style["margin-top"] = 0;
  1441. else $wrapper.style["margin-top"] = "-205px";
  1442. Storage.set("addonDisplay/showBag", show);
  1443. }
  1444. this.init = function() {
  1445. if (Storage.get("addonDisplay") == null) {
  1446. Storage.set("addonDisplay", {});
  1447. }
  1448. var moved = Storage.get("addonDisplay/movedToWindow")
  1449. if (moved) movedToWindow = moved;
  1450. $wrapper = document.querySelector(".b_wrapper");
  1451. $wrapper.innerHTML = "";
  1452.  
  1453. $title = document.createElement("div");
  1454. $title.classList.add("addonDisplay-header");
  1455. $wrapper.appendChild($title);
  1456.  
  1457. $singleWrapper = document.createElement("div");
  1458. $singleWrapper.classList.add("addonDisplay-single-wrapper");
  1459. $wrapper.appendChild($singleWrapper);
  1460.  
  1461. $scrollWrapper = document.createElement("div");
  1462. $scrollWrapper.classList.add("addonDisplay-scroll-wrapper");
  1463. $scrollContent = document.createElement("div");
  1464. $scrollContent.classList.add("addonDisplay-scroll-content");
  1465. $scrollWrapper.appendChild($scrollContent);
  1466. $wrapper.appendChild($scrollWrapper);
  1467.  
  1468. $bagHide = document.createElement("div");
  1469. $bagHide.classList.add("addonDisplay-hide-bag");
  1470. $bagHide.addEventListener("click", this.toggleBag);
  1471. $bagHide.dataset["tip"] = "ukryj/pokaż torbę";
  1472. document.querySelector(".inventory_wrapper").appendChild($bagHide);
  1473.  
  1474. $bag = document.getElementsByClassName("inventory-grid")[0];
  1475. $bagBG = document.getElementsByClassName("inventory-grid-bg")[0];
  1476.  
  1477. var style = `
  1478. .b_wrapper {
  1479. width: 241px;
  1480. display: none;
  1481. background: rgba(0,0,0,0.3);
  1482. color: white;
  1483. margin-left: 10px;
  1484. }
  1485. .addonDisplay-single-wrapper {
  1486. overflow: hidden;
  1487. width: 100%;
  1488. height: 260px;
  1489. padding: 5px;
  1490. }
  1491. .addonDisplay-single-wrapper.long {
  1492. height: 290px;
  1493. }
  1494. .addonDisplay-single-display {
  1495. color: white;
  1496. width: 100%;
  1497. overflow-y: scroll;
  1498. overflow-x: hidden;
  1499. height: 260px;
  1500. padding-right: 17px;
  1501. margin-top: 4px;
  1502. }
  1503. .addonDisplay-single-display.long {
  1504. height: 290px;
  1505. }
  1506. .addonDisplay-single-display.noForcedWndHeight {
  1507. height: initial;
  1508. }
  1509. .addonDisplay-single-wrapper > .addonDisplay-single-display.long {
  1510. height: 302px;
  1511. margin-top: -7px;
  1512. }
  1513. .addonDisplay-header {
  1514. border-bottom: 1px gray dashed;
  1515. font-size: 125%;
  1516. padding: 5px;
  1517. height: 20px;
  1518. line-height: 20px;
  1519. }
  1520. .addonDisplay-scroll-wrapper {
  1521. width: 100%;
  1522. height: 27px;
  1523. margin-top: 5px;
  1524. border-top: 1px gray dashed;
  1525. }
  1526. .addonDisplay-scroll-content > div {
  1527. float: left;
  1528. width: 24.5px;
  1529. height: 25px;
  1530. line-height: 25px;
  1531. font-size: 110%;
  1532. text-align: center;
  1533. border: 1px solid black;
  1534. border-collapse: collapse;
  1535. background: rgba(0,0,0,0.08);
  1536. cursor: url(http://aldous.margonem.pl/img/gui/cursor/5.png), auto;;
  1537. transition: background .1s ease-in-out;
  1538. }
  1539. .addonDisplay-scroll-content > div:hover {
  1540. background: rgba(55,55,55,0.47);
  1541. }
  1542. .addonDisplay-scroll-content > div.active {
  1543. background: rgba(70,70,70,0.47);
  1544. }
  1545. .addonDisplay-hide-bag {
  1546. background: url(https://i.imgur.com/PpUPE6G.png);
  1547. width: 32px;
  1548. height: 32px;
  1549. position: absolute;
  1550. top: -35px;
  1551. left: 73px;
  1552. display: none;
  1553. cursor: ${addons.cursors.pointer};
  1554. }
  1555. `;
  1556. var $style = document.createElement("style");
  1557. $style.innerHTML = style;
  1558. document.head.appendChild($style);
  1559.  
  1560. addons.emmiter.once("game-load", this.onGameLoad);
  1561. addons.emmiter.once("interface-load", this.tutorial);
  1562.  
  1563. for (let i=0; i<loadQueue.length; ++i) {
  1564. this.add(loadQueue[i]);
  1565. }
  1566. loadQueue.splice(0, loadQueue.length);
  1567.  
  1568. this.initSettings();
  1569. }
  1570. })(this);
  1571.  
  1572. // szczerze mówiąc... nie wiem, dlaczego muszę to inicjowac
  1573. // ale z powodów mi nieznanych, gra nie inicjuje tego poprawnie z tym skryptem zainstalowanym
  1574. // naprawdę, nie mam czasu ani chęci w to wnikać, danie tego inita tutaj jakoś działa
  1575. Engine.interface.initDefaultWidgetSet();
  1576.  
  1577. //new addon notification, init display
  1578. this.emmiter.once("interface-load", () => {
  1579. this.addonDisplay.init();
  1580. var len = Object.values(this.list).length;
  1581. if (Storage.get("lastAddonListLength") == null) return Storage.set("lastAddonListLength", len);
  1582. if (Storage.get("lastAddonListLength") < len) {
  1583. message(_l() == "pl" ? "W panelu dostępny jest nowy dodatek!" : "A new addon is available in the panel!");
  1584. Storage.set("lastAddonListLength", len);
  1585. }
  1586. });
  1587. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement