Upload folder via GUI - src
This commit is contained in:
@@ -92,6 +92,12 @@ public class IngameShopSpigot extends JavaPlugin implements Listener {
|
||||
private Map<Integer, OrderData> orderCache = new HashMap<>();
|
||||
private Map<UUID, Integer> activeOrderIds = new ConcurrentHashMap<>();
|
||||
|
||||
// Gift-System: Ausstehende Geschenk-Anfragen (Empfänger-UUID → OrderData)
|
||||
private final Map<UUID, GiftRequest> pendingGiftRequests = new ConcurrentHashMap<>();
|
||||
// URL für Geschenk-Endpoint und Rückerstattungs-Endpoint
|
||||
private String wpUrlGiftAccept;
|
||||
private String wpUrlGiftDecline;
|
||||
|
||||
private FlyManager flyManager;
|
||||
private FlyCodeManager flyCodeManager;
|
||||
private RankManager rankManager;
|
||||
@@ -134,6 +140,8 @@ public class IngameShopSpigot extends JavaPlugin implements Listener {
|
||||
wpUrlCancel = wpBase + "/cancel_order";
|
||||
wpUrlSellItems = wpBase + "/sell_items";
|
||||
wpUrlSell = wpBase + "/sell_item";
|
||||
wpUrlGiftAccept = wpBase + "/gift_accept";
|
||||
wpUrlGiftDecline = wpBase + "/gift_decline";
|
||||
|
||||
targetServer = getConfig().getString("server-name", "survival").toLowerCase();
|
||||
currency = getConfig().getString("currency-name", "Coins");
|
||||
@@ -280,7 +288,6 @@ public class IngameShopSpigot extends JavaPlugin implements Listener {
|
||||
"Spieler " + p.getName() + " hat aktive Order – überspringe.");
|
||||
continue;
|
||||
}
|
||||
// Join-Fetch läuft noch – nicht parallel pollen
|
||||
Long cooldown = joinFetchCooldown.get(p.getUniqueId());
|
||||
if (cooldown != null && System.currentTimeMillis() < cooldown) {
|
||||
if (debug) getLogger().info(
|
||||
@@ -328,20 +335,27 @@ public class IngameShopSpigot extends JavaPlugin implements Listener {
|
||||
String itemTitle = order.get("item_title").getAsString();
|
||||
double price = order.get("price").getAsDouble();
|
||||
|
||||
// Atomar: nur wenn noch keine aktive Order → eintragen und GUI öffnen
|
||||
// synchronized auf activeOrderIds verhindert Race Condition zwischen zwei Async-Threads
|
||||
// Gift-Empfänger auslesen – leer bei normalen Käufen
|
||||
String giftRecipient = (order.has("gift_recipient")
|
||||
&& !order.get("gift_recipient").isJsonNull())
|
||||
? order.get("gift_recipient").getAsString().trim() : "";
|
||||
|
||||
// Spieler A bestätigt IMMER zuerst selbst (verhindert Missbrauch).
|
||||
// giftRecipient wird in OrderData gespeichert und erst nach
|
||||
// Bestätigung + Geld-Abbuchung an Spieler B weitergeleitet.
|
||||
synchronized (activeOrderIds) {
|
||||
if (activeOrderIds.containsKey(p.getUniqueId())) {
|
||||
if (debug) getLogger().info(
|
||||
"Order #" + id + " für " + p.getName() + " ignoriert (bereits aktiv).");
|
||||
return;
|
||||
}
|
||||
OrderData data = new OrderData(id, "multi_item", itemTitle, price, 1, jsonResponse);
|
||||
OrderData data = new OrderData(id, "multi_item", itemTitle,
|
||||
price, 1, jsonResponse, giftRecipient);
|
||||
orderCache.put(id, data);
|
||||
activeOrderIds.put(p.getUniqueId(), id);
|
||||
}
|
||||
Bukkit.getScheduler().runTask(IngameShopSpigot.this,
|
||||
() -> openConfirmGUI(p, id, itemTitle, price, jsonResponse));
|
||||
() -> openConfirmGUI(p, id, itemTitle, price, jsonResponse, giftRecipient));
|
||||
}
|
||||
} else if (responseCode == 401) {
|
||||
getLogger().warning("❌ API-Key ungültig! HTTP 401 von " + endpointUrl);
|
||||
@@ -351,6 +365,224 @@ public class IngameShopSpigot extends JavaPlugin implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// GIFT-SYSTEM
|
||||
// ===========================================================
|
||||
|
||||
/**
|
||||
* Wird aufgerufen wenn eine Order ein gift_recipient-Feld hat.
|
||||
* Leitet die Anfrage an den Empfänger (Spieler B) weiter.
|
||||
* Falls Spieler B offline → Order bleibt pending (wird beim nächsten Join geholt).
|
||||
*/
|
||||
private void handleIncomingGift(String senderName, String recipientName,
|
||||
int orderId, String itemTitle,
|
||||
double price, String jsonResponse) {
|
||||
Player recipient = Bukkit.getPlayerExact(recipientName);
|
||||
if (recipient == null || !recipient.isOnline()) {
|
||||
// Empfänger offline – Order bleibt pending, beim Join wird sie erneut gepollt
|
||||
if (debug) getLogger().info(
|
||||
"[Gift] Empfänger " + recipientName + " offline – warte auf Join.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Empfänger bereits mit offener Gift-Anfrage?
|
||||
if (pendingGiftRequests.containsKey(recipient.getUniqueId())) {
|
||||
if (debug) getLogger().info(
|
||||
"[Gift] " + recipientName + " hat bereits eine offene Gift-Anfrage.");
|
||||
return;
|
||||
}
|
||||
|
||||
GiftRequest req = new GiftRequest(orderId, senderName, recipientName,
|
||||
itemTitle, price, jsonResponse);
|
||||
pendingGiftRequests.put(recipient.getUniqueId(), req);
|
||||
orderCache.put(orderId, new OrderData(orderId, "multi_item", itemTitle, price, 1, jsonResponse));
|
||||
|
||||
// Order auf WP auf 'processing' setzen damit sie nicht nochmal gepollt wird
|
||||
// (A hat bereits bezahlt, B muss nur noch annehmen/ablehnen)
|
||||
new BukkitRunnable() {
|
||||
@Override public void run() {
|
||||
try {
|
||||
HttpURLConnection conn = openAuthConnection(wpUrlExecute, "POST");
|
||||
writeJson(conn, "{\"id\":\"" + orderId + "\"}");
|
||||
conn.getResponseCode();
|
||||
} catch (Exception e) {
|
||||
if (debug) getLogger().log(Level.WARNING, "[Gift] Status-Update Fehler", e);
|
||||
}
|
||||
}
|
||||
}.runTaskAsynchronously(this);
|
||||
|
||||
Bukkit.getScheduler().runTask(this, () -> openGiftConfirmGUI(recipient, req));
|
||||
}
|
||||
|
||||
/** Öffnet dem Empfänger das Gift-Bestätigungs-GUI */
|
||||
private void openGiftConfirmGUI(Player recipient, GiftRequest req) {
|
||||
Inventory gui = Bukkit.createInventory(null, 27, GUI_GIFT_TITLE);
|
||||
|
||||
ItemStack pane = new ItemStack(Material.BLACK_STAINED_GLASS_PANE);
|
||||
ItemMeta pM = pane.getItemMeta();
|
||||
pM.setDisplayName(" ");
|
||||
pane.setItemMeta(pM);
|
||||
for (int i = 0; i < 27; i++) gui.setItem(i, pane);
|
||||
|
||||
// Info-Item in der Mitte
|
||||
Material icon = getFirstItemMaterial(req.jsonPayload);
|
||||
ItemStack info = new ItemStack(icon);
|
||||
ItemMeta infoMeta = info.getItemMeta();
|
||||
infoMeta.setDisplayName(ChatColor.GOLD + "" + ChatColor.BOLD + req.itemTitle);
|
||||
infoMeta.setLore(Arrays.asList(
|
||||
ChatColor.GRAY + "──────────────────",
|
||||
ChatColor.WHITE + "Von: " + ChatColor.YELLOW + req.senderName,
|
||||
ChatColor.WHITE + "Wert: " + ChatColor.YELLOW + req.price + " " + currency,
|
||||
ChatColor.GRAY + "──────────────────",
|
||||
ChatColor.GREEN + "🎁 Du hast ein Geschenk erhalten!",
|
||||
ChatColor.GRAY + "Annehmen oder ablehnen?"
|
||||
));
|
||||
info.setItemMeta(infoMeta);
|
||||
|
||||
// Annehmen
|
||||
ItemStack yes = new ItemStack(Material.LIME_WOOL);
|
||||
ItemMeta yM = yes.getItemMeta();
|
||||
yM.setDisplayName(ChatColor.GREEN + "" + ChatColor.BOLD + "✔ Annehmen");
|
||||
yM.setLore(Arrays.asList(ChatColor.GRAY + "Geschenk wird dir übergeben"));
|
||||
yes.setItemMeta(yM);
|
||||
|
||||
// Ablehnen
|
||||
ItemStack no = new ItemStack(Material.RED_WOOL);
|
||||
ItemMeta nM = no.getItemMeta();
|
||||
nM.setDisplayName(ChatColor.RED + "" + ChatColor.BOLD + "✘ Ablehnen");
|
||||
nM.setLore(Arrays.asList(
|
||||
ChatColor.GRAY + "Bestellung wird storniert,",
|
||||
ChatColor.GRAY + req.senderName + " erhält sein Geld zurück"
|
||||
));
|
||||
no.setItemMeta(nM);
|
||||
|
||||
gui.setItem(13, info);
|
||||
gui.setItem(11, yes);
|
||||
gui.setItem(15, no);
|
||||
recipient.openInventory(gui);
|
||||
}
|
||||
|
||||
/** Empfänger nimmt Geschenk an → Ware ausliefern */
|
||||
private void acceptGift(Player recipient, GiftRequest req) {
|
||||
// pendingGiftRequests wurde bereits im Click-Handler entfernt (vor closeInventory)
|
||||
|
||||
// "__GIFT_DELIVERY__" signalisiert executeShopLogic: kein Geldabzug, kein incomeReceiver
|
||||
// (Geld wurde bereits bei A's Bestätigung abgezogen)
|
||||
final OrderData deliverData = new OrderData(req.orderId, "multi_item", req.itemTitle,
|
||||
req.price, 1, req.jsonPayload, "__GIFT_DELIVERY__");
|
||||
|
||||
recipient.sendMessage(ChatColor.GREEN + "🎁 Du hast das Geschenk von "
|
||||
+ ChatColor.YELLOW + req.senderName
|
||||
+ ChatColor.GREEN + " angenommen!");
|
||||
|
||||
// Ware direkt ausliefern (Geld wurde bereits von Käufer A abgezogen)
|
||||
// executeShopLogic ruft intern markOrderCompleted auf → WP-Status wird 'completed'
|
||||
executeShopLogic(recipient, deliverData, req.orderId);
|
||||
|
||||
// Sender benachrichtigen falls online
|
||||
Player sender = Bukkit.getPlayerExact(req.senderName);
|
||||
if (sender != null && sender.isOnline()) {
|
||||
sender.sendMessage(ChatColor.GREEN + "🎁 " + ChatColor.YELLOW + recipient.getName()
|
||||
+ ChatColor.GREEN + " hat dein Geschenk angenommen!");
|
||||
sender.playSound(sender.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1.0F, 1.2F);
|
||||
}
|
||||
}
|
||||
|
||||
/** Empfänger lehnt Geschenk ab → Stornierung + Rückerstattung an Käufer */
|
||||
private void declineGift(Player recipient, GiftRequest req) {
|
||||
pendingGiftRequests.remove(recipient.getUniqueId());
|
||||
orderCache.remove(req.orderId);
|
||||
|
||||
recipient.sendMessage(ChatColor.YELLOW + "❌ Geschenk abgelehnt.");
|
||||
|
||||
new BukkitRunnable() {
|
||||
@Override public void run() {
|
||||
try {
|
||||
// 1) Order auf WordPress stornieren
|
||||
HttpURLConnection conn = openAuthConnection(wpUrlGiftDecline, "POST");
|
||||
writeJson(conn, "{\"id\":\"" + req.orderId + "\""
|
||||
+ ",\"sender\":\"" + req.senderName + "\""
|
||||
+ ",\"price\":" + (int) req.price + "}");
|
||||
int code = conn.getResponseCode();
|
||||
if (debug) getLogger().info(
|
||||
"[Gift] Decline HTTP " + code + " für Order #" + req.orderId);
|
||||
|
||||
// 2) Rückerstattung an Käufer (Vault)
|
||||
Bukkit.getScheduler().runTask(IngameShopSpigot.this, () -> {
|
||||
@SuppressWarnings("deprecation")
|
||||
org.bukkit.OfflinePlayer buyer =
|
||||
Bukkit.getOfflinePlayerIfCached(req.senderName);
|
||||
if (buyer == null) {
|
||||
for (org.bukkit.OfflinePlayer op : Bukkit.getOfflinePlayers()) {
|
||||
if (op.getName() != null
|
||||
&& op.getName().equalsIgnoreCase(req.senderName)) {
|
||||
buyer = op;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buyer != null) {
|
||||
econ.depositPlayer(buyer, req.price);
|
||||
if (debug) getLogger().info(
|
||||
"[Gift] Rückerstattung " + req.price + " " + currency
|
||||
+ " an " + req.senderName);
|
||||
}
|
||||
|
||||
// Käufer benachrichtigen falls online
|
||||
Player senderOnline = Bukkit.getPlayerExact(req.senderName);
|
||||
if (senderOnline != null && senderOnline.isOnline()) {
|
||||
senderOnline.sendMessage(ChatColor.RED
|
||||
+ "🎁 " + ChatColor.YELLOW + recipient.getName()
|
||||
+ ChatColor.RED + " hat dein Geschenk abgelehnt.");
|
||||
senderOnline.sendMessage(ChatColor.GREEN
|
||||
+ "💰 " + req.price + " " + currency
|
||||
+ " wurden dir erstattet.");
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
getLogger().log(Level.WARNING, "[Gift] Fehler bei decline", e);
|
||||
}
|
||||
}
|
||||
}.runTaskAsynchronously(this);
|
||||
}
|
||||
|
||||
// Gift-GUI Polling starten (Empfänger-Polling beim Join)
|
||||
private void checkGiftOrdersForPlayer(Player p) {
|
||||
new BukkitRunnable() {
|
||||
@Override public void run() {
|
||||
try {
|
||||
HttpURLConnection conn = openAuthConnection(
|
||||
wpBase + "/pending_gifts?recipient=" + p.getName(), "GET");
|
||||
int code = conn.getResponseCode();
|
||||
if (code != 200) return;
|
||||
String body = readResponse(conn);
|
||||
JsonObject json = JsonParser.parseString(body).getAsJsonObject();
|
||||
JsonArray orders = json.getAsJsonArray("orders");
|
||||
if (orders == null || orders.size() == 0) return;
|
||||
|
||||
JsonObject order = orders.get(0).getAsJsonObject();
|
||||
int id = order.get("id").getAsInt();
|
||||
String senderName = order.has("player_name")
|
||||
? order.get("player_name").getAsString() : "?";
|
||||
String orderServer = order.has("server")
|
||||
? order.get("server").getAsString().toLowerCase() : "";
|
||||
if (!orderServer.equals(targetServer)) return;
|
||||
|
||||
String jsonResponse = order.has("response")
|
||||
? order.get("response").getAsString() : "[]";
|
||||
String itemTitle = order.get("item_title").getAsString();
|
||||
double price = order.get("price").getAsDouble();
|
||||
|
||||
handleIncomingGift(senderName, p.getName(), id, itemTitle, price, jsonResponse);
|
||||
} catch (Exception e) {
|
||||
if (debug) getLogger().log(Level.WARNING, "[Gift] Polling Fehler", e);
|
||||
}
|
||||
}
|
||||
}.runTaskAsynchronously(this);
|
||||
}
|
||||
|
||||
private static final String GUI_GIFT_TITLE = ChatColor.GOLD + "🎁 Geschenk erhalten!";
|
||||
|
||||
// ===========================================================
|
||||
// OFFLINE-QUEUE & FLY-RESTORE
|
||||
// ===========================================================
|
||||
@@ -394,6 +626,11 @@ public class IngameShopSpigot extends JavaPlugin implements Listener {
|
||||
}.runTaskAsynchronously(this);
|
||||
}
|
||||
|
||||
// Ausstehende Gift-Orders prüfen (Spieler B ist jetzt online)
|
||||
new BukkitRunnable() {
|
||||
@Override public void run() { checkGiftOrdersForPlayer(p); }
|
||||
}.runTaskAsynchronously(this);
|
||||
|
||||
// Ausstehende Fly-Codes anzeigen
|
||||
new BukkitRunnable() {
|
||||
@Override public void run() {
|
||||
@@ -464,8 +701,21 @@ public class IngameShopSpigot extends JavaPlugin implements Listener {
|
||||
if (!(event.getPlayer() instanceof Player)) return;
|
||||
Player p = (Player) event.getPlayer();
|
||||
|
||||
// Confirm-GUI: bei ESC sofort wieder öffnen
|
||||
// Titel zuerst holen – wird für beide GUI-Checks benötigt
|
||||
String title = event.getView().getTitle();
|
||||
|
||||
// Gift-Confirm-GUI: bei ESC sofort wieder öffnen
|
||||
if (GUI_GIFT_TITLE.equals(title) && pendingGiftRequests.containsKey(p.getUniqueId())) {
|
||||
GiftRequest req = pendingGiftRequests.get(p.getUniqueId());
|
||||
if (req != null) {
|
||||
p.sendMessage(ChatColor.YELLOW + "⚠ Bitte nimm das Geschenk an oder lehne es ab!");
|
||||
Bukkit.getScheduler().runTaskLater(this,
|
||||
() -> openGiftConfirmGUI(p, req), 2L);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Confirm-GUI: bei ESC sofort wieder öffnen
|
||||
if (GUI_CONFIRM_TITLE.equals(title) && activeOrderIds.containsKey(p.getUniqueId())) {
|
||||
int orderId = activeOrderIds.get(p.getUniqueId());
|
||||
OrderData data = orderCache.get(orderId);
|
||||
@@ -494,24 +744,40 @@ public class IngameShopSpigot extends JavaPlugin implements Listener {
|
||||
|
||||
private void openConfirmGUI(Player player, int orderId,
|
||||
String itemTitle, double price, String jsonPayload) {
|
||||
openConfirmGUI(player, orderId, itemTitle, price, jsonPayload, "");
|
||||
}
|
||||
|
||||
private void openConfirmGUI(Player player, int orderId,
|
||||
String itemTitle, double price,
|
||||
String jsonPayload, String giftRecipient) {
|
||||
Inventory gui = Bukkit.createInventory(null, 27, GUI_CONFIRM_TITLE);
|
||||
Material icon = getFirstItemMaterial(jsonPayload);
|
||||
|
||||
boolean isGift = giftRecipient != null && !giftRecipient.isEmpty();
|
||||
|
||||
ItemStack info = new ItemStack(icon);
|
||||
ItemMeta infoMeta = info.getItemMeta();
|
||||
infoMeta.setDisplayName(ChatColor.GOLD + "" + ChatColor.BOLD + itemTitle);
|
||||
infoMeta.setLore(Arrays.asList(
|
||||
infoMeta.setDisplayName(ChatColor.GOLD + "" + ChatColor.BOLD
|
||||
+ (isGift ? "🎁 " : "") + itemTitle);
|
||||
List<String> lore = new ArrayList<>(Arrays.asList(
|
||||
ChatColor.GRAY + "──────────────────",
|
||||
ChatColor.WHITE + "Preis: " + ChatColor.YELLOW + price + " " + currency,
|
||||
ChatColor.GRAY + "──────────────────",
|
||||
ChatColor.GRAY + "Klicke Grün zum Bestätigen",
|
||||
ChatColor.GRAY + "Klicke Rot zum Abbrechen"
|
||||
ChatColor.WHITE + "Preis: " + ChatColor.YELLOW + price + " " + currency
|
||||
));
|
||||
if (isGift) {
|
||||
lore.add(ChatColor.LIGHT_PURPLE + "Geschenk für: "
|
||||
+ ChatColor.WHITE + giftRecipient);
|
||||
lore.add(ChatColor.GRAY + "Der Empfänger muss ingame annehmen.");
|
||||
}
|
||||
lore.add(ChatColor.GRAY + "──────────────────");
|
||||
lore.add(ChatColor.GRAY + "Klicke Grün zum Bestätigen");
|
||||
lore.add(ChatColor.GRAY + "Klicke Rot zum Abbrechen");
|
||||
infoMeta.setLore(lore);
|
||||
info.setItemMeta(infoMeta);
|
||||
|
||||
ItemStack yes = new ItemStack(Material.LIME_WOOL);
|
||||
ItemMeta yM = yes.getItemMeta();
|
||||
yM.setDisplayName(ChatColor.GREEN + "" + ChatColor.BOLD + "✔ JA, kaufen!");
|
||||
yM.setDisplayName(ChatColor.GREEN + "" + ChatColor.BOLD
|
||||
+ (isGift ? "🎁 JA, verschenken!" : "✔ JA, kaufen!"));
|
||||
yM.setLore(Arrays.asList(
|
||||
ChatColor.GRAY + "" + price + " " + currency + " werden abgezogen"));
|
||||
yes.setItemMeta(yM);
|
||||
@@ -565,6 +831,28 @@ public class IngameShopSpigot extends JavaPlugin implements Listener {
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
String title = event.getView().getTitle();
|
||||
|
||||
// ── Gift-Bestätigen GUI ────────────────────────────────────────────
|
||||
if (GUI_GIFT_TITLE.equals(title)) {
|
||||
event.setCancelled(true);
|
||||
if (!(event.getWhoClicked() instanceof Player)) return;
|
||||
Player p = (Player) event.getWhoClicked();
|
||||
int slot = event.getRawSlot();
|
||||
GiftRequest req = pendingGiftRequests.get(p.getUniqueId());
|
||||
if (req == null) { p.closeInventory(); return; }
|
||||
if (slot == 11) {
|
||||
// ERST aus pendingGiftRequests entfernen, DANN closeInventory –
|
||||
// sonst triggert onInventoryClose das GUI erneut
|
||||
pendingGiftRequests.remove(p.getUniqueId());
|
||||
p.closeInventory();
|
||||
acceptGift(p, req);
|
||||
} else if (slot == 15) {
|
||||
pendingGiftRequests.remove(p.getUniqueId());
|
||||
p.closeInventory();
|
||||
declineGift(p, req);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// ── Sell GUI ──────────────────────────────────────────────────────
|
||||
if (handleSellClick(event)) return;
|
||||
|
||||
@@ -840,18 +1128,21 @@ public class IngameShopSpigot extends JavaPlugin implements Listener {
|
||||
|
||||
private void executeShopLogic(Player player, OrderData data, int orderId) {
|
||||
try {
|
||||
if (econ.getBalance(player) < data.price) {
|
||||
player.sendMessage(ChatColor.RED + "❌ Nicht genug "
|
||||
+ currency + "! (Benötigt: " + data.price + ")");
|
||||
cancelOrder(player, orderId);
|
||||
return;
|
||||
// Bei Geschenk-Lieferung an B: kein Geldabzug – Geld wurde bereits von A abgezogen
|
||||
boolean isGiftDelivery = data.giftRecipient != null && data.giftRecipient.equals("__GIFT_DELIVERY__");
|
||||
if (!isGiftDelivery) {
|
||||
if (econ.getBalance(player) < data.price) {
|
||||
player.sendMessage(ChatColor.RED + "❌ Nicht genug "
|
||||
+ currency + "! (Benötigt: " + data.price + ")");
|
||||
cancelOrder(player, orderId);
|
||||
return;
|
||||
}
|
||||
econ.withdrawPlayer(player, data.price);
|
||||
player.sendMessage(ChatColor.GREEN + "💰 " + data.price + " " + currency + " abgezogen.");
|
||||
}
|
||||
|
||||
econ.withdrawPlayer(player, data.price);
|
||||
player.sendMessage(ChatColor.GREEN + "💰 " + data.price + " " + currency + " abgezogen.");
|
||||
|
||||
// Einnahmen an Empfänger-Account gutschreiben
|
||||
if (!incomeReceiver.isEmpty()) {
|
||||
// Einnahmen an Empfänger-Account gutschreiben (nicht bei Gift-Lieferung – bereits bei A gebucht)
|
||||
if (!isGiftDelivery && !incomeReceiver.isEmpty()) {
|
||||
try {
|
||||
@SuppressWarnings("deprecation")
|
||||
org.bukkit.OfflinePlayer receiver =
|
||||
@@ -878,6 +1169,20 @@ public class IngameShopSpigot extends JavaPlugin implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
// ── Gift-System: Ware geht an Empfänger B, nicht an Käufer A ──────
|
||||
// Direkt nach Geldabzug prüfen – BEVOR irgendwelche Items/Commands verteilt werden
|
||||
if (!isGiftDelivery && data.giftRecipient != null && !data.giftRecipient.isEmpty()) {
|
||||
player.sendMessage(ChatColor.LIGHT_PURPLE + "🎁 Dein Geschenk wird an "
|
||||
+ ChatColor.WHITE + data.giftRecipient
|
||||
+ ChatColor.LIGHT_PURPLE + " gesendet!");
|
||||
player.sendMessage(ChatColor.GRAY + "Der Empfänger muss es ingame annehmen.");
|
||||
handleIncomingGift(player.getName(), data.giftRecipient,
|
||||
orderId, data.itemTitle, data.price, data.jsonPayload);
|
||||
orderCache.remove(orderId);
|
||||
return;
|
||||
}
|
||||
// ────────────────────────────────────────────────────────────────
|
||||
|
||||
JsonElement root = gson.fromJson(data.jsonPayload, JsonElement.class);
|
||||
JsonObject rootObj = root.isJsonObject() ? root.getAsJsonObject() : null;
|
||||
|
||||
@@ -3293,6 +3598,8 @@ public class IngameShopSpigot extends JavaPlugin implements Listener {
|
||||
wpUrlCancel = wpBase + "/cancel_order";
|
||||
wpUrlSellItems = wpBase + "/sell_items";
|
||||
wpUrlSell = wpBase + "/sell_item";
|
||||
wpUrlGiftAccept = wpBase + "/gift_accept";
|
||||
wpUrlGiftDecline = wpBase + "/gift_decline";
|
||||
|
||||
targetServer = getConfig().getString("server-name", "survival").toLowerCase();
|
||||
currency = getConfig().getString("currency-name", "Coins");
|
||||
@@ -4231,23 +4538,49 @@ public class IngameShopSpigot extends JavaPlugin implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// GIFT REQUEST DATA CLASS
|
||||
// ===========================================================
|
||||
|
||||
private static class GiftRequest {
|
||||
final int orderId;
|
||||
final String senderName, recipientName, itemTitle, jsonPayload;
|
||||
final double price;
|
||||
|
||||
GiftRequest(int orderId, String senderName, String recipientName,
|
||||
String itemTitle, double price, String jsonPayload) {
|
||||
this.orderId = orderId;
|
||||
this.senderName = senderName;
|
||||
this.recipientName = recipientName;
|
||||
this.itemTitle = itemTitle;
|
||||
this.price = price;
|
||||
this.jsonPayload = jsonPayload;
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// DATA CLASS
|
||||
// ===========================================================
|
||||
|
||||
private static class OrderData {
|
||||
final int id, quantity;
|
||||
final String itemId, itemTitle, jsonPayload;
|
||||
final String itemId, itemTitle, jsonPayload, giftRecipient;
|
||||
final double price;
|
||||
|
||||
OrderData(int id, String itemId, String itemTitle,
|
||||
double price, int quantity, String jsonPayload) {
|
||||
this.id = id;
|
||||
this.itemId = itemId;
|
||||
this.itemTitle = itemTitle;
|
||||
this.price = price;
|
||||
this.quantity = quantity;
|
||||
this.jsonPayload = jsonPayload;
|
||||
this(id, itemId, itemTitle, price, quantity, jsonPayload, "");
|
||||
}
|
||||
|
||||
OrderData(int id, String itemId, String itemTitle,
|
||||
double price, int quantity, String jsonPayload, String giftRecipient) {
|
||||
this.id = id;
|
||||
this.itemId = itemId;
|
||||
this.itemTitle = itemTitle;
|
||||
this.price = price;
|
||||
this.quantity = quantity;
|
||||
this.jsonPayload = jsonPayload;
|
||||
this.giftRecipient = giftRecipient != null ? giftRecipient : "";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user