FarmRPG Helper Utils

Utility functions and constants for FarmRPG Helper scripts

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/534607/1581181/FarmRPG%20Helper%20Utils.js

  1. // ==UserScript==
  2. // @name FarmRPG Helper Utils
  3. // @namespace https://gf.qytechs.cn/users/1114461
  4. // @version 1.0.0
  5. // @description Utility functions and constants for FarmRPG Helper scripts
  6. // @author Fewfre
  7. // @license GNU GPLv3
  8. // @grant unsafeWindow
  9. // ==/UserScript==
  10.  
  11. (function() {
  12. 'use strict';
  13.  
  14. // START OF SECTION: Initial Setup and Polyfills
  15. // Note: localStorage is inherently global, no need to export.
  16. // Consider if this needs to run in the Utils script or only the main one.
  17. // If multiple scripts might use it, keeping it here is fine.
  18. localStorage.setItem('fewfh-enable-all', "1");
  19.  
  20. (function () { const e = document.createElement("link").relList; if (e && e.supports && e.supports("modulepreload")) return; for (const i of document.querySelectorAll('link[rel="modulepreload"]')) s(i); new MutationObserver(i => { for (const l of i) if (l.type === "childList") for (const r of l.addedNodes) r.tagName === "LINK" && r.rel === "modulepreload" && s(r) }).observe(document, { childList: !0, subtree: !0 }); function t(i) { const l = {}; return i.integrity && (l.integrity = i.integrity), i.referrerPolicy && (l.referrerPolicy = i.referrerPolicy), i.crossOrigin === "use-credentials" ? l.credentials = "include" : i.crossOrigin === "anonymous" ? l.credentials = "omit" : l.credentials = "same-origin", l } function s(i) { if (i.ep) return; i.ep = !0; const l = t(i); fetch(i.href, l) } })();
  21. // END OF SECTION: Initial Setup and Polyfills
  22.  
  23. // START OF SECTION: App Wrapper (Q)
  24. var Q_internal; (n => { const e = (typeof unsafeWindow < "u" ? unsafeWindow : window).myApp; function t(r, o) { e.onPageInit(r, o) } n.onPageInit = t; function s(r, o) { e.onPageBeforeRemove(r, o) } n.onPageBeforeRemove = s; function i(r, o) { let a = null; n.onPageInit("*", c => { a === r && c.name !== r && o(c), a = c.name }) } n.onPageExit = i; function l() { e.mainView.router.refreshPage() } n.refreshPage = l })(Q_internal || (Q_internal = {}));
  25. // Export Q to the window object for other scripts to use
  26. unsafeWindow.Q = Q_internal;
  27. // END OF SECTION: App Wrapper (Q)
  28.  
  29.  
  30. // START OF SECTION: Constants (de)
  31. var de_internal; (n => {
  32. var audioCtx;
  33.  
  34. // Keep _e local if only used here
  35. function _e(n, e) { return Math.random() * (e - n) + n }
  36. unsafeWindow._e = _e;
  37.  
  38. function playBeepInternal(duration = 150, frequency = 1000, volume = 0.3, type = 'sine') {
  39. try {
  40. if (!audioCtx || audioCtx.state === 'closed') {
  41. audioCtx = new (window.AudioContext || window.webkitAudioContext)();
  42. }
  43. if (audioCtx.state === 'suspended') {
  44. audioCtx.resume();
  45. }
  46.  
  47. const oscillator = audioCtx.createOscillator();
  48. const gainNode = audioCtx.createGain();
  49. oscillator.connect(gainNode);
  50. gainNode.connect(audioCtx.destination);
  51.  
  52. oscillator.type = type;
  53. oscillator.frequency.setValueAtTime(frequency, audioCtx.currentTime);
  54.  
  55. const now = audioCtx.currentTime;
  56. const attackTime = 0.01; // 10ms fade in
  57. const decayTime = 0.01; // 10ms fade out
  58. const beepEndTime = now + duration / 1000;
  59.  
  60. gainNode.gain.setValueAtTime(0, now);
  61. gainNode.gain.linearRampToValueAtTime(volume, now + attackTime);
  62. gainNode.gain.setValueAtTime(volume, beepEndTime - decayTime);
  63. gainNode.gain.linearRampToValueAtTime(0.0001, beepEndTime);
  64.  
  65. oscillator.start(now);
  66. oscillator.stop(beepEndTime);
  67.  
  68. oscillator.onended = () => {
  69. oscillator.disconnect();
  70. gainNode.disconnect();
  71. };
  72.  
  73. } catch (e) {
  74. console.error("FarmRPG Helper Utils: Error playing beep sound.", e);
  75. // Fail silently if Web Audio API not supported or fails
  76. }
  77. }
  78.  
  79. n.SOUND_FINISHED = {
  80. play: function() {
  81. playBeepInternal(); // Uses default beep parameters
  82. }
  83. // Add other methods like pause(), etc., if needed
  84. };
  85.  
  86. // Assuming the chevron image is still needed, keep it.
  87. n.IMAGE_CEVRON_RIGHT = "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PScwIDAgNjAgMTIwJyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnPjxwYXRoIGQ9J202MCA2MS41LTM4LjI1IDM4LjI1LTkuNzUtOS43NSAyOS4yNS0yOC41LTI5LjI1LTI4LjUgOS43NS05Ljc1eicgZmlsbD0nI2M3YzdjYycvPjwvc3ZnPg==";
  88.  
  89. })(de_internal || (de_internal = {}));
  90. // Export de to the window object for other scripts to use
  91. unsafeWindow.de = de_internal;
  92. // END OF SECTION: Constants (de)
  93.  
  94. // START OF SECTION: Utility Functions
  95. // Keep _e local as it's only used by V and ft within this script
  96. function _e(n, e) { return Math.random() * (e - n) + n }
  97.  
  98. async function V_internal(n, e) { return new Promise(t => { setTimeout(t, e ? _e(n * 1e3, e * 1e3) : n * 1e3) }) }
  99. unsafeWindow.V = V_internal; // Export V
  100.  
  101. function ft_internal(n, e) { let t, s; return { promise: new Promise(l => { s = l, t = setTimeout(l, e ? _e(n * 1e3, e * 1e3) : n * 1e3) }), timeoutId: t, cancel() { clearTimeout(t), s() } } }
  102. unsafeWindow.ft = ft_internal; // Export ft
  103.  
  104. function ve_internal(n, e = {}) { return new Promise((t, s) => { const i = r => $(r).is(":visible") && parseInt($(r).css("opacity")) > .1; if ($(n).length && (!e.visible || i(n))) return t($(n + ":visible").first()[0]); const l = new MutationObserver(r => { $(n).length && (!e.visible || i(n)) && (t($(n + ":visible").first()[0]), l.disconnect()) }); e.timeout && V_internal(e.timeout).then(() => { l.disconnect(), s(new Error("observer timed out")) }), l.observe(e.target || document.body, { attributes: !0, childList: !0, subtree: !0, ...e.config }) }) }
  105. unsafeWindow.ve = ve_internal; // Export ve
  106.  
  107. async function we_internal(n, e) { return fetch(`worker.php?go=buyitem&id=${n}&qty=${e}`, { method: "POST" }).then(t => t.text()).then(t => Number.isNaN(Number.parseInt(t)) ? t : we_internal(n, t)) }
  108. unsafeWindow.we = we_internal; // Export we
  109.  
  110. const le_internal = { farming: 0, fishing: 0, crafting: 0, exploring: 0, cooking: 0 };
  111. unsafeWindow.le = le_internal; // Export le
  112.  
  113. function st_internal() {
  114. // Assumes jQuery ($) is available globally
  115. if (typeof $ === 'undefined') {
  116. console.error("FarmRPG Helper Utils: jQuery ($) is not defined. Cannot update skill levels.");
  117. return le_internal;
  118. }
  119. if ($('[href="progress.php?type=Farming"]').length) {
  120. le_internal.farming = parseInt($('[href="progress.php?type=Farming"]').parent().text().replaceAll(/[^\d]/g, "") || "0");
  121. le_internal.fishing = parseInt($('[href="progress.php?type=Fishing"]').parent().text().replaceAll(/[^\d]/g, "") || "0");
  122. le_internal.crafting = parseInt($('[href="progress.php?type=Crafting"]').parent().text().replaceAll(/[^\d]/g, "") || "0");
  123. le_internal.exploring = parseInt($('[href="progress.php?type=Exploring"]').parent().text().replaceAll(/[^\d]/g, "") || "0");
  124. le_internal.cooking = parseInt($('[href="progress.php?type=Cooking"]').parent().text().replaceAll(/[^\d]/g, "") || "0");
  125. }
  126. return le_internal;
  127. }
  128. unsafeWindow.st = st_internal; // Export st
  129. // END OF SECTION: Utility Functions
  130.  
  131. })();

QingJ © 2025

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