Merge pull request #6 from DitFranXX/nostalgia

Nostalgia Forte Support
This commit is contained in:
Freddie Wang 2020-12-22 17:14:40 +08:00 committed by GitHub
commit 0312d7dcf2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 471 additions and 2926 deletions

View File

@ -1,13 +1,29 @@
# Nostalgia
Plugin Version: **v1.0.0**
Plugin Version: **v1.1.0**
Supported Versions
-------------------
- Forte (Experiment)
- Op.2
About Forte Support
-------------------
Forte support is live. But since it has much difference compared to Op.2, Forte is not-primary-supported version.
It may works unexpectedly. Forte was tested very lightly. So this feature is tagged as **Experiment**.
Also, Technically, This *may* support First version of Nostalgia too.
But It's highly not recommend to run First version with it.
Changelog
=========
1.1.0 (Current)
---------------
- Fix saving issue with brooch, island, and kentei.
- Moved to Base64 encoded data base.
- Forte support.
1.0.0
-----
Initial Release.

3
nostalgia@asphyxia/data/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
*.json
*.json
*.xml

View File

@ -0,0 +1,71 @@
import { CommonMusicDataField, readB64JSON, readXML } from "./helper";
export async function processData() {
if (IO.Exists("data/forte_mdb.json.b64")) {
return await readB64JSON("data/forte_mdb.json.b64");
}
const data = await readJSONOrXML("data/forte_mdb.json", "data/forte_mdb.xml")
// await IO.WriteFile("data/forte_mdb.json.b64", Buffer.from(JSON.stringify(data)).toString("base64"))
return data
}
export async function processMdbData(path: string): Promise<CommonMusicData> {
const data = await readXML(path);
const attr = $(data).attr("music_list");
const mdb = $(data).elements("music_list.music_spec");
const music: CommonMusicDataField[] = [];
for (const m of mdb) {
music.push(K.ATTR({ index: m.attr().index }, {
basename: K.ITEM("str", m.str("basename")),
title: K.ITEM("str", m.str("title", "title")),
title_kana: K.ITEM("str", m.str("title_kana", "title_kana")),
artist: K.ITEM("str", m.str("artist", "artist")),
artist_kana: K.ITEM("str", m.str("artist_kana", "artist_kana")),
priority: K.ITEM("s8", m.number("priority")),
category_flag: K.ARRAY("s32", m.numbers("category_flag")),
primary_category: K.ITEM("s8", m.number("primary_category")),
level_normal: K.ITEM("s8", m.number("level_normal")),
level_hard: K.ITEM("s8", m.number("level_hard")),
level_extreme: K.ITEM("s8", m.number("level_extreme")),
demo_popular: K.ITEM("bool", m.bool("demo_popular")),
demo_bemani: K.ITEM("bool", m.bool("demo_bemani")),
destination_j: K.ITEM("bool", true),
destination_a: K.ITEM("bool", true),
destination_y: K.ITEM("bool", true),
destination_k: K.ITEM("bool", true),
offline: K.ITEM("bool", m.bool("offline")),
unlock_type: K.ITEM("s8", m.number("unlock_type") == 3 ? 1 : m.number("unlock_type")),
volume_bgm: K.ITEM("s8", m.number("volume_bgm")),
volume_key: K.ITEM("s8", m.number("volume_key")),
start_date: K.ITEM("str", m.str("start_date")),
end_date: K.ITEM("str", "9999-12-31 23:59"),
description: K.ITEM("str", m.str("description", "description"))
}));
}
return K.ATTR({
release_code: attr.release_code,
revision: attr.revision,
}, {
music_spec: music,
});
}
export async function readJSONOrXML(jsonPath: string, xmlPath: string): Promise<CommonMusicData> {
if (!IO.Exists(jsonPath)) {
const data = await processMdbData(xmlPath)
await IO.WriteFile(jsonPath, JSON.stringify(data))
await IO.WriteFile(jsonPath.replace(".json", ".json.b64"), Buffer.from((JSON.stringify(data))).toString('base64'));
return data
} else {
const json = JSON.parse(await IO.ReadFile(jsonPath, 'utf-8'))
return json
}
}
interface CommonMusicData {
"@attr": {
revision: string,
release_code: string
}
music_spec: CommonMusicDataField[]
}

File diff suppressed because one or more lines are too long

View File

