Clean up using IDE inspections

This commit is contained in:
games647
2017-09-21 15:00:39 +02:00
parent 5bf9b05d30
commit 109508dae6
21 changed files with 164 additions and 313 deletions

25
.github/ISSUE_TEMPLATE.md vendored Normal file
View 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
View File

@ -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

View File

@ -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]

View File

@ -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
View File

@ -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)

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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

View File

@ -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));
}
}

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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 {

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -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");