Skip to content

Commit

Permalink
showfake persistence part 1: code cleanup/prep
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Oct 23, 2019
1 parent 4ec7fde commit ab0d134
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 116 deletions.
@@ -1,6 +1,8 @@
package com.denizenscript.denizen.nms.abstracts;

import com.denizenscript.denizen.nms.NMSHandler;
import com.denizenscript.denizen.utilities.blocks.ChunkCoordinate;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.block.Block;
Expand All @@ -15,23 +17,30 @@
public abstract class BlockLight {

protected static final Map<Location, BlockLight> lightsByLocation = new HashMap<>();
protected static final Map<Chunk, List<BlockLight>> lightsByChunk = new HashMap<>();
protected static final Map<ChunkCoordinate, List<BlockLight>> lightsByChunk = new HashMap<>();
protected static final BlockFace[] adjacentFaces = new BlockFace[] {
BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST, BlockFace.UP, BlockFace.DOWN
};

public final Block block;
public final Chunk chunk;
public final ChunkCoordinate chunkCoord;
public Chunk chunk;
public final int originalLight;
public int currentLight;
public int cachedLight;
public int intendedLevel;
public BukkitTask removeTask;
public BukkitTask updateTask;

public Chunk getChunk() {
chunk = Bukkit.getWorld(chunkCoord.worldName).getChunkAt(chunkCoord.x, chunkCoord.z);
return chunk;
}

protected BlockLight(Location location, long ticks) {
this.block = location.getBlock();
this.chunk = location.getChunk();
this.chunkCoord = new ChunkCoordinate(chunk);
this.originalLight = block.getLightFromBlocks();
this.currentLight = originalLight;
this.cachedLight = originalLight;
Expand Down Expand Up @@ -65,10 +74,10 @@ public static void removeLight(Location location) {
blockLight.removeTask = null;
}
lightsByLocation.remove(location);
List<BlockLight> lights = lightsByChunk.get(blockLight.chunk);
List<BlockLight> lights = lightsByChunk.get(blockLight.chunkCoord);
lights.remove(blockLight);
if (lights.isEmpty()) {
lightsByChunk.remove(blockLight.chunk);
lightsByChunk.remove(blockLight.chunkCoord);
}
}
}
Expand Down
@@ -1,7 +1,5 @@
package com.denizenscript.denizen.objects;

import com.denizenscript.denizen.utilities.DenizenAPI;
import com.denizenscript.denizen.utilities.blocks.FakeBlock;
import com.denizenscript.denizen.utilities.debugging.Debug;
import com.denizenscript.denizencore.objects.*;
import com.denizenscript.denizen.nms.NMSHandler;
Expand All @@ -20,7 +18,6 @@
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;

import java.util.*;

Expand Down Expand Up @@ -694,20 +691,6 @@ public void adjust(Mechanism mechanism) {
final int chunkX = getX();
final int chunkZ = getZ();
getWorld().refreshChunk(chunkX, chunkZ);
new BukkitRunnable() {
@Override
public void run() {
for (Map<Location, FakeBlock> blocks : FakeBlock.getBlocks().values()) {
for (Map.Entry<Location, FakeBlock> locBlock : blocks.entrySet()) {
Location location = locBlock.getKey();
if (Math.floor(location.getX() / 16) == chunkX
&& Math.floor(location.getZ() / 16) == chunkZ) {
locBlock.getValue().updateBlock();
}
}
}
}
}.runTaskLater(DenizenAPI.getCurrentInstance(), 2);
}

// <--[mechanism]
Expand Down
@@ -0,0 +1,51 @@
package com.denizenscript.denizen.utilities.blocks;

import org.bukkit.Chunk;
import org.bukkit.Location;

