Files
Documentation/content/patch-note/2026.01.15-c04fdfe10-2026.01.16-c508b9acd-prerelease-patch-note.md
2026-01-20 20:33:59 +01:00

1220 lines
43 KiB
Markdown

# Patch Notes: Hytale Server (Pre-release)
## Version 2026.01.15-c04fdfe10 → 2026.01.16-c508b9acd
**Date de release** : 16 janvier 2026 (Pre-release)
**Build précédent** : `c04fdfe10` (15 janvier 2026)
**Build actuel** : `c508b9acd` (16 janvier 2026)
---
## Statistiques
| Métrique | Valeur |
|----------|--------|
| Fichiers modifiés | 169 |
| Insertions | +1604 |
| Suppressions | -994 |
| Delta net | +610 lignes |
---
## Table des matières
1. [Authentification - ProfileServiceClient (NOUVEAU)](#1-authentification---profileserviceclient-nouveau)
2. [Authentification - ServerAuthManager Refactoring](#2-authentification---serverauthmanager-refactoring)
3. [Système de Commandes - GAME_PROFILE_LOOKUP (NOUVEAU)](#3-système-de-commandes---game_profile_lookup-nouveau)
4. [Commandes Access Control Refactorisées](#4-commandes-access-control-refactorisées)
5. [Système de Téléportation Refactorisé](#5-système-de-téléportation-refactorisé)
6. [WorldGen - BlockMaskCondition](#6-worldgen---blockmaskcondition)
7. [PrefabSaver - Async Chunk Loading](#7-prefabsaver---async-chunk-loading)
8. [ChunkStore - Thread Safety Generator](#8-chunkstore---thread-safety-generator)
9. [InteractionManager - Timing Refactoring](#9-interactionmanager---timing-refactoring)
10. [InteractionContext - Amélioration Sélection Inventaire](#10-interactioncontext---amélioration-sélection-inventaire)
11. [Système Memories - Nouvelles Fonctionnalités](#11-système-memories---nouvelles-fonctionnalités)
12. [Configuration Serveur - Suppression LocalCompression](#12-configuration-serveur---suppression-localcompression)
13. [Holder - Nouvelle méthode cloneSerializable](#13-holder---nouvelle-méthode-cloneserializable)
14. [BlockSelection - Tri et Filler Fix](#14-blockselection---tri-et-filler-fix)
15. [Corrections de Bugs](#15-corrections-de-bugs)
16. [Migration Annotations checkerframework → javax](#16-migration-annotations-checkerframework--javax)
17. [Liste complète des fichiers modifiés](#17-liste-complète-des-fichiers-modifiés)
---
## 1. Authentification - ProfileServiceClient (NOUVEAU)
**Nouveau fichier** : `com/hypixel/hytale/server/core/auth/ProfileServiceClient.java`
### 1.1 Description
Nouveau client HTTP pour le service de profils Hytale. Permet de récupérer les profils publics de joueurs par UUID ou par username.
**URL du service** : `https://account-data.hytale.com`
### 1.2 API Complète
```java
public class ProfileServiceClient {
private static final Duration REQUEST_TIMEOUT = Duration.ofSeconds(5L);
public ProfileServiceClient(@Nonnull String profileServiceUrl);
// Synchrone
@Nullable
public PublicGameProfile getProfileByUuid(@Nonnull UUID uuid, @Nonnull String bearerToken);
@Nullable
public PublicGameProfile getProfileByUsername(@Nonnull String username, @Nonnull String bearerToken);
// Asynchrone
public CompletableFuture<PublicGameProfile> getProfileByUuidAsync(@Nonnull UUID uuid, @Nonnull String bearerToken);
public CompletableFuture<PublicGameProfile> getProfileByUsernameAsync(@Nonnull String username, @Nonnull String bearerToken);
// Classe interne
public static class PublicGameProfile {
public static final BuilderCodec<PublicGameProfile> CODEC;
private UUID uuid;
private String username;
public UUID getUuid();
public String getUsername();
}
}
```
### 1.3 Endpoints
| Endpoint | Méthode | Description |
|----------|---------|-------------|
| `/profile/uuid/{uuid}` | GET | Récupère un profil par UUID |
| `/profile/username/{username}` | GET | Récupère un profil par username (URL encoded) |
### 1.4 Headers HTTP
```
Accept: application/json
Authorization: Bearer {token}
User-Agent: {AuthConfig.USER_AGENT}
```
### 1.5 Gestion des erreurs
- Timeout de 5 secondes
- Retourne `null` si HTTP status != 200
- Logging des erreurs IO, interruptions et exceptions
---
## 2. Authentification - ServerAuthManager Refactoring
**Fichier** : `com/hypixel/hytale/server/core/auth/ServerAuthManager.java`
### 2.1 Nouvelle intégration ProfileServiceClient
```java
private volatile ProfileServiceClient profileServiceClient;
@Nonnull
public ProfileServiceClient getProfileServiceClient() {
// Lazy initialization avec double-checked locking
if (this.profileServiceClient == null) {
synchronized (this) {
if (this.profileServiceClient == null) {
this.profileServiceClient = new ProfileServiceClient("https://account-data.hytale.com");
}
}
}
return this.profileServiceClient;
}
```
### 2.2 Refactoring gestion d'expiration des tokens
**Nouvelles méthodes privées** :
```java
// Calcule l'expiry effective (minimum entre session et identity token)
@Nullable
private Instant getEffectiveExpiry(@Nullable SessionServiceClient.GameSessionResponse session) {
Instant sessionExpiry = session != null ? session.getExpiresAtInstant() : null;
Instant identityExpiry = this.parseIdentityTokenExpiry(session != null ? session.identityToken : this.getIdentityToken());
if (sessionExpiry != null && identityExpiry != null) {
return sessionExpiry.isBefore(identityExpiry) ? sessionExpiry : identityExpiry;
}
return sessionExpiry != null ? sessionExpiry : identityExpiry;
}
// Parse l'expiry depuis le JWT identity token
@Nullable
private Instant parseIdentityTokenExpiry(@Nullable String idToken);
// Méthode unifiée pour définir l'expiry et planifier le refresh
private void setExpiryAndScheduleRefresh(@Nonnull Instant expiry);
```
### 2.3 Changements de signature
**Avant** :
```java
private void scheduleRefresh(int expiresInSeconds);
```
**Après** :
```java
private void setExpiryAndScheduleRefresh(@Nonnull Instant expiry);
```
### 2.4 Réorganisation des champs
```java
// Champs déplacés pour meilleure organisation
private volatile SessionServiceClient.GameProfile[] pendingProfiles;
private volatile AuthMode pendingAuthMode;
// ... maintenant au début de la classe
```
### 2.5 Fix typo
```java
// Avant
LOGGER.at(Level.INFO).log("Auto-selected profile from stroage: %s (%s)", ...);
// Après
LOGGER.at(Level.INFO).log("Auto-selected profile from storage: %s (%s)", ...);
```
### 2.6 Suppression de dépendance
```java
// Supprimé
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
```
---
## 3. Système de Commandes - GAME_PROFILE_LOOKUP (NOUVEAU)
**Fichier** : `com/hypixel/hytale/server/core/command/system/arguments/types/ArgTypes.java`
### 3.1 Nouveaux types d'arguments
```java
// Version asynchrone
public static final SingleArgumentType<CompletableFuture<ProfileServiceClient.PublicGameProfile>> GAME_PROFILE_LOOKUP_ASYNC;
// Version synchrone (bloquante)
public static final SingleArgumentType<ProfileServiceClient.PublicGameProfile> GAME_PROFILE_LOOKUP;
```
### 3.2 Logique de résolution
1. **Recherche locale** : Vérifie d'abord les joueurs connectés sur tous les mondes
2. **Parsing UUID** : Tente de parser l'input comme UUID
3. **Lookup distant** : Utilise `ProfileServiceClient` pour résoudre par UUID ou username
```java
// Pseudo-code de la logique
for (World world : Universe.get().getWorlds().values()) {
PlayerRef playerRef = NameMatching.DEFAULT.find(world.getPlayerRefs(), input, PlayerRef::getUsername);
if (playerRef != null) {
return new PublicGameProfile(playerRef.getUuid(), playerRef.getUsername());
}
}
// Fallback: lookup distant via ProfileServiceClient
```
### 3.3 Messages d'erreur
| Clé de traduction | Cas |
|-------------------|-----|
| `server.commands.parsing.argtype.playerUuidLookup.noAuth` | Pas de session token disponible |
| `server.commands.parsing.argtype.playerUuidLookup.notFound` | Joueur introuvable |
| `server.commands.parsing.argtype.playerUuidLookup.lookupError` | Erreur lors du lookup |
---
## 4. Commandes Access Control Refactorisées
### 4.1 BanCommand
**Fichier** : `com/hypixel/hytale/server/core/modules/accesscontrol/commands/BanCommand.java`
**Avant** :
```java
private final RequiredArg<String> usernameArg = this.withRequiredArg("username", "...", ArgTypes.STRING);
private final OptionalArg<String> reasonArg = this.withOptionalArg("reason", "...", ArgTypes.STRING);
// Utilisation
String username = this.usernameArg.get(context);
AuthUtil.lookupUuid(username).thenCompose(uuid -> { ... });
```
**Après** :
```java
private final RequiredArg<ProfileServiceClient.PublicGameProfile> playerArg =
this.withRequiredArg("player", "server.commands.ban.player.desc", ArgTypes.GAME_PROFILE_LOOKUP);
// Utilisation
ProfileServiceClient.PublicGameProfile profile = this.playerArg.get(context);
UUID uuid = profile.getUuid();
Message displayMessage = Message.raw(profile.getUsername()).bold(true);
```
**Changements clés** :
- Suppression de `AuthUtil.lookupUuid()` (lookup intégré dans `GAME_PROFILE_LOOKUP`)
- Affichage du nom en **gras** dans les messages
- Simplification du code (pas de chaîne `thenCompose`)
### 4.2 UnbanCommand
**Fichier** : `com/hypixel/hytale/server/core/modules/accesscontrol/commands/UnbanCommand.java`
Même refactoring que BanCommand.
### 4.3 WhitelistAddCommand
**Fichier** : `com/hypixel/hytale/server/core/modules/accesscontrol/commands/WhitelistAddCommand.java`
Même refactoring que BanCommand.
### 4.4 WhitelistRemoveCommand
**Fichier** : `com/hypixel/hytale/server/core/modules/accesscontrol/commands/WhitelistRemoveCommand.java`
Même refactoring que BanCommand.
---
## 5. Système de Téléportation Refactorisé
### 5.1 Teleport.java
**Fichier** : `com/hypixel/hytale/server/core/modules/entity/teleport/Teleport.java`
#### Nouveaux factory methods
```java
// Pour les joueurs - sépare rotation du corps et de la tête
@Nonnull
public static Teleport createForPlayer(@Nullable World world, @Nonnull Transform transform) {
Vector3f headRotation = transform.getRotation();
Vector3f bodyRotation = new Vector3f(0.0f, headRotation.getYaw(), 0.0f);
return new Teleport(world, transform.getPosition(), bodyRotation).setHeadRotation(headRotation);
}
@Nonnull
public static Teleport createForPlayer(@Nullable World world, @Nonnull Vector3d position, @Nonnull Vector3f rotation);
@Nonnull
public static Teleport createForPlayer(@Nonnull Vector3d position, @Nonnull Vector3f rotation);
@Nonnull
public static Teleport createForPlayer(@Nonnull Transform transform);
// Pour téléportation exacte (contrôle précis des rotations)
@Nonnull
public static Teleport createExact(@Nonnull Vector3d position, @Nonnull Vector3f bodyRotation, @Nonnull Vector3f headRotation);
@Nonnull
public static Teleport createExact(@Nonnull Vector3d position, @Nonnull Vector3f bodyRotation);
```
#### Constructeurs supprimés
```java
// Supprimés - remplacés par factory methods
public Teleport(@Nullable World world, @Nonnull Transform transform);
public Teleport(@Nonnull Transform transform);
```
#### Nouvelles méthodes de mutation
```java
public void setPosition(@Nonnull Vector3d position);
public void setRotation(@Nonnull Vector3f rotation);
// Renommé (anciennement withHeadRotation)
@Nonnull
public Teleport setHeadRotation(@Nonnull Vector3f headRotation) {
this.headRotation = headRotation.clone(); // Note: clone() ajouté
return this;
}
```
#### Méthodes supprimées
```java
// Supprimé
public Teleport withResetRoll();
```
### 5.2 Warp.java
**Fichier** : `com/hypixel/hytale/builtin/teleport/Warp.java`
#### Constructeur simplifié
**Avant** :
```java
public Warp(double locX, double locY, double locZ, float yaw, float pitch, float roll,
String id, @Nonnull World world, String creator, Instant creationDate) {
this.transform = new Transform(locX, locY, locZ, pitch, yaw, roll);
// ...
}
```
**Après** :
```java
public Warp(@Nonnull Transform transform, @Nonnull String id, @Nonnull World world,
@Nonnull String creator, @Nonnull Instant creationDate) {
this.transform = transform;
// ...
}
```
#### Utilisation de Teleport.createForPlayer
```java
// Avant
return new Teleport(worldInstance, this.transform);
// Après
return Teleport.createForPlayer(worldInstance, this.transform);
```
### 5.3 Commandes de téléportation mises à jour
| Fichier | Changement |
|---------|------------|
| `SpawnCommand.java` | `Teleport.createForPlayer()` |
| `SpawnSetCommand.java` | `Teleport.createForPlayer()` |
| `TeleportAllCommand.java` | `Teleport.createForPlayer()` |
| `TeleportHomeCommand.java` | `Teleport.createForPlayer()` |
| `TeleportTopCommand.java` | `Teleport.createForPlayer()` |
| `TeleportWorldCommand.java` | `Teleport.createForPlayer()` |
| `TeleportOtherToPlayerCommand.java` | `Teleport.createForPlayer()` |
| `TeleportPlayerToCoordinatesCommand.java` | `Teleport.createForPlayer()` |
| `TeleportToCoordinatesCommand.java` | `Teleport.createForPlayer()` |
| `TeleportToPlayerCommand.java` | `Teleport.createForPlayer()` |
| `WarpCommand.java` | `Teleport.createForPlayer()` |
| `WarpSetCommand.java` | `Teleport.createForPlayer()` |
---
## 6. WorldGen - BlockMaskCondition
**Fichier** : `com/hypixel/hytale/server/worldgen/util/condition/BlockMaskCondition.java`
### 6.1 Changement d'architecture
**Avant** : Interface fonctionnelle simple
```java
@FunctionalInterface
public interface BlockMaskCondition {
public boolean eval(int var1, int var2, BlockFluidEntry var3);
}
```
**Après** : Classe complète avec système de masques (+156 lignes)
```java
public class BlockMaskCondition {
public static final Mask DEFAULT_MASK;
public static final BlockMaskCondition DEFAULT_TRUE;
public static final BlockMaskCondition DEFAULT_FALSE;
@Nonnull
private Mask defaultMask = DEFAULT_MASK;
@Nonnull
private Long2ObjectMap<Mask> specificMasks = Long2ObjectMaps.emptyMap();
public void set(@Nonnull Mask defaultMask, @Nonnull Long2ObjectMap<Mask> specificMasks);
public boolean eval(int currentBlock, int currentFluid, int nextBlockId, int nextFluidId);
}
```
### 6.2 Classes internes
#### Mask
```java
public static class Mask {
private final boolean matchEmpty;
private final MaskEntry[] entries;
public Mask(@Nonnull MaskEntry[] entries);
private Mask(boolean matchEmpty, @Nonnull MaskEntry[] entries);
public boolean shouldReplace(int current, int fluid);
}
```
#### MaskEntry
Classe pour définir les conditions de remplacement basées sur :
- ID de bloc
- ID de fluide
- Tags de bloc
- Action (WHITELIST ou BLACKLIST)
### 6.3 Fichiers impactés
- `BlockPlacementMaskJsonLoader.java` (+36/-12)
- `BlockPlacementMaskRegistry.java` (+28/-8)
- `PrefabPasteUtil.java` (+8/-4)
---
## 7. PrefabSaver - Async Chunk Loading
**Fichier** : `com/hypixel/hytale/builtin/buildertools/prefabeditor/saving/PrefabSaver.java`
### 7.1 Nouveau flow asynchrone
**Avant** :
```java
@Nonnull
public static CompletableFuture<Boolean> savePrefab(...) {
return CompletableFuture.supplyAsync(() -> {
BlockSelection blockSelection = PrefabSaver.copyBlocks(...);
if (blockSelection == null) return false;
return PrefabSaver.save(...);
}, world);
}
```
**Après** :
```java
@Nonnull
public static CompletableFuture<Boolean> savePrefab(...) {
return PrefabSaver.copyBlocksAsync(...)
.thenApplyAsync(blockSelection -> {
if (blockSelection == null) return false;
return PrefabSaver.save(...);
}, (Executor)world);
}
```
### 7.2 Nouvelle méthode de préchargement
```java
@Nonnull
private static CompletableFuture<Long2ObjectMap<Ref<ChunkStore>>> preloadChunksInSelectionAsync(
@Nonnull ChunkStore chunkStore,
@Nonnull Vector3i minPoint,
@Nonnull Vector3i maxPoint
);
```
### 7.3 Méthode refactorisée
```java
// Avant (synchrone)
@Nullable
private static BlockSelection copyBlocks(...);
// Après (2 méthodes)
@Nonnull
private static CompletableFuture<BlockSelection> copyBlocksAsync(...);
@Nullable
private static BlockSelection copyBlocksWithLoadedChunks(..., @Nonnull Long2ObjectMap<Ref<ChunkStore>> loadedChunks, ...);
```
---
## 8. ChunkStore - Thread Safety Generator
**Fichier** : `com/hypixel/hytale/server/core/universe/world/storage/ChunkStore.java`
### 8.1 Nouveau lock pour le générateur
```java
private final StampedLock generatorLock = new StampedLock();
```
### 8.2 Accès thread-safe au générateur
**Avant** :
```java
@Nullable
public IWorldGen getGenerator() {
return this.generator;
}
public void setGenerator(@Nullable IWorldGen generator) {
if (this.generator != null) {
this.generator.shutdown();
}
this.generator = generator;
// ...
}
```
**Après** :
```java
@Nullable
public IWorldGen getGenerator() {
long readStamp = this.generatorLock.readLock();
try {
return this.generator;
} finally {
this.generatorLock.unlockRead(readStamp);
}
}
public void setGenerator(@Nullable IWorldGen generator) {
long writeStamp = this.generatorLock.writeLock();
try {
if (this.generator != null) {
this.generator.shutdown();
}
this.generator = generator;
// ...
} finally {
this.generatorLock.unlockWrite(writeStamp);
}
}
```
### 8.3 Nouvelle méthode
```java
public void shutdownGenerator() {
this.setGenerator(null);
}
```
### 8.4 Accès protégé dans getChunkReferenceAsync
Tous les accès à `this.generator` dans la méthode `getChunkReferenceAsync` sont maintenant protégés par `generatorLock.readLock()`.
---
## 9. InteractionManager - Timing Refactoring
**Fichier** : `com/hypixel/hytale/server/core/entity/InteractionManager.java`
### 9.1 Nouveau champ de temps
```java
private long currentTime = 1L;
```
### 9.2 Mise à jour du temps
```java
public void tick(@Nonnull Ref<EntityStore> ref, @Nonnull CommandBuffer<EntityStore> commandBuffer, float dt) {
this.currentTime += (long)commandBuffer.getExternalData().getWorld().getTickStepNanos();
// ...
}
```
### 9.3 Remplacement de System.nanoTime()
Toutes les occurrences de `System.nanoTime()` ont été remplacées par `this.currentTime` :
| Contexte | Avant | Après |
|----------|-------|-------|
| packetQueueTime | `System.nanoTime()` | `this.currentTime` |
| waitingForClientFinished | `System.nanoTime()` | `this.currentTime` |
| waitingForServerFinished | `System.nanoTime()` | `this.currentTime` |
| waitingForSyncData | `System.nanoTime()` | `this.currentTime` |
| tickTime | `System.nanoTime()` | `this.currentTime` |
| getTimeInSeconds | `System.nanoTime()` | `this.currentTime` |
**Avantage** : Le temps est maintenant basé sur les ticks du monde plutôt que sur l'horloge système, ce qui améliore la cohérence et la reproductibilité.
---
## 10. InteractionContext - Amélioration Sélection Inventaire
**Fichier** : `com/hypixel/hytale/server/core/entity/InteractionContext.java`
### 10.1 Nouveau cas de fallback
Quand les priorités d'interaction primaire et secondaire sont égales :
```java
} else {
if (type == InteractionType.Primary && !primary.getItem().getInteractions().containsKey((Object)InteractionType.Primary)) {
selectedInventory = -5;
}
if (type == InteractionType.Secondary && !primary.getItem().getInteractions().containsKey((Object)InteractionType.Secondary)) {
selectedInventory = -5;
}
}
```
**Effet** : Si l'item primaire n'a pas d'interaction du type demandé, le système utilise l'inventaire secondaire (-5).
---
## 11. Système Memories - Nouvelles Fonctionnalités
### 11.1 MemoriesPlugin.java
**Fichier** : `com/hypixel/hytale/builtin/adventure/memories/MemoriesPlugin.java`
#### Nouvelles pages UI
```java
// Nouvelle registration
OpenCustomUIInteraction.registerCustomPageSupplier(this, MemoriesUnlockedPage.class, "MemoriesUnlocked", new MemoriesUnlockedPageSuplier());
```
#### Protection shutdown
```java
@Override
protected void shutdown() {
if (!this.hasInitializedMemories) {
return; // Nouveau: évite NPE si pas initialisé
}
// ...
}
```
#### Nouvelle méthode setRecordedMemoriesCount
```java
public int setRecordedMemoriesCount(int count) {
if (count < 0) count = 0;
this.recordedMemories.lock.writeLock().lock();
try {
this.recordedMemories.memories.clear();
ObjectArrayList allAvailableMemories = new ObjectArrayList();
for (Map.Entry<String, Set<Memory>> entry : this.allMemories.entrySet()) {
allAvailableMemories.addAll(entry.getValue());
}
int actualCount = Math.min(count, allAvailableMemories.size());
for (int i = 0; i < actualCount; ++i) {
this.recordedMemories.memories.add(allAvailableMemories.get(i));
}
BsonUtil.writeSync(Constants.UNIVERSE_PATH.resolve("memories.json"), RecordedMemories.CODEC, this.recordedMemories, this.getLogger());
return actualCount;
} finally {
this.recordedMemories.lock.writeLock().unlock();
}
}
```
#### Fix calcul getMemoriesLevel
**Avant** (bug: incrémentation incorrecte):
```java
for (int i = 0; i < memoriesAmountPerLevel.length && recordedMemoriesCount >= memoriesAmountPerLevel[i]; ++i) {
memoriesLevel += i + 1;
}
```
**Après** :
```java
for (int i = memoriesAmountPerLevel.length - 1; i >= 0; --i) {
if (recordedMemoriesCount < memoriesAmountPerLevel[i]) continue;
return i + 2;
}
return memoriesLevel;
```
#### Suppression méthode
```java
// Supprimé
public int getMemoriesForNextLevel(@Nonnull GameplayConfig gameplayConfig);
```
### 11.2 NPCMemory.java
**Fichier** : `com/hypixel/hytale/builtin/adventure/memories/memories/npc/NPCMemory.java`
#### Nouvelle méthode displayCatchEntityParticles
```java
private static void displayCatchEntityParticles(MemoriesGameplayConfig memoriesGameplayConfig, Vector3d targetPosition, Ref<EntityStore> targetRef, @Nonnull CommandBuffer<EntityStore> commandBuffer) {
ModelParticle particle = memoriesGameplayConfig.getMemoriesCatchEntityParticle();
if (particle == null) return;
NetworkId networkIdComponent = commandBuffer.getComponent(targetRef, NetworkId.getComponentType());
if (networkIdComponent == null) return;
// Crée et envoie le packet de particules à tous les joueurs proches
SpawnModelParticles packet = new SpawnModelParticles(networkIdComponent.getId(), modelParticlesProtocol);
SpatialResource<Ref<EntityStore>, EntityStore> spatialResource = commandBuffer.getResource(EntityModule.get().getPlayerSpatialResourceType());
SpatialStructure<Ref<EntityStore>> spatialStructure = spatialResource.getSpatialStructure();
spatialStructure.ordered(targetPosition, memoriesGameplayConfig.getMemoriesCatchParticleViewDistance(), results);
for (Ref ref : results) {
PlayerRef playerRefComponent = commandBuffer.getComponent(ref, PlayerRef.getComponentType());
playerRefComponent.getPacketHandler().write((Packet)packet);
}
}
```
#### Appel dans GatherMemoriesSystem
```java
// Après création de l'item mémoire
commandBuffer.addEntity(memoryItemHolder, AddReason.SPAWN);
GatherMemoriesSystem.displayCatchEntityParticles(memoriesGameplayConfig, memoryItemHolderPosition, ref, commandBuffer);
```
### 11.3 Nouveaux fichiers
| Fichier | Description |
|---------|-------------|
| `page/MemoriesUnlockedPage.java` | Page UI pour afficher les mémoires débloquées |
| `page/MemoriesUnlockedPageSuplier.java` | Supplier pour la page |
---
## 12. Configuration Serveur - Suppression LocalCompression
**Fichier** : `com/hypixel/hytale/server/core/HytaleServerConfig.java`
### 12.1 Champ supprimé
```java
// Supprimé
private boolean localCompressionEnabled;
```
### 12.2 Méthodes supprimées
```java
// Supprimés
public boolean isLocalCompressionEnabled();
public void setLocalCompressionEnabled(boolean localCompression);
```
### 12.3 Codec mis à jour
Le champ `LocalCompressionEnabled` a été retiré du CODEC de configuration.
### 12.4 Impact sur SetupPacketHandler
**Fichier** : `com/hypixel/hytale/server/core/io/handlers/SetupPacketHandler.java`
```java
// Supprimé
HytaleServerConfig serverConfig = HytaleServer.get().getConfig();
boolean enableCompression = !serverConfig.isLocalCompressionEnabled() ? !oldHandler.isLocalConnection() : true;
oldHandler.setCompressionEnabled(enableCompression);
```
La configuration du serveur est maintenant récupérée plus tard, juste avant l'envoi de `ServerInfo`.
---
## 13. Holder - Nouvelle méthode cloneSerializable
**Fichier** : `com/hypixel/hytale/component/Holder.java`
### 13.1 Nouvelle méthode
```java
public Holder<ECS_TYPE> cloneSerializable(@Nonnull ComponentRegistry.Data<ECS_TYPE> data) {
assert (this.archetype != null);
assert (this.components != null);
assert (this.registry != null);
long stamp = this.lock.readLock();
try {
Archetype<ECS_TYPE> serializableArchetype = this.archetype.getSerializableArchetype(data);
Component[] componentsClone = new Component[serializableArchetype.length()];
for (int i = serializableArchetype.getMinIndex(); i < serializableArchetype.length(); ++i) {
ComponentType<ECS_TYPE, ?> componentType = serializableArchetype.get(i);
if (componentType == null) continue;
componentsClone[i] = this.components[i].cloneSerializable();
}
return this.registry.newHolder(serializableArchetype, componentsClone);
} finally {
this.lock.unlockRead(stamp);
}
}
```
**Usage** : Clone un holder en ne gardant que les composants sérialisables.
---
## 14. BlockSelection - Tri et Filler Fix
**Fichier** : `com/hypixel/hytale/server/core/prefab/selection/standard/BlockSelection.java`
### 14.1 Nouvelle méthode sortEntitiesByPosition
```java
public void sortEntitiesByPosition() {
this.entitiesLock.writeLock().lock();
try {
ComponentType<EntityStore, TransformComponent> transformType = TransformComponent.getComponentType();
this.entities.sort((a, b) -> {
TransformComponent ta = a.getComponent(transformType);
TransformComponent tb = b.getComponent(transformType);
// Comparaison par X, puis Y, puis Z
// Gestion des cas null
});
} finally {
this.entitiesLock.writeLock().unlock();
}
}
```
### 14.2 Fix filler blocks
```java
// Nouveau cas dans withBlockComponents
if (holder != null && b.filler != 0) {
return new BlockHolder(b.blockId(), b.rotation(), b.filler(), b.supportValue(), null);
}
```
**Effet** : Les blocs filler ne perdent plus leurs données lors de la copie.
---
## 15. Corrections de Bugs
### 15.1 PickupItemSystem - Fix NPE
**Fichier** : `com/hypixel/hytale/server/core/modules/entity/item/PickupItemSystem.java`
```java
// Avant
if (!targetRef.isValid()) {
// Après
if (targetRef == null || !targetRef.isValid()) {
```
### 15.2 World - Fix coordonnée Y dans blockValidator
**Fichier** : `com/hypixel/hytale/server/core/universe/world/World.java`
```java
// Avant (bug: utilisait y au lieu de worldY)
blockValidator.accept(worldX, y, worldZ, blockId, 0, 1.0f, holder, ...);
// Après
blockValidator.accept(worldX, worldY, worldZ, blockId, 0, 1.0f, holder, ...);
```
### 15.3 CoopBlock - ArrayList → ObjectArrayList
**Fichier** : `com/hypixel/hytale/builtin/adventure/farming/states/CoopBlock.java`
```java
// Avant
ArrayList<ItemStack> remainder = new ArrayList<ItemStack>();
// Après
ObjectArrayList<ItemStack> remainder = new ObjectArrayList<ItemStack>();
```
### 15.4 EnterBedSystem - Ajout assertion
**Fichier** : `com/hypixel/hytale/builtin/beds/sleep/systems/player/EnterBedSystem.java`
```java
PlayerRef playerRef = store.getComponent(ref, PlayerRef.getComponentType());
assert (playerRef != null); // Nouveau
```
### 15.5 UpdateSleepPacketSystem - Ajout assertions
**Fichier** : `com/hypixel/hytale/builtin/beds/sleep/systems/player/UpdateSleepPacketSystem.java`
```java
SleepTracker sleepTrackerComponent = archetypeChunk.getComponent(index, SleepTracker.getComponentType());
assert (sleepTrackerComponent != null); // Nouveau
PlayerRef playerRefComponent = archetypeChunk.getComponent(index, PlayerRef.getComponentType());
assert (playerRefComponent != null); // Nouveau
PlayerSomnolence playerSomnolenceComponent = archetypeChunk.getComponent(index, PlayerSomnolence.getComponentType());
assert (playerSomnolenceComponent != null); // Nouveau
```
### 15.6 WeatherSystem - Ajout assertion
**Fichier** : `com/hypixel/hytale/builtin/weather/systems/WeatherSystem.java`
```java
WeatherTracker weatherTrackerComponent = commandBuffer.getComponent(ref, WeatherTracker.getComponentType());
assert (weatherTrackerComponent != null); // Nouveau
weatherTrackerComponent.clear();
```
---
## 16. Migration Annotations checkerframework → javax
### 16.1 Annotations migrées
| Avant | Après |
|-------|-------|
| `@NonNullDecl` | `@Nonnull` |
| `@NullableDecl` | `@Nullable` |
### 16.2 Import supprimé
```java
// Supprimé de tous les fichiers concernés
import org.checkerframework.checker.nullness.compatqual.NonNullDecl;
import org.checkerframework.checker.nullness.compatqual.NullableDecl;
```
### 16.3 Fichiers impactés (liste partielle)
- `BedInteraction.java`
- `ServerAuthManager.java`
- `FarmingSystems.java`
- `FarmingUtil.java`
- `CoopResidentComponent.java`
- `UseCaptureCrateInteraction.java`
- `UseCoopInteraction.java`
- `CoopBlock.java`
- `PlayerSomnolence.java`
- `SleepTracker.java`
- `WorldSomnolence.java`
- `EnterBedSystem.java`
- `RegisterTrackerSystem.java`
- `UpdateSleepPacketSystem.java`
- `WakeUpOnDismountSystem.java`
- `StartSlumberSystem.java`
- `UpdateWorldSlumberSystem.java`
- `WeatherSystem.java`
- Et de nombreuses classes d'interaction...
---
## 17. Liste complète des fichiers modifiés
<details>
<summary>Cliquer pour afficher les 169 fichiers</summary>
```
com/hypixel/hytale/assetstore/AssetValidationResults.java
com/hypixel/hytale/builtin/camera/command/CameraEffectCommand.java
com/hypixel/hytale/builtin/adventure/farming/FarmingSystems.java
com/hypixel/hytale/builtin/adventure/farming/FarmingUtil.java
com/hypixel/hytale/builtin/adventure/farming/component/CoopResidentComponent.java
com/hypixel/hytale/builtin/adventure/farming/interactions/UseCaptureCrateInteraction.java
com/hypixel/hytale/builtin/adventure/farming/interactions/UseCoopInteraction.java
com/hypixel/hytale/builtin/adventure/farming/states/CoopBlock.java
com/hypixel/hytale/builtin/adventure/memories/MemoriesGameplayConfig.java
com/hypixel/hytale/builtin/adventure/memories/MemoriesPlugin.java
com/hypixel/hytale/builtin/adventure/memories/commands/MemoriesCommand.java
com/hypixel/hytale/builtin/adventure/memories/interactions/MemoriesConditionInteraction.java
com/hypixel/hytale/builtin/adventure/memories/memories/npc/NPCMemory.java
com/hypixel/hytale/builtin/adventure/memories/memories/npc/NPCMemoryProvider.java
com/hypixel/hytale/builtin/adventure/memories/page/MemoriesPage.java
com/hypixel/hytale/builtin/adventure/memories/page/MemoriesPageSupplier.java
com/hypixel/hytale/builtin/adventure/memories/temple/TempleRespawnPlayersSystem.java
com/hypixel/hytale/builtin/adventure/teleporter/component/Teleporter.java
com/hypixel/hytale/builtin/adventure/teleporter/systems/CreateWarpWhenTeleporterPlacedSystem.java
com/hypixel/hytale/builtin/asseteditor/AssetEditorPlugin.java
com/hypixel/hytale/builtin/beds/interactions/BedInteraction.java
com/hypixel/hytale/builtin/beds/sleep/components/PlayerSomnolence.java
com/hypixel/hytale/builtin/beds/sleep/components/SleepTracker.java
com/hypixel/hytale/builtin/beds/sleep/resources/WorldSomnolence.java
com/hypixel/hytale/builtin/beds/sleep/systems/player/EnterBedSystem.java
com/hypixel/hytale/builtin/beds/sleep/systems/player/RegisterTrackerSystem.java
com/hypixel/hytale/builtin/beds/sleep/systems/player/UpdateSleepPacketSystem.java
com/hypixel/hytale/builtin/beds/sleep/systems/player/WakeUpOnDismountSystem.java
com/hypixel/hytale/builtin/beds/sleep/systems/world/StartSlumberSystem.java
com/hypixel/hytale/builtin/beds/sleep/systems/world/UpdateWorldSlumberSystem.java
com/hypixel/hytale/builtin/blockphysics/WorldValidationUtil.java
com/hypixel/hytale/builtin/buildertools/commands/ReplaceCommand.java
com/hypixel/hytale/builtin/buildertools/prefabeditor/PrefabEditSessionManager.java
com/hypixel/hytale/builtin/buildertools/prefabeditor/saving/PrefabSaver.java
com/hypixel/hytale/builtin/buildertools/prefabeditor/ui/PrefabEditorSaveSettingsPage.java
com/hypixel/hytale/builtin/buildertools/prefabeditor/ui/PrefabTeleportPage.java
com/hypixel/hytale/builtin/crafting/window/StructuralCraftingWindow.java
com/hypixel/hytale/builtin/hub/interactions/HubPortalInteraction.java
com/hypixel/hytale/builtin/interaction/SpawnDeployableAtHitLocationInteraction.java
com/hypixel/hytale/builtin/interaction/SpawnDeployableFromRaycastInteraction.java
com/hypixel/hytale/builtin/instances/InstancesPlugin.java
com/hypixel/hytale/builtin/instances/command/InstanceEditLoadCommand.java
com/hypixel/hytale/builtin/instances/page/InstanceListPage.java
com/hypixel/hytale/builtin/mounts/interactions/SeatingInteraction.java
com/hypixel/hytale/builtin/path/PrefabPathSystems.java
com/hypixel/hytale/builtin/path/commands/WorldPathBuilderCommand.java
com/hypixel/hytale/builtin/singleplayer/systems/CloseWorldWhenBreakingDeviceSystems.java
com/hypixel/hytale/builtin/teleport/Warp.java
com/hypixel/hytale/builtin/teleport/commands/teleport/SpawnCommand.java
com/hypixel/hytale/builtin/teleport/commands/teleport/SpawnSetCommand.java
com/hypixel/hytale/builtin/teleport/commands/teleport/TeleportAllCommand.java
com/hypixel/hytale/builtin/teleport/commands/teleport/TeleportHomeCommand.java
com/hypixel/hytale/builtin/teleport/commands/teleport/TeleportTopCommand.java
com/hypixel/hytale/builtin/teleport/commands/teleport/TeleportWorldCommand.java
com/hypixel/hytale/builtin/teleport/commands/teleport/variant/TeleportOtherToPlayerCommand.java
com/hypixel/hytale/builtin/teleport/commands/teleport/variant/TeleportPlayerToCoordinatesCommand.java
com/hypixel/hytale/builtin/teleport/commands/teleport/variant/TeleportToCoordinatesCommand.java
com/hypixel/hytale/builtin/teleport/commands/teleport/variant/TeleportToPlayerCommand.java
com/hypixel/hytale/builtin/teleport/commands/warp/WarpCommand.java
com/hypixel/hytale/builtin/teleport/commands/warp/WarpSetCommand.java
com/hypixel/hytale/builtin/teleport/components/TeleportHistory.java
com/hypixel/hytale/builtin/weather/systems/WeatherSystem.java
com/hypixel/hytale/component/ComponentRegistry.java
com/hypixel/hytale/component/Holder.java
com/hypixel/hytale/server/cell/evaluator/SkipCellPointEvaluator.java
com/hypixel/hytale/server/core/HytaleServerConfig.java
com/hypixel/hytale/server/core/Message.java
com/hypixel/hytale/server/core/asset/type/fluid/DefaultFluidTicker.java
com/hypixel/hytale/server/core/asset/type/fluid/FluidTicker.java
com/hypixel/hytale/server/core/asset/type/gameplay/CraftingConfig.java
com/hypixel/hytale/server/core/asset/type/gameplay/respawn/HomeOrSpawnPoint.java
com/hypixel/hytale/server/core/asset/type/gameplay/respawn/WorldSpawnPoint.java
com/hypixel/hytale/server/core/asset/type/item/DroplistCommand.java
com/hypixel/hytale/server/core/asset/type/item/config/Item.java
com/hypixel/hytale/server/core/auth/AuthConfig.java
com/hypixel/hytale/server/core/auth/ServerAuthManager.java
com/hypixel/hytale/server/core/auth/oauth/OAuthClient.java
com/hypixel/hytale/server/core/commands/debug/DebugPlayerPositionCommand.java
com/hypixel/hytale/server/core/commands/player/inventory/GiveCommand.java
com/hypixel/hytale/server/core/commands/world/worldgen/WorldGenBenchmarkCommand.java
com/hypixel/hytale/server/core/command/system/arguments/types/ArgTypes.java
com/hypixel/hytale/server/core/entity/InteractionContext.java
com/hypixel/hytale/server/core/entity/InteractionManager.java
com/hypixel/hytale/server/core/entity/player/data/UniqueItemUsagesComponent.java
com/hypixel/hytale/server/core/io/handlers/SetupPacketHandler.java
com/hypixel/hytale/server/core/io/handlers/game/GamePacketHandler.java
com/hypixel/hytale/server/core/modules/accesscontrol/commands/BanCommand.java
com/hypixel/hytale/server/core/modules/accesscontrol/commands/UnbanCommand.java
com/hypixel/hytale/server/core/modules/accesscontrol/commands/WhitelistAddCommand.java
com/hypixel/hytale/server/core/modules/accesscontrol/commands/WhitelistRemoveCommand.java
com/hypixel/hytale/server/core/modules/accesscontrol/provider/HytaleWhitelistProvider.java
com/hypixel/hytale/server/core/modules/entity/EntityModule.java
com/hypixel/hytale/server/core/modules/entity/LegacyProjectileSystems.java
com/hypixel/hytale/server/core/modules/entity/component/DisplayNameComponent.java
com/hypixel/hytale/server/core/modules/entity/damage/DamageSystems.java
com/hypixel/hytale/server/core/modules/entity/item/PickupItemComponent.java
com/hypixel/hytale/server/core/modules/entity/item/PickupItemSystem.java
com/hypixel/hytale/server/core/modules/entity/player/PlayerSystems.java
com/hypixel/hytale/server/core/modules/entity/system/RespondToHitSystems.java
com/hypixel/hytale/server/core/modules/entity/system/UpdateLocationSystems.java
com/hypixel/hytale/server/core/modules/entity/teleport/Teleport.java
com/hypixel/hytale/server/core/modules/entitystats/EntityStatValue.java
com/hypixel/hytale/server/core/modules/interaction/config/SimpleInstantInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/SimpleInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/client/ApplyForceInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/client/ChainingInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/client/ChargingInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/client/FirstClickInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/client/MovementConditionInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/client/PickBlockInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/client/PlaceBlockInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/client/SimpleBlockInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/client/WieldingInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/none/BuilderToolInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/none/CameraInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/none/ChangeActiveSlotInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/none/ConditionInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/none/ParallelInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/none/RepeatInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/none/ReplaceInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/none/SelectInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/none/SerialInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/selector/HorizontalSelector.java
com/hypixel/hytale/server/core/modules/interaction/config/selector/StabSelector.java
com/hypixel/hytale/server/core/modules/interaction/config/server/CheckUniqueItemUsageInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/server/DamageEntityInteraction.java
com/hypixel/hytale/server/core/modules/interaction/config/server/IncreaseBackpackCapacityInteraction.java
com/hypixel/hytale/server/core/permissions/commands/op/OpAddCommand.java
com/hypixel/hytale/server/core/permissions/commands/op/OpRemoveCommand.java
com/hypixel/hytale/server/core/permissions/commands/op/OpSelfCommand.java
com/hypixel/hytale/server/core/prefab/PrefabCopyableComponent.java
com/hypixel/hytale/server/core/prefab/config/SelectionPrefabSerializer.java
com/hypixel/hytale/server/core/prefab/selection/standard/BlockSelection.java
com/hypixel/hytale/server/core/universe/world/World.java
com/hypixel/hytale/server/core/universe/world/accessor/IChunkAccessorSync.java
com/hypixel/hytale/server/core/universe/world/chunk/BlockComponentChunk.java
com/hypixel/hytale/server/core/universe/world/chunk/EntityChunk.java
com/hypixel/hytale/server/core/universe/world/chunk/WorldChunk.java
com/hypixel/hytale/server/core/universe/world/commands/world/perf/WorldPerfResetCommand.java
com/hypixel/hytale/server/core/universe/world/connectedblocks/builtin/RoofConnectedBlockRuleSet.java
com/hypixel/hytale/server/core/universe/world/meta/BlockState.java
com/hypixel/hytale/server/core/universe/world/path/SimplePathWaypoint.java
com/hypixel/hytale/server/core/universe/world/spawn/FitToHeightMapSpawnProvider.java
com/hypixel/hytale/server/core/universe/world/spawn/GlobalSpawnProvider.java
com/hypixel/hytale/server/core/universe/world/spawn/IndividualSpawnProvider.java
com/hypixel/hytale/server/core/universe/world/storage/ChunkStore.java
com/hypixel/hytale/server/core/universe/world/storage/component/ChunkSavingSystems.java
com/hypixel/hytale/server/core/universe/world/storage/provider/DefaultChunkStorageProvider.java
com/hypixel/hytale/server/core/universe/world/storage/provider/EmptyChunkStorageProvider.java
com/hypixel/hytale/server/core/universe/world/storage/provider/MigrationChunkStorageProvider.java
com/hypixel/hytale/server/core/util/PrefabUtil.java
com/hypixel/hytale/server/movement/BodyMotionTeleport.java
com/hypixel/hytale/server/npc/role/builders/BuilderRole.java
com/hypixel/hytale/server/npc/role/support/StateSupport.java
com/hypixel/hytale/server/npc/systems/NPCSystems.java
com/hypixel/hytale/server/worldgen/cave/shape/AbstractCaveNodeShape.java
com/hypixel/hytale/server/worldgen/cave/shape/DistortedCaveNodeShape.java
com/hypixel/hytale/server/worldgen/loader/cave/CavePrefabConfigJsonLoader.java
com/hypixel/hytale/server/worldgen/loader/cave/CaveTypeJsonLoader.java
com/hypixel/hytale/server/worldgen/loader/cave/PrefabCaveNodeShapeGeneratorJsonLoader.java
com/hypixel/hytale/server/worldgen/loader/prefab/BlockPlacementMaskJsonLoader.java
com/hypixel/hytale/server/worldgen/loader/prefab/BlockPlacementMaskRegistry.java
com/hypixel/hytale/server/worldgen/loader/prefab/PrefabPatternGeneratorJsonLoader.java
com/hypixel/hytale/server/worldgen/loader/prefab/UniquePrefabConfigurationJsonLoader.java
com/hypixel/hytale/server/worldgen/prefab/PrefabPasteUtil.java
com/hypixel/hytale/server/worldgen/util/cache/ConcurrentSizedTimeoutCache.java
com/hypixel/hytale/server/worldgen/util/condition/BlockMaskCondition.java
org/jline/reader/impl/LineReaderImpl.java
summary.txt
```
</details>
---
## Résumé des impacts
### Performance
| Changement | Impact |
|------------|--------|
| PrefabSaver async chunk loading | Sauvegarde de prefabs non-bloquante |
| ProfileServiceClient async | Récupération de profils sans bloquer |
| ChunkStore generator lock | Thread safety améliorée |
| InteractionManager currentTime | Timing plus cohérent basé sur les ticks |
### Stabilité
| Changement | Impact |
|------------|--------|
| PickupItemSystem NPE fix | Évite crash sur ref null |
| World blockValidator fix | Coordonnées Y correctes |
| Assertions ajoutées | Détection précoce des erreurs |
| ChunkStore thread safety | Évite race conditions sur generator |
### API
| Changement | Impact |
|------------|--------|
| Teleport factory methods | API plus claire pour la téléportation |
| BlockMaskCondition | Nouveau système de masques pour worldgen |
| ProfileServiceClient | Nouvelle API pour récupérer les profils |
| GAME_PROFILE_LOOKUP | Nouveau type d'argument pour les commandes |
| Holder.cloneSerializable() | Nouvelle méthode de clonage |
| BlockSelection.sortEntitiesByPosition() | Nouvelle méthode de tri |
### Qualité du code
| Changement | Impact |
|------------|--------|
| Migration annotations | Standardisation sur javax.annotation |
| ServerAuthManager refactoring | Code plus maintenable |
| Suppression LocalCompression | Simplification de la configuration |
| Typo fix "stroage" → "storage" | Meilleurs logs |
---
*Généré à partir du diff git entre les versions `c04fdfe10` et `c508b9acd`*
*169 fichiers analysés exhaustivement*