diff --git a/sdvx@asphyxia b/sdvx@asphyxia
deleted file mode 160000
index 27f1a25..0000000
--- a/sdvx@asphyxia
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 27f1a259b57ad4bc82b1fbdce7fb67a5be653a22
diff --git a/sdvx@asphyxia/README.md b/sdvx@asphyxia/README.md
new file mode 100644
index 0000000..44ef67e
--- /dev/null
+++ b/sdvx@asphyxia/README.md
@@ -0,0 +1,5 @@
+# SOUND VOLTEX
+
+Supported Versions:
+ * HEAVENLY HAVEN
+ * VIVID WAVE
diff --git a/sdvx@asphyxia/handlers/example.ts b/sdvx@asphyxia/handlers/example.ts
new file mode 100644
index 0000000..31b3813
--- /dev/null
+++ b/sdvx@asphyxia/handlers/example.ts
@@ -0,0 +1,53 @@
+/*
+EamusePluginRoute. Handle your game message like this
+
+You can send a plain XML request to test this route:
+
+
+
+*/
+export const example: EPR = async (info, data, send) => {
+ /* [Check documentation for the entire API] */
+
+ /*
+ Access data from request like this
+ NOTE: all card number will be automatically converted to refid.
+ This is to support older game that doesn't use cardmng,
+ yet still allow them to register with internal profile manager.
+ And they can show up in WebUI as a profile, along with card binding feature.
+ */
+ const refid = $(data).attr().card;
+
+ /* Access config like this */
+ const event = U.GetConfig('event');
+
+ /*
+ Create user data in profile space if not exists
+ WebUI will try to find a "name" field in profile documents and display them.
+ If you are using a collection of data for each profile,
+ make sure to avoid using name field in supplementary documents.
+ If you have multiple documents per refid, it is recommended to provide a field to
+ simulate collections in NoSQL database (e.g. MongoDB)
+ */
+ await DB.Upsert(
+ refid,
+ {
+ collection: 'profile',
+ name: 'PLAYER',
+ },
+ { $inc: { login_count: 1 } }
+ );
+
+ /*
+ Send your response like this
+ There are more methods for sending request.
+ */
+ send.pugFile('templates/example.pug', { refid, event });
+
+ /* Or you can send ejs template (plain xml works as well) */
+ // send.xmlFile('templates/example.xml', { refid, event });
+};
+
+export const changeName = async (data: any) => {
+ await DB.Update(data.refid, { collection: 'profile' }, { $set: { name: data.name } });
+};
diff --git a/sdvx@asphyxia/index.ts b/sdvx@asphyxia/index.ts
new file mode 100644
index 0000000..64f9c02
--- /dev/null
+++ b/sdvx@asphyxia/index.ts
@@ -0,0 +1,7 @@
+import { example, changeName } from './handlers/example';
+
+export function register() {
+ R.GameCode('KFC');
+
+ R.Route('example.method', example);
+}
diff --git a/sdvx@asphyxia/models/course_record.ts b/sdvx@asphyxia/models/course_record.ts
new file mode 100644
index 0000000..e69de29
diff --git a/sdvx@asphyxia/models/mix.ts b/sdvx@asphyxia/models/mix.ts
new file mode 100644
index 0000000..e69de29
diff --git a/sdvx@asphyxia/models/profile.ts b/sdvx@asphyxia/models/profile.ts
new file mode 100644
index 0000000..48aabe3
--- /dev/null
+++ b/sdvx@asphyxia/models/profile.ts
@@ -0,0 +1,34 @@
+export interface Profile {
+ modelVer: string;
+
+ name: string;
+ appeal: number;
+ akaname: number;
+
+ currency: {
+ packets: number;
+ blocks: number;
+ };
+
+ state: {
+ lastMusicID: number;
+ lastMusicType: number;
+ sortType: number;
+ headphone: number;
+ blasterEnergy: number;
+ blasterCount: number;
+ }
+
+ settings: {
+ hiSpeed: number;
+ laneSpeed: number;
+ gaugeOption: number;
+ arsOption: number;
+ notesOption: number;
+ earlyLateDisp: number;
+ drawAdjust: number;
+ effCLeft: number;
+ effCRight: number;
+ narrowDown: number;
+ }
+}
\ No newline at end of file
diff --git a/sdvx@asphyxia/models/song_record.ts b/sdvx@asphyxia/models/song_record.ts
new file mode 100644
index 0000000..e69de29
diff --git a/sdvx@asphyxia/models/version_data.ts b/sdvx@asphyxia/models/version_data.ts
new file mode 100644
index 0000000..4dbc4f0
--- /dev/null
+++ b/sdvx@asphyxia/models/version_data.ts
@@ -0,0 +1,13 @@
+// Version specific data (e.g. skills level)
+export interface VersionData {
+ version: number;
+ skillLevel: number;
+ skillBaseID: number;
+ skillNameID: number;
+ items: {
+ [key: string]: number;
+ };
+ params: {
+ [key: string]: number[];
+ };
+}
\ No newline at end of file
diff --git a/sdvx@asphyxia/templates/example.pug b/sdvx@asphyxia/templates/example.pug
new file mode 100644
index 0000000..38dfe19
--- /dev/null
+++ b/sdvx@asphyxia/templates/example.pug
@@ -0,0 +1,5 @@
+//-
+ Learn pug here: https://pugjs.org/api/getting-started.html
+example(status="0")
+ refid(__type="str") #{refid}
+ event(__type="str") #{event}
\ No newline at end of file
diff --git a/sdvx@asphyxia/templates/example.xml b/sdvx@asphyxia/templates/example.xml
new file mode 100644
index 0000000..264249c
--- /dev/null
+++ b/sdvx@asphyxia/templates/example.xml
@@ -0,0 +1,7 @@
+
+
+ <%= refid %>
+ <%= event %>
+
\ No newline at end of file
diff --git a/sdvx@asphyxia/webui/css/profile_name.css b/sdvx@asphyxia/webui/css/profile_name.css
new file mode 100644
index 0000000..bb2ac1c
--- /dev/null
+++ b/sdvx@asphyxia/webui/css/profile_name.css
@@ -0,0 +1,3 @@
+#change-name-button {
+ background-color: rgb(245, 147, 0);
+}
diff --git a/sdvx@asphyxia/webui/custom_page.pug b/sdvx@asphyxia/webui/custom_page.pug
new file mode 100644
index 0000000..baa5d1f
--- /dev/null
+++ b/sdvx@asphyxia/webui/custom_page.pug
@@ -0,0 +1,29 @@
+//-
+ Custom web component for plugin page
+ The following frontend components are already avaliable:
+ * Bulma [https://bulma.io/]
+ * MaterialDesignIcons [https://materialdesignicons.com/]
+ * jQuery [https://jquery.com/]
+ * axios [https://github.com/axios/axios]
+ * GeoPattern [https://github.com/btmills/geopattern]
+ * jdenticon [https://jdenticon.com/]
+ You can include your own js, css or images as well.
+
+ To request data from database, use //DATA// to indicate a comment block for capture and follow:
+ fieldName: expression
+
+ Then fieldName will be avaliable for the template engine when rendering.
+
+//DATA//
+ data: DB.FindOne({ clicked: { $exists: true } })
+
+.content
+ h3 Custom Page
+ p Clicked: #{data.clicked}
+ p
+ button.button.is-primary#plugin-click
+ | Send "click" event and refresh
+
+//- You can include custom javascripts and send data back to plugin using emit()
+ see profile_name.pug for sending data using form
+script(src="static/js/custom_page.js")
\ No newline at end of file
diff --git a/sdvx@asphyxia/webui/js/custom_page.js b/sdvx@asphyxia/webui/js/custom_page.js
new file mode 100644
index 0000000..86cc11a
--- /dev/null
+++ b/sdvx@asphyxia/webui/js/custom_page.js
@@ -0,0 +1,5 @@
+$('#plugin-click').on('click', () => {
+ emit('click', {}).then(() => {
+ location.reload();
+ });
+});
diff --git a/sdvx@asphyxia/webui/profile_name.pug b/sdvx@asphyxia/webui/profile_name.pug
new file mode 100644
index 0000000..7fd16d4
--- /dev/null
+++ b/sdvx@asphyxia/webui/profile_name.pug
@@ -0,0 +1,42 @@
+//-
+ Custom web component for individual user profile
+ The following frontend components are already avaliable:
+ * Bulma [https://bulma.io/]
+ * MaterialDesignIcons [https://materialdesignicons.com/]
+ * jQuery [https://jquery.com/]
+ * axios [https://github.com/axios/axios]
+ * GeoPattern [https://github.com/btmills/geopattern]
+ * jdenticon [https://jdenticon.com/]
+ You can include your own js/css as well
+
+ To request data from database, use //DATA// to indicate a comment block for capture and follow:
+ fieldName: expression
+
+ Then fieldName will be avaliable for the template engine when rendering.
+
+ WebUI file with prefix "profile_" is different from other pug file:
+ * This page have a "refid" local variable, you can request data with it or use it during render.
+ * User can access these page by editing a profile.
+
+//DATA//
+ profile: DB.FindOne(refid, { login_count: { $exists: true } })
+
+//-
+ You can include your own stylesheet
+link(rel="stylesheet" href="static/css/profile_name.css")
+
+div
+ h3 Hi #{profile.name}
+
+ section.section
+ //-
+ You can send data back to plugin using post method in form
+ see custom_page.pug for sending data using emit() function
+ form(method="post" action="/emit/change")
+ input(type="hidden" name="refid" value=refid)
+ .field
+ label.label Change Name
+ .field
+ input.input(type="text" name="name", value=profile.name)
+ .field
+ button.button.is-primary#change-name-button(type="submit") Submit