update PixLyzer.py and fix some pixlyzer issues

This commit is contained in:
Bixilon 2021-03-09 22:19:20 +01:00
parent 2e428dbdf4
commit 0b348bb92c
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
5 changed files with 74 additions and 105 deletions

View File

@ -9,7 +9,7 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>pixlyzer</name> <name>PixLyzer</name>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

View File

@ -208,7 +208,9 @@ object BlockGenerator : Generator(
val propertyData = JsonObject() val propertyData = JsonObject()
for ((property, stateProperty) in state.values) { 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) { 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 { private fun getOrAddVoxelShape(voxelShape: VoxelShape): Int {
if (VOXEL_SHAPES.contains(voxelShape)) { if (VOXEL_SHAPES.contains(voxelShape)) {
return VOXEL_SHAPES.indexOf(voxelShape) return VOXEL_SHAPES.indexOf(voxelShape)

View File

@ -2,6 +2,7 @@ package de.bixilon.pixlyzer.generator.generators
import com.google.gson.JsonObject import com.google.gson.JsonObject
import de.bixilon.pixlyzer.generator.Generator import de.bixilon.pixlyzer.generator.Generator
import de.bixilon.pixlyzer.util.ReflectionUtil.getClass
import de.bixilon.pixlyzer.util.ReflectionUtil.getField import de.bixilon.pixlyzer.util.ReflectionUtil.getField
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.level.dimension.DimensionType import net.minecraft.world.level.dimension.DimensionType
@ -12,7 +13,6 @@ object DimensionGenerator : Generator(
"dimensions" "dimensions"
) { ) {
override fun generate() { override fun generate() {
// val registry = Registry.REGISTRY.get(Registry.DIMENSION_TYPE_REGISTRY.location()) as Registry<DimensionType>
for ((resourceLocation, id, dimension) in getDimensions()) { for ((resourceLocation, id, dimension) in getDimensions()) {
val dimensionData = JsonObject() val dimensionData = JsonObject()
@ -100,6 +100,11 @@ object DimensionGenerator : Generator(
private val AMBIENT_LIGHT_FIELD = getField(DIMENSION_TYPE_CLASS, "ambientLight") 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<Triple<ResourceLocation, Int?, DimensionType>> { private fun getDimensions(): MutableSet<Triple<ResourceLocation, Int?, DimensionType>> {
val types: MutableSet<Triple<ResourceLocation, Int?, DimensionType>> = mutableSetOf() val types: MutableSet<Triple<ResourceLocation, Int?, DimensionType>> = mutableSetOf()
@ -121,6 +126,14 @@ object DimensionGenerator : Generator(
types.add(Triple(resourceLocation, null, field.get(null) as DimensionType)) 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<Any, DimensionType>) {
types.add(Triple(RESOURCE_KEY_LOCATION_METHOD!!.invoke(resourceLocation) as ResourceLocation, null, dimension))
}
}
return types return types
} }
} }

View File

@ -14,6 +14,7 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.Entity import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.LivingEntity import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.ai.attributes.Attribute import net.minecraft.world.entity.ai.attributes.Attribute
import net.minecraft.world.entity.ai.attributes.AttributeInstance
import java.lang.reflect.Modifier import java.lang.reflect.Modifier
object EntityGenerator : Generator( object EntityGenerator : Generator(
@ -49,12 +50,17 @@ object EntityGenerator : Generator(
if (entity is LivingEntity && entity2 is LivingEntity) { if (entity is LivingEntity && entity2 is LivingEntity) {
for ((resourceLocation, attribute) in ATTRIBUTE_MAP) { for ((resourceLocation, attribute) in ATTRIBUTE_MAP) {
entity.attributes.getInstance(attribute)?.value?.let { val attributes = LIVING_ENTITY_GET_ATTRIBUTES_METHOD.invoke(entity) ?: continue
if (it != entity2.attributes.getInstance(attribute)?.value) { val instance = BASE_ATTRIBUTE_MAP_GET_INSTANCE_METHOD.invoke(attributes, attribute) as AttributeInstance? ?: continue
return@let val value = ATTRIBUTE_INSTANCE_BASE_VALUE_METHOD.invoke(instance) as Double
}
entityData.addProperty(resourceIdentifier.toString(), it) 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 { // entity.getEatingSound(ItemStack.EMPTY)?.let {
@ -167,9 +173,19 @@ object EntityGenerator : Generator(
private val ATTRIBUTE_MAP: Map<String, Attribute> = getAttributes() private val ATTRIBUTE_MAP: Map<String, Attribute> = 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<String, Attribute> { private fun getAttributes(): Map<String, Attribute> {
val attributeRegistryField = getField(Registry::class.java, "ATTRIBUTE") val attributeRegistryField = getField(Registry::class.java, "ATTRIBUTE", "ATTRIBUTES")
val attributeNameField = try { val attributeNameField = try {
Attribute::class.java.getMethod("getName") Attribute::class.java.getMethod("getName")
} catch (exception: NoSuchMethodException) { } catch (exception: NoSuchMethodException) {

View File

@ -2,7 +2,7 @@ import os
import subprocess import subprocess
import urllib.request import urllib.request
import zipfile import zipfile
from enum import Enum from datetime import datetime
from pathlib import Path from pathlib import Path
import ujson import ujson
@ -12,12 +12,11 @@ SKIP_VERSIONS = ["19w35a", "19w34a"]
HASH_FOLDER = os.path.abspath("data/hash/") + "/" HASH_FOLDER = os.path.abspath("data/hash/") + "/"
ASSETS_HASH_INDEX_FILE = os.path.abspath("data/index") ASSETS_HASH_INDEX_FILE = os.path.abspath("data/index")
OUT_FOLDER = os.path.abspath("data/version/") + "/" OUT_FOLDER = os.path.abspath("data/version/") + "/"
LOGS_FOLDER = os.path.abspath("data/logs/") + "/"
DATA_FOLDER = os.path.abspath("data/data/") + "/" DATA_FOLDER = os.path.abspath("data/data/") + "/"
MC_REMAPPER_EXECUTABLE = "/home/moritz/Games/Minecraft/MC-Remapper/build/install/MC-Remapper/bin/MC-Remapper" 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" 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" VERSION_MANIFEST_URL = "https://launchermeta.mojang.com/mc/game/version_manifest.json"
@ -28,17 +27,6 @@ print("Starting PixLyzer generator")
print("Downloading version manifest") print("Downloading version manifest")
VERSION_MANIFEST = ujson.loads(urllib.request.urlopen(VERSION_MANIFEST_URL).read().decode("utf-8")) 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): def searchVersion(versionId):
global VERSION_MANIFEST global VERSION_MANIFEST
@ -48,45 +36,11 @@ def searchVersion(versionId):
raise Exception("Unknown version: %s" % versionId) raise Exception("Unknown version: %s" % versionId)
class CherryPickOperators(Enum): startWithVersion = input("Enter version to start with: ")
EQUALS = 0 if startWithVersion == "":
LESS = 1 startWithVersion = VERSION_MANIFEST["versions"][0]["id"]
GREATER = 2 print("No version provided, starting with %s" % startWithVersion)
searchVersion(startWithVersion)
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()
def runAndWait(command): def runAndWait(command):
@ -118,18 +72,20 @@ def checkDeobfuscatedJar(jarBasePath, jarType, version, versionJson):
mojangJarPath = jarBasePath + jarType + "_mojang.jar" mojangJarPath = jarBasePath + jarType + "_mojang.jar"
if not os.path.isfile(mojangJarPath): if not os.path.isfile(mojangJarPath):
print("Downloading mojang %s jar for %s" % (jarType, version["id"])) 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" mojangMappingsPath = jarBasePath + jarType + "_mappings.txt"
if not os.path.isfile(mojangMappingsPath): if not os.path.isfile(mojangMappingsPath):
print("Downloading mojang %s mappings for %s" % (jarType, version["id"])) 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 # deobfuscate
print("Deobfuscating %s jar for %s" % (jarType, version["id"])) print("Deobfuscating %s jar for %s" % (jarType, version["id"]))
global MC_REMAPPER_EXECUTABLE 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() exitCode = deobfuscateProcess.wait()
if exitCode != 0: if exitCode != 0:
print("Could not deobfuscate %s jar for %s" % (jarType, version["id"])) print("Could not deobfuscate %s jar for %s" % (jarType, version["id"]))
@ -140,8 +96,8 @@ def checkDeobfuscatedJar(jarBasePath, jarType, version, versionJson):
else: else:
# delete mojang jars # delete mojang jars
print("Deleting META-INF folder") print("Deleting META-INF folder")
zipIn = zipfile.ZipFile(jarPath, 'r') zipIn = zipfile.ZipFile(jarPath + ".tmp", 'r')
zipOut = zipfile.ZipFile(jarPath + ".tmp", 'w') zipOut = zipfile.ZipFile(jarPath + ".tmp2", 'w')
for item in zipIn.infolist(): for item in zipIn.infolist():
buffer = zipIn.read(item.filename) buffer = zipIn.read(item.filename)
if not item.filename.startswith("META-INF"): if not item.filename.startswith("META-INF"):
@ -150,8 +106,8 @@ def checkDeobfuscatedJar(jarBasePath, jarType, version, versionJson):
zipOut.close() zipOut.close()
zipIn.close() zipIn.close()
os.remove(jarPath) os.remove(jarPath + ".tmp")
os.rename(jarPath + ".tmp", jarPath) os.rename(jarPath + ".tmp2", jarPath)
print("Deleting %s jar and mappings for %s" % (jarType, version["id"])) print("Deleting %s jar and mappings for %s" % (jarType, version["id"]))
os.remove(mojangJarPath) os.remove(mojangJarPath)
@ -172,17 +128,20 @@ def replaceInFile(file, search, replace):
fout.write(line.replace(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"]: for version in VERSION_MANIFEST["versions"]:
if executionMode == ExecutionModes.CHERRY_PICK: if version["id"] == startWithVersion:
if version["id"] == versionToCherryPick: startWorking = True
startWorking = True
elif executionMode == ExecutionModes.GENERATE_START_WITH:
if version["id"] == startWithVersion:
startWorking = True
if not startWorking: if not startWorking:
continue continue
@ -191,15 +150,6 @@ for version in VERSION_MANIFEST["versions"]:
print("Skipping %s" % version["id"]) print("Skipping %s" % version["id"])
continue 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: if version["id"] == DOWNLOAD_UNTIL_VERSION:
print("Breaking at %s" % version["id"]) print("Breaking at %s" % version["id"])
break break
@ -208,29 +158,13 @@ for version in VERSION_MANIFEST["versions"]:
checkDeobfuscatedJars(version, versionJson) checkDeobfuscatedJars(version, versionJson)
# checkout correct branch, add jars to maven, build and run in maven versionStartTime = datetime.now()
if runAndWait('git checkout version-%s' % version["id"].replace(" ", "-")) != 0: print("Generating data for %s" % version["id"])
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
# execute # 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: 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"]) print("PixLyzer did not run successfully for %s" % version["id"])
break break
print("Done generating %s" % version["id"]) print("Done generating %s in %s" % (version["id"], (datetime.now() - versionStartTime)))
runAndWait('git checkout master')
print("Done with downloading and generating all data") print("Done with downloading and generating all data")