diff --git a/src/main/kotlin/one/oktw/galaxy/proxy/Main.kt b/src/main/kotlin/one/oktw/galaxy/proxy/Main.kt index 62c4dff..2d6b869 100644 --- a/src/main/kotlin/one/oktw/galaxy/proxy/Main.kt +++ b/src/main/kotlin/one/oktw/galaxy/proxy/Main.kt @@ -114,13 +114,13 @@ class Main : CoroutineScope by CoroutineScope(Dispatchers.Default + SupervisorJo } @Suppress("UnstableApiUsage") proxy.eventManager.register(this, ServerPostConnectEvent::class.java) { + // TODO: Get Galaxy Type if (it.player.currentServer.get().serverInfo.name == "galaxy-lobby") { - ResourcePackHelper.trySendResourcePack(it.player, "lobby") + ResourcePackHelper.updatePlayerResourcePacks(it.player, "lobby") } else { - // TODO: Check Galaxy Type if (it.previousServer?.serverInfo?.name != "galaxy-lobby") return@register - ResourcePackHelper.trySendResourcePack(it.player, "normal_galaxy") + ResourcePackHelper.updatePlayerResourcePacks(it.player, "normal_galaxy") } } diff --git a/src/main/kotlin/one/oktw/galaxy/proxy/config/ConfigManager.kt b/src/main/kotlin/one/oktw/galaxy/proxy/config/ConfigManager.kt index ee60616..2f96971 100644 --- a/src/main/kotlin/one/oktw/galaxy/proxy/config/ConfigManager.kt +++ b/src/main/kotlin/one/oktw/galaxy/proxy/config/ConfigManager.kt @@ -1,6 +1,7 @@ package one.oktw.galaxy.proxy.config import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import kotlinx.coroutines.runBlocking import one.oktw.galaxy.proxy.Main.Companion.main import one.oktw.galaxy.proxy.config.model.GalaxySpec @@ -22,10 +23,11 @@ class ConfigManager(private val basePath: Path = Paths.get("config")) { lateinit var redisConfig: RedisConfig private set val galaxies = HashMap() - val galaxiesResourcePack = ConcurrentHashMap() + val resourcePacks = ConcurrentHashMap() init { readConfig() + readResourcePacks() readGalaxies(FileSystems.newFileSystem(this::class.java.getResource("/config")!!.toURI(), emptyMap()).getPath("/config/galaxies")) readGalaxies(basePath.resolve("galaxies")) } @@ -41,6 +43,7 @@ class ConfigManager(private val basePath: Path = Paths.get("config")) { fun reloadGalaxies() { readGalaxies(basePath.resolve("galaxies")) + readResourcePacks() } private fun readConfig() { @@ -54,15 +57,23 @@ class ConfigManager(private val basePath: Path = Paths.get("config")) { if (Files.isDirectory(file) || !Files.isReadable(file)) return@forEach Files.newBufferedReader(file).use { json -> - val galaxyName = file.fileName.toString().substringBeforeLast(".") - galaxies[galaxyName] = gson.fromJson(json, GalaxySpec::class.java) - runBlocking { - try { - galaxiesResourcePack[galaxyName] = galaxies[galaxyName]?.let { spec -> if (spec.ResourcePack.isNotBlank()) ResourcePack.new(spec.ResourcePack) else null } ?: return@runBlocking - } catch (e: Exception) { - main.logger.error("Resource pack load failed!", e) - } + galaxies[file.fileName.toString().substringBeforeLast(".")] = gson.fromJson(json, GalaxySpec::class.java) + } + } + } + } + + private fun readResourcePacks() { + val mapType = object : TypeToken>() {} + val packs = fallbackToResource("resource_packs.json").reader().use { gson.fromJson(it, mapType) } + packs.forEach { pack -> + runBlocking { + try { + if (pack.value.isNotEmpty()) { + resourcePacks[pack.key] = ResourcePack.new(pack.value) } + } catch (e: Exception) { + main.logger.error("Resource pack {} load failed!", pack.key, e) } } } diff --git a/src/main/kotlin/one/oktw/galaxy/proxy/config/model/GalaxySpec.kt b/src/main/kotlin/one/oktw/galaxy/proxy/config/model/GalaxySpec.kt index 15c3809..2883482 100644 --- a/src/main/kotlin/one/oktw/galaxy/proxy/config/model/GalaxySpec.kt +++ b/src/main/kotlin/one/oktw/galaxy/proxy/config/model/GalaxySpec.kt @@ -4,7 +4,9 @@ data class GalaxySpec( val Image: String, val PullSecret: String, val Type: GalaxyType, - val ResourcePack: String, + // List of resource pack keys (defined with resource_packs.json) to apply in order (first item applies first). + // In Minecraft version prior to 1.20.2, only the last resource pack will be applied. + val ResourcePacks: List, val Resource: GalaxyResource? = null, val Storage: GalaxyStorage? = null ) { diff --git a/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePack.kt b/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePack.kt index 637adf4..6d7a28e 100644 --- a/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePack.kt +++ b/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePack.kt @@ -21,6 +21,7 @@ package one.oktw.galaxy.proxy.resourcepack import com.google.common.hash.Hashing import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.withContext +import one.oktw.galaxy.proxy.Main.Companion.main import java.io.FileNotFoundException import java.io.IOException import java.net.URI @@ -32,13 +33,18 @@ class ResourcePack private constructor(url: String) { var uri = URI(url) private set - var hash:ByteArray + var hash: ByteArray private set init { this.hash = getHashFromUri(uri) } + fun packInfo() = main.proxy.createResourcePackBuilder(this.uri.toString()) + .setHash(this.hash) + .setShouldForce(true) + .build() + @Throws(FileNotFoundException::class) @Suppress("UnstableApiUsage", "DEPRECATION") private fun getHashFromUri(uri: URI): ByteArray { diff --git a/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackHelper.kt b/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackHelper.kt index 02c6744..ad298c5 100644 --- a/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackHelper.kt +++ b/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackHelper.kt @@ -1,20 +1,30 @@ package one.oktw.galaxy.proxy.resourcepack import com.velocitypowered.api.proxy.Player +import com.velocitypowered.api.proxy.player.ResourcePackInfo import one.oktw.galaxy.proxy.Main.Companion.main +import kotlin.math.max class ResourcePackHelper { - companion object{ - fun trySendResourcePack(player: Player, galaxy: String){ - val resourcePack = main.config.galaxiesResourcePack[galaxy] ?: return + companion object { + fun updatePlayerResourcePacks(player: Player, galaxy: String) { + val targetResourcePacks = main.config.galaxies[galaxy]?.ResourcePacks?.distinct()?.mapNotNull { main.config.resourcePacks[it]?.packInfo() } ?: return + val appliedResourcePacks = player.appliedResourcePacks.toList().filterNotNull() - player.clearResourcePacks() - player.sendResourcePackOffer( - main.proxy.createResourcePackBuilder(resourcePack.uri.toString()) - .setHash(resourcePack.hash) - .setShouldForce(true) - .build() - ) + var skipFurtherCheck = false + val packsToQueue = mutableListOf() + val packsToRemove = mutableListOf() + + for (index in 0..max(targetResourcePacks.size, appliedResourcePacks.size)) { + if (targetResourcePacks.getOrNull(index)?.hash.contentEquals(appliedResourcePacks.getOrNull(index)?.hash) && !skipFurtherCheck) continue + + skipFurtherCheck = true + if (index < appliedResourcePacks.size) packsToRemove.add(appliedResourcePacks[index]) + if (index < targetResourcePacks.size) packsToQueue.add(targetResourcePacks[index]) + } + + packsToRemove.forEach { pack -> player.removeResourcePacks(pack) } + packsToQueue.forEach { pack -> player.sendResourcePacks(pack) } } } } diff --git a/src/main/resources/config/galaxies/lobby.json b/src/main/resources/config/galaxies/lobby.json index d5a212f..69c9697 100644 --- a/src/main/resources/config/galaxies/lobby.json +++ b/src/main/resources/config/galaxies/lobby.json @@ -2,7 +2,7 @@ "Image": "registry.gitlab.com/oktw-network/galaxy", "PullSecret": "", "Type": "LOBBY", - "ResourcePack": "", + "ResourcePacks": ["base", "lobby"], "Resource": { "CPULimit": "4000m", "CPURequest": "300m", diff --git a/src/main/resources/config/galaxies/normal_galaxy.json b/src/main/resources/config/galaxies/normal_galaxy.json index c729769..c540adf 100644 --- a/src/main/resources/config/galaxies/normal_galaxy.json +++ b/src/main/resources/config/galaxies/normal_galaxy.json @@ -2,7 +2,7 @@ "Image": "registry.gitlab.com/oktw-network/galaxy", "PullSecret": "", "Type": "GALAXY", - "ResourcePack": "", + "ResourcePacks": ["base"], "Resource": { "CPULimit": "4000m", "CPURequest": "300m", diff --git a/src/main/resources/config/resource_packs.json b/src/main/resources/config/resource_packs.json new file mode 100644 index 0000000..a42d852 --- /dev/null +++ b/src/main/resources/config/resource_packs.json @@ -0,0 +1,4 @@ +{ + "base": "", + "lobby": "" +}