9
0
mirror of https://github.com/Auxilor/EcoMobs.git synced 2025-12-22 08:29:20 +00:00

Initial commit

This commit is contained in:
Auxilor
2020-12-08 18:55:16 +00:00
commit 733cd22c29
114 changed files with 4984 additions and 0 deletions

23
.gitignore vendored Normal file
View File

@@ -0,0 +1,23 @@
# Java
*.class
# Eclipse IDE
.settings/
bin/
.classpath
.project
# IntelliJ IDEA
.idea/
*.iml
# Gradle
.gradle
**/build/
!src/**/build/
.gradletasknamecache
!gradle-wrapper.jar
gradle-app.setting
# Mac OSX
.DS_Store

44
LICENSE.md Normal file
View File

@@ -0,0 +1,44 @@
# ILLUSIONER LICENSE
## Version 1.0, August 2020
## Definitions
"Package" refers to the collection of files (unless something else is indicated inside the file) distributed
by the Copyright Holder, and derivatives of that collection of files created through textual modification.
"Copyright Holder" is whoever is named in the copyright or copyrights for the package.
"You" is you, if you're thinking about copying or distributing this Package.
## Copyright (C) 2020 Will Favier-Parsons
You are not allowed to redistribute full, partial or modified versions of the package to which the license
is associated. This license does not apply to modules or extensions that use but do not contain full,
partial or modified code from this package.
By purchasing the package from the offical distributor (spigotmc.org) you agree to the following terms:
1. No refunds, under any circumstance, unless explicitly approved by the copyright holder.
2. You are of legal age and/or have permission from your legal guardian.
## ILLUSIONER LICENSE
### TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
1. Do whatever you like with the original work, as long as you keep it for yourself or have the Copyright
Holder's permission.
2. You are not allowed to redistribute full, partial or modified versions of the package
3. Code is provided with no warranty. You have the right (and are even encouraged) to propose improvements
to the package as long as you don't use it as a way to circumvent the restrictions of the license.
4. By proposing a modification you agree to assign all your rights on your code to the Copyright Holder.
You must therefore own the modifications you propose or have the permission to assign their rights.
5. All modified versions of the package must also be open-source

9
NMS/API/build.gradle Normal file
View File

@@ -0,0 +1,9 @@
dependencies {
compileOnly 'org.spigotmc:spigot-api:1.15.2-R0.1-SNAPSHOT'
}
jar{
archiveFileName = findProperty("Name") + " v" + findProperty("version") + ".jar"
}
description = 'Illusioner API'

View File

@@ -0,0 +1,11 @@
package com.willfp.illusioner.nms.api;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
/**
* NMS Interface for breaking blocks as player
*/
public interface BlockBreakWrapper {
void breakBlock(Player player, Block block);
}

View File

@@ -0,0 +1,10 @@
package com.willfp.illusioner.nms.api;
import org.bukkit.entity.Player;
/**
* NMS Interface for getting attack cooldown
*/
public interface CooldownWrapper {
double getAttackCooldown(Player player);
}

View File

@@ -0,0 +1,12 @@
package com.willfp.illusioner.nms.api;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.plugin.Plugin;
/**
* NMS Interface for managing illusioner bosses
*/
public interface EntityIllusionerWrapper {
void createBossbar(Plugin plugin, BarColor color, BarStyle style);
}

View File

@@ -0,0 +1,10 @@
package com.willfp.illusioner.nms.api;
import org.bukkit.Location;
/**
* NMS Interface for managing illusioner bosses
*/
public interface IllusionerWrapper {
EntityIllusionerWrapper spawn(Location location, double maxHealth, double attackDamage);
}

View File

@@ -0,0 +1,7 @@
package com.willfp.illusioner.nms.api;
import org.bukkit.entity.Player;
public interface OpenInventoryWrapper {
Object getOpenInventory(Player player);
}

View File

@@ -0,0 +1,11 @@
package com.willfp.illusioner.nms.api;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
/**
* NMS Interface for getting an ItemStack from a Trident
*/
public interface TridentStackWrapper {
ItemStack getTridentStack(Trident trident);
}

10
NMS/v1_15_R1/build.gradle Normal file
View File

@@ -0,0 +1,10 @@
dependencies {
compileOnly project(':API')
compileOnly 'org.spigotmc:spigot:1.15.2-R0.1-SNAPSHOT'
}
jar{
archiveFileName = project.name + " v" + findProperty("version") + ".jar"
}
description = 'v1_15_R1'

View File

@@ -0,0 +1,14 @@
package com.willfp.illusioner.v1_15_R1;
import com.willfp.illusioner.nms.api.BlockBreakWrapper;
import net.minecraft.server.v1_15_R1.BlockPosition;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class BlockBreak implements BlockBreakWrapper {
@Override
public void breakBlock(Player player, Block block) {
((CraftPlayer)player).getHandle().playerInteractManager.breakBlock(new BlockPosition(block.getX(), block.getY(), block.getZ()));
}
}

View File

@@ -0,0 +1,14 @@
package com.willfp.illusioner.v1_15_R1;
import com.willfp.illusioner.nms.api.CooldownWrapper;
import net.minecraft.server.v1_15_R1.EntityHuman;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class Cooldown implements CooldownWrapper {
@Override
public double getAttackCooldown(Player player) {
EntityHuman entityHuman = ((CraftPlayer) player).getHandle();
return entityHuman.s(0);
}
}

View File

@@ -0,0 +1,12 @@
package com.willfp.illusioner.v1_15_R1;
import com.willfp.illusioner.nms.api.OpenInventoryWrapper;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class OpenInventory implements OpenInventoryWrapper {
@Override
public Object getOpenInventory(Player player) {
return ((CraftPlayer) player).getHandle().activeContainer;
}
}

View File

@@ -0,0 +1,16 @@
package com.willfp.illusioner.v1_15_R1;
import com.willfp.illusioner.nms.api.TridentStackWrapper;
import net.minecraft.server.v1_15_R1.EntityThrownTrident;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftTrident;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
public class TridentStack implements TridentStackWrapper {
@Override
public ItemStack getTridentStack(Trident trident) {
EntityThrownTrident t = ((CraftTrident) trident).getHandle();
return CraftItemStack.asBukkitCopy(t.trident);
}
}

10
NMS/v1_16_R1/build.gradle Normal file
View File

@@ -0,0 +1,10 @@
dependencies {
compileOnly project(':API')
compileOnly 'org.spigotmc:spigot:1.16.1-R0.1-SNAPSHOT'
}
jar{
archiveFileName = project.name + " v" + findProperty("version") + ".jar"
}
description = 'v1_16_R1'

View File

@@ -0,0 +1,14 @@
package com.willfp.illusioner.v1_16_R1;
import com.willfp.illusioner.nms.api.BlockBreakWrapper;
import net.minecraft.server.v1_16_R1.BlockPosition;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class BlockBreak implements BlockBreakWrapper {
@Override
public void breakBlock(Player player, Block block) {
((CraftPlayer)player).getHandle().playerInteractManager.breakBlock(new BlockPosition(block.getX(), block.getY(), block.getZ()));
}
}

View File

@@ -0,0 +1,11 @@
package com.willfp.illusioner.v1_16_R1;
import com.willfp.illusioner.nms.api.CooldownWrapper;
import org.bukkit.entity.Player;
public class Cooldown implements CooldownWrapper {
@Override
public double getAttackCooldown(Player player) {
return player.getAttackCooldown();
}
}

View File

@@ -0,0 +1,12 @@
package com.willfp.illusioner.v1_16_R1;
import com.willfp.illusioner.nms.api.OpenInventoryWrapper;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class OpenInventory implements OpenInventoryWrapper {
@Override
public Object getOpenInventory(Player player) {
return ((CraftPlayer) player).getHandle().activeContainer;
}
}

View File

@@ -0,0 +1,16 @@
package com.willfp.illusioner.v1_16_R1;
import com.willfp.illusioner.nms.api.TridentStackWrapper;
import net.minecraft.server.v1_16_R1.EntityThrownTrident;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftTrident;
import org.bukkit.craftbukkit.v1_16_R1.inventory.CraftItemStack;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
public class TridentStack implements TridentStackWrapper {
@Override
public ItemStack getTridentStack(Trident trident) {
EntityThrownTrident t = ((CraftTrident) trident).getHandle();
return CraftItemStack.asBukkitCopy(t.trident);
}
}

10
NMS/v1_16_R2/build.gradle Normal file
View File

@@ -0,0 +1,10 @@
dependencies {
compileOnly project(':API')
compileOnly 'org.spigotmc:spigot:1.16.2-R0.1-SNAPSHOT'
}
jar{
archiveFileName = project.name + " v" + findProperty("version") + ".jar"
}
description = 'v1_16_R2'

View File

@@ -0,0 +1,14 @@
package com.willfp.illusioner.v1_16_R2;
import com.willfp.illusioner.nms.api.BlockBreakWrapper;
import net.minecraft.server.v1_16_R2.BlockPosition;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class BlockBreak implements BlockBreakWrapper {
@Override
public void breakBlock(Player player, Block block) {
((CraftPlayer)player).getHandle().playerInteractManager.breakBlock(new BlockPosition(block.getX(), block.getY(), block.getZ()));
}
}

View File

@@ -0,0 +1,11 @@
package com.willfp.illusioner.v1_16_R2;
import com.willfp.illusioner.nms.api.CooldownWrapper;
import org.bukkit.entity.Player;
public class Cooldown implements CooldownWrapper {
@Override
public double getAttackCooldown(Player player) {
return player.getAttackCooldown();
}
}

View File

@@ -0,0 +1,12 @@
package com.willfp.illusioner.v1_16_R2;
import com.willfp.illusioner.nms.api.OpenInventoryWrapper;
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class OpenInventory implements OpenInventoryWrapper {
@Override
public Object getOpenInventory(Player player) {
return ((CraftPlayer) player).getHandle().activeContainer;
}
}

View File

@@ -0,0 +1,16 @@
package com.willfp.illusioner.v1_16_R2;
import com.willfp.illusioner.nms.api.TridentStackWrapper;
import net.minecraft.server.v1_16_R2.EntityThrownTrident;
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftTrident;
import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
public class TridentStack implements TridentStackWrapper {
@Override
public ItemStack getTridentStack(Trident trident) {
EntityThrownTrident t = ((CraftTrident) trident).getHandle();
return CraftItemStack.asBukkitCopy(t.trident);
}
}

10
NMS/v1_16_R3/build.gradle Normal file
View File

@@ -0,0 +1,10 @@
dependencies {
compileOnly project(':API')
compileOnly 'org.spigotmc:spigot:1.16.4-R0.1-SNAPSHOT'
}
jar{
archiveFileName = project.name + " v" + findProperty("version") + ".jar"
}
description = 'v1_16_R3'

View File

@@ -0,0 +1,14 @@
package com.willfp.illusioner.v1_16_R3;
import com.willfp.illusioner.nms.api.BlockBreakWrapper;
import net.minecraft.server.v1_16_R3.BlockPosition;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class BlockBreak implements BlockBreakWrapper {
@Override
public void breakBlock(Player player, Block block) {
((CraftPlayer)player).getHandle().playerInteractManager.breakBlock(new BlockPosition(block.getX(), block.getY(), block.getZ()));
}
}

View File

@@ -0,0 +1,11 @@
package com.willfp.illusioner.v1_16_R3;
import com.willfp.illusioner.nms.api.CooldownWrapper;
import org.bukkit.entity.Player;
public class Cooldown implements CooldownWrapper {
@Override
public double getAttackCooldown(Player player) {
return player.getAttackCooldown();
}
}

View File

@@ -0,0 +1,64 @@
package com.willfp.illusioner.v1_16_R3;
import com.willfp.illusioner.nms.api.EntityIllusionerWrapper;
import net.minecraft.server.v1_16_R3.*;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.attribute.Attribute;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarFlag;
import org.bukkit.boss.BarStyle;
import org.bukkit.boss.BossBar;
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
import org.bukkit.entity.LivingEntity;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
public class EntityIllusioner extends EntityIllagerIllusioner implements EntityIllusionerWrapper {
public EntityIllusioner(Location location, double maxHealth, double attackDamage) {
super(EntityTypes.ILLUSIONER, ((CraftWorld) location.getWorld()).getHandle());
this.setPosition(location.getX(), location.getY(), location.getZ());
this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(maxHealth);
this.setHealth((float) maxHealth);
this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(attackDamage);
this.goalSelector.a(0, new PathfinderGoalFloat(this));
this.goalSelector.a(1, new EntityIllagerWizard.b());
this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0D, false));
this.goalSelector.a(2, new PathfinderGoalBowShoot<>(this, 1.0D, 20, 15.0F));
this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D));
this.goalSelector.a(0, new PathfinderGoalFloat(this));
this.goalSelector.a(6, new PathfinderGoalBowShoot(this, 0.5D, 20, 15.0F));
this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D));
this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F));
this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F));
this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0]));
this.targetSelector.a(2, (new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, true)).a(300));
this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget(this, EntityVillagerAbstract.class, false)).a(300));
this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget(this, EntityIronGolem.class, false)).a(300));
}
@Override
public void createBossbar(Plugin plugin, BarColor color, BarStyle style) {
String name = this.getName();
BossBar bossBar = Bukkit.getServer().createBossBar(name, color, style, (BarFlag) null);
Bukkit.getServer().getOnlinePlayers().forEach(bossBar::addPlayer);
LivingEntity entity = (LivingEntity) this.getBukkitEntity();
new BukkitRunnable() {
@Override
public void run() {
if(!entity.isDead()) {
bossBar.setProgress(entity.getHealth() / entity.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue());
} else {
bossBar.getPlayers().forEach(bossBar::removePlayer);
bossBar.setVisible(false);
this.cancel();
}
}
}.runTaskTimer(plugin, 0, 1);
}
}

View File

@@ -0,0 +1,15 @@
package com.willfp.illusioner.v1_16_R3;
import com.willfp.illusioner.nms.api.EntityIllusionerWrapper;
import com.willfp.illusioner.nms.api.IllusionerWrapper;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
public class Illusioner implements IllusionerWrapper {
@Override
public EntityIllusionerWrapper spawn(Location location, double maxHealth, double attackDamage) {
EntityIllusioner illusioner = new EntityIllusioner(location, maxHealth, attackDamage);
((CraftWorld) location.getWorld()).getHandle().addEntity(illusioner);
return illusioner;
}
}

View File

@@ -0,0 +1,12 @@
package com.willfp.illusioner.v1_16_R3;
import com.willfp.illusioner.nms.api.OpenInventoryWrapper;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class OpenInventory implements OpenInventoryWrapper {
@Override
public Object getOpenInventory(Player player) {
return ((CraftPlayer) player).getHandle().activeContainer;
}
}

View File

@@ -0,0 +1,16 @@
package com.willfp.illusioner.v1_16_R3;
import com.willfp.illusioner.nms.api.TridentStackWrapper;
import net.minecraft.server.v1_16_R3.EntityThrownTrident;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftTrident;
import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
public class TridentStack implements TridentStackWrapper {
@Override
public ItemStack getTridentStack(Trident trident) {
EntityThrownTrident t = ((CraftTrident) trident).getHandle();
return CraftItemStack.asBukkitCopy(t.trident);
}
}

