getAccount.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import Logs from "./logs.js";
  2. import { getData, setData } from "./cache.js";
  3. import { findCurrencyInfo } from "./globalData.js";
  4. const accountOptionCacheFile = 'data/accountOptionCache.json';
  5. const ACCOUNT_OPTIONS = {
  6. currentIndex: 0,
  7. nextChangeTime: 0,
  8. };
  9. const IS_DEV = process.env.NODE_ENV == 'development';
  10. /**
  11. * 随机一个毫秒数
  12. * 范围:4小时 ~ 7小时
  13. * 测试环境范围:4分钟 ~ 7分钟
  14. * 加上当前时间戳
  15. * 计算下次切换时间
  16. */
  17. const getRandomTime = () => {
  18. const nowTime = Date.now();
  19. const min = 1000 * 60 * (IS_DEV ? 1 : 60) * 4;
  20. const max = 1000 * 60 * (IS_DEV ? 1 : 60) * 7;
  21. const randomTime = Math.floor(Math.random() * (max - min + 1)) + min;
  22. return nowTime + randomTime;
  23. }
  24. /**
  25. * 缓存GLOBAL_DATA数据到文件
  26. * @returns {Promise<void>}
  27. */
  28. const saveGlobalDataToCache = async () => {
  29. return setData(accountOptionCacheFile, ACCOUNT_OPTIONS);
  30. }
  31. /**
  32. * 从文件中加载GLOBAL_DATA数据
  33. * @returns {Promise<void>}
  34. */
  35. const loadGlobalDataFromCache = async () => {
  36. return getData(accountOptionCacheFile)
  37. .then(data => {
  38. if (!data) {
  39. return;
  40. }
  41. Object.keys(ACCOUNT_OPTIONS)?.forEach(key => {
  42. if (key in data) {
  43. ACCOUNT_OPTIONS[key] = data[key];
  44. }
  45. });
  46. });
  47. }
  48. /**
  49. * 获取当前账号信息
  50. * @returns
  51. */
  52. export const getAccountInfo = () => {
  53. const nowTime = Date.now();
  54. const accounts = process.env.PINNACLE_ACCOUNTS?.split(',').map(item => {
  55. const [username, password, localAddress, platform, currency='USD'] = item.split(':');
  56. return {
  57. username,
  58. password,
  59. localAddress,
  60. platform,
  61. currency,
  62. currencyInfo: findCurrencyInfo(currency),
  63. };
  64. }) ?? [];
  65. if (accounts.length == 0) {
  66. return null;
  67. }
  68. let isAccountChanged = false;
  69. if (ACCOUNT_OPTIONS.nextChangeTime == 0) {
  70. ACCOUNT_OPTIONS.currentIndex = 0;
  71. ACCOUNT_OPTIONS.nextChangeTime = getRandomTime();
  72. }
  73. else if (nowTime > ACCOUNT_OPTIONS.nextChangeTime) {
  74. ACCOUNT_OPTIONS.currentIndex++;
  75. if (ACCOUNT_OPTIONS.currentIndex >= accounts.length) {
  76. ACCOUNT_OPTIONS.currentIndex = 0;
  77. }
  78. ACCOUNT_OPTIONS.nextChangeTime = getRandomTime();
  79. isAccountChanged = true;
  80. saveGlobalDataToCache();
  81. }
  82. const accountInfo = accounts[ACCOUNT_OPTIONS.currentIndex];
  83. if (isAccountChanged) {
  84. const { password, ...accountInfoRest } = accountInfo;
  85. Logs.out('account changed', ACCOUNT_OPTIONS, accountInfoRest);
  86. }
  87. return accountInfo;
  88. }
  89. /**
  90. * 监听进程退出事件
  91. * 保存GLOBAL_DATA数据
  92. */
  93. const saveExit = (code) => {
  94. saveGlobalDataToCache()
  95. .then(() => {
  96. Logs.out('account options saved');
  97. })
  98. .catch(err => {
  99. Logs.err('failed to save account options', err.message);
  100. })
  101. .finally(() => {
  102. process.exit(code);
  103. });
  104. }
  105. process.on('SIGINT', () => {
  106. saveExit(0);
  107. });
  108. process.on('SIGTERM', () => {
  109. saveExit(0);
  110. });
  111. process.on('SIGUSR2', () => {
  112. saveExit(0);
  113. });
  114. loadGlobalDataFromCache();