const fs = require('fs'); const crypto = require('crypto'); const crc32 = require('crc-32'); const xlsx = require('node-xlsx'); const parseArgs = require('minimist'); const serverEnv = process.env['SERVER_ENV']; const numberHash = { '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9 }; function rspErr(rsp, errCode, errMsg) { rsp.send(jsonEncode({ 'errcode': errCode, 'errmsg': errMsg })); } function rspOk(rsp) { rsp.send(jsonEncode({ 'errcode': 0, 'errmsg': '' })); } function rspData(rsp, data) { data['errcode'] = 0; data['errmsg'] = ''; rsp.send(jsonEncode(data)); } function readJsonFromFile(url) { const jsondata = fs.readFileSync(url, "utf8"); const json = JSON.parse(jsondata); return json; } async function sleep(timeout) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve(); }, timeout); }); } function emptyReplace(val, newVal) { return !val ? newVal : val; } function throwError(msg) { console.log(msg); throw msg; } function isOnlineEnv() { return !serverEnv; } function getTickCount() { return Math.floor((new Date()).getTime() / 1); } function getUtcTime() { return Math.floor((new Date()).getTime() / 1000); } function getDaySeconds(time, timeZone) { return Math.floor((time + 3600 * timeZone) / 3600 / 24) * 3600 * 24 - 3600 * timeZone; } function getHourSeconds(time, timeZone) { const daySeconds = getDaySeconds(time, timeZone); return Math.floor((time - daySeconds) / 3600) * 3600; } function formatDate(date) { const year = date.getFullYear(); const month = date.getMonth() + 1;//月份是从0开始的 const day = date.getDate(); const hour = date.getHours(); const min = date.getMinutes(); const sec = date.getSeconds(); return year + '-' + (month < 10 ? '0' + month : month) + '-' + (day < 10 ? '0' + day : day) + ' ' + (hour < 10 ? '0' + hour : hour) + ':' + (min < 10 ? '0' + min : min) + ':' + (sec < 10 ? '0' + sec : sec); } function pad(num, n) { let result = num.toString(); let len = result.length; while (len < n) { result = '0' + result; len++; } return result.toString(); } function randRange(min, max) { if (min >= max) { return min; } return min + Math.floor(Math.random() * (max - min)); } function jsonEncode(obj) { return JSON.stringify(obj); } function prettyJsonEncode(obj) { return JSON.stringify(obj, "", " "); } function jsonDecode(jsonStr) { return JSON.parse(String(jsonStr)); } function isArray(val) { return Array.isArray(val); } function isObject(val) { return typeof(obj) == "object"; } function crc32Str(str) { return crc32.str('' + str); } function createAccountId(channel, gameId, openId) { const accountId = `${channel}_${gameId}_${openId}`; return accountId; } function extractChannel(accountId) { const ss = accountId.split('_'); return ss[0]; } function extractGameId(accountId) { const ss = accountId.split('_'); return ss[1]; } function extractOpenId(accountId) { const channel = extractChannel(accountId); const gameId = extractGameId(accountId); const openId = accountId.substr(accountId.indexOf(`${channel}_${gameId}_`)); return openId; } function extractRegisterTime(accountId, sessionId) { if (!sessionId) { return 0; } const ss = sessionId.split('_'); if (ss.length < 4){ return 0; } return ss[1]; } function createSessionId(accountId, registerTime, secretKey) { const nowTime = getUtcTime(); const rand = randRange(1, 1000000000); const sessionId = '' + nowTime + '_' + registerTime + '_' + rand + '_' + md5Str('' + accountId + secretKey + registerTime + nowTime); return sessionId; } function isValidSessionId(accountId, sessionId, secretKey) { if (!sessionId) { return false; } const ss = sessionId.split('_'); if (ss.length < 4){ return false; } const sessionCreateTime = ss[0]; const accountRegisterTime = ss[1]; const md5Str1 = ss[2]; const md5Str2 = ss[3]; const md5Tmp = md5Str('' + accountId + secretKey + accountRegisterTime + sessionCreateTime); return md5Tmp == md5Str2; } function md5Str(data) { const hash = crypto.createHash('md5'); return hash.update(data).digest('hex'); } function getVal(obj, key, defVal = null) { if (!obj){ return val; } return key in obj ? obj[key] : defVal; } async function excelToJson(fileName, nameIdx, dataIdx) { const sheetData = []; const sheetList = xlsx.parse(fileName); sheetList.forEach((sheet) => { for (let i = dataIdx; i < sheet.data.length; ++i) { const obj = {}; for (let ii = 0; ii < sheet.data[nameIdx].length; ++ii) { obj[sheet.data[nameIdx][ii]] = sheet.data[i][ii]; } if (!sheetData[sheet.name]) { sheetData[sheet.name] = []; } sheetData[sheet.name].push(obj); } }); return sheetData; } function getArgv(name, def = null) { const argv = parseArgs(process.argv.slice(2), opts = { string: [name] }); return argv[name] ? argv[name] : def; } function hasKey(obj, key) { return obj.hasOwnProperty(key); } function isPureNumberStr(str) { for (let i = 0; i < str.length; ++i){ const c = str[i]; if (!hasKey(numberHash, c)) { return false; } } return true; } function randItemByWeight(list, fieldName) { const ret = { 'index': -1, 'item': null }; let totalSpace = function () { let space = 0; list.forEach((item) => { space += Number(item[fieldName]); }); return space; }(); if (totalSpace > 0) { const rand = randRange(0, totalSpace - 1); let currSpace = 0; for (let i = 0; i < list.length; ++i) { currSpace += Number(list[i][fieldName]); //console.log(currSpace, rand, totalSpace, list); if (rand < currSpace) { ret['index'] = i; ret['item'] = list[i]; break; } } } else { console.log('randItemByWeight error:', list); } return ret; } function mapToArray(mapObj) { const result = []; mapObj.forEach((val, key) => { result.push(val); }); return result; } function mapToObject(mapObj) { const result = {}; mapObj.forEach((val, key) => { result[key] = val; }); return result; } function arrayToStrings(arr) { for (let i = 0; i < arr.length; ++i) { arr[i] = arr[i].toString(); } } async function serial(obj, cb) { let i = 0; const arr = obj instanceof Map ? mapToArray(obj) : obj; for (let val of arr) { await cb(val, i++); } } function removeLeadZero(data) { const dataStr = data.toString(); for (let i = 0; i < dataStr.length; ++i) { if (dataStr[i] != '0') { return dataStr.substr(i); } } return dataStr; } exports.rspErr = rspErr; exports.rspOk = rspOk; exports.rspData = rspData; exports.readJsonFromFile = readJsonFromFile; exports.sleep = sleep; exports.emptyReplace = emptyReplace; exports.throwError = throwError; exports.isOnlineEnv = isOnlineEnv; exports.getTickCount = getTickCount; exports.getUtcTime = getUtcTime; exports.getDaySeconds = getDaySeconds; exports.getHourSeconds = getHourSeconds; exports.formatDate = formatDate; exports.pad = pad; exports.randRange = randRange; exports.randItemByWeight = randItemByWeight; exports.jsonEncode = jsonEncode; exports.prettyJsonEncode = prettyJsonEncode; exports.jsonDecode = jsonDecode; exports.isArray = isArray; exports.isObject = isObject; exports.crc32Str = crc32Str; exports.createAccountId = createAccountId; exports.extractChannel = extractChannel; exports.extractGameId = extractGameId; exports.extractOpenId = extractOpenId; exports.extractRegisterTime = extractRegisterTime; exports.createSessionId = createSessionId; exports.isValidSessionId = isValidSessionId; exports.md5Str = md5Str; exports.getVal = getVal; exports.excelToJson = excelToJson; exports.getArgv = getArgv; exports.hasKey = hasKey; exports.isPureNumberStr = isPureNumberStr; exports.serial = serial; exports.mapToArray = mapToArray; exports.mapToObject = mapToObject; exports.arrayToStrings = arrayToStrings; exports.removeLeadZero = removeLeadZero;