port until 19w11b

This commit is contained in:
Bixilon 2021-03-24 15:26:59 +01:00
parent b71df12783
commit 6dc1eb0a75
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
11 changed files with 185 additions and 126 deletions

View File

@ -15,7 +15,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<kotlin.code.style>official</kotlin.code.style>
<kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>
<minecraft.version>1.14.4</minecraft.version>
<minecraft.version>1.14.3</minecraft.version>
</properties>
<repositories>
@ -78,7 +78,7 @@
<artifactId>client</artifactId>
<version>1</version>
<scope>system</scope>
<systemPath>${project.basedir}/wrapper/data/data/${minecraft.version}_yarn/${minecraft.version}_yarn_client.jar</systemPath>
<systemPath>${project.basedir}/wrapper/data/data/${minecraft.version}_yarn/${minecraft.version}-named.jar</systemPath>
</dependency>
<dependency>
@ -86,7 +86,7 @@
<artifactId>server</artifactId>
<version>1</version>
<scope>system</scope>
<systemPath>${project.basedir}/wrapper/data/data/${minecraft.version}_yarn/${minecraft.version}_server.jar</systemPath>
<systemPath>${project.basedir}/wrapper/data/data/${minecraft.version}_yarn/${minecraft.version}_server_mojang.jar</systemPath>
</dependency>
<dependency>
<groupId>org.objenesis</groupId>

View File

