Added void-world for selection
Added loading indicators Added speed modifiers Code cleanup
This commit is contained in:
parent
ebf9f36635
commit
bb363dc06f
5
.idea/gradle.xml
generated
5
.idea/gradle.xml
generated
@ -4,8 +4,11 @@
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="delegatedBuild" value="true" />
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleHome" value="/usr/share/java/gradle" />
|
||||
<option name="gradleJvm" value="17" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
|
1
.idea/misc.xml
generated
1
.idea/misc.xml
generated
@ -1,4 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="corretto-17" project-jdk-type="JavaSDK">
|
||||
|
26
build.gradle
26
build.gradle
@ -3,8 +3,7 @@ plugins {
|
||||
id "com.github.johnrengelman.shadow" version "7.1.0"
|
||||
}
|
||||
|
||||
group = '' +
|
||||
''
|
||||
group = 'eu.mhsl.craftattack.worldmuseum'
|
||||
version = '1.0'
|
||||
|
||||
repositories {
|
||||
@ -13,13 +12,24 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation 'com.github.Minestom:Minestom:8ad2c7701f'
|
||||
implementation 'com.github.waxeria:Minestom:e0427a36f3'
|
||||
implementation 'org.jctools:jctools-core:4.0.1'
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes 'Main-Class': 'eu.mhsl.craftattack.worldmuseum.Main',
|
||||
"Multi-Release": true
|
||||
tasks {
|
||||
jar {
|
||||
manifest {
|
||||
attributes 'Main-Class': 'eu.mhsl.craftattack.worldmuseum.Main'
|
||||
attributes 'Multi-Release': true
|
||||
}
|
||||
duplicatesStrategy = 'exclude'
|
||||
from configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
|
||||
}
|
||||
build {
|
||||
dependsOn(shadowJar)
|
||||
}
|
||||
shadowJar {
|
||||
mergeServiceFiles()
|
||||
archiveClassifier.set("")
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package eu.mhsl.craftattack.worldmuseum;
|
||||
|
||||
import eu.mhsl.craftattack.worldmuseum.commands.GamemodeCommand;
|
||||
import eu.mhsl.craftattack.worldmuseum.items.ItemManager;
|
||||
import eu.mhsl.craftattack.worldmuseum.commands.SpawnCommand;
|
||||
import eu.mhsl.craftattack.worldmuseum.commands.TeleportCommand;
|
||||
import eu.mhsl.craftattack.worldmuseum.listener.*;
|
||||
@ -10,7 +9,7 @@ import eu.mhsl.craftattack.worldmuseum.util.TablistUpdateTask;
|
||||
import eu.mhsl.craftattack.worldmuseum.util.Config;
|
||||
import eu.mhsl.craftattack.worldmuseum.util.MuseumPlayer;
|
||||
import eu.mhsl.craftattack.worldmuseum.handler.SignHandler;
|
||||
import eu.mhsl.craftattack.worldmuseum.worlds.World;
|
||||
import eu.mhsl.craftattack.worldmuseum.worlds.VoidWorld;
|
||||
import eu.mhsl.craftattack.worldmuseum.worlds.WorldManager;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.entity.GameMode;
|
||||
@ -21,13 +20,13 @@ import net.minestom.server.event.player.*;
|
||||
import net.minestom.server.extras.bungee.BungeeCordProxy;
|
||||
import net.minestom.server.timer.TaskSchedule;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Main {
|
||||
static int PORT = 25565;
|
||||
static final String IP = "0.0.0.0";
|
||||
|
||||
public static void main(String[] args) {
|
||||
public static void main(String[] args) throws IOException {
|
||||
// Initialization
|
||||
System.setProperty("minestom.chunk-view-distance", "16");
|
||||
MinecraftServer minecraftServer = MinecraftServer.init();
|
||||
@ -45,14 +44,12 @@ public class Main {
|
||||
//load main config
|
||||
Config config = Config.getInstance();
|
||||
config.loadConfig();
|
||||
World startworld = config.getStart_world();
|
||||
if (config.isBungeecordEnabled()) {
|
||||
BungeeCordProxy.enable();
|
||||
System.out.println("[Info] Bungeecord enabled");
|
||||
}
|
||||
|
||||
|
||||
// Add an event callback to specify the spawning instance (and the spawn position)
|
||||
GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
|
||||
|
||||
//listeners
|
||||
@ -60,7 +57,6 @@ public class Main {
|
||||
globalEventHandler.addListener(PlayerChunkUnloadEvent.class, new ChunkUnloading());
|
||||
globalEventHandler.addListener(InventoryPreClickEvent.class, new InventoryClickListener());
|
||||
globalEventHandler.addListener(PlayerBlockBreakEvent.class, new BlockBreakListener());
|
||||
globalEventHandler.addListener(PlayerMoveEvent.class, new MovementListener());
|
||||
globalEventHandler.addListener(PlayerBlockPlaceEvent.class, new BlockPlaceListener());
|
||||
globalEventHandler.addListener(PlayerDisconnectEvent.class, new DisconnectListener());
|
||||
|
||||
@ -78,18 +74,17 @@ public class Main {
|
||||
|
||||
globalEventHandler.addListener(PlayerLoginEvent.class, event -> {
|
||||
final MuseumPlayer player = (MuseumPlayer) event.getPlayer();
|
||||
player.setSyncCooldown(Duration.ofSeconds(3));
|
||||
event.setSpawningInstance(startworld);
|
||||
final VoidWorld voidWorld = new VoidWorld();
|
||||
|
||||
player.setPermissionLevel(4);
|
||||
player.setRespawnPoint(startworld.getSpawn());
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> {
|
||||
SkinCache.setSkin(player);
|
||||
player.setAllowFlying(true);
|
||||
player.getInventory().setItemStack(0, ItemManager.getCompassItem());
|
||||
player.getInventory().setItemStack(8, ItemManager.getBedItem());
|
||||
});
|
||||
player.setRespawnPoint(voidWorld.getSpawn());
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
player.setAllowFlying(true);
|
||||
SkinCache.setSkin(player);
|
||||
|
||||
event.setSpawningInstance(voidWorld);
|
||||
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> voidWorld.movePlayer(player));
|
||||
|
||||
System.out.println("[Join] Player " + player.getUsername() +" joined the server.");
|
||||
});
|
||||
|
||||
@ -98,6 +93,7 @@ public class Main {
|
||||
} catch (Exception e) {
|
||||
if (args.length != 0) System.out.println("Given port doesn't work.");
|
||||
}
|
||||
|
||||
// Start the server on port default port 25565 if none is given
|
||||
System.out.println("[Info] Running on " + IP + ":" + PORT);
|
||||
minecraftServer.start(IP, PORT);
|
||||
|
@ -1,17 +1,23 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.commands;
|
||||
|
||||
import eu.mhsl.craftattack.worldmuseum.util.MuseumPlayer;
|
||||
import eu.mhsl.craftattack.worldmuseum.worlds.World;
|
||||
import net.minestom.server.command.builder.Command;
|
||||
import net.minestom.server.entity.Player;
|
||||
|
||||
public class SpawnCommand extends Command {
|
||||
public SpawnCommand() {
|
||||
super("spawn");
|
||||
setDefaultExecutor((sender, context) -> {
|
||||
Player p = (Player) sender;
|
||||
World world = (World) p.getInstance();
|
||||
assert world != null;
|
||||
p.teleport(world.getSpawn());
|
||||
if(sender instanceof MuseumPlayer p) {
|
||||
teleportToSpawn(p);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void teleportToSpawn(MuseumPlayer p) {
|
||||
if(p.getInstance() instanceof World world) {
|
||||
p.startLoading();
|
||||
p.teleport(world.getSpawn()).thenRun(p::stopLoading);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,22 +11,23 @@ public class TeleportCommand extends Command {
|
||||
public TeleportCommand() {
|
||||
super("tp");
|
||||
|
||||
var cordinate = ArgumentType.RelativeBlockPosition("Koordinate");
|
||||
var coordinate = ArgumentType.RelativeBlockPosition("cords");
|
||||
addSyntax(((sender, context) -> {
|
||||
Pos pos = context.get(cordinate).fromSender(sender).asPosition();
|
||||
Pos pos = context.get(coordinate).fromSender(sender).asPosition();
|
||||
Player player = (Player) sender;
|
||||
player.teleport(pos);
|
||||
}), cordinate);
|
||||
}), coordinate);
|
||||
|
||||
var playerArgument = ArgumentType.Entity("Spieler").onlyPlayers(true).singleEntity(true);
|
||||
var playerArgument = ArgumentType.Entity("player").onlyPlayers(true).singleEntity(true);
|
||||
addSyntax(((sender, context) -> {
|
||||
if (context.get(playerArgument).find(sender).size() == 0) return; //check if player is online
|
||||
if (context.get(playerArgument).find(sender).isEmpty()) return; //check if player is online
|
||||
Player targetPlayer = (Player) context.get(playerArgument).find(sender).get(0);
|
||||
Player p = (Player) sender;
|
||||
if (!Objects.equals(p.getInstance(), targetPlayer.getInstance()))
|
||||
if (!Objects.equals(p.getInstance(), targetPlayer.getInstance())) {
|
||||
p.setInstance(Objects.requireNonNull(targetPlayer.getInstance()), targetPlayer.getPosition());
|
||||
else
|
||||
} else {
|
||||
p.teleport(targetPlayer.getPosition());
|
||||
}
|
||||
}), playerArgument);
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import java.util.Collection;
|
||||
public class SignHandler implements BlockHandler {
|
||||
@Override
|
||||
public @NotNull Collection<Tag<?>> getBlockEntityTags() {
|
||||
|
||||
return new ArrayList<>() {
|
||||
{
|
||||
add(Tag.Byte("GlowingText"));
|
||||
|
@ -0,0 +1,31 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.inventory;
|
||||
|
||||
import eu.mhsl.craftattack.worldmuseum.worlds.World;
|
||||
import eu.mhsl.craftattack.worldmuseum.worlds.WorldManager;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.minestom.server.inventory.Inventory;
|
||||
import net.minestom.server.inventory.InventoryType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WorldSelector extends Inventory {
|
||||
public WorldSelector() {
|
||||
super(InventoryType.CHEST_1_ROW, Component.text("Weltenauswahl").color(NamedTextColor.DARK_GRAY));
|
||||
|
||||
List<World> worlds = WorldManager.getInstance().getWorlds();
|
||||
for (int i = 0; i < worlds.size(); i++) {
|
||||
World world = worlds.get(i);
|
||||
setItemStack(i, world.getItem());
|
||||
}
|
||||
|
||||
addInventoryCondition((player, slot, clickType, inventoryConditionResult) -> {
|
||||
inventoryConditionResult.setCancel(true);
|
||||
|
||||
player.closeInventory();
|
||||
try {
|
||||
worlds.get(slot).movePlayer(player);
|
||||
} catch (IndexOutOfBoundsException ignore) {}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.items;
|
||||
|
||||
import eu.mhsl.craftattack.worldmuseum.util.MuseumPlayer;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.tag.Tag;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ActionItem {
|
||||
public static Tag<UUID> tag = Tag.UUID("action");
|
||||
public static Map<UUID, Consumer<MuseumPlayer>> actions = new HashMap<>();
|
||||
|
||||
private final ItemStack itemStack;
|
||||
|
||||
public ActionItem(Consumer<MuseumPlayer> action, ItemStack itemStack) {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
this.itemStack = itemStack.withTag(tag, uuid);
|
||||
actions.put(uuid, action);
|
||||
}
|
||||
|
||||
public static void run(UUID uuid, Player p) {
|
||||
actions.get(uuid).accept((MuseumPlayer) p);
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return itemStack;
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.items;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
|
||||
public class ItemManager {
|
||||
public static ItemStack getBedItem() {
|
||||
return ItemStack.builder(Material.RED_BED).displayName(Component.text("Spawn-Teleporter")).build();
|
||||
}
|
||||
public static ItemStack getCompassItem() {
|
||||
return ItemStack.builder(Material.COMPASS).displayName(Component.text("World-changer")).build();
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.items;
|
||||
|
||||
import eu.mhsl.craftattack.worldmuseum.commands.SpawnCommand;
|
||||
import eu.mhsl.craftattack.worldmuseum.util.MuseumPlayer;
|
||||
import eu.mhsl.craftattack.worldmuseum.worlds.VoidWorld;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public enum Items {
|
||||
HUB(
|
||||
ItemStack
|
||||
.of(Material.IRON_DOOR)
|
||||
.withDisplayName(
|
||||
Component
|
||||
.text("Zurück zur Überischt")
|
||||
.color(NamedTextColor.GOLD)
|
||||
),
|
||||
player -> new VoidWorld().movePlayer(player)
|
||||
),
|
||||
|
||||
SPAWN(
|
||||
ItemStack
|
||||
.of(Material.TARGET)
|
||||
.withDisplayName(
|
||||
Component
|
||||
.text("Zum Spawn")
|
||||
.color(NamedTextColor.GOLD)
|
||||
),
|
||||
SpawnCommand::teleportToSpawn
|
||||
),
|
||||
|
||||
MORE_SPEED(
|
||||
ItemStack
|
||||
.of(Material.FEATHER)
|
||||
.withDisplayName(
|
||||
Component
|
||||
.text("Schneller fliegen")
|
||||
.color(NamedTextColor.AQUA)
|
||||
),
|
||||
player -> player.updateFlyingSpeed(0.05f)
|
||||
),
|
||||
|
||||
LESS_SPEED(
|
||||
ItemStack
|
||||
.of(Material.ANVIL)
|
||||
.withDisplayName(
|
||||
Component
|
||||
.text("Langsamer fliegen")
|
||||
.color(NamedTextColor.AQUA)
|
||||
),
|
||||
player -> player.updateFlyingSpeed(-0.05f)
|
||||
);
|
||||
|
||||
|
||||
private final ActionItem item;
|
||||
Items(ItemStack itemStack, Consumer<MuseumPlayer> action) {
|
||||
item = new ActionItem(action, itemStack);
|
||||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
return item.getItemStack();
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package eu.mhsl.craftattack.worldmuseum.listener;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.coordinate.Point;
|
||||
import net.minestom.server.event.player.PlayerBlockBreakEvent;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.timer.TaskSchedule;
|
||||
import java.util.function.Consumer;
|
||||
@ -12,6 +13,8 @@ public class BlockBreakListener implements Consumer<PlayerBlockBreakEvent> {
|
||||
public void accept(PlayerBlockBreakEvent playerBlockBreakEvent) {
|
||||
Block block = playerBlockBreakEvent.getBlock();
|
||||
Point point = playerBlockBreakEvent.getBlockPosition();
|
||||
MinecraftServer.getSchedulerManager().scheduleTask(() -> playerBlockBreakEvent.getInstance().setBlock(point, block), TaskSchedule.seconds(10), TaskSchedule.stop());
|
||||
Instance instance = playerBlockBreakEvent.getInstance();
|
||||
|
||||
MinecraftServer.getSchedulerManager().scheduleTask(() -> instance.setBlock(point, block), TaskSchedule.seconds(10), TaskSchedule.stop());
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,25 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.listener;
|
||||
|
||||
import eu.mhsl.craftattack.worldmuseum.worlds.World;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
|
||||
import java.util.Objects;
|
||||
import net.minestom.server.event.player.PlayerUseItemEvent;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BlockPlaceListener implements Consumer<PlayerBlockPlaceEvent> {
|
||||
@Override
|
||||
public void accept(PlayerBlockPlaceEvent playerBlockPlaceEvent) {
|
||||
playerBlockPlaceEvent.getPlayer().teleport(((World) Objects.requireNonNull(playerBlockPlaceEvent.getPlayer().getInstance())).getSpawn());
|
||||
Player p = playerBlockPlaceEvent.getPlayer();
|
||||
|
||||
// Fire ItemUseListener for possible missed block-clicks
|
||||
new ItemUseListener().accept(
|
||||
new PlayerUseItemEvent(
|
||||
p,
|
||||
playerBlockPlaceEvent.getHand(),
|
||||
p.getInventory().getItemStack(p.getHeldSlot())
|
||||
)
|
||||
);
|
||||
|
||||
playerBlockPlaceEvent.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ public class ChunkUnloading implements Consumer<PlayerChunkUnloadEvent> {
|
||||
var chunk = e.getInstance().getChunk(e.getChunkX(), e.getChunkZ());
|
||||
if (chunk == null) return;
|
||||
|
||||
if (chunk.getViewers().size() == 0) {
|
||||
if (chunk.getViewers().isEmpty()) {
|
||||
try {
|
||||
e.getInstance().unloadChunk(e.getChunkX(), e.getChunkZ());
|
||||
} catch (NullPointerException ignored) {}
|
||||
|
@ -1,29 +1,12 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.listener;
|
||||
|
||||
import eu.mhsl.craftattack.worldmuseum.util.MuseumPlayer;
|
||||
import eu.mhsl.craftattack.worldmuseum.util.ChangeWorld;
|
||||
import eu.mhsl.craftattack.worldmuseum.worlds.World;
|
||||
import eu.mhsl.craftattack.worldmuseum.worlds.WorldManager;
|
||||
import net.minestom.server.event.inventory.InventoryPreClickEvent;
|
||||
import java.util.Objects;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class InventoryClickListener implements Consumer<InventoryPreClickEvent> {
|
||||
@Override
|
||||
public void accept(InventoryPreClickEvent inventoryPreClickEvent) {
|
||||
MuseumPlayer p = (MuseumPlayer) inventoryPreClickEvent.getPlayer();
|
||||
WorldManager worldManager = WorldManager.getInstance();
|
||||
|
||||
for (World w : worldManager.getWorlds()) {
|
||||
if (!w.getItem().equals(inventoryPreClickEvent.getClickedItem())) continue;
|
||||
if (Objects.equals(p.getInstance(), w)) {
|
||||
p.closeInventory();
|
||||
p.teleport(w.getSpawn());
|
||||
} else {
|
||||
p.closeInventory();
|
||||
ChangeWorld.changeWorld(p, w);
|
||||
}
|
||||
}
|
||||
inventoryPreClickEvent.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +1,18 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.listener;
|
||||
|
||||
import eu.mhsl.craftattack.worldmuseum.items.ItemManager;
|
||||
import eu.mhsl.craftattack.worldmuseum.util.MuseumPlayer;
|
||||
import eu.mhsl.craftattack.worldmuseum.worlds.World;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import eu.mhsl.craftattack.worldmuseum.items.ActionItem;
|
||||
import net.minestom.server.event.player.PlayerUseItemEvent;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class ItemUseListener implements Consumer<PlayerUseItemEvent> {
|
||||
|
||||
@Override
|
||||
public void accept(PlayerUseItemEvent playerUseItemEvent) {
|
||||
MuseumPlayer p = (MuseumPlayer) playerUseItemEvent.getPlayer();
|
||||
ItemStack usedItem = playerUseItemEvent.getItemStack();
|
||||
|
||||
if (usedItem.equals(ItemManager.getCompassItem())) compassUse(p);
|
||||
else if (usedItem.equals(ItemManager.getBedItem())) bedUse(p);
|
||||
if(playerUseItemEvent.getItemStack().hasTag(ActionItem.tag)) {
|
||||
ActionItem.run(playerUseItemEvent.getItemStack().getTag(ActionItem.tag), playerUseItemEvent.getPlayer());
|
||||
}
|
||||
|
||||
playerUseItemEvent.setCancelled(true);
|
||||
}
|
||||
private void compassUse(MuseumPlayer p) {
|
||||
if (!p.isAllowCompassUsage()) {
|
||||
long lastUsed = (System.currentTimeMillis() - p.getLastCompassUsage()) / 1000;
|
||||
p.sendActionBar(Component.text("Du kannst den Kompass erst in " + (15 - lastUsed) + " Sekunden wieder benutzen."));
|
||||
return;
|
||||
}
|
||||
p.openInventory(p.getCompassInventory());
|
||||
}
|
||||
|
||||
private void bedUse(MuseumPlayer player) {
|
||||
World world = (World) player.getInstance();
|
||||
assert world != null;
|
||||
player.teleport(world.getSpawn());
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.listener;
|
||||
|
||||
import eu.mhsl.craftattack.worldmuseum.util.MuseumPlayer;
|
||||
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class MovementListener implements Consumer<PlayerMoveEvent> {
|
||||
@Override
|
||||
public void accept(PlayerMoveEvent playerMoveEvent) {
|
||||
MuseumPlayer player = (MuseumPlayer) playerMoveEvent.getPlayer();
|
||||
if (!player.isAllowMovement()) playerMoveEvent.setCancelled(true);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.util;
|
||||
|
||||
import eu.mhsl.craftattack.worldmuseum.worlds.World;
|
||||
import net.minestom.server.potion.Potion;
|
||||
import net.minestom.server.potion.PotionEffect;
|
||||
public class ChangeWorld {
|
||||
public static void changeWorld(MuseumPlayer player, World targetWorld) {
|
||||
player.setAllowMovement(false);
|
||||
World world = (World) player.getInstance();
|
||||
player.setAllowCompassUsage(false);
|
||||
player.addEffect(new Potion(PotionEffect.BLINDNESS, (byte) 0, 1000000));
|
||||
|
||||
player.setRespawnPoint(targetWorld.getSpawn());
|
||||
player.setInstance(targetWorld, targetWorld.getSpawn()).thenRun(() -> {
|
||||
player.setAllowMovement(true);
|
||||
player.clearEffects();
|
||||
player.update_lastCompassUsage();
|
||||
player.setAllowCompassUsage(true);
|
||||
});
|
||||
assert world != null;
|
||||
System.out.println("[Worldchange] Player " + player.getUsername() + " changed world from " + world.getName() + " to " + targetWorld.getName() +".");
|
||||
}
|
||||
}
|
@ -25,13 +25,9 @@ public class Config {
|
||||
if (!w.getName().equals(config.get("start_world").getAsString())) continue;
|
||||
this.start_world = w;
|
||||
}
|
||||
if (start_world == null) {
|
||||
System.out.println("no starting world set");
|
||||
System.exit(0);
|
||||
}
|
||||
this.bungeecordEnabled = config.get("bungeecord").getAsBoolean();
|
||||
|
||||
}catch (IOException e) {
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -1,70 +1,66 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.util;
|
||||
|
||||
import eu.mhsl.craftattack.worldmuseum.worlds.World;
|
||||
import eu.mhsl.craftattack.worldmuseum.worlds.WorldManager;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import net.kyori.adventure.title.Title;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.inventory.Inventory;
|
||||
import net.minestom.server.inventory.InventoryType;
|
||||
import net.minestom.server.item.Enchantment;
|
||||
import net.minestom.server.item.ItemHideFlag;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||
import net.minestom.server.network.player.PlayerConnection;
|
||||
import net.minestom.server.potion.Potion;
|
||||
import net.minestom.server.potion.PotionEffect;
|
||||
import net.minestom.server.timer.ExecutionType;
|
||||
import net.minestom.server.timer.TaskSchedule;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MuseumPlayer extends Player {
|
||||
|
||||
private boolean allowMovement = true;
|
||||
private long lastCompassUsage = 0;
|
||||
private boolean allowCompassUsage = true;
|
||||
private boolean isLoading = false;
|
||||
|
||||
public MuseumPlayer(@NotNull UUID uuid, @NotNull String username, @NotNull PlayerConnection playerConnection) {
|
||||
super(uuid, username, playerConnection);
|
||||
}
|
||||
public void setSyncCooldown(@Nullable Duration cooldown) {
|
||||
this.setCustomSynchronizationCooldown(cooldown);
|
||||
|
||||
eventNode().addListener(PlayerMoveEvent.class, playerMoveEvent -> playerMoveEvent.setCancelled(isLoading));
|
||||
}
|
||||
|
||||
public boolean isAllowMovement() {
|
||||
return allowMovement;
|
||||
}
|
||||
public void update_lastCompassUsage() {
|
||||
lastCompassUsage = System.currentTimeMillis();
|
||||
}
|
||||
public boolean isAllowCompassUsage() {
|
||||
long UsageDifference = System.currentTimeMillis() - lastCompassUsage;
|
||||
long difference = 15000; //in Milisec
|
||||
return UsageDifference >= difference && allowCompassUsage;
|
||||
}
|
||||
public void setAllowMovement(boolean allowMovement) {
|
||||
this.allowMovement = allowMovement;
|
||||
}
|
||||
public void setAllowCompassUsage(boolean allowCompassUsage) {
|
||||
this.allowCompassUsage = allowCompassUsage;
|
||||
}
|
||||
public long getLastCompassUsage() {
|
||||
return lastCompassUsage;
|
||||
}
|
||||
public Inventory getCompassInventory() {
|
||||
Inventory inventory = new Inventory(InventoryType.CHEST_1_ROW, Component.text("World-changer"));
|
||||
for (World w : WorldManager.getInstance().getWorlds()) {
|
||||
if (!w.equals(this.getInstance())) {
|
||||
inventory.addItemStack(w.getItem());
|
||||
continue;
|
||||
public void startLoading() {
|
||||
isLoading = true;
|
||||
MinecraftServer.getSchedulerManager().submitTask(() -> {
|
||||
sendMessage("" + System.currentTimeMillis());
|
||||
addEffect(new Potion(PotionEffect.BLINDNESS, (byte) 3, 600));
|
||||
showTitle(Title.title(
|
||||
Component.text("Loading").decorate(TextDecoration.BOLD).color(NamedTextColor.GOLD),
|
||||
Component.text("...").color(NamedTextColor.YELLOW),
|
||||
Title.Times.times(Duration.ZERO, Duration.ofSeconds(30), Duration.ZERO)
|
||||
));
|
||||
|
||||
if(!isLoading) {
|
||||
clearEffects();
|
||||
clearTitle();
|
||||
return TaskSchedule.stop();
|
||||
}
|
||||
ItemStack itemStack = ItemStack.builder(w.getItem().material())
|
||||
.displayName(w.getItem().getDisplayName())
|
||||
.meta(metaBuilder ->
|
||||
metaBuilder
|
||||
.enchantment(Enchantment.MENDING, (short) 10)
|
||||
.hideFlag(ItemHideFlag.HIDE_ENCHANTS))
|
||||
.build();
|
||||
inventory.addItemStack(itemStack);
|
||||
}
|
||||
return inventory;
|
||||
return TaskSchedule.millis(100);
|
||||
}, ExecutionType.ASYNC);
|
||||
}
|
||||
|
||||
public void stopLoading() {
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
public void updateFlyingSpeed(float speed) {
|
||||
speed = MathUtils.clamp(getFlyingSpeed() + speed, 0.01f, 0.2f);
|
||||
setFlyingSpeed(speed);
|
||||
sendActionBar(
|
||||
Component
|
||||
.text("Geschwindigkeit: ")
|
||||
.color(NamedTextColor.GOLD)
|
||||
.append(Component.text(Math.round(speed * 1000) + "%").color(NamedTextColor.WHITE))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -5,9 +5,7 @@ import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.adventure.audience.Audiences;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.monitoring.TickMonitor;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class TablistUpdateTask implements Runnable {
|
||||
@Override
|
||||
@ -18,7 +16,7 @@ public class TablistUpdateTask implements Runnable {
|
||||
final Component header =
|
||||
Component.newline()
|
||||
.append(Component.text(" Welten-Museum ", NamedTextColor.GOLD))
|
||||
.append(Component.newline()).append(Component.text("Players: " + players.size()))
|
||||
.append(Component.newline()).append(Component.text("Spieler: " + players.size()))
|
||||
.append(Component.newline());
|
||||
|
||||
final Component footer =
|
||||
|
@ -0,0 +1,7 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.worlds;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
|
||||
public interface PlayerMovable {
|
||||
void movePlayer(Player p);
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.worlds;
|
||||
|
||||
import eu.mhsl.craftattack.worldmuseum.inventory.WorldSelector;
|
||||
import eu.mhsl.craftattack.worldmuseum.util.MuseumPlayer;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.inventory.InventoryCloseEvent;
|
||||
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||
import net.minestom.server.instance.InstanceContainer;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.world.DimensionType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class VoidWorld extends InstanceContainer implements PlayerMovable {
|
||||
public VoidWorld() {
|
||||
super(UUID.randomUUID(), DimensionType.OVERWORLD);
|
||||
MinecraftServer.getInstanceManager().registerInstance(this);
|
||||
setBlock(getSpawn().sub(0, 1, 0), Block.BARRIER);
|
||||
|
||||
eventNode().addListener(InventoryCloseEvent.class, inventoryCloseEvent -> {
|
||||
if(inventoryCloseEvent.getPlayer().getInstance() != this) return;
|
||||
inventoryCloseEvent.setNewInventory(inventoryCloseEvent.getInventory());
|
||||
});
|
||||
|
||||
eventNode().addListener(PlayerMoveEvent.class, playerMoveEvent -> playerMoveEvent.setCancelled(true));
|
||||
}
|
||||
|
||||
public Pos getSpawn() {
|
||||
return new Pos(0, 50, 0, 0, 0);
|
||||
}
|
||||
|
||||
public void movePlayer(Player p) {
|
||||
MuseumPlayer museumPlayer = (MuseumPlayer) p;
|
||||
if(p.getInstance() != this) p.setInstance(this).thenRun(() -> {
|
||||
p.teleport(getSpawn());
|
||||
p.openInventory(new WorldSelector());
|
||||
museumPlayer.stopLoading();
|
||||
});
|
||||
|
||||
museumPlayer.startLoading();
|
||||
p.getInventory().clear();
|
||||
p.setRespawnPoint(getSpawn());
|
||||
p.setAllowFlying(false);
|
||||
}
|
||||
}
|
@ -1,78 +1,108 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.worlds;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import eu.mhsl.craftattack.worldmuseum.items.Items;
|
||||
import eu.mhsl.craftattack.worldmuseum.util.MuseumPlayer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.coordinate.Pos;
|
||||
import net.minestom.server.entity.GameMode;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.instance.AnvilLoader;
|
||||
import net.minestom.server.instance.InstanceContainer;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.Material;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import net.minestom.server.world.DimensionType;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class World extends InstanceContainer {
|
||||
public class World extends InstanceContainer implements PlayerMovable {
|
||||
private final static DimensionType dimension = DimensionType.builder(NamespaceID.from("mhsl.eu:worldview_by_olischma")).height(400).ambientLight(2.0f).build();
|
||||
private final ItemStack item;
|
||||
private String name = "default";
|
||||
private Pos spawn = new Pos(0,0,0);
|
||||
private boolean enabled = false;
|
||||
|
||||
private final boolean enabled;
|
||||
private final String name;
|
||||
private final Material material;
|
||||
private final Pos spawn;
|
||||
private final List<String> tags = new ArrayList<>();
|
||||
|
||||
|
||||
static {
|
||||
MinecraftServer.getDimensionTypeManager().addDimension(dimension);
|
||||
}
|
||||
AnvilLoader anvilLoader;
|
||||
|
||||
public World(File file) {
|
||||
public World(File file) throws IOException {
|
||||
super(UUID.randomUUID(), dimension, new AnvilLoader(file.getPath()));
|
||||
this.anvilLoader = new AnvilLoader(file.getPath());
|
||||
MinecraftServer.getInstanceManager().registerInstance(this);
|
||||
try {
|
||||
File checkFile = new File(file.getPath() + "/config.json");
|
||||
if (checkFile.createNewFile()) {
|
||||
FileWriter fileWriter = new FileWriter(file.getPath() + "/config.json");
|
||||
String defaultConfig = """
|
||||
{
|
||||
"enabled": false,
|
||||
"name": "DEFAULT_NAME",
|
||||
"material": "GRASS_BLOCK",
|
||||
"spawn": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"tags": [
|
||||
"RANDOM_TAG"
|
||||
]
|
||||
}""";
|
||||
fileWriter.write(defaultConfig);
|
||||
fileWriter.close();
|
||||
}
|
||||
} catch (IOException e){
|
||||
e.printStackTrace();
|
||||
|
||||
File configFile = new File(file.getPath() + "/config.json");
|
||||
if (configFile.createNewFile()) {
|
||||
writeDefaultConfig(file);
|
||||
}
|
||||
|
||||
Material material = Material.GRASS_BLOCK;
|
||||
try {
|
||||
JsonObject config = (JsonObject) JsonParser.parseReader(new FileReader(file.getPath() + "/config.json"));
|
||||
this.name = config.get("name").getAsString();
|
||||
JsonObject spawn = config.getAsJsonObject("spawn");
|
||||
this.spawn = new Pos(spawn.get("x").getAsDouble(), spawn.get("y").getAsDouble(), spawn.get("z").getAsDouble());
|
||||
material = Material.fromNamespaceId("minecraft:" + config.get("material").getAsString().toLowerCase());
|
||||
this.enabled = config.get("enabled").getAsBoolean();
|
||||
JsonObject config = (JsonObject) JsonParser.parseReader(new FileReader(file.getPath() + "/config.json"));
|
||||
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
assert material != null;
|
||||
item = ItemStack.builder(material).displayName(Component.text(name)).build();
|
||||
this.enabled = config.get("enabled").getAsBoolean();
|
||||
this.name = config.get("name").getAsString();
|
||||
this.material = Material.fromNamespaceId("minecraft:" + config.get("material").getAsString().toLowerCase());
|
||||
|
||||
JsonObject spawn = config.getAsJsonObject("spawn");
|
||||
this.spawn = new Pos(spawn.get("x").getAsDouble(), spawn.get("y").getAsDouble(), spawn.get("z").getAsDouble());
|
||||
|
||||
JsonArray tags = config.getAsJsonArray("tags");
|
||||
tags.forEach(jsonElement -> this.tags.add(jsonElement.getAsString()));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void movePlayer(Player player) {
|
||||
MuseumPlayer p = (MuseumPlayer) player;
|
||||
|
||||
p.startLoading();
|
||||
p.teleport(getSpawn());
|
||||
p.setInstance(this).thenRun(() -> {
|
||||
p.setRespawnPoint(getSpawn());
|
||||
p.teleport(getSpawn());
|
||||
p.setGameMode(GameMode.SURVIVAL);
|
||||
p.setAllowFlying(true);
|
||||
|
||||
p.getInventory().setItemStack(3, Items.MORE_SPEED.getItem());
|
||||
p.getInventory().setItemStack(4, Items.LESS_SPEED.getItem());
|
||||
|
||||
p.getInventory().setItemStack(7, Items.SPAWN.getItem());
|
||||
p.getInventory().setItemStack(8, Items.HUB.getItem());
|
||||
|
||||
p.stopLoading();
|
||||
});
|
||||
}
|
||||
|
||||
private void writeDefaultConfig(File file) throws IOException {
|
||||
FileWriter fileWriter = new FileWriter(file.getPath() + "/config.json");
|
||||
String defaultConfig = """
|
||||
{
|
||||
"enabled": false,
|
||||
"name": "DEFAULT_NAME",
|
||||
"material": "GRASS_BLOCK",
|
||||
"spawn": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"tags": [
|
||||
"RANDOM_TAG"
|
||||
]
|
||||
}""";
|
||||
fileWriter.write(defaultConfig);
|
||||
fileWriter.close();
|
||||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
return item;
|
||||
return ItemStack.builder(material).displayName(Component.text(name)).build();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
@ -1,7 +1,9 @@
|
||||
package eu.mhsl.craftattack.worldmuseum.worlds;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class WorldManager {
|
||||
@ -14,11 +16,11 @@ public class WorldManager {
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
public void loadWorlds() {
|
||||
public void loadWorlds() throws IOException {
|
||||
File saveDirectory = new File("saves");
|
||||
List<File> worldFolders = getFolderNames(saveDirectory);
|
||||
for (File f: worldFolders
|
||||
) {
|
||||
if(!saveDirectory.exists()) throw new IOException("Saves folder 'saves' could not be found!");
|
||||
List<File> worldFolders = getFolders(saveDirectory);
|
||||
for (File f : worldFolders) {
|
||||
World w = new World(f);
|
||||
if (w.isEnabled()) {
|
||||
worlds.add(w);
|
||||
@ -26,16 +28,14 @@ public class WorldManager {
|
||||
System.out.println("Es gibt eine nicht aktivierte Welt: " + f);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private List<File> getFolderNames(File curDir) {
|
||||
File[] fileList = curDir.listFiles();
|
||||
List<File> returnFolders = new ArrayList<>();
|
||||
assert fileList != null;
|
||||
for (File f: fileList) {
|
||||
if (f.isDirectory()) returnFolders.add(f);
|
||||
}
|
||||
return returnFolders;
|
||||
private List<File> getFolders(File directory) {
|
||||
File[] fileList = directory.listFiles();
|
||||
if(fileList == null) return new ArrayList<>();
|
||||
|
||||
return Arrays.stream(fileList).filter(File::isDirectory).toList();
|
||||
}
|
||||
|
||||
public List<World> getWorlds() {
|
||||
|
Reference in New Issue
Block a user