Compare commits
138 Commits
0f629a6387
...
BauSystem/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de4f32feb2 | ||
|
|
a3d2d2be1e | ||
|
|
7a000efb93 | ||
|
|
42c9d6d612 | ||
|
|
67c679a20f | ||
|
|
a071d8a1f2 | ||
|
|
7b25bd31fc | ||
|
|
139a2c275c | ||
|
|
aa787b5a25 | ||
|
|
54adc12045 | ||
| 32c85b9bd5 | |||
| 15bb92fbba | |||
| d6a5caf95d | |||
| 66d18e316b | |||
| 5cdad8c2f4 | |||
| 87a7120a6a | |||
| b5a9564808 | |||
| f93362a023 | |||
| b1bef4ced5 | |||
| e7e1e2d968 | |||
| 713275ba11 | |||
| e72ae3cf94 | |||
| d36753dec1 | |||
|
|
84cc292df4 | ||
| f89c4e88f9 | |||
| a38f9222dd | |||
| 5ee9d3e167 | |||
| 98321de46c | |||
|
|
239ba3f213 | ||
|
|
3d7dedd3ad | ||
| ef66b8c1f1 | |||
| 1201b16ee4 | |||
| 4ddd88f540 | |||
| 147e34c0d6 | |||
| ca35ab9234 | |||
| 3df84a7dad | |||
| 313b22cb44 | |||
| 83c20729fa | |||
| 925901e40e | |||
| 059dd314d1 | |||
| 86ff619548 | |||
| 76e00b07db | |||
| 4edfd32ff5 | |||
| 5669725f9b | |||
| 335649fa87 | |||
| 9001e83321 | |||
| 32703c6659 | |||
| e393aad25f | |||
| 50543ddd4e | |||
| 230ac09b61 | |||
| 48ea88e1a7 | |||
| 05dc42355d | |||
| 17704487c9 | |||
| 76bbfd0381 | |||
| ae9166528d | |||
| 119fae4b51 | |||
| 43621b18b4 | |||
| e5bdbac3c7 | |||
| fd738f539a | |||
| b4c7576433 | |||
| 8204e2ad21 | |||
| 684a74b60d | |||
| 1f58b51af6 | |||
| c9cfb48c4e | |||
| ace567ba33 | |||
| 2094120150 | |||
| e143268caa | |||
| 7802fdd7d9 | |||
| 7fb3d3d137 | |||
| 61d84492dc | |||
| f74780d395 | |||
| 62dac000d4 | |||
| 424c80ec81 | |||
| ae7d394ae2 | |||
| 306444356c | |||
| 29dff8dce6 | |||
| cbaacd4e85 | |||
| e24dada435 | |||
| d04ffd5cf6 | |||
| 9da1de9b6c | |||
| 866c376ee5 | |||
| 0b14a216d9 | |||
| b2853b9dec | |||
| df5c363fb7 | |||
| 5b3c3f36b4 | |||
| e1bcdd59ba | |||
| c9e4b57f12 | |||
| fdcd248ba6 | |||
| f573771355 | |||
| 80078cd8e2 | |||
| 76fc468d89 | |||
| 1304048509 | |||
|
|
cf4ac95c2f | ||
| 4a816696ec | |||
| 038f54c3b3 | |||
|
|
f2d8c9c02b | ||
|
|
2405c5e620 | ||
| d9493c7474 | |||
| 2ccb240ef5 | |||
| d1d1679c0a | |||
| 4c6ab2c1a0 | |||
| 62002e44d7 | |||
|
|
9c3f7526ff | ||
| eefe17e5f7 | |||
|
|
812e78d277 | ||
| fd220d7fd4 | |||
| 446cd5deae | |||
| a6c46d0270 | |||
| 2686ab285b | |||
| 57ea1470e2 | |||
| bfdc9c118a | |||
| dafe838a8a | |||
| 13bd154383 | |||
| 9248c9fa51 | |||
|
|
764dec99f4 | ||
| c9a1528dfe | |||
| 8c37466312 | |||
| 3b7e38aceb | |||
| e7c4c998a0 | |||
| 5907648462 | |||
| b32d6e9c69 | |||
| f533e85007 | |||
| 81c310c946 | |||
| 47c8cb1701 | |||
| f62af55d39 | |||
| 1dcd2f102c | |||
| 87f0765506 | |||
| b37ded3a8d | |||
|
|
c4e9f80315 | ||
| 19e14f787a | |||
|
|
9467291020 | ||
|
|
e14c7321c2 | ||
|
|
c94d67660a | ||
|
|
394591f302 | ||
|
|
3b41cc4ac5 | ||
|
|
29cb1cc5da | ||
| 20c90d9af5 | |||
| c799046f43 |
@@ -109,7 +109,7 @@ public class FlatteningWrapper15 implements FlatteningWrapper {
|
||||
|
||||
@Override
|
||||
public void setSelection(Player p, Point minPoint, Point maxPoint) {
|
||||
WORLDEDIT_PLUGIN.getSession(p).setRegionSelector(BUKKITWORLD, new CuboidRegionSelector(BUKKITWORLD, toBlockVector3(minPoint), toBlockVector3(maxPoint)));
|
||||
WORLDEDIT_PLUGIN.getSession(p).setRegionSelector(BUKKITWORLD, new CuboidRegionSelector(BUKKITWORLD, minPoint.toBlockVector3(), maxPoint.toBlockVector3()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -178,9 +178,9 @@ public class FlatteningWrapper15 implements FlatteningWrapper {
|
||||
pastePoint.set(v);
|
||||
|
||||
if (pasteBuilder.isReset()) {
|
||||
e.setBlocks(new CuboidRegion(toBlockVector3(pasteBuilder.getMinPoint()), toBlockVector3(pasteBuilder.getMaxPoint())), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock());
|
||||
e.setBlocks(new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3()), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock());
|
||||
if (pasteBuilder.getWaterLevel() != 0) {
|
||||
e.setBlocks(new CuboidRegion(toBlockVector3(pasteBuilder.getMinPoint()), toBlockVector3(pasteBuilder.getMaxPoint()).withY(pasteBuilder.getWaterLevel())), Objects.requireNonNull(BlockTypes.WATER).getDefaultState().toBaseBlock());
|
||||
e.setBlocks(new CuboidRegion(pasteBuilder.getMinPoint().toBlockVector3(), pasteBuilder.getMaxPoint().toBlockVector3().withY(pasteBuilder.getWaterLevel())), Objects.requireNonNull(BlockTypes.WATER).getDefaultState().toBaseBlock());
|
||||
}
|
||||
}
|
||||
Operations.completeBlindly(ch.createPaste(e).to(v).ignoreAirBlocks(pasteBuilder.isIgnoreAir()).build());
|
||||
@@ -193,7 +193,7 @@ public class FlatteningWrapper15 implements FlatteningWrapper {
|
||||
@Override
|
||||
public Clipboard copy(Point minPoint, Point maxPoint, Point copyPoint) {
|
||||
BukkitWorld bukkitWorld = new BukkitWorld(Bukkit.getWorlds().get(0));
|
||||
CuboidRegion region = new CuboidRegion(bukkitWorld, toBlockVector3(minPoint), toBlockVector3(maxPoint));
|
||||
CuboidRegion region = new CuboidRegion(bukkitWorld, minPoint.toBlockVector3(), maxPoint.toBlockVector3());
|
||||
BlockArrayClipboard clipboard = new BlockArrayClipboard(region);
|
||||
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(bukkitWorld, -1)) {
|
||||
ForwardExtentCopy copy = new ForwardExtentCopy(
|
||||
@@ -204,7 +204,7 @@ public class FlatteningWrapper15 implements FlatteningWrapper {
|
||||
copy.setCopyingBiomes(false);
|
||||
|
||||
Operations.complete(copy);
|
||||
clipboard.setOrigin(toBlockVector3(copyPoint));
|
||||
clipboard.setOrigin(copyPoint.toBlockVector3());
|
||||
return clipboard;
|
||||
} catch (WorldEditException e) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, e.getMessage(), e);
|
||||
@@ -224,10 +224,6 @@ public class FlatteningWrapper15 implements FlatteningWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
private BlockVector3 toBlockVector3(Point point) {
|
||||
return BlockVector3.at(point.getX(), point.getY(), point.getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inWater(org.bukkit.World world, Vector tntPosition) {
|
||||
Block block = world.getBlockAt(tntPosition.getBlockX(), tntPosition.getBlockY(), tntPosition.getBlockZ());
|
||||
|
||||
@@ -947,6 +947,9 @@ SPEED_TAB_NAME=Input speed
|
||||
WORLDEDIT_WAND=WorldEdit Wand
|
||||
WORLDEDIT_LEFTCLICK=Left click: select pos #1
|
||||
WORLDEDIT_RIGHTCLICK=Right click: select pos #2
|
||||
TNT_DETAILS_COMMAND=§8/§etntdetails §8-§7 Toggle information printed after clicking on a TNT
|
||||
TNT_DETAILS_ON = §eTNTDetails §aactivated
|
||||
TNT_DETAILS_OFF = §eTNTDetails §cdeactivated
|
||||
TNT_CLICK_HEADER=§8---=== §eTNT §8===---
|
||||
TNT_CLICK_ORDER=§eEntity Order§8: §e{0}
|
||||
TNT_CLICK_FUSE_TIME=§eFuseTime§8: §e{0}
|
||||
|
||||
@@ -889,6 +889,9 @@ SPEED_TAB_NAME=Geschwindigkeit eingeben
|
||||
WORLDEDIT_WAND=WorldEdit Wand
|
||||
WORLDEDIT_LEFTCLICK=Left click: select pos #1
|
||||
WORLDEDIT_RIGHTCLICK=Right click: select pos #2
|
||||
TNT_DETAILS_COMMAND=§8/§etntdetails §8-§7 Aktiviert/Deaktiviert das senden von Details beim Klick auf TNT
|
||||
TNT_DETAILS_ON = §eTNTDetails §aaktiviert
|
||||
TNT_DETAILS_OFF = §eTNTDetails §cdeaktiviert
|
||||
TNT_CLICK_HEADER=§8---=== §eTNT §8===---
|
||||
TNT_CLICK_ORDER=§eEntity Order§8: §e{0}
|
||||
TNT_CLICK_FUSE_TIME=§eFuseTime§8: §e{0}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package de.steamwar.bausystem.features.printerTool;
|
||||
|
||||
import de.steamwar.bausystem.utils.ItemUtils;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
@Linked
|
||||
public class PrinterToolItem implements Listener {
|
||||
public static ItemStack getItem(Player p) {
|
||||
ItemStack itemStack = new SWItem(Material.WOODEN_PICKAXE, "Printer Tool").getItemStack();
|
||||
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||
itemMeta.setCustomModelData(1);
|
||||
itemStack.setItemMeta(itemMeta);
|
||||
ItemUtils.setItem(itemStack, "printer_tool");
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
public static boolean isItem(ItemStack itemStack) {
|
||||
return itemStack != null && ItemUtils.isItem(itemStack, "printer_tool");
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||
ItemStack item = event.getItem();
|
||||
|
||||
if(PrinterToolItem.isItem(item)) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,9 @@ import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.data.type.NoteBlock;
|
||||
import org.bukkit.block.data.type.Switch;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
@@ -60,6 +61,24 @@ public class FreezeListener implements Listener, ScoreboardElement {
|
||||
@EventHandler
|
||||
public void onPhysicsEvent(BlockPhysicsEvent e) {
|
||||
if (Region.getRegion(e.getBlock().getLocation()).get(Flag.FREEZE) == FreezeMode.ACTIVE) {
|
||||
if (e.getSourceBlock().getType() == Material.NOTE_BLOCK) {
|
||||
BlockState state = e.getSourceBlock().getState();
|
||||
NoteBlock noteBlock = (NoteBlock) state.getBlockData();
|
||||
if (noteBlock.isPowered()) {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
state.update(true, false);
|
||||
}, 1);
|
||||
}
|
||||
}
|
||||
if (e.getBlock().getType() == Material.NOTE_BLOCK) {
|
||||
BlockState state = e.getBlock().getState();
|
||||
NoteBlock noteBlock = (NoteBlock) state.getBlockData();
|
||||
if (noteBlock.isPowered()) {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
state.update(true, false);
|
||||
}, 1);
|
||||
}
|
||||
}
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -71,6 +90,105 @@ public class FreezeListener implements Listener, ScoreboardElement {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onNotePlay(NotePlayEvent event) {
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=45, z=98},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=44, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=97},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=99},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=custom_head,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=97},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=96},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=99},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-108, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=45, z=98},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-104, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=45, z=98},type=CYAN_TERRACOTTA,data=Block{minecraft:cyan_terracotta},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=BARRIER,data=Block{minecraft:barrier},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=harp,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@78078831}
|
||||
|
||||
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=45, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=46, z=100},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=49, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=99},type=SMOOTH_STONE,data=Block{minecraft:smooth_stone},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
////[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=true],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=102},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-108, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-107, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=100},type=STONE_SLAB,data=Block{minecraft:stone_slab}[type=bottom,waterlogged=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-104, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=46, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=48, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-105, y=47, z=100},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=101},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-107, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-105, y=47, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=46, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=48, z=98},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=97},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=99},type=AIR,data=Block{minecraft:air},fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
//[STDOUT] CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b} -> CraftBlock{pos=BlockPosition{x=-106, y=47, z=98},type=NOTE_BLOCK,data=Block{minecraft:note_block}[instrument=basedrum,note=9,powered=false],fluid=net.minecraft.world.level.material.FluidTypeEmpty@1531ed7b}
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void onPistonRetract(BlockPistonRetractEvent e) {
|
||||
if (Region.getRegion(e.getBlock().getLocation()).get(Flag.FREEZE) == FreezeMode.ACTIVE) {
|
||||
@@ -108,13 +226,13 @@ public class FreezeListener implements Listener, ScoreboardElement {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onBlockBreak(BlockBreakEvent e) {
|
||||
if (Core.getVersion() < 19) return;
|
||||
if (e.getPlayer().getInventory().getItemInMainHand().getType() == Material.DEBUG_STICK) return;
|
||||
if (Region.getRegion(e.getBlock().getLocation()).get(Flag.FREEZE) == FreezeMode.ACTIVE) {
|
||||
if (e.isCancelled()) return;
|
||||
e.setCancelled(true);
|
||||
e.getBlock().setType(Material.BARRIER, false);
|
||||
e.getBlock().setType(Material.AIR, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class TpsLib implements LuaLib {
|
||||
tpsLib.set("fiveMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES)));
|
||||
tpsLib.set("tenMinute", getter(() -> TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES)));
|
||||
tpsLib.set("current", getter(TPSWatcher::getTPS));
|
||||
tpsLib.set("limit", getter(tpsSystem::getCurrentTPSLimit));
|
||||
tpsLib.set("limit", getter(TPSSystem::getCurrentTPSLimit));
|
||||
return tpsLib;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.script.lua.libs;
|
||||
|
||||
import de.steamwar.bausystem.features.tracer.TNTPoint;
|
||||
import de.steamwar.bausystem.features.tracer.Trace;
|
||||
import de.steamwar.bausystem.features.tracer.TraceManager;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.luaj.vm2.LuaTable;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.lib.ZeroArgFunction;
|
||||
|
||||
@Linked
|
||||
public class TracerLib implements LuaLib {
|
||||
@Override
|
||||
public String name() {
|
||||
return "tracer";
|
||||
}
|
||||
|
||||
private static LuaTable convertTrace(Trace trace) {
|
||||
LuaTable luaTrace = new LuaTable();
|
||||
|
||||
luaTrace.set("getRecords", new ZeroArgFunction() {
|
||||
@Override
|
||||
public LuaValue call() {
|
||||
return LuaValue.listOf(
|
||||
trace.getHistories()
|
||||
.stream()
|
||||
.map((history) -> LuaValue.listOf(history
|
||||
.stream()
|
||||
.map(TracerLib::convertTntPoint)
|
||||
.toArray(LuaValue[]::new)))
|
||||
.toArray(LuaValue[]::new));
|
||||
}
|
||||
});
|
||||
|
||||
luaTrace.set("getId", new ZeroArgFunction() {
|
||||
@Override
|
||||
public LuaValue call() {
|
||||
return LuaValue.valueOf(trace.getUuid().toString());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return luaTrace;
|
||||
}
|
||||
|
||||
private static LuaTable convertTntPoint(TNTPoint tntPoint) {
|
||||
Location pointPos = tntPoint.getLocation();
|
||||
LuaTable luaPos = LuaValue.tableOf(new LuaValue[]{
|
||||
LuaValue.valueOf("x"), LuaValue.valueOf(pointPos.getX()),
|
||||
LuaValue.valueOf("y"), LuaValue.valueOf(pointPos.getY()),
|
||||
LuaValue.valueOf("z"), LuaValue.valueOf(pointPos.getZ()),
|
||||
});
|
||||
|
||||
Vector pointVel = tntPoint.getVelocity();
|
||||
LuaTable luaVel = LuaValue.tableOf(new LuaValue[]{
|
||||
LuaValue.valueOf("x"), LuaValue.valueOf(pointVel.getX()),
|
||||
LuaValue.valueOf("y"), LuaValue.valueOf(pointVel.getY()),
|
||||
LuaValue.valueOf("z"), LuaValue.valueOf(pointVel.getZ()),
|
||||
});
|
||||
|
||||
return LuaValue.tableOf(new LuaValue[]{
|
||||
LuaValue.valueOf("pos"), luaPos,
|
||||
LuaValue.valueOf("vel"), luaVel,
|
||||
LuaValue.valueOf("ticksSinceStart"), LuaValue.valueOf(tntPoint.getTicksSinceStart()),
|
||||
LuaValue.valueOf("fuse"), LuaValue.valueOf(tntPoint.getFuse()),
|
||||
LuaValue.valueOf("isExplosion"), LuaValue.valueOf(tntPoint.isExplosion()),
|
||||
LuaValue.valueOf("isInWater"), LuaValue.valueOf(tntPoint.isInWater()),
|
||||
LuaValue.valueOf("hasDestroyedBuild"), LuaValue.valueOf(tntPoint.isDestroyedBuildArea()),
|
||||
LuaValue.valueOf("hasDestroyedTestblock"), LuaValue.valueOf(tntPoint.isDestroyedTestBlock())
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public LuaTable get(Player player) {
|
||||
LuaTable rootTable = LuaValue.tableOf();
|
||||
|
||||
rootTable.set("getTraces", new ZeroArgFunction() {
|
||||
@Override
|
||||
public LuaValue call() {
|
||||
return LuaValue.listOf(TraceManager.instance.getAll()
|
||||
.stream()
|
||||
.map(TracerLib::convertTrace)
|
||||
.toArray(LuaValue[]::new));
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
return rootTable;
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public class SimulatorCommand extends SWCommand {
|
||||
|
||||
@Register(value = "start", description = "SIMULATOR_START_HELP")
|
||||
public void start(@Validator Player p, @ErrorMessage("SIMULATOR_NOT_EXISTS") Simulator simulator) {
|
||||
SimulatorExecutor.run(simulator);
|
||||
SimulatorExecutor.run(simulator, () -> {});
|
||||
}
|
||||
|
||||
@Register(value = "rename", description = "SIMULATOR_RENAME_HELP")
|
||||
|
||||
@@ -168,9 +168,19 @@ public class SimulatorCursor implements Listener {
|
||||
}
|
||||
return;
|
||||
}
|
||||
Simulator simulator = SimulatorStorage.getSimulator(player);
|
||||
SimulatorWatcher.show(simulator, player);
|
||||
|
||||
Simulator simulator = SimulatorStorage.getSimulator(player);
|
||||
if (simulator != null && simulator.getStabGenerator() != null) {
|
||||
removeCursor(player);
|
||||
SimulatorWatcher.show(null, player);
|
||||
SWUtils.sendToActionbar(player, "§cGenerating Stab");
|
||||
synchronized (calculating) {
|
||||
calculating.remove(player);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
SimulatorWatcher.show(simulator, player);
|
||||
List<REntity> entities = SimulatorWatcher.getEntitiesOfSimulator(simulator);
|
||||
RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(player, player.getLocation(), entities);
|
||||
if (rayTraceResult == null) {
|
||||
@@ -357,7 +367,7 @@ public class SimulatorCursor implements Listener {
|
||||
if (simulator == null) {
|
||||
return;
|
||||
}
|
||||
SimulatorExecutor.run(simulator);
|
||||
SimulatorExecutor.run(simulator, () -> {});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
package de.steamwar.bausystem.features.simulator.data;
|
||||
|
||||
import de.steamwar.bausystem.features.simulator.execute.SimulatorAction;
|
||||
import de.steamwar.bausystem.features.simulator.execute.SimulatorStabGenerator;
|
||||
import de.steamwar.inventory.InvCallback;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import lombok.Getter;
|
||||
@@ -30,13 +31,13 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@RequiredArgsConstructor
|
||||
public final class Simulator {
|
||||
private SimulatorStabGenerator stabGenerator = null;
|
||||
private Material material = Material.BARREL;
|
||||
private final String name;
|
||||
private boolean autoTrace = false;
|
||||
|
||||
@@ -60,6 +60,7 @@ public final class TNTPhase extends SimulatorPhase {
|
||||
|
||||
@Override
|
||||
public void toSimulatorActions(Vector position, BiConsumer<Integer, SimulatorAction> tickStart, BiConsumer<Integer, SimulatorAction> tickEnd) {
|
||||
if (count <= 0) return;
|
||||
tickStart.accept(tickOffset, new SimulatorAction(order, count) {
|
||||
@Override
|
||||
public void accept(World world) {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum Direction {
|
||||
X(Vector::getBlockX),
|
||||
Y(Vector::getBlockY),
|
||||
Z(Vector::getBlockZ);
|
||||
|
||||
public final Function<Vector, Integer> component;
|
||||
}
|
||||
@@ -46,7 +46,7 @@ public class SimulatorExecutor implements Listener {
|
||||
private static Map<Long, Map<Integer, List<SimulatorAction>>> tickStartActions = new HashMap<>();
|
||||
private static Map<Long, List<SimulatorAction>> tickEndActions = new HashMap<>();
|
||||
|
||||
public static boolean run(Simulator simulator) {
|
||||
public static boolean run(Simulator simulator, Runnable onEnd) {
|
||||
if (currentlyRunning.contains(simulator)) return false;
|
||||
currentlyRunning.add(simulator);
|
||||
|
||||
@@ -69,7 +69,7 @@ public class SimulatorExecutor implements Listener {
|
||||
public void accept(World world) {
|
||||
currentlyRunning.remove(simulator);
|
||||
|
||||
if (simulator.isAutoTrace()) {
|
||||
if (simulator.isAutoTrace() && onEnd == null) {
|
||||
simulator.getGroups()
|
||||
.stream()
|
||||
.map(SimulatorGroup::getElements)
|
||||
@@ -82,10 +82,12 @@ public class SimulatorExecutor implements Listener {
|
||||
TraceRecorder.instance.stopRecording(region);
|
||||
});
|
||||
}
|
||||
|
||||
onEnd.run();
|
||||
}
|
||||
});
|
||||
|
||||
if (simulator.isAutoTrace()) {
|
||||
if (simulator.isAutoTrace() && onEnd == null) {
|
||||
simulator.getGroups()
|
||||
.stream()
|
||||
.map(SimulatorGroup::getElements)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import de.steamwar.bausystem.features.simulator.data.Simulator;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.utils.bossbar.BossBarService;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class SimulatorStabGenerator {
|
||||
|
||||
private final StabData stabData;
|
||||
|
||||
public SimulatorStabGenerator(Region region, Simulator simulator, TNTElement tntElement, int depthLimit) {
|
||||
stabData = new StabData(region, simulator, tntElement, tntElement.getPhases(), depthLimit);
|
||||
new StabSetup(stabData);
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
stabData.cancel = true;
|
||||
stabData.simulator.setStabGenerator(null);
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
BossBarService.instance.remove(player, stabData.region, "simulator_stab_generator");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import de.steamwar.bausystem.features.simulator.data.Simulator;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class StabData {
|
||||
|
||||
protected static final int MAX_RECORDINGS = 5;
|
||||
protected static final int MAX_TICK_DIFFERENCE = 3;
|
||||
protected static final Level LEVEL = Level.INFO;
|
||||
protected static final int TNT_INCREASE = 10;
|
||||
protected static final int MIN_BLOCK_TO_COUNT_AS_DEPTH = 20;
|
||||
|
||||
protected final Region region;
|
||||
protected final Simulator simulator;
|
||||
protected final TNTElement tntElement;
|
||||
protected final List<TNTPhase> phases;
|
||||
protected final int depthLimit;
|
||||
|
||||
protected Clipboard clipboard;
|
||||
protected boolean cancel = false;
|
||||
|
||||
protected Direction direction = null;
|
||||
protected int currentDepth = 0;
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import de.steamwar.bausystem.features.simulator.data.SimulatorPhase;
|
||||
import de.steamwar.bausystem.features.tracer.TNTPoint;
|
||||
import de.steamwar.bausystem.features.tracer.Trace;
|
||||
import de.steamwar.bausystem.features.tracer.TraceManager;
|
||||
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class StabDirection extends StabStep {
|
||||
|
||||
public StabDirection(StabData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void start() {
|
||||
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) {
|
||||
e.setBlocks((com.sk89q.worldedit.regions.Region) new CuboidRegion(data.region.getMinPointTestblockExtension().toBlockVector3(), data.region.getMaxPointTestblockExtension().toBlockVector3()), Objects.requireNonNull(BlockTypes.AIR).getDefaultState().toBaseBlock());
|
||||
}
|
||||
|
||||
Trace trace = TraceRecorder.instance.startRecording(data.region);
|
||||
runSimulator(() -> {
|
||||
TraceRecorder.instance.stopRecording(data.region);
|
||||
calculateDirection(trace);
|
||||
});
|
||||
}
|
||||
|
||||
private void calculateDirection(Trace trace) {
|
||||
long tickSinceStart = -1;
|
||||
List<TNTPoint> points = null;
|
||||
for (List<TNTPoint> current : trace.getHistories()) {
|
||||
long ticks = current.get(0).getTicksSinceStart();
|
||||
if (points == null || ticks > tickSinceStart) {
|
||||
tickSinceStart = ticks;
|
||||
points = current;
|
||||
} else if (ticks == tickSinceStart && points.get(0).getTntId() < current.get(0).getTntId()) {
|
||||
points = current;
|
||||
}
|
||||
}
|
||||
TraceManager.instance.remove(trace);
|
||||
if (points == null) {
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
TNTPoint current = points.getLast();
|
||||
Vector velocity = current.getVelocity();
|
||||
if (velocity.getX() < 0) velocity.setX(-velocity.getX());
|
||||
if (velocity.getY() < 0) velocity.setY(-velocity.getY());
|
||||
if (velocity.getZ() < 0) velocity.setZ(-velocity.getZ());
|
||||
if (velocity.getX() > velocity.getY() && velocity.getX() > velocity.getZ()) {
|
||||
data.direction = Direction.X;
|
||||
} else if (velocity.getY() > velocity.getX() && velocity.getY() > velocity.getZ()) {
|
||||
data.direction = Direction.Y;
|
||||
} else if (velocity.getZ() > velocity.getX() && velocity.getZ() > velocity.getY()) {
|
||||
data.direction = Direction.Z;
|
||||
} else {
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Direction: {0}", data.direction);
|
||||
data.phases.getFirst().setOrder(SimulatorPhase.ORDER_LIMIT);
|
||||
data.phases.getFirst().setCount(StabData.TNT_INCREASE);
|
||||
new StabGenerator(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bossbar(BauSystemBossbar bossbar, boolean finished) {
|
||||
bossbar.setProgress(0);
|
||||
bossbar.setTitle("§eCalculating Stab Direction");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import de.steamwar.bausystem.features.tracer.Trace;
|
||||
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
||||
import de.steamwar.bausystem.region.flags.Flag;
|
||||
import de.steamwar.bausystem.region.flags.flagvalues.ColorMode;
|
||||
import de.steamwar.bausystem.region.utils.RegionExtensionType;
|
||||
import de.steamwar.bausystem.region.utils.RegionType;
|
||||
import de.steamwar.bausystem.utils.PasteBuilder;
|
||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||
|
||||
public class StabFinalizer extends StabStep {
|
||||
|
||||
public StabFinalizer(StabData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void start() {
|
||||
try {
|
||||
PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(data.clipboard);
|
||||
PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider)
|
||||
.color(data.region.getPlain(Flag.COLOR, ColorMode.class).getColor());
|
||||
data.region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION);
|
||||
} catch (SecurityException e) {
|
||||
stop();
|
||||
throw e;
|
||||
}
|
||||
|
||||
TraceRecorder.instance.startRecording(data.region);
|
||||
runSimulator(() -> {
|
||||
TraceRecorder.instance.stopRecording(data.region);
|
||||
stop();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bossbar(BauSystemBossbar bossbar, boolean stopped) {
|
||||
bossbar.setProgress(Math.min(data.currentDepth / (double) data.depthLimit, 1.0));
|
||||
bossbar.setTitle("§e" + data.currentDepth + "§8/§7" + data.depthLimit);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.region.flags.Flag;
|
||||
import de.steamwar.bausystem.region.flags.flagvalues.ColorMode;
|
||||
import de.steamwar.bausystem.region.utils.RegionExtensionType;
|
||||
import de.steamwar.bausystem.region.utils.RegionType;
|
||||
import de.steamwar.bausystem.utils.PasteBuilder;
|
||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static de.steamwar.bausystem.features.simulator.execute.Direction.Y;
|
||||
|
||||
public class StabGenerator extends StabStep implements Listener {
|
||||
|
||||
private int recordings = 0;
|
||||
private List<Integer> currentDepths = new ArrayList<>();
|
||||
private int lastDepth = 0;
|
||||
|
||||
private int retries = 0;
|
||||
|
||||
private final Map<Integer, Set<Location>> destroyedBlocksPerSlice = new HashMap<>();
|
||||
|
||||
private Set<Integer> gabStart = new HashSet<>();
|
||||
private Set<TNTPhase> failedAtLeastOnce = new HashSet<>();
|
||||
|
||||
@EventHandler
|
||||
public void onEntityExplode(EntityExplodeEvent event) {
|
||||
if (Region.getRegion(event.getEntity().getLocation()) == data.region) {
|
||||
event.blockList().forEach(block -> {
|
||||
if (!data.region.inRegion(block.getLocation(), RegionType.TESTBLOCK, RegionExtensionType.EXTENSION)) return;
|
||||
int component = data.direction.component.apply(block.getLocation().toVector());
|
||||
destroyedBlocksPerSlice.computeIfAbsent(component, __ -> new HashSet<>())
|
||||
.add(block.getLocation());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public StabGenerator(StabData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void start() {
|
||||
try {
|
||||
PasteBuilder.ClipboardProvider clipboardProvider = new PasteBuilder.ClipboardProviderImpl(data.clipboard);
|
||||
PasteBuilder pasteBuilder = new PasteBuilder(clipboardProvider)
|
||||
.color(data.region.getPlain(Flag.COLOR, ColorMode.class).getColor());
|
||||
data.region.reset(pasteBuilder, RegionType.TESTBLOCK, RegionExtensionType.EXTENSION);
|
||||
} catch (SecurityException e) {
|
||||
stop();
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (data.cancel) {
|
||||
HandlerList.unregisterAll(this);
|
||||
return;
|
||||
}
|
||||
|
||||
runSimulator(this::calculateStab);
|
||||
}
|
||||
|
||||
private void calculateStab() {
|
||||
TNTPhase lastPhase = data.phases.getLast();
|
||||
|
||||
List<Map.Entry<Integer, Set<Location>>> locations = destroyedBlocksPerSlice.entrySet()
|
||||
.stream()
|
||||
.sorted(Comparator.comparingInt(Map.Entry::getKey))
|
||||
.collect(Collectors.toList());
|
||||
int depth = 0;
|
||||
for (int i = 0; i < locations.size(); i++) {
|
||||
if (data.direction != Y && i > 0 && Math.abs(locations.get(i - 1).getKey() - locations.get(i).getKey()) > 3) {
|
||||
if (gabStart.add(locations.get(i).getKey())) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Increasing tnt count by {0} because of gap", StabData.TNT_INCREASE);
|
||||
lastPhase.setCount(lastPhase.getCount() + StabData.TNT_INCREASE);
|
||||
recordings = 0;
|
||||
currentDepths.clear();
|
||||
|
||||
run();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (i == 0 || i == locations.size() - 1) {
|
||||
if (locations.get(i).getValue().size() > StabData.MIN_BLOCK_TO_COUNT_AS_DEPTH) {
|
||||
depth++;
|
||||
}
|
||||
} else {
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
|
||||
if (depth > 0) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "{0} {1} {2}", new Object[]{depth, destroyedBlocksPerSlice.size(), destroyedBlocksPerSlice.values().stream().map(Set::size).collect(Collectors.toList())});
|
||||
destroyedBlocksPerSlice.clear();
|
||||
currentDepths.add(depth);
|
||||
} else {
|
||||
destroyedBlocksPerSlice.clear();
|
||||
lastPhase.setTickOffset(lastPhase.getTickOffset() + 1);
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "No dimension - Increasing tickOffset to: {0}", lastPhase.getTickOffset());
|
||||
lastPhase.setOrder(0);
|
||||
if (lastPhase.getTickOffset() > 80) {
|
||||
stop();
|
||||
} else {
|
||||
run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int minDepth = currentDepths.stream().min(Integer::compareTo).orElse(0);
|
||||
int maxDepth = currentDepths.stream().max(Integer::compareTo).orElse(0);
|
||||
data.currentDepth = maxDepth;
|
||||
|
||||
int countWithoutLast = 0;
|
||||
for (int i = 0; i < data.phases.size() - 1; i++) {
|
||||
countWithoutLast += data.phases.get(i).getCount();
|
||||
}
|
||||
countWithoutLast -= gabStart.size();
|
||||
|
||||
boolean moreTNTNeeded = maxDepth - countWithoutLast >= lastPhase.getCount() - 5;
|
||||
if (moreTNTNeeded) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Increasing tnt count by {0}", StabData.TNT_INCREASE);
|
||||
lastPhase.setCount(lastPhase.getCount() + StabData.TNT_INCREASE);
|
||||
recordings = 0;
|
||||
currentDepths.clear();
|
||||
|
||||
run();
|
||||
return;
|
||||
}
|
||||
|
||||
if (recordings++ < StabData.MAX_RECORDINGS) {
|
||||
run();
|
||||
return;
|
||||
}
|
||||
|
||||
recordings = 0;
|
||||
currentDepths.clear();
|
||||
|
||||
if (maxDepth - minDepth > lastPhase.getCount()) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Stab failed at least once. Adding one tnt to {0}", minDepth - 3);
|
||||
int current = 0;
|
||||
TNTPhase last = null;
|
||||
for (TNTPhase phase : data.phases) {
|
||||
if (current < minDepth - 3) {
|
||||
current += phase.getCount();
|
||||
last = phase;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (failedAtLeastOnce.add(last)) {
|
||||
last = null;
|
||||
break;
|
||||
}
|
||||
|
||||
if (last != null) {
|
||||
last.setCount(last.getCount() + 1);
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Added to phase {0} now has {1} tnt", new Object[]{data.phases.indexOf(last), last.getCount()});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (last != null) {
|
||||
run();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "No more TNT needed on phase adjusting - {0} new count; {1} current count", new Object[]{maxDepth - countWithoutLast, lastPhase.getCount()});
|
||||
lastPhase.setCount(maxDepth - countWithoutLast);
|
||||
if (lastPhase.getCount() <= 0) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Count was 0 or negative - removing last phase");
|
||||
data.phases.removeLast();
|
||||
}
|
||||
|
||||
if (maxDepth > data.depthLimit) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Depth is greater than {0} - finished", data.depthLimit);
|
||||
new StabFinalizer(data);
|
||||
return;
|
||||
}
|
||||
if (maxDepth <= lastDepth) {
|
||||
if (lastPhase.getCount() <= 0) {
|
||||
retries++;
|
||||
}
|
||||
if (lastPhase.getCount() > 0 || retries > StabData.MAX_TICK_DIFFERENCE) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Depth is equal to last depth recorded {0} - finished", maxDepth);
|
||||
new StabFinalizer(data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
lastDepth = maxDepth;
|
||||
|
||||
newPhase(data, lastPhase);
|
||||
run();
|
||||
}
|
||||
|
||||
public static void newPhase(StabData data, TNTPhase lastPhase) {
|
||||
Bukkit.getLogger().log(StabData.LEVEL, "Adding new phase in next tick");
|
||||
TNTPhase nextPhase = new TNTPhase();
|
||||
nextPhase.setCount(StabData.TNT_INCREASE);
|
||||
nextPhase.setTickOffset(lastPhase.getTickOffset() + 1);
|
||||
nextPhase.setXJump(lastPhase.isXJump());
|
||||
nextPhase.setYJump(lastPhase.isYJump());
|
||||
nextPhase.setZJump(lastPhase.isZJump());
|
||||
data.phases.add(nextPhase);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bossbar(BauSystemBossbar bossbar, boolean finished) {
|
||||
bossbar.setProgress(Math.min(data.currentDepth / (double) data.depthLimit, 1.0));
|
||||
if (finished) {
|
||||
bossbar.setTitle("§e" + data.currentDepth + "§8/§7" + data.depthLimit);
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder st = new StringBuilder();
|
||||
st.append("§7Direction §e").append(data.direction);
|
||||
st.append(" §e").append(data.currentDepth).append("§8/§7").append(data.depthLimit);
|
||||
if (recordings > 0) {
|
||||
st.append(" §7Retries§8:§e ").append(recordings).append("§8/§7").append(StabData.MAX_RECORDINGS);
|
||||
}
|
||||
bossbar.setTitle(st.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
|
||||
import de.steamwar.bausystem.features.tracer.TraceRecorder;
|
||||
import de.steamwar.bausystem.utils.FlatteningWrapper;
|
||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class StabSetup extends StabStep {
|
||||
|
||||
public StabSetup(StabData data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void start() {
|
||||
TNTPhase tntPhase = data.simulator.getGroups().stream()
|
||||
.filter(simulatorGroup -> !simulatorGroup.isDisabled())
|
||||
.map(SimulatorGroup::getElements)
|
||||
.flatMap(List::stream)
|
||||
.filter(TNTElement.class::isInstance)
|
||||
.map(TNTElement.class::cast)
|
||||
.filter(tntElement -> !tntElement.isDisabled())
|
||||
.filter(tntElement -> data.tntElement != tntElement)
|
||||
.map(tntElement -> tntElement.getPhases().stream().max(Comparator.comparingInt(TNTPhase::getTickOffset)))
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.peek(phase -> {
|
||||
if (phase.getOrder() > TNTPhase.ORDER_LIMIT) {
|
||||
phase.setOrder(TNTPhase.ORDER_LIMIT);
|
||||
}
|
||||
})
|
||||
.filter(phase -> phase != data.phases.get(0))
|
||||
.max(Comparator.comparingInt(TNTPhase::getTickOffset))
|
||||
.orElse(null);
|
||||
if (tntPhase == null) {
|
||||
throw new SecurityException("");
|
||||
}
|
||||
|
||||
TNTPhase phase = data.phases.get(0);
|
||||
data.phases.clear();
|
||||
data.phases.add(phase);
|
||||
phase.setCount(1);
|
||||
phase.setTickOffset(tntPhase.getTickOffset());
|
||||
phase.setOrder(100);
|
||||
|
||||
TraceRecorder.instance.stopRecording(data.region);
|
||||
if (TraceRecorder.instance.isAutoTraceEnabledInRegion(data.region)) {
|
||||
TraceRecorder.instance.removeAutoTraceRegion(data.region);
|
||||
}
|
||||
data.clipboard = FlatteningWrapper.impl.copy(data.region.getMinPointTestblockExtension(), data.region.getMaxPointTestblockExtension(), data.region.getTestBlockPoint());
|
||||
|
||||
new StabDirection(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bossbar(BauSystemBossbar bossbar, boolean finished) {
|
||||
bossbar.setProgress(0);
|
||||
bossbar.setTitle("§eSetting up Simulator");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bausystem.features.simulator.execute;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
|
||||
import de.steamwar.bausystem.utils.bossbar.BauSystemBossbar;
|
||||
import de.steamwar.bausystem.utils.bossbar.BossBarService;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.boss.BarColor;
|
||||
import org.bukkit.boss.BarStyle;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public abstract class StabStep {
|
||||
|
||||
protected final StabData data;
|
||||
|
||||
protected StabStep(StabData data) {
|
||||
this.data = data;
|
||||
run();
|
||||
}
|
||||
|
||||
protected final void run() {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
BauSystemBossbar bossbar = BossBarService.instance.get(player, data.region, "simulator_stab_generator");
|
||||
bossbar.setColor(BarColor.GREEN);
|
||||
bossbar.setStyle(BarStyle.SEGMENTED_10);
|
||||
bossbar(bossbar, false);
|
||||
}
|
||||
}, 1);
|
||||
|
||||
if (this instanceof Listener) {
|
||||
Bukkit.getPluginManager().registerEvents((Listener) this, BauSystem.getInstance());
|
||||
}
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), this::start, 20);
|
||||
}
|
||||
|
||||
protected abstract void start();
|
||||
|
||||
protected final void runSimulator(Runnable onFinish) {
|
||||
SimulatorExecutor.run(data.simulator, () -> {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
if (this instanceof Listener) {
|
||||
HandlerList.unregisterAll((Listener) this);
|
||||
}
|
||||
onFinish.run();
|
||||
}, 20);
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract void bossbar(BauSystemBossbar bossbar, boolean stopped);
|
||||
|
||||
protected final void stop() {
|
||||
data.simulator.setStabGenerator(null);
|
||||
SimulatorWatcher.update(data.simulator);
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
BauSystemBossbar bossbar = BossBarService.instance.get(player, data.region, "simulator_stab_generator");
|
||||
bossbar.setColor(BarColor.GREEN);
|
||||
bossbar.setStyle(BarStyle.SEGMENTED_10);
|
||||
bossbar(bossbar, true);
|
||||
}
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(4000);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} finally {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
BossBarService.instance.remove(player, data.region, "simulator_stab_generator");
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,11 @@ import de.steamwar.bausystem.features.simulator.data.Simulator;
|
||||
import de.steamwar.bausystem.features.simulator.data.SimulatorGroup;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTElement;
|
||||
import de.steamwar.bausystem.features.simulator.data.tnt.TNTPhase;
|
||||
import de.steamwar.bausystem.features.simulator.execute.SimulatorStabGenerator;
|
||||
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorAnvilGui;
|
||||
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorBaseGui;
|
||||
import de.steamwar.bausystem.features.simulator.gui.base.SimulatorScrollGui;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
@@ -97,6 +100,14 @@ public class SimulatorTNTGui extends SimulatorScrollGui<TNTPhase> {
|
||||
tnt.setDisabled(!tnt.isDisabled());
|
||||
SimulatorWatcher.update(simulator);
|
||||
}));
|
||||
inventory.setItem(49, new SWItem(Material.CALIBRATED_SCULK_SENSOR, "§eCreate Stab", click -> {
|
||||
new SimulatorAnvilGui<>(player, "Depth Limit", "", Integer::parseInt, depthLimit -> {
|
||||
if (depthLimit <= 0) return false;
|
||||
simulator.setStabGenerator(new SimulatorStabGenerator(Region.getRegion(player.getLocation()), simulator, tnt, depthLimit));
|
||||
SimulatorWatcher.update(simulator);
|
||||
return true;
|
||||
}, null).open();
|
||||
}));
|
||||
inventory.setItem(50, new SWItem(Material.CHEST, parent.getElements().size() == 1 ? "§eMake Group" : "§eAdd another TNT to Group", clickType -> {
|
||||
TNTElement tntElement = new TNTElement(tnt.getPosition().clone());
|
||||
tntElement.add(new TNTPhase());
|
||||
|
||||
@@ -44,7 +44,7 @@ public class SimulatorAnvilGui<T extends Number> {
|
||||
if (error.get()) {
|
||||
anvilInv.open();
|
||||
} else {
|
||||
back.open();
|
||||
if (back != null) back.open();
|
||||
}
|
||||
error.set(false);
|
||||
}, 0);
|
||||
|
||||
@@ -22,7 +22,6 @@ package de.steamwar.bausystem.features.simulator.gui.base;
|
||||
import de.steamwar.bausystem.features.simulator.SimulatorWatcher;
|
||||
import de.steamwar.bausystem.features.simulator.data.Simulator;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.core.TrickyTrialsWrapper;
|
||||
import de.steamwar.inventory.SWInventory;
|
||||
import de.steamwar.inventory.SWItem;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -64,7 +63,11 @@ public abstract class SimulatorBaseGui {
|
||||
if (Core.getVersion() > 19) {
|
||||
player.getOpenInventory().setTitle(title());
|
||||
}
|
||||
populate();
|
||||
if (simulator != null && simulator.getStabGenerator() != null) {
|
||||
populateStabGenerator();
|
||||
} else {
|
||||
populate();
|
||||
}
|
||||
if (player.getOpenInventory().getTopInventory() == inv) {
|
||||
inventory.open();
|
||||
SimulatorWatcher.watch(player, simulator, this::open);
|
||||
@@ -84,10 +87,21 @@ public abstract class SimulatorBaseGui {
|
||||
});
|
||||
|
||||
SimulatorWatcher.watch(player, simulator, this::open);
|
||||
populate();
|
||||
if (simulator != null && simulator.getStabGenerator() != null) {
|
||||
populateStabGenerator();
|
||||
} else {
|
||||
populate();
|
||||
}
|
||||
inventory.open();
|
||||
}
|
||||
|
||||
private void populateStabGenerator() {
|
||||
inventory.setItem(22, new SWItem(Material.BARRIER, "§cCancel Stab Generator", click -> {
|
||||
simulator.getStabGenerator().cancel();
|
||||
SimulatorWatcher.update(simulator);
|
||||
}));
|
||||
}
|
||||
|
||||
public boolean shouldOpen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import de.steamwar.bausystem.utils.WorldEditUtils;
|
||||
import de.steamwar.core.Core;
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
import org.bukkit.Location;
|
||||
@@ -56,7 +57,7 @@ public class Panzern {
|
||||
|
||||
private BaseBlock blockType;
|
||||
private BaseBlock slabType;
|
||||
private static final BaseBlock jukeboxType = BlockTypes.JUKEBOX.getDefaultState().toBaseBlock();
|
||||
private static final BaseBlock jukeboxType = (Core.getVersion() > 19 ? BlockTypes.get("lodestone"): BlockTypes.get("jukebox")).getDefaultState().toBaseBlock();
|
||||
private static final BaseBlock cobwebType = BlockTypes.COBWEB.getDefaultState().toBaseBlock();
|
||||
private static final BaseBlock airType = BlockTypes.AIR.getDefaultState().toBaseBlock();
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
package de.steamwar.bausystem.features.smartplace;
|
||||
|
||||
import de.steamwar.Reflection;
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.Reflection;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.bausystem.configplayer.Config;
|
||||
@@ -223,7 +223,7 @@ public class SmartPlaceListener implements Listener {
|
||||
Block block = event.getBlock().getRelative(BlockFace.DOWN);
|
||||
BlockState old = block.getState();
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
block.setType(Material.GLASS);
|
||||
block.setType(Material.GLASS, true);
|
||||
old.update(true, false);
|
||||
}, 1);
|
||||
}
|
||||
|
||||
@@ -42,16 +42,16 @@ public class TPSCommand extends SWCommand {
|
||||
public void genericCommand(Player p, String... args) {
|
||||
BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_HEAD", p);
|
||||
BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_MESSAGE", p,
|
||||
TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_SECOND),
|
||||
TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_SECONDS),
|
||||
TPSWatcher.getTPS(TPSWatcher.TPSType.ONE_MINUTE),
|
||||
TPSWatcher.getTPS(TPSWatcher.TPSType.FIVE_MINUTES),
|
||||
TPSWatcher.getTPS(TPSWatcher.TPSType.TEN_MINUTES)
|
||||
TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.ONE_SECOND),
|
||||
TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.TEN_SECONDS),
|
||||
TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.ONE_MINUTE),
|
||||
TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.FIVE_MINUTES),
|
||||
TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.TEN_MINUTES)
|
||||
);
|
||||
}
|
||||
|
||||
@Register
|
||||
public void genericCommand(Player p, TPSWatcher.TPSType type) {
|
||||
BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_SINGLE", p, tpsSystem.getTPS(type));
|
||||
BauSystem.MESSAGE.sendPrefixless("OTHER_TPS_SINGLE", p, TPSWatcher.getTPSUnlimited(type));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,11 +56,7 @@ import java.util.Arrays;
|
||||
public class TPSSystem implements Listener {
|
||||
|
||||
@Getter
|
||||
private double currentTPSLimit = 20;
|
||||
|
||||
public double getTPS(TPSWatcher.TPSType tpsType) {
|
||||
return TPSWatcher.getTPSUnlimited(tpsType);
|
||||
}
|
||||
private static double currentTPSLimit = 20;
|
||||
|
||||
public TPSSystem() {
|
||||
if (TPSFreezeUtils.isCanFreeze()) {
|
||||
@@ -338,26 +334,26 @@ public class TPSSystem implements Listener {
|
||||
} else if (TPSFreezeUtils.frozen()) {
|
||||
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: " + BauSystem.MESSAGE.parse("SCOREBOARD_TPS_FROZEN", p);
|
||||
} else {
|
||||
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: " + tpsColor() + tpsSystem.getTPS(TPSWatcher.TPSType.ONE_SECOND) + tpsLimit();
|
||||
return "§e" + BauSystem.MESSAGE.parse("SCOREBOARD_TPS", p) + "§8: " + tpsColor() + TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.ONE_SECOND) + tpsLimit();
|
||||
}
|
||||
}
|
||||
|
||||
private String tpsColor() {
|
||||
double tps = tpsSystem.getTPS(TPSWatcher.TPSType.ONE_SECOND);
|
||||
if (tps > tpsSystem.getCurrentTPSLimit() * 0.9) {
|
||||
double tps = TPSWatcher.getTPSUnlimited(TPSWatcher.TPSType.ONE_SECOND);
|
||||
if (tps > TPSSystem.getCurrentTPSLimit() * 0.9) {
|
||||
return "§a";
|
||||
}
|
||||
if (tps > tpsSystem.getCurrentTPSLimit() * 0.5) {
|
||||
if (tps > TPSSystem.getCurrentTPSLimit() * 0.5) {
|
||||
return "§e";
|
||||
}
|
||||
return "§c";
|
||||
}
|
||||
|
||||
private String tpsLimit() {
|
||||
if (tpsSystem.getCurrentTPSLimit() == 20) {
|
||||
if (TPSSystem.getCurrentTPSLimit() == 20) {
|
||||
return "";
|
||||
}
|
||||
return "§8/§7" + tpsSystem.getCurrentTPSLimit();
|
||||
return "§8/§7" + TPSSystem.getCurrentTPSLimit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -102,11 +102,14 @@ public class TraceRecorder implements Listener {
|
||||
*
|
||||
* @param region region to be recorded
|
||||
*/
|
||||
public void startRecording(Region region) {
|
||||
if (activeTraces.containsKey(region)) return;
|
||||
public Trace startRecording(Region region) {
|
||||
if (activeTraces.containsKey(region)) {
|
||||
return activeTraces.get(region).getTrace();
|
||||
}
|
||||
|
||||
TraceRecordingWrapper wrappedTrace = new TraceRecordingWrapper(region);
|
||||
activeTraces.put(region, wrappedTrace);
|
||||
return wrappedTrace.getTrace();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
package de.steamwar.bausystem.features.tracer.rendering;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.configplayer.Config;
|
||||
import de.steamwar.bausystem.features.tracer.TNTPoint;
|
||||
import de.steamwar.bausystem.features.tracer.Trace;
|
||||
import de.steamwar.bausystem.features.tracer.TraceManager;
|
||||
@@ -30,10 +31,13 @@ import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import yapion.hierarchy.types.YAPIONValue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static de.steamwar.bausystem.features.util.TNTClickListener.TNT_CLICK_DETAILS;
|
||||
|
||||
/**
|
||||
* Wrapper for the rendering of a record bundle
|
||||
*/
|
||||
@@ -66,6 +70,7 @@ public class TraceEntity extends RFallingBlockEntity {
|
||||
* @param player the player the message should be printed for
|
||||
*/
|
||||
public void printIntoChat(Player player) {
|
||||
if (!Config.getInstance().get(player).getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) return;
|
||||
TNTPoint representative = records.get(0);
|
||||
|
||||
BauSystem.MESSAGE.sendPrefixless("TNT_CLICK_HEADER", player);
|
||||
|
||||
@@ -42,6 +42,15 @@ public class SkullCommand extends SWCommand {
|
||||
super("skull", "head");
|
||||
}
|
||||
|
||||
@Register
|
||||
public void giveCommand(@Validator Player p) {
|
||||
if (p.getName().startsWith(".")) {
|
||||
BauSystem.MESSAGE.send("SKULL_INVALID", p);
|
||||
return;
|
||||
}
|
||||
giveCommand(p, p.getName());
|
||||
}
|
||||
|
||||
@Register(description = "SKULL_HELP")
|
||||
public void giveCommand(@Validator Player p, @Mapper("player") @ErrorMessage("SKULL_INVALID") String skull) {
|
||||
ItemStack is = SWItem.getPlayerSkull(skull).getItemStack();
|
||||
@@ -63,7 +72,7 @@ public class SkullCommand extends SWCommand {
|
||||
|
||||
@Override
|
||||
public List<String> tabCompletes(CommandSender commandSender, PreviousArguments previousArguments, String s) {
|
||||
return Bukkit.getOnlinePlayers().stream().map(Player::getName).filter(s1 -> !s1.endsWith("⍇")).collect(Collectors.toList());
|
||||
return Bukkit.getOnlinePlayers().stream().map(Player::getName).filter(s1 -> !s1.startsWith(".")).collect(Collectors.toList());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,22 +21,46 @@ package de.steamwar.bausystem.features.util;
|
||||
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.bausystem.configplayer.Config;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import yapion.hierarchy.types.YAPIONObject;
|
||||
import yapion.hierarchy.types.YAPIONValue;
|
||||
|
||||
@Linked
|
||||
public class TNTClickListener implements Listener {
|
||||
public class TNTClickListener extends SWCommand implements Listener {
|
||||
|
||||
public static final String TNT_CLICK_DETAILS = "tnt_click_details";
|
||||
|
||||
public TNTClickListener() {
|
||||
super("tntdetails");
|
||||
}
|
||||
|
||||
@Register(description = "TNT_DETAILS_COMMAND")
|
||||
public void toggle(Player player) {
|
||||
YAPIONObject yapionObject = Config.getInstance().get(player);
|
||||
if (yapionObject.getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) {
|
||||
yapionObject.put(TNT_CLICK_DETAILS, false);
|
||||
BauSystem.MESSAGE.send("TNT_DETAILS_OFF", player);
|
||||
} else {
|
||||
yapionObject.put(TNT_CLICK_DETAILS, true);
|
||||
BauSystem.MESSAGE.send("TNT_DETAILS_ON", player);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
if (!Permission.BUILD.hasPermission(event.getPlayer())) return;
|
||||
if (event.getHand() != EquipmentSlot.HAND) return;
|
||||
if (!Config.getInstance().get(event.getPlayer()).getOrSetDefault(TNT_CLICK_DETAILS, new YAPIONValue<>(true)).asBoolean().orElse(true)) return;
|
||||
|
||||
Entity entity = event.getRightClicked();
|
||||
if (event.getRightClicked() instanceof TNTPrimed) {
|
||||
|
||||
@@ -179,7 +179,12 @@ public class SpectatorListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
|
||||
if (event.getMessage().startsWith("/schem save") || event.getMessage().startsWith("//schem save") || event.getMessage().startsWith("/schematic save") || event.getMessage().startsWith("//schematic save")) {
|
||||
if (event.getMessage().startsWith("/schem save") ||
|
||||
event.getMessage().startsWith("//schem save") ||
|
||||
event.getMessage().startsWith("/schematic save") ||
|
||||
event.getMessage().startsWith("//schematic save") ||
|
||||
event.getMessage().startsWith("/download") ||
|
||||
event.getMessage().startsWith("//download")) {
|
||||
if (!Permission.SUPERVISOR.hasPermission(event.getPlayer())) {
|
||||
event.setCancelled(true);
|
||||
event.setMessage("/");
|
||||
|
||||
@@ -73,4 +73,8 @@ public class Point {
|
||||
public Location toLocation(Player player, double dx, double dy, double dz) {
|
||||
return new Location(player.getWorld(), x + dx, y + dy, z + dz, player.getLocation().getYaw(), player.getLocation().getPitch());
|
||||
}
|
||||
|
||||
public BlockVector3 toBlockVector3() {
|
||||
return BlockVector3.at(this.x, this.y, this.z);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
package de.steamwar.bausystem.utils.cursor;
|
||||
|
||||
import de.steamwar.bausystem.utils.RayTraceUtils;
|
||||
import de.steamwar.entity.REntity;
|
||||
import de.steamwar.entity.REntityServer;
|
||||
import de.steamwar.entity.RFallingBlockEntity;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.util.Vector;
|
||||
import yapion.hierarchy.types.YAPIONType;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@Getter
|
||||
public class RCursor {
|
||||
private final World WORLD = Bukkit.getWorlds().get(0);
|
||||
|
||||
private final REntityServer targetServer;
|
||||
private final REntityServer cursorServer;
|
||||
|
||||
private final Player owner;
|
||||
private final Material highlightMaterial;
|
||||
private final ClickHandler onClickHandler;
|
||||
|
||||
private RFallingBlockEntity cursorEntity;
|
||||
|
||||
private Location cursorLocation;
|
||||
private boolean isHittingEntity = false;
|
||||
|
||||
@Setter
|
||||
private Material cursorMaterial;
|
||||
@Setter
|
||||
private CursorMode cursorMode;
|
||||
private boolean visible = true;
|
||||
|
||||
|
||||
|
||||
public RCursor(REntityServer targetServer, Player owner, Material highlightMaterial, Material cursorMaterial, CursorMode cursorMode, ClickHandler onClickHandler) {
|
||||
this.targetServer = targetServer;
|
||||
this.owner = owner;
|
||||
this.highlightMaterial = highlightMaterial;
|
||||
this.cursorMaterial = cursorMaterial;
|
||||
this.cursorMode = cursorMode;
|
||||
this.onClickHandler = onClickHandler;
|
||||
|
||||
cursorServer = new REntityServer();
|
||||
cursorServer.addPlayer(owner);
|
||||
|
||||
RCursorManager.getInstance().registerCursor(this);
|
||||
}
|
||||
|
||||
public void render() {
|
||||
if (!visible) return;
|
||||
|
||||
RayTraceUtils.RRayTraceResult rayTraceResult = RayTraceUtils.traceREntity(owner, owner.getLocation(), targetServer.getEntities());
|
||||
if (rayTraceResult == null) {
|
||||
if(cursorEntity != null) cursorEntity.die();
|
||||
cursorEntity = null;
|
||||
return;
|
||||
}
|
||||
|
||||
REntity hitEntity = rayTraceResult.getHitEntity() == cursorEntity ? null : rayTraceResult.getHitEntity();
|
||||
|
||||
|
||||
Material activeCursorMaterial = hitEntity == null ? cursorMaterial : highlightMaterial;
|
||||
Location activeCursorLocation = hitEntity == null ? cursorMode.positionTransform.apply(owner, rayTraceResult).toLocation(WORLD)
|
||||
: new Vector(hitEntity.getX(), hitEntity.getY(), hitEntity.getZ()).toLocation(WORLD);
|
||||
|
||||
cursorLocation = activeCursorLocation;
|
||||
isHittingEntity = hitEntity != null;
|
||||
|
||||
if (cursorEntity == null) {
|
||||
cursorEntity = new RFallingBlockEntity(cursorServer, activeCursorLocation, activeCursorMaterial);
|
||||
cursorEntity.setNoGravity(true);
|
||||
} if (cursorEntity.getMaterial() == activeCursorMaterial) {
|
||||
cursorEntity.move(activeCursorLocation);
|
||||
} else {
|
||||
cursorEntity.die();
|
||||
cursorEntity = new RFallingBlockEntity(cursorServer, activeCursorLocation, activeCursorMaterial);
|
||||
cursorEntity.setNoGravity(true);
|
||||
if(activeCursorMaterial == highlightMaterial) {
|
||||
cursorEntity.setGlowing(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
visible = false;
|
||||
if (cursorEntity != null) {
|
||||
cursorEntity.die();
|
||||
cursorEntity = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void show() {
|
||||
visible = true;
|
||||
}
|
||||
|
||||
void handleClick(Action action) {
|
||||
if(!visible || cursorLocation == null) return;
|
||||
|
||||
onClickHandler.handle(cursorLocation, isHittingEntity, action);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
cursorServer.close();
|
||||
RCursorManager.getInstance().unregisterCursor(this);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public enum CursorMode {
|
||||
FREE((player, rayTraceResult) -> {
|
||||
Vector pos = rayTraceResult.getHitPosition();
|
||||
|
||||
BlockFace face = rayTraceResult.getHitBlockFace();
|
||||
if (face != null) {
|
||||
switch (face) {
|
||||
case DOWN:
|
||||
pos.setY(pos.getY() - 0.98);
|
||||
break;
|
||||
case EAST:
|
||||
pos.setX(pos.getX() + 0.49);
|
||||
break;
|
||||
case WEST:
|
||||
pos.setX(pos.getX() - 0.49);
|
||||
break;
|
||||
case NORTH:
|
||||
pos.setZ(pos.getZ() - 0.49);
|
||||
break;
|
||||
case SOUTH:
|
||||
pos.setZ(pos.getZ() + 0.49);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (face.getModY() == 0 && player.isSneaking()) {
|
||||
pos.setY(pos.getY() - 0.49);
|
||||
}
|
||||
}
|
||||
|
||||
if (!player.isSneaking()) {
|
||||
pos.setX(pos.getBlockX() + 0.5);
|
||||
if (face == null || face.getModY() == 0)
|
||||
pos.setY(pos.getBlockY() + 0.0);
|
||||
pos.setZ(pos.getBlockZ() + 0.5);
|
||||
}
|
||||
|
||||
return pos;
|
||||
}),
|
||||
BLOCK_ALIGNED((player, rayTraceResult) -> {
|
||||
Vector pos = rayTraceResult.getHitPosition();
|
||||
|
||||
BlockFace face = rayTraceResult.getHitBlockFace();
|
||||
if (face != null) {
|
||||
switch (face) {
|
||||
case DOWN:
|
||||
pos.setY(pos.getY() - 0.98);
|
||||
break;
|
||||
case EAST:
|
||||
pos.setX(pos.getX() + 0.49);
|
||||
break;
|
||||
case WEST:
|
||||
pos.setX(pos.getX() - 0.49);
|
||||
break;
|
||||
case NORTH:
|
||||
pos.setZ(pos.getZ() - 0.49);
|
||||
break;
|
||||
case SOUTH:
|
||||
pos.setZ(pos.getZ() + 0.49);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pos.setX(pos.getBlockX() + 0.5);
|
||||
if (pos.getY() - pos.getBlockY() != 0 && face == BlockFace.UP) {
|
||||
pos.setY(pos.getBlockY() + 1.0);
|
||||
} else {
|
||||
pos.setY(pos.getBlockY());
|
||||
}
|
||||
pos.setZ(pos.getBlockZ() + 0.5);
|
||||
return pos;
|
||||
});
|
||||
|
||||
|
||||
private final BiFunction<Player, RayTraceUtils.RRayTraceResult, Vector> positionTransform;
|
||||
}
|
||||
|
||||
public interface ClickHandler{
|
||||
public void handle(Location cursorLocation, boolean didHitEntity, Action action);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package de.steamwar.bausystem.utils.cursor;
|
||||
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.Reflection;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@Linked
|
||||
public class RCursorManager implements Listener {
|
||||
@Getter
|
||||
private static RCursorManager instance;
|
||||
|
||||
private final Set<Player> calculationActive = new HashSet<>();
|
||||
private final Map<Player, RCursor> activeCursors = new HashMap<>();
|
||||
|
||||
public RCursorManager() {
|
||||
if (instance == null) {
|
||||
instance = this;
|
||||
}
|
||||
|
||||
BiFunction<Player, Object, Object> function = (player, object) -> {
|
||||
updateCursor(player);
|
||||
return object;
|
||||
};
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
Set<Player> playersWithActiveCursor = activeCursors.keySet();
|
||||
|
||||
playersWithActiveCursor.forEach(this::updateCursor);
|
||||
}, 0);
|
||||
|
||||
Class<?> positionPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Pos");
|
||||
Class<?> lookPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$Rot");
|
||||
Class<?> positionLookPacketClass = Reflection.getClass("net.minecraft.network.protocol.game.ServerboundMovePlayerPacket$PosRot");
|
||||
|
||||
TinyProtocol.instance.addFilter(positionPacketClass, function);
|
||||
TinyProtocol.instance.addFilter(lookPacketClass, function);
|
||||
TinyProtocol.instance.addFilter(positionLookPacketClass, function);
|
||||
}
|
||||
|
||||
void registerCursor(RCursor cursor) {
|
||||
closeCursorOf(cursor.getOwner());
|
||||
|
||||
activeCursors.put(cursor.getOwner(), cursor);
|
||||
}
|
||||
|
||||
void unregisterCursor(RCursor cursor) {
|
||||
activeCursors.remove(cursor.getOwner());
|
||||
}
|
||||
|
||||
private void closeCursorOf(Player player) {
|
||||
RCursor currentPlayerCursor = activeCursors.get(player);
|
||||
|
||||
if(currentPlayerCursor != null) {
|
||||
currentPlayerCursor.close();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void updateCursor(Player player) {
|
||||
if (!activeCursors.containsKey(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (calculationActive) {
|
||||
if (calculationActive.contains(player)) {
|
||||
return;
|
||||
} else {
|
||||
calculationActive.add(player);
|
||||
}
|
||||
}
|
||||
|
||||
RCursor cursor = activeCursors.get(player);
|
||||
|
||||
if (cursor != null) {
|
||||
cursor.render();
|
||||
}
|
||||
|
||||
synchronized (calculationActive) {
|
||||
calculationActive.remove(player);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
private void handlePlayerInteract(PlayerInteractEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
RCursor cursorOfPlayer = activeCursors.get(player);
|
||||
|
||||
cursorOfPlayer.handleClick(event.getAction());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
private void handlePlayerQuit(PlayerQuitEvent event) {
|
||||
closeCursorOf(event.getPlayer());
|
||||
}
|
||||
}
|
||||
@@ -34,3 +34,19 @@ dependencies {
|
||||
implementation(project(":BauSystem:BauSystem_20"))
|
||||
implementation(project(":BauSystem:BauSystem_21"))
|
||||
}
|
||||
|
||||
tasks.register<DevServer>("DevBau20") {
|
||||
group = "run"
|
||||
description = "Run a 1.20 Dev Bau"
|
||||
dependsOn(":SpigotCore:shadowJar")
|
||||
dependsOn(":BauSystem:shadowJar")
|
||||
template = "Bau20"
|
||||
}
|
||||
|
||||
tasks.register<DevServer>("DevBau21") {
|
||||
group = "run"
|
||||
description = "Run a 1.21 Dev Bau"
|
||||
dependsOn(":SpigotCore:shadowJar")
|
||||
dependsOn(":BauSystem:shadowJar")
|
||||
template = "Bau21"
|
||||
}
|
||||
|
||||
@@ -200,21 +200,6 @@ function tnt.onlyTb() return nil end
|
||||
---@return boolean
|
||||
function tnt.onlyBuild() return nil end
|
||||
|
||||
---@class trace
|
||||
local trace = {}
|
||||
|
||||
---@return boolean
|
||||
function trace.active() return nil end
|
||||
|
||||
---@return boolean
|
||||
function trace.auto() return nil end
|
||||
|
||||
---@return string
|
||||
function trace.status() return nil end
|
||||
|
||||
---@return number
|
||||
function trace.time() return nil end
|
||||
|
||||
---@param name string
|
||||
---@return iregion
|
||||
function region.get(name) return nil end
|
||||
@@ -222,6 +207,25 @@ function region.get(name) return nil end
|
||||
---@return iregion[]
|
||||
function region.list() return nil end
|
||||
|
||||
---@class tracerLib
|
||||
tracer = {}
|
||||
|
||||
---@class TraceRecord
|
||||
---@field pos Position
|
||||
---@field vel Position
|
||||
---@field ticksSinceStart number
|
||||
---@field fuse number
|
||||
---@field isExplosion boolean
|
||||
---@field isInWater boolean
|
||||
---@field hasDestroyedBuild boolean
|
||||
---@field hasDestroyedTestblock boolean
|
||||
|
||||
---@class Tracer
|
||||
---@field getId fun(): string
|
||||
---@field getRecords fun(): {[number]: {[number]: TraceRecord}}
|
||||
|
||||
function tracer.getTraces() return nil end
|
||||
|
||||
---@class Position
|
||||
---@field x number
|
||||
---@field y number
|
||||
|
||||
@@ -31,10 +31,13 @@ public class SchematicNode {
|
||||
|
||||
static {
|
||||
SchematicType.Normal.name(); // Ensure SchematicType is loaded.
|
||||
new SqlTypeMapper<>(SchematicNode.class, null, (rs, identifier) -> { throw new SecurityException("SchematicNode cannot be used as type (recursive select)"); }, (st, index, value) -> st.setInt(index, value.nodeId));
|
||||
new SqlTypeMapper<>(SchematicNode.class, null, (rs, identifier) -> {
|
||||
throw new SecurityException("SchematicNode cannot be used as type (recursive select)");
|
||||
}, (st, index, value) -> st.setInt(index, value.nodeId));
|
||||
}
|
||||
|
||||
private static final Map<Integer, Map<String, List<String>>> TAB_CACHE = new HashMap<>();
|
||||
|
||||
public static void clear() {
|
||||
TAB_CACHE.clear();
|
||||
}
|
||||
@@ -42,39 +45,60 @@ public class SchematicNode {
|
||||
private static final String nodeSelector = "SELECT NodeId, NodeOwner, NodeOwner AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode ";
|
||||
|
||||
private static final Table<SchematicNode> table = new Table<>(SchematicNode.class);
|
||||
private static final Statement create = table.insertFields(true, "NodeOwner", "NodeName", "ParentNode", "NodeItem", "NodeType");
|
||||
private static final Statement update = table.update(Table.PRIMARY, "NodeName", "ParentNode", "NodeItem", "NodeType", "NodeRank", "ReplaceColor", "AllowReplay");
|
||||
private static final Statement create = table.insertFields(true, "NodeOwner", "NodeName", "ParentNode", "NodeItem",
|
||||
"NodeType");
|
||||
private static final Statement update = table.update(Table.PRIMARY, "NodeName", "ParentNode", "NodeItem",
|
||||
"NodeType", "NodeRank", "ReplaceColor", "AllowReplay");
|
||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||
|
||||
private static final SelectStatement<SchematicNode> byId = new SelectStatement<>(table, nodeSelector + "WHERE NodeId = ?");
|
||||
private static final SelectStatement<SchematicNode> byOwnerNameParent = new SelectStatement<>(table, nodeSelector + "WHERE NodeOwner = ? AND NodeName = ? AND ParentNode " + Statement.NULL_SAFE_EQUALS + "?");
|
||||
private static final SelectStatement<SchematicNode> byParent = new SelectStatement<>(table, nodeSelector + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> dirsByParent = new SelectStatement<>(table, nodeSelector + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? AND NodeType is NULL ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byOwnerType = new SelectStatement<>(table, nodeSelector + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byType = new SelectStatement<>(table, nodeSelector + "WHERE NodeType = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> all = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> list = new SelectStatement<>(table, "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId " + Statement.NULL_SAFE_EQUALS + "? AND NM.UserId = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE (? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?) ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byParentName = new SelectStatement<>(table, "SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId " + Statement.NULL_SAFE_EQUALS + "? AND NM.UserId = ? AND SchematicNode.NodeName = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE ((? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?)) AND NodeName = ?");
|
||||
private static final SelectStatement<SchematicNode> schematicAccessibleForUser = new SelectStatement<>(table, "SELECT COUNT(DISTINCT NodeId) FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND NodeId = ?");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUserTypeInParent = new SelectStatement<>(table, "WITH RECURSIVE RSASN AS(WITH RECURSIVE RSAN AS (WITH RSANH AS (WITH RECURSIVE RSA AS (SELECT SN.NodeId, NM.ParentId FROM SchematicNode SN LEFT JOIN NodeMember NM on SN.NodeId = NM.NodeId WHERE NM.UserId = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN INNER JOIN RSA ON RSA.NodeId = SN.ParentNode) SELECT * FROM RSA UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?) SELECT * FROM RSANH UNION SELECT SN.NodeId, SN.ParentNode FROM RSANH JOIN SchematicNode SN ON SN.ParentNode = RSANH.NodeId) SELECT RSAN.NodeId, RSAN.ParentId FROM RSAN JOIN SchematicNode SN ON SN.NodeId = RSAN.NodeId WHERE NodeType = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN JOIN RSASN ON SN.NodeId = RSASN.ParentId) SELECT SN.*, ? as EffectiveOwner, RSASN.ParentId AS ParentNode FROM RSASN JOIN SchematicNode SN ON SN.NodeId = RSASN.NodeId WHERE RSASN.ParentId" + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUserType = new SelectStatement<>(table, "WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE NodeType = ?");
|
||||
private static final SelectStatement<SchematicNode> byIdAndUser = new SelectStatement<>(table, "SELECT NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE NodeId = ?");
|
||||
private static final SelectStatement<SchematicNode> allParentsOfNode = new SelectStatement<>(table, "WITH RECURSIVE R AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeId = ? AND EffectiveOwner = ? UNION SELECT E.NodeId, E.ParentNode FROM R, EffectiveSchematicNode E WHERE R.ParentNode = E.NodeId AND E.EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, R.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank, SN.ReplaceColor, SN.AllowReplay FROM R INNER JOIN SchematicNode SN ON SN.NodeId = R.NodeId");
|
||||
private static final SelectStatement<SchematicNode> byId = new SelectStatement<>(table,
|
||||
nodeSelector + "WHERE NodeId = ?");
|
||||
private static final SelectStatement<SchematicNode> byOwnerNameParent = new SelectStatement<>(table,
|
||||
nodeSelector + "WHERE NodeOwner = ? AND NodeName = ? AND ParentNode " + Statement.NULL_SAFE_EQUALS + "?");
|
||||
private static final SelectStatement<SchematicNode> byParent = new SelectStatement<>(table,
|
||||
nodeSelector + "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> dirsByParent = new SelectStatement<>(table, nodeSelector
|
||||
+ "WHERE ParentNode" + Statement.NULL_SAFE_EQUALS + "? AND NodeType is NULL ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byOwnerType = new SelectStatement<>(table,
|
||||
nodeSelector + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byType = new SelectStatement<>(table,
|
||||
nodeSelector + "WHERE NodeType = ? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> all = new SelectStatement<>(table,
|
||||
"WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId");
|
||||
private static final SelectStatement<SchematicNode> list = new SelectStatement<>(table,
|
||||
"SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId "
|
||||
+ Statement.NULL_SAFE_EQUALS
|
||||
+ "? AND NM.UserId = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE (? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?) ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> byParentName = new SelectStatement<>(table,
|
||||
"SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, NM.ParentId AS ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode INNER JOIN NodeMember NM on SchematicNode.NodeId = NM.NodeId WHERE NM.ParentId "
|
||||
+ Statement.NULL_SAFE_EQUALS
|
||||
+ "? AND NM.UserId = ? AND SchematicNode.NodeName = ? UNION ALL SELECT SchematicNode.NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE ((? IS NULL AND ParentNode IS NULL AND NodeOwner = ?) OR (? IS NOT NULL AND ParentNode = ?)) AND NodeName = ?");
|
||||
private static final SelectStatement<SchematicNode> schematicAccessibleForUser = new SelectStatement<>(table,
|
||||
"WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE NodeId = ?");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUserTypeInParent = new SelectStatement<>(table,
|
||||
"WITH RECURSIVE RSASN AS(WITH RECURSIVE RSAN AS (WITH RSANH AS (WITH RECURSIVE RSA AS (SELECT SN.NodeId, NM.ParentId FROM SchematicNode SN LEFT JOIN NodeMember NM on SN.NodeId = NM.NodeId WHERE NM.UserId = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN INNER JOIN RSA ON RSA.NodeId = SN.ParentNode) SELECT * FROM RSA UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?) SELECT * FROM RSANH UNION SELECT SN.NodeId, SN.ParentNode FROM RSANH JOIN SchematicNode SN ON SN.ParentNode = RSANH.NodeId) SELECT RSAN.NodeId, RSAN.ParentId FROM RSAN JOIN SchematicNode SN ON SN.NodeId = RSAN.NodeId WHERE NodeType = ? UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN JOIN RSASN ON SN.NodeId = RSASN.ParentId) SELECT SN.*, ? as EffectiveOwner, RSASN.ParentId AS ParentNode FROM RSASN JOIN SchematicNode SN ON SN.NodeId = RSASN.NodeId WHERE RSASN.ParentId"
|
||||
+ Statement.NULL_SAFE_EQUALS + "? ORDER BY NodeName");
|
||||
private static final SelectStatement<SchematicNode> accessibleByUserType = new SelectStatement<>(table,
|
||||
"WITH RECURSIVE Nodes AS (SELECT NodeId, ParentId as ParentNode FROM NodeMember WHERE UserId = ? UNION SELECT NodeId, ParentNode FROM SchematicNode WHERE NodeOwner = ?), RSN AS ( SELECT NodeId, ParentNode FROM Nodes UNION SELECT SN.NodeId, SN.ParentNode FROM SchematicNode SN, RSN WHERE SN.ParentNode = RSN.NodeId ) SELECT SN.*, ? AS EffectiveOwner FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE NodeType = ?");
|
||||
private static final SelectStatement<SchematicNode> byIdAndUser = new SelectStatement<>(table,
|
||||
"SELECT NodeId, NodeOwner, ? AS EffectiveOwner, NodeName, ParentNode, LastUpdate, NodeItem, NodeType, NodeRank, ReplaceColor, AllowReplay FROM SchematicNode WHERE NodeId = ?");
|
||||
private static final SelectStatement<SchematicNode> allParentsOfNode = new SelectStatement<>(table,
|
||||
"WITH RECURSIVE R AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeId = ? AND EffectiveOwner = ? UNION SELECT E.NodeId, E.ParentNode FROM R, EffectiveSchematicNode E WHERE R.ParentNode = E.NodeId AND E.EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, R.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank, SN.ReplaceColor, SN.AllowReplay FROM R INNER JOIN SchematicNode SN ON SN.NodeId = R.NodeId");
|
||||
|
||||
static {
|
||||
NodeMember.init();
|
||||
}
|
||||
|
||||
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||
@Field(keys = { Table.PRIMARY }, autoincrement = true)
|
||||
private final int nodeId;
|
||||
@Field(keys = {"OwnerNameParent"})
|
||||
@Field(keys = { "OwnerNameParent" })
|
||||
private final int nodeOwner;
|
||||
@Field(def = "0")
|
||||
@Getter
|
||||
private final int effectiveOwner;
|
||||
@Field(keys = {"OwnerNameParent"})
|
||||
@Field(keys = { "OwnerNameParent" })
|
||||
private String nodeName;
|
||||
@Field(keys = {"OwnerNameParent"}, nullable = true)
|
||||
@Field(keys = { "OwnerNameParent" }, nullable = true)
|
||||
private Integer parentNode;
|
||||
@Field(def = "CURRENT_TIMESTAMP")
|
||||
private Timestamp lastUpdate;
|
||||
@@ -102,8 +126,7 @@ public class SchematicNode {
|
||||
SchematicType nodeType,
|
||||
int nodeRank,
|
||||
boolean replaceColor,
|
||||
boolean allowReplay
|
||||
) {
|
||||
boolean allowReplay) {
|
||||
this.nodeId = nodeId;
|
||||
this.nodeOwner = nodeOwner;
|
||||
this.effectiveOwner = effectiveOwner;
|
||||
@@ -118,7 +141,7 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAll(SteamwarUser user) {
|
||||
return all.listSelect(user);
|
||||
return all.listSelect(user, user, user);
|
||||
}
|
||||
|
||||
public static Map<Integer, List<SchematicNode>> getAllMap(SteamwarUser user) {
|
||||
@@ -130,7 +153,8 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public static SchematicNode byParentName(SteamwarUser user, Integer schematicId, String name) {
|
||||
return byParentName.select(user, schematicId, user, name, user, schematicId, user, schematicId, schematicId, name);
|
||||
return byParentName.select(user, schematicId, user, name, user, schematicId, user, schematicId, schematicId,
|
||||
name);
|
||||
}
|
||||
|
||||
public static List<SchematicNode> accessibleByUserType(SteamwarUser user, SchematicType type) {
|
||||
@@ -142,10 +166,11 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public static boolean schematicAccessibleForUser(SteamwarUser user, Integer schematicId) {
|
||||
return schematicAccessibleForUser.select(user, schematicId) != null;
|
||||
return schematicAccessibleForUser.select(user, user, user, schematicId) != null;
|
||||
}
|
||||
|
||||
public static List<SchematicNode> accessibleByUserTypeParent(SteamwarUser user, SchematicType type, Integer parentId) {
|
||||
public static List<SchematicNode> accessibleByUserTypeParent(SteamwarUser user, SchematicType type,
|
||||
Integer parentId) {
|
||||
return accessibleByUserTypeInParent.listSelect(user, user, type, user, parentId);
|
||||
}
|
||||
|
||||
@@ -160,7 +185,8 @@ public class SchematicNode {
|
||||
private static Map<Integer, List<SchematicNode>> map(List<SchematicNode> in) {
|
||||
Map<Integer, List<SchematicNode>> map = new HashMap<>();
|
||||
for (SchematicNode effectiveSchematicNode : in) {
|
||||
map.computeIfAbsent(effectiveSchematicNode.getOptionalParent().orElse(0), k -> new ArrayList<>()).add(effectiveSchematicNode);
|
||||
map.computeIfAbsent(effectiveSchematicNode.getOptionalParent().orElse(0), k -> new ArrayList<>())
|
||||
.add(effectiveSchematicNode);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
@@ -218,7 +244,8 @@ public class SchematicNode {
|
||||
return byId.select(id);
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent) {
|
||||
public static List<SchematicNode> getAccessibleSchematicsOfTypeInParent(int owner, String schemType,
|
||||
Integer parent) {
|
||||
return accessibleByUserTypeParent(SteamwarUser.get(owner), SchematicType.fromDB(schemType), parent);
|
||||
}
|
||||
|
||||
@@ -283,10 +310,12 @@ public class SchematicNode {
|
||||
}
|
||||
if (s.contains("/")) {
|
||||
String[] layers = s.split("/");
|
||||
Optional<SchematicNode> currentNode = Optional.ofNullable(SchematicNode.byParentName(user, null, layers[0]));
|
||||
Optional<SchematicNode> currentNode = Optional
|
||||
.ofNullable(SchematicNode.byParentName(user, null, layers[0]));
|
||||
for (int i = 1; i < layers.length; i++) {
|
||||
int finalI = i;
|
||||
Optional<SchematicNode> node = currentNode.map(effectiveSchematicNode -> SchematicNode.byParentName(user, effectiveSchematicNode.getId(), layers[finalI]));
|
||||
Optional<SchematicNode> node = currentNode.map(effectiveSchematicNode -> SchematicNode
|
||||
.byParentName(user, effectiveSchematicNode.getId(), layers[finalI]));
|
||||
if (!node.isPresent()) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -365,7 +394,7 @@ public class SchematicNode {
|
||||
|
||||
@Deprecated
|
||||
public void setType(String type) {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Node is Directory");
|
||||
this.nodeType = SchematicType.fromDB(type);
|
||||
updateDB();
|
||||
@@ -376,13 +405,13 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public String getFileEnding() {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Node is Directory");
|
||||
return NodeData.get(this).getNodeFormat().getFileEnding();
|
||||
}
|
||||
|
||||
public int getRank() {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Node is Directory");
|
||||
return nodeRank;
|
||||
}
|
||||
@@ -393,19 +422,19 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public void setRank(int rank) {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Node is Directory");
|
||||
this.nodeRank = rank;
|
||||
}
|
||||
|
||||
public SchematicType getSchemtype() {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Is Directory");
|
||||
return nodeType;
|
||||
}
|
||||
|
||||
public void setSchemtype(SchematicType type) {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Is Directory");
|
||||
this.nodeType = type;
|
||||
updateDB();
|
||||
@@ -416,7 +445,7 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public void setReplaceColor(boolean replaceColor) {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Is Directory");
|
||||
this.replaceColor = replaceColor;
|
||||
updateDB();
|
||||
@@ -427,14 +456,15 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public void setAllowReplay(boolean allowReplay) {
|
||||
if(isDir())
|
||||
if (isDir())
|
||||
throw new SecurityException("Is Directory");
|
||||
this.allowReplay = allowReplay;
|
||||
updateDB();
|
||||
}
|
||||
|
||||
public SchematicNode getParentNode() {
|
||||
if(parentNode == null) return null;
|
||||
if (parentNode == null)
|
||||
return null;
|
||||
return SchematicNode.getSchematicNode(parentNode);
|
||||
}
|
||||
|
||||
@@ -486,7 +516,7 @@ public class SchematicNode {
|
||||
}
|
||||
|
||||
public String generateBreadcrumbs() {
|
||||
if(brCache == null) {
|
||||
if (brCache == null) {
|
||||
brCache = generateBreadcrumbs("/");
|
||||
}
|
||||
return brCache;
|
||||
@@ -495,11 +525,15 @@ public class SchematicNode {
|
||||
public String generateBreadcrumbs(String split) {
|
||||
StringBuilder builder = new StringBuilder(getName());
|
||||
Optional<SchematicNode> currentNode = Optional.of(this);
|
||||
if(currentNode.map(SchematicNode::isDir).orElse(false)) {
|
||||
if (currentNode.map(SchematicNode::isDir).orElse(false)) {
|
||||
builder.append(split);
|
||||
}
|
||||
while (currentNode.isPresent()) {
|
||||
currentNode = currentNode.flatMap(schematicNode -> Optional.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner)).map(NodeMember::getParent).orElse(schematicNode.getOptionalParent())).map(SchematicNode::getSchematicNode);
|
||||
currentNode = currentNode
|
||||
.flatMap(schematicNode -> Optional
|
||||
.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner))
|
||||
.map(NodeMember::getParent).orElse(schematicNode.getOptionalParent()))
|
||||
.map(SchematicNode::getSchematicNode);
|
||||
currentNode.ifPresent(node -> builder.insert(0, split).insert(0, node.getName()));
|
||||
}
|
||||
return builder.toString();
|
||||
@@ -508,17 +542,22 @@ public class SchematicNode {
|
||||
public List<Map.Entry<String, Integer>> generateBreadcrumbsMap(SteamwarUser user) {
|
||||
List<Map.Entry<String, Integer>> map = new ArrayList<>();
|
||||
Optional<SchematicNode> currentNode = Optional.of(this);
|
||||
if(currentNode.map(SchematicNode::isDir).orElse(false)) {
|
||||
if (currentNode.map(SchematicNode::isDir).orElse(false)) {
|
||||
map.add(new AbstractMap.SimpleEntry<>(getName(), getId()));
|
||||
}
|
||||
while (currentNode.isPresent()) {
|
||||
currentNode = currentNode.flatMap(schematicNode -> Optional.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner)).map(NodeMember::getParent).orElse(schematicNode.getOptionalParent())).map(SchematicNode::getSchematicNode);
|
||||
currentNode = currentNode
|
||||
.flatMap(schematicNode -> Optional
|
||||
.ofNullable(NodeMember.getNodeMember(schematicNode.getId(), effectiveOwner))
|
||||
.map(NodeMember::getParent).orElse(schematicNode.getOptionalParent()))
|
||||
.map(SchematicNode::getSchematicNode);
|
||||
currentNode.ifPresent(node -> map.add(0, new AbstractMap.SimpleEntry<>(node.getName(), node.getId())));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private static final List<String> FORBIDDEN_NAMES = Collections.unmodifiableList(Arrays.asList("public"));
|
||||
|
||||
public static boolean invalidSchemName(String[] layers) {
|
||||
for (String layer : layers) {
|
||||
if (layer.isEmpty()) {
|
||||
@@ -535,7 +574,7 @@ public class SchematicNode {
|
||||
layer.contains(" ")) {
|
||||
return true;
|
||||
}
|
||||
if(FORBIDDEN_NAMES.contains(layer.toLowerCase())) {
|
||||
if (FORBIDDEN_NAMES.contains(layer.toLowerCase())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -549,14 +588,15 @@ public class SchematicNode {
|
||||
}
|
||||
int index = s.lastIndexOf("/");
|
||||
String cacheKey = index == -1 ? "" : s.substring(0, index);
|
||||
if(TAB_CACHE.containsKey(user.getId()) && TAB_CACHE.get(user.getId()).containsKey(cacheKey)) {
|
||||
if (TAB_CACHE.containsKey(user.getId()) && TAB_CACHE.get(user.getId()).containsKey(cacheKey)) {
|
||||
return new ArrayList<>(TAB_CACHE.get(user.getId()).get(cacheKey));
|
||||
}
|
||||
List<String> list = new ArrayList<>();
|
||||
if (s.contains("/")) {
|
||||
String preTab = s.substring(0, s.lastIndexOf("/") + 1);
|
||||
SchematicNode pa = SchematicNode.getNodeFromPath(user, preTab);
|
||||
if (pa == null) return new ArrayList<>();
|
||||
if (pa == null)
|
||||
return new ArrayList<>();
|
||||
List<SchematicNode> nodes = SchematicNode.list(user, pa.getId());
|
||||
String br = pa.generateBreadcrumbs();
|
||||
nodes.forEach(node -> list.add((sws ? "/" : "") + br + node.getName() + (node.isDir() ? "/" : "")));
|
||||
|
||||
@@ -75,15 +75,7 @@ public class UserElo {
|
||||
|
||||
public static void setElo(int userId, String gameMode, int elo) {
|
||||
emblemCache.remove(userId);
|
||||
|
||||
int oldPlacement = getPlacement(getElo(userId, gameMode).orElse(0), gameMode);
|
||||
int newPlacement = getPlacement(elo, gameMode);
|
||||
|
||||
gameModeUserEloCache.getOrDefault(gameMode, Collections.emptyMap()).remove(userId);
|
||||
if (oldPlacement <= 3 || newPlacement <= 3) {
|
||||
emblemCache.clear();
|
||||
}
|
||||
|
||||
setElo.update(Season.getSeason(), gameMode, userId, elo);
|
||||
}
|
||||
|
||||
@@ -112,27 +104,17 @@ public class UserElo {
|
||||
public static String getEmblemProgression(String gameMode, int userId) {
|
||||
switch (getProgression(userId, gameMode)) {
|
||||
case -1:
|
||||
return "§f/ §8∨ ∧ ∨ ∧ ∨ ∧ ❂ III II I";
|
||||
return "§8❱❱❱❱ ❂";
|
||||
case 0:
|
||||
return "§8/ §6∨ §8∧ ∨ ∧ ∨ ∧ ❂ III II I";
|
||||
return "§e❱§8❱❱❱ ❂";
|
||||
case 1:
|
||||
return "§8/ ∨ §6∧ §8∨ ∧ ∨ ∧ ❂ III II I";
|
||||
return "§e❱❱§8❱❱ ❂";
|
||||
case 2:
|
||||
return "§8/ ∨ ∧ §7∨ §8∧ ∨ ∧ ❂ III II I";
|
||||
return "§e❱❱❱§8❱ ❂";
|
||||
case 3:
|
||||
return "§8/ ∨ ∧ ∨ §7∧ §8∨ ∧ ❂ III II I";
|
||||
return "§e❱❱❱❱§8 ❂";
|
||||
case 4:
|
||||
return "§8/ ∨ ∧ ∨ ∧ §e∨ §8∧ ❂ III II I";
|
||||
case 5:
|
||||
return "§8/ ∨ ∧ ∨ ∧ ∨ §e∧ §8❂ III II I";
|
||||
case 6:
|
||||
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ §5❂ §8III II I";
|
||||
case 7:
|
||||
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ §5III §8II I";
|
||||
case 8:
|
||||
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ III §5II §8I";
|
||||
case 9:
|
||||
return "§8/ ∨ ∧ ∨ ∧ ∨ ∧ ❂ III II §5I";
|
||||
return "§8❱❱❱❱ §5❂";
|
||||
default:
|
||||
throw new SecurityException("Progression is not in range");
|
||||
}
|
||||
@@ -142,19 +124,11 @@ public class UserElo {
|
||||
int elo = getElo(userId, gameMode).orElse(-1);
|
||||
if (elo < 0) return -1;
|
||||
|
||||
if (elo <= 100) return 0;
|
||||
if (elo <= 200) return 1;
|
||||
if (elo <= 400) return 2;
|
||||
if (elo <= 600) return 3;
|
||||
if (elo <= 900) return 4;
|
||||
if (elo <= 1200) return 5;
|
||||
|
||||
int placement = getPlacement(elo, gameMode);
|
||||
if (placement == 1) return 9;
|
||||
if (placement == 2) return 8;
|
||||
if (placement == 3) return 7;
|
||||
|
||||
return 6;
|
||||
if (elo < 150) return 0;
|
||||
if (elo < 350) return 1;
|
||||
if (elo < 600) return 2;
|
||||
if (elo < 900) return 3;
|
||||
return 4;
|
||||
}
|
||||
|
||||
public static String toEmblem(int progression) {
|
||||
@@ -162,25 +136,15 @@ public class UserElo {
|
||||
case -1:
|
||||
return "";
|
||||
case 0:
|
||||
return "§6∨ ";
|
||||
return "§e❱ ";
|
||||
case 1:
|
||||
return "§6∧ ";
|
||||
return "§e❱❱ ";
|
||||
case 2:
|
||||
return "§7∨ ";
|
||||
return "§e❱❱❱ ";
|
||||
case 3:
|
||||
return "§7∧ ";
|
||||
return "§e❱❱❱❱ ";
|
||||
case 4:
|
||||
return "§e∨ ";
|
||||
case 5:
|
||||
return "§e∧ ";
|
||||
case 6:
|
||||
return "§5❂ ";
|
||||
case 7:
|
||||
return "§5III ";
|
||||
case 8:
|
||||
return "§5II ";
|
||||
case 9:
|
||||
return "§5I ";
|
||||
default:
|
||||
throw new SecurityException("Progression out of range");
|
||||
}
|
||||
|
||||
@@ -29,4 +29,5 @@ dependencies {
|
||||
compileOnly(libs.worldedit15)
|
||||
compileOnly(libs.fastutil)
|
||||
compileOnly(libs.authlib)
|
||||
compileOnly(libs.netty)
|
||||
}
|
||||
|
||||
@@ -97,6 +97,7 @@ public class FightSystem extends JavaPlugin {
|
||||
new PrepareSchem();
|
||||
new TestJoin();
|
||||
new NormalJoin();
|
||||
new Spectator();
|
||||
new RunningWorldInteraction();
|
||||
new PersonalKitCreator();
|
||||
new ArrowStopper();
|
||||
@@ -156,6 +157,7 @@ public class FightSystem extends JavaPlugin {
|
||||
new LockschemCommand();
|
||||
new StateCommand();
|
||||
new SkipCommand();
|
||||
new TechhiderbugCommand();
|
||||
new TPSWarpCommand();
|
||||
new UnrankCommand();
|
||||
new WinCommand();
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.commands;
|
||||
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.fight.Fight;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependentCommand;
|
||||
import de.steamwar.sql.SWException;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class TechhiderbugCommand implements CommandExecutor {
|
||||
|
||||
public TechhiderbugCommand() {
|
||||
new StateDependentCommand(ArenaMode.All, FightState.All, "techhiderbug", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmd, String alias, String[] args) {
|
||||
StringWriter writer = new StringWriter();
|
||||
|
||||
try {
|
||||
writer.append("ArenaMode: ").append(Config.mode.name()).append('\n');
|
||||
writer.append("FightState: ").append(FightState.getFightState().name()).append('\n');
|
||||
writer.append("TechHider enabled: ").append(FightState.getStateDependentFeatures().get(FightSystem.getTechHider()).toString()).append('\n');
|
||||
|
||||
writer.append("Arena region: ").append(Config.ArenaRegion.toString()).append('\n');
|
||||
writer.append("Team regions: ");
|
||||
Fight.teams().forEach(t -> writer.append(t.getName()).append(':').append(t.getExtendRegion().toString()).append(' '));
|
||||
writer.append('\n');
|
||||
|
||||
writer.append("HullHider regions: ");
|
||||
FightSystem.getHullHider().getHullMap().forEach((t, h) -> writer.append(t.getName()).append(':').append(h.getRegion().toString()).append(' '));
|
||||
writer.append('\n');
|
||||
|
||||
writer.append("Hidden regions: ");
|
||||
FightSystem.getTechHider().getHiddenRegion().forEach((p, r) -> writer.append(p.getName()).append(':').append(r.toString()).append(' '));
|
||||
writer.append('\n');
|
||||
|
||||
writer.append("TinyProtocol: ");
|
||||
writer.append(TinyProtocol.instance.toString()).append('\n');
|
||||
|
||||
writer.append('\n').append("Netty pipelines:\n");
|
||||
Bukkit.getOnlinePlayers().forEach(p -> writer.append(p.getName()).append(": ").append(String.join(" ", TinyProtocol.instance.getPlayerInterceptors().get(p).getChannel().pipeline().names())).append('\n'));
|
||||
} catch (Exception e) {
|
||||
writer.append("Error while generating bug report: ").append(e.getMessage()).append('\n');
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Error while generating bug report", e);
|
||||
}
|
||||
|
||||
SWException.log("Techhider-Bug reported by " + sender.getName() + ": " + Arrays.toString(args), writer.toString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -104,40 +104,6 @@ public class Fight {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void setPlayerGamemode(Player player, GameMode gameMode) {
|
||||
player.setGameMode(gameMode);
|
||||
|
||||
if(gameMode == GameMode.SPECTATOR) {
|
||||
for(Player currentPlayer : Bukkit.getServer().getOnlinePlayers()) {
|
||||
if(currentPlayer.getUniqueId() != player.getUniqueId() && currentPlayer.getGameMode() == GameMode.SPECTATOR) {
|
||||
currentPlayer.hidePlayer(player);
|
||||
player.hidePlayer(currentPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
if(Config.test() || Config.isReferee(player))
|
||||
return;
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
|
||||
if(!player.isOnline())
|
||||
return;
|
||||
pseudoSpectator(player, true);
|
||||
}, 1);
|
||||
}else if(gameMode == GameMode.SURVIVAL) {
|
||||
for(Player currentPlayer : Bukkit.getServer().getOnlinePlayers()) {
|
||||
if(currentPlayer.getUniqueId() != player.getUniqueId() && currentPlayer.getGameMode() == GameMode.SPECTATOR) {
|
||||
currentPlayer.showPlayer(player);
|
||||
player.showPlayer(currentPlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void pseudoSpectator(Player player, boolean enable) {
|
||||
TinyProtocol.instance.sendPacket(player, ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.GAMEMODE, new GameProfile(player.getUniqueId(), player.getName()), enable ? GameMode.CREATIVE : GameMode.SPECTATOR));
|
||||
}
|
||||
|
||||
public static boolean publicOnly() {
|
||||
if (Config.OnlyPublicSchematics) {
|
||||
return true;
|
||||
|
||||
@@ -73,7 +73,6 @@ public class FightTeam {
|
||||
|
||||
if(ArenaMode.VariableTeams.contains(Config.mode)){
|
||||
notReadyKit.setItem(2, "REQUESTS", new ItemBuilder(Material.PAPER).build(), GUI::chooseJoinRequests);
|
||||
notReadyKit.setItem(3, "MANAGE_PLAYERS", SWItem.getPlayerSkull("AdmiralSeekrank").getItemStack(), GUI::managePlayers);
|
||||
if(!AIManager.availableAIs().isEmpty())
|
||||
notReadyKit.setItem(6, "ADD_AI", new ItemBuilder(Material.REDSTONE).build(), GUI::addAI);
|
||||
}
|
||||
@@ -81,6 +80,7 @@ public class FightTeam {
|
||||
if(Config.test())
|
||||
notReadyKit.setItem(5, "CHOOSE_SCHEMATIC", new ItemBuilder(SWItem.getMaterial("CAULDRON_ITEM")).enchant().build(), GUI::preSchemDialog);
|
||||
|
||||
notReadyKit.setItem(3, "MANAGE_PLAYERS", SWItem.getPlayerSkull("AdmiralSeekrank").getItemStack(), GUI::managePlayers);
|
||||
notReadyKit.setItem(4, "TEAM_NOT_READY", new ItemBuilder(SWItem.getDye(10), (short) 10).enchant().build(), player -> Objects.requireNonNull(Fight.getPlayerTeam(player)).setReady(true));
|
||||
}
|
||||
private static final HotbarKit chooseSchemKit = new HotbarKit(notReadyKit);
|
||||
@@ -282,9 +282,9 @@ public class FightTeam {
|
||||
FightSystem.getHullHider().updatePlayer(player);
|
||||
|
||||
if(FightState.Spectate.contains(FightState.getFightState())) {
|
||||
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
} else {
|
||||
Fight.setPlayerGamemode(player, GameMode.SURVIVAL);
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
(FightState.ingame() ? fightPlayer.getKit() : memberKit).loadToPlayer(player);
|
||||
}
|
||||
});
|
||||
@@ -317,7 +317,7 @@ public class FightTeam {
|
||||
entity.teleport(Config.SpecSpawn);
|
||||
|
||||
fightPlayer.ifPlayer(player -> {
|
||||
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
player.getInventory().clear();
|
||||
|
||||
if(player.isOnline()){
|
||||
@@ -517,14 +517,14 @@ public class FightTeam {
|
||||
@Override
|
||||
public void enable() {
|
||||
players.values().forEach(fightPlayer -> {
|
||||
fightPlayer.ifPlayer(player -> Fight.setPlayerGamemode(player, GameMode.SPECTATOR));
|
||||
fightPlayer.ifPlayer(player -> player.setGameMode(GameMode.SPECTATOR));
|
||||
fightPlayer.getEntity().teleport(FightTeam.this.spawn);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
players.values().forEach(fightPlayer -> fightPlayer.ifPlayer(player -> Fight.setPlayerGamemode(player, GameMode.SURVIVAL)));
|
||||
players.values().forEach(fightPlayer -> fightPlayer.ifPlayer(player -> player.setGameMode(GameMode.SURVIVAL)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,11 +29,15 @@ import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||
import de.steamwar.fightsystem.utils.ItemBuilder;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryOpenEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -107,6 +111,19 @@ public class HotbarKit extends Kit {
|
||||
|
||||
Player player = event.getPlayer();
|
||||
int slot = player.getInventory().getHeldItemSlot();
|
||||
click(player, slot, event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
int slot = event.getSlot();
|
||||
if (slot < 0 || slot >= HOTBAR_SIZE) return;
|
||||
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
click(player, slot, event);
|
||||
}
|
||||
|
||||
private void click(Player player, int slot, Cancellable event) {
|
||||
Kit activeKit = activeKits.get(player);
|
||||
if(!(activeKit instanceof HotbarKit) || PersonalKitCreator.inKitCreator(player) || activeKit.getInventory()[slot] == null)
|
||||
return;
|
||||
|
||||
@@ -84,6 +84,6 @@ public class LeaveableArena implements Listener {
|
||||
|
||||
private void markInArena(Player player) {
|
||||
spectatorsInArena.put(player, player.getGameMode());
|
||||
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ public class Permanent implements Listener {
|
||||
public void handlePlayerRespawn(PlayerRespawnEvent event){
|
||||
Player player = event.getPlayer();
|
||||
if(Fight.fighting(player)) {
|
||||
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
|
||||
FightTeam team = Fight.getPlayerTeam(player);
|
||||
event.setRespawnLocation(team == null ? Config.SpecSpawn : team.getSpawn());
|
||||
@@ -98,11 +98,11 @@ public class Permanent implements Listener {
|
||||
FightPlayer fp = Fight.getFightPlayer(player);
|
||||
|
||||
if (!Config.ArenaLeaveable && fp == null) {
|
||||
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
spectatorTeam.addEntry(player.getName());
|
||||
player.teleport(Config.SpecSpawn);
|
||||
} else if(fp != null && !fp.isLiving()) {
|
||||
Fight.setPlayerGamemode(player, GameMode.SPECTATOR);
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
player.teleport(fp.getTeam().getSpawn());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2025 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.fightsystem.listener;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerGameModeChangeEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
|
||||
import de.steamwar.core.ProtocolWrapper;
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.fight.Fight;
|
||||
import de.steamwar.fightsystem.fight.FightPlayer;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||
|
||||
|
||||
public class Spectator implements Listener {
|
||||
|
||||
private final Set<Player> pseudoSpectator = new HashSet<>();
|
||||
|
||||
public Spectator() {
|
||||
new StateDependentListener(ArenaMode.AntiTest, FightState.All, this);
|
||||
new StateDependentTask(ArenaMode.AntiTest, FightState.All, this::pseudoSpectatorCheck, 1, 1);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void handlePlayerJoin(PlayerJoinEvent e) {
|
||||
Player player = e.getPlayer();
|
||||
|
||||
if(player.getGameMode() == GameMode.SPECTATOR)
|
||||
gameModeChange(player, GameMode.SPECTATOR);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onGameModeChange(PlayerGameModeChangeEvent e) {
|
||||
gameModeChange(e.getPlayer(), e.getNewGameMode());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void gameModeChange(Player player, GameMode gameMode) {
|
||||
if (gameMode == GameMode.SPECTATOR) {
|
||||
for(Player p : Bukkit.getServer().getOnlinePlayers()) {
|
||||
if(p.getUniqueId() != player.getUniqueId())
|
||||
p.hidePlayer(player);
|
||||
}
|
||||
} else {
|
||||
for(Player p : Bukkit.getServer().getOnlinePlayers()) {
|
||||
if(p.getUniqueId() != player.getUniqueId())
|
||||
p.showPlayer(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void playerQuit(PlayerQuitEvent e) {
|
||||
pseudoSpectator.remove(e.getPlayer());
|
||||
}
|
||||
|
||||
private void pseudoSpectatorCheck() {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (player.getGameMode() != GameMode.SPECTATOR) {
|
||||
pseudoSpectator.remove(player);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Config.isReferee(player))
|
||||
continue;
|
||||
|
||||
FightPlayer fightPlayer = Fight.getFightPlayer(player);
|
||||
if (fightPlayer == null || !fightPlayer.getTeam().getExtendRegion().playerInRegion(player.getLocation())) {
|
||||
if (pseudoSpectator.add(player))
|
||||
pseudoSpectator(player, true);
|
||||
} else {
|
||||
if (pseudoSpectator.remove(player))
|
||||
pseudoSpectator(player, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void pseudoSpectator(Player player, boolean enable) {
|
||||
TinyProtocol.instance.sendPacket(player, ProtocolWrapper.impl.playerInfoPacketConstructor(ProtocolWrapper.PlayerInfoAction.GAMEMODE, new GameProfile(player.getUniqueId(), player.getName()), enable ? GameMode.CREATIVE : GameMode.SPECTATOR));
|
||||
}
|
||||
}
|
||||
@@ -19,9 +19,14 @@
|
||||
|
||||
package de.steamwar.fightsystem.listener;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import de.steamwar.fightsystem.ArenaMode;
|
||||
import de.steamwar.fightsystem.Config;
|
||||
import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.events.BoardingEvent;
|
||||
import de.steamwar.fightsystem.events.TeamDeathEvent;
|
||||
import de.steamwar.fightsystem.events.TeamLeaveEvent;
|
||||
@@ -32,23 +37,12 @@ import de.steamwar.fightsystem.fight.FightTeam;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import de.steamwar.fightsystem.states.OneShotStateDependent;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class TeamArea implements Listener {
|
||||
|
||||
private final FightTeam team;
|
||||
private final Border spectatorBorder;
|
||||
private final Border bordingBorder;
|
||||
private final Set<Player> realSpectator = new HashSet<>();
|
||||
|
||||
public TeamArea(FightTeam team) {
|
||||
this.team = team;
|
||||
@@ -56,7 +50,6 @@ public class TeamArea implements Listener {
|
||||
this.bordingBorder = new Border(team.getExtendRegion().to2d(), true, 1, "NO_ENTERN", team.getName() + ".boardingBorder");
|
||||
|
||||
new StateDependentListener(ArenaMode.AntiTest, FightState.All, this);
|
||||
new StateDependentTask(ArenaMode.AntiTest, FightState.TeamFix, this::realSpectatorCheck, 1, 1);
|
||||
new OneShotStateDependent(ArenaMode.AntiTest, FightState.Spectate, () -> Fight.teams().forEach(t -> t.getPlayers().forEach(this::teamSpectator)));
|
||||
}
|
||||
|
||||
@@ -114,30 +107,5 @@ public class TeamArea implements Listener {
|
||||
Player player = e.getPlayer();
|
||||
spectatorBorder.removePlayer(player);
|
||||
bordingBorder.removePlayer(player);
|
||||
realSpectator.remove(player);
|
||||
}
|
||||
|
||||
private void realSpectatorCheck() {
|
||||
for(FightPlayer fightPlayer : team.getPlayers()) {
|
||||
if(fightPlayer.isLiving())
|
||||
continue;
|
||||
|
||||
fightPlayer.ifPlayer(player -> {
|
||||
boolean inRegion = team.getExtendRegion().playerInRegion(player.getLocation());
|
||||
if(inRegion && !realSpectator.contains(player)) {
|
||||
realSpectator.add(player);
|
||||
|
||||
//Later to prevent race condition with Fight.setSpecatator() during respawn
|
||||
Bukkit.getScheduler().runTaskLater(FightSystem.getPlugin(), () -> {
|
||||
if(!player.isOnline())
|
||||
return;
|
||||
Fight.pseudoSpectator(player, false);
|
||||
}, 2);
|
||||
}else if(!inRegion && realSpectator.contains(player)) {
|
||||
Fight.pseudoSpectator(player, true);
|
||||
realSpectator.remove(player);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ public enum FightState {
|
||||
public static final Set<FightState> AntiIngame = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(PRE_RUNNING, RUNNING)));
|
||||
public static final Set<FightState> AntiSpectate = Collections.unmodifiableSet(EnumSet.complementOf(EnumSet.of(SPECTATE)));
|
||||
|
||||
@Getter
|
||||
private static final Map<IStateDependent, Boolean> stateDependentFeatures = new HashMap<>();
|
||||
@Getter
|
||||
private static FightState fightState = PRE_LEADER_SETUP;
|
||||
|
||||
@@ -45,6 +45,7 @@ public class Hull {
|
||||
return material.isOccluding() || Config.HiddenBlocks.contains(material);
|
||||
}
|
||||
|
||||
@Getter
|
||||
private final Region region;
|
||||
private final boolean groundVisible;
|
||||
private final IntVector[] directions;
|
||||
|
||||
@@ -33,6 +33,7 @@ import de.steamwar.fightsystem.states.StateDependent;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import de.steamwar.fightsystem.states.StateDependentTask;
|
||||
import de.steamwar.techhider.TechHider;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@@ -56,6 +57,7 @@ import java.util.function.Function;
|
||||
|
||||
public class HullHider implements Listener {
|
||||
|
||||
@Getter
|
||||
private final Map<FightTeam, Hull> hullMap = new HashMap<>();
|
||||
private final Hull[] hulls;
|
||||
private final Map<Class<?>, BiFunction<Player, Object, Object>> packetHiders = new HashMap<>();
|
||||
|
||||
@@ -159,4 +159,9 @@ public class Region {
|
||||
public interface TriConsumer<T, V, U>{
|
||||
void accept(T x, V y, U z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return minX + "," + minY + "," + minZ + "->" + maxX + "," + maxY + "," + maxZ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import de.steamwar.fightsystem.states.StateDependent;
|
||||
import de.steamwar.fightsystem.states.StateDependentListener;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import de.steamwar.techhider.TechHider;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -51,6 +52,7 @@ public class TechHiderWrapper extends StateDependent implements TechHider.Locati
|
||||
|
||||
public static final boolean ENABLED = !Config.OnlyPublicSchematics && !Config.test() && Config.TechhiderActive;
|
||||
|
||||
@Getter
|
||||
private final ConcurrentHashMap<Player, Region> hiddenRegion = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<Player, Long> patterns = new ConcurrentHashMap<>();
|
||||
private final TechHider techHider;
|
||||
|
||||
@@ -27,4 +27,5 @@ commands:
|
||||
resettb:
|
||||
tpslimit:
|
||||
tpswarp:
|
||||
techhiderbug:
|
||||
unrank:
|
||||
@@ -39,3 +39,13 @@ dependencies {
|
||||
implementation(project(":FightSystem:FightSystem_20"))
|
||||
implementation(project(":FightSystem:FightSystem_21"))
|
||||
}
|
||||
|
||||
tasks.register<FightServer>("WarGear20") {
|
||||
group = "run"
|
||||
description = "Run a WarGear 1.20 Fight Server"
|
||||
dependsOn(":SpigotCore:shadowJar")
|
||||
dependsOn(":FightSystem:shadowJar")
|
||||
template = "WarGear20"
|
||||
worldName = "arenas/Pentraki"
|
||||
config = "WarGear20.yml"
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ public class JumpAndRun extends BasicListener {
|
||||
|
||||
int count = CLICKED_COUNT.getOrDefault(player, -1);
|
||||
if (count >= 0) {
|
||||
if (count > 60) {
|
||||
if (count > 20) {
|
||||
toReset.add(player);
|
||||
return;
|
||||
}
|
||||
@@ -104,12 +104,18 @@ public class JumpAndRun extends BasicListener {
|
||||
return;
|
||||
}
|
||||
Vector point = points.get(index);
|
||||
if (location.getY() < point.getY()) {
|
||||
return;
|
||||
}
|
||||
if (location.toVector().distanceSquared(point) >= 12.25) {
|
||||
if (location.getY() < point.getY()) index = -2;
|
||||
if (location.toVector().distanceSquared(point) >= 17) index = -2;
|
||||
if (index > 0 && index < points.size() - 1) {
|
||||
Vector nextPoint = points.get(index + 1);
|
||||
if (location.getY() >= nextPoint.getY() && location.toVector().distanceSquared(nextPoint) < 17) {
|
||||
index = index + 1;
|
||||
}
|
||||
}
|
||||
if (index == -2) {
|
||||
return;
|
||||
}
|
||||
|
||||
CURRENT_POS.put(event.getPlayer(), index);
|
||||
event.getPlayer().playSound(event.getPlayer().getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 0.4F, 1);
|
||||
if (index < points.size() - 1) {
|
||||
|
||||
@@ -184,6 +184,7 @@ public class MWTeam {
|
||||
|
||||
public void leave(Player p) {
|
||||
if (!players.contains(p)) return;
|
||||
players.remove(p);
|
||||
|
||||
for (ItemStack stack : p.getInventory().getContents()) {
|
||||
if (stack == null) continue;
|
||||
@@ -198,7 +199,6 @@ public class MWTeam {
|
||||
if (players.isEmpty() && MissileWars.getFightState() == FightState.FIGHTING)
|
||||
MissileWars.end(WinReasons.NO_ENEMY, enemy());
|
||||
|
||||
players.remove(p);
|
||||
sbteam.removePlayer(p);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@ public class DownloadCommand extends SWCommand {
|
||||
@Register(help = true)
|
||||
public void genericCommand(Player player, String... args) {
|
||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||
SchematicNode copyNode = SchematicNode.getSchematicNode(user.getId(), "//copy", 0);
|
||||
SchematicNode copyNode = SchematicNode.getSchematicNode(user.getId(), "//copy", (Integer) null);
|
||||
boolean newSchem = false;
|
||||
if(copyNode == null) {
|
||||
copyNode = SchematicNode.createSchematicNode(user.getId(), "//copy", 0, SchematicType.Normal.toDB(), "");
|
||||
if (copyNode == null) {
|
||||
copyNode = SchematicNode.createSchematicNode(user.getId(), "//copy", null, SchematicType.Normal.toDB(), "");
|
||||
newSchem = true;
|
||||
}
|
||||
|
||||
@@ -46,13 +46,13 @@ public class DownloadCommand extends SWCommand {
|
||||
new SchematicData(copyNode).saveFromPlayer(player);
|
||||
} catch (IOException e) {
|
||||
SchematicSystem.MESSAGE.send("DOWNLOAD_ERROR", player);
|
||||
if(newSchem) {
|
||||
if (newSchem) {
|
||||
copyNode.delete();
|
||||
}
|
||||
throw new SecurityException(e);
|
||||
} catch (NoClipboardException e) {
|
||||
SchematicSystem.MESSAGE.send("COMMAND_SAVE_CLIPBOARD_EMPTY", player);
|
||||
if(newSchem) {
|
||||
if (newSchem) {
|
||||
copyNode.delete();
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -66,8 +66,8 @@ public class BlockIds14 implements BlockIds {
|
||||
return getBlock.invoke(null, material);
|
||||
}
|
||||
|
||||
private static final Reflection.Method getCombinedId = Reflection.getTypedMethod(TechHider.block, null, int.class, TechHider.iBlockData);
|
||||
private int getCombinedId(Object blockData) {
|
||||
@Override
|
||||
public int getCombinedId(Object blockData) {
|
||||
return (int) getCombinedId.invoke(null, blockData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,12 @@ import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
public class BlockIds8 implements BlockIds {
|
||||
@Override
|
||||
public int getCombinedId(Object iBlockData) {
|
||||
int id = (int) getCombinedId.invoke(null, iBlockData); // blockState << 12 | blockId
|
||||
return (id & 4095) | (id >> 12);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public int materialToId(Material material) {
|
||||
|
||||
@@ -23,6 +23,7 @@ import de.steamwar.Reflection;
|
||||
import de.steamwar.Reflection.Field;
|
||||
import de.steamwar.core.Core;
|
||||
import io.netty.channel.*;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@@ -67,8 +68,20 @@ public class TinyProtocol implements Listener {
|
||||
private boolean closed;
|
||||
|
||||
private final Map<Class<?>, List<BiFunction<Player, Object, Object>>> packetFilters = new HashMap<>();
|
||||
@Getter
|
||||
private final Map<Player, PacketInterceptor> playerInterceptors = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TinyProtocol{" +
|
||||
"plugin=" + plugin +
|
||||
", connections=" + connections +
|
||||
", closed=" + closed +
|
||||
", packetFilters=" + packetFilters +
|
||||
", playerInterceptors=" + playerInterceptors +
|
||||
'}';
|
||||
}
|
||||
|
||||
private TinyProtocol(final Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.connections = networkManagers.get(getServerConnection(plugin));
|
||||
@@ -82,6 +95,7 @@ public class TinyProtocol implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerLogin(PlayerLoginEvent e) {
|
||||
plugin.getLogger().info("Creating PacketInterceptor for: " + e.getPlayer().getName() + " (" + closed + ")");
|
||||
if(closed)
|
||||
return;
|
||||
new PacketInterceptor(e.getPlayer());
|
||||
@@ -116,6 +130,8 @@ public class TinyProtocol implements Listener {
|
||||
}
|
||||
|
||||
public final void close() {
|
||||
plugin.getLogger().log(Level.INFO, "Closing PacketInterceptor", new Exception("Stacktrace"));
|
||||
|
||||
if(closed)
|
||||
return;
|
||||
closed = true;
|
||||
@@ -136,8 +152,9 @@ public class TinyProtocol implements Listener {
|
||||
private static final Field<Channel> getChannel = Reflection.getField(networkManager, Channel.class, 0);
|
||||
private static final Field<UUID> getUUID = Reflection.getField(networkManager, UUID.class, 0);
|
||||
|
||||
private final class PacketInterceptor extends ChannelDuplexHandler {
|
||||
public final class PacketInterceptor extends ChannelDuplexHandler {
|
||||
private final Player player;
|
||||
@Getter
|
||||
private final Channel channel;
|
||||
|
||||
private PacketInterceptor(Player player) {
|
||||
@@ -154,6 +171,7 @@ public class TinyProtocol implements Listener {
|
||||
synchronized (playerInterceptors) {
|
||||
playerInterceptors.put(player, this);
|
||||
}
|
||||
plugin.getLogger().info("Adding Techhider for: " + player.getName());
|
||||
|
||||
try {
|
||||
channel.pipeline().addBefore("packet_handler", HANDLER_NAME, this);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
package de.steamwar.techhider;
|
||||
|
||||
import de.steamwar.Reflection;
|
||||
import de.steamwar.core.Core;
|
||||
import de.steamwar.core.VersionDependent;
|
||||
import org.bukkit.Material;
|
||||
@@ -28,6 +29,9 @@ import java.util.Set;
|
||||
public interface BlockIds {
|
||||
BlockIds impl = VersionDependent.getVersionImpl(Core.getInstance());
|
||||
|
||||
Reflection.Method getCombinedId = Reflection.getTypedMethod(TechHider.block, null, int.class, TechHider.iBlockData);
|
||||
|
||||
int getCombinedId(Object iBlockData);
|
||||
int materialToId(Material material);
|
||||
Set<Integer> materialToAllIds(Material material);
|
||||
}
|
||||
|
||||
@@ -49,10 +49,8 @@ public class TechHider {
|
||||
public static final Class<?> craftMagicNumbers = Reflection.getClass("org.bukkit.craftbukkit.util.CraftMagicNumbers");
|
||||
private static final Reflection.Method getBlockByMaterial = Reflection.getTypedMethod(craftMagicNumbers, "getBlock", block, Material.class);
|
||||
|
||||
private static final Reflection.Method getBlockByBlockData = Reflection.getTypedMethod(iBlockData, null, block);
|
||||
private static final Reflection.Method getMaterialByBlock = Reflection.getTypedMethod(craftMagicNumbers, "getMaterial", Material.class, block);
|
||||
public boolean iBlockDataHidden(Object iBlockData) {
|
||||
return obfuscate.contains((Material) getMaterialByBlock.invoke(null, getBlockByBlockData.invoke(iBlockData)));
|
||||
return obfuscateIds.contains(BlockIds.impl.getCombinedId(iBlockData));
|
||||
}
|
||||
|
||||
public static final Object AIR = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, Material.AIR));
|
||||
@@ -66,15 +64,12 @@ public class TechHider {
|
||||
@Getter
|
||||
private final int obfuscationTargetId;
|
||||
@Getter
|
||||
private final Set<Material> obfuscate;
|
||||
@Getter
|
||||
private final Set<Integer> obfuscateIds;
|
||||
@Getter
|
||||
private final Set<String> hiddenBlockEntities;
|
||||
|
||||
public TechHider(LocationEvaluator locationEvaluator, Material obfuscationTarget, Set<Material> obfuscate, Set<String> hiddenBlockEntities) {
|
||||
this.locationEvaluator = locationEvaluator;
|
||||
this.obfuscate = obfuscate;
|
||||
this.obfuscateIds = obfuscate.stream().flatMap(m -> BlockIds.impl.materialToAllIds(m).stream()).collect(Collectors.toSet());
|
||||
this.hiddenBlockEntities = hiddenBlockEntities;
|
||||
this.obfuscationTarget = getBlockDataByBlock.invoke(getBlockByMaterial.invoke(null, obfuscationTarget));
|
||||
|
||||
@@ -35,6 +35,8 @@ import org.bukkit.event.player.PlayerAttemptPickupItemEvent
|
||||
import org.bukkit.event.player.PlayerInteractEntityEvent
|
||||
import org.bukkit.event.player.PlayerJoinEvent
|
||||
import org.bukkit.event.player.PlayerMoveEvent
|
||||
import org.bukkit.event.player.*
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
|
||||
object IngameListener : Listener {
|
||||
|
||||
@@ -75,9 +77,9 @@ object IngameListener : Listener {
|
||||
|
||||
@EventHandler
|
||||
fun onPickupCoins(e: PlayerAttemptPickupItemEvent) {
|
||||
if (e.item.itemStack.isSimilar(DealerInventory.coins)) {
|
||||
TNTLeagueGame.getTeam(e.player)?.coins =
|
||||
e.item.itemStack.amount + (TNTLeagueGame.getTeam(e.player)?.coins ?: 0)
|
||||
if (e.item.itemStack.persistentDataContainer.has(DealerInventory.coinKey)) {
|
||||
val numberOfCoins = e.item.itemStack.persistentDataContainer[DealerInventory.coinKey, PersistentDataType.INTEGER] ?: 0
|
||||
TNTLeagueGame.getTeam(e.player)?.coins = (e.item.itemStack.amount * numberOfCoins) + (TNTLeagueGame.getTeam(e.player)?.coins ?: 0)
|
||||
|
||||
e.item.itemStack.amount = 0
|
||||
e.isCancelled = true
|
||||
|
||||
@@ -24,8 +24,6 @@ import de.steamwar.message.SubMessage
|
||||
import de.steamwar.network.NetworkSender
|
||||
import de.steamwar.network.packets.common.FightInfoPacket
|
||||
import de.steamwar.scoreboard.SWScoreboard
|
||||
import de.steamwar.sql.Fight
|
||||
import de.steamwar.sql.FightPlayer
|
||||
import de.steamwar.sql.SteamwarUser
|
||||
import de.steamwar.tntleague.colorByTeam
|
||||
import de.steamwar.tntleague.config.TNTLeagueConfig
|
||||
@@ -37,10 +35,9 @@ import de.steamwar.tntleague.events.LobbyListener
|
||||
import de.steamwar.tntleague.inventory.DealerInventory
|
||||
import de.steamwar.tntleague.message
|
||||
import de.steamwar.tntleague.plugin
|
||||
import de.steamwar.tntleague.util.*
|
||||
import de.steamwar.tntleague.util.TNTLeagueScoreboard
|
||||
import org.bukkit.GameMode
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.Sound
|
||||
import org.bukkit.entity.Item
|
||||
import org.bukkit.entity.Player
|
||||
@@ -51,6 +48,7 @@ import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.scheduler.BukkitTask
|
||||
import java.sql.Timestamp
|
||||
import java.time.Instant
|
||||
import kotlin.random.Random
|
||||
|
||||
object TNTLeagueGame {
|
||||
var state: GameState = GameState.LOBBY
|
||||
@@ -87,18 +85,24 @@ object TNTLeagueGame {
|
||||
|
||||
message.broadcast("GAME_STARTED")
|
||||
|
||||
val tnt = ItemStack(Material.TNT)
|
||||
|
||||
start = Timestamp.from(Instant.now())
|
||||
|
||||
var spawnCount = 0
|
||||
spawnerTask = plugin.server.scheduler.runTaskTimer(plugin, bukkit {
|
||||
val coinsToSpawn = if (spawnCount % 28 == 0) {
|
||||
DealerInventory.huge_coins
|
||||
} else if (spawnCount % 7 == 0) {
|
||||
DealerInventory.big_coins
|
||||
} else {
|
||||
DealerInventory.coins
|
||||
}
|
||||
spawnCount++
|
||||
|
||||
if (world.getNearbyEntitiesByType(Item::class.java, TNTLeagueWorldConfig.blueTeam.itemSpawn, 3.0).sumOf { it.itemStack.amount } <= 256) {
|
||||
spawnItems(TNTLeagueWorldConfig.blueTeam.itemSpawn, tnt)
|
||||
spawnItems(TNTLeagueWorldConfig.blueTeam.itemSpawn, DealerInventory.coins)
|
||||
spawnItems(TNTLeagueWorldConfig.blueTeam.itemSpawn, coinsToSpawn)
|
||||
}
|
||||
if (world.getNearbyEntitiesByType(Item::class.java, TNTLeagueWorldConfig.redTeam.itemSpawn, 3.0).sumOf { it.itemStack.amount } <= 256) {
|
||||
spawnItems(TNTLeagueWorldConfig.redTeam.itemSpawn, tnt)
|
||||
spawnItems(TNTLeagueWorldConfig.redTeam.itemSpawn, DealerInventory.coins)
|
||||
spawnItems(TNTLeagueWorldConfig.redTeam.itemSpawn, coinsToSpawn)
|
||||
}
|
||||
}, 5, 10)
|
||||
|
||||
|
||||
@@ -59,13 +59,31 @@ class DealerInventory(player: Player): KotlinInventory(player) {
|
||||
companion object {
|
||||
private val priceKey = NamespacedKey(plugin, "price")
|
||||
private val amountKey = NamespacedKey(plugin, "amount")
|
||||
private val coinKey = NamespacedKey(plugin, "coin")
|
||||
val coinKey = NamespacedKey(plugin, "coin")
|
||||
|
||||
val coins = ItemStack(Material.RAW_GOLD).apply {
|
||||
itemMeta = itemMeta.apply {
|
||||
displayName(Component.text("Coins").color(NamedTextColor.GOLD))
|
||||
persistentDataContainer.apply {
|
||||
set(coinKey, PersistentDataType.BOOLEAN, true)
|
||||
set(coinKey, PersistentDataType.INTEGER, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val big_coins = ItemStack(Material.GOLD_INGOT).apply {
|
||||
itemMeta = itemMeta.apply {
|
||||
displayName(Component.text("Big Coins").color(NamedTextColor.GOLD))
|
||||
persistentDataContainer.apply {
|
||||
set(coinKey, PersistentDataType.INTEGER, 3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val huge_coins = ItemStack(Material.GOLD_BLOCK).apply {
|
||||
itemMeta = itemMeta.apply {
|
||||
displayName(Component.text("Huge Coins").color(NamedTextColor.GOLD))
|
||||
persistentDataContainer.apply {
|
||||
set(coinKey, PersistentDataType.INTEGER, 9)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,20 +17,23 @@
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
PREFIX=<EFBFBD>eTowerRun<EFBFBD>8<EFBFBD><EFBFBD>r
|
||||
PREFIX=§eTowerRun§8§§r
|
||||
|
||||
PLAYER_DIED=<EFBFBD>c{0} <EFBFBD>7died<EFBFBD>8!
|
||||
PLAYER_ESCAPE=<EFBFBD>a{0} <EFBFBD>7escaped<EFBFBD>8!
|
||||
GAME_START=<EFBFBD>aThe game has started<EFBFBD>8!
|
||||
GAME_WIN=<EFBFBD>a{0} <EFBFBD>7has won the game<EFBFBD>8!
|
||||
GAME_STARTING=<EFBFBD>7Starting: <EFBFBD>e{0}s<EFBFBD>8!
|
||||
GAME_WAITING=<EFBFBD>7Waiting for players<EFBFBD>8...
|
||||
SERVER_STOPPING=<EFBFBD>cThe server stops in <EFBFBD>e{0}s<EFBFBD>8!
|
||||
SERVER_RESET=<EFBFBD>cThe server will be reset in <EFBFBD>e{0}s<EFBFBD>8!
|
||||
KEY_NAME=<EFBFBD>eKey
|
||||
KEY_FOUND=<EFBFBD>a{0} <EFBFBD>7found a key<EFBFBD>8!
|
||||
GAME_TIE=<EFBFBD>aThe game ended in a tie<EFBFBD>8!
|
||||
GAME_TIME=<EFBFBD>a{0}:{1}
|
||||
CATCH_UP_WARNING=<EFBFBD>4!! <EFBFBD>cYou should catch up <EFBFBD>4!!
|
||||
PLAYER_DIED=§c{0} §7died§8!
|
||||
PLAYER_ESCAPE=§a{0} §7escaped§8!
|
||||
GAME_START=§aThe game has started§8!
|
||||
GAME_WIN=§a{0} §7has won the game§8!
|
||||
GAME_STARTING=§7Starting: §e{0}s§8!
|
||||
GAME_WAITING=§7Waiting for players§8...
|
||||
SERVER_STOPPING=§cThe server stops in §e{0}s§8!
|
||||
SERVER_RESET=§cThe server will be reset in §e{0}s§8!
|
||||
KEY_NAME=§eKey
|
||||
KEY_FOUND=§a{0} §7found a key§8!
|
||||
GAME_TIE=§aThe game ended in a tie§8!
|
||||
GAME_TIME=§a{0}:{1}
|
||||
CATCH_UP_WARNING=§4!! §cYou should catch up §4!!
|
||||
|
||||
COMMAND_START=<EFBFBD>aThe game will start soon<EFBFBD>8!
|
||||
COMMAND_START=§aThe game will start soon§8!
|
||||
|
||||
PARTICIPANT_CHAT={0} {1}§8» §7{2}
|
||||
SPECTATOR_CHAT=§7{0}§8» §7{1}
|
||||
@@ -17,19 +17,19 @@
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
PLAYER_DIED=<EFBFBD>c{0} <EFBFBD>7ist gestorben<EFBFBD>8!
|
||||
PLAYER_ESCAPE=<EFBFBD>a{0} <EFBFBD>7ist entkommen<EFBFBD>8!
|
||||
GAME_START=<EFBFBD>aDas Spiel beginnt<EFBFBD>8!
|
||||
GAME_WIN=<EFBFBD>a{0} <EFBFBD>7hat das Spiel gewonnen<EFBFBD>8!
|
||||
GAME_STARTING=<EFBFBD>7Das Spiel startet in <EFBFBD>e{0}s<EFBFBD>8!
|
||||
GAME_WAITING=<EFBFBD>7Warte auf weitere Spieler<EFBFBD>8...
|
||||
SERVER_STOPPING=<EFBFBD>cDer Server stoppt in <EFBFBD>e{0}s<EFBFBD>8!
|
||||
SERVER_RESET=<EFBFBD>cDer Server wird in <EFBFBD>e{0}s <EFBFBD>czur<EFBFBD>ckgesetzt<EFBFBD>8!
|
||||
GAME_TIE=<EFBFBD>7Keiner hat gewonnen<EFBFBD>8!
|
||||
PLAYER_DIED=§c{0} §7ist gestorben§8!
|
||||
PLAYER_ESCAPE=§a{0} §7ist entkommen§8!
|
||||
GAME_START=§aDas Spiel beginnt§8!
|
||||
GAME_WIN=§a{0} §7hat das Spiel gewonnen§8!
|
||||
GAME_STARTING=§7Das Spiel startet in §e{0}s§8!
|
||||
GAME_WAITING=§7Warte auf weitere Spieler§8...
|
||||
SERVER_STOPPING=§cDer Server stoppt in §e{0}s§8!
|
||||
SERVER_RESET=§cDer Server wird in §e{0}s §czur§ckgesetzt§8!
|
||||
GAME_TIE=§7Keiner hat gewonnen§8!
|
||||
|
||||
KEY_NAME=<EFBFBD>eSchl<EFBFBD>ssel
|
||||
KEY_FOUND=<EFBFBD>a{0} <EFBFBD>7hat einen Schl<EFBFBD>ssel gefunden<EFBFBD>8!
|
||||
KEY_NAME=§eSchl§ssel
|
||||
KEY_FOUND=§a{0} §7hat einen Schl§ssel gefunden§8!
|
||||
|
||||
CATCH_UP_WARNING=<EFBFBD>4!! <EFBFBD>cDu solltest aufholen <EFBFBD>4!!
|
||||
CATCH_UP_WARNING=§4!! §cDu solltest aufholen §4!!
|
||||
|
||||
COMMAND_START=<EFBFBD>7Das Spiel startet bald<EFBFBD>8!
|
||||
COMMAND_START=§7Das Spiel startet bald§8!
|
||||
@@ -35,7 +35,8 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@UtilityClass
|
||||
public class WorldConfig {
|
||||
@@ -54,7 +55,7 @@ public class WorldConfig {
|
||||
public static final int MAP_MIN_Z;
|
||||
public static final int MAP_MAX_X;
|
||||
public static final int MAP_MAX_Z;
|
||||
public static final Map<Material, Integer> MELTING_TIMES;
|
||||
public static final boolean MELTING;
|
||||
public static final TowerGeneratorConfig TOWER_GENERATOR_CONFIG;
|
||||
|
||||
public static final List<WinCondition> WINCONDITIONS = new ArrayList<>();
|
||||
@@ -161,16 +162,7 @@ public class WorldConfig {
|
||||
MAP_MAX_X = config.getInt("maxX");
|
||||
MAP_MAX_Z = config.getInt("maxZ");
|
||||
|
||||
ConfigurationSection meltingBlocksSection = tower.getConfigurationSection("meltingBlocks");
|
||||
if (meltingBlocksSection != null) {
|
||||
Map<Material, Integer> meltingTimes = new HashMap<>();
|
||||
meltingBlocksSection.getKeys(false).forEach(s -> {
|
||||
meltingTimes.put(Material.valueOf(s), meltingBlocksSection.getInt(s));
|
||||
});
|
||||
MELTING_TIMES = Collections.unmodifiableMap(meltingTimes);
|
||||
} else {
|
||||
MELTING_TIMES = Collections.emptyMap();
|
||||
}
|
||||
MELTING = tower.getBoolean("melting") || tower.contains("meltingBlocks"); // Backwards compatibility with meltingBlocks key!
|
||||
|
||||
ACTIVE_WINCONDITIONS = config.getStringList("winconditions");
|
||||
WINCONDITIONS.stream().filter(winCondition -> ACTIVE_WINCONDITIONS.contains(winCondition.getName())).forEach(winCondition -> winCondition.setActive(true));
|
||||
|
||||
@@ -46,6 +46,10 @@ public class TowerRunGame {
|
||||
public static final List<TowerRunPlayer> PLAYERS_ESCAPED = new ArrayList<>();
|
||||
private static final World world = Bukkit.getWorlds().get(0);
|
||||
|
||||
public static boolean isEscaped(TowerRunPlayer player) {
|
||||
return PLAYERS_ESCAPED.contains(player);
|
||||
}
|
||||
|
||||
public static boolean isAlive(TowerRunPlayer player) {
|
||||
return PLAYERS_ALIVE.contains(player);
|
||||
}
|
||||
|
||||
@@ -19,20 +19,20 @@
|
||||
|
||||
package de.steamwar.towerrun.listener;
|
||||
|
||||
import de.steamwar.towerrun.TowerRun;
|
||||
import de.steamwar.towerrun.config.WorldConfig;
|
||||
import de.steamwar.towerrun.game.TowerRunGame;
|
||||
import de.steamwar.towerrun.game.TowerRunPlayer;
|
||||
import de.steamwar.towerrun.state.GameState;
|
||||
import de.steamwar.towerrun.state.GameStateBukkitListener;
|
||||
import de.steamwar.towerrun.state.GameStates;
|
||||
import lombok.val;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
import org.bukkit.event.player.*;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
@@ -67,4 +67,25 @@ public class GlobalListener extends GameStateBukkitListener implements Listener
|
||||
public void onPlayerRespawn(PlayerRespawnEvent event) {
|
||||
event.setRespawnLocation(WorldConfig.SPAWN);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onAsyncPlayerChat(AsyncPlayerChatEvent event) {
|
||||
TowerRunPlayer player = TowerRunPlayer.get(event.getPlayer());
|
||||
if (GameState.getCurrentState() == GameStates.RUNNING && (TowerRunGame.isAlive(player) || TowerRunGame.isEscaped(player))) {
|
||||
String prefix;
|
||||
if (TowerRunGame.isAlive(player)) {
|
||||
if (event.getPlayer().getGameMode() == GameMode.SPECTATOR) {
|
||||
prefix = "§c☠";
|
||||
} else {
|
||||
prefix = "§6❤";
|
||||
}
|
||||
} else {
|
||||
prefix = "§a✔";
|
||||
}
|
||||
TowerRun.getMessage().broadcastPrefixless("PARTICIPANT_CHAT", prefix, event.getPlayer().getName(), event.getMessage());
|
||||
} else {
|
||||
TowerRun.getMessage().broadcastPrefixless("SPECTATOR_CHAT", event.getPlayer().getName(), event.getMessage());
|
||||
}
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,13 +62,13 @@ public class IngameListener extends GameStateBukkitListener {
|
||||
blocksToMeltRunnable = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
List<Block> blocks = blocksToMelt.get(time);
|
||||
List<Block> blocks = blocksToMelt.remove(time);
|
||||
time++;
|
||||
if (blocks == null) {
|
||||
return;
|
||||
}
|
||||
blocks.forEach(block -> {
|
||||
if (!WorldConfig.MELTING_TIMES.containsKey(block.getType())) return;
|
||||
if (block.getType() == Material.AIR || block.getType() == Material.LAVA) return;
|
||||
block.setType(Material.AIR);
|
||||
block.getWorld().playSound(block.getLocation(), Sound.BLOCK_FIRE_EXTINGUISH, 0.1F, 1);
|
||||
});
|
||||
@@ -189,6 +189,9 @@ public class IngameListener extends GameStateBukkitListener {
|
||||
|
||||
@EventHandler
|
||||
public void onBlockPhysics(BlockPhysicsEvent event) {
|
||||
if (!WorldConfig.MELTING) {
|
||||
return;
|
||||
}
|
||||
if (event.getSourceBlock().getType() != Material.LAVA) {
|
||||
return;
|
||||
}
|
||||
@@ -202,11 +205,9 @@ public class IngameListener extends GameStateBukkitListener {
|
||||
}
|
||||
|
||||
private void shouldMelt(Block block) {
|
||||
int meltingTime = WorldConfig.MELTING_TIMES.getOrDefault(block.getType(), -1);
|
||||
if (meltingTime == -1) {
|
||||
return;
|
||||
}
|
||||
blocksToMelt.computeIfAbsent(time + meltingTime * 20, integer -> new ArrayList<>()).add(block);
|
||||
if (block.getType().isBurnable()) return;
|
||||
int meltingTime = (int) (block.getType().getHardness() * 48 * 20);
|
||||
blocksToMelt.computeIfAbsent(time + meltingTime, integer -> new ArrayList<>()).add(block);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -66,4 +66,12 @@ dependencies {
|
||||
implementation(libs.apolloprotos)
|
||||
|
||||
implementation(libs.nbt)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register<DevServer>("DevVelocity") {
|
||||
group = "run"
|
||||
description = "Run a Dev Velocity"
|
||||
dependsOn(":VelocityCore:shadowJar")
|
||||
dependsOn(":VelocityCore:Persistent:jar")
|
||||
template = "DevVelocity"
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ UNPUNISHMENT_USAGE=§8/§7{0} §8[§eplayer§8]
|
||||
PUNISHMENT_UNTIL=until {0}
|
||||
PUNISHMENT_PERMA=permanent
|
||||
|
||||
BAN_TEAM={0} §e{1} §7was §e§lbanned§7 by §e{2} {3}§8: §f{4}
|
||||
BAN_TEAM=§e{0} §7was §e§lbanned§7 by §e{1} {2}§8: §f{3}
|
||||
BAN_PERMA=§7You are §e§lbanned §epermanently§8: §e{0}
|
||||
BAN_UNTIL=§7You are §e§lbanned §euntil {0}§8: §e{1}
|
||||
UNBAN_ERROR=§cThe player isn't banned.
|
||||
@@ -164,49 +164,49 @@ BAN_AVOIDING_ALERT=§cPotential ban bypass by §r{0}§c: {1}
|
||||
BAN_AVOIDING_LIST=§c{0} §e{1}
|
||||
BAN_AVOIDING_BAN_HOVER=§cBan player because of bann bypass.
|
||||
|
||||
MUTE_TEAM={0} §e{1} §7was §e§lmuted§7 by §e{2} {3}§8: §f{4}
|
||||
MUTE_TEAM=§e{0} §7was §e§lmuted§7 by §e{1} {2}§8: §f{3}
|
||||
MUTE_PERMA=§7You are §epermanently §e§lmuted§8: §e{0}
|
||||
MUTE_UNTIL=§7You are §e§lmuted §euntil {0}§8: §e{1}
|
||||
UNMUTE_ERROR=§cThe player isn't muted.
|
||||
UNMUTE=§7You have §e§lunmuted §e{0}.
|
||||
|
||||
NOSCHEMRECEIVING_TEAM={0} §e{1} §7was excluded from §e{2} {3} §7from §e§lrecieving schematics§8: §f{4}
|
||||
NOSCHEMRECEIVING_TEAM=§e{0} §7was excluded from §e{1} {2} §7from §e§lrecieving schematics§8: §f{3}
|
||||
NOSCHEMRECEIVING_PERMA=§7You are §epermanently§7 excluded from receiving §e§lschematics§8: §e{0}
|
||||
NOSCHEMRECEIVING_UNTIL=§7You are excluded from receiving §e§lschematics §euntil {0}§8: §e{1}
|
||||
UNNOSCHEMRECEIVING_ERROR=§cThe player is not excluded from receiving schematics.
|
||||
UNNOSCHEMRECEIVING=§e{0} §7may now receive §e§lschematics§7 again§8.
|
||||
|
||||
NOSCHEMSHARING_TEAM={0} §e{1} §7was excluded from §e{2} {3} §7from §e§lsharing schematics§8: §f{4}
|
||||
NOSCHEMSHARING_TEAM=§e{0} §7was excluded from §e{1} {2} §7from §e§lsharing schematics§8: §f{3}
|
||||
NOSCHEMSHARING_PERMA=§7You are §epermanently§7 excluded from sharing §e§lschematics§8: §e{0}
|
||||
NOSCHEMSHARING_UNTIL=§7You are excluded from sharing §e§lschematics §euntil {0}§8: §e{1}
|
||||
UNNOSCHEMSHARING_ERROR=§cThe player is not excluded from sharing schematics.
|
||||
UNNOSCHEMSHARING=§e{0} §7may now share §e§lschematics§7 again§8.
|
||||
|
||||
NOSCHEMSUBMITTING_TEAM={0} §e{1} §7was excluded from §e{2} {3} §7from §e§lsubmitting schematics§8: §f{4}
|
||||
NOSCHEMSUBMITTING_TEAM=§e{0} §7was excluded from §e{1} {2} §7from §e§lsubmitting schematics§8: §f{3}
|
||||
NOSCHEMSUBMITTING_PERMA=§7You are §epermanently§7 excluded from submitting §e§lschematics§8: §e{0}
|
||||
NOSCHEMSUBMITTING_UNTIL=§7You are excluded from submitting §e§lschematics §euntil {0}§8: §e{1}
|
||||
UNNOSCHEMSUBMITTING_ERROR=§cThe player is not excluded from submitting schematics.
|
||||
UNNOSCHEMSUBMITTING=§e{0} §7may now submit §e§lschematics§7 again§8.
|
||||
|
||||
NODEVSERVER_TEAM={0} §e{1} §7has annoyed §e{2} §7with reason §f{4}§7 and therefore has received §e§ldev server prohibition§7§8, §f{3}
|
||||
NODEVSERVER_TEAM=§e{0} §7has annoyed §e{1} §7with reason §f{3}§7 and therefore has received §e§ldev server prohibition§7§8, §f{2}
|
||||
NODEVSERVER_PERMA=§7You are §epermanently§7 excluded from §e§ldev servers§8: §e{0}
|
||||
NODEVSERVER_UNTIL=§7You are excluded from §e§ldev servers§7 §euntil {0}§8: §e{1}
|
||||
UNNODEVSERVER_ERROR=§cThe player is not excluded from dev servers.
|
||||
UNNODEVSERVER=§e{0} §7may now join §e§ldev servers§7 again§8.
|
||||
|
||||
NOFIGHTSERVER_TEAM={0} §e{1} §7was excluded from §e{2} {3} §7from §e§lfighting§8: §f{4}
|
||||
NOFIGHTSERVER_TEAM=§e{0} §7was excluded from §e{1} {2} §7from §e§lfighting§8: §f{3}
|
||||
NOFIGHTSERVER_PERMA=§7You are §epermanently§7 excluded from §e§lfighting§8: §e{0}
|
||||
NOFIGHTSERVER_UNTIL=§7You are excluded from §e§lfighting§7 §euntil {0}§8: §e{1}
|
||||
UNNOFIGHTSERVER_ERROR=§cThe player is not excluded from fighting.
|
||||
UNNOFIGHTSERVER=§e{0} §7may now join §e§lfights§7 again§8.
|
||||
|
||||
NOTEAMSERVER_TEAM={0} §e{1} §7was excluded from §e{2} {3} §7from §e§lteam servers§8: §f{4}
|
||||
NOTEAMSERVER_TEAM=§e{0} §7was excluded from §e{1} {2} §7from §e§lteam servers§8: §f{3}
|
||||
NOTEAMSERVER_PERMA=§7You are §epermanently§7 excluded from §e§lteam servers§8: §e{0}
|
||||
NOTEAMSERVER_UNTIL=§7You are excluded from §e§lteam servers§7 §euntil {0}§8: §e{1}
|
||||
UNNOTEAMSERVER_ERROR=§cThe player is not excluded from team servers.
|
||||
UNNOTEAMSERVER=§e{0} §7may now set §e§lteam servers§7 again§8.
|
||||
|
||||
NOTE_TEAM={0} §e{1} §7received a §e§lnote§7 from §e{2} {3}: §f{4}
|
||||
NOTE_TEAM=§e{0} §7received a §e§lnote§7 from §e{1} {2}: §f{3}
|
||||
|
||||
#BugCommand
|
||||
BUG_MESSAGE=§7Please describe the issue in a Discord ticket with the bug ID §e{0} §7further§8.
|
||||
@@ -572,6 +572,7 @@ CHAT_NO_RECEIVER=§cNobody receives your message
|
||||
CHAT_EMPTY=§cDon\'t write meaningless empty messages.
|
||||
|
||||
CHAT_SERVERTEAM=§8STC §e{0}§8» §f{2}
|
||||
CHAT_DISCORD_SERVERTEAM=§8STC §e{0}§8» §f{2}
|
||||
CHAT_GLOBAL={3}{4}{5}{6}{0}§8» {7}{2}
|
||||
CHAT_DISCORD_GLOBAL=§8Dc {5}{6}{0}§8» {7}{2}
|
||||
CHAT_TEAM=§8TC §e{0}§8» §f{2}
|
||||
|
||||
@@ -138,7 +138,7 @@ UNPUNISHMENT_USAGE=§8/§7{0} §8[§eSpieler§8]
|
||||
PUNISHMENT_UNTIL=bis zum {0}
|
||||
PUNISHMENT_PERMA=permanent
|
||||
|
||||
BAN_TEAM={0} §e{1} §7wurde von §e{2} {3} §e§lgebannt§8. §7Grund§8: §f{4}
|
||||
BAN_TEAM=§e{1} §7wurde von §e{2} {3} §e§lgebannt§8. §7Grund§8: §f{4}
|
||||
BAN_PERMA=§7Du bist §epermanent §e§lgebannt§8. §7Grund§8: §e{0}
|
||||
BAN_UNTIL=§7Du bist §ebis zum {0} §e§lgebannt§8. §7Grund§8: §e{1}
|
||||
UNBAN_ERROR=§cDer Spieler ist nicht gebannt.
|
||||
@@ -148,49 +148,49 @@ BAN_AVOIDING_ALERT=§cMögliche Bannumgehung durch §r{0}§c: {1}
|
||||
BAN_AVOIDING_LIST=§c{0} §e{1}
|
||||
BAN_AVOIDING_BAN_HOVER=§cBanne Spieler wegen Bannumgehung
|
||||
|
||||
MUTE_TEAM={0} §e{1} §7wurde von §e{2} {3} §e§lgemuted§8. §7Grund§8: §f{4}
|
||||
MUTE_TEAM=§e{0} §7wurde von §e{1} {2} §e§lgemuted§8. §7Grund§8: §f{3}
|
||||
MUTE_PERMA=§7Du bist §epermanent §e§lgemuted§8. §7Grund§8: §e{0}
|
||||
MUTE_UNTIL=§7Du bist §ebis zum {0} §e§lgemuted§8. §7Grund§8: §e{1}
|
||||
UNMUTE_ERROR=§cDer Spieler ist nicht gemuted.
|
||||
UNMUTE=§7Du hast §e{0} §e§lentmuted.
|
||||
|
||||
NOSCHEMRECEIVING_TEAM={0} §e{1} §7wurde von §e{2} {3} §7vom §e§lSchematicerhalten§7 ausgeschlossen§8: §f{4}
|
||||
NOSCHEMRECEIVING_TEAM=§e{0} §7wurde von §e{1} {2} §7vom §e§lSchematicerhalten§7 ausgeschlossen§8: §f{3}
|
||||
NOSCHEMRECEIVING_PERMA=§7Du bist §epermanent §7vom Erhalten von §e§lSchematics§7 ausgeschlossen§8: §e{0}
|
||||
NOSCHEMRECEIVING_UNTIL=§7Du bist §ebis zum {0} §7vom Erhalten von §e§lSchematics§7 ausgeschlossen§8: §e{1}
|
||||
UNNOSCHEMRECEIVING_ERROR=§cDer Spieler ist nicht vom Erhalten von Schematics ausgeschlossen.
|
||||
UNNOSCHEMRECEIVING=§e{0} §7darf nun wieder §e§lSchematics§7 erhalten§8.
|
||||
|
||||
NOSCHEMSHARING_TEAM={0} §e{1} §7wurde von §e{2} {3} §7vom §e§lSchematicverteilen§7 ausgeschlossen§8: §f{4}
|
||||
NOSCHEMSHARING_TEAM=§e{0} §7wurde von §e{1} {2} §7vom §e§lSchematicverteilen§7 ausgeschlossen§8: §f{3}
|
||||
NOSCHEMSHARING_PERMA=§7Du bist §epermanent §7vom §e§lVerteilen von Schematics§7 ausgeschlossen§8: §e{0}
|
||||
NOSCHEMSHARING_UNTIL=§7Du bist §ebis zum {0} §7vom §e§lVerteilen von Schematics§7 ausgeschlossen§8: §e{1}
|
||||
UNNOSCHEMSHARING_ERROR=§cDer Spieler ist nicht vom Verteilen von Schematics ausgeschlossen.
|
||||
UNNOSCHEMSHARING=§e{0} §7darf nun wieder §e§lSchematics§7 verteilen§8.
|
||||
|
||||
NOSCHEMSUBMITTING_TEAM={0} §e{1} §7wurde von §e{2} {3} §7vom §e§lSchematiceinsenden§7 ausgeschlossen§8: §f{4}
|
||||
NOSCHEMSUBMITTING_TEAM=§e{0} §7wurde von §e{1} {2} §7vom §e§lSchematiceinsenden§7 ausgeschlossen§8: §f{3}
|
||||
NOSCHEMSUBMITTING_PERMA=§7Du bist §epermanent §7vom §e§lEinsenden von Schematics§7 ausgeschlossen§8: §e{0}
|
||||
NOSCHEMSUBMITTING_UNTIL=§7Du bist §ebis zum {0} §7vom §e§lEinsenden von Schematics§7 ausgeschlossen§8: §e{1}
|
||||
UNNOSCHEMSUBMITTING_ERROR=§cDer Spieler ist nicht vom Einsenden von Schematics ausgeschlossen.
|
||||
UNNOSCHEMSUBMITTING=§e{0} §7darf nun wieder §e§lSchematis§7 einsenden§8.
|
||||
|
||||
NODEVSERVER_TEAM={0} §e{1} §7hat §e{2} §7mit Grund §f{4}§7 zu genervt und hat daher §e§lDevserververbot§7 erhalten§8, §f{3}
|
||||
NODEVSERVER_TEAM=§e{0} §7hat §e{1} §7mit Grund §f{3}§7 zu genervt und hat daher §e§lDevserververbot§7 erhalten§8, §f{2}
|
||||
NODEVSERVER_PERMA=§7Du bist §epermanent §7vom §e§lDevserver§7 ausgeschlossen§8: §e{0}
|
||||
NODEVSERVER_UNTIL=§7Du bist §ebis zum {0} §7vom §e§lDevserver§7 ausgeschlossen§8: §e{1}
|
||||
UNNODEVSERVER_ERROR=§cDer Spieler ist nicht vom Devserver ausgeschlossen.
|
||||
UNNODEVSERVER=§e{0} §7darf nun wieder dem §e§lDevserver§7 beitreten§8.
|
||||
|
||||
NOFIGHTSERVER_TEAM={0} §e{1} §7wurde von §e{2} {3} §7vom §e§lKämpfen§7 ausgeschlossen§8: §f{4}
|
||||
NOFIGHTSERVER_TEAM=§e{0} §7wurde von §e{1} {2} §7vom §e§lKämpfen§7 ausgeschlossen§8: §f{3}
|
||||
NOFIGHTSERVER_PERMA=§7Du bist §epermanent §7vom §e§lKämpfen§7 ausgeschlossen§8: §e{0}
|
||||
NOFIGHTSERVER_UNTIL=§7Du bist §ebis zum {0} §7vom §e§lKämpfen§7 ausgeschlossen§8: §e{1}
|
||||
UNNOFIGHTSERVER_ERROR=§cDer Spieler ist nicht vom Kämpfen ausgeschlossen.
|
||||
UNNOFIGHTSERVER=§e{0} §7darf nun wieder §e§lKämpfen§7 beitreten§8.
|
||||
|
||||
NOTEAMSERVER_TEAM={0} §e{1} §7wurde von §e{2} {3} §7vom §e§lTeamserver§7 setzen ausgeschlossen§8: §f{4}
|
||||
NOTEAMSERVER_TEAM=§e{0} §7wurde von §e{1} {2} §7vom §e§lTeamserver§7 setzen ausgeschlossen§8: §f{3}
|
||||
NOTEAMSERVER_PERMA=§7Du bist §epermanent §7vom §e§lTeamserver§7 setzen ausgeschlossen§8: §e{0}
|
||||
NOTEAMSERVER_UNTIL=§7Du bist §ebis zum {0} §7vom §e§lTeamserver§7 setzen ausgeschlossen§8: §e{1}
|
||||
UNNOTEAMSERVER_ERROR=§cDer Spieler ist nicht vom Teamserver setzten ausgeschlossen.
|
||||
UNNOTEAMSERVER=§e{0} §7darf nun wieder §e§lTeamserver§7 setzen§8.
|
||||
|
||||
NOTE_TEAM={0} §e{1} §7erhielt von §e{2} {3} §7die §e§lNotiz§7§8: §f{4}
|
||||
NOTE_TEAM=§e{0} §7erhielt von §e{1} {2} §7die §e§lNotiz§7§8: §f{3}
|
||||
|
||||
#BugCommand
|
||||
BUG_MESSAGE=§7Bitte beschreibe das Problem in einem Discordticket genauer und gebe dabei die Bug-ID §e{0} §7an§8.
|
||||
@@ -536,9 +536,9 @@ CHAT_YOYONOW_3=Vielen Dank.
|
||||
CHAT_YOYONOW_4=Ich wünsche dir noch weiterhin ein reibungsloses Spielerlebnis.
|
||||
CHAT_CHAOSCAOT_1=Du hast mich gerufen!
|
||||
CHAT_CHAOSCAOT_2=Wenn etwas nicht funktioniert, dann nen es einfach ein Feature.
|
||||
CHAT_CHAOSCAOT_3=Und wenn es ein Feature ist, dann kann es nicht kaputt.
|
||||
CHAT_CHAOSCAOT_4=Kaputt ist nur eine Definition. Wenn du es als Feature definiert, dann kann es nicht kaputt sein.
|
||||
CHAT_CHAOSCAOT_5=Und wenn du es als kaputt definiert, dann sag uns bescheid mit dem Befehl "/bug <MESSAGE>".
|
||||
CHAT_CHAOSCAOT_3=Und wenn es ein Feature ist, dann kann es nicht kaputt sein.
|
||||
CHAT_CHAOSCAOT_4=Kaputt ist nur eine Definition. Wenn du alles als Feature definierst, dann kann es auch keine Bugs geben.
|
||||
CHAT_CHAOSCAOT_5=Solltest du es aber doch als Bug definieren, dann sag uns bescheid mit dem Befehl "/bug <MESSAGE>".
|
||||
CHAT_CHAOSCAOT_6=Vielen Dank.
|
||||
CHAT_RECEIVE=§cUm Chatnachrichten versenden zu können, musst du auch welche empfangen!
|
||||
CHAT_NO_LINKS=§cDu darfst keine Links versenden.
|
||||
@@ -547,6 +547,7 @@ CHAT_NO_RECEIVER=§cNiemand empfängt deine Nachricht
|
||||
CHAT_EMPTY=§cSchreibe keine inhaltslosen Nachrichten.
|
||||
|
||||
CHAT_SERVERTEAM=§8STC §e{0}§8» §f{2}
|
||||
CHAT_DISCORD_SERVERTEAM=§8STC §e{0}§8» §f{2}
|
||||
CHAT_GLOBAL={3}{4}{5}{6}{0}§8» {7}{2}
|
||||
CHAT_DISCORD_GLOBAL=§8Dc {5}{6}{0}§8» {7}{2}
|
||||
CHAT_TEAM=§8TC §e{0}§8» §f{2}
|
||||
|
||||
@@ -22,6 +22,7 @@ package de.steamwar.velocitycore;
|
||||
import de.steamwar.sql.SchematicType;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
|
||||
public class ArenaMode extends GameModeConfig {
|
||||
@@ -76,7 +77,7 @@ public class ArenaMode extends GameModeConfig {
|
||||
public static List<String> getAllChatNames(boolean historic) {
|
||||
List<String> chatNames = new LinkedList<>();
|
||||
for(ArenaMode mode : byInternal.values()){
|
||||
if(historic == mode.isHistoric())
|
||||
if(mode.isActive() && historic == mode.isHistoric())
|
||||
chatNames.addAll(mode.getServer().getChatNames());
|
||||
}
|
||||
return chatNames;
|
||||
@@ -94,6 +95,9 @@ public class ArenaMode extends GameModeConfig {
|
||||
@Getter
|
||||
private String config;
|
||||
|
||||
@Getter
|
||||
private List<Integer> ActiveMonths = Collections.emptyList();
|
||||
|
||||
public String hasMap(String map){
|
||||
for(String m : getMaps()) {
|
||||
if(m.equalsIgnoreCase(map))
|
||||
@@ -114,8 +118,10 @@ public class ArenaMode extends GameModeConfig {
|
||||
return getServer().getChatNames().get(0);
|
||||
}
|
||||
|
||||
public boolean withoutChatName(){
|
||||
return getServer().getChatNames().isEmpty();
|
||||
public boolean isActive() {
|
||||
if (getServer().getChatNames().isEmpty()) return false;
|
||||
if (ActiveMonths.isEmpty()) return true;
|
||||
return ActiveMonths.contains(LocalDateTime.now().getMonth().getValue());
|
||||
}
|
||||
|
||||
public String getSchemTypeOrInternalName() {
|
||||
|
||||
@@ -44,6 +44,7 @@ public enum ServerVersion {
|
||||
PAPER_18("paper-1.18.2.jar", 15, ProtocolVersion.MINECRAFT_1_18_2),
|
||||
PAPER_19("paper-1.19.3.jar", 19, ProtocolVersion.MINECRAFT_1_19_3),
|
||||
PAPER_20("paper-1.20.1.jar", 20, ProtocolVersion.MINECRAFT_1_20),
|
||||
DEVEL_21("paper-1.21.5.jar", 21, ProtocolVersion.MINECRAFT_1_21_5),
|
||||
PAPER_21("paper-1.21.3.jar", 21, ProtocolVersion.MINECRAFT_1_21_2);
|
||||
|
||||
private static final Map<String, ServerVersion> chatMap = new HashMap<>();
|
||||
@@ -94,6 +95,10 @@ public enum ServerVersion {
|
||||
}
|
||||
|
||||
public static ServerVersion get(int version) {
|
||||
if (version == 21) {
|
||||
return DEVEL_21;
|
||||
}
|
||||
|
||||
return versionMap.get(version);
|
||||
}
|
||||
|
||||
|
||||
@@ -135,12 +135,12 @@ public class DevCommand extends SWCommand {
|
||||
});
|
||||
|
||||
devServerPorts.forEach((username, value) -> {
|
||||
if (devServers.containsKey(username))
|
||||
return;
|
||||
|
||||
SteamwarUser user = SteamwarUser.get(username);
|
||||
String name = "Dev " + user.getUserName();
|
||||
((VelocityViaConfig) Via.getConfig()).getVelocityServerProtocols().put(name, ServerVersion.get(devServerVersions.get(username)).getProtocolVersion().getProtocol());
|
||||
|
||||
if (devServers.containsKey(username))
|
||||
return;
|
||||
devServers.put(user.getUserName().toLowerCase(), VelocityCore.getProxy().registerServer(new ServerInfo(name, new InetSocketAddress("127.0.0.1", value))));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class FightCommand extends SWCommand {
|
||||
private static void getModes(Chatter sender, String precommand, boolean historic){
|
||||
Component start = Component.empty();
|
||||
for(ArenaMode mode : ArenaMode.getAllModes()){
|
||||
if(mode.withoutChatName() || mode.isHistoric() != historic)
|
||||
if (!mode.isActive() || mode.isHistoric() != historic)
|
||||
continue;
|
||||
|
||||
String command = precommand + mode.getChatName();
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
package de.steamwar.velocitycore.commands;
|
||||
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.proxy.Velocity;
|
||||
import de.steamwar.velocitycore.VelocityCore;
|
||||
import de.steamwar.velocitycore.listeners.ChatListener;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.messages.Chatter;
|
||||
@@ -41,7 +43,7 @@ public class MsgCommand extends SWCommand {
|
||||
}
|
||||
|
||||
public static void msg(PlayerChatter sender, Player target, String[] args) {
|
||||
if(target == null) {
|
||||
if(target == null || VelocityCore.getProxy().getPlayer(target.getUniqueId()).orElse(null) == null) {
|
||||
sender.system("MSG_OFFLINE");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ public class PunishmentCommand {
|
||||
target.punish(punishmentType, banTime, msg, punisher.getId(), isPerma);
|
||||
if(punishmentType == Punishment.PunishmentType.Ban)
|
||||
ban(target, banTime, msg, punisher, isPerma);
|
||||
Chatter.serverteam().system(punishmentType.getTeamMessage(), new Message("PREFIX"), target, sender, new Message((isPerma ? "PUNISHMENT_PERMA" : "PUNISHMENT_UNTIL"), banTime), msg);
|
||||
Chatter.serverteam().system(punishmentType.getTeamMessage(), target, sender, new Message((isPerma ? "PUNISHMENT_PERMA" : "PUNISHMENT_UNTIL"), banTime), msg);
|
||||
}
|
||||
|
||||
@Register
|
||||
|
||||
@@ -49,7 +49,11 @@ public class TypeMappers {
|
||||
return new TypeMapper<>() {
|
||||
@Override
|
||||
public ArenaMode map(Chatter sender, PreviousArguments previousArguments, String s) {
|
||||
return ArenaMode.getByChat(s);
|
||||
ArenaMode arenaMode = ArenaMode.getByChat(s);
|
||||
if (arenaMode == null) return null;
|
||||
if (arenaMode.isHistoric() != historic) return null;
|
||||
if (!arenaMode.isActive()) return null;
|
||||
return arenaMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -167,14 +167,19 @@ public class DiscordBot {
|
||||
checklistChannel = new ChecklistChannel(config.channel("checklist"));
|
||||
config.getCouncilThread().forEach((roleId, threadId) -> new CouncilChannel(DiscordBot.getGuild().getRoleById(roleId), DiscordBot.getGuild().getThreadChannelById(threadId)));
|
||||
|
||||
announcementChannel = new DiscordChannel(config.channel("announcement")) {
|
||||
announcementChannel = new DiscordChannel(config.channel("announcement"), 0) {
|
||||
@Override
|
||||
public void received(MessageReceivedEvent event) {
|
||||
Chatter.broadcast().system("ALERT", event.getMessage().getContentDisplay());
|
||||
}
|
||||
};
|
||||
ingameChat = new DiscordChatRoom(config.channel("ingame"), "CHAT_DISCORD_GLOBAL", Chatter::broadcast);
|
||||
serverTeamChat = new DiscordChatRoom(config.channel("serverteam"), "CHAT_SERVERTEAM", Chatter::serverteam);
|
||||
|
||||
// There is a hard limit of 30 messages per minute to send as a webhook, thus with 8 webhooks we can send
|
||||
// 240 messages per minute. Which means 4 every second. I looked at the WGS fights and there were around
|
||||
// ~70 in a short burst and then rather long no new message.
|
||||
ingameChat = new DiscordChatRoom(config.channel("ingame"), "CHAT_DISCORD_GLOBAL", Chatter::globalChat, 8);
|
||||
// 60 messages per minute should be enough for the server team!
|
||||
serverTeamChat = new DiscordChatRoom(config.channel("serverteam"), "CHAT_DISCORD_SERVERTEAM", Chatter::serverteam, 2);
|
||||
|
||||
VelocityCore.schedule(() -> {
|
||||
try {
|
||||
|
||||
@@ -23,6 +23,7 @@ import de.steamwar.sql.SchematicNode;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import de.steamwar.velocitycore.commands.CheckCommand;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -31,7 +32,7 @@ public class ChecklistChannel extends DiscordChannel {
|
||||
private final List<Integer> lastSchematics = new ArrayList<>();
|
||||
|
||||
public ChecklistChannel(String channel) {
|
||||
super(channel);
|
||||
super(channel, 0);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
@@ -41,7 +42,8 @@ public class ChecklistChannel extends DiscordChannel {
|
||||
schems.removeIf(schem -> lastSchematics.contains(schem.getId()));
|
||||
|
||||
for(SchematicNode schem : schems) {
|
||||
system("CHECK_LIST_TO_CHECK", CheckCommand.getWaitTime(schem), schem.getSchemtype().getKuerzel(), SteamwarUser.get(schem.getOwner()).getUserName(), schem.getName());
|
||||
String waitTime = "<t:" + (schem.getLastUpdate().getTime() / 1000) + ":R>";
|
||||
system("CHECK_LIST_TO_CHECK", waitTime, schem.getSchemtype().getKuerzel(), SteamwarUser.get(schem.getOwner()).getUserName(), schem.getName());
|
||||
lastSchematics.add(schem.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,13 +27,20 @@ import de.steamwar.velocitycore.discord.listeners.ChannelListener;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import net.dv8tion.jda.api.entities.Webhook;
|
||||
import net.dv8tion.jda.api.entities.WebhookClient;
|
||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
|
||||
import net.dv8tion.jda.api.events.interaction.component.GenericComponentInteractionCreateEvent;
|
||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
|
||||
import net.dv8tion.jda.internal.requests.IncomingWebhookClientImpl;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Queue;
|
||||
|
||||
|
||||
@AllArgsConstructor
|
||||
public class DiscordChannel extends Chatter.PlayerlessChatter {
|
||||
@@ -43,30 +50,82 @@ public class DiscordChannel extends Chatter.PlayerlessChatter {
|
||||
return user != null ? user : SteamwarUser.get(0);
|
||||
}
|
||||
|
||||
private final Queue<Webhook> webhooks = new ArrayDeque<>();
|
||||
|
||||
private final SteamwarUser user;
|
||||
@Getter
|
||||
private final MessageChannel channel;
|
||||
|
||||
private final int maxNumberOfWebhooks;
|
||||
|
||||
public DiscordChannel(User user) {
|
||||
this(userOrPublic(user), user.openPrivateChannel().complete());
|
||||
this(userOrPublic(user), user.openPrivateChannel().complete(), 0);
|
||||
}
|
||||
|
||||
public DiscordChannel(String channel) {
|
||||
this(DiscordBot.getGuild().getTextChannelById(channel));
|
||||
public DiscordChannel(String channel, int maxNumberOfWebhooks) {
|
||||
this(DiscordBot.getGuild().getTextChannelById(channel), maxNumberOfWebhooks);
|
||||
}
|
||||
|
||||
public DiscordChannel(MessageChannel channel) {
|
||||
this(SteamwarUser.get(-1), channel);
|
||||
public DiscordChannel(MessageChannel channel, int maxNumberOfWebhooks) {
|
||||
this(SteamwarUser.get(-1), channel, maxNumberOfWebhooks);
|
||||
ChannelListener.getChannels().put(this.channel, this);
|
||||
|
||||
if (channel instanceof TextChannel) {
|
||||
TextChannel textChannel = (TextChannel) channel;
|
||||
webhooks.addAll(textChannel.retrieveWebhooks().complete());
|
||||
while (webhooks.size() > maxNumberOfWebhooks) {
|
||||
webhooks.remove().delete().queue();
|
||||
}
|
||||
while (webhooks.size() < maxNumberOfWebhooks) {
|
||||
webhooks.add(textChannel.createWebhook(DiscordBot.getInstance().getJda().getSelfUser().getName()).complete());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void send(String message) {
|
||||
message = message
|
||||
.replace("&", "")
|
||||
.replace("@everyone", "`@everyone`")
|
||||
.replace("@here", "`@here`")
|
||||
.replaceAll("<[@#]!?\\d+>", "`$0`");
|
||||
|
||||
if (maxNumberOfWebhooks > 0 && getChannel() instanceof TextChannel && message.contains("»")) {
|
||||
String[] strings = message.split("»", 2);
|
||||
String userName = strings[0];
|
||||
String sendMessage = strings[1];
|
||||
strings = userName.split(" ");
|
||||
|
||||
String ingameName = strings[strings.length - 1];
|
||||
|
||||
SteamwarUser user = SteamwarUser.get(ingameName);
|
||||
if (user == null) {
|
||||
send(new MessageCreateBuilder()
|
||||
.setContent(message));
|
||||
return;
|
||||
}
|
||||
|
||||
String avatarUrl;
|
||||
if (user.getDiscordId() != null) {
|
||||
avatarUrl = DiscordBot.getGuild().retrieveMemberById(user.getDiscordId()).complete().getEffectiveAvatarUrl();
|
||||
} else {
|
||||
avatarUrl = DiscordBot.getInstance().getJda().getSelfUser().getAvatarUrl();
|
||||
}
|
||||
|
||||
Webhook webhook = webhooks.poll();
|
||||
webhooks.add(webhook);
|
||||
|
||||
// This works as per this documentation: https://discord.com/developers/docs/resources/webhook#execute-webhook
|
||||
IncomingWebhookClientImpl webhookClient = (IncomingWebhookClientImpl) WebhookClient.createClient(DiscordBot.getInstance().getJda(), webhook.getUrl());
|
||||
webhookClient.sendRequest()
|
||||
.setUsername(userName)
|
||||
.setAvatarUrl(avatarUrl)
|
||||
.setContent(sendMessage)
|
||||
.queue();
|
||||
return;
|
||||
}
|
||||
|
||||
send(new MessageCreateBuilder()
|
||||
.setContent(message
|
||||
.replace("&", "")
|
||||
.replace("@everyone", "`@everyone`")
|
||||
.replace("@here", "`@here`")
|
||||
.replaceAll("<[@#]!?\\d+>", "`$0`")));
|
||||
.setContent(message));
|
||||
}
|
||||
|
||||
public void send(MessageCreateBuilder builder) {
|
||||
|
||||
@@ -33,8 +33,8 @@ public class DiscordChatRoom extends DiscordChannel {
|
||||
private final String format;
|
||||
private final Supplier<ChatterGroup> target;
|
||||
|
||||
public DiscordChatRoom(String channel, String format, Supplier<ChatterGroup> target) {
|
||||
super(channel);
|
||||
public DiscordChatRoom(String channel, String format, Supplier<ChatterGroup> target, int maxNumberOfWebhooks) {
|
||||
super(channel, maxNumberOfWebhooks);
|
||||
this.format = format;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@@ -46,14 +46,14 @@ public class StaticMessageChannel extends DiscordChannel {
|
||||
}
|
||||
|
||||
public StaticMessageChannel(String channel, Supplier<MessageCreateBuilder> supplier, Consumer<GenericComponentInteractionCreateEvent> interaction) {
|
||||
super(channel);
|
||||
super(channel, 0);
|
||||
this.supplier = supplier;
|
||||
this.interaction = interaction;
|
||||
init();
|
||||
}
|
||||
|
||||
public StaticMessageChannel(MessageChannel channel, Supplier<MessageCreateBuilder> supplier, Consumer<GenericComponentInteractionCreateEvent> interaction) {
|
||||
super(channel);
|
||||
super(channel, 0);
|
||||
this.supplier = supplier;
|
||||
this.interaction = interaction;
|
||||
init();
|
||||
|
||||
@@ -70,7 +70,7 @@ public class DiscordTicketHandler extends ListenerAdapter {
|
||||
Permission.MESSAGE_HISTORY).complete();
|
||||
ticketChannel.getManager().setTopic(event.getUser().getId()).complete();
|
||||
|
||||
DiscordChannel channel = new DiscordChannel(DiscordChannel.userOrPublic(event.getUser()), ticketChannel);
|
||||
DiscordChannel channel = new DiscordChannel(DiscordChannel.userOrPublic(event.getUser()), ticketChannel, 0);
|
||||
channel.send(new MessageCreateBuilder()
|
||||
.setEmbeds(new EmbedBuilder()
|
||||
.setTitle(channel.parseToPlain("DC_TICKET_TITLE"))
|
||||
|
||||
@@ -377,7 +377,8 @@ public class PluginMessage extends BasicListener {
|
||||
"axiom:hello", "axiom:set_gamemode", "axiom:set_fly_speed", "axiom:set_world_time",
|
||||
"axiom:set_world_property", "axiom:set_block", "axiom:set_hotbar_slot", "axiom:switch_active_hotbar",
|
||||
"axiom:teleport", "axiom:request_chunk_data", "axiom:spawn_entity", "axiom:response_entity_data",
|
||||
"axiom:manipulate_entity", "axiom:delete_entity", "axiom:marker_nbt_request", "axiom:set_buffer"
|
||||
"axiom:manipulate_entity", "axiom:delete_entity", "axiom:marker_nbt_request", "axiom:set_buffer",
|
||||
"axiom:allowed_gamemodes", "axiom:ignore_display_entities", "axiom:add_server_heightmap"
|
||||
)) {
|
||||
channelRegisterHandlers.put(channel, player -> {});
|
||||
registerPassthroughToServer(channel);
|
||||
|
||||
@@ -185,7 +185,6 @@ public class Tablist extends ChannelInboundHandlerAdapter {
|
||||
if(msg instanceof UpsertPlayerInfoPacket packet) {
|
||||
packet.getActions().remove(UpsertPlayerInfoPacket.Action.INITIALIZE_CHAT);
|
||||
packet.getActions().remove(UpsertPlayerInfoPacket.Action.UPDATE_LATENCY);
|
||||
packet.getActions().remove(UpsertPlayerInfoPacket.Action.UPDATE_DISPLAY_NAME);
|
||||
packet.getActions().remove(UpsertPlayerInfoPacket.Action.UPDATE_LISTED);
|
||||
if(packet.getActions().isEmpty()) {
|
||||
ReferenceCountUtil.release(msg);
|
||||
|
||||
@@ -149,6 +149,23 @@ fun Route.configureSchematic() {
|
||||
return@let SchematicFormat.SPONGE_V2
|
||||
}
|
||||
|
||||
if (version == SchematicFormat.SPONGE_V3) {
|
||||
try {
|
||||
val fawe = schem.getCompound("Metadata")
|
||||
.getCompound("WorldEdit")
|
||||
.getString("Version")
|
||||
.value
|
||||
|
||||
if (fawe.equals("2.12.3-SNAPSHOT")) {
|
||||
SWException.log("Schematic with Bugged Version Uploaded", """
|
||||
Schematic=$schemName
|
||||
User=${user.userName}
|
||||
Id=${user.id}
|
||||
""".trimIndent())
|
||||
}
|
||||
} catch (_: Exception) {}
|
||||
}
|
||||
|
||||
val data = NodeData(node.id, version)
|
||||
data.saveFromStream(content.inputStream(), version)
|
||||
|
||||
|
||||
214
buildSrc/src/steamwar.devserver.gradle
Normal file
214
buildSrc/src/steamwar.devserver.gradle
Normal file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
plugins {
|
||||
}
|
||||
|
||||
class DevServer extends DefaultTask {
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
String worldName = null
|
||||
|
||||
@Input
|
||||
String template = null
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
String plugins = null
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
Integer port = null
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
String jar = null
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
Map<String, String> dParams = new HashMap<>()
|
||||
|
||||
DevServer() {
|
||||
super()
|
||||
doFirst {
|
||||
List<Project> projects = []
|
||||
projects.add(project)
|
||||
while (projects.first.parent != null) {
|
||||
projects.add(0, projects.first.parent)
|
||||
}
|
||||
|
||||
def properties = new Properties()
|
||||
projects.forEach {
|
||||
def file = new File(it.projectDir, "steamwar.properties")
|
||||
if (file.exists()) {
|
||||
properties.load(new FileInputStream(file))
|
||||
}
|
||||
}
|
||||
|
||||
if (worldName == null) worldName = properties.get("worldName")
|
||||
host = properties.get("host")
|
||||
|
||||
if (host == null) {
|
||||
throw new GradleException("Please supply the 'host' in a 'steamwar.properties' files either in this project dir or any parent project!")
|
||||
}
|
||||
}
|
||||
doLast {
|
||||
checkHasTemplate()
|
||||
uploadDependencies()
|
||||
startDevServer()
|
||||
}
|
||||
finalizedBy(new Finalizer())
|
||||
}
|
||||
|
||||
@Internal
|
||||
BufferedWriter processInput
|
||||
|
||||
@Internal
|
||||
String host
|
||||
|
||||
@Internal
|
||||
Boolean running = true
|
||||
|
||||
class Finalizer extends DefaultTask {
|
||||
|
||||
Finalizer() {
|
||||
super()
|
||||
doLast {
|
||||
running = false
|
||||
if (processInput != null) {
|
||||
processInput.write(template.endsWith("Velocity") ? "end\n" : "stop\n")
|
||||
processInput.flush()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void checkHasTemplate() {
|
||||
def process = new ProcessBuilder("ssh", host, "-T", "ls $template").start()
|
||||
process.waitFor()
|
||||
if (new BufferedReader(new InputStreamReader(process.inputStream)).lines().count() < 4) {
|
||||
throw new GradleException("Used template is not in your user.home directory of the given host $host")
|
||||
}
|
||||
}
|
||||
|
||||
void uploadDependencies() {
|
||||
def base = plugins == null ? "$template/plugins" : plugins
|
||||
println("Uploading to ~/$base")
|
||||
this.dependsOn.forEach {
|
||||
Project resolved
|
||||
AbstractArchiveTask archiveTask
|
||||
if (it instanceof String) {
|
||||
resolved = project.findProject(it.substring(0, it.lastIndexOf(':')))
|
||||
archiveTask = (AbstractArchiveTask) resolved.tasks.findByName(it.substring(it.lastIndexOf(':') + 1))
|
||||
} else {
|
||||
throw new GradleException("Illegal argument for uploading dependencies")
|
||||
}
|
||||
|
||||
def archive = archiveTask.archiveFile.get().asFile
|
||||
println("Uploading $archive")
|
||||
new ProcessBuilder("ssh", host, "-T", "rm $base/${archive.name.replace("-all", "")}").start().waitFor()
|
||||
new ProcessBuilder("scp", archive.absolutePath, "$host:~/$base/${archive.name.replace("-all", "")}").start().waitFor()
|
||||
println("Uploaded $archive")
|
||||
}
|
||||
}
|
||||
|
||||
void startDevServer() {
|
||||
def devPy = new StringBuilder().append("dev.py")
|
||||
if (port != null) devPy.append(" --port $port")
|
||||
if (worldName != null) devPy.append(" -w $template/$worldName")
|
||||
if (plugins != null) devPy.append(" -p $plugins")
|
||||
if (jar != null) devPy.append(" --jar $jar")
|
||||
for (Map.Entry<String, String> dParam : dParams.entrySet()) {
|
||||
devPy.append(" -D${dParam.key}=${dParam.value}")
|
||||
}
|
||||
devPy.append(" $template")
|
||||
println("Starting $template with command ${devPy.toString()}")
|
||||
|
||||
def process = new ProcessBuilder("ssh", host, "-T", devPy.toString()).start()
|
||||
def processOutput = new BufferedReader(new InputStreamReader(process.inputStream))
|
||||
new Thread({
|
||||
while (running) {
|
||||
if (processOutput.ready()) {
|
||||
println(processOutput.readLine())
|
||||
}
|
||||
}
|
||||
}).start()
|
||||
|
||||
processInput = new BufferedWriter(new OutputStreamWriter(process.outputStream))
|
||||
def input = new BufferedReader(new InputStreamReader(System.in))
|
||||
new Thread({
|
||||
while (running) {
|
||||
def text = input.readLine()
|
||||
if (text == null) break
|
||||
processInput.write(text)
|
||||
processInput.newLine()
|
||||
processInput.flush()
|
||||
}
|
||||
}).start()
|
||||
|
||||
process.waitFor()
|
||||
processInput = null
|
||||
running = false
|
||||
}
|
||||
}
|
||||
|
||||
class FightServer extends DevServer {
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
Integer checkSchemID = 0
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
Integer prepareSchemID = 0
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
Integer replay = 0
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
String config = null
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
// Property: fightID
|
||||
Integer eventKampfID = 0
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
UUID blueLeader = null
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
UUID redLeader = null
|
||||
|
||||
FightServer() {
|
||||
super()
|
||||
doFirst {
|
||||
if (checkSchemID != 0) dParams.put("checkSchemID", "$checkSchemID")
|
||||
if (prepareSchemID != 0) dParams.put("prepareSchemID", "$prepareSchemID")
|
||||
if (replay != 0) dParams.put("replay", "$replay")
|
||||
if (eventKampfID != 0) dParams.put("fightID", "$eventKampfID")
|
||||
if (blueLeader != null) dParams.put("blueLeader", blueLeader.toString())
|
||||
if (redLeader != null) dParams.put("redLeader", redLeader.toString())
|
||||
if (config != null) dParams.put("config", config)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,6 @@ private val isInCi by lazy { Os.isFamily(Os.FAMILY_UNIX) && ProcessBuilder("host
|
||||
|
||||
dependencyResolutionManagement {
|
||||
repositories {
|
||||
|
||||
maven {
|
||||
url = URI("https://m2.dv8tion.net/releases")
|
||||
content {
|
||||
@@ -46,7 +45,7 @@ dependencyResolutionManagement {
|
||||
if (isInCi) {
|
||||
url = URI("file:///var/www/maven/")
|
||||
} else {
|
||||
url = URI("https://steamwar.de/maven/")
|
||||
url = URI("https://maven.steamwar.de/")
|
||||
credentials {
|
||||
val swProps = Properties()
|
||||
swProps.load(rootDir.resolve("steamwar.properties").inputStream())
|
||||
|
||||
Reference in New Issue
Block a user