mirror of
https://github.com/zDevelopers/ImageOnMap.git
synced 2024-09-28 22:47:45 +02:00
commit
5191dca932
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -15,7 +15,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
java: [8, 9, 10, 11, 12, 13, 14, 15]
|
||||
java: [8, 11, 16, 17]
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
2
pom.xml
2
pom.xml
@ -39,7 +39,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>fr.moribus</groupId>
|
||||
<artifactId>ImageOnMap</artifactId>
|
||||
<version>4.1.2</version>
|
||||
<version>4.2.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
|
@ -43,7 +43,6 @@ import fr.moribus.imageonmap.commands.maptool.GetCommand;
|
||||
import fr.moribus.imageonmap.commands.maptool.GetRemainingCommand;
|
||||
import fr.moribus.imageonmap.commands.maptool.GiveCommand;
|
||||
import fr.moribus.imageonmap.commands.maptool.ListCommand;
|
||||
import fr.moribus.imageonmap.commands.maptool.MigrateCommand;
|
||||
import fr.moribus.imageonmap.commands.maptool.NewCommand;
|
||||
import fr.moribus.imageonmap.commands.maptool.RenameCommand;
|
||||
import fr.moribus.imageonmap.commands.maptool.UpdateCommand;
|
||||
@ -51,8 +50,6 @@ import fr.moribus.imageonmap.image.ImageIOExecutor;
|
||||
import fr.moribus.imageonmap.image.ImageRendererExecutor;
|
||||
import fr.moribus.imageonmap.image.MapInitEvent;
|
||||
import fr.moribus.imageonmap.map.MapManager;
|
||||
import fr.moribus.imageonmap.migration.MigratorExecutor;
|
||||
import fr.moribus.imageonmap.migration.V3Migrator;
|
||||
import fr.moribus.imageonmap.ui.MapItemManager;
|
||||
import fr.zcraft.quartzlib.components.commands.CommandWorkers;
|
||||
import fr.zcraft.quartzlib.components.commands.Commands;
|
||||
@ -104,7 +101,7 @@ public final class ImageOnMap extends QuartzPlugin {
|
||||
public void onEnable() {
|
||||
// Creating the images and maps directories if necessary
|
||||
try {
|
||||
imagesDirectory = checkPluginDirectory(imagesDirectory, V3Migrator.getOldImagesDirectory(this));
|
||||
//imagesDirectory = checkPluginDirectory(imagesDirectory, V3Migrator.getOldImagesDirectory(this));
|
||||
checkPluginDirectory(mapsDirectory);
|
||||
} catch (final IOException ex) {
|
||||
PluginLogger.error("FATAL: " + ex.getMessage());
|
||||
@ -136,7 +133,7 @@ public final class ImageOnMap extends QuartzPlugin {
|
||||
GiveCommand.class,
|
||||
GetRemainingCommand.class,
|
||||
ExploreCommand.class,
|
||||
MigrateCommand.class,
|
||||
//MigrateCommand.class,//Removed for now doesn't work nor is useful, maybe useful later on
|
||||
UpdateCommand.class
|
||||
);
|
||||
|
||||
@ -161,7 +158,7 @@ public final class ImageOnMap extends QuartzPlugin {
|
||||
public void onDisable() {
|
||||
MapManager.exit();
|
||||
MapItemManager.exit();
|
||||
MigratorExecutor.waitForMigration();
|
||||
//MigratorExecutor.waitForMigration();//Removed for now doesn't work nor is useful, maybe useful later on
|
||||
|
||||
super.onDisable();
|
||||
}
|
||||
|
@ -37,7 +37,11 @@
|
||||
package fr.moribus.imageonmap;
|
||||
|
||||
|
||||
import fr.zcraft.quartzlib.components.i18n.I;
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
import java.util.Set;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.bukkit.permissions.PermissionAttachmentInfo;
|
||||
|
||||
public enum Permissions {
|
||||
NEW("imageonmap.new", "imageonmap.userender"),
|
||||
@ -47,6 +51,7 @@ public enum Permissions {
|
||||
GETOTHER("imageonmap.getother"),
|
||||
RENAME("imageonmap.rename"),
|
||||
PLACE_SPLATTER_MAP("imageonmap.placesplattermap"),
|
||||
PLACE_INVISIBLE_SPLATTER_MAP("imageonmap.placeinvisiblesplattermap"),
|
||||
REMOVE_SPLATTER_MAP("imageonmap.removesplattermap"),
|
||||
DELETE("imageonmap.delete"),
|
||||
DELETEOTHER("imageonmap.deleteother"),
|
||||
@ -54,7 +59,10 @@ public enum Permissions {
|
||||
UPDATEOTHER("imageonmap.updateother"),
|
||||
ADMINISTRATIVE("imageonmap.administrative"),
|
||||
BYPASS_SIZE("imageonmap.bypasssize"),
|
||||
GIVE("imageonmap.give");
|
||||
BYPASS_IMAGE_LIMIT("imageonmap.bypassimagelimit"),
|
||||
BYPASS_MAP_LIMIT("imageonmap.bypassmaplimit"),
|
||||
GIVE("imageonmap.give"),
|
||||
IGNOREALLOWLIST("imageonmap.ignoreallowlist_hostingsite");
|
||||
|
||||
private final String permission;
|
||||
private final String[] aliases;
|
||||
@ -83,4 +91,37 @@ public enum Permissions {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the limit of map the user is allowed to make
|
||||
*
|
||||
* @param permissible The permissible to check.
|
||||
* @return the limit
|
||||
*/
|
||||
public int getLimitPermission(Permissible permissible, LimitType type) {
|
||||
Set<PermissionAttachmentInfo> perms = permissible.getEffectivePermissions();
|
||||
String prefix = String.format("imageonmap.%slimit.", type.name());
|
||||
for (PermissionAttachmentInfo pai : perms) {
|
||||
String permString = pai.getPermission().toLowerCase();
|
||||
if (permString.startsWith(prefix)) {
|
||||
if (pai.getValue()) {
|
||||
try {
|
||||
int limit = Integer.parseInt(permString.split(prefix)[1].trim());
|
||||
return limit;
|
||||
} catch (Exception e) {
|
||||
PluginLogger.warning(
|
||||
I.t("The correct syntax for setting map limit node is: ImageOnMap.mapLimit.X "
|
||||
+ "where you can replace X with the limit of map a player is allowed to have"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return 2147483647; //Virtually no limit
|
||||
}
|
||||
|
||||
public enum LimitType {
|
||||
map,
|
||||
image
|
||||
}
|
||||
}
|
@ -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", "");
|
||||
|
||||
}
|
||||
|
@ -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,20 @@ import org.bukkit.entity.Player;
|
||||
public abstract class IoMCommand extends Command {
|
||||
|
||||
|
||||
protected boolean checkHostingSite(URL url) {
|
||||
String urlsString = PluginConfiguration.ALLOWLIST_HOSTINGSITE.get();
|
||||
if (urlsString.trim().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
String[] hosts = urlsString.trim().replaceAll("https://","").split(",");
|
||||
for (String host : hosts) {
|
||||
if (url.getHost().equals(host.trim())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void retrieveUUID(String arg, Consumer<UUID> consumer) {
|
||||
UUID uuid;
|
||||
OfflinePlayer offlinePlayer;
|
||||
|
@ -41,6 +41,7 @@ import fr.moribus.imageonmap.commands.IoMCommand;
|
||||
import fr.moribus.imageonmap.image.ImageRendererExecutor;
|
||||
import fr.moribus.imageonmap.image.ImageUtils;
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.moribus.imageonmap.map.MapManager;
|
||||
import fr.moribus.imageonmap.map.PosterMap;
|
||||
import fr.zcraft.quartzlib.components.commands.CommandException;
|
||||
import fr.zcraft.quartzlib.components.commands.CommandInfo;
|
||||
@ -87,9 +88,35 @@ public class NewCommand extends IoMCommand {
|
||||
if (args.length < 1) {
|
||||
throwInvalidArgument(I.t("You must give an URL to take the image from."));
|
||||
}
|
||||
|
||||
//Checking if the map limit and image limit
|
||||
if (!Permissions.BYPASS_IMAGE_LIMIT.grantedTo(player)) {
|
||||
int imageLimit = Permissions.NEW.getLimitPermission(player, Permissions.LimitType.image);
|
||||
int imageCount = MapManager.getPlayerMapStore(player.getUniqueId()).getImagesCount();
|
||||
if (imageLimit <= imageCount) {
|
||||
throwInvalidArgument(
|
||||
I.t("Your image limit is set to {0} and you currently have {1} loaded image(s)",
|
||||
imageLimit,
|
||||
imageCount));
|
||||
}
|
||||
}
|
||||
if (!Permissions.BYPASS_MAP_LIMIT.grantedTo(player)) {
|
||||
int mapLimit = Permissions.NEW.getLimitPermission(player, Permissions.LimitType.map);
|
||||
int mapCount = MapManager.getPlayerMapStore(player.getUniqueId()).getMapCount();
|
||||
if (mapLimit <= mapCount) {
|
||||
throwInvalidArgument(
|
||||
I.t("Your map limit is set to {0} and you currently have {1} loaded map(s)",
|
||||
mapLimit,
|
||||
mapCount));
|
||||
}
|
||||
}
|
||||
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;
|
||||
@ -121,7 +148,7 @@ public class NewCommand extends IoMCommand {
|
||||
}
|
||||
scaling = resizeMode();
|
||||
}
|
||||
if (width == 0 || height == 0) {
|
||||
if (width < 0 || height < 0) {
|
||||
throwInvalidArgument(I.t("You need to specify a valid size. e.g. resize 4 5"));
|
||||
return;
|
||||
}
|
||||
|
@ -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."));
|
||||
}
|
||||
});
|
||||
|
@ -46,6 +46,7 @@ import fr.zcraft.quartzlib.components.gui.Gui;
|
||||
import fr.zcraft.quartzlib.components.gui.GuiAction;
|
||||
import fr.zcraft.quartzlib.components.gui.PromptGui;
|
||||
import fr.zcraft.quartzlib.components.i18n.I;
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
import fr.zcraft.quartzlib.tools.items.ItemStackBuilder;
|
||||
import fr.zcraft.quartzlib.tools.runners.RunTask;
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
@ -208,32 +209,35 @@ public class MapDetailGui extends ExplorerGui<Integer> {
|
||||
return;
|
||||
}
|
||||
|
||||
PromptGui.prompt(getPlayer(), newName -> {
|
||||
if (!Permissions.RENAME.grantedTo(getPlayer())) {
|
||||
I.sendT(getPlayer(), "{ce}You are no longer allowed to do that.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
PromptGui.prompt(getPlayer(), newName -> {
|
||||
if (!Permissions.RENAME.grantedTo(getPlayer())) {
|
||||
I.sendT(getPlayer(), "{ce}You are no longer allowed to do that.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (newName == null || newName.isEmpty()) {
|
||||
I.sendT(getPlayer(), "{ce}Map names can't be empty.");
|
||||
return;
|
||||
}
|
||||
if (newName.equals(map.getName())) {
|
||||
return;
|
||||
}
|
||||
if (newName == null || newName.isEmpty()) {
|
||||
I.sendT(getPlayer(), "{ce}Map names can't be empty.");
|
||||
return;
|
||||
}
|
||||
if (newName.equals(map.getName())) {
|
||||
return;
|
||||
}
|
||||
|
||||
map.rename(newName);
|
||||
I.sendT(getPlayer(), "{cs}Map successfully renamed.");
|
||||
map.rename(newName);
|
||||
I.sendT(getPlayer(), "{cs}Map successfully renamed.");
|
||||
|
||||
if (getParent() != null) {
|
||||
RunTask.later(() -> Gui.open(getPlayer(), this), 1L);
|
||||
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
}, map.getName(), this);
|
||||
if (getParent() != null) {
|
||||
RunTask.later(() -> Gui.open(getPlayer(), this), 1L);
|
||||
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
}, map.getName(), this);
|
||||
|
||||
} catch (IllegalStateException e) {
|
||||
PluginLogger.error("Error while renaming map: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
@GuiAction("delete")
|
||||
|
@ -98,6 +98,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 +163,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();
|
||||
|
@ -38,9 +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;
|
||||
@ -49,7 +56,10 @@ import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageByBlockEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||
import org.bukkit.event.hanging.HangingBreakEvent;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
@ -57,8 +67,11 @@ 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)) {
|
||||
@ -97,11 +110,13 @@ public class MapInitEvent implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onChunkLoad(ChunkLoadEvent event) {
|
||||
for (Entity entity : event.getChunk().getEntities()) {
|
||||
if (entity instanceof ItemFrame) {
|
||||
initMap(((ItemFrame) entity).getItem());
|
||||
RunTask.later(() -> {
|
||||
for (Entity entity : event.getChunk().getEntities()) {
|
||||
if (entity instanceof ItemFrame) {
|
||||
initMap(((ItemFrame) entity).getItem());
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 5L);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -131,4 +146,114 @@ public class MapInitEvent implements Listener {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) {
|
||||
//Negate entity interaction with item frame containing IoM maps.
|
||||
|
||||
Entity entity = event.getEntity();
|
||||
if (!(entity instanceof ItemFrame)) {
|
||||
return;
|
||||
}
|
||||
Entity damager = event.getDamager();
|
||||
if (damager instanceof Player) {
|
||||
//can solve the dup with the map here by doing a better handling
|
||||
return;
|
||||
}
|
||||
ItemStack item = ((ItemFrame) entity).getItem();
|
||||
if (item.getType() == Material.FILLED_MAP) {
|
||||
//if the map exist we canceled the event
|
||||
if (MapManager.getMap(item) != null) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEntityDamageByBlockEvent(EntityDamageByBlockEvent event) {
|
||||
//Negate damage done to IoM maps by some blocks
|
||||
|
||||
Entity entity = event.getEntity();
|
||||
if (!(entity instanceof ItemFrame)) {
|
||||
return;
|
||||
}
|
||||
ItemStack item = ((ItemFrame) entity).getItem();
|
||||
if (item.getType() == Material.FILLED_MAP) {
|
||||
//if the map exist we canceled the event
|
||||
if (MapManager.getMap(item) != null) {
|
||||
switch (event.getCause()) {
|
||||
case MAGIC:
|
||||
case ENTITY_EXPLOSION:
|
||||
case FIRE_TICK:
|
||||
case LIGHTNING:
|
||||
case CRAMMING:
|
||||
case WITHER:
|
||||
case SUFFOCATION:
|
||||
case DROWNING:
|
||||
case BLOCK_EXPLOSION:
|
||||
event.setCancelled(true);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onHangingBreakEvent(HangingBreakEvent event) {
|
||||
Entity entity = event.getEntity();
|
||||
if (!(entity instanceof ItemFrame)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack item = ((ItemFrame) entity).getItem();
|
||||
if (item.getType() == Material.FILLED_MAP) {
|
||||
//if the map exist we canceled the event
|
||||
if (MapManager.getMap(item) != null) {
|
||||
if (event.getCause() == HangingBreakEvent.RemoveCause.EXPLOSION) {
|
||||
//creeper goes boom
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -37,17 +37,16 @@
|
||||
package fr.moribus.imageonmap.ui;
|
||||
|
||||
import fr.moribus.imageonmap.Permissions;
|
||||
import fr.moribus.imageonmap.PluginConfiguration;
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.moribus.imageonmap.map.MapManager;
|
||||
import fr.moribus.imageonmap.map.PosterMap;
|
||||
import fr.moribus.imageonmap.map.SingleMap;
|
||||
import fr.zcraft.quartzlib.components.i18n.I;
|
||||
import fr.zcraft.quartzlib.core.QuartzLib;
|
||||
import fr.zcraft.quartzlib.tools.PluginLogger;
|
||||
import fr.zcraft.quartzlib.tools.items.ItemStackBuilder;
|
||||
import fr.zcraft.quartzlib.tools.items.ItemUtils;
|
||||
import fr.zcraft.quartzlib.tools.runners.RunTask;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.HashMap;
|
||||
import java.util.Queue;
|
||||
@ -320,7 +319,6 @@ public class MapItemManager implements Listener {
|
||||
|| !SplatterMapManager.hasSplatterMap(player, poster)) {
|
||||
poster.give(player);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -329,7 +327,7 @@ public class MapItemManager implements Listener {
|
||||
if (!MapManager.managesMap(frame.getItem())) {
|
||||
return;
|
||||
}
|
||||
|
||||
SplatterMapManager.removePropertiesFromFrames(player, frame);
|
||||
frame.setItem(new ItemStackBuilder(item)
|
||||
.title(getMapTitle(item))
|
||||
.hideAllAttributes()
|
||||
|
@ -37,6 +37,7 @@
|
||||
package fr.moribus.imageonmap.ui;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import fr.moribus.imageonmap.Permissions;
|
||||
import fr.moribus.imageonmap.image.MapInitEvent;
|
||||
import fr.moribus.imageonmap.map.ImageMap;
|
||||
import fr.moribus.imageonmap.map.MapManager;
|
||||
@ -53,6 +54,7 @@ import fr.zcraft.quartzlib.tools.runners.RunTask;
|
||||
import fr.zcraft.quartzlib.tools.text.MessageSender;
|
||||
import fr.zcraft.quartzlib.tools.world.FlatLocation;
|
||||
import fr.zcraft.quartzlib.tools.world.WorldUtils;
|
||||
import java.lang.reflect.Method;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.Material;
|
||||
@ -65,7 +67,8 @@ import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.MapMeta;
|
||||
|
||||
|
||||
//TODO rework splatter effect, using ID is far more stable than nbt tags.
|
||||
// To update when adding small picture previsualization.
|
||||
public abstract class SplatterMapManager {
|
||||
private SplatterMapManager() {
|
||||
}
|
||||
@ -137,6 +140,7 @@ public abstract class SplatterMapManager {
|
||||
* @return True if the attribute was detected.
|
||||
*/
|
||||
public static boolean hasSplatterAttributes(ItemStack itemStack) {
|
||||
|
||||
try {
|
||||
final NBTCompound nbt = NBT.fromItemStack(itemStack);
|
||||
if (!nbt.containsKey("Enchantments")) {
|
||||
@ -240,6 +244,7 @@ public abstract class SplatterMapManager {
|
||||
//Rotation management relative to player rotation the default position is North,
|
||||
// when on ceiling we flipped the rotation
|
||||
RunTask.later(() -> {
|
||||
addPropertiesToFrames(player, frame);
|
||||
frame.setItem(
|
||||
new ItemStackBuilder(Material.FILLED_MAP).nbt(ImmutableMap.of("map", id)).craftItem());
|
||||
}, 5L);
|
||||
@ -301,6 +306,7 @@ public abstract class SplatterMapManager {
|
||||
int id = poster.getMapIdAtReverseY(i);
|
||||
|
||||
RunTask.later(() -> {
|
||||
addPropertiesToFrames(player, frame);
|
||||
frame.setItem(
|
||||
new ItemStackBuilder(Material.FILLED_MAP).nbt(ImmutableMap.of("map", id)).craftItem());
|
||||
}, 5L);
|
||||
@ -359,10 +365,31 @@ public abstract class SplatterMapManager {
|
||||
|
||||
for (ItemFrame frame : matchingFrames) {
|
||||
if (frame != null) {
|
||||
removePropertiesFromFrames(player, frame);
|
||||
frame.setItem(null);
|
||||
}
|
||||
}
|
||||
|
||||
return poster;
|
||||
}
|
||||
|
||||
public static void addPropertiesToFrames(Player player, ItemFrame frame) {
|
||||
if (Permissions.PLACE_INVISIBLE_SPLATTER_MAP.grantedTo(player)) {
|
||||
try {
|
||||
Method setVisible = frame.getClass().getMethod("setVisible", boolean.class);
|
||||
setVisible.invoke(frame, false);
|
||||
} catch (Exception e) {
|
||||
//1.16-
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void removePropertiesFromFrames(Player player, ItemFrame frame) {
|
||||
try {
|
||||
Method setVisible = frame.getClass().getMethod("setVisible", boolean.class);
|
||||
setVisible.invoke(frame, true);
|
||||
} catch (Exception e) {
|
||||
//1.16-
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -1,6 +1,6 @@
|
||||
name: ImageOnMap
|
||||
main: fr.moribus.imageonmap.ImageOnMap
|
||||
version: "4.1.2"
|
||||
version: "4.2.0"
|
||||
api-version: "1.13"
|
||||
|
||||
|
||||
@ -38,6 +38,10 @@ permissions:
|
||||
imageonmap.give: false
|
||||
imageonmap.update: true
|
||||
imageonmap.updateother: false
|
||||
imageonmap.bypassmaplimit: false
|
||||
imageonmap.bypassimagelimit: false
|
||||
imageonmap.ignoreallowlist_hostingsite: true
|
||||
imageonmap.placeinvisiblesplattermap: true
|
||||
|
||||
imageonmap.userender:
|
||||
description: "Allows you to use /tomap and related commands (/maptool getremaining). Alias of imageonmap.new."
|
||||
@ -110,3 +114,19 @@ permissions:
|
||||
imageonmap.updateother:
|
||||
description: "Allows you to update an existing map of an other player with a new image."
|
||||
default: op
|
||||
|
||||
imageonmap.bypassmaplimit:
|
||||
description: "Allows you to bypass permission node check for the number of used map (by default users have an unlimited amount of maps)."
|
||||
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
|
||||
|
||||
imageonmap.ignoreallowlist_hostingsite:
|
||||
description: "Allows you to ignore the restriction on the allow list for image hosting website."
|
||||
default: true
|
||||
|
||||
imageonmap.placeinvisiblesplattermap:
|
||||
description: "Allows you to make the item frame on which you placed your splatter map invisible."
|
||||
default: true
|
||||
|
Loading…
Reference in New Issue
Block a user