This commit is contained in:
2025-08-03 11:13:47 +02:00
parent bf7e52138d
commit 3f0814639d
5 changed files with 68 additions and 41 deletions

View File

@ -6,6 +6,7 @@ import eu.mhsl.minecraft.pixelpics.render.render.Renderer;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
@ -13,6 +14,7 @@ import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Objects;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
@ -20,18 +22,42 @@ public final class Main extends JavaPlugin {
private static Main instance;
private Renderer screenRenderer;
public final NamespacedKey pictureIdFlag = Objects.requireNonNull(
NamespacedKey.fromString("imageId".toLowerCase(), this),
"Failed to create item-Flag Namespace"
);
@Override
public void onEnable() {
instance = this;
extractJsonResources();
Bukkit.getPluginCommand("pixelPic").setExecutor(new PixelPicsCommand());
Objects.requireNonNull(Bukkit.getPluginCommand("pixelPic"))
.setExecutor(new PixelPicsCommand());
Bukkit.getPluginCommand("test").setExecutor((sender, command, label, args) -> {
// Dialog dialog = Dialog.create(
// builder -> builder.empty()
// .base(
// DialogBase.builder(Component.text("Hello World")).build()
// )
// .type(DialogType.multiAction(
// List.of(
// ActionButton.builder(Component.text("Option 1")).action(DialogAction.staticAction(ClickEvent.callback(audience -> System.out.println("HIIIII")))).build(),
// ActionButton.builder(Component.text("Option 2")).action(DialogAction.customClick(Key.key("test"), null)).build(),
// ActionButton.builder(Component.text("Option 3")).action(DialogAction.commandTemplate("say hi")).build()
// ),
// ActionButton.builder(Component.text("Beenden")).build(),
// 3
// ))
//
// );
// sender.showDialog(dialog);
Material.getMaterial("acacia_button");
Bukkit.broadcast(Component.text(Material.STONE.getBlockTranslationKey().replace("block.minecraft.", "")));
if(!(sender instanceof Player player))
if(!(sender instanceof Player))
throw new IllegalStateException("Dieser Command kann nur von einem Spieler ausgeführt werden!");
File blockDir = new File(getDataFolder(), "models/block");
@ -48,12 +74,8 @@ public final class Main extends JavaPlugin {
});
}
@Override
public void onDisable() {
}
public void extractJsonResources() {
String resourcePath = "models/block/"; // Pfad im JAR
String resourcePath = "models/block/";
File outputDir = new File(getDataFolder(), resourcePath);
if (outputDir.exists()) return;
outputDir.mkdirs();

View File

@ -1,6 +1,6 @@
package eu.mhsl.minecraft.pixelpics.commands;
import eu.mhsl.minecraft.pixelpics.ImageMapRenderer;
import eu.mhsl.minecraft.pixelpics.utils.ImageMapRenderer;
import eu.mhsl.minecraft.pixelpics.Main;
import eu.mhsl.minecraft.pixelpics.render.render.Resolution;
import org.bukkit.Bukkit;
@ -12,11 +12,14 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta;
import org.bukkit.map.MapView;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
public class PixelPicsCommand implements CommandExecutor {
@Override
@ -24,33 +27,38 @@ public class PixelPicsCommand implements CommandExecutor {
if(!(sender instanceof Player player))
throw new IllegalStateException("Dieser Command kann nur von einem Spieler ausgeführt werden!");
Resolution.Pixels pixels = Resolution.Pixels._128P;
Resolution.AspectRatio aspectRatio = Resolution.AspectRatio._1_1;
Resolution resolution = new Resolution(pixels, aspectRatio);
if(args.length > 0)
return false;
BufferedImage image = Main.getInstance().getScreenRenderer().render(player, resolution);
// render image
Resolution resolution = new Resolution(Resolution.Pixels._128P, Resolution.AspectRatio._1_1);
BufferedImage image = Main.getInstance().getScreenRenderer().render(player.getEyeLocation(), resolution);
File file = new File(Main.getInstance().getDataFolder(), "Bild" + ".png");
// save image
UUID imageId = UUID.randomUUID();
File imageFolder = new File(Main.getInstance().getDataFolder(), "images");
try {
Main.getInstance().getDataFolder().mkdir();
ImageIO.write(image, "png", file);
} catch (Exception e) {
return true;
if(!imageFolder.exists() && !imageFolder.mkdirs())
throw new IOException("Failed to create folders for image output!");
ImageIO.write(image, "png", new File(imageFolder, String.format("%s.png", imageId)));
} catch (IOException e) {
throw new RuntimeException("Failed to save image to disk!");
}
// image item
ItemStack map = new ItemStack(Material.FILLED_MAP, 1);
MapMeta meta = (MapMeta) map.getItemMeta();
meta.getPersistentDataContainer().set(Main.getInstance().pictureIdFlag, PersistentDataType.STRING, imageId.toString());
// display image
MapView mapView = Bukkit.createMap(Bukkit.getWorlds().getFirst());
mapView.getRenderers().forEach(mapView::removeRenderer);
mapView.addRenderer(new ImageMapRenderer(image));
meta.setMapView(mapView);
map.setItemMeta(meta);
player.getInventory().addItem(map);
player.updateInventory();
return true;
}
}

View File

@ -5,7 +5,6 @@ import eu.mhsl.minecraft.pixelpics.render.raytrace.Raytracer;
import eu.mhsl.minecraft.pixelpics.render.util.MathUtil;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import java.awt.image.BufferedImage;
@ -30,16 +29,16 @@ public class DefaultScreenRenderer implements Renderer {
}
@Override
public BufferedImage render(Player player, Resolution resolution) {
public BufferedImage render(Location eyeLocation, Resolution resolution) {
int width = resolution.getWidth();
int height = resolution.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] imageData = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
World world = player.getWorld();
Vector linePoint = player.getEyeLocation().toVector();
List<Vector> rayMap = buildRayMap(player, resolution);
World world = eyeLocation.getWorld();
Vector linePoint = eyeLocation.toVector();
List<Vector> rayMap = buildRayMap(eyeLocation, resolution);
for (int i = 0; i < rayMap.size(); i++) {
imageData[i] = raytracer.trace(world, linePoint, rayMap.get(i));
}
@ -47,8 +46,7 @@ public class DefaultScreenRenderer implements Renderer {
return image;
}
private List<Vector> buildRayMap(Player p, Resolution resolution) {
Location eyeLocation = p.getEyeLocation();
private List<Vector> buildRayMap(Location eyeLocation, Resolution resolution) {
Vector lineDirection = eyeLocation.getDirection();
double x = lineDirection.getX();

View File

@ -1,10 +1,9 @@
package eu.mhsl.minecraft.pixelpics.render.render;
import org.bukkit.entity.Player;
import org.bukkit.Location;
import java.awt.image.BufferedImage;
public interface Renderer {
BufferedImage render(Player player, Resolution resolution);
BufferedImage render(Location eyeLocation, Resolution resolution);
}

View File

@ -1,4 +1,4 @@
package eu.mhsl.minecraft.pixelpics;
package eu.mhsl.minecraft.pixelpics.utils;
import org.bukkit.entity.Player;
import org.bukkit.map.MapCanvas;
@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull;
import java.awt.image.BufferedImage;
public class ImageMapRenderer extends MapRenderer {
public static final int IMAGE_SIZE = 128;
public static final int MAP_SIZE = 128;
private final BufferedImage image;
private boolean alreadyRendered = false;
@ -18,18 +18,18 @@ public class ImageMapRenderer extends MapRenderer {
}
public ImageMapRenderer(BufferedImage image, int x, int y) {
this.image = recalculateInput(image, x, y);
this.image = this.recalculateInput(image, x, y);
}
public static BufferedImage recalculateInput(BufferedImage input, int x, int y) {
if (x * IMAGE_SIZE > input.getWidth() || y * IMAGE_SIZE > input.getHeight())
throw new RuntimeException(String.format("Input image mus match a multiple of x and y with %d", IMAGE_SIZE));
private BufferedImage recalculateInput(BufferedImage input, int x, int y) {
if (x * MAP_SIZE > input.getWidth() || y * MAP_SIZE > input.getHeight())
throw new RuntimeException(String.format("Input image mus match a multiple of x and y with %d", MAP_SIZE));
int x1 = (int) (double) (x * IMAGE_SIZE);
int y1 = (int) (double) (y * IMAGE_SIZE);
int x1 = (int) (double) (x * MAP_SIZE);
int y1 = (int) (double) (y * MAP_SIZE);
int x2 = (int) (double) Math.min(input.getWidth(), ((x + 1) * IMAGE_SIZE));
int y2 = (int) (double) Math.min(input.getHeight(), ((y + 1) * IMAGE_SIZE));
int x2 = (int) (double) Math.min(input.getWidth(), ((x + 1) * MAP_SIZE));
int y2 = (int) (double) Math.min(input.getHeight(), ((y + 1) * MAP_SIZE));
if (x2 - x1 <= 0 || y2 - y1 <= 0)
throw new RuntimeException("Invalid Image dimensions!");