Compare commits
9 Commits
ed0d15b3d4
...
b68835918f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b68835918f | ||
|
|
d3cd059af1 | ||
|
|
612a0281d6 | ||
|
|
d4f33b8c2e | ||
|
|
9fa43c8c65 | ||
|
|
13a78515c5 | ||
|
|
91e6d3be8e | ||
|
|
06a8aa0f65 | ||
|
|
139c51e9b8 |
|
|
@ -1,5 +1,6 @@
|
||||||
package com.alttd.essentia;
|
package com.alttd.essentia;
|
||||||
|
|
||||||
|
import com.alttd.essentia.api.model.randomteleport.LocationValidator;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
public interface EssentiaAPI {
|
public interface EssentiaAPI {
|
||||||
|
|
@ -19,4 +20,6 @@ public interface EssentiaAPI {
|
||||||
Provider.instance = instance;
|
Provider.instance = instance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addLocationValidator(LocationValidator locationValidator);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.alttd.essentia.api.model.randomteleport;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
|
public interface LocationValidator {
|
||||||
|
|
||||||
|
boolean validate(Location location);
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@ plugins {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":api"))
|
implementation(project(":api"))
|
||||||
compileOnly("com.alttd:Galaxy-API:1.21.1-R0.1-SNAPSHOT")
|
compileOnly("com.alttd.cosmos:cosmos-api:1.21.6-R0.1-SNAPSHOT")
|
||||||
api("org.reflections:reflections:0.10.2")
|
api("org.reflections:reflections:0.10.2")
|
||||||
|
|
||||||
compileOnly("org.projectlombok:lombok:1.18.34")
|
compileOnly("org.projectlombok:lombok:1.18.34")
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,15 @@ package com.alttd.essentia;
|
||||||
|
|
||||||
import com.alttd.essentia.commands.EssentiaCommand;
|
import com.alttd.essentia.commands.EssentiaCommand;
|
||||||
import com.alttd.essentia.configuration.Config;
|
import com.alttd.essentia.configuration.Config;
|
||||||
|
import com.alttd.essentia.api.model.randomteleport.LocationValidator;
|
||||||
|
import com.alttd.essentia.feature.Features;
|
||||||
|
import com.alttd.essentia.model.annotations.Depends;
|
||||||
import com.alttd.essentia.storage.StorageManager;
|
import com.alttd.essentia.storage.StorageManager;
|
||||||
import com.alttd.essentia.storage.StorageProvider;
|
import com.alttd.essentia.storage.StorageProvider;
|
||||||
import com.alttd.essentia.storage.StorageType;
|
import com.alttd.essentia.storage.StorageType;
|
||||||
import com.alttd.essentia.user.EssentiaUserManager;
|
import com.alttd.essentia.user.EssentiaUserManager;
|
||||||
import com.alttd.essentia.api.user.UserManager;
|
import com.alttd.essentia.api.user.UserManager;
|
||||||
|
import com.alttd.essentia.util.Timer;
|
||||||
import io.papermc.paper.command.brigadier.Commands;
|
import io.papermc.paper.command.brigadier.Commands;
|
||||||
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
|
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
|
||||||
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
|
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
|
||||||
|
|
@ -18,6 +22,8 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.reflections.Reflections;
|
import org.reflections.Reflections;
|
||||||
import org.reflections.scanners.Scanners;
|
import org.reflections.scanners.Scanners;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class EssentiaPlugin extends JavaPlugin implements EssentiaAPI {
|
public class EssentiaPlugin extends JavaPlugin implements EssentiaAPI {
|
||||||
|
|
@ -27,10 +33,15 @@ public class EssentiaPlugin extends JavaPlugin implements EssentiaAPI {
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private UserManager userManager;
|
private UserManager userManager;
|
||||||
|
@Getter
|
||||||
|
private List<LocationValidator> locationValidators;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private StorageProvider storageProvider;
|
private StorageProvider storageProvider;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Features features;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
instance = this;
|
instance = this;
|
||||||
|
|
@ -39,11 +50,15 @@ public class EssentiaPlugin extends JavaPlugin implements EssentiaAPI {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
loadConfiguration();
|
new Timer("onEnable", () -> {
|
||||||
loadCommands();
|
new Timer("loadConfiguration", this::loadConfiguration);
|
||||||
loadEventListeners();
|
new Timer("loadFeatures", this::loadFeatures);
|
||||||
loadManagers();
|
new Timer("loadCommands", this::loadCommands);
|
||||||
loadStorageProvider();
|
new Timer("loadEventListeners", this::loadEventListeners);
|
||||||
|
new Timer("loadManagers", this::loadManagers);
|
||||||
|
new Timer("loadStorageProvider", this::loadStorageProvider);
|
||||||
|
new Timer("loadLocationValidators", this::loadLocationValidators);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -57,6 +72,11 @@ public class EssentiaPlugin extends JavaPlugin implements EssentiaAPI {
|
||||||
Config.init();
|
Config.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void loadFeatures() {
|
||||||
|
features = new Features(this);
|
||||||
|
features.registerAll();
|
||||||
|
}
|
||||||
|
|
||||||
void loadCommands() {
|
void loadCommands() {
|
||||||
Reflections reflections = new Reflections("com.alttd.essentia.commands");
|
Reflections reflections = new Reflections("com.alttd.essentia.commands");
|
||||||
Set<Class<?>> subTypes = reflections.get(Scanners.SubTypes.of(EssentiaCommand.class).asClass());
|
Set<Class<?>> subTypes = reflections.get(Scanners.SubTypes.of(EssentiaCommand.class).asClass());
|
||||||
|
|
@ -67,6 +87,13 @@ public class EssentiaPlugin extends JavaPlugin implements EssentiaAPI {
|
||||||
subTypes.forEach(clazz -> {
|
subTypes.forEach(clazz -> {
|
||||||
try {
|
try {
|
||||||
EssentiaCommand essentiaCommand = (EssentiaCommand) clazz.getDeclaredConstructor().newInstance();
|
EssentiaCommand essentiaCommand = (EssentiaCommand) clazz.getDeclaredConstructor().newInstance();
|
||||||
|
final Depends depends = clazz.getAnnotation(Depends.class);
|
||||||
|
if (depends != null) {
|
||||||
|
if (!features.isEnabled(depends.value())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
commands.register(essentiaCommand.command(), essentiaCommand.description(), essentiaCommand.aliases());
|
commands.register(essentiaCommand.command(), essentiaCommand.description(), essentiaCommand.aliases());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
EssentiaPlugin.instance().getLogger().severe("Failed to register command " + clazz.getSimpleName());
|
EssentiaPlugin.instance().getLogger().severe("Failed to register command " + clazz.getSimpleName());
|
||||||
|
|
@ -100,4 +127,26 @@ public class EssentiaPlugin extends JavaPlugin implements EssentiaAPI {
|
||||||
storageProvider.startAutoSaving();
|
storageProvider.startAutoSaving();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void loadLocationValidators() {
|
||||||
|
this.locationValidators = new ArrayList<>();
|
||||||
|
Reflections reflections = new Reflections("com.alttd.essentia.feature.randomteleport.validator");
|
||||||
|
Set<Class<?>> subTypes = reflections.get(Scanners.SubTypes.of(LocationValidator.class).asClass());
|
||||||
|
|
||||||
|
subTypes.forEach(clazz -> {
|
||||||
|
try {
|
||||||
|
LocationValidator locationValidator = (LocationValidator) clazz.getDeclaredConstructor().newInstance();
|
||||||
|
addLocationValidator(locationValidator);
|
||||||
|
} catch (Exception e) {
|
||||||
|
EssentiaPlugin.instance().getLogger().severe("Failed to add locationValidator " + clazz.getSimpleName());
|
||||||
|
EssentiaPlugin.instance().getLogger().severe(e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO -- make this reload proof for API
|
||||||
|
@Override
|
||||||
|
public void addLocationValidator(LocationValidator locationValidator) {
|
||||||
|
locationValidators.add(locationValidator);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.alttd.essentia.commands.admin;
|
||||||
|
|
||||||
|
import com.alttd.essentia.EssentiaPlugin;
|
||||||
|
import com.alttd.essentia.commands.EssentiaCommand;
|
||||||
|
import com.alttd.essentia.request.RandomTeleportRequest;
|
||||||
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
|
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||||
|
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||||
|
import io.papermc.paper.command.brigadier.Commands;
|
||||||
|
import io.papermc.paper.command.brigadier.argument.ArgumentTypes;
|
||||||
|
import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class RandomTeleportCommand implements EssentiaCommand {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String commandName() {
|
||||||
|
return "randomteleport";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull LiteralCommandNode<CommandSourceStack> command() {
|
||||||
|
final LiteralArgumentBuilder<CommandSourceStack> builder =
|
||||||
|
Commands.literal(commandName())
|
||||||
|
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminCommandPermission()))
|
||||||
|
.then(
|
||||||
|
Commands.argument("player", ArgumentTypes.player())
|
||||||
|
.requires(commandSourceStack -> commandSourceStack.getSender().hasPermission(adminOtherCommandPermission()))
|
||||||
|
.executes((source) -> {
|
||||||
|
CommandSourceStack sourceStack = source.getSource();
|
||||||
|
Player target = source.getArgument("player", PlayerSelectorArgumentResolver.class).resolve(sourceStack).getFirst();
|
||||||
|
execute(source.getSource().getSender(), target);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String description() {
|
||||||
|
return "Teleport a player to a random location!";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute(CommandSender sender, Player target) { // TODO - messages
|
||||||
|
TagResolver placeholders = TagResolver.resolver(
|
||||||
|
Placeholder.component("requester", sender.name()),
|
||||||
|
Placeholder.component("target", target.displayName())
|
||||||
|
);
|
||||||
|
|
||||||
|
new RandomTeleportRequest(EssentiaPlugin.instance(), target, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,8 @@ package com.alttd.essentia.configuration;
|
||||||
|
|
||||||
import com.alttd.essentia.EssentiaPlugin;
|
import com.alttd.essentia.EssentiaPlugin;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
@ -34,7 +36,7 @@ public class Config {
|
||||||
config.load(CONFIG_FILE);
|
config.load(CONFIG_FILE);
|
||||||
} catch (IOException ignore) {
|
} catch (IOException ignore) {
|
||||||
} catch (InvalidConfigurationException ex) {
|
} catch (InvalidConfigurationException ex) {
|
||||||
EssentiaPlugin.instance().getLogger().log(Level.SEVERE, "Could not load config.yml, please correct your syntax errors", ex);
|
log(Level.SEVERE, "Could not load config.yml, please correct your syntax errors", ex);
|
||||||
Throwables.throwIfUnchecked(ex);
|
Throwables.throwIfUnchecked(ex);
|
||||||
}
|
}
|
||||||
config.options().header(HEADER);
|
config.options().header(HEADER);
|
||||||
|
|
@ -43,7 +45,7 @@ public class Config {
|
||||||
version = getInt("config-version", 1);
|
version = getInt("config-version", 1);
|
||||||
set("config-version", 1);
|
set("config-version", 1);
|
||||||
|
|
||||||
EssentiaPlugin.instance().getLogger().info("Essentia Configuration loaded!");
|
log(Level.INFO,"Essentia Configuration loaded!");
|
||||||
readConfig(Config.class, null);
|
readConfig(Config.class, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,7 +59,7 @@ public class Config {
|
||||||
} catch (InvocationTargetException ex) {
|
} catch (InvocationTargetException ex) {
|
||||||
Throwables.throwIfUnchecked(ex);
|
Throwables.throwIfUnchecked(ex);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
EssentiaPlugin.instance().getLogger().log(Level.SEVERE, "Error invoking " + method, ex);
|
log(Level.SEVERE, "Error invoking " + method, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -69,7 +71,7 @@ public class Config {
|
||||||
try {
|
try {
|
||||||
config.save(CONFIG_FILE);
|
config.save(CONFIG_FILE);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
EssentiaPlugin.instance().getLogger().log(Level.SEVERE, "Could not save " + CONFIG_FILE, ex);
|
log(Level.SEVERE, "Could not save " + CONFIG_FILE, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,6 +109,10 @@ public class Config {
|
||||||
EssentiaPlugin.instance().getLogger().log(level, s);
|
EssentiaPlugin.instance().getLogger().log(level, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static void log(Level level, String s, Throwable thrown) {
|
||||||
|
EssentiaPlugin.instance().getLogger().log(level, s, thrown);
|
||||||
|
}
|
||||||
|
|
||||||
public static int TELEPORT_REQUEST_TIMEOUT = 30;
|
public static int TELEPORT_REQUEST_TIMEOUT = 30;
|
||||||
public static boolean TELEPORT_REQUEST_TIMEOUT_MESSAGES = true;
|
public static boolean TELEPORT_REQUEST_TIMEOUT_MESSAGES = true;
|
||||||
public static boolean BACK_ON_DEATH = false;
|
public static boolean BACK_ON_DEATH = false;
|
||||||
|
|
@ -270,4 +276,10 @@ public class Config {
|
||||||
MYSQL_PASSWORD = getString("storage.mysql.password", MYSQL_PASSWORD);
|
MYSQL_PASSWORD = getString("storage.mysql.password", MYSQL_PASSWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Object2BooleanMap<String> enabledFeatures = new Object2BooleanOpenHashMap<>();
|
||||||
|
private static void features() {
|
||||||
|
enabledFeatures.clear();
|
||||||
|
enabledFeatures.defaultReturnValue(true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.alttd.essentia.feature;
|
||||||
|
|
||||||
|
public interface EssentiaFeature {
|
||||||
|
|
||||||
|
String featureName();
|
||||||
|
|
||||||
|
void register();
|
||||||
|
|
||||||
|
boolean isEnabled();
|
||||||
|
|
||||||
|
default void start() {}
|
||||||
|
|
||||||
|
default void stop() {}
|
||||||
|
|
||||||
|
default void reload() {
|
||||||
|
stop();
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.alttd.essentia.feature;
|
||||||
|
|
||||||
|
import com.alttd.essentia.EssentiaPlugin;
|
||||||
|
import com.alttd.essentia.configuration.Config;
|
||||||
|
import org.reflections.Reflections;
|
||||||
|
import org.reflections.scanners.Scanners;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
public class Features {
|
||||||
|
|
||||||
|
private final EssentiaPlugin plugin;
|
||||||
|
private final Map<String, EssentiaFeature> features;
|
||||||
|
|
||||||
|
public Features(EssentiaPlugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
features = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabled(String featureName) {
|
||||||
|
if (features.containsKey(featureName)) {
|
||||||
|
return features.get(featureName).isEnabled();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerAll() {
|
||||||
|
Reflections reflections = new Reflections("com.alttd.essentia.feature");
|
||||||
|
Set<Class<?>> subTypes = reflections.get(Scanners.SubTypes.of(EssentiaFeature.class).asClass());
|
||||||
|
|
||||||
|
subTypes.forEach(clazz -> {
|
||||||
|
try {
|
||||||
|
EssentiaFeature essentiaFeature = (EssentiaFeature) clazz.getDeclaredConstructor().newInstance();
|
||||||
|
if (!Config.enabledFeatures.getBoolean(essentiaFeature.featureName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
essentiaFeature.register();
|
||||||
|
essentiaFeature.reload();
|
||||||
|
|
||||||
|
features.putIfAbsent(essentiaFeature.featureName(), essentiaFeature);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log(Level.SEVERE,"Failed to register feature " + clazz.getSimpleName(), e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void log(Level level, String s) {
|
||||||
|
plugin.getLogger().log(level, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void log(Level level, String s, Throwable thrown) {
|
||||||
|
plugin.getLogger().log(level, s, thrown);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.alttd.essentia.feature.cuff;
|
||||||
|
|
||||||
|
import com.alttd.essentia.EssentiaPlugin;
|
||||||
|
import com.alttd.essentia.feature.EssentiaFeature;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
|
||||||
|
public class CuffFeature implements EssentiaFeature {
|
||||||
|
|
||||||
|
private final EssentiaPlugin plugin;
|
||||||
|
|
||||||
|
private boolean enabled = false;
|
||||||
|
|
||||||
|
public CuffFeature() {
|
||||||
|
this.plugin = EssentiaPlugin.instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String featureName() {
|
||||||
|
return "cuff";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register() {
|
||||||
|
final PluginManager pluginManager = plugin.getServer().getPluginManager();
|
||||||
|
pluginManager.registerEvents(new CuffListener(), plugin);
|
||||||
|
|
||||||
|
this.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.alttd.essentia.listeners;
|
package com.alttd.essentia.feature.cuff;
|
||||||
|
|
||||||
import com.alttd.essentia.EssentiaPlugin;
|
import com.alttd.essentia.EssentiaPlugin;
|
||||||
import com.alttd.essentia.api.user.User;
|
import com.alttd.essentia.api.user.User;
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.alttd.essentia.feature.flight;
|
||||||
|
|
||||||
|
import com.alttd.essentia.EssentiaPlugin;
|
||||||
|
import com.alttd.essentia.feature.EssentiaFeature;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
|
||||||
|
public class FlightFeature implements EssentiaFeature {
|
||||||
|
|
||||||
|
private final EssentiaPlugin plugin;
|
||||||
|
|
||||||
|
private boolean enabled = false;
|
||||||
|
|
||||||
|
public FlightFeature() {
|
||||||
|
this.plugin = EssentiaPlugin.instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String featureName() {
|
||||||
|
return "flight";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register() {
|
||||||
|
final PluginManager pluginManager = plugin.getServer().getPluginManager();
|
||||||
|
pluginManager.registerEvents(new FlightListener(), plugin);
|
||||||
|
|
||||||
|
this.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package com.alttd.essentia.listeners;
|
package com.alttd.essentia.feature.flight;
|
||||||
|
|
||||||
import com.alttd.essentia.EssentiaPlugin;
|
import com.alttd.essentia.EssentiaPlugin;
|
||||||
import com.alttd.essentia.api.model.UserSettings;
|
import com.alttd.essentia.api.model.UserSettings;
|
||||||
|
|
@ -8,7 +8,7 @@ import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||||
|
// TODO -- set flight and flying when player logs in!
|
||||||
public class FlightListener implements Listener {
|
public class FlightListener implements Listener {
|
||||||
|
|
||||||
private final EssentiaPlugin plugin;
|
private final EssentiaPlugin plugin;
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.alttd.essentia.feature.godmode;
|
||||||
|
|
||||||
|
import com.alttd.essentia.EssentiaPlugin;
|
||||||
|
import com.alttd.essentia.api.model.UserSettings;
|
||||||
|
import com.alttd.essentia.api.user.User;
|
||||||
|
import com.alttd.essentia.api.user.UserManager;
|
||||||
|
import com.alttd.essentia.feature.EssentiaFeature;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
|
||||||
|
public class GodModeFeature implements EssentiaFeature {
|
||||||
|
|
||||||
|
private final EssentiaPlugin plugin;
|
||||||
|
|
||||||
|
private boolean enabled = false;
|
||||||
|
|
||||||
|
public GodModeFeature() {
|
||||||
|
this.plugin = EssentiaPlugin.instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String featureName() {
|
||||||
|
return "GodMode";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register() {
|
||||||
|
final PluginManager pluginManager = plugin.getServer().getPluginManager();
|
||||||
|
pluginManager.registerEvents(new GodModeListener(this), plugin);
|
||||||
|
|
||||||
|
this.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isGodModeEnabled(Player player) {
|
||||||
|
UserManager userManager = plugin.userManager();
|
||||||
|
User user = userManager.getUser(player);
|
||||||
|
if (user == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
UserSettings userSettings = user.getUserSettings();
|
||||||
|
return userSettings.godMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
package com.alttd.essentia.feature.godmode;
|
||||||
|
|
||||||
|
import com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.*;
|
||||||
|
|
||||||
|
public class GodModeListener implements Listener {
|
||||||
|
|
||||||
|
private GodModeFeature godModeFeature;
|
||||||
|
public GodModeListener(GodModeFeature godModeFeature) {
|
||||||
|
this.godModeFeature = godModeFeature;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onFoodLevelChange(FoodLevelChangeEvent event) {
|
||||||
|
if (!(event.getEntity() instanceof Player player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!isGodModeEnabled(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPhantomPreSpawn(PhantomPreSpawnEvent event) {
|
||||||
|
if (!(event.getSpawningEntity() instanceof Player player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!isGodModeEnabled(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
event.setShouldAbortSpawn(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onEntityTargetLivingEntity(EntityTargetLivingEntityEvent event) {
|
||||||
|
if (!(event.getEntity() instanceof Player player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!isGodModeEnabled(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) {
|
||||||
|
if (!(event.getEntity() instanceof Player player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!isGodModeEnabled(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPotionSplashEvent(PotionSplashEvent event) {
|
||||||
|
for (LivingEntity entity : event.getAffectedEntities()) {
|
||||||
|
if (!(entity instanceof Player player))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!isGodModeEnabled(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
event.setIntensity(player, 0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onEntityCombustByEntityEvent(EntityCombustByEntityEvent event) {
|
||||||
|
if (!(event.getEntity() instanceof Player player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!isGodModeEnabled(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
|
public void onEntityCombust(final EntityCombustEvent event) {
|
||||||
|
if (!(event.getEntity() instanceof Player player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!isGodModeEnabled(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||||
|
public void onEntityDamage(final EntityDamageEvent event) {
|
||||||
|
if (!(event.getEntity() instanceof Player player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!isGodModeEnabled(player))
|
||||||
|
return;
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isGodModeEnabled(Player player) {
|
||||||
|
return godModeFeature.isGodModeEnabled(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.alttd.essentia.feature.randomteleport;
|
||||||
|
|
||||||
|
import com.alttd.essentia.api.model.randomteleport.LocationValidator;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
// TODO - load biomes from config
|
||||||
|
public class BiomeValidator implements LocationValidator {
|
||||||
|
|
||||||
|
private final boolean whitelist;
|
||||||
|
private final Set<Biome> biomes;
|
||||||
|
|
||||||
|
public BiomeValidator() {
|
||||||
|
this.biomes = new HashSet<>();
|
||||||
|
this.whitelist = false;
|
||||||
|
this.biomes.add(Biome.OCEAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean validate(Location location) {
|
||||||
|
Block block = location.getBlock();
|
||||||
|
return biomes.contains(block.getBiome()) == whitelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package com.alttd.essentia.feature.randomteleport;
|
||||||
|
|
||||||
|
import com.alttd.essentia.api.model.randomteleport.LocationValidator;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
// TODO - load block list from config
|
||||||
|
public class BlockValidator implements LocationValidator {
|
||||||
|
|
||||||
|
private final boolean whitelist;
|
||||||
|
private final Set<Material> materials;
|
||||||
|
|
||||||
|
public BlockValidator() {
|
||||||
|
materials = new HashSet<>();
|
||||||
|
this.whitelist = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean validate(Location location) {
|
||||||
|
Block block = location.getBlock();
|
||||||
|
return materials.contains(block.getType()) == whitelist;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.alttd.essentia.feature.randomteleport;
|
||||||
|
|
||||||
|
import com.alttd.essentia.api.model.randomteleport.LocationValidator;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
|
// TODO - claim hooks for GP. LandClaims should hook into the plugin and add the validator.
|
||||||
|
public class ProtectionValidator implements LocationValidator {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean validate(Location location) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.alttd.essentia.feature.randomteleport;
|
||||||
|
|
||||||
|
import com.alttd.essentia.api.model.randomteleport.LocationValidator;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
|
public class WorldBorderValidator implements LocationValidator {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean validate(Location location) {
|
||||||
|
return location.getWorld().getWorldBorder().isInside(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
package com.alttd.essentia.listeners;
|
|
||||||
|
|
||||||
import com.alttd.essentia.EssentiaPlugin;
|
|
||||||
import com.alttd.essentia.api.model.UserSettings;
|
|
||||||
import com.alttd.essentia.api.user.User;
|
|
||||||
import com.alttd.essentia.api.user.UserManager;
|
|
||||||
import com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
|
|
||||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
|
||||||
|
|
||||||
public class GodModeListener implements Listener {
|
|
||||||
|
|
||||||
private final EssentiaPlugin plugin;
|
|
||||||
|
|
||||||
public GodModeListener() {
|
|
||||||
this.plugin = EssentiaPlugin.instance();
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onFoodLevelChange(FoodLevelChangeEvent event) {
|
|
||||||
if (!(event.getEntity() instanceof Player player))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!hasGodMode(player))
|
|
||||||
return;
|
|
||||||
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPhantomPreSpawn(PhantomPreSpawnEvent event) {
|
|
||||||
if (!(event.getSpawningEntity() instanceof Player player))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!hasGodMode(player))
|
|
||||||
return;
|
|
||||||
|
|
||||||
event.setCancelled(true);
|
|
||||||
event.setShouldAbortSpawn(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onEntityTargetLivingEntity(EntityTargetLivingEntityEvent event) {
|
|
||||||
if (!(event.getEntity() instanceof Player player))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!hasGodMode(player))
|
|
||||||
return;
|
|
||||||
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasGodMode(Player player) {
|
|
||||||
UserManager userManager = plugin.userManager();
|
|
||||||
User user = userManager.getUser(player);
|
|
||||||
if (user == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
UserSettings userSettings = user.getUserSettings();
|
|
||||||
return userSettings.godMode();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package com.alttd.essentia.model.annotations;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface Depends {
|
||||||
|
String value();
|
||||||
|
}
|
||||||
|
|
@ -12,10 +12,10 @@ import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public abstract class EssentiaRequest implements Request {
|
public abstract class EssentiaRequest implements Request {
|
||||||
|
|
||||||
private final EssentiaPlugin plugin;
|
protected final EssentiaPlugin plugin;
|
||||||
@Getter private final Player requester;
|
@Getter private final Player requester;
|
||||||
@Getter private final Player target;
|
@Getter private final Player target;
|
||||||
private final RequestTimeout timeoutTask;
|
@Getter private final RequestTimeout timeoutTask;
|
||||||
|
|
||||||
TagResolver placeholders;
|
TagResolver placeholders;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,168 @@
|
||||||
|
package com.alttd.essentia.request;
|
||||||
|
|
||||||
|
import com.alttd.essentia.EssentiaPlugin;
|
||||||
|
import com.alttd.essentia.api.model.randomteleport.LocationValidator;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.common.collect.MultimapBuilder;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class RandomTeleportRequest extends EssentiaRequest {
|
||||||
|
|
||||||
|
private static final List<int[]> CHUNK_POS = new ArrayList<>();
|
||||||
|
private final Multimap<Integer, Integer> checked = MultimapBuilder.hashKeys().hashSetValues().build();
|
||||||
|
|
||||||
|
private final Random random;
|
||||||
|
private final Location center; // todo - config
|
||||||
|
private final int minRadius; // todo - config
|
||||||
|
private final int maxRadius; // todo - config
|
||||||
|
private final int maxTries = 100; // TODO - config
|
||||||
|
|
||||||
|
private int checks;
|
||||||
|
CompletableFuture<Location> future;
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (int x = 0; x < 16; x++) {
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
CHUNK_POS.add(new int[]{x, z});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RandomTeleportRequest(EssentiaPlugin plugin, Player requester, Player target) {
|
||||||
|
super(plugin, requester, target);
|
||||||
|
this.random = new Random();
|
||||||
|
this.center = Bukkit.getWorlds().getFirst().getSpawnLocation(); // todo - config and sanity check for worlds
|
||||||
|
this.minRadius = 50;
|
||||||
|
this.maxRadius = 20000;
|
||||||
|
|
||||||
|
this.timeoutTask().cancel();
|
||||||
|
this.teleport();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start searching for a safe random location within the world
|
||||||
|
*
|
||||||
|
* @return A CompletableFuture for when the searching is finished.
|
||||||
|
*/
|
||||||
|
public CompletableFuture<Location> startSearch() {
|
||||||
|
future = new CompletableFuture<>();
|
||||||
|
target().sendRichMessage("Running search task");
|
||||||
|
plugin.getServer().getScheduler().runTask(plugin, () -> searchRandomLocation(future));
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
|
||||||
|
// needs to be a task
|
||||||
|
private void searchRandomLocation(CompletableFuture<Location> future) {
|
||||||
|
if (future.isCancelled() || future.isDone() || future.isCompletedExceptionally()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Location randomLoc = center.clone();
|
||||||
|
int minChunk = minRadius >> 4;
|
||||||
|
int maxChunk = maxRadius >> 4;
|
||||||
|
int randChunkX;
|
||||||
|
int randChunkZ;
|
||||||
|
|
||||||
|
do {
|
||||||
|
checks++;
|
||||||
|
if (checks >= maxTries) {
|
||||||
|
future.completeExceptionally(new Exception("Could not find random location within %s tries".formatted(maxTries + "")));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
randChunkX = (random.nextBoolean() ? 1 : -1) * random.nextInt(maxChunk + 1);
|
||||||
|
randChunkZ = (random.nextBoolean() ? 1 : -1) * random.nextInt(maxChunk + 1);
|
||||||
|
target().sendRichMessage("randChunkX: " + randChunkX + ", randChunkZ: " + randChunkZ);
|
||||||
|
} while (!checked.put(randChunkX, randChunkZ)
|
||||||
|
|| !inRadius(Math.abs(randChunkX), Math.abs(randChunkZ), minChunk, maxChunk)
|
||||||
|
/*|| randomLoc.getWorld().isChunkGenerated(randChunkX, randChunkZ)*/);
|
||||||
|
|
||||||
|
|
||||||
|
randomLoc.setX(((center.getBlockX() >> 4) + randChunkX) * 16);
|
||||||
|
randomLoc.setZ(((center.getBlockZ() >> 4) + randChunkZ) * 16);
|
||||||
|
randomLoc.getWorld().getChunkAtAsync(randomLoc).thenApply(chunk -> {
|
||||||
|
if (chunk == null) {
|
||||||
|
searchRandomLocation(future);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
chunk.addPluginChunkTicket(plugin);
|
||||||
|
try {
|
||||||
|
int indexOffset = random.nextInt(CHUNK_POS.size());
|
||||||
|
Location foundLoc = null;
|
||||||
|
for (int i = 0; i < CHUNK_POS.size(); i++) {
|
||||||
|
int index = (i + indexOffset) % CHUNK_POS.size();
|
||||||
|
boolean validated = true;
|
||||||
|
Location loc = randomLoc.clone().add(CHUNK_POS.get(index)[0], 0, CHUNK_POS.get(index)[1]);
|
||||||
|
|
||||||
|
if (!inRadius(loc)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (LocationValidator validator : plugin.locationValidators()) {
|
||||||
|
if (!validator.validate(loc)) {
|
||||||
|
validated = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (validated) {
|
||||||
|
foundLoc = loc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundLoc != null) {
|
||||||
|
// all checks are for the top block, put we want a location above that so add 1 to y
|
||||||
|
future.complete(foundLoc.add(0, 1, 0));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
plugin.getServer().getScheduler().runTaskLater(plugin, () -> searchRandomLocation(future), 1);
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
chunk.removePluginChunkTicket(plugin);
|
||||||
|
}
|
||||||
|
}).exceptionally(future::completeExceptionally);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean inRadius(Location location) {
|
||||||
|
int diffX = Math.abs(location.getBlockX() - center.getBlockX());
|
||||||
|
int diffZ = Math.abs(location.getBlockZ() - center.getBlockZ());
|
||||||
|
return inRadius(diffX, diffZ, minRadius, maxRadius);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean inRadius(int diffX, int diffZ, int minRadius, int maxRadius) {
|
||||||
|
return diffX >= minRadius && diffX <= maxRadius && diffZ <= maxRadius
|
||||||
|
|| diffZ >= minRadius && diffZ <= maxRadius && diffX <= maxRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void teleport() {
|
||||||
|
startSearch().thenApply(randomLocation -> {
|
||||||
|
randomLocation.setX(randomLocation.getBlockX() + 0.5);
|
||||||
|
randomLocation.setY(randomLocation.getY() + 0.5);
|
||||||
|
randomLocation.setZ(randomLocation.getBlockZ() + 0.5);
|
||||||
|
target().teleportAsync(randomLocation)
|
||||||
|
.whenComplete((success, exception) -> {
|
||||||
|
target().sendMessage("You have been teleported to a random location."); // todo -- config
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if (!target().isOnline() || !requester().isOnline()) {
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
try {
|
||||||
|
timeoutTask().cancel();
|
||||||
|
} catch (IllegalStateException ignore) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
17
plugin/src/main/java/com/alttd/essentia/util/Timer.java
Normal file
17
plugin/src/main/java/com/alttd/essentia/util/Timer.java
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.alttd.essentia.util;
|
||||||
|
|
||||||
|
import com.alttd.essentia.EssentiaPlugin;
|
||||||
|
|
||||||
|
public class Timer {
|
||||||
|
|
||||||
|
public Timer(String id, Runnable runnable) {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
runnable.run();
|
||||||
|
|
||||||
|
long duration = System.currentTimeMillis() - startTime;
|
||||||
|
|
||||||
|
EssentiaPlugin.instance().getLogger().info("Loading " + id + " took " + duration + "ms");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ name: Essentia
|
||||||
version: ${version}
|
version: ${version}
|
||||||
main: com.alttd.essentia.EssentiaPlugin
|
main: com.alttd.essentia.EssentiaPlugin
|
||||||
description: Altitude essentials ;)
|
description: Altitude essentials ;)
|
||||||
|
load: POSTWORLD
|
||||||
authors:
|
authors:
|
||||||
- destro174
|
- destro174
|
||||||
api-version: "1.21"
|
api-version: "1.21"
|
||||||
Loading…
Reference in New Issue
Block a user