61
Plugin/build.gradle Normal file
View File

@@ -0,0 +1,61 @@
plugins {
id 'com.github.johnrengelman.shadow' version '5.2.0'
}
dependencies {
implementation project(':API')
implementation project(':v1_15_R1')
implementation project(':v1_16_R1')
implementation project(':v1_16_R2')
implementation project(':v1_16_R3')
implementation 'org.apache.maven:maven-artifact:3.0.3'
implementation 'org.jetbrains:annotations:19.0.0'
implementation 'org.bstats:bstats-bukkit:1.7'
compileOnly 'org.spigotmc:spigot-api:1.16.3-R0.1-SNAPSHOT'
compileOnly 'commons-io:commons-io:2.8.0'
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.4-SNAPSHOT'
compileOnly 'com.github.TechFortress:GriefPrevention:16.14.0'
compileOnly 'com.massivecraft:Factions:1.6.9.5-U0.5.10'
compileOnly 'com.github.cryptomorin:kingdoms:1.10.3.1'
shadow files('../lib/SpartanAPI.jar')
compileOnly 'com.github.TownyAdvanced:Towny:0.96.2.0'
compileOnly 'com.github.angeschossen:LandsAPI:4.7.3'
compileOnly 'fr.neatmonster:nocheatplus:3.16.1-SNAPSHOT'
compileOnly 'de.janmm14:aac-api:4.2.0'
compileOnly 'com.github.jiangdashao:matrix-api-repo:317d4635fd'
compileOnly 'com.comphenix.protocol:ProtocolLib:4.6.0-SNAPSHOT'
compileOnly 'com.destroystokyo.paper:paper-api:1.16.3-R0.1-SNAPSHOT'
compileOnly 'com.gmail.nossr50.mcMMO:mcMMO:2.1.157'
compileOnly 'me.clip:placeholderapi:2.10.9'
}
shadowJar {
relocate('org.bstats.bukkit', 'com.willfp.illusioner.shaded.bstats')
relocate('org.jetbrains', 'com.willfp.illusioner.shaded.jetbrains')
relocate('org.intellij', 'com.willfp.illusioner.shaded.intellij')
relocate('org.apache.maven', 'com.willfp.illusioner.shaded.maven')
archiveFileName = findProperty("plugin-name") + " v" + findProperty("version") + ".jar"
}
processResources {
filesNotMatching(["**/*.png", "**/models/**", "**/textures/**"]) {
expand projectVersion: findProperty("version")
}
}
jar {
archiveFileName = findProperty("plugin-name") + " v" + findProperty("version") + " " + "unshaded" + ".jar"
}
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
tasks.withType(Jar) {
destinationDirectory = file("$rootDir/bin/")
}
build.dependsOn shadowJar
description = 'Illusioner'
compileJava.options.encoding = 'UTF-8'

View File

@@ -0,0 +1,49 @@
package com.willfp.illusioner;
import com.willfp.illusioner.util.internal.Loader;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
/**
* The Main class for Illusioner
*/
public class IllusionerPlugin extends JavaPlugin {
/**
* Instance of Illusioner
*/
private static IllusionerPlugin instance;
/**
* NMS version
*/
public static final String NMS_VERSION = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
/**
* Calls {@link Loader#load()}
*/
public void onEnable() {
Loader.load();
}
/**
* Calls {@link Loader#unload()}
*/
public void onDisable() {
Loader.unload();
}
/**
* Sets instance
*/
public void onLoad() {
instance = this;
}
/**
* Get plugin instance
* @return Plugin instance
*/
public static IllusionerPlugin getInstance() {
return instance;
}
}

View File

@@ -0,0 +1,71 @@
package com.willfp.illusioner.command;
import com.willfp.illusioner.config.ConfigManager;
import com.willfp.illusioner.util.interfaces.Registerable;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
public abstract class AbstractCommand implements CommandExecutor, Registerable {
private final String name;
private final String permission;
private final boolean playersOnly;
protected AbstractCommand(String name, String permission, boolean playersOnly) {
this.name = name;
this.permission = permission;
this.playersOnly = playersOnly;
}
public AbstractTabCompleter getTab() {
return null;
}
public String getPermission() {
return this.permission;
}
public String getName() {
return this.name;
}
@Override
public boolean onCommand(@NotNull CommandSender sender, Command command, @NotNull String label, String[] args) {
if(!command.getName().equalsIgnoreCase(name)) return false;
if(playersOnly && !(sender instanceof Player)) {
sender.sendMessage(ConfigManager.getLang().getMessage("not-player"));
return true;
}
if (!sender.hasPermission(permission) && sender instanceof Player) {
sender.sendMessage(ConfigManager.getLang().getNoPermission());
return true;
}
onExecute(sender, Arrays.asList(args));
return true;
}
@Override
public final void register() {
PluginCommand command = Bukkit.getPluginCommand(name);
assert command != null;
command.setExecutor(this);
AbstractTabCompleter tabCompleter = this.getTab();
if(tabCompleter != null) {
command.setTabCompleter(tabCompleter);
}
}
public abstract void onExecute(CommandSender sender, List<String> args);
}

View File

@@ -0,0 +1,31 @@
package com.willfp.illusioner.command;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
public abstract class AbstractTabCompleter implements TabCompleter {
private final AbstractCommand command;
public AbstractTabCompleter(AbstractCommand command) {
this.command = command;
}
@Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(!command.getName().equalsIgnoreCase(this.command.getName()))
return null;
if(!sender.hasPermission(this.command.getPermission()))
return null;
return onTab(sender, Arrays.asList(args));
}
public abstract List<String> onTab(CommandSender sender, List<String> args);
}

View File

@@ -0,0 +1,41 @@
package com.willfp.illusioner.command.commands;
import com.willfp.illusioner.IllusionerPlugin;
import com.willfp.illusioner.command.AbstractCommand;
import com.willfp.illusioner.util.internal.Logger;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
@SuppressWarnings("unchecked")
public class CommandIldebug extends AbstractCommand {
public CommandIldebug() {
super("ildebug", "illusioner.debug", false);
}
@Override
public void onExecute(CommandSender sender, List<String> args) {
Logger.info("--------------- BEGIN DEBUG ----------------");
if(sender instanceof Player) {
Player player = (Player) sender;
player.sendMessage("Held Item: " + player.getInventory().getItemInMainHand().toString());
Logger.info("");
Logger.info("Held Item: " + player.getInventory().getItemInMainHand().toString());
Logger.info("");
}
Logger.info("Running Version: " + IllusionerPlugin.getInstance().getDescription().getVersion());
Logger.info("");
Logger.info("Server Information: ");
Logger.info("Players Online: " + Bukkit.getServer().getOnlinePlayers().size());
Logger.info("Bukkit IP: " + Bukkit.getIp());
Logger.info("Running Version: " + Bukkit.getVersion() + ", Bukkit Version: " + Bukkit.getBukkitVersion() + ", Alt Version: " + Bukkit.getServer().getVersion());
Logger.info("Motd: " + Bukkit.getServer().getMotd());
Logger.info("--------------- END DEBUG ----------------");
}
}

View File

@@ -0,0 +1,20 @@
package com.willfp.illusioner.command.commands;
import com.willfp.illusioner.command.AbstractCommand;
import com.willfp.illusioner.config.ConfigManager;
import com.willfp.illusioner.util.internal.Loader;
import org.bukkit.command.CommandSender;
import java.util.List;
public class CommandIlreload extends AbstractCommand {
public CommandIlreload() {
super("ilreload", "illusioner.reload", false);
}
@Override
public void onExecute(CommandSender sender, List<String> args) {
Loader.reload();
sender.sendMessage(ConfigManager.getLang().getMessage("reloaded"));
}
}

View File

@@ -0,0 +1,34 @@
package com.willfp.illusioner.config;
import com.willfp.illusioner.config.configs.Config;
import com.willfp.illusioner.config.configs.Lang;
public class ConfigManager {
private static final Lang LANG = new Lang();
private static final Config CONFIG = new Config();
/**
* Update all configs
* Called on /ecoreload
*/
public static void updateConfigs() {
LANG.update();
CONFIG.update();
}
/**
* Get lang.yml
* @return lang.yml
*/
public static Lang getLang() {
return LANG;
}
/**
* Get config.yml
* @return config.yml
*/
public static Config getConfig() {
return CONFIG;
}
}

View File

