SimpleBalancer

Balances API key and URL pairs usage

Tento skript by neměl být instalován přímo. Jedná se o knihovnu, kterou by měly jiné skripty využívat pomocí meta příkazu // @require https://update.greatest.deepsurf.us/scripts/528703/1546610/SimpleBalancer.js

  1. // ==UserScript==
  2. // @name SimpleBalancer
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description Balances API key and URL pairs usage
  6. // @author RoCry
  7. // @grant GM_setValue
  8. // @grant GM_getValue
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. class SimpleBalancer {
  13. /**
  14. * Balances API key and URL pairs usage
  15. */
  16. constructor() {
  17. this.loadUsageData();
  18. }
  19.  
  20. loadUsageData() {
  21. try {
  22. // Use GM_getValue for Tampermonkey/Greasemonkey persistence
  23. this.pairUsage = GM_getValue('simpleBalancerUsage', {});
  24. } catch (error) {
  25. console.error('Error loading balancer data:', error);
  26. this.pairUsage = {};
  27. }
  28. }
  29.  
  30. saveUsageData() {
  31. try {
  32. // Use GM_setValue for Tampermonkey/Greasemonkey persistence
  33. GM_setValue('simpleBalancerUsage', this.pairUsage);
  34. } catch (error) {
  35. console.error('Error saving balancer data:', error);
  36. }
  37. }
  38.  
  39. parseItems(items) {
  40. return items.split(',').map(item => item.trim()).filter(item => item);
  41. }
  42.  
  43. createPairKey(key, url) {
  44. return `${key}|||${url}`;
  45. }
  46.  
  47. parsePairKey(pairKey) {
  48. const [key, url] = pairKey.split('|||');
  49. return [key, url];
  50. }
  51.  
  52. /**
  53. * Choose a key-URL pair based on usage balancing.
  54. * Cases:
  55. * 1. 1 key, 1 url -> single pair
  56. * 2. 1 key, n urls -> key paired with each url
  57. * 3. n keys, n urls -> matching pairs
  58. * 4. n keys, 1 url -> each key paired with url
  59. *
  60. * @param {string} keys - Comma-separated list of API keys
  61. * @param {string} urls - Comma-separated list of URLs
  62. * @returns {Array} - [key, url] pair that was selected
  63. */
  64. choosePair(keys, urls) {
  65. const keyList = this.parseItems(keys);
  66. const urlList = this.parseItems(urls);
  67.  
  68. if (keyList.length === 0 || urlList.length === 0) {
  69. throw new Error("Keys and URLs cannot be empty");
  70. }
  71.  
  72. // Generate valid pairs based on the cases
  73. let pairs = [];
  74.  
  75. if (urlList.length === 1) {
  76. pairs = keyList.map(key => [key, urlList[0]]);
  77. } else if (keyList.length === 1) {
  78. pairs = urlList.map(url => [keyList[0], url]);
  79. } else {
  80. if (keyList.length !== urlList.length) {
  81. throw new Error("When using multiple keys and URLs, their counts must match");
  82. }
  83. pairs = keyList.map((key, index) => [key, urlList[index]]);
  84. }
  85.  
  86. // Convert pairs to pairKeys and initialize usage count if needed
  87. const pairKeys = pairs.map(([key, url]) => {
  88. const pairKey = this.createPairKey(key, url);
  89. if (!(pairKey in this.pairUsage)) {
  90. this.pairUsage[pairKey] = 0;
  91. }
  92. return pairKey;
  93. });
  94.  
  95. // Find the minimum usage count
  96. const minUsage = Math.min(...pairKeys.map(key => this.pairUsage[key]));
  97.  
  98. // Find all pairs with minimum usage
  99. const leastUsedPairKeys = pairKeys.filter(key => this.pairUsage[key] === minUsage);
  100.  
  101. // Randomly select one of the least used pairs
  102. const randomIndex = Math.floor(Math.random() * leastUsedPairKeys.length);
  103. const chosenPairKey = leastUsedPairKeys[randomIndex];
  104.  
  105. // Increment usage for the chosen pair
  106. this.pairUsage[chosenPairKey]++;
  107.  
  108. // Save updated usage data
  109. this.saveUsageData();
  110.  
  111. // Return the chosen pair
  112. return this.parsePairKey(chosenPairKey);
  113. }
  114.  
  115. resetUsage() {
  116. this.pairUsage = {};
  117. this.saveUsageData();
  118. }
  119.  
  120. getUsageStats() {
  121. const stats = {};
  122. for (const pairKey in this.pairUsage) {
  123. const [key, url] = this.parsePairKey(pairKey);
  124. stats[`${key}, ${url}`] = this.pairUsage[pairKey];
  125. }
  126. return stats;
  127. }
  128. }
  129.  
  130. // Make it available globally for other scripts to use
  131. if (typeof module !== 'undefined') {
  132. module.exports = SimpleBalancer;
  133. } else {
  134. window.SimpleBalancer = SimpleBalancer;
  135. }