跟单

try to take over the world!

  1. // ==UserScript==
  2. // @name 跟单
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.5
  5. // @description try to take over the world!
  6. // @author You
  7. // @include http*://q1.88666333.com/*
  8. // @grant GM_xmlhttpRequest
  9. // @grant GM.getTab
  10. // @grant GM.saveTab
  11. // @grant GM.setValue
  12. // @grant GM.getValue
  13. // @run-at document-body
  14. // ==/UserScript==
  15.  
  16. (function() {
  17. 'use strict';
  18. const THREAD_SIZE = 10;
  19. var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
  20. function isPromise(obj) {
  21. return !!obj && ((typeof obj === 'object' && typeof obj.then === 'function') || (typeof obj === 'function' && typeof obj().then === 'function'));
  22. }
  23. /**
  24. * Wait Resource.
  25. *
  26. * @param {Function} resourceFn pred function to check resource
  27. * @param {Object} options
  28. * @returns Promise
  29. */
  30. function waitResource(resourceFn, options) {
  31. var optionsRes = Object.assign(
  32. {
  33. interval: 1000,
  34. max: 6
  35. },
  36. options
  37. );
  38. var current = 0;
  39. return new Promise((resolve, reject) => {
  40. var timer = setInterval(() => {
  41. if (isPromise(resourceFn)) {
  42. resourceFn().then(res => {
  43. if(res) {
  44. clearInterval(timer);
  45. resolve();
  46. }
  47. });
  48. } else if (resourceFn()) {
  49. clearInterval(timer);
  50. resolve();
  51. }
  52. current++;
  53. if (current >= optionsRes.max) {
  54. clearInterval(timer);
  55. reject('Time out');
  56. }
  57. }, optionsRes.interval);
  58. });
  59. }
  60.  
  61.  
  62. function requestAsync(data) {
  63. // console.log(data);
  64. return new Promise((resolve, reject) => {
  65. var reportAJAX_Error = (rspObj) => {
  66. console.error (`Request error: ${data}`);
  67. reject(`Request => Error ${data} RES ${rspObj.status}! ${rspObj.statusText}`);
  68. }
  69.  
  70. var processJSON_Response = (rspObj) => {
  71. if (rspObj.status != 200 && rspObj.status != 304) {
  72. reportAJAX_Error (rspObj);
  73. } else {
  74. let resJSON = {};
  75. try{
  76. resJSON = JSON.parse(rspObj.responseText);
  77. } catch(err) {
  78. // ignore
  79. console.log(err);
  80. }
  81. resolve(resJSON);
  82. }
  83. };
  84. GM_xmlhttpRequest ( {
  85. method: "POST",
  86. url: document.location.origin + "/!/MemberBet",
  87. headers: {
  88. "Referer": document.location.href,
  89. "Content-Type": "application/x-www-form-urlencoded"
  90. },
  91. data: data,
  92. // responseType: "json",
  93. onload: processJSON_Response,
  94. onabort: reportAJAX_Error,
  95. onerror: reportAJAX_Error,
  96. ontimeout: reportAJAX_Error
  97. });
  98. });
  99. }
  100.  
  101. function getOrdersAsync(account, gameType, gameCode, pageIndex) {
  102. return new Promise((resolve, reject) => {
  103. $.get(`${document.location.origin}/!/UserBets?Account=${account}&GameType=${gameType}&GameCode=${gameCode}&PageSize=100&PageIndex=${pageIndex}`).done(function(result) {
  104. resolve(result);
  105. }).fail(function(jqXHR, textStatus, errorThrown) {
  106. reject(`Request => Error ${errorThrown} status ${textStatus}`);
  107. });
  108. });
  109. }
  110. function resToMask(res) {
  111. let placeHolders = ['abcXX', 'abXcX', 'abXXc', 'aXbcX', 'aXbXc', 'aXXbc', 'XabcX', 'XabXc', 'XaXbc', 'XXabc'];
  112. return placeHolders.map(a => {
  113. let mask = 'XXXXX'.split('');
  114. for(let i = 0; i < 5; i++) {
  115. if (a[i] !== 'X') {
  116. mask[i] = res[i];
  117. }
  118. }
  119. return mask.join('');
  120. });
  121. }
  122.  
  123. function signalA(pool) {
  124. return false;
  125. }
  126.  
  127. async function bet(pools) {
  128. let count = pools.length;
  129. // %3D
  130. //const REQ_DATA = `SourceType=quick-comb&SourceData=%7B%22bet-type%22%3A%22d3%22%2C%22bet-count%22%3A${count}%2C%22dingwei-include%22%3A1%2C%22dingwei-1%22%3A%2212%22%2C%22dingwei-2%22%3A%221%22%2C%22dingwei-3%22%3A%221%22%2C%22hefeng-include%22%3A1%2C%22dan-include%22%3A1%2C%22shuang-include%22%3A1%7D&Game=${GameType}&Pools=${pools.join('%2C')}&Amount=${amount}`;
  131. const REQ_DATA = `SourceType=txt-import&SourceData=${count}+%E4%B8%AA%E5%8F%B7%E7%A0%81%EF%BC%88%E5%B8%A6%E9%87%91%E9%A2%9D%EF%BC%89&Game=${GameType}&Pools=${pools.join('%2C')}&Amount=`;
  132. console.log(REQ_DATA);
  133. return await requestAsync(REQ_DATA);
  134. }
  135.  
  136. function addUI() {
  137. let div=document.createElement("div");
  138. div.setAttribute("style", "width:360px");
  139. let btn=document.createElement("BUTTON");
  140. btn.setAttribute("id", "betBtn");
  141. div.appendChild(btn);
  142. let amount = document.createElement("INPUT");
  143. amount.setAttribute("id", "sigAccount");
  144. amount.setAttribute("placeholder", "跟单信号源");
  145. amount.setAttribute("type", "text");
  146. div.appendChild(amount);
  147. let node = document.querySelector('#branch-info');
  148. let parentNode = node.parentNode;
  149. parentNode.insertBefore(div, node);
  150. }
  151.  
  152. async function main() {
  153. if (window !== top) {
  154. console.log(window.location.href);
  155. // let summaryUsersGame = document.querySelector("a[href='summary-users-game.html']");
  156. if (window.location.pathname.includes("summary-users.html")) {
  157. while (true) {
  158. let summaryUsersGame = document.querySelector("a[href='summary-users-game.html']");
  159. if (summaryUsersGame && summaryUsersGame.classList[0] !== 'active') {
  160. summaryUsersGame.click();
  161. }
  162. await wait(3000);
  163. }
  164. } else {
  165. return;
  166. }
  167. }
  168.  
  169. console.log("START...", new Date());
  170. if (window.location.pathname === "/") { // login
  171. let user = await GM.getTab();
  172. console.log("DEBUG ", user);
  173. if (!!user && !!user.name) {
  174. await wait(1000);
  175. document.querySelector('#login-id').value = user.name;
  176. await wait(500);
  177. document.querySelector('#password').value = user.password;
  178. await wait(500);
  179. document.querySelector('.btn-primary').click();
  180. } else {
  181. document.querySelector('.btn-primary').onclick = async () => {
  182. user.name = document.querySelector('#login-id').value;
  183. user.password = document.querySelector('#password').value;
  184. await GM.saveTab(user);
  185. }
  186. }
  187. return;
  188. }
  189. if (window.location.pathname === "/agreement.html") {
  190. await wait(500);
  191. document.querySelector('#lnk-agree').click();
  192. return;
  193. }
  194. await waitResource(async () => {
  195. console.log(document.querySelector('#account'));
  196. return typeof ENV === "object" && ENV !== null && !!ENV[GameType] && !!ENV[GameType].Resulted;
  197. });
  198. if (!!document.querySelector('#branch-info')) // member
  199. {
  200. addUI();
  201. while (true) {
  202. await GM.setValue("currentGameCode", ENV[GameType].Current.Code);
  203. let tabObj = await GM.getTab();
  204. // console.log('tabObj: ', tabObj);
  205. if (tabObj.started) {
  206. if (tabObj.gameType !== GameType) {
  207. document.querySelector(`#game-type-${tabObj.gameType}`).click();
  208. }
  209. document.querySelector('#betBtn').innerText = `结束`;
  210. document.querySelector("#sigAccount").value = await GM.getValue('sigAccount');
  211. document.querySelector('#betBtn').onclick = async () => {
  212. tabObj.started = false;
  213. await GM.saveTab(tabObj);
  214. await GM.setValue('sigGameType', null);
  215. await GM.setValue('sigAccount', null);
  216. document.querySelector('#betBtn').innerText = "...";
  217. }
  218. } else {
  219. document.querySelector('#betBtn').innerText = "开始";
  220. document.querySelector('#betBtn').onclick = async () => {
  221. tabObj.started = true;
  222. tabObj.gameType = GameType;
  223. tabObj.betInfo = {
  224. gameCode: ENV[GameType].Current.Code,
  225. betIdMap: {}
  226. };
  227. await GM.saveTab(tabObj);
  228. await GM.setValue('sigGameType', GameType);
  229. await GM.setValue('sigAccount', document.querySelector("#sigAccount").value);
  230. document.querySelector('#betBtn').innerText = "...";
  231. }
  232. }
  233.  
  234. if (!tabObj.started || new Date().getTime() / 1000 > ENV[GameType].Current.Close) {
  235. await wait(1000);
  236. continue;
  237. }
  238. let sigOrders = await GM.getValue("sigOrders", {});
  239. if (sigOrders.gameCode !== ENV[GameType].Current.Code) {
  240. console.log("Game code not current");
  241. await wait(1000);
  242. continue;
  243. }
  244. if (tabObj.betInfo.gameCode !== ENV[GameType].Current.Code) {
  245. tabObj.betInfo.gameCode = ENV[GameType].Current.Code;
  246. tabObj.betInfo.betIdMap = {};
  247. }
  248. // work
  249. let betId = 0;
  250. Object.keys(sigOrders.pools).forEach((key) => {
  251. if (betId === 0 && !tabObj.betInfo.betIdMap[key]) {
  252. betId = parseInt(key);
  253. }
  254. });
  255. //
  256. if (betId > 0) {
  257. // if (true) {
  258. let res = await bet(sigOrders.pools[betId]);
  259. if (res.Error && res.Error !== '额度不足' && res.Error !== '账号已停用下注') {
  260. throw(res);
  261. }
  262. console.log(res);
  263. console.log("betId", betId, tabObj.betInfo);
  264. tabObj.betInfo.betIdMap[betId] = true;
  265. await GM.saveTab(tabObj);
  266. continue;
  267. }
  268. // end work
  269. await wait(1000);
  270. }
  271. } else if (!!document.querySelector('#user-link')) { // signal
  272. while (true) {
  273. // 打开报表
  274. if (document.querySelector('a[href="/a/summary-users.html').classList[1] !== 'selected') {
  275. document.querySelector('a[href="/a/summary-users.html').click();
  276. await wait(5000);
  277. continue;
  278. }
  279. let sigAccount = await GM.getValue("sigAccount");
  280. let sigGameType = await GM.getValue("sigGameType");
  281. console.log(sigAccount, sigGameType);
  282. if (!sigAccount || !sigGameType) {
  283. await wait(1000);
  284. continue;
  285. }
  286. let sigOrders = await GM.getValue("sigOrders", {});
  287. console.log("DEBUG sigOrder init", sigOrders);
  288. if (sigOrders.gameType !== sigGameType || sigOrders.gameCode !== ENV[sigGameType].Current.Code) {
  289. sigOrders.gameType = sigGameType;
  290. sigOrders.gameCode = ENV[sigGameType].Current.Code;
  291. sigOrders.pools = {};
  292. sigOrders.total = 0;
  293. }
  294. let res = null;
  295. try {
  296. res = await getOrdersAsync(sigAccount,sigGameType, sigOrders.gameCode, 0);
  297. await wait(1000);
  298. } catch (err) {
  299. console.log('ignore error:', err);
  300. continue;
  301. }
  302. let remainPages = Math.ceil((res.Total - sigOrders.total) / 100);
  303. console.log("remain pages", remainPages, res.Total, sigOrders.total);
  304. let idx = 0;
  305. let rows = [];
  306. let baseIdx = 0;
  307. while (remainPages > 0) {
  308. let jobSize = remainPages <= THREAD_SIZE ? remainPages : THREAD_SIZE;
  309. let jobReses = await Promise.all([...Array(jobSize).keys()].map((a) => getOrdersAsync(sigAccount,sigGameType, sigOrders.gameCode, a + baseIdx)));
  310. console.log("jobs result", jobReses);
  311. jobReses.forEach((res) => {
  312. for (let i = 0; i < res.List.length && (rows.length < res.Total - sigOrders.total); i++) {
  313. rows.push({
  314. betId: res.List[i].BetID,
  315. pool: res.List[i].Pool,
  316. amount: res.List[i].Amounts[0] / 1000
  317. });
  318. }
  319. });
  320. await wait(1000);
  321. remainPages -= jobSize;
  322. baseIdx += jobSize;
  323. }
  324.  
  325. for (let i = rows.length - 1; i >= 0; i--) {
  326. let id = rows[i].betId;
  327. if (!Array.isArray(sigOrders.pools[id])) { // new a bet
  328. sigOrders.pools[id] = [];
  329. }
  330. sigOrders.pools[id].push(`${rows[i].pool}%3D${rows[i].amount}`);
  331. sigOrders.total++;
  332. }
  333. // console.log(sigOrders);
  334. await GM.setValue("sigOrders", sigOrders);
  335. await wait(2000);
  336. }
  337. }
  338. }
  339. main()
  340. .then(() => console.log("Main Done"))
  341. .catch((err) => {
  342. console.error(err, "Restart in 6 secs ...");
  343. setTimeout(() => location.reload(), 6 * 1000);
  344. });
  345. })();

QingJ © 2025

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