如何优雅地换皮肤给榜一大哥看?
欢迎大家来到兔兔子的直播间~刷一个嘉年华可以换皮肤哦~
想必跟我一样的擦边主播在此时都会有一个问题:
如何优雅地换皮肤给榜一大哥看?
这个问题会有如下几个选项:
1,原地脱去皮肤,穿上新的皮肤,但是容易被超管封直播间
2,“暂时离开”直播间,在别处换好了皮肤之后再回来,但是可能会损失一些现成的流量
3,圈到圆子了就跑路,不换皮肤了。什么,退钱?退你妈!
但是这些选项显然都有一些代价,那么是否有又便捷又优雅的换皮肤方式呢?
当然有!直接原地把现在穿着的皮肤改为新皮肤就好了!
要给玩家更换皮肤,在服务端需要有以下步骤:
1,获取材质
2,给指定玩家更换材质
3,通过nms使更换生效
第一步和第二步都非常简单,通过bukkitApi即可实现,第三步使用nms包即可实现。但是由于众所周知的原因,nms包的调用非常麻烦,而且对跨版本有一定的局限性,即便可以通过nmsPorxy或是Class.forName()处理起来也并不简单,而且容易发生意料之外的问题。
大概在20年写的通过nms使更换生效的代码,应该没人会想自己处理原生的nms代码吧?
我们可以使用一个魔法道具——SkinsRestorerApi,让别人去帮忙处理屎山。
以下内容均针对于群组服。
override fun onEnable(){
skinsRestorerApi = SkinsRestorerProvider.get();
getProxy().getPluginManager().registerListener(this,this);
getProxy().registerChannel("BungeeCord");
}
@EventHandler
fun onPluginMessageReceived(e: PluginMessageEvent){
}如此,相当于直播间的公告栏
那么如何通过公告栏告诉观众:刷一个嘉年华主播就换皮肤呢
fun skinProperty(value: String, signature: String): SkinProperty {
return SkinProperty.of(value, signature)
}
fun skinChangeHandle(player: ProxiedPlayer, skin: SkinProperty) {
proxy.scheduler.runAsync(
this
) {
skinsRestorerApi.getSkinApplier<ProxiedPlayer>(ProxiedPlayer::class.java).applySkin(player, skin)
}
}
// 移除皮肤最好考虑一下是否直接换成mc的默认皮肤
fun removeSkin(player: ProxiedPlayer) {
skinsRestorerApi.playerStorage.removeSkinIdOfPlayer(player.uniqueId)
proxy.scheduler.runAsync(this) {
// 如果有相应的正版皮肤则给正版皮肤
try {
val optionalSkin = skinsRestorerApi.playerStorage
.getSkinForPlayer(player.uniqueId, player.displayName)
if (optionalSkin.isPresent) {
skinChangeHandle(player, optionalSkin.get())
}
} catch () {}
}
}
然后在onPluginMessageReceived中接收榜一大哥的礼物,随后调用skinChangeHandle()即可
那么,榜一大哥要如何刷礼物呢?
fun setSkin(skin: ISkinsEntry){
this.setTextures(skin.texture,skin.signature)
}
fun setTextures(textures: String, signature: String){
this.rawPlayer?.let {
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, Runnable {
val b = ByteArrayOutputStream()
val o = DataOutputStream(b)
try {
o.writeUTF("skin")
o.writeUTF(it.uniqueId)
o.writeUTF(textures)
o.writeUTF(signature)
o.flush()
// BungeeCord君 我要进来咯!
it.sendPluginMessage(plugin, "BungeeCord", b.toByteArray())
} catch () {}
}, 20L)
}
}
这里给20个tick的Later是为了预防在PlayerJoinEvent中使用,可能会导致意料之外的错误发生。
由于众所周知的原因,咱们擦边主播会有一部分人守不住底线,脱掉自己皮肤的情况
proxy.scheduler.runAsync(
this
) {
skinsRestorerApi.getSkinApplier<ProxiedPlayer>(ProxiedPlayer::class.java)
.applySkin(player, SkinProperty.of("", ""))//将皮肤的材质和签名都设置为"",即会换成mc的默认皮肤
}
这是我前几天折腾一个即时、动态更换玩家皮肤的需求时的解决方案,由于利益相关,暂时不能抛出完整代码。
使用BC处理是因为SkinsRestorerApi目前要求jdk17(SkinsRestorerApi降版本的话太难用了,那我还不如nmsProxy呢),而这个需求要求的mc版本是1.16.5,需要使用jdk16,于是我选择曲线救国在BC使用SkinsRestorerApi处理玩家皮肤,而子服(paper)只负责告诉bc需要将哪位玩家的皮肤更换为什么材质。
虽然我觉得应该不会有其他人遇到这么奇葩的需求了,但是万一呢。其实主要是想水一帖
因此稍微整理了一下发出来,如果你也遇到了这么奇葩的需求,希望这篇帖子能帮到你。
好耶,打call[贴吧_吐舌] 差一点就点走了
页: [1]