Initial commit

This commit is contained in:
BenceX100 2024-04-04 13:01:21 +02:00
commit 5b34367a56
17 changed files with 955 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

113
.gitignore vendored Normal file
View File

@ -0,0 +1,113 @@
# User-specific stuff
.idea/
*.iml
*.ipr
*.iws
# IntelliJ
out/
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.mvn/wrapper/maven-wrapper.jar
.flattened-pom.xml
# Common working directory
run/

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Artillex-Studios
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

132
pom.xml Normal file
View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.artillexstudios</groupId>
<artifactId>AxTrade</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>AxTrade</name>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<relocations>
<relocation>
<pattern>com.artillexstudios.axapi</pattern>
<shadedPattern>com.artillexstudios.axtrade.libs.axapi</shadedPattern>
</relocation>
<relocation>
<pattern>org.bstats</pattern>
<shadedPattern>com.artillexstudios.axtrade.libs.bstats</shadedPattern>
</relocation>
<relocation>
<pattern>dev.triumphteam.gui</pattern>
<shadedPattern>com.artillexstudios.axtrade.libs.gui</shadedPattern>
</relocation>
<relocation>
<pattern>net.kyori.adventure</pattern>
<shadedPattern>com.artillexstudios.axtrade.libs.kyori</shadedPattern>
</relocation>
<relocation>
<pattern>revxrsal.commands</pattern>
<shadedPattern>com.artillexstudios.axtrade.libs.lamp</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>Artillex-Studios</id>
<url>https://repo.artillex-studios.com/releases/</url>
</repository>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>placeholderapi</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.artillexstudios.axapi</groupId>
<artifactId>axapi</artifactId>
<version>1.4.109</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.18-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>dev.triumphteam</groupId>
<artifactId>triumph-gui</artifactId>
<version>3.1.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.11.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>3.0.2</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,60 @@
package com.artillexstudios.axtrade;
import com.artillexstudios.axapi.AxPlugin;
import com.artillexstudios.axapi.config.Config;
import com.artillexstudios.axapi.data.ThreadedQueue;
import com.artillexstudios.axapi.libs.boostedyaml.boostedyaml.dvs.versioning.BasicVersioning;
import com.artillexstudios.axapi.libs.boostedyaml.boostedyaml.settings.dumper.DumperSettings;
import com.artillexstudios.axapi.libs.boostedyaml.boostedyaml.settings.general.GeneralSettings;
import com.artillexstudios.axapi.libs.boostedyaml.boostedyaml.settings.loader.LoaderSettings;
import com.artillexstudios.axapi.libs.boostedyaml.boostedyaml.settings.updater.UpdaterSettings;
import com.artillexstudios.axapi.utils.MessageUtils;
import com.artillexstudios.axapi.utils.StringUtils;
import com.artillexstudios.axtrade.commands.Commands;
import com.artillexstudios.axtrade.trade.TradeTicker;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import java.io.File;
public final class AxTrade extends AxPlugin {
public static Config CONFIG;
public static Config LANG;
public static Config GUIS;
public static MessageUtils MESSAGEUTILS;
private static AxPlugin instance;
private static ThreadedQueue<Runnable> threadedQueue;
public static BukkitAudiences BUKKITAUDIENCES;
public static ThreadedQueue<Runnable> getThreadedQueue() {
return threadedQueue;
}
public static AxPlugin getInstance() {
return instance;
}
public void enable() {
instance = this;
int pluginId = 21500;
new Metrics(this, pluginId);
CONFIG = new Config(new File(getDataFolder(), "config.yml"), getResource("config.yml"), GeneralSettings.builder().setUseDefaults(false).build(), LoaderSettings.builder().setAutoUpdate(true).build(), DumperSettings.DEFAULT, UpdaterSettings.builder().setKeepAll(true).setVersioning(new BasicVersioning("version")).build());
GUIS = new Config(new File(getDataFolder(), "guis.yml"), getResource("guis.yml"), GeneralSettings.builder().setUseDefaults(false).build(), LoaderSettings.builder().setAutoUpdate(true).build(), DumperSettings.DEFAULT, UpdaterSettings.builder().setKeepAll(true).setVersioning(new BasicVersioning("version")).build());
LANG = new Config(new File(getDataFolder(), "lang.yml"), getResource("lang.yml"), GeneralSettings.builder().setUseDefaults(false).build(), LoaderSettings.builder().setAutoUpdate(true).build(), DumperSettings.DEFAULT, UpdaterSettings.builder().setKeepAll(true).setVersioning(new BasicVersioning("version")).build());
MESSAGEUTILS = new MessageUtils(LANG.getBackingDocument(), "prefix", CONFIG.getBackingDocument());
threadedQueue = new ThreadedQueue<>("AxRewards-Datastore-thread");
BUKKITAUDIENCES = BukkitAudiences.create(this);
new TradeTicker().start();
Commands.registerCommand();
Bukkit.getConsoleSender().sendMessage(StringUtils.formatToString("&#00ffdd[AxTrade] Loaded plugin!"));
}
}

