### Initialize Linkie System with Configuration Source: https://context7.com/linkie/linkie-core/llms.txt Call `Namespaces.init` once at startup to register namespaces, configure the cache, and start the background refresh cycle. Use `namespace.reloading` to wait for initial data. ```kotlin import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import me.shedaniel.linkie.LinkieConfig import me.shedaniel.linkie.Namespaces import me.shedaniel.linkie.namespaces.YarnNamespace import me.shedaniel.linkie.namespaces.MojangNamespace import me.shedaniel.linkie.namespaces.MCPNamespace fun main() = runBlocking { // Initialize with multiple namespaces, a custom cache dir, and a 30-minute reload cycle Namespaces.init( LinkieConfig.DEFAULT.copy( namespaces = listOf(YarnNamespace, MojangNamespace, MCPNamespace), maximumLoadedVersions = 4, ) ) // Wait for initial data to load delay(2000) while (YarnNamespace.reloading || MojangNamespace.reloading) delay(100) println("Yarn versions: ${YarnNamespace.getAllSortedVersions().take(5)}") // Output: Yarn versions: [1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20] } ``` -------------------------------- ### Namespaces.init — Initialize the Linkie system with a configuration Source: https://context7.com/linkie/linkie-core/llms.txt Call `Namespaces.init` once at startup to register namespaces, configure the cache directory, and start the background refresh cycle. Use `namespace.reloading` to wait for initial data load. ```APIDOC ## Namespaces.init — Initialize the Linkie system with a configuration ### Description Call `Namespaces.init` once at startup. It registers all requested `Namespace` objects, configures the cache directory and reload cycle, and starts the background coroutine that periodically refreshes mapping data. The function is non-blocking; use `namespace.reloading` to wait for the initial data load. ### Method `Namespaces.init(config: LinkieConfig)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```kotlin import kotlinx.coroutines.delay import kotlinx.coroutines.runBlocking import me.shedaniel.linkie.LinkieConfig import me.shedaniel.linkie.Namespaces import me.shedaniel.linkie.namespaces.YarnNamespace import me.shedaniel.linkie.namespaces.MojangNamespace import me.shedaniel.linkie.namespaces.MCPNamespace fun main() = runBlocking { // Initialize with multiple namespaces, a custom cache dir, and a 30-minute reload cycle Namespaces.init( LinkieConfig.DEFAULT.copy( namespaces = listOf(YarnNamespace, MojangNamespace, MCPNamespace), maximumLoadedVersions = 4, ) ) // Wait for initial data to load delay(2000) while (YarnNamespace.reloading || MojangNamespace.reloading) delay(100) println("Yarn versions: ${YarnNamespace.getAllSortedVersions().take(5)}") // Output: Yarn versions: [1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20] } ``` ### Response #### Success Response (200) None (initializes the system) #### Response Example None ``` -------------------------------- ### Configure Linkie Runtime Behavior Source: https://context7.com/linkie/linkie-core/llms.txt `LinkieConfig` controls caching, namespaces, and reload behavior. Start with `LinkieConfig.DEFAULT` and use `.copy(...)` to override fields. The `cacheDirectory` stores downloaded JARs. ```kotlin import com.soywiz.klock.minutes import com.soywiz.korio.file.std.localCurrentDirVfs import me.shedaniel.linkie.LinkieConfig import me.shedaniel.linkie.Namespaces import me.shedaniel.linkie.jar.GameJarDownloadingProvider import me.shedaniel.linkie.namespaces.YarnNamespace import me.shedaniel.linkie.utils.div val config = LinkieConfig( cacheDirectory = localCurrentDirVfs / "my-cache", // where JARs are stored maximumLoadedVersions = 3, // max MappingsContainers held in RAM namespaces = listOf(YarnNamespace), reloadCycleDuration = 60.minutes, // refresh data every 60 min gameJarProvider = ::GameJarDownloadingProvider, // downloads Minecraft JARs for source generation remapSourceDaemonDuration = null, ) Namespaces.init(config) ``` -------------------------------- ### Retrieve MappingsProvider for a Version Source: https://context7.com/linkie/linkie-core/llms.txt Use getProvider(version) to get a MappingsProvider for a specific game version. getDefaultProvider() retrieves the provider for the default version. Call .get() on the provider to load the MappingsContainer. ```kotlin import kotlinx.coroutines.runBlocking import kotlinx.coroutines.delay import me.shedaniel.linkie.LinkieConfig import me.shedaniel.linkie.Namespaces import me.shedaniel.linkie.namespaces.YarnNamespace import me.shedaniel.linkie.namespaces.MCPNamespace runBlocking { Namespaces.init(LinkieConfig.DEFAULT.copy(namespaces = listOf(YarnNamespace, MCPNamespace))) delay(2000) while (YarnNamespace.reloading) delay(100) // Latest Yarn mappings val latestYarn = YarnNamespace.getDefaultProvider().get() println("Yarn ${latestYarn.version}: ${latestYarn.allClasses.size} classes") // Specific Yarn version val yarn1165 = YarnNamespace.getProvider("1.16.5").get() println("Yarn 1.16.5: ${yarn1165.allClasses.size} classes") // MCP for 1.14.4 while (MCPNamespace.reloading) delay(100) val mcp1144 = MCPNamespace.getProvider("1.14.4").get() println("MCP 1.14.4: ${mcp1144.allClasses.size} classes") // Output example: // Yarn 1.20.4: 5012 classes // Yarn 1.16.5: 4321 classes // MCP 1.14.4: 3987 classes } ``` -------------------------------- ### LinkieConfig — Configure caching, namespaces, and reload behavior Source: https://context7.com/linkie/linkie-core/llms.txt `LinkieConfig` is a data class that controls all runtime behavior. Start from `LinkieConfig.DEFAULT` and use `.copy(...)` to override specific fields. ```APIDOC ## LinkieConfig — Configure caching, namespaces, and reload behavior ### Description `LinkieConfig` is a data class that controls all runtime behavior. Start from `LinkieConfig.DEFAULT` and use `.copy(...)` to override specific fields. The `cacheDirectory` stores downloaded mapping JARs and remapped game Jars. ### Fields - **cacheDirectory** (VfsFile) - The directory where mapping JARs and remapped game JARs are stored. - **maximumLoadedVersions** (Int) - The maximum number of `MappingsContainer` instances to hold in RAM. - **namespaces** (List) - A list of `Namespace` objects to register and load. - **reloadCycleDuration** (Duration) - The interval at which mapping data is refreshed. - **gameJarProvider** (Function) - A provider function for downloading Minecraft JARs used for source generation. - **remapSourceDaemonDuration** (Duration?) - Optional duration for the remapping source daemon. ### Usage Example ```kotlin import com.soywiz.klock.minutes import com.soywiz.korio.file.std.localCurrentDirVfs import me.shedaniel.linkie.LinkieConfig import me.shedaniel.linkie.Namespaces import me.shedaniel.linkie.jar.GameJarDownloadingProvider import me.shedaniel.linkie.namespaces.YarnNamespace import me.shedaniel.linkie.utils.div val config = LinkieConfig( cacheDirectory = localCurrentDirVfs / "my-cache", // where JARs are stored maximumLoadedVersions = 3, // max MappingsContainers held in RAM namespaces = listOf(YarnNamespace), reloadCycleDuration = 60.minutes, // refresh data every 60 min gameJarProvider = ::GameJarDownloadingProvider, // downloads Minecraft JARs for source generation remapSourceDaemonDuration = null, ) Namespaces.init(config) ``` ``` -------------------------------- ### Parse and Compare Minecraft Version Strings Source: https://context7.com/linkie/linkie-core/llms.txt Use `tryToVersion()` for safe parsing and `toVersion()` for direct conversion. Snapshots sort before releases, and pre-release versions are ordered correctly relative to release candidates and snapshots. ```kotlin import me.shedaniel.linkie.utils.Version import me.shedaniel.linkie.utils.tryToVersion import me.shedaniel.linkie.utils.toVersion // Parsing println("1.16.5".tryToVersion()) // Version(major=1, minor=16, patch=5) println("1.16-pre3".tryToVersion()) // Version(major=1, minor=16, snapshot="pre3") println("1.16 Pre-Release 3".tryToVersion()) // same as above println("20w17a".tryToVersion()) // Version(major=1, minor=16, snapshot="alpha.20.w.17a") println("1.16-rc1".tryToVersion()) // Version(major=1, minor=16, snapshot="rc1") println("invalid".tryToVersion()) // null // Comparison — snapshots sort before release, pre < rc < release val v1165 = "1.16.5".toVersion() val v116pre3 = "1.16-pre3".toVersion() val v116rc1 = "1.16-rc1".toVersion() val v116snap = "20w17a".toVersion() println(v1165 > v116rc1) // true (release > rc) println(v116rc1 > v116pre3) // true (rc > pre) println(v116pre3 > v116snap) // true (pre > weekly snapshot) println(v1165 >= "1.16.5".toVersion()) // true (equal) ``` -------------------------------- ### Namespace.getProvider / getDefaultProvider Source: https://context7.com/linkie/linkie-core/llms.txt Retrieve a MappingsProvider for a specific game version or the default version. Use .get() on the provider to load the MappingsContainer. ```APIDOC ## Namespace.getProvider / getDefaultProvider — Retrieve a MappingsProvider for a version `getProvider(version)` returns a `MappingsProvider` for the given game version string. `getDefaultProvider()` uses the namespace's `defaultVersion` (usually the latest stable release). Call `.get()` on the provider to actually load (or retrieve from cache) the `MappingsContainer`. ```kotlin import kotlinx.coroutines.runBlocking import kotlinx.coroutines.delay import me.shedaniel.linkie.LinkieConfig import me.shedaniel.linkie.Namespaces import me.shedaniel.linkie.namespaces.YarnNamespace import me.shedaniel.linkie.namespaces.MCPNamespace runBlocking { Namespaces.init(LinkieConfig.DEFAULT.copy(namespaces = listOf(YarnNamespace, MCPNamespace))) delay(2000) while (YarnNamespace.reloading) delay(100) // Latest Yarn mappings val latestYarn = YarnNamespace.getDefaultProvider().get() println("Yarn ${latestYarn.version}: ${latestYarn.allClasses.size} classes") // Specific Yarn version val yarn1165 = YarnNamespace.getProvider("1.16.5").get() println("Yarn 1.16.5: ${yarn1165.allClasses.size} classes") // MCP for 1.14.4 while (MCPNamespace.reloading) delay(100) val mcp1144 = MCPNamespace.getProvider("1.14.4").get() println("MCP 1.14.4: ${mcp1144.allClasses.size} classes") // Output example: // Yarn 1.20.4: 5012 classes // Yarn 1.16.5: 4321 classes // MCP 1.14.4: 3987 classes } ``` ``` -------------------------------- ### buildMappings / MappingsBuilder Source: https://context7.com/linkie/linkie-core/llms.txt Programmatically construct a MappingsContainer using a suspend DSL builder. Define classes, methods, and fields with their various names. ```APIDOC ## buildMappings / MappingsBuilder — Programmatically construct a MappingsContainer `buildMappings` is a suspend DSL builder for constructing a `MappingsContainer` from scratch. Use `ClassBuilder`, `FieldBuilder`, and `MethodBuilder` to add entries with their obfuscated, intermediary, and mapped names. ```kotlin import me.shedaniel.linkie.buildMappings import kotlinx.coroutines.runBlocking val container = runBlocking { buildMappings( version = "1.16.5", name = "Custom", fillFieldDesc = true, fillMethodDesc = true, ) { clazz("net/minecraft/class_310", obfName = "bck", mappedName = "net/minecraft/client/MinecraftClient") { method("method_1507", "(Lnet/minecraft/class_437;)V") { obfMethod("a") mapMethod("openScreen") } field("field_1735", "Lnet/minecraft/class_437;") { obfField("f") mapField("currentScreen") } } clazz("net/minecraft/class_437", obfName = "czz", mappedName = "net/minecraft/client/gui/screen/Screen") } } println("Classes: ${container.allClasses.size}") // Classes: 2 ``` ``` -------------------------------- ### Programmatically Construct a MappingsContainer Source: https://context7.com/linkie/linkie-core/llms.txt Use the buildMappings suspend DSL to construct a MappingsContainer from scratch. Define classes, methods, and fields with their various names (obfuscated, intermediary, mapped). ```kotlin import me.shedaniel.linkie.buildMappings import kotlinx.coroutines.runBlocking val container = runBlocking { buildMappings( version = "1.16.5", name = "Custom", fillFieldDesc = true, fillMethodDesc = true, ) { clazz("net/minecraft/class_310", obfName = "bck", mappedName = "net/minecraft/client/MinecraftClient") { method("method_1507", "(Lnet/minecraft/class_437;)V") { obfMethod("a") mapMethod("openScreen") } field("field_1735", "Lnet/minecraft/class_437;") { obfField("f") mapField("currentScreen") } } clazz("net/minecraft/class_437", obfName = "czz", mappedName = "net/minecraft/client/gui/screen/Screen") } } println("Classes: ${container.allClasses.size}") // Classes: 2 ``` -------------------------------- ### Search Mappings by Name using MappingsQuery Source: https://context7.com/linkie/linkie-core/llms.txt Use MappingsQuery to perform fuzzy and exact searches on class, method, and field names. Initialize Namespaces and obtain a MappingsProvider before creating a QueryContext with the desired search key, accuracy, and limit. ```kotlin import kotlinx.coroutines.runBlocking import kotlinx.coroutines.delay import me.shedaniel.linkie.LinkieConfig import me.shedaniel.linkie.Namespaces import me.shedaniel.linkie.namespaces.YarnNamespace import me.shedaniel.linkie.optimumName import me.shedaniel.linkie.utils.MappingsQuery import me.shedaniel.linkie.utils.MatchAccuracy import me.shedaniel.linkie.utils.QueryContext import me.shedaniel.linkie.utils.MemberEntry import me.shedaniel.linkie.Class import me.shedaniel.linkie.Method import me.shedaniel.linkie.Field runBlocking { Namespaces.init(LinkieConfig.DEFAULT.copy(namespaces = listOf(YarnNamespace))) delay(2000) while (YarnNamespace.reloading) delay(100) val provider = YarnNamespace.getProvider("1.16.5") val context = QueryContext(provider, "MinecraftClient", accuracy = MatchAccuracy.Exact, limit = 5) // Search classes val classResult = MappingsQuery.queryClasses(context) println("Mappings version: ${classResult.mappings.version}") classResult.value.forEach { holder -> println(" [${holder.score}] ${holder.value.optimumName}") } // [1.0] net/minecraft/client/MinecraftClient // Search methods with class filter: "MinecraftClient.openScreen" val methodCtx = QueryContext(provider, "MinecraftClient/openScreen", limit = 3) val methodResult = MappingsQuery.queryMethods(methodCtx) methodResult.value.forEach { val entry = it.value println(" ${entry.owner.optimumName}.${entry.member.optimumName}") } // net/minecraft/client/MinecraftClient.openScreen // Fuzzy search val fuzzyCtx = QueryContext(provider, "MinecraffClient", accuracy = MatchAccuracy.Fuzzy, limit = 3) val fuzzyResult = MappingsQuery.queryClasses(fuzzyCtx) fuzzyResult.value.forEach { println(" fuzzy: ${it.value.optimumName} (${it.score})") } // Wildcard: get all fields val wildcardCtx = QueryContext(provider, "MinecraftClient/*", limit = 10) val fieldResult = MappingsQuery.queryFields(wildcardCtx) fieldResult.value.forEach { println(" ${it.value.member.intermediaryName} -> ${it.value.member.mappedName}") } } ``` -------------------------------- ### MappingBuffers Source: https://context7.com/linkie/linkie-core/llms.txt Provides binary serialization for MappingsContainer using ByteBuffer and SwimmingPoolByteBuffer for compact storage and efficient transfer. ```APIDOC ## MappingBuffers — Binary serialization of MappingsContainer `ByteBuffer` and `SwimmingPoolByteBuffer` provide compact binary serialization for `MappingsContainer`. Use `writeMappingsContainer` / `readMappingsContainer` to round-trip mappings without network round-trips. `SwimmingPoolByteBuffer` uses a shared string pool for smaller output. ### Serialize MappingsContainer ```kotlin val container: MappingsContainer = /* ... loaded container ... */ val buffer = writer() // standard ByteBuffer buffer.writeMappingsContainer(container) val bytes: ByteArray = buffer.writeTo() ``` ### Deserialize MappingsContainer ```kotlin val readBuffer = reader(bytes) val restored: MappingsContainer = readBuffer.readMappingsContainer() println("Restored: ${restored.version} with ${restored.allClasses.size} classes") ``` ### Serialize with String Swimming Pool ```kotlin val poolBuffer = swimmingPoolWriter() poolBuffer.writeMappingsContainer(container) val poolBytes = poolBuffer.writeTo() println("Standard size: ${bytes.size} bytes, Pool size: ${poolBytes.size} bytes") ``` ### Deserialize with String Swimming Pool ```kotlin val poolRead = poolBytes.swimmingPoolReader() val poolRestored = poolRead.readMappingsContainer() println("Pool-restored: ${poolRestored.version} with ${poolRestored.allClasses.size} classes") ``` ``` -------------------------------- ### Serialize and Deserialize MappingsContainer with ByteBuffer Source: https://context7.com/linkie/linkie-core/llms.txt Provides compact binary serialization for MappingsContainer using ByteBuffer and SwimmingPoolByteBuffer. Use writeMappingsContainer/readMappingsContainer for round-tripping. SwimmingPoolByteBuffer uses a shared string pool for smaller output. ```kotlin import me.shedaniel.linkie.* // Serialize val container: MappingsContainer = /* ... loaded container ... */ val buffer = writer() // standard ByteBuffer buffer.writeMappingsContainer(container) val bytes: ByteArray = buffer.writeTo() // Deserialize val readBuffer = reader(bytes) val restored: MappingsContainer = readBuffer.readMappingsContainer() println("Restored: ${restored.version} with ${restored.allClasses.size} classes") // Compact form with string swimming pool (smaller payload for many repeated strings) val poolBuffer = swimmingPoolWriter() poolBuffer.writeMappingsContainer(container) val poolBytes = poolBuffer.writeTo() println("Standard size: ${bytes.size} bytes, Pool size: ${poolBytes.size} bytes") val poolRead = poolBytes.swimmingPoolReader() val poolRestored = poolRead.readMappingsContainer() println("Pool-restored: ${poolRestored.version} with ${poolRestored.allClasses.size} classes") ``` -------------------------------- ### Retrieve Decompiled Source Code using Namespace.getSource Source: https://context7.com/linkie/linkie-core/llms.txt Fetch decompiled source code for a given class name from namespaces that support it (e.g., Yarn, Mojang). Ensure the namespace is initialized and reload is complete before calling getSources or getSource. ```kotlin import kotlinx.coroutines.runBlocking import kotlinx.coroutines.delay import me.shedaniel.linkie.LinkieConfig import me.shedaniel.linkie.Namespaces import me.shedaniel.linkie.namespaces.YarnNamespace import me.shedaniel.linkie.optimumName runBlocking { Namespaces.init(LinkieConfig.DEFAULT.copy(namespaces = listOf(YarnNamespace))) delay(2000) while (YarnNamespace.reloading) delay(100) val provider = YarnNamespace.getDefaultProvider() val container = provider.get() // Pick a random class and retrieve its decompiled source val className = container.allClasses .filter { it.mappedName != null } .random() .optimumName println("Fetching source for: $className") val sourceFile = provider.getSources(className) // returns a VfsFile println("Source written to: ${sourceFile.absolutePath}") // Source written to: .linkie-cache/minecraft-jars/sources/yarn-1.20.4/net/minecraft/client/MinecraftClient.java } ``` -------------------------------- ### Export MappingsContainer to Tiny v2 Stream Source: https://context7.com/linkie/linkie-core/llms.txt Converts a MappingsContainer into a Tiny v2 format InputStream. Provide namespace labels to include them in the output. Optional parameters can be omitted to exclude namespaces. ```kotlin import me.shedaniel.linkie.TinyExporter import me.shedaniel.linkie.buildMappings import kotlinx.coroutines.runBlocking import java.io.FileOutputStream runBlocking { val container = buildMappings("1.16.5", "Yarn") { clazz("net/minecraft/class_310", obfName = "bck", mappedName = "net/minecraft/client/MinecraftClient") { method("method_1507", "(Lnet/minecraft/class_437;)V") { obfMethod("a") mapMethod("openScreen") } } } // Export with intermediary + named + merged obf namespaces val stream = TinyExporter.export( container = container, intermediary = "intermediary", named = "named", obfMerged = "official", ) // Save to file FileOutputStream("output.tiny").use { fos -> stream.copyTo(fos) } println("Tiny v2 file written.") // Export only intermediary + named (no obf) val minimalStream = TinyExporter.export(container, intermediary = "intermediary", named = "named") } ``` -------------------------------- ### Access and Traverse Mapping Entries Source: https://context7.com/linkie/linkie-core/llms.txt Use MappingsContainer to access classes, methods, and fields. Look up entries by intermediary, obfuscated, or mapped names using helper functions. Each entry provides access to its obfuscated, intermediary, and mapped names. ```kotlin import me.shedaniel.linkie.MappingsContainer import me.shedaniel.linkie.getClassByObfName import me.shedaniel.linkie.getClassByOptimumName import me.shedaniel.linkie.optimumName // container: MappingsContainer already loaded fun inspectClass(container: MappingsContainer) { // Lookup by intermediary name val clazz = container.getClass("net/minecraft/class_310") // MinecraftClient println("Intermediary: ${clazz?.intermediaryName}") println("Mapped: ${clazz?.mappedName}") // "net/minecraft/client/MinecraftClient" println("Obf merged: ${clazz?.obfMergedName}") // e.g. "bck" // Lookup by obfuscated name val byObf = container.getClassByObfName("bck") println("By obf: ${byObf?.optimumName}") // Lookup by mapped/intermediary optimum name val byOptimum = container.getClassByOptimumName("net/minecraft/client/MinecraftClient") byOptimum?.methods?.forEach { method -> println(" Method: ${method.intermediaryName} -> ${method.mappedName}") } // Pretty-print the entire container to logs container.prettyPrint() } ``` -------------------------------- ### MappingsContainer Source: https://context7.com/linkie/linkie-core/llms.txt Access and traverse mapping entries for a game version. Use helper functions to find classes by different name types and access their methods and fields. ```APIDOC ## MappingsContainer — Access and traverse mapping entries `MappingsContainer` holds all classes, methods, and fields for a game version. Use `getClass`, `getOrCreateClass`, and the extension functions `getClassByObfName` / `getClassByOptimumName` to find entries. Every `Class` has `.methods` and `.fields` lists; each entry exposes `.intermediaryName`, `.mappedName`, and `.obfName`. ```kotlin import me.shedaniel.linkie.MappingsContainer import me.shedaniel.linkie.getClassByObfName import me.shedaniel.linkie.getClassByOptimumName import me.shedaniel.linkie.optimumName // container: MappingsContainer already loaded fun inspectClass(container: MappingsContainer) { // Lookup by intermediary name val clazz = container.getClass("net/minecraft/class_310") // MinecraftClient println("Intermediary: ${clazz?.intermediaryName}") println("Mapped: ${clazz?.mappedName}") // "net/minecraft/client/MinecraftClient" println("Obf merged: ${clazz?.obfMergedName}") // e.g. "bck" // Lookup by obfuscated name val byObf = container.getClassByObfName("bck") println("By obf: ${byObf?.optimumName}") // Lookup by mapped/intermediary optimum name val byOptimum = container.getClassByOptimumName("net/minecraft/client/MinecraftClient") byOptimum?.methods?.forEach { method -> println(" Method: ${method.intermediaryName} -> ${method.mappedName}") } // Pretty-print the entire container to logs container.prettyPrint() } ``` ``` -------------------------------- ### TinyExporter.export Source: https://context7.com/linkie/linkie-core/llms.txt Converts a MappingsContainer into a Tiny v2 format InputStream. You can specify which namespace labels to include in the output. ```APIDOC ## TinyExporter.export — Export a MappingsContainer to a Tiny v2 stream `TinyExporter.export` converts a `MappingsContainer` into a Tiny v2 format `InputStream` that can be fed directly into other tooling or saved to disk. Provide the namespace labels you want included; omit optional parameters to exclude them from the output. ### Method ```kotlin TinyExporter.export( container: MappingsContainer, intermediary: String? = null, named: String? = null, obfMerged: String? = null ): InputStream ``` ### Parameters - **container** (MappingsContainer) - The MappingsContainer to export. - **intermediary** (String?, optional) - The namespace label for intermediary mappings. - **named** (String?, optional) - The namespace label for named mappings. - **obfMerged** (String?, optional) - The namespace label for merged obfuscated mappings. ### Request Example ```kotlin runBlocking { val container = buildMappings("1.16.5", "Yarn") { /* ... */ } // Export with intermediary + named + merged obf namespaces val stream = TinyExporter.export( container = container, intermediary = "intermediary", named = "named", obfMerged = "official", ) // Save to file FileOutputStream("output.tiny").use { fos -> stream.copyTo(fos) } println("Tiny v2 file written.") // Export only intermediary + named (no obf) val minimalStream = TinyExporter.export(container, intermediary = "intermediary", named = "named") } ``` ``` -------------------------------- ### MappingsMember descriptor utilities Source: https://context7.com/linkie/linkie-core/llms.txt Extension functions on MappingsMember to resolve JVM descriptors across namespaces, allowing remapping and localization of field and method descriptors. ```APIDOC ## MappingsMember descriptor utilities — Remap and localize field/method descriptors Extension functions on `MappingsMember` resolve JVM descriptors across namespaces. `getMappedDesc`, `getObfMergedDesc`, `getObfClientDesc`, and `getObfServerDesc` all rewrite class references within a descriptor using the container's class mappings. `remapDescriptor` and `localiseFieldDesc` provide lower-level string operations. ### Get Mapped Descriptor ```kotlin val mappedDesc = method.getMappedDesc(container) println("Mapped desc: $mappedDesc") // Mapped desc: (Lnet/minecraft/client/gui/screen/Screen;)V ``` ### Get Obfuscated Merged Descriptor ```kotlin val obfDesc = method.getObfMergedDesc(container) println("Obf merged desc: $obfDesc") // Obf merged desc: (Lczz;)V ``` ### Remap Descriptor String ```kotlin val remapped = "(Lnet/minecraft/class_437;)V".remapDescriptor { internalName -> container.getClass(internalName)?.mappedName ?: internalName } println("Remapped: $remapped") // Remapped: (Lnet/minecraft/client/gui/screen/Screen;)V ``` ### Localize Field Descriptor ```kotlin println("[Lme/shedaniel/linkie/MappingsKt;".localiseFieldDesc()) // me.shedaniel.linkie.MappingsKt[] println("[I".localiseFieldDesc()) // int[] println("Z".localiseFieldDesc()) // boolean ``` ``` -------------------------------- ### Remap and Localize MappingsMember Descriptors Source: https://context7.com/linkie/linkie-core/llms.txt Extension functions on MappingsMember resolve JVM descriptors across namespaces. Use getMappedDesc, getObfMergedDesc, getObfClientDesc, and getObfServerDesc to rewrite class references. remapDescriptor and localiseFieldDesc offer lower-level string operations. ```kotlin import me.shedaniel.linkie.* import me.shedaniel.linkie.utils.localiseFieldDesc import me.shedaniel.linkie.utils.remapDescriptor val container: MappingsContainer = /* ... loaded container ... */ val clazz = container.getClass("net/minecraft/class_310")!! val method = clazz.methods.first { it.mappedName == "openScreen" } // Resolve descriptor with mapped class names val mappedDesc = method.getMappedDesc(container) println("Mapped desc: $mappedDesc") // Mapped desc: (Lnet/minecraft/client/gui/screen/Screen;)V // Resolve descriptor with obfuscated class names (merged) val obfDesc = method.getObfMergedDesc(container) println("Obf merged desc: $obfDesc") // Obf merged desc: (Lczz;)V // Remap a raw descriptor string with a custom mapping function val remapped = "(Lnet/minecraft/class_437;)V".remapDescriptor { internalName -> container.getClass(internalName)?.mappedName ?: internalName } println("Remapped: $remapped") // Remapped: (Lnet/minecraft/client/gui/screen/Screen;)V // Localise a field descriptor to a human-readable type name println("[Lme/shedaniel/linkie/MappingsKt;".localiseFieldDesc()) // me.shedaniel.linkie.MappingsKt[] println("[I".localiseFieldDesc()) // int[] println("Z".localiseFieldDesc()) // boolean ``` -------------------------------- ### Remap Intermediary Names Between Mappings Containers Source: https://context7.com/linkie/linkie-core/llms.txt Use `rewireIntermediaryFrom` to replace intermediary names in one container with those from another. This is useful for bridging different mapping namespaces, such as Mojang's raw obfuscated names to Fabric's intermediary names. ```kotlin import me.shedaniel.linkie.MappingsContainer import me.shedaniel.linkie.rewireIntermediaryFrom import kotlinx.coroutines.runBlocking import kotlinx.coroutines.delay import me.shedaniel.linkie.LinkieConfig import me.shedaniel.linkie.Namespaces import me.shedaniel.linkie.namespaces.YarnNamespace import me.shedaniel.linkie.namespaces.MojangRawNamespace runBlocking { Namespaces.init(LinkieConfig.DEFAULT.copy( namespaces = listOf(MojangRawNamespace, YarnNamespace) )) delay(2000) while (MojangRawNamespace.reloading || YarnNamespace.reloading) delay(100) val mojangRaw: MappingsContainer = MojangRawNamespace.getProvider("1.16.5").get().clone() val yarnIntermediary: MappingsContainer = YarnNamespace.getProvider("1.16.5").get() // Rewire mojangRaw's intermediary names to match Fabric's intermediary namespace // removeUnfound=false keeps entries that have no match in yarn mojangRaw.rewireIntermediaryFrom(yarnIntermediary, removeUnfound = false, mapClassNames = true) // Now mojangRaw uses class_XXX intermediary names instead of obf names val clazz = mojangRaw.getClass("net/minecraft/class_310") println("After rewire: ${clazz?.intermediaryName} -> ${clazz?.mappedName}") // After rewire: net/minecraft/class_310 -> net/minecraft/client/MinecraftClient } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.