1
0
mirror of https://github.com/GeyserMC/Floodgate.git synced 2025-12-30 12:19:22 +00:00

Fix linked player skins; clean up skin applying code

Fixes #39
This commit is contained in:
Camotoy
2022-06-15 21:21:45 -04:00
parent 7482ac791b
commit d52b33588a
9 changed files with 100 additions and 46 deletions

View File

@@ -110,7 +110,6 @@ task remappedShadowJar(type: RemapJarTask) {
dependsOn tasks.shadowJar
input = tasks.shadowJar.archiveFile
addNestedDependencies = true
//remapAccessWidener = true // Required for our access widener changes to go into effect and not crash on startup
archiveName = "floodgate-fabric.jar"
}

View File

@@ -8,9 +8,6 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.loader.api.FabricLoader;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.module.*;
import org.geysermc.floodgate.pluginmessage.FabricSkinApplier;
import org.geysermc.floodgate.util.FabricCommandUtil;
import org.geysermc.floodgate.util.FabricPlatformUtils;
public class FabricMod implements ModInitializer {
@Override
@@ -31,9 +28,7 @@ public class FabricMod implements ModInitializer {
// Stupid hack, see the class for more information
// This can probably be Guice-i-fied but that is beyond me
FabricCommandUtil.setServer(server);
FabricSkinApplier.setServer(server);
FabricPlatformUtils.setServer(server);
MinecraftServerHolder.set(server);
platform.enable(
new FabricAddonModule(),

View File

@@ -0,0 +1,20 @@
package org.geysermc.floodgate;
import net.minecraft.server.MinecraftServer;
public final class MinecraftServerHolder {
// Static because commands *need* to be initialized before the server is available
// Otherwise it would be a class variable
private static MinecraftServer INSTANCE;
public static MinecraftServer get() {
return INSTANCE;
}
static void set(MinecraftServer instance) {
INSTANCE = instance;
}
private MinecraftServerHolder() {
}
}

View File

@@ -1,12 +1,15 @@
package org.geysermc.floodgate.addon.data;
import com.mojang.logging.LogUtils;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import net.minecraft.DefaultUncaughtExceptionHandler;
import net.minecraft.network.Connection;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.handshake.ClientIntentionPacket;
import net.minecraft.network.protocol.login.ServerboundHelloPacket;
import net.minecraft.server.network.ServerLoginPacketListenerImpl;
import org.geysermc.floodgate.MinecraftServerHolder;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.mixin.ConnectionMixin;
import org.geysermc.floodgate.mixin.ClientIntentionPacketMixin;
@@ -17,10 +20,13 @@ import org.geysermc.floodgate.api.player.FloodgatePlayer;
import org.geysermc.floodgate.config.FloodgateConfig;
import org.geysermc.floodgate.player.FloodgateHandshakeHandler;
import org.geysermc.floodgate.player.FloodgateHandshakeHandler.HandshakeResult;
import org.slf4j.Logger;
import java.net.InetSocketAddress;
public final class FabricDataHandler extends CommonDataHandler {
private static final Logger LOGGER = LogUtils.getLogger();
private final FloodgateLogger logger;
private Connection networkManager;
private FloodgatePlayer player;
@@ -95,8 +101,27 @@ public final class FabricDataHandler extends CommonDataHandler {
GameProfile gameProfile = new GameProfile(player.getCorrectUniqueId(), player.getCorrectUsername());
((ServerLoginPacketListenerSetter) networkManager.getPacketListener()).setGameProfile(gameProfile);
((ServerLoginPacketListenerSetter) networkManager.getPacketListener()).setLoginState();
if (player.isLinked() && player.getCorrectUniqueId().version() == 4) {
Thread texturesThread = new Thread("Bedrock Linked Player Texture Download") {
@Override
public void run() {
try {
MinecraftServerHolder.get().getSessionService()
.fillProfileProperties(gameProfile, true);
} catch (Exception e) {
LOGGER.error("Unable to get Bedrock linked player textures for " + gameProfile.getName(), e);
}
((ServerLoginPacketListenerSetter) networkManager.getPacketListener())
.setGameProfile(gameProfile);
((ServerLoginPacketListenerSetter) networkManager.getPacketListener()).setLoginState();
}
};
texturesThread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER));
texturesThread.start();
} else {
((ServerLoginPacketListenerSetter) networkManager.getPacketListener()).setGameProfile(gameProfile);
((ServerLoginPacketListenerSetter) networkManager.getPacketListener()).setLoginState();
}
ctx.pipeline().remove(this);
return true;

View File

@@ -6,7 +6,9 @@ import org.geysermc.floodgate.listener.FabricEventRegistration;
import org.geysermc.floodgate.logger.Log4jFloodgateLogger;
import org.geysermc.floodgate.platform.listener.ListenerRegistration;
import org.geysermc.floodgate.platform.util.PlatformUtils;
import org.geysermc.floodgate.pluginmessage.FabricPluginMessageRegistration;
import org.geysermc.floodgate.pluginmessage.FabricSkinApplier;
import org.geysermc.floodgate.pluginmessage.PluginMessageRegistration;
import org.geysermc.floodgate.util.FabricCommandUtil;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
@@ -85,6 +87,12 @@ public final class FabricPlatformModule extends AbstractModule {
return "Fabric";
}
@Provides
@Singleton
public PluginMessageRegistration pluginMessageRegister() {
return new FabricPluginMessageRegistration();
}
@Provides
@Singleton
public SkinApplier skinApplier() {

View File

@@ -0,0 +1,17 @@
package org.geysermc.floodgate.pluginmessage;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.resources.ResourceLocation;
public class FabricPluginMessageRegistration implements PluginMessageRegistration {
@Override
public void register(PluginMessageChannel channel) {
ServerPlayNetworking.registerGlobalReceiver(new ResourceLocation(channel.getIdentifier()),
(server, player, handler, buf, responseSender) -> {
System.out.println("Received channel of " + channel.getIdentifier());
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);
channel.handleServerCall(bytes, player.getUUID(), player.getGameProfile().getName());
});
}
}

View File

@@ -3,23 +3,23 @@ package org.geysermc.floodgate.pluginmessage;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.properties.PropertyMap;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import org.geysermc.floodgate.MinecraftServerHolder;
import org.geysermc.floodgate.api.player.FloodgatePlayer;
import org.geysermc.floodgate.mixin.ChunkMapMixin;
import org.geysermc.floodgate.skin.SkinApplier;
import org.geysermc.floodgate.skin.SkinData;
public final class FabricSkinApplier implements SkinApplier {
// See FabricCommandUtil
private static MinecraftServer SERVER;
@Override
public void applySkin(FloodgatePlayer floodgatePlayer, SkinData skinData) {
SERVER.execute(() -> {
ServerPlayer bedrockPlayer = SERVER.getPlayerList().getPlayer(floodgatePlayer.getCorrectUniqueId());
MinecraftServerHolder.get().execute(() -> {
System.out.println("Refreshing skins for " + floodgatePlayer);
ServerPlayer bedrockPlayer = MinecraftServerHolder.get().getPlayerList()
.getPlayer(floodgatePlayer.getCorrectUniqueId());
if (bedrockPlayer == null) {
// Disconnected probably?
return;
@@ -33,24 +33,28 @@ public final class FabricSkinApplier implements SkinApplier {
ChunkMap tracker = ((ServerLevel) bedrockPlayer.level).getChunkSource().chunkMap;
ChunkMap.TrackedEntity entry = ((ChunkMapMixin) tracker).getEntityMap().get(bedrockPlayer.getId());
entry.broadcastRemoved();
System.out.println("eeeee");
// Skin is applied - now it's time to refresh the player for everyone.
for (ServerPlayer otherPlayer : SERVER.getPlayerList().getPlayers()) {
if (otherPlayer == bedrockPlayer) {
continue;
for (ServerPlayer otherPlayer : MinecraftServerHolder.get().getPlayerList().getPlayers()) {
boolean samePlayer = otherPlayer == bedrockPlayer;
if (!samePlayer) {
// TrackedEntity#broadcastRemoved doesn't actually remove them from seenBy
entry.removePlayer(otherPlayer);
}
otherPlayer.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.REMOVE_PLAYER, bedrockPlayer));
otherPlayer.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, bedrockPlayer));
if (samePlayer) {
continue;
}
if (bedrockPlayer.level == otherPlayer.level) {
System.out.println("Updating entry");
entry.updatePlayer(otherPlayer);
}
}
});
}
public static void setServer(MinecraftServer server) {
SERVER = server;
}
}

View File

@@ -4,11 +4,11 @@ import com.mojang.authlib.GameProfile;
import me.lucko.fabric.api.permissions.v0.Permissions;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.network.chat.Component;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.players.UserWhiteListEntry;
import net.minecraft.world.entity.Entity;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.floodgate.MinecraftServerHolder;
import org.geysermc.floodgate.api.FloodgateApi;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.platform.command.CommandUtil;
@@ -17,10 +17,6 @@ import org.geysermc.floodgate.player.UserAudience;
import java.util.*;
public final class FabricCommandUtil extends CommandUtil {
// Static because commands *need* to be initialized before the server is available
// Otherwise it would be a class variable
private static MinecraftServer SERVER;
private final FloodgateLogger logger;
private UserAudience console;
@@ -58,19 +54,19 @@ public final class FabricCommandUtil extends CommandUtil {
@Override
public Object getPlayerByUuid(@NonNull UUID uuid) {
ServerPlayer player = SERVER.getPlayerList().getPlayer(uuid);
ServerPlayer player = MinecraftServerHolder.get().getPlayerList().getPlayer(uuid);
return player != null ? player : uuid;
}
@Override
public Object getPlayerByUsername(@NonNull String username) {
ServerPlayer player = SERVER.getPlayerList().getPlayerByName(username);
ServerPlayer player = MinecraftServerHolder.get().getPlayerList().getPlayerByName(username);
return player != null ? player : username;
}
@Override
protected Collection<?> getOnlinePlayers() {
return SERVER.getPlayerList().getPlayers();
return MinecraftServerHolder.get().getPlayerList().getPlayers();
}
@Override
@@ -82,7 +78,7 @@ public final class FabricCommandUtil extends CommandUtil {
public void sendMessage(Object target, String message) {
CommandSourceStack commandSource = (CommandSourceStack) target;
if (commandSource.getEntity() instanceof ServerPlayer) {
SERVER.execute(() -> ((ServerPlayer) commandSource.getEntity())
MinecraftServerHolder.get().execute(() -> ((ServerPlayer) commandSource.getEntity())
.displayClientMessage(Component.literal(message), false));
} else {
// Console?
@@ -100,18 +96,14 @@ public final class FabricCommandUtil extends CommandUtil {
@Override
public boolean whitelistPlayer(UUID uuid, String username) {
GameProfile profile = new GameProfile(uuid, username);
SERVER.getPlayerList().getWhiteList().add(new UserWhiteListEntry(profile));
MinecraftServerHolder.get().getPlayerList().getWhiteList().add(new UserWhiteListEntry(profile));
return true;
}
@Override
public boolean removePlayerFromWhitelist(UUID uuid, String username) {
GameProfile profile = new GameProfile(uuid, username);
SERVER.getPlayerList().getWhiteList().remove(profile);
MinecraftServerHolder.get().getPlayerList().getWhiteList().remove(profile);
return true;
}
public static void setServer(MinecraftServer server) {
SERVER = server;
}
}

View File

@@ -1,15 +1,13 @@
package org.geysermc.floodgate.util;
import net.minecraft.SharedConstants;
import net.minecraft.server.MinecraftServer;
import org.geysermc.floodgate.MinecraftServerHolder;
import org.geysermc.floodgate.platform.util.PlatformUtils;
public class FabricPlatformUtils extends PlatformUtils {
private static MinecraftServer SERVER;
@Override
public AuthType authType() {
return SERVER.usesAuthentication() ? AuthType.ONLINE : AuthType.OFFLINE;
return MinecraftServerHolder.get().usesAuthentication() ? AuthType.ONLINE : AuthType.OFFLINE;
}
@Override
@@ -19,10 +17,6 @@ public class FabricPlatformUtils extends PlatformUtils {
@Override
public String serverImplementationName() {
return "Fabric";
}
public static void setServer(MinecraftServer server) {
SERVER = server;
return MinecraftServerHolder.get().getServerModName();
}
}