public class ChunkCoordinate {

public final int x;

public final int z;

public final String worldName;

public ChunkCoordinate(int _x, int _z, String _worldName) {
x = _x;
z = _z;
worldName = _worldName;
}

public ChunkCoordinate(Location location) {
x = location.getBlockX() >> 4;
z = location.getBlockZ() >> 4;
worldName = location.getWorld().getName();
}

public ChunkCoordinate(Chunk chunk) {
x = chunk.getX();
z = chunk.getZ();
worldName = chunk.getWorld().getName();
}

@Override
public int hashCode() {
return x + z + worldName.hashCode();
}

@Override
public boolean equals(Object other) {
if (!(other instanceof ChunkCoordinate)) {
return false;
}
return equals((ChunkCoordinate) other);
}

public boolean equals(ChunkCoordinate other) {
if (other == null) {
return false;
}
return x == other.x && z == other.z && worldName.equals(other.worldName);
}
}
Expand Up @@ -3,6 +3,7 @@
import com.denizenscript.denizen.nms.NMSHandler;
import com.denizenscript.denizen.nms.interfaces.BlockData;
import com.denizenscript.denizen.objects.CuboidTag;
import com.denizenscript.denizen.objects.LocationTag;
import com.denizenscript.denizen.objects.MaterialTag;
import com.denizenscript.denizen.objects.PlayerTag;
import com.denizenscript.denizen.scripts.commands.world.SchematicCommand;
Expand Down Expand Up @@ -113,7 +114,7 @@ public void setBlockSingle(BlockData block, int x, int y, int z, InputParams inp
block.setBlock(destBlock, false);
}
else {
FakeBlock.showFakeBlockTo(input.fakeTo, destBlock.getLocation(), new MaterialTag(block.modern()), input.fakeDuration);
FakeBlock.showFakeBlockTo(input.fakeTo, new LocationTag(destBlock.getLocation()), new MaterialTag(block.modern()), input.fakeDuration);
}
}

Expand Down
Expand Up @@ -5,10 +5,6 @@
import com.denizenscript.denizen.objects.PlayerTag;
import com.denizenscript.denizen.utilities.DenizenAPI;
import com.denizenscript.denizencore.objects.core.DurationTag;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;

