Skip to content

开发文档 ​

提示

开发依赖可在售后群下载,开发交流请联系作者 15568820

事件 ​

Cancellable 事件可取消;物品数据(快照)只能读取不可修改,货币报价可在更新前修改。取消事件不包含离线、关闭界面等强制结束

kotlin
package me.yeezhi.soultrade.api.event

import me.yeezhi.soultrade.api.entity.trade.TradeResult
import me.yeezhi.soultrade.api.entity.trade.TradeRequest
import org.bukkit.event.Cancellable
import org.bukkit.event.Event
import org.bukkit.event.HandlerList

/**
 * 交易请求事件
 */
object TradeRequestEvent {
    /**
     * 请求发送前,可取消
     * @param requester 发起方数据
     * @param target 接收方数据
     */
    class Before(
        val requester: TradeResult,
        val target: TradeResult
    ) : Event(), Cancellable {

        private var cancelled: Boolean = false

        override fun isCancelled(): Boolean = cancelled

        override fun setCancelled(cancel: Boolean) {
            cancelled = cancel
        }

        override fun getHandlers(): HandlerList = handlerList

        companion object {
            @JvmStatic
            val handlerList = HandlerList()
        }
    }

    /**
     * 请求创建后
     * @param request 请求数据
     * @param requester 发起方数据
     * @param target 接收方数据
     */
    class After(
        val request: TradeRequest,
        val requester: TradeResult,
        val target: TradeResult
    ) : Event() {

        override fun getHandlers(): HandlerList = handlerList

        companion object {
            @JvmStatic
            val handlerList = HandlerList()
        }
    }
}
kotlin
package me.yeezhi.soultrade.api.event

import me.yeezhi.soultrade.api.entity.trade.TradeSession
import org.bukkit.entity.Player
import org.bukkit.event.Cancellable
import org.bukkit.event.Event
import org.bukkit.event.HandlerList

/**
 * 接受交易事件
 * @param player 操作者
 * @param target 对方玩家
 * @param session 交易会话
 */
class TradeAcceptEvent(
    val player: Player,
    val target: Player,
    val session: TradeSession
) : Event(), Cancellable {

    private var cancelled: Boolean = false

    override fun isCancelled(): Boolean = cancelled

    override fun setCancelled(cancel: Boolean) {
        cancelled = cancel
    }

    override fun getHandlers(): HandlerList = handlerList

    companion object {
        @JvmStatic
        val handlerList = HandlerList()
    }
}
kotlin
package me.yeezhi.soultrade.api.event

import me.yeezhi.soultrade.api.entity.trade.TradeResult
import me.yeezhi.soultrade.api.entity.trade.TradeSession
import org.bukkit.event.Cancellable
import org.bukkit.event.Event
import org.bukkit.event.HandlerList

/**
 * 交易会话创建事件
 */
object TradeSessionCreateEvent {

    /**
     * 创建前,可取消
     * @param session 会话
     * @param requester 发起方数据
     * @param target 接收方数据
     */
    class Before(
        val session: TradeSession,
        val requester: TradeResult,
        val target: TradeResult
    ) : Event(), Cancellable {

        private var cancelled: Boolean = false

        override fun isCancelled(): Boolean = cancelled

        override fun setCancelled(cancel: Boolean) {
            cancelled = cancel
        }

        override fun getHandlers(): HandlerList = handlerList

        companion object {
            @JvmStatic
            val handlerList = HandlerList()
        }
    }

    /**
     * 创建后
     * @param session 会话
     * @param requester 发起方数据
     * @param target 接收方数据
     */
    class After(
        val session: TradeSession,
        val requester: TradeResult,
        val target: TradeResult
    ) : Event() {

        override fun getHandlers(): HandlerList = handlerList

        companion object {
            @JvmStatic
            val handlerList = HandlerList()
        }
    }
}
kotlin
package me.yeezhi.soultrade.api.event

