Call event when hdmap is requested

This commit is contained in:
LOOHP committed 2025-11-11 22:18:54 +00:00
1 parent c339a51723
commit 5ade6c9b24
3 files changed
+148 -49

No files matched your search

@@ -0,0 +1,91 @@
/*
* This file is part of ImageFrame.
*
* Copyright (C) 2025. LoohpJames <jamesloohp@gmail.com>
* 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 <https://www.gnu.org/licenses/>.
*/
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;
}
}
@@ -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<UUID, Long> acknowledgements;
private final Set<UUID> acknowledged;
@@ -165,58 +167,56 @@ public class CustomClientNetworkManager implements PluginMessageListener, Listen
List<byte[]> 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<byte[]> 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<byte[]> 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;
@@ -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;
}
}