Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package vg.civcraft.mc.civmodcore.mods.packets;

import com.google.gson.JsonElement;
import net.kyori.adventure.key.Key;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;

public interface CivModPacketHandler {
public static final CivModPacketHandler NOOP = (sender, packetId, json) -> {};

public void handleCivModPacket(
@NotNull Player sender,
@NotNull Key packetId,
@NotNull JsonElement json
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package vg.civcraft.mc.civmodcore.mods.packets;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import net.kyori.adventure.key.Key;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.messaging.Messenger;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CivModPackets {
private static final Logger LOGGER = LoggerFactory.getLogger(CivModPackets.class);
private static final Gson GSON = new Gson();

public static void registerPacket(
final @NotNull JavaPlugin plugin,
final @NotNull Key packetId,
final boolean registerIncoming,
final boolean registerOutgoing,
final @NotNull CivModPacketHandler handler
) {
Objects.requireNonNull(plugin);
Objects.requireNonNull(packetId);
Objects.requireNonNull(handler);
final Messenger messenger = Bukkit.getMessenger();
if (registerIncoming) {
messenger.registerIncomingPluginChannel(plugin, packetId.toString(), (channel, sender, payload) -> {
final Key receivedPacketId;
try {
receivedPacketId = Key.key(channel);
}
catch (final Exception e) {
LOGGER.warn(
"{} sent a packet with an invalid packetId: {}",
sender.getName(),
channel,
e
);
return;
}
final JsonElement json; {
final String raw = new String(payload, StandardCharsets.UTF_8);
try {
json = GSON.fromJson(raw, JsonElement.class);
}
catch (final Exception e) {
LOGGER.warn(
"{} sent a packet [packetId:{}] with an invalid payload: {}",
sender.getName(),
receivedPacketId,
raw,
e
);
return;
}
}
LOGGER.info(
"{} sent packet [packetId:{}]: {}",
sender.getName(),
receivedPacketId,
json
);
try {
handler.handleCivModPacket(sender, receivedPacketId, json);
}
catch (final Exception e) {
LOGGER.warn(
"Something went wrong while handling {}'s [packetId:{}] with payload: {}",
sender.getName(),
receivedPacketId,
json,
e
);
}
});
}
if (registerOutgoing) {
messenger.registerOutgoingPluginChannel(plugin, packetId.toString());
}
}

/// Use this to register incoming-only packets. If the packet is bidirectional, use [#registerPacket] instead.
public static void registerIncomingPacket(
final @NotNull JavaPlugin plugin,
final @NotNull Key packetId,
final @NotNull CivModPacketHandler handler
) {
registerPacket(plugin, packetId, true, false, handler);
}

/// Use this to register outgoing-only packets. If the packet is bidirectional, use [#registerPacket] instead.
public static void registerOutgoingPacket(
final @NotNull JavaPlugin plugin,
final @NotNull Key packetId
) {
registerPacket(plugin, packetId, false, true, CivModPacketHandler.NOOP);
}

public static void sendPacket(
final @NotNull JavaPlugin plugin,
final @NotNull Player recipient,
final @NotNull Key packetId,
final @NotNull JsonElement json
) {
final String payload = GSON.toJson(json);
LOGGER.info(
"Sending packet to {}: [packetId:{}]: {}",
recipient.getName(),
packetId,
payload
);
recipient.sendPluginMessage(
plugin,
packetId.toString(),
payload.getBytes(StandardCharsets.UTF_8)
);
}
}


Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package vg.civcraft.mc.civmodcore.utilities;

import io.papermc.paper.plugin.provider.classloader.ConfiguredPluginClassLoader;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -70,4 +72,27 @@ public static NamespacedKey testKey(@NotNull final String key) {
return new NamespacedKey("test", key);
}

public static @NotNull NamespacedKey of(
final @NotNull Class<? extends JavaPlugin> pluginClass,
final @NotNull String value
) {
/// This code is based on [JavaPlugin#getPlugin] but avoids accessing the plugin instance itself, making this
/// safe to use even when a plugin instance doesn't necessarily exist yet.
if (!JavaPlugin.class.isAssignableFrom(pluginClass)) {
throw new IllegalArgumentException("%s does not extend %s!".formatted(
pluginClass.getName(),
JavaPlugin.class.getName()
));
}
if (!(pluginClass.getClassLoader() instanceof ConfiguredPluginClassLoader classLoader)) {
throw new IllegalArgumentException("%s was not loaded by %s!".formatted(
pluginClass.getName(),
ConfiguredPluginClassLoader.class.getName()
));
}
return new NamespacedKey(
classLoader.getConfiguration().namespace(),
value
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.untamedears.itemexchange.glues.jukealert.JukeAlertGlue;
import com.untamedears.itemexchange.glues.namelayer.NameLayerGlue;
import com.untamedears.itemexchange.rules.ModifierRegistrar;
import com.untamedears.itemexchange.rules.ShopRule;
import com.untamedears.itemexchange.rules.modifiers.BookModifier;
import com.untamedears.itemexchange.rules.modifiers.DamageableModifier;
import com.untamedears.itemexchange.rules.modifiers.DisplayNameModifier;
Expand All @@ -16,6 +17,7 @@
import java.util.List;
import vg.civcraft.mc.civmodcore.ACivMod;
import vg.civcraft.mc.civmodcore.commands.CommandManager;
import vg.civcraft.mc.civmodcore.mods.packets.CivModPackets;
import vg.civcraft.mc.civmodcore.utilities.DependencyGlue;

/**
Expand Down Expand Up @@ -54,6 +56,7 @@ public void onEnable() {
modifiers.registerModifier(BookModifier.TEMPLATE); // 1000
registerListener(new ItemExchangeListener());
this.glues.forEach(DependencyGlue::registerGlue);
CivModPackets.registerOutgoingPacket(this, ShopRule.SHOW_TRADE_PACKET);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@ public final class GroupModifier extends ModifierData {
// Make sure to have a template instance to make registration easier
public static final GroupModifier TEMPLATE = new GroupModifier();

private static final String ID_KEY = "id";
private static final String NAME_KEY = "name";

private int groupId;
private String groupName;

@Override
Expand All @@ -51,18 +49,18 @@ public boolean conforms(final ItemStack item) {

@Override
public boolean isBroken() {
return false;
return this.groupName == null;
}

@Override
public void toNBT(final @NotNull NbtCompound nbt) {
nbt.setInt(ID_KEY, getGroupId());
nbt.setString(NAME_KEY, getGroupName());
if (this.groupName instanceof final String groupName) {
nbt.setString(NAME_KEY, groupName);
}
}

public static @NotNull GroupModifier fromNBT(final @NotNull NbtCompound nbt) {
final var modifier = new GroupModifier();
modifier.setGroupId(nbt.getInt(ID_KEY, 0));
modifier.setGroupName(nbt.getString(NAME_KEY, null));
return modifier;
}
Expand All @@ -76,7 +74,7 @@ public List<String> getDisplayInfo() {

@Override
public String toString() {
return "%S{%s:%d}".formatted(getSlug(), getGroupName(), getGroupId());
return "%S:%s".formatted(getSlug(), getGroupName());
}

// ------------------------------------------------------------
Expand Down Expand Up @@ -104,7 +102,6 @@ public void commandSetGroup(final Player player,
return;
}
final GroupModifier modifier = handler.ensureModifier();
modifier.setGroupId(group.getGroupId());
modifier.setGroupName(group.getName());
handler.relay(ChatColor.GREEN + "Set trade to group \"" + group.getName() + "\"");
}
Expand All @@ -114,14 +111,6 @@ public void commandSetGroup(final Player player,
// Getters + Setters
// ------------------------------------------------------------

public int getGroupId() {
return this.groupId;
}

public void setGroupId(final int groupId) {
this.groupId = groupId;
}

public String getGroupName() {
return this.groupName;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void denyPurchaseIfNotGotPerms(final BrowseOrPurchaseEvent event) {
final GroupModifier modifier = event.getTrade().getInput().getModifiers().get(GroupModifier.class);
if (!Validation.checkValidity(modifier)
|| PermissionsGlue.PURCHASE_PERMISSION.testPermission(
GroupManager.getGroup(modifier.getGroupId()), event.getBrowser())) {
GroupManager.getGroup(modifier.getGroupName()), event.getBrowser())) {
return;
}
event.limitToBrowsing();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,27 @@

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.mojang.serialization.JsonOps;
import com.untamedears.itemexchange.ItemExchangeConfig;
import com.untamedears.itemexchange.ItemExchangePlugin;
import com.untamedears.itemexchange.events.BlockInventoryRequestEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import net.minecraft.nbt.NbtOps;
import org.apache.commons.collections4.CollectionUtils;
import org.bukkit.ChatColor;
import org.bukkit.NamespacedKey;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.BlockIterator;
import vg.civcraft.mc.civmodcore.inventory.InventoryUtils;
import vg.civcraft.mc.civmodcore.mods.packets.CivModPackets;
import vg.civcraft.mc.civmodcore.nbt.NbtCompound;
import vg.civcraft.mc.civmodcore.utilities.KeyedUtils;
import vg.civcraft.mc.civmodcore.utilities.Validation;
import vg.civcraft.mc.civmodcore.world.WorldUtils;

Expand All @@ -28,6 +34,7 @@
public final class ShopRule implements Validation {

private final ItemExchangePlugin PLUGIN = ItemExchangePlugin.getInstance();
public static final NamespacedKey SHOW_TRADE_PACKET = KeyedUtils.of(ItemExchangePlugin.class, "trade-details");

private final List<TradeRule> trades = new ArrayList<>();

Expand Down Expand Up @@ -84,19 +91,36 @@ public void presentShopToPlayer(Player player) {
if (trade == null) {
throw new NullPointerException("Could not message player about trade... this shouldn't happen.");
}
final int currentTradeIndex = this.currentTradeIndex + 1, tradesCount = this.trades.size();
player.sendMessage(String.format("%s(%d/%d) exchanges present.",
ChatColor.YELLOW, this.currentTradeIndex + 1, this.trades.size()));
ChatColor.YELLOW, currentTradeIndex, tradesCount));
for (String line : trade.getInput().getDisplayInfo()) {
player.sendMessage(line);
}
if (trade.getOutput() != null) {
for (String line : trade.getOutput().getDisplayInfo()) {
int stock = 0;
if (trade.getOutput() instanceof final ExchangeRule outputRule) {
for (String line : outputRule.getDisplayInfo()) {
player.sendMessage(line);
}
PLUGIN.debug("[ShopRule] Calculating stock.");
int stock = trade.calculateStock();
stock = trade.calculateStock();
player.sendMessage(ChatColor.YELLOW + "" + stock + " exchange" + (stock == 1 ? "" : "s") + " available.");
}
// Mod support
final var displayNbt = new NbtCompound();
displayNbt.setInt("trades", tradesCount);
displayNbt.setInt("index", currentTradeIndex);
displayNbt.setCompound("input", trade.getInput().toNBT());
if (trade.getOutput() instanceof final ExchangeRule outputRule) {
displayNbt.setCompound("output", outputRule.toNBT());
displayNbt.setInt("stock", stock);
}
CivModPackets.sendPacket(
ItemExchangePlugin.getInstance(),
player,
SHOW_TRADE_PACKET,
NbtOps.INSTANCE.convertTo(JsonOps.INSTANCE, displayNbt.internal())
);
}

// ------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@

@Deprecated
public interface NBTSerializable {
default @NotNull NbtCompound toNBT() {
final var nbt = new NbtCompound();
this.toNBT(nbt);
return nbt;
}

/**
* Serializes this class onto a given NBTCompound.
*
Expand Down
Loading