ReplBridge

Game-loader side of the REPL. Builds the MaskingClassLoader, crosses into the masking world with a single reflective bootstrap of ...repl.impl.MaskingBridgeImpl — reached type-safely thereafter through the shared MaskingBridge interface — and caches the result so every compile / execute after the first is a warm call. The same bridge also fronts the remap-cache builder (buildRemapArtifacts), so ALL masking-only calls share this one hop.

Why reflection: MaskingBridgeImpl and its backends (ReplHost, RemapCacheBuilder) link the Kotlin scripting / remapper APIs, which live only on the masking loader's urls (see MaskingClassLoader for why they cannot sit on the game's module path). The game loader therefore cannot link them by name, and this one bootstrap hop is the whole cost of that isolation.

Only types the masking loader delegates to the parent may cross the boundary: java.*, Object, and the mod's own classes outside repl.impl — which is also why MaskingBridge itself must stay in ...repl; see MaskingClassLoader.

Constructors

Link copied to clipboard
private constructor()

Properties

Link copied to clipboard
private open var classpath: List<File>
Link copied to clipboard
private open var host: MaskingBridge
Link copied to clipboard
①: CommonClass.init trigger — the baseline the other three timestamps are relative to.
Link copied to clipboard
private val LOCK: Any
Link copied to clipboard
private open var masking: MaskingClassLoader
Link copied to clipboard
private open var maskingReady: Boolean
Link copied to clipboard
Gates buildClasspath on a host that has plugins — not on their jars, which are all loaded before any is enabled, but on the urls a plugin attaches to its own loader inside onEnable, which PluginJarCollector reads live.
Link copied to clipboard
③: compiler working set preloaded (~= initStartNanos on a training launch).
Link copied to clipboard
②: remap symbols ready (~= initStartNanos on a mojmap runtime, where no remap is needed).
Link copied to clipboard
No recorded working-set list at start ⇒ this launch trains one.
Link copied to clipboard
open var warmDone: Boolean
True once warmup finishes; McpServer gates execute_code on this (set even on failure).
Link copied to clipboard
④: compiler built + one dummy snippet compiled and run — the first eval is now warm.
Link copied to clipboard
Counted down by the remap thread and the preload thread; the gate thread awaits both before building.

Functions

Link copied to clipboard
private open fun addRuntimeDep(cp: Set<File>, gl: ClassLoader, className: String)
Add the jar backing className (via its CodeSource on the game loader) to the compile classpath, if it resolves to a real file not already present.
Link copied to clipboard
private open fun appendApiDepJars(cp: Set<File>, gl: ClassLoader, bundle: RemapBundle)
Probe each type listed in the bundle's deps.txt on the game loader and add its backing jar to cp, recovering the MC API-dep jars (e.g.
Link copied to clipboard
open fun buildClasspath()
Assemble the compile classpath (game cp + all mods + JiJ libs + mojmap remap symbols + MC API deps).
Link copied to clipboard
open fun buildForgeArtifacts(joinedTsrg: String, clientTxt: String, mcUri: String, outMappings: String, outSymbolsDir: String)
Forge Mixed-SRG analog of buildRemapArtifacts: assemble srg_to_official.tsrg from MCPConfig joinedTsrg (obf → srg) + Mojang clientTxt, and reverse-remap the Mixed-SRG runtime jar into a mojmap symbol jar.
Link copied to clipboard
private open fun buildMaskingUrls(): Array<URL>
Masking-loader urls: the Kotlin scripting stack (never on the module path) + the source of the repl.impl classes, so ReplHost resolves child-first.
Link copied to clipboard
open fun buildRemapArtifacts(clientTxt: String, secondSource: String, mcUri: String, outMappings: String, outSymbolsDir: String)
Cross into the masking loader (mapping-io + tiny-remapper live only there) to assemble the remap mappings and reverse-remap the runtime jar into a mojmap symbol jar.
Link copied to clipboard
private open fun bukkitPresent(): Boolean
Whether the runtime carries a Bukkit layer at all.
Link copied to clipboard
open fun compile(code: String, killIdField: String, evalId: Int): Any
Compile code to an opaque handle, OFF any tick — pure computation, no game state.
Link copied to clipboard
private open fun ensureInit()
Lazy fallback: a direct compile/eval arriving before the eager background warmup finished ensures both halves itself.
Link copied to clipboard
open fun ensureMasking()
Build the masking loader + instantiate the MaskingBridge.
Link copied to clipboard
open fun execute(handle: Any, code: String, out: Capture): Any
Run a handle from compile and return an exec.Outcome (result text + isError) or, if the snippet's value was a stdlib iterator { ... yield() ... }, an exec.IterEval for the lane to drive one step per tick.
Link copied to clipboard
private open fun extractEmbedded(prefix: String): List<URL>
Production fallback: extract the nested jars under prefix (e.g.
Link copied to clipboard
private open fun maskingLoader(): MaskingClassLoader
The masking loader, built once and shared by every masking-only entry point.
Link copied to clipboard
private open fun mcpCacheDir(): File
The mod's own writable cache dir, asked of the loader — see IPlatformHelper.cacheDir.
Link copied to clipboard
private open fun modJarLocation(): URL
Our own mod jar, via this class's CodeSource — the anchor for production self-extraction.
Link copied to clipboard
open fun remapReady()
Called by the remap init (CommonClass) the moment mojmap symbols are ready — or immediately on a mojmap runtime where no remap is needed.
Link copied to clipboard
private open fun selfJar(): File
Our own mod jar, or null when we run from a classes dir (dev): toJarFile resolves that location to the DIRECTORY, hence the isFile check.
Link copied to clipboard
Spawn the warmup threads described above: preload, and the gate that awaits both halves.