import me.yeezhi.soultrade.api.entity.trade.TradeResult
import me.yeezhi.soultrade.api.entity.trade.TradeSession
import org.bukkit.event.Cancellable
import org.bukkit.event.Event
import org.bukkit.event.HandlerList

/**
 * 交易物品更新事件
 */
object TradeItemsUpdateEvent {

    /**
     * 更新前,可取消;修改 party 不会替换槽位
     * @param session 会话
     * @param party 报价快照
     */
    class Before(
        val session: TradeSession,
        var party: TradeResult
    ) : Event(), Cancellable {

        private var cancelled: Boolean = false

        override fun isCancelled(): Boolean = cancelled

        override fun setCancelled(cancel: Boolean) {
            cancelled = cancel
        }

        override fun getHandlers(): HandlerList = handlerList

        companion object {
            @JvmStatic
            val handlerList = HandlerList()
        }
    }

    /**
     * 更新后
     * @param session 会话
     * @param party 报价快照
     */
    class After(
        val session: TradeSession,
        val party: TradeResult
    ) : Event() {

        override fun getHandlers(): HandlerList = handlerList

        companion object {
            @JvmStatic
            val handlerList = HandlerList()
        }
    }
}
kotlin
package me.yeezhi.soultrade.api.event

import me.yeezhi.soultrade.api.entity.trade.TradeResult
import org.bukkit.event.Cancellable
import org.bukkit.event.Event
import org.bukkit.event.HandlerList

/**
 * 交易货币更新事件
 */
object TradeCurrencyUpdateEvent {

    /**
     * 更新前,可修改金额或取消
     * @param party 货币报价
     */
    class Before(
        var party: TradeResult
    ) : Event(), Cancellable {

        private var cancelled: Boolean = false

        override fun isCancelled(): Boolean = cancelled

        override fun setCancelled(cancel: Boolean) {
            cancelled = cancel
        }

        override fun getHandlers(): HandlerList = handlerList

        companion object {
            @JvmStatic
            val handlerList = HandlerList()
        }
    }

    /**
     * 更新后
     * @param party 货币报价
     */
    class After(
        val party: TradeResult
    ) : Event() {

        override fun getHandlers(): HandlerList = handlerList

        companion object {
            @JvmStatic
            val handlerList = HandlerList()
        }
    }
}
kotlin
package me.yeezhi.soultrade.api.event

import me.yeezhi.soultrade.api.entity.trade.TradeResult
import me.yeezhi.soultrade.api.entity.trade.TradeSession
import org.bukkit.event.Cancellable
import org.bukkit.event.Event
import org.bukkit.event.HandlerList

/**
 * 交易确认事件
 */
object TradeLockEvent {

    /**
     * 确认前,可取消
     * @param session 会话
     * @param party 报价快照
     */
    class Before(
        val session: TradeSession,
        val party: TradeResult
    ) : Event(), Cancellable {

        private var cancelled: Boolean = false

        override fun isCancelled(): Boolean = cancelled

        override fun setCancelled(cancel: Boolean) {
            cancelled = cancel
        }

        override fun getHandlers(): HandlerList = handlerList

        companion object {
            @JvmStatic
            val handlerList = HandlerList()
        }
    }

    /**
     * 确认后
     * @param session 会话
     * @param party 报价快照
     */
    class After(
        val session: TradeSession,
        val party: TradeResult
    ) : Event() {

        override fun getHandlers(): HandlerList = handlerList

        companion object {
            @JvmStatic
            val handlerList = HandlerList()
        }
    }
}
kotlin
package me.yeezhi.soultrade.api.event

import me.yeezhi.soultrade.api.entity.trade.TradeSession
import org.bukkit.entity.Player
import org.bukkit.event.Cancellable
import org.bukkit.event.Event
import org.bukkit.event.HandlerList

/**
 * 取消交易事件
 * @param player 操作者
 * @param target 对方玩家
 * @param session 交易会话
 */
