Update 3.3.3

This commit is contained in:
Xephi 2014-02-20 12:54:10 +01:00
parent 5a089fa690
commit 4e7e9e6cb4
21 changed files with 315 additions and 127 deletions

View File

@ -24,12 +24,12 @@
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
<version>3.3.2</version> <version>3.3.3</version>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.bukkit</groupId> <groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId> <artifactId>craftbukkit</artifactId>
<version>1.7.2-R0.3-SNAPSHOT</version> <version>1.7.2-R0.3</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.milkbowl.vault</groupId> <groupId>net.milkbowl.vault</groupId>

View File

@ -720,7 +720,7 @@ public class AuthMe extends JavaPlugin {
ConsoleLogger.info("AutoPurgeDatabase : Remove " + i + " EssentialsFiles"); ConsoleLogger.info("AutoPurgeDatabase : Remove " + i + " EssentialsFiles");
} }
public Location getSpawnLocation(World world) { public Location getSpawnLocation(String name, World world) {
Location spawnLoc = world.getSpawnLocation(); Location spawnLoc = world.getSpawnLocation();
if (multiverse != null && Settings.multiverse) { if (multiverse != null && Settings.multiverse) {
try { try {
@ -733,8 +733,10 @@ public class AuthMe extends JavaPlugin {
if (essentialsSpawn != null) { if (essentialsSpawn != null) {
spawnLoc = essentialsSpawn; spawnLoc = essentialsSpawn;
} }
if (Spawn.getInstance().getLocation() != null) if (Spawn.getInstance().getSpawn() != null)
spawnLoc = Spawn.getInstance().getLocation(); spawnLoc = Spawn.getInstance().getSpawn();
if (!database.isAuthAvailable(name) && Spawn.getInstance().getFirstSpawn() != null)
spawnLoc = Spawn.getInstance().getFirstSpawn();
return spawnLoc; return spawnLoc;
} }

View File

@ -19,60 +19,63 @@ import fr.xephi.authme.events.AuthMeTeleportEvent;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
public class Utils { public class Utils {
private String currentGroup; private String currentGroup;
private static Utils singleton; private static Utils singleton;
int id; int id;
public AuthMe plugin; public AuthMe plugin;
public Utils(AuthMe plugin) { public Utils(AuthMe plugin) {
this.plugin = plugin; this.plugin = plugin;
} }
public void setGroup(Player player, groupType group) { public void setGroup(Player player, groupType group) {
if (!player.isOnline()) setGroup(player.getName(), group);
return; }
if(!Settings.isPermissionCheckEnabled)
return; public void setGroup(String player, groupType group) {
if(plugin.permission == null) if(!Settings.isPermissionCheckEnabled)
return; return;
try { if(plugin.permission == null)
currentGroup = plugin.permission.getPrimaryGroup(player); return;
} catch (UnsupportedOperationException e) { try {
ConsoleLogger.showError("Your permission system (" + plugin.permission.getName() + ") do not support Group system with that config... unhook!"); World world = null;
plugin.permission = null; currentGroup = plugin.permission.getPrimaryGroup(world, player);
return; } catch (UnsupportedOperationException e) {
} ConsoleLogger.showError("Your permission system (" + plugin.permission.getName() + ") do not support Group system with that config... unhook!");
World world = null; plugin.permission = null;
String name = player.getName(); return;
switch(group) { }
case UNREGISTERED: { World world = null;
plugin.permission.playerRemoveGroup(world, name, currentGroup); String name = player;
plugin.permission.playerAddGroup(world, name, Settings.unRegisteredGroup); switch(group) {
break; case UNREGISTERED: {
} plugin.permission.playerRemoveGroup(world, name, currentGroup);
case REGISTERED: { plugin.permission.playerAddGroup(world, name, Settings.unRegisteredGroup);
plugin.permission.playerRemoveGroup(world, name, currentGroup); break;
plugin.permission.playerAddGroup(world, name, Settings.getRegisteredGroup); }
break; case REGISTERED: {
} plugin.permission.playerRemoveGroup(world, name, currentGroup);
case NOTLOGGEDIN: { plugin.permission.playerAddGroup(world, name, Settings.getRegisteredGroup);
if(!useGroupSystem()) break; break;
plugin.permission.playerRemoveGroup(world, name, currentGroup); }
plugin.permission.playerAddGroup(world, name, Settings.getUnloggedinGroup); case NOTLOGGEDIN: {
break; if(!useGroupSystem()) break;
} plugin.permission.playerRemoveGroup(world, name, currentGroup);
case LOGGEDIN: { plugin.permission.playerAddGroup(world, name, Settings.getUnloggedinGroup);
if(!useGroupSystem()) break; break;
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(player.getName().toLowerCase()); }
if (limbo == null) break; case LOGGEDIN: {
String realGroup = limbo.getGroup(); if(!useGroupSystem()) break;
plugin.permission.playerRemoveGroup(world, name, currentGroup); LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name.toLowerCase());
plugin.permission.playerAddGroup(world, name, realGroup); if (limbo == null) break;
break; String realGroup = limbo.getGroup();
} plugin.permission.playerRemoveGroup(world, name, currentGroup);
} plugin.permission.playerAddGroup(world, name, realGroup);
return; break;
} }
}
return;
}
public boolean addNormal(Player player, String group) { public boolean addNormal(Player player, String group) {
if(!useGroupSystem()){ if(!useGroupSystem()){

View File

@ -98,7 +98,9 @@ public class PlayerAuth {
} }
public String getIp() { public String getIp() {
return ip; if (ip == null || ip.isEmpty())
ip = "127.0.0.1";
return ip;
} }
public String getNickname() { public String getNickname() {
@ -145,6 +147,12 @@ public class PlayerAuth {
this.z = d; this.z = d;
} }
public long getLastLogin() { public long getLastLogin() {
try {
if (Long.valueOf(lastLogin) == null)
lastLogin = 0L;
} catch (NullPointerException e) {
lastLogin = 0L;
}
return lastLogin; return lastLogin;
} }

View File

@ -89,7 +89,7 @@ public class LimboCache {
gameMode = GameMode.SURVIVAL; gameMode = GameMode.SURVIVAL;
} }
if(player.isDead()) { if(player.isDead()) {
loc = plugin.getSpawnLocation(player.getWorld()); loc = plugin.getSpawnLocation(player.getName().toLowerCase(), player.getWorld());
} }
cache.put(player.getName().toLowerCase(), new LimboPlayer(name, loc, inv, arm, gameMode, operator, playerGroup, flying)); cache.put(player.getName().toLowerCase(), new LimboPlayer(name, loc, inv, arm, gameMode, operator, playerGroup, flying));
} }

View File

@ -13,6 +13,7 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
@ -22,13 +23,16 @@ import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.Utils; import fr.xephi.authme.Utils;
import fr.xephi.authme.Utils.groupType;
import fr.xephi.authme.api.API; import fr.xephi.authme.api.API;
import fr.xephi.authme.cache.auth.PlayerAuth; import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache; import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.converter.FlatToSql; import fr.xephi.authme.converter.FlatToSql;
import fr.xephi.authme.converter.FlatToSqlite; import fr.xephi.authme.converter.FlatToSqlite;
import fr.xephi.authme.converter.RakamakConverter; import fr.xephi.authme.converter.RakamakConverter;
@ -36,11 +40,14 @@ import fr.xephi.authme.converter.RoyalAuthConverter;
import fr.xephi.authme.converter.newxAuthToFlat; import fr.xephi.authme.converter.newxAuthToFlat;
import fr.xephi.authme.converter.oldxAuthToFlat; import fr.xephi.authme.converter.oldxAuthToFlat;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.SpawnTeleportEvent;
import fr.xephi.authme.security.PasswordSecurity; import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.Spawn; import fr.xephi.authme.settings.Spawn;
import fr.xephi.authme.settings.SpoutCfg; import fr.xephi.authme.settings.SpoutCfg;
import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask;
public class AdminCommand implements CommandExecutor { public class AdminCommand implements CommandExecutor {
@ -385,6 +392,19 @@ public class AdminCommand implements CommandExecutor {
ConsoleLogger.showError(ex.getMessage()); ConsoleLogger.showError(ex.getMessage());
} }
return true; return true;
} else if (args[0].equalsIgnoreCase("setfirstspawn")) {
try {
if (sender instanceof Player) {
if (Spawn.getInstance().setFirstSpawn(((Player) sender).getLocation()))
sender.sendMessage("[AuthMe] Correctly define new first spawn");
else sender.sendMessage("[AuthMe] SetFirstSpawn fail , please retry");
} else {
sender.sendMessage("[AuthMe] Please use that command in game");
}
} catch (NullPointerException ex) {
ConsoleLogger.showError(ex.getMessage());
}
return true;
} else if (args[0].equalsIgnoreCase("purgebannedplayers")) { } else if (args[0].equalsIgnoreCase("purgebannedplayers")) {
List<String> bannedPlayers = new ArrayList<String>(); List<String> bannedPlayers = new ArrayList<String>();
for (OfflinePlayer off : plugin.getServer().getBannedPlayers()) { for (OfflinePlayer off : plugin.getServer().getBannedPlayers()) {
@ -413,8 +433,8 @@ public class AdminCommand implements CommandExecutor {
} else if (args[0].equalsIgnoreCase("spawn")) { } else if (args[0].equalsIgnoreCase("spawn")) {
try { try {
if (sender instanceof Player) { if (sender instanceof Player) {
if (Spawn.getInstance().getLocation() != null) if (Spawn.getInstance().getSpawn() != null)
((Player) sender).teleport(Spawn.getInstance().getLocation()); ((Player) sender).teleport(Spawn.getInstance().getSpawn());
else sender.sendMessage("[AuthMe] Spawn fail , please try to define the spawn"); else sender.sendMessage("[AuthMe] Spawn fail , please try to define the spawn");
} else { } else {
sender.sendMessage("[AuthMe] Please use that command in game"); sender.sendMessage("[AuthMe] Please use that command in game");
@ -423,6 +443,19 @@ public class AdminCommand implements CommandExecutor {
ConsoleLogger.showError(ex.getMessage()); ConsoleLogger.showError(ex.getMessage());
} }
return true; return true;
} else if (args[0].equalsIgnoreCase("firstspawn")) {
try {
if (sender instanceof Player) {
if (Spawn.getInstance().getFirstSpawn() != null)
((Player) sender).teleport(Spawn.getInstance().getFirstSpawn());
else sender.sendMessage("[AuthMe] Spawn fail , please try to define the first spawn");
} else {
sender.sendMessage("[AuthMe] Please use that command in game");
}
} catch (NullPointerException ex) {
ConsoleLogger.showError(ex.getMessage());
}
return true;
} else if (args[0].equalsIgnoreCase("changepassword") || args[0].equalsIgnoreCase("cp")) { } else if (args[0].equalsIgnoreCase("changepassword") || args[0].equalsIgnoreCase("cp")) {
if (args.length != 3) { if (args.length != 3) {
sender.sendMessage("Usage: /authme changepassword playername newpassword"); sender.sendMessage("Usage: /authme changepassword playername newpassword");
@ -467,8 +500,36 @@ public class AdminCommand implements CommandExecutor {
m._(sender, "error"); m._(sender, "error");
return true; return true;
} }
Player target = Bukkit.getPlayer(name);
PlayerCache.getInstance().removePlayer(name); PlayerCache.getInstance().removePlayer(name);
sender.sendMessage("unregistered"); Utils.getInstance().setGroup(name, groupType.UNREGISTERED);
if (target != null) {
if (target.isOnline()) {
if (Settings.isTeleportToSpawnEnabled) {
Location spawn = plugin.getSpawnLocation(name, target.getWorld());
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(target, target.getLocation(), spawn, false);
plugin.getServer().getPluginManager().callEvent(tpEvent);
if(!tpEvent.isCancelled()) {
target.teleport(tpEvent.getTo());
}
}
LimboCache.getInstance().addLimboPlayer(target);
int delay = Settings.getRegistrationTimeout * 20;
int interval = Settings.getWarnMessageInterval;
BukkitScheduler sched = sender.getServer().getScheduler();
if (delay != 0) {
int id = sched.scheduleSyncDelayedTask(plugin, new TimeoutTask(plugin, name), delay);
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id);
}
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(sched.scheduleSyncDelayedTask(plugin, new MessageTask(plugin, name, m._("reg_msg"), interval)));
m._(target, "unregistered");
} else {
// Player isn't online, do nothing else
}
} else {
// Player does not exist, do nothing else
}
m._(sender, "unregistered");
ConsoleLogger.info(args[1] + " unregistered"); ConsoleLogger.info(args[1] + " unregistered");
return true; return true;
} else if (args[0].equalsIgnoreCase("purgelastpos")){ } else if (args[0].equalsIgnoreCase("purgelastpos")){

View File

@ -59,6 +59,12 @@ public class EmailCommand implements CommandExecutor {
m._(player, "usage_email_add"); m._(player, "usage_email_add");
return true; return true;
} }
if(Settings.getmaxRegPerEmail > 0) {
if (!plugin.authmePermissible(sender, "authme.allow2accounts") && data.getAllAuthsByEmail(args[1]).size() >= Settings.getmaxRegPerEmail) {
m._(player, "max_reg");
return true;
}
}
if(args[1].equals(args[2]) && PlayerCache.getInstance().isAuthenticated(name)) { if(args[1].equals(args[2]) && PlayerCache.getInstance().isAuthenticated(name)) {
PlayerAuth auth = PlayerCache.getInstance().getAuth(name); PlayerAuth auth = PlayerCache.getInstance().getAuth(name);
if (auth.getEmail() == null || (!auth.getEmail().equals("your@email.com") && !auth.getEmail().isEmpty())) { if (auth.getEmail() == null || (!auth.getEmail().equals("your@email.com") && !auth.getEmail().isEmpty())) {
@ -87,6 +93,12 @@ public class EmailCommand implements CommandExecutor {
} }
} }
} else if(args[0].equalsIgnoreCase("change") && args.length == 3 ) { } else if(args[0].equalsIgnoreCase("change") && args.length == 3 ) {
if(Settings.getmaxRegPerEmail > 0) {
if (!plugin.authmePermissible(sender, "authme.allow2accounts") && data.getAllAuthsByEmail(args[1]).size() >= Settings.getmaxRegPerEmail) {
m._(player, "max_reg");
return true;
}
}
if(PlayerCache.getInstance().isAuthenticated(name)) { if(PlayerCache.getInstance().isAuthenticated(name)) {
PlayerAuth auth = PlayerCache.getInstance().getAuth(name); PlayerAuth auth = PlayerCache.getInstance().getAuth(name);
if (auth.getEmail() == null || auth.getEmail().equals("your@email.com") || auth.getEmail().isEmpty()) { if (auth.getEmail() == null || auth.getEmail().equals("your@email.com") || auth.getEmail().isEmpty()) {

View File

@ -23,7 +23,6 @@ import fr.xephi.authme.events.AuthMeTeleportEvent;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.settings.PlayersLogs; import fr.xephi.authme.settings.PlayersLogs;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.Spawn;
import fr.xephi.authme.task.MessageTask; import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.task.TimeoutTask; import fr.xephi.authme.task.TimeoutTask;
@ -73,12 +72,7 @@ public class LogoutCommand implements CommandExecutor {
PlayerCache.getInstance().removePlayer(name); PlayerCache.getInstance().removePlayer(name);
if (Settings.isTeleportToSpawnEnabled) { if (Settings.isTeleportToSpawnEnabled) {
Location spawnLoc = player.getWorld().getSpawnLocation(); Location spawnLoc = plugin.getSpawnLocation(name, player.getWorld());
if (plugin.essentialsSpawn != null) {
spawnLoc = plugin.essentialsSpawn;
}
if (Spawn.getInstance().getLocation() != null)
spawnLoc = Spawn.getInstance().getLocation();
AuthMeTeleportEvent tpEvent = new AuthMeTeleportEvent(player, spawnLoc); AuthMeTeleportEvent tpEvent = new AuthMeTeleportEvent(player, spawnLoc);
plugin.getServer().getPluginManager().callEvent(tpEvent); plugin.getServer().getPluginManager().callEvent(tpEvent);
if(!tpEvent.isCancelled()) { if(!tpEvent.isCancelled()) {

View File

@ -72,12 +72,21 @@ public class UnregisterCommand implements CommandExecutor {
return true; return true;
} }
if(Settings.isForcedRegistrationEnabled) { if(Settings.isForcedRegistrationEnabled) {
if (Settings.isTeleportToSpawnEnabled) {
Location spawn = plugin.getSpawnLocation(name, player.getWorld());
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawn, false);
plugin.getServer().getPluginManager().callEvent(tpEvent);
if(!tpEvent.isCancelled()) {
player.teleport(tpEvent.getTo());
}
}
player.getInventory().setContents(new ItemStack[36]); player.getInventory().setContents(new ItemStack[36]);
player.getInventory().setArmorContents(new ItemStack[4]); player.getInventory().setArmorContents(new ItemStack[4]);
player.saveData(); player.saveData();
PlayerCache.getInstance().removePlayer(player.getName().toLowerCase()); PlayerCache.getInstance().removePlayer(player.getName().toLowerCase());
if (!Settings.getRegisteredGroup.isEmpty())
Utils.getInstance().setGroup(player, groupType.UNREGISTERED);
LimboCache.getInstance().addLimboPlayer(player); LimboCache.getInstance().addLimboPlayer(player);
Utils.getInstance().setGroup(player, groupType.UNREGISTERED);
int delay = Settings.getRegistrationTimeout * 20; int delay = Settings.getRegistrationTimeout * 20;
int interval = Settings.getWarnMessageInterval; int interval = Settings.getWarnMessageInterval;
BukkitScheduler sched = sender.getServer().getScheduler(); BukkitScheduler sched = sender.getServer().getScheduler();
@ -86,14 +95,11 @@ public class UnregisterCommand implements CommandExecutor {
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id); LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id);
} }
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(sched.scheduleSyncDelayedTask(plugin, new MessageTask(plugin, name, m._("reg_msg"), interval))); LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(sched.scheduleSyncDelayedTask(plugin, new MessageTask(plugin, name, m._("reg_msg"), interval)));
if(!Settings.unRegisteredGroup.isEmpty()){ m._(player, "unregistered");
Utils.getInstance().setGroup(player, Utils.groupType.UNREGISTERED); ConsoleLogger.info(player.getDisplayName() + " unregistered himself");
} if(plugin.notifications != null) {
m._(player, "unregistered"); plugin.notifications.showNotification(new Notification("[AuthMe] " + player.getName() + " unregistered himself!"));
ConsoleLogger.info(player.getDisplayName() + " unregistered himself"); }
if(plugin.notifications != null) {
plugin.notifications.showNotification(new Notification("[AuthMe] " + player.getName() + " unregistered himself!"));
}
return true; return true;
} }
if(!Settings.unRegisteredGroup.isEmpty()){ if(!Settings.unRegisteredGroup.isEmpty()){
@ -114,7 +120,7 @@ public class UnregisterCommand implements CommandExecutor {
plugin.notifications.showNotification(new Notification("[AuthMe] " + player.getName() + " unregistered himself!")); plugin.notifications.showNotification(new Notification("[AuthMe] " + player.getName() + " unregistered himself!"));
} }
if (Settings.isTeleportToSpawnEnabled) { if (Settings.isTeleportToSpawnEnabled) {
Location spawn = plugin.getSpawnLocation(player.getWorld()); Location spawn = plugin.getSpawnLocation(name, player.getWorld());
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawn, false); SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawn, false);
plugin.getServer().getPluginManager().callEvent(tpEvent); plugin.getServer().getPluginManager().callEvent(tpEvent);
if(!tpEvent.isCancelled()) { if(!tpEvent.isCancelled()) {

View File

@ -14,7 +14,7 @@ public class CacheDataSource implements DataSource {
private DataSource source; private DataSource source;
public AuthMe plugin; public AuthMe plugin;
private final HashMap<String, PlayerAuth> cache = new HashMap<String, PlayerAuth>(); private HashMap<String, PlayerAuth> cache = new HashMap<String, PlayerAuth>();
public CacheDataSource(AuthMe plugin, DataSource source) { public CacheDataSource(AuthMe plugin, DataSource source) {
this.plugin = plugin; this.plugin = plugin;
@ -23,16 +23,18 @@ public class CacheDataSource implements DataSource {
@Override @Override
public synchronized boolean isAuthAvailable(String user) { public synchronized boolean isAuthAvailable(String user) {
return cache.containsKey(user) ? true : source.isAuthAvailable(user); if (cache.containsKey(user.toLowerCase())) return true;
return source.isAuthAvailable(user.toLowerCase());
} }
@Override @Override
public synchronized PlayerAuth getAuth(String user) { public synchronized PlayerAuth getAuth(String user) {
if(cache.containsKey(user)) { if(cache.containsKey(user.toLowerCase())) {
return cache.get(user); return cache.get(user.toLowerCase());
} else { } else {
PlayerAuth auth = source.getAuth(user); PlayerAuth auth = source.getAuth(user.toLowerCase());
cache.put(user, auth); if (auth != null)
cache.put(user.toLowerCase(), auth);
return auth; return auth;
} }
} }
@ -49,7 +51,8 @@ public class CacheDataSource implements DataSource {
@Override @Override
public synchronized boolean updatePassword(PlayerAuth auth) { public synchronized boolean updatePassword(PlayerAuth auth) {
if (source.updatePassword(auth)) { if (source.updatePassword(auth)) {
cache.get(auth.getNickname()).setHash(auth.getHash()); if (cache.containsKey(auth.getNickname().toLowerCase()))
cache.get(auth.getNickname()).setHash(auth.getHash());
return true; return true;
} }
return false; return false;
@ -58,8 +61,10 @@ public class CacheDataSource implements DataSource {
@Override @Override
public boolean updateSession(PlayerAuth auth) { public boolean updateSession(PlayerAuth auth) {
if (source.updateSession(auth)) { if (source.updateSession(auth)) {
cache.get(auth.getNickname()).setIp(auth.getIp()); if (cache.containsKey(auth.getNickname().toLowerCase())) {
cache.get(auth.getNickname()).setLastLogin(auth.getLastLogin()); cache.get(auth.getNickname()).setIp(auth.getIp());
cache.get(auth.getNickname()).setLastLogin(auth.getLastLogin());
}
return true; return true;
} }
return false; return false;
@ -68,10 +73,12 @@ public class CacheDataSource implements DataSource {
@Override @Override
public boolean updateQuitLoc(PlayerAuth auth) { public boolean updateQuitLoc(PlayerAuth auth) {
if (source.updateQuitLoc(auth)) { if (source.updateQuitLoc(auth)) {
cache.get(auth.getNickname()).setQuitLocX(auth.getQuitLocX()); if (cache.containsKey(auth.getNickname().toLowerCase())) {
cache.get(auth.getNickname()).setQuitLocY(auth.getQuitLocY()); cache.get(auth.getNickname()).setQuitLocX(auth.getQuitLocX());
cache.get(auth.getNickname()).setQuitLocZ(auth.getQuitLocZ()); cache.get(auth.getNickname()).setQuitLocY(auth.getQuitLocY());
cache.get(auth.getNickname()).setWorld(auth.getWorld()); cache.get(auth.getNickname()).setQuitLocZ(auth.getQuitLocZ());
cache.get(auth.getNickname()).setWorld(auth.getWorld());
}
return true; return true;
} }
return false; return false;
@ -110,8 +117,8 @@ public class CacheDataSource implements DataSource {
@Override @Override
public synchronized boolean removeAuth(String user) { public synchronized boolean removeAuth(String user) {
if (source.removeAuth(user)) { if (source.removeAuth(user.toLowerCase())) {
cache.remove(user); cache.remove(user.toLowerCase());
return true; return true;
} }
return false; return false;
@ -125,6 +132,7 @@ public class CacheDataSource implements DataSource {
@Override @Override
public void reload() { public void reload() {
cache.clear(); cache.clear();
source.reload();
for (Player player : plugin.getServer().getOnlinePlayers()) { for (Player player : plugin.getServer().getOnlinePlayers()) {
String user = player.getName().toLowerCase(); String user = player.getName().toLowerCase();
if (PlayerCache.getInstance().isAuthenticated(user)) { if (PlayerCache.getInstance().isAuthenticated(user)) {
@ -141,7 +149,8 @@ public class CacheDataSource implements DataSource {
@Override @Override
public synchronized boolean updateEmail(PlayerAuth auth) { public synchronized boolean updateEmail(PlayerAuth auth) {
if(source.updateEmail(auth)) { if(source.updateEmail(auth)) {
cache.get(auth.getNickname()).setEmail(auth.getEmail()); if (cache.containsKey(auth.getNickname().toLowerCase()))
cache.get(auth.getNickname()).setEmail(auth.getEmail());
return true; return true;
} }
return false; return false;
@ -150,7 +159,8 @@ public class CacheDataSource implements DataSource {
@Override @Override
public synchronized boolean updateSalt(PlayerAuth auth) { public synchronized boolean updateSalt(PlayerAuth auth) {
if(source.updateSalt(auth)) { if(source.updateSalt(auth)) {
cache.get(auth.getNickname()).setSalt(auth.getSalt()); if (cache.containsKey(auth.getNickname().toLowerCase()))
cache.get(auth.getNickname()).setSalt(auth.getSalt());
return true; return true;
} }
return false; return false;

View File

@ -604,6 +604,17 @@ public class MySQLDataSource implements DataSource {
@Override @Override
public void reload() { public void reload() {
try {
reconnect(true);
} catch (Exception e) {
ConsoleLogger.showError(e.getMessage());
if (Settings.isStopEnabled) {
ConsoleLogger.showError("Can't reconnect to MySQL database... Please check your MySQL informations ! SHUTDOWN...");
AuthMe.getInstance().getServer().shutdown();
}
if (!Settings.isStopEnabled)
AuthMe.getInstance().getServer().getPluginManager().disablePlugin(AuthMe.getInstance());
}
} }
private void close(Statement st) { private void close(Statement st) {
@ -749,7 +760,7 @@ public class MySQLDataSource implements DataSource {
} catch (Exception te) { } catch (Exception te) {
try { try {
con = null; con = null;
reconnect(); reconnect(false);
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.showError(e.getMessage()); ConsoleLogger.showError(e.getMessage());
if (Settings.isStopEnabled) { if (Settings.isStopEnabled) {
@ -765,7 +776,7 @@ public class MySQLDataSource implements DataSource {
throw new AssertionError(ae.getMessage()); throw new AssertionError(ae.getMessage());
try { try {
con = null; con = null;
reconnect(); reconnect(false);
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.showError(e.getMessage()); ConsoleLogger.showError(e.getMessage());
if (Settings.isStopEnabled) { if (Settings.isStopEnabled) {
@ -781,7 +792,7 @@ public class MySQLDataSource implements DataSource {
return con; return con;
} }
private synchronized void reconnect() throws ClassNotFoundException, SQLException, TimeoutException { private synchronized void reconnect(boolean reload) throws ClassNotFoundException, SQLException, TimeoutException {
conPool.dispose(); conPool.dispose();
Class.forName("com.mysql.jdbc.Driver"); Class.forName("com.mysql.jdbc.Driver");
MysqlConnectionPoolDataSource dataSource = new MysqlConnectionPoolDataSource(); MysqlConnectionPoolDataSource dataSource = new MysqlConnectionPoolDataSource();
@ -791,7 +802,8 @@ public class MySQLDataSource implements DataSource {
dataSource.setUser(username); dataSource.setUser(username);
dataSource.setPassword(password); dataSource.setPassword(password);
conPool = new MiniConnectionPoolManager(dataSource, 10); conPool = new MiniConnectionPoolManager(dataSource, 10);
ConsoleLogger.info("ConnectionPool was unavailable... Reconnected!"); if(!reload)
ConsoleLogger.info("ConnectionPool was unavailable... Reconnected!");
} }
} }

View File

@ -366,7 +366,7 @@ public class AuthMePlayerListener implements Listener {
} }
int radius = Settings.getMovementRadius; int radius = Settings.getMovementRadius;
Location spawn = plugin.getSpawnLocation(player.getWorld()); Location spawn = plugin.getSpawnLocation(name, player.getWorld());
if (!event.getPlayer().getWorld().equals(spawn.getWorld())) { if (!event.getPlayer().getWorld().equals(spawn.getWorld())) {
event.getPlayer().teleport(spawn); event.getPlayer().teleport(spawn);
@ -542,9 +542,9 @@ public class AuthMePlayerListener implements Listener {
} }
Player player = event.getPlayer(); Player player = event.getPlayer();
World world = player.getWorld(); World world = player.getWorld();
Location spawnLoc = plugin.getSpawnLocation(world);
gm = player.getGameMode();
final String name = player.getName().toLowerCase(); final String name = player.getName().toLowerCase();
Location spawnLoc = plugin.getSpawnLocation(name, world);
gm = player.getGameMode();
gameMode.put(name, gm); gameMode.put(name, gm);
BukkitScheduler sched = plugin.getServer().getScheduler(); BukkitScheduler sched = plugin.getServer().getScheduler();
@ -588,6 +588,8 @@ public class AuthMePlayerListener implements Listener {
PlayerCache.getInstance().addPlayer(auth); PlayerCache.getInstance().addPlayer(auth);
} }
m._(player, "valid_session"); m._(player, "valid_session");
// Restore Permission Group
utils.setGroup(player, Utils.groupType.LOGGEDIN);
return; return;
} else if (!Settings.sessionExpireOnIpChange){ } else if (!Settings.sessionExpireOnIpChange){
GameMode gM = gameMode.get(name); GameMode gM = gameMode.get(name);
@ -646,9 +648,20 @@ public class AuthMePlayerListener implements Listener {
if(!Settings.unRegisteredGroup.isEmpty()){ if(!Settings.unRegisteredGroup.isEmpty()){
utils.setGroup(player, Utils.groupType.UNREGISTERED); utils.setGroup(player, Utils.groupType.UNREGISTERED);
} }
if (Settings.isTeleportToSpawnEnabled || (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName()))) {
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, PlayerCache.getInstance().isAuthenticated(name));
plugin.getServer().getPluginManager().callEvent(tpEvent);
if(!tpEvent.isCancelled()) {
if (!tpEvent.getTo().getWorld().getChunkAt(tpEvent.getTo()).isLoaded()) {
tpEvent.getTo().getWorld().getChunkAt(tpEvent.getTo()).load();
}
player.teleport(tpEvent.getTo());
}
}
if (!Settings.isForcedRegistrationEnabled) { if (!Settings.isForcedRegistrationEnabled) {
return; return;
} }
} }
if(Settings.protectInventoryBeforeLogInEnabled) { if(Settings.protectInventoryBeforeLogInEnabled) {
try { try {
@ -763,8 +776,8 @@ public class AuthMePlayerListener implements Listener {
playerBackup.removeCache(name); playerBackup.removeCache(name);
} }
} }
PlayerCache.getInstance().removePlayer(name);
try { try {
PlayerCache.getInstance().removePlayer(name);
PlayersLogs.players.remove(player.getName()); PlayersLogs.players.remove(player.getName());
PlayersLogs.getInstance().save(); PlayersLogs.getInstance().save();
player.getVehicle().eject(); player.getVehicle().eject();
@ -1086,7 +1099,7 @@ public class AuthMePlayerListener implements Listener {
if (!Settings.isForcedRegistrationEnabled) if (!Settings.isForcedRegistrationEnabled)
return; return;
Location spawn = plugin.getSpawnLocation(player.getWorld()); Location spawn = plugin.getSpawnLocation(name, player.getWorld());
if(Settings.isSaveQuitLocationEnabled && data.isAuthAvailable(name)) { if(Settings.isSaveQuitLocationEnabled && data.isAuthAvailable(name)) {
final PlayerAuth auth = new PlayerAuth(name,spawn.getX(),spawn.getY(),spawn.getZ(),spawn.getWorld().getName()); final PlayerAuth auth = new PlayerAuth(name,spawn.getX(),spawn.getY(),spawn.getZ(),spawn.getWorld().getName());
try { try {

View File

@ -194,19 +194,19 @@ public class AsyncronousLogin {
if (auth == null) { if (auth == null) {
return; return;
} }
if (this.database.getAllAuthsByName(auth).isEmpty() || this.database.getAllAuthsByName(auth) == null) { List<String> auths = this.database.getAllAuthsByName(auth);
if (auths.isEmpty() || auths == null) {
return; return;
} }
if (this.database.getAllAuthsByName(auth).size() == 1) { if (auths.size() == 1) {
return; return;
} }
List<String> accountList = this.database.getAllAuthsByName(auth);
String message = "[AuthMe] "; String message = "[AuthMe] ";
int i = 0; int i = 0;
for (String account : accountList) { for (String account : auths) {
i++; i++;
message = message + account; message = message + account;
if (i != accountList.size()) { if (i != auths.size()) {
message = message + ", "; message = message + ", ";
} else { } else {
message = message + "."; message = message + ".";
@ -215,7 +215,7 @@ public class AsyncronousLogin {
for (Player player : plugin.getServer().getOnlinePlayers()) { for (Player player : plugin.getServer().getOnlinePlayers()) {
if (plugin.authmePermissible(player, "authme.seeOtherAccounts")) { if (plugin.authmePermissible(player, "authme.seeOtherAccounts")) {
player.sendMessage("[AuthMe] The player " + auth.getNickname() + " has " player.sendMessage("[AuthMe] The player " + auth.getNickname() + " has "
+ accountList.size() + " accounts"); + auths.size() + " accounts");
player.sendMessage(message); player.sendMessage(message);
} }
} }

View File

@ -68,7 +68,7 @@ public class ProcessSyncronousPlayerLogin implements Runnable {
} }
} }
protected void teleportToSpawn() { protected void teleportToSpawn() {
Location spawnL = plugin.getSpawnLocation(player.getWorld()); Location spawnL = plugin.getSpawnLocation(name, player.getWorld());
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnL, true); SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnL, true);
pm.callEvent(tpEvent); pm.callEvent(tpEvent);
if (!tpEvent.isCancelled()) { if (!tpEvent.isCancelled()) {
@ -187,7 +187,7 @@ public class ProcessSyncronousPlayerLogin implements Runnable {
if(Settings.useWelcomeMessage) if(Settings.useWelcomeMessage)
if(Settings.broadcastWelcomeMessage) { if(Settings.broadcastWelcomeMessage) {
for (String s : Settings.welcomeMsg) { for (String s : Settings.welcomeMsg) {
Bukkit.getServer().broadcastMessage(s); Bukkit.getServer().broadcastMessage(plugin.replaceAllInfos(s, player));
} }
} else { } else {
for (String s : Settings.welcomeMsg) { for (String s : Settings.welcomeMsg) {

View File

@ -66,17 +66,24 @@ public class AsyncronousRegister {
} }
if(Settings.getmaxRegPerIp > 0 ){ if(Settings.getmaxRegPerIp > 0 ){
if(!plugin.authmePermissible(player, "authme.allow2accounts") && database.getAllAuthsByIp(getIp()).size() >= Settings.getmaxRegPerIp) { if(!plugin.authmePermissible(player, "authme.allow2accounts") && database.getAllAuthsByIp(getIp()).size() >= Settings.getmaxRegPerIp && !getIp().equalsIgnoreCase("127.0.0.1") && !getIp().equalsIgnoreCase("localhost")) {
m._(player, "max_reg"); m._(player, "max_reg");
allowRegister = false; allowRegister = false;
} }
} }
} }
public void process() { public void process() {
preRegister(); preRegister();
if(!allowRegister) return; if(!allowRegister) return;
if(!email.isEmpty() && email != "") { if(!email.isEmpty() && email != "") {
if(Settings.getmaxRegPerEmail > 0) {
if (!plugin.authmePermissible(player, "authme.allow2accounts") && database.getAllAuthsByEmail(email).size() >= Settings.getmaxRegPerEmail) {
m._(player, "max_reg");
return;
}
}
emailRegister(); emailRegister();
return; return;
} }

View File

@ -49,7 +49,7 @@ public class ProcessSyncronousEmailRegister implements Runnable {
if (Settings.isTeleportToSpawnEnabled) { if (Settings.isTeleportToSpawnEnabled) {
World world = player.getWorld(); World world = player.getWorld();
Location loca = plugin.getSpawnLocation(world); Location loca = plugin.getSpawnLocation(name, world);
RegisterTeleportEvent tpEvent = new RegisterTeleportEvent(player, loca); RegisterTeleportEvent tpEvent = new RegisterTeleportEvent(player, loca);
plugin.getServer().getPluginManager().callEvent(tpEvent); plugin.getServer().getPluginManager().callEvent(tpEvent);
if(!tpEvent.isCancelled()) { if(!tpEvent.isCancelled()) {

View File

@ -44,7 +44,7 @@ public class ProcessSyncronousPasswordRegister implements Runnable {
player.setGameMode(limbo.getGameMode()); player.setGameMode(limbo.getGameMode());
if (Settings.isTeleportToSpawnEnabled) { if (Settings.isTeleportToSpawnEnabled) {
World world = player.getWorld(); World world = player.getWorld();
Location loca = plugin.getSpawnLocation(world); Location loca = plugin.getSpawnLocation(name, world);
RegisterTeleportEvent tpEvent = new RegisterTeleportEvent(player, loca); RegisterTeleportEvent tpEvent = new RegisterTeleportEvent(player, loca);
plugin.getServer().getPluginManager().callEvent(tpEvent); plugin.getServer().getPluginManager().callEvent(tpEvent);
if(!tpEvent.isCancelled()) { if(!tpEvent.isCancelled()) {

View File

@ -1,9 +1,6 @@
package fr.xephi.authme.settings; package fr.xephi.authme.settings;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -14,7 +11,6 @@ import org.bukkit.Location;
public class Spawn extends CustomConfiguration { public class Spawn extends CustomConfiguration {
private static Spawn spawn; private static Spawn spawn;
private static List<String> emptyList = new ArrayList<String>();
public Spawn() { public Spawn() {
super(new File("./plugins/AuthMe/spawn.yml")); super(new File("./plugins/AuthMe/spawn.yml"));
@ -26,7 +22,6 @@ public class Spawn extends CustomConfiguration {
private void saveDefault() { private void saveDefault() {
if (!contains("spawn")) { if (!contains("spawn")) {
set("spawn", emptyList);
set("spawn.world", ""); set("spawn.world", "");
set("spawn.x", ""); set("spawn.x", "");
set("spawn.y", ""); set("spawn.y", "");
@ -35,6 +30,15 @@ public class Spawn extends CustomConfiguration {
set("spawn.pitch", ""); set("spawn.pitch", "");
save(); save();
} }
if (!contains("firstspawn")) {
set("firstspawn.world", "");
set("firstspawn.x", "");
set("firstspawn.y", "");
set("firstspawn.z", "");
set("firstspawn.yaw", "");
set("firstspawn.pitch", "");
save();
}
} }
public static Spawn getInstance() { public static Spawn getInstance() {
@ -59,7 +63,27 @@ public class Spawn extends CustomConfiguration {
} }
} }
public boolean setFirstSpawn(Location location) {
try {
set("firstspawn.world", location.getWorld().getName());
set("firstspawn.x", location.getX());
set("firstspawn.y", location.getY());
set("firstspawn.z", location.getZ());
set("firstspawn.yaw", location.getYaw());
set("firstspawn.pitch", location.getPitch());
save();
return true;
} catch (NullPointerException npe) {
return false;
}
}
@Deprecated
public Location getLocation() { public Location getLocation() {
return getSpawn();
}
public Location getSpawn() {
try { try {
if (this.getString("spawn.world").isEmpty() || this.getString("spawn.world") == "") return null; if (this.getString("spawn.world").isEmpty() || this.getString("spawn.world") == "") return null;
Location location = new Location(Bukkit.getWorld(this.getString("spawn.world")), this.getDouble("spawn.x"), this.getDouble("spawn.y"), this.getDouble("spawn.z"), Float.parseFloat(this.getString("spawn.yaw")), Float.parseFloat(this.getString("spawn.pitch"))); Location location = new Location(Bukkit.getWorld(this.getString("spawn.world")), this.getDouble("spawn.x"), this.getDouble("spawn.y"), this.getDouble("spawn.z"), Float.parseFloat(this.getString("spawn.yaw")), Float.parseFloat(this.getString("spawn.pitch")));
@ -71,4 +95,16 @@ public class Spawn extends CustomConfiguration {
} }
} }
public Location getFirstSpawn() {
try {
if (this.getString("firstspawn.world").isEmpty() || this.getString("firstspawn.world") == "") return null;
Location location = new Location(Bukkit.getWorld(this.getString("firstspawn.world")), this.getDouble("firstspawn.x"), this.getDouble("firstspawn.y"), this.getDouble("firstspawn.z"), Float.parseFloat(this.getString("firstspawn.yaw")), Float.parseFloat(this.getString("firstspawn.pitch")));
return location;
} catch (NullPointerException npe) {
return null;
} catch (NumberFormatException nfe) {
return null;
}
}
} }

View File

@ -64,7 +64,6 @@ public class MySQLThread extends Thread implements DataSource {
this.columnEmail = Settings.getMySQLColumnEmail; this.columnEmail = Settings.getMySQLColumnEmail;
this.columnOthers = Settings.getMySQLOtherUsernameColumn; this.columnOthers = Settings.getMySQLOtherUsernameColumn;
this.columnID = Settings.getMySQLColumnId; this.columnID = Settings.getMySQLColumnId;
try { try {
this.connect(); this.connect();
this.setup(); this.setup();
@ -635,6 +634,17 @@ public class MySQLThread extends Thread implements DataSource {
@Override @Override
public void reload() { public void reload() {
try {
reconnect(true);
} catch (Exception e) {
ConsoleLogger.showError(e.getMessage());
if (Settings.isStopEnabled) {
ConsoleLogger.showError("Can't reconnect to MySQL database... Please check your MySQL informations ! SHUTDOWN...");
AuthMe.getInstance().getServer().shutdown();
}
if (!Settings.isStopEnabled)
AuthMe.getInstance().getServer().getPluginManager().disablePlugin(AuthMe.getInstance());
}
} }
private void close(Statement st) { private void close(Statement st) {
@ -780,7 +790,7 @@ public class MySQLThread extends Thread implements DataSource {
} catch (Exception te) { } catch (Exception te) {
try { try {
con = null; con = null;
reconnect(); reconnect(false);
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.showError(e.getMessage()); ConsoleLogger.showError(e.getMessage());
if (Settings.isStopEnabled) { if (Settings.isStopEnabled) {
@ -796,7 +806,7 @@ public class MySQLThread extends Thread implements DataSource {
throw new AssertionError(ae.getMessage()); throw new AssertionError(ae.getMessage());
try { try {
con = null; con = null;
reconnect(); reconnect(false);
} catch (Exception e) { } catch (Exception e) {
ConsoleLogger.showError(e.getMessage()); ConsoleLogger.showError(e.getMessage());
if (Settings.isStopEnabled) { if (Settings.isStopEnabled) {
@ -812,7 +822,7 @@ public class MySQLThread extends Thread implements DataSource {
return con; return con;
} }
private synchronized void reconnect() throws ClassNotFoundException, SQLException, TimeoutException { private synchronized void reconnect(boolean reload) throws ClassNotFoundException, SQLException, TimeoutException {
conPool.dispose(); conPool.dispose();
Class.forName("com.mysql.jdbc.Driver"); Class.forName("com.mysql.jdbc.Driver");
MysqlConnectionPoolDataSource dataSource = new MysqlConnectionPoolDataSource(); MysqlConnectionPoolDataSource dataSource = new MysqlConnectionPoolDataSource();
@ -822,7 +832,8 @@ public class MySQLThread extends Thread implements DataSource {
dataSource.setUser(username); dataSource.setUser(username);
dataSource.setPassword(password); dataSource.setPassword(password);
conPool = new MiniConnectionPoolManager(dataSource, 10); conPool = new MiniConnectionPoolManager(dataSource, 10);
ConsoleLogger.info("ConnectionPool was unavailable... Reconnected!"); if (!reload)
ConsoleLogger.info("ConnectionPool was unavailable... Reconnected!");
} }
} }

View File

@ -3,7 +3,7 @@ author: Xephi59
website: http://dev.bukkit.org/bukkit-plugins/authme-reloaded/ website: http://dev.bukkit.org/bukkit-plugins/authme-reloaded/
description: AuthMe prevents people, which aren't logged in, from doing stuff like placing blocks, moving, typing commands or seeing the inventory of the current player. description: AuthMe prevents people, which aren't logged in, from doing stuff like placing blocks, moving, typing commands or seeing the inventory of the current player.
main: fr.xephi.authme.AuthMe main: fr.xephi.authme.AuthMe
version: 3.3.2 version: 3.3.3
softdepend: [Vault, ChestShop, Spout, Multiverse-Core, Notifications, Citizens, CombatTag, Essentials, EssentialsSpawn] softdepend: [Vault, ChestShop, Spout, Multiverse-Core, Notifications, Citizens, CombatTag, Essentials, EssentialsSpawn]
commands: commands:
register: register:
@ -159,3 +159,9 @@ permissions:
authme.admin.royalauth: authme.admin.royalauth:
description: Import RoyalAuth database into AuthMe description: Import RoyalAuth database into AuthMe
default: op default: op
authme.admin.setfirstspawn:
description: Set the AuthMe First Spawn Point
default: op
authme.admin.firstspawn:
description: Teleport to AuthMe First Spawn Point
default: op

View File

@ -5,3 +5,10 @@ spawn:
z: '' z: ''
yaw: '' yaw: ''
pitch: '' pitch: ''
firstspawn:
world: ''
x: ''
y: ''
z: ''
yaw: ''
pitch: ''