Fixed an issue with image loading on paper and added allow list for image hosting sites

This commit is contained in:
Vlammar 2021-11-11 21:41:37 +01:00
parent 0f05a05d84
commit 52ba80ab70
9 changed files with 96 additions and 7 deletions

View File

@ -60,7 +60,8 @@ public enum Permissions {
BYPASS_SIZE("imageonmap.bypasssize"),
BYPASS_IMAGE_LIMIT("imageonmap.bypassimagelimit"),
BYPASS_MAP_LIMIT("imageonmap.bypassmaplimit"),
GIVE("imageonmap.give");
GIVE("imageonmap.give"),
IGNOREALLOWLIST("imageonmap.ignoreallowlist_hostingsite");
private final String permission;
private final String[] aliases;

View File

@ -59,4 +59,6 @@ public final class PluginConfiguration extends Configuration {
public static ConfigurationItem<Integer> LIMIT_SIZE_X = item("limit-map-size-x", 0);
public static ConfigurationItem<Integer> LIMIT_SIZE_Y = item("limit-map-size-y", 0);
public static ConfigurationItem<String> ALLOWLIST_HOSTINGSITE = item("allowlist_hostingsite", "");
}

View File

@ -36,11 +36,14 @@
package fr.moribus.imageonmap.commands;
import fr.moribus.imageonmap.PluginConfiguration;
import fr.moribus.imageonmap.map.ImageMap;
import fr.moribus.imageonmap.map.MapManager;
import fr.zcraft.quartzlib.components.commands.Command;
import fr.zcraft.quartzlib.components.commands.CommandException;
import fr.zcraft.quartzlib.components.i18n.I;
import fr.zcraft.quartzlib.tools.PluginLogger;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@ -53,6 +56,23 @@ import org.bukkit.entity.Player;
public abstract class IoMCommand extends Command {
protected boolean checkHostingSite(URL url) {
PluginLogger.info("allow list " + PluginConfiguration.ALLOWLIST_HOSTINGSITE.get());
String urlsString = PluginConfiguration.ALLOWLIST_HOSTINGSITE.get();
if (urlsString.trim().equals("")) {
return true;
}
String[] hosts = urlsString.trim().replaceAll("https://","").split(",");
for (String host : hosts) {
PluginLogger.info(host);
PluginLogger.info(url.getHost());
if (url.getHost().equals(host.trim())) {
return true;
}
}
return false;
}
protected void retrieveUUID(String arg, Consumer<UUID> consumer) {
UUID uuid;
OfflinePlayer offlinePlayer;

View File

@ -107,6 +107,12 @@ public class NewCommand extends IoMCommand {
}
try {
url = new URL(args[0]);
if (!Permissions.IGNOREALLOWLIST.grantedTo(player) && !checkHostingSite(url)) {
throwInvalidArgument(I.t("This hosting website is not trusted, if you think that this is an error "
+ " contact your server administrator"));
return;
}
} catch (MalformedURLException ex) {
throwInvalidArgument(I.t("Invalid URL."));
return;

View File

@ -168,6 +168,12 @@ public class UpdateCommand extends IoMCommand {
URL url1;
try {
url1 = new URL(url);
if (!Permissions.IGNOREALLOWLIST.grantedTo(playerSender) && !checkHostingSite(url1)) {
throwInvalidArgument(I.t("This hosting website is not trusted, if you think that this is an error "
+ " contact your server administrator"));
return;
}
//TODO replace by a check of the load status.(if not loaded load the mapmanager)
MapManager.load(false);//we don't want to spam the console each time we reload the mapManager
@ -211,7 +217,7 @@ public class UpdateCommand extends IoMCommand {
ActionBar.removeMessage(playerSender);
}
}
} catch (MalformedURLException ex) {
} catch (MalformedURLException | CommandException ex) {
warning(sender, I.t("Invalid URL."));
}
});

View File

@ -38,6 +38,7 @@ package fr.moribus.imageonmap.image;
import fr.moribus.imageonmap.Permissions;
import fr.moribus.imageonmap.PluginConfiguration;
import fr.moribus.imageonmap.commands.IoMCommand;
import fr.moribus.imageonmap.map.ImageMap;
import fr.moribus.imageonmap.map.MapManager;
import fr.zcraft.quartzlib.components.i18n.I;
@ -98,6 +99,7 @@ public class ImageRendererExecutor extends Worker {
public ImageMap run() throws Throwable {
BufferedImage image = null;
//If the link is an imgur one
if (url.toString().toLowerCase().startsWith("https://imgur.com/")) {
@ -162,7 +164,6 @@ public class ImageRendererExecutor extends Worker {
submitQuery(new WorkerRunnable<ImageMap>() {
@Override
public ImageMap run() throws Throwable {
final URLConnection connection = connecting(url);
final InputStream stream = connection.getInputStream();

View File

@ -38,10 +38,16 @@ package fr.moribus.imageonmap.image;
import fr.moribus.imageonmap.ImageOnMap;
import fr.moribus.imageonmap.map.MapManager;
import fr.zcraft.quartzlib.components.events.FutureEventHandler;
import fr.zcraft.quartzlib.components.events.FutureEvents;
import fr.zcraft.quartzlib.components.events.WrappedEvent;
import fr.zcraft.quartzlib.core.QuartzLib;
import fr.zcraft.quartzlib.tools.PluginLogger;
import fr.zcraft.quartzlib.tools.reflection.Reflection;
import fr.zcraft.quartzlib.tools.runners.RunTask;
import java.io.File;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Entity;
@ -53,13 +59,17 @@ import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.world.ChunkEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.map.MapView;
public class MapInitEvent implements Listener {
public static void init() {
QuartzLib.registerEvents(new MapInitEvent());
FutureEvents.registerFutureEvents(new EntitiesLoadListener());
for (World world : Bukkit.getWorlds()) {
for (ItemFrame frame : world.getEntitiesByClass(ItemFrame.class)) {
@ -98,7 +108,6 @@ public class MapInitEvent implements Listener {
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
//Fix for paper
RunTask.later(() -> {
for (Entity entity : event.getChunk().getEntities()) {
if (entity instanceof ItemFrame) {
@ -135,4 +144,41 @@ public class MapInitEvent implements Listener {
}
}
protected static final class EntitiesLoadListener implements Listener {
@FutureEventHandler(event = "world.EntitiesLoadEvent")
public void onEntitiesLoad(WrappedEvent event) {
//New in 1.17
//Used to make sure map are really loaded in 1.17 on Paper (else some won't render or update properly)
RunTask.later(() -> {
try {
Chunk chunk = (Chunk) Reflection.call(event.getEvent(), "getChunk");
Entity[] entities = chunk.getEntities();
//Not the most efficient method because we go through entity already loaded
//The direct method using getEntities of
// https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/world/EntitiesLoadEvent.html
//Return an unmodifiable list of entities.
//Using this make the overall process a bit more efficient but way more complicated and very weak
// to change.
//TODO Investigate if there is a better way to do this.
//Early exit, most are empty entities array
if (entities.length == 0) {
return;
}
for (Entity entity : entities) {
if (entity instanceof ItemFrame) {
initMap(((ItemFrame) entity).getItem());
}
}
} catch (Exception e) {
PluginLogger.error(e.toString());
return;
}
}, 5L);
}
}
}

View File

@ -26,3 +26,6 @@ limit-map-size-y: 0
# Should the full image be saved when a map is rendered?
save-full-image: false
# Give the name of trusted image hosting website
#Example allowlist_hostingsite: https://imgur.com/, https://i.imgur.com/, https://cdn.discordapp.com
allowlist_hostingsite:

View File

@ -40,7 +40,7 @@ permissions:
imageonmap.updateother: false
imageonmap.bypassmaplimit: false
imageonmap.bypassimagelimit: false
imageonmap.ignoreallowlist_hostingsite: true
imageonmap.userender:
description: "Allows you to use /tomap and related commands (/maptool getremaining). Alias of imageonmap.new."
default: true
@ -118,5 +118,9 @@ permissions:
default: op
imageonmap.bypassimagelimit:
description: "Allows you to bypass permission node check for the number of images in the playerMapStore(by default users have an unlimited amount of images)."
default: op
description: "Allows you to bypass permission node check for the number of images in the playerMapStore (by default users have an unlimited amount of images)."
default: op
imageonmap.ignoreallowlist_hostingsite:
description: "Allows you to ignore the restriction on the allow list for image hosting website."
default: true