fancyholograms v3: Fix trait_trait trait saving and loading

This commit is contained in:
Oliver
2025-07-30 19:08:25 +02:00
parent 982d9db32c
commit 7f41e1978b
9 changed files with 87 additions and 109 deletions

View File

@@ -3,6 +3,8 @@ package com.fancyinnovations.fancyholograms.api.data;
import com.fancyinnovations.fancyholograms.api.FancyHolograms; import com.fancyinnovations.fancyholograms.api.FancyHolograms;
import com.fancyinnovations.fancyholograms.api.data.property.Visibility; import com.fancyinnovations.fancyholograms.api.data.property.Visibility;
import com.fancyinnovations.fancyholograms.api.hologram.HologramType; import com.fancyinnovations.fancyholograms.api.hologram.HologramType;
import com.fancyinnovations.fancyholograms.api.trait.HologramTrait;
import com.fancyinnovations.fancyholograms.api.trait.HologramTraitTrait;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
@@ -11,6 +13,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
@@ -20,7 +23,7 @@ public class HologramData implements YamlData {
public static final Visibility DEFAULT_VISIBILITY = Visibility.ALL; public static final Visibility DEFAULT_VISIBILITY = Visibility.ALL;
public static final boolean DEFAULT_IS_VISIBLE = true; public static final boolean DEFAULT_IS_VISIBLE = true;
public static final boolean DEFAULT_PERSISTENCE = true; public static final boolean DEFAULT_PERSISTENCE = true;
protected final @NotNull HologramTraitTrait traitTrait;
private final String name; private final String name;
private final HologramType type; private final HologramType type;
private String filePath; private String filePath;
@@ -48,6 +51,7 @@ public class HologramData implements YamlData {
} else { } else {
this.worldName = null; this.worldName = null;
} }
this.traitTrait = new HologramTraitTrait();
} }
public @NotNull String getName() { public @NotNull String getName() {
@@ -192,6 +196,32 @@ public class HologramData implements YamlData {
return this; return this;
} }
@ApiStatus.Experimental
public @NotNull HologramTraitTrait getTraitTrait() {
return traitTrait;
}
@ApiStatus.Experimental
public HologramData addTrait(HologramTrait trait) {
traitTrait.addTrait(trait);
return this;
}
@ApiStatus.Experimental
public HologramData addTrait(Class<? extends HologramTrait> traitClass) {
HologramTrait trait = null;
try {
trait = traitClass.getConstructor(null).newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
NoSuchMethodException e) {
FancyHolograms.get().getFancyLogger().error("Failed to instantiate trait " + traitClass.getSimpleName());
FancyHolograms.get().getFancyLogger().error(e);
}
traitTrait.addTrait(trait);
return this;
}
@Override @Override
@ApiStatus.Internal @ApiStatus.Internal
public boolean read(ConfigurationSection section, String name) { public boolean read(ConfigurationSection section, String name) {

View File

@@ -1,11 +1,8 @@
package com.fancyinnovations.fancyholograms.api.hologram; package com.fancyinnovations.fancyholograms.api.hologram;
import com.google.common.collect.Sets;
import com.fancyinnovations.fancyholograms.api.FancyHolograms;
import com.fancyinnovations.fancyholograms.api.data.HologramData; import com.fancyinnovations.fancyholograms.api.data.HologramData;
import com.fancyinnovations.fancyholograms.api.data.TextHologramData; import com.fancyinnovations.fancyholograms.api.data.TextHologramData;
import com.fancyinnovations.fancyholograms.api.trait.HologramTrait; import com.google.common.collect.Sets;
import com.fancyinnovations.fancyholograms.api.trait.HologramTraitTrait;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -14,7 +11,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.lushplugins.chatcolorhandler.ModernChatColorHandler; import org.lushplugins.chatcolorhandler.ModernChatColorHandler;
import java.lang.reflect.InvocationTargetException;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@@ -32,13 +28,13 @@ public abstract class Hologram {
protected final @NotNull HologramData data; protected final @NotNull HologramData data;
protected final @NotNull Set<UUID> viewers; protected final @NotNull Set<UUID> viewers;
protected final @NotNull HologramTraitTrait traitTrait;
protected Hologram(@NotNull final HologramData data) { protected Hologram(@NotNull final HologramData data) {
this.data = data; this.data = data;
this.viewers = new HashSet<>(); this.viewers = new HashSet<>();
this.traitTrait = new HologramTraitTrait(this);
this.data.setOnModify(this.traitTrait::onModify); this.data.getTraitTrait().attachHologram(this);
this.data.setOnModify(this.data.getTraitTrait()::onModify);
} }
/** /**
@@ -100,32 +96,6 @@ public abstract class Hologram {
return this.viewers.contains(player); return this.viewers.contains(player);
} }
@ApiStatus.Experimental
public @NotNull HologramTraitTrait getTraitTrait() {
return traitTrait;
}
@ApiStatus.Experimental
public HologramData addTrait(HologramTrait trait) {
traitTrait.addTrait(trait);
return data;
}
@ApiStatus.Experimental
public HologramData addTrait(Class<? extends HologramTrait> traitClass) {
HologramTrait trait = null;
try {
trait = traitClass.getConstructor(null).newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
NoSuchMethodException e) {
FancyHolograms.get().getFancyLogger().error("Failed to instantiate trait " + traitClass.getSimpleName());
FancyHolograms.get().getFancyLogger().error(e);
}
traitTrait.addTrait(trait);
return data;
}
public final @NotNull HologramData getData() { public final @NotNull HologramData getData() {
return this.data; return this.data;
} }

View File

@@ -1,10 +1,10 @@
package com.fancyinnovations.fancyholograms.api.trait; package com.fancyinnovations.fancyholograms.api.trait;
import de.oliver.fancyanalytics.logger.ExtendedFancyLogger;
import com.fancyinnovations.fancyholograms.api.FancyHolograms; import com.fancyinnovations.fancyholograms.api.FancyHolograms;
import com.fancyinnovations.fancyholograms.api.HologramController; import com.fancyinnovations.fancyholograms.api.HologramController;
import com.fancyinnovations.fancyholograms.api.HologramRegistry; import com.fancyinnovations.fancyholograms.api.HologramRegistry;
import com.fancyinnovations.fancyholograms.api.hologram.Hologram; import com.fancyinnovations.fancyholograms.api.hologram.Hologram;
import de.oliver.fancyanalytics.logger.ExtendedFancyLogger;
import de.oliver.jdb.JDB; import de.oliver.jdb.JDB;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
@@ -108,7 +108,7 @@ public abstract class HologramTrait {
} }
protected final boolean isTraitAttached(Class<? extends HologramTrait> trait) { protected final boolean isTraitAttached(Class<? extends HologramTrait> trait) {
for (HologramTrait hologramTrait : hologram.getTraitTrait().getTraits()) { for (HologramTrait hologramTrait : hologram.getData().getTraitTrait().getTraits()) {
if (hologramTrait.getClass().equals(trait)) { if (hologramTrait.getClass().equals(trait)) {
return true; return true;
} }
@@ -118,7 +118,7 @@ public abstract class HologramTrait {
} }
protected final <T extends HologramTrait> T getTrait(Class<T> trait) { protected final <T extends HologramTrait> T getTrait(Class<T> trait) {
for (HologramTrait hologramTrait : hologram.getTraitTrait().getTraits()) { for (HologramTrait hologramTrait : hologram.getData().getTraitTrait().getTraits()) {
if (hologramTrait.getClass().equals(trait)) { if (hologramTrait.getClass().equals(trait)) {
return (T) hologramTrait; return (T) hologramTrait;
} }

View File

@@ -1,10 +1,8 @@
package com.fancyinnovations.fancyholograms.api.trait; package com.fancyinnovations.fancyholograms.api.trait;
import com.fancyinnovations.fancyholograms.api.events.HologramTraitAttachedEvent; import com.fancyinnovations.fancyholograms.api.events.HologramTraitAttachedEvent;
import com.fancyinnovations.fancyholograms.api.hologram.Hologram;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -12,27 +10,21 @@ import java.util.List;
public class HologramTraitTrait extends HologramTrait { public class HologramTraitTrait extends HologramTrait {
private final List<HologramTrait> traits; private final List<HologramTrait> traits;
private Configuration configuration;
public HologramTraitTrait(Hologram hologram) { public HologramTraitTrait() {
this.configuration = new Configuration(new ArrayList<>());
this.traits = new ArrayList<>(); this.traits = new ArrayList<>();
attachHologram(hologram);
} }
public void addTrait(HologramTrait trait) { public void addTrait(HologramTrait trait) {
if (!new HologramTraitAttachedEvent(hologram, trait, false).callEvent()) {
return;
}
trait.attachHologram(hologram);
this.traits.add(trait); this.traits.add(trait);
this.configuration.traits().add(trait.getName());
try { // Attach the trait to the hologram if hologram already exists
storage.set(hologram.getData().getName(), configuration); if (hologram != null) {
} catch (IOException e) { if (!new HologramTraitAttachedEvent(hologram, trait, false).callEvent()) {
logger.error("Failed to save configuration for HologramTraitTrait"); return;
logger.error(e); }
trait.attachHologram(hologram);
} }
} }
@@ -47,11 +39,6 @@ public class HologramTraitTrait extends HologramTrait {
try { try {
HologramTrait trait = ti.clazz().getConstructor().newInstance(); HologramTrait trait = ti.clazz().getConstructor().newInstance();
if (!new HologramTraitAttachedEvent(hologram, trait, true).callEvent()) {
continue;
}
trait.attachHologram(hologram);
this.traits.add(trait); this.traits.add(trait);
} catch (Exception e) { } catch (Exception e) {
logger.error("Failed to instantiate default trait " + ti.name()); logger.error("Failed to instantiate default trait " + ti.name());
@@ -61,38 +48,13 @@ public class HologramTraitTrait extends HologramTrait {
logger.debug("Attached default trait " + ti.name() + " to hologram " + hologram.getData().getName()); logger.debug("Attached default trait " + ti.name() + " to hologram " + hologram.getData().getName());
} }
// Attach all traits that are already attached to the hologram // Attach all traits that were added to the hologram
try { for (HologramTrait trait : traits) {
configuration = storage.get(hologram.getData().getName(), Configuration.class); if (!new HologramTraitAttachedEvent(hologram, trait, false).callEvent()) {
} catch (IOException e) {
logger.error("Failed to load configuration for HologramTraitTrait");
logger.error(e);
return;
}
if (configuration == null) {
return;
}
for (String traitName : configuration.traits()) {
HologramTraitRegistry.TraitInfo traitInfo = api.getTraitRegistry().getTrait(traitName);
if (traitInfo == null) {
logger.warn("Trait " + traitName + " is not registered");
continue; continue;
} }
try { trait.attachHologram(hologram);
HologramTrait trait = traitInfo.clazz().getConstructor().newInstance();
if (!new HologramTraitAttachedEvent(hologram, trait, false).callEvent()) {
return;
}
trait.attachHologram(hologram);
this.traits.add(trait);
} catch (Exception e) {
logger.error("Failed to instantiate trait " + traitName);
logger.error(e);
}
} }
} }
@@ -156,13 +118,4 @@ public class HologramTraitTrait extends HologramTrait {
return traits; return traits;
} }
public Configuration getConfiguration() {
return configuration;
}
public record Configuration(
List<String> traits
) {
}
} }

View File

@@ -34,7 +34,7 @@ public class HologramControllerImpl implements HologramController {
} }
hologram.spawnTo(player); hologram.spawnTo(player);
hologram.getTraitTrait().onSpawn(player); hologram.getData().getTraitTrait().onSpawn(player);
} }
} }
@@ -49,7 +49,7 @@ public class HologramControllerImpl implements HologramController {
} }
hologram.despawnFrom(player); hologram.despawnFrom(player);
hologram.getTraitTrait().onDespawn(player); hologram.getData().getTraitTrait().onDespawn(player);
} }
} }
@@ -65,7 +65,7 @@ public class HologramControllerImpl implements HologramController {
} }
hologram.updateFor(player); hologram.updateFor(player);
hologram.getTraitTrait().onUpdate(player); hologram.getData().getTraitTrait().onUpdate(player);
} }
} }

View File

@@ -1,13 +1,13 @@
package com.fancyinnovations.fancyholograms.hologram; package com.fancyinnovations.fancyholograms.hologram;
import com.fancyinnovations.fancyholograms.api.data.HologramData;
import com.viaversion.viaversion.api.Via;
import com.fancyinnovations.fancyholograms.api.FancyHolograms; import com.fancyinnovations.fancyholograms.api.FancyHolograms;
import com.fancyinnovations.fancyholograms.api.data.HologramData;
import com.fancyinnovations.fancyholograms.api.events.HologramDespawnEvent; import com.fancyinnovations.fancyholograms.api.events.HologramDespawnEvent;
import com.fancyinnovations.fancyholograms.api.events.HologramSpawnEvent; import com.fancyinnovations.fancyholograms.api.events.HologramSpawnEvent;
import com.fancyinnovations.fancyholograms.api.hologram.Hologram; import com.fancyinnovations.fancyholograms.api.hologram.Hologram;
import com.fancyinnovations.fancyholograms.main.FancyHologramsPlugin; import com.fancyinnovations.fancyholograms.main.FancyHologramsPlugin;
import com.fancyinnovations.fancyholograms.util.PluginUtils; import com.fancyinnovations.fancyholograms.util.PluginUtils;
import com.viaversion.viaversion.api.Via;
import de.oliver.fancysitula.api.entities.*; import de.oliver.fancysitula.api.entities.*;
import de.oliver.fancysitula.factories.FancySitula; import de.oliver.fancysitula.factories.FancySitula;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -63,7 +63,7 @@ public final class HologramImpl extends Hologram {
this.viewers.add(player.getUniqueId()); this.viewers.add(player.getUniqueId());
updateFor(player); updateFor(player);
traitTrait.onSpawn(player); data.getTraitTrait().onSpawn(player);
} }
@Override @Override
@@ -85,7 +85,7 @@ public final class HologramImpl extends Hologram {
this.viewers.remove(player.getUniqueId()); this.viewers.remove(player.getUniqueId());
traitTrait.onDespawn(player); data.getTraitTrait().onDespawn(player);
} }

View File

@@ -26,7 +26,7 @@ public class HologramRegistryImpl implements HologramRegistry {
boolean registered = holograms.putIfAbsent(hologram.getData().getName(), hologram) != null; boolean registered = holograms.putIfAbsent(hologram.getData().getName(), hologram) != null;
hologram.getTraitTrait().onRegister(); hologram.getData().getTraitTrait().onRegister();
return registered; return registered;
} }
@@ -41,7 +41,7 @@ public class HologramRegistryImpl implements HologramRegistry {
FancyHologramsPlugin.get().getStorage().delete(hologram.getData()); FancyHologramsPlugin.get().getStorage().delete(hologram.getData());
hologram.getTraitTrait().onUnregister(); hologram.getData().getTraitTrait().onUnregister();
return removed; return removed;
} }

View File

@@ -1,6 +1,9 @@
package com.fancyinnovations.fancyholograms.storage.json; package com.fancyinnovations.fancyholograms.storage.json;
import com.fancyinnovations.fancyholograms.api.FancyHolograms;
import com.fancyinnovations.fancyholograms.api.data.HologramData; import com.fancyinnovations.fancyholograms.api.data.HologramData;
import com.fancyinnovations.fancyholograms.api.trait.HologramTrait;
import com.fancyinnovations.fancyholograms.api.trait.HologramTraitRegistry;
import com.fancyinnovations.fancyholograms.storage.json.model.*; import com.fancyinnovations.fancyholograms.storage.json.model.*;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@@ -26,7 +29,10 @@ public class JsonAdapter {
data.getWorldName(), data.getWorldName(),
data.getVisibilityDistance(), data.getVisibilityDistance(),
data.getVisibility(), data.getVisibility(),
data.getLinkedNpcName() data.getLinkedNpcName(),
data.getTraitTrait().getTraits().stream()
.map(HologramTrait::getName)
.toList()
); );
} }
@@ -197,6 +203,22 @@ public class JsonAdapter {
.setLinkedNpcName(data.hologram_data().linkedNpcName()); .setLinkedNpcName(data.hologram_data().linkedNpcName());
}; };
for (String traitName : data.hologram_data().traits()) {
HologramTraitRegistry.TraitInfo traitInfo = FancyHolograms.get().getTraitRegistry().getTrait(traitName);
if (traitInfo == null) {
FancyHolograms.get().getFancyLogger().warn("Trait " + traitName + " is not registered");
continue;
}
try {
HologramTrait trait = traitInfo.clazz().getConstructor().newInstance();
hologramData.getTraitTrait().addTrait(trait);
} catch (Exception e) {
FancyHolograms.get().getFancyLogger().error("Failed to instantiate trait " + traitName);
FancyHolograms.get().getFancyLogger().error(e);
}
}
return hologramData; return hologramData;
} }
} }

View File

@@ -3,6 +3,8 @@ package com.fancyinnovations.fancyholograms.storage.json.model;
import com.fancyinnovations.fancyholograms.api.data.property.Visibility; import com.fancyinnovations.fancyholograms.api.data.property.Visibility;
import com.fancyinnovations.fancyholograms.api.hologram.HologramType; import com.fancyinnovations.fancyholograms.api.hologram.HologramType;
import java.util.List;
public record JsonHologramData( public record JsonHologramData(
String name, String name,
HologramType type, HologramType type,
@@ -10,7 +12,8 @@ public record JsonHologramData(
String worldName, String worldName,
Integer visibilityDistance, Integer visibilityDistance,
Visibility visibility, Visibility visibility,
String linkedNpcName String linkedNpcName,
List<String> traits
) { ) {
} }