From 5ade6c9b247a956b23d62e7e8da7a9eb96a0a2e2 Mon Sep 17 00:00:00 2001 From: LOOHP Date: Tue, 11 Nov 2025 22:15:12 +0000 Subject: [PATCH] Call event when hdmap is requested --- .../api/events/HDMapPreRespondEvent.java | 91 +++++++++++++++++ .../CustomClientNetworkManager.java | 98 +++++++++---------- .../loohp/imageframe/utils/ImageUtils.java | 8 ++ 3 files changed, 148 insertions(+), 49 deletions(-) create mode 100644 common/src/main/java/com/loohp/imageframe/api/events/HDMapPreRespondEvent.java diff --git a/common/src/main/java/com/loohp/imageframe/api/events/HDMapPreRespondEvent.java b/common/src/main/java/com/loohp/imageframe/api/events/HDMapPreRespondEvent.java new file mode 100644 index 0000000..8ad6f27 --- /dev/null +++ b/common/src/main/java/com/loohp/imageframe/api/events/HDMapPreRespondEvent.java @@ -0,0 +1,91 @@ +/* + * This file is part of ImageFrame. + * + * Copyright (C) 2025. LoohpJames + * Copyright (C) 2025. Contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.loohp.imageframe.api.events; + +import com.loohp.imageframe.objectholders.ImageMap; +import com.loohp.platformscheduler.Scheduler; +import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; +import org.bukkit.map.MapView; + +import java.awt.image.BufferedImage; + +import static com.loohp.imageframe.utils.ImageUtils.copy; + +public class HDMapPreRespondEvent extends PlayerEvent { + + private static final HandlerList HANDLERS = new HandlerList(); + + public static HandlerList getHandlerList() { + return HANDLERS; + } + + private final int mapId; + private final ImageMap imageMap; + private final MapView mapView; + + private boolean requestAccepted; + private BufferedImage image; + + public HDMapPreRespondEvent(Player player, int mapId, ImageMap imageMap, MapView mapView, boolean requestAccepted, BufferedImage image) { + super(player, !Scheduler.isPrimaryThread()); + this.player = player; + this.mapId = mapId; + this.imageMap = imageMap; + this.mapView = mapView; + this.requestAccepted = requestAccepted; + this.image = image; + } + + public int getMapId() { + return mapId; + } + + public ImageMap getImageMap() { + return imageMap; + } + + public MapView getMapView() { + return mapView; + } + + public boolean isRequestAccepted() { + return requestAccepted; + } + + public void setRequestAccepted(boolean requestAccepted) { + this.requestAccepted = requestAccepted; + } + + public BufferedImage getImage() { + return image == null ? null : copy(image); + } + + public void setImage(BufferedImage image) { + this.image = image == null ? null : copy(image); + } + + public HandlerList getHandlers() { + return HANDLERS; + } + +} diff --git a/common/src/main/java/com/loohp/imageframe/objectholders/CustomClientNetworkManager.java b/common/src/main/java/com/loohp/imageframe/objectholders/CustomClientNetworkManager.java index 826b195..bbfe141 100644 --- a/common/src/main/java/com/loohp/imageframe/objectholders/CustomClientNetworkManager.java +++ b/common/src/main/java/com/loohp/imageframe/objectholders/CustomClientNetworkManager.java @@ -24,6 +24,7 @@ import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteArrayDataOutput; import com.google.common.io.ByteStreams; import com.loohp.imageframe.ImageFrame; +import com.loohp.imageframe.api.events.HDMapPreRespondEvent; import com.loohp.imageframe.api.events.ImageMapUpdatedEvent; import com.loohp.imageframe.utils.MapUtils; import com.loohp.platformscheduler.Scheduler; @@ -48,7 +49,6 @@ import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutionException; import java.util.concurrent.ThreadLocalRandom; import java.util.function.BooleanSupplier; import java.util.function.Consumer; @@ -68,6 +68,8 @@ public class CustomClientNetworkManager implements PluginMessageListener, Listen public static final String SERVERBOUND_IMAGEMAP_DETAILS_REQUEST = "imageframe:serverbound_imagemap_details"; public static final String CLIENTBOUND_IMAGEMAP_DETAILS_RESPONSE = "imageframe:clientbound_imagemap_details"; + private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; + private final Map acknowledgements; private final Set acknowledged; @@ -165,58 +167,56 @@ public class CustomClientNetworkManager implements PluginMessageListener, Listen List list = new ArrayList<>(); ByteArrayDataOutput out = ByteStreams.newDataOutput(); out.writeInt(mapId); - if (imageMap == null) { - out.writeBoolean(true); - writeVarInt(out, 0); - out.writeBoolean(false); - } else { - try { - MapView mapView = imageMap.getMapViewFromMapId(mapId); - if (MapUtils.canViewMap(player, mapView).get()) { - out.writeBoolean(true); - BufferedImage image = imageMap.getOriginalImage(mapId); - if (image == null) { - writeVarInt(out, 0); - out.writeBoolean(false); - } else { - try { - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - ImageIO.write(image, "png", byteArrayOutputStream); - byte[] array = byteArrayOutputStream.toByteArray(); - List chunked = chunked(array, 32000); - writeVarInt(out, chunked.get(0).length); - out.write(chunked.get(0)); - if (chunked.size() <= 1) { - out.writeBoolean(false); - } else { - int multipartId = ThreadLocalRandom.current().nextInt(); - out.writeBoolean(true); - out.writeInt(multipartId); - for (int i = 1; i < chunked.size(); i++) { - ByteArrayDataOutput outMulti = ByteStreams.newDataOutput(); - outMulti.writeInt(mapId); - outMulti.writeInt(multipartId); - outMulti.writeInt(i); - writeVarInt(outMulti, chunked.get(i).length); - outMulti.write(chunked.get(i)); - outMulti.writeBoolean(i + 1 >= chunked.size()); - list.add(outMulti.toByteArray()); - } - } - } catch (IOException e) { - e.printStackTrace(); - writeVarInt(out, 0); - out.writeBoolean(false); - } - } - } else { - out.writeBoolean(false); + try { + MapView mapView = imageMap == null ? null : imageMap.getMapViewFromMapId(mapId); + boolean requestAccepted = imageMap == null || MapUtils.canViewMap(player, mapView).get(); + BufferedImage image = imageMap == null ? null : imageMap.getOriginalImage(mapId); + HDMapPreRespondEvent event = new HDMapPreRespondEvent(player, mapId, imageMap, mapView, requestAccepted, image); + Bukkit.getPluginManager().callEvent(event); + requestAccepted = event.isRequestAccepted(); + image = event.getImage(); + out.writeBoolean(requestAccepted); + if (image == null) { + writeVarInt(out, 0); + out.writeBoolean(false); + } else { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byte[] array; + try { + ImageIO.write(image, "png", byteArrayOutputStream); + array = byteArrayOutputStream.toByteArray(); + } catch (IOException e) { + e.printStackTrace(); + array = EMPTY_BYTE_ARRAY; + } + if (array.length == 0) { writeVarInt(out, 0); out.writeBoolean(false); + } else { + List chunked = chunked(array, 32000); + writeVarInt(out, chunked.get(0).length); + out.write(chunked.get(0)); + if (chunked.size() <= 1) { + out.writeBoolean(false); + } else { + int multipartId = ThreadLocalRandom.current().nextInt(); + out.writeBoolean(true); + out.writeInt(multipartId); + for (int i = 1; i < chunked.size(); i++) { + ByteArrayDataOutput outMulti = ByteStreams.newDataOutput(); + outMulti.writeInt(mapId); + outMulti.writeInt(multipartId); + outMulti.writeInt(i); + writeVarInt(outMulti, chunked.get(i).length); + outMulti.write(chunked.get(i)); + outMulti.writeBoolean(i + 1 >= chunked.size()); + list.add(outMulti.toByteArray()); + } + } } - } catch (InterruptedException | ExecutionException e) { - throw new RuntimeException(e); } + } catch (Throwable e) { + throw new RuntimeException(e); } list.add(0, out.toByteArray()); return list; diff --git a/common/src/main/java/com/loohp/imageframe/utils/ImageUtils.java b/common/src/main/java/com/loohp/imageframe/utils/ImageUtils.java index f58b832..4a54bd6 100644 --- a/common/src/main/java/com/loohp/imageframe/utils/ImageUtils.java +++ b/common/src/main/java/com/loohp/imageframe/utils/ImageUtils.java @@ -38,4 +38,12 @@ public class ImageUtils { return b; } + public static BufferedImage copy(BufferedImage source) { + BufferedImage b = new BufferedImage(source.getWidth(), source.getHeight(), BufferedImage.TYPE_INT_ARGB); + Graphics2D g = b.createGraphics(); + g.drawImage(source, 0, 0, null); + g.dispose(); + return b; + } + }