Audio Alerts for DHP
当前为
// ==UserScript==
// @name Idle Pixel Audio Alerts
// @namespace http://tampermonkey.net/
// @version 1.0.1
// @description Audio Alerts for DHP
// @author Felipe Dounford
// @require https://greasyfork.org/scripts/461221-hack-timer-js-by-turuslan/code/Hack%20Timerjs%20By%20Turuslan.js?version=1159560
// @require https://greasyfork.org/scripts/441206-idlepixel/code/IdlePixel+.js
// @match *://idle-pixel.com/login/play*
// @icon https://www.google.com/s2/favicons?sz=64&domain=greasyfork.org
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
//Change ding url to set default sound
let ding = 'https://raw.githubusercontent.com/Dounford-Felipe/Audio-Alerts/main/ding.wav'
//Change defaultText to set default TTS Text
let defaultText = 'Ready'
let alerts = [];
window.muteAllAlerts = false;
window.alertVolume = 1;
window.alertVoices = [];
window.alertVoice = '';
class AlertsPlugin extends IdlePixelPlusPlugin {
constructor() {
super("alerts", {
about: {
name: GM_info.script.name + " (ver: " + GM_info.script.version + ")",
version: GM_info.script.version,
author: GM_info.script.author,
description: GM_info.script.description
}
});
}
onLogin() {
IdlePixelPlus.plugins.alerts.addUI()
IdlePixelPlus.plugins.alerts.loadAlerts()
speechSynthesis.onvoiceschanged = function () {
IdlePixelPlus.plugins.alerts.getVoices()
}
const alertLoopInterval = setInterval(function(){
IdlePixelPlus.plugins.alerts.newValue()
IdlePixelPlus.plugins.alerts.alertLoop()
}, 1000);
}
//Gets the tts voices, populate the select with them and set the current voice
getVoices() {
alertVoices = speechSynthesis.getVoices();
const voiceSelect = document.getElementById('ttsVoices');
alertVoices.forEach((voice, index) => {
const option = document.createElement('option');
option.value = index;
option.textContent = voice.name;
voiceSelect.appendChild(option);
});
// Set the current voice based on the value stored in localStorage or use the first voice
alertVoice = localStorage.getItem('audioAlertsVoice') ? alertVoices[localStorage.getItem('audioAlertsVoice')] : alertVoices[0]
document.getElementById('ttsVoices').value = localStorage.getItem('audioAlertsVoice') ? localStorage.getItem('audioAlertsVoice') : 0
}
//Adds the table and Style
addUI() {
let alertTable = `<table border="1" cellpadding="1" cellspacing="1" style="text-align: center;color: white;font-weight: bold;text-shadow: 1px 1px black;">
<thead>
<tr>
<th style="width: 30%;">Variable</th>
<th style="width: 10%;" colspan="2">Trigger</th>
<th style="width: 10%;">Current Value</th>
<th style="width: 10%;">Sound Type</th>
<th style="width: 20%;">Option</th>
<th style="width: 10%;">Enabled</th>
<th></th>
</tr>
</thead>
<tbody id="alertsBody">
</tbody>
<tfoot>
<tr id="alertsFooter">
<td colspan="3">
<select id="ttsVoices" onchange="alertVoice = alertVoices[this.value]" style="width:100%"></select>
</td>
<td colspan="2">
<input type="checkbox" onclick="muteAllAlerts = !muteAllAlerts" style="margin-right: 10px;"> Mute ALL
</td>
<td>
<input type="range" min="1" max="100" value="100" id="alertVolume" onchange="alertVolume = this.value"> Volume
</td>
<td>
<button onclick="IdlePixelPlus.plugins.alerts.saveAlerts()">Save</button>
</td>
<td>
<button onclick="IdlePixelPlus.plugins.alerts.addAlert()">ADD</button>
</td>
</tr>
</tfoot>
</table>`
IdlePixelPlus.addPanel("audioAlerts", "Audio Alerts", alertTable);
let alertButton = `<div onclick="IdlePixelPlus.setPanel('audioAlerts')" class="hover hover-menu-bar-item left-menu-item">
<table class="game-menu-bar-left-table-btn left-menu-item-other" style="width: 100%;">
<tbody>
<tr>
<td style="width: 30px;"><img id="menu-bar-idlepixelplus-icon" src="https://dhm.idle-pixel.com/images/soundOn.png" class="w20" title="alerts"></td>
<td>AUDIO ALERTS</td>
</tr>
</tbody>
</table>
</div>`
$('#menu-bar-buttons').append(alertButton)
}
//Adds new alert row and a new key to alerts array
addAlert = function() {
let alertRows = document.getElementById('alertsBody').getElementsByTagName("tr")
let totalAlerts = alertRows.length
let alertRow = document.createElement('tr')
alertRow.id = `alert${totalAlerts+1}`
alertRow.innerHTML = `<td>
<input placeholder="Variable Name" id="variableName${totalAlerts+1}" style="width:100%">
</td>
<td>
<select id="variableType${totalAlerts+1}">
<option value="lt"><</option>
<option value="le">≤</option>
<option value="gt">></option>
<option value="ge">≥</option>
<option value="eq">=</option>
<option value="ne">≠</option>
</select>
</td>
<td>
<input placeholder="Value to Trigger" type="number" id="wantedValue${totalAlerts+1}">
</td>
<td><span id="variableValue"></span></td>
<td>
<select id="audioType${totalAlerts+1}">
<option value="audio" selected="">Audio File</option>
<option value="tts">Text To Speech</option>
<option value="eval">Eval (Advanced Users Only!)</option>
</select>
</td>
<td>
<input placeholder="Text to Speech or sound URL" id="soundOption${totalAlerts+1}">
</td>
<td>
<input type="checkbox" id="enabled${totalAlerts+1}">
</td>
<td style="padding-right: 6px;">
<button onclick="IdlePixelPlus.plugins.alerts.removeAlert(this.parentNode.parentNode)">Delete</button>
</td>`
document.getElementById('alertsBody').append(alertRow)
alerts[totalAlerts] = {type:'lt',variableName:'',wantedValue:'',soundType:'audio',sound:ding,enabled:false,triggered:false}
}
//Remove alert row and the array key, also changes the id of the remaining rows
removeAlert = function(row) {
let id = row.id.slice(5)
alerts.splice(id-1,1)
row.remove()
let alertRows = document.getElementById('alertsBody').getElementsByTagName("tr")
// Update remaining row IDs
for (let i = 0; i < alertRows.length; i++) {alertRows[i].id = `alert${i+1}`}
// Add a new alert if there are no rows remaining
if (alertRows.length == 0) {IdlePixelPlus.plugins.alerts.addAlert()}
}
//Save the alerts, also sets the alerts, volume and current voice on localStorage
saveAlerts = function() {
let alertRows = document.getElementById('alertsBody').getElementsByTagName("tr")
for (let i = 0; i < alertRows.length; i++) {
alerts[i].type = alertRows[i].getElementsByTagName('select')[0].value
alerts[i].variableName = 'var_' + alertRows[i].getElementsByTagName('input')[0].value
alerts[i].wantedValue = alertRows[i].getElementsByTagName('input')[1].value
alerts[i].soundType = alertRows[i].getElementsByTagName('select')[1].value
alerts[i].sound = alertRows[i].getElementsByTagName('input')[2].value == '' ? ding : alertRows[i].getElementsByTagName('input')[2].value
alerts[i].enabled = alertRows[i].getElementsByTagName("input")[3].checked
alerts[i].triggered = false
}
let key = `audioAlerts`;
localStorage.setItem(key, JSON.stringify(alerts));
localStorage.setItem('audioAlertsVolume', alertVolume);
let voiceIndex = document.getElementById('ttsVoices').value
localStorage.setItem('audioAlertsVoice', voiceIndex);
}
//Loads both volume and alerts from the localStorage
loadAlerts() {
let key = `audioAlerts`;
let audioAlerts = localStorage.getItem(key);
if (audioAlerts) {
audioAlerts = JSON.parse(audioAlerts);
let alertRows = document.getElementById('alertsBody').getElementsByTagName("tr")
for (let i = 0; i < audioAlerts.length; i++) {
IdlePixelPlus.plugins.alerts.addAlert()
alertRows[i].getElementsByTagName('select')[0].value = audioAlerts[i].type
alertRows[i].getElementsByTagName('input')[0].value = audioAlerts[i].variableName.slice(4)
alertRows[i].getElementsByTagName('input')[1].value = audioAlerts[i].wantedValue
alertRows[i].getElementsByTagName('select')[1].value = audioAlerts[i].soundType
alertRows[i].getElementsByTagName('input')[3].checked = audioAlerts[i].enabled
alertRows[i].getElementsByTagName('input')[2].value = audioAlerts[i].sound == ding ? '' : audioAlerts[i].sound;
}
alerts = audioAlerts;
} else {IdlePixelPlus.plugins.alerts.addAlert()}
alertVolume = localStorage.getItem('audioAlertsVolume') ? localStorage.getItem('audioAlertsVolume') : 100;
document.getElementById('alertVolume').value = alertVolume
}
//Displays the current value of the alert variables
newValue() {
let alertRows = document.getElementById('alertsBody').getElementsByTagName("tr")
for (let i = 0; i < alertRows.length; i++) {
alertRows[i].getElementsByTagName('span')[0].innerText = window[alerts[i].variableName] == undefined ? '' : window[alerts[i].variableName]
}
}
//This is were the alert happen
alertLoop() {
for (let i = 0; i < alerts.length; i++) {
if (alerts[i].enabled) {
let type = alerts[i].type
let triggered = 0
switch(type) {
case "lt": {
triggered = window[alerts[i].variableName] < alerts[i].wantedValue ? 1 : 0
break;
}
case "le": {
triggered = window[alerts[i].variableName] <= alerts[i].wantedValue ? 1 : 0
break;
}
case "gt": {
triggered = window[alerts[i].variableName] > alerts[i].wantedValue ? 1 : 0
break;
}
case "ge": {
triggered = window[alerts[i].variableName] >= alerts[i].wantedValue ? 1 : 0
break;
}
case "eq": {
triggered = window[alerts[i].variableName] == alerts[i].wantedValue ? 1 : 0
break;
}
case "ne": {
triggered = window[alerts[i].variableName] != alerts[i].wantedValue && typeof window[alerts[i].variableName] != 'undefined' ? 1 : 0
break;
}
}
if (triggered == 1 && alerts[i].triggered == false) {
alerts[i].triggered = true
if (muteAllAlerts != true) {
if(alerts[i].soundType == "audio") {
let sound = new Audio(alerts[i].sound)
sound = isNaN(sound.duration) ? new Audio(ding) : sound
sound.volume = alertVolume / 100
sound.play()
} else if (alerts[i].soundType == "tts") {
const message = new SpeechSynthesisUtterance();
message.text = alerts[i].sound == ding ? defaultText : alerts[i].sound
message.voice = alertVoice
message.volume = alertVolume / 100
window.speechSynthesis.speak(message);
} else if (alerts[i].soundType == "eval") {// Remove from here
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
eval(command) // To here if you don't want eval
}
}
}
if (triggered == 0) {
alerts[i].triggered = false
}
}
}
}
}
const plugin = new AlertsPlugin();
IdlePixelPlus.registerPlugin(plugin);
})();