415 lines
9.3 KiB
JavaScript
415 lines
9.3 KiB
JavaScript
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 compactFormatDate(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 sha1Str(data) {
|
|
const hash = crypto.createHash('sha1');
|
|
return hash.update(data).digest('hex').toLowerCase();
|
|
}
|
|
|
|
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 0;
|
|
}
|
|
|
|
function safeDumpErrStack(err) {
|
|
if (err && err.stack) {
|
|
console.log(err.stack);
|
|
} else {
|
|
console.log('safeDumpErrStack: no stack');
|
|
}
|
|
}
|
|
|
|
function normalMd5UrlSign(params, $secretKey) {
|
|
const sortedKeys = Object.keys(params).sort();
|
|
const connStr = '&';
|
|
let paramsStr = '';
|
|
sortedKeys.forEach
|
|
(
|
|
(key) => {
|
|
paramsStr += '' + key + '=' + params[key] + connStr;
|
|
}
|
|
);
|
|
return md5Str(paramsStr + $secretKey);
|
|
}
|
|
|
|
function genUuid() {
|
|
return crypto.randomUUID();
|
|
}
|
|
|
|
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.compactFormatDate = compactFormatDate;
|
|
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.sha1Str = sha1Str;
|
|
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;
|
|
exports.safeDumpErrStack = safeDumpErrStack;
|
|
exports.normalMd5UrlSign = normalMd5UrlSign;
|
|
exports.genUuid = genUuid;
|