geforkt von Mirrors/AxiomPaperPlugin
Finish world properties, add WorldPropertiesExample
Dieser Commit ist enthalten in:
Ursprung
f88d558f88
Commit
59cf7b49b9
@ -1,8 +1,13 @@
|
||||
package com.moulberry.axiom;
|
||||
|
||||
import com.moulberry.axiom.buffer.CompressedBlockEntity;
|
||||
import com.moulberry.axiom.event.AxiomCreateWorldPropertiesEvent;
|
||||
import com.moulberry.axiom.event.AxiomTimeChangeEvent;
|
||||
import com.moulberry.axiom.packet.*;
|
||||
import com.moulberry.axiom.world_properties.WorldPropertyCategory;
|
||||
import com.moulberry.axiom.world_properties.WorldPropertyWidgetType;
|
||||
import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry;
|
||||
import com.moulberry.axiom.world_properties.server.ServerWorldProperty;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.papermc.paper.event.player.PlayerFailMoveEvent;
|
||||
@ -15,6 +20,7 @@ import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.PacketFlow;
|
||||
import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -24,15 +30,23 @@ import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.plugin.messaging.Messenger;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class AxiomPaper extends JavaPlugin implements Listener {
|
||||
|
||||
public static AxiomPaper PLUGIN; // tsk tsk tsk
|
||||
|
||||
public final Set<UUID> activeAxiomPlayers = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
PLUGIN = this;
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(this, this);
|
||||
// Bukkit.getPluginManager().registerEvents(new WorldPropertiesExample(), this);
|
||||
CompressedBlockEntity.initialize(this);
|
||||
|
||||
Messenger msg = Bukkit.getMessenger();
|
||||
@ -42,13 +56,14 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:set_editor_views");
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:block_entities");
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:register_world_properties");
|
||||
|
||||
final Set<UUID> activeAxiomPlayers = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:set_world_property");
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:ack_world_properties");
|
||||
|
||||
msg.registerIncomingPluginChannel(this, "axiom:hello", new HelloPacketListener(this, activeAxiomPlayers));
|
||||
msg.registerIncomingPluginChannel(this, "axiom:set_gamemode", new SetGamemodePacketListener());
|
||||
msg.registerIncomingPluginChannel(this, "axiom:set_fly_speed", new SetFlySpeedPacketListener());
|
||||
msg.registerIncomingPluginChannel(this, "axiom:set_world_time", new SetTimePacketListener());
|
||||
msg.registerIncomingPluginChannel(this, "axiom:set_world_property", new SetWorldPropertyListener());
|
||||
msg.registerIncomingPluginChannel(this, "axiom:set_block", new SetBlockPacketListener(this));
|
||||
msg.registerIncomingPluginChannel(this, "axiom:set_hotbar_slot", new SetHotbarSlotPacketListener());
|
||||
msg.registerIncomingPluginChannel(this, "axiom:switch_active_hotbar", new SwitchActiveHotbarPacketListener());
|
||||
@ -99,6 +114,18 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
||||
}, 20, 20);
|
||||
}
|
||||
|
||||
private final WeakHashMap<World, ServerWorldPropertiesRegistry> worldProperties = new WeakHashMap<>();
|
||||
|
||||
public @Nullable ServerWorldPropertiesRegistry getWorldProperties(World world) {
|
||||
if (worldProperties.containsKey(world)) {
|
||||
return worldProperties.get(world);
|
||||
} else {
|
||||
ServerWorldPropertiesRegistry properties = createWorldProperties(world);
|
||||
worldProperties.put(world, properties);
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onFailMove(PlayerFailMoveEvent event) {
|
||||
if (event.getPlayer().hasPermission("axiom.*") &&
|
||||
@ -107,25 +134,43 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
private final WeakHashMap<World, ServerWorldPropertiesRegistry> worldProperties = new WeakHashMap<>();
|
||||
|
||||
@EventHandler
|
||||
public void onChangedWorld(PlayerChangedWorldEvent event) {
|
||||
System.out.println("Changed world!");
|
||||
|
||||
World world = event.getPlayer().getWorld();
|
||||
ServerWorldPropertiesRegistry properties = worldProperties.computeIfAbsent(world, k -> new ServerWorldPropertiesRegistry());
|
||||
|
||||
ServerWorldPropertiesRegistry properties = getWorldProperties(world);
|
||||
|
||||
if (properties == null) {
|
||||
event.getPlayer().sendPluginMessage(this, "axiom:register_world_properties", new byte[]{0});
|
||||
} else {
|
||||
properties.registerFor(this, event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(this, () -> {
|
||||
World world = player.getWorld();
|
||||
ServerWorldPropertiesRegistry properties = worldProperties.computeIfAbsent(world, k -> new ServerWorldPropertiesRegistry());
|
||||
|
||||
ServerWorldPropertiesRegistry properties = getWorldProperties(world);
|
||||
|
||||
if (properties == null) {
|
||||
player.sendPluginMessage(this, "axiom:register_world_properties", new byte[]{0});
|
||||
} else {
|
||||
properties.registerFor(this, player);
|
||||
}
|
||||
}, 20); // Why does this need to be delayed?
|
||||
}
|
||||
|
||||
private ServerWorldPropertiesRegistry createWorldProperties(World world) {
|
||||
ServerWorldPropertiesRegistry registry = new ServerWorldPropertiesRegistry();
|
||||
|
||||
AxiomCreateWorldPropertiesEvent createEvent = new AxiomCreateWorldPropertiesEvent(world, registry);
|
||||
Bukkit.getPluginManager().callEvent(createEvent);
|
||||
if (createEvent.isCancelled()) return null;
|
||||
|
||||
return registry;
|
||||
}
|
||||
|
||||
}
|
||||
|
55
src/main/java/com/moulberry/axiom/WorldPropertiesExample.java
Normale Datei
55
src/main/java/com/moulberry/axiom/WorldPropertiesExample.java
Normale Datei
@ -0,0 +1,55 @@
|
||||
package com.moulberry.axiom;
|
||||
|
||||
import com.moulberry.axiom.event.AxiomCreateWorldPropertiesEvent;
|
||||
import com.moulberry.axiom.world_properties.WorldPropertyCategory;
|
||||
import com.moulberry.axiom.world_properties.WorldPropertyWidgetType;
|
||||
import com.moulberry.axiom.world_properties.server.ServerWorldProperty;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Unit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WorldPropertiesExample implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onCreateWorldProperties(AxiomCreateWorldPropertiesEvent event) {
|
||||
WorldPropertyCategory category = new WorldPropertyCategory("Examples", false);
|
||||
|
||||
World world = event.getWorld();
|
||||
|
||||
ServerWorldProperty<Boolean> checkbox = new ServerWorldProperty<>(new ResourceLocation("axiom:checkbox"),
|
||||
"Checkbox",
|
||||
false, WorldPropertyWidgetType.CHECKBOX, false, bool -> {
|
||||
world.sendMessage(Component.text("Checkbox: " + bool)); // Do something with input
|
||||
return true; // true to sync with client
|
||||
});
|
||||
|
||||
ServerWorldProperty<Integer> slider = new ServerWorldProperty<>(new ResourceLocation("axiom:slider"),
|
||||
"Slider",
|
||||
false, new WorldPropertyWidgetType.Slider(0, 8), 4, integer -> {
|
||||
world.sendMessage(Component.text("Slider: " + integer)); // Do something with input
|
||||
return true; // true to sync with client
|
||||
});
|
||||
|
||||
ServerWorldProperty<String> textbox = new ServerWorldProperty<>(new ResourceLocation("axiom:textbox"),
|
||||
"Textbox",
|
||||
false, WorldPropertyWidgetType.TEXTBOX, "Hello", string -> {
|
||||
world.sendMessage(Component.text("Textbox: " + string)); // Do something with input
|
||||
return true; // true to sync with client
|
||||
});
|
||||
|
||||
ServerWorldProperty<Unit> button = new ServerWorldProperty<>(new ResourceLocation("axiom:button"),
|
||||
"Button",
|
||||
false, WorldPropertyWidgetType.BUTTON, Unit.INSTANCE, unit -> {
|
||||
world.sendMessage(Component.text("Button pressed")); // Do something with input
|
||||
return true; // true to sync with client
|
||||
});
|
||||
|
||||
event.addCategory(category, List.of(checkbox, slider, textbox, button));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.moulberry.axiom.event;
|
||||
|
||||
import com.moulberry.axiom.world_properties.WorldPropertyCategory;
|
||||
import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry;
|
||||
import com.moulberry.axiom.world_properties.server.ServerWorldProperty;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AxiomCreateWorldPropertiesEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList HANDLERS = new HandlerList();
|
||||
|
||||
private final World world;
|
||||
private final ServerWorldPropertiesRegistry registry;
|
||||
private boolean cancelled = false;
|
||||
|
||||
public AxiomCreateWorldPropertiesEvent(World world, ServerWorldPropertiesRegistry registry) {
|
||||
this.world = world;
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public void addCategory(WorldPropertyCategory category, List<ServerWorldProperty<?>> properties) {
|
||||
this.registry.addCategory(category, properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.cancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull HandlerList getHandlers() {
|
||||
return HANDLERS;
|
||||
}
|
||||
|
||||
}
|
@ -60,7 +60,6 @@ public class HelloPacketListener implements PluginMessageListener {
|
||||
// Enable
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||
buf.writeBoolean(true);
|
||||
buf.writeByte(0); // todo: world properties
|
||||
buf.writeInt(handshakeEvent.getMaxBufferSize()); // Max Buffer Size
|
||||
buf.writeBoolean(false); // No source info
|
||||
buf.writeBoolean(false); // No source settings
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.moulberry.axiom.packet;
|
||||
|
||||
import com.moulberry.axiom.event.AxiomFlySpeedChangeEvent;
|
||||
import com.moulberry.axiom.event.AxiomTimeChangeEvent;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
@ -11,7 +10,6 @@ import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -25,7 +23,7 @@ public class SetTimePacketListener implements PluginMessageListener {
|
||||
}
|
||||
|
||||
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message));
|
||||
ResourceKey<Level> key = friendlyByteBuf.readResourceKey(Registries.DIMENSION); // Ignore
|
||||
ResourceKey<Level> key = friendlyByteBuf.readResourceKey(Registries.DIMENSION);
|
||||
Integer time = friendlyByteBuf.readNullable(FriendlyByteBuf::readInt);
|
||||
Boolean freezeTime = friendlyByteBuf.readNullable(FriendlyByteBuf::readBoolean);
|
||||
|
||||
|
@ -0,0 +1,53 @@
|
||||
package com.moulberry.axiom.packet;
|
||||
|
||||
import com.moulberry.axiom.AxiomPaper;
|
||||
import com.moulberry.axiom.event.AxiomTimeChangeEvent;
|
||||
import com.moulberry.axiom.world_properties.WorldPropertyCategory;
|
||||
import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry;
|
||||
import com.moulberry.axiom.world_properties.server.ServerWorldProperty;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SetWorldPropertyListener implements PluginMessageListener {
|
||||
|
||||
@Override
|
||||
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message) {
|
||||
if (!player.hasPermission("axiom.*")) {
|
||||
return;
|
||||
}
|
||||
|
||||
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message));
|
||||
ResourceLocation id = friendlyByteBuf.readResourceLocation();
|
||||
int type = friendlyByteBuf.readVarInt();
|
||||
byte[] data = friendlyByteBuf.readByteArray();
|
||||
int updateId = friendlyByteBuf.readVarInt();
|
||||
|
||||
ServerWorldPropertiesRegistry registry = AxiomPaper.PLUGIN.getWorldProperties(player.getWorld());
|
||||
if (registry == null) return;
|
||||
|
||||
ServerWorldProperty<?> property = registry.getById(id);
|
||||
if (property != null && property.getType().getTypeId() == type) {
|
||||
property.update(player.getWorld(), data);
|
||||
}
|
||||
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||
buf.writeVarInt(updateId);
|
||||
player.sendPluginMessage(AxiomPaper.PLUGIN, "axiom:ack_world_properties",
|
||||
buf.accessByteBufWithCorrectSize());
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ package com.moulberry.axiom.world_properties;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
@ -108,4 +109,21 @@ public abstract class WorldPropertyDataType<T> {
|
||||
}
|
||||
};
|
||||
|
||||
public static WorldPropertyDataType<Unit> EMPTY = new WorldPropertyDataType<>() {
|
||||
@Override
|
||||
public int getTypeId() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] serialize(Unit value) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Unit deserialize(byte[] bytes) {
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,23 +1,14 @@
|
||||
package com.moulberry.axiom.world_properties;
|
||||
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.Unit;
|
||||
|
||||
public interface WorldPropertyWidgetType<T> {
|
||||
|
||||
WorldPropertyDataType<T> dataType();
|
||||
void write(FriendlyByteBuf friendlyByteBuf);
|
||||
|
||||
static WorldPropertyWidgetType<?> read(FriendlyByteBuf friendlyByteBuf) {
|
||||
int type = friendlyByteBuf.readVarInt();
|
||||
return switch (type) {
|
||||
case 0 -> CHECKBOX;
|
||||
case 1 -> new Slider(friendlyByteBuf.readInt(), friendlyByteBuf.readInt());
|
||||
case 2 -> TEXTBOX;
|
||||
case 3 -> TIME;
|
||||
default -> throw new RuntimeException("Unknown widget type: " + type);
|
||||
};
|
||||
}
|
||||
|
||||
WorldPropertyWidgetType<Boolean> CHECKBOX = new WorldPropertyWidgetType<>() {
|
||||
@Override
|
||||
public WorldPropertyDataType<Boolean> dataType() {
|
||||
@ -68,4 +59,17 @@ public interface WorldPropertyWidgetType<T> {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
WorldPropertyWidgetType<Unit> BUTTON = new WorldPropertyWidgetType<>() {
|
||||
@Override
|
||||
public WorldPropertyDataType<Unit> dataType() {
|
||||
return WorldPropertyDataType.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(FriendlyByteBuf friendlyByteBuf) {
|
||||
friendlyByteBuf.writeVarInt(4);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
package com.moulberry.axiom.world_properties.server;
|
||||
|
||||
import com.moulberry.axiom.AxiomPaper;
|
||||
import com.moulberry.axiom.world_properties.WorldPropertyCategory;
|
||||
import com.moulberry.axiom.world_properties.WorldPropertyDataType;
|
||||
import com.moulberry.axiom.world_properties.WorldPropertyWidgetType;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@ -36,22 +39,37 @@ public class ServerWorldProperty<T> {
|
||||
return this.widget.dataType();
|
||||
}
|
||||
|
||||
public void update(ServerLevel serverLevel, byte[] data) {
|
||||
public void update(World world, byte[] data) {
|
||||
this.value = this.widget.dataType().deserialize(data);
|
||||
if (this.handler.test(this.value)) {
|
||||
// AxiomClientboundSetWorldProperty packet = new AxiomClientboundSetWorldProperty(this.id,
|
||||
// this.widget.dataType().getTypeId(), this.widget.dataType().serialize(this.value));
|
||||
|
||||
// for (ServerPlayer player : serverLevel.players()) {
|
||||
// if (player.hasPermissions(2)) packet.send(player);
|
||||
// }
|
||||
this.sync(world);
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(T value) {
|
||||
public void setValueWithoutSyncing(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void setValue(World world, T value) {
|
||||
this.value = value;
|
||||
this.sync(world);
|
||||
}
|
||||
|
||||
public void sync(World world) {
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||
|
||||
buf.writeResourceLocation(this.id);
|
||||
buf.writeVarInt(this.widget.dataType().getTypeId());
|
||||
buf.writeByteArray(this.widget.dataType().serialize(this.value));
|
||||
|
||||
byte[] message = buf.accessByteBufWithCorrectSize();
|
||||
for (Player player : world.getPlayers()) {
|
||||
if (AxiomPaper.PLUGIN.activeAxiomPlayers.contains(player.getUniqueId())) {
|
||||
player.sendPluginMessage(AxiomPaper.PLUGIN, "axiom:set_world_property", message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void write(FriendlyByteBuf friendlyByteBuf) {
|
||||
friendlyByteBuf.writeResourceLocation(this.id);
|
||||
friendlyByteBuf.writeUtf(this.name);
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren