InvSync开发者文档
接入API方法
方式1 不需要读取离线玩家的同步
同步需要实现一个接口 com.xbaimiao.invsync.api.addon.InvSyncAddon
然后调用 com.xbaimiao.invsync.api.addon.InvSyncAddonManager#register方法注册即可
以下代码为这个接口的源代码
public interface InvSyncAddon {
/**
* 服务器给玩家同步数据的时候调用
*
* @param event 同步的事件 里面包含玩家和数据 这时可以往里面获取自己的数据
*/
void onSync(InvSyncPluginDataSyncEvent event);
@Deprecated()
default void onSave(InvSyncPluginDataSaveEvent event) {
}
/**
* 服务器保存数据的时候调用
*
* @param event 保存的事件 里面包含玩家和数据 这时可以往里面存入自己的数据
* @param reason 保存原因
*/
default void onSave(InvSyncPluginDataSaveEvent event, SaveReason reason) {
}
}
方式2 需要读取离线玩家数据的
需要继承一个抽象类 com.xbaimiao.invsync.bukkit.api.addon.OfflineInvSyncAddon
然后调用 com.xbaimiao.invsync.api.addon.InvSyncAddonManager#register方法注册即可
下面是这个抽象类的源代码
public abstract class OfflineInvSyncAddon implements InvSyncAddon {
@Nullable
public PluginDataSync readOfflineData(@NotNull UUID uuid) {
if (Bukkit.getPlayer(uuid) != null) throw new RuntimeException("玩家在线");
PlayerData playerData = InvSyncAPI.getAPI().readFromRedisOrMysql(uuid);
if (playerData == null) return null;
return new PluginDataSync(playerData.getPluginData());
}
/**
* 读取离线玩家的数据
*
* @param uuid 玩家uuid
* @param key 数据key
*/
public byte @Nullable [] readOfflineData(@NotNull UUID uuid, @NotNull String key) {
if (Bukkit.getPlayer(uuid) != null) throw new RuntimeException("玩家在线");
PlayerData playerData = InvSyncAPI.getAPI().readFromRedisOrMysql(uuid);
if (playerData == null) return null;
PluginDataSync pluginDataSync = new PluginDataSync(playerData.getPluginData());
return pluginDataSync.read(key);
}
/**
* 写入离线玩家的数据
*
* @param uuid 玩家uuid
* @param key 数据key
* @param bytes 数据
*/
public void writeOfflineData(@NotNull UUID uuid, @NotNull String key, byte @NotNull [] bytes) {
if (Bukkit.getPlayer(uuid) != null) throw new RuntimeException("玩家在线");
PlayerData playerData = InvSyncAPI.getAPI().readFromRedisOrMysql(uuid);
if (playerData == null) return;
PluginDataSync pluginDataSync = new PluginDataSync(playerData.getPluginData());
pluginDataSync.put(key, bytes);
playerData.pluginData = pluginDataSync.serializer();
InvSync.getPlugin().getRedisManager().setPlayerData(playerData);
InvSync.getPlugin().getMysqlManager().savePlayerData(playerData);
}
/**
* 获取玩家uuid
*
* @param name 玩家名字
* @return 玩家的UUID
*/
public UUID getUUID(String name) {
return UtilKt.toPlayerUUID(name);
}
}
示范例子:同步玩家飞行状态
public class SyncFlyAddon implements InvSyncAddon {
private String flag = "fly";
@Override
public void onSync(InvSyncPluginDataSyncEvent event) {
Player player = event.getPlayer();
byte[] data = event.readData(flag);
if (data == null) return;
try {
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
player.setAllowFlight(dis.readBoolean());
player.setFlying(dis.readBoolean());
dis.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void onSave(InvSyncPluginDataSaveEvent event, SaveReason reason) {
Player player = event.getPlayer();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
try {
dos.writeBoolean(player.getAllowFlight());
dos.writeBoolean(player.isFlying());
event.putData(flag, baos.toByteArray());
dos.close();
baos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
kotlin进阶玩法
委托基本属性
第一步 需要放置一个源文件在你的项目里,因为InvSync的kotlin为relocate过的,直接调用不可取 所以必须要把我发的源文件放置在你的项目
import com.xbaimiao.invsync.api.delegate.DelegatePropertyAddon
import org.bukkit.entity.Player
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
interface DelegateProperty<K, V> : ReadWriteProperty<K, V?> {
fun defaultsTo(defaultValue: (k: K) -> V): ReadWriteProperty<K, V> {
val parent = this
return object : ReadWriteProperty<K, V> {
override fun getValue(thisRef: K, property: KProperty<*>): V {
return parent.getValue(thisRef, property) ?: defaultValue(thisRef).also {
setValue(thisRef, property, it)
}
}
override fun setValue(thisRef: K, property: KProperty<*>, value: V) {
parent.setValue(thisRef, property, value)
}
}
}
}
fun <V> delegateProperty(
id: String,
serializableProperty: SerializableProperty<V>
): DelegateProperty<Player, V> {
return object : DelegateProperty<Player, V> {
override fun getValue(thisRef: Player, property: KProperty<*>): V? {
val dataMap = DelegatePropertyAddon.playerDataMap(thisRef)
val value = dataMap.get(id)
return if (value == null) {
null
} else {
serializableProperty.deserialize(value)
}
}
override fun setValue(thisRef: Player, property: KProperty<*>, value: V?) {
val dataMap = DelegatePropertyAddon.playerDataMap(thisRef)
dataMap.put(id, value?.let { serializableProperty.serialize(it) })
}
}
}
interface SerializableProperty<V> {
fun serialize(value: V): String
fun deserialize(value: String): V
companion object {
val LONG = object : SerializableProperty<Long> {
override fun serialize(value: Long): String {
return value.toString()
}
override fun deserialize(value: String): Long {
return value.toLong()
}
}
val STRING = object : SerializableProperty<String> {
override fun serialize(value: String): String {
return value
}
override fun deserialize(value: String): String {
return value
}
}
val BOOLEAN = object : SerializableProperty<Boolean> {
override fun serialize(value: Boolean): String {
return value.toString()
}
override fun deserialize(value: String): Boolean {
return value.toBoolean()
}
}
val DOUBLE = object : SerializableProperty<Double> {
override fun serialize(value: Double): String {
return value.toString()
}
override fun deserialize(value: String): Double {
return value.toDouble()
}
}
}
}
第二步 定义一个自定义的属性 示例中采用 Boolean作为测试
var Player.isSb by delegateProperty<Boolean>("sb", SerializableProperty.BOOLEAN)
.defaultsTo { false }
第三步 就可以直接操作这个自定义的属性了
此属性会安全的全服同步,前提是玩家在线时进行操作的
fun main(player: Player) {
player.isSb = true
}
委托自定义类
自己看看源码吧
var Player.isSb by delegateProperty<Boolean>("sb", SerializableProperty.BOOLEAN)
.defaultsTo { false }
var Player.data by delegateProperty<DIYClass>("data", DIYClassSerializer)
object DIYClassSerializer : SerializableProperty<DIYClass> {
private val gson = Gson()
override fun serialize(value: DIYClass): String {
return gson.toJson(value)
}
override fun deserialize(value: String): DIYClass {
return gson.fromJson(value, DIYClass::class.java)
}
}
class DIYClass(
val name: String,
val age: Int
)
fun main(player: Player) {
player.isSb = true
val data = player.data
if (data == null) {
player.data = DIYClass("测试", 0)
} else {
println(data.name)
}
}
#minecraft(3)文章作者:Administrator
文章链接:https://halo.xbaimiao.com/archives/invsynckai-fa-zhe-wen-dang
版权声明:本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0 许可协议,转载请注明出处!
评论