Merge pull request #61 from dannylin0711/stable

SDVX EG S3 support
This commit is contained in:
Freddie Wang 2023-10-07 12:53:49 +08:00 committed by GitHub
commit ccd98fc76c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1919 changed files with 18048 additions and 12799 deletions

View File

@ -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.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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
},
]
},
];

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,32 @@
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';
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 = [];
@ -11,35 +35,9 @@ export const common: EPR = async (info, data, send) => {
const version = parseInt(info.model.split(":")[4]);
if (version <= 2013052900) {
return send.pugFile('templates/booth/common.pug');
}
if (version <= 2014112000) {
courses = COURSE2;
return send.pugFile('templates/infiniteinfection/common.pug',{
courses,
});
}
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));
events = EVENT6;
courses = COURSES6;
EXTENDS6.forEach(val => extend.push(Object.assign({}, val)));
break;
@ -49,11 +47,7 @@ export const common: EPR = async (info, data, send) => {
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 +75,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 +112,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 +159,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 +217,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 +254,39 @@ 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', [
1,1,1,1,
1,1,1,1,
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),
})),
}
},
{ encoding: 'utf8' }
);

View File

@ -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);
}

View File

@ -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>[]) {
@ -43,117 +42,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 +49,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 +62,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 +166,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 +272,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 +302,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 +330,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 +337,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 +362,18 @@ 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;
// 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 +383,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 +430,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 +498,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 +516,5 @@ export const print: EPR = async (info, data, send) => {
generator_id: K.ITEM('s32', r),
param: K.ITEM('s32', 10),
}))
}), { status: "0" };
});
}

View File

@ -1,7 +1,11 @@
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';
export const updateProfile = async (data: {
refid: string;
@ -15,6 +19,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 +49,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 +94,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 +201,52 @@ 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;
}) => {
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 <= 50; 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}
)
}
}
}
export const import_assets = async (data: { path: string }, send: WebUISend) => {
let path = data.path
console.log(path)
let fs = require('fs')
if (!fs.existsSync(path + '/data/graphics/')) {
console.log('Path does not exist.')
send.error(400,'Path 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)
})
console.log('Assets imported.')
send.json({status:"ok"})
};

View File

@ -1,10 +1,20 @@
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
// sendImg,
// sendImgWithID,
// getScore,
// getScoreCount,
// test
} from './handlers/webui';
import {
load,
@ -17,9 +27,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 +59,19 @@ 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 total number 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);
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 +100,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);

View File

@ -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;

View File

@ -0,0 +1,9 @@
export interface MatchingRoom{
gameID: number;
gip: string;
lip: string;
port: number;
filter: number;
sec: number;
}

View File

@ -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[];
}

View File

@ -6,4 +6,5 @@ export interface Skill {
level: number;
base: number;
name: number;
stype: number;
}

211
sdvx@asphyxia/s3p.ts Normal file
View 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();
// }

View File

@ -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

View File

@ -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);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Some files were not shown because too many files have changed in this diff Show More