diff --git a/bans-api/src/main/java/space/arim/libertybans/api/select/PunishmentSelector.java b/bans-api/src/main/java/space/arim/libertybans/api/select/PunishmentSelector.java
index 0e2bb1c44..bf6709bfa 100644
--- a/bans-api/src/main/java/space/arim/libertybans/api/select/PunishmentSelector.java
+++ b/bans-api/src/main/java/space/arim/libertybans/api/select/PunishmentSelector.java
@@ -1,6 +1,6 @@
/*
* LibertyBans
- * Copyright © 2022 Anand Beh
+ * Copyright © 2024 Anand Beh
*
* LibertyBans is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -77,6 +77,9 @@ public interface PunishmentSelector {
* the player's UUID and IP. It may be, the player's IP is banned, the player's UUID is banned,
* or the player has played on a banned IP and that IP is banned while strict address enforcement is enabled.
*
+ * For maximum accuracy, the UUID and IP address pair should be taken from an actual user who has logged on before.
+ * Due to specifics in terms of how applicability is computed, some punishments
+ *
* By default, the server's configured address strictness is used, but this may be changed if desired.
*
* @param uuid the uuid of the user for whom to select applicable punishments
diff --git a/bans-core/src/main/java/space/arim/libertybans/core/database/sql/ApplicableViewFields.java b/bans-core/src/main/java/space/arim/libertybans/core/database/sql/ApplicableViewFields.java
index 2933361c4..9f42c0a15 100644
--- a/bans-core/src/main/java/space/arim/libertybans/core/database/sql/ApplicableViewFields.java
+++ b/bans-core/src/main/java/space/arim/libertybans/core/database/sql/ApplicableViewFields.java
@@ -1,6 +1,6 @@
/*
* LibertyBans
- * Copyright © 2023 Anand Beh
+ * Copyright © 2024 Anand Beh
*
* LibertyBans is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -31,7 +31,6 @@
import space.arim.libertybans.core.scope.ScopeType;
import java.time.Instant;
-import java.util.Objects;
import java.util.UUID;
public record ApplicableViewFields scopeType() {
}
public Field uuid() {
- return Objects.requireNonNull(fieldSupplier.field11(), "uuid field does not exist");
+ return fieldSupplier.field11();
+ }
+
+ public Field address() {
+ return fieldSupplier.field12();
}
}
diff --git a/bans-core/src/main/java/space/arim/libertybans/core/selector/EnforcementConfig.java b/bans-core/src/main/java/space/arim/libertybans/core/selector/EnforcementConfig.java
index fe27bc98d..083c88b70 100644
--- a/bans-core/src/main/java/space/arim/libertybans/core/selector/EnforcementConfig.java
+++ b/bans-core/src/main/java/space/arim/libertybans/core/selector/EnforcementConfig.java
@@ -1,6 +1,6 @@
/*
* LibertyBans
- * Copyright © 2022 Anand Beh
+ * Copyright © 2024 Anand Beh
*
* LibertyBans is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -19,6 +19,7 @@
package space.arim.libertybans.core.selector;
+import java.util.List;
import java.util.Set;
import space.arim.dazzleconf.annote.ConfComments;
@@ -138,4 +139,29 @@ interface AltAccountExpiration {
long expirationTimeDays();
}
+
+ @ConfKey("alts-registry")
+ @SubSection
+ AltsRegistry altsRegistry();
+
+ @ConfHeader({"Controls if all servers should register the IP address of the player connecting."})
+ interface AltsRegistry {
+
+ @ConfComments({"The server names in this list will be excluded from associating the IP address of the player connecting.",
+ "Please note that the server's name in the list should be the same as the ones in your proxy configuration.",
+ "This is intended to be used by LibertyBans proxy installations.",
+ "If you are planning to use this feature, you MUST enable the 'enforce-server-switch' option."
+ })
+ @ConfKey("servers-without-ip-registration")
+ @DefaultStrings({"auth"})
+ List serversWithoutRegistration();
+
+ @ConfComments({"If you want to register the IP address of the player connecting, set this to true.",
+ "If you are running a proxy and don't want to register the IP when players connect, ",
+ "set this to false and add the authentication servers' names in the list above.",
+ "If this is a backend server, set it to false; if it's an authentication server, set to true."})
+ @ConfKey("should-register-on-connection)")
+ @ConfDefault.DefaultBoolean(true)
+ boolean shouldRegisterOnConnection();
+ }
}
diff --git a/bans-core/src/main/java/space/arim/libertybans/core/selector/Gatekeeper.java b/bans-core/src/main/java/space/arim/libertybans/core/selector/Gatekeeper.java
index a47fadb97..55d0f4c56 100644
--- a/bans-core/src/main/java/space/arim/libertybans/core/selector/Gatekeeper.java
+++ b/bans-core/src/main/java/space/arim/libertybans/core/selector/Gatekeeper.java
@@ -1,6 +1,6 @@
/*
* LibertyBans
- * Copyright © 2023 Anand Beh
+ * Copyright © 2024 Anand Beh
*
* LibertyBans is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -22,6 +22,8 @@
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import net.kyori.adventure.text.Component;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.jooq.DSLContext;
import space.arim.libertybans.api.NetworkAddress;
import space.arim.libertybans.api.PunishmentType;
import space.arim.libertybans.api.punish.Punishment;
@@ -74,14 +76,17 @@ CentralisedFuture executeAndCheckConnection(UUID uuid, String name, N
Set scopes, SelectorImpl selector) {
return queryExecutor.get().queryWithRetry((context, transaction) -> {
Instant currentTime = time.currentTimestamp();
+ EnforcementConfig config = configs.getMainConfig().enforcement();
- Association association = new Association(uuid, context);
- association.associateCurrentName(name, currentTime);
- association.associateCurrentAddress(address, currentTime);
+ boolean recordUserAssociation = config.altsRegistry().shouldRegisterOnConnection();
+ if (recordUserAssociation) {
+ doAssociation(uuid, name, address, currentTime, context);
+ }
Punishment ban = selector.selectionByApplicabilityBuilder(uuid, address)
.type(PunishmentType.BAN)
.scopes(SelectionPredicate.matchingAnyOf(scopes))
+ .canAssumeUserRecorded(recordUserAssociation)
.build()
.findFirstSpecificPunishment(context, () -> currentTime, SortPunishments.LATEST_END_DATE_FIRST);
if (ban != null) {
@@ -113,4 +118,42 @@ CentralisedFuture executeAndCheckConnection(UUID uuid, String name, N
return futuresFactory.completedFuture(null);
});
}
+
+ public CentralisedFuture<@Nullable Component> checkServerSwitch(UUID uuid, String name, NetworkAddress address,
+ String destinationServer, ServerScope serverScope,
+ SelectorImpl selector) {
+ if (!configs.getMainConfig().platforms().proxies().enforceServerSwitch()) {
+ return null;
+ }
+
+ return queryExecutor.get().queryWithRetry((context, transaction) -> {
+ Instant currentTime = time.currentTimestamp();
+ var altsRegistry = configs.getMainConfig().enforcement().altsRegistry();
+ boolean registerOnConnection = altsRegistry.shouldRegisterOnConnection();
+ List serversWithoutAssociation = altsRegistry.serversWithoutRegistration();
+
+ if (!registerOnConnection && !serversWithoutAssociation.contains(destinationServer)) {
+ doAssociation(uuid, name, address, currentTime, context);
+ }
+
+ return selector.selectionByApplicabilityBuilder(uuid, address)
+ .type(PunishmentType.BAN)
+ .scopes(SelectionPredicate.matchingOnly(serverScope))
+ .build()
+ .findFirstSpecificPunishment(context, () -> currentTime, SortPunishments.LATEST_END_DATE_FIRST);
+ }).thenCompose((punishment) -> {
+ if (punishment != null) {
+ return formatter.getPunishmentMessage(punishment);
+ } else {
+ return futuresFactory.completedFuture(null);
+ }
+ });
+ }
+
+ private void doAssociation(UUID uuid, String name, NetworkAddress address,
+ Instant currentTime, DSLContext context) {
+ Association association = new Association(uuid, context);
+ association.associateCurrentName(name, currentTime);
+ association.associateCurrentAddress(address, currentTime);
+ }
}
diff --git a/bans-core/src/main/java/space/arim/libertybans/core/selector/Guardian.java b/bans-core/src/main/java/space/arim/libertybans/core/selector/Guardian.java
index 488bcd127..14c20e01e 100644
--- a/bans-core/src/main/java/space/arim/libertybans/core/selector/Guardian.java
+++ b/bans-core/src/main/java/space/arim/libertybans/core/selector/Guardian.java
@@ -35,9 +35,9 @@ public interface Guardian {
* Adds the uuid and name to the local fast cache, queries for an applicable ban, and formats the
* ban reason as the punishment message.
*
- * @param uuid the player's uuid
- * @param name the player's name
- * @param address the player's network address
+ * @param uuid the player's uuid
+ * @param name the player's name
+ * @param address the player's network address
* @return a future which yields the punishment message if denied, else null if allowed
*/
CentralisedFuture<@Nullable Component> executeAndCheckConnection(UUID uuid, String name, NetworkAddress address);
@@ -63,11 +63,27 @@ public interface Guardian {
* Queries for an applicable ban, and formats the ban reason as the punishment message.
*
* @param uuid the player's uuid
+ * @param name the player's name
* @param address the player's network address
* @param destinationServer the player's destination server
* @return a future which yields the punishment message if denied, else null if allowed
*/
- CentralisedFuture<@Nullable Component> checkServerSwitch(UUID uuid, InetAddress address, String destinationServer);
+ CentralisedFuture<@Nullable Component> checkServerSwitch(UUID uuid, String name, NetworkAddress address, String destinationServer);
+
+ /**
+ * Enforces a server switch, returning a punishment message if denied, null if allowed.
+ *
+ * Queries for an applicable ban, and formats the ban reason as the punishment message.
+ *
+ * @param uuid the player's uuid
+ * @param name the player's name
+ * @param address the player's network address
+ * @param destinationServer the player's destination server
+ * @return a future which yields the punishment message if denied, else null if allowed
+ */
+ default CentralisedFuture<@Nullable Component> checkServerSwitch(UUID uuid, String name, InetAddress address, String destinationServer) {
+ return checkServerSwitch(uuid, name, NetworkAddress.of(address), destinationServer);
+ }
/**
* Enforces a chat message or executed command, returning a punishment message if denied, null if allowed.
diff --git a/bans-core/src/main/java/space/arim/libertybans/core/selector/IntelligentGuardian.java b/bans-core/src/main/java/space/arim/libertybans/core/selector/IntelligentGuardian.java
index 632dfc7c7..ed7510b88 100644
--- a/bans-core/src/main/java/space/arim/libertybans/core/selector/IntelligentGuardian.java
+++ b/bans-core/src/main/java/space/arim/libertybans/core/selector/IntelligentGuardian.java
@@ -24,9 +24,7 @@
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable;
import space.arim.libertybans.api.NetworkAddress;
-import space.arim.libertybans.api.PunishmentType;
import space.arim.libertybans.api.scope.ScopeManager;
-import space.arim.libertybans.api.select.SortPunishments;
import space.arim.libertybans.core.config.Configs;
import space.arim.libertybans.core.config.InternalFormatter;
import space.arim.libertybans.core.selector.cache.MuteCache;
@@ -34,7 +32,6 @@
import space.arim.omnibus.util.concurrent.CentralisedFuture;
import space.arim.omnibus.util.concurrent.FactoryOfTheFuture;
-import java.net.InetAddress;
import java.util.UUID;
import java.util.concurrent.CompletionException;
import java.util.concurrent.TimeUnit;
@@ -98,23 +95,12 @@ private static Function timeoutHandler(String where) {
}
@Override
- public CentralisedFuture<@Nullable Component> checkServerSwitch(UUID uuid, InetAddress address,
+ public CentralisedFuture<@Nullable Component> checkServerSwitch(UUID uuid, String name, NetworkAddress address,
String destinationServer) {
- if (!configs.getMainConfig().platforms().proxies().enforceServerSwitch()) {
- return futuresFactory.completedFuture(null);
- }
return selector
- .selectionByApplicabilityBuilder(uuid, address)
- .type(PunishmentType.BAN)
- .scope(scopeManager.specificScope(destinationServer))
- .build()
- .getFirstSpecificPunishment(SortPunishments.LATEST_END_DATE_FIRST)
- .thenCompose((punishment) -> {
- if (punishment.isEmpty()) {
- return futuresFactory.completedFuture(null);
- }
- return formatter.getPunishmentMessage(punishment.get());
- })
+ .executeAndCheckServerSwitch(
+ uuid, name, address, destinationServer
+ )
.toCompletableFuture()
.orTimeout(12, TimeUnit.SECONDS)
.exceptionally(timeoutHandler("server switch"));
diff --git a/bans-core/src/main/java/space/arim/libertybans/core/selector/InternalSelector.java b/bans-core/src/main/java/space/arim/libertybans/core/selector/InternalSelector.java
index bb3a43cad..82542ae53 100644
--- a/bans-core/src/main/java/space/arim/libertybans/core/selector/InternalSelector.java
+++ b/bans-core/src/main/java/space/arim/libertybans/core/selector/InternalSelector.java
@@ -42,14 +42,26 @@ public interface InternalSelector extends PunishmentSelector {
/**
* Checks a player connection's in a single connection query, enforcing any applicable bans,
* connection limits, and dealing out alt checks
- *
- * @param uuid the player uuid
- * @param name the player name
- * @param address the player address
- * @param scopes the server scopes to include in the selection query
+ *
+ * @param uuid the player uuid
+ * @param name the player name
+ * @param address the player address
+ * @param scopes the server scopes to include in the selection query
* @return a future which yields the denial message, or null if there is none
*/
CentralisedFuture executeAndCheckConnection(UUID uuid, String name, NetworkAddress address,
Set scopes);
+ /**
+ * Checks a player connection's in a single connection query, enforcing any applicable bans if
+ * enforce server switch is enabled.
+ *
+ * @param uuid the player uuid
+ * @param name the player name
+ * @param address the player address
+ * @param destinationServer the server the player is switching to
+ * @return a future which yields the denial message, or null if there is none
+ */
+ CentralisedFuture executeAndCheckServerSwitch(UUID uuid, String name, NetworkAddress address,
+ String destinationServer);
}
diff --git a/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectionByApplicabilityBuilderImpl.java b/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectionByApplicabilityBuilderImpl.java
index cbb0f6747..26551cb4b 100644
--- a/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectionByApplicabilityBuilderImpl.java
+++ b/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectionByApplicabilityBuilderImpl.java
@@ -1,6 +1,6 @@
/*
* LibertyBans
- * Copyright © 2023 Anand Beh
+ * Copyright © 2024 Anand Beh
*
* LibertyBans is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -39,6 +39,7 @@ public final class SelectionByApplicabilityBuilderImpl
private final NetworkAddress address;
private AddressStrictness strictness;
private final AddressStrictness defaultStrictness;
+ private boolean potentialNewEntrant;
SelectionByApplicabilityBuilderImpl(SelectionResources resources,
UUID uuid, NetworkAddress address, AddressStrictness defaultStrictness) {
@@ -68,7 +69,7 @@ SelectionByApplicabilityBuilder yieldSelf() {
@Override
SelectionByApplicability buildWith(SelectionBaseImpl.Details details) {
return new SelectionByApplicabilityImpl(
- details, resources, uuid, address, strictness
+ details, resources, uuid, address, strictness, potentialNewEntrant
);
}
@@ -89,4 +90,17 @@ public SelectionByApplicabilityImpl build() {
return (SelectionByApplicabilityImpl) super.build();
}
+ /**
+ * For internal use, to accomodate a new user whose UUID and IP address combination
+ * has not yet been entered to the database. Sets whether this scenario is potential.
+ *
+ * @param canAssumeUserRecorded if the user is definitely registered, set to true. True by default.
+ * @return this builder
+ */
+ public SelectionByApplicabilityBuilderImpl canAssumeUserRecorded(boolean canAssumeUserRecorded) {
+ // A user is a potential new entrant if we can't assume they're recorded
+ this.potentialNewEntrant = !canAssumeUserRecorded;
+ return this;
+ }
+
}
diff --git a/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectionByApplicabilityImpl.java b/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectionByApplicabilityImpl.java
index 1fc9c87a9..3e95db55d 100644
--- a/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectionByApplicabilityImpl.java
+++ b/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectionByApplicabilityImpl.java
@@ -1,6 +1,6 @@
/*
* LibertyBans
- * Copyright © 2023 Anand Beh
+ * Copyright © 2024 Anand Beh
*
* LibertyBans is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -38,6 +38,7 @@
import java.util.UUID;
import static org.jooq.impl.DSL.inline;
+import static org.jooq.impl.DSL.or;
import static space.arim.libertybans.core.schema.tables.StrictLinks.STRICT_LINKS;
public final class SelectionByApplicabilityImpl extends SelectionBaseSQL implements SelectionByApplicability {
@@ -45,13 +46,16 @@ public final class SelectionByApplicabilityImpl extends SelectionBaseSQL impleme
private final UUID uuid;
private final NetworkAddress address;
private final AddressStrictness strictness;
+ private final boolean potentialNewEntrant;
SelectionByApplicabilityImpl(Details details, SelectionResources resources,
- UUID uuid, NetworkAddress address, AddressStrictness strictness) {
+ UUID uuid, NetworkAddress address, AddressStrictness strictness,
+ boolean potentialNewEntrant) {
super(details, resources);
this.uuid = Objects.requireNonNull(uuid, "uuid");
this.address = Objects.requireNonNull(address, "address");
this.strictness = Objects.requireNonNull(strictness, "strictness");
+ this.potentialNewEntrant = potentialNewEntrant;
}
@Override
@@ -69,6 +73,16 @@ public AddressStrictness getAddressStrictness() {
return strictness;
}
+ /*
+ If the potentialNewEntrant flag is set, our task becomes significantly more complicated.
+ We now have to account for the enforcement of non-lenient address strictness by acting as if
+ the user had their IP address recorded already. This means attaching additional predication
+ to scans for IP-based punishments and patching over the applicability links we are accustomed
+ to having the database account for.
+
+ Thanks to SnakeAmazing for providing this marvelous intellectual puzzle.
+ */
+
@Override
Query> requestQuery(QueryParameters parameters) {
PunishmentFields fields = null;
@@ -83,21 +97,74 @@ Query> requestQuery(QueryParameters parameters) {
ApplicableViewFields> applView = requestApplicableView();
fields = applView;
table = fields.table();
+ if (potentialNewEntrant) {
+ // appl.uuid = uuid
+ // OR victim_type != 'PLAYER' AND victim_address = address
+ //
+ // Note: It must be victim_address and not appl.address
+ // Exercise for understanding: Why?
+ //
+ yield or(
+ applView.uuid().eq(uuid),
+ applView.victimType().notEqual(inline(VictimType.PLAYER))
+ .and(applView.victimAddress().eq(address))
+ );
+ }
yield applView.uuid().eq(uuid); // appl.uuid = uuid
}
case STERN -> {
+ if (potentialNewEntrant) {
+ ApplicableViewFields> applView = requestApplicableView();
+ fields = applView;
+ table = fields
+ .table()
+ .leftJoin(STRICT_LINKS)
+ .on(applView.uuid().eq(STRICT_LINKS.UUID1));
+ // appl.uuid = uuid # NORMAL
+ // OR victim_type != 'PLAYER' AND (
+ // appl.address = address # NORMAL + STERN
+ // OR strict_links.uuid2 IS NOT NULL AND strict_links.uuid2 = uuid # STERN
+ // )
+ //
+ // Note: The last predicate must use appl.address and not victim_address
+ // Exercise for understanding: Why?
+ //
+ yield or(
+ applView.uuid().eq(uuid),
+ applView.victimType().notEqual(inline(VictimType.PLAYER)).and(or(
+ STRICT_LINKS.UUID2.isNotNull().and(STRICT_LINKS.UUID2.eq(uuid)),
+ applView.address().eq(address)
+ ))
+ );
+ }
ApplicableViewFields> applView = requestApplicableView();
fields = applView;
table = fields
.table()
.innerJoin(STRICT_LINKS)
.on(applView.uuid().eq(STRICT_LINKS.UUID1));
- // appl.uuid = strict_links.uuid1 = uuid
- // OR victim_type != 'PLAYER' AND strict_links.uuid2 = uuid
+ // appl.uuid = strict_links.uuid1 = uuid # NORMAL
+ // OR victim_type != 'PLAYER' AND strict_links.uuid2 = uuid # STERN
yield STRICT_LINKS.UUID1.eq(uuid).or(
STRICT_LINKS.UUID2.eq(uuid).and(applView.victimType().notEqual(inline(VictimType.PLAYER))));
}
case STRICT -> {
+ if (potentialNewEntrant) {
+ ApplicableViewFields> applView = requestApplicableView();
+ fields = applView;
+ table = fields
+ .table()
+ .leftJoin(STRICT_LINKS)
+ .on(applView.uuid().eq(STRICT_LINKS.UUID1));
+ // appl.uuid = uuid # NORMAL
+ // OR appl.address = address # NORMAL + STRICT
+ // OR strict_links.uuid2 IS NOT NULL AND strict_links.uuid2 = uuid # STRICT
+ yield or(
+ applView.uuid().eq(uuid),
+ applView.address().eq(address),
+ STRICT_LINKS.UUID2.isNotNull().and(STRICT_LINKS.UUID2.eq(uuid))
+ );
+ }
ApplicableViewFields> applView = requestApplicableView();
fields = applView;
table = fields
diff --git a/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectorImpl.java b/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectorImpl.java
index 630e97fb1..110e30904 100644
--- a/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectorImpl.java
+++ b/bans-core/src/main/java/space/arim/libertybans/core/selector/SelectorImpl.java
@@ -26,6 +26,7 @@
import space.arim.libertybans.api.NetworkAddress;
import space.arim.libertybans.api.PunishmentType;
import space.arim.libertybans.api.punish.Punishment;
+import space.arim.libertybans.api.scope.ScopeManager;
import space.arim.libertybans.api.scope.ServerScope;
import space.arim.libertybans.api.select.AddressStrictness;
import space.arim.libertybans.api.select.SelectionOrderBuilder;
@@ -47,15 +48,18 @@ public class SelectorImpl implements InternalSelector {
private final Gatekeeper gatekeeper;
private final Provider muteCache;
private final SelectionResources resources;
+ private final ScopeManager scopeManager;
@Inject
public SelectorImpl(Configs configs, IDImpl idImpl, Gatekeeper gatekeeper,
- Provider muteCache, SelectionResources resources) {
+ Provider muteCache, SelectionResources resources,
+ ScopeManager scopeManager) {
this.configs = configs;
this.idImpl = idImpl;
this.gatekeeper = gatekeeper;
this.muteCache = muteCache;
this.resources = resources;
+ this.scopeManager = scopeManager;
}
@Override
@@ -112,6 +116,13 @@ public CentralisedFuture executeAndCheckConnection(UUID uuid, String
return gatekeeper.executeAndCheckConnection(uuid, name, address, scopes, this);
}
+ @Override
+ public CentralisedFuture executeAndCheckServerSwitch(UUID uuid, String name, NetworkAddress address,
+ String destinationServer) {
+ return gatekeeper.checkServerSwitch(uuid, name, address, destinationServer,
+ scopeManager.specificScope(destinationServer), this);
+ }
+
@Override
public ReactionStage> getCachedMute(UUID uuid, NetworkAddress address) {
Objects.requireNonNull(uuid, "uuid");
diff --git a/bans-env/bungee/src/main/java/space/arim/libertybans/env/bungee/ConnectionListener.java b/bans-env/bungee/src/main/java/space/arim/libertybans/env/bungee/ConnectionListener.java
index ef24d4848..231ac9a94 100644
--- a/bans-env/bungee/src/main/java/space/arim/libertybans/env/bungee/ConnectionListener.java
+++ b/bans-env/bungee/src/main/java/space/arim/libertybans/env/bungee/ConnectionListener.java
@@ -108,7 +108,7 @@ public void onServerSwitch(ServerConnectEvent event) {
InetAddress address = addressReporter.getAddress(player);
Component message = guardian.checkServerSwitch(
- player.getUniqueId(), address, event.getTarget().getName()
+ player.getUniqueId(), player.getName(), address, event.getTarget().getName()
).join();
if (message != null) {
event.setCancelled(true);
diff --git a/bans-env/velocity/src/main/java/space/arim/libertybans/env/velocity/ConnectionListener.java b/bans-env/velocity/src/main/java/space/arim/libertybans/env/velocity/ConnectionListener.java
index ce019f2c6..a09a74a3f 100644
--- a/bans-env/velocity/src/main/java/space/arim/libertybans/env/velocity/ConnectionListener.java
+++ b/bans-env/velocity/src/main/java/space/arim/libertybans/env/velocity/ConnectionListener.java
@@ -68,6 +68,7 @@ public EventTask onConnect(LoginEvent event) {
return null;
}
Player player = event.getPlayer();
+
return EventTask.resumeWhenComplete(guardian.executeAndCheckConnection(
player.getUniqueId(), player.getUsername(), player.getRemoteAddress().getAddress()
).thenAccept((message) -> {
@@ -91,7 +92,8 @@ public EventTask onServerSwitch(ServerPreConnectEvent event) {
}
Player player = event.getPlayer();
return EventTask.resumeWhenComplete(guardian.checkServerSwitch(
- player.getUniqueId(), player.getRemoteAddress().getAddress(), destination.getServerInfo().getName()
+ player.getUniqueId(), player.getUsername(), player.getRemoteAddress().getAddress(),
+ destination.getServerInfo().getName()
).thenAccept((message) -> {
if (message != null) {
event.setResult(ServerPreConnectEvent.ServerResult.denied());