Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbfcf60ac7 | ||
|
|
c94b6cb36f | ||
|
|
7fe1b0536e | ||
|
|
5179e79ca5 | ||
|
|
8e862231c0 | ||
|
|
8465294b38 | ||
|
|
f6b0115fea | ||
|
|
d07f822f70 | ||
|
|
5ca14ab461 | ||
|
|
02a2c7d973 | ||
|
|
649a30a90e | ||
|
|
9996c5ead4 | ||
|
|
39d517ba5a | ||
|
|
97a9e65682 | ||
|
|
c9c59e0872 |
@@ -1,4 +0,0 @@
|
||||
handlers/test.json
|
||||
webui/test_asset
|
||||
s3p_extract.exe
|
||||
ffmpeg.exe
|
||||
@@ -1,70 +1,106 @@
|
||||
# SOUND VOLTEX
|
||||
# DanceDanceRevolution
|
||||
|
||||
**Plugin Version:** fork-6.0.3.4
|
||||
**Plugin Version:** fork-mdx-3.0.3d
|
||||
|
||||
**Supported game versions:** EXCEED GEAR (2024070900)
|
||||
|
||||
**Unsupported game versions:** Every other game, as they're untested.
|
||||
**Supported game versions:** WORLD (2024101500)
|
||||
|
||||
**Required Asphyxia Core version** [1.50c](https://github.com/asphyxia-core/asphyxia-core.github.io/releases/tag/v1.50)
|
||||
|
||||
**Notes:**
|
||||
- This is a WIP plugin for DDR World and things might break so please use this at your own risk.
|
||||
- Please be aware that this plugin and the savefile it produces are incompatible with the official plugin, or any other forks. Please be cautious of using other plugins' savefiles with this fork of the plugin, or using this fork's savefile with other plugins.
|
||||
- Before using this plugin, run the [WebUI Asset Update](/plugin/sdvx@asphyxia/update%20webui%20assets). Do this every data and plugin update.
|
||||
- Please back up your save data to prevent unwanted issues (just in case)
|
||||
- Please back up your save data to prevent unwanted issues, especially while using this experimental plugin.
|
||||
- Please please please feel free to open PRs!
|
||||
|
||||
musicdb.xml Usage Guide
|
||||
===========
|
||||
1. Put your musicdb.xml file(s) in the _ddr@asphyxia/data_ directory.
|
||||
2. Configure plugin settings:
|
||||
- There are 2 related fields in the plugin settings:
|
||||
- **_musicdb.xml for musicdata\_load_**: mdb file where song difficulty and limited info will be retrieved. Set this config to the filename of the musicdb.xml file you copied. This file is required for other songs to appear.
|
||||
- **_musicdb.xml for WebUI_**: mdb file where song titles will be retrieved, this will be used for WebUI stuff. If you have a different xml file you want to use, set this config to the filename of that other musicdb.xml file, or keep it blank to use the same musicdb.xml as above.
|
||||
- **Sample setup 1**: I use a modified World musicdb with all difficulties and limited info defined for all songs. I do not need to use a separate musicdb.xml for WebUI (but I would also update this file to include upcoming songs.)
|
||||
- **Sample setup 2**: I use the last A3 musicdb for musicdata\_load. This will set difficulty and limited data for songs released up until A3. World songs info will be set using SONGS\_WORLD defined in _data/world.ts_. Then I use World musicdb for WebUI, so I could get all titles of songs released up until World (I would need to replace this file every time the game updates its song list.)
|
||||
|
||||
|
||||
|
||||
Changelog
|
||||
===========
|
||||
## fork-6.0.3.4
|
||||
### fork-mdx-3.0.3d
|
||||
|
||||
### New:
|
||||
|
||||
1. Main:
|
||||
- 2024070900 support
|
||||
- Added ARENA season 14 (rank match: MEGAMIX BATTLE)
|
||||
- ARENA STATION set 14 added.
|
||||
- Added TAMANEKO Adventure: new unlock system where you complete map missions and earn food for TAMANEKO. Completing maps unlock new songs and new XCD charts.
|
||||
- Track Liberation map can be enabled/disabled in the main settings.
|
||||
- Check 'Unlocking Events -> Stamp Events -> TAMA猫アドベンチャー (TAMANEKO Adventure)' to toggle the event.
|
||||
|
||||
2. Misc:
|
||||
- Updated Achievements list.
|
||||
- Fixed WebUI flare skill calculation mistake.
|
||||
- Fixed getLastGhostId function.
|
||||
- Added "unlock all songs" option.
|
||||
- Still requires musicdb.xml to get the song ids.
|
||||
- Added Triple Tribe 4 event data.
|
||||
- Gold cab exclusive, otherwise the songs will not appear in the songs list.
|
||||
- You can use patches to force the game to imitate gold cab.
|
||||
- Added "Step This Way" Challenge difficulties
|
||||
- Added "MVP" to SONGS_WORLD.
|
||||
- Added "Time to HYPERDRIVE" to SONGS_WORLD.
|
||||
- Song should appear if you're Silver rank in WORLD LEAGUE.
|
||||
- Added new charts to advanced play
|
||||
- "1116"
|
||||
- "Sahara"
|
||||
- "High & Low" (CHA)
|
||||
- "ONYX" (CHA)
|
||||
- Added new player customization options in Profile Settings.
|
||||
- BPL Team Supporter Appeal Board
|
||||
- Added 2nd WORLD LEAGUE info
|
||||
- Will start 11/14 10:00 JST.
|
||||
- Will add Hakken difficulties as soon as it is revealed.
|
||||
|
||||
|
||||
## fork-6.0.3.3
|
||||
### fork-mdx-3.0.2
|
||||
|
||||
### New:
|
||||
|
||||
1. Main:
|
||||
- 2024060401 support
|
||||
- Added PREMIUM GENERATOR (角巻わため、 / Tsunomaki Watame set)
|
||||
- Note: subbg files from this pregene set are missing on some leaked update data, you will not be able to use those until those files are in your data.
|
||||
- Added Watame songs to licensed songs list (exg.ts)
|
||||
- Watame crew usable (exg.ts)
|
||||
|
||||
2. Misc
|
||||
- Added option to hide/show serverside-removed music (enabled by default)
|
||||
|
||||
|
||||
## fork-6.0.3.2
|
||||
|
||||
### New:
|
||||
|
||||
1. Main:
|
||||
- 2024043001 support
|
||||
- Added ARENA season 13 (rank match: ARENA BATTLE point system)
|
||||
- ARENA STATION set 13 added.
|
||||
- VALKYRIE GENERATOR 14 added.
|
||||
- Added BPL S3 Stamp Event (eXLIPXe)
|
||||
- Check "Unlocking Events -> Stamp Events -> BEMANI PRO LEAGUE -SEASON 3- Special Stamp" to toggle the event.
|
||||
2. Misc:
|
||||
- Updated ARENA STATION pricing to reflect real game server prices (might miss some though)
|
||||
- WORLD LEAGUE
|
||||
- I did my best emulating what I understand how WORLD LEAGUE works, so my apologies if there's something that isn't accurately implemented. But this is how it works right now:
|
||||
- Promotion and demotion borders are determined by the league score of the player in rank 1. If you play alone on your server, you'll automatically be rank 1 all the time.
|
||||
- Bronze class promotion border is set to >= 50% of the rank 1's score.
|
||||
- Silver class promotion and demotion borders are set to >= 65% and <= 15% of the rank 1's score, respectively.
|
||||
- Gold class demotion border is set to <= 15% as well.
|
||||
- League info and period is defined in data/world.ts:LEAGUE_WORLD.
|
||||
- League period ends after 'end' datetime.
|
||||
- Promotion/demotion occurs after 'summary' datetime.
|
||||
- Class benefits will apply depending on your class.
|
||||
- Note: Since difficulty level info isn't revealed until the songs are officially released, I cannot add them to the list yet. I will update this plugin with the correct song info once they are released officially.
|
||||
- Privilege of early play: this filter now displays applicable songs (Grand Prix advanced play songs)
|
||||
- WebUI stuff
|
||||
- Flare Data Page: displays your top 30 songs for Classic, White and Gold.
|
||||
- Fixes
|
||||
- Rewrote getLastGhostId function.
|
||||
- Fixed "So What" and "Akatsuki" diffLv mix up.
|
||||
|
||||
|
||||
### Todo:
|
||||
### fork-mdx-3.0.1
|
||||
|
||||
1. Figure out how to use image (png) files to appear in information/news popup.
|
||||
2. More work on online matchmaking (idk if this is possible)
|
||||
3. Implement pro_team_id setting.
|
||||
4. Reminder to add new achievements (when it is released officially)
|
||||
- Support for 2024091000.
|
||||
- Added list of old songs' re-rates in _data/world.ts:SONGS\_OVERRIDE\_WORLD_.
|
||||
- Updated events list & event loading code:
|
||||
- Galaxy Play
|
||||
- EXTRA SAVIOR
|
||||
- MYSTICAL Re:UNION (songs automatically unlocked on login)
|
||||
- Attempts to fix ghost data loading:
|
||||
- Added ghost id to score and ghost data
|
||||
- Ghost data gets created when there is no existing \[compatible\] data; and it gets updated when getting a higher or the same score. Side effect of this is when you have set a high score prior to this plugin update, the ghost data won't be updated unless you break or match that high score.
|
||||
- Unfortunately I could not find a way to match the old scores to their respective ghost data, since the old ghost data only stored the song id and difficulty, and not the style (single/double.)
|
||||
- World, Area and Machine #1 high score saving/loading (WIP)
|
||||
- Area high score: uses locationid to search, save and load scores.
|
||||
- Machine high score: uses locationid and pcbid.
|
||||
- Ghost data also gets created for each new high score (overwritten when high score is broken/matched)
|
||||
- WebUI stuff (WIP) - musicdb.xml required for proper score display.
|
||||
- Basic profile info
|
||||
- Flare skill info
|
||||
- Music/score table
|
||||
|
||||
|
||||
|
||||
To do:
|
||||
===========
|
||||
|
||||
1. Look for more missing features
|
||||
2. Refactor hiscore code
|
||||
3. More WebUI stuff
|
||||
4. Figure out unknown values in score_str
|
||||
5. Rival loading and figure out unknown values in rival record_str
|
||||
6. Proper loading of Flare skill in-game (make sure to include only top 30 scores from classic, white and gold)
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
@echo off
|
||||
for /f %%a in ('dir "webui\asset\audio\" /b /s /a-d ^| findstr ".wma"') do (
|
||||
echo Converting %%~fa
|
||||
ffmpeg -loglevel error -y -i "%%~fa" -vn -ar 44100 -ac 2 -b:a 192k "%%~dpa%%~na.mp3"
|
||||
del %%~fa
|
||||
)
|
||||
@echo on
|
||||
@@ -1 +0,0 @@
|
||||
find . -type f -name "*.wma" -exec bash -c 'echo "Converting $1" && ffmpeg -loglevel error -y -i $1 -vn -ar 44100 -ac 2 -b:a 192k ${1%.wma}.mp3 && rm $1' bash {} \;
|
||||
@@ -0,0 +1 @@
|
||||
*.xml
|
||||
@@ -1,32 +0,0 @@
|
||||
export const COURSE2 = [
|
||||
{
|
||||
id: 0,
|
||||
level: 0,
|
||||
season_id: 0,
|
||||
season_name: '',
|
||||
new_flg: 0,
|
||||
name: '',
|
||||
type: 0,
|
||||
name_id: 0,
|
||||
matching_assist: 0,
|
||||
guage_type: 0,
|
||||
paseli_type: 0,
|
||||
tracks: [
|
||||
{
|
||||
no: 0,
|
||||
id: 2,
|
||||
type: 0
|
||||
},
|
||||
{
|
||||
no: 1,
|
||||
id: 2,
|
||||
type: 0
|
||||
},
|
||||
{
|
||||
no: 2,
|
||||
id: 2,
|
||||
type: 0
|
||||
},
|
||||
]
|
||||
},
|
||||
];
|
||||
@@ -1,74 +0,0 @@
|
||||
export const textureslist = [
|
||||
{
|
||||
'file': '/data/graphics/ver06/arena_rank.ifs',
|
||||
'asset_folder': 'arena_rank',
|
||||
'md5': '0311d56e5db4fe276aaab4435cb52354',
|
||||
'textures': [
|
||||
['glow.png', 2890640, 16288, [2, 570, 2, 106], [0, 572, 0, 108]],
|
||||
['mixstar.png', 2712288, 48206, [2, 542, 110, 650], [0, 544, 108, 652]],
|
||||
['u1.png', 457712, 149908, [574, 1114, 2, 542], [572, 1116, 0, 544]],
|
||||
['u2.png', 153136, 152586, [1118, 1658, 2, 542], [1116, 1660, 0, 544]],
|
||||
['u3.png', 0, 153136, [546, 1086, 546, 1086], [544, 1088, 544, 1088]],
|
||||
['u4.png', 305728, 151974, [1090, 1630, 546, 1086], [1088, 1632, 544, 1088]],
|
||||
['u.png', 607632, 147016, [2, 542, 654, 1194], [0, 544, 652, 1196]],
|
||||
['s1.png', 1067584, 102100, [546, 1086, 1090, 1630], [544, 1088, 1088, 1632]],
|
||||
['s2.png', 860160, 103886, [1090, 1630, 1090, 1630], [1088, 1632, 1088, 1632]],
|
||||
['s3.png', 754656, 105494, [2, 542, 1198, 1738], [0, 544, 1196, 1740]],
|
||||
['s4.png', 964048, 103534, [1662, 2202, 2, 542], [1660, 2204, 0, 544]],
|
||||
['a1.png', 1856768, 93336, [2206, 2746, 2, 542], [2204, 2748, 0, 544]],
|
||||
['a2.png', 1666144, 96328, [2750, 3290, 2, 542], [2748, 3292, 0, 544]],
|
||||
['a3.png', 1568784, 97346, [3294, 3834, 2, 542], [3292, 3836, 0, 544]],
|
||||
['a4.png', 1762480, 94284, [1634, 2174, 546, 1086], [1632, 2176, 544, 1088]],
|
||||
['b1.png', 2484560, 86781, [2178, 2718, 546, 1086], [2176, 2720, 544, 1088]],
|
||||
['b2.png', 2220768, 88790, [2722, 3262, 546, 1086], [2720, 3264, 544, 1088]],
|
||||
['b3.png', 2041344, 90088, [3266, 3806, 546, 1086], [3264, 3808, 544, 1088]],
|
||||
['b4.png', 2309568, 87663, [1634, 2174, 1090, 1630], [1632, 2176, 1088, 1632]],
|
||||
['c1.png', 1470944, 97837, [2178, 2718, 1090, 1630], [2176, 2720, 1088, 1632]],
|
||||
['c2.png', 1271488, 100109, [2722, 3262, 1090, 1630], [2720, 3264, 1088, 1632]],
|
||||
['c3.png', 1169696, 101777, [3266, 3806, 1090, 1630], [3264, 3808, 1088, 1632]],
|
||||
['c4.png', 1371600, 99342, [546, 1086, 1634, 2174], [544, 1088, 1632, 2176]],
|
||||
['d1.png', 2571344, 85426, [1090, 1630, 1634, 2174], [1088, 1632, 1632, 2176]],
|
||||
['d2.png', 2131440, 89314, [1634, 2174, 1634, 2174], [1632, 2176, 1632, 2176]],
|
||||
['d3.png', 1950112, 91226, [2178, 2718, 1634, 2174], [2176, 2720, 1632, 2176]],
|
||||
['d4.png', 2397232, 87321, [2722, 3262, 1634, 2174], [2720, 3264, 1632, 2176]],
|
||||
['none.png', 2656784, 55490, [3266, 3806, 1634, 2174], [3264, 3808, 1632, 2176]],
|
||||
['fudawinstat.png', 2922368, 9846, [2, 514, 1742, 1826], [0, 516, 1740, 1828]]
|
||||
]
|
||||
},
|
||||
{
|
||||
'file': '/data/graphics/ver06/psd_level.ifs',
|
||||
'asset_folder': 'difficulty',
|
||||
'md5': '26ef89b4550cac6156fa78ef4e59e8c3',
|
||||
'textures': [
|
||||
['level_small_xcd.png', 193824, 2181, [710, 922, 2, 50], [708, 924, 0, 52]]
|
||||
]
|
||||
},
|
||||
{
|
||||
'file': '/data/graphics/ver06/psd_skill.ifs',
|
||||
'asset_folder': 'skill_lv',
|
||||
'md5': '9a5684960c0d86cd18f1c64f6e13c98b',
|
||||
'textures': [
|
||||
['skill_frame_normal_sp.png', 549552, 45470, [2, 602, 242, 582], [0, 604, 240, 584]],
|
||||
['skill_frame_normal_silver.png', 884448, 32373, [2, 602, 586, 926], [0, 604, 584, 928]],
|
||||
['skill_frame_normal_gold.png', 850288, 34158, [610, 1210, 2, 342], [608, 1212, 0, 344]],
|
||||
['skill_frame_god_sp_none.png', 595024, 40145, [1214, 1814, 2, 342], [1212, 1816, 0, 344]],
|
||||
['skill_frame_god_sp.png', 195312, 80745, [606, 1206, 346, 686], [604, 1208, 344, 688]],
|
||||
['skill_frame_god_silver.png', 346064, 53343, [1210, 1810, 346, 686], [1208, 1812, 344, 688]],
|
||||
['skill_frame_god_gold.png', 276064, 69987, [606, 1206, 690, 1030], [604, 1208, 688, 1032]],
|
||||
['skill_none.png', 1227792, 10209, [2, 454, 930, 1058], [0, 456, 928, 1060]],
|
||||
['skill_12.png', 1012656, 20206, [458, 910, 1034, 1162], [456, 912, 1032, 1164]],
|
||||
['skill_11.png', 1050144, 14880, [914, 1366, 1034, 1162], [912, 1368, 1032, 1164]],
|
||||
['skill_10.png', 1156848, 12906, [1370, 1822, 1034, 1162], [1368, 1824, 1032, 1164]],
|
||||
['skill_09.png', 1169760, 12873, [2, 454, 1062, 1190], [0, 456, 1060, 1192]],
|
||||
['skill_08.png', 1091424, 13181, [458, 910, 1166, 1294], [456, 912, 1164, 1296]],
|
||||
['skill_07.png', 1065024, 13193, [914, 1366, 1166, 1294], [912, 1368, 1164, 1296]],
|
||||
['skill_06.png', 1078224, 13189, [1370, 1822, 1166, 1294], [1368, 1824, 1164, 1296]],
|
||||
['skill_05.png', 1104608, 13144, [2, 454, 1194, 1322], [0, 456, 1192, 1324]],
|
||||
['skill_04.png', 1182640, 12353, [458, 910, 1298, 1426], [456, 912, 1296, 1428]],
|
||||
['skill_03.png', 1117760, 13079, [914, 1366, 1298, 1426], [912, 1368, 1296, 1428]],
|
||||
['skill_02.png', 1130848, 13045, [1370, 1822, 1298, 1426], [1368, 1824, 1296, 1428]],
|
||||
['skill_01.png', 1143904, 12943, [2, 454, 1326, 1454], [0, 456, 1324, 1456]],
|
||||
['skill_00.png', 1217568, 10211, [458, 910, 1430, 1558], [456, 912, 1428, 1560]]
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,343 @@
|
||||
export const SONGS_WORLD = [
|
||||
{ mcode: 38665, limited_ary: [2, 2, 2, 2, 2, -1, 2, 2, 2, 2], diffLv: [3, 6, 10, 13, 15, 0, 6, 10, 13, 15] },
|
||||
{ mcode: 38661, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [3, 5, 9, 12, 0, 0, 5, 9, 12, 0] },
|
||||
{ mcode: 38659, limited_ary: [2, 2, 2, 2, 2, -1, 2, 2, 2, 2], diffLv: [3, 7, 12, 14, 16, 0, 7, 12, 14, 16] },
|
||||
{ mcode: 38669, limited_ary: [2, 2, 2, 2, 2, -1, 2, 2, 2, 2], diffLv: [3, 7, 11, 14, 15, 0, 7, 11, 14, 15] },
|
||||
{ mcode: 38668, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [3, 6, 10, 13, 0, 0, 6, 10, 13, 0] },
|
||||
{ mcode: 38667, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [3, 6, 9, 12, 0, 0, 6, 9, 12, 0] },
|
||||
{ mcode: 38663, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [3, 7, 10, 13, 0, 0, 7, 10, 13, 0] },
|
||||
{ mcode: 38660, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [1, 4, 8, 12, 0, 0, 4, 8, 12, 0] },
|
||||
{ mcode: 38688, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [3, 7, 11, 14, 0, 0, 7, 11, 14, 0] },
|
||||
{ mcode: 38672, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [2, 4, 9, 13, 0, 0, 4, 9, 13, 0] },
|
||||
{ mcode: 38662, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [2, 5, 8, 13, 0, 0, 4, 8, 13, 0] },
|
||||
{ mcode: 38731, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [1, 3, 9, 13, 0, 0, 3, 9, 12, 0] },
|
||||
{ mcode: 38722, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [2, 6, 10, 14, 0, 0, 6, 10, 14, 0] },
|
||||
{ mcode: 38704, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [1, 4, 9, 12, 0, 0, 4, 9, 12, 0] },
|
||||
{ mcode: 38724, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [3, 5, 9, 13, 0, 0, 4, 9, 13, 0] },
|
||||
{ mcode: 38730, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [2, 4, 8, 13, 0, 0, 4, 8, 13, 0] },
|
||||
{ mcode: 38723, limited_ary: [0, 0, 0, 0, 0, -1, 0, 0, 0, 0], diffLv: [2, 4, 9, 14, 12, 0, 5, 10, 14, 12] },
|
||||
{ mcode: 38721, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [2, 4, 8, 12, 0, 0, 4, 8, 12, 0] },
|
||||
{ mcode: 38706, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [1, 4, 9, 13, 0, 0, 4, 9, 13, 0] },
|
||||
{ mcode: 38705, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [2, 6, 10, 13, 0, 0, 6, 10, 13, 0] },
|
||||
{ mcode: 38727, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [3, 7, 11, 14, 0, 0, 7, 11, 14, 0] },
|
||||
{ mcode: 38739, limited_ary: [0, 0, 0, 0, 2, -1, 0, 0, 0, 2], diffLv: [3, 5, 9, 12, 15, 0, 5, 9, 12, 15] },
|
||||
{ mcode: 38664, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [3, 7, 9, 12, 0, 0, 7, 9, 12, 0] },
|
||||
{ mcode: 38670, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [4, 7, 10, 13, 0, 0, 7, 10, 13, 0] },
|
||||
{ mcode: 38680, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [3, 6, 11, 14, 0, 0, 6, 11, 14, 0] },
|
||||
{ mcode: 38666, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [3, 7, 10, 14, 0, 0, 7, 10, 14, 0] },
|
||||
{ mcode: 38671, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [1, 4, 8, 13, 0, 0, 4, 8, 13, 0] },
|
||||
{ mcode: 38677, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [3, 6, 9, 12, 0, 0, 6, 9, 12, 0] },
|
||||
{ mcode: 38678, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [1, 5, 9, 11, 0, 0, 3, 9, 12, 0] },
|
||||
{ mcode: 38707, limited_ary: [0, -1, -1, -1, -1, -1, -1, -1, -1, -1], diffLv: [6, 0, 0, 0, 0, 0, 0, 0, 0, 0] },
|
||||
{ mcode: 38695, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [3, 7, 11, 14, 0, 0, 7, 11, 14, 0] },
|
||||
{ mcode: 38692, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [2, 7, 12, 15, 0, 0, 7, 12, 15, 0] },
|
||||
{ mcode: 38694, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [3, 6, 11, 14, 0, 0, 6, 11, 14, 0] },
|
||||
{ mcode: 38691, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [2, 8, 12, 15, 0, 0, 7, 12, 15, 0] },
|
||||
{ mcode: 38693, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [3, 7, 11, 15, 0, 0, 7, 11, 15, 0] },
|
||||
{ mcode: 38733, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [2, 5, 9, 12, 0, 0, 5, 9, 12, 0] },
|
||||
{ mcode: 38736, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [2, 5, 8, 13, 0, 0, 5, 8, 13, 0] },
|
||||
{ mcode: 38735, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [3, 6, 10, 16, 0, 0, 6, 10, 16, 0] },
|
||||
{ mcode: 38728, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [3, 7, 12, 15, 0, 0, 7, 12, 15, 0] },
|
||||
{ mcode: 38746, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [4, 8, 14, 16, 0, 0, 8, 14, 16, 0] },
|
||||
{ mcode: 38745, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [3, 7, 12, 16, 0, 0, 7, 12, 16, 0] },
|
||||
{ mcode: 38744, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [4, 7, 13, 17, 0, 0, 7, 13, 17, 0] },
|
||||
{ mcode: 38747, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [4, 10, 15, 18, 0, 0, 10, 15, 18, 0] },
|
||||
{ mcode: 38748, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [4, 9, 13, 16, 0, 0, 9, 13, 16, 0] },
|
||||
{ mcode: 38749, limited_ary: [0, 0, 0, 0, 0, -1, 0, 0, 0, 0], diffLv: [2, 2, 7, 11, 13, 0, 2, 7, 11, 14] },
|
||||
{ mcode: 38734, limited_ary: [0, 0, 0, 0, 0, -1, 0, 0, 0, 0], diffLv: [3, 6, 10, 13, 8, 0, 6, 10, 13, 9] },
|
||||
{ mcode: 38737, limited_ary: [2, 2, 2, 2, 2, -1, 2, 2, 2, 2], diffLv: [3, 6, 11, 13, 16, 0, 6, 11, 13, 16] },
|
||||
{ mcode: 38738, limited_ary: [2, 2, 2, 2, 2, -1, 2, 2, 2, 2], diffLv: [2, 5, 8, 12, 17, 5, 8, 12, 17] },
|
||||
{ mcode: 37222, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [2, 4, 10, 13, 0, 0, 4, 9, 13, 0] },
|
||||
{ mcode: 37604, limited_ary: [2, 2, 2, 2, 2, -1, 2, 2, 2, 2], diffLv: [2, 6, 9, 12, 14, 0, 5, 9, 12, 14] },
|
||||
{ mcode: 37234, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [1, 3, 7, 11, 0, 0, 3, 7, 11, 0] },
|
||||
{ mcode: 37363, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [2, 5, 9, 13, 0, 0, 5, 9, 13, 0] },
|
||||
{ mcode: 38756, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [3, 8, 15, 18, 0, 0, 8, 14, 18, 0] },
|
||||
{ mcode: 38758, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [5, 10, 13, 17, 0, 0, 10, 13, 17, 0] },
|
||||
{ mcode: 38759, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [3, 6, 13, 15, 0, 0, 7, 13, 15, 0] },
|
||||
{ mcode: 38757, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [2, 5, 8, 13, 0, 0, 5, 8, 13, 0] },
|
||||
{ mcode: 38622, limited_ary: [12, 12, 12, 12, -1, -1, 12, 12, 12, -1], diffLv: [2, 7, 12, 15, 0, 0, 7, 12, 15, 0] },
|
||||
{ mcode: 38760, limited_ary: [2, 2, 2, 2, 2, -1, 2, 2, 2, 2], diffLv: [4, 8, 13, 16, 18, 0, 8, 13, 16, 18] },
|
||||
{ mcode: 38761, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [4, 8, 12, 15, 0, 0, 8, 12, 15, 0] },
|
||||
|
||||
// songs that have yet to release. unknown difficulty lvls.
|
||||
// { mcode: 38629, limited_ary: [13, 13, 13, 13, -1, -1 13, 13 13, -1], diffLv: [] } // hakken
|
||||
]
|
||||
|
||||
export const SONGS_OVERRIDE_WORLD = [
|
||||
// Override info for old songs
|
||||
{ mcode: 38624, limited_ary: [2, 2, 2, 2, 2, -1, 2, 2, 2, 2], diffLv: [2, 5, 10, 15, 17, 0, 5, 10, 15, 17] },
|
||||
{ mcode: 38623, limited_ary: [2, 2, 2, 2, 2, -1, 2, 2, 2, 2], diffLv: [3, 11, 15, 17, 18, 0, 11, 14, 17, 18] },
|
||||
{ mcode: 38628, limited_ary: [2, 2, 2, 2, -1, -1, 2, 2, 2, -1], diffLv: [5, 9, 14, 18, 0, 0, 9, 14, 18, 0] },
|
||||
{ mcode: 11, limited_ary: [], diffLv: [3, 6, 6, 10, 10, 0, 6, 8, 9, 10] },
|
||||
{ mcode: 13, limited_ary: [], diffLv: [4, 6, 8, 9, 12, 0, 7, 8, 9, 12] },
|
||||
{ mcode: 84, limited_ary: [], diffLv: [3, 7, 8, 11, 0, 0, 9, 11, 12, 0] },
|
||||
{ mcode: 137, limited_ary: [], diffLv: [2, 3, 6, 8, 0, 0, 5, 6, 8, 0] },
|
||||
{ mcode: 126, limited_ary: [], diffLv: [3, 6, 10, 12, 12, 0, 7, 8, 11, 12] },
|
||||
{ mcode: 128, limited_ary: [], diffLv: [4, 7, 8, 10, 0, 0, 5, 9, 13, 0] },
|
||||
{ mcode: 182, limited_ary: [], diffLv: [2, 2, 4, 7, 0, 0, 3, 5, 8, 0] },
|
||||
{ mcode: 155, limited_ary: [], diffLv: [3, 5, 7, 11, 0, 0, 5, 7, 12, 0] },
|
||||
{ mcode: 221, limited_ary: [], diffLv: [3, 6, 8, 11, 0, 0, 7, 8, 10, 0] },
|
||||
{ mcode: 159, limited_ary: [], diffLv: [5, 7, 8, 11, 0, 0, 4, 8, 10, 0] },
|
||||
{ mcode: 160, limited_ary: [], diffLv: [5, 9, 10, 12, 0, 0, 7, 10, 13, 0] },
|
||||
{ mcode: 257, limited_ary: [], diffLv: [3, 5, 7, 10, 0, 0, 6, 8, 11, 0] },
|
||||
{ mcode: 267, limited_ary: [], diffLv: [4, 7, 9, 12, 0, 0, 8, 9, 13, 0] },
|
||||
{ mcode: 238, limited_ary: [], diffLv: [5, 6, 9, 12, 0, 0, 7, 9, 12, 0] },
|
||||
{ mcode: 365, limited_ary: [], diffLv: [4, 5, 7, 10, 0, 0, 4, 7, 10, 0] },
|
||||
{ mcode: 472, limited_ary: [], diffLv: [3, 4, 6, 9, 0, 0, 5, 7, 9, 0] },
|
||||
{ mcode: 480, limited_ary: [], diffLv: [5, 6, 8, 12, 12, 0, 7, 8, 12, 11] },
|
||||
{ mcode: 478, limited_ary: [], diffLv: [3, 4, 7, 10, 0, 0, 6, 9, 11, 0] },
|
||||
{ mcode: 436, limited_ary: [], diffLv: [4, 5, 7, 12, 0, 0, 5, 8, 12, 0] },
|
||||
{ mcode: 429, limited_ary: [], diffLv: [3, 6, 7, 9, 0, 0, 5, 7, 11, 0] },
|
||||
{ mcode: 476, limited_ary: [], diffLv: [3, 4, 7, 10, 0, 0, 4, 7, 10, 0] },
|
||||
{ mcode: 467, limited_ary: [], diffLv: [2, 4, 7, 9, 0, 0, 4, 7, 11, 0] },
|
||||
{ mcode: 437, limited_ary: [], diffLv: [3, 5, 7, 8, 0, 0, 4, 7, 9, 0] },
|
||||
{ mcode: 33811, limited_ary: [], diffLv: [2, 3, 9, 11, 0, 0, 3, 6, 10, 0] },
|
||||
{ mcode: 36914, limited_ary: [], diffLv: [2, 3, 7, 12, 0, 0, 4, 9, 11, 0] },
|
||||
{ mcode: 415, limited_ary: [], diffLv: [3, 4, 7, 11, 0, 0, 5, 7, 10, 0] },
|
||||
{ mcode: 33818, limited_ary: [], diffLv: [7, 10, 13, 15, 16, 0, 10, 12, 15, 17] },
|
||||
{ mcode: 33806, limited_ary: [], diffLv: [3, 7, 9, 10, 0, 0, 8, 10, 12, 0] },
|
||||
{ mcode: 33048, limited_ary: [], diffLv: [3, 6, 7, 11, 0, 0, 5, 7, 8, 0] },
|
||||
{ mcode: 36931, limited_ary: [], diffLv: [4, 4, 8, 10, 0, 0, 4, 8, 10, 0] },
|
||||
{ mcode: 36873, limited_ary: [], diffLv: [5, 5, 9, 11, 0, 0, 4, 9, 11, 0] },
|
||||
{ mcode: 36935, limited_ary: [], diffLv: [3, 6, 8, 11, 0, 0, 5, 8, 11, 0] },
|
||||
{ mcode: 36878, limited_ary: [], diffLv: [3, 4, 7, 9, 0, 0, 4, 7, 9, 0] },
|
||||
{ mcode: 37267, limited_ary: [], diffLv: [3, 4, 7, 10, 0, 0, 5, 7, 11, 0] },
|
||||
{ mcode: 37190, limited_ary: [], diffLv: [3, 5, 7, 9, 11, 0, 5, 7, 9, 12] },
|
||||
{ mcode: 37121, limited_ary: [], diffLv: [3, 7, 9, 13, 0, 0, 6, 9, 12, 0] },
|
||||
{ mcode: 37290, limited_ary: [], diffLv: [2, 5, 9, 12, 0, 0, 5, 7, 12, 0] },
|
||||
{ mcode: 37295, limited_ary: [], diffLv: [4, 6, 9, 11, 0, 0, 7, 8, 11, 0] },
|
||||
{ mcode: 37408, limited_ary: [], diffLv: [2, 3, 7, 9, 0, 0, 5, 6, 9, 0] },
|
||||
{ mcode: 37228, limited_ary: [], diffLv: [2, 4, 7, 11, 0, 0, 5, 7, 11, 0] },
|
||||
{ mcode: 37686, limited_ary: [], diffLv: [2, 4, 7, 10, 8, 0, 4, 7, 11, 8] },
|
||||
{ mcode: 37623, limited_ary: [], diffLv: [2, 4, 6, 9, 12, 0, 4, 7, 10, 12] },
|
||||
{ mcode: 37694, limited_ary: [], diffLv: [2, 5, 8, 11, 13, 0, 5, 8, 11, 13] },
|
||||
{ mcode: 37666, limited_ary: [], diffLv: [3, 5, 8, 11, 0, 0, 4, 8, 13, 0] },
|
||||
{ mcode: 37749, limited_ary: [], diffLv: [4, 6, 9, 12, 16, 0, 6, 9, 12, 16] },
|
||||
{ mcode: 37511, limited_ary: [], diffLv: [2, 4, 7, 9, 0, 0, 4, 7, 9, 0] },
|
||||
{ mcode: 37698, limited_ary: [], diffLv: [2, 2, 8, 11, 0, 0, 2, 9, 11, 0] },
|
||||
{ mcode: 37662, limited_ary: [], diffLv: [3, 8, 10, 14, 16, 0, 9, 11, 15, 16] },
|
||||
{ mcode: 37532, limited_ary: [], diffLv: [2, 4, 6, 9, 0, 0, 5, 7, 10, 0] },
|
||||
{ mcode: 37644, limited_ary: [], diffLv: [3, 6, 11, 15, 18, 0, 6, 9, 14, 18] },
|
||||
{ mcode: 37803, limited_ary: [], diffLv: [2, 4, 8, 12, 15, 0, 4, 8, 12, 15] },
|
||||
{ mcode: 37775, limited_ary: [], diffLv: [2, 5, 7, 10, 13, 0, 5, 8, 11, 13] },
|
||||
{ mcode: 37784, limited_ary: [], diffLv: [2, 4, 7, 9, 0, 0, 4, 6, 9, 0] },
|
||||
{ mcode: 37765, limited_ary: [], diffLv: [2, 4, 7, 10, 0, 0, 4, 7, 11, 0] },
|
||||
{ mcode: 37586, limited_ary: [], diffLv: [2, 4, 7, 9, 0, 0, 5, 8, 10, 0] },
|
||||
{ mcode: 37793, limited_ary: [], diffLv: [3, 6, 7, 10, 0, 0, 6, 7, 11, 0] },
|
||||
{ mcode: 37736, limited_ary: [], diffLv: [2, 4, 8, 10, 0, 0, 4, 8, 10, 0] },
|
||||
{ mcode: 37794, limited_ary: [], diffLv: [3, 4, 7, 11, 12, 0, 5, 7, 11, 12] },
|
||||
{ mcode: 37798, limited_ary: [], diffLv: [2, 5, 7, 11, 0, 0, 3, 7, 11, 0] },
|
||||
{ mcode: 37862, limited_ary: [], diffLv: [2, 5, 8, 13, 0, 0, 5, 9, 13, 0] },
|
||||
{ mcode: 37657, limited_ary: [], diffLv: [2, 3, 8, 10, 0, 0, 4, 8, 10, 0] },
|
||||
{ mcode: 37587, limited_ary: [], diffLv: [2, 5, 7, 9, 0, 0, 5, 7, 10, 0] },
|
||||
{ mcode: 37840, limited_ary: [], diffLv: [2, 4, 8, 11, 10, 0, 4, 8, 11, 11] },
|
||||
{ mcode: 37800, limited_ary: [], diffLv: [3, 5, 10, 12, 16, 0, 6, 9, 12, 16] },
|
||||
{ mcode: 37565, limited_ary: [], diffLv: [2, 5, 7, 12, 0, 0, 5, 7, 11, 0] },
|
||||
{ mcode: 37588, limited_ary: [], diffLv: [2, 4, 6, 9, 0, 0, 4, 6, 9, 0] },
|
||||
{ mcode: 37907, limited_ary: [], diffLv: [3, 7, 9, 13, 16, 0, 7, 10, 13, 16] },
|
||||
{ mcode: 37930, limited_ary: [], diffLv: [2, 7, 9, 14, 13, 0, 7, 9, 14, 13] },
|
||||
{ mcode: 37827, limited_ary: [], diffLv: [2, 5, 8, 11, 0, 0, 5, 9, 11, 0] },
|
||||
{ mcode: 37543, limited_ary: [], diffLv: [2, 3, 7, 9, 13, 0, 4, 7, 9, 13] },
|
||||
{ mcode: 37239, limited_ary: [], diffLv: [3, 4, 7, 12, 15, 0, 4, 7, 12, 15] },
|
||||
{ mcode: 37934, limited_ary: [], diffLv: [3, 7, 10, 14, 0, 0, 6, 10, 14, 0] },
|
||||
{ mcode: 37908, limited_ary: [], diffLv: [3, 7, 9, 11, 13, 0, 6, 9, 11, 13] },
|
||||
{ mcode: 37597, limited_ary: [], diffLv: [2, 4, 6, 10, 0, 0, 4, 6, 10, 0] },
|
||||
{ mcode: 37927, limited_ary: [], diffLv: [2, 6, 9, 13, 0, 0, 6, 9, 13, 0] },
|
||||
{ mcode: 37932, limited_ary: [], diffLv: [3, 4, 11, 16, 9, 0, 7, 12, 16, 9] },
|
||||
{ mcode: 37889, limited_ary: [], diffLv: [2, 7, 9, 12, 15, 0, 7, 10, 12, 15] },
|
||||
{ mcode: 37965, limited_ary: [], diffLv: [2, 4, 8, 10, 0, 0, 5, 9, 13, 0] },
|
||||
{ mcode: 37887, limited_ary: [], diffLv: [2, 5, 8, 11, 13, 0, 5, 8, 11, 13] },
|
||||
{ mcode: 38030, limited_ary: [], diffLv: [6, 10, 13, 16, 18, 0, 9, 13, 16, 18] },
|
||||
{ mcode: 38032, limited_ary: [], diffLv: [8, 12, 15, 16, 19, 0, 12, 16, 18, 19] },
|
||||
{ mcode: 38027, limited_ary: [], diffLv: [3, 7, 12, 15, 0, 0, 7, 12, 15, 0] },
|
||||
{ mcode: 38051, limited_ary: [], diffLv: [7, 10, 13, 17, 0, 0, 10, 13, 18, 0] },
|
||||
{ mcode: 37988, limited_ary: [], diffLv: [3, 4, 10, 14, 0, 0, 4, 10, 14, 0] },
|
||||
{ mcode: 38010, limited_ary: [], diffLv: [4, 8, 11, 15, 18, 0, 7, 12, 15, 18] },
|
||||
{ mcode: 38054, limited_ary: [], diffLv: [4, 6, 11, 15, 0, 0, 6, 11, 15, 0] },
|
||||
{ mcode: 38079, limited_ary: [], diffLv: [2, 5, 8, 10, 0, 0, 5, 8, 10, 0] },
|
||||
{ mcode: 38149, limited_ary: [], diffLv: [9, 13, 16, 18, 19, 0, 13, 16, 18, 19] },
|
||||
{ mcode: 38092, limited_ary: [], diffLv: [2, 5, 9, 12, 0, 0, 4, 9, 12, 0] },
|
||||
{ mcode: 38069, limited_ary: [], diffLv: [2, 5, 9, 13, 0, 0, 5, 9, 13, 0] },
|
||||
{ mcode: 38218, limited_ary: [], diffLv: [9, 12, 16, 18, 19, 0, 12, 16, 18, 19] },
|
||||
{ mcode: 38215, limited_ary: [], diffLv: [3, 6, 8, 11, 14, 0, 5, 8, 12, 14] },
|
||||
{ mcode: 38199, limited_ary: [], diffLv: [2, 3, 8, 11, 0, 0, 3, 8, 11, 0] },
|
||||
{ mcode: 38187, limited_ary: [], diffLv: [3, 5, 9, 12, 0, 0, 5, 9, 12, 0] },
|
||||
{ mcode: 38122, limited_ary: [], diffLv: [4, 6, 10, 13, 0, 0, 7, 10, 13, 0] },
|
||||
{ mcode: 38207, limited_ary: [], diffLv: [2, 4, 8, 13, 15, 0, 5, 9, 13, 15] },
|
||||
{ mcode: 38073, limited_ary: [], diffLv: [2, 4, 10, 13, 0, 0, 5, 11, 13, 0] },
|
||||
{ mcode: 38160, limited_ary: [], diffLv: [4, 5, 10, 13, 0, 0, 5, 11, 13, 0] },
|
||||
{ mcode: 38104, limited_ary: [], diffLv: [4, 6, 9, 12, 0, 0, 6, 10, 12, 0] },
|
||||
{ mcode: 38103, limited_ary: [], diffLv: [3, 7, 11, 15, 16, 0, 7, 11, 15, 17] },
|
||||
{ mcode: 38209, limited_ary: [], diffLv: [2, 3, 8, 11, 0, 0, 3, 8, 11, 0] },
|
||||
{ mcode: 38186, limited_ary: [], diffLv: [3, 5, 10, 14, 0, 0, 5, 10, 14, 0] },
|
||||
{ mcode: 38158, limited_ary: [], diffLv: [3, 6, 10, 13, 0, 0, 7, 11, 13, 0] },
|
||||
{ mcode: 38189, limited_ary: [], diffLv: [2, 4, 8, 12, 0, 0, 5, 9, 12, 0] },
|
||||
{ mcode: 38219, limited_ary: [], diffLv: [4, 10, 14, 17, 18, 0, 10, 14, 18, 18] },
|
||||
{ mcode: 38268, limited_ary: [], diffLv: [2, 5, 10, 13, 0, 0, 5, 10, 14, 0] },
|
||||
{ mcode: 38274, limited_ary: [], diffLv: [2, 3, 7, 11, 0, 0, 4, 7, 11, 0] },
|
||||
{ mcode: 38273, limited_ary: [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1], diffLv: [3, 5, 9, 12, 0, 0, 5, 9, 11, 0] },
|
||||
{ mcode: 38231, limited_ary: [], diffLv: [2, 5, 8, 11, 0, 0, 5, 8, 10, 0] },
|
||||
{ mcode: 38332, limited_ary: [], diffLv: [5, 8, 13, 16, 0, 0, 8, 13, 16, 0] },
|
||||
{ mcode: 38395, limited_ary: [], diffLv: [3, 6, 10, 14, 18, 0, 6, 10, 14, 18] },
|
||||
{ mcode: 38316, limited_ary: [], diffLv: [2, 6, 10, 14, 15, 0, 6, 10, 14, 14] },
|
||||
{ mcode: 38410, limited_ary: [], diffLv: [5, 10, 14, 17, 0, 0, 10, 14, 18, 0] },
|
||||
{ mcode: 38343, limited_ary: [], diffLv: [3, 7, 10, 14, 0, 0, 7, 10, 14, 0] },
|
||||
{ mcode: 38377, limited_ary: [], diffLv: [3, 7, 10, 15, 0, 0, 7, 10, 15, 0] },
|
||||
{ mcode: 38423, limited_ary: [], diffLv: [4, 9, 12, 16, 0, 0, 9, 12, 16, 0] },
|
||||
{ mcode: 38380, limited_ary: [], diffLv: [3, 5, 8, 11, 0, 0, 4, 8, 10, 0] },
|
||||
{ mcode: 38384, limited_ary: [], diffLv: [2, 4, 7, 10, 0, 0, 4, 7, 10, 0] },
|
||||
{ mcode: 38440, limited_ary: [], diffLv: [2, 4, 8, 12, 14, 0, 4, 8, 12, 14] },
|
||||
{ mcode: 38562, limited_ary: [], diffLv: [2, 5, 10, 13, 0, 0, 5, 11, 14, 0] },
|
||||
{ mcode: 38591, limited_ary: [], diffLv: [6, 10, 15, 18, 19, 0, 10, 15, 18, 19] },
|
||||
{ mcode: 37224, limited_ary: [], diffLv: [2, 6, 10, 15, 0, 0, 6, 11, 15, 0] },
|
||||
{ mcode: 38598, limited_ary: [], diffLv: [2, 7, 12, 17, 0, 0, 7, 12, 17, 0] },
|
||||
{ mcode: 38406, limited_ary: [], diffLv: [6, 11, 15, 17, 18, 0, 11, 15, 17, 18] },
|
||||
{ mcode: 38555, limited_ary: [], diffLv: [2, 4, 10, 14, 0, 0, 5, 10, 14, 0] },
|
||||
{ mcode: 38614, limited_ary: [], diffLv: [2, 5, 10, 14, 0, 0, 5, 10, 14, 0] },
|
||||
{ mcode: 38547, limited_ary: [], diffLv: [4, 9, 14, 17, 0, 0, 9, 15, 17, 0] },
|
||||
{ mcode: 38558, limited_ary: [], diffLv: [2, 5, 10, 14, 0, 0, 5, 10, 13, 0] },
|
||||
{ mcode: 37233, limited_ary: [], diffLv: [2, 5, 7, 11, 0, 0, 5, 8, 11, 0] },
|
||||
{ mcode: 38552, limited_ary: [], diffLv: [2, 8, 13, 16, 0, 0, 8, 13, 16, 0] },
|
||||
{ mcode: 37523, limited_ary: [], diffLv: [2, 6, 9, 12, 0, 0, 5, 9, 12, 0] },
|
||||
{ mcode: 38597, limited_ary: [], diffLv: [2, 7, 12, 18, 0, 0, 7, 12, 18, 0] },
|
||||
{ mcode: 38570, limited_ary: [], diffLv: [2, 3, 7, 13, 0, 0, 3, 7, 13, 0] },
|
||||
{ mcode: 37563, limited_ary: [], diffLv: [2, 5, 7, 11, 0, 0, 5, 7, 11, 0] },
|
||||
{ mcode: 37308, limited_ary: [], diffLv: [2, 5, 9, 13, 0, 0, 4, 9, 13, 0] },
|
||||
{ mcode: 38605, limited_ary: [], diffLv: [4, 7, 11, 15, 18, 0, 7, 11, 15, 17] },
|
||||
{ mcode: 38602, limited_ary: [], diffLv: [2, 4, 7, 11, 0, 0, 4, 7, 11, 0] },
|
||||
{ mcode: 37435, limited_ary: [], diffLv: [2, 6, 11, 14, 0, 0, 7, 12, 15, 0] },
|
||||
{ mcode: 38643, limited_ary: [], diffLv: [2, 5, 9, 13, 16, 0, 4, 9, 13, 16] },
|
||||
{ mcode: 38516, limited_ary: [], diffLv: [4, 8, 11, 14, 17, 0, 7, 11, 14, 17] },
|
||||
{ mcode: 38269, limited_ary: [0, 0, 0, 0, -1, -1, 0, 0, 0, -1], diffLv: [2, 5, 7, 10, 0, 0, 5, 7, 10, 0] },
|
||||
{ mcode: 38652, limited_ary: [0, 0, 0, 0, 0, -1, 0, 0, 0, 0], diffLv: [2, 6, 10, 15, 17, 0, 6, 10, 15, 17] },
|
||||
{ mcode: 37251, limited_ary: [0, 0, 0, 0, 0, -1, 0, 0, 0, 0], diffLv: [6, 10, 12, 15, 18, 0, 10, 11, 16, 17] },
|
||||
{ mcode: 38212, limited_ary: [0, 0, 0, 0, 2, -1, 0, 0, 0, 2], diffLv: [3, 7, 10, 15, 16, 0, 8, 11, 15, 16] },
|
||||
{ mcode: 38295, limited_ary: [0, 0, 0, 0, 2, -1, 0, 0, 0, 2], diffLv: [3, 7, 11, 14, 17, 0, 7, 11, 14, 17] },
|
||||
{ mcode: 38258, limited_ary: [0, 0, 0, 0, 2, -1, 0, 0, 0, 2], diffLv: [2, 6, 10, 14, 16, 0, 6, 11, 14, 16] },
|
||||
{ mcode: 38263, limited_ary: [0, 0, 0, 0, 2, -1, 0, 0, 0, 2], diffLv: [4, 7, 11, 14, 16, 0, 8, 12, 15, 16] },
|
||||
{ mcode: 38195, limited_ary: [0, 0, 0, 0, 2, -1, 0, 0, 0, 2], diffLv: [5, 7, 10, 13, 17, 0, 7, 10, 13, 17] },
|
||||
{ mcode: 38420, limited_ary: [0, 0, 0, 0, 2, -1, 0, 0, 0, 2], diffLv: [4, 8, 12, 15, 17, 0, 8, 12, 15, 17] },
|
||||
{ mcode: 38405, limited_ary: [0, 0, 0, 0, 2, -1, 0, 0, 0, 2], diffLv: [3, 6, 9, 13, 17, 0, 5, 9, 14, 17] },
|
||||
{ mcode: 38442, limited_ary: [0, 0, 0, 0, 2, -1, 0, 0, 0, 2], diffLv: [3, 8, 13, 16, 18, 0, 8, 13, 16, 18] },
|
||||
{ mcode: 38436, limited_ary: [0, 0, 0, 0, 2, -1, 0, 0, 0, 2], diffLv: [4, 7, 11, 14, 17, 0, 7, 11, 14, 17] },
|
||||
{ mcode: 38407, limited_ary: [0, 0, 0, 0, 0, -1, 0, 0, 0, 0], diffLv: [4, 9, 12, 16, 17, 0, 9, 12, 16, 17] },
|
||||
{ mcode: 38428, limited_ary: [0, 0, 0, 0, 0, -1, 0, 0, 0, 0], diffLv: [4, 8, 12, 16, 18, 0, 8, 12, 16, 18] },
|
||||
{ mcode: 38424, limited_ary: [0, 0, 0, 0, 0, -1, 0, 0, 0, 0], diffLv: [4, 8, 11, 14, 17, 0, 8, 11, 14, 17] }
|
||||
|
||||
// new charts
|
||||
// { mcode: 38339, limited_ary: [0, 0, 0, 0, 0, -1, 0, 0, 0, 0], diffLv: [3, 7, 11, 14, ?, 0, 7, 11, 14, ?] }, cbme
|
||||
]
|
||||
|
||||
export const EVENTS_WORLD = [
|
||||
{ id: 89, no: 0, cond: 0, rwrd: 0, type: 9999 },
|
||||
{ id: 96, no: 0, cond: 0, rwrd: 0, type: 9999 },
|
||||
{ id: 101, no: 0, cond: 0, rwrd: 0, type: 9999 },
|
||||
|
||||
{ id: 1, no: 1, cond: 1, rwrd: 38667, type: 70 }, { id: 2, no: 1, cond: 1, rwrd: 38667, type: 71 }, { id: 3, no: 1, cond: 1, rwrd: 38667, type: 72 }, { id: 4, no: 1, cond: 1, rwrd: 38667, type: 73 },
|
||||
{ id: 5, no: 1, cond: 1, rwrd: 38661, type: 70 }, { id: 6, no: 1, cond: 1, rwrd: 38661, type: 71 }, { id: 7, no: 1, cond: 1, rwrd: 38661, type: 72 }, { id: 8, no: 1, cond: 1, rwrd: 38661, type: 73 },
|
||||
{ id: 9, no: 1, cond: 1, rwrd: 38668, type: 70 }, { id: 10, no: 1, cond: 1, rwrd: 38668, type: 71 }, { id: 11, no: 1, cond: 1, rwrd: 38668, type: 72 }, { id: 12, no: 1, cond: 1, rwrd: 38668, type: 73 },
|
||||
{ id: 13, no: 1, cond: 1, rwrd: 38665, type: 70 }, { id: 14, no: 1, cond: 1, rwrd: 38665, type: 71 }, { id: 15, no: 1, cond: 1, rwrd: 38665, type: 72 }, { id: 16, no: 1, cond: 1, rwrd: 38665, type: 73 }, { id: 17, no: 1, cond: 1, rwrd: 38665, type: 74 },
|
||||
{ id: 18, no: 1, cond: 1, rwrd: 38669, type: 70 }, { id: 19, no: 1, cond: 1, rwrd: 38669, type: 71 }, { id: 20, no: 1, cond: 1, rwrd: 38669, type: 72 }, { id: 21, no: 1, cond: 1, rwrd: 38669, type: 73 }, { id: 22, no: 1, cond: 1, rwrd: 38669, type: 74 },
|
||||
{ id: 23, no: 1, cond: 1, rwrd: 38659, type: 70 }, { id: 24, no: 1, cond: 1, rwrd: 38659, type: 71 }, { id: 25, no: 1, cond: 1, rwrd: 38659, type: 72 }, { id: 26, no: 1, cond: 1, rwrd: 38659, type: 73 }, { id: 27, no: 1, cond: 1, rwrd: 38659, type: 74 },
|
||||
{ id: 28, no: 1, cond: 1, rwrd: 38667, type: 81 }, { id: 29, no: 1, cond: 1, rwrd: 38667, type: 82 }, { id: 30, no: 1, cond: 1, rwrd: 38667, type: 83 },
|
||||
{ id: 31, no: 1, cond: 1, rwrd: 38661, type: 81 }, { id: 32, no: 1, cond: 1, rwrd: 38661, type: 82 }, { id: 33, no: 1, cond: 1, rwrd: 38661, type: 83 },
|
||||
{ id: 34, no: 1, cond: 1, rwrd: 38668, type: 81 }, { id: 35, no: 1, cond: 1, rwrd: 38668, type: 82 }, { id: 36, no: 1, cond: 1, rwrd: 38668, type: 83 },
|
||||
{ id: 37, no: 1, cond: 1, rwrd: 38665, type: 81 }, { id: 38, no: 1, cond: 1, rwrd: 38665, type: 82 }, { id: 39, no: 1, cond: 1, rwrd: 38665, type: 83 }, { id: 40, no: 1, cond: 1, rwrd: 38665, type: 84 },
|
||||
{ id: 41, no: 1, cond: 1, rwrd: 38669, type: 81 }, { id: 42, no: 1, cond: 1, rwrd: 38669, type: 82 }, { id: 43, no: 1, cond: 1, rwrd: 38669, type: 83 }, { id: 44, no: 1, cond: 1, rwrd: 38669, type: 84 },
|
||||
{ id: 45, no: 1, cond: 1, rwrd: 38659, type: 81 }, { id: 46, no: 1, cond: 1, rwrd: 38659, type: 82 }, { id: 47, no: 1, cond: 1, rwrd: 38659, type: 83 }, { id: 48, no: 1, cond: 1, rwrd: 38659, type: 84 },
|
||||
{ id: 49, no: 0, cond: 2, rwrd: 38736, type: 27 }, { id: 50, no: 0, cond: 2, rwrd: 38735, type: 27 }, { id: 51, no: 0, cond: 2, rwrd: 38728, type: 27 },
|
||||
{ id: 52, no: 0, cond: 1, rwrd: 38624, type: 27 }, { id: 53, no: 0, cond: 1, rwrd: 38623, type: 27 }, { id: 54, no: 0, cond: 1, rwrd: 38628, type: 27 },
|
||||
{ id: 55, no: 0, cond: 1, rwrd: 38736, type: 25 }, { id: 56, no: 1, cond: 1, rwrd: 38736, type: 25 }, { id: 57, no: 2, cond: 1, rwrd: 38736, type: 25 }, { id: 58, no: 3, cond: 1, rwrd: 38736, type: 25 },
|
||||
{ id: 59, no: 0, cond: 1, rwrd: 38735, type: 25 }, { id: 60, no: 1, cond: 1, rwrd: 38735, type: 25 }, { id: 61, no: 2, cond: 1, rwrd: 38735, type: 25 }, { id: 62, no: 3, cond: 1, rwrd: 38735, type: 25 },
|
||||
{ id: 63, no: 0, cond: 1, rwrd: 38728, type: 25 }, { id: 64, no: 1, cond: 1, rwrd: 38728, type: 25 }, { id: 65, no: 2, cond: 1, rwrd: 38728, type: 25 }, { id: 66, no: 3, cond: 1, rwrd: 38728, type: 25 },
|
||||
{ id: 67, no: 0, cond: 1, rwrd: 38624, type: 25 }, { id: 68, no: 1, cond: 1, rwrd: 38624, type: 25 }, { id: 69, no: 2, cond: 1, rwrd: 38624, type: 25 }, { id: 70, no: 3, cond: 1, rwrd: 38624, type: 25 }, { id: 71, no: 4, cond: 1, rwrd: 38624, type: 25, dep: [67, 68, 69, 70, 72, 73, 74, 75, 77, 78, 79, 80] },
|
||||
{ id: 72, no: 0, cond: 1, rwrd: 38623, type: 25 }, { id: 73, no: 1, cond: 1, rwrd: 38623, type: 25 }, { id: 74, no: 2, cond: 1, rwrd: 38623, type: 25 }, { id: 75, no: 3, cond: 1, rwrd: 38623, type: 25 }, { id: 76, no: 4, cond: 1, rwrd: 38623, type: 25, dep: [67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 78, 79, 80] },
|
||||
{ id: 77, no: 0, cond: 1, rwrd: 38628, type: 25 }, { id: 78, no: 1, cond: 1, rwrd: 38628, type: 25 }, { id: 79, no: 2, cond: 1, rwrd: 38628, type: 25 }, { id: 80, no: 3, cond: 1, rwrd: 38628, type: 25 },
|
||||
{ id: 81, no: 0, cond: 1, rwrd: 1185, type: 201, save: 1, dep: [67, 68, 69, 70, 72, 73, 74, 75, 77, 78, 79, 80] },
|
||||
{ id: 82, no: 0, cond: 1, rwrd: 1186, type: 201, save: 1, dep: [67, 68, 69, 70, 71, 72, 73, 74, 75, 77, 78, 79, 80] },
|
||||
{ id: 83, no: 0, cond: 1, rwrd: 38746, type: 17, comp: 0, save: 1 },
|
||||
{ id: 84, no: 0, cond: 1, rwrd: 38745, type: 17, comp: 0, save: 1 },
|
||||
{ id: 85, no: 0, cond: 1, rwrd: 38744, type: 17, comp: 0, save: 1 },
|
||||
{ id: 86, no: 0, cond: 1, rwrd: 38747, type: 17, comp: 0, save: 1 },
|
||||
{ id: 87, no: 0, cond: 1, rwrd: 38748, type: 17, comp: 0, save: 1 },
|
||||
{ id: 88, no: 0, cond: 1, rwrd: 1189, type: 201, save: 1 },
|
||||
{ id: 89, no: 0, cond: 1, rwrd: 1188, type: 201, save: 1 },
|
||||
{ id: 90, no: 0, cond: 1, rwrd: 38737, type: 50 },
|
||||
{ id: 91, no: 0, cond: 1, rwrd: 38737, type: 52 },
|
||||
{ id: 92, no: 0, cond: 1, rwrd: 38738, type: 50 },
|
||||
{ id: 93, no: 0, cond: 1, rwrd: 38738, type: 52 },
|
||||
{ id: 94, no: 0, cond: 1, rwrd: 38212, type: 52 },
|
||||
{ id: 95, no: 0, cond: 1, rwrd: 38295, type: 52 },
|
||||
{ id: 96, no: 0, cond: 1, rwrd: 38258, type: 52 },
|
||||
{ id: 97, no: 0, cond: 1, rwrd: 38263, type: 52 },
|
||||
{ id: 98, no: 0, cond: 1, rwrd: 38195, type: 52 },
|
||||
{ id: 99, no: 0, cond: 1, rwrd: 38739, type: 52 },
|
||||
{ id: 100, no: 0, cond: 1, rwrd: 38420, type: 52 },
|
||||
{ id: 101, no: 0, cond: 1, rwrd: 38405, type: 52 },
|
||||
{ id: 102, no: 0, cond: 1, rwrd: 38442, type: 52 },
|
||||
{ id: 103, no: 0, cond: 1, rwrd: 37222, type: 50 },
|
||||
{ id: 104, no: 0, cond: 1, rwrd: 37604, type: 50 },
|
||||
{ id: 105, no: 0, cond: 1, rwrd: 37604, type: 52 },
|
||||
{ id: 106, no: 0, cond: 1, rwrd: 37234, type: 50 },
|
||||
{ id: 107, no: 0, cond: 1, rwrd: 37363, type: 50 },
|
||||
{ id: 108, no: 0, cond: 1, rwrd: 38436, type: 52 },
|
||||
{ id: 109, no: 0, cond: 1, rwrd: 1197, type: 201, save: 1 },
|
||||
{ id: 110, no: 0, cond: 1, rwrd: 38759, type: 43, comp: 0, save: 1 },
|
||||
{ id: 111, no: 0, cond: 1, rwrd: 38758, type: 43, comp: 0, save: 1 },
|
||||
{ id: 112, no: 0, cond: 1, rwrd: 38756, type: 43, comp: 0, save: 1 },
|
||||
{ id: 113, no: 0, cond: 1, rwrd: 1201, type: 201, save: 1 },
|
||||
{ id: 114, no: 0, cond: 1, rwrd: 38760, type: 50 },
|
||||
{ id: 115, no: 0, cond: 1, rwrd: 38760, type: 52 },
|
||||
{ id: 116, no: 0, cond: 1, rwrd: 38761, type: 50 },
|
||||
{ id: 117, no: 0, cond: 1, rwrd: 38428, type: 52 },
|
||||
{ id: 118, no: 0, cond: 1, rwrd: 38424, type: 52 }
|
||||
]
|
||||
|
||||
export const LEAGUE_WORLD = [
|
||||
{
|
||||
id: 1,
|
||||
name: "第1回 WORLD LEAGUE",
|
||||
name_eng: "The 1st WORLD LEAGUE",
|
||||
start: BigInt(Date.parse('8 Oct 2024 01:00:00 GMT')),
|
||||
end: BigInt(Date.parse('6 Nov 2024 08:00:00 GMT')),
|
||||
summary: BigInt(Date.parse('6 Nov 2024 09:00:00 GMT')),
|
||||
advanceBorder: [0, 0, 0]
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "第2回 WORLD LEAGUE",
|
||||
name_eng: "The 2nd WORLD LEAGUE",
|
||||
start: BigInt(Date.parse('14 Nov 2024 01:00:00 GMT')),
|
||||
end: BigInt(Date.parse('11 Dec 2024 08:00:00 GMT')),
|
||||
summary: BigInt(Date.parse('11 Dec 2024 09:00:00 GMT')),
|
||||
advanceBorder: [0, 0, 0]
|
||||
}
|
||||
]
|
||||
|
||||
export const LOCKED_SONGS = [
|
||||
{
|
||||
unlock_date: BigInt(Date.parse("1 Jul 2024 01:00:00 GMT")),
|
||||
ids: [38583],
|
||||
ids_cha: []
|
||||
},
|
||||
{
|
||||
unlock_date: BigInt(Date.parse("31 Jul 2024 01:00:00 GMT")),
|
||||
ids: [38591, 38593, 38597, 38592, 38598, 38595, 38596, 38594, 38599],
|
||||
ids_cha: [38591]
|
||||
},
|
||||
{
|
||||
unlock_date: BigInt(Date.parse("30 Aug 2024 01:00:00 GMT")),
|
||||
ids: [],
|
||||
ids_cha: [38625, 38626, 38627]
|
||||
},
|
||||
{
|
||||
unlock_date: BigInt(Date.parse("29 Nov 2024 01:00:00 GMT")),
|
||||
ids: [38632, 38618, 38619, 38637, 38639, 38638],
|
||||
ids_cha: [38102, 38517]
|
||||
},
|
||||
{
|
||||
unlock_date: BigInt(Date.parse("27 Dec 2024 01:00:00 GMT")),
|
||||
ids: [38644, 38647, 38645, 38651, 38648, 38650, 38646, 38649],
|
||||
ids_cha: [38138, 38017]
|
||||
}
|
||||
];
|
||||
@@ -1,549 +1,18 @@
|
||||
import { EVENT4, COURSES4, EXTENDS4 } from '../data/hvn';
|
||||
import { EVENT5, COURSES5, EXTENDS5 } from '../data/vvw';
|
||||
import { EVENT6, COURSES6, EXTENDS6, APRILFOOLSSONGS, VALKYRIE_SONGS,
|
||||
LICENSED_SONGS6, ARENA, VALGENE, INFORMATION6, STAMP_EVENTS6,
|
||||
REMOVED_SONGS6
|
||||
} from '../data/exg';
|
||||
import { COURSE2 } from '../data/inf';
|
||||
import {getVersion, getRandomIntInclusive} from '../utils';
|
||||
|
||||
export const common: EPR = async (info, data, send) => {
|
||||
try {
|
||||
let music_db = await IO.ReadFile('webui/asset/json/music_db.json')
|
||||
let events = [];
|
||||
let courses = [];
|
||||
let extend = [];
|
||||
let date = new Date();
|
||||
let currentYMDDate = parseInt([date.getFullYear(), ((date.getMonth() + 1) > 9 ? '' : '0') + (date.getMonth() + 1), (date.getDate() > 9 ? '' : '0') + date.getDate()].join(''));
|
||||
let currentDate = date.toLocaleDateString()
|
||||
console.log('====================================')
|
||||
console.log("Calling common function");
|
||||
|
||||
const version = parseInt(info.model.split(":")[4]);
|
||||
|
||||
if (version <= 2013052900) {
|
||||
console.log('Game: Booth')
|
||||
return send.pugFile('templates/booth/common.pug');
|
||||
}
|
||||
|
||||
if (version <= 2014112000) {
|
||||
console.log('Game: Infinite Infection')
|
||||
courses = COURSE2;
|
||||
return send.pugFile('templates/infiniteinfection/common.pug',{
|
||||
courses,
|
||||
});
|
||||
}
|
||||
|
||||
switch (info.method) {
|
||||
case 'sv4_common': {
|
||||
console.log('Game: Heavenly Haven')
|
||||
events = EVENT4;
|
||||
courses = COURSES4;
|
||||
//extend = EXTENDS4;
|
||||
EXTENDS4.forEach(val => extend.push(Object.assign({}, val)));
|
||||
break;
|
||||
}
|
||||
case 'sv5_common': {
|
||||
console.log('Game: Vivid Wave')
|
||||
events = EVENT5;
|
||||
courses = COURSES5;
|
||||
//extend = EXTENDS5;
|
||||
EXTENDS5.forEach(val => extend.push(Object.assign({}, val)));
|
||||
break;
|
||||
}
|
||||
case 'sv6_common': {
|
||||
console.log('Game: Exceed Gear')
|
||||
//events = EVENT6;
|
||||
EVENT6.forEach(val => events.push(val));
|
||||
if(IO.Exists('webui/asset/config/flags.json')) {
|
||||
let bufFlagConfig = await IO.ReadFile('webui/asset/config/flags.json')
|
||||
let flagConfig = JSON.parse(bufFlagConfig.toString())
|
||||
for(const flagIter in flagConfig) {
|
||||
if(flagConfig[flagIter]['toggle']) events.push(flagConfig[flagIter]['str'])
|
||||
}
|
||||
}
|
||||
courses = COURSES6;
|
||||
EXTENDS6.forEach(val => extend.push(Object.assign({}, val)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
let songs = [];
|
||||
const gameVersion = getVersion(info);
|
||||
let songNum = 2200;
|
||||
if(gameVersion === 2) songNum = 554;
|
||||
if(gameVersion === 3) songNum = 954;
|
||||
if(gameVersion === 4) songNum = 1368;
|
||||
|
||||
if(U.GetConfig('unlock_all_songs')) {
|
||||
console.log("Unlocking songs");
|
||||
for (let i = 1; i < songNum; ++i) {
|
||||
for (let j = 0; j < 5; ++j) {
|
||||
songs.push({
|
||||
music_id: K.ITEM('s32', i),
|
||||
music_type: K.ITEM('u8', j),
|
||||
limited: K.ITEM('u8', 3),
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let mdb = JSON.parse(music_db.toString());
|
||||
|
||||
let limitedNo = 2;
|
||||
songNum = parseInt(mdb.mdb.music[mdb.mdb.music.length - 1]['@id'])
|
||||
console.log("Latest song id in mdb: " + songNum)
|
||||
for (let i = 0; i <= songNum; i++) {
|
||||
var foundSongIndex = mdb.mdb.music.map(function(x) {return x['@id']; }).indexOf(i.toString());
|
||||
if(foundSongIndex != -1) {
|
||||
var songData = mdb.mdb.music[foundSongIndex];
|
||||
if(gameVersion === 6 || gameVersion === -6) {
|
||||
if(parseInt(songData['info']['distribution_date']['#text']) > currentYMDDate) {
|
||||
console.log("Unreleased song: " + songData.info.title_name)
|
||||
}
|
||||
else {
|
||||
limitedNo = 2;
|
||||
// if song is released during exceed gear
|
||||
if(songData.info.version['#text'] === '6') {
|
||||
// Songs are removed for multiple reasons, this will check whether to show or hide them (for songs released during EG)
|
||||
if(REMOVED_SONGS6.includes(i.toString()) && !U.GetConfig('enable_removed_songs')) {
|
||||
limitedNo -= 1;
|
||||
}
|
||||
// Licensed songs released in Exceed Gear needs limited=3 to appear
|
||||
if(LICENSED_SONGS6.includes(i.toString())) {
|
||||
limitedNo += 1;
|
||||
}
|
||||
else if(VALKYRIE_SONGS.includes(i.toString()) && (!U.GetConfig('enable_valk_songs') && info.model.split(":")[2].match(/^(G|H)$/g) == null)){
|
||||
limitedNo -= 1;
|
||||
}
|
||||
for(let j = 0; j < 5; j++) {
|
||||
songs.push({
|
||||
music_id: K.ITEM('s32', i),
|
||||
music_type: K.ITEM('u8', j),
|
||||
limited: K.ITEM('u8', limitedNo),
|
||||
});
|
||||
}
|
||||
}
|
||||
// if song has new XCD track
|
||||
else if (songData.info.inf_ver['#text'] === '6') {
|
||||
songs.push({
|
||||
music_id: K.ITEM('s32', i),
|
||||
music_type: K.ITEM('u8', 3),
|
||||
limited: K.ITEM('u8', limitedNo),
|
||||
});
|
||||
}
|
||||
// Songs are removed for multiple reasons, this will check whether to show or hide them (for songs released before EG)
|
||||
else if(REMOVED_SONGS6.includes(i.toString()) && !U.GetConfig('enable_removed_songs')) {
|
||||
for(let j = 0; j < 5; j++) {
|
||||
songs.push({
|
||||
music_id: K.ITEM('s32', i),
|
||||
music_type: K.ITEM('u8', j),
|
||||
limited: K.ITEM('u8', 2),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(U.GetConfig('use_information')){
|
||||
console.log("Sending server information");
|
||||
let time = new Date();
|
||||
let tempDate = time.getDate();
|
||||
const currentTime = parseInt((time.getTime()/100000) as unknown as string)*100;
|
||||
extend.push({
|
||||
id: 1,
|
||||
type: 1,
|
||||
params: [
|
||||
1,
|
||||
currentTime,
|
||||
1,
|
||||
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]',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
],
|
||||
});
|
||||
}
|
||||
else if(INFORMATION6[version.toString()] != undefined) {
|
||||
console.log("Sending server information");
|
||||
let time = new Date();
|
||||
let tempDate = time.getDate();
|
||||
const currentTime = parseInt((time.getTime()/100000) as unknown as string)*100;
|
||||
for(const keyIter in INFORMATION6[version.toString()]) {
|
||||
extend.push({
|
||||
id: parseInt(keyIter) + 1,
|
||||
type: 1,
|
||||
params: [
|
||||
1,
|
||||
currentTime,
|
||||
0,
|
||||
0,
|
||||
31,
|
||||
'[f:0]SERVER INFORMATION',
|
||||
INFORMATION6[version.toString()][keyIter],
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(IO.Exists('webui/asset/config/events.json')) {
|
||||
const itemTypeList = {"track": 'e', "appeal": 'a', "crew": 'c', "pcb": 'b', "prereq": "r"}
|
||||
let bufEventData = await IO.ReadFile('webui/asset/json/events.json')
|
||||
let bufEventConfig = await IO.ReadFile('webui/asset/config/events.json')
|
||||
let eventData = JSON.parse(bufEventData.toString())
|
||||
let eventConfig = JSON.parse(bufEventConfig.toString())
|
||||
for(const eventIter in eventData['events']) {
|
||||
let stmpEvntInfo = STAMP_EVENTS6[eventData['events'][eventIter]['id']]
|
||||
if(eventData['events'][eventIter]['type'] === 'stamp' && eventConfig[eventData['events'][eventIter]['id']] !== undefined && eventConfig[eventData['events'][eventIter]['id']]['toggle']) {
|
||||
for(const stmpDataIter in stmpEvntInfo['info']['data']) {
|
||||
extend.push({
|
||||
'type': 3,
|
||||
'id': stmpEvntInfo['info']['data'][stmpDataIter]['stmpid'],
|
||||
'params': [
|
||||
5,
|
||||
stmpEvntInfo['info']['data'][stmpDataIter]['stps'],
|
||||
0,
|
||||
stmpEvntInfo['info']['data'][stmpDataIter]['stps'],
|
||||
0,
|
||||
'',
|
||||
stmpEvntInfo['info']['stmpHd'],
|
||||
'',
|
||||
stmpEvntInfo['info']['stmpFt'],
|
||||
stmpEvntInfo['info']['data'][stmpDataIter]['stprwrd']
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
if(stmpEvntInfo['type'] === 'select') {
|
||||
extend.push({
|
||||
'type': 3,
|
||||
'id': stmpEvntInfo['info']['id'],
|
||||
'params': [
|
||||
9,
|
||||
(stmpEvntInfo['info']['textstampval'] !== undefined) ? stmpEvntInfo['info']['textstampval'] : 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
stmpEvntInfo['info']['sheet'],
|
||||
'',
|
||||
stmpEvntInfo['info']['stmpSlHd'],
|
||||
stmpEvntInfo['info']['stmpSlFt'],
|
||||
stmpEvntInfo['info']['stmpBg']
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
else if(eventData['events'][eventIter]['type'] === 'completestamp' && eventConfig[eventData['events'][eventIter]['id']] !== undefined && eventConfig[eventData['events'][eventIter]['id']]['toggle']) {
|
||||
extend.push({
|
||||
'type': 19,
|
||||
'id': stmpEvntInfo['info']['id'],
|
||||
'params': [
|
||||
0, 0, 0, 0, 0,
|
||||
JSON.stringify(stmpEvntInfo['info']['data']),
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
''
|
||||
]
|
||||
})
|
||||
}
|
||||
else if(eventData['events'][eventIter]['type'] === 'tama' && eventConfig[eventData['events'][eventIter]['id']] !== undefined && eventConfig[eventData['events'][eventIter]['id']]['toggle']) {
|
||||
events.push('TAMAADV_ENABLE')
|
||||
extend.push({
|
||||
'type': 20,
|
||||
'id': stmpEvntInfo['info']['id'],
|
||||
'params': [
|
||||
0, 0, 0, 0, 0,
|
||||
(U.GetConfig('tama_track_lib') ? '0,' : '') + stmpEvntInfo['info']['list'],
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
''
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(IO.Exists('handlers/test.json')) {
|
||||
let bufTest = await IO.ReadFile('handlers/test.json')
|
||||
let extendTest = JSON.parse(bufTest.toString())
|
||||
for(const ex in extendTest) {
|
||||
extend.push({
|
||||
'type': extendTest[ex]['type'],
|
||||
'id': extendTest[ex]['id'],
|
||||
'params': extendTest[ex]['params']
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if(U.GetConfig('use_asphyxia_gameover')){
|
||||
let time = new Date();
|
||||
let tempDate = time.getDate();
|
||||
const currentTime = parseInt((time.getTime()/100000) as unknown as string)*100;
|
||||
let rightCharater = [
|
||||
"go_bansui","go_bof","go_cannon","go_chinema","go_chocopla",
|
||||
"go_dd","go_ekusa","go_esp","go_flowry","go_fukuryu",
|
||||
"go_gorilla","go_grace","go_grace_rori","go_grace_ver06","go_haelequin",
|
||||
"go_haruka","go_joyeuse","go_kino","go_kisa","go_mai",
|
||||
"go_makina","go_makishima","go_left","go_makishima_ver06","go_mitsuru","go_miyako",
|
||||
"go_nana","go_natsuhi","go_noisia","go_left_ver06","go_ondine","go_pannakotta",
|
||||
"go_psychoholic","go_rain","go_rain02","go_ribbon","go_right",
|
||||
"go_riot","go_rishna","go_rouge","go_sakurako","go_satan",
|
||||
"go_tama","go_torako","go_vela","go_vertex","go_wabutan",
|
||||
"go_wanlove","go_yusya",
|
||||
];
|
||||
let leftCharater = [
|
||||
"go_akane","go_apex4sis","go_candy","go_capsaicin","go_chikage",
|
||||
"go_evileye","go_fluorine","go_gangara","go_gin","go_hero",
|
||||
"go_hiryubiren","go_hiyuki","go_hotaru","go_inoten","go_kamito",
|
||||
"go_kanade","go_kemuri","go_kokona","go_konoha","go_kouki",
|
||||
"go_kureha","go_left_bag","go_madholic",
|
||||
"go_mimiko","go_mion","go_mitsuruco","go_nathanael","go_nishinippori",
|
||||
"go_ortlinde","go_pico","go_pilica","go_profession","go_rasis",
|
||||
"go_rasis_ver06","go_right_ver06","go_rimuru","go_rowa","go_saigawara",
|
||||
"go_setu","go_shelly","go_soul","go_tamaneko","go_toraipuru",
|
||||
"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 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)];
|
||||
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)];
|
||||
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)];
|
||||
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)];
|
||||
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
|
||||
extend.push({
|
||||
id: 3,
|
||||
type: 1,
|
||||
params: [
|
||||
3,
|
||||
currentTime,
|
||||
0,
|
||||
60,
|
||||
0,
|
||||
'[GAMEOVER]',
|
||||
'[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,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
console.log("Sending common objects");
|
||||
|
||||
let arena_szn = U.GetConfig('arena_szn')
|
||||
let arena_catalog_items = []
|
||||
|
||||
if(arena_szn !== 'None') {
|
||||
arena_catalog_items = ARENA[arena_szn].arena_items.map(item => ({
|
||||
catalog_id: K.ITEM('s32', item.catalog_id),
|
||||
catalog_type: K.ITEM('s32', item.catalog_type),
|
||||
price: K.ITEM('s32', item.price),
|
||||
item_type: K.ITEM('s32', item.item_type),
|
||||
item_id: K.ITEM('s32', item.item_id),
|
||||
param: K.ITEM('s32', item.param),
|
||||
}))
|
||||
}
|
||||
|
||||
let valgene_info = []
|
||||
let valgene_items = []
|
||||
|
||||
valgene_info = VALGENE.info.map(val => ({
|
||||
valgene_name: K.ITEM('str', val.valgene_name),
|
||||
valgene_name_english: K.ITEM('str', val.valgene_name_english),
|
||||
valgene_id: K.ITEM('s32', val.valgene_id)
|
||||
}))
|
||||
|
||||
VALGENE.catalog.forEach((val) => {
|
||||
val.items.forEach((itemVal) => {
|
||||
itemVal.item_ids.forEach((item_id) => {
|
||||
valgene_items.push({
|
||||
valgene_id: K.ITEM('s32', val.volume),
|
||||
rarity: K.ITEM('s32', VALGENE.rarity[itemVal.type.toString()]),
|
||||
item_type: K.ITEM('s32', itemVal.type),
|
||||
item_id: K.ITEM('s32', item_id)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
if(currentDate.substring(0,4) === '4/1/' || U.GetConfig('april_fools')) {
|
||||
console.log('Using April Fools Event')
|
||||
events.push('APRIL_GRACE');
|
||||
events.push('EVENTDATE_APRILFOOL');
|
||||
for (const afsong in APRILFOOLSSONGS) {
|
||||
for (let j = 0; j < 5; ++j) {
|
||||
songs.push({
|
||||
music_id: K.ITEM('s32', parseInt(APRILFOOLSSONGS[afsong])),
|
||||
music_type: K.ITEM('u8', j),
|
||||
limited: K.ITEM('u8', 3),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
send.object(
|
||||
{
|
||||
valgene: {
|
||||
info: valgene_info,
|
||||
catalog: valgene_items
|
||||
},
|
||||
arena: (arena_szn !== 'None') ? {
|
||||
season: K.ITEM('s32', ARENA[arena_szn].details.season),
|
||||
rule: K.ITEM('s32', ARENA[arena_szn].details.rule),
|
||||
rank_match_target: K.ITEM('s32', ARENA[arena_szn].details.rank_match_target),
|
||||
time_start: K.ITEM('u64', ARENA[arena_szn].details.time_start),
|
||||
time_end: K.ITEM('u64', ARENA[arena_szn].details.time_end),
|
||||
shop_start: K.ITEM('u64', ARENA[arena_szn].details.shop_start),
|
||||
shop_end: K.ITEM('u64', ARENA[arena_szn].details.shop_end),
|
||||
is_open: K.ITEM('bool', ARENA[arena_szn].details.is_open),
|
||||
is_shop: K.ITEM('bool', ARENA[arena_szn].details.is_shop),
|
||||
catalog: arena_catalog_items
|
||||
} : {},
|
||||
event: {
|
||||
info: events.map(e => ({
|
||||
event_id: K.ITEM('str', e),
|
||||
})),
|
||||
},
|
||||
extend: {
|
||||
info: extend.map(e => ({
|
||||
extend_id: K.ITEM('u32', e.id),
|
||||
extend_type: K.ITEM('u32', e.type),
|
||||
param_num_1: K.ITEM('s32', e.params[0]),
|
||||
param_num_2: K.ITEM('s32', e.params[1]),
|
||||
param_num_3: K.ITEM('s32', e.params[2]),
|
||||
param_num_4: K.ITEM('s32', e.params[3]),
|
||||
param_num_5: K.ITEM('s32', e.params[4]),
|
||||
param_str_1: K.ITEM('str', e.params[5]),
|
||||
param_str_2: K.ITEM('str', e.params[6]),
|
||||
param_str_3: K.ITEM('str', e.params[7]),
|
||||
param_str_4: K.ITEM('str', e.params[8]),
|
||||
param_str_5: K.ITEM('str', e.params[9]),
|
||||
})),
|
||||
},
|
||||
music_limited: { info: songs },
|
||||
skill_course: {
|
||||
info: courses.reduce(
|
||||
(acc, s) => {
|
||||
let courseData = 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', c.type),
|
||||
course_id: K.ITEM('s16', c.id),
|
||||
course_name: K.ITEM('str', c.name),
|
||||
skill_level: K.ITEM('s16', c.level),
|
||||
skill_type: K.ITEM('s16', 0),
|
||||
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),
|
||||
})),
|
||||
}))
|
||||
acc = acc.concat(courseData)
|
||||
if((info.model.split(":")[2] === 'G' || info.model.split(":")[2] === 'H') && s.hasGod !== undefined && s.hasGod === 1) {
|
||||
courseData = courseData.concat(
|
||||
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', c.type),
|
||||
course_id: K.ITEM('s16', c.id),
|
||||
course_name: K.ITEM('str', c.name),
|
||||
skill_level: K.ITEM('s16', c.level),
|
||||
skill_type: K.ITEM('s16', s.hasGod),
|
||||
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),
|
||||
})),
|
||||
}))
|
||||
)
|
||||
acc = acc.concat(courseData)
|
||||
}
|
||||
return acc
|
||||
},
|
||||
[]
|
||||
),
|
||||
},
|
||||
},
|
||||
{ encoding: 'utf8' }
|
||||
);
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
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 log: EPR = async (info, data, send) => {
|
||||
send.success();
|
||||
}
|
||||
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])
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -0,0 +1,907 @@
|
||||
import { Profile } from "../models/profile";
|
||||
import { ProfileWorld, ScoreWorld, EventWorld, GhostWorld, RivalWorld, HiScoreWorld, LeagueWorld, CustomizeWorld } from "../models/ddrworld";
|
||||
import { SONGS_WORLD, SONGS_OVERRIDE_WORLD, EVENTS_WORLD, LEAGUE_WORLD, LOCKED_SONGS } from "../data/world";
|
||||
|
||||
function getLastGhostId(ghost: any) {
|
||||
let ghostFiltered = ghost.filter(a => (a.ghostId !== undefined))
|
||||
if(ghostFiltered.length > 0) return ghostFiltered.sort((a, b) => b.ghostId - a.ghostId)[0].ghostId
|
||||
else return 0
|
||||
}
|
||||
|
||||
async function saveScores(refid: string, hiScoreInfo: any, songId: number, style: number, difficulty: number, rank: number, clearKind: number, score: number, exScore: number, maxCombo: number, flareForce: number, ghostSize: number, ghost: string) {
|
||||
let stepScore = await DB.FindOne<ScoreWorld>(refid, {collection: "score3", songId: songId, style: style, difficulty: difficulty})
|
||||
let ghostData = await DB.Find<GhostWorld>(null, {collection: "ghost3"})
|
||||
let lastGhostId = getLastGhostId(ghostData)
|
||||
let hiScoreCheck = score
|
||||
let ghostId = 0
|
||||
if(lastGhostId === 0) {
|
||||
ghostId = 1
|
||||
} else ghostId = lastGhostId += 1
|
||||
/*
|
||||
Ghost data gets created when there is no existing data and it gets updated when getting a higher or the same score
|
||||
Side effect of this is when you have set a high score prior to this update, the ghost data wouldn't be updated unless you break or match that high score.
|
||||
Unfortunately I could not find a way to match the old scores to their respective ghost data, since the old ghost data only stored the song id and difficulty, and not the style (single/double.) Stupid me.
|
||||
Still needs more work.
|
||||
*/
|
||||
if(stepScore) {
|
||||
ghostId = (stepScore.ghostId) ? stepScore.ghostId : ghostId
|
||||
let stepGhost = await DB.FindOne<GhostWorld>(null, {collection: "ghost3", ghostId: ghostId })
|
||||
|
||||
if(stepGhost) {
|
||||
ghostSize = (score >= stepScore.score) ? ghostSize : stepGhost.ghostSize
|
||||
ghost = (score >= stepScore.score) ? ghost : stepGhost.ghost
|
||||
}
|
||||
|
||||
rank = (rank < stepScore.rank) ? rank : stepScore.rank;
|
||||
clearKind = (clearKind != 6 && clearKind > stepScore.clearKind) ? clearKind : stepScore.clearKind;
|
||||
score = (score > stepScore.score) ? score : stepScore.score;
|
||||
exScore = (exScore > stepScore.exScore) ? exScore : stepScore.exScore;
|
||||
maxCombo = (maxCombo > stepScore.maxCombo) ? maxCombo : stepScore.maxCombo;
|
||||
flareForce = (flareForce > stepScore.flareForce) ? flareForce : stepScore.flareForce;
|
||||
|
||||
}
|
||||
|
||||
await DB.Upsert<ScoreWorld>(refid, {
|
||||
collection: "score3",
|
||||
songId,
|
||||
style,
|
||||
difficulty
|
||||
}, {
|
||||
$set: {
|
||||
ghostId,
|
||||
rank,
|
||||
clearKind,
|
||||
score,
|
||||
exScore,
|
||||
maxCombo,
|
||||
flareForce
|
||||
}
|
||||
});
|
||||
|
||||
await DB.Upsert<GhostWorld>(refid, {
|
||||
collection: "ghost3",
|
||||
ghostId,
|
||||
}, {
|
||||
$set: {
|
||||
ghostSize,
|
||||
ghost
|
||||
}
|
||||
});
|
||||
|
||||
let slot = 0
|
||||
let country = hiScoreInfo.country
|
||||
let region = hiScoreInfo.region
|
||||
let customerCode = hiScoreInfo.customerCode
|
||||
let companyCode = hiScoreInfo.companyCode
|
||||
let locationId = hiScoreInfo.locationId
|
||||
let pcbid = hiScoreInfo.pcbid
|
||||
let dancerName = hiScoreInfo.dancerName
|
||||
|
||||
let worldBreak = false
|
||||
let areaBreak = false
|
||||
let machineBreak = false
|
||||
|
||||
// Hiscore stuff
|
||||
let hiScoreWorld1 = await DB.FindOne<HiScoreWorld>(null, {collection: 'hiscore3', slot: 1, songId: songId, style: style, difficulty: difficulty})
|
||||
ghostData = await DB.Find<GhostWorld>(null, {collection: "ghost3"})
|
||||
lastGhostId = getLastGhostId(ghostData)
|
||||
ghostId = 0
|
||||
if(lastGhostId === 0) ghostId = 1
|
||||
else ghostId = lastGhostId += 1
|
||||
|
||||
if(hiScoreWorld1) {
|
||||
if(hiScoreCheck >= hiScoreWorld1.score) {
|
||||
worldBreak = true
|
||||
ghostId = (hiScoreWorld1.ghostId) ? hiScoreWorld1.ghostId : ghostId
|
||||
await DB.Upsert<GhostWorld>(refid, {collection: "ghost3", ghostId }, {$set: { ghostSize, ghost }});
|
||||
}
|
||||
} else {
|
||||
worldBreak = true
|
||||
await DB.Upsert<GhostWorld>(refid, {collection: "ghost3", ghostId }, {$set: { ghostSize, ghost }});
|
||||
}
|
||||
slot = 1
|
||||
if(worldBreak) {
|
||||
await DB.Upsert<HiScoreWorld>(refid, {collection: "hiscore3", slot, songId, style, difficulty}, { $set: { country, region, customerCode, companyCode, locationId, pcbid, dancerName, score: hiScoreCheck, ghostId }});
|
||||
}
|
||||
|
||||
let hiScoreArea1 = await DB.FindOne<HiScoreWorld>(null, {collection: 'hiscore3', slot: 2, locationId: locationId, songId: songId, style: style, difficulty: difficulty})
|
||||
ghostData = await DB.Find<GhostWorld>(null, {collection: "ghost3"})
|
||||
lastGhostId = getLastGhostId(ghostData)
|
||||
ghostId = 0
|
||||
if(lastGhostId === 0) ghostId = 1
|
||||
else ghostId = lastGhostId += 1
|
||||
|
||||
if(hiScoreArea1) {
|
||||
if(hiScoreCheck >= hiScoreArea1.score) {
|
||||
areaBreak = true
|
||||
ghostId = (hiScoreArea1.ghostId) ? hiScoreArea1.ghostId : ghostId
|
||||
await DB.Upsert<GhostWorld>(refid, {collection: "ghost3", ghostId }, {$set: { ghostSize, ghost }});
|
||||
}
|
||||
} else {
|
||||
areaBreak = true
|
||||
await DB.Upsert<GhostWorld>(refid, {collection: "ghost3", ghostId }, {$set: { ghostSize, ghost }});
|
||||
}
|
||||
slot = 2
|
||||
if(areaBreak) {
|
||||
await DB.Upsert<HiScoreWorld>(refid, {collection: "hiscore3", slot, locationId, songId, style, difficulty}, { $set: { country, region, customerCode, companyCode, pcbid, dancerName, score: hiScoreCheck, ghostId }});
|
||||
}
|
||||
|
||||
|
||||
let hiScoreMachine1 = await DB.FindOne<HiScoreWorld>(null, {collection: 'hiscore3', slot: 3, locationId: locationId, pcbid: pcbid, songId: songId, style: style, difficulty: difficulty})
|
||||
ghostData = await DB.Find<GhostWorld>(null, {collection: "ghost3"})
|
||||
lastGhostId = getLastGhostId(ghostData)
|
||||
ghostId = 0
|
||||
if(lastGhostId === 0) ghostId = 1
|
||||
else ghostId = lastGhostId += 1
|
||||
|
||||
if(hiScoreMachine1) {
|
||||
if(hiScoreCheck >= hiScoreMachine1.score) {
|
||||
machineBreak = true
|
||||
ghostId = (hiScoreMachine1.ghostId) ? hiScoreMachine1.ghostId : ghostId
|
||||
await DB.Upsert<GhostWorld>(refid, {collection: "ghost3", ghostId }, {$set: { ghostSize, ghost }});
|
||||
}
|
||||
} else {
|
||||
machineBreak = true
|
||||
await DB.Upsert<GhostWorld>(refid, {collection: "ghost3", ghostId }, {$set: { ghostSize, ghost }});
|
||||
}
|
||||
slot = 3
|
||||
if(machineBreak) {
|
||||
await DB.Upsert<HiScoreWorld>(refid, {collection: "hiscore3", slot, locationId, pcbid, songId, style, difficulty}, { $set: { country, region, customerCode, companyCode, dancerName, score: hiScoreCheck, ghostId }});
|
||||
}
|
||||
}
|
||||
|
||||
export const playerdatanew: EPR = async (info, data, send) => {
|
||||
const refid = $(data).str("data.refid");
|
||||
let ddrCode = _.random(1, 99999999)
|
||||
await DB.Upsert<ProfileWorld>(refid, { collection: "profile3" }, {
|
||||
collection: "profile3",
|
||||
ddrCode: ddrCode
|
||||
})
|
||||
return send.object({
|
||||
result: K.ITEM("s32", 0),
|
||||
refid: K.ITEM("str", refid),
|
||||
ddrcode: K.ITEM("s32", ddrCode),
|
||||
istakeover: K.ITEM('bool', false)
|
||||
})
|
||||
}
|
||||
|
||||
export const playerdatasave: EPR = async (info, data, send) => {
|
||||
const refid = $(data).str("data.refid");
|
||||
if(!refid.startsWith("X000")) {
|
||||
if($(data).number("data.savekind") === 1) {
|
||||
await DB.Upsert<ProfileWorld>(refid, { collection: "profile3" }, {
|
||||
collection: "profile3",
|
||||
|
||||
ddrCode: $(data).number('data.common.ddrcode'),
|
||||
dancerName: $(data).str('data.common.dancername'),
|
||||
area: $(data).number('data.common.area'),
|
||||
extraStar: $(data).number('data.common.extrastar'),
|
||||
playCount: 0,
|
||||
weight: 0,
|
||||
todayCal: $(data).number('data.common.today_cal'),
|
||||
isDispWeight: true,
|
||||
prePlayableNum: 0,
|
||||
|
||||
opHispeed: $(data).number('data.option.hispeed'),
|
||||
opGauge: $(data).number('data.option.gauge'),
|
||||
opFastSlow: $(data).number('data.option.fastslow'),
|
||||
opGuideline: $(data).number('data.option.guideline'),
|
||||
opStepZone: $(data).number('data.option.stepzone'),
|
||||
opTimingDisp: $(data).number('data.option.timing_disp'),
|
||||
opVisibility: $(data).number('data.option.visibility'),
|
||||
opVisibleTime: $(data).number('data.option.visible_time'),
|
||||
opLane: $(data).number('data.option.lane'),
|
||||
opLaneHiddenPos: $(data).number('data.option.lane_hiddenpos'),
|
||||
opLaneSuddenPos: $(data).number('data.option.lane_suddenpos'),
|
||||
opLaneHidSudPos: $(data).number('data.option.lane_hidsudpos'),
|
||||
opLaneFilter: $(data).number('data.option.lane_filter'),
|
||||
opScrollDirection: $(data).number('data.option.scroll_direction'),
|
||||
opScrollMoving: $(data).number('data.option.scroll_moving'),
|
||||
opArrowPriority: $(data).number('data.option.arrow_priority'),
|
||||
opArrowPlacement: $(data).number('data.option.arrow_placement'),
|
||||
opArrowColor: $(data).number('data.option.arrow_color'),
|
||||
opArrowDesign: $(data).number('data.option.arrow_design'),
|
||||
opCutTiming: $(data).number('data.option.cut_timing'),
|
||||
opCutFreeze: $(data).number('data.option.cut_freeze'),
|
||||
opCutJump: $(data).number('data.option.cut_jump'),
|
||||
|
||||
lpMode: $(data).number('data.lastplay.mode'),
|
||||
lpFolder: $(data).number('data.lastplay.folder'),
|
||||
lpMcode: $(data).number('data.lastplay.mcode'),
|
||||
lpStyle: $(data).number('data.lastplay.style'),
|
||||
lpDifficulty: $(data).number('data.lastplay.difficulty'),
|
||||
lpWindowMain: $(data).number('data.lastplay.window_main'),
|
||||
lpWindowSub: $(data).number('data.lastplay.window_sub'),
|
||||
lpTarget: $(data).number('data.lastplay.target'),
|
||||
lpTabMain: $(data).number('data.lastplay.tab_main'),
|
||||
lpTabSub: $(data).number('data.lastplay.tab_sub'),
|
||||
|
||||
fsTitle: $(data).number('data.filtersort.title'),
|
||||
fsVersion: $(data).number('data.filtersort.version'),
|
||||
fsGenre: $(data).number('data.filtersort.genre'),
|
||||
fsBpm: $(data).number('data.filtersort.bpm'),
|
||||
fsEvent: $(data).number('data.filtersort.event'),
|
||||
fsLevel: $(data).number('data.filtersort.level'),
|
||||
fsFlareRank: $(data).number('data.filtersort.flare_rank'),
|
||||
fsClearRank: $(data).number('data.filtersort.clear_rank'),
|
||||
fsFlareSkillTarget: $(data).number('data.filtersort.flare_skill_target'),
|
||||
fsRivalFlareSkill: $(data).number('data.filtersort.rival_flare_skill'),
|
||||
fsRivalScoreRank: $(data).number('data.filtersort.rival_score_rank'),
|
||||
fsSortType: $(data).number('data.filtersort.sort_type'),
|
||||
fsOrderType: $(data).number('data.filtersort.order_type'),
|
||||
|
||||
cgTipsBasic: $(data).number('data.checkguide.tips_basic'),
|
||||
cgTipsOption: $(data).number('data.checkguide.tips_option'),
|
||||
cgTipsEvent: $(data).number('data.checkguide.tips_event'),
|
||||
cgTipsGimmick: $(data).number('data.checkguide.tips_gimmick'),
|
||||
cgTipsAdvance: $(data).number('data.checkguide.tips_advance'),
|
||||
cgGuideScene: $(data).number('data.checkguide.guide_scene')
|
||||
})
|
||||
}
|
||||
else if($(data).number("data.savekind") === 2) {
|
||||
let hiScoreInfo = {
|
||||
country: $(data).str("data.country"),
|
||||
region: $(data).str("data.region"),
|
||||
customerCode: $(data).str("data.customercode"),
|
||||
companyCode: $(data).str("data.companycode"),
|
||||
locationId: $(data).str("data.locationid"),
|
||||
pcbid: $(data).str("data.pcbid"),
|
||||
dancerName: $(data).str("data.common.dancername")
|
||||
}
|
||||
|
||||
let songId = $(data).number("data.result.mcode");
|
||||
let style = $(data).number("data.result.style");
|
||||
let difficulty = $(data).number("data.result.difficulty");
|
||||
let rank = $(data).number("data.result.rank");
|
||||
let clearKind = $(data).number("data.result.clearkind");
|
||||
let score = $(data).number("data.result.score");
|
||||
let exScore = $(data).number("data.result.exscore");
|
||||
let maxCombo = $(data).number("data.result.maxcombo");
|
||||
let flareForce = $(data).number("data.result.flare_force");
|
||||
let ghostSize = $(data).number("data.result.ghostsize");
|
||||
let ghost = $(data).str("data.result.ghost");
|
||||
await saveScores(refid, hiScoreInfo, songId, style, difficulty, rank, clearKind, score, exScore, maxCombo, flareForce, ghostSize, ghost)
|
||||
}
|
||||
else if($(data).number("data.savekind") === 3) {
|
||||
let profile = await DB.FindOne<ProfileWorld>(refid, {collection: "profile3"})
|
||||
await DB.Upsert<ProfileWorld>(refid, { collection: "profile3" }, {
|
||||
collection: "profile3",
|
||||
|
||||
ddrCode: $(data).number('data.common.ddrcode'),
|
||||
dancerName: $(data).str('data.common.dancername'),
|
||||
area: $(data).number('data.common.area'),
|
||||
extraStar: $(data).number('data.common.extrastar'),
|
||||
playCount: profile.playCount += 1,
|
||||
weight: 0,
|
||||
todayCal: $(data).number('data.common.today_cal'),
|
||||
isDispWeight: true,
|
||||
prePlayableNum: 0,
|
||||
|
||||
opHispeed: $(data).number('data.option.hispeed'),
|
||||
opGauge: $(data).number('data.option.gauge'),
|
||||
opFastSlow: $(data).number('data.option.fastslow'),
|
||||
opGuideline: $(data).number('data.option.guideline'),
|
||||
opStepZone: $(data).number('data.option.stepzone'),
|
||||
opTimingDisp: $(data).number('data.option.timing_disp'),
|
||||
opVisibility: $(data).number('data.option.visibility'),
|
||||
opVisibleTime: $(data).number('data.option.visible_time'),
|
||||
opLane: $(data).number('data.option.lane'),
|
||||
opLaneHiddenPos: $(data).number('data.option.lane_hiddenpos'),
|
||||
opLaneSuddenPos: $(data).number('data.option.lane_suddenpos'),
|
||||
opLaneHidSudPos: $(data).number('data.option.lane_hidsudpos'),
|
||||
opLaneFilter: $(data).number('data.option.lane_filter'),
|
||||
opScrollDirection: $(data).number('data.option.scroll_direction'),
|
||||
opScrollMoving: $(data).number('data.option.scroll_moving'),
|
||||
opArrowPriority: $(data).number('data.option.arrow_priority'),
|
||||
opArrowPlacement: $(data).number('data.option.arrow_placement'),
|
||||
opArrowColor: $(data).number('data.option.arrow_color'),
|
||||
opArrowDesign: $(data).number('data.option.arrow_design'),
|
||||
opCutTiming: $(data).number('data.option.cut_timing'),
|
||||
opCutFreeze: $(data).number('data.option.cut_freeze'),
|
||||
opCutJump: $(data).number('data.option.cut_jump'),
|
||||
|
||||
lpMode: $(data).number('data.lastplay.mode'),
|
||||
lpFolder: $(data).number('data.lastplay.folder'),
|
||||
lpMcode: $(data).number('data.lastplay.mcode'),
|
||||
lpStyle: $(data).number('data.lastplay.style'),
|
||||
lpDifficulty: $(data).number('data.lastplay.difficulty'),
|
||||
lpWindowMain: $(data).number('data.lastplay.window_main'),
|
||||
lpWindowSub: $(data).number('data.lastplay.window_sub'),
|
||||
lpTarget: $(data).number('data.lastplay.target'),
|
||||
lpTabMain: $(data).number('data.lastplay.tab_main'),
|
||||
lpTabSub: $(data).number('data.lastplay.tab_sub'),
|
||||
|
||||
fsTitle: $(data).number('data.filtersort.title'),
|
||||
fsVersion: $(data).number('data.filtersort.version'),
|
||||
fsGenre: $(data).number('data.filtersort.genre'),
|
||||
fsBpm: $(data).number('data.filtersort.bpm'),
|
||||
fsEvent: $(data).number('data.filtersort.event'),
|
||||
fsLevel: $(data).number('data.filtersort.level'),
|
||||
fsFlareRank: $(data).number('data.filtersort.flare_rank'),
|
||||
fsClearRank: $(data).number('data.filtersort.clear_rank'),
|
||||
fsFlareSkillTarget: $(data).number('data.filtersort.flare_skill_target'),
|
||||
fsRivalFlareSkill: $(data).number('data.filtersort.rival_flare_skill'),
|
||||
fsRivalScoreRank: $(data).number('data.filtersort.rival_score_rank'),
|
||||
fsSortType: $(data).number('data.filtersort.sort_type'),
|
||||
fsOrderType: $(data).number('data.filtersort.order_type'),
|
||||
|
||||
cgTipsBasic: $(data).number('data.checkguide.tips_basic'),
|
||||
cgTipsOption: $(data).number('data.checkguide.tips_option'),
|
||||
cgTipsEvent: $(data).number('data.checkguide.tips_event'),
|
||||
cgTipsGimmick: $(data).number('data.checkguide.tips_gimmick'),
|
||||
cgTipsAdvance: $(data).number('data.checkguide.tips_advance'),
|
||||
cgGuideScene: $(data).number('data.checkguide.guide_scene')
|
||||
})
|
||||
|
||||
let eventData = $(data).elements('data.event')
|
||||
if(eventData) {
|
||||
for(const e of eventData) {
|
||||
let eid = e.number('eventid')
|
||||
let eno = e.number('eventno')
|
||||
let etype = e.number('eventtype')
|
||||
let ctime = e.number('comptime')
|
||||
let sdata = e.number('savedata')
|
||||
|
||||
await DB.Upsert<EventWorld>(refid, { collection: "event3", eventId: eid, eventNo: eno, eventType: etype }, {
|
||||
collection: "event3",
|
||||
eventId: eid,
|
||||
eventNo: eno,
|
||||
eventType: etype,
|
||||
compTime: ctime,
|
||||
saveData: sdata
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let leagueData = $(data).element('data.league.current')
|
||||
if(leagueData) {
|
||||
let leagueId = leagueData.number("league_id")
|
||||
let score = leagueData.number("score")
|
||||
let playCount = leagueData.number("playcount")
|
||||
let leagueExist = await DB.FindOne<LeagueWorld>(refid, {collection: 'league3', id: leagueId})
|
||||
|
||||
await DB.Upsert<LeagueWorld>(refid, { collection: "league3", id: leagueId }, {
|
||||
$set: {
|
||||
class: ((leagueExist.class === 0) ? 1 : leagueExist.class),
|
||||
score: score,
|
||||
playCount: playCount
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return send.object({
|
||||
result: K.ITEM("s32", 0)
|
||||
})
|
||||
}
|
||||
|
||||
return send.object({
|
||||
result: K.ITEM("s32", 1)
|
||||
})
|
||||
};
|
||||
|
||||
export const playerdataload: EPR = async (info, data, send) => {
|
||||
const refid = $(data).str("data.refid");
|
||||
const profile = await DB.FindOne<ProfileWorld>(refid, { collection: "profile3" });
|
||||
|
||||
if (!profile || !profile.dancerName || refid.startsWith("X000")) {
|
||||
return send.object({
|
||||
result: K.ITEM("s32", 0),
|
||||
refid: K.ITEM("str", refid),
|
||||
gamesession: K.ITEM('s64', BigInt(1)),
|
||||
servertime: K.ITEM("u64", BigInt(getDate())),
|
||||
is_locked: K.ITEM('bool', false),
|
||||
common: {
|
||||
ddrcode: K.ITEM("s32", profile ? profile.ddrCode : 0),
|
||||
dancername: K.ITEM("str", ''),
|
||||
is_new: K.ITEM('bool', (!profile || refid.startsWith("X000")) ? true : false),
|
||||
is_registering: K.ITEM('bool', (profile && !profile.dancerName) ? true : false),
|
||||
is_takeover: K.ITEM('bool', false),
|
||||
area: K.ITEM("s32", 0),
|
||||
extrastar: K.ITEM("s32", 0),
|
||||
playcount: K.ITEM("s32", 0),
|
||||
weight: K.ITEM("s32", 0),
|
||||
today_cal: K.ITEM("u64", BigInt(0)),
|
||||
is_disp_weight: K.ITEM("bool", false),
|
||||
pre_playable_num: K.ITEM("s32", 0)
|
||||
},
|
||||
option: {
|
||||
hispeed: K.ITEM("s32", 0),
|
||||
gauge: K.ITEM("s32", 0),
|
||||
fastslow: K.ITEM("s32", 0),
|
||||
guideline: K.ITEM("s32", 0),
|
||||
stepzone: K.ITEM("s32", 0),
|
||||
timing_disp: K.ITEM("s32", 0),
|
||||
visibility: K.ITEM("s32", 0),
|
||||
visible_time: K.ITEM("s32", 0),
|
||||
lane: K.ITEM("s32", 0),
|
||||
lane_hiddenpos: K.ITEM("s32", 0),
|
||||
lane_suddenpos: K.ITEM("s32", 0),
|
||||
lane_hidsudpos: K.ITEM("s32", 0),
|
||||
lane_filter: K.ITEM("s32", 0),
|
||||
scroll_direction: K.ITEM("s32", 0),
|
||||
scroll_moving: K.ITEM("s32", 0),
|
||||
arrow_priority: K.ITEM("s32", 0),
|
||||
arrow_placement: K.ITEM("s32", 0),
|
||||
arrow_color: K.ITEM("s32", 0),
|
||||
arrow_design: K.ITEM("s32", 0),
|
||||
cut_timing: K.ITEM("s32", 0),
|
||||
cut_freeze: K.ITEM("s32", 0),
|
||||
cut_jump: K.ITEM("s32", 0)
|
||||
},
|
||||
lastplay: {
|
||||
mode: K.ITEM("s32", 0),
|
||||
folder: K.ITEM("s32", 0),
|
||||
mcode: K.ITEM("s32", 0),
|
||||
style: K.ITEM("s32", 0),
|
||||
difficulty: K.ITEM("s32", 0),
|
||||
window_main: K.ITEM("s32", 0),
|
||||
window_sub: K.ITEM("s32", 0),
|
||||
target: K.ITEM("s32", 0),
|
||||
tab_main: K.ITEM("s32", 0),
|
||||
tab_sub: K.ITEM("s32", 0)
|
||||
},
|
||||
filtersort: {
|
||||
title: K.ITEM("u64", BigInt(0)),
|
||||
version: K.ITEM("u64", BigInt(0)),
|
||||
genre: K.ITEM("u64", BigInt(0)),
|
||||
bpm: K.ITEM("u64", BigInt(0)),
|
||||
event: K.ITEM("u64", BigInt(0)),
|
||||
level: K.ITEM("u64", BigInt(0)),
|
||||
flare_rank: K.ITEM("u64", BigInt(0)),
|
||||
clear_rank: K.ITEM("u64", BigInt(0)),
|
||||
flare_skill_target: K.ITEM("u64", BigInt(0)),
|
||||
rival_flare_skill: K.ITEM("u64", BigInt(0)),
|
||||
rival_score_rank: K.ITEM("u64", BigInt(0)),
|
||||
sort_type: K.ITEM("u64", BigInt(0)),
|
||||
order_type: K.ITEM("s32", 0),
|
||||
},
|
||||
checkguide: {
|
||||
tips_basic: K.ITEM("u64", BigInt(0)),
|
||||
tips_option: K.ITEM("u64", BigInt(0)),
|
||||
tips_event: K.ITEM("u64", BigInt(0)),
|
||||
tips_gimmick: K.ITEM("u64", BigInt(0)),
|
||||
tips_advance: K.ITEM("u64", BigInt(0)),
|
||||
guide_scene: K.ITEM("u64", BigInt(0)),
|
||||
},
|
||||
rival: [
|
||||
{
|
||||
slot: K.ITEM("s32", 0),
|
||||
rivalcode: K.ITEM("s32", 0)
|
||||
}
|
||||
],
|
||||
score: [
|
||||
{
|
||||
mcode: K.ITEM("s32", 0),
|
||||
score_single: {
|
||||
score_str: K.ITEM("str", "")
|
||||
},
|
||||
score_double: {
|
||||
score_str: K.ITEM("str", "")
|
||||
}
|
||||
}
|
||||
],
|
||||
event: {
|
||||
event_str: K.ITEM("str", "")
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
// await addGhostId(refid)
|
||||
const scores = await DB.Find<ScoreWorld>(refid, { collection: "score3" });
|
||||
let scoreFin = []
|
||||
if(scores) {
|
||||
for(const scoreData of scores) {
|
||||
let mcodeIndex = scoreFin.findIndex(x => $(x).number('mcode') === scoreData.songId)
|
||||
if(mcodeIndex < 0) {
|
||||
let scr = {}
|
||||
scr['mcode'] = K.ITEM('s32', scoreData.songId)
|
||||
scr['score_single'] = []
|
||||
scr['score_double'] = []
|
||||
/*
|
||||
difficulty,idk,grade,clearkind,score,ghostid,flaredisp,flarepoints,idk
|
||||
needs more work, 9 vals
|
||||
*/
|
||||
scr[(scoreData.style === 0) ? 'score_single' : 'score_double'] = [
|
||||
{
|
||||
score_str: K.ITEM('str', scoreData.difficulty + ',1,' + scoreData.rank + ',' + scoreData.clearKind + ',' + scoreData.score + ',' + scoreData.ghostId + ',' + scoreData.flareForce + ',' + scoreData.flareForce)
|
||||
}
|
||||
]
|
||||
scoreFin.push(scr)
|
||||
|
||||
} else {
|
||||
scoreFin[mcodeIndex][(scoreData.style === 0) ? 'score_single' : 'score_double'].push({
|
||||
score_str: K.ITEM('str', scoreData.difficulty + ',1,' + scoreData.rank + ',' + scoreData.clearKind + ',' + scoreData.score + ',' + scoreData.ghostId + ',' + scoreData.flareForce + ',' + scoreData.flareForce)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let eventFin = []
|
||||
let eventData = await DB.Find<EventWorld>(refid, { collection: "event3"});
|
||||
for(const event of EVENTS_WORLD) {
|
||||
let eData = eventData.find(e => e.eventId === event.id)
|
||||
let condmet = true
|
||||
let compTime = 0
|
||||
if(event.dep) {
|
||||
event.dep.forEach(dep => {
|
||||
let eData = eventData.find(e => e.eventId === dep)
|
||||
if(eData === undefined) condmet = false
|
||||
else if(eData.compTime === 0) condmet = false
|
||||
})
|
||||
}
|
||||
// id,type,no,condition,reward,comptime,savedata
|
||||
if(condmet) {
|
||||
if([17, 43].includes(event.type)) {
|
||||
if (eData) eData.compTime = eData.compTime ? 0 : 1
|
||||
compTime = event.comp ? 0 : 1
|
||||
}
|
||||
eventFin.push({
|
||||
event_str: K.ITEM('str', event.id + ',' + event.type + ',' + event.no + ',' + event.cond + ',' + event.rwrd + ',' + (eData ? BigInt(eData.compTime) : compTime) + ',' + ((eData) ? eData.saveData : ((event.save !== undefined) ? event.save : '0')))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let leagueData = {}
|
||||
let curLeague = LEAGUE_WORLD[1]
|
||||
let league = await DB.FindOne(refid, {collection: 'league3', id: curLeague.id})
|
||||
if(!league) {
|
||||
let leagueClass = 0
|
||||
let prevLeague = await DB.FindOne(refid, {collection: 'league3', id: curLeague.id - 1})
|
||||
if(prevLeague) leagueClass = prevLeague['class']
|
||||
await DB.Upsert<LeagueWorld>(refid, { collection: "league3", id: curLeague.id }, {
|
||||
collection: "league3",
|
||||
|
||||
id: curLeague.id,
|
||||
class: leagueClass,
|
||||
score: 0,
|
||||
playCount: 0,
|
||||
ended: false,
|
||||
})
|
||||
}
|
||||
league = await DB.FindOne(refid, {collection: 'league3', id: curLeague.id})
|
||||
if(league) {
|
||||
let leagueAll = await DB.Find(null, {collection: 'league3', id: curLeague.id, class: league['class']})
|
||||
let joinNum = leagueAll.length
|
||||
let resultClass = league['class']
|
||||
let promoteScore = 0
|
||||
let promoteRank = 0
|
||||
let demoteScore = 0
|
||||
let demoteRank = 0
|
||||
let leagueStatus = 0
|
||||
let leagueScores = leagueAll.map(a => a['score']).sort((a, b) => b - a)
|
||||
if(leagueScores[0] > 0) {
|
||||
if(league['class'] === 1) {
|
||||
promoteScore = Math.round(leagueScores[0] / 2)
|
||||
leagueScores = leagueScores.concat([promoteScore]).sort((a, b) => b - a)
|
||||
promoteRank = leagueScores.findIndex(s => s === promoteScore) + 1
|
||||
joinNum += ((joinNum < 2) ? 2 : 1)
|
||||
} else if(league['class'] === 2) {
|
||||
promoteScore = Math.round(leagueScores[0] - (leagueScores[0] - (35 / 100 * leagueScores[0])))
|
||||
demoteScore = Math.round(leagueScores[0] - (leagueScores[0] - (85 / 100 * leagueScores[0])))
|
||||
leagueScores = leagueScores.concat([promoteScore, demoteScore]).sort((a, b) => b - a)
|
||||
promoteRank = leagueScores.findIndex(s => s === promoteScore) + 1
|
||||
demoteScore = leagueScores.findIndex(s => s === demoteScore) + 1
|
||||
joinNum += 2
|
||||
} else if(league['class'] === 3) {
|
||||
demoteScore = Math.round(leagueScores[0] - (leagueScores[0] - (85 / 100 * leagueScores[0])))
|
||||
leagueScores = leagueScores.concat([demoteScore]).sort((a, b) => b - a)
|
||||
demoteRank = leagueScores.findIndex(s => s === demoteScore) + 1
|
||||
joinNum += ((joinNum < 2) ? 2 : 1)
|
||||
}
|
||||
}
|
||||
let rank = leagueScores.findIndex(s => s === league['score']) + 1
|
||||
let leagueClass = (league['class'] === 0) ? 1 : league['class']
|
||||
|
||||
if(leagueClass === 1 && league['score'] >= promoteScore) resultClass += 1
|
||||
else if(leagueClass === 2) {
|
||||
if(league['score'] >= promoteScore) resultClass += 1
|
||||
else if(league['score'] < demoteScore) resultClass -= 1
|
||||
}
|
||||
else if(leagueClass === 3 && league['score'] < demoteScore) resultClass -= 1
|
||||
|
||||
if(BigInt(Date.now()) >= curLeague.start) leagueStatus = 1
|
||||
if(BigInt(Date.now()) >= curLeague.end) leagueStatus = 2
|
||||
if(BigInt(Date.now()) >= curLeague.summary) {
|
||||
leagueStatus = 0
|
||||
if(!league['ended']) await DB.Upsert<LeagueWorld>(refid, {collection: 'league3', id: curLeague.id}, {$set: {ended: true, class: resultClass}})
|
||||
}
|
||||
leagueData = {
|
||||
league_class: K.ITEM("s32", (BigInt(Date.now()) >= curLeague.summary && !league['ended']) ? resultClass : league['class']),
|
||||
current: {
|
||||
league_id: K.ITEM("s32", curLeague.id),
|
||||
league_name: K.ITEM("str", Buffer.from(curLeague.name, 'utf8').toString('base64')),
|
||||
league_name_eng: K.ITEM("str", Buffer.from(curLeague.name_eng, 'utf8').toString('base64')),
|
||||
starttime: K.ITEM("u64", curLeague.start),
|
||||
endtime: K.ITEM("u64", curLeague.end),
|
||||
summarytime: K.ITEM("u64", curLeague.summary),
|
||||
league_status: K.ITEM("s32", leagueStatus),
|
||||
league_class: K.ITEM("s32", leagueClass),
|
||||
result_league_class: K.ITEM("s32", resultClass),
|
||||
rank: K.ITEM("s32", rank),
|
||||
score: K.ITEM("s32", league['score']),
|
||||
playcount: K.ITEM("s32", league['playCount']),
|
||||
advance_border: K.ITEM("s32", curLeague.advanceBorder[leagueClass - 1]),
|
||||
join_num: K.ITEM("s32", joinNum),
|
||||
promote_rank: K.ITEM("s32", promoteRank),
|
||||
promote_score: K.ITEM("s32", promoteScore),
|
||||
demote_rank: K.ITEM("s32", demoteRank),
|
||||
demote_score: K.ITEM("s32", demoteScore),
|
||||
ranking_score: K.ITEM("s32", league['score'])
|
||||
},
|
||||
result: (BigInt(Date.now()) >= curLeague.summary && !league['ended']) ? [
|
||||
{
|
||||
league_id: K.ITEM("s32", curLeague.id),
|
||||
league_name: K.ITEM("str", Buffer.from(curLeague.name, 'utf8').toString('base64')),
|
||||
league_name_eng: K.ITEM("str", Buffer.from(curLeague.name_eng, 'utf8').toString('base64')),
|
||||
starttime: K.ITEM("u64", curLeague.start),
|
||||
endtime: K.ITEM("u64", curLeague.end),
|
||||
summarytime: K.ITEM("u64", curLeague.summary),
|
||||
league_status: K.ITEM("s32", 1),
|
||||
league_class: K.ITEM("s32", league['class']),
|
||||
result_league_class: K.ITEM("s32", resultClass),
|
||||
rank: K.ITEM("s32", rank),
|
||||
score: K.ITEM("s32", league['score']),
|
||||
playcount: K.ITEM("s32", league['playCount']),
|
||||
advance_border: K.ITEM("s32", curLeague.advanceBorder[leagueClass - 1]),
|
||||
join_num: K.ITEM("s32", joinNum),
|
||||
promote_rank: K.ITEM("s32", promoteRank),
|
||||
promote_score: K.ITEM("s32", promoteScore),
|
||||
demote_rank: K.ITEM("s32", demoteRank),
|
||||
demote_score: K.ITEM("s32", demoteScore)
|
||||
}
|
||||
] : []
|
||||
}
|
||||
}
|
||||
|
||||
let userCustomize = []
|
||||
let customize = await DB.Find<CustomizeWorld>(refid, {collection: 'customize3'})
|
||||
customize.forEach(cus => {
|
||||
userCustomize.push({
|
||||
category: K.ITEM('s32', cus.category),
|
||||
key: K.ITEM('s32', cus.key),
|
||||
pattern: K.ITEM('s32', cus.pattern)
|
||||
})
|
||||
})
|
||||
|
||||
// test
|
||||
if(IO.Exists('data/test.json')) {
|
||||
let bufTest = await IO.ReadFile('data/test.json')
|
||||
let eventTest = JSON.parse(bufTest.toString())
|
||||
for(const ex in eventTest['eventtest']) {
|
||||
eventFin.push({ event_str: K.ITEM('str', eventTest['eventtest'][ex]) })
|
||||
}
|
||||
}
|
||||
|
||||
return send.object({
|
||||
result: K.ITEM("s32", 0),
|
||||
refid: K.ITEM("str", refid),
|
||||
gamesession: K.ITEM('s64', BigInt(1)),
|
||||
servertime: K.ITEM("u64", BigInt(getDate())),
|
||||
is_locked: K.ITEM('bool', false),
|
||||
common: {
|
||||
ddrcode: K.ITEM("s32", profile.ddrCode),
|
||||
dancername: K.ITEM("str", profile.dancerName),
|
||||
is_new: K.ITEM('bool', false),
|
||||
is_registering: K.ITEM('bool', false),
|
||||
is_takeover: K.ITEM('bool', false),
|
||||
area: K.ITEM("s32", profile.area),
|
||||
extrastar: K.ITEM("s32", profile.extraStar),
|
||||
playcount: K.ITEM("s32", profile.playCount),
|
||||
weight: K.ITEM("s32", profile.weight),
|
||||
today_cal: K.ITEM("u64", BigInt(profile.todayCal)),
|
||||
is_disp_weight: K.ITEM("bool", profile.isDispWeight),
|
||||
pre_playable_num: K.ITEM("s32", profile.prePlayableNum)
|
||||
},
|
||||
option: {
|
||||
hispeed: K.ITEM("s32", profile.opHispeed),
|
||||
gauge: K.ITEM("s32", profile.opGauge),
|
||||
fastslow: K.ITEM("s32", profile.opFastSlow),
|
||||
guideline: K.ITEM("s32", profile.opGuideline),
|
||||
stepzone: K.ITEM("s32", profile.opStepZone),
|
||||
timing_disp: K.ITEM("s32", profile.opTimingDisp),
|
||||
visibility: K.ITEM("s32", profile.opVisibility),
|
||||
visible_time: K.ITEM("s32", profile.opVisibleTime),
|
||||
lane: K.ITEM("s32", profile.opLane),
|
||||
lane_hiddenpos: K.ITEM("s32", profile.opLaneHiddenPos),
|
||||
lane_suddenpos: K.ITEM("s32", profile.opLaneSuddenPos),
|
||||
lane_hidsudpos: K.ITEM("s32", profile.opLaneHidSudPos),
|
||||
lane_filter: K.ITEM("s32", profile.opLaneFilter),
|
||||
scroll_direction: K.ITEM("s32", profile.opScrollDirection),
|
||||
scroll_moving: K.ITEM("s32", profile.opScrollMoving),
|
||||
arrow_priority: K.ITEM("s32", profile.opArrowPriority),
|
||||
arrow_placement: K.ITEM("s32", profile.opArrowPlacement),
|
||||
arrow_color: K.ITEM("s32", profile.opArrowColor),
|
||||
arrow_design: K.ITEM("s32", profile.opArrowDesign),
|
||||
cut_timing: K.ITEM("s32", profile.opCutTiming),
|
||||
cut_freeze: K.ITEM("s32", profile.opCutFreeze),
|
||||
cut_jump: K.ITEM("s32", profile.opCutJump)
|
||||
},
|
||||
lastplay: {
|
||||
mode: K.ITEM("s32", profile.lpMode),
|
||||
folder: K.ITEM("s32", profile.lpFolder),
|
||||
mcode: K.ITEM("s32", profile.lpMcode),
|
||||
style: K.ITEM("s32", profile.lpStyle),
|
||||
difficulty: K.ITEM("s32", profile.lpDifficulty),
|
||||
window_main: K.ITEM("s32", profile.lpWindowMain),
|
||||
window_sub: K.ITEM("s32", profile.lpWindowSub),
|
||||
target: K.ITEM("s32", profile.lpTarget),
|
||||
tab_main: K.ITEM("s32", profile.lpTabMain),
|
||||
tab_sub: K.ITEM("s32", profile.lpTabSub)
|
||||
},
|
||||
filtersort: {
|
||||
title: K.ITEM("u64", BigInt(profile.fsTitle)),
|
||||
version: K.ITEM("u64", BigInt(profile.fsVersion)),
|
||||
genre: K.ITEM("u64", BigInt(profile.fsGenre)),
|
||||
bpm: K.ITEM("u64", BigInt(profile.fsBpm)),
|
||||
event: K.ITEM("u64", BigInt(profile.fsEvent)),
|
||||
level: K.ITEM("u64", BigInt(profile.fsLevel)),
|
||||
flare_rank: K.ITEM("u64", BigInt(profile.fsFlareRank)),
|
||||
clear_rank: K.ITEM("u64", BigInt(profile.fsClearRank)),
|
||||
flare_skill_target: K.ITEM("u64", BigInt(profile.fsFlareSkillTarget)),
|
||||
rival_flare_skill: K.ITEM("u64", BigInt(profile.fsRivalFlareSkill)),
|
||||
rival_score_rank: K.ITEM("u64", BigInt(profile.fsRivalScoreRank)),
|
||||
sort_type: K.ITEM("u64", BigInt(profile.fsSortType)),
|
||||
order_type: K.ITEM("s32", profile.fsOrderType),
|
||||
},
|
||||
checkguide: {
|
||||
tips_basic: K.ITEM("u64", BigInt(profile.cgTipsBasic)),
|
||||
tips_option: K.ITEM("u64", BigInt(profile.cgTipsOption)),
|
||||
tips_event: K.ITEM("u64", BigInt(profile.cgTipsEvent)),
|
||||
tips_gimmick: K.ITEM("u64", BigInt(profile.cgTipsGimmick)),
|
||||
tips_advance: K.ITEM("u64", BigInt(profile.cgTipsAdvance)),
|
||||
guide_scene: K.ITEM("u64", BigInt(profile.cgGuideScene)),
|
||||
},
|
||||
rival: [],
|
||||
score: scoreFin,
|
||||
event: eventFin,
|
||||
league: leagueData,
|
||||
customize: userCustomize
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const musicdataload: EPR = async (info, data, send) => {
|
||||
// I personally use the last A3 db for this, will check for missing songs
|
||||
let musicList = []
|
||||
let mdbLimName = U.GetConfig('mdb_limited')
|
||||
if(mdbLimName !== '') {
|
||||
if(IO.Exists('data/' + mdbLimName)) {
|
||||
let mdb = U.parseXML(U.DecodeString(await IO.ReadFile('data/' + mdbLimName), "shift_jis"), false)
|
||||
for(const music of mdb['mdb']['music']) {
|
||||
let difficultyArr = $(music).numbers('diffLv')
|
||||
let limited = ($(music).number('limited')) ? $(music).number('limited') : 0
|
||||
let limitedCha = ($(music).number('limited_cha')) ? $(music).number('limited_cha') : 0
|
||||
let limitedAry = ($(music).numbers('limited_ary')) ? $(music).numbers('limited_ary') : []
|
||||
|
||||
let overrideIndex = SONGS_OVERRIDE_WORLD.findIndex(s => s.mcode === $(music).number('mcode'))
|
||||
if(overrideIndex > -1) {
|
||||
limitedAry = (SONGS_OVERRIDE_WORLD[overrideIndex]['limited_ary'] !== [] ? SONGS_OVERRIDE_WORLD[overrideIndex]['limited_ary'] : limitedAry)
|
||||
difficultyArr = SONGS_OVERRIDE_WORLD[overrideIndex]['diffLv']
|
||||
}
|
||||
|
||||
for(const [index, diff] of difficultyArr.entries()) {
|
||||
limited = ((index % 5 === 4) && limitedCha) ? limitedCha : limited
|
||||
limited = (limitedAry.length > 0) ? limitedAry[index] : limited
|
||||
|
||||
if($(music).number('series') === 20 && overrideIndex === -1) {
|
||||
limited = 0
|
||||
for(const ls in LOCKED_SONGS) {
|
||||
if(index % 5 < 4) {
|
||||
if(LOCKED_SONGS[ls].ids.includes($(music).number('mcode')) && BigInt(Date.now()) < LOCKED_SONGS[ls].unlock_date) {
|
||||
limited = 1
|
||||
break
|
||||
}
|
||||
} else if(index % 5 === 4) {
|
||||
if(LOCKED_SONGS[ls].ids_cha.includes($(music).number('mcode')) && BigInt(Date.now()) < LOCKED_SONGS[ls].unlock_date) {
|
||||
limited = 1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
musicList.push({
|
||||
music_str: K.ITEM('str', $(music).number('mcode') + ',' + ((index > 4) ? '1,' : '0,') + (index % 5) + ',' + (U.GetConfig('song_unlock') && limited != -1 ? '0' : limited) + ',' + diff)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(const music of SONGS_WORLD) {
|
||||
for(const [index, diff] of music.diffLv.entries()) {
|
||||
if(music.limited_ary[index] != -1) {
|
||||
musicList.push({
|
||||
music_str: K.ITEM('str', music.mcode + ',' + ((index > 4) ? '1,' : '0,') + (index % 5) + ',' + (U.GetConfig('song_unlock') && music.limited_ary[index] != -1 ? '0' : music.limited_ary[index]) + ',' + diff)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
// test
|
||||
if(IO.Exists('data/test.json')) {
|
||||
let bufTest = await IO.ReadFile('data/test.json')
|
||||
let eventTest = JSON.parse(bufTest.toString())
|
||||
for(const ex in eventTest['songstest']) {
|
||||
for(const [index, diff] of eventTest['songstest'][ex].diffLv.entries()) {
|
||||
if(eventTest['songstest'][ex].limited_ary[index] != -1) {
|
||||
musicList.push({
|
||||
music_str: K.ITEM('str', eventTest['songstest'][ex].mcode + ',' + ((index > 4) ? '1,' : '0,') + (index % 5) + ',' + eventTest['songstest'][ex].limited_ary[index] + ',' + diff)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return send.object({
|
||||
result: K.ITEM("s32", 0),
|
||||
servertime: K.ITEM("u64", BigInt(getDate())),
|
||||
music: musicList
|
||||
});
|
||||
};
|
||||
|
||||
export const rivaldataload: EPR = async (info, data, send) => {
|
||||
const ddrCode = $(data).number("data.ddrcode");
|
||||
const loadKind = $(data).number("data.loadkind");
|
||||
const country = $(data).str("data.country");
|
||||
const region = $(data).str("data.region");
|
||||
const customerCode = $(data).str("data.customercode");
|
||||
const companyCode = $(data).str("data.companycode");
|
||||
const locationId = $(data).str("data.locationid");
|
||||
const pcbid = $(data).str("data.pcbid");
|
||||
|
||||
// song id, style, difficulty, idk, dancername, idk, idk, scoredisp, score, ghost
|
||||
let record = []
|
||||
let hiscore: any
|
||||
if(ddrCode === 0) {
|
||||
if(loadKind === 1) {
|
||||
hiscore = await DB.Find<HiScoreWorld>(null, {collection: 'hiscore3', slot: loadKind})
|
||||
} else if(loadKind === 2) {
|
||||
hiscore = await DB.Find<HiScoreWorld>(null, {collection: 'hiscore3', slot: loadKind, locationId: locationId})
|
||||
} else if(loadKind === 3) {
|
||||
hiscore = await DB.Find<HiScoreWorld>(null, {collection: 'hiscore3', slot: loadKind, locationId: locationId, pcbid: pcbid})
|
||||
}
|
||||
for(const hsi in hiscore) {
|
||||
record.push({
|
||||
record_str: K.ITEM('str', hiscore[hsi].songId + ',' + hiscore[hsi].style + ',' + hiscore[hsi].difficulty + ',0,' + hiscore[hsi].dancerName + ',0,0,1,' + hiscore[hsi].score + ',' + hiscore[hsi].ghostId)
|
||||
})
|
||||
}
|
||||
}
|
||||
return send.object({
|
||||
result: K.ITEM("s32", 0),
|
||||
record: record
|
||||
})
|
||||
};
|
||||
|
||||
export const ghostdataload: EPR = async (info, data, send) => {
|
||||
const refid = $(data).str("data.refid");
|
||||
const ghostId = $(data).number("data.ghostid");
|
||||
let ghostData = await DB.FindOne<GhostWorld>(null, {collection: 'ghost3', ghostId: ghostId})
|
||||
if(ghostData) {
|
||||
return send.object({
|
||||
result: K.ITEM("s32", 0),
|
||||
ghostsize: K.ITEM("s32", ghostData.ghostSize),
|
||||
ghost: K.ITEM("str", ghostData.ghost)
|
||||
});
|
||||
}
|
||||
return send.object({ result: K.ITEM("s32", 0) });
|
||||
};
|
||||
|
||||
export const taboowordcheck: EPR = async (info, data, send) => {
|
||||
// Automatically accept word
|
||||
return send.object({
|
||||
result: K.ITEM("s32", 0),
|
||||
is_taboo: K.ITEM("bool", false)
|
||||
});
|
||||
};
|
||||
|
||||
export const minidump: EPR = async (info, data, send) => {
|
||||
return send.object({ result: K.ITEM('s32', 0) })
|
||||
};
|
||||
|
||||
function getDate(): number {
|
||||
let time = new Date();
|
||||
let tempDate = time.getDate();
|
||||
const currentTime = parseInt((time.getTime()/100000) as unknown as string)*100;
|
||||
return currentTime
|
||||
}
|
||||
@@ -1,260 +0,0 @@
|
||||
import { Profile } from '../models/profile';
|
||||
import { MusicRecord } from '../models/music_record';
|
||||
import { Matchmaker } from '../models/matchmaker';
|
||||
import { getVersion, IDToCode, GetCounter } from '../utils';
|
||||
import { Mix } from '../models/mix';
|
||||
import { Rival } from '../models/rival';
|
||||
|
||||
export const hiscore: EPR = async (info, data, send) => {
|
||||
const records = await DB.Find<MusicRecord>(null, { collection: 'music' });
|
||||
|
||||
const version = getVersion(info);
|
||||
|
||||
const profiles = _.groupBy(
|
||||
await DB.Find<Profile>(null, { collection: 'profile' }),
|
||||
'__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(
|
||||
_.groupBy(records, r => {
|
||||
return `${r.mid}:${r.type}`;
|
||||
}),
|
||||
r => _.maxBy(r, 'score')
|
||||
).map(r => ({
|
||||
id: K.ITEM('u32', r.mid),
|
||||
ty: K.ITEM('u32', r.type),
|
||||
a_sq: K.ITEM('str', IDToCode(profiles[r.__refid][0].id)),
|
||||
a_nm: K.ITEM('str', profiles[r.__refid][0].name),
|
||||
a_sc: K.ITEM('u32', r.score),
|
||||
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),
|
||||
})),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const rival: EPR = async (info, data, send) => {
|
||||
const refid = $(data).str('refid');
|
||||
const version = parseInt(info.model.split(":")[4]);
|
||||
if (!refid) return send.deny();
|
||||
|
||||
const rivals = (
|
||||
await DB.Find<Rival>(refid, { collection: 'rival', mutual: true })
|
||||
).filter(p => p.refid != refid);
|
||||
|
||||
return send.object({
|
||||
rival: await Promise.all(
|
||||
rivals.map(async (p, index) => {
|
||||
return {
|
||||
no: K.ITEM('s16', index),
|
||||
seq: K.ITEM('str', IDToCode(p.sdvxID)),
|
||||
name: K.ITEM('str', p.name),
|
||||
music: (
|
||||
await DB.Find<MusicRecord>(p.refid, { collection: 'music' })
|
||||
).map(r => ({
|
||||
// Changes were somehow made in the order of the field for the version 2023042500
|
||||
param: K.ARRAY('u32', version < 2023042500 ? [r.mid, r.type, r.score, r.clear, r.grade] : [r.mid, r.type, r.score, r.exscore, r.clear, r.grade]),
|
||||
})),
|
||||
};
|
||||
})
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
export const saveMix: EPR = async (info, data, send) => {
|
||||
const refid = $(data).str('ref_id');
|
||||
if (!refid) return send.deny();
|
||||
|
||||
const profile = await DB.FindOne<Profile>(refid, { collection: 'profile' });
|
||||
if (!profile) return send.deny();
|
||||
|
||||
const mix = $(data).element('automation');
|
||||
|
||||
const id = await GetCounter('mix');
|
||||
let code = _.padStart(_.random(0, 999999999999).toString(), 12, '0');
|
||||
while (await DB.FindOne<Mix>({ collection: 'mix', code })) {
|
||||
code = _.padStart(_.random(0, 999999999999).toString(), 12, '0');
|
||||
}
|
||||
|
||||
const doc = await DB.Insert<Mix>({
|
||||
collection: 'mix',
|
||||
id,
|
||||
code,
|
||||
name: mix.str('mix_name'),
|
||||
creator: profile.name,
|
||||
param: mix.str('generate_param'),
|
||||
tag: mix.number('tag_bit'),
|
||||
jacket: mix.number('jacket_id'),
|
||||
});
|
||||
|
||||
return send.object({
|
||||
automation: {
|
||||
mix_id: K.ITEM('s32', id),
|
||||
mix_code: K.ITEM('str', doc.code),
|
||||
seq: K.ITEM('str', doc.code),
|
||||
mix_name: K.ITEM('str', doc.name),
|
||||
player_name: K.ITEM('str', doc.creator),
|
||||
generate_param: K.ITEM('str', doc.param),
|
||||
distribution_date: K.ITEM('u32', 19990101),
|
||||
jacket_id: K.ITEM('s32', doc.jacket),
|
||||
tag_bit: K.ITEM('s32', doc.tag),
|
||||
like_flg: K.ITEM('bool', 0),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const loadMix: EPR = async (info, data, send) => {
|
||||
const code = $(data).str('mix_code');
|
||||
|
||||
const mix = await DB.FindOne<Mix>({ collection: 'mix', code });
|
||||
if (!mix) {
|
||||
return send.object({ result: K.ITEM('s32', 1) });
|
||||
}
|
||||
|
||||
return send.object({
|
||||
automation: {
|
||||
mix_id: K.ITEM('s32', mix.id),
|
||||
mix_code: K.ITEM('str', mix.code),
|
||||
seq: K.ITEM('str', mix.code),
|
||||
mix_name: K.ITEM('str', mix.name),
|
||||
player_name: K.ITEM('str', mix.creator),
|
||||
generate_param: K.ITEM('str', mix.param),
|
||||
distribution_date: K.ITEM('u32', 19990101),
|
||||
jacket_id: K.ITEM('s32', mix.jacket),
|
||||
tag_bit: K.ITEM('s32', mix.tag),
|
||||
like_flg: K.ITEM('bool', 0),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const entryE: EPR = async (info, data, send) => {
|
||||
console.log("entry_e id: " + $(data).number('eid'))
|
||||
send.success()
|
||||
}
|
||||
|
||||
export const globalMatch: EPR = async (info, data, send) => {
|
||||
let entryData: Matchmaker = {
|
||||
collection: 'matchmaker',
|
||||
timestamp: Date.now(),
|
||||
c_ver: $(data).number('c_ver'),
|
||||
p_num: $(data).number('p_num'),
|
||||
p_rest: $(data).number('p_rest'),
|
||||
filter: $(data).number('filter'),
|
||||
mid: $(data).number('mid'),
|
||||
sec: $(data).number('sec'),
|
||||
port: $(data).number('port'),
|
||||
gip: $(data).numbers('gip'),
|
||||
lip: $(data).numbers('lip'),
|
||||
claim: $(data).number('claim'),
|
||||
entry_id: $(data).number('entry_id')
|
||||
}
|
||||
|
||||
let loggip = entryData.gip.join(".")
|
||||
let loglip = entryData.lip.join(".")
|
||||
|
||||
console.log("====================================")
|
||||
// console.log(" c_ver: " + entryData.c_ver)
|
||||
// console.log(" p_num: " + entryData.p_num) // current match player count
|
||||
// console.log(" p_rest: " + entryData.p_rest) // remaining player spaces
|
||||
// console.log(" filter: " + entryData.filter) // game mode matchmaking filter
|
||||
// console.log(" mid: " + entryData.mid)
|
||||
// console.log(" sec: " + entryData.sec) // remaining seconds
|
||||
// console.log(" port: " + entryData.port)
|
||||
// console.log(" gip: " + entryData.gip)
|
||||
// console.log(" lip: " + entryData.lip)
|
||||
// console.log(" claim: " + entryData.claim)
|
||||
// console.log("entry_id: " + entryData.entry_id)
|
||||
console.log("[" + loglip + " | " + loggip + "] Searching for online match opponents")
|
||||
let expCnt = await DB.Remove({collection: 'matchmaker', timestamp: {$lt: Date.now() - 100000}})
|
||||
console.log("[" + loglip + " | " + loggip + "] Removed " + expCnt + " expired match data.")
|
||||
|
||||
if(await DB.Count({collection: 'matchmaker', lip: entryData.lip}) === 0) {
|
||||
console.log("[" + loglip + " | " + loggip + "] Adding your info.")
|
||||
await DB.Upsert<Matchmaker>(
|
||||
{ collection: 'matchmaker', gip: entryData.gip, lip: entryData.lip},
|
||||
entryData
|
||||
)
|
||||
} else {
|
||||
console.log("[" + loglip + " | " + loggip + "] Updating info.")
|
||||
await DB.Upsert<Matchmaker>(
|
||||
{ collection: 'matchmaker', gip: entryData.gip, lip: entryData.lip},
|
||||
{ $set: {
|
||||
c_ver: entryData.c_ver,
|
||||
p_num: entryData.p_num,
|
||||
p_rest: entryData.p_rest,
|
||||
filter: entryData.filter,
|
||||
mid: entryData.mid,
|
||||
sec: entryData.sec,
|
||||
claim: entryData.claim
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if(entryData.p_rest < 1) {
|
||||
console.log("[" + loglip + " | " + loggip + "] Room is full. Halting.")
|
||||
return send.deny();
|
||||
}
|
||||
|
||||
console.log("[" + loglip + " | " + loggip + "] Searching...")
|
||||
|
||||
let opData = await DB.Find<Matchmaker>({collection: 'matchmaker', filter: entryData.filter, mid: entryData.mid, claim: entryData.claim, entry_id: entryData.entry_id})
|
||||
let opponents = {
|
||||
entry_id: K.ITEM('u32', entryData.entry_id),
|
||||
entry: opData.map(e => ({
|
||||
port: K.ITEM('u16', e.port),
|
||||
gip: K.ITEM('4u8', e.gip),
|
||||
lip: K.ITEM('4u8', e.lip)
|
||||
}))
|
||||
}
|
||||
console.log("[" + loglip + " | " + loggip + "] Players found: " + (opponents.entry.length - 1) + "")
|
||||
if(opponents.entry.length === 1) send.deny()
|
||||
else send.object(opponents)
|
||||
}
|
||||
|
||||
export const lounge: EPR = async (info, data, send) => {
|
||||
let filter = $(data).number('filter')
|
||||
await DB.Remove({collection: 'matchmaker', timestamp: {$lt: Date.now() - 100000}})
|
||||
let matches = await DB.Find<Matchmaker>({collection: 'matchmaker', filter: filter})
|
||||
if(matches.length < 1) {
|
||||
send.object({
|
||||
interval: K.ITEM('u32', 5)
|
||||
})
|
||||
} else {
|
||||
let longestWait = Math.max(...matches.map(m => m.sec))
|
||||
send.object({
|
||||
interval: K.ITEM('u32', 10),
|
||||
wait: K.ITEM('u32', longestWait)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
};
|
||||
};
|
||||
@@ -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)
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
@@ -1,821 +0,0 @@
|
||||
import { Profile } from '../models/profile';
|
||||
import { MusicRecord } from '../models/music_record';
|
||||
import { ValgeneTicket } from '../models/valgene_ticket';
|
||||
import { Skill } from '../models/skill';
|
||||
import { getVersion, IDToCode, GetCounter } from '../utils';
|
||||
import { Mix } from '../models/mix';
|
||||
import { Rival } from '../models/rival';
|
||||
import { PREGENE, COURSES6} from '../data/exg';
|
||||
import { textureslist } from '../data/webui'
|
||||
import * as fs from 'fs';
|
||||
import { PNG } from '../webui/asset/js/pngjs/png.js';
|
||||
|
||||
export const updateProfile = async (data: {
|
||||
refid: string;
|
||||
name?: string;
|
||||
appeal?: string;
|
||||
akaname?: string;
|
||||
bplSupport?: string;
|
||||
nemsys?: string;
|
||||
bgm?: string;
|
||||
subbg?: string;
|
||||
stampA?: string;
|
||||
stampB?: string;
|
||||
stampC?: string;
|
||||
stampD?: string;
|
||||
stampRA?: string;
|
||||
stampRB?: string;
|
||||
stampRC?: string;
|
||||
stampRD?: string;
|
||||
sysBG?: string;
|
||||
valgeneTicket?: string;
|
||||
skilltitle?: string;
|
||||
creatorItem?: string;
|
||||
}) => {
|
||||
if (data.refid == null) return;
|
||||
|
||||
const update: Update<Profile>['$set'] = {};
|
||||
|
||||
if (data.name && data.name.length > 0) {
|
||||
const validName = data.name
|
||||
.toUpperCase()
|
||||
.replace(/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!?#$&*\-\.\ ]/g, '')
|
||||
.slice(0, 8);
|
||||
if (validName.length > 0) update.name = validName;
|
||||
}
|
||||
|
||||
if (data.appeal && data.appeal.length > 0) {
|
||||
const validAppeal = parseInt(data.appeal);
|
||||
if (!_.isNaN(validAppeal)) update.appeal = validAppeal;
|
||||
}
|
||||
|
||||
if (data.akaname && data.akaname.length > 0) {
|
||||
const validAka = parseInt(data.akaname);
|
||||
if (!_.isNaN(validAka)) update.akaname = validAka;
|
||||
}
|
||||
|
||||
if (data.nemsys && data.nemsys.length > 0) {
|
||||
const validNemsys = parseInt(data.nemsys);
|
||||
if (!_.isNaN(validNemsys)) update.nemsys = validNemsys;
|
||||
}
|
||||
|
||||
if (data.bplSupport && data.bplSupport.length > 0) {
|
||||
const validBplSupport = parseInt(data.bplSupport);
|
||||
if (!_.isNaN(validBplSupport)) update.bplSupport = validBplSupport;
|
||||
}
|
||||
|
||||
if (data.subbg && data.subbg.length > 0) {
|
||||
const validSubbg = parseInt(data.subbg);
|
||||
if (!_.isNaN(validSubbg)) update.subbg = validSubbg;
|
||||
}
|
||||
|
||||
if (data.bgm && data.bgm.length > 0) {
|
||||
const validBGM = parseInt(data.bgm);
|
||||
if (!_.isNaN(validBGM)) update.bgm = validBGM;
|
||||
}
|
||||
|
||||
if (data.stampA && data.stampA.length > 0) {
|
||||
const validStampA = parseInt(data.stampA);
|
||||
if (!_.isNaN(validStampA)) update.stampA = validStampA;
|
||||
}
|
||||
|
||||
if (data.stampB && data.stampB.length > 0) {
|
||||
const validStampB = parseInt(data.stampB);
|
||||
if (!_.isNaN(validStampB)) update.stampB = validStampB;
|
||||
}
|
||||
|
||||
if (data.stampC && data.stampC.length > 0) {
|
||||
const validStampC = parseInt(data.stampC);
|
||||
if (!_.isNaN(validStampC)) update.stampC = validStampC;
|
||||
}
|
||||
|
||||
if (data.stampD && data.stampD.length > 0) {
|
||||
const validStampD = parseInt(data.stampD);
|
||||
if (!_.isNaN(validStampD)) update.stampD = validStampD;
|
||||
}
|
||||
|
||||
if (data.stampRA && data.stampRA.length > 0) {
|
||||
const validStampRA = parseInt(data.stampRA);
|
||||
if (!_.isNaN(validStampRA)) update.stampRA = validStampRA;
|
||||
}
|
||||
|
||||
if (data.stampRB && data.stampRB.length > 0) {
|
||||
const validStampRB = parseInt(data.stampRB);
|
||||
if (!_.isNaN(validStampRB)) update.stampRB = validStampRB;
|
||||
}
|
||||
|
||||
if (data.stampRC && data.stampRC.length > 0) {
|
||||
const validStampRC = parseInt(data.stampRC);
|
||||
if (!_.isNaN(validStampRC)) update.stampRC = validStampRC;
|
||||
}
|
||||
|
||||
if (data.stampRD && data.stampRD.length > 0) {
|
||||
const validStampRD = parseInt(data.stampRD);
|
||||
if (!_.isNaN(validStampRD)) update.stampRD = validStampRD;
|
||||
}
|
||||
|
||||
if (data.sysBG && data.sysBG.length > 0) {
|
||||
const validSysBG = parseInt(data.sysBG);
|
||||
if (!_.isNaN(validSysBG)) update.sysBG = validSysBG;
|
||||
}
|
||||
|
||||
if (data.creatorItem && data.creatorItem.length > 0) {
|
||||
const validCreatorItem = parseInt(data.creatorItem);
|
||||
if (!_.isNaN(validCreatorItem)) update.creatorItem = validCreatorItem;
|
||||
}
|
||||
|
||||
await DB.Update<Profile>(
|
||||
data.refid,
|
||||
{ collection: 'profile' },
|
||||
{ $set: update }
|
||||
);
|
||||
|
||||
if (parseInt(data.skilltitle) >= 0) {
|
||||
await DB.Update<Skill>(
|
||||
data.refid,
|
||||
{ collection: 'skill' },
|
||||
{ $set: {
|
||||
name: parseInt(data.skilltitle)
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (parseInt(data.valgeneTicket) >= 0) {
|
||||
await DB.Upsert<ValgeneTicket>(
|
||||
data.refid,
|
||||
{ collection: 'valgene_ticket' },
|
||||
{ $set: {
|
||||
ticketNum: parseInt(data.valgeneTicket),
|
||||
limitDate: Date.parse('31 Dec 2099 23:59:59 GMT')
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const updateMix = async (data: {
|
||||
code: string;
|
||||
name?: string;
|
||||
creator?: string;
|
||||
}) => {
|
||||
const update: Update<Mix>['$set'] = {};
|
||||
|
||||
if (data.name && data.name.length > 0) {
|
||||
if (data.name.length > 0) update.name = data.name;
|
||||
}
|
||||
|
||||
if (data.creator && data.creator.length > 0) {
|
||||
// const validCreator = data.creator
|
||||
// .toUpperCase()
|
||||
// .replace(/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!?#$&*\-\.\ ]/g, '')
|
||||
// .slice(0, 8);
|
||||
if (data.creator.length > 0) update.creator = data.creator;
|
||||
}
|
||||
|
||||
await DB.Update<Mix>(
|
||||
{ collection: 'mix', code: data.code },
|
||||
{ $set: update }
|
||||
);
|
||||
};
|
||||
|
||||
export const importMix = async (data: { json: string }) => {
|
||||
if (data.json.startsWith('`')) {
|
||||
data.json = data.json.slice(1);
|
||||
}
|
||||
|
||||
if (data.json.endsWith('`')) {
|
||||
data.json = data.json.slice(0, data.json.length - 1);
|
||||
}
|
||||
|
||||
const mix: any[] = JSON.parse(data.json);
|
||||
|
||||
let code = mix[0];
|
||||
while (await DB.FindOne<Mix>({ collection: 'mix', code })) {
|
||||
code = _.padStart(_.random(0, 999999999999).toString(), 12, '0');
|
||||
}
|
||||
|
||||
const id = await GetCounter('mix');
|
||||
const musics = mix.slice(9);
|
||||
|
||||
if (musics.length % 2 !== 0) return;
|
||||
|
||||
const mdata = [];
|
||||
|
||||
for (let i = 0; i < musics.length; i += 2) {
|
||||
mdata.push({
|
||||
grade: musics[i + 1],
|
||||
id: musics[i],
|
||||
});
|
||||
}
|
||||
|
||||
await DB.Insert<Mix>({
|
||||
collection: 'mix',
|
||||
code,
|
||||
id,
|
||||
name: mix[1],
|
||||
creator: mix[2],
|
||||
param: `{ "dbVer" : "${mix[3]
|
||||
}", "gene" : { "params" : "{ \\"minorVer\\" : \\"${mix[4]
|
||||
}\\", \\"seed\\" : ${mix[5]} }", "ver" : "${mix[6]
|
||||
}" }, "musics" : ${JSON.stringify(mdata)}, "voxdj" : { "params" : "${mix[7]
|
||||
}", "ver" : "${mix[8]}" } }`,
|
||||
jacket: 0,
|
||||
tag: 1,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteMix = async (data: { code: string }) => {
|
||||
await DB.Remove<Mix>({ collection: 'mix', code: data.code });
|
||||
};
|
||||
|
||||
export const copyResourcesFromGame = async (data: {}, send: WebUISend) => {
|
||||
let mdbJsonFix = [];
|
||||
let mdbJsonFixFinal;
|
||||
let newJsonSongs = [];
|
||||
let newVersionSongs = [];
|
||||
let newXCDSongs = [];
|
||||
let newNemsysData = []
|
||||
let newAPCardData = []
|
||||
let newSubBGData = []
|
||||
let newBGMData = []
|
||||
let newChatStampData = []
|
||||
let newValgeneItemFiles = []
|
||||
let newAkanames = []
|
||||
let runErrors = []
|
||||
let resourceJsonData = JSON.parse(U.DecodeString(await IO.ReadFile('webui/asset/json/data.json'), 'utf8'))
|
||||
let apCardJsonData = JSON.parse(U.DecodeString(await IO.ReadFile('webui/asset/json/appeal.json'), 'utf8'))
|
||||
|
||||
// Get new music data from music_db.xml
|
||||
console.log('Getting new music_db info')
|
||||
if(IO.Exists(U.GetConfig('sdvx_eg_root_dir') + "/data/others/music_db.xml")) {
|
||||
let ea3Config = []
|
||||
let version = ''
|
||||
let mdb = U.parseXML(U.DecodeString(await IO.ReadFile(U.GetConfig('sdvx_eg_root_dir') + "/data/others/music_db.xml"), "shift_jis"), false)
|
||||
|
||||
if(IO.Exists(U.GetConfig('sdvx_eg_root_dir') + "/prop/ea3-config.xml")) {
|
||||
console.log("Reading ea3-config.xml")
|
||||
ea3Config = U.parseXML(U.DecodeString(await IO.ReadFile(U.GetConfig('sdvx_eg_root_dir') + "/prop/ea3-config.xml"), "shift_jis"), false)
|
||||
version = ea3Config['ea3']['soft']['ext']['@content'];
|
||||
} else if(IO.Exists(U.GetConfig('sdvx_eg_root_dir') + "/prop/ea3-ident.xml")) {
|
||||
console.log("Reading ea3-ident.xml")
|
||||
ea3Config = U.parseXML(U.DecodeString(await IO.ReadFile(U.GetConfig('sdvx_eg_root_dir') + "/prop/ea3-ident.xml"), "shift_jis"), false)
|
||||
version = ea3Config['ea3_conf']['soft']['ext']['@content'];
|
||||
}
|
||||
let prevAssetMdb = []
|
||||
if(IO.Exists('webui/asset/json/music_db.json')) {
|
||||
prevAssetMdb = JSON.parse(U.DecodeString(await IO.ReadFile('webui/asset/json/music_db.json'), 'utf8'))
|
||||
}
|
||||
|
||||
mdb.mdb.music.forEach(musicValue => {
|
||||
if(Object.keys(prevAssetMdb).length > 0) {
|
||||
if(prevAssetMdb['mdb']['music'].find(item => parseInt(item['@id']) == parseInt(musicValue['@attr'].id)) == undefined) {
|
||||
console.log("New song added to json: " + musicValue.info.title_name['@content'] + " (" + musicValue.info.distribution_date['@content'] + ")")
|
||||
newJsonSongs.push([ musicValue['@attr'].id, '[' + musicValue.info.distribution_date['@content'] + ' | ' + musicValue['@attr'].id + '] ' + musicValue.info.title_name['@content']])
|
||||
}
|
||||
|
||||
if(prevAssetMdb['mdb']['music'].find(item => (parseInt(item['@id']) == parseInt(musicValue['@attr'].id) && parseInt(item['info']['inf_ver']['#text']) === 0)) != undefined) {
|
||||
if(musicValue.info.inf_ver['@content'] == '6') {
|
||||
console.log("New XCD difficulty song: " + musicValue.info.title_name['@content'] + " (" + musicValue.info.distribution_date['@content'] + ")")
|
||||
newXCDSongs.push([ musicValue['@attr'].id, '[' + musicValue.info.distribution_date['@content'] + ' | ' + musicValue['@attr'].id + '] ' + musicValue.info.title_name['@content']])
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log("New song added to json: " + musicValue.info.title_name['@content'] + " (" + musicValue.info.distribution_date['@content'] + ")")
|
||||
newJsonSongs.push([ musicValue['@attr'].id, '[' + musicValue.info.distribution_date['@content'] + ' | ' + musicValue['@attr'].id + '] ' + musicValue.info.title_name['@content']])
|
||||
|
||||
if(musicValue.info.inf_ver['@content'] == '6') {
|
||||
console.log("New XCD difficulty song: " + musicValue.info.title_name['@content'] + " (" + musicValue.info.distribution_date['@content'] + ")")
|
||||
newXCDSongs.push([ musicValue['@attr'].id, '[' + musicValue.info.distribution_date['@content'] + ' | ' + musicValue['@attr'].id + '] ' + musicValue.info.title_name['@content']])
|
||||
}
|
||||
}
|
||||
|
||||
if(parseInt(musicValue.info.distribution_date['@content'][0]) >= parseInt(version.substring(0,8))) {
|
||||
console.log("Found new song for version " + version + ": " + musicValue.info.title_name['@content'] + " (" + musicValue.info.distribution_date['@content'] + ")");
|
||||
newVersionSongs.push([ musicValue['@attr'].id, '[' + musicValue.info.distribution_date['@content'] + ' | ' + musicValue['@attr'].id + '] ' + musicValue.info.title_name['@content']])
|
||||
}
|
||||
|
||||
mdbJsonFix.push({
|
||||
'@id': musicValue['@attr'].id,
|
||||
'info': {
|
||||
'title_name': musicValue.info.title_name['@content'],
|
||||
'version': {
|
||||
'@__type': 'u8',
|
||||
'#text': musicValue.info.version['@content'][0].toString()
|
||||
},
|
||||
'inf_ver': {
|
||||
'@__type': 'u8',
|
||||
'#text': musicValue.info.inf_ver['@content'][0].toString()
|
||||
},
|
||||
'distribution_date' : {
|
||||
'#text': musicValue.info.distribution_date['@content'][0]
|
||||
}
|
||||
},
|
||||
'difficulty': {
|
||||
'novice': {
|
||||
'difnum': {
|
||||
'@__type': 'u8',
|
||||
'#text': musicValue.difficulty.novice.difnum['@content'][0].toString()
|
||||
}
|
||||
},
|
||||
'advanced': {
|
||||
'difnum': {
|
||||
'@__type': 'u8',
|
||||
'#text': musicValue.difficulty.advanced.difnum['@content'][0].toString()
|
||||
}
|
||||
},
|
||||
'exhaust': {
|
||||
'difnum': {
|
||||
'@__type': 'u8',
|
||||
'#text': musicValue.difficulty.exhaust.difnum['@content'][0].toString()
|
||||
}
|
||||
},
|
||||
'maximum': {
|
||||
'difnum': {
|
||||
'@__type': 'u8',
|
||||
'#text': musicValue.difficulty.maximum != undefined ? musicValue.difficulty.maximum.difnum['@content'][0].toString() : '0'
|
||||
}
|
||||
},
|
||||
'infinite': {
|
||||
'difnum': {
|
||||
'@__type': 'u8',
|
||||
'#text': musicValue.difficulty.infinite != undefined ? musicValue.difficulty.infinite.difnum['@content'][0].toString() : '0'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
mdbJsonFixFinal = {
|
||||
'mdb': {
|
||||
'version': version,
|
||||
'music': mdbJsonFix
|
||||
}
|
||||
};
|
||||
IO.WriteFile('webui/asset/json/music_db.json', JSON.stringify(mdbJsonFixFinal, null, 4));
|
||||
} else {
|
||||
console.log('Error reading music_db.xml. Check your "Exceed Gear Data Directory" config.')
|
||||
runErrors.push('[music_db] Error reading music_db.xml. Check your "Exceed Gear Data Directory" config.')
|
||||
}
|
||||
|
||||
// Copying new nemsys files from gamedata
|
||||
console.log("Copying new nemsys files from gamedata")
|
||||
if(IO.Exists(U.GetConfig('sdvx_eg_root_dir') + "/data/graphics/game_nemsys")) {
|
||||
let nemsysFiles = await IO.ReadDir(U.GetConfig('sdvx_eg_root_dir') + "/data/graphics/game_nemsys")
|
||||
for await (const nemsys of nemsysFiles) {
|
||||
let fileToWrite = await IO.ReadFile(U.GetConfig('sdvx_eg_root_dir') + "/data/graphics/game_nemsys/" + nemsys.name)
|
||||
if(!IO.Exists('webui/asset/nemsys/' + nemsys.name.substring(0, (nemsys.name.length - 4)) + ".png") && !IO.Exists('webui/asset/nemsys/' + nemsys.name.substring(0, (nemsys.name.length - 4)) + ".jpg")) {
|
||||
console.log("[nemsys] copying " + nemsys.name)
|
||||
IO.WriteFile('webui/asset/nemsys/' + nemsys.name, fileToWrite)
|
||||
newNemsysData.push(nemsys.name)
|
||||
}
|
||||
|
||||
if(nemsys.name.match(/([0-9]+)/g) != undefined) {
|
||||
let nemsysId = parseInt(nemsys.name.match(/([0-9]+)/g)[0])
|
||||
if(nemsysId && ![8, 9, 10, 11].includes(nemsysId) && resourceJsonData.nemsys.find(nem => nem.value == nemsysId) == undefined) {
|
||||
console.log("[nemsys] adding to json: " + nemsys.name)
|
||||
resourceJsonData.nemsys.push({"value": nemsysId, "name": nemsys.name})
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('Error reading nemsys directory. Check your "Exceed Gear Data Directory" config.')
|
||||
runErrors.push('[nemsys] Error reading nemsys directory. Check your "Exceed Gear Data Directory" config.')
|
||||
}
|
||||
|
||||
// Copying new subbg files from gamedata
|
||||
console.log("Copying new subbg files from gamedata")
|
||||
if(IO.Exists(U.GetConfig('sdvx_eg_root_dir') + "/data/graphics/submonitor_bg")) {
|
||||
let subBGFiles = await IO.ReadDir(U.GetConfig('sdvx_eg_root_dir') + "/data/graphics/submonitor_bg")
|
||||
for await (const subbg of subBGFiles) {
|
||||
if (subbg.name.match(/^(subbg[_0-9]*)(\.png|\.jpg|\.mp4)/g)) {
|
||||
let fileToWrite = await IO.ReadFile(U.GetConfig('sdvx_eg_root_dir') + "/data/graphics/submonitor_bg/" + subbg.name)
|
||||
if(!IO.Exists('webui/asset/submonitor_bg/' + subbg.name.substring(0, (subbg.name.length - 4)) + ".png") && !IO.Exists('webui/asset/submonitor_bg/' + subbg.name.substring(0, (subbg.name.length - 4)) + ".jpg") && !IO.Exists('webui/asset/submonitor_bg/' + subbg.name.substring(0, (subbg.name.length - 4)) + ".mp4")) {
|
||||
console.log("[subbg] copying " + subbg.name)
|
||||
IO.WriteFile('webui/asset/submonitor_bg/' + subbg.name, fileToWrite)
|
||||
newSubBGData.push(subbg.name)
|
||||
}
|
||||
|
||||
let subbgId = parseInt(subbg.name.match(/([0-9]+)/g)[0])
|
||||
if(subbgId) {
|
||||
let subbgName = subbg.name
|
||||
let subbgType = 'normal'
|
||||
let foundSubbg = resourceJsonData.subbg.findIndex(subbg => subbg.value === subbgId)
|
||||
|
||||
if(subbg.name.match(/(subbg_[0-9]+_[0-9]+)/g)) {
|
||||
subbgName = subbg.name.match(/(subbg_[0-9]+)/g)[0]
|
||||
subbgType = 'slideshow'
|
||||
} else if(subbg.name.includes('.mp4')) subbgType = 'video'
|
||||
|
||||
if(foundSubbg == -1) {
|
||||
console.log("[subbg] adding " + subbgId + " - " + subbgName + " (" + subbgType + ")")
|
||||
resourceJsonData.subbg.push({"value": subbgId, "type": subbgType, "name": subbgName})
|
||||
} else {
|
||||
resourceJsonData.subbg[foundSubbg] = {"value": subbgId, "type": subbgType, "name": subbgName}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('Error reading submonitor_bg directory. Check your "Exceed Gear Data Directory" config.')
|
||||
runErrors.push('[submonitor_bg] Error reading submonitor_bg directory. Check your "Exceed Gear Data Directory" config.')
|
||||
}
|
||||
|
||||
// Copying new bgm files from gamedata
|
||||
console.log("Copying new bgm files from gamedata")
|
||||
if(IO.Exists(U.GetConfig('sdvx_eg_root_dir') + "/data/sound/custom")) {
|
||||
let bgmFiles = await IO.ReadDir(U.GetConfig('sdvx_eg_root_dir') + "/data/sound/custom")
|
||||
for await (const bgm of bgmFiles) {
|
||||
if (bgm.name.match(/(\.s3p)/g)) {
|
||||
let folderName = bgm.name.match(/(custom|special)_([0-9]*)/g)[0]
|
||||
if(folderName != '') {
|
||||
if(!IO.Exists('webui/asset/audio/' + folderName)) {
|
||||
console.log("[bgm] extracting audio files from " + bgm.name + ".")
|
||||
|
||||
// Thanks to mon/s3p_extract on GitHub.
|
||||
let bufOffset = 4
|
||||
let s3pBuffer = await IO.ReadFile(U.GetConfig('sdvx_eg_root_dir') + "/data/sound/custom/" + bgm.name, {flag: 'r'})
|
||||
let fileMagic = s3pBuffer.toString('utf8', 0, 4)
|
||||
let fileEntries = s3pBuffer.readInt32LE(bufOffset)
|
||||
let entries = []
|
||||
bufOffset += 4
|
||||
for(let entryCtr = 0; entryCtr < fileEntries; entryCtr++) {
|
||||
entries.push(
|
||||
{
|
||||
offset: s3pBuffer.readInt32LE(bufOffset),
|
||||
length: s3pBuffer.readInt32LE(bufOffset + 4)
|
||||
}
|
||||
)
|
||||
bufOffset += 8
|
||||
}
|
||||
|
||||
let filename = 0
|
||||
entries.forEach(entry => {
|
||||
let magic = s3pBuffer.toString('utf8', entry.offset, entry.offset + 4)
|
||||
let fileStart = s3pBuffer.readInt32LE(entry.offset + 4)
|
||||
let arrayBuffer = s3pBuffer.buffer.slice(entry.offset, entry.offset + entry.length)
|
||||
IO.WriteFile('webui/asset/audio/' + folderName + '/' + filename + '.wma', s3pBuffer.toString('binary', entry.offset + fileStart, entry.offset + entry.length), {encoding: 'binary'})
|
||||
filename++
|
||||
})
|
||||
}
|
||||
|
||||
let bgmId = parseInt(bgm.name.match(/(?<=(custom|special)_)([0-9]*)/g)[0])
|
||||
if(bgmId && resourceJsonData.bgm.find(bgm => bgm.value == bgmId) == undefined) {
|
||||
console.log("[bgm] adding to json: " + bgmId + " - " + bgm.name)
|
||||
newBGMData.push(bgm.name)
|
||||
resourceJsonData.bgm.push({"value": bgmId, "name": bgm.name})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('Error reading BGM directory. Check your "Exceed Gear Data Directory" config.')
|
||||
runErrors.push('[BGM] Error reading BGM directory. Check your "Exceed Gear Data Directory" config.')
|
||||
}
|
||||
|
||||
// Copying new chat stamps from gamedata
|
||||
console.log("Copying new chat stamps from gamedata")
|
||||
if(IO.Exists(U.GetConfig('sdvx_eg_root_dir') + "/data/others/chat_stamp.xml")) {
|
||||
let chatStampData = U.parseXML(U.DecodeString(await IO.ReadFile(U.GetConfig('sdvx_eg_root_dir') + "/data/others/chat_stamp.xml"), "shift_jis"), false)
|
||||
// console.log(JSON.stringify(chatStampData.chat_stamp_data))
|
||||
for(const chatStamp of chatStampData.chat_stamp_data.info) {
|
||||
if(resourceJsonData.stamp.find(stamp => stamp['value'] === chatStamp.id['@content'][0]) == undefined) {
|
||||
let stampTitle = chatStamp.title['@content'] + " " + (parseInt(chatStamp.id['@content'][0]) % 4 !== 0 ? parseInt(chatStamp.id['@content'][0]) % 4 : 4)
|
||||
console.log("[chat_stamp] " + chatStamp.id['@content'][0] + " - " + stampTitle)
|
||||
resourceJsonData.stamp.push({"value": chatStamp.id['@content'][0], "name": stampTitle})
|
||||
newChatStampData.push(chatStamp.id['@content'][0] + ": " + chatStamp.filename['@content'])
|
||||
}
|
||||
if(!IO.Exists('webui/asset/chat_stamp/' + chatStamp.filename['@content'] + '.png') && !IO.Exists('webui/asset/chat_stamp/' + chatStamp.filename['@content'] + '.png')) {
|
||||
console.log("[chat_stamp] copying " + chatStamp.filename['@content'] + '.png')
|
||||
let fileToWrite = await IO.ReadFile(U.GetConfig('sdvx_eg_root_dir') + "/data/graphics/chat_stamp/" + chatStamp.filename['@content'] + ".png")
|
||||
IO.WriteFile('webui/asset/chat_stamp/' + chatStamp.filename['@content'] + '.png', fileToWrite)
|
||||
}
|
||||
}
|
||||
resourceJsonData.stamp.sort(function(a, b){return a.value - b.value})
|
||||
} else {
|
||||
console.log('Error reading chat stamp xml file. Check your "Exceed Gear Data Directory" config.')
|
||||
runErrors.push('[chat stamp] Error reading chat stamp xml file. Check your "Exceed Gear Data Directory" config.')
|
||||
}
|
||||
|
||||
// Copying new valgene_item files from gamedata
|
||||
console.log("Copying new valgene_item files from gamedata")
|
||||
if(IO.Exists(U.GetConfig('sdvx_eg_root_dir') + "/data/graphics/valgene_item")) {
|
||||
let valgeneItemFiles = await IO.ReadDir(U.GetConfig('sdvx_eg_root_dir') + "/data/graphics/valgene_item")
|
||||
for await (const valgeneItem of valgeneItemFiles) {
|
||||
if (valgeneItem.name.substring(valgeneItem.name.length-4, valgeneItem.name.length).match(/(\.png|\.jpg)/g)) {
|
||||
let fileToWrite = await IO.ReadFile(U.GetConfig('sdvx_eg_root_dir') + "/data/graphics/valgene_item/" + valgeneItem.name)
|
||||
if(!IO.Exists('webui/asset/valgene_item/' + valgeneItem.name.substring(0, (valgeneItem.name.length - 4)) + ".png") && !IO.Exists('webui/asset/valgene_item/' + valgeneItem.name.substring(0, (valgeneItem.name.length - 4)) + ".jpg")) {
|
||||
console.log("[valgene_item] copying " + valgeneItem.name)
|
||||
IO.WriteFile('webui/asset/valgene_item/' + valgeneItem.name, fileToWrite)
|
||||
newValgeneItemFiles.push(valgeneItem.name)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('Error reading valgene_item directory. Check your "Exceed Gear Data Directory" config.')
|
||||
runErrors.push('[valgene_item] Error reading valgene_item directory. Check your "Exceed Gear Data Directory" config.')
|
||||
}
|
||||
|
||||
// Copying new akanames from gamedata
|
||||
console.log("Copying new appeal titles from gamedata")
|
||||
// resourceJsonData.akaname = []
|
||||
if(IO.Exists(U.GetConfig('sdvx_eg_root_dir') + "/data/others/akaname_parts.xml")) {
|
||||
let akanameData = U.parseXML(U.DecodeString(await IO.ReadFile(U.GetConfig('sdvx_eg_root_dir') + "/data/others/akaname_parts.xml"), "shift_jis"), false)
|
||||
for(const akaname of akanameData.akaname_parts.part) {
|
||||
if(resourceJsonData.akaname.find(aka => aka.value === akaname['@attr'].id) === undefined) {
|
||||
let akanameFmtd = ('@content' in akaname.word) ? akaname.word['@content'].replace(/(\[[A-z0-9:,\/\]]*)/g,'') : ''
|
||||
console.log("[appeal title] adding " + akaname['@attr'].id + " - " + akanameFmtd)
|
||||
resourceJsonData.akaname.push({"value": akaname['@attr'].id, "name": akanameFmtd})
|
||||
newAkanames.push(akaname['@attr'].id + ": " + akanameFmtd )
|
||||
}
|
||||
}
|
||||
resourceJsonData.akaname.sort(function(a, b){return parseInt(a.value) - parseInt(b.value)})
|
||||
} else {
|
||||
console.log('Error reading akaname xml file. Check your "Exceed Gear Data Directory" config.')
|
||||
runErrors.push('[akaname] Error reading akaname xml file. Check your "Exceed Gear Data Directory" config.')
|
||||
}
|
||||
|
||||
// Copying new appeal card data from gamedata
|
||||
console.log("Copying new appeal card data from gamedata")
|
||||
if(IO.Exists(U.GetConfig('sdvx_eg_root_dir') + "/data/others/appeal_card.xml")) {
|
||||
let apCardData = U.parseXML(U.DecodeString(await IO.ReadFile(U.GetConfig('sdvx_eg_root_dir') + "/data/others/appeal_card.xml"), "shift_jis"), false)
|
||||
for(const apCard of apCardData.appeal_card_data.card) {
|
||||
if(apCardJsonData.appeal_card_data.card.find(ap => ap['@id'] === apCard['@attr'].id) == undefined) {
|
||||
console.log("[ap_card] adding to json: " + apCard['@attr'].id + " - " + apCard.info['title']['@content'])
|
||||
apCardJsonData.appeal_card_data.card.push({"@id": apCard['@attr'].id, "info": {"texture": apCard.info['texture']['@content'], "title": apCard.info['title']['@content']}})
|
||||
newAPCardData.push(apCard['@attr'].id + ": " + apCard.info['texture']['@content'] + "(" + apCard.info['title']['@content'] + ")")
|
||||
}
|
||||
if(!IO.Exists('webui/asset/ap_card/' + apCard.info['texture']['@content'] + '.png') && !IO.Exists('webui/asset/ap_card/' + apCard.info['texture']['@content'] + '.jpg')) {
|
||||
console.log("[ap_card] copying " + apCard.info['texture']['@content'] + '.png')
|
||||
let fileToWrite = await IO.ReadFile(U.GetConfig('sdvx_eg_root_dir') + "/data/graphics/ap_card/" + apCard.info['texture']['@content'] + ".png")
|
||||
IO.WriteFile('webui/asset/ap_card/' + apCard.info['texture']['@content'] + '.png', fileToWrite)
|
||||
}
|
||||
}
|
||||
apCardJsonData.appeal_card_data.card.sort(function(a, b){return parseInt(a['@id']) - parseInt(b['@id'])})
|
||||
} else {
|
||||
console.log('Error reading appeal card xml file. Check your "Exceed Gear Data Directory" config.')
|
||||
runErrors.push('[appeal card] Error reading appeal card xml file. Check your "Exceed Gear Data Directory" config.')
|
||||
}
|
||||
|
||||
await IO.WriteFile('webui/asset/json/data.json', JSON.stringify(resourceJsonData, null, 4))
|
||||
await IO.WriteFile('webui/asset/json/appeal.json', JSON.stringify(apCardJsonData, null, 4))
|
||||
|
||||
// Extract textures from ifs files using pngjs. Massive thanks to https://github.com/mon/ifstools
|
||||
console.log("Extracting textures from IFS files")
|
||||
let ifsSuccess = []
|
||||
for(let listIter = 0; listIter < textureslist.length; listIter++) {
|
||||
let manifestJson = {}
|
||||
let bufOffset = 0
|
||||
let magic = '6CAD8F89'
|
||||
console.log(textureslist[listIter]['file'] + ":")
|
||||
let ifsBuffer = await IO.ReadFile(U.GetConfig('sdvx_eg_root_dir') + textureslist[listIter].file, {flag: 'r'})
|
||||
if(!fs.existsSync('plugins/sdvx@asphyxia/webui/asset/' + textureslist[listIter].asset_folder)) {
|
||||
fs.mkdirSync('plugins/sdvx@asphyxia/webui/asset/' + textureslist[listIter].asset_folder)
|
||||
}
|
||||
let header = Buffer.from(ifsBuffer.buffer.slice(0, 36))
|
||||
let sig = header.readUInt32BE().toString(16).toUpperCase()
|
||||
bufOffset += 4
|
||||
if(sig === magic) {
|
||||
bufOffset += 12
|
||||
let manifest_end = ifsBuffer.readUInt32BE(bufOffset)
|
||||
bufOffset += 4
|
||||
let md5_hash = ifsBuffer.toString('hex', bufOffset, bufOffset + 16)
|
||||
bufOffset += 16
|
||||
if(md5_hash === textureslist[listIter].md5) {
|
||||
for(let texIter = 0; texIter < textureslist[listIter]['textures'].length; texIter++) {
|
||||
let tdFileName = textureslist[listIter]['textures'][texIter][0]
|
||||
let tdOffset = parseInt(textureslist[listIter]['textures'][texIter][1].toString())
|
||||
let tdSize = parseInt(textureslist[listIter]['textures'][texIter][2].toString())
|
||||
let tdUvrect = textureslist[listIter]['textures'][texIter][3]
|
||||
let tdImgRect = textureslist[listIter]['textures'][texIter][4]
|
||||
|
||||
let imgBufferHead = Buffer.from(ifsBuffer.buffer.slice(manifest_end + tdOffset, manifest_end + tdOffset + 8))
|
||||
let imgBufferHeadOff = 0
|
||||
let imgBuffer = Buffer.from(ifsBuffer.buffer.slice(manifest_end + tdOffset + 8, manifest_end + tdOffset + tdSize))
|
||||
let imgBufferOff = 0
|
||||
let imgUncompressedSize = imgBufferHead.readUInt32BE(imgBufferHeadOff)
|
||||
imgBufferHeadOff += 4
|
||||
let imgCompressedSize = imgBufferHead.readUInt32BE(imgBufferHeadOff)
|
||||
imgBufferHeadOff += 4
|
||||
|
||||
// Decompression algorithm & code from ifstools/handlers/lz77.py
|
||||
let decompressed = []
|
||||
let contLoop = true
|
||||
let diff, flag, w, position, length
|
||||
while(contLoop) {
|
||||
flag = imgBuffer.readUInt8(imgBufferOff)
|
||||
imgBufferOff++
|
||||
for(let i = 0; i < 8; i++){
|
||||
if (((flag >> i) & 1) === 1) {
|
||||
decompressed.push(imgBuffer.readUInt8(imgBufferOff))
|
||||
imgBufferOff++
|
||||
}
|
||||
else {
|
||||
w = imgBuffer.readUInt16BE(imgBufferOff)
|
||||
imgBufferOff+=2
|
||||
position = (w >> 4)
|
||||
length = (w & 0x0F) + 3
|
||||
if(position === 0) {
|
||||
contLoop = false
|
||||
break;
|
||||
}
|
||||
if(position > decompressed.length) {
|
||||
diff = 0
|
||||
diff = position - decompressed.length
|
||||
diff = Math.min(diff, length)
|
||||
for(let e2p = 0; e2p < diff; e2p++) {
|
||||
decompressed.push(0)
|
||||
}
|
||||
length -= diff
|
||||
}
|
||||
if (-position+length < 0) {
|
||||
decompressed.push(...decompressed.slice(decompressed.length + (-position), decompressed.length + (-position+length)))
|
||||
}
|
||||
else {
|
||||
for(let loop = 0; loop < length; loop++) {
|
||||
decompressed.push(decompressed[decompressed.length + (-position)])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Swap red and blue data (RGBA -> BGRA)
|
||||
if(decompressed.length === imgUncompressedSize) {
|
||||
for(let decCtr = 0; decCtr < decompressed.length; decCtr += 4) {
|
||||
decompressed[decCtr + 2] = [decompressed[decCtr], decompressed[decCtr] = decompressed[decCtr + 2]][0];
|
||||
}
|
||||
|
||||
let pngf = new PNG({
|
||||
width: Math.floor(tdImgRect[1]/2) - Math.floor(tdImgRect[0]/2),
|
||||
height: Math.floor(tdImgRect[3]/2) - Math.floor(tdImgRect[2]/2),
|
||||
bitDepth: 8,
|
||||
colorType: 6,
|
||||
inputHasAlpha: true
|
||||
})
|
||||
|
||||
pngf.data = Buffer.from(decompressed)
|
||||
const outputStream = await fs.createWriteStream('plugins/sdvx@asphyxia/webui/asset/' + textureslist[listIter].asset_folder + '/' + tdFileName);
|
||||
await pngf.pack().pipe(outputStream);
|
||||
console.log(' - ' + tdFileName + ' created successfully.');
|
||||
ifsSuccess.push(textureslist[listIter].file + ' - ' + tdFileName)
|
||||
} else {
|
||||
console.log("Decompression mismatch.")
|
||||
runErrors.push('[ifs] decompression mismatch for ' + textureslist[listIter]['file'] + '/' + tdFileName)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('MD5 mismatch.')
|
||||
runErrors.push('[ifs] MD5 mismatch - ' + textureslist[listIter].file)
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log('IFS file unsupported/invalid.')
|
||||
runErrors.push('[ifs] IFS file "' + textureslist[listIter].file + '" unsupported/invalid.')
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Updating course_data.json")
|
||||
let courseDataUpdateSuccess = false
|
||||
let courseData = JSON.parse(U.DecodeString(await IO.ReadFile('webui/asset/json/course_data.json'), 'utf8'))
|
||||
for(let cIter = 0; cIter < courseData.courseData.length; cIter++) {
|
||||
if(courseData.courseData[cIter].version === 6) {
|
||||
courseData.courseData[cIter].info = COURSES6
|
||||
courseDataUpdateSuccess = true
|
||||
}
|
||||
}
|
||||
if(courseDataUpdateSuccess === false) runErrors.push('[course_data] Update unsuccessful.')
|
||||
|
||||
await IO.WriteFile('webui/asset/json/course_data.json', JSON.stringify(courseData, null, 4))
|
||||
|
||||
send.json(
|
||||
{
|
||||
status: 'ok',
|
||||
course: courseDataUpdateSuccess,
|
||||
ifs: ifsSuccess,
|
||||
akaname: newAkanames,
|
||||
nemsys: newNemsysData,
|
||||
apCard: newAPCardData,
|
||||
subbg: newSubBGData,
|
||||
bgm: newBGMData,
|
||||
chatStamp: newChatStampData,
|
||||
valgeneItemFiles: newValgeneItemFiles,
|
||||
versionSongs: newVersionSongs.sort((a, b) => a[0] - b[0]),
|
||||
jsonSongs: newJsonSongs.sort((a, b) => a[0] - b[0]),
|
||||
xcdSongs: newXCDSongs.sort((a, b) => a[0] - b[0]),
|
||||
errors: runErrors
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
export const getRivalScores = async (data: { rivalId: string; refid: string; }, send: WebUISend) => {
|
||||
let rival = await DB.FindOne<Rival>(data.refid, {collection: 'rival', refid: data.rivalId})
|
||||
send.json({
|
||||
rival: await DB.FindOne<Profile>(data.rivalId, {collection: 'profile'}),
|
||||
yourScores: await DB.Find<MusicRecord>(data.refid, { collection: 'music' }),
|
||||
rivalScores: await DB.Find<MusicRecord>(rival.refid, { collection: 'music' })
|
||||
})
|
||||
}
|
||||
|
||||
export const addRival = async (data: { rivalId: string; refid: string; }, send: WebUISend) => {
|
||||
let you = await DB.FindOne<Profile>(data.refid, {collection: 'profile'})
|
||||
let rival = await DB.FindOne<Profile>(data.rivalId, {collection: 'profile'})
|
||||
|
||||
let checkMutual = (await DB.Count<Rival>(data.rivalId, {collection: 'rival', refid: data.refid}) > 0)
|
||||
if(await DB.Count<Rival>(data.refid, {collection: 'rival', refid: data.rivalId}) === 0) {
|
||||
if(checkMutual) {
|
||||
DB.Upsert(data.rivalId, {"collection": "rival", "sdvxID": you.id, "refid": data.refid, "name": you.name}, {$set: {"mutual": checkMutual}})
|
||||
}
|
||||
DB.Insert(data.refid, {"collection": "rival", "sdvxID": rival.id, "refid": data.rivalId, "name": rival.name, "mutual": checkMutual})
|
||||
send.json({
|
||||
"msg": "Successfully added profile to rival. In order for your rivals to appear in-game, they need to add you as their rival as well."
|
||||
})
|
||||
} else {
|
||||
if(checkMutual) {
|
||||
DB.Upsert(data.rivalId, {"collection": "rival", "sdvxID": you.id, "refid": data.refid, "name": you.name}, {$set: {"mutual": false}})
|
||||
}
|
||||
DB.Remove(data.refid, {"collection": "rival", "sdvxID": rival.id, "refid": data.rivalId, "name": rival.name})
|
||||
send.json({
|
||||
"msg": "Successfully removed profile from rival."
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const preGeneRoll = async (data: { set: number, refid: string, items: [] }, send: WebUISend) => {
|
||||
|
||||
let itemId = {
|
||||
'crew': 11,
|
||||
'stamp': 17,
|
||||
'subbg': 18,
|
||||
'bgm': 19,
|
||||
'nemsys': 20,
|
||||
'sysbg': 21
|
||||
}
|
||||
let preGeneSet = PREGENE.find(itemSet => itemSet.id === data.set)
|
||||
let finishedRolling = false
|
||||
if(preGeneSet != undefined) {
|
||||
while(!finishedRolling) {
|
||||
let rollWhat = 0
|
||||
let probability = Math.random();
|
||||
console.log("Rolling Premium Generator")
|
||||
for(const probIndex in preGeneSet.probability) {
|
||||
if(probability <= preGeneSet.probability[probIndex]) {
|
||||
rollWhat = parseInt(probIndex);
|
||||
break;
|
||||
}
|
||||
if(parseInt(probIndex) === preGeneSet.probability.length - 1) rollWhat = parseInt(probIndex);
|
||||
}
|
||||
|
||||
let unobtainedItems = preGeneSet.items[Object.keys(preGeneSet.items)[rollWhat]].map((x) => x)
|
||||
data.items.forEach(item => {
|
||||
let checkId = 0;
|
||||
checkId = item['id']
|
||||
if(item['type'] == 17) checkId = (item['id'] / 4)
|
||||
if(item['type'] == itemId[Object.keys(preGeneSet.items)[rollWhat]] && preGeneSet.items[Object.keys(preGeneSet.items)[rollWhat]].includes(checkId)) {
|
||||
unobtainedItems.splice(unobtainedItems.indexOf(checkId), 1)
|
||||
}
|
||||
})
|
||||
if(unobtainedItems.length > 0) {
|
||||
let randomItemIndex = Math.floor(Math.random() * unobtainedItems.length);
|
||||
console.log("Rolled item id: " + unobtainedItems[randomItemIndex] + " | item type: " + itemId[Object.keys(preGeneSet.items)[rollWhat]])
|
||||
if(itemId[Object.keys(preGeneSet.items)[rollWhat]] == 17) {
|
||||
for(let stampID = (unobtainedItems[randomItemIndex] * 4) - 3; stampID <= (unobtainedItems[randomItemIndex] * 4); stampID++) {
|
||||
DB.Upsert(data.refid, {
|
||||
"collection": "item",
|
||||
"type": itemId[Object.keys(preGeneSet.items)[rollWhat]],
|
||||
"id": stampID },
|
||||
{$set: {"param": 1}}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
DB.Upsert(data.refid, {
|
||||
"collection": "item",
|
||||
"type": itemId[Object.keys(preGeneSet.items)[rollWhat]],
|
||||
"id": unobtainedItems[randomItemIndex] },
|
||||
{$set: {"param": 1}}
|
||||
)
|
||||
}
|
||||
let finalItemType = (Object.keys(preGeneSet.items)[rollWhat] === 'subbg') ? 'bg' : Object.keys(preGeneSet.items)[rollWhat]
|
||||
finishedRolling = true
|
||||
send.json(
|
||||
{
|
||||
status: 'ok',
|
||||
id: unobtainedItems[randomItemIndex],
|
||||
type: finalItemType
|
||||
}
|
||||
)
|
||||
} else {
|
||||
console.log("No more " + Object.keys(preGeneSet.items)[rollWhat] + " items to get, will re-roll.")
|
||||
}
|
||||
}
|
||||
} else console.log('pregeneset none')
|
||||
}
|
||||
|
||||
export const manageEvents = async (data: { eventConfig: {} }) => {
|
||||
IO.WriteFile('webui/asset/config/events.json', JSON.stringify(data.eventConfig, null, 4));
|
||||
}
|
||||
|
||||
export const manageStartupFlags = async (data: { flagConfig: {} }) => {
|
||||
IO.WriteFile('webui/asset/config/flags.json', JSON.stringify(data.flagConfig, null, 4));
|
||||
}
|
||||
@@ -1,127 +1,263 @@
|
||||
import {common, log} from './handlers/common';
|
||||
import {hiscore, rival, saveMix, loadMix, globalMatch, lounge, entryE} from './handlers/features';
|
||||
import {
|
||||
updateProfile,
|
||||
updateMix,
|
||||
importMix,
|
||||
deleteMix,
|
||||
copyResourcesFromGame,
|
||||
getRivalScores,
|
||||
addRival,
|
||||
preGeneRoll,
|
||||
manageEvents,
|
||||
manageStartupFlags
|
||||
} from './handlers/webui';
|
||||
import {
|
||||
load,
|
||||
create,
|
||||
loadScore,
|
||||
save,
|
||||
saveScore,
|
||||
saveCourse,
|
||||
buy,
|
||||
print,
|
||||
saveValgene,
|
||||
saveE
|
||||
} from './handlers/profiles';
|
||||
import {
|
||||
ARENA
|
||||
} from './data/exg';
|
||||
|
||||
export function register() {
|
||||
|
||||
R.Contributor("LatoWolf#1170");
|
||||
R.Contributor("ovv (this fork)");
|
||||
R.GameCode('KFC');
|
||||
|
||||
R.Config('arena_szn',{ type: 'string', options: Object.keys(ARENA), default: 'None', name: 'Ranked Match Season', desc: 'Current ARENA/SINGLE BATTLE ranked season. Also sets ARENA STATION catalog corresponding to that season.'});
|
||||
R.Config('enable_valk_songs' ,{ type: 'boolean', default: false, name:'Enable Valkyrie Model Songs', desc:'Enable the valkyrie model songs on non-valkyrie mode.'});
|
||||
R.Config('use_blasterpass',{ type: 'boolean', default: true, name:'Use Blaster Pass', desc:'Enable Blaster Pass for VW and EG'});
|
||||
R.Config('tama_track_lib',{ type: 'boolean', default: true, name:'Enable Track Liberation', desc:'(Requires TAMANEKO adventure event to be enabled) A TAMANEKO adventure map that will unlock a random song that has no unlock condition. OVER ADVENTURE will be displayed if this is disabled and if you have completed all other adventures.'});
|
||||
R.Config('unlock_all_valk_items', { type: 'boolean', default: false, name:'Unlock All Valkyrie and Premium Items', desc: 'Unlock Nemsys, BGM, Submonitor BG, System BG and Stamp Items (Valk crews not included; check \'unlock all navigators\' option)'});
|
||||
R.Config('unlock_all_songs', { type: 'boolean', default: false, name:'Unlock All Songs'});
|
||||
R.Config('unlock_all_navigators', { type: 'boolean', default: false, name:'Unlock All Navigators'} );
|
||||
R.Config('unlock_all_appeal_cards', { type: 'boolean', default: false, name:'Unlock All Appeal Cards'});
|
||||
R.Config('enable_removed_songs', {type: 'boolean', default: true, name:'Enable removed songs', desc: 'Songs hidden or removed server-side will appear.'})
|
||||
R.Config('sdvx_eg_root_dir', { type: 'string', needRestart: true, default: '', name: 'Exceed Gear Data Directory', desc: 'The root directory of your SDVX Exceed Gear game files (for asset copying)'});
|
||||
R.Config('use_information' ,{ type: 'boolean', default: true, name:'Use Asphyxia Information', desc:'Enable the Asphyxia information section after entry. Otherwise, it will try to look for official information data and display them.'});
|
||||
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('april_fools',{ type: 'boolean', default: false, name:'April Fools', desc:'Enable April Fools Event (toggles Grace crew + April Fools songs)'});
|
||||
// R.Config('new_year_special',{ type: 'boolean', default: false, name:'Use New Year Special', desc:'Enable New Year Special BGM for login.'});
|
||||
|
||||
R.WebUIEvent('copyResourcesFromGame', copyResourcesFromGame);
|
||||
R.WebUIEvent('getRivalScores', getRivalScores);
|
||||
R.WebUIEvent('addRival', addRival);
|
||||
R.WebUIEvent('preGeneRoll', preGeneRoll);
|
||||
R.WebUIEvent('manageEvents', manageEvents);
|
||||
R.WebUIEvent('manageStartupFlags', manageStartupFlags);
|
||||
R.WebUIEvent('updateProfile', updateProfile);
|
||||
R.WebUIEvent('updateMix', updateMix);
|
||||
R.WebUIEvent('importMix', importMix);
|
||||
R.WebUIEvent('deleteMix', deleteMix);
|
||||
|
||||
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);
|
||||
|
||||
// Profile
|
||||
MultiRoute('new', create);
|
||||
MultiRoute('load', load);
|
||||
MultiRoute('load_m', loadScore);
|
||||
MultiRoute('save', save);
|
||||
MultiRoute('save_m', saveScore);
|
||||
MultiRoute('save_c', saveCourse);
|
||||
MultiRoute('save_valgene', saveValgene);
|
||||
MultiRoute('frozen', true);
|
||||
MultiRoute('buy', buy);
|
||||
MultiRoute('print',print);
|
||||
|
||||
// Features
|
||||
MultiRoute('hiscore', hiscore);
|
||||
MultiRoute('load_r', rival);
|
||||
MultiRoute('save_ap', saveMix);
|
||||
MultiRoute('load_ap', loadMix);
|
||||
|
||||
// Lazy
|
||||
MultiRoute('lounge', lounge);
|
||||
MultiRoute('shop', (_, __, send) => send.object({
|
||||
nxt_time: K.ITEM('u32', 1000 * 5 * 60)
|
||||
}));
|
||||
MultiRoute('save_e', saveE);
|
||||
MultiRoute('save_mega', true);
|
||||
MultiRoute('play_e', true);
|
||||
MultiRoute('play_s', true);
|
||||
MultiRoute('entry_s', globalMatch);
|
||||
MultiRoute('entry_e', entryE);
|
||||
MultiRoute('exception', true);
|
||||
MultiRoute('log',log);
|
||||
|
||||
R.Route('eventlog.write', (_, __, send) => send.object({
|
||||
gamesession: K.ITEM('s64', BigInt(1)),
|
||||
logsendflg: K.ITEM('s32', 0),
|
||||
logerrlevel: K.ITEM('s32', 0),
|
||||
evtidnosendflg: K.ITEM('s32', 0)
|
||||
}));
|
||||
|
||||
R.Route('package.list',(_,__,send)=>send.object({
|
||||
package:K.ATTR({expire:"1200"},{status:"1"})
|
||||
}));
|
||||
|
||||
R.Route('ins.netlog', (_, __, send) => send.object({
|
||||
//gamesession: K.ITEM('s64', BigInt(1)),
|
||||
//logsendflg: K.ITEM('s32', 0),
|
||||
//logerrlevel: K.ITEM('s32', 0),
|
||||
//evtidnosendflg: K.ITEM('s32', 0)
|
||||
}));
|
||||
|
||||
R.Unhandled(undefined)
|
||||
}
|
||||
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 { musicdataload, playerdatanew, playerdatasave, playerdataload, rivaldataload, ghostdataload, taboowordcheck, minidump } from "./handlers/ddrworld";
|
||||
import { CommonOffset, OptionOffset, Profile } from "./models/profile";
|
||||
import { ProfileWorld, CustomizeWorld } from "./models/ddrworld";
|
||||
import { SONGS_WORLD, SONGS_OVERRIDE_WORLD, LEAGUE_WORLD } from "./data/world"
|
||||
|
||||
export function register() {
|
||||
R.GameCode("MDX");
|
||||
|
||||
R.Unhandled(undefined);
|
||||
|
||||
R.Config("save_option", {
|
||||
name: "Save option",
|
||||
desc: "Gets the previously set options as they are.",
|
||||
default: true,
|
||||
type: "boolean"
|
||||
});
|
||||
R.Config("song_unlock", {
|
||||
name: "Unlock all songs",
|
||||
desc: "Still requires musicdb.xml to get the song ids.",
|
||||
default: true,
|
||||
type: "boolean"
|
||||
});
|
||||
R.Config("mdb_limited", {
|
||||
name: "musicdb.xml for musicdata_load",
|
||||
desc: "musicdb.xml file to use for importing limited and diffLv info. Put this xml file in the 'data' directory of the plugin.",
|
||||
type: "string",
|
||||
default: ""
|
||||
});
|
||||
R.Config("mdb_title", {
|
||||
name: "musicdb.xml for WebUI",
|
||||
desc: "musicdb.xml file to retrieve song titles from, for use in WebUI. Put this xml file in the 'data' directory of the plugin, or keep this blank if you want to use the same file as above.",
|
||||
type: "string",
|
||||
default: ""
|
||||
});
|
||||
|
||||
const RoutePlayerData = (method: string, handler: EPR | boolean) => {
|
||||
R.Route(`playerdata.${method}`, handler);
|
||||
};
|
||||
|
||||
const RoutePlayData = (method: string, handler: EPR | boolean) => {
|
||||
R.Route(`playdata_3.${method}`, handler);
|
||||
|
||||
};
|
||||
|
||||
const WordCheck = (method: string, handler: EPR | boolean) => {
|
||||
R.Route(`wordcheck_3.${method}`, handler);
|
||||
}
|
||||
|
||||
const RouteSystem = (method: string, handler: EPR | boolean) => {
|
||||
R.Route(`system.${method}`, handler);
|
||||
R.Route(`system_3.${method}`, handler);
|
||||
};
|
||||
|
||||
const RouteEventLog = (method: string, handler: EPR | boolean) => {
|
||||
R.Route(`eventlog.${method}`, handler);
|
||||
R.Route(`eventlog_3.${method}`, handler);
|
||||
};
|
||||
|
||||
RoutePlayerData('usergamedata_advanced', usergamedata);
|
||||
RoutePlayerData('usergamedata_recv', usergamedata_recv);
|
||||
RoutePlayerData('usergamedata_send', usergamedata_send);
|
||||
RoutePlayData('musicdata_load', musicdataload);
|
||||
RoutePlayData('playerdata_new', playerdatanew);
|
||||
RoutePlayData('playerdata_load', playerdataload);
|
||||
RoutePlayData('playerdata_save', playerdatasave);
|
||||
RoutePlayData('rivaldata_load', rivaldataload);
|
||||
RoutePlayData('ghostdata_load', ghostdataload);
|
||||
RouteSystem("convcardnumber", convcardnumber);
|
||||
RouteSystem("minidump", minidump);
|
||||
RouteEventLog("write", eventLog);
|
||||
WordCheck('tabooword_check', taboowordcheck)
|
||||
|
||||
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(",")
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
R.WebUIEvent("updateName3", async ({ refid, name }) => {
|
||||
await DB.Update<ProfileWorld>(refid, { collection: "profile3" }, {
|
||||
$set: {
|
||||
dancerName: name
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
R.WebUIEvent("updateWeight3", async ({ refid, weight }) => {
|
||||
await DB.Update<ProfileWorld>(refid, { collection: "profile3" }, {
|
||||
$set: {
|
||||
weight: weight
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
R.WebUIEvent("updateDisplayCalories3", async ({ refid, selected }) => {
|
||||
await DB.Update<ProfileWorld>(refid, { collection: "profile3" }, {
|
||||
$set: {
|
||||
isDispWeight: selected
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
R.WebUIEvent("playerCustomize", async ({ customize, refid, selected }) => {
|
||||
const catPat = {'appeal': [1, 1]}
|
||||
if(selected === 0) await DB.Remove<CustomizeWorld>(refid, { collection: "customize3", category: catPat[customize][0], pattern: catPat[customize][1] })
|
||||
else await DB.Upsert<CustomizeWorld>(refid, { collection: "customize3", category: catPat[customize][0] }, {
|
||||
$set: {
|
||||
key: selected,
|
||||
pattern: catPat[customize][1]
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
R.WebUIEvent("getMDB", async (data: {}, send: WebUISend) => {
|
||||
let mdbData = []
|
||||
let mdbLimName = U.GetConfig('mdb_limited')
|
||||
let mdbTitleName = U.GetConfig('mdb_title')
|
||||
|
||||
if(mdbLimName !== '') {
|
||||
if(IO.Exists('data/' + mdbLimName)) {
|
||||
let mdbLim = U.parseXML(U.DecodeString(await IO.ReadFile('data/' + mdbLimName), "utf8"), false)
|
||||
|
||||
mdbLim['mdb']['music'].forEach(music => {
|
||||
if(SONGS_WORLD.concat(SONGS_OVERRIDE_WORLD).findIndex(so => so.mcode === $(music).number('mcode')) < 0) {
|
||||
mdbData.push({
|
||||
mcode: $(music).number('mcode'),
|
||||
title: $(music).str('title'),
|
||||
diffLv: $(music).numbers('diffLv'),
|
||||
series: $(music).number('series')
|
||||
})
|
||||
}
|
||||
})
|
||||
let mdbTitle = (mdbTitleName === mdbLimName || mdbTitleName === '') ? mdbLim : U.parseXML(U.DecodeString(await IO.ReadFile('data/' + mdbTitleName), "utf8"), false)
|
||||
SONGS_WORLD.concat(SONGS_OVERRIDE_WORLD).forEach(sw => {
|
||||
let musicInfo = mdbTitle['mdb']['music'].find(m => $(m).number('mcode') === sw.mcode)
|
||||
let songTitle = 'ID ' + sw.mcode
|
||||
let series = 0
|
||||
if(musicInfo) {
|
||||
songTitle = $(musicInfo).str('title')
|
||||
series = $(musicInfo).number('series')
|
||||
}
|
||||
mdbData.push({
|
||||
mcode: sw.mcode,
|
||||
title: songTitle,
|
||||
diffLv: sw.diffLv,
|
||||
series: series
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
send.json({mdb: mdbData})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
export interface Arena {
|
||||
collection: 'arena';
|
||||
|
||||
last_play_season: number;
|
||||
rank_point: number;
|
||||
shop_point: number;
|
||||
ultimate_rate: number;
|
||||
megamix_rate: number;
|
||||
rank_play_cnt: number;
|
||||
ultimate_play_cnt: number;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
export interface Counter {
|
||||
collection: 'counter';
|
||||
|
||||
key: string;
|
||||
value: number;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
export interface CourseRecord {
|
||||
collection: 'course';
|
||||
|
||||
version: number;
|
||||
|
||||
sid: number;
|
||||
cid: number;
|
||||
stype: number;
|
||||
score: number;
|
||||
exscore: number;
|
||||
clear: number;
|
||||
grade: number;
|
||||
rate: number;
|
||||
count: number;
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
import { Difficulty, Rank, ClearKind } from '../models/score'
|
||||
|
||||
export interface RivalWorld {
|
||||
collection: "rival3";
|
||||
|
||||
slot: number;
|
||||
rivalCode: number;
|
||||
}
|
||||
|
||||
export interface ScoreWorld {
|
||||
collection: "score3";
|
||||
|
||||
scoreId: number;
|
||||
songId: number;
|
||||
style: number;
|
||||
difficulty: Difficulty;
|
||||
ghostId: number;
|
||||
rank: Rank;
|
||||
clearKind: ClearKind;
|
||||
score: number;
|
||||
exScore: number;
|
||||
maxCombo: number;
|
||||
flareForce: number;
|
||||
}
|
||||
|
||||
export interface HiScoreWorld {
|
||||
collection: "hiscore3";
|
||||
|
||||
slot: number;
|
||||
country: string;
|
||||
region: string;
|
||||
customerCode: string;
|
||||
companyCode: string;
|
||||
locationId: string;
|
||||
pcbid: string;
|
||||
songId: number;
|
||||
style: number;
|
||||
difficulty: number;
|
||||
dancerName: string;
|
||||
score: number;
|
||||
ghostId: number;
|
||||
}
|
||||
|
||||
export interface GhostWorld {
|
||||
collection: "ghost3"
|
||||
|
||||
ghostId: number;
|
||||
ghostSize: number;
|
||||
ghost: string;
|
||||
}
|
||||
|
||||
export interface EventWorld {
|
||||
collection: "event3";
|
||||
|
||||
eventId: number;
|
||||
eventNo: number;
|
||||
eventType: number;
|
||||
compTime: number;
|
||||
saveData: number;
|
||||
}
|
||||
|
||||
export interface LeagueWorld {
|
||||
collection: "league3";
|
||||
|
||||
id: number,
|
||||
class: number,
|
||||
score: number,
|
||||
playCount: number,
|
||||
ended: boolean
|
||||
}
|
||||
|
||||
export interface CustomizeWorld {
|
||||
collection: "customize3";
|
||||
|
||||
category: number;
|
||||
key: number;
|
||||
pattern: number;
|
||||
}
|
||||
|
||||
export interface ProfileWorld {
|
||||
collection: "profile3";
|
||||
|
||||
ddrCode: number;
|
||||
dancerName: string;
|
||||
area: number;
|
||||
extraStar: number;
|
||||
playCount: number;
|
||||
weight: number;
|
||||
todayCal: number;
|
||||
isDispWeight: boolean;
|
||||
prePlayableNum: number;
|
||||
|
||||
opHispeed: number;
|
||||
opGauge: number;
|
||||
opFastSlow: number;
|
||||
opGuideline: number;
|
||||
opStepZone: number;
|
||||
opTimingDisp: number;
|
||||
opVisibility: number;
|
||||
opVisibleTime: number;
|
||||
opLane: number;
|
||||
opLaneHiddenPos: number;
|
||||
opLaneSuddenPos: number;
|
||||
opLaneHidSudPos: number;
|
||||
opLaneFilter: number;
|
||||
opScrollDirection: number;
|
||||
opScrollMoving: number;
|
||||
opArrowPriority: number;
|
||||
opArrowPlacement: number;
|
||||
opArrowColor: number;
|
||||
opArrowDesign: number;
|
||||
opCutTiming: number;
|
||||
opCutFreeze: number;
|
||||
opCutJump: number;
|
||||
|
||||
lpMode: number;
|
||||
lpFolder: number;
|
||||
lpMcode: number;
|
||||
lpStyle: number;
|
||||
lpDifficulty: number;
|
||||
lpWindowMain: number;
|
||||
lpWindowSub: number;
|
||||
lpTarget: number;
|
||||
lpTabMain: number;
|
||||
lpTabSub: number;
|
||||
|
||||
fsTitle: number;
|
||||
fsVersion: number;
|
||||
fsGenre: number;
|
||||
fsBpm: number;
|
||||
fsEvent: number;
|
||||
fsLevel: number;
|
||||
fsFlareRank: number;
|
||||
fsClearRank: number;
|
||||
fsFlareSkillTarget: number;
|
||||
fsRivalFlareSkill: number;
|
||||
fsRivalScoreRank: number;
|
||||
fsSortType: number;
|
||||
fsOrderType: number;
|
||||
|
||||
cgTipsBasic: number;
|
||||
cgTipsOption: number;
|
||||
cgTipsEvent: number;
|
||||
cgTipsGimmick: number;
|
||||
cgTipsAdvance: number;
|
||||
cgGuideScene: number;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export interface Ghost {
|
||||
collection: "ghost";
|
||||
|
||||
songId: number;
|
||||
difficulty: number;
|
||||
ghostSize: number;
|
||||
ghost: string;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
export interface Item {
|
||||
collection: 'item';
|
||||
|
||||
type: number;
|
||||
id: number;
|
||||
param: number;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
export interface Matchmaker {
|
||||
collection: 'matchmaker';
|
||||
|
||||
timestamp: number,
|
||||
c_ver: number,
|
||||
p_num: number,
|
||||
p_rest: number,
|
||||
filter: number,
|
||||
mid: number,
|
||||
sec: number,
|
||||
port: number,
|
||||
gip: number[],
|
||||
lip: number[],
|
||||
claim: number,
|
||||
entry_id: number
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
export interface Mix {
|
||||
collection: 'mix';
|
||||
|
||||
id: number;
|
||||
code: string;
|
||||
name: string;
|
||||
creator: string;
|
||||
param: string;
|
||||
jacket: number;
|
||||
tag: number;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
export interface MusicRecord {
|
||||
collection: 'music';
|
||||
|
||||
mid: number;
|
||||
type: number;
|
||||
score: number;
|
||||
exscore: number;
|
||||
clear: number;
|
||||
grade: number;
|
||||
buttonRate: number;
|
||||
longRate: number;
|
||||
volRate: number;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
export interface Param {
|
||||
collection: 'param';
|
||||
type: number;
|
||||
id: number;
|
||||
param: number[];
|
||||
}
|
||||
@@ -1,64 +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';
|
||||
|
||||
pluginVer: number;
|
||||
|
||||
id: number;
|
||||
name: string;
|
||||
appeal: number;
|
||||
akaname: number;
|
||||
|
||||
packets: number;
|
||||
blocks: number;
|
||||
|
||||
expPoint: number;
|
||||
mUserCnt: number;
|
||||
|
||||
musicID: number;
|
||||
musicType: number;
|
||||
sortType: number;
|
||||
headphone: number;
|
||||
blasterEnergy: number;
|
||||
blasterCount: number;
|
||||
extrackEnergy: number;
|
||||
|
||||
hiSpeed: number;
|
||||
laneSpeed: number;
|
||||
gaugeOption: number;
|
||||
arsOption: number;
|
||||
notesOption: number;
|
||||
earlyLateDisp: number;
|
||||
drawAdjust: number;
|
||||
effCLeft: number;
|
||||
effCRight: number;
|
||||
narrowDown: number;
|
||||
|
||||
bgm: number;
|
||||
subbg: number;
|
||||
nemsys: number;
|
||||
|
||||
stampA: number;
|
||||
stampB: number;
|
||||
stampC: number;
|
||||
stampD: number;
|
||||
stampRA: number;
|
||||
stampRB: number;
|
||||
stampRC: number;
|
||||
stampRD: number;
|
||||
sysBG: number;
|
||||
|
||||
boothFrame: number[];
|
||||
|
||||
playCount: number;
|
||||
dayCount: number;
|
||||
todayCount: number;
|
||||
playchain: number;
|
||||
maxPlayChain: number;
|
||||
weekCount: number;
|
||||
weekPlayCount: number;
|
||||
weekChain: number;
|
||||
maxWeekChain: number;
|
||||
|
||||
bplSupport: number;
|
||||
creatorItem: number;
|
||||
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;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
export interface Rival {
|
||||
collection: 'rival';
|
||||
|
||||
sdvxID: number;
|
||||
refid: string;
|
||||
name: string;
|
||||
mutual: boolean;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
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,
|
||||
FAILED,
|
||||
ASSIST_CLEAR,
|
||||
CLEAR,
|
||||
LIFE4_1,
|
||||
LIFE4_2,
|
||||
LIFE4,
|
||||
GOOD_COMBO,
|
||||
GREAT_COMBO,
|
||||
PERFECT_COMBO,
|
||||
MARVELOUS_COMBO
|
||||
}
|
||||
|
||||
export interface Score {
|
||||
collection: "score";
|
||||
|
||||
songId: number;
|
||||
difficulty: Difficulty;
|
||||
rank: Rank;
|
||||
clearKind: ClearKind;
|
||||
score: number;
|
||||
maxCombo: number;
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
export interface Skill {
|
||||
collection: 'skill';
|
||||
|
||||
version: number;
|
||||
|
||||
level: number;
|
||||
base: number;
|
||||
name: number;
|
||||
type: number;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
export interface ValgeneTicket {
|
||||
collection: 'valgene_ticket';
|
||||
|
||||
ticketNum: number;
|
||||
limitDate: number;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
- let music = 0;
|
||||
- let event = 0;
|
||||
- let catalog = 0;
|
||||
|
||||
game
|
||||
limited
|
||||
while music < 200
|
||||
music(id=music++, flag=2)
|
||||
|
||||
event
|
||||
while event < 16
|
||||
info(id=event++)
|
||||
|
||||
catalog
|
||||
while catalog < 256
|
||||
info(id=catalog++, currency=1, price=1)
|
||||
@@ -1,23 +0,0 @@
|
||||
game
|
||||
name(__type="str") #{name}
|
||||
code(__type="str") #{code}
|
||||
gamecoin_packet(__type="u32") #{packets}
|
||||
gamecoin_block(__type="u32") #{blocks}
|
||||
exp_point(__type="u32") #{expPoint ? expPoint : 0}
|
||||
m_user_cnt(__type="u32") #{mUserCnt ? mUserCnt : 0}
|
||||
have_item(__type="bool" __count=512) #{Array(512).fill(1).join(" ")}
|
||||
have_note(__type="bool" __count=512) #{Array(512).fill(1).join(" ")}
|
||||
|
||||
last(
|
||||
music_id=musicID,
|
||||
music_type=musicType,
|
||||
sort_type=sortType,
|
||||
headphone=headphone,
|
||||
hispeed=hiSpeed,
|
||||
appeal_id=appeal,
|
||||
frame0=boothFrame ? boothFrame[0] : 0,
|
||||
frame1=boothFrame ? boothFrame[1] : 0,
|
||||
frame2=boothFrame ? boothFrame[2] : 0,
|
||||
frame3=boothFrame ? boothFrame[3] : 0,
|
||||
frame4=boothFrame ? boothFrame[4] : 0,
|
||||
)
|
||||
@@ -1,38 +0,0 @@
|
||||
- let music = 0;
|
||||
- let event = 0;
|
||||
- let catalog = 0;
|
||||
|
||||
|
||||
game
|
||||
music_limited
|
||||
while music < 23
|
||||
each type in [0,1,2,3]
|
||||
info
|
||||
music_id(__type="s32") #{music++}
|
||||
music_type(__type="u8") #{type}
|
||||
limited(__type="u8") 3
|
||||
|
||||
event
|
||||
while event < 41
|
||||
info
|
||||
event_id(__type="u32") #{event++}
|
||||
|
||||
skill_course
|
||||
each course in courses
|
||||
info
|
||||
course_id(__type="s16") #{course.id}
|
||||
level(__type="s16") #{course.level}
|
||||
season_id(__type="s16") #{course.season_id}
|
||||
season_name(__type="str") #{course.season_name}
|
||||
season_new_flg(__type="bool") #{course.new_flg}
|
||||
course_name(_type="str") #{course.name}
|
||||
course_type(__type="s16") #{course.type}
|
||||
skill_name_id(__type="s16") #{course.name_id}
|
||||
matching_assist(__type="bool") #{course.matching_assist}
|
||||
guage_type(__type="s16") #{course.guage_type}
|
||||
paseli_type(type="s16") #{course.paseli_type}
|
||||
each trackinfo in course.tracks
|
||||
track
|
||||
track_no(__type="s16") #{trackinfo.no}
|
||||
music_id(__type="s32") #{trackinfo.id}
|
||||
music_type(__type="s8") #{trackinfo.type}
|
||||
@@ -1,105 +0,0 @@
|
||||
game
|
||||
result(__type="u8") 0
|
||||
name(__type="str") #{name}
|
||||
code(__type="str") #{code}
|
||||
sdvx_id(__type="str") #{code}
|
||||
gamecoin_packet(__type="u32") #{packets}
|
||||
gamecoin_block(__type="u32") #{blocks}
|
||||
|
||||
|
||||
last
|
||||
music_id(__type="s32") #{musicID}
|
||||
music_type(__type="u8") #{musicType}
|
||||
sort_type(__type="u8") #{sortType}
|
||||
comment_id(__type="u16") 0
|
||||
appeal_id(__type="u16") #{appeal}
|
||||
headphone(__type="u8") #{headphone}
|
||||
narrow_down(__type="u8") #{narrowDown}
|
||||
gauge_option(__type="u8") #{gaugeOption}
|
||||
blaster_energy(__type="u32") #{blasterEnergy}
|
||||
blaster_count(__type="u32") #{blasterCount}
|
||||
extrack_energy(__type="u16") #{extrackEnergy}
|
||||
|
||||
hispeed(__type="s32") #{hiSpeed}
|
||||
lanespeed(__type="u32") #{laneSpeed}
|
||||
|
||||
ars_option(__type="u8") #{arsOption}
|
||||
notes_option(__type="u8") #{notesOption}
|
||||
early_late_disp(__type="u8") #{earlyLateDisp}
|
||||
draw_adjust(__type="s32") #{drawAdjust}
|
||||
eff_c_left(__type="u8") #{effCLeft}
|
||||
eff_c_right(__type="u8") #{effCRight}
|
||||
|
||||
|
||||
kac_id(__type="str") #{name}
|
||||
|
||||
skill_level(__type="s16") #{skill.level}
|
||||
skill_base_id(__type="s16") #{skill.base}
|
||||
skill_name_id(__type="s16") #{skill.name}
|
||||
|
||||
ea_shop
|
||||
packet_booster(__type="s32") 1
|
||||
if version < 5
|
||||
block_booster(__type="s32") 1
|
||||
if version >= 5
|
||||
blaster_pass_enable(__type="bool") 1
|
||||
blaster_pass_limit_date(__type="u64") #{currentTime}
|
||||
|
||||
eaappli
|
||||
relation(__type="s8") 1
|
||||
cloud
|
||||
relation(__type="s8") 1
|
||||
block_no(__type="s32") 0
|
||||
|
||||
skill
|
||||
course
|
||||
each course in courses
|
||||
d
|
||||
ssnid(__type="s16") #{course.sid}
|
||||
crsid(__type="s16") #{course.cid}
|
||||
sc(__type="s32") #{course.score}
|
||||
ex(__type="s32") 0
|
||||
ct(__type="s16") #{course.clear}
|
||||
gr(__type="s16") #{course.grade}
|
||||
ar(__type="s16") #{course.rate}
|
||||
cnt(__type="s16") #{course.count}
|
||||
course_total
|
||||
each course in courses
|
||||
d
|
||||
ssnid(__type="s16") #{course.sid}
|
||||
crsid(__type="s16") #{course.cid}
|
||||
sc(__type="s32") #{course.score}
|
||||
ex(__type="s32") 0
|
||||
ct(__type="s16") #{course.clear}
|
||||
gr(__type="s16") #{course.grade}
|
||||
ar(__type="s16") #{course.rate}
|
||||
cnt(__type="s16") #{course.count}
|
||||
course_all
|
||||
each course in courses
|
||||
d
|
||||
ssnid(__type="s16") #{course.sid}
|
||||
crsid(__type="s16") #{course.cid}
|
||||
sc(__type="s32") #{course.score}
|
||||
ex(__type="s32") 0
|
||||
ct(__type="s16") #{course.clear}
|
||||
gr(__type="s16") #{course.grade}
|
||||
ar(__type="s16") #{course.rate}
|
||||
cnt(__type="s16") #{course.count}
|
||||
|
||||
item
|
||||
each item in tempItem
|
||||
info
|
||||
type(__type="u8") #{item.type}
|
||||
id(__type="u32") #{item.id}
|
||||
param(__type="u32") #{item.param}
|
||||
|
||||
|
||||
play_count(__type="u32") 1001
|
||||
day_count(__type="u32") 301
|
||||
today_count(__type="u32") 21
|
||||
play_chain(__type="u32") 31
|
||||
max_play_chain(__type="u32") 31
|
||||
week_count(__type="u32") 9
|
||||
week_play_count(__type="u32") 101
|
||||
week_chain(__type="u32") 31
|
||||
max_week_chain(__type="u32") 31
|
||||
@@ -1,14 +0,0 @@
|
||||
game
|
||||
new
|
||||
each music in temp
|
||||
music
|
||||
music_id (__type="u32")#{music.mid}
|
||||
music_type (__type="u32")#{music.type}
|
||||
score (__type="u32")#{music.score}
|
||||
cnt (__type="u32")1
|
||||
clear_type (__type="u32")#{music.clear}
|
||||
score_grade (__type="u32")#{music.grade}
|
||||
btn_rate (__type="u32")#{music.buttonRate}
|
||||
long_rate (__type="u32")#{music.longRate}
|
||||
vol_rate (__type="u32")#{music.volRate}
|
||||
old
|
||||
@@ -1,155 +0,0 @@
|
||||
game
|
||||
result(__type="u8") 0
|
||||
name(__type="str") #{name}
|
||||
code(__type="str") #{code}
|
||||
sdvx_id(__type="str") #{code}
|
||||
gamecoin_packet(__type="u32") #{packets}
|
||||
gamecoin_block(__type="u32") #{blocks}
|
||||
appeal_id(__type="u16") #{appeal}
|
||||
|
||||
last_music_id(__type="s32") #{musicID}
|
||||
last_music_type(__type="u8") #{musicType}
|
||||
sort_type(__type="u8") #{sortType}
|
||||
headphone(__type="u8") #{headphone}
|
||||
blaster_energy(__type="u32") #{blasterEnergy}
|
||||
blaster_count(__type="u32") 0
|
||||
extrack_energy(__type="u16") #{extrackEnergy}
|
||||
|
||||
hispeed(__type="s32") #{hiSpeed}
|
||||
lanespeed(__type="u32") #{laneSpeed}
|
||||
gauge_option(__type="u8") #{gaugeOption}
|
||||
ars_option(__type="u8") #{arsOption}
|
||||
notes_option(__type="u8") #{notesOption}
|
||||
early_late_disp(__type="u8") #{earlyLateDisp}
|
||||
draw_adjust(__type="s32") #{drawAdjust}
|
||||
eff_c_left(__type="u8") #{effCLeft}
|
||||
eff_c_right(__type="u8") #{effCRight}
|
||||
narrow_down(__type="u8") #{narrowDown}
|
||||
|
||||
kac_id(__type="str") #{name}
|
||||
|
||||
skill_level(__type="s16") #{skill.level}
|
||||
skill_base_id(__type="s16") #{skill.base}
|
||||
skill_name_id(__type="s16") #{skill.name}
|
||||
skill_type(__type="s16") #{skill.type !== undefined ? skill.type : 0}
|
||||
|
||||
if bplSupport
|
||||
support_team_id(__type="s32") #{bplSupport}
|
||||
|
||||
ea_shop
|
||||
packet_booster(__type="s32") 1
|
||||
if version < 5
|
||||
block_booster(__type="s32") 1
|
||||
if version >= 5
|
||||
blaster_pass_enable(__type="bool") #{blasterpass}
|
||||
blaster_pass_limit_date(__type="u64") #{currentTime}
|
||||
|
||||
eaappli
|
||||
relation(__type="s8") 1
|
||||
cloud
|
||||
relation(__type="s8") 1
|
||||
block_no(__type="s32") 0
|
||||
|
||||
skill
|
||||
each course in courses
|
||||
course
|
||||
ssnid(__type="s16") #{course.sid}
|
||||
crsid(__type="s16") #{course.cid}
|
||||
st(__type="s16") #{course.stype !== undefined ? course.stype : 0}
|
||||
sc(__type="s32") #{course.score}
|
||||
ex(__type="s32") #{course.exscore !== undefined ? course.exscore : 0}
|
||||
ct(__type="s16") #{course.clear}
|
||||
gr(__type="s16") #{course.grade}
|
||||
ar(__type="s16") #{course.rate}
|
||||
cnt(__type="s16") #{course.count}
|
||||
|
||||
item
|
||||
each item in items
|
||||
info
|
||||
type(__type="u8") #{item.type}
|
||||
id(__type="u32") #{item.id}
|
||||
param(__type="u32") #{item.param}
|
||||
|
||||
//- Unlock automation songs
|
||||
each song in automation
|
||||
info
|
||||
type(__type="u8") 15
|
||||
id(__type="u32") #{song}
|
||||
param(__type="u32") 1
|
||||
|
||||
present
|
||||
each item in present
|
||||
info
|
||||
type(__type="u8") #{item.type}
|
||||
id(__type="u32") #{item.id}
|
||||
param(__type="u32") #{item.param}
|
||||
|
||||
param
|
||||
each param in params
|
||||
info
|
||||
type(__type="s32") #{param.type}
|
||||
id(__type="s32") #{param.id}
|
||||
param(__type="s32" __count=param.param.length) #{param.param.join(" ")}
|
||||
|
||||
//- Akaname
|
||||
each id in [0, 1, 2]
|
||||
info
|
||||
type(__type="s32") 6
|
||||
id(__type="s32") #{id}
|
||||
param(__type="s32" __count="1") #{akaname}
|
||||
|
||||
if playCount
|
||||
play_count(__type="u32") #{playCount}
|
||||
if dayCount
|
||||
day_count(__type="u32") #{dayCount}
|
||||
if todayCount
|
||||
today_count(__type="u32") #{todayCount}
|
||||
if playChain
|
||||
play_chain(__type="u32") #{playChain}
|
||||
if maxPlayChain
|
||||
max_play_chain(__type="u32") #{maxPlayChain}
|
||||
if weekCount
|
||||
week_count(__type="u32") #{weekCount}
|
||||
if weekPlayCount
|
||||
week_play_count(__type="u32") #{weekPlayCount}
|
||||
if weekChain
|
||||
week_chain(__type="u32") #{weekChain}
|
||||
if maxWeekChain
|
||||
max_week_chain(__type="u32") #{maxWeekChain}
|
||||
|
||||
if mixes
|
||||
each mix in mixes
|
||||
automation
|
||||
mix_id(__type="s32") #{mix.id}
|
||||
mix_code(__type="str") #{mix.code}
|
||||
seq(__type="str")
|
||||
mix_name(__type="str") #{mix.name}
|
||||
player_name(__type="str") #{mix.creator}
|
||||
generate_param(__type="str") #{mix.param}
|
||||
distribution_date(__type="u32") 20200101
|
||||
jacket_id(__type="s32") #{mix.jacket}
|
||||
tag_bit(__type="s32") #{mix.tag}
|
||||
like_flg(__type="u8") 0
|
||||
|
||||
if arena
|
||||
arena
|
||||
last_play_season(__type="s32") #{arena.season !== undefined ? arena.season : 0}
|
||||
rank_point(__type="s32") #{arena.rankPoint}
|
||||
shop_point(__type="s32") #{arena.shopPoint}
|
||||
ultimate_rate(__type="s32") #{arena.ultimateRate}
|
||||
ultimate_rank_num(__type="s32") #{arena.ultimateRankNum !== undefined ? arena.ultimateRankNum : 0}
|
||||
megamix_rate(__type="s32") #{arena.megamixRate !== undefined ? arena.megamixRate : 0}
|
||||
rank_play_cnt(__type="s32") #{arena.rankCount}
|
||||
ultimate_play_cnt(__type="s32") #{arena.ultimateCount}
|
||||
|
||||
if valgeneTicket
|
||||
valgene_ticket
|
||||
ticket_num(__type="s32") #{valgeneTicket.ticketNum}
|
||||
limit_date(__type="u64") #{valgeneTicket.limitDate}
|
||||
|
||||
if creatorItem > 1
|
||||
creator_item
|
||||
info
|
||||
creator_type(__type="u32") #{creatorItem}
|
||||
item_id(__type="u32") 0
|
||||
param(__type="u32") 0
|
||||
@@ -1,33 +1,13 @@
|
||||
import {Counter} from './models/counter';
|
||||
|
||||
export function IDToCode(id: number) {
|
||||
const padded = _.padStart(id.toString(), 8);
|
||||
return `${padded.slice(0, 4)}-${padded.slice(4)}`;
|
||||
}
|
||||
|
||||
export async function GetCounter(key: string) {
|
||||
return (
|
||||
await DB.Upsert<Counter>(
|
||||
{ collection: 'counter', key: 'mix' },
|
||||
{ $inc: { value: 1 } }
|
||||
)
|
||||
).docs[0].value;
|
||||
}
|
||||
|
||||
export function getVersion(info: EamuseInfo) {
|
||||
const dateCode = parseInt(info.model.split(":")[4]);
|
||||
if (dateCode <= 2013052900) return 1;
|
||||
if (dateCode <= 2014112000) return 2;
|
||||
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;
|
||||
|
||||
if (dateCode >= 2019022600 && dateCode <= 2020020300) return 10;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 formatCode(ddrCode: number) {
|
||||
const pad = (ddrCode + "").padStart(8, "0");
|
||||
|
||||
return pad.replace(/^([0-9]{4})([0-9]{4})$/, "$1-$2");
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 17 KiB |