@@ -0,0 +1,77 @@
package com.willfp.illusioner.config;
import com.willfp.illusioner.IllusionerPlugin;
import com.willfp.illusioner.util.internal.Logger;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
public abstract class UpdatingYamlConfig {
public YamlConfiguration config;
private File configFile;
private final String name;
private final boolean removeUnused;
public UpdatingYamlConfig(String name, boolean removeUnused) {
this.name = name + ".yml";
this.removeUnused = removeUnused;
init();
}
private void init() {
if (!new File(IllusionerPlugin.getInstance().getDataFolder(), name).exists()) {
createFile();
}
this.configFile = new File(IllusionerPlugin.getInstance().getDataFolder(), name);
this.config = YamlConfiguration.loadConfiguration(configFile);
update();
}
private void createFile() {
IllusionerPlugin.getInstance().saveResource(name, false);
}
public void update() {
try {
config.load(configFile);
InputStream newIn = IllusionerPlugin.getInstance().getResource(name);
if(newIn == null) {
Logger.error(name + " is null?");
return;
}
BufferedReader reader = new BufferedReader(new InputStreamReader(newIn, StandardCharsets.UTF_8));
YamlConfiguration newConfig = new YamlConfiguration();
newConfig.load(reader);
if(newConfig.getKeys(true).equals(config.getKeys(true)))
return;
newConfig.getKeys(true).forEach((s -> {
if (!config.getKeys(true).contains(s)) {
config.set(s, newConfig.get(s));
}
}));
if(this.removeUnused) {
config.getKeys(true).forEach((s -> {
if(!newConfig.getKeys(true).contains(s)) {
config.set(s, null);
}
}));
}
config.save(configFile);
} catch (IOException | InvalidConfigurationException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,55 @@
package com.willfp.illusioner.config.configs;
import com.willfp.illusioner.config.UpdatingYamlConfig;
import org.bukkit.inventory.ItemStack;
import java.util.List;
/**
* Wrapper for config.yml
*/
public class Config extends UpdatingYamlConfig {
public Config() {
super("config", true);
}
public int getInt(String path) {
return config.getInt(path);
}
public int getInt(String path, int def) {
return config.getInt(path, def);
}
public List<Integer> getInts(String path) {
return config.getIntegerList(path);
}
public boolean getBool(String path) {
return config.getBoolean(path);
}
public List<Boolean> getBools(String path) {
return config.getBooleanList(path);
}
public String getString(String path) {
return config.getString(path);
}
public List<String> getStrings(String path) {
return config.getStringList(path);
}
public double getDouble(String path) {
return config.getDouble(path);
}
public List<Double> getDoubles(String path) {
return config.getDoubleList(path);
}
public ItemStack getItemStack(String path) {
return config.getItemStack(path);
}
}

View File

@@ -0,0 +1,36 @@
package com.willfp.illusioner.config.configs;
import com.willfp.illusioner.config.UpdatingYamlConfig;
import com.willfp.illusioner.util.StringUtils;
import java.util.List;
/**
* Wrapper for lang.yml
*/
public class Lang extends UpdatingYamlConfig {
public Lang() {
super("lang", false);
}
public String getString(String path) {
return StringUtils.translate(String.valueOf(config.getString(path)));
}
public List<String> getStrings(String path) {
return config.getStringList(path);
}
public String getPrefix() {
return StringUtils.translate(config.getString("messages.prefix"));
}
public String getNoPermission() {
return getPrefix() + StringUtils.translate(config.getString("messages.no-permission"));
}
public String getMessage(String message) {
return getPrefix() + StringUtils.translate(config.getString("messages." + message));
}
}

View File

@@ -0,0 +1,123 @@
package com.willfp.illusioner.events.armorequip;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
/**
* @author Arnah
* @since Jul 30, 2015
*/
public class ArmorEquipEvent extends PlayerEvent implements Cancellable {
private static final HandlerList handlers = new HandlerList();
private boolean cancel = false;
private final EquipMethod equipType;
private final ArmorType type;
private ItemStack oldArmorPiece, newArmorPiece;
public ArmorEquipEvent(final Player player, final EquipMethod equipType, final ArmorType type, final ItemStack oldArmorPiece, final ItemStack newArmorPiece) {
super(player);
this.equipType = equipType;
this.type = type;
this.oldArmorPiece = oldArmorPiece;
this.newArmorPiece = newArmorPiece;
}
/**
* Gets a list of handlers handling this event.
*
* @return A list of handlers handling this event.
*/
@Override
public @NotNull HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
/**
* Sets if this event should be cancelled.
*
* @param cancel If this event should be cancelled.
*/
public final void setCancelled(final boolean cancel) {
this.cancel = cancel;
}
/**
* Gets if this event is cancelled.
*
* @return If this event is cancelled
*/
public final boolean isCancelled() {
return cancel;
}
public final ArmorType getType() {
return type;
}
public final ItemStack getOldArmorPiece() {
return oldArmorPiece;
}
public final void setOldArmorPiece(final ItemStack oldArmorPiece) {
this.oldArmorPiece = oldArmorPiece;
}
public final ItemStack getNewArmorPiece() {
return newArmorPiece;
}
public final void setNewArmorPiece(final ItemStack newArmorPiece) {
this.newArmorPiece = newArmorPiece;
}
public EquipMethod getMethod() {
return equipType;
}
public enum EquipMethod {// These have got to be the worst documentations ever.
/**
* When you shift click an armor piece to equip or unequip
*/
SHIFT_CLICK,
/**
* When you drag and drop the item to equip or unequip
*/
DRAG,
/**
* When you manually equip or unequip the item. Use to be DRAG
*/
PICK_DROP,
/**
* When you right click an armor piece in the hotbar without the inventory open to equip.
*/
HOTBAR,
/**
* When you press the hotbar slot number while hovering over the armor slot to equip or unequip
*/
HOTBAR_SWAP,
/**
* When in range of a dispenser that shoots an armor piece to equip.<br>
* Requires the spigot version to have {@link org.bukkit.event.block.BlockDispenseArmorEvent} implemented.
*/
DISPENSER,
/**
* When an armor piece is removed due to it losing all durability.
*/
BROKE,
/**
* When you die causing all armor to unequip
*/
DEATH,
;
}
}

View File

@@ -0,0 +1,204 @@
package com.willfp.illusioner.events.armorequip;
import com.willfp.illusioner.events.armorequip.ArmorEquipEvent.EquipMethod;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemBreakEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.inventory.ItemStack;
/**
* @author Arnah
* @since Jul 30, 2015
*/
@SuppressWarnings("deprecation")
public class ArmorListener implements Listener {
//Event Priority is highest because other plugins might cancel the events before we check.
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public final void inventoryClick(final InventoryClickEvent e) {
boolean shift = false, numberkey = false;
if (e.isCancelled()) return;
if (e.getAction() == InventoryAction.NOTHING) return;// Why does this get called if nothing happens??
if (e.getClick().equals(ClickType.SHIFT_LEFT) || e.getClick().equals(ClickType.SHIFT_RIGHT)) {
shift = true;
}
if (e.getClick().equals(ClickType.NUMBER_KEY)) {
numberkey = true;
}
if (e.getSlotType() != SlotType.ARMOR && e.getSlotType() != SlotType.QUICKBAR && e.getSlotType() != SlotType.CONTAINER)
return;
if (e.getClickedInventory() != null && !e.getClickedInventory().getType().equals(InventoryType.PLAYER)) return;
if (!e.getInventory().getType().equals(InventoryType.CRAFTING) && !e.getInventory().getType().equals(InventoryType.PLAYER))
return;
if (!(e.getWhoClicked() instanceof Player)) return;
ArmorType newArmorType = ArmorType.matchType(shift ? e.getCurrentItem() : e.getCursor());
if (!shift && newArmorType != null && e.getRawSlot() != newArmorType.getSlot()) {
// Used for drag and drop checking to make sure you aren't trying to place a helmet in the boots slot.
return;
}
if (shift) {
newArmorType = ArmorType.matchType(e.getCurrentItem());
if (newArmorType != null) {
boolean equipping = true;
if (e.getRawSlot() == newArmorType.getSlot()) {
equipping = false;
}
if (newArmorType.equals(ArmorType.HELMET) && (equipping == isAirOrNull(e.getWhoClicked().getInventory().getHelmet())) || newArmorType.equals(ArmorType.CHESTPLATE) && (equipping == isAirOrNull(e.getWhoClicked().getInventory().getChestplate())) || newArmorType.equals(ArmorType.LEGGINGS) && (equipping == isAirOrNull(e.getWhoClicked().getInventory().getLeggings())) || newArmorType.equals(ArmorType.BOOTS) && (equipping == isAirOrNull(e.getWhoClicked().getInventory().getBoots()))) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(), EquipMethod.SHIFT_CLICK, newArmorType, equipping ? null : e.getCurrentItem(), equipping ? e.getCurrentItem() : null);
Bukkit.getPluginManager().callEvent(armorEquipEvent);
if (armorEquipEvent.isCancelled()) {
e.setCancelled(true);
}
}
}
} else {
ItemStack newArmorPiece = e.getCursor();
ItemStack oldArmorPiece = e.getCurrentItem();
if (numberkey) {
if (e.getClickedInventory().getType().equals(InventoryType.PLAYER)) {// Prevents shit in the 2by2 crafting
// e.getClickedInventory() == The players inventory
// e.getHotBarButton() == key people are pressing to equip or unequip the item to or from.
// e.getRawSlot() == The slot the item is going to.
// e.getSlot() == Armor slot, can't use e.getRawSlot() as that gives a hotbar slot ;-;
ItemStack hotbarItem = e.getClickedInventory().getItem(e.getHotbarButton());
if (!isAirOrNull(hotbarItem)) {// Equipping
newArmorType = ArmorType.matchType(hotbarItem);
newArmorPiece = hotbarItem;
oldArmorPiece = e.getClickedInventory().getItem(e.getSlot());
} else {// Unequipping
newArmorType = ArmorType.matchType(!isAirOrNull(e.getCurrentItem()) ? e.getCurrentItem() : e.getCursor());
}
}
} else {
if (isAirOrNull(e.getCursor()) && !isAirOrNull(e.getCurrentItem())) {// unequip with no new item going into the slot.
newArmorType = ArmorType.matchType(e.getCurrentItem());
}
// e.getCurrentItem() == Unequip
// e.getCursor() == Equip
// newArmorType = ArmorType.matchType(!isAirOrNull(e.getCurrentItem()) ? e.getCurrentItem() : e.getCursor());
}
if (newArmorType != null && e.getRawSlot() == newArmorType.getSlot()) {
EquipMethod method = EquipMethod.PICK_DROP;
if (e.getAction().equals(InventoryAction.HOTBAR_SWAP) || numberkey) method = EquipMethod.HOTBAR_SWAP;
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) e.getWhoClicked(), method, newArmorType, oldArmorPiece, newArmorPiece);
Bukkit.getPluginManager().callEvent(armorEquipEvent);
if (armorEquipEvent.isCancelled()) {
e.setCancelled(true);
}
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void playerInteractEvent(PlayerInteractEvent e) {
if (e.useItemInHand().equals(Result.DENY)) return;
//
if (e.getAction() == Action.PHYSICAL) return;
if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
Player player = e.getPlayer();
if (!e.useInteractedBlock().equals(Result.DENY)) {
if (e.getClickedBlock() != null && e.getAction() == Action.RIGHT_CLICK_BLOCK && !player.isSneaking()) {// Having both of these checks is useless, might as well do it though.
// Some blocks have actions when you right click them which stops the client from equipping the armor in hand.
Material mat = e.getClickedBlock().getType();
}
}
ArmorType newArmorType = ArmorType.matchType(e.getItem());
if (newArmorType != null) {
if (newArmorType.equals(ArmorType.HELMET) && isAirOrNull(e.getPlayer().getInventory().getHelmet()) || newArmorType.equals(ArmorType.CHESTPLATE) && isAirOrNull(e.getPlayer().getInventory().getChestplate()) || newArmorType.equals(ArmorType.LEGGINGS) && isAirOrNull(e.getPlayer().getInventory().getLeggings()) || newArmorType.equals(ArmorType.BOOTS) && isAirOrNull(e.getPlayer().getInventory().getBoots())) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(e.getPlayer(), EquipMethod.HOTBAR, ArmorType.matchType(e.getItem()), null, e.getItem());
Bukkit.getPluginManager().callEvent(armorEquipEvent);
if (armorEquipEvent.isCancelled()) {
e.setCancelled(true);
player.updateInventory();
}
}
}
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void inventoryDrag(InventoryDragEvent event) {
// getType() seems to always be even.
// Old Cursor gives the item you are equipping
// Raw slot is the ArmorType slot
// Can't replace armor using this method making getCursor() useless.
ArmorType type = ArmorType.matchType(event.getOldCursor());
if (event.getRawSlots().isEmpty()) return;// Idk if this will ever happen
if (type != null && type.getSlot() == event.getRawSlots().stream().findFirst().orElse(0)) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent((Player) event.getWhoClicked(), EquipMethod.DRAG, type, null, event.getOldCursor());
Bukkit.getPluginManager().callEvent(armorEquipEvent);
if (armorEquipEvent.isCancelled()) {
event.setResult(Result.DENY);
event.setCancelled(true);
}
}
// Debug shit
}
@EventHandler
public void playerJoinEvent(PlayerJoinEvent e) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(e.getPlayer(), null, null, null, null);
Bukkit.getPluginManager().callEvent(armorEquipEvent);
}
@EventHandler
public void playerRespawnEvent(PlayerRespawnEvent e) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(e.getPlayer(), null, null, null, null);
Bukkit.getPluginManager().callEvent(armorEquipEvent);
}
@EventHandler
public void itemBreakEvent(PlayerItemBreakEvent e) {
ArmorType type = ArmorType.matchType(e.getBrokenItem());
if (type != null) {
Player p = e.getPlayer();
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, EquipMethod.BROKE, type, e.getBrokenItem(), null);
Bukkit.getPluginManager().callEvent(armorEquipEvent);
if (armorEquipEvent.isCancelled()) {
ItemStack i = e.getBrokenItem().clone();
i.setAmount(1);
i.setDurability((short) (i.getDurability() - 1));
if (type.equals(ArmorType.HELMET)) {
p.getInventory().setHelmet(i);
} else if (type.equals(ArmorType.CHESTPLATE)) {
p.getInventory().setChestplate(i);
} else if (type.equals(ArmorType.LEGGINGS)) {
p.getInventory().setLeggings(i);
} else if (type.equals(ArmorType.BOOTS)) {
p.getInventory().setBoots(i);
}
}
}
}
@EventHandler
public void playerDeathEvent(PlayerDeathEvent e) {
Player p = e.getEntity();
if (e.getKeepInventory()) return;
for (ItemStack i : p.getInventory().getArmorContents()) {
if (!isAirOrNull(i)) {
Bukkit.getPluginManager().callEvent(new ArmorEquipEvent(p, EquipMethod.DEATH, ArmorType.matchType(i), i, null));
// No way to cancel a death event.
}
}
}
public static boolean isAirOrNull(ItemStack item) {
return item == null || item.getType().equals(Material.AIR);
}
}

View File

@@ -0,0 +1,38 @@
package com.willfp.illusioner.events.armorequip;
import org.bukkit.inventory.ItemStack;
/**
* @author Arnah
* @since Jul 30, 2015
*/
public enum ArmorType {
HELMET(5), CHESTPLATE(6), LEGGINGS(7), BOOTS(8);
private final int slot;
ArmorType(int slot) {
this.slot = slot;
}
/**
* Attempts to match the ArmorType for the specified ItemStack.
*
* @param itemStack The ItemStack to parse the type of.
*
* @return The parsed ArmorType, or null if not found.
*/
public static ArmorType matchType(final ItemStack itemStack) {
if (ArmorListener.isAirOrNull(itemStack)) return null;
String type = itemStack.getType().name();
if (type.endsWith("_HELMET") || type.endsWith("_SKULL") || type.endsWith("PLAYER_HEAD")) return HELMET;
else if (type.endsWith("_CHESTPLATE") || type.endsWith("ELYTRA")) return CHESTPLATE;
else if (type.endsWith("_LEGGINGS")) return LEGGINGS;
else if (type.endsWith("_BOOTS")) return BOOTS;
else return null;
}
public int getSlot() {
return slot;
}
}

View File

@@ -0,0 +1,28 @@
package com.willfp.illusioner.events.armorequip;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockDispenseArmorEvent;
/**
* @author Arnah
* @since Feb 08, 2019
*/
public class DispenserArmorListener implements Listener {
@EventHandler
public void dispenseArmorEvent(BlockDispenseArmorEvent event) {
ArmorType type = ArmorType.matchType(event.getItem());
if (type != null) {
if (event.getTargetEntity() instanceof Player) {
Player p = (Player) event.getTargetEntity();
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(p, ArmorEquipEvent.EquipMethod.DISPENSER, type, null, event.getItem());
Bukkit.getPluginManager().callEvent(armorEquipEvent);
if (armorEquipEvent.isCancelled()) {
event.setCancelled(true);
}
}
}
}
}

View File

@@ -0,0 +1,58 @@
package com.willfp.illusioner.events.entitydeathbyentity;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.ItemStack;
import java.util.List;
class EntityDeathByEntityBuilder {
private LivingEntity victim = null;
private Entity damager;
private EntityDeathEvent deathEvent;
private List<ItemStack> drops;
private int xp = 0;
private boolean dropItems;
public EntityDeathByEntityBuilder() {
}
public LivingEntity getVictim() {
return this.victim;
}
public void setDeathEvent(EntityDeathEvent deathEvent) {
this.deathEvent = deathEvent;
}
public void setVictim(LivingEntity victim) {
this.victim = victim;
}
public void setDamager(Entity damager) {
this.damager = damager;
}
public void setDrops(List<ItemStack> drops) {
this.drops = drops;
}
public void setXp(int xp) {
this.xp = xp;
}
public void push() {
if(this.victim == null) return;
if(this.damager == null) return;
if(this.drops == null) return;
if(this.deathEvent == null) return;
EntityDeathByEntityEvent event = new EntityDeathByEntityEvent(victim, damager, drops, xp, deathEvent);
Bukkit.getPluginManager().callEvent(event);
}
}

View File

@@ -0,0 +1,115 @@
package com.willfp.illusioner.events.entitydeathbyentity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Event triggered when entity is killed by entity.
*/
public class EntityDeathByEntityEvent extends Event {
private static final HandlerList HANDLERS = new HandlerList();
/**
* The {@link LivingEntity} killed
*/
private final LivingEntity victim;
/**
* The {@link Entity} that killed;
*/
private final Entity damager;
/**
* The associated {@link EntityDeathEvent}
*/
private final EntityDeathEvent deathEvent;
/**
* The entity drops
*/
private final List<ItemStack> drops;
/**
* The xp to drop
*/
private final int xp;
/**
* Create event based off parameters
*
* @param victim The killed entity
* @param damager The killer
* @param drops The item drops
* @param xp The amount of xp to drop
* @param deathEvent The associated {@link EntityDeathEvent}
*/
public EntityDeathByEntityEvent(@NotNull LivingEntity victim, @NotNull Entity damager, @NotNull List<ItemStack> drops, int xp, @NotNull EntityDeathEvent deathEvent) {
this.victim = victim;
this.damager = damager;
this.drops = drops;
this.xp = xp;
this.deathEvent = deathEvent;
}
/**
* Get victim
*
* @return The victim
*/
public LivingEntity getVictim() {
return this.victim;
}
/**
* Get killer
*
* @return The killer
*/
public Entity getKiller() {
return this.damager;
}
/**
* Get xp amount
*
* @return The xp
*/
public int getDroppedExp() {
return this.xp;
}
/**
* Get drops
*
* @return {@link List} of drops
*/
public List<ItemStack> getDrops() {
return this.drops;
}
/**
* Get associated {@link EntityDeathEvent}
* Use this to modify event parameters.
*
* @return The associated {@link EntityDeathEvent}
*/
public EntityDeathEvent getDeathEvent() {
return this.deathEvent;
}
@Override
public @NotNull HandlerList getHandlers() {
return HANDLERS;
}
public static HandlerList getHandlerList() {
return HANDLERS;
}
}

View File

@@ -0,0 +1,69 @@
package com.willfp.illusioner.events.entitydeathbyentity;
import com.willfp.illusioner.IllusionerPlugin;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
public class EntityDeathByEntityListeners implements Listener {
final Set<EntityDeathByEntityBuilder> events = new HashSet<>();
@EventHandler(priority = EventPriority.HIGH)
public void onEntityDamage(EntityDamageByEntityEvent event) {
if(!(event.getEntity() instanceof LivingEntity)) return;
LivingEntity victim = (LivingEntity) event.getEntity();
if(victim.getHealth() > event.getFinalDamage()) return;
EntityDeathByEntityBuilder builtEvent = new EntityDeathByEntityBuilder();
builtEvent.setVictim(victim);
builtEvent.setDamager(event.getDamager());
events.add(builtEvent);
new BukkitRunnable() {
@Override
public void run() {
events.remove(builtEvent);
}
}.runTaskLater(IllusionerPlugin.getInstance(), 1);
}
@EventHandler
public void onEntityDeath(EntityDeathEvent event) {
LivingEntity victim = event.getEntity();
List<ItemStack> drops = event.getDrops();
int xp = event.getDroppedExp();
AtomicReference<EntityDeathByEntityBuilder> atomicBuiltEvent = new AtomicReference<>(null);
EntityDeathByEntityBuilder builtEvent;
events.forEach((deathByEntityEvent) -> {
if(deathByEntityEvent.getVictim().equals(victim)) {
atomicBuiltEvent.set(deathByEntityEvent);
}
});
if(atomicBuiltEvent.get() == null) return;
builtEvent = atomicBuiltEvent.get();
events.remove(builtEvent);
builtEvent.setDrops(drops);
builtEvent.setXp(xp);
builtEvent.setDeathEvent(event);
builtEvent.push();
}
}

