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

This commit is contained in:
ljacqu 2015-12-28 13:33:18 +01:00
commit 6ac1967364
33 changed files with 112 additions and 160 deletions

View File

@ -15,6 +15,8 @@
- Build status (CircleCI): [![Circle CI](https://circleci.com/gh/Xephi/AuthMeReloaded.svg?style=svg)](https://circleci.com/gh/Xephi/AuthMeReloaded)
- Code Coverage: [![Coverage Status](https://coveralls.io/repos/AuthMe-Team/AuthMeReloaded/badge.svg?branch=master&service=github)](https://coveralls.io/github/AuthMe-Team/AuthMeReloaded?branch=master)
- Issue Tracking : [![Stories in Ready](https://badge.waffle.io/Xephi/AuthMeReloaded.png?label=ready&title=Ready)](https://waffle.io/Xephi/AuthMeReloaded) [![Stories in Bugs](https://badge.waffle.io/Xephi/AuthMeReloaded.png?label=bugs&title=Bugs)](https://waffle.io/Xephi/AuthMeReloaded) [![Stories in In%20Progress](https://badge.waffle.io/Xephi/AuthMeReloaded.png?label=in%20progress&title=In%20Progress)](https://waffle.io/Xephi/AuthMeReloaded)
- Build Server (<strong>DEVELOPMENT BUILDS</strong>): <a href="http://ci.xephi.fr/job/AuthMeReloaded">Xephi's Jenkins</a>

View File

@ -111,7 +111,6 @@ permissions:
authme.admin.accounts: true
authme.admin.getemail: true
authme.admin.getip: true
authme.admin.resetposition: true
authme.admin.setspawn: true
authme.admin.spawn: true
authme.admin.setfirstspawn: true
@ -156,9 +155,6 @@ permissions:
authme.admin.getip:
description: Get IP from a player (fake and real)
default: false
authme.admin.resetposition:
description: Reset last position for a player
default: false
authme.admin.setspawn:
description: Set the AuthMe spawn point
default: false
@ -181,7 +177,7 @@ permissions:
description: Purge banned players
default: false
authme.admin.purgelastpos:
description: Purge last pos of players
description: Purge last position of a player/players
default: false
authme.admin.converter:
description: Allow the /authme converter command

View File

@ -40,6 +40,8 @@ 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.security.HashAlgorithm;
import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.OtherAccounts;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.Spawn;
@ -578,13 +580,26 @@ public class AuthMe extends JavaPlugin {
if (Settings.getDataSource == DataSource.DataSourceType.FILE) {
ConsoleLogger.showError("FlatFile backend has been detected and is now deprecated, it will be changed to SQLite... Connection will be impossible until conversion is done!");
ForceFlatToSqlite converter = new ForceFlatToSqlite(database, this);
ForceFlatToSqlite converter = new ForceFlatToSqlite(database);
DataSource source = converter.run();
if (source != null) {
database = source;
}
}
// TODO: Move this to another place maybe ?
if (Settings.getPasswordHash == HashAlgorithm.PLAINTEXT)
{
ConsoleLogger.showError("Your HashAlgorithm has been detected has plaintext and is now deprecrated, it will be changed and hashed now to AuthMe default hashing method");
for (PlayerAuth auth : database.getAllAuths())
{
auth.setHash(PasswordSecurity.getHash(HashAlgorithm.SHA256, auth.getHash(), auth.getNickname()));
database.updatePassword(auth);
}
Settings.setValue("settings.security.passwordHash", "SHA256");
Settings.reload();
}
if (Settings.isCachingEnabled) {
database = new CacheDataSource(database);
}

View File

@ -222,8 +222,8 @@ public final class CommandInitializer {
.labels("resetpos", "purgelastposition", "purgelastpos", "resetposition",
"resetlastposition", "resetlastpos")
.description("Purge player's last position")
.detailedDescription("Purge the last know position of the specified player.")
.withArgument("player", "Player name", false)
.detailedDescription("Purge the last know position of the specified player or all of them.")
.withArgument("player/*", "Player name or * for all players", false)
.permissions(OP_ONLY, AdminPermission.PURGE_LAST_POSITION)
.executableCommand(new PurgeLastPositionCommand())
.build();

View File

@ -15,6 +15,21 @@ public class PurgeLastPositionCommand implements ExecutableCommand {
String playerName = arguments.isEmpty() ? sender.getName() : arguments.get(0);
String playerNameLowerCase = playerName.toLowerCase();
if (playerNameLowerCase.equalsIgnoreCase("*"))
{
for (PlayerAuth auth : commandService.getDataSource().getAllAuths())
{
// Set the last position
auth.setQuitLocX(0D);
auth.setQuitLocY(0D);
auth.setQuitLocZ(0D);
auth.setWorld("world");
commandService.getDataSource().updateQuitLoc(auth);
}
sender.sendMessage("All players last position locations are now reset");
}
else
{
// Get the user auth and make sure the user exists
PlayerAuth auth = commandService.getDataSource().getAuth(playerNameLowerCase);
if (auth == null) {
@ -32,4 +47,6 @@ public class PurgeLastPositionCommand implements ExecutableCommand {
// Show a status message
sender.sendMessage(playerNameLowerCase + "'s last position location is now reset");
}
}
}

View File

@ -14,13 +14,11 @@ import java.io.IOException;
/**
* @author Xephi59
* @version $Revision: 1.0 $
*/
public class CrazyLoginConverter implements Converter {
public final AuthMe instance;
public final DataSource database;
public final CommandSender sender;
private final DataSource database;
private final CommandSender sender;
/**
* Constructor for CrazyLoginConverter.
@ -29,7 +27,6 @@ public class CrazyLoginConverter implements Converter {
* @param sender CommandSender
*/
public CrazyLoginConverter(AuthMe instance, CommandSender sender) {
this.instance = instance;
this.database = instance.database;
this.sender = sender;
}

View File

@ -1,6 +1,5 @@
package fr.xephi.authme.converter;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
@ -13,21 +12,10 @@ public class ForceFlatToSqlite {
private final DataSource data;
/**
* Constructor for ForceFlatToSqlite.
*
* @param data DataSource
* @param plugin AuthMe
*/
public ForceFlatToSqlite(DataSource data, AuthMe plugin) {
public ForceFlatToSqlite(DataSource data) {
this.data = data;
}
/**
* Method run.
*
* @see java.lang.Runnable#run()
*/
public DataSource run() {
DataSource sqlite = null;
try {
@ -39,7 +27,7 @@ public class ForceFlatToSqlite {
Settings.setValue("DataSource.backend", "sqlite");
ConsoleLogger.info("Database successfully converted to sqlite !");
} catch (Exception e) {
ConsoleLogger.showError("An error occured while trying to convert flatfile to sqlite ...");
ConsoleLogger.showError("An error occurred while trying to convert flatfile to sqlite ...");
return null;
}
return sqlite;

View File

@ -19,7 +19,6 @@ import java.util.Map.Entry;
/**
* @author Xephi59
* @version $Revision: 1.0 $
*/
public class RakamakConverter implements Converter {
@ -27,32 +26,16 @@ public class RakamakConverter implements Converter {
public final DataSource database;
public final CommandSender sender;
/**
* Constructor for RakamakConverter.
*
* @param instance AuthMe
* @param sender CommandSender
*/
public RakamakConverter(AuthMe instance, CommandSender sender) {
this.instance = instance;
this.database = instance.database;
this.sender = sender;
}
/**
* Method getInstance.
*
* @return RakamakConverter
*/
public RakamakConverter getInstance() {
return this;
}
/**
* Method run.
*
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
HashAlgorithm hash = Settings.getPasswordHash;

View File

@ -8,28 +8,16 @@ import org.bukkit.OfflinePlayer;
import java.io.File;
/**
*/
public class RoyalAuthConverter implements Converter {
public final AuthMe plugin;
private final AuthMe plugin;
private final DataSource data;
/**
* Constructor for RoyalAuthConverter.
*
* @param plugin AuthMe
*/
public RoyalAuthConverter(AuthMe plugin) {
this.plugin = plugin;
this.data = plugin.database;
}
/**
* Method run.
*
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
for (OfflinePlayer o : plugin.getServer().getOfflinePlayers()) {

View File

@ -4,35 +4,18 @@ import fr.xephi.authme.settings.CustomConfiguration;
import java.io.File;
/**
*/
public class RoyalAuthYamlReader extends CustomConfiguration {
class RoyalAuthYamlReader extends CustomConfiguration {
/**
* Constructor for RoyalAuthYamlReader.
*
* @param file File
*/
public RoyalAuthYamlReader(File file) {
super(file);
load();
save();
}
/**
* Method getLastLogin.
*
* @return long
*/
public long getLastLogin() {
return getLong("timestamps.quit");
}
/**
* Method getHash.
*
* @return String
*/
public String getHash() {
return getString("login.password");
}

View File

@ -2,38 +2,22 @@ package fr.xephi.authme.converter;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.datasource.DataSource;
import org.bukkit.command.CommandSender;
/**
*/
public class vAuthConverter implements Converter {
public final AuthMe plugin;
public final DataSource database;
public final CommandSender sender;
private final AuthMe plugin;
private final CommandSender sender;
/**
* Constructor for vAuthConverter.
*
* @param plugin AuthMe
* @param sender CommandSender
*/
public vAuthConverter(AuthMe plugin, CommandSender sender) {
this.plugin = plugin;
this.database = plugin.database;
this.sender = sender;
}
/**
* Method run.
*
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
try {
new vAuthFileReader(plugin, sender).convert();
new vAuthFileReader(plugin).convert();
} catch (Exception e) {
sender.sendMessage(e.getMessage());
ConsoleLogger.showError(e.getMessage());

View File

@ -6,30 +6,24 @@ import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import java.io.File;
import java.util.Scanner;
import java.util.UUID;
/**
*/
public class vAuthFileReader {
class vAuthFileReader {
public final AuthMe plugin;
public final DataSource database;
public final CommandSender sender;
private final AuthMe plugin;
private final DataSource database;
/**
* Constructor for vAuthFileReader.
*
* @param plugin AuthMe
* @param sender CommandSender
*/
public vAuthFileReader(AuthMe plugin, CommandSender sender) {
public vAuthFileReader(AuthMe plugin) {
this.plugin = plugin;
this.database = plugin.database;
this.sender = sender;
}
public void convert() {
@ -68,13 +62,6 @@ public class vAuthFileReader {
return s.length() > 8 && s.charAt(8) == '-';
}
/**
* Method getName.
*
* @param uuid UUID
*
* @return String
*/
private String getName(UUID uuid) {
try {
for (OfflinePlayer op : Bukkit.getOfflinePlayers()) {

View File

@ -5,8 +5,8 @@ import org.bukkit.command.CommandSender;
public class xAuthConverter implements Converter {
public final AuthMe plugin;
public final CommandSender sender;
private final AuthMe plugin;
private final CommandSender sender;
public xAuthConverter(AuthMe plugin, CommandSender sender) {
this.plugin = plugin;

View File

@ -16,11 +16,11 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class xAuthToFlat {
class xAuthToFlat {
public final AuthMe instance;
public final DataSource database;
public final CommandSender sender;
private final AuthMe instance;
private final DataSource database;
private final CommandSender sender;
/**
* Constructor for xAuthToFlat.
@ -57,14 +57,14 @@ public class xAuthToFlat {
database.saveAuth(auth);
}
}
sender.sendMessage("[AuthMe] Successfully convert from xAuth database");
sender.sendMessage("[AuthMe] Successfully converted from xAuth database");
} catch (Exception e) {
sender.sendMessage("[AuthMe] An error has been thrown while import xAuth database, the import hadn't fail but can be not complete ");
}
return true;
}
public String getIdPlayer(int id) {
private String getIdPlayer(int id) {
String realPass = "";
Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
PreparedStatement ps = null;
@ -86,7 +86,7 @@ public class xAuthToFlat {
return realPass;
}
public List<Integer> getXAuthPlayers() {
private List<Integer> getXAuthPlayers() {
List<Integer> xP = new ArrayList<>();
Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
PreparedStatement ps = null;
@ -107,7 +107,7 @@ public class xAuthToFlat {
return xP;
}
public String getPassword(int accountId) {
private String getPassword(int accountId) {
String realPass = "";
Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
PreparedStatement ps = null;

View File

@ -70,8 +70,7 @@ public class BungeeCordMessage implements PluginMessageListener {
} else if ("register".equals(act)) {
ConsoleLogger.info("Player " + auth.getNickname()
+ " has registered out from one of your server!");
}
else if ("changepassword".equals(act)) {
} else if ("changepassword".equals(act)) {
final String password = args[2];
auth.setHash(password);
if (args.length == 4)

View File

@ -16,9 +16,15 @@ public class AuthMeServerStop extends Thread {
public void run() {
// TODO: add a MessageKey
if (Settings.kickPlayersBeforeStopping) {
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable()
{
@Override
public void run() {
for (Player p : plugin.getServer().getOnlinePlayers()) {
p.kickPlayer("Server is restarting");
}
}
});
}
}
}

View File

@ -85,7 +85,7 @@ public enum MessageKey {
FORGOT_PASSWORD_MESSAGE("recovery_email"),
USAGE_CAPTCHA("usage_captcha"),
USAGE_CAPTCHA("usage_captcha", "<theCaptcha>"),
CAPTCHA_WRONG_ERROR("wrong_captcha", "THE_CAPTCHA"),

View File

@ -80,8 +80,6 @@ public class AsyncChangeEmail {
return;
}
m.send(player, MessageKey.EMAIL_CHANGED_SUCCESS);
// TODO ljacqu 20151124: Did I really miss "email_defined" or is it not present in the 'en' messages?
// player.sendMessage(Arrays.toString(m.send("email_defined")) + auth.getEmail());
} else {
if (plugin.database.isAuthAvailable(playerName)) {
m.send(player, MessageKey.LOGIN_MESSAGE);

View File

@ -58,7 +58,7 @@ public class AsynchronousJoin {
}
final String ip = plugin.getIP(player);
if (Settings.isAllowRestrictedIp && !Settings.getRestrictedIp(name, ip)) {
if (Settings.isAllowRestrictedIp && !Settings.getRestrictedIp(name, ip, player.getAddress().getHostName())) {
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
@Override

View File

@ -13,6 +13,7 @@ public enum HashAlgorithm {
XAUTH(fr.xephi.authme.security.crypts.XAUTH.class),
MD5VB(fr.xephi.authme.security.crypts.MD5VB.class),
PHPBB(fr.xephi.authme.security.crypts.PHPBB.class),
@Deprecated
PLAINTEXT(fr.xephi.authme.security.crypts.PLAINTEXT.class),
MYBB(fr.xephi.authme.security.crypts.MYBB.class),
IPB3(fr.xephi.authme.security.crypts.IPB3.class),

View File

@ -385,7 +385,7 @@ public final class Settings {
*
* @return boolean
*/
public static boolean getRestrictedIp(String name, String ip) {
public static boolean getRestrictedIp(String name, String ip, String domain) {
Iterator<String> iterator = getRestrictedIp.iterator();
boolean trueOnce = false;
@ -396,10 +396,19 @@ public final class Settings {
String testIp = args[1];
if (testName.equalsIgnoreCase(name)) {
nameFound = true;
if (ip != null)
{
if (testIp.equalsIgnoreCase(ip)) {
trueOnce = true;
}
}
if (domain != null)
{
if (testIp.equalsIgnoreCase(domain)) {
trueOnce = true;
}
}
}
}
return !nameFound || trueOnce;
}

View File

@ -181,7 +181,6 @@ settings:
# Example unLoggedinGroup: NotLogged
unLoggedinGroup: unLoggedinGroup
# possible values: MD5, SHA1, SHA256, WHIRLPOOL, XAUTH, MD5VB, PHPBB,
# PLAINTEXT ( unhashed password),
# MYBB, IPB3, PHPFUSION, SMF, XENFORO, SALTED2MD5, JOOMLA, BCRYPT, WBB3, SHA512,
# DOUBLEMD5, PBKDF2, PBKDF2DJANGO, WORDPRESS, ROYALAUTH, CUSTOM(for developpers only)
passwordHash: SHA256

View File

@ -37,7 +37,7 @@ name_len: '&cТвоя никнейм е твърде малък или голя
regex: '&cТвоя никнейм съдържа забранени знацхи. Позволените са: REG_EX'
add_email: '&cМоля добави своя имейл с : /email add имейл имейл'
recovery_email: '&cЗабравихте своята парола? Моля използвай /email recovery <имейл>'
usage_captcha: '&cYou need to type a captcha, please type: /captcha <код>'
usage_captcha: '&cYou need to type a captcha, please type: /captcha <theCaptcha>'
wrong_captcha: '&cГрешен код, използвай : /captcha THE_CAPTCHA'
valid_captcha: '&cТвоя код е валиден!'
kick_forvip: '&cVIP влезе докато сървъра е пълен, ти беше изгонен!'

View File

@ -37,7 +37,7 @@ name_len: '&cTvuj nick je prilis kratky, nebo prilis dlouhy'
regex: '&cTvuj nick obsahuje nepovolene znaky. Pripustne znaky jsou: REG_EX'
add_email: '&cPridej prosim svuj email pomoci : /email add TvujEmail TvujEmail'
recovery_email: '&cZapomel jsi heslo? Zadej: /email recovery <TvujEmail>'
usage_captcha: '&cPouzij: /captcha <Captcha_text>'
usage_captcha: '&cPouzij: /captcha <theCaptcha>'
wrong_captcha: '&cSpatne opsana Captcha, pouzij prosim: /captcha THE_CAPTCHA'
valid_captcha: '&cZadana captcha je v poradku!'
kick_forvip: '&cVIP Hrac se pripojil na plny server!'

View File

@ -38,7 +38,7 @@ name_len: '&cTu nombre de usuario es muy largo o muy corto'
regex: '&cTu usuario tiene carácteres no admitidos, los cuales son: REG_EX'
add_email: '&cPor favor agrega tu e-mail con: /email add tuEmail confirmarEmail'
recovery_email: '&c¿Olvidaste tu contraseña? Por favor usa /email recovery <tuEmail>'
usage_captcha: '&cUso: /captcha <elCaptcha>'
usage_captcha: '&cUso: /captcha <theCaptcha>'
wrong_captcha: '&cCaptcha incorrecto, please use : /captcha THE_CAPTCHA'
valid_captcha: '&c¡ Captcha ingresado correctamente !'
kick_forvip: '&cUn jugador VIP ha ingresado al servidor lleno!'

View File

@ -37,7 +37,7 @@ name_len: '&cPelaajanimesi on liian lyhyt tai pitkä'
regex: '&cPelaajanimesi sisältää luvattomia merkkejä. Hyväksytyt merkit: REG_EX'
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>'
usage_captcha: '&cKäyttötapa: /captcha <theCaptcha>'
wrong_captcha: '&cVäärä varmistus, käytä : /captcha THE_CAPTCHA'
valid_captcha: '&cSinun varmistus onnistui.!'
kick_forvip: '&cVIP pelaaja liittyi täyteen palvelimeen!'

View File

@ -38,7 +38,7 @@ name_len: '&cVotre pseudo est trop long ou trop court'
regex: '&cCaractères autorisés: REG_EX'
add_email: '&cMerci d''ajouter votre email : /email add yourEmail confirmEmail'
recovery_email: '&cVous avez oublié votre MotdePasse? Utilisez /email recovery <yourEmail>'
usage_captcha: '&cTrop de tentatives de connexion échouées, utilisez: /captcha <leCaptcha>'
usage_captcha: '&cTrop de tentatives de connexion échouées, utilisez: /captcha <theCaptcha>'
wrong_captcha: '&cCaptcha incorrect, écrivez de nouveau : /captcha THE_CAPTCHA'
valid_captcha: '&cLe Captcha est valide, merci!'
kick_forvip: '&cUn joueur VIP a rejoint le serveur plein!'

View File

@ -37,7 +37,7 @@ name_len: '&cO teu nome é demasiado curto ou demasiado longo'
regex: '&cO teu nome contén caracteres ilegais. Caracteres permitidos: REG_EX'
add_email: '&cPor favor, engade o teu correo electrónico con: /email add <oTeuCorreo> <confirmarCorreo>'
recovery_email: '&cOlvidaches o contrasinal? Por favor, usa /email recovery <oTeuCorreo>'
usage_captcha: '&cNecesitas escribir un captcha, por favor escribe: /captcha <oCaptcha>'
usage_captcha: '&cNecesitas escribir un captcha, por favor escribe: /captcha <theCaptcha>'
wrong_captcha: '&cCaptcha equivocado, por favor usa: /captcha THE_CAPTCHA'
valid_captcha: '&cO teu captcha é válido !'
kick_forvip: '&cUn xogador VIP uniuse ao servidor cheo!'

View File

@ -37,7 +37,7 @@ name_len: '&cIl tuo nome utente è troppo corto o troppo lungo!'
regex: '&cIl tuo nome utente contiene caratteri non consentiti. I caratteri consentiti sono: REG_EX'
add_email: '&cPer poter recuperare la password in futuro, aggiungi un indirizzo email al tuo account con il comando: "/email add <tuaEmail> <confermaEmail>"'
recovery_email: '&cHai dimenticato la tua password? Puoi recuperarla eseguendo il comando: "/email recovery <tuaEmail>"'
usage_captcha: '&cAbbiamo bisogno che tu inserisca un captcha, perfavore scrivi: "/captcha THE_CAPTCHA"'
usage_captcha: '&cAbbiamo bisogno che tu inserisca un captcha, perfavore scrivi: "/captcha <theCaptcha>"'
wrong_captcha: '&cCaptcha sbagliato, perfavore riprova con il comando: "/captcha THE_CAPTCHA"'
valid_captcha: '&cIl captcha inserito è valido!'
kick_forvip: '&cUn utente VIP è entrato mentre il server era pieno e ha preso il tuo posto!'

View File

@ -36,7 +36,7 @@ name_len: '&cJe gebruikersnaam is te kort'
regex: '&cJouw gebruikersnaam bevat illegale tekens. Toegestaane karakters: REG_EX'
add_email: '&cVoeg uw E-mail alstublieft toe met: /email add <E-mail> <wachtwoord> <herhaalWachtwoord>'
recovery_email: '&cWachtwoord vergeten? Gebruik alstublieft "/email recovery <E-mail>"'
usage_captcha: '&cGebruik: /captcha <captcha>'
usage_captcha: '&cGebruik: /captcha <theCaptcha>'
wrong_captcha: '&cVerkeerde Captcha, gebruik alstublieft: /captcha THE_CAPTCHA'
valid_captcha: '&cDe captcha is geldig!'
kick_forvip: '&cEen VIP Gebruiker ga naar de volledige server!'

View File

@ -37,7 +37,7 @@ name_len: '&cTwoje konto ma za dluga badz za krotka nazwe'
regex: '&cTwoje konto ma w nazwie niedozwolone znaki. Dozwolone znaki: REG_EX'
add_email: '&cProsze dodac swoj email: /email add twojEmail powtorzEmail'
recovery_email: '&cZapomniales hasla? Prosze uzyj komendy /email recovery <TwojEmail>'
usage_captcha: '&cWpisz: /captcha <kod>'
usage_captcha: '&cWpisz: /captcha <theCaptcha>'
wrong_captcha: '&cZly kod, prosze wpisac: /captcha THE_CAPTCHA'
valid_captcha: '&cTwoj kod jest nieprawidlowy!'
kick_forvip: '&cA Gracz VIP dolaczyl do gry!'

View File

@ -35,7 +35,7 @@ name_len: '&cTên đăng nhập của bạn quá ngắn hoặc quá dài'
regex: '&cTên đăng nhập của bạn có chứa kí tự đặc biệt không được cho phép. Các kí tự hợp lệ: REG_EX'
add_email: '&cVui lòng thêm địa chỉ email cho tài khoản với lệnh: /email add email-của-bạn nhập-lại-email-của-bạn'
recovery_email: '&cQuên mật khẩu? Hãy dùng lệnh /email recovery <email-của-bạn>'
usage_captcha: '&cBạn cần nhập mã xác nhận: /captcha <mã-xác-nhận>'
usage_captcha: '&cBạn cần nhập mã xác nhận: /captcha <theCaptcha>'
wrong_captcha: '&cSai mã xác nhận, nhập lại: /captcha <mã-xác-nhận>'
valid_captcha: '&aMã xác nhận hợp lệ!'
kick_forvip: '&cNgười chơi VIP đã vào server hiện đang full!'

View File

@ -40,7 +40,7 @@ name_len: '&8[&6用戶系統&8] &c你的用戶名不符合規定長度。'
regex: '&8[&6用戶系統&8] &c用戶名稱錯誤 登入系統只接受以下字符: REG_EX'
add_email: '&8[&6用戶系統&8] &b請為你的帳戶立即添加電郵地址 《 /email add <電郵地址> <重覆電郵地址> 》'
recovery_email: '&8[&6用戶系統&8] &c忘記密碼 請使用這個指令來更新密碼: 《 /email recovery <電郵地址> 》'
usage_captcha: '&8[&6用戶系統&8] &f用法 《 /captcha <驗證碼> 》'
usage_captcha: '&8[&6用戶系統&8] &f用法 《 /captcha <theCaptcha> 》'
wrong_captcha: '&8[&6用戶系統&8] &c你所輸入的驗證碼無效請使用 《 /captcha <驗證碼> 》 再次輸入。'
valid_captcha: '&8[&6用戶系統&8] &c你所輸入的驗證碼無效 '
kick_forvip: '&c因為有VIP玩家登入了伺服器。'