diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java
index 43a6a37..27b28dd 100644
--- a/src/de/steamwar/bungeecore/BungeeCore.java
+++ b/src/de/steamwar/bungeecore/BungeeCore.java
@@ -78,6 +78,7 @@ public class BungeeCore extends Plugin {
errorLogger = new ErrorLogger();
new ConnectionListener();
new Forge();
+ new Forge12();
new LabyMod();
new Badlion();
new ChatListener();
diff --git a/src/de/steamwar/bungeecore/Message.java b/src/de/steamwar/bungeecore/Message.java
index b9a6f58..f755cdf 100644
--- a/src/de/steamwar/bungeecore/Message.java
+++ b/src/de/steamwar/bungeecore/Message.java
@@ -44,24 +44,26 @@ public class Message {
};
public static TextComponent parseToComponent(String message, boolean prefixed, CommandSender sender, Object... params){
- return new TextComponent(TextComponent.fromLegacyText(parse(message, prefixed, sender, params)));
+ return new TextComponent(TextComponent.fromLegacyText(parse(message, prefixed, locale(sender), params)));
}
public static String parsePrefixed(String message, CommandSender sender, Object... params){
- return parse(message, true, sender, params);
+ return parse(message, true, locale(sender), params);
}
public static String parse(String message, CommandSender sender, Object... params){
- return parse(message, false, sender, params);
+ return parse(message, false, locale(sender), params);
}
- private static String parse(String message, boolean prefixed, CommandSender sender, Object... params){
- Locale locale = null;
- if(sender instanceof ProxiedPlayer)
- locale = ((ProxiedPlayer)sender).getLocale();
- if(locale == null)
- locale = Locale.getDefault();
+ public static String parse(String message, Locale locale, Object... params){
+ return parse(message, false, locale, params);
+ }
+ private static Locale locale(CommandSender sender) {
+ return sender instanceof ProxiedPlayer ? ((ProxiedPlayer)sender).getLocale() : Locale.getDefault();
+ }
+
+ private static String parse(String message, boolean prefixed, Locale locale, Object... params){
ResourceBundle resourceBundle = ResourceBundle.getBundle("de.steamwar.messages.BungeeCore", locale, CONTROL);
String pattern = "";
if(prefixed)
@@ -72,7 +74,7 @@ public class Message {
for (int i = 0; i < params.length; i++) {
if(params[i] instanceof Message) {
Message msg = (Message) params[i];
- params[i] = parse(msg.getMessage(), sender, msg.getParams());
+ params[i] = parse(msg.getMessage(), false, locale, msg.getParams());
} else if(params[i] instanceof Date) {
params[i] = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale).format((Date) params[i]);
}
@@ -120,7 +122,7 @@ public class Message {
public static void broadcast(String message, String onHover, ClickEvent onClick, Object... params){
for(ProxiedPlayer player : ProxyServer.getInstance().getPlayers())
- send(message, player, parse(onHover, false, player, params), onClick, params);
+ send(message, player, parse(onHover, player, params), onClick, params);
}
public static void broadcast(String message, Object... params){
diff --git a/src/de/steamwar/bungeecore/listeners/mods/FMLPing.java b/src/de/steamwar/bungeecore/listeners/mods/FMLPing.java
new file mode 100644
index 0000000..a8b5994
--- /dev/null
+++ b/src/de/steamwar/bungeecore/listeners/mods/FMLPing.java
@@ -0,0 +1,86 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+package de.steamwar.bungeecore.listeners.mods;
+
+import net.md_5.bungee.api.ServerPing;
+
+import java.util.*;
+
+public class FMLPing extends ServerPing {
+
+ private final ForgeData forgeData;
+
+ public FMLPing(ServerPing existing, int version) {
+ super(existing.getVersion(), existing.getPlayers(), existing.getDescriptionComponent(), existing.getFaviconObject());
+ forgeData = new ForgeData(version);
+ }
+
+ private static class ForgeData {
+ private final List channels = new ArrayList<>();
+ private final List mods = new ArrayList<>();
+ private final int fmlNetworkVersion = 2;
+
+ public ForgeData(int versionNumber) {
+ channels.add(new ForgeChannel("minecraft:unregister"));
+ channels.add(new ForgeChannel("minecraft:register"));
+ channels.add(new ForgeChannel("fml:handshake"));
+ mods.add(new ForgeMod("minecraft", ProtocolVersion.getVersion(versionNumber)));
+ mods.add(new ForgeMod("forge", "ANY"));
+ }
+
+ public final static class ProtocolVersion {
+
+ private static final HashMap versions;
+
+ static {
+ versions = new HashMap();
+ versions.put(757, "1.18");
+ versions.put(756, "1.17.1");
+ versions.put(754, "1.16.5");
+ versions.put(578, "1.15.2");
+ versions.put(498, "1.14.1");
+ versions.put(393, "1.13");
+ }
+
+ public static String getVersion(int version) {
+ return versions.get(version);
+ }
+ }
+
+ private static class ForgeChannel {
+ private final String res;
+ private final String version = "FML2";
+ private final boolean required = true;
+
+ private ForgeChannel(String res) {
+ this.res = res;
+ }
+ }
+
+ private static class ForgeMod {
+ private final String modId;
+ private final String modmarker;
+
+ private ForgeMod(String modId, String modmarker) {
+ this.modId = modId;
+ this.modmarker = modmarker;
+ }
+ }
+ }
+}
diff --git a/src/de/steamwar/bungeecore/listeners/mods/Forge.java b/src/de/steamwar/bungeecore/listeners/mods/Forge.java
index 905eecb..2a6a8ca 100644
--- a/src/de/steamwar/bungeecore/listeners/mods/Forge.java
+++ b/src/de/steamwar/bungeecore/listeners/mods/Forge.java
@@ -22,102 +22,112 @@ package de.steamwar.bungeecore.listeners.mods;
import de.steamwar.bungeecore.BungeeCore;
import de.steamwar.bungeecore.listeners.BasicListener;
import de.steamwar.bungeecore.sql.Mod;
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.UnpooledByteBufAllocator;
-import net.md_5.bungee.api.ProxyServer;
-import net.md_5.bungee.api.connection.Connection;
-import net.md_5.bungee.api.connection.ProxiedPlayer;
-import net.md_5.bungee.api.event.PluginMessageEvent;
-import net.md_5.bungee.api.event.PostLoginEvent;
+import net.md_5.bungee.api.connection.PendingConnection;
+import net.md_5.bungee.api.event.LoginEvent;
+import net.md_5.bungee.api.event.ProxyPingEvent;
+import net.md_5.bungee.connection.InitialHandler;
import net.md_5.bungee.event.EventHandler;
+import net.md_5.bungee.netty.ChannelWrapper;
+import net.md_5.bungee.netty.HandlerBoss;
+import net.md_5.bungee.netty.PacketHandler;
+import net.md_5.bungee.protocol.packet.LoginPayloadRequest;
+import net.md_5.bungee.protocol.packet.LoginPayloadResponse;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.logging.Level;
public class Forge extends BasicListener {
- private static final String FMLHS = "FML|HS";
- private static final String FMLHS13 = "fml:handshake";
- private static final byte[] REGISTER;
- private static final byte[] REGISTER13;
- private static final byte[] HELLO = new byte[]{0, 2, 0, 0, 0, 0};
- private static final Set unlocked = new HashSet<>();
+ private static final String WRAPPER = "fml:loginwrapper";
+ private static final Field initialHandlerCh;
static{
- ByteBuf buf = UnpooledByteBufAllocator.DEFAULT.directBuffer(7);
- buf.writeByte(6);
- buf.writeCharSequence(FMLHS, StandardCharsets.UTF_8);
- REGISTER = new byte[buf.readableBytes()];
- buf.readBytes(REGISTER);
-
- buf.clear();
- buf.writeByte(13);
- buf.writeCharSequence(FMLHS13, StandardCharsets.UTF_8);
- REGISTER13 = new byte[buf.readableBytes()];
- buf.readBytes(REGISTER13);
+ try {
+ initialHandlerCh = InitialHandler.class.getDeclaredField("ch");
+ } catch (NoSuchFieldException e) {
+ throw new SecurityException("Could not initialize Reflection", e);
+ }
+ initialHandlerCh.setAccessible(true);
}
@EventHandler
- public void onPostLogin(PostLoginEvent event) {
- ProxiedPlayer player = event.getPlayer();
+ public void onServerPing(ProxyPingEvent event) {
+ event.setResponse(new FMLPing(event.getResponse(), event.getConnection().getVersion()));
+ }
- synchronized (unlocked) {
- if(unlocked.contains(player.getUniqueId())){
- unlocked.remove(player.getUniqueId());
+ @EventHandler
+ public void onServerConnected(LoginEvent event){
+ if(event.getConnection().getVersion() < 340) return; //1.13+
+
+ //fml:handshake without mods, channels and registries
+ //for more information see https://wiki.vg/Minecraft_Forge_Handshake#FML2_protocol_.281.13_-_Current.29
+ event.getConnection().unsafe().sendPacket(new LoginPayloadRequest(1, WRAPPER, new byte[]{13,102,109,108,58,104,97,110,100,115,104,97,107,101,4,1,0,0,0}));
+
+ InitialHandler handler = (InitialHandler) event.getConnection();
+
+ ChannelWrapper wrapper;
+ try{
+ wrapper = (ChannelWrapper) initialHandlerCh.get(handler);
+ } catch (IllegalAccessException e) {
+ BungeeCore.get().getLogger().log(Level.SEVERE, "Could not get Channel", e);
+ return;
+ }
+
+ event.registerIntent(BungeeCore.get());
+ wrapper.getHandle().pipeline().get(HandlerBoss.class).setHandler(new CustomPacketHandler(event));
+ }
+
+ private static class CustomPacketHandler extends PacketHandler {
+ private final LoginEvent event;
+
+ public CustomPacketHandler(LoginEvent event) {
+ this.event = event;
+ }
+
+ @Override
+ public String toString() {
+ return "SteamWar Forge Handler";
+ }
+
+ @Override
+ public void handle(LoginPayloadResponse response){
+ byte[] data = response.getData();
+ if(data == null) {
+ event.completeIntent(BungeeCore.get());
return;
}
- }
- if(player.getPendingConnection().getVersion() > 340) {
- player.sendData("minecraft:register", REGISTER13); //1.13+
- player.sendData(FMLHS13, Forge.HELLO);
- }else{
- player.sendData("REGISTER", REGISTER); //1.12-
- player.sendData(FMLHS, Forge.HELLO);
- }
- }
+ //for more information see https://wiki.vg/Minecraft_Forge_Handshake#FML2_protocol_.281.13_-_Current.29
+ Utils.VarInt channelLength = Utils.readVarInt(data, 0);
+ int pos = channelLength.length;
+ assert new String(data, pos, channelLength.value).equals("fml:handshake");
- @EventHandler
- public void onPluginMessageEvent(PluginMessageEvent e){
- if(!e.getTag().equals(FMLHS) && !e.getTag().equals(FMLHS13))
- return;
+ Utils.VarInt length = Utils.readVarInt(data, pos);
+ pos += length.length;
+ assert channelLength.length + channelLength.value + length.length + length.value == data.length;
- e.setCancelled(true);
- byte[] data = e.getData();
+ Utils.VarInt packetId = Utils.readVarInt(data, pos);
+ pos += packetId.length;
+ assert packetId.value == 2;
- Connection sender = e.getSender();
- if(!(sender instanceof ProxiedPlayer))
- return;
- ProxiedPlayer p = (ProxiedPlayer) sender;
+ Utils.VarInt modCount = Utils.readVarInt(data, pos);
+ pos += modCount.length;
- if (data[0] == 2) {
- Utils.VarInt numMods = Utils.readVarInt(data, 1);
- List mods = new LinkedList<>();
+ List mods = new ArrayList<>();
+ for(int i = 0; i < modCount.value; i++) {
+ Utils.VarInt nameLength = Utils.readVarInt(data, pos);
+ pos += nameLength.length;
- int bytePos = 1 + numMods.length;
- for (int i = 0; i < numMods.value; i++) {
- byte[] name = Arrays.copyOfRange(data, bytePos + 1, bytePos + data[bytePos] + 1);
- bytePos += 1 + data[bytePos];
- //Version information is unused
- bytePos += 1 + data[bytePos];
-
- mods.add(Mod.get(new String(name), Mod.Platform.FORGE));
+ mods.add(Mod.get(new String(data, pos, nameLength.value), Mod.Platform.FORGE));
+ pos += nameLength.value;
}
- if (Utils.handleMods(p, mods)) {
- synchronized (unlocked) {
- unlocked.add(p.getUniqueId());
- }
- ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(),
- () -> p.disconnect(BungeeCore.stringToText("§7Deine installierten Mods wurden überprüft\n§aDu kannst nun §eSteam§8War §abetreten")),
- 2, TimeUnit.SECONDS);
- ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
- synchronized (unlocked) {
- unlocked.remove(p.getUniqueId());
- }
- }, 30, TimeUnit.SECONDS);
- }
+ PendingConnection connection = event.getConnection();
+ if(Utils.handleMods(connection.getUniqueId(), Locale.getDefault(), connection::disconnect, mods))
+ event.completeIntent(BungeeCore.get());
}
}
}
diff --git a/src/de/steamwar/bungeecore/listeners/mods/Forge12.java b/src/de/steamwar/bungeecore/listeners/mods/Forge12.java
new file mode 100644
index 0000000..eb463f4
--- /dev/null
+++ b/src/de/steamwar/bungeecore/listeners/mods/Forge12.java
@@ -0,0 +1,113 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2022 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+package de.steamwar.bungeecore.listeners.mods;
+
+import de.steamwar.bungeecore.BungeeCore;
+import de.steamwar.bungeecore.listeners.BasicListener;
+import de.steamwar.bungeecore.sql.Mod;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.UnpooledByteBufAllocator;
+import net.md_5.bungee.api.ProxyServer;
+import net.md_5.bungee.api.connection.Connection;
+import net.md_5.bungee.api.connection.ProxiedPlayer;
+import net.md_5.bungee.api.event.PluginMessageEvent;
+import net.md_5.bungee.api.event.PostLoginEvent;
+import net.md_5.bungee.event.EventHandler;
+
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+public class Forge12 extends BasicListener {
+ private static final String FMLHS = "FML|HS";
+ private static final byte[] REGISTER;
+ private static final byte[] HELLO = new byte[]{0, 2, 0, 0, 0, 0};
+
+ private static final Set unlocked = new HashSet<>();
+
+ static {
+ ByteBuf buf = UnpooledByteBufAllocator.DEFAULT.directBuffer(7);
+ buf.writeByte(6);
+ buf.writeCharSequence(FMLHS, StandardCharsets.UTF_8);
+ REGISTER = new byte[buf.readableBytes()];
+ buf.readBytes(REGISTER);
+ }
+
+
+ @EventHandler
+ public void onPostLogin(PostLoginEvent event) {
+ ProxiedPlayer player = event.getPlayer();
+
+ synchronized (unlocked) {
+ if(unlocked.contains(player.getUniqueId())){
+ unlocked.remove(player.getUniqueId());
+ return;
+ }
+ }
+
+ if(player.getPendingConnection().getVersion() <= 340) {
+ player.sendData("REGISTER", REGISTER); //1.12-
+ player.sendData(FMLHS, HELLO);
+ }
+ }
+
+ @EventHandler
+ public void onPluginMessageEvent(PluginMessageEvent e){
+ if(!e.getTag().equals(FMLHS))
+ return;
+
+ e.setCancelled(true);
+ byte[] data = e.getData();
+
+ Connection sender = e.getSender();
+ if(!(sender instanceof ProxiedPlayer))
+ return;
+ ProxiedPlayer p = (ProxiedPlayer) sender;
+
+ if (data[0] == 2) {
+ Utils.VarInt numMods = Utils.readVarInt(data, 1);
+ List mods = new LinkedList<>();
+
+ int bytePos = 1 + numMods.length;
+ for (int i = 0; i < numMods.value; i++) {
+ byte[] name = Arrays.copyOfRange(data, bytePos + 1, bytePos + data[bytePos] + 1);
+ bytePos += 1 + data[bytePos];
+ //Version information is unused
+ bytePos += 1 + data[bytePos];
+
+ mods.add(Mod.get(new String(name), Mod.Platform.FORGE));
+ }
+
+ if (Utils.handleMods(p, mods)) {
+ synchronized (unlocked) {
+ unlocked.add(p.getUniqueId());
+ }
+ ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(),
+ () -> p.disconnect(BungeeCore.stringToText("§7Deine installierten Mods wurden überprüft\n§aDu kannst nun §eSteam§8War §abetreten")),
+ 2, TimeUnit.SECONDS);
+ ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
+ synchronized (unlocked) {
+ unlocked.remove(p.getUniqueId());
+ }
+ }, 30, TimeUnit.SECONDS);
+ }
+ }
+ }
+}
diff --git a/src/de/steamwar/bungeecore/listeners/mods/ModLoaderBlocker.java b/src/de/steamwar/bungeecore/listeners/mods/ModLoaderBlocker.java
index 281830c..a4d54e6 100644
--- a/src/de/steamwar/bungeecore/listeners/mods/ModLoaderBlocker.java
+++ b/src/de/steamwar/bungeecore/listeners/mods/ModLoaderBlocker.java
@@ -56,26 +56,6 @@ public class ModLoaderBlocker extends BasicListener {
}
}
- @EventHandler
- public void onPluginMessage(PluginMessageEvent e){
- if(!e.getTag().equals("minecraft:register"))
- return;
-
- Connection sender = e.getSender();
- if(!(sender instanceof ProxiedPlayer))
- return;
- ProxiedPlayer p = (ProxiedPlayer) sender;
-
- if(p.getPendingConnection().getVersion() <= 340)
- return;
-
- String registered = new String(e.getData(), StandardCharsets.UTF_8);
- if(registered.contains("fml:loginwrapper") || registered.contains("fml:handshake") || registered.contains("fml:play")){
- Storage.fabricPlayers.add(p);
- Message.send("MODLOADER_INSTALLED", p, "Forge");
- }
- }
-
@EventHandler
public void onDisconnect(PlayerDisconnectEvent e){
Storage.fabricPlayers.remove(e.getPlayer());
diff --git a/src/de/steamwar/bungeecore/listeners/mods/Utils.java b/src/de/steamwar/bungeecore/listeners/mods/Utils.java
index 9ed160a..417f846 100644
--- a/src/de/steamwar/bungeecore/listeners/mods/Utils.java
+++ b/src/de/steamwar/bungeecore/listeners/mods/Utils.java
@@ -25,6 +25,8 @@ import de.steamwar.bungeecore.sql.Mod;
import de.steamwar.bungeecore.sql.Mod.ModType;
import de.steamwar.bungeecore.sql.Punishment;
import de.steamwar.bungeecore.sql.SteamwarUser;
+import net.md_5.bungee.api.chat.BaseComponent;
+import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.sql.Timestamp;
@@ -32,6 +34,9 @@ import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Iterator;
import java.util.List;
+import java.util.Locale;
+import java.util.UUID;
+import java.util.function.Consumer;
import java.util.logging.Level;
class Utils {
@@ -55,9 +60,13 @@ class Utils {
return new VarInt(numRead, result);
}
- static boolean handleMods(ProxiedPlayer player, List mods){
- SteamwarUser user = SteamwarUser.get(player.getUniqueId());
- boolean privileged = player.hasPermission("bungeecore.youtubermods");
+ static boolean handleMods(ProxiedPlayer player, List mods) {
+ return handleMods(player.getUniqueId(), player.getLocale(), player::disconnect, mods);
+ }
+
+ static boolean handleMods(UUID uuid, Locale locale, Consumer disconnect, List mods){
+ SteamwarUser user = SteamwarUser.get(uuid);
+ boolean privileged = user.getUserGroup().privilegedMods();
ModType max = ModType.YELLOW;
Iterator it = mods.iterator();
@@ -74,9 +83,9 @@ class Utils {
if(mods.size() == 1){
if(max == ModType.YELLOW)
- player.disconnect(BungeeCore.stringToText(Message.parse("MOD_YELLOW_SING", player, mods.get(0).getModName())));
+ disconnect.accept(TextComponent.fromLegacyText(Message.parse("MOD_YELLOW_SING", locale, mods.get(0).getModName())));
else{
- user.punish(Punishment.PunishmentType.Ban, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), Message.parse("MOD_RED_SING", player, mods.get(0).getModName()), 0, false);
+ user.punish(Punishment.PunishmentType.Ban, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), Message.parse("MOD_RED_SING", locale, mods.get(0).getModName()), 0, false);
BungeeCore.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen des Mods " + mods.get(0).getModName() + " gebannt.");
}
}else{
@@ -84,10 +93,10 @@ class Utils {
mods.forEach(mod -> sb.append(mod.getModName()).append('\n'));
if(max == ModType.YELLOW)
- player.disconnect(BungeeCore.stringToText(Message.parse("MOD_YELLOW_PLUR", player, sb.toString())));
+ disconnect.accept(TextComponent.fromLegacyText(Message.parse("MOD_YELLOW_PLUR", locale, sb.toString())));
else{
- user.punish(Punishment.PunishmentType.Ban, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), Message.parse("MOD_RED_PLUR", player, sb.toString()), 0, false);
- BungeeCore.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen der Mods " + sb.toString() + " gebannt.");
+ user.punish(Punishment.PunishmentType.Ban, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), Message.parse("MOD_RED_PLUR", locale, sb.toString()), 0, false);
+ BungeeCore.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen der Mods " + sb + " gebannt.");
}
}
diff --git a/src/de/steamwar/bungeecore/sql/UserGroup.java b/src/de/steamwar/bungeecore/sql/UserGroup.java
index 73273dc..e6c30f9 100644
--- a/src/de/steamwar/bungeecore/sql/UserGroup.java
+++ b/src/de/steamwar/bungeecore/sql/UserGroup.java
@@ -24,26 +24,28 @@ import java.util.stream.Collectors;
public enum UserGroup {
- Admin("§4", "§e", true, true, true),
- Developer("§3", "§f", true, true, true),
- Moderator("§c", "§f", true, true, true),
- Supporter("§9", "§f", false, true, true),
- Builder("§2", "§f", false, true, false),
- YouTuber("§5", "§f", false, false, false),
- Member("§7", "§7", false, false, false);
+ Admin("§4", "§e", true, true, true, true),
+ Developer("§3", "§f", true, true, true, true),
+ Moderator("§c", "§f", true, true, true, true),
+ Supporter("§9", "§f", false, true, true, true),
+ Builder("§2", "§f", false, true, false, true),
+ YouTuber("§5", "§f", false, false, false, true),
+ Member("§7", "§7", false, false, false, false);
private final String colorCode;
private final String chatColorCode;
private final boolean adminGroup;
private final boolean teamGroup;
private final boolean checkSchematics;
+ private final boolean privilegedMods;
- UserGroup(String colorCode, String chatColorCode, boolean adminGroup, boolean teamGroup, boolean checkSchematics) {
+ UserGroup(String colorCode, String chatColorCode, boolean adminGroup, boolean teamGroup, boolean checkSchematics, boolean privilegedMods) {
this.colorCode = colorCode;
this.chatColorCode = chatColorCode;
this.adminGroup = adminGroup;
this.teamGroup = teamGroup;
this.checkSchematics = checkSchematics;
+ this.privilegedMods = privilegedMods;
}
public String getColorCode() {
@@ -62,6 +64,10 @@ public enum UserGroup {
return checkSchematics;
}
+ public boolean privilegedMods() {
+ return privilegedMods;
+ }
+
public String getChatColorCode() {
return chatColorCode;
}