Skip to content
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Built for [DemocracyCraft](https://www.democracycraft.net/) and [StateCraft](htt
| `database-settings.yml` | MariaDB URL, username, password |
| `settings.yml` | Shop icon templates, lore, click command, preview scale |
| `item-code-groupings.yml` | Item code aliases mapped to canonical item codes |
| `messages.yml` | Player-facing messages |
| `messages.yml` | Player-facing messages (MiniMessage) |

## Building

Expand Down
15 changes: 15 additions & 0 deletions adapters/geyser-floodgate/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
plugins {
id("chestshop-database.library-conventions")
}

repositories {
maven {
name = "opencollab"
url = uri("https://repo.opencollab.dev/main/")
}
}

dependencies {
compileOnlyApi(libs.geyserApi)
compileOnlyApi(libs.floodgateApi)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.github.md5sha256.chestshopdatabase.adapters.geyserfloodgate;

import org.geysermc.floodgate.api.FloodgateApi;
import org.jetbrains.annotations.NotNull;

import java.util.UUID;

/**
* Bedrock detection via Floodgate (typically when Floodgate is installed on this backend).
*/
public final class FloodgateBedrockDetector {

private FloodgateBedrockDetector() {
}

public static boolean isBedrockPlayer(@NotNull UUID uuid) {
return FloodgateApi.getInstance().isFloodgatePlayer(uuid);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.github.md5sha256.chestshopdatabase.adapters.geyserfloodgate;

import org.geysermc.geyser.api.GeyserApi;
import org.jetbrains.annotations.NotNull;

import java.util.UUID;

/**
* Bedrock detection via Geyser when the Geyser plugin is present on this server.
*/
public final class GeyserBedrockDetector {

private GeyserBedrockDetector() {
}

public static boolean isBedrockPlayer(@NotNull UUID uuid) {
var api = GeyserApi.api();
return api != null && api.isBedrockPlayer(uuid);
}
}
3 changes: 3 additions & 0 deletions chestshop-database-bukkit/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ dependencies {
implementation(projects.adapters.worldguard) {
isTransitive = false
}
implementation(projects.adapters.geyserFloodgate) {
isTransitive = false
}

// Libraries
implementation("org.mybatis:mybatis:3.5.19")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import io.github.md5sha256.chestshopdatabase.adapters.fawe.FAWEHandler;
import io.github.md5sha256.chestshopdatabase.adapters.geyserfloodgate.FloodgateBedrockDetector;
import io.github.md5sha256.chestshopdatabase.adapters.geyserfloodgate.GeyserBedrockDetector;
import io.github.md5sha256.chestshopdatabase.adapters.worldedit.WorldEditHandler;
import io.github.md5sha256.chestshopdatabase.adapters.worldguard.WorldGuardHandler;
import io.github.md5sha256.chestshopdatabase.command.CommandBean;
Expand Down Expand Up @@ -31,6 +33,7 @@
import org.apache.ibatis.session.SqlSessionFactory;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
Expand All @@ -51,6 +54,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.logging.Logger;

Expand Down Expand Up @@ -133,6 +137,7 @@ public void onDisable() {
}

private void registerCommands(@NotNull SqlSessionFactory sessionFactory) {
PluginManager pluginManager = getServer().getPluginManager();
Supplier<DatabaseSession> sessionSupplier = () -> new DatabaseSession(sessionFactory,
MariaChestshopMapper.class, MariaPreferenceMapper.class);
FindTaskFactory findTaskFactory = new FindTaskFactory(sessionSupplier, executorState);
Expand All @@ -142,14 +147,17 @@ private void registerCommands(@NotNull SqlSessionFactory sessionFactory) {
executorState,
this,
this.previewHandler);
Predicate<Player> isBedrockPlayer = bedrockPlayerPredicate(pluginManager);
var findCommand = new FindCommand(this.shopState,
this.discoverer,
findTaskFactory,
this.gui,
this,
this.previewHandler,
sessionSupplier,
this.executorState);
this.executorState,
isBedrockPlayer,
this.messageContainer);
List<CommandBean> commands = List.of(
findCommand,
new ResyncCommand(this, resyncTaskFactory),
Expand All @@ -170,6 +178,19 @@ private void registerCommands(@NotNull SqlSessionFactory sessionFactory) {
);
}

private @NotNull Predicate<Player> bedrockPlayerPredicate(@NotNull PluginManager pluginManager) {
Predicate<Player> predicate = player -> false;
if (pluginManager.isPluginEnabled("floodgate")) {
predicate = predicate.or(
player -> FloodgateBedrockDetector.isBedrockPlayer(player.getUniqueId()));
}
if (pluginManager.isPluginEnabled("Geyser-Spigot")) {
predicate = predicate.or(
player -> GeyserBedrockDetector.isBedrockPlayer(player.getUniqueId()));
}
return predicate;
}

private void registerAdapters() {
PluginManager pluginManager = getServer().getPluginManager();
if (pluginManager.isPluginEnabled("WorldEdit")) {
Expand Down Expand Up @@ -246,7 +267,7 @@ private ConfigurationNode copyDefaultsYaml(@NotNull String resourceName) throws
try (FileOutputStream fileOutputStream = new FileOutputStream(file);
InputStream inputStream = getResource(fileName)) {
if (inputStream == null) {
getLogger().severe("Failed to copy default messages!");
getLogger().severe("Failed to copy default resource: " + fileName);
} else {
inputStream.transferTo(fileOutputStream);
}
Expand All @@ -270,15 +291,15 @@ private Settings loadSettings() throws IOException {
return settingsRoot.get(Settings.class);
}

private ConfigurationNode loadMessages() throws IOException {
return copyDefaultsYaml("messages");
}

private DatabaseSettings loadDatabaseSettings() throws IOException {
ConfigurationNode settingsRoot = copyDefaultsYaml("database-settings");
return settingsRoot.get(DatabaseSettings.class);
}

public ConfigurationNode loadMessages() throws IOException {
return copyDefaultsYaml("messages");
}

public ItemCodeGroupings loadItemCodeGroupings() throws IOException {
ConfigurationNode settingsRoot = copyDefaultsYaml("item-code-groupings");
ItemCodeGroupings groupings = settingsRoot.get(ItemCodeGroupings.class);
Expand All @@ -302,12 +323,13 @@ public CompletableFuture<Boolean> reload() {
private CompletableFuture<Boolean> reloadMessagesAndSettings() {
CompletableFuture<Boolean> future = new CompletableFuture<>();
getServer().getScheduler().runTaskAsynchronously(this, () -> {
ConfigurationNode messagesNode;
Settings settings;
ConfigurationNode messagesNode;
ItemCodeGroupings groupings;
try {
ConfigurationNode settingsRoot = copyDefaultsYaml("settings");
settings = settingsRoot.get(Settings.class);
messagesNode = loadMessages();
settings = loadSettings();
groupings = loadItemCodeGroupings();
} catch (IOException ex) {
ex.printStackTrace();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import io.github.md5sha256.chestshopdatabase.gui.dialog.FindDialog;
import io.github.md5sha256.chestshopdatabase.model.ChestshopItem;
import io.github.md5sha256.chestshopdatabase.preview.PreviewHandler;
import io.github.md5sha256.chestshopdatabase.settings.MessageContainer;
import io.github.md5sha256.chestshopdatabase.util.BlockPosition;
import io.papermc.paper.command.brigadier.CommandSourceStack;
import io.papermc.paper.command.brigadier.Commands;
Expand All @@ -33,6 +34,7 @@

import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
import java.util.function.Supplier;

public record FindCommand(@NotNull ChestShopState shopState,
Expand All @@ -42,7 +44,9 @@ public record FindCommand(@NotNull ChestShopState shopState,
@NotNull Plugin plugin,
@NotNull PreviewHandler previewHandler,
@NotNull Supplier<DatabaseSession> session,
@NotNull ExecutorState executorState) implements CommandBean.Single {
@NotNull ExecutorState executorState,
@NotNull Predicate<Player> isBedrockPlayer,
@NotNull MessageContainer messages) implements CommandBean.Single {


@Override
Expand Down Expand Up @@ -276,7 +280,8 @@ private void processCommandWithItem(@NotNull Player player, @NotNull ItemStack i
);
findState.setWorld(queryPosition.world());
findState.setQueryPosition(queryPosition);
Dialog dialog = FindDialog.createMainPageDialog(findState, taskFactory, gui, plugin);
Dialog dialog = FindDialog.createMainPageDialog(findState, taskFactory, gui, plugin,
isBedrockPlayer, messages);
player.showDialog(dialog);
});
}
Expand All @@ -303,7 +308,8 @@ private void processCommandWithItemCode(@NotNull Player player, @NotNull String
);
findState.setWorld(queryPosition.world());
findState.setQueryPosition(queryPosition);
Dialog dialog = FindDialog.createMainPageDialog(findState, taskFactory, gui, plugin);
Dialog dialog = FindDialog.createMainPageDialog(findState, taskFactory, gui, plugin,
isBedrockPlayer, messages);
player.showDialog(dialog);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import io.github.md5sha256.chestshopdatabase.model.ChestshopItem;
import io.github.md5sha256.chestshopdatabase.model.ShopAttribute;
import io.github.md5sha256.chestshopdatabase.model.ShopType;
import io.github.md5sha256.chestshopdatabase.settings.MessageContainer;
import io.github.md5sha256.chestshopdatabase.util.DialogUtil;
import io.github.md5sha256.chestshopdatabase.util.SortDirection;
import io.papermc.paper.datacomponent.DataComponentTypes;
Expand All @@ -28,9 +29,12 @@
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.function.Predicate;

public class FindDialog {

private static final String MESSAGE_FIND_QUERYING = "find.querying";

@NotNull
private static DialogBase createMainPageBase(@Nullable ChestshopItem item) {
if (item == null) {
Expand Down Expand Up @@ -70,11 +74,18 @@ private static void submit(
@NotNull FindState findState,
@NotNull FindTaskFactory taskFactory,
@NotNull ShopResultsGUI resultsGUI,
@NotNull Plugin plugin) {
audience.showDialog(waitScreen());
@NotNull Plugin plugin,
@NotNull Predicate<Player> isBedrockPlayer,
@NotNull MessageContainer messages) {
if (!(audience instanceof Player player)) {
audience.showDialog(waitScreen());
return;
}
if (isBedrockPlayer.test(player)) {
player.sendMessage(messages.messageFor(MESSAGE_FIND_QUERYING));
} else {
audience.showDialog(waitScreen());
}
taskFactory.findTask(findState).whenComplete((res, ex) -> {
audience.closeDialog();
if (ex != null) {
Expand All @@ -98,10 +109,12 @@ public static Dialog createMainPageDialog(
@NotNull FindState findState,
@NotNull FindTaskFactory taskFactory,
@NotNull ShopResultsGUI resultsGUI,
@NotNull Plugin plugin
@NotNull Plugin plugin,
@NotNull Predicate<Player> isBedrockPlayer,
@NotNull MessageContainer messages
) {
DialogAction submitAction = DialogAction.customClick((view, audience) -> {
submit(view, audience, findState, taskFactory, resultsGUI, plugin);
submit(view, audience, findState, taskFactory, resultsGUI, plugin, isBedrockPlayer, messages);
}, ClickCallback.Options.builder().uses(1).build());
DialogAction buyCheapAction = DialogAction.customClick((view, audience) -> {
findState.setShopTypes(List.of(ShopType.BUY, ShopType.BOTH));
Expand All @@ -110,7 +123,7 @@ public static Dialog createMainPageDialog(
findState.setSortDirection(ShopAttribute.UNIT_BUY_PRICE, SortDirection.ASCENDING);
findState.setSortDirection(ShopAttribute.DISTANCE, SortDirection.ASCENDING);
findState.setHideEmptyShops(true);
submit(view, audience, findState, taskFactory, resultsGUI, plugin);
submit(view, audience, findState, taskFactory, resultsGUI, plugin, isBedrockPlayer, messages);
}, ClickCallback.Options.builder().uses(1).build());
DialogAction buyNearbyAction = DialogAction.customClick((view, audience) -> {
findState.setShopTypes(List.of(ShopType.BUY, ShopType.BOTH));
Expand All @@ -119,7 +132,7 @@ public static Dialog createMainPageDialog(
findState.setSortDirection(ShopAttribute.DISTANCE, SortDirection.ASCENDING);
findState.setSortDirection(ShopAttribute.UNIT_BUY_PRICE, SortDirection.ASCENDING);
findState.setHideEmptyShops(true);
submit(view, audience, findState, taskFactory, resultsGUI, plugin);
submit(view, audience, findState, taskFactory, resultsGUI, plugin, isBedrockPlayer, messages);
}, ClickCallback.Options.builder().uses(1).build());
DialogAction sellBestPriceAction = DialogAction.customClick((view, audience) -> {
findState.setShopTypes(List.of(ShopType.SELL, ShopType.BOTH));
Expand All @@ -130,7 +143,7 @@ public static Dialog createMainPageDialog(
findState.setSortDirection(ShopAttribute.REMAINING_CAPACITY, SortDirection.DESCENDING);
findState.setSortDirection(ShopAttribute.DISTANCE, SortDirection.ASCENDING);
findState.setHideFullShops(true);
submit(view, audience, findState, taskFactory, resultsGUI, plugin);
submit(view, audience, findState, taskFactory, resultsGUI, plugin, isBedrockPlayer, messages);
}, ClickCallback.Options.builder().uses(1).build());

ActionButton submitButton = ActionButton.builder(Component.text("Search", NamedTextColor.GREEN))
Expand All @@ -157,12 +170,14 @@ public static Dialog createMainPageDialog(
ActionButton.builder(Component.text("Filters"))
.action(DialogUtil.openDialogAction(() -> FilterDialog.createFiltersDialog(
findState,
() -> createMainPageDialog(findState, taskFactory, resultsGUI, plugin))))
() -> createMainPageDialog(findState, taskFactory, resultsGUI, plugin,
isBedrockPlayer, messages))))
.build(),
ActionButton.builder(Component.text("Sorting"))
.action(DialogUtil.openDialogAction(() -> SortDialog.createSortDialog(
findState,
() -> createMainPageDialog(findState, taskFactory, resultsGUI, plugin))))
() -> createMainPageDialog(findState, taskFactory, resultsGUI, plugin,
isBedrockPlayer, messages))))
.build(),
submitButton
);
Expand Down
6 changes: 6 additions & 0 deletions chestshop-database-bukkit/src/main/resources/paper-plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ dependencies:
AsyncWorldEdit:
join-classpath: true
required: false
floodgate:
join-classpath: true
required: false
Geyser-Spigot:
join-classpath: true
required: false

permissions:
csdb.find:
Expand Down
6 changes: 5 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ minecraft = "1.21.8-R0.1-SNAPSHOT"
worldedit = "7.3.16"
worldguard = "7.0.14"
fawe = "2.14.0"
geyserApi = "2.9.0-SNAPSHOT"
floodgateApi = "2.2.4-SNAPSHOT"

[libraries]
# Platform
Expand All @@ -14,4 +16,6 @@ paper = { group = "io.papermc.paper", name = "paper-api", version.ref = "minecra
# Minecraft Plugins
worldeditCore = { group = "com.sk89q.worldedit", name = "worldedit-core", version.ref = "worldedit" }
fastasyncworldeditCore = { group = "com.fastasyncworldedit", name = "FastAsyncWorldEdit-Core", version.ref = "fawe" }
worldguardBukkit = { group = "com.sk89q.worldguard", name = "worldguard-bukkit", version.ref = "worldguard" }
worldguardBukkit = { group = "com.sk89q.worldguard", name = "worldguard-bukkit", version.ref = "worldguard" }
geyserApi = { group = "org.geysermc.geyser", name = "api", version.ref = "geyserApi" }
floodgateApi = { group = "org.geysermc.floodgate", name = "api", version.ref = "floodgateApi" }
Empty file modified gradlew
100644 → 100755
Empty file.
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ rootProject.name = "chestshop-database"
include(":adapters:worldedit")
include(":adapters:fawe")
include(":adapters:worldguard")
include(":adapters:geyser-floodgate")

// Core
include(":core")
Expand Down
Loading