From 0d357fdf07f43e5937b3333893e2e24750d9a12a Mon Sep 17 00:00:00 2001 From: vvo Date: Fri, 6 Oct 2023 20:47:24 +0800 Subject: [PATCH] some fixes --- sdvx@asphyxia/README.md | 42 ++++- sdvx@asphyxia/data/exg.ts | 109 ++++++++---- sdvx@asphyxia/handlers/common.ts | 54 +++--- sdvx@asphyxia/handlers/features.ts | 102 ++++++++--- sdvx@asphyxia/handlers/profiles.ts | 19 ++- sdvx@asphyxia/handlers/webui.ts | 76 ++++++--- sdvx@asphyxia/index.ts | 4 +- sdvx@asphyxia/models/profile.ts | 4 + sdvx@asphyxia/models/xrecord.ts | 6 - sdvx@asphyxia/templates/load.pug | 7 +- sdvx@asphyxia/webui/asset/js/events.js | 6 + sdvx@asphyxia/webui/asset/js/preview.js | 186 ++++++++++++++++++--- sdvx@asphyxia/webui/asset/json/events.json | 149 ++++++++++++----- sdvx@asphyxia/webui/profile_--setting.pug | 71 +++++++- 14 files changed, 635 insertions(+), 200 deletions(-) delete mode 100644 sdvx@asphyxia/models/xrecord.ts diff --git a/sdvx@asphyxia/README.md b/sdvx@asphyxia/README.md index b282450..457a370 100644 --- a/sdvx@asphyxia/README.md +++ b/sdvx@asphyxia/README.md @@ -20,12 +20,46 @@ Changelog =========== +## fork-6.0.2.2 + +### New: + +1. Event updates: + - Enabled BPL S2 (SuddeИDeath) stamp event. Unlock all other songs first to make SuddeИDeath appear. + - Added SDVX x CCJ song online crossover event. + - Enabled item auto-unlock for 'cross_online' / cross events (X-record, BPL2021, Ichika, CCJ, etc.) + - I would love to make point/progression systems for each event but it would take a lot of work and I would potentially need to update other games' plugins, so I'd rather not, and just give the option to unlock the songs automatically. Maybe in the future? +2. ARENA updates: + - Ranked match and rule implementation: + - The active ranked match game mode and the point system used depends on the individual season. + - Some seasons will have the ARENA BATTLE as the active ranked match, some will have SINGLE BATTLE. + - Point system/rule can either be based on score, or based on star point. As of the moment, only season 1 has used the score-based rule. + - Reference: [BEMANIWiki](https://bemaniwiki.com/index.php?SOUND+VOLTEX+EXCEED+GEAR/ARENA+BATTLE#ONLINE_ARENA) + - ARENA STATION catalog will still be based on the season it came out with. + - Added option to not choose an active ARENA season. +3. Other: + - Initial online matchmaking code (WIP / unfinished / doesn't work) +4. WebUI: + - Added support for setting FX-R chat stamps. + - Added video player for submonitor background videos (via Video.js) + +### Fixes: + +1. Fixes WebUI resource update not adding video submonitor backgrounds. I 100% recommend updating your WebUI assets. + +### Todo: +1. Figure out how to use image (png) files to appear in information/news popup. +2. Figure out how demoloop works. +3. More work/research on online matchmaking (globalMatch.) I can't seem to make clients establish a connection. + + ## fork-6.0.2.1 ### Fixes: 1. Fixed missing Megamix songs (extend string param getting cut off) + ## fork-6.0.2.0 ### New: @@ -42,7 +76,7 @@ Changelog 7. Added support for System Backgrounds 8. Added event data: - BPL S3 Triple Tribe songs unlock toggle (suspicions, etc.) - - KAC 2023 song unlock toggle (Perfect Eater) + - KAC 2023 song unlock toggle (パーフェクトイーター) - KAC 2023 song stamp event (for 累乗のカルマ) - KAC 2023 song stamp event (for Stylus & QQ) 9. Updated licensed songs and valk-exclusive songs list @@ -61,9 +95,3 @@ Changelog 2. Fixed bug in stamp select data. 3. Fixed bug for when common.ts or profiles.ts is looking for a specific event key but it is undefined. 3. Skill Analyzer: skill level requirement for Lv.11 and ∞. Song input/unlock status must be met as well, or just use the unlock all songs option in the WebUI. - -### Todo: -1. BPL Season 2 Special Stamp Event Implementation - - All songs on the stamp event selection screen should be completed and unlocked for SuddeИDeath to appear. Still don't know how to implement that. -2. Figure out how to use image (png) files to appear in information/news popup and in demo_info. -3. Megamix Battle song list updated but I cannot make a lot of them appear in the list. diff --git a/sdvx@asphyxia/data/exg.ts b/sdvx@asphyxia/data/exg.ts index 7e94563..7d1c1a5 100644 --- a/sdvx@asphyxia/data/exg.ts +++ b/sdvx@asphyxia/data/exg.ts @@ -371,6 +371,14 @@ export const STAMP_EVENTS6 = { 'bnr': 'sheet_track_1938', 'stps': 30, 'stprwrd': [ + ['0', 'prereq', 'x', '14'], + ['0', 'prereq', 'x', '15'], + ['0', 'prereq', 'x', '16'], + ['0', 'prereq', 'x', '17'], + ['0', 'prereq', 'x', '18'], + ['0', 'prereq', 'x', '19'], + ['0', 'prereq', 'x', '20'], + ['0', 'prereq', 'x', '21'], ['30', 'track', '1938', '23'] ] } @@ -431,9 +439,15 @@ export const STAMP_EVENTS6 = { export const EVENT_SONGS6 = { // X-Record songs - 'xrecord_1': ['1736', '1737', '1738'], - 'xrecord_2': ['1847', '1848', '1849'], - 'xrecord_3': ['1980', '1978', '1979'], + 'xrecord_1_1': ['1737'], + 'xrecord_1_2': ['1738'], + 'xrecord_1_3': ['1736'], + 'xrecord_2_1': ['1848'], + 'xrecord_2_2': ['1849'], + 'xrecord_2_3': ['1847'], + 'xrecord_3_1': ['1979'], + 'xrecord_3_2': ['1980'], + 'xrecord_3_3': ['1978'], // Konaste songs 'konasute_1': ['1762'], 'konasute_2': ['1763'], @@ -441,15 +455,25 @@ export const EVENT_SONGS6 = { 'konasute_4': ['1765'], 'konasute_5': ['1811'], // BPL2021 songs - 'bpl2021': ['1808', '1809'], + 'bpl2021_1': ['1808'], + 'bpl2021_2': ['1809'], // BSB2021 songs - 'bsb2021': ['1802', '1803', '1804', '1805', '1806', '1807'], + 'bsb2021_1': ['1802'], + 'bsb2021_2': ['1803'], + 'bsb2021_3': ['1804'], + 'bsb2021_4': ['1805'], + 'bsb2021_5': ['1806'], + 'bsb2021_6': ['1807'], // SDVX 10th anniversary stamp event songs 'sdvx10thstamp': ['1838', '1839', '1840', '1841', '1842', '1843', '1844'], // REFLECT BEAT stamp event songs 'reflecstamp': ['1850', '1851', '1852', '1853', '1854'], // BEMANI ichika 2022 event songs - 'gmz2022': ['1906', '1907', '1908', '1909', '1910'], + 'gmz2022_1': ['1906'], + 'gmz2022_2': ['1907'], + 'gmz2022_3': ['1908'], + 'gmz2022_4': ['1909'], + 'gmz2022_5': ['1910'], // BPL2022 songs "bpl2022_1": ['1952', '1943'], "bpl2022_2": ['1948', '1951'], @@ -470,7 +494,9 @@ export const EVENT_SONGS6 = { // BPL S3 Triple Tribe "bpls3songs_1": ['2063'], "bpls3songs_2": ['2064'], - "bpls3songs_3": ['2065'] + "bpls3songs_3": ['2065'], + // CHASECHASEJOKERS song + "ccjsong": ['2027'] } export const APRILFOOLSSONGS = [ @@ -484,9 +510,12 @@ export const VALKYRIE_SONGS = [ ] export const ARENA = { - 'Set 1 (04/25/22)': { + 'None': {}, + 'Season 1 (ARENA BATTLE 2022/04/25~2022/06/05)': { details: { - // season: 1, + season: 1, + rule: 0, + rank_match_target: 0, time_start: BigInt(Date.parse('25 Apr 2022 00:00:00 GMT')), time_end: BigInt(Date.parse('31 Dec 2099 23:59:59 GMT')), shop_start: BigInt(Date.parse('25 Apr 2022 00:00:00 GMT')), @@ -585,9 +614,11 @@ export const ARENA = { }, ] }, - 'Set 2 (06/30/22)': { + 'Season 2 (ARENA BATTLE 2022/06/30~2022/08/14)': { details: { - // season: 2, + season: 2, + rule: 1, + rank_match_target: 0, time_start: BigInt(Date.parse('30 Jun 2022 00:00:00 GMT')), time_end: BigInt(Date.parse('31 Dec 2099 23:59:59 GMT')), shop_start: BigInt(Date.parse('30 Jun 2022 00:00:00 GMT')), @@ -652,11 +683,13 @@ export const ARENA = { item_id: 132, param: 8, } - ], - }, - 'Set 3 (09/01/22)': { + ] + }, + 'Season 3 (ARENA BATTLE 2022/09/01~2022/10/02)': { details: { - // season: 3, + season: 3, + rule: 1, + rank_match_target: 0, time_start: BigInt(Date.parse('01 Sep 2022 00:00:00 GMT')), time_end: BigInt(Date.parse('31 Dec 2099 23:59:59 GMT')), shop_start: BigInt(Date.parse('01 Sep 2022 00:00:00 GMT')), @@ -721,11 +754,13 @@ export const ARENA = { item_id: 323, param: 8, } - ], + ] }, - 'Set 4 (10/20/22)': { + 'Season 4 (ARENA BATTLE 2022/10/20~2022/11/13)': { details: { - // season: 4, + season: 4, + rule: 1, + rank_match_target: 0, time_start: BigInt(Date.parse('20 Oct 2022 00:00:00 GMT')), time_end: BigInt(Date.parse('31 Dec 2099 23:59:59 GMT')), shop_start: BigInt(Date.parse('20 Oct 2022 00:00:00 GMT')), @@ -830,11 +865,13 @@ export const ARENA = { item_id: 88, param: 8, }, - ], + ] }, - 'Set 5 (12/22/22)': { + 'Season 5 (ARENA BATTLE 2022/12/22~2023/01/16)': { details: { - // season: 4, + season: 5, + rule: 1, + rank_match_target: 0, time_start: BigInt(Date.parse('22 Dec 2022 00:00:00 GMT')), time_end: BigInt(Date.parse('31 Dec 2099 23:59:59 GMT')), shop_start: BigInt(Date.parse('22 Dec 2022 00:00:00 GMT')), @@ -909,9 +946,11 @@ export const ARENA = { } ] }, - 'Set 6 (02/16/23)': { + 'Season 6 (ARENA BATTLE 2023/02/16~2023/03/13)': { details: { - // season: 4, + season: 6, + rule: 1, + rank_match_target: 0, time_start: BigInt(Date.parse('16 Feb 2023 00:00:00 GMT')), time_end: BigInt(Date.parse('31 Dec 2099 23:59:59 GMT')), shop_start: BigInt(Date.parse('16 Feb 2023 00:00:00 GMT')), @@ -978,9 +1017,11 @@ export const ARENA = { } ] }, - 'Set 7 (04/27/23)': { + 'Season 7 (SINGLE BATTLE 2023/04/27~2023/05/15)': { details: { - // season: 4, + season: 7, + rule: 1, + rank_match_target: 1, time_start: BigInt(Date.parse('27 Apr 2023 00:00:00 GMT')), time_end: BigInt(Date.parse('31 Dec 2099 23:59:59 GMT')), shop_start: BigInt(Date.parse('27 Apr 2023 00:00:00 GMT')), @@ -1127,9 +1168,11 @@ export const ARENA = { } ] }, - 'Set 8 (06/08/23)': { + 'Season 8 (SINGLE BATTLE 2023/06/08~2023/06/26)': { details: { - // season: 4, + season: 8, + rule: 1, + rank_match_target: 1, time_start: BigInt(Date.parse('8 Jun 2023 00:00:00 GMT')), time_end: BigInt(Date.parse('31 Dec 2099 23:59:59 GMT')), shop_start: BigInt(Date.parse('8 Jun 2023 00:00:00 GMT')), @@ -1228,9 +1271,11 @@ export const ARENA = { } ] }, - 'Set 9 (07/13/23)': { + 'Season 9 (ARENA BATTLE 2023/07/13~2023/07/31)': { details: { - // season: 4, + season: 9, + rule: 1, + rank_match_target: 0, time_start: BigInt(Date.parse('13 Jul 2023 00:00:00 GMT')), time_end: BigInt(Date.parse('31 Dec 2099 23:59:59 GMT')), shop_start: BigInt(Date.parse('13 Jul 2023 00:00:00 GMT')), @@ -1321,9 +1366,11 @@ export const ARENA = { } ] }, - 'Set 10 (08/17/23)': { + 'Season 10 (SINGLE BATTLE 2023/08/17~2023/09/04)': { details: { - // season: 4, + season: 10, + rule: 1, + rank_match_target: 1, time_start: BigInt(Date.parse('17 Aug 2023 00:00:00 GMT')), time_end: BigInt(Date.parse('31 Dec 2099 23:59:59 GMT')), shop_start: BigInt(Date.parse('17 Aug 2023 00:00:00 GMT')), diff --git a/sdvx@asphyxia/handlers/common.ts b/sdvx@asphyxia/handlers/common.ts index 838c561..fce753a 100644 --- a/sdvx@asphyxia/handlers/common.ts +++ b/sdvx@asphyxia/handlers/common.ts @@ -15,7 +15,7 @@ export const common: EPR = async (info, data, send) => { 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('====================================') console.log("Calling common function"); const version = parseInt(info.model.split(":")[4]); @@ -146,7 +146,7 @@ export const common: EPR = async (info, data, send) => { ' [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]メリー。。。クリスマス、です。。。'+ + '[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]', '', @@ -181,7 +181,7 @@ export const common: EPR = async (info, data, send) => { } if(IO.Exists('webui/asset/config/events.json')) { - const itemTypeList = {"track": 'e', "appeal": 'a', "crew": 'c', "pcb": 'b'} + 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()) @@ -198,7 +198,7 @@ export const common: EPR = async (info, data, send) => { prmStr1Sel += stmpEvntInfo['info']['data'][stmpDataIter]['stmpid'] + '#' + stmpEvntInfo['info']['data'][stmpDataIter]['bnr'] + '#' + itemTypeList[stmpRwrd[stmpRwrd.length - 1][1]] + '#' + sSheetName + (stmpEvntInfo['info']['data'].length - 1 === parseInt(stmpDataIter) ? '' : ',') for(const stmpRwrdIter in stmpRwrd) { let iID = stmpRwrd[stmpRwrdIter][2] - if (stmpRwrd[stmpRwrdIter][1] === 'track') iID += stmpRwrd[stmpRwrdIter][3] + if (stmpRwrd[stmpRwrdIter][1] === 'track' || stmpRwrd[stmpRwrdIter][1] === 'prereq') iID += stmpRwrd[stmpRwrdIter][3] prmStr5 += stmpRwrd[stmpRwrdIter][0] + ':' + itemTypeList[stmpRwrd[stmpRwrdIter][1]] + ':' + iID + (stmpRwrd.length - 1 === parseInt(stmpRwrdIter) ? '' : ' ') } let newSelMainExtend = { @@ -343,28 +343,30 @@ export const common: EPR = async (info, data, send) => { console.log("Sending common objects"); + let arena_szn = U.GetConfig('arena_szn') let arena_catalog_items = [] - let catalog = [] - let campaign = [] - for (let catalog_item in ARENA[U.GetConfig('arena_szn')].arena_items) { - arena_catalog_items.push({ - catalog_id: K.ITEM('s32', ARENA[U.GetConfig('arena_szn')].arena_items[catalog_item].catalog_id), - catalog_type: K.ITEM('s32', ARENA[U.GetConfig('arena_szn')].arena_items[catalog_item].catalog_type), - price: K.ITEM('s32', ARENA[U.GetConfig('arena_szn')].arena_items[catalog_item].price), - item_type: K.ITEM('s32', ARENA[U.GetConfig('arena_szn')].arena_items[catalog_item].item_type), - item_id: K.ITEM('s32', ARENA[U.GetConfig('arena_szn')].arena_items[catalog_item].item_id), - param: K.ITEM('s32', ARENA[U.GetConfig('arena_szn')].arena_items[catalog_item].param), - }) + 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.forEach(val => valgene_info.push({ + + 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) => { @@ -399,16 +401,18 @@ export const common: EPR = async (info, data, send) => { info: valgene_info, catalog: valgene_items }, - arena: { - // season: K.ITEM('s32', ARENA[U.GetConfig('arena_szn')].details.season), - time_start: K.ITEM('u64', ARENA[U.GetConfig('arena_szn')].details.time_start), - time_end: K.ITEM('u64', ARENA[U.GetConfig('arena_szn')].details.time_end), - shop_start: K.ITEM('u64', ARENA[U.GetConfig('arena_szn')].details.shop_start), - shop_end: K.ITEM('u64', ARENA[U.GetConfig('arena_szn')].details.shop_end), - is_open: K.ITEM('bool', ARENA[U.GetConfig('arena_szn')].details.is_open), - is_shop: K.ITEM('bool', ARENA[U.GetConfig('arena_szn')].details.is_shop), + 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), diff --git a/sdvx@asphyxia/handlers/features.ts b/sdvx@asphyxia/handlers/features.ts index a57c7d4..6eeab8d 100644 --- a/sdvx@asphyxia/handlers/features.ts +++ b/sdvx@asphyxia/handlers/features.ts @@ -1,5 +1,6 @@ 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'; @@ -156,27 +157,84 @@ export const loadMix: EPR = async (info, data, send) => { }; export const globalMatch: EPR = async (info, data, send) => { - // console.log("Current MID: "+$(data).number('mid')); - // console.log("Port: "+$(data).number('port')); - // console.log("Global IP: "+$(data).numbers('gip')); - // console.log("Private IP: "+$(data).numbers('lip')); + 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') + } - // var mid = $(data).number('mid'); - // var port = $(data).number('port'); - // var gip = $(data).str('gip'); - // var lip = $(data).str('lip'); - // var testArray = [{ - // port: port, - // gip:gip, - // lip:lip, - // }]; - // return send.object({ - // entry_id: K.ITEM('str', '123456789'), - // entry: testArray.map(a=>{ - // port: K.ITEM('u16',a.port); - // gip: K.ITEM('ip4',a.gip); - // lip: K.ITEM('ip4',a.lip); - // }) - // }); - send.success(); + let loggip = entryData.gip.join(".") + + console.log("====================================") + console.log("[" + loggip + "] Searching for online match opponents") + console.log("[" + loggip + "] Removed " + await DB.Remove({collection:'matchmaker', timestamp: {$lt: Date.now() - 100000}}) + " expired match data.") + + if(entryData.p_rest < 1) { + console.log("[" + loggip + "] Room is full. Halting.") + return send.deny(); + } + + // 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("[" + loggip + "] Adding/updating your match data") + if(await DB.Count({collection: 'matchmaker', gip: entryData.gip}) === 0) { + await DB.Upsert( + { collection: 'matchmaker', gip: entryData.gip }, + entryData + ) + } else { + await DB.Upsert( + { collection: 'matchmaker', gip: entryData.gip}, + { $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 + } + } + ) + } + + console.log("[" + loggip + "] Searching...") + let filteredDB = await DB.Find({collection: "matchmaker", entry_id: entryData.entry_id, filter: entryData.filter, $not: {gip: entryData.gip}}) + + let opponents = filteredDB.length === 0 ? null : { + entry_id: K.ITEM('u32', entryData.entry_id), + entry: filteredDB.map(e => ({ + port: K.ITEM('u16', e.port), + gip: K.ITEM('4u8', e.gip), + lip: K.ITEM('4u8', e.lip) + })) + } + if(opponents !== null) { + console.log("[" + loggip + "] Opponent/s found.") + send.object(opponents) + } + else { + console.log("[" + loggip + "] No found opponents.") + send.deny() + } } diff --git a/sdvx@asphyxia/handlers/profiles.ts b/sdvx@asphyxia/handlers/profiles.ts index 412a0df..ed3705b 100644 --- a/sdvx@asphyxia/handlers/profiles.ts +++ b/sdvx@asphyxia/handlers/profiles.ts @@ -593,9 +593,10 @@ export const save: EPR = async (info, data, send) => { // Save Arena Data const arena_data = $(data).elements('arena'); for (const are of arena_data) { - const earnedUR = are.number('earned_ultimate_rate'); - const earnedSP = are.number('earned_shop_point'); + const szn = are.number('season'); const earnedRP = are.number('earned_rank_point'); + const earnedSP = are.number('earned_shop_point'); + const earnedUR = are.number('earned_ultimate_rate'); const earnedLE = are.number('earned_live_energy'); const rankPlay = are.str('rank_play') == 'true' ? 1 : 0; const ultimatePlay = are.str('ultimate_play') == 'true' ? 1 : 0; @@ -603,7 +604,7 @@ export const save: EPR = async (info, data, send) => { refid, { collection: 'arena', - season: Object.keys(ARENA).findIndex(data => data == U.GetConfig('arena_szn')) + 1 + season: szn }, { $inc: { @@ -653,7 +654,7 @@ export const load: EPR = async (info, data, send) => { let eventData = JSON.parse(bufEventData.toString()) let eventConfig = JSON.parse(bufEventConfig.toString()) for(const eventIter in eventData['events']) { - if(eventData['events'][eventIter]['type'] === 'gift' && eventConfig[eventData['events'][eventIter]['id']] !== undefined) { + if(['gift', 'cross_online'].includes(eventData['events'][eventIter]['type']) && eventConfig[eventData['events'][eventIter]['id']] !== undefined) { if(typeof eventConfig[eventData['events'][eventIter]['id']]['toggle'] === "boolean") { if(eventConfig[eventData['events'][eventIter]['id']]['toggle']) { for(const itemIter in EVENT_SONGS6[eventData['events'][eventIter]['id']]) { @@ -739,12 +740,16 @@ export const load: EPR = async (info, data, send) => { const stampB = profile.stampB ? profile.stampB : 0; const stampC = profile.stampC ? profile.stampC : 0; const stampD = profile.stampD ? profile.stampD : 0; + const stampRA = profile.stampRA ? profile.stampRA : 0; + const stampRB = profile.stampRB ? profile.stampRB : 0; + const stampRC = profile.stampRC ? profile.stampRC : 0; + const stampRD = profile.stampRD ? profile.stampRD : 0; const sysBG = profile.sysBG ? profile.sysBG : 0; const bplSupport = profile.bplSupport ? profile.bplSupport : 0; const customize = []; - customize.push(bgm, subbg, nemsys, stampA, stampB, stampC, stampD, 0, 0, 0, 0, sysBG); + customize.push(bgm, subbg, nemsys, stampA, stampB, stampC, stampD, stampRA, stampRB, stampRC, stampRD, sysBG); var tempCustom = params.findIndex((e) => (e.type == 2 && e.id == 2)) @@ -828,6 +833,10 @@ export const create: EPR = async (info, data, send) => { stampB: 0, stampC: 0, stampD: 0, + stampRA: 0, + stampRB: 0, + stampRC: 0, + stampRD: 0, sysBG: 0, diff --git a/sdvx@asphyxia/handlers/webui.ts b/sdvx@asphyxia/handlers/webui.ts index eb9e0c7..160e4f9 100644 --- a/sdvx@asphyxia/handlers/webui.ts +++ b/sdvx@asphyxia/handlers/webui.ts @@ -17,6 +17,10 @@ export const updateProfile = async (data: { stampB?: string; stampC?: string; stampD?: string; + stampRA?: string; + stampRB?: string; + stampRC?: string; + stampRD?: string; sysBG?: string; }) => { if (data.refid == null) return; @@ -81,6 +85,26 @@ export const updateProfile = async (data: { 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) { console.log(data.sysBG) const validSysBG = parseInt(data.sysBG); @@ -315,7 +339,7 @@ export const copyResourcesFromGame = async (data: {}, send: WebUISend) => { let nemsysId = parseInt(nemsys.name.match(/([0-9]+)/g)[0]) if(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 + " (please rename)"}) + resourceJsonData.nemsys.push({"value": nemsysId, "name": nemsys.name}) } } } @@ -329,9 +353,9 @@ export const copyResourcesFromGame = async (data: {}, send: WebUISend) => { 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(/(\.png|\.jpg)/g)) { + if (subbg.name.match(/(\.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")) { + 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) @@ -340,11 +364,19 @@ export const copyResourcesFromGame = async (data: {}, send: WebUISend) => { let subbgId = parseInt(subbg.name.match(/([0-9]+)/g)[0]) if(subbgId) { let subbgName = subbg.name - let foundSubbg = resourceJsonData.subbg.find(subbg => subbg.value === subbgId) - if(foundSubbg == undefined) { - if(subbg.name.match(/(subbg_[0-9]+_[0-9]+)/g)) subbgName = subbg.name.match(/(subbg_[0-9]+)/g)[0] - console.log("[subbg] adding to json: " + subbgId + " - " + subbgName) - resourceJsonData.subbg.push({"value": subbgId, "name": subbgName + " (please rename)"}) + 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' + console.log("[subbg] adding to json: " + subbgId + " - " + subbgName) + if(foundSubbg == -1) { + resourceJsonData.subbg.push({"value": subbgId, "type": subbgType, "name": subbgName}) + } else { + resourceJsonData.subbg[foundSubbg] = {"value": subbgId, "type": subbgType, "name": subbgName} } } } @@ -372,7 +404,7 @@ export const copyResourcesFromGame = async (data: {}, send: WebUISend) => { 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) - resourceJsonData.bgm.push({"value": bgmId, "name": bgm.name + " (please rename)"}) + resourceJsonData.bgm.push({"value": bgmId, "name": bgm.name}) } } } @@ -467,19 +499,19 @@ export const copyResourcesFromGame = async (data: {}, send: WebUISend) => { await IO.WriteFile('webui/asset/json/appeal.json', JSON.stringify(apCardJsonData, null, 4)) send.json( { - status: 'ok', - 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 - } + status: 'ok', + 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 + } ) } diff --git a/sdvx@asphyxia/index.ts b/sdvx@asphyxia/index.ts index 9648784..5122a29 100644 --- a/sdvx@asphyxia/index.ts +++ b/sdvx@asphyxia/index.ts @@ -31,7 +31,7 @@ export function register() { R.Contributor("ovv (this fork)"); R.GameCode('KFC'); - R.Config('arena_szn',{ type: 'string', options: Object.keys(ARENA), default: 'Set 1 (04/25/22)', name: 'Arena Station Item Set', desc: 'Choose which season set of items in the arena station you want to show up in arena station'}); + 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('new_year_special',{ type: 'boolean', default: false, name:'Use New Year Special', desc:'Enable New Year Special BGM for login (doesn\'t work right now)'}); // R.Config('april_fools',{ type: 'boolean', default: false, name:'April Fools', desc:'Enable April Fools Event (doesn\'t work properly right now)'}); @@ -91,7 +91,7 @@ export function register() { nxt_time: K.ITEM('u32', 1000 * 5 * 60) })); MultiRoute('save_e', saveE); - MultiRoute('save_mega',true); + MultiRoute('save_mega', true); MultiRoute('play_e', true); MultiRoute('play_s', true); MultiRoute('entry_s', globalMatch); diff --git a/sdvx@asphyxia/models/profile.ts b/sdvx@asphyxia/models/profile.ts index 851b327..8be2c74 100644 --- a/sdvx@asphyxia/models/profile.ts +++ b/sdvx@asphyxia/models/profile.ts @@ -41,6 +41,10 @@ export interface Profile { stampB: number; stampC: number; stampD: number; + stampRA: number; + stampRB: number; + stampRC: number; + stampRD: number; sysBG: number; boothFrame: number[]; diff --git a/sdvx@asphyxia/models/xrecord.ts b/sdvx@asphyxia/models/xrecord.ts deleted file mode 100644 index e549afb..0000000 --- a/sdvx@asphyxia/models/xrecord.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface XRecord { - collection: 'x-record'; - - lm: number; - vm: number; -} diff --git a/sdvx@asphyxia/templates/load.pug b/sdvx@asphyxia/templates/load.pug index 51b8ff0..8c575d5 100644 --- a/sdvx@asphyxia/templates/load.pug +++ b/sdvx@asphyxia/templates/load.pug @@ -133,9 +133,10 @@ game if arena arena - ultimate_rate(__type="s32") #{arena.ultimateRate} - shop_point(__type="s32") #{arena.shopPoint} + last_play_season(__type="s32") #{arena.season !== undefined ? arena.season : 0} rank_point(__type="s32") #{arena.rankPoint} - live_energy(__type="s32") #{arena.liveEnergy} + shop_point(__type="s32") #{arena.shopPoint} + ultimate_rate(__type="s32") #{arena.ultimateRate} + ultimate_rank_num(__type="s32") #{arena.ultimateRankNum !== undefined ? arena.ultimateRankNum : 0} rank_play_cnt(__type="s32") #{arena.rankCount} ultimate_play_cnt(__type="s32") #{arena.ultimateCount} diff --git a/sdvx@asphyxia/webui/asset/js/events.js b/sdvx@asphyxia/webui/asset/js/events.js index 141ca0c..49e8a28 100644 --- a/sdvx@asphyxia/webui/asset/js/events.js +++ b/sdvx@asphyxia/webui/asset/js/events.js @@ -1,5 +1,10 @@ function generateEventToggles(eventInfo, eventConfig, eventEnabled) { let cardContent = $('
') + cardContent.append('
" + eventInfo['name'] + "") + ).append( + $("

