qqwryUpdate.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. require('stream.pipeline-shim/auto');
  2. const zlib = require('zlib');
  3. const util = require('util');
  4. const fs = require('fs');
  5. const stream = require('stream');
  6. const axios = require('axios');
  7. const GBK = require('gbk.js');
  8. const pipeline = util.promisify(stream.pipeline);
  9. const ProgressBar = require('progress');
  10. const urls = {
  11. copywrite: 'http://update.cz88.net/ip/copywrite.rar',
  12. qqwry: 'http://update.cz88.net/ip/qqwry.rar'
  13. };
  14. class QqwryDecode extends stream.Transform {
  15. constructor(key, options) {
  16. super(options);
  17. this._key = key;
  18. this._writeN = 0x200;
  19. }
  20. _transform(chunk, encoding, callback) {
  21. if (this._writeN <= 0) return callback(null, chunk);
  22. let max = this._writeN > chunk.length ? chunk.length : this._writeN;
  23. let key = this._key;
  24. this._writeN -= max;
  25. for (let i = 0; i < max; i++) {
  26. key *= 0x805;
  27. key++;
  28. key &= 0xff;
  29. chunk[i] = chunk[i] ^ key;
  30. }
  31. this._key = key;
  32. return callback(null, chunk);
  33. }
  34. _flush(cb) {
  35. cb();
  36. }
  37. }
  38. // async function getURLFile(url, resType = 'arraybuffer') {
  39. async function getURLFile(url, showProgressBar = false) {
  40. return axios
  41. .get(url, {
  42. responseType: 'stream',
  43. // 适应qqwry新规则
  44. headers: {
  45. 'User-Agent': 'Mozilla/3.0 (compatible; Indy Library)'
  46. }
  47. })
  48. .then(res => {
  49. if (showProgressBar) {
  50. let bar = new ProgressBar(
  51. 'downloading [:bar]:percent :rate/bps :etas',
  52. {
  53. complete: '=',
  54. incomplete: ' ',
  55. width: 20,
  56. total: +res.headers['content-length']
  57. }
  58. );
  59. res.data.on('data', function(buffer) {
  60. bar.tick(buffer.length);
  61. });
  62. }
  63. return res.data;
  64. });
  65. }
  66. let get_copywrite = showBar => getURLFile(urls.copywrite, showBar);
  67. let get_qqwry = showBar => getURLFile(urls.qqwry, showBar);
  68. async function getLastInfo() {
  69. let copywrite = await get_copywrite();
  70. copywrite.read(20);
  71. let key = copywrite.read(4).readUIntLE(0, 4);
  72. let version = GBK.decode(copywrite.read(128)).replace(/\0/g, '');
  73. return {
  74. version,
  75. key
  76. };
  77. }
  78. async function update(dataPath, key) {
  79. if (!key) {
  80. key = (await getLastInfo()).key;
  81. }
  82. let _temPath = dataPath + '.tmp';
  83. return pipeline(
  84. await get_qqwry(true),
  85. new QqwryDecode(key),
  86. zlib.createInflate(),
  87. fs.createWriteStream(_temPath)
  88. ).then(() => {
  89. fs.renameSync(_temPath, dataPath);
  90. });
  91. }
  92. exports.getLastInfo = getLastInfo;
  93. exports.update = update;
  94. exports.QqwryDecode = QqwryDecode;