From e929d80cae71740e9db076f6916a7060a79155f2 Mon Sep 17 00:00:00 2001 From: Bixilon Date: Sun, 12 Dec 2021 14:13:50 +0100 Subject: [PATCH] wip assets manager (2) --- src/main/java/de/bixilon/minosoft/Minosoft.kt | 5 +- .../bixilon/minosoft/assets/AssetsLoader.kt | 31 ++++ .../DirectoryAssetsManager.kt | 42 ++++- .../assets/file/ResourcesAssetsUtil.kt | 1 + .../assets/minecraft/JarAssetsManager.kt | 9 +- .../minecraft/index/IndexAssetsManager.kt | 30 +++- .../assets/minecraft/index/IndexAssetsType.kt | 9 ++ .../assets/multi/PriorityAssetsManager.kt | 3 + .../version/AssetsVersionProperties.kt | 2 +- .../minosoft/assets/util/FileAssetsUtil.kt | 44 +++--- .../bixilon/minosoft/assets/util/FileUtil.kt | 6 + .../profile/profiles/eros/general/GeneralC.kt | 4 +- .../profiles/eros/server/entries/Server.kt | 2 +- .../profiles/resources/ResourcesProfile.kt | 2 + .../profiles/resources/assets/AssetsC.kt | 15 ++ .../resources/assets/packs/ResourcePack.kt | 6 + .../assets/packs/ResourcePackType.kt | 11 ++ .../parser/minosoft/VersionParser.java | 2 +- .../minosoft/data/inventory/ItemStack.kt | 6 +- .../minosoft/data/language/LanguageManager.kt | 12 +- .../registries/RegistriesLoadingException.kt | 21 --- .../data/registries/registries/Registries.kt | 10 +- .../registries/registries/RegistriesLoader.kt | 49 ++++++ .../data/registries/versions/Version.kt | 148 +++--------------- .../data/registries/versions/VersionTypes.kt | 2 +- .../data/registries/versions/Versions.java | 112 ------------- .../data/registries/versions/Versions.kt | 104 ++++++++++++ .../gui/eros/crash/ErosCrashReport.kt | 2 +- .../gui/eros/dialog/ServerModifyDialog.kt | 14 +- .../gui/rendering/world/WorldRenderer.kt | 2 +- .../network/connection/play/PlayConnection.kt | 41 ++--- .../clientsettings/ClientSettingsManager.kt | 2 +- .../connection/status/StatusConnection.kt | 2 +- .../packets/c2s/play/ClientSettingsC2SP.kt | 16 +- .../s2c/status/ServerStatusResponseS2CP.kt | 2 +- .../minosoft/protocol/protocol/PacketTypes.kt | 12 +- .../protocol/protocol/PlayInByteBuffer.kt | 2 +- .../bixilon/minosoft/terminal/AutoConnect.kt | 4 +- .../java/de/bixilon/minosoft/util/KUtil.kt | 2 +- .../bixilon/minosoft/util/ShutdownManager.kt | 2 +- .../java/de/bixilon/minosoft/util/Util.java | 7 +- .../bixilon/minosoft/util/enum/ValuesEnum.kt | 2 +- 42 files changed, 433 insertions(+), 367 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/assets/AssetsLoader.kt rename src/main/java/de/bixilon/minosoft/assets/{file => directory}/DirectoryAssetsManager.kt (53%) create mode 100644 src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/assets/AssetsC.kt create mode 100644 src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/assets/packs/ResourcePack.kt create mode 100644 src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/assets/packs/ResourcePackType.kt delete mode 100644 src/main/java/de/bixilon/minosoft/data/registries/RegistriesLoadingException.kt create mode 100644 src/main/java/de/bixilon/minosoft/data/registries/registries/RegistriesLoader.kt delete mode 100644 src/main/java/de/bixilon/minosoft/data/registries/versions/Versions.java create mode 100644 src/main/java/de/bixilon/minosoft/data/registries/versions/Versions.kt diff --git a/src/main/java/de/bixilon/minosoft/Minosoft.kt b/src/main/java/de/bixilon/minosoft/Minosoft.kt index c09951997..f960fce3f 100644 --- a/src/main/java/de/bixilon/minosoft/Minosoft.kt +++ b/src/main/java/de/bixilon/minosoft/Minosoft.kt @@ -22,6 +22,7 @@ import de.bixilon.minosoft.data.language.LanguageManager.Companion.load import de.bixilon.minosoft.data.language.MultiLanguageManager import de.bixilon.minosoft.data.registries.DefaultRegistries import de.bixilon.minosoft.data.registries.ResourceLocation +import de.bixilon.minosoft.data.registries.versions.Versions import de.bixilon.minosoft.gui.eros.Eros import de.bixilon.minosoft.gui.eros.XStartOnFirstThreadWarning import de.bixilon.minosoft.gui.eros.crash.ErosCrashReport.Companion.crash @@ -69,7 +70,7 @@ object Minosoft { taskWorker += Task(identifier = StartupTasks.LOAD_VERSIONS, priority = ThreadPool.HIGH, executor = { Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Loading versions..." } - // Versions.loadAvailableVersions(MINOSOFT_ASSETS_MANAGER.readLegacyJsonAsset(ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "mapping/versions.json"))) + Versions.load() Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Versions loaded!" } }) @@ -90,7 +91,7 @@ object Minosoft { val language = ErosProfileManager.selected.general.language ErosProfileManager.selected.general::language.profileWatch(this, true) { Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Loading language files (${language})" } - LANGUAGE_MANAGER.translators[ProtocolDefinition.MINOSOFT_NAMESPACE] = load(it, null, ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "language/")) + LANGUAGE_MANAGER.translators[ProtocolDefinition.MINOSOFT_NAMESPACE] = load(it, null, MINOSOFT_ASSETS_MANAGER, ResourceLocation(ProtocolDefinition.MINOSOFT_NAMESPACE, "language/")) Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Language files loaded!" } } }) diff --git a/src/main/java/de/bixilon/minosoft/assets/AssetsLoader.kt b/src/main/java/de/bixilon/minosoft/assets/AssetsLoader.kt new file mode 100644 index 000000000..ac328402c --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/assets/AssetsLoader.kt @@ -0,0 +1,31 @@ +package de.bixilon.minosoft.assets + +import de.bixilon.minosoft.Minosoft +import de.bixilon.minosoft.assets.minecraft.JarAssetsManager +import de.bixilon.minosoft.assets.minecraft.index.IndexAssetsManager +import de.bixilon.minosoft.assets.multi.PriorityAssetsManager +import de.bixilon.minosoft.assets.properties.version.AssetsVersionProperties +import de.bixilon.minosoft.assets.properties.version.AssetsVersionProperty +import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfile +import de.bixilon.minosoft.data.registries.versions.Version + +object AssetsLoader { + + fun create(profile: ResourcesProfile, version: Version, property: AssetsVersionProperty = AssetsVersionProperties[version] ?: throw IllegalAccessException("$version has no assets!")): AssetsManager { + val assetsManager = PriorityAssetsManager() + + for (resourcePack in profile.assets.resourcePacks) { + assetsManager += resourcePack.type.creator(resourcePack) + } + + if (!profile.assets.disableIndexAssets) { + assetsManager += IndexAssetsManager(profile, property.indexVersion, property.indexHash, profile.assets.indexAssetsTypes.toSet()) + } + if (!profile.assets.disableJarAssets) { + assetsManager += JarAssetsManager(property.jarAssetsHash, property.clientJarHash, profile, version) + } + assetsManager += Minosoft.MINOSOFT_ASSETS_MANAGER + + return assetsManager + } +} diff --git a/src/main/java/de/bixilon/minosoft/assets/file/DirectoryAssetsManager.kt b/src/main/java/de/bixilon/minosoft/assets/directory/DirectoryAssetsManager.kt similarity index 53% rename from src/main/java/de/bixilon/minosoft/assets/file/DirectoryAssetsManager.kt rename to src/main/java/de/bixilon/minosoft/assets/directory/DirectoryAssetsManager.kt index 050d73350..220a5bb58 100644 --- a/src/main/java/de/bixilon/minosoft/assets/file/DirectoryAssetsManager.kt +++ b/src/main/java/de/bixilon/minosoft/assets/directory/DirectoryAssetsManager.kt @@ -11,11 +11,15 @@ * This software is not affiliated with Mojang AB, the original developer of Minecraft. */ -package de.bixilon.minosoft.assets.file +package de.bixilon.minosoft.assets.directory +import de.bixilon.minosoft.assets.AssetsManager +import de.bixilon.minosoft.assets.util.FileAssetsUtil.toAssetName import de.bixilon.minosoft.assets.util.FileUtil import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.util.CountUpAndDownLatch +import java.io.File +import java.io.FileNotFoundException import java.io.InputStream @@ -25,18 +29,50 @@ import java.io.InputStream class DirectoryAssetsManager( private val basePath: String, -) : FileAssetsManager() { +) : AssetsManager { + override val namespaces: MutableSet = mutableSetOf() + private var assets: MutableSet = mutableSetOf() private val ResourceLocation.filePath: String get() = "$basePath/$namespace/$path" - override fun load(latch: CountUpAndDownLatch) = Unit + // ToDo: Load properties + + private fun scanDirectory(directory: File) { + for (file in directory.listFiles() ?: return) { + if (file.isDirectory) { + scanDirectory(file) + continue + } + val path = file.path.removePrefix(basePath).removePrefix("/").toAssetName(false) ?: continue + assets += path + namespaces += path.namespace + } + } + + override fun load(latch: CountUpAndDownLatch) { + scanDirectory(File(basePath)) + } + + override fun unload() { + assets.clear() + } + + override fun iterator(): Iterator> { + TODO("Not yet implemented") + } override fun get(path: ResourceLocation): InputStream { + if (path !in assets) { + throw FileNotFoundException("Can not find asset $path") + } return FileUtil.readFile(path.filePath, false) } override fun nullGet(path: ResourceLocation): InputStream? { + if (path !in assets) { + return null + } return FileUtil.saveReadFile(path.filePath, false) } } diff --git a/src/main/java/de/bixilon/minosoft/assets/file/ResourcesAssetsUtil.kt b/src/main/java/de/bixilon/minosoft/assets/file/ResourcesAssetsUtil.kt index 076f3f4e9..a090ebb7b 100644 --- a/src/main/java/de/bixilon/minosoft/assets/file/ResourcesAssetsUtil.kt +++ b/src/main/java/de/bixilon/minosoft/assets/file/ResourcesAssetsUtil.kt @@ -1,6 +1,7 @@ package de.bixilon.minosoft.assets.file import de.bixilon.minosoft.assets.AssetsManager +import de.bixilon.minosoft.assets.directory.DirectoryAssetsManager import java.io.FileNotFoundException import java.net.URLDecoder import java.nio.charset.StandardCharsets diff --git a/src/main/java/de/bixilon/minosoft/assets/minecraft/JarAssetsManager.kt b/src/main/java/de/bixilon/minosoft/assets/minecraft/JarAssetsManager.kt index 637dfb365..e0599129a 100644 --- a/src/main/java/de/bixilon/minosoft/assets/minecraft/JarAssetsManager.kt +++ b/src/main/java/de/bixilon/minosoft/assets/minecraft/JarAssetsManager.kt @@ -41,12 +41,15 @@ class JarAssetsManager( val version: Version, ) : MinecraftAssetsManager { override val namespaces = setOf(ProtocolDefinition.DEFAULT_NAMESPACE) - private var jarAssets: Map = mapOf() + private var jarAssets: MutableMap = mutableMapOf() override fun load(latch: CountUpAndDownLatch) { val jarAssetFile = File(FileAssetsUtil.getPath(jarAssetsHash)) if (FileAssetsUtil.verifyAsset(jarAssetsHash, jarAssetFile, profile.verify)) { - jarAssets = FileUtil.readFile(jarAssetFile).readArchive() + val jarAssets = FileUtil.readFile(jarAssetFile).readArchive() + for ((path, data) in jarAssets) { + this.jarAssets[path.removePrefix("assets/" + ProtocolDefinition.DEFAULT_NAMESPACE + "/")] = data + } } else { var clientJar = FileUtil.saveReadFile(File(FileAssetsUtil.getPath(clientJarHash)), false)?.readZipArchive() if (clientJar == null) { @@ -112,7 +115,7 @@ class JarAssetsManager( } override fun unload() { - jarAssets = mapOf() + jarAssets = mutableMapOf() } override fun iterator(): Iterator> { diff --git a/src/main/java/de/bixilon/minosoft/assets/minecraft/index/IndexAssetsManager.kt b/src/main/java/de/bixilon/minosoft/assets/minecraft/index/IndexAssetsManager.kt index 1c312d6e8..92d7e0981 100644 --- a/src/main/java/de/bixilon/minosoft/assets/minecraft/index/IndexAssetsManager.kt +++ b/src/main/java/de/bixilon/minosoft/assets/minecraft/index/IndexAssetsManager.kt @@ -20,11 +20,15 @@ import de.bixilon.minosoft.assets.util.FileUtil import de.bixilon.minosoft.assets.util.FileUtil.readJsonObject import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfile import de.bixilon.minosoft.data.registries.ResourceLocation +import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.util.CountUpAndDownLatch import de.bixilon.minosoft.util.KUtil.synchronizedMapOf import de.bixilon.minosoft.util.KUtil.toLong import de.bixilon.minosoft.util.Util import de.bixilon.minosoft.util.json.Jackson +import de.bixilon.minosoft.util.logging.Log +import de.bixilon.minosoft.util.logging.LogLevels +import de.bixilon.minosoft.util.logging.LogMessageType import de.bixilon.minosoft.util.nbt.tag.NBTUtil.asCompound import de.bixilon.minosoft.util.task.pool.DefaultThreadPool import de.bixilon.minosoft.util.task.pool.ThreadPool @@ -39,13 +43,13 @@ import java.io.InputStream */ class IndexAssetsManager( private val profile: ResourcesProfile, - private val verify: Boolean, private val assetsVersion: String, private val indexHash: String, private val types: Set, ) : MinecraftAssetsManager { + private val verify: Boolean = profile.verify private val assets: MutableMap = synchronizedMapOf() - override val namespaces: MutableSet = mutableSetOf() + override val namespaces: Set = setOf(ProtocolDefinition.DEFAULT_NAMESPACE) private fun downloadAssetsIndex(): Map { return Jackson.MAPPER.readValue(FileAssetsUtil.downloadAndGetAsset(Util.formatString(profile.source.mojangPackages, @@ -65,6 +69,7 @@ class IndexAssetsManager( "hashPrefix" to hash.substring(0, 2), "fullHash" to hash, )) + Log.log(LogMessageType.ASSETS, LogLevels.VERBOSE) { "Downloading asset $url" } val downloadedHash = FileAssetsUtil.downloadAsset(url) if (downloadedHash != hash) { throw IOException("Verification of asset $hash failed!") @@ -73,23 +78,34 @@ class IndexAssetsManager( override fun load(latch: CountUpAndDownLatch) { var assets = FileUtil.saveReadFile(FileAssetsUtil.getPath(indexHash))?.readJsonObject() ?: downloadAssetsIndex() + + assets["objects"].let { assets = it.asCompound() } + val tasks = CountUpAndDownLatch(0) val assetsLatch = CountUpAndDownLatch(assets.size, parent = latch) - val tasks = CountUpAndDownLatch(0) - assets["objects"].let { assets = it.asCompound() } for ((path, data) in assets) { check(data is Map<*, *>) - val name = path.toAssetName() ?: continue + val name = path.toAssetName(false) + if (name == null) { + assetsLatch.dec() + continue + } + val type = when { name.path.startsWith("lang/") -> IndexAssetsType.LANGUAGE name.path.startsWith("sounds/") -> IndexAssetsType.SOUNDS + name.path == "sounds.json" -> IndexAssetsType.SOUNDS name.path.startsWith("textures/") -> IndexAssetsType.TEXTURES - else -> continue + else -> { + assetsLatch.dec() + continue + } } if (type !in this.types) { + assetsLatch.dec() continue } - namespaces += name.namespace + val size = data["size"]?.toLong() ?: -1 val hash = data["hash"].toString() if (tasks.count > DefaultThreadPool.threadCount - 1) { diff --git a/src/main/java/de/bixilon/minosoft/assets/minecraft/index/IndexAssetsType.kt b/src/main/java/de/bixilon/minosoft/assets/minecraft/index/IndexAssetsType.kt index 739a09144..e81db1b81 100644 --- a/src/main/java/de/bixilon/minosoft/assets/minecraft/index/IndexAssetsType.kt +++ b/src/main/java/de/bixilon/minosoft/assets/minecraft/index/IndexAssetsType.kt @@ -1,8 +1,17 @@ package de.bixilon.minosoft.assets.minecraft.index +import de.bixilon.minosoft.util.KUtil +import de.bixilon.minosoft.util.enum.ValuesEnum + enum class IndexAssetsType { LANGUAGE, SOUNDS, TEXTURES, ; + + companion object : ValuesEnum { + override val VALUES: Array = values() + override val NAME_MAP: Map = KUtil.getEnumValues(VALUES) + + } } diff --git a/src/main/java/de/bixilon/minosoft/assets/multi/PriorityAssetsManager.kt b/src/main/java/de/bixilon/minosoft/assets/multi/PriorityAssetsManager.kt index 6c796927d..f309b2d41 100644 --- a/src/main/java/de/bixilon/minosoft/assets/multi/PriorityAssetsManager.kt +++ b/src/main/java/de/bixilon/minosoft/assets/multi/PriorityAssetsManager.kt @@ -46,9 +46,12 @@ class PriorityAssetsManager( fun add(manager: AssetsManager) { for (namespace in manager.namespaces) { this.managers.getOrPut(namespace) { mutableSetOf() } += manager + this.namespaces += namespace } } + operator fun plusAssign(manager: AssetsManager) = add(manager) + override fun get(path: ResourceLocation): InputStream { return nullGet(path) ?: throw FileNotFoundException("Can not find assets-manager for $path") } diff --git a/src/main/java/de/bixilon/minosoft/assets/properties/version/AssetsVersionProperties.kt b/src/main/java/de/bixilon/minosoft/assets/properties/version/AssetsVersionProperties.kt index 572c86c8f..96f993bd1 100644 --- a/src/main/java/de/bixilon/minosoft/assets/properties/version/AssetsVersionProperties.kt +++ b/src/main/java/de/bixilon/minosoft/assets/properties/version/AssetsVersionProperties.kt @@ -16,7 +16,7 @@ object AssetsVersionProperties { } val assetsProperties: Map = Minosoft.MINOSOFT_ASSETS_MANAGER[ASSETS_PROPERTIES_FILE].readJson() for ((versionName, property) in assetsProperties) { - PROPERTIES[Versions.getVersionByName(versionName) ?: continue] = property + PROPERTIES[Versions[versionName] ?: continue] = property } } diff --git a/src/main/java/de/bixilon/minosoft/assets/util/FileAssetsUtil.kt b/src/main/java/de/bixilon/minosoft/assets/util/FileAssetsUtil.kt index 7239f15ed..4f8efbfe2 100644 --- a/src/main/java/de/bixilon/minosoft/assets/util/FileAssetsUtil.kt +++ b/src/main/java/de/bixilon/minosoft/assets/util/FileAssetsUtil.kt @@ -88,6 +88,7 @@ object FileAssetsUtil { file.parentFile.apply { mkdirs() if (!isDirectory) { + tempFile.delete() throw IllegalStateException("Could not create folder $this") } } @@ -108,8 +109,8 @@ object FileAssetsUtil { return saveAndGet(ByteArrayInputStream(data), compress, false) } - fun String.toAssetName(): ResourceLocation? { - if (!startsWith("assets/")) { + fun String.toAssetName(verifyPrefix: Boolean = true): ResourceLocation? { + if (verifyPrefix && !startsWith("assets/")) { return null } val split = removePrefix("assets/").split("/", limit = 2) @@ -135,26 +136,31 @@ object FileAssetsUtil { return true } - val digest = MessageDigest.getInstance("SHA-1") + try { + val digest = MessageDigest.getInstance("SHA-1") - var input: InputStream = FileInputStream(file) - if (compress) { - input = ZstdInputStream(input) - } - - val buffer = ByteArray(ProtocolDefinition.DEFAULT_BUFFER_SIZE) - var length: Int - while (true) { - length = input.read(buffer, 0, buffer.size) - if (length < 0) { - break + var input: InputStream = FileInputStream(file) + if (compress) { + input = ZstdInputStream(input) } - digest.update(buffer, 0, length) - } - val equals = hash != Util.byteArrayToHexString(digest.digest()) - if (!equals) { + + val buffer = ByteArray(ProtocolDefinition.DEFAULT_BUFFER_SIZE) + var length: Int + while (true) { + length = input.read(buffer, 0, buffer.size) + if (length < 0) { + break + } + digest.update(buffer, 0, length) + } + val equals = hash == Util.byteArrayToHexString(digest.digest()) + if (!equals) { + file.delete() + } + return equals + } catch (exception: Throwable) { file.delete() + return false } - return equals } } diff --git a/src/main/java/de/bixilon/minosoft/assets/util/FileUtil.kt b/src/main/java/de/bixilon/minosoft/assets/util/FileUtil.kt index 4311de85e..0285495ff 100644 --- a/src/main/java/de/bixilon/minosoft/assets/util/FileUtil.kt +++ b/src/main/java/de/bixilon/minosoft/assets/util/FileUtil.kt @@ -15,7 +15,9 @@ package de.bixilon.minosoft.assets.util import com.fasterxml.jackson.module.kotlin.readValue import com.github.luben.zstd.ZstdInputStream +import de.bixilon.mbf.MBFBinaryReader import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition +import de.bixilon.minosoft.util.KUtil.unsafeCast import de.bixilon.minosoft.util.json.Jackson import de.matthiasmann.twl.utils.PNGDecoder import org.apache.commons.compress.archivers.tar.TarArchiveInputStream @@ -127,4 +129,8 @@ object FileUtil { return colors } + + fun InputStream.readMBFMap(): Map { + return MBFBinaryReader(this).readMBF().data.unsafeCast() + } } diff --git a/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/general/GeneralC.kt b/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/general/GeneralC.kt index e9d32c0aa..77c0e0d04 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/general/GeneralC.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/general/GeneralC.kt @@ -6,6 +6,7 @@ import de.bixilon.minosoft.config.profile.profiles.account.AccountProfile import de.bixilon.minosoft.config.profile.profiles.account.AccountProfileManager import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager.delegate import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager.mapDelegate +import de.bixilon.minosoft.data.language.LanguageManager import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.util.KUtil.fullName import java.util.* @@ -14,7 +15,7 @@ class GeneralC { /** * Language to use for eros. This is also the fallback language for other profiles */ - var language: String by delegate(Locale.getDefault()?.fullName ?: "en_US") + var language: String by delegate(Locale.getDefault()?.fullName ?: LanguageManager.FALLBACK_LANGUAGE) @get:JsonProperty("account_profile") private var _accountProfile: String? by delegate(null) @@ -29,5 +30,4 @@ class GeneralC { * If profile is not set or not found, the global default profile is used */ var profileOverrides: MutableMap by mapDelegate() - } diff --git a/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/server/entries/Server.kt b/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/server/entries/Server.kt index f8bdc0a1f..ebb76f2d8 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/server/entries/Server.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/profiles/eros/server/entries/Server.kt @@ -53,7 +53,7 @@ class Server( private var _forcedVersion by delegate(forcedVersion?.name) @get:JsonIgnore - var forcedVersion by backingDelegate(getter = { Versions.getVersionByName(_forcedVersion) }, setter = { _forcedVersion = it?.name }) + var forcedVersion by backingDelegate(getter = { Versions[_forcedVersion] }, setter = { _forcedVersion = it?.name }) @get:JsonInclude(JsonInclude.Include.NON_DEFAULT) var faviconHash: String? by delegate(null) { if (it != null) check(it.length == 40) { "Not a valid sha1 hash!" } } diff --git a/src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/ResourcesProfile.kt b/src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/ResourcesProfile.kt index dd38d7235..bf6dfec36 100644 --- a/src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/ResourcesProfile.kt +++ b/src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/ResourcesProfile.kt @@ -4,6 +4,7 @@ import de.bixilon.minosoft.config.profile.ProfileManager import de.bixilon.minosoft.config.profile.profiles.Profile import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfileManager.delegate import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfileManager.latestVersion +import de.bixilon.minosoft.config.profile.profiles.resources.assets.AssetsC import de.bixilon.minosoft.config.profile.profiles.resources.source.SourceC import de.bixilon.minosoft.util.KUtil.unsafeCast @@ -23,6 +24,7 @@ class ResourcesProfile( override var description by delegate(description ?: "") val source = SourceC() + val assets = AssetsC() /** * If set, all downloaded assets will be checked on load. diff --git a/src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/assets/AssetsC.kt b/src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/assets/AssetsC.kt new file mode 100644 index 000000000..f291620be --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/assets/AssetsC.kt @@ -0,0 +1,15 @@ +package de.bixilon.minosoft.config.profile.profiles.resources.assets + +import de.bixilon.minosoft.assets.minecraft.index.IndexAssetsType +import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfileManager.delegate +import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfileManager.listDelegate +import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfileManager.setDelegate +import de.bixilon.minosoft.config.profile.profiles.resources.assets.packs.ResourcePack + +class AssetsC { + var disableJarAssets by delegate(false) + var disableIndexAssets by delegate(false) + val indexAssetsTypes: MutableSet by setDelegate(mutableSetOf(*IndexAssetsType.VALUES)) + + val resourcePacks: List by listDelegate() +} diff --git a/src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/assets/packs/ResourcePack.kt b/src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/assets/packs/ResourcePack.kt new file mode 100644 index 000000000..661482fa4 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/assets/packs/ResourcePack.kt @@ -0,0 +1,6 @@ +package de.bixilon.minosoft.config.profile.profiles.resources.assets.packs + +class ResourcePack( + var type: ResourcePackType, + var path: String, +) diff --git a/src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/assets/packs/ResourcePackType.kt b/src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/assets/packs/ResourcePackType.kt new file mode 100644 index 000000000..6594dc5d9 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/config/profile/profiles/resources/assets/packs/ResourcePackType.kt @@ -0,0 +1,11 @@ +package de.bixilon.minosoft.config.profile.profiles.resources.assets.packs + +import de.bixilon.minosoft.assets.AssetsManager +import de.bixilon.minosoft.assets.directory.DirectoryAssetsManager +import de.bixilon.minosoft.assets.file.ZipAssetsManager + +enum class ResourcePackType(val creator: (ResourcePack) -> AssetsManager) { + ZIP({ ZipAssetsManager(it.path) }), + DIRECTORY({ DirectoryAssetsManager(it.path) }), + ; +} diff --git a/src/main/java/de/bixilon/minosoft/data/commands/parser/minosoft/VersionParser.java b/src/main/java/de/bixilon/minosoft/data/commands/parser/minosoft/VersionParser.java index 4b8f5c61c..dc6979bad 100644 --- a/src/main/java/de/bixilon/minosoft/data/commands/parser/minosoft/VersionParser.java +++ b/src/main/java/de/bixilon/minosoft/data/commands/parser/minosoft/VersionParser.java @@ -35,7 +35,7 @@ public class VersionParser extends CommandParser { if (StringUtils.isBlank(rawVersionName)) { throw new BlankStringCommandParseException(stringReader, rawVersionName); } - Version version = Versions.getVersionByName(rawVersionName); + Version version = Versions.INSTANCE.get(rawVersionName); if (version == null) { throw new InvalidVersionCommandParseException(stringReader, rawVersionName); } diff --git a/src/main/java/de/bixilon/minosoft/data/inventory/ItemStack.kt b/src/main/java/de/bixilon/minosoft/data/inventory/ItemStack.kt index f0426cb9e..4ad3dded4 100644 --- a/src/main/java/de/bixilon/minosoft/data/inventory/ItemStack.kt +++ b/src/main/java/de/bixilon/minosoft/data/inventory/ItemStack.kt @@ -254,20 +254,20 @@ class ItemStack( val enchantmentList: MutableList> = mutableListOf() for ((enchantment, level) in enchantments) { val enchantmentTag: MutableMap = mutableMapOf() - enchantmentTag[ENCHANTMENT_ID_TAG] = if (connection.version.isFlattened()) { + enchantmentTag[ENCHANTMENT_ID_TAG] = if (connection.version.flattened) { enchantment.resourceLocation.full } else { connection.registries.enchantmentRegistry.getId(enchantment) } - enchantmentTag[ENCHANTMENT_LEVEL_TAG] = if (connection.version.isFlattened()) { + enchantmentTag[ENCHANTMENT_LEVEL_TAG] = if (connection.version.flattened) { level } else { level.toShort() } enchantmentList += enchantmentTag } - if (connection.version.isFlattened()) { + if (connection.version.flattened) { nbt[ENCHANTMENT_FLATTENING_TAG] = enchantmentList } else { nbt[ENCHANTMENT_PRE_FLATTENING_TAG] = enchantmentList diff --git a/src/main/java/de/bixilon/minosoft/data/language/LanguageManager.kt b/src/main/java/de/bixilon/minosoft/data/language/LanguageManager.kt index 8a776099b..3ce85ba8e 100644 --- a/src/main/java/de/bixilon/minosoft/data/language/LanguageManager.kt +++ b/src/main/java/de/bixilon/minosoft/data/language/LanguageManager.kt @@ -13,7 +13,7 @@ package de.bixilon.minosoft.data.language -import de.bixilon.minosoft.Minosoft +import de.bixilon.minosoft.assets.AssetsManager import de.bixilon.minosoft.assets.util.FileUtil.readAsString import de.bixilon.minosoft.assets.util.FileUtil.readJsonObject import de.bixilon.minosoft.data.registries.ResourceLocation @@ -53,10 +53,9 @@ class LanguageManager( } companion object { + const val FALLBACK_LANGUAGE = "en_US" - - fun load(language: String, version: Version?, path: ResourceLocation = ResourceLocation("lang/")): LanguageManager { - val assetsManager = version?.jarAssetsManager ?: Minosoft.MINOSOFT_ASSETS_MANAGER + fun load(language: String, version: Version?, assetsManager: AssetsManager, path: ResourceLocation = ResourceLocation("lang/")): LanguageManager { fun loadMinecraftLanguage(language: String): Language { val data: MutableMap = mutableMapOf() @@ -82,13 +81,12 @@ class LanguageManager( val languages: MutableList = mutableListOf() - if (language != "en_US") { + if (language != FALLBACK_LANGUAGE) { tryCatch(FileNotFoundException::class.java, executor = { languages += loadMinecraftLanguage(language) }) } - languages += loadMinecraftLanguage("en_US") + languages += loadMinecraftLanguage(FALLBACK_LANGUAGE) return LanguageManager(languages) - } } } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/RegistriesLoadingException.kt b/src/main/java/de/bixilon/minosoft/data/registries/RegistriesLoadingException.kt deleted file mode 100644 index f0a88fffb..000000000 --- a/src/main/java/de/bixilon/minosoft/data/registries/RegistriesLoadingException.kt +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Minosoft - * Copyright (C) 2020 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 . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ -package de.bixilon.minosoft.data.registries - -class RegistriesLoadingException : Exception { - constructor() - constructor(message: String?) : super(message) - constructor(message: String?, cause: Throwable?) : super(message, cause) - constructor(cause: Throwable?) : super(cause) - constructor(message: String?, cause: Throwable?, enableSuppression: Boolean, writableStackTrace: Boolean) : super(message, cause, enableSuppression, writableStackTrace) -} diff --git a/src/main/java/de/bixilon/minosoft/data/registries/registries/Registries.kt b/src/main/java/de/bixilon/minosoft/data/registries/registries/Registries.kt index e916e1049..18fc2aec3 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/registries/Registries.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/registries/Registries.kt @@ -127,8 +127,8 @@ class Registries { } } - fun load(version: Version, pixlyzerData: MutableMap) { - isFlattened = version.isFlattened() + fun load(version: Version, pixlyzerData: Map) { + isFlattened = version.flattened blockStateRegistry.flattened = isFlattened // pre init stuff loadShapes(pixlyzerData["shapes"]?.compoundCast()) @@ -157,7 +157,7 @@ class Registries { entityTypeRegistry.rawInitialize(pixlyzerData["entities"]?.compoundCast(), this, EntityType) - motiveRegistry.rawInitialize(pixlyzerData["motives"]?.compoundCast(), this, Motive, version.isFlattened()) + motiveRegistry.rawInitialize(pixlyzerData["motives"]?.compoundCast(), this, Motive, version.flattened) soundEventRegistry.rawInitialize(pixlyzerData["sound_events"]?.compoundCast()) particleTypeRegistry.rawInitialize(pixlyzerData["particles"]?.compoundCast(), this, ParticleType) materialRegistry.rawInitialize(pixlyzerData["materials"]?.compoundCast(), this, Material) @@ -166,8 +166,8 @@ class Registries { biomeRegistry.rawInitialize(pixlyzerData["biomes"]?.compoundCast(), this, Biome) dimensionRegistry.rawInitialize(pixlyzerData["dimensions"]?.compoundCast(), this, Dimension) fluidRegistry.rawInitialize(pixlyzerData["fluids"]?.compoundCast(), this, Fluid) - blockRegistry.rawInitialize(pixlyzerData["blocks"]?.compoundCast(), this, Block, version.isFlattened(), Registry.MetaTypes.BITS_4) - itemRegistry.rawInitialize(pixlyzerData["items"]?.compoundCast(), this, Item, version.isFlattened(), Registry.MetaTypes.BITS_16) + blockRegistry.rawInitialize(pixlyzerData["blocks"]?.compoundCast(), this, Block, version.flattened, Registry.MetaTypes.BITS_4) + itemRegistry.rawInitialize(pixlyzerData["items"]?.compoundCast(), this, Item, version.flattened, Registry.MetaTypes.BITS_16) blockEntityTypeRegistry.rawInitialize(pixlyzerData["block_entities"]?.compoundCast(), this, BlockEntityType) diff --git a/src/main/java/de/bixilon/minosoft/data/registries/registries/RegistriesLoader.kt b/src/main/java/de/bixilon/minosoft/data/registries/registries/RegistriesLoader.kt new file mode 100644 index 000000000..538c5dd79 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/registries/registries/RegistriesLoader.kt @@ -0,0 +1,49 @@ +package de.bixilon.minosoft.data.registries.registries + +import de.bixilon.minosoft.assets.properties.version.AssetsVersionProperties +import de.bixilon.minosoft.assets.util.FileAssetsUtil +import de.bixilon.minosoft.assets.util.FileUtil +import de.bixilon.minosoft.assets.util.FileUtil.readMBFMap +import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfile +import de.bixilon.minosoft.data.registries.versions.Version +import de.bixilon.minosoft.util.Util +import de.bixilon.minosoft.util.nbt.tag.NBTUtil.compoundCast +import java.io.ByteArrayInputStream +import java.io.File + +object RegistriesLoader { + + fun load(profile: ResourcesProfile, version: Version): Registries { + // ToDo: Pre flattening support + val pixlyzerHash = AssetsVersionProperties[version]?.pixlyzerHash ?: throw IllegalStateException("$version has no pixlyzer data available!") + + val pixlyzerData = getPixlyzerData(profile.source.pixlyzer, pixlyzerHash) + + val registries = Registries() + registries.load(version, pixlyzerData) + + return registries + } + + private fun getPixlyzerData(url: String, hash: String): Map { + val path = FileAssetsUtil.getPath(hash) + val file = File(path) + if (file.exists()) { + // ToDo: Verify + return FileUtil.readFile(file, false).readMBFMap().compoundCast() ?: throw IllegalStateException("Could not read pixlyzer data!") + } + + val savedHash = FileAssetsUtil.downloadAndGetAsset(Util.formatString( + url, + mapOf( + "hashPrefix" to hash.substring(0, 2), + "fullHash" to hash, + ) + ), false) + if (savedHash.first != hash) { + throw IllegalStateException("Data mismatch, expected $hash, got ${savedHash.first}") + } + + return ByteArrayInputStream(savedHash.second).readMBFMap().compoundCast() ?: throw IllegalStateException("Invalid pixlyzer data!") + } +} diff --git a/src/main/java/de/bixilon/minosoft/data/registries/versions/Version.kt b/src/main/java/de/bixilon/minosoft/data/registries/versions/Version.kt index 5f0005991..30cc31bbd 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/versions/Version.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/versions/Version.kt @@ -1,157 +1,45 @@ -/* - * Minosoft - * Copyright (C) 2020 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 . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ package de.bixilon.minosoft.data.registries.versions -import com.google.common.collect.HashBiMap -import de.bixilon.mbf.MBFBinaryReader -import de.bixilon.minosoft.assets.minecraft.JarAssetsManager -import de.bixilon.minosoft.assets.minecraft.index.IndexAssetsManager -import de.bixilon.minosoft.assets.properties.version.AssetsVersionProperties -import de.bixilon.minosoft.assets.util.FileAssetsUtil -import de.bixilon.minosoft.assets.util.FileUtil +import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfile import de.bixilon.minosoft.data.registries.registries.Registries -import de.bixilon.minosoft.protocol.protocol.PacketTypes.C2S -import de.bixilon.minosoft.protocol.protocol.PacketTypes.S2C +import de.bixilon.minosoft.data.registries.registries.RegistriesLoader +import de.bixilon.minosoft.protocol.protocol.PacketTypes import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition import de.bixilon.minosoft.protocol.protocol.ProtocolStates import de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_15W31A -import de.bixilon.minosoft.util.CountUpAndDownLatch -import de.bixilon.minosoft.util.KUtil import de.bixilon.minosoft.util.KUtil.decide -import de.bixilon.minosoft.util.logging.Log -import de.bixilon.minosoft.util.logging.LogLevels -import de.bixilon.minosoft.util.logging.LogMessageType -import de.bixilon.minosoft.util.nbt.tag.NBTUtil.asCompound -@Deprecated(message = "Some refactoring needed") -data class Version( - var name: String, +class Version( + val name: String, val versionId: Int, val protocolId: Int, - val c2SPacketMapping: Map>, - val s2CPacketMapping: Map>, + val s2cPackets: Map>, + val c2sPackets: Map>, ) { val sortingId: Int = (versionId == -1).decide(Int.MAX_VALUE, versionId) - val type: VersionTypes = VersionTypes[this] - var isLoaded = false - val registries: Registries = Registries() - lateinit var jarAssetsManager: JarAssetsManager - lateinit var indexAssetsManager: IndexAssetsManager + val type = VersionTypes[this] + var registries: Registries? = null + private set - fun getPacketById(state: ProtocolStates, command: Int): S2C? { - return s2CPacketMapping[state]?.inverse()?.get(command) - } - fun getPacketId(packet: C2S): Int? { - return c2SPacketMapping[packet.state]?.get(packet) - } - - fun isFlattened(): Boolean { - return versionId >= ProtocolDefinition.FLATTING_VERSION_ID - } - - private fun initializeAssetManger(latch: CountUpAndDownLatch) { - if (this::jarAssetsManager.isInitialized) { + @Synchronized + fun load(profile: ResourcesProfile) { + if (registries != null) { + // already loaded return } - if (!isFlattened() && versionId != ProtocolDefinition.PRE_FLATTENING_VERSION_ID) { - jarAssetsManager = Versions.PRE_FLATTENING_VERSION.jarAssetsManager - return - } - // ToDo + registries = RegistriesLoader.load(profile, this) } @Synchronized - fun load(latch: CountUpAndDownLatch) { - if (isLoaded) { - return - } - - if (!isFlattened() && this !== Versions.PRE_FLATTENING_VERSION && !Versions.PRE_FLATTENING_VERSION.isLoaded) { - // no matter what, we need the version mapping for all pre flattening versions - try { - Versions.PRE_FLATTENING_VERSION.load(latch) - } catch (exception: Exception) { - Versions.PRE_FLATTENING_VERSION.unload() - Versions.PRE_FLATTENING_MAPPING = null - throw exception - } - } - latch.inc() - Log.log(LogMessageType.VERSION_LOADING, level = LogLevels.INFO) { "Loading registries for $this..." } - initializeAssetManger(latch) - val startTime = KUtil.time - - - if (versionId == ProtocolDefinition.PRE_FLATTENING_VERSION_ID) { - Versions.PRE_FLATTENING_MAPPING = registries - } else if (!isFlattened()) { - registries.parentRegistries = Versions.PRE_FLATTENING_MAPPING - } - val pixlyzerData = try { - MBFBinaryReader(FileUtil.readFile(FileAssetsUtil.getPath(AssetsVersionProperties[this]!!.pixlyzerHash ?: throw IllegalStateException("$this has no pixlyzer data!")), false)).readMBF().data.asCompound() - } catch (exception: Throwable) { - // should not happen, but if this version is not flattened, we can fallback to the flatten mappings. Some things might not work... - Log.log(LogMessageType.VERSION_LOADING, level = LogLevels.VERBOSE) { exception } - if (isFlattened()) { - throw exception - } - if (versionId == ProtocolDefinition.PRE_FLATTENING_VERSION_ID) { - Versions.PRE_FLATTENING_MAPPING = null - } - mutableMapOf() - } - latch.inc() - registries.load(this, pixlyzerData) - latch.dec() - if (pixlyzerData.isNotEmpty()) { - Log.log(LogMessageType.VERSION_LOADING, level = LogLevels.INFO) { "Loaded registries for $name in ${KUtil.time - startTime}ms" } - } else { - Log.log(LogMessageType.VERSION_LOADING, level = LogLevels.WARN) { "Could not load registries for ${name}. Some features might not work." } - } - isLoaded = true - latch.dec() - } - fun unload() { - registries.clear() - if (registries.parentRegistries == registries) { - registries.parentRegistries = null - } - isLoaded = false - } - - override fun hashCode(): Int { - return versionId - } - - override fun equals(other: Any?): Boolean { - if (super.equals(other)) { - return true - } - if (other !is Version) { - return false - } - return if (hashCode() != other.hashCode()) { - false - } else { - this.name == other.name - } + this.registries = null } override fun toString(): String { return name } - val hasOffhand = versionId >= V_15W31A + val flattened: Boolean = versionId >= ProtocolDefinition.FLATTING_VERSION_ID + val hasOffhand: Boolean = versionId >= V_15W31A } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/versions/VersionTypes.kt b/src/main/java/de/bixilon/minosoft/data/registries/versions/VersionTypes.kt index 3c21f539d..d5b84f854 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/versions/VersionTypes.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/versions/VersionTypes.kt @@ -22,7 +22,7 @@ enum class VersionTypes { private val SNAPSHOT_DETECT_REGEX = "(\\d{2}w\\d{2})[a-f]|(1.\\d{1,2}(.\\d+)?-?(rc|pre)\\d*)".toRegex() @Deprecated(message = "Should be saved in the versions.json") - operator fun get(version: Version): VersionTypes { + operator fun get(version: de.bixilon.minosoft.data.registries.versions.Version): VersionTypes { if (SNAPSHOT_DETECT_REGEX.matches(version.name)) { return SNAPSHOT } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/versions/Versions.java b/src/main/java/de/bixilon/minosoft/data/registries/versions/Versions.java deleted file mode 100644 index 52ada2774..000000000 --- a/src/main/java/de/bixilon/minosoft/data/registries/versions/Versions.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Minosoft - * Copyright (C) 2020 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 . - * - * This software is not affiliated with Mojang AB, the original developer of Minecraft. - */ - -package de.bixilon.minosoft.data.registries.versions; - -import com.google.common.collect.HashBiMap; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import de.bixilon.minosoft.data.registries.registries.Registries; -import de.bixilon.minosoft.protocol.protocol.PacketTypes; -import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition; -import de.bixilon.minosoft.protocol.protocol.ProtocolStates; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.HashMap; -import java.util.Map; - -@Deprecated -public class Versions { - public static final Version AUTOMATIC_VERSION = new Version("Automatic", -1, -1, new HashMap<>(), new HashMap<>()); - public static final HashBiMap VERSION_ID_MAP = HashBiMap.create(500); - private static final HashBiMap VERSION_PROTOCOL_ID_MAP = HashBiMap.create(500); - private static final HashBiMap VERSION_NAME_MAP = HashBiMap.create(500); - public static Registries PRE_FLATTENING_MAPPING; - public static Version PRE_FLATTENING_VERSION; - - public static Version getVersionById(int versionId) { - return VERSION_ID_MAP.get(versionId); - } - - public static Version getVersionByProtocolId(int protocolId) { - return VERSION_PROTOCOL_ID_MAP.get(protocolId); - } - - @Nullable - public static Version getVersionByName(@Nullable final String name) { - if ("automatic".equals(name)) { - return AUTOMATIC_VERSION; - } - return VERSION_NAME_MAP.get(name); - } - - public static void loadAvailableVersions(JsonObject json) { - for (String versionId : json.keySet()) { - loadVersion(json, versionId); - } - } - - private static Version loadVersion(JsonObject json, String versionIdString) { - JsonObject versionJson = json.getAsJsonObject(versionIdString); - String versionName = versionJson.get("name").getAsString(); - int versionId = Integer.parseInt(versionIdString); - if (VERSION_ID_MAP.containsKey(versionId)) { - // already loaded, skip - return VERSION_ID_MAP.get(versionId); - } - - Map> c2sMapping; - Map> s2cMapping; - if (versionJson.get("mapping").isJsonPrimitive()) { - // inherits or copies mapping from an other version - Version parent = VERSION_ID_MAP.get(versionJson.get("mapping").getAsInt()); - if (parent == null) { - parent = loadVersion(json, versionJson.get("mapping").getAsString()); - } - c2sMapping = parent.getC2SPacketMapping(); - s2cMapping = parent.getS2CPacketMapping(); - } else { - JsonObject mappingJson = versionJson.getAsJsonObject("mapping"); - c2sMapping = new HashMap<>(); - - for (JsonElement packetElement : mappingJson.getAsJsonArray("c2s")) { - PacketTypes.C2S packet = PacketTypes.C2S.valueOf(packetElement.getAsString()); - if (!c2sMapping.containsKey(packet.getState())) { - c2sMapping.put(packet.getState(), HashBiMap.create(30)); - } - c2sMapping.get(packet.getState()).put(packet, c2sMapping.get(packet.getState()).size()); - } - s2cMapping = new HashMap<>(); - for (JsonElement packetElement : mappingJson.getAsJsonArray("s2c")) { - PacketTypes.S2C packet = PacketTypes.S2C.valueOf(packetElement.getAsString()); - if (!s2cMapping.containsKey(packet.getState())) { - s2cMapping.put(packet.getState(), HashBiMap.create(100)); - } - s2cMapping.get(packet.getState()).put(packet, s2cMapping.get(packet.getState()).size()); - } - } - int protocolId = versionId; - if (versionJson.has("protocol_id")) { - protocolId = versionJson.get("protocol_id").getAsInt(); - } - Version version = new Version(versionName, versionId, protocolId, c2sMapping, s2cMapping); - VERSION_ID_MAP.put(version.getVersionId(), version); - VERSION_PROTOCOL_ID_MAP.put(version.getProtocolId(), version); - VERSION_NAME_MAP.put(version.getName(), version); - if (version.getVersionId() == ProtocolDefinition.PRE_FLATTENING_VERSION_ID) { - PRE_FLATTENING_VERSION = version; - } - return version; - } -} diff --git a/src/main/java/de/bixilon/minosoft/data/registries/versions/Versions.kt b/src/main/java/de/bixilon/minosoft/data/registries/versions/Versions.kt new file mode 100644 index 000000000..3e59f778a --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/registries/versions/Versions.kt @@ -0,0 +1,104 @@ +package de.bixilon.minosoft.data.registries.versions + +import de.bixilon.minosoft.Minosoft +import de.bixilon.minosoft.assets.util.FileUtil.readJson +import de.bixilon.minosoft.protocol.protocol.PacketTypes +import de.bixilon.minosoft.protocol.protocol.ProtocolStates +import de.bixilon.minosoft.util.KUtil.toInt +import de.bixilon.minosoft.util.KUtil.toResourceLocation +import de.bixilon.minosoft.util.KUtil.unsafeCast + +object Versions : Iterable { + private val VERSIONS_INDEX = "minosoft:mapping/versions.json".toResourceLocation() + val AUTOMATIC = Version("Automatic", -1, -1, mapOf(), mapOf()) + private val VERSIONS_BY_NAME: MutableMap = mutableMapOf() + private val VERSIONS_BY_ID: MutableMap = mutableMapOf() + private val VERSIONS_BY_PROTOCOL: MutableMap = mutableMapOf() + + private fun addVersion(version: Version) { + VERSIONS_BY_NAME.put(version.name, version)?.let { throw IllegalStateException("Duplicated version name: ${version.name}") } + VERSIONS_BY_ID.put(version.versionId, version)?.let { throw IllegalStateException("Duplicated version id: ${version.name}") } + VERSIONS_BY_PROTOCOL.put(version.protocolId, version)?.let { throw IllegalStateException("Duplicated protocol id: ${version.name}") } + } + + @Synchronized + fun load() { + val index: Map> = Minosoft.MINOSOFT_ASSETS_MANAGER[VERSIONS_INDEX].readJson() + + fun loadVersion(versionId: Int, data: Map = index[versionId.toString()]!!): Version { + VERSIONS_BY_ID[versionId]?.let { return it } + + + val s2cPackets: Map> + val c2sPackets: Map> + + when (val mapping = data["mapping"]) { + is Int -> { + val mappingVersion = loadVersion(mapping) + s2cPackets = mappingVersion.s2cPackets + c2sPackets = mappingVersion.c2sPackets + } + is Map<*, *> -> { + mapping["s2c"].unsafeCast>().let { + val map: MutableMap> = mutableMapOf() + for (packetName in it) { + val packetType = PacketTypes.S2C[packetName] + map.getOrPut(packetType.state) { mutableListOf() } += packetType + } + val mapOut: MutableMap> = mutableMapOf() + for ((state, types) in map) { + mapOut[state] = types.toTypedArray() + } + s2cPackets = mapOut.toMap() + } + + mapping["c2s"].unsafeCast>().let { + val map: MutableMap> = mutableMapOf() + for (packetName in it) { + val packetType = PacketTypes.C2S[packetName] + map.getOrPut(packetType.state) { mutableListOf() } += packetType + } + val mapOut: MutableMap> = mutableMapOf() + for ((state, types) in map) { + mapOut[state] = types.toTypedArray() + } + c2sPackets = mapOut.toMap() + } + + } + else -> TODO("Can not create version mapping $mapping") + } + + + val version = Version( + name = data["name"].toString(), + versionId = versionId, + protocolId = data["protocol_id"]?.toInt() ?: versionId, + s2cPackets = s2cPackets, + c2sPackets = c2sPackets, + ) + addVersion(version) + return version + } + + for ((versionId, data) in index) { + loadVersion(versionId.toInt(), data) + } + } + + operator fun get(name: String?): Version? { + return VERSIONS_BY_NAME[name] + } + + fun getById(versionId: Int): Version? { + return VERSIONS_BY_ID[versionId] + } + + fun getByProtocol(protocolId: Int): Version? { + return VERSIONS_BY_PROTOCOL[protocolId] + } + + override fun iterator(): Iterator { + return VERSIONS_BY_NAME.values.iterator() + } +} diff --git a/src/main/java/de/bixilon/minosoft/gui/eros/crash/ErosCrashReport.kt b/src/main/java/de/bixilon/minosoft/gui/eros/crash/ErosCrashReport.kt index 9d3ae0663..0889f5f5c 100644 --- a/src/main/java/de/bixilon/minosoft/gui/eros/crash/ErosCrashReport.kt +++ b/src/main/java/de/bixilon/minosoft/gui/eros/crash/ErosCrashReport.kt @@ -129,7 +129,7 @@ class ErosCrashReport : JavaFXWindowController() { } }) tryCatch(executor = { - for (connection in PlayConnection.ACTIVE_CONENCTIONS.toSynchronizedSet()) { + for (connection in PlayConnection.ACTIVE_CONNECTIONS.toSynchronizedSet()) { connection.disconnect() } }) diff --git a/src/main/java/de/bixilon/minosoft/gui/eros/dialog/ServerModifyDialog.kt b/src/main/java/de/bixilon/minosoft/gui/eros/dialog/ServerModifyDialog.kt index 58421dc86..c36783f39 100644 --- a/src/main/java/de/bixilon/minosoft/gui/eros/dialog/ServerModifyDialog.kt +++ b/src/main/java/de/bixilon/minosoft/gui/eros/dialog/ServerModifyDialog.kt @@ -75,7 +75,7 @@ class ServerModifyDialog( private fun refreshVersions() { val selected = forcedVersionFX.selectionModel.selectedItem forcedVersionFX.items.clear() - for (version in Versions.VERSION_ID_MAP.values) { + for (version in Versions) { if (version.type == VersionTypes.RELEASE && !showReleasesFX.isSelected) { continue } @@ -85,14 +85,14 @@ class ServerModifyDialog( forcedVersionFX.items += version } - forcedVersionFX.items += Versions.AUTOMATIC_VERSION + forcedVersionFX.items += Versions.AUTOMATIC forcedVersionFX.items.sortByDescending { it.sortingId } if (forcedVersionFX.items.contains(selected)) { forcedVersionFX.selectionModel.select(selected) } else { - forcedVersionFX.selectionModel.select(Versions.AUTOMATIC_VERSION) + forcedVersionFX.selectionModel.select(Versions.AUTOMATIC) } } @@ -135,7 +135,7 @@ class ServerModifyDialog( super.updateItem(version, empty) version ?: return - text = if (version == Versions.AUTOMATIC_VERSION) { + text = if (version == Versions.AUTOMATIC) { Minosoft.LANGUAGE_MANAGER.translate(VERSION_AUTOMATIC).message } else { "${version.name} (${version.type.name.lowercase()})" @@ -146,12 +146,12 @@ class ServerModifyDialog( refreshVersions() if (server == null) { - forcedVersionFX.selectionModel.select(Versions.AUTOMATIC_VERSION) + forcedVersionFX.selectionModel.select(Versions.AUTOMATIC) // add descriptionFX.text = ADD_DESCRIPTION modifyServerButtonFX.ctext = ADD_UPDATE_BUTTON } else { - forcedVersionFX.selectionModel.select(server.forcedVersion ?: Versions.AUTOMATIC_VERSION) + forcedVersionFX.selectionModel.select(server.forcedVersion ?: Versions.AUTOMATIC) descriptionFX.text = EDIT_DESCRIPTION modifyServerButtonFX.ctext = EDIT_UPDATE_BUTTON @@ -173,7 +173,7 @@ class ServerModifyDialog( if (modifyServerButtonFX.isDisable) { return } - val forcedVersion = (forcedVersionFX.selectionModel.selectedItem == Versions.AUTOMATIC_VERSION).decide(null) { forcedVersionFX.selectionModel.selectedItem } + val forcedVersion = (forcedVersionFX.selectionModel.selectedItem == Versions.AUTOMATIC).decide(null) { forcedVersionFX.selectionModel.selectedItem } DefaultThreadPool += { onUpdate(serverNameFX.text.isBlank().decide({ serverAddressFX.text.toString() }, { serverNameFX.text.trim() }), serverAddressFX.text, forcedVersion, profiles) } stage.close() } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt index e94587d7b..054485103 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/world/WorldRenderer.kt @@ -130,7 +130,7 @@ class WorldRenderer( override fun init() { val asset = AssetsVersionProperties[connection.version]!! - val zip = FileUtil.readFile(FileAssetsUtil.getPath(asset.clientJarHash)).readArchive() + val zip = FileUtil.readFile(FileAssetsUtil.getPath(asset.jarAssetsHash)).readArchive() val modelLoader = ModelLoader(zip, renderWindow) modelLoader.load() diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/PlayConnection.kt b/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/PlayConnection.kt index d5878d0e7..249f5bd9e 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/PlayConnection.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/PlayConnection.kt @@ -13,8 +13,8 @@ package de.bixilon.minosoft.protocol.network.connection.play -import de.bixilon.minosoft.Minosoft -import de.bixilon.minosoft.assets.multi.PriorityAssetsManager +import de.bixilon.minosoft.assets.AssetsLoader +import de.bixilon.minosoft.assets.AssetsManager import de.bixilon.minosoft.config.profile.ConnectionProfiles import de.bixilon.minosoft.data.ChatTextPositions import de.bixilon.minosoft.data.accounts.Account @@ -24,7 +24,6 @@ import de.bixilon.minosoft.data.language.LanguageManager import de.bixilon.minosoft.data.physics.CollisionDetector import de.bixilon.minosoft.data.player.LocalPlayerEntity import de.bixilon.minosoft.data.player.tab.TabList -import de.bixilon.minosoft.data.registries.RegistriesLoadingException import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.ResourceLocationAble import de.bixilon.minosoft.data.registries.recipes.Recipes @@ -83,7 +82,7 @@ class PlayConnection( @Deprecated(message = "PacketSender is deprecated") val sender = PacketSender(this) val serverInfo = ServerInfo() - lateinit var assetsManager: PriorityAssetsManager + lateinit var assetsManager: AssetsManager private set val tags: MutableMap>> = synchronizedMapOf() lateinit var language: LanguageManager @@ -129,7 +128,7 @@ class PlayConnection( when (value) { ProtocolStates.HANDSHAKING -> { state = PlayConnectionStates.HANDSHAKING - ACTIVE_CONENCTIONS += this + ACTIVE_CONNECTIONS += this for ((validators, invokers) in GlobalEventMaster.specificEventInvokers) { var valid = false for (serverAddress in validators) { @@ -206,7 +205,7 @@ class PlayConnection( TimeWorker.removeTask(randomTickTask) } state = PlayConnectionStates.DISCONNECTED - ACTIVE_CONENCTIONS -= this + ACTIVE_CONNECTIONS -= this } else -> { } @@ -218,16 +217,20 @@ class PlayConnection( try { state = PlayConnectionStates.LOADING fireEvent(RegistriesLoadEvent(this, registries, RegistriesLoadEvent.States.PRE)) - version.load(latch) // ToDo: show gui loader - assetsManager = PriorityAssetsManager(Minosoft.MINOSOFT_ASSETS_MANAGER) - language = LanguageManager.load(profiles.connection.language ?: profiles.eros.general.language, version) + version.load(profiles.resources) registries.parentRegistries = version.registries + + assetsManager = AssetsLoader.create(profiles.resources, version) + Log.log(LogMessageType.ASSETS, LogLevels.INFO) { "Downloading and verifying assets. This might take a while..." } + assetsManager.load(latch) + Log.log(LogMessageType.ASSETS, LogLevels.INFO) { "Assets verified!" } + + language = LanguageManager.load(profiles.connection.language ?: profiles.eros.general.language, version, assetsManager) + fireEvent(RegistriesLoadEvent(this, registries, RegistriesLoadEvent.States.POST)) player = LocalPlayerEntity(account, this) if (!RunConfiguration.DISABLE_RENDERING) { - assetsManager.add(version.jarAssetsManager) - assetsManager.add(version.indexAssetsManager) val renderer = Rendering(this) this.rendering = renderer val renderLatch = CountUpAndDownLatch(0, latch) @@ -239,26 +242,28 @@ class PlayConnection( state = PlayConnectionStates.ESTABLISHING } catch (exception: Throwable) { Log.log(LogMessageType.VERSION_LOADING, level = LogLevels.FATAL) { exception } - Log.log(LogMessageType.VERSION_LOADING, level = LogLevels.FATAL) { "Could not load version $version. This version seems to be unsupported" } version.unload() - error = RegistriesLoadingException("Registries could not be loaded", exception) + if (this::assetsManager.isInitialized) { + assetsManager.unload() + } + error = exception retry = false } latch.dec() } - override fun getPacketId(packetType: PacketTypes.C2S): Int { - return version.getPacketId(packetType) ?: Protocol.getPacketId(packetType) ?: error("Can not find packet $packetType for $version") + // ToDo: Improve speed + return version.c2sPackets[packetType.state]?.indexOf(packetType) ?: Protocol.getPacketId(packetType) ?: error("Can not find packet $packetType for $version") } override fun getPacketById(packetId: Int): PacketTypes.S2C { - return version.getPacketById(protocolState, packetId) ?: Protocol.getPacketById(protocolState, packetId) ?: let { + return version.s2cPackets[protocolState]?.getOrNull(packetId) ?: Protocol.getPacketById(protocolState, packetId) ?: let { // wtf, notchain sends play disconnect packet in login state... if (protocolState != ProtocolStates.LOGIN) { return@let null } - val playPacket = version.getPacketById(ProtocolStates.PLAY, packetId) + val playPacket = version.s2cPackets[ProtocolStates.PLAY]?.getOrNull(packetId) if (playPacket == PacketTypes.S2C.PLAY_KICK) { return@let playPacket } @@ -301,6 +306,6 @@ class PlayConnection( } companion object { - val ACTIVE_CONENCTIONS: MutableSet = synchronizedSetOf() + val ACTIVE_CONNECTIONS: MutableSet = synchronizedSetOf() } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/clientsettings/ClientSettingsManager.kt b/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/clientsettings/ClientSettingsManager.kt index c96393238..397bf93f6 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/clientsettings/ClientSettingsManager.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/network/connection/play/clientsettings/ClientSettingsManager.kt @@ -64,7 +64,7 @@ class ClientSettingsManager( return } this.language = language - connection.language = LanguageManager.load(language, connection.version) + connection.language = LanguageManager.load(language, connection.version, connection.assetsManager) sendClientSettings() } diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/connection/status/StatusConnection.kt b/src/main/java/de/bixilon/minosoft/protocol/network/connection/status/StatusConnection.kt index 0cac4b219..5d2feeb88 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/connection/status/StatusConnection.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/network/connection/status/StatusConnection.kt @@ -124,7 +124,7 @@ class StatusConnection( when (value) { ProtocolStates.HANDSHAKING -> { state = StatusConnectionStates.HANDSHAKING - network.sendPacket(HandshakeC2SP(realAddress!!, ProtocolStates.STATUS, Versions.AUTOMATIC_VERSION.protocolId)) + network.sendPacket(HandshakeC2SP(realAddress!!, ProtocolStates.STATUS, Versions.AUTOMATIC.protocolId)) protocolState = ProtocolStates.STATUS } ProtocolStates.STATUS -> { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/c2s/play/ClientSettingsC2SP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/c2s/play/ClientSettingsC2SP.kt index 9feb2c11c..d749d2ae8 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/c2s/play/ClientSettingsC2SP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/c2s/play/ClientSettingsC2SP.kt @@ -24,14 +24,14 @@ import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogMessageType class ClientSettingsC2SP( - val locale: String = "en_US", - var chatColors: Boolean = true, - val viewDistance: Int = 10, - val chatMode: ChatModes = ChatModes.EVERYTHING, - val skinParts: Array = SkinParts.VALUES, - val mainArm: Arms = Arms.RIGHT, - val disableTextFiltering: Boolean = true, - val allowListing: Boolean = true, + val locale: String, + var chatColors: Boolean, + val viewDistance: Int, + val chatMode: ChatModes, + val skinParts: Array, + val mainArm: Arms, + val disableTextFiltering: Boolean, + val allowListing: Boolean, ) : PlayC2SPacket { override fun write(buffer: PlayOutByteBuffer) { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/status/ServerStatusResponseS2CP.kt b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/status/ServerStatusResponseS2CP.kt index a522e8d04..1cb5dfeab 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/status/ServerStatusResponseS2CP.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/s2c/status/ServerStatusResponseS2CP.kt @@ -31,7 +31,7 @@ class ServerStatusResponseS2CP(buffer: InByteBuffer) : StatusS2CPacket() { override fun handle(connection: StatusConnection) { connection.lastServerStatus = status - val version: Version? = Versions.getVersionByProtocolId(status.protocolId ?: -1) + val version: Version? = Versions.getByProtocol(status.protocolId ?: -1) if (version == null) { Log.log(LogMessageType.NETWORK_STATUS, LogLevels.WARN) { "Server is running on unknown version (protocolId=${status.protocolId})" } } else { diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketTypes.kt b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketTypes.kt index 85824e200..9a7e27850 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketTypes.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketTypes.kt @@ -49,6 +49,8 @@ import de.bixilon.minosoft.protocol.packets.s2c.play.scoreboard.teams.TeamsS2CF import de.bixilon.minosoft.protocol.packets.s2c.play.title.* import de.bixilon.minosoft.protocol.packets.s2c.status.ServerStatusResponseS2CP import de.bixilon.minosoft.protocol.packets.s2c.status.StatusPongS2CP +import de.bixilon.minosoft.util.KUtil +import de.bixilon.minosoft.util.enum.ValuesEnum class PacketTypes { @@ -115,8 +117,10 @@ class PacketTypes { val state: ProtocolStates = ProtocolStates.valueOf(name.split("_".toRegex()).toTypedArray()[0]) - companion object { + companion object : ValuesEnum { private val MAPPING: Map, C2S> + override val VALUES: Array = values() + override val NAME_MAP: Map = KUtil.getEnumValues(VALUES) init { val mapping: MutableMap, C2S> = mutableMapOf() @@ -288,5 +292,11 @@ class PacketTypes { val state: ProtocolStates = ProtocolStates.valueOf(name.split("_".toRegex()).toTypedArray()[0]) + + + companion object : ValuesEnum { + override val VALUES: Array = values() + override val NAME_MAP: Map = KUtil.getEnumValues(VALUES) + } } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/PlayInByteBuffer.kt b/src/main/java/de/bixilon/minosoft/protocol/protocol/PlayInByteBuffer.kt index 6fd77dbd6..a215821e9 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/PlayInByteBuffer.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/PlayInByteBuffer.kt @@ -116,7 +116,7 @@ class PlayInByteBuffer : InByteBuffer { } val count = readUnsignedByte() var metaData = 0 - if (connection.version.isFlattened()) { + if (!connection.version.flattened) { metaData = readUnsignedShort() } val nbt = readNBTTag(versionId < V_14W28B)?.compoundCast() diff --git a/src/main/java/de/bixilon/minosoft/terminal/AutoConnect.kt b/src/main/java/de/bixilon/minosoft/terminal/AutoConnect.kt index 38105bb33..9c94a120f 100644 --- a/src/main/java/de/bixilon/minosoft/terminal/AutoConnect.kt +++ b/src/main/java/de/bixilon/minosoft/terminal/AutoConnect.kt @@ -40,11 +40,11 @@ object AutoConnect { // ToDo: Show those connections in eros val split = connectString.split(',') val address = split[0] - val version = Versions.getVersionByName(split.getOrNull(1) ?: "automatic") ?: throw IllegalArgumentException("Auto connect: Version not found!") + val version = Versions[split.getOrNull(1) ?: "automatic"] ?: throw IllegalArgumentException("Auto connect: Version not found!") val accountProfile = AccountProfileManager.selected val account = accountProfile.entries[split.getOrNull(2)] ?: accountProfile.selected ?: throw RuntimeException("Auto connect: Account not found! Have you started normal before or added an account?") - if (version == Versions.AUTOMATIC_VERSION) { + if (version == Versions.AUTOMATIC) { Log.log(LogMessageType.AUTO_CONNECT, LogLevels.INFO) { "Pinging server to get version..." } val ping = StatusConnection(address) ping.ping() diff --git a/src/main/java/de/bixilon/minosoft/util/KUtil.kt b/src/main/java/de/bixilon/minosoft/util/KUtil.kt index c9d648a94..b060709df 100644 --- a/src/main/java/de/bixilon/minosoft/util/KUtil.kt +++ b/src/main/java/de/bixilon/minosoft/util/KUtil.kt @@ -53,7 +53,7 @@ object KUtil { val ret: MutableMap = mutableMapOf() for (value in values) { - ret[value.name.lowercase(Locale.getDefault())] = value + ret[value.name.lowercase()] = value if (value is AliasableEnum) { for (name in value.names) { diff --git a/src/main/java/de/bixilon/minosoft/util/ShutdownManager.kt b/src/main/java/de/bixilon/minosoft/util/ShutdownManager.kt index b26f69380..989cdfb4c 100644 --- a/src/main/java/de/bixilon/minosoft/util/ShutdownManager.kt +++ b/src/main/java/de/bixilon/minosoft/util/ShutdownManager.kt @@ -30,7 +30,7 @@ object ShutdownManager { fun shutdown(message: String? = null, reason: ShutdownReasons = ShutdownReasons.UNKNOWN) { Log.log(LogMessageType.GENERAL, LogLevels.INFO) { "Shutting down..." } - for (connection in PlayConnection.ACTIVE_CONENCTIONS.toSynchronizedSet()) { + for (connection in PlayConnection.ACTIVE_CONNECTIONS.toSynchronizedSet()) { connection.disconnect() } FileWatcherService.stop() diff --git a/src/main/java/de/bixilon/minosoft/util/Util.java b/src/main/java/de/bixilon/minosoft/util/Util.java index 357aba534..f96860837 100644 --- a/src/main/java/de/bixilon/minosoft/util/Util.java +++ b/src/main/java/de/bixilon/minosoft/util/Util.java @@ -36,7 +36,6 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.*; import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadLocalRandom; import java.util.regex.Pattern; import java.util.zip.*; @@ -46,7 +45,7 @@ public final class Util { public static final char[] RANDOM_STRING_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray(); public static final String LINE_SEPARATOR = System.getProperty("line.separator"); public static final Gson GSON = new Gson(); - private static final Random THREAD_LOCAL_RANDOM = ThreadLocalRandom.current(); + private static final Random RANDOM = new Random(); private static final Field JSON_READER_POS_FIELD; private static final Field JSON_READER_LINE_START_FIELD; @@ -251,11 +250,11 @@ public final class Util { } public static char getRandomChar(char[] chars) { - return chars[(THREAD_LOCAL_RANDOM.nextInt(chars.length))]; + return chars[(RANDOM.nextInt(chars.length))]; } public static char getRandomChar() { - return (char) THREAD_LOCAL_RANDOM.nextInt(); + return (char) RANDOM.nextInt(); } public static String getStringBetween(String search, String first, String second) { diff --git a/src/main/java/de/bixilon/minosoft/util/enum/ValuesEnum.kt b/src/main/java/de/bixilon/minosoft/util/enum/ValuesEnum.kt index 2d29d3154..341f9f43c 100644 --- a/src/main/java/de/bixilon/minosoft/util/enum/ValuesEnum.kt +++ b/src/main/java/de/bixilon/minosoft/util/enum/ValuesEnum.kt @@ -22,7 +22,7 @@ interface ValuesEnum> { } operator fun get(name: String): T { - return NAME_MAP[name] ?: throw IllegalArgumentException("Can not find enum value: $name") + return NAME_MAP[name.lowercase()] ?: throw IllegalArgumentException("Can not find enum value: $name") } fun next(current: T): T {