ZZZ-Plugin/model/abyss.js
A-nony-mous 9f56228b9b
style: %危局通关时刻日期格式变更 (#142)
* fix: 日期格式变更

将`危局强袭战`和`式舆防卫战`的时间显示格式添加了前导零`2025.01.01 01:01:01`,和官方一致。

* fix: 修复`式舆防卫战`顶部时间不合预期
2025-08-12 15:46:46 +08:00

372 lines
8.7 KiB
JavaScript
Raw Permalink 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 { 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'
)}`;
}
}