Ver código fonte

init: moutai xmTravel

mrabit 2 anos atrás
commit
0e12d2a4cf
9 arquivos alterados com 598 adições e 0 exclusões
  1. 173 0
      .gitignore
  2. 9 0
      .prettierrc
  3. 17 0
      .vscode/launch.json
  4. 5 0
      config.example.js
  5. 11 0
      console.js
  6. 178 0
      index.js
  7. 175 0
      package-lock.json
  8. 18 0
      package.json
  9. 12 0
      script.json

+ 173 - 0
.gitignore

@@ -0,0 +1,173 @@
+
+# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,node
+# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,node
+
+### Node ###
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+.pnpm-debug.log*
+
+# Diagnostic reports (https://nodejs.org/api/report.html)
+report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+*.lcov
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# Snowpack dependency directory (https://snowpack.dev/)
+web_modules/
+
+# TypeScript cache
+*.tsbuildinfo
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional stylelint cache
+.stylelintcache
+
+# Microbundle cache
+.rpt2_cache/
+.rts2_cache_cjs/
+.rts2_cache_es/
+.rts2_cache_umd/
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variable files
+.env
+.env.development.local
+.env.test.local
+.env.production.local
+.env.local
+
+# parcel-bundler cache (https://parceljs.org/)
+.cache
+.parcel-cache
+
+# Next.js build output
+.next
+out
+
+# Nuxt.js build / generate output
+.nuxt
+dist
+
+# Gatsby files
+.cache/
+# Comment in the public line in if your project uses Gatsby and not Next.js
+# https://nextjs.org/blog/next-9-1#public-directory-support
+# public
+
+# vuepress build output
+.vuepress/dist
+
+# vuepress v2.x temp and cache directory
+.temp
+
+# Docusaurus cache and generated files
+.docusaurus
+
+# Serverless directories
+.serverless/
+
+# FuseBox cache
+.fusebox/
+
+# DynamoDB Local files
+.dynamodb/
+
+# TernJS port file
+.tern-port
+
+# Stores VSCode versions used for testing VSCode extensions
+.vscode-test
+
+# yarn v2
+.yarn/cache
+.yarn/unplugged
+.yarn/build-state.yml
+.yarn/install-state.gz
+.pnp.*
+
+### Node Patch ###
+# Serverless Webpack directories
+.webpack/
+
+# Optional stylelint cache
+
+# SvelteKit build / generate output
+.svelte-kit
+
+### VisualStudioCode ###
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+!.vscode/*.code-snippets
+
+# Local History for Visual Studio Code
+.history/
+
+# Built Visual Studio Code Extensions
+*.vsix
+
+### VisualStudioCode Patch ###
+# Ignore all local history of files
+.history
+.ionide
+
+# Support for Project snippet scope
+.vscode/*.code-snippets
+
+# Ignore code-workspaces
+*.code-workspace
+
+# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,node
+n
+
+config.js

+ 9 - 0
.prettierrc

@@ -0,0 +1,9 @@
+{
+  "singleQuote": true,
+  "semi": false,
+  "endOfLine": "lf",
+  "tabWidth": 2,
+  "trailingComma": "none",
+  "bracketSpacing": true,
+  "arrowParens": "avoid"
+}

+ 17 - 0
.vscode/launch.json

@@ -0,0 +1,17 @@
+{
+  // Use IntelliSense to learn about possible attributes.
+  // Hover to view descriptions of existing attributes.
+  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "type": "pwa-node",
+      "request": "launch",
+      "name": "Launch Program",
+      "skipFiles": [
+        "<node_internals>/**"
+      ],
+      "program": "${workspaceFolder}/index.js"
+    }
+  ]
+}

+ 5 - 0
config.example.js

@@ -0,0 +1,5 @@
+module.exports = {
+  baseURL: '',
+  cookie: '',
+  deviceId: ''
+}

+ 11 - 0
console.js

@@ -0,0 +1,11 @@
+const dayjs = require('dayjs')
+const colors = require('colors')
+
+console.log = (function (oriLogFunc) {
+  return function (...args) {
+    args.unshift(
+      colors.green(`[${dayjs(new Date()).format('YY-MM-DD HH:mm:ss')}]`)
+    )
+    oriLogFunc.apply(console, args)
+  }
+})(console.log)

+ 178 - 0
index.js

@@ -0,0 +1,178 @@
+const { default: axios } = require('axios')
+const dayjs = require('dayjs')
+const duration = require('dayjs/plugin/duration')
+const schedule = require('node-schedule')
+const { baseURL, cookie, deviceId } = require('./config')
+require('./console')
+
+dayjs.extend(duration)
+
+// axios.defaults.baseURL = baseURL
+axios.interceptors.request.use(req => {
+  req.headers['X-Requested-With'] = 'XMLHttpRequest'
+  req.headers['Accept-Language'] = 'zh-cn'
+  req.headers['MT-Request-ID'] = getGUID()
+  req.headers[
+    'User-Agent'
+  ] = `Mozilla/5.0 (iPhone; CPU iPhone OS 14_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 moutaiapp/1.2.1 device-id/${deviceId}`
+  req.headers['Referer'] =
+    'https://h5.moutai519.com.cn/gux/game/main?appConfig=2_1_2'
+  req.headers['Cookie'] = cookie
+  req.headers['Accept'] = 'application/json, text/javascript, */*; q=0.01'
+  req.headers['Content-Type'] = 'application/json'
+  req.headers['MT-APP-Version'] = '1.0.0'
+  req.headers['Origin'] = 'https://h5.moutai519.com.cn'
+  return req
+})
+
+function getGUID(key = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx') {
+  return key.replace(/[xy]/g, function (c) {
+    var r = (Math.random() * 16) | 0
+    var v = c == 'x' ? r : (r & 0x3) | 0x8
+
+    return v.toString(16)
+  })
+}
+
+async function httpRequest(url, method = 'get', _data) {
+  let params = ''
+  let data = {}
+  if (method === 'get') {
+    params = _data
+  } else {
+    data = _data
+  }
+  return await axios({
+    url,
+    method,
+    data,
+    params
+  })
+    .then(d => d.data)
+    .catch(d => {
+      if (d.response.status === 500 && d.response.data) {
+        return Promise.resolve(d.response.data)
+      }
+      console.log(d)
+    })
+}
+
+function getXmTravelInfo() {
+  console.log()
+  console.log('获取旅行信息: ')
+  return httpRequest(baseURL + 'getXmTravelInfo', 'get', {
+    __timestamp: +new Date()
+  }).then(d => {
+    let { lastStartTravelTs, travelTotalTime, remainTravelCnt, travelStatus } =
+      d.data
+
+    let startTime = dayjs(lastStartTravelTs)
+    let endTime = startTime.add(3, 'h')
+
+    let finish = +new Date() - endTime.valueOf() >= 0
+    if (!finish) {
+      console.log('旅行暂未结束')
+      console.log(
+        '本次旅行开始时间: ',
+        dayjs(lastStartTravelTs).format('YYYY-MM-DD HH:mm:ss')
+      )
+      console.log(
+        '本次旅行结束时间: ',
+        startTime.add(3, 'h').format('YYYY-MM-DD HH:mm:ss')
+      )
+      console.log(
+        '本次旅行剩余时间: ',
+        dayjs.duration(endTime - +new Date()).format('HH 小时 mm 分钟 ss 秒')
+      )
+      return Promise.reject()
+    }
+    if (remainTravelCnt >= travelTotalTime) {
+      console.log('当日旅行次数已耗尽')
+      return Promise.reject()
+    }
+    console.log('剩余旅行次数: ', travelTotalTime - remainTravelCnt)
+  })
+}
+
+function getUserEnergyAward() {
+  console.log()
+  console.log('获取申购耐力值: ')
+  return httpRequest(
+    'https://h5.moutai519.com.cn/game/isolationPage/getUserEnergyAward',
+    'post',
+    {}
+  ).then(d => {
+    if (d.code === 2000) {
+      console.log('耐力值领取成功')
+    } else {
+      console.log('耐力值领取失败', d.message || '')
+      return Promise.reject()
+    }
+  })
+}
+
+function getXmTravelReward() {
+  console.log()
+  console.log('查询旅行奖励: ')
+  return httpRequest(baseURL + 'getXmTravelReward', 'get', {
+    __timestamp: +new Date()
+  }).then(d => {
+    if (d.code === 2000 && d.data.travelRewardXmy) {
+      console.log('可获取小茅运: ', d.data.travelRewardXmy)
+    } else {
+      console.log('旅行暂未完成', d.message || '')
+      return Promise.reject()
+    }
+  })
+}
+
+function receiveReward() {
+  console.log()
+  console.log('领取旅行奖励: ')
+  return httpRequest(baseURL + 'receiveReward', 'post', {}).then(d => {
+    if (d.code === 2000) {
+      console.log('领取成功')
+    } else {
+      console.log('领取失败', d.message || '')
+      return Promise.reject()
+    }
+  })
+}
+
+function startTravel() {
+  console.log()
+  console.log('开始旅行: ')
+  return httpRequest(baseURL + 'startTravel', 'post', {}).then(d => {
+    if (d.code === 2000) {
+      console.log('开始旅行成功')
+    } else {
+      console.log('开始旅行失败', d.message || '')
+      return Promise.reject()
+    }
+  })
+}
+
+async function init() {
+  console.log('开始执行')
+  let time = +dayjs().format('HH')
+  if (time < 9) {
+    console.log('活动未开始')
+    return false
+  }
+  try {
+    await getUserEnergyAward()
+  } catch (e) {}
+  try {
+    await getXmTravelInfo()
+    await getXmTravelReward()
+    await receiveReward()
+    await startTravel()
+  } catch (e) {
+    console.log()
+    console.log('脚本执行完毕')
+    console.log()
+  }
+}
+
+init()
+schedule.scheduleJob('00 00 */1 * * *', init) // 每小时

