105105import java .util .ArrayList ;
106106import java .util .Arrays ;
107107import java .util .Collection ;
108+ import java .util .HashMap ;
108109import java .util .List ;
109110import java .util .Map ;
111+ import java .util .Objects ;
110112import java .util .Set ;
111113import java .util .UUID ;
112114import java .util .concurrent .CompletableFuture ;
@@ -183,24 +185,24 @@ public void initialize(MinecraftServer server) {
183185 MinecraftServer .getCommandManager ().register (command .getCommand ());
184186 } catch (Exception e ) {
185187 Logger .error (e , "Failed to register command {} in class {}" ,
186- command .getCommand ().getName (), command .getClass ().getSimpleName ());
188+ command .getCommand ().getName (), command .getClass ().getSimpleName ());
187189 }
188190 });
189191
190192 loopThroughPackage ("net.swofty.type.skyblockgeneric.abiphone.impl" , AbiphoneNPC .class )
191- .forEach (AbiphoneRegistry ::registerContact );
193+ .forEach (AbiphoneRegistry ::registerContact );
192194
193195 // Register entities
194196 loopThroughPackage ("net.swofty.type.skyblockgeneric.entity.mob.mobs" , SkyBlockMob .class )
195- .forEach (mob -> MobRegistry .registerExtraMob (mob .getClass ()));
197+ .forEach (mob -> MobRegistry .registerExtraMob (mob .getClass ()));
196198
197199 MathUtility .delay (() -> SkyBlockMob .runRegionPopulators (MinecraftServer .getSchedulerManager ()), 50 );
198200
199201 /**
200202 * Start generic SkyBlock tablist
201203 */
202204 MinecraftServer .getGlobalEventHandler ().addListener (ServerTickMonitorEvent .class , event ->
203- HypixelGenericLoader .LAST_TICK .set (event .getTickMonitor ()));
205+ HypixelGenericLoader .LAST_TICK .set (event .getTickMonitor ()));
204206 BenchmarkManager benchmarkManager = MinecraftServer .getBenchmarkManager ();
205207 benchmarkManager .enable (Duration .ofDays (3 ));
206208 MinecraftServer .getSchedulerManager ().buildTask (() -> {
@@ -221,42 +223,42 @@ public void initialize(MinecraftServer server) {
221223 }
222224
223225 final Component header = Component .text ("§bYou are playing on §e§lMC.HYPIXEL.NET" )
224- .append (Component .newline ())
225- .append (Component .text ("§7RAM USAGE: §8" + ramUsage + " MB" ))
226- .append (Component .newline ())
227- .append (Component .text ("§7TPS: §8" + TPS ))
228- .append (Component .newline ());
226+ .append (Component .newline ())
227+ .append (Component .text ("§7RAM USAGE: §8" + ramUsage + " MB" ))
228+ .append (Component .newline ())
229+ .append (Component .text ("§7TPS: §8" + TPS ))
230+ .append (Component .newline ());
229231
230232 // Send per-player footer with their active effects
231233 for (SkyBlockPlayer player : players ) {
232234 Component footer = Component .newline ()
233- .append (Component .text ("§a§lActive Effects" ))
234- .append (Component .newline ());
235+ .append (Component .text ("§a§lActive Effects" ))
236+ .append (Component .newline ());
235237
236238 List <TemporaryStatistic > activeEffects = player .getStatistics ().getDisplayableActiveEffects ();
237239 if (activeEffects .isEmpty ()) {
238240 footer = footer .append (Component .text ("§7No effects active. Drink potions or splash them on the" ))
239- .append (Component .newline ())
240- .append (Component .text ("§7ground to buff yourself!" ));
241+ .append (Component .newline ())
242+ .append (Component .text ("§7ground to buff yourself!" ));
241243 } else {
242244 for (TemporaryStatistic effect : activeEffects ) {
243245 String color = effect .getDisplayColor () != null ? effect .getDisplayColor () : "§7" ;
244246 String name = effect .getDisplayName ();
245247 String duration = formatEffectDuration (effect .getRemainingMs ());
246248 footer = footer .append (Component .text (color + name + " §f" + duration ))
247- .append (Component .newline ());
249+ .append (Component .newline ());
248250 }
249251 }
250252
251253 footer = footer .append (Component .newline ())
252- .append (Component .text ("§d§lCookie Buff" ))
253- .append (Component .newline ())
254- .append (Component .text ("§7Not active! Obtain booster cookies from the community" ))
255- .append (Component .newline ())
256- .append (Component .text ("§7shop in the hub." ))
257- .append (Component .newline ())
258- .append (Component .newline ())
259- .append (Component .text ("§aRanks, Boosters & MORE! §c§lSTORE.HYPIXEL.NET" ));
254+ .append (Component .text ("§d§lCookie Buff" ))
255+ .append (Component .newline ())
256+ .append (Component .text ("§7Not active! Obtain booster cookies from the community" ))
257+ .append (Component .newline ())
258+ .append (Component .text ("§7shop in the hub." ))
259+ .append (Component .newline ())
260+ .append (Component .newline ())
261+ .append (Component .text ("§aRanks, Boosters & MORE! §c§lSTORE.HYPIXEL.NET" ));
260262
261263 player .sendPlayerListHeaderAndFooter (header , footer );
262264 }
@@ -296,20 +298,20 @@ public void initialize(MinecraftServer server) {
296298 * Register packet event
297299 */
298300 loopThroughPackage ("net.swofty.type.skyblockgeneric.packets.client" , HypixelPacketClientListener .class )
299- .forEach (HypixelPacketClientListener ::cacheListener );
301+ .forEach (HypixelPacketClientListener ::cacheListener );
300302 loopThroughPackage ("net.swofty.type.skyblockgeneric.packets.server" , HypixelPacketServerListener .class )
301- .forEach (HypixelPacketServerListener ::cacheListener );
303+ .forEach (HypixelPacketServerListener ::cacheListener );
302304 HypixelPacketClientListener .register (HypixelConst .getEventHandler ());
303305 HypixelPacketServerListener .register (HypixelConst .getEventHandler ());
304306
305307 // Load regions
306308 SkyBlockRegion .cacheRegions ();
307309 SkyBlockRegenConfiguration .startRepeater (MinecraftServer .getSchedulerManager ());
308310 MinecraftServer .getDimensionTypeRegistry ().register (
309- Key .key ("skyblock:island" ),
310- DimensionType .builder ()
311- .ambientLight (1 )
312- .build ());
311+ Key .key ("skyblock:island" ),
312+ DimensionType .builder ()
313+ .ambientLight (1 )
314+ .build ());
313315 SkyBlockIsland .runVacantLoop (MinecraftServer .getSchedulerManager ());
314316
315317 SkyBlockRegion .getRegions ().forEach (region -> {
@@ -374,13 +376,13 @@ public void initialize(MinecraftServer server) {
374376 SkyBlockItem item = new SkyBlockItem (type );
375377 ServerOrbComponent asCrystal = item .getComponent (ServerOrbComponent .class );
376378 ServerCrystalImpl crystalImpl = new ServerCrystalImpl (
377- asCrystal .getSpawnMaterialFunction (),
378- crystal .url ,
379- asCrystal .getValidBlocks ()
379+ asCrystal .getSpawnMaterialFunction (),
380+ crystal .url ,
381+ asCrystal .getValidBlocks ()
380382 );
381383
382384 crystalImpl .setInstance (HypixelConst .getInstanceContainer (),
383- new Pos (crystal .position .x (), crystal .position .y (), crystal .position .z ()));
385+ new Pos (crystal .position .x (), crystal .position .y (), crystal .position .z ()));
384386 });
385387 });
386388 }
@@ -401,23 +403,23 @@ public void initialize(MinecraftServer server) {
401403
402404 // Register missions
403405 loopThroughPackage ("net.swofty.type.skyblockgeneric.mission.missions" , SkyBlockMission .class )
404- .forEach ((event ) -> {
405- MissionData .registerMission (event .getClass ());
406- });
406+ .forEach ((event ) -> {
407+ MissionData .registerMission (event .getClass ());
408+ });
407409 loopThroughPackage ("net.swofty.type.skyblockgeneric.mission.missions" , MissionRepeater .class )
408- .forEach ((event ) -> {
409- event .getTask (MinecraftServer .getSchedulerManager ());
410- });
410+ .forEach ((event ) -> {
411+ event .getTask (MinecraftServer .getSchedulerManager ());
412+ });
411413 loopThroughPackage ("net.swofty.type.skyblockgeneric.item.set.sets" , SetRepeatable .class )
412- .forEach ((event ) -> {
413- event .getTask (MinecraftServer .getSchedulerManager ());
414- });
414+ .forEach ((event ) -> {
415+ event .getTask (MinecraftServer .getSchedulerManager ());
416+ });
415417 loopThroughPackage ("net.swofty.type.skyblockgeneric.enchantment.impl" , SkyBlockValueEvent .class )
416- .forEach (SkyBlockValueEvent ::cacheEvent );
418+ .forEach (SkyBlockValueEvent ::cacheEvent );
417419 loopThroughPackage ("net.swofty.type.skyblockgeneric.item.set.sets" , SkyBlockValueEvent .class )
418- .forEach (SkyBlockValueEvent ::cacheEvent );
420+ .forEach (SkyBlockValueEvent ::cacheEvent );
419421 loopThroughPackage ("net.swofty.type.skyblockgeneric.item.events" , SkyBlockValueEvent .class )
420- .forEach (SkyBlockValueEvent ::cacheEvent );
422+ .forEach (SkyBlockValueEvent ::cacheEvent );
421423 SkyBlockValueEvent .register (); // Value events are SkyBlock-specific
422424 CustomEventCaller .start (); // Value events are SkyBlock-specific
423425 HypixelEventHandler .register (HypixelConst .getEventHandler ());
@@ -465,17 +467,17 @@ public void initialize(MinecraftServer server) {
465467 recipeInstance .setCanCraft ((player ) -> {
466468 int amount = player .getCollection ().get (collection .type ());
467469 return new SkyBlockRecipe .CraftingResult (
468- amount >= reward .requirement (),
469- new String []{"§7You must have §c" + collection .type ().getDisplayName ()
470- + " Collection "
471- + StringUtility .getAsRomanNumeral (collection .getPlacementOf (reward ))}
470+ amount >= reward .requirement (),
471+ new String []{"§7You must have §c" + collection .type ().getDisplayName ()
472+ + " Collection "
473+ + StringUtility .getAsRomanNumeral (collection .getPlacementOf (reward ))}
472474 );
473475 });
474476 recipes .add (recipeInstance );
475477 });
476478 } catch (Exception e ) {
477479 Logger .error (e , "Failed to parse collection recipe for {} with requirement {}" ,
478- collection .type (), reward .requirement ());
480+ collection .type (), reward .requirement ());
479481 }
480482 }
481483 });
@@ -496,7 +498,7 @@ public void initialize(MinecraftServer server) {
496498 Arrays .stream (reward .unlocks ()).forEach (unlock -> {
497499 if (unlock instanceof CollectionCategory .UnlockCustomAward award ) {
498500 CustomCollectionAward .AWARD_CACHE .put (award .getAward (),
499- Map .entry (collection .type (), reward .requirement ()));
501+ Map .entry (collection .type (), reward .requirement ()));
500502 }
501503 });
502504 });
@@ -557,17 +559,17 @@ public void initialize(MinecraftServer server) {
557559 public static List <SkyBlockPlayer > getLoadedPlayers () {
558560 List <SkyBlockPlayer > players = new ArrayList <>();
559561 MinecraftServer .getConnectionManager ().getOnlinePlayers ()
560- .stream ()
561- .filter (player -> {
562- try {
563- SkyBlockDataHandler .getUser (player .getUuid ());
564- } catch (Exception e ) {
565- return false ;
566- }
567- return true ;
568- })
569- .filter (player -> player .getInstance () != null )
570- .forEach (player -> players .add ((SkyBlockPlayer ) player ));
562+ .stream ()
563+ .filter (player -> {
564+ try {
565+ SkyBlockDataHandler .getUser (player .getUuid ());
566+ } catch (Exception e ) {
567+ return false ;
568+ }
569+ return true ;
570+ })
571+ .filter (player -> player .getInstance () != null )
572+ .forEach (player -> players .add ((SkyBlockPlayer ) player ));
571573 return players ;
572574 }
573575
@@ -584,20 +586,18 @@ public static <T> Stream<T> loopThroughPackage(String packageName, Class<T> claz
584586 Set <Class <? extends T >> subTypes = reflections .getSubTypesOf (clazz );
585587
586588 return subTypes .stream ()
587- .map (subClass -> {
588- try {
589- return clazz .cast (subClass .getDeclaredConstructor ().newInstance ());
590- } catch (InstantiationException | IllegalAccessException | NoSuchMethodException |
591- InvocationTargetException e ) {
592- return null ;
593- }
594- })
595- .filter (java . util . Objects ::nonNull );
589+ .map (subClass -> {
590+ try {
591+ return clazz .cast (subClass .getDeclaredConstructor ().newInstance ());
592+ } catch (InstantiationException | IllegalAccessException | NoSuchMethodException |
593+ InvocationTargetException e ) {
594+ return null ;
595+ }
596+ })
597+ .filter (Objects ::nonNull );
596598 }
597599
598- private void setBiome (int x , int y , int z , RegistryKey <Biome > biome ) {
599- CompletableFuture <Chunk > chunk = HypixelConst .getInstanceContainer ().loadChunk (CoordConversion .globalToChunk (x ), CoordConversion .globalToChunk (z ));
600- chunk .thenAccept ((c ) -> c .setBiome (x , y , z , biome ));
600+ private record ChunkKey (int chunkX , int chunkZ ) {
601601 }
602602
603603 private void setBiome (Pos start , Pos end , RegistryKey <Biome > biome ) {
@@ -610,11 +610,48 @@ private void setBiome(Pos start, Pos end, RegistryKey<Biome> biome) {
610610 int minZ = Math .min (start .blockZ (), end .blockZ ());
611611 int maxZ = Math .max (start .blockZ (), end .blockZ ());
612612
613- for (int x = minX ; x <= maxX ; x ++) {
614- for (int y = minY ; y <= maxY ; y ++) {
615- for (int z = minZ ; z <= maxZ ; z ++) {
616- setBiome (x , y , z , biome );
617- }
613+ int minChunkX = CoordConversion .globalToChunk (minX );
614+ int maxChunkX = CoordConversion .globalToChunk (maxX );
615+ int minChunkZ = CoordConversion .globalToChunk (minZ );
616+ int maxChunkZ = CoordConversion .globalToChunk (maxZ );
617+
618+ Map <ChunkKey , CompletableFuture <Chunk >> loadedChunks = new HashMap <>();
619+
620+ for (int chunkX = minChunkX ; chunkX <= maxChunkX ; chunkX ++) {
621+ for (int chunkZ = minChunkZ ; chunkZ <= maxChunkZ ; chunkZ ++) {
622+ ChunkKey key = new ChunkKey (chunkX , chunkZ );
623+
624+ CompletableFuture <Chunk > chunkFuture = loadedChunks .computeIfAbsent (
625+ key ,
626+ k -> HypixelConst .getInstanceContainer ().loadChunk (k .chunkX (), k .chunkZ ())
627+ );
628+
629+ final int chunkStartX = chunkX << 4 ;
630+ final int chunkStartZ = chunkZ << 4 ;
631+ final int chunkEndX = chunkStartX + 15 ;
632+ final int chunkEndZ = chunkStartZ + 15 ;
633+
634+ final boolean fullChunkX = minX <= chunkStartX && maxX >= chunkEndX ;
635+ final boolean fullChunkZ = minZ <= chunkStartZ && maxZ >= chunkEndZ ;
636+
637+ final int startXInChunk = fullChunkX ? 0 : Math .max (0 , minX - chunkStartX );
638+ final int endXInChunk = fullChunkX ? 15 : Math .min (15 , maxX - chunkStartX );
639+
640+ final int startZInChunk = fullChunkZ ? 0 : Math .max (0 , minZ - chunkStartZ );
641+ final int endZInChunk = fullChunkZ ? 15 : Math .min (15 , maxZ - chunkStartZ );
642+
643+ chunkFuture .thenAccept (chunk -> {
644+ for (int localX = startXInChunk ; localX <= endXInChunk ; localX += 4 ) {
645+ int worldX = chunkStartX + localX ;
646+
647+ for (int y = minY ; y <= maxY ; y += 4 ) {
648+ for (int localZ = startZInChunk ; localZ <= endZInChunk ; localZ += 4 ) {
649+ int worldZ = chunkStartZ + localZ ;
650+ chunk .setBiome (worldX , y , worldZ , biome );
651+ }
652+ }
653+ }
654+ });
618655 }
619656 }
620657 }
0 commit comments