Merge branch 'master' of https://github.com/AuthMe-Team/AuthMeReloaded into commands-refactor

This commit is contained in:
ljacqu 2015-12-12 11:59:19 +01:00
commit 2f3738aa9a
60 changed files with 852 additions and 713 deletions

View File

@ -3,7 +3,7 @@
<hr>
####Development history:
[![Guava AuthMe History Video](http://img.youtube.com/vi/hJRzNfYyd9k/hqdefault.jpg)](https://www.youtube.com/watch?v=hJRzNfYyd9k)
[![Gource AuthMe History Video](http://img.youtube.com/vi/hJRzNfYyd9k/hqdefault.jpg)](https://www.youtube.com/watch?v=hJRzNfYyd9k)
#####Development tools:
@ -54,12 +54,12 @@ McStats: http://mcstats.org/plugin/AuthMe
#####"The best authentication plugin for the Bukkit/Spigot API!"
<p>Prevent username stealing on your server! Full compatible with UUIDs and Craftbukkit/Spigot 1.8.X!<br>
Use it to secure your Offline mode server or to incrase your Online mode server's protection!</p>
<p>Prevent username stealing on your server! Fully compatible with UUIDs and Craftbukkit/Spigot 1.8.X!<br>
Use it to secure your Offline mode server or to increase your Online mode server's protection!</p>
<p>AuthMeReloaded disallows players who aren't authenticated to do actions like placing blocks, moving,<br>
typing commands or use the inventory. It can also kick players with uncommon long or short player names or kick players from banned countries.</p>
<p>With the Session Login feature you don't have to execute the authentication command everytime you connect to the server! Each command and every feature can be enabled or disabled from our well structured configuration file.</p>
typing commands or using the inventory. It can also kick players with uncommonly long or short player names or kick players from banned countries.</p>
<p>With the Session Login feature you don't have to execute the authentication command every time you connect to the server! Each command and every feature can be enabled or disabled from our well structured configuration file.</p>
<p>You can also create your own translation file and, if you want, you can share it with us! :)</p>
####Features:
@ -76,7 +76,7 @@ typing commands or use the inventory. It can also kick players with uncommon lon
<li>Supported password encryption algorithms: MD5, SHA1, SHA256, <a href="https://github.com/CypherX/xAuth/wiki/Password-Hashing">xAuth</a>, <a href="http://en.wikipedia.org/wiki/Whirlpool_(cryptography)">Whirlpool</a></li>
<li>Supported alternative registration methods:<br>
<ul>
<li>PHPBB, VBullettin: MD5VB - PHPBB</li>
<li>PHPBB, VBulletin: MD5VB - PHPBB</li>
<li>MyBB: MYBB</li>
<li>IPB3: IPB3</li>
<li>PhpFusion: PHPFUSION</li>
@ -96,7 +96,7 @@ typing commands or use the inventory. It can also kick players with uncommon lon
<li>Protect player's inventory until a correct Authentication</li>
<li>Saves the quit location of the player</li>
<li>Automatic database Backup</li>
<li>Avariable languages: en, de, br, cz, pl, fr, uk, ru, hu, sk, es, fi, zhtw, zhhk, zhcn, lt, it, ko, pt, nl, gl, bg, eu, tr (feel free to send new translations)</li>
<li>Available languages: en, de, br, cz, pl, fr, uk, ru, hu, sk, es, fi, zhtw, zhhk, zhcn, lt, it, ko, pt, nl, gl, bg, eu, tr, vn (feel free to send new translations)</li>
<li>Built-in Deprecated FlatFile (auths.db) to SQL (authme.sql) converter!</li>
<li><strong>Import your old database from other plugins like Rakamak, xAuth, CrazyLogin, RoyalAuth and vAuth!</strong></li>
</ul>
@ -108,15 +108,14 @@ typing commands or use the inventory. It can also kick players with uncommon lon
####Commands
<a href="http://dev.bukkit.org/server-mods/authme-reloaded/pages/command/">Command list and usage</a>
####Permissions
<ul><li>authme.player.* - for all user command
</li><li>authme.admin.* - for all admin command
</li><li>authme.* - for all user and admin command
<ul><li>authme.player.* - for all user commands
</li><li>authme.admin.* - for all admin commands
</li><li><a href="http://dev.bukkit.org/server-mods/authme-reloaded/pages/permissions/">List of all single permissions</a>
</li></ul>
####How To
<ul><li><a href="http://dev.bukkit.org/server-mods/authme-reloaded/pages/how-to-install-and-initial-configuration/">How to Install and Setup</a>
</li><li><a href="http://dev.bukkit.org/server-mods/authme-reloaded/pages/how-to-import-database-from-xauth/">How to import database from xAuth</a>
</li><li><a href="http://dev.bukkit.org/server-mods/authme-reloaded/pages/web-site-integration/">WebSite Integration</a>
</li><li><a href="http://dev.bukkit.org/server-mods/authme-reloaded/pages/web-site-integration/">Website Integration</a>
</li><li><a href="https://raw.githubusercontent.com/Xephi/AuthMeReloaded/master/src/main/resources/config.yml">Click here for an example of the Config file</a>
</li><li><a href="http://dev.bukkit.org/server-mods/authme-reloaded/pages/how-to-import-database-from-rakamak/">How to convert from Rakamak</a>
</li><li>Convert from FlatFile (auths.db but not the sqlite one ) to MySQL: /converter

View File

@ -326,7 +326,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.4</version>
<version>2.5</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>

View File

@ -13,10 +13,20 @@ import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.command.CommandInitializer;
import fr.xephi.authme.converter.Converter;
import fr.xephi.authme.converter.ForceFlatToSqlite;
import fr.xephi.authme.datasource.*;
import fr.xephi.authme.datasource.CacheDataSource;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.datasource.FlatFile;
import fr.xephi.authme.datasource.MySQL;
import fr.xephi.authme.datasource.SQLite;
import fr.xephi.authme.hooks.BungeeCordMessage;
import fr.xephi.authme.hooks.EssSpawn;
import fr.xephi.authme.listener.*;
import fr.xephi.authme.listener.AuthMeBlockListener;
import fr.xephi.authme.listener.AuthMeEntityListener;
import fr.xephi.authme.listener.AuthMeInventoryPacketAdapter;
import fr.xephi.authme.listener.AuthMePlayerListener;
import fr.xephi.authme.listener.AuthMePlayerListener16;
import fr.xephi.authme.listener.AuthMePlayerListener18;
import fr.xephi.authme.listener.AuthMeServerListener;
import fr.xephi.authme.modules.ModuleManager;
import fr.xephi.authme.output.ConsoleFilter;
import fr.xephi.authme.output.Log4JFilter;
@ -25,7 +35,9 @@ import fr.xephi.authme.output.Messages;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.settings.*;
import fr.xephi.authme.settings.OtherAccounts;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.Spawn;
import fr.xephi.authme.util.GeoLiteAPI;
import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Utils;
@ -577,20 +589,19 @@ public class AuthMe extends JavaPlugin {
if (isSQLite) {
server.getScheduler().runTaskAsynchronously(this, new Runnable() {
@Override
public void run() {
int accounts = database.getAccountsRegistered();
if (accounts >= 4000)
ConsoleLogger.showError("YOU'RE USING THE SQLITE DATABASE WITH " + accounts + "+ ACCOUNTS, FOR BETTER PERFORMANCES, PLEASE UPGRADE TO MYSQL!!");
if (accounts >= 4000) {
ConsoleLogger.showError("YOU'RE USING THE SQLITE DATABASE WITH "
+ accounts + "+ ACCOUNTS, FOR BETTER PERFORMANCES, PLEASE UPGRADE TO MYSQL!!");
}
}
});
}
if (Settings.isCachingEnabled) {
database = new CacheDataSource(this, database);
} else {
database = new DatabaseCalls(database);
}
if (Settings.getDataSource == DataSource.DataSourceType.FILE) {
@ -919,14 +930,14 @@ public class AuthMe extends JavaPlugin {
String realIP = player.getAddress().getAddress().getHostAddress();
String sUrl = "http://monitor-1.verygames.net/api/?action=ipclean-real-ip&out=raw&ip=%IP%&port=%PORT%";
sUrl = sUrl.replace("%IP%", player.getAddress().getAddress().getHostAddress())
.replace("%PORT%", "" + player.getAddress().getPort());
.replace("%PORT%", "" + player.getAddress().getPort());
try {
URL url = new URL(sUrl);
URLConnection urlCon = url.openConnection();
try (BufferedReader in = new BufferedReader(new InputStreamReader(urlCon.getInputStream()))) {
String inputLine = in.readLine();
if (!StringUtils.isEmpty(inputLine) && !inputLine.equalsIgnoreCase("error")
&& !inputLine.contains("error")) {
&& !inputLine.contains("error")) {
realIP = inputLine;
}
} catch (IOException e) {

View File

@ -2,6 +2,8 @@ package fr.xephi.authme;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.settings.Settings;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.bukkit.Bukkit;
@ -81,8 +83,14 @@ public class SendMailSSL {
ConsoleLogger.showError("Unable to send new password as image! Using normal text! Dest: " + mail);
}
}
email.setHtmlMsg(content);
email.setTextMsg(content);
try {
email.setHtmlMsg(content);
email.setTextMsg(content);
} catch (EmailException e)
{
ConsoleLogger.showError("Your email.html config contains some error and cannot be send!");
return;
}
try {
email.send();
} catch (Exception e) {

View File

@ -3,6 +3,11 @@ package fr.xephi.authme.cache.auth;
import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.settings.Settings;
import static com.google.common.base.Objects.firstNonNull;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.nullToEmpty;
/**
*/
public class PlayerAuth {
@ -461,7 +466,7 @@ public class PlayerAuth {
* @return String
*/
public String serialize() {
StringBuilder str = new StringBuilder();
StringBuffer str = new StringBuffer();
char d = ';';
str.append(this.nickname).append(d);
str.append(this.realName).append(d);
@ -503,34 +508,35 @@ public class PlayerAuth {
public static final class Builder {
private String name;
private String realName = "Player";
private String hash = "";
private String salt = "";
private String ip = "127.0.0.1";
private String world = "world";
private String realName;
private String hash;
private String salt;
private String ip;
private String world;
private String email;
private int groupId = -1;
private double x = 0.0f;
private double y = 0.0f;
private double z = 0.0f;
private long lastLogin = System.currentTimeMillis();
private int groupId = -1;
private String email = "your@email.com";
public PlayerAuth build() {
return new PlayerAuth(
name,
hash,
salt,
checkNotNull(name).toLowerCase(),
nullToEmpty(hash),
nullToEmpty(salt),
groupId,
ip,
firstNonNull(ip, "127.0.0.1"),
lastLogin,
x, y, z, world,
email,
realName
x, y, z,
firstNonNull(world, "world"),
firstNonNull(email, "your@email.com"),
firstNonNull(realName, "Player")
);
}
public Builder name(String name) {
this.name = name.toLowerCase();
this.name = name;
return this;
}

View File

@ -102,7 +102,7 @@ public class HelpPrinter {
if (sender instanceof Player)
nodePermission = AuthMe.getInstance().getPermissionsManager().hasPermission((Player) sender, node);
final String nodePermsString = ChatColor.GRAY + (nodePermission ? ChatColor.ITALIC + " (Permission!)" : ChatColor.ITALIC + " (No Permission!)");
sender.sendMessage(" " + ChatColor.YELLOW + ChatColor.ITALIC + node + nodePermsString);
sender.sendMessage(" " + ChatColor.YELLOW + ChatColor.ITALIC + node.getNode() + nodePermsString);
}
// Print the default permission

View File

@ -49,6 +49,10 @@ public class CacheDataSource implements DataSource {
});
}
public void addAuthToCache(PlayerAuth auth) {
cache.put(auth.getNickname().toLowerCase(), auth);
}
/**
* Method isAuthAvailable.
*

View File

@ -1,513 +0,0 @@
package fr.xephi.authme.datasource;
import fr.xephi.authme.cache.auth.PlayerAuth;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
*/
public class DatabaseCalls implements DataSource {
private final ExecutorService exec;
private final DataSource database;
/**
* Constructor for DatabaseCalls.
*
* @param database DataSource
*/
public DatabaseCalls(DataSource database) {
this.database = database;
this.exec = Executors.newCachedThreadPool();
}
/**
* Method isAuthAvailable.
*
* @param user String
*
* @return boolean * @see fr.xephi.authme.datasource.DataSource#isAuthAvailable(String)
*/
@Override
public synchronized boolean isAuthAvailable(final String user) {
try {
return exec.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
return database.isAuthAvailable(user);
}
}).get();
} catch (Exception e) {
return false;
}
}
/**
* Method getAuth.
*
* @param user String
*
* @return PlayerAuth * @see fr.xephi.authme.datasource.DataSource#getAuth(String)
*/
@Override
public synchronized PlayerAuth getAuth(final String user) {
try {
return exec.submit(new Callable<PlayerAuth>() {
public PlayerAuth call() throws Exception {
return database.getAuth(user);
}
}).get();
} catch (Exception e) {
return null;
}
}
/**
* Method saveAuth.
*
* @param auth PlayerAuth
*
* @return boolean * @see fr.xephi.authme.datasource.DataSource#saveAuth(PlayerAuth)
*/
@Override
public synchronized boolean saveAuth(final PlayerAuth auth) {
try {
return exec.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
return database.saveAuth(auth);
}
}).get();
} catch (Exception e) {
return false;
}
}
/**
* Method updateSession.
*
* @param auth PlayerAuth
*
* @return boolean * @see fr.xephi.authme.datasource.DataSource#updateSession(PlayerAuth)
*/
@Override
public synchronized boolean updateSession(final PlayerAuth auth) {
try {
return exec.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
return database.updateSession(auth);
}
}).get();
} catch (Exception e) {
return false;
}
}
/**
* Method updatePassword.
*
* @param auth PlayerAuth
*
* @return boolean * @see fr.xephi.authme.datasource.DataSource#updatePassword(PlayerAuth)
*/
@Override
public synchronized boolean updatePassword(final PlayerAuth auth) {
try {
return exec.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
return database.updatePassword(auth);
}
}).get();
} catch (Exception e) {
return false;
}
}
/**
* Method purgeDatabase.
*
* @param until long
*
* @return int * @see fr.xephi.authme.datasource.DataSource#purgeDatabase(long)
*/
@Override
public synchronized int purgeDatabase(final long until) {
try {
return exec.submit(new Callable<Integer>() {
public Integer call() throws Exception {
return database.purgeDatabase(until);
}
}).get();
} catch (Exception e) {
return -1;
}
}
/**
* Method autoPurgeDatabase.
*
* @param until long
*
* @return List<String> * @see fr.xephi.authme.datasource.DataSource#autoPurgeDatabase(long)
*/
@Override
public synchronized List<String> autoPurgeDatabase(final long until) {
try {
return exec.submit(new Callable<List<String>>() {
public List<String> call() throws Exception {
return database.autoPurgeDatabase(until);
}
}).get();
} catch (Exception e) {
return new ArrayList<>();
}
}
/**
* Method removeAuth.
*
* @param user String
*
* @return boolean * @see fr.xephi.authme.datasource.DataSource#removeAuth(String)
*/
@Override
public synchronized boolean removeAuth(final String user) {
try {
return exec.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
return database.removeAuth(user);
}
}).get();
} catch (Exception e) {
return false;
}
}
/**
* Method updateQuitLoc.
*
* @param auth PlayerAuth
*
* @return boolean * @see fr.xephi.authme.datasource.DataSource#updateQuitLoc(PlayerAuth)
*/
@Override
public synchronized boolean updateQuitLoc(final PlayerAuth auth) {
try {
return exec.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
return database.updateQuitLoc(auth);
}
}).get();
} catch (Exception e) {
return false;
}
}
/**
* Method getIps.
*
* @param ip String
*
* @return int * @see fr.xephi.authme.datasource.DataSource#getIps(String)
*/
@Override
public synchronized int getIps(final String ip) {
try {
return exec.submit(new Callable<Integer>() {
public Integer call() throws Exception {
return database.getIps(ip);
}
}).get();
} catch (Exception e) {
return -1;
}
}
/**
* Method getAllAuthsByName.
*
* @param auth PlayerAuth
*
* @return List<String> * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByName(PlayerAuth)
*/
@Override
public synchronized List<String> getAllAuthsByName(final PlayerAuth auth) {
try {
return exec.submit(new Callable<List<String>>() {
public List<String> call() throws Exception {
return database.getAllAuthsByName(auth);
}
}).get();
} catch (Exception e) {
return new ArrayList<>();
}
}
/**
* Method getAllAuthsByIp.
*
* @param ip String
*
* @return List<String> * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByIp(String)
*/
@Override
public synchronized List<String> getAllAuthsByIp(final String ip) {
try {
return exec.submit(new Callable<List<String>>() {
public List<String> call() throws Exception {
return database.getAllAuthsByIp(ip);
}
}).get();
} catch (Exception e) {
return new ArrayList<>();
}
}
/**
* Method getAllAuthsByEmail.
*
* @param email String
*
* @return List<String> * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByEmail(String)
*/
@Override
public synchronized List<String> getAllAuthsByEmail(final String email) {
try {
return exec.submit(new Callable<List<String>>() {
public List<String> call() throws Exception {
return database.getAllAuthsByEmail(email);
}
}).get();
} catch (Exception e) {
return new ArrayList<>();
}
}
/**
* Method updateEmail.
*
* @param auth PlayerAuth
*
* @return boolean * @see fr.xephi.authme.datasource.DataSource#updateEmail(PlayerAuth)
*/
@Override
public synchronized boolean updateEmail(final PlayerAuth auth) {
try {
return exec.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
return database.updateEmail(auth);
}
}).get();
} catch (Exception e) {
return false;
}
}
/**
* Method updateSalt.
*
* @param auth PlayerAuth
*
* @return boolean * @see fr.xephi.authme.datasource.DataSource#updateSalt(PlayerAuth)
*/
@Override
public synchronized boolean updateSalt(final PlayerAuth auth) {
try {
return exec.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
return database.updateSalt(auth);
}
}).get();
} catch (Exception e) {
return false;
}
}
/**
* Method close.
*
* @see fr.xephi.authme.datasource.DataSource#close()
*/
@Override
public synchronized void close() {
exec.shutdown();
database.close();
}
/**
* Method reload.
*
* @see fr.xephi.authme.datasource.DataSource#reload()
*/
@Override
public synchronized void reload() {
database.reload();
}
/**
* Method purgeBanned.
*
* @param banned List<String>
*
* @see fr.xephi.authme.datasource.DataSource#purgeBanned(List<String>)
*/
@Override
public synchronized void purgeBanned(final List<String> banned) {
new Thread(new Runnable() {
public synchronized void run() {
database.purgeBanned(banned);
}
}).start();
}
/**
* Method getType.
*
* @return DataSourceType * @see fr.xephi.authme.datasource.DataSource#getType()
*/
@Override
public synchronized DataSourceType getType() {
return database.getType();
}
/**
* Method isLogged.
*
* @param user String
*
* @return boolean * @see fr.xephi.authme.datasource.DataSource#isLogged(String)
*/
@Override
public synchronized boolean isLogged(final String user) {
try {
return exec.submit(new Callable<Boolean>() {
public Boolean call() throws Exception {
return database.isLogged(user);
}
}).get();
} catch (Exception e) {
return false;
}
}
/**
* Method setLogged.
*
* @param user String
*
* @see fr.xephi.authme.datasource.DataSource#setLogged(String)
*/
@Override
public synchronized void setLogged(final String user) {
exec.execute(new Runnable() {
public synchronized void run() {
database.setLogged(user);
}
});
}
/**
* Method setUnlogged.
*
* @param user String
*
* @see fr.xephi.authme.datasource.DataSource#setUnlogged(String)
*/
@Override
public synchronized void setUnlogged(final String user) {
exec.execute(new Runnable() {
public synchronized void run() {
database.setUnlogged(user);
}
});
}
/**
* Method purgeLogged.
*
* @see fr.xephi.authme.datasource.DataSource#purgeLogged()
*/
@Override
public synchronized void purgeLogged() {
exec.execute(new Runnable() {
public synchronized void run() {
database.purgeLogged();
}
});
}
/**
* Method getAccountsRegistered.
*
* @return int * @see fr.xephi.authme.datasource.DataSource#getAccountsRegistered()
*/
@Override
public synchronized int getAccountsRegistered() {
try {
return exec.submit(new Callable<Integer>() {
public Integer call() throws Exception {
return database.getAccountsRegistered();
}
}).get();
} catch (Exception e) {
return -1;
}
}
/**
* Method updateName.
*
* @param oldOne String
* @param newOne String
*
* @see fr.xephi.authme.datasource.DataSource#updateName(String, String)
*/
@Override
public synchronized void updateName(final String oldOne, final String newOne) {
exec.execute(new Runnable() {
public synchronized void run() {
database.updateName(oldOne, newOne);
}
});
}
/**
* Method getAllAuths.
*
* @return List<PlayerAuth> * @see fr.xephi.authme.datasource.DataSource#getAllAuths()
*/
@Override
public synchronized List<PlayerAuth> getAllAuths() {
try {
return exec.submit(new Callable<List<PlayerAuth>>() {
public List<PlayerAuth> call() throws Exception {
return database.getAllAuths();
}
}).get();
} catch (Exception e) {
return new ArrayList<>();
}
}
/**
* Method getLoggedPlayers.
*
* @return List<PlayerAuth> * @see fr.xephi.authme.datasource.DataSource#getLoggedPlayers()
*/
@Override
public List<PlayerAuth> getLoggedPlayers() {
try {
return exec.submit(new Callable<List<PlayerAuth>>() {
public List<PlayerAuth> call() throws Exception {
return database.getLoggedPlayers();
}
}).get();
} catch (Exception e) {
return new ArrayList<>();
}
}
}

