mirror of
https://github.com/YouHaveTrouble/PreventStabby.git
synced 2026-05-12 05:16:55 +00:00
Compare commits
21 Commits
2.0.0-pre-2
...
2.1.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 624cc335f2 | |||
| 23fc50ac46 | |||
| 466091f1ea | |||
| 138170c066 | |||
| c1d0fcf5b3 | |||
| b3d9ae720f | |||
| 667e441460 | |||
| fb913d97ae | |||
| d013eabd02 | |||
| df20c95e38 | |||
| c6f0df5d50 | |||
| 6a5e5f8d44 | |||
| ee3526c55d | |||
| 2189616a9e | |||
| 1484d262c0 | |||
| 4976ff56f0 | |||
| 477f042e91 | |||
| 409d115337 | |||
| 6c022dd88e | |||
| 01b6cd309c | |||
| 7253eab958 |
@@ -4,16 +4,16 @@
|
|||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>me.youhavetrouble</groupId>
|
<groupId>me.youhavetrouble.preventstabby</groupId>
|
||||||
<artifactId>PreventStabby</artifactId>
|
<artifactId>PreventStabby</artifactId>
|
||||||
<version>2.0.0-pre-2</version>
|
<version>2.1.0</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>PreventStabby</name>
|
<name>PreventStabby</name>
|
||||||
|
|
||||||
<description>Stop people from getting stabbed!</description>
|
<description>Stop people from getting stabbed!</description>
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>17</java.version>
|
<java.version>21</java.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>3.3.0</version>
|
<version>3.6.0</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<phase>package</phase>
|
<phase>package</phase>
|
||||||
@@ -46,6 +46,13 @@
|
|||||||
<shadedPattern>me.youhavetrouble.preventstabby.bstats</shadedPattern>
|
<shadedPattern>me.youhavetrouble.preventstabby.bstats</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
</relocations>
|
</relocations>
|
||||||
|
<transformers>
|
||||||
|
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||||
|
<manifestEntries>
|
||||||
|
<paperweight-mappings-namespace>mojang</paperweight-mappings-namespace>
|
||||||
|
</manifestEntries>
|
||||||
|
</transformer>
|
||||||
|
</transformers>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
@@ -78,7 +85,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.papermc.paper</groupId>
|
<groupId>io.papermc.paper</groupId>
|
||||||
<artifactId>paper-api</artifactId>
|
<artifactId>paper-api</artifactId>
|
||||||
<version>1.20.4-R0.1-SNAPSHOT</version>
|
<version>1.21-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
@@ -97,7 +104,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.clip</groupId>
|
<groupId>me.clip</groupId>
|
||||||
<artifactId>placeholderapi</artifactId>
|
<artifactId>placeholderapi</artifactId>
|
||||||
<version>2.11.1</version>
|
<version>2.11.6</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@@ -11,11 +11,16 @@ import me.youhavetrouble.preventstabby.listeners.PvpListener;
|
|||||||
import me.youhavetrouble.preventstabby.listeners.UtilListener;
|
import me.youhavetrouble.preventstabby.listeners.UtilListener;
|
||||||
import me.youhavetrouble.preventstabby.util.*;
|
import me.youhavetrouble.preventstabby.util.*;
|
||||||
import org.bstats.bukkit.Metrics;
|
import org.bstats.bukkit.Metrics;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.PluginCommand;
|
import org.bukkit.command.PluginCommand;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Tameable;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
public final class PreventStabby extends JavaPlugin {
|
public final class PreventStabby extends JavaPlugin {
|
||||||
|
|
||||||
@@ -57,17 +62,37 @@ public final class PreventStabby extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Metrics metrics = new Metrics(this, 14074);
|
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
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
if (getServer().getPluginManager().getPlugin("WorldGuard") != null) {
|
if (getServer().getPluginManager().getPlugin("WorldGuard") != null) {
|
||||||
try {
|
try {
|
||||||
WorldGuardHook.init();
|
WorldGuardHook.init(this.getLogger());
|
||||||
worldGuardHook = true;
|
worldGuardHook = true;
|
||||||
} catch (NoClassDefFoundError e) {
|
} catch (NoClassDefFoundError e) {
|
||||||
worldGuardHook = false;
|
worldGuardHook = false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
worldGuardHook = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
package me.youhavetrouble.preventstabby.config;
|
package me.youhavetrouble.preventstabby.config;
|
||||||
|
|
||||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class ConfigCache {
|
public class ConfigCache {
|
||||||
|
|
||||||
@@ -18,7 +16,7 @@ public class ConfigCache {
|
|||||||
bucket_stopper_enabled,
|
bucket_stopper_enabled,
|
||||||
fire_stopper_enabled,
|
fire_stopper_enabled,
|
||||||
block_stopper_enabled,
|
block_stopper_enabled,
|
||||||
punish_for_combat_logout,
|
punish_for_combat_logout_kill,
|
||||||
punish_for_combat_logout_announce,
|
punish_for_combat_logout_announce,
|
||||||
block_teleports_in_combat,
|
block_teleports_in_combat,
|
||||||
allow_fishing_rod_pull;
|
allow_fishing_rod_pull;
|
||||||
@@ -36,6 +34,7 @@ public class ConfigCache {
|
|||||||
public final double combat_time, login_protection_time, teleport_protection_time, bucket_stopper_radius,
|
public final double combat_time, login_protection_time, teleport_protection_time, bucket_stopper_radius,
|
||||||
fire_stopper_radius, block_stopper_radius;
|
fire_stopper_radius, block_stopper_radius;
|
||||||
private final Set<String> combatBlockedCommands = new HashSet<>();
|
private final Set<String> combatBlockedCommands = new HashSet<>();
|
||||||
|
private final Set<Material> dangerousBlocks = new HashSet<>();
|
||||||
|
|
||||||
private final FileConfiguration config;
|
private final FileConfiguration config;
|
||||||
|
|
||||||
@@ -43,6 +42,10 @@ public class ConfigCache {
|
|||||||
plugin.reloadConfig();
|
plugin.reloadConfig();
|
||||||
config = plugin.getConfig();
|
config = plugin.getConfig();
|
||||||
|
|
||||||
|
migrate("settings.punish_for_combat_logout.enabled",
|
||||||
|
"settings.punish_for_combat_logout.kill",
|
||||||
|
true);
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
this.pvp_enabled_by_default = getBoolean(
|
this.pvp_enabled_by_default = getBoolean(
|
||||||
"settings.pvp_enabled_by_default",
|
"settings.pvp_enabled_by_default",
|
||||||
@@ -55,23 +58,26 @@ public class ConfigCache {
|
|||||||
25,
|
25,
|
||||||
List.of("How long in seconds should combat last since the last hit")
|
List.of("How long in seconds should combat last since the last hit")
|
||||||
);
|
);
|
||||||
this.punish_for_combat_logout = getBoolean(
|
|
||||||
"settings.punish_for_combat_logout.enabled",
|
this.punish_for_combat_logout_kill = getBoolean(
|
||||||
|
"settings.punish_for_combat_logout.kill",
|
||||||
true,
|
true,
|
||||||
List.of("Should players be killed if they log out during combat?")
|
List.of("Should players be killed if they log out during combat?")
|
||||||
);
|
);
|
||||||
this.punish_for_combat_logout_announce = getBoolean(
|
this.punish_for_combat_logout_announce = getBoolean(
|
||||||
"settings.punish_for_combat_logout.announce",
|
"settings.punish_for_combat_logout.announce",
|
||||||
true,
|
true,
|
||||||
List.of("Should killing of a player that logged out of combat be announced?")
|
List.of("Should we announce that player logged out of combat?")
|
||||||
);
|
);
|
||||||
|
|
||||||
this.combatBlockedCommands.addAll(getList(
|
List<String> commandsBlockedInCombat = getList(
|
||||||
"settings.block_in_combat.commands",
|
"settings.block_in_combat.commands",
|
||||||
List.of("spawn", "tpa", "home"),
|
List.of("spawn", "tpa", "home"),
|
||||||
List.of("Commands to block when player is in combat")
|
List.of("Commands to block when player is in combat")
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
for (String command : commandsBlockedInCombat) {
|
||||||
|
this.combatBlockedCommands.add(command.toLowerCase(Locale.ENGLISH));
|
||||||
|
}
|
||||||
|
|
||||||
this.block_teleports_in_combat = getBoolean(
|
this.block_teleports_in_combat = getBoolean(
|
||||||
"settings.block_in_combat.teleports",
|
"settings.block_in_combat.teleports",
|
||||||
@@ -125,6 +131,21 @@ public class ConfigCache {
|
|||||||
2.5,
|
2.5,
|
||||||
List.of("Distance from the player where placing dangerous blocks will be disallowed")
|
List.of("Distance from the player where placing dangerous blocks will be disallowed")
|
||||||
);
|
);
|
||||||
|
List<String> rawDangerousBlocks = getList(
|
||||||
|
"settings.environmental.block_stopper.blocks",
|
||||||
|
List.of("tnt", "magma_block", "cactus", "campfire"),
|
||||||
|
List.of("List of dangerous blocks that will be blocked when placed near players with pvp off")
|
||||||
|
);
|
||||||
|
for (String block : rawDangerousBlocks) {
|
||||||
|
Material material = Material.matchMaterial(block);
|
||||||
|
if (material != null) {
|
||||||
|
dangerousBlocks.add(material);
|
||||||
|
} else {
|
||||||
|
plugin.getLogger().warning("Invalid material: " + block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Messages
|
// Messages
|
||||||
this.pvp_enabled = getString("messages.pvp_enabled", "<red>You enabled PvP!");
|
this.pvp_enabled = getString("messages.pvp_enabled", "<red>You enabled PvP!");
|
||||||
@@ -174,48 +195,83 @@ public class ConfigCache {
|
|||||||
return Collections.unmodifiableSet(combatBlockedCommands);
|
return Collections.unmodifiableSet(combatBlockedCommands);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<Material> getDangerousBlocks() {
|
||||||
|
return Collections.unmodifiableSet(dangerousBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
private String getString(String path, @NotNull String def) {
|
private String getString(String path, @NotNull String def) {
|
||||||
return getString(path, def, null);
|
return getString(path, def, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getString(String path, @NotNull String def, @Nullable List<String> comments) {
|
private String getString(String path, @NotNull String def, @Nullable List<String> comments) {
|
||||||
if (config.isSet(path)) return config.getString(path, def);
|
String value;
|
||||||
|
if (config.isSet(path)) {
|
||||||
|
value = config.getString(path, def);
|
||||||
|
} else {
|
||||||
config.set(path, def);
|
config.set(path, def);
|
||||||
|
value = def;
|
||||||
|
}
|
||||||
if (comments != null) config.setComments(path, comments);
|
if (comments != null) config.setComments(path, comments);
|
||||||
return def;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean getBoolean(String path, boolean def, @Nullable List<String> comments) {
|
private boolean getBoolean(String path, boolean def, @Nullable List<String> comments) {
|
||||||
if (config.isSet(path)) return config.getBoolean(path, def);
|
boolean value;
|
||||||
|
if (config.isSet(path)) {
|
||||||
|
value = config.getBoolean(path, def);
|
||||||
|
} else {
|
||||||
config.set(path, def);
|
config.set(path, def);
|
||||||
|
value = def;
|
||||||
|
}
|
||||||
if (comments != null) config.setComments(path, comments);
|
if (comments != null) config.setComments(path, comments);
|
||||||
return def;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double getDouble(String path, double def, @Nullable List<String> comments) {
|
private double getDouble(String path, double def, @Nullable List<String> comments) {
|
||||||
if (config.isSet(path)) return config.getDouble(path, def);
|
double value;
|
||||||
|
if (config.isSet(path)) {
|
||||||
|
value = config.getDouble(path, def);
|
||||||
|
} else {
|
||||||
config.set(path, def);
|
config.set(path, def);
|
||||||
|
value = def;
|
||||||
|
}
|
||||||
if (comments != null) config.setComments(path, comments);
|
if (comments != null) config.setComments(path, comments);
|
||||||
return def;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getLong(String path, long def, @Nullable List<String> comments) {
|
private long getLong(String path, long def, @Nullable List<String> comments) {
|
||||||
if (config.isSet(path)) return config.getLong(path, def);
|
long value;
|
||||||
|
if (config.isSet(path)) {
|
||||||
|
value = config.getLong(path, def);
|
||||||
|
} else {
|
||||||
config.set(path, def);
|
config.set(path, def);
|
||||||
|
value = def;
|
||||||
|
}
|
||||||
if (comments != null) config.setComments(path, comments);
|
if (comments != null) config.setComments(path, comments);
|
||||||
return def;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getList(String path, List<String> def, @Nullable List<String> comments) {
|
private List<String> getList(String path, List<String> def, @Nullable List<String> comments) {
|
||||||
if (config.isSet(path)) return config.getStringList(path);
|
List<String> value;
|
||||||
|
if (config.isSet(path)) {
|
||||||
|
value = config.getStringList(path);
|
||||||
|
} else {
|
||||||
config.set(path, def);
|
config.set(path, def);
|
||||||
|
value = def;
|
||||||
|
}
|
||||||
if (comments != null) config.setComments(path, comments);
|
if (comments != null) config.setComments(path, comments);
|
||||||
return def;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getList(String path, List<String> def) {
|
private List<String> getList(String path, List<String> def) {
|
||||||
return getList(path, def, null);
|
return getList(path, def, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void migrate(String oldPath, String newPath, @Nullable Object defaultValue) {
|
||||||
|
if (config.isSet(oldPath) && !config.isSet(newPath)) {
|
||||||
|
Object value = config.get(oldPath);
|
||||||
|
config.set(newPath, value != null ? value : defaultValue);
|
||||||
|
config.set(oldPath, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package me.youhavetrouble.preventstabby.data;
|
package me.youhavetrouble.preventstabby.data;
|
||||||
|
|
||||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -13,6 +16,7 @@ public class PlayerData {
|
|||||||
private long lastAccessTimestamp;
|
private long lastAccessTimestamp;
|
||||||
private Long combatStartTimestamp, teleportTimestamp, loginTimestamp;
|
private Long combatStartTimestamp, teleportTimestamp, loginTimestamp;
|
||||||
private boolean pvpEnabled, lastCombatCheck;
|
private boolean pvpEnabled, lastCombatCheck;
|
||||||
|
private final Set<UUID> relatedEntities = new HashSet<>();
|
||||||
|
|
||||||
public PlayerData(UUID playerUuid, boolean pvpEnabled) {
|
public PlayerData(UUID playerUuid, boolean pvpEnabled) {
|
||||||
this.playerUuid = playerUuid;
|
this.playerUuid = playerUuid;
|
||||||
@@ -106,6 +110,7 @@ public class PlayerData {
|
|||||||
* Retrieves the login timestamp for the player.
|
* Retrieves the login timestamp for the player.
|
||||||
* @return The login timestamp for the player.
|
* @return The login timestamp for the player.
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
public Long getLoginTimestamp() {
|
public Long getLoginTimestamp() {
|
||||||
return loginTimestamp;
|
return loginTimestamp;
|
||||||
}
|
}
|
||||||
@@ -162,4 +167,28 @@ public class PlayerData {
|
|||||||
public boolean isProtected() {
|
public boolean isProtected() {
|
||||||
return hasLoginProtection() || hasTeleportProtection();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,13 +44,14 @@ public class PlayerListener implements Listener {
|
|||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
public void onPlayerLeave(PlayerQuitEvent event) {
|
public void onPlayerLeave(PlayerQuitEvent event) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
if (!PreventStabby.getPlugin().getConfigCache().punish_for_combat_logout) return;
|
if (!PreventStabby.getPlugin().getConfigCache().punish_for_combat_logout_announce) {
|
||||||
|
PluginMessages.broadcastMessage(player, PreventStabby.getPlugin().getConfigCache().punish_for_combat_logout_message);
|
||||||
|
}
|
||||||
|
if (!PreventStabby.getPlugin().getConfigCache().punish_for_combat_logout_kill) return;
|
||||||
PlayerData playerData = PreventStabby.getPlugin().getPlayerManager().getPlayer(player.getUniqueId());
|
PlayerData playerData = PreventStabby.getPlugin().getPlayerManager().getPlayer(player.getUniqueId());
|
||||||
if (playerData == null) return;
|
if (playerData == null) return;
|
||||||
if (!playerData.isInCombat()) return;
|
if (!playerData.isInCombat()) return;
|
||||||
player.setHealth(0);
|
player.setHealth(0);
|
||||||
if (!PreventStabby.getPlugin().getConfigCache().punish_for_combat_logout_announce) return;
|
|
||||||
PluginMessages.broadcastMessage(player, PreventStabby.getPlugin().getConfigCache().punish_for_combat_logout_message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||||
@@ -78,7 +79,10 @@ public class PlayerListener implements Listener {
|
|||||||
if (!(entity instanceof Tameable tameable)) return;
|
if (!(entity instanceof Tameable tameable)) return;
|
||||||
UUID ownerId = tameable.getOwnerUniqueId();
|
UUID ownerId = tameable.getOwnerUniqueId();
|
||||||
if (ownerId == null) return;
|
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.PreventStabby;
|
||||||
import me.youhavetrouble.preventstabby.api.event.PlayerEnterCombatEvent;
|
import me.youhavetrouble.preventstabby.api.event.PlayerEnterCombatEvent;
|
||||||
import me.youhavetrouble.preventstabby.api.event.PlayerLeaveCombatEvent;
|
import me.youhavetrouble.preventstabby.api.event.PlayerLeaveCombatEvent;
|
||||||
|
import me.youhavetrouble.preventstabby.hooks.WorldGuardHook;
|
||||||
import me.youhavetrouble.preventstabby.util.PluginMessages;
|
import me.youhavetrouble.preventstabby.util.PluginMessages;
|
||||||
import me.youhavetrouble.preventstabby.util.PvpState;
|
import me.youhavetrouble.preventstabby.util.PvpState;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.entity.Tameable;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@@ -29,25 +31,29 @@ public class PlayerManager {
|
|||||||
playerList.values().removeIf(PlayerData::isCacheExpired);
|
playerList.values().removeIf(PlayerData::isCacheExpired);
|
||||||
}, 250, 250, TimeUnit.MILLISECONDS);
|
}, 250, 250, TimeUnit.MILLISECONDS);
|
||||||
|
|
||||||
Bukkit.getGlobalRegionScheduler().runAtFixedRate(plugin, (task) -> Bukkit.getWorlds().forEach((world -> {
|
Bukkit.getAsyncScheduler().runAtFixedRate(plugin, (task) -> {
|
||||||
for (Chunk chunk : world.getLoadedChunks()) {
|
Collection<? extends Player> players = new ArrayList<>(Bukkit.getOnlinePlayers());
|
||||||
if (!chunk.isEntitiesLoaded()) continue;
|
// Load data for all online players as a failsafe
|
||||||
Bukkit.getRegionScheduler().run(plugin, chunk.getWorld(), chunk.getX(), chunk.getZ(), (task1) -> {
|
CompletableFuture.allOf(players.stream().map(player -> getPlayerData(player.getUniqueId())).toArray(CompletableFuture[]::new)).join();
|
||||||
for (Entity entity : chunk.getEntities()) {
|
// Refresh cache time for all players
|
||||||
if (!(entity instanceof Tameable tameable)) continue;
|
for (PlayerData playerData : playerList.values()) {
|
||||||
UUID ownerId = tameable.getOwnerUniqueId();
|
if (playerData == null) continue;
|
||||||
if (ownerId == null) continue;
|
playerData.refreshCacheTime();
|
||||||
getPlayerData(ownerId);
|
|
||||||
}
|
}
|
||||||
});
|
}, 1, 1, TimeUnit.SECONDS);
|
||||||
}
|
|
||||||
})), 5, 20 * 15);
|
|
||||||
|
|
||||||
Bukkit.getGlobalRegionScheduler().runAtFixedRate(plugin, (task) -> {
|
Bukkit.getGlobalRegionScheduler().runAtFixedRate(plugin, (task) -> {
|
||||||
for (PlayerData playerData : playerList.values()) {
|
for (PlayerData playerData : playerList.values()) {
|
||||||
if (playerData == null) continue;
|
if (playerData == null) continue;
|
||||||
Player player = Bukkit.getPlayer(playerData.getPlayerUuid());
|
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
|
playerData.refreshCacheTime(); // Refresh cache timer if player is online
|
||||||
// leaving combat logic
|
// leaving combat logic
|
||||||
if (playerData.getLastCombatCheckState() && !playerData.isInCombat()) {
|
if (playerData.getLastCombatCheckState() && !playerData.isInCombat()) {
|
||||||
@@ -169,7 +175,7 @@ public class PlayerManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!attackerPlayerData.isPvpEnabled()) {
|
if (!attackerPlayerData.isPvpEnabled() && (PreventStabby.worldGuardHookEnabled() && !WorldGuardHook.isPlayerForcedToPvp(Bukkit.getPlayer(attackerId)))) {
|
||||||
String message = switch (victimClassifier) {
|
String message = switch (victimClassifier) {
|
||||||
case PLAYER -> plugin.getConfigCache().cannot_attack_attacker;
|
case PLAYER -> plugin.getConfigCache().cannot_attack_attacker;
|
||||||
case PET -> plugin.getConfigCache().cannot_attack_pets_victim;
|
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));
|
return new DamageCheckResult(false, attackerId, victimId, message, victimClassifier.equals(Target.EntityClassifier.PLAYER));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!victimPlayerData.isPvpEnabled()) {
|
if (!victimPlayerData.isPvpEnabled() && (PreventStabby.worldGuardHookEnabled() && !WorldGuardHook.isPlayerForcedToPvp(Bukkit.getPlayer(victimId)))) {
|
||||||
String message = switch (victimClassifier) {
|
String message = switch (victimClassifier) {
|
||||||
case PLAYER -> plugin.getConfigCache().cannot_attack_victim;
|
case PLAYER -> plugin.getConfigCache().cannot_attack_victim;
|
||||||
case PET -> plugin.getConfigCache().cannot_attack_pets_attacker;
|
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 player is in cache update that
|
||||||
if (getPlayer(uuid) != null) {
|
if (getPlayer(uuid) != null) {
|
||||||
getPlayer(uuid).setPvpEnabled(state);
|
getPlayer(uuid).setPvpEnabled(state);
|
||||||
}
|
}
|
||||||
|
return CompletableFuture.runAsync(() -> {
|
||||||
// Update the database aswell
|
// Update the database aswell
|
||||||
plugin.getSqLite().updatePlayerInfo(uuid, new PlayerData(uuid, state));
|
plugin.getSqLite().updatePlayerInfo(uuid, new PlayerData(uuid, state));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Boolean> togglePlayerPvpState(UUID uuid) {
|
public CompletableFuture<Boolean> togglePlayerPvpState(UUID uuid) {
|
||||||
|
|||||||
@@ -15,17 +15,19 @@ import com.sk89q.worldguard.protection.regions.RegionQuery;
|
|||||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class WorldGuardHook {
|
public class WorldGuardHook {
|
||||||
|
|
||||||
private static FlagRegistry flagRegistry;
|
private static FlagRegistry flagRegistry;
|
||||||
public static StateFlag FORCE_PVP_FLAG;
|
public static StateFlag FORCE_PVP_FLAG;
|
||||||
|
|
||||||
public static void init() {
|
public static void init(Logger logger) {
|
||||||
try {
|
try {
|
||||||
Class.forName("com.sk89q.worldguard.protection.flags.registry.FlagRegistry");
|
Class.forName("com.sk89q.worldguard.protection.flags.registry.FlagRegistry");
|
||||||
WorldGuardPlugin worldGuardPlugin = WorldGuardPlugin.inst();
|
WorldGuardPlugin worldGuardPlugin = WorldGuardPlugin.inst();
|
||||||
if (WorldGuard.getInstance() == null || worldGuardPlugin == null) return;
|
if (WorldGuard.getInstance() == null || worldGuardPlugin == null) return;
|
||||||
PreventStabby.getPlugin().getLogger().info("[PreventStabby] Hooking into WorldGuard");
|
logger.info("Hooking into WorldGuard");
|
||||||
flagRegistry = WorldGuard.getInstance().getFlagRegistry();
|
flagRegistry = WorldGuard.getInstance().getFlagRegistry();
|
||||||
createForcePvpFlag();
|
createForcePvpFlag();
|
||||||
} catch (NoClassDefFoundError | ClassNotFoundException ignored) {
|
} catch (NoClassDefFoundError | ClassNotFoundException ignored) {
|
||||||
@@ -50,6 +52,8 @@ public class WorldGuardHook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isPlayerForcedToPvp(Player player) {
|
public static boolean isPlayerForcedToPvp(Player player) {
|
||||||
|
if (player == null) return false;
|
||||||
|
if (!PreventStabby.worldGuardHookEnabled()) return false;
|
||||||
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
|
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
|
||||||
RegionQuery query = container.createQuery();
|
RegionQuery query = container.createQuery();
|
||||||
org.bukkit.Location loc = player.getLocation();
|
org.bukkit.Location loc = player.getLocation();
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class EnvironmentalListener implements Listener {
|
|||||||
dangerousBuckets.add(Material.POWDER_SNOW_BUCKET);
|
dangerousBuckets.add(Material.POWDER_SNOW_BUCKET);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
public void onDangerousBucketDump(PlayerBucketEmptyEvent event) {
|
public void onDangerousBucketDump(PlayerBucketEmptyEvent event) {
|
||||||
ConfigCache config = plugin.getConfigCache();
|
ConfigCache config = plugin.getConfigCache();
|
||||||
if (!config.bucket_stopper_enabled) return;
|
if (!config.bucket_stopper_enabled) return;
|
||||||
@@ -53,7 +53,7 @@ public class EnvironmentalListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
public void onBlockIgnite(BlockIgniteEvent event) {
|
public void onBlockIgnite(BlockIgniteEvent event) {
|
||||||
ConfigCache config = plugin.getConfigCache();
|
ConfigCache config = plugin.getConfigCache();
|
||||||
if (!config.fire_stopper_enabled) return;
|
if (!config.fire_stopper_enabled) return;
|
||||||
@@ -77,14 +77,15 @@ public class EnvironmentalListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
public void onBlockIgnite(BlockPlaceEvent event) {
|
public void onDangerousBlockPlace(BlockPlaceEvent event) {
|
||||||
ConfigCache config = plugin.getConfigCache();
|
ConfigCache config = plugin.getConfigCache();
|
||||||
if (!config.block_stopper_enabled) return;
|
if (!config.block_stopper_enabled) return;
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
Location location = event.getBlock().getLocation().toCenterLocation();
|
Location location = event.getBlock().getLocation().toCenterLocation();
|
||||||
Target target = Target.getTarget(player);
|
Target target = Target.getTarget(player);
|
||||||
if (target == null) return;
|
if (target == null) return;
|
||||||
|
if (!config.getDangerousBlocks().contains(event.getBlock().getType())) return;
|
||||||
double radius = config.block_stopper_radius;
|
double radius = config.block_stopper_radius;
|
||||||
|
|
||||||
BoundingBox boundingBox = BoundingBox.of(location.toVector(), radius, radius, radius);
|
BoundingBox boundingBox = BoundingBox.of(location.toVector(), radius, radius, radius);
|
||||||
|
|||||||
@@ -2,19 +2,20 @@ package me.youhavetrouble.preventstabby.listeners;
|
|||||||
|
|
||||||
import me.youhavetrouble.preventstabby.PreventStabby;
|
import me.youhavetrouble.preventstabby.PreventStabby;
|
||||||
import me.youhavetrouble.preventstabby.data.DamageCheckResult;
|
import me.youhavetrouble.preventstabby.data.DamageCheckResult;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.*;
|
||||||
import org.bukkit.entity.Item;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.entity.AreaEffectCloudApplyEvent;
|
import org.bukkit.event.entity.AreaEffectCloudApplyEvent;
|
||||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
import org.bukkit.event.entity.PotionSplashEvent;
|
import org.bukkit.event.entity.PotionSplashEvent;
|
||||||
|
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||||
import org.bukkit.event.player.PlayerFishEvent;
|
import org.bukkit.event.player.PlayerFishEvent;
|
||||||
import org.bukkit.potion.PotionEffect;
|
import org.bukkit.potion.PotionEffect;
|
||||||
import org.bukkit.potion.PotionEffectType;
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
import org.bukkit.potion.PotionType;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public class PvpListener implements Listener {
|
public class PvpListener implements Listener {
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ public class PvpListener implements Listener {
|
|||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
public void onEntityDamage(EntityDamageByEntityEvent event) {
|
public void onEntityDamage(EntityDamageByEntityEvent event) {
|
||||||
Entity attacker = event.getDamager();
|
Entity attacker = event.getDamager();
|
||||||
Entity victim = event.getEntity();
|
Entity victim = event.getEntity();
|
||||||
@@ -36,7 +37,7 @@ public class PvpListener implements Listener {
|
|||||||
plugin.getPlayerManager().handleDamageCheck(result);
|
plugin.getPlayerManager().handleDamageCheck(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
public void onPotionSplash(PotionSplashEvent event) {
|
public void onPotionSplash(PotionSplashEvent event) {
|
||||||
if (!(event.getEntity().getShooter() instanceof Player thrower)) return;
|
if (!(event.getEntity().getShooter() instanceof Player thrower)) return;
|
||||||
boolean harmful = false;
|
boolean harmful = false;
|
||||||
@@ -56,11 +57,14 @@ public class PvpListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
public void onPotionCloudEffectApply(AreaEffectCloudApplyEvent event) {
|
public void onPotionCloudEffectApply(AreaEffectCloudApplyEvent event) {
|
||||||
if (!(event.getEntity().getSource() instanceof Player thrower)) return;
|
if (!(event.getEntity().getSource() instanceof Player thrower)) return;
|
||||||
boolean harmful = false;
|
boolean harmful = false;
|
||||||
for (PotionEffect effect : event.getEntity().getBasePotionType().getPotionEffects()) {
|
AreaEffectCloud cloud = event.getEntity();
|
||||||
|
if (cloud.getBasePotionType() == null) return;
|
||||||
|
PotionType potionType = cloud.getBasePotionType();
|
||||||
|
for (PotionEffect effect : potionType.getPotionEffects()) {
|
||||||
if (!PotionEffectType.Category.HARMFUL.equals(effect.getType().getEffectCategory())) continue;
|
if (!PotionEffectType.Category.HARMFUL.equals(effect.getType().getEffectCategory())) continue;
|
||||||
harmful = true;
|
harmful = true;
|
||||||
break;
|
break;
|
||||||
@@ -78,7 +82,7 @@ public class PvpListener implements Listener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
public void onFish(PlayerFishEvent event) {
|
public void onFish(PlayerFishEvent event) {
|
||||||
if (event.getCaught() instanceof Item) return;
|
if (event.getCaught() instanceof Item) return;
|
||||||
if (plugin.getConfigCache().allow_fishing_rod_pull) return;
|
if (plugin.getConfigCache().allow_fishing_rod_pull) return;
|
||||||
@@ -93,4 +97,19 @@ public class PvpListener implements Listener {
|
|||||||
plugin.getPlayerManager().handleDamageCheck(result);
|
plugin.getPlayerManager().handleDamageCheck(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
|
public void onCommandInCombat(PlayerCommandPreprocessEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (!plugin.getPlayerManager().getPlayer(player.getUniqueId()).isInCombat()) return;
|
||||||
|
String message = event.getMessage().toLowerCase(Locale.ROOT);
|
||||||
|
if (message.startsWith("/")) {
|
||||||
|
message = message.substring(1);
|
||||||
|
}
|
||||||
|
message = message.split(" ")[0];
|
||||||
|
if (!plugin.getConfigCache().getCombatBlockedCommands().contains(message)) return;
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
player.sendMessage(plugin.getConfigCache().cant_do_that_during_combat);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ name: PreventStabby
|
|||||||
version: ${project.version}
|
version: ${project.version}
|
||||||
main: me.youhavetrouble.preventstabby.PreventStabby
|
main: me.youhavetrouble.preventstabby.PreventStabby
|
||||||
authors: [YouHaveTrouble]
|
authors: [YouHaveTrouble]
|
||||||
api-version: 1.20
|
api-version: 1.21
|
||||||
folia-supported: true
|
folia-supported: true
|
||||||
description: Stop people from getting stabbed!
|
description: Stop people from getting stabbed!
|
||||||
soft-depend:
|
soft-depend:
|
||||||
|
|||||||
Reference in New Issue
Block a user