mgecomHelper.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*
  2. 小芒商城助手
  3. [Script]
  4. # > 小芒商城助手
  5. ^https?:\/\/*\.api\.mgtv\.com url script-request-body https://git.jojo21.top/shawenguan/Quantumult-X/raw/master/Scripts/mangguo/mgecomHelper.js
  6. ^https?:\/\/*\.api\.mgtv\.com url script-response-body https://git.jojo21.top/shawenguan/Quantumult-X/raw/master/Scripts/mangguo/mgecomHelper.js
  7. [MITM]
  8. hostname = api.mgtv.com
  9. */
  10. const scriptName = `小芒商城助手`;
  11. const magicJS = MagicJS(scriptName, "INFO");
  12. const MGEcomConstKey = {
  13. AllUserInfo: 'mgeComAllUserInfo',
  14. AllUserConfig: 'mgeComAllUserConfig',
  15. };
  16. const gUserAgent = `Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Html5Plus/1.0 (Immersed/20) uni-app`;
  17. const gHost = `api.wubian.pro`;
  18. let gToken = magicJS.data.read(WuBianConstKey.Token, '');
  19. const gCommonHeaders = {
  20. 'Accept': `*/*`,
  21. 'Accept-Encoding': `gzip, deflate, br`,
  22. 'Connection': `keep-alive`,
  23. 'Content-Type': `application/json`,
  24. 'Cookie': `token=${gToken}`,
  25. 'Host': gHost,
  26. 'User-Agent': gUserAgent,
  27. 'CLIENT-TYPE': `APP`,
  28. 'token': gToken,
  29. 'Accept-Language': `zh-CN,zh-Hans;q=0.9`
  30. };
  31. let gRetBody;
  32. let gAllStateData = {
  33. }
  34. let SignHelper = (function () {
  35. const goldenRatio = 2654435769;
  36. function decodeByteArray(byteArray, hasLengthPrefix) {
  37. const length = byteArray.length;
  38. let totalLength = length << 2;
  39. if (hasLengthPrefix) {
  40. const lastByte = byteArray[length - 1];
  41. if (totalLength -= 4, lastByte < totalLength - 3 || lastByte > totalLength) return "";
  42. totalLength = lastByte;
  43. }
  44. for (let i = 0; i < length; i++) {
  45. byteArray[i] = String.fromCharCode(255 & byteArray[i], byteArray[i] >>> 8 & 255, byteArray[i] >>> 16 & 255, byteArray[i] >>> 24 & 255);
  46. }
  47. const resultString = byteArray.join("");
  48. return hasLengthPrefix ? resultString.substring(0, totalLength) : resultString;
  49. }
  50. function stringToByteArray(str, hasLengthPrefix) {
  51. const length = str.length;
  52. let byteArray, arrayLength = length >> 2;
  53. if (length & 3 !== 0) arrayLength++;
  54. if (hasLengthPrefix) {
  55. byteArray = new Array(arrayLength + 1);
  56. byteArray[arrayLength] = length;
  57. } else {
  58. byteArray = new Array(arrayLength);
  59. }
  60. for (let i = 0; i < length; ++i) {
  61. byteArray[i >> 2] |= str.charCodeAt(i) << ((3 & i) << 3);
  62. }
  63. return byteArray;
  64. }
  65. function unsignedRightShift(value) {
  66. return 4294967295 & value;
  67. }
  68. function customHashFunction(value, key, accumulator, index, arrayLength, keys) {
  69. return (accumulator >>> 5 ^ key << 2) + (key >>> 3 ^ accumulator << 4) ^ (value ^ key) + (keys[3 & index ^ arrayLength] ^ accumulator);
  70. }
  71. function ensureLength(byteArray) {
  72. if (byteArray.length < 4) byteArray.length = 4;
  73. return byteArray;
  74. }
  75. function encodeByteArray(byteArray, keys) {
  76. const length = byteArray.length;
  77. const lastIndex = length - 1;
  78. let temp, prevByte, nextByte;
  79. let sum = 0;
  80. for (prevByte = byteArray[lastIndex], sum = 0 | Math.floor(6 + 52 / length); sum > 0; --sum) {
  81. sum = unsignedRightShift(sum + goldenRatio);
  82. nextByte = sum >>> 2 & 3;
  83. for (let i = 0; i < lastIndex; ++i) {
  84. temp = byteArray[i + 1];
  85. prevByte = byteArray[i] = unsignedRightShift(byteArray[i] + customHashFunction(sum, temp, prevByte, i, nextByte, keys));
  86. }
  87. temp = byteArray[0];
  88. prevByte = byteArray[lastIndex] = unsignedRightShift(byteArray[lastIndex] + customHashFunction(sum, temp, prevByte, lastIndex, nextByte, keys));
  89. }
  90. return byteArray;
  91. }
  92. function utf8Encode(str) {
  93. if (/^[\x00-\x7f]*$/.test(str)) return str;
  94. const utf8Str = [];
  95. const length = str.length;
  96. for (let i = 0, j = 0; i < length; ++i, ++j) {
  97. const charCode = str.charCodeAt(i);
  98. if (charCode < 128) {
  99. utf8Str[j] = str.charAt(i);
  100. } else if (charCode < 2048) {
  101. utf8Str[j] = String.fromCharCode(192 | charCode >> 6, 128 | 63 & charCode);
  102. } else {
  103. if (charCode >= 55296 && charCode <= 57343) {
  104. if (i + 1 < length) {
  105. const nextCharCode = str.charCodeAt(i + 1);
  106. if (charCode < 56320 && 56320 <= nextCharCode && nextCharCode <= 57343) {
  107. const surrogatePair = 65536 + ((1023 & charCode) << 10 | 1023 & nextCharCode);
  108. utf8Str[j] = String.fromCharCode(240 | surrogatePair >> 18 & 63, 128 | surrogatePair >> 12 & 63, 128 | surrogatePair >> 6 & 63, 128 | 63 & surrogatePair);
  109. ++i;
  110. continue;
  111. }
  112. }
  113. throw new Error("Malformed string");
  114. }
  115. utf8Str[j] = String.fromCharCode(224 | charCode >> 12, 128 | charCode >> 6 & 63, 128 | 63 & charCode);
  116. }
  117. }
  118. return utf8Str.join("");
  119. }
  120. function encryptString(str, key) {
  121. if (str.length === 0) return str;
  122. str = utf8Encode(str);
  123. key = utf8Encode(key);
  124. return decodeByteArray(encodeByteArray(stringToByteArray(str, true), ensureLength(stringToByteArray(key, false))), false);
  125. }
  126. function base64Encode(str1, str2) {
  127. return btoa(encryptString(str1, str2));
  128. }
  129. function generateCustomString(str1, str2) {
  130. const md5 = createWMd5();
  131. return md5.hex_md5_32(`string xiaomang = "${str1}|${str2}";`);
  132. }
  133. function generateUuidWithVersion(uuid, version, offset) {
  134. const data = {
  135. uuid: uuid,
  136. reunixtime: Math.round((Date.now() - offset) / 1000),
  137. };
  138. const customString = generateCustomString(uuid, version);
  139. return base64Encode(JSON.stringify(data), customString);
  140. }
  141. function generateAnotherCustomString(str1, str2) {
  142. const md5 = createWMd5();
  143. return md5.hex_md5_32(`string ma = "${str1}|${str2}";`);
  144. }
  145. function generateRandomSalt() {
  146. const multiplier = 38833;
  147. const randomValue = Math.floor(Math.random() * 2 ** 32) + 1;
  148. return randomValue * multiplier;
  149. }
  150. function generateSignedUuid(uuid, version, offset, maBig, maSi) {
  151. let i = 0;
  152. let signedUuid = "";
  153. while (!(signedUuid <= maBig && signedUuid.includes(maSi))) {
  154. if (++i > 100000) return "";
  155. signedUuid = generateUuidWithSalt(uuid, version, offset);
  156. }
  157. console.log(i);
  158. return signedUuid;
  159. }
  160. function generateUuidWithSalt(uuid, version, offset) {
  161. const data = {
  162. uuid: uuid,
  163. reunixtime: Math.round((Date.now() - offset) / 1000),
  164. salt: generateRandomSalt(),
  165. };
  166. const customString = generateAnotherCustomString(uuid, version);
  167. return base64Encode(JSON.stringify(data), customString);
  168. }
  169. async function getDySign(uuid) {
  170. let stateData = await getStateData();
  171. const { userConfig, userInfo, diffTime } = stateData;
  172. return generateUuidWithVersion(userInfo.uuid, userConfig.version, diffTime);
  173. }
  174. async function getMaSign(uuid) {
  175. let stateData = await getStateData();
  176. const { userConfig, userInfo, diffTime } = stateData;
  177. return generateSignedUuid(userInfo.uuid || "", userConfig.version, diffTime, userConfig.version_ma_big, userConfig.version_ma_si);
  178. }
  179. return {
  180. getDySign: getDySign,
  181. getMaSign: getMaSign,
  182. };
  183. })();
  184. async function Main() {
  185. if (magicJS.isStrictRequest) {
  186. magicJS.checkRecordRequestBody();
  187. }
  188. if (magicJS.isRequest) {
  189. checkHandleRequest();
  190. } else {
  191. updateHeaders();
  192. }
  193. magicJS.notification.msg('');
  194. if (gRetBody) {
  195. magicJS.done({
  196. body: JSON.stringify(gRetBody)
  197. });
  198. } else {
  199. magicJS.done();
  200. }
  201. }
  202. function checkHandleRequest() {
  203. const url = $request.url;
  204. const path = $request.path;
  205. magicJS.logger.info(`请求url=${url}#${$request.method}`);
  206. magicJS.logger.info(`请求body=${magicJS.getRequestBody()}`);
  207. if ($request && $request.method != 'OPTIONS') {
  208. switch (path) {
  209. case '/GetUserInfo':
  210. handleUserInfo();
  211. break;
  212. case '/user/home/info':
  213. handleUserHomeInfo();
  214. break;
  215. default:
  216. break;
  217. }
  218. }
  219. }
  220. function handleHeaders() {
  221. }
  222. function updateHeaders() {
  223. }
  224. function getResponsePlainData() {
  225. let data = magicJS.getResponseBody();
  226. if (!data) {
  227. return;
  228. }
  229. try {
  230. return JSON.parse(data);
  231. } catch (err) {
  232. magicJS.logger.info(data);
  233. magicJS.logger.error(err);
  234. }
  235. }
  236. function getRequestPlainData() {
  237. let data = magicJS.getRequestBody();
  238. let reqData = null;
  239. if (data) {
  240. reqData = JSON.parse(data);
  241. } else {
  242. reqData = magicJS.parseQueryStr($request.url);
  243. }
  244. return reqData;
  245. }
  246. function getQueryPlainData() {
  247. let params = magicJS.parseQueryStr($request.url);
  248. return params;
  249. }
  250. function handleUserInfo() {
  251. let rspData = getResponsePlainData();
  252. if (!rspData) {
  253. return;
  254. }
  255. if (rspData.code != 200) {
  256. return;
  257. }
  258. let allUserDict = magicJS.data.read(MGEcomConstKey.AllUserInfo, {});
  259. const userInfo = rspData.data;
  260. if (userInfo) {
  261. let uuid = userInfo.uuid;
  262. let mobile = userInfo.relate_mobile;
  263. if (userInfo.ticket) {
  264. allUserDict[uuid] = userInfo;
  265. allUserDict[mobile] = userInfo;
  266. setDiffTime(Date.now() - 1e3 * homeInfo.unixtime);
  267. } else {
  268. delete allUserDict[uuid];
  269. delete allUserDict[mobile];
  270. }
  271. } else {
  272. let reqData = getQueryPlainData();
  273. let uuid = reqData.uuid;
  274. let oldUserInfo = allUserDict[uuid];
  275. if (oldUserInfo) {
  276. let mobile = oldUserInfo.relate_mobile;
  277. delete allUserDict[uuid];
  278. delete allUserDict[mobile];
  279. }
  280. }
  281. magicJS.data.write(MGEcomConstKey.AllUserInfo, allUserDict);
  282. }
  283. function handleUserHomeInfo() {
  284. let rspData = getResponsePlainData();
  285. if (!rspData) {
  286. return;
  287. }
  288. if (rspData.code != 200) {
  289. return;
  290. }
  291. const homeInfo = rspData.data;
  292. let allConfigDict = magicJS.data.read(MGEcomConstKey.AllUserConfig, {});
  293. let reqData = getQueryPlainData();
  294. let uuid = reqData.uuid;
  295. allConfigDict[uuid] = homeInfo;
  296. magicJS.data.write(MGEcomConstKey.AllUserConfig, allConfigDict);
  297. setDiffTime(Date.now() - 1e3 * homeInfo.unixtime);
  298. }
  299. async function getStateData(uuid) {
  300. let state = gAllStateData[uuid];
  301. if (!state) {
  302. state = {
  303. diffTime: 0,
  304. userInfo: null,
  305. userConfig: null,
  306. };
  307. gAllStateData[uuid] = state;
  308. };
  309. if (!state.userInfo) {
  310. state.userConfig = await getUserConfig(uuid);
  311. }
  312. if (!state.userInfo) {
  313. state.userInfo = await getUserInfo(uuid);
  314. }
  315. return state;
  316. }
  317. async function getUserConfig(uuid) {
  318. let allUserDict = magicJS.data.read(MGEcomConstKey.AllUserInfo, {});
  319. let userConfig = allUserDict[uuid];
  320. if (!userConfig) {
  321. }
  322. return userConfig;
  323. }
  324. async function getUserInfo(uuid) {
  325. let allConfigDict = magicJS.data.read(MGEcomConstKey.AllUserConfig, {});
  326. let userInfo = allConfigDict[uuid];
  327. if (!userInfo) {
  328. }
  329. return userInfo;
  330. }
  331. async function getDiffTime() {
  332. return 0;
  333. }
  334. function setDiffTime(diffTime) {
  335. }
  336. Main().catch((e) => magicJS.logger.log(`-\n ${e}`)).finally(() => magicJS.done());