Fix logging, add config, fix UnsafeValues
This commit is contained in:
parent
56eff72525
commit
018ef2a8fa
@ -54,6 +54,7 @@ dependencies {
|
||||
implementation("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18")
|
||||
implementation("org.apache.maven.resolver:maven-resolver-util:1.9.18")
|
||||
implementation("com.google.protobuf:protobuf-java:$protobufVersion")
|
||||
implementation("org.slf4j:slf4j-jdk14:2.0.16")
|
||||
}
|
||||
|
||||
java {
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
package org.patchbukkit;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.material.MaterialData;
|
||||
|
||||
@SuppressWarnings({ "deprecation", "removal" })
|
||||
public final class PatchBukkitLegacy {
|
||||
private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(PatchBukkitLegacy.class);
|
||||
|
||||
public static Material fromLegacy(Material material) {
|
||||
if (material == null || !material.isLegacy()) {
|
||||
return material;
|
||||
}
|
||||
|
||||
return PatchBukkitLegacy.fromLegacy(new MaterialData(material));
|
||||
}
|
||||
|
||||
public static Material fromLegacy(MaterialData materialData) {
|
||||
return PatchBukkitLegacy.fromLegacy(materialData, false);
|
||||
}
|
||||
|
||||
public static Material fromLegacy(MaterialData materialData, boolean itemPriority) {
|
||||
Material material = materialData.getItemType();
|
||||
if (material == null || !material.isLegacy()) {
|
||||
return material;
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("Cannot convert from legacy to new Material");
|
||||
}
|
||||
}
|
||||
@ -90,6 +90,8 @@ import org.patchbukkit.command.PatchBukkitCommandMap;
|
||||
import org.patchbukkit.command.PatchBukkitConsoleCommandSender;
|
||||
import org.patchbukkit.events.PatchBukkitEventManager;
|
||||
import org.patchbukkit.scheduler.PatchBukkitScheduler;
|
||||
import org.patchbukkit.versioning.Versioning;
|
||||
|
||||
import patchbukkit.bridge.NativeBridgeFfi;
|
||||
import patchbukkit.log.LogLevel;
|
||||
import patchbukkit.log.SendLogRequest;
|
||||
@ -114,7 +116,7 @@ public class PatchBukkitServer implements Server {
|
||||
configureRootLogger();
|
||||
}
|
||||
|
||||
private static final Map<Level, LogLevel> LEVEL_MAP = Map.of(
|
||||
public static final Map<Level, LogLevel> LEVEL_MAP = Map.of(
|
||||
Level.SEVERE, LogLevel.SEVERE,
|
||||
Level.WARNING, LogLevel.WARNING,
|
||||
Level.INFO, LogLevel.INFO,
|
||||
|
||||
@ -12,11 +12,14 @@ import java.util.Map;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.HoverEvent;
|
||||
import net.kyori.adventure.text.event.HoverEvent.ShowItem;
|
||||
import net.kyori.adventure.text.flattener.ComponentFlattener;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||
import patchbukkit.bridge.NativeBridgeFfi;
|
||||
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.advancement.Advancement;
|
||||
import org.bukkit.attribute.Attributable;
|
||||
@ -25,6 +28,7 @@ import org.bukkit.attribute.AttributeModifier;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.damage.DamageSource;
|
||||
import org.bukkit.damage.DamageSource.Builder;
|
||||
import org.bukkit.damage.DamageType;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
@ -38,9 +42,14 @@ import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.potion.PotionType;
|
||||
import org.bukkit.potion.PotionType.InternalPotionData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
import org.patchbukkit.events.PatchBukkitLifecycleEventManager;
|
||||
import org.patchbukkit.versioning.ApiVersion;
|
||||
import org.patchbukkit.versioning.Versioning;
|
||||
import patchbukkit.common.EmptyRequest;
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
public class PatchBukkitUnsafeValues implements UnsafeValues {
|
||||
@ -48,342 +57,334 @@ public class PatchBukkitUnsafeValues implements UnsafeValues {
|
||||
public static final PatchBukkitUnsafeValues INSTANCE =
|
||||
new PatchBukkitUnsafeValues();
|
||||
|
||||
// These are commonly used - implement first
|
||||
@Override
|
||||
public int getDataVersion() {
|
||||
return 4189; // 1.21.4 data version - match your server
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack modifyItemStack(ItemStack stack, String arguments) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportedApiVersion(String apiVersion) {
|
||||
// Accept common API versions
|
||||
return (
|
||||
apiVersion != null &&
|
||||
(apiVersion.equals("1.21") || apiVersion.equals("1.20"))
|
||||
);
|
||||
}
|
||||
if (apiVersion == null) return false;
|
||||
final ApiVersion toCheck = ApiVersion.getOrCreateVersion(apiVersion);
|
||||
var minimumApi = NativeBridgeFfi.getPatchBukkitConfig(EmptyRequest.newBuilder().build()).getMinimumSupportedPluginApi();
|
||||
final ApiVersion minimumVersion = ApiVersion.getOrCreateVersion(minimumApi);
|
||||
|
||||
@Override
|
||||
public byte[] serializeItem(ItemStack item) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack deserializeItem(byte[] data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull JsonObject serializeItemAsJson(
|
||||
@NotNull ItemStack itemStack
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack deserializeItemFromJson(@NotNull JsonObject data)
|
||||
throws IllegalArgumentException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte@NotNull [] serializeEntity(
|
||||
@NotNull Entity entity,
|
||||
@NonNull @NotNull EntitySerializationFlag... serializationFlags
|
||||
) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Entity deserializeEntity(
|
||||
byte@NotNull [] data,
|
||||
@NotNull World world,
|
||||
boolean preserveUUID,
|
||||
boolean preservePassengers
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextEntityId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getMainLevelName() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtocolVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidRepairItemStack(
|
||||
@NotNull ItemStack itemToBeRepaired,
|
||||
@NotNull ItemStack repairMaterial
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDefaultEntityAttributes(
|
||||
@NotNull NamespacedKey entityKey
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Attributable getDefaultEntityAttributes(
|
||||
@NotNull NamespacedKey entityKey
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull NamespacedKey getBiomeKey(
|
||||
RegionAccessor accessor,
|
||||
int x,
|
||||
int y,
|
||||
int z
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiomeKey(
|
||||
RegionAccessor accessor,
|
||||
int x,
|
||||
int y,
|
||||
int z,
|
||||
NamespacedKey biomeKey
|
||||
) {}
|
||||
|
||||
@Override
|
||||
public String getStatisticCriteriaKey(@NotNull Statistic statistic) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Color getSpawnEggLayerColor(
|
||||
EntityType entityType,
|
||||
int layer
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LifecycleEventManager<Plugin> createPluginLifecycleEventManager(
|
||||
JavaPlugin plugin,
|
||||
BooleanSupplier registrationCheck
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<Component> computeTooltipLines(
|
||||
@NotNull ItemStack itemStack,
|
||||
@NotNull TooltipContext tooltipContext,
|
||||
@Nullable Player player
|
||||
) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack createEmptyStack() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<String, Object> serializeStack(ItemStack itemStack) {
|
||||
return Map.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack deserializeStack(
|
||||
@NotNull Map<String, Object> args
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack deserializeItemHover(
|
||||
HoverEvent.@NotNull ShowItem itemHover
|
||||
) {
|
||||
return null;
|
||||
return !toCheck.isNewerThan(ApiVersion.CURRENT) && !toCheck.isOlderThan(minimumVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkSupported(PluginDescriptionFile pdf)
|
||||
throws InvalidPluginException {
|
||||
// Be lenient during development - accept most plugins
|
||||
String api = pdf.getAPIVersion();
|
||||
if (api != null && !isSupportedApiVersion(api)) {
|
||||
throw new InvalidPluginException("Unsupported API: " + api);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] processClass(
|
||||
PluginDescriptionFile pdf,
|
||||
String path,
|
||||
byte[] clazz
|
||||
) {
|
||||
// Return unchanged - skip Commodore remapping for now
|
||||
return clazz;
|
||||
}
|
||||
@Override
|
||||
public ComponentFlattener componentFlattener() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'componentFlattener'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Advancement loadAdvancement(NamespacedKey key, String advancement) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public PlainComponentSerializer plainComponentSerializer() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'plainComponentSerializer'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAdvancement(NamespacedKey key) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public PlainTextComponentSerializer plainTextSerializer() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'plainTextSerializer'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Multimap<Attribute, AttributeModifier> getDefaultAttributeModifiers(
|
||||
Material material,
|
||||
EquipmentSlot slot
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public GsonComponentSerializer gsonComponentSerializer() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'gsonComponentSerializer'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreativeCategory getCreativeCategory(Material material) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public GsonComponentSerializer colorDownsamplingGsonComponentSerializer() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'colorDownsamplingGsonComponentSerializer'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBlockTranslationKey(Material material) {
|
||||
return "";
|
||||
}
|
||||
@Override
|
||||
public LegacyComponentSerializer legacyComponentSerializer() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'legacyComponentSerializer'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getItemTranslationKey(Material material) {
|
||||
return "";
|
||||
}
|
||||
@Override
|
||||
public Component resolveWithContext(Component component, CommandSender context, Entity scoreboardSubject,
|
||||
boolean bypassPermissions) throws IOException {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'resolveWithContext'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslationKey(EntityType entityType) {
|
||||
return "";
|
||||
}
|
||||
@Override
|
||||
public Material toLegacy(Material material) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'toLegacy'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslationKey(ItemStack itemStack) {
|
||||
return "";
|
||||
}
|
||||
@Override
|
||||
public Material fromLegacy(Material material) {
|
||||
return PatchBukkitLegacy.fromLegacy(material);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTranslationKey(Attribute attribute) {
|
||||
return "";
|
||||
}
|
||||
@Override
|
||||
public Material fromLegacy(MaterialData material) {
|
||||
return PatchBukkitLegacy.fromLegacy(material);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PotionType.InternalPotionData getInternalPotionData(
|
||||
NamespacedKey key
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Material fromLegacy(MaterialData material, boolean itemPriority) {
|
||||
return PatchBukkitLegacy.fromLegacy(material, itemPriority);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DamageSource.@NotNull Builder createDamageSourceBuilder(
|
||||
@NotNull DamageType damageType
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public BlockData fromLegacy(Material material, byte data) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'fromLegacy'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(Class<?> aClass, String value) {
|
||||
return "";
|
||||
}
|
||||
@Override
|
||||
public Material getMaterial(String material, int version) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getMaterial'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends Keyed> B get(RegistryKey<B> registry, NamespacedKey key) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public int getDataVersion() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getDataVersion'");
|
||||
}
|
||||
|
||||
// Adventure components - commonly used
|
||||
@Override
|
||||
public ComponentFlattener componentFlattener() {
|
||||
return ComponentFlattener.basic();
|
||||
}
|
||||
@Override
|
||||
public ItemStack modifyItemStack(ItemStack stack, String arguments) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'modifyItemStack'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlainComponentSerializer plainComponentSerializer() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public byte[] processClass(PluginDescriptionFile pdf, String path, byte[] clazz) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'processClass'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlainTextComponentSerializer plainTextSerializer() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Advancement loadAdvancement(NamespacedKey key, String advancement) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'loadAdvancement'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public GsonComponentSerializer gsonComponentSerializer() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public boolean removeAdvancement(NamespacedKey key) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'removeAdvancement'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public GsonComponentSerializer colorDownsamplingGsonComponentSerializer() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public Multimap<Attribute, AttributeModifier> getDefaultAttributeModifiers(Material material, EquipmentSlot slot) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getDefaultAttributeModifiers'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public LegacyComponentSerializer legacyComponentSerializer() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public CreativeCategory getCreativeCategory(Material material) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getCreativeCategory'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component resolveWithContext(
|
||||
Component component,
|
||||
CommandSender context,
|
||||
Entity scoreboardSubject,
|
||||
boolean bypassPermissions
|
||||
) throws IOException {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String getBlockTranslationKey(Material material) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getBlockTranslationKey'");
|
||||
}
|
||||
|
||||
// Stub everything else
|
||||
@Override
|
||||
public Material toLegacy(Material material) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Pumpkin doesn't support legacy materials"
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public String getItemTranslationKey(Material material) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getItemTranslationKey'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material fromLegacy(Material material) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String getTranslationKey(EntityType entityType) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getTranslationKey'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material fromLegacy(MaterialData material) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String getTranslationKey(ItemStack itemStack) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getTranslationKey'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material fromLegacy(MaterialData material, boolean itemPriority) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String getTranslationKey(Attribute attribute) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getTranslationKey'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockData fromLegacy(Material material, byte data) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public InternalPotionData getInternalPotionData(NamespacedKey key) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getInternalPotionData'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getMaterial(String material, int version) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public @NotNull Builder createDamageSourceBuilder(@NotNull DamageType damageType) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'createDamageSourceBuilder'");
|
||||
}
|
||||
|
||||
// ... etc
|
||||
@Override
|
||||
public String get(Class<?> aClass, String value) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'get'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <B extends Keyed> B get(RegistryKey<B> registry, NamespacedKey key) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'get'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] serializeItem(ItemStack item) {
|
||||
System.out.println("Serializing item: " + item);
|
||||
System.out.println(item.getType().getKey().getKey());
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'serializeItem'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack deserializeItem(byte[] data) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'deserializeItem'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull JsonObject serializeItemAsJson(@NotNull ItemStack itemStack) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'serializeItemAsJson'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack deserializeItemFromJson(@NotNull JsonObject data) throws IllegalArgumentException {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'deserializeItemFromJson'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte @NotNull [] serializeEntity(@NotNull Entity entity,
|
||||
@NotNull EntitySerializationFlag... serializationFlags) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'serializeEntity'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Entity deserializeEntity(byte @NotNull [] data, @NotNull World world, boolean preserveUUID,
|
||||
boolean preservePassengers) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'deserializeEntity'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextEntityId() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'nextEntityId'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getMainLevelName() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getMainLevelName'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtocolVersion() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getProtocolVersion'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidRepairItemStack(@NotNull ItemStack itemToBeRepaired, @NotNull ItemStack repairMaterial) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'isValidRepairItemStack'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDefaultEntityAttributes(@NotNull NamespacedKey entityKey) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'hasDefaultEntityAttributes'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Attributable getDefaultEntityAttributes(@NotNull NamespacedKey entityKey) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getDefaultEntityAttributes'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull NamespacedKey getBiomeKey(RegionAccessor accessor, int x, int y, int z) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getBiomeKey'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiomeKey(RegionAccessor accessor, int x, int y, int z, NamespacedKey biomeKey) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'setBiomeKey'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatisticCriteriaKey(@NotNull Statistic statistic) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getStatisticCriteriaKey'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Color getSpawnEggLayerColor(EntityType entityType, int layer) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getSpawnEggLayerColor'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public LifecycleEventManager<Plugin> createPluginLifecycleEventManager(JavaPlugin plugin,
|
||||
BooleanSupplier registrationCheck) {
|
||||
return new PatchBukkitLifecycleEventManager(plugin, registrationCheck);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<Component> computeTooltipLines(@NotNull ItemStack itemStack,
|
||||
@NotNull TooltipContext tooltipContext, @Nullable Player player) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'computeTooltipLines'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack createEmptyStack() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'createEmptyStack'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Map<String, Object> serializeStack(ItemStack itemStack) {
|
||||
System.out.println("Serializing itemstack: " + itemStack);
|
||||
System.out.println(itemStack.getType().getKey().getKey());
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'serializeStack'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack deserializeStack(@NotNull Map<String, Object> args) {
|
||||
System.out.println("Deserializing itemstack: " + args);
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'deserializeStack'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ItemStack deserializeItemHover(@NotNull ShowItem itemHover) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'deserializeItemHover'");
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.permissions.PermissibleBase;
|
||||
@ -18,6 +19,11 @@ import org.jetbrains.annotations.Nullable;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
|
||||
import patchbukkit.bridge.NativeBridgeFfi;
|
||||
import patchbukkit.log.LogLevel;
|
||||
import patchbukkit.log.SendLogRequest;
|
||||
import org.patchbukkit.PatchBukkitServer;
|
||||
|
||||
public class PatchBukkitCommandSender implements CommandSender, ServerOperator {
|
||||
|
||||
private final Server server;
|
||||
@ -133,7 +139,14 @@ public class PatchBukkitCommandSender implements CommandSender, ServerOperator {
|
||||
if (this.server != null && this.server.getLogger() != null) {
|
||||
this.server.getLogger().info(message);
|
||||
} else {
|
||||
System.out.println(message);
|
||||
LogLevel logLevel = LogLevel.INFO;
|
||||
NativeBridgeFfi.sendLog(
|
||||
SendLogRequest.newBuilder()
|
||||
.setLevel(logLevel)
|
||||
.setMessage(ChatColor.stripColor(message))
|
||||
.setLoggerName("console")
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
package org.patchbukkit.events;
|
||||
|
||||
import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
|
||||
import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler;
|
||||
import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration;
|
||||
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
public class PatchBukkitLifecycleEventManager implements LifecycleEventManager<Plugin> {
|
||||
|
||||
private final Plugin plugin;
|
||||
private final BooleanSupplier registrationCheck;
|
||||
private final List<RegisteredHandler<?>> handlers = new ArrayList<>();
|
||||
|
||||
public PatchBukkitLifecycleEventManager(Plugin plugin, BooleanSupplier registrationCheck) {
|
||||
this.plugin = plugin;
|
||||
this.registrationCheck = registrationCheck;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerEventHandler(
|
||||
@NotNull LifecycleEventHandlerConfiguration<? super Plugin> handlerConfiguration) {
|
||||
if (!registrationCheck.getAsBoolean()) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot register lifecycle event handler for " + plugin.getName()
|
||||
+ " — registration is not allowed at this time");
|
||||
}
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
private record RegisteredHandler<E extends LifecycleEvent>(
|
||||
LifecycleEventType<? super Plugin, E, ?> type,
|
||||
LifecycleEventHandler<? super E> handler
|
||||
) {}
|
||||
}
|
||||
@ -0,0 +1,130 @@
|
||||
package org.patchbukkit.versioning;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class ApiVersion implements Comparable<ApiVersion>, Serializable {
|
||||
|
||||
public static final ApiVersion CURRENT;
|
||||
public static final ApiVersion FLATTENING;
|
||||
public static final ApiVersion FIELD_NAME_PARITY;
|
||||
public static final ApiVersion ABSTRACT_COW;
|
||||
public static final ApiVersion NONE;
|
||||
|
||||
private static final Map<String, ApiVersion> versions;
|
||||
|
||||
static {
|
||||
versions = new HashMap<>();
|
||||
CURRENT = getOrCreateVersion(Versioning.getCurrentApiVersion());
|
||||
FLATTENING = getOrCreateVersion("1.13");
|
||||
FIELD_NAME_PARITY = getOrCreateVersion("1.20.5");
|
||||
ABSTRACT_COW = getOrCreateVersion("1.21.5");
|
||||
NONE = getOrCreateVersion("none");
|
||||
}
|
||||
|
||||
private final boolean none;
|
||||
private final int major;
|
||||
private final int minor;
|
||||
private final int patch;
|
||||
|
||||
private ApiVersion() {
|
||||
this.none = true;
|
||||
this.major = Integer.MIN_VALUE;
|
||||
this.minor = Integer.MIN_VALUE;
|
||||
this.patch = Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
private ApiVersion(int major, int minor, int patch) {
|
||||
this.none = false;
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.patch = patch;
|
||||
}
|
||||
|
||||
public static ApiVersion getOrCreateVersion(String versionString) {
|
||||
if (versionString == null || versionString.trim().isEmpty() || versionString.equalsIgnoreCase("none")) {
|
||||
return ApiVersion.versions.computeIfAbsent("none", s -> new ApiVersion());
|
||||
}
|
||||
|
||||
ApiVersion version = ApiVersion.versions.get(versionString);
|
||||
|
||||
if (version != null) {
|
||||
return version;
|
||||
}
|
||||
|
||||
String[] versionParts = versionString.split("\\.");
|
||||
|
||||
if (versionParts.length != 2 && versionParts.length != 3) {
|
||||
throw new IllegalArgumentException(String.format("API version string should be of format \"major.minor.patch\" or \"major.minor\", where \"major\", \"minor\" and \"patch\" are numbers. For example \"1.18.2\" or \"1.13\", but got '%s' instead.", versionString));
|
||||
}
|
||||
|
||||
int major = ApiVersion.parseNumber(versionParts[0]);
|
||||
int minor = ApiVersion.parseNumber(versionParts[1]);
|
||||
|
||||
int patch;
|
||||
if (versionParts.length == 3) {
|
||||
patch = ApiVersion.parseNumber(versionParts[2]);
|
||||
} else {
|
||||
patch = 0;
|
||||
}
|
||||
|
||||
versionString = ApiVersion.toVersionString(major, minor, patch);
|
||||
return ApiVersion.versions.computeIfAbsent(versionString, s -> new ApiVersion(major, minor, patch));
|
||||
}
|
||||
|
||||
private static int parseNumber(String number) {
|
||||
return Integer.parseInt(number);
|
||||
}
|
||||
|
||||
private static String toVersionString(int major, int minor, int patch) {
|
||||
return major + "." + minor + "." + patch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull ApiVersion other) {
|
||||
int result = Integer.compare(this.major, other.major);
|
||||
|
||||
if (result == 0) {
|
||||
result = Integer.compare(this.minor, other.minor);
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
result = Integer.compare(this.patch, other.patch);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getVersionString() {
|
||||
if (this.none) {
|
||||
return "none";
|
||||
}
|
||||
|
||||
return ApiVersion.toVersionString(this.major, this.minor, this.patch);
|
||||
}
|
||||
|
||||
public boolean isNewerThan(ApiVersion apiVersion) {
|
||||
return this.compareTo(apiVersion) > 0;
|
||||
}
|
||||
|
||||
public boolean isOlderThan(ApiVersion apiVersion) {
|
||||
return this.compareTo(apiVersion) < 0;
|
||||
}
|
||||
|
||||
public boolean isNewerThanOrSameAs(ApiVersion apiVersion) {
|
||||
return this.compareTo(apiVersion) >= 0;
|
||||
}
|
||||
|
||||
public boolean isOlderThanOrSameAs(ApiVersion apiVersion) {
|
||||
return this.compareTo(apiVersion) <= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getVersionString();
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0L;
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
package org.patchbukkit;
|
||||
package org.patchbukkit.versioning;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@ -5,6 +5,7 @@ import "google/protobuf/empty.proto";
|
||||
import "google/protobuf/wrappers.proto";
|
||||
import "patchbukkit/abilities.proto";
|
||||
import "patchbukkit/common/types.proto";
|
||||
import "patchbukkit/config.proto";
|
||||
import "patchbukkit/events/event.proto";
|
||||
import "patchbukkit/log.proto";
|
||||
import "patchbukkit/message.proto";
|
||||
@ -28,4 +29,6 @@ service NativeBridge {
|
||||
rpc PlayerPlaySound(patchbukkit.sound.PlayerPlaySoundRequest) returns (google.protobuf.Empty);
|
||||
|
||||
rpc SendLog(patchbukkit.log.SendLogRequest) returns (google.protobuf.Empty);
|
||||
|
||||
rpc GetPatchBukkitConfig(patchbukkit.common.EmptyRequest) returns (patchbukkit.config.GetPatchBukkitConfigResponse);
|
||||
}
|
||||
|
||||
@ -25,3 +25,5 @@ message Location {
|
||||
float yaw = 3;
|
||||
float pitch = 4;
|
||||
}
|
||||
|
||||
message EmptyRequest {}
|
||||
|
||||
12
proto/patchbukkit/config.proto
Normal file
12
proto/patchbukkit/config.proto
Normal file
@ -0,0 +1,12 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package patchbukkit.config;
|
||||
|
||||
import "patchbukkit/common/types.proto";
|
||||
|
||||
option java_multiple_files = true;
|
||||
option java_package = "patchbukkit.config";
|
||||
|
||||
message GetPatchBukkitConfigResponse {
|
||||
string minimum_supported_plugin_api = 1;
|
||||
}
|
||||
17
proto/patchbukkit/itemstack.proto
Normal file
17
proto/patchbukkit/itemstack.proto
Normal file
@ -0,0 +1,17 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package patchbukkit.itemstack;
|
||||
|
||||
import "patchbukkit/common/types.proto";
|
||||
|
||||
option java_multiple_files = true;
|
||||
option java_package = "patchbukkit.itemstack";
|
||||
|
||||
// message GetPatchBukkitConfigResponse {
|
||||
// string minimum_supported_plugin_api = 1;
|
||||
// }
|
||||
|
||||
message ItemStack {
|
||||
string type = 1;
|
||||
uint32 amount = 2;
|
||||
}
|
||||
141
rust/Cargo.lock
generated
141
rust/Cargo.lock
generated
@ -400,9 +400,9 @@ checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.4.2"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b"
|
||||
checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6"
|
||||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
@ -1132,18 +1132,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.4.1"
|
||||
version = "0.4.0-rc.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec"
|
||||
checksum = "74f70a332ddf75e5e5e43284304179ba02f391f82f692f030b08a8378adf3c99"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"rand_core 0.10.0",
|
||||
"wasip2",
|
||||
"wasip3",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1905,12 +1903,14 @@ dependencies = [
|
||||
"pumpkin-data",
|
||||
"pumpkin-protocol",
|
||||
"pumpkin-util",
|
||||
"pumpkin-world",
|
||||
"rand",
|
||||
"rust-embed",
|
||||
"serde",
|
||||
"serde-saphyr",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"toml 1.0.2+spec-1.1.0",
|
||||
"tracing",
|
||||
"uuid",
|
||||
"walkdir",
|
||||
@ -2193,7 +2193,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pumpkin"
|
||||
version = "0.1.0-dev+1.21.11"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#e438e09991619d105c9835570b09c1b4624eedc5"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#6e1bea72b7ec7b1d193149a124225e08930764f3"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"base64",
|
||||
@ -2203,7 +2203,6 @@ dependencies = [
|
||||
"futures",
|
||||
"hmac 0.13.0-rc.5",
|
||||
"libloading 0.9.0",
|
||||
"log",
|
||||
"num-bigint",
|
||||
"pkcs8 0.11.0-rc.10",
|
||||
"pumpkin-config",
|
||||
@ -2235,7 +2234,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pumpkin-api-macros"
|
||||
version = "0.1.0-dev+1.21.11"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#e438e09991619d105c9835570b09c1b4624eedc5"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#6e1bea72b7ec7b1d193149a124225e08930764f3"
|
||||
dependencies = [
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
@ -2246,19 +2245,19 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pumpkin-config"
|
||||
version = "0.1.0-dev+1.21.11"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#e438e09991619d105c9835570b09c1b4624eedc5"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#6e1bea72b7ec7b1d193149a124225e08930764f3"
|
||||
dependencies = [
|
||||
"log",
|
||||
"pumpkin-util",
|
||||
"serde",
|
||||
"toml",
|
||||
"toml 0.9.11+spec-1.1.0",
|
||||
"tracing",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pumpkin-data"
|
||||
version = "0.1.0-dev+1.21.11"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#e438e09991619d105c9835570b09c1b4624eedc5"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#6e1bea72b7ec7b1d193149a124225e08930764f3"
|
||||
dependencies = [
|
||||
"crc-fast",
|
||||
"phf",
|
||||
@ -2270,22 +2269,22 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pumpkin-inventory"
|
||||
version = "0.1.0-dev+1.21.11"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#e438e09991619d105c9835570b09c1b4624eedc5"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#6e1bea72b7ec7b1d193149a124225e08930764f3"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
"log",
|
||||
"pumpkin-data",
|
||||
"pumpkin-protocol",
|
||||
"pumpkin-util",
|
||||
"pumpkin-world",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pumpkin-macros"
|
||||
version = "0.1.0-dev+1.21.11"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#e438e09991619d105c9835570b09c1b4624eedc5"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#6e1bea72b7ec7b1d193149a124225e08930764f3"
|
||||
dependencies = [
|
||||
"proc-macro-error2",
|
||||
"pumpkin-data",
|
||||
@ -2296,7 +2295,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pumpkin-nbt"
|
||||
version = "0.1.0-dev+1.21.11"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#e438e09991619d105c9835570b09c1b4624eedc5"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#6e1bea72b7ec7b1d193149a124225e08930764f3"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"cesu8",
|
||||
@ -2308,13 +2307,14 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pumpkin-protocol"
|
||||
version = "0.1.0-dev+1.21.11"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#e438e09991619d105c9835570b09c1b4624eedc5"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#6e1bea72b7ec7b1d193149a124225e08930764f3"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"async-compression",
|
||||
"bitflags",
|
||||
"bytes",
|
||||
"cfb8",
|
||||
"flate2",
|
||||
"pumpkin-data",
|
||||
"pumpkin-macros",
|
||||
"pumpkin-nbt",
|
||||
@ -2330,7 +2330,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pumpkin-util"
|
||||
version = "0.1.0-dev+1.21.11"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#e438e09991619d105c9835570b09c1b4624eedc5"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#6e1bea72b7ec7b1d193149a124225e08930764f3"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
@ -2355,7 +2355,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "pumpkin-world"
|
||||
version = "0.1.0-dev+1.21.11"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#e438e09991619d105c9835570b09c1b4624eedc5"
|
||||
source = "git+https://github.com/Pumpkin-MC/Pumpkin.git?branch=master#6e1bea72b7ec7b1d193149a124225e08930764f3"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bytes",
|
||||
@ -2366,7 +2366,6 @@ dependencies = [
|
||||
"flate2",
|
||||
"futures",
|
||||
"itertools",
|
||||
"log",
|
||||
"lz4-java-wrc",
|
||||
"num_cpus",
|
||||
"pumpkin-config",
|
||||
@ -2383,6 +2382,7 @@ dependencies = [
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
@ -2417,7 +2417,7 @@ version = "0.10.0-rc.9"
|
||||
source = "git+https://github.com/rust-random/rand#72afe1e973fcd83d840cf597888223072bbdb04c"
|
||||
dependencies = [
|
||||
"chacha20",
|
||||
"getrandom 0.4.1",
|
||||
"getrandom 0.4.0-rc.1",
|
||||
"rand_core 0.10.0",
|
||||
]
|
||||
|
||||
@ -3124,9 +3124,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.47"
|
||||
version = "0.3.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
|
||||
checksum = "9da98b7d9b7dad93488a84b8248efc35352b0b2657397d4167e7ad67e5d535e5"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
@ -3146,9 +3146,9 @@ checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.27"
|
||||
version = "0.2.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
|
||||
checksum = "78cc610bac2dcee56805c99642447d4c5dbde4d01f752ffea0199aee1f601dc4"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
@ -3214,7 +3214,22 @@ dependencies = [
|
||||
"indexmap",
|
||||
"serde_core",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_datetime 0.7.5+spec-1.1.0",
|
||||
"toml_parser",
|
||||
"toml_writer",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "1.0.2+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1dfefef6a142e93f346b64c160934eb13b5594b84ab378133ac6815cb2bd57f"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde_core",
|
||||
"serde_spanned",
|
||||
"toml_datetime 1.0.0+spec-1.1.0",
|
||||
"toml_parser",
|
||||
"toml_writer",
|
||||
"winnow",
|
||||
@ -3230,10 +3245,19 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_parser"
|
||||
version = "1.0.6+spec-1.1.0"
|
||||
name = "toml_datetime"
|
||||
version = "1.0.0+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44"
|
||||
checksum = "32c2555c699578a4f59f0cc68e5116c8d7cabbd45e1409b989d4be085b53f13e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_parser"
|
||||
version = "1.0.9+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4"
|
||||
dependencies = [
|
||||
"winnow",
|
||||
]
|
||||
@ -3524,16 +3548,16 @@ version = "1.0.2+wasi-0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
|
||||
dependencies = [
|
||||
"wit-bindgen",
|
||||
"wit-bindgen 0.51.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasip3"
|
||||
version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
|
||||
version = "0.3.1+wasi-0.3.0-rc-2025-09-16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
|
||||
checksum = "87ba4be47b1d11244670d11857eee0758a8f2c39aea64d80b78c1ce29b4642cd"
|
||||
dependencies = [
|
||||
"wit-bindgen",
|
||||
"wit-bindgen 0.48.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3583,9 +3607,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
version = "0.244.0"
|
||||
version = "0.241.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
|
||||
checksum = "e01164c9dda68301e34fdae536c23ed6fe90ce6d97213ccc171eebbd3d02d6b8"
|
||||
dependencies = [
|
||||
"leb128fmt",
|
||||
"wasmparser",
|
||||
@ -3593,9 +3617,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-metadata"
|
||||
version = "0.244.0"
|
||||
version = "0.241.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
|
||||
checksum = "876fe286f2fa416386deedebe8407e6f19e0b5aeaef3d03161e77a15fa80f167"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"indexmap",
|
||||
@ -3605,9 +3629,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.244.0"
|
||||
version = "0.241.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
|
||||
checksum = "46d90019b1afd4b808c263e428de644f3003691f243387d30d673211ee0cb8e8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"hashbrown 0.15.5",
|
||||
@ -3834,18 +3858,24 @@ checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.51.0"
|
||||
version = "0.48.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
|
||||
checksum = "7f8c2adb5f74ac9395bc3121c99a1254bf9310482c27b13f97167aedb5887138"
|
||||
dependencies = [
|
||||
"wit-bindgen-rust-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-core"
|
||||
name = "wit-bindgen"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
|
||||
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-core"
|
||||
version = "0.48.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b881a098cae03686d7a0587f8f306f8a58102ad8da8b5599100fbe0e7f5800b"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
@ -3854,9 +3884,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rust"
|
||||
version = "0.51.0"
|
||||
version = "0.48.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
|
||||
checksum = "69667efa439a453e1d50dac939c6cab6d2c3ac724a9d232b6631dad2472a5b70"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck",
|
||||
@ -3870,9 +3900,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rust-macro"
|
||||
version = "0.51.0"
|
||||
version = "0.48.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
|
||||
checksum = "eae2e22cceb5d105d52326c07e3e67603a861cc7add70fc467f7cc7ec5265017"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"prettyplease",
|
||||
@ -3885,9 +3915,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wit-component"
|
||||
version = "0.244.0"
|
||||
version = "0.241.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
|
||||
checksum = "1fd0c57df25e7ee612d946d3b7646c1ddb2310f8280aa2c17e543b66e0812241"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags",
|
||||
@ -3904,9 +3934,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wit-parser"
|
||||
version = "0.244.0"
|
||||
version = "0.241.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
|
||||
checksum = "09ef1c6ad67f35c831abd4039c02894de97034100899614d1c44e2268ad01c91"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"id-arena",
|
||||
@ -4045,9 +4075,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "7.4.0"
|
||||
version = "7.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc12baa6db2b15a140161ce53d72209dacea594230798c24774139b54ecaa980"
|
||||
checksum = "c42e33efc22a0650c311c2ef19115ce232583abbe80850bc8b66509ebef02de0"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"bzip2",
|
||||
@ -4055,7 +4085,8 @@ dependencies = [
|
||||
"crc32fast",
|
||||
"deflate64",
|
||||
"flate2",
|
||||
"getrandom 0.4.1",
|
||||
"generic-array",
|
||||
"getrandom 0.3.4",
|
||||
"hmac 0.12.1",
|
||||
"indexmap",
|
||||
"lzma-rust2",
|
||||
|
||||
@ -14,6 +14,7 @@ pumpkin-data = { git = "https://github.com/Pumpkin-MC/Pumpkin.git", branch = "ma
|
||||
pumpkin-protocol = { git = "https://github.com/Pumpkin-MC/Pumpkin.git", branch = "master", package = "pumpkin-protocol" }
|
||||
pumpkin-util = { git = "https://github.com/Pumpkin-MC/Pumpkin.git", branch = "master", package = "pumpkin-util" }
|
||||
pumpkin-api-macros = { git = "https://github.com/Pumpkin-MC/Pumpkin.git", branch = "master", package = "pumpkin-api-macros" }
|
||||
pumpkin-world = { git = "https://github.com/Pumpkin-MC/Pumpkin.git", branch = "master", package = "pumpkin-world" }
|
||||
|
||||
tokio = "1"
|
||||
tracing = "0.1"
|
||||
@ -33,6 +34,8 @@ serde-saphyr = "0.0.17"
|
||||
rand = { git = "https://github.com/rust-random/rand"}
|
||||
prost = "0.14"
|
||||
|
||||
toml = "1.0"
|
||||
|
||||
[build-dependencies]
|
||||
j4rs = { version = "0.24", artifact = "cdylib", lib = true }
|
||||
env_logger = "0.11.8"
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
pub mod paper;
|
||||
pub mod patchbukkit;
|
||||
pub mod spigot;
|
||||
|
||||
37
rust/src/config/patchbukkit.rs
Normal file
37
rust/src/config/patchbukkit.rs
Normal file
@ -0,0 +1,37 @@
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub struct PatchBukkitConfig {
|
||||
pub settings: SettingsConfig,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct SettingsConfig {
|
||||
pub minimum_supported_plugin_api: Option<String>,
|
||||
}
|
||||
|
||||
impl PatchBukkitConfig {
|
||||
pub const DEFAULT: PatchBukkitConfig = PatchBukkitConfig {
|
||||
settings: SettingsConfig {
|
||||
minimum_supported_plugin_api: None,
|
||||
},
|
||||
};
|
||||
|
||||
pub fn parse<S: AsRef<str>>(config: S) -> Result<Self, toml::de::Error> {
|
||||
toml::from_str(config.as_ref())
|
||||
}
|
||||
|
||||
pub fn get_or_create<P: AsRef<Path>>(config_path: P) -> anyhow::Result<Self> {
|
||||
let config_path = config_path.as_ref();
|
||||
if !config_path.exists() {
|
||||
let default = PatchBukkitConfig::DEFAULT;
|
||||
std::fs::write(config_path, &toml::to_string_pretty(&default)?)?;
|
||||
return Ok(default);
|
||||
}
|
||||
let config = PatchBukkitConfig::parse(fs::read_to_string(config_path)?)?;
|
||||
Ok(config)
|
||||
}
|
||||
}
|
||||
@ -7,8 +7,8 @@ use tokio::sync::{mpsc, oneshot};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
commands::SimpleCommandSender, events::handler::JvmEventPayload,
|
||||
proto::patchbukkit::events::FireEventResponse,
|
||||
commands::SimpleCommandSender, config::patchbukkit::PatchBukkitConfig,
|
||||
events::handler::JvmEventPayload, proto::patchbukkit::events::FireEventResponse,
|
||||
};
|
||||
|
||||
pub enum LoadPluginResult {
|
||||
@ -26,6 +26,7 @@ pub enum JvmCommand {
|
||||
respond_to: oneshot::Sender<Result<()>>,
|
||||
context: Arc<Context>,
|
||||
command_tx: mpsc::Sender<Self>,
|
||||
config: PatchBukkitConfig,
|
||||
},
|
||||
LoadPlugin {
|
||||
plugin_path: PathBuf,
|
||||
|
||||
@ -48,11 +48,13 @@ impl JvmWorker {
|
||||
respond_to,
|
||||
context,
|
||||
command_tx,
|
||||
config,
|
||||
} => {
|
||||
init_callback_context(
|
||||
context.clone(),
|
||||
tokio::runtime::Handle::current(),
|
||||
command_tx.clone(),
|
||||
config,
|
||||
)
|
||||
.unwrap();
|
||||
self.context = Some(context);
|
||||
|
||||
21
rust/src/java/native_callbacks/config.rs
Normal file
21
rust/src/java/native_callbacks/config.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use crate::{
|
||||
java::native_callbacks::CALLBACK_CONTEXT,
|
||||
proto::patchbukkit::{common::EmptyRequest, config::GetPatchBukkitConfigResponse},
|
||||
};
|
||||
|
||||
pub fn ffi_native_bridge_get_patch_bukkit_config_impl(
|
||||
_request: EmptyRequest,
|
||||
) -> Option<GetPatchBukkitConfigResponse> {
|
||||
if let Some(context) = CALLBACK_CONTEXT.get() {
|
||||
Some(GetPatchBukkitConfigResponse {
|
||||
minimum_supported_plugin_api: context
|
||||
.config
|
||||
.settings
|
||||
.minimum_supported_plugin_api
|
||||
.clone()
|
||||
.unwrap_or("0.0.0".to_string()),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
5
rust/src/java/native_callbacks/itemstack.rs
Normal file
5
rust/src/java/native_callbacks/itemstack.rs
Normal file
@ -0,0 +1,5 @@
|
||||
// pub fn ffi_native_bridge_serialize_item_stack_impl(
|
||||
// request: SerializeItemStackRequest,
|
||||
// ) -> Option<SerializeItemStackResponse> {
|
||||
// Some(())
|
||||
// }
|
||||
@ -5,7 +5,10 @@ use j4rs::Jvm;
|
||||
use pumpkin::plugin::Context;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
use crate::{java::jvm::commands::JvmCommand, proto::initialize_ffi_callbacks};
|
||||
use crate::{
|
||||
config::patchbukkit::PatchBukkitConfig, java::jvm::commands::JvmCommand,
|
||||
proto::initialize_ffi_callbacks,
|
||||
};
|
||||
|
||||
mod abilities;
|
||||
pub use abilities::*;
|
||||
@ -30,23 +33,32 @@ pub mod utils;
|
||||
pub mod log;
|
||||
pub use log::*;
|
||||
|
||||
pub mod config;
|
||||
pub use config::*;
|
||||
|
||||
pub mod itemstack;
|
||||
pub use itemstack::*;
|
||||
|
||||
static CALLBACK_CONTEXT: OnceLock<CallbackContext> = OnceLock::new();
|
||||
|
||||
struct CallbackContext {
|
||||
pub plugin_context: Arc<Context>,
|
||||
pub runtime: tokio::runtime::Handle,
|
||||
pub command_tx: mpsc::Sender<JvmCommand>,
|
||||
pub config: PatchBukkitConfig,
|
||||
}
|
||||
|
||||
pub fn init_callback_context(
|
||||
plugin_context: Arc<Context>,
|
||||
runtime: tokio::runtime::Handle,
|
||||
command_tx: mpsc::Sender<JvmCommand>,
|
||||
config: PatchBukkitConfig,
|
||||
) -> Result<()> {
|
||||
let context = CallbackContext {
|
||||
plugin_context,
|
||||
runtime,
|
||||
command_tx,
|
||||
config,
|
||||
};
|
||||
|
||||
CALLBACK_CONTEXT
|
||||
|
||||
@ -86,6 +86,7 @@ pub const DEPENDENCIES: &[(&str, &str, &str)] = &[
|
||||
// These are deps of patchbukkit itself
|
||||
("io.papermc.paper", "paper-api", "1.21.11-R0.1-SNAPSHOT"),
|
||||
("com.google.protobuf", "protobuf-java", "4.33.5"),
|
||||
("org.slf4j", "slf4j-jdk14", "2.0.16"),
|
||||
];
|
||||
|
||||
pub fn setup_j4rs(j4rs_folder: &Path) -> Result<()> {
|
||||
|
||||
@ -19,12 +19,15 @@ use tokio::sync::{
|
||||
oneshot,
|
||||
};
|
||||
|
||||
use crate::java::{
|
||||
jvm::{
|
||||
commands::{JvmCommand, LoadPluginResult},
|
||||
worker::JvmWorker,
|
||||
use crate::{
|
||||
config::patchbukkit::PatchBukkitConfig,
|
||||
java::{
|
||||
jvm::{
|
||||
commands::{JvmCommand, LoadPluginResult},
|
||||
worker::JvmWorker,
|
||||
},
|
||||
resources::setup_j4rs,
|
||||
},
|
||||
resources::setup_j4rs,
|
||||
};
|
||||
|
||||
async fn on_load_inner(plugin: &PatchBukkitPlugin, server: Arc<Context>) -> Result<(), String> {
|
||||
@ -34,7 +37,10 @@ async fn on_load_inner(plugin: &PatchBukkitPlugin, server: Arc<Context>) -> Resu
|
||||
// Setup directories
|
||||
let dirs = setup_directories(&server)?;
|
||||
|
||||
proto::patchbukkit::common::Uuid::default();
|
||||
let mut config_path = dirs.base.clone();
|
||||
config_path.push("patchbukkit.config.toml");
|
||||
let config = PatchBukkitConfig::get_or_create(config_path)
|
||||
.map_err(|e| format!("Failed to setup PatchBukkit config: {e}"))?;
|
||||
|
||||
// Discover and prepare JAR files
|
||||
let jar_paths = discover_jar_files(&dirs.plugins);
|
||||
@ -112,6 +118,7 @@ async fn on_load_inner(plugin: &PatchBukkitPlugin, server: Arc<Context>) -> Resu
|
||||
respond_to: tx,
|
||||
context: server.clone(),
|
||||
command_tx: plugin.command_tx.clone(),
|
||||
config,
|
||||
})
|
||||
.await
|
||||
.map_err(|e| format!("Failed to send command to initialize J4RS: {e}"))?;
|
||||
|
||||
@ -30,6 +30,14 @@ pub mod patchbukkit {
|
||||
pub mod log {
|
||||
include!(concat!(env!("OUT_DIR"), "/patchbukkit.log.rs"));
|
||||
}
|
||||
|
||||
pub mod config {
|
||||
include!(concat!(env!("OUT_DIR"), "/patchbukkit.config.rs"));
|
||||
}
|
||||
|
||||
pub mod itemstack {
|
||||
include!(concat!(env!("OUT_DIR"), "/patchbukkit.itemstack.rs"));
|
||||
}
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/ffi_init.rs"));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user