diff --git a/pom.xml b/pom.xml
index a9f495c..1d52d74 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
1.0-SNAPSHOT
jar
- pixlyzer
+ PixLyzer
UTF-8
diff --git a/src/main/kotlin/de/bixilon/pixlyzer/generator/generators/BlockGenerator.kt b/src/main/kotlin/de/bixilon/pixlyzer/generator/generators/BlockGenerator.kt
index ebbddd3..e9d2ef2 100644
--- a/src/main/kotlin/de/bixilon/pixlyzer/generator/generators/BlockGenerator.kt
+++ b/src/main/kotlin/de/bixilon/pixlyzer/generator/generators/BlockGenerator.kt
@@ -208,7 +208,9 @@ object BlockGenerator : Generator(
val propertyData = JsonObject()
for ((property, stateProperty) in state.values) {
- addJsonWithType(stateProperty.toString().toLowerCase(), propertyData, property.name.toLowerCase())
+ val propertyValue = (PROPERTY_NAME_METHOD.invoke(property) as String).toLowerCase()
+ val propertyName = stateProperty.toString().toLowerCase()
+ addJsonWithType(propertyName, propertyData, propertyValue)
}
if (propertyData.size() > 0) {
@@ -316,6 +318,10 @@ object BlockGenerator : Generator(
}
}
+ val PROPERTY_METHOD = getClass("net.minecraft.world.level.block.state.properties.Property")!!
+
+ val PROPERTY_NAME_METHOD = PROPERTY_METHOD.getDeclaredMethod("getName")
+
private fun getOrAddVoxelShape(voxelShape: VoxelShape): Int {
if (VOXEL_SHAPES.contains(voxelShape)) {
return VOXEL_SHAPES.indexOf(voxelShape)
diff --git a/src/main/kotlin/de/bixilon/pixlyzer/generator/generators/DimensionGenerator.kt b/src/main/kotlin/de/bixilon/pixlyzer/generator/generators/DimensionGenerator.kt
index 3c3ed2e..71cbd67 100644
--- a/src/main/kotlin/de/bixilon/pixlyzer/generator/generators/DimensionGenerator.kt
+++ b/src/main/kotlin/de/bixilon/pixlyzer/generator/generators/DimensionGenerator.kt
@@ -2,6 +2,7 @@ package de.bixilon.pixlyzer.generator.generators
import com.google.gson.JsonObject
import de.bixilon.pixlyzer.generator.Generator
+import de.bixilon.pixlyzer.util.ReflectionUtil.getClass
import de.bixilon.pixlyzer.util.ReflectionUtil.getField
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.level.dimension.DimensionType
@@ -12,7 +13,6 @@ object DimensionGenerator : Generator(
"dimensions"
) {
override fun generate() {
- // val registry = Registry.REGISTRY.get(Registry.DIMENSION_TYPE_REGISTRY.location()) as Registry
for ((resourceLocation, id, dimension) in getDimensions()) {
val dimensionData = JsonObject()
@@ -100,6 +100,11 @@ object DimensionGenerator : Generator(
private val AMBIENT_LIGHT_FIELD = getField(DIMENSION_TYPE_CLASS, "ambientLight")
+ private val RESOURCE_KEY_CLASS = getClass("net.minecraft.resources.ResourceKey")
+
+ private val RESOURCE_KEY_LOCATION_METHOD = RESOURCE_KEY_CLASS?.getDeclaredMethod("location")
+
+
private fun getDimensions(): MutableSet> {
val types: MutableSet> = mutableSetOf()
@@ -121,6 +126,14 @@ object DimensionGenerator : Generator(
types.add(Triple(resourceLocation, null, field.get(null) as DimensionType))
}
+ if (types.isEmpty()) {
+ val field = getField(DimensionType::class.java, "BUILTIN") ?: return types
+
+ for ((resourceLocation, dimension) in field.get(null) as Map) {
+ types.add(Triple(RESOURCE_KEY_LOCATION_METHOD!!.invoke(resourceLocation) as ResourceLocation, null, dimension))
+ }
+ }
+
return types
}
}
diff --git a/src/main/kotlin/de/bixilon/pixlyzer/generator/generators/EntityGenerator.kt b/src/main/kotlin/de/bixilon/pixlyzer/generator/generators/EntityGenerator.kt
index 105066c..4a00a05 100644
--- a/src/main/kotlin/de/bixilon/pixlyzer/generator/generators/EntityGenerator.kt
+++ b/src/main/kotlin/de/bixilon/pixlyzer/generator/generators/EntityGenerator.kt
@@ -14,6 +14,7 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.attributes.Attribute
+import net.minecraft.world.entity.ai.attributes.AttributeInstance
import java.lang.reflect.Modifier
object EntityGenerator : Generator(
@@ -49,12 +50,17 @@ object EntityGenerator : Generator(
if (entity is LivingEntity && entity2 is LivingEntity) {
for ((resourceLocation, attribute) in ATTRIBUTE_MAP) {
- entity.attributes.getInstance(attribute)?.value?.let {
- if (it != entity2.attributes.getInstance(attribute)?.value) {
- return@let
- }
- entityData.addProperty(resourceIdentifier.toString(), it)
+ val attributes = LIVING_ENTITY_GET_ATTRIBUTES_METHOD.invoke(entity) ?: continue
+ val instance = BASE_ATTRIBUTE_MAP_GET_INSTANCE_METHOD.invoke(attributes, attribute) as AttributeInstance? ?: continue
+ val value = ATTRIBUTE_INSTANCE_BASE_VALUE_METHOD.invoke(instance) as Double
+
+ val attributes2 = LIVING_ENTITY_GET_ATTRIBUTES_METHOD.invoke(entity2) ?: continue
+ val instance2 = BASE_ATTRIBUTE_MAP_GET_INSTANCE_METHOD.invoke(attributes2, attribute) as AttributeInstance? ?: continue
+ val value2 = ATTRIBUTE_INSTANCE_BASE_VALUE_METHOD.invoke(instance2) as Double
+ if (value != value2) {
+ continue
}
+ entityData.addProperty(resourceLocation, value)
}
// entity.getEatingSound(ItemStack.EMPTY)?.let {
@@ -167,9 +173,19 @@ object EntityGenerator : Generator(
private val ATTRIBUTE_MAP: Map = getAttributes()
+ private val BASE_ATTRIBUTE_MAP_CLASS = getClass("net.minecraft.world.entity.ai.attributes.AttributeMap", "net.minecraft.world.entity.ai.attributes.BaseAttributeMap")!!
+
+ private val BASE_ATTRIBUTE_MAP_GET_INSTANCE_METHOD = BASE_ATTRIBUTE_MAP_CLASS.getDeclaredMethod("getInstance", Attribute::class.java)
+
+ private val LIVING_ENTITY_GET_ATTRIBUTES_METHOD = LivingEntity::class.java.getDeclaredMethod("getAttributes")
+
+ private val ATTRIBUTE_INSTANCE_CLASS = getClass("net.minecraft.world.entity.ai.attributes.AttributeInstance")!!
+
+ private val ATTRIBUTE_INSTANCE_BASE_VALUE_METHOD = ATTRIBUTE_INSTANCE_CLASS.getMethod("getBaseValue")
+
private fun getAttributes(): Map {
- val attributeRegistryField = getField(Registry::class.java, "ATTRIBUTE")
+ val attributeRegistryField = getField(Registry::class.java, "ATTRIBUTE", "ATTRIBUTES")
val attributeNameField = try {
Attribute::class.java.getMethod("getName")
} catch (exception: NoSuchMethodException) {
diff --git a/wrapper/PixLyzer.py b/wrapper/PixLyzer.py
index 12e3809..8584152 100755
--- a/wrapper/PixLyzer.py
+++ b/wrapper/PixLyzer.py
@@ -2,7 +2,7 @@ import os
import subprocess
import urllib.request
import zipfile
-from enum import Enum
+from datetime import datetime
from pathlib import Path
import ujson
@@ -12,12 +12,11 @@ SKIP_VERSIONS = ["19w35a", "19w34a"]
HASH_FOLDER = os.path.abspath("data/hash/") + "/"
ASSETS_HASH_INDEX_FILE = os.path.abspath("data/index")
OUT_FOLDER = os.path.abspath("data/version/") + "/"
-LOGS_FOLDER = os.path.abspath("data/logs/") + "/"
DATA_FOLDER = os.path.abspath("data/data/") + "/"
MC_REMAPPER_EXECUTABLE = "/home/moritz/Games/Minecraft/MC-Remapper/build/install/MC-Remapper/bin/MC-Remapper"
JAVA_PATH = "/usr/lib/jvm/java-8-openjdk-amd64/bin/java"
-ADDITIONAL_CLASSPATH = "/home/moritz/kotlin-stdlib-1.4.30.jar"
+ADDITIONAL_CLASSPATH = "/home/moritz/kotlin-stdlib-1.4.30.jar:/home/moritz/Games/Minecraft/PixLyzer/wrapper/data/objenesis-tck-3.1.jar"
VERSION_MANIFEST_URL = "https://launchermeta.mojang.com/mc/game/version_manifest.json"
@@ -28,17 +27,6 @@ print("Starting PixLyzer generator")
print("Downloading version manifest")
VERSION_MANIFEST = ujson.loads(urllib.request.urlopen(VERSION_MANIFEST_URL).read().decode("utf-8"))
-rawExecutionMode = input("Enter execution mode (generate, cherry-pick, generate-start-at) [generate]: ")
-
-
-class ExecutionModes(Enum):
- GENERATE = 0
- GENERATE_START_WITH = 1
- CHERRY_PICK = 2
-
-
-executionMode = ExecutionModes.GENERATE
-
def searchVersion(versionId):
global VERSION_MANIFEST
@@ -48,45 +36,11 @@ def searchVersion(versionId):
raise Exception("Unknown version: %s" % versionId)
-class CherryPickOperators(Enum):
- EQUALS = 0
- LESS = 1
- GREATER = 2
-
-
-cherryPickCommit = ""
-versionToCherryPick = ""
-cherryPickOperator = CherryPickOperators.EQUALS
-
-startWithVersion = ""
-
-
-def detectExecutionMode():
- global executionMode, cherryPickCommit, versionToCherryPick, cherryPickOperator, startWithVersion
- if rawExecutionMode == "generate" or rawExecutionMode == "":
- executionMode = ExecutionModes.GENERATE
- elif rawExecutionMode == "generate-start-at":
- executionMode = ExecutionModes.GENERATE_START_WITH
- startWithVersion = input("Enter version to start with: ")
- searchVersion(startWithVersion)
- elif rawExecutionMode == "cherry-pick":
- executionMode = ExecutionModes.CHERRY_PICK
- cherryPickCommit = input("Enter commit to cherry-pick: ")
- versionToCherryPick = input("Enter versions to cherry-pick (<1.15.2, ...): ")
- if versionToCherryPick.startswith("<"):
- cherryPickOperator = CherryPickOperators.LESS
- versionToCherryPick = versionToCherryPick = versionToCherryPick[1:]
- elif versionToCherryPick.startswith(">"):
- cherryPickOperator = CherryPickOperators.GREATER
- versionToCherryPick = versionToCherryPick = versionToCherryPick[1:]
- searchVersion(versionToCherryPick)
-
- else:
- print("Unknown execution mode: %s" % rawExecutionMode)
- exit(2)
-
-
-detectExecutionMode()
+startWithVersion = input("Enter version to start with: ")
+if startWithVersion == "":
+ startWithVersion = VERSION_MANIFEST["versions"][0]["id"]
+ print("No version provided, starting with %s" % startWithVersion)
+searchVersion(startWithVersion)
def runAndWait(command):
@@ -118,18 +72,20 @@ def checkDeobfuscatedJar(jarBasePath, jarType, version, versionJson):
mojangJarPath = jarBasePath + jarType + "_mojang.jar"
if not os.path.isfile(mojangJarPath):
print("Downloading mojang %s jar for %s" % (jarType, version["id"]))
- urllib.request.urlretrieve(versionJson["downloads"][jarType]["url"], mojangJarPath)
+ urllib.request.urlretrieve(versionJson["downloads"][jarType]["url"], mojangJarPath + ".tmp")
+ os.rename(mojangJarPath + ".tmp", mojangJarPath)
mojangMappingsPath = jarBasePath + jarType + "_mappings.txt"
if not os.path.isfile(mojangMappingsPath):
print("Downloading mojang %s mappings for %s" % (jarType, version["id"]))
- urllib.request.urlretrieve(versionJson["downloads"][jarType + "_mappings"]["url"], mojangMappingsPath)
+ urllib.request.urlretrieve(versionJson["downloads"][jarType + "_mappings"]["url"], mojangMappingsPath + ".tmp")
+ os.rename(mojangMappingsPath + ".tmp", mojangMappingsPath)
# deobfuscate
print("Deobfuscating %s jar for %s" % (jarType, version["id"]))
global MC_REMAPPER_EXECUTABLE
- deobfuscateProcess = subprocess.Popen('%s \"%s\" \"%s\" --output-name \"%s\"' % (MC_REMAPPER_EXECUTABLE, mojangJarPath, mojangMappingsPath, jarPath), cwd=r'.', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ deobfuscateProcess = subprocess.Popen('%s \"%s\" \"%s\" --output-name \"%s\"' % (MC_REMAPPER_EXECUTABLE, mojangJarPath, mojangMappingsPath, jarPath + ".tmp"), cwd=r'.', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
exitCode = deobfuscateProcess.wait()
if exitCode != 0:
print("Could not deobfuscate %s jar for %s" % (jarType, version["id"]))
@@ -140,8 +96,8 @@ def checkDeobfuscatedJar(jarBasePath, jarType, version, versionJson):
else:
# delete mojang jars
print("Deleting META-INF folder")
- zipIn = zipfile.ZipFile(jarPath, 'r')
- zipOut = zipfile.ZipFile(jarPath + ".tmp", 'w')
+ zipIn = zipfile.ZipFile(jarPath + ".tmp", 'r')
+ zipOut = zipfile.ZipFile(jarPath + ".tmp2", 'w')
for item in zipIn.infolist():
buffer = zipIn.read(item.filename)
if not item.filename.startswith("META-INF"):
@@ -150,8 +106,8 @@ def checkDeobfuscatedJar(jarBasePath, jarType, version, versionJson):
zipOut.close()
zipIn.close()
- os.remove(jarPath)
- os.rename(jarPath + ".tmp", jarPath)
+ os.remove(jarPath + ".tmp")
+ os.rename(jarPath + ".tmp2", jarPath)
print("Deleting %s jar and mappings for %s" % (jarType, version["id"]))
os.remove(mojangJarPath)
@@ -172,17 +128,20 @@ def replaceInFile(file, search, replace):
fout.write(line.replace(search, replace))
-stopCherryPicking = cherryPickOperator == CherryPickOperators.LESS
+def compilePixLyzer():
+ print("Compiling pixlyzer...")
+ if runAndWait('mvn clean verify') != 0:
+ raise Exception("Can not compile for %s" % version["id"])
+ print("PixLyzer is now compiled")
-startWorking = executionMode == ExecutionModes.GENERATE
+
+compilePixLyzer()
+
+startWorking = False
for version in VERSION_MANIFEST["versions"]:
- if executionMode == ExecutionModes.CHERRY_PICK:
- if version["id"] == versionToCherryPick:
- startWorking = True
- elif executionMode == ExecutionModes.GENERATE_START_WITH:
- if version["id"] == startWithVersion:
- startWorking = True
+ if version["id"] == startWithVersion:
+ startWorking = True
if not startWorking:
continue
@@ -191,15 +150,6 @@ for version in VERSION_MANIFEST["versions"]:
print("Skipping %s" % version["id"])
continue
- if cherryPickOperator == CherryPickOperators.GREATER:
- if version["id"] == versionToCherryPick:
- stopCherryPicking = True
- print("Stop cherry picking.")
- elif cherryPickOperator == CherryPickOperators.LESS:
- if version["id"] == versionToCherryPick:
- stopCherryPicking = False
- print("Start cherry picking.")
-
if version["id"] == DOWNLOAD_UNTIL_VERSION:
print("Breaking at %s" % version["id"])
break
@@ -208,29 +158,13 @@ for version in VERSION_MANIFEST["versions"]:
checkDeobfuscatedJars(version, versionJson)
- # checkout correct branch, add jars to maven, build and run in maven
- if runAndWait('git checkout version-%s' % version["id"].replace(" ", "-")) != 0:
- print("WARN: No branch not found (%s). Skipping this version" % version["id"].replace(" ", "-"))
- continue
-
- if executionMode == ExecutionModes.CHERRY_PICK and not stopCherryPicking:
- print("Cherry-picking commit %s for %s" % (cherryPickCommit, version["id"]))
- if runAndWait("git cherry-pick --strategy=recursive -X theirs %s" % cherryPickCommit) != 0:
- print("Failed to cherry-pick commit %s for %s" % (cherryPickCommit, version["id"]))
- break
-
- # build
- if runAndWait('mvn clean verify') != 0:
- print("Can not compile for %s" % version["id"])
- break
-
+ versionStartTime = datetime.now()
+ print("Generating data for %s" % version["id"])
# execute
if runAndWait("%s -classpath \"%s:%s:%s:%s\" de.bixilon.pixlyzer.PixLyzer %s %s %s" % (JAVA_PATH, ADDITIONAL_CLASSPATH, DATA_FOLDER + version["id"] + "/" + version["id"] + "_client.jar", DATA_FOLDER + version["id"] + "/" + version["id"] + "_server.jar", "target/classes", OUT_FOLDER + version["id"], HASH_FOLDER, ASSETS_HASH_INDEX_FILE)) != 0:
print("PixLyzer did not run successfully for %s" % version["id"])
break
- print("Done generating %s" % version["id"])
-
-runAndWait('git checkout master')
+ print("Done generating %s in %s" % (version["id"], (datetime.now() - versionStartTime)))
print("Done with downloading and generating all data")