import { data_type, week_data_type } from "../../module_link/game/Player"; export enum PeriodDataUpdate { none = 0, day = 1, week = 2, month = 3, } /**周期数据 * @param T 为一个枚举类型 * @param update PeriodDataUpdate 更新周期 * @param limt 限制值最大,最小 * 调用check检测更新 * @exampl 定义数据枚举 字段名和字段key需要一致 export enum day_type{ score ="score", level ="level", relive="relive", } 初始所有定义数据 day_data = new PeriodData(PeriodDataUpdate.day, Object.keys(day_type) as day_type[], new Map([ [day_type.relive,{min:0,max:3}],//限制每日复活3次 ]) ); day_data.get(day_type.score)... */ export default class PeriodData { private _data: Map = new Map(); private _data_Array: Map = new Map(); private _last: number = 0; private _update: PeriodDataUpdate; constructor(update: PeriodDataUpdate, limt?: Map) { this._update = update; if (!limt) return; //遍历所有键进行初始化 limt.forEach((v, key) => { this._data.set(key, { v: v.min ?? 0, min: v.min, max: v.max }); }, this); } /** * 序列化(数据库存储) */ public serialize(): any { const obj: { [key: string]: number } = {}; this._data.forEach((value, key) => { obj[String(key)] = value.v; }); const obj1: { [key: string]: any } = {}; this._data_Array.forEach((value, key) => { obj1[String(key)] = value; }); const data = { "last": this._last, "data": obj, "data_Array": obj1 }; return data; } /** * 反序列化 */ public unserialize(data: any): void { if (!data) return; this._last = data.last ?? 0; const obj: { [key: string]: number } = data.data; if (obj) { for (const key in obj) { const value = obj[key]; this._get(key as T).v = value; } } const obj1: { [key: string]: any } = data.data_Array; if (obj1) { for (const key in obj1) { const value = obj1[key]; this.set_Array(key as T, value); } } } private _get(key: T): { v: number, min: number, max: number } { let data = this._data.get(key); if (!data) { data = { v: 0, min: 0, max: null }; this._data.set(key, data); } return data; } private _get_Array(key: T): any { let data = this._data_Array.get(key); if (!data) { data = new Array(7).fill(false); this._data_Array.set(key, data); } return data; } /**如果有必要,重新设置数据的min,max*/ set(key: T, value: number, min?: number | null, max?: number | null) { const d = this._get(key); d.v = value; d.min = min; d.max = max; } /**获取数据*/ get(key: T): number { return this._get(key).v; } set_Array(key: T, value: any) { this._data_Array.set(key, value); } /**获取数据*/ get_Array(key: T): any { return this._get_Array(key); } /**有大最值的话,获取数据为剩余可用次数*/ get_available(key: T): number { const d = this._get(key); if (d.max) return d.max - d.v; return d.v; } isEnble(key: T): boolean { const d = this._get(key); return d.v > 0; } enble(key: T): void { this._get(key).v = 1; } disEnble(key: T): void { this._get(key).v = 0; } /**增加数据的值*/ add(key: T, n: number = 1): number | null { return this.change(key, n); } /**减小数据的值*/ sub(key: T, n: number = 1): number | null { return this.change(key, -n); } /**改变数据 n>0增加 小于0减少*/ change(key: T, n: number): number | null { const d = this._get(key); if (!d) return null; d.v += n; if (d.min && d.v < d.min) d.v = d.min; if (d.max && d.v > d.max) d.v = d.max; return d.v; } /**改变数据,比原本值大直接替换,没有改变返回null*/ change_big(key: T, n: number): number | null { const d = this._get(key); if (!d) return null; if (n > d.v) { d.v = n; if (d.min && d.v < d.min) d.v = d.min; if (d.max && d.v > d.max) d.v = d.max; return d.v; } return null; } /**改变数据,比原本值小直接替换,没有改变返回null*/ change_sm(key: T, n: number): number | null { const d = this._get(key); if (!d) return null; if (n < d.v) { d.v = n; if (d.min && d.v < d.min) d.v = d.min; if (d.max && d.v > d.max) d.v = d.max; return d.v; } return null; } /**检测更新now当前时间戳(ms)*/ check(now: number): boolean { if (this._update == PeriodDataUpdate.none) return false; if (this._update == PeriodDataUpdate.day) { if (!this.isSameDate(now, this._last)) { this._last = now; this.reset(); return true; } } if (this._update == PeriodDataUpdate.week) { if (!this.areDatesInSameWeek(now, this._last)) { this._last = now; this.reset(); this._data_Array=new Map(); return true; } } if (this._update == PeriodDataUpdate.month) { if (!this.areDatesInSameMonth(now, this._last)) { this._last = now; this.reset(); return true; } } return false; } reset(): void { for (const key of this._data.keys()) { const data = this._get(key); data.v = data.min ?? 0; } } /**判定两个时间是否是同一天*/ private isSameDate(timestamp1: number, timestamp2: number): boolean { let date1 = new Date(timestamp1); let date2 = new Date(timestamp2); return date1.getFullYear() == date2.getFullYear() && date1.getMonth() == date2.getMonth() && date1.getDate() == date2.getDate(); } /**判定两个时间是否是同一周*/ private areDatesInSameWeek(date1: number, date2: number): boolean { const startOfWeek1 = this.getStartOfWeek(new Date(date1)); const startOfWeek2 = this.getStartOfWeek(new Date(date2)); return startOfWeek1.getTime() === startOfWeek2.getTime(); } private getStartOfWeek(date: Date): Date { const startOfWeek = new Date(date); const day = startOfWeek.getDay(); // 星期日是 0,星期一是 1,依此类推 const diff = startOfWeek.getDate() - day; // 计算当前日期所在周的第一天 startOfWeek.setDate(diff); // 设置为该周的第一天 startOfWeek.setHours(0, 0, 0, 0); // 设置时间为 00:00:00 return startOfWeek; } private areDatesInSameMonth(date1: number, date2: number): boolean { const d1 = new Date(date1); const d2 = new Date(date2); return d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth(); } }