geforkt von SteamWar/BungeeCore
WIP Velocity: Mods, Listeners
Signed-off-by: Lixfel <git-5w3l@lixfel.de>
Dieser Commit ist enthalten in:
Ursprung
a1d8ec806f
Commit
f6f568ee40
14
build.gradle
14
build.gradle
@ -94,20 +94,12 @@ dependencies {
|
|||||||
annotationProcessor 'org.projectlombok:lombok:1.18.22'
|
annotationProcessor 'org.projectlombok:lombok:1.18.22'
|
||||||
testAnnotationProcessor 'org.projectlombok:lombok:1.18.22'
|
testAnnotationProcessor 'org.projectlombok:lombok:1.18.22'
|
||||||
|
|
||||||
compileOnly 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT'
|
|
||||||
annotationProcessor 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT'
|
annotationProcessor 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT'
|
||||||
// TODO: Add velocity-proxy as a compileOnly dependency to steamwar-maven
|
compileOnly 'de.steamwar:velocity:RELEASE'
|
||||||
//compileOnly 'com.velocitypowered:velocity-proxy:3.3.0-SNAPSHOT'
|
//compileOnly 'de.steamwar:persistentbungeecore:RELEASE'
|
||||||
|
|
||||||
//implementation 'org.reflections:reflections:0.10.2'
|
|
||||||
|
|
||||||
compileOnly 'io.netty:netty-buffer:4.1.106.Final'
|
|
||||||
compileOnly 'io.netty:netty-transport:4.1.106.Final'
|
|
||||||
|
|
||||||
implementation 'org.yaml:snakeyaml:2.2'
|
|
||||||
|
|
||||||
// TODO: Monorepo?
|
// TODO: Monorepo?
|
||||||
compileOnly files('persistentvelocitycore.jar')
|
compileOnly files('persistentvelocitycore.jar')
|
||||||
|
|
||||||
implementation("net.dv8tion:JDA:4.4.0_352") {
|
implementation("net.dv8tion:JDA:4.4.0_352") {
|
||||||
exclude module: 'opus-java'
|
exclude module: 'opus-java'
|
||||||
}
|
}
|
||||||
|
96
src/de/steamwar/bungeecore/Reflection.java
Normale Datei
96
src/de/steamwar/bungeecore/Reflection.java
Normale Datei
@ -0,0 +1,96 @@
|
|||||||
|
package de.steamwar.bungeecore;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
|
import java.lang.reflect.*;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class Reflection {
|
||||||
|
|
||||||
|
public interface ConstructorInvoker {
|
||||||
|
Object invoke(Object... arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface MethodInvoker {
|
||||||
|
Object invoke(Object target, Object... arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class Field<C, T> {
|
||||||
|
private final java.lang.reflect.Field f;
|
||||||
|
|
||||||
|
public T get(C target) {
|
||||||
|
try {
|
||||||
|
return (T) f.get(target);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new IllegalArgumentException("Cannot access reflection.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(C target, T value) {
|
||||||
|
try {
|
||||||
|
f.set(target, value);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new IllegalArgumentException("Cannot access reflection.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <C, T> Field<C, T> getField(Class<C> target, String name) {
|
||||||
|
try {
|
||||||
|
java.lang.reflect.Field field = target.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return new Field<>(field);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
throw new IllegalArgumentException("Cannot find field with name " + name, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MethodInvoker getMethod(Class<?> clazz, String methodName, Class<?>... params) {
|
||||||
|
return getTypedMethod(clazz, methodName, null, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MethodInvoker getTypedMethod(Class<?> clazz, String methodName, Class<?> returnType, Class<?>... params) {
|
||||||
|
for (final Method method : clazz.getDeclaredMethods()) {
|
||||||
|
if ((methodName == null || method.getName().equals(methodName))
|
||||||
|
&& (returnType == null || method.getReturnType().equals(returnType))
|
||||||
|
&& Arrays.equals(method.getParameterTypes(), params)) {
|
||||||
|
method.setAccessible(true);
|
||||||
|
|
||||||
|
return (target, arguments) -> {
|
||||||
|
try {
|
||||||
|
return method.invoke(target, arguments);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException("Cannot invoke method " + method, e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search in every superclass
|
||||||
|
if (clazz.getSuperclass() != null)
|
||||||
|
return getTypedMethod(clazz.getSuperclass(), methodName, returnType, params);
|
||||||
|
|
||||||
|
throw new IllegalStateException(String.format("Unable to find method %s (%s).", methodName, Arrays.asList(params)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConstructorInvoker getConstructor(Class<?> clazz, Class<?>... params) {
|
||||||
|
for (final Constructor<?> constructor : clazz.getDeclaredConstructors()) {
|
||||||
|
if (Arrays.equals(constructor.getParameterTypes(), params)) {
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
|
||||||
|
return arguments -> {
|
||||||
|
try {
|
||||||
|
return constructor.newInstance(arguments);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException("Cannot invoke constructor " + constructor, e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalStateException(String.format("Unable to find constructor for %s (%s).", clazz, Arrays.asList(params)));
|
||||||
|
}
|
||||||
|
}
|
@ -127,9 +127,9 @@ public class VelocityCore {
|
|||||||
|
|
||||||
initStaticServers();
|
initStaticServers();
|
||||||
PollSystem.init();
|
PollSystem.init();
|
||||||
|
ServerListPing.init();
|
||||||
|
|
||||||
new Hostname();
|
new Hostname();
|
||||||
new ServerListPing();
|
|
||||||
new PluginMessage();
|
new PluginMessage();
|
||||||
new Schematica();
|
new Schematica();
|
||||||
new Badlion();
|
new Badlion();
|
||||||
|
@ -20,14 +20,14 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.discord.DiscordBot;
|
import de.steamwar.bungeecore.discord.DiscordBot;
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
|
|
||||||
public class AlertCommand extends SWCommand {
|
public class AlertCommand extends SWCommand {
|
||||||
|
|
||||||
public AlertCommand() {
|
public AlertCommand() {
|
||||||
super("alert", ConnectionListener.ALERT_PERMISSION, "broadcast", "bbc");
|
super("alert", UserPerm.MODERATION, "broadcast", "bbc");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(description = "USAGE_ALERT")
|
@Register(description = "USAGE_ALERT")
|
||||||
|
@ -46,7 +46,7 @@ public class BauCommand extends SWCommand {
|
|||||||
private final HelpCommand command;
|
private final HelpCommand command;
|
||||||
|
|
||||||
public BauCommand(HelpCommand command) {
|
public BauCommand(HelpCommand command) {
|
||||||
super("bau", null, "b", "build", "gs");
|
super("bau", "b", "build", "gs");
|
||||||
this.command = command;
|
this.command = command;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ import de.steamwar.messages.Chatter;
|
|||||||
|
|
||||||
public class BugCommand extends SWCommand {
|
public class BugCommand extends SWCommand {
|
||||||
public BugCommand() {
|
public BugCommand() {
|
||||||
super("bug", null);
|
super("bug");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -4,12 +4,12 @@ import de.steamwar.bungeecore.ArenaMode;
|
|||||||
import de.steamwar.bungeecore.ServerStarter;
|
import de.steamwar.bungeecore.ServerStarter;
|
||||||
import de.steamwar.bungeecore.ServerVersion;
|
import de.steamwar.bungeecore.ServerVersion;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.command.PreviousArguments;
|
import de.steamwar.command.PreviousArguments;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.command.TypeMapper;
|
import de.steamwar.command.TypeMapper;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
import de.steamwar.messages.PlayerChatter;
|
import de.steamwar.messages.PlayerChatter;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -22,7 +22,7 @@ import java.util.stream.Collectors;
|
|||||||
public class BuilderCloudCommand extends SWCommand {
|
public class BuilderCloudCommand extends SWCommand {
|
||||||
|
|
||||||
public BuilderCloudCommand() {
|
public BuilderCloudCommand() {
|
||||||
super("buildercloud", ConnectionListener.BUILDERCLOUD_PERMISSION, "builder");
|
super("buildercloud", UserPerm.BUILD, "builder");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(value = "create", description = "BUILDERCLOUD_CREATE_USAGE")
|
@Register(value = "create", description = "BUILDERCLOUD_CREATE_USAGE")
|
||||||
|
@ -25,7 +25,6 @@ import de.steamwar.bungeecore.Bauserver;
|
|||||||
import de.steamwar.bungeecore.ServerStarter;
|
import de.steamwar.bungeecore.ServerStarter;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.discord.util.DiscordAlert;
|
import de.steamwar.bungeecore.discord.util.DiscordAlert;
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
import de.steamwar.messages.Message;
|
import de.steamwar.messages.Message;
|
||||||
@ -67,7 +66,7 @@ public class CheckCommand extends SWCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CheckCommand() {
|
public CheckCommand() {
|
||||||
super("check", ConnectionListener.CHECK_PERMISSION);
|
super("check", UserPerm.CHECK);
|
||||||
|
|
||||||
VelocityCore.schedule(() -> sendReminder(Chatter.serverteam())).repeat(10, TimeUnit.MINUTES).schedule();
|
VelocityCore.schedule(() -> sendReminder(Chatter.serverteam())).repeat(10, TimeUnit.MINUTES).schedule();
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,12 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
import de.steamwar.sql.Event;
|
import de.steamwar.sql.Event;
|
||||||
import de.steamwar.sql.EventFight;
|
import de.steamwar.sql.EventFight;
|
||||||
import de.steamwar.sql.Team;
|
import de.steamwar.sql.Team;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -34,7 +34,7 @@ import java.util.ListIterator;
|
|||||||
public class EventRescheduleCommand extends SWCommand {
|
public class EventRescheduleCommand extends SWCommand {
|
||||||
|
|
||||||
public EventRescheduleCommand() {
|
public EventRescheduleCommand() {
|
||||||
super("eventreschedule", ConnectionListener.EVENTRELOAD_PERMISSION);
|
super("eventreschedule", UserPerm.MODERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -19,14 +19,14 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
import de.steamwar.sql.EventFight;
|
import de.steamwar.sql.EventFight;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
|
|
||||||
public class EventreloadCommand extends SWCommand {
|
public class EventreloadCommand extends SWCommand {
|
||||||
public EventreloadCommand() {
|
public EventreloadCommand() {
|
||||||
super("eventreload", ConnectionListener.EVENTRELOAD_PERMISSION);
|
super("eventreload", UserPerm.MODERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -36,7 +36,7 @@ import net.kyori.adventure.text.format.TextDecoration;
|
|||||||
public class FightCommand extends SWCommand {
|
public class FightCommand extends SWCommand {
|
||||||
|
|
||||||
public FightCommand() {
|
public FightCommand() {
|
||||||
super("fight", "", "f");
|
super("fight", "f");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void getModes(Chatter sender, String precommand, boolean historic){
|
private static void getModes(Chatter sender, String precommand, boolean historic){
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
import de.steamwar.messages.PlayerChatter;
|
import de.steamwar.messages.PlayerChatter;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
import de.steamwar.sql.internal.Statement;
|
import de.steamwar.sql.internal.Statement;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@ -15,7 +15,7 @@ import java.util.zip.ZipOutputStream;
|
|||||||
public class GDPRQuery extends SWCommand {
|
public class GDPRQuery extends SWCommand {
|
||||||
|
|
||||||
public GDPRQuery() {
|
public GDPRQuery() {
|
||||||
super("gdprquery", ConnectionListener.SOFTRELOAD_PERMISSION);
|
super("gdprquery", UserPerm.ADMINISTRATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -29,7 +29,7 @@ import java.util.function.Function;
|
|||||||
public class HelpCommand extends SWCommand {
|
public class HelpCommand extends SWCommand {
|
||||||
|
|
||||||
public HelpCommand() {
|
public HelpCommand() {
|
||||||
super("help", "", "?");
|
super("help", "?");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -28,7 +28,7 @@ import net.kyori.adventure.text.event.ClickEvent;
|
|||||||
|
|
||||||
public class HistoricCommand extends SWCommand {
|
public class HistoricCommand extends SWCommand {
|
||||||
public HistoricCommand() {
|
public HistoricCommand() {
|
||||||
super("historic", null);
|
super("historic");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -27,7 +27,7 @@ import de.steamwar.sql.SteamwarUser;
|
|||||||
public class IgnoreCommand extends SWCommand {
|
public class IgnoreCommand extends SWCommand {
|
||||||
|
|
||||||
public IgnoreCommand() {
|
public IgnoreCommand() {
|
||||||
super("ignore", null);
|
super("ignore");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(description = "USAGE_IGNORE")
|
@Register(description = "USAGE_IGNORE")
|
||||||
|
@ -19,16 +19,16 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
import de.steamwar.messages.PlayerChatter;
|
import de.steamwar.messages.PlayerChatter;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
import net.kyori.adventure.text.event.ClickEvent;
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
|
|
||||||
public class JoinmeCommand extends SWCommand {
|
public class JoinmeCommand extends SWCommand {
|
||||||
|
|
||||||
public JoinmeCommand() {
|
public JoinmeCommand() {
|
||||||
super("joinme", ConnectionListener.TEAMCHAT_PERMISSION);
|
super("joinme", UserPerm.TEAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -20,14 +20,14 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
|
|
||||||
public class KickCommand extends SWCommand {
|
public class KickCommand extends SWCommand {
|
||||||
|
|
||||||
public KickCommand() {
|
public KickCommand() {
|
||||||
super("kick", ConnectionListener.KICK_PERMISSION);
|
super("kick", UserPerm.MODERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(description = "KICK_USAGE")
|
@Register(description = "KICK_USAGE")
|
||||||
|
@ -35,7 +35,7 @@ import java.util.stream.Collectors;
|
|||||||
public class ListCommand extends SWCommand {
|
public class ListCommand extends SWCommand {
|
||||||
|
|
||||||
public ListCommand() {
|
public ListCommand() {
|
||||||
super("list", "");
|
super("list");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized TreeMap<String, List<Player>> getCustomTablist(){
|
public static synchronized TreeMap<String, List<Player>> getCustomTablist(){
|
||||||
|
@ -26,7 +26,7 @@ import de.steamwar.messages.PlayerChatter;
|
|||||||
public class LocalCommand extends SWCommand {
|
public class LocalCommand extends SWCommand {
|
||||||
|
|
||||||
public LocalCommand() {
|
public LocalCommand() {
|
||||||
super("local", null, "bc", "bauchat");
|
super("local", "bc", "bauchat");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -19,16 +19,16 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.messages.Message;
|
|
||||||
import de.steamwar.bungeecore.inventory.SWInventory;
|
import de.steamwar.bungeecore.inventory.SWInventory;
|
||||||
import de.steamwar.bungeecore.inventory.SWItem;
|
import de.steamwar.bungeecore.inventory.SWItem;
|
||||||
import de.steamwar.bungeecore.inventory.SWListInv;
|
import de.steamwar.bungeecore.inventory.SWListInv;
|
||||||
import de.steamwar.bungeecore.inventory.SWStreamInv;
|
import de.steamwar.bungeecore.inventory.SWStreamInv;
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
|
import de.steamwar.messages.Message;
|
||||||
import de.steamwar.messages.PlayerChatter;
|
import de.steamwar.messages.PlayerChatter;
|
||||||
import de.steamwar.sql.Mod;
|
import de.steamwar.sql.Mod;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -39,7 +39,7 @@ import java.util.stream.Collectors;
|
|||||||
public class ModCommand extends SWCommand {
|
public class ModCommand extends SWCommand {
|
||||||
|
|
||||||
public ModCommand() {
|
public ModCommand() {
|
||||||
super("mod", ConnectionListener.MOD_PERMISSION, "mods");
|
super("mod", UserPerm.MODERATION, "mods");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Map<UUID, Mod.ModType> playerFilterType = new HashMap<>();
|
public static final Map<UUID, Mod.ModType> playerFilterType = new HashMap<>();
|
||||||
|
@ -32,7 +32,7 @@ import static de.steamwar.bungeecore.Storage.lastChats;
|
|||||||
public class MsgCommand extends SWCommand {
|
public class MsgCommand extends SWCommand {
|
||||||
|
|
||||||
public MsgCommand() {
|
public MsgCommand() {
|
||||||
super("msg", "", "w", "tell");
|
super("msg", "w", "tell");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(description = "MSG_USAGE")
|
@Register(description = "MSG_USAGE")
|
||||||
|
@ -19,19 +19,19 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.bungeecore.listeners.PollSystem;
|
import de.steamwar.bungeecore.listeners.PollSystem;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.command.TypeValidator;
|
import de.steamwar.command.TypeValidator;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
import de.steamwar.sql.PollAnswer;
|
import de.steamwar.sql.PollAnswer;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class PollresultCommand extends SWCommand {
|
public class PollresultCommand extends SWCommand {
|
||||||
|
|
||||||
public PollresultCommand() {
|
public PollresultCommand() {
|
||||||
super("pollresult", ConnectionListener.POLLRESULT_PERMISSION);
|
super("pollresult", UserPerm.MODERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -22,13 +22,12 @@ package de.steamwar.bungeecore.commands;
|
|||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.messages.Message;
|
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.bungeecore.listeners.IPSanitizer;
|
import de.steamwar.bungeecore.listeners.IPSanitizer;
|
||||||
import de.steamwar.command.PreviousArguments;
|
import de.steamwar.command.PreviousArguments;
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.command.TypeMapper;
|
import de.steamwar.command.TypeMapper;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
|
import de.steamwar.messages.Message;
|
||||||
import de.steamwar.sql.BannedUserIPs;
|
import de.steamwar.sql.BannedUserIPs;
|
||||||
import de.steamwar.sql.Punishment;
|
import de.steamwar.sql.Punishment;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
@ -180,7 +179,7 @@ public class PunishmentCommand {
|
|||||||
private final Punishment.PunishmentType punishmentType;
|
private final Punishment.PunishmentType punishmentType;
|
||||||
|
|
||||||
private PunishCommand(String command, Punishment.PunishmentType punishmentType) {
|
private PunishCommand(String command, Punishment.PunishmentType punishmentType) {
|
||||||
super(command, ConnectionListener.BAN_PERMISSION);
|
super(command, UserPerm.TEAM);
|
||||||
this.command = command;
|
this.command = command;
|
||||||
this.punishmentType = punishmentType;
|
this.punishmentType = punishmentType;
|
||||||
}
|
}
|
||||||
@ -245,7 +244,7 @@ public class PunishmentCommand {
|
|||||||
private final Punishment.PunishmentType punishmentType;
|
private final Punishment.PunishmentType punishmentType;
|
||||||
|
|
||||||
private UnpunishCommand(String command, Punishment.PunishmentType punishmentType) {
|
private UnpunishCommand(String command, Punishment.PunishmentType punishmentType) {
|
||||||
super(command, ConnectionListener.BAN_PERMISSION);
|
super(command, UserPerm.TEAM);
|
||||||
this.command = command;
|
this.command = command;
|
||||||
this.punishmentType = punishmentType;
|
this.punishmentType = punishmentType;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ import static de.steamwar.bungeecore.Storage.lastChats;
|
|||||||
public class RCommand extends SWCommand {
|
public class RCommand extends SWCommand {
|
||||||
|
|
||||||
public RCommand() {
|
public RCommand() {
|
||||||
super("r", "", "reply");
|
super("r", "reply");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(description = "R_USAGE")
|
@Register(description = "R_USAGE")
|
||||||
|
@ -28,7 +28,7 @@ import java.util.Arrays;
|
|||||||
|
|
||||||
public class RulesCommand extends SWCommand {
|
public class RulesCommand extends SWCommand {
|
||||||
public RulesCommand() {
|
public RulesCommand() {
|
||||||
super("rules", null, "regeln");
|
super("rules", "regeln");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -20,14 +20,14 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.listeners.ChatListener;
|
import de.steamwar.bungeecore.listeners.ChatListener;
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
|
|
||||||
public class ServerTeamchatCommand extends SWCommand {
|
public class ServerTeamchatCommand extends SWCommand {
|
||||||
|
|
||||||
public ServerTeamchatCommand() {
|
public ServerTeamchatCommand() {
|
||||||
super("stc", ConnectionListener.TEAMCHAT_PERMISSION,"serverteamchat");
|
super("stc", UserPerm.TEAM, "serverteamchat");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(description = "STC_USAGE")
|
@Register(description = "STC_USAGE")
|
||||||
|
@ -29,7 +29,7 @@ import java.util.Objects;
|
|||||||
public class SetLocaleCommand extends SWCommand {
|
public class SetLocaleCommand extends SWCommand {
|
||||||
|
|
||||||
public SetLocaleCommand() {
|
public SetLocaleCommand() {
|
||||||
super("setlocale", null, "setlanguage");
|
super("setlocale", "setlanguage");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
package de.steamwar.bungeecore.commands;
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.Node;
|
import de.steamwar.bungeecore.Node;
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
@ -32,7 +32,7 @@ import java.util.Map;
|
|||||||
public class StatCommand extends SWCommand {
|
public class StatCommand extends SWCommand {
|
||||||
|
|
||||||
public StatCommand() {
|
public StatCommand() {
|
||||||
super("stat", ConnectionListener.SOFTRELOAD_PERMISSION, "stats");
|
super("stat", UserPerm.ADMINISTRATION, "stats");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -28,7 +28,7 @@ import de.steamwar.sql.SteamwarUser;
|
|||||||
public class TeamchatCommand extends SWCommand {
|
public class TeamchatCommand extends SWCommand {
|
||||||
|
|
||||||
public TeamchatCommand() {
|
public TeamchatCommand() {
|
||||||
super("tc", "","teamchat");
|
super("tc", "teamchat");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register(description = "TC_USAGE")
|
@Register(description = "TC_USAGE")
|
||||||
|
@ -40,7 +40,7 @@ import java.util.List;
|
|||||||
public class TpCommand extends SWCommand {
|
public class TpCommand extends SWCommand {
|
||||||
|
|
||||||
public TpCommand(){
|
public TpCommand(){
|
||||||
super("join", null, "tp", "teleport");
|
super("join", "tp", "teleport");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -42,7 +42,7 @@ import java.util.stream.Collectors;
|
|||||||
public class TutorialCommand extends SWCommand {
|
public class TutorialCommand extends SWCommand {
|
||||||
|
|
||||||
public TutorialCommand() {
|
public TutorialCommand() {
|
||||||
super("tutorial", null);
|
super("tutorial");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Register
|
@Register
|
||||||
|
@ -29,7 +29,7 @@ import java.io.InputStreamReader;
|
|||||||
public class WebpasswordCommand extends SWCommand {
|
public class WebpasswordCommand extends SWCommand {
|
||||||
|
|
||||||
public WebpasswordCommand() {
|
public WebpasswordCommand() {
|
||||||
super("webpassword", null, "webpw", "web");
|
super("webpassword", "webpw", "web");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@ package de.steamwar.bungeecore.discord.listeners;
|
|||||||
import de.steamwar.bungeecore.discord.DiscordBot;
|
import de.steamwar.bungeecore.discord.DiscordBot;
|
||||||
import de.steamwar.bungeecore.discord.channels.DiscordChannel;
|
import de.steamwar.bungeecore.discord.channels.DiscordChannel;
|
||||||
import de.steamwar.bungeecore.discord.channels.InteractionReply;
|
import de.steamwar.bungeecore.discord.channels.InteractionReply;
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.command.SWCommand;
|
import de.steamwar.command.SWCommand;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.dv8tion.jda.api.entities.ChannelType;
|
import net.dv8tion.jda.api.entities.ChannelType;
|
||||||
import net.dv8tion.jda.api.entities.MessageChannel;
|
import net.dv8tion.jda.api.entities.MessageChannel;
|
||||||
@ -33,7 +33,6 @@ import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
|||||||
import net.dv8tion.jda.api.interactions.InteractionType;
|
import net.dv8tion.jda.api.interactions.InteractionType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -73,8 +72,8 @@ public class ChannelListener extends ListenerAdapter {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
SWCommand command = DiscordBot.getCommands().get(event.getName());
|
SWCommand command = DiscordBot.getCommands().get(event.getName());
|
||||||
String permission = command.getPermission();
|
UserPerm permission = command.getPermission();
|
||||||
if(permission != null && sender.user().perms().stream().noneMatch(perm -> Arrays.asList(ConnectionListener.getCommandPermissions().getOrDefault(perm, new String[0])).contains(permission)))
|
if(permission != null && !sender.user().perms().contains(permission))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
command.execute(sender, event.getOption(DiscordBot.ARGUMENT_NAME).getAsString().split(" "));
|
command.execute(sender, event.getOption(DiscordBot.ARGUMENT_NAME).getAsString().split(" "));
|
||||||
|
@ -24,10 +24,8 @@ import de.steamwar.messages.PlayerChatter;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.md_5.bungee.BungeeCord;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.List;
|
||||||
|
|
||||||
public class SWListInv<T> extends SWInventory {
|
public class SWListInv<T> extends SWInventory {
|
||||||
@Setter
|
@Setter
|
||||||
@ -81,28 +79,6 @@ public class SWListInv<T> extends SWInventory {
|
|||||||
void clicked(InvCallback.ClickType click, T element);
|
void clicked(InvCallback.ClickType click, T element);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<SWListEntry<UUID>> createPlayerList(UUID without){
|
|
||||||
List<SWListEntry<UUID>> onlinePlayers = new ArrayList<>();
|
|
||||||
for(ProxiedPlayer player : BungeeCord.getInstance().getPlayer(without).getServer().getInfo().getPlayers()){
|
|
||||||
if(without != null && player.getUniqueId().equals(without))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
onlinePlayers.add(new SWListEntry<>(SWItem.getSkull(player.getName()), player.getUniqueId()));
|
|
||||||
}
|
|
||||||
return onlinePlayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<SWListEntry<UUID>> createGlobalPlayerList(UUID without){
|
|
||||||
List<SWListEntry<UUID>> onlinePlayers = new ArrayList<>();
|
|
||||||
for(ProxiedPlayer player : BungeeCord.getInstance().getPlayers()){
|
|
||||||
if(without != null && player.getUniqueId().equals(without))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
onlinePlayers.add(new SWListEntry<>(SWItem.getSkull(player.getName()), player.getUniqueId()));
|
|
||||||
}
|
|
||||||
return onlinePlayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public static class SWListEntry<T> {
|
public static class SWListEntry<T> {
|
||||||
|
@ -19,7 +19,9 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.connection.LoginEvent;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import de.steamwar.bungeecore.commands.PunishmentCommand;
|
import de.steamwar.bungeecore.commands.PunishmentCommand;
|
||||||
import de.steamwar.bungeecore.commands.WebpasswordCommand;
|
import de.steamwar.bungeecore.commands.WebpasswordCommand;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
@ -27,11 +29,7 @@ import de.steamwar.messages.Message;
|
|||||||
import de.steamwar.sql.BannedUserIPs;
|
import de.steamwar.sql.BannedUserIPs;
|
||||||
import de.steamwar.sql.Punishment;
|
import de.steamwar.sql.Punishment;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
|
||||||
import net.md_5.bungee.api.connection.PendingConnection;
|
|
||||||
import net.md_5.bungee.api.event.LoginEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
@ -41,18 +39,14 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
public class BanListener extends BasicListener {
|
public class BanListener extends BasicListener {
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onLogin(LoginEvent event) {
|
public void onLogin(LoginEvent event) {
|
||||||
event.registerIntent(VelocityCore.get());
|
Player player = event.getPlayer();
|
||||||
ProxyServer.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> {
|
SteamwarUser user = SteamwarUser.getOrCreate(player.getUniqueId(), player.getUsername(), ConnectionListener::newPlayer, WebpasswordCommand::changeUsername);
|
||||||
PendingConnection connection = event.getConnection();
|
String ip = IPSanitizer.getTrueAddress(player).getHostAddress();
|
||||||
SteamwarUser user = SteamwarUser.getOrCreate(connection.getUniqueId(), connection.getName(), ConnectionListener::newPlayer, WebpasswordCommand::changeUsername);
|
|
||||||
String ip = IPSanitizer.getTrueAddress(connection).getHostAddress();
|
|
||||||
if (user.isPunished(Punishment.PunishmentType.Ban)) {
|
if (user.isPunished(Punishment.PunishmentType.Ban)) {
|
||||||
event.setCancelled(true);
|
|
||||||
BannedUserIPs.banIP(user.getId(), ip);
|
BannedUserIPs.banIP(user.getId(), ip);
|
||||||
Chatter.of(event).system(PunishmentCommand.punishmentMessage(user, Punishment.PunishmentType.Ban));
|
Chatter.of(event).system(PunishmentCommand.punishmentMessage(user, Punishment.PunishmentType.Ban));
|
||||||
event.completeIntent(VelocityCore.get());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +66,7 @@ public class BanListener extends BasicListener {
|
|||||||
highestBan = ban.getEndTime();
|
highestBan = ban.getEndTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClickEvent clickEvent = new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/ban " + user.getUserName() + " "
|
ClickEvent clickEvent = ClickEvent.runCommand("/ban " + user.getUserName() + " "
|
||||||
+ (perma ? "perma" : highestBan.toLocalDateTime().format(DateTimeFormatter.ofPattern("dd.MM.yyyy_HH:mm")))
|
+ (perma ? "perma" : highestBan.toLocalDateTime().format(DateTimeFormatter.ofPattern("dd.MM.yyyy_HH:mm")))
|
||||||
+ " Ban Evasion - Bannumgehung");
|
+ " Ban Evasion - Bannumgehung");
|
||||||
|
|
||||||
@ -88,8 +82,5 @@ public class BanListener extends BasicListener {
|
|||||||
}).collect(Collectors.joining(" ")))
|
}).collect(Collectors.joining(" ")))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
event.completeIntent(VelocityCore.get());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,10 @@
|
|||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.plugin.Listener;
|
|
||||||
|
|
||||||
public abstract class BasicListener implements Listener {
|
public abstract class BasicListener {
|
||||||
|
|
||||||
protected BasicListener() {
|
protected BasicListener() {
|
||||||
ProxyServer.getInstance().getPluginManager().registerListener(VelocityCore.get(), this);
|
VelocityCore.getProxy().getEventManager().register(VelocityCore.get(), this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.player.PlayerChatEvent;
|
||||||
|
import com.velocitypowered.api.event.player.TabCompleteEvent;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import de.steamwar.bungeecore.ArenaMode;
|
import de.steamwar.bungeecore.ArenaMode;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.Servertype;
|
import de.steamwar.bungeecore.Servertype;
|
||||||
@ -33,13 +37,6 @@ import de.steamwar.messages.Message;
|
|||||||
import de.steamwar.messages.PlayerChatter;
|
import de.steamwar.messages.PlayerChatter;
|
||||||
import de.steamwar.network.packets.server.PingPacket;
|
import de.steamwar.network.packets.server.PingPacket;
|
||||||
import de.steamwar.sql.*;
|
import de.steamwar.sql.*;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.ChatEvent;
|
|
||||||
import net.md_5.bungee.api.event.TabCompleteResponseEvent;
|
|
||||||
import net.md_5.bungee.api.scheduler.TaskScheduler;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -51,14 +48,12 @@ public class ChatListener extends BasicListener {
|
|||||||
|
|
||||||
private static final List<String> rankedModes = ArenaMode.getAllModes().stream().filter(ArenaMode::isRanked).map(ArenaMode::getSchemType).collect(Collectors.toList());
|
private static final List<String> rankedModes = ArenaMode.getAllModes().stream().filter(ArenaMode::isRanked).map(ArenaMode::getSchemType).collect(Collectors.toList());
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onChatEvent(ChatEvent e) {
|
public void onChatEvent(PlayerChatEvent e) {
|
||||||
if(!(e.getSender() instanceof ProxiedPlayer))
|
Player player = e.getPlayer();
|
||||||
return;
|
|
||||||
ProxiedPlayer player = (ProxiedPlayer) e.getSender();
|
|
||||||
String message = e.getMessage();
|
String message = e.getMessage();
|
||||||
|
|
||||||
e.setCancelled(true);
|
e.setResult(PlayerChatEvent.ChatResult.denied());
|
||||||
|
|
||||||
if (message.contains("jndi:ldap")) {
|
if (message.contains("jndi:ldap")) {
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
@ -71,7 +66,7 @@ public class ChatListener extends BasicListener {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Subserver subserver = Subserver.getSubserver(player);
|
Subserver subserver = Subserver.getSubserver(player);
|
||||||
if(subserver != null && subserver.getType() == Servertype.ARENA && subserver.getServer() == player.getServer().getInfo()) {
|
if(subserver != null && subserver.getType() == Servertype.ARENA && subserver.getServer() == player.getCurrentServer().orElseThrow().getServerInfo()) {
|
||||||
localChat(Chatter.of(player), message);
|
localChat(Chatter.of(player), message);
|
||||||
} else if (message.startsWith("+")) {
|
} else if (message.startsWith("+")) {
|
||||||
localChat(Chatter.of(player), message.substring(1));
|
localChat(Chatter.of(player), message.substring(1));
|
||||||
@ -80,10 +75,10 @@ public class ChatListener extends BasicListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isCommand(ProxiedPlayer player, String message) {
|
private static boolean isCommand(Player player, String message) {
|
||||||
String command = message.substring(1);
|
String command = message.substring(1);
|
||||||
boolean isCommand = message.startsWith("/") || (message.startsWith("7") && command.split(" ", 2)[0].matches("[7/]?[A-Za-z]+"));
|
boolean isCommand = message.startsWith("/") || (message.startsWith("7") && command.split(" ", 2)[0].matches("[7/]?[A-Za-z]+"));
|
||||||
if(isCommand && !ProxyServer.getInstance().getPluginManager().dispatchCommand(player, command)) {
|
if(isCommand && !VelocityCore.getProxy().getCommandManager().executeImmediatelyAsync(player, command).join()) {
|
||||||
if(command.startsWith("7"))
|
if(command.startsWith("7"))
|
||||||
command = "/" + command.substring(1);
|
command = "/" + command.substring(1);
|
||||||
message = "/" + command;
|
message = "/" + command;
|
||||||
@ -99,7 +94,7 @@ public class ChatListener extends BasicListener {
|
|||||||
|
|
||||||
public static void sendChat(Chatter sender, ChatterGroup receivers, String format, Chatter msgReceiver, String message) {
|
public static void sendChat(Chatter sender, ChatterGroup receivers, String format, Chatter msgReceiver, String message) {
|
||||||
SteamwarUser user = sender.user();
|
SteamwarUser user = sender.user();
|
||||||
final String coloredMessage = user.hasPerm(UserPerm.COLOR_CHAT) ? ChatColor.translateAlternateColorCodes('&', message) : message;
|
final String coloredMessage = user.hasPerm(UserPerm.COLOR_CHAT) ? message.replace('&', '§') : message;
|
||||||
if(chatFilter(sender, coloredMessage))
|
if(chatFilter(sender, coloredMessage))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -194,10 +189,9 @@ public class ChatListener extends BasicListener {
|
|||||||
|
|
||||||
private static void specialAlert(Chatter sender, String name, String baseMessage, int... delay) {
|
private static void specialAlert(Chatter sender, String name, String baseMessage, int... delay) {
|
||||||
sender.system("CHAT_LIXFEL_ACTION_BAR");
|
sender.system("CHAT_LIXFEL_ACTION_BAR");
|
||||||
TaskScheduler scheduler = ProxyServer.getInstance().getScheduler();
|
|
||||||
for(int i = 0; i < delay.length; i++) {
|
for(int i = 0; i < delay.length; i++) {
|
||||||
int finalI = i;
|
int finalI = i;
|
||||||
scheduler.schedule(VelocityCore.get(), () -> sender.prefixless("CHAT_MSG", name, sender.user(), new Message(baseMessage + (finalI+1))), delay[i], TimeUnit.SECONDS);
|
VelocityCore.schedule( () -> sender.prefixless("CHAT_MSG", name, sender.user(), new Message(baseMessage + (finalI+1)))).delay(delay[i], TimeUnit.SECONDS).schedule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,16 +201,16 @@ public class ChatListener extends BasicListener {
|
|||||||
|
|
||||||
String mark = "@" + player.user().getUserName();
|
String mark = "@" + player.user().getUserName();
|
||||||
return Arrays.stream(message.split(" ")).map(cur -> {
|
return Arrays.stream(message.split(" ")).map(cur -> {
|
||||||
if(cur.equalsIgnoreCase(mark)) {
|
if(cur.equalsIgnoreCase(mark) && player.getPlayer() != null) {
|
||||||
NetworkSender.send(ProxyServer.getInstance().getPlayer(player.user().getUUID()), new PingPacket(player.user().getId()));
|
NetworkSender.send(player.getPlayer(), new PingPacket(player.user().getId()));
|
||||||
return "§e" + cur + returnColor;
|
return "§e" + cur + returnColor;
|
||||||
}
|
}
|
||||||
return cur;
|
return cur;
|
||||||
}).collect(Collectors.joining(" "));
|
}).collect(Collectors.joining(" "));
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onTabCompleteResponseEvent(TabCompleteResponseEvent e){
|
public void onTabCompleteResponseEvent(TabCompleteEvent e){
|
||||||
List<String> suggestions = e.getSuggestions();
|
List<String> suggestions = e.getSuggestions();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i < suggestions.size()) {
|
while (i < suggestions.size()) {
|
||||||
|
@ -19,6 +19,11 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||||
|
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||||
|
import com.velocitypowered.api.event.player.ServerConnectedEvent;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import de.steamwar.bungeecore.Bauserver;
|
import de.steamwar.bungeecore.Bauserver;
|
||||||
import de.steamwar.bungeecore.Servertype;
|
import de.steamwar.bungeecore.Servertype;
|
||||||
import de.steamwar.bungeecore.Subserver;
|
import de.steamwar.bungeecore.Subserver;
|
||||||
@ -26,18 +31,13 @@ import de.steamwar.bungeecore.commands.CheckCommand;
|
|||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
import de.steamwar.sql.SchematicNode;
|
import de.steamwar.sql.SchematicNode;
|
||||||
import de.steamwar.sql.SchematicType;
|
import de.steamwar.sql.SchematicType;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
|
||||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
|
||||||
import net.md_5.bungee.api.event.ServerSwitchEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CheckListener extends BasicListener {
|
public class CheckListener extends BasicListener {
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onPlayerJoin(PostLoginEvent e){
|
public void onPlayerJoin(PostLoginEvent e){
|
||||||
Chatter sender = Chatter.of(e.getPlayer());
|
Chatter sender = Chatter.of(e.getPlayer());
|
||||||
|
|
||||||
@ -51,11 +51,11 @@ public class CheckListener extends BasicListener {
|
|||||||
sender.system("CHECK_UNCHECKED", uncheckedSchematics.size());
|
sender.system("CHECK_UNCHECKED", uncheckedSchematics.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onServerSwitch(ServerSwitchEvent e){
|
public void onServerSwitch(ServerConnectedEvent e){
|
||||||
ProxiedPlayer player = e.getPlayer();
|
Player player = e.getPlayer();
|
||||||
if(CheckCommand.isChecking(player)){
|
if(CheckCommand.isChecking(player)){
|
||||||
Subserver server = Subserver.getSubserver(player.getServer().getInfo());
|
Subserver server = Subserver.getSubserver(e.getServer().getServerInfo());
|
||||||
if(
|
if(
|
||||||
server == null ||
|
server == null ||
|
||||||
server.getType() != Servertype.BAUSERVER ||
|
server.getType() != Servertype.BAUSERVER ||
|
||||||
@ -65,9 +65,9 @@ public class CheckListener extends BasicListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onPlayerDisconnect(PlayerDisconnectEvent e){
|
public void onPlayerDisconnect(DisconnectEvent e){
|
||||||
ProxiedPlayer player = e.getPlayer();
|
Player player = e.getPlayer();
|
||||||
if(CheckCommand.isChecking(player))
|
if(CheckCommand.isChecking(player))
|
||||||
CheckCommand.abort(player);
|
CheckCommand.abort(player);
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,16 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
import de.steamwar.messages.Message;
|
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||||
|
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||||
|
import com.velocitypowered.api.event.permission.PermissionsSetupEvent;
|
||||||
|
import com.velocitypowered.api.event.player.KickedFromServerEvent;
|
||||||
|
import com.velocitypowered.api.permission.Tristate;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import de.steamwar.bungeecore.Servertype;
|
import de.steamwar.bungeecore.Servertype;
|
||||||
import de.steamwar.bungeecore.Subserver;
|
import de.steamwar.bungeecore.Subserver;
|
||||||
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.commands.ChallengeCommand;
|
import de.steamwar.bungeecore.commands.ChallengeCommand;
|
||||||
import de.steamwar.bungeecore.commands.CheckCommand;
|
import de.steamwar.bungeecore.commands.CheckCommand;
|
||||||
import de.steamwar.bungeecore.commands.ModCommand;
|
import de.steamwar.bungeecore.commands.ModCommand;
|
||||||
@ -31,134 +37,75 @@ import de.steamwar.bungeecore.discord.DiscordBot;
|
|||||||
import de.steamwar.bungeecore.discord.util.DiscordRanks;
|
import de.steamwar.bungeecore.discord.util.DiscordRanks;
|
||||||
import de.steamwar.bungeecore.mods.ModUtils;
|
import de.steamwar.bungeecore.mods.ModUtils;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
|
import de.steamwar.messages.Message;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.sql.UserPerm;
|
import de.steamwar.sql.UserPerm;
|
||||||
import lombok.Getter;
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
import net.md_5.bungee.api.AbstractReconnectHandler;
|
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
|
||||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
|
||||||
import net.md_5.bungee.api.event.ServerKickEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public class ConnectionListener extends BasicListener {
|
public class ConnectionListener extends BasicListener {
|
||||||
|
|
||||||
public static final String ALERT_PERMISSION = "bungeecore.alert";
|
|
||||||
public static final String BAN_PERMISSION = "bungeecore.ban";
|
|
||||||
public static final String BUILDERCLOUD_PERMISSION = "bungeecore.buildercloud";
|
|
||||||
public static final String CHECK_PERMISSION = "bungeecore.check";
|
|
||||||
public static final String EVENTRELOAD_PERMISSION = "bungeecore.eventreload";
|
|
||||||
public static final String KICK_PERMISSION = "bungeecore.kick";
|
|
||||||
public static final String POLLRESULT_PERMISSION = "bungeecore.pollresult";
|
|
||||||
public static final String SOFTRELOAD_PERMISSION = "bungeecore.softreload";
|
|
||||||
public static final String TEAMCHAT_PERMISSION = "bungeecore.teamchat";
|
|
||||||
public static final String MOD_PERMISSION = "bungeecore.mod";
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private static final Map<UserPerm, String[]> commandPermissions = new EnumMap<>(UserPerm.class);
|
|
||||||
static {
|
|
||||||
commandPermissions.put(UserPerm.ADMINISTRATION, new String[]{
|
|
||||||
"bungeecord.command.end",
|
|
||||||
"bungeecord.command.reload",
|
|
||||||
"bungeecord.command.ip",
|
|
||||||
SOFTRELOAD_PERMISSION
|
|
||||||
});
|
|
||||||
commandPermissions.put(UserPerm.MODERATION, new String[]{
|
|
||||||
ALERT_PERMISSION,
|
|
||||||
KICK_PERMISSION,
|
|
||||||
POLLRESULT_PERMISSION,
|
|
||||||
EVENTRELOAD_PERMISSION,
|
|
||||||
MOD_PERMISSION
|
|
||||||
});
|
|
||||||
commandPermissions.put(UserPerm.TEAM, new String[]{
|
|
||||||
"bungeecord.command.list",
|
|
||||||
"bungeecord.command.send",
|
|
||||||
"bungeecord.command.server",
|
|
||||||
TEAMCHAT_PERMISSION,
|
|
||||||
BAN_PERMISSION
|
|
||||||
});
|
|
||||||
commandPermissions.put(UserPerm.CHECK, new String[]{
|
|
||||||
CHECK_PERMISSION
|
|
||||||
});
|
|
||||||
commandPermissions.put(UserPerm.BUILD, new String[]{
|
|
||||||
BUILDERCLOUD_PERMISSION
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Set<UUID> newPlayers = new HashSet<>();
|
private static final Set<UUID> newPlayers = new HashSet<>();
|
||||||
|
|
||||||
public static void newPlayer(UUID player){
|
public static void newPlayer(UUID player){
|
||||||
newPlayers.add(player);
|
newPlayers.add(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
private static final Set<String> TEAM_PERMISSIONS = Set.of("velocity.command.send", "velocity.command.glist");
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onPermissionSetup(PermissionsSetupEvent event) {
|
||||||
|
event.setProvider(subject -> {
|
||||||
|
if(!(subject instanceof Player))
|
||||||
|
return perm -> Tristate.TRUE;
|
||||||
|
|
||||||
|
Set<UserPerm> perms = SteamwarUser.get(((Player) subject).getUniqueId()).perms();
|
||||||
|
if(perms.contains(UserPerm.ADMINISTRATION))
|
||||||
|
return perm -> Tristate.TRUE;
|
||||||
|
else if(perms.contains(UserPerm.TEAM))
|
||||||
|
return perm -> Tristate.fromBoolean(TEAM_PERMISSIONS.contains(perm));
|
||||||
|
else
|
||||||
|
return perm -> Tristate.FALSE;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
public void onPostLogin(PostLoginEvent event) {
|
public void onPostLogin(PostLoginEvent event) {
|
||||||
ProxiedPlayer player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
Chatter chatter = Chatter.of(player);
|
Chatter chatter = Chatter.of(player);
|
||||||
|
|
||||||
user.perms().forEach(perm -> {
|
|
||||||
for(String permission : commandPermissions.getOrDefault(perm, new String[0]))
|
|
||||||
player.setPermission(permission, true);
|
|
||||||
});
|
|
||||||
|
|
||||||
if(user.hasPerm(UserPerm.CHECK))
|
if(user.hasPerm(UserPerm.CHECK))
|
||||||
CheckCommand.sendReminder(chatter);
|
CheckCommand.sendReminder(chatter);
|
||||||
|
|
||||||
for(Subserver subserver : Subserver.getServerList()) {
|
for(Subserver subserver : Subserver.getServerList()) {
|
||||||
if(subserver.getType() == Servertype.ARENA) {
|
if(subserver.getType() == Servertype.ARENA) {
|
||||||
chatter.system("JOIN_ARENA", new Message("JOIN_ARENA_HOVER"), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + subserver.getServer().getName()), subserver.getServer().getName());
|
chatter.system("JOIN_ARENA", new Message("JOIN_ARENA_HOVER"), ClickEvent.runCommand("/arena " + subserver.getServer().getName()), subserver.getServer().getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(newPlayers.contains(player.getUniqueId())){
|
if(newPlayers.contains(player.getUniqueId())){
|
||||||
Chatter.broadcast().system("JOIN_FIRST", player.getName());
|
Chatter.broadcast().system("JOIN_FIRST", player);
|
||||||
newPlayers.remove(player.getUniqueId());
|
newPlayers.remove(player.getUniqueId());
|
||||||
}
|
}
|
||||||
|
|
||||||
DiscordBot.withBot(bot -> DiscordRanks.update(user));
|
DiscordBot.withBot(bot -> DiscordRanks.update(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** To redirect players to the lobby in case of server closure. */
|
/** To redirect players to the lobby in case of server closure. */ //TODO still necessary?
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onServerKickEvent(ServerKickEvent ev)
|
public void onServerKickEvent(KickedFromServerEvent e) {
|
||||||
{
|
e.setResult(KickedFromServerEvent.RedirectPlayer.create(VelocityCore.get().getConfig().lobbyserver(), e.getServerKickReason().orElse(null)));
|
||||||
if(!ev.getPlayer().isConnected())
|
|
||||||
return;
|
|
||||||
|
|
||||||
ServerInfo kickedFrom;
|
|
||||||
|
|
||||||
if (ev.getPlayer().getServer() != null){
|
|
||||||
kickedFrom = ev.getPlayer().getServer().getInfo();
|
|
||||||
}else if (ProxyServer.getInstance().getReconnectHandler() != null){
|
|
||||||
kickedFrom = ProxyServer.getInstance().getReconnectHandler().getServer(ev.getPlayer());
|
|
||||||
}else{
|
|
||||||
kickedFrom = AbstractReconnectHandler.getForcedHost(ev.getPlayer().getPendingConnection());
|
|
||||||
if (kickedFrom == null){
|
|
||||||
kickedFrom = ProxyServer.getInstance().getServerInfo(ev.getPlayer().getPendingConnection().getListener().getDefaultServer());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ServerInfo kickTo = ProxyServer.getInstance().getServerInfo(VelocityCore.get().getConfig().getLobbyserver());
|
@Subscribe
|
||||||
|
public void onDisconnect(DisconnectEvent e){
|
||||||
if (kickedFrom != null && kickedFrom.equals(kickTo)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ev.setCancelled(true);
|
|
||||||
ev.setCancelServer(kickTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onDisconnect(PlayerDisconnectEvent e){
|
|
||||||
ChallengeCommand.remove(e.getPlayer());
|
ChallengeCommand.remove(e.getPlayer());
|
||||||
MsgCommand.remove(e.getPlayer());
|
MsgCommand.remove(e.getPlayer());
|
||||||
ModUtils.getPlayerModMap().remove(e.getPlayer().getUniqueId());
|
ModUtils.getPlayerModMap().remove(e.getPlayer().getUniqueId());
|
||||||
ModCommand.playerFilterType.remove(e.getPlayer());
|
ModCommand.playerFilterType.remove(e.getPlayer().getUniqueId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
import de.steamwar.sql.Event;
|
import de.steamwar.sql.Event;
|
||||||
import de.steamwar.sql.Referee;
|
import de.steamwar.sql.Referee;
|
||||||
import de.steamwar.sql.TeamTeilnahme;
|
import de.steamwar.sql.TeamTeilnahme;
|
||||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
public class EventModeListener extends BasicListener {
|
public class EventModeListener extends BasicListener {
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onPostLogin(PostLoginEvent e) {
|
public void onPostLogin(PostLoginEvent e) {
|
||||||
Chatter sender = Chatter.disconnect(e.getPlayer());
|
Chatter sender = Chatter.disconnect(e.getPlayer());
|
||||||
|
|
||||||
|
@ -19,49 +19,34 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.connection.PreLoginEvent;
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
|
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||||
|
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||||
|
import com.velocitypowered.proxy.connection.client.LoginInboundConnection;
|
||||||
|
import de.steamwar.bungeecore.Reflection;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import net.md_5.bungee.api.connection.PendingConnection;
|
import de.steamwar.bungeecore.mods.Hostname;
|
||||||
import net.md_5.bungee.api.event.LoginEvent;
|
|
||||||
import net.md_5.bungee.connection.InitialHandler;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
import net.md_5.bungee.netty.ChannelWrapper;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.SocketAddress;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class IPSanitizer extends BasicListener {
|
public class IPSanitizer extends BasicListener {
|
||||||
|
|
||||||
private static final Field initialHandlerCh;
|
private static final Reflection.Field<MinecraftConnection, SocketAddress> remoteAddress = Reflection.getField(MinecraftConnection.class, "remoteAddress");
|
||||||
static {
|
|
||||||
try {
|
|
||||||
initialHandlerCh = InitialHandler.class.getDeclaredField("ch");
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
throw new SecurityException("Could not initialize Reflection", e);
|
|
||||||
}
|
|
||||||
initialHandlerCh.setAccessible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ChannelWrapper getChannelWrapper(PendingConnection connection) {
|
|
||||||
try {
|
|
||||||
return (ChannelWrapper) initialHandlerCh.get(connection);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
throw new SecurityException("Could not get channel wrapper", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static InetAddress getTrueAddress(Player player) {
|
public static InetAddress getTrueAddress(Player player) {
|
||||||
return player.getRemoteAddress().getAddress();
|
return ((InetSocketAddress) ((ConnectedPlayer)player).getConnection().getChannel().remoteAddress()).getAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private final InetSocketAddress sanitized = new InetSocketAddress("127.127.127.127", 25565);
|
private final InetSocketAddress sanitized = new InetSocketAddress("127.127.127.127", 25565);
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void loginEvent(LoginEvent e) {
|
public void loginEvent(PreLoginEvent e) {
|
||||||
VelocityCore.getLogger().log(Level.INFO, e.getConnection().getSocketAddress() + " has logged in with user name " + e.getConnection().getName());
|
VelocityCore.getLogger().log(Level.INFO, e.getConnection().getRemoteAddress() + " has logged in with user name " + e.getUsername());
|
||||||
getChannelWrapper(e.getConnection()).setRemoteAddress(sanitized);
|
remoteAddress.set(Hostname.getInitialInboundConnection((LoginInboundConnection) e.getConnection()).getConnection(), sanitized);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.lunarclient.apollo.ApolloManager;
|
import com.lunarclient.apollo.ApolloManager;
|
||||||
import com.velocitypowered.api.event.Subscribe;
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
@ -27,15 +26,15 @@ import com.velocitypowered.api.network.ProtocolVersion;
|
|||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.proxy.ServerConnection;
|
import com.velocitypowered.api.proxy.ServerConnection;
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
||||||
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
|
|
||||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.commands.TeamCommand;
|
import de.steamwar.bungeecore.commands.TeamCommand;
|
||||||
import de.steamwar.bungeecore.mods.*;
|
import de.steamwar.bungeecore.mods.*;
|
||||||
import de.steamwar.bungeecore.network.ServerMetaInfo;
|
import de.steamwar.bungeecore.network.ServerMetaInfo;
|
||||||
|
import de.steamwar.messages.Chatter;
|
||||||
import de.steamwar.network.packets.NetworkPacket;
|
import de.steamwar.network.packets.NetworkPacket;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
|
||||||
@ -46,20 +45,15 @@ import java.util.*;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class PluginMessage {
|
public class PluginMessage extends BasicListener {
|
||||||
|
|
||||||
private final Lunar lunar;
|
|
||||||
private final LabyMod labyMod;
|
|
||||||
private final WorldDownloader wdl;
|
|
||||||
private final FabricModSender fms;
|
|
||||||
private final FML flm;
|
|
||||||
|
|
||||||
public static void send(Player player, String legacyChannel, String channel, byte[] data) {
|
public static void send(Player player, String legacyChannel, String channel, byte[] data) {
|
||||||
// 1.12 format change
|
// 1.12 format change
|
||||||
send(player, player.getProtocolVersion().getProtocol() > 340 ? channel : legacyChannel, data);
|
send(player, player.getProtocolVersion().greaterThan(ProtocolVersion.MINECRAFT_1_12_2) ? channel : legacyChannel, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void send(Player player, String channel, byte[] data) {
|
public static void send(Player player, String channel, byte[] data) {
|
||||||
|
//TODO only if player has registered channel
|
||||||
player.sendPluginMessage(MinecraftChannelIdentifier.from(channel), data);
|
player.sendPluginMessage(MinecraftChannelIdentifier.from(channel), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,33 +83,28 @@ public class PluginMessage {
|
|||||||
void accept(DataOutputStream out) throws IOException;
|
void accept(DataOutputStream out) throws IOException;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Parser UNKNOWN = event -> {
|
private static final Parser UNKNOWN = event -> VelocityCore.getLogger().log(Level.WARNING, () -> "Undefined PluginMessage on channel " + event.getIdentifier() + " from " + event.getSource() + " received.\n" + new String(event.getData()) + "\n" + Arrays.toString(event.getData()));
|
||||||
VelocityCore.get().getLogger().log(Level.WARNING, () -> "Undefined PluginMessage on channel " + event.getIdentifier().getId() + " from " + (event.getSource() instanceof Player pl ? pl.getUsername() : event.getSource().toString()) + " received.\n" + new String(event.getData()) + "\n" + Arrays.toString(event.getData()));
|
|
||||||
event.setResult(PluginMessageEvent.ForwardResult.handled());
|
|
||||||
};
|
|
||||||
private static final Parser PASS_THROUGH = event -> event.setResult(PluginMessageEvent.ForwardResult.forward());
|
private static final Parser PASS_THROUGH = event -> event.setResult(PluginMessageEvent.ForwardResult.forward());
|
||||||
private static final Parser DROP = event -> event.setResult(PluginMessageEvent.ForwardResult.handled());
|
private static final Parser DROP = event -> {};
|
||||||
|
|
||||||
|
private final Lunar lunar = new Lunar();
|
||||||
|
private final Badlion badlion = new Badlion();
|
||||||
|
|
||||||
private final Set<String> knownBrands = new HashSet<>();
|
private final Set<String> knownBrands = new HashSet<>();
|
||||||
private final Map<String, Consumer<Player>> channelRegisterHandlers = new HashMap<>();
|
private final Map<String, Consumer<Player>> channelRegisterHandlers = new HashMap<>();
|
||||||
private final Map<String, Parser> handlers = new HashMap<>();
|
private final Map<String, Parser> handlers = new HashMap<>();
|
||||||
|
|
||||||
public PluginMessage() {
|
public PluginMessage() {
|
||||||
ModUtils utils = new ModUtils();
|
LabyMod labyMod = new LabyMod();
|
||||||
|
WorldDownloader wdl = new WorldDownloader();
|
||||||
|
|
||||||
this.lunar = new Lunar(utils);
|
knownBrands.addAll(Arrays.asList("vanilla", "badlion", "fabric", "quilt", "forge", "optifine", "Geyser", "labymod", "Feather Fabric"));
|
||||||
this.labyMod = new LabyMod(utils);
|
|
||||||
this.wdl = new WorldDownloader();
|
|
||||||
this.fms = new FabricModSender(utils);
|
|
||||||
this.flm = new FML(utils);
|
|
||||||
|
|
||||||
knownBrands.addAll(Arrays.asList("vanilla", "fabric", "quilt", "forge", "optifine", "Geyser", "labymod", "Feather Fabric"));
|
|
||||||
|
|
||||||
for(String channel : Arrays.asList(
|
for(String channel : Arrays.asList(
|
||||||
"fabric:container/open", "fabric:registry/sync/direct", "fabric:registry/sync",
|
"fabric:container/open", "fabric:registry/sync/direct", "fabric:registry/sync",
|
||||||
"fabric-screen-handler-api-v1:open_screen",
|
"fabric-screen-handler-api-v1:open_screen",
|
||||||
|
|
||||||
FML.CHANNEL.getId(), "fml:loginwrapper", "fml:handshake", "fml:play", "forge:tier_sorting", "forge:split",
|
FML.CHANNEL, "fml:loginwrapper", "fml:handshake", "fml:play", "forge:tier_sorting", "forge:split",
|
||||||
"forge:login", "forge:handshake",
|
"forge:login", "forge:handshake",
|
||||||
|
|
||||||
"labymod3:main", "labymod:neo",
|
"labymod3:main", "labymod:neo",
|
||||||
@ -153,18 +142,16 @@ public class PluginMessage {
|
|||||||
"noxesium-v1:reset", "noxesium-v1:change_server_rules", "noxesium-v1:server_info",
|
"noxesium-v1:reset", "noxesium-v1:change_server_rules", "noxesium-v1:server_info",
|
||||||
"noxesium-v1:mcc_server", "noxesium-v1:mcc_game_state", "noxesium-v1:reset_server_rules",
|
"noxesium-v1:mcc_server", "noxesium-v1:mcc_game_state", "noxesium-v1:reset_server_rules",
|
||||||
"noxesium-v1:stop_sound", "noxesium-v1:start_sound", "noxesium-v1:modify_sound"
|
"noxesium-v1:stop_sound", "noxesium-v1:start_sound", "noxesium-v1:modify_sound"
|
||||||
)) {
|
))
|
||||||
channelRegisterHandlers.put(channel, player -> {
|
channelRegisterHandlers.put(channel, player -> {});
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
channelRegisterHandlers.put(ApolloManager.PLUGIN_MESSAGE_CHANNEL, lunar::sendRestrictions);
|
channelRegisterHandlers.put(ApolloManager.PLUGIN_MESSAGE_CHANNEL, lunar::sendRestrictions);
|
||||||
channelRegisterHandlers.put(Feather.CHANNEL.getId(), new Feather()::sendRestrictions);
|
channelRegisterHandlers.put(Feather.CHANNEL, new Feather()::sendRestrictions);
|
||||||
channelRegisterHandlers.put("xaerominimap:main", player -> player.sendMessage(Component.text("§n§o§m§i§n§i§m§a§p"))); //https://www.curseforge.com/minecraft/mc-mods/xaeros-minimap
|
channelRegisterHandlers.put("xaerominimap:main", player -> player.sendMessage(Component.text("§n§o§m§i§n§i§m§a§p"))); //https://www.curseforge.com/minecraft/mc-mods/xaeros-minimap
|
||||||
channelRegisterHandlers.put("litemoretica:init_easy_place", player -> player.disconnect(ChatSender.of(player).parseToComponent(false, new Message("MOD_YELLOW_SING", "litematica")))); //https://github.com/Earthcomputer/litemoretica/tree/master
|
channelRegisterHandlers.put("litemoretica:init_easy_place", player -> Chatter.disconnect(player).prefixless("MOD_YELLOW_SING", "litematica")); //https://github.com/Earthcomputer/litemoretica/tree/master
|
||||||
channelRegisterHandlers.put("voxelmap:settings", player -> player.disconnect(ChatSender.of(player).parseToComponent(false, new Message("MOD_YELLOW_SING", "voxelmap")))); //https://modrinth.com/mod/voxelmap-updated undocumented
|
channelRegisterHandlers.put("voxelmap:settings", player -> Chatter.disconnect(player).prefixless("MOD_YELLOW_SING", "voxelmap")); //https://modrinth.com/mod/voxelmap-updated undocumented
|
||||||
channelRegisterHandlers.put("worldinfo:world_id", player -> player.disconnect(ChatSender.of(player).parseToComponent(false, new Message("MOD_YELLOW_SING", "minimap")))); // JourneyMap and VoxelMap
|
channelRegisterHandlers.put("worldinfo:world_id", player -> Chatter.disconnect(player).prefixless("MOD_YELLOW_SING", "minimap")); // JourneyMap and VoxelMap
|
||||||
channelRegisterHandlers.put(Controlify.CHANNEL.getId(), new Controlify()::onRegister);
|
channelRegisterHandlers.put(Controlify.CHANNEL, new Controlify()::onRegister);
|
||||||
|
|
||||||
registerBiDirPassthrough("worldedit:cui");
|
registerBiDirPassthrough("worldedit:cui");
|
||||||
|
|
||||||
@ -198,15 +185,13 @@ public class PluginMessage {
|
|||||||
register("REGISTER", false, directional(this::serverRegistersChannel, this::clientRegistersChannel));
|
register("REGISTER", false, directional(this::serverRegistersChannel, this::clientRegistersChannel));
|
||||||
register("minecraft:register", false, directional(this::serverRegistersChannel, this::clientRegistersChannel));
|
register("minecraft:register", false, directional(this::serverRegistersChannel, this::clientRegistersChannel));
|
||||||
|
|
||||||
register("BungeeCord", false, onlySWSource(PASS_THROUGH));
|
|
||||||
register("bungeecord:main", false, onlySWSource(PASS_THROUGH));
|
|
||||||
register("MC|Brand", false, directional(this::steamWarBrand, this::userBrand));
|
register("MC|Brand", false, directional(this::steamWarBrand, this::userBrand));
|
||||||
register("minecraft:brand", false, directional(this::steamWarBrand, this::userBrand));
|
register("minecraft:brand", false, directional(this::steamWarBrand, this::userBrand));
|
||||||
|
|
||||||
//Needs to be registered cause paper refuses to send PluginMessages on unregistered channels...
|
//Needs to be registered cause paper refuses to send PluginMessages on unregistered channels...
|
||||||
register("sw:bridge", true, directional(onlySWSource(async(event -> NetworkPacket.handle(new ServerMetaInfo(((ServerConnection) event.getSource()).getServer()), event.getData()))), UNKNOWN));
|
register("sw:bridge", true, directional(onlySWSource(async(event -> NetworkPacket.handle(new ServerMetaInfo((ServerConnection) event.getSource()), event.getData()))), UNKNOWN));
|
||||||
register("sw:hotkeys", false, directional(UNKNOWN, PASS_THROUGH));
|
register("sw:hotkeys", false, directional(UNKNOWN, PASS_THROUGH));
|
||||||
register("fabricmodsender:mods", true, directional(UNKNOWN, async(fms::handlePluginMessage)));
|
register("fabricmodsender:mods", true, directional(UNKNOWN, async(new FabricModSender()::handlePluginMessage)));
|
||||||
|
|
||||||
register("WDL|INIT", true, directional(UNKNOWN, wdl::handlePluginMessage));
|
register("WDL|INIT", true, directional(UNKNOWN, wdl::handlePluginMessage));
|
||||||
register("wdl:init", true, directional(UNKNOWN, wdl::handlePluginMessage));
|
register("wdl:init", true, directional(UNKNOWN, wdl::handlePluginMessage));
|
||||||
@ -215,7 +200,7 @@ public class PluginMessage {
|
|||||||
register("LMC", true, directional(UNKNOWN, async(labyMod::handlePluginMessage)));
|
register("LMC", true, directional(UNKNOWN, async(labyMod::handlePluginMessage)));
|
||||||
register("labymod3:main", true, directional(UNKNOWN, async(labyMod::handlePluginMessage)));
|
register("labymod3:main", true, directional(UNKNOWN, async(labyMod::handlePluginMessage)));
|
||||||
register("labymod:neo", false, directional(UNKNOWN, DROP)); //undocumented, JSON format "0" byte, packetlängen byte, {"version":"4.1.25"}
|
register("labymod:neo", false, directional(UNKNOWN, DROP)); //undocumented, JSON format "0" byte, packetlängen byte, {"version":"4.1.25"}
|
||||||
register(FML.CHANNEL.getId(), true, directional(UNKNOWN, async(flm::handlePluginMessage)));
|
register(FML.CHANNEL, true, directional(UNKNOWN, async(new FML()::handlePluginMessage)));
|
||||||
|
|
||||||
//vanilla does not register any channels (sends only one minecraft:brand vanilla, nothing else (potential spoofed client detection))
|
//vanilla does not register any channels (sends only one minecraft:brand vanilla, nothing else (potential spoofed client detection))
|
||||||
//Forge interestingly registers all channels the server registers
|
//Forge interestingly registers all channels the server registers
|
||||||
@ -257,14 +242,14 @@ public class PluginMessage {
|
|||||||
private void register(String channel, boolean clientSideRegister, Parser handler) {
|
private void register(String channel, boolean clientSideRegister, Parser handler) {
|
||||||
handlers.put(channel, handler);
|
handlers.put(channel, handler);
|
||||||
if(clientSideRegister)
|
if(clientSideRegister)
|
||||||
VelocityCore.get().getProxyServer().getChannelRegistrar().register(MinecraftChannelIdentifier.from(channel));
|
VelocityCore.getProxy().getChannelRegistrar().register(MinecraftChannelIdentifier.from(channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clientRegistersChannel(PluginMessageEvent event) {
|
private void clientRegistersChannel(PluginMessageEvent event) {
|
||||||
Player player = (Player) event.getSource();
|
Player player = (Player) event.getSource();
|
||||||
|
|
||||||
for(String channel : new String(event.getData()).split("\0")) {
|
for(String channel : new String(event.getData()).split("\0")) {
|
||||||
channelRegisterHandlers.getOrDefault(channel, p -> VelocityCore.get().getLogger().log(Level.WARNING, () -> p.getUsername() + " registered unknown channel " + channel)).accept(player);
|
channelRegisterHandlers.getOrDefault(channel, p -> VelocityCore.getLogger().log(Level.WARNING, () -> p.getUsername() + " registered unknown channel " + channel)).accept(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
PASS_THROUGH.handle(event);
|
PASS_THROUGH.handle(event);
|
||||||
@ -275,30 +260,29 @@ public class PluginMessage {
|
|||||||
|
|
||||||
List<String> channels = new ArrayList<>(Arrays.asList(new String(event.getData()).split("\0")));
|
List<String> channels = new ArrayList<>(Arrays.asList(new String(event.getData()).split("\0")));
|
||||||
channels.removeIf(channel -> channel.equals("sw:bridge"));
|
channels.removeIf(channel -> channel.equals("sw:bridge"));
|
||||||
player.sendPluginMessage((player).getProtocolVersion().greaterThan(ProtocolVersion.MINECRAFT_1_12_2) ? MinecraftChannelIdentifier.from("minecraft:register") : new LegacyChannelIdentifier("REGISTER"), String.join("\0", channels).getBytes());
|
send(player, "REGISTER", "minecraft:register", String.join("\0", channels).getBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void userBrand(PluginMessageEvent event) {
|
private void userBrand(PluginMessageEvent event) {
|
||||||
Player player = (Player) event.getSource();
|
Player player = (Player) event.getSource();
|
||||||
|
|
||||||
ByteBuf buf = Unpooled.wrappedBuffer(event.getData());
|
ByteBuf buf = Unpooled.wrappedBuffer(event.getData());
|
||||||
String brand = ProtocolUtils.readString(buf);
|
String brand = ProtocolUtils.readString(buf);
|
||||||
boolean lunarclient = brand.startsWith("lunarclient:");
|
boolean lunarclient = brand.startsWith("lunarclient:");
|
||||||
|
|
||||||
VelocityCore.get().getLogger().log(knownBrands.contains(brand) || lunarclient ? Level.INFO : Level.WARNING, () -> player.getUsername() + " joins with brand: " + brand);
|
VelocityCore.getLogger().log(knownBrands.contains(brand) || lunarclient ? Level.INFO : Level.WARNING, () -> player.getUsername() + " joins with brand: " + brand);
|
||||||
if(lunarclient)
|
if(lunarclient)
|
||||||
lunar.sendRestrictions(player);
|
lunar.sendRestrictions(player);
|
||||||
|
if(brand.equals("badlion"))
|
||||||
|
badlion.sendRestrictions(player);
|
||||||
|
|
||||||
PASS_THROUGH.handle(event);
|
PASS_THROUGH.handle(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void steamWarBrand(PluginMessageEvent event) {
|
private void steamWarBrand(PluginMessageEvent event) {
|
||||||
Player player = (Player) event.getTarget();
|
Player player = (Player) event.getTarget();
|
||||||
String brandString = ChatSender.of(player).parseToLegacy("STEAMWAR_BRAND", "Velocity", player.getCurrentServer().map(serverConnection -> serverConnection.getServerInfo().getName()).orElse(""), new String(event.getData(), 1, event.getData().length - 1));
|
String brand = Chatter.of(player).parseToLegacy("STEAMWAR_BRAND", "Velocity", player.getCurrentServer().map(serverConnection -> serverConnection.getServerInfo().getName()).orElse(""), new String(event.getData(), 1, event.getData().length - 1));
|
||||||
|
player.sendPluginMessage(event.getIdentifier(), genBufPacket(buf -> ProtocolUtils.writeString(buf, brand)));
|
||||||
ByteBuf brand = ByteBufAllocator.DEFAULT.heapBuffer();
|
|
||||||
ProtocolUtils.writeString(brand, brandString);
|
|
||||||
player.sendPluginMessage(event.getIdentifier(), brand.array());
|
|
||||||
brand.release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -314,7 +298,7 @@ public class PluginMessage {
|
|||||||
private Parser onlySWSource(Parser parser) {
|
private Parser onlySWSource(Parser parser) {
|
||||||
return event -> {
|
return event -> {
|
||||||
ChannelMessageSource sender = event.getSource();
|
ChannelMessageSource sender = event.getSource();
|
||||||
if(TeamCommand.isLocalhost(sender instanceof Player player ? IPSanitizer.getTrueAddress((player)) : ((ServerConnection) sender).getServerInfo().getAddress().getAddress()))
|
if(TeamCommand.isLocalhost(sender instanceof Player player ? IPSanitizer.getTrueAddress(player) : ((ServerConnection) sender).getServerInfo().getAddress().getAddress()))
|
||||||
parser.handle(event);
|
parser.handle(event);
|
||||||
else
|
else
|
||||||
UNKNOWN.handle(event);
|
UNKNOWN.handle(event);
|
||||||
@ -322,7 +306,7 @@ public class PluginMessage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Parser async(Parser parser) {
|
private Parser async(Parser parser) {
|
||||||
return event -> VelocityCore.get().getProxyServer().getScheduler().buildTask(VelocityCore.get(), () -> parser.handle(event)).schedule();
|
return event -> VelocityCore.schedule(() -> parser.handle(event)).schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface Parser {
|
private interface Parser {
|
||||||
|
@ -19,18 +19,15 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||||
import de.steamwar.bungeecore.Config;
|
import de.steamwar.bungeecore.Config;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.messages.Message;
|
|
||||||
import de.steamwar.command.TypeValidator;
|
import de.steamwar.command.TypeValidator;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
|
import de.steamwar.messages.Message;
|
||||||
import de.steamwar.sql.PollAnswer;
|
import de.steamwar.sql.PollAnswer;
|
||||||
import net.md_5.bungee.api.chat.ClickEvent;
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class PollSystem extends BasicListener {
|
public class PollSystem extends BasicListener {
|
||||||
|
|
||||||
@ -49,7 +46,7 @@ public class PollSystem extends BasicListener {
|
|||||||
private static Config.Poll poll = null;
|
private static Config.Poll poll = null;
|
||||||
|
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onPostLogin(PostLoginEvent event){
|
public void onPostLogin(PostLoginEvent event){
|
||||||
Chatter player = Chatter.of(event.getPlayer());
|
Chatter player = Chatter.of(event.getPlayer());
|
||||||
|
|
||||||
@ -66,7 +63,7 @@ public class PollSystem extends BasicListener {
|
|||||||
player.prefixless("POLL_QUESTION", poll.getQuestion());
|
player.prefixless("POLL_QUESTION", poll.getQuestion());
|
||||||
|
|
||||||
for(int i = 1; i <= poll.getAnswers().size(); i++) {
|
for(int i = 1; i <= poll.getAnswers().size(); i++) {
|
||||||
player.prefixless("POLL_ANSWER", new Message("POLL_ANSWER_HOVER", poll.getAnswers().get(i-1)), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/poll " + i), poll.getAnswers().get(i-1));
|
player.prefixless("POLL_ANSWER", new Message("POLL_ANSWER_HOVER", poll.getAnswers().get(i-1)), ClickEvent.runCommand("/poll " + i), poll.getAnswers().get(i-1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,13 +19,12 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||||
|
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.sql.Session;
|
import de.steamwar.sql.Session;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
|
||||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@ -34,16 +33,16 @@ import static de.steamwar.bungeecore.Storage.sessions;
|
|||||||
|
|
||||||
public class SessionManager extends BasicListener {
|
public class SessionManager extends BasicListener {
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onPostLogin(PostLoginEvent event){
|
public void onPostLogin(PostLoginEvent event){
|
||||||
sessions.put(event.getPlayer(), Timestamp.from(Instant.now()));
|
sessions.put(event.getPlayer(), Timestamp.from(Instant.now()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onDisconnect(PlayerDisconnectEvent e){
|
public void onDisconnect(DisconnectEvent e){
|
||||||
Timestamp timestamp = sessions.remove(e.getPlayer());
|
Timestamp timestamp = sessions.remove(e.getPlayer());
|
||||||
if(timestamp != null) {
|
if(timestamp != null) {
|
||||||
ProxyServer.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> Session.insertSession(SteamwarUser.get(e.getPlayer().getUniqueId()).getId(), timestamp));
|
VelocityCore.schedule(() -> Session.insertSession(SteamwarUser.get(e.getPlayer().getUniqueId()).getId(), timestamp)).schedule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,24 +19,23 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.listeners;
|
package de.steamwar.bungeecore.listeners;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.player.PlayerSettingsChangedEvent;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.network.NetworkSender;
|
import de.steamwar.bungeecore.network.NetworkSender;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.network.packets.server.LocaleInvalidationPacket;
|
import de.steamwar.network.packets.server.LocaleInvalidationPacket;
|
||||||
import net.md_5.bungee.BungeeCord;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.SettingsChangedEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
public class SettingsChangedListener extends BasicListener {
|
public class SettingsChangedListener extends BasicListener {
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onSettingsChanged(SettingsChangedEvent event) {
|
public void onSettingsChanged(PlayerSettingsChangedEvent event) {
|
||||||
BungeeCord.getInstance().getScheduler().runAsync(VelocityCore.get(), () -> {
|
VelocityCore.schedule(() -> {
|
||||||
ProxiedPlayer player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||||
user.setLocale(player.getLocale(), false);
|
user.setLocale(event.getPlayerSettings().getLocale(), false);
|
||||||
NetworkSender.send(player, new LocaleInvalidationPacket(user.getId()));
|
NetworkSender.send(player, new LocaleInvalidationPacket(user.getId()));
|
||||||
});
|
}).schedule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,7 @@
|
|||||||
package de.steamwar.bungeecore.mods;
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.velocitypowered.api.event.Subscribe;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
|
||||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
|
|
||||||
public class Badlion {
|
public class Badlion {
|
||||||
@ -50,8 +49,7 @@ public class Badlion {
|
|||||||
packet = json.toString().getBytes();
|
packet = json.toString().getBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
public void sendRestrictions(Player player) {
|
||||||
public void onPostLogin(PostLoginEvent event) {
|
player.sendPluginMessage(MinecraftChannelIdentifier.from("badlion:mods"), packet);
|
||||||
event.getPlayer().sendPluginMessage(MinecraftChannelIdentifier.from("badlion:mods"), packet);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
package de.steamwar.bungeecore.mods;
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
|
||||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import de.steamwar.bungeecore.listeners.PluginMessage;
|
import de.steamwar.bungeecore.listeners.PluginMessage;
|
||||||
@ -30,7 +29,7 @@ public class Controlify {
|
|||||||
//https://github.com/isXander/Controlify/blob/1.20.x/dev/src/main/java/dev/isxander/controlify/server/ServerPolicyPacket.java
|
//https://github.com/isXander/Controlify/blob/1.20.x/dev/src/main/java/dev/isxander/controlify/server/ServerPolicyPacket.java
|
||||||
//https://github.com/isXander/Controlify/blob/1.20.x/dev/src/main/java/dev/isxander/controlify/server/ServerPolicies.java
|
//https://github.com/isXander/Controlify/blob/1.20.x/dev/src/main/java/dev/isxander/controlify/server/ServerPolicies.java
|
||||||
|
|
||||||
public static final ChannelIdentifier CHANNEL = MinecraftChannelIdentifier.from("controlify:server_policy");
|
public static final String CHANNEL = "controlify:server_policy";
|
||||||
|
|
||||||
private final byte[][] packets;
|
private final byte[][] packets;
|
||||||
public Controlify() {
|
public Controlify() {
|
||||||
@ -49,6 +48,6 @@ public class Controlify {
|
|||||||
|
|
||||||
public void onRegister(Player player) {
|
public void onRegister(Player player) {
|
||||||
for(byte[] packet : packets)
|
for(byte[] packet : packets)
|
||||||
player.sendPluginMessage(CHANNEL, packet);
|
player.sendPluginMessage(MinecraftChannelIdentifier.from(CHANNEL), packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,68 +19,26 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.mods;
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.velocitypowered.api.event.Subscribe;
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
import com.velocitypowered.api.event.connection.ConnectionHandshakeEvent;
|
|
||||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||||
import com.velocitypowered.api.proxy.LoginPhaseConnection;
|
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.proxy.ProxyServer;
|
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
|
||||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
import com.velocitypowered.proxy.connection.ConnectionType;
|
|
||||||
import com.velocitypowered.proxy.connection.ConnectionTypes;
|
|
||||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
|
||||||
import com.velocitypowered.proxy.connection.client.InitialInboundConnection;
|
|
||||||
import com.velocitypowered.proxy.connection.client.LoginInboundConnection;
|
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.util.annotations.Create;
|
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||||
|
import de.steamwar.messages.Chatter;
|
||||||
import de.steamwar.sql.Mod;
|
import de.steamwar.sql.Mod;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import lombok.SneakyThrows;
|
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Create
|
public class FML extends BasicListener {
|
||||||
public class FML {
|
|
||||||
// https://wiki.vg/Minecraft_Forge_Handshake#FML_protocol_.281.7_-_1.12.29
|
// https://wiki.vg/Minecraft_Forge_Handshake#FML_protocol_.281.7_-_1.12.29
|
||||||
|
|
||||||
private static final Field delegateField;
|
public static final String CHANNEL = "FML|HS";
|
||||||
private static final Field handshakeField;
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
delegateField = LoginInboundConnection.class.getDeclaredField("delegate");
|
|
||||||
handshakeField = InitialInboundConnection.class.getDeclaredField("handshake");
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ModUtils utils;
|
|
||||||
private final ProxyServer proxyServer;
|
|
||||||
private final VelocityCore core;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public FML(ModUtils utils) {
|
|
||||||
this.utils = utils;
|
|
||||||
this.proxyServer = VelocityCore.getProxy();
|
|
||||||
this.core = VelocityCore.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
public static boolean isFML(LoginPhaseConnection connection, String type) {
|
|
||||||
return handshakeField.get(delegateField.get(connection)) instanceof HandshakePacket packet && packet.getServerAddress().endsWith("\0" + type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final ChannelIdentifier CHANNEL = MinecraftChannelIdentifier.from("FML|HS");
|
|
||||||
private final byte[] helloPacket = new byte[]{
|
private final byte[] helloPacket = new byte[]{
|
||||||
/* Packet type: ServerHello */ 0,
|
/* Packet type: ServerHello */ 0,
|
||||||
/* FML protocol version */ 2,
|
/* FML protocol version */ 2,
|
||||||
@ -100,9 +58,8 @@ public class FML {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(((ConnectedPlayer) event.getPlayer()).getConnection().getType() == ConnectionTypes.LEGACY_FORGE) {
|
//if(isFML(player, "\0FML\0"))
|
||||||
player.sendPluginMessage(CHANNEL, helloPacket);
|
player.sendPluginMessage(MinecraftChannelIdentifier.from(CHANNEL), helloPacket);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handlePluginMessage(PluginMessageEvent event) {
|
public void handlePluginMessage(PluginMessageEvent event) {
|
||||||
@ -120,16 +77,16 @@ public class FML {
|
|||||||
mods.add(Mod.getOrCreate(name, Mod.Platform.FORGE));
|
mods.add(Mod.getOrCreate(name, Mod.Platform.FORGE));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (utils.handleMods(p, mods)) {
|
if (ModUtils.handleMods(p, mods)) {
|
||||||
synchronized (unlocked) {
|
synchronized (unlocked) {
|
||||||
unlocked.add(p.getUniqueId());
|
unlocked.add(p.getUniqueId());
|
||||||
}
|
}
|
||||||
p.disconnect(LegacyComponentSerializer.legacySection().deserialize("§7Deine installierten Mods wurden überprüft\n§aDu kannst nun §eSteam§8War §abetreten"));
|
Chatter.disconnect(p).system("MODS_CHECKED");
|
||||||
proxyServer.getScheduler().buildTask(core, () -> {
|
VelocityCore.schedule(() -> {
|
||||||
synchronized (unlocked) {
|
synchronized (unlocked) {
|
||||||
unlocked.remove(p.getUniqueId());
|
unlocked.remove(p.getUniqueId());
|
||||||
}
|
}
|
||||||
}).delay(30, TimeUnit.SECONDS);
|
}).delay(30, TimeUnit.SECONDS).schedule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,29 +19,25 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.mods;
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.velocitypowered.api.event.Subscribe;
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
import com.velocitypowered.api.event.connection.PreLoginEvent;
|
import com.velocitypowered.api.event.connection.PreLoginEvent;
|
||||||
import com.velocitypowered.api.proxy.LoginPhaseConnection;
|
import com.velocitypowered.api.proxy.LoginPhaseConnection;
|
||||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
import com.velocitypowered.proxy.connection.client.LoginInboundConnection;
|
import com.velocitypowered.proxy.connection.client.LoginInboundConnection;
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.listeners.IPSanitizer;
|
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||||
import de.steamwar.bungeecore.listeners.PluginMessage;
|
import de.steamwar.bungeecore.listeners.PluginMessage;
|
||||||
import de.steamwar.bungeecore.util.annotations.Create;
|
|
||||||
import de.steamwar.sql.Mod;
|
import de.steamwar.sql.Mod;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import lombok.AllArgsConstructor;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class FML2 {
|
public class FML2 extends BasicListener {
|
||||||
|
|
||||||
protected final ModUtils modUtils;
|
|
||||||
// FML2: https://wiki.vg/Minecraft_Forge_Handshake#FML2_protocol_.281.13_-_Current.29
|
// FML2: https://wiki.vg/Minecraft_Forge_Handshake#FML2_protocol_.281.13_-_Current.29
|
||||||
// FML3: https://github.com/adde0109/Ambassador/tree/non-api/src/main/java/org/adde0109/ambassador/forge
|
// FML3: https://github.com/adde0109/Ambassador/tree/non-api/src/main/java/org/adde0109/ambassador/forge
|
||||||
|
|
||||||
@ -49,12 +45,15 @@ public class FML2 {
|
|||||||
// FORGE: https://github.com/MinecraftForge/MinecraftForge/blob/1.20.x/src/main/java/net/minecraftforge/network/ForgePacketHandler.java
|
// FORGE: https://github.com/MinecraftForge/MinecraftForge/blob/1.20.x/src/main/java/net/minecraftforge/network/ForgePacketHandler.java
|
||||||
// FORGE: https://github.com/MinecraftForge/MinecraftForge/blob/1.20.x/src/main/java/net/minecraftforge/network/packets/ModVersions.java
|
// FORGE: https://github.com/MinecraftForge/MinecraftForge/blob/1.20.x/src/main/java/net/minecraftforge/network/packets/ModVersions.java
|
||||||
|
|
||||||
|
public static boolean isFML(LoginInboundConnection connection, String type) {
|
||||||
|
return Hostname.getExtraHandshakeData(connection).equals(type);
|
||||||
|
}
|
||||||
|
|
||||||
private final byte[] fml2ModListPacket;
|
private final byte[] fml2ModListPacket;
|
||||||
private final byte[] fml3ModListPacket;
|
private final byte[] fml3ModListPacket;
|
||||||
private final byte[] forgeModListPacket;
|
private final byte[] forgeModListPacket;
|
||||||
|
|
||||||
public FML2() {
|
public FML2() {
|
||||||
this.modUtils = modUtils;
|
|
||||||
fml2ModListPacket = generateModListPacket(false);
|
fml2ModListPacket = generateModListPacket(false);
|
||||||
fml3ModListPacket = generateModListPacket(true);
|
fml3ModListPacket = generateModListPacket(true);
|
||||||
forgeModListPacket = PluginMessage.genBufPacket(buf -> {
|
forgeModListPacket = PluginMessage.genBufPacket(buf -> {
|
||||||
@ -74,18 +73,18 @@ public class FML2 {
|
|||||||
public void onLogin(PreLoginEvent event) {
|
public void onLogin(PreLoginEvent event) {
|
||||||
LoginInboundConnection connection = (LoginInboundConnection) event.getConnection();
|
LoginInboundConnection connection = (LoginInboundConnection) event.getConnection();
|
||||||
|
|
||||||
boolean fml2 = FML.isFML(connection, "FML2\0");
|
boolean fml2 = isFML(connection, "\0FML2\0");
|
||||||
boolean fml3 = FML.isFML(connection, "FML3\0");
|
boolean fml3 = isFML(connection, "\0FML3\0");
|
||||||
boolean forge = FML.isFML(connection, "FORGE");
|
boolean forge = isFML(connection, "\0FORGE");
|
||||||
if(!fml2 && !fml3 && !forge)
|
if(!fml2 && !fml3 && !forge)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FML2LoginHandler handler = new FML2LoginHandler(connection, event.getUniqueId(), forge);
|
FML2LoginHandler handler = new FML2LoginHandler(connection, event.getUniqueId(), forge);
|
||||||
|
|
||||||
if(forge) {
|
if(forge) {
|
||||||
((LoginInboundConnection) event.getConnection()).sendLoginPluginMessage(MinecraftChannelIdentifier.from("forge:login"), forgeModListPacket, handler);
|
connection.sendLoginPluginMessage(MinecraftChannelIdentifier.from("forge:login"), forgeModListPacket, handler);
|
||||||
} else {
|
} else {
|
||||||
((LoginInboundConnection) event.getConnection()).sendLoginPluginMessage(MinecraftChannelIdentifier.from("fml:loginwrapper"), fml3 ? fml3ModListPacket : fml2ModListPacket, handler);
|
connection.sendLoginPluginMessage(MinecraftChannelIdentifier.from("fml:loginwrapper"), fml3 ? fml3ModListPacket : fml2ModListPacket, handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,29 +113,20 @@ public class FML2 {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FML2LoginHandler implements LoginPhaseConnection.MessageConsumer {
|
@AllArgsConstructor
|
||||||
|
private static class FML2LoginHandler implements LoginPhaseConnection.MessageConsumer {
|
||||||
|
|
||||||
private final LoginInboundConnection connection;
|
private final LoginInboundConnection connection;
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
private final boolean forge;
|
private final boolean forge;
|
||||||
|
|
||||||
private FML2LoginHandler(LoginInboundConnection connection, UUID uuid, boolean forge) {
|
|
||||||
this.connection = connection;
|
|
||||||
this.uuid = uuid;
|
|
||||||
this.forge = forge;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SteamWar Forge Handler";
|
return "SteamWar Forge Handler";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void abort(byte[] response, String error) {
|
|
||||||
|
|
||||||
VelocityCore.get().getLogger().log(Level.SEVERE, () -> error + "\n" + Base64.getEncoder().encodeToString(response));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessageResponse(byte @Nullable [] data) {
|
public void onMessageResponse(byte[] data) {
|
||||||
if(data == null) {
|
if(data == null) {
|
||||||
abort(null, "Not FML2/3 client");
|
abort(null, "Not FML2/3 client");
|
||||||
return;
|
return;
|
||||||
@ -175,7 +165,12 @@ public class FML2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
modUtils.handleMods(uuid, Locale.getDefault(), connection::disconnect, mods);
|
ModUtils.handleMods(uuid, Locale.getDefault(), connection::disconnect, mods);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void abort(byte[] response, String error) {
|
||||||
|
connection.disconnect(Component.text(error));
|
||||||
|
VelocityCore.getLogger().log(Level.SEVERE, () -> error + "\n" + Base64.getEncoder().encodeToString(response));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,18 +22,15 @@ package de.steamwar.bungeecore.mods;
|
|||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.velocitypowered.api.event.Subscribe;
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
import com.velocitypowered.api.event.player.ServerConnectedEvent;
|
import com.velocitypowered.api.event.player.ServerConnectedEvent;
|
||||||
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
|
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.proxy.ProxyServer;
|
|
||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
|
||||||
import de.steamwar.bungeecore.Storage;
|
import de.steamwar.bungeecore.Storage;
|
||||||
import de.steamwar.bungeecore.util.annotations.Create;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
|
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||||
import de.steamwar.sql.Mod;
|
import de.steamwar.sql.Mod;
|
||||||
import de.steamwar.sql.SWException;
|
import de.steamwar.sql.SWException;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
@ -43,19 +40,12 @@ import io.netty.buffer.Unpooled;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Create
|
public class FabricModSender extends BasicListener {
|
||||||
public class FabricModSender {
|
|
||||||
|
|
||||||
private final ModUtils utils;
|
|
||||||
private final ProxyServer proxyServer;
|
|
||||||
|
|
||||||
private final Set<String> neededFabricMods = new HashSet<>();
|
private final Set<String> neededFabricMods = new HashSet<>();
|
||||||
private final Set<String> neededQuiltMods = new HashSet<>();
|
private final Set<String> neededQuiltMods = new HashSet<>();
|
||||||
|
|
||||||
@Inject
|
public FabricModSender() {
|
||||||
public FabricModSender(ModUtils utils) {
|
|
||||||
this.utils = utils;
|
|
||||||
this.proxyServer = VelocityCore.getProxy();
|
|
||||||
neededFabricMods.add("java");
|
neededFabricMods.add("java");
|
||||||
neededFabricMods.add("minecraft");
|
neededFabricMods.add("minecraft");
|
||||||
neededFabricMods.add("steamwarmodsender");
|
neededFabricMods.add("steamwarmodsender");
|
||||||
@ -64,7 +54,7 @@ public class FabricModSender {
|
|||||||
neededFabricMods.add("fabricloader");
|
neededFabricMods.add("fabricloader");
|
||||||
neededQuiltMods.add("quilt_loader");
|
neededQuiltMods.add("quilt_loader");
|
||||||
|
|
||||||
proxyServer.getScheduler().buildTask(VelocityCore.get(), () -> {
|
VelocityCore.schedule(() -> {
|
||||||
synchronized (Storage.fabricExpectPluginMessage) {
|
synchronized (Storage.fabricExpectPluginMessage) {
|
||||||
for (Map.Entry<Player, Long> entry : Storage.fabricExpectPluginMessage.entrySet()) {
|
for (Map.Entry<Player, Long> entry : Storage.fabricExpectPluginMessage.entrySet()) {
|
||||||
if (!Storage.fabricCheckedPlayers.containsKey(entry.getKey())) {
|
if (!Storage.fabricCheckedPlayers.containsKey(entry.getKey())) {
|
||||||
@ -76,7 +66,7 @@ public class FabricModSender {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).repeat(1, TimeUnit.SECONDS);
|
}).repeat(1, TimeUnit.SECONDS).schedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handlePluginMessage(PluginMessageEvent e){
|
public void handlePluginMessage(PluginMessageEvent e){
|
||||||
@ -113,7 +103,7 @@ public class FabricModSender {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!utils.handleMods(player,mods))
|
if(!ModUtils.handleMods(player,mods))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!Storage.fabricCheckedPlayers.containsKey(player)) {
|
if (!Storage.fabricCheckedPlayers.containsKey(player)) {
|
||||||
|
@ -22,13 +22,12 @@ package de.steamwar.bungeecore.mods;
|
|||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
|
||||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
|
|
||||||
public class Feather {
|
public class Feather {
|
||||||
//https://github.com/Koupah/Feather-Client-API/blob/main/src/club/koupah/feather/packets/FeatherMod.java
|
//https://github.com/Koupah/Feather-Client-API/blob/main/src/club/koupah/feather/packets/FeatherMod.java
|
||||||
//https://archive.org/details/feather-server-api
|
//https://archive.org/details/feather-server-api
|
||||||
public static final ChannelIdentifier CHANNEL = MinecraftChannelIdentifier.from("feather:client");
|
public static final String CHANNEL = "feather:client";
|
||||||
|
|
||||||
private final byte[] packet;
|
private final byte[] packet;
|
||||||
public Feather() {
|
public Feather() {
|
||||||
@ -53,6 +52,6 @@ public class Feather {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void sendRestrictions(Player player) {
|
public void sendRestrictions(Player player) {
|
||||||
player.sendPluginMessage(CHANNEL, packet);
|
player.sendPluginMessage(MinecraftChannelIdentifier.from(CHANNEL), packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,18 +20,37 @@
|
|||||||
package de.steamwar.bungeecore.mods;
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
import com.velocitypowered.api.event.Subscribe;
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
|
import com.velocitypowered.api.event.connection.ConnectionHandshakeEvent;
|
||||||
|
import com.velocitypowered.proxy.connection.client.InitialInboundConnection;
|
||||||
|
import com.velocitypowered.proxy.connection.client.LoginInboundConnection;
|
||||||
|
import com.velocitypowered.proxy.protocol.packet.HandshakePacket;
|
||||||
|
import de.steamwar.bungeecore.Reflection;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.util.annotations.Create;
|
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
@Create
|
public class Hostname extends BasicListener {
|
||||||
public class Hostname {
|
|
||||||
|
private static final Reflection.Field<LoginInboundConnection, InitialInboundConnection> delegate = Reflection.getField(LoginInboundConnection.class, "delegate");
|
||||||
|
public static InitialInboundConnection getInitialInboundConnection(LoginInboundConnection loginInboundConnection) {
|
||||||
|
return delegate.get(loginInboundConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Reflection.Field<InitialInboundConnection, HandshakePacket> handshake = Reflection.getField(InitialInboundConnection.class, "handshake");
|
||||||
|
public static String getExtraHandshakeData(LoginInboundConnection loginInboundConnection) {
|
||||||
|
HandshakePacket handshakePacket = handshake.get(getInitialInboundConnection(loginInboundConnection));
|
||||||
|
int i = handshakePacket.getServerAddress().indexOf('\0');
|
||||||
|
if(i == -1)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
return handshakePacket.getServerAddress().substring(i);
|
||||||
|
}
|
||||||
|
|
||||||
private final Set<String> knownHostnames = new HashSet<>();
|
private final Set<String> knownHostnames = new HashSet<>();
|
||||||
|
private final Set<String> knownExtraData = new HashSet<>();
|
||||||
|
|
||||||
public Hostname() {
|
public Hostname() {
|
||||||
knownHostnames.add("steamwar.de");
|
knownHostnames.add("steamwar.de");
|
||||||
@ -44,13 +63,22 @@ public class Hostname {
|
|||||||
knownHostnames.add("wtf.mynx.lol"); //https://discord.com/invite/serverseeker
|
knownHostnames.add("wtf.mynx.lol"); //https://discord.com/invite/serverseeker
|
||||||
knownHostnames.add("masscan");
|
knownHostnames.add("masscan");
|
||||||
knownHostnames.add("aaa");
|
knownHostnames.add("aaa");
|
||||||
|
|
||||||
|
knownExtraData.add("");
|
||||||
|
knownExtraData.add("\0FML\0");
|
||||||
|
knownExtraData.add("\0FML2\0");
|
||||||
|
knownExtraData.add("\0FML3\0");
|
||||||
|
knownExtraData.add("\0FORGE");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onHandshake(ProxyPingEvent event) {
|
public void onHandshake(ConnectionHandshakeEvent event) {
|
||||||
String hostname = event.getConnection().getVirtualHost().map(inetSocketAddress -> inetSocketAddress.getHostName()).orElse("");
|
String hostname = event.getConnection().getVirtualHost().orElseThrow().getHostName().toLowerCase();
|
||||||
if (!knownHostnames.contains(hostname) && !hostname.endsWith(".steamwar.de")) {
|
if (!knownHostnames.contains(hostname) && !hostname.endsWith(".steamwar.de"))
|
||||||
VelocityCore.get().getLogger().log(Level.WARNING, () -> event.getConnection().getRemoteAddress().toString() + " connected with unknown hostname '" + hostname + "'");
|
VelocityCore.getLogger().log(Level.WARNING, () -> event.getConnection().getRemoteAddress() + " connected with unknown hostname " + hostname);
|
||||||
}
|
|
||||||
|
String extraData = getExtraHandshakeData((LoginInboundConnection) event.getConnection());
|
||||||
|
if (!knownExtraData.contains(extraData))
|
||||||
|
VelocityCore.getLogger().log(Level.WARNING, () -> event.getConnection().getRemoteAddress() + " connected with unknown extra data " + extraData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ import com.velocitypowered.api.proxy.Player;
|
|||||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.listeners.PluginMessage;
|
import de.steamwar.bungeecore.listeners.PluginMessage;
|
||||||
import de.steamwar.bungeecore.util.annotations.Create;
|
|
||||||
import de.steamwar.sql.Mod;
|
import de.steamwar.sql.Mod;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
@ -36,17 +35,13 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
@Create
|
|
||||||
public class LabyMod {
|
public class LabyMod {
|
||||||
// https://docs.labymod.net/pages/server/introduction/
|
// https://docs.labymod.net/pages/server/introduction/
|
||||||
// https://github.com/LabyMod/labymod-server-api
|
// https://github.com/LabyMod/labymod-server-api
|
||||||
// https://dl.labymod.net/addons.json
|
// https://dl.labymod.net/addons.json
|
||||||
|
|
||||||
private final ModUtils utils;
|
|
||||||
|
|
||||||
private final byte[] gameInfoPacket;
|
private final byte[] gameInfoPacket;
|
||||||
public LabyMod(ModUtils utils) {
|
public LabyMod() {
|
||||||
this.utils = utils;
|
|
||||||
gameInfoPacket = PluginMessage.genBufPacket(buf -> {
|
gameInfoPacket = PluginMessage.genBufPacket(buf -> {
|
||||||
ProtocolUtils.writeString(buf, "discord_rpc");
|
ProtocolUtils.writeString(buf, "discord_rpc");
|
||||||
|
|
||||||
@ -79,7 +74,7 @@ public class LabyMod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(message.has("mods")) {
|
if(message.has("mods")) {
|
||||||
VelocityCore.get().getLogger().log(Level.WARNING, () -> "LabyMod External Mods for debugging: " + message.getAsJsonArray("mods"));
|
VelocityCore.getLogger().log(Level.WARNING, () -> "LabyMod External Mods for debugging: " + message.getAsJsonArray("mods"));
|
||||||
for(JsonElement element : message.getAsJsonArray("mods")) {
|
for(JsonElement element : message.getAsJsonArray("mods")) {
|
||||||
JsonObject addon = element.getAsJsonObject();
|
JsonObject addon = element.getAsJsonObject();
|
||||||
//TODO observe: FORGE and FABRIC mods available, do they always and with .jar? (would equal new mod platform)
|
//TODO observe: FORGE and FABRIC mods available, do they always and with .jar? (would equal new mod platform)
|
||||||
@ -87,6 +82,6 @@ public class LabyMod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.handleMods(player, mods);
|
ModUtils.handleMods(player, mods);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,10 +34,8 @@ import com.lunarclient.apollo.player.v1.ModMessage;
|
|||||||
import com.lunarclient.apollo.player.v1.PlayerHandshakeMessage;
|
import com.lunarclient.apollo.player.v1.PlayerHandshakeMessage;
|
||||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
|
||||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.util.annotations.Create;
|
|
||||||
import de.steamwar.sql.Mod;
|
import de.steamwar.sql.Mod;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
@ -47,16 +45,13 @@ import java.util.UUID;
|
|||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
@Create
|
|
||||||
public class Lunar {
|
public class Lunar {
|
||||||
// https://lunarclient.dev/apollo/introduction
|
// https://lunarclient.dev/apollo/introduction
|
||||||
// https://github.com/LunarClient/Apollo
|
// https://github.com/LunarClient/Apollo
|
||||||
|
|
||||||
private final ApolloModuleManager manager = new ApolloModuleManagerImpl().addModule(ModSettingModule.class);
|
private final ApolloModuleManager manager = new ApolloModuleManagerImpl().addModule(ModSettingModule.class);
|
||||||
|
|
||||||
private final ModUtils utils;
|
public Lunar() { //TODO seems defunct
|
||||||
|
|
||||||
public Lunar(ModUtils utils) { //TODO seems defunct
|
|
||||||
Options modSettings = manager.getModule(ModSettingModule.class).getOptions();
|
Options modSettings = manager.getModule(ModSettingModule.class).getOptions();
|
||||||
modSettings.set(ModReplaymod.ENABLED, false); // TODO check if restrictions working
|
modSettings.set(ModReplaymod.ENABLED, false); // TODO check if restrictions working
|
||||||
modSettings.set(ModFreelook.ENABLED, false);
|
modSettings.set(ModFreelook.ENABLED, false);
|
||||||
@ -66,8 +61,6 @@ public class Lunar {
|
|||||||
modSettings.set(ModTeamView.ENABLED, false);
|
modSettings.set(ModTeamView.ENABLED, false);
|
||||||
modSettings.set(ModTntCountdown.ENABLED, false);
|
modSettings.set(ModTntCountdown.ENABLED, false);
|
||||||
modSettings.set(ModToggleSneak.TOGGLE_SNEAK_CONTAINER, false);
|
modSettings.set(ModToggleSneak.TOGGLE_SNEAK_CONTAINER, false);
|
||||||
|
|
||||||
this.utils = utils;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendRestrictions(Player player) {
|
public void sendRestrictions(Player player) {
|
||||||
@ -102,12 +95,12 @@ public class Lunar {
|
|||||||
case TYPE_UNSPECIFIED:
|
case TYPE_UNSPECIFIED:
|
||||||
case UNRECOGNIZED:
|
case UNRECOGNIZED:
|
||||||
default:
|
default:
|
||||||
VelocityCore.get().getLogger().log(Level.INFO, () -> player.getUsername() + " uses Lunar mod with unknown type " + mod);
|
VelocityCore.getLogger().log(Level.INFO, () -> player.getUsername() + " uses Lunar mod with unknown type " + mod);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.handleMods(player, mods);
|
ModUtils.handleMods(player, mods);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,8 +113,6 @@ public class Lunar {
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
private static class SWApolloPlayer extends AbstractApolloPlayer {
|
private static class SWApolloPlayer extends AbstractApolloPlayer {
|
||||||
|
|
||||||
private static final ChannelIdentifier CHANNEL = MinecraftChannelIdentifier.from(ApolloManager.PLUGIN_MESSAGE_CHANNEL);
|
|
||||||
|
|
||||||
private final Player player;
|
private final Player player;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -131,7 +122,7 @@ public class Lunar {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendPacket(byte[] bytes) {
|
public void sendPacket(byte[] bytes) {
|
||||||
player.sendPluginMessage(CHANNEL, bytes);
|
player.sendPluginMessage(MinecraftChannelIdentifier.from(ApolloManager.PLUGIN_MESSAGE_CHANNEL), bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public UUID getUniqueId() { return player.getUniqueId(); }
|
@Override public UUID getUniqueId() { return player.getUniqueId(); }
|
||||||
|
@ -22,12 +22,13 @@ package de.steamwar.bungeecore.mods;
|
|||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.commands.PunishmentCommand;
|
import de.steamwar.bungeecore.commands.PunishmentCommand;
|
||||||
import de.steamwar.messages.Message;
|
import de.steamwar.messages.Chatter;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
|
||||||
import de.steamwar.sql.Mod;
|
import de.steamwar.sql.Mod;
|
||||||
import de.steamwar.sql.Mod.ModType;
|
import de.steamwar.sql.Mod.ModType;
|
||||||
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.sql.UserPerm;
|
import de.steamwar.sql.UserPerm;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
|
||||||
@ -37,27 +38,23 @@ import java.time.temporal.ChronoUnit;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
public class ModUtils {
|
public class ModUtils {
|
||||||
private final Logger logger;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final Map<UUID,List<Mod>> playerModMap = new HashMap<>();
|
private static final Map<UUID,List<Mod>> playerModMap = new HashMap<>();
|
||||||
|
|
||||||
public ModUtils() {
|
public static boolean handleMods(Player player, List<Mod> mods) {
|
||||||
this.logger = VelocityCore.getLogger();
|
return handleMods(player.getUniqueId(), Chatter.of(player).getLocale(), player::disconnect, mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean handleMods(Player player, List<Mod> mods) {
|
public static boolean handleMods(UUID uuid, Locale locale, Consumer<Component> disconnect, List<Mod> mods){
|
||||||
return handleMods(player.getUniqueId(), ChatSender.of(player).getLocale(), player::disconnect, mods);
|
Chatter sender = Chatter.of(uuid);
|
||||||
}
|
SteamwarUser user = sender.user();
|
||||||
|
|
||||||
public boolean handleMods(UUID uuid, Locale locale, Consumer<Component> disconnect, List<Mod> mods){
|
|
||||||
SteamwarUser user = SteamwarUser.get(uuid);
|
|
||||||
playerModMap.put(uuid,new ArrayList<>(mods));
|
playerModMap.put(uuid,new ArrayList<>(mods));
|
||||||
VelocityCore.get().getLogger().log(Level.INFO, user.getUserName() + " declares mods: " + mods.stream().map(mod -> mod.getPlatform() + ":" + mod.getModName()).collect(Collectors.joining(" ")));
|
VelocityCore.getLogger().log(Level.INFO, user.getUserName() + " declares mods: " + mods.stream().map(mod -> mod.getPlatform() + ":" + mod.getModName()).collect(Collectors.joining(" ")));
|
||||||
|
|
||||||
ModType max = ModType.YELLOW;
|
ModType max = ModType.YELLOW;
|
||||||
Iterator<Mod> it = mods.iterator();
|
Iterator<Mod> it = mods.iterator();
|
||||||
@ -79,14 +76,14 @@ public class ModUtils {
|
|||||||
String message;
|
String message;
|
||||||
|
|
||||||
if(mods.size() == 1) {
|
if(mods.size() == 1) {
|
||||||
message = Message.parse(max == ModType.RED ? "MOD_RED_SING" : "MOD_YELLOW_SING", locale, modList);
|
message = sender.parseToLegacy(max == ModType.RED ? "MOD_RED_SING" : "MOD_YELLOW_SING", locale, modList);
|
||||||
} else {
|
} else {
|
||||||
message = Message.parse(max == ModType.RED ? "MOD_RED_PLUR" : "MOD_YELLOW_PLUR", locale, modList);
|
message = sender.parseToLegacy(max == ModType.RED ? "MOD_RED_PLUR" : "MOD_YELLOW_PLUR", locale, modList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(max == ModType.RED) {
|
if(max == ModType.RED) {
|
||||||
PunishmentCommand.ban(user, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), message, SteamwarUser.get(-1), false);
|
PunishmentCommand.ban(user, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), message, SteamwarUser.get(-1), false);
|
||||||
logger.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen der Mods " + modList + " gebannt.");
|
VelocityCore.getLogger().log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen der Mods " + modList + " gebannt.");
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnect.accept(LegacyComponentSerializer.legacySection().deserialize(message));
|
disconnect.accept(LegacyComponentSerializer.legacySection().deserialize(message));
|
||||||
|
@ -19,17 +19,15 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.mods;
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.event.Subscribe;
|
||||||
|
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import de.steamwar.bungeecore.Bauserver;
|
import de.steamwar.bungeecore.Bauserver;
|
||||||
import de.steamwar.bungeecore.Builderserver;
|
import de.steamwar.bungeecore.Builderserver;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.Subserver;
|
import de.steamwar.bungeecore.Subserver;
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||||
import de.steamwar.bungeecore.listeners.PluginMessage;
|
import de.steamwar.bungeecore.listeners.PluginMessage;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
import net.md_5.bungee.api.config.ServerInfo;
|
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
|
||||||
import net.md_5.bungee.api.event.ServerSwitchEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@ -51,15 +49,14 @@ public class ReplayMod extends BasicListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@Subscribe
|
||||||
public void onPlayerJoin(ServerSwitchEvent event) {
|
public void onPlayerJoin(ServerPostConnectEvent event) {
|
||||||
ProxiedPlayer player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
ServerInfo server = player.getServer().getInfo();
|
if(VelocityCore.get().getConfig().lobbyserver().getPlayersConnected().contains(player))
|
||||||
if(ProxyServer.getInstance().getServerInfo(VelocityCore.LOBBY_SERVER) == server)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Subserver subserver = Subserver.getSubserver(server);
|
Subserver subserver = Subserver.getSubserver(player.getCurrentServer().orElseThrow().getServerInfo());
|
||||||
if(subserver instanceof Builderserver || (subserver instanceof Bauserver && ((Bauserver) subserver).getOwner().equals(player.getUniqueId())))
|
if(subserver instanceof Builderserver || (subserver instanceof Bauserver bauserver && bauserver.getOwner().equals(player.getUniqueId())))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PluginMessage.send(player, "Replay|Restrict", "replaymod:restrict", restrict);
|
PluginMessage.send(player, "Replay|Restrict", "replaymod:restrict", restrict);
|
||||||
|
@ -20,37 +20,33 @@
|
|||||||
package de.steamwar.bungeecore.mods;
|
package de.steamwar.bungeecore.mods;
|
||||||
|
|
||||||
import com.google.gson.*;
|
import com.google.gson.*;
|
||||||
import com.velocitypowered.api.proxy.ProxyServer;
|
|
||||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
public class ServerListPing {
|
@AllArgsConstructor
|
||||||
|
public class ServerListPing implements JsonSerializer<ServerPing>, JsonDeserializer<ServerPing> {
|
||||||
// https://github.com/Aizistral-Studios/No-Chat-Reports/discussions/206
|
// https://github.com/Aizistral-Studios/No-Chat-Reports/discussions/206
|
||||||
// https://github.com/Aizistral-Studios/No-Chat-Reports/wiki/How-to-Get-Safe-Server-Status
|
// https://github.com/Aizistral-Studios/No-Chat-Reports/wiki/How-to-Get-Safe-Server-Status
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
private final ProxyServer proxyServer;
|
|
||||||
|
|
||||||
private static final String[] FIELDS_TO_OVERRIDE = new String[] {
|
private static final String[] FIELDS_TO_OVERRIDE = new String[] {
|
||||||
"PRE_1_16_PING_SERIALIZER",
|
"PRE_1_16_PING_SERIALIZER",
|
||||||
"PRE_1_20_3_PING_SERIALIZER",
|
"PRE_1_20_3_PING_SERIALIZER",
|
||||||
"MODERN_PING_SERIALIZER"
|
"MODERN_PING_SERIALIZER"
|
||||||
};
|
};
|
||||||
|
|
||||||
public ServerListPing() {
|
public static void init() {
|
||||||
this.proxyServer = VelocityCore.getProxy();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (String fieldName : FIELDS_TO_OVERRIDE) {
|
for (String fieldName : FIELDS_TO_OVERRIDE) {
|
||||||
Field field = proxyServer.getClass().getDeclaredField(fieldName);
|
Field field = VelocityCore.getProxy().getClass().getDeclaredField(fieldName);
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
Object obj = field.get(null);
|
Object obj = field.get(null);
|
||||||
if (obj instanceof Gson gsonOld) {
|
if (obj instanceof Gson gsonOld) {
|
||||||
Gson gsonNew = new GsonBuilder()
|
Gson gsonNew = new GsonBuilder()
|
||||||
.registerTypeAdapter(ServerPing.class, new ServerListPingSerializer(gsonOld))
|
.registerTypeAdapter(ServerPing.class, new ServerListPing(gsonOld))
|
||||||
.create();
|
.create();
|
||||||
field.set(null, gsonNew);
|
field.set(null, gsonNew);
|
||||||
} else {
|
} else {
|
||||||
@ -62,8 +58,7 @@ public class ServerListPing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private record ServerListPingSerializer(
|
private final Gson gson;
|
||||||
Gson gson) implements JsonSerializer<ServerPing>, JsonDeserializer<ServerPing> {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JsonElement serialize(ServerPing ping, Type type, JsonSerializationContext context) {
|
public JsonElement serialize(ServerPing ping, Type type, JsonSerializationContext context) {
|
||||||
@ -80,4 +75,3 @@ public class ServerListPing {
|
|||||||
return gson.fromJson(element, ServerPing.class);
|
return gson.fromJson(element, ServerPing.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -29,7 +29,6 @@ import de.steamwar.network.packets.PacketHandler;
|
|||||||
import de.steamwar.network.packets.common.FightInfoPacket;
|
import de.steamwar.network.packets.common.FightInfoPacket;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class FightInfoHandler extends PacketHandler {
|
public class FightInfoHandler extends PacketHandler {
|
||||||
@ -46,22 +45,13 @@ public class FightInfoHandler extends PacketHandler {
|
|||||||
|
|
||||||
@Handler
|
@Handler
|
||||||
public void handle(FightInfoPacket packet) {
|
public void handle(FightInfoPacket packet) {
|
||||||
RegisteredServer info = ((ServerMetaInfo) packet.getMetaInfos()).getSender().getServer();
|
ServerInfo info = ((ServerMetaInfo) packet.getMetaInfos()).getSender().getServerInfo();
|
||||||
|
|
||||||
FightInfoPacket lobbyPacket = packet.withServerName(info.getServerInfo().getName());
|
FightInfoPacket lobbyPacket = packet.withServerName(info.getName());
|
||||||
|
|
||||||
TablistManager.newFightInfo(info, packet);
|
TablistManager.newFightInfo(info, packet);
|
||||||
|
|
||||||
Iterator<RegisteredServer> lobbyIt = lobbys.iterator();
|
lobbys.removeIf(server -> server.getPlayersConnected().isEmpty());
|
||||||
while(lobbyIt.hasNext()) {
|
lobbys.forEach(lobby -> NetworkSender.send(lobby, lobbyPacket));
|
||||||
RegisteredServer lobby = lobbyIt.next();
|
|
||||||
Iterator<Player> it = lobby.getPlayersConnected().iterator();
|
|
||||||
if(!it.hasNext()){
|
|
||||||
lobbyIt.remove();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworkSender.send(lobby, lobbyPacket);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ import de.steamwar.network.packets.PacketHandler;
|
|||||||
import de.steamwar.network.packets.client.PrepareSchemPacket;
|
import de.steamwar.network.packets.client.PrepareSchemPacket;
|
||||||
import de.steamwar.sql.SchematicType;
|
import de.steamwar.sql.SchematicType;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
|
||||||
|
|
||||||
public class PrepareSchemHandler extends PacketHandler {
|
public class PrepareSchemHandler extends PacketHandler {
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public class TablistManager extends BasicListener {
|
|||||||
private int seconds = 0;
|
private int seconds = 0;
|
||||||
|
|
||||||
public TablistManager() {
|
public TablistManager() {
|
||||||
VelocityCore.schedule(this::updateTablist).repeat(1, TimeUnit.SECONDS);
|
VelocityCore.schedule(this::updateTablist).repeat(1, TimeUnit.SECONDS).schedule();
|
||||||
synchronized (tablists) {
|
synchronized (tablists) {
|
||||||
VelocityCore.getProxy().getAllPlayers().forEach(player -> tablists.put(player, new Tablist(player)));
|
VelocityCore.getProxy().getAllPlayers().forEach(player -> tablists.put(player, new Tablist(player)));
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.tablist;
|
package de.steamwar.bungeecore.tablist;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
import de.steamwar.sql.SteamwarUser;
|
import de.steamwar.sql.SteamwarUser;
|
||||||
import de.steamwar.sql.UserPerm;
|
import de.steamwar.sql.UserPerm;
|
||||||
@ -34,11 +35,11 @@ import java.util.UUID;
|
|||||||
|
|
||||||
interface TablistPart {
|
interface TablistPart {
|
||||||
String sortKey();
|
String sortKey();
|
||||||
void print(Chatter viewer, ProxiedPlayer player, List<Item> tablist, List<Item> direct);
|
void print(Chatter viewer, Player player, List<Item> tablist, List<Item> direct);
|
||||||
|
|
||||||
class Item {
|
class Item {
|
||||||
|
|
||||||
public static Property[] playerProperties(ProxiedPlayer player) {
|
public static Property[] playerProperties(Player player) {
|
||||||
LoginResult loginResult = ((InitialHandler) player.getPendingConnection()).getLoginProfile();
|
LoginResult loginResult = ((InitialHandler) player.getPendingConnection()).getLoginProfile();
|
||||||
if(loginResult == null)
|
if(loginResult == null)
|
||||||
return new Property[0];
|
return new Property[0];
|
||||||
|
@ -21,10 +21,10 @@ package de.steamwar.command;
|
|||||||
|
|
||||||
import com.velocitypowered.api.command.SimpleCommand;
|
import com.velocitypowered.api.command.SimpleCommand;
|
||||||
import de.steamwar.bungeecore.VelocityCore;
|
import de.steamwar.bungeecore.VelocityCore;
|
||||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
|
||||||
import de.steamwar.messages.Message;
|
|
||||||
import de.steamwar.bungeecore.discord.DiscordBot;
|
import de.steamwar.bungeecore.discord.DiscordBot;
|
||||||
import de.steamwar.messages.Chatter;
|
import de.steamwar.messages.Chatter;
|
||||||
|
import de.steamwar.messages.Message;
|
||||||
|
import de.steamwar.sql.UserPerm;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.kyori.adventure.text.event.ClickEvent;
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
|
|
||||||
@ -43,22 +43,18 @@ public class SWCommand extends AbstractSWCommand<Chatter> {
|
|||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
@Getter
|
@Getter
|
||||||
private final String permission;
|
private final UserPerm permission;
|
||||||
private final String[] aliases;
|
private final String[] aliases;
|
||||||
|
|
||||||
private SimpleCommand command;
|
private SimpleCommand command;
|
||||||
|
|
||||||
private final List<String> defaultHelpMessages = new ArrayList<>();
|
private final List<String> defaultHelpMessages = new ArrayList<>();
|
||||||
|
|
||||||
protected SWCommand(String command) {
|
protected SWCommand(String command, String... aliases) {
|
||||||
this(command, null);
|
this(command, null, aliases);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SWCommand(String command, String permission) {
|
protected SWCommand(String command, UserPerm permission, String... aliases) {
|
||||||
this(command, permission, new String[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected SWCommand(String command, String permission, String... aliases) {
|
|
||||||
super(Chatter.class, command, aliases);
|
super(Chatter.class, command, aliases);
|
||||||
this.name = command;
|
this.name = command;
|
||||||
this.permission = permission;
|
this.permission = permission;
|
||||||
@ -92,8 +88,7 @@ public class SWCommand extends AbstractSWCommand<Chatter> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPermission(Invocation invocation) {
|
public boolean hasPermission(Invocation invocation) {
|
||||||
//TODO nicer solution?
|
return permission == null || Chatter.of(invocation.source()).user().perms().contains(permission);
|
||||||
return permission != null && Chatter.of(invocation.source()).user().perms().stream().noneMatch(perm -> Arrays.asList(ConnectionListener.getCommandPermissions().getOrDefault(perm, new String[0])).contains(permission));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren