From 33246e52b60cbef6bda82316eb502497cb325154 Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sat, 9 Jul 2022 01:04:29 +0800 Subject: [PATCH] Support sided obfuscated names, handle namespace localization --- .../shedaniel/linkie/web/LinkieWebServer.kt | 32 +++++++++++++- frontend/src/app/backend.ts | 12 ++++++ .../mappings/MappingsEntryBlock.vue | 42 ++++++++++++++---- .../mappings/MappingsFilterBlock.vue | 43 +++++++++++++++---- frontend/src/routes/Mappings.vue | 12 ++++++ 5 files changed, 121 insertions(+), 20 deletions(-) diff --git a/backend/src/main/kotlin/me/shedaniel/linkie/web/LinkieWebServer.kt b/backend/src/main/kotlin/me/shedaniel/linkie/web/LinkieWebServer.kt index de87f99..75a2770 100644 --- a/backend/src/main/kotlin/me/shedaniel/linkie/web/LinkieWebServer.kt +++ b/backend/src/main/kotlin/me/shedaniel/linkie/web/LinkieWebServer.kt @@ -31,8 +31,12 @@ import me.shedaniel.linkie.Method import me.shedaniel.linkie.Namespaces import me.shedaniel.linkie.getClassByObfName import me.shedaniel.linkie.getMappedDesc +import me.shedaniel.linkie.getObfClientDesc import me.shedaniel.linkie.getObfMergedDesc +import me.shedaniel.linkie.getObfServerDesc +import me.shedaniel.linkie.obfClientName import me.shedaniel.linkie.obfMergedName +import me.shedaniel.linkie.obfServerName import me.shedaniel.linkie.utils.MemberEntry import me.shedaniel.linkie.utils.ResultHolder import me.shedaniel.linkie.utils.toVersion @@ -129,8 +133,8 @@ fun main() { val allowFields = call.parameters["allowFields"]?.toBoolean() ?: true val translateNsStr = call.parameters["translate"]?.lowercase() require(limit in 1..1000) { "Limit must be between 1 and 1000" } - val namespace = Namespaces[namespaceStr] - val translateNamespace = translateNsStr?.let { Namespaces[it] } + val namespace = Namespaces.namespaces[namespaceStr] ?: throw IllegalArgumentException("No namespace found for $namespaceStr") + val translateNamespace = translateNsStr?.let { Namespaces.namespaces[it] ?: throw IllegalArgumentException("No namespace found for $it") } val allVersions = namespace.getAllSortedVersions().toMutableList() if (translateNamespace != null) { @@ -253,6 +257,8 @@ fun toJsonFromEntry(mappings: MappingsContainer, entry: Any?, score: Double): Js obf = entry.obfMergedName, intermediary = entry.intermediaryName, named = entry.mappedName, + obfClient = entry.obfClientName, + obfServer = entry.obfServerName, score = score, memberType = "c", ) @@ -268,6 +274,12 @@ fun toJsonFromEntry(mappings: MappingsContainer, entry: Any?, score: Double): Js descObf = entry.member.getObfMergedDesc(mappings), descIntermediary = entry.member.intermediaryDesc, descNamed = entry.member.getMappedDesc(mappings), + ownerObfClient = entry.owner.obfClientName, + obfClient = entry.member.obfClientName, + descObfClient = entry.member.getObfClientDesc(mappings), + ownerObfServer = entry.owner.obfServerName, + obfServer = entry.member.obfServerName, + descObfServer = entry.member.getObfServerDesc(mappings), score = score, memberType = if (entry.member is Field) "f" else "m" ) @@ -349,6 +361,10 @@ data class SearchResultClassEntry( val intermediary: String, @SerialName("n") val named: String?, + @SerialName("h") + val obfClient: String?, + @SerialName("l") + val obfServer: String?, @SerialName("z") val score: Double, @SerialName("t") @@ -375,6 +391,18 @@ data class SearchResultMemberEntry( val descIntermediary: String, @SerialName("f") val descNamed: String?, + @SerialName("g") + val ownerObfClient: String?, + @SerialName("h") + val obfClient: String?, + @SerialName("j") + val descObfClient: String?, + @SerialName("k") + val ownerObfServer: String?, + @SerialName("l") + val obfServer: String?, + @SerialName("m") + val descObfServer: String?, @SerialName("z") val score: Double, @SerialName("t") diff --git a/frontend/src/app/backend.ts b/frontend/src/app/backend.ts index ca92cab..2a78f44 100644 --- a/frontend/src/app/backend.ts +++ b/frontend/src/app/backend.ts @@ -33,3 +33,15 @@ export function reqSearch(namespace: string, version: string, query: st export function reqOss(): Promise> { return HTTP.get(`/api/oss`) } + +export let namespaceLocalizations: { [namespace: string]: string } = { + "yarn": "Yarn", + "mojang": "Official Mojang (Fabric Intermediary)", + "mojang_srg": "Official Mojang (Forge SRG)", + "mojang_hashed": "Official Mojang (Quilt Hashed)", + "mcp": "MCP", + "quilt-mappings": "Quilt Mappings", + "legacy-yarn": "Legacy Yarn (Unofficial)", + "yarrn": "Yarrn", + "plasma": "Plasma", +} diff --git a/frontend/src/components/mappings/MappingsEntryBlock.vue b/frontend/src/components/mappings/MappingsEntryBlock.vue index b02a681..263d6af 100644 --- a/frontend/src/components/mappings/MappingsEntryBlock.vue +++ b/frontend/src/components/mappings/MappingsEntryBlock.vue @@ -2,7 +2,7 @@ {{ getDisplayName(entry) }} - > {{ getDisplayName(entry.translatedTo) }} + > {{ getDisplayName(entry.translatedTo) }}
-
+
@@ -79,6 +79,22 @@ function getObf(entry: MappingEntry) { } } +function getObfClient(entry: MappingEntry) { + if (entry.type == "class") { + return formatName(entry.obfClient) + } else { + return `${formatName(entry.ownerObfClient)}.${onlyClass(entry.obfClient)}` + } +} + +function getObfServer(entry: MappingEntry) { + if (entry.type == "class") { + return formatName(entry.obfServer) + } else { + return `${formatName(entry.ownerObfServer)}.${onlyClass(entry.obfServer)}` + } +} + function getIntermediaryName(entry: MappingEntry) { if (entry.type == "class") { return formatName(entry.intermediary) @@ -103,11 +119,18 @@ function getDisplayName(entry: MappingEntry, simplify: boolean = true) { } } -function getBreadcrumbs(entry: MappingEntry) { +function getBreadcrumbs(hasTranslation: boolean, entry: MappingEntry) { let breadcrumbs = [] as string[] - if (!entry.translatedTo) { + if (!hasTranslation) { if (entry.obf) { breadcrumbs.push(getObf(entry)!) + } else { + let list = [] as string[] + if (entry.obfClient) list.push(getObfClient(entry)! + " (client)") + if (entry.obfServer) list.push(getObfServer(entry)! + " (server)") + if (list.length > 0) { + breadcrumbs.push(list.join(" / ")) + } } let intermediary = getIntermediaryName(entry)! let named = getDisplayName(entry, false)! @@ -199,7 +222,10 @@ export default defineComponent({ }, computed: { breadcrumbs() { - return getBreadcrumbs(this.entry) + return getBreadcrumbs(this.hasTranslation, this.entry) + }, + hasTranslation() { + return this.entry.translatedTo && this.translatedToNamespace }, }, methods: { @@ -228,12 +254,10 @@ export default defineComponent({ }, props: { namespace: { - type: Object as PropType, - required: true, + type: Object as PropType, }, translatedToNamespace: { - type: Object as PropType, - required: true, + type: Object as PropType, }, entry: { type: Object as PropType, diff --git a/frontend/src/components/mappings/MappingsFilterBlock.vue b/frontend/src/components/mappings/MappingsFilterBlock.vue index ae0028e..1c47b64 100644 --- a/frontend/src/components/mappings/MappingsFilterBlock.vue +++ b/frontend/src/components/mappings/MappingsFilterBlock.vue @@ -2,13 +2,13 @@
Namespace - +
Version
@@ -18,7 +18,7 @@ @input="allowSnapshots = ($event.target as any)?.checked ?? allowSnapshots"/>
- + + @change="translateAs = ($event.target as any)?.value === 'Do not translate' ? undefined : delocalizeNamespace(($event.target as any)?.value).id" + :value="localizeNamespace(translateAs) ?? 'Do not translate'">
@@ -65,17 +66,41 @@ import {defineComponent, PropType} from "vue" import {mapWritableState} from "pinia" import {useMappingsStore} from "../../app/mappings-store" import {MappingsData, Namespace} from "../../routes/Mappings.vue" -import {useDependencySearchStore} from "../../app/dependency-store" import SubHeader from "../dependencies/SubHeader.vue" +import {namespaceLocalizations} from "../../app/backend" export default defineComponent({ name: "MappingsFilterBlock", components: {SubHeader}, + methods: { + localizeNamespace(namespace?: Namespace | string): string | undefined { + if (typeof namespace === "string") { + return namespaceLocalizations[namespace.toLowerCase()] || namespace.toLowerCase() + } else if (namespace) { + let id = namespace.id + return namespaceLocalizations[id.toLowerCase()] || id.toLowerCase() + } else { + return undefined + } + }, + delocalizeNamespace(string: string) : Namespace { + let id = Object.entries(namespaceLocalizations) + .find(([id, name]) => name === string) + ?.[0] ?? this.namespace?.id + return this.namespaces.find(ns => ns.id === id) ?? (this.namespace ?? this.namespaces[0]) + } + }, computed: { ...mapWritableState(useMappingsStore, ["namespace", "version", "allowSnapshots", "allowClasses", "allowFields", "allowMethods", "translateAs"]), namespaces(): Namespace[] { return this.data.namespaces }, + namespacesSorted(): Namespace[] { + return this.namespaces.sort((a, b) => (this.localizeNamespace(a) ?? "").localeCompare(this.localizeNamespace(b) ?? "")) + }, + firstNamespace(): Namespace | undefined { + return this.namespaces.at(0) + }, applicableVersions(): string[] { let {namespace, allowSnapshots, translateAs} = useMappingsStore() if (!namespace) return [] @@ -83,7 +108,7 @@ export default defineComponent({ if (!namespaceObj) return [] let versions = namespaceObj.versions if (versions && !allowSnapshots) { - versions = versions.filter(entry => entry.stable) + versions = versions.filter(entry => entry.stable) } if (versions && translateAs) { let translateAsObj = this.data.namespaces.find(value => value.id === translateAs) diff --git a/frontend/src/routes/Mappings.vue b/frontend/src/routes/Mappings.vue index 1ba438f..7702a4e 100644 --- a/frontend/src/routes/Mappings.vue +++ b/frontend/src/routes/Mappings.vue @@ -55,6 +55,12 @@ export interface MappingEntry { ownerObf?: string, ownerIntermediary?: string, ownerNamed?: string, + ownerObfClient?: string, + obfClient?: string, + descObfClient?: string, + ownerObfServer?: string, + obfServer?: string, + descObfServer?: string, type: MappingType, translatedTo?: MappingEntry, } @@ -259,6 +265,12 @@ export default defineComponent({ ownerObf: obj.a, ownerIntermediary: obj.b, ownerNamed: obj.c, + ownerObfClient: obj.g, + obfClient: obj.h, + descObfClient: obj.j, + ownerObfServer: obj.k, + obfServer: obj.l, + descObfServer: obj.m, type, translatedTo, } as MappingEntry