Fast WorldReset, reduce spawned tasks, fix schemcoloring
Dieser Commit ist enthalten in:
Ursprung
d71cb738c7
Commit
b73052c5e0
@ -43,6 +43,7 @@ import org.bukkit.scheduler.BukkitTask;
|
|||||||
import java.io.EOFException;
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -54,15 +55,38 @@ class PacketProcessor {
|
|||||||
|
|
||||||
private final PacketSource source;
|
private final PacketSource source;
|
||||||
private final BukkitTask task;
|
private final BukkitTask task;
|
||||||
|
private final LinkedList<Runnable> syncList = new LinkedList<>();
|
||||||
|
|
||||||
|
|
||||||
public PacketProcessor(PacketSource source){
|
public PacketProcessor(PacketSource source){
|
||||||
this.source = source;
|
this.source = source;
|
||||||
if(source.async())
|
if(source.async()) {
|
||||||
task = Bukkit.getScheduler().runTaskAsynchronously(SpectateSystem.get(), this::process);
|
Bukkit.getScheduler().runTaskAsynchronously(SpectateSystem.get(), this::process);
|
||||||
else
|
task = Bukkit.getScheduler().runTaskTimer(SpectateSystem.get(), this::runSync, 1, 1);
|
||||||
|
}else
|
||||||
task = Bukkit.getScheduler().runTaskTimer(SpectateSystem.get(), this::process, 1, 1);
|
task = Bukkit.getScheduler().runTaskTimer(SpectateSystem.get(), this::process, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void runSync() {
|
||||||
|
synchronized (syncList) {
|
||||||
|
for(Runnable runnable : syncList) {
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
syncList.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void execSync(Runnable runnable){
|
||||||
|
if (!source.async()) {
|
||||||
|
runnable.run();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (syncList) {
|
||||||
|
syncList.add(runnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void playerJoins() throws IOException {
|
private void playerJoins() throws IOException {
|
||||||
int entityId = source.rInt();
|
int entityId = source.rInt();
|
||||||
int userId = source.rInt();
|
int userId = source.rInt();
|
||||||
@ -70,7 +94,7 @@ class PacketProcessor {
|
|||||||
if(user == null)
|
if(user == null)
|
||||||
throw new IOException("Unknown user " + userId);
|
throw new IOException("Unknown user " + userId);
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> new RPlayer(user.getUUID(), user.getUserName(), entityId));
|
execSync(() -> new RPlayer(user.getUUID(), user.getUserName(), entityId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void entityMoves() throws IOException {
|
private void entityMoves() throws IOException {
|
||||||
@ -82,33 +106,33 @@ class PacketProcessor {
|
|||||||
float yaw = source.rFloat();
|
float yaw = source.rFloat();
|
||||||
byte headYaw = source.rByte();
|
byte headYaw = source.rByte();
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> REntity.getEntity(entityId).move(locX, locY, locZ, yaw, pitch, headYaw));
|
execSync(() -> REntity.getEntity(entityId).move(locX, locY, locZ, yaw, pitch, headYaw));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void entityDespawns() throws IOException {
|
private void entityDespawns() throws IOException {
|
||||||
int entityId = source.rInt();
|
int entityId = source.rInt();
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> REntity.getEntity(entityId).remove());
|
execSync(() -> REntity.getEntity(entityId).remove());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void entitySneak() throws IOException {
|
private void entitySneak() throws IOException {
|
||||||
int entityId = source.rInt();
|
int entityId = source.rInt();
|
||||||
boolean sneaking = source.rBoolean();
|
boolean sneaking = source.rBoolean();
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> REntity.getEntity(entityId).sneak(sneaking));
|
execSync(() -> REntity.getEntity(entityId).sneak(sneaking));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void entityAnimation() throws IOException {
|
private void entityAnimation() throws IOException {
|
||||||
int entityId = source.rInt();
|
int entityId = source.rInt();
|
||||||
byte animation = source.rByte();
|
byte animation = source.rByte();
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> REntity.getEntity(entityId).animation(animation));
|
execSync(() -> REntity.getEntity(entityId).animation(animation));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tntSpawn() throws IOException {
|
private void tntSpawn() throws IOException {
|
||||||
int entityId = source.rInt();
|
int entityId = source.rInt();
|
||||||
|
|
||||||
new RTnT(entityId);
|
execSync(() -> new RTnT(entityId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void entityVelocity() throws IOException {
|
private void entityVelocity() throws IOException {
|
||||||
@ -118,7 +142,7 @@ class PacketProcessor {
|
|||||||
double dY = source.rDouble();
|
double dY = source.rDouble();
|
||||||
double dZ = source.rDouble();
|
double dZ = source.rDouble();
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> {
|
execSync(() -> {
|
||||||
REntity entity = REntity.getEntity(entityId);
|
REntity entity = REntity.getEntity(entityId);
|
||||||
if(entity != null)
|
if(entity != null)
|
||||||
entity.setMotion(dX, dY, dZ);
|
entity.setMotion(dX, dY, dZ);
|
||||||
@ -131,19 +155,19 @@ class PacketProcessor {
|
|||||||
boolean enchanted = source.rBoolean();
|
boolean enchanted = source.rBoolean();
|
||||||
String slot = source.rString();
|
String slot = source.rString();
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> ((RPlayer)REntity.getEntity(entityId)).setItem(item, enchanted, slot));
|
execSync(() -> ((RPlayer)REntity.getEntity(entityId)).setItem(item, enchanted, slot));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void arrowSpawn() throws IOException {
|
private void arrowSpawn() throws IOException {
|
||||||
int entityId = source.rInt();
|
int entityId = source.rInt();
|
||||||
|
|
||||||
new RArrow(entityId);
|
execSync(() -> new RArrow(entityId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fireballSpawn() throws IOException {
|
private void fireballSpawn() throws IOException {
|
||||||
int entityId = source.rInt();
|
int entityId = source.rInt();
|
||||||
|
|
||||||
new RFireball(entityId);
|
execSync(() -> new RFireball(entityId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void send(ChatMessageType type) throws IOException {
|
private void send(ChatMessageType type) throws IOException {
|
||||||
@ -171,6 +195,23 @@ class PacketProcessor {
|
|||||||
setBlock(x, y, z, blockState);
|
setBlock(x, y, z, blockState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setBlock(int x, int y, int z, int blockState){
|
||||||
|
if(Config.ArenaMinX > x || Config.ArenaMaxX < x || Config.ArenaMinZ > z || Config.ArenaMaxZ < z)
|
||||||
|
return; //Outside of the arena
|
||||||
|
|
||||||
|
if (Config.TechhiderActive && Config.HiddenBlocks.contains(blockState)) {
|
||||||
|
blockState = Config.ObfuscateWith;
|
||||||
|
}
|
||||||
|
IBlockData blockData = Objects.requireNonNull(Block.REGISTRY_ID.fromId(blockState));
|
||||||
|
execSync(() -> {
|
||||||
|
WorldServer cworld = ((CraftWorld)world).getHandle();
|
||||||
|
BlockPosition pos = new BlockPosition(x, y, z);
|
||||||
|
cworld.removeTileEntity(pos);
|
||||||
|
cworld.setTypeAndData(pos, blockData, 1042);
|
||||||
|
cworld.getChunkProvider().flagDirty(pos);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void particle() throws IOException {
|
private void particle() throws IOException {
|
||||||
double x = source.rDouble();
|
double x = source.rDouble();
|
||||||
double y = source.rDouble();
|
double y = source.rDouble();
|
||||||
@ -178,7 +219,7 @@ class PacketProcessor {
|
|||||||
|
|
||||||
String particleName = source.rString();
|
String particleName = source.rString();
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> world.spawnParticle(Particle.valueOf(particleName), x, y, z, 1));
|
execSync(() -> world.spawnParticle(Particle.valueOf(particleName), x, y, z, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sound() throws IOException {
|
private void sound() throws IOException {
|
||||||
@ -195,7 +236,7 @@ class PacketProcessor {
|
|||||||
Sound sound = Sound.valueOf(soundName);
|
Sound sound = Sound.valueOf(soundName);
|
||||||
SoundCategory sCategory = SoundCategory.valueOf(soundCategory);
|
SoundCategory sCategory = SoundCategory.valueOf(soundCategory);
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> world.playSound(new Location(world, x, y, z), sound, sCategory, volume, pitch));
|
execSync(() -> world.playSound(new Location(world, x, y, z), sound, sCategory, volume, pitch));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void soundAtPlayer() throws IOException {
|
private void soundAtPlayer() throws IOException {
|
||||||
@ -206,21 +247,21 @@ class PacketProcessor {
|
|||||||
|
|
||||||
Sound sound = Sound.valueOf(soundName);
|
Sound sound = Sound.valueOf(soundName);
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> {
|
execSync(() -> {
|
||||||
for(Player player : Bukkit.getOnlinePlayers()){
|
for(Player player : Bukkit.getOnlinePlayers()){
|
||||||
player.playSound(player.getLocation(), sound, volume, pitch);
|
player.playSound(player.getLocation(), sound, volume, pitch);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pasteSchem(int cornerX, int cornerY, int cornerZ, boolean rotate, String prefix) throws IOException {
|
private void pasteSchem(int pasteX, int cornerY, int pasteZ, int cornerX, int cornerZ, boolean rotate, String prefix) throws IOException {
|
||||||
int schemId = source.rInt();
|
int schemId = source.rInt();
|
||||||
|
|
||||||
Schematic schem = Schematic.getSchemFromDB(schemId);
|
Schematic schem = Schematic.getSchemFromDB(schemId);
|
||||||
DyeColor c = ColorConverter.chat2dye(ChatColor.getByChar(ChatColor.getLastColors(prefix).replace("§", "")));
|
DyeColor c = ColorConverter.chat2dye(ChatColor.getByChar(ChatColor.getLastColors(prefix).replace("§", "")));
|
||||||
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> {
|
execSync(() -> {
|
||||||
try {
|
try {
|
||||||
EditSession e = Paster.pasteSchematic(schem, cornerX, cornerY, cornerZ, rotate);
|
EditSession e = Paster.pasteSchematic(schem, pasteX, cornerY, pasteZ, rotate);
|
||||||
Paster.replaceTeamColor(e, c, cornerX, cornerY, cornerZ);
|
Paster.replaceTeamColor(e, c, cornerX, cornerY, cornerZ);
|
||||||
} catch (NoClipboardException | IOException e) {
|
} catch (NoClipboardException | IOException e) {
|
||||||
throw new SecurityException("Could not load Clipboard", e);
|
throw new SecurityException("Could not load Clipboard", e);
|
||||||
@ -232,7 +273,7 @@ class PacketProcessor {
|
|||||||
int blueId = source.rInt();
|
int blueId = source.rInt();
|
||||||
int redId = source.rInt();
|
int redId = source.rInt();
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> BlockTextCreator.pasteTeamNames(blueId, redId));
|
execSync(() -> BlockTextCreator.pasteTeamNames(blueId, redId));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void scoreboardTitle() throws IOException {
|
private void scoreboardTitle() throws IOException {
|
||||||
@ -248,23 +289,6 @@ class PacketProcessor {
|
|||||||
SpectateSystem.getScoreboard().addValue(key, value);
|
SpectateSystem.getScoreboard().addValue(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setBlock(int x, int y, int z, int blockState){
|
|
||||||
if(Config.ArenaMinX > x || Config.ArenaMaxX < x || Config.ArenaMinZ > z || Config.ArenaMaxZ < z)
|
|
||||||
return; //Outside of the arena
|
|
||||||
|
|
||||||
if (Config.TechhiderActive && Config.HiddenBlocks.contains(blockState)) {
|
|
||||||
blockState = Config.ObfuscateWith;
|
|
||||||
}
|
|
||||||
IBlockData blockData = Objects.requireNonNull(Block.REGISTRY_ID.fromId(blockState));
|
|
||||||
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> {
|
|
||||||
WorldServer cworld = ((CraftWorld)world).getHandle();
|
|
||||||
BlockPosition pos = new BlockPosition(x, y, z);
|
|
||||||
cworld.removeTileEntity(pos);
|
|
||||||
cworld.setTypeAndData(pos, blockData, 1042);
|
|
||||||
cworld.getChunkProvider().flagDirty(pos);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void endSpectating(){
|
private void endSpectating(){
|
||||||
WorldLoader.reloadWorld();
|
WorldLoader.reloadWorld();
|
||||||
SpectateSystem.getScoreboard().setTitle("§eKein Kampf");
|
SpectateSystem.getScoreboard().setTitle("§eKein Kampf");
|
||||||
@ -339,10 +363,10 @@ class PacketProcessor {
|
|||||||
send(ChatMessageType.SYSTEM);
|
send(ChatMessageType.SYSTEM);
|
||||||
break;
|
break;
|
||||||
case (byte) 0xB0:
|
case (byte) 0xB0:
|
||||||
pasteSchem(Config.TeamBluePasteX, Config.TeamBlueCornerY, Config.TeamBluePasteZ, Config.TeamBlueRotate, Config.TeamBluePrefix);
|
pasteSchem(Config.TeamBluePasteX, Config.TeamBlueCornerY, Config.TeamBluePasteZ, Config.TeamBlueCornerX, Config.TeamBlueCornerZ, Config.TeamBlueRotate, Config.TeamBluePrefix);
|
||||||
break;
|
break;
|
||||||
case (byte) 0xB1:
|
case (byte) 0xB1:
|
||||||
pasteSchem(Config.TeamRedPasteX, Config.TeamRedCornerY, Config.TeamRedPasteZ, Config.TeamRedRotate, Config.TeamRedPrefix);
|
pasteSchem(Config.TeamRedPasteX, Config.TeamRedCornerY, Config.TeamRedPasteZ, Config.TeamRedCornerX, Config.TeamRedCornerZ, Config.TeamRedRotate, Config.TeamRedPrefix);
|
||||||
break;
|
break;
|
||||||
case (byte) 0xB2:
|
case (byte) 0xB2:
|
||||||
teams();
|
teams();
|
||||||
@ -376,8 +400,7 @@ class PacketProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(source.isClosed()){
|
if(source.isClosed()){
|
||||||
endSpectating();
|
execSync(() -> endSpectating());
|
||||||
if(!source.async())
|
|
||||||
task.cancel();
|
task.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,18 +19,19 @@
|
|||||||
|
|
||||||
package de.steamwar.spectatesystem.util;
|
package de.steamwar.spectatesystem.util;
|
||||||
|
|
||||||
|
import de.steamwar.core.events.ChunkListener;
|
||||||
import de.steamwar.spectatesystem.Config;
|
import de.steamwar.spectatesystem.Config;
|
||||||
import de.steamwar.spectatesystem.SpectateSystem;
|
import de.steamwar.spectatesystem.SpectateSystem;
|
||||||
import de.steamwar.spectatesystem.elements.REntity;
|
import de.steamwar.spectatesystem.elements.REntity;
|
||||||
import net.minecraft.server.v1_15_R1.BlockPosition;
|
import net.minecraft.server.v1_15_R1.BlockPosition;
|
||||||
import net.minecraft.server.v1_15_R1.Blocks;
|
import net.minecraft.server.v1_15_R1.Blocks;
|
||||||
import net.minecraft.server.v1_15_R1.IBlockData;
|
import net.minecraft.server.v1_15_R1.Chunk;
|
||||||
import net.minecraft.server.v1_15_R1.WorldServer;
|
import net.minecraft.server.v1_15_R1.WorldServer;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.WorldCreator;
|
import org.bukkit.WorldCreator;
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.CraftChunk;
|
|
||||||
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public class WorldLoader {
|
public class WorldLoader {
|
||||||
private WorldLoader(){}
|
private WorldLoader(){}
|
||||||
@ -49,24 +50,20 @@ public class WorldLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void reloadWorld() {
|
public static void reloadWorld() {
|
||||||
Bukkit.getScheduler().runTask(SpectateSystem.get(), () -> {
|
|
||||||
REntity.removeAll();
|
REntity.removeAll();
|
||||||
World backupWorld = new WorldCreator(world.getName() + "-backup").createWorld();
|
World backupWorld = new WorldCreator(world.getName() + "-backup").createWorld();
|
||||||
|
|
||||||
int delay = 1;
|
fillTeamArea(Config.TeamBlueCornerX, Config.TeamBlueCornerY, Config.TeamBlueCornerZ, Config.SchemsizeX, Config.SchemsizeY, Config.SchemsizeZ);
|
||||||
Bukkit.getScheduler().runTaskLater(SpectateSystem.get(), () -> fillTeamArea(Config.TeamBlueCornerX, Config.TeamBlueCornerY, Config.TeamBlueCornerZ, Config.SchemsizeX, Config.SchemsizeY, Config.SchemsizeZ), delay++);
|
fillTeamArea(Config.TeamRedCornerX, Config.TeamRedCornerY, Config.TeamRedCornerZ, Config.SchemsizeX, Config.SchemsizeY, Config.SchemsizeZ);
|
||||||
Bukkit.getScheduler().runTaskLater(SpectateSystem.get(), () -> fillTeamArea(Config.TeamRedCornerX, Config.TeamRedCornerY, Config.TeamRedCornerZ, Config.SchemsizeX, Config.SchemsizeY, Config.SchemsizeZ), delay++);
|
|
||||||
|
|
||||||
for(int cX = (int) Math.floor(Config.ArenaMinX / 16.0); cX <= (int) Math.floor(Config.ArenaMaxX / 16.0); cX++){
|
Bukkit.getScheduler().runTaskLater(SpectateSystem.get(), () -> {
|
||||||
for(int cZ = (int) Math.floor(Config.ArenaMinZ / 16.0); cZ <= (int) Math.floor(Config.ArenaMaxZ / 16.0); cZ++){
|
for(int cZ = (int) Math.floor(Config.ArenaMinZ / 16.0); cZ <= (int) Math.floor(Config.ArenaMaxZ / 16.0); cZ++){
|
||||||
int finalCX = cX;
|
for(int cX = (int) Math.floor(Config.ArenaMinX / 16.0); cX <= (int) Math.floor(Config.ArenaMaxX / 16.0); cX++){
|
||||||
int finalCZ = cZ;
|
reloadChunk(backupWorld, cX, cZ);
|
||||||
Bukkit.getScheduler().runTaskLater(SpectateSystem.get(), () -> reloadChunk(backupWorld, finalCX, finalCZ), delay++);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Bukkit.unloadWorld(world.getName() + "-backup", false);
|
||||||
Bukkit.getScheduler().runTaskLater(SpectateSystem.get(), () -> Bukkit.unloadWorld(world.getName() + "-backup", false), delay);
|
}, 10);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void fillTeamArea(int teamX, int teamY, int teamZ, int sizeX, int sizeY, int sizeZ){
|
public static void fillTeamArea(int teamX, int teamY, int teamZ, int sizeX, int sizeY, int sizeZ){
|
||||||
@ -83,24 +80,17 @@ public class WorldLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reloadChunk(World backupWorld, int cX, int cZ){
|
public static void reloadChunk(World backup, int x, int z){
|
||||||
WorldServer cworld = ((CraftWorld)world).getHandle();
|
Chunk chunk = ((CraftWorld) world).getHandle().getChunkAt(x, z);
|
||||||
WorldServer backup = ((CraftWorld) backupWorld).getHandle();
|
Chunk backupChunk = ((CraftWorld) backup).getHandle().getChunkAt(x, z);
|
||||||
|
|
||||||
net.minecraft.server.v1_15_R1.Chunk cchunk = ((CraftChunk) world.getChunkAt(cX, cZ)).getHandle();
|
System.arraycopy(backupChunk.getSections(), 0, chunk.getSections(), 0, chunk.getSections().length);
|
||||||
for(int y = 255; y >= 0; y--){ // y top down to reduce lightning calculations
|
chunk.tileEntities.clear();
|
||||||
for(int x = cX * 16; x < (cX + 1) * 16; x++){
|
chunk.tileEntities.putAll(backupChunk.tileEntities);
|
||||||
for(int z = cZ * 16; z < (cZ + 1) * 16; z++){
|
chunk.heightMap.clear();
|
||||||
BlockPosition blockPos = new BlockPosition(x, y, z);
|
chunk.heightMap.putAll(backupChunk.heightMap);
|
||||||
IBlockData backupBlock = backup.getType(blockPos);
|
for(Player p : Bukkit.getOnlinePlayers()){
|
||||||
if(backupBlock == cworld.getType(blockPos))
|
ChunkListener.sendChunk(p, x, z);
|
||||||
continue;
|
|
||||||
|
|
||||||
cchunk.removeTileEntity(blockPos);
|
|
||||||
cworld.setTypeAndData(blockPos, backupBlock, 1042);
|
|
||||||
cworld.getChunkProvider().flagDirty(blockPos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren