Merge branch 'asphyxia-core:stable' into stable
|
|
@ -11,6 +11,20 @@ export function getEncoreStageData(info: EamuseInfo): EncoreStageData {
|
|||
const level: number = U.GetConfig("encore_version")
|
||||
const ntDummyEncore = U.GetConfig("nextage_dummy_encore")
|
||||
switch (getVersion(info)) {
|
||||
case 'highvoltage':
|
||||
return {
|
||||
level,
|
||||
musics: [
|
||||
2686, // CYCLONICxSTORM
|
||||
2687, // Heptagram
|
||||
2700, // Saiph
|
||||
2706, // LUCID NIGHTMARE
|
||||
2740, // Mobius
|
||||
2748, // Under The Shades Of The Divine Ray
|
||||
2772, // REBELLION
|
||||
2812, // THE LAST OF FIREFACE
|
||||
]
|
||||
}
|
||||
case 'nextage':
|
||||
return {
|
||||
level,
|
||||
|
|
|
|||
1
gitadora@asphyxia/data/mdb/hv.b64
Normal file
|
|
@ -42,7 +42,7 @@ export async function readMDBFile(path: string, processHandler?: processRawDataH
|
|||
processHandler = 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))
|
||||
// await IO.WriteFile(path.replace(".xml", ".json"), JSON.stringify(result))
|
||||
break;
|
||||
case '.b64':
|
||||
const buff = await IO.ReadFile(path, 'utf-8');
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Extra } from "../models/extra";
|
||||
import { FavoriteMusic } from "../models/favoritemusic";
|
||||
import { isSharedFavoriteMusicEnabled } from "../utils";
|
||||
import { isSharedFavoriteMusicEnabled } from "../utils/index";
|
||||
import Logger from "../utils/logger";
|
||||
|
||||
const logger = new Logger("FavoriteMusic");
|
||||
|
|
|
|||
|
|
@ -102,22 +102,22 @@ export const getPlayer: EPR = async (info, data, send) => {
|
|||
musicdata.push(K.ATTR({ musicid }, {
|
||||
mdata: K.ARRAY('s16', [
|
||||
-1,
|
||||
_.get(score, 'diffs.1.perc', -2),
|
||||
_.get(score, 'diffs.2.perc', -2),
|
||||
_.get(score, 'diffs.3.perc', -2),
|
||||
_.get(score, 'diffs.4.perc', -2),
|
||||
_.get(score, 'diffs.5.perc', -2),
|
||||
_.get(score, 'diffs.6.perc', -2),
|
||||
_.get(score, 'diffs.7.perc', -2),
|
||||
_.get(score, 'diffs.8.perc', -2),
|
||||
_.get(score, 'diffs.1.rank', 0),
|
||||
_.get(score, 'diffs.2.rank', 0),
|
||||
_.get(score, 'diffs.3.rank', 0),
|
||||
_.get(score, 'diffs.4.rank', 0),
|
||||
_.get(score, 'diffs.5.rank', 0),
|
||||
_.get(score, 'diffs.6.rank', 0),
|
||||
_.get(score, 'diffs.7.rank', 0),
|
||||
_.get(score, 'diffs.8.rank', 0),
|
||||
_.get(score, 'diffs.1.clear', false) ? _.get(score, 'diffs.1.perc', -2) : -1,
|
||||
_.get(score, 'diffs.2.clear', false) ? _.get(score, 'diffs.2.perc', -2) : -1,
|
||||
_.get(score, 'diffs.3.clear', false) ? _.get(score, 'diffs.3.perc', -2) : -1,
|
||||
_.get(score, 'diffs.4.clear', false) ? _.get(score, 'diffs.4.perc', -2) : -1,
|
||||
_.get(score, 'diffs.5.clear', false) ? _.get(score, 'diffs.5.perc', -2) : -1,
|
||||
_.get(score, 'diffs.6.clear', false) ? _.get(score, 'diffs.6.perc', -2) : -1,
|
||||
_.get(score, 'diffs.7.clear', false) ? _.get(score, 'diffs.7.perc', -2) : -1,
|
||||
_.get(score, 'diffs.8.clear', false) ? _.get(score, 'diffs.8.perc', -2) : -1,
|
||||
_.get(score, 'diffs.1.clear', false) ? _.get(score, 'diffs.1.rank', 0) : -1,
|
||||
_.get(score, 'diffs.2.clear', false) ? _.get(score, 'diffs.2.rank', 0) : -1,
|
||||
_.get(score, 'diffs.3.clear', false) ? _.get(score, 'diffs.3.rank', 0) : -1,
|
||||
_.get(score, 'diffs.4.clear', false) ? _.get(score, 'diffs.4.rank', 0) : -1,
|
||||
_.get(score, 'diffs.5.clear', false) ? _.get(score, 'diffs.5.rank', 0) : -1,
|
||||
_.get(score, 'diffs.6.clear', false) ? _.get(score, 'diffs.6.rank', 0) : -1,
|
||||
_.get(score, 'diffs.7.clear', false) ? _.get(score, 'diffs.7.rank', 0) : -1,
|
||||
_.get(score, 'diffs.8.clear', false) ? _.get(score, 'diffs.8.rank', 0) : -1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -629,6 +629,7 @@ async function updatePlayerScoreCollection(refid, playedStages, version, game) {
|
|||
const clear = stage.bool('clear');
|
||||
const fc = stage.bool('fullcombo');
|
||||
const ex = stage.bool('excellent');
|
||||
const newMeter = stage.bool('is_new_meter');
|
||||
|
||||
const perc = stage.number('perc', 0);
|
||||
const rank = stage.number('rank', 0);
|
||||
|
|
@ -650,7 +651,7 @@ async function updatePlayerScoreCollection(refid, playedStages, version, game) {
|
|||
scores[mid].diffs[seq] = { //FIXME: Real server is bit complicated. this one is too buggy.
|
||||
perc: Math.max(_.get(scores[mid].diffs[seq], 'perc', 0), perc),
|
||||
rank: Math.max(_.get(scores[mid].diffs[seq], 'rank', 0), rank),
|
||||
meter: meter.toString(),
|
||||
meter: newMeter ? meter.toString() : _.get(scores[mid].diffs[seq], 'meter', 0),
|
||||
prog: Math.max(_.get(scores[mid].diffs[seq], 'prog', 0), prog),
|
||||
clear: _.get(scores[mid].diffs[seq], 'clear') || clear,
|
||||
fc: _.get(scores[mid].diffs[seq], 'fc') || fc,
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ export function register() {
|
|||
R.Route(`exchain_${method}`, handler);
|
||||
R.Route(`matixx_${method}`, handler);
|
||||
R.Route(`nextage_${method}`, handler)
|
||||
R.Route(`highvoltage_${method}`, handler)
|
||||
// TODO: TB, TBRE and more older version?
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -7,15 +7,28 @@
|
|||
function getFullGameName(shortName) {
|
||||
switch (shortName) {
|
||||
case "dm" :
|
||||
return "Drummania"
|
||||
case "gf":
|
||||
return "Guitar Freaks"
|
||||
default:
|
||||
return "DrumMania"
|
||||
case "gf":
|
||||
return "GuitarFreaks"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
const versions = ["exchain", "nextage"]
|
||||
function getFullVersionName(shortName) {
|
||||
switch (shortName) {
|
||||
case "exchain" :
|
||||
return "GITADORA EXCHAIN"
|
||||
case "nextage":
|
||||
return "GITADORA NEX+AGE"
|
||||
case "highvoltage":
|
||||
return "GITADORA HIGH-VOLTAGE"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
const versions = ["exchain", "nextage", "highvoltage"]
|
||||
const games = ["gf", "dm"]
|
||||
|
||||
function generateLeaderboards(infos, profiles) {
|
||||
|
|
@ -64,7 +77,7 @@
|
|||
-
|
||||
|
||||
each board in generateLeaderboards(infos, profiles)
|
||||
h3 #{getFullGameName(board.game)} #{board.version}
|
||||
h3 #{getFullVersionName(board.version)} #{getFullGameName(board.game)}
|
||||
table
|
||||
tr
|
||||
th Rank
|
||||
|
|
|
|||
|
|
@ -1,84 +1,101 @@
|
|||
import Profile from "../models/profile";
|
||||
import { Score } from "../models/score";
|
||||
import Profile from '../models/profile';
|
||||
import { Score } from '../models/score';
|
||||
|
||||
export const getProfile = async (info: EamuseInfo, data: any, send: EamuseSend) => {
|
||||
console.log("gametop.regist");
|
||||
let refId = $(data).str("data.player.refid");
|
||||
const name = $(data).str("data.player.name");
|
||||
export const getProfile = async (
|
||||
info: EamuseInfo,
|
||||
data: any,
|
||||
send: EamuseSend
|
||||
) => {
|
||||
console.log('gametop.regist');
|
||||
let refId = $(data).str('data.player.refid');
|
||||
const name = $(data).str('data.player.name');
|
||||
|
||||
console.log(data, {depth:null});
|
||||
if (!refId) return send.deny();
|
||||
console.log(data, { depth: null });
|
||||
if (!refId) return send.deny();
|
||||
|
||||
let profile = await DB.FindOne<Profile>(refId, { collection: "profile" });
|
||||
|
||||
if (!profile && name) {
|
||||
const newProfile: Profile = {
|
||||
collection: "profile",
|
||||
jubeatId: Math.round(Math.random() * 99999999),
|
||||
eventFlag: 0,
|
||||
name: name,
|
||||
isFirstplay: true,
|
||||
emo: [],
|
||||
lastShopname: "",
|
||||
lastAreaname: ""
|
||||
};
|
||||
|
||||
await DB.Upsert<Profile>(refId, { collection: "profile" }, newProfile);
|
||||
|
||||
profile = newProfile;
|
||||
}else if (!profile && !name) {
|
||||
return send.deny();
|
||||
}
|
||||
let profile = await DB.FindOne<Profile>(refId, { collection: 'profile' });
|
||||
|
||||
return send.object({
|
||||
data: {
|
||||
...require("../templates/gameInfos.ts")(),
|
||||
if (!profile && name) {
|
||||
const newProfile: Profile = {
|
||||
collection: 'profile',
|
||||
jubeatId: Math.round(Math.random() * 99999999),
|
||||
eventFlag: 0,
|
||||
name: name,
|
||||
isFirstplay: true,
|
||||
emo: [],
|
||||
lastShopname: '',
|
||||
lastAreaname: '',
|
||||
};
|
||||
|
||||
player: {
|
||||
|
||||
jid: K.ITEM("s32", profile.jubeatId),
|
||||
session_id: K.ITEM("s32", 1),
|
||||
name: K.ITEM("str", profile.name),
|
||||
event_flag: K.ITEM("u64", BigInt(profile.eventFlag || 0)),
|
||||
await DB.Upsert<Profile>(refId, { collection: 'profile' }, newProfile);
|
||||
|
||||
...await require("../templates/profiles.ts")(profile),
|
||||
profile = newProfile;
|
||||
} else if (!profile && !name) {
|
||||
return send.deny();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}, {compress: true}
|
||||
);
|
||||
return send.object(
|
||||
{
|
||||
data: {
|
||||
...require('../templates/gameInfos.ts')(),
|
||||
|
||||
player: {
|
||||
jid: K.ITEM('s32', profile.jubeatId),
|
||||
session_id: K.ITEM('s32', 1),
|
||||
name: K.ITEM('str', profile.name),
|
||||
event_flag: K.ITEM('u64', BigInt(profile.eventFlag || 0)),
|
||||
|
||||
...(await require('../templates/profiles.ts')(profile)),
|
||||
},
|
||||
},
|
||||
},
|
||||
{ compress: true }
|
||||
);
|
||||
};
|
||||
|
||||
export const Getinfo = (info: EamuseInfo, data: any, send: EamuseSend) =>{
|
||||
console.log(data, {depth:null});
|
||||
return send.object({ data: require("../templates/gameInfos")() }, { compress: true });
|
||||
}
|
||||
export const Getinfo = (info: EamuseInfo, data: any, send: EamuseSend) => {
|
||||
console.log(data, { depth: null });
|
||||
return send.object(
|
||||
{ data: require('../templates/gameInfos')() },
|
||||
{ compress: true }
|
||||
);
|
||||
};
|
||||
|
||||
export const loadScore = async (info, data, send) => {
|
||||
console.log("gametop.get_mdata");
|
||||
console.log(data,{depth:null});
|
||||
const mdata_ver = $(data).number("data.player.mdata_ver");
|
||||
const jubeatId = $(data).number("data.player.jid");
|
||||
console.log('gametop.get_mdata');
|
||||
console.log(data, { depth: null });
|
||||
const mdata_ver = $(data).number('data.player.mdata_ver');
|
||||
const jubeatId = $(data).number('data.player.jid');
|
||||
if (!jubeatId) return send.deny();
|
||||
|
||||
const profile = await DB.FindOne<Profile>(null, { collection: "profile", jubeatId });
|
||||
const profile = await DB.FindOne<Profile>(null, {
|
||||
collection: 'profile',
|
||||
jubeatId,
|
||||
});
|
||||
if (!profile) return send.deny();
|
||||
|
||||
const scores = await DB.Find<Score>(profile.__refid, { collection: "score" });
|
||||
const scoreData: {
|
||||
const scores = await DB.Find<Score>(profile.__refid, { collection: 'score' });
|
||||
const scoreData: {
|
||||
[musicId: number]: {
|
||||
[isHardMode: number]: {
|
||||
musicRate: number[], score: number[], clear: number[], playCnt: number[], clearCnt: number[], fcCnt: number[], exCnt: number[], bar: number[][]
|
||||
}
|
||||
}
|
||||
musicRate: number[];
|
||||
score: number[];
|
||||
clear: number[];
|
||||
playCnt: number[];
|
||||
clearCnt: number[];
|
||||
fcCnt: number[];
|
||||
exCnt: number[];
|
||||
bar: number[][];
|
||||
};
|
||||
};
|
||||
} = {};
|
||||
|
||||
for (const score of scores) {
|
||||
if (!scoreData[score.musicId]) {
|
||||
scoreData[score.musicId] = {};
|
||||
}
|
||||
if(!scoreData[score.musicId][score.isHardMode & 1]) {
|
||||
scoreData[score.musicId][score.isHardMode & 1] = {
|
||||
if (!scoreData[score.musicId][score.isHardMode ? 1 : 0]) {
|
||||
scoreData[score.musicId][score.isHardMode ? 1 : 0] = {
|
||||
musicRate: [0, 0, 0],
|
||||
playCnt: [0, 0, 0],
|
||||
clearCnt: [0, 0, 0],
|
||||
|
|
@ -89,9 +106,8 @@ export const loadScore = async (info, data, send) => {
|
|||
bar: [Array(30).fill(0), Array(30).fill(0), Array(30).fill(0)],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
const data = scoreData[score.musicId][score.isHardMode & 1];
|
||||
const data = scoreData[score.musicId][score.isHardMode ? 1 : 0];
|
||||
data.musicRate[score.seq] = score.musicRate;
|
||||
data.playCnt[score.seq] = score.playCount;
|
||||
data.clearCnt[score.seq] = score.clearCount;
|
||||
|
|
@ -105,62 +121,91 @@ export const loadScore = async (info, data, send) => {
|
|||
var sendobj = {
|
||||
data: {
|
||||
player: {
|
||||
jid: K.ITEM("s32", jubeatId),
|
||||
jid: K.ITEM('s32', jubeatId),
|
||||
|
||||
mdata_list: {
|
||||
music: (() => {
|
||||
var musicArray = [];
|
||||
Object.keys(scoreData).forEach(musicId =>
|
||||
Object.keys(scoreData).forEach(musicId =>
|
||||
Object.keys(scoreData[musicId]).forEach(isHardMode => {
|
||||
musicArray.push(
|
||||
K.ATTR({ music_id: String(musicId) }, {
|
||||
[isHardMode === "1" ? "hard" : "normal"]:
|
||||
K.ATTR(
|
||||
{ music_id: String(musicId) },
|
||||
{
|
||||
score: K.ARRAY("s32", scoreData[musicId][isHardMode].score),
|
||||
clear: K.ARRAY("s8", scoreData[musicId][isHardMode].clear),
|
||||
music_rate: K.ARRAY("s32", scoreData[musicId][isHardMode].musicRate),
|
||||
play_cnt: K.ARRAY("s32", scoreData[musicId][isHardMode].playCnt),
|
||||
clear_cnt: K.ARRAY("s32", scoreData[musicId][isHardMode].clearCnt),
|
||||
fc_cnt: K.ARRAY("s32", scoreData[musicId][isHardMode].fcCnt),
|
||||
ex_cnt: K.ARRAY("s32", scoreData[musicId][isHardMode].exCnt),
|
||||
bar: scoreData[musicId][isHardMode].bar.map((bar, seq) => K.ARRAY("u8", bar, { seq: String(seq) }))
|
||||
[isHardMode === '1' ? 'hard' : 'normal']: {
|
||||
score: K.ARRAY(
|
||||
's32',
|
||||
scoreData[musicId][isHardMode].score
|
||||
),
|
||||
clear: K.ARRAY(
|
||||
's8',
|
||||
scoreData[musicId][isHardMode].clear
|
||||
),
|
||||
music_rate: K.ARRAY(
|
||||
's32',
|
||||
scoreData[musicId][isHardMode].musicRate
|
||||
),
|
||||
play_cnt: K.ARRAY(
|
||||
's32',
|
||||
scoreData[musicId][isHardMode].playCnt
|
||||
),
|
||||
clear_cnt: K.ARRAY(
|
||||
's32',
|
||||
scoreData[musicId][isHardMode].clearCnt
|
||||
),
|
||||
fc_cnt: K.ARRAY(
|
||||
's32',
|
||||
scoreData[musicId][isHardMode].fcCnt
|
||||
),
|
||||
ex_cnt: K.ARRAY(
|
||||
's32',
|
||||
scoreData[musicId][isHardMode].exCnt
|
||||
),
|
||||
bar: scoreData[musicId][isHardMode].bar.map(
|
||||
(bar, seq) => K.ARRAY('u8', bar, { seq: String(seq) })
|
||||
),
|
||||
},
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
})
|
||||
)
|
||||
);
|
||||
return musicArray;
|
||||
})()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if(mdata_ver!=1){
|
||||
sendobj = {
|
||||
data:{
|
||||
player:{
|
||||
jid: K.ITEM("s32", jubeatId),
|
||||
mdata_list: []
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
console.log(sendobj, {depth:null});
|
||||
return send.object(sendobj, {compress:true});
|
||||
}
|
||||
|
||||
export const Meeting = (req: EamuseInfo, data: any, send: EamuseSend) => {
|
||||
return send.object({
|
||||
data: {
|
||||
meeting: {
|
||||
single: K.ATTR({ count: "0" }),
|
||||
},
|
||||
reward: {
|
||||
total: K.ITEM("s32", 0),
|
||||
point: K.ITEM("s32", 0),
|
||||
})(),
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {compress:true});
|
||||
};
|
||||
|
||||
if (mdata_ver != 1) {
|
||||
sendobj = {
|
||||
data: {
|
||||
player: {
|
||||
jid: K.ITEM('s32', jubeatId),
|
||||
mdata_list: {
|
||||
music: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
console.log(sendobj, { depth: null });
|
||||
return send.object(sendobj, { compress: true });
|
||||
};
|
||||
|
||||
export const Meeting = (req: EamuseInfo, data: any, send: EamuseSend) => {
|
||||
return send.object(
|
||||
{
|
||||
data: {
|
||||
meeting: {
|
||||
single: K.ATTR({ count: '0' }),
|
||||
},
|
||||
reward: {
|
||||
total: K.ITEM('s32', 0),
|
||||
point: K.ITEM('s32', 0),
|
||||
},
|
||||
},
|
||||
},
|
||||
{ compress: true }
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,27 +1,57 @@
|
|||
# SOUND VOLTEX
|
||||
|
||||
Plugin Version: **v6.0.0**
|
||||
Plugin Version: **v6.1.2**
|
||||
|
||||
## Provide out of box usable exprience, everything is unlocked and good to go.
|
||||
|
||||
Prerequisite CORE version: v1.50c or above
|
||||
|
||||
Supported Versions:
|
||||
|
||||
- BOOTH
|
||||
- HEAVENLY HAVEN
|
||||
- VIVIDWAVE
|
||||
- EXCEED GEAR
|
||||
|
||||
Versions Not Supported:
|
||||
|
||||
- BOOTH
|
||||
- INFINITE INFECTION
|
||||
- GRAVITY WARS
|
||||
- HEAVENLY HAVEN
|
||||
- VIVIDWAVE
|
||||
|
||||
The plugin now mainly maintained versions:
|
||||
|
||||
- VIVIDWAVE
|
||||
- EXCEED GEAR
|
||||
|
||||
If you need support for HH and VW, use older version instead, too many new things in EG and they're messing older codes.
|
||||
|
||||
If you want to help with the plugin, you can open pull request.
|
||||
|
||||
This version save data is not compatible with some forks plugin, please use it with caution if you already uses an unsupported version.
|
||||
|
||||
Remember to import asset from the game files first time when using webui.
|
||||
|
||||
Change Log
|
||||
===========
|
||||
|
||||
## 6.1.2
|
||||
|
||||
1. Hotfix for 神 skill analyzer not showing after passed.
|
||||
|
||||
## 6.1.1
|
||||
|
||||
1. Support EG version up to 2023091200.
|
||||
2. Added ability to select Main Screen Background.
|
||||
|
||||
## 6.1.0
|
||||
|
||||
1. Support EG version up to 2023053001.
|
||||
2. Support Global Matching function, this will only work with the port opened or under same subnet.
|
||||
3. Support Arena, since the plugin unlocks everything, Arena Point(AP) will not be saved.
|
||||
4. Added support for import asset from game directly to webui usage, this function is still is testing phase, which may cause some problem, use it with caution.
|
||||
5. Added function to edit the unlock song count, which is editable from webui, defaulted to 2200.
|
||||
6. Temporarily support Valkyrie Generator, but since webui is able to change everything, the data won't be saved but you can do as much gacha as you want.
|
||||
7. Remove support for versions other than EG.
|
||||
|
||||
## 6.0.0
|
||||
|
||||
1. Plugin version now follows the pattern (MAX SDVX VER,Plugin VER of supporting the MAX version of SDVX,hotfix).
|
||||
|
|
@ -29,4 +59,10 @@ Change Log
|
|||
|
||||
## 1.1
|
||||
|
||||
1. Support VIVIDWAVE
|
||||
1. Support VIVIDWAVE
|
||||
|
||||
TODO
|
||||
===========
|
||||
|
||||
This is confirmed need to use addition library, and need more time to do the core update.
|
||||
- Convert BGM directly using pure nodejs without any additional library.
|
||||
3522
sdvx@asphyxia/data/exg_data.json
Normal file
|
|
@ -1,32 +0,0 @@
|
|||
export const COURSE2 = [
|
||||
{
|
||||
id: 0,
|
||||
level: 0,
|
||||
season_id: 0,
|
||||
season_name: '',
|
||||
new_flg: 0,
|
||||
name: '',
|
||||
type: 0,
|
||||
name_id: 0,
|
||||
matching_assist: 0,
|
||||
guage_type: 0,
|
||||
paseli_type: 0,
|
||||
tracks: [
|
||||
{
|
||||
no: 0,
|
||||
id: 2,
|
||||
type: 0
|
||||
},
|
||||
{
|
||||
no: 1,
|
||||
id: 2,
|
||||
type: 0
|
||||
},
|
||||
{
|
||||
no: 2,
|
||||
id: 2,
|
||||
type: 0
|
||||
},
|
||||
]
|
||||
},
|
||||
];
|
||||
|
|
@ -1,59 +1,52 @@
|
|||
import { EVENT4, COURSES4, EXTENDS4 } from '../data/hvn';
|
||||
import { EVENT5, COURSES5, EXTENDS5 } from '../data/vvw';
|
||||
import { EVENT6, COURSES6, EXTENDS6 } from '../data/exg';
|
||||
import { COURSE2 } from '../data/inf';
|
||||
import { EVENT6, COURSES6, EXTENDS6, VALGENE6 } from '../data/exg';
|
||||
import {getVersion, getRandomIntInclusive} from '../utils';
|
||||
import fs from 'fs';
|
||||
|
||||
export const informationString =
|
||||
`[sz:120] [olc:555555][ol:4][c:ff3333,3333ff,77ff77]Asphyxia
|
||||
[sz:75] CORE
|
||||
[sz:30][sz:30][c:ffffff,888888]
|
||||
|
||||
[c:00d5ff,888888]ASPHYXIA CORE ${CORE_VERSION}
|
||||
[c:e5f3ff,a3d5ff]SDVX Plugin ver 6.1.0
|
||||
|
||||
|
||||
[f:0][c:ff3333,ffffff]FREE SOFTWARE. BEWARE OF SCAMMERS.
|
||||
[c:ffffff,888888] If you bought this software, request refund immediately.
|
||||
|
||||
|
||||
[/ol]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[sz:32][c:560000,FC0000]DO NOT STREAM OR DISTRIBUTE THIS GAME IN PUBLIC`
|
||||
|
||||
// Special Banner, under [/ol]
|
||||
// [br:10][c:561F55,FCB2BF][sz:70] Trick or... Trick ?
|
||||
|
||||
|
||||
export const common: EPR = async (info, data, send) => {
|
||||
let events = [];
|
||||
let courses = [];
|
||||
let extend = [];
|
||||
console.log("Calling common function");
|
||||
|
||||
const version = parseInt(info.model.split(":")[4]);
|
||||
let exg_data_json = JSON.parse(fs.readFileSync('./plugins/sdvx@asphyxia/data/exg_data.json', 'utf8'));
|
||||
|
||||
if (version <= 2013052900) {
|
||||
return send.pugFile('templates/booth/common.pug');
|
||||
}
|
||||
|
||||
if (version <= 2014112000) {
|
||||
courses = COURSE2;
|
||||
return send.pugFile('templates/infiniteinfection/common.pug',{
|
||||
courses,
|
||||
});
|
||||
}
|
||||
events = EVENT6;
|
||||
courses = COURSES6;
|
||||
// EXTENDS6.forEach(val => extend.push(Object.assign({}, val)));
|
||||
extend = EXTENDS6;
|
||||
extend = extend.concat(exg_data_json.extends_data);
|
||||
// extend = extend.concat(exg_data.extends_data);
|
||||
|
||||
switch (info.method) {
|
||||
case 'sv4_common': {
|
||||
events = EVENT4;
|
||||
courses = COURSES4;
|
||||
//extend = EXTENDS4;
|
||||
EXTENDS4.forEach(val => extend.push(Object.assign({}, val)));
|
||||
break;
|
||||
}
|
||||
case 'sv5_common': {
|
||||
events = EVENT5;
|
||||
courses = COURSES5;
|
||||
//extend = EXTENDS5;
|
||||
EXTENDS5.forEach(val => extend.push(Object.assign({}, val)));
|
||||
break;
|
||||
}
|
||||
case 'sv6_common': {
|
||||
//events = EVENT6;
|
||||
EVENT6.forEach(val => events.push(val));
|
||||
courses = COURSES6;
|
||||
EXTENDS6.forEach(val => extend.push(Object.assign({}, val)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
let songs = [];
|
||||
|
||||
if (U.GetConfig('unlock_all_songs')) {
|
||||
console.log("Unlocking songs");
|
||||
const gameVersion = getVersion(info);
|
||||
let songNum = 2000;
|
||||
if(gameVersion === 2) songNum = 554;
|
||||
if(gameVersion === 3) songNum = 954;
|
||||
if(gameVersion === 4) songNum = 1368;
|
||||
let songNum = U.GetConfig('music_count');
|
||||
for (let i = 1; i < songNum; ++i) {
|
||||
for (let j = 0; j < 5; ++j) {
|
||||
songs.push({
|
||||
|
|
@ -81,26 +74,13 @@ export const common: EPR = async (info, data, send) => {
|
|||
1,
|
||||
31,
|
||||
'[f:0]SERVER INFORMATION',
|
||||
'[sz:120] [olc:555555][ol:4][c:ff3333,3333ff,77ff77]Asphyxia\n'+
|
||||
'[sz:75] CORE\n[sz:30]'+
|
||||
'[sz:30][c:ffffff,888888] \n \n'+
|
||||
' [c:00d5ff,888888]ASPHYXIA CORE'+CORE_VERSION+'\n'+
|
||||
' [c:e5f3ff,a3d5ff]SDVX Plugin ver 6.0.0\n \n \n'+
|
||||
'\n\n [f:0][c:ff3333,ffffff]FREE SOFTWARE. BEWARE OF SCAMMERS.\n'+
|
||||
'[c:ffffff,888888] If you bought this software, request refund immediately.\n \n \n[/ol]'+
|
||||
'[br:10][c:00FFFF][sz:50]メリー。。。クリスマス、です。。。'+
|
||||
'\n \n \n \n[sz:32][c:560000,FC0000]DO NOT STREAM OR DISTRIBUTE THIS GAME IN PUBLIC',
|
||||
//'[img:test]',
|
||||
informationString,
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if(U.GetConfig('new_year_special')){
|
||||
events.push('NEW_YEAR_2022');
|
||||
}
|
||||
|
||||
if(U.GetConfig('use_asphyxia_gameover')){
|
||||
let time = new Date();
|
||||
|
|
@ -131,54 +111,40 @@ export const common: EPR = async (info, data, send) => {
|
|||
"go_tsubaki","go_tsumabuki","go_tsumabuki_ver06","go_yuki","go_yukito",
|
||||
];
|
||||
let middleCharater = ["go_cat","go_cawoashi","go_iruyoru","go_neno",];
|
||||
// Pattern 1 Left Right Left
|
||||
// Pattern 2 Right Left Right
|
||||
// Pattern 3 Right Middle Left
|
||||
// Pattern 4 Left Middle Right
|
||||
// switch(getVersion(info)){
|
||||
// case 5:{
|
||||
// break;
|
||||
// }
|
||||
// case 6:{
|
||||
// rightCharater.push();
|
||||
// leftCharater.push();
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
var charaString = "characters: ";
|
||||
let charaString = "characters: ";
|
||||
let pattern = getRandomIntInclusive(1,4);
|
||||
switch(pattern){
|
||||
case 1:{
|
||||
var chara1 = leftCharater[getRandomIntInclusive(0,leftCharater.length-1)];
|
||||
var chara2 = rightCharater[getRandomIntInclusive(0,rightCharater.length-1)];
|
||||
var chara3 = leftCharater[getRandomIntInclusive(0,leftCharater.length-1)];
|
||||
let chara1 = leftCharater[getRandomIntInclusive(0,leftCharater.length-1)];
|
||||
let chara2 = rightCharater[getRandomIntInclusive(0,rightCharater.length-1)];
|
||||
let chara3 = leftCharater[getRandomIntInclusive(0,leftCharater.length-1)];
|
||||
charaString += "chara01/"+chara1+" chara02/"+chara2+" chara01/"+chara3;
|
||||
break;
|
||||
}
|
||||
case 2:{
|
||||
var chara1 = rightCharater[getRandomIntInclusive(0,rightCharater.length-1)];
|
||||
var chara2 = leftCharater[getRandomIntInclusive(0,leftCharater.length-1)];
|
||||
var chara3 = rightCharater[getRandomIntInclusive(0,rightCharater.length-1)];
|
||||
let chara1 = rightCharater[getRandomIntInclusive(0,rightCharater.length-1)];
|
||||
let chara2 = leftCharater[getRandomIntInclusive(0,leftCharater.length-1)];
|
||||
let chara3 = rightCharater[getRandomIntInclusive(0,rightCharater.length-1)];
|
||||
charaString += "chara02/"+chara1+" chara01/"+chara2+" chara02/"+chara3;
|
||||
break;
|
||||
}
|
||||
case 3:{
|
||||
var chara1 = rightCharater[getRandomIntInclusive(0,rightCharater.length-1)];
|
||||
var chara2 = middleCharater[getRandomIntInclusive(0,middleCharater.length-1)]
|
||||
var chara3 = leftCharater[getRandomIntInclusive(0,leftCharater.length-1)];
|
||||
let chara1 = rightCharater[getRandomIntInclusive(0,rightCharater.length-1)];
|
||||
let chara2 = middleCharater[getRandomIntInclusive(0,middleCharater.length-1)]
|
||||
let chara3 = leftCharater[getRandomIntInclusive(0,leftCharater.length-1)];
|
||||
charaString += "chara02/"+chara1+" chara03/"+chara2+" chara01/"+chara3;
|
||||
break;
|
||||
}
|
||||
case 4:{
|
||||
var chara1 = leftCharater[getRandomIntInclusive(0,leftCharater.length-1)];
|
||||
var chara2 = middleCharater[getRandomIntInclusive(0,middleCharater.length-1)];
|
||||
var chara3 = rightCharater[getRandomIntInclusive(0,rightCharater.length-1)];
|
||||
let chara1 = leftCharater[getRandomIntInclusive(0,leftCharater.length-1)];
|
||||
let chara2 = middleCharater[getRandomIntInclusive(0,middleCharater.length-1)];
|
||||
let chara3 = rightCharater[getRandomIntInclusive(0,rightCharater.length-1)];
|
||||
charaString += "chara01/"+chara1+" chara03/"+chara2+" chara02/"+chara3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(Math.abs(getVersion(info)) == 6){//Due to older version misses newer characters, not supported on older versions
|
||||
if(Math.abs(getVersion(info)) == 6){
|
||||
extend.push({
|
||||
id: 3,
|
||||
type: 1,
|
||||
|
|
@ -192,14 +158,30 @@ export const common: EPR = async (info, data, send) => {
|
|||
'[ol:6][olc:FFFFFF][ds:4][dsc:000000][sz:32][c:99FF00A8]Thank You For Using Asphyxia CORE!!!',
|
||||
'[ol:6][olc:FFFFFF][ds:4][dsc:000000][sz:32][c:990D46F2]For more information please visit our Discord!',
|
||||
'[ol:6][olc:FFFFFF][ds:4][dsc:000000][sz:32][c:99ED4F39]Nice Play!!!',
|
||||
//'characters: chara01/go_rasis_ver06 chara02/go_left_ver06 chara01/go_right_ver06',
|
||||
charaString,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let unlock_codes = [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
]
|
||||
|
||||
let time = new Date();
|
||||
let tempDate = time.getDate();
|
||||
const currentTime = time.getTime();
|
||||
tempDate += 30;
|
||||
time.setDate(tempDate);
|
||||
const newTime = time.getTime();
|
||||
|
||||
console.log("Sending common objects");
|
||||
send.object(
|
||||
{
|
||||
|
|
@ -234,6 +216,26 @@ export const common: EPR = async (info, data, send) => {
|
|||
season_name: K.ITEM('str', s.name),
|
||||
season_new_flg: K.ITEM('bool', s.isNew),
|
||||
course_type: K.ITEM('s16', 0),
|
||||
skill_type: K.ITEM('s16', 0),
|
||||
course_id: K.ITEM('s16', c.id),
|
||||
course_name: K.ITEM('str', c.name),
|
||||
skill_level: K.ITEM('s16', c.level),
|
||||
skill_name_id: K.ITEM('s16', c.nameID),
|
||||
matching_assist: K.ITEM('bool', c.assist),
|
||||
clear_rate: K.ITEM('s32', 5000),
|
||||
avg_score: K.ITEM('u32', 15000000),
|
||||
track: c.tracks.map(t => ({
|
||||
track_no: K.ITEM('s16', t.no),
|
||||
music_id: K.ITEM('s32', t.mid),
|
||||
music_type: K.ITEM('s8', t.mty),
|
||||
})),
|
||||
})),
|
||||
s.courses.map(c => ({
|
||||
season_id: K.ITEM('s32', s.id),
|
||||
season_name: K.ITEM('str', s.name),
|
||||
season_new_flg: K.ITEM('bool', s.isNew),
|
||||
course_type: K.ITEM('s16', 0),
|
||||
skill_type: K.ITEM('s16', 1),
|
||||
course_id: K.ITEM('s16', c.id),
|
||||
course_name: K.ITEM('str', c.name),
|
||||
skill_level: K.ITEM('s16', c.level),
|
||||
|
|
@ -251,6 +253,42 @@ export const common: EPR = async (info, data, send) => {
|
|||
[]
|
||||
),
|
||||
},
|
||||
arena: {
|
||||
season: K.ITEM('s32',3),
|
||||
rule: K.ITEM('s32',0),
|
||||
rank_match_target: K.ARRAY('s32', [
|
||||
2,2,2,2,
|
||||
2,2,2,2,
|
||||
1,1,1,1,
|
||||
1,1,1,1,
|
||||
0,0,0,0,
|
||||
0,0,0,0,
|
||||
0,0,0,0,
|
||||
0,0,0,0,
|
||||
]),
|
||||
time_start: K.ITEM('u64',BigInt(currentTime)),
|
||||
time_end: K.ITEM('u64',BigInt(newTime)),
|
||||
shop_start: K.ITEM('u64',BigInt(currentTime)),
|
||||
shop_end: K.ITEM('u64',BigInt(newTime)),
|
||||
is_open: K.ITEM('bool',true),
|
||||
is_shop: K.ITEM('bool',true)
|
||||
},
|
||||
valgene: {
|
||||
info: unlock_codes.map(v => ({
|
||||
valgene_name: K.ITEM('str', 'VALKYRIE GENERATOR VOL.' + v),
|
||||
valgene_name_english: K.ITEM('str', 'VALKYRIE GENERATOR VOL.' + v),
|
||||
valgene_id: K.ITEM('s32', v),
|
||||
})),
|
||||
catalog: VALGENE6.catalog.map(c => ({
|
||||
valgene_id: K.ITEM('s32', c.valgene_id),
|
||||
rarity: K.ITEM('s32', c.rarity),
|
||||
item_type: K.ITEM('s32', c.item_type),
|
||||
item_id: K.ITEM('s32', c.item_id),
|
||||
})),
|
||||
},
|
||||
invest:{
|
||||
limit_date: K.ITEM('u64',BigInt(newTime)),
|
||||
}
|
||||
},
|
||||
{ encoding: 'utf8' }
|
||||
);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ import { Profile } from '../models/profile';
|
|||
import { MusicRecord } from '../models/music_record';
|
||||
import { getVersion, IDToCode, GetCounter } from '../utils';
|
||||
import { Mix } from '../models/mix';
|
||||
import { MatchingRoom } from '../models/matching';
|
||||
|
||||
let Tracker:MatchingRoom[] = [];
|
||||
|
||||
export const hiscore: EPR = async (info, data, send) => {
|
||||
const records = await DB.Find<MusicRecord>(null, { collection: 'music' });
|
||||
|
|
@ -13,33 +16,6 @@ export const hiscore: EPR = async (info, data, send) => {
|
|||
'__refid'
|
||||
);
|
||||
|
||||
if (version === 1) {
|
||||
return send.object({
|
||||
hiscore: K.ATTR({ type: "1" }, {
|
||||
music: _.map(
|
||||
_.groupBy(records, r => {
|
||||
return `${r.mid}:${r.type}`;
|
||||
}),
|
||||
r => _.maxBy(r, 'score')
|
||||
).map(r => (K.ATTR({ id: String(r.mid) }, {
|
||||
note: (() => {
|
||||
const notes = [];
|
||||
|
||||
for (let i = 1; i <= 3; i++) {
|
||||
if (r.type !== i) continue;
|
||||
notes.push(K.ATTR({ type: String(r.type) }, {
|
||||
name: K.ITEM('str', profiles[r.__refid][0].name),
|
||||
score: K.ITEM('u32', r.score)
|
||||
}))
|
||||
}
|
||||
|
||||
return notes;
|
||||
})()
|
||||
}))),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return send.object({
|
||||
sc: {
|
||||
d: _.map(
|
||||
|
|
@ -56,6 +32,14 @@ export const hiscore: EPR = async (info, data, send) => {
|
|||
l_sq: K.ITEM('str', IDToCode(profiles[r.__refid][0].id)),
|
||||
l_nm: K.ITEM('str', profiles[r.__refid][0].name),
|
||||
l_sc: K.ITEM('u32', r.score),
|
||||
ax_sq: K.ITEM('str', IDToCode(profiles[r.__refid][0].id)),
|
||||
ax_nm: K.ITEM('str', profiles[r.__refid][0].name),
|
||||
ax_sc: K.ITEM('u32', r.exscore ?? 0),
|
||||
lx_sq: K.ITEM('str', IDToCode(profiles[r.__refid][0].id)),
|
||||
lx_nm: K.ITEM('str', profiles[r.__refid][0].name),
|
||||
lx_sc: K.ITEM('u32', r.exscore ?? 0),
|
||||
avg_sc: K.ITEM('u32', r.score),
|
||||
cr: K.ITEM('s32', 8763)
|
||||
})),
|
||||
},
|
||||
});
|
||||
|
|
@ -79,7 +63,7 @@ export const rival: EPR = async (info, data, send) => {
|
|||
music: (
|
||||
await DB.Find<MusicRecord>(p.__refid, { collection: 'music' })
|
||||
).map(r => ({
|
||||
param: K.ARRAY('u32', [r.mid, r.type, r.score, r.clear, r.grade]),
|
||||
param: K.ARRAY('u32', [r.mid, r.type, r.score, r.exscore, r.clear, r.grade]),
|
||||
})),
|
||||
};
|
||||
})
|
||||
|
|
@ -153,28 +137,60 @@ export const loadMix: EPR = async (info, data, send) => {
|
|||
});
|
||||
};
|
||||
|
||||
export const globalMatch: EPR = async (info, data, send) => {
|
||||
// console.log("Current MID: "+$(data).number('mid'));
|
||||
// console.log("Port: "+$(data).number('port'));
|
||||
// console.log("Global IP: "+$(data).numbers('gip'));
|
||||
// console.log("Private IP: "+$(data).numbers('lip'));
|
||||
|
||||
// var mid = $(data).number('mid');
|
||||
// var port = $(data).number('port');
|
||||
// var gip = $(data).str('gip');
|
||||
// var lip = $(data).str('lip');
|
||||
// var testArray = [{
|
||||
// port: port,
|
||||
// gip:gip,
|
||||
// lip:lip,
|
||||
// }];
|
||||
// return send.object({
|
||||
// entry_id: K.ITEM('str', '123456789'),
|
||||
// entry: testArray.map(a=>{
|
||||
// port: K.ITEM('u16',a.port);
|
||||
// gip: K.ITEM('ip4',a.gip);
|
||||
// lip: K.ITEM('ip4',a.lip);
|
||||
// })
|
||||
// });
|
||||
send.success();
|
||||
export const globalMatch: EPR = async (info, data, send) => {
|
||||
const gipArr = $(data).numbers('gip');
|
||||
const lipArr = $(data).numbers('lip');
|
||||
const gip = gipArr.join('.');
|
||||
const lip = lipArr.join('.');
|
||||
const gameID = $(data).number('mid');
|
||||
|
||||
const filter = $(data).number('filter');
|
||||
|
||||
Tracker = Tracker.filter(e => Math.trunc(new Date().getTime()/1000) - e.sec <= 90)
|
||||
|
||||
let curr_game_arr = Tracker.filter(e => e.filter == filter);
|
||||
curr_game_arr = curr_game_arr.filter(e => e.gameID == gameID);
|
||||
|
||||
console.log(JSON.stringify(curr_game_arr,null,2))
|
||||
|
||||
|
||||
let in_tracker = false;
|
||||
|
||||
for(const element of curr_game_arr) {
|
||||
if(element.gip == gip){
|
||||
in_tracker = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!in_tracker){
|
||||
let curr_game:MatchingRoom;
|
||||
curr_game = <MatchingRoom> {
|
||||
gameID:gameID,
|
||||
gip:gip,
|
||||
lip:lip,
|
||||
sec: Math.trunc(new Date().getTime()/1000),
|
||||
port:$(data).number('port'),
|
||||
filter:filter
|
||||
};
|
||||
Tracker.push(curr_game);
|
||||
}
|
||||
|
||||
|
||||
console.log(JSON.stringify(Tracker,null,2))
|
||||
|
||||
let temp = {
|
||||
entry_id: K.ITEM('u32',0),
|
||||
entry: curr_game_arr.map(e => ({
|
||||
gip: K.ITEM('4u8',e.gip.split('.').map(e => parseInt(e))),
|
||||
lip: K.ITEM('4u8',e.lip.split('.').map(e => parseInt(e))),
|
||||
port: K.ITEM('u16',e.port),
|
||||
}))
|
||||
}
|
||||
console.log(JSON.stringify(temp, null, 2));
|
||||
|
||||
send.object(temp);
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import { Skill } from '../models/skill';
|
||||
import { SDVX_AUTOMATION_SONGS } from '../data/vvw';
|
||||
import { Item } from '../models/item';
|
||||
import { Param } from '../models/param';
|
||||
import { MusicRecord } from '../models/music_record';
|
||||
|
|
@ -12,7 +11,7 @@ async function getAutomationMixes(params: Param[]) {
|
|||
const mixids = params
|
||||
.filter(p => p.id == 3)
|
||||
.reduce((res, p) => _.union(res, p.param), []);
|
||||
return await DB.Find<Mix>({ collection: 'mix', id: { $in: mixids } });
|
||||
return DB.Find<Mix>({ collection: 'mix', id: { $in: mixids } });
|
||||
}
|
||||
|
||||
function unlockNavigators(items: Partial<Item>[]) {
|
||||
|
|
@ -20,6 +19,7 @@ function unlockNavigators(items: Partial<Item>[]) {
|
|||
console.log("Unlocking Navigators");
|
||||
// 10 genesis card for MITSURU's voice
|
||||
items.push({ type: 4, id: 599, param: 10 });
|
||||
// items.push({ type: 21, id: 1, param: 1 });
|
||||
return items;
|
||||
}
|
||||
|
||||
|
|
@ -30,6 +30,16 @@ function unlockAppealCards(items: Partial<Item>[]) {
|
|||
return items;
|
||||
}
|
||||
|
||||
function unlock_all_valkgen(items: Partial<Item>[]) {
|
||||
// for (let i = 0; i < 500; ++i) items.push({ type: 17, id: i, param: 1 }); // stamp
|
||||
// for (let i = 0; i < 600; ++i) items.push({ type: 18, id: i, param: 1 }); // subbg
|
||||
// for (let i = 0; i < 100; ++i) items.push({ type: 19, id: i, param: 1 }); // bgm
|
||||
// for (let i = 0; i < 100; ++i) items.push({ type: 20, id: i, param: 1 }); // nemsys
|
||||
// for (let i = 0; i < 30; ++i) items.push({ type: 21, id: i, param: 1 }); // mainbg
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
export const loadScore: EPR = async (info, data, send) => {
|
||||
console.log("Now loading score");
|
||||
const version = Math.abs(getVersion(info));
|
||||
|
|
@ -43,117 +53,6 @@ export const loadScore: EPR = async (info, data, send) => {
|
|||
const records = await DB.Find<MusicRecord>(refid, { collection: 'music' });
|
||||
|
||||
|
||||
//console.log(version);
|
||||
if (version === 1) {
|
||||
return send.object({
|
||||
music: records.map(r => (K.ATTR({ music_id: String(r.mid) }, {
|
||||
type: (() => {
|
||||
const records = [];
|
||||
|
||||
for (let i = 1; i <= 3; i++) {
|
||||
if (r.type != i) continue;
|
||||
records.push(K.ATTR({
|
||||
type_id: String(i),
|
||||
score: String(r.score),
|
||||
clear_type: String(r.clear),
|
||||
score_grade: String(r.grade),
|
||||
cnt: "0"
|
||||
}));
|
||||
}
|
||||
|
||||
return records;
|
||||
})()
|
||||
})))
|
||||
});
|
||||
}
|
||||
|
||||
if (version === 2) {
|
||||
let temp = Array.from(records.values()).filter(r => (r.mid <= 554));
|
||||
//console.log([...temp]);
|
||||
//return send.pugFile('templates/infiniteinfection/score.pug', {
|
||||
// temp});
|
||||
return send.object(
|
||||
{
|
||||
"new": {
|
||||
music: temp.map(r => ({
|
||||
music_id: K.ITEM('u32', r.mid),
|
||||
music_type: K.ITEM('u32', r.type),
|
||||
score: K.ITEM('u32', r.score),
|
||||
cnt: K.ITEM('u32', 1),
|
||||
clear_type: K.ITEM('u32', r.clear),
|
||||
score_grade: K.ITEM('u32', r.grade),
|
||||
btn_rate: K.ITEM('u32', r.buttonRate),
|
||||
long_rate: K.ITEM('u32', r.longRate),
|
||||
vol_rate: K.ITEM('u32', r.volRate),
|
||||
}))
|
||||
}, old: {}
|
||||
}, { rootName: "game" });
|
||||
}
|
||||
|
||||
if (version === 6) {
|
||||
return send.object({
|
||||
music: {
|
||||
info: records.map(r => ({
|
||||
param: K.ARRAY('u32', [
|
||||
r.mid,
|
||||
r.type,
|
||||
r.score,
|
||||
r.exscore,
|
||||
r.clear,
|
||||
r.grade,
|
||||
0,
|
||||
0,
|
||||
r.buttonRate,
|
||||
r.longRate,
|
||||
r.volRate,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
]),
|
||||
})),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (version === 4 || version === 3) {
|
||||
let temp = Array.from(records.values()).filter(r => (r.mid <= 1368));
|
||||
|
||||
|
||||
return send.object({
|
||||
music: {
|
||||
info: temp.map(r => ({
|
||||
param: K.ARRAY('u32', [
|
||||
r.mid,
|
||||
r.type,
|
||||
r.score,
|
||||
r.clear,
|
||||
r.grade,
|
||||
0,
|
||||
0,
|
||||
r.buttonRate,
|
||||
r.longRate,
|
||||
r.volRate,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
]),
|
||||
})
|
||||
),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return send.object({
|
||||
music: {
|
||||
info: records.map(r => ({
|
||||
|
|
@ -161,9 +60,10 @@ export const loadScore: EPR = async (info, data, send) => {
|
|||
r.mid,
|
||||
r.type,
|
||||
r.score,
|
||||
r.exscore,
|
||||
r.clear,
|
||||
r.grade,
|
||||
0,
|
||||
0, // max chain
|
||||
0,
|
||||
r.buttonRate,
|
||||
r.longRate,
|
||||
|
|
@ -173,163 +73,69 @@ export const loadScore: EPR = async (info, data, send) => {
|
|||
0,
|
||||
0,
|
||||
0,
|
||||
0, // last update time
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
]),
|
||||
})),
|
||||
},
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
export const saveScore: EPR = async (info, data, send) => {
|
||||
const refid = $(data).str('refid', $(data).attr().dataid);
|
||||
if (!refid) return send.deny();
|
||||
|
||||
const version = getVersion(info);
|
||||
const tracks = $(data).elements('track');
|
||||
for (const i of tracks) {
|
||||
const mid = i.number('music_id');
|
||||
const type = i.number('music_type');
|
||||
if (_.isNil(mid) || _.isNil(type)) return send.deny();
|
||||
|
||||
// Booth - Save score
|
||||
if (version === 1) {
|
||||
try {
|
||||
const mid = parseInt($(data).attr().music_id);
|
||||
const type = parseInt($(data).attr().music_type);
|
||||
const record = (await DB.FindOne<MusicRecord>(refid, {
|
||||
collection: 'music',
|
||||
mid,
|
||||
type,
|
||||
})) || {
|
||||
collection: 'music',
|
||||
mid,
|
||||
type,
|
||||
score: 0,
|
||||
exscore: 0,
|
||||
clear: 0,
|
||||
grade: 0,
|
||||
buttonRate: 0,
|
||||
longRate: 0,
|
||||
volRate: 0,
|
||||
};
|
||||
|
||||
if (_.isNil(mid) || _.isNil(type)) return send.deny();
|
||||
|
||||
const record = (await DB.FindOne<MusicRecord>(refid, {
|
||||
collection: 'music',
|
||||
mid,
|
||||
type,
|
||||
})) || {
|
||||
collection: 'music',
|
||||
mid,
|
||||
type,
|
||||
score: 0,
|
||||
clear: 0,
|
||||
grade: 0,
|
||||
buttonRate: 0,
|
||||
longRate: 0,
|
||||
volRate: 0,
|
||||
};
|
||||
|
||||
const score = $(data).attr().score ? parseInt($(data).attr().score) : 0;
|
||||
const clear = $(data).attr().clear_type ? parseInt($(data).attr().clear_type) : 0;
|
||||
const grade = $(data).attr().score_grade ? parseInt($(data).attr().score_grade) : 0;
|
||||
if (score > record.score) {
|
||||
record.score = score;
|
||||
}
|
||||
|
||||
record.clear = Math.max(clear, record.clear);
|
||||
record.grade = Math.max(grade, record.grade);
|
||||
|
||||
await DB.Upsert<MusicRecord>(
|
||||
refid,
|
||||
{ collection: 'music', mid, type },
|
||||
record
|
||||
);
|
||||
|
||||
return send.success();
|
||||
} catch {
|
||||
return send.deny();
|
||||
const score = i.number('score', 0);
|
||||
const exscore = i.number('exscore', 0);
|
||||
if (score > record.score) {
|
||||
record.score = score;
|
||||
record.buttonRate = i.number('btn_rate', 0);
|
||||
record.longRate = i.number('long_rate', 0);
|
||||
record.volRate = i.number('vol_rate', 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (version === -6) { // Using alternate scoring system after 20210831
|
||||
const tracks = $(data).elements('track');
|
||||
for (const i of tracks) {
|
||||
const mid = i.number('music_id');
|
||||
const type = i.number('music_type');
|
||||
if (_.isNil(mid) || _.isNil(type)) return send.deny();
|
||||
|
||||
const record = (await DB.FindOne<MusicRecord>(refid, {
|
||||
collection: 'music',
|
||||
mid,
|
||||
type,
|
||||
})) || {
|
||||
collection: 'music',
|
||||
mid,
|
||||
type,
|
||||
score: 0,
|
||||
exscore: 0,
|
||||
clear: 0,
|
||||
grade: 0,
|
||||
buttonRate: 0,
|
||||
longRate: 0,
|
||||
volRate: 0,
|
||||
};
|
||||
|
||||
const score = i.number('score', 0);
|
||||
const exscore = i.number('exscore', 0);
|
||||
if (score > record.score) {
|
||||
record.score = score;
|
||||
record.buttonRate = i.number('btn_rate', 0);
|
||||
record.longRate = i.number('long_rate', 0);
|
||||
record.volRate = i.number('vol_rate', 0);
|
||||
}
|
||||
if (exscore > record.exscore) {
|
||||
record.exscore = exscore;
|
||||
}
|
||||
|
||||
record.clear = Math.max(i.number('clear_type', 0), record.clear);
|
||||
record.grade = Math.max(i.number('score_grade', 0), record.grade);
|
||||
|
||||
|
||||
|
||||
await DB.Upsert<MusicRecord>(
|
||||
refid,
|
||||
{ collection: 'music', mid, type },
|
||||
record
|
||||
);
|
||||
if (exscore > record.exscore) {
|
||||
record.exscore = exscore;
|
||||
}
|
||||
return send.success();
|
||||
|
||||
record.clear = Math.max(i.number('clear_type', 0), record.clear);
|
||||
record.grade = Math.max(i.number('score_grade', 0), record.grade);
|
||||
|
||||
|
||||
|
||||
await DB.Upsert<MusicRecord>(
|
||||
refid,
|
||||
{ collection: 'music', mid, type },
|
||||
record
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const mid = $(data).number('music_id');
|
||||
const type = $(data).number('music_type');
|
||||
console.log("Saving score for version later than HH(include), ID:" + mid + " type:" + type);
|
||||
if (_.isNil(mid) || _.isNil(type)) return send.deny();
|
||||
|
||||
const record = (await DB.FindOne<MusicRecord>(refid, {
|
||||
collection: 'music',
|
||||
mid,
|
||||
type,
|
||||
})) || {
|
||||
collection: 'music',
|
||||
mid,
|
||||
type,
|
||||
score: 0,
|
||||
exscore: 0,
|
||||
clear: 0,
|
||||
grade: 0,
|
||||
buttonRate: 0,
|
||||
longRate: 0,
|
||||
volRate: 0,
|
||||
};
|
||||
|
||||
const score = $(data).number('score', 0);
|
||||
const exscore = $(data).number('exscore', 0);
|
||||
if (score > record.score) {
|
||||
record.score = score;
|
||||
record.buttonRate = $(data).number('btn_rate', 0);
|
||||
record.longRate = $(data).number('long_rate', 0);
|
||||
record.volRate = $(data).number('vol_rate', 0);
|
||||
}
|
||||
if (exscore > record.exscore) {
|
||||
record.exscore = exscore;
|
||||
}
|
||||
|
||||
record.clear = Math.max($(data).number('clear_type', 0), record.clear);
|
||||
record.grade = Math.max($(data).number('score_grade', 0), record.grade);
|
||||
|
||||
|
||||
|
||||
await DB.Upsert<MusicRecord>(
|
||||
refid,
|
||||
{ collection: 'music', mid, type },
|
||||
record
|
||||
);
|
||||
|
||||
return send.success();
|
||||
};
|
||||
|
||||
|
|
@ -371,119 +177,55 @@ export const save: EPR = async (info, data, send) => {
|
|||
const version = Math.abs(getVersion(info));
|
||||
if (version == 0) return send.deny();
|
||||
|
||||
if (version === 1) {
|
||||
try {
|
||||
// Save Profile
|
||||
await DB.Update<Profile>(
|
||||
refid,
|
||||
{ collection: 'profile' },
|
||||
{
|
||||
$set: {
|
||||
headphone: $(data).number('headphone'),
|
||||
hiSpeed: $(data).number('hispeed'),
|
||||
appeal: $(data).number('appeal_id'),
|
||||
boothFrame: [$(data).number('frame0'), $(data).number('frame1'), $(data).number('frame2'), $(data).number('frame3'), $(data).number('frame4')],
|
||||
musicID: parseInt($(data).attr("last").music_id),
|
||||
musicType: parseInt($(data).attr("last").music_type),
|
||||
sortType: parseInt($(data).attr("last").sort_type),
|
||||
mUserCnt: $(data).number('m_user_cnt'),
|
||||
},
|
||||
$inc: {
|
||||
expPoint: $(data).number('gain_exp'),
|
||||
packets: $(data).number('earned_gamecoin_packet'),
|
||||
blocks: $(data).number('earned_gamecoin_block'),
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return send.success();
|
||||
} catch {
|
||||
return send.deny();
|
||||
await DB.Update<Profile>(
|
||||
refid,
|
||||
{ collection: 'profile' },
|
||||
{
|
||||
$set: {
|
||||
appeal: $(data).number('appeal_id'),
|
||||
|
||||
musicID: $(data).number('music_id'),
|
||||
musicType: $(data).number('music_type'),
|
||||
sortType: $(data).number('sort_type'),
|
||||
headphone: $(data).number('headphone'),
|
||||
blasterCount: $(data).number('blaster_count'),
|
||||
|
||||
hiSpeed: $(data).number('hispeed'),
|
||||
laneSpeed: $(data).number('lanespeed'),
|
||||
gaugeOption: $(data).number('gauge_option'),
|
||||
arsOption: $(data).number('ars_option'),
|
||||
notesOption: $(data).number('notes_option'),
|
||||
earlyLateDisp: $(data).number('early_late_disp'),
|
||||
drawAdjust: $(data).number('draw_adjust'),
|
||||
effCLeft: $(data).number('eff_c_left'),
|
||||
effCRight: $(data).number('eff_c_right'),
|
||||
narrowDown: $(data).number('narrow_down'),
|
||||
},
|
||||
$inc: {
|
||||
packets: $(data).number('earned_gamecoin_packet'),
|
||||
blocks: $(data).number('earned_gamecoin_block'),
|
||||
blasterEnergy: $(data).number('earned_blaster_energy'),
|
||||
extrackEnergy: $(data).number('earned_extrack_energy'),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Save Profile
|
||||
if (version === 6) {
|
||||
await DB.Update<Profile>(
|
||||
refid,
|
||||
{ collection: 'profile' },
|
||||
{
|
||||
$set: {
|
||||
appeal: $(data).number('appeal_id'),
|
||||
|
||||
musicID: $(data).number('music_id'),
|
||||
musicType: $(data).number('music_type'),
|
||||
sortType: $(data).number('sort_type'),
|
||||
headphone: $(data).number('headphone'),
|
||||
blasterCount: $(data).number('blaster_count'),
|
||||
|
||||
hiSpeed: $(data).number('hispeed'),
|
||||
laneSpeed: $(data).number('lanespeed'),
|
||||
gaugeOption: $(data).number('gauge_option'),
|
||||
arsOption: $(data).number('ars_option'),
|
||||
notesOption: $(data).number('notes_option'),
|
||||
earlyLateDisp: $(data).number('early_late_disp'),
|
||||
drawAdjust: $(data).number('draw_adjust'),
|
||||
effCLeft: $(data).number('eff_c_left'),
|
||||
effCRight: $(data).number('eff_c_right'),
|
||||
narrowDown: $(data).number('narrow_down'),
|
||||
},
|
||||
$inc: {
|
||||
packets: $(data).number('earned_gamecoin_packet'),
|
||||
blocks: $(data).number('earned_gamecoin_block'),
|
||||
blasterEnergy: $(data).number('earned_blaster_energy'),
|
||||
extrackEnergy: $(data).number('earned_extrack_energy'),
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
if (version === 5 || version === 4) {
|
||||
await DB.Update<Profile>(
|
||||
refid,
|
||||
{ collection: 'profile' },
|
||||
{
|
||||
$set: {
|
||||
appeal: $(data).number('appeal_id'),
|
||||
|
||||
musicID: $(data).number('music_id'),
|
||||
musicType: $(data).number('music_type'),
|
||||
sortType: $(data).number('sort_type'),
|
||||
headphone: $(data).number('headphone'),
|
||||
blasterCount: $(data).number('blaster_count'),
|
||||
|
||||
hiSpeed: $(data).number('hispeed'),
|
||||
laneSpeed: $(data).number('lanespeed'),
|
||||
gaugeOption: $(data).number('gauge_option'),
|
||||
arsOption: $(data).number('ars_option'),
|
||||
notesOption: $(data).number('notes_option'),
|
||||
earlyLateDisp: $(data).number('early_late_disp'),
|
||||
drawAdjust: $(data).number('draw_adjust'),
|
||||
effCLeft: $(data).number('eff_c_left'),
|
||||
effCRight: $(data).number('eff_c_right'),
|
||||
narrowDown: $(data).number('narrow_down'),
|
||||
},
|
||||
$inc: {
|
||||
packets: $(data).number('earned_gamecoin_packet'),
|
||||
blocks: $(data).number('earned_gamecoin_block'),
|
||||
blasterEnergy: $(data).number('earned_blaster_energy'),
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
// New course saving function found in sdvx 20220214
|
||||
const course = $(data).element('course');
|
||||
if(!_.isNil(course)){
|
||||
const sid = course.number('ssnid');
|
||||
const cid = course.number('crsid');
|
||||
|
||||
const skill_type = course.number('st');
|
||||
if (!(_.isNil(sid) || _.isNil(cid))){
|
||||
await DB.Upsert<CourseRecord>(
|
||||
refid,
|
||||
{ collection: 'course', sid, cid, version },
|
||||
{ collection: 'course', sid, cid, version, skill_type },
|
||||
{
|
||||
$max: {
|
||||
score: course.number('sc', 0),
|
||||
exscore: course.number('ex', 0),
|
||||
clear: course.number('ct', 0),
|
||||
grade: course.number('gr', 0),
|
||||
rate: course.number('ar', 0),
|
||||
|
|
@ -541,6 +283,7 @@ export const save: EPR = async (info, data, send) => {
|
|||
base: $(data).number('skill_base_id'),
|
||||
level: $(data).number('skill_level'),
|
||||
name: $(data).number('skill_name_id'),
|
||||
stype: $(data).number('skill_type')
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
@ -570,9 +313,19 @@ export const load: EPR = async (info, data, send) => {
|
|||
let skill = (await DB.FindOne<Skill>(refid, {
|
||||
collection: 'skill',
|
||||
version,
|
||||
})) || { base: 0, name: 0, level: 0 };
|
||||
})) || { base: 0, name: 0, level: 0, stype:0 };
|
||||
|
||||
skill.stype = skill.stype ?? 0;
|
||||
|
||||
|
||||
const courses = await DB.Find<CourseRecord>(refid, { collection: 'course', version });
|
||||
|
||||
for(const c of courses){
|
||||
c.skill_type = c.skill_type ?? 0;
|
||||
c.exscore = c.exscore ?? 0;
|
||||
}
|
||||
|
||||
|
||||
const items = await DB.Find<Item>(refid, { collection: 'item' });
|
||||
const params = await DB.Find<Param>(refid, { collection: 'param' });
|
||||
let time = new Date();
|
||||
|
|
@ -588,21 +341,6 @@ export const load: EPR = async (info, data, send) => {
|
|||
profile.extrackEnergy = 0;
|
||||
}
|
||||
|
||||
if (version === 1) {
|
||||
return send.pugFile('templates/booth/load.pug', { code: IDToCode(profile.id), ...profile });
|
||||
}
|
||||
|
||||
if (version === 2) {
|
||||
let tempItem = U.GetConfig('unlock_all_appeal_cards') ? unlockAppealCards(items) : items
|
||||
tempItem = Array.from(tempItem.values()).filter(r => (r.id <= 220));
|
||||
return send.pugFile('templates/infiniteinfection/load.pug', {
|
||||
courses,
|
||||
tempItem,
|
||||
params,
|
||||
skill,
|
||||
...profile
|
||||
});
|
||||
}
|
||||
const bgm = profile.bgm ? profile.bgm : 0;
|
||||
const subbg = profile.subbg ? profile.subbg : 0;
|
||||
const nemsys = profile.nemsys ? profile.nemsys : 0;
|
||||
|
|
@ -610,13 +348,17 @@ export const load: EPR = async (info, data, send) => {
|
|||
const stampB = profile.stampB ? profile.stampB : 0;
|
||||
const stampC = profile.stampC ? profile.stampC : 0;
|
||||
const stampD = profile.stampD ? profile.stampD : 0;
|
||||
|
||||
const stampA_R = profile.stampA_R ? profile.stampA_R : 0;
|
||||
const stampB_R = profile.stampB_R ? profile.stampB_R : 0;
|
||||
const stampC_R = profile.stampC_R ? profile.stampC_R : 0;
|
||||
const stampD_R = profile.stampD_R ? profile.stampD_R : 0;
|
||||
const mainbg = profile.mainbg ? profile.mainbg : 0;
|
||||
|
||||
const customize = [];
|
||||
customize.push(bgm, subbg, nemsys, stampA, stampB, stampC, stampD);
|
||||
customize.push(bgm, subbg, nemsys, stampA, stampB, stampC, stampD, stampA_R, stampB_R, stampC_R, stampD_R, mainbg);
|
||||
|
||||
|
||||
var tempCustom = params.findIndex((e) => (e.type == 2 && e.id == 2))
|
||||
let tempCustom = params.findIndex((e) => (e.type == 2 && e.id == 2))
|
||||
|
||||
if (tempCustom == -1) {
|
||||
const tempParam: Param = { collection: 'param', type: 2, id: 2, param: [] };
|
||||
|
|
@ -631,14 +373,19 @@ export const load: EPR = async (info, data, send) => {
|
|||
|
||||
let blasterpass = U.GetConfig('use_blasterpass') ? 1 : 0;
|
||||
|
||||
var tempItem = U.GetConfig('unlock_all_navigators') ? unlockNavigators(items) : items;
|
||||
tempItem = U.GetConfig('unlock_all_appeal_cards') ? unlockAppealCards(items) : items;
|
||||
let tempItem = U.GetConfig('unlock_all_navigators') ? unlockNavigators(items) : items;
|
||||
tempItem = U.GetConfig('unlock_all_appeal_cards') ? unlockAppealCards(tempItem) : tempItem;
|
||||
tempItem = unlock_all_valkgen(tempItem);
|
||||
|
||||
// Make generator power always 100%,
|
||||
for (let i = 0; i < 50; i++) {
|
||||
const tempGene: Item = { collection: 'item', type: 7, id: i, param: 10 };
|
||||
tempItem.push(tempGene);
|
||||
}
|
||||
profile.appeal_frame = profile.appeal_frame ? profile.appeal_frame : 0;
|
||||
profile.support_team = profile.support_team ? profile.support_team : 0;
|
||||
|
||||
|
||||
return send.pugFile('templates/load.pug', {
|
||||
courses,
|
||||
items: tempItem,
|
||||
|
|
@ -648,7 +395,7 @@ export const load: EPR = async (info, data, send) => {
|
|||
mixes,
|
||||
version,
|
||||
blasterpass,
|
||||
automation: version == 5 ? SDVX_AUTOMATION_SONGS : [],
|
||||
automation: [],
|
||||
code: IDToCode(profile.id),
|
||||
...profile,
|
||||
});
|
||||
|
|
@ -695,6 +442,13 @@ export const create: EPR = async (info, data, send) => {
|
|||
stampB: 0,
|
||||
stampC: 0,
|
||||
stampD: 0,
|
||||
stampA_R: 0,
|
||||
stampB_R: 0,
|
||||
stampC_R: 0,
|
||||
stampD_R: 0,
|
||||
mainbg: 0,
|
||||
appeal_frame: 0,
|
||||
support_team: 0,
|
||||
|
||||
headphone: 0,
|
||||
musicID: 0,
|
||||
|
|
@ -756,8 +510,7 @@ export const buy: EPR = async (info, data, send) => {
|
|||
|
||||
export const print: EPR = async (info, data, send) => {
|
||||
const genesisCards = $(data).elements('genesis_card');
|
||||
var genesisCardsArray = [];
|
||||
var generatorArray = [];
|
||||
let generatorArray = [];
|
||||
for (const g of genesisCards) {
|
||||
let tempGeneratorID = g.number('generator_id');
|
||||
let exist = generatorArray.findIndex((e) => (e == tempGeneratorID));
|
||||
|
|
@ -775,5 +528,5 @@ export const print: EPR = async (info, data, send) => {
|
|||
generator_id: K.ITEM('s32', r),
|
||||
param: K.ITEM('s32', 10),
|
||||
}))
|
||||
}), { status: "0" };
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
import { Profile } from '../models/profile';
|
||||
import { MusicRecord } from '../models/music_record';
|
||||
import { Item } from '../models/item';
|
||||
import { getVersion, IDToCode, GetCounter } from '../utils';
|
||||
import { Mix } from '../models/mix';
|
||||
import { fstat } from 'fs';
|
||||
import { error } from 'console';
|
||||
import { setMaxIdleHTTPParsers } from 'http';
|
||||
import { unpackS3P } from '../s3p';
|
||||
import { secureHeapUsed } from 'crypto';
|
||||
|
||||
export const updateProfile = async (data: {
|
||||
refid: string;
|
||||
|
|
@ -15,6 +21,13 @@ export const updateProfile = async (data: {
|
|||
stampB?: string;
|
||||
stampC?: string;
|
||||
stampD?: string;
|
||||
stampA_R?: string;
|
||||
stampB_R?: string;
|
||||
stampC_R?: string;
|
||||
stampD_R?: string;
|
||||
mainbg?: string;
|
||||
appeal_frame?: string;
|
||||
support_team?: string;
|
||||
}) => {
|
||||
if (data.refid == null) return;
|
||||
|
||||
|
|
@ -38,6 +51,16 @@ export const updateProfile = async (data: {
|
|||
if (!_.isNaN(validAka)) update.akaname = validAka;
|
||||
}
|
||||
|
||||
if (data.appeal_frame && data.appeal_frame.length > 0) {
|
||||
const validAppealFrame = parseInt(data.appeal_frame);
|
||||
if (!_.isNaN(validAppealFrame)) update.appeal_frame = validAppealFrame;
|
||||
}
|
||||
|
||||
if (data.support_team && data.support_team.length > 0) {
|
||||
const validSupportTeam = parseInt(data.support_team);
|
||||
if (!_.isNaN(validSupportTeam)) update.support_team = validSupportTeam;
|
||||
}
|
||||
|
||||
if (data.nemsys && data.nemsys.length > 0) {
|
||||
const validNemsys = parseInt(data.nemsys);
|
||||
if (!_.isNaN(validNemsys)) update.nemsys = validNemsys;
|
||||
|
|
@ -73,6 +96,31 @@ export const updateProfile = async (data: {
|
|||
if (!_.isNaN(validStampD)) update.stampD = validStampD;
|
||||
}
|
||||
|
||||
if (data.stampA_R && data.stampA_R.length > 0) {
|
||||
const validStampA_R = parseInt(data.stampA_R);
|
||||
if (!_.isNaN(validStampA_R)) update.stampA_R = validStampA_R;
|
||||
}
|
||||
|
||||
if (data.stampB_R && data.stampB_R.length > 0) {
|
||||
const validStampB_R = parseInt(data.stampB_R);
|
||||
if (!_.isNaN(validStampB_R)) update.stampB_R = validStampB_R;
|
||||
}
|
||||
|
||||
if (data.stampC_R && data.stampC_R.length > 0) {
|
||||
const validStampC_R = parseInt(data.stampC_R);
|
||||
if (!_.isNaN(validStampC_R)) update.stampC_R = validStampC_R;
|
||||
}
|
||||
|
||||
if (data.stampD_R && data.stampD_R.length > 0) {
|
||||
const validStampD_R = parseInt(data.stampD_R);
|
||||
if (!_.isNaN(validStampD_R)) update.stampD_R = validStampD_R;
|
||||
}
|
||||
|
||||
if (data.mainbg && data.mainbg.length > 0) {
|
||||
const validMainbg = parseInt(data.mainbg);
|
||||
if (!_.isNaN(validMainbg)) update.mainbg = validMainbg;
|
||||
}
|
||||
|
||||
await DB.Update<Profile>(
|
||||
data.refid,
|
||||
{ collection: 'profile' },
|
||||
|
|
@ -155,4 +203,266 @@ export const deleteMix = async (data: { code: string }) => {
|
|||
await DB.Remove<Mix>({ collection: 'mix', code: data.code });
|
||||
};
|
||||
|
||||
export const make_hexa_easier = async(data:{
|
||||
refid:string;
|
||||
}, send: WebUISend) => {
|
||||
let all_hexa = await DB.Find<Item>(data.refid, { collection: 'item' ,type:16 })
|
||||
let playedNum = [] // Prevent previous unlocked hexa from being locked again
|
||||
all_hexa.forEach((item:Item)=>{
|
||||
console.log(item.id)
|
||||
if(item.param == 10000){
|
||||
playedNum.push(item.id)
|
||||
}
|
||||
});
|
||||
|
||||
for(let i = 1; i <= 71; i++){ // Hexa Diver 7, up to id = 50
|
||||
if(!playedNum.includes(i)){
|
||||
await DB.Upsert<Item>(
|
||||
data.refid,
|
||||
{collection:'item', id:i, type:16},
|
||||
{collection:'item', id:i, type:16, param:9000}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
send.json({status:"ok"})
|
||||
}
|
||||
|
||||
export const converted_received = async (data: { zip_file:any }, send: WebUISend) => {
|
||||
|
||||
}
|
||||
|
||||
|
||||
export const import_assets = async (data: { path: string }, send: WebUISend) => {
|
||||
|
||||
// await init(wasmUrl);
|
||||
// let ffmpeg = await Wasmer.fromRegistry("wasmer/ffmpeg");
|
||||
let Admzip = require('../../_shared/lib/adm-zip')
|
||||
let path = data.path
|
||||
console.log(path)
|
||||
let fs = require('fs')
|
||||
if (!fs.existsSync(path + '/data/graphics/')) {
|
||||
console.log('Path for Graphics does not exist.')
|
||||
send.error(400,'Path for Graphics does not exist.')
|
||||
return
|
||||
}
|
||||
|
||||
await fs.promises.cp(path + "/data/graphics/ap_card", './plugins/sdvx@asphyxia/webui/asset/ap_card', {recursive: true}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
await fs.promises.cp(path + "/data/graphics/chat_stamp", './plugins/sdvx@asphyxia/webui/asset/chat_stamp', {recursive: true}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
await fs.promises.cp(path + "/data/graphics/game_nemsys", './plugins/sdvx@asphyxia/webui/asset/nemsys', {recursive: true}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
await fs.promises.cp(path + "/data/graphics/submonitor_bg", './plugins/sdvx@asphyxia/webui/asset/submonitor_bg', {recursive: true}).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
if (!fs.existsSync(path + '/data/sound/')) {
|
||||
console.log('Path for sound does not exist.')
|
||||
send.error(400,'Path for sound does not exist.')
|
||||
return
|
||||
}
|
||||
|
||||
let zip = new Admzip()
|
||||
await fs.promises.readdir(path + "/data/sound/custom").then((files: any) => {
|
||||
// let file = files[0]
|
||||
console.log(files)
|
||||
|
||||
for(let i in files){
|
||||
let file = files[i]
|
||||
if(file.endsWith('.s3p')){
|
||||
fs.mkdirSync('./plugins/sdvx@asphyxia/webui/asset/temp/'+file, { recursive: true });
|
||||
// fs.mkdirSync('./plugins/sdvx@asphyxia/webui/asset/audio/'+file.substring(0, 9), { recursive: true });
|
||||
unpackS3P('./plugins/sdvx@asphyxia/webui/asset/temp/'+file, path + "/data/sound/custom/" + file, {})
|
||||
// fs.promises.readFileSync('./plugins/sdvx@asphyxia/webui/asset/temp/'+file+'/0.wma').then(async (data: any) => {
|
||||
// const instance = await ffmpeg.entrypoint.run({
|
||||
// args: ["-i", "-", "-f", "wav", "-"],
|
||||
// stdin: new Uint8Array(data),
|
||||
// });
|
||||
// const { stdout } = await instance.wait();
|
||||
// fs.writeFileSync('./plugins/sdvx@asphyxia/webui/asset/audio/'+file.substring(0, 9)+'/0.wav', stdout);
|
||||
|
||||
// })
|
||||
// exec(shell([ffmpeg, '-i', './plugins/sdvx@asphyxia/webui/asset/temp/'+file+'/0.wma', './plugins/sdvx@asphyxia/webui/asset/audio/'+file.substring(0, 9)+'/0.mp3']), (err: any, stdout: any, stderr: any) => {
|
||||
// console.log(err)
|
||||
// })
|
||||
|
||||
// exec(shell([ffmpeg, '-i', './plugins/sdvx@asphyxia/webui/asset/temp/'+file+'/1.wma', './plugins/sdvx@asphyxia/webui/asset/audio/'+file.substring(0, 9)+'/1.mp3']), (err: any, stdout: any, stderr: any) => {
|
||||
// console.log(err)
|
||||
// })
|
||||
|
||||
// if(fs.existsSync('./plugins/sdvx@asphyxia/webui/asset/temp/'+file+'/2.wma')){
|
||||
// exec(shell([ffmpeg, '-i', './plugins/sdvx@asphyxia/webui/asset/temp/'+file+'/2.wma', './plugins/sdvx@asphyxia/webui/asset/audio/'+file.substring(0, 9)+'/2.mp3']), (err: any, stdout: any, stderr: any) => {
|
||||
// console.log(err)
|
||||
// })
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}).finally(() => {
|
||||
|
||||
zip.addLocalFolder('./plugins/sdvx@asphyxia/webui/asset/temp', 'temp')
|
||||
zip.writeZip('./plugins/sdvx@asphyxia/webui/asset/temp.zip')
|
||||
})
|
||||
|
||||
await fs.promises.rm('./plugins/sdvx@asphyxia/webui/asset/temp', { recursive: true, force: true }).catch((err: any) => {
|
||||
console.log(err)
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
console.log('Assets imported. Now converting audio files on browser...')
|
||||
send.file('webui/asset/temp.zip')
|
||||
|
||||
// fs.promises.rm('./plugins/sdvx@asphyxia/webui/asset/temp.zip', { force: true }).catch((err: any) => {
|
||||
// console.log(err)
|
||||
// })
|
||||
// send.json({status:"ok"})
|
||||
};
|
||||
|
||||
export const update_webui_nemsys_data = async (data: any, send: WebUISend) => {
|
||||
let string = data.file
|
||||
let nemsys_xml = U.parseXML(string)
|
||||
|
||||
const fs = require('fs')
|
||||
const filename = "../webui/asset/json/data.json"
|
||||
const datajson = require(filename)
|
||||
|
||||
nemsys_xml.custom_nemsys_data.info.filter((e: any) => e.id != 8 && e.id != 9 && e.id != 10 && e.id != 11).forEach((item: any) => {
|
||||
if(datajson.nemsys.filter((e: any) => e.value == item.id).length == 0){
|
||||
datajson.nemsys.push({
|
||||
value: item.id,
|
||||
name: item.texture_name
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
fs.writeFileSync("./plugins/sdvx@asphyxia/webui/asset/json/data.json", JSON.stringify(datajson, null, 2))
|
||||
send.json({status:"ok"})
|
||||
}
|
||||
|
||||
export const update_webui_stamp_data = async (data: any, send: WebUISend) => {
|
||||
let string = data.file
|
||||
let chat_stamp_xml = U.parseXML(string)
|
||||
|
||||
const fs = require('fs')
|
||||
const filename = "../webui/asset/json/data.json"
|
||||
const datajson = require(filename)
|
||||
|
||||
chat_stamp_xml.chat_stamp_data.info.forEach((item: any) => {
|
||||
if(datajson.stamp.filter((e: any) => e.value == item.id).length == 0){
|
||||
let addition = ""
|
||||
if(item.filename != ""){
|
||||
addition = item.filename.substring(item.filename.length - 2)
|
||||
}
|
||||
|
||||
datajson.stamp.push({
|
||||
value: item.id,
|
||||
name: item.title + " " +addition
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
fs.writeFileSync("./plugins/sdvx@asphyxia/webui/asset/json/data.json", JSON.stringify(datajson, null, 2))
|
||||
send.json({status:"ok"})
|
||||
}
|
||||
|
||||
export const update_webui_subbg_data = async (data: any, send: WebUISend) => {
|
||||
const fs = require('fs')
|
||||
const filename = "../webui/asset/json/data.json"
|
||||
const datajson = require(filename)
|
||||
|
||||
let subbg_folder = fs.readdirSync("./plugins/sdvx@asphyxia/webui/asset/submonitor_bg")
|
||||
let subbg_entry = {}
|
||||
subbg_folder.forEach((item: any) => {
|
||||
if(item.endsWith(".png")||item.endsWith(".mp4")){
|
||||
if(subbg_entry[item.substring(6, 10)] == undefined){
|
||||
subbg_entry[item.substring(6, 10)] = {"count":1, "video":false}
|
||||
}else{
|
||||
subbg_entry[item.substring(6, 10)]["count"] += 1
|
||||
}
|
||||
}
|
||||
if(item.endsWith(".mp4")){
|
||||
subbg_entry[item.substring(6, 10)]["video"] = true
|
||||
}
|
||||
})
|
||||
|
||||
console.log(JSON.stringify(subbg_entry, null, 2))
|
||||
|
||||
Object.keys(subbg_entry).forEach((item: any) => {
|
||||
if(datajson.subbg.filter((e: any) => e.value == item).length == 0){
|
||||
if(subbg_entry[item]["video"]){
|
||||
datajson.subbg.push({
|
||||
value: parseInt(item),
|
||||
name: "SubBG "+ item,
|
||||
video: true,
|
||||
})
|
||||
}else if(subbg_entry[item]["count"] > 1){
|
||||
datajson.subbg.push({
|
||||
value: parseInt(item),
|
||||
name: "SubBG "+ item,
|
||||
multi: true,
|
||||
})
|
||||
}else{
|
||||
datajson.subbg.push({
|
||||
value: parseInt(item),
|
||||
name: "SubBG "+ item,
|
||||
})
|
||||
}
|
||||
}else{
|
||||
if(subbg_entry[item]["video"]){
|
||||
datajson.subbg.forEach((e: any) => {
|
||||
if(e.value == parseInt(item)){
|
||||
e.video = true
|
||||
}
|
||||
})
|
||||
}else if(subbg_entry[item]["count"] > 1){
|
||||
datajson.subbg.forEach((e: any) => {
|
||||
if(e.value == parseInt(item)){
|
||||
e.multi = true
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
fs.writeFileSync("./plugins/sdvx@asphyxia/webui/asset/json/data.json", JSON.stringify(datajson, null, 2))
|
||||
send.json({status:"ok"})
|
||||
}
|
||||
|
||||
export const update_webui_bgm_data = async (data: any, send: WebUISend) => {
|
||||
const fs = require('fs')
|
||||
const filename = "../webui/asset/json/data.json"
|
||||
const datajson = require(filename)
|
||||
|
||||
let bgm_folder = fs.readdirSync("./plugins/sdvx@asphyxia/webui/asset/audio")
|
||||
let bgm_entry = []
|
||||
|
||||
bgm_folder.forEach((item: any) => {
|
||||
if(item.substring(0, 6) == "custom"){
|
||||
bgm_entry.push(parseInt(item.substring(item.length - 2)))
|
||||
}
|
||||
})
|
||||
|
||||
console.log(bgm_entry)
|
||||
|
||||
bgm_entry.forEach((item: any) => {
|
||||
if(datajson.bgm.filter((e: any) => e.value == item).length == 0){
|
||||
datajson.bgm.push({
|
||||
value: parseInt(item),
|
||||
name: "BGM "+ item,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
fs.writeFileSync("./plugins/sdvx@asphyxia/webui/asset/json/data.json", JSON.stringify(datajson, null, 2))
|
||||
send.json({status:"ok"})
|
||||
}
|
||||
|
|
@ -1,10 +1,24 @@
|
|||
import {common,log} from './handlers/common';
|
||||
import {hiscore, rival, saveMix, loadMix, globalMatch} from './handlers/features';
|
||||
// import {} from './handlers/sv4/';
|
||||
// import {} from './handlers/sv5/';
|
||||
// import {} from './handlers/sv6/';
|
||||
import {
|
||||
updateProfile,
|
||||
updateMix,
|
||||
importMix,
|
||||
deleteMix,
|
||||
make_hexa_easier,
|
||||
import_assets,
|
||||
update_webui_nemsys_data,
|
||||
update_webui_stamp_data,
|
||||
update_webui_subbg_data,
|
||||
update_webui_bgm_data
|
||||
// sendImg,
|
||||
// sendImgWithID,
|
||||
// getScore,
|
||||
// getScoreCount,
|
||||
// test
|
||||
} from './handlers/webui';
|
||||
import {
|
||||
load,
|
||||
|
|
@ -17,9 +31,29 @@ import {
|
|||
print,
|
||||
} from './handlers/profiles';
|
||||
|
||||
import { MusicRecord } from './models/music_record';
|
||||
|
||||
enum Version{
|
||||
Booth = 'game.',
|
||||
II = 'game_2.',
|
||||
GW = 'game_3.',
|
||||
HH = 'game.sv4_',
|
||||
VW = 'game.sv5_',
|
||||
EG = 'game.sv6_',
|
||||
}
|
||||
|
||||
export let music_db;
|
||||
|
||||
function load_music_db(){
|
||||
IO.ReadFile('./webui/asset/json/music_db.json',{encoding:'utf8'}).then(data => {
|
||||
music_db = JSON.parse(data);
|
||||
console.log('music_db loaded, total: '+music_db.mdb.music.length);
|
||||
})
|
||||
}
|
||||
|
||||
export function register() {
|
||||
|
||||
R.Contributor("LatoWolf#1170");
|
||||
R.Contributor("LatoWolf");
|
||||
R.GameCode('KFC');
|
||||
|
||||
R.Config('unlock_all_songs', { type: 'boolean', default: false, name:'Unlock All Songs'});
|
||||
|
|
@ -29,21 +63,23 @@ export function register() {
|
|||
R.Config('use_asphyxia_gameover',{ type: 'boolean', default: true, name:'Use Asphyxia Gameover', desc:'Enable the Asphyxia gameover message after ending the game.'})
|
||||
R.Config('use_blasterpass',{ type: 'boolean', default: true, name:'Use Blaster Pass', desc:'Enable Blaster Pass for VW and EG'});
|
||||
R.Config('new_year_special',{ type: 'boolean', default: true, name:'Use New Year Special', desc:'Enable New Year Special BGM for login'});
|
||||
|
||||
R.Config('music_count',{ type: 'integer', default: 2200, name:'Music Count', desc:'The maximum id of music in the game.'});
|
||||
|
||||
R.WebUIEvent('updateProfile', updateProfile);
|
||||
R.WebUIEvent('updateMix', updateMix);
|
||||
R.WebUIEvent('importMix', importMix);
|
||||
R.WebUIEvent('deleteMix', deleteMix);
|
||||
R.WebUIEvent('easyHexa', make_hexa_easier);
|
||||
R.WebUIEvent('import_assets', import_assets);
|
||||
R.WebUIEvent('update_webui_nemsys', update_webui_nemsys_data);
|
||||
R.WebUIEvent('update_webui_chat_stamp', update_webui_stamp_data);
|
||||
R.WebUIEvent('update_webui_subbg', update_webui_subbg_data);
|
||||
R.WebUIEvent('update_webui_bgm', update_webui_bgm_data);
|
||||
|
||||
const MultiRoute = (method: string, handler: EPR | boolean) => {
|
||||
// Helper for register multiple versions.
|
||||
R.Route(`game.${method}`, handler);
|
||||
R.Route(`game_2.${method}`, handler);
|
||||
//R.Route(`game_3.${method}`, handler);
|
||||
R.Route(`game.sv4_${method}`, handler);
|
||||
R.Route(`game.sv5_${method}`, handler);
|
||||
R.Route(`game.sv6_${method}`, handler);
|
||||
};
|
||||
|
||||
|
||||
// Common
|
||||
MultiRoute('common', common);
|
||||
|
|
@ -72,7 +108,8 @@ export function register() {
|
|||
MultiRoute('shop', (_, __, send) => send.object({
|
||||
nxt_time: K.ITEM('u32', 1000 * 5 * 60)
|
||||
}));
|
||||
MultiRoute('save_e', true);
|
||||
|
||||
MultiRoute('save_e', true);
|
||||
MultiRoute('save_mega',true);
|
||||
MultiRoute('play_e', true);
|
||||
MultiRoute('play_s', true);
|
||||
|
|
@ -98,6 +135,8 @@ export function register() {
|
|||
//logerrlevel: K.ITEM('s32', 0),
|
||||
//evtidnosendflg: K.ITEM('s32', 0)
|
||||
}));
|
||||
|
||||
|
||||
|
||||
|
||||
R.Unhandled();
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ export interface CourseRecord {
|
|||
collection: 'course';
|
||||
|
||||
version: number;
|
||||
|
||||
skill_type: number;
|
||||
sid: number;
|
||||
cid: number;
|
||||
score: number;
|
||||
exscore: number;
|
||||
clear: number;
|
||||
grade: number;
|
||||
rate: number;
|
||||
|
|
|
|||
9
sdvx@asphyxia/models/matching.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
export interface MatchingRoom{
|
||||
gameID: number;
|
||||
gip: string;
|
||||
lip: string;
|
||||
port: number;
|
||||
filter: number;
|
||||
sec: number;
|
||||
}
|
||||
|
|
@ -21,6 +21,8 @@ export interface Profile {
|
|||
blasterEnergy: number;
|
||||
blasterCount: number;
|
||||
extrackEnergy: number;
|
||||
appeal_frame: number;
|
||||
support_team: number;
|
||||
|
||||
hiSpeed: number;
|
||||
laneSpeed: number;
|
||||
|
|
@ -42,5 +44,11 @@ export interface Profile {
|
|||
stampC: number;
|
||||
stampD: number;
|
||||
|
||||
stampA_R: number;
|
||||
stampB_R: number;
|
||||
stampC_R: number;
|
||||
stampD_R: number;
|
||||
mainbg: number;
|
||||
|
||||
boothFrame: number[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,4 +6,5 @@ export interface Skill {
|
|||
level: number;
|
||||
base: number;
|
||||
name: number;
|
||||
stype: number;
|
||||
}
|
||||
|
|
|
|||
211
sdvx@asphyxia/s3p.ts
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
export function unpackS3P(directory, filePath, names) {
|
||||
const stream = fs.readFileSync(filePath);
|
||||
if (stream.slice(0, 4).toString() !== 'S3P0') {
|
||||
throw new Error('Invalid S3P file');
|
||||
}
|
||||
|
||||
let offset = 4;
|
||||
const entries = stream.readUInt32LE(offset);
|
||||
offset += 4;
|
||||
|
||||
const offsets = [];
|
||||
for (let i = 0; i < entries; i++) {
|
||||
const offsetValue = stream.readUInt32LE(offset);
|
||||
offset += 4;
|
||||
const length = stream.readUInt32LE(offset);
|
||||
offset += 4;
|
||||
offsets.push([offsetValue, length]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (let n = 0; n < offsets.length; n++) {
|
||||
const [offsetValue, length] = offsets[n];
|
||||
offset = offsetValue;
|
||||
if (stream.slice(offset, offset + 4).toString() !== 'S3V0') {
|
||||
throw new Error('Invalid S3V0 header');
|
||||
}
|
||||
offset += 4;
|
||||
const hlen = stream.readUInt32LE(offset);
|
||||
offset += 4;
|
||||
const headerExtra = stream.slice(offset, offset + hlen - 8);
|
||||
offset += hlen - 8;
|
||||
// const [wmaFileLength, , , , , , ,] = new Uint32Array(headerExtra.buffer);
|
||||
|
||||
const data = stream.slice(offset, offset + length - hlen);
|
||||
offset += length - hlen;
|
||||
|
||||
const outPath = path.join(directory, `${names[n] || n}.wma`);
|
||||
console.log(`I: ${outPath}`);
|
||||
fs.writeFileSync(outPath, data);
|
||||
}
|
||||
}
|
||||
|
||||
export function packS3P(directory, output, names) {
|
||||
let paths = fs.readdirSync(directory);
|
||||
if (names) {
|
||||
const namesBack = {};
|
||||
for (const key in names) {
|
||||
namesBack[names[key]] = key;
|
||||
}
|
||||
paths = paths.filter((i) => namesBack[i.split('.')[0]]);
|
||||
paths.sort((a, b) => namesBack[a.split('.')[0]] - namesBack[b.split('.')[0]]);
|
||||
} else {
|
||||
paths.sort((a, b) => parseInt(a.split('.')[0]) - parseInt(b.split('.')[0]));
|
||||
}
|
||||
|
||||
let offset = 0;
|
||||
const out = Buffer.alloc(4 + 4 + 8 * paths.length);
|
||||
|
||||
out.write('S3P0', offset, 'binary');
|
||||
offset += 4;
|
||||
|
||||
out.writeUInt32LE(paths.length, offset);
|
||||
offset += 4;
|
||||
|
||||
for (let i = 0; i < paths.length; i++) {
|
||||
out.writeUInt32LE(0, offset);
|
||||
offset += 4;
|
||||
out.writeUInt32LE(0, offset);
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
const offsets = [];
|
||||
for (const i of paths) {
|
||||
const data = fs.readFileSync(path.join(directory, i));
|
||||
offsets.push([offset, data.length + 32]);
|
||||
|
||||
out.write('S3V0', offset, 'binary');
|
||||
offset += 4;
|
||||
|
||||
out.writeUInt32LE(32, offset);
|
||||
offset += 4;
|
||||
|
||||
const headerExtra = Buffer.alloc(20);
|
||||
headerExtra.writeUInt32LE(data.length, 0);
|
||||
headerExtra.writeUInt32LE(0, 4); // You might need to adjust this value
|
||||
headerExtra.writeUInt32LE(64130, 8);
|
||||
out.writeUInt16LE(0, 12); // Short
|
||||
out.writeUInt16LE(0, 14); // Short
|
||||
out.writeUInt16LE(0, 16); // Short
|
||||
out.writeUInt16LE(0, 18); // Short
|
||||
out.writeUInt32LE(0, 20); // Reserved
|
||||
headerExtra.copy(out, offset + 4, 0, 20); // Copy headerExtra excluding the first 4 bytes
|
||||
offset += 24;
|
||||
|
||||
data.copy(out, offset, 0, data.length);
|
||||
offset += data.length;
|
||||
}
|
||||
|
||||
// Re-write tracks table
|
||||
offset = 8;
|
||||
for (const [offsetValue, length] of offsets) {
|
||||
out.writeUInt32LE(offsetValue, offset);
|
||||
offset += 4;
|
||||
out.writeUInt32LE(length, offset);
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
fs.writeFileSync(output, out);
|
||||
}
|
||||
|
||||
|
||||
function usage() {
|
||||
console.log(`Usage: node ${process.argv[1]} pack <output.s3p> <directory> [enum/def path]`);
|
||||
console.log(` node ${process.argv[1]} unpack <intput.s3p> <directory> [enum/def path]`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function loadNames(filePath) {
|
||||
const base = path.join(path.dirname(filePath), path.basename(filePath, path.extname(filePath)));
|
||||
const filenames = {};
|
||||
|
||||
if (fs.existsSync(base + '.def')) {
|
||||
const defData = fs.readFileSync(base + '.def', 'utf8');
|
||||
const lines = defData.split('\n');
|
||||
for (const line of lines) {
|
||||
if (line.trim().startsWith('#define')) {
|
||||
const [, name, id] = line.trim().split(/\s+/);
|
||||
filenames[parseInt(id)] = name;
|
||||
}
|
||||
}
|
||||
} else if (fs.existsSync(base + '.enum')) {
|
||||
const enumData = fs.readFileSync(base + '.enum', 'utf8');
|
||||
if (enumData.startsWith('enum struct ')) {
|
||||
const lines = enumData.split('\n');
|
||||
for (let i = 1; i < lines.length; i++) {
|
||||
const line = lines[i].trim();
|
||||
if (line === '};') {
|
||||
break;
|
||||
}
|
||||
filenames[i - 1] = line.replace(',', '').trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return filenames;
|
||||
}
|
||||
|
||||
// function main() {
|
||||
// if (process.argv.length !== 5 && process.argv.length !== 6) {
|
||||
// usage();
|
||||
// }
|
||||
// if (process.argv[2] !== 'pack' && process.argv[2] !== 'unpack') {
|
||||
// usage();
|
||||
// }
|
||||
|
||||
// const s3p = process.argv[3];
|
||||
// const directory = process.argv[4];
|
||||
|
||||
// let names = {};
|
||||
// if (process.argv.length === 6) {
|
||||
// names = loadNames(process.argv[5]);
|
||||
// } else {
|
||||
// names = loadNames(s3p);
|
||||
// }
|
||||
|
||||
// if (!names) {
|
||||
// console.log('W: Filenames not loaded');
|
||||
// }
|
||||
|
||||
// if (process.argv[2] === 'pack') {
|
||||
// if (!fs.existsSync(directory)) {
|
||||
// console.error(`F: No such file or directory ${directory}`);
|
||||
// process.exit(1);
|
||||
// }
|
||||
|
||||
// const files = fs.readdirSync(directory);
|
||||
// if (!files.every((i) => /^\d+\.wma$/.test(i) || Object.values(names).includes(i.split('.')[0]))) {
|
||||
// console.error('F: Files must all be [number].wma');
|
||||
// process.exit(1);
|
||||
// }
|
||||
|
||||
// const dirname = path.dirname(s3p);
|
||||
// if (dirname) {
|
||||
// fs.mkdirSync(dirname, { recursive: true });
|
||||
// }
|
||||
|
||||
// packS3P(directory, s3p, names);
|
||||
// console.log(`I: ${s3p}`);
|
||||
// } else {
|
||||
// if (!fs.existsSync(s3p)) {
|
||||
// console.error(`F: No such file or directory ${s3p}`);
|
||||
// process.exit(1);
|
||||
// }
|
||||
|
||||
// if (fs.existsSync(directory) && !fs.lstatSync(directory).isDirectory()) {
|
||||
// console.error('F: Output is not a directory');
|
||||
// process.exit(1);
|
||||
// }
|
||||
|
||||
// fs.mkdirSync(directory, { recursive: true });
|
||||
// unpackS3P(directory, s3p, names);
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (require.main === module) {
|
||||
// main();
|
||||
// }
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
- let music = 0;
|
||||
- let event = 0;
|
||||
- let catalog = 0;
|
||||
|
||||
game
|
||||
limited
|
||||
while music < 200
|
||||
music(id=music++, flag=2)
|
||||
|
||||
event
|
||||
while event < 16
|
||||
info(id=event++)
|
||||
|
||||
catalog
|
||||
while catalog < 256
|
||||
info(id=catalog++, currency=1, price=1)
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
game
|
||||
name(__type="str") #{name}
|
||||
code(__type="str") #{code}
|
||||
gamecoin_packet(__type="u32") #{packets}
|
||||
gamecoin_block(__type="u32") #{blocks}
|
||||
exp_point(__type="u32") #{expPoint ? expPoint : 0}
|
||||
m_user_cnt(__type="u32") #{mUserCnt ? mUserCnt : 0}
|
||||
have_item(__type="bool" __count=512) #{Array(512).fill(1).join(" ")}
|
||||
have_note(__type="bool" __count=512) #{Array(512).fill(1).join(" ")}
|
||||
|
||||
last(
|
||||
music_id=musicID,
|
||||
music_type=musicType,
|
||||
sort_type=sortType,
|
||||
headphone=headphone,
|
||||
hispeed=hiSpeed,
|
||||
appeal_id=appeal,
|
||||
frame0=boothFrame ? boothFrame[0] : 0,
|
||||
frame1=boothFrame ? boothFrame[1] : 0,
|
||||
frame2=boothFrame ? boothFrame[2] : 0,
|
||||
frame3=boothFrame ? boothFrame[3] : 0,
|
||||
frame4=boothFrame ? boothFrame[4] : 0,
|
||||
)
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
- let music = 0;
|
||||
- let event = 0;
|
||||
- let catalog = 0;
|
||||
|
||||
|
||||
game
|
||||
music_limited
|
||||
while music < 23
|
||||
each type in [0,1,2,3]
|
||||
info
|
||||
music_id(__type="s32") #{music++}
|
||||
music_type(__type="u8") #{type}
|
||||
limited(__type="u8") 3
|
||||
|
||||
event
|
||||
while event < 41
|
||||
info
|
||||
event_id(__type="u32") #{event++}
|
||||
|
||||
skill_course
|
||||
each course in courses
|
||||
info
|
||||
course_id(__type="s16") #{course.id}
|
||||
level(__type="s16") #{course.level}
|
||||
season_id(__type="s16") #{course.season_id}
|
||||
season_name(__type="str") #{course.season_name}
|
||||
season_new_flg(__type="bool") #{course.new_flg}
|
||||
course_name(_type="str") #{course.name}
|
||||
course_type(__type="s16") #{course.type}
|
||||
skill_name_id(__type="s16") #{course.name_id}
|
||||
matching_assist(__type="bool") #{course.matching_assist}
|
||||
guage_type(__type="s16") #{course.guage_type}
|
||||
paseli_type(type="s16") #{course.paseli_type}
|
||||
each trackinfo in course.tracks
|
||||
track
|
||||
track_no(__type="s16") #{trackinfo.no}
|
||||
music_id(__type="s32") #{trackinfo.id}
|
||||
music_type(__type="s8") #{trackinfo.type}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
game
|
||||
result(__type="u8") 0
|
||||
name(__type="str") #{name}
|
||||
code(__type="str") #{code}
|
||||
sdvx_id(__type="str") #{code}
|
||||
gamecoin_packet(__type="u32") #{packets}
|
||||
gamecoin_block(__type="u32") #{blocks}
|
||||
|
||||
|
||||
last
|
||||
music_id(__type="s32") #{musicID}
|
||||
music_type(__type="u8") #{musicType}
|
||||
sort_type(__type="u8") #{sortType}
|
||||
comment_id(__type="u16") 0
|
||||
appeal_id(__type="u16") #{appeal}
|
||||
headphone(__type="u8") #{headphone}
|
||||
narrow_down(__type="u8") #{narrowDown}
|
||||
gauge_option(__type="u8") #{gaugeOption}
|
||||
blaster_energy(__type="u32") #{blasterEnergy}
|
||||
blaster_count(__type="u32") #{blasterCount}
|
||||
extrack_energy(__type="u16") #{extrackEnergy}
|
||||
|
||||
hispeed(__type="s32") #{hiSpeed}
|
||||
lanespeed(__type="u32") #{laneSpeed}
|
||||
|
||||
ars_option(__type="u8") #{arsOption}
|
||||
notes_option(__type="u8") #{notesOption}
|
||||
early_late_disp(__type="u8") #{earlyLateDisp}
|
||||
draw_adjust(__type="s32") #{drawAdjust}
|
||||
eff_c_left(__type="u8") #{effCLeft}
|
||||
eff_c_right(__type="u8") #{effCRight}
|
||||
|
||||
|
||||
kac_id(__type="str") #{name}
|
||||
|
||||
skill_level(__type="s16") #{skill.level}
|
||||
skill_base_id(__type="s16") #{skill.base}
|
||||
skill_name_id(__type="s16") #{skill.name}
|
||||
|
||||
ea_shop
|
||||
packet_booster(__type="s32") 1
|
||||
if version < 5
|
||||
block_booster(__type="s32") 1
|
||||
if version >= 5
|
||||
blaster_pass_enable(__type="bool") 1
|
||||
blaster_pass_limit_date(__type="u64") #{currentTime}
|
||||
|
||||
eaappli
|
||||
relation(__type="s8") 1
|
||||
cloud
|
||||
relation(__type="s8") 1
|
||||
block_no(__type="s32") 0
|
||||
|
||||
skill
|
||||
course
|
||||
each course in courses
|
||||
d
|
||||
ssnid(__type="s16") #{course.sid}
|
||||
crsid(__type="s16") #{course.cid}
|
||||
sc(__type="s32") #{course.score}
|
||||
ex(__type="s32") 0
|
||||
ct(__type="s16") #{course.clear}
|
||||
gr(__type="s16") #{course.grade}
|
||||
ar(__type="s16") #{course.rate}
|
||||
cnt(__type="s16") #{course.count}
|
||||
course_total
|
||||
each course in courses
|
||||
d
|
||||
ssnid(__type="s16") #{course.sid}
|
||||
crsid(__type="s16") #{course.cid}
|
||||
sc(__type="s32") #{course.score}
|
||||
ex(__type="s32") 0
|
||||
ct(__type="s16") #{course.clear}
|
||||
gr(__type="s16") #{course.grade}
|
||||
ar(__type="s16") #{course.rate}
|
||||
cnt(__type="s16") #{course.count}
|
||||
course_all
|
||||
each course in courses
|
||||
d
|
||||
ssnid(__type="s16") #{course.sid}
|
||||
crsid(__type="s16") #{course.cid}
|
||||
sc(__type="s32") #{course.score}
|
||||
ex(__type="s32") 0
|
||||
ct(__type="s16") #{course.clear}
|
||||
gr(__type="s16") #{course.grade}
|
||||
ar(__type="s16") #{course.rate}
|
||||
cnt(__type="s16") #{course.count}
|
||||
|
||||
item
|
||||
each item in tempItem
|
||||
info
|
||||
type(__type="u8") #{item.type}
|
||||
id(__type="u32") #{item.id}
|
||||
param(__type="u32") #{item.param}
|
||||
|
||||
|
||||
play_count(__type="u32") 1001
|
||||
day_count(__type="u32") 301
|
||||
today_count(__type="u32") 21
|
||||
play_chain(__type="u32") 31
|
||||
max_play_chain(__type="u32") 31
|
||||
week_count(__type="u32") 9
|
||||
week_play_count(__type="u32") 101
|
||||
week_chain(__type="u32") 31
|
||||
max_week_chain(__type="u32") 31
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
game
|
||||
new
|
||||
each music in temp
|
||||
music
|
||||
music_id (__type="u32")#{music.mid}
|
||||
music_type (__type="u32")#{music.type}
|
||||
score (__type="u32")#{music.score}
|
||||
cnt (__type="u32")1
|
||||
clear_type (__type="u32")#{music.clear}
|
||||
score_grade (__type="u32")#{music.grade}
|
||||
btn_rate (__type="u32")#{music.buttonRate}
|
||||
long_rate (__type="u32")#{music.longRate}
|
||||
vol_rate (__type="u32")#{music.volRate}
|
||||
old
|
||||
|
|
@ -29,6 +29,7 @@ game
|
|||
kac_id(__type="str") #{name}
|
||||
|
||||
skill_level(__type="s16") #{skill.level}
|
||||
skill_type(__type="s16") #{skill.stype}
|
||||
skill_base_id(__type="s16") #{skill.base}
|
||||
skill_name_id(__type="s16") #{skill.name}
|
||||
|
||||
|
|
@ -51,8 +52,9 @@ game
|
|||
course
|
||||
ssnid(__type="s16") #{course.sid}
|
||||
crsid(__type="s16") #{course.cid}
|
||||
st(__type="s16") #{course.skill_type}
|
||||
sc(__type="s32") #{course.score}
|
||||
ex(__type="s32") 0
|
||||
ex(__type="s32") #{course.exscore}
|
||||
ct(__type="s16") #{course.clear}
|
||||
gr(__type="s16") #{course.grade}
|
||||
ar(__type="s16") #{course.rate}
|
||||
|
|
@ -96,6 +98,25 @@ game
|
|||
week_chain(__type="u32") 31
|
||||
max_week_chain(__type="u32") 31
|
||||
|
||||
creator_item
|
||||
info
|
||||
creator_type(__type="u32") #{appeal_frame}
|
||||
item_id(__type="u32") 0
|
||||
param(__type="u32") 0
|
||||
|
||||
|
||||
arena
|
||||
last_play_season(__type="s32") 3
|
||||
rank_point(__type="s32") 30000
|
||||
shop_point(__type="s32") 0
|
||||
ultimate_rate(__type="s32") 0
|
||||
rank_play_cnt(__type="s32") 1
|
||||
ultimate_play_cnt(__type="s32") 1
|
||||
|
||||
//- additional_info
|
||||
|
||||
support_team_id(__type="s32") #{support_team}
|
||||
|
||||
if mixes
|
||||
each mix in mixes
|
||||
automation
|
||||
|
|
@ -108,4 +129,5 @@ game
|
|||
distribution_date(__type="u32") 20200101
|
||||
jacket_id(__type="s32") #{mix.jacket}
|
||||
tag_bit(__type="s32") #{mix.tag}
|
||||
like_flg(__type="u8") 0
|
||||
like_flg(__type="u8") 0
|
||||
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import {Counter} from './models/counter';
|
||||
import { music_db } from '.';
|
||||
|
||||
export function IDToCode(id: number) {
|
||||
const padded = _.padStart(id.toString(), 8);
|
||||
|
|
@ -21,7 +22,6 @@ export function getVersion(info: EamuseInfo) {
|
|||
if (dateCode <= 2016121200) return 3;
|
||||
if (info.method.startsWith('sv4')) return 4;
|
||||
if (info.method.startsWith('sv5')) return 5;
|
||||
if (dateCode >= 2021083100) return -6;
|
||||
if (info.method.startsWith('sv6')) return 6;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -30,4 +30,133 @@ export function getRandomIntInclusive(min, max) {
|
|||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(Math.random() * (max - min + 1) + min); //The maximum is inclusive and the minimum is inclusive
|
||||
}
|
||||
|
||||
export function add_extend(e_id: number, e_type: number,
|
||||
p1: number, p2: number, p3: number, p4: number, p5: number,
|
||||
sp1: string, sp2: string, sp3: string, sp4: string, sp5: string){
|
||||
return {
|
||||
id: e_id,
|
||||
type: e_type,
|
||||
params: [
|
||||
p1,
|
||||
p2,
|
||||
p3,
|
||||
p4,
|
||||
p5,
|
||||
sp1,
|
||||
sp2,
|
||||
sp3,
|
||||
sp4,
|
||||
sp5,
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
export function getRandomCharaterRight(){
|
||||
|
||||
}
|
||||
|
||||
export function getRandomCharaterLeft(){
|
||||
|
||||
}
|
||||
|
||||
export function getRandomCharaterMiddle(){
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export function send_webhook(data: any) {
|
||||
let https = require('https');
|
||||
let contents = JSON.stringify({
|
||||
"content": null,
|
||||
"embeds": [
|
||||
{
|
||||
"title": "New SOUND VOLTEX Score",
|
||||
"color": 16711680,
|
||||
"fields": [
|
||||
{
|
||||
"name": "Player Name",
|
||||
"value": data.name
|
||||
},
|
||||
{
|
||||
"name": "Song Name",
|
||||
"value": data.id,
|
||||
"inline": true
|
||||
},
|
||||
{
|
||||
"name": "Difficulty",
|
||||
"value": data.type,
|
||||
"inline": true
|
||||
},
|
||||
{
|
||||
"name": "Score",
|
||||
"value": data.score,
|
||||
},
|
||||
{
|
||||
"name": "Ex Score",
|
||||
"value": data.exscore,
|
||||
},
|
||||
{
|
||||
"name": "Clear Medal",
|
||||
"value": data.clear,
|
||||
"inline": true
|
||||
},
|
||||
{
|
||||
"name": "Grade",
|
||||
"value": data.grade,
|
||||
},
|
||||
{
|
||||
"name": "S-Critical",
|
||||
"value": "0",
|
||||
"inline": true
|
||||
},
|
||||
{
|
||||
"name": "Critical",
|
||||
"value": "0",
|
||||
"inline": true
|
||||
},
|
||||
{
|
||||
"name": "Near",
|
||||
"value": "0",
|
||||
"inline": true
|
||||
},
|
||||
{
|
||||
"name": "Error",
|
||||
"value": "0",
|
||||
"inline": true
|
||||
}
|
||||
],
|
||||
"author": {
|
||||
"name": "Asphyxia CORE",
|
||||
"icon_url": "https://asphyxia-core.github.io/img/core-logo.png"
|
||||
},
|
||||
"thumbnail": {
|
||||
"url": "https://asphyxia-core.github.io/img/core-logo.png"
|
||||
}
|
||||
}
|
||||
],
|
||||
"attachments": []
|
||||
})
|
||||
console.log(contents);
|
||||
let options = {
|
||||
host:'discord.com',
|
||||
path:U.GetConfig('discord_webhook_url'),
|
||||
method:'POST',
|
||||
headers:{
|
||||
'Content-Type':'application/json; charset=utf-8',
|
||||
'Content-Length':contents.length
|
||||
}
|
||||
}
|
||||
if(U.GetConfig('discord_webhook')){
|
||||
let req = https.request(options, res => {
|
||||
console.log(`${res.statusCode}`);
|
||||
res.on('data', (d) => {
|
||||
// process.stdout.write(d);
|
||||
});
|
||||
});
|
||||
req.write(contents);
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |