mirror of
https://github.com/YouHaveTrouble/PreventStabby.git
synced 2026-05-11 21:06:55 +00:00
Compare commits
5 Commits
2.0.0-pre-5
...
2.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
| fb913d97ae | |||
| d013eabd02 | |||
| df20c95e38 | |||
| c6f0df5d50 | |||
| 6a5e5f8d44 |
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>me.youhavetrouble</groupId>
|
||||
<artifactId>PreventStabby</artifactId>
|
||||
<version>2.0.0-pre-5</version>
|
||||
<version>2.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>PreventStabby</name>
|
||||
|
||||
@@ -11,11 +11,16 @@ import me.youhavetrouble.preventstabby.listeners.PvpListener;
|
||||
import me.youhavetrouble.preventstabby.listeners.UtilListener;
|
||||
import me.youhavetrouble.preventstabby.util.*;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class PreventStabby extends JavaPlugin {
|
||||
|
||||
@@ -57,17 +62,37 @@ public final class PreventStabby extends JavaPlugin {
|
||||
}
|
||||
|
||||
Metrics metrics = new Metrics(this, 14074);
|
||||
|
||||
getServer().getOnlinePlayers().forEach(player -> playerManager.getPlayerData(player.getUniqueId()));
|
||||
getServer().getWorlds().forEach(world -> {
|
||||
for (Chunk chunk : world.getLoadedChunks()) {
|
||||
if (!chunk.isEntitiesLoaded()) continue;
|
||||
Bukkit.getRegionScheduler().run(plugin, chunk.getWorld(), chunk.getX(), chunk.getZ(), (task) -> {
|
||||
for (Entity entity : chunk.getEntities()) {
|
||||
if (!(entity instanceof Tameable tameable)) continue;
|
||||
UUID ownerId = tameable.getOwnerUniqueId();
|
||||
if (ownerId == null) continue;
|
||||
getPlayerManager().getPlayerData(ownerId).thenAccept(playerData -> {
|
||||
if (playerData == null) return;
|
||||
playerData.addRelatedEntity(entity.getUniqueId());
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
if (getServer().getPluginManager().getPlugin("WorldGuard") != null) {
|
||||
try {
|
||||
WorldGuardHook.init();
|
||||
WorldGuardHook.init(this.getLogger());
|
||||
worldGuardHook = true;
|
||||
} catch (NoClassDefFoundError e) {
|
||||
worldGuardHook = false;
|
||||
}
|
||||
} else {
|
||||
worldGuardHook = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package me.youhavetrouble.preventstabby.data;
|
||||
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@@ -13,6 +16,7 @@ public class PlayerData {
|
||||
private long lastAccessTimestamp;
|
||||
private Long combatStartTimestamp, teleportTimestamp, loginTimestamp;
|
||||
private boolean pvpEnabled, lastCombatCheck;
|
||||
private final Set<UUID> relatedEntities = new HashSet<>();
|
||||
|
||||
public PlayerData(UUID playerUuid, boolean pvpEnabled) {
|
||||
this.playerUuid = playerUuid;
|
||||
@@ -106,6 +110,7 @@ public class PlayerData {
|
||||
* Retrieves the login timestamp for the player.
|
||||
* @return The login timestamp for the player.
|
||||
*/
|
||||
@Nullable
|
||||
public Long getLoginTimestamp() {
|
||||
return loginTimestamp;
|
||||
}
|
||||
@@ -162,4 +167,28 @@ public class PlayerData {
|
||||
public boolean isProtected() {
|
||||
return hasLoginProtection() || hasTeleportProtection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of entities related to the player that should keep player's data loaded
|
||||
* @return The list of entities related to the player that should keep player's data loaded
|
||||
*/
|
||||
public Set<UUID> getRelatedEntities() {
|
||||
return relatedEntities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getRelatedEntities()
|
||||
* @param entity The entity id to add to the list of related entities
|
||||
*/
|
||||
public void addRelatedEntity(UUID entity) {
|
||||
relatedEntities.add(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getRelatedEntities()
|
||||
* @param entity The entity id to remove from the list of related entities
|
||||
*/
|
||||
public void removeRelatedEntity(UUID entity) {
|
||||
relatedEntities.remove(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,10 @@ public class PlayerListener implements Listener {
|
||||
if (!(entity instanceof Tameable tameable)) return;
|
||||
UUID ownerId = tameable.getOwnerUniqueId();
|
||||
if (ownerId == null) return;
|
||||
PreventStabby.getPlugin().getPlayerManager().getPlayerData(ownerId);
|
||||
PreventStabby.getPlugin().getPlayerManager().getPlayerData(ownerId).thenAccept(playerData -> {
|
||||
if (playerData == null) return;
|
||||
playerData.addRelatedEntity(entity.getUniqueId());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,14 +3,16 @@ package me.youhavetrouble.preventstabby.data;
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import me.youhavetrouble.preventstabby.api.event.PlayerEnterCombatEvent;
|
||||
import me.youhavetrouble.preventstabby.api.event.PlayerLeaveCombatEvent;
|
||||
import me.youhavetrouble.preventstabby.hooks.WorldGuardHook;
|
||||
import me.youhavetrouble.preventstabby.util.PluginMessages;
|
||||
import me.youhavetrouble.preventstabby.util.PvpState;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -29,25 +31,29 @@ public class PlayerManager {
|
||||
playerList.values().removeIf(PlayerData::isCacheExpired);
|
||||
}, 250, 250, TimeUnit.MILLISECONDS);
|
||||
|
||||
Bukkit.getGlobalRegionScheduler().runAtFixedRate(plugin, (task) -> Bukkit.getWorlds().forEach((world -> {
|
||||
for (Chunk chunk : world.getLoadedChunks()) {
|
||||
if (!chunk.isEntitiesLoaded()) continue;
|
||||
Bukkit.getRegionScheduler().run(plugin, chunk.getWorld(), chunk.getX(), chunk.getZ(), (task1) -> {
|
||||
for (Entity entity : chunk.getEntities()) {
|
||||
if (!(entity instanceof Tameable tameable)) continue;
|
||||
UUID ownerId = tameable.getOwnerUniqueId();
|
||||
if (ownerId == null) continue;
|
||||
getPlayerData(ownerId);
|
||||
}
|
||||
});
|
||||
Bukkit.getAsyncScheduler().runAtFixedRate(plugin, (task) -> {
|
||||
Collection<? extends Player> players = new ArrayList<>(Bukkit.getOnlinePlayers());
|
||||
// Load data for all online players as a failsafe
|
||||
CompletableFuture.allOf(players.stream().map(player -> getPlayerData(player.getUniqueId())).toArray(CompletableFuture[]::new)).join();
|
||||
// Refresh cache time for all players
|
||||
for (PlayerData playerData : playerList.values()) {
|
||||
if (playerData == null) continue;
|
||||
playerData.refreshCacheTime();
|
||||
}
|
||||
})), 5, 20 * 15);
|
||||
}, 1, 1, TimeUnit.SECONDS);
|
||||
|
||||
Bukkit.getGlobalRegionScheduler().runAtFixedRate(plugin, (task) -> {
|
||||
for (PlayerData playerData : playerList.values()) {
|
||||
if (playerData == null) continue;
|
||||
Player player = Bukkit.getPlayer(playerData.getPlayerUuid());
|
||||
if (player == null || !player.isOnline()) continue;
|
||||
if (player == null || !player.isOnline()) {
|
||||
// player not online, so check for related entities
|
||||
playerData.getRelatedEntities().removeIf( uuid -> {
|
||||
Entity entity = Bukkit.getEntity(uuid);
|
||||
return entity == null;
|
||||
});
|
||||
if (playerData.getRelatedEntities().isEmpty()) continue;
|
||||
}
|
||||
playerData.refreshCacheTime(); // Refresh cache timer if player is online
|
||||
// leaving combat logic
|
||||
if (playerData.getLastCombatCheckState() && !playerData.isInCombat()) {
|
||||
@@ -169,7 +175,7 @@ public class PlayerManager {
|
||||
}
|
||||
}
|
||||
|
||||
if (!attackerPlayerData.isPvpEnabled()) {
|
||||
if (!attackerPlayerData.isPvpEnabled() && !WorldGuardHook.isPlayerForcedToPvp(Bukkit.getPlayer(attackerId))) {
|
||||
String message = switch (victimClassifier) {
|
||||
case PLAYER -> plugin.getConfigCache().cannot_attack_attacker;
|
||||
case PET -> plugin.getConfigCache().cannot_attack_pets_victim;
|
||||
@@ -179,7 +185,7 @@ public class PlayerManager {
|
||||
return new DamageCheckResult(false, attackerId, victimId, message, victimClassifier.equals(Target.EntityClassifier.PLAYER));
|
||||
}
|
||||
|
||||
if (!victimPlayerData.isPvpEnabled()) {
|
||||
if (!victimPlayerData.isPvpEnabled() && !WorldGuardHook.isPlayerForcedToPvp(Bukkit.getPlayer(victimId))) {
|
||||
String message = switch (victimClassifier) {
|
||||
case PLAYER -> plugin.getConfigCache().cannot_attack_victim;
|
||||
case PET -> plugin.getConfigCache().cannot_attack_pets_attacker;
|
||||
@@ -238,13 +244,15 @@ public class PlayerManager {
|
||||
});
|
||||
}
|
||||
|
||||
public void setPlayerPvpState(UUID uuid, boolean state) {
|
||||
public CompletableFuture<Void> setPlayerPvpState(UUID uuid, boolean state) {
|
||||
// If player is in cache update that
|
||||
if (getPlayer(uuid) != null) {
|
||||
getPlayer(uuid).setPvpEnabled(state);
|
||||
}
|
||||
// Update the database aswell
|
||||
plugin.getSqLite().updatePlayerInfo(uuid, new PlayerData(uuid, state));
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
// Update the database aswell
|
||||
plugin.getSqLite().updatePlayerInfo(uuid, new PlayerData(uuid, state));
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<Boolean> togglePlayerPvpState(UUID uuid) {
|
||||
|
||||
@@ -15,17 +15,19 @@ import com.sk89q.worldguard.protection.regions.RegionQuery;
|
||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class WorldGuardHook {
|
||||
|
||||
private static FlagRegistry flagRegistry;
|
||||
public static StateFlag FORCE_PVP_FLAG;
|
||||
|
||||
public static void init() {
|
||||
public static void init(Logger logger) {
|
||||
try {
|
||||
Class.forName("com.sk89q.worldguard.protection.flags.registry.FlagRegistry");
|
||||
WorldGuardPlugin worldGuardPlugin = WorldGuardPlugin.inst();
|
||||
if (WorldGuard.getInstance() == null || worldGuardPlugin == null) return;
|
||||
PreventStabby.getPlugin().getLogger().info("[PreventStabby] Hooking into WorldGuard");
|
||||
logger.info("Hooking into WorldGuard");
|
||||
flagRegistry = WorldGuard.getInstance().getFlagRegistry();
|
||||
createForcePvpFlag();
|
||||
} catch (NoClassDefFoundError | ClassNotFoundException ignored) {
|
||||
@@ -50,6 +52,8 @@ public class WorldGuardHook {
|
||||
}
|
||||
|
||||
public static boolean isPlayerForcedToPvp(Player player) {
|
||||
if (player == null) return false;
|
||||
if (!PreventStabby.worldGuardHookEnabled()) return false;
|
||||
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
|
||||
RegionQuery query = container.createQuery();
|
||||
org.bukkit.Location loc = player.getLocation();
|
||||
|
||||
Reference in New Issue
Block a user