@ -7,6 +7,7 @@ import de.bixilon.pixlyzer.util.ReflectionUtil.setFinalField
import net.minecraft.client.network.OtherClientPlayerEntity
import net.minecraft.entity.Entity
import net.minecraft.entity.EntityType
import net.minecraft.entity.decoration.ItemFrameEntity
import net.minecraft.scoreboard.Scoreboard
import net.minecraft.world.World
import net.minecraft.world.border.WorldBorder
@ -18,21 +19,29 @@ import java.util.*
object EntitySpawner {
fun summonEntity(entityType: EntityType<*>): Entity {
val factory = FACTORY_FIELD.get(entityType) as EntityType.EntityFactory<Entity>
val entity = factory.create(entityType as EntityType<Entity>?, CLIENT_LEVEL)
when (entityType) {
EntityType.PLAYER -> return OtherClientPlayerEntity::class.java.getConstructor(levelClass, GameProfile::class.java).newInstance(CLIENT_LEVEL, GameProfile(UUID.randomUUID(), "dummy"))
EntityType.LIGHTNING_BOLT -> return OBJENSIS.newInstance(LIGHTNING_BOLT_CLASS) as Entity
EntityType.FISHING_BOBBER -> return OBJENSIS.newInstance(FISHING_HOOK_CLASS) as Entity
EntityType.ITEM_FRAME -> return OBJENSIS.newInstance(ItemFrameEntity::class.java) as Entity
}
val entity = try {
ENTITY_CREATE_METHOD?.invoke(FACTORY_FIELD.get(entityType), entityType, CLIENT_LEVEL) as Entity?
} catch (exception: Exception) {
exception.printStackTrace()
TODO()
}
if (entity != null) {
return entity
}
return when (entityType) {
EntityType.PLAYER -> OtherClientPlayerEntity::class.java.getConstructor(levelClass, GameProfile::class.java).newInstance(CLIENT_LEVEL, GameProfile(UUID.randomUUID(), "dummy"))
EntityType.LIGHTNING_BOLT -> OBJENSIS.newInstance(LIGHTNING_BOLT_CLASS) as Entity
EntityType.FISHING_BOBBER -> OBJENSIS.newInstance(FISHING_HOOK_CLASS) as Entity
else -> TODO("Entity type: $entityType")
}
TODO("Entity type: $entityType")
}
private val LIGHTNING_BOLT_CLASS = getClass("net.minecraft.entity.LightningEntity")!!
private val FISHING_HOOK_CLASS = getClass("net.minecraft.entity.projectile.FishingBobberEntity")!!
@ -40,9 +49,21 @@ object EntitySpawner {
private val FACTORY_FIELD = getField(EntityType::class.java, "factory")!!
private val ENTITY_CREATE_METHOD = try {
getClass("net.minecraft.entity.EntityType\$EntityFactory")?.getDeclaredMethod("create", EntityType::class.java, World::class.java)
} catch (exception: Exception) {
null
}
private val LEGACY_ENTITY_CREATE_METHOD = try {
getClass("net.minecraft.entity.EntityType\$EntityFactory")?.getDeclaredMethod("create", EntityType::class.java, World::class.java)
} catch (exception: Exception) {
null
}
var OBJENSIS: Objenesis = ObjenesisStd()
val CLIENT_LEVEL = OBJENSIS.newInstance(levelClass) as World
private val CLIENT_LEVEL = OBJENSIS.newInstance(levelClass) as World
init {

View File

@ -70,7 +70,13 @@ object PixLyzer {
val startTime = System.currentTimeMillis()
println("Starting ${generator.name}...")
generator.generate()
try {
generator.generate()
} catch (exception: IllegalArgumentException) {
// not implemented
println("Skipping ${generator.name}: ${exception.message}")
continue
}
if (generator.data.size() == 0) {
error("${generator.fileName} has 0 entries!")
}
@ -125,7 +131,7 @@ object PixLyzer {
val assetsIndexJson = Util.readJsonFile(assetsIndex.absolutePath + ".json")
val versionId = MinecraftVersion.create().id
val versionId = MinecraftVersion.create().name // ToDo: Should be id, but in 1.14 there is a hash in the id???
assetsIndexJson.addProperty(versionId, hash)

View File

@ -3,6 +3,7 @@ package de.bixilon.pixlyzer.generator.generators
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import de.bixilon.pixlyzer.generator.Generator
import de.bixilon.pixlyzer.util.ReflectionUtil
import net.minecraft.block.Block
import net.minecraft.block.entity.BlockEntityType
import net.minecraft.util.registry.Registry
@ -16,7 +17,7 @@ object BlockEntityGenerator : Generator(
val blockEntityData = JsonObject()
blockEntityData.addProperty("id", Registry.BLOCK_ENTITY.getRawId(blockEntityType))
(BLOCK_ENTITY_VALID_BLOCKS_FIELD.get(blockEntityType) as Set<Block>).let {
(BLOCK_ENTITY_VALID_BLOCKS_FIELD?.get(blockEntityType) as Set<Block>?)?.let {
val blockTypes = JsonArray()
for (block in it) {
@ -32,9 +33,5 @@ object BlockEntityGenerator : Generator(
}
}
private val BLOCK_ENTITY_VALID_BLOCKS_FIELD = BlockEntityType::class.java.getDeclaredField("blocks")
init {
BLOCK_ENTITY_VALID_BLOCKS_FIELD.isAccessible = true
}
private val BLOCK_ENTITY_VALID_BLOCKS_FIELD = ReflectionUtil.getField(BlockEntityType::class.java, "blocks")
}

View File

@ -126,7 +126,9 @@ object BlockGenerator : Generator(
}
}
val colorProperties = DEFAULT_BLOCK_COLORS.method_21592(block)
val hasColorProperties = (TINT_PROPERTIES_METHOD?.invoke(DEFAULT_BLOCK_COLORS, block) as Set<*>?)?.size?.let { it > 0 } ?: let {
true
}
val states = JsonObject()
@ -195,7 +197,7 @@ object BlockGenerator : Generator(
try {
if (colorProperties.size > 0) {
if (hasColorProperties) {
val tintColor = DEFAULT_BLOCK_COLORS.getColor(state, null, null)
if (tintColor == -1) {
throw IllegalStateException()
@ -270,7 +272,7 @@ object BlockGenerator : Generator(
}
stateData.addProperty("large_collision_shape", it)
}
IS_COLLISION_SHAPE_FULL_BLOCK.getBoolean(cache).let {
IS_COLLISION_SHAPE_FULL_BLOCK?.getBoolean(cache)?.let {
if (!it) {
return@let
}
@ -298,13 +300,13 @@ object BlockGenerator : Generator(
}
(CACHE_COLLISION_SHAPES_FIELD.get(cache) as VoxelShape?)?.let {
(CACHE_COLLISION_SHAPES_FIELD?.get(cache) as VoxelShape?)?.let {
if (it.isEmpty) {
return@let
}
stateData.addProperty("collision_shapes", getOrAddVoxelShape(it))
}
(IS_FACE_STURDY.get(cache) as BooleanArray?)?.let {
(IS_FACE_STURDY?.get(cache) as BooleanArray?)?.let {
if (allTheSame(it)) {
stateData.addProperty("is_sturdy", it[0])
return@let
@ -330,6 +332,13 @@ object BlockGenerator : Generator(
}
}
private val TINT_PROPERTIES_METHOD = try {
BlockColors::class.java.getDeclaredMethod("method_21592")
} catch (exception: Exception) {
null
}
private val PROPERTY_METHOD = getClass("net.minecraft.state.property.Property")!!
private val PROPERTY_NAME_METHOD = PROPERTY_METHOD.getDeclaredMethod("getName")
@ -378,10 +387,10 @@ object BlockGenerator : Generator(
private val CACHE_PROPAGATES_SKYLIGHT_DOWN_FIELD = BLOCK_STATE_CACHE_CLASS.getDeclaredField("translucent")
private val CACHE_LIGHT_BLOCK_FIELD = BLOCK_STATE_CACHE_CLASS.getDeclaredField("lightSubtracted")
private val CACHE_OCCLUSION_SHAPES_FIELD = BLOCK_STATE_CACHE_CLASS.getDeclaredField("shapes")
private val CACHE_COLLISION_SHAPES_FIELD = BLOCK_STATE_CACHE_CLASS.getDeclaredField("collisionShape")
private val CACHE_COLLISION_SHAPES_FIELD = getField(BLOCK_STATE_CACHE_CLASS, "collisionShape") // ToDo: Not working in < 1.14.3
private val LARGE_COLLISION_SHAPE_FIELD = BLOCK_STATE_CACHE_CLASS.getDeclaredField("field_17651")
private val IS_FACE_STURDY = getField(BLOCK_STATE_CACHE_CLASS, "faceSturdy", "isFaceSturdy", "solidFullSquare")!!
private val IS_COLLISION_SHAPE_FULL_BLOCK = BLOCK_STATE_CACHE_CLASS.getDeclaredField("shapeIsFullCube")
private val IS_FACE_STURDY = getField(BLOCK_STATE_CACHE_CLASS, "faceSturdy", "isFaceSturdy", "solidFullSquare")
private val IS_COLLISION_SHAPE_FULL_BLOCK = getField(BLOCK_STATE_CACHE_CLASS, "shapeIsFullCube", "field_17651")
private val BLOCK_SPEED_FACTOR_FIELD = getField(Block::class.java, "speedFactor")
@ -396,10 +405,7 @@ object BlockGenerator : Generator(
CACHE_PROPAGATES_SKYLIGHT_DOWN_FIELD.isAccessible = true
CACHE_LIGHT_BLOCK_FIELD.isAccessible = true
CACHE_OCCLUSION_SHAPES_FIELD.isAccessible = true
CACHE_COLLISION_SHAPES_FIELD.isAccessible = true
LARGE_COLLISION_SHAPE_FIELD.isAccessible = true
IS_FACE_STURDY.isAccessible = true
IS_COLLISION_SHAPE_FULL_BLOCK.isAccessible = true
}
private val BLOCK_STATE_REGISTRY: IdList<BlockState> = Block.STATE_IDS

View File

@ -7,12 +7,15 @@ import de.bixilon.pixlyzer.generator.Generator
import de.bixilon.pixlyzer.util.ReflectionUtil.getClass
import de.bixilon.pixlyzer.util.ReflectionUtil.getField
import net.minecraft.entity.Entity
import net.minecraft.entity.EntityCategory
import net.minecraft.entity.EntityType
import net.minecraft.entity.LivingEntity
import net.minecraft.entity.attribute.EntityAttribute
import net.minecraft.entity.attribute.EntityAttributeInstance
import net.minecraft.entity.data.TrackedData
import net.minecraft.util.Identifier
import net.minecraft.util.registry.Registry
import java.lang.reflect.Method
import java.lang.reflect.Modifier
object EntityGenerator : Generator(
@ -28,24 +31,32 @@ object EntityGenerator : Generator(
entityType.translationKey?.let {
entityData.addProperty("description_id", it)
}
entityData.addProperty("category", entityType.category.ordinal)
entityData.addProperty("serialize", entityType.isSaveable)
entityData.addProperty("summon", entityType.isSummonable)
entityData.addProperty("fire_immune", entityType.isFireImmune)
entityData.addProperty("can_spawn_far_from_player", entityType.method_20814())
ENTITY_TYPE_FIRE_IMMUNE_FIELD?.getBoolean(entityType)?.let {
entityData.addProperty("fire_immune", it)
}
CAN_SPAWN_FAR_AWAY_FROM_PLAYER_METHOD?.invoke(entityType)?.let {
entityData.addProperty("can_spawn_far_from_player", it as Boolean)
}
entityType.lootTableId?.let {
entityData.addProperty("loot_table", it.toString())
}
entityData.addProperty("width", entityType.dimensions.width)
entityData.addProperty("height", entityType.dimensions.height)
entityData.addProperty("size_fixed", entityType.dimensions.fixed)
getEntitySize(entityType).let {
entityData.addProperty("width", it.first)
entityData.addProperty("height", it.second)
entityData.addProperty("size_fixed", it.third)
}
val entity = EntitySpawner.summonEntity(entityType)
val entity2 = EntitySpawner.summonEntity(entityType)
// some entities have random values, we can and will ignore these ones
entityData.addProperty("category", entityType.getEntityCategory(entity).ordinal)
if (entity is LivingEntity && entity2 is LivingEntity) {
for ((resourceLocation, attribute) in ATTRIBUTE_MAP) {
val attributes = LIVING_ENTITY_GET_ATTRIBUTES_METHOD.invoke(entity) ?: continue
@ -170,6 +181,14 @@ object EntityGenerator : Generator(
return json
}
private val CAN_SPAWN_FAR_AWAY_FROM_PLAYER_METHOD: Method? = try {
EntityType::class.java.getDeclaredMethod("method_20814")
} catch (exception: Exception) {
null
}
private val ENTITY_TYPE_FIRE_IMMUNE_FIELD = getField(EntityType::class.java, "fireImmune")
private val ATTRIBUTE_CLASS = getClass("net.minecraft.world.entity.ai.attributes.Attributes", "net.minecraft.world.entity.monster.SharedMonsterAttributes", "net.minecraft.entity.attribute.EntityAttributes")!!
private val ATTRIBUTE_MAP: Map<String, EntityAttribute> = getAttributes()
@ -189,6 +208,25 @@ object EntityGenerator : Generator(
private val ATTRIBUTE_INSTANCE_BASE_VALUE_METHOD = ATTRIBUTE_INSTANCE_CLASS.getMethod("getBaseValue")
private val ENTITY_DIMENSION_FIELD = getField(EntityType::class.java, "dimensions")
private val ENTITY_DIMENSION_CLASS = getClass("net.minecraft.entity.EntityDimensions")
private val ENTITY_DIMENSION_WIDTH_FIELD = getField(ENTITY_DIMENSION_CLASS, "width")
private val ENTITY_DIMENSION_HEIGHT_FIELD = getField(ENTITY_DIMENSION_CLASS, "height")
private val ENTITY_DIMENSION_FIXED_FIELD = getField(ENTITY_DIMENSION_CLASS, "fixed")
private val ENTITY_WIDTH_FIELD = getField(EntityType::class.java, "field_17488")
private val ENTITY_HEIGHT_FIELD = getField(EntityType::class.java, "field_17489")
private fun getEntitySize(entityType: EntityType<*>): Triple<Float, Float, Boolean?> {
ENTITY_DIMENSION_CLASS?.let {
val dimension = ENTITY_DIMENSION_FIELD!!.get(entityType)
return Triple(ENTITY_DIMENSION_WIDTH_FIELD!!.getFloat(dimension), ENTITY_DIMENSION_HEIGHT_FIELD!!.getFloat(dimension), ENTITY_DIMENSION_FIXED_FIELD!!.getBoolean(dimension))
}
return Triple(ENTITY_WIDTH_FIELD!!.getFloat(entityType), ENTITY_HEIGHT_FIELD!!.getFloat(entityType), null)
}
private fun getAttributes(): Map<String, EntityAttribute> {
val attributeRegistryField = getField(Registry::class.java, "ATTRIBUTE", "ATTRIBUTES")
@ -227,3 +265,18 @@ object EntityGenerator : Generator(
TODO()
}
}
private val CATEGORY_FIELD = getField(EntityType::class.java, "category")
private val ENTITY_CATEGORY_GET_CATEGORY_METHOD = try {
EntityCategory::class.java.getDeclaredMethod("method_17350", Entity::class.java)
} catch (exception: Exception) {
null
}
private fun EntityType<*>.getEntityCategory(entity: Entity): EntityCategory {
(CATEGORY_FIELD?.get(this) as EntityCategory?)?.let {
return it
}
return ENTITY_CATEGORY_GET_CATEGORY_METHOD!!.invoke(entity) as EntityCategory
}

View File

@ -3,21 +3,29 @@ package de.bixilon.pixlyzer.generator.generators
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import de.bixilon.pixlyzer.generator.Generator
import de.bixilon.pixlyzer.util.ReflectionUtil
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.util.registry.Registry
import net.minecraft.world.poi.PointOfInterestType
import java.lang.reflect.Method
object PointOfInterestGenerator : Generator(
"points_of_interest"
) {
override fun generate() {
if (POINT_OF_INTEREST_REGISTRY == null) {
throw IllegalArgumentException("Not available in this version yet!")
}
for (pointOfInterestType in Registry.POINT_OF_INTEREST_TYPE) {
val resourceIdentifier = Registry.POINT_OF_INTEREST_TYPE.getId(pointOfInterestType)
val pointOfInterestData = JsonObject()
pointOfInterestData.addProperty("id", Registry.POINT_OF_INTEREST_TYPE.getRawId(pointOfInterestType))
pointOfInterestData.addProperty("max_tickets", pointOfInterestType.ticketCount)
pointOfInterestData.addProperty("valid_range", pointOfInterestType.method_21648())
VALID_RANGE_METHOD?.invoke(pointOfInterestType)?.let {
pointOfInterestData.addProperty("valid_range", it as Int)
}
(POINT_OF_INTEREST_MATCHING_STATES_FIELD.get(pointOfInterestType) as Set<BlockState>).let {
val states = JsonArray()
@ -31,9 +39,18 @@ object PointOfInterestGenerator : Generator(
}
}
val POINT_OF_INTEREST_REGISTRY = ReflectionUtil.getField(Registry::class.java, "POINT_OF_INTEREST_TYPE")?.get(null) as Registry<Any>?
private val POINT_OF_INTEREST_MATCHING_STATES_FIELD = PointOfInterestType::class.java.getDeclaredField("blockStates")
private val VALID_RANGE_METHOD: Method?
init {
POINT_OF_INTEREST_MATCHING_STATES_FIELD.isAccessible = true
VALID_RANGE_METHOD = try {
PointOfInterestType::class.java.getDeclaredMethod("method_21648")
} catch (exception: Exception) {
null
}
}
}

View File

@ -1,9 +1,12 @@
package de.bixilon.pixlyzer.generator.generators
import com.google.common.collect.ImmutableSet
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import de.bixilon.pixlyzer.generator.Generator
import de.bixilon.pixlyzer.util.ReflectionUtil.getField
import net.minecraft.block.Block
import net.minecraft.item.Item
import net.minecraft.sound.SoundEvent
import net.minecraft.util.registry.Registry
import net.minecraft.village.VillagerProfession
@ -17,9 +20,11 @@ object VillagerProfessionGenerator : Generator(
val villagerProfessionData = JsonObject()
villagerProfessionData.addProperty("id", Registry.VILLAGER_PROFESSION.getRawId(villagerProfession))
villagerProfessionData.addProperty("primary_point_of_interest", Registry.POINT_OF_INTEREST_TYPE.getRawId(villagerProfession.workStation))
PointOfInterestGenerator.POINT_OF_INTEREST_REGISTRY?.let {
villagerProfessionData.addProperty("primary_point_of_interest", it.getRawId(WORK_STATION_VILLAGER_PROFESSION_TYPE_FIELD!!.get(villagerProfession)))
}
villagerProfession.gatherableItems.let {
(GATHERABLE_ITEMS_FIELD?.get(villagerProfession) as ImmutableSet<Item>?)?.let {
val requestedItems = JsonArray()
for (item in it) {
requestedItems.add(Registry.ITEM.getRawId(item))
@ -30,7 +35,7 @@ object VillagerProfessionGenerator : Generator(
}
}
villagerProfession.secondaryJobSites.let {
(SECONDARY_JOB_SITES_FIELD?.get(villagerProfession) as ImmutableSet<Block>?)?.let {
val blocks = JsonArray()
for (block in it) {
blocks.add(Registry.BLOCK.getRawId(block))
@ -49,5 +54,11 @@ object VillagerProfessionGenerator : Generator(
}
}
val WORK_SOUND_PROFESSION = getField(VillagerProfession::class.java, "workSound")
private val WORK_SOUND_PROFESSION = getField(VillagerProfession::class.java, "workSound")
private val WORK_STATION_VILLAGER_PROFESSION_TYPE_FIELD = getField(VillagerProfession::class.java, "workStation")
private val SECONDARY_JOB_SITES_FIELD = getField(VillagerProfession::class.java, "secondaryJobSites")
private val GATHERABLE_ITEMS_FIELD = getField(VillagerProfession::class.java, "gatherableItems")
}

View File

@ -3,6 +3,7 @@ package de.bixilon.pixlyzer.generator.generators
import com.google.gson.JsonArray
import com.google.gson.JsonObject
import de.bixilon.pixlyzer.generator.Generator
import de.bixilon.pixlyzer.util.ReflectionUtil
import net.minecraft.util.math.Box
import net.minecraft.util.shape.VoxelShape
@ -27,16 +28,12 @@ object VoxelShapeGenerator : Generator(
}
private val VOXEL_SHAPE_FACES_FIELD = VoxelShape::class.java.getDeclaredField("shapeCache")
init {
VOXEL_SHAPE_FACES_FIELD.isAccessible = true
}
private val VOXEL_SHAPE_FACES_FIELD = ReflectionUtil.getField(VoxelShape::class.java, "shapeCache")
private fun VoxelShape.serialize(): JsonObject {
val json = JsonObject()
val faces = VOXEL_SHAPE_FACES_FIELD.get(this) as Array<VoxelShape>?
val faces = VOXEL_SHAPE_FACES_FIELD?.get(this) as Array<VoxelShape>?
if (faces != null) {
check(faces.size == 6)

View File

@ -320,7 +320,8 @@
"data": {
"FUSE_SPEED": "CREEPER_STATE",
"CHARGED": "CREEPER_IS_CHARGED",
"IGNITED": "CREEPER_IS_IGNITED"
"IGNITED": "CREEPER_IS_IGNITED",
"field_19170": "3d_SHAREWARE_D20_BOOLEAN"
}
},
"EndermanEntity": {

View File

@ -1,31 +1,33 @@
import os
import subprocess
import urllib.request
import zipfile
from datetime import datetime
from pathlib import Path
import ujson
DOWNLOAD_UNTIL_VERSION = "1.14.4-pre7"
SKIP_VERSIONS = ["19w35a", "19w34a"]
# ToDo: "19w35a", "19w34a","19w11a", "19w09a", "19w08b", "19w08a", "19w07a", "19w06a", "19w05a", "19w04b", "19w04a", "19w03c", "19w03b", "19w03a", "19w02a", "18w50a", "18w49a", "18w48b" "18w48a", "18w47b", "18w47a", "18w46a", "18w45a", "18w44a", "18w43c", "18w43b"
VERSIONS_DO_GENERATE = ["1.14.4-pre7", "1.14.4-pre6", "1.14.4-pre5", "1.14.4-pre4", "1.14.4-pre3", "1.14.4-pre2", "1.14.4-pre1", "1.14.3", "1.14.3", "1.14.3-pre4",
"1.14.3-pre3", "1.14.3-pre2", "1.14.3-pre1", "1.14.2", "1.14.2 Pre-Release 4", "1.14.2 Pre-Release 3", "1.14.2 Pre-Release 2", "1.14.2 Pre-Release 1", "1.14.1",
"1.14.1 Pre-Release 2", "1.14.1 Pre-Release 1", "1.14", "1.14 Pre-Release 5", "1.14 Pre-Release 4", "1.14 Pre-Release 3", "1.14 Pre-Release 2", "1.14 Pre-Release 1",
"19w14b", "19w14a", "3D Shareware v1.34", "19w13b", "19w13a", "19w12b", "19w12a", "19w11b"]
HASH_FOLDER = os.path.abspath("data/hash/") + "/"
ASSETS_HASH_INDEX_FILE = os.path.abspath("data/index")
OUT_FOLDER = os.path.abspath("data/version/") + "/"
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/graalvm-ce-java11-21.0.0.2/bin/java"
JAVA_PATH = "/usr/lib/jvm/graalvm-ce-java8-21.0.0.2//bin/java"
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"
COMPILE_VERSION = "21w08a"
COMPILE_VERSION = "19w35a"
failedVersionIds = []
partlyFailedVersionIds = []
print("Starting PixLyzer generator")
print("Starting PixLyzer-yarn generator")
print("Downloading version manifest")
VERSION_MANIFEST = ujson.loads(urllib.request.urlopen(VERSION_MANIFEST_URL).read().decode("utf-8"))
@ -38,13 +40,6 @@ def searchVersion(versionId):
raise Exception("Unknown version: %s" % versionId)
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):
process = subprocess.Popen(command, cwd=r'../', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
exitCode = process.wait()
@ -58,7 +53,7 @@ def getVersionJson(versionEntry):
# check cache
global DATA_FOLDER
versionId = versionEntry["id"]
path = DATA_FOLDER + versionId + "/" + versionId + ".json"
path = DATA_FOLDER + versionId + "_yarn/" + versionId + ".json"
if not os.path.isfile(path):
# download
print("Debug: Downloading %s.json" % versionEntry["id"])
@ -68,60 +63,28 @@ def getVersionJson(versionEntry):
return ujson.load(open(path))
def checkDeobfuscatedJar(jarBasePath, jarType, version, versionJson):
jarPath = jarBasePath + jarType + ".jar"
def checkServerJar(jarBasePath, version, versionJson):
jarPath = jarBasePath + ".jar"
if not os.path.isfile(jarPath):
mojangJarPath = jarBasePath + jarType + "_mojang.jar"
mojangJarPath = jarBasePath + "_server_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 + ".tmp")
print("Downloading mojang server jar for %s" % (version["id"]))
urllib.request.urlretrieve(versionJson["downloads"]["server"]["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 + ".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 + ".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"]))
print()
print(deobfuscateProcess.stdout.read().decode('utf-8'))
print(deobfuscateProcess.stderr.read().decode('utf-8'))
exit(5)
else:
# delete mojang jars
print("Deleting META-INF folder")
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"):
zipOut.writestr(item, buffer)
zipOut.close()
zipIn.close()
os.remove(jarPath + ".tmp")
os.rename(jarPath + ".tmp2", jarPath)
print("Deleting %s jar and mappings for %s" % (jarType, version["id"]))
os.remove(mojangJarPath)
os.remove(mojangMappingsPath)
def checkDeobfuscatedClientJar(jarBasePath, version, versionJson):
yarnJarPath = jarBasePath + "-named.jar"
if not os.path.isfile(yarnJarPath):
raise Exception("Yarn jar does not exist for %s. You must generate it first!" % version["id"])
def checkDeobfuscatedJars(version, versionJson):
def checkJars(version, versionJson):
global DATA_FOLDER
jarBasePath = DATA_FOLDER + version["id"] + "/" + version["id"] + "_"
checkDeobfuscatedJar(jarBasePath, "client", version, versionJson)
checkDeobfuscatedJar(jarBasePath, "server", version, versionJson)
jarBasePath = DATA_FOLDER + version["id"] + "_yarn/" + version["id"]
checkDeobfuscatedClientJar(jarBasePath, version, versionJson)
checkServerJar(jarBasePath, version, versionJson)
def replaceInFile(file, search, replace):
@ -139,7 +102,7 @@ def compilePixLyzer():
for versionEntry in searched:
compileVersion[versionEntry] = searched[versionEntry]
checkDeobfuscatedJars(compileVersion, getVersionJson(compileVersion))
checkJars(compileVersion, getVersionJson(compileVersion))
if runAndWait('mvn clean verify') != 0:
raise Exception("Can not compile PixLyzer")
print("PixLyzer is now compiled")
@ -147,31 +110,18 @@ def compilePixLyzer():
compilePixLyzer()
startWorking = False
for version in VERSION_MANIFEST["versions"]:
if version["id"] == startWithVersion:
startWorking = True
if not startWorking:
if version["id"] not in VERSIONS_DO_GENERATE:
continue
if version["id"] in SKIP_VERSIONS:
print("Skipping %s" % version["id"])
continue
if version["id"] == DOWNLOAD_UNTIL_VERSION:
print("Breaking at %s" % version["id"])
break
versionJson = getVersionJson(version)
checkDeobfuscatedJars(version, versionJson)
checkJars(version, versionJson)
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:
if runAndWait("%s -classpath \"%s:%s:%s:%s\" de.bixilon.pixlyzer.PixLyzer \"%s\" \"%s\" \"%s\"" % (JAVA_PATH, ADDITIONAL_CLASSPATH, DATA_FOLDER + version["id"] + "_yarn/" + version["id"] + "-named.jar", DATA_FOLDER + version["id"] + "_yarn/" + version["id"] + "_server_mojang.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