From 834546e3baac1814662e9784cd7d440a273dc5e8 Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Sun, 29 Dec 2024 07:16:00 -0500 Subject: [PATCH] [+] TODO: Proxy matching --- .../aqua/sega/chusan/ChusanMatchingApis.kt | 72 ++++++++++++++++--- 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/src/main/java/icu/samnyan/aqua/sega/chusan/ChusanMatchingApis.kt b/src/main/java/icu/samnyan/aqua/sega/chusan/ChusanMatchingApis.kt index 1fd2f705..25b9d4e0 100644 --- a/src/main/java/icu/samnyan/aqua/sega/chusan/ChusanMatchingApis.kt +++ b/src/main/java/icu/samnyan/aqua/sega/chusan/ChusanMatchingApis.kt @@ -1,23 +1,29 @@ +@file:Suppress("UNCHECKED_CAST") + package icu.samnyan.aqua.sega.chusan -import ext.JDict -import ext.int -import ext.millis -import ext.parsing -import icu.samnyan.aqua.sega.chusan.model.response.data.MatchingMemberInfo +import ext.* import icu.samnyan.aqua.sega.chusan.model.response.data.MatchingWaitState +import icu.samnyan.aqua.sega.chusan.model.userdata.Chu3MatchingMemberReq -@Suppress("UNCHECKED_CAST") fun ChusanController.matchingApiInit() { + if (props.externalMatching.isNullOrBlank()) serverOnlyMatching() + else if (props.proxiedMatching) proxyMatching() +} + +/** + * Matching implementation that matches you to players in this server only (not tested very well) + */ +fun ChusanController.serverOnlyMatching() { // Matching - data class MatchingRoom(val members: MutableList, val startTime: Long) + data class MatchingRoom(val members: MutableList, val startTime: Long) val matchingRooms = mutableMapOf() var matchingLast = 0 val matchingTime = 120 // Seconds "BeginMatching" { - val memberInfo = parsing { mapper.convert(data["matchingMemberInfo"] as JDict) } + val memberInfo = parsing { mapper.convert(data["matchingMemberInfo"] as JDict) } // Check if there are any room available with less than 4 members and not started var id = matchingRooms.entries.find { it.value.members.size < 4 && it.value.startTime == 0L }?.key @@ -46,7 +52,53 @@ fun ChusanController.matchingApiInit() { "matchingMemberInfoList" to room.members, "matchingMemberRoleList" to room.members.indices.map { mapOf("role" to it) }, "matchingResult" to 1, - "reflectorUri" to "http://reflector.naominet.live:18080/" + "reflectorUri" to props.reflectorUrl ) } -} \ No newline at end of file +} + +/** + * Matching implementation + */ +fun ChusanController.proxyMatching() { + val ext = props.externalMatching!! + + // ID Cache is used to obfuscate the user ID + val processedCache = mutableSetOf() + val idCache = mutableMapOf() + + fun Chu3MatchingMemberReq.checkFromAquaDX(): Boolean { + if (userId in idCache) return true + if (userId in processedCache) return false + + // Check if this user is from our server + val user = db.userData.findByCard_ExtId(userId)() + if (user == null) { + // User is from another server, check if they have been checked in + if (db.matchingMember.existsByUserIdAndUserName(userId, userName)) { + // Check in + db.matchingMember.save(this) + log.info("[Matching] User $userId ($userName) not found, checking in.") + } + processedCache.add(userId) + } + else { + // Is from our server, obfuscate the user ID to enhance security + val randomId = (0..Int.MAX_VALUE).random().toLong() + idCache[randomId] = userId + userId = randomId + log.info("[Matching] User $userId ($userName) is from our server, obfuscated to $randomId.") + } + return user != null + } + + "BeginMatching" { + val member = parsing { mapper.convert(data["matchingMemberInfo"] as JDict) } + member.checkFromAquaDX() + + // Forward BeginMatching to external server +// val res = + } + + TODO("The external matching API is not implemented yet.") +}