mirror of
https://github.com/asphyxia-core/plugins.git
synced 2026-03-21 17:34:46 -05:00
Support Dance Dance Revolution A, A20
This commit is contained in:
parent
732d5ee6dc
commit
34f506c3ce
18
ddr@asphyxia/README.md
Normal file
18
ddr@asphyxia/README.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Dance Dance Revolution
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
Supported version
|
||||
|
||||
- Dance Dance Revolution A20
|
||||
- Dance Dance Revolution A
|
||||
|
||||
---
|
||||
|
||||
Changelogs
|
||||
|
||||
**v1.0.0**
|
||||
|
||||
- Initial release
|
||||
18
ddr@asphyxia/handlers/common.ts
Normal file
18
ddr@asphyxia/handlers/common.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
export const eventLog: EPR = (info, data, send) => {
|
||||
return send.object({
|
||||
gamesession: K.ITEM("s64", BigInt(1)),
|
||||
logsendflg: K.ITEM("s32", 0),
|
||||
logerrlevel: K.ITEM("s32", 0),
|
||||
evtidnosendflg: K.ITEM("s32", 0)
|
||||
});
|
||||
};
|
||||
|
||||
export const convcardnumber: EPR = (info, data, send) => {
|
||||
return send.object({
|
||||
result: K.ITEM("s32", 0),
|
||||
|
||||
data: {
|
||||
card_number: K.ITEM("str", $(data).str("data.card_id").split("|")[0])
|
||||
}
|
||||
});
|
||||
};
|
||||
275
ddr@asphyxia/handlers/usergamedata.ts
Normal file
275
ddr@asphyxia/handlers/usergamedata.ts
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
import { CommonOffset, LastOffset, OptionOffset, Profile } from "../models/profile";
|
||||
import { formatCode } from "../utils";
|
||||
import { Score } from "../models/score";
|
||||
import { Ghost } from "../models/ghost";
|
||||
|
||||
enum GameStyle {
|
||||
SINGLE,
|
||||
DOUBLE,
|
||||
VERSUS
|
||||
}
|
||||
|
||||
export const usergamedata: EPR = async (info, data, send) => {
|
||||
const mode = $(data).str("data.mode");
|
||||
const refId = $(data).str("data.refid");
|
||||
|
||||
switch (mode) {
|
||||
case "userload":
|
||||
return send.object(await userload(refId));
|
||||
case "usernew":
|
||||
return send.object(await usernew(refId, data));
|
||||
case "usersave":
|
||||
return send.object(await usersave(refId, data));
|
||||
case "rivalload":
|
||||
return send.object(await rivalload(refId, data));
|
||||
case "ghostload":
|
||||
return send.object(await ghostload(refId, data));
|
||||
case "inheritance":
|
||||
return send.object(inheritance(refId));
|
||||
default:
|
||||
return send.deny();
|
||||
}
|
||||
};
|
||||
|
||||
const userload = async (refId: string) => {
|
||||
let resObj = {
|
||||
result: K.ITEM("s32", 0),
|
||||
is_new: K.ITEM("bool", false),
|
||||
music: [],
|
||||
eventdata: []
|
||||
};
|
||||
|
||||
if (!refId.startsWith("X000")) {
|
||||
const profile = await DB.FindOne<Profile>(refId, { collection: "profile" });
|
||||
|
||||
if (!profile) resObj.is_new = K.ITEM("bool", true);
|
||||
|
||||
const scores = await DB.Find<Score>(refId, { collection: "score" });
|
||||
|
||||
for (const score of scores) {
|
||||
const note = [];
|
||||
|
||||
for (let i = 0; i < 9; i++) {
|
||||
if (score.difficulty !== i) {
|
||||
note.push({
|
||||
count: K.ITEM("u16", 0),
|
||||
rank: K.ITEM("u8", 0),
|
||||
clearkind: K.ITEM("u8", 0),
|
||||
score: K.ITEM("s32", 0),
|
||||
ghostid: K.ITEM("s32", 0)
|
||||
});
|
||||
} else {
|
||||
note.push({
|
||||
count: K.ITEM("u16", 1),
|
||||
rank: K.ITEM("u8", score.rank),
|
||||
clearkind: K.ITEM("u8", score.clearKind),
|
||||
score: K.ITEM("s32", score.score),
|
||||
ghostid: K.ITEM("s32", score.songId)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
resObj.music.push({
|
||||
mcode: K.ITEM("u32", score.songId),
|
||||
note
|
||||
});
|
||||
}
|
||||
|
||||
resObj["grade"] = {
|
||||
single_grade: K.ITEM("u32", profile.singleGrade || 0),
|
||||
dougle_grade: K.ITEM("u32", profile.doubleGrade || 0)
|
||||
};
|
||||
}
|
||||
|
||||
return resObj;
|
||||
};
|
||||
|
||||
const usernew = async (refId: string, data: any) => {
|
||||
const shopArea = $(data).str("data.shoparea", "");
|
||||
|
||||
let profile = await DB.FindOne<Profile>(refId, { collection: "profile" });
|
||||
|
||||
if (!profile) {
|
||||
profile = (await DB.Upsert<Profile>(refId, { collection: "profile" }, {
|
||||
collection: "profile",
|
||||
ddrCode: _.random(1, 99999999),
|
||||
shopArea
|
||||
})).docs[0];
|
||||
}
|
||||
|
||||
return {
|
||||
result: K.ITEM("s32", 0),
|
||||
seq: K.ITEM("str", formatCode(profile.ddrCode)),
|
||||
code: K.ITEM("s32", profile.ddrCode),
|
||||
shoparea: K.ITEM("str", profile.shopArea),
|
||||
};
|
||||
};
|
||||
|
||||
const usersave = async (refId: string, serverData: any) => {
|
||||
const profile = await DB.FindOne<Profile>(refId, { collection: "profile" });
|
||||
|
||||
if (profile) {
|
||||
const data = $(serverData).element("data");
|
||||
const notes = data.elements("note");
|
||||
const events = data.elements("event");
|
||||
|
||||
const common = profile.usergamedata.COMMON.strdata.split(",");
|
||||
const option = profile.usergamedata.OPTION.strdata.split(",");
|
||||
const last = profile.usergamedata.LAST.strdata.split(",");
|
||||
|
||||
if (data.bool("isgameover")) {
|
||||
const style = data.number("playstyle");
|
||||
|
||||
if (style === GameStyle.DOUBLE) {
|
||||
common[CommonOffset.DOUBLE_PLAYS] = (parseInt(common[CommonOffset.DOUBLE_PLAYS]) + 1) + "";
|
||||
} else {
|
||||
common[CommonOffset.SINGLE_PLAYS] = (parseInt(common[CommonOffset.SINGLE_PLAYS]) + 1) + "";
|
||||
}
|
||||
|
||||
common[CommonOffset.TOTAL_PLAYS] = (+common[CommonOffset.DOUBLE_PLAYS]) + (+common[CommonOffset.SINGLE_PLAYS]) + "";
|
||||
|
||||
const workoutEnabled = !!+common[CommonOffset.WEIGHT_DISPLAY];
|
||||
const workoutWeight = +common[CommonOffset.WEIGHT];
|
||||
|
||||
if (workoutEnabled && workoutWeight > 0) {
|
||||
let total = 0;
|
||||
|
||||
for (const note of notes) {
|
||||
total = total + note.number("calorie", 0);
|
||||
}
|
||||
|
||||
last[LastOffset.CALORIES] = total + "";
|
||||
}
|
||||
|
||||
for (const event of events) {
|
||||
const eventId = event.number("eventid", 0);
|
||||
const eventType = event.number("eventtype", 0);
|
||||
if (eventId === 0 || eventType === 0) continue;
|
||||
|
||||
const eventCompleted = event.number("comptime") !== 0;
|
||||
const eventProgress = event.number("savedata");
|
||||
|
||||
if (!profile.events) profile.events = {};
|
||||
profile.events[eventId] = {
|
||||
completed: eventCompleted,
|
||||
progress: eventProgress
|
||||
};
|
||||
}
|
||||
|
||||
const gradeNode = data.element("grade");
|
||||
|
||||
if (gradeNode) {
|
||||
const single = gradeNode.number("single_grade", 0);
|
||||
const double = gradeNode.number("double_grade", 0);
|
||||
|
||||
profile.singleGrade = single;
|
||||
profile.doubleGrade = double;
|
||||
}
|
||||
}
|
||||
|
||||
let scoreData: KDataReader | null;
|
||||
let stageNum = 0;
|
||||
|
||||
for (const note of notes) {
|
||||
if (note.number("stagenum") > stageNum) {
|
||||
scoreData = note;
|
||||
stageNum = note.number("stagenum");
|
||||
}
|
||||
}
|
||||
|
||||
if (scoreData) {
|
||||
const songId = scoreData.number("mcode");
|
||||
const difficulty = scoreData.number("notetype");
|
||||
const rank = scoreData.number("rank");
|
||||
const clearKind = scoreData.number("clearkind");
|
||||
const score = scoreData.number("score");
|
||||
const maxCombo = scoreData.number("maxcombo");
|
||||
const ghostSize = scoreData.number("ghostsize");
|
||||
const ghost = scoreData.str("ghost");
|
||||
|
||||
option[OptionOffset.SPEED] = scoreData.number("opt_speed").toString(16);
|
||||
option[OptionOffset.BOOST] = scoreData.number("opt_boost").toString(16);
|
||||
option[OptionOffset.APPEARANCE] = scoreData.number("opt_appearance").toString(16);
|
||||
option[OptionOffset.TURN] = scoreData.number("opt_turn").toString(16);
|
||||
option[OptionOffset.STEP_ZONE] = scoreData.number("opt_dark").toString(16);
|
||||
option[OptionOffset.SCROLL] = scoreData.number("opt_scroll").toString(16);
|
||||
option[OptionOffset.ARROW_COLOR] = scoreData.number("opt_arrowcolor").toString(16);
|
||||
option[OptionOffset.CUT] = scoreData.number("opt_cut").toString(16);
|
||||
option[OptionOffset.FREEZE] = scoreData.number("opt_freeze").toString(16);
|
||||
option[OptionOffset.JUMP] = scoreData.number("opt_jump").toString(16);
|
||||
option[OptionOffset.ARROW_SKIN] = scoreData.number("opt_arrowshape").toString(16);
|
||||
option[OptionOffset.FILTER] = scoreData.number("opt_filter").toString(16);
|
||||
option[OptionOffset.GUIDELINE] = scoreData.number("opt_guideline").toString(16);
|
||||
option[OptionOffset.GAUGE] = scoreData.number("opt_gauge").toString(16);
|
||||
option[OptionOffset.COMBO_POSITION] = scoreData.number("opt_judgepriority").toString(16);
|
||||
option[OptionOffset.FAST_SLOW] = scoreData.number("opt_timing").toString(16);
|
||||
|
||||
await DB.Upsert<Score>(refId, {
|
||||
collection: "score",
|
||||
songId,
|
||||
difficulty
|
||||
}, {
|
||||
$set: {
|
||||
rank,
|
||||
clearKind,
|
||||
score,
|
||||
maxCombo
|
||||
}
|
||||
});
|
||||
|
||||
await DB.Upsert<Ghost>(refId, {
|
||||
collection: "ghost",
|
||||
songId,
|
||||
difficulty
|
||||
}, {
|
||||
$set: {
|
||||
ghostSize,
|
||||
ghost
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
await DB.Update<Profile>(refId, { collection: "profile" }, {
|
||||
$set: {
|
||||
"usergamedata.COMMON.strdata": common.join(","),
|
||||
"usergamedata.OPTION.strdata": option.join(","),
|
||||
"usergamedata.LAST.strdata": last.join(","),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
result: K.ITEM("s32", 0)
|
||||
};
|
||||
};
|
||||
|
||||
const rivalload = (refId: string, data: any) => {
|
||||
const loadFlag = $(data).number("data.loadflag");
|
||||
|
||||
const record = [];
|
||||
|
||||
return {
|
||||
result: K.ITEM("s32", 0),
|
||||
|
||||
data: {
|
||||
recordtype: K.ITEM("s32", loadFlag),
|
||||
record
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const ghostload = (refId: string, data: any) => {
|
||||
const ghostdata = {};
|
||||
|
||||
return {
|
||||
result: K.ITEM("s32", 0),
|
||||
ghostdata
|
||||
};
|
||||
};
|
||||
|
||||
const inheritance = (refId: string) => {
|
||||
return {
|
||||
result: K.ITEM("s32", 0),
|
||||
InheritanceStatus: K.ITEM("s32", 1)
|
||||
};
|
||||
};
|
||||
45
ddr@asphyxia/handlers/usergamedata_recv.ts
Normal file
45
ddr@asphyxia/handlers/usergamedata_recv.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { Profile } from "../models/profile";
|
||||
|
||||
export const usergamedata_recv: EPR = async (info, data, send) => {
|
||||
const refId = $(data).str("data.refid");
|
||||
const profile = await DB.FindOne<Profile>(refId, { collection: "profile" });
|
||||
|
||||
let recordNum = 0;
|
||||
const record = [];
|
||||
|
||||
const d = [];
|
||||
const types = $(data).str("data.recv_csv").split(",").filter((_, i) => (i % 2 === 0));
|
||||
|
||||
for (const type of types) {
|
||||
let strdata = "<NODATA>";
|
||||
let bindata = "<NODATA>";
|
||||
|
||||
if (profile) {
|
||||
strdata = profile.usergamedata[type]["strdata"];
|
||||
bindata = profile.usergamedata[type]["bindata"];
|
||||
|
||||
if (type === "OPTION") {
|
||||
const split = strdata.split(",");
|
||||
|
||||
split[0] = U.GetConfig("save_option") ? "1" : "0";
|
||||
|
||||
strdata = split.join(",");
|
||||
}
|
||||
}
|
||||
|
||||
d.push({
|
||||
...K.ITEM("str", !profile ? strdata : Buffer.from(strdata).toString("base64")),
|
||||
...profile && { bin1: K.ITEM("str", Buffer.from(bindata).toString("base64")) }
|
||||
});
|
||||
recordNum++;
|
||||
}
|
||||
record.push({ d });
|
||||
|
||||
return send.object({
|
||||
result: K.ITEM("s32", 0),
|
||||
player: {
|
||||
record,
|
||||
record_num: K.ITEM("u32", recordNum)
|
||||
}
|
||||
});
|
||||
};
|
||||
31
ddr@asphyxia/handlers/usergamedata_send.ts
Normal file
31
ddr@asphyxia/handlers/usergamedata_send.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { Profile } from "../models/profile";
|
||||
|
||||
export const usergamedata_send: EPR = async (info, data, send) => {
|
||||
const refId = $(data).str("data.refid");
|
||||
|
||||
const profile = await DB.FindOne<Profile>(refId, { collection: "profile" });
|
||||
if (!profile) return send.deny();
|
||||
|
||||
for (const record of $(data).elements("data.record.d")) {
|
||||
const decodeStr = Buffer.from(record.str("", ""), "base64").toString("ascii");
|
||||
const decodeBin = Buffer.from(record.str("bin1", ""), "base64").toString("ascii");
|
||||
|
||||
const strdata = decodeStr.split(",");
|
||||
const type = Buffer.from(strdata[1]).toString("utf-8");
|
||||
|
||||
if (!profile.usergamedata) profile.usergamedata = {};
|
||||
if (!profile.usergamedata[type]) profile.usergamedata[type] = {};
|
||||
profile.usergamedata[type] = {
|
||||
strdata: strdata.slice(2, -1).join(","),
|
||||
bindata: decodeBin
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
await DB.Update<Profile>(refId, { collection: "profile" }, profile);
|
||||
|
||||
return send.object({ result: K.ITEM("s32", 0) });
|
||||
} catch {
|
||||
return send.deny();
|
||||
}
|
||||
};
|
||||
135
ddr@asphyxia/index.ts
Normal file
135
ddr@asphyxia/index.ts
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
import { convcardnumber, eventLog } from "./handlers/common";
|
||||
import { usergamedata } from "./handlers/usergamedata";
|
||||
import { usergamedata_recv } from "./handlers/usergamedata_recv";
|
||||
import { usergamedata_send } from "./handlers/usergamedata_send";
|
||||
import { CommonOffset, OptionOffset, Profile } from "./models/profile";
|
||||
|
||||
export function register() {
|
||||
R.GameCode("MDX");
|
||||
|
||||
R.Config("save_option", {
|
||||
name: "Save option",
|
||||
desc: "Gets the previously set options as they are.",
|
||||
default: true,
|
||||
type: "boolean"
|
||||
});
|
||||
|
||||
R.Route("playerdata.usergamedata_advanced", usergamedata);
|
||||
R.Route("playerdata.usergamedata_recv", usergamedata_recv);
|
||||
R.Route("playerdata.usergamedata_send", usergamedata_send);
|
||||
|
||||
R.Route("system.convcardnumber", convcardnumber);
|
||||
R.Route("eventlog.write", eventLog);
|
||||
|
||||
R.WebUIEvent("updateName", async ({ refid, name }) => {
|
||||
let strdata: Profile | string[] = await DB.FindOne<Profile>(refid, { collection: "profile" });
|
||||
|
||||
if (strdata) {
|
||||
strdata = strdata.usergamedata.COMMON.strdata.split(",");
|
||||
strdata[CommonOffset.NAME] = name;
|
||||
await DB.Update<Profile>(refid, { collection: "profile" }, {
|
||||
$set: {
|
||||
"usergamedata.COMMON.strdata": strdata.join(",")
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
R.WebUIEvent("updateWeight", async ({ refid, weight }) => {
|
||||
let strdata: Profile | string[] = await DB.FindOne<Profile>(refid, { collection: "profile" });
|
||||
|
||||
if (strdata) {
|
||||
strdata = strdata.usergamedata.COMMON.strdata.split(",");
|
||||
strdata[CommonOffset.WEIGHT] = weight;
|
||||
await DB.Update<Profile>(refid, { collection: "profile" }, {
|
||||
$set: {
|
||||
"usergamedata.COMMON.strdata": strdata.join(",")
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
R.WebUIEvent("updateDisplayCalories", async ({ refid, selected }) => {
|
||||
let strdata: Profile | string[] = await DB.FindOne<Profile>(refid, { collection: "profile" });
|
||||
|
||||
if (strdata) {
|
||||
strdata = strdata.usergamedata.COMMON.strdata.split(",");
|
||||
strdata[CommonOffset.WEIGHT_DISPLAY] = selected;
|
||||
await DB.Update<Profile>(refid, { collection: "profile" }, {
|
||||
$set: {
|
||||
"usergamedata.COMMON.strdata": strdata.join(",")
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
R.WebUIEvent("updateArrowSkin", async ({ refid, selected }) => {
|
||||
let strdata: Profile | string[] = await DB.FindOne<Profile>(refid, { collection: "profile" });
|
||||
|
||||
if (strdata) {
|
||||
strdata = strdata.usergamedata.OPTION.strdata.split(",");
|
||||
strdata[OptionOffset.ARROW_SKIN] = selected;
|
||||
await DB.Update<Profile>(refid, { collection: "profile" }, {
|
||||
$set: {
|
||||
"usergamedata.OPTION.strdata": strdata.join(",")
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
R.WebUIEvent("updateGuideline", async ({ refid, selected }) => {
|
||||
let strdata: Profile | string[] = await DB.FindOne<Profile>(refid, { collection: "profile" });
|
||||
|
||||
if (strdata) {
|
||||
strdata = strdata.usergamedata.OPTION.strdata.split(",");
|
||||
strdata[OptionOffset.GUIDELINE] = selected;
|
||||
await DB.Update<Profile>(refid, { collection: "profile" }, {
|
||||
$set: {
|
||||
"usergamedata.OPTION.strdata": strdata.join(",")
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
R.WebUIEvent("updateFilter", async ({ refid, selected }) => {
|
||||
let strdata: Profile | string[] = await DB.FindOne<Profile>(refid, { collection: "profile" });
|
||||
|
||||
if (strdata) {
|
||||
strdata = strdata.usergamedata.OPTION.strdata.split(",");
|
||||
strdata[OptionOffset.FILTER] = selected;
|
||||
await DB.Update<Profile>(refid, { collection: "profile" }, {
|
||||
$set: {
|
||||
"usergamedata.OPTION.strdata": strdata.join(",")
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
R.WebUIEvent("updateJudgmentPriority", async ({ refid, selected }) => {
|
||||
let strdata: Profile | string[] = await DB.FindOne<Profile>(refid, { collection: "profile" });
|
||||
|
||||
if (strdata) {
|
||||
strdata = strdata.usergamedata.OPTION.strdata.split(",");
|
||||
strdata[OptionOffset.COMBO_POSITION] = selected;
|
||||
await DB.Update<Profile>(refid, { collection: "profile" }, {
|
||||
$set: {
|
||||
"usergamedata.OPTION.strdata": strdata.join(",")
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
R.WebUIEvent("updateDisplayTiming", async ({ refid, selected }) => {
|
||||
let strdata: Profile | string[] = await DB.FindOne<Profile>(refid, { collection: "profile" });
|
||||
|
||||
if (strdata) {
|
||||
strdata = strdata.usergamedata.OPTION.strdata.split(",");
|
||||
strdata[OptionOffset.FAST_SLOW] = selected;
|
||||
await DB.Update<Profile>(refid, { collection: "profile" }, {
|
||||
$set: {
|
||||
"usergamedata.OPTION.strdata": strdata.join(",")
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
8
ddr@asphyxia/models/ghost.ts
Normal file
8
ddr@asphyxia/models/ghost.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
export interface Ghost {
|
||||
collection: "ghost";
|
||||
|
||||
songId: number;
|
||||
difficulty: number;
|
||||
ghostSize: number;
|
||||
ghost: string;
|
||||
}
|
||||
77
ddr@asphyxia/models/profile.ts
Normal file
77
ddr@asphyxia/models/profile.ts
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
export enum CommonOffset {
|
||||
AREA = 1,
|
||||
SEQ_HEX = 1,
|
||||
WEIGHT_DISPLAY = 3,
|
||||
CHARACTER,
|
||||
EXTRA_CHARGE,
|
||||
TOTAL_PLAYS = 9,
|
||||
SINGLE_PLAYS = 11,
|
||||
DOUBLE_PLAYS,
|
||||
WEIGHT = 17,
|
||||
NAME = 25,
|
||||
SEQ
|
||||
}
|
||||
|
||||
export enum OptionOffset {
|
||||
SPEED = 1,
|
||||
BOOST,
|
||||
APPEARANCE,
|
||||
TURN,
|
||||
STEP_ZONE,
|
||||
SCROLL,
|
||||
ARROW_COLOR,
|
||||
CUT,
|
||||
FREEZE,
|
||||
JUMP,
|
||||
ARROW_SKIN,
|
||||
FILTER,
|
||||
GUIDELINE,
|
||||
GAUGE,
|
||||
COMBO_POSITION,
|
||||
FAST_SLOW
|
||||
}
|
||||
|
||||
export enum LastOffset {
|
||||
SONG = 3,
|
||||
CALORIES = 10
|
||||
}
|
||||
|
||||
export enum RivalOffset {
|
||||
RIVAL_1_ACTIVE = 1,
|
||||
RIVAL_2_ACTIVE,
|
||||
RIVAL_3_ACTIVE,
|
||||
RIVAL_1_DDRCODE = 9,
|
||||
RIVAL_2_DDRCODE,
|
||||
RIVAL_3_DDRCODE,
|
||||
}
|
||||
|
||||
export interface Profile {
|
||||
collection: "profile";
|
||||
|
||||
ddrCode: number;
|
||||
shopArea: string;
|
||||
|
||||
singleGrade?: number;
|
||||
doubleGrade?: number;
|
||||
|
||||
events?: {};
|
||||
|
||||
usergamedata?: {
|
||||
COMMON?: {
|
||||
strdata?: string;
|
||||
bindata?: string;
|
||||
};
|
||||
OPTION?: {
|
||||
strdata?: string;
|
||||
bindata?: string;
|
||||
};
|
||||
LAST?: {
|
||||
strdata?: string;
|
||||
bindata?: string;
|
||||
};
|
||||
RIVAL?: {
|
||||
strdata?: string;
|
||||
bindata?: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
49
ddr@asphyxia/models/score.ts
Normal file
49
ddr@asphyxia/models/score.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
export enum Difficulty {
|
||||
SINGLE_BEGINNER,
|
||||
SINGLE_BASIC,
|
||||
SINGLE_DIFFICULT,
|
||||
SINGLE_EXPERT,
|
||||
SINGLE_CHALLENGE,
|
||||
DOUBLE_BASIC,
|
||||
DOUBLE_DIFFICULT,
|
||||
DOUBLE_EXPERT,
|
||||
DOUBLE_CHALLENGE
|
||||
}
|
||||
|
||||
export enum Rank {
|
||||
AAA,
|
||||
AA_PLUS,
|
||||
AA,
|
||||
AA_MINUS,
|
||||
A_PLUS,
|
||||
A,
|
||||
A_MINUS,
|
||||
B_PLUS,
|
||||
B,
|
||||
B_MINUS,
|
||||
C_PLUS,
|
||||
C,
|
||||
C_MINUS,
|
||||
D_PLUS,
|
||||
D,
|
||||
E
|
||||
}
|
||||
|
||||
export enum ClearKind {
|
||||
NONE = 6,
|
||||
GOOD_COMBO,
|
||||
GREAT_COMBO,
|
||||
PERPECT_COMBO,
|
||||
MARVELOUS_COMBO
|
||||
}
|
||||
|
||||
export interface Score {
|
||||
collection: "score";
|
||||
|
||||
songId: number;
|
||||
difficulty: Difficulty;
|
||||
rank: Rank;
|
||||
clearKind: ClearKind;
|
||||
score: number;
|
||||
maxCombo: number;
|
||||
}
|
||||
13
ddr@asphyxia/utils.ts
Normal file
13
ddr@asphyxia/utils.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
export function getVersion(info: EamuseInfo) {
|
||||
const dateCode = parseInt(info.model.split(":")[4]);
|
||||
|
||||
if (dateCode >= 2019022600 && dateCode <= 2020020300) return 10;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
export function formatCode(ddrCode: number) {
|
||||
const pad = (ddrCode + "").padStart(8, "0");
|
||||
|
||||
return pad.replace(/^([0-9]{4})([0-9]{4})$/, "$1-$2");
|
||||
}
|
||||
49
ddr@asphyxia/webui/js/profile_settings.js
Normal file
49
ddr@asphyxia/webui/js/profile_settings.js
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
$('#change-name').on('click', () => {
|
||||
const name = $('#dancer_name').val().toUpperCase();
|
||||
|
||||
emit('updateName', { refid, name }).then(() => location.reload());
|
||||
});
|
||||
|
||||
$('#change-weight').on('click', () => {
|
||||
const weight1 = $('#weight_1').val();
|
||||
const weight2 = $('#weight_2').val();
|
||||
const weight = weight1 + '.' + weight2;
|
||||
|
||||
emit('updateWeight', { refid, weight }).then(() => location.reload());
|
||||
});
|
||||
|
||||
$('#change-display-calories').on('click', () => {
|
||||
const selected = $('#display_calories option:selected').val();
|
||||
|
||||
emit('updateDisplayCalories', { refid, selected }).then(() => location.reload());
|
||||
});
|
||||
|
||||
$('#change-arrow-skin').on('click', () => {
|
||||
const selected = $('#arrow_skin option:selected').val();
|
||||
|
||||
emit('updateArrowSkin', { refid, selected }).then(() => location.reload());
|
||||
});
|
||||
|
||||
$('#change-guideline').on('click', () => {
|
||||
const selected = $('#guideline option:selected').val();
|
||||
|
||||
emit('updateGuideline', { refid, selected }).then(() => location.reload());
|
||||
});
|
||||
|
||||
$('#change-filter').on('click', () => {
|
||||
const selected = $('#filter option:selected').val();
|
||||
|
||||
emit('updateFilter', { refid, selected }).then(() => location.reload());
|
||||
});
|
||||
|
||||
$('#change-judgment-priority').on('click', () => {
|
||||
const selected = $('#judgment_priority option:selected').val();
|
||||
|
||||
emit('updateJudgmentPriority', { refid, selected }).then(() => location.reload());
|
||||
});
|
||||
|
||||
$('#change-display-timing').on('click', () => {
|
||||
const selected = $('#display_timing option:selected').val();
|
||||
|
||||
emit('updateDisplayTiming', { refid, selected }).then(() => location.reload());
|
||||
});
|
||||
147
ddr@asphyxia/webui/profile_settings.pug
Normal file
147
ddr@asphyxia/webui/profile_settings.pug
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
//DATA//
|
||||
profile: DB.FindOne(refid, { collection: "profile" })
|
||||
|
||||
-
|
||||
const onOff = [ "Off", "On" ];
|
||||
const characters = [ "All Character Random", "Man Random", "Female Random", "Yuni", "Rage", "Afro", "Jenny", "Emi", "Baby-Lon", "Gus", "Ruby", "Alice", "Julio", "Bonnie", "Zero", "Rinon" ];
|
||||
const arrowSkins = [ "Normal", "X", "Classic", "Cyber", "Medium", "Small", "Dot" ];
|
||||
const guidelines = [ "Off", "Border", "Center" ];
|
||||
const filters = [ "Off", "Dark", "Darker", "Darkest" ];
|
||||
const judgmentPrioritys = [ "Judgment priority", "Arrow priority" ];
|
||||
|
||||
if (profile.usergamedata)
|
||||
-
|
||||
const common = profile.usergamedata.COMMON.strdata.split(",");
|
||||
const option = profile.usergamedata.OPTION.strdata.split(",");
|
||||
|
||||
const name = common[25];
|
||||
const weight = common[17];
|
||||
const displayCalories = parseInt(common[3]);
|
||||
const character = parseInt(common[4]);
|
||||
const arrowSkin = parseInt(option[11]);
|
||||
const guideline = parseInt(option[13]);
|
||||
const filter = parseInt(option[12]);
|
||||
const judgmentPriority = parseInt(option[15]);
|
||||
const displayTiming = parseInt(option[16]);
|
||||
|
||||
div
|
||||
.card
|
||||
.card-header
|
||||
p.card-header-title
|
||||
span.icon
|
||||
i.mdi.mdi-cog
|
||||
| Profile Settings
|
||||
|
||||
.card-content
|
||||
.field.is-horizontal.has-addons
|
||||
.field-label.is-normal
|
||||
label.label Dancer Name
|
||||
.field-body
|
||||
p.control
|
||||
input.input(type="text", id="dancer_name", pattern="[A-Z]{8}", maxlength=8, value=name)
|
||||
p.control
|
||||
a.button.is-primary#change-name Change
|
||||
|
||||
.field.is-horizontal.has-addons
|
||||
.field-label.is-normal
|
||||
label.label Workout Weight
|
||||
.field-body
|
||||
p.control
|
||||
input.input(type="number", id="weight_1", value=weight.split(".")[0])
|
||||
p.control
|
||||
input.input(type="number", id="weight_2", value=weight.split(".")[1])
|
||||
p.control
|
||||
a.button.is-primary#change-weight Change
|
||||
|
||||
.field.is-horizontal.has-addons
|
||||
.field-label.is-normal
|
||||
label.label Workout Display Calories
|
||||
.field-body
|
||||
p.control
|
||||
.select
|
||||
select#display_calories
|
||||
if (displayCalories === 1)
|
||||
option(value=0) Off
|
||||
option(value=1, selected) On
|
||||
else
|
||||
option(value=0, selected) Off
|
||||
option(value=1) On
|
||||
p.control
|
||||
a.button.is-primary#change-display-calories Submit
|
||||
|
||||
.field.is-horizontal.has-addons
|
||||
.field-label.is-normal
|
||||
label.label Arrow Skin
|
||||
.field-body
|
||||
p.control
|
||||
.select
|
||||
select#arrow_skin
|
||||
each v, i in arrowSkins
|
||||
if (arrowSkin === i)
|
||||
option(value=i, selected) #{v}
|
||||
else
|
||||
option(value=i) #{v}
|
||||
p.control
|
||||
a.button.is-primary#change-arrow-skin Submit
|
||||
|
||||
.field.is-horizontal.has-addons
|
||||
.field-label.is-normal
|
||||
label.label Guideline
|
||||
.field-body
|
||||
p.control
|
||||
.select
|
||||
select#guideline
|
||||
each v, i in guidelines
|
||||
if (guideline === i)
|
||||
option(value=i, selected) #{v}
|
||||
else
|
||||
option(value=i) #{v}
|
||||
p.control
|
||||
a.button.is-primary#change-guideline Submit
|
||||
|
||||
.field.is-horizontal.has-addons
|
||||
.field-label.is-normal
|
||||
label.label Filter concentration
|
||||
.field-body
|
||||
p.control
|
||||
.select
|
||||
select#filter
|
||||
each v, i in filters
|
||||
if (filter === i)
|
||||
option(value=i, selected) #{v}
|
||||
else
|
||||
option(value=i) #{v}
|
||||
p.control
|
||||
a.button.is-primary#change-filter Submit
|
||||
|
||||
.field.is-horizontal.has-addons
|
||||
.field-label.is-normal
|
||||
label.label Judgment display priority
|
||||
.field-body
|
||||
p.control
|
||||
.select
|
||||
select#judgment_priority
|
||||
each v, i in judgmentPrioritys
|
||||
if (judgmentPriority === i)
|
||||
option(value=i, selected) #{v}
|
||||
else
|
||||
option(value=i) #{v}
|
||||
p.control
|
||||
a.button.is-primary#change-judgment-priority Submit
|
||||
|
||||
.field.is-horizontal.has-addons
|
||||
.field-label.is-normal
|
||||
label.label Display Timing judgment
|
||||
.field-body
|
||||
p.control
|
||||
.select
|
||||
select#display_timing
|
||||
each v, i in ["Off", "On"]
|
||||
if (displayTiming === i)
|
||||
option(value=i, selected) #{v}
|
||||
else
|
||||
option(value=i) #{v}
|
||||
p.control
|
||||
a.button.is-primary#change-display-timing Submit
|
||||
|
||||
script(src="static/js/profile_settings.js")
|
||||
Loading…
Reference in New Issue
Block a user