Merge master into 477-lastlogin-timestamp
Conflicts:
- Settings.java
This commit is contained in:
@@ -61,6 +61,7 @@ import fr.xephi.authme.listener.AuthMePlayerListener16;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener18;
|
||||
import fr.xephi.authme.listener.AuthMeServerListener;
|
||||
import fr.xephi.authme.listener.AuthMeTabCompletePacketAdapter;
|
||||
import fr.xephi.authme.listener.AuthMeTablistPacketAdapter;
|
||||
import fr.xephi.authme.mail.SendMailSSL;
|
||||
import fr.xephi.authme.output.ConsoleFilter;
|
||||
import fr.xephi.authme.output.Log4JFilter;
|
||||
@@ -133,6 +134,7 @@ public class AuthMe extends JavaPlugin {
|
||||
public CombatTagPlus combatTagPlus;
|
||||
public AuthMeInventoryPacketAdapter inventoryProtector;
|
||||
public AuthMeTabCompletePacketAdapter tabComplete;
|
||||
public AuthMeTablistPacketAdapter tablistHider;
|
||||
|
||||
/*
|
||||
* Maps and stuff
|
||||
@@ -230,7 +232,7 @@ public class AuthMe extends JavaPlugin {
|
||||
return;
|
||||
}
|
||||
|
||||
messages = new Messages(newSettings.getMessagesFile());
|
||||
messages = new Messages(newSettings.getMessagesFile(), newSettings.getDefaultMessagesFile());
|
||||
|
||||
// Connect to the database and setup tables
|
||||
try {
|
||||
@@ -665,10 +667,14 @@ public class AuthMe extends JavaPlugin {
|
||||
inventoryProtector.unregister();
|
||||
inventoryProtector = null;
|
||||
}
|
||||
if (tabComplete == null) {
|
||||
if (tabComplete == null && newSettings.getProperty(RestrictionSettings.DENY_TABCOMPLETE_BEFORE_LOGIN)) {
|
||||
tabComplete = new AuthMeTabCompletePacketAdapter(this);
|
||||
tabComplete.register();
|
||||
}
|
||||
if (tablistHider == null && newSettings.getProperty(RestrictionSettings.HIDE_TABLIST_BEFORE_LOGIN)) {
|
||||
tablistHider = new AuthMeTablistPacketAdapter(this);
|
||||
tablistHider.register();
|
||||
}
|
||||
}
|
||||
|
||||
// Save Player Data
|
||||
|
||||
@@ -36,6 +36,7 @@ public class PerformBackup {
|
||||
* Constructor for PerformBackup.
|
||||
*
|
||||
* @param instance AuthMe
|
||||
* @param settings The plugin settings
|
||||
*/
|
||||
public PerformBackup(AuthMe instance, NewSetting settings) {
|
||||
this.dataFolder = instance.getDataFolder();
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
|
||||
/**
|
||||
* Common supertype for all AuthMe teleport events.
|
||||
*/
|
||||
public abstract class AbstractTeleportEvent extends CustomEvent implements Cancellable {
|
||||
|
||||
private final Player player;
|
||||
private final Location from;
|
||||
private Location to;
|
||||
private boolean isCancelled;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param isAsync Whether to fire the event asynchronously or not
|
||||
* @param player The player
|
||||
* @param from The location the player is being teleported away from
|
||||
* @param to The teleport destination
|
||||
*/
|
||||
public AbstractTeleportEvent(boolean isAsync, Player player, Location from, Location to) {
|
||||
super(isAsync);
|
||||
this.player = player;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor, using the player's current location as "from" location.
|
||||
*
|
||||
* @param isAsync Whether to fire the event asynchronously or not
|
||||
* @param player The player
|
||||
* @param to The teleport destination
|
||||
*/
|
||||
public AbstractTeleportEvent(boolean isAsync, Player player, Location to) {
|
||||
this(isAsync, player, player.getLocation(), to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the player planned to be teleported.
|
||||
*
|
||||
* @return The player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the location the player is being teleported away from.
|
||||
*
|
||||
* @return The location prior to the teleport
|
||||
*/
|
||||
public Location getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the destination of the teleport.
|
||||
*
|
||||
* @param to The location to teleport the player to
|
||||
*/
|
||||
public void setTo(Location to) {
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the destination the player is being teleported to.
|
||||
*
|
||||
* @return The teleport destination
|
||||
*/
|
||||
public Location getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean isCancelled) {
|
||||
this.isCancelled = isCancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return isCancelled;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -5,21 +5,19 @@ import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* This event is call when a player try to /login
|
||||
*
|
||||
* @author Xephi59
|
||||
* @version $Revision: 1.0 $
|
||||
* This event is called when a player uses the /login command with correct credentials.
|
||||
* {@link #setCanLogin(boolean) {@code event.setCanLogin(false)}} prevents the player from logging in.
|
||||
*/
|
||||
public class AuthMeAsyncPreLoginEvent extends Event {
|
||||
public class AuthMeAsyncPreLoginEvent extends CustomEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Player player;
|
||||
private boolean canLogin = true;
|
||||
|
||||
/**
|
||||
* Constructor for AuthMeAsyncPreLoginEvent.
|
||||
* Constructor.
|
||||
*
|
||||
* @param player Player
|
||||
* @param player The player
|
||||
*/
|
||||
public AuthMeAsyncPreLoginEvent(Player player) {
|
||||
super(true);
|
||||
@@ -27,37 +25,41 @@ public class AuthMeAsyncPreLoginEvent extends Event {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getPlayer.
|
||||
* Return the player concerned by this event.
|
||||
*
|
||||
* @return Player
|
||||
* @return The player who executed a valid {@code /login} command
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method canLogin.
|
||||
* Return whether the player is allowed to log in.
|
||||
*
|
||||
* @return boolean
|
||||
* @return True if the player can log in, false otherwise
|
||||
*/
|
||||
public boolean canLogin() {
|
||||
return canLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setCanLogin.
|
||||
* Define whether or not the player may log in.
|
||||
*
|
||||
* @param canLogin boolean
|
||||
* @param canLogin True to allow the player to log in; false to prevent him
|
||||
*/
|
||||
public void setCanLogin(boolean canLogin) {
|
||||
this.canLogin = canLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getHandlers.
|
||||
* Return the list of handlers, equivalent to {@link #getHandlers()} and required by {@link Event}.
|
||||
*
|
||||
* @return HandlerList
|
||||
* @return The list of handlers
|
||||
*/
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
|
||||
@@ -2,65 +2,38 @@ package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* This event is call when AuthMe try to teleport a player
|
||||
*
|
||||
* @author Xephi59
|
||||
* @version $Revision: 1.0 $
|
||||
* This event is fired before AuthMe teleports a player for general purposes.
|
||||
*/
|
||||
public class AuthMeTeleportEvent extends CustomEvent {
|
||||
public class AuthMeTeleportEvent extends AbstractTeleportEvent {
|
||||
|
||||
private final Player player;
|
||||
private Location to;
|
||||
private final Location from;
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
/**
|
||||
* Constructor for AuthMeTeleportEvent.
|
||||
* Constructor.
|
||||
*
|
||||
* @param player Player
|
||||
* @param to Location
|
||||
* @param player The player
|
||||
* @param to The teleport destination
|
||||
*/
|
||||
public AuthMeTeleportEvent(Player player, Location to) {
|
||||
this.player = player;
|
||||
this.from = player.getLocation();
|
||||
this.to = to;
|
||||
super(false, player, to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getPlayer.
|
||||
* Return the list of handlers, equivalent to {@link #getHandlers()} and required by {@link Event}.
|
||||
*
|
||||
* @return Player
|
||||
* @return The list of handlers
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getTo.
|
||||
*
|
||||
* @return Location
|
||||
*/
|
||||
public Location getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setTo.
|
||||
*
|
||||
* @param to Location
|
||||
*/
|
||||
public void setTo(Location to) {
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getFrom.
|
||||
*
|
||||
* @return Location
|
||||
*/
|
||||
public Location getFrom() {
|
||||
return from;
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,67 +1,27 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* @author Xephi59
|
||||
* @version $Revision: 1.0 $
|
||||
* The parent of all AuthMe events.
|
||||
*/
|
||||
public class CustomEvent extends Event implements Cancellable {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean isCancelled;
|
||||
public abstract class CustomEvent extends Event {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public CustomEvent() {
|
||||
super(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for CustomEvent.
|
||||
* Constructor, specifying whether the event is asynchronous or not.
|
||||
*
|
||||
* @param b boolean
|
||||
* @param isAsync {@code true} to fire the event asynchronously, false otherwise
|
||||
* @see Event#Event(boolean)
|
||||
*/
|
||||
public CustomEvent(boolean b) {
|
||||
super(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getHandlerList.
|
||||
*
|
||||
* @return HandlerList
|
||||
*/
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getHandlers.
|
||||
*
|
||||
* @return HandlerList
|
||||
*/
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method isCancelled.
|
||||
*
|
||||
* @return boolean * @see org.bukkit.event.Cancellable#isCancelled()
|
||||
*/
|
||||
public boolean isCancelled() {
|
||||
return this.isCancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setCancelled.
|
||||
*
|
||||
* @param cancelled boolean
|
||||
*
|
||||
* @see org.bukkit.event.Cancellable#setCancelled(boolean)
|
||||
*/
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.isCancelled = cancelled;
|
||||
public CustomEvent(boolean isAsync) {
|
||||
super(isAsync);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,67 +2,40 @@ package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called if a player is teleported to the authme first spawn
|
||||
*
|
||||
* @author Xephi59
|
||||
* @version $Revision: 1.0 $
|
||||
* Event that is called if a player is teleported to the AuthMe first spawn, i.e. to the
|
||||
* spawn location for players who have never played before.
|
||||
*/
|
||||
public class FirstSpawnTeleportEvent extends CustomEvent {
|
||||
public class FirstSpawnTeleportEvent extends AbstractTeleportEvent {
|
||||
|
||||
private final Player player;
|
||||
private Location to;
|
||||
private final Location from;
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
/**
|
||||
* Constructor for FirstSpawnTeleportEvent.
|
||||
* Constructor.
|
||||
*
|
||||
* @param player Player
|
||||
* @param from Location
|
||||
* @param to Location
|
||||
* @param player The player
|
||||
* @param from The location the player is being teleported away from
|
||||
* @param to The teleport destination
|
||||
*/
|
||||
public FirstSpawnTeleportEvent(Player player, Location from, Location to) {
|
||||
super(true);
|
||||
this.player = player;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
super(true, player, from, to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getPlayer.
|
||||
* Return the list of handlers, equivalent to {@link #getHandlers()} and required by {@link Event}.
|
||||
*
|
||||
* @return Player
|
||||
* @return The list of handlers
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getTo.
|
||||
*
|
||||
* @return Location
|
||||
*/
|
||||
public Location getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setTo.
|
||||
*
|
||||
* @param to Location
|
||||
*/
|
||||
public void setTo(Location to) {
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getFrom.
|
||||
*
|
||||
* @return Location
|
||||
*/
|
||||
public Location getFrom() {
|
||||
return from;
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,80 +5,40 @@ import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* This event is called when a player login or register through AuthMe. The
|
||||
* boolean 'isLogin' will be false if, and only if, login/register failed.
|
||||
*
|
||||
* @author Xephi59
|
||||
* @version $Revision: 1.0 $
|
||||
* Event fired when a player has successfully logged in or registered.
|
||||
*/
|
||||
public class LoginEvent extends Event {
|
||||
public class LoginEvent extends CustomEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private Player player;
|
||||
private boolean isLogin;
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* Constructor for LoginEvent.
|
||||
* Constructor.
|
||||
*
|
||||
* @param player Player
|
||||
* @param isLogin boolean
|
||||
* @param player The player
|
||||
*/
|
||||
public LoginEvent(Player player, boolean isLogin) {
|
||||
public LoginEvent(Player player) {
|
||||
this.player = player;
|
||||
this.isLogin = isLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getHandlerList.
|
||||
* Return the player that has successfully logged in or registered.
|
||||
*
|
||||
* @return HandlerList
|
||||
* @return The player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of handlers, equivalent to {@link #getHandlers()} and required by {@link Event}.
|
||||
*
|
||||
* @return The list of handlers
|
||||
*/
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getPlayer.
|
||||
*
|
||||
* @return Player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setPlayer.
|
||||
*
|
||||
* @param player Player
|
||||
*/
|
||||
public void setPlayer(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method isLogin.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isLogin() {
|
||||
return isLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setLogin.
|
||||
*
|
||||
* @param isLogin boolean
|
||||
*/
|
||||
@Deprecated
|
||||
public void setLogin(boolean isLogin) {
|
||||
this.isLogin = isLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getHandlers.
|
||||
*
|
||||
* @return HandlerList
|
||||
*/
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
|
||||
@@ -5,57 +5,42 @@ import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* This event is called when a player logout through AuthMe.
|
||||
*
|
||||
* @author Xephi59
|
||||
* @version $Revision: 1.0 $
|
||||
* This event is called when a player logs out through AuthMe, i.e. only when the player
|
||||
* has executed the {@code /logout} command. This event is not fired if a player simply
|
||||
* leaves the server.
|
||||
*/
|
||||
public class LogoutEvent extends Event {
|
||||
public class LogoutEvent extends CustomEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private Player player;
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* Constructor for LogoutEvent.
|
||||
* Constructor.
|
||||
*
|
||||
* @param player Player
|
||||
* @param player The player
|
||||
*/
|
||||
public LogoutEvent(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getHandlerList.
|
||||
* Return the player who logged out.
|
||||
*
|
||||
* @return HandlerList
|
||||
*/
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getPlayer.
|
||||
*
|
||||
* @return Player
|
||||
* @return The player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setPlayer.
|
||||
* Return the list of handlers, equivalent to {@link #getHandlers()} and required by {@link Event}.
|
||||
*
|
||||
* @param player Player
|
||||
* @return The list of handlers
|
||||
*/
|
||||
public void setPlayer(Player player) {
|
||||
this.player = player;
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getHandlers.
|
||||
*
|
||||
* @return HandlerList
|
||||
*/
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
|
||||
@@ -5,24 +5,33 @@ import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* This event is called when we need to compare or hash password and allows
|
||||
* This event is called when we need to compare or hash a password for a player and allows
|
||||
* third-party listeners to change the encryption method. This is typically
|
||||
* done with the {@link fr.xephi.authme.security.HashAlgorithm#CUSTOM} setting.
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class PasswordEncryptionEvent extends Event {
|
||||
public class PasswordEncryptionEvent extends CustomEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private EncryptionMethod method;
|
||||
private String playerName;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param method The method used to encrypt the password
|
||||
* @param playerName The name of the player
|
||||
*/
|
||||
public PasswordEncryptionEvent(EncryptionMethod method, String playerName) {
|
||||
super(false);
|
||||
this.method = method;
|
||||
this.playerName = playerName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of handlers, equivalent to {@link #getHandlers()} and required by {@link Event}.
|
||||
*
|
||||
* @return The list of handlers
|
||||
*/
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
@@ -32,14 +41,29 @@ public class PasswordEncryptionEvent extends Event {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the encryption method used to hash the password.
|
||||
*
|
||||
* @return The encryption method
|
||||
*/
|
||||
public EncryptionMethod getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the encryption method to hash the password with.
|
||||
*
|
||||
* @param method The encryption method to use
|
||||
*/
|
||||
public void setMethod(EncryptionMethod method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the player the event has been fired for.
|
||||
*
|
||||
* @return The player name
|
||||
*/
|
||||
public String getPlayerName() {
|
||||
return playerName;
|
||||
}
|
||||
|
||||
@@ -1,98 +1,84 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* This event is call just after store inventory into cache and will empty the
|
||||
* player inventory.
|
||||
*
|
||||
* @author Xephi59
|
||||
* @version $Revision: 1.0 $
|
||||
* This event is called before the inventory data of a player is suppressed,
|
||||
* i.e. the inventory of the player is not displayed until he has authenticated.
|
||||
*/
|
||||
public class ProtectInventoryEvent extends CustomEvent {
|
||||
public class ProtectInventoryEvent extends CustomEvent implements Cancellable {
|
||||
|
||||
private final ItemStack[] storedinventory;
|
||||
private final ItemStack[] storedarmor;
|
||||
private ItemStack[] emptyInventory = null;
|
||||
private ItemStack[] emptyArmor = null;
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final ItemStack[] storedInventory;
|
||||
private final ItemStack[] storedArmor;
|
||||
private final Player player;
|
||||
private boolean isCancelled;
|
||||
|
||||
/**
|
||||
* Constructor for ProtectInventoryEvent.
|
||||
* Constructor.
|
||||
*
|
||||
* @param player Player
|
||||
* @param player The player
|
||||
*/
|
||||
public ProtectInventoryEvent(Player player) {
|
||||
super(true);
|
||||
this.player = player;
|
||||
this.storedinventory = player.getInventory().getContents();
|
||||
this.storedarmor = player.getInventory().getArmorContents();
|
||||
this.emptyInventory = new ItemStack[36];
|
||||
this.emptyArmor = new ItemStack[4];
|
||||
this.storedInventory = player.getInventory().getContents();
|
||||
this.storedArmor = player.getInventory().getArmorContents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getStoredInventory.
|
||||
* Return the inventory of the player.
|
||||
*
|
||||
* @return ItemStack[]
|
||||
* @return The player's inventory
|
||||
*/
|
||||
public ItemStack[] getStoredInventory() {
|
||||
return this.storedinventory;
|
||||
return storedInventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getStoredArmor.
|
||||
* Return the armor of the player.
|
||||
*
|
||||
* @return ItemStack[]
|
||||
* @return The player's armor
|
||||
*/
|
||||
public ItemStack[] getStoredArmor() {
|
||||
return this.storedarmor;
|
||||
return storedArmor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getPlayer.
|
||||
* Return the player whose inventory will be hidden.
|
||||
*
|
||||
* @return Player
|
||||
* @return The player associated with this event
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean isCancelled) {
|
||||
this.isCancelled = isCancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return isCancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setNewInventory.
|
||||
* Return the list of handlers, equivalent to {@link #getHandlers()} and required by {@link Event}.
|
||||
*
|
||||
* @param emptyInventory ItemStack[]
|
||||
* @return The list of handlers
|
||||
*/
|
||||
public void setNewInventory(ItemStack[] emptyInventory) {
|
||||
this.emptyInventory = emptyInventory;
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getEmptyInventory.
|
||||
*
|
||||
* @return ItemStack[]
|
||||
*/
|
||||
public ItemStack[] getEmptyInventory() {
|
||||
return this.emptyInventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setNewArmor.
|
||||
*
|
||||
* @param emptyArmor ItemStack[]
|
||||
*/
|
||||
public void setNewArmor(ItemStack[] emptyArmor) {
|
||||
this.emptyArmor = emptyArmor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getEmptyArmor.
|
||||
*
|
||||
* @return ItemStack[]
|
||||
*/
|
||||
public ItemStack[] getEmptyArmor() {
|
||||
return this.emptyArmor;
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* This event is call if, and only if, a player is teleported just after a
|
||||
* register.
|
||||
*
|
||||
* @author Xephi59
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class RegisterTeleportEvent extends CustomEvent {
|
||||
|
||||
private final Player player;
|
||||
private Location to;
|
||||
private final Location from;
|
||||
|
||||
/**
|
||||
* Constructor for RegisterTeleportEvent.
|
||||
*
|
||||
* @param player Player
|
||||
* @param to Location
|
||||
*/
|
||||
public RegisterTeleportEvent(Player player, Location to) {
|
||||
this.player = player;
|
||||
this.from = player.getLocation();
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getPlayer.
|
||||
*
|
||||
* @return Player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getTo.
|
||||
*
|
||||
* @return Location
|
||||
*/
|
||||
public Location getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setTo.
|
||||
*
|
||||
* @param to Location
|
||||
*/
|
||||
public void setTo(Location to) {
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getFrom.
|
||||
*
|
||||
* @return Location
|
||||
*/
|
||||
public Location getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* This event is call when a creative inventory is reseted.
|
||||
*
|
||||
* @author Xephi59
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class ResetInventoryEvent extends CustomEvent {
|
||||
|
||||
private Player player;
|
||||
|
||||
/**
|
||||
* Constructor for ResetInventoryEvent.
|
||||
*
|
||||
* @param player Player
|
||||
*/
|
||||
public ResetInventoryEvent(Player player) {
|
||||
super(true);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getPlayer.
|
||||
*
|
||||
* @return Player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setPlayer.
|
||||
*
|
||||
* @param player Player
|
||||
*/
|
||||
public void setPlayer(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,52 +1,60 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* This event restore the inventory.
|
||||
*
|
||||
* @author Xephi59
|
||||
* @version $Revision: 1.0 $
|
||||
* This event is fired when the inventory of a player is restored
|
||||
* (the inventory data is no longer hidden from the user).
|
||||
*/
|
||||
public class RestoreInventoryEvent extends CustomEvent {
|
||||
public class RestoreInventoryEvent extends CustomEvent implements Cancellable {
|
||||
|
||||
private Player player;
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Player player;
|
||||
private boolean isCancelled;
|
||||
|
||||
/**
|
||||
* Constructor for RestoreInventoryEvent.
|
||||
* Constructor.
|
||||
*
|
||||
* @param player Player
|
||||
* @param player The player
|
||||
*/
|
||||
public RestoreInventoryEvent(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for RestoreInventoryEvent.
|
||||
*
|
||||
* @param player Player
|
||||
* @param async boolean
|
||||
*/
|
||||
public RestoreInventoryEvent(Player player, boolean async) {
|
||||
super(async);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getPlayer.
|
||||
* Return the player whose inventory will be restored.
|
||||
*
|
||||
* @return Player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return isCancelled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean isCancelled) {
|
||||
this.isCancelled = isCancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setPlayer.
|
||||
* Return the list of handlers, equivalent to {@link #getHandlers()} and required by {@link Event}.
|
||||
*
|
||||
* @param player Player
|
||||
* @return The list of handlers
|
||||
*/
|
||||
public void setPlayer(Player player) {
|
||||
this.player = player;
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,79 +2,51 @@ package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called if a player is teleported to a specific spawn
|
||||
*
|
||||
* @author Xephi59
|
||||
* @version $Revision: 1.0 $
|
||||
* Called if a player is teleported to a specific spawn upon joining or logging in.
|
||||
*/
|
||||
public class SpawnTeleportEvent extends CustomEvent {
|
||||
public class SpawnTeleportEvent extends AbstractTeleportEvent {
|
||||
|
||||
private final Player player;
|
||||
private Location to;
|
||||
private final Location from;
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final boolean isAuthenticated;
|
||||
|
||||
/**
|
||||
* Constructor for SpawnTeleportEvent.
|
||||
* Constructor.
|
||||
*
|
||||
* @param player Player
|
||||
* @param from Location
|
||||
* @param to Location
|
||||
* @param isAuthenticated boolean
|
||||
* @param player The player
|
||||
* @param from The location the player is being teleported away from
|
||||
* @param to The teleport destination
|
||||
* @param isAuthenticated Whether or not the player is logged in
|
||||
*/
|
||||
public SpawnTeleportEvent(Player player, Location from, Location to,
|
||||
boolean isAuthenticated) {
|
||||
this.player = player;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
public SpawnTeleportEvent(Player player, Location from, Location to, boolean isAuthenticated) {
|
||||
super(false, player, from, to);
|
||||
this.isAuthenticated = isAuthenticated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getPlayer.
|
||||
* Return whether or not the player is authenticated.
|
||||
*
|
||||
* @return Player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getTo.
|
||||
*
|
||||
* @return Location
|
||||
*/
|
||||
public Location getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setTo.
|
||||
*
|
||||
* @param to Location
|
||||
*/
|
||||
public void setTo(Location to) {
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getFrom.
|
||||
*
|
||||
* @return Location
|
||||
*/
|
||||
public Location getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method isAuthenticated.
|
||||
*
|
||||
* @return boolean
|
||||
* @return true if the player is logged in, false otherwise
|
||||
*/
|
||||
public boolean isAuthenticated() {
|
||||
return isAuthenticated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of handlers, equivalent to {@link #getHandlers()} and required by {@link Event}.
|
||||
*
|
||||
* @return The list of handlers
|
||||
*/
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -188,7 +188,33 @@ public class AuthMePlayerListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onJoinMessage(PlayerJoinEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings.removeJoinMessage) {
|
||||
event.setJoinMessage(null);
|
||||
return;
|
||||
}
|
||||
if (!Settings.delayJoinMessage) {
|
||||
return;
|
||||
}
|
||||
|
||||
String name = player.getName().toLowerCase();
|
||||
String joinMsg = event.getJoinMessage();
|
||||
|
||||
// Remove the join message while the player isn't logging in
|
||||
if (joinMsg == null) {
|
||||
return;
|
||||
}
|
||||
event.setJoinMessage(null);
|
||||
joinMessage.put(name, joinMsg);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
if (player == null) {
|
||||
@@ -200,15 +226,6 @@ public class AuthMePlayerListener implements Listener {
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
}
|
||||
|
||||
String name = player.getName().toLowerCase();
|
||||
String joinMsg = event.getJoinMessage();
|
||||
|
||||
// Remove the join message while the player isn't logging in
|
||||
if (Settings.delayJoinLeaveMessages && joinMsg != null) {
|
||||
event.setJoinMessage(null);
|
||||
joinMessage.put(name, joinMsg);
|
||||
}
|
||||
|
||||
// Shedule login task so works after the prelogin
|
||||
// (Fix found by Koolaid5000)
|
||||
Bukkit.getScheduler().runTask(plugin, new Runnable() {
|
||||
@@ -348,7 +365,7 @@ public class AuthMePlayerListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings.delayJoinLeaveMessages && !Utils.checkAuth(player)) {
|
||||
if (Settings.removeLeaveMessage) {
|
||||
event.setQuitMessage(null);
|
||||
}
|
||||
|
||||
@@ -374,11 +391,11 @@ public class AuthMePlayerListener implements Listener {
|
||||
|
||||
/*
|
||||
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
* TODO #360: npc status can be used to bypass security!!!
|
||||
* Note #360: npc status can be used to bypass security!!!
|
||||
* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||
*/
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerPickupItem(PlayerPickupItemEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
@@ -392,14 +409,14 @@ public class AuthMePlayerListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerConsumeItem(PlayerItemConsumeEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerInventoryOpen(InventoryOpenEvent event) {
|
||||
final Player player = (Player) event.getPlayer();
|
||||
|
||||
@@ -491,14 +508,14 @@ public class AuthMePlayerListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerShear(PlayerShearEntityEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerFish(PlayerFishEvent event) {
|
||||
if (shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.bukkit.event.player.PlayerEditBookEvent;
|
||||
*/
|
||||
public class AuthMePlayerListener16 implements Listener {
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL)
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onPlayerEditBook(PlayerEditBookEvent event) {
|
||||
if (ListenerService.shouldCancelEvent(event)) {
|
||||
event.setCancelled(true);
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package fr.xephi.authme.listener;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
|
||||
public class AuthMeTablistPacketAdapter extends PacketAdapter {
|
||||
|
||||
public AuthMeTablistPacketAdapter(AuthMe plugin) {
|
||||
super(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.PLAYER_INFO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event)
|
||||
{
|
||||
if (event.getPacketType() == PacketType.Play.Server.PLAYER_INFO) {
|
||||
try
|
||||
{
|
||||
if (!PlayerCache.getInstance().isAuthenticated(event.getPlayer().getName().toLowerCase())) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
catch (FieldAccessException e)
|
||||
{
|
||||
ConsoleLogger.showError("Couldn't access field.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void register() {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(this);
|
||||
}
|
||||
|
||||
public void unregister() {
|
||||
ProtocolLibrary.getProtocolManager().removePacketListener(this);
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,33 @@
|
||||
package fr.xephi.authme.output;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Class for retrieving and sending translatable messages to players.
|
||||
* This class detects when the language settings have changed and will
|
||||
* automatically update to use a new language file.
|
||||
*/
|
||||
public class Messages {
|
||||
|
||||
private MessagesManager manager;
|
||||
private FileConfiguration configuration;
|
||||
private String fileName;
|
||||
private final File defaultFile;
|
||||
private FileConfiguration defaultConfiguration;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param messageFile The messages file to use
|
||||
* @param defaultFile The file with messages to use as default if missing
|
||||
*/
|
||||
public Messages(File messageFile) {
|
||||
manager = new MessagesManager(messageFile);
|
||||
public Messages(File messageFile, File defaultFile) {
|
||||
initializeFile(messageFile);
|
||||
this.defaultFile = defaultFile;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,7 +37,7 @@ public class Messages {
|
||||
* @param key The key of the message to send
|
||||
*/
|
||||
public void send(CommandSender sender, MessageKey key) {
|
||||
String[] lines = manager.retrieve(key.getKey());
|
||||
String[] lines = retrieve(key);
|
||||
for (String line : lines) {
|
||||
sender.sendMessage(line);
|
||||
}
|
||||
@@ -38,7 +45,7 @@ public class Messages {
|
||||
|
||||
/**
|
||||
* Send the given message code to the player with the given tag replacements. Note that this method
|
||||
* issues an exception if the number of supplied replacements doesn't correspond to the number of tags
|
||||
* logs an error if the number of supplied replacements doesn't correspond to the number of tags
|
||||
* the message key contains.
|
||||
*
|
||||
* @param sender The entity to send the message to
|
||||
@@ -48,13 +55,13 @@ public class Messages {
|
||||
public void send(CommandSender sender, MessageKey key, String... replacements) {
|
||||
String message = retrieveSingle(key);
|
||||
String[] tags = key.getTags();
|
||||
if (replacements.length != tags.length) {
|
||||
throw new IllegalStateException(
|
||||
"Given replacement size does not match the tags in message key '" + key + "'");
|
||||
}
|
||||
|
||||
for (int i = 0; i < tags.length; ++i) {
|
||||
message = message.replace(tags[i], replacements[i]);
|
||||
if (replacements.length == tags.length) {
|
||||
for (int i = 0; i < tags.length; ++i) {
|
||||
message = message.replace(tags[i], replacements[i]);
|
||||
}
|
||||
} else {
|
||||
ConsoleLogger.showError("Invalid number of replacements for message key '" + key + "'");
|
||||
send(sender, key);
|
||||
}
|
||||
|
||||
for (String line : message.split("\n")) {
|
||||
@@ -66,18 +73,24 @@ public class Messages {
|
||||
* Retrieve the message from the text file and return it split by new line as an array.
|
||||
*
|
||||
* @param key The message key to retrieve
|
||||
*
|
||||
* @return The message split by new lines
|
||||
*/
|
||||
public String[] retrieve(MessageKey key) {
|
||||
return manager.retrieve(key.getKey());
|
||||
final String code = key.getKey();
|
||||
String message = configuration.getString(code);
|
||||
|
||||
if (message == null) {
|
||||
ConsoleLogger.showError("Error getting message with key '" + code + "'. "
|
||||
+ "Please verify your config file at '" + fileName + "'");
|
||||
return formatMessage(getDefault(code));
|
||||
}
|
||||
return formatMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the message from the text file.
|
||||
*
|
||||
* @param key The message key to retrieve
|
||||
*
|
||||
* @return The message from the file
|
||||
*/
|
||||
public String retrieveSingle(MessageKey key) {
|
||||
@@ -86,9 +99,40 @@ public class Messages {
|
||||
|
||||
/**
|
||||
* Reload the messages manager.
|
||||
*
|
||||
* @param messagesFile The new file to load messages from
|
||||
*/
|
||||
public void reload(File messagesFile) {
|
||||
manager = new MessagesManager(messagesFile);
|
||||
initializeFile(messagesFile);
|
||||
}
|
||||
|
||||
private void initializeFile(File messageFile) {
|
||||
this.configuration = YamlConfiguration.loadConfiguration(messageFile);
|
||||
this.fileName = messageFile.getName();
|
||||
}
|
||||
|
||||
private String getDefault(String code) {
|
||||
if (defaultFile == null) {
|
||||
return getDefaultErrorMessage(code);
|
||||
}
|
||||
|
||||
if (defaultConfiguration == null) {
|
||||
defaultConfiguration = YamlConfiguration.loadConfiguration(defaultFile);
|
||||
}
|
||||
String message = defaultConfiguration.getString(code);
|
||||
return message == null ? getDefaultErrorMessage(code) : message;
|
||||
}
|
||||
|
||||
private static String getDefaultErrorMessage(String code) {
|
||||
return "Error retrieving message '" + code + "'";
|
||||
}
|
||||
|
||||
private static String[] formatMessage(String message) {
|
||||
String[] lines = message.split("&n");
|
||||
for (int i = 0; i < lines.length; ++i) {
|
||||
lines[i] = ChatColor.translateAlternateColorCodes('&', lines[i]);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
package fr.xephi.authme.output;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Class responsible for reading messages from a file and formatting them for Minecraft.
|
||||
* <p>
|
||||
* This class is used within {@link Messages}, which offers a high-level interface for accessing
|
||||
* or sending messages from a properties file.
|
||||
*/
|
||||
class MessagesManager {
|
||||
|
||||
private final YamlConfiguration configuration;
|
||||
private final String fileName;
|
||||
|
||||
/**
|
||||
* Constructor for Messages.
|
||||
*
|
||||
* @param file the configuration file
|
||||
*/
|
||||
MessagesManager(File file) {
|
||||
this.fileName = file.getName();
|
||||
this.configuration = YamlConfiguration.loadConfiguration(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the message from the configuration file.
|
||||
*
|
||||
* @param key The key to retrieve
|
||||
*
|
||||
* @return The message
|
||||
*/
|
||||
public String[] retrieve(String key) {
|
||||
String message = configuration.getString(key);
|
||||
if (message != null) {
|
||||
return formatMessage(message);
|
||||
}
|
||||
|
||||
// Message is null: log key not being found and send error back as message
|
||||
String retrievalError = "Error getting message with key '" + key + "'. ";
|
||||
ConsoleLogger.showError(retrievalError + "Please verify your config file at '" + fileName + "'");
|
||||
return new String[]{
|
||||
retrievalError + "Please contact the admin to verify or update the AuthMe messages file."};
|
||||
}
|
||||
|
||||
private static String[] formatMessage(String message) {
|
||||
String[] lines = message.split("&n");
|
||||
for (int i = 0; i < lines.length; ++i) {
|
||||
lines[i] = ChatColor.translateAlternateColorCodes('&', lines[i]);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,6 +26,7 @@ public class Management {
|
||||
* Constructor for Management.
|
||||
*
|
||||
* @param plugin AuthMe
|
||||
* @param settings The plugin settings
|
||||
*/
|
||||
public Management(AuthMe plugin, NewSetting settings) {
|
||||
this.plugin = plugin;
|
||||
|
||||
@@ -80,18 +80,17 @@ public class AsynchronousJoin {
|
||||
if (Settings.getMaxJoinPerIp > 0
|
||||
&& !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS)
|
||||
&& !ip.equalsIgnoreCase("127.0.0.1")
|
||||
&& !ip.equalsIgnoreCase("localhost")) {
|
||||
if (plugin.hasJoinedIp(player.getName(), ip)) {
|
||||
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
&& !ip.equalsIgnoreCase("localhost")
|
||||
&& plugin.hasJoinedIp(player.getName(), ip)) {
|
||||
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
player.kickPlayer("A player with the same IP is already in game!");
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
player.kickPlayer("A player with the same IP is already in game!");
|
||||
}
|
||||
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
final Location spawnLoc = plugin.getSpawnLocation(player);
|
||||
final boolean isAuthAvailable = database.isAuthAvailable(name);
|
||||
@@ -104,12 +103,9 @@ public class AsynchronousJoin {
|
||||
public void run() {
|
||||
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, PlayerCache.getInstance().isAuthenticated(name));
|
||||
plugin.getServer().getPluginManager().callEvent(tpEvent);
|
||||
if (!tpEvent.isCancelled()) {
|
||||
if (player.isOnline() && tpEvent.getTo() != null) {
|
||||
if (tpEvent.getTo().getWorld() != null) {
|
||||
player.teleport(tpEvent.getTo());
|
||||
}
|
||||
}
|
||||
if (!tpEvent.isCancelled() && player.isOnline() && tpEvent.getTo() != null
|
||||
&& tpEvent.getTo().getWorld() != null) {
|
||||
player.teleport(tpEvent.getTo());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,25 +151,21 @@ public class AsynchronousJoin {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Settings.noTeleport) {
|
||||
if (!needFirstSpawn() && Settings.isTeleportToSpawnEnabled || (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName()))) {
|
||||
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
if (!Settings.noTeleport && !needFirstSpawn() && Settings.isTeleportToSpawnEnabled
|
||||
|| (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName()))) {
|
||||
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, PlayerCache.getInstance().isAuthenticated(name));
|
||||
plugin.getServer().getPluginManager().callEvent(tpEvent);
|
||||
if (!tpEvent.isCancelled()) {
|
||||
if (player.isOnline() && tpEvent.getTo() != null) {
|
||||
if (tpEvent.getTo().getWorld() != null) {
|
||||
player.teleport(tpEvent.getTo());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, PlayerCache.getInstance().isAuthenticated(name));
|
||||
plugin.getServer().getPluginManager().callEvent(tpEvent);
|
||||
if (!tpEvent.isCancelled() && player.isOnline() && tpEvent.getTo() != null
|
||||
&& tpEvent.getTo().getWorld() != null) {
|
||||
player.teleport(tpEvent.getTo());
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,8 +28,7 @@ import fr.xephi.authme.util.Utils.GroupType;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN;
|
||||
|
||||
/**
|
||||
*/
|
||||
|
||||
public class ProcessSyncPlayerLogin implements Runnable {
|
||||
|
||||
private final LimboPlayer limbo;
|
||||
@@ -47,7 +46,8 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
*
|
||||
* @param player Player
|
||||
* @param plugin AuthMe
|
||||
* @param database DataSource
|
||||
* @param database DataSource
|
||||
* @param settings The plugin settings
|
||||
*/
|
||||
public ProcessSyncPlayerLogin(Player player, AuthMe plugin,
|
||||
DataSource database, NewSetting settings) {
|
||||
@@ -62,24 +62,19 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getLimbo.
|
||||
*
|
||||
* @return LimboPlayer
|
||||
*/
|
||||
public LimboPlayer getLimbo() {
|
||||
return limbo;
|
||||
}
|
||||
|
||||
protected void restoreOpState() {
|
||||
private void restoreOpState() {
|
||||
player.setOp(limbo.getOperator());
|
||||
}
|
||||
|
||||
protected void packQuitLocation() {
|
||||
private void packQuitLocation() {
|
||||
Utils.packCoords(auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ(), auth.getWorld(), player);
|
||||
}
|
||||
|
||||
protected void teleportBackFromSpawn() {
|
||||
private void teleportBackFromSpawn() {
|
||||
AuthMeTeleportEvent tpEvent = new AuthMeTeleportEvent(player, limbo.getLoc());
|
||||
pm.callEvent(tpEvent);
|
||||
if (!tpEvent.isCancelled() && tpEvent.getTo() != null) {
|
||||
@@ -87,7 +82,7 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
protected void teleportToSpawn() {
|
||||
private void teleportToSpawn() {
|
||||
Location spawnL = plugin.getSpawnLocation(player);
|
||||
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnL, true);
|
||||
pm.callEvent(tpEvent);
|
||||
@@ -96,14 +91,14 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
protected void restoreSpeedEffects() {
|
||||
private void restoreSpeedEffects() {
|
||||
if (Settings.isRemoveSpeedEnabled) {
|
||||
player.setWalkSpeed(0.2F);
|
||||
player.setFlySpeed(0.1F);
|
||||
}
|
||||
}
|
||||
|
||||
protected void restoreInventory() {
|
||||
private void restoreInventory() {
|
||||
RestoreInventoryEvent event = new RestoreInventoryEvent(player);
|
||||
pm.callEvent(event);
|
||||
if (!event.isCancelled() && plugin.inventoryProtector != null) {
|
||||
@@ -111,7 +106,7 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
protected void forceCommands() {
|
||||
private void forceCommands() {
|
||||
for (String command : Settings.forceCommands) {
|
||||
player.performCommand(command.replace("%p", player.getName()));
|
||||
}
|
||||
@@ -120,7 +115,7 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
protected void sendBungeeMessage() {
|
||||
private void sendBungeeMessage() {
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
out.writeUTF("Forward");
|
||||
out.writeUTF("ALL");
|
||||
@@ -129,11 +124,6 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method run.
|
||||
*
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
// Limbo contains the State of the Player before /login
|
||||
@@ -174,8 +164,9 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
if (jm != null) {
|
||||
if (!jm.isEmpty()) {
|
||||
for (Player p : Utils.getOnlinePlayers()) {
|
||||
if (p.isOnline())
|
||||
if (p.isOnline()) {
|
||||
p.sendMessage(jm);
|
||||
}
|
||||
}
|
||||
}
|
||||
AuthMePlayerListener.joinMessage.remove(name);
|
||||
@@ -187,12 +178,13 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
}
|
||||
|
||||
// The Login event now fires (as intended) after everything is processed
|
||||
Bukkit.getServer().getPluginManager().callEvent(new LoginEvent(player, true));
|
||||
Bukkit.getServer().getPluginManager().callEvent(new LoginEvent(player));
|
||||
player.saveData();
|
||||
if (Settings.bungee)
|
||||
if (Settings.bungee) {
|
||||
sendBungeeMessage();
|
||||
}
|
||||
// Login is finish, display welcome message if we use email registration
|
||||
if (Settings.useWelcomeMessage && Settings.emailRegistration)
|
||||
if (Settings.useWelcomeMessage && Settings.emailRegistration) {
|
||||
if (Settings.broadcastWelcomeMessage) {
|
||||
for (String s : settings.getWelcomeMessage()) {
|
||||
Bukkit.getServer().broadcastMessage(plugin.replaceAllInfo(s, player));
|
||||
@@ -202,6 +194,7 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
player.sendMessage(plugin.replaceAllInfo(s, player));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Login is now finished; we can force all commands
|
||||
forceCommands();
|
||||
|
||||
@@ -39,6 +39,7 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
*
|
||||
* @param player Player
|
||||
* @param plugin AuthMe
|
||||
* @param settings The plugin settings
|
||||
*/
|
||||
public ProcessSyncPasswordRegister(Player player, AuthMe plugin, NewSetting settings) {
|
||||
this.m = plugin.getMessages();
|
||||
@@ -119,7 +120,7 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
}
|
||||
|
||||
// The LoginEvent now fires (as intended) after everything is processed
|
||||
plugin.getServer().getPluginManager().callEvent(new LoginEvent(player, true));
|
||||
plugin.getServer().getPluginManager().callEvent(new LoginEvent(player));
|
||||
player.saveData();
|
||||
|
||||
if (!Settings.noConsoleSpam) {
|
||||
|
||||
@@ -13,6 +13,7 @@ public enum HashAlgorithm {
|
||||
CRAZYCRYPT1(fr.xephi.authme.security.crypts.CRAZYCRYPT1.class),
|
||||
DOUBLEMD5(fr.xephi.authme.security.crypts.DOUBLEMD5.class),
|
||||
IPB3(fr.xephi.authme.security.crypts.IPB3.class),
|
||||
IPB4(fr.xephi.authme.security.crypts.IPB4.class),
|
||||
JOOMLA(fr.xephi.authme.security.crypts.JOOMLA.class),
|
||||
MD5(fr.xephi.authme.security.crypts.MD5.class),
|
||||
MD5VB(fr.xephi.authme.security.crypts.MD5VB.class),
|
||||
@@ -29,8 +30,8 @@ public enum HashAlgorithm {
|
||||
SHA1(fr.xephi.authme.security.crypts.SHA1.class),
|
||||
SHA256(fr.xephi.authme.security.crypts.SHA256.class),
|
||||
SHA512(fr.xephi.authme.security.crypts.SHA512.class),
|
||||
TWO_FACTOR(fr.xephi.authme.security.crypts.TwoFactor.class),
|
||||
SMF(fr.xephi.authme.security.crypts.SMF.class),
|
||||
TWO_FACTOR(fr.xephi.authme.security.crypts.TwoFactor.class),
|
||||
WBB3(fr.xephi.authme.security.crypts.WBB3.class),
|
||||
WBB4(fr.xephi.authme.security.crypts.WBB4.class),
|
||||
WHIRLPOOL(fr.xephi.authme.security.crypts.WHIRLPOOL.class),
|
||||
|
||||
@@ -8,18 +8,10 @@ import java.util.Random;
|
||||
*/
|
||||
public final class RandomString {
|
||||
|
||||
private static final char[] chars = new char[36];
|
||||
private static final String CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
private static final Random RANDOM = new SecureRandom();
|
||||
private static final int HEX_MAX_INDEX = 16;
|
||||
|
||||
static {
|
||||
for (int idx = 0; idx < 10; ++idx) {
|
||||
chars[idx] = (char) ('0' + idx);
|
||||
}
|
||||
for (int idx = 10; idx < 36; ++idx) {
|
||||
chars[idx] = (char) ('a' + idx - 10);
|
||||
}
|
||||
}
|
||||
private static final int LOWER_ALPHANUMERIC_INDEX = 36;
|
||||
|
||||
private RandomString() {
|
||||
}
|
||||
@@ -31,7 +23,7 @@ public final class RandomString {
|
||||
* @return The random string
|
||||
*/
|
||||
public static String generate(int length) {
|
||||
return generate(length, chars.length);
|
||||
return generate(length, LOWER_ALPHANUMERIC_INDEX);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,13 +37,24 @@ public final class RandomString {
|
||||
return generate(length, HEX_MAX_INDEX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random string with digits and lowercase and uppercase letters. The result of this
|
||||
* method matches the pattern [0-9a-zA-Z].
|
||||
*
|
||||
* @param length The length of the random string to generate
|
||||
* @return The random string
|
||||
*/
|
||||
public static String generateLowerUpper(int length) {
|
||||
return generate(length, CHARS.length());
|
||||
}
|
||||
|
||||
private static String generate(int length, int maxIndex) {
|
||||
if (length < 0) {
|
||||
throw new IllegalArgumentException("Length must be positive but was " + length);
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(length);
|
||||
for (int i = 0; i < length; ++i) {
|
||||
sb.append(chars[RANDOM.nextInt(maxIndex)]);
|
||||
sb.append(CHARS.charAt(RANDOM.nextInt(maxIndex)));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -388,7 +388,7 @@ public class BCryptService {
|
||||
private static String encode_base64(byte d[], int len)
|
||||
throws IllegalArgumentException {
|
||||
int off = 0;
|
||||
StringBuffer rs = new StringBuffer();
|
||||
StringBuilder rs = new StringBuilder();
|
||||
int c1, c2;
|
||||
|
||||
if (len <= 0 || len > d.length)
|
||||
@@ -441,7 +441,7 @@ public class BCryptService {
|
||||
*/
|
||||
private static byte[] decode_base64(String s, int maxolen)
|
||||
throws IllegalArgumentException {
|
||||
StringBuffer rs = new StringBuffer();
|
||||
StringBuilder rs = new StringBuilder();
|
||||
int off = 0, slen = s.length(), olen = 0;
|
||||
byte ret[];
|
||||
byte c1, c2, c3, c4, o;
|
||||
@@ -486,7 +486,7 @@ public class BCryptService {
|
||||
* @param lr an array containing the two 32-bit half blocks
|
||||
* @param off the position in the array of the blocks
|
||||
*/
|
||||
private final void encipher(int lr[], int off) {
|
||||
private void encipher(int lr[], int off) {
|
||||
int i, n, l = lr[off], r = lr[off + 1];
|
||||
|
||||
l ^= P[0];
|
||||
@@ -534,8 +534,8 @@ public class BCryptService {
|
||||
* Initialise the Blowfish key schedule
|
||||
*/
|
||||
private void init_key() {
|
||||
P = (int[])P_orig.clone();
|
||||
S = (int[])S_orig.clone();
|
||||
P = P_orig.clone();
|
||||
S = S_orig.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -653,8 +653,8 @@ public class BCryptService {
|
||||
String real_salt;
|
||||
byte passwordb[], saltb[], hashed[];
|
||||
char minor = (char)0;
|
||||
int rounds, off = 0;
|
||||
StringBuffer rs = new StringBuffer();
|
||||
int rounds, off;
|
||||
StringBuilder rs = new StringBuilder();
|
||||
|
||||
if (salt.charAt(0) != '$' || salt.charAt(1) != '2')
|
||||
throw new IllegalArgumentException ("Invalid salt version");
|
||||
@@ -684,8 +684,7 @@ public class BCryptService {
|
||||
saltb = decode_base64(real_salt, BCRYPT_SALT_LEN);
|
||||
|
||||
B = new BCryptService();
|
||||
hashed = B.crypt_raw(passwordb, saltb, rounds,
|
||||
(int[])bf_crypt_ciphertext.clone());
|
||||
hashed = B.crypt_raw(passwordb, saltb, rounds, bf_crypt_ciphertext.clone());
|
||||
|
||||
rs.append("$2");
|
||||
if (minor >= 'a')
|
||||
@@ -714,7 +713,7 @@ public class BCryptService {
|
||||
* @return an encoded salt value
|
||||
*/
|
||||
public static String gensalt(int log_rounds, SecureRandom random) {
|
||||
StringBuffer rs = new StringBuffer();
|
||||
StringBuilder rs = new StringBuilder();
|
||||
byte rnd[] = new byte[BCRYPT_SALT_LEN];
|
||||
|
||||
random.nextBytes(rnd);
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.security.crypts.description.HasSalt;
|
||||
import fr.xephi.authme.security.crypts.description.Recommendation;
|
||||
import fr.xephi.authme.security.crypts.description.SaltType;
|
||||
import fr.xephi.authme.security.crypts.description.Usage;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
* Implementation for IPB4 (Invision Power Board 4).
|
||||
* <p>
|
||||
* The hash uses standard BCrypt with 13 as log<sub>2</sub> number of rounds. Additionally,
|
||||
* IPB4 requires that the salt be stored additionally in the column "members_pass_hash"
|
||||
* (even though BCrypt hashes already have the salt in the result).
|
||||
*/
|
||||
@Recommendation(Usage.DOES_NOT_WORK)
|
||||
@HasSalt(value = SaltType.TEXT, length = 22)
|
||||
public class IPB4 implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String computeHash(String password, String salt, String name) {
|
||||
return BCryptService.hashpw(password, "$2a$13$" + salt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashedPassword computeHash(String password, String name) {
|
||||
String salt = generateSalt();
|
||||
return new HashedPassword(computeHash(password, salt, name), salt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String password, HashedPassword hash, String name) {
|
||||
try {
|
||||
return hash.getHash().length() > 3 && BCryptService.checkpw(password, hash.getHash());
|
||||
} catch (IllegalArgumentException e) {
|
||||
ConsoleLogger.showError("Bcrypt checkpw() returned " + StringUtils.formatException(e));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateSalt() {
|
||||
return RandomString.generateLowerUpper(22);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSeparateSalt() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import org.yaml.snakeyaml.Yaml;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -108,6 +109,21 @@ public class NewSetting {
|
||||
return messagesFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default messages file within the JAR that should contain all messages.
|
||||
*
|
||||
* @return The default messages file, or {@code null} if it could not be retrieved
|
||||
*/
|
||||
public File getDefaultMessagesFile() {
|
||||
String defaultFilePath = "/messages/messages_en.yml";
|
||||
URL url = NewSetting.class.getResource(defaultFilePath);
|
||||
if (url == null) {
|
||||
return null;
|
||||
}
|
||||
File file = new File(url.getFile());
|
||||
return file.exists() ? file : null;
|
||||
}
|
||||
|
||||
public String getEmailMessage() {
|
||||
return emailMessage;
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.datasource.DataSourceType;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.Wrapper;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -22,8 +26,6 @@ public final class Settings {
|
||||
public static final File PLUGIN_FOLDER = Wrapper.getInstance().getDataFolder();
|
||||
public static final File MODULE_FOLDER = new File(PLUGIN_FOLDER, "modules");
|
||||
public static final File CACHE_FOLDER = new File(PLUGIN_FOLDER, "cache");
|
||||
private static final File SETTINGS_FILE = new File(PLUGIN_FOLDER, "config.yml");
|
||||
public static final File LOG_FILE = new File(PLUGIN_FOLDER, "authme.log");
|
||||
// This is not an option!
|
||||
public static boolean antiBotInAction = false;
|
||||
public static List<String> allowCommands;
|
||||
@@ -63,7 +65,8 @@ public final class Settings {
|
||||
purgeLimitedCreative, purgeAntiXray, purgePermissions,
|
||||
enableProtection, enableAntiBot, recallEmail, useWelcomeMessage,
|
||||
broadcastWelcomeMessage, forceRegKick, forceRegLogin,
|
||||
checkVeryGames, delayJoinLeaveMessages, noTeleport, applyBlindEffect,
|
||||
checkVeryGames, removeJoinMessage, removeLeaveMessage, delayJoinMessage,
|
||||
noTeleport, applyBlindEffect, hideTablistBeforeLogin, denyTabcompleteBeforeLogin,
|
||||
kickPlayersBeforeStopping, allowAllCommandsIfRegIsOptional,
|
||||
customAttributes, generateImage, isRemoveSpeedEnabled, preventOtherCase;
|
||||
public static String getNickRegex, getUnloggedinGroup, getMySQLHost,
|
||||
@@ -103,7 +106,7 @@ public final class Settings {
|
||||
}
|
||||
|
||||
public static void loadVariables() {
|
||||
isPermissionCheckEnabled = configFile.getBoolean("permission.EnablePermissionCheck", false);
|
||||
isPermissionCheckEnabled = load(PluginSettings.ENABLE_PERMISSION_CHECK);
|
||||
isForcedRegistrationEnabled = configFile.getBoolean("settings.registration.force", true);
|
||||
isRegistrationEnabled = configFile.getBoolean("settings.registration.enabled", true);
|
||||
isTeleportToSpawnEnabled = configFile.getBoolean("settings.restrictions.teleportUnAuthedToSpawn", false);
|
||||
@@ -130,16 +133,16 @@ public final class Settings {
|
||||
isSaveQuitLocationEnabled = configFile.getBoolean("settings.restrictions.SaveQuitLocation", false);
|
||||
isForceSurvivalModeEnabled = configFile.getBoolean("settings.GameMode.ForceSurvivalMode", false);
|
||||
getmaxRegPerIp = configFile.getInt("settings.restrictions.maxRegPerIp", 1);
|
||||
getPasswordHash = getPasswordHash();
|
||||
getUnloggedinGroup = configFile.getString("settings.security.unLoggedinGroup", "unLoggedInGroup");
|
||||
getDataSource = getDataSource();
|
||||
isCachingEnabled = configFile.getBoolean("DataSource.caching", true);
|
||||
getMySQLHost = configFile.getString("DataSource.mySQLHost", "127.0.0.1");
|
||||
getMySQLPort = configFile.getString("DataSource.mySQLPort", "3306");
|
||||
getMySQLUsername = configFile.getString("DataSource.mySQLUsername", "authme");
|
||||
getMySQLPassword = configFile.getString("DataSource.mySQLPassword", "12345");
|
||||
getMySQLDatabase = configFile.getString("DataSource.mySQLDatabase", "authme");
|
||||
getMySQLTablename = configFile.getString("DataSource.mySQLTablename", "authme");
|
||||
getPasswordHash = load(SecuritySettings.PASSWORD_HASH);
|
||||
getUnloggedinGroup = load(SecuritySettings.UNLOGGEDIN_GROUP);
|
||||
getDataSource = load(DatabaseSettings.BACKEND);
|
||||
isCachingEnabled = load(DatabaseSettings.USE_CACHING);
|
||||
getMySQLHost = load(DatabaseSettings.MYSQL_HOST);
|
||||
getMySQLPort = load(DatabaseSettings.MYSQL_PORT);
|
||||
getMySQLUsername = load(DatabaseSettings.MYSQL_USERNAME);
|
||||
getMySQLPassword = load(DatabaseSettings.MYSQL_PASSWORD);
|
||||
getMySQLDatabase = load(DatabaseSettings.MYSQL_DATABASE);
|
||||
getMySQLTablename = load(DatabaseSettings.MYSQL_TABLE);
|
||||
getMySQLColumnEmail = configFile.getString("DataSource.mySQLColumnEmail", "email");
|
||||
getMySQLColumnName = configFile.getString("DataSource.mySQLColumnName", "username");
|
||||
getMySQLColumnPassword = configFile.getString("DataSource.mySQLColumnPassword", "password");
|
||||
@@ -161,12 +164,15 @@ public final class Settings {
|
||||
}
|
||||
|
||||
getRegisteredGroup = configFile.getString("GroupOptions.RegisteredPlayerGroup", "");
|
||||
enablePasswordConfirmation = configFile.getBoolean("settings.restrictions.enablePasswordConfirmation", true);
|
||||
enablePasswordConfirmation = load(RestrictionSettings.ENABLE_PASSWORD_CONFIRMATION);
|
||||
|
||||
protectInventoryBeforeLogInEnabled = load(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN);
|
||||
denyTabcompleteBeforeLogin = load(RestrictionSettings.DENY_TABCOMPLETE_BEFORE_LOGIN);
|
||||
hideTablistBeforeLogin = load(RestrictionSettings.HIDE_TABLIST_BEFORE_LOGIN);
|
||||
|
||||
protectInventoryBeforeLogInEnabled = configFile.getBoolean("settings.restrictions.ProtectInventoryBeforeLogIn", true);
|
||||
plugin.checkProtocolLib();
|
||||
|
||||
passwordMaxLength = configFile.getInt("settings.security.passwordMaxLength", 20);
|
||||
passwordMaxLength = load(SecuritySettings.MAX_PASSWORD_LENGTH);
|
||||
backupWindowsPath = configFile.getString("BackupSystem.MysqlWindowsPath", "C:\\Program Files\\MySQL\\MySQL Server 5.1\\");
|
||||
isStopEnabled = configFile.getBoolean("Security.SQLProblem.stopServer", true);
|
||||
reloadSupport = configFile.getBoolean("Security.ReloadCommand.useReloadCommandSupport", true);
|
||||
@@ -240,7 +246,9 @@ public final class Settings {
|
||||
getMaxLoginPerIp = configFile.getInt("settings.restrictions.maxLoginPerIp", 0);
|
||||
getMaxJoinPerIp = configFile.getInt("settings.restrictions.maxJoinPerIp", 0);
|
||||
checkVeryGames = configFile.getBoolean("VeryGames.enableIpCheck", false);
|
||||
delayJoinLeaveMessages = configFile.getBoolean("settings.delayJoinLeaveMessages", false);
|
||||
removeJoinMessage = load(RegistrationSettings.REMOVE_JOIN_MESSAGE);
|
||||
removeLeaveMessage = load(RegistrationSettings.REMOVE_LEAVE_MESSAGE);
|
||||
delayJoinMessage = load(RegistrationSettings.DELAY_JOIN_MESSAGE);
|
||||
noTeleport = configFile.getBoolean("settings.restrictions.noTeleport", false);
|
||||
crazyloginFileName = configFile.getString("Converter.CrazyLogin.fileName", "accounts.db");
|
||||
getPassRegex = configFile.getString("settings.restrictions.allowedPasswordCharacters", "[\\x21-\\x7E]*");
|
||||
@@ -257,70 +265,6 @@ public final class Settings {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getPasswordHash.
|
||||
*
|
||||
* @return HashAlgorithm
|
||||
*/
|
||||
private static HashAlgorithm getPasswordHash() {
|
||||
String key = "settings.security.passwordHash";
|
||||
try {
|
||||
return HashAlgorithm.valueOf(configFile.getString(key, "SHA256").toUpperCase());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
ConsoleLogger.showError("Unknown Hash Algorithm; defaulting to SHA256");
|
||||
return HashAlgorithm.SHA256;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method getDataSource.
|
||||
*
|
||||
* @return DataSourceType
|
||||
*/
|
||||
private static DataSourceType getDataSource() {
|
||||
String key = "DataSource.backend";
|
||||
try {
|
||||
return DataSourceType.valueOf(configFile.getString(key, "sqlite").toUpperCase());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
ConsoleLogger.showError("Unknown database backend; defaulting to SQLite database");
|
||||
return DataSourceType.SQLITE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the configuration to disk
|
||||
*
|
||||
* @return True if saved successfully
|
||||
*/
|
||||
private static boolean save() {
|
||||
try {
|
||||
configFile.save(SETTINGS_FILE);
|
||||
return true;
|
||||
} catch (IOException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method checkLang.
|
||||
*
|
||||
* @param lang String
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
private static String checkLang(String lang) {
|
||||
if (new File(PLUGIN_FOLDER, "messages" + File.separator + "messages_" + lang + ".yml").exists()) {
|
||||
ConsoleLogger.info("Set Language to: " + lang);
|
||||
return lang;
|
||||
}
|
||||
if (AuthMe.class.getResourceAsStream("/messages/messages_" + lang + ".yml") != null) {
|
||||
ConsoleLogger.info("Set Language to: " + lang);
|
||||
return lang;
|
||||
}
|
||||
ConsoleLogger.info("Language file not found for " + lang + ", set to default language: en !");
|
||||
return "en";
|
||||
}
|
||||
|
||||
/**
|
||||
* Method switchAntiBotMod.
|
||||
*
|
||||
@@ -337,20 +281,13 @@ public final class Settings {
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves current configuration (plus defaults) to disk.
|
||||
* <p>
|
||||
* If defaults and configuration are empty, saves blank file.
|
||||
* Load the value via the new Property setup for temporary support within this old settings manager.
|
||||
*
|
||||
* @return True if saved successfully
|
||||
* @param property The property to load
|
||||
* @param <T> The property type
|
||||
* @return The config value of the property
|
||||
*/
|
||||
private boolean saveDefaults() {
|
||||
configFile.options()
|
||||
.copyDefaults(true)
|
||||
.copyHeader(true);
|
||||
boolean success = save();
|
||||
configFile.options()
|
||||
.copyDefaults(false)
|
||||
.copyHeader(false);
|
||||
return success;
|
||||
private static <T> T load(Property<T> property) {
|
||||
return property.getFromFile(configFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.DELAY_JOIN_MESSAGE;
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.REMOVE_JOIN_MESSAGE;
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.REMOVE_LEAVE_MESSAGE;
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS;
|
||||
import static java.lang.String.format;
|
||||
|
||||
@@ -43,9 +46,12 @@ public final class SettingsMigrationService {
|
||||
configuration.set(ALLOWED_NICKNAME_CHARACTERS.getPath(), "[a-zA-Z0-9_]*");
|
||||
changes = true;
|
||||
}
|
||||
changes = changes || performMailTextToFileMigration(configuration, pluginFolder);
|
||||
|
||||
return changes;
|
||||
// Note ljacqu 20160211: Concatenating migration methods with | instead of the usual ||
|
||||
// ensures that all migrations will be performed
|
||||
return changes
|
||||
| performMailTextToFileMigration(configuration, pluginFolder)
|
||||
| migrateJoinLeaveMessages(configuration);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -61,8 +67,7 @@ public final class SettingsMigrationService {
|
||||
private static boolean hasDeprecatedProperties(FileConfiguration configuration) {
|
||||
String[] deprecatedProperties = {
|
||||
"Converter.Rakamak.newPasswordHash", "Hooks.chestshop", "Hooks.legacyChestshop", "Hooks.notifications",
|
||||
"Passpartu", "Performances", "settings.delayJoinMessage", "settings.restrictions.enablePasswordVerifier",
|
||||
"Xenoforo.predefinedSalt"};
|
||||
"Passpartu", "Performances", "settings.restrictions.enablePasswordVerifier", "Xenoforo.predefinedSalt"};
|
||||
for (String deprecatedPath : deprecatedProperties) {
|
||||
if (configuration.contains(deprecatedPath)) {
|
||||
return true;
|
||||
@@ -104,6 +109,33 @@ public final class SettingsMigrationService {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect deprecated {@code settings.delayJoinLeaveMessages} and inform user of new "remove join messages"
|
||||
* and "remove leave messages" settings.
|
||||
*
|
||||
* @param configuration The file configuration
|
||||
* @return True if the configuration has changed, false otherwise
|
||||
*/
|
||||
private static boolean migrateJoinLeaveMessages(FileConfiguration configuration) {
|
||||
final String oldDelayJoinPath = "settings.delayJoinLeaveMessages";
|
||||
if (configuration.contains(oldDelayJoinPath)) {
|
||||
ConsoleLogger.info("Detected deprecated property " + oldDelayJoinPath);
|
||||
ConsoleLogger.info(String.format("Note that we now also have the settings %s and %s",
|
||||
REMOVE_JOIN_MESSAGE.getPath(), REMOVE_LEAVE_MESSAGE.getPath()));
|
||||
if (!configuration.contains(DELAY_JOIN_MESSAGE.getPath())) {
|
||||
configuration.set(DELAY_JOIN_MESSAGE.getPath(), true);
|
||||
ConsoleLogger.info("Renamed " + oldDelayJoinPath + " to " + DELAY_JOIN_MESSAGE.getPath());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// -------
|
||||
// Utilities
|
||||
// -------
|
||||
|
||||
/**
|
||||
* Copy a resource file (from the JAR) to the given file if it doesn't exist.
|
||||
*
|
||||
|
||||
@@ -80,9 +80,17 @@ public class RegistrationSettings implements SettingsClass {
|
||||
public static final Property<Boolean> BROADCAST_WELCOME_MESSAGE =
|
||||
newProperty("settings.broadcastWelcomeMessage", false);
|
||||
|
||||
@Comment("Do we need to delay the join/leave message to be displayed only when the player is authenticated?")
|
||||
public static final Property<Boolean> DELAY_JOIN_LEAVE_MESSAGES =
|
||||
newProperty("settings.delayJoinLeaveMessages", true);
|
||||
@Comment("Should we delay the join message and display it once the player has logged in?")
|
||||
public static final Property<Boolean> DELAY_JOIN_MESSAGE =
|
||||
newProperty("settings.delayJoinMessage", false);
|
||||
|
||||
@Comment("Should we remove join messages altogether?")
|
||||
public static final Property<Boolean> REMOVE_JOIN_MESSAGE =
|
||||
newProperty("settings.removeJoinMessage", false);
|
||||
|
||||
@Comment("Should we remove leave messages?")
|
||||
public static final Property<Boolean> REMOVE_LEAVE_MESSAGE =
|
||||
newProperty("settings.removeLeaveMessage", false);
|
||||
|
||||
@Comment("Do we need to add potion effect Blinding before login/reigster?")
|
||||
public static final Property<Boolean> APPLY_BLIND_EFFECT =
|
||||
|
||||
@@ -126,10 +126,18 @@ public class RestrictionSettings implements SettingsClass {
|
||||
public static final Property<Boolean> ENABLE_PASSWORD_CONFIRMATION =
|
||||
newProperty("settings.restrictions.enablePasswordConfirmation", true);
|
||||
|
||||
@Comment("Should we protect the player inventory before logging in?")
|
||||
@Comment("Should we protect the player inventory before logging in? Requires ProtocolLib.")
|
||||
public static final Property<Boolean> PROTECT_INVENTORY_BEFORE_LOGIN =
|
||||
newProperty("settings.restrictions.ProtectInventoryBeforeLogIn", true);
|
||||
|
||||
@Comment("Should we deny the tabcomplete feature before logging in? Requires ProtocolLib.")
|
||||
public static final Property<Boolean> DENY_TABCOMPLETE_BEFORE_LOGIN =
|
||||
newProperty("settings.restrictions.DenyTabCompleteBeforeLogin", true);
|
||||
|
||||
@Comment("Should we hide the tablist before logging in? Requires ProtocolLib.")
|
||||
public static final Property<Boolean> HIDE_TABLIST_BEFORE_LOGIN =
|
||||
newProperty("settings.restrictions.HideTablistBeforeLogin", true);
|
||||
|
||||
@Comment({
|
||||
"Should we display all other accounts from a player when he joins?",
|
||||
"permission: /authme.admin.accounts"})
|
||||
|
||||
@@ -9,7 +9,6 @@ import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static fr.xephi.authme.settings.domain.PropertyType.STRING_LIST;
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
|
||||
public class SecuritySettings implements SettingsClass {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user