View File

@@ -0,0 +1,46 @@
package com.willfp.illusioner.events.naturalexpgainevent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.player.PlayerExpChangeEvent;
class NaturalExpGainBuilder {
private final LivingEntity victim = null;
private boolean cancelled = false;
private PlayerExpChangeEvent event;
private Location loc;
public NaturalExpGainBuilder() {
}
public LivingEntity getVictim() {
return this.victim;
}
public void setEvent(PlayerExpChangeEvent event) {
this.event = event;
}
public void setCancelled(boolean cancel) {
this.cancelled = cancel;
}
public void setLoc(Location location) {
this.loc = location;
}
public Location getLoc() {
return this.loc;
}
public void push() {
if(this.event == null) return;
if(this.cancelled) return;
NaturalExpGainEvent naturalExpGainEvent = new NaturalExpGainEvent(event);
Bukkit.getPluginManager().callEvent(naturalExpGainEvent);
}
}

View File

@@ -0,0 +1,46 @@
package com.willfp.illusioner.events.naturalexpgainevent;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerExpChangeEvent;
import org.jetbrains.annotations.NotNull;
/**
* Event triggered when player receives experience not from bottle
*/
public class NaturalExpGainEvent extends Event {
private static final HandlerList HANDLERS = new HandlerList();
/**
* The associated {@link PlayerExpChangeEvent}
*/
private final PlayerExpChangeEvent event;
/**
* Create event based off parameters
*
* @param event The associate PlayerExpChangeEvent
*/
public NaturalExpGainEvent(@NotNull PlayerExpChangeEvent event) {
this.event = event;
}
/**
* Get associated {@link PlayerExpChangeEvent}
* Use this to modify event parameters.
*
* @return The associated {@link PlayerExpChangeEvent}
*/
public PlayerExpChangeEvent getExpChangeEvent() {
return this.event;
}
@Override
public @NotNull HandlerList getHandlers() {
return HANDLERS;
}
public static HandlerList getHandlerList() {
return HANDLERS;
}
}

View File

@@ -0,0 +1,56 @@
package com.willfp.illusioner.events.naturalexpgainevent;
import com.willfp.illusioner.IllusionerPlugin;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ExpBottleEvent;
import org.bukkit.event.player.PlayerExpChangeEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
public class NaturalExpGainListeners implements Listener {
final Set<NaturalExpGainBuilder> events = new HashSet<>();
@EventHandler
public void onExpChange(PlayerExpChangeEvent event) {
NaturalExpGainBuilder builtEvent = new NaturalExpGainBuilder();
builtEvent.setEvent(event);
AtomicBoolean isNatural = new AtomicBoolean(true);
AtomicReference<NaturalExpGainBuilder> atomicBuiltEvent = new AtomicReference<>();
Set<NaturalExpGainBuilder> eventsClone = new HashSet<>(events);
eventsClone.forEach((builder) -> {
if(builder.getLoc().getWorld().getNearbyEntities(builder.getLoc(), 7.25, 7.25, 7.25).contains(event.getPlayer())) {
events.remove(builder);
isNatural.set(false);
atomicBuiltEvent.set(builder);
}
});
if(isNatural.get()) {
events.remove(atomicBuiltEvent.get());
builtEvent.push();
}
new BukkitRunnable() {
@Override
public void run() {
events.remove(builtEvent);
}
}.runTaskLater(IllusionerPlugin.getInstance(), 1);
}
@EventHandler
public void onExpBottle(ExpBottleEvent event) {
NaturalExpGainBuilder builtEvent = new NaturalExpGainBuilder();
builtEvent.setLoc(event.getEntity().getLocation());
events.add(builtEvent);
}
}

View File

@@ -0,0 +1,105 @@
package com.willfp.illusioner.illusioner;
import com.willfp.illusioner.util.NumberUtils;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AttackListeners implements Listener {
@EventHandler
public void onIllusionerAttack(EntityDamageByEntityEvent event) {
if(!event.getDamager().getType().equals(EntityType.ILLUSIONER))
return;
if(!(event.getEntity() instanceof Player))
return;
Player player = (Player) event.getEntity();
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, 40, 1));
player.playSound(player.getLocation(), Sound.ENTITY_ILLUSIONER_CAST_SPELL, 1, 1f);
if(!player.hasPotionEffect(PotionEffectType.CONFUSION)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.CONFUSION, 200, 10));
player.playSound(player.getLocation(), Sound.ENTITY_ILLUSIONER_CAST_SPELL, 1, 2f);
}
if(NumberUtils.randInt(1, 10) <= 2) {
player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 40, 2));
player.playSound(player.getLocation(), Sound.ENTITY_ILLUSIONER_CAST_SPELL, 1, 2f);
}
if(NumberUtils.randInt(1, 10) <= 2) {
player.addPotionEffect(new PotionEffect(PotionEffectType.SLOW_DIGGING, 40, 2));
player.playSound(player.getLocation(), Sound.ENTITY_ILLUSIONER_CAST_SPELL, 1, 2f);
}
if(NumberUtils.randInt(1, 20) == 1) {
List<ItemStack> hotbar = new ArrayList<>();
for(int i = 0; i<9; i++) {
hotbar.add(player.getInventory().getItem(i));
}
Collections.shuffle(hotbar);
int i2 = 0;
for(ItemStack item : hotbar) {
player.getInventory().setItem(i2, item);
i2++;
}
player.playSound(player.getLocation(), Sound.ENTITY_ENDER_PEARL_THROW, 1, 0.5f);
}
}
@EventHandler
public void onIllusionerDamageByPlayer(EntityDamageByEntityEvent event) {
if(!event.getEntity().getType().equals(EntityType.ILLUSIONER))
return;
if(!(event.getDamager() instanceof Player))
return;
Player player = (Player) event.getDamager();
if(NumberUtils.randInt(1, 10) == 1) {
Location loc = player.getLocation().add(NumberUtils.randInt(2,6), 0, NumberUtils.randInt(2,6));
while(!loc.getBlock().getType().equals(Material.AIR)) {
loc.add(0, 1, 0);
}
player.getWorld().spawnEntity(loc, EntityType.EVOKER);
player.playSound(player.getLocation(), Sound.ENTITY_EVOKER_PREPARE_ATTACK, 1, 2f);
}
if(NumberUtils.randInt(1, 10) == 1) {
Location loc = player.getLocation().add(NumberUtils.randInt(2,6), 0, NumberUtils.randInt(2,6));
while(!loc.getBlock().getType().equals(Material.AIR)) {
loc.add(0, 1, 0);
}
player.getWorld().spawnEntity(loc, EntityType.VINDICATOR);
player.playSound(player.getLocation(), Sound.ENTITY_EVOKER_PREPARE_ATTACK, 1, 2f);
}
ExperienceOrb experienceOrb = (ExperienceOrb) event.getEntity().getWorld().spawnEntity(event.getEntity().getLocation(), EntityType.EXPERIENCE_ORB);
experienceOrb.setExperience(NumberUtils.randInt(5,20));
}
@EventHandler
public void onIllusionerDamage(EntityDamageEvent event) {
if(!event.getEntity().getType().equals(EntityType.ILLUSIONER))
return;
if(event.getCause().equals(EntityDamageEvent.DamageCause.ENTITY_EXPLOSION)
|| event.getCause().equals(EntityDamageEvent.DamageCause.BLOCK_EXPLOSION)) {
event.setCancelled(true);
}
}
}

View File

@@ -0,0 +1,24 @@
package com.willfp.illusioner.illusioner;
import com.willfp.illusioner.util.NumberUtils;
import org.bukkit.Sound;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
public class DeathListeners implements Listener {
@EventHandler
public void onIllusionerDeath(EntityDeathEvent event) {
if(!event.getEntityType().equals(EntityType.ILLUSIONER))
return;
event.getEntity().getWorld().playSound(event.getEntity().getLocation(), Sound.ENTITY_EVOKER_PREPARE_WOLOLO, 50, 0.8f);
event.getEntity().getWorld().playSound(event.getEntity().getLocation(), Sound.ENTITY_ILLUSIONER_PREPARE_BLINDNESS, 50, 1f);
event.getEntity().getWorld().playSound(event.getEntity().getLocation(), Sound.ENTITY_WITHER_DEATH, 50, 2f);
ExperienceOrb eo1 = (ExperienceOrb) event.getEntity().getWorld().spawnEntity(event.getEntity().getLocation(), EntityType.EXPERIENCE_ORB);
eo1.setExperience(NumberUtils.randInt(20000,25000));
}
}

View File

@@ -0,0 +1,36 @@
package com.willfp.illusioner.illusioner;
import com.willfp.illusioner.IllusionerPlugin;
import com.willfp.illusioner.nms.NMSIllusioner;
import com.willfp.illusioner.nms.api.EntityIllusionerWrapper;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.boss.BarColor;
import org.bukkit.boss.BarStyle;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
public class SpawnListeners implements Listener {
@EventHandler
public void onSpawn(BlockPlaceEvent event) {
if(!event.getBlock().getType().equals(Material.DRAGON_HEAD))
return;
if(!event.getBlock().getLocation().add(0,-1,0).getBlock().getType().equals(Material.BEACON))
return;
if(!event.getBlock().getLocation().add(0,-2,0).getBlock().getType().equals(Material.DIAMOND_BLOCK))
return;
try {
event.getBlock().getLocation().getBlock().setType(Material.AIR);
event.getBlock().getLocation().add(0, -1, 0).getBlock().setType(Material.AIR);
event.getBlock().getLocation().add(0, -2, 0).getBlock().setType(Material.AIR);
event.getBlock().getWorld().playSound(event.getBlock().getLocation(), Sound.ENTITY_ILLUSIONER_MIRROR_MOVE, 1000, 0.5f);
event.getBlock().getWorld().playSound(event.getBlock().getLocation(), Sound.ENTITY_WITHER_SPAWN, 1000, 2f);
EntityIllusionerWrapper illusioner = NMSIllusioner.spawn(event.getBlock().getLocation(), 600, 50);
illusioner.createBossbar(IllusionerPlugin.getInstance(), BarColor.BLUE, BarStyle.SOLID);
} catch(Exception ignored) {}
}
}

View File

@@ -0,0 +1,12 @@
package com.willfp.illusioner.integrations;
/**
* Interface for all integrations with optional dependencies
*/
public interface Integration {
/**
* Get the name of integration
* @return The name
*/
String getPluginName();
}

View File

@@ -0,0 +1,49 @@
package com.willfp.illusioner.integrations.anticheat;
import com.willfp.illusioner.IllusionerPlugin;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import java.util.HashSet;
import java.util.Set;
/**
* Utility class for Anticheat Integrations
*/
public class AnticheatManager {
private static final Set<AnticheatWrapper> anticheats = new HashSet<>();
/**
* Register a new anticheat
*
* @param anticheat The anticheat to register
*/
public static void register(AnticheatWrapper anticheat) {
if (anticheat instanceof Listener) {
Bukkit.getPluginManager().registerEvents((Listener) anticheat, IllusionerPlugin.getInstance());
}
anticheats.add(anticheat);
}
/**
* Exempt a player from triggering anticheats
*
* @param player The player to exempt
*/
public static void exemptPlayer(Player player) {
anticheats.forEach(anticheat -> anticheat.exempt(player));
}
/**
* Unexempt a player from triggering anticheats
* This is ran a tick after it is called to ensure that there are no event timing conflicts
*
* @param player The player to remove the exemption
*/
public static void unexemptPlayer(Player player) {
Bukkit.getScheduler().runTaskLater(IllusionerPlugin.getInstance(), () -> {
anticheats.forEach(anticheat -> anticheat.unexempt(player));
}, 1);
}
}

View File

@@ -0,0 +1,23 @@
package com.willfp.illusioner.integrations.anticheat;
import com.willfp.illusioner.integrations.Integration;
import org.bukkit.entity.Player;
/**
* Interface for anticheat integrations
*/
public interface AnticheatWrapper extends Integration {
/**
* Exempt a player from checks
*
* @param player The player to exempt
*/
void exempt(Player player);
/**
* Unexempt a player from checks
*
* @param player The player to unexempt
*/
void unexempt(Player player);
}

View File

@@ -0,0 +1,40 @@
package com.willfp.illusioner.integrations.anticheat.plugins;
import com.willfp.illusioner.integrations.anticheat.AnticheatWrapper;
import me.konsolas.aac.api.PlayerViolationEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
public class AnticheatAAC implements AnticheatWrapper, Listener {
private final Set<UUID> exempt = new HashSet<>();
@Override
public String getPluginName() {
return "AAC";
}
@Override
public void exempt(Player player) {
this.exempt.add(player.getUniqueId());
}
@Override
public void unexempt(Player player) {
this.exempt.remove(player.getUniqueId());
}
@EventHandler(priority = EventPriority.LOWEST)
private void onViolate(PlayerViolationEvent event) {
if (!exempt.contains(event.getPlayer().getUniqueId())) {
return;
}
event.setCancelled(true);
}
}

View File

@@ -0,0 +1,40 @@
package com.willfp.illusioner.integrations.anticheat.plugins;
import com.willfp.illusioner.integrations.anticheat.AnticheatWrapper;
import me.rerere.matrix.api.events.PlayerViolationEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
public class AnticheatMatrix implements AnticheatWrapper, Listener {
private final Set<UUID> exempt = new HashSet<>();
@Override
public String getPluginName() {
return "Matrix";
}
@Override
public void exempt(Player player) {
this.exempt.add(player.getUniqueId());
}
@Override
public void unexempt(Player player) {
this.exempt.remove(player.getUniqueId());
}
@EventHandler(priority = EventPriority.LOWEST)
private void onViolate(PlayerViolationEvent event) {
if (!exempt.contains(event.getPlayer().getUniqueId())) {
return;
}
event.setCancelled(true);
}
}

View File

@@ -0,0 +1,37 @@
package com.willfp.illusioner.integrations.anticheat.plugins;
import com.willfp.illusioner.integrations.anticheat.AnticheatWrapper;
import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import org.bukkit.entity.Player;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
public class AnticheatNCP implements AnticheatWrapper {
private final Set<UUID> exempt = new HashSet<>();
@Override
public String getPluginName() {
return "NCP";
}
@Override
public void exempt(Player player) {
if (!NCPExemptionManager.isExempted(player, CheckType.ALL)) {
return;
}
if (exempt.add(player.getUniqueId())) {
NCPExemptionManager.exemptPermanently(player, CheckType.ALL);
}
}
@Override
public void unexempt(Player player) {
if (exempt.remove(player.getUniqueId())) {
NCPExemptionManager.unexempt(player, CheckType.ALL);
}
}
}

View File

