Skip to content

Commit

Permalink
[no ci] new: (wip) Initial client renderer server-side impl
Browse files Browse the repository at this point in the history
  • Loading branch information
MATRIX-feather committed Oct 28, 2023
1 parent 0699c9b commit 726d3d7
Show file tree
Hide file tree
Showing 10 changed files with 292 additions and 37 deletions.
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ project_version=0.13.1

# FM Protocols
protocols_version=8aeff50
protocols_use_local_build=false
protocols_local_version=0.12.7
protocols_use_local_build=true
protocols_local_version=0.13.2

minecraft_version=1.20.2-R0.1-SNAPSHOT

Expand Down
82 changes: 59 additions & 23 deletions src/main/java/xiamomc/morph/MorphManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import xiamomc.morph.misc.*;
import xiamomc.morph.misc.permissions.CommonPermissions;
import xiamomc.morph.network.commands.S2C.AbstractS2CCommand;
import xiamomc.morph.network.commands.S2C.clientrender.*;
import xiamomc.morph.network.commands.S2C.map.S2CMapCommand;
import xiamomc.morph.network.commands.S2C.map.S2CMapRemoveCommand;
import xiamomc.morph.network.commands.S2C.map.S2CPartialMapCommand;
Expand All @@ -53,6 +54,7 @@
import xiamomc.morph.storage.playerdata.PlayerDataStore;
import xiamomc.morph.storage.playerdata.PlayerMeta;
import xiamomc.morph.utilities.DisguiseUtils;
import xiamomc.morph.utilities.MapMetaUtils;
import xiamomc.morph.utilities.NbtUtils;
import xiamomc.pluginbase.Annotations.Initializer;
import xiamomc.pluginbase.Annotations.Resolved;
Expand Down Expand Up @@ -83,13 +85,18 @@ public class MorphManager extends MorphPluginObject implements IManagePlayerData
@Resolved
private MorphConfigManager config;

@Resolved
private NetworkingHelper networkingHelper;

public static final DisguiseProvider fallbackProvider = new FallbackProvider();

public static final String disguiseFallbackName = "@default";

public static final String forcedDisguiseNoneId = "@none";

private DisguiseBackend<?, ?> currentBackend = new NilBackend();
private final NilBackend nilBackend = new NilBackend();

private DisguiseBackend<?, ?> currentBackend = nilBackend;

public DisguiseBackend<?, ?> getCurrentBackend()
{
Expand All @@ -112,17 +119,20 @@ private void load()

try
{
if (1+1==2)
throw new NoClassDefFoundError();

this.currentBackend = new LibsBackend();
}
catch (NoClassDefFoundError e)
{
logger.error("Unable to initialize LibsDisguises as our disguise backend because it's not installed on the server.");
logger.error("Initializing NilBackend, displaying disguises at the server side will not be supported this run.");
logger.error("Using NilBackend, displaying disguises at the server side will not be supported this run.");
}
catch (Throwable t)
{
logger.error("Unable to initialize LibsDisguise as our disguise backend, please check your server setup!");
logger.error("Initializing NilBackend, displaying disguises at the server side will not be supported this run.");
logger.error("Using NilBackend, displaying disguises at the server side will not be supported this run.");
logger.error("If you believe this is an error, please consider reporting this issue to our GitHub: https://github.com/XiaMoZhiShi/MorphPlugin/issues");

t.printStackTrace();
Expand Down Expand Up @@ -573,16 +583,18 @@ else if (!key.equals("minecraft:player")) // 禁止不带参数的玩家伪装

var provider = getProvider(strippedKey[0]);

DisguiseState outComingState = null;
DisguiseState outComingState;

if (provider == MorphManager.fallbackProvider)
{
outComingState = null;
source.sendMessage(MessageUtils.prefixes(source, MorphStrings.disguiseBannedOrNotSupportedString()));
logger.error("Unable to find any provider that matches the identifier '%s'".formatted(strippedKey[0]));
return false;
}
else if (!provider.isValid(key))
{
outComingState = null;
source.sendMessage(MessageUtils.prefixes(source, MorphStrings.invalidIdentityString()));
return false;
}
Expand Down Expand Up @@ -673,7 +685,22 @@ else if (!provider.isValid(key))
source.sendMessage(MessageUtils.prefixes(source, msg));

// 向管理员发送map消息
sendCommandToRevealablePlayers(genPartialMapCommand(outComingState));
networkingHelper.sendCommandToRevealablePlayers(genPartialMapCommand(outComingState));

//发送元数据
if (isUsingNilServerBackend())
{
networkingHelper.sendCommandToAllPlayers(new S2CRenderMapAddCommand(outComingState.getPlayer().getEntityId(), outComingState.getDisguiseIdentifier()));

var meta = new S2CRenderMeta(player.getEntityId());
meta.profileCompound = outComingState.getProfileNbtString();
meta.sNbt = outComingState.getCachedNbtString();
meta.showOverridedEquipment = outComingState.showingDisguisedItems();
meta.overridedEquipment = MapMetaUtils.toPacketEquipment(outComingState.getDisguisedItems());

var packet = new S2CRenderMapMetaCommand(meta);
networkingHelper.sendCommandToAllPlayers(packet);
}

return true;
}
Expand Down Expand Up @@ -701,19 +728,13 @@ else if (!provider.isValid(key))
}
}

