forked from SteamWar/SteamWar
Allow removing hulls and resend their chunks
HullHider#removeHull stops hiding a hull: it shows the entities and REntities the hull hid and resends its chunks to everybody who could not view it. A hull is enabled again by adding and initialising it. Hull#resendChunks only resends chunks the player has loaded. HullHider now resends the chunks to non-viewers after initialising a hull itself, so FightHullHider no longer does it.
This commit is contained in:
@@ -32,7 +32,6 @@ import de.steamwar.fightsystem.states.StateDependentListener;
|
|||||||
import de.steamwar.fightsystem.states.StateDependentTask;
|
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||||
import de.steamwar.hullhider.Hull;
|
import de.steamwar.hullhider.Hull;
|
||||||
import de.steamwar.hullhider.HullHider;
|
import de.steamwar.hullhider.HullHider;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -68,14 +67,6 @@ public class FightHullHider {
|
|||||||
public void initialize(FightTeam team) {
|
public void initialize(FightTeam team) {
|
||||||
if (!TechHiderWrapper.ENABLED) return;
|
if (!TechHiderWrapper.ENABLED) return;
|
||||||
hullHider.initialize(team);
|
hullHider.initialize(team);
|
||||||
|
|
||||||
// Chunks encoded while the hull was filled as hidden contain obfuscated blocks that are visible now, but no block update is generated for them
|
|
||||||
Hull hull = hullHider.getHull(team);
|
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
|
||||||
if (!hull.isViewer(player)) {
|
|
||||||
FightSystem.getTechHider().reloadChunks(player, team.getExtendRegion(), Region.EMPTY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fill(FightTeam team, boolean visible) {
|
public void fill(FightTeam team, boolean visible) {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ package de.steamwar.hullhider;
|
|||||||
|
|
||||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import de.steamwar.core.CraftbukkitWrapper;
|
||||||
import de.steamwar.core.ProtocolWrapper;
|
import de.steamwar.core.ProtocolWrapper;
|
||||||
import de.steamwar.entity.REntity;
|
import de.steamwar.entity.REntity;
|
||||||
import it.unimi.dsi.fastutil.shorts.Short2ObjectArrayMap;
|
import it.unimi.dsi.fastutil.shorts.Short2ObjectArrayMap;
|
||||||
@@ -32,6 +33,7 @@ import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
|
|||||||
import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket;
|
import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@@ -180,6 +182,38 @@ public class Hull {
|
|||||||
rentities.remove(entity);
|
rentities.remove(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows all entities hidden by this hull again, used when the hull is removed.
|
||||||
|
*/
|
||||||
|
public void reveal() {
|
||||||
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
|
if (isViewer(player)) continue;
|
||||||
|
|
||||||
|
for (Entity entity : entities) {
|
||||||
|
if (!player.equals(entity)) trackEntity(player, entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entities.clear();
|
||||||
|
|
||||||
|
for (REntity entity : rentities) {
|
||||||
|
entity.hide(false);
|
||||||
|
}
|
||||||
|
rentities.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resends the chunks of this hull the player has loaded, so they are encoded with the current visibility.
|
||||||
|
*/
|
||||||
|
public void resendChunks(Player player) {
|
||||||
|
if (player.getWorld() != world) return;
|
||||||
|
|
||||||
|
region.forEachChunk((chunkX, chunkZ) -> {
|
||||||
|
if (player.isChunkSent(Chunk.getChunkKey(chunkX, chunkZ))) {
|
||||||
|
CraftbukkitWrapper.sendChunk(player, chunkX, chunkZ);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void fill(boolean visible) {
|
public void fill(boolean visible) {
|
||||||
visibility.set(0, visibility.size(), visible);
|
visibility.set(0, visibility.size(), visible);
|
||||||
occluding.set(0, occluding.size(), !visible);
|
occluding.set(0, occluding.size(), !visible);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
package de.steamwar.hullhider;
|
package de.steamwar.hullhider;
|
||||||
|
|
||||||
import de.steamwar.entity.REntity;
|
import de.steamwar.entity.REntity;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
@@ -45,11 +46,30 @@ public class HullHider<K> implements Listener {
|
|||||||
// Read on netty threads, replaced on every change
|
// Read on netty threads, replaced on every change
|
||||||
private volatile Hull[] hulls = new Hull[0];
|
private volatile Hull[] hulls = new Hull[0];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hull hides everything from non-viewers until it is initialised.
|
||||||
|
*/
|
||||||
public void addHull(K key, Hull hull) {
|
public void addHull(K key, Hull hull) {
|
||||||
hullMap.put(key, hull);
|
hullMap.put(key, hull);
|
||||||
hulls = hullMap.values().toArray(new Hull[0]);
|
hulls = hullMap.values().toArray(new Hull[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops hiding the hull: shows the entities it hid and resends its chunks to everybody who could not view it.
|
||||||
|
*/
|
||||||
|
public void removeHull(K key) {
|
||||||
|
Hull hull = hullMap.remove(key);
|
||||||
|
if (hull == null) return;
|
||||||
|
hulls = hullMap.values().toArray(new Hull[0]);
|
||||||
|
|
||||||
|
hull.reveal();
|
||||||
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
|
if (!hull.isViewer(player)) {
|
||||||
|
hull.resendChunks(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Hull getHull(K key) {
|
public Hull getHull(K key) {
|
||||||
return hullMap.get(key);
|
return hullMap.get(key);
|
||||||
}
|
}
|
||||||
@@ -59,7 +79,22 @@ public class HullHider<K> implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(K key) {
|
public void initialize(K key) {
|
||||||
hullMap.get(key).initialize();
|
Hull hull = hullMap.get(key);
|
||||||
|
hull.initialize();
|
||||||
|
|
||||||
|
// Chunks encoded while the hull was filled as hidden contain obfuscated blocks that are visible now, but no block update is generated for them
|
||||||
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
|
if (!hull.isViewer(player)) {
|
||||||
|
hull.resendChunks(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has to be called after the player became a viewer of the hull or stopped being one.
|
||||||
|
*/
|
||||||
|
public void resendChunks(Player player, K key) {
|
||||||
|
hullMap.get(key).resendChunks(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fill(K key, boolean visible) {
|
public void fill(K key, boolean visible) {
|
||||||
|
|||||||
@@ -90,10 +90,22 @@ public final class HullRegion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void forEachChunk(ChunkConsumer executor) {
|
||||||
|
for (int chunkX = minX >> 4; chunkX <= (maxX - 1) >> 4; chunkX++) {
|
||||||
|
for (int chunkZ = minZ >> 4; chunkZ <= (maxZ - 1) >> 4; chunkZ++) {
|
||||||
|
executor.accept(chunkX, chunkZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public interface BlockConsumer {
|
public interface BlockConsumer {
|
||||||
void accept(int x, int y, int z);
|
void accept(int x, int y, int z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ChunkConsumer {
|
||||||
|
void accept(int chunkX, int chunkZ);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return minX + "," + minY + "," + minZ + "->" + maxX + "," + maxY + "," + maxZ;
|
return minX + "," + minY + "," + minZ + "->" + maxX + "," + maxY + "," + maxZ;
|
||||||
|
|||||||
Reference in New Issue
Block a user