View File

@ -0,0 +1,80 @@
package com.artillexstudios.axtrade.commands;
import com.artillexstudios.axapi.utils.StringUtils;
import com.artillexstudios.axtrade.AxTrade;
import com.artillexstudios.axtrade.trade.Trades;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.permissions.PermissionDefault;
import org.jetbrains.annotations.NotNull;
import revxrsal.commands.annotation.DefaultFor;
import revxrsal.commands.annotation.Subcommand;
import revxrsal.commands.bukkit.BukkitCommandHandler;
import revxrsal.commands.bukkit.annotation.CommandPermission;
import revxrsal.commands.orphan.OrphanCommand;
import revxrsal.commands.orphan.Orphans;
import java.util.Map;
import static com.artillexstudios.axtrade.AxTrade.CONFIG;
import static com.artillexstudios.axtrade.AxTrade.GUIS;
import static com.artillexstudios.axtrade.AxTrade.LANG;
import static com.artillexstudios.axtrade.AxTrade.MESSAGEUTILS;
public class Commands implements OrphanCommand {
@DefaultFor({"~", "~ help"})
public void help(@NotNull CommandSender sender) {
if (!sender.hasPermission("axtrade.admin")) {
for (String m : LANG.getStringList("player-help")) {
sender.sendMessage(StringUtils.formatToString(m));
}
} else {
for (String m : LANG.getStringList("admin-help")) {
sender.sendMessage(StringUtils.formatToString(m));
}
}
}
@Subcommand("reload")
@CommandPermission(value = "axtrade.admin", defaultAccess = PermissionDefault.OP)
public void reload(@NotNull CommandSender sender) {
Bukkit.getConsoleSender().sendMessage(StringUtils.formatToString("&#00FFDD[AxTrade] &#AAFFDDReloading configuration..."));
if (!CONFIG.reload()) {
MESSAGEUTILS.sendFormatted(sender, "reload.failed", Map.of("%file%", "config.yml"));
return;
}
Bukkit.getConsoleSender().sendMessage(StringUtils.formatToString("&#00FFDD╠ &#AAFFDDReloaded &fconfig.yml&#AAFFDD!"));
if (!LANG.reload()) {
MESSAGEUTILS.sendFormatted(sender, "reload.failed", Map.of("%file%", "lang.yml"));
return;
}
Bukkit.getConsoleSender().sendMessage(StringUtils.formatToString("&#00FFDD╠ &#AAFFDDReloaded &flang.yml&#AAFFDD!"));
if (!GUIS.reload()) {
MESSAGEUTILS.sendFormatted(sender, "reload.failed", Map.of("%file%", "guis.yml"));
return;
}
Bukkit.getConsoleSender().sendMessage(StringUtils.formatToString("&#00FFDD╠ &#AAFFDDReloaded &fguis.yml&#AAFFDD!"));
Commands.registerCommand();
Bukkit.getConsoleSender().sendMessage(StringUtils.formatToString("&#00FFDD╚ &#AAFFDDSuccessful reload!"));
MESSAGEUTILS.sendLang(sender, "reload.success");
}
@Subcommand("force")
@CommandPermission(value = "axtrade.admin", defaultAccess = PermissionDefault.OP)
public void force(@NotNull Player sender, Player other) {
Trades.addTrade(sender, other);
}
public static void registerCommand() {
final BukkitCommandHandler handler = BukkitCommandHandler.create(AxTrade.getInstance());
handler.unregisterAllCommands();
handler.register(Orphans.path(CONFIG.getStringList("command-aliases").toArray(String[]::new)).handler(new Commands()));
handler.registerBrigadier();
}
}

