feat: base panel

This commit is contained in:
bietiaop 2024-07-12 02:43:32 +08:00
parent cbef7478c2
commit ac0c3d0d6c
12 changed files with 361 additions and 149 deletions

View file

@ -1,5 +1,4 @@
import { ZZZPlugin } from '../lib/plugin.js';
import _ from 'lodash';
import render from '../lib/render.js';
import { rulePrefix } from '../lib/common.js';
import { ZZZIndexResp } from '../model/index.js';
@ -23,25 +22,27 @@ export class Card extends ZZZPlugin {
const { api, deviceFp } = await this.getAPI();
if (!api) return false;
await this.getPlayerInfo();
let indexData = await api.getData('zzzIndex', { deviceFp });
indexData = await api.checkCode(this.e, indexData, 'zzzIndex', {});
if (!indexData || indexData.retcode !== 0) {
await this.reply('[zzznote]Index数据获取失败');
return false;
}
indexData = indexData.data;
const indexData = await api.getFinalData(this.e, 'zzzIndex', { deviceFp });
if (!indexData) return false;
let zzzAvatarList = await api.getData('zzzAvatarList', { deviceFp });
indexData.avatar_list = zzzAvatarList.data.avatar_list;
let zzzAvatarList = await api.getFinalData(this.e, 'zzzAvatarList', {
deviceFp,
});
if (!zzzAvatarList) return false;
indexData.avatar_list = zzzAvatarList.avatar_list;
let zzzBuddyList = await api.getData('zzzBuddyList', { deviceFp });
indexData.buddy_list = zzzBuddyList.data.list;
let zzzBuddyList = await api.getFinalData(this.e, 'zzzBuddyList', {
deviceFp,
});
if (!zzzBuddyList) return false;
indexData.buddy_list = zzzBuddyList.list;
indexData = new ZZZIndexResp(indexData);
this.e.playerCard.player.region_name = indexData.stats.world_level_name;
await indexData.get_assets();
const finalIndexData = new ZZZIndexResp(indexData);
this.e.playerCard.player.region_name =
finalIndexData.stats.world_level_name;
await finalIndexData.get_assets();
const data = {
card: indexData,
card: finalIndexData,
};
await render(this.e, 'card/index.html', data);
}

View file

@ -1,5 +1,4 @@
import { ZZZPlugin } from '../lib/plugin.js';
import _ from 'lodash';
import render from '../lib/render.js';
import { rulePrefix } from '../lib/common.js';
import { getAuthKey } from '../lib/authkey.js';

View file

