Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use loginevent #95

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 36 additions & 24 deletions Bungee/src/main/java/me/egg82/antivpn/events/PlayerEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,18 @@
import me.egg82.antivpn.api.model.ip.IPManager;
import me.egg82.antivpn.api.model.player.PlayerManager;
import me.egg82.antivpn.api.platform.BungeePlatform;
import me.egg82.antivpn.bungee.BungeeEnvironmentUtil;
import me.egg82.antivpn.config.CachedConfig;
import me.egg82.antivpn.config.ConfigUtil;
import me.egg82.antivpn.hooks.LuckPermsHook;
import me.egg82.antivpn.services.lookup.PlayerInfo;
import me.egg82.antivpn.services.lookup.PlayerLookup;
import me.egg82.antivpn.utils.LoginEventWrapper;
import me.egg82.antivpn.utils.ExceptionUtil;
import me.egg82.antivpn.utils.ValidationUtil;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.event.LoginEvent;
import net.md_5.bungee.api.event.PostLoginEvent;
import net.md_5.bungee.api.event.PreLoginEvent;
import net.md_5.bungee.api.plugin.Plugin;
Expand All @@ -41,21 +44,32 @@ public class PlayerEvents extends EventHolder {
public PlayerEvents(@NonNull Plugin plugin, @NonNull CommandIssuer console) {
this.console = console;

boolean useLoginEvent = true;
CachedConfig cachedConfig = ConfigUtil.getCachedConfig();
if (cachedConfig != null) {
useLoginEvent = cachedConfig.getLoginEvent();
}
if(!useLoginEvent) {
logger.warn("Not using LoginEvent, performance issues and failed UUID lookups expected");
}

events.add(
BungeeEvents.subscribe(plugin, PreLoginEvent.class, EventPriority.HIGH)
(useLoginEvent ? BungeeEvents.subscribe(plugin, LoginEvent.class, EventPriority.LOW)
: BungeeEvents.subscribe(plugin, PreLoginEvent.class, EventPriority.HIGH))
.handler(e -> e.registerIntent(plugin))
.handler(e -> POOL.submit(() -> {
try {
checkPerms(e);
checkPerms(new LoginEventWrapper(e,plugin));
} finally {
e.completeIntent(plugin);
}
}))
);

events.add(
BungeeEvents.subscribe(plugin, PostLoginEvent.class, EventPriority.LOWEST)
.handler(this::checkPlayer)
(useLoginEvent ? BungeeEvents.subscribe(plugin, LoginEvent.class, EventPriority.NORMAL)
: BungeeEvents.subscribe(plugin, PostLoginEvent.class, EventPriority.LOWEST))
.handler(e -> this.checkPlayer(new LoginEventWrapper(e,plugin)))
);

events.add(
Expand All @@ -71,7 +85,7 @@ public PlayerEvents(@NonNull Plugin plugin, @NonNull CommandIssuer console) {
);
}

private void checkPerms(@NonNull PreLoginEvent event) {
private void checkPerms(@NonNull LoginEventWrapper event) {
Optional<LuckPermsHook> luckPermsHook;
try {
luckPermsHook = ServiceLocator.getOptional(LuckPermsHook.class);
Expand Down Expand Up @@ -115,7 +129,7 @@ private void checkPerms(@NonNull PreLoginEvent event) {
}
}

private void checkPermsPlayer(@NonNull PreLoginEvent event, @NonNull UUID uuid, boolean hasBypass) {
private void checkPermsPlayer(@NonNull LoginEventWrapper event, @NonNull UUID uuid, boolean hasBypass) {
if (hasBypass) {
if (ConfigUtil.getDebugOrFalse()) {
console.sendMessage("<c1>" + event.getConnection().getName() + "</c1> <c2>bypasses pre-check. Ignoring.</c2>");
Expand Down Expand Up @@ -160,8 +174,7 @@ private void checkPermsPlayer(@NonNull PreLoginEvent event, @NonNull UUID uuid,
}
String kickMessage = ipManager.getVpnKickMessage(event.getConnection().getName(), uuid, ip);
if (kickMessage != null) {
event.setCancelled(true);
event.setCancelReason(TextComponent.fromLegacyText(kickMessage));
event.disconnect(ip,false,TextComponent.fromLegacyText(kickMessage));
}
}

Expand All @@ -174,13 +187,12 @@ private void checkPermsPlayer(@NonNull PreLoginEvent event, @NonNull UUID uuid,
}
String kickMessage = playerManager.getMcLeaksKickMessage(event.getConnection().getName(), uuid, ip);
if (kickMessage != null) {
event.setCancelled(true);
event.setCancelReason(TextComponent.fromLegacyText(kickMessage));
event.disconnect(ip,true,TextComponent.fromLegacyText(kickMessage));
}
}
}

private void cachePlayer(@NonNull PreLoginEvent event, UUID uuid) {
private void cachePlayer(@NonNull LoginEventWrapper event, UUID uuid) {
if (uuid == null) {
return;
}
Expand Down Expand Up @@ -245,7 +257,7 @@ private void cacheData(@NonNull String ip, @NonNull UUID uuid, @NonNull CachedCo
}
}

private void checkPlayer(@NonNull PostLoginEvent event) {
private void checkPlayer(@NonNull LoginEventWrapper event) {
Optional<LuckPermsHook> luckPermsHook;
try {
luckPermsHook = ServiceLocator.getOptional(LuckPermsHook.class);
Expand All @@ -258,7 +270,7 @@ private void checkPlayer(@NonNull PostLoginEvent event) {
return;
}

String ip = getIp(event.getPlayer().getAddress());
String ip = getIp(event.getAddress());
if (ip == null || ip.isEmpty()) {
return;
}
Expand All @@ -269,7 +281,7 @@ private void checkPlayer(@NonNull PostLoginEvent event) {
return;
}

if (event.getPlayer().hasPermission("avpn.bypass")) {
if (event.getPlayer() != null && event.getPlayer().hasPermission("avpn.bypass")) {
if (ConfigUtil.getDebugOrFalse()) {
console.sendMessage("<c1>" + event.getPlayer().getName() + "</c1> <c2>bypasses actions. Ignoring.</c2>");
}
Expand All @@ -279,40 +291,40 @@ private void checkPlayer(@NonNull PostLoginEvent event) {
for (String testAddress : cachedConfig.getIgnoredIps()) {
if (ValidationUtil.isValidIp(testAddress) && ip.equalsIgnoreCase(testAddress)) {
if (ConfigUtil.getDebugOrFalse()) {
console.sendMessage("<c1>" + event.getPlayer().getName() + "</c1> <c2>is using an ignored IP</c2> <c1>" + ip + "</c1><c2>. Ignoring.</c2>");
console.sendMessage("<c1>" + event.getName() + "</c1> <c2>is using an ignored IP</c2> <c1>" + ip + "</c1><c2>. Ignoring.</c2>");
}
return;
} else if (ValidationUtil.isValidIpRange(testAddress) && rangeContains(testAddress, ip)) {
if (ConfigUtil.getDebugOrFalse()) {
console.sendMessage("<c1>" + event.getPlayer().getName() + "</c1> <c2>is under an ignored range</c2> <c1>" + testAddress + " (" + ip + ")" + "</c1><c2>. Ignoring.</c2>");
console.sendMessage("<c1>" + event.getName() + "</c1> <c2>is under an ignored range</c2> <c1>" + testAddress + " (" + ip + ")" + "</c1><c2>. Ignoring.</c2>");
}
return;
}
}

if (isVpn(ip, event.getPlayer().getName(), cachedConfig)) {
if (isVpn(ip, event.getName(), cachedConfig)) {
AntiVPN.incrementBlockedVPNs();
IPManager ipManager = VPNAPIProvider.getInstance().getIPManager();
List<String> commands = ipManager.getVpnCommands(event.getPlayer().getName(), event.getPlayer().getUniqueId(), ip);
List<String> commands = ipManager.getVpnCommands(event.getName(), event.getUniqueId(), ip);
for (String command : commands) {
ProxyServer.getInstance().getPluginManager().dispatchCommand(ProxyServer.getInstance().getConsole(), command);
}
String kickMessage = ipManager.getVpnKickMessage(event.getPlayer().getName(), event.getPlayer().getUniqueId(), ip);
String kickMessage = ipManager.getVpnKickMessage(event.getName(), event.getUniqueId(), ip);
if (kickMessage != null) {
event.getPlayer().disconnect(TextComponent.fromLegacyText(kickMessage));
event.disconnect(ip,false,TextComponent.fromLegacyText(kickMessage));
}
}

if (isMcLeaks(event.getPlayer().getName(), event.getPlayer().getUniqueId(), cachedConfig)) {
if (isMcLeaks(event.getName(), event.getUniqueId(), cachedConfig)) {
AntiVPN.incrementBlockedMCLeaks();
PlayerManager playerManager = VPNAPIProvider.getInstance().getPlayerManager();
List<String> commands = playerManager.getMcLeaksCommands(event.getPlayer().getName(), event.getPlayer().getUniqueId(), ip);
List<String> commands = playerManager.getMcLeaksCommands(event.getName(), event.getUniqueId(), ip);
for (String command : commands) {
ProxyServer.getInstance().getPluginManager().dispatchCommand(ProxyServer.getInstance().getConsole(), command);
}
String kickMessage = playerManager.getMcLeaksKickMessage(event.getPlayer().getName(), event.getPlayer().getUniqueId(), ip);
String kickMessage = playerManager.getMcLeaksKickMessage(event.getName(), event.getUniqueId(), ip);
if (kickMessage != null) {
event.getPlayer().disconnect(TextComponent.fromLegacyText(kickMessage));
event.disconnect(ip,true,TextComponent.fromLegacyText(kickMessage));
}
}
}
Expand Down
115 changes: 115 additions & 0 deletions Bungee/src/main/java/me/egg82/antivpn/utils/LoginEventWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package me.egg82.antivpn.utils;

import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.LoginEvent;
import net.md_5.bungee.api.event.PostLoginEvent;
import net.md_5.bungee.api.event.PreLoginEvent;
import net.md_5.bungee.api.plugin.Plugin;

import javax.annotation.Nullable;
import java.net.InetSocketAddress;
import java.util.UUID;

public class LoginEventWrapper {
private PreLoginEvent preLoginEvent = null;
private PostLoginEvent postLoginEvent = null;
private LoginEvent loginEvent = null;
private Plugin plugin;

public LoginEventWrapper(Object event,Plugin plugin) {
if (event instanceof PreLoginEvent) {
preLoginEvent = (PreLoginEvent) event;
}else if (event instanceof PostLoginEvent) {
postLoginEvent = (PostLoginEvent) event;
} else {
loginEvent = (LoginEvent) event;
}
this.plugin = plugin;
}

public InetSocketAddress getAddress() {
if (preLoginEvent != null) {
return preLoginEvent.getConnection().getAddress();
} else if (postLoginEvent != null) {
return postLoginEvent.getPlayer().getAddress();
} else {
return loginEvent.getConnection().getAddress();
}
}
public void disconnect(String ip,boolean mcLeaks,BaseComponent... message){
if (preLoginEvent != null) {
preLoginEvent.setCancelled(true);
preLoginEvent.setCancelReason(message);
} else if (postLoginEvent != null) {
postLoginEvent.getPlayer().disconnect(message);
} else {
loginEvent.setCancelled(true);
loginEvent.setCancelReason(message);
}
plugin.getLogger().info("Disconnecting " + getConnection().getName() + " for using a" + (mcLeaks ? "n MCLeaks account" : " VPN") + ". Address: " + ip);
}

public UUID getUniqueId() {
if (preLoginEvent != null) {
throw new IllegalArgumentException("PreLoginEvent doesn't have method getUniqueID");
} else if (postLoginEvent != null) {
return postLoginEvent.getPlayer().getUniqueId();
} else {
return loginEvent.getConnection().getUniqueId();
}
}

public String getName() {
if (preLoginEvent != null) {
return preLoginEvent.getConnection().getName();
} else if (postLoginEvent != null) {
return postLoginEvent.getPlayer().getName();
} else {
return loginEvent.getConnection().getName();
}
}

@Nullable
public ProxiedPlayer getPlayer() {
if (preLoginEvent != null) {
return null;
} else if (postLoginEvent != null) {
return postLoginEvent.getPlayer();
} else {
return null;
}
}

public void setCancelReason(BaseComponent... cancelReason) {
if (preLoginEvent != null) {
preLoginEvent.setCancelReason(cancelReason);
} else if (postLoginEvent != null) {
throw new IllegalArgumentException("PostLoginEvent doesn't have method setCancelReason");
} else {
loginEvent.setCancelReason(cancelReason);
}
}

public PendingConnection getConnection() {
if (preLoginEvent != null) {
return preLoginEvent.getConnection();
} else if (postLoginEvent != null) {
throw new IllegalArgumentException("PostLoginEvent doesn't have method getConnection");
} else {
return loginEvent.getConnection();
}
}

public void setCancelled(boolean cancelled) {
if (preLoginEvent != null) {
preLoginEvent.setCancelled(true);
} else if (postLoginEvent != null) {
throw new IllegalArgumentException("PostLoginEvent doesn't have method setCancelReason");
} else {
loginEvent.setCancelled(true);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public IPInfo() {
throw new APIException(true, "Key is not defined for " + getName());
}

WebRequest.Builder builder = getDefaultBuilder("https://ipinfo.io/" + ip + "/privacy?token=" + key, getCachedConfig().getTimeout());
WebRequest.Builder builder = getDefaultBuilder("https://ipinfo.io/" + ip + "?token=" + key, getCachedConfig().getTimeout());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

HttpURLConnection conn = getConnection(builder.build());
JSONDeserializer<IPInfoModel> modelDeserializer = new JSONDeserializer<>();
return modelDeserializer.deserialize(getString(conn), IPInfoModel.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ private CachedConfig() { }
private long timeout = 5000L;
public long getTimeout() { return timeout; }

private boolean loginEvent = true;
public boolean getLoginEvent() { return loginEvent; }

private String vpnKickMessage = "&cPlease disconnect from your proxy or VPN before re-joining!";
public @NonNull String getVPNKickMessage() { return vpnKickMessage; }

Expand Down Expand Up @@ -156,6 +159,11 @@ public CachedConfig.Builder timeout(long value) {
return this;
}

public CachedConfig.Builder loginEvent(boolean value) {
values.loginEvent = value;
return this;
}

public CachedConfig.Builder vpnKickMessage(@NonNull String value) {
values.vpnKickMessage = value;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public static void reloadConfig(@NonNull File dataDirectory, @NonNull CommandIss
.ignoredIps(getIgnoredIps(config, debug, console))
.threads(config.node("connection", "threads").getInt(4))
.timeout(config.node("connection", "timeout").getLong(5000L))
.loginEvent(config.node("use-login-event").getBoolean(true))
.vpnKickMessage(config.node("action", "vpn", "kick-message").getString("&cPlease disconnect from your proxy or VPN before re-joining!"))
.vpnActionCommands(getVpnActionCommands(config, debug, console))
.mcleaksKickMessage(config.node("action", "mcleaks", "kick-message").getString("&cPlease discontinue your use of an MCLeaks account!"))
Expand Down
2 changes: 2 additions & 0 deletions Common/src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,8 @@ connection:

# When true, logs some extra output to the console so you can see if/why things might be failing
debug: false
# When true, uses login event instead of Pre/PostLoginEvent (requires restart)
use-login-event: true
# Default language (affects console output)
lang: 'en'

Expand Down