/**
* 将某一客户端指令发送给所有拥有橙字显示权限的玩家
* @param cmd 目标指令
*/
public void sendCommandToRevealablePlayers(AbstractS2CCommand<?> cmd)
public boolean isUsingNilServerBackend()
{
var target = Bukkit.getOnlinePlayers().stream()
.filter(p -> p.hasPermission(CommonPermissions.DISGUISE_REVEALING))
.toList();

target.forEach(p -> clientHandler.sendCommand(p, cmd));
return currentBackend == nilBackend;
}

//region Command generating

/**
* 生成用于橙字显示的map指令
*/
Expand All @@ -729,22 +750,34 @@ public S2CMapCommand genMapCommand()
return new S2CMapCommand(map);
}

public S2CRenderMapSyncCommand genRenderSyncCommand()
{
var map = new HashMap<Integer, String>();
for (DisguiseState disguiseState : this.disguiseStates)
{
var player = disguiseState.getPlayer();
map.put(player.getEntityId(), disguiseState.getDisguiseIdentifier());
}

return S2CRenderMapSyncCommand.of(map);
}

/**
* 生成用于橙字显示的部分map(mapp)指令
* @param diff 用于生成的伪装状态
*/
public S2CPartialMapCommand genPartialMapCommand(DisguiseState... diff)
{
var map = new HashMap<Integer, String>();
for (DisguiseState disguiseState : diff)
{
var player = disguiseState.getPlayer();
map.put(player.getEntityId(), player.getName());
}
return networkingHelper.genPartialMapCommand(diff);
}

return new S2CPartialMapCommand(map);
public S2CRenderMapAddCommand genClientRenderAddCommand(DisguiseState diff)
{
return networkingHelper.genClientRenderAddCommand(diff);
}

//endregion Command generating

