277 lines
9.7 KiB
TypeScript
277 lines
9.7 KiB
TypeScript
import { string } from 'mathjs';
|
||
import { ApiCall } from 'tsrpc';
|
||
import { prizeType } from '../protocols/type';
|
||
import { player } from '../protocols/user/type';
|
||
|
||
export class PublicShared {
|
||
/**合并奖励 */
|
||
static mergePrize(prize: prizeType[]): prizeType[] {
|
||
let typeObj: k_v<k_v<{
|
||
n: number;
|
||
colour?: number;
|
||
}>> = {};
|
||
let mergeArr: prizeType[] = [];
|
||
|
||
prize.forEach(atn => {
|
||
if (!typeObj[atn.a]) typeObj[atn.a] = {};
|
||
if (!typeObj[atn.a][atn.t]) typeObj[atn.a][atn.t] = { n: 0, colour: atn.colour || 0 };
|
||
typeObj[atn.a][atn.t].n += atn.n;
|
||
});
|
||
for (let type in typeObj) {
|
||
for (let id in typeObj[type]) {
|
||
mergeArr.push({
|
||
a: type,
|
||
t: id,
|
||
n: typeObj[type][id].n,
|
||
colour: typeObj[type][id].colour
|
||
});
|
||
}
|
||
}
|
||
return mergeArr;
|
||
}
|
||
|
||
static exprStr2Compile = {};
|
||
/**eval预编译 */
|
||
static eval(expr:any, scope?:object){
|
||
if(Array.isArray(expr)) {
|
||
let res = []
|
||
expr.forEach( item => {
|
||
if(! this.exprStr2Compile[item] ){
|
||
this.exprStr2Compile[item] = mathJs.compile(item);
|
||
}
|
||
res.push(this.exprStr2Compile[item].evaluate(scope))
|
||
})
|
||
return res
|
||
} else {
|
||
if(! this.exprStr2Compile[expr] ){
|
||
this.exprStr2Compile[expr] = mathJs.compile(expr);
|
||
}
|
||
return this.exprStr2Compile[expr].evaluate(scope);
|
||
}
|
||
}
|
||
|
||
/**合并属性 */
|
||
static mergeProperty(obj1: any = {}, obj2: any = {}) {
|
||
for (let k in obj2) {
|
||
|
||
if (obj2[k] instanceof Array) {
|
||
if (obj1[k]) obj1[k] = obj1[k].concat(obj2[k]);
|
||
else obj1[k] = obj2[k];
|
||
} else if (obj2[k] instanceof Object) {
|
||
if (obj1[k]) PublicShared.mergeProperty(obj1[k], obj2[k]);
|
||
else {
|
||
obj1[k] = {};
|
||
PublicShared.mergeProperty(obj1[k], obj2[k]);
|
||
}
|
||
} else {
|
||
if (obj1[k]) obj1[k] += obj2[k];
|
||
else obj1[k] = obj2[k];
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* 随机掉落组
|
||
* @param id 掉落组id
|
||
* @param num 随机次数
|
||
* @param conf
|
||
*/
|
||
static randomDropGroup(id: string | number, num = 1, conf = G.gc.diaoluo): prizeType[] {
|
||
let prize = [];
|
||
let weight = [];
|
||
let dlz = JSON.parse(JSON.stringify(conf[id]));
|
||
|
||
dlz.forEach((d, index) => {
|
||
if (weight[index - 1]) {
|
||
weight.push(weight[index - 1] + d.p);
|
||
} else {
|
||
weight.push(d.p);
|
||
}
|
||
});
|
||
|
||
for (let n = 0; n < num; n++) {
|
||
let prizeIndex = 0;
|
||
// debug 举例:diaoluo.json 250001参数的[p:1, p:140], 随机数范围是 1-141,小于等于1的概率较小,所以大部分取后面的值,后面的值给的物品数量是0
|
||
let randomNum = this.randomNum(1, weight[weight.length - 1]);
|
||
|
||
for (let index = 0; index < weight.length; index++) {
|
||
if (randomNum <= weight[index]) {
|
||
prizeIndex = index;
|
||
break;
|
||
}
|
||
}
|
||
|
||
prize.push(dlz[prizeIndex]);
|
||
}
|
||
|
||
return prize;
|
||
}
|
||
/**
|
||
* 随机概率组
|
||
*/
|
||
static randomDropAny<T extends { p: number; }>(dropArr: T[]): T {
|
||
let dropGrop = { 0: dropArr };
|
||
return this.randomDropGroup(0, 1, dropGrop as any)[0] as any;
|
||
}
|
||
/**
|
||
* 随机生成区间范围整数
|
||
*/
|
||
static randomNum(min: number, max: number) {
|
||
return Math.floor(Math.random() * (max - min + 1) + min);
|
||
}
|
||
/**获取道具配置 */
|
||
static getAtnConf(atn: prizeType) {
|
||
if (atn.a == 'attr') return G.gc.attr[atn.t];
|
||
else if (atn.a == 'item') return G.gc.item[atn.t];
|
||
else if (atn.a == 'hero') return G.gc.hero[atn.t];
|
||
else if (atn.a == 'equip') return G.gc.equip[atn.t];
|
||
|
||
return null;
|
||
}
|
||
/**获取当天0点时间戳 */
|
||
static getToDayZeroTime(time: string): number;
|
||
static getToDayZeroTime(time?: number): number;
|
||
static getToDayZeroTime(time: string | number) {
|
||
let t = typeof time == 'string' ? new Date(time) : new Date((time || G.time) * 1000);
|
||
return Math.round(t.setHours(0, 0, 0, 0) / 1000);
|
||
}
|
||
/**获取本周周一0点时间戳 */
|
||
static getToWeekMondayZeroTime(time = G.time) {
|
||
let toDay = new Date(time * 1000);
|
||
let day = toDay.getDay() || 7;
|
||
let z = new Date(toDay.getFullYear(), toDay.getMonth(), toDay.getDate() + 1 - day);
|
||
return Math.round(z.getTime() / 1000);
|
||
}
|
||
|
||
/**获取当前第几周 避免跨年导致key不一样,以周一时间戳去计算*/
|
||
static getToWeek(time = this.getToWeekMondayZeroTime()) {
|
||
let toDay = new Date(time * 1000);
|
||
let day = toDay.getDay() || 7;
|
||
let z = new Date(toDay.getFullYear(), toDay.getMonth(), toDay.getDate() + 1 - day);
|
||
|
||
let z2 = new Date(toDay.getFullYear(), 0, 1);
|
||
|
||
let rq = (z.getTime() - z2.getTime()) / 1000;
|
||
let s1 = Math.ceil(rq / (24 * 60 * 60));
|
||
let s2 = Math.ceil(s1 / 7);
|
||
return `${toDay.getFullYear()}_${s2}`;
|
||
}
|
||
|
||
/**周几 */
|
||
static getWeek(timestamp: number) {
|
||
let toDay = new Date(timestamp * 1000);
|
||
const day = toDay.getDay();
|
||
return day
|
||
}
|
||
|
||
/**是否同一天 */
|
||
static chkSameDate(time: string | number, chktime: string | number) {
|
||
if (this.getToDayZeroTime(time as string) === this.getToDayZeroTime(chktime as string))
|
||
return true;
|
||
return false;
|
||
}
|
||
/**获取今天是开服第几天 */
|
||
static getOpenServerDay(openTime: any = G.openTime, time = G.time) {
|
||
let oDay = this.getToDayZeroTime(openTime);
|
||
return Math.ceil((time - oDay) / 86400);
|
||
}
|
||
/**获取相差天数 */
|
||
static getDiff(oldTime: number, time = G.time) {
|
||
let oDay = this.getToDayZeroTime(oldTime);
|
||
return Math.ceil((time - oDay) / 86400);
|
||
}
|
||
|
||
/**数组buff转对象buff */
|
||
static arrBuffToObjectBuff(arrBuff: (string | number)[]) {
|
||
let buff = {};
|
||
for (let i = 0; i < arrBuff.length; i++) {
|
||
if (i % 2 != 0) continue;
|
||
buff[arrBuff[i]] = arrBuff[i + 1];
|
||
}
|
||
return buff;
|
||
}
|
||
static str(str: string, ...args: Array<number | string>) {
|
||
if (arguments.length < 2) return str;
|
||
if (arguments.length == 2 && Object.prototype.toString.call(arguments[1]) == '[object Array]') {
|
||
let args = arguments[1];
|
||
for (let i = 0; i < args.length; i++) {
|
||
str = str.replace(new RegExp('\\{' + (i + 1) + '\\}', 'g'), args[i]);
|
||
}
|
||
} else {
|
||
for (let i = 1; i < arguments.length; i++) {
|
||
str = str.replace(new RegExp('\\{' + i + '\\}', 'g'), arguments[i]);
|
||
}
|
||
}
|
||
return str;
|
||
}
|
||
|
||
static getEventIsOpen(cond: k_v<number>, player: Partial<player>) {
|
||
|
||
let arr = Object.entries(cond);
|
||
|
||
for (let [k, v] of arr) {
|
||
if (k == 'day' && this.getOpenServerDay() < v) return false;
|
||
if (player[k] < v) return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/**转化时间戳显示日期 */
|
||
static fmtTime(timestamp: number) {
|
||
const date = new Date(timestamp * 1000);
|
||
const year = date.getFullYear();
|
||
const month = date.getMonth() + 1; // 获取月份,需要加1
|
||
const day = date.getDate(); // 获取日期
|
||
const hour = date.getHours(); // 获取小时
|
||
const minute = date.getMinutes(); // 获取分钟
|
||
const second = date.getSeconds(); // 获取秒数
|
||
// const formattedDate = `${year}-${month}-${day} ${hour}:${minute}:${second}`; // 拼接成格式化后的日期字符串
|
||
const formattedDate = `${month}月${day}日${hour}:${minute}`; // 拼接成格式化后的日期字符串
|
||
return formattedDate;
|
||
}
|
||
|
||
/**功能开启 */
|
||
static getOpenCond(call: ApiCall, gongneng: string): [boolean, string] {
|
||
let _con = G.gc.openCond[gongneng]
|
||
if (!_con) return [false, "功能不存在"]
|
||
|
||
let _res = false
|
||
let _and = Object.keys(_con.and)
|
||
for (let index = 0; index < _and.length; index++) {
|
||
_res = true
|
||
const element = _and[index];
|
||
if (element == "lv" && call.conn.gud.lv < _con.and[element]) {
|
||
_res = false
|
||
} else if (element == "openTime" && this.getOpenServerDay() < _con.and[element]) {
|
||
_res = false
|
||
} else if (element == "vip" && call.conn.gud.vip < _con.and[element]) {
|
||
_res = false
|
||
} else if (element == "mapId" && call.conn.gud.mapId < _con.and[element]) {
|
||
_res = false
|
||
}
|
||
|
||
if (!_res) return [false, _con.tips]
|
||
}
|
||
|
||
let _or = Object.keys(_con.or)
|
||
for (let index = 0; index < _or.length; index++) {
|
||
_res = false
|
||
const element = _or[index];
|
||
if (element == "lv" && call.conn.gud.lv >= _con.or[element]) {
|
||
_res = true
|
||
break
|
||
} else if (element == "openTime" && this.getOpenServerDay() >= _con.or[element]) {
|
||
_res = true
|
||
break
|
||
} else if (element == "vip" && call.conn.gud.vip >= _con.or[element]) {
|
||
_res = true
|
||
break
|
||
} else if (element == "mapId" && call.conn.gud.mapId >= _con.or[element]) {
|
||
_res = true
|
||
break
|
||
}
|
||
}
|
||
|
||
return [_res, _con.tips];
|
||
}
|
||
|
||
} |