portal preview selection

This commit is contained in:
SuperRonanCraft 2020-11-17 23:10:30 -05:00
parent 628dd55b43
commit 9dc7605d40
8 changed files with 487 additions and 41 deletions

View File

@ -8,15 +8,16 @@ import com.comphenix.protocol.wrappers.BlockPosition;
import com.comphenix.protocol.wrappers.ChunkCoordIntPair;
import com.comphenix.protocol.wrappers.MultiBlockChangeInfo;
import com.comphenix.protocol.wrappers.WrappedBlockData;
import io.papermc.lib.PaperLib;
import me.SuperRonanCraft.BetterRTPAddons.Main;
import me.SuperRonanCraft.BetterRTPAddons.addons.portals.cmds.WrapperPlayServerBlockChange;
import me.SuperRonanCraft.BetterRTPAddons.packets.BlockChangeArray;
import me.SuperRonanCraft.BetterRTPAddons.packets.WrapperPlayServerBlockChange;
import me.SuperRonanCraft.BetterRTPAddons.packets.WrapperPlayServerMultiBlockChange;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
@ -43,26 +44,39 @@ public class PortalsCache {
}
Location old_loc1 = portal.loc_1;
Location old_loc2 = portal.loc_1;
if (loc2) portal.loc_2 = loc;
else portal.loc_1 = loc;
if (loc2)
portal.loc_2 = loc;
else
portal.loc_1 = loc;
if (Bukkit.getPluginManager().isPluginEnabled("ProtocolLib")) {
ProtocolManager pm = ProtocolLibrary.getProtocolManager();
WrapperPlayServerBlockChange block = new WrapperPlayServerBlockChange(pm.createPacket(PacketType.Play.Server.BLOCK_CHANGE));
block.setBlockData(WrappedBlockData.createData(Material.GLOWSTONE));
block.setLocation(new BlockPosition(loc.toVector()));
block.sendPacket(p);
}
if (portal.loc_1 != null && portal.loc_2 != null) {
//if (Math.abs(portal.loc_1.getBlockX() - portal.loc_2.getBlockX()) <= 10)
//if (Math.abs(portal.loc_1.getBlockZ() - portal.loc_2.getBlockZ()) <= 10)
//if (Math.abs(portal.loc_1.getBlockY() - portal.loc_2.getBlockY()) <= 10) {
preview(portal.loc_1, portal.loc_2);
//}
} else {
p.sendMessage((portal.loc_1 == null) + " " + (portal.loc_2 == null));
if (portal.loc_1 != null && portal.loc_2 != null) {
//if (Math.abs(portal.loc_1.getBlockX() - portal.loc_2.getBlockX()) <= 10)
//if (Math.abs(portal.loc_1.getBlockZ() - portal.loc_2.getBlockZ()) <= 10)
//if (Math.abs(portal.loc_1.getBlockY() - portal.loc_2.getBlockY()) <= 10) {
//preview(portal.loc_1, portal.loc_2);
//}
Location max = portal.loc_1;
Location min = portal.loc_2;
for (int x = Math.max(max.getBlockX(), min.getBlockX()); x >= Math.min(min.getBlockX(), max.getBlockX()); x--) {
for (int y = Math.max(max.getBlockY(), min.getBlockY()); y >= Math.min(min.getBlockY(), max.getBlockY()); y--) {
for (int z = Math.max(max.getBlockZ(), min.getBlockZ()); z >= Math.min(min.getBlockZ(), max.getBlockZ()); z--) {
WrapperPlayServerBlockChange packet = new WrapperPlayServerBlockChange(pm.createPacket(PacketType.Play.Server.BLOCK_CHANGE));
packet.setBlockData(WrappedBlockData.createData(Material.REDSTONE_BLOCK));
packet.setLocation(new BlockPosition(new Location(max.getWorld(), x, y, z).toVector()));
packet.sendPacket(p);
//Block block = max.getWorld().getBlockAt(x, y, z);
//block.setType(Material.GLOWSTONE);
}
}
}
} else {
WrapperPlayServerBlockChange packet = new WrapperPlayServerBlockChange(pm.createPacket(PacketType.Play.Server.BLOCK_CHANGE));
packet.setBlockData(WrappedBlockData.createData(Material.GLOWSTONE));
packet.setLocation(new BlockPosition(loc.toVector()));
packet.sendPacket(p);
}
}
}
@ -72,21 +86,24 @@ public class PortalsCache {
PacketContainer packet = pm
.createPacket(PacketType.Play.Server.MULTI_BLOCK_CHANGE);
Chunk chunk = loc1.getChunk();
ChunkCoordIntPair chunkcoords = new ChunkCoordIntPair(chunk.getX(),
chunk.getZ());
MultiBlockChangeInfo[] change = new MultiBlockChangeInfo[256];
BlockChangeArray change = new BlockChangeArray(256);
WrapperPlayServerMultiBlockChange wrapper = new WrapperPlayServerMultiBlockChange(packet);
//wrapper.setChunk(new ChunkCoordIntPair(chunk.getX(), chunk.getZ()));
for (int x = 0; x <= 15; x++) {
for(int z = 0; z <= 15; z++) {
change[(16 * x) + z] = new MultiBlockChangeInfo(new Location(loc1.getWorld(), loc1.getX() + x, 100, loc1.getZ() + z), WrappedBlockData.createData(Material.GOLD_BLOCK));
int index = (16 * x) + z;
BlockChangeArray.BlockChange block = change.getBlockChange(index);
block.setBlockID(WrappedBlockData.createData(Material.GOLD_BLOCK).getType().getId());
Location loc = loc1.clone();
loc.setX(loc.getX() + x);
loc.setZ(loc.getZ() + z);
block.setLocation(loc);
change.setBlockChange(index, block);
}
}
packet.getChunkCoordIntPairs().write(0, chunkcoords);
packet.getMultiBlockChangeInfoArrays().write(0, change);
wrapper.setRecordData(change);
for (Player player : Bukkit.getOnlinePlayers()) {
try {
pm.sendServerPacket(player, packet);

View File

@ -13,11 +13,11 @@ public interface LocationFinder {
BlockIterator iter = new BlockIterator(player, range);
Block lastBlock = null;
while (iter.hasNext()) {
lastBlock = iter.next();
if (lastBlock.getType() == Material.AIR) {
continue;
Block block = iter.next();
if (block.getType() != Material.AIR) {
lastBlock = block;
break;
}
break;
}
return lastBlock;
}

View File

@ -10,6 +10,7 @@ import me.SuperRonanCraft.BetterRTPAddons.addons.portals.AddonPortals;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -22,8 +23,13 @@ public class PortalsCommand_Loc1 implements PortalsCommands, LocationFinder {
@Override
public void execute(CommandSender sendi, String label, String[] args, AddonPortals addonPortals) {
Player p = (Player) sendi;
Location loc = getTargetBlock(p, 10).getLocation();
addonPortals.getPortals().setPortal(p, loc, false);
sendi.sendMessage("Location 1 set to this location!");
Block block = getTargetBlock(p, 10);
if (block != null) {
Location loc = block.getLocation();
addonPortals.getPortals().setPortal(p, loc, false);
sendi.sendMessage("Location 1 set to this location!");
} else {
sendi.sendMessage("Please look at a block!");
}
}
}

View File

@ -13,8 +13,13 @@ public class PortalsCommand_Loc2 implements PortalsCommands, LocationFinder {
@Override
public void execute(CommandSender sendi, String label, String[] args, AddonPortals addonPortals) {
Player p = (Player) sendi;
Location loc = getTargetBlock(p, 10).getLocation();
addonPortals.getPortals().setPortal(p, loc, true);
sendi.sendMessage("Location 2 set to this location!");
Block block = getTargetBlock(p, 10);
if (block != null) {
Location loc = block.getLocation();
addonPortals.getPortals().setPortal(p, loc, true);
sendi.sendMessage("Location 2 set to this location!");
} else {
sendi.sendMessage("Please look at a block!");
}
}
}

View File

@ -1,4 +1,4 @@
package me.SuperRonanCraft.BetterRTPAddons.addons.portals.cmds;
package me.SuperRonanCraft.BetterRTPAddons.packets;
import java.lang.reflect.InvocationTargetException;

View File

@ -0,0 +1,259 @@
package me.SuperRonanCraft.BetterRTPAddons.packets;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.bukkit.Location;
import org.bukkit.World;
/**
* Utility class for creating arrays of block changes.
* <p>
* See also {@link Packet34MultiBlockChange}.
*
* @author Kristian
*/
public class BlockChangeArray {
/**
* Represents a single block change.
* <p>
* Retrieved by {@link BlockChangeArray#getBlockChange(int)}.
*
* @author Kristian
*/
public class BlockChange {
// Index of the block change entry that we may change
private final int index;
private BlockChange(int index) {
this.index = index;
}
/**
* Set the location of the block change.
* <p<
* The coordinates will be correctly converted to relative coordinates, provided that all the blocks
* are from the same chunk (16x16 column of blocks).
* @param loc - location.
* @return This block change, for chaining.
*/
public BlockChange setLocation(Location loc) {
setRelativeX(loc.getBlockX() & 0xF);
setRelativeZ(loc.getBlockZ() & 0xF);
setAbsoluteY(loc.getBlockY());
return this;
}
/**
* Retrieve the location of this block change.
* <p>
* The world and absolute chunk position must be provided.
* @param world - the world the block belongs to.
* @param chunkX - the x position of the origin chunk
* @param chunkZ - the y position of the origin chunk
* @return The location.
*/
public Location getLocation(World world, int chunkX, int chunkZ) {
if (world == null)
throw new IllegalArgumentException("World cannot be NULL.");
return new Location(
world,
(chunkX << 4) + getRelativeX(),
getAbsoluteY(),
(chunkZ << 4) + getRelativeZ()
);
}
/**
* Set the relative x-axis position of current block change in the chunk.
* @param relativeX - relative block change location.
* @return This block change, for chaining.
*/
public BlockChange setRelativeX(int relativeX) {
setValue(relativeX, 28, 0xF0000000);
return this;
}
/**
* Retrieve the relative x-axis position of the current block change.
* @return X-axis position of the block change.
*/
public int getRelativeX() {
return getValue(28, 0xF0000000);
}
/**
* Set the relative z-axis position of current block change in the chunk.
* @param relativeZ - relative block change location.
* @return This block change, for chaining.
*/
public BlockChange setRelativeZ(int relativeX) {
setValue(relativeX, 24, 0xF000000);
return this;
}
/**
* Retrieve the relative z-axis position of the current block change.
* @return Z-axis position of the block change.
*/
public byte getRelativeZ() {
return (byte) getValue(24, 0xF000000);
}
/**
* Set the absolute y-axis position of the current block change.
* @param absoluteY - the absolute y-axis position.
* @return This block change, for chaining.
*/
public BlockChange setAbsoluteY(int absoluteY) {
setValue(absoluteY, 16, 0xFF0000);
return this;
}
/**
* Retrieve the absolute y-axis position of the current block change.
* @return Y-axis position of the block change.
*/
public int getAbsoluteY() {
return getValue(16, 0xFF0000);
}
/**
* Set the block ID of the current block change.
* @param blockID - ID that the changed block will have.
* @return This block change, for chaining.
*/
public BlockChange setBlockID(int blockID) {
setValue(blockID, 4, 0xFFF0);
return this;
}
/**
* Retrieve the block ID of the current block change.
* @return The block ID that the block will change into.
*/
public int getBlockID() {
return getValue(4, 0xFFF0);
}
/**
* Set the block metadata of the current block change.
* @param metadata - metadata that the changed block will have.
* @return This block change, for chaining.
*/
public BlockChange setMetadata(int metadata) {
setValue(metadata, 0, 0xF);
return this;
}
/**
* Retrieve the block metadata of the current block change.
* @return The block metadata that the block will change into.
*/
public int getMetadata() {
return getValue(0, 0xF);
}
/**
* Retrieve the index of the current block change.
* @return Index of the current block change.
*/
public int getIndex() {
return index;
}
/**
* Retrieve the integer representation of this block change.
* @return Integer representation.
*/
private int asInteger() {
return data[index];
}
// Should be inlined
private void setValue(int value, int leftShift, int updateMask) {
data[index] = ((value << leftShift) & updateMask) | (data[index] & ~updateMask);
}
private int getValue(int rightShift, int updateMask) {
return (data[index] & updateMask) >> rightShift;
}
}
/**
* Single of a single block change record in bytes.
*/
private static final int RECORD_SIZE = 4;
/**
* The internally backed array.
*/
private int[] data;
/**
* Construct a new array of block changes.
* @param blockChanges - the number of blocks that have been changed.
*/
public BlockChangeArray(int blockChanges) {
data = new int[blockChanges];
}
/**
* Construct a new block change array from the copy of a given data array.
* @param data - the data array to store internally.
*/
public BlockChangeArray(byte[] input) {
if ((input.length % RECORD_SIZE) != 0)
throw new IllegalArgumentException("The lenght of the input data array should be a multiple of " + RECORD_SIZE + ".");
IntBuffer source = ByteBuffer.wrap(input).asIntBuffer();
IntBuffer destination = IntBuffer.allocate(input.length / RECORD_SIZE);
destination.put(source);
// Get the copied array
data = destination.array();
}
/**
* Retrieve a view of the block change entry at the given index.
* <p>
* Any modification to this view will be stored in the block change array itself.
* @param index - index of the block change to retrieve.
* @return A view of the block change entry.
*/
public BlockChange getBlockChange(int index) {
if (index < 0 || index >= getSize())
throw new IllegalArgumentException("Index is out of bounds.");
return new BlockChange(index);
}
/**
* Set the block change at the specified index to contain the given block.
* @param loc - the location that will be converted.
* @param block - the new content of the block change.
*/
public void setBlockChange(int index, BlockChange change) {
if (change == null)
throw new IllegalArgumentException("Block change cannot be NULL.");
data[index] = change.asInteger();
}
/**
* Retrieve the number of block changes.
* @return The number of block changes.
*/
public int getSize() {
return data.length;
}
/**
* Convert this block change array to a byte array.
* @return The resulting byte array.
*/
public byte[] toByteArray() {
ByteBuffer copy = ByteBuffer.allocate(data.length * RECORD_SIZE);
// Copy in the integer array
copy.asIntBuffer().put(data);
return copy.array();
}
}

View File

@ -1,4 +1,4 @@
package me.SuperRonanCraft.BetterRTPAddons.addons.portals.cmds;
package me.SuperRonanCraft.BetterRTPAddons.packets;
import org.bukkit.Location;
import org.bukkit.World;

View File

@ -0,0 +1,159 @@
package me.SuperRonanCraft.BetterRTPAddons.packets;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.ChunkCoordIntPair;
/**
* Represents a multi-block change.
* <p>
* See also {@link BlockChangeArray} for constructing an array of block changes.
*
* @author Kristian
*/
public class WrapperPlayServerMultiBlockChange extends AbstractPacket {
public static final PacketType TYPE = PacketType.Play.Server.MULTI_BLOCK_CHANGE;
public WrapperPlayServerMultiBlockChange() {
super(new PacketContainer(TYPE), TYPE);
handle.getModifier().writeDefaults();
}
public WrapperPlayServerMultiBlockChange(PacketContainer packet) {
super(packet, TYPE);
}
/**
* Retrieve the chunk x position.
* @return The chunk x.
*/
public int getChunkX() {
return getChunk().getChunkX();
}
/**
* Set the chunk x position.
* @param index - the new position.
*/
public void setChunkX(int index) {
setChunk(new ChunkCoordIntPair(index, getChunkZ()));
}
/**
* Retrieve the chunk Z position.
* @return The chunk z.
*/
public int getChunkZ() {
return getChunk().getChunkZ();
}
/**
* Set the chunk Z position.
* @param index - the new position.
*/
public void setChunkZ(int index) {
setChunk(new ChunkCoordIntPair(getChunkX(), index));
}
/**
* Retrieve the chunk that has been altered.
* @return The current chunk
*/
public ChunkCoordIntPair getChunk() {
return handle.getChunkCoordIntPairs().read(0);
}
/**
* Set chunk that has been altered.
* @param value - new value.
*/
public void setChunk(ChunkCoordIntPair value) {
handle.getChunkCoordIntPairs().write(0, value);
}
/**
* Retrieve the number of blocks affected.
* @return The current Record count
*/
public short getRecordCount() {
return handle.getIntegers().read(0).shortValue();
}
/**
* Set the number of blocks affected.
* @param value - new value.
*/
public void setRecordCount(short value) {
handle.getIntegers().write(0, (int) value);
}
/**
* Retrieve the record data.
* <p>
* Each record is four bytes, containing the following data:
* <table border="1" cellpadding="3">
* <tr>
* <th>Bit mask</th>
* <th>Width</th>
* <th>Meaning</th>
* </tr>
* <tr>
* <td>00 00 00 0F</td>
* <td>4 bits</td>
* <td>Block metadata</td>
* </tr>
* <tr>
* <td>00 00 FF F0</td>
* <td>12 bits</td>
* <td>Block ID</td>
* </tr>
* <tr>
* <td>00 FF 00 00</td>
* <td>8 bits</td>
* <td>Y co-ordinate</td>
* </tr>
* <tr>
* <td>0F 00 00 00</td>
* <td>4 bits</td>
* <td>Z co-ordinate, relative to chunk </td>
* </tr>
* <tr>
* <td>F0 00 00 00 </td>
* <td>4 bits</td>
* <td>X co-ordinate, relative to chunk</td>
* </tr>
* </table>
*
* @return The current Record count
*/
public byte[] getRecordData() {
return handle.getByteArrays().read(0);
}
/**
* Set the record data.
* <p>
* Each record is four bytes. See {@link #getRecordData()} for more information.
* @param value - new value.
*/
public void setRecordData(byte[] value) {
setRecordCount((short) value.length);
handle.getByteArrays().write(0, value);
}
/**
* Set the record data using the given helper array.
* @param array - useful helper array.
*/
public void setRecordData(BlockChangeArray array) {
setRecordData(array.toByteArray());
}
/**
* Retrieve a copy of the record data as a block change array.
* @return The copied block change array.
*/
public BlockChangeArray getRecordDataArray() {
return new BlockChangeArray(getRecordData());
}
}