mirror of
https://github.com/ZZZure/ZZZ-Plugin.git
synced 2025-12-15 12:47:48 +00:00
* fix: 日期格式变更 将`危局强袭战`和`式舆防卫战`的时间显示格式添加了前导零`2025.01.01 01:01:01`,和官方一致。 * fix: 修复`式舆防卫战`顶部时间不合预期
372 lines
8.7 KiB
JavaScript
372 lines
8.7 KiB
JavaScript
import { element } from '../lib/convert.js';
|
||
import { getSquareAvatar, getSquareBangboo } from '../lib/download.js';
|
||
/**
|
||
* @typedef {Object} IChallengeAvatar
|
||
* @property {number} id
|
||
* @property {number} level
|
||
* @property {string} rarity
|
||
* @property {number} element_type
|
||
*/
|
||
|
||
/**
|
||
* @typedef {Object} IChallengeBangboo
|
||
* @property {number} id
|
||
* @property {string} rarity
|
||
* @property {number} level
|
||
*/
|
||
|
||
/**
|
||
* @typedef {Object} IHadalTime
|
||
* @property {number} year
|
||
* @property {number} month
|
||
* @property {number} day
|
||
* @property {number} hour
|
||
* @property {number} minute
|
||
* @property {number} second
|
||
*/
|
||
|
||
/**
|
||
* @typedef {Object} IMonsterInfo
|
||
* @property {number} id
|
||
* @property {string} name
|
||
* @property {number} weak_element_type
|
||
*/
|
||
|
||
/**
|
||
* @typedef {Object} IBuff
|
||
* @property {string} title
|
||
* @property {string} text
|
||
*/
|
||
|
||
/**
|
||
* @typedef {Object} IChallengeNode
|
||
* @property {IChallengeAvatar[]} avatars
|
||
* @property {IChallengeBangboo} buddy
|
||
* @property {number[]} element_type_list
|
||
* @property {IMonsterInfo} monster_info
|
||
*/
|
||
|
||
/**
|
||
* @typedef {Object} IFloorChallengeTime
|
||
* @property {number} year
|
||
* @property {number} month
|
||
* @property {number} day
|
||
* @property {number} hour
|
||
* @property {number} minute
|
||
* @property {number} second
|
||
*/
|
||
|
||
/**
|
||
* @typedef {Object} IFloorDetail
|
||
* @property {number} layer_index
|
||
* @property {string} rating
|
||
* @property {number} layer_id
|
||
* @property {IBuff[]} buffs
|
||
* @property {IChallengeNode} node_1
|
||
* @property {IChallengeNode} node_2
|
||
* @property {number} challenge_time
|
||
* @property {string} zone_name
|
||
* @property {IFloorChallengeTime} floor_challenge_time
|
||
*/
|
||
|
||
/**
|
||
* @typedef {Object} IRating
|
||
* @property {number} times
|
||
* @property {string} rating
|
||
*/
|
||
|
||
/**
|
||
* @typedef {Object} IZZZChallenge
|
||
* @property {number} schedule_id
|
||
* @property {number} begin_time
|
||
* @property {number} end_time
|
||
* @property {IRating[]} rating_list
|
||
* @property {boolean} has_data
|
||
* @property {IFloorDetail[]} all_floor_detail
|
||
* @property {number} fast_layer_time
|
||
* @property {number} max_layer
|
||
* @property {IHadalTime} hadal_begin_time
|
||
* @property {IHadalTime} hadal_end_time
|
||
*/
|
||
|
||
/**
|
||
* @class ChallengeAvatar.
|
||
*/
|
||
export class ChallengeAvatar {
|
||
/**
|
||
* @param {IChallengeAvatar} data
|
||
*/
|
||
constructor(data) {
|
||
this.id = data.id;
|
||
this.level = data.level;
|
||
this.rarity = data.rarity;
|
||
this.element_type = data.element_type;
|
||
this.rank = data.rank;
|
||
}
|
||
|
||
async get_assets() {
|
||
const result = await getSquareAvatar(this.id);
|
||
this.square_icon = result;
|
||
}
|
||
|
||
get element() {
|
||
return element.IDToElement(this.element_type);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @class ChallengeBangboo.
|
||
*/
|
||
export class ChallengeBangboo {
|
||
/**
|
||
* @param {IChallengeBangboo} data
|
||
*/
|
||
constructor(data) {
|
||
this.id = data.id;
|
||
this.rarity = data.rarity;
|
||
this.level = data.level;
|
||
}
|
||
|
||
async get_assets() {
|
||
const result = await getSquareBangboo(this.id);
|
||
this.square_icon = result;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @class MonsterInfo.
|
||
*/
|
||
export class MonsterInfo {
|
||
/**
|
||
* @param {IMonsterInfo} data
|
||
*/
|
||
constructor(data) {
|
||
this.id = data.id;
|
||
this.name = data.name;
|
||
this.weak_element_type = data.weak_element_type;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @class Buff.
|
||
*/
|
||
export class Buff {
|
||
/**
|
||
* @param {IBuff} data
|
||
*/
|
||
constructor(data) {
|
||
this.title = data.title;
|
||
this.text = data.text;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @class ChallengeNode.
|
||
*/
|
||
export class ChallengeNode {
|
||
/**
|
||
* @param {IChallengeNode} data
|
||
*/
|
||
constructor(data) {
|
||
/** @type {IChallengeAvatar[]} */
|
||
this.avatars = data?.avatars?.map(avatar => new ChallengeAvatar(avatar));
|
||
/** @type {IChallengeBangboo} */
|
||
this.buddy = data?.buddy && new ChallengeBangboo(data.buddy);
|
||
/** @type {number[]} */
|
||
this.element_type_list = data.element_type_list;
|
||
/** @type {MonsterInfo} */
|
||
this.monster_info =
|
||
data?.monster_info && new MonsterInfo(data.monster_info);
|
||
/** @type {number} */
|
||
this.battle_time = data.battle_time;
|
||
}
|
||
|
||
async get_assets() {
|
||
if (this.avatars) {
|
||
await Promise.all(this.avatars.map(avatar => avatar.get_assets()));
|
||
}
|
||
if (this.buddy) {
|
||
await this.buddy.get_assets();
|
||
}
|
||
}
|
||
|
||
get elements() {
|
||
return this.element_type_list.map(type => {
|
||
return element.IDToElement(type);
|
||
});
|
||
}
|
||
|
||
get formattedTime() {
|
||
const seconds = this.battle_time % 60;
|
||
const minutes = Math.floor(this.battle_time / 60);
|
||
return `${minutes ? minutes + '分' : ''}${seconds + '秒'}`;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @class FloorChallengeTime.
|
||
*/
|
||
export class FloorChallengeTime {
|
||
/**
|
||
* @param {IFloorChallengeTime} data
|
||
*/
|
||
constructor(data) {
|
||
/** @type {number} */
|
||
this.year = data.year;
|
||
/** @type {number} */
|
||
this.month = data.month;
|
||
/** @type {number} */
|
||
this.day = data.day;
|
||
/** @type {number} */
|
||
this.hour = data.hour;
|
||
/** @type {number} */
|
||
this.minute = data.minute;
|
||
/** @type {number} */
|
||
this.second = data.second;
|
||
}
|
||
|
||
/** @type {string} */
|
||
get formattedTime() {
|
||
return `${this.year}/${this.month}/${this.day} ${this.hour}:${this.minute}:${this.second}`;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @class FloorDetail.
|
||
*/
|
||
export class FloorDetail {
|
||
/**
|
||
* @param {IFloorDetail} data
|
||
*/
|
||
constructor(data) {
|
||
/** @type {number} */
|
||
this.layer_index = data.layer_index;
|
||
/** @type {string} */
|
||
this.rating = data.rating;
|
||
/** @type {number} */
|
||
this.layer_id = data.layer_id;
|
||
/** @type {IBuff[]} */
|
||
this.buffs = data.buffs.map(buff => new Buff(buff));
|
||
/** @type {IChallengeNode} */
|
||
this.node_1 = data?.node_1 && new ChallengeNode(data.node_1);
|
||
/** @type {IChallengeNode} */
|
||
this.node_2 = data?.node_2 && new ChallengeNode(data.node_2);
|
||
/** @type {number} */
|
||
this.challenge_time = data.challenge_time;
|
||
/** @type {string} */
|
||
this.zone_name = data.zone_name;
|
||
/** @type {IFloorChallengeTime} */
|
||
this.floor_challenge_time = new FloorChallengeTime(
|
||
data.floor_challenge_time
|
||
);
|
||
}
|
||
|
||
async get_assets() {
|
||
if (this.node_1) {
|
||
await this.node_1.get_assets();
|
||
}
|
||
if (this.node_2) {
|
||
await this.node_2.get_assets();
|
||
}
|
||
}
|
||
|
||
/** @type {string} */
|
||
get formattedTime() {
|
||
const time = this.floor_challenge_time;
|
||
return `${time.year}.${String(time.month).padStart(2, '0')}.${String(
|
||
time.day
|
||
).padStart(2, '0')} ${String(time.hour).padStart(2, '0')}:${String(
|
||
time.minute
|
||
).padStart(2, '0')}:${String(time.second).padStart(2, '0')}`;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @class Rating.
|
||
*/
|
||
export class Rating {
|
||
/**
|
||
* @param {IRating} data
|
||
*/
|
||
constructor(data) {
|
||
this.times = data.times;
|
||
this.rating = data.rating;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @class ZZZChallenge.
|
||
*/
|
||
export class ZZZChallenge {
|
||
/**
|
||
* @param {IZZZChallenge} data
|
||
*/
|
||
constructor(data) {
|
||
// 类型标注
|
||
/** @type {number} */
|
||
this.schedule_id = data.schedule_id;
|
||
/** @type {number} */
|
||
this._begin_time = data.begin_time;
|
||
/** @type {number} */
|
||
this._end_time = data.end_time;
|
||
/** @type {IRating[]} */
|
||
this.rating_list = data.rating_list.map(rating => new Rating(rating));
|
||
/** @type {boolean} */
|
||
this.has_data = data.has_data;
|
||
/** @type {IFloorDetail[]} */
|
||
this.all_floor_detail = data.all_floor_detail.map(
|
||
floorDetail => new FloorDetail(floorDetail)
|
||
);
|
||
/** @type {number} */
|
||
this.fast_layer_time = data.fast_layer_time;
|
||
/** @type {number} */
|
||
this.max_layer = data.max_layer;
|
||
/** @type {IHadalTime} */
|
||
this.hadal_begin_time = data.hadal_begin_time;
|
||
/** @type {IHadalTime} */
|
||
this.hadal_end_time = data.hadal_end_time;
|
||
|
||
/** @type {{
|
||
* S: number;
|
||
* A: number;
|
||
* B: number;
|
||
* }} */
|
||
this.rate_count = {
|
||
S: this.rating_list.find(rating => rating.rating === 'S')?.times || 0,
|
||
A: this.rating_list.find(rating => rating.rating === 'A')?.times || 0,
|
||
B: this.rating_list.find(rating => rating.rating === 'B')?.times || 0,
|
||
};
|
||
}
|
||
|
||
async get_assets() {
|
||
await Promise.all(this.all_floor_detail.map(floor => floor.get_assets()));
|
||
}
|
||
|
||
get fast_layer_time_str() {
|
||
// 将秒数转换为 xx小时xx分钟xx秒 的格式,例如:234 -> 3分钟54秒
|
||
const seconds = this.fast_layer_time % 60;
|
||
const minutes = Math.floor(this.fast_layer_time / 60) % 60;
|
||
const hours = Math.floor(this.fast_layer_time / 3600);
|
||
return `${hours ? hours + '小时' : ''}${minutes ? minutes + '分钟' : ''}${
|
||
seconds ? seconds + '秒' : ''
|
||
}`;
|
||
}
|
||
|
||
/** @type {string} */
|
||
get begin_time() {
|
||
const time = this.hadal_begin_time;
|
||
return `${String(time.month).padStart(2, '0')}.${String(time.day).padStart(
|
||
2,
|
||
'0'
|
||
)}`;
|
||
}
|
||
|
||
/** @type {string} */
|
||
get end_time() {
|
||
const time = this.hadal_end_time;
|
||
return `${String(time.month).padStart(2, '0')}.${String(time.day).padStart(
|
||
2,
|
||
'0'
|
||
)}`;
|
||
}
|
||
}
|