mirror of
https://github.com/TuxCoding/FastLogin.git
synced 2025-07-29 10:17:38 +02:00
Clean up using IDE inspections
This commit is contained in:
25
.github/ISSUE_TEMPLATE.md
vendored
Normal file
25
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
#### Make sure you are running the latest build of the plugin and checked for duplicate issues!
|
||||
|
||||
### What behaviour is observed:
|
||||
What happened?
|
||||
|
||||
### What behaviour is expected:
|
||||
What did you expect?
|
||||
|
||||
### Steps/models to reproduce:
|
||||
The actions that cause the issue
|
||||
|
||||
### Plugin list:
|
||||
This can be found by running `/pl`
|
||||
|
||||
### Environment description
|
||||
Standalone server/Bungeecord network, SQLite/MySql, ...
|
||||
|
||||
### Plugin version:
|
||||
This can be found by running `/version plugin-name`
|
||||
|
||||
### Error Log:
|
||||
[Hastebin](https://hastebin.com/) / [Gist](https://gist.github.com/) link of the error or stacktrace (if any)
|
||||
|
||||
### Configuration:
|
||||
[Hastebin](https://hastebin.com/) / [Gist](https://gist.github.com/) link of your config.yml file (remember to delete any sensitive data)
|
19
.gitignore
vendored
19
.gitignore
vendored
@ -3,22 +3,21 @@
|
||||
/.project
|
||||
/.settings
|
||||
|
||||
# netbeans
|
||||
/nbproject
|
||||
# NetBeans
|
||||
*/nbproject
|
||||
nb-configuration.xml
|
||||
/bukkit/nbproject/
|
||||
|
||||
# maven
|
||||
/target
|
||||
*/target
|
||||
|
||||
# vim
|
||||
.*.sw[a-p]
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
# virtual machine crash logs, see https://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
# various other potential build files
|
||||
/build
|
||||
*/build/
|
||||
/bin
|
||||
/dist
|
||||
/manifest.mf
|
||||
@ -27,7 +26,7 @@ hs_err_pid*
|
||||
# Mac filesystem dust
|
||||
.DS_Store
|
||||
|
||||
# intellij
|
||||
# IntelliJ
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
@ -41,9 +40,3 @@ gradle-app.setting
|
||||
|
||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||
!gradle-wrapper.jar
|
||||
|
||||
# Project module targets
|
||||
bukkit/target
|
||||
universal/target
|
||||
bungee/target
|
||||
core/target
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Use https://travis-ci.org/ for automatic tests
|
||||
# Use https://travis-ci.org/ for automatic testing
|
||||
|
||||
# speed up testing https://blog.travis-ci.com/2014-12-17-faster-builds-with-container-based-infrastructure/
|
||||
sudo: false
|
||||
@ -8,5 +8,4 @@ language: java
|
||||
|
||||
script: mvn compile test
|
||||
|
||||
# We run on 8
|
||||
jdk: [oraclejdk8]
|
||||
|
@ -1,5 +1,7 @@
|
||||
### 1.11
|
||||
|
||||
* Drop support for deprecated AuthMe API
|
||||
* Remove legacy database migration code
|
||||
* Drop support for RoyalAuth, because it doesn't seem to be supported anymore
|
||||
* Clean up client-server encryption -> use only one cipher per connection, simplify code
|
||||
|
||||
|
102
README.md
102
README.md
@ -28,7 +28,6 @@ So they don't need to enter passwords. This is also called auto login (auto-logi
|
||||
### Commands:
|
||||
* /premium [player] Label the invoker or the argument as paid account
|
||||
* /cracked [player] Label the invoker or the argument as cracked account
|
||||
* /importdb <autoIn/bpa/eldzi> <mysql/sqlite> [host:port] [database] [username] [password] - Imports the database from another plugin
|
||||
|
||||
### Permissions:
|
||||
* fastlogin.bukkit.command.premium
|
||||
@ -39,7 +38,7 @@ So they don't need to enter passwords. This is also called auto login (auto-logi
|
||||
|
||||
### Requirements:
|
||||
* Plugin: [ProtocolLib](https://www.spigotmc.org/resources/protocollib.1997/) or [ProtocolSupport](https://www.spigotmc.org/resources/protocolsupport.7201/)
|
||||
* Tested Bukkit/[Spigot](https://www.spigotmc.org) 1.9 (could also work with other versions)
|
||||
* Tested [Spigot](https://www.spigotmc.org) 1.8+ (could also work with other versions)
|
||||
* Java 8+
|
||||
* Run Spigot and/or BungeeCord/Waterfall in offline mode (see server.properties or config.yml)
|
||||
* An auth plugin. Supported plugins
|
||||
@ -58,10 +57,6 @@ So they don't need to enter passwords. This is also called auto login (auto-logi
|
||||
|
||||
* [BungeeAuth](https://www.spigotmc.org/resources/bungeeauth.493/)
|
||||
|
||||
### Downloads
|
||||
|
||||
https://www.spigotmc.org/resources/fastlogin.14153/history
|
||||
|
||||
***
|
||||
|
||||
### How to install
|
||||
@ -84,98 +79,3 @@ Put your stats id from the BungeeCord config into this file
|
||||
7. Set your proxy (BungeeCord) in offline mode by setting the value onlinemode in your config.yml to false
|
||||
8. You should *always* firewall your spigot server that it's only accessible through BungeeCord https://www.spigotmc.org/wiki/bungeecord-installation/#post-installation
|
||||
9. (BungeeCord doesn't support SQLite per default, so you should change the configuration to MySQL or MariaDB)
|
||||
|
||||
***
|
||||
|
||||
### FAQ
|
||||
|
||||
#### Index
|
||||
1. [How does Minecraft logins work?](#how-does-minecraft-logins-work)
|
||||
2. [How does this plugin work?](#how-does-this-plugin-work)
|
||||
3. [Why does the plugin require offline mode?](#why-does-the-plugin-require-offline-mode)
|
||||
4. [Can cracked player join with premium usernames?](#can-cracked-player-join-with-premium-usernames)
|
||||
5. [Why do players have to invoke a command?](#why-do-players-have-to-invoke-a-command)
|
||||
6. [What happens if a paid account joins with a used username?](#what-happens-if-a-paid-account-joins-with-a-used-username)
|
||||
7. [Does the plugin have BungeeCord support?](#does-the-plugin-have-bungeecord-support)
|
||||
8. [Could premium players have a premium UUID and Skin?](#could-premium-players-have-a-premium-uuid-and-skin)
|
||||
9. [Is this plugin compatible with Cauldron?](#is-this-plugin-compatible-with-cauldron)
|
||||
|
||||
#### How does minecraft logins work?
|
||||
###### Online Mode
|
||||
1. Client -> Server: I want to login, here is my username
|
||||
2. Server -> Client: Okay. I'm in online mode so here is my public key for encryption and my server id
|
||||
3. Client -> Mojang: I'm player "xyz". I want to join a server with that server id
|
||||
4. Mojang -> Client: Session data checked. You can continue
|
||||
5. Client -> Server: I received a successful response from Mojang. Here our shared secret key
|
||||
6. Server -> Mojang: Does the player "xyz" with this shared secret key has a valid account to join me?
|
||||
7. Mojang -> Server: Yes, the player has the following additionally properties (UUID, Skin)
|
||||
8. Client and Server: encrypt all following communication packet
|
||||
9. Server -> Client: Everything checked you can play now
|
||||
|
||||
|
||||
###### Offline Mode
|
||||
In offline mode step 2-7 is skipped. So a login request is directly followed by 8.
|
||||
|
||||
###### More details
|
||||
http://wiki.vg/Protocol#Login
|
||||
|
||||
#### How does this plugin work?
|
||||
By using ProtocolLib, this plugin works as a proxy between the client and server. This plugin will fake that the server
|
||||
runs in online mode. It does everything an online mode server would do. This will be for example, generating keys or
|
||||
checking for valid sessions. Because everything is the same compared to an offline mode login after an encrypted
|
||||
connection, we will intercept only **login** packets of **premium** players.
|
||||
|
||||
1. Player is connecting to the server.
|
||||
2. Plugin checks if the username we received activated the fast login method (i.e. using command)
|
||||
3. Run a check if the username is currently used by a paid account.
|
||||
(We don't know yet if the client connecting is premium)
|
||||
4. Request an Mojang Session Server authentication
|
||||
5. On response check if all data is correct
|
||||
6. Encrypt the connection
|
||||
7. On success intercept all related login packets and fake a new login packet as a normal offline login
|
||||
|
||||
#### Why does the plugin require offline mode?
|
||||
1. As you can see in the question "how does minecraft login works", offline mode is equivalent to online mode except of
|
||||
the encryption and session checks on login. So we can intercept and cancel the first packets for premium players and
|
||||
enable an encrypted connection. Then we send a new fake packet in order to pretend that this a new login request from
|
||||
a offline mode player. The server will handle the rest.
|
||||
2. Some plugins check if the server is in online mode. If so, they could process the real offline (cracked) accounts
|
||||
incorrectly. For example, a plugin tries to fetch the UUID from Mojang, but the name of the player is not associated to
|
||||
a paid account.
|
||||
3. Servers, who allow cracked players and just speed up logins for premium players, are **already** in offline mode.
|
||||
|
||||
#### Can cracked player join with premium usernames?
|
||||
Yes, indeed. Therefore the command for toggling the fast login method exists.
|
||||
|
||||
#### Why do players have to invoke a command?
|
||||
1. It's a secure way to make sure a person with a paid account cannot steal the account
|
||||
of a cracked player that has the same username. The player have to proof first that it's his own account.
|
||||
2. We only receive the username from the player on login. We could check if that username is associated
|
||||
to a paid account but if we request a online mode login from a cracked player (who uses a username from
|
||||
a paid account), the player will disconnect with the reason "bad login" or "Invalid session". There is no way to change
|
||||
that message on the server side (without client modifications), because it's a connection between the Client and the
|
||||
session-server.
|
||||
3. If a premium player would skip registration too, a player of a cracked account could later still register the
|
||||
account and would claim and steal the account from the premium player. Because commands cannot be invoked unless the
|
||||
player has a account or is logged in, protects this method also premium players
|
||||
|
||||
### What happens if a paid account joins with a used username?
|
||||
The player on the server have to activate the feature of this plugin by command. If a person buys the username
|
||||
of his own account, it's still secured. A normal offline mode login makes sure he's the owner of the server account
|
||||
and Mojang account. Then the command can be executed. So someone different cannot steal the account of cracked player
|
||||
by buying the username.
|
||||
|
||||
#### Does the plugin have BungeeCord support?
|
||||
Yes it has. See the how to install above.
|
||||
|
||||
#### Could premium players have a premium UUID and Skin?
|
||||
Since 0.7 both features are implemented. You can check the config.yml in order to activate it.
|
||||
|
||||
#### Is this plugin compatible with Cauldron?
|
||||
It's not tested yet, but all needed methods also exists in Cauldron so it could work together.
|
||||
|
||||
***
|
||||
|
||||
### Useful Links:
|
||||
* [Login Protocol](http://wiki.vg/Protocol#Login)
|
||||
* [Protocol Encryption](http://wiki.vg/Protocol_Encryption)
|
||||
|
@ -65,7 +65,7 @@
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.12-R0.1-SNAPSHOT</version>
|
||||
<version>1.12.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -126,7 +126,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
|
||||
|
||||
public void sendBungeeActivateMessage(CommandSender sender, String target, boolean activate) {
|
||||
if (sender instanceof Player) {
|
||||
notifyBungeeCord((Player) sender, target, activate, sender instanceof Player);
|
||||
notifyBungeeCord((Player) sender, target, activate, true);
|
||||
} else {
|
||||
Player firstPlayer = Iterables.getFirst(getServer().getOnlinePlayers(), null);
|
||||
if (firstPlayer == null) {
|
||||
@ -134,7 +134,7 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
|
||||
return;
|
||||
}
|
||||
|
||||
notifyBungeeCord(firstPlayer, target, activate, sender instanceof Player);
|
||||
notifyBungeeCord(firstPlayer, target, activate, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -24,41 +24,44 @@ public class MojangApiBukkit extends MojangApiConnector {
|
||||
private static final String HAS_JOINED_URL = "https://sessionserver.mojang.com/session/minecraft/hasJoined?" +
|
||||
"username=%s&serverId=%s";
|
||||
|
||||
public MojangApiBukkit(Logger logger, List<String> localAddresses, int rateLimit, Map<String, Integer> proxies) {
|
||||
public MojangApiBukkit(Logger logger, Collection<String> localAddresses, int rateLimit
|
||||
, Map<String, Integer> proxies) {
|
||||
super(logger, localAddresses, rateLimit, proxies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasJoinedServer(LoginSession session, String serverId, InetSocketAddress ip) {
|
||||
BukkitLoginSession playerSession = (BukkitLoginSession) session;
|
||||
|
||||
String url = String.format(HAS_JOINED_URL, playerSession.getUsername(), serverId);
|
||||
try {
|
||||
String url = String.format(HAS_JOINED_URL, playerSession.getUsername(), serverId);
|
||||
if (ip != null) {
|
||||
url += "&ip=" + URLEncoder.encode(ip.getAddress().getHostAddress(), "UTF-8");
|
||||
}
|
||||
|
||||
HttpURLConnection conn = getConnection(url);
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
String line = reader.readLine();
|
||||
if (line != null && !"null".equals(line)) {
|
||||
//validate parsing
|
||||
//http://wiki.vg/Protocol_Encryption#Server
|
||||
JSONObject userData = (JSONObject) JSONValue.parseWithException(line);
|
||||
String uuid = (String) userData.get("id");
|
||||
playerSession.setUuid(FastLoginCore.parseId(uuid));
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
|
||||
String line = reader.readLine();
|
||||
if (line != null && !"null".equals(line)) {
|
||||
//validate parsing
|
||||
//http://wiki.vg/Protocol_Encryption#Server
|
||||
JSONObject userData = (JSONObject) JSONValue.parseWithException(line);
|
||||
String uuid = (String) userData.get("id");
|
||||
playerSession.setUuid(FastLoginCore.parseId(uuid));
|
||||
|
||||
JSONArray properties = (JSONArray) userData.get("properties");
|
||||
JSONObject skinProperty = (JSONObject) properties.get(0);
|
||||
JSONArray properties = (JSONArray) userData.get("properties");
|
||||
JSONObject skinProperty = (JSONObject) properties.get(0);
|
||||
|
||||
String propertyName = (String) skinProperty.get("name");
|
||||
if ("textures".equals(propertyName)) {
|
||||
String skinValue = (String) skinProperty.get("value");
|
||||
String signature = (String) skinProperty.get("signature");
|
||||
playerSession.setSkin(skinValue, signature);
|
||||
String propertyName = (String) skinProperty.get("name");
|
||||
if ("textures".equals(propertyName)) {
|
||||
String skinValue = (String) skinProperty.get("value");
|
||||
String signature = (String) skinProperty.get("signature");
|
||||
playerSession.setSkin(skinValue, signature);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
//catch not only io-exceptions also parse and NPE on unexpected json format
|
||||
|
@ -34,7 +34,7 @@ public class PremiumPlaceholder extends PlaceholderHook {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean register(FastLoginBukkit plugin) {
|
||||
return PlaceholderAPI.registerPlaceholderHook(plugin, new PremiumPlaceholder(plugin));
|
||||
public static void register(FastLoginBukkit plugin) {
|
||||
PlaceholderAPI.registerPlaceholderHook(plugin, new PremiumPlaceholder(plugin));
|
||||
}
|
||||
}
|
||||
|
@ -20,11 +20,9 @@ public class LogItHook implements AuthPlugin<Player> {
|
||||
@Override
|
||||
public boolean forceLogin(Player player) {
|
||||
SessionManager sessionManager = LogItCore.getInstance().getSessionManager();
|
||||
if (sessionManager.isSessionAlive(player)) {
|
||||
return true;
|
||||
}
|
||||
return sessionManager.isSessionAlive(player)
|
||||
|| sessionManager.startSession(player) == CancelledState.NOT_CANCELLED;
|
||||
|
||||
return sessionManager.startSession(player) == CancelledState.NOT_CANCELLED;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -24,11 +24,8 @@ public class LoginSecurityHook implements AuthPlugin<Player> {
|
||||
@Override
|
||||
public boolean forceLogin(Player player) {
|
||||
PlayerSession session = LoginSecurity.getSessionManager().getPlayerSession(player);
|
||||
if (session.isAuthorized()) {
|
||||
return true;
|
||||
}
|
||||
return session.isAuthorized() || session.performAction(new LoginAction(AuthService.PLUGIN, plugin)).isSuccess();
|
||||
|
||||
return session.performAction(new LoginAction(AuthService.PLUGIN, plugin)).isSuccess();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -52,11 +52,7 @@ public class UltraAuthHook implements AuthPlugin<Player> {
|
||||
@Override
|
||||
public boolean forceRegister(Player player, String password) {
|
||||
UltraAuthAPI.setPlayerPasswordOnline(player, password);
|
||||
if (PlayerManager.getInstance().checkPlayerPassword(player, password)) {
|
||||
//the register method silents any exception so check if our entry was saved
|
||||
return forceLogin(player);
|
||||
}
|
||||
|
||||
return false;
|
||||
//the register method silents any exception so check if our entry was saved
|
||||
return PlayerManager.getInstance().checkPlayerPassword(player, password) && forceLogin(player);
|
||||
}
|
||||
}
|
||||
|
@ -63,15 +63,11 @@ public class xAuthHook implements AuthPlugin<Player> {
|
||||
//not thread-safe
|
||||
Future<Boolean> future = Bukkit.getScheduler().callSyncMethod(xAuthPlugin, () -> {
|
||||
xAuthPlayer xAuthPlayer = xAuthPlugin.getPlayerManager().getPlayer(player);
|
||||
if (xAuthPlayer != null) {
|
||||
//this should run async because the plugin executes a sql query, but the method
|
||||
//accesses non thread-safe collections :(
|
||||
//this should run async because the plugin executes a sql query, but the method
|
||||
//accesses non thread-safe collections :(
|
||||
return xAuthPlayer != null
|
||||
&& xAuthPlugin.getAuthClass(xAuthPlayer).adminRegister(player.getName(), password, null);
|
||||
|
||||
return xAuthPlugin.getAuthClass(xAuthPlayer)
|
||||
.adminRegister(player.getName(), password, null);
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
try {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.github.games647.fastlogin.bungee;
|
||||
|
||||
import com.github.games647.fastlogin.bungee.hooks.BungeeAuthHook;
|
||||
import com.github.games647.fastlogin.bungee.listener.PlayerConnectionListener;
|
||||
import com.github.games647.fastlogin.bungee.listener.ConnectionListener;
|
||||
import com.github.games647.fastlogin.bungee.listener.PluginMessageListener;
|
||||
import com.github.games647.fastlogin.core.shared.FastLoginCore;
|
||||
import com.github.games647.fastlogin.core.shared.MojangApiConnector;
|
||||
@ -46,7 +46,7 @@ public class FastLoginBungee extends Plugin implements PlatformPlugin<CommandSen
|
||||
}
|
||||
|
||||
//events
|
||||
getProxy().getPluginManager().registerListener(this, new PlayerConnectionListener(this));
|
||||
getProxy().getPluginManager().registerListener(this, new ConnectionListener(this));
|
||||
getProxy().getPluginManager().registerListener(this, new PluginMessageListener(this));
|
||||
|
||||
//this is required to listen to messages from the server
|
||||
|
@ -4,7 +4,7 @@ import com.github.games647.fastlogin.core.shared.LoginSession;
|
||||
import com.github.games647.fastlogin.core.shared.MojangApiConnector;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ -12,7 +12,8 @@ import net.md_5.bungee.BungeeCord;
|
||||
|
||||
public class MojangApiBungee extends MojangApiConnector {
|
||||
|
||||
public MojangApiBungee(Logger logger, List<String> localAddresses, int rateLimit, Map<String, Integer> proxies) {
|
||||
public MojangApiBungee(Logger logger, Collection<String> localAddresses, int rateLimit
|
||||
, Map<String, Integer> proxies) {
|
||||
super(logger, localAddresses, rateLimit, proxies);
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,8 @@ public class BungeeAuthHook implements AuthPlugin<ProxiedPlayer> {
|
||||
@Override
|
||||
public boolean forceLogin(ProxiedPlayer player) {
|
||||
String playerName = player.getName();
|
||||
if (Main.plonline.contains(playerName)) {
|
||||
return true;
|
||||
}
|
||||
return Main.plonline.contains(playerName) || requestHandler.forceLogin(playerName);
|
||||
|
||||
return requestHandler.forceLogin(playerName);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -31,11 +31,11 @@ import net.md_5.bungee.event.EventPriority;
|
||||
* plugin message to the Bukkit version of this plugin in
|
||||
* order to clear that the connection is online mode.
|
||||
*/
|
||||
public class PlayerConnectionListener implements Listener {
|
||||
public class ConnectionListener implements Listener {
|
||||
|
||||
private final FastLoginBungee plugin;
|
||||
|
||||
public PlayerConnectionListener(FastLoginBungee plugin) {
|
||||
public ConnectionListener(FastLoginBungee plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
@ -54,11 +54,8 @@ public class ForceLoginTask extends ForceLoginManagement<ProxiedPlayer, CommandS
|
||||
|
||||
@Override
|
||||
public boolean forceRegister(ProxiedPlayer player) {
|
||||
if (session.isAlreadyLogged()) {
|
||||
return true;
|
||||
}
|
||||
return session.isAlreadyLogged() || super.forceRegister(player);
|
||||
|
||||
return super.forceRegister(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -62,12 +62,8 @@ public class AuthStorage {
|
||||
}
|
||||
|
||||
public void createTables() throws SQLException {
|
||||
Connection con = null;
|
||||
Statement createStmt = null;
|
||||
try {
|
||||
con = dataSource.getConnection();
|
||||
createStmt = con.createStatement();
|
||||
|
||||
try (Connection con = dataSource.getConnection();
|
||||
Statement createStmt = con.createStatement()) {
|
||||
String createDataStmt = "CREATE TABLE IF NOT EXISTS " + PREMIUM_TABLE + " ("
|
||||
+ "UserID INTEGER PRIMARY KEY AUTO_INCREMENT, "
|
||||
+ "UUID CHAR(36), "
|
||||
@ -84,132 +80,106 @@ public class AuthStorage {
|
||||
}
|
||||
|
||||
createStmt.executeUpdate(createDataStmt);
|
||||
} finally {
|
||||
closeQuietly(con);
|
||||
closeQuietly(createStmt);
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerProfile loadProfile(String name) {
|
||||
Connection con = null;
|
||||
PreparedStatement loadStmt = null;
|
||||
ResultSet resultSet = null;
|
||||
try {
|
||||
con = dataSource.getConnection();
|
||||
loadStmt = con.prepareStatement("SELECT * FROM " + PREMIUM_TABLE + " WHERE Name=? LIMIT 1");
|
||||
try (Connection con = dataSource.getConnection();
|
||||
PreparedStatement loadStmt = con.prepareStatement("SELECT * FROM "
|
||||
+ PREMIUM_TABLE + " WHERE Name=? LIMIT 1")) {
|
||||
loadStmt.setString(1, name);
|
||||
|
||||
resultSet = loadStmt.executeQuery();
|
||||
if (resultSet.next()) {
|
||||
long userId = resultSet.getInt(1);
|
||||
try (ResultSet resultSet = loadStmt.executeQuery()) {
|
||||
if (resultSet.next()) {
|
||||
long userId = resultSet.getInt(1);
|
||||
|
||||
UUID uuid = FastLoginCore.parseId(resultSet.getString(2));
|
||||
UUID uuid = FastLoginCore.parseId(resultSet.getString(2));
|
||||
|
||||
boolean premium = resultSet.getBoolean(4);
|
||||
String lastIp = resultSet.getString(5);
|
||||
long lastLogin = resultSet.getTimestamp(6).getTime();
|
||||
return new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
|
||||
} else {
|
||||
return new PlayerProfile(null, name, false, "");
|
||||
boolean premium = resultSet.getBoolean(4);
|
||||
String lastIp = resultSet.getString(5);
|
||||
long lastLogin = resultSet.getTimestamp(6).getTime();
|
||||
return new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
|
||||
} else {
|
||||
return new PlayerProfile(null, name, false, "");
|
||||
}
|
||||
}
|
||||
} catch (SQLException sqlEx) {
|
||||
core.getPlugin().getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);
|
||||
} finally {
|
||||
closeQuietly(con);
|
||||
closeQuietly(loadStmt);
|
||||
closeQuietly(resultSet);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public PlayerProfile loadProfile(UUID uuid) {
|
||||
Connection con = null;
|
||||
PreparedStatement loadStmt = null;
|
||||
ResultSet resultSet = null;
|
||||
try {
|
||||
con = dataSource.getConnection();
|
||||
loadStmt = con.prepareStatement("SELECT * FROM " + PREMIUM_TABLE + " WHERE UUID=? LIMIT 1");
|
||||
try (Connection con = dataSource.getConnection();
|
||||
PreparedStatement loadStmt = con.prepareStatement("SELECT * FROM "
|
||||
+ PREMIUM_TABLE + " WHERE UUID=? LIMIT 1")) {
|
||||
loadStmt.setString(1, uuid.toString().replace("-", ""));
|
||||
|
||||
resultSet = loadStmt.executeQuery();
|
||||
if (resultSet.next()) {
|
||||
long userId = resultSet.getInt(1);
|
||||
try (ResultSet resultSet = loadStmt.executeQuery()) {
|
||||
if (resultSet.next()) {
|
||||
long userId = resultSet.getInt(1);
|
||||
|
||||
String name = resultSet.getString(3);
|
||||
boolean premium = resultSet.getBoolean(4);
|
||||
String lastIp = resultSet.getString(5);
|
||||
long lastLogin = resultSet.getTimestamp(6).getTime();
|
||||
return new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
|
||||
String name = resultSet.getString(3);
|
||||
boolean premium = resultSet.getBoolean(4);
|
||||
String lastIp = resultSet.getString(5);
|
||||
long lastLogin = resultSet.getTimestamp(6).getTime();
|
||||
return new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
|
||||
}
|
||||
}
|
||||
} catch (SQLException sqlEx) {
|
||||
core.getPlugin().getLogger().log(Level.SEVERE, "Failed to query profile", sqlEx);
|
||||
} finally {
|
||||
closeQuietly(con);
|
||||
closeQuietly(loadStmt);
|
||||
closeQuietly(resultSet);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean save(PlayerProfile playerProfile) {
|
||||
Connection con = null;
|
||||
PreparedStatement updateStmt = null;
|
||||
PreparedStatement saveStmt = null;
|
||||
|
||||
ResultSet generatedKeys = null;
|
||||
try {
|
||||
con = dataSource.getConnection();
|
||||
|
||||
try (Connection con = dataSource.getConnection()) {
|
||||
UUID uuid = playerProfile.getUuid();
|
||||
|
||||
if (playerProfile.getUserId() == -1) {
|
||||
saveStmt = con.prepareStatement("INSERT INTO " + PREMIUM_TABLE
|
||||
+ " (UUID, Name, Premium, LastIp) VALUES (?, ?, ?, ?) ", Statement.RETURN_GENERATED_KEYS);
|
||||
try (PreparedStatement saveStmt = con.prepareStatement("INSERT INTO " + PREMIUM_TABLE
|
||||
+ " (UUID, Name, Premium, LastIp) VALUES (?, ?, ?, ?) ", Statement.RETURN_GENERATED_KEYS)) {
|
||||
if (uuid == null) {
|
||||
saveStmt.setString(1, null);
|
||||
} else {
|
||||
saveStmt.setString(1, uuid.toString().replace("-", ""));
|
||||
}
|
||||
|
||||
if (uuid == null) {
|
||||
saveStmt.setString(1, null);
|
||||
} else {
|
||||
saveStmt.setString(1, uuid.toString().replace("-", ""));
|
||||
}
|
||||
saveStmt.setString(2, playerProfile.getPlayerName());
|
||||
saveStmt.setBoolean(3, playerProfile.isPremium());
|
||||
saveStmt.setString(4, playerProfile.getLastIp());
|
||||
|
||||
saveStmt.setString(2, playerProfile.getPlayerName());
|
||||
saveStmt.setBoolean(3, playerProfile.isPremium());
|
||||
saveStmt.setString(4, playerProfile.getLastIp());
|
||||
saveStmt.execute();
|
||||
|
||||
saveStmt.execute();
|
||||
|
||||
generatedKeys = saveStmt.getGeneratedKeys();
|
||||
if (generatedKeys != null && generatedKeys.next()) {
|
||||
playerProfile.setUserId(generatedKeys.getInt(1));
|
||||
try (ResultSet generatedKeys = saveStmt.getGeneratedKeys()) {
|
||||
if (generatedKeys != null && generatedKeys.next()) {
|
||||
playerProfile.setUserId(generatedKeys.getInt(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
saveStmt = con.prepareStatement("UPDATE " + PREMIUM_TABLE
|
||||
+ " SET UUID=?, Name=?, Premium=?, LastIp=?, LastLogin=CURRENT_TIMESTAMP WHERE UserID=?");
|
||||
try (PreparedStatement saveStmt = con.prepareStatement("UPDATE " + PREMIUM_TABLE
|
||||
+ " SET UUID=?, Name=?, Premium=?, LastIp=?, LastLogin=CURRENT_TIMESTAMP WHERE UserID=?")) {
|
||||
if (uuid == null) {
|
||||
saveStmt.setString(1, null);
|
||||
} else {
|
||||
saveStmt.setString(1, uuid.toString().replace("-", ""));
|
||||
}
|
||||
|
||||
if (uuid == null) {
|
||||
saveStmt.setString(1, null);
|
||||
} else {
|
||||
saveStmt.setString(1, uuid.toString().replace("-", ""));
|
||||
saveStmt.setString(2, playerProfile.getPlayerName());
|
||||
saveStmt.setBoolean(3, playerProfile.isPremium());
|
||||
saveStmt.setString(4, playerProfile.getLastIp());
|
||||
|
||||
saveStmt.setLong(5, playerProfile.getUserId());
|
||||
saveStmt.execute();
|
||||
}
|
||||
|
||||
saveStmt.setString(2, playerProfile.getPlayerName());
|
||||
saveStmt.setBoolean(3, playerProfile.isPremium());
|
||||
saveStmt.setString(4, playerProfile.getLastIp());
|
||||
|
||||
saveStmt.setLong(5, playerProfile.getUserId());
|
||||
saveStmt.execute();
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (SQLException ex) {
|
||||
core.getPlugin().getLogger().log(Level.SEVERE, "Failed to save playerProfile", ex);
|
||||
} finally {
|
||||
closeQuietly(con);
|
||||
closeQuietly(updateStmt);
|
||||
closeQuietly(saveStmt);
|
||||
closeQuietly(generatedKeys);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -218,14 +188,4 @@ public class AuthStorage {
|
||||
public void close() {
|
||||
dataSource.close();
|
||||
}
|
||||
|
||||
private void closeQuietly(AutoCloseable closeable) {
|
||||
if (closeable != null) {
|
||||
try {
|
||||
closeable.close();
|
||||
} catch (Exception closeEx) {
|
||||
core.getPlugin().getLogger().log(Level.SEVERE, "Failed to close connection", closeEx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,41 +83,18 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
|
||||
saveDefaultFile("messages.yml");
|
||||
saveDefaultFile("config.yml");
|
||||
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
reader = new BufferedReader(new InputStreamReader(getClass().getClassLoader().getResourceAsStream("config.yml")));
|
||||
sharedConfig = new SharedConfig(plugin.loadYamlFile(reader));
|
||||
reader.close();
|
||||
sharedConfig = new SharedConfig(loadFile("config.yml"));
|
||||
Map<String, Object> messages = loadFile("messages.yml");
|
||||
|
||||
reader = Files.newBufferedReader(plugin.getDataFolder().toPath().resolve("config.yml"));
|
||||
sharedConfig.getConfigValues().putAll(plugin.loadYamlFile(reader));
|
||||
reader.close();
|
||||
|
||||
reader = new BufferedReader(new InputStreamReader(getClass().getClassLoader().getResourceAsStream("messages.yml")));
|
||||
reader = Files.newBufferedReader(plugin.getDataFolder().toPath().resolve("messages.yml"));
|
||||
Map<String, Object> messageConfig = plugin.loadYamlFile(reader);
|
||||
reader.close();
|
||||
|
||||
reader = Files.newBufferedReader(plugin.getDataFolder().toPath().resolve("messages.yml"));
|
||||
messageConfig.putAll(plugin.loadYamlFile(reader));
|
||||
for (Entry<String, Object> entry : messageConfig.entrySet()) {
|
||||
for (Entry<String, Object> entry : messages.entrySet()) {
|
||||
String message = plugin.translateColorCodes('&', (String) entry.getValue());
|
||||
if (!message.isEmpty()) {
|
||||
localeMessages.put(entry.getKey(), message);
|
||||
}
|
||||
}
|
||||
|
||||
reader.close();
|
||||
} catch (IOException ioEx) {
|
||||
plugin.getLogger().log(Level.INFO, "Failed to load yaml files", ioEx);
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException ex) {
|
||||
plugin.getLogger().log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<String> ipAddresses = sharedConfig.get("ip-addresses");
|
||||
@ -130,6 +107,22 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
|
||||
this.apiConnector = plugin.makeApiConnector(plugin.getLogger(), ipAddresses, requestLimit, proxies);
|
||||
}
|
||||
|
||||
private Map<String, Object> loadFile(String fileName) throws IOException {
|
||||
Map<String, Object> values;
|
||||
|
||||
try (InputStream defaultStream = getClass().getClassLoader().getResourceAsStream(fileName);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(defaultStream))) {
|
||||
values = plugin.loadYamlFile(reader);
|
||||
}
|
||||
|
||||
Path file = plugin.getDataFolder().toPath().resolve(fileName);
|
||||
try (BufferedReader reader = Files.newBufferedReader(file)) {
|
||||
values.putAll(plugin.loadYamlFile(reader));
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
public MojangApiConnector getApiConnector() {
|
||||
return apiConnector;
|
||||
}
|
||||
@ -213,17 +206,10 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
|
||||
|
||||
Path configFile = dataFolder.resolve(fileName);
|
||||
if (Files.notExists(configFile)) {
|
||||
InputStream in = getClass().getClassLoader().getResourceAsStream(fileName);
|
||||
try {
|
||||
try (InputStream in = getClass().getClassLoader().getResourceAsStream(fileName)) {
|
||||
Files.copy(in, configFile);
|
||||
} catch (IOException ioExc) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Error saving default " + fileName, ioExc);
|
||||
} finally {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException ex) {
|
||||
plugin.getLogger().log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,10 +92,11 @@ public abstract class MojangApiConnector {
|
||||
}
|
||||
|
||||
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||
String line = reader.readLine();
|
||||
if (!"null".equals(line)) {
|
||||
return FastLoginCore.parseId(getUUIDFromJson(line));
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
|
||||
String line = reader.readLine();
|
||||
if (!"null".equals(line)) {
|
||||
return FastLoginCore.parseId(getUUIDFromJson(line));
|
||||
}
|
||||
}
|
||||
} else if (connection.getResponseCode() == RATE_LIMIT_CODE) {
|
||||
logger.info("RATE_LIMIT REACHED");
|
||||
|
Reference in New Issue
Block a user