View File

@ -0,0 +1,97 @@
package com.artillexstudios.axtrade.trade;
import com.artillexstudios.axapi.config.Config;
import com.artillexstudios.axapi.utils.NumberUtils;
import com.artillexstudios.axtrade.utils.ItemBuilderUtil;
import dev.triumphteam.gui.components.GuiAction;
import dev.triumphteam.gui.guis.BaseGui;
import dev.triumphteam.gui.guis.GuiItem;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class GuiFrame {
private static final ItemStack air = new ItemStack(Material.AIR);
protected final Config file;
protected BaseGui gui;
protected Player player;
public GuiFrame(Config file, Player player) {
this.file = file;
this.player = player;
}
public void setGui(BaseGui gui) {
this.gui = gui;
for (String str : file.getBackingDocument().getRoutesAsStrings(false)) createItem(str);
}
@NotNull
public Config getFile() {
return file;
}
protected ItemStack buildItem(@NotNull String key) {
if (file.getSection(key) == null) return air;
return ItemBuilderUtil.newBuilder(file.getSection(key), player).get();
}
protected ItemStack buildItem(@NotNull String key, Map<String, String> replacements) {
if (file.getSection(key) == null) return air;
return ItemBuilderUtil.newBuilder(file.getSection(key), replacements, player).get();
}
protected void createItem(@NotNull String route) {
createItem(route, event -> event.setCancelled(true), Map.of());
}
protected void createItem(@NotNull String route, @Nullable GuiAction<InventoryClickEvent> action) {
createItem(route, action, Map.of());
}
protected void createItem(@NotNull String route, @Nullable GuiAction<InventoryClickEvent> action, Map<String, String> replacements) {
createItem(route + ".slot", route, action, replacements);
}
protected void createItem(@NotNull String slotRoute, String itemRoute, @Nullable GuiAction<InventoryClickEvent> action, Map<String, String> replacements) {
createItem(slotRoute, itemRoute, action, replacements, 1);
}
protected void createItem(@NotNull String slotRoute, String itemRoute, @Nullable GuiAction<InventoryClickEvent> action, Map<String, String> replacements, int amount) {
if (file.getString(itemRoute + ".type") == null && file.getString(itemRoute + ".material") == null) return;
final ItemStack it = buildItem(itemRoute, replacements);
it.setAmount(amount);
final GuiItem guiItem = new GuiItem(it, action);
gui.setItem(getSlots(slotRoute), guiItem);
}
protected List<Integer> getSlots(String r) {
final List<Integer> slots = new ArrayList<>();
if (!file.getStringList(r).isEmpty()) {
for (Object route : file.getStringList(r)) {
if (NumberUtils.isInt(("" + route))) {
slots.add(Integer.parseInt(("" + route)));
} else {
String[] split = ("" + route).split("-");
int min = Integer.parseInt(split[0]);
int max = Integer.parseInt(split[1]);
for (int i = min; i <= max; i++) {
slots.add(i);
}
}
}
} else {
slots.add(file.getInt(r));
}
return slots;
}
}

View File

@ -0,0 +1,44 @@
package com.artillexstudios.axtrade.trade;
import com.artillexstudios.axapi.scheduler.Scheduler;
import org.bukkit.entity.Player;
import java.util.Map;
import static com.artillexstudios.axtrade.AxTrade.MESSAGEUTILS;
public class Trade {
protected final TradePlayer player1;
protected final TradePlayer player2;
private boolean ended = false;
public Trade(Player p1, Player p2) {
this.player1 = new TradePlayer(this, p1);
this.player2 = new TradePlayer(this, p2);
player1.setOtherPlayer(player2);
player2.setOtherPlayer(player1);
}
public void update() {
player1.getTradeGui().update();
player2.getTradeGui().update();
}
public void abort() {
if (ended) return;
// todo: refund items
MESSAGEUTILS.sendLang(player1.getPlayer(), "trade-aborted", Map.of("%player%", player2.getPlayer().getName()));
MESSAGEUTILS.sendLang(player2.getPlayer(), "trade-aborted", Map.of("%player%", player1.getPlayer().getName()));
end();
}
public void end() {
if (ended) return;
ended = true;
Scheduler.get().run(scheduledTask -> Trades.removeTrade(Trade.this));
player1.getPlayer().closeInventory();
player1.getPlayer().updateInventory();
player2.getPlayer().closeInventory();
player2.getPlayer().updateInventory();
}
}

