forked from TuxCoding/FastLogin
Compare commits
1 Commits
add-postgr
...
0.1
Author | SHA1 | Date | |
---|---|---|---|
4eeb6c64a3 |
50
.gitignore
vendored
50
.gitignore
vendored
@ -1,8 +1,42 @@
|
||||
target/
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
# Eclipse stuff
|
||||
/.classpath
|
||||
/.project
|
||||
/.settings
|
||||
|
||||
# netbeans
|
||||
/nbproject
|
||||
nb-configuration.xml
|
||||
|
||||
# maven
|
||||
/target
|
||||
|
||||
# vim
|
||||
.*.sw[a-p]
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
# various other potential build files
|
||||
/build
|
||||
/bin
|
||||
/dist
|
||||
/manifest.mf
|
||||
*.log
|
||||
|
||||
# Mac filesystem dust
|
||||
.DS_Store
|
||||
|
||||
# intellij
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# Gradle
|
||||
.gradle
|
||||
|
||||
# Ignore Gradle GUI config
|
||||
gradle-app.setting
|
||||
|
||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||
!gradle-wrapper.jar
|
||||
|
@ -1,2 +1,7 @@
|
||||
# FastLogin
|
||||
Checks if a minecraft player has a valid paid account. If so, they can skip offline authentification.
|
||||
# mcMMOExtras
|
||||
|
||||
A visual boss bar Bukkit plugin for mcMMO that keeps people entertained and encourages them to want to level up.
|
||||
|
||||
See
|
||||
* http://dev.bukkit.org/bukkit-plugins/mcmmoextras/
|
||||
* http://www.curse.com/bukkit-plugins/minecraft/mcmmoextras
|
||||
|
198
config-from-autoin.txt
Normal file
198
config-from-autoin.txt
Normal file
@ -0,0 +1,198 @@
|
||||
Options:
|
||||
ConfigurationVersion_DO_NOT_CHANGE_THIS: 6
|
||||
|
||||
# 0 -> unlimited/as needed.
|
||||
NettyThreads: 0
|
||||
|
||||
# DON'T USE THAT IF YOU CAN USE SOCKETS, Enable when you can't use sockets but you want use that on bungee server, it isn't good as sockets, but it should not explode. NOTE: You NEED MySQL for that, and this is slower and may by VERY buggy on first join.
|
||||
UseChannels: false
|
||||
|
||||
# Time in ms between trying connect LISTENER to HANLDER socket, on linux using smaller times can cause some weird problems.
|
||||
ReTryConnectSocketTime: 250
|
||||
|
||||
# where AutoIn should store exceptions, enabled login, whitelists, cache and other player settings.
|
||||
SaveData:
|
||||
Type: MySQL
|
||||
MySQL:
|
||||
Host: localhost
|
||||
Port: 3306
|
||||
User: minecraft
|
||||
Pass:
|
||||
Database: minecraft
|
||||
Prefix: AutoIn_
|
||||
SQLite:
|
||||
File: AutoIn_PlayerOptions.db
|
||||
|
||||
# Both
|
||||
|
||||
Both:
|
||||
|
||||
Dependencies:
|
||||
|
||||
# If you have one of that plugin, you can force AutoIn to don't use them even if they can be used. (change to true)
|
||||
ForceDisable:
|
||||
ProtocolLib: false
|
||||
Skript: false
|
||||
AuthMe: false
|
||||
LogIt: false
|
||||
XAuth: false
|
||||
LoginSecurity: false
|
||||
|
||||
Listeners:
|
||||
|
||||
# you can try disable that and manualy configure priority below if auto-login will stop work after update of auth pluhin. PS: tell me about that problem!
|
||||
GetFromModule: true
|
||||
PlayerLoginEvent: LOWEST
|
||||
PlayerJoinEvent: LOWEST
|
||||
PlayerQuitEvent: MONITOR
|
||||
|
||||
Players:
|
||||
|
||||
# no more /login commands for premium users! Enable only on servers where you have auth plugin!
|
||||
AutoLogin: true
|
||||
|
||||
# if true autoin will try fix skins, you can disable that if you want use other plugin. (some plugins may still not work)
|
||||
FixSkins: true
|
||||
|
||||
# if true, then all players are exception by default, they can use /ai IAmNowPremium to remove exception flag (NOTE: they will lose all data after login as premium if you have fixedUUIDs set to false)
|
||||
NegateExceptions: false
|
||||
|
||||
# if true, then even premium players needs to register. PS: You can make registration optional, see wiki: https://github.com/GotoFinal/AutoIn/wiki/Registration
|
||||
Registration: true
|
||||
|
||||
# A.K.A. SwitchMode, If you disable that, only old cracked players will be able to join. New cracked players will be kicked from server. Good if you want switch from offline-mode to online-mode without losing players!
|
||||
AllowNewCrackedPlayers: true
|
||||
|
||||
# if true, then everyone have UUID generated from nickname
|
||||
FixedUUID: false
|
||||
|
||||
# WhiteList that works only on cracked players, black-list works even if this is disabled.
|
||||
CrackedWhiteListEnabled: false
|
||||
|
||||
ForceLogin:
|
||||
|
||||
# Allow use RegEx in nicknames list, like 'Test\\d{1,3}'
|
||||
UseRegEx: false
|
||||
|
||||
# Nicknames from this list don't need use login or register command, use to supprot mods like buildcraft and others
|
||||
Nicknames:
|
||||
- SomeNicknameThatDoNotNeedUseLoginOrRegisterCommandEvenIfHeDoNotHavePremium
|
||||
|
||||
Sessions:
|
||||
|
||||
# If enabled, plugin will remember premium players with their IP number, when servers will be down, premium players can be still auto-logged if IP will be valid.
|
||||
Enabled: true
|
||||
|
||||
# If true, then players with valid session can join even if mojang server are down and without using password. PS: You can enable this and ServerProtect, then registered players OR players with valid session can join.
|
||||
AsServerProtect: true
|
||||
|
||||
# time in easy format, 1w = 1 week, 1d = 1 day, 1d5h12s -> 1 day, 5 hours, 12 seconds
|
||||
Expires: 1d
|
||||
|
||||
# If true sessions aren't saved on reload.
|
||||
ExpiresOnRestart: true
|
||||
|
||||
Protections:
|
||||
|
||||
# If enabled, when new cracked player join to game he will get special protection "flag", that work like exception-player. so even if someone buy premium account with this same nickname, he will be still tract as cracked player.
|
||||
# If player will buy premium, he must disable protection using "IamNowPremium" command, or admin must disable it manually, using API or /setProtection command.
|
||||
CrackedPlayersNicknames:
|
||||
Enabled: true
|
||||
|
||||
# If disabled, player must use "ProtectMe" command, or protection must be enabled manually, using API or /setProtection command
|
||||
AutoProtect: true
|
||||
|
||||
|
||||
|
||||
ServerProtect:
|
||||
|
||||
# If enabled and mojang server don't work, only registered players can join (So you must set "Registration" to true). If disabled, all players will be kicked.
|
||||
Enabled: false
|
||||
|
||||
|
||||
# If enabled plugin will remember if username was premium. (It's saved to database/file) NOTE: Enable that if you have bigger server, like 100/200+ players online.
|
||||
Cache: true
|
||||
|
||||
# Server
|
||||
|
||||
|
||||
# ignored by proxy plugin
|
||||
Server:
|
||||
|
||||
|
||||
# It will try check if cache is updated before player join.
|
||||
UpdateCacheOnPreJoin: false
|
||||
|
||||
# It will try check if cache is updated after player join.
|
||||
UpdateCacheOnJoin: true
|
||||
|
||||
|
||||
# Proxy
|
||||
|
||||
|
||||
# ignored by server
|
||||
Proxy:
|
||||
|
||||
# Players needs to be logged in to use commands
|
||||
NeedLoginToUseCommands: true
|
||||
|
||||
# Player can use this commands
|
||||
NotBlocked:
|
||||
- /login
|
||||
- /register
|
||||
- /l
|
||||
|
||||
# players from selected group can be send to other servers. This override Proxy/BungeeCord setting!
|
||||
ForcedServers:
|
||||
PREMIUM:
|
||||
Enabled: false
|
||||
|
||||
# works like "default_server" from bungee
|
||||
Server: PremiumServer
|
||||
|
||||
# works like "force_default_server" from bungee
|
||||
Force: false
|
||||
|
||||
# works like "forced_hosts" from bungee -> this override "Force" option
|
||||
ForcedHosts:
|
||||
eg: nul.goto. ...\\.. .final..IIlIlIIlIl@71c66aab
|
||||
|
||||
# like "fallback_server" from bungee
|
||||
Fallback: FallbackServer
|
||||
CRACKED:
|
||||
Enabled: true
|
||||
|
||||
# works like "default_server" from bungee
|
||||
Server: CrackedServer
|
||||
|
||||
# works like "force_default_server" from bungee
|
||||
Force: true
|
||||
|
||||
# like "fallback_server" from bungee
|
||||
Fallback: FallbackServer
|
||||
EXCEPTION:
|
||||
Enabled: false
|
||||
|
||||
# works like "default_server" from bungee
|
||||
Server: PremiumServer
|
||||
|
||||
# works like "force_default_server" from bungee
|
||||
Force: true
|
||||
|
||||
# like "fallback_server" from bungee
|
||||
Fallback: FallbackServer
|
||||
|
||||
# This status will use this same settings as parent status, but you can override that settings by adding them here.
|
||||
Parent: CRACKED
|
||||
ERROR:
|
||||
Enabled: false
|
||||
|
||||
# works like "default_server" from bungee
|
||||
Server: ErrorServer
|
||||
|
||||
# works like "force_default_server" from bungee
|
||||
Force: false
|
||||
|
||||
# like "fallback_server" from bungee
|
||||
Fallback: FallbackServer
|
||||
|
149
pom.xml
Normal file
149
pom.xml
Normal file
@ -0,0 +1,149 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.github.games647</groupId>
|
||||
<!--This have to be in lowercase because it's used by plugin.yml-->
|
||||
<artifactId>fastlogin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>FastLogin</name>
|
||||
<version>0.1</version>
|
||||
<inceptionYear>2015</inceptionYear>
|
||||
<url>http://dev.bukkit.org/bukkit-plugins/fastlogin</url>
|
||||
<description>
|
||||
Automatically logins premium player on a offline mode server
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!--Possibility to deploy directly to the plugins folder-->
|
||||
<outputDir>${basedir}/target</outputDir>
|
||||
</properties>
|
||||
|
||||
<issueManagement>
|
||||
<system>GitHub</system>
|
||||
<url>https://github.com/games647/FastLogin/issues</url>
|
||||
</issueManagement>
|
||||
|
||||
<scm>
|
||||
<url>https://github.com/games647/FastLogin</url>
|
||||
<connection>scm:git:git://github.com/games647/FastLogin.git</connection>
|
||||
<developerConnection>scm:git:ssh://git@github.com:games647/FastLogin.git</developerConnection>
|
||||
</scm>
|
||||
|
||||
<build>
|
||||
<defaultGoal>install</defaultGoal>
|
||||
<!--Just use the project name to replace an old version of the plugin if the user does only copy-paste-->
|
||||
<finalName>${project.name}</finalName>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.2</version>
|
||||
<configuration>
|
||||
<!--So many people still use Java 6 ;( http://mcstats.org/global/#Java+Version-->
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
<showWarnings>true</showWarnings>
|
||||
<showDeprecation>true</showDeprecation>
|
||||
<!--false means actual true http://jira.codehaus.org/browse/MCOMPILER-209-->
|
||||
<useIncrementalCompilation>false</useIncrementalCompilation>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
<configuration>
|
||||
<outputDirectory>${outputDir}</outputDirectory>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<!--Replace variables-->
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
|
||||
<!--Add the license to jar in order to see it in the final jar-->
|
||||
<resource>
|
||||
<directory>${basedir}</directory>
|
||||
<includes>
|
||||
<include>LICENSE</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<!--Bukkit-Server-API -->
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
|
||||
<!--ProtocolLib-->
|
||||
<repository>
|
||||
<id>dmulloy2-repo</id>
|
||||
<url>http://repo.dmulloy2.net/content/groups/public/</url>
|
||||
</repository>
|
||||
|
||||
<!--Authme Reloaded-->
|
||||
<repository>
|
||||
<id>xephi-repo</id>
|
||||
<url>http://ci.xephi.fr/plugin/repository/everything/</url>
|
||||
</repository>
|
||||
|
||||
<!--xAuth-->
|
||||
<repository>
|
||||
<id>luricos.de-repo</id>
|
||||
<url>http://repo.luricos.de/bukkit-plugins/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!--Server API-->
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>1.8.8-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--Library for listening and sending Minecraft packets-->
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<version>3.6.3-SNAPSHOT</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!--Login Plugins-->
|
||||
<dependency>
|
||||
<groupId>fr.xephi</groupId>
|
||||
<artifactId>authme</artifactId>
|
||||
<version>5.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>de.luricos.bukkit</groupId>
|
||||
<artifactId>xAuth</artifactId>
|
||||
<version>2.6</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>net.gravitydevelopment.updater</groupId>
|
||||
<artifactId>updater</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>EssentialsGroupManager</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
93
src/main/java/com/github/games647/fastlogin/FastLogin.java
Normal file
93
src/main/java/com/github/games647/fastlogin/FastLogin.java
Normal file
@ -0,0 +1,93 @@
|
||||
package com.github.games647.fastlogin;
|
||||
|
||||
import com.github.games647.fastlogin.listener.PlayerListener;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.github.games647.fastlogin.listener.EncryptionPacketListener;
|
||||
import com.github.games647.fastlogin.listener.StartPacketListener;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class FastLogin extends JavaPlugin {
|
||||
|
||||
private final KeyPair keyPair = generateKey();
|
||||
private final Cache<String, PlayerData> session = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(2, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
if (!isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!getServer().getPluginManager().isPluginEnabled("AuthMe")
|
||||
&& !getServer().getPluginManager().isPluginEnabled("xAuth")) {
|
||||
getLogger().warning("No support offline Auth plugin found. ");
|
||||
getLogger().warning("Disabling this plugin...");
|
||||
|
||||
setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
|
||||
protocolManager.addPacketListener(new EncryptionPacketListener(this, protocolManager));
|
||||
protocolManager.addPacketListener(new StartPacketListener(this, protocolManager));
|
||||
|
||||
getServer().getPluginManager().registerEvents(new PlayerListener(this), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
//online mode is only changeable aftter a restart
|
||||
if (getServer().getOnlineMode()) {
|
||||
getLogger().severe("Server have to be in offline mode");
|
||||
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
generateKey();
|
||||
}
|
||||
|
||||
private KeyPair generateKey() {
|
||||
try {
|
||||
KeyPairGenerator keypairgenerator = KeyPairGenerator.getInstance("RSA");
|
||||
|
||||
keypairgenerator.initialize(1024);
|
||||
return keypairgenerator.generateKeyPair();
|
||||
} catch (NoSuchAlgorithmException noSuchAlgorithmException) {
|
||||
//Should be default existing in every vm
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Cache<String, PlayerData> getSession() {
|
||||
return session;
|
||||
}
|
||||
|
||||
public KeyPair getKeyPair() {
|
||||
return keyPair;
|
||||
}
|
||||
|
||||
public HttpURLConnection getConnection(String url) throws IOException {
|
||||
final HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
|
||||
connection.setConnectTimeout(15000);
|
||||
connection.setReadTimeout(15000);
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setRequestProperty("User-Agent", "Premium-Checker");
|
||||
|
||||
return connection;
|
||||
}
|
||||
}
|
20
src/main/java/com/github/games647/fastlogin/PlayerData.java
Normal file
20
src/main/java/com/github/games647/fastlogin/PlayerData.java
Normal file
@ -0,0 +1,20 @@
|
||||
package com.github.games647.fastlogin;
|
||||
|
||||
public class PlayerData {
|
||||
|
||||
private final byte[] verifyToken;
|
||||
private final String username;
|
||||
|
||||
public PlayerData(byte[] verifyToken, String username) {
|
||||
this.username = username;
|
||||
this.verifyToken = verifyToken;
|
||||
}
|
||||
|
||||
public byte[] getVerifyToken() {
|
||||
return verifyToken;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
package com.github.games647.fastlogin.listener;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.injector.server.SocketInjector;
|
||||
import com.comphenix.protocol.injector.server.TemporaryPlayerFactory;
|
||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
import com.github.games647.fastlogin.FastLogin;
|
||||
import com.github.games647.fastlogin.PlayerData;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.security.PrivateKey;
|
||||
import java.util.Arrays;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
import net.minecraft.server.v1_8_R3.MinecraftEncryption;
|
||||
import net.minecraft.server.v1_8_R3.NetworkManager;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
|
||||
public class EncryptionPacketListener extends PacketAdapter {
|
||||
|
||||
private static final String HAS_JOINED_URL = "https://sessionserver.mojang.com/session/minecraft/hasJoined?";
|
||||
|
||||
private final ProtocolManager protocolManager;
|
||||
private final FastLogin fastLogin;
|
||||
|
||||
public EncryptionPacketListener(FastLogin plugin, ProtocolManager protocolManger) {
|
||||
super(params(plugin, PacketType.Login.Client.ENCRYPTION_BEGIN).optionAsync());
|
||||
|
||||
this.fastLogin = plugin;
|
||||
this.protocolManager = protocolManger;
|
||||
}
|
||||
|
||||
/*
|
||||
* C->S : Handshake State=2
|
||||
* C->S : Login Start
|
||||
* S->C : Encryption Key Request
|
||||
* (Client Auth)
|
||||
* C->S : Encryption Key Response
|
||||
* (Server Auth, Both enable encryption)
|
||||
* S->C : Login Success (*)
|
||||
*/
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent event) {
|
||||
PacketContainer packet = event.getPacket();
|
||||
Player player = event.getPlayer();
|
||||
|
||||
final byte[] sharedSecret = packet.getByteArrays().read(0);
|
||||
byte[] clientVerify = packet.getByteArrays().read(1);
|
||||
|
||||
PrivateKey privateKey = fastLogin.getKeyPair().getPrivate();
|
||||
|
||||
String addressString = player.getAddress().toString();
|
||||
PlayerData cachedEntry = fastLogin.getSession().asMap().get(addressString);
|
||||
byte[] serverVerify = cachedEntry.getVerifyToken();
|
||||
if (!Arrays.equals(serverVerify, MinecraftEncryption.b(privateKey, clientVerify))) {
|
||||
player.kickPlayer("Invalid token");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
//encrypt all following packets
|
||||
NetworkManager networkManager = getNetworkManager(event);
|
||||
SecretKey loginKey = MinecraftEncryption.a(privateKey, sharedSecret);
|
||||
networkManager.a(loginKey);
|
||||
String serverId = (new BigInteger(MinecraftEncryption.a("", fastLogin.getKeyPair().getPublic(), loginKey)))
|
||||
.toString(16);
|
||||
|
||||
String username = cachedEntry.getUsername();
|
||||
if (!hasJoinedServer(username, serverId)) {
|
||||
//user tried to fake a authentification
|
||||
player.kickPlayer("Invalid session");
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
//fake a new login packet
|
||||
PacketContainer startPacket = protocolManager.createPacket(PacketType.Login.Client.START, true);
|
||||
WrappedGameProfile fakeProfile = WrappedGameProfile.fromOfflinePlayer(Bukkit.getOfflinePlayer(username));
|
||||
startPacket.getGameProfiles().write(0, fakeProfile);
|
||||
try {
|
||||
protocolManager.recieveClientPacket(event.getPlayer(), startPacket, false);
|
||||
} catch (InvocationTargetException | IllegalAccessException ex) {
|
||||
plugin.getLogger().log(Level.WARNING, null, ex);
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
private NetworkManager getNetworkManager(PacketEvent event) throws IllegalArgumentException {
|
||||
SocketInjector injector = TemporaryPlayerFactory.getInjectorFromPlayer(event.getPlayer());
|
||||
NetworkManager networkManager = null;
|
||||
try {
|
||||
Field declaredField = injector.getClass().getDeclaredField("injector");
|
||||
declaredField.setAccessible(true);
|
||||
|
||||
Object rawInjector = declaredField.get(injector);
|
||||
|
||||
declaredField = rawInjector.getClass().getDeclaredField("networkManager");
|
||||
declaredField.setAccessible(true);
|
||||
networkManager = (NetworkManager) declaredField.get(rawInjector);
|
||||
} catch (IllegalAccessException | NoSuchFieldException ex) {
|
||||
plugin.getLogger().log(Level.WARNING, null, ex);
|
||||
}
|
||||
|
||||
return networkManager;
|
||||
}
|
||||
|
||||
private boolean hasJoinedServer(String username, String serverId) {
|
||||
try {
|
||||
String url = HAS_JOINED_URL + "username=" + username + "&serverId=" + serverId;
|
||||
|
||||
HttpURLConnection conn = fastLogin.getConnection(url);
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
String line = reader.readLine();
|
||||
if (!line.equals("null")) {
|
||||
JSONObject object = (JSONObject) JSONValue.parse(line);
|
||||
String uuid = (String) object.get("id");
|
||||
String name = (String) object.get("name");
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
plugin.getLogger().log(Level.WARNING, null, ex);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.github.games647.fastlogin.listener;
|
||||
|
||||
import com.github.games647.fastlogin.FastLogin;
|
||||
|
||||
import de.luricos.bukkit.xAuth.xAuth;
|
||||
import de.luricos.bukkit.xAuth.xAuthPlayer;
|
||||
import de.luricos.bukkit.xAuth.xAuthPlayer.Status;
|
||||
|
||||
import fr.xephi.authme.api.NewAPI;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
public class PlayerListener implements Listener {
|
||||
|
||||
private final FastLogin plugin;
|
||||
|
||||
public PlayerListener(FastLogin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true)
|
||||
public void onJoin(PlayerJoinEvent joinEvent) {
|
||||
final Player player = joinEvent.getPlayer();
|
||||
String address = player.getAddress().toString();
|
||||
if (plugin.getSession().asMap().containsKey(address)) {
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||
doLogin(player);
|
||||
}, 1 * 20L);
|
||||
}
|
||||
}
|
||||
|
||||
private void doLogin(Player player) {
|
||||
if (Bukkit.getPluginManager().isPluginEnabled("AuthMe")) {
|
||||
//add cache entry - otherwise loggin wouldn't work
|
||||
LimboCache.getInstance().addLimboPlayer(player);
|
||||
|
||||
//skips registration and login
|
||||
NewAPI.getInstance().forceLogin(player);
|
||||
} else if (Bukkit.getPluginManager().isPluginEnabled("xAuth")) {
|
||||
xAuth xAuthPlugin = xAuth.getPlugin();
|
||||
|
||||
xAuthPlayer xAuthPlayer = xAuthPlugin.getPlayerManager().getPlayer(player);
|
||||
xAuthPlayer.setPremium(true);
|
||||
xAuthPlugin.getAuthClass(xAuthPlayer).online(xAuthPlayer.getName());
|
||||
xAuthPlayer.setLoginTime(new Timestamp(System.currentTimeMillis()));
|
||||
|
||||
xAuthPlayer.setStatus(Status.AUTHENTICATED);
|
||||
|
||||
xAuthPlugin.getPlayerManager().unprotect(xAuthPlayer);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.github.games647.fastlogin.listener;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.github.games647.fastlogin.FastLogin;
|
||||
import com.github.games647.fastlogin.PlayerData;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.security.PublicKey;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class StartPacketListener extends PacketAdapter {
|
||||
|
||||
//only premium members have a uuid from there
|
||||
private static final String UUID_LINK = "https://api.mojang.com/users/profiles/minecraft/";
|
||||
|
||||
private final ProtocolManager protocolManager;
|
||||
private final FastLogin fastLogin;
|
||||
|
||||
private final Random random = new Random();
|
||||
|
||||
public StartPacketListener(FastLogin plugin, ProtocolManager protocolManger) {
|
||||
super(params(plugin, PacketType.Login.Client.START).optionAsync());
|
||||
|
||||
this.fastLogin = plugin;
|
||||
this.protocolManager = protocolManger;
|
||||
}
|
||||
|
||||
/*
|
||||
* C->S : Handshake State=2
|
||||
* C->S : Login Start
|
||||
* S->C : Encryption Key Request
|
||||
* (Client Auth)
|
||||
* C->S : Encryption Key Response
|
||||
* (Server Auth, Both enable encryption)
|
||||
* S->C : Login Success (*)
|
||||
*/
|
||||
@Override
|
||||
public void onPacketReceiving(PacketEvent packetEvent) {
|
||||
PacketContainer packet = packetEvent.getPacket();
|
||||
Player player = packetEvent.getPlayer();
|
||||
|
||||
String username = packet.getGameProfiles().read(0).getName();
|
||||
if (isPremium(username)) {
|
||||
//do premium login process
|
||||
try {
|
||||
PacketContainer newPacket = protocolManager.createPacket(PacketType.Login.Server.ENCRYPTION_BEGIN, true);
|
||||
|
||||
//constr ServerID=""
|
||||
//public key=plugin.getPublic
|
||||
newPacket.getSpecificModifier(PublicKey.class).write(0, fastLogin.getKeyPair().getPublic());
|
||||
byte[] verifyToken = new byte[4];
|
||||
random.nextBytes(verifyToken);
|
||||
newPacket.getByteArrays().write(0, verifyToken);
|
||||
|
||||
String addressString = player.getAddress().toString();
|
||||
fastLogin.getSession().asMap().put(addressString, new PlayerData(verifyToken, username));
|
||||
|
||||
protocolManager.sendServerPacket(player, newPacket, false);
|
||||
} catch (InvocationTargetException ex) {
|
||||
plugin.getLogger().log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
//cancel only if the player is premium
|
||||
packetEvent.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPremium(String playerName) {
|
||||
try {
|
||||
final HttpURLConnection connection = fastLogin.getConnection(UUID_LINK + playerName);
|
||||
final int responseCode = connection.getResponseCode();
|
||||
|
||||
return responseCode == HttpURLConnection.HTTP_OK;
|
||||
} catch (IOException ex) {
|
||||
plugin.getLogger().log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
14
src/main/resources/plugin.yml
Normal file
14
src/main/resources/plugin.yml
Normal file
@ -0,0 +1,14 @@
|
||||
# project informations for Bukkit in order to register our plugin with all it components
|
||||
# ${project.name} are variables from Maven (pom.xml) which will be replaced after the build
|
||||
name: ${project.name}
|
||||
version: ${project.version}
|
||||
main: ${project.groupId}.${project.artifactId}.${project.name}
|
||||
|
||||
# meta informations for plugin managers
|
||||
authors: [Xeroun, games647, 'https://github.com/games647/FastLogin/graphs/contributors']
|
||||
description: |
|
||||
${project.description}
|
||||
website: ${project.url}
|
||||
dev-url: ${project.url}
|
||||
|
||||
depend: [ProtocolLib]
|
Reference in New Issue
Block a user