Add requirements for mods and see mods in use if so

This commit is contained in:
libraryaddict 2020-04-16 18:32:09 +12:00
parent 1791622323
commit caa0aa69d9
No known key found for this signature in database
GPG Key ID: 052E4FBCD257AEA4
8 changed files with 209 additions and 10 deletions

View File

@ -16,6 +16,7 @@ import me.libraryaddict.disguise.utilities.reflection.NmsVersion;
import me.libraryaddict.disguise.utilities.translations.LibsMsg; import me.libraryaddict.disguise.utilities.translations.LibsMsg;
import me.libraryaddict.disguise.utilities.translations.TranslateType; import me.libraryaddict.disguise.utilities.translations.TranslateType;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.boss.BarColor; import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle; import org.bukkit.boss.BarStyle;
@ -590,6 +591,8 @@ public class DisguiseConfig {
return; return;
} }
ArrayList<String> channels = new ArrayList<>();
for (String name : config.getConfigurationSection("Custom-Entities").getKeys(false)) { for (String name : config.getConfigurationSection("Custom-Entities").getKeys(false)) {
try { try {
if (!name.matches("[a-zA-Z0-9_]+")) { if (!name.matches("[a-zA-Z0-9_]+")) {
@ -620,6 +623,20 @@ public class DisguiseConfig {
String[] version = String[] version =
mod == null || !section.contains("Version") ? null : section.getString("Version").split(","); mod == null || !section.contains("Version") ? null : section.getString("Version").split(",");
String requireMessage = mod == null ? null : section.getString("Required"); String requireMessage = mod == null ? null : section.getString("Required");
if (section.contains("Channels")) {
for (String s : section.getString("Channels").split(",")) {
if (!s.contains("|")) {
s += "|";
DisguiseUtilities.getLogger().severe("No channel version declared for " + s);
}
channels.add(s);
}
}
if (requireMessage != null) {
requireMessage = ChatColor.translateAlternateColorCodes('&', requireMessage);
}
CustomEntity entity = new CustomEntity(null, name, living, mod, version, requireMessage, 0); CustomEntity entity = new CustomEntity(null, name, living, mod, version, requireMessage, 0);
@ -635,6 +652,8 @@ public class DisguiseConfig {
ex.printStackTrace(); ex.printStackTrace();
} }
} }
new ModdedManager(channels);
} }
public static ArrayList<String> doOutput(ConfigurationSection config, boolean informChangedUnknown, public static ArrayList<String> doOutput(ConfigurationSection config, boolean informChangedUnknown,

View File

@ -12,6 +12,8 @@ import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.LibsEntityInteract; import me.libraryaddict.disguise.utilities.LibsEntityInteract;
import me.libraryaddict.disguise.utilities.LibsPremium; import me.libraryaddict.disguise.utilities.LibsPremium;
import me.libraryaddict.disguise.utilities.UpdateChecker; import me.libraryaddict.disguise.utilities.UpdateChecker;
import me.libraryaddict.disguise.utilities.modded.CustomEntity;
import me.libraryaddict.disguise.utilities.modded.ModdedManager;
import me.libraryaddict.disguise.utilities.translations.LibsMsg; import me.libraryaddict.disguise.utilities.translations.LibsMsg;
import org.apache.commons.lang.math.RandomUtils; import org.apache.commons.lang.math.RandomUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -41,6 +43,7 @@ import org.bukkit.scheduler.BukkitTask;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Optional;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -372,6 +375,18 @@ public class DisguiseListener implements Listener {
} }
} }
@EventHandler
public void onLogin(PlayerRegisterChannelEvent event) {
// If it's not a forge handshake, or we didn't register it
if (!event.getChannel().equals("fml:handshake") ||
!Bukkit.getMessenger().isOutgoingChannelRegistered(LibsDisguises.getInstance(), "fml:handshake")) {
return;
}
event.getPlayer()
.sendPluginMessage(LibsDisguises.getInstance(), "fml:handshake", ModdedManager.getFmlHandshake());
}
@EventHandler @EventHandler
public void onJoin(PlayerJoinEvent event) { public void onJoin(PlayerJoinEvent event) {
Player p = event.getPlayer(); Player p = event.getPlayer();
@ -428,17 +443,41 @@ public class DisguiseListener implements Listener {
new BukkitRunnable() { new BukkitRunnable() {
@Override @Override
public void run() { public void run() {
if (!event.getPlayer().isOnline()) { if (!p.isOnline()) {
return; return;
} }
DisguiseUtilities.registerNoName(event.getPlayer().getScoreboard()); DisguiseUtilities.registerNoName(p.getScoreboard());
if (event.getPlayer().getScoreboard() != Bukkit.getScoreboardManager().getMainScoreboard()) { if (p.getScoreboard() != Bukkit.getScoreboardManager().getMainScoreboard()) {
DisguiseUtilities.registerAllExtendedNames(event.getPlayer().getScoreboard()); DisguiseUtilities.registerAllExtendedNames(p.getScoreboard());
}
if (!p.hasMetadata("forge_mods")) {
Optional<CustomEntity> required = ModdedManager.getEntities().values().stream()
.filter(c -> c.getMod() != null && c.getRequired() != null).findAny();
required.ifPresent(customEntity -> p.kickPlayer(customEntity.getRequired()));
} }
} }
}.runTaskLater(LibsDisguises.getInstance(), 20); }.runTaskLater(LibsDisguises.getInstance(), 20);
new BukkitRunnable() {
@Override
public void run() {
if (!p.isOnline()) {
return;
}
if (!p.hasMetadata("forge_mods")) {
Optional<CustomEntity> required = ModdedManager.getEntities().values().stream()
.filter(c -> c.getMod() != null && c.getRequired() != null).findAny();
required.ifPresent(customEntity -> p.kickPlayer(customEntity.getRequired()));
}
}
}.runTaskLater(LibsDisguises.getInstance(), 60);
} }
/** /**

View File

@ -106,6 +106,40 @@ public class LibsDisguisesCommand implements CommandExecutor, TabCompleter {
DisguiseConfig.loadConfig(); DisguiseConfig.loadConfig();
sender.sendMessage(LibsMsg.RELOADED_CONFIG.get()); sender.sendMessage(LibsMsg.RELOADED_CONFIG.get());
return true; return true;
} else if (args[0].equalsIgnoreCase("mods")) {
if (!sender.hasPermission("libsdisguises.mods")) {
sender.sendMessage(LibsMsg.NO_PERM.get());
return true;
}
if (!Bukkit.getMessenger().isOutgoingChannelRegistered(LibsDisguises.getInstance(), "fml:handshake")) {
sender.sendMessage(LibsMsg.NO_MODS_LISTENING.get());
return true;
}
Player player;
if (args.length > 1) {
player = Bukkit.getPlayer(args[1]);
if (player == null) {
sender.sendMessage(LibsMsg.CANNOT_FIND_PLAYER.get(args[1]));
return true;
}
} else if (sender instanceof Player) {
player = (Player) sender;
} else {
sender.sendMessage(LibsMsg.NO_CONSOLE.get());
return true;
}
if (!player.hasMetadata("forge_mods")) {
sender.sendMessage(LibsMsg.NO_MODS.get(player.getName()));
return true;
}
sender.sendMessage(LibsMsg.MODS_LIST.get(player.getName(),
StringUtils.join((List<String>) player.getMetadata("forge_mods").get(0).value(), ", ")));
} else if (args[0].equalsIgnoreCase("scoreboard") || args[0].equalsIgnoreCase("board") || } else if (args[0].equalsIgnoreCase("scoreboard") || args[0].equalsIgnoreCase("board") ||
args[0].equalsIgnoreCase("teams")) { args[0].equalsIgnoreCase("teams")) {
if (!sender.hasPermission("libsdisguises.scoreboardtest")) { if (!sender.hasPermission("libsdisguises.scoreboardtest")) {
@ -368,7 +402,7 @@ public class LibsDisguisesCommand implements CommandExecutor, TabCompleter {
String[] args = getArgs(origArgs); String[] args = getArgs(origArgs);
if (args.length == 0) if (args.length == 0)
tabs.addAll(Arrays.asList("reload", "scoreboard", "permtest", "json", "metainfo", "config")); tabs.addAll(Arrays.asList("reload", "scoreboard", "permtest", "json", "metainfo", "config", "mods"));
return filterTabs(tabs, origArgs); return filterTabs(tabs, origArgs);
} }

View File

@ -1,10 +1,18 @@
package me.libraryaddict.disguise.utilities.modded; package me.libraryaddict.disguise.utilities.modded;
import com.comphenix.protocol.utility.StreamSerializer;
import lombok.Getter;
import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.DisguiseType; import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.utilities.parser.DisguisePerm; import me.libraryaddict.disguise.utilities.parser.DisguisePerm;
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.plugin.messaging.PluginMessageListener;
import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -12,8 +20,52 @@ import java.util.Map;
/** /**
* Created by libraryaddict on 14/04/2020. * Created by libraryaddict on 14/04/2020.
*/ */
public class ModdedManager { public class ModdedManager implements PluginMessageListener {
@Getter
private static final HashMap<NamespacedKey, CustomEntity> entities = new HashMap<>(); private static final HashMap<NamespacedKey, CustomEntity> entities = new HashMap<>();
@Getter
private static byte[] fmlHandshake;
public ModdedManager(ArrayList<String> channels) {
if (getEntities().isEmpty()) {
return;
}
if (getEntities().values().stream().noneMatch(e -> e.getMod() != null)) {
return;
}
Bukkit.getMessenger().registerOutgoingPluginChannel(LibsDisguises.getInstance(), "fml:handshake");
Bukkit.getMessenger().registerIncomingPluginChannel(LibsDisguises.getInstance(), "fml:handshake", this);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(stream);
StreamSerializer s = StreamSerializer.getDefault();
try {
// Packet id 1
s.serializeVarInt(output, 1);
// We have no mods to declare
s.serializeVarInt(output, 0);
// We want to declare some channels
s.serializeVarInt(output, channels.size());
for (String channel : channels) {
s.serializeString(output, channel.substring(0, channel.indexOf("|")));
s.serializeString(output, channel.substring(channel.indexOf("|") + 1));
}
// We have no resources to declare
s.serializeVarInt(output, 0);
}
catch (IOException e) {
e.printStackTrace();
}
fmlHandshake = stream.toByteArray();
}
public static void registerCustomEntity(NamespacedKey name, CustomEntity entity, boolean register) { public static void registerCustomEntity(NamespacedKey name, CustomEntity entity, boolean register) {
if (entities.keySet().stream().anyMatch(n -> n.toString().equalsIgnoreCase(name.toString()))) { if (entities.keySet().stream().anyMatch(n -> n.toString().equalsIgnoreCase(name.toString()))) {
@ -68,4 +120,54 @@ public class ModdedManager {
return perms; return perms;
} }
@Override
public void onPluginMessageReceived(String channel, Player player, byte[] bytes) {
if (player.hasMetadata("forge_mods")) {
return;
}
DataInputStream stream = new DataInputStream(new ByteArrayInputStream(bytes));
try {
StreamSerializer s = StreamSerializer.getDefault();
int packetId = s.deserializeVarInt(stream);
if (packetId != 2) {
return;
}
int count = s.deserializeVarInt(stream);
ArrayList<String> mods = new ArrayList<>();
for (int i = 0; i < count; i++) {
mods.add(s.deserializeString(stream, 256));
}
player.setMetadata("forge_mods", new FixedMetadataValue(LibsDisguises.getInstance(), mods));
for (CustomEntity e : getEntities().values()) {
if (e.getMod() == null) {
continue;
}
if (mods.contains(e.getMod().toLowerCase())) {
continue;
}
// TODO Idk, something because they don't have a mod?
if (e.getRequired() == null) {
continue;
}
player.kickPlayer(e.getRequired());
break;
}
}
catch (IOException e) {
e.printStackTrace();
}
}
} }

View File

@ -306,7 +306,7 @@ public class PacketHandlerSpawn implements IPacketHandler {
PacketContainer spawnEntity; PacketContainer spawnEntity;
if (NmsVersion.v1_14.isSupported()) { if (NmsVersion.v1_14.isSupported()) {System.out.println("...");
Object entityType; Object entityType;
if (disguise.isCustomDisguise()) { if (disguise.isCustomDisguise()) {

View File

@ -134,8 +134,11 @@ public enum LibsMsg {
MADE_REF(ChatColor.RED + "Constructed a %s disguise! Your reference is %s"), MADE_REF(ChatColor.RED + "Constructed a %s disguise! Your reference is %s"),
MADE_REF_EXAMPLE(ChatColor.RED + "Example usage: /disguise %s"), MADE_REF_EXAMPLE(ChatColor.RED + "Example usage: /disguise %s"),
NO_CONSOLE(ChatColor.RED + "You may not use this command from the console!"), NO_CONSOLE(ChatColor.RED + "You may not use this command from the console!"),
NO_MODS(ChatColor.RED + "%s is not using any mods!"),
MODS_LIST(ChatColor.DARK_GREEN + "%s has the mods:" + ChatColor.AQUA + " %s"),
NO_PERM(ChatColor.RED + "You are forbidden to use this command."), NO_PERM(ChatColor.RED + "You are forbidden to use this command."),
NO_PERM_DISGUISE(ChatColor.RED + "You do not have permission for that disguise!"), NO_PERM_DISGUISE(ChatColor.RED + "You do not have permission for that disguise!"),
NO_MODS_LISTENING(ChatColor.RED + "This server is not listening for mods!"),
NO_PERMS_USE_OPTIONS(ChatColor.RED + NO_PERMS_USE_OPTIONS(ChatColor.RED +
"Ignored %s methods you do not have permission to use. Add 'show' to view unusable methods."), "Ignored %s methods you do not have permission to use. Add 'show' to view unusable methods."),
OWNED_BY(ChatColor.GOLD + "Plugin registered to '%%__USER__%%'!"), OWNED_BY(ChatColor.GOLD + "Plugin registered to '%%__USER__%%'!"),

View File

@ -53,6 +53,6 @@ Custom-Entities:
# Register: true # This means Lib's Disguises should register the EntityType in nms, not another plugin # Register: true # This means Lib's Disguises should register the EntityType in nms, not another plugin
# Type: LIVING # MISC, LIVING - What type of disguise type, doesn't support custom packets # Type: LIVING # MISC, LIVING - What type of disguise type, doesn't support custom packets
# Mod: LibAttacks # The mod they need installed # Mod: LibAttacks # The mod they need installed
# Version: '1.0,1.01,@2\.[0]+' # The version they need seperated by commas, the prefix @ means its regex # If exists, will prevent anyone without the mod from joining with this error
# If exists, will prevent anyone without the mod/version from joining with this error # Required: 'Install LibAttacks! Download it from our site!'
# Required: 'Install LibAttacks! Download it from our site!' # Channels: librarian:channel|1 # Sometimes a mod needs a channel enabled.. Seperate each channel with a comma

View File

@ -88,6 +88,8 @@ commands:
permissions: permissions:
libsdisguises.reload: libsdisguises.reload:
description: Allows the user to reload LibsDisguises. description: Allows the user to reload LibsDisguises.
libsdisguises.mods:
description: Allows the user to see mods in use.
libsdisguises.seethrough: libsdisguises.seethrough:
description: Allows player to see through disguises. description: Allows player to see through disguises.
default: false default: false