View File

@ -259,8 +259,9 @@ public class MySQL implements DataSource {
pst.setString(1, user.toLowerCase());
ResultSet rs = pst.executeQuery();
return rs.next();
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return false;
}
@ -312,8 +313,9 @@ public class MySQL implements DataSource {
pAuth.setHash(new String(bytes));
}
}
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
return null;
}
return pAuth;
@ -521,8 +523,9 @@ public class MySQL implements DataSource {
pst.close();
}
return true;
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return false;
}
@ -574,8 +577,9 @@ public class MySQL implements DataSource {
pst.close();
}
return true;
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return false;
}
@ -602,7 +606,7 @@ public class MySQL implements DataSource {
pst.executeUpdate();
pst.close();
return true;
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
}
return false;
@ -625,8 +629,9 @@ public class MySQL implements DataSource {
PreparedStatement pst = con.prepareStatement(sql);
pst.setLong(1, until);
result = pst.executeUpdate();
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return result;
}
@ -653,8 +658,9 @@ public class MySQL implements DataSource {
sql = "DELETE FROM " + tableName + " WHERE " + columnLastLogin + "<" + until;
st.executeUpdate(sql);
st.close();
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return list;
}
@ -693,8 +699,9 @@ public class MySQL implements DataSource {
pst.setString(1, user);
pst.executeUpdate();
return true;
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return false;
}
@ -723,8 +730,9 @@ public class MySQL implements DataSource {
pst.executeUpdate();
pst.close();
return true;
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return false;
}
@ -751,8 +759,9 @@ public class MySQL implements DataSource {
}
rs.close();
pst.close();
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return countIp;
}
@ -776,7 +785,7 @@ public class MySQL implements DataSource {
pst.executeUpdate();
pst.close();
return true;
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
@ -805,8 +814,9 @@ public class MySQL implements DataSource {
pst.executeUpdate();
pst.close();
return true;
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return false;
}
@ -820,9 +830,10 @@ public class MySQL implements DataSource {
public void reload() {
try {
reloadArguments();
} catch (Exception e) {
ConsoleLogger.showError(e.getMessage());
} catch (Exception ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.showError("Can't reconnect to MySQL database... Please check your MySQL configuration!");
ConsoleLogger.writeStackTrace(ex);
AuthMe.getInstance().stopOrUnload();
}
}
@ -861,8 +872,9 @@ public class MySQL implements DataSource {
}
rs.close();
pst.close();
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return result;
}
@ -889,8 +901,9 @@ public class MySQL implements DataSource {
}
rs.close();
pst.close();
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return result;
}
@ -938,8 +951,9 @@ public class MySQL implements DataSource {
pst.executeUpdate();
}
pst.close();
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
}
@ -969,8 +983,9 @@ public class MySQL implements DataSource {
pst.setString(1, user);
ResultSet rs = pst.executeQuery();
isLogged = rs.next() && (rs.getInt(columnLogged) == 1);
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return isLogged;
}
@ -991,8 +1006,9 @@ public class MySQL implements DataSource {
pst.setString(2, user.toLowerCase());
pst.executeUpdate();
pst.close();
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
}
@ -1012,8 +1028,9 @@ public class MySQL implements DataSource {
pst.setString(2, user.toLowerCase());
pst.executeUpdate();
pst.close();
} catch (Exception ex) {
} catch (SQLException ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
}
@ -1033,6 +1050,7 @@ public class MySQL implements DataSource {
pst.close();
} catch (Exception ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
}
@ -1047,15 +1065,16 @@ public class MySQL implements DataSource {
public int getAccountsRegistered() {
int result = 0;
try (Connection con = getConnection()) {
PreparedStatement pst = con.prepareStatement("SELECT COUNT(*) FROM " + tableName + ";");
ResultSet rs = pst.executeQuery();
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("SELECT COUNT(*) FROM " + tableName);
if (rs.next()) {
result = rs.getInt(1);
}
rs.close();
pst.close();
st.close();
} catch (Exception ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return result;
}
@ -1078,6 +1097,7 @@ public class MySQL implements DataSource {
pst.executeUpdate();
} catch (Exception ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
}
@ -1131,6 +1151,7 @@ public class MySQL implements DataSource {
st.close();
} catch (Exception ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return auths;
}
@ -1182,6 +1203,7 @@ public class MySQL implements DataSource {
}
} catch (Exception ex) {
ConsoleLogger.showError(ex.getMessage());
ConsoleLogger.writeStackTrace(ex);
}
return auths;
}