@@ -0,0 +1,40 @@
package com.willfp.illusioner.integrations.anticheat.plugins;
import com.willfp.illusioner.integrations.anticheat.AnticheatWrapper;
import me.vagdedes.spartan.api.PlayerViolationEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
public class AnticheatSpartan implements AnticheatWrapper, Listener {
private final Set<UUID> exempt = new HashSet<>();
@Override
public String getPluginName() {
return "Spartan";
}
@Override
public void exempt(Player player) {
this.exempt.add(player.getUniqueId());
}
@Override
public void unexempt(Player player) {
this.exempt.remove(player.getUniqueId());
}
@EventHandler(priority = EventPriority.LOWEST)
private void onViolate(PlayerViolationEvent event) {
if (!exempt.contains(event.getPlayer().getUniqueId())) {
return;
}
event.setCancelled(true);
}
}

View File

@@ -0,0 +1,66 @@
package com.willfp.illusioner.integrations.antigrief;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import java.util.HashSet;
import java.util.Set;
public class AntigriefManager {
private static final Set<AntigriefWrapper> antigriefs = new HashSet<>();
/**
* Register a new AntiGrief/Land Management integration
*
* @param antigrief The integration to register
*/
public static void register(AntigriefWrapper antigrief) {
antigriefs.add(antigrief);
}
/**
* Can player break block
*
* @param player The player
* @param block The block
* @return If player can break block
*/
public static boolean canBreakBlock(Player player, Block block) {
return antigriefs.stream().allMatch(antigriefWrapper -> antigriefWrapper.canBreakBlock(player, block));
}
/**
* Can player create explosion at location
*
* @param player The player
* @param location The location
* @return If player can create explosion
*/
public static boolean canCreateExplosion(Player player, Location location) {
return antigriefs.stream().allMatch(antigriefWrapper -> antigriefWrapper.canCreateExplosion(player, location));
}
/**
* Can player place block
*
* @param player The player
* @param block The block
* @return If player can place block
*/
public static boolean canPlaceBlock(Player player, Block block) {
return antigriefs.stream().allMatch(antigriefWrapper -> antigriefWrapper.canPlaceBlock(player, block));
}
/**
* Can player injure living entity
*
* @param player The player
* @param victim The victim
* @return If player can injure
*/
public static boolean canInjure(Player player, LivingEntity victim) {
return antigriefs.stream().allMatch(antigriefWrapper -> antigriefWrapper.canInjure(player, victim));
}
}

View File

@@ -0,0 +1,48 @@
package com.willfp.illusioner.integrations.antigrief;
import com.willfp.illusioner.integrations.Integration;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
/**
* Interface for Antigrief integrations
*/
public interface AntigriefWrapper extends Integration {
/**
* Can player break block
*
* @param player The player
* @param block The block
* @return If player cna break block
*/
boolean canBreakBlock(Player player, Block block);
/**
* Can player create explosion at location
*
* @param player The player
* @param location The location
* @return If player can create explosion
*/
boolean canCreateExplosion(Player player, Location location);
/**
* Can player place block
*
* @param player The player
* @param block The block
* @return If player can place block
*/
boolean canPlaceBlock(Player player, Block block);
/**
* Can player injure living entity
*
* @param player The player
* @param victim The victim
* @return If player can injure
*/
boolean canInjure(Player player, LivingEntity victim);
}

View File

@@ -0,0 +1,71 @@
package com.willfp.illusioner.integrations.antigrief.plugins;
import com.massivecraft.factions.Board;
import com.massivecraft.factions.FLocation;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.Faction;
import com.massivecraft.factions.perms.PermissibleAction;
import com.willfp.illusioner.integrations.antigrief.AntigriefWrapper;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
public class AntigriefFactionsUUID implements AntigriefWrapper {
@Override
public boolean canBreakBlock(Player player, Block block) {
FPlayer fplayer = FPlayers.getInstance().getByPlayer(player);
FLocation flocation = new FLocation(block.getLocation());
Faction faction = Board.getInstance().getFactionAt(flocation);
if (!faction.hasAccess(fplayer, PermissibleAction.DESTROY)) {
return fplayer.isAdminBypassing();
}
return true;
}
@Override
public boolean canCreateExplosion(Player player, Location location) {
FPlayer fplayer = FPlayers.getInstance().getByPlayer(player);
FLocation flocation = new FLocation(location);
Faction faction = Board.getInstance().getFactionAt(flocation);
return !faction.noExplosionsInTerritory();
}
@Override
public boolean canPlaceBlock(Player player, Block block) {
FPlayer fplayer = FPlayers.getInstance().getByPlayer(player);
FLocation flocation = new FLocation(block.getLocation());
Faction faction = Board.getInstance().getFactionAt(flocation);
if (!faction.hasAccess(fplayer, PermissibleAction.BUILD)) {
return fplayer.isAdminBypassing();
}
return true;
}
@Override
public boolean canInjure(Player player, LivingEntity victim) {
FPlayer fplayer = FPlayers.getInstance().getByPlayer(player);
FLocation flocation = new FLocation(victim.getLocation());
Faction faction = Board.getInstance().getFactionAt(flocation);
if(victim instanceof Player) {
if (faction.isPeaceful()) {
return fplayer.isAdminBypassing();
}
} else {
if (faction.hasAccess(fplayer, PermissibleAction.DESTROY)) {
return fplayer.isAdminBypassing();
}
}
return true;
}
@Override
public String getPluginName() {
return "FactionsUUID";
}
}

View File

@@ -0,0 +1,56 @@
package com.willfp.illusioner.integrations.antigrief.plugins;
import com.willfp.illusioner.integrations.antigrief.AntigriefWrapper;
import me.ryanhamshire.GriefPrevention.Claim;
import me.ryanhamshire.GriefPrevention.GriefPrevention;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
public class AntigriefGriefPrevention implements AntigriefWrapper {
@Override
public boolean canBreakBlock(Player player, Block block) {
Claim claim = GriefPrevention.instance.dataStore.getClaimAt(block.getLocation(), false, null);
if (claim != null) {
return claim.allowBreak(player, block.getType()) == null;
}
return true;
}
@Override
public boolean canCreateExplosion(Player player, Location location) {
Claim claim = GriefPrevention.instance.dataStore.getClaimAt(location, false, null);
if (claim != null) {
return claim.areExplosivesAllowed;
}
return true;
}
@Override
public boolean canPlaceBlock(Player player, Block block) {
Claim claim = GriefPrevention.instance.dataStore.getClaimAt(block.getLocation(), false, null);
if (claim != null) {
return claim.allowBuild(player, block.getType()) == null;
}
return true;
}
@Override
public boolean canInjure(Player player, LivingEntity victim) {
Claim claim = GriefPrevention.instance.dataStore.getClaimAt(victim.getLocation(), false, null);
if(victim instanceof Player) {
return claim == null;
} else {
if (claim != null && claim.ownerID != null) {
return claim.ownerID.equals(player.getUniqueId());
}
return true;
}
}
@Override
public String getPluginName() {
return "GriefPrevention";
}
}

View File

@@ -0,0 +1,60 @@
package com.willfp.illusioner.integrations.antigrief.plugins;
import com.willfp.illusioner.integrations.antigrief.AntigriefWrapper;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.kingdoms.constants.kingdom.Kingdom;
import org.kingdoms.constants.land.Land;
import org.kingdoms.managers.PvPManager;
import org.kingdoms.managers.land.LandManager;
public class AntigriefKingdoms implements AntigriefWrapper {
@Override
public boolean canBreakBlock(Player player, Block block) {
BlockBreakEvent event = new BlockBreakEvent(block, player);
LandManager.onBreak(event);
return !event.isCancelled();
}
@Override
public boolean canCreateExplosion(Player player, Location location) {
Land land = Land.getLand(location);
if (land == null) return true;
if(!land.isClaimed()) return true;
Kingdom kingdom = land.getKingdom();
return kingdom.isMember(player);
}
@Override
public boolean canPlaceBlock(Player player, Block block) {
Block placedOn = block.getRelative(0, -1, 0);
BlockPlaceEvent event = new BlockPlaceEvent(block, block.getState(), placedOn, player.getInventory().getItemInMainHand(), player, true, EquipmentSlot.HAND);
LandManager.onPlace(event);
return !event.isCancelled();
}
@Override
public boolean canInjure(Player player, LivingEntity victim) {
if(victim instanceof Player) {
return PvPManager.canFight(player, (Player) victim);
} else {
Land land = Land.getLand(victim.getLocation());
if (land == null) return true;
if(!land.isClaimed()) return true;
Kingdom kingdom = land.getKingdom();
return kingdom.isMember(player);
}
}
@Override
public String getPluginName() {
return "Kingdoms";
}
}

View File

@@ -0,0 +1,64 @@
package com.willfp.illusioner.integrations.antigrief.plugins;
import com.willfp.illusioner.IllusionerPlugin;
import com.willfp.illusioner.integrations.antigrief.AntigriefWrapper;
import me.angeschossen.lands.api.integration.LandsIntegration;
import me.angeschossen.lands.api.land.Area;
import me.angeschossen.lands.api.role.enums.RoleSetting;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
public class AntigriefLands implements AntigriefWrapper {
@Override
public boolean canBreakBlock(Player player, Block block) {
LandsIntegration landsIntegration = new LandsIntegration(IllusionerPlugin.getInstance());
Area area = landsIntegration.getAreaByLoc(block.getLocation());
if (area != null) {
return area.canSetting(player, RoleSetting.BLOCK_BREAK, false);
}
return true;
}
@Override
public boolean canCreateExplosion(Player player, Location location) {
LandsIntegration landsIntegration = new LandsIntegration(IllusionerPlugin.getInstance());
Area area = landsIntegration.getAreaByLoc(location);
if (area != null) {
return area.canSetting(player, RoleSetting.BLOCK_IGNITE, false);
}
return true;
}
@Override
public boolean canPlaceBlock(Player player, Block block) {
LandsIntegration landsIntegration = new LandsIntegration(IllusionerPlugin.getInstance());
Area area = landsIntegration.getAreaByLoc(block.getLocation());
if (area != null) {
return area.canSetting(player, RoleSetting.BLOCK_PLACE, false);
}
return true;
}
@Override
public boolean canInjure(Player player, LivingEntity victim) {
LandsIntegration landsIntegration = new LandsIntegration(IllusionerPlugin.getInstance());
Area area = landsIntegration.getAreaByLoc(victim.getLocation());
if(victim instanceof Player) {
if (area != null) {
return area.canSetting(player, RoleSetting.ATTACK_PLAYER, false);
}
} else {
if (area != null) {
return area.canSetting(player, RoleSetting.ATTACK_ANIMAL, false);
}
}
return true;
}
@Override
public String getPluginName() {
return "Lands";
}
}

View File

@@ -0,0 +1,50 @@
package com.willfp.illusioner.integrations.antigrief.plugins;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownyPermission;
import com.palmergames.bukkit.towny.object.WorldCoord;
import com.palmergames.bukkit.towny.utils.PlayerCacheUtil;
import com.willfp.illusioner.integrations.antigrief.AntigriefWrapper;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
public class AntigriefTowny implements AntigriefWrapper {
@Override
public boolean canBreakBlock(Player player, Block block) {
return PlayerCacheUtil.getCachePermission(player, block.getLocation(), block.getType(), TownyPermission.ActionType.DESTROY);
}
@Override
public boolean canCreateExplosion(Player player, Location location) {
return PlayerCacheUtil.getCachePermission(player, location, Material.TNT, TownyPermission.ActionType.ITEM_USE);
}
@Override
public boolean canPlaceBlock(Player player, Block block) {
return PlayerCacheUtil.getCachePermission(player, block.getLocation(), block.getType(), TownyPermission.ActionType.BUILD);
}
@Override
public boolean canInjure(Player player, LivingEntity victim) {
if(victim instanceof Player) {
try {
Town town = WorldCoord.parseWorldCoord(victim.getLocation()).getTownBlock().getTown();
return town.isPVP();
} catch (Exception ignored) {}
} else {
try {
Town town = WorldCoord.parseWorldCoord(victim.getLocation()).getTownBlock().getTown();
return town.hasMobs();
} catch (Exception ignored) {}
}
return true;
}
@Override
public String getPluginName() {
return "Towny";
}
}

View File

@@ -0,0 +1,79 @@
package com.willfp.illusioner.integrations.antigrief.plugins;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.WorldGuard;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.flags.Flags;
import com.sk89q.worldguard.protection.regions.RegionContainer;
import com.sk89q.worldguard.protection.regions.RegionQuery;
import com.willfp.illusioner.integrations.antigrief.AntigriefWrapper;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
public class AntigriefWorldGuard implements AntigriefWrapper {
@Override
public boolean canBreakBlock(Player player, Block block) {
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery();
if (!query.testState(BukkitAdapter.adapt(block.getLocation()), localPlayer, Flags.BUILD)) {
return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(block.getWorld()));
}
return true;
}
@Override
public boolean canCreateExplosion(Player player, Location location) {
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery();
World world = location.getWorld();
Validate.notNull(world, "World cannot be null!");
if (!query.testState(BukkitAdapter.adapt(location), localPlayer, Flags.OTHER_EXPLOSION)) {
return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(world));
}
return true;
}
@Override
public boolean canPlaceBlock(Player player, Block block) {
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery();
if (!query.testState(BukkitAdapter.adapt(block.getLocation()), localPlayer, Flags.BLOCK_PLACE)) {
return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(block.getWorld()));
}
return true;
}
@Override
public boolean canInjure(Player player, LivingEntity victim) {
LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery();
if(victim instanceof Player) {
if (!query.testState(BukkitAdapter.adapt(victim.getLocation()), localPlayer, Flags.PVP)) {
return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(player.getWorld()));
}
} else {
if (!query.testState(BukkitAdapter.adapt(victim.getLocation()), localPlayer, Flags.DAMAGE_ANIMALS)) {
return WorldGuard.getInstance().getPlatform().getSessionManager().hasBypass(localPlayer, BukkitAdapter.adapt(player.getWorld()));
}
}
return true;
}
@Override
public String getPluginName() {
return "WorldGuard";
}
}

View File

@@ -0,0 +1,17 @@
package com.willfp.illusioner.integrations.anvilgui;
import com.willfp.illusioner.integrations.Integration;
/**
* Interface for AnvilGUI integrations
*/
public interface AnvilGUIIntegration extends Integration {
/**
* Get if the NMS inventory is an instance of an AnvilGUI
*
* @param object The NMS inventory to check
* @return If the object is an AnvilGUI
* @see com.willfp.illusioner.nms.OpenInventory
*/
boolean isInstance(Object object);
}

View File

@@ -0,0 +1,35 @@
package com.willfp.illusioner.integrations.anvilgui;
import com.willfp.illusioner.nms.OpenInventory;
import org.bukkit.entity.Player;
import java.util.HashSet;
import java.util.Set;
/**
* Utility class for interfacing with plugins that use WesJD's AnvilGUI library
*/
public class AnvilGUIManager {
private static final Set<AnvilGUIIntegration> integrations = new HashSet<>();
/**
* Register a new AnvilGUI integration
*
* @param integration The integration to register
*/
public static void registerIntegration(AnvilGUIIntegration integration) {
integrations.add(integration);
}
/**
* Get if a player's open inventory is an AnvilGUI
*
* @param player The player to check
* @return If the player's open inventory is an AnvilGUI
*/
public static boolean hasAnvilGUIOpen(Player player) {
if (integrations.isEmpty())
return false;
return integrations.stream().anyMatch(integration -> integration.isInstance(OpenInventory.getOpenInventory(player)));
}
}

