Some work

This commit is contained in:
TomTom 2024-07-24 18:01:33 +02:00
parent e7f0e580a3
commit f55c83ef0a
8 changed files with 122 additions and 14 deletions

View File

@ -15,7 +15,7 @@ repositories {
}
dependencies {
implementation("com.artillexstudios.axapi:axapi:1.4.310:all")
implementation("com.artillexstudios.axapi:axapi:1.4.314:all")
implementation("dev.jorel:commandapi-bukkit-shade:9.5.0")
implementation("org.bstats:bstats-bukkit:3.0.2")
compileOnly("com.github.ben-manes.caffeine:caffeine:3.1.8")

View File

@ -55,7 +55,13 @@ public final class AxMinionsPlugin extends AxPlugin {
}
DataHandler.setup().thenRun(() -> LogUtils.debug("Loaded database!"));
this.reload();
for (World world : Bukkit.getWorlds()) {
DataHandler.loadMinions(world).toCompletableFuture().thenAccept(loaded -> {
LogUtils.debug("Loaded {} minions in world {} in {} ms!", loaded.firstInt(), world.getName(), loaded.secondLong() / 1_000_000);
});
}
for (World world : Bukkit.getWorlds()) {
MinionWorldCache.loadArea(world);

View File

@ -3,11 +3,17 @@ 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.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 com.google.common.base.Preconditions;
import it.unimi.dsi.fastutil.ints.IntLongPair;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
@ -15,6 +21,7 @@ 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;
@ -156,7 +163,7 @@ public final class DataHandler {
if (!select.isEmpty()) {
Record record = select.get(0);
LogUtils.debug("World select record: {}", record);
return (Integer) record.get("ID");
return record.get(Fields.ID);
}
Record1<Integer> insert = DatabaseConnector.getInstance().context()
@ -185,7 +192,7 @@ public final class DataHandler {
if (!select.isEmpty()) {
Record record = select.get(0);
LogUtils.debug("Location select record: {}", record);
return (Integer) record.get("ID");
return record.get(Fields.ID);
}
Record1<Integer> insert = DatabaseConnector.getInstance().context()
@ -204,6 +211,14 @@ public final class DataHandler {
return insert.get(Fields.ID);
}
public static String minionType(short id) {
return DatabaseConnector.getInstance().context()
.select()
.from(Tables.TYPES)
.where(Fields.ID.eq((int) id))
.fetchSingle(Fields.NAME);
}
public static CompletionStage<Void> insertMinion(Minion minion) {
return CompletableFuture.runAsync(() -> {
World world = minion.location().getWorld();
@ -240,6 +255,72 @@ public final class DataHandler {
});
}
public static CompletionStage<IntLongPair> loadMinions(World world) {
return CompletableFuture.supplyAsync(() -> {
int loadedMinions = 0;
long start = System.nanoTime();
int worldId = worldId(world);
if (worldId == FAILED_QUERY) {
log.error("Failed worldId fetching when loading minions!");
return IntLongPair.of(0, 0);
}
Result<Record> locations = DatabaseConnector.getInstance().context()
.select()
.from(Tables.LOCATIONS)
.where(Fields.WORLD_ID.eq(worldId))
.fetch();
for (Record location : locations) {
int id = location.get(Fields.ID);
Result<Record> minions = DatabaseConnector.getInstance().context()
.select()
.from(Tables.MINIONS)
.where(Fields.LOCATION_ID.eq(id))
.fetch();
if (minions.isEmpty()) {
continue;
}
Record record = minions.get(0);
short typeId = record.get(Fields.TYPE_ID, short.class);
int x = location.get(Fields.LOCATION_X, int.class);
int y = location.get(Fields.LOCATION_Y, int.class);
int z = location.get(Fields.LOCATION_Z, int.class);
MinionType type = MinionTypes.parse(typeId);
if (type == null) {
LogUtils.warn("Failed to load minion in world {} at ({};{};{})! Unregistered miniontype: {}", world.getName(), x, y, z, minionType(typeId));
continue;
}
int ownerId = record.get(Fields.OWNER_ID, int.class);
short level = record.get(Fields.LEVEL, short.class);
long charge = record.get(Fields.CHARGE, long.class);
short facing = record.get(Fields.FACING, short.class);
byte[] tool = record.get(Fields.TOOL, byte[].class);
String extraData = record.get(Fields.EXTRA_DATA, String.class);
Level minionLevel = type.level(level);
if (minionLevel == null) {
LogUtils.warn("Failed to load minion in world {} at ({};{};{})! Level does not exist: {}", world.getName(), x, y, z, level);
continue;
}
MinionData data = new MinionData(ownerId, type, Direction.entries[facing], null, minionLevel, charge, WrappedItemStack.wrap(tool).toBukkit(), null, MinionData.deserialize(extraData));
Minion minion = new Minion(new Location(world, x, y, z), data);
MinionWorldCache.add(minion);
minion.spawn();
loadedMinions++;
}
long took = System.nanoTime() - start;
return IntLongPair.of(loadedMinions, took);
}, databaseExecutor).exceptionallyAsync(throwable -> {
log.error("An unexpected error occurred while loading minions in world {}!", world.getName(), throwable);
return IntLongPair.of(0, 0);
});
}
public static CompletionStage<Integer> insertType(MinionType type) {
Preconditions.checkNotNull(type, "Tried to insert null miniontype");
return CompletableFuture.supplyAsync(() -> {
@ -252,7 +333,7 @@ public final class DataHandler {
if (!select.isEmpty()) {
Record record = select.get(0);
LogUtils.debug("select record: {}", record);
return (Integer) record.get("ID");
return record.get(Fields.ID);
}
Record1<Integer> insert = DatabaseConnector.getInstance().context()

View File

@ -12,8 +12,8 @@ public final class DefaultBlockIntegrable implements BlockIntegrable {
@Override
public Collection<ItemStack> lootAndBreak(Location location, ItemStack itemStack) {
Block block = location.getBlock();
Collection<ItemStack> drops = block.getDrops(itemStack);
block.setType(Material.AIR, true);
return drops;
}

View File

@ -11,6 +11,7 @@ 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.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.EulerAngle;
@ -20,6 +21,7 @@ import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
public final class Minion {
private static final ItemStack AIR = new ItemStack(Material.AIR);
private final Location location;
private final PacketEntity entity;
private final AtomicBoolean needsSaving = new AtomicBoolean(false);
@ -101,7 +103,7 @@ public final class Minion {
}
public ItemStack tool() {
return this.minionData.tool();
return this.minionData.tool() == null ? AIR : this.minionData.tool();
}
public Level level() {

View File

@ -1,5 +1,7 @@
package com.artillexstudios.axminions.minions;
import com.artillexstudios.axminions.utils.LogUtils;
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -10,6 +12,7 @@ import java.util.concurrent.ConcurrentHashMap;
public final class MinionTypes {
private static final ConcurrentHashMap<String, MinionType> TYPES = new ConcurrentHashMap<>(8);
private static final Short2ObjectOpenHashMap<MinionType> TYPE_IDS = new Short2ObjectOpenHashMap<>(8);
private static final Collection<String> KEY_SET = Collections.unmodifiableCollection(TYPES.keySet());
private static final Logger log = LoggerFactory.getLogger(MinionTypes.class);
@ -21,6 +24,12 @@ public final class MinionTypes {
}
TYPES.put(lowercase, minionType);
TYPE_IDS.put((short) minionType.id(), minionType);
LogUtils.debug("Put {} to {}", minionType.name(), (short) minionType.id());
}
public static MinionType parse(short id) {
return TYPE_IDS.get(id);
}
public static MinionType parse(String minionType) {

View File

@ -1,5 +1,9 @@
package com.artillexstudios.axminions.minions.actions.effects.implementation;
import com.artillexstudios.axapi.loot.LootContextParamSets;
import com.artillexstudios.axapi.loot.LootContextParams;
import com.artillexstudios.axapi.loot.LootParams;
import com.artillexstudios.axapi.loot.LootTables;
import com.artillexstudios.axapi.nms.NMSHandlers;
import com.artillexstudios.axminions.minions.Minion;
import com.artillexstudios.axminions.minions.actions.effects.Effect;
@ -8,12 +12,9 @@ import com.artillexstudios.axminions.utils.LogUtils;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.loot.LootContext;
import org.bukkit.loot.LootTables;
import java.util.Collection;
import java.util.Map;
import java.util.Random;
public class DamageEntityEffect extends Effect<Entity, ItemCollection> {
private static final Player dummyPlayer = NMSHandlers.getNmsHandler().dummyPlayer();
@ -24,11 +25,19 @@ public class DamageEntityEffect extends Effect<Entity, ItemCollection> {
@Override
public ItemCollection run(Minion minion, Entity argument) {
Collection<ItemStack> items = LootTables.ZOMBIE.getLootTable().populateLoot(new Random(), new LootContext.Builder(argument.getLocation())
.killer(dummyPlayer)
.lootedEntity(argument)
.build()
);
dummyPlayer.getInventory().setItemInMainHand(minion.tool());
LootParams params = new LootParams.Builder(argument.getWorld())
.withParameter(LootContextParams.THIS_ENTITY, argument)
.withParameter(LootContextParams.ORIGIN, argument.getLocation())
.withParameter(LootContextParams.DAMAGE_SOURCE, dummyPlayer)
.withParameter(LootContextParams.ATTACKING_ENTITY, dummyPlayer)
.withParameter(LootContextParams.DIRECT_ATTACKING_ENTITY, dummyPlayer)
.withParameter(LootContextParams.LAST_DAMAGE_PLAYER, dummyPlayer)
.build(LootContextParamSets.ENTITY);
Collection<ItemStack> items = LootTables.entityLootTable(argument.getType())
.randomItems(params);
LogUtils.debug("DamageEntityEffect, {} items: {}", argument, items);
return new ItemCollection(items);
}

View File

@ -8,6 +8,7 @@ public enum Direction {
SOUTH(0f, BlockFace.SOUTH),
EAST(-90f, BlockFace.EAST);
public static final Direction[] entries = Direction.values();
private final float yaw;
private final BlockFace face;