Greasy Fork is available in English.

TheWest-Notifier

Plays a notification sound, when specified events are triggered in the browser game The West!

  1. // ==UserScript==
  2. // @name TheWest-Notifier
  3. // @namespace TWNotifier_M77
  4. // @author Meuchelfix77 (updated by Tom Robert)
  5. // @description Plays a notification sound, when specified events are triggered in the browser game The West!
  6. // @include https://*.the-west.*/game.php*
  7. // @exclude https://classic.the-west.net*
  8. // @version 1.023
  9. // @icon http://twm.pf-control.de/TWNotifier/favicon.ico
  10. // @grant none
  11. // ==/UserScript==
  12. (function (fn) {
  13. var script = document.createElement('script');
  14. script.setAttribute('type', 'text/javascript');
  15. script.textContent = '(' + fn.toString() + ')();';
  16. (document.head || document.body || document.documentElement).appendChild(script);
  17. script.parentNode.removeChild(script);
  18. })(function () {
  19. TWN = {
  20. version: '1.023',
  21. name: 'TheWest-Notifier',
  22. author: 'Meuchelfix77 (updated by Tom Robert)',
  23. website: 'https://greasyfork.org/scripts/16917',
  24. LANGUAGE: (localStorage.getItem('scriptsLang') || Game.locale.substr(0, 2)),
  25. init: function () {
  26. switch (TWN.LANGUAGE) {
  27. default:
  28. TWN.lang = {
  29. translator: 'Meuchelfix77',
  30. notifications: 'Notifications',
  31. confirmationTitle: 'Confirmation',
  32. confirmation: 'Are you sure to remove this notification?',
  33. types: {
  34. messages: 'Messages',
  35. reports: 'Reports',
  36. townforum: 'Townforum',
  37. friends: 'Friends',
  38. wayFinished: 'Way finished',
  39. noQueue: 'Empty job queue',
  40. newItem: 'New item',
  41. nickInChat: 'Nickname in chat',
  42. },
  43. sounds: {
  44. bum: 'Bum',
  45. chime: 'Chime',
  46. coin: 'Coin',
  47. coin2: 'Coin 2',
  48. icq: 'ICQ',
  49. qip: 'QIP',
  50. tinkle: 'Tinkle',
  51. trumpet: 'Trumpet',
  52. vk: 'VK',
  53. custom: 'Custom',
  54. },
  55. event: 'Event',
  56. info: 'Information',
  57. remove: 'Remove this notification',
  58. listen: 'Listen to this sound',
  59. sound: 'Sound',
  60. soundFile: 'Sound file',
  61. soundInfo: 'Warning! Not all files can be played in your browser.',
  62. desc: {
  63. messages: 'Telegram received:',
  64. reports: 'Report received of type:',
  65. townforum: 'New forum post in:',
  66. friends: 'Friend(s) online:',
  67. wayFinished: 'Way finished:',
  68. noQueue: 'Empty job queue:',
  69. newItem: 'New item in inventory:',
  70. nickInChat: 'Nickname typed in chat:',
  71. },
  72. reportTypes: {
  73. all: 'All',
  74. work: 'Work',
  75. duels: 'Duels',
  76. achvmnt: 'Achievements',
  77. fort: 'Fort battles',
  78. other: 'Other',
  79. },
  80. add: 'Add notification',
  81. wayFinishedInfo: 'Triggers when you have finished your way and reached your destination.',
  82. reportInfo: '<b>Warning!</b> This will cause problems with the blinking messages button on the bottom screen.<br>Selecting <i>All</i> will solve these problems.',
  83. noQueueInfo: 'Triggers when there are no more job assignments in you job queue.',
  84. messagesInfo: 'Triggers when you receive a telegram.',
  85. friendListInfo: 'Seperate multiple friends with a semicolon (;)',
  86. townforumInfo: 'Triggers when somebody writes a post in the forum<span id="selectedForum"></span>.',
  87. newItemInfo: 'Triggers when you find, buy or get a new item.',
  88. nickInChatInfo: 'Triggers when your name was typed in the chat. Seperate more nicks with a semicolon (;)',
  89. install: 'Install',
  90. cancel: 'Cancel',
  91. update: 'Update',
  92. updateAvailable: 'A new version of the script is available',
  93. };
  94. break;
  95. case ('de'):
  96. TWN.lang = {
  97. translator: 'Meuchelfix77',
  98. notifications: 'Benachrichtigungen',
  99. confirmationTitle: 'Bestätigung',
  100. confirmation: 'Willst du diese Benachrichtigung wirklich löschen?',
  101. types: {
  102. messages: 'Telegramme',
  103. reports: 'Berichte',
  104. townforum: 'Stadtforum',
  105. friends: 'Freunde',
  106. wayFinished: 'Weg beendet',
  107. noQueue: 'Keine Arbeitsaufträge',
  108. newItem: 'Neues Item',
  109. nickInChat: 'Spielername im Chat',
  110. },
  111. sounds: {
  112. bum: 'Bum',
  113. chime: 'Glockenspiel',
  114. coin: 'Münze',
  115. coin2: 'Münze 2',
  116. icq: 'ICQ',
  117. qip: 'QIP',
  118. tinkle: 'Glitzer',
  119. trumpet: 'Trompete',
  120. vk: 'VK',
  121. custom: 'Eigene',
  122. },
  123. event: 'Ereignis',
  124. remove: 'Diese Benachrichtigung löschen',
  125. listen: 'Anhören',
  126. sound: 'Ton',
  127. soundFile: 'Audio-Datei',
  128. soundInfo: 'Achtung! Nicht alle Dateien werden von deinem Browser unterstützt.',
  129. desc: {
  130. messages: 'Telegramm erhalten:',
  131. reports: 'Bericht erhalten vom Typ:',
  132. townforum: 'Neuer Foren-Beitrag in:',
  133. friends: 'Freund(e) online:',
  134. wayFinished: 'Weg beendet:',
  135. noQueue: 'Keine weiteren Aufträge:',
  136. newItem: 'Neues Item im Inventar:',
  137. nickInChat: 'Name im Chat erwähnt:',
  138. },
  139. reportTypes: {
  140. all: 'Alle',
  141. work: 'Arbeiten',
  142. duels: 'Duelle',
  143. achvmnt: 'Erfolge',
  144. fort: 'Fortkämpfe',
  145. other: 'Sonstige',
  146. },
  147. add: 'Benachrichtigung hinzufügen',
  148. wayFinishedInfo: 'Wird ausgelöst, wenn du dein Ziel erreicht hast.',
  149. reportInfo: '<b>Achtung!</b> Diese Einstellung verursacht ein Problem mit der blinkenden Nachrichten-Schaltfläche am unteren Bildrand.<br>Die Option <i>Alle</i> behebt dieses Problem.',
  150. noQueueInfo: 'Wird ausgelöst, wenn du keine Arbeiten mehr in der Warteschlange hast.',
  151. messagesInfo: 'Wird ausgelöst, wenn du ein Telegramm erhälst.',
  152. friendListInfo: 'Trenne mehrere Freunde mit einem Semikolon (;)',
  153. townforumInfo: 'Wird ausgelöst, wenn jemand einen Beitrag im Stadtforum<span id="selectedForum"></span> verfasst.',
  154. newItemInfo: 'Wird ausgelöst wenn du ein neues Item findest oder kaufst.',
  155. nickInChatInfo: 'Wird ausgelöst wenn dein Name im Chat steht. Trenne weitere Nicks mit einem Semikolon (;)',
  156. install: 'Installieren',
  157. cancel: 'Abbrechen',
  158. };
  159. break;
  160. case ('pl'):
  161. TWN.lang = {
  162. translator: 'Darius II',
  163. notifications: 'Powiadomienia',
  164. confirmationTitle: 'Potwierdzenie',
  165. confirmation: 'Chcesz usunąć to powiadomienie?',
  166. types: {
  167. messages: 'Wiadomości',
  168. reports: 'Raporty',
  169. townforum: 'Forum',
  170. friends: 'Znajomi',
  171. wayFinished: 'Dotarcie do celu',
  172. noQueue: 'Brak zadań',
  173. newItem: 'New item',
  174. nickInChat: 'Nickname in chat',
  175. },
  176. sounds: {
  177. bum: 'Bum',
  178. chime: 'Kurant',
  179. coin: 'Kucie',
  180. coin2: 'Kucie 2',
  181. icq: 'ICQ',
  182. qip: 'QIP',
  183. tinkle: 'Dzwonek',
  184. trumpet: 'Trąbka',
  185. vk: 'VK',
  186. custom: 'Własny',
  187. },
  188. event: 'Zdarzenie',
  189. remove: 'Usuń zdarzenie',
  190. listen: 'Odsłuchaj',
  191. sound: 'Dźwięk',
  192. soundFile: 'Plik dźwięku',
  193. soundInfo: 'Uwaga! Nie wszystkie typy plików dźwiękowych mogą być odtwarzane w przeglądarce.',
  194. desc: {
  195. messages: 'Otrzymano wiadomość:',
  196. reports: 'Typ raportu:',
  197. townforum: 'Nowy wpis w:',
  198. friends: 'Pojawił się znajomy/a :',
  199. wayFinished: 'Ośiągnięto cel:',
  200. noQueue: 'Brak zadań:',
  201. newItem: 'New item in inventory:',
  202. nickInChat: 'Nickname typed in chat:',
  203. },
  204. reportTypes: {
  205. all: 'Wszystkie',
  206. work: 'Praca',
  207. duels: 'Pojedynki',
  208. achvmnt: 'Osiągnięcia',
  209. fort: 'Fortowe',
  210. other: 'Pozostałe',
  211. },
  212. add: 'Dodaj powiadomienie',
  213. wayFinishedInfo: 'Odtworzy dźwięk kiedy dotrzesz na wyznaczoną pozycję.',
  214. reportInfo: '<b>Uwaga!</b> Ten wybór powoduje problemy z migotaniem przycisku "wiadomości/raporty", wybrór <i>Wszystkie</i> rozwiąże ten problem.',
  215. noQueueInfo: 'Odtworzy dźwięk, kiedy zostaną wykonane wszystkie zadania.',
  216. messagesInfo: 'Odtworzy dźwięk, kiedy otrzymasz telegram.',
  217. friendListInfo: 'Oddziel znajomych średnikiem (;)',
  218. townforumInfo: 'Odtworzy dźwięk, kiedy ktoś napisze wiadomośc na forum w zakładce: <span id="selectedForum"></span>.',
  219. newItemInfo: 'Triggers when you find, buy or get a new item.',
  220. nickInChatInfo: 'Triggers when your name was typed in the chat. Seperate more nicks with a semicolon (;)',
  221. install: 'Zainstaluj',
  222. cancel: 'Anuluj',
  223. };
  224. break;
  225. case ('pt'):
  226. TWN.lang = {
  227. translator: 'jccwest',
  228. notifications: 'Notificações',
  229. confirmationTitle: 'confirmação',
  230. confirmation: 'Tem certeza que deseja remover esta notificação?',
  231. types: {
  232. messages: 'Mensagens',
  233. reports: 'Relatórios',
  234. townforum: 'Fórum da cidade',
  235. friends: 'Amigos',
  236. wayFinished: 'Chegou ao destino',
  237. noQueue: 'Sem trabalhos',
  238. newItem: 'Novo item no inventário',
  239. nickInChat: 'Nickname in chat',
  240. },
  241. sounds: {
  242. bum: 'Bum',
  243. chime: 'Chime',
  244. coin: 'Coin',
  245. coin2: 'Coin 2',
  246. icq: 'ICQ',
  247. qip: 'QIP',
  248. tinkle: 'Tinkle',
  249. trumpet: 'Trompete',
  250. vk: 'VK',
  251. custom: 'Custom',
  252. },
  253. event: 'Evento',
  254. info: 'Informação',
  255. remove: 'Remover esta notificação',
  256. listen: 'reproduzir o som',
  257. sound: 'Som',
  258. soundFile: 'arquivo de som',
  259. soundInfo: 'Aviso! Nem todos os arquivos podem ser reproduzidos no seu navegador.',
  260. desc: {
  261. messages: 'Telegrama recebido:',
  262. reports: 'Relatório recebeu do tipo:',
  263. townforum: 'Novo post no fórum:',
  264. friends: 'Amigo(s) on-line:',
  265. wayFinished: 'Chegou ao destino:',
  266. noQueue: 'Sem trabalhos:',
  267. newItem: 'Novo item no inventário:',
  268. nickInChat: 'Nickname typed in chat:',
  269. },
  270. reportTypes: {
  271. all: 'Todos',
  272. work: 'Trabalho',
  273. duels: 'Duelos',
  274. achvmnt: 'Conquistas',
  275. fort: 'Batalhas no forte',
  276. other: 'Outro',
  277. },
  278. add: 'Adicionar notificação',
  279. wayFinishedInfo: 'Avisa quando tiver terminado o meu caminho e a chegada ao destino.',
  280. reportInfo: '<b>Aviso!</b> Isto irá causar problemas com o botão piscando mensagens na tela inferior seleção <i>Todos</i> vai resolver estes problemas.',
  281. noQueueInfo: 'Avisa quando não há mais trabalhos atribuídos.',
  282. messagesInfo: 'Avisa quando recebe um telegrama.',
  283. friendListInfo: 'Separe vários amigos com um ponto e vírgula (;)',
  284. townforumInfo: 'Avisa quando alguém escreve um post no fórum <span id="selectedForum"></span>.',
  285. newItemInfo: 'Avisa quando encontra,ou compra um novo item.',
  286. nickInChatInfo: 'Triggers when your name was typed in the chat. Seperate more nicks with a semicolon (;)',
  287. install: 'Instalar',
  288. cancel: 'Cancelar',
  289. };
  290. break;
  291. case ('el'):
  292. TWN.lang = {
  293. translator: 'Timemod Herkumo',
  294. notifications: 'Ειδοποιήσεις',
  295. confirmationTitle: 'Επιβεβαίωση',
  296. confirmation: 'Είστε βέβαιοι ότι θέλετε να καταργήσετε αυτήν την ειδοποίηση;',
  297. types: {
  298. messages: 'Μυνήματα',
  299. reports: 'Αναφορές',
  300. townforum: 'Φόρουμ πόλης',
  301. friends: 'Φιλοι',
  302. wayFinished: 'Τέλος προορισμού',
  303. noQueue: 'Κενή ουρά εργασίας',
  304. newItem: 'Νέο αντικείμενο',
  305. nickInChat: 'Ψευδώνυμο στην συνομιλία',
  306. },
  307. sounds: {
  308. bum: 'Bum',
  309. chime: 'Κουδούνι',
  310. coin: 'Νόμισμα',
  311. coin2: 'Νόμισμα 2',
  312. icq: 'ICQ',
  313. qip: 'QIP',
  314. tinkle: 'Λάμψη',
  315. trumpet: 'Τρομπέτα',
  316. vk: 'VK',
  317. custom: 'Προσαρμοσμένο',
  318. },
  319. event: 'Εκδήλωση',
  320. info: 'Πληροφορίες',
  321. remove: 'Κατάργηση αυτής της ειδοποίησης',
  322. listen: 'Ακούστε αυτόν τον ήχο',
  323. sound: 'Ήχοι',
  324. soundFile: 'Αρχείο ήχου',
  325. soundInfo: '<b>Προειδοποίηση!</b><br>Δεν είναι δυνατή η αναπαραγωγή όλων των αρχείων στο πρόγραμμα περιήγησής σας.',
  326. desc: {
  327. messages: 'Λάβατε νέο τηλεγάφημα:',
  328. reports: 'Λάβατε νέα αναφορά:',
  329. townforum: 'Νέο θέμα στο Φόρουμ:',
  330. friends: 'Συνδεδεμένος φίλος:',
  331. wayFinished: 'Προορισμός:',
  332. noQueue: 'Κενή ουρά εργασίας:',
  333. newItem: 'Νέο αντικείμενο:',
  334. nickInChat: 'Ψευδόνυμο στο τσατ:',
  335. },
  336. reportTypes: {
  337. all: 'Όλα',
  338. work: 'Εργασίες',
  339. duels: 'Μονομαχίες',
  340. achvmnt: 'Επιτεύγματα',
  341. fort: 'Μάχες Οχυρού',
  342. other: 'Άλλο',
  343. },
  344. add: 'Προσθήκη ειδοποίησης',
  345. wayFinishedInfo: 'Ενεργοποιείται όταν φτάσετε στον προορισμό σας.',
  346. reportInfo: '<b>Προειδοποίηση!</b><br>Αυτό θα προκαλέσει προβλήματα με την αναλαμπή του κουμπιού μηνυμάτων στην κάτω μπάρα μενού.<br>Η επιλογή <i>"Όλα"</i> θα λύσει αυτά τα προβλήματα.',
  347. noQueueInfo: 'Ενεργοποιείται όταν δεν υπάρχουν εργασίες στην ουρά εργασίας.',
  348. messagesInfo: 'Ενεργοποιείται όταν λαμβάνετε ένα τηλεγράφημα.',
  349. friendListInfo: 'Ξεχωρίστε πολλούς φίλους με ένα ερωτηματικό (;)',
  350. townforumInfo: 'Ενεργοποιείται όταν κάποιος γράφει μια ανάρτηση στο φόρουμ .',
  351. newItemInfo: 'Ενεργοποιείται όταν βρίσκετε, αγοράζετε ή λαμβάνετε ένα νέο αντικείμενο.',
  352. nickInChatInfo: 'Ενεργοποιείται όταν αναφέρεται το όνομά σας στη συζήτηση. Seperate more nicks with a semicolon (;)',
  353. install: 'Εγκατάσταση',
  354. cancel: 'Ματαίωση',
  355. };
  356. break;
  357. } // Init all modules of TWNotifier
  358.  
  359. TWN.initStyleSheet();
  360. TWN.settings.init();
  361. TWN.notifications.init();
  362. },
  363. roomsListening: [
  364. ],
  365. // init the global stylesheet
  366. initStyleSheet: function () {
  367. var css = $('<style id="TWNotifierStyles"></style>');
  368. $(document.head || document.body || document.documentElement).append(css);
  369. },
  370. // add global CSS information
  371. addStyle: function (css) {
  372. var styles = $('#TWNotifierStyles');
  373. styles.html(styles.html() + '\n' + css);
  374. },
  375. // returns a value from our storage
  376. get: function (key, val) {
  377. return (localStorage.getItem('TWNotifier_' + key) || val);
  378. },
  379. // sets a value pair in our storage
  380. set: function (key, val) {
  381. localStorage.setItem('TWNotifier_' + key, val);
  382. },
  383. // removes a key-value pair from our storage
  384. remove: function (key) {
  385. localStorage.removeItem('TWNotifier_' + key);
  386. },
  387. showMessage: function (text, icon) {
  388. new UserMessage(text, icon).show();
  389. },
  390. // append the specified function
  391. appendFunction: function (oldFn, newFn, _thisOld, _thisNew) {
  392. var fn = parent,
  393. i = 1; // start for finding the function to replace
  394. // every loop we get one step deeper/closer to our function to replace/append to
  395. while (fn[oldFn[i - 1]][oldFn[i]]) {
  396. fn = fn[oldFn[i - 1]];
  397. i++;
  398. }
  399. var tmpFn = fn[oldFn[i - 1]]; // avoid recursion
  400. fn[oldFn[i - 1]] = function () {
  401. newFn.apply(_thisNew, arguments); // and afterwards our new
  402. return tmpFn.apply(this, arguments); // call the old function;
  403. };
  404. }
  405. };
  406. TWN.images = {
  407. right_menu: 'data:image/png;base64,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',
  408. right_menu_hover: 'data:image/png;base64,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',
  409. sound: 'data:image/png;base64,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',
  410. remove: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAcCAYAAAB75n/uAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAMPSURBVHja7FVNaFxVFP7uzJ15781rMy6CUkNJ0ygi1W40i4BCgmKF0k1FxEXFpeDCZUEFKZKCLnSZlRuz8GfhQgISxa1SkbQF0xICFYUSDZ1kOjPv595z7j0uJplMJplxmupKP3jv3Xu/8853zjvn3qfeeu2ZK7Ozs7i+fMViF6rnec/YupuVZ2ZmRDvna8WihveSHWCn7nHeATsfFbUWbclt6FIAdr51CEd9BSy5uKgDaENuU5dDMLsGAOk1lPaa7E4HovNpjaWRUhAqneW0EYSx5Ja3dq3UwTVQf1MT2Q0kM2yDMBbdSkwtqowgy6nWE4zavisAqjJ57stuNru1+Mo+/yKdDNPMqiCMoY3lrFQOYcil3ZYA4LcjGj11fum9dy6CmAEAJa1xaQ5f3Fn56ky/ZFqpLUVxVXSjZZpRXFXNxDS6Izgx9eoP3S9cmvtgn5PRU+eXdsa//vTZdDfXaOVBFFehk9zmYTyCRivvZPDkzOtXP5p7e+iev7ayhk+BH5e/++T0zlozNUeiI1XoZsvklfgBbNbTPfugnjBq9TqMIVhrkVuD3BCsJWRZjjTLkKQp0iQFMQEANjaTjo+7zTyvxFWlDbHT5QCZYdct8P6HH+ONCy9h+edrIC9g50CWYcjCWIYlhvcekxMTWF1b2969KXWaICcuB7HS7UFlD7kwf3n8wpvv/vboIydRa1mcfvwkmhlj8Zvv8fz00/j9j02srt7E8bExhFGEX26sYGH+8nh3gN6LFHVJtLHsykGEZmL2ZEC2refYgYnA7OC9h3MM53bGDiICsoQ7Wwn3nhZh5Si0Jed1KUCSWd/NOubhKqzUQNtCP4LYDucfAA+w7SvAw2YAgOgQGTDRkO4VmOlfzEDhcDXwvl1zL+0DSUTgvUf7MBGI+E4NdmwPgu5HFAtt7WennoDxgC8QXnzhOdQbTURRhInJx+AdIwgCKKUGNsFTIgKl1HovOXv25du31/9EoaCgtv8SSqnOJSJ4+KEH8e3Xn48d4PuYiAwWuE8cE5H+Nfin8L/Af0DgrwEAWMmrNSQDjVcAAAAASUVORK5CYII=',
  411. listen: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAATLSURBVHjabNTbb1MFAAbw75ye09Nz2q5dt17W7tbuonNuMBzb2Mhgg8GEcQk6zEIwBo2LBucLWaIhM2AkmvhiYiJoNAIPE0RRUCAaQHCwQdmVrcuQrbtQ1nbrveecrrfjAwmJke8P+D18+fIRhw/3wOl0guM4WK2FoGkasZgAgITX6yH6+vq6Ozo6vrdYzB6fz4f1ja3Q6TIQE/zs0VO+a6KsgP2iK2u1UkHBH0mBwjMilyuwvLyEeCI14PP5a7q7u38F4Cl/oRJvHXgXl/+4ApohxKWoqS7E5uOrC/6z77SRe8UVGcj/Y3J4PB46EAz1t7Zuq6mtrYNGo+HVKiWOn/gaNJVG7/VIZ/6LjYqe1/jn6PB93J3Xtf8+EGnjFNITUJKkp9ji4qI6EAzd6+jYV9e2/WVwnAICH5FtbG7BmtVFOPZt36E7gc3HT15V/11XXfZgY8FIj285gJH5jG+cjwSQgiDA51tGMBjE9PSMJZFIDnV2dlY2NzWCokgkk0kY9Nnxli1bMexwoWVt1qWKHJ9o/wfVJ2/q2zet4T5W8zfgiipMjvlUK5mbm3d+1+49A+vqG/qtVpujq+tgcW1NNQDA7fZi1jkdb25aHxF1Oz797GKWo6S4wNFWNr4rEVnEDQdOxekiFKrnTnu9IgIC207t3fvqbovFDEkCvF4vGEaOyckpLPv8CIcjCIWCKU1GqeSPKWseBjVl311PflhvUx7T2e3BgLBT65eKzAWGv0475pz7l4WyanJmxhmcevAQExMOjI6Ooe/WABYWXKAoCrkWMzgugx0cHIo+zw68kq92YWiWOvI4ooNe4b0YiaTgiXL16XRyisUSxCSRR+Xl50kmkwnxlRWwrAIGgwFKJQeSfDIAiyUHt2/3KxemRwMaIguhiJ4SUypwTHp6RQyDj2mzpDQhyLCCNMBR7sXHRDqVhCAIEEUBRqPhKQYAIAhUlBfx2ZbSDK+dgM7Ap7RsDHwsbY2nJSiZRCBGSlxCokASEKne3jNavcGIWCyGJa8XllwzamtqYLNZoVar4Vtyi+XlpaqpcMXPc34SLQ3po2ZNGI+DzE5ltgzZXPjWEmRl4YQKNJGcp0w55ps0Lc9RKBSSXC4vCYXCRG/vDygtLUVJSQn8gZAs4A8SL2VKIzZ9IP/t7dlHf/xpsXkhasusKk7EjfJHrsvuxCcpWTa0dGCQioZDG2acM2AYBiZTTvmqVZVXQ+GIcWR4ELNzc0hJhPy3S3+q69ZdPvTRvqZD4+NTpWf7dRdYrRUbKuVvMCkXHrjVr5uKNNAro+dIgiRB03IwjALJZHJi0jFepVJyszt27IZOlwU+GkWUF5kz585iXVUhrt1x7RqZVysbKhQjb26Rei/emPvAR6whCrMEb1UJc4l80jsBAKAoGViWWxwbHa5yuRYcTU2bUFBohUqlTA0P2XHn3gQOH9z2+XrL8HsHNjMNd+1DtivjpmNGcz6qbGJnnon77zlIkgSCIJCpzQy6Hs1Xj40NT8bjcUSjPBuLxfF+VxdSybS0f6vpS7fzltB9Ymk6pVqL+uLQ+Z2Nhl/4mPTs+0pLEjQajSgKfLWMJI709PREDAY9eF7A5NRD1NQ3gI8GOaP2vl1Hu9iu9rI9apZFPL6CfwcAFv8pW2JrAdUAAAAASUVORK5CYII=',
  412. add: 'data:image/png;base64,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',
  413. info: 'data:image/png;base64,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',
  414. };
  415. TWN.sounds = [
  416. 'bum', 'chime', 'coin', 'coin2', 'icq', 'qip', 'tinkle', 'trumpet', 'vk',
  417. ];
  418. TWN.notifications = {
  419. list: {
  420. length: 0
  421. },
  422. init: function () {
  423. // Load notifications
  424. this.list.length = TWN.get('notificationCount', 0);
  425. for (var i = 0; i < this.list.length; i++) {
  426. var data = TWN.get('notification_' + i, '');
  427. if (data == '') {
  428. this.remove(i);
  429. i = 0;
  430. continue;
  431. }
  432. data = JSON.parse(data);
  433. this.list[i] = data;
  434. }
  435. // append TW-functions with TWNotifier-functionality
  436. // friend online
  437. TWN.appendFunction([
  438. 'west', 'notification', 'ToastOnlineNotification', 'prototype', 'init'
  439. ], function (name) {
  440. var sound = '';
  441. for (var i = 0; i < this.list.length; i++) {
  442. if (this.list[i].event == 'friends') {
  443. if (this.list[i].info == '*')
  444. sound = this.list[i].sound;
  445. else if (this.list[i].info.split(';').includes(name)) {
  446. sound = this.list[i].sound;
  447. break;
  448. }
  449. }
  450. }
  451. TWN.notifications.playSound(sound);
  452. }, west.notification.ToastOnlineNotification.prototype._super.prototype, this);
  453. // new report
  454. TWN.appendFunction(['Character', 'setToRead'], function (type, status) {
  455. if (status == false)
  456. return;
  457. // TOWNFORUM
  458. if (type == 'townforum') {
  459. var notifications = {
  460. length: 0
  461. };
  462. var custom = 0; // 0 = no notification, 1 = only all; 2 = custom notification
  463. for (var notification in TWN.notifications.list) {
  464. if (TWN.notifications.list[notification].event == 'townforum') {
  465. notifications[notifications.length] = TWN.notifications.list[notification].info;
  466. notifications.length++;
  467. if (TWN.notifications.list[notification].info == '*' && custom == 0)
  468. custom = 1;
  469. else
  470. custom = 2;
  471. }
  472. } // No notifications for forum
  473.  
  474. if (custom == 0 || notifications.length == 0)
  475. return;
  476. // no custom notifications
  477. if (custom == 1) {
  478. TWN.notifications.playSound(TWN.notifications.list[TWN.notifications.getIndex('townforum', '*')].sound);
  479. return;
  480. } // custom notifications
  481.  
  482. $.ajax('forum.php', {
  483. complete: function (data) {
  484. var DOM = $.parseHTML(data.responseText);
  485. var forumList = $('#forum_list', DOM);
  486. forumList.children().each(function (i, el) {
  487. if ($(el).hasClass('background')) {
  488. var index = TWN.notifications.getIndex('townforum', $(el).find('span').text());
  489. if (index != -1) {
  490. TWN.notifications.playSound(TWN.notifications.list[index].sound);
  491. return false;
  492. }
  493. }
  494. });
  495. }
  496. });
  497. return;
  498. }
  499. // MESSAGES
  500. if (type == 'messages') {
  501. var index = TWN.notifications.getIndex('messages');
  502. if (index != -1)
  503. TWN.notifications.playSound(TWN.notifications.list[index].sound);
  504. return;
  505. }
  506. // REPORTS
  507. if (type == 'reports') {
  508. // If no report types are specified, just play the sound for 'all reports', if specified (no requests)
  509. var allSound = 'data:audio/ogg;base64,;';
  510. for (var noti in TWN.notifications.list) {
  511. if (TWN.notifications.list[noti].event == 'reports') {
  512. if (TWN.notifications.list[noti].info != 'all') {
  513. allSound = '';
  514. break;
  515. } else
  516. allSound = TWN.notifications.list[noti].sound;
  517. }
  518. }
  519. if (allSound != '') {
  520. TWN.notifications.playSound(allSound);
  521. return;
  522. }
  523. // Send requests to check if there are new reports for the specified report types
  524. Ajax.remoteCall('reports', 'get_reports', {
  525. page: 0,
  526. folder: 'all'
  527. }, function (json) {
  528. if (json.error != false || !json.reports[0])
  529. return;
  530. var report_id = json.reports[0].report_id; // latest report
  531. // create counter
  532. var sounds = {},
  533. counter = (TWN.notifications.getIndex('reports', 'all') == -1 ? -6 : 0);
  534. for (type in TWN.lang.reportTypes) {
  535. var index = TWN.notifications.getIndex('reports', type);
  536. if (index != -1) {
  537. sounds[type] = TWN.notifications.list[index].sound;
  538. counter++;
  539. } else
  540. sounds[type] = '';
  541. }
  542. var gen = function (type, report) {
  543. return function (json) {
  544. if (json.error != false || !json.reports[0] || sounds[type] == '')
  545. return;
  546. if (json.reports[0].report_id == report) {
  547. counter = 0;
  548. TWN.notifications.playSound(sounds[type]);
  549. } else {
  550. counter--;
  551. if (counter == 0)
  552. TWN.notifications.playSound(sounds.all);
  553. }
  554. };
  555. };
  556. for (type in sounds)
  557. Ajax.remoteCall('reports', 'get_reports', {
  558. page: 0,
  559. folder: type
  560. }, gen(type, report_id));
  561. });
  562. return;
  563. }
  564. }, Character, this);
  565. // way finished
  566. TWN.appendFunction(['OnGoingWayFinishedEntry'], function () {
  567. for (var i = 0; i < this.list.length; i++) {
  568. if (this.list[i].event == 'wayFinished') {
  569. this.playSound(this.list[i].sound);
  570. break;
  571. }
  572. }
  573. }, OnGoingEntry, TWN.notifications);
  574. OnGoingWayFinishedEntry.prototype = new OnGoingEntry;
  575. // empty job queue
  576. EventHandler.listen('taskqueue-updated', function () {
  577. if (TaskQueueUi.isEmpty) {
  578. var index = TWN.notifications.getIndex('noQueue');
  579. if (index != -1)
  580. TWN.notifications.playSound(TWN.notifications.list[index].sound);
  581. }
  582. });
  583. // new item in inventory
  584. TWN.appendFunction(['WestUi',
  585. 'showInventoryChanged'], function (type, item_id, count) {
  586. if (type == 'add') {
  587. var index = TWN.notifications.getIndex('newItem');
  588. if (index != -1)
  589. TWN.notifications.playSound(TWN.notifications.list[index].sound);
  590. }
  591. }, WestUi);
  592. // nickname in chat
  593. TWN.addListeners = function () {
  594. var roomChanged = function (room, type, data) {
  595. var index = TWN.notifications.getIndex('nickInChat');
  596. if (index != -1 && type == 'NewMessage') {
  597. var div = $(data[0]);
  598. var cText = div.find('.chat_text').html().toLowerCase();
  599. var nli = TWN.notifications.list[index];
  600. var nList = [Character.name];
  601. if (nli.info != '*')
  602. nList.push(...nli.info.split(';'));
  603. for (var n of nList)
  604. if (cText.includes(n.toLowerCase())) {
  605. TWN.notifications.playSound(nli.sound);
  606. break;
  607. }
  608. }
  609. };
  610. var rooms = Chat.Resource.Manager.getRooms();
  611. for (var r in rooms) {
  612. var room = Chat.Resource.Manager.getRoom(r);
  613. if (TWN.roomsListening.indexOf(room.id) == -1) {
  614. TWN.roomsListening.push(room.id);
  615. room.addListener(roomChanged);
  616. }
  617. }
  618. };
  619. if (EventHandler.hasOwnProperty('add')) {
  620. EventHandler.add('chat_room_added', function (room) {
  621. TWN.addListeners();
  622. });
  623. } else {
  624. EventHandler.listen('chat_room_added', function (room) {
  625. TWN.addListeners();
  626. });
  627. }
  628. },
  629. // Add notification
  630. add: function (event, info, sound) {
  631. TWN.set('notification_' + this.list.length, JSON.stringify({
  632. event: event,
  633. info: info,
  634. sound: sound
  635. }));
  636. this.list[this.list.length++] = {
  637. event: event,
  638. info: info,
  639. sound: sound
  640. };
  641. TWN.set('notificationCount', this.list.length);
  642. },
  643. // Remove specified notification
  644. remove: function (id) {
  645. for (var i = id; i < this.list.length; i++) {
  646. TWN.set('notification_' + i, TWN.get('notification_' + (i + 1), ''));
  647. this.list[i] = this.list[i + 1];
  648. }
  649. TWN.remove('notification_' + (--this.list.length));
  650. this.list[this.list.length] = {};
  651. TWN.set('notificationCount', this.list.length);
  652. },
  653. getIndex: function (event, info) {
  654. for (var i = 0; i < this.list.length; i++)
  655. if (this.list[i].event == event && (this.list[i].info == info || info == undefined))
  656. return i;
  657. return -1;
  658. },
  659. // Play the specified sound
  660. playSound: function (src) {
  661. if (src && $('#ui-loader').css('display') == 'none') {
  662. var audio = TWN.sounds.includes(src) ? 'https://tomrobert.safe-ws.de/' + src + '.mp3' : src;
  663. new Audio(audio).play();
  664. }
  665. }
  666. };
  667. TWN.settings = {
  668. gui: {
  669. window: {},
  670. comboboxes: {}
  671. },
  672. table: null,
  673. townforumTopics: {
  674. length: 0
  675. },
  676. init: function () {
  677. var rightBar = $('.ui_menucontainer');
  678. var optionEl = $('<div id="TWNotifierSettingsBtn" onclick="TWN.settings.open ();" title="' + TWN.name + '"></div>');
  679. if (rightBar && rightBar[1]) {
  680. rightBar = $(rightBar[1]);
  681. rightBar.css('max-height', (rightBar.children('div').length * 30 - 2) + 'px');
  682. rightBar.append(optionEl);
  683. }
  684. TWN.addStyle('#TWNotifierSettingsBtn { width:32px; height:41px; margin:-8px -16px 0 -7px; cursor:pointer; background:url(' + TWN.images.right_menu + '); }' +
  685. '#TWNotifierSettingsBtn:hover { background:url(' + TWN.images.right_menu_hover + '); }' +
  686. '.TWNotifier-event-col { min-width:175px; font-weight:bold; }' +
  687. '.TWNotifier-sound-col, .TWNotifier-remove-col { float:right; }' +
  688. '.TWNotifier-sound-col { margin-right:-2px; }' +
  689. '.TWNotifier-sound-col img, .TWNotifier-remove-col img { margin-top:-3px; cursor:pointer; }' +
  690. '.tbody .TWNotifier-event-col, .tbody .TWNotifier-info-col { margin-left:4px; }' +
  691. '.TWNotifierButton { background:rgba(29,28,28,0.5); border:1px solid #646464; border-radius:2px; box-shadow:0 0 1px 1px #000; display:inline-block; margin-left:8px; padding:1px 2px; }' +
  692. '.TWNotifierSettings #TWNotifierSettings { padding:4px 0 0 4px; border-top:1px solid rgba(0,0,0,0.77); margin:2px -2px; }' +
  693. '.TWNotifierSettings #reportWarning { margin:5px 5px 0 0; padding:5px 5px; display:none; border:1px solid #C33; }' +
  694. '.TWNotifierSettings .tfoot { padding:0 !important; height:6px; }' +
  695. '.TWNotifierSettings #settingInfo { margin:5px 5px 0 0; padding:5px 5px; text-align:center; border:1px solid #000; background:rgba(0,0,0,0.32); }' +
  696. '.TWNotifierSettings #settingInfo img { margin:0 16px; vertical-align:middle; }' +
  697. '.TWNotifierSettings #selectedForum { font-style:italic; }');
  698. },
  699. open: function () {
  700. this.gui.window = wman.open('TWNotifierSettings', TWN.name, 'noreload').setMiniTitle(TWN.name);
  701. TWN.settings.gui.window.showLoader();
  702. // Create table
  703. this.table = new west.gui.Table(false);
  704. this.table.addColumn('TWNotifier-event-col').addColumn('TWNotifier-info-col').addColumn('TWNotifier-remove-col').addColumn('TWNotifier-sound-col');
  705. this.table.appendToCell('head', 'TWNotifier-event-col', TWN.lang.event).appendToCell('head', 'TWNotifier-info-col', TWN.lang.info).appendToCell('head', 'TWNotifier-remove-col', '&nbsp;').appendToCell('head', 'TWNotifier-sound-col', '&nbsp;');
  706. this.table.setScrollbar();
  707. // Fill table
  708. TWN.settings.refreshTable();
  709. TWN.settings.gui.window.appendToContentPane(this.table.getMainDiv());
  710. // Create settings
  711. var settings = $('<div id="TWNotifierSettings"></div>');
  712. var dropdown = new west.gui.Combobox('TWNotifierNotificationType').setWidth(130).addListener(function () {
  713. TWN.settings.changeSettings(dropdown.getValue());
  714. });
  715. for (var type in TWN.lang.types)
  716. dropdown.addItem(type, TWN.lang.types[type]);
  717. // TODO: Correct width (depending on other elements)
  718. var soundName = new west.gui.Textfield('TWNotifierSoundName').setWidth(165).setPlaceholder('https:// .mp3');
  719. var soundBox = new west.gui.Combobox('TWNotifierSoundBox').setWidth(130);
  720. for (var sound of TWN.sounds)
  721. soundBox.addItem(sound, TWN.lang.sounds[sound]);
  722. soundBox.addItem('custom', TWN.lang.sounds.custom).addListener(function () {
  723. if (soundBox.getValue() == 'custom')
  724. soundName.getMainDiv().css('display', 'inline-block');
  725. else
  726. soundName.getMainDiv().css('display', 'none');
  727. });
  728. var testSound = $('<div class="TWNotifierButton" title="' + TWN.lang.listen + '"><img src="' + TWN.images.listen + '" style="cursor:pointer;"></div>').click(function () {
  729. if (soundBox.getValue() != 'custom')
  730. TWN.notifications.playSound(soundBox.getValue());
  731. else
  732. TWN.notifications.playSound(soundName.getValue());
  733. });
  734. var addButton = $('<div class="TWNotifierButton" title="' + TWN.lang.add + '"><img src="' + TWN.images.add + '" style="cursor:pointer;"></div>').click(function () {
  735. var event = dropdown.getValue();
  736. var info = TWN.settings.getInfo(event);
  737. var sound = soundBox.getValue();
  738. if (sound == 'custom')
  739. sound = soundName.getValue();
  740. TWN.notifications.add(event, info, sound);
  741. TWN.settings.refreshTable();
  742. });
  743. TWN.settings.gui.window.appendToContentPane($('<span>' + TWN.lang.event + ': </span>')).appendToContentPane(dropdown.getMainDiv()).appendToContentPane($('<span style="margin-left:8px;">' + TWN.lang.sound + ': </span>'));
  744. TWN.settings.gui.window.appendToContentPane(soundBox.getMainDiv()).appendToContentPane(soundName.getMainDiv().css({
  745. 'display': 'none',
  746. 'margin-top': '1px'
  747. })).appendToContentPane(testSound).appendToContentPane(addButton).appendToContentPane(settings);
  748. TWN.settings.changeSettings();
  749. TWN.settings.gui.window.hideLoader();
  750. },
  751. removeConfirmation: function (id) {
  752. var dialog = new west.gui.Dialog(TWN.lang.confirmationTitle, TWN.lang.confirmation);
  753. dialog.addButton('yes', function () {
  754. TWN.notifications.remove(id);
  755. $('.TWNotifierSettings .row_' + id).remove();
  756. TWN.settings.refreshTable();
  757. }).addButton('no', function () {
  758. dialog.hide();
  759. }).show();
  760. },
  761. refreshTable: function () {
  762. this.table.clearBody();
  763. for (var i = 0; i < TWN.notifications.list.length; i++) {
  764. var inl = TWN.notifications.list[i];
  765. var sound = inl.sound;
  766. this.table.appendRow(null, '');
  767. this.table.appendToCell(-1, 'TWNotifier-event-col', TWN.lang.desc[inl.event] || inl.event);
  768. this.table.appendToCell(-1, 'TWNotifier-info-col', TWN.settings.getDescription(inl));
  769. this.table.appendToCell(-1, 'TWNotifier-remove-col', $('<img src="' + TWN.images.remove + '" onclick="TWN.settings.removeConfirmation (' + i + ');" title="' + TWN.lang.remove + '">'));
  770. this.table.appendToCell(-1, 'TWNotifier-sound-col', $('<img src="' + TWN.images.sound + '" onclick="TWN.notifications.playSound(\'' + sound + '\');" title="' + TWN.lang.listen + '">'));
  771. }
  772. },
  773. changeSettings: function (val) {
  774. var settings = $('#TWNotifierSettings').html('');
  775. switch (val) {
  776. case ('friends'):
  777. settings.append($('<label for="friendsName" style="cursor:pointer;">' + TWN.lang.types.friends + ':</label>'), new west.gui.Textfield('friendsName').getMainDiv(), this.infoBox(val));
  778. break;
  779. case ('wayFinished'):
  780. settings.append(this.infoBox(val));
  781. break;
  782. case ('noQueue'):
  783. settings.append(this.infoBox(val));
  784. break;
  785. case ('townforum'):
  786. var dropdown = new west.gui.Combobox('TWNotifierTownforumTopic');
  787. $.ajax('forum.php', {
  788. complete: function (data) {
  789. var DOM = $.parseHTML(data.responseText);
  790. $('#forum_list', DOM).children('div').each(function (i, el) {
  791. if ($(el).find('span').text() == '')
  792. return;
  793. TWN.settings.townforumTopics[TWN.settings.townforumTopics.length] = $(el).find('span').text();
  794. TWN.settings.townforumTopics.length++;
  795. });
  796. dropdown.addListener(function () {
  797. $('#selectedForum').html((dropdown.getValue() != '*' ? ' ' + dropdown.getValue() : ''));
  798. });
  799. dropdown.addItem('*', TWN.lang.reportTypes.all);
  800. for (var i = 0; i < TWN.settings.townforumTopics.length; i++)
  801. dropdown.addItem(TWN.settings.townforumTopics[i], TWN.settings.townforumTopics[i]);
  802. TWN.settings.gui.comboboxes.townforumTopics = dropdown;
  803. settings.append($('<span>' + TWN.lang.types.townforum + ': </span>'), dropdown.getMainDiv(), TWN.settings.infoBox(val));
  804. }
  805. });
  806. break;
  807. case ('reports'):
  808. var dropdown = new west.gui.Combobox('TWNotifierReportType');
  809. var types = [
  810. 'all',
  811. 'work',
  812. 'duels',
  813. 'achvmnt',
  814. 'fort',
  815. 'other'
  816. ];
  817. for (var i = 0; i < types.length; i++)
  818. dropdown.addItem(types[i], TWN.lang.reportTypes[types[i]]);
  819. dropdown.addListener(function (selected) {
  820. if (selected != 'all')
  821. $('#reportWarning').css('display', 'block');
  822. else
  823. $('#reportWarning').css('display', 'none');
  824. });
  825. settings.append($('<span>' + TWN.lang.types.reports + ': </span>'), dropdown.getMainDiv(), $('<div id="reportWarning">' + TWN.lang.reportInfo + '</div>'));
  826. TWN.settings.gui.comboboxes.reportTypes = dropdown;
  827. break;
  828. case ('newItem'):
  829. settings.append(this.infoBox(val));
  830. break;
  831. case ('nickInChat'):
  832. settings.append($('<label for="TWNnicks" style="cursor:pointer;">' + TWN.lang.types.nickInChat + ':</label>'), new west.gui.Textfield('TWNnicks').getMainDiv(), this.infoBox(val));
  833. break;
  834. //case ('messages'):
  835. default:
  836. settings.append(this.infoBox('messages'));
  837. break;
  838. }
  839. },
  840. infoBox: function (text) {
  841. return $('<div id="settingInfo"><img src="' + TWN.images.info + '"> ' + TWN.lang[text + 'Info'] + ' <img src="' + TWN.images.info + '"></div>');
  842. },
  843. getInfo: function (i) {
  844. switch (i) {
  845. case ('reports'):
  846. return TWN.settings.gui.comboboxes.reportTypes.getValue() || 'all';
  847. case ('townforum'):
  848. return TWN.settings.gui.comboboxes.townforumTopics.getValue() || '*';
  849. case ('friends'):
  850. var fTF = $('#friendsName').val();
  851. return fTF ? fTF.replace(/;\s+/g, ';').replace(/;$/g, '') : '*';
  852. case ('nickInChat'):
  853. var nTF = $('#TWNnicks').val();
  854. return nTF ? nTF.replace(/;\s+/g, ';').replace(/;$/g, '') : '*';
  855. default:
  856. return '';
  857. }
  858. },
  859. getDescription: function (e) {
  860. var info = e.info;
  861. switch (e.event) {
  862. case ('reports'):
  863. return TWN.lang.reportTypes[info] || info;
  864. case ('townforum'):
  865. if (info == '*')
  866. return TWN.lang.reportTypes.all;
  867. return info;
  868. case ('friends'):
  869. if (info == '*')
  870. return TWN.lang.reportTypes.all;
  871. var res = '';
  872. info = info.split(';');
  873. for (var i = 0; i < info.length; i++) {
  874. if (i != 0 && info[i] != '')
  875. res += ', ';
  876. res += '<a href="javascript:PlayerProfileWindow.open (encodeURIComponent (\'' + info[i].replace(/'/g, '\\\'') + '\') );">' + info[i] + '</a>';
  877. }
  878. return res;
  879. case ('nickInChat'):
  880. var res = Character.name;
  881. if (info == '*')
  882. return res;
  883. info = info.split(';');
  884. for (var nick of info)
  885. res += ', ' + nick;
  886. return res;
  887. default:
  888. return TWN.lang[e.event + 'Info'];
  889. }
  890. },
  891. };
  892. TWN.init();
  893. });