HJ_Server/src/shared/public/public.ts
2023-12-28 14:18:58 +08:00

277 lines
9.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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];
}
}