View File

@ -0,0 +1,73 @@
package com.artillexstudios.axtrade.trade;
import com.artillexstudios.axapi.scheduler.ScheduledTask;
import com.artillexstudios.axapi.scheduler.Scheduler;
import com.artillexstudios.axapi.utils.StringUtils;
import dev.triumphteam.gui.guis.Gui;
import dev.triumphteam.gui.guis.StorageGui;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import static com.artillexstudios.axtrade.AxTrade.GUIS;
public class TradeGui extends GuiFrame {
private final Trade trade;
private final TradePlayer player;
private final boolean shouldMirror;
protected final StorageGui gui;
protected final List<Integer> slots = getSlots("own-slots");
public TradeGui(@NotNull Trade trade, @NotNull TradePlayer player) {
super(GUIS, player.getPlayer());
this.trade = trade;
this.player = player;
this.shouldMirror = player == trade.player2;
this.gui = Gui.storage()
.rows(GUIS.getInt("rows",6))
.title(StringUtils.format(GUIS.getString("title").replace("%player%", player.getOtherPlayer().getPlayer().getName())))
.create();
setGui(gui);
gui.setDefaultTopClickAction(event -> {
if (!slots.contains(event.getSlot())) {
event.setCancelled(true);
if (event.getCursor() == null) return;
player.getPlayer().getInventory().addItem(event.getCursor().clone());
event.getCursor().setAmount(0);
return;
}
Scheduler.get().run(scheduledTask -> trade.update());
});
update();
gui.open(player.getPlayer());
}
public void update() {
if (player.hasConfirmed()) {
super.createItem("own.confirm-item.slot", "own.confirm-item.cancel", event -> {
event.setCancelled(true);
player.cancel();
}, Map.of(), player.getConfirmed());
} else {
super.createItem("own.confirm-item.slot", "own.confirm-item.accept", event -> {
event.setCancelled(true);
player.confirm();
}, Map.of());
}
if (player.getOtherPlayer().hasConfirmed()) {
super.createItem("partner.confirm-item.slot", "partner.confirm-item.cancel", event -> {
event.setCancelled(true);
}, Map.of(), player.getOtherPlayer().getConfirmed());
} else {
super.createItem("partner.confirm-item.slot", "partner.confirm-item.accept", event -> {
event.setCancelled(true);
}, Map.of());
}
gui.update();
}
}

View File

@ -0,0 +1,67 @@
package com.artillexstudios.axtrade.trade;
import org.bukkit.entity.Player;
import static com.artillexstudios.axtrade.AxTrade.CONFIG;
public class TradePlayer {
private final Player player;
private TradePlayer otherPlayer;
private TradeGui tradeGui;
private final Trade trade;
// confirmed
// null > not confirmed
// number > decrease every sec
private Integer confirmed = null;
public TradePlayer(Trade trade, Player player) {
this.player = player;
this.trade = trade;
}
public void setOtherPlayer(TradePlayer otherPlayer) {
this.otherPlayer = otherPlayer;
this.tradeGui = new TradeGui(trade, this);
}
public Player getPlayer() {
return player;
}
public TradePlayer getOtherPlayer() {
return otherPlayer;
}
public TradeGui getTradeGui() {
return tradeGui;
}
public Integer getConfirmed() {
return confirmed;
}
public boolean hasConfirmed() {
return confirmed != null;
}
public void confirm() {
this.confirmed = CONFIG.getInt("trade-confirm-seconds", 10);
trade.update();
}
public void cancel() {
this.confirmed = null;
otherPlayer.setConfirmed(null);
trade.update();
}
public void setConfirmed(Integer confirmed) {
this.confirmed = confirmed;
}
public void tick() {
confirmed -= 1;
trade.update();
}
}

View File

