Fix several issues on Gem Hunters, including a duping attack vector resulting from combat logger inventory desync
This commit is contained in:
parent
cc98f4fdd5
commit
b73958ec96
@ -26,15 +26,10 @@ import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.core.utils.UtilGameProfile;
|
||||
import mineplex.gemhunters.death.event.QuitNPCDespawnEvent;
|
||||
import mineplex.gemhunters.economy.EconomyModule;
|
||||
import mineplex.gemhunters.loot.InventoryModule;
|
||||
import mineplex.gemhunters.quest.QuestModule;
|
||||
import mineplex.gemhunters.quest.QuestPlayerData;
|
||||
|
||||
public class QuitNPC implements Listener
|
||||
{
|
||||
|
||||
// Managers
|
||||
private final QuitNPCModule _npc;
|
||||
private final DisguiseManager _disguise;
|
||||
|
||||
// Time
|
||||
@ -52,10 +47,9 @@ public class QuitNPC implements Listener
|
||||
|
||||
private final int _gems;
|
||||
|
||||
public QuitNPC(QuitNPCModule npc, Player player, long quitMills)
|
||||
public QuitNPC(Player player, long quitMills)
|
||||
{
|
||||
// Managers
|
||||
_npc = npc;
|
||||
_disguise = Managers.get(DisguiseManager.class);
|
||||
|
||||
// Time
|
||||
@ -162,7 +156,6 @@ public class QuitNPC implements Listener
|
||||
|
||||
if (killer != null)
|
||||
{
|
||||
_npc.setKilledBy(_uuid, killer.getName());
|
||||
Managers.get(EconomyModule.class).addToStore(killer, "Killing " + F.name(_name + "'s") + " NPC", (int) (_gems * EconomyModule.GEM_KILL_FACTOR));
|
||||
}
|
||||
|
||||
@ -192,4 +185,4 @@ public class QuitNPC implements Listener
|
||||
{
|
||||
return _uuid;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,40 +1,38 @@
|
||||
package mineplex.gemhunters.death.quitnpc;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.gemhunters.economy.CashOutModule;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.ReflectivelyCreateMiniPlugin;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.texttutorial.TextTutorialManager;
|
||||
import mineplex.gemhunters.death.event.QuitNPCDespawnEvent;
|
||||
import mineplex.gemhunters.death.event.QuitNPCSpawnEvent;
|
||||
import mineplex.gemhunters.economy.event.PlayerCashOutCompleteEvent;
|
||||
import mineplex.gemhunters.economy.CashOutModule;
|
||||
|
||||
@ReflectivelyCreateMiniPlugin
|
||||
public class QuitNPCModule extends MiniPlugin
|
||||
{
|
||||
|
||||
private static final long LOG_OUT_TIME = TimeUnit.SECONDS.toMillis(60);
|
||||
|
||||
private final CashOutModule _cashOut;
|
||||
|
||||
private final Map<UUID, QuitNPC> _npcs;
|
||||
private final Map<UUID, String> _killedBy;
|
||||
|
||||
private final String _serverName;
|
||||
private final QuitNPCRepository _repo;
|
||||
|
||||
private QuitNPCModule()
|
||||
{
|
||||
@ -43,7 +41,8 @@ public class QuitNPCModule extends MiniPlugin
|
||||
_cashOut = require(CashOutModule.class);
|
||||
|
||||
_npcs = new HashMap<>();
|
||||
_killedBy = new HashMap<>();
|
||||
_serverName = UtilServer.getServerName();
|
||||
_repo = new QuitNPCRepository();
|
||||
}
|
||||
|
||||
public void spawnNpc(Player player)
|
||||
@ -73,7 +72,8 @@ public class QuitNPCModule extends MiniPlugin
|
||||
return;
|
||||
}
|
||||
|
||||
_npcs.put(player.getUniqueId(), new QuitNPC(this, player, LOG_OUT_TIME));
|
||||
_npcs.put(player.getUniqueId(), new QuitNPC(player, LOG_OUT_TIME));
|
||||
_repo.insertNpc(player.getUniqueId(), _serverName);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
@ -93,23 +93,30 @@ public class QuitNPCModule extends MiniPlugin
|
||||
public void npcDespawn(QuitNPCDespawnEvent event)
|
||||
{
|
||||
log("Despawning npc for " + _npcs.remove(event.getNpc().getUniqueId()).getName());
|
||||
_repo.deleteNpc(event.getNpc().getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void playerJoin(PlayerJoinEvent event)
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onLogin(AsyncPlayerPreLoginEvent event)
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
UUID key = player.getUniqueId();
|
||||
|
||||
if (_killedBy.containsKey(key))
|
||||
try
|
||||
{
|
||||
player.sendMessage(F.main("Game", "You were killed while you were logged out. You were killed by " + F.name(_killedBy.remove(key)) + "."));
|
||||
String npcServer = _repo.loadNpcServer(event.getUniqueId()).get();
|
||||
if (npcServer == null || npcServer.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (npcServer.equals(_serverName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
event.disallow(Result.KICK_OTHER, C.cRed + "You have a combat logger alive on " + npcServer + "! Either wait for it to despawn or join that server directly!");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void setKilledBy(UUID dead, String killedBy)
|
||||
{
|
||||
_killedBy.put(dead, killedBy);
|
||||
}
|
||||
|
||||
public QuitNPC getNPC(Player player)
|
||||
@ -121,5 +128,4 @@ public class QuitNPCModule extends MiniPlugin
|
||||
{
|
||||
return _npcs.containsKey(player.getUniqueId());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package mineplex.gemhunters.death.quitnpc;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.serverdata.database.DBPool;
|
||||
import mineplex.serverdata.database.RepositoryBase;
|
||||
import mineplex.serverdata.database.column.ColumnVarChar;
|
||||
|
||||
public class QuitNPCRepository extends RepositoryBase
|
||||
{
|
||||
private static final String GET_DATA = "SELECT serverName FROM gemHuntersQuitNpcs WHERE uuid=?;";
|
||||
private static final String INSERT_DATA = "INSERT INTO gemHuntersQuitNpcs (uuid, serverName) VALUES (?, ?);";
|
||||
private static final String DELETE_DATA = "DELETE FROM gemHuntersQuitNpcs WHERE uuid=?;";
|
||||
|
||||
public QuitNPCRepository()
|
||||
{
|
||||
super(DBPool.getAccount());
|
||||
}
|
||||
|
||||
public CompletableFuture<String> loadNpcServer(UUID uuid)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection conn = getConnection())
|
||||
{
|
||||
PreparedStatement stmt = conn.prepareStatement(GET_DATA);
|
||||
stmt.setString(1, uuid.toString());
|
||||
|
||||
String serverName = null;
|
||||
|
||||
ResultSet resultSet = stmt.executeQuery();
|
||||
if (resultSet.next())
|
||||
{
|
||||
serverName = resultSet.getString("serverName");
|
||||
}
|
||||
|
||||
return serverName;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void deleteNpc(UUID uuid)
|
||||
{
|
||||
final String uuidStr = uuid.toString();
|
||||
UtilServer.runAsync(() ->
|
||||
{
|
||||
executeUpdate(DELETE_DATA, new ColumnVarChar("uuid", uuidStr.length(), uuidStr));
|
||||
});
|
||||
}
|
||||
|
||||
public void insertNpc(UUID uuid, String serverName)
|
||||
{
|
||||
final String uuidStr = uuid.toString();
|
||||
UtilServer.runAsync(() ->
|
||||
{
|
||||
executeInsert(INSERT_DATA, null, new ColumnVarChar("uuid", uuidStr.length(), uuidStr), new ColumnVarChar("serverName", serverName.length(), serverName));
|
||||
});
|
||||
}
|
||||
}
|
@ -1,30 +1,28 @@
|
||||
package mineplex.gemhunters.join;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.ReflectivelyCreateMiniPlugin;
|
||||
import mineplex.core.account.CoreClient;
|
||||
import mineplex.core.account.CoreClientManager;
|
||||
import mineplex.core.inventory.InventoryManager;
|
||||
import mineplex.gemhunters.death.quitnpc.QuitNPC;
|
||||
import mineplex.gemhunters.death.quitnpc.QuitNPCModule;
|
||||
import mineplex.gemhunters.economy.EconomyModule;
|
||||
import mineplex.gemhunters.loot.InventoryModule;
|
||||
import mineplex.gemhunters.map.ItemMapModule;
|
||||
import mineplex.gemhunters.persistence.PersistenceData;
|
||||
import mineplex.gemhunters.persistence.PersistenceModule;
|
||||
import mineplex.gemhunters.persistence.PersistenceRepository;
|
||||
import mineplex.gemhunters.quest.QuestModule;
|
||||
import mineplex.gemhunters.spawn.SpawnModule;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@ReflectivelyCreateMiniPlugin
|
||||
public class JoinModule extends MiniPlugin
|
||||
{
|
||||
|
||||
private final CoreClientManager _client;
|
||||
private final EconomyModule _economy;
|
||||
private final QuestModule _quest;
|
||||
@ -81,9 +79,9 @@ public class JoinModule extends MiniPlugin
|
||||
|
||||
if (!repository.exists(client))
|
||||
{
|
||||
_spawn.teleportToSpawn(player);
|
||||
runSync(() -> _spawn.teleportToSpawn(player));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,5 +1,19 @@
|
||||
package mineplex.gemhunters.persistence;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.ReflectivelyCreateMiniPlugin;
|
||||
import mineplex.core.account.CoreClient;
|
||||
@ -12,24 +26,6 @@ import mineplex.gemhunters.economy.EconomyModule;
|
||||
import mineplex.gemhunters.loot.InventoryModule;
|
||||
import mineplex.gemhunters.quest.QuestModule;
|
||||
import mineplex.gemhunters.quest.QuestPlayerData;
|
||||
import mineplex.serverdata.commands.ServerTransfer;
|
||||
import net.minecraft.server.v1_8_R3.EntityItemFrame;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
|
||||
import org.bukkit.event.player.AsyncPlayerPreLoginEvent.Result;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@ReflectivelyCreateMiniPlugin
|
||||
public class PersistenceModule extends MiniPlugin
|
||||
@ -149,4 +145,4 @@ public class PersistenceModule extends MiniPlugin
|
||||
{
|
||||
return _repository;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user