85 lines
3.4 KiB
Python
85 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Dumps the Minecraft API surface PhotoSync depends on, for every bucket.
|
|
|
|
The adapters in :platform are written against exactly these signatures, and
|
|
docs/PORTING.md's breakpoint table is generated from this output. Run it after
|
|
adding a bucket to see, in one place, what that version changed:
|
|
|
|
./gradlew :platform:<version>:build # once, so Loom caches the jar
|
|
python3 tools/probe-api.py > /tmp/api.txt
|
|
"""
|
|
|
|
import glob
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
LOOM = os.path.expanduser("~/.gradle/caches/fabric-loom/minecraftMaven/net/minecraft")
|
|
|
|
# Class, then the members worth watching. A name missing from the output is
|
|
# itself the finding -- that is how the 26.x GuiGraphics removal showed up.
|
|
TARGETS = [
|
|
(["net.minecraft.client.gui.GuiGraphics",
|
|
"net.minecraft.client.gui.GuiGraphicsExtractor"],
|
|
r"\b(fill|fillGradient|enableScissor|disableScissor|drawString|text|blit)\("),
|
|
(["net.minecraft.client.gui.Font"], r"\b(width|lineHeight)\b"),
|
|
(["net.minecraft.client.gui.components.events.GuiEventListener"],
|
|
r"\b(mouseClicked|mouseReleased|mouseDragged|mouseScrolled|keyPressed|charTyped)\("),
|
|
(["net.minecraft.client.gui.screens.Screen"],
|
|
r"\b(render|extractRenderState|renderBackground|extractBackground|init|resize|removed"
|
|
r"|isPauseScreen|shouldCloseOnEsc|tick)\("),
|
|
(["net.minecraft.client.renderer.texture.DynamicTexture"], r"DynamicTexture\(|close\(|upload\(|getPixels\("),
|
|
(["net.minecraft.client.renderer.texture.TextureManager"], r"\b(register|release|getTexture)\("),
|
|
(["com.mojang.blaze3d.platform.NativeImage"], r"\b(read|writeToFile|setPixelRGBA|setPixel|close)\("),
|
|
(["net.minecraft.client.Screenshot"], r"\b(grab|takeScreenshot|_grab)\("),
|
|
# setScreen picks up setScreenAndShow too, which is the 26.x replacement.
|
|
(["net.minecraft.client.Minecraft"], r"\b(stop|close|getInstance|setScreen|getWindow)\w*\("),
|
|
(["net.minecraft.util.thread.BlockableEventLoop"], r"\b(execute|isSameThread)\("),
|
|
(["net.minecraft.Util", "net.minecraft.util.Util"], r"\b(getPlatform|ioPool)\("),
|
|
]
|
|
|
|
VERSION_KEY = re.compile(r"minecraft-merged-(\d+(?:\.\d+)*)-")
|
|
|
|
|
|
def jars():
|
|
found = {}
|
|
for jar in glob.glob(os.path.join(LOOM, "minecraft-merged", "*", "*.jar")):
|
|
if "sources" in jar:
|
|
continue
|
|
match = VERSION_KEY.search(os.path.basename(jar))
|
|
if match:
|
|
found.setdefault(match.group(1), jar)
|
|
return sorted(found.items(), key=lambda item: [int(p) for p in item[0].split(".")])
|
|
|
|
|
|
def dump(jar, class_name, pattern):
|
|
try:
|
|
out = subprocess.run(["javap", "-cp", jar, "-p", class_name],
|
|
capture_output=True, text=True, timeout=120)
|
|
except FileNotFoundError:
|
|
sys.exit("javap not on PATH; run this with a JDK available")
|
|
if out.returncode != 0:
|
|
return None
|
|
return [line.strip() for line in out.stdout.splitlines() if re.search(pattern, line)]
|
|
|
|
|
|
def main():
|
|
for version, jar in jars():
|
|
print("=" * 70)
|
|
print(version)
|
|
print("=" * 70)
|
|
for class_names, pattern in TARGETS:
|
|
for class_name in class_names:
|
|
members = dump(jar, class_name, pattern)
|
|
if members is None:
|
|
continue
|
|
print(f"\n-- {class_name}")
|
|
for member in members:
|
|
print(f" {member}")
|
|
print()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|