mirror of
https://github.com/SimplexDevelopment/ArcanumOcculta.git
synced 2024-11-14 21:43:33 +00:00
updates
This commit is contained in:
parent
57f0381731
commit
f5690dd658
@ -8,8 +8,8 @@ version = '1.0'
|
|||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven {
|
maven {
|
||||||
name = "spigotmc-repo"
|
name "papermc-repo"
|
||||||
url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/"
|
url "https://repo.papermc.io/repository/maven-public/"
|
||||||
}
|
}
|
||||||
maven {
|
maven {
|
||||||
name = "sonatype"
|
name = "sonatype"
|
||||||
@ -18,7 +18,7 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly "org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT"
|
compileOnly "io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT"
|
||||||
compileOnly "org.reflections:reflections:0.10.2"
|
compileOnly "org.reflections:reflections:0.10.2"
|
||||||
implementation "org.jetbrains:annotations:23.0.0"
|
implementation "org.jetbrains:annotations:23.0.0"
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
package app.simplexdev.arcanumocculta;
|
package app.simplexdev.arcanumocculta;
|
||||||
|
|
||||||
import app.simplexdev.arcanumocculta.api.event.ExperienceUpdateEvent;
|
import app.simplexdev.arcanumocculta.command.CasterCommand;
|
||||||
import org.bukkit.Bukkit;
|
import app.simplexdev.arcanumocculta.command.base.CommandLoader;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
public class ArcanumOcculta extends JavaPlugin
|
public class ArcanumOcculta extends JavaPlugin
|
||||||
{
|
{
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onEnable() {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ArcanumOcculta getInstance()
|
public static ArcanumOcculta getInstance()
|
||||||
{
|
{
|
||||||
return JavaPlugin.getPlugin(ArcanumOcculta.class);
|
return JavaPlugin.getPlugin(ArcanumOcculta.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable()
|
||||||
|
{
|
||||||
|
// Registers every command contained in the package which CasterCommand is located.
|
||||||
|
new CommandLoader(this)
|
||||||
|
.register(CasterCommand.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,19 @@ public abstract class AbstractSpell implements Spell
|
|||||||
private final long coolDown;
|
private final long coolDown;
|
||||||
private final SplittableRandom random = new SplittableRandom();
|
private final SplittableRandom random = new SplittableRandom();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new spell with the given parameters.
|
||||||
|
*
|
||||||
|
* @param name The display name of the spell.
|
||||||
|
* @param id The actual id of the spell, typically the display name in all lowercase
|
||||||
|
* separated by underscores instead of spaces.
|
||||||
|
* @param description The description of the spell.
|
||||||
|
* @param levelRequirement The level requirement (using {@link CasterLevel}) of the spell.
|
||||||
|
* @param baseDamage The base damage (using {@link Damages}) of the spell.
|
||||||
|
* @param effectDuration The duration (using {@link Durations}) of the spell's effects.
|
||||||
|
* @param manaCost The mana cost (using {@link ManaCosts}) of the spell.
|
||||||
|
* @param coolDown The cool down of the spell in seconds.
|
||||||
|
*/
|
||||||
protected AbstractSpell(final String name, final String id,
|
protected AbstractSpell(final String name, final String id,
|
||||||
final String description, final CasterLevel levelRequirement,
|
final String description, final CasterLevel levelRequirement,
|
||||||
final Damages baseDamage, final Durations effectDuration,
|
final Damages baseDamage, final Durations effectDuration,
|
||||||
@ -51,6 +64,15 @@ public abstract class AbstractSpell implements Spell
|
|||||||
this.coolDown = coolDown;
|
this.coolDown = coolDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the actual "projectile," which is just an item display entity with a velocity.
|
||||||
|
*
|
||||||
|
* @param visual The visual of the projectile
|
||||||
|
* @param world The world to spawn the projectile in
|
||||||
|
* @param location The location to spawn the projectile at
|
||||||
|
* @param velocity The velocity of the projectile
|
||||||
|
* @return The projectile entity
|
||||||
|
*/
|
||||||
private static ItemDisplay createProjectile(final Material visual, final World world, final Location location,
|
private static ItemDisplay createProjectile(final Material visual, final World world, final Location location,
|
||||||
final Vector velocity)
|
final Vector velocity)
|
||||||
{
|
{
|
||||||
@ -136,6 +158,9 @@ public abstract class AbstractSpell implements Spell
|
|||||||
&& caster.getCurrentLevel().isAtLeast(this.getLevelRequirement());
|
&& caster.getCurrentLevel().isAtLeast(this.getLevelRequirement());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A singular {@link SplittableRandom} instance for this spell.
|
||||||
|
*/
|
||||||
protected SplittableRandom random()
|
protected SplittableRandom random()
|
||||||
{
|
{
|
||||||
return random;
|
return random;
|
||||||
@ -156,6 +181,12 @@ public abstract class AbstractSpell implements Spell
|
|||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the contents of {@link #getSpellEffects()} to the given targets.
|
||||||
|
*
|
||||||
|
* @param targets The targets to apply the effects to
|
||||||
|
* @param caster The caster who is casting the spell
|
||||||
|
*/
|
||||||
public void applyEffects(final List<Entity> targets, final Caster caster)
|
public void applyEffects(final List<Entity> targets, final Caster caster)
|
||||||
{
|
{
|
||||||
targets.stream()
|
targets.stream()
|
||||||
@ -167,16 +198,35 @@ public abstract class AbstractSpell implements Spell
|
|||||||
getSpellEffects()));
|
getSpellEffects()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simulates an explosion at the given location.
|
||||||
|
*
|
||||||
|
* @param location The location to simulate the explosion at
|
||||||
|
* @param size The size of the explosion
|
||||||
|
* @param breakBlocks Whether the explosion should break blocks or not.
|
||||||
|
*/
|
||||||
public void simulateExplosion(final Location location, final float size, boolean breakBlocks)
|
public void simulateExplosion(final Location location, final float size, boolean breakBlocks)
|
||||||
{
|
{
|
||||||
location.getWorld().createExplosion(location, size, true, breakBlocks);
|
location.getWorld().createExplosion(location, size, true, breakBlocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a vector that points in the direction the caster is looking.
|
||||||
|
*
|
||||||
|
* @param caster The caster who is casting the spell
|
||||||
|
* @return A vector that points in the direction the caster is looking
|
||||||
|
*/
|
||||||
public Vector tracerVector(final Caster caster)
|
public Vector tracerVector(final Caster caster)
|
||||||
{
|
{
|
||||||
return caster.bukkit().getLocation().clone().getDirection().multiply(2);
|
return caster.bukkit().getLocation().clone().getDirection().multiply(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the top most block at the caster's eye location.
|
||||||
|
*
|
||||||
|
* @param caster The caster who is casting the spell
|
||||||
|
* @return The top most block at the caster's eye location
|
||||||
|
*/
|
||||||
public Location topLocation(final Caster caster)
|
public Location topLocation(final Caster caster)
|
||||||
{
|
{
|
||||||
final World world = caster.bukkit().getWorld();
|
final World world = caster.bukkit().getWorld();
|
||||||
@ -185,6 +235,12 @@ public abstract class AbstractSpell implements Spell
|
|||||||
return eyeLocation.add(0, diff, 0);
|
return eyeLocation.add(0, diff, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a vector that points downwards.
|
||||||
|
*
|
||||||
|
* @param caster The caster who is casting the spell
|
||||||
|
* @return A vector that points downwards
|
||||||
|
*/
|
||||||
public Vector meteorVector(final Caster caster)
|
public Vector meteorVector(final Caster caster)
|
||||||
{
|
{
|
||||||
final Location topLocation = topLocation(caster);
|
final Location topLocation = topLocation(caster);
|
||||||
@ -192,6 +248,14 @@ public abstract class AbstractSpell implements Spell
|
|||||||
return v.multiply(new Vector(0, -5, 0));
|
return v.multiply(new Vector(0, -5, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a projectile which fires from the caster's eye height.
|
||||||
|
*
|
||||||
|
* @param caster The caster who is casting the spell
|
||||||
|
* @param visual The visual of the projectile
|
||||||
|
* @param velocity The velocity of the projectile
|
||||||
|
* @return The projectile entity
|
||||||
|
*/
|
||||||
public Entity prepareProjectile(final Caster caster, final Material visual, final Vector velocity)
|
public Entity prepareProjectile(final Caster caster, final Material visual, final Vector velocity)
|
||||||
{
|
{
|
||||||
final double expMod = getLevelRequirement().getNextLevelExp();
|
final double expMod = getLevelRequirement().getNextLevelExp();
|
||||||
@ -205,6 +269,14 @@ public abstract class AbstractSpell implements Spell
|
|||||||
return projectile;
|
return projectile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawns a single particle with a random directional offset based on the standard gaussian distribution.
|
||||||
|
* This keeps the particles in a relatively straight line while giving them some minor movement.
|
||||||
|
*
|
||||||
|
* @param world The world to spawn the particle in
|
||||||
|
* @param location The location to spawn the particle at
|
||||||
|
* @param particle The particle to spawn
|
||||||
|
*/
|
||||||
public void tracerDirectional(final World world, final Location location, final Particle particle)
|
public void tracerDirectional(final World world, final Location location, final Particle particle)
|
||||||
{
|
{
|
||||||
world.spawnParticle(particle,
|
world.spawnParticle(particle,
|
||||||
@ -215,6 +287,16 @@ public abstract class AbstractSpell implements Spell
|
|||||||
random().nextDouble(-2, 2));
|
random().nextDouble(-2, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawns a single particle with a color based on the specified R G B values.
|
||||||
|
*
|
||||||
|
* @param world The world to spawn the particle in
|
||||||
|
* @param location The location to spawn the particle at
|
||||||
|
* @param particle The particle to spawn
|
||||||
|
* @param r The red value of the particle
|
||||||
|
* @param g The green value of the particle
|
||||||
|
* @param b The blue value of the particle
|
||||||
|
*/
|
||||||
public void tracerRGB(final World world, final Location location,
|
public void tracerRGB(final World world, final Location location,
|
||||||
final Particle particle, final int r,
|
final Particle particle, final int r,
|
||||||
final int g, final int b)
|
final int g, final int b)
|
||||||
@ -222,6 +304,13 @@ public abstract class AbstractSpell implements Spell
|
|||||||
world.spawnParticle(particle, location, 0, r, g, b);
|
world.spawnParticle(particle, location, 0, r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawns a particle spiral with a radius of 2 and an incremental step of 5 at the given location.
|
||||||
|
*
|
||||||
|
* @param world The world to spawn the particle in
|
||||||
|
* @param location The location to spawn the particle at
|
||||||
|
* @param particle The particle to spawn
|
||||||
|
*/
|
||||||
public void spiral(final World world, final Location location, final Particle particle)
|
public void spiral(final World world, final Location location, final Particle particle)
|
||||||
{
|
{
|
||||||
final double step = 0.5;
|
final double step = 0.5;
|
||||||
@ -229,14 +318,26 @@ public abstract class AbstractSpell implements Spell
|
|||||||
final double area = Math.PI * Math.pow(radius, 2);
|
final double area = Math.PI * Math.pow(radius, 2);
|
||||||
final double theta = area / step;
|
final double theta = area / step;
|
||||||
final double phi = step / radius;
|
final double phi = step / radius;
|
||||||
for (double i = 0; i < theta; i += phi)
|
for (double i = 0; i < 2 * Math.PI; i += step)
|
||||||
{
|
{
|
||||||
final double x = radius * Math.cos(i);
|
final double x = theta * Math.cos(i);
|
||||||
final double z = radius * Math.sin(i);
|
final double y = phi * Math.sin(i);
|
||||||
world.spawnParticle(particle, location.clone().add(x, 0, z), 0);
|
world.spawnParticle(particle, location.clone().add(x, y, 0), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawns a cloud effect using an area effect cloud.
|
||||||
|
* The PotionType parameter can be null if you don't want to apply a potion effect.
|
||||||
|
*
|
||||||
|
* @param world The world to spawn the cloud in
|
||||||
|
* @param location The location to spawn the cloud at
|
||||||
|
* @param particle The particle to use for the cloud
|
||||||
|
* @param size The size of the cloud
|
||||||
|
* @param duration The duration of the cloud
|
||||||
|
* @param effect The potion effect to apply to the cloud, can be null.
|
||||||
|
* @return The cloud entity
|
||||||
|
*/
|
||||||
public AreaEffectCloud cloud(final World world,
|
public AreaEffectCloud cloud(final World world,
|
||||||
final Location location,
|
final Location location,
|
||||||
final Particle particle,
|
final Particle particle,
|
||||||
@ -259,6 +360,13 @@ public abstract class AbstractSpell implements Spell
|
|||||||
return cloud;
|
return cloud;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the given effects to the target.
|
||||||
|
*
|
||||||
|
* @param target The target to apply the effects to
|
||||||
|
* @param caster The caster who is casting the spell
|
||||||
|
* @param effects The effects to apply
|
||||||
|
*/
|
||||||
protected void applyEffectsIndividually(final LivingEntity target,
|
protected void applyEffectsIndividually(final LivingEntity target,
|
||||||
final Caster caster, final SpellEffect... effects)
|
final Caster caster, final SpellEffect... effects)
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Simplex Development Group
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* with the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package app.simplexdev.arcanumocculta.command;
|
||||||
|
|
||||||
|
import app.simplexdev.arcanumocculta.command.base.CommandResponse;
|
||||||
|
import app.simplexdev.arcanumocculta.command.base.Commander;
|
||||||
|
import app.simplexdev.arcanumocculta.command.base.Completion;
|
||||||
|
import app.simplexdev.arcanumocculta.command.base.Info;
|
||||||
|
import app.simplexdev.arcanumocculta.command.base.Permissions;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
@Info(name = "caster", description = "Caster commands", usage = "/caster <subcommand> [args]")
|
||||||
|
@Permissions("arcaneum.caster")
|
||||||
|
@Completion(index = 0, args = {})
|
||||||
|
@Completion(index = 1, args = {})
|
||||||
|
public class CasterCommand implements Commander
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public CommandResponse run(CommandSender sender, String[] args)
|
||||||
|
{
|
||||||
|
return CommandResponse.of("Not implemented yet!");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Simplex Development Group
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* with the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package app.simplexdev.arcanumocculta.command;
|
||||||
|
|
||||||
|
public class WandCommand
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Simplex Development Group
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* with the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package app.simplexdev.arcanumocculta.command.base;
|
||||||
|
|
||||||
|
import app.simplexdev.arcanumocculta.ArcanumOcculta;
|
||||||
|
import java.util.List;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.ConsoleCommandSender;
|
||||||
|
import org.bukkit.command.PluginIdentifiableCommand;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
final class CommandDelegate extends Command implements PluginIdentifiableCommand
|
||||||
|
{
|
||||||
|
final Commander command;
|
||||||
|
final ArcanumOcculta plugin;
|
||||||
|
|
||||||
|
public CommandDelegate(final ArcanumOcculta plugin, final Commander command)
|
||||||
|
{
|
||||||
|
super(command.getName());
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.command = command;
|
||||||
|
this.setLabel(command.getName());
|
||||||
|
this.setDescription(command.getDescription());
|
||||||
|
this.setUsage(command.getUsage());
|
||||||
|
this.setPermission(command.getPermission());
|
||||||
|
this.setPermissionMessage(command.getPermissionMessage());
|
||||||
|
this.setAliases(command.getAliasList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args)
|
||||||
|
{
|
||||||
|
if (!commandLabel.equalsIgnoreCase(command.getName())
|
||||||
|
|| !command.getAliasList().contains(commandLabel))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!command.allowConsole() && sender instanceof ConsoleCommandSender)
|
||||||
|
{
|
||||||
|
sender.sendMessage("This command cannot be executed from the console.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sender.hasPermission(command.getPermission()))
|
||||||
|
{
|
||||||
|
sender.sendMessage(command.getPermissionMessage());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
final CommandResponse response = command.run(sender, args);
|
||||||
|
|
||||||
|
if (response != null && !response.isEmpty())
|
||||||
|
{
|
||||||
|
sender.sendMessage(response.getResponse());
|
||||||
|
Bukkit.getLogger().info(response.getResponse());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args)
|
||||||
|
throws IllegalArgumentException
|
||||||
|
{
|
||||||
|
return command.getTabCompletions(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Plugin getPlugin()
|
||||||
|
{
|
||||||
|
return this.plugin;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Simplex Development Group
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* with the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package app.simplexdev.arcanumocculta.command.base;
|
||||||
|
|
||||||
|
import app.simplexdev.arcanumocculta.ArcanumOcculta;
|
||||||
|
import java.util.Objects;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.reflections.Reflections;
|
||||||
|
|
||||||
|
public class CommandLoader
|
||||||
|
{
|
||||||
|
private final ArcanumOcculta plugin;
|
||||||
|
|
||||||
|
public CommandLoader(final ArcanumOcculta plugin)
|
||||||
|
{
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerCommand(final Commander command)
|
||||||
|
{
|
||||||
|
final CommandDelegate delegate = new CommandDelegate(this.plugin, command);
|
||||||
|
Bukkit.getCommandMap().register("arcaneum", delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(final Class<? extends Commander> reference)
|
||||||
|
{
|
||||||
|
new Reflections(reference.getPackage().getName())
|
||||||
|
.getSubTypesOf(Commander.class)
|
||||||
|
.stream()
|
||||||
|
.map(c ->
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return c.getDeclaredConstructor();
|
||||||
|
}
|
||||||
|
catch (ReflectiveOperationException ex)
|
||||||
|
{
|
||||||
|
Bukkit.getLogger().severe(ex.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.map(c ->
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return c.newInstance();
|
||||||
|
}
|
||||||
|
catch (ReflectiveOperationException ex)
|
||||||
|
{
|
||||||
|
Bukkit.getLogger().severe(ex.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.map(Commander.class::cast)
|
||||||
|
.forEach(this::registerCommand);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Simplex Development Group
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* with the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package app.simplexdev.arcanumocculta.command.base;
|
||||||
|
|
||||||
|
public final class CommandResponse
|
||||||
|
{
|
||||||
|
private final String response;
|
||||||
|
private final boolean isEmpty;
|
||||||
|
|
||||||
|
private CommandResponse(final String response) {
|
||||||
|
if (response == null) {
|
||||||
|
this.isEmpty = true;
|
||||||
|
this.response = "";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.isEmpty = false;
|
||||||
|
this.response = response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CommandResponse() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CommandResponse empty() {
|
||||||
|
return new CommandResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CommandResponse of(final String response) {
|
||||||
|
return new CommandResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResponse() {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return isEmpty;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Simplex Development Group
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* with the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package app.simplexdev.arcanumocculta.command.base;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
public interface Commander
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Runs the command.
|
||||||
|
*
|
||||||
|
* @param sender The sender of the command.
|
||||||
|
* @param args The command arguments.
|
||||||
|
* @return A message which can be sent to both logs and the command sender.
|
||||||
|
* @see CommandResponse
|
||||||
|
*/
|
||||||
|
CommandResponse run(final CommandSender sender, final String[] args);
|
||||||
|
|
||||||
|
default Info getInfoData()
|
||||||
|
{
|
||||||
|
return this.getClass().getDeclaredAnnotation(Info.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
default Completion[] getCompletionData()
|
||||||
|
{
|
||||||
|
return this.getClass().getDeclaredAnnotationsByType(Completion.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
default Permissions getPermissionData()
|
||||||
|
{
|
||||||
|
return this.getClass().getDeclaredAnnotation(Permissions.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getName()
|
||||||
|
{
|
||||||
|
return this.getInfoData().name();
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getDescription()
|
||||||
|
{
|
||||||
|
return this.getInfoData().description();
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getUsage()
|
||||||
|
{
|
||||||
|
return this.getInfoData().usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<String> getAliasList()
|
||||||
|
{
|
||||||
|
return List.of(getAliasArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
default String[] getAliasArray()
|
||||||
|
{
|
||||||
|
return this.getInfoData().aliases();
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getPermission()
|
||||||
|
{
|
||||||
|
return this.getPermissionData().permission();
|
||||||
|
}
|
||||||
|
|
||||||
|
default String getPermissionMessage()
|
||||||
|
{
|
||||||
|
return this.getPermissionData().permissionMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean allowConsole()
|
||||||
|
{
|
||||||
|
return this.getPermissionData().allowConsole();
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<String> getTabCompletions(final String[] args)
|
||||||
|
{
|
||||||
|
final List<Completion> completions = List.of(this.getCompletionData());
|
||||||
|
final List<String> returnable = new ArrayList<>();
|
||||||
|
completions.stream()
|
||||||
|
.filter(completion -> completion.index() == args.length - 1)
|
||||||
|
.map(Completion::args)
|
||||||
|
.flatMap(Stream::of)
|
||||||
|
.filter(arg -> arg.startsWith(args[args.length - 1]))
|
||||||
|
.forEach(returnable::add);
|
||||||
|
return returnable;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Simplex Development Group
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* with the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package app.simplexdev.arcanumocculta.command.base;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Repeatable;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Repeatable(Completions.class)
|
||||||
|
public @interface Completion
|
||||||
|
{
|
||||||
|
int index();
|
||||||
|
|
||||||
|
String[] args();
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Simplex Development Group
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* with the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package app.simplexdev.arcanumocculta.command.base;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
public @interface Completions
|
||||||
|
{
|
||||||
|
Completion[] value();
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Simplex Development Group
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* with the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package app.simplexdev.arcanumocculta.command.base;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
public @interface Info
|
||||||
|
{
|
||||||
|
String name();
|
||||||
|
|
||||||
|
String description() default "No description provided.";
|
||||||
|
|
||||||
|
String usage() default "/<command>";
|
||||||
|
|
||||||
|
String[] aliases() default {};
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Simplex Development Group
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* with the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package app.simplexdev.arcanumocculta.command.base;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
public @interface Permissions
|
||||||
|
{
|
||||||
|
String value();
|
||||||
|
|
||||||
|
String permissionMessage() default "You do not have permission to use this command!";
|
||||||
|
|
||||||
|
boolean allowConsole() default true;
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 Simplex Development Group
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* with the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package app.simplexdev.arcanumocculta.listener;
|
||||||
|
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
public class PlayerListener implements Listener
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user