Greasy Fork is available in English.

SimpleBalancer

Balances API key and URL pairs usage

Ten skrypt nie powinien być instalowany bezpośrednio. Jest to biblioteka dla innych skyptów do włączenia dyrektywą meta // @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. }