- ◆ 支持核心
- Spigot
- ◆ 插件前置
- AyCore
- ◆ 游戏版本
- 1.12.2,1.16.5, 1.21.1
有问题可以前往 此处 提出。
目前仅对 1.12.2,1.16.5, 1.21.1 提供了支持,如果你有其他版本需求,可前往 此处 提出。
在插件趋于稳定之前会积极维护此项目,欢迎感兴趣的用户尝试并反馈问题。
开源地址:https://github.com/blank038/eSync
一、特性
/esync kickAll 踢出全部玩家(触发存储)
/esync inv <UUID> 查看玩家背包数据
/esync ender <UUID> 查看玩家末影箱数据
/esync reload 重载插件配置
三、开发接口
目前仅对 1.12.2,1.16.5, 1.21.1 提供了支持,如果你有其他版本需求,可前往 此处 提出。
在插件趋于稳定之前会积极维护此项目,欢迎感兴趣的用户尝试并反馈问题。
开源地址:https://github.com/blank038/eSync
一、特性
- 同步方式支持 MySQL、PostgreSQL
- 同步数据:玩家背包、血量与药水效果、末影箱、统计数据
- 查看离线玩家数据(背包、末影箱)
- 首次进入服务器执行命令
/esync kickAll 踢出全部玩家(触发存储)
/esync inv <UUID> 查看玩家背包数据
/esync ender <UUID> 查看玩家末影箱数据
/esync reload 重载插件配置
三、开发接口
代码:
// Gradle
repositories {
maven {
name = "AiYo Studio Repository"
url = uri("https://repo.mc9y.com/snapshots")
}
}
dependencies {
compileOnly("com.aiyostudio.esync:eSync:1.3.0-beta")
}
// Maven 同理
代码:
/// 注册模块
// Java
EfficientSync.INSTANCE.api.registerModule("模块名", 模块类.class)
// Kotlin
EfficientSync.api.registerModule("模块名", 模块名::class.java, true)
/// 实现模块(这里以 eSyncCobblemon 为例)
class CobblemonEntity : IEntity {
lateinit var partyCompound: CompoundTag
lateinit var pcCompound: CompoundTag
override fun apply(player: Any): Boolean {
if (player !is UUID) {
return false
}
val registryAccess = Cobblemon.implementation.server()?.registryAccess() ?: return false
val partyStorage = Cobblemon.storage.getParty(player, registryAccess)
val pcStorage = Cobblemon.storage.getPC(player, registryAccess)
pcStorage.boxes.clear()
partyStorage.loadFromNBT(partyCompound, registryAccess)
pcStorage.loadFromNBT(pcCompound, registryAccess)
partyStorage.initialize()
pcStorage.initialize()
player.getPlayer()?.let(Cobblemon.storage::onPlayerDataSync)
return true
}
}
class CobblemonModuleImpl : AbstractModule<CobblemonEntity>() {
override val uniqueKey: String = "cobblemon"
init {
if (EfficientSyncCobblemon.instance.config.getBoolean("depend")) {
CacheHandler.dependModules.add(uniqueKey)
}
}
override fun firstLoad(uuid: UUID, bytea: ByteArray?): Boolean {
if (bytea == null || bytea.isEmpty()) {
this.caches[uuid] = CobblemonEntity()
} else {
this.caches[uuid] = wrapper(bytea)
}
return true
}
override fun attemptLoad(uuid: UUID, bytea: ByteArray?): Boolean {
return firstLoad(uuid, bytea)
}
override fun preLoad(uuid: UUID) {
val registryAccess = requireNotNull(Cobblemon.implementation.server()?.registryAccess())
if (EfficientSyncCobblemon.instance.config.getBoolean("option.always-clear")) {
val partyStorage = Cobblemon.storage.getParty(uuid, registryAccess)
val pcStorage = Cobblemon.storage.getPC(uuid, registryAccess)
partyStorage.clearParty()
pcStorage.clearPC()
}
}
override fun apply(uuid: UUID): Boolean {
return this.find(uuid)?.apply(uuid) ?: false
}
override fun toByteArray(uuid: UUID): ByteArray? {
val buf = Unpooled.buffer()
val registryAccess = requireNotNull(Cobblemon.implementation.server()?.registryAccess())
// write party data
val partyStorage = Cobblemon.storage.getParty(uuid, registryAccess)
val partyCompound = partyStorage.saveToNBT(CompoundTag(), registryAccess)
val partyBytea = partyCompound.toString().toByteArray(Charsets.UTF_8)
buf.writeInt(partyBytea.size)
buf.writeBytes(partyBytea)
// write pc data
val pcStorage = Cobblemon.storage.getPC(uuid, registryAccess)
val pcCompound = pcStorage.saveToNBT(CompoundTag(), registryAccess)
val pcBytea = pcCompound.toString().toByteArray(Charsets.UTF_8)
buf.writeInt(pcBytea.size)
buf.writeBytes(pcBytea)
return buf.array()
}
override fun wrapper(bytea: ByteArray): CobblemonEntity {
val entity = CobblemonEntity()
val buf = Unpooled.wrappedBuffer(bytea)
// read party data
val partyByteaLength = buf.readInt()
val partyBytea = ByteArray(partyByteaLength)
buf.readBytes(partyBytea)
entity.partyCompound = TagParser.parseTag(String(partyBytea, Charsets.UTF_8))
// read pc data
val pcByteaLength = buf.readInt()
val pcBytea = ByteArray(pcByteaLength)
buf.readBytes(pcBytea)
entity.pcCompound = TagParser.parseTag(String(pcBytea, Charsets.UTF_8))
return entity
}
}