@ -1,699 +0,0 @@
<?xml version="1.0" encoding="shift_jis"?>
<course_data_list release_code="2019022700">
<course_data index="1">
<name __type="str">ベーシック10級検定</name>
<priority __type="s32">40</priority>
<req_nos __type="s32">1000</req_nos>
<mode_type __type="s32">1</mode_type>
<req_grade __type="s32">80000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">140</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">850000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">225</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">1725000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">170</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">2625000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2019-01-01 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="2">
<name __type="str">ベーシック9級検定</name>
<priority __type="s32">39</priority>
<req_nos __type="s32">1500</req_nos>
<mode_type __type="s32">1</mode_type>
<req_grade __type="s32">120000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">199</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">875000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">209</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">1775000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">212</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">2700000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2019-01-01 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="3">
<name __type="str">ベーシック8級検定</name>
<priority __type="s32">38</priority>
<req_nos __type="s32">2000</req_nos>
<mode_type __type="s32">1</mode_type>
<req_grade __type="s32">200000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">220</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">900000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">232</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">1825000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">82</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">2775000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2019-01-01 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="4">
<name __type="str">ベーシック7級検定</name>
<priority __type="s32">37</priority>
<req_nos __type="s32">2500</req_nos>
<mode_type __type="s32">1</mode_type>
<req_grade __type="s32">300000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">186</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">925000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">141</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">1875000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">32</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">2850000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2019-01-01 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="5">
<name __type="str">ベーシック6級検定</name>
<priority __type="s32">36</priority>
<req_nos __type="s32">3000</req_nos>
<mode_type __type="s32">1</mode_type>
<req_grade __type="s32">400000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">36</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">925000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">87</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">1875000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">242</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">2850000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2019-01-01 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="6">
<name __type="str">ベーシック5級検定</name>
<priority __type="s32">35</priority>
<req_nos __type="s32">3500</req_nos>
<mode_type __type="s32">1</mode_type>
<req_grade __type="s32">450000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">122</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">925000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">40</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">1875000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">85</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">2850000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2019-01-01 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="7">
<name __type="str">ベーシック4級検定</name>
<priority __type="s32">34</priority>
<req_nos __type="s32">4000</req_nos>
<mode_type __type="s32">1</mode_type>
<req_grade __type="s32">500000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">7</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">925000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">28</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">1875000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">49</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">2850000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2020-01-21 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="8">
<name __type="str">ベーシック3級検定</name>
<priority __type="s32">33</priority>
<req_nos __type="s32">4500</req_nos>
<mode_type __type="s32">1</mode_type>
<req_grade __type="s32">525000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">8</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">925000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">29</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">1875000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">50</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">2850000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2020-01-21 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="9">
<name __type="str">ベーシック2級検定</name>
<priority __type="s32">32</priority>
<req_nos __type="s32">5000</req_nos>
<mode_type __type="s32">1</mode_type>
<req_grade __type="s32">540000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">9</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">925000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">30</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">1875000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">51</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">2850000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2020-01-21 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="10">
<name __type="str">ベーシック1級検定</name>
<priority __type="s32">31</priority>
<req_nos __type="s32">6000</req_nos>
<mode_type __type="s32">1</mode_type>
<req_grade __type="s32">550000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">10</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">925000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">31</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">1875000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">52</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">2850000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2020-01-21 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="11">
<name __type="str">リサイタル10級検定</name>
<priority __type="s32">30</priority>
<req_nos __type="s32">1000</req_nos>
<mode_type __type="s32">2</mode_type>
<req_grade __type="s32">80000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">7</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">34000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">238</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">72000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">227</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">114000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2019-01-01 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="12">
<name __type="str">リサイタル9級検定</name>
<priority __type="s32">29</priority>
<req_nos __type="s32">1500</req_nos>
<mode_type __type="s32">2</mode_type>
<req_grade __type="s32">120000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">19</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">36000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">220</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">76000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">214</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">120000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2019-01-01 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="13">
<name __type="str">リサイタル8級検定</name>
<priority __type="s32">28</priority>
<req_nos __type="s32">2000</req_nos>
<mode_type __type="s32">2</mode_type>
<req_grade __type="s32">200000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">8</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">38000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">63</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">80000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">86</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">126000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2019-01-01 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="14">
<name __type="str">リサイタル7級検定</name>
<priority __type="s32">27</priority>
<req_nos __type="s32">2500</req_nos>
<mode_type __type="s32">2</mode_type>
<req_grade __type="s32">300000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">72</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">40000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">71</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">84000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">70</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">132000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2019-01-01 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="15">
<name __type="str">リサイタル6級検定</name>
<priority __type="s32">26</priority>
<req_nos __type="s32">3000</req_nos>
<mode_type __type="s32">2</mode_type>
<req_grade __type="s32">400000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">105</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">40000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">101</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">84000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">186</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">132000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2019-01-01 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="16">
<name __type="str">リサイタル5級検定</name>
<priority __type="s32">25</priority>
<req_nos __type="s32">3500</req_nos>
<mode_type __type="s32">2</mode_type>
<req_grade __type="s32">450000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">26</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">40000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">160</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">84000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">133</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">132000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2019-01-01 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="17">
<name __type="str">リサイタル4級検定</name>
<priority __type="s32">24</priority>
<req_nos __type="s32">4000</req_nos>
<mode_type __type="s32">2</mode_type>
<req_grade __type="s32">500000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">17</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">40000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">38</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">84000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">59</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">132000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2020-01-21 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="18">
<name __type="str">リサイタル3級検定</name>
<priority __type="s32">23</priority>
<req_nos __type="s32">4500</req_nos>
<mode_type __type="s32">2</mode_type>
<req_grade __type="s32">525000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">18</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">40000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">39</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">84000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">60</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">132000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2020-01-21 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="19">
<name __type="str">リサイタル2級検定</name>
<priority __type="s32">22</priority>
<req_nos __type="s32">5000</req_nos>
<mode_type __type="s32">2</mode_type>
<req_grade __type="s32">540000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">19</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">40000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">40</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">84000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">61</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">132000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2020-01-21 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="20">
<name __type="str">リサイタル1級検定</name>
<priority __type="s32">21</priority>
<req_nos __type="s32">6000</req_nos>
<mode_type __type="s32">2</mode_type>
<req_grade __type="s32">550000</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">20</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">40000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">41</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">84000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">62</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">132000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">0</unlock_music>
<unlock_item_list />
<start_date __type="str">2020-01-21 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="21">
<name __type="str">KACスペシャル検定(Normal)</name>
<priority __type="s32">60</priority>
<req_nos __type="s32">2000</req_nos>
<mode_type __type="s32">1</mode_type>
<req_grade __type="s32">0</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">261</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">900000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">262</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">1800000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">263</index>
<difficulty __type="s32">0</difficulty>
<clear_point __type="s32">2750000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">263</unlock_music>
<unlock_item_list>
<unlock_item unlock_item_no="0">
<type __type="s32">1</type>
<index __type="s32">263</index>
<unlock_condition __type="s32">2</unlock_condition>
</unlock_item>
</unlock_item_list>
<start_date __type="str">2019-02-28 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="22">
<name __type="str">KACスペシャル検定(Hard)</name>
<priority __type="s32">59</priority>
<req_nos __type="s32">2000</req_nos>
<mode_type __type="s32">1</mode_type>
<req_grade __type="s32">0</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">261</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">925000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">262</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">1875000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">263</index>
<difficulty __type="s32">1</difficulty>
<clear_point __type="s32">2850000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">263</unlock_music>
<unlock_item_list>
<unlock_item unlock_item_no="0">
<type __type="s32">1</type>
<index __type="s32">263</index>
<unlock_condition __type="s32">2</unlock_condition>
</unlock_item>
</unlock_item_list>
<start_date __type="str">2019-02-28 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="23">
<name __type="str">KACスペシャル検定(Expert)</name>
<priority __type="s32">58</priority>
<req_nos __type="s32">2000</req_nos>
<mode_type __type="s32">1</mode_type>
<req_grade __type="s32">0</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">261</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">925000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">262</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">1875000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">263</index>
<difficulty __type="s32">2</difficulty>
<clear_point __type="s32">2850000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">263</unlock_music>
<unlock_item_list>
<unlock_item unlock_item_no="0">
<type __type="s32">1</type>
<index __type="s32">263</index>
<unlock_condition __type="s32">2</unlock_condition>
</unlock_item>
</unlock_item_list>
<start_date __type="str">2019-02-28 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
<course_data index="24">
<name __type="str">KACスペシャル検定(Real)</name>
<priority __type="s32">57</priority>
<req_nos __type="s32">2000</req_nos>
<mode_type __type="s32">1</mode_type>
<req_grade __type="s32">0</req_grade>
<seq_list>
<tune tune_no="0">
<index __type="s32">261</index>
<difficulty __type="s32">3</difficulty>
<clear_point __type="s32">925000</clear_point>
</tune>
<tune tune_no="1">
<index __type="s32">262</index>
<difficulty __type="s32">3</difficulty>
<clear_point __type="s32">1875000</clear_point>
</tune>
<tune tune_no="2">
<index __type="s32">263</index>
<difficulty __type="s32">3</difficulty>
<clear_point __type="s32">2850000</clear_point>
</tune>
</seq_list>
<unlock_music __type="s32">263</unlock_music>
<unlock_item_list>
<unlock_item unlock_item_no="0">
<type __type="s32">1</type>
<index __type="s32">263</index>
<unlock_condition __type="s32">2</unlock_condition>
</unlock_item>
</unlock_item_list>
<start_date __type="str">2019-02-28 10:00</start_date>
<end_date __type="str">9999-01-01 00:00</end_date>
</course_data>
</course_data_list>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,43 @@
export interface CommonMusicDataField {
basename: KITEM<"str">;
title: KITEM<"str">;
title_kana: KITEM<"str">;
artist: KITEM<"str">;
artist_kana: KITEM<"str">
priority: KITEM<"s8">;
category_flag: KARRAY<"s32">;
primary_category: KITEM<"s8">;
level_normal: KITEM<"s8">;
level_hard: KITEM<"s8">;
level_extreme: KITEM<"s8">;
demo_popular: KITEM<"bool">;
demo_bemani: KITEM<"bool">
destination_j: KITEM<"bool">;
destination_a: KITEM<"bool">;
destination_y: KITEM<"bool">;
destination_k: KITEM<"bool">;
unlock_type: KITEM<"s8">;
offline: KITEM<"bool">;
volume_bgm: KITEM<"s8">;
volume_key: KITEM<"s8">;
start_date: KITEM<"str">;
end_date: KITEM<"str">;
description: KITEM<"str">;
}
export async function readXML(path: string) {
const xml = await IO.ReadFile(path, 'utf-8');
const json = U.parseXML(xml, false)
return json
}
export async function readJSON(path: string) {
const str = await IO.ReadFile(path, 'utf-8');
const json = JSON.parse(str)
return json
}
export async function readB64JSON(b64path: string) {
const buff = await IO.ReadFile(b64path, 'utf-8');
return JSON.parse(Buffer.from(buff, 'base64').toString('utf-8'));
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,6 @@
import * as path from "path";
import { processData } from "../data/ForteMusic";
import { readB64JSON } from "../data/helper";
export const permitted_list = {
flag: [
@ -9,10 +11,22 @@ export const permitted_list = {
],
};
export const forte_permitted_list = {
flag: [
K.ARRAY('s32', Array(32).fill(-1), { sheet_type: '0' }),
K.ARRAY('s32', Array(32).fill(-1), { sheet_type: '1' }),
K.ARRAY('s32', Array(32).fill(-1), { sheet_type: '2' }),
],
}
async function ReadData(filename: string) {
const xml = await IO.ReadFile(`data/${filename}.xml`, { encoding: 'utf-8'});
if (!IO.Exists(`data/${filename}.xml`)) {
const xml = await IO.ReadFile(`data/${filename}.xml`, 'utf-8');
const json = U.parseXML(xml, false)
// await IO.WriteFile(`data/${filename}.json.b64`, Buffer.from(JSON.stringify(json)).toString('base64'));
return json
}
return readB64JSON(`data/${filename}.json.b64`)
}
async function processIslandData() {
@ -56,7 +70,7 @@ async function processCourseData() {
return { course_data: courseData };
}
export const get_common_info = async (req, data, send) => {
export const get_common_info = async (info, data, send) => {
send.object({
permitted_list,
olupdate: {
@ -65,10 +79,12 @@ export const get_common_info = async (req, data, send) => {
});
};
export const get_music_info: EPR = async (req, data, send) => {
export const get_music_info: EPR = async (info, data, send) => {
const isForte = !info.module.includes("op")
const music_spec: any = [];
for (let i = 1; i < 400; ++i) {
music_spec.push(K.ATTR({ index: `${i}`}, {
music_spec.push(K.ATTR({ index: `${i}` }, {
jk_jpn: K.ITEM('bool', 1),
jk_asia: K.ITEM('bool', 1),
jk_kor: K.ITEM('bool', 1),
@ -83,18 +99,25 @@ export const get_music_info: EPR = async (req, data, send) => {
}));
}
send.object({
permitted_list,
const versionObject = isForte
? {
permitted_list: forte_permitted_list,
music_list: await processData()
}
: {
permitted_list,
island_data_list: await processIslandData(),
course_data_list: await processCourseData(),
island_data_list: await processIslandData(),
course_data_list: await processCourseData(),
overwrite_music_list: K.ATTR({
overwrite_music_list: K.ATTR({
revision: '16706',
release_code: '2019100200',
}, {
music_spec: music_spec,
}),
music_spec: music_spec,
}),
};
send.object({
...versionObject,
gamedata_flag_list: {
event: {

View File

@ -3,7 +3,7 @@
// import { Logger } from '../../util/Logger';
import { Profile } from '../models/profile';
import { Scores } from '../models/scores';
import { permitted_list } from './common';
import { permitted_list, forte_permitted_list } from './common';
// import { getValue, getArray, getAttr, getStr, getBigInt } from '../../util/Helper';
@ -18,9 +18,10 @@ import { permitted_list } from './common';
// },
// };
const getEventInfo = () => {
const getEventInfo = (isForte: boolean) => {
const event: any[] = [];
for (let i = 1; i <= 17; ++i) {
const event_num = isForte ? 10 : 17
for (let i = 1; i <= event_num; ++i) {
event.push({
type: K.ITEM('s32', 4),
index: K.ITEM('s32', i),
@ -34,8 +35,9 @@ const getEventInfo = () => {
return event;
};
const getPlayerData = async (refid: string, name?: string) => {
const getPlayerData = async (refid: string, info: EamuseInfo, name?: string) => {
const p = await readProfile(refid);
const isForte = !info.module.includes("op")
if (name && name.length > 0) {
p.name = name;
@ -45,7 +47,7 @@ const getPlayerData = async (refid: string, name?: string) => {
const param: any[] = [];
for (const t in p.params) {
const para = p.params[t];
param.push(K.ATTR({type: t}, {
param.push(K.ATTR({ type: t }, {
count: K.ITEM('s32', para.length),
params_array: K.ARRAY('s32', para),
}));
@ -53,6 +55,7 @@ const getPlayerData = async (refid: string, name?: string) => {
const brooch: any[] = [];
for (const b in p.brooches) {
if (isForte && parseInt(b, 10) > 147) continue; // Forte Brooch is ~147.
const bData = p.brooches[b];
brooch.push(K.ATTR({ index: b }, {
watch_count: K.ITEM('s32', bData.watch),
@ -72,6 +75,20 @@ const getPlayerData = async (refid: string, name?: string) => {
}));
}
// Forte
const stairs: any[] = [];
for (const s in (p.cat_stairs || defaultProfile.cat_stairs)) {
const stair = (p.cat_stairs || defaultProfile.cat_stairs)[s];
stairs.push(K.ATTR({ index: s }, {
total_steps: K.ITEM("s32", stair.total),
chapter_index: K.ITEM("s32", stair.index),
chapter_steps: K.ITEM("s32", stair.steps),
chapter_goal: K.ITEM("s32", stair.goal)
}));
}
// >= Op2
const kentei_record: any[] = [];
for (const k in p.kentei) {
const kentei = p.kentei[k];
@ -86,6 +103,7 @@ const getPlayerData = async (refid: string, name?: string) => {
});
}
// >= Op2
const island_progress: any[] = [];
for (const i in p.islands) {
const island = p.islands[i];
@ -119,40 +137,50 @@ const getPlayerData = async (refid: string, name?: string) => {
}));
}
const correct_permitted_list = !isForte ? permitted_list : forte_permitted_list
const music_list = [
K.ARRAY('s32', p.musicList.type_0, { sheet_type: '0' }),
K.ARRAY('s32', p.musicList.type_1, { sheet_type: '1' }),
K.ARRAY('s32', p.musicList.type_2, { sheet_type: '2' }),
K.ARRAY('s32', p.musicList.type_3, { sheet_type: '3' }),
];
const music_list2 = [
K.ARRAY('s32', p.musicList2.type_0, { sheet_type: '0' }),
K.ARRAY('s32', p.musicList2.type_1, { sheet_type: '1' }),
K.ARRAY('s32', p.musicList2.type_2, { sheet_type: '2' }),
K.ARRAY('s32', p.musicList2.type_3, { sheet_type: '3' }),
];
if(isForte) {
music_list.pop();
music_list2.pop();
}
return {
name: K.ITEM('str', p.name),
play_count: K.ITEM('s32', p.playCount),
today_play_count: K.ITEM('s32', p.todayPlayCount),
permitted_list,
event_info_list: { event: getEventInfo() },
permitted_list: correct_permitted_list,
event_info_list: { event: getEventInfo(isForte) }, // Op2
event_control_list: { event: getEventInfo(isForte) }, // Forte
music_list: {
flag: [
K.ARRAY('s32', p.musicList.type_0, { sheet_type: '0' }),
K.ARRAY('s32', p.musicList.type_1, { sheet_type: '1' }),
K.ARRAY('s32', p.musicList.type_2, { sheet_type: '2' }),
K.ARRAY('s32', p.musicList.type_3, { sheet_type: '3' }),
],
flag: music_list,
},
free_for_play_music_list: {
flag: [
K.ARRAY('s32', p.musicList2.type_0, { sheet_type: '0' }),
K.ARRAY('s32', p.musicList2.type_1, { sheet_type: '1' }),
K.ARRAY('s32', p.musicList2.type_2, { sheet_type: '2' }),
K.ARRAY('s32', p.musicList2.type_3, { sheet_type: '3' }),
],
flag: music_list2,
},
last: {
music_index: K.ITEM('s32', p.music),
sheet_type: K.ITEM('s8', p.sheet),
brooch_index: K.ITEM('s32', p.brooch),
music_index: K.ITEM('s32', forteNumericHandler(isForte, p.music, 195, 0)),
sheet_type: K.ITEM('s8', forteNumericHandler(isForte, p.sheet, 3, 0)),
brooch_index: K.ITEM('s32', forteNumericHandler(isForte, p.brooch, 147, 0)),
hi_speed_level: K.ITEM('s32', p.hispeed),
beat_guide: K.ITEM('s8', p.beatGuide),
headphone_volume: K.ITEM('s8', p.headphone),
judge_bar_pos: K.ITEM('s32', p.judgeBar),
music_group: K.ITEM('s32', p.group),
hands_mode: K.ITEM('s8', p.mode),
hands_mode: isForte ? K.ITEM('s32', p.mode) : K.ITEM('s8', p.mode),
near_setting: K.ITEM('s8', p.near),
judge_delay_offset: K.ITEM('s8', p.offset),
judge_delay_offset: isForte ? K.ITEM('s32', p.offset) : K.ITEM('s8', p.offset),
bingo_index: K.ITEM('s32', p.bingo),
total_skill_value: K.ITEM('u64', BigInt(p.skill)),
key_beam_level: K.ITEM('s8', p.keyBeam),
@ -169,14 +197,16 @@ const getPlayerData = async (refid: string, name?: string) => {
judge_effect_adjust: K.ITEM('s8', p.judgeFX),
simple_bg: K.ITEM('s8', p.simple),
},
brooch_list: {
brooch,
// TODO: Full unlock instead of saving?
cat_progress: {
stair: stairs
},
brooch_list: { brooch },
extra_param: { param },
present_list: {},
various_music_list: {
data: [
K.ATTR({ list_type: '0' }, {
K.ATTR({ list_type: '0' }, {
cond_flag: K.ITEM('s32', 0),
flag: K.ITEM('s32', 0, { sheet_type: '0' }),
}),
@ -202,14 +232,14 @@ export const regist_playdata: EPR = async (info, data, send) => {
const name = $(data).str('name');
console.debug(`nos op2 regist: ${name}`);
send.object(await getPlayerData(refid, name));
send.object(await getPlayerData(refid, info, name));
};
export const get_playdata: EPR = async (info, data, send) => {
const refid = $(data).str('refid');
if (!refid) return send.deny();
send.object(await getPlayerData(refid));
send.object(await getPlayerData(refid, info));
};
// export const set_stage_result: EPR = async (info, data, send) => {
@ -220,6 +250,7 @@ export const set_total_result: EPR = async (info, data, send) => {
const refid = $(data).str('refid');
if (!refid) return send.deny();
const isForte = !info.module.includes("op")
const p = await readProfile(refid);
p.playCount = $(data).number('play_count', p.playCount);
@ -321,7 +352,7 @@ export const set_total_result: EPR = async (info, data, send) => {
// BROOCHES
let broochs = $(data).elements('brooch_list.brooch');
for (const brooch of broochs) {
const index = parseInt(_.get(brooch, '@attr.index', '-1'));
const index = parseInt(brooch.attr().index || '-1', 10);
if (index < 0) continue;
p.brooches[index] = {
@ -335,7 +366,7 @@ export const set_total_result: EPR = async (info, data, send) => {
// ISLAND
let islands = $(data).elements('island_progress_list.island_progress');
for (const island of islands) {
const index = parseInt(_.get(island, '@attr.index', '-1'));
const index = parseInt(island.attr().index || '-1', 10);
if (index < 0) continue;
const containers: Profile['islands']['0']['containers'] = {};
@ -366,6 +397,23 @@ export const set_total_result: EPR = async (info, data, send) => {
};
}
// CAT STAIR
let stairs = $(data).elements('cat_progress.stair');
if (!p.cat_stairs) {
p.cat_stairs = defaultProfile.cat_stairs
}
for (const stair of stairs) {
const index = parseInt(stair.attr().index || '-1', 10);
if (index < 0) continue;
p.cat_stairs[index] = {
total: stair.number('total_steps', 0),
index: stair.number('chapter_index', 1),
steps: stair.number('chapter_steps', 0),
goal: stair.number('chapter_goal', 0),
};
}
await writeProfile(refid, p);
const scoreData = await readScores(refid);
@ -376,12 +424,12 @@ export const set_total_result: EPR = async (info, data, send) => {
const type = stage.attr().sheet_type
const key = `${mid}:${type}`;
const c = stage.element('common');
const c = isForte ? stage : stage.element('common');
const o = _.get(scoreData, `scores.${key}`, {});
const isHigh = c.number('score', 0) >= _.get(o, 'score', 0);
scoreData.scores[key] = {
score: Math.max(c.number('score', 0), _.get(o, 'score', 0)),
grade: Math.max(c.number('grade_basic', 0), _.get(o, 'grade', 0)),
grade: Math.max(Math.max(c.number('grade_basic', 0), c.number('evaluation', 0)), _.get(o, 'grade', 0)),
recital: Math.max(c.number('grade_recital', 0), _.get(o, 'recital', 0)),
mode: isHigh ? c.number('hands_mode', 0) : _.get(o, 'mode', 0),
count: Math.max(c.number('play_count', 0), _.get(o, 'count', 1)),
@ -393,7 +441,7 @@ export const set_total_result: EPR = async (info, data, send) => {
// Save Recitals
const rInfo = $(data).element('recital_info.recital');
if (rInfo){
if (rInfo) {
const rIndex = rInfo.number('recital_index', -1);
if (rIndex >= 0) {
const r = rInfo.element('result');
@ -423,6 +471,7 @@ export const get_musicdata: EPR = async (info, data, send) => {
const refid = $(data).str('refid');
if (!refid) return send.deny();
const isForte = !info.module.includes("op")
const scoreData = await readScores(refid);
const recital_record: any[] = [];
@ -450,18 +499,21 @@ export const get_musicdata: EPR = async (info, data, send) => {
const mdata = m.split(':');
const musi = scoreData.scores[m];
if (isForte && parseInt(mdata[0], 10) > 195) continue;
music.push(K.ATTR({
music_index: mdata[0],
sheet_type: mdata[1],
}, {
'score': K.ITEM('s32', musi.score),
'grade_basic': K.ITEM('u32', musi.grade),
'grade_recital': K.ITEM('u32', musi.recital),
'play_count': K.ITEM('s32', musi.count),
'clear_count': K.ITEM('s32', musi.clear),
'multi_count': K.ITEM('s32', musi.multi),
'hands_mode': K.ITEM('s8', musi.mode),
'clear_flag': K.ITEM('s32', musi.flag),
music_index: mdata[0],
sheet_type: mdata[1],
}, {
score: K.ITEM('s32', musi.score),
evaluation: K.ITEM('u32', musi.grade), // Forte
grade_basic: K.ITEM('u32', musi.grade),
grade_recital: K.ITEM('u32', musi.recital),
play_count: K.ITEM('s32', musi.count),
clear_count: K.ITEM('s32', musi.clear),
multi_count: K.ITEM('s32', musi.multi),
hands_mode: K.ITEM('s8', musi.mode),
clear_flag: K.ITEM('s32', musi.flag),
}));
}
@ -471,83 +523,95 @@ export const get_musicdata: EPR = async (info, data, send) => {
});
};
function forteNumericHandler(isForte: boolean, input: number, max: number, def: number = 0) {
return isForte ? input > max ? def : input : input;
}
async function readProfile(refid: string): Promise<Profile> {
const profile = await DB.FindOne<Profile>(refid, { collection: 'profile'} )
const profile = await DB.FindOne<Profile>(refid, { collection: 'profile' })
return profile || defaultProfile
}
async function writeProfile(refid: string, profile: Profile) {
await DB.Upsert<Profile>(refid, { collection: 'profile'}, profile)
await DB.Upsert<Profile>(refid, { collection: 'profile' }, profile)
}
async function readScores(refid: string): Promise<Scores> {
const score = await DB.FindOne<Scores>(refid, { collection: 'scores'} )
return score || { collection: 'scores', recitals: {}, scores: {}}
const score = await DB.FindOne<Scores>(refid, { collection: 'scores' })
return score || { collection: 'scores', recitals: {}, scores: {} }
}
async function writeScores(refid: string, scores: Scores) {
await DB.Upsert<Scores>(refid, { collection: 'scores'}, scores)
await DB.Upsert<Scores>(refid, { collection: 'scores' }, scores)
}
const defaultProfile: Profile = {
collection: 'profile',
collection: 'profile',
name: 'GUEST',
music: 0,
sheet: 0,
brooch: 0,
hispeed: 0,
beatGuide: 1,
headphone: 0,
judgeBar: 250,
group: 0,
mode: 0,
near: 0,
offset: 0,
bingo: 0,
skill: '0',
playCount: 0,
todayPlayCount: 0,
keyBeam: 0,
orbit: 0,
noteHeight: 10,
noteWidth: 0,
judgeWidth: 0,
beatVolume: 0,
beatType: 0,
keyVolume: 0,
bgmVolume: 0,
note: 0,
sf: 0,
judgeFX: 0,
simple: 0,
money: 0,
fame: 0,
fameId: 0,
island: 0,
brooches: {
'1': {
level: 1,
watch: 0,
steps: 0,
new: 0,
},
},
islands: {},
kentei: {},
params: {
'1': [0],
},
musicList: {
type_0: Array(32).fill(-1),
type_1: Array(32).fill(-1),
type_2: Array(32).fill(-1),
type_3: Array(32).fill(-1),
},
musicList2: {
type_0: Array(32).fill(-1),
type_1: Array(32).fill(-1),
type_2: Array(32).fill(-1),
type_3: Array(32).fill(-1),
name: 'GUEST',
music: 0,
sheet: 0,
brooch: 0,
hispeed: 0,
beatGuide: 1,
headphone: 0,
judgeBar: 250,
group: 0,
mode: 0,
near: 0,
offset: 0,
bingo: 0,
skill: '0',
playCount: 0,
todayPlayCount: 0,
keyBeam: 0,
orbit: 0,
noteHeight: 10,
noteWidth: 0,
judgeWidth: 0,
beatVolume: 0,
beatType: 0,
keyVolume: 0,
bgmVolume: 0,
note: 0,
sf: 0,
judgeFX: 0,
simple: 0,
money: 0,
fame: 0,
fameId: 0,
island: 0,
brooches: {
'1': {
level: 1,
watch: 0,
steps: 0,
new: 0,
},
},
islands: {},
kentei: {},
cat_stairs: {
'0': {
total: 0,
index: 0,
steps: 0,
goal: 0
}
},
params: {
'1': [0],
},
musicList: {
type_0: Array(32).fill(-1),
type_1: Array(32).fill(-1),
type_2: Array(32).fill(-1),
type_3: Array(32).fill(-1),
},
musicList2: {
type_0: Array(32).fill(-1),
type_1: Array(32).fill(-1),
type_2: Array(32).fill(-1),
type_3: Array(32).fill(-1),
},
}

View File

@ -1,21 +1,21 @@
import { get_common_info, get_music_info } from "./handler/common";
import { get_musicdata, get_playdata, regist_playdata, set_total_result} from "./handler/player"
import { get_musicdata, get_playdata, regist_playdata, set_total_result } from "./handler/player"
export function register() {
R.GameCode('PAN');
const MultiRoute = (method: string, handler: EPR | boolean) => {
// Helper for register multiple versions.
// But.. only Opus 2 for now.
R.Route(`op2_${method}`, handler);
// Helper for register multiple versions.
R.Route(method, handler); // First version and Forte.
R.Route(`op2_${method}`, handler);
};
const CommonRoute = (method: string, handler: EPR | boolean) =>
const CommonRoute = (method: string, handler: EPR | boolean) =>
MultiRoute(`common.${method}`, handler)
const PlayerRoute = (method: string, handler: EPR | boolean) =>
const PlayerRoute = (method: string, handler: EPR | boolean) =>
MultiRoute(`player.${method}`, handler)
// Common
CommonRoute('get_common_info', get_common_info);
CommonRoute('get_music_info', get_music_info);
@ -25,4 +25,13 @@ export function register() {
PlayerRoute('get_playdata', get_playdata)
PlayerRoute('regist_playdata', regist_playdata)
PlayerRoute('set_total_result', set_total_result)
//TODO: Fix this things with actual working handler.
PlayerRoute('set_stage_result', true)
R.Unhandled(async (info, data, send) => {
if (["eventlog"].includes(info.module)) return;
console.error(`Received Unhandled Response on ${info.method} by ${info.model}/${info.module}`)
console.error(`Received Request: ${JSON.stringify(data, null, 4)}`)
})
}

View File

@ -1,82 +1,90 @@
export interface Profile {
collection: 'profile',
name: string;
playCount: number;
todayPlayCount: number;
music: number;
sheet: number;
brooch: number;
hispeed: number;
beatGuide: number;
headphone: number;
judgeBar: number;
group: number;
mode: number;
near: number;
offset: number;
bingo: number;
skill: string;
keyBeam: number;
orbit: number;
noteHeight: number;
noteWidth: number;
judgeWidth: number;
beatVolume: number;
beatType: number;
keyVolume: number;
bgmVolume: number;
note: number;
sf: number;
judgeFX: number;
simple: number;
money: number;
fame: number;
fameId: number;
island: number;
params: {
[key: string]: number[];
collection: 'profile',
name: string;
playCount: number;
todayPlayCount: number;
music: number;
sheet: number;
brooch: number;
hispeed: number;
beatGuide: number;
headphone: number;
judgeBar: number;
group: number;
mode: number;
near: number;
offset: number;
bingo: number;
skill: string;
keyBeam: number;
orbit: number;
noteHeight: number;
noteWidth: number;
judgeWidth: number;
beatVolume: number;
beatType: number;
keyVolume: number;
bgmVolume: number;
note: number;
sf: number;
judgeFX: number;
simple: number;
money: number;
fame: number;
fameId: number;
island: number;
params: {
[key: string]: number[];
};
brooches: {
[key: string]: {
watch: number;
level: number;
steps: number;
new: number;
};
brooches: {
[key: string]: {
watch: number;
level: number;
steps: number;
new: number;
};
};
islands: {
[key: string]: {
look: number;
select: number;
time: number;
containers: {
[key: string]: {
prog: number;
rewards: { [key: string]: number };
};
};
islands: {
[key: string]: {
look: number;
select: number;
time: number;
containers: {
[key: string]: {
prog: number;
rewards: { [key: string]: number };
};
};
};
kentei: {
[key: string]: {
stage: number;
score: number[];
rate: number;
flag: number;
count: number;
};
};
kentei: {
[key: string]: {
stage: number;
score: number[];
rate: number;
flag: number;
count: number;
};
musicList: {
type_0: number[];
type_1: number[];
type_2: number[];
type_3: number[];
};
musicList2: {
type_0: number[];
type_1: number[];
type_2: number[];
type_3: number[];
};
}
};
cat_stairs: {
[key: string]: {
total: number,
index: number,
steps: number,
goal: number
}
};
musicList: {
type_0: number[];
type_1: number[];
type_2: number[];
type_3: number[];
};
musicList2: {
type_0: number[];
type_1: number[];
type_2: number[];
type_3: number[];
};
}

View File

@ -1,30 +1,30 @@
export interface Scores {
collection: 'scores',
recitals: {
[key: string]: {
count: number;
hall: number;
cat: number[];
audience: number;
money: number;
fame: number;
player: number;
score: number;
start: string;
end: string;
};
recitals: {
[key: string]: {
count: number;
hall: number;
cat: number[];
audience: number;
money: number;
fame: number;
player: number;
score: number;
start: string;
end: string;
};
scores: {
[key: string]: {
score: number;
grade: number;
recital: number;
count: number;
clear: number;
multi: number;
mode: number;
flag: number;
};
};
scores: {
[key: string]: {
score: number;
grade: number;
recital: number;
count: number;
clear: number;
multi: number;
mode: number;
flag: number;
};
}
};
}