mirror of
https://github.com/Artillex-Studios/AxMinions.git
synced 2024-11-26 12:15:57 +01:00
More datahandler work
This commit is contained in:
parent
e5c2557586
commit
01effe18b1
@ -12,6 +12,7 @@ import com.artillexstudios.axminions.database.DataHandler;
|
||||
import com.artillexstudios.axminions.database.DatabaseConnector;
|
||||
import com.artillexstudios.axminions.listeners.BlockPlaceListener;
|
||||
import com.artillexstudios.axminions.listeners.ChunkListener;
|
||||
import com.artillexstudios.axminions.listeners.MinionPlaceListener;
|
||||
import com.artillexstudios.axminions.listeners.PlayerListener;
|
||||
import com.artillexstudios.axminions.listeners.WorldListener;
|
||||
import com.artillexstudios.axminions.minions.MinionTicker;
|
||||
@ -64,6 +65,7 @@ public final class AxMinionsPlugin extends AxPlugin {
|
||||
Bukkit.getPluginManager().registerEvents(new ChunkListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new PlayerListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new BlockPlaceListener(), this);
|
||||
Bukkit.getPluginManager().registerEvents(new MinionPlaceListener(), this);
|
||||
|
||||
if (PaperUtils.isFolia()) {
|
||||
ticker = new FoliaMinionTicker();
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.artillexstudios.axminions.command;
|
||||
|
||||
import com.artillexstudios.axapi.utils.ContainerUtils;
|
||||
import com.artillexstudios.axapi.utils.MessageUtils;
|
||||
import com.artillexstudios.axminions.AxMinionsPlugin;
|
||||
import com.artillexstudios.axminions.command.arguments.MinionLevelArgument;
|
||||
@ -14,6 +15,7 @@ import com.artillexstudios.axminions.minions.MinionArea;
|
||||
import com.artillexstudios.axminions.minions.MinionData;
|
||||
import com.artillexstudios.axminions.minions.MinionType;
|
||||
import com.artillexstudios.axminions.minions.MinionWorldCache;
|
||||
import com.artillexstudios.axminions.utils.Direction;
|
||||
import com.artillexstudios.axminions.utils.FileUtils;
|
||||
import com.artillexstudios.axminions.utils.LocationUtils;
|
||||
import dev.jorel.commandapi.CommandTree;
|
||||
@ -44,7 +46,13 @@ public final class AxMinionsCommand {
|
||||
.then(MinionTypeArgument.minionType("miniontype")
|
||||
.then(MinionLevelArgument.level("level")
|
||||
.then(new IntegerArgument("amount")
|
||||
|
||||
.executes((sender, args) -> {
|
||||
Player player = args.getByClass("player", Player.class);
|
||||
MinionType type = args.getByClass("miniontype", MinionType.class);
|
||||
Level level = args.getByClass("level", Level.class);
|
||||
Integer amount = args.getByClass("amount", Integer.class);
|
||||
handleGive(sender, player, type, level, amount);
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -102,7 +110,7 @@ public final class AxMinionsCommand {
|
||||
MinionType type = args.getByClass("miniontype", MinionType.class);
|
||||
Level level = args.getByClass("level", Level.class);
|
||||
Location location = LocationUtils.toBlockCenter(sender.getLocation());
|
||||
MinionData data = new MinionData(0, type, null, level, new ItemStack(Material.DIAMOND_PICKAXE), null, new HashMap<>());
|
||||
MinionData data = new MinionData(0, type, Direction.NORTH, null, level, 0, new ItemStack(Material.DIAMOND_PICKAXE), null, new HashMap<>());
|
||||
Minion minion = new Minion(location, data);
|
||||
minion.spawn();
|
||||
MinionArea area = MinionWorldCache.getArea(location.getWorld());
|
||||
@ -117,6 +125,8 @@ public final class AxMinionsCommand {
|
||||
}
|
||||
|
||||
private static void handleGive(CommandSender sender, Player player, MinionType type, Level level, Integer amount) {
|
||||
|
||||
ItemStack item = type.item(new MinionData(0, type, null, null, level, 0, null, null, new HashMap<>(0)));
|
||||
item.setAmount(amount);
|
||||
ContainerUtils.INSTANCE.addOrDrop(player.getInventory(), List.of(item), player.getLocation());
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
package com.artillexstudios.axminions.database;
|
||||
|
||||
import com.artillexstudios.axapi.items.WrappedItemStack;
|
||||
import com.artillexstudios.axapi.nms.NMSHandlers;
|
||||
import com.artillexstudios.axminions.config.Config;
|
||||
import com.artillexstudios.axminions.minions.Minion;
|
||||
import com.artillexstudios.axminions.minions.MinionData;
|
||||
import com.artillexstudios.axminions.minions.MinionType;
|
||||
import com.artillexstudios.axminions.utils.LogUtils;
|
||||
import com.google.common.base.Preconditions;
|
||||
@ -13,13 +15,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Record1;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.impl.DSL;
|
||||
import org.jooq.impl.SQLDataType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@ -97,7 +97,7 @@ public final class DataHandler {
|
||||
|
||||
futures.add(locations.toCompletableFuture());
|
||||
|
||||
CompletionStage<Integer> minions = DatabaseConnector.getInstance().context().createTableIfNotExists(Tables.LOCATIONS)
|
||||
CompletionStage<Integer> minions = DatabaseConnector.getInstance().context().createTableIfNotExists(Tables.MINIONS)
|
||||
.column(Fields.ID, SQLDataType.INTEGER.identity(true))
|
||||
.column(Fields.LOCATION_ID, SQLDataType.INTEGER)
|
||||
.column(Fields.OWNER_ID, SQLDataType.INTEGER)
|
||||
@ -160,7 +160,7 @@ public final class DataHandler {
|
||||
}
|
||||
|
||||
Record1<Integer> insert = DatabaseConnector.getInstance().context()
|
||||
.insertInto(Tables.TYPES)
|
||||
.insertInto(Tables.WORLDS)
|
||||
.set(Fields.WORLD_UUID, world.getUID())
|
||||
.returningResult(Fields.ID)
|
||||
.fetchOne();
|
||||
@ -172,22 +172,6 @@ public final class DataHandler {
|
||||
return insert.get(Fields.ID);
|
||||
}
|
||||
|
||||
public static int ownerId(Player player) {
|
||||
Result<Record> select = DatabaseConnector.getInstance().context()
|
||||
.select()
|
||||
.from(Tables.USERS)
|
||||
.where(Fields.UUID.eq(player.getUniqueId()))
|
||||
.fetch();
|
||||
|
||||
if (!select.isEmpty()) {
|
||||
Record record = select.get(0);
|
||||
LogUtils.debug("World select record: {}", record);
|
||||
return (Integer) record.get("ID");
|
||||
}
|
||||
|
||||
return FAILED_QUERY;
|
||||
}
|
||||
|
||||
public static int locationId(int world, Location location) {
|
||||
Result<Record> select = DatabaseConnector.getInstance().context()
|
||||
.select()
|
||||
@ -205,7 +189,7 @@ public final class DataHandler {
|
||||
}
|
||||
|
||||
Record1<Integer> insert = DatabaseConnector.getInstance().context()
|
||||
.insertInto(Tables.TYPES)
|
||||
.insertInto(Tables.LOCATIONS)
|
||||
.set(Fields.WORLD_ID, world)
|
||||
.set(Fields.LOCATION_X, location.getBlockX())
|
||||
.set(Fields.LOCATION_Y, location.getBlockY())
|
||||
@ -242,7 +226,13 @@ public final class DataHandler {
|
||||
DatabaseConnector.getInstance().context()
|
||||
.insertInto(Tables.MINIONS)
|
||||
.set(Fields.LOCATION_ID, locationId)
|
||||
.set(Fields.OWNER_ID, locationId)
|
||||
.set(Fields.OWNER_ID, minion.ownerId())
|
||||
.set(Fields.TYPE_ID, minion.type().id())
|
||||
.set(Fields.LEVEL, minion.level().id())
|
||||
.set(Fields.CHARGE, minion.charge())
|
||||
.set(Fields.FACING, minion.facing().ordinal())
|
||||
.set(Fields.TOOL, minion.tool() == null || minion.tool().getType().isAir() ? null : WrappedItemStack.wrap(minion.tool()).serialize())
|
||||
.set(Fields.EXTRA_DATA, MinionData.serialize(minion.extraData()))
|
||||
.execute();
|
||||
}, databaseExecutor).exceptionallyAsync(throwable -> {
|
||||
log.error("An unexpected error occurred while inserting minion!", throwable);
|
||||
|
@ -7,7 +7,7 @@ import org.jooq.impl.DSL;
|
||||
public final class Tables {
|
||||
public static final Table<Record> USERS = DSL.table("axminions_users");
|
||||
public static final Table<Record> TYPES = DSL.table("axminions_types");
|
||||
public static final Table<Record> WORLDS = DSL.table("axminions_locations");
|
||||
public static final Table<Record> WORLDS = DSL.table("axminions_worlds");
|
||||
public static final Table<Record> LOCATIONS = DSL.table("axminions_locations");
|
||||
public static final Table<Record> MINIONS = DSL.table("axminions_minions");
|
||||
}
|
||||
|
@ -1,13 +1,91 @@
|
||||
package com.artillexstudios.axminions.listeners;
|
||||
|
||||
import com.artillexstudios.axapi.items.WrappedItemStack;
|
||||
import com.artillexstudios.axapi.items.component.DataComponents;
|
||||
import com.artillexstudios.axapi.items.nbt.CompoundTag;
|
||||
import com.artillexstudios.axminions.config.Minions;
|
||||
import com.artillexstudios.axminions.database.DataHandler;
|
||||
import com.artillexstudios.axminions.minions.Level;
|
||||
import com.artillexstudios.axminions.minions.Minion;
|
||||
import com.artillexstudios.axminions.minions.MinionArea;
|
||||
import com.artillexstudios.axminions.minions.MinionData;
|
||||
import com.artillexstudios.axminions.minions.MinionType;
|
||||
import com.artillexstudios.axminions.minions.MinionTypes;
|
||||
import com.artillexstudios.axminions.minions.MinionWorldCache;
|
||||
import com.artillexstudios.axminions.utils.Direction;
|
||||
import com.artillexstudios.axminions.utils.LogUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public final class MinionPlaceListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerInteractEvent(PlayerInteractEvent event) {
|
||||
LogUtils.debug("MinionPlaceListener - PlayerInteractEvent");
|
||||
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
|
||||
LogUtils.debug("Not right click block, but {}.", event.getAction());
|
||||
return;
|
||||
}
|
||||
|
||||
Block clickedBlock = event.getClickedBlock();
|
||||
if (clickedBlock == null) {
|
||||
LogUtils.debug("Clicked block is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
EquipmentSlot hand = event.getHand();
|
||||
if (hand == null) {
|
||||
LogUtils.debug("Hand is null!");
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack itemStack = event.getPlayer().getInventory().getItem(hand);
|
||||
if (itemStack == null || itemStack.getType().isAir()) {
|
||||
LogUtils.debug("Item is either null, or air!");
|
||||
return;
|
||||
}
|
||||
|
||||
WrappedItemStack wrappedItemStack = WrappedItemStack.wrap(itemStack);
|
||||
CompoundTag compoundTag = wrappedItemStack.get(DataComponents.customData());
|
||||
if (!compoundTag.contains("axminions_minion_type")) {
|
||||
LogUtils.debug("Does not contain miniontype");
|
||||
return;
|
||||
}
|
||||
|
||||
String typeName = compoundTag.getString("axminions_minion_type");
|
||||
if (typeName == null || typeName.isBlank()) {
|
||||
LogUtils.warn("ItemStack in {}'s hand is an invalid minion; the miniontype is empty!", event.getPlayer().getName());
|
||||
return;
|
||||
}
|
||||
|
||||
MinionType minionType = MinionTypes.parse(typeName);
|
||||
if (minionType == null) {
|
||||
LogUtils.warn("ItemStack in {}'s hand is an invalid minion; no miniontype with id {} is loaded!", typeName);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: level
|
||||
itemStack.setAmount(itemStack.getAmount() - 1);
|
||||
Location location = clickedBlock.getRelative(event.getBlockFace()).getLocation();
|
||||
// TODO: Database queries, etc..
|
||||
// TODO: ownerId
|
||||
MinionData data = new MinionData(0, minionType, Direction.NORTH, null, minionType.level(1), 0, null, null, new HashMap<>());
|
||||
Minion minion = new Minion(location, data);
|
||||
MinionArea area = MinionWorldCache.getArea(location.getWorld());
|
||||
MinionWorldCache.add(minion);
|
||||
DataHandler.insertMinion(minion).thenRun(() -> {
|
||||
LogUtils.debug("Inserted minion!");
|
||||
});
|
||||
minion.spawn();
|
||||
area.startTicking(location.getChunk());
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import com.artillexstudios.axapi.utils.EquipmentSlot;
|
||||
import com.artillexstudios.axminions.config.Config;
|
||||
import com.artillexstudios.axminions.integrations.Integrations;
|
||||
import com.artillexstudios.axminions.minions.skins.Skin;
|
||||
import com.artillexstudios.axminions.utils.Direction;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -83,6 +84,22 @@ public final class Minion {
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> extraData() {
|
||||
return this.minionData.extraData();
|
||||
}
|
||||
|
||||
public Direction facing() {
|
||||
return this.minionData.direction();
|
||||
}
|
||||
|
||||
public long charge() {
|
||||
return this.minionData.charge();
|
||||
}
|
||||
|
||||
public int ownerId() {
|
||||
return this.minionData.ownerId();
|
||||
}
|
||||
|
||||
public ItemStack tool() {
|
||||
return this.minionData.tool();
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.artillexstudios.axminions.minions;
|
||||
|
||||
import com.artillexstudios.axminions.minions.skins.Skin;
|
||||
import com.artillexstudios.axminions.utils.CollectionUtils;
|
||||
import com.artillexstudios.axminions.utils.Direction;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@ -10,15 +11,16 @@ import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
// The data needed to spawn a minion
|
||||
public record MinionData(int ownerId, MinionType type, Location linkedChest, Level level, ItemStack tool, Skin skin, HashMap<String, String> storage) {
|
||||
public record MinionData(int ownerId, MinionType type, Direction direction, Location linkedChest, Level level,
|
||||
long charge, ItemStack tool, Skin skin, HashMap<String, String> extraData) {
|
||||
private static final Pattern SEMICOLON = Pattern.compile(";");
|
||||
private static final Pattern DASH = Pattern.compile("-");
|
||||
|
||||
public MinionData withSkin(Skin skin) {
|
||||
return new MinionData(this.ownerId, this.type, this.linkedChest, this.level, this.tool, skin, this.storage);
|
||||
}
|
||||
|
||||
public static String serialize(Map<String, String> map) {
|
||||
if (map.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
builder.append(entry.getKey()).append('-').append(entry.getValue()).append(';');
|
||||
@ -28,9 +30,9 @@ public record MinionData(int ownerId, MinionType type, Location linkedChest, Lev
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static Map<String, String> deserialize(String string) {
|
||||
if (string.isBlank() || !string.contains("-")) {
|
||||
return Map.of();
|
||||
public static HashMap<String, String> deserialize(String string) {
|
||||
if (string.isEmpty()) {
|
||||
return new HashMap<>(0);
|
||||
}
|
||||
|
||||
String[] split = SEMICOLON.split(string);
|
||||
@ -43,4 +45,8 @@ public record MinionData(int ownerId, MinionType type, Location linkedChest, Lev
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
public MinionData withSkin(Skin skin) {
|
||||
return new MinionData(this.ownerId, this.type, this.direction, this.linkedChest, this.level, this.charge, this.tool, skin, this.extraData);
|
||||
}
|
||||
}
|
||||
|
@ -93,6 +93,8 @@ public final class MinionType {
|
||||
CompoundTag tag = wrappedItemStack.get(DataComponents.customData());
|
||||
// TODO: Store statistics, level, etc
|
||||
tag.putString("axminions_minion_type", this.name);
|
||||
wrappedItemStack.set(DataComponents.customData(), tag);
|
||||
wrappedItemStack.finishEdit();
|
||||
return wrappedItemStack.toBukkit();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
package com.artillexstudios.axminions.utils;
|
||||
|
||||
import org.bukkit.block.BlockFace;
|
||||
|
||||
public enum Direction {
|
||||
NORTH(180f, BlockFace.NORTH),
|
||||
WEST(90f, BlockFace.WEST),
|
||||
SOUTH(0f, BlockFace.SOUTH),
|
||||
EAST(-90f, BlockFace.EAST);
|
||||
|
||||
private final float yaw;
|
||||
private final BlockFace face;
|
||||
|
||||
Direction(float yaw, BlockFace face) {
|
||||
this.yaw = yaw;
|
||||
this.face = face;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user