mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-15 18:34:56 -04:00
registry: use reflections to set parent
This commit is contained in:
parent
32c1b4eb8a
commit
41b32fb466
@ -26,7 +26,6 @@ import de.bixilon.minosoft.data.inventory.ItemNBTValues.UNBREAKABLE_TAG
|
||||
import de.bixilon.minosoft.data.mappings.Enchantment
|
||||
import de.bixilon.minosoft.data.mappings.items.Item
|
||||
import de.bixilon.minosoft.data.mappings.versions.Version
|
||||
import de.bixilon.minosoft.data.mappings.versions.VersionMapping
|
||||
import de.bixilon.minosoft.data.text.ChatComponent
|
||||
import de.bixilon.minosoft.util.BitByte
|
||||
import de.bixilon.minosoft.util.nbt.tag.*
|
||||
@ -110,7 +109,7 @@ class ItemStack(
|
||||
additionalNBT = nbt
|
||||
}
|
||||
|
||||
fun getNbt(mapping: VersionMapping): CompoundTag {
|
||||
fun getNBT(): CompoundTag {
|
||||
val nbt = additionalNBT?.clone() ?: CompoundTag()
|
||||
if (repairCost != 0) {
|
||||
nbt.writeTag(REPAIR_COST_TAG, IntTag(repairCost))
|
||||
@ -147,13 +146,13 @@ class ItemStack(
|
||||
val enchantmentTag = CompoundTag()
|
||||
enchantmentTag.writeTag(ENCHANTMENT_ID_TAG, StringTag(id.toString()))
|
||||
|
||||
enchantmentTag.writeTag(ENCHANTMENT_LEVEL_TAG, if (mapping.version!!.isFlattened()) {
|
||||
enchantmentTag.writeTag(ENCHANTMENT_LEVEL_TAG, if (version!!.isFlattened()) {
|
||||
IntTag(level)
|
||||
} else {
|
||||
ShortTag(level.toShort())
|
||||
})
|
||||
}
|
||||
if (mapping.version!!.isFlattened()) {
|
||||
if (version!!.isFlattened()) {
|
||||
nbt.writeTag(ENCHANTMENT_FLATTENING_TAG, enchantmentList)
|
||||
} else {
|
||||
nbt.writeTag(ENCHANTMENT_PRE_FLATTENING_TAG, enchantmentList)
|
||||
|
@ -24,7 +24,7 @@ class EnumRegistry<T : Enum<*>>(
|
||||
private var parentRegistry: EnumRegistry<T>? = null,
|
||||
var values: ValuesEnum<T>,
|
||||
private val mutable: Boolean = true,
|
||||
) : Clearable {
|
||||
) : Clearable, Parentable<EnumRegistry<T>> {
|
||||
private var initialized = false
|
||||
private val idValueMap: MutableMap<Int, T> = mutableMapOf()
|
||||
private val valueIdMap: MutableMap<T, Int> = mutableMapOf()
|
||||
@ -37,11 +37,11 @@ class EnumRegistry<T : Enum<*>>(
|
||||
return valueIdMap[value] ?: parentRegistry?.getId(value)!!
|
||||
}
|
||||
|
||||
fun setParent(registry: EnumRegistry<T>?) {
|
||||
override fun setParent(parent: EnumRegistry<T>?) {
|
||||
if (!mutable) {
|
||||
throw IllegalStateException("Registry is immutable!")
|
||||
}
|
||||
this.parentRegistry = registry
|
||||
this.parentRegistry = parent
|
||||
}
|
||||
|
||||
private fun getEnum(data: Any): T {
|
||||
|
@ -19,7 +19,7 @@ import de.bixilon.minosoft.util.collections.Clearable
|
||||
|
||||
class FakeEnumRegistry<T : RegistryFakeEnumerable>(
|
||||
private var parentRegistry: FakeEnumRegistry<T>? = null,
|
||||
) : Clearable {
|
||||
) : Clearable, Parentable<FakeEnumRegistry<T>> {
|
||||
private var initialized = false
|
||||
private val idValueMap: MutableMap<Int, T> = mutableMapOf()
|
||||
private val valueIdMap: MutableMap<T, Int> = mutableMapOf()
|
||||
@ -37,9 +37,9 @@ class FakeEnumRegistry<T : RegistryFakeEnumerable>(
|
||||
return valueIdMap[value] ?: parentRegistry?.getId(value)!!
|
||||
}
|
||||
|
||||
fun setParent(registry: FakeEnumRegistry<T>?) {
|
||||
check(registry !== this) { "Can not set our self as parent!" }
|
||||
this.parentRegistry = registry
|
||||
override fun setParent(parent: FakeEnumRegistry<T>?) {
|
||||
check(parent !== this) { "Can not set our self as parent!" }
|
||||
this.parentRegistry = parent
|
||||
}
|
||||
|
||||
fun initialize(data: JsonObject?, mappings: VersionMapping, deserializer: IdDeserializer<T>): FakeEnumRegistry<T> {
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.data.mappings.registry
|
||||
|
||||
interface Parentable<T> {
|
||||
|
||||
fun setParent(parent: T?)
|
||||
}
|
@ -21,7 +21,7 @@ import de.bixilon.minosoft.util.json.ResourceLocationJsonMap.toResourceLocationM
|
||||
|
||||
open class Registry<T : RegistryItem>(
|
||||
private var parentRegistry: Registry<T>? = null,
|
||||
) : Iterable<T>, Clearable {
|
||||
) : Iterable<T>, Clearable, Parentable<Registry<T>> {
|
||||
private var initialized = false
|
||||
private val idValueMap: MutableMap<Int, T> = mutableMapOf()
|
||||
private val valueIdMap: MutableMap<T, Int> = mutableMapOf()
|
||||
@ -40,8 +40,8 @@ open class Registry<T : RegistryItem>(
|
||||
return valueIdMap[value] ?: parentRegistry?.getId(value)!!
|
||||
}
|
||||
|
||||
fun setParent(registry: Registry<T>?) {
|
||||
this.parentRegistry = registry
|
||||
override fun setParent(parent: Registry<T>?) {
|
||||
this.parentRegistry = parent
|
||||
}
|
||||
|
||||
open fun initialize(data: Map<ResourceLocation, JsonObject>?, mappings: VersionMapping?, deserializer: ResourceLocationDeserializer<T>, flattened: Boolean = true, metaType: MetaTypes = MetaTypes.NONE): Registry<T> {
|
||||
|
@ -36,7 +36,7 @@ data class Version(
|
||||
) {
|
||||
var isLoaded = false
|
||||
var isGettingLoaded = false
|
||||
val mapping: VersionMapping = VersionMapping(this)
|
||||
val mapping: VersionMapping = VersionMapping()
|
||||
lateinit var assetsManager: MinecraftAssetsManager
|
||||
lateinit var localeManager: MinecraftLocaleManager
|
||||
|
||||
@ -110,8 +110,7 @@ data class Version(
|
||||
JsonObject()
|
||||
}
|
||||
latch.addCount(1)
|
||||
mapping.version = this
|
||||
mapping.load(pixlyzerData)
|
||||
mapping.load(this, pixlyzerData)
|
||||
latch.countDown()
|
||||
if (pixlyzerData.size() > 0) {
|
||||
Log.verbose(String.format("Loaded mappings for version %s in %dms (%s)", this, (System.currentTimeMillis() - startTime), versionName))
|
||||
|
@ -31,10 +31,7 @@ import de.bixilon.minosoft.data.mappings.items.Item
|
||||
import de.bixilon.minosoft.data.mappings.items.ItemRegistry
|
||||
import de.bixilon.minosoft.data.mappings.materials.Material
|
||||
import de.bixilon.minosoft.data.mappings.particle.Particle
|
||||
import de.bixilon.minosoft.data.mappings.registry.EnumRegistry
|
||||
import de.bixilon.minosoft.data.mappings.registry.FakeEnumRegistry
|
||||
import de.bixilon.minosoft.data.mappings.registry.PerEnumVersionRegistry
|
||||
import de.bixilon.minosoft.data.mappings.registry.Registry
|
||||
import de.bixilon.minosoft.data.mappings.registry.*
|
||||
import de.bixilon.minosoft.data.mappings.statistics.Statistic
|
||||
import de.bixilon.minosoft.gui.rendering.chunk.VoxelShape
|
||||
import de.bixilon.minosoft.gui.rendering.chunk.models.AABB
|
||||
@ -43,10 +40,11 @@ import de.bixilon.minosoft.protocol.packets.clientbound.play.title.TitlePacketFa
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.collections.Clearable
|
||||
import de.bixilon.minosoft.util.json.ResourceLocationJsonMap.toResourceLocationMap
|
||||
import java.lang.reflect.Field
|
||||
import java.util.*
|
||||
|
||||
|
||||
class VersionMapping(var version: Version?) {
|
||||
class VersionMapping {
|
||||
var shapes: MutableList<VoxelShape> = mutableListOf()
|
||||
val motiveRegistry: Registry<Motive> = Registry()
|
||||
val blockRegistry: Registry<Block> = Registry()
|
||||
@ -94,32 +92,9 @@ class VersionMapping(var version: Version?) {
|
||||
set(value) {
|
||||
_parentMapping = value
|
||||
|
||||
// ToDo: Use reflections for this
|
||||
|
||||
motiveRegistry.setParent(value?.motiveRegistry)
|
||||
itemRegistry.setParent(value?.itemRegistry)
|
||||
enchantmentRegistry.setParent(value?.enchantmentRegistry)
|
||||
particleRegistry.setParent(value?.particleRegistry)
|
||||
statusEffectRegistry.setParent(value?.statusEffectRegistry)
|
||||
blockRegistry.setParent(value?.blockRegistry)
|
||||
statisticRegistry.setParent(value?.statisticRegistry)
|
||||
biomeRegistry.setParent(value?.biomeRegistry)
|
||||
dimensionRegistry.setParent(value?.dimensionRegistry)
|
||||
biomePrecipitationRegistry.setParent(value?.biomePrecipitationRegistry)
|
||||
biomeCategoryRegistry.setParent(value?.biomeCategoryRegistry)
|
||||
materialRegistry.setParent(value?.materialRegistry)
|
||||
villagerProfessionRegistry.setParent(value?.villagerProfessionRegistry)
|
||||
|
||||
equipmentSlotRegistry.setParent(value?.equipmentSlotRegistry)
|
||||
handEquipmentSlotRegistry.setParent(value?.handEquipmentSlotRegistry)
|
||||
armorEquipmentSlotRegistry.setParent(value?.armorEquipmentSlotRegistry)
|
||||
armorStandEquipmentSlotRegistry.setParent(value?.armorStandEquipmentSlotRegistry)
|
||||
entityMetaDataDataDataTypesRegistry.setParent(value?.entityMetaDataDataDataTypesRegistry)
|
||||
creativeModeTabRegistry.setParent(value?.creativeModeTabRegistry)
|
||||
|
||||
titleActionsRegistry.setParent(value?.titleActionsRegistry)
|
||||
|
||||
entityRegistry.setParent(value?.entityRegistry)
|
||||
for (field in PARENTABLE_FIELDS) {
|
||||
PARENTABLE_SET_PARENT_METHOD.invoke(field.get(this), value?.let { field.get(it) })
|
||||
}
|
||||
}
|
||||
|
||||
fun getBlockState(blockState: Int): BlockState? {
|
||||
@ -133,30 +108,29 @@ class VersionMapping(var version: Version?) {
|
||||
return entityMetaIndexMap[field] ?: _parentMapping?.getEntityMetaDataIndex(field)
|
||||
}
|
||||
|
||||
private fun <T : Enum<*>> loadEnumRegistry(data: JsonElement?, registry: EnumRegistry<T>, alternative: PerEnumVersionRegistry<T>) {
|
||||
private fun <T : Enum<*>> loadEnumRegistry(version: Version, data: JsonElement?, registry: EnumRegistry<T>, alternative: PerEnumVersionRegistry<T>) {
|
||||
data?.let {
|
||||
registry.initialize(it)
|
||||
} ?: let {
|
||||
registry.setParent(alternative.forVersion(version!!))
|
||||
registry.setParent(alternative.forVersion(version))
|
||||
}
|
||||
}
|
||||
|
||||
fun load(pixlyzerData: JsonObject) {
|
||||
val version = version!!
|
||||
fun load(version: Version, pixlyzerData: JsonObject) {
|
||||
// pre init stuff
|
||||
loadShapes(pixlyzerData["shapes"]?.asJsonObject)
|
||||
|
||||
loadBlockModels(pixlyzerData["models"].asJsonObject.toResourceLocationMap())
|
||||
|
||||
// enums
|
||||
loadEnumRegistry(pixlyzerData["equipment_slots"], equipmentSlotRegistry, DefaultRegistries.EQUIPMENT_SLOTS_REGISTRY)
|
||||
loadEnumRegistry(pixlyzerData["hand_equipment_slots"], handEquipmentSlotRegistry, DefaultRegistries.HAND_EQUIPMENT_SLOTS_REGISTRY)
|
||||
loadEnumRegistry(pixlyzerData["armor_equipment_slots"], armorEquipmentSlotRegistry, DefaultRegistries.ARMOR_EQUIPMENT_SLOTS_REGISTRY)
|
||||
loadEnumRegistry(pixlyzerData["armor_stand_equipment_slots"], armorStandEquipmentSlotRegistry, DefaultRegistries.ARMOR_STAND_EQUIPMENT_SLOTS_REGISTRY)
|
||||
loadEnumRegistry(version, pixlyzerData["equipment_slots"], equipmentSlotRegistry, DefaultRegistries.EQUIPMENT_SLOTS_REGISTRY)
|
||||
loadEnumRegistry(version, pixlyzerData["hand_equipment_slots"], handEquipmentSlotRegistry, DefaultRegistries.HAND_EQUIPMENT_SLOTS_REGISTRY)
|
||||
loadEnumRegistry(version, pixlyzerData["armor_equipment_slots"], armorEquipmentSlotRegistry, DefaultRegistries.ARMOR_EQUIPMENT_SLOTS_REGISTRY)
|
||||
loadEnumRegistry(version, pixlyzerData["armor_stand_equipment_slots"], armorStandEquipmentSlotRegistry, DefaultRegistries.ARMOR_STAND_EQUIPMENT_SLOTS_REGISTRY)
|
||||
|
||||
loadEnumRegistry(pixlyzerData["entity_meta_data_data_types"], entityMetaDataDataDataTypesRegistry, DefaultRegistries.ENTITY_META_DATA_DATA_TYPES_REGISTRY)
|
||||
loadEnumRegistry(version, pixlyzerData["entity_meta_data_data_types"], entityMetaDataDataDataTypesRegistry, DefaultRegistries.ENTITY_META_DATA_DATA_TYPES_REGISTRY)
|
||||
|
||||
loadEnumRegistry(pixlyzerData["title_actions"], titleActionsRegistry, DefaultRegistries.TITLE_ACTIONS_REGISTRY)
|
||||
loadEnumRegistry(version, pixlyzerData["title_actions"], titleActionsRegistry, DefaultRegistries.TITLE_ACTIONS_REGISTRY)
|
||||
|
||||
// id stuff
|
||||
biomeCategoryRegistry.initialize(pixlyzerData["biome_categories"]?.asJsonObject, this, BiomeCategory)
|
||||
@ -242,4 +216,22 @@ class VersionMapping(var version: Version?) {
|
||||
field.javaClass.getMethod("clear").invoke(this)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val PARENTABLE_FIELDS: List<Field>
|
||||
private val PARENTABLE_SET_PARENT_METHOD = Parentable::class.java.getDeclaredMethod("setParent", Any::class.java)
|
||||
|
||||
init {
|
||||
val fields: MutableList<Field> = mutableListOf()
|
||||
|
||||
for (field in VersionMapping::class.java.declaredFields) {
|
||||
if (!Parentable::class.java.isAssignableFrom(field.type)) {
|
||||
continue
|
||||
}
|
||||
fields.add(field)
|
||||
}
|
||||
|
||||
PARENTABLE_FIELDS = fields.toList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ public class Connection {
|
||||
private int desiredVersionNumber = -1;
|
||||
private ServerAddress address;
|
||||
private Version version = Versions.LOWEST_VERSION_SUPPORTED; // default
|
||||
private final VersionMapping customMapping = new VersionMapping(this.version);
|
||||
private final VersionMapping customMapping = new VersionMapping();
|
||||
private ConnectionStates state = ConnectionStates.DISCONNECTED;
|
||||
private ConnectionReasons reason;
|
||||
private ConnectionReasons nextReason;
|
||||
@ -144,7 +144,6 @@ public class Connection {
|
||||
setVersion(version);
|
||||
try {
|
||||
version.load(latch); // ToDo: show gui loader
|
||||
this.customMapping.setVersion(version);
|
||||
this.customMapping.setParentMapping(version.getMapping());
|
||||
this.player = new Player(this.account, this);
|
||||
|
||||
@ -159,10 +158,6 @@ public class Connection {
|
||||
} catch (Throwable exception) {
|
||||
Log.printException(exception, LogLevels.DEBUG);
|
||||
Log.fatal(String.format("Could not load version %s. This version seems to be unsupported!", version));
|
||||
if (this.customMapping.getVersion() != null) {
|
||||
this.customMapping.getVersion().getMapping().setParentMapping(null);
|
||||
}
|
||||
this.customMapping.setVersion(null);
|
||||
version.unload();
|
||||
this.lastException = new MappingsLoadingException("Mappings could not be loaded", exception);
|
||||
setConnectionState(ConnectionStates.FAILED_NO_RETRY);
|
||||
|
@ -190,7 +190,7 @@ public class OutByteBuffer {
|
||||
writeShort((short) this.connection.getMapping().getItemRegistry().getId(itemStack.getItem()));
|
||||
writeByte((byte) itemStack.getItemCount());
|
||||
writeShort((short) itemStack.getItemMetadata());
|
||||
writeNBT(itemStack.getNbt(this.connection.getMapping()));
|
||||
writeNBT(itemStack.getNBT());
|
||||
}
|
||||
if (itemStack == null) {
|
||||
writeBoolean(false);
|
||||
@ -198,7 +198,7 @@ public class OutByteBuffer {
|
||||
}
|
||||
writeVarInt(this.connection.getMapping().getItemRegistry().getId(itemStack.getItem()));
|
||||
writeByte((byte) itemStack.getItemCount());
|
||||
writeNBT(itemStack.getNbt(this.connection.getMapping()));
|
||||
writeNBT(itemStack.getNBT());
|
||||
}
|
||||
|
||||
void writeNBT(CompoundTag nbt) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user