Replacing old inventory protecting with safe packet modifications using ProtocolLib.

Instead of clearing the inventory of players and storing it's contents in a file, we now prevent
the server from sending the inventory packet if the player is not logged in. The player will
see a empty inventory, but has still his items stored on the server. Therefore we don't
need to modify the player's inventory and we won't make any inventory corrupted.

Fixes Xephi/AuthMeReloaded#203,
Fixes Xephi/AuthMeReloaded#193,
Fixes Xephi/AuthMeReloaded#191,
Fixes Xephi/AuthMeReloaded#148

Remove dead code + Fix empty inventory on the unregister command

Fix NPE if ProtocolLib isn't enabled or installed
This commit is contained in:
games647 2015-09-30 18:55:41 +02:00
parent a013a6c54f
commit 86ff20b6c9
19 changed files with 1464 additions and 1537 deletions

View File

@ -294,6 +294,14 @@
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<!--ProtocolLib http://dev.bukkit.org/bukkit-plugins/protocollib/ -->
<dependency>
<groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId>
<version>3.4.0</version>
<optional>true</optional>
</dependency>
<!-- Vault, http://dev.bukkit.org/bukkit-plugins/vault/ --> <!-- Vault, http://dev.bukkit.org/bukkit-plugins/vault/ -->
<dependency> <dependency>
<groupId>net.milkbowl.vault</groupId> <groupId>net.milkbowl.vault</groupId>

File diff suppressed because it is too large Load Diff

View File

