From 19c19929f0e8bb5d724f94aadfedf07009f165ba Mon Sep 17 00:00:00 2001 From: jimchen5209 Date: Sun, 25 Aug 2024 16:52:22 +0800 Subject: [PATCH 1/6] feat: try send multi resource packs --- src/main/kotlin/one/oktw/galaxy/proxy/Main.kt | 6 ++-- .../oktw/galaxy/proxy/config/ConfigManager.kt | 29 ++++++++++++------ .../galaxy/proxy/config/model/GalaxySpec.kt | 4 ++- .../galaxy/proxy/resourcepack/ResourcePack.kt | 9 +++++- .../proxy/resourcepack/ResourcePackHelper.kt | 30 ++++++++++++------- src/main/resources/config/galaxies/lobby.json | 2 +- .../config/galaxies/normal_galaxy.json | 2 +- src/main/resources/config/resource_packs.json | 4 +++ 8 files changed, 60 insertions(+), 26 deletions(-) create mode 100644 src/main/resources/config/resource_packs.json 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..e55bead 100644 --- a/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePack.kt +++ b/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePack.kt @@ -19,8 +19,10 @@ package one.oktw.galaxy.proxy.resourcepack import com.google.common.hash.Hashing +import com.velocitypowered.api.proxy.player.ResourcePackInfo 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 +34,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(): ResourcePackInfo = 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..e5d93aa --- /dev/null +++ b/src/main/resources/config/resource_packs.json @@ -0,0 +1,4 @@ +{ + "base": "", + "lobby": "" +} From 5038ff7f73483ee82e4f807cb803c0a297046c4b Mon Sep 17 00:00:00 2001 From: jimchen5209 Date: Sun, 25 Aug 2024 19:39:53 +0800 Subject: [PATCH 2/6] fix: appliedResourcePacks in api is not ordered --- src/main/kotlin/one/oktw/galaxy/proxy/Main.kt | 13 +++++-- .../proxy/resourcepack/ResourcePackHelper.kt | 35 +++++++++++-------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/main/kotlin/one/oktw/galaxy/proxy/Main.kt b/src/main/kotlin/one/oktw/galaxy/proxy/Main.kt index 2d6b869..a0be7fa 100644 --- a/src/main/kotlin/one/oktw/galaxy/proxy/Main.kt +++ b/src/main/kotlin/one/oktw/galaxy/proxy/Main.kt @@ -2,6 +2,7 @@ package one.oktw.galaxy.proxy import com.google.inject.Inject import com.velocitypowered.api.event.Subscribe +import com.velocitypowered.api.event.connection.DisconnectEvent import com.velocitypowered.api.event.player.KickedFromServerEvent import com.velocitypowered.api.event.player.ServerPostConnectEvent import com.velocitypowered.api.event.player.ServerPreConnectEvent @@ -53,6 +54,7 @@ class Main : CoroutineScope by CoroutineScope(Dispatchers.Default + SupervisorJo private set lateinit var manager: Manager private set + lateinit var resourcePackHelper: ResourcePackHelper @Inject fun init(proxy: ProxyServer, logger: Logger) { @@ -63,6 +65,7 @@ class Main : CoroutineScope by CoroutineScope(Dispatchers.Default + SupervisorJo this.config = ConfigManager() this.kubernetesClient = KubernetesClient() this.redisClient = RedisClient() + this.resourcePackHelper = ResourcePackHelper() manager = Manager(config.redisConfig.URI, config.redisConfig.PubSubPrefix) manager.subscribe(MESSAGE_TOPIC) @@ -113,14 +116,20 @@ class Main : CoroutineScope by CoroutineScope(Dispatchers.Default + SupervisorJo it.result = ServerPreConnectEvent.ServerResult.allowed(lobby) } + // Remove player on disconnect + proxy.eventManager.register(this, DisconnectEvent::class.java) { + this.resourcePackHelper.removePlayer(it.player) + } + + // Update resourcepacks @Suppress("UnstableApiUsage") proxy.eventManager.register(this, ServerPostConnectEvent::class.java) { // TODO: Get Galaxy Type if (it.player.currentServer.get().serverInfo.name == "galaxy-lobby") { - ResourcePackHelper.updatePlayerResourcePacks(it.player, "lobby") + this.resourcePackHelper.updatePlayerResourcePacks(it.player, "lobby") } else { if (it.previousServer?.serverInfo?.name != "galaxy-lobby") return@register - ResourcePackHelper.updatePlayerResourcePacks(it.player, "normal_galaxy") + this.resourcePackHelper.updatePlayerResourcePacks(it.player, "normal_galaxy") } } 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 ad298c5..e6e2212 100644 --- a/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackHelper.kt +++ b/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackHelper.kt @@ -6,25 +6,30 @@ import one.oktw.galaxy.proxy.Main.Companion.main import kotlin.math.max class ResourcePackHelper { - 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() + private val appliedPacks: MutableMap> = mutableMapOf() - var skipFurtherCheck = false - val packsToQueue = mutableListOf() - val packsToRemove = mutableListOf() + fun updatePlayerResourcePacks(player: Player, galaxy: String) { + val targetResourcePacks = main.config.galaxies[galaxy]?.ResourcePacks?.distinct()?.mapNotNull { main.config.resourcePacks[it]?.packInfo() } ?: return + val appliedResourcePacks = this.appliedPacks.getOrPut(player) { listOf() } - for (index in 0..max(targetResourcePacks.size, appliedResourcePacks.size)) { - if (targetResourcePacks.getOrNull(index)?.hash.contentEquals(appliedResourcePacks.getOrNull(index)?.hash) && !skipFurtherCheck) continue + var skipFurtherCheck = false + val packsToQueue = mutableListOf() + val packsToRemove = mutableListOf() - skipFurtherCheck = true - if (index < appliedResourcePacks.size) packsToRemove.add(appliedResourcePacks[index]) - if (index < targetResourcePacks.size) packsToQueue.add(targetResourcePacks[index]) - } + for (index in 0..max(targetResourcePacks.size, appliedResourcePacks.size)) { + if (targetResourcePacks.getOrNull(index)?.id == appliedResourcePacks.getOrNull(index)?.id && !skipFurtherCheck) continue - packsToRemove.forEach { pack -> player.removeResourcePacks(pack) } - packsToQueue.forEach { pack -> player.sendResourcePacks(pack) } + 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) } + appliedPacks[player] = targetResourcePacks.toList() + } + + fun removePlayer(player: Player) { + appliedPacks.remove(player) } } From 8621198122b3c784d08200bd722809ef6676cdb1 Mon Sep 17 00:00:00 2001 From: jimchen5209 Date: Sun, 10 Nov 2024 18:57:57 +0800 Subject: [PATCH 3/6] refactor: add more var --- .../kotlin/one/oktw/galaxy/proxy/config/ConfigManager.kt | 3 ++- .../one/oktw/galaxy/proxy/resourcepack/ResourcePackHelper.kt | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) 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 2f96971..330caf2 100644 --- a/src/main/kotlin/one/oktw/galaxy/proxy/config/ConfigManager.kt +++ b/src/main/kotlin/one/oktw/galaxy/proxy/config/ConfigManager.kt @@ -57,7 +57,8 @@ class ConfigManager(private val basePath: Path = Paths.get("config")) { if (Files.isDirectory(file) || !Files.isReadable(file)) return@forEach Files.newBufferedReader(file).use { json -> - galaxies[file.fileName.toString().substringBeforeLast(".")] = gson.fromJson(json, GalaxySpec::class.java) + val galaxyName = file.fileName.toString().substringBeforeLast(".") + galaxies[galaxyName] = gson.fromJson(json, GalaxySpec::class.java) } } } 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 e6e2212..04af5f5 100644 --- a/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackHelper.kt +++ b/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackHelper.kt @@ -17,7 +17,10 @@ class ResourcePackHelper { val packsToRemove = mutableListOf() for (index in 0..max(targetResourcePacks.size, appliedResourcePacks.size)) { - if (targetResourcePacks.getOrNull(index)?.id == appliedResourcePacks.getOrNull(index)?.id && !skipFurtherCheck) continue + // Skip applied pack on same position + val targetPack = targetResourcePacks.getOrNull(index) + val appliedPack = appliedResourcePacks.getOrNull(index) + if (targetPack?.id == appliedPack?.id && !skipFurtherCheck) continue skipFurtherCheck = true if (index < appliedResourcePacks.size) packsToRemove.add(appliedResourcePacks[index]) From 7a0c0e4c6528ab4eac295bdb4cdfc68c5c99c869 Mon Sep 17 00:00:00 2001 From: James58899 Date: Sun, 10 Nov 2024 18:53:14 +0800 Subject: [PATCH 4/6] Rename ResourcePackHelper to ResourcePackManager --- src/main/kotlin/one/oktw/galaxy/proxy/Main.kt | 13 +++++++------ ...ResourcePackHelper.kt => ResourcePackManager.kt} | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) rename src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/{ResourcePackHelper.kt => ResourcePackManager.kt} (98%) diff --git a/src/main/kotlin/one/oktw/galaxy/proxy/Main.kt b/src/main/kotlin/one/oktw/galaxy/proxy/Main.kt index a0be7fa..286d8c8 100644 --- a/src/main/kotlin/one/oktw/galaxy/proxy/Main.kt +++ b/src/main/kotlin/one/oktw/galaxy/proxy/Main.kt @@ -24,7 +24,7 @@ import one.oktw.galaxy.proxy.event.TabListUpdater import one.oktw.galaxy.proxy.kubernetes.KubernetesClient import one.oktw.galaxy.proxy.pubsub.Manager import one.oktw.galaxy.proxy.redis.RedisClient -import one.oktw.galaxy.proxy.resourcepack.ResourcePackHelper +import one.oktw.galaxy.proxy.resourcepack.ResourcePackManager import org.slf4j.Logger import java.net.InetSocketAddress import kotlin.system.exitProcess @@ -54,7 +54,8 @@ class Main : CoroutineScope by CoroutineScope(Dispatchers.Default + SupervisorJo private set lateinit var manager: Manager private set - lateinit var resourcePackHelper: ResourcePackHelper + lateinit var resourcePackManager: ResourcePackManager + private set @Inject fun init(proxy: ProxyServer, logger: Logger) { @@ -65,7 +66,7 @@ class Main : CoroutineScope by CoroutineScope(Dispatchers.Default + SupervisorJo this.config = ConfigManager() this.kubernetesClient = KubernetesClient() this.redisClient = RedisClient() - this.resourcePackHelper = ResourcePackHelper() + this.resourcePackManager = ResourcePackManager() manager = Manager(config.redisConfig.URI, config.redisConfig.PubSubPrefix) manager.subscribe(MESSAGE_TOPIC) @@ -118,18 +119,18 @@ class Main : CoroutineScope by CoroutineScope(Dispatchers.Default + SupervisorJo // Remove player on disconnect proxy.eventManager.register(this, DisconnectEvent::class.java) { - this.resourcePackHelper.removePlayer(it.player) + this.resourcePackManager.removePlayer(it.player) } // Update resourcepacks @Suppress("UnstableApiUsage") proxy.eventManager.register(this, ServerPostConnectEvent::class.java) { // TODO: Get Galaxy Type if (it.player.currentServer.get().serverInfo.name == "galaxy-lobby") { - this.resourcePackHelper.updatePlayerResourcePacks(it.player, "lobby") + this.resourcePackManager.updatePlayerResourcePacks(it.player, "lobby") } else { if (it.previousServer?.serverInfo?.name != "galaxy-lobby") return@register - this.resourcePackHelper.updatePlayerResourcePacks(it.player, "normal_galaxy") + this.resourcePackManager.updatePlayerResourcePacks(it.player, "normal_galaxy") } } diff --git a/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackHelper.kt b/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackManager.kt similarity index 98% rename from src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackHelper.kt rename to src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackManager.kt index 04af5f5..ad328e7 100644 --- a/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackHelper.kt +++ b/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackManager.kt @@ -5,7 +5,7 @@ import com.velocitypowered.api.proxy.player.ResourcePackInfo import one.oktw.galaxy.proxy.Main.Companion.main import kotlin.math.max -class ResourcePackHelper { +class ResourcePackManager { private val appliedPacks: MutableMap> = mutableMapOf() fun updatePlayerResourcePacks(player: Player, galaxy: String) { From 048c1f0fb5906367bc95e6c5c72db00a773b8e40 Mon Sep 17 00:00:00 2001 From: James58899 Date: Sun, 10 Nov 2024 18:54:13 +0800 Subject: [PATCH 5/6] Change GalaxySpec ResourcePacks from List to Set --- .../kotlin/one/oktw/galaxy/proxy/config/model/GalaxySpec.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 2883482..9629968 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,9 +4,7 @@ data class GalaxySpec( val Image: String, val PullSecret: String, val Type: GalaxyType, - // 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 ResourcePacks: Set, val Resource: GalaxyResource? = null, val Storage: GalaxyStorage? = null ) { From bc708bad81b94fe2bb7ea3571a378cf932d57c89 Mon Sep 17 00:00:00 2001 From: James58899 Date: Sun, 10 Nov 2024 18:56:33 +0800 Subject: [PATCH 6/6] Refactor update player resource packs --- .../proxy/resourcepack/ResourcePackManager.kt | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackManager.kt b/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackManager.kt index ad328e7..81a10bb 100644 --- a/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackManager.kt +++ b/src/main/kotlin/one/oktw/galaxy/proxy/resourcepack/ResourcePackManager.kt @@ -3,35 +3,35 @@ 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 +import kotlin.math.min class ResourcePackManager { private val appliedPacks: MutableMap> = mutableMapOf() fun updatePlayerResourcePacks(player: Player, galaxy: String) { - val targetResourcePacks = main.config.galaxies[galaxy]?.ResourcePacks?.distinct()?.mapNotNull { main.config.resourcePacks[it]?.packInfo() } ?: return - val appliedResourcePacks = this.appliedPacks.getOrPut(player) { listOf() } - - var skipFurtherCheck = false - val packsToQueue = mutableListOf() - val packsToRemove = mutableListOf() - - for (index in 0..max(targetResourcePacks.size, appliedResourcePacks.size)) { - // Skip applied pack on same position - val targetPack = targetResourcePacks.getOrNull(index) - val appliedPack = appliedResourcePacks.getOrNull(index) - if (targetPack?.id == appliedPack?.id && !skipFurtherCheck) continue - - skipFurtherCheck = true - if (index < appliedResourcePacks.size) packsToRemove.add(appliedResourcePacks[index]) - if (index < targetResourcePacks.size) packsToQueue.add(targetResourcePacks[index]) + val new = main.config.galaxies[galaxy]?.ResourcePacks?.mapNotNull { main.config.resourcePacks[it]?.packInfo() } ?: emptyList() + val old = this.appliedPacks.getOrElse(player) { listOf() } + + // Matching new resource packs + var updateIndex = old.lastIndex + for (i in 0..min(old.size, new.size)) { + if (old.getOrNull(i)?.hash != new.getOrNull(i)?.hash) { + updateIndex = i + break + } } - packsToRemove.forEach { pack -> player.removeResourcePacks(pack) } - packsToQueue.forEach { pack -> player.sendResourcePacks(pack) } - appliedPacks[player] = targetResourcePacks.toList() + // Remove not match resource packs + old.subList(updateIndex, old.size).forEach(player::removeResourcePacks) + + // Add new resource packs + new.subList(updateIndex, new.size).forEach(player::sendResourcePacks) + + // Save player resource packs state + appliedPacks[player] = new.toList() } + // Remove player resource packs state fun removePlayer(player: Player) { appliedPacks.remove(player) }