Skip to content

Commit

Permalink
Redesign authCompleteAsync and implement a Bukkit Event
Browse files Browse the repository at this point in the history
  • Loading branch information
Brianetta committed Feb 19, 2018
1 parent 6ca1c6b commit 87af64b
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 15 deletions.
4 changes: 3 additions & 1 deletion 1.10.2/src/main/java/net/dries007/mclink/MCLink.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

package net.dries007.mclink;

import com.google.common.collect.ImmutableCollection;
import com.mojang.authlib.GameProfile;
import net.dries007.mclink.api.APIException;
import net.dries007.mclink.api.Authentication;
import net.dries007.mclink.api.Constants;
import net.dries007.mclink.binding.FormatCode;
import net.dries007.mclink.binding.IConfig;
Expand Down Expand Up @@ -104,7 +106,7 @@ public void loginEvent(PlayerLoggedInEvent event)
}

@Override
protected void authCompleteAsync(IPlayer player, String msg)
protected void authCompleteAsync(IPlayer player, String msg, UUID name, ImmutableCollection<Authentication> authentications)
{
server.addScheduledTask(() -> {
EntityPlayerMP p = server.getPlayerList().getPlayerByUUID(player.getUuid());
Expand Down
4 changes: 3 additions & 1 deletion 1.12.2/src/main/java/net/dries007/mclink/MCLink.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

package net.dries007.mclink;

import com.google.common.collect.ImmutableCollection;
import com.mojang.authlib.GameProfile;
import net.dries007.mclink.api.APIException;
import net.dries007.mclink.api.Authentication;
import net.dries007.mclink.api.Constants;
import net.dries007.mclink.binding.FormatCode;
import net.dries007.mclink.binding.IConfig;
Expand Down Expand Up @@ -94,7 +96,7 @@ public void loginEvent(PlayerLoggedInEvent event)
}

@Override
protected void authCompleteAsync(IPlayer player, String msg)
protected void authCompleteAsync(IPlayer player, String msg, UUID name, ImmutableCollection<Authentication> authentications)
{
server.addScheduledTask(() -> {
EntityPlayerMP p = server.getPlayerList().getPlayerByUUID(player.getUuid());
Expand Down
4 changes: 3 additions & 1 deletion 1.12/src/main/java/net/dries007/mclink/MCLink.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@

package net.dries007.mclink;

import com.google.common.collect.ImmutableCollection;
import com.mojang.authlib.GameProfile;
import net.dries007.mclink.api.APIException;
import net.dries007.mclink.api.Authentication;
import net.dries007.mclink.api.Constants;
import net.dries007.mclink.binding.FormatCode;
import net.dries007.mclink.binding.IConfig;
Expand Down Expand Up @@ -101,7 +103,7 @@ public void loginEvent(PlayerLoggedInEvent event)
}

@Override
protected void authCompleteAsync(IPlayer player, String msg)
protected void authCompleteAsync(IPlayer player, String msg, UUID name, ImmutableCollection<Authentication> authentications)
{
server.addScheduledTask(() -> {
EntityPlayerMP p = server.getPlayerList().getPlayerByUUID(player.getUuid());
Expand Down
4 changes: 3 additions & 1 deletion 1.7.10/src/main/java/net/dries007/mclink/MCLink.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package net.dries007.mclink;

import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableCollection;
import com.mojang.authlib.GameProfile;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
Expand All @@ -17,6 +18,7 @@
import cpw.mods.fml.common.network.FMLNetworkEvent;
import cpw.mods.fml.relauncher.ReflectionHelper;
import net.dries007.mclink.api.APIException;
import net.dries007.mclink.api.Authentication;
import net.dries007.mclink.api.Constants;
import net.dries007.mclink.binding.FormatCode;
import net.dries007.mclink.binding.IConfig;
Expand Down Expand Up @@ -142,7 +144,7 @@ public void tickEvent(TickEvent.ServerTickEvent event)
}

@Override
protected void authCompleteAsync(IPlayer player, String msg)
protected void authCompleteAsync(IPlayer player, String msg, UUID name, ImmutableCollection<Authentication> authentications)
{
// 1.7.10 doesn't have threading, so use server tick even to sync.
TO_KICK.put(player.getName(), msg);
Expand Down
19 changes: 17 additions & 2 deletions Bukkit/src/main/java/net/dries007/mclink/MCLink.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
package net.dries007.mclink;

import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableCollection;
import net.dries007.mclink.api.Authentication;
import net.dries007.mclink.binding.FormatCode;
import net.dries007.mclink.binding.IPlayer;
import net.dries007.mclink.common.JavaLogger;
Expand All @@ -17,6 +19,7 @@
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.Nullable;

import java.util.UUID;
Expand All @@ -41,9 +44,21 @@ public void sendMessage(String message, FormatCode formatCode)
}

@Override
protected void authCompleteAsync(IPlayer player, String msg)
protected void authCompleteAsync(IPlayer player, String msg, UUID name, ImmutableCollection<Authentication> authentications)
{
Bukkit.getScheduler().runTask(MCLink.this, () -> Bukkit.getPlayer(player.getUuid()).kickPlayer(msg));
if (authentications == null) {
// null authentications means "kick"
Bukkit.getScheduler().runTask(MCLink.this, () -> Bukkit.getPlayer(player.getUuid()).kickPlayer(msg));
} else {
// Authentication returned something, now schedule a synchronous Event for Bukkit plugins to handle
new BukkitRunnable() {
@Override
public void run() {
// Call the event with a Bukkit player and the list of authentications
Bukkit.getServer().getPluginManager().callEvent(new MCLinkAuthEvent(Bukkit.getPlayer(player.getUuid()), authentications));
}
}.runTask(MCLink.this);
}
}

@Nullable
Expand Down
38 changes: 38 additions & 0 deletions Bukkit/src/main/java/net/dries007/mclink/MCLinkAuthEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package net.dries007.mclink;

/*
* Copyright (c) 2018 Dries007 & Brian Ronald. All rights reserved
*/

import com.google.common.collect.ImmutableCollection;
import net.dries007.mclink.api.Authentication;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;

public class MCLinkAuthEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private ImmutableCollection<Authentication> authentication;
private org.bukkit.entity.Player player;

public MCLinkAuthEvent(org.bukkit.entity.Player player, ImmutableCollection<Authentication> authentication) {
this.player = player;
this.authentication = authentication;
}

@Override
public HandlerList getHandlers() {
return handlers;
}

public static HandlerList getHandlerList() {
return handlers;
}

public org.bukkit.entity.Player getPlayer() {
return player;
}

public ImmutableCollection<Authentication> getAuthentication() {
return authentication;
}
}
27 changes: 18 additions & 9 deletions src/main/java/net/dries007/mclink/common/MCLinkCommon.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public abstract class MCLinkCommon implements IMinecraft
private Status latestStatus;
private String branding;

protected abstract void authCompleteAsync(IPlayer player, String msg);
protected abstract void authCompleteAsync(IPlayer player, String msg, UUID name, ImmutableCollection<Authentication> authentications);

@Nullable
protected abstract String nameFromUUID(UUID uuid);
Expand Down Expand Up @@ -81,13 +81,14 @@ public void login(IPlayer player, boolean sendStatus)
case IN_PROGRESS:
break;
case DENIED_NO_AUTH:
authCompleteAsync(player, config.getKickMessage());
// null authentications means "kick"
authCompleteAsync(player, config.getKickMessage(), player.getUuid(), null);
return;
case DENIED_ERROR:
authCompleteAsync(player, config.getErrorMessage());
authCompleteAsync(player, config.getErrorMessage(), player.getUuid(), null);
return;
case DENIED_CLOSED:
authCompleteAsync(player, config.getClosedMessage());
authCompleteAsync(player, config.getClosedMessage(), player.getUuid(), null);
return;
}
if (sendStatus && latestStatus != null && config.isShowStatus())
Expand Down Expand Up @@ -208,6 +209,9 @@ public void checkAuthStatusAsync(@NotNull IPlayer player, boolean oped, boolean
if (config.isFreeToJoin()) {
logger.info("Player {0} was authorized because the server is allowing all players", player);
UUID_STATUS_MAP.put(player.getUuid(), Marker.ALLOWED);
// Want to check status anyway, so we can maybe fire off an Event
logger.info("Player {0} authorization is being checked anyway...", player);
runner.accept(() -> check(player, true));
return;
}

Expand All @@ -228,22 +232,24 @@ public void checkAuthStatusAsync(@NotNull IPlayer player, boolean oped, boolean
UUID_STATUS_MAP.put(player.getUuid(), Marker.IN_PROGRESS);
logger.info("Player {0} authorization is being checked...", player);

runner.accept(() -> check(player));
// At this point, we're a non-free server awaiting auth. Free is false.
runner.accept(() -> check(player, false));
}

private void check(IPlayer player)
private void check(IPlayer player,boolean free)
{
try
{
ImmutableMultimap<UUID, Authentication> map = API.getAuthorization(config.getTokenConfig(), player.getUuid());
ImmutableCollection<Authentication> auth = map.get(player.getUuid());
if (auth.isEmpty())
if (auth.isEmpty() & !free)
{
logger.info("Player {0} authorization was denied by MCLink.", player);
if (UUID_STATUS_MAP.put(player.getUuid(), Marker.DENIED_NO_AUTH) == null) // was already removed by login
{
UUID_STATUS_MAP.remove(player.getUuid()); // login event already past, so we don't need this anymore.
authCompleteAsync(player, config.getKickMessage());
// null authentications means "kick"
authCompleteAsync(player, config.getKickMessage(), player.getUuid(), null);
}
}
else
Expand All @@ -256,6 +262,8 @@ private void check(IPlayer player)
auths.add(a.name + " from " + (name == null ? a.token : name + "[" + a.token + "]") + " with " + a.extra);
}
logger.info("Player {0} was authorized by: {1}", player, auths);
// send the authentications to the mod in question
authCompleteAsync(player, null, player.getUuid(), auth);
if (UUID_STATUS_MAP.put(player.getUuid(), Marker.ALLOWED) == null) // was already removed by login
{
UUID_STATUS_MAP.remove(player.getUuid()); // login event already passed, so we don't need this anymore.
Expand All @@ -270,7 +278,8 @@ private void check(IPlayer player)
if (UUID_STATUS_MAP.put(player.getUuid(), Marker.DENIED_ERROR) == null) // was already removed by login
{
UUID_STATUS_MAP.remove(player.getUuid()); // login event already past, so we don't need this anymore.
authCompleteAsync(player, config.getErrorMessage());
// null authentications means "kick"
authCompleteAsync(player, config.getErrorMessage(), player.getUuid(), null);
}
}
}
Expand Down

0 comments on commit 87af64b

Please sign in to comment.