Use Instant for timestamps

This commit is contained in:
games647
2017-10-01 17:11:06 +02:00
parent dce44295d0
commit 105e00b7e8
24 changed files with 122 additions and 101 deletions

View File

@ -13,9 +13,9 @@ The actions that cause the issue
This can be found by running `/pl`
### Environment description
Standalone server/Bungeecord network, SQLite/MySql, ...
Standalone server/Bungeecord network, SQLite/MySQL, ...
### Plugin version:
### Plugin version or build number (don't write latest):
This can be found by running `/version plugin-name`
### Error Log:

View File

@ -37,7 +37,8 @@ So they don't need to enter passwords. This is also called auto login (auto-logi
* fastlogin.command.import
### Requirements:
* Plugin: [ProtocolLib](https://www.spigotmc.org/resources/protocollib.1997/) or [ProtocolSupport](https://www.spigotmc.org/resources/protocolsupport.7201/)
* Plugin: [ProtocolLib](https://www.spigotmc.org/resources/protocollib.1997/) or
[ProtocolSupport](https://www.spigotmc.org/resources/protocolsupport.7201/)
* [Spigot](https://www.spigotmc.org) 1.7+
* Java 8+
* Run Spigot and/or BungeeCord/Waterfall in offline mode (see server.properties or config.yml)
@ -77,5 +78,6 @@ Put your stats id from the BungeeCord config into this file
5. Download and Install FastLogin on BungeeCord AND Spigot
6. Check your database settings in the config of FastLogin on BungeeCord
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
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)

View File

@ -2,8 +2,8 @@ package com.github.games647.fastlogin.bukkit;
import com.github.games647.fastlogin.bukkit.commands.CrackedCommand;
import com.github.games647.fastlogin.bukkit.commands.PremiumCommand;
import com.github.games647.fastlogin.bukkit.listener.JoinListener;
import com.github.games647.fastlogin.bukkit.listener.BungeeListener;
import com.github.games647.fastlogin.bukkit.listener.JoinListener;
import com.github.games647.fastlogin.bukkit.listener.protocollib.LoginSkinApplyListener;
import com.github.games647.fastlogin.bukkit.listener.protocollib.ProtocolLibListener;
import com.github.games647.fastlogin.bukkit.listener.protocolsupport.ProtocolSupportListener;
@ -17,11 +17,11 @@ import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import com.google.common.net.HostAndPort;
import java.nio.file.Path;
import java.security.KeyPair;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ThreadFactory;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -188,6 +188,11 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
sender.sendPluginMessage(this, getName(), dataOutput.toByteArray());
}
@Override
public Path getPluginFolder() {
return getDataFolder().toPath();
}
@Override
public Logger getLog() {
return logger;
@ -206,6 +211,6 @@ public class FastLoginBukkit extends JavaPlugin implements PlatformPlugin<Comman
@Override
public MojangApiConnector makeApiConnector(List<String> addresses, int requests, List<HostAndPort> proxies) {
return new MojangApiBukkit(getLog(), addresses, requests, proxies);
return new MojangApiBukkit(logger, addresses, requests, proxies);
}
}

View File

@ -12,7 +12,6 @@ import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URLEncoder;
import java.util.Collection;
import java.util.List;
import org.slf4j.Logger;
@ -23,7 +22,7 @@ public class MojangApiBukkit extends MojangApiConnector {
"username=%s&serverId=%s&ip=%s";
public MojangApiBukkit(Logger logger, Collection<String> localAddresses, int rateLimit
, List<HostAndPort> proxies) {
, Iterable<HostAndPort> proxies) {
super(logger, localAddresses, rateLimit, proxies);
}

View File

@ -93,9 +93,7 @@ public class CrazyLoginHook implements AuthPlugin<Player> {
//create a fake account - this will be saved to the database with the password=FAILEDLOADING
//user cannot login with that password unless the admin uses plain text
//this automatically marks the player as logged in
playerData = new LoginPlayerData(player);
crazyDatabase.save(playerData);
crazyDatabase.save(new LoginPlayerData(player));
return forceLogin(player);
}

View File

@ -6,6 +6,9 @@ import io.github.lucaseasedup.logit.CancelledState;
import io.github.lucaseasedup.logit.LogItCore;
import io.github.lucaseasedup.logit.account.Account;
import io.github.lucaseasedup.logit.session.SessionManager;
import java.time.Instant;
import org.bukkit.entity.Player;
/**
@ -22,7 +25,6 @@ public class LogItHook implements AuthPlugin<Player> {
SessionManager sessionManager = LogItCore.getInstance().getSessionManager();
return sessionManager.isSessionAlive(player)
|| sessionManager.startSession(player) == CancelledState.NOT_CANCELLED;
}
@Override
@ -34,8 +36,10 @@ public class LogItHook implements AuthPlugin<Player> {
public boolean forceRegister(Player player, String password) {
Account account = new Account(player.getName());
account.changePassword(password);
account.setLastActiveDate(System.currentTimeMillis() / 1000);
account.setRegistrationDate(System.currentTimeMillis() / 1000);
Instant now = Instant.now();
account.setLastActiveDate(now.getEpochSecond());
account.setRegistrationDate(now.getEpochSecond());
return LogItCore.getInstance().getAccountManager().insertAccount(account) == CancelledState.NOT_CANCELLED;
}
}

View File

@ -95,7 +95,7 @@ public class BungeeListener implements PluginMessageListener {
}
public Set<UUID> loadBungeeCordIds() {
Path whitelistFile = plugin.getDataFolder().toPath().resolve(FILE_NAME);
Path whitelistFile = plugin.getPluginFolder().resolve(FILE_NAME);
try {
if (Files.notExists(whitelistFile)) {
Files.createFile(whitelistFile);

View File

@ -23,7 +23,8 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
private final Player player;
private final String username;
public NameCheckTask(FastLoginBukkit plugin, PacketEvent packetEvent, Random random, Player player, String username) {
public NameCheckTask(FastLoginBukkit plugin, PacketEvent packetEvent, Random random,
Player player, String username) {
super(plugin.getCore(), plugin.getCore().getAuthPluginHook());
this.plugin = plugin;
@ -45,7 +46,8 @@ public class NameCheckTask extends JoinManagement<Player, CommandSender, Protoco
//minecraft server implementation
//https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/LoginListener.java#L161
@Override
public void requestPremiumLogin(ProtocolLibLoginSource source, PlayerProfile profile, String username, boolean registered) {
public void requestPremiumLogin(ProtocolLibLoginSource source, PlayerProfile profile
, String username, boolean registered) {
try {
source.setOnlineMode();
} catch (Exception ex) {

View File

@ -52,13 +52,15 @@ public class ProtocolSupportListener extends JoinManagement<Player, CommandSende
}
@Override
public void requestPremiumLogin(ProtocolLoginSource source, PlayerProfile profile, String username, boolean registered) {
public void requestPremiumLogin(ProtocolLoginSource source, PlayerProfile profile, String username
, boolean registered) {
source.setOnlineMode();
String ip = source.getAddress().getAddress().getHostAddress();
plugin.getCore().getPendingLogin().put(ip + username, new Object());
BukkitLoginSession playerSession = new BukkitLoginSession(username, null, null, registered, profile);
BukkitLoginSession playerSession = new BukkitLoginSession(username, null, null
, registered, profile);
plugin.getLoginSessions().put(source.getAddress().toString(), playerSession);
if (plugin.getConfig().getBoolean("premiumUuid")) {
source.getLoginStartEvent().setUseOnlineModeUUID(true);

View File

@ -9,7 +9,9 @@ import com.github.games647.fastlogin.core.shared.FastLoginCore;
import com.github.games647.fastlogin.core.shared.PlatformPlugin;
import com.google.common.collect.Maps;
import com.google.common.net.HostAndPort;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ThreadFactory;
@ -79,6 +81,11 @@ public class FastLoginBungee extends Plugin implements PlatformPlugin<CommandSen
return getDescription().getName();
}
@Override
public Path getPluginFolder() {
return getDataFolder().toPath();
}
@Override
public Logger getLog() {
return logger;
@ -92,11 +99,16 @@ public class FastLoginBungee extends Plugin implements PlatformPlugin<CommandSen
@Override
@SuppressWarnings("deprecation")
public ThreadFactory getThreadFactory() {
return new GroupedThreadFactory(this, getName());
return new ThreadFactoryBuilder()
.setNameFormat(core.getPlugin().getName() + " Database Pool Thread #%1$d")
//Hikari create daemons by default
.setDaemon(true)
.setThreadFactory(new GroupedThreadFactory(this, getName()))
.build();
}
@Override
public MojangApiConnector makeApiConnector(List<String> addresses, int requests, List<HostAndPort> proxies) {
return new MojangApiConnector(getLog(), addresses, requests, proxies);
return new MojangApiConnector(logger, addresses, requests, proxies);
}
}

View File

@ -33,6 +33,7 @@ import net.md_5.bungee.event.EventPriority;
public class ConnectListener implements Listener {
private final FastLoginBungee plugin;
private final Property[] emptyProperties = {};
public ConnectListener(FastLoginBungee plugin) {
this.plugin = plugin;
@ -89,7 +90,7 @@ public class ConnectListener implements Listener {
//this is null on offline mode
LoginResult loginProfile = initialHandler.getLoginProfile();
if (loginProfile != null) {
loginProfile.setProperties(new Property[]{});
loginProfile.setProperties(emptyProperties);
}
}
}

View File

@ -42,7 +42,8 @@ public class AsyncPremiumCheck extends JoinManagement<ProxiedPlayer, CommandSend
}
@Override
public void requestPremiumLogin(BungeeLoginSource source, PlayerProfile profile, String username, boolean registered) {
public void requestPremiumLogin(BungeeLoginSource source, PlayerProfile profile,
String username, boolean registered) {
source.setOnlineMode();
plugin.getSession().put(source.getConnection(), new BungeeLoginSession(username, registered, profile));

View File

@ -15,7 +15,8 @@ import net.md_5.bungee.api.connection.PendingConnection;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.connection.Server;
public class ForceLoginTask extends ForceLoginManagement<ProxiedPlayer, CommandSender, BungeeLoginSession, FastLoginBungee> {
public class ForceLoginTask
extends ForceLoginManagement<ProxiedPlayer, CommandSender, BungeeLoginSession, FastLoginBungee> {
private final Server server;

View File

@ -1,7 +1,6 @@
package com.github.games647.fastlogin.core;
import com.github.games647.fastlogin.core.shared.FastLoginCore;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
@ -10,14 +9,24 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.Instant;
import java.util.Properties;
import java.util.UUID;
import java.util.concurrent.ThreadFactory;
import static java.sql.Statement.RETURN_GENERATED_KEYS;
public class AuthStorage {
private static final String PREMIUM_TABLE = "premium";
private static final String LOAD_BY_NAME = "SELECT * FROM " + PREMIUM_TABLE + " WHERE Name=? LIMIT 1";
private static final String LOAD_BY_UUID = "SELECT * FROM " + PREMIUM_TABLE + " WHERE UUID=? LIMIT 1";
private static final String INSERT_PROFILE = "INSERT INTO " + PREMIUM_TABLE + " (UUID, Name, Premium, LastIp) "
+ "VALUES (?, ?, ?, ?) ";
private static final String UPDATE_PROFILE = "UPDATE " + PREMIUM_TABLE
+ " SET UUID=?, Name=?, Premium=?, LastIp=?, LastLogin=CURRENT_TIMESTAMP WHERE UserID=?";
private final FastLoginCore<?, ?, ?> core;
private final HikariDataSource dataSource;
@ -38,22 +47,18 @@ public class AuthStorage {
ThreadFactory platformThreadFactory = core.getPlugin().getThreadFactory();
if (platformThreadFactory != null) {
config.setThreadFactory(new ThreadFactoryBuilder()
.setNameFormat(core.getPlugin().getName() + " Database Pool Thread #%1$d")
//Hikari create daemons by default
.setDaemon(true)
.setThreadFactory(platformThreadFactory)
.build());
config.setThreadFactory(platformThreadFactory);
}
databasePath = databasePath.replace("{pluginDir}", core.getPlugin().getDataFolder().getAbsolutePath());
String pluginFolder = core.getPlugin().getPluginFolder().toAbsolutePath().toString();
databasePath = databasePath.replace("{pluginDir}", pluginFolder);
String jdbcUrl = "jdbc:";
if (driver.contains("sqlite")) {
jdbcUrl += "sqlite" + "://" + databasePath;
jdbcUrl += "sqlite://" + databasePath;
config.setConnectionTestQuery("SELECT 1");
} else {
jdbcUrl += "mysql" + "://" + host + ':' + port + '/' + databasePath;
jdbcUrl += "mysql://" + host + ':' + port + '/' + databasePath;
}
config.setJdbcUrl(jdbcUrl);
@ -84,8 +89,7 @@ public class AuthStorage {
public PlayerProfile loadProfile(String name) {
try (Connection con = dataSource.getConnection();
PreparedStatement loadStmt = con.prepareStatement("SELECT * FROM "
+ PREMIUM_TABLE + " WHERE Name=? LIMIT 1")) {
PreparedStatement loadStmt = con.prepareStatement(LOAD_BY_NAME)) {
loadStmt.setString(1, name);
try (ResultSet resultSet = loadStmt.executeQuery()) {
@ -96,7 +100,7 @@ public class AuthStorage {
boolean premium = resultSet.getBoolean(4);
String lastIp = resultSet.getString(5);
long lastLogin = resultSet.getTimestamp(6).getTime();
Instant lastLogin = resultSet.getTimestamp(6).toInstant();
return new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
} else {
return new PlayerProfile(null, name, false, "");
@ -111,8 +115,7 @@ public class AuthStorage {
public PlayerProfile loadProfile(UUID uuid) {
try (Connection con = dataSource.getConnection();
PreparedStatement loadStmt = con.prepareStatement("SELECT * FROM "
+ PREMIUM_TABLE + " WHERE UUID=? LIMIT 1")) {
PreparedStatement loadStmt = con.prepareStatement(LOAD_BY_UUID)) {
loadStmt.setString(1, uuid.toString().replace("-", ""));
try (ResultSet resultSet = loadStmt.executeQuery()) {
@ -122,7 +125,7 @@ public class AuthStorage {
String name = resultSet.getString(3);
boolean premium = resultSet.getBoolean(4);
String lastIp = resultSet.getString(5);
long lastLogin = resultSet.getTimestamp(6).getTime();
Instant lastLogin = resultSet.getTimestamp(6).toInstant();
return new PlayerProfile(userId, uuid, name, premium, lastIp, lastLogin);
}
}
@ -138,8 +141,7 @@ public class AuthStorage {
UUID uuid = playerProfile.getUuid();
if (playerProfile.getUserId() == -1) {
try (PreparedStatement saveStmt = con.prepareStatement("INSERT INTO " + PREMIUM_TABLE
+ " (UUID, Name, Premium, LastIp) VALUES (?, ?, ?, ?) ", Statement.RETURN_GENERATED_KEYS)) {
try (PreparedStatement saveStmt = con.prepareStatement(INSERT_PROFILE, RETURN_GENERATED_KEYS)) {
if (uuid == null) {
saveStmt.setString(1, null);
} else {
@ -159,8 +161,7 @@ public class AuthStorage {
}
}
} else {
try (PreparedStatement saveStmt = con.prepareStatement("UPDATE " + PREMIUM_TABLE
+ " SET UUID=?, Name=?, Premium=?, LastIp=?, LastLogin=CURRENT_TIMESTAMP WHERE UserID=?")) {
try (PreparedStatement saveStmt = con.prepareStatement(UPDATE_PROFILE)) {
if (uuid == null) {
saveStmt.setString(1, null);
} else {

View File

@ -136,8 +136,9 @@ public class CompatibleCacheBuilder<K, V> {
* <p>
* <p>
* When {@code size} is zero, elements will be evicted immediately after being loaded into the cache. This has the
* same effect as invoking {@link #expireAfterWrite expireAfterWrite}{@code (0, unit)} or {@link #expireAfterAccess expireAfterAccess}{@code (0,
* unit)}. It can be useful in testing, or to disable caching temporarily without a code change.
* same effect as invoking {@link #expireAfterWrite expireAfterWrite}{@code (0, unit)} or
* {@link #expireAfterAccess expireAfterAccess}{@code (0,unit)}.
* It can be useful in testing, or to disable caching temporarily without a code change.
*
* @param size the maximum size of the cache
* @return This for chaining
@ -180,7 +181,8 @@ public class CompatibleCacheBuilder<K, V> {
* @throws IllegalStateException if a removal listener was already set
*/
@SuppressWarnings("unchecked")
public <K1 extends K, V1 extends V> CompatibleCacheBuilder<K1, V1> removalListener(RemovalListener<? super K1, ? super V1> listener) {
public <K1 extends K, V1 extends V> CompatibleCacheBuilder<K1, V1> removalListener(
RemovalListener<? super K1, ? super V1> listener) {
builder.removalListener(listener);
return (CompatibleCacheBuilder<K1, V1>) this;
}

View File

@ -1,5 +1,6 @@
package com.github.games647.fastlogin.core;
import java.time.Instant;
import java.util.UUID;
public class PlayerProfile {
@ -11,9 +12,9 @@ public class PlayerProfile {
private UUID uuid;
private boolean premium;
private String lastIp;
private long lastLogin;
private Instant lastLogin;
public PlayerProfile(long userId, UUID uuid, String playerName, boolean premium, String lastIp, long lastLogin) {
public PlayerProfile(long userId, UUID uuid, String playerName, boolean premium, String lastIp, Instant lastLogin) {
this.userId = userId;
this.uuid = uuid;
this.playerName = playerName;
@ -23,7 +24,7 @@ public class PlayerProfile {
}
public PlayerProfile(UUID uuid, String playerName, boolean premium, String lastIp) {
this(-1, uuid, playerName, premium, lastIp, System.currentTimeMillis());
this(-1, uuid, playerName, premium, lastIp, Instant.now());
}
public synchronized String getPlayerName() {
@ -66,11 +67,11 @@ public class PlayerProfile {
this.lastIp = lastIp;
}
public synchronized long getLastLogin() {
public synchronized Instant getLastLogin() {
return lastLogin;
}
public synchronized void setLastLogin(long lastLogin) {
public synchronized void setLastLogin(Instant lastLogin) {
this.lastLogin = lastLogin;
}
}

View File

@ -3,7 +3,8 @@ package com.github.games647.fastlogin.core.hooks;
/**
* Represents a supporting authentication plugin in BungeeCord and Bukkit/Spigot/... servers
*
* @param <P> either org.bukkit.entity.GameProfile for Bukkit or net.md_5.bungee.api.connection.ProxiedPlayer for BungeeCord
* @param <P> either org.bukkit.entity.GameProfile for Bukkit or net.md_5.bungee.api.connection.ProxiedPlayer
* for BungeeCord
*/
public interface AuthPlugin<P> {

View File

@ -20,6 +20,8 @@ import java.net.Proxy;
import java.net.Proxy.Type;
import java.net.URL;
import java.net.UnknownHostException;
import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@ -53,7 +55,7 @@ public class MojangApiConnector {
private final SSLSocketFactory sslFactory;
private final int rateLimit;
private long lastRateLimit;
private Instant lastRateLimit;
protected final Gson gson = new GsonBuilder().registerTypeAdapter(UUID.class, new UUIDTypeAdapter()).create();
protected final Logger logger;
@ -72,9 +74,6 @@ public class MojangApiConnector {
this.proxies = Iterables.cycle(proxyBuilder).iterator();
}
/**
* @return null on non-premium
*/
public Optional<UUID> getPremiumUUID(String playerName) {
if (!validNameMatcher.matcher(playerName).matches()) {
//check if it's a valid player name
@ -83,7 +82,7 @@ public class MojangApiConnector {
try {
HttpsURLConnection connection;
if (requests.size() >= rateLimit || System.currentTimeMillis() - lastRateLimit < 1_000 * 60 * 10) {
if (requests.size() >= rateLimit || Duration.between(lastRateLimit, Instant.now()).getSeconds() < 60 * 10) {
synchronized (proxies) {
if (proxies.hasNext()) {
connection = getConnection(UUID_LINK + playerName, proxies.next());
@ -103,7 +102,7 @@ public class MojangApiConnector {
}
} else if (connection.getResponseCode() == RATE_LIMIT_CODE) {
logger.info("RATE_LIMIT REACHED");
lastRateLimit = System.currentTimeMillis();
lastRateLimit = Instant.now();
if (!connection.usingProxy()) {
return getPremiumUUID(playerName);
}
@ -153,25 +152,25 @@ public class MojangApiConnector {
}
private SSLSocketFactory buildAddresses(Logger logger, Collection<String> localAddresses) {
if (localAddresses.isEmpty()) {
if (!localAddresses.isEmpty()) {
return HttpsURLConnection.getDefaultSSLSocketFactory();
} else {
Set<InetAddress> addresses = Sets.newHashSet();
for (String localAddress : localAddresses) {
try {
InetAddress address = InetAddress.getByName(localAddress);
if (!address.isAnyLocalAddress()) {
logger.warn("Submitted IP-Address is not local {0}", address);
continue;
}
addresses.add(address);
} catch (UnknownHostException ex) {
logger.error("IP-Address is unknown to us", ex);
}
}
return new BalancedSSLFactory(HttpsURLConnection.getDefaultSSLSocketFactory(), addresses);
}
Set<InetAddress> addresses = Sets.newHashSet();
for (String localAddress : localAddresses) {
try {
InetAddress address = InetAddress.getByName(localAddress);
if (!address.isAnyLocalAddress()) {
logger.warn("Submitted IP-Address is not local {}", address);
continue;
}
addresses.add(address);
} catch (UnknownHostException ex) {
logger.error("IP-Address is unknown to us", ex);
}
}
return new BalancedSSLFactory(HttpsURLConnection.getDefaultSSLSocketFactory(), addresses);
}
}

View File

@ -2,13 +2,11 @@ package com.github.games647.fastlogin.core.mojang;
public class SkinProperties {
private final String name = "textures";
private String value;
private String signature;
public String getName() {
return "textures";
}
public String getValue() {
return value;
}

View File

@ -11,18 +11,10 @@ import java.util.UUID;
public class UUIDTypeAdapter extends TypeAdapter<UUID> {
public void write(JsonWriter out, UUID value) throws IOException {
out.value(fromUUID(value));
out.value(value.toString().replace("-", ""));
}
public UUID read(JsonReader in) throws IOException {
return fromString(in.nextString());
}
public static String fromUUID(UUID value) {
return value.toString().replace("-", "");
}
public static UUID fromString(String input) {
return CommonUtil.parseId(input);
return CommonUtil.parseId(in.nextString());
}
}

View File

@ -90,7 +90,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
defaults = configProvider.load(defaultStream);
}
File file = new File(plugin.getDataFolder(), fileName);
File file = plugin.getPluginFolder().resolve(fileName).toFile();
return configProvider.load(file, defaults);
}
@ -167,7 +167,7 @@ public class FastLoginCore<P extends C, C, T extends PlatformPlugin<C>> {
}
public void saveDefaultFile(String fileName) {
Path dataFolder = plugin.getDataFolder().toPath();
Path dataFolder = plugin.getPluginFolder();
try {
Files.createDirectories(dataFolder);

View File

@ -3,7 +3,7 @@ package com.github.games647.fastlogin.core.shared;
import com.github.games647.fastlogin.core.mojang.MojangApiConnector;
import com.google.common.net.HostAndPort;
import java.io.File;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.ThreadFactory;
@ -13,7 +13,7 @@ public interface PlatformPlugin<C> {
String getName();
File getDataFolder();
Path getPluginFolder();
Logger getLog();

View File

@ -62,8 +62,8 @@ premiumUuid: false
# #### Case 1
# nameChangeCheck = false ----- autoRegister = false
#
# GameProfile logins as cracked until the player invoked the command /premium. Then we could override the existing database
# record.
# GameProfile logins as cracked until the player invoked the command /premium. Then we could override the existing
# database record.
#
# #### Case 2
#
@ -128,8 +128,8 @@ premium-warning: true
# Once the limit is reached, new players are always logged in as cracked until the rate-limit is expired.
# (to the next ten minutes)
#
# The limit is IP-wide. If you have multiple IPv4-addresses you specify them here. FastLogin will then use it in rotating
# order --> 5 different IP-addresses 5 * 600 per 10 minutes
# The limit is IP-wide. If you have multiple IPv4-addresses you specify them here. FastLogin will then use it in
# rotating order --> 5 different IP-addresses 5 * 600 per 10 minutes
# If this list is empty only the default one will be used
#
# Lists are created like this:

View File

@ -86,7 +86,7 @@ invalid-session: '&4Invalid session'
# The client sent a malicious packet without a login request packet
invalid-requst: '&4Invalid request'
# Message if the bukkit isn't fully started to inject the packets
# Message if the Bukkit isn't fully started to inject the packets
not-started: '&cServer is not fully started yet. Please retry'
# Warning message if a user invoked /premium command