Added trust protections, made broadcasting not spam console, updated unique and armor checks.

This commit is contained in:
2025-03-27 20:08:06 -05:00
parent 1f6b172158
commit ab6b82272e
19 changed files with 149 additions and 23 deletions

Binary file not shown.

View File

@@ -18,4 +18,8 @@ commands:
usage: "/asmp usage" usage: "/asmp usage"
aliases: aliases:
- asmp - asmp
- armor_smp - armor_smp
ability:
description: Utilize unique abilities.
aliases:
- a

View File

@@ -1,6 +1,7 @@
package me.trouper.armorsmp; package me.trouper.armorsmp;
import io.github.itzispyder.pdk.PDK; import io.github.itzispyder.pdk.PDK;
import io.github.itzispyder.pdk.utils.misc.Timer;
import me.trouper.armorsmp.server.Manager; import me.trouper.armorsmp.server.Manager;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@@ -8,9 +9,11 @@ public final class ArmorSMP extends JavaPlugin {
private static ArmorSMP instance; private static ArmorSMP instance;
private Manager manager; private Manager manager;
private Timer timer;
@Override @Override
public void onLoad() { public void onLoad() {
timer = Timer.start();
getLogger().info("Instantiating Plugin"); getLogger().info("Instantiating Plugin");
instance = this; instance = this;
@@ -25,6 +28,7 @@ public final class ArmorSMP extends JavaPlugin {
getLogger().info("Initializing Manager"); getLogger().info("Initializing Manager");
manager.init(); manager.init();
getLogger().info("Successfully enabled ArmorSMP in %s".formatted(timer.end().getStampPrecise()));
} }
@Override @Override

View File

@@ -1,15 +1,26 @@
package me.trouper.armorsmp.data; package me.trouper.armorsmp.data;
import io.github.itzispyder.pdk.plugin.builders.ItemBuilder; import io.github.itzispyder.pdk.plugin.builders.ItemBuilder;
import io.github.itzispyder.pdk.utils.raytracers.CustomDisplayRaytracer;
import me.trouper.armorsmp.ArmorSMP;
import me.trouper.armorsmp.utils.Text; import me.trouper.armorsmp.utils.Text;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.AreaEffectCloud;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; 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.util.Vector;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Stream;
public enum Unique { public enum Unique {
HELMET(ItemBuilder.create() HELMET(ItemBuilder.create()
@@ -46,6 +57,25 @@ public enum Unique {
p.addPotionEffect(new PotionEffect(PotionEffectType.STRENGTH,21,0,true,false,false)); p.addPotionEffect(new PotionEffect(PotionEffectType.STRENGTH,21,0,true,false,false));
p.addPotionEffect(new PotionEffect(PotionEffectType.RESISTANCE,21,0,true,false,false)); p.addPotionEffect(new PotionEffect(PotionEffectType.RESISTANCE,21,0,true,false,false));
}, (p) -> { }, (p) -> {
// TODO: Test Dragon's Breath
World world = p.getWorld();
Location eyeLocation = p.getEyeLocation();
Vector direction = eyeLocation.getDirection();
Location hit = CustomDisplayRaytracer.trace(eyeLocation,direction,30,point -> {
Location particleLocation = point.getLoc();
world.spawnParticle(Particle.DRAGON_BREATH, particleLocation, 10, 0.2, 0.2, 0.2, 0.01);
return !point.getBlock().isPassable();
}).getLoc();
AreaEffectCloud cloud = (AreaEffectCloud) world.spawnEntity(hit, EntityType.AREA_EFFECT_CLOUD);
cloud.setRadius(3.0f);
cloud.setDuration(200);
cloud.setParticle(Particle.DRAGON_BREATH);
cloud.addCustomEffect(PotionEffectType.INSTANT_DAMAGE.createEffect(1,1),true);
cloud.setOwnerUniqueId(p.getUniqueId());
}, 50), }, 50),
LEGGINGS(ItemBuilder.create() LEGGINGS(ItemBuilder.create()
.material(Material.NETHERITE_LEGGINGS) .material(Material.NETHERITE_LEGGINGS)
@@ -61,9 +91,23 @@ public enum Unique {
.build(), .build(),
"Netherite Leggings", (p) -> { "Netherite Leggings", (p) -> {
p.addPotionEffect(new PotionEffect(PotionEffectType.RESISTANCE,21,0,true,false,false)); p.addPotionEffect(new PotionEffect(PotionEffectType.RESISTANCE,21,0,true,false,false));
}, (p) -> { }, (p) -> {
// TODO: yoink shield ability from OgreDupeAlias // TODO: Test Shield
Stream<Entity> toKnockBack = p.getNearbyEntities(10,10,10).stream().filter(target -> {
if (!(target instanceof Player v)) return false;
boolean tooClose = target.getLocation().distance(p.getLocation()) < 10;
boolean self = target.getUniqueId().equals(p.getUniqueId());
boolean trusted = ArmorSMP.getInstance().getManager().trust.getTrustees(p).contains(v.getUniqueId().toString());
return tooClose && !self && !trusted;
});
toKnockBack.forEach((target -> {
Vector direction = target.getLocation().toVector().subtract(p.getLocation().toVector());
direction.normalize();
direction.multiply(2);
direction.setY(direction.getY() + 0.5);
target.setVelocity(direction);
}));
}, 45), }, 45),
BOOTS(ItemBuilder.create() BOOTS(ItemBuilder.create()
.material(Material.NETHERITE_BOOTS) .material(Material.NETHERITE_BOOTS)
@@ -82,7 +126,10 @@ public enum Unique {
"Netherite Boots", (p) -> { "Netherite Boots", (p) -> {
p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,21,0,true,false,false)); p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED,21,0,true,false,false));
}, (p) -> { }, (p) -> {
// TODO: Vector math for dash ability Vector direction = p.getLocation().getDirection();
Vector velocity = direction.multiply(4); // TODO: Test Vector
p.setVelocity(velocity);
}, 50), }, 50),
MACE(ItemBuilder.create() MACE(ItemBuilder.create()
.material(Material.MACE) .material(Material.MACE)

View File

@@ -6,6 +6,7 @@ import io.github.itzispyder.pdk.commands.CustomCommand;
import io.github.itzispyder.pdk.commands.completions.CompletionBuilder; import io.github.itzispyder.pdk.commands.completions.CompletionBuilder;
import io.github.itzispyder.pdk.utils.misc.Cooldown; import io.github.itzispyder.pdk.utils.misc.Cooldown;
import io.github.itzispyder.pdk.utils.misc.Pair; import io.github.itzispyder.pdk.utils.misc.Pair;
import me.trouper.armorsmp.ArmorSMP;
import me.trouper.armorsmp.data.Unique; import me.trouper.armorsmp.data.Unique;
import me.trouper.armorsmp.utils.Text; import me.trouper.armorsmp.utils.Text;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@@ -13,12 +14,13 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import java.util.UUID; import java.util.UUID;
@CommandRegistry(value = "ability", printStackTrace = true, playersOnly = true) @CommandRegistry(value = "ability", printStackTrace = true, playersOnly = true)
public class AbilityCommand implements CustomCommand { public class AbilityCommand implements CustomCommand {
Cooldown<Pair<Unique, UUID>> abilityCooldown = new Cooldown<>(); private final Cooldown<Pair<Unique, UUID>> abilityCooldown = new Cooldown<>();
@Override @Override
public void dispatchCommand(CommandSender sender, Command command, String label, Args args) { public void dispatchCommand(CommandSender sender, Command command, String label, Args args) {
@@ -28,6 +30,10 @@ public class AbilityCommand implements CustomCommand {
Text.sendMessage(false, Text.Pallet.ERROR, sender, "Error: {0} is not a valid unique. Please choose from these values: ", args.get(2).toString(), Arrays.toString(Unique.values())); Text.sendMessage(false, Text.Pallet.ERROR, sender, "Error: {0} is not a valid unique. Please choose from these values: ", args.get(2).toString(), Arrays.toString(Unique.values()));
return; return;
} }
if (p.getUniqueId().toString().equals(ArmorSMP.getInstance().getManager().io.storage.uniques.owners.get(piece))) {
Text.sendMessage(false, Text.Pallet.WARNING, sender, "You do not own {0}.",piece.getCanonical());
return;
}
if (abilityCooldown.isOnCooldown(Pair.of(piece,p.getUniqueId()))) { if (abilityCooldown.isOnCooldown(Pair.of(piece,p.getUniqueId()))) {
Text.sendMessage(false, Text.Pallet.WARNING, sender, "The ability for your {0} is on cooldown for {1} seconds.",piece.getCanonical(),abilityCooldown.getCooldownSec(Pair.of(piece,p.getUniqueId()))); Text.sendMessage(false, Text.Pallet.WARNING, sender, "The ability for your {0} is on cooldown for {1} seconds.",piece.getCanonical(),abilityCooldown.getCooldownSec(Pair.of(piece,p.getUniqueId())));
return; return;

View File

@@ -5,9 +5,7 @@ import io.papermc.paper.event.entity.EntityDamageItemEvent;
import me.trouper.armorsmp.data.Unique; import me.trouper.armorsmp.data.Unique;
import org.bukkit.entity.Item; import org.bukkit.entity.Item;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByBlockEvent; import org.bukkit.event.entity.*;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.ItemDespawnEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
public class ItemDestroyEvents implements CustomListener { public class ItemDestroyEvents implements CustomListener {
@@ -28,7 +26,31 @@ public class ItemDestroyEvents implements CustomListener {
} }
@EventHandler @EventHandler
public void onBlockDamage(EntityDamageByEntityEvent e) { public void onEntityDamage(EntityDamageByEntityEvent e) {
if (!(e.getEntity() instanceof Item i)) return;
if (!Unique.isUnique(i.getItemStack())) return;
e.setCancelled(true);
}
@EventHandler
public void onCombust(EntityCombustEvent e) {
if (!(e.getEntity() instanceof Item i)) return;
if (!Unique.isUnique(i.getItemStack())) return;
e.setCancelled(true);
}
@EventHandler
public void onEntityCombust(EntityCombustByEntityEvent e) {
if (!(e.getEntity() instanceof Item i)) return;
if (!Unique.isUnique(i.getItemStack())) return;
e.setCancelled(true);
}
@EventHandler
public void onBlockCombust(EntityCombustByBlockEvent e) {
if (!(e.getEntity() instanceof Item i)) return; if (!(e.getEntity() instanceof Item i)) return;
if (!Unique.isUnique(i.getItemStack())) return; if (!Unique.isUnique(i.getItemStack())) return;

View File

@@ -31,7 +31,7 @@ public class JoinEvent implements CustomListener {
final Map<String, Boolean> armorCache = ArmorSMP.getInstance().getManager().io.storage.armorUpdateCache; final Map<String, Boolean> armorCache = ArmorSMP.getInstance().getManager().io.storage.armorUpdateCache;
if (armorCache.containsKey(p.getUniqueId().toString()) || !ArmorSMP.getInstance().getManager().armor.verifyArmor(p)) { if (armorCache.containsKey(p.getUniqueId().toString()) || !ArmorSMP.getInstance().getManager().armor.verifyArmor(p)) {
Verbose.send("Updating armor"); Verbose.send("Updating armor");
ArmorSMP.getInstance().getManager().armor.queueUpdate(p,armorCache.get(p.getUniqueId().toString())); ArmorSMP.getInstance().getManager().armor.queueUpdate(p,armorCache.getOrDefault(p.getUniqueId().toString(),true));
ArmorSMP.getInstance().getManager().io.storage.armorUpdateCache.remove(p.getUniqueId().toString()); ArmorSMP.getInstance().getManager().io.storage.armorUpdateCache.remove(p.getUniqueId().toString());
} }
final Set<String> uniquesCache = ArmorSMP.getInstance().getManager().io.storage.uniqueUpdateCache; final Set<String> uniquesCache = ArmorSMP.getInstance().getManager().io.storage.uniqueUpdateCache;

View File

@@ -0,0 +1,30 @@
package me.trouper.armorsmp.server.events;
import io.github.itzispyder.pdk.events.CustomListener;
import me.trouper.armorsmp.ArmorSMP;
import org.bukkit.entity.AreaEffectCloud;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import java.util.Set;
public class TrustEvents implements CustomListener {
@EventHandler
public void onDamage(EntityDamageByEntityEvent e) {
if (!(e.getEntity() instanceof Player v)) return;
Set<String> trustees = ArmorSMP.getInstance().getManager().trust.getTrustees(v);
String damager = e.getDamager().getUniqueId().toString();
if (trustees.contains(damager)) {
e.setCancelled(true);
return;
}
if (e.getDamager() instanceof AreaEffectCloud aoe && aoe.getOwnerUniqueId() != null) {
if (trustees.contains(aoe.getOwnerUniqueId().toString())) {
e.setCancelled(true);
return;
}
}
}
}

View File

@@ -51,7 +51,7 @@ public class ArmorBackend {
} }
public boolean upTier(OfflinePlayer target) { public boolean upTier(OfflinePlayer target) {
int numeric = storage.userData.playerTiers.get(target.getUniqueId().toString()).getNumeric(); int numeric = storage.userData.playerTiers.computeIfAbsent(target.getUniqueId().toString(),tier->ArmorTier.NONE).getNumeric();
Verbose.send("Upgrading %s, current numeric: %s",target.getName(),numeric); Verbose.send("Upgrading %s, current numeric: %s",target.getName(),numeric);
if (numeric > 4) return false; if (numeric > 4) return false;
numeric++; numeric++;

View File

@@ -4,6 +4,7 @@ import io.github.itzispyder.pdk.utils.misc.Randomizer;
import me.trouper.armorsmp.ArmorSMP; import me.trouper.armorsmp.ArmorSMP;
import me.trouper.armorsmp.data.io.IO; import me.trouper.armorsmp.data.io.IO;
import me.trouper.armorsmp.utils.Text; import me.trouper.armorsmp.utils.Text;
import org.bukkit.entity.Player;
public class Broadcaster { public class Broadcaster {
@@ -15,6 +16,9 @@ public class Broadcaster {
public void broadcastTip() { public void broadcastTip() {
String tip = new Randomizer().getRandomElement(io.config.tips.tipList); String tip = new Randomizer().getRandomElement(io.config.tips.tipList);
ArmorSMP.getInstance().getServer().broadcast(Text.getMessage(false, Text.Pallet.NEUTRAL,tip)); for (Player onlinePlayer : ArmorSMP.getInstance().getServer().getOnlinePlayers()) {
if (ArmorSMP.getInstance().getManager().io.storage.userData.tipsDisabled.contains(onlinePlayer.getUniqueId().toString())) continue;
onlinePlayer.sendMessage(Text.getMessage(false, Text.Pallet.NEUTRAL,tip));
}
} }
} }

View File

@@ -1,5 +1,6 @@
package me.trouper.armorsmp.server.systems; package me.trouper.armorsmp.server.systems;
import me.trouper.armorsmp.ArmorSMP;
import me.trouper.armorsmp.data.io.IO; import me.trouper.armorsmp.data.io.IO;
import me.trouper.armorsmp.data.io.Storage; import me.trouper.armorsmp.data.io.Storage;
import me.trouper.armorsmp.data.Unique; import me.trouper.armorsmp.data.Unique;
@@ -7,6 +8,8 @@ import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.UUID;
public class UniquesBackend { public class UniquesBackend {
private final Storage storage; private final Storage storage;
@@ -15,20 +18,22 @@ public class UniquesBackend {
storage = io.storage; storage = io.storage;
} }
private void updateUniques(Player p) { private void updateUniques() {
if (!storage.uniques.owners.containsValue(p.getUniqueId().toString())) return; ArmorSMP.getInstance().getServer().getOnlinePlayers().forEach(this::updateUniques);
for (Player player : Bukkit.getOnlinePlayers()) { }
} public void updateUniques(Player p) {
storage.uniques.owners.forEach((unique,owner)->{ ArmorSMP.getInstance().getManager().io.storage.uniques.owners.forEach(((unique, id) -> {
if (unique.equals(Unique.MACE) || unique.equals(Unique.SWORD) || unique.equals(Unique.AXE) && owner.equals(p.getUniqueId().toString()) && !p.getInventory().contains(unique.getInGameItem())) { if (id.equals(p.getUniqueId().toString())) {
p.getInventory().addItem(unique.getInGameItem()); if (!p.getInventory().contains(unique.getInGameItem())) p.getInventory().addItem(unique.getInGameItem());
} else {
p.getInventory().removeItemAnySlot(unique.getInGameItem());
} }
}); }));
} }
public void queueUpdate(OfflinePlayer target) { public void queueUpdate(OfflinePlayer target) {
if (target.getPlayer() != null && target.isOnline()) updateUniques(target.getPlayer()); if (target.getPlayer() != null && target.isOnline()) updateUniques();
else storage.uniqueUpdateCache.add(target.getUniqueId().toString()); else storage.uniqueUpdateCache.add(target.getUniqueId().toString());
} }

View File

@@ -18,4 +18,8 @@ commands:
usage: "/asmp usage" usage: "/asmp usage"
aliases: aliases:
- asmp - asmp
- armor_smp - armor_smp
ability:
description: Utilize unique abilities.
aliases:
- a