mirror of
https://github.com/TuxCoding/FastLogin.git
synced 2025-07-30 02:37:34 +02:00
Fixed json parsing for logins
This commit is contained in:
@ -24,7 +24,8 @@ import javax.crypto.spec.IvParameterSpec;
|
|||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encryption and decryption minecraft util for connection between servers and paid minecraft account clients
|
* Encryption and decryption minecraft util for connection between servers
|
||||||
|
* and paid minecraft account clients.
|
||||||
*
|
*
|
||||||
* Source: https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/MinecraftEncryption.java
|
* Source: https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/MinecraftEncryption.java
|
||||||
*
|
*
|
||||||
|
@ -76,7 +76,7 @@ public class FastLogin extends JavaPlugin {
|
|||||||
protocolManager.addPacketListener(new StartPacketListener(this, protocolManager));
|
protocolManager.addPacketListener(new StartPacketListener(this, protocolManager));
|
||||||
|
|
||||||
//register commands using a unique name
|
//register commands using a unique name
|
||||||
getCommand(getName()).setExecutor(new PremiumCommand(this));
|
getCommand("premium").setExecutor(new PremiumCommand(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -145,6 +145,7 @@ public class FastLogin extends JavaPlugin {
|
|||||||
Class<?> clazz = clazzInfo.load();
|
Class<?> clazz = clazzInfo.load();
|
||||||
//uses only member classes which uses AuthPlugin interface (skip interfaces)
|
//uses only member classes which uses AuthPlugin interface (skip interfaces)
|
||||||
if (AuthPlugin.class.isAssignableFrom(clazz)
|
if (AuthPlugin.class.isAssignableFrom(clazz)
|
||||||
|
//check only for enabled plugins. A single plugin could be disabled by plugin managers
|
||||||
&& getServer().getPluginManager().isPluginEnabled(pluginName)) {
|
&& getServer().getPluginManager().isPluginEnabled(pluginName)) {
|
||||||
authPluginHook = (AuthPlugin) clazz.newInstance();
|
authPluginHook = (AuthPlugin) clazz.newInstance();
|
||||||
getLogger().log(Level.INFO, "Hooking into auth plugin: {0}", pluginName);
|
getLogger().log(Level.INFO, "Hooking into auth plugin: {0}", pluginName);
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.github.games647.fastlogin.hooks;
|
package com.github.games647.fastlogin.hooks;
|
||||||
|
|
||||||
import fr.xephi.authme.api.NewAPI;
|
import fr.xephi.authme.api.NewAPI;
|
||||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
@ -13,12 +12,6 @@ public class AuthMeHook implements AuthPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void forceLogin(Player player) {
|
public void forceLogin(Player player) {
|
||||||
//here is the gamemode, inventory ... saved
|
|
||||||
if (!LimboCache.getInstance().hasLimboPlayer(player.getName().toLowerCase())) {
|
|
||||||
//add cache entry - otherwise logging in wouldn't work
|
|
||||||
LimboCache.getInstance().addLimboPlayer(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
//skips registration and login
|
//skips registration and login
|
||||||
NewAPI.getInstance().forceLogin(player);
|
NewAPI.getInstance().forceLogin(player);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ public class CrazyLoginHook implements AuthPlugin {
|
|||||||
if (playerData == null) {
|
if (playerData == null) {
|
||||||
//create a fake account - this will be saved to the database with the password=FAILEDLOADING
|
//create a fake account - this will be saved to the database with the password=FAILEDLOADING
|
||||||
//user cannot login with that password unless the admin uses plain text
|
//user cannot login with that password unless the admin uses plain text
|
||||||
|
//this automatically marks the player as logged in
|
||||||
playerData = new LoginPlayerData(player);
|
playerData = new LoginPlayerData(player);
|
||||||
crazyDatabase.save(playerData);
|
crazyDatabase.save(playerData);
|
||||||
} else {
|
} else {
|
||||||
|
@ -24,7 +24,7 @@ public class LoginSecurityHook implements AuthPlugin {
|
|||||||
securityPlugin.authList.remove(name);
|
securityPlugin.authList.remove(name);
|
||||||
//cancel timeout timer
|
//cancel timeout timer
|
||||||
securityPlugin.thread.timeout.remove(name);
|
securityPlugin.thread.timeout.remove(name);
|
||||||
//remove effects
|
//remove effects and restore location
|
||||||
securityPlugin.rehabPlayer(player, name);
|
securityPlugin.rehabPlayer(player, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,18 +19,20 @@ public class xAuthHook implements AuthPlugin {
|
|||||||
xAuth xAuthPlugin = xAuth.getPlugin();
|
xAuth xAuthPlugin = xAuth.getPlugin();
|
||||||
|
|
||||||
xAuthPlayer xAuthPlayer = xAuthPlugin.getPlayerManager().getPlayer(player);
|
xAuthPlayer xAuthPlayer = xAuthPlugin.getPlayerManager().getPlayer(player);
|
||||||
//we checked that the player is premium (paid account)
|
if (xAuthPlayer != null) {
|
||||||
xAuthPlayer.setPremium(true);
|
//we checked that the player is premium (paid account)
|
||||||
//mark the player online
|
xAuthPlayer.setPremium(true);
|
||||||
xAuthPlugin.getAuthClass(xAuthPlayer).online(xAuthPlayer.getName());
|
//mark the player online
|
||||||
|
xAuthPlugin.getAuthClass(xAuthPlayer).online(xAuthPlayer.getName());
|
||||||
|
|
||||||
//update last login time
|
//update last login time
|
||||||
xAuthPlayer.setLoginTime(new Timestamp(System.currentTimeMillis()));
|
xAuthPlayer.setLoginTime(new Timestamp(System.currentTimeMillis()));
|
||||||
|
|
||||||
//mark the player as logged in
|
//mark the player as logged in
|
||||||
xAuthPlayer.setStatus(Status.AUTHENTICATED);
|
xAuthPlayer.setStatus(Status.AUTHENTICATED);
|
||||||
|
|
||||||
//restore inventory
|
//restore inventory
|
||||||
xAuthPlugin.getPlayerManager().unprotect(xAuthPlayer);
|
xAuthPlugin.getPlayerManager().unprotect(xAuthPlayer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import java.util.logging.Level;
|
|||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.json.simple.JSONArray;
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
import org.json.simple.JSONValue;
|
import org.json.simple.JSONValue;
|
||||||
|
|
||||||
@ -198,9 +199,10 @@ public class EncryptionPacketListener extends PacketAdapter {
|
|||||||
String uuid = (String) userData.get("id");
|
String uuid = (String) userData.get("id");
|
||||||
String name = (String) userData.get("name");
|
String name = (String) userData.get("name");
|
||||||
|
|
||||||
JSONObject properties = (JSONObject) userData.get("properties");
|
JSONArray properties = (JSONArray) userData.get("properties");
|
||||||
|
JSONObject skinData = (JSONObject) properties.get(0);
|
||||||
//base64 encoded skin data
|
//base64 encoded skin data
|
||||||
String encodedSkin = (String) properties.get("value");
|
String encodedSkin = (String) skinData.get("value");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -218,6 +220,7 @@ public class EncryptionPacketListener extends PacketAdapter {
|
|||||||
//see StartPacketListener for packet information
|
//see StartPacketListener for packet information
|
||||||
PacketContainer startPacket = protocolManager.createPacket(PacketType.Login.Client.START, true);
|
PacketContainer startPacket = protocolManager.createPacket(PacketType.Login.Client.START, true);
|
||||||
|
|
||||||
|
//uuid is ignored
|
||||||
WrappedGameProfile fakeProfile = new WrappedGameProfile(UUID.randomUUID(), username);
|
WrappedGameProfile fakeProfile = new WrappedGameProfile(UUID.randomUUID(), username);
|
||||||
startPacket.getGameProfiles().write(0, fakeProfile);
|
startPacket.getGameProfiles().write(0, fakeProfile);
|
||||||
try {
|
try {
|
||||||
|
@ -18,6 +18,8 @@ import org.bukkit.event.player.PlayerJoinEvent;
|
|||||||
* plugin can skip authentication.
|
* plugin can skip authentication.
|
||||||
*/
|
*/
|
||||||
public class PlayerListener implements Listener {
|
public class PlayerListener implements Listener {
|
||||||
|
|
||||||
|
private static final long DELAY_LOGIN = 1 * 20L;
|
||||||
|
|
||||||
private final FastLogin plugin;
|
private final FastLogin plugin;
|
||||||
private final AuthPlugin authPlugin;
|
private final AuthPlugin authPlugin;
|
||||||
@ -46,7 +48,7 @@ public class PlayerListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Wait before auth plugin initializes the player
|
//Wait before auth plugin initializes the player
|
||||||
}, 2 * 20L);
|
}, DELAY_LOGIN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,12 +36,13 @@ public class StartPacketListener extends PacketAdapter {
|
|||||||
private static final String UUID_LINK = "https://api.mojang.com/users/profiles/minecraft/";
|
private static final String UUID_LINK = "https://api.mojang.com/users/profiles/minecraft/";
|
||||||
//this includes a-zA-Z1-9_
|
//this includes a-zA-Z1-9_
|
||||||
private static final String VALID_PLAYERNAME = "^\\w{2,16}$";
|
private static final String VALID_PLAYERNAME = "^\\w{2,16}$";
|
||||||
|
private static final int VERIFY_TOKEN_LENGTH = 4;
|
||||||
|
|
||||||
private final ProtocolManager protocolManager;
|
private final ProtocolManager protocolManager;
|
||||||
//hides the inherit Plugin plugin field, but we need a more detailed type than just Plugin
|
//hides the inherit Plugin plugin field, but we need a more detailed type than just Plugin
|
||||||
private final FastLogin plugin;
|
private final FastLogin plugin;
|
||||||
|
|
||||||
//just create a new once on plugin enable
|
//just create a new once on plugin enable. This used for verify token generation
|
||||||
private final Random random = new Random();
|
private final Random random = new Random();
|
||||||
//compile the pattern on plugin enable
|
//compile the pattern on plugin enable
|
||||||
private final Pattern playernameMatcher = Pattern.compile(VALID_PLAYERNAME);
|
private final Pattern playernameMatcher = Pattern.compile(VALID_PLAYERNAME);
|
||||||
@ -121,15 +122,15 @@ public class StartPacketListener extends PacketAdapter {
|
|||||||
|
|
||||||
newPacket.getSpecificModifier(PublicKey.class).write(0, plugin.getKeyPair().getPublic());
|
newPacket.getSpecificModifier(PublicKey.class).write(0, plugin.getKeyPair().getPublic());
|
||||||
//generate a random token which should be the same when we receive it from the client
|
//generate a random token which should be the same when we receive it from the client
|
||||||
byte[] verifyToken = new byte[4];
|
byte[] verifyToken = new byte[VERIFY_TOKEN_LENGTH];
|
||||||
random.nextBytes(verifyToken);
|
random.nextBytes(verifyToken);
|
||||||
newPacket.getByteArrays().write(0, verifyToken);
|
newPacket.getByteArrays().write(0, verifyToken);
|
||||||
|
|
||||||
protocolManager.sendServerPacket(player, newPacket);
|
protocolManager.sendServerPacket(player, newPacket);
|
||||||
|
|
||||||
//cancel only if the player has a paid account otherwise login as normal offline player
|
//cancel only if the player has a paid account otherwise login as normal offline player
|
||||||
packetEvent.setCancelled(true);
|
|
||||||
plugin.getSessions().put(sessionKey, new PlayerSession(verifyToken, username));
|
plugin.getSessions().put(sessionKey, new PlayerSession(verifyToken, username));
|
||||||
|
packetEvent.setCancelled(true);
|
||||||
} catch (InvocationTargetException ex) {
|
} catch (InvocationTargetException ex) {
|
||||||
plugin.getLogger().log(Level.SEVERE, "Cannot send encryption packet. Falling back to normal login", ex);
|
plugin.getLogger().log(Level.SEVERE, "Cannot send encryption packet. Falling back to normal login", ex);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user