# 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*