@ -1,5 +1,4 @@
import { ZZZPlugin } from '../lib/plugin.js';
import _ from 'lodash';
import { rulePrefix } from '../lib/common.js';
export class Help extends ZZZPlugin {

View file

@ -1,5 +1,4 @@
import { ZZZPlugin } from '../lib/plugin.js';
import _ from 'lodash';
import render from '../lib/render.js';
import { ZZZNoteResp } from '../model/note.js';
import { rulePrefix } from '../lib/common.js';
@ -23,14 +22,11 @@ export class Note extends ZZZPlugin {
const { api, deviceFp } = await this.getAPI();
if (!api) return false;
await this.getPlayerInfo();
let noteData = await api.getData('zzzNote', { deviceFp });
noteData = await api.checkCode(this.e, noteData, 'zzzNote', {});
if (!noteData || noteData.retcode !== 0) {
await this.reply('[zzznote]每日数据获取失败');
return false;
}
noteData = noteData.data;
noteData = new ZZZNoteResp(noteData);
const noteResponse = await api.getFinalData(this.e, 'zzzNote', {
deviceFp,
});
if (!noteResponse) return false;
const noteData = new ZZZNoteResp(noteResponse);
const finalData = {
note: noteData,
};

View file

@ -1,8 +1,7 @@
import { ZZZPlugin } from '../lib/plugin.js';
import _ from 'lodash';
import render from '../lib/render.js';
import { ZZZNoteResp } from '../model/note.js';
import { rulePrefix } from '../lib/common.js';
import { getPanelList, refreshPanel, getPanel } from '../lib/avatar.js';
export class Panel extends ZZZPlugin {
constructor() {
@ -16,25 +15,60 @@ export class Panel extends ZZZPlugin {
reg: `${rulePrefix}((刷新|更新)面板|面板(刷新|更新))$`,
fnc: 'refreshPanel',
},
{
reg: `${rulePrefix}面板列表$`,
fnc: 'getPanelList',
},
{
reg: `${rulePrefix}(.+)面板$`,
fnc: 'getPanel',
},
],
});
}
async refreshPanel() {
const { api, deviceFp } = await this.getAPI();
if (!api) return false;
await this.reply('TODO');
// await this.getPlayerInfo();
// let noteData = await api.getData('zzzNote', { deviceFp });
// noteData = await api.checkCode(this.e, noteData, 'zzzNote', {});
// if (!noteData || noteData.retcode !== 0) {
// await this.reply('[zzznote]每日数据获取失败');
// return false;
// }
// noteData = noteData.data;
// noteData = new ZZZNoteResp(noteData);
const { api, deviceFp, uid } = await this.getAPI();
if (!api || !uid) return false;
await this.getPlayerInfo();
const result = await refreshPanel(this.e, api, uid, deviceFp);
const newChar = result.filter(item => item.isNew);
let str = '面板列表获取成功,本次共刷新了' + newChar.length + '个角色:';
for (const item of result) {
str += '\n' + item.name_mi18n;
}
str += '\n总计' + result.length + '个角色';
await this.reply(str);
// const finalData = {
// note: noteData,
// list: noteData,
// };
// await render(this.e, 'note/index.html', finalData);
// await render(this.e, 'panel/refresh.html', finalData);
}
async getPanelList() {
const uid = await this.getUID();
if (!uid) return false;
const noteData = getPanelList(uid);
if (!noteData) return false;
await this.getPlayerInfo();
let str = '面板列表获取成功,共计' + noteData.length + '个角色:';
for (const item of noteData) {
str += '\n' + item.name_mi18n;
}
await this.reply(str);
// const finalData = {
// list: noteData,
// };
// await render(this.e, 'panel/list.html', finalData);
}
async getPanel() {
const uid = await this.getUID();
if (!uid) return false;
const reg = new RegExp(`${rulePrefix}(.+)面板$`);
const name = this.e.msg.match(reg)[4];
const data = getPanel(uid, name);
await this.reply(JSON.stringify(data, null, 2));
// const finalData = {
// list: noteData,
// };
// await render(this.e, 'panel/list.html', finalData);
}
}

105
lib/avatar.js Normal file
View file

@ -0,0 +1,105 @@
import { ZZZAvatarBasic, ZZZAvatarInfo } from '../model/avatar.js';
import MysZZZApi from './mysapi.js';
import { getPanelData, savePanelData } from './db.js';
import { char } from './convert.js';
/**
* 获取角色基础信息列表
* @param {*} e 消息事件
* @param {MysZZZApi} api
* @param {string} deviceFp
* @param {boolean} origin 是否返回原始数据
* @returns {Promise<ZZZAvatarBasic[] | null>}
*/
export async function getAvatarBasicList(e, api, deviceFp, origin = false) {
const avatarBaseListData = await api.getFinalData(e, 'zzzAvatarList', {
deviceFp,
});
if (!avatarBaseListData) return null;
if (origin) return avatarBaseListData.avatar_list;
const result = avatarBaseListData.avatar_list.map(
item => new ZZZAvatarBasic(item)
);
return result;
}
/**
* 获取角色详细信息列表
* @param {*} e 消息事件
* @param {MysZZZApi} api
* @returns {Promise<ZZZAvatarInfo[] | null>}
* @param {string} deviceFp
* @param {boolean} origin 是否返回原始数据
*/
export async function getAvatarInfoList(e, api, deviceFp, origin = false) {
const avatarBaseList = await getAvatarBasicList(e, api, deviceFp, origin);
if (!avatarBaseList) return null;
const avatarInfoList = await api.getFinalData(e, 'zzzAvatarInfo', {
deviceFp,
query: {
id_list: avatarBaseList.map(item => item.id),
},
});
if (!avatarInfoList) return null;
if (origin) return avatarInfoList.avatar_list;
const result = avatarInfoList.avatar_list.map(
item => new ZZZAvatarInfo(item)
);
return result;
}
/**
* 刷新面板
* @param {*} e 消息事件
* @param {MysZZZApi} api
* @param {string} uid
* @param {string} deviceFp
* @returns {Promise<ZZZAvatarInfo[] | null>}
*/
export async function refreshPanel(e, api, uid, deviceFp) {
const originData = getPanelData(uid);
const newData = await getAvatarInfoList(e, api, deviceFp, true);
if (!newData) return null;
const finalData = [...newData];
if (originData) {
for (const item of originData) {
if (!finalData.find(i => i.id === item.id)) {
finalData.push(item);
}
}
}
savePanelData(uid, finalData);
finalData.forEach(item => {
item.isNew = newData.find(i => i.id === item.id);
});
const formattedData = finalData.map(item => new ZZZAvatarInfo(item));
for (const item of formattedData) {
await item.get_basic_assets();
}
return formattedData;
}
/**
*获取面板数据
* @param {string} uid
* @returns {ZZZAvatarInfo[]}
*/
export function getPanelList(uid) {
const data = getPanelData(uid);
return data.map(item => new ZZZAvatarInfo(item));
}
/**
* 获取某个角色的面板数据
* @param {string} uid
* @param {string} name
* @returns {ZZZAvatarInfo | null}
*/
export function getPanel(uid, name) {
logger.debug('获取面板数据', uid, name);
const data = getPanelData(uid).map(item => new ZZZAvatarInfo(item));
const id = char.atlasToID(name);
logger.debug('获取角色ID', id);
if (!id) return null;
return data.find(item => item.id === id) || null;
}