@ -0,0 +1,30 @@
package com.artillexstudios.axtrade.trade;
import com.artillexstudios.axapi.scheduler.Scheduler;
import java.util.Map;
import static com.artillexstudios.axtrade.AxTrade.MESSAGEUTILS;
public class TradeTicker {
public void start() {
Scheduler.get().runTimer(scheduledTask -> {
for (Trade trade : Trades.getTrades()) {
if (!(trade.player1.hasConfirmed() && trade.player2.hasConfirmed())) continue;
if (trade.player1.getConfirmed() == 1) {
MESSAGEUTILS.sendLang(trade.player1.getPlayer(), "trade-completed", Map.of("%player%", trade.player2.getPlayer().getName()));
MESSAGEUTILS.sendLang(trade.player2.getPlayer(), "trade-completed", Map.of("%player%", trade.player1.getPlayer().getName()));
// todo: transfer items
trade.end();
continue;
}
trade.player1.tick();
trade.player2.tick();
}
}, 20, 20);
}
}

View File

@ -0,0 +1,27 @@
package com.artillexstudios.axtrade.trade;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Map;
import static com.artillexstudios.axtrade.AxTrade.MESSAGEUTILS;
public class Trades {
private static final ArrayList<Trade> trades = new ArrayList<>();
public static void addTrade(Player p1, Player p2) {
Trade trade = new Trade(p1, p2);
trades.add(trade);
MESSAGEUTILS.sendLang(p1, "trade-started", Map.of("%player%", p2.getName()));
MESSAGEUTILS.sendLang(p2, "trade-started", Map.of("%player%", p1.getName()));
}
public static void removeTrade(Trade trade) {
trades.remove(trade);
}
public static ArrayList<Trade> getTrades() {
return trades;
}
}

View File

@ -0,0 +1,47 @@
package com.artillexstudios.axtrade.utils;
import com.artillexstudios.axapi.libs.boostedyaml.boostedyaml.block.implementation.Section;
import com.artillexstudios.axapi.utils.ClassUtils;
import com.artillexstudios.axapi.utils.ItemBuilder;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
public class ItemBuilderUtil {
@NotNull
public static ItemBuilder newBuilder(@NotNull Section section, @Nullable Player player) {
return newBuilder(section, Map.of(), player);
}
@NotNull
public static ItemBuilder newBuilder(@NotNull Section section, Map<String, String> replacements, @Nullable Player player) {
final ItemBuilder builder = new ItemBuilder(section);
section.getOptionalString("name").ifPresent((name) -> {
if (ClassUtils.classExists("me.clip.placeholderapi.PlaceholderAPI")) {
name = me.clip.placeholderapi.PlaceholderAPI.setPlaceholders(player, name);
}
builder.setName(name, replacements);
});
section.getOptionalStringList("lore").ifPresent((lore) -> {
if (ClassUtils.classExists("me.clip.placeholderapi.PlaceholderAPI")) {
lore = me.clip.placeholderapi.PlaceholderAPI.setPlaceholders(player, lore);
}
builder.setLore(lore, replacements);
});
return builder;
}
@NotNull
@Contract("_ -> new")
public static ItemBuilder newBuilder(@NotNull ItemStack itemStack) {
return new ItemBuilder(itemStack);
}
}

View File

@ -0,0 +1,13 @@
prefix: "&#00ffdd&lAxTrade &7» "
# you must define at least 1
# reloading will add new commands, however a restart is recommended when editing this
command-aliases:
- "axtrade"
- "trade"
# the time after clicking the trade confirm button before the trade finishes
trade-confirm-seconds: 10
# do not change this
version: 1

118
src/main/resources/guis.yml Normal file
View File