class TradeCancelEvent(
    val player: Player,
    val target: Player,
    val session: TradeSession
) : Event(), Cancellable {

    private var cancelled: Boolean = false

    override fun isCancelled(): Boolean = cancelled

    override fun setCancelled(cancel: Boolean) {
        cancelled = cancel
    }

    override fun getHandlers(): HandlerList = handlerList

    companion object {
        @JvmStatic
        val handlerList = HandlerList()
    }
}
kotlin
package me.yeezhi.soultrade.api.event

import me.yeezhi.soultrade.api.entity.trade.TradeResult
import me.yeezhi.soultrade.api.entity.trade.TradeSession
import org.bukkit.event.Cancellable
import org.bukkit.event.Event
import org.bukkit.event.HandlerList

/**
 * 交易结算事件
 */
object TradeFinalizeEvent {

    /**
     * 结算前,可取消
     * @param session 会话
     * @param requester 发起方数据
     * @param target 接收方数据
     */
    class Before(
        val session: TradeSession,
        val requester: TradeResult,
        val target: TradeResult
    ) : Event(), Cancellable {

        private var cancelled: Boolean = false

        override fun isCancelled(): Boolean = cancelled

        override fun setCancelled(cancel: Boolean) {
            cancelled = cancel
        }

        override fun getHandlers(): HandlerList = handlerList

        companion object {
            @JvmStatic
            val handlerList = HandlerList()
        }
    }
}

交易数据 ​

kotlin
package me.yeezhi.soultrade.api.entity.trade

import me.yeezhi.soultrade.api.TradeView
import org.bukkit.entity.Player
import java.util.UUID

/**
 * 交易会话
 */
interface TradeSession {
    val id: UUID
    val requester: String
    val target: String
    val view: TradeView
    // 创建时间戳(毫秒)
    val createdAt: Long
    // 未确认方修改报价时是否解除确认
    val unlockOnEdit: Boolean
    // 是否跳过世界、距离和脱战限制
    val forced: Boolean
    // 是否正在结算
    var settling: Boolean
    // 确认截止时间戳(毫秒),0 表示未开始
    var confirmationEndsAt: Long
    // 是否有玩家已确认
    val hasLocked: Boolean
    // 是否仍允许修改报价
    val editable: Boolean

    /**
     * 检查玩家是否可修改报价
     * @param name 玩家名
     */
    fun canEdit(name: String): Boolean

    /**
     * 获取一方的报价快照
     * @param player 报价玩家
     */
    fun snapshot(player: Player): TradeResult

    /**
     * 获取双方玩家名
     */
    fun participants(): Set<String>

    /**
     * 获取对方玩家名
     * @param name 当前玩家名
     */
    fun other(name: String): String

    /**
     * 获取一方货币报价
     * @param name 玩家名
     */
    fun currenciesOf(name: String): Map<String, Long>

    /**
     * 获取双方货币快照
     */
    fun currenciesSnapshot(): Map<String, Map<String, Long>>

    /**
     * 获取已确认玩家快照
     */
    fun lockedSnapshot(): Set<String>

    /**
     * 更新货币报价
     * @param name 玩家名
     * @param currencies 币种和金额
     */
    fun updateCurrencies(name: String, currencies: Map<String, Long>)

    /**
     * 确认交易
     * @param name 玩家名
     */
    fun lock(name: String)

    /**
     * 撤回双方确认
     */
    fun unlock()

    /**
     * 查询一方是否已确认
     * @param name 玩家名
     */
    fun isLocked(name: String): Boolean

    /**
     * 查询双方是否已确认
     */
    fun allLocked(): Boolean

    /**
     * 获取玩家视角的确认状态标识
     * @param name 玩家名
     */
    fun confirmationState(name: String): String
}
kotlin
package me.yeezhi.soultrade.api.entity.trade


import org.bukkit.Material
import org.bukkit.inventory.ItemStack

/**
 * 一方的交易报价
 */
