From 397144a2a94ea4ea5726ce56542fcdda64498701 Mon Sep 17 00:00:00 2001 From: Kirito Date: Thu, 20 May 2021 10:51:49 +0900 Subject: [PATCH] Matching Support (Experimental) --- jubeat@asphyxia/README.md | 6 +- jubeat@asphyxia/handlers/common.ts | 38 ++++---- jubeat@asphyxia/handlers/matching.ts | 127 +++++++++++++++++++++++---- jubeat@asphyxia/index.ts | 74 +++++----------- jubeat@asphyxia/models/matching.ts | 18 ++++ jubeat@asphyxia/utils.ts | 15 +++- 6 files changed, 184 insertions(+), 94 deletions(-) create mode 100644 jubeat@asphyxia/models/matching.ts diff --git a/jubeat@asphyxia/README.md b/jubeat@asphyxia/README.md index 7ba2d49..bf52113 100644 --- a/jubeat@asphyxia/README.md +++ b/jubeat@asphyxia/README.md @@ -1,6 +1,6 @@ # Jubeat -Plugin Version: **v1.2.0** +Plugin Version: **v1.3.0** ### Supported Versions @@ -15,6 +15,10 @@ Plugin Version: **v1.2.0** *** +#### 1.3.0 + +- Matching Support (Experimental) + #### 1.2.0 - copious (APPEND) support diff --git a/jubeat@asphyxia/handlers/common.ts b/jubeat@asphyxia/handlers/common.ts index 06756a6..bd791cb 100644 --- a/jubeat@asphyxia/handlers/common.ts +++ b/jubeat@asphyxia/handlers/common.ts @@ -1,25 +1,27 @@ -import {getVersion} from "../utils"; +import {getVersion, VersionRange} from '../utils'; -export const shopinfo: EPR = (info, data, send) => { - const locId = $(data).content("shop.locationid"); +export const gameInfo: EPR = (info, data, send) => { + const locId = $(data).content('shop.locationid'); const version = getVersion(info); if (version === 0) return send.deny(); - if (version === 3 || version === 4) { - return send.object({ - data: { - cabid: K.ITEM('u32', 1), + return send.object({ + data: { + ...info.module === 'shopinfo' && { + cabid: K.ITEM('u32', _.random(1, 10)), locationid: K.ITEM('str', locId), - is_send: K.ITEM("u8", 1) - } - }); - } + ...VersionRange(version, 3, 6) && { is_send: K.ITEM('u8', 1) }, + }, - return send.deny(); + ...VersionRange(version, 5, 6) && { + white_music_list: K.ARRAY('s32', Array(32).fill(-1)) + } + } + }); }; export const demodata = { - getNews: (_, __, send) => send.object({ data: { officialnews: K.ATTR({ count: "0" }) } }), + getNews: (_, __, send) => send.object({ data: { officialnews: K.ATTR({ count: '0' }) } }), getData: (_, data, send) => { const newsId = $(data).number('officialnews.newsid'); return send.object({ @@ -38,15 +40,9 @@ export const demodata = { hitchart: { update: K.ITEM('str', ''), - hitchart_lic: K.ATTR({ count: "0" }), - hitchart_org: K.ATTR({ count: "0" }), + hitchart_lic: K.ATTR({ count: '0' }), + hitchart_org: K.ATTR({ count: '0' }), } } }), }; - -export const netlog: EPR = (info, data, send) => { - const errMsg = $(data).str('msg'); - console.error(errMsg); - return send.success(); -}; diff --git a/jubeat@asphyxia/handlers/matching.ts b/jubeat@asphyxia/handlers/matching.ts index e6b26ff..e200f43 100644 --- a/jubeat@asphyxia/handlers/matching.ts +++ b/jubeat@asphyxia/handlers/matching.ts @@ -1,4 +1,6 @@ -export const check: EPR = (info, data, send) => { +import {Room} from '../models/matching'; + +export const check: EPR = async (info, data, send) => { const enter = $(data).bool('data.enter'); const time = $(data).number('data.time'); @@ -9,46 +11,137 @@ export const check: EPR = (info, data, send) => { return send.object({ data: { entrant_nr: K.ITEM('u32', 1, { time: String(time) }), - interval: K.ITEM('s16', 1), - entry_timeout: K.ITEM('s16', U.GetConfig("matching_entry_timeout")), - waitlist: K.ATTR({ count: "0" }) + interval: K.ITEM('s16', 5), + entry_timeout: K.ITEM('s16', 30), + waitlist: K.ATTR({ count: '0' }) } }); }; -export const entry: EPR = (info, data, send) => { - const localMatchingNode = $(data).element("data.local_matching"); - const connectNode = $(data).element("data.connect"); +export const entry: EPR = async (info, data, send) => { + const localMatchingNode = $(data).element('data.local_matching'); + const connectNode = $(data).element('data.connect'); const musicNode = $(data).element('data.music'); - const roomId = _.random(1, 999999999999999); + const localKey = localMatchingNode.numbers('key'); + const connectKey = connectNode.numbers('key'); - // TODO Local matching support + let matchRoom = await DB.FindOne({ + collection: 'matching_rooms', + musicId: musicNode.number('id'), + seqId: musicNode.number('seq'), + isMatchEnd: false, + isFull: false + }); + + if (!matchRoom) { + matchRoom = { + collection: 'matching_rooms', + + version: $(data).number('data.version'), + roomId: _.random(1, 999999999), + masterKey: connectKey, + masterGlobal: connectNode.str('global'), + masterPrivate: connectNode.str('private'), + localKey, + musicId: musicNode.number('id'), + seqId: musicNode.number('seq'), + members: [ + { + cabid: $(data).number('data.cabid'), + addr: connectNode.str('private') + } + ], + isFull: false, + isMatchEnd: false + }; + + await DB.Upsert({ + collection: 'matching_rooms', localKey, + musicId: musicNode.number('id'), + seqId: musicNode.number('seq'), + isMatchEnd: false, + isFull: false + }, matchRoom); + } return send.object({ data: { - roomid: K.ITEM('s64', BigInt(roomId), { master: "1" }), - refresh_intr: K.ITEM('s16', 3), + roomid: K.ITEM('s64', BigInt(matchRoom.roomId), { master: matchRoom.masterKey === connectKey ? '1' : '0' }), + ...matchRoom.masterKey === connectKey && { + refresh_intr: K.ITEM('s16', 10), + }, + ...matchRoom.masterKey !== connectKey && { + connect: { + key: K.ARRAY('u8', matchRoom.masterKey), + global: K.ITEM('str', matchRoom.masterGlobal), + private: K.ITEM('str', matchRoom.masterPrivate), + } + }, music: { - id: K.ITEM("u32", musicNode.number("id")), - seq: K.ITEM("u8", musicNode.number("seq")), + id: K.ITEM('u32', matchRoom.musicId), + seq: K.ITEM('u8', matchRoom.seqId), } } }); }; -export const refresh: EPR = (info, data, send) => { +export const refresh: EPR = async (info, data, send) => { + const roomId = Number($(data).bigint('data.roomid')); + const pcbinfos = $(data).elements('data.joined.pcbinfo'); + + const room = await DB.FindOne({ collection: 'matching_rooms', roomId }); + + if (room) { + for (const i of pcbinfos) { + const cabid = i.number('cabid'); + const addr = i.str('addr'); + + for (const i of room.members) { + if (i.addr === addr) continue; + + room.members.push({ + cabid, + addr + }); + } + } + + await DB.Update({ collection: 'matching_rooms', roomId: Number(roomId) }, { + $set: { + members: room.members + } + }); + + if (room.members.length >= 4) { + await DB.Update({ collection: 'matching_rooms', roomId: Number(roomId) }, { + $set: { + isFull: true + } + }); + } + } + return send.object({ data: { - refresh_intr: K.ITEM('s16', 2), + refresh_intr: K.ITEM('s16', 5), + start: K.ITEM('bool', room.isFull) } }); }; -export const report: EPR = (info, data, send) => { +export const report: EPR = async (info, data, send) => { + const roomId = $(data).bigint('data.roomid'); + + await DB.Update({ collection: 'matching_rooms', roomId: Number(roomId) }, { + $set: { + isMatchEnd: true + } + }); + return send.object({ data: { - refresh_intr: K.ITEM('s16', 1), + refresh_intr: K.ITEM('s16', 3), } }); }; diff --git a/jubeat@asphyxia/index.ts b/jubeat@asphyxia/index.ts index 57ba8b8..967becd 100644 --- a/jubeat@asphyxia/index.ts +++ b/jubeat@asphyxia/index.ts @@ -1,65 +1,35 @@ -import {demodata, netlog, shopinfo} from "./handlers/common"; -import {check, entry, refresh, report} from "./handlers/matching"; -import {getCollabo, loadScore, meeting, profile, saveProfile} from "./handlers/profile"; +import {demodata, gameInfo} from './handlers/common'; +import {check, entry, refresh, report} from './handlers/matching'; +import {getCollabo, loadScore, meeting, profile, saveProfile} from './handlers/profile'; export function register() { if (CORE_VERSION_MAJOR <= 1 && CORE_VERSION_MINOR < 31) { - console.error("The current version of Asphyxia Core is not supported. Requires version '1.31' or later."); + console.error('The current version of Asphyxia Core is not supported. Requires version \'1.31\' or later.'); return; } - R.GameCode("J44"); - R.GameCode("K44"); + R.GameCode('J44'); + R.GameCode('K44'); - R.Config("unlock_all_songs", { - name: "Unlock All Songs", - desc: "Tired of unlocking songs? Have this!", - type: "boolean", - default: false - }); - - R.Config("quick_matching_end", { - name: "Quick Matching End", - desc: "Supported from clan to festo.", - type: "boolean", - default: false - }); - - R.Config("matching_entry_timeout", { - name: "Online Matching Timeout", - desc: "If online matching songs are too boring, save time! (second)", - type: "integer", - default: 30, - range: [15, 99], - }); - - R.Route("shopinfo.regist", shopinfo); - - R.Route("gametop.regist", profile); - R.Route("gametop.get_pdata", profile); - R.Route("gametop.get_mdata", loadScore); - R.Route("gametop.get_meeting", meeting); - R.Route("gametop.get_collabo", getCollabo); + R.Route('gametop.regist', profile); + R.Route('gametop.get_info', gameInfo); + R.Route('gametop.get_pdata', profile); + R.Route('gametop.get_mdata', loadScore); + R.Route('gametop.get_meeting', meeting); + R.Route('gametop.get_collabo', getCollabo); R.Route('gameend.regist', saveProfile); R.Route('gameend.log', true); R.Route('gameend.set_collabo', true); - R.Route("shopinfo.regist", shopinfo); - R.Route("netlog.send", netlog); - R.Route("demodata.get_news", demodata.getNews); - R.Route("demodata.get_data", demodata.getData); - R.Route("demodata.get_hitchart", demodata.getHitchart); - R.Route("lobby.check", check); - R.Route("lobby.entry", entry); - R.Route("lobby.refresh", refresh); - R.Route("lobby.report", report); + R.Route('shopinfo.regist', gameInfo); + R.Route('demodata.get_news', demodata.getNews); + R.Route('demodata.get_data', demodata.getData); + R.Route('demodata.get_hitchart', demodata.getHitchart); + R.Route('lobby.check', check); + R.Route('lobby.entry', entry); + R.Route('lobby.refresh', refresh); + R.Route('lobby.report', report); - R.Route("logger.report", true); - - R.Unhandled((info, data, send) => { - console.log(info.module, info.method); - console.log(U.toXML(data)); - - return send.deny(); - }); + R.Route('netlog.send', true); + R.Route('logger.report', true); } diff --git a/jubeat@asphyxia/models/matching.ts b/jubeat@asphyxia/models/matching.ts new file mode 100644 index 0000000..79597a4 --- /dev/null +++ b/jubeat@asphyxia/models/matching.ts @@ -0,0 +1,18 @@ +export interface Room { + collection: 'matching_rooms'; + + version: number; + roomId: number; + masterKey: number[]; + masterGlobal: string; + masterPrivate: string; + localKey: number[]; + musicId: number; + seqId: number; + members: { + cabid: number; + addr: string; + }[]; + isFull: boolean; + isMatchEnd: boolean; +} diff --git a/jubeat@asphyxia/utils.ts b/jubeat@asphyxia/utils.ts index 322b855..2ebb467 100644 --- a/jubeat@asphyxia/utils.ts +++ b/jubeat@asphyxia/utils.ts @@ -1,7 +1,16 @@ export function getVersion({ model }: EamuseInfo) { - const dateCode = model.split(':')[4]; + const dateCode = parseInt(model.split(':')[4]); - if (model.startsWith("J44")) return 3; - if (model.startsWith("K44")) return 4; + if (model.startsWith('J44')) return 3; + if (model.startsWith('K44')) return 4; + if (model.startsWith('L44')) { + if (dateCode >= 2014030303 && dateCode <= 2014121802) return 6; + return 0; + } return 0; } + +export function VersionRange(version: number, start: number, end: number = -1) { + if (end === -1) return version >= start; + return version >= start && version <= end; +}