Mirror von
https://github.com/PaperMC/Paper.git
synchronisiert 2024-11-16 13:00:06 +01:00
Added API for manipulating map items. Thanks SpaceManiac, codename_B, sk89q and dested!
Dieser Commit ist enthalten in:
Ursprung
e6876a97da
Commit
748a6288e4
@ -1,5 +1,10 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
// CraftBukkit start
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.server.MapInitializeEvent;
|
||||
// CraftBukkit end
|
||||
|
||||
public class ItemWorldMap extends ItemWorldMapBase {
|
||||
|
||||
protected ItemWorldMap(int i) {
|
||||
@ -22,6 +27,11 @@ public class ItemWorldMap extends ItemWorldMapBase {
|
||||
worldmap.map = (byte) world.worldProvider.dimension;
|
||||
worldmap.a();
|
||||
world.a(s, (WorldMapBase) worldmap);
|
||||
|
||||
// CraftBukkit start
|
||||
MapInitializeEvent event = new MapInitializeEvent(worldmap.mapView);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
return worldmap;
|
||||
|
@ -11,6 +11,7 @@ import java.util.UUID;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.map.CraftMapView;
|
||||
// CraftBukkit end
|
||||
|
||||
public class WorldMap extends WorldMapBase {
|
||||
@ -26,13 +27,17 @@ public class WorldMap extends WorldMapBase {
|
||||
public List i = new ArrayList();
|
||||
|
||||
// CraftBukkit start
|
||||
public final CraftMapView mapView;
|
||||
private CraftServer server;
|
||||
private UUID uniqueId = null;
|
||||
// CraftBukkit end
|
||||
|
||||
public WorldMap(String s) {
|
||||
super(s);
|
||||
server = (CraftServer) Bukkit.getServer(); // CraftBukkit
|
||||
// CraftBukkit start
|
||||
mapView = new CraftMapView(this);
|
||||
server = (CraftServer) Bukkit.getServer();
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
public void a(NBTTagCompound nbttagcompound) {
|
||||
|
101
src/main/java/net/minecraft/server/WorldMapHumanTracker.java
Normale Datei
101
src/main/java/net/minecraft/server/WorldMapHumanTracker.java
Normale Datei
@ -0,0 +1,101 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
// CraftBukkit start
|
||||
import org.bukkit.map.MapCursor;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.map.RenderData;
|
||||
// CraftBukkit end
|
||||
|
||||
public class WorldMapHumanTracker {
|
||||
|
||||
public final EntityHuman trackee;
|
||||
public int[] b;
|
||||
public int[] c;
|
||||
private int e;
|
||||
private int f;
|
||||
private byte[] g;
|
||||
|
||||
final WorldMap d;
|
||||
|
||||
public WorldMapHumanTracker(WorldMap worldmap, EntityHuman entityhuman) {
|
||||
this.d = worldmap;
|
||||
this.b = new int[128];
|
||||
this.c = new int[128];
|
||||
this.e = 0;
|
||||
this.f = 0;
|
||||
this.trackee = entityhuman;
|
||||
|
||||
for (int i = 0; i < this.b.length; ++i) {
|
||||
this.b[i] = 0;
|
||||
this.c[i] = 127;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] a(ItemStack itemstack) {
|
||||
int i;
|
||||
int j;
|
||||
|
||||
RenderData render = this.d.mapView.render((CraftPlayer) trackee.getBukkitEntity()); // CraftBukkit
|
||||
|
||||
if (--this.f < 0) {
|
||||
this.f = 4;
|
||||
byte[] abyte = new byte[render.cursors.size() * 3 + 1]; // CraftBukkit
|
||||
|
||||
abyte[0] = 1;
|
||||
|
||||
// CraftBukkit start
|
||||
for (i = 0; i < render.cursors.size(); ++i) {
|
||||
MapCursor cursor = render.cursors.get(i);
|
||||
if (!cursor.isVisible()) continue;
|
||||
|
||||
byte value = (byte) (((cursor.getRawType() == 0 || cursor.getDirection() < 8 ? cursor.getDirection() : cursor.getDirection() - 1) & 15) * 16);
|
||||
abyte[i * 3 + 1] = (byte) (value | (cursor.getRawType() != 0 && value < 0 ? 16 - cursor.getRawType() : cursor.getRawType()));
|
||||
abyte[i * 3 + 2] = (byte) cursor.getX();
|
||||
abyte[i * 3 + 3] = (byte) cursor.getY();
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
boolean flag = true;
|
||||
|
||||
if (this.g != null && this.g.length == abyte.length) {
|
||||
for (j = 0; j < abyte.length; ++j) {
|
||||
if (abyte[j] != this.g[j]) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
flag = false;
|
||||
}
|
||||
|
||||
if (!flag) {
|
||||
this.g = abyte;
|
||||
return abyte;
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k < 10; ++k) {
|
||||
i = this.e * 11 % 128;
|
||||
++this.e;
|
||||
if (this.b[i] >= 0) {
|
||||
j = this.c[i] - this.b[i] + 1;
|
||||
int l = this.b[i];
|
||||
byte[] abyte1 = new byte[j + 3];
|
||||
|
||||
abyte1[0] = 0;
|
||||
abyte1[1] = (byte) i;
|
||||
abyte1[2] = (byte) l;
|
||||
|
||||
for (int i1 = 0; i1 < abyte1.length - 3; ++i1) {
|
||||
abyte1[i1 + 3] = render.buffer[(i1 + l) * 128 + i]; // CraftBukkit
|
||||
}
|
||||
|
||||
this.c[i] = -1;
|
||||
this.b[i] = -1;
|
||||
return abyte1;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -49,7 +49,12 @@ import net.minecraft.server.ServerCommand;
|
||||
import net.minecraft.server.ICommandListener;
|
||||
import net.minecraft.server.Packet;
|
||||
import net.minecraft.server.Packet3Chat;
|
||||
import net.minecraft.server.Item;
|
||||
import net.minecraft.server.ItemStack;
|
||||
import net.minecraft.server.WorldMap;
|
||||
import net.minecraft.server.WorldMapCollection;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.map.MapView;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.ServicesManager;
|
||||
@ -62,6 +67,7 @@ import org.bukkit.craftbukkit.inventory.CraftRecipe;
|
||||
import org.bukkit.craftbukkit.inventory.CraftShapedRecipe;
|
||||
import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe;
|
||||
import org.bukkit.craftbukkit.command.ServerCommandListener;
|
||||
import org.bukkit.craftbukkit.map.CraftMapView;
|
||||
import org.bukkit.scheduler.BukkitWorker;
|
||||
import org.bukkit.craftbukkit.scheduler.CraftScheduler;
|
||||
import org.bukkit.craftbukkit.util.DefaultPermissions;
|
||||
@ -776,4 +782,20 @@ public final class CraftServer implements Server {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public CraftMapView getMap(short id) {
|
||||
WorldMapCollection collection = console.worlds.get(0).worldMaps;
|
||||
WorldMap worldmap = (WorldMap) collection.a(WorldMap.class, "map_" + id);
|
||||
if (worldmap == null) {
|
||||
return null;
|
||||
}
|
||||
return worldmap.mapView;
|
||||
}
|
||||
|
||||
public CraftMapView createMap(World world) {
|
||||
ItemStack stack = new ItemStack(Item.MAP, 1, -1);
|
||||
WorldMap worldmap = Item.MAP.a(stack, ((CraftWorld) world).getHandle());
|
||||
return worldmap.mapView;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import net.minecraft.server.EntityHuman;
|
||||
import net.minecraft.server.EntityPlayer;
|
||||
import net.minecraft.server.Packet131;
|
||||
import net.minecraft.server.Packet200Statistic;
|
||||
import net.minecraft.server.Packet3Chat;
|
||||
import net.minecraft.server.Packet51MapChunk;
|
||||
@ -21,8 +22,11 @@ import org.bukkit.Note;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.map.CraftMapView;
|
||||
import org.bukkit.craftbukkit.map.RenderData;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.map.MapView;
|
||||
|
||||
public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
public CraftPlayer(CraftServer server, EntityPlayer entity) {
|
||||
@ -205,6 +209,19 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void sendMap(MapView map) {
|
||||
RenderData data = ((CraftMapView) map).render(this);
|
||||
for (int x = 0; x < 128; ++x) {
|
||||
byte[] bytes = new byte[131];
|
||||
bytes[1] = (byte) x;
|
||||
for (int y = 0; y < 128; ++y) {
|
||||
bytes[y + 3] = data.buffer[y * 128 + x];
|
||||
}
|
||||
Packet131 packet = new Packet131((short) Material.MAP.getId(), map.getId(), bytes);
|
||||
getHandle().netServerHandler.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean teleport(Location location) {
|
||||
// From = Players current Location
|
||||
|
107
src/main/java/org/bukkit/craftbukkit/map/CraftMapCanvas.java
Normale Datei
107
src/main/java/org/bukkit/craftbukkit/map/CraftMapCanvas.java
Normale Datei
@ -0,0 +1,107 @@
|
||||
package org.bukkit.craftbukkit.map;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.util.Arrays;
|
||||
import org.bukkit.map.MapCanvas;
|
||||
import org.bukkit.map.MapCursorCollection;
|
||||
import org.bukkit.map.MapFont;
|
||||
import org.bukkit.map.MapFont.CharacterSprite;
|
||||
import org.bukkit.map.MapPalette;
|
||||
|
||||
public class CraftMapCanvas implements MapCanvas {
|
||||
|
||||
private final byte[] buffer = new byte[128 * 128];
|
||||
private final CraftMapView mapView;
|
||||
private byte[] base;
|
||||
private MapCursorCollection cursors = new MapCursorCollection();
|
||||
|
||||
protected CraftMapCanvas(CraftMapView mapView) {
|
||||
this.mapView = mapView;
|
||||
Arrays.fill(buffer, (byte) -1);
|
||||
}
|
||||
|
||||
public CraftMapView getMapView() {
|
||||
return mapView;
|
||||
}
|
||||
|
||||
public MapCursorCollection getCursors() {
|
||||
return cursors;
|
||||
}
|
||||
|
||||
public void setCursors(MapCursorCollection cursors) {
|
||||
this.cursors = cursors;
|
||||
}
|
||||
|
||||
public void setPixel(int x, int y, byte color) {
|
||||
if (x < 0 || y < 0 || x >= 128 || y >= 128) return;
|
||||
if (buffer[y * 128 + x] != color) {
|
||||
buffer[y * 128 + x] = color;
|
||||
mapView.worldMap.a(x, y, y);
|
||||
}
|
||||
}
|
||||
|
||||
public byte getPixel(int x, int y) {
|
||||
if (x < 0 || y < 0 || x >= 128 || y >= 128) return 0;
|
||||
return buffer[y * 128 + x];
|
||||
}
|
||||
|
||||
public byte getBasePixel(int x, int y) {
|
||||
if (x < 0 || y < 0 || x >= 128 || y >= 128) return 0;
|
||||
return base[y * 128 + x];
|
||||
}
|
||||
|
||||
protected void setBase(byte[] base) {
|
||||
this.base = base;
|
||||
}
|
||||
|
||||
protected byte[] getBuffer() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public void drawImage(int x, int y, Image image) {
|
||||
byte[] bytes = MapPalette.imageToBytes(image);
|
||||
for (int x2 = 0; x2 < image.getWidth(null); ++x2) {
|
||||
for (int y2 = 0; y2 < image.getHeight(null); ++y2) {
|
||||
setPixel(x + x2, y + y2, bytes[y2 * image.getWidth(null) + x2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void drawText(int x, int y, MapFont font, String text) {
|
||||
int xStart = x;
|
||||
byte color = MapPalette.DARK_GRAY;
|
||||
if (!font.isValid(text)) {
|
||||
throw new IllegalArgumentException("text contains invalid characters");
|
||||
}
|
||||
|
||||
for (int i = 0; i < text.length(); ++i) {
|
||||
char ch = text.charAt(i);
|
||||
if (ch == '\n') {
|
||||
x = xStart;
|
||||
y += font.getHeight() + 1;
|
||||
continue;
|
||||
} else if (ch == '\u00A7') {
|
||||
int j = text.indexOf(';', i);
|
||||
if (j >= 0) {
|
||||
try {
|
||||
color = Byte.parseByte(text.substring(i + 1, j));
|
||||
i = j;
|
||||
continue;
|
||||
}
|
||||
catch (NumberFormatException ex) {}
|
||||
}
|
||||
}
|
||||
|
||||
CharacterSprite sprite = font.getChar(text.charAt(i));
|
||||
for (int r = 0; r < font.getHeight(); ++r) {
|
||||
for (int c = 0; c < sprite.getWidth(); ++c) {
|
||||
if (sprite.get(r, c)) {
|
||||
setPixel(x + c, y + r, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
x += sprite.getWidth() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
43
src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java
Normale Datei
43
src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java
Normale Datei
@ -0,0 +1,43 @@
|
||||
package org.bukkit.craftbukkit.map;
|
||||
|
||||
import net.minecraft.server.WorldMap;
|
||||
import net.minecraft.server.WorldMapOrienter;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.map.MapCanvas;
|
||||
import org.bukkit.map.MapRenderer;
|
||||
import org.bukkit.map.MapView;
|
||||
import org.bukkit.map.MapCursorCollection;
|
||||
|
||||
public class CraftMapRenderer extends MapRenderer {
|
||||
|
||||
private final CraftMapView mapView;
|
||||
private final WorldMap worldMap;
|
||||
|
||||
public CraftMapRenderer(CraftMapView mapView, WorldMap worldMap) {
|
||||
super(false);
|
||||
this.mapView = mapView;
|
||||
this.worldMap = worldMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MapView map, MapCanvas canvas, Player player) {
|
||||
// Map
|
||||
for (int x = 0; x < 128; ++x) {
|
||||
for (int y = 0; y < 128; ++y) {
|
||||
canvas.setPixel(x, y, worldMap.f[y * 128 + x]);
|
||||
}
|
||||
}
|
||||
|
||||
// Cursors
|
||||
MapCursorCollection cursors = canvas.getCursors();
|
||||
while (cursors.size() > 0) {
|
||||
cursors.removeCursor(cursors.getCursor(0));
|
||||
}
|
||||
for (int i = 0; i < worldMap.i.size(); ++i) {
|
||||
WorldMapOrienter orienter = (WorldMapOrienter) worldMap.i.get(i);
|
||||
cursors.addCursor(orienter.b, orienter.c, (byte)(orienter.d & 15), (byte)(orienter.a));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
161
src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java
Normale Datei
161
src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java
Normale Datei
@ -0,0 +1,161 @@
|
||||
package org.bukkit.craftbukkit.map;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.server.WorldMap;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.map.MapRenderer;
|
||||
import org.bukkit.map.MapView;
|
||||
|
||||
public final class CraftMapView implements MapView {
|
||||
|
||||
private final Map<CraftPlayer, RenderData> renderCache = new HashMap<CraftPlayer, RenderData>();
|
||||
private final List<MapRenderer> renderers = new ArrayList<MapRenderer>();
|
||||
private final Map<MapRenderer, Map<CraftPlayer, CraftMapCanvas>> canvases = new HashMap<MapRenderer, Map<CraftPlayer, CraftMapCanvas>>();
|
||||
protected final WorldMap worldMap;
|
||||
|
||||
public CraftMapView(WorldMap worldMap) {
|
||||
this.worldMap = worldMap;
|
||||
addRenderer(new CraftMapRenderer(this, worldMap));
|
||||
}
|
||||
|
||||
public short getId() {
|
||||
String text = worldMap.a;
|
||||
if (text.startsWith("map_")) {
|
||||
try {
|
||||
return Short.parseShort(text.substring("map_".length()));
|
||||
}
|
||||
catch (NumberFormatException ex) {
|
||||
throw new IllegalStateException("Map has non-numeric ID");
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Map has invalid ID");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVirtual() {
|
||||
return renderers.size() > 0 && !(renderers.get(0) instanceof CraftMapRenderer);
|
||||
}
|
||||
|
||||
public Scale getScale() {
|
||||
return Scale.valueOf(worldMap.e);
|
||||
}
|
||||
|
||||
public void setScale(Scale scale) {
|
||||
worldMap.e = scale.getValue();
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
byte dimension = worldMap.map;
|
||||
for (World world : Bukkit.getServer().getWorlds()) {
|
||||
if (((CraftWorld) world).getHandle().dimension == dimension) {
|
||||
return world;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setWorld(World world) {
|
||||
worldMap.map = (byte) ((CraftWorld) world).getHandle().dimension;
|
||||
}
|
||||
|
||||
public int getCenterX() {
|
||||
return worldMap.b;
|
||||
}
|
||||
|
||||
public int getCenterZ() {
|
||||
return worldMap.c;
|
||||
}
|
||||
|
||||
public void setCenterX(int x) {
|
||||
worldMap.b = x;
|
||||
}
|
||||
|
||||
public void setCenterZ(int z) {
|
||||
worldMap.c = z;
|
||||
}
|
||||
|
||||
public List<MapRenderer> getRenderers() {
|
||||
return new ArrayList<MapRenderer>(renderers);
|
||||
}
|
||||
|
||||
public void addRenderer(MapRenderer renderer) {
|
||||
if (!renderers.contains(renderer)) {
|
||||
renderers.add(renderer);
|
||||
canvases.put(renderer, new HashMap<CraftPlayer, CraftMapCanvas>());
|
||||
renderer.initialize(this);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean removeRenderer(MapRenderer renderer) {
|
||||
if (renderers.contains(renderer)) {
|
||||
renderers.remove(renderer);
|
||||
for (Map.Entry<CraftPlayer, CraftMapCanvas> entry : canvases.get(renderer).entrySet()) {
|
||||
for (int x = 0; x < 128; ++x) {
|
||||
for (int y = 0; y < 128; ++y) {
|
||||
entry.getValue().setPixel(x, y, (byte) -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
canvases.remove(renderer);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isContextual() {
|
||||
for (MapRenderer renderer : renderers) {
|
||||
if (renderer.isContextual()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public RenderData render(CraftPlayer player) {
|
||||
boolean context = isContextual();
|
||||
RenderData render = renderCache.get(context ? player : null);
|
||||
|
||||
if (render == null) {
|
||||
render = new RenderData();
|
||||
renderCache.put(context ? player : null, render);
|
||||
}
|
||||
|
||||
if (context && renderCache.containsKey(null)) {
|
||||
renderCache.remove(null);
|
||||
}
|
||||
|
||||
Arrays.fill(render.buffer, (byte) 0);
|
||||
render.cursors.clear();
|
||||
|
||||
for (MapRenderer renderer : renderers) {
|
||||
CraftMapCanvas canvas = canvases.get(renderer).get(renderer.isContextual() ? player : null);
|
||||
if (canvas == null) {
|
||||
canvas = new CraftMapCanvas(this);
|
||||
canvases.get(renderer).put(renderer.isContextual() ? player : null, canvas);
|
||||
}
|
||||
|
||||
canvas.setBase(render.buffer);
|
||||
renderer.render(this, canvas, player);
|
||||
|
||||
byte[] buf = canvas.getBuffer();
|
||||
for (int i = 0; i < buf.length; ++i) {
|
||||
if (buf[i] >= 0) render.buffer[i] = buf[i];
|
||||
}
|
||||
|
||||
for (int i = 0; i < canvas.getCursors().size(); ++i) {
|
||||
render.cursors.add(canvas.getCursors().getCursor(i));
|
||||
}
|
||||
}
|
||||
|
||||
return render;
|
||||
}
|
||||
|
||||
}
|
16
src/main/java/org/bukkit/craftbukkit/map/RenderData.java
Normale Datei
16
src/main/java/org/bukkit/craftbukkit/map/RenderData.java
Normale Datei
@ -0,0 +1,16 @@
|
||||
package org.bukkit.craftbukkit.map;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import org.bukkit.map.MapCursor;
|
||||
|
||||
public class RenderData {
|
||||
|
||||
public final byte[] buffer;
|
||||
public final ArrayList<MapCursor> cursors;
|
||||
|
||||
public RenderData() {
|
||||
this.buffer = new byte[128 * 128];
|
||||
this.cursors = new ArrayList<MapCursor>();
|
||||
}
|
||||
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren