DHM - Audio Alerts

Audio Alerts for DHM

目前為 2023-12-21 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name DHM - Audio Alerts
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0.1
  5. // @description Audio Alerts for DHM
  6. // @author Felipe Dounford
  7. // @require https://gf.qytechs.cn/scripts/461221-hack-timer-js-by-turuslan/code/Hack%20Timerjs%20By%20Turuslan.js?version=1159560
  8. // @match https://dhm.idle-pixel.com/
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=gf.qytechs.cn
  10. // @grant none
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. //Change ding url to set default sound
  18. let ding = 'https://raw.githubusercontent.com/Dounford-Felipe/Audio-Alerts/main/ding.wav'
  19. //Change defaultText to set default TTS Text
  20. let defaultText = 'Ready'
  21. let alerts = [];
  22. window.muteAllAlerts = false;
  23. window.alertVolume = 1;
  24. window.alertVoices = [];
  25. window.alertVoice = '';
  26.  
  27. //Gets the tts voices, populate the select with them and set the current voice
  28. function getVoices() {
  29. alertVoices = speechSynthesis.getVoices();
  30. const voiceSelect = document.getElementById('ttsVoices');
  31. alertVoices.forEach((voice, index) => {
  32. const option = document.createElement('option');
  33. option.value = index;
  34. option.textContent = voice.name;
  35. voiceSelect.appendChild(option);
  36. });
  37. // Set the current voice based on the value stored in localStorage or use the first voice
  38. alertVoice = localStorage.getItem('audioAlertsVoice') ? alertVoices[localStorage.getItem('audioAlertsVoice')] : alertVoices[0]
  39. document.getElementById('ttsVoices').value = localStorage.getItem('audioAlertsVoice') ? localStorage.getItem('audioAlertsVoice') : 0
  40. }
  41.  
  42. //Adds the table and Style
  43. function addUI() {
  44. let miscTab = document.querySelectorAll("#tab-misc > .main-button")[2];
  45. let scriptConfBar = `<div onclick="document.getElementById('dialogue-audioAlerts').style.display = ''" class="main-button" style="cursor: pointer;">
  46. <table>
  47. <tbody><tr>
  48. <td><img src="images/soundOn.png" class="img-small"></td>
  49. <td style="text-align:right;padding-right:20px;font-size:12pt;">AUDIO ALERTS</td>
  50. </tr>
  51. </tbody></table>
  52. </div>`;
  53. $(scriptConfBar).insertAfter(miscTab)
  54. let alertTable = `<div id="dialogue-audioAlerts" class="smittys-dialogues" style="padding-bottom: 50px; top: 0px;display:none">
  55. <table border="1" cellpadding="1" cellspacing="1">
  56. <thead>
  57. <tr>
  58. <th scope="col">Variable</th>
  59. <th colspan="2" rowspan="1" scope="col">Trigger</th>
  60. <th scope="col">Current Value</th>
  61. <th scope="col" style="width: 96px;">Sound Type</th>
  62. <th scope="col" style="width: 111px;">Option</th>
  63. <th scope="col" style="width: 64px;">Enabled</th>
  64. <th scope="col"></th>
  65. </tr>
  66. </thead>
  67. <tbody id="alertsBody">
  68. </tbody>
  69. <tfoot>
  70. <tr id="alertsFooter">
  71. <td>
  72. <select id="ttsVoices" onchange="alertVoice = alertVoices[this.value]" style="width:100%"></select>
  73. </td>
  74. <td colspan="3">
  75. <input type="checkbox" onclick="muteAllAlerts = !muteAllAlerts">Mute ALL
  76. </td>
  77. <td colspan="2">
  78. <input type="range" min="1" max="100" value="100" id="alertVolume" onchange="alertVolume = this.value"> Volume
  79. </td>
  80. <td>
  81. <button onclick="saveAlerts()">Save</button>
  82. </td>
  83. <td>
  84. <button onclick="addAlert()">ADD</button>
  85. </td>
  86. </tr>
  87. </tfoot>
  88. </table>
  89. <br>
  90. <br>
  91. <input type="button" onclick="this.parentNode.style.display='none'" style="cursor: pointer;" value="Close">
  92. </div>`
  93. $(alertTable).insertBefore('#tab-misc');
  94. }
  95.  
  96. //Adds new alert row and a new key to alerts array
  97. window.addAlert = function() {
  98. let alertRows = document.getElementById('alertsBody').getElementsByTagName("tr")
  99. let totalAlerts = alertRows.length
  100. let alertRow = document.createElement('tr')
  101. alertRow.id = `alert${totalAlerts+1}`
  102. alertRow.innerHTML = `<td>
  103. <input placeholder="Variable Name" id="variableName${totalAlerts+1}" style="width:100%">
  104. </td>
  105. <td>
  106. <select id="variableType${totalAlerts+1}">
  107. <option value="lt">&lt;</option>
  108. <option value="le">&le;</option>
  109. <option value="gt">&gt;</option>
  110. <option value="ge">&ge;</option>
  111. <option value="eq">&equals;</option>
  112. <option value="ne">&ne;</option>
  113. </select>
  114. </td>
  115. <td>
  116. <input placeholder="Value to Trigger" id="wantedValue${totalAlerts+1}">
  117. </td>
  118. <td><span id="variableValue"></span></td>
  119. <td>
  120. <select id="audioType${totalAlerts+1}">
  121. <option value="audio" selected="">Audio File</option>
  122. <option value="tts">Text To Speech</option>
  123. <option value="eval">Eval (Advanced Users Only!)</option>
  124. </select>
  125. </td>
  126. <td>
  127. <input placeholder="Text to Speech or sound URL" id="soundOption${totalAlerts+1}">
  128. </td>
  129. <td>
  130. <input type="checkbox" id="enabled${totalAlerts+1}">
  131. </td>
  132. <td>
  133. <button onclick="removeAlert(this.parentNode.parentNode)">Delete</button>
  134. </td>`
  135. document.getElementById('alertsBody').append(alertRow)
  136. alerts[totalAlerts] = {type:'lt',variableName:'',wantedValue:'',soundType:'audio',sound:ding,enabled:false,triggered:false}
  137. }
  138.  
  139. //Remove alert row and the array key, also changes the id of the remaining rows
  140. window.removeAlert = function(row) {
  141. let id = row.id.slice(5)
  142. alerts.splice(id-1,1)
  143. row.remove()
  144. let alertRows = document.getElementById('alertsBody').getElementsByTagName("tr")
  145. // Update remaining row IDs
  146. for (let i = 0; i < alertRows.length; i++) {alertRows[i].id = `alert${i+1}`}
  147. // Add a new alert if there are no rows remaining
  148. if (alertRows.length == 0) {addAlert()}
  149. }
  150.  
  151. //Save the alerts, also sets the alerts, volume and current voice on localStorage
  152. window.saveAlerts = function() {
  153. let alertRows = document.getElementById('alertsBody').getElementsByTagName("tr")
  154. for (let i = 0; i < alertRows.length; i++) {
  155. alerts[i].type = alertRows[i].getElementsByTagName('select')[0].value
  156. alerts[i].variableName = alertRows[i].getElementsByTagName('input')[0].value
  157. alerts[i].wantedValue = alertRows[i].getElementsByTagName('input')[1].value
  158. alerts[i].soundType = alertRows[i].getElementsByTagName('select')[1].value
  159. alerts[i].sound = alertRows[i].getElementsByTagName('input')[2].value == '' ? ding : alertRows[i].getElementsByTagName('input')[2].value
  160. alerts[i].enabled = alertRows[i].getElementsByTagName("input")[3].checked
  161. }
  162. let key = `audioAlerts`;
  163. localStorage.setItem(key, JSON.stringify(alerts));
  164. localStorage.setItem('audioAlertsVolume', alertVolume);
  165. let voiceIndex = document.getElementById('ttsVoices').value
  166. localStorage.setItem('audioAlertsVoice', voiceIndex);
  167. }
  168.  
  169. //Loads both volume and alerts from the localStorage
  170. function loadAlerts() {
  171. let key = `audioAlerts`;
  172. let audioAlerts = localStorage.getItem(key);
  173. if (audioAlerts) {
  174. audioAlerts = JSON.parse(audioAlerts);
  175. let alertRows = document.getElementById('alertsBody').getElementsByTagName("tr")
  176. for (let i = 0; i < audioAlerts.length; i++) {
  177. addAlert()
  178. alertRows[i].getElementsByTagName('select')[0].value = audioAlerts[i].type
  179. alertRows[i].getElementsByTagName('input')[0].value = audioAlerts[i].variableName
  180. alertRows[i].getElementsByTagName('input')[1].value = audioAlerts[i].wantedValue
  181. alertRows[i].getElementsByTagName('select')[1].value = audioAlerts[i].soundType
  182. alertRows[i].getElementsByTagName('input')[3].checked = audioAlerts[i].enabled
  183. alertRows[i].getElementsByTagName('input')[2].value = audioAlerts[i].sound == ding ? '' : audioAlerts[i].sound;
  184. }
  185. alerts = audioAlerts;
  186. } else {addAlert()}
  187. alertVolume = localStorage.getItem('audioAlertsVolume') ? localStorage.getItem('audioAlertsVolume') : 100;
  188. document.getElementById('alertVolume').value = alertVolume
  189. }
  190.  
  191. //Displays the current value of the alert variables
  192. function newValue() {
  193. let alertRows = document.getElementById('alertsBody').getElementsByTagName("tr")
  194. for (let i = 0; i < alertRows.length; i++) {
  195. alertRows[i].getElementsByTagName('span')[0].innerText = window[alerts[i].variableName] == undefined ? '' : window[alerts[i].variableName]
  196. }
  197. }
  198.  
  199. //This is were the alert happen
  200. function alertLoop() {
  201. for (let i = 0; i < alerts.length; i++) {
  202. if (alerts[i].enabled) {
  203. let type = alerts[i].type
  204. let triggered = 0
  205. switch(type) {
  206. case "lt": {
  207. triggered = window[alerts[i].variableName] < alerts[i].wantedValue ? 1 : 0
  208. break;
  209. }
  210. case "le": {
  211. triggered = window[alerts[i].variableName] <= alerts[i].wantedValue ? 1 : 0
  212. break;
  213. }
  214. case "gt": {
  215. triggered = window[alerts[i].variableName] > alerts[i].wantedValue ? 1 : 0
  216. break;
  217. }
  218. case "ge": {
  219. triggered = window[alerts[i].variableName] >= alerts[i].wantedValue ? 1 : 0
  220. break;
  221. }
  222. case "eq": {
  223. triggered = window[alerts[i].variableName] == alerts[i].wantedValue ? 1 : 0
  224. break;
  225. }
  226. case "ne": {
  227. triggered = window[alerts[i].variableName] != alerts[i].wantedValue && typeof window[alerts[i].variableName] != 'undefined' ? 1 : 0
  228. break;
  229. }
  230. }
  231. if (triggered == 1 && alerts[i].triggered == false) {
  232. alerts[i].triggered = true
  233. if (muteAllAlerts != true) {
  234. if(alerts[i].soundType == "audio") {
  235. let sound = new Audio(alerts[i].sound)
  236. sound = isNaN(sound.duration) ? new Audio(ding) : sound
  237. sound.volume = alertVolume / 100
  238. sound.play()
  239. } else if (alerts[i].soundType == "tts") {
  240. const message = new SpeechSynthesisUtterance();
  241. message.text = alerts[i].sound == ding ? defaultText : alerts[i].sound
  242. message.voice = alertVoice
  243. message.volume = alertVolume / 100
  244. window.speechSynthesis.speak(message);
  245. } else if (alerts[i].soundType == "eval") {// Remove from here
  246. let command = alerts[i].sound == 'https://raw.githubusercontent.com/Dounford-Felipe/Audio-Alerts/main/ding.wav' ? `console.log('You need to set ' + alerts[i].variableName + ' command')` : alerts[i].sound
  247. eval(command) // To here if you don't want eval
  248. }
  249. }
  250. }
  251. if (triggered == 0) {
  252. alerts[i].triggered = false
  253. }
  254. }
  255. }
  256. }
  257.  
  258. function initLoginNotifications() {
  259. var loginObserver = new MutationObserver(function(mutations) {
  260. mutations.forEach(function(mutationRecord) {
  261. if (document.getElementById("game-screen").style.display !== "none") {
  262. addUI()
  263. loadAlerts()
  264. speechSynthesis.onvoiceschanged = function () {
  265. getVoices()
  266. }
  267. //Loop every second the alert function and the function that displays the current value of functions
  268. const alertLoopInterval = setInterval(function(){
  269. newValue()
  270. alertLoop()
  271. }, 1000);
  272. }
  273. });
  274. });
  275. var loginTarget = document.getElementById('game-screen');
  276. loginObserver.observe(loginTarget, { attributes : true, attributeFilter : ['style'] });
  277. }
  278.  
  279. initLoginNotifications();
  280. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址