Merge branch 'master' into plugin-message-event

# Conflicts:
#	proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java
#	proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java
This commit is contained in:
Andrew Steinborn
2018-09-16 02:35:38 -04:00
33 changed files with 750 additions and 215 deletions

View File

@@ -0,0 +1,28 @@
package com.velocitypowered.api.event.connection;
import com.google.common.base.Preconditions;
import com.velocitypowered.api.proxy.Player;
/**
* This event is fired once the player has been successfully authenticated and
* fully initialized and player will be connected to server after this event
*/
public class PostLoginEvent {
private final Player player;
public PostLoginEvent(Player player) {
this.player = Preconditions.checkNotNull(player, "player");
}
public Player getPlayer() {
return player;
}
@Override
public String toString() {
return "PostLoginEvent{"
+ "player=" + player
+ '}';
}
}

View File

@@ -3,8 +3,10 @@ package com.velocitypowered.api.event.connection;
import com.google.common.base.Preconditions;
import com.velocitypowered.api.event.ResultedEvent;
import com.velocitypowered.api.proxy.InboundConnection;
import java.util.Optional;
import net.kyori.text.Component;
import net.kyori.text.serializer.ComponentSerializers;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -52,44 +54,59 @@ public class PreLoginEvent implements ResultedEvent<PreLoginEvent.PreLoginCompon
}
/**
* Represents an "allowed/allowed with online mode/denied" result with a reason allowed for denial.
* Represents an "allowed/allowed with forced online\offline mode/denied" result with a reason allowed for denial.
*/
public static class PreLoginComponentResult extends ResultedEvent.ComponentResult {
private static final PreLoginComponentResult ALLOWED = new PreLoginComponentResult((Component) null);
private static final PreLoginComponentResult FORCE_ONLINEMODE = new PreLoginComponentResult(true);
public static class PreLoginComponentResult implements ResultedEvent.Result {
private final boolean onlineMode;
private static final PreLoginComponentResult ALLOWED = new PreLoginComponentResult(Result.ALLOWED, null);
private static final PreLoginComponentResult FORCE_ONLINEMODE = new PreLoginComponentResult(Result.FORCE_ONLINE, null);
private static final PreLoginComponentResult FORCE_OFFLINEMODE = new PreLoginComponentResult(Result.FORCE_OFFLINE, null);
/**
* Allows online mode to be enabled for the player connection, if Velocity is running in offline mode.
* @param allowedOnlineMode if true, online mode will be used for the connection
*/
private PreLoginComponentResult(boolean allowedOnlineMode) {
super(true, null);
this.onlineMode = allowedOnlineMode;
private final Result result;
private final Optional<Component> reason;
private PreLoginComponentResult(Result result, @Nullable Component reason) {
this.result = result;
this.reason = Optional.ofNullable(reason);
}
private PreLoginComponentResult(@Nullable Component reason) {
super(reason == null, reason);
// Don't care about this
this.onlineMode = false;
@Override
public boolean isAllowed() {
return result != Result.DISALLOWED;
}
public Optional<Component> getReason() {
return reason;
}
public boolean isOnlineModeAllowed() {
return this.onlineMode;
return result == Result.FORCE_ONLINE;
}
public boolean isForceOfflineMode() {
return result == Result.FORCE_OFFLINE;
}
@Override
public String toString() {
if (isForceOfflineMode()) {
return "allowed with force offline mode";
}
if (isOnlineModeAllowed()) {
return "allowed with online mode";
}
return super.toString();
if (isAllowed()) {
return "allowed";
}
if (reason.isPresent()) {
return "denied: " + ComponentSerializers.PLAIN.serialize(reason.get());
}
return "denied";
}
/**
* Returns a result indicating the connection will be allowed through the proxy.
* Returns a result indicating the connection will be allowed through
* the proxy.
* @return the allowed result
*/
public static PreLoginComponentResult allowed() {
@@ -97,23 +114,41 @@ public class PreLoginEvent implements ResultedEvent<PreLoginEvent.PreLoginCompon
}
/**
* Returns a result indicating the connection will be allowed through the proxy, but the connection will be
* forced to use online mode provided that the proxy is in offline mode. This acts similarly to {@link #allowed()}
* on an online-mode proxy.
* Returns a result indicating the connection will be allowed through
* the proxy, but the connection will be forced to use online mode
* provided that the proxy is in offline mode. This acts similarly to
* {@link #allowed()} on an online-mode proxy.
* @return the result
*/
public static PreLoginComponentResult forceOnlineMode() {
return FORCE_ONLINEMODE;
}
/**
* Returns a result indicating the connection will be allowed through
* the proxy, but the connection will be forced to use offline mode even
* when proxy running in online mode
* @return the result
*/
public static PreLoginComponentResult forceOfflineMode() {
return FORCE_OFFLINEMODE;
}
/**
* Denies the login with the specified reason.
* @param reason the reason for disallowing the connection
* @return a new result
*/
public static PreLoginComponentResult denied(@NonNull Component reason) {
public static PreLoginComponentResult denied(Component reason) {
Preconditions.checkNotNull(reason, "reason");
return new PreLoginComponentResult(reason);
return new PreLoginComponentResult(Result.DISALLOWED, reason);
}
private enum Result {
ALLOWED,
FORCE_ONLINE,
FORCE_OFFLINE,
DISALLOWED
}
}
}

View File

@@ -0,0 +1,118 @@
package com.velocitypowered.api.event.player;
import com.google.common.base.Preconditions;
import com.velocitypowered.api.event.ResultedEvent;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.server.ServerInfo;
import net.kyori.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull;
/**
* Fired when a player is kicked from a server. You may either allow Velocity to kick the player (with an optional reason
* override) or redirect the player to a separate server.
*/
public class KickedFromServerEvent implements ResultedEvent<KickedFromServerEvent.ServerKickResult> {
private final Player player;
private final ServerInfo server;
private final Component originalReason;
private final boolean duringLogin;
private ServerKickResult result;
public KickedFromServerEvent(Player player, ServerInfo server, Component originalReason, boolean duringLogin, Component fancyReason) {
this.player = Preconditions.checkNotNull(player, "player");
this.server = Preconditions.checkNotNull(server, "server");
this.originalReason = Preconditions.checkNotNull(originalReason, "originalReason");
this.duringLogin = duringLogin;
this.result = new DisconnectPlayer(fancyReason);
}
@Override
public ServerKickResult getResult() {
return result;
}
@Override
public void setResult(@NonNull ServerKickResult result) {
this.result = Preconditions.checkNotNull(result, "result");
}
public Player getPlayer() {
return player;
}
public ServerInfo getServer() {
return server;
}
public Component getOriginalReason() {
return originalReason;
}
public boolean kickedDuringLogin() {
return duringLogin;
}
/**
* Represents the base interface for {@link KickedFromServerEvent} results.
*/
public interface ServerKickResult extends ResultedEvent.Result {}
/**
* Tells the proxy to disconnect the player with the specified reason.
*/
public static class DisconnectPlayer implements ServerKickResult {
private final Component component;
private DisconnectPlayer(Component component) {
this.component = Preconditions.checkNotNull(component, "component");
}
@Override
public boolean isAllowed() {
return true;
}
public Component getReason() {
return component;
}
/**
* Creates a new {@link DisconnectPlayer} with the specified reason.
* @param reason the reason to use when disconnecting the player
* @return the disconnect result
*/
public static DisconnectPlayer create(Component reason) {
return new DisconnectPlayer(reason);
}
}
/**
* Tells the proxy to redirect the player to another server. No messages will be sent from the proxy
* when this result is used.
*/
public static class RedirectPlayer implements ServerKickResult {
private final ServerInfo server;
private RedirectPlayer(ServerInfo server) {
this.server = Preconditions.checkNotNull(server, "server");
}
@Override
public boolean isAllowed() {
return false;
}
public ServerInfo getServer() {
return server;
}
/**
* Creates a new redirect result to forward the player to the specified {@code server}.
* @param server the server to send the player to
* @return the redirect result
*/
public static RedirectPlayer create(ServerInfo server) {
return new RedirectPlayer(server);
}
}
}

View File

@@ -14,11 +14,13 @@ import java.util.Optional;
*/
public class ServerPreConnectEvent implements ResultedEvent<ServerPreConnectEvent.ServerResult> {
private final Player player;
private final ServerInfo originalServer;
private ServerResult result;
public ServerPreConnectEvent(Player player, ServerResult result) {
public ServerPreConnectEvent(Player player, ServerInfo originalServer) {
this.player = Preconditions.checkNotNull(player, "player");
this.result = Preconditions.checkNotNull(result, "result");
this.originalServer = Preconditions.checkNotNull(originalServer, "originalServer");
this.result = ServerResult.allowed(originalServer);
}
public Player getPlayer() {
@@ -35,10 +37,15 @@ public class ServerPreConnectEvent implements ResultedEvent<ServerPreConnectEven
this.result = Preconditions.checkNotNull(result, "result");
}
public ServerInfo getOriginalServer() {
return originalServer;
}
@Override
public String toString() {
return "ServerPreConnectEvent{" +
"player=" + player +
", originalServer=" + originalServer +
", result=" + result +
'}';
}
@@ -50,11 +57,11 @@ public class ServerPreConnectEvent implements ResultedEvent<ServerPreConnectEven
private static final ServerResult DENIED = new ServerResult(false, null);
private final boolean allowed;
private final ServerInfo info;
private final ServerInfo server;
private ServerResult(boolean allowed, @Nullable ServerInfo info) {
private ServerResult(boolean allowed, @Nullable ServerInfo server) {
this.allowed = allowed;
this.info = info;
this.server = server;
}
@Override
@@ -62,8 +69,8 @@ public class ServerPreConnectEvent implements ResultedEvent<ServerPreConnectEven
return allowed;
}
public Optional<ServerInfo> getInfo() {
return Optional.ofNullable(info);
public Optional<ServerInfo> getServer() {
return Optional.ofNullable(server);
}
@Override
@@ -71,7 +78,7 @@ public class ServerPreConnectEvent implements ResultedEvent<ServerPreConnectEven
if (!allowed) {
return "denied";
}
return "allowed: connect to " + info.getName();
return "allowed: connect to " + server.getName();
}
public static ServerResult denied() {

View File

@@ -4,7 +4,6 @@ import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.velocitypowered.api.util.Favicon;
import net.kyori.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.*;
@@ -17,12 +16,18 @@ public class ServerPing {
private final Players players;
private final Component description;
private final @Nullable Favicon favicon;
private final Modinfo modinfo;
public ServerPing(Version version, @Nullable Players players, Component description, @Nullable Favicon favicon) {
this(version, players, description, favicon, Modinfo.DEFAULT);
}
public ServerPing(Version version, @Nullable Players players, Component description, @Nullable Favicon favicon, @Nullable Modinfo modinfo) {
this.version = Preconditions.checkNotNull(version, "version");
this.players = players;
this.description = Preconditions.checkNotNull(description, "description");
this.favicon = favicon;
this.modinfo = modinfo;
}
public Version getVersion() {
@@ -41,6 +46,10 @@ public class ServerPing {
return Optional.ofNullable(favicon);
}
public Optional<Modinfo> getModinfo() {
return Optional.ofNullable(modinfo);
}
@Override
public String toString() {
return "ServerPing{" +
@@ -54,11 +63,19 @@ public class ServerPing {
public Builder asBuilder() {
Builder builder = new Builder();
builder.version = version;
builder.onlinePlayers = players.online;
builder.maximumPlayers = players.max;
builder.samplePlayers.addAll(players.sample);
if (players != null) {
builder.onlinePlayers = players.online;
builder.maximumPlayers = players.max;
builder.samplePlayers.addAll(players.sample);
} else {
builder.nullOutPlayers = true;
}
builder.description = description;
builder.favicon = favicon;
builder.nullOutModinfo = modinfo == null;
if (modinfo != null) {
builder.mods.addAll(modinfo.modList);
}
return builder;
}
@@ -74,9 +91,11 @@ public class ServerPing {
private int onlinePlayers;
private int maximumPlayers;
private final List<SamplePlayer> samplePlayers = new ArrayList<>();
private final List<Mod> mods = new ArrayList<>();
private Component description;
private Favicon favicon;
private boolean nullOutPlayers;
private boolean nullOutModinfo;
private Builder() {
@@ -102,11 +121,26 @@ public class ServerPing {
return this;
}
public Builder mods(Mod... mods) {
this.mods.addAll(Arrays.asList(mods));
return this;
}
public Builder clearMods() {
this.mods.clear();
return this;
}
public Builder clearSamplePlayers() {
this.samplePlayers.clear();
return this;
}
public Builder notModCompatible() {
this.nullOutModinfo = true;
return this;
}
public Builder nullPlayers() {
this.nullOutPlayers = true;
return this;
@@ -123,7 +157,8 @@ public class ServerPing {
}
public ServerPing build() {
return new ServerPing(version, nullOutPlayers ? null : new Players(onlinePlayers, maximumPlayers, samplePlayers), description, favicon);
return new ServerPing(version, nullOutPlayers ? null : new Players(onlinePlayers, maximumPlayers, samplePlayers), description, favicon,
nullOutModinfo ? null : new Modinfo(mods));
}
public Version getVersion() {
@@ -150,6 +185,10 @@ public class ServerPing {
return favicon;
}
public List<Mod> getMods() {
return mods;
}
@Override
public String toString() {
return "Builder{" +
@@ -157,8 +196,11 @@ public class ServerPing {
", onlinePlayers=" + onlinePlayers +
", maximumPlayers=" + maximumPlayers +
", samplePlayers=" + samplePlayers +
", mods=" + mods +
", description=" + description +
", favicon=" + favicon +
", nullOutPlayers=" + nullOutPlayers +
", nullOutModinfo=" + nullOutModinfo +
'}';
}
}
@@ -247,4 +289,25 @@ public class ServerPing {
'}';
}
}
public static class Modinfo {
public static final Modinfo DEFAULT = new Modinfo(ImmutableList.of());
private final String type = "FML";
private final List<Mod> modList;
public Modinfo(List<Mod> modList) {
this.modList = ImmutableList.copyOf(modList);
}
}
public static class Mod {
private final String id;
private final String version;
public Mod(String id, String version) {
this.id = Preconditions.checkNotNull(id, "id");
this.version = Preconditions.checkNotNull(version, "version");
}
}
}

View File

@@ -57,7 +57,7 @@ public final class GameProfile {
'}';
}
public final class Property {
public final static class Property {
private final String name;
private final String value;
private final String signature;