View File

@@ -0,0 +1,21 @@
package com.willfp.illusioner.integrations.anvilgui.plugins;
import com.willfp.illusioner.IllusionerPlugin;
import com.willfp.illusioner.integrations.anvilgui.AnvilGUIIntegration;
/**
* Concrete implementation of {@link AnvilGUIIntegration}
*/
public class AnvilGUIImpl implements AnvilGUIIntegration {
private static final String ANVIL_GUI_CLASS = "net.wesjd.anvilgui.version.Wrapper" + IllusionerPlugin.NMS_VERSION.substring(1) + "$AnvilContainer";
@Override
public boolean isInstance(Object object) {
return object.getClass().toString().equals(ANVIL_GUI_CLASS);
}
@Override
public String getPluginName() {
return "AnvilGUI";
}
}

View File

@@ -0,0 +1,14 @@
package com.willfp.illusioner.integrations.mcmmo;
import com.willfp.illusioner.integrations.Integration;
import org.bukkit.event.Event;
/**
* Interface for mcMMO integrations
*/
public interface McmmoIntegration extends Integration {
/**
* @see McmmoManager#isFake(Event)
*/
boolean isFake(Event event);
}

View File

@@ -0,0 +1,41 @@
package com.willfp.illusioner.integrations.mcmmo;
import com.willfp.illusioner.util.ClassUtils;
import org.bukkit.event.Event;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Utility class for interfacing with mcMMO
*/
public class McmmoManager {
private static final Set<McmmoIntegration> integrations = new HashSet<>();
/**
* Register a new mcMMO integration
*
* @param integration The integration to register
*/
public static void registerIntegration(McmmoIntegration integration) {
if(!ClassUtils.exists("com.gmail.nossr50.events.fake.FakeEvent"))
return;
integrations.add(integration);
}
/**
* Get if an event is fake
*
* @param event The event to check
* @return If the event is fake
*/
public static boolean isFake(Event event) {
AtomicBoolean isFake = new AtomicBoolean(false);
integrations.forEach(integration -> {
if (integration.isFake(event)) isFake.set(true);
});
return isFake.get();
}
}

View File

@@ -0,0 +1,20 @@
package com.willfp.illusioner.integrations.mcmmo.plugins;
import com.gmail.nossr50.events.fake.FakeEvent;
import com.willfp.illusioner.integrations.mcmmo.McmmoIntegration;
import org.bukkit.event.Event;
/**
* Concrete implementation of {@link McmmoIntegration}
*/
public class McmmoIntegrationImpl implements McmmoIntegration {
@Override
public boolean isFake(Event event) {
return event instanceof FakeEvent;
}
@Override
public String getPluginName() {
return "mcMMO";
}
}

View File

@@ -0,0 +1,65 @@
package com.willfp.illusioner.integrations.placeholder;
import com.willfp.illusioner.util.interfaces.ObjectBiCallable;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
/**
* A placeholder entry consists of an identifier and an {@link ObjectBiCallable} to fetch the result
*/
public class PlaceholderEntry {
private final String identifier;
private final ObjectBiCallable<String, Player> function;
private final boolean requiresPlayer;
/**
* Create a placeholder entry that doesn't require a player
*
* @param identifier The identifier of the placeholder
* @param function A lambda to get the result of the placeholder
*/
public PlaceholderEntry(String identifier, ObjectBiCallable<String, Player> function) {
this(identifier, function, false);
}
/**
* Create a placeholder entry that may require a player
*
* @param identifier The identifier of the placeholder
* @param function A lambda to get the result of the placeholder
* @param requiresPlayer If the placeholder requires a player
*/
public PlaceholderEntry(String identifier, ObjectBiCallable<String, Player> function, boolean requiresPlayer) {
this.identifier = identifier;
this.function = function;
this.requiresPlayer = requiresPlayer;
}
/**
* Get the identifier of the placeholder
*
* @return The identifier
*/
public String getIdentifier() {
return this.identifier;
}
/**
* Get the result of the placeholder with respect to a player
*
* @param player The player to translate with respect to
* @return The result of the placeholder
*/
public String getResult(@Nullable Player player) {
return this.function.call(player);
}
/**
* Get if the placeholder requires a player to get a result
*
* @return If the placeholder requires a player
*/
public boolean requiresPlayer() {
return requiresPlayer;
}
}

View File

@@ -0,0 +1,24 @@
package com.willfp.illusioner.integrations.placeholder;
import com.willfp.illusioner.integrations.Integration;
import org.bukkit.entity.Player;
/**
* Interface for Placeholder integrations
*/
public interface PlaceholderIntegration extends Integration {
/**
* Register the integration with the specified plugin
* Not to be confused with internal registration in {@link PlaceholderManager#addIntegration(PlaceholderIntegration)}
*/
void registerIntegration();
/**
* Translate all the placeholders in a string with respect to a player
*
* @param text The text to translate
* @param player The player to translate with respect to
* @return The string, translated
*/
String translate(String text, Player player);
}

View File

@@ -0,0 +1,67 @@
package com.willfp.illusioner.integrations.placeholder;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
/**
* Utility class for placeholders
*/
public class PlaceholderManager {
private static final Set<PlaceholderEntry> placeholders = new HashSet<>();
private static final Set<PlaceholderIntegration> integrations = new HashSet<>();
/**
* Register a new placeholder integration
*
* @param integration The {@link PlaceholderIntegration} to register
*/
public static void addIntegration(PlaceholderIntegration integration) {
integration.registerIntegration();
integrations.add(integration);
}
/**
* Register a placeholder
*
* @param expansion The {@link PlaceholderEntry} to register
*/
public static void registerPlaceholder(PlaceholderEntry expansion) {
placeholders.removeIf(placeholderEntry -> placeholderEntry.getIdentifier().equalsIgnoreCase(expansion.getIdentifier()));
placeholders.add(expansion);
}
/**
* Get the result of a placeholder with respect to a player
*
* @param player The player to get the result from
* @param identifier The placeholder identifier
* @return The value of the placeholder
*/
public static String getResult(@Nullable Player player, String identifier) {
Optional<PlaceholderEntry> matching = placeholders.stream().filter(expansion -> expansion.getIdentifier().equalsIgnoreCase(identifier)).findFirst();
if (!matching.isPresent())
return null;
PlaceholderEntry entry = matching.get();
if (player == null && entry.requiresPlayer())
return "";
return entry.getResult(player);
}
/**
* Translate all placeholders with respect to a player
*
* @param text The text that may contain placeholders to translate
* @param player The player to translate the placeholders with respect to
* @return The text, translated
*/
public static String translatePlaceholders(String text, @Nullable Player player) {
AtomicReference<String> translatedReference = new AtomicReference<>(text);
integrations.forEach(placeholderIntegration -> translatedReference.set(placeholderIntegration.translate(translatedReference.get(), player)));
return translatedReference.get();
}
}

View File

@@ -0,0 +1,59 @@
package com.willfp.illusioner.integrations.placeholder.plugins;
import com.willfp.illusioner.IllusionerPlugin;
import com.willfp.illusioner.integrations.placeholder.PlaceholderIntegration;
import com.willfp.illusioner.integrations.placeholder.PlaceholderManager;
import me.clip.placeholderapi.PlaceholderAPI;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
/**
* PlaceholderAPI integration
*/
public class PlaceholderIntegrationPAPI extends PlaceholderExpansion implements PlaceholderIntegration {
@Override
public boolean persist() {
return true;
}
@Override
public boolean canRegister() {
return true;
}
@Override
public @NotNull String getAuthor() {
return "Auxilor";
}
@Override
public @NotNull String getIdentifier() {
return "illusioner";
}
@Override
public @NotNull String getVersion() {
return IllusionerPlugin.getInstance().getDescription().getVersion();
}
@Override
public String onPlaceholderRequest(Player player, @NotNull String identifier) {
return PlaceholderManager.getResult(player, identifier);
}
@Override
public void registerIntegration() {
this.register();
}
@Override
public String getPluginName() {
return "PlaceholderAPI";
}
@Override
public String translate(String text, Player player) {
return PlaceholderAPI.setPlaceholders(player, text);
}
}

View File

@@ -0,0 +1,39 @@
package com.willfp.illusioner.nms;
import com.willfp.illusioner.IllusionerPlugin;
import com.willfp.illusioner.nms.api.BlockBreakWrapper;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
/**
* Utility class to break a block as if the player had done it manually
*/
public class BlockBreak {
private static BlockBreakWrapper blockBreakWrapper;
@ApiStatus.Internal
public static boolean init() {
try {
final Class<?> class2 = Class.forName("com.willfp.illusioner." + IllusionerPlugin.NMS_VERSION + ".BlockBreak");
if (BlockBreakWrapper.class.isAssignableFrom(class2)) {
blockBreakWrapper = (BlockBreakWrapper) class2.getConstructor().newInstance();
}
} catch (Exception e) {
e.printStackTrace();
blockBreakWrapper = null;
}
return blockBreakWrapper != null;
}
/**
* Break a block as a player
*
* @param player The player to break the block as
* @param block The block to break
*/
public static void breakBlock(Player player, Block block) {
assert blockBreakWrapper != null;
blockBreakWrapper.breakBlock(player, block);
}
}

View File

@@ -0,0 +1,38 @@
package com.willfp.illusioner.nms;
import com.willfp.illusioner.IllusionerPlugin;
import com.willfp.illusioner.nms.api.CooldownWrapper;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
/**
* Utility class to get the attack cooldown of a player
*/
public class Cooldown {
private static CooldownWrapper cooldown;
@ApiStatus.Internal
public static boolean init() {
try {
final Class<?> class2 = Class.forName("com.willfp.illusioner." + IllusionerPlugin.NMS_VERSION + ".Cooldown");
if (CooldownWrapper.class.isAssignableFrom(class2)) {
cooldown = (CooldownWrapper) class2.getConstructor().newInstance();
}
} catch (Exception e) {
e.printStackTrace();
cooldown = null;
}
return cooldown != null;
}
/**
* Get a player's attack cooldown
*
* @param player The player to check
* @return A value between 0 and 1, with 1 representing max strength
*/
public static double getCooldown(Player player) {
assert cooldown != null;
return cooldown.getAttackCooldown(player);
}
}

View File

@@ -0,0 +1,41 @@
package com.willfp.illusioner.nms;
import com.willfp.illusioner.IllusionerPlugin;
import com.willfp.illusioner.nms.api.EntityIllusionerWrapper;
import com.willfp.illusioner.nms.api.IllusionerWrapper;
import org.bukkit.Location;
import org.jetbrains.annotations.ApiStatus;
/**
* Utility class to manage NMS illusioner
*/
public class NMSIllusioner {
private static IllusionerWrapper illusionerWrapper;
@ApiStatus.Internal
public static boolean init() {
try {
final Class<?> class2 = Class.forName("com.willfp.illusioner." + IllusionerPlugin.NMS_VERSION + ".Illusioner");
if (IllusionerWrapper.class.isAssignableFrom(class2)) {
illusionerWrapper = (IllusionerWrapper) class2.getConstructor().newInstance();
}
} catch (Exception e) {
e.printStackTrace();
illusionerWrapper = null;
}
return illusionerWrapper != null;
}
/**
* Spawn a new Illusioner Boss
*
* @param location The location to spawn it at
* @param maxHealth The max health for the illusioner to have
* @param attackDamage The attack damage for the illusioner
* @return The illusioner
*/
public static EntityIllusionerWrapper spawn(Location location, double maxHealth, double attackDamage) {
assert illusionerWrapper != null;
return illusionerWrapper.spawn(location, maxHealth, attackDamage);
}
}

View File

@@ -0,0 +1,38 @@
package com.willfp.illusioner.nms;
import com.willfp.illusioner.IllusionerPlugin;
import com.willfp.illusioner.nms.api.OpenInventoryWrapper;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
/**
* Utility class to get the NMS implementation of a players' currently open inventory
*/
public class OpenInventory {
private static OpenInventoryWrapper openInventoryWrapper;
@ApiStatus.Internal
public static boolean init() {
try {
final Class<?> class2 = Class.forName("com.willfp.illusioner." + IllusionerPlugin.NMS_VERSION + ".OpenInventory");
if (OpenInventoryWrapper.class.isAssignableFrom(class2)) {
openInventoryWrapper = (OpenInventoryWrapper) class2.getConstructor().newInstance();
}
} catch (Exception e) {
e.printStackTrace();
openInventoryWrapper = null;
}
return openInventoryWrapper != null;
}
/**
* Get the NMS container of the inventory
*
* @param player The player to check
* @return The NMS container
*/
public static Object getOpenInventory(Player player) {
assert openInventoryWrapper != null;
return openInventoryWrapper.getOpenInventory(player);
}
}

View File

@@ -0,0 +1,40 @@
package com.willfp.illusioner.nms;
import com.willfp.illusioner.IllusionerPlugin;
import com.willfp.illusioner.nms.api.TridentStackWrapper;
import org.bukkit.entity.Trident;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
/**
* Utility class to get the {@link ItemStack} of a given {@link Trident}
*/
public class TridentStack {
private static TridentStackWrapper tridentStackWrapper;
@ApiStatus.Internal
public static boolean init() {
try {
final Class<?> class2 = Class.forName("com.willfp.illusioner." + IllusionerPlugin.NMS_VERSION + ".TridentStack");
if (TridentStackWrapper.class.isAssignableFrom(class2)) {
tridentStackWrapper = (TridentStackWrapper) class2.getConstructor().newInstance();
}
} catch (Exception e) {
e.printStackTrace();
tridentStackWrapper = null;
}
return tridentStackWrapper != null;
}
/**
* Get the {@link ItemStack} of a given {@link Trident}
*
* @param trident The trident to get the ItemStack from
* @return The ItemStack associated with the trident
*/
public static ItemStack getTridentStack(Trident trident) {
assert tridentStackWrapper != null;
return tridentStackWrapper.getTridentStack(trident);
}
}

View File

@@ -0,0 +1,37 @@
package com.willfp.illusioner.util;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class BlockUtils {
private static Set<Block> getNearbyBlocks(Block start, List<Material> allowedMaterials, HashSet<Block> blocks, int limit) {
for (BlockFace face : BlockFace.values()) {
Block block = start.getRelative(face);
if (!blocks.contains(block) && allowedMaterials.contains(block.getType())) {
blocks.add(block);
if (blocks.size() > limit) return blocks;
if (blocks.size() > 2500) return blocks; // anti stack overflow
blocks.addAll(getNearbyBlocks(block, allowedMaterials, blocks, limit));
}
}
return blocks;
}
/**
* Get a set of all blocks in contact with each other of a specific type
*
* @param start The initial block
* @param allowedMaterials A list of all valid {@link Material}s
* @param limit The maximum size of vein to return
* @return A set of all {@link Block}s
*/
public static Set<Block> getVein(Block start, List<Material> allowedMaterials, int limit) {
return getNearbyBlocks(start, allowedMaterials, new HashSet<>(), limit);
}
}

View File

