mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2025-12-30 20:29:30 +00:00
Update for 1.19
With thanks to Kastle.
This commit is contained in:
40
build.gradle
40
build.gradle
@@ -2,7 +2,7 @@ import net.fabricmc.loom.task.RemapJarTask
|
||||
|
||||
plugins {
|
||||
id 'com.github.johnrengelman.shadow' version '7.0.0'
|
||||
id 'fabric-loom' version '0.10-SNAPSHOT'
|
||||
id 'fabric-loom' version '0.12-SNAPSHOT'
|
||||
id 'java'
|
||||
id 'maven-publish'
|
||||
}
|
||||
@@ -14,8 +14,8 @@ archivesBaseName = project.archives_base_name
|
||||
version = project.mod_version
|
||||
group = project.maven_group
|
||||
|
||||
minecraft {
|
||||
accessWidener = file("src/main/resources/floodgate.accesswidener")
|
||||
loom {
|
||||
accessWidenerPath = file("src/main/resources/floodgate.accesswidener")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -31,19 +31,20 @@ dependencies {
|
||||
// You may need to force-disable transitiveness on them.
|
||||
|
||||
// Base Floodgate
|
||||
implementation("org.geysermc.floodgate:common:${project.mod_version}")
|
||||
shadow("org.geysermc.floodgate:common:${project.mod_version}") {
|
||||
implementation("org.geysermc.floodgate:core:${project.mod_version}")
|
||||
shadow("org.geysermc.floodgate:core:${project.mod_version}") {
|
||||
exclude group: 'com.google.guava', module: "guava"
|
||||
exclude group: 'com.google.code.gson', module: "gson"
|
||||
exclude group: 'org.slf4j', module: "slf4j-api"
|
||||
exclude group: 'net.kyori', module: '*' // Let Adventure-Platform provide its desired Adventure version
|
||||
exclude group: 'it.unimi.dsi.fastutil', module: "*"
|
||||
}
|
||||
|
||||
include(modImplementation('cloud.commandframework:cloud-fabric:1.5.0') {
|
||||
include(modImplementation('cloud.commandframework:cloud-fabric:1.7.0-SNAPSHOT') {
|
||||
because "Commands library implementation for Fabric"
|
||||
})
|
||||
|
||||
include(modImplementation('net.kyori:adventure-platform-fabric:5.2.1') {
|
||||
include(modImplementation('net.kyori:adventure-platform-fabric:5.4.0-SNAPSHOT') {
|
||||
because "Chat library implementation for Fabric that includes methods for communicating with the server"
|
||||
// Thanks to zml for this fix
|
||||
// The package modifies Brigadier which causes a LinkageError at runtime if included
|
||||
@@ -60,6 +61,12 @@ repositories {
|
||||
maven {
|
||||
url = 'https://oss.sonatype.org/content/repositories/snapshots'
|
||||
}
|
||||
// specifically for adventure-platform-fabric:5.4.0-SNAPSHOT
|
||||
maven {
|
||||
name = "sonatype-oss-snapshots1"
|
||||
url = "https://s01.oss.sonatype.org/content/repositories/snapshots/"
|
||||
mavenContent { snapshotsOnly() }
|
||||
}
|
||||
// Standard OpenCollab repositories
|
||||
maven {
|
||||
name = 'opencollab-release-repo'
|
||||
@@ -96,29 +103,14 @@ task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
// dependencies {
|
||||
// exclude('net.fabricmc:.*')
|
||||
// //include(dependency('org.geysermc.floodgate:.*'))
|
||||
// //include(dependency("org.geysermc.cumulus:.*"))
|
||||
// //include(dependency('org.geysermc:.*'))
|
||||
// exclude '/mappings/*'
|
||||
// }
|
||||
configurations = [project.configurations.shadow]
|
||||
//dependencies {
|
||||
//exclude(dependency('cloud.commandframework:cloud-fabric:.*'))
|
||||
//exclude(dependency('net.kyori:adventure-platform-fabric:.*'))
|
||||
//}
|
||||
|
||||
//relocate 'net.kyori', 'org.geysermc.floodgate.relocations.kyori'
|
||||
//relocate 'cloud.commandframework', 'org.geysermc.floodgate.relocations.cloud'
|
||||
relocate 'it.unimi.dsi.fastutil', 'org.geysermc.floodgate.relocations.fastutil'
|
||||
}
|
||||
|
||||
task remappedShadowJar(type: RemapJarTask) {
|
||||
dependsOn tasks.shadowJar
|
||||
input = tasks.shadowJar.archivePath
|
||||
input = tasks.shadowJar.archiveFile
|
||||
addNestedDependencies = true
|
||||
remapAccessWidener = true // Required for our access widener changes to go into effect and not crash on startup
|
||||
//remapAccessWidener = true // Required for our access widener changes to go into effect and not crash on startup
|
||||
archiveName = "floodgate-fabric.jar"
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
# Done to increase the memory available to gradle.
|
||||
org.gradle.jvmargs=-Xmx1G
|
||||
org.gradle.jvmargs=-Xmx2G
|
||||
# Fabric Properties
|
||||
# check these on https://modmuss50.me/fabric.html
|
||||
minecraft_version=1.18.2
|
||||
loader_version=0.12.6
|
||||
minecraft_version=1.19
|
||||
loader_version=0.14.6
|
||||
# Mod Properties
|
||||
mod_version=2.1.0-SNAPSHOT
|
||||
mod_version=2.2.0-SNAPSHOT
|
||||
maven_group=org.geysermc.floodgate
|
||||
archives_base_name=floodgate-fabric
|
||||
# Dependencies
|
||||
# check this on https://modmuss50.me/fabric.html
|
||||
fabric_version=0.43.1+1.18
|
||||
fabric_version=0.55.3+1.19
|
||||
# Our stuff
|
||||
lombok_version=1.18.20
|
||||
|
||||
@@ -6,11 +6,11 @@ import com.google.inject.Injector;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.kyori.adventure.platform.fabric.FabricServerAudiences;
|
||||
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
|
||||
@@ -29,12 +29,11 @@ public class FabricMod implements ModInitializer {
|
||||
ServerLifecycleEvents.SERVER_STARTED.register((server) -> {
|
||||
long ctm = System.currentTimeMillis();
|
||||
|
||||
FabricServerAudiences adventure = FabricServerAudiences.of(server);
|
||||
|
||||
// Stupid hack, see the class for more information
|
||||
// This can probably be Guice-i-fied but that is beyond me
|
||||
FabricCommandUtil.setLaterVariables(server, adventure);
|
||||
FabricCommandUtil.setServer(server);
|
||||
FabricSkinApplier.setServer(server);
|
||||
FabricPlatformUtils.setServer(server);
|
||||
|
||||
platform.enable(
|
||||
new FabricAddonModule(),
|
||||
|
||||
@@ -41,7 +41,7 @@ public final class FabricDataAddon implements InjectorAddon {
|
||||
@Override
|
||||
public void onChannelClosed(Channel channel) {
|
||||
FloodgatePlayer player = channel.attr(playerAttribute).get();
|
||||
if (player != null && api.removePlayer(player)) {
|
||||
if (player != null && api.setPendingRemove(player)) {
|
||||
logger.translatedInfo("floodgate.ingame.disconnect_name", player.getCorrectUsername());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.player.FloodgatePlayerImpl;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
|
||||
public final class FabricEventListener {
|
||||
@@ -18,7 +17,6 @@ public final class FabricEventListener {
|
||||
public void onPlayerJoin(ServerGamePacketListenerImpl networkHandler, PacketSender packetSender, MinecraftServer server) {
|
||||
FloodgatePlayer player = api.getPlayer(networkHandler.player.getUUID());
|
||||
if (player != null) {
|
||||
player.as(FloodgatePlayerImpl.class).setLogin(false);
|
||||
logger.translatedInfo(
|
||||
"floodgate.ingame.login_name",
|
||||
player.getCorrectUsername(), player.getCorrectUniqueId()
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.geysermc.floodgate.mixin;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(ChunkMap.class)
|
||||
public interface ChunkMapMixin {
|
||||
@Accessor("entityMap")
|
||||
Int2ObjectMap<ChunkMap.TrackedEntity> getEntityMap();
|
||||
}
|
||||
@@ -19,7 +19,7 @@ public final class FabricCommandModule extends CommandModule {
|
||||
public CommandManager<UserAudience> commandManager(CommandUtil commandUtil) {
|
||||
FabricCommandManager<UserAudience, CommandSourceStack> commandManager = new FabricServerCommandManager<>(
|
||||
CommandExecutionCoordinator.simpleCoordinator(),
|
||||
commandUtil::getAudience,
|
||||
commandUtil::getUserAudience,
|
||||
audience -> (CommandSourceStack) audience.source()
|
||||
);
|
||||
commandManager.registerCommandPreProcessor(new FloodgateCommandPreprocessor<>(commandUtil));
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.geysermc.floodgate.listener.FabricEventListener;
|
||||
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.FabricSkinApplier;
|
||||
import org.geysermc.floodgate.util.FabricCommandUtil;
|
||||
import com.google.inject.AbstractModule;
|
||||
@@ -18,11 +19,17 @@ import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.inject.CommonPlatformInjector;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.skin.SkinApplier;
|
||||
import org.geysermc.floodgate.util.FabricPlatformUtils;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class FabricPlatformModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(PlatformUtils.class).to(FabricPlatformUtils.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public FloodgateLogger floodgateLogger(LanguageManager languageManager) {
|
||||
@@ -35,7 +42,7 @@ public final class FabricPlatformModule extends AbstractModule {
|
||||
FloodgateApi api,
|
||||
FloodgateLogger logger,
|
||||
LanguageManager languageManager) {
|
||||
return new FabricCommandUtil(api, logger, languageManager);
|
||||
return new FabricCommandUtil(languageManager, api, logger);
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
@@ -1,26 +1,17 @@
|
||||
package org.geysermc.floodgate.pluginmessage;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.*;
|
||||
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 net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import net.minecraft.world.entity.ai.attributes.AttributeInstance;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
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;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class FabricSkinApplier implements SkinApplier {
|
||||
// See FabricCommandUtil
|
||||
private static MinecraftServer SERVER;
|
||||
@@ -40,60 +31,20 @@ public final class FabricSkinApplier implements SkinApplier {
|
||||
properties.removeAll("textures");
|
||||
properties.put("textures", new Property("textures", skinData.getValue(), skinData.getSignature()));
|
||||
|
||||
// Skin is applied - now it's time to refresh the player for everyone. Oof.
|
||||
ChunkMap tracker = ((ServerLevel) bedrockPlayer.level).getChunkSource().chunkMap;
|
||||
ChunkMap.TrackedEntity entry = ((ChunkMapMixin) tracker).getEntityMap().get(bedrockPlayer.getId());
|
||||
entry.broadcastRemoved();
|
||||
|
||||
// Skin is applied - now it's time to refresh the player for everyone.
|
||||
for (ServerPlayer otherPlayer : SERVER.getPlayerList().getPlayers()) {
|
||||
if (otherPlayer == bedrockPlayer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean loadedInWorld = otherPlayer.getCommandSenderWorld().getEntity(bedrockPlayer.getId()) != null;
|
||||
if (loadedInWorld) {
|
||||
// Player is loaded in this world
|
||||
otherPlayer.connection.send(new ClientboundRemoveEntitiesPacket(bedrockPlayer.getId()));
|
||||
}
|
||||
otherPlayer.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.REMOVE_PLAYER, bedrockPlayer));
|
||||
|
||||
otherPlayer.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, bedrockPlayer));
|
||||
if (loadedInWorld) {
|
||||
// Copied from EntityTrackerEntry
|
||||
Packet<?> spawnPacket = bedrockPlayer.getAddEntityPacket();
|
||||
otherPlayer.connection.send(spawnPacket);
|
||||
if (!bedrockPlayer.getEntityData().isEmpty()) {
|
||||
otherPlayer.connection.send(new ClientboundSetEntityDataPacket(bedrockPlayer.getId(), bedrockPlayer.getEntityData(), true));
|
||||
}
|
||||
|
||||
Collection<AttributeInstance> collection = bedrockPlayer.getAttributes().getDirtyAttributes();
|
||||
if (!collection.isEmpty()) {
|
||||
otherPlayer.connection.send(new ClientboundUpdateAttributesPacket(bedrockPlayer.getId(), collection));
|
||||
}
|
||||
|
||||
otherPlayer.connection.send(new ClientboundSetEntityMotionPacket(bedrockPlayer.getId(), bedrockPlayer.getDeltaMovement()));
|
||||
|
||||
List<Pair<EquipmentSlot, ItemStack>> equipmentList = Lists.newArrayList();
|
||||
EquipmentSlot[] slots = EquipmentSlot.values();
|
||||
|
||||
for (EquipmentSlot equipmentSlot : slots) {
|
||||
ItemStack itemStack = bedrockPlayer.getItemBySlot(equipmentSlot);
|
||||
if (!itemStack.isEmpty()) {
|
||||
equipmentList.add(Pair.of(equipmentSlot, itemStack.copy()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!equipmentList.isEmpty()) {
|
||||
otherPlayer.connection.send(new ClientboundSetEquipmentPacket(bedrockPlayer.getId(), equipmentList));
|
||||
}
|
||||
|
||||
for (MobEffectInstance mobEffectInstance : bedrockPlayer.getActiveEffects()) {
|
||||
otherPlayer.connection.send(new ClientboundUpdateMobEffectPacket(bedrockPlayer.getId(), mobEffectInstance));
|
||||
}
|
||||
|
||||
if (!bedrockPlayer.getPassengers().isEmpty()) {
|
||||
otherPlayer.connection.send(new ClientboundSetPassengersPacket(bedrockPlayer));
|
||||
}
|
||||
|
||||
if (bedrockPlayer.getVehicle() != null) {
|
||||
otherPlayer.connection.send(new ClientboundSetPassengersPacket(bedrockPlayer.getVehicle()));
|
||||
}
|
||||
if (bedrockPlayer.level == otherPlayer.level) {
|
||||
entry.updatePlayer(otherPlayer);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
package org.geysermc.floodgate.util;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.fabric.api.permissions.v0.Permissions;
|
||||
import net.kyori.adventure.platform.fabric.FabricServerAudiences;
|
||||
import net.kyori.adventure.platform.fabric.PlayerLocales;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.players.UserWhiteListEntry;
|
||||
@@ -17,110 +11,66 @@ import net.minecraft.world.entity.Entity;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.platform.command.TranslatableMessage;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.geysermc.floodgate.player.UserAudienceArgument;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class FabricCommandUtil implements CommandUtil {
|
||||
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;
|
||||
// This one also requires the server so it's bundled in
|
||||
private static FabricServerAudiences ADVENTURE;
|
||||
|
||||
@Getter private final FloodgateApi api;
|
||||
@Getter private final FloodgateLogger logger;
|
||||
@Getter private final LanguageManager manager;
|
||||
private final FloodgateLogger logger;
|
||||
private UserAudience console;
|
||||
|
||||
@Override
|
||||
public @NonNull UserAudience getAudience(@NonNull Object source) {
|
||||
if (!(source instanceof CommandSourceStack commandSource)) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
if (commandSource.getEntity() instanceof ServerPlayer) {
|
||||
return getAudience0((ServerPlayer) commandSource.getEntity());
|
||||
}
|
||||
|
||||
return new FabricUserAudience(null, manager.getDefaultLocale(), commandSource, this);
|
||||
public FabricCommandUtil(LanguageManager manager, FloodgateApi api, FloodgateLogger logger) {
|
||||
super(manager, api);
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserAudience getAudienceByUuid(@NonNull UUID uuid) {
|
||||
public UserAudience getUserAudience(final @NonNull Object sourceObj) {
|
||||
if (!(sourceObj instanceof CommandSourceStack stack)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (stack.getEntity() == null) {
|
||||
if (console != null) {
|
||||
return console;
|
||||
}
|
||||
return console = new UserAudience.ConsoleAudience(stack, this);
|
||||
}
|
||||
ServerPlayer player = stack.getPlayer();
|
||||
//Locale locale = PlayerLocales.locale(player);
|
||||
return new UserAudience.PlayerAudience(player.getUUID(), player.getGameProfile().getName(), "en_US",
|
||||
stack, this, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getUsernameFromSource(@NonNull Object source) {
|
||||
return ((ServerPlayer) source).getGameProfile().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected UUID getUuidFromSource(@NonNull Object source) {
|
||||
return ((ServerPlayer) source).getUUID();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPlayerByUuid(@NonNull UUID uuid) {
|
||||
ServerPlayer player = SERVER.getPlayerList().getPlayer(uuid);
|
||||
if (player != null) {
|
||||
return getAudience0(player);
|
||||
}
|
||||
return getOfflineAudienceByUuid(uuid);
|
||||
return player != null ? player : uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserAudience getAudienceByUsername(@NonNull String username) {
|
||||
public Object getPlayerByUsername(@NonNull String username) {
|
||||
ServerPlayer player = SERVER.getPlayerList().getPlayerByName(username);
|
||||
if (player != null) {
|
||||
return getAudience0(player);
|
||||
}
|
||||
return getOfflineAudienceByUsername(username);
|
||||
}
|
||||
|
||||
private FabricUserAudience getAudience0(ServerPlayer player) {
|
||||
// Apparently can be null even if Javadocs say otherwise
|
||||
Locale locale = PlayerLocales.locale(player);
|
||||
return new FabricUserAudience.NamedFabricUserAudience(
|
||||
player.getName().getString(),
|
||||
player.getUUID(), locale != null ?
|
||||
locale.getLanguage().toLowerCase(Locale.ROOT) + "_" + locale.getCountry().toUpperCase(Locale.ROOT) :
|
||||
manager.getDefaultLocale(), player.createCommandSourceStack(), this, true);
|
||||
return player != null ? player : username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull UserAudience getOfflineAudienceByUuid(@NonNull UUID uuid) {
|
||||
return new FabricUserAudience(uuid, null, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull UserAudience getOfflineAudienceByUsername(@NonNull String username) {
|
||||
UUID uuid = null;
|
||||
Optional<GameProfile> profile = SERVER.getProfileCache().get(username);
|
||||
if (profile.isPresent()) {
|
||||
uuid = profile.get().getId();
|
||||
}
|
||||
return new FabricUserAudience.NamedFabricUserAudience(username, uuid, username, null, this, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Collection<String> getOnlineUsernames(UserAudienceArgument.@NonNull PlayerType limitTo) {
|
||||
List<ServerPlayer> players = SERVER.getPlayerList().getPlayers();
|
||||
|
||||
Collection<String> usernames = new ArrayList<>();
|
||||
switch (limitTo) {
|
||||
case ALL_PLAYERS:
|
||||
for (ServerPlayer player : players) {
|
||||
usernames.add(player.getName().getString());
|
||||
}
|
||||
break;
|
||||
case ONLY_JAVA:
|
||||
for (ServerPlayer player : players) {
|
||||
if (!api.isFloodgatePlayer(player.getUUID())) {
|
||||
usernames.add(player.getName().getString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ONLY_BEDROCK:
|
||||
for (ServerPlayer player : players) {
|
||||
if (api.isFloodgatePlayer(player.getUUID())) {
|
||||
usernames.add(player.getName().getString());
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown PlayerType");
|
||||
}
|
||||
return usernames;
|
||||
protected Collection<?> getOnlinePlayers() {
|
||||
return SERVER.getPlayerList().getPlayers();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -128,35 +78,12 @@ public final class FabricCommandUtil implements CommandUtil {
|
||||
return Permissions.check((Entity) player, permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Object> getOnlinePlayersWithPermission(String permission) {
|
||||
List<Object> players = new ArrayList<>();
|
||||
for (ServerPlayer player : SERVER.getPlayerList().getPlayers()) {
|
||||
if (hasPermission(player, permission)) {
|
||||
players.add(player);
|
||||
}
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(Object player, String locale, TranslatableMessage message, Object... args) {
|
||||
CommandSourceStack commandSource = (CommandSourceStack) player;
|
||||
if (commandSource.getEntity() instanceof ServerPlayer) {
|
||||
SERVER.execute(() -> ((ServerPlayer) commandSource.getEntity())
|
||||
.displayClientMessage(translateAndTransform(locale, message, args), false));
|
||||
} else {
|
||||
// Console?
|
||||
logger.info(message.translateMessage(manager, locale, args));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(Object target, String message) {
|
||||
CommandSourceStack commandSource = (CommandSourceStack) target;
|
||||
if (commandSource.getEntity() instanceof ServerPlayer) {
|
||||
SERVER.execute(() -> ((ServerPlayer) commandSource.getEntity())
|
||||
.displayClientMessage(new TextComponent(message), false));
|
||||
.displayClientMessage(Component.literal(message), false));
|
||||
} else {
|
||||
// Console?
|
||||
logger.info(message);
|
||||
@@ -164,8 +91,10 @@ public final class FabricCommandUtil implements CommandUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kickPlayer(Object player, String locale, TranslatableMessage message, Object... args) {
|
||||
getPlayer(player).connection.disconnect(translateAndTransform(locale, message, args));
|
||||
public void kickPlayer(Object o, String message) {
|
||||
if (o instanceof ServerPlayer player) {
|
||||
player.connection.disconnect(Component.literal(message));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -182,26 +111,7 @@ public final class FabricCommandUtil implements CommandUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
private ServerPlayer getPlayer(Object instance) {
|
||||
try {
|
||||
CommandSourceStack source = (CommandSourceStack) instance;
|
||||
return source.getPlayerOrException();
|
||||
} catch (ClassCastException | CommandSyntaxException exception) {
|
||||
logger.error("Failed to cast {} as a player", instance.getClass().getName());
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
public Component translateAndTransform(String locale, TranslatableMessage message, Object... args) {
|
||||
return new TextComponent(message.translateMessage(manager, locale, args));
|
||||
}
|
||||
|
||||
public FabricServerAudiences getAdventure() {
|
||||
return ADVENTURE;
|
||||
}
|
||||
|
||||
public static void setLaterVariables(MinecraftServer server, FabricServerAudiences adventure) {
|
||||
public static void setServer(MinecraftServer server) {
|
||||
SERVER = server;
|
||||
ADVENTURE = adventure;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.geysermc.floodgate.util;
|
||||
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String minecraftVersion() {
|
||||
return SharedConstants.getCurrentVersion().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String serverImplementationName() {
|
||||
return "Fabric";
|
||||
}
|
||||
|
||||
public static void setServer(MinecraftServer server) {
|
||||
SERVER = server;
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
package org.geysermc.floodgate.util;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.lucko.fabric.api.permissions.v0.Permissions;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.audience.ForwardingAudience;
|
||||
import net.kyori.adventure.audience.MessageType;
|
||||
import net.kyori.adventure.identity.Identity;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.floodgate.platform.command.TranslatableMessage;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class FabricUserAudience implements UserAudience, ForwardingAudience.Single {
|
||||
private final UUID uuid;
|
||||
private final String locale;
|
||||
private final CommandSourceStack source;
|
||||
private final FabricCommandUtil commandUtil;
|
||||
|
||||
@Override
|
||||
public @NonNull Audience audience() {
|
||||
return commandUtil.getAdventure().audience(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull UUID uuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String username() {
|
||||
if (source == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return source.getTextName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String locale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull CommandSourceStack source() {
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(@NonNull String permission) {
|
||||
return Permissions.check(source, permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(@NonNull Identity source, @NonNull Component message, @NonNull MessageType type) {
|
||||
commandUtil.getAdventure().audience(this.source).sendMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(TranslatableMessage message, Object... args) {
|
||||
commandUtil.sendMessage(this.source, this.locale, message, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(@NonNull Component reason) {
|
||||
if (source.getEntity() instanceof ServerPlayer) {
|
||||
((ServerPlayer) source.getEntity()).connection.disconnect(
|
||||
commandUtil.getAdventure().toNative(reason)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(TranslatableMessage message, Object... args) {
|
||||
if (source.getEntity() instanceof ServerPlayer) {
|
||||
((ServerPlayer) source.getEntity()).connection.disconnect(
|
||||
commandUtil.translateAndTransform(this.locale, message, args)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used whenever a name has been explicitly defined for us. Most helpful in offline players.
|
||||
*/
|
||||
public static final class NamedFabricUserAudience extends FabricUserAudience implements PlayerAudience {
|
||||
private final String name;
|
||||
private final boolean online;
|
||||
|
||||
public NamedFabricUserAudience(
|
||||
String name,
|
||||
UUID uuid,
|
||||
String locale,
|
||||
CommandSourceStack source,
|
||||
FabricCommandUtil commandUtil,
|
||||
boolean online) {
|
||||
super(uuid, locale, source, commandUtil);
|
||||
this.name = name;
|
||||
this.online = online;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String username() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean online() {
|
||||
return online;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,8 @@
|
||||
"floodgate.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.11.3",
|
||||
"fabricloader": ">=0.14.6",
|
||||
"fabric": "*",
|
||||
"minecraft": ">=1.18.2"
|
||||
"minecraft": ">=1.19"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
accessWidener v1 named
|
||||
|
||||
# To change login state
|
||||
accessible class net/minecraft/server/network/ServerLoginPacketListenerImpl$State
|
||||
accessible class net/minecraft/server/network/ServerLoginPacketListenerImpl$State
|
||||
# For player skin refreshing
|
||||
accessible class net/minecraft/server/level/ChunkMap$TrackedEntity
|
||||
@@ -4,10 +4,11 @@
|
||||
"package": "org.geysermc.floodgate.mixin",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
"ChunkMapMixin",
|
||||
"ClientIntentionPacketMixin",
|
||||
"ConnectionMixin",
|
||||
"ServerLoginPacketListenerImplMixin",
|
||||
"ServerConnectionListenerMixin",
|
||||
"ClientIntentionPacketMixin"
|
||||
"ServerLoginPacketListenerImplMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
||||
Reference in New Issue
Block a user