mirror of
https://github.com/asphyxia-core/plugins.git
synced 2026-03-21 17:34:46 -05:00
Merge pull request #42 from thomeval/feature/00_betterMDB
Feature/00 better mdb
This commit is contained in:
commit
1a2e955dd4
|
|
@ -1,6 +1,6 @@
|
|||
GITADORA Plugin for Asphyxia-Core
|
||||
=================================
|
||||

|
||||

|
||||
|
||||
This plugin is based on converted from public-exported Asphyxia's Routes.
|
||||
|
||||
|
|
@ -26,10 +26,18 @@ Known Issues
|
|||
* ~Information dialog keep showing as plugin doesn't store item data currently.~ (Fixed as of version 1.2.1)
|
||||
* Special Premium Encore on Nextage
|
||||
- Bandage solution is implemented. Try it.
|
||||
* Friends and Rivals are unimplemented.
|
||||
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
v1.2.2
|
||||
----------------
|
||||
* Major improvements to the MDB (song data) loader. MDB files can now be in .json, .xml or .b64 format. This applies to both the per-version defaults and custom MDBs. To use a custom MDB, enable it in the web UI, and place a 'custom.xml', 'custom.json' or 'custom.b64' file in the data/mdb subfolder.
|
||||
* Added several player profile stats to the web UI.
|
||||
* MDB loader now logs the number of loaded songs available to GF and DM when in dev mode.
|
||||
* MDB: Fixed "is_secret" field being ignored (always set to false)
|
||||
|
||||
v1.2.1
|
||||
----------------
|
||||
* Secret Music (unlocked songs) are now saved and loaded correctly. Partially fixes Github issue #34. Note that all songs are already marked as unlocked by the server - there is no need to unlock them manually. If you would like to lock them, consider using a custom MDB.
|
||||
|
|
|
|||
3
gitadora@asphyxia/data/mdb/.gitignore
vendored
3
gitadora@asphyxia/data/mdb/.gitignore
vendored
|
|
@ -6,4 +6,5 @@ ex.json
|
|||
mt.json
|
||||
nt.json
|
||||
hv.json
|
||||
custom.xml
|
||||
custom.xml
|
||||
custom.json
|
||||
|
|
@ -1,18 +1,6 @@
|
|||
import Logger from "../../utils/logger";
|
||||
import { CommonMusicData } from "../../models/commonmusicdata";
|
||||
|
||||
export interface CommonMusicDataField {
|
||||
id: KITEM<"s32">;
|
||||
cont_gf: KITEM<"bool">;
|
||||
cont_dm: KITEM<"bool">;
|
||||
is_secret: KITEM<"bool">;
|
||||
is_hot: KITEM<"bool">;
|
||||
data_ver: KITEM<"s32">;
|
||||
diff: KARRAY<"u16">;
|
||||
}
|
||||
|
||||
export interface CommonMusicData {
|
||||
music: CommonMusicDataField[]
|
||||
}
|
||||
|
||||
export enum DATAVersion {
|
||||
HIGHVOLTAGE = "hv",
|
||||
|
|
@ -21,6 +9,9 @@ export enum DATAVersion {
|
|||
MATTIX = "mt"
|
||||
}
|
||||
|
||||
const allowedFormats = ['.json', '.xml', '.b64']
|
||||
const mdbFolder = "data/mdb/"
|
||||
|
||||
type processRawDataHandler = (path: string) => Promise<CommonMusicData>
|
||||
|
||||
const logger = new Logger("mdb")
|
||||
|
|
@ -32,30 +23,43 @@ export async function readXML(path: string) {
|
|||
return json
|
||||
}
|
||||
|
||||
export async function readJSON(path: string) {
|
||||
logger.debugInfo(`Loading MDB data from ${path}.`)
|
||||
const str = await IO.ReadFile(path, 'utf-8');
|
||||
const json = JSON.parse(str)
|
||||
return json
|
||||
}
|
||||
export async function readMDBFile(path: string, processHandler?: processRawDataHandler): Promise<CommonMusicData> {
|
||||
|
||||
export async function readJSONOrXML(jsonPath: string, xmlPath: string, processHandler: processRawDataHandler): Promise<CommonMusicData> {
|
||||
if (!IO.Exists(jsonPath)) {
|
||||
logger.debugInfo(`Loading MDB data from ${xmlPath}.`)
|
||||
const data = await processHandler(xmlPath)
|
||||
await IO.WriteFile(jsonPath, JSON.stringify(data))
|
||||
return data
|
||||
} else {
|
||||
logger.debugInfo(`Loading MDB data from ${jsonPath}.`)
|
||||
const json = JSON.parse(await IO.ReadFile(jsonPath, 'utf-8'))
|
||||
return json
|
||||
if (!IO.Exists(path)) {
|
||||
throw "Unable to find MDB file at " + path
|
||||
}
|
||||
}
|
||||
|
||||
export async function readB64JSON(b64path: string) {
|
||||
logger.debugInfo(`Loading MDB data from ${b64path}.`)
|
||||
const buff = await IO.ReadFile(b64path, 'utf-8');
|
||||
return JSON.parse(Buffer.from(buff, 'base64').toString('utf-8'));
|
||||
logger.debugInfo(`Loading MDB data from ${path}.`)
|
||||
|
||||
let result : CommonMusicData;
|
||||
const fileType = path.substring(path.lastIndexOf('.')).toLowerCase()
|
||||
|
||||
switch (fileType) {
|
||||
case '.json':
|
||||
const str = await IO.ReadFile(path, 'utf-8');
|
||||
result = JSON.parse(str)
|
||||
break;
|
||||
case '.xml':
|
||||
processHandler ?? defaultProcessRawXmlData
|
||||
result = await processHandler(path)
|
||||
// Uncomment to save the loaded XML file as JSON.
|
||||
// await IO.WriteFile(path.replace(".xml", ".json"), JSON.stringify(data))
|
||||
break;
|
||||
case '.b64':
|
||||
const buff = await IO.ReadFile(path, 'utf-8');
|
||||
const json = Buffer.from(buff, 'base64').toString('utf-8')
|
||||
// Uncomment to save the decoded base64 file as JSON.
|
||||
// await IO.WriteFile(path.replace(".b64",".json"), json)
|
||||
result = JSON.parse(json)
|
||||
break;
|
||||
default:
|
||||
throw `Invalid MDB file type: ${fileType}. Only .json, .xml, .b64 are supported.`
|
||||
}
|
||||
|
||||
let gfCount = result.music.filter((e) => e.cont_gf["@content"][0]).length
|
||||
let dmCount = result.music.filter((e) => e.cont_dm["@content"][0]).length
|
||||
logger.debugInfo(`Loaded ${result.music.length} songs from MDB file. ${gfCount} songs for GF, ${dmCount} songs for DM.`)
|
||||
return result
|
||||
}
|
||||
|
||||
export function gameVerToDataVer(ver: string): DATAVersion {
|
||||
|
|
@ -72,18 +76,47 @@ export function gameVerToDataVer(ver: string): DATAVersion {
|
|||
}
|
||||
}
|
||||
|
||||
export async function processDataBuilder(gameVer: string, processHandler?: processRawDataHandler) {
|
||||
const ver = gameVerToDataVer(gameVer)
|
||||
const base = `data/mdb/${ver}`
|
||||
if (IO.Exists(`${base}.b64`)) {
|
||||
return await readB64JSON(`${base}.b64`);
|
||||
/**
|
||||
* Attempts to find a .json, .xml, or .b64 file (in that order) matching the given name in the specified folder.
|
||||
* @param fileNameWithoutExtension - The name of the file to find (without the extension).
|
||||
* @param path - The path to the folder to search. If left null, the default MDB folder ('data/mdb' in the plugin folder) will be used.
|
||||
* @returns - The path of the first matching file found, or null if no file was found.
|
||||
*/
|
||||
export function findMDBFile(fileNameWithoutExtension: string, path: string = null): string {
|
||||
|
||||
path = path ?? mdbFolder
|
||||
if (!IO.Exists(path)) {
|
||||
throw `Path does not exist: ${path}`
|
||||
}
|
||||
const { music } = await readJSONOrXML(`${base}.json`, `${base}.xml`, processHandler ?? defaultProcessRawData)
|
||||
// await IO.WriteFile(`${base}.b64`, Buffer.from(JSON.stringify({music})).toString("base64"))
|
||||
return { music };
|
||||
|
||||
if (!path.endsWith("/")) {
|
||||
path += "/"
|
||||
}
|
||||
|
||||
for (const ext of allowedFormats) {
|
||||
const filePath = path + fileNameWithoutExtension + ext
|
||||
if (IO.Exists(filePath)) {
|
||||
return filePath
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export async function defaultProcessRawData(path: string): Promise<CommonMusicData> {
|
||||
export async function loadSongsForGameVersion(gameVer: string, processHandler?: processRawDataHandler) {
|
||||
const ver = gameVerToDataVer(gameVer)
|
||||
|
||||
let mdbFile = findMDBFile(ver, mdbFolder)
|
||||
|
||||
if (mdbFile == null) {
|
||||
throw `No valid MDB files were found in the data/mdb subfolder. Ensure that this folder contains at least one of the following: ${ver}.json, ${ver}.xml or ${ver}.b64`
|
||||
}
|
||||
|
||||
const music = await readMDBFile(mdbFile, processHandler ?? defaultProcessRawXmlData)
|
||||
return music
|
||||
}
|
||||
|
||||
export async function defaultProcessRawXmlData(path: string): Promise<CommonMusicData> {
|
||||
const data = await readXML(path)
|
||||
const mdb = $(data).elements("mdb.mdb_data");
|
||||
const music: any[] = [];
|
||||
|
|
@ -106,7 +139,7 @@ export async function defaultProcessRawData(path: string): Promise<CommonMusicDa
|
|||
id: K.ITEM('s32', m.number("music_id")),
|
||||
cont_gf: K.ITEM('bool', gf == 0 ? 0 : 1),
|
||||
cont_dm: K.ITEM('bool', dm == 0 ? 0 : 1),
|
||||
is_secret: K.ITEM('bool', 0),
|
||||
is_secret: K.ITEM('bool', m.number("is_secret", 0)),
|
||||
is_hot: K.ITEM('bool', type == 2 ? 0 : 1),
|
||||
data_ver: K.ITEM('s32', m.number("data_ver", 115)),
|
||||
diff: K.ARRAY('u16', [
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
import { getVersion } from "../utils";
|
||||
import { defaultProcessRawData, processDataBuilder } from "../data/mdb"
|
||||
import { CommonMusicDataField, readJSONOrXML, readXML } from "../data/mdb";
|
||||
import { CommonMusicDataField, findMDBFile, readMDBFile, loadSongsForGameVersion } from "../data/mdb";
|
||||
import Logger from "../utils/logger"
|
||||
|
||||
const logger = new Logger("MusicList")
|
||||
|
||||
export const playableMusic: EPR = async (info, data, send) => {
|
||||
const version = getVersion(info);
|
||||
|
||||
let music: CommonMusicDataField[] = [];
|
||||
try {
|
||||
if (U.GetConfig("enable_custom_mdb")) {
|
||||
music = (await defaultProcessRawData('data/mdb/custom.xml')).music
|
||||
let customMdb = findMDBFile("custom")
|
||||
music = (await readMDBFile(customMdb)).music
|
||||
}
|
||||
} catch (e) {
|
||||
logger.warn("Read Custom MDB failed. Using default MDB as a fallback.")
|
||||
|
|
@ -19,10 +20,15 @@ export const playableMusic: EPR = async (info, data, send) => {
|
|||
}
|
||||
|
||||
if (music.length == 0) {
|
||||
music = _.get(await processDataBuilder(version), 'music', []);
|
||||
music = (await loadSongsForGameVersion(version)).music
|
||||
}
|
||||
|
||||
await send.object({
|
||||
let response = getPlayableMusicResponse(music)
|
||||
await send.object(response)
|
||||
};
|
||||
|
||||
function getPlayableMusicResponse(music) {
|
||||
return {
|
||||
hot: {
|
||||
major: K.ITEM('s32', 1),
|
||||
minor: K.ITEM('s32', 1),
|
||||
|
|
@ -30,5 +36,5 @@ export const playableMusic: EPR = async (info, data, send) => {
|
|||
musicinfo: K.ATTR({ nr: `${music.length}` }, {
|
||||
music,
|
||||
}),
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
import { getEncoreStageData } from "../data/extrastage";
|
||||
import Logger from "../utils/logger";
|
||||
|
||||
const logger = new Logger('info');
|
||||
export const shopInfoRegist: EPR = async (info, data, send) => {
|
||||
send.object({
|
||||
data: {
|
||||
|
|
@ -16,64 +18,8 @@ export const shopInfoRegist: EPR = async (info, data, send) => {
|
|||
}
|
||||
|
||||
export const gameInfoGet: EPR = async (info, data, send) => {
|
||||
const addition: any = {
|
||||
monstar_subjugation: {
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
bear_fes: {},
|
||||
nextadium: {},
|
||||
};
|
||||
const time = BigInt(31536000);
|
||||
for (let i = 1; i <= 20; ++i) {
|
||||
const obj = {
|
||||
term: K.ITEM('u8', 0),
|
||||
start_date_ms: K.ITEM('u64', time),
|
||||
end_date_ms: K.ITEM('u64', time),
|
||||
};
|
||||
if (i == 1) {
|
||||
addition[`phrase_combo_challenge`] = obj;
|
||||
addition[`long_otobear_fes_1`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
start_date_ms: K.ITEM('u64', time),
|
||||
end_date_ms: K.ITEM('u64', time),
|
||||
bonus_musicid: {},
|
||||
};
|
||||
addition[`sdvx_stamprally3`] = obj;
|
||||
addition[`chronicle_1`] = obj;
|
||||
addition[`paseli_point_lottery`] = obj;
|
||||
addition['sticker_campaign'] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
sticker_list: {},
|
||||
};
|
||||
addition['thanksgiving'] = {
|
||||
...obj,
|
||||
box_term: {
|
||||
state: K.ITEM('u8', 0)
|
||||
}
|
||||
};
|
||||
addition['lotterybox'] = {
|
||||
...obj,
|
||||
box_term: {
|
||||
state: K.ITEM('u8', 0)
|
||||
}
|
||||
};
|
||||
} else {
|
||||
addition[`phrase_combo_challenge_${i}`] = obj;
|
||||
}
|
||||
|
||||
if (i <= 4) {
|
||||
addition['monstar_subjugation'][`monstar_subjugation_${i}`] = obj;
|
||||
addition['bear_fes'][`bear_fes_${i}`] = obj;
|
||||
}
|
||||
|
||||
if (i <= 3) {
|
||||
addition[`kouyou_challenge_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const eventData = getEventDataResponse()
|
||||
const extraData = getEncoreStageData(info)
|
||||
|
||||
await send.object({
|
||||
|
|
@ -157,6 +103,70 @@ export const gameInfoGet: EPR = async (info, data, send) => {
|
|||
},
|
||||
},
|
||||
},
|
||||
...addition,
|
||||
...eventData,
|
||||
});
|
||||
};
|
||||
|
||||
function getEventDataResponse() {
|
||||
const addition: any = {
|
||||
monstar_subjugation: {
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
},
|
||||
bear_fes: {},
|
||||
nextadium: {},
|
||||
};
|
||||
const time = BigInt(31536000);
|
||||
|
||||
for (let i = 1; i <= 20; ++i) {
|
||||
const obj = {
|
||||
term: K.ITEM('u8', 0),
|
||||
start_date_ms: K.ITEM('u64', time),
|
||||
end_date_ms: K.ITEM('u64', time),
|
||||
};
|
||||
if (i == 1) {
|
||||
addition[`phrase_combo_challenge`] = obj;
|
||||
addition[`long_otobear_fes_1`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
start_date_ms: K.ITEM('u64', time),
|
||||
end_date_ms: K.ITEM('u64', time),
|
||||
bonus_musicid: {},
|
||||
};
|
||||
addition[`sdvx_stamprally3`] = obj;
|
||||
addition[`chronicle_1`] = obj;
|
||||
addition[`paseli_point_lottery`] = obj;
|
||||
addition['sticker_campaign'] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
sticker_list: {},
|
||||
};
|
||||
addition['thanksgiving'] = {
|
||||
...obj,
|
||||
box_term: {
|
||||
state: K.ITEM('u8', 0)
|
||||
}
|
||||
};
|
||||
addition['lotterybox'] = {
|
||||
...obj,
|
||||
box_term: {
|
||||
state: K.ITEM('u8', 0)
|
||||
}
|
||||
};
|
||||
} else {
|
||||
|
||||
addition[`phrase_combo_challenge_${i}`] = obj;
|
||||
}
|
||||
|
||||
if (i <= 4) {
|
||||
addition['monstar_subjugation'][`monstar_subjugation_${i}`] = obj;
|
||||
addition['bear_fes'][`bear_fes_${i}`] = obj;
|
||||
}
|
||||
|
||||
if (i <= 3) {
|
||||
addition[`kouyou_challenge_${i}`] = {
|
||||
term: K.ITEM('u8', 0),
|
||||
bonus_musicid: K.ITEM('s32', 0),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return addition
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import { Record } from "../models/record";
|
|||
import { Extra } from "../models/extra";
|
||||
import { getVersion, isDM } from "../utils";
|
||||
import { Scores } from "../models/scores";
|
||||
import { PlayerStickerResponse } from "../models/playerstickerresponse";
|
||||
import { SecretMusicResponse } from "../models/secretmusicresponse";
|
||||
import { PLUGIN_VER } from "../const";
|
||||
import Logger from "../utils/logger"
|
||||
import { isAsphyxiaDebugMode } from "../Utils/index";
|
||||
|
|
@ -230,38 +232,7 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
}));
|
||||
}
|
||||
|
||||
const sticker: any[] = [];
|
||||
|
||||
if (_.isArray(name.card)) {
|
||||
for (const item of name.card) {
|
||||
const id = _.get(item, 'id');
|
||||
const posX = _.get(item, 'position.0');
|
||||
const posY = _.get(item, 'position.1');
|
||||
const scaleX = _.get(item, 'scale.0');
|
||||
const scaleY = _.get(item, 'scale.1');
|
||||
const rotation = _.get(item, 'rotation');
|
||||
|
||||
if (
|
||||
!isFinite(id) ||
|
||||
!isFinite(posX) ||
|
||||
!isFinite(posY) ||
|
||||
!isFinite(scaleX) ||
|
||||
!isFinite(scaleY) ||
|
||||
!isFinite(rotation)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
sticker.push({
|
||||
id: K.ITEM('s32', id),
|
||||
pos_x: K.ITEM('float', posX),
|
||||
pos_y: K.ITEM('float', posY),
|
||||
scale_x: K.ITEM('float', scaleX),
|
||||
scale_y: K.ITEM('float', scaleY),
|
||||
rotate: K.ITEM('float', rotation),
|
||||
});
|
||||
}
|
||||
}
|
||||
const sticker: PlayerStickerResponse[] = getPlayerStickers(name.card);
|
||||
|
||||
const playerData: any = {
|
||||
playerboard: {
|
||||
|
|
@ -376,6 +347,7 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
}
|
||||
|
||||
const innerSecretMusic = getSecretMusicResponse(profile)
|
||||
const innerFriendData = getFriendDataResponse(profile)
|
||||
|
||||
const response = {
|
||||
player: K.ATTR({ 'no': `${no}` }, {
|
||||
|
|
@ -392,7 +364,10 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
status: K.ARRAY('u32', extra.reward_status ?? Array(50).fill(0)),
|
||||
},
|
||||
rivaldata: {},
|
||||
frienddata: {},
|
||||
frienddata: {
|
||||
friend: innerFriendData
|
||||
},
|
||||
|
||||
thanks_medal: {
|
||||
medal: K.ITEM('s32', 0),
|
||||
grant_medal: K.ITEM('s32', 0),
|
||||
|
|
@ -527,6 +502,42 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
send.object(response);
|
||||
}
|
||||
|
||||
function getPlayerStickers(playerCard) : PlayerStickerResponse[] {
|
||||
let stickers : PlayerStickerResponse[] = []
|
||||
if (_.isArray(playerCard)) {
|
||||
for (const item of playerCard) {
|
||||
const id = _.get(item, 'id');
|
||||
const posX = _.get(item, 'position.0');
|
||||
const posY = _.get(item, 'position.1');
|
||||
const scaleX = _.get(item, 'scale.0');
|
||||
const scaleY = _.get(item, 'scale.1');
|
||||
const rotation = _.get(item, 'rotation');
|
||||
|
||||
if (
|
||||
!isFinite(id) ||
|
||||
!isFinite(posX) ||
|
||||
!isFinite(posY) ||
|
||||
!isFinite(scaleX) ||
|
||||
!isFinite(scaleY) ||
|
||||
!isFinite(rotation)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
stickers.push({
|
||||
id: K.ITEM('s32', id),
|
||||
pos_x: K.ITEM('float', posX),
|
||||
pos_y: K.ITEM('float', posY),
|
||||
scale_x: K.ITEM('float', scaleX),
|
||||
scale_y: K.ITEM('float', scaleY),
|
||||
rotate: K.ITEM('float', rotation),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return stickers
|
||||
}
|
||||
|
||||
async function getOrRegisterPlayerInfo(refid: string, version: string, no: number) {
|
||||
let playerInfo = await DB.FindOne<PlayerInfo>(refid, {
|
||||
collection: 'playerinfo',
|
||||
|
|
@ -953,6 +964,8 @@ async function saveSinglePlayer(dataplayer: KDataReader, refid: string, no: numb
|
|||
await DB.Upsert(refid, { collection: 'extra', game, version }, extra)
|
||||
|
||||
const playedStages = dataplayer.elements('stage');
|
||||
// logStagesPlayed(playedStages)
|
||||
|
||||
const scores = await updatePlayerScoreCollection(refid, playedStages, version, game)
|
||||
await saveScore(refid, version, game, scores);
|
||||
}
|
||||
|
|
@ -1122,8 +1135,8 @@ function parseSecretMusic(playerData: KDataReader) : SecretMusicEntry[]
|
|||
return response
|
||||
}
|
||||
|
||||
function getSecretMusicResponse(profile: Profile) {
|
||||
let response = []
|
||||
function getSecretMusicResponse(profile: Profile) : SecretMusicResponse[] {
|
||||
let response : SecretMusicResponse[] = []
|
||||
|
||||
if (!profile.secretmusic?.music ) {
|
||||
return response
|
||||
|
|
@ -1140,3 +1153,19 @@ function getSecretMusicResponse(profile: Profile) {
|
|||
return response
|
||||
}
|
||||
|
||||
function getFriendDataResponse(profile: Profile) {
|
||||
let response = []
|
||||
return response;
|
||||
}
|
||||
|
||||
function logStagesPlayed(playedStages: KDataReader[]) {
|
||||
|
||||
let result = "Stages played: "
|
||||
for (let stage of playedStages) {
|
||||
let id = stage.number('musicid')
|
||||
result += `${id}, `
|
||||
}
|
||||
|
||||
logger.debugLog(result)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,14 +25,15 @@ export function register() {
|
|||
name: "Dummy Encore for SPE (Nextage Only)",
|
||||
desc: "Since Nextage's Special Premium Encore system is bit complicated, \n"
|
||||
+ "SPE System isn't fully implemented. \n"
|
||||
+ "This thing is bandage of these problem as limiting some Encores for SPE.",
|
||||
+ "This option is a workaround for this issue as limiting some Encores for SPE.",
|
||||
type: "boolean",
|
||||
default: false
|
||||
})
|
||||
|
||||
R.Config("enable_custom_mdb", {
|
||||
name: "Enable Custom MDB",
|
||||
desc: "For who uses own MDB. eg) Omnimix.",
|
||||
desc: "If disabled, the server will provide the default MDB (song list) to Gitadora clients, depending on which version of the game they are running." +
|
||||
"Enable this option to provide your own custom MDB instead. MDB files are stored in the 'gitadora@asphyxia/data/mdb' folder, and can be in .xml, .json or .b64 format.",
|
||||
type: "boolean",
|
||||
default: false,
|
||||
})
|
||||
|
|
@ -40,7 +41,7 @@ export function register() {
|
|||
R.DataFile("data/mdb/custom.xml", {
|
||||
accept: ".xml",
|
||||
name: "Custom MDB",
|
||||
desc: "You need to enable Custom MDB option first."
|
||||
desc: "You need to enable the 'Enable Custom MDB' option for the uploaded file to have any effect."
|
||||
})
|
||||
|
||||
R.WebUIEvent('updatePlayerInfo', updatePlayerInfo);
|
||||
|
|
|
|||
13
gitadora@asphyxia/models/commonmusicdata.ts
Normal file
13
gitadora@asphyxia/models/commonmusicdata.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
export interface CommonMusicDataField {
|
||||
id: KITEM<"s32">;
|
||||
cont_gf: KITEM<"bool">;
|
||||
cont_dm: KITEM<"bool">;
|
||||
is_secret: KITEM<"bool">;
|
||||
is_hot: KITEM<"bool">;
|
||||
data_ver: KITEM<"s32">;
|
||||
diff: KARRAY<"u16">;
|
||||
}
|
||||
|
||||
export interface CommonMusicData {
|
||||
music: CommonMusicDataField[]
|
||||
}
|
||||
8
gitadora@asphyxia/models/playerstickerresponse.ts
Normal file
8
gitadora@asphyxia/models/playerstickerresponse.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
export interface PlayerStickerResponse {
|
||||
id: KITEM<'s32'>,
|
||||
pos_x: KITEM<'float'> ,
|
||||
pos_y: KITEM<'float'>,
|
||||
scale_x: KITEM<'float'> ,
|
||||
scale_y: KITEM<'float'>,
|
||||
rotate: KITEM<'float'>
|
||||
}
|
||||
|
|
@ -2,4 +2,4 @@ export interface SecretMusicEntry {
|
|||
musicid: number;
|
||||
seq: number;
|
||||
kind: number;
|
||||
}
|
||||
}
|
||||
5
gitadora@asphyxia/models/secretmusicresponse.ts
Normal file
5
gitadora@asphyxia/models/secretmusicresponse.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export interface SecretMusicResponse {
|
||||
musicid: KITEM<'s32'>;
|
||||
seq: KITEM<'u16'>;
|
||||
kind: KITEM<'s32'>;
|
||||
}
|
||||
|
|
@ -7,7 +7,6 @@ export default class Logger {
|
|||
this.category = (category == null) ? null : `[${category}]`
|
||||
}
|
||||
|
||||
|
||||
public error(...args: any[]) {
|
||||
this.argsHandler(console.error, ...args)
|
||||
}
|
||||
|
|
@ -18,7 +17,6 @@ export default class Logger {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public warn(...args: any[]) {
|
||||
this.argsHandler(console.warn, ...args)
|
||||
}
|
||||
|
|
@ -29,7 +27,6 @@ export default class Logger {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public info(...args: any[]) {
|
||||
this.argsHandler(console.info, ...args)
|
||||
}
|
||||
|
|
@ -40,7 +37,6 @@ export default class Logger {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public log(...args: any[]) {
|
||||
this.argsHandler(console.log, ...args)
|
||||
}
|
||||
|
|
@ -51,7 +47,6 @@ export default class Logger {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private argsHandler(target: Function, ...args: any[]) {
|
||||
if (this.category == null) {
|
||||
target(...args)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,19 @@
|
|||
//DATA//
|
||||
info: DB.Find(refid, { collection: 'playerinfo' })
|
||||
profile: DB.Find(refid, { collection: 'profile' })
|
||||
-
|
||||
|
||||
-
|
||||
function getFullGameName(shortName) {
|
||||
switch (shortName) {
|
||||
case "dm" :
|
||||
return "Drummania"
|
||||
case "gf":
|
||||
return "Guitar Freaks"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
-
|
||||
|
||||
div
|
||||
|
|
@ -33,4 +46,39 @@ div
|
|||
button.button.is-primary(type="submit")
|
||||
span.icon
|
||||
i.mdi.mdi-check
|
||||
span Submit
|
||||
span Submit
|
||||
|
||||
div
|
||||
each pr in profile
|
||||
.card
|
||||
.card-header
|
||||
p.card-header-title
|
||||
span.icon
|
||||
i.mdi.mdi-account-details
|
||||
| Profile Detail (#{getFullGameName(pr.game)} #{pr.version})
|
||||
.card-content
|
||||
form(method="post")
|
||||
.field
|
||||
label.label Skill
|
||||
.control
|
||||
input.input(type="text" name="skill", value=(pr.skill/100) readonly)
|
||||
.field
|
||||
label.label Skill (All Songs)
|
||||
.control
|
||||
input.input(type="text" name="all_skill", value=(pr.all_skill/100) readonly)
|
||||
.field
|
||||
label.label Stages Cleared
|
||||
.control
|
||||
input.input(type="text" name="clear_num", value=pr.clear_num readonly)
|
||||
.field
|
||||
label.label Full Combos
|
||||
.control
|
||||
input.input(type="text" name="full_num", value=pr.full_num readonly)
|
||||
.field
|
||||
label.label Excellent Full Combos
|
||||
.control
|
||||
input.input(type="text" name="exce_num", value=pr.exce_num readonly)
|
||||
.field
|
||||
label.label Sessions
|
||||
.control
|
||||
input.input(type="text" name="session_cnt", value=pr.session_cnt readonly)
|
||||
Loading…
Reference in New Issue
Block a user