@@ -0,0 +1,19 @@
package com.willfp.illusioner.util;
public class ClassUtils {
/**
* Get if a class exists
*
* @param className The class to check
* @return If the class exists
* @see Class#forName(String)
*/
public static boolean exists(String className) {
try {
Class.forName(className);
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
}

View File

@@ -0,0 +1,112 @@
package com.willfp.illusioner.util;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.SoundCategory;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerItemBreakEvent;
import org.bukkit.event.player.PlayerItemDamageEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta;
/**
* Contains methods for damaging/repairing items
*/
public class DurabilityUtils {
/**
* Damage an item in a player's inventory
* The slot of a held item can be obtained with {@link PlayerInventory#getHeldItemSlot()}
* Armor slots are 39 (helmet), 38 (chestplate), 37 (leggings), 36 (boots)
*
* @param player The player
* @param item The item to damage
* @param damage The amount of damage to deal
* @param slot The slot in the inventory of the item
*/
public static void damageItem(Player player, ItemStack item, int damage, int slot) {
if (item == null) return;
if (item.getItemMeta() == null) return;
if (item.getItemMeta().isUnbreakable()) return;
PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage);
Bukkit.getPluginManager().callEvent(event3);
if (!event3.isCancelled()) {
int damage2 = event3.getDamage();
if (item.getItemMeta() instanceof Damageable) {
Damageable meta = (Damageable) item.getItemMeta();
meta.setDamage(meta.getDamage() + damage2);
if (meta.getDamage() >= item.getType().getMaxDurability()) {
meta.setDamage(item.getType().getMaxDurability());
item.setItemMeta((ItemMeta) meta);
PlayerItemBreakEvent event = new PlayerItemBreakEvent(player, item);
Bukkit.getPluginManager().callEvent(event);
player.getInventory().clear(slot);
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, SoundCategory.BLOCKS, 1, 1);
} else {
item.setItemMeta((ItemMeta) meta);
}
}
}
}
/**
* Damage an item in a player's inventory without breaking it
* The slot of a held item can be obtained with {@link PlayerInventory#getHeldItemSlot()}
* Armor slots are 39 (helmet), 38 (chestplate), 37 (leggings), 36 (boots)
*
* @param item The item to damage
* @param damage The amount of damage to deal
* @param player The player
*/
public static void damageItemNoBreak(ItemStack item, int damage, Player player) {
if (item == null) return;
if (item.getItemMeta() == null) return;
if (item.getItemMeta().isUnbreakable()) return;
PlayerItemDamageEvent event3 = new PlayerItemDamageEvent(player, item, damage);
Bukkit.getPluginManager().callEvent(event3);
if (!event3.isCancelled()) {
int damage2 = event3.getDamage();
if (item.getItemMeta() instanceof Damageable) {
Damageable meta = (Damageable) item.getItemMeta();
meta.setDamage(meta.getDamage() + damage2);
if (meta.getDamage() >= item.getType().getMaxDurability()) {
meta.setDamage(item.getType().getMaxDurability() - 1);
}
item.setItemMeta((ItemMeta) meta);
}
}
}
/**
* Repair an item in a player's inventory
* The slot of a held item can be obtained with {@link PlayerInventory#getHeldItemSlot()}
* Armor slots are 39 (helmet), 38 (chestplate), 37 (leggings), 36 (boots)
*
* @param item The item to damage
* @param repair The amount of damage to heal
*/
public static void repairItem(ItemStack item, int repair) {
if (item == null) return;
if (item.getItemMeta() == null) return;
if (item.getItemMeta().isUnbreakable()) return;
if (item.getItemMeta() instanceof Damageable) {
Damageable meta = (Damageable) item.getItemMeta();
meta.setDamage(meta.getDamage() - repair);
if (meta.getDamage() < 0) {
meta.setDamage(0);
}
item.setItemMeta((ItemMeta) meta);
}
}
}

View File

@@ -0,0 +1,26 @@
package com.willfp.illusioner.util;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
/**
* Class containing methods for striking lightning
*/
public class LightningUtils {
/**
* Strike lightning on player without fire
*
* @param victim The entity to smite
* @param damage The damage to deal
*/
public static void strike(LivingEntity victim, double damage) {
if (victim == null) return;
Location loc = victim.getLocation();
victim.getWorld().strikeLightningEffect(loc);
victim.damage(damage);
}
}

View File

@@ -0,0 +1,148 @@
package com.willfp.illusioner.util;
import java.text.DecimalFormat;
import java.util.TreeMap;
public class NumberUtils {
private final static TreeMap<Integer, String> NUMERALS = new TreeMap<>();
static {
NUMERALS.put(1000, "M");
NUMERALS.put(900, "CM");
NUMERALS.put(500, "D");
NUMERALS.put(400, "CD");
NUMERALS.put(100, "C");
NUMERALS.put(90, "XC");
NUMERALS.put(50, "L");
NUMERALS.put(40, "XL");
NUMERALS.put(10, "X");
NUMERALS.put(9, "IX");
NUMERALS.put(5, "V");
NUMERALS.put(4, "IV");
NUMERALS.put(1, "I");
}
/**
* Bias the input value according to a curve
*
* @param input The input value
* @param bias The bias between -1 and 1, where higher values bias input values to lower output values
* @return The biased output
*/
public static double bias(double input, double bias) {
double k = Math.pow(1 - bias, 3);
return (input * k) / (input * k - input + 1);
}
/**
* If value is above maximum, set it to maximum
*
* @param toChange The value to test
* @param limit The maximum
* @return The new value
*/
public static int equalIfOver(int toChange, int limit) {
if (toChange > limit) {
toChange = limit;
}
return toChange;
}
/**
* If value is above maximum, set it to maximum
*
* @param toChange The value to test
* @param limit The maximum
* @return The new value
*/
public static double equalIfOver(double toChange, double limit) {
if (toChange > limit) {
toChange = limit;
}
return toChange;
}
/**
* Get Roman Numeral from number
*
* @param number The number to convert
* @return The number, converted to a roman numeral
*/
public static String toNumeral(int number) {
if (number >= 1 && number <= 4096) {
int l = NUMERALS.floorKey(number);
if (number == l) {
return NUMERALS.get(number);
}
return NUMERALS.get(l) + toNumeral(number - l);
} else return String.valueOf(number);
}
/**
* Generate random integer in range
*
* @param min Minimum
* @param max Maximum
* @return Random integer
*/
public static int randInt(int min, int max) {
return (int) ((long) min + Math.random() * ((long) max - min + 1));
}
/**
* Generate random double in range
*
* @param min Minimum
* @param max Maximum
* @return Random double
*/
public static double randFloat(double min, double max) {
java.util.Random rand = new java.util.Random();
return rand.nextFloat() * (max - min) + min;
}
/**
* Generate random double with a triangular distribution
*
* @param minimum Minimum
* @param maximum Maximum
* @param peak Peak
* @return Random double
*/
public static double triangularDistribution(double minimum, double maximum, double peak) {
double F = (peak - minimum) / (maximum - minimum);
double rand = Math.random();
if (rand < F) {
return minimum + Math.sqrt(rand * (maximum - minimum) * (peak - minimum));
} else {
return maximum - Math.sqrt((1 - rand) * (maximum - minimum) * (maximum - peak));
}
}
/**
* Get Log base 2 of a number
*
* @param N The number
* @return The result
*/
public static int log2(int N) {
return (int) (Math.log(N) / Math.log(2));
}
/**
* Format double to string
*
* @param toFormat The number to format
* @return Formatted
*/
public static String format(double toFormat) {
DecimalFormat df = new DecimalFormat("0.00");
String formatted = df.format(toFormat);
return formatted.endsWith("00") ? String.valueOf((int) toFormat) : formatted;
}
}

View File

@@ -0,0 +1,94 @@
package com.willfp.illusioner.util;
import com.willfp.illusioner.integrations.placeholder.PlaceholderManager;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static net.md_5.bungee.api.ChatColor.COLOR_CHAR;
public class StringUtils {
/**
* Translate a string - converts Placeholders and Color codes
*
* @param message The message to translate
* @param player The player to translate placeholders with respect to
* @return The message, translated
*/
public static String translate(String message, @Nullable Player player) {
message = PlaceholderManager.translatePlaceholders(message, player);
message = translateHexColorCodes(message);
message = ChatColor.translateAlternateColorCodes('&', message);
return ChatColor.translateAlternateColorCodes('&', translateHexColorCodes(message));
}
/**
* Translate a string without respect to a player
*
* @param message The message to translate
* @return The message, translated
* @see StringUtils#translate(String, Player)
*/
public static String translate(String message) {
message = PlaceholderManager.translatePlaceholders(message, null);
message = translateHexColorCodes(message);
message = ChatColor.translateAlternateColorCodes('&', message);
return ChatColor.translateAlternateColorCodes('&', translateHexColorCodes(message));
}
private static String translateHexColorCodes(String message) {
Pattern hexPattern = Pattern.compile("&#" + "([A-Fa-f0-9]{6})" + "");
Matcher matcher = hexPattern.matcher(message);
StringBuffer buffer = new StringBuffer(message.length() + 4 * 8);
while (matcher.find()) {
String group = matcher.group(1);
matcher.appendReplacement(buffer, COLOR_CHAR + "x"
+ COLOR_CHAR + group.charAt(0) + COLOR_CHAR + group.charAt(1)
+ COLOR_CHAR + group.charAt(2) + COLOR_CHAR + group.charAt(3)
+ COLOR_CHAR + group.charAt(4) + COLOR_CHAR + group.charAt(5));
}
return matcher.appendTail(buffer).toString();
}
/**
* Internal implementation of {@link String#valueOf}
* Formats collections and doubles better
*
* @param object The object to convert to string
* @return The object stringified
*/
public static String internalToString(@Nullable Object object) {
if (object == null) return "null";
if (object instanceof Integer) {
return ((Integer) object).toString();
} else if (object instanceof String) {
return (String) object;
} else if (object instanceof Double) {
return NumberUtils.format((Double) object);
} else if (object instanceof Collection<?>) {
Collection<?> c = (Collection<?>) object;
return c.stream().map(String::valueOf).collect(Collectors.joining(", "));
} else return String.valueOf(object);
}
/**
* Remove a string of characters from the start of a string
*
* @param s The string to remove the prefix from
* @param prefix The substring to remove
* @return The string with the prefix removed
*/
public static String removePrefix(String s, String prefix) {
if (s != null && prefix != null && s.startsWith(prefix)) {
return s.substring(prefix.length());
}
return s;
}
}

View File

@@ -0,0 +1,141 @@
package com.willfp.illusioner.util;
import org.bukkit.util.NumberConversions;
import org.bukkit.util.Vector;
import java.util.ArrayList;
public class VectorUtils {
/**
* If vector has all components as finite
*
* @param vector The vector to check
* @return If the vector is finite
*/
public static boolean isFinite(Vector vector) {
try {
NumberConversions.checkFinite(vector.getX(), "x not finite");
NumberConversions.checkFinite(vector.getY(), "y not finite");
NumberConversions.checkFinite(vector.getZ(), "z not finite");
} catch (IllegalArgumentException e) {
return false;
}
return true;
}
/**
* Only keep largest part of normalised vector.
* For example: -0.8, 0.01, -0.2 would become -1, 0, 0
*
* @param vec The vector to simplify
* @return The vector, simplified
*/
public static Vector simplifyVector(Vector vec) {
double x = Math.abs(vec.getX());
double y = Math.abs(vec.getY());
double z = Math.abs(vec.getZ());
double max = Math.max(x, Math.max(y, z));
if (x > 1 || z > 1) {
max = y;
}
if (max == x) {
if (vec.getX() < 0) {
return new Vector(-1, 0, 0);
}
return new Vector(1, 0, 0);
} else if (max == y) {
if (vec.getY() < 0) {
return new Vector(0, -1, 0);
}
return new Vector(0, 1, 0);
} else {
if (vec.getZ() < 0) {
return new Vector(0, 0, -1);
}
return new Vector(0, 0, 1);
}
}
/**
* Get circle as relative vectors
*
* @param radius The radius
* @return An array of {@link Vector}s
*/
public static Vector[] getCircle(int radius) {
ArrayList<Vector> circleVecs = new ArrayList<>();
int xoffset = -radius;
int zoffset = -radius;
while (zoffset <= radius) {
while (xoffset <= radius) {
if (Math.round(Math.sqrt((xoffset * xoffset) + (zoffset * zoffset))) <= radius) {
circleVecs.add(new Vector(xoffset, 0, zoffset));
} else {
xoffset++;
continue;
}
xoffset++;
}
xoffset = -radius;
zoffset++;
}
return circleVecs.toArray(new Vector[0]);
}
/**
* Get square as relative vectors
*
* @param radius The radius of the square
* @return An array of {@link Vector}s
*/
public static Vector[] getSquare(int radius) {
ArrayList<Vector> circleVecs = new ArrayList<>();
int xoffset = -radius;
int zoffset = -radius;
while (zoffset <= radius) {
while (xoffset <= radius) {
circleVecs.add(new Vector(xoffset, 0, zoffset));
xoffset++;
}
xoffset = -radius;
zoffset++;
}
return circleVecs.toArray(new Vector[0]);
}
/**
* Get cube as relative vectors
*
* @param radius The radius of the cube
* @return An array of {@link Vector}s
*/
public static Vector[] getCube(int radius) {
ArrayList<Vector> cubeVecs = new ArrayList<>();
int xoffset = -radius;
int zoffset = -radius;
int yoffset = -radius;
while (yoffset <= radius) {
while (zoffset <= radius) {
while (xoffset <= radius) {
cubeVecs.add(new Vector(xoffset, yoffset, zoffset));
xoffset++;
}
xoffset = -radius;
zoffset++;
}
zoffset = -radius;
yoffset++;
}
return cubeVecs.toArray(new Vector[0]);
}
}

View File

@@ -0,0 +1,9 @@
package com.willfp.illusioner.util.interfaces;
/**
* Simple functional interface to run some code on demand
*/
@FunctionalInterface
public interface Callable {
void call();
}

View File

@@ -0,0 +1,12 @@
package com.willfp.illusioner.util.interfaces;
/**
* Functional Interface to return a value of a specified type given a certain parameter
*
* @param <A> The type of object to return
* @param <B> The type of object for the parameter
*/
@FunctionalInterface
public interface ObjectBiCallable<A, B> {
A call(B object);
}

View File

@@ -0,0 +1,11 @@
package com.willfp.illusioner.util.interfaces;
/**
* Functional Interface to return a value of a given type
*
* @param <A> The type to return
*/
@FunctionalInterface
public interface ObjectCallable<A> {
A call();
}

View File

@@ -0,0 +1,8 @@
package com.willfp.illusioner.util.interfaces;
/**
* Interface for objects that can be internally registered
*/
public interface Registerable {
void register();
}

View File

