OpenUserJS Bullshit Filter

Hides scripts for popular browser games and social networks as well as scripts that use "foreign" characters in descriptions.

目前為 2019-11-15 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name OpenUserJS Bullshit Filter
  3. // @namespace darkred
  4. // @version 2019.11.15
  5. // @description Hides scripts for popular browser games and social networks as well as scripts that use "foreign" characters in descriptions.
  6. // @author kuehlschrank, darkred, valacar
  7. // @license MIT
  8. // @include /^https:\/\/openuserjs\.org\/((\?(q|p|orderBy|library)=|group\/|users\/.*\/scripts).*)?$/
  9. // @include /^http:\/\/localhost:8080\/((\?(q|p|orderBy|library)=|group\/|users\/.*\/scripts).*)?$/
  10. // @grant none
  11. // @icon https://raw.githubusercontent.com/darkred/Userscripts/master/OpenUserJS_Bullshit_Filter/large.png
  12. // This is an edited version of this script (http://userscripts-mirror.org/scripts/show/97145) by kuehlschrank.
  13. // Thanks a lot to kuehlschrank for making another great script.
  14. // Thanks a lot to valacar for the refactoring.
  15. // ==/UserScript==
  16.  
  17.  
  18. (function() {
  19.  
  20. const DEBUGGING = 0;
  21.  
  22. const filters = {
  23. 'Non-ASCII': /[^\x00-\xBF\s]+/i,
  24. 'Games': /\w+\.io|Aimbot|AntiGame|Agar|agar\.io|alis\.io|angel\.io|ExtencionRipXChetoMalo|AposBot|DFxLite|ZTx-Lite|AposFeedingBot|AposLoader|Blah Blah|Orc Clan Script|Astro\s*Empires|^\s*Attack|^\s*Battle|BiteFight|Blood\s*Wars|Bots|Bots4|Brawler|\bBvS\b|Business\s*Tycoon|Castle\s*Age|City\s*Ville|chopcoin\.io|Comunio|Conquer\s*Club|CosmoPulse|cursors\.io|Dark\s*Orbit|Dead\s*Frontier|Diep\.io|\bDOA\b|doblons\.io|DotD|Dossergame|Dragons\s*of\s*Atlantis|driftin\.io|Dugout|\bDS[a-z]+\n|elites\.io|Empire\s*Board|eRep(ublik)?|Epicmafia|Epic.*War|ExoPlanet|Falcon Tools|Feuerwache|Farming|FarmVille|Fightinfo|Frontier\s*Ville|Ghost\s*Trapper|Gladiatus|Goalline|Gondal|gota\.io|Grepolis|Hobopolis|\bhwm(\b|_)|Ikariam|\bIT2\b|Jellyneo|Kapi\s*Hospital|Kings\s*Age|Kingdoms?\s*of|knastv(o|oe)gel|Knight\s*Fight|\b(Power)?KoC(Atta?ck)?\b|\bKOL\b|Kongregate|Last\s*Emperor|Legends?\s*of|Light\s*Rising|lite\.ext\.io|Lockerz|\bLoU\b|Mafia\s*(Wars|Mofo)|Menelgame|Mob\s*Wars|Mouse\s*Hunt|Molehill\s*Empire|NeoQuest|MyFreeFarm|narwhale\.io|Neopets|Nemexia|\bOGame\b|Ogar(io)?|Pardus|Pennergame|Pigskin\s*Empire|PlayerScripts|pokeradar\.io|Popmundo|Po?we?r\s*(Bot|Tools)|PsicoTSI|Ravenwood|Schulterglatze|slither\.io|slitherplus\.io|slitheriogameplay|SpaceWars|splix\.io|\bSW_[a-z]+\n|\bSnP\b|The\s*Crims|The\s*West|torto\.io|Travian|Treasure\s*Isl(and|e)|Tribal\s*Wars|TW.?PRO|Vampire\s*Wars|vertix\.io|War\s*of\s*Ninja|World\s*of\s*Tanks|West\s*Wars|wings\.io|\bWoD\b|World\s*of\s*Dungeons|wtf\s*battles|Wurzelimperium/iu,
  25. 'Social Networks': /Face\s*book|Google(\+| Plus)|\bHabbo|Kaskus|\bLepra|Leprosorium|MySpace|meinVZ|odnoklassniki|Одноклассники|Orkut|sch(ue|ü)ler(VZ|\.cc)?|studiVZ|Unfriend|Valenth|VK|vkontakte|ВКонтакте|Qzone|Twitter|TweetDeck/iu,
  26. 'Clutter': /^\s*(.{1,3})\1+\n|^\s*(.+?)\n+\2\n*$|^\s*.{1,5}\n|do\s*n('|o)?t (install|download)|nicht installieren|(just)?(\s*a)?\s*test|^\s*.{0,4}test.{0,4}\n|\ntest(ing)?\s*|^\s*(\{@|Smolka|Hacks)|\[\d{4,5}\]|free\s*download|theme|(night|dark) ?(mode)?/iu
  27. };
  28.  
  29. const commonCss = `
  30. .filter-status {
  31. margin-left: 6px;
  32. }
  33.  
  34. .filter-switches {
  35. display: none;
  36. }
  37.  
  38. :hover>.filter-switches {
  39. display: block;
  40. }
  41.  
  42. .filter-on,
  43. .filter-off {
  44. display: block;
  45. width: 125px;
  46. }
  47.  
  48. .filter-switches a {
  49. text-decoration: none;
  50. color: inherit;
  51. cursor: pointer;
  52. }
  53.  
  54. .filter-switches a {
  55. margin-left: 8px;
  56. padding: 0 4px;
  57. }
  58.  
  59. a.filter-on {
  60. background-color: #ffcccc;
  61. color: #333333;
  62. text-decoration: line-through;
  63. }
  64.  
  65. a.filter-off {
  66. background-color: #ccffcc;
  67. color: #333333
  68. }
  69. `;
  70.  
  71. // const isOnForum = window.location.href.includes('forum');
  72.  
  73. const site = {};
  74.  
  75.  
  76.  
  77. // if (isOnForum) {
  78. // // site.css = '.ItemDiscussion.filtered { display: none; } .filter-on, .filter-off { color: black; } ' + commonCss;
  79. // site.css = '.tr-link.filtered { display: none; } ' + commonCss;
  80. // site.cssDebug = '.tr-link.filtered { background-color: khaki; } ' + commonCss;
  81. // // site.filterStatusLocation = '#Head';
  82. // site.filterStatusLocation = '.col-md-2';
  83. // site.itemsToCheck = '.tr-link';
  84. // site.itemType = 'discussions';
  85. // site.removeFilter = function(el) {
  86. // el.classList.remove('filtered');
  87. // };
  88. // site.applyFilter = function(el, activeFilter) {
  89. // let textToFilter = el.firstElementChild.firstElementChild.innerText;
  90. // if (textToFilter.match(activeFilter) ) {
  91. // el.classList.add('filtered');
  92. // return true;
  93. // }
  94. // return false;
  95. // };
  96. // } else {
  97.  
  98. site.css = 'tr.filtered { display: none; } ' + commonCss;
  99. site.cssDebug = 'tr.filtered { background-color: khaki; } ' + commonCss;
  100. site.filterStatusLocation = '.col-sm-4';
  101. site.itemsToCheck = '.col-sm-8 tbody tr';
  102. site.itemType = 'scripts';
  103. site.removeFilter = function(el) {
  104. el.classList.remove('filtered');
  105. };
  106. site.applyFilter = function(el, activeFilter) {
  107. // if (el.innerText.match(activeFilter)) {
  108. let textToFilter = el.firstElementChild.querySelector('a.tr-link-a').innerText + ' ' + el.firstElementChild.lastElementChild.innerText ; // Script title + description
  109. if (textToFilter.match(activeFilter) ) {
  110.  
  111. el.classList.add('filtered');
  112. return true;
  113. }
  114. return false;
  115. };
  116. // }
  117.  
  118. insertStyle();
  119. insertStatus();
  120. filterScripts();
  121. insertSwitches();
  122.  
  123. function insertStyle() {
  124. const style = document.createElement('style');
  125. style.textContent = DEBUGGING ? site.cssDebug : site.css;
  126. style.type = 'text/css';
  127. document.head.appendChild(style);
  128. }
  129.  
  130. function insertStatus() {
  131. const p = document.querySelector(site.filterStatusLocation);
  132. if (p) {
  133. const status = document.createElement('span');
  134. status.className = 'filter-status';
  135. p.appendChild(status);
  136. }
  137. }
  138.  
  139.  
  140.  
  141. function filterScripts() {
  142. const activeFilters = [];
  143. for (let filterType of Object.keys(filters)) {
  144. if (configGetValue(filterType, 'on') === 'on') {
  145. activeFilters.push(filters[filterType]);
  146. }
  147. }
  148. const nodes = document.querySelectorAll(site.itemsToCheck);
  149. let numFiltered = 0;
  150. for (let node of nodes) {
  151. site.removeFilter(node);
  152. for (let activeFilter of activeFilters) {
  153. let filtered = site.applyFilter(node, activeFilter);
  154. if (filtered) {
  155. numFiltered++;
  156. break;
  157. }
  158. }
  159. }
  160. const filterStatus = document.querySelector('.filter-status');
  161. if (filterStatus) {
  162. const numUnfiltered = document.querySelectorAll(site.itemsToCheck).length - numFiltered;
  163. filterStatus.textContent = `${numUnfiltered} ${site.itemType} (${numFiltered} filtered)`;
  164. }
  165. }
  166.  
  167. function insertSwitches() {
  168. const span = document.createElement('span');
  169. span.className = 'filter-switches';
  170. for (let filterType of Object.keys(filters)) {
  171. span.appendChild(createSwitch(filterType, configGetValue(filterType, 'on') === 'on'));
  172. }
  173. const filterStatus = document.querySelector('.filter-status');
  174. if (filterStatus) {
  175. filterStatus.parentNode.appendChild(span);
  176. }
  177. }
  178.  
  179. function createSwitch(label, isOn) {
  180. const a = document.createElement('a');
  181. a.className = isOn ? 'filter-on' : 'filter-off';
  182. a.textContent = label;
  183. a.addEventListener('click', function(e) {
  184. if (this.className === 'filter-on') {
  185. this.className = 'filter-off';
  186. configSetValue(this.textContent, 'off');
  187. } else {
  188. this.className = 'filter-on';
  189. configSetValue(this.textContent, 'on');
  190. }
  191. filterScripts();
  192. e.preventDefault();
  193. }, false);
  194. return a;
  195. }
  196.  
  197. function configSetValue(name, value) {
  198. localStorage.setItem(name, value);
  199. }
  200.  
  201. function configGetValue(name, defaultValue) {
  202. const value = localStorage.getItem(name);
  203. return value ? value : defaultValue;
  204. }
  205.  
  206. })();

QingJ © 2025

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