data class TradeResult(
    // 玩家名称
    val name: String,
    // 槽位与物品快照
    val items: Map<Int, ItemStack> = emptyMap(),
    // 货币标识与金额
    val currencies: Map<String, Long> = emptyMap(),
    // 报价格对应的来源仓库
    val warehouses: Map<Int, String> = emptyMap()
) {
    /**
     * 没有有效物品和正数货币报价
     */
    fun isEmpty(): Boolean = items.values.none { it.type != Material.AIR && it.amount > 0 } &&
        currencies.values.none { it > 0 }

    /**
     * 复制报价及物品
     */
    fun deepCopy(): TradeResult = copy(
        items = items.mapValues { it.value.clone() },
        currencies = currencies.toMap(),
        warehouses = warehouses.toMap()
    )
}
kotlin
package me.yeezhi.soultrade.api.entity.trade

/**
 * 交易请求
 * @param requester 发起方玩家名
 * @param target 接收方玩家名
 * @param createdAt 创建时间戳(毫秒)
 * @param expiresAt 过期时间戳(毫秒)
 */
data class TradeRequest(
    val requester: String,
    val target: String,
    val createdAt: Long = System.currentTimeMillis(),
    val expiresAt: Long
) {
    /**
     * 是否已过期
     * @param now 当前时间戳(毫秒)
     */
    fun isExpired(now: Long = System.currentTimeMillis()): Boolean = now >= expiresAt
}

监听示例 ​

示例每 5 秒检测云端加载状态,完成后注册监听并停止检测,演示数据获取与事件拦截

java
package example;

import me.yeezhi.soultrade.api.entity.trade.TradeResult;
import me.yeezhi.soultrade.api.entity.trade.TradeSession;
import me.yeezhi.soultrade.api.event.TradeFinalizeEvent;
import me.yeezhi.soultrade.api.event.TradeItemsUpdateEvent;
import me.yeezhi.yeeplugins.CloudPlugins;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

import java.util.Map;

/**
 * 交易事件的数据读取与拦截示例
 */
public class SoulTradeListenerExample extends JavaPlugin implements Listener {

    /**
     * 插件启用后等待云端加载
     */
    @Override
    public void onEnable() {
        // 云端加载可能晚于 onEnable,使用 BukkitRunnable 定时等待
        // 同步任务在主线程执行,加载完成后再注册 Bukkit 监听
        new BukkitRunnable() {
            @Override
            public void run() {
                if (!getServer().getPluginManager().isPluginEnabled("SoulTrade")) {
                    return;
                }
                if (!CloudPlugins.INSTANCE.isLicense("SoulTrade")) {
                    return;
                }
                getServer().getPluginManager().registerEvents(SoulTradeListenerExample.this, SoulTradeListenerExample.this);
                // 注册完成后停止检测,避免重复注册
                cancel();
            }
        }.runTaskTimer(this, 100L, 100L); // 延迟和间隔均为 100 tick,即 5 秒
    }


    /**
     * 获取物品报价数据并拦截变更
     * @param event 物品报价更新事件
     */
    @EventHandler(ignoreCancelled = true)
    public void onItemsUpdate(TradeItemsUpdateEvent.Before event) {
        // 交易会话
        TradeSession session = event.getSession();
        // 本次报价
        TradeResult party = event.getParty();
        // 报价玩家名
        String playerName = party.getName();
        // 报价格索引与物品快照
        Map<Integer, ItemStack> items = party.getItems();
        // 币种与报价金额
        Map<String, Long> currencies = party.getCurrencies();
        // 报价格索引与来源仓库,背包物品不包含在内
        Map<Integer, String> warehouses = party.getWarehouses();

        // 需要拦截本次物品变更时调用
        event.setCancelled(true);
    }

    /**
     * 获取双方报价并拦截结算
     * @param event 交易结算前事件
     */
    @EventHandler(ignoreCancelled = true)
    public void onFinalize(TradeFinalizeEvent.Before event) {
        // 交易会话
        TradeSession session = event.getSession();
        // 发起方报价
        TradeResult requester = event.getRequester();
        // 接收方报价
        TradeResult target = event.getTarget();

        // 需要拦截本次结算时调用
        event.setCancelled(true);
    }
}