@ -1,36 +1,17 @@
package fr.xephi.authme.cache.backup; package fr.xephi.authme.cache.backup;
import org.bukkit.inventory.ItemStack;
public class DataFileCache { public class DataFileCache {
private ItemStack[] inventory;
private ItemStack[] armor;
private String group; private String group;
private boolean operator; private boolean operator;
private boolean flying; private boolean flying;
public DataFileCache(ItemStack[] inventory, ItemStack[] armor) { public DataFileCache(String group, boolean operator, boolean flying) {
this(inventory, armor, "", false, false);
}
public DataFileCache(ItemStack[] inventory, ItemStack[] armor,
String group, boolean operator, boolean flying) {
this.inventory = inventory;
this.armor = armor;
this.group = group; this.group = group;
this.operator = operator; this.operator = operator;
this.flying = flying; this.flying = flying;
} }
public ItemStack[] getInventory() {
return inventory;
}
public ItemStack[] getArmour() {
return armor;
}
public String getGroup() { public String getGroup() {
return group; return group;
} }

View File

@ -3,20 +3,13 @@ package fr.xephi.authme.cache.backup;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.google.common.io.Files; import com.google.common.io.Files;
import com.google.gson.*; import com.google.gson.*;
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.settings.Settings; import fr.xephi.authme.settings.Settings;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.util.io.BukkitObjectInputStream;
import org.bukkit.util.io.BukkitObjectOutputStream;
import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder;
import java.io.ByteArrayInputStream; import org.bukkit.entity.Player;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Type; import java.lang.reflect.Type;
@ -24,11 +17,9 @@ import java.lang.reflect.Type;
public class JsonCache { public class JsonCache {
private final Gson gson; private final Gson gson;
private final AuthMe plugin;
private final File cacheDir; private final File cacheDir;
public JsonCache(AuthMe plugin) { public JsonCache() {
this.plugin = plugin;
cacheDir = Settings.CACHE_FOLDER; cacheDir = Settings.CACHE_FOLDER;
if (!cacheDir.exists() && !cacheDir.isDirectory() && !cacheDir.mkdir()) { if (!cacheDir.exists() && !cacheDir.isDirectory() && !cacheDir.mkdir()) {
ConsoleLogger.showError("Failed to create cache directory."); ConsoleLogger.showError("Failed to create cache directory.");
@ -99,49 +90,8 @@ public class JsonCache {
jsonObject.addProperty("operator", dataFileCache.getOperator()); jsonObject.addProperty("operator", dataFileCache.getOperator());
jsonObject.addProperty("flying", dataFileCache.isFlying()); jsonObject.addProperty("flying", dataFileCache.isFlying());
JsonArray arr;
ItemStack[] contents;
// inventory
contents = dataFileCache.getInventory();
arr = new JsonArray();
putItems(contents, arr);
jsonObject.add("inventory", arr);
// armour
contents = dataFileCache.getArmour();
arr = new JsonArray();
putItems(contents, arr);
jsonObject.add("armour", arr);
return jsonObject; return jsonObject;
} }
private void putItems(ItemStack[] contents, JsonArray target) {
for (ItemStack item : contents) {
if (item == null) {
item = new ItemStack(Material.AIR);
}
JsonObject val = new JsonObject();
if (item.getType() == Material.SKULL_ITEM) {
SkullMeta meta = (SkullMeta) item.getItemMeta();
if (meta.hasOwner() && (meta.getOwner() == null || meta.getOwner().isEmpty())) {
item.setItemMeta(plugin.getServer().getItemFactory().getItemMeta(Material.SKULL_ITEM));
}
}
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BukkitObjectOutputStream objectOut = new BukkitObjectOutputStream(baos);
objectOut.writeObject(item);
objectOut.close();
val.addProperty("item", Base64Coder.encodeLines(baos.toByteArray()));
} catch (IOException e) {
e.printStackTrace();
continue;
}
target.add(val);
}
}
} }
private static class PlayerDataDeserializer implements JsonDeserializer<DataFileCache> { private static class PlayerDataDeserializer implements JsonDeserializer<DataFileCache> {
@ -166,39 +116,7 @@ public class JsonCache {
flying = e.getAsBoolean(); flying = e.getAsBoolean();
} }
JsonArray arr; return new DataFileCache(group, operator, flying);
ItemStack[] inv = null;
ItemStack[] armour = null;
if (jsonObject.has("inventory")) {
arr = jsonObject.get("inventory").getAsJsonArray();
inv = getItems(arr);
}
if (jsonObject.has("armour")) {
arr = jsonObject.get("armour").getAsJsonArray();
armour = getItems(arr);
}
return new DataFileCache(inv, armour, group, operator, flying);
}
private ItemStack[] getItems(JsonArray arr) {
ItemStack[] contents = new ItemStack[arr.size()];
for (int i = 0; i < arr.size(); i++) {
JsonObject item = arr.get(i).getAsJsonObject();
String encoded = item.get("item").getAsString();
byte[] decoded = Base64Coder.decodeLines(encoded);
try {
ByteArrayInputStream baos = new ByteArrayInputStream(decoded);
BukkitObjectInputStream objectIn = new BukkitObjectInputStream(baos);
contents[i] = (ItemStack) objectIn.readObject();
objectIn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return contents;
} }
} }

View File

@ -11,7 +11,6 @@ import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -25,15 +24,13 @@ public class LimboCache {
private LimboCache(AuthMe plugin) { private LimboCache(AuthMe plugin) {
this.plugin = plugin; this.plugin = plugin;
this.cache = new ConcurrentHashMap<>(); this.cache = new ConcurrentHashMap<>();
this.playerData = new JsonCache(plugin); this.playerData = new JsonCache();
} }
public void addLimboPlayer(Player player) { public void addLimboPlayer(Player player) {
String name = player.getName().toLowerCase(); String name = player.getName().toLowerCase();
Location loc = player.getLocation(); Location loc = player.getLocation();
GameMode gameMode = player.getGameMode(); GameMode gameMode = player.getGameMode();
ItemStack[] arm;
ItemStack[] inv;
boolean operator = false; boolean operator = false;
String playerGroup = ""; String playerGroup = "";
boolean flying = false; boolean flying = false;
@ -42,12 +39,10 @@ public class LimboCache {
final StoreInventoryEvent event = new StoreInventoryEvent(player, playerData); final StoreInventoryEvent event = new StoreInventoryEvent(player, playerData);
Bukkit.getServer().getPluginManager().callEvent(event); Bukkit.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled() && event.getInventory() != null && event.getArmor() != null) { if (!event.isCancelled() && event.getInventory() != null && event.getArmor() != null) {
inv = event.getInventory(); player.getInventory().setContents(event.getInventory());
arm = event.getArmor(); player.getInventory().setArmorContents(event.getArmor());
} else {
inv = null;
arm = null;
} }
DataFileCache cache = playerData.readCache(player); DataFileCache cache = playerData.readCache(player);
if (cache != null) { if (cache != null) {
playerGroup = cache.getGroup(); playerGroup = cache.getGroup();
@ -58,12 +53,10 @@ public class LimboCache {
StoreInventoryEvent event = new StoreInventoryEvent(player); StoreInventoryEvent event = new StoreInventoryEvent(player);
Bukkit.getServer().getPluginManager().callEvent(event); Bukkit.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled() && event.getInventory() != null && event.getArmor() != null) { if (!event.isCancelled() && event.getInventory() != null && event.getArmor() != null) {
inv = event.getInventory(); player.getInventory().setContents(event.getInventory());
arm = event.getArmor(); player.getInventory().setArmorContents(event.getArmor());
} else {
inv = null;
arm = null;
} }
operator = player.isOp(); operator = player.isOp();
flying = player.isFlying(); flying = player.isFlying();
if (plugin.permission != null) { if (plugin.permission != null) {
@ -93,7 +86,7 @@ public class LimboCache {
if (player.isDead()) { if (player.isDead()) {
loc = plugin.getSpawnLocation(player); loc = plugin.getSpawnLocation(player);
} }
cache.put(name, new LimboPlayer(name, loc, inv, arm, gameMode, operator, playerGroup, flying)); cache.put(name, new LimboPlayer(name, loc, gameMode, operator, playerGroup, flying));
} }
public void addLimboPlayer(Player player, String group) { public void addLimboPlayer(Player player, String group) {

View File

@ -2,14 +2,11 @@ package fr.xephi.authme.cache.limbo;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
public class LimboPlayer { public class LimboPlayer {
private String name; private String name;
private ItemStack[] inventory;
private ItemStack[] armour;
private Location loc = null; private Location loc = null;
private BukkitTask timeoutTaskId = null; private BukkitTask timeoutTaskId = null;
private BukkitTask messageTaskId = null; private BukkitTask messageTaskId = null;
@ -18,19 +15,6 @@ public class LimboPlayer {
private String group = ""; private String group = "";
private boolean flying = false; private boolean flying = false;
public LimboPlayer(String name, Location loc, ItemStack[] inventory,
ItemStack[] armour, GameMode gameMode, boolean operator,
String group, boolean flying) {
this.name = name;
this.loc = loc;
this.inventory = inventory;
this.armour = armour;
this.gameMode = gameMode;
this.operator = operator;
this.group = group;
this.flying = flying;
}
public LimboPlayer(String name, Location loc, GameMode gameMode, public LimboPlayer(String name, Location loc, GameMode gameMode,
boolean operator, String group, boolean flying) { boolean operator, String group, boolean flying) {
this.name = name; this.name = name;
@ -54,22 +38,6 @@ public class LimboPlayer {
return loc; return loc;
} }
public ItemStack[] getArmour() {
return armour;
}
public ItemStack[] getInventory() {
return inventory;
}
public void setArmour(ItemStack[] armour) {
this.armour = armour;
}
public void setInventory(ItemStack[] inventory) {
this.inventory = inventory;
}
public GameMode getGameMode() { public GameMode getGameMode() {
return gameMode; return gameMode;
} }
@ -105,5 +73,4 @@ public class LimboPlayer {
public boolean isFlying() { public boolean isFlying() {
return flying; return flying;
} }
} }

View File

@ -18,7 +18,6 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitScheduler;
@ -34,7 +33,7 @@ public class UnregisterCommand implements CommandExecutor {
public UnregisterCommand(AuthMe plugin) { public UnregisterCommand(AuthMe plugin) {
this.plugin = plugin; this.plugin = plugin;
this.playerCache = new JsonCache(plugin); this.playerCache = new JsonCache();
} }
@Override @Override
@ -79,8 +78,7 @@ public class UnregisterCommand implements CommandExecutor {
player.teleport(tpEvent.getTo()); player.teleport(tpEvent.getTo());
} }
} }
player.getInventory().setContents(new ItemStack[36]);
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()) if (!Settings.getRegisteredGroup.isEmpty())

View File

@ -4,7 +4,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
/** /**
* *
* This event is call just after store inventory into cache and will empty the * This event is call just after store inventory into cache and will empty the
* player inventory. * player inventory.
* *
@ -18,12 +18,11 @@ public class ProtectInventoryEvent extends CustomEvent {
private ItemStack[] emptyArmor = null; private ItemStack[] emptyArmor = null;
private Player player; private Player player;
public ProtectInventoryEvent(Player player, ItemStack[] storedinventory, public ProtectInventoryEvent(Player player) {
ItemStack[] storedarmor) {
super(true); super(true);
this.player = player; this.player = player;
this.storedinventory = storedinventory; this.storedinventory = player.getInventory().getContents();
this.storedarmor = storedarmor; this.storedarmor = player.getInventory().getArmorContents();
this.emptyInventory = new ItemStack[36]; this.emptyInventory = new ItemStack[36];
this.emptyArmor = new ItemStack[4]; this.emptyArmor = new ItemStack[4];
} }

View File

@ -4,8 +4,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
/** /**
* * This event restore the inventory.
* This event restore the inventory from cache
* *
* @author Xephi59 * @author Xephi59
*/ */
@ -15,16 +14,14 @@ public class RestoreInventoryEvent extends CustomEvent {
private ItemStack[] armor; private ItemStack[] armor;
private Player player; private Player player;
public RestoreInventoryEvent(Player player, ItemStack[] inventory, public RestoreInventoryEvent(Player player) {
ItemStack[] armor) {
this.player = player; this.player = player;
this.inventory = inventory; this.inventory = player.getInventory().getContents();
this.armor = armor; this.armor = player.getInventory().getArmorContents();
} }
public RestoreInventoryEvent(Player player, ItemStack[] inventory, public RestoreInventoryEvent(Player player, boolean async) {
ItemStack[] armor, boolean b) { super(async);
super(b);
this.player = player; this.player = player;
this.inventory = inventory; this.inventory = inventory;
this.armor = armor; this.armor = armor;
@ -53,5 +50,4 @@ public class RestoreInventoryEvent extends CustomEvent {
public void setPlayer(Player player) { public void setPlayer(Player player) {
this.player = player; this.player = player;
} }
} }

View File

@ -1,6 +1,5 @@
package fr.xephi.authme.events; package fr.xephi.authme.events;
import fr.xephi.authme.cache.backup.DataFileCache;
import fr.xephi.authme.cache.backup.JsonCache; import fr.xephi.authme.cache.backup.JsonCache;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -24,14 +23,8 @@ public class StoreInventoryEvent extends CustomEvent {
public StoreInventoryEvent(Player player, JsonCache jsonCache) { public StoreInventoryEvent(Player player, JsonCache jsonCache) {
this.player = player; this.player = player;
DataFileCache cache = jsonCache.readCache(player); this.inventory = player.getInventory().getContents();
if (cache != null) { this.armor = player.getInventory().getArmorContents();
this.inventory = cache.getInventory();
this.armor = cache.getArmour();
} else {
this.inventory = player.getInventory().getContents();
this.armor = player.getInventory().getArmorContents();
}
} }
public ItemStack[] getInventory() { public ItemStack[] getInventory() {
@ -57,5 +50,4 @@ public class StoreInventoryEvent extends CustomEvent {
public void setPlayer(Player player) { public void setPlayer(Player player) {
this.player = player; this.player = player;
} }
} }

View File

@ -0,0 +1,101 @@
/*
* Copyright (C) 2015 AuthMe-Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package fr.xephi.authme.listener;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.settings.Settings;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collections;
import java.util.logging.Level;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
public class AuthMeInventoryListener extends PacketAdapter {
private static final int PLAYER_INVENTORY = 0;
//http://wiki.vg/Inventory#Inventory (0-4 crafting, 5-8 armor, 9-35 main inventory, 36-44 inventory)
//+1 because an index starts with 0
private static final int PLAYER_CRAFTING_SIZE = 5;
private static final int HOTBAR_SIZE = 9;
public AuthMeInventoryListener(AuthMe plugin) {
super(plugin, PacketType.Play.Server.SET_SLOT, PacketType.Play.Server.WINDOW_ITEMS);
}
@Override
public void onPacketSending(PacketEvent packetEvent) {
Player player = packetEvent.getPlayer();
PacketContainer packet = packetEvent.getPacket();
byte windowId = packet.getIntegers().read(0).byteValue();
if (windowId == PLAYER_INVENTORY && Settings.protectInventoryBeforeLogInEnabled
&& !PlayerCache.getInstance().isAuthenticated(player.getName())) {
packetEvent.setCancelled(true);
}
}
public void sendInventoryPacket(Player player) {
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
PacketContainer inventoryPacket = protocolManager.createPacket(PacketType.Play.Server.WINDOW_ITEMS);
//we are sending our own inventory
inventoryPacket.getIntegers().write(0, PLAYER_INVENTORY);
ItemStack[] playerCrafting = new ItemStack[PLAYER_CRAFTING_SIZE];
ItemStack[] armorContents = player.getInventory().getArmorContents();
ItemStack[] mainInventory = player.getInventory().getContents();
//bukkit saves the armor in reversed order
Collections.reverse(Arrays.asList(armorContents));
//same main inventory. The hotbar is at the beginning but it should be at the end of the array
ItemStack[] hotbar = Arrays.copyOfRange(mainInventory, 0, HOTBAR_SIZE);
ItemStack[] storedInventory = Arrays.copyOfRange(mainInventory, HOTBAR_SIZE, mainInventory.length);
//concat all parts of the inventory together
int inventorySize = playerCrafting.length + armorContents.length + mainInventory.length;
ItemStack[] completeInventory = new ItemStack[inventorySize];
System.arraycopy(playerCrafting, 0, completeInventory, 0, playerCrafting.length);
System.arraycopy(armorContents, 0, completeInventory, playerCrafting.length, armorContents.length);
//storedInventory and hotbar
System.arraycopy(storedInventory, 0, completeInventory
, playerCrafting.length + armorContents.length, storedInventory.length);
System.arraycopy(hotbar, 0, completeInventory
, playerCrafting.length + armorContents.length + storedInventory.length, hotbar.length);
inventoryPacket.getItemArrayModifier().write(0, completeInventory);
try {
protocolManager.sendServerPacket(player, inventoryPacket, false);
} catch (InvocationTargetException invocationExc) {
plugin.getLogger().log(Level.WARNING, "Error during inventory recovery", invocationExc);
}
}
}

View File

@ -68,6 +68,10 @@ public class AuthMeServerListener implements Listener {
plugin.permission = null; plugin.permission = null;
ConsoleLogger.showError("Vault has been disabled, unhook permissions!"); ConsoleLogger.showError("Vault has been disabled, unhook permissions!");
} }
if (pluginName.equalsIgnoreCase("ProtocolLib")) {
plugin.inventoryProtector = null;
ConsoleLogger.showError("ProtocolLib has been disabled, unhook packet inventory protection!");
}
} }
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
@ -83,5 +87,8 @@ public class AuthMeServerListener implements Listener {
plugin.checkCombatTagPlus(); plugin.checkCombatTagPlus();
if (pluginName.equalsIgnoreCase("Vault")) if (pluginName.equalsIgnoreCase("Vault"))
plugin.checkVault(); plugin.checkVault();
if (pluginName.equalsIgnoreCase("ProtocolLib")) {
plugin.checkProtocolLib();
}
} }
} }

View File

@ -1,315 +1,296 @@
package fr.xephi.authme.process.join; package fr.xephi.authme.process.join;
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.Utils.GroupType;
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.backup.DataFileCache; import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.backup.JsonCache; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.events.FirstSpawnTeleportEvent;
import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.events.ProtectInventoryEvent;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.events.SpawnTeleportEvent;
import fr.xephi.authme.events.FirstSpawnTeleportEvent; import fr.xephi.authme.listener.AuthMePlayerListener;
import fr.xephi.authme.events.ProtectInventoryEvent; import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.events.SpawnTeleportEvent; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.listener.AuthMePlayerListener; import fr.xephi.authme.settings.Spawn;
import fr.xephi.authme.settings.Messages; import fr.xephi.authme.task.MessageTask;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.task.TimeoutTask;
import fr.xephi.authme.settings.Spawn; import org.bukkit.Bukkit;
import fr.xephi.authme.task.MessageTask; import org.bukkit.GameMode;
import fr.xephi.authme.task.TimeoutTask; import org.bukkit.Location;
import org.bukkit.Bukkit; import org.bukkit.Material;
import org.bukkit.GameMode; import org.bukkit.block.Block;
import org.bukkit.Location; import org.bukkit.entity.Player;
import org.bukkit.Material; import org.bukkit.potion.PotionEffect;
import org.bukkit.block.Block; import org.bukkit.potion.PotionEffectType;
import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.inventory.ItemStack; import org.bukkit.scheduler.BukkitTask;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; public class AsyncronousJoin {
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask; protected Player player;
protected DataSource database;
public class AsyncronousJoin { protected AuthMe plugin;
protected String name;
protected Player player; private Messages m = Messages.getInstance();
protected DataSource database;
protected AuthMe plugin; public AsyncronousJoin(Player player, AuthMe plugin, DataSource database) {
protected String name; this.player = player;
private Messages m = Messages.getInstance(); this.plugin = plugin;
private JsonCache playerBackup; this.database = database;
this.name = player.getName().toLowerCase();
public AsyncronousJoin(Player player, AuthMe plugin, DataSource database) { }
this.player = player;
this.plugin = plugin; public void process() {
this.database = database; if (AuthMePlayerListener.gameMode.containsKey(name))
this.playerBackup = new JsonCache(plugin); AuthMePlayerListener.gameMode.remove(name);
this.name = player.getName().toLowerCase(); AuthMePlayerListener.gameMode.putIfAbsent(name, player.getGameMode());
} BukkitScheduler sched = plugin.getServer().getScheduler();
public void process() { if (Utils.isNPC(player) || Utils.isUnrestricted(player)) {
if (AuthMePlayerListener.gameMode.containsKey(name)) return;
AuthMePlayerListener.gameMode.remove(name); }
AuthMePlayerListener.gameMode.putIfAbsent(name, player.getGameMode());
BukkitScheduler sched = plugin.getServer().getScheduler(); if (plugin.ess != null && Settings.disableSocialSpy) {
plugin.ess.getUser(player).setSocialSpyEnabled(false);
if (Utils.isNPC(player) || Utils.isUnrestricted(player)) { }
return;
} final String ip = plugin.getIP(player);
if (Settings.isAllowRestrictedIp && !Settings.getRestrictedIp(name, ip)) {
if (plugin.ess != null && Settings.disableSocialSpy) { final GameMode gM = AuthMePlayerListener.gameMode.get(name);
plugin.ess.getUser(player).setSocialSpyEnabled(false); sched.scheduleSyncDelayedTask(plugin, new Runnable() {
}
@Override
final String ip = plugin.getIP(player); public void run() {
if (Settings.isAllowRestrictedIp && !Settings.getRestrictedIp(name, ip)) { AuthMePlayerListener.causeByAuthMe.putIfAbsent(name, true);
final GameMode gM = AuthMePlayerListener.gameMode.get(name); player.setGameMode(gM);
sched.scheduleSyncDelayedTask(plugin, new Runnable() { player.kickPlayer("You are not the Owner of this account, please try another name!");
if (Settings.banUnsafeIp)
@Override plugin.getServer().banIP(ip);
public void run() { }
AuthMePlayerListener.causeByAuthMe.putIfAbsent(name, true);
player.setGameMode(gM); });
player.kickPlayer("You are not the Owner of this account, please try another name!"); return;
if (Settings.banUnsafeIp) }
plugin.getServer().banIP(ip); if (Settings.getMaxJoinPerIp > 0 && !plugin.authmePermissible(player, "authme.allow2accounts") && !ip.equalsIgnoreCase("127.0.0.1") && !ip.equalsIgnoreCase("localhost")) {
} if (plugin.hasJoinedIp(player.getName(), ip)) {
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
});
return; @Override
} public void run() {
if (Settings.getMaxJoinPerIp > 0 && !plugin.authmePermissible(player, "authme.allow2accounts") && !ip.equalsIgnoreCase("127.0.0.1") && !ip.equalsIgnoreCase("localhost")) { player.kickPlayer("A player with the same IP is already in game!");
if (plugin.hasJoinedIp(player.getName(), ip)) { }
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
});
@Override return;
public void run() { }
player.kickPlayer("A player with the same IP is already in game!"); }
} final Location spawnLoc = plugin.getSpawnLocation(player);
final boolean isAuthAvailable = database.isAuthAvailable(name);
}); if (isAuthAvailable) {
return; if (Settings.isForceSurvivalModeEnabled && !Settings.forceOnlyAfterLogin) {
} sched.scheduleSyncDelayedTask(plugin, new Runnable() {
}
final Location spawnLoc = plugin.getSpawnLocation(player); @Override
final boolean isAuthAvailable = database.isAuthAvailable(name); public void run() {
if (isAuthAvailable) { AuthMePlayerListener.causeByAuthMe.putIfAbsent(name, true);
if (Settings.isForceSurvivalModeEnabled && !Settings.forceOnlyAfterLogin) { Utils.forceGM(player);
sched.scheduleSyncDelayedTask(plugin, new Runnable() { }
@Override });
public void run() { }
AuthMePlayerListener.causeByAuthMe.putIfAbsent(name, true); if (!Settings.noTeleport)
Utils.forceGM(player); if (Settings.isTeleportToSpawnEnabled || (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName()))) {
} sched.scheduleSyncDelayedTask(plugin, new Runnable() {
}); @Override
} public void run() {
if (!Settings.noTeleport) SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, PlayerCache.getInstance().isAuthenticated(name));
if (Settings.isTeleportToSpawnEnabled || (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName()))) { plugin.getServer().getPluginManager().callEvent(tpEvent);
sched.scheduleSyncDelayedTask(plugin, new Runnable() { if (!tpEvent.isCancelled()) {
if (player.isOnline() && tpEvent.getTo() != null) {
@Override if (tpEvent.getTo().getWorld() != null)
public void run() { player.teleport(tpEvent.getTo());
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()); }
} placePlayerSafely(player, spawnLoc);
} LimboCache.getInstance().updateLimboPlayer(player);
} // protect inventory
if (Settings.protectInventoryBeforeLogInEnabled && plugin.inventoryProtector != null) {
}); ProtectInventoryEvent ev = new ProtectInventoryEvent(player);
} plugin.getServer().getPluginManager().callEvent(ev);
placePlayerSafely(player, spawnLoc); if (ev.isCancelled()) {
LimboCache.getInstance().updateLimboPlayer(player); plugin.inventoryProtector.sendInventoryPacket(player);
DataFileCache dataFile = new DataFileCache(LimboCache.getInstance().getLimboPlayer(name).getInventory(), LimboCache.getInstance().getLimboPlayer(name).getArmour()); if (!Settings.noConsoleSpam)
playerBackup.createCache(player, dataFile); ConsoleLogger.info("ProtectInventoryEvent has been cancelled for " + player.getName() + " ...");
// protect inventory }
if (Settings.protectInventoryBeforeLogInEnabled) { }
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(player.getName().toLowerCase()); } else {
ProtectInventoryEvent ev = new ProtectInventoryEvent(player, limbo.getInventory(), limbo.getArmour()); if (Settings.isForceSurvivalModeEnabled && !Settings.forceOnlyAfterLogin) {
plugin.getServer().getPluginManager().callEvent(ev); sched.scheduleSyncDelayedTask(plugin, new Runnable() {
if (ev.isCancelled()) {
if (!Settings.noConsoleSpam) @Override
ConsoleLogger.info("ProtectInventoryEvent has been cancelled for " + player.getName() + " ..."); public void run() {
} else { AuthMePlayerListener.causeByAuthMe.putIfAbsent(name, true);
final ItemStack[] inv = ev.getEmptyArmor(); Utils.forceGM(player);
final ItemStack[] armor = ev.getEmptyArmor(); }
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
});
@Override }
public void run() { if (!Settings.unRegisteredGroup.isEmpty()) {
plugin.api.setPlayerInventory(player, inv, armor); Utils.setGroup(player, Utils.GroupType.UNREGISTERED);
} }
if (!Settings.isForcedRegistrationEnabled) {
}); return;
} }
} if (!Settings.noTeleport)
} else { if (!needFirstspawn() && Settings.isTeleportToSpawnEnabled || (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName()))) {
if (Settings.isForceSurvivalModeEnabled && !Settings.forceOnlyAfterLogin) { sched.scheduleSyncDelayedTask(plugin, new Runnable() {
sched.scheduleSyncDelayedTask(plugin, new Runnable() { @Override
public void run() {
@Override SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, PlayerCache.getInstance().isAuthenticated(name));
public void run() { plugin.getServer().getPluginManager().callEvent(tpEvent);
AuthMePlayerListener.causeByAuthMe.putIfAbsent(name, true); if (!tpEvent.isCancelled()) {
Utils.forceGM(player); if (player.isOnline() && tpEvent.getTo() != null) {
} if (tpEvent.getTo().getWorld() != null)
player.teleport(tpEvent.getTo());
}); }
} }
if (!Settings.unRegisteredGroup.isEmpty()) { }
Utils.setGroup(player, Utils.GroupType.UNREGISTERED);
} });
if (!Settings.isForcedRegistrationEnabled) { }
return;
} }
if (!Settings.noTeleport) String[] msg;
if (!needFirstspawn() && Settings.isTeleportToSpawnEnabled || (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName()))) { if (Settings.emailRegistration) {
sched.scheduleSyncDelayedTask(plugin, new Runnable() { msg = isAuthAvailable ? m.send("login_msg") : m.send("reg_email_msg");
@Override } else {
public void run() { msg = isAuthAvailable ? m.send("login_msg") : m.send("reg_msg");
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnLoc, PlayerCache.getInstance().isAuthenticated(name)); }
plugin.getServer().getPluginManager().callEvent(tpEvent); int time = Settings.getRegistrationTimeout * 20;
if (!tpEvent.isCancelled()) { int msgInterval = Settings.getWarnMessageInterval;
if (player.isOnline() && tpEvent.getTo() != null) { if (time != 0) {
if (tpEvent.getTo().getWorld() != null) BukkitTask id = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), time);
player.teleport(tpEvent.getTo()); if (!LimboCache.getInstance().hasLimboPlayer(name))
} LimboCache.getInstance().addLimboPlayer(player);
} LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id);
} }
if (!LimboCache.getInstance().hasLimboPlayer(name))
}); LimboCache.getInstance().addLimboPlayer(player);
} if (isAuthAvailable) {
Utils.setGroup(player, GroupType.NOTLOGGEDIN);
} } else {
String[] msg; Utils.setGroup(player, GroupType.UNREGISTERED);
if (Settings.emailRegistration) { }
msg = isAuthAvailable ? m.send("login_msg") : m.send("reg_email_msg"); sched.scheduleSyncDelayedTask(plugin, new Runnable() {
} else {
msg = isAuthAvailable ? m.send("login_msg") : m.send("reg_msg"); @Override
} public void run() {
int time = Settings.getRegistrationTimeout * 20; if (player.isOp())
int msgInterval = Settings.getWarnMessageInterval; player.setOp(false);
if (time != 0) { if (player.getGameMode() != GameMode.CREATIVE && !Settings.isMovementAllowed) {
BukkitTask id = sched.runTaskLaterAsynchronously(plugin, new TimeoutTask(plugin, name, player), time); player.setAllowFlight(true);
if (!LimboCache.getInstance().hasLimboPlayer(name)) player.setFlying(true);
LimboCache.getInstance().addLimboPlayer(player); }
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id); player.setNoDamageTicks(Settings.getRegistrationTimeout * 20);
} if (Settings.useEssentialsMotd)
if (!LimboCache.getInstance().hasLimboPlayer(name)) player.performCommand("motd");
LimboCache.getInstance().addLimboPlayer(player); if (Settings.applyBlindEffect)
if (isAuthAvailable) { player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, Settings.getRegistrationTimeout * 20, 2));
Utils.setGroup(player, GroupType.NOTLOGGEDIN); if (!Settings.isMovementAllowed && Settings.isRemoveSpeedEnabled) {
} else { player.setWalkSpeed(0.0f);
Utils.setGroup(player, GroupType.UNREGISTERED); player.setFlySpeed(0.0f);
} }
sched.scheduleSyncDelayedTask(plugin, new Runnable() { }
@Override });
public void run() { if (Settings.isSessionsEnabled && isAuthAvailable && (PlayerCache.getInstance().isAuthenticated(name) || database.isLogged(name))) {
if (player.isOp()) if (plugin.sessions.containsKey(name))
player.setOp(false); plugin.sessions.get(name).cancel();
if (player.getGameMode() != GameMode.CREATIVE && !Settings.isMovementAllowed) { plugin.sessions.remove(name);
player.setAllowFlight(true); PlayerAuth auth = database.getAuth(name);
player.setFlying(true); if (auth != null && auth.getIp().equals(ip)) {
} m.send(player, "valid_session");
player.setNoDamageTicks(Settings.getRegistrationTimeout * 20); PlayerCache.getInstance().removePlayer(name);
if (Settings.useEssentialsMotd) database.setUnlogged(name);
player.performCommand("motd"); plugin.management.performLogin(player, "dontneed", true);
if (Settings.applyBlindEffect) } else if (Settings.sessionExpireOnIpChange) {
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, Settings.getRegistrationTimeout * 20, 2)); PlayerCache.getInstance().removePlayer(name);
if (!Settings.isMovementAllowed && Settings.isRemoveSpeedEnabled) { database.setUnlogged(name);
player.setWalkSpeed(0.0f); m.send(player, "invalid_session");
player.setFlySpeed(0.0f); }
} return;
} }
BukkitTask msgT = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, msg, msgInterval));
}); LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgT);
if (Settings.isSessionsEnabled && isAuthAvailable && (PlayerCache.getInstance().isAuthenticated(name) || database.isLogged(name))) { }
if (plugin.sessions.containsKey(name))
plugin.sessions.get(name).cancel(); private boolean needFirstspawn() {
plugin.sessions.remove(name); if (player.hasPlayedBefore())
PlayerAuth auth = database.getAuth(name); return false;
if (auth != null && auth.getIp().equals(ip)) { if (Spawn.getInstance().getFirstSpawn() == null || Spawn.getInstance().getFirstSpawn().getWorld() == null)
m.send(player, "valid_session"); return false;
PlayerCache.getInstance().removePlayer(name); FirstSpawnTeleportEvent tpEvent = new FirstSpawnTeleportEvent(player, player.getLocation(), Spawn.getInstance().getFirstSpawn());
database.setUnlogged(name); plugin.getServer().getPluginManager().callEvent(tpEvent);
plugin.management.performLogin(player, "dontneed", true); if (!tpEvent.isCancelled()) {
} else if (Settings.sessionExpireOnIpChange) { if (player.isOnline() && tpEvent.getTo() != null && tpEvent.getTo().getWorld() != null) {
PlayerCache.getInstance().removePlayer(name); final Location fLoc = tpEvent.getTo();
database.setUnlogged(name); Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
m.send(player, "invalid_session");
} @Override
return; public void run() {
} player.teleport(fLoc);
BukkitTask msgT = sched.runTaskAsynchronously(plugin, new MessageTask(plugin, name, msg, msgInterval)); }
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgT);
} });
}
private boolean needFirstspawn() { }
if (player.hasPlayedBefore()) return true;
return false;
if (Spawn.getInstance().getFirstSpawn() == null || Spawn.getInstance().getFirstSpawn().getWorld() == null) }
return false;
FirstSpawnTeleportEvent tpEvent = new FirstSpawnTeleportEvent(player, player.getLocation(), Spawn.getInstance().getFirstSpawn()); private void placePlayerSafely(final Player player,
plugin.getServer().getPluginManager().callEvent(tpEvent); final Location spawnLoc) {
if (!tpEvent.isCancelled()) { Location loc = null;
if (player.isOnline() && tpEvent.getTo() != null && tpEvent.getTo().getWorld() != null) { if (spawnLoc == null)
final Location fLoc = tpEvent.getTo(); return;
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { if (!Settings.noTeleport)
return;
@Override if (Settings.isTeleportToSpawnEnabled || (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName())))
public void run() { return;
player.teleport(fLoc); if (!player.hasPlayedBefore())
} return;
Block b = player.getLocation().getBlock();
}); if (b.getType() == Material.PORTAL || b.getType() == Material.ENDER_PORTAL) {
} m.send(player, "unsafe_spawn");
} if (spawnLoc.getWorld() != null)
return true; loc = spawnLoc;
} else {
} Block c = player.getLocation().add(0D, 1D, 0D).getBlock();
if (c.getType() == Material.PORTAL || c.getType() == Material.ENDER_PORTAL) {
private void placePlayerSafely(final Player player, m.send(player, "unsafe_spawn");
final Location spawnLoc) { if (spawnLoc.getWorld() != null)
Location loc = null; loc = spawnLoc;
if (spawnLoc == null) }
return; }
if (!Settings.noTeleport) if (loc != null) {
return; final Location floc = loc;
if (Settings.isTeleportToSpawnEnabled || (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName()))) Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
return;
if (!player.hasPlayedBefore()) @Override
return; public void run() {
Block b = player.getLocation().getBlock(); player.teleport(floc);
if (b.getType() == Material.PORTAL || b.getType() == Material.ENDER_PORTAL) { }
m.send(player, "unsafe_spawn");
if (spawnLoc.getWorld() != null) });
loc = spawnLoc; }
} else { }
Block c = player.getLocation().add(0D, 1D, 0D).getBlock();
if (c.getType() == Material.PORTAL || c.getType() == Material.ENDER_PORTAL) { }
m.send(player, "unsafe_spawn");
if (spawnLoc.getWorld() != null)
loc = spawnLoc;
}
}
if (loc != null) {
final Location floc = loc;
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
player.teleport(floc);
}
});
}
}
}

View File

@ -42,7 +42,7 @@ public class ProcessSyncronousPlayerLogin implements Runnable {
this.name = player.getName().toLowerCase(); this.name = player.getName().toLowerCase();
this.limbo = LimboCache.getInstance().getLimboPlayer(name); this.limbo = LimboCache.getInstance().getLimboPlayer(name);
this.auth = database.getAuth(name); this.auth = database.getAuth(name);
this.playerCache = new JsonCache(plugin); this.playerCache = new JsonCache();
} }
public LimboPlayer getLimbo() { public LimboPlayer getLimbo() {
@ -92,10 +92,11 @@ public class ProcessSyncronousPlayerLogin implements Runnable {
} }
protected void restoreInventory() { protected void restoreInventory() {
RestoreInventoryEvent event = new RestoreInventoryEvent(player, limbo.getInventory(), limbo.getArmour()); RestoreInventoryEvent event = new RestoreInventoryEvent(player);
Bukkit.getServer().getPluginManager().callEvent(event); Bukkit.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (!event.isCancelled()) {
plugin.api.setPlayerInventory(player, event.getInventory(), event.getArmor()); plugin.api.setPlayerInventory(player, event.getInventory(), event.getArmor());
plugin.inventoryProtector.sendInventoryPacket(player);
} }
} }
@ -128,7 +129,7 @@ public class ProcessSyncronousPlayerLogin implements Runnable {
// Inventory - Make it after restore GameMode , cause we need to // Inventory - Make it after restore GameMode , cause we need to
// restore the // restore the
// right inventory in the right gamemode // right inventory in the right gamemode
if (Settings.protectInventoryBeforeLogInEnabled && player.hasPlayedBefore()) { if (Settings.protectInventoryBeforeLogInEnabled && plugin.inventoryProtector != null) {
restoreInventory(); restoreInventory();
} }
if (Settings.forceOnlyAfterLogin) { if (Settings.forceOnlyAfterLogin) {

View File

@ -1,91 +1,81 @@
package fr.xephi.authme.process.logout; package fr.xephi.authme.process.logout;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitScheduler;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.AuthMe;
import fr.xephi.authme.Utils; import fr.xephi.authme.Utils;
import fr.xephi.authme.Utils.GroupType; import fr.xephi.authme.Utils.GroupType;
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.backup.DataFileCache; import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.backup.JsonCache; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.events.AuthMeTeleportEvent;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.events.AuthMeTeleportEvent; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.Messages;
import fr.xephi.authme.settings.Settings; public class AsyncronousLogout {
public class AsyncronousLogout { protected Player player;
protected String name;
protected Player player; protected AuthMe plugin;
protected String name; protected DataSource database;
protected AuthMe plugin; protected boolean canLogout = true;
protected DataSource database; private Messages m = Messages.getInstance();
protected boolean canLogout = true;
private Messages m = Messages.getInstance(); public AsyncronousLogout(Player player, AuthMe plugin,
private JsonCache playerBackup; DataSource database) {
this.player = player;
public AsyncronousLogout(Player player, AuthMe plugin, this.plugin = plugin;
DataSource database) { this.database = database;
this.player = player; this.name = player.getName().toLowerCase();
this.plugin = plugin; }
this.database = database;
this.name = player.getName().toLowerCase(); private void preLogout() {
this.playerBackup = new JsonCache(plugin); if (!PlayerCache.getInstance().isAuthenticated(name)) {
} m.send(player, "not_logged_in");
canLogout = false;
private void preLogout() { }
if (!PlayerCache.getInstance().isAuthenticated(name)) { }
m.send(player, "not_logged_in");
canLogout = false; public void process() {
} preLogout();
} if (!canLogout)
return;
public void process() { final Player p = player;
preLogout(); BukkitScheduler sched = p.getServer().getScheduler();
if (!canLogout) PlayerAuth auth = PlayerCache.getInstance().getAuth(name);
return; database.updateSession(auth);
final Player p = player; auth.setQuitLocX(p.getLocation().getX());
BukkitScheduler sched = p.getServer().getScheduler(); auth.setQuitLocY(p.getLocation().getY());
PlayerAuth auth = PlayerCache.getInstance().getAuth(name); auth.setQuitLocZ(p.getLocation().getZ());
database.updateSession(auth); auth.setWorld(p.getWorld().getName());
auth.setQuitLocX(p.getLocation().getX()); database.updateQuitLoc(auth);
auth.setQuitLocY(p.getLocation().getY());
auth.setQuitLocZ(p.getLocation().getZ()); PlayerCache.getInstance().removePlayer(name);
auth.setWorld(p.getWorld().getName()); database.setUnlogged(name);
database.updateQuitLoc(auth); if (Settings.isTeleportToSpawnEnabled && !Settings.noTeleport) {
Location spawnLoc = plugin.getSpawnLocation(p);
PlayerCache.getInstance().removePlayer(name); final AuthMeTeleportEvent tpEvent = new AuthMeTeleportEvent(p, spawnLoc);
database.setUnlogged(name); sched.scheduleSyncDelayedTask(plugin, new Runnable() {
if (Settings.isTeleportToSpawnEnabled && !Settings.noTeleport) {
Location spawnLoc = plugin.getSpawnLocation(p); @Override
final AuthMeTeleportEvent tpEvent = new AuthMeTeleportEvent(p, spawnLoc); public void run() {
sched.scheduleSyncDelayedTask(plugin, new Runnable() { plugin.getServer().getPluginManager().callEvent(tpEvent);
if (!tpEvent.isCancelled()) {
@Override if (tpEvent.getTo() != null)
public void run() { p.teleport(tpEvent.getTo());
plugin.getServer().getPluginManager().callEvent(tpEvent); }
if (!tpEvent.isCancelled()) { }
if (tpEvent.getTo() != null) });
p.teleport(tpEvent.getTo()); }
}
} if (LimboCache.getInstance().hasLimboPlayer(name))
}); LimboCache.getInstance().deleteLimboPlayer(name);
} LimboCache.getInstance().addLimboPlayer(player);
Utils.setGroup(player, GroupType.NOTLOGGEDIN);
if (LimboCache.getInstance().hasLimboPlayer(name))
LimboCache.getInstance().deleteLimboPlayer(name); sched.scheduleSyncDelayedTask(plugin, new ProcessSyncronousPlayerLogout(p, plugin));
LimboCache.getInstance().addLimboPlayer(player); }
Utils.setGroup(player, GroupType.NOTLOGGEDIN); }
if (Settings.protectInventoryBeforeLogInEnabled) {
player.getInventory().clear();
// create cache file for handling lost of inventories on unlogged in
// status
DataFileCache playerData = new DataFileCache(LimboCache.getInstance().getLimboPlayer(name).getInventory(), LimboCache.getInstance().getLimboPlayer(name).getArmour());
playerBackup.createCache(player, playerData);
}
sched.scheduleSyncDelayedTask(plugin, new ProcessSyncronousPlayerLogout(p, plugin));
}
}

View File

@ -1,110 +1,93 @@
package fr.xephi.authme.process.quit; package fr.xephi.authme.process.quit;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.scheduler.BukkitTask;
import org.bukkit.scheduler.BukkitTask;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.Utils;
import fr.xephi.authme.Utils; 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.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.listener.AuthMePlayerListener;
import fr.xephi.authme.events.RestoreInventoryEvent; import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.listener.AuthMePlayerListener;
import fr.xephi.authme.settings.Settings; public class AsyncronousQuit {
public class AsyncronousQuit { protected AuthMe plugin;
protected DataSource database;
protected AuthMe plugin; protected Player player;
protected DataSource database; private String name;
protected Player player; private boolean isOp = false;
private String name; private boolean isFlying = false;
private ItemStack[] armor = null; private boolean needToChange = false;
private ItemStack[] inv = null; private boolean isKick = false;
private boolean isOp = false;
private boolean isFlying = false; public AsyncronousQuit(Player p, AuthMe plugin, DataSource database,
private boolean needToChange = false; boolean isKick) {
private boolean isKick = false; this.player = p;
this.plugin = plugin;
public AsyncronousQuit(Player p, AuthMe plugin, DataSource database, this.database = database;
boolean isKick) { this.name = p.getName().toLowerCase();
this.player = p; this.isKick = isKick;
this.plugin = plugin; }
this.database = database;
this.name = p.getName().toLowerCase(); public void process() {
this.isKick = isKick; if (player == null)
} return;
if (Utils.isNPC(player) || Utils.isUnrestricted(player)) {
public void process() { return;
if (player == null) }
return;
if (Utils.isNPC(player) || Utils.isUnrestricted(player)) { String ip = plugin.getIP(player);
return;
} if (PlayerCache.getInstance().isAuthenticated(name)) {
if (Settings.isSaveQuitLocationEnabled && database.isAuthAvailable(name)) {
String ip = plugin.getIP(player); Location loc = player.getLocation();
PlayerAuth auth = new PlayerAuth(name, loc.getX(), loc.getY(), loc.getZ(), loc.getWorld().getName(), player.getName());
if (PlayerCache.getInstance().isAuthenticated(name)) { database.updateQuitLoc(auth);
if (Settings.isSaveQuitLocationEnabled && database.isAuthAvailable(name)) { }
Location loc = player.getLocation(); PlayerAuth auth = new PlayerAuth(name, ip, System.currentTimeMillis(), player.getName());
PlayerAuth auth = new PlayerAuth(name, loc.getX(), loc.getY(), loc.getZ(), loc.getWorld().getName(), player.getName()); database.updateSession(auth);
database.updateQuitLoc(auth); }
}
PlayerAuth auth = new PlayerAuth(name, ip, System.currentTimeMillis(), player.getName()); if (LimboCache.getInstance().hasLimboPlayer(name)) {
database.updateSession(auth); LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name);
} if (limbo.getGroup() != null && !limbo.getGroup().equals(""))
Utils.addNormal(player, limbo.getGroup());
if (LimboCache.getInstance().hasLimboPlayer(name)) { needToChange = true;
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name); isOp = limbo.getOperator();
if (Settings.protectInventoryBeforeLogInEnabled && player.hasPlayedBefore()) { isFlying = limbo.isFlying();
inv = limbo.getInventory(); if (limbo.getTimeoutTaskId() != null)
armor = limbo.getArmour(); limbo.getTimeoutTaskId().cancel();
} if (limbo.getMessageTaskId() != null)
if (limbo.getGroup() != null && !limbo.getGroup().equals("")) limbo.getMessageTaskId().cancel();
Utils.addNormal(player, limbo.getGroup()); LimboCache.getInstance().deleteLimboPlayer(name);
needToChange = true; }
isOp = limbo.getOperator(); if (Settings.isSessionsEnabled && !isKick) {
isFlying = limbo.isFlying(); if (Settings.getSessionTimeout != 0) {
if (limbo.getTimeoutTaskId() != null) BukkitTask task = plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() {
limbo.getTimeoutTaskId().cancel();
if (limbo.getMessageTaskId() != null) @Override
limbo.getMessageTaskId().cancel(); public void run() {
LimboCache.getInstance().deleteLimboPlayer(name); PlayerCache.getInstance().removePlayer(name);
} if (database.isLogged(name))
if (Settings.isSessionsEnabled && !isKick) { database.setUnlogged(name);
if (Settings.getSessionTimeout != 0) { plugin.sessions.remove(name);
BukkitTask task = plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() { }
@Override }, Settings.getSessionTimeout * 20 * 60);
public void run() { plugin.sessions.put(name, task);
PlayerCache.getInstance().removePlayer(name); }
if (database.isLogged(name)) } else {
database.setUnlogged(name); PlayerCache.getInstance().removePlayer(name);
plugin.sessions.remove(name); database.setUnlogged(name);
} }
}, Settings.getSessionTimeout * 20 * 60); AuthMePlayerListener.gameMode.remove(name);
plugin.sessions.put(name, task); Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new ProcessSyncronousPlayerQuit(plugin, player, isOp, isFlying, needToChange));
} }
} else { }
PlayerCache.getInstance().removePlayer(name);
database.setUnlogged(name);
}
AuthMePlayerListener.gameMode.remove(name);
final Player p = player;
RestoreInventoryEvent ev = new RestoreInventoryEvent(player, inv, armor, true);
Bukkit.getPluginManager().callEvent(ev);
if (ev.isCancelled()) {
inv = null;
armor = null;
} else {
inv = ev.getInventory();
armor = ev.getArmor();
}
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new ProcessSyncronousPlayerQuit(plugin, p, inv, armor, isOp, isFlying, needToChange));
}
}

View File

@ -1,48 +1,49 @@
package fr.xephi.authme.process.quit; package fr.xephi.authme.process.quit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.AuthMe; import fr.xephi.authme.events.RestoreInventoryEvent;
import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.Settings;
import org.bukkit.Bukkit;
public class ProcessSyncronousPlayerQuit implements Runnable {
public class ProcessSyncronousPlayerQuit implements Runnable {
protected AuthMe plugin;
protected Player player; protected AuthMe plugin;
protected boolean isOp; protected Player player;
protected boolean isFlying; protected boolean isOp;
protected ItemStack[] inv; protected boolean isFlying;
protected ItemStack[] armor; protected boolean needToChange;
protected boolean needToChange;
public ProcessSyncronousPlayerQuit(AuthMe plugin, Player player
public ProcessSyncronousPlayerQuit(AuthMe plugin, Player player, , boolean isOp, boolean isFlying
ItemStack[] inv, ItemStack[] armor, boolean isOp, boolean isFlying, , boolean needToChange) {
boolean needToChange) { this.plugin = plugin;
this.plugin = plugin; this.player = player;
this.player = player; this.isOp = isOp;
this.isOp = isOp; this.isFlying = isFlying;
this.isFlying = isFlying; this.needToChange = needToChange;
this.armor = armor; }
this.inv = inv;
this.needToChange = needToChange; @Override
} public void run() {
RestoreInventoryEvent ev = new RestoreInventoryEvent(player);
@Override Bukkit.getPluginManager().callEvent(ev);
public void run() { if (!ev.isCancelled()) {
if (inv != null && armor != null) plugin.api.setPlayerInventory(player, ev.getInventory(), ev.getArmor());
plugin.api.setPlayerInventory(player, inv, armor); }
if (needToChange) {
player.setOp(isOp); if (needToChange) {
if (player.getGameMode() != GameMode.CREATIVE && !Settings.isMovementAllowed) { player.setOp(isOp);
player.setAllowFlight(isFlying); if (player.getGameMode() != GameMode.CREATIVE && !Settings.isMovementAllowed) {
player.setFlying(isFlying); player.setAllowFlight(isFlying);
} player.setFlying(isFlying);
} }
try { }
player.getVehicle().eject(); try {
} catch (Exception e) { player.getVehicle().eject();
} } catch (Exception e) {
} }
} }
}

View File

@ -91,14 +91,17 @@ public class ProcessSyncronousPasswordRegister implements Runnable {
player.teleport(tpEvent.getTo()); player.teleport(tpEvent.getTo());
} }
} }
if (Settings.protectInventoryBeforeLogInEnabled && limbo.getInventory() != null && limbo.getArmour() != null) {
RestoreInventoryEvent event = new RestoreInventoryEvent(player, limbo.getInventory(), limbo.getArmour()); if (Settings.protectInventoryBeforeLogInEnabled && plugin.inventoryProtector != null) {
RestoreInventoryEvent event = new RestoreInventoryEvent(player);
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled() && event.getArmor() != null && event.getInventory() != null) { if (!event.isCancelled() && event.getArmor() != null && event.getInventory() != null) {
player.getInventory().setContents(event.getInventory()); player.getInventory().setContents(event.getInventory());
player.getInventory().setArmorContents(event.getArmor()); player.getInventory().setArmorContents(event.getArmor());
plugin.inventoryProtector.sendInventoryPacket(player);
} }
} }
limbo.getTimeoutTaskId().cancel(); limbo.getTimeoutTaskId().cancel();
limbo.getMessageTaskId().cancel(); limbo.getMessageTaskId().cancel();
LimboCache.getInstance().deleteLimboPlayer(name); LimboCache.getInstance().deleteLimboPlayer(name);
@ -153,6 +156,5 @@ public class ProcessSyncronousPasswordRegister implements Runnable {
// Register is now finish , we can force all commands // Register is now finish , we can force all commands
forceCommands(); forceCommands();
} }
} }

View File

@ -4,7 +4,7 @@ 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 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 player.
main: fr.xephi.authme.AuthMe main: fr.xephi.authme.AuthMe
version: ${project.version} version: ${project.version}
softdepend: [Vault, ChestShop, Multiverse-Core, Citizens, CombatTag, Essentials, EssentialsSpawn, PerWorldInventories] softdepend: [Vault, ChestShop, Multiverse-Core, Citizens, CombatTag, Essentials, EssentialsSpawn, PerWorldInventories, ProtocolLib]
commands: commands:
register: register:
description: Register an account description: Register an account
@ -22,7 +22,7 @@ commands:
usage: /logout usage: /logout
unregister: unregister:
description: unregister your account description: unregister your account
usage: /unregister password usage: /unregister password
authme: authme:
description: AuthMe op commands description: AuthMe op commands
usage: '/authme reload|register playername password|changepassword playername password|unregister playername|version' usage: '/authme reload|register playername password|changepassword playername password|unregister playername|version'