block-unwanted-pickpocketing-target

Hide unwanted targets from pickpocketing crime page to avoid unintended operation.

  1. // ==UserScript==
  2. // @name block-unwanted-pickpocketing-target
  3. // @namespace nodelore.torn.easy-market
  4. // @version 1.3
  5. // @description Hide unwanted targets from pickpocketing crime page to avoid unintended operation.
  6. // @author nodelore[2786679]
  7. // @license MIT
  8. // @match https://www.torn.com/loader.php?sid=crimes*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=torn.com
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function(){
  14. console.log(`[BUP] Block unwanted pickpocketing target!`)
  15. const $ = window.jQuery;
  16. const url = location.href;
  17. if(url.indexOf('pickpocketing') === -1){
  18. return;
  19. }
  20. let blockFlag = true;
  21.  
  22. // According to https://www.torn.com/forums.php#/p=threads&f=61&t=16358739&b=0&a=0
  23. const safety_targets = [
  24. "Drunk man",
  25. "Drunk woman",
  26. "Homeless person",
  27. "Junkie",
  28. "Elderly man",
  29. "Elderly woman"
  30. ]
  31.  
  32. // add targets you want to block here
  33. const block_targets = [
  34. "Gang member",
  35. "Thug",
  36. "Police officer",
  37. "Mobster",
  38. ]
  39.  
  40. // add activities you want to block here
  41. const avoid_activities = [
  42. "Jogging",
  43. "Cycling",
  44. "Walking", // you can remove this to enable showing walking target
  45. ]
  46.  
  47. const block_physicalprops = [
  48. "Muscular",
  49. "Athletic",
  50. ]
  51.  
  52. const block_elements = [];
  53.  
  54. const extractPhysical = function(physicalProps){
  55. if(physicalProps.length > 0){
  56. const allText = physicalProps.text();
  57. if(allText.length > 0){
  58. const splitProps = allText.split(',');
  59. if(splitProps.length > 0){
  60. return splitProps[0].split(' ')[0];
  61. }
  62. }
  63. }
  64. return '';
  65. }
  66.  
  67. const updatePocketState = function(crimeTitle){
  68. // update state
  69. const total = $('div.crime-option');
  70. let totalCount = 0;
  71. let blockCount = 0;
  72. total.each(function(){
  73. const clock = $(this).find("div[class^='clock']").text();
  74. if(clock === "0s"){
  75. $(this).hide();
  76. return;
  77. }
  78. else if($(this).css('display') === 'none'){
  79. blockCount += 1;
  80. }
  81. totalCount += 1;
  82. })
  83. // crimeTitle.find('span.pocket-state').text(`(${blockCount} of ${totalCount} blocked)`);
  84. }
  85.  
  86. const updateCrimeOption = function(option){
  87. const crimeTitle = $("div[class^='crimeHeading'] div:eq(0)");
  88. if(crimeTitle.find("span.pocket-state").length < 1){
  89. const pocket_state = $(`<span class="pocket-state t-red" title="Click to toggle"></span>`);
  90. pocket_state.click(function(){
  91. blockFlag = !blockFlag;
  92. if(blockFlag){
  93. for(let ele of block_elements){
  94. if(ele){
  95. ele.hide();
  96. }
  97. }
  98. crimeTitle.find('span.pocket-state').text(`(Blocking Enabled)`);
  99. }
  100. else{
  101. $('div.crime-option').each(function(){
  102. if($(this).css('display') === 'none'){
  103. $(this).show();
  104. block_elements.push($(this));
  105. }
  106. });
  107. crimeTitle.find('span.pocket-state').text(`(Blocking Disabled)`);
  108. }
  109. updatePocketState(crimeTitle);
  110. });
  111. crimeTitle.append(pocket_state);
  112. }
  113.  
  114. updatePocketState(crimeTitle);
  115. if(blockFlag){
  116. crimeTitle.find('span.pocket-state').text(`(Blocking Enabled)`);
  117. }
  118.  
  119. const titleProps = option.find("div[class^='titleAndProps'] div");
  120. const physicalProps = option.find("div[class^='titleAndProps'] button[class^='physicalPropsButton']");
  121.  
  122. const activities = option.find("div[class^='activity']");
  123. if(titleProps.length > 0 && activities.length > 0){
  124. const title = titleProps.contents().filter(function(){
  125. return this.nodeType === 3;
  126. }).text();
  127. const physical = extractPhysical(physicalProps);
  128. const activity = activities.contents().filter(function(){
  129. return this.nodeType === 3;
  130. }).text();
  131.  
  132. if(block_targets.indexOf(title) !== -1){
  133. block_elements.push(option);
  134. option.find("button[class*='commitButton']").css({
  135. border: '2px solid red'
  136. });
  137. if(blockFlag){
  138. option.hide();
  139. }
  140. console.log(`[BUP] Block ${title} who is ${activity} with physical status ${physical}`);
  141. }
  142. else if(avoid_activities.indexOf(activity) !== -1){
  143. block_elements.push(option);
  144. option.find("button[class*='commitButton']").css({
  145. border: '2px solid red'
  146. });
  147. if(blockFlag){
  148. option.hide();
  149. }
  150. console.log(`[BUP] Block ${title} who is ${activity} with physical status ${physical}`);
  151. }
  152. else if(block_physicalprops.indexOf(physical) !== -1){
  153. block_elements.push(option);
  154. option.find("button[class*='commitButton']").css({
  155. border: '2px solid red'
  156. });
  157. if(blockFlag){
  158. option.hide();
  159. }
  160. console.log(`[BUP] Block ${title} who is ${activity} with physical status ${physical}`);
  161. }
  162. else if(safety_targets.indexOf(title) !== -1){
  163. option.find("button[class*='commitButton']").css({
  164. border: '2px solid #37b24d'
  165. });
  166. console.log(`[BUP] Highlight ${title} who is ${activity} with physical status ${physical}`);
  167. }
  168. }
  169. }
  170.  
  171. waitForKeyElements('.crime-option', updateCrimeOption);
  172. })();
  173.  
  174. function waitForKeyElements(
  175. selectorTxt,
  176. actionFunction,
  177. bWaitOnce,
  178. iframeSelector
  179. ) {
  180. var targetNodes, btargetsFound;
  181. if (typeof iframeSelector == "undefined") targetNodes = $(selectorTxt);
  182. else targetNodes = $(iframeSelector).contents().find(selectorTxt);
  183. if (targetNodes && targetNodes.length > 0) {
  184. btargetsFound = true;
  185. /*--- Found target node(s). Go through each and act if they
  186. are new.
  187. */
  188. targetNodes.each(function () {
  189. var jThis = $(this);
  190. var alreadyFound = jThis.data("alreadyFound") || false;
  191. if (!alreadyFound) {
  192. //--- Call the payload function.
  193. var cancelFound = actionFunction(jThis);
  194. if (cancelFound) btargetsFound = false;
  195. else jThis.data("alreadyFound", true);
  196. }
  197. });
  198. } else {
  199. btargetsFound = false;
  200. }
  201. //--- Get the timer-control variable for this selector.
  202. var controlObj = waitForKeyElements.controlObj || {};
  203. var controlKey = selectorTxt.replace(/[^\w]/g, "_");
  204. var timeControl = controlObj[controlKey];
  205. //--- Now set or clear the timer as appropriate.
  206. if (btargetsFound && bWaitOnce && timeControl) {
  207. //--- The only condition where we need to clear the timer.
  208. clearInterval(timeControl);
  209. delete controlObj[controlKey];
  210. } else {
  211. //--- Set a timer, if needed.
  212. if (!timeControl) {
  213. timeControl = setInterval(function () {
  214. waitForKeyElements(
  215. selectorTxt,
  216. actionFunction,
  217. bWaitOnce,
  218. iframeSelector
  219. );
  220. }, 300);
  221. controlObj[controlKey] = timeControl;
  222. }
  223. }
  224. waitForKeyElements.controlObj = controlObj;
  225. }