@ -0,0 +1,118 @@
# ----- SETTINGS -----
title: "&0Trading with: %player%"
# a gui can have 1-6 rows
rows: 6
# ----- SLOTS -----
# the slots where the items can be placed
# make sure to not put decorative items in the these slots (or change this too)
# the own-slots and partner-slots must have an equal amount of slots
own-slots:
- 9-12
- 18-21
- 27-30
- 36-39
- 45-48
partner-slots:
- 14-17
- 23-26
- 32-35
- 41-44
- 50-53
# ----- ITEMS -----
# items on your side
own:
confirm-item:
slot: 0
accept:
material: "RED_CONCRETE"
name: "&#00ffdd&lᴀᴇᴘᴛ ᴛʀᴀᴅᴇ"
lore:
- ""
- " &7- &fAre you happy with the trade?"
- ""
- "&#00ffdd&l> &#00ffddClick &8- &#00ffddConfirm Trade"
cancel:
material: "LIME_CONCRETE"
name: "&#00ffdd&lᴀɴᴇʟ ᴄᴏɴғɪʀᴍᴀᴛɪᴏɴ"
lore:
- ""
- " &7- &fDo you want to change something?"
- ""
- "&#00ffdd&l> &#00ffddClick &8- &#00ffddCancel Confirmation"
# you can define as many currencies as you want, also make sure to copy them to the 'partner' section!
currency1:
slot: 2
# you need Vault installed for this
currency: "vault:money"
material: "GOLD_NUGGET"
name: "&#00ffdd&lᴍɴᴇʏ"
lore:
- ""
- " &7- &fAmount:"
- ""
- "&#00ffdd&l> &#00ffddClick &8- &#00ffddChange Amount"
currency2:
slot: 3
# you need Vault installed for this
currency: "vanilla:experience"
material: "EXPERIENCE_BOTTLE"
name: "&#00ffdd&lᴇxᴘᴇʀɪᴇɴᴇ"
lore:
- ""
- " &7- &fAmount:"
- ""
- "&#00ffdd&l> &#00ffddClick &8- &#00ffddChange Amount"
# items on your trade partner's side
partner:
confirm-item:
slot: 8
accept:
material: "RED_CONCRETE"
name: "&#00ffdd&lɪɪɴɢ ғᴏʀ ᴏᴛʜᴇʀ ᴘʟᴀʏᴇʀ"
lore:
- ""
- " &7- &fThe other player has not yet confirmed the trade!"
- ""
cancel:
material: "LIME_CONCRETE"
name: "&#00ffdd&lɪɪɴɢ ғᴏʀ ʏ"
lore:
- ""
- " &7- &fThe other player has confirmed the trade!"
currency1:
slot: 6
# you need Vault installed for this
currency: "vault:money"
material: "GOLD_NUGGET"
name: "&#00ffdd&lᴍɴᴇʏ"
lore:
- ""
- " &7- &fAmount:"
- ""
- "&#00ffdd&l> &#00ffddClick &8- &#00ffddChange Amount"
currency2:
slot: 5
# you need Vault installed for this
currency: "vanilla:experience"
material: "EXPERIENCE_BOTTLE"
name: "&#00ffdd&lᴇxᴘᴇʀɪᴇɴᴇ"
lore:
- ""
- " &7- &fAmount:"
- ""
- "&#00ffdd&l> &#00ffddClick &8- &#00ffddChange Amount"
decoration-example:
slot: [4, 13, 22, 31, 40, 49]
material: "LIGHT_BLUE_STAINED_GLASS_PANE"
name: " "
# do not change this
version: 1

View File

@ -0,0 +1,23 @@
player-help:
- " "
- "&#00FFDD&lAxTrade &7»"
- " &7- &f/axtrade <player> &7| &#00FFDDSend trade request"
- " "
admin-help:
- " "
- "&#00FFDD&lAxTrade &7»"
- " &7- &f/axtrade <player> &7| &#00FFDDSend trade request"
- " &7- &f/axtrade reload &7| &#00FFDDReload plugin"
- " "
reload:
success: "&#33FF33Plugin successfully reloaded!"
failed: "&#FF3333Failed to reload the plugin! Something is wrong in the &f%file%&#FF3333 file, look in the console or use a yaml validator to fix the errors!"
trade-started: "&#CCFFEEYou have started a trade with &#00FFDD%player%&#CCFFEE!"
trade-aborted: "&#CCFFEEYour trade with &#00FFDD%player% &#CCFFEEwas aborted!"
trade-completed: "&#CCFFEEYour trade with &#00FFDD%player% &#CCFFEEwas completed!"
# do not change this
version: 1

View File

@ -0,0 +1,8 @@
name: AxTrade
version: '${project.version}'
main: com.artillexstudios.axtrade.AxTrade
api-version: '1.18'
folia-supported: true
softdepend:
- PlaceholderAPI