" + eventInfo['desc'] + "

") + ) if(typeof eventInfo['info'] === 'string') { cardContent.append( $('
').append( @@ -95,6 +100,7 @@ $(document).ready(async function() { if(eventData['events'][eventIter]['id'] === $(value).parent().children('input').attr('name')) { eventConfig[eventData['events'][eventIter]['id']]['toggle'] = toggle } else if ($(value).parent().children('input').attr('name').includes(eventData['events'][eventIter]['id'] + "_")) { + if(eventConfig[eventData['events'][eventIter]['id']]['toggle'] !== undefined && typeof eventConfig[eventData['events'][eventIter]['id']]['toggle'] === 'boolean') eventConfig[eventData['events'][eventIter]['id']]['toggle'] = {} eventConfig[eventData['events'][eventIter]['id']]['toggle'][[$(value).parent().children('input').attr('name')]] = toggle } } diff --git a/sdvx@asphyxia/webui/asset/js/preview.js b/sdvx@asphyxia/webui/asset/js/preview.js index 26db218..fde88cc 100644 --- a/sdvx@asphyxia/webui/asset/js/preview.js +++ b/sdvx@asphyxia/webui/asset/js/preview.js @@ -5,21 +5,16 @@ function zeroPad(num, places) { function getImageFileFormat(assetType, id) { if(assetType == 0) { - return (id >= 103) ? '.png' : '.jpg' + if (id >= 103) { + if (id >= 359 && id <= 368) { + return '.mp4' + } + return '.png' + } + return '.jpg' } } -function checkPregeneSubbg(subbg) { - let stat = $.ajax({ - url:'static/asset/submonitor_bg/subbg_' + zeroPad(subbg, 4) + getImageFileFormat(0, parseInt(zeroPad(subbg, 4))), - type:'HEAD', - async: false - }).status; - if(stat === 200) return false - else return true -} - -; (function($) { $.preload = function() { var imgs = Object.prototype.toString.call(arguments[0]) === '[object Array]' ? @@ -46,9 +41,17 @@ $('#nemsys_select').change(function() { }); $('[name="subbg"]').change(async function() { - let isSubbgSlideshow = checkPregeneSubbg($('[name="subbg"]').val()) - $('#sub_pre').fadeOut(200, () => { $('#sub_pre').attr("src", isSubbgSlideshow ? "static/asset/submonitor_bg/subbg_" + zeroPad($('[name="subbg"]').val(), 4) + "_0" + (Math.floor(Math.random() * 3) + 1) + getImageFileFormat(0, parseInt(zeroPad($('[name="subbg"]').val(), 4))) : "static/asset/submonitor_bg/subbg_" + zeroPad($('[name="subbg"]').val(), 4) + getImageFileFormat(0, parseInt(zeroPad($('[name="subbg"]').val(), 4)) )); }); - $('#sub_pre').fadeIn(200); + let isSubbgSlideshow = (database['subbg'][$('[name="subbg"]').val()]['type'] === 'slideshow') + $('#sub_pre').fadeOut(200) + $('#sub_pre_vid').fadeOut(200) + if(getImageFileFormat(0, parseInt(zeroPad($('[name="subbg"]').val(), 4))) === '.mp4') { + $('#sub_pre_vid_src').attr('src', "static/asset/submonitor_bg/subbg_" + zeroPad($('[name="subbg"]').val(), 4) + getImageFileFormat(0, parseInt(zeroPad($('[name="subbg"]').val(), 4)))) + document.getElementById('sub_pre_vid').load() + $('#sub_pre_vid').fadeIn(200) + } else { + $('#sub_pre').fadeOut(200, () => { $('#sub_pre').attr("src", isSubbgSlideshow ? "static/asset/submonitor_bg/subbg_" + zeroPad($('[name="subbg"]').val(), 4) + "_0" + (Math.floor(Math.random() * 3) + 1) + getImageFileFormat(0, parseInt(zeroPad($('[name="subbg"]').val(), 4))) : "static/asset/submonitor_bg/subbg_" + zeroPad($('[name="subbg"]').val(), 4) + getImageFileFormat(0, parseInt(zeroPad($('[name="subbg"]').val(), 4)) )); }); + $('#sub_pre').fadeIn(200); + } }); $('[name="bgm"]').change(function() { @@ -75,8 +78,6 @@ $('[name="bgm"]').change(function() { var testcurrent = 2.8; - - $('[name="stampA"]').change(function() { $('#a_pre').fadeOut(200, () => { var stamp = $('[name="stampA"]').val(); @@ -136,6 +137,66 @@ $('[name="stampD"]').change(function() { }); $('#d_pre').fadeIn(200); }); + +$('[name="stampRA"]').change(function() { + $('#ra_pre').fadeOut(200, () => { + var stamp = $('[name="stampRA"]').val(); + if (stamp == 0) { + $('#ra_pre').attr("src", "static/asset/nostamp.png"); + } else { + var group = Math.trunc((stamp - 1) / 4 + 1); + var item = stamp % 4; + if (item == 0) item = 4; + $('#ra_pre').attr("src", "static/asset/chat_stamp/stamp_" + zeroPad(group, 4) + "/stamp_" + zeroPad(group, 4) + "_" + zeroPad(item, 2) + ".png"); + } + }); + $('#ra_pre').fadeIn(200); +}); + +$('[name="stampRB"]').change(function() { + $('#rb_pre').fadeOut(200, () => { + var stamp = $('[name="stampRB"]').val(); + if (stamp == 0) { + $('#rb_pre').attr("src", "static/asset/nostamp.png"); + } else { + var group = Math.trunc((stamp - 1) / 4 + 1); + var item = stamp % 4; + if (item == 0) item = 4; + $('#rb_pre').attr("src", "static/asset/chat_stamp/stamp_" + zeroPad(group, 4) + "/stamp_" + zeroPad(group, 4) + "_" + zeroPad(item, 2) + ".png"); + } + }); + $('#rb_pre').fadeIn(200); +}); + +$('[name="stampRC"]').change(function() { + $('#rc_pre').fadeOut(200, () => { + var stamp = $('[name="stampRC"]').val(); + if (stamp == 0) { + $('#rc_pre').attr("src", "static/asset/nostamp.png"); + } else { + var group = Math.trunc((stamp - 1) / 4 + 1); + var item = stamp % 4; + if (item == 0) item = 4; + $('#rc_pre').attr("src", "static/asset/chat_stamp/stamp_" + zeroPad(group, 4) + "/stamp_" + zeroPad(group, 4) + "_" + zeroPad(item, 2) + ".png"); + } + }); + $('#rc_pre').fadeIn(200); +}); + +$('[name="stampRD"]').change(function() { + $('#rd_pre').fadeOut(200, () => { + var stamp = $('[name="stampRD"]').val(); + if (stamp == 0) { + $('#rd_pre').attr("src", "static/asset/nostamp.png"); + } else { + var group = Math.trunc((stamp - 1) / 4 + 1); + var item = stamp % 4; + if (item == 0) item = 4; + $('#rd_pre').attr("src", "static/asset/chat_stamp/stamp_" + zeroPad(group, 4) + "/stamp_" + zeroPad(group, 4) + "_" + zeroPad(item, 2) + ".png"); + } + }); + $('#rd_pre').fadeIn(200); +}); var profile_data, database; var play_bgm = false; var play_sel = false; @@ -161,7 +222,6 @@ $(document).ready(function() { $('[name="bplSupport"]').val(profile_data["bplSupport"] ? profile_data["bplSupport"] : 0); for (var i in json["sysbg"]) { - console.log(json["sysbg"][i].id) if(unlock_all || (items_sysbg.find(x => x.id === json["sysbg"][i].id) || json["sysbg"][i].id === 0)) { $('[name="sysBG"]').append($('