+ 175 - 0
package-lock.json

@@ -0,0 +1,175 @@
+{
+  "name": "xmtravel",
+  "version": "1.0.0",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://ddns.mrabit.com:10054/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
+    "axios": {
+      "version": "0.27.2",
+      "resolved": "https://ddns.mrabit.com:10054/axios/-/axios-0.27.2.tgz",
+      "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
+      "requires": {
+        "follow-redirects": "^1.14.9",
+        "form-data": "^4.0.0"
+      }
+    },
+    "call-bind": {
+      "version": "1.0.2",
+      "resolved": "https://ddns.mrabit.com:10054/call-bind/-/call-bind-1.0.2.tgz",
+      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+      "requires": {
+        "function-bind": "^1.1.1",
+        "get-intrinsic": "^1.0.2"
+      }
+    },
+    "colors": {
+      "version": "1.4.0",
+      "resolved": "https://ddns.mrabit.com:10054/colors/-/colors-1.4.0.tgz",
+      "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="
+    },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://ddns.mrabit.com:10054/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "cron-parser": {
+      "version": "3.5.0",
+      "resolved": "https://ddns.mrabit.com:10054/cron-parser/-/cron-parser-3.5.0.tgz",
+      "integrity": "sha512-wyVZtbRs6qDfFd8ap457w3XVntdvqcwBGxBoTvJQH9KGVKL/fB+h2k3C8AqiVxvUQKN1Ps/Ns46CNViOpVDhfQ==",
+      "requires": {
+        "is-nan": "^1.3.2",
+        "luxon": "^1.26.0"
+      }
+    },
+    "dayjs": {
+      "version": "1.11.2",
+      "resolved": "https://ddns.mrabit.com:10054/dayjs/-/dayjs-1.11.2.tgz",
+      "integrity": "sha512-F4LXf1OeU9hrSYRPTTj/6FbO4HTjPKXvEIC1P2kcnFurViINCVk3ZV0xAS3XVx9MkMsXbbqlK6hjseaYbgKEHw=="
+    },
+    "define-properties": {
+      "version": "1.1.4",
+      "resolved": "https://ddns.mrabit.com:10054/define-properties/-/define-properties-1.1.4.tgz",
+      "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
+      "requires": {
+        "has-property-descriptors": "^1.0.0",
+        "object-keys": "^1.1.1"
+      }
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://ddns.mrabit.com:10054/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
+    },
+    "follow-redirects": {
+      "version": "1.15.1",
+      "resolved": "https://ddns.mrabit.com:10054/follow-redirects/-/follow-redirects-1.15.1.tgz",
+      "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA=="
+    },
+    "form-data": {
+      "version": "4.0.0",
+      "resolved": "https://ddns.mrabit.com:10054/form-data/-/form-data-4.0.0.tgz",
+      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      }
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://ddns.mrabit.com:10054/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+    },
+    "get-intrinsic": {
+      "version": "1.1.1",
+      "resolved": "https://ddns.mrabit.com:10054/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
+      "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
+      "requires": {
+        "function-bind": "^1.1.1",
+        "has": "^1.0.3",
+        "has-symbols": "^1.0.1"
+      }
+    },
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://ddns.mrabit.com:10054/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "requires": {
+        "function-bind": "^1.1.1"
+      }
+    },
+    "has-property-descriptors": {
+      "version": "1.0.0",
+      "resolved": "https://ddns.mrabit.com:10054/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+      "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+      "requires": {
+        "get-intrinsic": "^1.1.1"
+      }
+    },
+    "has-symbols": {
+      "version": "1.0.3",
+      "resolved": "https://ddns.mrabit.com:10054/has-symbols/-/has-symbols-1.0.3.tgz",
+      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
+    },
+    "is-nan": {
+      "version": "1.3.2",
+      "resolved": "https://ddns.mrabit.com:10054/is-nan/-/is-nan-1.3.2.tgz",
+      "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==",
+      "requires": {
+        "call-bind": "^1.0.0",
+        "define-properties": "^1.1.3"
+      }
+    },
+    "long-timeout": {
+      "version": "0.1.1",
+      "resolved": "https://ddns.mrabit.com:10054/long-timeout/-/long-timeout-0.1.1.tgz",
+      "integrity": "sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w=="
+    },
+    "luxon": {
+      "version": "1.28.0",
+      "resolved": "https://ddns.mrabit.com:10054/luxon/-/luxon-1.28.0.tgz",
+      "integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ=="
+    },
+    "mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://ddns.mrabit.com:10054/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
+    },
+    "mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://ddns.mrabit.com:10054/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "requires": {
+        "mime-db": "1.52.0"
+      }
+    },
+    "node-schedule": {
+      "version": "2.1.0",
+      "resolved": "https://ddns.mrabit.com:10054/node-schedule/-/node-schedule-2.1.0.tgz",
+      "integrity": "sha512-nl4JTiZ7ZQDc97MmpTq9BQjYhq7gOtoh7SiPH069gBFBj0PzD8HI7zyFs6rzqL8Y5tTiEEYLxgtbx034YPrbyQ==",
+      "requires": {
+        "cron-parser": "^3.5.0",
+        "long-timeout": "0.1.1",
+        "sorted-array-functions": "^1.3.0"
+      }
+    },
+    "object-keys": {
+      "version": "1.1.1",
+      "resolved": "https://ddns.mrabit.com:10054/object-keys/-/object-keys-1.1.1.tgz",
+      "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
+    },
+    "sorted-array-functions": {
+      "version": "1.3.0",
+      "resolved": "https://ddns.mrabit.com:10054/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz",
+      "integrity": "sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA=="
+    }
+  }
+}

+ 18 - 0
package.json

@@ -0,0 +1,18 @@
+{
+  "name": "xmtravel",
+  "version": "1.0.0",
+  "description": "",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "keywords": [],
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+    "axios": "^0.27.2",
+    "colors": "^1.4.0",
+    "dayjs": "^1.11.2",
+    "node-schedule": "^2.1.0"
+  }
+}

+ 12 - 0
script.json

@@ -0,0 +1,12 @@
+{
+  "name": "xmtravel",
+  "script": "node",
+  "args": "index.js",
+  "cwd": "./",
+  "watch": ["index.js", "config.js"],
+  "ignore_watch": ["node_modules"],
+  "watch_options": {
+    "followSymlinks": false
+  },
+  "autorestart": false
+}