679 lines
20 KiB
TypeScript
679 lines
20 KiB
TypeScript
import { STATUS } from './../consts/statusCode';
|
||
|
||
import { HeroModel, HeroType } from '../db/Hero';
|
||
|
||
const csprng = require('csprng');
|
||
import fs = require('fs');
|
||
import path = require('path');
|
||
import { HERO_CE_RATIO, ABI_STAGE, GACHA_TO_FLOOR, REFRESH_TIME, ROBOT_SYS_TYPE, } from '../consts';
|
||
|
||
import { findIndex } from 'underscore';
|
||
import { getTimeFunM } from './timeUtil';
|
||
import { Floor } from '../domain/activityField/gachaField';
|
||
import { WhiteListModel } from '../db/WhiteList';
|
||
import { UserModel } from '../db/User';
|
||
const randomName = require("chinese-random-name");
|
||
const moment = require('moment');
|
||
const crypto = require('crypto');
|
||
|
||
export function aesEncrypt(data, key, iv) {
|
||
const cipher = crypto.createCipheriv('aes-192-cbc', key, iv);
|
||
let crypted = cipher.update(data, 'utf8', 'hex');
|
||
crypted += cipher.final('hex');
|
||
return crypted;
|
||
}
|
||
|
||
export function aesDecrypt(data, key, iv) {
|
||
const decipher = crypto.createDecipheriv('aes-192-cbc', key, iv);
|
||
let decrypted = decipher.update(data, 'hex', 'utf8');
|
||
decrypted += decipher.final('utf8');
|
||
return decrypted;
|
||
}
|
||
|
||
export function aesEncryptcfb(data, key, iv) {
|
||
const cipher = crypto.createCipheriv('aes-192-cfb', key, iv);
|
||
let crypted = cipher.update(data, 'utf8', 'hex');
|
||
crypted += cipher.final('hex');
|
||
// console.log('****aesEncryptcfb', data, crypted)
|
||
return crypted;
|
||
}
|
||
|
||
export function aesDecryptcfb(data, key, iv) {
|
||
if (data) {
|
||
const decipher = crypto.createDecipheriv('aes-192-cfb', key, iv);
|
||
let decrypted = decipher.update(data, 'hex', 'utf8');
|
||
decrypted += decipher.final('utf8');
|
||
return decrypted;
|
||
} else {
|
||
return ''
|
||
}
|
||
}
|
||
|
||
export function genCode(len) {
|
||
const chars = '123456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijklmnopqrstuvwxyz';
|
||
const charArr = chars.split('');
|
||
let code = '';
|
||
for (let i = 0; i < len; i++) {
|
||
code += charArr[Math.floor(Math.random() * charArr.length)];
|
||
}
|
||
return code;
|
||
}
|
||
|
||
/**
|
||
* 生成 len 长度的随机字符串
|
||
* @param len 长度
|
||
* @param radix 基数
|
||
*/
|
||
export function generateStr(len: number, radix = 36) {
|
||
return `${csprng(len, radix)}`;
|
||
}
|
||
|
||
export function generateNum(len: number) {
|
||
let code = '';
|
||
for (let i = 0; i < len; i++) {
|
||
code += parseInt(`${Math.random() * 10}`);
|
||
}
|
||
return code;
|
||
}
|
||
|
||
/**
|
||
* 将 | 分隔的字符串解析为数组,如:a|b|c 解析为[a, b, c]
|
||
* @param str 要解析的字符串
|
||
*/
|
||
export function decodeArrayStr(str: string, splitForm = '|') {
|
||
let last = str.substr(str.length - 1, 1);
|
||
if (last == '&') str = str.substr(0, str.length - 1);
|
||
if (str == '') {
|
||
return new Array<string>()
|
||
} else {
|
||
return str.split(splitForm);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 将 | 和 & 分隔的字符串解析为 Map,,如:a&b&c|c&d&f 解析为 [[a,b,c], [c,d,f]]
|
||
* @param str 要解析的字符串
|
||
*/
|
||
export function decodeArrayListStr(str: string) {
|
||
return decodeArrayStr(str).map(cur => decodeArrayStr(cur, '&'));
|
||
}
|
||
|
||
/**
|
||
* 将 | 和 & 分隔的字符串解析为 Map,,如:a&b|c&d|e&f 解析为 Map {a=>b, c=>d, e=>f}
|
||
* @param str 要解析的字符串
|
||
*/
|
||
export function decodeIdCntArrayStr(str: string, multi: number) {
|
||
const strArr = decodeArrayStr(str);
|
||
// console.log('decodeIdCntArrayStr: ', strArr);
|
||
const strMap = new Map<string, number>();
|
||
strArr.forEach(item => {
|
||
const kv = item.split('&');
|
||
strMap.set(kv[0], multi ? Math.ceil(parseInt(kv[1]) * multi) : parseInt(kv[1]));
|
||
});
|
||
return strMap;
|
||
}
|
||
|
||
// 计算当前武将战力
|
||
export async function calculateSumCE(roleId: string, type: number, param: { num?: number, heroes?: Array<number> }) {
|
||
let sum: number;
|
||
if (type == 1) { // 最高num人历史最高战力和
|
||
sum = await HeroModel.sumTopHeroCe(roleId, param.num || 0);
|
||
} else if (type == 2) { // 所有人战力和
|
||
sum = await HeroModel.sumHeroCe(roleId);
|
||
}
|
||
sum = reduceCe(sum);
|
||
return sum;
|
||
}
|
||
|
||
/**
|
||
* 传入两个时间,返回按照时间差计算,第二个时间比第一个晚几天
|
||
* @param preTime 之前的时间
|
||
* @param proTime 之后的时间
|
||
*/
|
||
export function deltaDays(preTime: Date, proTime: Date): number {
|
||
return moment(proTime).diff(moment(preTime), "days");
|
||
}
|
||
|
||
/**
|
||
* 计算按照每 x 天 y 点刷新一次,是否应该刷新
|
||
* @param preTime 基准时间
|
||
* @param curTime 当前时间
|
||
* @param hour 几点刷新
|
||
* @param deltaDay 间隔几天刷新,默认每天刷新(deltaDay = 1)
|
||
*/
|
||
export function shouldRefresh(preTime: Date, now: Date, hour: number = REFRESH_TIME, deltaDay = 1): boolean {
|
||
if (!preTime) return true;
|
||
let curTime = new Date(now.getTime());
|
||
let refreshTime = new Date(now.getTime());
|
||
refreshTime.setHours(hour, 0, 0, 0);
|
||
let refeshTime = refreshTime.getTime();
|
||
|
||
if (refeshTime - preTime.getTime() > (deltaDay >= 1 ? deltaDay - 1 : 0) * 24 * 60 * 60 * 1000 && curTime.getTime() >= refeshTime) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 计算按照每 x 天 y 点刷新一次,是否应该刷新
|
||
* @param preTime 基准时间
|
||
* @param curTime 当前时间
|
||
* @param day 周几刷新
|
||
* @param hour 几点刷新
|
||
* @param deltaDay 间隔几天刷新,默认每天刷新(deltaDay = 1)
|
||
*/
|
||
export function shouldRefreshWeek(preTime: Date, now: Date, day: number = 1, hour: number = REFRESH_TIME, deltaWeek = 1): boolean {
|
||
if (!preTime) return true;
|
||
let curTime = new Date(now.getTime());
|
||
let refreshTime = <number>getTimeFunM(now).getTimeWithWeek(day, hour);
|
||
|
||
if (refreshTime - preTime.getTime() > (deltaWeek >= 1 ? deltaWeek - 1 : 0) * 7 * 24 * 60 * 60 * 1000 && curTime.getTime() >= refreshTime) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 从一个数组中随机返回不重复的 cnt 个元素数组
|
||
* @param source 原数组
|
||
* @param cnt 返回随机元素个数
|
||
*/
|
||
export function getRandEelm<T>(source: Array<T> = [], cnt = 1): Array<T> {
|
||
if (cnt == 0) return [];
|
||
if (cnt >= source.length) return source;
|
||
let idxs = new Set();
|
||
|
||
while (1) {
|
||
let rand = Math.floor(Math.random() * source.length);
|
||
idxs.add(rand);
|
||
if (idxs.size >= cnt) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
return source.filter((_item, idx) => idxs.has(idx));
|
||
}
|
||
|
||
/**
|
||
* 从一个数组中随机返回1元素
|
||
* @param source
|
||
*/
|
||
export function getRandSingleEelm<T>(source: Array<T>): T {
|
||
let len = source.length;
|
||
return source[Math.floor(Math.random() * len)]
|
||
}
|
||
|
||
/**
|
||
* 随机数组中一个index
|
||
* @param len
|
||
*/
|
||
export function getRandSingleIndex(len: number) {
|
||
return Math.floor(Math.random() * len);
|
||
}
|
||
|
||
/**
|
||
* 从一个数组根据权重随机一个元素
|
||
* @param randomList
|
||
*/
|
||
export function getRandEelmWithWeight<T extends { weight: number }>(randomList: T[]): { dic: T, index: number } {
|
||
let len = randomList.reduce((pre, cur) => {
|
||
return pre + cur.weight || 1;
|
||
}, 0);
|
||
let index = Math.floor(Math.random() * len);
|
||
let result = { dic: null, index: -1 };
|
||
for (let i = 0; i < randomList.length; i++) {
|
||
let { weight = 0 } = randomList[i];
|
||
if (index < weight) {
|
||
result.dic = randomList[i];
|
||
result.index = i;
|
||
break;
|
||
}
|
||
index -= weight;
|
||
}
|
||
return result
|
||
}
|
||
|
||
/**
|
||
* 不改变原数组长度,将内部元素打乱
|
||
* @param source
|
||
*/
|
||
export function sortArrRandom(source = []) {
|
||
let arr = deepCopy(source);
|
||
return arr.sort(() => { return Math.random() - 0.5; });
|
||
}
|
||
|
||
/**
|
||
* 在给定数值的浮动范围中随机一个值
|
||
* @param base 基础数值
|
||
* @param ratio 随机范围:base 值上下浮动 ratio(小于 1 的整数)
|
||
* @param decimal 返回值保留的小数位数
|
||
*/
|
||
export function getRandValue(base: number, ratio: number, decimal = 2): number {
|
||
return parseFloat((base * (1 - ratio + Math.random() * ratio * 2)).toFixed(decimal));
|
||
}
|
||
|
||
|
||
/**
|
||
* 在给定最大最小值中随机一个值
|
||
* @param min 最小
|
||
* @param max 最大
|
||
* @param decimal 返回值保留的小数位数
|
||
*/
|
||
export function getRandValueByMinMax(min: number, max: number, decimal = 2): number {
|
||
let pow = Math.pow(10, decimal);
|
||
return Math.floor((min + (max - min) * Math.random()) * pow)/pow;
|
||
|
||
}
|
||
|
||
export function resResult<T>(status: { code: number, simStr: string }, data: T = <T>{}, customMsg = ''): { code: number, msg: string, data: T } {
|
||
const { code, simStr } = status;
|
||
if (code !== STATUS.SUCCESS.code) {
|
||
console.log(`normal err, code: ${code}, des: ${customMsg || simStr}`);
|
||
}
|
||
return { code, msg: customMsg || simStr, data };
|
||
}
|
||
|
||
export function getResStr(status: { code: number, simStr: string }) {
|
||
return status.simStr;
|
||
}
|
||
|
||
// 消除 js 浮点计算bug
|
||
|
||
export const cal = {
|
||
add: function (a: number, b: number) {
|
||
var c: number, d: number, e: number;
|
||
try {
|
||
c = a.toString().split(".")[1].length;
|
||
} catch (f) {
|
||
c = 0;
|
||
}
|
||
try {
|
||
d = b.toString().split(".")[1].length;
|
||
} catch (f) {
|
||
d = 0;
|
||
}
|
||
e = Math.pow(10, Math.max(c, d));
|
||
return (this.mul(a, e) + this.mul(b, e)) / e;
|
||
},
|
||
sub: function sub(a: number, b: number) {
|
||
var c: number, d: number, e: number;
|
||
try {
|
||
c = a.toString().split(".")[1].length;
|
||
} catch (f) {
|
||
c = 0;
|
||
}
|
||
try {
|
||
d = b.toString().split(".")[1].length;
|
||
} catch (f) {
|
||
d = 0;
|
||
}
|
||
e = Math.pow(10, Math.max(c, d));
|
||
return (this.mul(a, e) - this.mul(b, e)) / e;
|
||
},
|
||
mul: function mul(a: number, b: number) {
|
||
var c = 0,
|
||
d = a.toString(),
|
||
e = b.toString();
|
||
try {
|
||
c += d.split(".")[1].length;
|
||
} catch (f) { }
|
||
try {
|
||
c += e.split(".")[1].length;
|
||
} catch (f) { }
|
||
return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
|
||
},
|
||
div: function div(a: number, b: number) {
|
||
var c: number, d: number, e = 0,
|
||
f = 0;
|
||
try {
|
||
e = a.toString().split(".")[1].length;
|
||
} catch (g) { }
|
||
try {
|
||
f = b.toString().split(".")[1].length;
|
||
} catch (g) { }
|
||
c = Number(a.toString().replace(".", ""));
|
||
d = Number(b.toString().replace(".", ""));
|
||
return this.mul(c / d, Math.pow(10, f - e));
|
||
}
|
||
};
|
||
|
||
//计算公式
|
||
// export function calculateNum(ratio: { A: number, B: number }, params: { num: number }, defaultVal = 0) {
|
||
// // result = a * num + b
|
||
// try {
|
||
// let { A, B } = ratio;
|
||
// let { num } = params;
|
||
// let result = A * num + B;
|
||
// if (isNaN(result)) {
|
||
// console.error('calculate wrong: ', A, B, num)
|
||
// return defaultVal;
|
||
// } else {
|
||
// return result;
|
||
// }
|
||
// } catch (e) {
|
||
// console.error(e);
|
||
// return defaultVal;
|
||
// }
|
||
// }
|
||
|
||
export function ratioReward(reward: {id: number, count: number}[], ratio: number): {id: number, count: number}[] {
|
||
return reward.map(cur => {
|
||
return {id: cur.id, count: cur.count * ratio}
|
||
});
|
||
}
|
||
|
||
export function getItems(str: string) {
|
||
let arr = new Array<{ id: number, count: number }>();
|
||
let strArr = str.split('|');
|
||
for (let item of strArr) {
|
||
var itemArr = item.split('&');
|
||
arr.push({
|
||
id: parseInt(itemArr[0]),
|
||
count: parseInt(itemArr[1])
|
||
});
|
||
}
|
||
return arr;
|
||
}
|
||
|
||
export function deepCopy(obj) {
|
||
if (typeof obj !== 'object' || obj === null) {
|
||
return obj;
|
||
}
|
||
var target;
|
||
if (obj instanceof Array) {
|
||
target = [];
|
||
obj.forEach(element => {
|
||
target.push(deepCopy(element));
|
||
});
|
||
} else {
|
||
target = {};
|
||
for (const key in obj) {
|
||
if (obj.hasOwnProperty(key)) {
|
||
const element = obj[key];
|
||
if (!!element || element == 0) {
|
||
target[key] = deepCopy(element);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return target;
|
||
};
|
||
|
||
export function readFile(addr: string) {
|
||
return fs.readFileSync(path.resolve(__dirname, `${addr}`)).toString('utf8').replace(/^\uFEFF/, '');
|
||
}
|
||
|
||
export function writeFile(addr: string, data: string) {
|
||
return fs.writeFileSync(addr, data);
|
||
}
|
||
|
||
export function readFileAndParseJson(path: string) {
|
||
try {
|
||
let readResult = readFile(path);
|
||
return JSON.parse(readResult);
|
||
} catch(e) {
|
||
throw new Error(`connectors.json 格式错误:${(<Error>e).message}`);
|
||
}
|
||
}
|
||
|
||
export function readJsonFile(fileName: string) {
|
||
const folder = 'jsons';
|
||
return fs.readFileSync(path.resolve(__dirname, `../resource/${folder}/${fileName}.json`)).toString('utf8').replace(/^\uFEFF/, '');
|
||
}
|
||
|
||
export function readWarJsonFileList() {
|
||
const folder = 'warJsons';
|
||
return fs.readdirSync(__dirname + `/../resource/${folder}`)
|
||
.filter(cur => { return cur.indexOf('.') != 0 })
|
||
.map(file => {
|
||
return {
|
||
name: file,
|
||
str: fs.readFileSync(path.resolve(__dirname, `../resource/${folder}/${file}`)).toString('utf8')
|
||
}
|
||
});
|
||
}
|
||
|
||
export function readWordTxt(fileName: string) {
|
||
try {
|
||
let file = fs.readFileSync(path.resolve(__dirname, `../resource/${fileName}.txt`)).toString('utf8').replace(/^\uFEFF/, '');
|
||
return file;
|
||
} catch(e) {
|
||
console.log(e)
|
||
return null
|
||
}
|
||
}
|
||
|
||
export function writeWordTxt(fileName: string, words: string) {
|
||
try {
|
||
let file = fs.writeFileSync(path.resolve(__dirname, `../resource/${fileName}.txt`), words);
|
||
return file;
|
||
} catch(e) {
|
||
return null
|
||
}
|
||
}
|
||
|
||
export function readTsFile(fileName: string) {
|
||
try {
|
||
let file = fs.readFileSync(path.resolve(__dirname, `../pubUtils/${fileName}.js`)).toString('utf8').replace(/^\uFEFF/, '');
|
||
return file;
|
||
} catch(e) {
|
||
return null
|
||
}
|
||
}
|
||
|
||
export function readFileAndParse(fileName: string) {
|
||
try {
|
||
let readResult = readJsonFile(fileName);
|
||
return JSON.parse(readResult);
|
||
} catch(e) {
|
||
throw new Error(`${fileName}格式错误:${(<Error>e).message}`);
|
||
}
|
||
}
|
||
|
||
export function readWarJsonFileAndParse() {
|
||
let warJsons = readWarJsonFileList();
|
||
let result = [];
|
||
for(let { name, str } of warJsons) {
|
||
try {
|
||
let json = JSON.parse(str);
|
||
result.push(json);
|
||
} catch(e) {
|
||
throw new Error(`${name}格式错误:${(<Error>e).message}`);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
// 字典表常用解析方法
|
||
// 解析物品 {"id": number, "count": number} 格式
|
||
export function parseGoodStr(str: string) {
|
||
let result = new Array<{ id: number, count: number }>();
|
||
if (!str) return result;
|
||
let decodeArr = decodeArrayListStr(str);
|
||
for (let [id, count] of decodeArr) {
|
||
if (isNaN(parseInt(id)) || isNaN(parseInt(count))) {
|
||
throw new Error('data table format wrong');
|
||
}
|
||
result.push({ id: parseInt(id), count: parseInt(count) });
|
||
}
|
||
return result
|
||
}
|
||
// 根据类型解析物品 {"type":number, "id": number, "count": number} 格式
|
||
//type 1.英雄,2.物品
|
||
export function parseGoodStrWithType(str: string) {
|
||
let result = new Array<{ type: number, id: number, count: number }>();
|
||
if (!str) return result;
|
||
let decodeArr = decodeArrayListStr(str);
|
||
for (let [type, id, count] of decodeArr) {
|
||
if (isNaN(parseInt(type)) || isNaN(parseInt(id)) || isNaN(parseInt(count))) {
|
||
throw new Error('data table format wrong');
|
||
}
|
||
result.push({ type: parseInt(type), id: parseInt(id), count: parseInt(count) });
|
||
}
|
||
return result
|
||
}
|
||
|
||
// 根据类型解析物品 {"type":number, "hid": number, "count": number} 格式
|
||
//type 1.英雄,2.物品
|
||
export function parseHeroStrWithType(str: string) {
|
||
let result = new Array<{ type: number, hid: number, count: number }>();
|
||
if (!str) return result;
|
||
let decodeArr = decodeArrayListStr(str);
|
||
for (let [type, hid, count] of decodeArr) {
|
||
if (isNaN(parseInt(type)) || isNaN(parseInt(hid)) || isNaN(parseInt(count))) {
|
||
throw new Error('data table format wrong');
|
||
}
|
||
result.push({ type: parseInt(type), hid: parseInt(hid), count: parseInt(count) });
|
||
}
|
||
return result
|
||
}
|
||
|
||
// 根据类型解析物品 {"type":number, "id": number, "count": number} 格式
|
||
//type 1.英雄,2.物品, 3.RMB
|
||
export function parseResStr(str: string) {
|
||
let result = new Array<{ type: number, id: number, count: number }>();
|
||
if (!str) return result;
|
||
let decodeArr = decodeArrayListStr(str);
|
||
for (let [type, id, count] of decodeArr) {
|
||
if (isNaN(parseInt(type)) || isNaN(parseInt(id)) || isNaN(parseInt(count))) {
|
||
throw new Error('data table format wrong');
|
||
}
|
||
result.push({ type: parseInt(type), id: parseInt(id), count: parseInt(count) });
|
||
}
|
||
return result
|
||
}
|
||
|
||
// 数字列表
|
||
export function parseNumberList(str: string) {
|
||
let res = new Array<number>();
|
||
if (!str) return res;
|
||
let arr = decodeArrayStr(str, '&');
|
||
for (let g of arr) {
|
||
if (g === "") continue;
|
||
res.push(parseFloat(g));
|
||
}
|
||
return res;
|
||
}
|
||
|
||
export function mergeSameGoods(goods: Array<{ id: number, count: number }>) {
|
||
let resGoods = [];
|
||
for (let { id, count } of goods) {
|
||
let index = findIndex(resGoods, { id });
|
||
if (index > -1) {
|
||
resGoods[index].count += count;
|
||
} else {
|
||
resGoods.push({ id, count });
|
||
}
|
||
}
|
||
return resGoods;
|
||
}
|
||
|
||
export function returnHeroCeRatio(hero: HeroType) {
|
||
let ce = reduceCe(hero.ce);
|
||
return Object.assign(hero, { ce });
|
||
}
|
||
|
||
// 缩小战力
|
||
export function reduceCe(ce: number = 0) {
|
||
return Math.floor(ce / HERO_CE_RATIO / HERO_CE_RATIO)
|
||
}
|
||
|
||
|
||
// 获取全部属性
|
||
export function getAllAttrStage() {
|
||
let attrs = new Array<number>(); // 有升级的属性 1-hp 2-atk 3-def 4-mdef 5-agi 6-luk
|
||
for (let stage = ABI_STAGE.START + 1; stage <= ABI_STAGE.END; stage++) {
|
||
attrs.push(stage)
|
||
};
|
||
return attrs;
|
||
}
|
||
|
||
export function getChineseName() {
|
||
return randomName.generate()
|
||
}
|
||
|
||
export function getRobotInfo(sysType?: ROBOT_SYS_TYPE) {
|
||
return {
|
||
robotRoleName: getChineseName(),
|
||
robotRoleId: makeRobotId(genCode(8), sysType),
|
||
}
|
||
}
|
||
|
||
// 根据roleId判断是不是机器人
|
||
export function checkRoleIsRobot(roleId: string) {
|
||
return !!roleId.match(/_r/);
|
||
}
|
||
|
||
// 将一般的roleId转为带_r的
|
||
export function makeRobotId(roleId: string, sysType?: ROBOT_SYS_TYPE) {
|
||
if(sysType) {
|
||
return `${sysType}|${roleId}_r`;
|
||
} else {
|
||
return `${roleId}_r`;
|
||
}
|
||
}
|
||
// 获取来源系统
|
||
export function getRobotSysType(roleId: string) {
|
||
let type = roleId.split('|')[0];
|
||
if(isNaN(parseInt(type))) {
|
||
return 0
|
||
} else {
|
||
return parseInt(type);
|
||
}
|
||
|
||
}
|
||
|
||
// 将一般的roleId去掉_r
|
||
export function robotIdComBack(robotRoleId: string) {
|
||
return robotRoleId.replace(/_r/, '')
|
||
}
|
||
|
||
export function splitString(dataString: string, key: string) {
|
||
if (!dataString) {
|
||
return [];
|
||
}
|
||
let array = dataString.split(key).filter(obj => { return obj && obj != '' });
|
||
let numberArray = [];
|
||
for (let num of array) {
|
||
numberArray.push(Number(num));
|
||
}
|
||
return numberArray;
|
||
}
|
||
|
||
|
||
/**
|
||
* @description 获取抽卡保底状态
|
||
* @param gachaId 招募类型
|
||
* @param floor 玩家保底
|
||
*/
|
||
export function getFloorStatus(gachaId: number, floor: Floor[]) {
|
||
let floorMap = new Map<number, number>();
|
||
for (let { id, count } of floor) {
|
||
floorMap.set(id, count);
|
||
}
|
||
let dicFloorType = GACHA_TO_FLOOR.get(gachaId);
|
||
return dicFloorType.map(id => {
|
||
return {
|
||
id,
|
||
count: floorMap.get(id) || 0
|
||
}
|
||
});
|
||
}
|
||
|
||
export async function checkWhiteListWithUid(uid: number) {
|
||
let user = await UserModel.findUserByUid(uid);
|
||
if(!user) return false;
|
||
let { tel, ip } = user;
|
||
return await checkWhiteList(tel, ip);
|
||
}
|
||
|
||
export async function checkWhiteList(tel: string, ip: string) {
|
||
if(tel) {
|
||
let result = await WhiteListModel.checkTel(tel);
|
||
if(!!result) return true;
|
||
}
|
||
if(ip) {
|
||
let result = await WhiteListModel.checkIp(ip);
|
||
if(!!result) return true;
|
||
}
|
||
return false
|
||
} |