improve holo commands, add skin command

This commit is contained in:
Pyrbu 2023-05-11 14:25:26 +01:00
parent ca94951b63
commit e6a7e6f2f0
7 changed files with 90 additions and 9 deletions

@ -190,6 +190,7 @@ public class ZNpcsPlus extends JavaPlugin {
manager.registerCommand("npc", new MultiCommand()
.addSubcommand("action", new ActionCommand())
.addSubcommand("create", new CreateCommand())
.addSubcommand("skin", new SkinCommand())
.addSubcommand("delete", new DeleteCommand())
.addSubcommand("move", new MoveCommand())
.addSubcommand("properties", new PropertiesCommand())

@ -0,0 +1,67 @@
package lol.pyr.znpcsplus.commands;
import lol.pyr.director.adventure.command.CommandContext;
import lol.pyr.director.adventure.command.CommandHandler;
import lol.pyr.director.common.command.CommandExecutionException;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
import lol.pyr.znpcsplus.npc.NpcImpl;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor;
import lol.pyr.znpcsplus.skin.descriptor.MirrorDescriptor;
import lol.pyr.znpcsplus.skin.descriptor.PrefetchedDescriptor;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import java.util.Collections;
import java.util.List;
public class SkinCommand implements CommandHandler {
@Override
public void run(CommandContext context) throws CommandExecutionException {
context.setUsage(context.getLabel() + " skin <id> <type> [value]");
NpcImpl npc = context.parse(NpcEntryImpl.class).getNpc();
if (npc.getType() != NpcTypeImpl.byName("player")) context.halt(Component.text("The NPC must be a player to have a skin", NamedTextColor.RED));
String type = context.popString();
if (type.equalsIgnoreCase("mirror")) {
npc.setProperty(EntityPropertyImpl.SKIN, new MirrorDescriptor());
npc.respawn();
context.halt(Component.text("The NPC's skin will now mirror the player that it's being displayed to", NamedTextColor.GREEN));
}
if (type.equalsIgnoreCase("static")) {
context.ensureArgsNotEmpty();
String name = context.dumpAllArgs();
context.send(Component.text("Fetching skin \"" + name + "\"...", NamedTextColor.GREEN));
PrefetchedDescriptor.forPlayer(name).thenAccept(skin -> {
if (skin == null) {
context.send(Component.text("Failed to fetch skin, are you sure the player name is valid?", NamedTextColor.RED));
return;
}
npc.setProperty(EntityPropertyImpl.SKIN, skin);
npc.respawn();
context.send(Component.text("The NPC's skin has been set to \"" + name + "\""));
});
return;
}
if (type.equalsIgnoreCase("dynamic")) {
context.ensureArgsNotEmpty();
String name = context.dumpAllArgs();
npc.setProperty(EntityPropertyImpl.SKIN, new FetchingDescriptor(name));
npc.respawn();
context.halt(Component.text("The NPC's skin will now be resolved per-player from \"" + name + "\""));
}
context.send(Component.text("Unknown skin type! Please use one of the following: mirror, static, dynamic"));
}
@Override
public List<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(NpcRegistryImpl.get().modifiableIds());
if (context.argSize() == 2) return context.suggestLiteral("mirror", "static", "dynamic");
if (context.matchSuggestion("*", "static")) return context.suggestPlayers();
return Collections.emptyList();
}
}

@ -18,6 +18,7 @@ public class HoloAddCommand implements CommandHandler {
public void run(CommandContext context) throws CommandExecutionException {
context.setUsage(context.getLabel() + " holo add <id> <text>");
HologramImpl hologram = context.parse(NpcEntryImpl.class).getNpc().getHologram();
context.ensureArgsNotEmpty();
hologram.addLine(ZNpcsPlus.LEGACY_AMPERSAND_SERIALIZER.deserialize(context.dumpAllArgs()));
context.send(Component.text("NPC line added!", NamedTextColor.GREEN));
}

@ -21,6 +21,7 @@ public class HoloInsertCommand implements CommandHandler {
HologramImpl hologram = context.parse(NpcEntryImpl.class).getNpc().getHologram();
int line = context.parse(Integer.class);
if (line < 0 || line >= hologram.getLines().size()) context.halt(Component.text("Invalid line number!", NamedTextColor.RED));
context.ensureArgsNotEmpty();
hologram.insertLine(line, ZNpcsPlus.LEGACY_AMPERSAND_SERIALIZER.deserialize(context.dumpAllArgs()));
context.send(Component.text("NPC line inserted!", NamedTextColor.GREEN));
}

@ -21,6 +21,7 @@ public class HoloSetCommand implements CommandHandler {
HologramImpl hologram = context.parse(NpcEntryImpl.class).getNpc().getHologram();
int line = context.parse(Integer.class);
if (line < 0 || line >= hologram.getLines().size()) context.halt(Component.text("Invalid line number!", NamedTextColor.RED));
context.ensureArgsNotEmpty();
hologram.removeLine(line);
hologram.insertLine(line, ZNpcsPlus.LEGACY_AMPERSAND_SERIALIZER.deserialize(context.dumpAllArgs()));
context.send(Component.text("NPC line set!", NamedTextColor.GREEN));

@ -31,4 +31,9 @@ public interface MainConfig {
@ConfComments("The storage type to use. Available storage types: YAML")
@DefaultString("YAML")
NpcStorageType storageType();
@ConfKey("disable-skin-fetcher-warnings")
@ConfComments("Set this to true if you don't want to be warned in the console when a skin fails to resolve")
@DefaultBoolean(false)
boolean disableSkinFetcherWarnings();
}

@ -3,6 +3,8 @@ package lol.pyr.znpcsplus.skin.cache;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.mojang.authlib.GameProfile;
import lol.pyr.znpcsplus.ZNpcsPlus;
import lol.pyr.znpcsplus.config.Configs;
import lol.pyr.znpcsplus.reflection.Reflections;
import lol.pyr.znpcsplus.skin.Skin;
import org.bukkit.Bukkit;
@ -36,8 +38,7 @@ public class SkinCache {
if (cache.containsKey(name.toLowerCase())) return fetchByUUID(idCache.get(name.toLowerCase()).getId());
CompletableFuture<Skin> future = new CompletableFuture<>();
CompletableFuture.runAsync(() -> {
return CompletableFuture.supplyAsync(() -> {
URL url = parseUrl("https://api.mojang.com/users/profiles/minecraft/" + name);
HttpURLConnection connection = null;
try {
@ -45,18 +46,21 @@ public class SkinCache {
connection.setRequestMethod("GET");
try (Reader reader = new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)) {
JsonObject obj = JsonParser.parseReader(reader).getAsJsonObject();
if (obj.has("errorMessage")) future.complete(null);
if (obj.has("errorMessage")) return null;
String id = obj.get("id").getAsString();
idCache.put(name.toLowerCase(), new CachedId(id));
fetchByUUID(id).thenAccept(future::complete);
return fetchByUUID(id).join();
}
} catch (IOException exception) {
exception.printStackTrace();
if (!Configs.config().disableSkinFetcherWarnings()) {
ZNpcsPlus.LOGGER.warning("Failed to uuid from player name:");
exception.printStackTrace();
}
} finally {
if (connection != null) connection.disconnect();
}
return null;
});
return future;
}
public static CompletableFuture<Skin> fetchByUUID(UUID uuid) {
@ -96,7 +100,6 @@ public class SkinCache {
HttpURLConnection connection = null;
try {
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
try (Reader reader = new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)) {
JsonObject obj = JsonParser.parseReader(reader).getAsJsonObject();
@ -105,11 +108,13 @@ public class SkinCache {
return skin;
}
} catch (IOException exception) {
exception.printStackTrace();
if (!Configs.config().disableSkinFetcherWarnings()) {
ZNpcsPlus.LOGGER.warning("Failed to fetch skin:");
exception.printStackTrace();
}
} finally {
if (connection != null) connection.disconnect();
}
Bukkit.broadcastMessage("failed");
return null;
});
}