diff --git a/pom.xml b/pom.xml
index f9def84..0f4f46a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,6 +56,11 @@
2.9.2
provided
+
+ mysql
+ mysql-connector-java
+ 8.0.13
+
@@ -90,6 +95,8 @@
com.beust:jcommander
com.github.jai-imageio:jai-imageio-core
commons-codec:commons-codec
+ mysql:mysql-connector-java
+ com.google.protobuf:protobuf-java
${project.name}
diff --git a/src/main/java/eu/oskar3123/spigot2fa/Main.java b/src/main/java/eu/oskar3123/spigot2fa/Main.java
index 11721e6..8e21ad4 100644
--- a/src/main/java/eu/oskar3123/spigot2fa/Main.java
+++ b/src/main/java/eu/oskar3123/spigot2fa/Main.java
@@ -1,28 +1,39 @@
package eu.oskar3123.spigot2fa;
import eu.oskar3123.spigot2fa.command.TFACommand;
-import eu.oskar3123.spigot2fa.config.Config;
-import eu.oskar3123.spigot2fa.config.ConfigHandler;
+import eu.oskar3123.spigot2fa.config.PlayersConfiguration;
+import eu.oskar3123.spigot2fa.config.SQLPlayersConfiguration;
+import eu.oskar3123.spigot2fa.config.YAMLPlayersConfiguration;
+import eu.oskar3123.spigot2fa.config.yaml.Config;
+import eu.oskar3123.spigot2fa.config.yaml.ConfigHandler;
import eu.oskar3123.spigot2fa.handler.TFAHandler;
import eu.oskar3123.spigot2fa.listener.AuthListener;
import eu.oskar3123.spigot2fa.listener.MapListener;
+import org.bukkit.configuration.Configuration;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
+import java.sql.SQLException;
+
public class Main extends JavaPlugin
{
public TFAHandler tfaHandler;
public ConfigHandler configHandler;
public Config config;
- public Config players;
+ public PlayersConfiguration players;
@Override
public void onEnable()
{
this.configHandler = new ConfigHandler(this);
this.config = this.configHandler.addConfig(new Config("config"));
- this.players = this.configHandler.addConfig(new Config("players"));
+ if (!initPlayersConfig())
+ {
+ getLogger().severe("Failed to init players backend, disabling plugin");
+ getServer().getPluginManager().disablePlugin(this);
+ return;
+ }
this.tfaHandler = new TFAHandler(this);
registerCommands();
registerListeners();
@@ -31,7 +42,51 @@ public class Main extends JavaPlugin
@Override
public void onDisable()
{
- this.tfaHandler.abortAll();
+ if (this.tfaHandler != null)
+ {
+ this.tfaHandler.abortAll();
+ }
+ }
+
+ private boolean initPlayersConfig()
+ {
+ Configuration c = this.configHandler.getConfig(this.config);
+ String mode = c.getString("backend");
+ if (mode.equalsIgnoreCase("yml") || mode.equalsIgnoreCase("yaml"))
+ {
+ players = new YAMLPlayersConfiguration(this.configHandler, "players");
+ return true;
+ }
+ else if (mode.equalsIgnoreCase("mysql"))
+ {
+ String hostname = c.getString("mysql.hostname");
+ String port = c.getString("mysql.port");
+ String database = c.getString("mysql.database");
+ String username = c.getString("mysql.username");
+ String password = c.getString("mysql.password");
+ String tablePrefix = c.getString("mysql.tableprefix");
+ try
+ {
+ players = new SQLPlayersConfiguration(hostname, port, database, username, password, tablePrefix);
+ return true;
+ }
+ catch (ClassNotFoundException e)
+ {
+ e.printStackTrace();
+ getLogger().severe("JDBC driver for mysql not found");
+ return false;
+ }
+ catch (SQLException e)
+ {
+ e.printStackTrace();
+ getLogger().severe("Failed to connect to database, check your settings");
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
}
private void registerCommands()
diff --git a/src/main/java/eu/oskar3123/spigot2fa/config/PlayersConfiguration.java b/src/main/java/eu/oskar3123/spigot2fa/config/PlayersConfiguration.java
new file mode 100644
index 0000000..4554ad9
--- /dev/null
+++ b/src/main/java/eu/oskar3123/spigot2fa/config/PlayersConfiguration.java
@@ -0,0 +1,52 @@
+package eu.oskar3123.spigot2fa.config;
+
+import java.util.UUID;
+
+public interface PlayersConfiguration
+{
+
+ class PlayersData
+ {
+
+ private UUID uuid;
+ private String secret;
+ private String lastIp;
+ private long lastLogin;
+
+ public PlayersData(UUID uuid, String secret, String lastIp, long lastLogin)
+ {
+ this.uuid = uuid;
+ this.secret = secret;
+ this.lastIp = lastIp;
+ this.lastLogin = lastLogin;
+ }
+
+ public UUID getUUID()
+ {
+ return uuid;
+ }
+
+ public String getSecret()
+ {
+ return secret;
+ }
+
+ public String getLastIP()
+ {
+ return lastIp;
+ }
+
+ public long getLastLogin()
+ {
+ return lastLogin;
+ }
+
+ }
+
+ boolean hasData(UUID uuid);
+
+ PlayersData getData(UUID uuid);
+
+ boolean setData(UUID uuid, PlayersData data);
+
+}
diff --git a/src/main/java/eu/oskar3123/spigot2fa/config/SQLPlayersConfiguration.java b/src/main/java/eu/oskar3123/spigot2fa/config/SQLPlayersConfiguration.java
new file mode 100644
index 0000000..b5a3ac8
--- /dev/null
+++ b/src/main/java/eu/oskar3123/spigot2fa/config/SQLPlayersConfiguration.java
@@ -0,0 +1,164 @@
+package eu.oskar3123.spigot2fa.config;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.UUID;
+
+public class SQLPlayersConfiguration implements PlayersConfiguration
+{
+
+ private String hostname;
+ private String port;
+ private String database;
+ private String username;
+ private String password;
+ private String tableName;
+ private Connection connection;
+
+ public SQLPlayersConfiguration(String hostname, String port, String database, String username, String password, String tablePrefix) throws ClassNotFoundException, SQLException
+ {
+ this.hostname = hostname;
+ this.port = port;
+ this.database = database;
+ this.username = username;
+ this.password = password;
+ Class.forName("com.mysql.jdbc.Driver");
+ this.tableName = tablePrefix + "playerdata";
+ if (!connect(10))
+ {
+ throw new SQLException("Failed to connect");
+ }
+ init();
+ }
+
+ private boolean connect(int retries)
+ {
+ retries--;
+ try
+ {
+ if (connection != null && connection.isValid(1))
+ {
+ return true;
+ }
+ connection = DriverManager.getConnection(String.format("jdbc:mysql://%s:%s/%s", this.hostname, this.port, this.database), this.username, this.password);
+ return true;
+ }
+ catch (SQLException e)
+ {
+ if (retries > 0)
+ {
+ return connect(retries);
+ }
+ return false;
+ }
+ }
+
+ private void init() throws SQLException
+ {
+ String createSql = "CREATE TABLE IF NOT EXISTS `" + this.tableName + "` ( \n" +
+ " `uuid` VARCHAR(36) NOT NULL , \n" +
+ " `secret` VARCHAR(32) NOT NULL , \n" +
+ " `lastip` VARCHAR(15) NOT NULL , \n" +
+ " `lastlogin` BIGINT NOT NULL , \n" +
+ " PRIMARY KEY (`uuid`)\n" +
+ ") ENGINE = InnoDB;";
+ connection.createStatement().executeUpdate(createSql);
+ }
+
+ @Override
+ public boolean hasData(UUID uuid)
+ {
+ try
+ {
+ if (!connect(10))
+ {
+ return false;
+ }
+ String querySql = "SELECT COUNT(`uuid`) FROM `" + this.tableName + "` WHERE `uuid`='" + uuid.toString() + "';";
+ ResultSet result = connection.createStatement().executeQuery(querySql);
+ if (result.next())
+ {
+ return result.getLong(1) > 0;
+
+ }
+ return false;
+ }
+ catch (SQLException e)
+ {
+ return false;
+ }
+ }
+
+ @Override
+ public PlayersData getData(UUID uuid)
+ {
+ try
+ {
+ if (!connect(10))
+ {
+ return null;
+ }
+ String querySql = "SELECT `secret`, `lastip`, `lastlogin` FROM `" + this.tableName + "` WHERE `uuid`='" + uuid.toString() + "';";
+ ResultSet result = connection.createStatement().executeQuery(querySql);
+ if (!result.next())
+ {
+ return null;
+ }
+ String secret = result.getString("secret");
+ String lastIp = result.getString("lastip");
+ long lastLogin = result.getLong("lastlogin");
+ return new PlayersData(uuid, secret, lastIp, lastLogin);
+ }
+ catch (SQLException e)
+ {
+ return null;
+ }
+ }
+
+ @Override
+ public boolean setData(UUID uuid, PlayersData data)
+ {
+ try
+ {
+ if (!connect(10))
+ {
+ return false;
+ }
+ if (data == null)
+ {
+ String deleteSql = "DELETE FROM `" + this.tableName + "` WHERE `uuid`='" + uuid.toString() + "';";
+ System.out.println(deleteSql);
+ connection.isValid(1);
+ connection.createStatement().executeUpdate(deleteSql);
+ return true;
+ }
+ if (hasData(uuid))
+ {
+ String updateSql = "UPDATE `" + this.tableName + "` SET `secret`='" +
+ data.getSecret() + "', `lastip`='" +
+ data.getLastIP() + "', `lastlogin`=" +
+ data.getLastLogin() + " WHERE `uuid`='" +
+ data.getUUID().toString() + "';";
+ System.out.println(updateSql);
+ connection.createStatement().executeUpdate(updateSql);
+ return true;
+ }
+ String insertSql = "INSERT INTO `" + this.tableName + "` (`uuid`, `secret`, `lastip`, `lastlogin`) VALUES (" +
+ "'" + uuid.toString() + "', " +
+ "'" + data.getSecret() + "', " +
+ "'" + data.getLastIP() + "', " +
+ data.getLastLogin() + ");";
+ System.out.println(insertSql);
+ connection.createStatement().executeUpdate(insertSql);
+ return true;
+ }
+ catch (SQLException e)
+ {
+ System.out.println("setData failed");
+ return false;
+ }
+ }
+
+}
diff --git a/src/main/java/eu/oskar3123/spigot2fa/config/YAMLPlayersConfiguration.java b/src/main/java/eu/oskar3123/spigot2fa/config/YAMLPlayersConfiguration.java
new file mode 100644
index 0000000..b2a048b
--- /dev/null
+++ b/src/main/java/eu/oskar3123/spigot2fa/config/YAMLPlayersConfiguration.java
@@ -0,0 +1,52 @@
+package eu.oskar3123.spigot2fa.config;
+
+import eu.oskar3123.spigot2fa.config.yaml.Config;
+import eu.oskar3123.spigot2fa.config.yaml.ConfigHandler;
+import org.bukkit.configuration.Configuration;
+
+import java.util.UUID;
+
+public class YAMLPlayersConfiguration implements PlayersConfiguration
+{
+
+ private ConfigHandler configHandler;
+ private Config config;
+
+ public YAMLPlayersConfiguration(ConfigHandler configHandler, String name)
+ {
+ this.configHandler = configHandler;
+ this.configHandler.addConfig(this.config = new Config(name));
+ }
+
+ @Override
+ public boolean hasData(UUID uuid)
+ {
+ return this.configHandler.getConfig(this.config).isSet(uuid.toString());
+ }
+
+ @Override
+ public PlayersData getData(UUID uuid)
+ {
+ if (!hasData(uuid))
+ {
+ return null;
+ }
+ Configuration c = this.configHandler.getConfig(this.config);
+ String secret = c.getString(uuid.toString() + ".secret");
+ String lastIp = c.getString(uuid.toString() + ".lastip");
+ long lastLogin = c.getLong(uuid.toString() + ".lastlogin");
+ return new PlayersData(uuid, secret, lastIp, lastLogin);
+ }
+
+ @Override
+ public boolean setData(UUID uuid, PlayersData data)
+ {
+ Configuration c = this.configHandler.getConfig(this.config);
+ c.set(uuid.toString() + ".secret", data.getSecret());
+ c.set(uuid.toString() + ".lastip", data.getLastIP());
+ c.set(uuid.toString() + ".lastlogin", data.getLastLogin());
+ this.configHandler.saveConfig(this.config, true);
+ return true;
+ }
+
+}
diff --git a/src/main/java/eu/oskar3123/spigot2fa/config/Config.java b/src/main/java/eu/oskar3123/spigot2fa/config/yaml/Config.java
similarity index 84%
rename from src/main/java/eu/oskar3123/spigot2fa/config/Config.java
rename to src/main/java/eu/oskar3123/spigot2fa/config/yaml/Config.java
index 63d55a3..5319189 100644
--- a/src/main/java/eu/oskar3123/spigot2fa/config/Config.java
+++ b/src/main/java/eu/oskar3123/spigot2fa/config/yaml/Config.java
@@ -1,4 +1,4 @@
-package eu.oskar3123.spigot2fa.config;
+package eu.oskar3123.spigot2fa.config.yaml;
import org.bukkit.configuration.file.FileConfiguration;
diff --git a/src/main/java/eu/oskar3123/spigot2fa/config/ConfigHandler.java b/src/main/java/eu/oskar3123/spigot2fa/config/yaml/ConfigHandler.java
similarity index 98%
rename from src/main/java/eu/oskar3123/spigot2fa/config/ConfigHandler.java
rename to src/main/java/eu/oskar3123/spigot2fa/config/yaml/ConfigHandler.java
index 52b4f7f..38fd5d4 100644
--- a/src/main/java/eu/oskar3123/spigot2fa/config/ConfigHandler.java
+++ b/src/main/java/eu/oskar3123/spigot2fa/config/yaml/ConfigHandler.java
@@ -1,4 +1,4 @@
-package eu.oskar3123.spigot2fa.config;
+package eu.oskar3123.spigot2fa.config.yaml;
import com.google.common.base.Charsets;
import org.bukkit.Bukkit;
diff --git a/src/main/java/eu/oskar3123/spigot2fa/handler/TFAHandler.java b/src/main/java/eu/oskar3123/spigot2fa/handler/TFAHandler.java
index 39a0914..a2aae72 100644
--- a/src/main/java/eu/oskar3123/spigot2fa/handler/TFAHandler.java
+++ b/src/main/java/eu/oskar3123/spigot2fa/handler/TFAHandler.java
@@ -1,12 +1,12 @@
package eu.oskar3123.spigot2fa.handler;
import eu.oskar3123.spigot2fa.Main;
+import eu.oskar3123.spigot2fa.config.PlayersConfiguration;
import eu.oskar3123.spigot2fa.map.QRMapRenderer;
import eu.oskar3123.spigot2fa.tfa.TFA;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
-import org.bukkit.configuration.Configuration;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta;
@@ -52,9 +52,13 @@ public class TFAHandler
}
long now = new Date().getTime();
long sessionTimeInMs = plugin.configHandler.getConfig(plugin.config).getLong("2fa.sessiontime") * 60000L;
- Configuration players = plugin.configHandler.getConfig(plugin.players);
- long last = players.getLong(uuid.toString() + ".lastlogin");
- String lastIp = players.getString(uuid.toString() + ".lastip");
+ PlayersConfiguration.PlayersData playersData = plugin.players.getData(uuid);
+ if (playersData == null)
+ {
+ return true;
+ }
+ long last = playersData.getLastLogin();
+ String lastIp = playersData.getLastIP();
return last >= now - sessionTimeInMs && ip.equalsIgnoreCase(lastIp);
}
@@ -75,10 +79,12 @@ public class TFAHandler
{
now = time;
}
- Configuration players = plugin.configHandler.getConfig(plugin.players);
- players.set(uuid.toString() + ".lastlogin", now);
- players.set(uuid.toString() + ".lastip", ip);
- plugin.configHandler.saveConfig(plugin.players, true);
+ PlayersConfiguration.PlayersData playersData = plugin.players.getData(uuid);
+ PlayersConfiguration.PlayersData newData = new PlayersConfiguration.PlayersData(uuid, playersData.getSecret(), ip, now);
+ if (!plugin.players.setData(uuid, newData))
+ {
+ plugin.getLogger().severe("Failed to set data");
+ }
}
public String formatSecret(String secret)
@@ -88,21 +94,26 @@ public class TFAHandler
public void remove2FA(UUID uuid)
{
- plugin.configHandler.getConfig(plugin.players).set(uuid.toString(), null);
- plugin.configHandler.saveConfig(plugin.players, true);
+ if (!plugin.players.setData(uuid, null))
+ {
+ plugin.getLogger().severe("Failed to set data");
+ }
}
public boolean hasEnabled2FA(UUID uuid)
{
- return plugin.configHandler.getConfig(plugin.players).isString(uuid.toString() + ".secret");
+ return plugin.players.hasData(uuid);
}
public void creatingSuccess(Player player)
{
String secret = remove(player.getUniqueId());
player.getInventory().setItemInMainHand(new ItemStack(Material.AIR));
- plugin.configHandler.getConfig(plugin.players).set(player.getUniqueId().toString() + ".secret", secret);
- plugin.configHandler.saveConfig(plugin.players, true);
+ PlayersConfiguration.PlayersData playersData = new PlayersConfiguration.PlayersData(player.getUniqueId(), secret, player.getAddress().getAddress().getHostAddress(), 0);
+ if (!plugin.players.setData(player.getUniqueId(), playersData))
+ {
+ plugin.getLogger().severe("Failed to set data");
+ }
}
public void creatingFailed(Player player)
@@ -187,8 +198,12 @@ public class TFAHandler
{
return isInProcess.get(uuid);
}
- Configuration players = plugin.configHandler.getConfig(plugin.players);
- return players.getString(uuid.toString() + ".secret");
+ PlayersConfiguration.PlayersData playersData = plugin.players.getData(uuid);
+ if (playersData == null)
+ {
+ return null;
+ }
+ return playersData.getSecret();
}
public void stopCreating(Player player)
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index fa3136c..98a5e57 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -1,3 +1,12 @@
+mysql:
+ hostname: ''
+ port: ''
+ database: ''
+ username: ''
+ password: ''
+ tableprefix: '2fa_'
+# yml or mysql
+backend: 'yml'
2fa:
issuer: 'Mineworlds'
account: '{NAME}'