View file

@ -6,7 +6,7 @@ const PartnerId2SpriteId = getMapData('PartnerId2Data');
/**
*
* @param {string} id
* @param {string | number} id
* @param {boolean} full 显示全称
* @param {boolean} en 是否为英文
* @returns string | null
@ -21,7 +21,7 @@ export const IDToCharName = (id, full = true, en = false) => {
/**
*
* @param {string} id
* @param {string | number} id
* @returns string | null
*/
export const IDToCharSprite = id => {
@ -32,11 +32,11 @@ export const IDToCharSprite = id => {
/**
* @param {string} name
* @returns string | null
* @returns number | null
*/
export const charNameToID = name => {
for (const [id, data] of Object.entries(PartnerId2SpriteId)) {
if (data['full_name'] === name) return id;
if (data['name'] === name) return Number(id);
}
return null;
};
@ -47,7 +47,7 @@ export const charNameToID = name => {
*/
export const charNameToSprite = name => {
for (const [_id, data] of Object.entries(PartnerId2SpriteId)) {
if (data['full_name'] === name) return data['sprite'];
if (data['name'] === name) return data['sprite'];
}
return null;
};
@ -70,21 +70,16 @@ export const atlasToName = _atlas => {
* @returns string | null
*/
export const atlasToSprite = _atlas => {
const atlas = settings.getConfig('atlas');
for (const [_id, data] of Object.entries(atlas)) {
if (data.includes(_atlas)) return data['sprite'];
}
return null;
const name = atlasToName(name);
return charNameToSprite(name);
};
/**
* @param {string} name
* @returns string | null
* @returns number | null
*/
export const atlasToID = name => {
const atlas = settings.getConfig('atlas');
for (const [id, data] of Object.entries(atlas)) {
if (data.includes(name)) return charNameToID(id);
}
return null;
const _name = atlasToName(name);
const id = charNameToID(_name);
return id;
};

View file

@ -4,13 +4,14 @@ import { checkFolderExistAndCreate } from '../utils/file.js';
import { dataPath } from './path.js';
const dbPath = {
gacha: 'gacha',
panel: 'panel',
};
/**
*
* @param {string} dbName
* @param {string} dbFile
* @returns {object}
* @returns {object | Array<object> | null}
*/
export function getDB(dbName, dbFile) {
const db = dbPath[dbName];
@ -57,3 +58,19 @@ export function getGachaLog(uid) {
export function saveGachaLog(uid, data) {
setDB('gacha', uid, data);
}
/**
* @param {string} uid
* @returns {Array<object>}
*/
export function getPanelData(uid) {
return getDB('panel', uid) || [];
}
/**
* @param {string} uid
* @param {Array<object>} data
*/
export function savePanelData(uid, data) {
setDB('panel', uid, data);
}

View file

@ -59,6 +59,24 @@ export default class MysZZZApi extends MysApi {
dsSalt = '',
} = urlMap[type];
if (query) url += `?${query}`;
if (data.query) {
let str = '';
for (let key in data.query) {
if (data.query[key] === undefined) continue;
else if (data.query[key] === null) str += `${key}&`;
else if (Array.isArray(data.query[key])) {
data.query[key].forEach(item => {
str += `${key}[]=${item}&`;
});
} else str += `${key}=${data.query[key]}&`;
}
str = str.slice(0, -1);
if (url.includes('?')) {
url += `&${str}`;
} else {
url += `?${str}`;
}
}
if (body) body = JSON.stringify(body);
let headers = this.getHeaders(query, body);
@ -96,6 +114,7 @@ export default class MysZZZApi extends MysApi {
body = JSON.stringify(body);
}
}
logger.debug(`[mysapi]请求url${url}`);
return { url, headers, body };
}
@ -168,7 +187,7 @@ export default class MysZZZApi extends MysApi {
*/
async checkCode(e, res, type, data = {}) {
if (!res || !e) {
this.e.reply('米游社接口请求失败,暂时无法查询');
e.reply('米游社接口请求失败,暂时无法查询');
return false;
}
this.e = e;
@ -221,6 +240,20 @@ export default class MysZZZApi extends MysApi {
}
return res;
}
/**
* 获取米游社数据
* @param {*} e 消息e
* @param {keyof ZZZApiTool['zzzUrlMap']} type 请求类型
* @param {{deviceFp: string; query: Record<string, any>; headers: object;}} data
* @param {boolean} cached
*/
async getFinalData(e, type, data = {}, cached = false) {
const result = await this.getData(type, data, cached);
const _data = await this.checkCode(e, result, type, {});
if (!_data || _data.retcode !== 0) return false;
return _data.data;
}
}
export function randomString(length) {

View file

@ -15,29 +15,60 @@ export default class ZZZApiTool {
this.server = server;
this.game = 'zzz';
this.uuid = crypto.randomUUID();
if (['prod_gf_cn'].includes(this.server)) {
this.host = 'https://api-takumi.mihoyo.com/';
this.hostRecord = 'https://api-takumi-record.mihoyo.com/';
this.hostPublicData = 'https://public-data-api.mihoyo.com/';
} else {
this.host = 'https://sg-public-api.hoyolab.com/';
this.hostRecord = 'https://bbs-api-os.hoyolab.com/';
this.hostPublicData = 'https://sg-public-data-api.hoyoverse.com/';
}
this.zzzUrlMap = {
zzzUser: {
url: `${this.host}binding/api/getUserGameRolesByCookie`,
query: `game_biz=nap_cn&region=${this.server}&game_uid=${this.uid}`,
},
zzzNote: {
url: `${this.hostRecord}event/game_record_zzz/api/zzz/note`,
query: `role_id=${this.uid}&server=${this.server}`,
},
zzzIndex: {
url: `${this.hostRecord}event/game_record_zzz/api/zzz/index`,
query: `role_id=${this.uid}&server=${this.server}`,
},
zzzAvatarList: {
url: `${this.hostRecord}event/game_record_zzz/api/zzz/avatar/basic`,
query: `role_id=${this.uid}&server=${this.server}`,
},
zzzAvatarInfo: {
url: `${this.hostRecord}event/game_record_zzz/api/zzz/avatar/info`,
query: `role_id=${this.uid}&server=${this.server}&need_wiki=false`,
},
zzzBuddyList: {
url: `${this.hostRecord}event/game_record_zzz/api/zzz/buddy/info`,
query: `role_id=${this.uid}&server=${this.server}`,
},
zzzAuthKey: {
url: `${this.host}binding/api/genAuthKey`,
body: {
auth_appid: 'webview_gacha',
game_biz: 'nap_cn',
game_uid: this.uid * 1,
region: this.server,
},
dsSalt: 'web',
},
};
}
getUrlMap = (data = {}) => {
let host, hostRecord, hostPublicData;
if (['prod_gf_cn'].includes(this.server)) {
host = 'https://api-takumi.mihoyo.com/';
hostRecord = 'https://api-takumi-record.mihoyo.com/';
hostPublicData = 'https://public-data-api.mihoyo.com/';
} else {
host = 'https://sg-public-api.hoyolab.com/';
hostRecord = 'https://bbs-api-os.hoyolab.com/';
hostPublicData = 'https://sg-public-data-api.hoyoverse.com/';
}
let urlMap = {
zzz: {
...(['prod_gf_cn'].includes(this.server)
? {
zzzUser: {
url: `${host}binding/api/getUserGameRolesByCookie`,
query: `game_biz=nap_cn&region=${this.server}&game_uid=${this.uid}`,
},
getFp: {
url: `${hostPublicData}device-fp/api/getFp`,
url: `${this.hostPublicData}device-fp/api/getFp`,
body: {
seed_id: `${generateSeed(16)}`,
device_id: data.deviceId,
@ -51,12 +82,8 @@ export default class ZZZApiTool {
},
}
: {
zzzUser: {
url: `${host}binding/api/getUserGameRolesByCookie`,
query: `game_biz=nap_global&region=${this.server}&game_uid=${this.uid}`,
},
getFp: {
url: `${hostPublicData}device-fp/api/getFp`,
url: `${this.hostPublicData}device-fp/api/getFp`,
body: {
seed_id: `${this.uuid}`,
device_id: '35315696b7071100',
@ -70,45 +97,29 @@ export default class ZZZApiTool {
noDs: true,
},
}),
zzzNote: {
url: `${hostRecord}event/game_record_zzz/api/zzz/note`,
query: `role_id=${this.uid}&server=${this.server}`,
},
zzzIndex: {
url: `${hostRecord}event/game_record_zzz/api/zzz/index`,
query: `role_id=${this.uid}&server=${this.server}`,
},
zzzAvatarList: {
url: `${hostRecord}event/game_record_zzz/api/zzz/avatar/basic`,
query: `role_id=${this.uid}&server=${this.server}`,
},
zzzBuddyList: {
url: `${hostRecord}event/game_record_zzz/api/zzz/buddy/info`,
query: `role_id=${this.uid}&server=${this.server}`,
},
zzzAuthKey: {
url: `${host}binding/api/genAuthKey`,
body: {
auth_appid: 'webview_gacha',
game_biz: 'nap_cn',
game_uid: this.uid * 1,
region: this.server,
},
dsSalt: 'web',
},
...this.zzzUrlMap,
},
};
if (/_us|_eu|_jp|_sg/.test(this.server)) {
urlMap.zzz.zzzNote.url = 'https://sg-act-nap-api.hoyolab.com/event/game_record_zzz/api/zzz/note'
urlMap.zzz.zzzNote.query = `role_id=${this.uid}&server=${this.server}`
urlMap.zzz.zzzIndex.url = 'https://sg-act-nap-api.hoyolab.com/event/game_record_zzz/api/zzz/index'
urlMap.zzz.zzzIndex.query = `lang=zh-cn&role_id=${this.uid}&server=${this.server}`
urlMap.zzz.zzzAvatarList.url = 'https://sg-act-nap-api.hoyolab.com/event/game_record_zzz/api/zzz/avatar/basic'
urlMap.zzz.zzzAvatarList.query = `role_id=${this.uid}&server=${this.server}`
urlMap.zzz.zzzBuddyList.url = 'https://sg-act-nap-api.hoyolab.com/event/game_record_zzz/api/zzz/buddy/info'
urlMap.zzz.zzzBuddyList.query = `role_id=${this.uid}&server=${this.server}`
};
urlMap.zzz.zzzNote.url =
'https://sg-act-nap-api.hoyolab.com/event/game_record_zzz/api/zzz/note';
urlMap.zzz.zzzNote.query = `role_id=${this.uid}&server=${this.server}`;
urlMap.zzz.zzzIndex.url =
'https://sg-act-nap-api.hoyolab.com/event/game_record_zzz/api/zzz/index';
urlMap.zzz.zzzIndex.query = `lang=zh-cn&role_id=${this.uid}&server=${this.server}`;
urlMap.zzz.zzzAvatarList.url =
'https://sg-act-nap-api.hoyolab.com/event/game_record_zzz/api/zzz/avatar/basic';
urlMap.zzz.zzzAvatarList.query = `role_id=${this.uid}&server=${this.server}`;
urlMap.zzz.zzzAvatarInfo.url =
'https://sg-act-nap-api.hoyolab.com/event/game_record_zzz/api/zzz/avatar/info';
urlMap.zzz.zzzAvatarInfo.query = `role_id=${this.uid}&server=${this.server}&need_wiki=false`;
urlMap.zzz.zzzBuddyList.url =
'https://sg-act-nap-api.hoyolab.com/event/game_record_zzz/api/zzz/buddy/info';
urlMap.zzz.zzzBuddyList.query = `role_id=${this.uid}&server=${this.server}`;
urlMap.zzzUser.url = `${this.host}binding/api/getUserGameRolesByCookie`;
urlMap.zzzUser.query = `game_biz=nap_global&region=${this.server}&game_uid=${this.uid}`;
}
return urlMap[this.game];
};
}

View file

@ -4,20 +4,28 @@ import _ from 'lodash';
import NoteUser from '../../genshin/model/mys/NoteUser.js';
export class ZZZPlugin extends plugin {
/**
*
* @returns {Promise<string>}
*/
async getUID() {
let user = this.e;
if (this.e.at) {
user = this.e.at;
}
this.User = await NoteUser.create(user);
let uid = this.e.msg.match(/\d+/)?.[0];
uid = uid || this.User?.getUid('zzz');
// let uid = this.e.msg.match(/\d+/)?.[0];
const uid = this.User?.getUid('zzz');
if (!uid) {
await this.reply('uid为空米游社查询请先绑定cookie其他查询请携带uid');
return false;
}
return uid;
}
/**
*
* @returns {Promise<{api: MysZZZApi, uid: string, deviceFp: string}>}
*/
async getAPI() {
let uid = await this.getUID();
if (!uid) return false;
@ -47,15 +55,17 @@ export class ZZZPlugin extends plugin {
}
return { api, uid, deviceFp };
}
/**
*
* @returns {Promise<boolean | object>}
*/
async getPlayerInfo() {
const { api } = await this.getAPI();
if (!api) return false;
let userData = await api.getData('zzzUser');
if (!userData?.data || _.isEmpty(userData.data.list)) {
await this.reply('[zzznote]玩家信息获取失败');
return false;
}
userData = userData?.data?.list[0];
let userData = await api.getFinalData(this.e, 'zzzUser');
if (!userData) return false;
userData = userData?.list[0];
let avatar = this.e.bot.avatar;
// 头像
if (this.e.member?.getAvatarUrl) {

View file

@ -72,31 +72,34 @@ export class AvatarIconPaths {
*/
export class ZZZAvatarBasic {
/**
* @param {number} id
* @param {number} level
* @param {string} name_mi18n
* @param {string} full_name_mi18n
* @param {number} element_type
* @param {string} camp_name_mi18n
* @param {number} avatar_profession
* @param {string} rarity
* @param {AvatarIconPaths} icon_paths
* @param {number} rank
* @param {boolean} is_chosen
* @param {{
* id: number;
* level: number;
* name_mi18n: string;
* full_name_mi18n: string;
* element_type: number;
* camp_name_mi18n: string;
* avatar_profession: number;
* rarity: string;
* icon_paths: AvatarIconPaths;
* rank: number;
* is_chosen: boolean;
* }} data
*/
constructor(
id,
level,
name_mi18n,
full_name_mi18n,
element_type,
camp_name_mi18n,
avatar_profession,
rarity,
icon_paths,
rank,
is_chosen
) {
constructor(data) {
const {
id,
level,
name_mi18n,
full_name_mi18n,
element_type,
camp_name_mi18n,
avatar_profession,
rarity,
icon_paths,
rank,
is_chosen,
} = data;
this.id = id;
this.level = level;
this.name_mi18n = name_mi18n;
@ -155,6 +158,8 @@ export class ZZZAvatarInfo {
* skills: Skill[];
* rank: number;
* ranks: Rank[];
*
* isNew?: boolean;
* }} data
*/
constructor(data) {
@ -175,6 +180,7 @@ export class ZZZAvatarInfo {
skills,
rank,
ranks,
isNew,
} = data;
this.id = id;
this.level = level;
@ -194,11 +200,17 @@ export class ZZZAvatarInfo {
this.ranks = ranks;
this.element_str = element.IDToElement(element_type);
this.isNew = isNew;
}
async get_assets() {
async get_basic_assets() {
const result = await getSquareAvatar(this.id);
this.square_icon = result;
}
async get_assets() {
await this.get_basic_assets();
}
}
/**