mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2026-01-04 15:31:48 +00:00
Support API usage in disconnect events. Removed the login field
This commit is contained in:
@@ -86,7 +86,7 @@ public class BungeeDataAddon implements InjectorAddon {
|
||||
@Override
|
||||
public void onChannelClosed(Channel channel) {
|
||||
FloodgatePlayer player = channel.attr(playerAttribute).get();
|
||||
if (player != null && api.removePlayer(player)) {
|
||||
if (player != null && api.setPendingRemove(player)) {
|
||||
logger.translatedInfo("floodgate.ingame.disconnect_name", player.getCorrectUsername());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,8 @@ public final class BungeeListener implements Listener {
|
||||
UUID uniqueId = event.getConnection().getUniqueId();
|
||||
FloodgatePlayer player = api.getPlayer(uniqueId);
|
||||
if (player != null) {
|
||||
player.as(FloodgatePlayerImpl.class).setLogin(false);
|
||||
//todo we should probably move this log message earlier in the process, so that we know
|
||||
// that Floodgate has done its job
|
||||
logger.translatedInfo(
|
||||
"floodgate.ingame.login_name",
|
||||
player.getCorrectUsername(), uniqueId
|
||||
@@ -122,6 +123,8 @@ public final class BungeeListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerDisconnect(PlayerDisconnectEvent event) {
|
||||
api.playerRemoved(event.getPlayer().getUniqueId());
|
||||
|
||||
BungeeCommandUtil.AUDIENCE_CACHE.remove(event.getPlayer().getUniqueId()); //todo
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
package org.geysermc.floodgate.api;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
@@ -33,7 +35,7 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.cumulus.Form;
|
||||
import org.geysermc.cumulus.util.FormBuilder;
|
||||
@@ -41,7 +43,6 @@ import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.api.unsafe.Unsafe;
|
||||
import org.geysermc.floodgate.config.FloodgateConfigHolder;
|
||||
import org.geysermc.floodgate.player.FloodgatePlayerImpl;
|
||||
import org.geysermc.floodgate.pluginmessage.PluginMessageManager;
|
||||
import org.geysermc.floodgate.pluginmessage.channel.FormChannel;
|
||||
import org.geysermc.floodgate.pluginmessage.channel.TransferChannel;
|
||||
@@ -52,6 +53,11 @@ import org.geysermc.floodgate.util.Utils;
|
||||
@RequiredArgsConstructor
|
||||
public class SimpleFloodgateApi implements FloodgateApi {
|
||||
private final Map<UUID, FloodgatePlayer> players = new HashMap<>();
|
||||
private final Cache<UUID, FloodgatePlayer> pendingRemove =
|
||||
CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(20, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
private final PluginMessageManager pluginMessageManager;
|
||||
private final FloodgateConfigHolder configHolder;
|
||||
private final FloodgateLogger logger;
|
||||
@@ -79,10 +85,14 @@ public class SimpleFloodgateApi implements FloodgateApi {
|
||||
@Override
|
||||
public FloodgatePlayer getPlayer(UUID uuid) {
|
||||
FloodgatePlayer selfPlayer = players.get(uuid);
|
||||
if (selfPlayer != null) {
|
||||
return selfPlayer;
|
||||
}
|
||||
|
||||
// bedrock players are always stored by their xuid,
|
||||
// so we return the instance if we know that the given uuid is a Floodgate uuid
|
||||
if (selfPlayer != null || isFloodgateId(uuid)) {
|
||||
return selfPlayer;
|
||||
if (isFloodgateId(uuid)) {
|
||||
return pendingRemove.getIfPresent(uuid);
|
||||
}
|
||||
|
||||
// make it possible to find player by Java id (linked players)
|
||||
@@ -91,7 +101,8 @@ public class SimpleFloodgateApi implements FloodgateApi {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
// and don't forget the pending remove linked players
|
||||
return getPendingRemovePlayer(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -164,67 +175,39 @@ public class SimpleFloodgateApi implements FloodgateApi {
|
||||
return new UnsafeFloodgateApi(pluginMessageManager);
|
||||
}
|
||||
|
||||
public FloodgatePlayer addPlayer(UUID uuid, FloodgatePlayer player) {
|
||||
return players.put(uuid, player);
|
||||
public FloodgatePlayer addPlayer(FloodgatePlayer player) {
|
||||
// Bedrock players are always stored by their xuid
|
||||
return players.put(player.getJavaUniqueId(), player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a player (should only be used internally)
|
||||
*
|
||||
* @param onlineId The UUID of the online player
|
||||
* @param removeLogin true if it should remove a sessions who is still logging in
|
||||
* @return the FloodgatePlayer the player was logged in with
|
||||
* This method is invoked when the player is no longer on the server, but the related platform-
|
||||
* dependant event hasn't fired yet
|
||||
*/
|
||||
@Nullable
|
||||
public FloodgatePlayer removePlayer(UUID onlineId, boolean removeLogin) {
|
||||
FloodgatePlayer selfPlayer = players.get(onlineId);
|
||||
// the player is a non-linked player or a linked player but somehow someone tried to
|
||||
// remove the player by his xuid, we have to find out
|
||||
if (selfPlayer != null) {
|
||||
// we don't allow them to remove a player by his xuid
|
||||
// because a linked player is never registered by his linked java uuid
|
||||
if (selfPlayer.getLinkedPlayer() != null) {
|
||||
return null;
|
||||
}
|
||||
public boolean setPendingRemove(FloodgatePlayer player) {
|
||||
pendingRemove.put(player.getJavaUniqueId(), player);
|
||||
return players.remove(player.getJavaUniqueId(), player);
|
||||
}
|
||||
|
||||
// removeLogin logic
|
||||
if (!canRemove(selfPlayer, removeLogin)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// passed the test
|
||||
players.remove(onlineId);
|
||||
// was the account linked?
|
||||
return selfPlayer;
|
||||
public void playerRemoved(UUID correctUuid) {
|
||||
// we can remove the player directly if it is a Floodgate UUID.
|
||||
// since it's stored by their Floodgate UUID
|
||||
if (isFloodgateId(correctUuid)) {
|
||||
pendingRemove.invalidate(correctUuid);
|
||||
return;
|
||||
}
|
||||
FloodgatePlayer linkedPlayer = getPendingRemovePlayer(correctUuid);
|
||||
if (linkedPlayer != null) {
|
||||
pendingRemove.invalidate(linkedPlayer.getJavaUniqueId());
|
||||
}
|
||||
}
|
||||
|
||||
// we still want to be able to remove a linked-player by his linked java uuid
|
||||
for (FloodgatePlayer player : players.values()) {
|
||||
if (canRemove(player, removeLogin) && player.getCorrectUniqueId().equals(onlineId)) {
|
||||
players.remove(player.getJavaUniqueId());
|
||||
private FloodgatePlayer getPendingRemovePlayer(UUID correctUuid) {
|
||||
for (FloodgatePlayer player : pendingRemove.asMap().values()) {
|
||||
if (player.getCorrectUniqueId().equals(correctUuid)) {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean canRemove(FloodgatePlayer player, boolean removeLogin) {
|
||||
FloodgatePlayerImpl impl = player.as(FloodgatePlayerImpl.class);
|
||||
return impl.isLogin() && removeLogin || !impl.isLogin() && !removeLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalant of {@link #removePlayer(UUID, boolean)} but with removeLogin = false.
|
||||
*/
|
||||
public FloodgatePlayer removePlayer(UUID onlineId) {
|
||||
return removePlayer(onlineId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent of {@link #removePlayer(UUID, boolean)} except that it removes a FloodgatePlayer
|
||||
* instance directly.
|
||||
*/
|
||||
public boolean removePlayer(FloodgatePlayer player) {
|
||||
return players.remove(player.getJavaUniqueId(), player);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ public final class FloodgateHandshakeHandler {
|
||||
|
||||
FloodgatePlayer player = FloodgatePlayerImpl.from(bedrockData, handshakeData);
|
||||
|
||||
api.addPlayer(player.getJavaUniqueId(), player);
|
||||
api.addPlayer(player);
|
||||
|
||||
channel.attr(playerAttribute).set(player);
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ import java.util.UUID;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.InstanceHolder;
|
||||
import org.geysermc.floodgate.api.ProxyFloodgateApi;
|
||||
@@ -68,16 +67,11 @@ public final class FloodgatePlayerImpl implements FloodgatePlayer {
|
||||
private final String verifyCode;
|
||||
|
||||
@Getter(AccessLevel.PRIVATE)
|
||||
public Map<PropertyKey, Object> propertyKeyToValue;
|
||||
private Map<PropertyKey, Object> propertyKeyToValue;
|
||||
@Getter(AccessLevel.PRIVATE)
|
||||
private Map<String, PropertyKey> stringToPropertyKey;
|
||||
|
||||
/**
|
||||
* Returns true if the player is still logging in
|
||||
*/
|
||||
@Setter private boolean login = true;
|
||||
|
||||
protected static FloodgatePlayerImpl from(BedrockData data, HandshakeData handshakeData) {
|
||||
static FloodgatePlayerImpl from(BedrockData data, HandshakeData handshakeData) {
|
||||
FloodgateApi api = InstanceHolder.getApi();
|
||||
|
||||
UUID javaUniqueId = Utils.getJavaUuid(data.getXuid());
|
||||
|
||||
@@ -66,7 +66,7 @@ public final class SpigotDataAddon implements InjectorAddon {
|
||||
@Override
|
||||
public void onChannelClosed(Channel channel) {
|
||||
FloodgatePlayer player = channel.attr(playerAttribute).get();
|
||||
if (player != null && api.removePlayer(player)) {
|
||||
if (player != null && api.setPendingRemove(player)) {
|
||||
logger.translatedInfo("floodgate.ingame.disconnect_name", player.getCorrectUsername());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,8 @@ public final class SpigotListener implements Listener {
|
||||
// he would've been disconnected by now
|
||||
FloodgatePlayer player = api.getPlayer(uniqueId);
|
||||
if (player != null) {
|
||||
player.as(FloodgatePlayerImpl.class).setLogin(false);
|
||||
//todo we should probably move this log message earlier in the process, so that we know
|
||||
// that Floodgate has done its job
|
||||
logger.translatedInfo(
|
||||
"floodgate.ingame.login_name",
|
||||
player.getCorrectUsername(), player.getCorrectUniqueId()
|
||||
@@ -66,6 +67,8 @@ public final class SpigotListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
api.playerRemoved(event.getPlayer().getUniqueId());
|
||||
|
||||
SpigotCommandUtil.AUDIENCE_CACHE.remove(event.getPlayer().getUniqueId()); //todo
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public final class VelocityDataAddon implements InjectorAddon {
|
||||
@Override
|
||||
public void onChannelClosed(Channel channel) {
|
||||
FloodgatePlayer player = channel.attr(playerAttribute).get();
|
||||
if (player != null && api.removePlayer(player)) {
|
||||
if (player != null && api.setPendingRemove(player)) {
|
||||
logger.translatedInfo("floodgate.ingame.disconnect_name", player.getUsername());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,6 +158,8 @@ public final class VelocityListener {
|
||||
|
||||
@Subscribe(order = PostOrder.LAST)
|
||||
public void onDisconnect(DisconnectEvent event) {
|
||||
api.playerRemoved(event.getPlayer().getUniqueId());
|
||||
|
||||
VelocityCommandUtil.AUDIENCE_CACHE.remove(event.getPlayer().getUniqueId()); //todo
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user