From 627098598912c01bf1e5a707b4f43a9bd7e53b26 Mon Sep 17 00:00:00 2001 From: fullwall Date: Sat, 3 Sep 2022 15:39:08 +0800 Subject: [PATCH] Make text edit check argument length, move some code into ProfileFetchThread --- .../main/java/net/citizensnpcs/Settings.java | 1 + .../citizensnpcs/commands/NPCCommands.java | 14 ++- .../npc/profile/ProfileFetchThread.java | 112 +++++++++++++++++- .../npc/profile/ProfileFetcher.java | 110 ----------------- .../java/net/citizensnpcs/npc/skin/Skin.java | 14 +++ .../trait/text/TextBasePrompt.java | 12 +- 6 files changed, 144 insertions(+), 119 deletions(-) diff --git a/main/src/main/java/net/citizensnpcs/Settings.java b/main/src/main/java/net/citizensnpcs/Settings.java index 065c81edd..68d4535d0 100644 --- a/main/src/main/java/net/citizensnpcs/Settings.java +++ b/main/src/main/java/net/citizensnpcs/Settings.java @@ -78,6 +78,7 @@ public class Settings { DEBUG_FILE("general.debug-file", ""), DEBUG_MODE("general.debug-mode", false), DEBUG_PATHFINDING("general.debug-pathfinding", false), + DEFAULT_BLOCK_BREAKER_RADIUS("npc.defaults.block-breaker-radius", -1), DEFAULT_CACHE_WAYPOINT_PATHS("npc.default.waypoints.cache-paths", false), DEFAULT_DESTINATION_TELEPORT_MARGIN("npc.pathfinding.defaults.destination-teleport-margin", -1), DEFAULT_DISTANCE_MARGIN("npc.pathfinding.default-distance-margin", 2), diff --git a/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java b/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java index 5188e55bd..588d1370b 100644 --- a/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java +++ b/main/src/main/java/net/citizensnpcs/commands/NPCCommands.java @@ -333,6 +333,8 @@ public class NPCCommands { BlockBreakerConfiguration cfg = new BlockBreakerConfiguration(); if (args.hasValueFlag("radius")) { cfg.radius(args.getFlagDouble("radius")); + } else if (Setting.DEFAULT_BLOCK_BREAKER_RADIUS.asDouble() > 0) { + cfg.radius(Setting.DEFAULT_BLOCK_BREAKER_RADIUS.asDouble()); } BlockBreaker breaker = npc.getBlockBreaker(args.getSenderTargetBlockLocation().getBlock(), cfg); npc.getDefaultGoalController().addBehavior(StatusMapper.singleUse(breaker), 1); @@ -1895,6 +1897,8 @@ public class NPCCommands { String owner = args.getFlag("owner"); Player playerOwner = Bukkit.getPlayerExact(owner); for (NPC rem : Lists.newArrayList(CitizensAPI.getNPCRegistry())) { + if (!rem.getOrAddTrait(Owner.class).isOwnedBy(sender)) + continue; if (playerOwner != null && rem.getOrAddTrait(Owner.class).isOwnedBy(playerOwner)) { history.add(sender, new RemoveNPCHistoryItem(rem)); rem.destroy(sender); @@ -1906,12 +1910,14 @@ public class NPCCommands { Messaging.sendTr(sender, Messages.NPCS_REMOVED); return; } + if (args.hasValueFlag("world")) { String world = args.getFlag("world"); for (NPC rem : Lists.newArrayList(CitizensAPI.getNPCRegistry())) { Location loc = rem.getStoredLocation(); - if (loc != null && loc.getWorld() != null && (loc.getWorld().getUID().toString().equals(world) - || loc.getWorld().getName().equalsIgnoreCase(world))) { + if (loc != null && rem.getOrAddTrait(Owner.class).isOwnedBy(sender) && loc.getWorld() != null + && (loc.getWorld().getUID().toString().equals(world) + || loc.getWorld().getName().equalsIgnoreCase(world))) { history.add(sender, new RemoveNPCHistoryItem(rem)); rem.destroy(sender); } @@ -1919,9 +1925,11 @@ public class NPCCommands { Messaging.sendTr(sender, Messages.NPCS_REMOVED); return; } + if (args.hasValueFlag("eid")) { Entity entity = Bukkit.getServer().getEntity(UUID.fromString(args.getFlag("eid"))); - if (entity != null && (npc = CitizensAPI.getNPCRegistry().getNPC(entity)) != null) { + if (entity != null && (npc = CitizensAPI.getNPCRegistry().getNPC(entity)) != null + && npc.getOrAddTrait(Owner.class).isOwnedBy(sender)) { history.add(sender, new RemoveNPCHistoryItem(npc)); npc.destroy(sender); Messaging.sendTr(sender, Messages.NPC_REMOVED, npc.getName(), npc.getId()); diff --git a/main/src/main/java/net/citizensnpcs/npc/profile/ProfileFetchThread.java b/main/src/main/java/net/citizensnpcs/npc/profile/ProfileFetchThread.java index bc8925422..c06c432aa 100644 --- a/main/src/main/java/net/citizensnpcs/npc/profile/ProfileFetchThread.java +++ b/main/src/main/java/net/citizensnpcs/npc/profile/ProfileFetchThread.java @@ -2,6 +2,7 @@ package net.citizensnpcs.npc.profile; import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Collection; import java.util.Deque; import java.util.HashMap; import java.util.List; @@ -12,8 +13,15 @@ import javax.annotation.Nullable; import org.bukkit.Bukkit; import com.google.common.base.Preconditions; +import com.google.common.base.Throwables; +import com.mojang.authlib.Agent; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.GameProfileRepository; +import com.mojang.authlib.ProfileLookupCallback; import net.citizensnpcs.api.CitizensAPI; +import net.citizensnpcs.api.util.Messaging; +import net.citizensnpcs.util.NMS; /** * Thread used to fetch profiles from the Mojang servers. @@ -25,7 +33,6 @@ import net.citizensnpcs.api.CitizensAPI; * @see ProfileFetcher */ class ProfileFetchThread implements Runnable { - private final ProfileFetcher profileFetcher = new ProfileFetcher(); private final Deque queue = new ArrayDeque(); private final Map requested = new HashMap(40); private final Object sync = new Object(); // sync for queue & requested fields @@ -106,6 +113,75 @@ class ProfileFetchThread implements Runnable { } } + /** + * Fetch one or more profiles. + * + * @param requests + * The profile requests. + */ + private void fetchRequests(final Collection requests) { + Preconditions.checkNotNull(requests); + + final GameProfileRepository repo = NMS.getGameProfileRepository(); + + String[] playerNames = new String[requests.size()]; + + int i = 0; + for (ProfileRequest request : requests) { + playerNames[i++] = request.getPlayerName(); + } + + repo.findProfilesByNames(playerNames, Agent.MINECRAFT, new ProfileLookupCallback() { + @Override + public void onProfileLookupFailed(GameProfile profile, Exception e) { + if (Messaging.isDebugging()) { + Messaging.debug( + "Profile lookup for player '" + profile.getName() + "' failed2: " + getExceptionMsg(e)); + Messaging.debug(Throwables.getStackTraceAsString(e)); + } + + ProfileRequest request = findRequest(profile.getName(), requests); + if (request == null) + return; + + if (isProfileNotFound(e)) { + request.setResult(null, ProfileFetchResult.NOT_FOUND); + } else if (isTooManyRequests(e)) { + request.setResult(null, ProfileFetchResult.TOO_MANY_REQUESTS); + } else { + request.setResult(null, ProfileFetchResult.FAILED); + } + } + + @Override + public void onProfileLookupSucceeded(final GameProfile profile) { + if (Messaging.isDebugging()) { + Messaging.debug("Fetched profile " + profile.getId() + " for player " + profile.getName()); + } + + ProfileRequest request = findRequest(profile.getName(), requests); + if (request == null) + return; + + try { + request.setResult(NMS.fillProfileProperties(profile, true), ProfileFetchResult.SUCCESS); + } catch (Throwable e) { + if (Messaging.isDebugging()) { + Messaging.debug("Profile lookup for player '" + profile.getName() + "' failed: " + + getExceptionMsg(e) + " " + isTooManyRequests(e)); + Messaging.debug(Throwables.getStackTraceAsString(e)); + } + + if (isTooManyRequests(e)) { + request.setResult(null, ProfileFetchResult.TOO_MANY_REQUESTS); + } else { + request.setResult(null, ProfileFetchResult.FAILED); + } + } + } + }); + } + @Override public void run() { List requests; @@ -118,7 +194,7 @@ class ProfileFetchThread implements Runnable { queue.clear(); } - profileFetcher.fetchRequests(requests); + fetchRequests(requests); } private static void addHandler(final ProfileRequest request, final ProfileFetchHandler handler) { @@ -130,6 +206,38 @@ class ProfileFetchThread implements Runnable { }, 1); } + @Nullable + private static ProfileRequest findRequest(String name, Collection requests) { + name = name.toLowerCase(); + + for (ProfileRequest request : requests) { + if (request.getPlayerName().equals(name)) { + return request; + } + } + return null; + } + + private static String getExceptionMsg(Throwable e) { + return Throwables.getRootCause(e).getMessage(); + } + + private static boolean isProfileNotFound(Exception e) { + String message = e.getMessage(); + String cause = e.getCause() != null ? e.getCause().getMessage() : null; + + return (message != null && message.contains("did not find")) + || (cause != null && cause.contains("did not find")); + } + + private static boolean isTooManyRequests(Throwable e) { + String message = e.getMessage(); + String cause = e.getCause() != null ? e.getCause().getMessage() : null; + + return (message != null && message.contains("too many requests")) + || (cause != null && cause.contains("too many requests")); + } + private static void sendResult(final ProfileFetchHandler handler, final ProfileRequest request) { Bukkit.getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() { @Override diff --git a/main/src/main/java/net/citizensnpcs/npc/profile/ProfileFetcher.java b/main/src/main/java/net/citizensnpcs/npc/profile/ProfileFetcher.java index cf2a1f433..0846bf459 100644 --- a/main/src/main/java/net/citizensnpcs/npc/profile/ProfileFetcher.java +++ b/main/src/main/java/net/citizensnpcs/npc/profile/ProfileFetcher.java @@ -1,22 +1,13 @@ package net.citizensnpcs.npc.profile; -import java.util.Collection; - import javax.annotation.Nullable; import org.bukkit.Bukkit; import org.bukkit.scheduler.BukkitTask; import com.google.common.base.Preconditions; -import com.google.common.base.Throwables; -import com.mojang.authlib.Agent; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.GameProfileRepository; -import com.mojang.authlib.ProfileLookupCallback; import net.citizensnpcs.api.CitizensAPI; -import net.citizensnpcs.api.util.Messaging; -import net.citizensnpcs.util.NMS; /** * Fetches game profiles that include skin data from Mojang servers. @@ -27,75 +18,6 @@ public class ProfileFetcher { ProfileFetcher() { } - /** - * Fetch one or more profiles. - * - * @param requests - * The profile requests. - */ - void fetchRequests(final Collection requests) { - Preconditions.checkNotNull(requests); - - final GameProfileRepository repo = NMS.getGameProfileRepository(); - - String[] playerNames = new String[requests.size()]; - - int i = 0; - for (ProfileRequest request : requests) { - playerNames[i++] = request.getPlayerName(); - } - - repo.findProfilesByNames(playerNames, Agent.MINECRAFT, new ProfileLookupCallback() { - @Override - public void onProfileLookupFailed(GameProfile profile, Exception e) { - if (Messaging.isDebugging()) { - Messaging.debug( - "Profile lookup for player '" + profile.getName() + "' failed2: " + getExceptionMsg(e)); - Messaging.debug(Throwables.getStackTraceAsString(e)); - } - - ProfileRequest request = findRequest(profile.getName(), requests); - if (request == null) - return; - - if (isProfileNotFound(e)) { - request.setResult(null, ProfileFetchResult.NOT_FOUND); - } else if (isTooManyRequests(e)) { - request.setResult(null, ProfileFetchResult.TOO_MANY_REQUESTS); - } else { - request.setResult(null, ProfileFetchResult.FAILED); - } - } - - @Override - public void onProfileLookupSucceeded(final GameProfile profile) { - if (Messaging.isDebugging()) { - Messaging.debug("Fetched profile " + profile.getId() + " for player " + profile.getName()); - } - - ProfileRequest request = findRequest(profile.getName(), requests); - if (request == null) - return; - - try { - request.setResult(NMS.fillProfileProperties(profile, true), ProfileFetchResult.SUCCESS); - } catch (Throwable e) { - if (Messaging.isDebugging()) { - Messaging.debug("Profile lookup for player '" + profile.getName() + "' failed: " - + getExceptionMsg(e) + " " + isTooManyRequests(e)); - Messaging.debug(Throwables.getStackTraceAsString(e)); - } - - if (isTooManyRequests(e)) { - request.setResult(null, ProfileFetchResult.TOO_MANY_REQUESTS); - } else { - request.setResult(null, ProfileFetchResult.FAILED); - } - } - } - }); - } - /** * Fetch a profile. * @@ -122,22 +44,6 @@ public class ProfileFetcher { PROFILE_THREAD.fetchForced(name, handler); } - @Nullable - private static ProfileRequest findRequest(String name, Collection requests) { - name = name.toLowerCase(); - - for (ProfileRequest request : requests) { - if (request.getPlayerName().equals(name)) { - return request; - } - } - return null; - } - - private static String getExceptionMsg(Throwable e) { - return Throwables.getRootCause(e).getMessage(); - } - private static void initThread() { if (THREAD_TASK != null) { THREAD_TASK.cancel(); @@ -147,22 +53,6 @@ public class ProfileFetcher { THREAD_TASK = Bukkit.getScheduler().runTaskTimerAsynchronously(CitizensAPI.getPlugin(), PROFILE_THREAD, 21, 20); } - private static boolean isProfileNotFound(Exception e) { - String message = e.getMessage(); - String cause = e.getCause() != null ? e.getCause().getMessage() : null; - - return (message != null && message.contains("did not find")) - || (cause != null && cause.contains("did not find")); - } - - private static boolean isTooManyRequests(Throwable e) { - String message = e.getMessage(); - String cause = e.getCause() != null ? e.getCause().getMessage() : null; - - return (message != null && message.contains("too many requests")) - || (cause != null && cause.contains("too many requests")); - } - /** * Clear all queued and cached requests. */ diff --git a/main/src/main/java/net/citizensnpcs/npc/skin/Skin.java b/main/src/main/java/net/citizensnpcs/npc/skin/Skin.java index f2797adf7..64064f212 100644 --- a/main/src/main/java/net/citizensnpcs/npc/skin/Skin.java +++ b/main/src/main/java/net/citizensnpcs/npc/skin/Skin.java @@ -116,6 +116,7 @@ public class Skin { return false; } } + setNPCSkinData(entity, skinName, skinId, skinData); return true; @@ -137,6 +138,7 @@ public class Skin { if (!npc.isSpawned()) return; + Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(CitizensAPI.getPlugin(), new Runnable() { @Override public void run() { @@ -154,12 +156,18 @@ public class Skin { } return; } + if (skinName.length() < 3 || skinName.length() > 16) { if (Messaging.isDebugging()) { Messaging.debug("Skin name invalid length '" + skinName + "'"); } return; } + + if (skinName.toLowerCase().startsWith("cit-")) { + return; + } + fetching = true; ProfileFetcher.fetch(this.skinName, new ProfileFetchHandler() { @@ -213,6 +221,11 @@ public class Skin { } return; } + + if (skinName.toLowerCase().startsWith("cit-")) { + return; + } + fetching = true; ProfileFetcher.fetchForced(this.skinName, new ProfileFetchHandler() { @@ -371,6 +384,7 @@ public class Skin { synchronized (CACHE) { skin = CACHE.get(skinName); } + if (skin == null) { skin = new Skin(skinName); } else if (forceUpdate) { diff --git a/main/src/main/java/net/citizensnpcs/trait/text/TextBasePrompt.java b/main/src/main/java/net/citizensnpcs/trait/text/TextBasePrompt.java index b55dd017c..4ec41edc5 100644 --- a/main/src/main/java/net/citizensnpcs/trait/text/TextBasePrompt.java +++ b/main/src/main/java/net/citizensnpcs/trait/text/TextBasePrompt.java @@ -32,11 +32,15 @@ public class TextBasePrompt extends StringPrompt { text.add(Joiner.on(' ').join(Arrays.copyOfRange(parts, 1, parts.length))); return this; } else if (input.equalsIgnoreCase("edit")) { - int index = Integer.parseInt(parts[1]); - if (!text.hasIndex(index)) { - Messaging.sendErrorTr(sender, Messages.TEXT_EDITOR_INVALID_INDEX, index); + if (parts.length < 2) { + Messaging.sendErrorTr(sender, Messages.TEXT_EDITOR_INVALID_INDEX, "missing index"); } else { - text.edit(index, Joiner.on(' ').join(Arrays.copyOfRange(parts, 2, parts.length))); + int index = Integer.parseInt(parts[1]); + if (!text.hasIndex(index)) { + Messaging.sendErrorTr(sender, Messages.TEXT_EDITOR_INVALID_INDEX, index); + } else { + text.edit(index, Joiner.on(' ').join(Arrays.copyOfRange(parts, 2, parts.length))); + } } } else if (input.equalsIgnoreCase("remove")) { int index = Integer.parseInt(parts[1]);