Expand All @@ -19,90 +15,110 @@
*/
public class FakeBlock {

private final static Map<UUID, Map<Location, FakeBlock>> blocks = new HashMap<>();
public static class FakeBlockMap {

private final PlayerTag player;
private final Location location;
private MaterialTag material;
private long cancelTime = -1;
private BukkitTask currentTask = null;
Map<LocationTag, FakeBlock> byLocation = new HashMap<>();

private FakeBlock(PlayerTag player, Location location) {
Map<ChunkCoordinate, List<FakeBlock>> byChunk = new HashMap<>();

public FakeBlock getOrAdd(PlayerTag player, LocationTag location) {
FakeBlock block = byLocation.get(location);
if (block != null) {
return block;
}
block = new FakeBlock(player, location);
byLocation.put(location, block);
List<FakeBlock> chunkBlocks = byChunk.get(block.chunkCoord);
if (chunkBlocks == null) {
chunkBlocks = new ArrayList<>();
byChunk.put(block.chunkCoord, chunkBlocks);
}
chunkBlocks.add(block);
return block;
}

public void remove(FakeBlock block) {
if (byLocation.remove(block.location) != null) {
List<FakeBlock> chunkBlocks = byChunk.get(block.chunkCoord);
if (chunkBlocks != null) {
chunkBlocks.remove(block);
}
}
}
}

public final static Map<UUID, FakeBlockMap> blocks = new HashMap<>();

public static FakeBlock getFakeBlockFor(UUID id, LocationTag location) {
FakeBlockMap map = blocks.get(id);
if (map == null) {
return null;
}
return map.byLocation.get(location);
}

public static List<FakeBlock> getFakeBlocksFor(UUID id, ChunkCoordinate chunkCoord) {
FakeBlockMap map = blocks.get(id);
if (map == null) {
return null;
}
return map.byChunk.get(chunkCoord);
}

public final PlayerTag player;
public final LocationTag location;
public final ChunkCoordinate chunkCoord;
public MaterialTag material;
public BukkitTask currentTask = null;

private FakeBlock(PlayerTag player, LocationTag location) {
this.player = player;
this.location = location;
this.chunkCoord = new ChunkCoordinate(location);
}

public static void showFakeBlockTo(List<PlayerTag> players, Location location, MaterialTag material, DurationTag duration) {
public static void showFakeBlockTo(List<PlayerTag> players, LocationTag location, MaterialTag material, DurationTag duration) {
for (PlayerTag player : players) {
if (!player.isOnline() || !player.isValid()) {
continue;
}
UUID uuid = player.getPlayerEntity().getUniqueId();
if (!blocks.containsKey(uuid)) {
blocks.put(uuid, new HashMap<>());
}
Map<Location, FakeBlock> playerBlocks = blocks.get(uuid);
if (!playerBlocks.containsKey(location)) {
playerBlocks.put(location, new FakeBlock(player, location));
FakeBlockMap playerBlocks = blocks.get(uuid);
if (playerBlocks == null) {
playerBlocks = new FakeBlockMap();
blocks.put(uuid, playerBlocks);
}
playerBlocks.get(location).updateBlock(material, duration.getTicks());
FakeBlock block = playerBlocks.getOrAdd(player, location);
block.updateBlock(material, duration);
}
}

public static void stopShowingTo(List<PlayerTag> players, final LocationTag location) {
final List<UUID> uuids = new ArrayList<>();
for (PlayerTag player : players) {
if (!player.isOnline() || !player.isValid()) {
continue;
}
UUID uuid = player.getPlayerEntity().getUniqueId();
uuids.add(uuid);
if (blocks.containsKey(uuid)) {
Map<Location, FakeBlock> playerBlocks = blocks.get(uuid);
if (playerBlocks.containsKey(location)) {
playerBlocks.get(location).cancelBlock();
FakeBlockMap playerBlocks = blocks.get(player.getPlayerEntity().getUniqueId());
if (playerBlocks != null) {
FakeBlock block = playerBlocks.byLocation.get(location);
if (block != null) {
block.cancelBlock();
}
}
}
new BukkitRunnable() {
@Override
public void run() {
for (UUID uuid : blocks.keySet()) {
if (uuids.contains(uuid)) {
continue;
}
Map<Location, FakeBlock> playerBlocks = blocks.get(uuid);
if (playerBlocks.containsKey(location)) {
playerBlocks.get(location).updateBlock();
}
}
}
}.runTaskLater(DenizenAPI.getCurrentInstance(), 2);
}

public static Map<UUID, Map<Location, FakeBlock>> getBlocks() {
return blocks;
}

private void cancelBlock() {
public void cancelBlock() {
if (currentTask != null) {
currentTask.cancel();
currentTask = null;
}
cancelTime = -1;
material = null;
location.getBlock().getState().update();
blocks.get(player.getOfflinePlayer().getUniqueId()).remove(location);
}


public void updateBlock() {
if (material != null) {
updateBlock(material, cancelTime == -1 ? 0 : cancelTime - location.getWorld().getFullTime());
if (player.isOnline()) {
location.getBlock().getState().update();
}
FakeBlockMap mapping = blocks.get(player.getOfflinePlayer().getUniqueId());
mapping.remove(this);
}

private void updateBlock(MaterialTag material, long ticks) {
private void updateBlock(MaterialTag material, DurationTag duration) {
if (currentTask != null) {
currentTask.cancel();
}
Expand All @@ -114,39 +130,16 @@ private void updateBlock(MaterialTag material, long ticks) {
material.getModernData().sendFakeChangeTo(player.getPlayerEntity(), location);
}
else {
player.getPlayerEntity().sendBlockChange(location, material.getMaterial(),
material.getMaterialData().getData());
player.getPlayerEntity().sendBlockChange(location, material.getMaterial(), material.getMaterialData().getData());
}
if (ticks > 0) {
cancelTime = location.getWorld().getFullTime() + ticks;
if (duration != null && duration.getTicks() > 0) {
currentTask = new BukkitRunnable() {
@Override
public void run() {
currentTask = null;
if (player.isValid() && player.isOnline()) {
cancelBlock();
}
cancelBlock();
}
}.runTaskLater(DenizenAPI.getCurrentInstance(), ticks);
}
}

static {
final FakeBlockListeners listeners = new FakeBlockListeners();
}

public static class FakeBlockListeners implements Listener {
public FakeBlockListeners() {
DenizenAPI.getCurrentInstance().getServer().getPluginManager()
.registerEvents(this, DenizenAPI.getCurrentInstance());
}

@EventHandler
public void playerQuit(PlayerQuitEvent event) {
UUID uuid = event.getPlayer().getUniqueId();
if (blocks.containsKey(uuid)) {
blocks.remove(uuid);
}
}.runTaskLater(DenizenAPI.getCurrentInstance(), duration.getTicks());
}
}
}
Expand Down

0 comments on commit ab0d134

Please sign in to comment.