@@ -0,0 +1,270 @@
package com.willfp.illusioner.util.internal;
import com.willfp.illusioner.IllusionerPlugin;
import com.willfp.illusioner.command.commands.CommandIldebug;
import com.willfp.illusioner.command.commands.CommandIlreload;
import com.willfp.illusioner.config.ConfigManager;
import com.willfp.illusioner.events.armorequip.ArmorListener;
import com.willfp.illusioner.events.armorequip.DispenserArmorListener;
import com.willfp.illusioner.events.entitydeathbyentity.EntityDeathByEntityListeners;
import com.willfp.illusioner.events.naturalexpgainevent.NaturalExpGainListeners;
import com.willfp.illusioner.illusioner.AttackListeners;
import com.willfp.illusioner.illusioner.DeathListeners;
import com.willfp.illusioner.illusioner.SpawnListeners;
import com.willfp.illusioner.integrations.anticheat.AnticheatManager;
import com.willfp.illusioner.integrations.anticheat.plugins.AnticheatAAC;
import com.willfp.illusioner.integrations.anticheat.plugins.AnticheatMatrix;
import com.willfp.illusioner.integrations.anticheat.plugins.AnticheatNCP;
import com.willfp.illusioner.integrations.anticheat.plugins.AnticheatSpartan;
import com.willfp.illusioner.integrations.antigrief.AntigriefManager;
import com.willfp.illusioner.integrations.antigrief.plugins.AntigriefFactionsUUID;
import com.willfp.illusioner.integrations.antigrief.plugins.AntigriefGriefPrevention;
import com.willfp.illusioner.integrations.antigrief.plugins.AntigriefKingdoms;
import com.willfp.illusioner.integrations.antigrief.plugins.AntigriefLands;
import com.willfp.illusioner.integrations.antigrief.plugins.AntigriefTowny;
import com.willfp.illusioner.integrations.antigrief.plugins.AntigriefWorldGuard;
import com.willfp.illusioner.integrations.anvilgui.AnvilGUIManager;
import com.willfp.illusioner.integrations.anvilgui.plugins.AnvilGUIImpl;
import com.willfp.illusioner.integrations.mcmmo.McmmoManager;
import com.willfp.illusioner.integrations.mcmmo.plugins.McmmoIntegrationImpl;
import com.willfp.illusioner.integrations.placeholder.PlaceholderManager;
import com.willfp.illusioner.integrations.placeholder.plugins.PlaceholderIntegrationPAPI;
import com.willfp.illusioner.nms.BlockBreak;
import com.willfp.illusioner.nms.Cooldown;
import com.willfp.illusioner.nms.NMSIllusioner;
import com.willfp.illusioner.nms.OpenInventory;
import com.willfp.illusioner.nms.TridentStack;
import com.willfp.illusioner.util.interfaces.Callable;
import com.willfp.illusioner.util.internal.updater.PlayerJoinListener;
import com.willfp.illusioner.util.internal.updater.UpdateChecker;
import com.willfp.illusioner.util.optional.Prerequisite;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Class containing methods for the loading and unloading of Illusioner
*/
public class Loader {
/**
* Called by {@link IllusionerPlugin#onEnable()}
*/
public static void load() {
Logger.info("==========================================");
Logger.info("");
Logger.info("Loading &9Illusioner");
Logger.info("Made by &9Auxilor&f - willfp.com");
Logger.info("");
Logger.info("==========================================");
/*
Load Configs
*/
Logger.info("Loading Configs...");
ConfigManager.updateConfigs();
Logger.info("");
/*
Load NMS
*/
Logger.info("Loading NMS APIs...");
if (Cooldown.init()) {
Logger.info("Cooldown: &aSUCCESS");
} else {
Logger.info("Cooldown: &cFAILURE");
Logger.error("&cAborting...");
Bukkit.getPluginManager().disablePlugin(IllusionerPlugin.getInstance());
}
if (TridentStack.init()) {
Logger.info("Trident API: &aSUCCESS");
} else {
Logger.info("Trident API: &cFAILURE");
Logger.error("&cAborting...");
Bukkit.getPluginManager().disablePlugin(IllusionerPlugin.getInstance());
}
if (BlockBreak.init()) {
Logger.info("Block Break: &aSUCCESS");
} else {
Logger.info("Block Break: &cFAILURE");
Logger.error("&cAborting...");
Bukkit.getPluginManager().disablePlugin(IllusionerPlugin.getInstance());
}
if (OpenInventory.init()) {
Logger.info("Open Inventory: &aSUCCESS");
} else {
Logger.info("Open Inventory: &cFAILURE");
Logger.error("&cAborting...");
Bukkit.getPluginManager().disablePlugin(IllusionerPlugin.getInstance());
}
if (NMSIllusioner.init()) {
Logger.info("NMS Illusioner: &aSUCCESS");
} else {
Logger.info("NMS Illusioner: &cFAILURE");
Logger.error("&cAborting...");
Bukkit.getPluginManager().disablePlugin(IllusionerPlugin.getInstance());
}
Logger.info("");
/*
Register Events
*/
Logger.info("Registering Events...");
Bukkit.getPluginManager().registerEvents(new ArmorListener(), IllusionerPlugin.getInstance());
Bukkit.getPluginManager().registerEvents(new DispenserArmorListener(), IllusionerPlugin.getInstance());
Bukkit.getPluginManager().registerEvents(new PlayerJoinListener(), IllusionerPlugin.getInstance());
Bukkit.getPluginManager().registerEvents(new EntityDeathByEntityListeners(), IllusionerPlugin.getInstance());
Bukkit.getPluginManager().registerEvents(new NaturalExpGainListeners(), IllusionerPlugin.getInstance());
Bukkit.getPluginManager().registerEvents(new AttackListeners(), IllusionerPlugin.getInstance());
Bukkit.getPluginManager().registerEvents(new DeathListeners(), IllusionerPlugin.getInstance());
Bukkit.getPluginManager().registerEvents(new SpawnListeners(), IllusionerPlugin.getInstance());
Logger.info("");
/*
Load integrations
*/
Logger.info("Loading Integrations...");
final HashMap<String, Callable> integrations = new HashMap<String, Callable>() {{
// AntiGrief
put("WorldGuard", () -> AntigriefManager.register(new AntigriefWorldGuard()));
put("GriefPrevention", () -> AntigriefManager.register(new AntigriefGriefPrevention()));
put("FactionsUUID", () -> AntigriefManager.register(new AntigriefFactionsUUID()));
put("Towny", () -> AntigriefManager.register(new AntigriefTowny()));
put("Lands", () -> AntigriefManager.register(new AntigriefLands()));
put("Kingdoms", () -> AntigriefManager.register(new AntigriefKingdoms()));
// AntiCheat
put("AAC", () -> AnticheatManager.register(new AnticheatAAC()));
put("Matrix", () -> AnticheatManager.register(new AnticheatMatrix()));
put("NoCheatPlus", () -> AnticheatManager.register(new AnticheatNCP()));
put("Spartan", () -> AnticheatManager.register(new AnticheatSpartan()));
// MISC
put("PlaceholderAPI", () -> PlaceholderManager.addIntegration(new PlaceholderIntegrationPAPI()));
put("mcMMO", () -> McmmoManager.registerIntegration(new McmmoIntegrationImpl()));
}};
Set<String> enabledPlugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).collect(Collectors.toSet());
integrations.forEach(((s, callable) -> {
StringBuilder log = new StringBuilder();
log.append(s).append(": ");
if (enabledPlugins.contains(s)) {
callable.call();
log.append("&aENABLED");
} else {
log.append("&9DISABLED");
}
Logger.info(log.toString());
}));
Prerequisite.update();
AnvilGUIManager.registerIntegration(new AnvilGUIImpl()); // No direct lib, can always register
Logger.info("");
/*
Load Commands
*/
Logger.info("Loading Commands...");
new CommandIlreload().register();
new CommandIldebug().register();
Logger.info("");
/*
Start bStats
*/
Logger.info("Hooking into bStats...");
new Metrics(IllusionerPlugin.getInstance(), 7666);
Logger.info("");
/*
Finish
*/
Bukkit.getScheduler().runTaskLater(IllusionerPlugin.getInstance(), Loader::postLoad, 1);
Logger.info("Loaded &9Illusioner!");
}
/**
* Called after server is loaded
*/
public static void postLoad() {
new UpdateChecker(IllusionerPlugin.getInstance(), 79573).getVersion((version) -> {
DefaultArtifactVersion currentVersion = new DefaultArtifactVersion(IllusionerPlugin.getInstance().getDescription().getVersion());
DefaultArtifactVersion mostRecentVersion = new DefaultArtifactVersion(version);
Logger.info("----------------------------");
Logger.info("");
Logger.info("Illusioner Updater");
Logger.info("");
if (currentVersion.compareTo(mostRecentVersion) > 0 || currentVersion.equals(mostRecentVersion)) {
Logger.info("&aIllusioner is up to date! (Version " + IllusionerPlugin.getInstance().getDescription().getVersion() + ")");
} else {
UpdateChecker.setOutdated(true);
UpdateChecker.setNewVersion(version);
Bukkit.getScheduler().runTaskTimer(IllusionerPlugin.getInstance(), () -> {
Logger.info("&6Illusioner is out of date! (Version " + IllusionerPlugin.getInstance().getDescription().getVersion() + ")");
Logger.info("&6The newest version is &f" + version);
Logger.info("&6Download the new version here: &fhttps://www.spigotmc.org/resources/illusioner.79573/");
}, 0, 864000);
}
Logger.info("");
Logger.info("----------------------------");
});
/*
Check for paper
*/
if (!Prerequisite.HasPaper.isMet()) {
Logger.error("");
Logger.error("----------------------------");
Logger.error("");
Logger.error("You don't seem to be running paper!");
Logger.error("Paper is strongly recommended for all servers,");
Logger.error("and some features may not function properly without it");
Logger.error("Download Paper from &fhttps://papermc.io");
Logger.error("");
Logger.error("----------------------------");
Logger.error("");
}
Logger.info("");
}
/**
* Called by {@link IllusionerPlugin#onDisable()}
*/
public static void unload() {
Logger.info("&cDisabling Illusioner...");
Logger.info("&fBye! :)");
}
/**
* Called by /ecoreload
*/
public static void reload() {
ConfigManager.updateConfigs();
}
}

View File

@@ -0,0 +1,39 @@
package com.willfp.illusioner.util.internal;
import com.willfp.illusioner.IllusionerPlugin;
import com.willfp.illusioner.util.StringUtils;
/**
* The internal logger for Illusioner
* Automatically formats all inputs using {@link StringUtils#translate(String)}
*/
public class Logger {
private static final IllusionerPlugin INSTANCE = IllusionerPlugin.getInstance();
/**
* Print an info (neutral) message to console
*
* @param message The message to send
*/
public static void info(String message) {
INSTANCE.getLogger().info(StringUtils.translate(message));
}
/**
* Print a warning to console
*
* @param message The warning
*/
public static void warn(String message) {
INSTANCE.getLogger().warning(StringUtils.translate(message));
}
/**
* Print an error to console
*
* @param message The error
*/
public static void error(String message) {
INSTANCE.getLogger().severe(StringUtils.translate(message));
}
}

View File

@@ -0,0 +1,19 @@
package com.willfp.illusioner.util.internal.updater;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
public class PlayerJoinListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
/*
if (UpdateChecker.isOutdated()) {
if (event.getPlayer().hasPermission("illusioner.updateannounce")) {
event.getPlayer().sendMessage(ConfigManager.getLang().getMessage("outdated").replace("%ver%", IllusionerPlugin.getInstance().getDescription().getVersion())
.replace("%newver%", UpdateChecker.getNewVersion()));
}
}
*/
}
}

View File

@@ -0,0 +1,86 @@
package com.willfp.illusioner.util.internal.updater;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.Consumer;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Scanner;
/**
* Checks spigot if the plugin is out of date
*/
public class UpdateChecker {
private static boolean outdated;
private static String newVersion;
private final Plugin plugin;
private final int resourceId;
/**
* Create an update checker for the specified spigot resource id
*
* @param plugin The plugin to check
* @param resourceId The resource ID of the plugin
*/
public UpdateChecker(Plugin plugin, int resourceId) {
this.plugin = plugin;
this.resourceId = resourceId;
}
/**
* Get the latest version of the plugin
*
* @param consumer The process to run after checking
*/
public void getVersion(final Consumer<? super String> consumer) {
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> {
try (InputStream inputStream = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + this.resourceId).openStream(); Scanner scanner = new Scanner(inputStream)) {
if (scanner.hasNext()) {
consumer.accept(scanner.next());
}
} catch (IOException exception) {
this.plugin.getLogger().warning("Failed to check for Illusioner updates: " + exception.getMessage());
}
});
}
/**
* Get if the plugin is outdated
*
* @return If the plugin is outdated
*/
public static boolean isOutdated() {
return outdated;
}
/**
* Get the newest available version of the plugin
*
* @return The latest version
*/
public static String getNewVersion() {
return newVersion;
}
/**
* Mark the plugin as outdated or not
*
* @param outdated Whether the plugin is outdated
*/
public static void setOutdated(boolean outdated) {
UpdateChecker.outdated = outdated;
}
/**
* Set the newest available version of the plugin
*
* @param newVersion The newest version
*/
public static void setNewVersion(String newVersion) {
UpdateChecker.newVersion = newVersion;
}
}

View File

@@ -0,0 +1,89 @@
package com.willfp.illusioner.util.optional;
import com.willfp.illusioner.util.ClassUtils;
import com.willfp.illusioner.util.interfaces.ObjectCallable;
import org.bukkit.Bukkit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* An object representing a condition that must be met in order to perform an action
*/
public class Prerequisite {
private static final List<Prerequisite> values = new ArrayList<>();
/**
* Requires the server to be running minecraft version 1.16 or higher
*/
public static final Prerequisite MinVer1_16 = new Prerequisite(
() -> !Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3].contains("15"),
"Requires minimum server version of 1.16"
);
/**
* Requires the server to be running an implementation of paper
*/
public static final Prerequisite HasPaper = new Prerequisite(
() -> ClassUtils.exists("com.destroystokyo.paper.event.player.PlayerElytraBoostEvent"),
"Requires server to be running paper (or a fork)"
);
private boolean isMet;
private final ObjectCallable<Boolean> isMetCallable;
private final String description;
/**
* Create a prerequisite
*
* @param isMetCallable An {@link ObjectCallable<Boolean>} that returns if the prerequisite is met
* @param description The description of the prerequisite, shown to the user if it isn't
*/
public Prerequisite(ObjectCallable<Boolean> isMetCallable, String description) {
this.isMetCallable = isMetCallable;
this.isMet = isMetCallable.call();
this.description = description;
values.add(this);
}
/**
* Get the description of the prerequisite
*
* @return The description
*/
public String getDescription() {
return description;
}
/**
* Get if the prerequisite has been met
*
* @return If the prerequisite is met
*/
public boolean isMet() {
return isMet;
}
private void refresh() {
this.isMet = this.isMetCallable.call();
}
/**
* Update all prerequisites' {@link Prerequisite#isMet}
*/
public static void update() {
values.forEach(Prerequisite::refresh);
}
/**
* Check if all prerequisites in array are met
*
* @param prerequisites A primitive array of prerequisites to check
* @return If all the prerequisites are met
*/
public static boolean areMet(Prerequisite[] prerequisites) {
update();
return Arrays.stream(prerequisites).allMatch(Prerequisite::isMet);
}
}

Some files were not shown because too many files have changed in this diff Show More