Skip to content

Commit 10fd7db

Browse files
fix(generic): apply resource pack during configuration phase
The pack was pushed after spawn, forcing a mid-game resource reload while world data streamed in. Chunk sections received during that reload are never rendered by the client even after a manual chunk rebuild, which made generated dungeon instances appear invisible. The push now happens in the configuration phase and blocks until the client reports a terminal pack status, matching how Hypixel applies theirs before any world data is sent.
1 parent 5b68e85 commit 10fd7db

3 files changed

Lines changed: 30 additions & 1 deletion

File tree

type.generic/src/main/java/net/swofty/type/generic/event/actions/data/ActionPlayerDataLoad.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,11 @@ public class ActionPlayerDataLoad implements HypixelEventClass {
1717
public void run(AsyncPlayerConfigurationEvent event) {
1818
HypixelPlayer player = (HypixelPlayer) event.getPlayer();
1919
PlayerFlow.run(player, "generic-data/load", () -> GenericPlayerDataFlow.load(player));
20+
21+
var packManager = net.swofty.type.generic.HypixelConst.getResourcePackManager();
22+
if (packManager != null) {
23+
PlayerFlow.run(player, "generic-data/resource-pack",
24+
() -> packManager.sendPackBlocking(player, 25));
25+
}
2026
}
2127
}

type.generic/src/main/java/net/swofty/type/generic/resourcepack/ResourcePackManager.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@ public void initialize() {
2727
}
2828

2929
public void sendPack(Player player) {
30+
sendPackBlocking(player, 0);
31+
}
32+
33+
/**
34+
* Pushes the pack and, when {@code timeoutSeconds > 0}, waits for the client's
35+
* terminal pack status. The pack must finish applying during the configuration
36+
* phase, before any world data streams: a mid-game resource reload leaves
37+
* already-received chunk sections permanently unrendered on the client.
38+
*/
39+
public void sendPackBlocking(Player player, int timeoutSeconds) {
3040
String packUrl = activePack.getPackUrl();
3141
String packHash = activePack.getPackHash();
3242

@@ -41,13 +51,27 @@ public void sendPack(Player player) {
4151
packHash
4252
);
4353

54+
java.util.concurrent.CompletableFuture<Void> resolved = new java.util.concurrent.CompletableFuture<>();
4455
ResourcePackRequest request = ResourcePackRequest.resourcePackRequest()
4556
.packs(info)
4657
.replace(true)
4758
.required(activePack.isRequired())
4859
.prompt(Component.text("§aThis resource pack is required to play on Hypixel."))
60+
.callback((packId, status, audience) -> {
61+
if (status.intermediate()) return;
62+
resolved.complete(null);
63+
})
4964
.build();
5065

5166
player.sendResourcePacks(request);
67+
68+
if (timeoutSeconds > 0) {
69+
try {
70+
resolved.get(timeoutSeconds, java.util.concurrent.TimeUnit.SECONDS);
71+
} catch (Exception exception) {
72+
Logger.warn("Resource pack for {} did not resolve within {}s, continuing",
73+
player.getUsername(), timeoutSeconds);
74+
}
75+
}
5276
}
5377
}

type.generic/src/main/java/net/swofty/type/generic/user/flow/GenericPlayerDataFlow.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ public static void postSpawn(HypixelPlayer player) {
7070

7171
ResourcePackManager packManager = HypixelConst.getResourcePackManager();
7272
if (packManager != null) {
73-
packManager.sendPack(player);
7473
packManager.getActivePack().onPlayerJoin(player);
7574
}
7675

0 commit comments

Comments
 (0)