/**
* 检查某个伪装是否已被禁用
* @param key 伪装ID
Expand Down Expand Up @@ -914,7 +947,10 @@ public void unMorph(@Nullable CommandSender source, Player player, boolean bypas
new PlayerUnMorphEvent(player).callEvent();

// 向管理员发送map移除指令
sendCommandToRevealablePlayers(new S2CMapRemoveCommand(player.getEntityId()));
networkingHelper.sendCommandToRevealablePlayers(new S2CMapRemoveCommand(player.getEntityId()));

if (isUsingNilServerBackend())
networkingHelper.sendCommandToAllPlayers(new S2CRenderMapRemoveCommand(player.getEntityId()));
}

@Resolved
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/xiamomc/morph/MorphPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import xiamomc.morph.messages.MessageUtils;
import xiamomc.morph.messages.MorphMessageStore;
import xiamomc.morph.messages.vanilla.VanillaMessageStore;
import xiamomc.morph.misc.NetworkingHelper;
import xiamomc.morph.misc.PlayerOperationSimulator;
import xiamomc.morph.misc.UpdateHandler;
import xiamomc.morph.misc.integrations.gsit.GSitCompactProcessor;
Expand Down Expand Up @@ -100,6 +101,7 @@ public void onEnable()

//缓存依赖
dependencyManager.cache(this);
dependencyManager.cache(new NetworkingHelper());
dependencyManager.cache(morphManager = new MorphManager());
dependencyManager.cache(skillHandler = new MorphSkillHandler());
dependencyManager.cache(abilityHandler = new AbilityHandler());
Expand Down
19 changes: 9 additions & 10 deletions src/main/java/xiamomc/morph/backends/DisguiseWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.util.BoundingBox;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xiamomc.morph.misc.CollisionBoxRecord;
Expand All @@ -20,13 +19,13 @@

/**
* A wrapper that holds the underlying disguise instance
* @param <T> Type of the disguise instance
* @param <TInstance> Type of the disguise instance
*/
public abstract class DisguiseWrapper<T>
public abstract class DisguiseWrapper<TInstance>
{
protected T instance;
protected TInstance instance;

public DisguiseWrapper(@NotNull T instance, DisguiseBackend<T, ? extends DisguiseWrapper<T>> backend)
public DisguiseWrapper(@NotNull TInstance instance, DisguiseBackend<TInstance, ? extends DisguiseWrapper<TInstance>> backend)
{
this.instance = instance;
this.backend = backend;
Expand All @@ -36,14 +35,14 @@ public DisguiseWrapper(@NotNull T instance, DisguiseBackend<T, ? extends Disguis
* Gets the underlying disguise instance
* @return The underlying disguise instance
*/
public T getInstance()
public TInstance getInstance()
{
return instance;
}

private final DisguiseBackend<T, ? extends DisguiseWrapper<T>> backend;
private final DisguiseBackend<TInstance, ? extends DisguiseWrapper<TInstance>> backend;

public DisguiseBackend<T, ? extends DisguiseWrapper<T>> getBackend()
public DisguiseBackend<TInstance, ? extends DisguiseWrapper<TInstance>> getBackend()
{
return backend;
}
Expand Down Expand Up @@ -76,13 +75,13 @@ public T getInstance()
* Clone the underlying disguise instance
* @return A new instance cloned from the underlying disguise
*/
public abstract T copyInstance();
public abstract TInstance copyInstance();

/**
* Clone this wrapper
* @return A new wrapper cloned from this instance, everything in the new instance should not have any reference with this wrapper
*/
public abstract DisguiseWrapper<T> clone();
public abstract DisguiseWrapper<TInstance> clone();

/**
* 返回此伪装的名称
Expand Down
32 changes: 31 additions & 1 deletion src/main/java/xiamomc/morph/events/CommonEventProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,30 @@
import xiamomc.morph.config.ConfigOption;
import xiamomc.morph.config.MorphConfigManager;
import xiamomc.morph.events.api.gameplay.PlayerJoinedWithDisguiseEvent;
import xiamomc.morph.events.api.lifecycle.ManagerFinishedInitializeEvent;
import xiamomc.morph.messages.HintStrings;
import xiamomc.morph.messages.MessageUtils;
import xiamomc.morph.messages.MorphStrings;
import xiamomc.morph.messages.SkillStrings;
import xiamomc.morph.messages.vanilla.VanillaMessageStore;
import xiamomc.morph.misc.DisguiseState;
import xiamomc.morph.misc.DisguiseTypes;
import xiamomc.morph.misc.NetworkingHelper;
import xiamomc.morph.misc.permissions.CommonPermissions;
import xiamomc.morph.network.commands.S2C.S2CSwapCommand;
import xiamomc.morph.network.commands.S2C.clientrender.S2CRenderMapMetaCommand;
import xiamomc.morph.network.commands.S2C.clientrender.S2CRenderMeta;
import xiamomc.morph.network.commands.S2C.map.S2CMapRemoveCommand;
import xiamomc.morph.network.server.MorphClientHandler;
import xiamomc.morph.network.server.ServerSetEquipCommand;
import xiamomc.morph.skills.MorphSkillHandler;
import xiamomc.morph.utilities.EntityTypeUtils;
import xiamomc.morph.utilities.MapMetaUtils;
import xiamomc.pluginbase.Annotations.Initializer;
import xiamomc.pluginbase.Annotations.Resolved;
import xiamomc.pluginbase.Bindables.Bindable;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

Expand All @@ -69,8 +76,28 @@ public class CommonEventProcessor extends MorphPluginObject implements Listener
@Resolved(shouldSolveImmediately = true)
private RevealingHandler revealingHandler;

@Resolved(shouldSolveImmediately = true)
private NetworkingHelper networkingHelper;

private Bindable<Boolean> unMorphOnDeath;

//region Test
@EventHandler
public void onLoadComplete(ManagerFinishedInitializeEvent e)
{
var players = List.of("Icalingua", "Player111", "NekoCrystal");
var ids = List.of("player:NekoCrystal", "null", "minecraft:allay");

for (var str : players)
{
var player = Bukkit.getPlayerExact(str);
if (player == null) continue;
if (ids.get(players.indexOf(str)).equals("null")) continue;
e.manager.morph(null, player, ids.get(players.indexOf(str)), null);
}
}
//endregion

@EventHandler
public void onEntityDeath(EntityDeathEvent e)
{
Expand Down Expand Up @@ -420,7 +447,10 @@ public void onPlayerJoin(PlayerJoinEvent e)

state.refreshSkillsAbilities();

morphs.sendCommandToRevealablePlayers(morphs.genPartialMapCommand(state));
networkingHelper.sendCommandToRevealablePlayers(morphs.genPartialMapCommand(state));

if (morphs.isUsingNilServerBackend())
networkingHelper.sendCommandToAllPlayers(morphs.genClientRenderAddCommand(state));

//调用Morph事件
new PlayerJoinedWithDisguiseEvent(player, state).callEvent();
Expand Down
58 changes: 58 additions & 0 deletions src/main/java/xiamomc/morph/misc/NetworkingHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package xiamomc.morph.misc;

import org.bukkit.Bukkit;
import xiamomc.morph.MorphPluginObject;
import xiamomc.morph.misc.permissions.CommonPermissions;
import xiamomc.morph.network.commands.S2C.AbstractS2CCommand;
import xiamomc.morph.network.commands.S2C.clientrender.S2CRenderMapAddCommand;
import xiamomc.morph.network.commands.S2C.map.S2CPartialMapCommand;
import xiamomc.morph.network.server.MorphClientHandler;
import xiamomc.pluginbase.Annotations.Resolved;

import java.util.HashMap;

public class NetworkingHelper extends MorphPluginObject
{
@Resolved
private MorphClientHandler clientHandler;

/**
* 生成用于橙字显示的部分map(mapp)指令
* @param diff 用于生成的伪装状态
*/
public S2CPartialMapCommand genPartialMapCommand(DisguiseState... diff)
{
var map = new HashMap<Integer, String>();
for (DisguiseState disguiseState : diff)
{
var player = disguiseState.getPlayer();
map.put(player.getEntityId(), player.getName());
}

return new S2CPartialMapCommand(map);
}

public S2CRenderMapAddCommand genClientRenderAddCommand(DisguiseState diff)
{
var player = diff.getPlayer();
return new S2CRenderMapAddCommand(player.getEntityId(), diff.getDisguiseIdentifier());
}

/**
* 将某一客户端指令发送给所有拥有橙字显示权限的玩家
* @param cmd 目标指令
*/
public void sendCommandToRevealablePlayers(AbstractS2CCommand<?> cmd)
{
var target = Bukkit.getOnlinePlayers().stream()
.filter(p -> p.hasPermission(CommonPermissions.DISGUISE_REVEALING))
.toList();

target.forEach(p -> clientHandler.sendCommand(p, cmd));
}

public void sendCommandToAllPlayers(AbstractS2CCommand<?> cmd)
{
Bukkit.getOnlinePlayers().forEach(p -> clientHandler.sendCommand(p, cmd));
}
}
Loading

0 comments on commit 726d3d7

Please sign in to comment.