View File

@ -3,6 +3,10 @@ package fr.xephi.authme.hooks;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.datasource.CacheDataSource;
import org.bukkit.entity.Player;
import org.bukkit.plugin.messaging.PluginMessageListener;
@ -31,8 +35,7 @@ public class BungeeCordMessage implements PluginMessageListener {
* @see org.bukkit.plugin.messaging.PluginMessageListener#onPluginMessageReceived(String, Player, byte[])
*/
@Override
public void onPluginMessageReceived(String channel, Player player,
byte[] message) {
public void onPluginMessageReceived(String channel, Player player, byte[] message) {
if (!channel.equals("BungeeCord")) {
return;
}
@ -43,6 +46,29 @@ public class BungeeCordMessage implements PluginMessageListener {
// Put the IP (only the ip not the port) in the hashMap
plugin.realIp.put(player.getName().toLowerCase(), ip);
}
if (subChannel.equalsIgnoreCase("AuthMe")) {
String str = in.readUTF();
String[] args = str.split(";");
String name = args[1];
PlayerAuth auth = plugin.database.getAuth(name);
if (auth == null) {
return;
}
if ("login".equals(args[0])) {
PlayerCache.getInstance().updatePlayer(auth);
plugin.database.setLogged(name);
ConsoleLogger.info("Player " + auth.getNickname() + " has logged in from one of your server!");
} else if ("logout".equals(args[0])) {
PlayerCache.getInstance().removePlayer(name);
plugin.database.setUnlogged(name);
ConsoleLogger.info("Player " + auth.getNickname() + " has logged out from one of your server!");
} else if ("register".equals(args[0])) {
if (plugin.database instanceof CacheDataSource) {
((CacheDataSource)plugin.database).addAuthToCache(auth);
}
ConsoleLogger.info("Player " + auth.getNickname() + " has registered out from one of your server!");
}
}
}
}

View File

@ -50,6 +50,7 @@ import org.bukkit.event.player.PlayerShearEntityEvent;
import java.util.concurrent.ConcurrentHashMap;
/**
* Listener class for player's events
*/
public class AuthMePlayerListener implements Listener {
@ -196,12 +197,6 @@ public class AuthMePlayerListener implements Listener {
return;
}
/* IMPOSSIBLE!!!! TODO: check this!
if(Utils.isNPC(player)) {
return;
}
*/
String name = player.getName().toLowerCase();
String joinMsg = event.getJoinMessage();
@ -369,11 +364,16 @@ public class AuthMePlayerListener implements Listener {
plugin.getManagement().performQuit(player, true);
}
/*
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
* TODO: npc status can be used to bypass security!!!
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
*/
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
public void onPlayerPickupItem(PlayerPickupItemEvent event) {
Player player = event.getPlayer();
// TODO: npc status can be used to bypass security!!!
if (Utils.checkAuth(player) || Utils.isNPC(player)) {
return;
}
@ -384,7 +384,6 @@ public class AuthMePlayerListener implements Listener {
public void onPlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
// TODO: npc status can be used to bypass security!!!
if (Utils.checkAuth(player) || Utils.isNPC(player)) {
return;
}
@ -395,7 +394,6 @@ public class AuthMePlayerListener implements Listener {
public void onPlayerConsumeItem(PlayerItemConsumeEvent event) {
Player player = event.getPlayer();
// TODO: npc status can be used to bypass security!!!
if (Utils.checkAuth(player) || Utils.isNPC(player)) {
return;
}
@ -406,7 +404,6 @@ public class AuthMePlayerListener implements Listener {
public void onPlayerInventoryOpen(InventoryOpenEvent event) {
final Player player = (Player) event.getPlayer();
// TODO: npc status can be used to bypass security!!!
if (Utils.checkAuth(player) || Utils.isNPC(player)) {
return;
}
@ -432,8 +429,6 @@ public class AuthMePlayerListener implements Listener {
return;
if (Utils.checkAuth((Player) event.getWhoClicked()))
return;
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) event.getWhoClicked()))
return;
event.setCancelled(true);
@ -448,8 +443,6 @@ public class AuthMePlayerListener implements Listener {
if (Utils.checkAuth((Player) damager)) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC((Player) damager)) {
return;
}
@ -461,8 +454,6 @@ public class AuthMePlayerListener implements Listener {
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
@ -474,8 +465,6 @@ public class AuthMePlayerListener implements Listener {
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
@ -487,8 +476,6 @@ public class AuthMePlayerListener implements Listener {
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
@ -500,8 +487,6 @@ public class AuthMePlayerListener implements Listener {
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
@ -513,8 +498,6 @@ public class AuthMePlayerListener implements Listener {
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
@ -536,8 +519,6 @@ public class AuthMePlayerListener implements Listener {
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
@ -560,8 +541,6 @@ public class AuthMePlayerListener implements Listener {
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
@ -573,12 +552,9 @@ public class AuthMePlayerListener implements Listener {
if (Utils.checkAuth(event.getPlayer())) {
return;
}
// TODO: npc status can be used to bypass security!!!
if (Utils.isNPC(event.getPlayer())) {
return;
}
event.setCancelled(true);
}
}

View File

@ -1,5 +1,7 @@
package fr.xephi.authme.process.login;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.backup.JsonCache;
@ -113,6 +115,15 @@ public class ProcessSyncronousPlayerLogin implements Runnable {
}
}
protected void sendBungeeMessage() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("Forward");
out.writeUTF("ALL");
out.writeUTF("AuthMe");
out.writeUTF("login;" + name);
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
}
/**
* Method run.
*
@ -186,7 +197,8 @@ public class ProcessSyncronousPlayerLogin implements Runnable {
// The Login event now fires (as intended) after everything is processed
Bukkit.getServer().getPluginManager().callEvent(new LoginEvent(player, true));
player.saveData();
if (Settings.bungee)
sendBungeeMessage();
// Login is finish, display welcome message
if (Settings.useWelcomeMessage)
if (Settings.broadcastWelcomeMessage) {

View File

@ -1,5 +1,7 @@
package fr.xephi.authme.process.logout;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.limbo.LimboCache;
@ -38,6 +40,15 @@ public class ProcessSyncronousPlayerLogout implements Runnable {
this.name = player.getName().toLowerCase();
}
protected void sendBungeeMessage() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("Forward");
out.writeUTF("ALL");
out.writeUTF("AuthMe");
out.writeUTF("logout;" + name);
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
}
/**
* Method run.
*
@ -76,6 +87,8 @@ public class ProcessSyncronousPlayerLogout implements Runnable {
}
// Player is now logout... Time to fire event !
Bukkit.getServer().getPluginManager().callEvent(new LogoutEvent(player));
if (Settings.bungee)
sendBungeeMessage();
m.send(player, MessageKey.LOGOUT_SUCCESS);
ConsoleLogger.info(player.getName() + " logged out");
}

View File

@ -145,7 +145,7 @@ public class AsyncRegister {
database.setLogged(name);
}
plugin.otherAccounts.addPlayer(player.getUniqueId());
ProcessSyncronousPasswordRegister sync = new ProcessSyncronousPasswordRegister(player, plugin);
ProcessSyncPasswordRegister sync = new ProcessSyncPasswordRegister(player, plugin);
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, sync);
}
}

View File

@ -64,8 +64,9 @@ public class ProcessSyncEmailRegister implements Runnable {
}
player.saveData();
if (!Settings.noConsoleSpam)
if (!Settings.noConsoleSpam) {
ConsoleLogger.info(player.getName() + " registered " + plugin.getIP(player));
}
}
}

View File

@ -1,5 +1,7 @@
package fr.xephi.authme.process.register;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.limbo.LimboCache;
@ -21,7 +23,7 @@ import org.bukkit.scheduler.BukkitTask;
/**
*/
public class ProcessSyncronousPasswordRegister implements Runnable {
public class ProcessSyncPasswordRegister implements Runnable {
protected final Player player;
protected final String name;
@ -29,18 +31,27 @@ public class ProcessSyncronousPasswordRegister implements Runnable {
private final Messages m;
/**
* Constructor for ProcessSyncronousPasswordRegister.
* Constructor for ProcessSyncPasswordRegister.
*
* @param player Player
* @param plugin AuthMe
*/
public ProcessSyncronousPasswordRegister(Player player, AuthMe plugin) {
public ProcessSyncPasswordRegister(Player player, AuthMe plugin) {
this.m = plugin.getMessages();
this.player = player;
this.name = player.getName().toLowerCase();
this.plugin = plugin;
}
private void sendBungeeMessage() {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("Forward");
out.writeUTF("ALL");
out.writeUTF("AuthMe");
out.writeUTF("register;" + name);
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
}
private void forceCommands() {
for (String command : Settings.forceRegisterCommands) {
player.performCommand(command.replace("%p", player.getName()));
@ -155,6 +166,10 @@ public class ProcessSyncronousPasswordRegister implements Runnable {
}
}
if (Settings.bungee) {
sendBungeeMessage();
}
// Register is now finish , we can force all commands
forceCommands();
}

View File

@ -1,5 +1,7 @@
package fr.xephi.authme.settings;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.datasource.DataSource;
@ -8,10 +10,14 @@ import fr.xephi.authme.security.HashAlgorithm;
import fr.xephi.authme.util.Wrapper;
import org.bukkit.configuration.file.YamlConfiguration;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import java.io.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
@ -94,7 +100,7 @@ public final class Settings {
getMailPort, maxLoginTry, captchaLength, saltLength,
getmaxRegPerEmail, bCryptLog2Rounds, getPhpbbGroup,
antiBotSensibility, antiBotDuration, delayRecall, getMaxLoginPerIp,
getMaxJoinPerIp, getMySQLMaxConnections;
getMaxJoinPerIp;
protected static YamlConfiguration configFile;
private static AuthMe plugin;
private static Settings instance;
@ -170,7 +176,6 @@ public final class Settings {
isCachingEnabled = configFile.getBoolean("DataSource.caching", true);
getMySQLHost = configFile.getString("DataSource.mySQLHost", "127.0.0.1");
getMySQLPort = configFile.getString("DataSource.mySQLPort", "3306");
getMySQLMaxConnections = configFile.getInt("DataSource.mySQLMaxConections", 25);
getMySQLUsername = configFile.getString("DataSource.mySQLUsername", "authme");
getMySQLPassword = configFile.getString("DataSource.mySQLPassword", "12345");
getMySQLDatabase = configFile.getString("DataSource.mySQLDatabase", "authme");
@ -302,39 +307,36 @@ public final class Settings {
}
private static String loadEmailText() {
if (!EMAIL_FILE.exists())
saveDefaultEmailText();
StringBuilder str = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new FileReader(EMAIL_FILE));
String s;
while ((s = in.readLine()) != null)
str.append(s);
in.close();
} catch(IOException e)
{
}
return str.toString();
}
if (!EMAIL_FILE.exists())
saveDefaultEmailText();
StringBuilder str = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new FileReader(EMAIL_FILE));
String s;
while ((s = in.readLine()) != null)
str.append(s);
in.close();
} catch (IOException ignored) {
}
return str.toString();
}
private static void saveDefaultEmailText() {
InputStream file = plugin.getResource("email.html");
StringBuilder str = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(file, Charset.forName("utf-8")));
String s;
while ((s = in.readLine()) != null)
str.append(s);
in.close();
Files.touch(EMAIL_FILE);
Files.write(str.toString(), EMAIL_FILE, Charsets.UTF_8);
}
catch(Exception e)
{
}
}
private static void saveDefaultEmailText() {
InputStream file = plugin.getResource("email.html");
StringBuilder str = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(file, Charset.forName("utf-8")));
String s;
while ((s = in.readLine()) != null)
str.append(s);
in.close();
Files.touch(EMAIL_FILE);
Files.write(str.toString(), EMAIL_FILE, Charsets.UTF_8);
} catch (Exception ignored) {
}
}
public static void setValue(String key, Object value) {
public static void setValue(String key, Object value) {
instance.set(key, value);
save();
}
@ -720,10 +722,9 @@ public final class Settings {
changes = true;
}
if (contains("Email.mailText"))
{
set("Email.mailText", null);
ConsoleLogger.showError("Remove Email.mailText from config, we now use the email.html file");
if (contains("Email.mailText")) {
set("Email.mailText", null);
ConsoleLogger.showError("Remove Email.mailText from config, we now use the email.html file");
}
if (changes) {

View File

@ -8,8 +8,6 @@ DataSource:
mySQLHost: 127.0.0.1
# Database Port
mySQLPort: '3306'
# MySql Max Connections
mySQLMaxConections: 8
# Username about Database Connection Infos
mySQLUsername: authme
# Password about Database Connection Infos

View File

@ -1,8 +1,7 @@
unknown_user: '&fПотребителя не е в БД'
unsafe_spawn: '&fТвоята локация когато излезе не беше безопасна, телепортиран си на Spawn!'
not_logged_in: '&cНе си влязъл!'
reg_voluntarily: '&fМоже да се регистрираш с тази команда:
"/register парола парола"'
reg_voluntarily: '&fМоже да се регистрираш с тази команда:&n "/register парола парола"'
usage_log: '&cКоманда: /login парола'
wrong_pwd: '&cГрешна парола!'
unregistered: '&cУспешно от-регистриран!'
@ -24,7 +23,7 @@ user_unknown: '&cПотребителя не е регистриран'
password_error: '&fПаролата не съвпада'
password_error_nick: '&fYou can''t use your name as password'
password_error_unsafe: '&fYou can''t use unsafe passwords'
invalid_session: '&fSession Dataes doesnt corrispond Plaese wait the end of session'
invalid_session: '&cYour IP has been changed and your session data has expired!'
reg_only: '&fСамо за регистрирани! Моля посети http://example.com за регистрация'
logged_in: '&cВече сте влязъл!'
logout: '&cУспешен изход от регистрацията!'
@ -43,7 +42,7 @@ wrong_captcha: '&cГрешен код, използвай : /captcha THE_CAPTCHA
valid_captcha: '&cТвоя код е валиден!'
kick_forvip: '&cVIP влезе докато сървъра е пълен, ти беше изгонен!'
kick_fullserver: '&cСървъра е пълен, Съжеляваме!'
usage_email_add: '&fКоманда: /email add <email> <confirmeEmail> '
usage_email_add: '&fКоманда: /email add <email> <confirmEmail> '
usage_email_change: '&fКоманда: /email change <СтарИмейл> <НовИмейл> '
usage_email_recovery: '&fКоманда: /email recovery <имейл>'
new_email_invalid: '[AuthMe] Новия имейл е грешен!'
@ -56,3 +55,5 @@ email_send: '[AuthMe] Изпраен е имейл !'
country_banned: Твоята държава е забранена в този сървър!
antibot_auto_enabled: '[AuthMe] AntiBotMod автоматично включен, открита е потенциална атака!'
antibot_auto_disabled: '[AuthMe] AntiBotMod автоматично изключване след %m Минути.'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -56,3 +56,4 @@ email_exists: '[AuthMe] Um email já existe na sua conta. Você pode mudalo usan
country_banned: 'O seu pais é banido desse servidor'
antibot_auto_enabled: '[AuthMe] AntiBotMod ativado automaticamente devido a um aumento anormal de tentativas de ligação!'
antibot_auto_disabled: '[AuthMe] AntiBotMod desactivado automaticamente após %m minutos, esperamos que a invasão tenha parado'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'

View File

@ -19,7 +19,7 @@ reg_email_msg: '&cProsim registruj se pomoci "/register <email> <potvrzeni_email
usage_unreg: '&cPouzij: "/unregister TvojeHeslo".'
pwd_changed: '&cHeslo zmeneno!'
user_unknown: '&cUzivatelske jmeno neni registrovano.'
reg_only: '&cServer je pouze pro registrovane! Navstivte http://bit.ly/zyEzzS.'
reg_only: '&cServer je pouze pro registrovane! Navstivte http://example.com.'
logged_in: '&cJiz jsi prihlasen!'
logout: '&cOdhlaseni bylo uspesne.'
same_nick: '&cUzivatel s timto jmenem jiz hraje.'
@ -55,3 +55,5 @@ email_send: '[AuthMe] Email pro obnoveni hesla odeslan!'
country_banned: 'Vase zeme je na tomto serveru zakazana'
antibot_auto_enabled: '[AuthMe] AntiBotMod automaticky spusten z duvodu masivnich pripojeni!'
antibot_auto_disabled: '[AuthMe] AntiBotMod automaticky ukoncen po %m minutach, doufejme v konec invaze'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -56,3 +56,4 @@ email_exists: '&cEine Wiederherstellungs-Email wurde bereits versandt! Nutze fol
country_banned: '&4Dein Land ist gesperrt'
antibot_auto_enabled: '&4[AntiBotService] AntiBotMod wurde aufgrund hoher Netzauslastung automatisch aktiviert!'
antibot_auto_disabled: '&2[AntiBotService] AntiBotMod wurde nach %m Minuten deaktiviert, hoffentlich ist die Invasion vorbei'
kick_antibot: 'AntiBotMod ist aktiviert! Bitte warte einige Minuten, bevor du dich mit dem Server verbindest'

View File

@ -56,3 +56,5 @@ email_send: '[AuthMe] Correo de recuperación enviado !'
country_banned: 'Tu país ha sido baneado de este servidor!'
antibot_auto_enabled: '[AuthMe] AntiBotMod activado automáticamente debido a conexiones masivas!'
antibot_auto_disabled: '[AuthMe] AntiBotMod desactivado automáticamente luego de %m minutos. Esperamos que haya terminado'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -56,3 +56,4 @@ email_exists: '[AuthMe] An email already exists on your account. You can change
country_banned: '[AuthMe]Zure herrialdea blokeatuta dago zerbitzari honetan'
antibot_auto_enabled: '[AuthMe] AntiBotMod automatically enabled due to massive connections!'
antibot_auto_disabled: '[AuthMe] AntiBotMod automatically disabled after %m Minutes,hope invasion stopped'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'

View File

@ -38,7 +38,7 @@ regex: '&cPelaajanimesi sisältää luvattomia merkkejä. Hyväksytyt merkit: RE
add_email: '&cLisää sähköpostisi: /email add sähköpostisi sähköpostisiUudelleen'
recovery_email: '&cUnohtuiko salasana? Käytä komentoa: /email recovery <Sähköpostisi>'
usage_captcha: '&cKäyttötapa: /captcha <Captcha>'
wrong_captcha: '&cVäärä varmistus, käytä : /captcha CAPTCHA'
wrong_captcha: '&cVäärä varmistus, käytä : /captcha THE_CAPTCHA'
valid_captcha: '&cSinun varmistus onnistui.!'
kick_forvip: '&cVIP pelaaja liittyi täyteen palvelimeen!'
kick_fullserver: '&cPalvelin on täynnä, Yritä pian uudelleen!'
@ -55,3 +55,5 @@ email_send: '[AuthMe] Palautus sähköposti lähetetty!'
country_banned: 'Your country is banned from this server'
antibot_auto_enabled: '[AuthMe] AntiBotMod automatically enabled due to massive connections!'
antibot_auto_disabled: '[AuthMe] AntiBotMod automatically disabled after %m Minutes, hope invasion stopped'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -25,7 +25,7 @@ pwd_changed: '&cMotdePasse changé avec succès!'
user_unknown: '&c Ce compte n''est pas enregistré'
password_error: '&fCe mot de passe est incorrect'
invalid_session: '&fSession invalide, relancez le jeu ou attendez la fin de la session'
reg_only: '&fSeul les joueurs enregistré sont admis!'
reg_only: '&fSeul les joueurs enregistré sont admis! Visite http://example.com'
logged_in: '&cVous êtes déjà connecté!'
logout: '&cVous avez été déconnecté!'
same_nick: '&fUne personne ayant ce même pseudo joue déjà..'
@ -56,3 +56,5 @@ email_send: '[AuthMe] Email de récupération envoyé!'
country_banned: 'Votre pays est banni de ce serveur'
antibot_auto_enabled: '[AuthMe] AntiBotMod a été activé automatiquement à cause de nombreuses connections!'
antibot_auto_disabled: '[AuthMe] AntiBotMod a été désactivé automatiquement après %m Minutes, espérons que l''invasion soit arrêtée!'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -1,8 +1,7 @@
unknown_user: '&fO usuario non está na base de datos'
unsafe_spawn: '&fA localización dende a que saíches era insegura, teletransportándote ao spawn do mundo'
not_logged_in: '&cNon te identificaches!'
reg_voluntarily: '&fPodes rexistrar o teu nome no servidor co comando
"/register <contrasinal> <confirmarContrasinal>"'
reg_voluntarily: '&fPodes rexistrar o teu nome no servidor co comando "/register <contrasinal> <confirmarContrasinal>"'
usage_log: '&cUso: /login <contrasinal>'
wrong_pwd: '&cContrasinal equivocado'
unregistered: '&cFeito! Xa non estás rexistrado!'
@ -55,5 +54,6 @@ email_changed: '[AuthMe] Cambiouse o correo!'
email_send: '[AuthMe] Enviouse o correo de confirmación!'
country_banned: 'O teu país está bloqueado neste servidor'
antibot_auto_enabled: '[AuthMe] AntiBotMod conectouse automáticamente debido a conexións masivas!'
antibot_auto_disabled: '[AuthMe] AntiBotMod desactivouse automáticamente despois de %m minutos,
esperemos que a invasión se detivera'
antibot_auto_disabled: '[AuthMe] AntiBotMod desactivouse automáticamente despois de %m minutos,&n esperemos que a invasión se detivera'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -55,3 +55,5 @@ email_send: '[AuthMe] Recovery Email Send !'
country_banned: 'Your country is banned from this server'
antibot_auto_enabled: '[AuthMe] AntiBotMod automatically enabled due to massive connections!'
antibot_auto_disabled: '[AuthMe] AntiBotMod automatically disabled after %m Minutes, hope invasion stopped'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -56,3 +56,4 @@ email_exists: '&cEmail pemulihan sudah dikirim! kamu bisa membatalkan dan mengir
country_banned: '&4Your country is banned from this server!'
antibot_auto_enabled: '&4[AntiBotService] AntiBot diaktifkan dikarenakan banyak koneksi yg diterima!'
antibot_auto_disabled: '&2[AntiBotService] AntiBot dimatikan setelah %m menit!'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'

View File

@ -56,3 +56,4 @@ email_exists: 'Il tuo account ha già un''indirizzo email configurato. Se vuoi,
country_banned: 'Il tuo paese è bandito da questo server!'
antibot_auto_enabled: 'Il servizio di AntiBot è stato automaticamente abilitato a seguito delle numerose connessioni!'
antibot_auto_disabled: "Il servizio di AntiBot è stato automaticamente disabilitato dopo %m Minuti, sperando che l'attacco sia finito!"
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'

View File

@ -60,3 +60,4 @@ email_exists: '[AuthMe] 당신의 계정에 이미 이메일이 존재합니다.
country_banned: '당신의 국가는 이 서버에서 차단당했습니다'
antibot_auto_enabled: '[AuthMe] 봇차단모드가 연결 개수 때문에 자동적으로 활성화됩니다!'
antibot_auto_disabled: '[AuthMe] 봇차단모드가 %m 분 후에 자동적으로 비활성화됩니다'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'

View File

@ -55,3 +55,5 @@ email_send: '[AuthMe] Recovery Email Send !'
country_banned: 'Your country is banned from this server'
antibot_auto_enabled: '[AuthMe] AntiBotMod automatically enabled due to massive connections!'
antibot_auto_disabled: '[AuthMe] AntiBotMod automatically disabled after %m Minutes, hope invasion stopped'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -54,3 +54,6 @@ email_send: '[AuthMe] Herstel E-mail Verzonden!'
country_banned: 'Jouw land is geband op deze server'
antibot_auto_enabled: '[AuthMe] AntiBotMod automatisch aangezet vanewge veel verbindingen!'
antibot_auto_disabled: '[AuthMe] AntiBotMod automatisch uitgezet na %m minuten, hopelijk is de invasie gestopt'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
reg_email_msg: '&3Please, register to the server with the command "/register <email> <confirmEmail>"'

View File

@ -55,3 +55,5 @@ email_send: '[AuthMe] Email z odzyskaniem wyslany!'
country_banned: 'Your country is banned from this server'
antibot_auto_enabled: '[AuthMe] AntiBotMod automatically enabled due to massive connections!'
antibot_auto_disabled: '[AuthMe] AntiBotMod automatically disabled after %m Minutes, hope invasion stopped'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -56,3 +56,5 @@ email_send: 'Nova palavra-passe enviada para o seu email!'
country_banned: 'O seu país está banido deste servidor'
antibot_auto_enabled: '[AuthMe] AntiBotMod activado automaticamente devido a um aumento anormal de tentativas de ligação!'
antibot_auto_disabled: '[AuthMe] AntiBotMod desactivado automaticamente após %m minutos, esperamos que a invasão tenha parado'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -1,4 +1,4 @@
unknown_user: '&fПользователь не найден в Базе Данных'
unknown_user: '&fПользователь не найден в Базе Данных'
unsafe_spawn: '&eВаше расположение перед выходом было опасным - вы перенесены на спавн'
not_logged_in: '&c&lВы еще не вошли!'
reg_voluntarily: '&aЧтобы зарегистрироваться введите: &e&l/reg ПАРОЛЬ ПОВТОРАРОЛЯ'
@ -55,3 +55,5 @@ email_send: '[AuthMe] Письмо с инструкциями для восст
country_banned: 'Вход с IP-адресов вашей страны воспрещен на этом сервере'
antibot_auto_enabled: '&a[AuthMe] AntiBot-режим автоматически включен из-за большого количества входов!'
antibot_auto_disabled: '&a[AuthMe] AntiBot-режим автоматичски отключен после %m мин. Надеюсь атака закончилась'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -59,3 +59,5 @@ email_send: '[AuthMe] Recovery Email Send !'
country_banned: 'Your country is banned from this server'
antibot_auto_enabled: '[AuthMe] AntiBotMod automatically enabled due to massive connections!'
antibot_auto_disabled: '[AuthMe] AntiBotMod automatically disabled after %m Minutes, hope invasion stopped'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -56,3 +56,4 @@ email_exists: '[AuthMe] An email already exists on your account. You can change
country_banned: 'Ulken bu serverdan banlandi !'
antibot_auto_enabled: '[AuthMe] AntiBotMode otomatik olarak etkinlestirildi!'
antibot_auto_disabled: '[AuthMe] AntiBotMode %m dakika sonra otomatik olarak isgal yuzundan devredisi birakildi'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'

View File

@ -55,3 +55,5 @@ email_send: '[AuthMe] Лист для відновлення надіслано
country_banned: 'Сервер не доступний для вашої країни | Your country is banned from this server'
antibot_auto_enabled: '[AuthMe] AntiBotMod автоматично увімкнений (забагато одначасних з`єднань)!'
antibot_auto_disabled: '[AuthMe] AntiBotMod автоматично вимкнувся, сподіваємось атака зупинена'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -21,7 +21,7 @@ usage_unreg: '&eSử dụng: /unregister mật-khẩu'
pwd_changed: '&cĐã đổi mật khẩu!'
user_unknown: '&cTài khoản này chưa được đăng kí'
password_error: '&fMật khẩu không khớp'
unvalid_session: '&fPhiên đăng nhập không hồi đáp, vui lòng chờ phiên đăng nhập kết thúc'
invalid_session: '&fPhiên đăng nhập không hồi đáp, vui lòng chờ phiên đăng nhập kết thúc'
reg_only: '&fChỉ cho phép người đã đăng kí! Hãy vào trang http://web-của.bạn/ để đăng kí'
logged_in: '&cĐã đăng nhập!'
logout: '&cThoát đăng nhập thành công'
@ -52,4 +52,8 @@ email_changed: '[AuthMe] Đã thay đổi email !'
email_send: '[AuthMe] Đã gửi email khôi phục mật khẩu tới bạn !'
country_banned: 'Rất tiếc, quốc gia của bạn không được phép gia nhập server'
antibot_auto_enabled: '[AuthMe] AntiBot đã được kích hoạt vì lượng người chơi kết nối vượt quá giới hạn!'
antibot_auto_disabled: '[AuthMe] AntiBot tự huỷ kích hoạt sau %m phút, hi vọng lượng kết nối sẽ giảm bớt'
antibot_auto_disabled: '[AuthMe] AntiBot tự huỷ kích hoạt sau %m phút, hi vọng lượng kết nối sẽ giảm bớt'
password_error_nick: '&cYou can''t use your name as password, please choose another one...'
password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -58,3 +58,5 @@ email_send: '&8[&6用戶系統&8] 忘記密碼信件已寄出,請查收。'
country_banned: '&8[&6用戶系統&8] 本伺服器已停止對你的國家提供遊戲服務。'
antibot_auto_enabled: '&8[&6用戶系統&8] 防止機械人程序已因應現時大量不尋常連線而啟用。'
antibot_auto_disabled: '&8[&6用戶系統&8] 不正常連接數已減少,防止機械人程序將於 %m 分鐘後停止。'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'

View File

@ -1,4 +1,4 @@
# Translator: MineWolf50
# Translator: MineWolf50
# Last Time Edit : 2015 / 7 / 14 , A.M.10:14
# = = = = = = = = = = = = = = = = = = = = = = = #
unknown_user: "&b【AuthMe】&6沒有在資料庫內找到該玩家。"
@ -58,4 +58,5 @@ email_send: '&b【AuthMe】&6已經送出重設密碼要求至你的Email , 請
email_exists: '&b【AuthMe】&6這個帳戶已經有設定電子郵件了'
country_banned: '&b【AuthMe】&6你所在的地區無法進入此伺服器'
antibot_auto_enabled: '&b【AuthMe】&6AntiBotMod已自動啟用!'
antibot_auto_disabled: '&b【AuthMe】&6AntiBotMod將會於 &c%m &6分鐘後自動關閉'
antibot_auto_disabled: '&b【AuthMe】&6AntiBotMod將會於 &c%m &6分鐘後自動關閉'
kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'

128
src/tools/ToolsRunner.java Normal file
View File

@ -0,0 +1,128 @@
import utils.ToolTask;
import utils.ToolsConstants;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
* Runner for executing tool tasks.
*/
public final class ToolsRunner {
private ToolsRunner() {
}
/**
* Entry point of the runner.
*
* @param args .
*/
public static void main(String... args) {
// Collect tasks and show them
File toolsFolder = new File(ToolsConstants.TOOLS_SOURCE_ROOT);
Map<String, ToolTask> tasks = new HashMap<>();
collectTasksInDirectory(toolsFolder, tasks);
listAllTasks(tasks);
// Prompt user for task and handle input
System.out.println("Please enter the task to run:");
Scanner scanner = new Scanner(System.in);
String inputTask = scanner.nextLine();
ToolTask task = tasks.get(inputTask);
if (task != null) {
task.execute(scanner);
} else {
System.out.println("Unknown task");
}
scanner.close();
}
private static void listAllTasks(Map<String, ToolTask> taskCollection) {
System.out.println("The following tasks are available:");
for (String key : taskCollection.keySet()) {
System.out.println("- " + key);
}
}
/**
* Add all implementations of {@link ToolTask} from the given folder to the provided collection.
*
* @param dir The directory to scan
* @param taskCollection The collection to add results to
*/
// Note ljacqu 20151212: If the tools folder becomes a lot bigger, it will make sense to restrict the depth
// of this recursive collector
private static void collectTasksInDirectory(File dir, Map<String, ToolTask> taskCollection) {
File[] files = dir.listFiles();
if (files == null) {
throw new RuntimeException("Cannot read folder '" + dir + "'");
}
for (File file : files) {
if (file.isDirectory()) {
collectTasksInDirectory(file, taskCollection);
} else if (file.isFile()) {
ToolTask task = getTaskFromFile(file);
if (task != null) {
taskCollection.put(task.getTaskName(), task);
}
}
}
}
/**
* Return a {@link ToolTask} instance defined by the given source file.
*
* @param file The file to load
* @return ToolTask instance, or null if not applicable
*/
private static ToolTask getTaskFromFile(File file) {
Class<? extends ToolTask> taskClass = loadTaskClassFromFile(file);
if (taskClass == null) {
return null;
}
try {
Constructor<? extends ToolTask> constructor = taskClass.getConstructor();
return constructor.newInstance();
} catch (NoSuchMethodException | InvocationTargetException |
IllegalAccessException | InstantiationException e) {
throw new RuntimeException("Cannot instantiate task '" + taskClass + "'");
}
}
/**
* Return the class the file defines if it implements {@link ToolTask}.
*
* @return The class instance, or null if not applicable
*/
@SuppressWarnings("unchecked")
private static Class<? extends ToolTask> loadTaskClassFromFile(File file) {
if (!file.getName().endsWith(".java")) {
return null;
}
String filePath = file.getPath();
String className = filePath
.substring(ToolsConstants.TOOLS_SOURCE_ROOT.length(), filePath.length() - 5)
.replace(File.separator, ".");
try {
Class<?> clazz = ClassLoader.getSystemClassLoader().loadClass(className);
return ToolTask.class.isAssignableFrom(clazz) && isInstantiable(clazz)
? (Class<? extends ToolTask>) clazz
: null;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
private static boolean isInstantiable(Class<?> clazz) {
return !clazz.isInterface() && !Modifier.isAbstract(clazz.getModifiers());
}
}

View File

@ -0,0 +1,115 @@
package messages;
import fr.xephi.authme.output.MessageKey;
import utils.FileUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Verifies a message file's keys to ensure that it is in sync with {@link MessageKey}, i.e. that the file contains
* all keys and that it doesn't have any unknown ones.
*/
public class MessageFileVerifier {
private static final String NEW_LINE = "\n";
private final String messagesFile;
private final Set<String> unknownKeys = new HashSet<>();
// Map with the missing key and a boolean indicating whether or not it was added to the file by this object
private final Map<String, Boolean> missingKeys = new HashMap<>();
/**
* Create a verifier that verifies the given messages file.
*
* @param messagesFile The messages file to process
*/
public MessageFileVerifier(String messagesFile) {
this.messagesFile = messagesFile;
verifyKeys();
}
/**
* Return the list of unknown keys, i.e. the list of keys present in the file that are not
* part of the {@link MessageKey} enum.
*
* @return List of unknown keys
*/
public Set<String> getUnknownKeys() {
return unknownKeys;
}
/**
* Return the list of missing keys, i.e. all keys that are part of {@link MessageKey} but absent
* in the messages file.
*
* @return The list of missing keys in the file
*/
public Map<String, Boolean> getMissingKeys() {
return missingKeys;
}
private void verifyKeys() {
Set<String> messageKeys = getAllMessageKeys();
List<String> fileLines = FileUtils.readLinesFromFile(messagesFile);
for (String line : fileLines) {
// Skip comments and empty lines
if (!line.startsWith("#") && !line.trim().isEmpty()) {
processKeyInFile(line, messageKeys);
}
}
// All keys that remain are keys that are absent in the file
for (String missingKey : messageKeys) {
missingKeys.put(missingKey, false);
}
}
private void processKeyInFile(String line, Set<String> messageKeys) {
if (line.indexOf(':') == -1) {
System.out.println("Skipping line in unknown format: '" + line + "'");
return;
}
final String key = line.substring(0, line.indexOf(':'));
if (messageKeys.contains(key)) {
messageKeys.remove(key);
} else {
unknownKeys.add(key);
}
}
/**
* Add missing keys to the file with the provided default (English) message.
*
* @param defaultMessages The collection of default messages
*/
public void addMissingKeys(Map<String, String> defaultMessages) {
List<String> keysToAdd = new ArrayList<>();
for (Map.Entry<String, Boolean> entry : missingKeys.entrySet()) {
if (Boolean.FALSE.equals(entry.getValue()) && defaultMessages.get(entry.getKey()) != null) {
keysToAdd.add(entry.getKey());
}
}
// We know that all keys in keysToAdd are safe to retrieve and write
StringBuilder sb = new StringBuilder(NEW_LINE);
for (String keyToAdd : keysToAdd) {
sb.append(keyToAdd).append(":").append(defaultMessages.get(keyToAdd)).append(NEW_LINE);
missingKeys.put(keyToAdd, true);
}
FileUtils.appendToFile(messagesFile, sb.toString());
}
private static Set<String> getAllMessageKeys() {
Set<String> messageKeys = new HashSet<>(MessageKey.values().length);
for (MessageKey key : MessageKey.values()) {
messageKeys.add(key.getKey());
}
return messageKeys;
}
}

View File

@ -0,0 +1,2 @@
## Messages
Verifies the messages files and adds any missing indices with the English content as default.

View File

@ -0,0 +1,157 @@
package messages;
import fr.xephi.authme.util.StringUtils;
import utils.FileUtils;
import utils.ToolTask;
import utils.ToolsConstants;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.regex.Pattern;
import static java.lang.String.format;
/**
* Task to verify the keys in the messages files.
*/
public final class VerifyMessagesTask implements ToolTask {
/** The folder containing the message files. */
private static final String MESSAGES_FOLDER = ToolsConstants.MAIN_RESOURCES_ROOT + "messages/";
/** Pattern of the message file names. */
private static final Pattern MESSAGE_FILE_PATTERN = Pattern.compile("messages_[a-z]{2,7}\\.yml");
/** Tag that is replaced to the messages folder in user input. */
private static final String SOURCES_TAG = "{msgdir}";
@Override
public String getTaskName() {
return "verifyMessages";
}
@Override
public void execute(Scanner scanner) {
System.out.println("Check a specific file only?");
System.out.println("- Empty line will check all files in the resources messages folder (default)");
System.out.println(format("- %s will be replaced to the messages folder %s", SOURCES_TAG, MESSAGES_FOLDER));
String inputFile = scanner.nextLine();
System.out.println("Add any missing keys to files? ['y' = yes]");
boolean addMissingKeys = "y".equals(scanner.nextLine());
// Set up needed objects
Map<String, String> defaultMessages = null;
if (addMissingKeys) {
defaultMessages = constructDefaultMessages();
}
List<File> messageFiles;
if (StringUtils.isEmpty(inputFile)) {
messageFiles = getMessagesFiles();
} else {
File customFile = new File(inputFile.replace(SOURCES_TAG, MESSAGES_FOLDER));
messageFiles = Collections.singletonList(customFile);
}
// Verify the given files
for (File file : messageFiles) {
System.out.println("Verifying '" + file.getName() + "'");
MessageFileVerifier verifier = new MessageFileVerifier(file.getAbsolutePath());
if (addMissingKeys) {
verifyFileAndAddKeys(verifier, defaultMessages);
} else {
verifyFile(verifier);
}
}
if (messageFiles.size() > 1) {
System.out.println("Checked " + messageFiles.size() + " files");
}
}
private static void verifyFile(MessageFileVerifier verifier) {
Map<String, Boolean> missingKeys = verifier.getMissingKeys();
if (!missingKeys.isEmpty()) {
System.out.println(" Missing keys: " + missingKeys.keySet());
}
Set<String> unknownKeys = verifier.getUnknownKeys();
if (!unknownKeys.isEmpty()) {
System.out.println(" Unknown keys: " + unknownKeys);
}
}
private static void verifyFileAndAddKeys(MessageFileVerifier verifier, Map<String, String> defaultMessages) {
Map<String, Boolean> missingKeys = verifier.getMissingKeys();
if (!missingKeys.isEmpty()) {
verifier.addMissingKeys(defaultMessages);
missingKeys = verifier.getMissingKeys();
List<String> addedKeys = getKeysWithValue(Boolean.TRUE, missingKeys);
System.out.println(" Added missing keys " + addedKeys);
List<String> unsuccessfulKeys = getKeysWithValue(Boolean.FALSE, missingKeys);
if (!unsuccessfulKeys.isEmpty()) {
System.out.println(" Warning! Could not add all missing keys (problem with loading " +
"default messages?)");
System.out.println(" Could not add keys " + unsuccessfulKeys);
}
}
Set<String> unknownKeys = verifier.getUnknownKeys();
if (!unknownKeys.isEmpty()) {
System.out.println(" Unknown keys: " + unknownKeys);
}
}
private static Map<String, String> constructDefaultMessages() {
String defaultMessagesFile = MESSAGES_FOLDER + "messages_en.yml";
List<String> lines = FileUtils.readLinesFromFile(defaultMessagesFile);
Map<String, String> messages = new HashMap<>(lines.size());
for (String line : lines) {
if (line.startsWith("#") || line.trim().isEmpty()) {
continue;
}
if (line.indexOf(':') == -1 || line.indexOf(':') == line.length() - 1) {
System.out.println("Warning! Unknown format in default messages file for line '" + line + "'");
} else {
String key = line.substring(0, line.indexOf(':'));
messages.put(key, line.substring(line.indexOf(':') + 1));
}
}
return messages;
}
private static <K, V> List<K> getKeysWithValue(V value, Map<K, V> map) {
List<K> result = new ArrayList<>();
for (Map.Entry<K, V> entry : map.entrySet()) {
if (value.equals(entry.getValue())) {
result.add(entry.getKey());
}
}
return result;
}
private static List<File> getMessagesFiles() {
File folder = new File(MESSAGES_FOLDER);
File[] files = folder.listFiles();
if (files == null) {
throw new RuntimeException("Could not read files from folder '" + folder.getName() + "'");
}
List<File> messageFiles = new ArrayList<>();
for (File file : files) {
if (MESSAGE_FILE_PATTERN.matcher(file.getName()).matches()) {
messageFiles.add(file);
}
}
if (messageFiles.isEmpty()) {
throw new RuntimeException("Error getting message files: list of files is empty");
}
return messageFiles;
}
}

View File

@ -3,12 +3,9 @@ package permissions;
import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.util.StringUtils;
import utils.FileUtils;
import utils.ToolsConstants;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
@ -23,10 +20,6 @@ import java.util.regex.Pattern;
*/
public class PermissionNodesGatherer {
/** The folder in which the implementations of {@link PermissionNode} reside. */
private static final String PERMISSION_NODE_SOURCE_FOLDER =
"src/main/java/fr/xephi/authme/permission/";
/**
* Regular expression that should match the JavaDoc comment above an enum, <i>including</i>
* the name of the enum value. The first group (i.e. {@code \\1}) should be the JavaDoc description;
@ -100,14 +93,8 @@ public class PermissionNodesGatherer {
* @return Source code of the file
*/
private static <T extends Enum<T> & PermissionNode> String getSourceForClass(Class<T> clazz) {
String classFile = PERMISSION_NODE_SOURCE_FOLDER + clazz.getSimpleName() + ".java";
Charset cs = Charset.forName("utf-8");
try {
return StringUtils.join("\n",
Files.readAllLines(Paths.get(classFile), cs));
} catch (IOException e) {
throw new RuntimeException("Failed to get the source for class '" + clazz.getSimpleName() + "'");
}
String classFile = ToolsConstants.MAIN_SOURCE_ROOT + clazz.getName().replace(".", "/") + ".java";
return FileUtils.readFromFile(classFile);
}
}

View File

@ -1,8 +1,9 @@
package permissions;
import utils.ANewMap;
import utils.GeneratedFileWriter;
import utils.FileUtils;
import utils.TagReplacer;
import utils.ToolTask;
import utils.ToolsConstants;
import java.util.Map;
@ -10,42 +11,44 @@ import java.util.Scanner;
import java.util.Set;
/**
* Class responsible for formatting a permissions node list and
* Task responsible for formatting a permissions node list and
* for writing it to a file if desired.
*/
public class PermissionsListWriter {
public class PermissionsListWriter implements ToolTask {
private static final String PERMISSIONS_OUTPUT_FILE = ToolsConstants.DOCS_FOLDER + "permission_nodes.md";
public static void main(String[] args) {
@Override
public String getTaskName() {
return "writePermissionsList";
}
@Override
public void execute(Scanner scanner) {
// Ask if result should be written to file
Scanner scanner = new Scanner(System.in);
System.out.println("Include description? [Enter 'n' for no]");
boolean includeDescription = !matches("n", scanner);
if (!includeDescription) {
outputSimpleList();
return;
boolean writeToFile = false;
if (includeDescription) {
System.out.println("Write to file? [Enter 'y' for yes]");
writeToFile = matches("y", scanner);
}
System.out.println("Write to file? [Enter 'n' for console output]");
boolean writeToFile = !matches("n", scanner);
scanner.close();
if (writeToFile) {
if (!includeDescription) {
outputSimpleList();
} else if (writeToFile) {
generateAndWriteFile();
} else {
System.out.println(generatePermissionsList());
}
}
private static void generateAndWriteFile() {
final String permissionsTagValue = generatePermissionsList();
Map<String, Object> tags = ANewMap.<String, Object>with("permissions", permissionsTagValue).build();
GeneratedFileWriter.generateFileFromTemplate(
FileUtils.generateFileFromTemplate(
ToolsConstants.TOOLS_SOURCE_ROOT + "permissions/permission_nodes.tpl.md", PERMISSIONS_OUTPUT_FILE, tags);
System.out.println("Wrote to '" + PERMISSIONS_OUTPUT_FILE + "'");
System.out.println("Before committing, please verify the output!");
@ -55,7 +58,7 @@ public class PermissionsListWriter {
PermissionNodesGatherer gatherer = new PermissionNodesGatherer();
Map<String, String> permissions = gatherer.gatherNodesWithJavaDoc();
final String template = GeneratedFileWriter.readFromToolsFile("permissions/permission_node_entry.tpl.md");
final String template = FileUtils.readFromToolsFile("permissions/permission_node_entry.tpl.md");
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : permissions.entrySet()) {

View File

@ -0,0 +1,11 @@
#!/bin/sh
#
# Usage: ./analyze_project.sh
#
if [ -z $jarfile ];
then
./setvars.sh
fi
mvn clean verify sonar:sonar -f $pomfile

View File

@ -0,0 +1,11 @@
#!/bin/sh
#
# Usage: ./build_project.sh
#
if [ -z $jarfile ];
then
./setvars.sh
fi
mvn clean install -f $pomfile -B

View File

@ -0,0 +1,2 @@
#!/bin/sh
ls -aB *.sh

View File

@ -0,0 +1,16 @@
#!/bin/sh
#
# Usage: ./move_plugin.sh
#
if [ -z $jarfile ];
then
./setvars.sh
fi
if [ -f $jarfile ]
then
cp $jarfile $plugins
else
echo "Target file not found: $jarfile"
fi

View File

@ -0,0 +1,11 @@
#!/bin/sh
#
# Usage: ./analyze_project.sh
#
if [ -z $jarfile ];
then
./setvars.sh
fi
mvn install -f $pomfile -Dmaven.test.skip

View File

@ -0,0 +1,11 @@
#!/bin/sh
if [ -z $jarfile ]
then
./setvars.sh
fi
cd $server
java -Xmx1024M -Xms1024M -jar spigot_server.jar
cd $batdir
./list_files.sh

View File

@ -0,0 +1,16 @@
#!/bin/sh
#The folder in which these .sh files are located
EXPORT batdir=/home/yourhome/IdeaProjects/AuthMeReloaded/src/tools/shhelpers/
#The location of the generated JAR file
EXPORT jarfile=/home/yourhome/IdeaProjects/AuthMeReloaded/target/AuthMe-5.2-SNAPSHOT.jar
#The location of the pom.xml file of the project
EXPORT pomfile=/home/yourhome/IdeaProjects/AuthMeReloaded/pom.xml
#The folder in which the server is located
EXPORT server=/home/yourhome/AUTHME_DEV/spigot-server/
#The Location of the plugins folder of the Minecraft server
EXPORT plugins=$server/plugins/

View File

@ -0,0 +1,6 @@
#!/bin/sh
#
# That script sort the content of all files in the current directory
#
ls | grep -v .sort | while read file; do sort "$file" > "$file".sort; done
for file in *.sort; do mv "$file" "${file%%.sort}"; done

View File

@ -4,16 +4,18 @@ import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.Map;
/**
* Utility class for writing a generated file with a timestamp.
* Utility class for reading from and writing to files.
*/
public final class GeneratedFileWriter {
public final class FileUtils {
private final static Charset CHARSET = Charset.forName("utf-8");
private GeneratedFileWriter() {
private FileUtils() {
}
public static void generateFileFromTemplate(String templateFile, String destinationFile, Map<String, Object> tags) {
@ -31,6 +33,14 @@ public final class GeneratedFileWriter {
}
}
public static void appendToFile(String outputFile, String contents) {
try {
Files.write(Paths.get(outputFile), contents.getBytes(), StandardOpenOption.APPEND);
} catch (IOException e) {
throw new RuntimeException("Failed to append to file '" + outputFile + "'", e);
}
}
public static String readFromFile(String file) {
try {
return new String(Files.readAllBytes(Paths.get(file)), CHARSET);
@ -39,9 +49,16 @@ public final class GeneratedFileWriter {
}
}
public static List<String> readLinesFromFile(String file) {
try {
return Files.readAllLines(Paths.get(file), CHARSET);
} catch (IOException e) {
throw new RuntimeException("Could not read from file '" + file + "'", e);
}
}
public static String readFromToolsFile(String file) {
return readFromFile(ToolsConstants.TOOLS_SOURCE_ROOT + file);
}
}

View File

@ -0,0 +1,25 @@
package utils;
import java.util.Scanner;
/**
* Common interface for tool tasks. Note that the implementing tasks are instantiated
* with the default constructor. It is required that it be public.
*/
public interface ToolTask {
/**
* Return the name of the task.
*
* @return Name of the task
*/
String getTaskName();
/**
* Execute the task.
*
* @param scanner Scanner to prompt the user with for options. Do not close it.
*/
void execute(Scanner scanner);
}

View File

@ -10,6 +10,8 @@ public final class ToolsConstants {
public static final String MAIN_SOURCE_ROOT = "src/main/java/";
public static final String MAIN_RESOURCES_ROOT = "src/main/resources/";
public static final String TOOLS_SOURCE_ROOT = "src/tools/";
public static final String DOCS_FOLDER = TOOLS_SOURCE_ROOT + "docs/";