add uuids to npcs & add uuid importing to znpcs importer

This commit is contained in:
Pyrbu 2023-06-19 14:29:12 +02:00
parent 697fdb36e1
commit 78fbb13348
10 changed files with 80 additions and 40 deletions

@ -1,8 +1,11 @@
package lol.pyr.znpcsplus.api.npc; package lol.pyr.znpcsplus.api.npc;
import lol.pyr.znpcsplus.api.hologram.Hologram;
import lol.pyr.znpcsplus.api.entity.PropertyHolder; import lol.pyr.znpcsplus.api.entity.PropertyHolder;
import lol.pyr.znpcsplus.api.hologram.Hologram;
import java.util.UUID;
public interface Npc extends PropertyHolder { public interface Npc extends PropertyHolder {
Hologram getHologram(); Hologram getHologram();
UUID getUuid();
} }

@ -4,6 +4,7 @@ import lol.pyr.znpcsplus.util.NpcLocation;
import org.bukkit.World; import org.bukkit.World;
import java.util.Collection; import java.util.Collection;
import java.util.UUID;
public interface NpcRegistry { public interface NpcRegistry {
Collection<? extends NpcEntry> getAll(); Collection<? extends NpcEntry> getAll();
@ -11,6 +12,7 @@ public interface NpcRegistry {
Collection<? extends NpcEntry> getAllPlayerMade(); Collection<? extends NpcEntry> getAllPlayerMade();
Collection<String> getAllPlayerMadeIds(); Collection<String> getAllPlayerMadeIds();
NpcEntry create(String id, World world, NpcType type, NpcLocation location); NpcEntry create(String id, World world, NpcType type, NpcLocation location);
NpcEntry get(String id); NpcEntry getById(String id);
NpcEntry getByUuid(UUID uuid);
void delete(String id); void delete(String id);
} }

@ -30,7 +30,7 @@ public class CreateCommand implements CommandHandler {
Player player = context.ensureSenderIsPlayer(); Player player = context.ensureSenderIsPlayer();
String id = context.popString(); String id = context.popString();
if (npcRegistry.get(id) != null) context.halt(Component.text("NPC with that ID already exists.", NamedTextColor.RED)); if (npcRegistry.getById(id) != null) context.halt(Component.text("NPC with that ID already exists.", NamedTextColor.RED));
NpcTypeImpl type = context.parse(NpcTypeImpl.class); NpcTypeImpl type = context.parse(NpcTypeImpl.class);
NpcEntryImpl entry = npcRegistry.create(id, player.getWorld(), type, new NpcLocation(player.getLocation())); NpcEntryImpl entry = npcRegistry.create(id, player.getWorld(), type, new NpcLocation(player.getLocation()));

@ -22,7 +22,7 @@ public class ListCommand implements CommandHandler {
public void run(CommandContext context) throws CommandExecutionException { public void run(CommandContext context) throws CommandExecutionException {
TextComponent.Builder component = Component.text("Npc List:\n").color(NamedTextColor.GOLD).toBuilder(); TextComponent.Builder component = Component.text("Npc List:\n").color(NamedTextColor.GOLD).toBuilder();
for (String id : npcRegistry.getModifiableIds()) { for (String id : npcRegistry.getModifiableIds()) {
NpcImpl npc = npcRegistry.get(id).getNpc(); NpcImpl npc = npcRegistry.getById(id).getNpc();
NpcLocation location = npc.getLocation(); NpcLocation location = npc.getLocation();
component.append(Component.text("ID: " + id, NamedTextColor.GREEN)) component.append(Component.text("ID: " + id, NamedTextColor.GREEN))
.append(Component.text(" | ", NamedTextColor.GRAY)) .append(Component.text(" | ", NamedTextColor.GRAY))

@ -40,10 +40,7 @@ import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
public class ZNpcImporter implements DataImporter { public class ZNpcImporter implements DataImporter {
private final ConfigManager configManager; private final ConfigManager configManager;
@ -102,7 +99,8 @@ public class ZNpcImporter implements DataImporter {
ZNpcsLocation oldLoc = model.getLocation(); ZNpcsLocation oldLoc = model.getLocation();
NpcLocation location = new NpcLocation(oldLoc.getX(), oldLoc.getY(), oldLoc.getZ(), oldLoc.getYaw(), oldLoc.getPitch()); NpcLocation location = new NpcLocation(oldLoc.getX(), oldLoc.getY(), oldLoc.getZ(), oldLoc.getYaw(), oldLoc.getPitch());
NpcImpl npc = new NpcImpl(configManager, packetFactory, textSerializer, oldLoc.getWorld(), typeRegistry.getByName(type), location); UUID uuid = model.getUuid() == null ? UUID.randomUUID() : model.getUuid();
NpcImpl npc = new NpcImpl(uuid, configManager, packetFactory, textSerializer, oldLoc.getWorld(), typeRegistry.getByName(type), location);
HologramImpl hologram = npc.getHologram(); HologramImpl hologram = npc.getHologram();
hologram.setOffset(model.getHologramHeight()); hologram.setOffset(model.getHologramHeight());

@ -2,10 +2,12 @@ package lol.pyr.znpcsplus.conversion.znpcs.model;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class ZNpcsModel { public class ZNpcsModel {
private int id; private int id;
private UUID uuid;
private double hologramHeight; private double hologramHeight;
private String skinName; private String skinName;
private String glowName; private String glowName;
@ -20,6 +22,10 @@ public class ZNpcsModel {
return id; return id;
} }
public UUID getUuid() {
return uuid;
}
public double getHologramHeight() { public double getHologramHeight() {
return hologramHeight; return hologramHeight;
} }

@ -25,19 +25,21 @@ public class NpcImpl extends Viewable implements Npc {
private NpcLocation location; private NpcLocation location;
private NpcTypeImpl type; private NpcTypeImpl type;
private final HologramImpl hologram; private final HologramImpl hologram;
private final UUID uuid;
private final Map<EntityPropertyImpl<?>, Object> propertyMap = new HashMap<>(); private final Map<EntityPropertyImpl<?>, Object> propertyMap = new HashMap<>();
private final List<InteractionAction> actions = new ArrayList<>(); private final List<InteractionAction> actions = new ArrayList<>();
protected NpcImpl(ConfigManager configManager, LegacyComponentSerializer textSerializer, World world, NpcTypeImpl type, NpcLocation location, PacketFactory packetFactory) { protected NpcImpl(UUID uuid, ConfigManager configManager, LegacyComponentSerializer textSerializer, World world, NpcTypeImpl type, NpcLocation location, PacketFactory packetFactory) {
this(configManager, packetFactory, textSerializer, world.getName(), type, location); this(uuid, configManager, packetFactory, textSerializer, world.getName(), type, location);
} }
public NpcImpl(ConfigManager configManager, PacketFactory packetFactory, LegacyComponentSerializer textSerializer, String world, NpcTypeImpl type, NpcLocation location) { public NpcImpl(UUID uuid, ConfigManager configManager, PacketFactory packetFactory, LegacyComponentSerializer textSerializer, String world, NpcTypeImpl type, NpcLocation location) {
this.packetFactory = packetFactory; this.packetFactory = packetFactory;
this.worldName = world; this.worldName = world;
this.type = type; this.type = type;
this.location = location; this.location = location;
this.uuid = uuid;
entity = new PacketEntity(packetFactory, this, type.getType(), location); entity = new PacketEntity(packetFactory, this, type.getType(), location);
hologram = new HologramImpl(configManager, packetFactory, textSerializer, location.withY(location.getY() + type.getHologramOffset())); hologram = new HologramImpl(configManager, packetFactory, textSerializer, location.withY(location.getY() + type.getHologramOffset()));
} }
@ -76,6 +78,10 @@ public class NpcImpl extends Viewable implements Npc {
return hologram; return hologram;
} }
public UUID getUuid() {
return uuid;
}
public World getWorld() { public World getWorld() {
return Bukkit.getWorld(worldName); return Bukkit.getWorld(worldName);
} }

@ -14,10 +14,7 @@ import lol.pyr.znpcsplus.util.NpcLocation;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.World; import org.bukkit.World;
import java.util.Collection; import java.util.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class NpcRegistryImpl implements NpcRegistry { public class NpcRegistryImpl implements NpcRegistry {
@ -26,7 +23,9 @@ public class NpcRegistryImpl implements NpcRegistry {
private final ConfigManager configManager; private final ConfigManager configManager;
private final LegacyComponentSerializer textSerializer; private final LegacyComponentSerializer textSerializer;
private final Map<String, NpcEntryImpl> npcMap = new HashMap<>(); private final List<NpcEntryImpl> npcList = new ArrayList<>();
private final Map<String, NpcEntryImpl> npcIdLookupMap = new HashMap<>();
private final Map<UUID, NpcEntryImpl> npcUuidLookupMap = new HashMap<>();
public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, TaskScheduler scheduler, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) { public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, TaskScheduler scheduler, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) {
this.textSerializer = textSerializer; this.textSerializer = textSerializer;
@ -40,49 +39,73 @@ public class NpcRegistryImpl implements NpcRegistry {
} }
} }
public void registerAll(Collection<NpcEntryImpl> entries) { private void register(NpcEntryImpl entry) {
for (NpcEntryImpl entry : entries) { unregister(npcIdLookupMap.put(entry.getId(), entry));
NpcEntryImpl old = npcMap.put(entry.getId(), entry); unregister(npcUuidLookupMap.put(entry.getNpc().getUuid(), entry));
if (old != null) old.getNpc().delete(); npcList.add(entry);
} }
private void unregister(NpcEntryImpl entry) {
if (entry == null) return;
npcList.remove(entry);
NpcImpl one = npcIdLookupMap.remove(entry.getId()).getNpc();
NpcImpl two = npcUuidLookupMap.remove(entry.getNpc().getUuid()).getNpc();
if (one != null) one.delete();
if (two != null && !Objects.equals(one, two)) two.delete();
}
private void unregisterAll() {
for (NpcEntryImpl entry : npcList) entry.getNpc().delete();
npcList.clear();
npcIdLookupMap.clear();
npcUuidLookupMap.clear();
}
public void registerAll(Collection<NpcEntryImpl> entries) {
for (NpcEntryImpl entry : entries) register(entry);
} }
public void reload() { public void reload() {
for (NpcEntryImpl entry : npcMap.values()) entry.getNpc().delete(); unregisterAll();
npcMap.clear(); registerAll(storage.loadNpcs());
for (NpcEntryImpl entry : storage.loadNpcs()) npcMap.put(entry.getId(), entry);
} }
public void save() { public void save() {
storage.saveNpcs(npcMap.values().stream().filter(NpcEntryImpl::isSave).collect(Collectors.toList())); storage.saveNpcs(npcList.stream().filter(NpcEntryImpl::isSave).collect(Collectors.toList()));
} }
public NpcEntryImpl get(String id) { @Override
return npcMap.get(id.toLowerCase()); public NpcEntryImpl getById(String id) {
return npcIdLookupMap.get(id.toLowerCase());
}
@Override
public NpcEntry getByUuid(UUID uuid) {
return npcUuidLookupMap.get(uuid);
} }
public Collection<NpcEntryImpl> getAll() { public Collection<NpcEntryImpl> getAll() {
return Collections.unmodifiableCollection(npcMap.values()); return Collections.unmodifiableCollection(npcList);
} }
public Collection<NpcEntryImpl> getProcessable() { public Collection<NpcEntryImpl> getProcessable() {
return Collections.unmodifiableCollection(npcMap.values().stream() return Collections.unmodifiableCollection(npcList.stream()
.filter(NpcEntryImpl::isProcessed) .filter(NpcEntryImpl::isProcessed)
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }
public Collection<NpcEntryImpl> getAllModifiable() { public Collection<NpcEntryImpl> getAllModifiable() {
return Collections.unmodifiableCollection(npcMap.values().stream() return Collections.unmodifiableCollection(npcList.stream()
.filter(NpcEntryImpl::isAllowCommandModification) .filter(NpcEntryImpl::isAllowCommandModification)
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }
public NpcEntryImpl getByEntityId(int id) { public NpcEntryImpl getByEntityId(int id) {
return getAll().stream().filter(entry -> entry.getNpc().getEntity().getEntityId() == id).findFirst().orElse(null); return npcList.stream().filter(entry -> entry.getNpc().getEntity().getEntityId() == id).findFirst().orElse(null);
} }
public Collection<String> getAllIds() { public Collection<String> getAllIds() {
return Collections.unmodifiableSet(npcMap.keySet()); return Collections.unmodifiableSet(npcIdLookupMap.keySet());
} }
@Override @Override
@ -98,7 +121,7 @@ public class NpcRegistryImpl implements NpcRegistry {
} }
public Collection<String> getModifiableIds() { public Collection<String> getModifiableIds() {
return Collections.unmodifiableSet(npcMap.entrySet().stream() return Collections.unmodifiableSet(npcIdLookupMap.entrySet().stream()
.filter(entry -> entry.getValue().isAllowCommandModification()) .filter(entry -> entry.getValue().isAllowCommandModification())
.map(Map.Entry::getKey) .map(Map.Entry::getKey)
.collect(Collectors.toSet())); .collect(Collectors.toSet()));
@ -110,17 +133,17 @@ public class NpcRegistryImpl implements NpcRegistry {
public NpcEntryImpl create(String id, World world, NpcTypeImpl type, NpcLocation location) { public NpcEntryImpl create(String id, World world, NpcTypeImpl type, NpcLocation location) {
id = id.toLowerCase(); id = id.toLowerCase();
if (npcMap.containsKey(id)) throw new IllegalArgumentException("An npc with the id " + id + " already exists!"); if (npcIdLookupMap.containsKey(id)) throw new IllegalArgumentException("An npc with the id " + id + " already exists!");
NpcImpl npc = new NpcImpl(configManager, textSerializer, world, type, location, packetFactory); NpcImpl npc = new NpcImpl(UUID.randomUUID(), configManager, textSerializer, world, type, location, packetFactory);
NpcEntryImpl entry = new NpcEntryImpl(id, npc); NpcEntryImpl entry = new NpcEntryImpl(id, npc);
npcMap.put(id, entry); npcIdLookupMap.put(id, entry);
return entry; return entry;
} }
@Override @Override
public void delete(String id) { public void delete(String id) {
id = id.toLowerCase(); id = id.toLowerCase();
if (!npcMap.containsKey(id)) return; if (!npcIdLookupMap.containsKey(id)) return;
npcMap.remove(id).getNpc().delete(); npcIdLookupMap.remove(id).getNpc().delete();
} }
} }

@ -19,7 +19,7 @@ public class NpcEntryParser extends ParserType<NpcEntryImpl> {
@Override @Override
public NpcEntryImpl parse(Deque<String> deque) throws CommandExecutionException { public NpcEntryImpl parse(Deque<String> deque) throws CommandExecutionException {
NpcEntryImpl entry = npcRegistry.get(deque.pop()); NpcEntryImpl entry = npcRegistry.getById(deque.pop());
if (entry == null || !entry.isAllowCommandModification()) throw new CommandExecutionException(); if (entry == null || !entry.isAllowCommandModification()) throw new CommandExecutionException();
return entry; return entry;
} }

@ -48,7 +48,8 @@ public class YamlStorage implements NpcStorage {
List<NpcEntryImpl> npcs = new ArrayList<>(files.length); List<NpcEntryImpl> npcs = new ArrayList<>(files.length);
for (File file : files) if (file.isFile() && file.getName().toLowerCase().endsWith(".yml")) { for (File file : files) if (file.isFile() && file.getName().toLowerCase().endsWith(".yml")) {
YamlConfiguration config = YamlConfiguration.loadConfiguration(file); YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
NpcImpl npc = new NpcImpl(configManager, packetFactory, textSerializer, config.getString("world"), UUID uuid = config.contains("uuid") ? UUID.fromString(config.getString("uuid")) : UUID.randomUUID();
NpcImpl npc = new NpcImpl(uuid, configManager, packetFactory, textSerializer, config.getString("world"),
typeRegistry.getByName(config.getString("type")), deserializeLocation(config.getConfigurationSection("location"))); typeRegistry.getByName(config.getString("type")), deserializeLocation(config.getConfigurationSection("location")));
ConfigurationSection properties = config.getConfigurationSection("properties"); ConfigurationSection properties = config.getConfigurationSection("properties");
@ -83,6 +84,7 @@ public class YamlStorage implements NpcStorage {
config.set("allow-commands", entry.isAllowCommandModification()); config.set("allow-commands", entry.isAllowCommandModification());
NpcImpl npc = entry.getNpc(); NpcImpl npc = entry.getNpc();
config.set("uuid", npc.getUuid().toString());
config.set("world", npc.getWorldName()); config.set("world", npc.getWorldName());
config.set("location", serializeLocation(npc.getLocation())); config.set("location", serializeLocation(npc.getLocation()));
config.set("type", npc.getType().getName()); config.set("type", npc.getType().getName());