Compare commits

...

49 Commits

Author SHA1 Message Date
092d33beb3 prototype for grief detection 2025-03-29 22:03:12 +01:00
71d5d8303d added lightning fire control 2025-03-15 23:37:24 +01:00
49eeb646ea using common interface instead of individual methods in displayname appliance 2025-03-15 21:54:18 +01:00
ceca038b27 code reformat 2025-03-15 21:41:07 +01:00
76ceb9ef79 removed public directive where possible to reduce number of global accessible classes 2025-03-15 21:38:55 +01:00
219879974c categorized appliances in groups 2025-03-15 21:20:57 +01:00
bd630ebb7a fixed tabcomplete on mute command 2025-02-01 23:01:48 +01:00
c56f318f1c fixed wrong formatting on playtime 2025-02-01 23:01:28 +01:00
4d98d7aa75 removed restart kick message to trigger limbo when used 2024-12-27 11:01:18 +01:00
619190d0ae changed acInform teleport action to grim spectate 2024-12-27 11:00:55 +01:00
06641c5d84 added chatmute 2024-12-27 10:59:56 +01:00
2a52177043 added support for sentences in acinform reports 2024-12-26 20:50:01 +01:00
fc067a2ae0 moved late integrity check to login flow 2024-12-26 20:49:24 +01:00
116a9c11a2 updated ac inform design 2024-12-26 01:56:40 +01:00
3f29ceb08f fixed not respawning at spawnpoint on player death 2024-12-25 23:34:23 +01:00
a33ee357e8 fixed acinform not working with floating point numbers 2024-12-25 23:06:15 +01:00
e36256d5be async whitelist check 2024-12-25 21:09:42 +01:00
0e3a54a1b9 made repository calls async 2024-12-25 16:12:07 +01:00
2e67b41b44 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	src/main/java/eu/mhsl/craftattack/spawn/appliances/spawnpoint/Spawnpoint.java
2024-12-25 00:37:31 +01:00
e4ac8f7a63 renamed spawnpoint key name 2024-12-25 00:37:12 +01:00
e89e9d2181 renamed spawnpoint key name 2024-12-25 00:35:09 +01:00
8faf0efd60 added spawnpoint 2024-12-25 00:32:54 +01:00
2f1aeb71ee disabled infobars join restore 2024-12-25 00:13:54 +01:00
6475a7b825 updated texts and coordinates 2024-12-24 11:23:19 +01:00
193d8d778f Merge remote-tracking branch 'origin/master' 2024-12-20 21:52:25 +01:00
38da5b1d34 updated coordinates 2024-12-20 21:52:22 +01:00
04e3ddb09f changed custom advancements datapack name 2024-12-20 21:49:04 +01:00
47db27a86e removed bedrock block from WorldMuseum 2024-12-20 19:55:07 +01:00
f13534da3f more robust error handling on Whitelist 2024-12-20 19:54:38 +01:00
e45698c88a fix swapped command feedback 2024-12-20 18:46:20 +01:00
9197840873 removed unwanted HotbarRefill message 2024-12-20 13:34:32 +01:00
63d8335b3a reformatted code 2024-12-17 13:58:41 +01:00
184617e9c3 added EventRepository 2024-12-16 00:30:38 +01:00
696c4bc260 added bedrock displayname prefix 2024-12-09 22:04:30 +01:00
9004609c1b better synchronous call warning 2024-12-08 22:36:11 +01:00
ddedcea8ea added FeedbackRepository 2024-12-08 22:27:54 +01:00
318a30fe54 Merge branch 'refs/heads/master' into develop-apiUtil
# Conflicts:
#	src/main/java/eu/mhsl/craftattack/spawn/appliances/report/Report.java
2024-12-08 13:10:27 +01:00
4808d22f6a Merge remote-tracking branch 'origin/develop-apiUtil' into develop-apiUtil
# Conflicts:
#	src/main/java/eu/mhsl/craftattack/spawn/api/client/repositories/ReportRepository.java
#	src/main/java/eu/mhsl/craftattack/spawn/appliances/report/Report.java
2024-12-05 23:10:05 +01:00
6b2a323a9c implemented report repository 2024-12-05 23:02:15 +01:00
694ca0efba implemented reports request in Report.java 2024-12-05 22:16:15 +01:00
0276763a8d started implementing report repository 2024-12-05 18:58:55 +01:00
8811328571 implemented working WhitelistRepository 2024-12-05 12:46:51 +01:00
b3c43f1763 WIP: repositoryLoader and infrastructure 2024-12-04 23:34:12 +01:00
86677c942f implemented repository design pattern 2024-12-04 22:11:28 +01:00
31581fc643 added api util 2024-12-04 09:23:20 +01:00
a412f5c24c Merge remote-tracking branch 'refs/remotes/origin/master' into develop-feedback 2024-12-03 20:38:06 +01:00
eae979ee65 added feedback 2024-12-03 20:37:14 +01:00
28b9b84e07 changed afk timings map and time limit 2024-12-01 21:40:52 +01:00
a5cdb93f1b added /reports command 2024-12-01 18:03:33 +01:00
187 changed files with 2322 additions and 1396 deletions

View File

@ -1,6 +1,7 @@
package eu.mhsl.craftattack.spawn; package eu.mhsl.craftattack.spawn;
import eu.mhsl.craftattack.spawn.api.HttpServer; import eu.mhsl.craftattack.spawn.api.client.RepositoryLoader;
import eu.mhsl.craftattack.spawn.api.server.HttpServer;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.config.Configuration; import eu.mhsl.craftattack.spawn.config.Configuration;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -19,15 +20,16 @@ public final class Main extends JavaPlugin {
private static Logger logger; private static Logger logger;
private List<Appliance> appliances; private List<Appliance> appliances;
private RepositoryLoader repositoryLoader;
@Override @Override
public void onEnable() { public void onEnable() {
instance = this; instance = this;
logger = instance().getLogger(); logger = instance().getLogger();
saveDefaultConfig(); this.saveDefaultConfig();
try { try {
this.wrappedEnable(); this.wrappedEnable();
} catch (Exception e) { } catch(Exception e) {
Main.logger().log(Level.SEVERE, "Error while initializing Spawn plugin, shutting down!", e); Main.logger().log(Level.SEVERE, "Error while initializing Spawn plugin, shutting down!", e);
Bukkit.shutdown(); Bukkit.shutdown();
} }
@ -37,7 +39,11 @@ public final class Main extends JavaPlugin {
Configuration.readConfig(); Configuration.readConfig();
List<String> disabledAppliances = Configuration.pluginConfig.getStringList("disabledAppliances"); List<String> disabledAppliances = Configuration.pluginConfig.getStringList("disabledAppliances");
Main.logger.info("Loading appliances..."); Main.logger().info("Loading Repositories...");
this.repositoryLoader = new RepositoryLoader();
Main.logger().info(String.format("Loaded %d repositories!", this.repositoryLoader.getRepositories().size()));
Main.logger().info("Loading appliances...");
Reflections reflections = new Reflections(this.getClass().getPackageName()); Reflections reflections = new Reflections(this.getClass().getPackageName());
Set<Class<? extends Appliance>> applianceClasses = reflections.getSubTypesOf(Appliance.class); Set<Class<? extends Appliance>> applianceClasses = reflections.getSubTypesOf(Appliance.class);
@ -46,31 +52,31 @@ public final class Main extends JavaPlugin {
.map(applianceClass -> { .map(applianceClass -> {
try { try {
return (Appliance) applianceClass.getDeclaredConstructor().newInstance(); return (Appliance) applianceClass.getDeclaredConstructor().newInstance();
} catch (Exception e) { } catch(Exception e) {
throw new RuntimeException(String.format("Failed to create instance of '%s'", applianceClass.getName()), e); throw new RuntimeException(String.format("Failed to create instance of '%s'", applianceClass.getName()), e);
} }
}) })
.toList(); .toList();
Main.logger().info(String.format("Loaded %d appliances!", appliances.size())); Main.logger().info(String.format("Loaded %d appliances!", this.appliances.size()));
Main.logger().info("Initializing appliances..."); Main.logger().info("Initializing appliances...");
this.appliances.forEach(appliance -> { this.appliances.forEach(appliance -> {
appliance.onEnable(); appliance.onEnable();
appliance.initialize(this); appliance.initialize(this);
}); });
Main.logger().info(String.format("Initialized %d appliances!", appliances.size())); Main.logger().info(String.format("Initialized %d appliances!", this.appliances.size()));
Main.logger().info("Starting HTTP API..."); Main.logger().info("Starting HTTP API...");
new HttpServer(); new HttpServer();
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); this.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
Main.logger().info("Startup complete!"); Main.logger().info("Startup complete!");
} }
@Override @Override
public void onDisable() { public void onDisable() {
Main.logger().info("Disabling appliances..."); Main.logger().info("Disabling appliances...");
appliances.forEach(appliance -> { this.appliances.forEach(appliance -> {
Main.logger().info("Disabling " + appliance.getClass().getSimpleName()); Main.logger().info("Disabling " + appliance.getClass().getSimpleName());
appliance.onDisable(); appliance.onDisable();
appliance.destruct(this); appliance.destruct(this);
@ -78,7 +84,7 @@ public final class Main extends JavaPlugin {
HandlerList.unregisterAll(this); HandlerList.unregisterAll(this);
Bukkit.getScheduler().cancelTasks(this); Bukkit.getScheduler().cancelTasks(this);
Main.logger().info("Disabled " + appliances.size() + " appliances!"); Main.logger().info("Disabled " + this.appliances.size() + " appliances!");
} }
public <T extends Appliance> T getAppliance(Class<T> clazz) { public <T extends Appliance> T getAppliance(Class<T> clazz) {
@ -95,7 +101,11 @@ public final class Main extends JavaPlugin {
} }
public List<Appliance> getAppliances() { public List<Appliance> getAppliances() {
return appliances; return this.appliances;
}
public RepositoryLoader getRepositoryLoader() {
return this.repositoryLoader;
} }
public static Main instance() { public static Main instance() {

View File

@ -0,0 +1,91 @@
package eu.mhsl.craftattack.spawn.api.client;
import eu.mhsl.craftattack.spawn.Main;
import org.apache.http.client.utils.URIBuilder;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.function.Consumer;
@RepositoryLoader.IgnoreRepository
public abstract class HttpRepository extends Repository {
private final Consumer<URIBuilder> baseUriBuilder;
public HttpRepository(URI basePath) {
this(basePath, null);
}
public HttpRepository(URI basePath, @Nullable Consumer<URIBuilder> baseUriBuilder) {
super(basePath);
this.baseUriBuilder = baseUriBuilder == null
? uriBuilder -> {
}
: baseUriBuilder;
}
protected <TInput, TOutput> ReqResp<TOutput> post(String command, TInput data, Class<TOutput> outputType) {
return this.post(command, parameters -> {
}, data, outputType);
}
protected <TInput, TOutput> ReqResp<TOutput> post(String command, Consumer<URIBuilder> parameters, TInput data, Class<TOutput> outputType) {
HttpRequest request = this.getRequestBuilder(this.getUri(command, parameters))
.POST(HttpRequest.BodyPublishers.ofString(this.gson.toJson(data)))
.build();
return this.execute(request, outputType);
}
protected <TOutput> ReqResp<TOutput> get(String command, Class<TOutput> outputType) {
return this.get(command, parameters -> {
}, outputType);
}
protected <TOutput> ReqResp<TOutput> get(String command, Consumer<URIBuilder> parameters, Class<TOutput> outputType) {
HttpRequest request = this.getRequestBuilder(this.getUri(command, parameters))
.GET()
.build();
return this.execute(request, outputType);
}
private URI getUri(String command, Consumer<URIBuilder> parameters) {
try {
URIBuilder builder = new URIBuilder(this.basePath + "/" + command);
this.baseUriBuilder.accept(builder);
parameters.accept(builder);
return builder.build();
} catch(URISyntaxException e) {
throw new RuntimeException(e);
}
}
private HttpRequest.Builder getRequestBuilder(URI endpoint) {
return HttpRequest.newBuilder()
.uri(endpoint)
.header("User-Agent", Main.instance().getServer().getBukkitVersion())
.header("Content-Type", "application/json");
}
private <TResponse> ReqResp<TResponse> execute(HttpRequest request, Class<TResponse> clazz) {
ReqResp<String> rawResponse = this.sendHttp(request);
return new ReqResp<>(rawResponse.status(), this.gson.fromJson(rawResponse.data(), clazz));
}
private ReqResp<String> sendHttp(HttpRequest request) {
try(HttpClient client = HttpClient.newHttpClient()) {
this.validateThread(request.uri().getPath());
HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
return new ReqResp<>(httpResponse.statusCode(), httpResponse.body());
} catch(IOException | InterruptedException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,27 @@
package eu.mhsl.craftattack.spawn.api.client;
import com.google.gson.Gson;
import eu.mhsl.craftattack.spawn.Main;
import org.bukkit.Bukkit;
import java.net.URI;
public abstract class Repository {
protected URI basePath;
protected Gson gson;
public Repository(URI basePath) {
this.basePath = basePath;
this.gson = new Gson();
}
protected void validateThread(String commandName) {
if(!Bukkit.isPrimaryThread()) return;
Main.logger().warning(String.format(
"Repository '%s' was called synchronously with command '%s'!",
this.getClass().getSimpleName(),
commandName
));
}
}

View File

@ -0,0 +1,48 @@
package eu.mhsl.craftattack.spawn.api.client;
import org.apache.commons.lang3.NotImplementedException;
import org.reflections.Reflections;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Set;
public class RepositoryLoader {
private final List<Repository> repositories;
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreRepository {
}
public RepositoryLoader() {
Reflections reflections = new Reflections(this.getClass().getPackageName());
Set<Class<? extends Repository>> repositories = reflections.getSubTypesOf(Repository.class);
this.repositories = repositories.stream()
.filter(repository -> !repository.isAnnotationPresent(IgnoreRepository.class))
.map(repository -> {
try {
return (Repository) repository.getDeclaredConstructor().newInstance();
} catch(InstantiationException | IllegalAccessException | InvocationTargetException |
NoSuchMethodException e) {
throw new RuntimeException(e);
}
})
.toList();
}
public <T> T getRepository(Class<T> clazz) {
//noinspection unchecked
return this.repositories.stream()
.filter(clazz::isInstance)
.map(repository -> (T) repository)
.findFirst()
.orElseThrow(() -> new NotImplementedException(String.format("Repository '%s' not found!", clazz.getSimpleName())));
}
public List<Repository> getRepositories() {
return this.repositories;
}
}

View File

@ -0,0 +1,4 @@
package eu.mhsl.craftattack.spawn.api.client;
public record ReqResp<TData>(int status, TData data) {
}

View File

@ -0,0 +1,29 @@
package eu.mhsl.craftattack.spawn.api.client.repositories;
import eu.mhsl.craftattack.spawn.api.client.HttpRepository;
import eu.mhsl.craftattack.spawn.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.util.api.EventApiUtil;
import java.util.UUID;
public class EventRepository extends HttpRepository {
public EventRepository() {
super(EventApiUtil.getBaseUri());
}
public record CreatedRoom(UUID uuid) {
}
public record QueueRoom(UUID player, UUID room) {
public record Response(String error) {
}
}
public ReqResp<CreatedRoom> createSession() {
return this.post("room", null, CreatedRoom.class);
}
public ReqResp<QueueRoom.Response> queueRoom(QueueRoom request) {
return this.post("queueRoom", request, QueueRoom.Response.class);
}
}

View File

@ -0,0 +1,27 @@
package eu.mhsl.craftattack.spawn.api.client.repositories;
import com.google.common.reflect.TypeToken;
import eu.mhsl.craftattack.spawn.api.client.HttpRepository;
import eu.mhsl.craftattack.spawn.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.util.api.WebsiteApiUtil;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class FeedbackRepository extends HttpRepository {
public FeedbackRepository() {
super(WebsiteApiUtil.getBaseUri(), WebsiteApiUtil::withAuthorizationSecret);
}
public record Request(String event, List<UUID> users) {
}
public ReqResp<Map<UUID, String>> createFeedbackUrls(Request data) {
final Type responseType = new TypeToken<Map<UUID, String>>() {
}.getType();
ReqResp<Object> rawData = this.post("feedback", data, Object.class);
return new ReqResp<>(rawData.status(), this.gson.fromJson(this.gson.toJson(rawData.data()), responseType));
}
}

View File

@ -0,0 +1,57 @@
package eu.mhsl.craftattack.spawn.api.client.repositories;
import eu.mhsl.craftattack.spawn.api.client.HttpRepository;
import eu.mhsl.craftattack.spawn.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.util.api.WebsiteApiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.UUID;
public class ReportRepository extends HttpRepository {
public ReportRepository() {
super(WebsiteApiUtil.getBaseUri(), WebsiteApiUtil::withAuthorizationSecret);
}
public record ReportCreationInfo(@NotNull UUID reporter, @Nullable UUID reported, String reason) {
}
public record ReportUrl(@NotNull String url) {
}
public record PlayerReports(
List<Report> from_self,
Object to_self
) {
public record Report(
@Nullable Reporter reported,
@NotNull String subject,
boolean draft,
@NotNull String status,
@NotNull String url
) {
public record Reporter(
@NotNull String username,
@NotNull String uuid
) {
}
}
}
public ReqResp<PlayerReports> queryReports(UUID player) {
return this.get(
"report",
(parameters) -> parameters.addParameter("uuid", player.toString()),
PlayerReports.class
);
}
public ReqResp<ReportUrl> createReport(ReportCreationInfo data) {
return this.post(
"report",
data,
ReportUrl.class
);
}
}

View File

@ -0,0 +1,31 @@
package eu.mhsl.craftattack.spawn.api.client.repositories;
import eu.mhsl.craftattack.spawn.api.client.HttpRepository;
import eu.mhsl.craftattack.spawn.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.util.api.WebsiteApiUtil;
import java.util.UUID;
public class WhitelistRepository extends HttpRepository {
public WhitelistRepository() {
super(WebsiteApiUtil.getBaseUri(), WebsiteApiUtil::withAuthorizationSecret);
}
public record UserData(
UUID uuid,
String username,
String firstname,
String lastname,
Long banned_until,
Long outlawed_until
) {
}
public ReqResp<UserData> getUserData(UUID userId) {
return this.get(
"user",
parameters -> parameters.addParameter("uuid", userId.toString()),
UserData.class
);
}
}

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.api; package eu.mhsl.craftattack.spawn.api.server;
import com.google.gson.Gson; import com.google.gson.Gson;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;

View File

@ -1,7 +1,8 @@
package eu.mhsl.craftattack.spawn.appliance; package eu.mhsl.craftattack.spawn.appliance;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.api.HttpServer; import eu.mhsl.craftattack.spawn.api.client.Repository;
import eu.mhsl.craftattack.spawn.api.server.HttpServer;
import eu.mhsl.craftattack.spawn.config.Configuration; import eu.mhsl.craftattack.spawn.config.Configuration;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.PluginCommand; import org.bukkit.command.PluginCommand;
@ -72,8 +73,8 @@ public abstract class Appliance {
*/ */
@NotNull @NotNull
public ConfigurationSection localConfig() { public ConfigurationSection localConfig() {
return Optional.ofNullable(Configuration.cfg.getConfigurationSection(localConfigPath)) return Optional.ofNullable(Configuration.cfg.getConfigurationSection(this.localConfigPath))
.orElseGet(() -> Configuration.cfg.createSection(localConfigPath)); .orElseGet(() -> Configuration.cfg.createSection(this.localConfigPath));
} }
public void onEnable() { public void onEnable() {
@ -83,21 +84,25 @@ public abstract class Appliance {
} }
public void initialize(@NotNull JavaPlugin plugin) { public void initialize(@NotNull JavaPlugin plugin) {
this.listeners = listeners(); this.listeners = this.listeners();
this.commands = commands(); this.commands = this.commands();
listeners.forEach(listener -> Bukkit.getPluginManager().registerEvents(listener, plugin)); this.listeners.forEach(listener -> Bukkit.getPluginManager().registerEvents(listener, plugin));
commands.forEach(command -> setCommandExecutor(plugin, command.commandName, command)); this.commands.forEach(command -> this.setCommandExecutor(plugin, command.commandName, command));
} }
public void destruct(@NotNull JavaPlugin plugin) { public void destruct(@NotNull JavaPlugin plugin) {
listeners.forEach(HandlerList::unregisterAll); this.listeners.forEach(HandlerList::unregisterAll);
} }
protected static <T extends Appliance> T queryAppliance(Class<T> clazz) { protected <T extends Appliance> T queryAppliance(Class<T> clazz) {
return Main.instance().getAppliance(clazz); return Main.instance().getAppliance(clazz);
} }
protected <T extends Repository> T queryRepository(Class<T> clazz) {
return Main.instance().getRepositoryLoader().getRepository(clazz);
}
private void setCommandExecutor(JavaPlugin plugin, String name, ApplianceCommand<?> executor) { private void setCommandExecutor(JavaPlugin plugin, String name, ApplianceCommand<?> executor) {
PluginCommand command = plugin.getCommand(name); PluginCommand command = plugin.getCommand(name);
if(command != null && executor != null) { if(command != null && executor != null) {
@ -110,10 +115,10 @@ public abstract class Appliance {
} }
public List<Listener> getListeners() { public List<Listener> getListeners() {
return listeners; return this.listeners;
} }
public List<ApplianceCommand<?>> getCommands() { public List<ApplianceCommand<?>> getCommands() {
return commands; return this.commands;
} }
} }

View File

@ -33,12 +33,12 @@ public abstract class ApplianceCommand<T extends Appliance> extends CachedApplia
@Override @Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
try { try {
execute(sender, command, label, args); this.execute(sender, command, label, args);
} catch(Error e) { } catch(Error e) {
sender.sendMessage(errorMessage.append(Component.text(e.getMessage()))); sender.sendMessage(this.errorMessage.append(Component.text(e.getMessage())));
} catch(Exception e) { } catch(Exception e) {
sender.sendMessage(errorMessage.append(Component.text("Interner Fehler"))); sender.sendMessage(this.errorMessage.append(Component.text("Interner Fehler")));
Main.logger().warning("Error executing appliance command " + commandName + ": " + e.getMessage()); Main.logger().warning("Error executing appliance command " + this.commandName + ": " + e.getMessage());
e.printStackTrace(System.err); e.printStackTrace(System.err);
return false; return false;
} }
@ -80,7 +80,7 @@ public abstract class ApplianceCommand<T extends Appliance> extends CachedApplia
@Override @Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(!(sender instanceof Player)) { if(!(sender instanceof Player)) {
sender.sendMessage(notPlayerMessage); sender.sendMessage(this.notPlayerMessage);
return false; return false;
} }
this.player = (Player) sender; this.player = (Player) sender;

View File

@ -6,7 +6,7 @@ public class CachedApplianceSupplier<T extends Appliance> implements IApplianceS
private final T appliance; private final T appliance;
public CachedApplianceSupplier() { public CachedApplianceSupplier() {
this.appliance = Main.instance().getAppliance(Main.getApplianceType(getClass())); this.appliance = Main.instance().getAppliance(Main.getApplianceType(this.getClass()));
} }
@Override @Override

View File

@ -1,14 +0,0 @@
package eu.mhsl.craftattack.spawn.appliances.adminMarker;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Color;
import org.bukkit.entity.Player;
public class AdminMarkerListener extends ApplianceListener<AdminMarker> {
private TextColor getPlayerColor(Player player) {
if(player.hasPermission("chatcolor"))
return TextColor.color(Color.AQUA.asRGB()); // TODO read permission from config
return TextColor.color(Color.WHITE.asRGB());
}
}

View File

@ -1,13 +0,0 @@
package eu.mhsl.craftattack.spawn.appliances.customAdvancements.listener;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import eu.mhsl.craftattack.spawn.appliances.customAdvancements.CustomAdvancements;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
public class ApplyPendingAdvancementsListener extends ApplianceListener<CustomAdvancements> {
@EventHandler
public void onJoin(PlayerJoinEvent event) {
getAppliance().applyPendingAdvancements(event.getPlayer());
}
}

View File

@ -1,68 +0,0 @@
package eu.mhsl.craftattack.spawn.appliances.displayName;
import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliances.adminMarker.AdminMarker;
import eu.mhsl.craftattack.spawn.appliances.adminMarker.AdminMarkerListener;
import eu.mhsl.craftattack.spawn.appliances.afkTag.AfkTag;
import eu.mhsl.craftattack.spawn.appliances.outlawed.Outlawed;
import eu.mhsl.craftattack.spawn.appliances.sleepTag.SleepTag;
import eu.mhsl.craftattack.spawn.appliances.yearRank.YearRank;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentBuilder;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.function.Supplier;
import java.util.logging.Level;
public class DisplayName extends Appliance {
public interface DisplayNamed {
@Nullable Component getNamePrefix(Player player);
}
public void update(Player player) {
TextColor playerColor = queryAppliance(AdminMarker.class).getPlayerColor(player);
List<Supplier<Component>> prefixes = List.of(
() -> queryAppliance(Outlawed.class).getNamePrefix(player),
() -> queryAppliance(YearRank.class).getNamePrefix(player),
() -> queryAppliance(AfkTag.class).getNamePrefix(player),
() -> queryAppliance(SleepTag.class).getNamePrefix(player)
);
ComponentBuilder<TextComponent, TextComponent.Builder> playerName = Component.text();
prefixes.forEach(supplier -> {
Component prefix = supplier.get();
if(prefix == null) return;
playerName.append(prefix).append(
Component.text(" ").hoverEvent(Component.empty().asHoverEvent()));
});
playerName.append(Component.text(player.getName(), playerColor));
setGlobal(player, playerName.build());
}
private void setGlobal(Player player, Component component) {
try {
player.customName(component);
player.displayName(component);
player.playerListName(component);
} catch(Exception e) {
//TODO this throws often exceptions, but still works, don't know why
Main.instance().getLogger().log(Level.SEVERE, e, e::getMessage);
}
}
@Override
@NotNull
protected List<Listener> listeners() {
return List.of(new AdminMarkerListener());
}
}

View File

@ -1,13 +0,0 @@
package eu.mhsl.craftattack.spawn.appliances.displayName;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerJoinEvent;
public class DisplayNameUpdateListener extends ApplianceListener<DisplayName> {
@EventHandler(priority = EventPriority.LOWEST)
public void onJoin(PlayerJoinEvent event) {
getAppliance().update(event.getPlayer());
}
}

View File

@ -1,13 +0,0 @@
package eu.mhsl.craftattack.spawn.appliances.event.listener;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import eu.mhsl.craftattack.spawn.appliances.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
public class ApplyPendingRewardsListener extends ApplianceListener<Event> {
@EventHandler
public void onJoin(PlayerJoinEvent event) {
getAppliance().applyPendingRewards(event.getPlayer());
}
}

View File

@ -1,34 +0,0 @@
package eu.mhsl.craftattack.spawn.appliances.feedback;
import eu.mhsl.craftattack.spawn.appliance.Appliance;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.List;
public class Feedback extends Appliance {
public void requestFeedback(String eventName) {
List<Player> players = Bukkit.getOnlinePlayers().stream()
.map(player -> (Player) player)
.toList();
requestFeedback(eventName, players);
}
public void requestFeedback(String eventName, List<Player> receivers) {
receivers.forEach(player -> player.sendMessage(
Component.text()
.append(Component.text("------------------------------", NamedTextColor.GRAY))
.appendNewline()
.append(Component.text("Klicke hier und gib Feedback, damit wir dein Spielerlebnis verbessern können!", NamedTextColor.GREEN)
.clickEvent(ClickEvent.openUrl(String.format("https://www.google.com/search?q=%s", eventName))))
.hoverEvent(HoverEvent.showText(Component.text("Klicke, um Feedback zu geben.").color(NamedTextColor.GOLD)))
.appendNewline()
.append(Component.text("------------------------------", NamedTextColor.GRAY))
));
}
}

View File

@ -1,8 +1,8 @@
package eu.mhsl.craftattack.spawn.appliances.antiSignEdit; package eu.mhsl.craftattack.spawn.appliances.gameplay.antiSignEdit;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.SelectSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.datatypes.SelectSetting;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;

View File

@ -1,15 +1,15 @@
package eu.mhsl.craftattack.spawn.appliances.antiSignEdit; package eu.mhsl.craftattack.spawn.appliances.gameplay.antiSignEdit;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import io.papermc.paper.event.player.PlayerOpenSignEvent; import io.papermc.paper.event.player.PlayerOpenSignEvent;
import org.bukkit.block.sign.SignSide; import org.bukkit.block.sign.SignSide;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
public class OnSignEditListener extends ApplianceListener<AntiSignEdit> { class OnSignEditListener extends ApplianceListener<AntiSignEdit> {
@EventHandler @EventHandler
public void onEdit(PlayerOpenSignEvent event) { public void onEdit(PlayerOpenSignEvent event) {
if(event.getCause().equals(PlayerOpenSignEvent.Cause.PLACE)) return; if(event.getCause().equals(PlayerOpenSignEvent.Cause.PLACE)) return;
SignSide signSide = event.getSign().getSide(event.getSide()); SignSide signSide = event.getSign().getSide(event.getSide());
event.setCancelled(getAppliance().preventSignEdit(event.getPlayer(), signSide)); event.setCancelled(this.getAppliance().preventSignEdit(event.getPlayer(), signSide));
} }
} }

View File

@ -1,9 +1,9 @@
package eu.mhsl.craftattack.spawn.appliances.antiSignEdit; package eu.mhsl.craftattack.spawn.appliances.gameplay.antiSignEdit;
import eu.mhsl.craftattack.spawn.appliances.settings.CategorizedSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.CategorizedSetting;
import eu.mhsl.craftattack.spawn.appliances.settings.SettingCategory; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.SettingCategory;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.SelectSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.datatypes.SelectSetting;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.autoShulker; package eu.mhsl.craftattack.spawn.appliances.gameplay.autoShulker;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Material; import org.bukkit.Material;
@ -31,7 +31,8 @@ public class AutoShulker extends Appliance {
ShulkerBox shulkerBox = (ShulkerBox) blockStateMeta.getBlockState(); ShulkerBox shulkerBox = (ShulkerBox) blockStateMeta.getBlockState();
HashMap<Integer, ItemStack> leftOver = shulkerBox.getInventory().addItem(itemStack); HashMap<Integer, ItemStack> leftOver = shulkerBox.getInventory().addItem(itemStack);
if(leftOver.size() > 1) throw new IllegalStateException("Multiple ItemStacks cannot be processed by AutoShulker!"); if(leftOver.size() > 1)
throw new IllegalStateException("Multiple ItemStacks cannot be processed by AutoShulker!");
if(itemStack.equals(leftOver.get(0))) { if(itemStack.equals(leftOver.get(0))) {
p.sendActionBar(Component.text("Die Shulkerbox ist voll!", NamedTextColor.RED)); p.sendActionBar(Component.text("Die Shulkerbox ist voll!", NamedTextColor.RED));
return false; return false;

View File

@ -1,9 +1,9 @@
package eu.mhsl.craftattack.spawn.appliances.autoShulker; package eu.mhsl.craftattack.spawn.appliances.gameplay.autoShulker;
import eu.mhsl.craftattack.spawn.appliances.settings.CategorizedSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.CategorizedSetting;
import eu.mhsl.craftattack.spawn.appliances.settings.SettingCategory; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.SettingCategory;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.SelectSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.datatypes.SelectSetting;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;

View File

@ -1,20 +1,20 @@
package eu.mhsl.craftattack.spawn.appliances.autoShulker; package eu.mhsl.craftattack.spawn.appliances.gameplay.autoShulker;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.SelectSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.datatypes.SelectSetting;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.entity.EntityPickupItemEvent;
public class ItemPickupListener extends ApplianceListener<AutoShulker> { class ItemPickupListener extends ApplianceListener<AutoShulker> {
@EventHandler @EventHandler
public void onPickup(EntityPickupItemEvent event) { public void onPickup(EntityPickupItemEvent event) {
if(event.getEntity() instanceof Player p) { if(event.getEntity() instanceof Player p) {
SelectSetting.Options.Option setting = Settings.instance().getSetting(p, Settings.Key.AutoShulker, SelectSetting.Options.Option.class); SelectSetting.Options.Option setting = Settings.instance().getSetting(p, Settings.Key.AutoShulker, SelectSetting.Options.Option.class);
if(setting.is(AutoShulkerSetting.disabled)) return; if(setting.is(AutoShulkerSetting.disabled)) return;
if(setting.is(AutoShulkerSetting.notFromPlayers) && event.getItem().getThrower() != null) return; if(setting.is(AutoShulkerSetting.notFromPlayers) && event.getItem().getThrower() != null) return;
event.setCancelled(getAppliance().tryAutoShulker(p, event.getItem())); event.setCancelled(this.getAppliance().tryAutoShulker(p, event.getItem()));
} }
} }
} }

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.customAdvancements; package eu.mhsl.craftattack.spawn.appliances.gameplay.customAdvancements;
public class Advancements { public class Advancements {
public static String searchTrouble = "search_trouble"; public static String searchTrouble = "search_trouble";

View File

@ -0,0 +1,12 @@
package eu.mhsl.craftattack.spawn.appliances.gameplay.customAdvancements;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
class ApplyPendingAdvancementsListener extends ApplianceListener<CustomAdvancements> {
@EventHandler
public void onJoin(PlayerJoinEvent event) {
this.getAppliance().applyPendingAdvancements(event.getPlayer());
}
}

View File

@ -1,9 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.customAdvancements; package eu.mhsl.craftattack.spawn.appliances.gameplay.customAdvancements;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliances.customAdvancements.listener.ApplyPendingAdvancementsListener;
import eu.mhsl.craftattack.spawn.appliances.customAdvancements.listener.CustomAdvancementsListener;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.advancement.Advancement; import org.bukkit.advancement.Advancement;
@ -25,15 +23,21 @@ public class CustomAdvancements extends Appliance {
public void grantAdvancement(String advancementName, UUID playerUUID) { public void grantAdvancement(String advancementName, UUID playerUUID) {
Player player = Bukkit.getPlayer(playerUUID); Player player = Bukkit.getPlayer(playerUUID);
if(player == null) { if(player == null) {
addPendingAdvancement(playerUUID, advancementName); this.addPendingAdvancement(playerUUID, advancementName);
return; return;
} }
try { try {
NamespacedKey namespacedKey = Objects.requireNonNull(NamespacedKey.fromString("custom_advancements:craftattack/" + advancementName), "NamespacedKey is invalid!"); NamespacedKey namespacedKey = Objects.requireNonNull(
Advancement advancement = Objects.requireNonNull(Bukkit.getAdvancement(namespacedKey), "The advancement does not exist!"); NamespacedKey.fromString("craftattack_advancements:craftattack/" + advancementName),
String.format("NamespacedKey with '%s' is invalid!", advancementName)
);
Advancement advancement = Objects.requireNonNull(
Bukkit.getAdvancement(namespacedKey),
String.format("The advancement '%s' does not exist!", namespacedKey.asString())
);
player.getAdvancementProgress(advancement).awardCriteria("criteria"); player.getAdvancementProgress(advancement).awardCriteria("criteria");
} catch (Exception e) { } catch(Exception e) {
Main.logger().info("Advancement " + advancementName + " not found! (is Custom Advancements data pack loaded?)"); Main.logger().info("Advancement " + advancementName + " not found! (is Custom Advancements data pack loaded?)");
throw e; throw e;
} }
@ -41,14 +45,14 @@ public class CustomAdvancements extends Appliance {
public void applyPendingAdvancements(Player player) { public void applyPendingAdvancements(Player player) {
if(this.pendingAdvancements.isEmpty()) return; if(this.pendingAdvancements.isEmpty()) return;
List<PendingAdvancement> grantedAdvancements = pendingAdvancements.stream() List<PendingAdvancement> grantedAdvancements = this.pendingAdvancements.stream()
.filter(pendingAdvancement -> pendingAdvancement.receiver.equals(player.getUniqueId())).toList(); .filter(pendingAdvancement -> pendingAdvancement.receiver.equals(player.getUniqueId())).toList();
this.pendingAdvancements.removeAll(grantedAdvancements); this.pendingAdvancements.removeAll(grantedAdvancements);
grantedAdvancements.forEach(pendingAdvancement -> grantAdvancement(pendingAdvancement.advancement(), player.getUniqueId())); grantedAdvancements.forEach(pendingAdvancement -> this.grantAdvancement(pendingAdvancement.advancement(), player.getUniqueId()));
} }
private void addPendingAdvancement(UUID receiver, String advancement) { private void addPendingAdvancement(UUID receiver, String advancement) {
pendingAdvancements.add(new PendingAdvancement(receiver, advancement)); this.pendingAdvancements.add(new PendingAdvancement(receiver, advancement));
} }
@Override @Override

View File

@ -1,8 +1,6 @@
package eu.mhsl.craftattack.spawn.appliances.customAdvancements.listener; package eu.mhsl.craftattack.spawn.appliances.gameplay.customAdvancements;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import eu.mhsl.craftattack.spawn.appliances.customAdvancements.Advancements;
import eu.mhsl.craftattack.spawn.appliances.customAdvancements.CustomAdvancements;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -12,7 +10,7 @@ import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
public class CustomAdvancementsListener extends ApplianceListener<CustomAdvancements> { class CustomAdvancementsListener extends ApplianceListener<CustomAdvancements> {
@EventHandler @EventHandler
public void onEntityDamageEntity(EntityDamageByEntityEvent event) { public void onEntityDamageEntity(EntityDamageByEntityEvent event) {
if(!(event.getEntity() instanceof Player damaged)) return; if(!(event.getEntity() instanceof Player damaged)) return;
@ -20,7 +18,7 @@ public class CustomAdvancementsListener extends ApplianceListener<CustomAdvancem
if(!damager.getInventory().getItemInMainHand().getType().equals(Material.AIR)) return; if(!damager.getInventory().getItemInMainHand().getType().equals(Material.AIR)) return;
if(!damaged.hasPermission("admin")) return; if(!damaged.hasPermission("admin")) return;
getAppliance().grantAdvancement(Advancements.searchTrouble, damager.getUniqueId()); this.getAppliance().grantAdvancement(Advancements.searchTrouble, damager.getUniqueId());
} }
@EventHandler @EventHandler
@ -30,12 +28,12 @@ public class CustomAdvancementsListener extends ApplianceListener<CustomAdvancem
if(!(event.getView().getPlayer() instanceof Player player)) return; if(!(event.getView().getPlayer() instanceof Player player)) return;
if(result.getType() == Material.RED_SHULKER_BOX) { if(result.getType() == Material.RED_SHULKER_BOX) {
getAppliance().grantAdvancement(Advancements.fleischerchest, player.getUniqueId()); this.getAppliance().grantAdvancement(Advancements.fleischerchest, player.getUniqueId());
return; return;
} }
if(result.getItemMeta().itemName().equals(Component.text("98fdf0ae-c3ab-4ef7-ae25-efd518d600de"))) { if(result.getItemMeta().itemName().equals(Component.text("98fdf0ae-c3ab-4ef7-ae25-efd518d600de"))) {
getAppliance().grantAdvancement(Advancements.craftPixelblock, player.getUniqueId()); this.getAppliance().grantAdvancement(Advancements.craftPixelblock, player.getUniqueId());
} }
} }
@ -43,6 +41,6 @@ public class CustomAdvancementsListener extends ApplianceListener<CustomAdvancem
public void onChangeWorld(PlayerChangedWorldEvent event) { public void onChangeWorld(PlayerChangedWorldEvent event) {
if(!event.getPlayer().getWorld().getName().startsWith("plugins/PixelBlocks/worlds")) return; if(!event.getPlayer().getWorld().getName().startsWith("plugins/PixelBlocks/worlds")) return;
getAppliance().grantAdvancement(Advancements.usePixelblock, event.getPlayer().getUniqueId()); this.getAppliance().grantAdvancement(Advancements.usePixelblock, event.getPlayer().getUniqueId());
} }
} }

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.doubeDoor; package eu.mhsl.craftattack.spawn.appliances.gameplay.doubleDoor;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
@ -19,9 +19,9 @@ public class DoubleDoor extends Appliance {
public void openNextDoor(Block block) { public void openNextDoor(Block block) {
BlockData clickedData = block.getBlockData(); BlockData clickedData = block.getBlockData();
if (!(clickedData instanceof Door clickedDoor)) return; if(!(clickedData instanceof Door clickedDoor)) return;
BlockFace neighborFace = getNeighborFace(clickedDoor.getFacing(), clickedDoor.getHinge()); BlockFace neighborFace = this.getNeighborFace(clickedDoor.getFacing(), clickedDoor.getHinge());
Block neighbourBlock = block.getRelative(neighborFace); Block neighbourBlock = block.getRelative(neighborFace);
BlockData neighbourData = neighbourBlock.getBlockData(); BlockData neighbourData = neighbourBlock.getBlockData();
@ -39,7 +39,8 @@ public class DoubleDoor extends Appliance {
case WEST -> (hinge == Door.Hinge.RIGHT) ? BlockFace.SOUTH : BlockFace.NORTH; case WEST -> (hinge == Door.Hinge.RIGHT) ? BlockFace.SOUTH : BlockFace.NORTH;
case SOUTH -> (hinge == Door.Hinge.RIGHT) ? BlockFace.EAST : BlockFace.WEST; case SOUTH -> (hinge == Door.Hinge.RIGHT) ? BlockFace.EAST : BlockFace.WEST;
case NORTH -> (hinge == Door.Hinge.RIGHT) ? BlockFace.WEST : BlockFace.EAST; case NORTH -> (hinge == Door.Hinge.RIGHT) ? BlockFace.WEST : BlockFace.EAST;
default -> throw new IllegalStateException(String.format("BlockFace '%s' of clicked door is not valid!", face)); default ->
throw new IllegalStateException(String.format("BlockFace '%s' of clicked door is not valid!", face));
}; };
} }

View File

@ -1,9 +1,9 @@
package eu.mhsl.craftattack.spawn.appliances.doubeDoor; package eu.mhsl.craftattack.spawn.appliances.gameplay.doubleDoor;
import eu.mhsl.craftattack.spawn.appliances.settings.CategorizedSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.CategorizedSetting;
import eu.mhsl.craftattack.spawn.appliances.settings.SettingCategory; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.SettingCategory;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.BoolSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.datatypes.BoolSetting;
import org.bukkit.Material; import org.bukkit.Material;
public class DoubleDoorSetting extends BoolSetting implements CategorizedSetting { public class DoubleDoorSetting extends BoolSetting implements CategorizedSetting {

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.doubeDoor; package eu.mhsl.craftattack.spawn.appliances.gameplay.doubleDoor;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -11,7 +11,7 @@ import org.bukkit.inventory.EquipmentSlot;
import java.util.Objects; import java.util.Objects;
public class OnDoorInteractListener extends ApplianceListener<DoubleDoor> { class OnDoorInteractListener extends ApplianceListener<DoubleDoor> {
@EventHandler @EventHandler
public void onPlayerInteract(PlayerInteractEvent event) { public void onPlayerInteract(PlayerInteractEvent event) {
if(!event.hasBlock()) return; if(!event.hasBlock()) return;
@ -22,6 +22,6 @@ public class OnDoorInteractListener extends ApplianceListener<DoubleDoor> {
if(clickedBlock == null) return; if(clickedBlock == null) return;
if(clickedBlock.getType().equals(Material.IRON_DOOR)) return; if(clickedBlock.getType().equals(Material.IRON_DOOR)) return;
if(!Settings.instance().getSetting(event.getPlayer(), Settings.Key.DoubleDoors, Boolean.class)) return; if(!Settings.instance().getSetting(event.getPlayer(), Settings.Key.DoubleDoors, Boolean.class)) return;
getAppliance().openNextDoor(clickedBlock); this.getAppliance().openNextDoor(clickedBlock);
} }
} }

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.fleischerchest; package eu.mhsl.craftattack.spawn.appliances.gameplay.fleischerchest;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.fleischerchest; package eu.mhsl.craftattack.spawn.appliances.gameplay.fleischerchest;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import org.bukkit.Material; import org.bukkit.Material;
@ -6,13 +6,13 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.PrepareItemCraftEvent; import org.bukkit.event.inventory.PrepareItemCraftEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
public class FleischerchestCraftItemListener extends ApplianceListener<Fleischerchest> { class FleischerchestCraftItemListener extends ApplianceListener<Fleischerchest> {
@EventHandler @EventHandler
public void onPrepareItemCraft(PrepareItemCraftEvent event) { public void onPrepareItemCraft(PrepareItemCraftEvent event) {
ItemStack result = event.getInventory().getResult(); ItemStack result = event.getInventory().getResult();
if(result == null) return; if(result == null) return;
if(result.getType() != Material.RED_SHULKER_BOX) return; if(result.getType() != Material.RED_SHULKER_BOX) return;
getAppliance().renameItem(event.getInventory().getResult()); this.getAppliance().renameItem(event.getInventory().getResult());
} }
} }

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.glowingBerries; package eu.mhsl.craftattack.spawn.appliances.gameplay.glowingBerries;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import net.kyori.adventure.sound.Sound; import net.kyori.adventure.sound.Sound;

View File

@ -1,13 +1,14 @@
package eu.mhsl.craftattack.spawn.appliances.glowingBerries; package eu.mhsl.craftattack.spawn.appliances.gameplay.glowingBerries;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerItemConsumeEvent; import org.bukkit.event.player.PlayerItemConsumeEvent;
public class OnBerryEaten extends ApplianceListener<GlowingBerries> { class OnBerryEaten extends ApplianceListener<GlowingBerries> {
@EventHandler @EventHandler
public void onEat(PlayerItemConsumeEvent event) { public void onEat(PlayerItemConsumeEvent event) {
if(event.getItem().getType().equals(Material.GLOW_BERRIES)) getAppliance().letPlayerGlow(event.getPlayer()); if(event.getItem().getType().equals(Material.GLOW_BERRIES))
this.getAppliance().letPlayerGlow(event.getPlayer());
} }
} }

View File

@ -1,8 +1,8 @@
package eu.mhsl.craftattack.spawn.appliances.hotbarRefill; package eu.mhsl.craftattack.spawn.appliances.gameplay.hotbarRefill;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -47,7 +47,6 @@ public class HotbarRefill extends Appliance {
player.sendActionBar(Component.text("Die Hotbar wurde aufgefüllt", NamedTextColor.GREEN)); player.sendActionBar(Component.text("Die Hotbar wurde aufgefüllt", NamedTextColor.GREEN));
}, 1); }, 1);
} catch(NoSuchElementException ignored) { } catch(NoSuchElementException ignored) {
player.sendActionBar(Component.text("Keine weiteren Items dieser Art im Inventar vorhanden", NamedTextColor.RED));
} }
} }

View File

@ -1,7 +1,8 @@
package eu.mhsl.craftattack.spawn.appliances.hotbarRefill; package eu.mhsl.craftattack.spawn.appliances.gameplay.hotbarRefill;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
@ -9,7 +10,9 @@ import org.bukkit.event.player.PlayerItemBreakEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent; import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
public class HotbarRefillListener extends ApplianceListener<HotbarRefill> { import java.util.List;
class HotbarRefillListener extends ApplianceListener<HotbarRefill> {
private HotbarRefillSetting.HotbarReplaceConfig getPlayerSetting(Player player) { private HotbarRefillSetting.HotbarReplaceConfig getPlayerSetting(Player player) {
return Settings.instance().getSetting( return Settings.instance().getSetting(
player, player,
@ -23,22 +26,24 @@ public class HotbarRefillListener extends ApplianceListener<HotbarRefill> {
ItemStack stackInHand = event.getItemInHand(); ItemStack stackInHand = event.getItemInHand();
if(stackInHand.getAmount() != 1) return; if(stackInHand.getAmount() != 1) return;
if(stackInHand.getType().getMaxDurability() > 0) return; if(stackInHand.getType().getMaxDurability() > 0) return;
if(stackInHand.getType().getMaxStackSize() > 0) return;
if(!getPlayerSetting(event.getPlayer()).onBlocks()) return; if(!this.getPlayerSetting(event.getPlayer()).onBlocks()) return;
getAppliance().handleHotbarChange(event.getPlayer(), stackInHand); this.getAppliance().handleHotbarChange(event.getPlayer(), stackInHand);
} }
@EventHandler @EventHandler
public void onPlayerItemBreak(PlayerItemBreakEvent event) { public void onPlayerItemBreak(PlayerItemBreakEvent event) {
if(!getPlayerSetting(event.getPlayer()).onTools()) return; if(!this.getPlayerSetting(event.getPlayer()).onTools()) return;
getAppliance().handleHotbarChange(event.getPlayer(), event.getBrokenItem()); this.getAppliance().handleHotbarChange(event.getPlayer(), event.getBrokenItem());
} }
@EventHandler @EventHandler
public void onPlayerItemConsume(PlayerItemConsumeEvent event) { public void onPlayerItemConsume(PlayerItemConsumeEvent event) {
if(!getPlayerSetting(event.getPlayer()).onConsumable()) return; if(List.of(Material.POTION, Material.HONEY_BOTTLE).contains(event.getItem().getType())) return;
if(!this.getPlayerSetting(event.getPlayer()).onConsumable()) return;
getAppliance().handleHotbarChange(event.getPlayer(), event.getItem()); this.getAppliance().handleHotbarChange(event.getPlayer(), event.getItem());
} }
} }

View File

@ -1,9 +1,9 @@
package eu.mhsl.craftattack.spawn.appliances.hotbarRefill; package eu.mhsl.craftattack.spawn.appliances.gameplay.hotbarRefill;
import eu.mhsl.craftattack.spawn.appliances.settings.CategorizedSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.CategorizedSetting;
import eu.mhsl.craftattack.spawn.appliances.settings.SettingCategory; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.SettingCategory;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.MultiBoolSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.datatypes.MultiBoolSetting;
import org.bukkit.Material; import org.bukkit.Material;
public class HotbarRefillSetting extends MultiBoolSetting<HotbarRefillSetting.HotbarReplaceConfig> implements CategorizedSetting { public class HotbarRefillSetting extends MultiBoolSetting<HotbarRefillSetting.HotbarReplaceConfig> implements CategorizedSetting {
@ -16,7 +16,8 @@ public class HotbarRefillSetting extends MultiBoolSetting<HotbarRefillSetting.Ho
@DisplayName("Blöcke") boolean onBlocks, @DisplayName("Blöcke") boolean onBlocks,
@DisplayName("Werkzeuge") boolean onTools, @DisplayName("Werkzeuge") boolean onTools,
@DisplayName("Essen") boolean onConsumable @DisplayName("Essen") boolean onConsumable
) {} ) {
}
public HotbarRefillSetting() { public HotbarRefillSetting() {
super(Settings.Key.HotbarReplacer); super(Settings.Key.HotbarReplacer);

View File

@ -1,9 +1,9 @@
package eu.mhsl.craftattack.spawn.appliances.knockDoor; package eu.mhsl.craftattack.spawn.appliances.gameplay.knockDoor;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.SelectSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.datatypes.SelectSetting;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -25,7 +25,7 @@ public class KnockDoor extends Appliance {
if(setting.is(KnockDoorSetting.disabled)) return; if(setting.is(KnockDoorSetting.disabled)) return;
if(setting.is(KnockDoorSetting.knockSingleTime)) { if(setting.is(KnockDoorSetting.knockSingleTime)) {
playSound(knockedBlock); this.playSound(knockedBlock);
} }
if(setting.is(KnockDoorSetting.knockThreeTimes)) { if(setting.is(KnockDoorSetting.knockThreeTimes)) {
@ -39,10 +39,10 @@ public class KnockDoor extends Appliance {
int timesKnocked = knockingPlayer.getMetadata(metadataKey).getFirst().asInt(); int timesKnocked = knockingPlayer.getMetadata(metadataKey).getFirst().asInt();
if(timesKnocked >= 3) { if(timesKnocked >= 3) {
knockingPlayer.removeMetadata(metadataKey, Main.instance()); knockingPlayer.removeMetadata(metadataKey, Main.instance());
cancel(); this.cancel();
return; return;
} }
playSound(knockedBlock); KnockDoor.this.playSound(knockedBlock);
knockingPlayer.setMetadata(metadataKey, new FixedMetadataValue(Main.instance(), timesKnocked + 1)); knockingPlayer.setMetadata(metadataKey, new FixedMetadataValue(Main.instance(), timesKnocked + 1));
} }
}.runTaskTimer(Main.instance(), 0, 8); }.runTaskTimer(Main.instance(), 0, 8);

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.knockDoor; package eu.mhsl.craftattack.spawn.appliances.gameplay.knockDoor;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import org.bukkit.GameMode; import org.bukkit.GameMode;
@ -7,12 +7,12 @@ import org.bukkit.block.data.type.Door;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockDamageAbortEvent; import org.bukkit.event.block.BlockDamageAbortEvent;
public class KnockDoorListener extends ApplianceListener<KnockDoor> { class KnockDoorListener extends ApplianceListener<KnockDoor> {
@EventHandler @EventHandler
public void onKnock(BlockDamageAbortEvent event) { public void onKnock(BlockDamageAbortEvent event) {
if(event.getPlayer().getGameMode() != GameMode.SURVIVAL) return; if(event.getPlayer().getGameMode() != GameMode.SURVIVAL) return;
Block block = event.getBlock(); Block block = event.getBlock();
if(!(block.getBlockData() instanceof Door)) return; if(!(block.getBlockData() instanceof Door)) return;
getAppliance().knockAtDoor(event.getPlayer(), block); this.getAppliance().knockAtDoor(event.getPlayer(), block);
} }
} }

View File

@ -1,9 +1,9 @@
package eu.mhsl.craftattack.spawn.appliances.knockDoor; package eu.mhsl.craftattack.spawn.appliances.gameplay.knockDoor;
import eu.mhsl.craftattack.spawn.appliances.settings.CategorizedSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.CategorizedSetting;
import eu.mhsl.craftattack.spawn.appliances.settings.SettingCategory; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.SettingCategory;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.SelectSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.datatypes.SelectSetting;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;

View File

@ -0,0 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.gameplay.outlawed;
class OutlawChangeNotPermitted extends Exception {
public OutlawChangeNotPermitted(String message) {
super(message);
}
}

View File

@ -1,10 +1,10 @@
package eu.mhsl.craftattack.spawn.appliances.outlawed; package eu.mhsl.craftattack.spawn.appliances.gameplay.outlawed;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.displayName.DisplayName; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.displayName.DisplayName;
import eu.mhsl.craftattack.spawn.appliances.whitelist.Whitelist; import eu.mhsl.craftattack.spawn.appliances.tooling.whitelist.Whitelist;
import eu.mhsl.craftattack.spawn.config.Configuration; import eu.mhsl.craftattack.spawn.config.Configuration;
import eu.mhsl.craftattack.spawn.util.text.DisconnectInfo; import eu.mhsl.craftattack.spawn.util.text.DisconnectInfo;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.*; import java.util.*;
public class Outlawed extends Appliance implements DisplayName.DisplayNamed { public class Outlawed extends Appliance implements DisplayName.Prefixed {
public final int timeoutInMs = 1000 * 60 * 60 * 6; public final int timeoutInMs = 1000 * 60 * 60 * 6;
private final Map<UUID, Long> timeouts = new HashMap<>(); private final Map<UUID, Long> timeouts = new HashMap<>();
@ -34,13 +34,13 @@ public class Outlawed extends Appliance implements DisplayName.DisplayNamed {
super("outlawed"); super("outlawed");
Bukkit.getScheduler().runTaskTimerAsynchronously( Bukkit.getScheduler().runTaskTimerAsynchronously(
Main.instance(), Main.instance(),
() -> playerStatusMap.forEach((player, status) -> { () -> this.playerStatusMap.forEach((player, status) -> {
if(!player.isOnline()) return; if(!player.isOnline()) return;
if(status != Status.FORCED) return; if(status != Status.FORCED) return;
try { try {
queryAppliance(Whitelist.class).integrityCheck(player); this.queryAppliance(Whitelist.class).fullIntegrityCheck(player);
} catch(DisconnectInfo.Throwable e) { } catch(DisconnectInfo.Throwable e) {
Bukkit.getScheduler().runTask(Main.instance(), () -> e.getDisconnectScreen().applyKick(player)); e.getDisconnectScreen().applyKick(player);
} }
}), }),
20 * 60, 20 * 60,
@ -49,55 +49,55 @@ public class Outlawed extends Appliance implements DisplayName.DisplayNamed {
} }
public void switchLawStatus(Player player) throws OutlawChangeNotPermitted { public void switchLawStatus(Player player) throws OutlawChangeNotPermitted {
if(getLawStatus(player).equals(Status.FORCED)) { if(this.getLawStatus(player).equals(Status.FORCED)) {
throw new OutlawChangeNotPermitted("Dein Vogelfreistatus wurde als Strafe auferlegt und kann daher nicht verändert werden."); throw new OutlawChangeNotPermitted("Dein Vogelfreistatus wurde als Strafe auferlegt und kann daher nicht verändert werden.");
} }
if(isTimeout(player)) { if(this.isTimeout(player)) {
throw new OutlawChangeNotPermitted("Du kannst deinen Vogelfreistatus nicht so schnell wechseln. Bitte warte einige Stunden bevor du umschaltest!"); throw new OutlawChangeNotPermitted("Du kannst deinen Vogelfreistatus nicht so schnell wechseln. Bitte warte einige Stunden bevor du umschaltest!");
} }
setLawStatus(player, isOutlawed(player) ? Status.DISABLED : Status.VOLUNTARILY); this.setLawStatus(player, this.isOutlawed(player) ? Status.DISABLED : Status.VOLUNTARILY);
setTimeout(player); this.setTimeout(player);
} }
public void updateForcedStatus(Player player, boolean forced) { public void updateForcedStatus(Player player, boolean forced) {
setLawStatus(player, forced ? Status.FORCED : getLawStatus(player) == Status.FORCED ? Status.DISABLED : getLawStatus(player)); this.setLawStatus(player, forced ? Status.FORCED : this.getLawStatus(player) == Status.FORCED ? Status.DISABLED : this.getLawStatus(player));
} }
public Status getLawStatus(Player player) { public Status getLawStatus(Player player) {
return playerStatusMap.computeIfAbsent(player, p -> { return this.playerStatusMap.computeIfAbsent(player, p -> {
if(localConfig().getStringList(voluntarilyEntry).contains(p.getUniqueId().toString())) if(this.localConfig().getStringList(this.voluntarilyEntry).contains(p.getUniqueId().toString()))
return Status.VOLUNTARILY; return Status.VOLUNTARILY;
return Status.DISABLED; return Status.DISABLED;
}); });
} }
private void setLawStatus(Player player, Status status) { private void setLawStatus(Player player, Status status) {
playerStatusMap.put(player, status); this.playerStatusMap.put(player, status);
queryAppliance(DisplayName.class).update(player); this.queryAppliance(DisplayName.class).update(player);
List<String> newList = localConfig().getStringList(voluntarilyEntry); List<String> newList = this.localConfig().getStringList(this.voluntarilyEntry);
if(status.equals(Status.VOLUNTARILY)) { if(status.equals(Status.VOLUNTARILY)) {
newList.add(player.getUniqueId().toString()); newList.add(player.getUniqueId().toString());
} else { } else {
newList.remove(player.getUniqueId().toString()); newList.remove(player.getUniqueId().toString());
} }
localConfig().set(voluntarilyEntry, newList.stream().distinct().toList()); this.localConfig().set(this.voluntarilyEntry, newList.stream().distinct().toList());
Configuration.saveChanges(); Configuration.saveChanges();
} }
public boolean isOutlawed(Player player) { public boolean isOutlawed(Player player) {
return getLawStatus(player) != Status.DISABLED; return this.getLawStatus(player) != Status.DISABLED;
} }
private boolean isTimeout(Player player) { private boolean isTimeout(Player player) {
return timeouts.getOrDefault(player.getUniqueId(), 0L) > System.currentTimeMillis() - timeoutInMs; return this.timeouts.getOrDefault(player.getUniqueId(), 0L) > System.currentTimeMillis() - this.timeoutInMs;
} }
private void setTimeout(Player player) { private void setTimeout(Player player) {
timeouts.put(player.getUniqueId(), System.currentTimeMillis()); this.timeouts.put(player.getUniqueId(), System.currentTimeMillis());
} }
public Component getStatusDescription(Status status) { public Component getStatusDescription(Status status) {
@ -112,7 +112,7 @@ public class Outlawed extends Appliance implements DisplayName.DisplayNamed {
@Override @Override
public Component getNamePrefix(Player player) { public Component getNamePrefix(Player player) {
if(isOutlawed(player)) { if(this.isOutlawed(player)) {
return Component.text("[☠]", NamedTextColor.RED) return Component.text("[☠]", NamedTextColor.RED)
.hoverEvent(HoverEvent.showText(Component.text("Vogelfreie Spieler dürfen ohne Grund angegriffen werden!"))); .hoverEvent(HoverEvent.showText(Component.text("Vogelfreie Spieler dürfen ohne Grund angegriffen werden!")));
} }

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.outlawed; package eu.mhsl.craftattack.spawn.appliances.gameplay.outlawed;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -7,7 +7,7 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class OutlawedCommand extends ApplianceCommand.PlayerChecked<Outlawed> { class OutlawedCommand extends ApplianceCommand.PlayerChecked<Outlawed> {
public OutlawedCommand() { public OutlawedCommand() {
super("vogelfrei"); super("vogelfrei");
} }
@ -15,10 +15,10 @@ public class OutlawedCommand extends ApplianceCommand.PlayerChecked<Outlawed> {
@Override @Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception {
try { try {
getAppliance().switchLawStatus(getPlayer()); this.getAppliance().switchLawStatus(this.getPlayer());
sender.sendMessage( sender.sendMessage(
getAppliance() this.getAppliance()
.getStatusDescription(getAppliance().getLawStatus(getPlayer())) .getStatusDescription(this.getAppliance().getLawStatus(this.getPlayer()))
); );
} catch(OutlawChangeNotPermitted e) { } catch(OutlawChangeNotPermitted e) {
sender.sendMessage(Component.text(e.getMessage(), NamedTextColor.RED)); sender.sendMessage(Component.text(e.getMessage(), NamedTextColor.RED));

View File

@ -0,0 +1,14 @@
package eu.mhsl.craftattack.spawn.appliances.gameplay.outlawed;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
class OutlawedReminderListener extends ApplianceListener<Outlawed> {
@EventHandler
public void onJoin(PlayerJoinEvent e) {
if(this.getAppliance().isOutlawed(e.getPlayer())) {
e.getPlayer().sendMessage(this.getAppliance().getStatusDescription(this.getAppliance().getLawStatus(e.getPlayer())));
}
}
}

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.portableCrafting; package eu.mhsl.craftattack.spawn.appliances.gameplay.portableCrafting;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import org.bukkit.Material; import org.bukkit.Material;
@ -6,11 +6,11 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.block.Action; import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
public class OnCraftingTableUseListener extends ApplianceListener<PortableCrafting> { class OnCraftingTableUseListener extends ApplianceListener<PortableCrafting> {
@EventHandler @EventHandler
public void inInteract(PlayerInteractEvent event) { public void inInteract(PlayerInteractEvent event) {
if(!event.getAction().equals(Action.RIGHT_CLICK_AIR)) return; if(!event.getAction().equals(Action.RIGHT_CLICK_AIR)) return;
if(!event.getMaterial().equals(Material.CRAFTING_TABLE)) return; if(!event.getMaterial().equals(Material.CRAFTING_TABLE)) return;
getAppliance().openFor(event.getPlayer()); this.getAppliance().openFor(event.getPlayer());
} }
} }

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.portableCrafting; package eu.mhsl.craftattack.spawn.appliances.gameplay.portableCrafting;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@ -1,9 +1,9 @@
package eu.mhsl.craftattack.spawn.appliances.portableCrafting; package eu.mhsl.craftattack.spawn.appliances.gameplay.portableCrafting;
import eu.mhsl.craftattack.spawn.appliances.settings.CategorizedSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.CategorizedSetting;
import eu.mhsl.craftattack.spawn.appliances.settings.SettingCategory; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.SettingCategory;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.BoolSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.datatypes.BoolSetting;
import org.bukkit.Material; import org.bukkit.Material;
public class PortableCraftingSetting extends BoolSetting implements CategorizedSetting { public class PortableCraftingSetting extends BoolSetting implements CategorizedSetting {

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.snowballKnockback; package eu.mhsl.craftattack.spawn.appliances.gameplay.snowballKnockback;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;

View File

@ -1,11 +1,13 @@
package eu.mhsl.craftattack.spawn.appliances.snowballKnockback; package eu.mhsl.craftattack.spawn.appliances.gameplay.snowballKnockback;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import org.bukkit.entity.*; import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.entity.ProjectileHitEvent;
public class SnowballKnockbackListener extends ApplianceListener<SnowballKnockback> { class SnowballKnockbackListener extends ApplianceListener<SnowballKnockback> {
@EventHandler @EventHandler
public void onSnowballHit(ProjectileHitEvent event) { public void onSnowballHit(ProjectileHitEvent event) {
if(event.getHitEntity() == null) return; if(event.getHitEntity() == null) return;
@ -13,6 +15,6 @@ public class SnowballKnockbackListener extends ApplianceListener<SnowballKnockba
if(!(event.getHitEntity() instanceof LivingEntity hitEntity)) return; if(!(event.getHitEntity() instanceof LivingEntity hitEntity)) return;
Entity snowball = event.getEntity(); Entity snowball = event.getEntity();
getAppliance().dealSnowballKnockback(hitEntity, snowball); this.getAppliance().dealSnowballKnockback(hitEntity, snowball);
} }
} }

View File

@ -1,9 +1,9 @@
package eu.mhsl.craftattack.spawn.appliances.debug; package eu.mhsl.craftattack.spawn.appliances.internal.debug;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.debug.command.AppliancesCommand; import eu.mhsl.craftattack.spawn.appliances.internal.debug.command.AppliancesCommand;
import eu.mhsl.craftattack.spawn.appliances.debug.command.UserInfoCommand; import eu.mhsl.craftattack.spawn.appliances.internal.debug.command.UserInfoCommand;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;

View File

@ -1,8 +1,8 @@
package eu.mhsl.craftattack.spawn.appliances.debug.command; package eu.mhsl.craftattack.spawn.appliances.internal.debug.command;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.debug.Debug; import eu.mhsl.craftattack.spawn.appliances.internal.debug.Debug;
import eu.mhsl.craftattack.spawn.util.text.ComponentUtil; import eu.mhsl.craftattack.spawn.util.text.ComponentUtil;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentBuilder; import net.kyori.adventure.text.ComponentBuilder;

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.debug.command; package eu.mhsl.craftattack.spawn.appliances.internal.debug.command;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.debug.Debug; import eu.mhsl.craftattack.spawn.appliances.internal.debug.Debug;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
@ -50,13 +50,13 @@ public class UserInfoCommand extends ApplianceCommand<Debug> {
.appendNewline() .appendNewline()
.append( .append(
Component Component
.text("Erster Besuch: " + formatUnixTimestamp(player.getFirstPlayed()), NamedTextColor.GRAY) .text("Erster Besuch: " + this.formatUnixTimestamp(player.getFirstPlayed()), NamedTextColor.GRAY)
.clickEvent(ClickEvent.copyToClipboard(String.valueOf(player.getFirstPlayed()))) .clickEvent(ClickEvent.copyToClipboard(String.valueOf(player.getFirstPlayed())))
) )
.appendNewline() .appendNewline()
.append( .append(
Component Component
.text("Letzter Besuch: " + formatUnixTimestamp(player.getLastSeen()), NamedTextColor.GRAY) .text("Letzter Besuch: " + this.formatUnixTimestamp(player.getLastSeen()), NamedTextColor.GRAY)
.clickEvent(ClickEvent.copyToClipboard(String.valueOf(player.getLastSeen()))) .clickEvent(ClickEvent.copyToClipboard(String.valueOf(player.getLastSeen())))
) )
.appendNewline() .appendNewline()

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.titleClear; package eu.mhsl.craftattack.spawn.appliances.internal.titleClear;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

View File

@ -1,12 +1,12 @@
package eu.mhsl.craftattack.spawn.appliances.titleClear; package eu.mhsl.craftattack.spawn.appliances.internal.titleClear;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
public class TitleClearListener extends ApplianceListener<TitleClear> { class TitleClearListener extends ApplianceListener<TitleClear> {
@EventHandler @EventHandler
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
getAppliance().clearTitle(event.getPlayer()); this.getAppliance().clearTitle(event.getPlayer());
} }
} }

View File

@ -1,13 +1,9 @@
package eu.mhsl.craftattack.spawn.appliances.adminMarker; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.adminMarker;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class AdminMarker extends Appliance { public class AdminMarker extends Appliance {
public TextColor getPlayerColor(Player player) { public TextColor getPlayerColor(Player player) {
@ -15,10 +11,4 @@ public class AdminMarker extends Appliance {
return TextColor.color(Color.AQUA.asRGB()); // TODO read permission from config return TextColor.color(Color.AQUA.asRGB()); // TODO read permission from config
return TextColor.color(Color.WHITE.asRGB()); return TextColor.color(Color.WHITE.asRGB());
} }
@Override
@NotNull
protected List<Listener> listeners() {
return List.of(new AdminMarkerListener());
}
} }

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.afkTag; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.afkTag;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import io.papermc.paper.event.player.AsyncChatEvent; import io.papermc.paper.event.player.AsyncChatEvent;
@ -7,24 +7,24 @@ import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
public class AfkResetListener extends ApplianceListener<AfkTag> { class AfkResetListener extends ApplianceListener<AfkTag> {
@EventHandler @EventHandler
public void onMove(PlayerMoveEvent event) { public void onMove(PlayerMoveEvent event) {
getAppliance().resetTiming(event.getPlayer()); this.getAppliance().resetTiming(event.getPlayer());
} }
@EventHandler @EventHandler
public void onInteract(PlayerInteractEvent event) { public void onInteract(PlayerInteractEvent event) {
getAppliance().resetTiming(event.getPlayer()); this.getAppliance().resetTiming(event.getPlayer());
} }
@EventHandler @EventHandler
public void onChat(AsyncChatEvent event) { public void onChat(AsyncChatEvent event) {
getAppliance().resetTiming(event.getPlayer()); this.getAppliance().resetTiming(event.getPlayer());
} }
@EventHandler @EventHandler
public void onJoin(PlayerJoinEvent event) { public void onJoin(PlayerJoinEvent event) {
getAppliance().resetTiming(event.getPlayer()); this.getAppliance().resetTiming(event.getPlayer());
} }
} }

View File

@ -1,8 +1,8 @@
package eu.mhsl.craftattack.spawn.appliances.afkTag; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.afkTag;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliances.displayName.DisplayName; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.displayName.DisplayName;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
@ -13,13 +13,15 @@ import org.bukkit.event.Listener;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.WeakHashMap; import java.util.Objects;
import java.util.UUID;
public class AfkTag extends Appliance implements DisplayName.DisplayNamed { public class AfkTag extends Appliance implements DisplayName.Prefixed {
private final WeakHashMap<Player, Long> afkTimings = new WeakHashMap<>(); private final HashMap<UUID, Long> afkTimings = new HashMap<>();
private static final int updateIntervalSeconds = 30; private static final int updateIntervalSeconds = 30;
private static final int afkWhenMillis = 5 * 60 * 1000; private static final int afkWhenMillis = 3 * 60 * 1000;
@Override @Override
public void onEnable() { public void onEnable() {
@ -32,22 +34,23 @@ public class AfkTag extends Appliance implements DisplayName.DisplayNamed {
} }
public void resetTiming(Player player) { public void resetTiming(Player player) {
boolean wasAfk = isAfk(player); boolean wasAfk = this.isAfk(player);
this.afkTimings.put(player, System.currentTimeMillis()); this.afkTimings.put(player.getUniqueId(), System.currentTimeMillis());
if (wasAfk) this.updateAfkPrefix(player); if(wasAfk) this.updateAfkPrefix(player);
} }
private void checkAfkPlayers() { private void checkAfkPlayers() {
this.afkTimings.keySet().forEach((player) -> { this.afkTimings.keySet().stream()
if(!isAfk(player)) return; .map(Bukkit::getPlayer)
this.updateAfkPrefix(player); .filter(Objects::nonNull)
}); .filter(this::isAfk)
.forEach(this::updateAfkPrefix);
} }
private boolean isAfk(Player player) { private boolean isAfk(Player player) {
if(player.isSleeping()) return false; if(player.isSleeping()) return false;
long lastTimeActive = this.afkTimings.getOrDefault(player, 0L); long lastTimeActive = this.afkTimings.getOrDefault(player.getUniqueId(), 0L);
long timeSinceLastActive = System.currentTimeMillis() - lastTimeActive; long timeSinceLastActive = System.currentTimeMillis() - lastTimeActive;
return timeSinceLastActive >= afkWhenMillis; return timeSinceLastActive >= afkWhenMillis;
} }
@ -58,7 +61,7 @@ public class AfkTag extends Appliance implements DisplayName.DisplayNamed {
@Override @Override
public @Nullable Component getNamePrefix(Player player) { public @Nullable Component getNamePrefix(Player player) {
if(isAfk(player)) return Component.text("[ᵃᶠᵏ]", NamedTextColor.GRAY) if(this.isAfk(player)) return Component.text("[ᵃᶠᵏ]", NamedTextColor.GRAY)
.hoverEvent(HoverEvent.showText(Component.text("Der Spieler ist AFK"))); .hoverEvent(HoverEvent.showText(Component.text("Der Spieler ist AFK")));
return null; return null;

View File

@ -1,8 +1,8 @@
package eu.mhsl.craftattack.spawn.appliances.chatMention; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.chatMention;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import net.kyori.adventure.sound.Sound; import net.kyori.adventure.sound.Sound;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
@ -56,7 +56,7 @@ public class ChatMention extends Appliance {
@Override @Override
public void onEnable() { public void onEnable() {
Settings.instance().declareSetting(ChatMentionSetting.class); Settings.instance().declareSetting(ChatMentionSetting.class);
refreshPlayers(); this.refreshPlayers();
} }
@Override @Override

View File

@ -1,9 +1,9 @@
package eu.mhsl.craftattack.spawn.appliances.chatMention; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.chatMention;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import eu.mhsl.craftattack.spawn.appliances.chatMessages.ChatMessages; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.chatMessages.ChatMessages;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import eu.mhsl.craftattack.spawn.util.text.ComponentUtil; import eu.mhsl.craftattack.spawn.util.text.ComponentUtil;
import io.papermc.paper.event.player.AsyncChatDecorateEvent; import io.papermc.paper.event.player.AsyncChatDecorateEvent;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -15,7 +15,7 @@ import org.bukkit.event.player.PlayerJoinEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ChatMentionListener extends ApplianceListener<ChatMention> { class ChatMentionListener extends ApplianceListener<ChatMention> {
@SuppressWarnings("UnstableApiUsage") @SuppressWarnings("UnstableApiUsage")
@EventHandler @EventHandler
public void coloringEvent(AsyncChatDecorateEvent event) { public void coloringEvent(AsyncChatDecorateEvent event) {
@ -30,11 +30,11 @@ public class ChatMentionListener extends ApplianceListener<ChatMention> {
Component result = words.stream() Component result = words.stream()
.map(word -> { .map(word -> {
String wordWithoutAnnotation = word.replace("@", ""); String wordWithoutAnnotation = word.replace("@", "");
boolean isPlayer = getAppliance().getPlayerNames().contains(wordWithoutAnnotation); boolean isPlayer = this.getAppliance().getPlayerNames().contains(wordWithoutAnnotation);
if(isPlayer && config.applyMentions()) { if(isPlayer && config.applyMentions()) {
mentioned.add(wordWithoutAnnotation); mentioned.add(wordWithoutAnnotation);
Component mention = Component.text( Component mention = Component.text(
getAppliance().formatPlayer(wordWithoutAnnotation), this.getAppliance().formatPlayer(wordWithoutAnnotation),
NamedTextColor.GOLD NamedTextColor.GOLD
); );
return chatMessages.addReportActions(mention, wordWithoutAnnotation); return chatMessages.addReportActions(mention, wordWithoutAnnotation);
@ -45,12 +45,12 @@ public class ChatMentionListener extends ApplianceListener<ChatMention> {
.reduce(ComponentUtil::appendWithSpace) .reduce(ComponentUtil::appendWithSpace)
.orElseThrow(); .orElseThrow();
getAppliance().notifyPlayers(mentioned); this.getAppliance().notifyPlayers(mentioned);
event.result(result); event.result(result);
} }
@EventHandler @EventHandler
public void onJoin(PlayerJoinEvent event) { public void onJoin(PlayerJoinEvent event) {
getAppliance().refreshPlayers(); this.getAppliance().refreshPlayers();
} }
} }

View File

@ -1,9 +1,9 @@
package eu.mhsl.craftattack.spawn.appliances.chatMention; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.chatMention;
import eu.mhsl.craftattack.spawn.appliances.settings.CategorizedSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.CategorizedSetting;
import eu.mhsl.craftattack.spawn.appliances.settings.SettingCategory; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.SettingCategory;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.MultiBoolSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.datatypes.MultiBoolSetting;
import org.bukkit.Material; import org.bukkit.Material;
public class ChatMentionSetting extends MultiBoolSetting<ChatMentionSetting.ChatMentionConfig> implements CategorizedSetting { public class ChatMentionSetting extends MultiBoolSetting<ChatMentionSetting.ChatMentionConfig> implements CategorizedSetting {
@ -15,7 +15,8 @@ public class ChatMentionSetting extends MultiBoolSetting<ChatMentionSetting.Chat
public record ChatMentionConfig( public record ChatMentionConfig(
@DisplayName("Spielernamen hervorheben") boolean applyMentions, @DisplayName("Spielernamen hervorheben") boolean applyMentions,
@DisplayName("Benachrichtigungston") boolean notifyOnMention @DisplayName("Benachrichtigungston") boolean notifyOnMention
) {} ) {
}
public ChatMentionSetting() { public ChatMentionSetting() {
super(Settings.Key.ChatMentions); super(Settings.Key.ChatMentions);

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.chatMessages; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.chatMessages;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.event.HoverEvent;
@ -19,7 +19,7 @@ public class ChatMessages extends Appliance {
} }
public Component getReportablePlayerName(Player player) { public Component getReportablePlayerName(Player player) {
return addReportActions(player.displayName(), player.getName()); return this.addReportActions(player.displayName(), player.getName());
} }
public Component addReportActions(Component message, String username) { public Component addReportActions(Component message, String username) {

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.chatMessages; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.chatMessages;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import eu.mhsl.craftattack.spawn.util.IteratorUtil; import eu.mhsl.craftattack.spawn.util.IteratorUtil;
import io.papermc.paper.event.player.AsyncChatEvent; import io.papermc.paper.event.player.AsyncChatEvent;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -9,25 +9,26 @@ import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextColor;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import java.util.Optional; import java.util.Optional;
public class ChatMessagesListener extends ApplianceListener<ChatMessages> { class ChatMessagesListener extends ApplianceListener<ChatMessages> {
@EventHandler @EventHandler
public void onPlayerChatEvent(AsyncChatEvent event) { public void onPlayerChatEvent(AsyncChatEvent event) {
event.renderer( event.renderer(
(source, sourceDisplayName, message, viewer) -> (source, sourceDisplayName, message, viewer) ->
Component.text("") Component.text("")
.append(getAppliance().getReportablePlayerName(source)) .append(this.getAppliance().getReportablePlayerName(source))
.append(Component.text(" > ").color(TextColor.color(Color.GRAY.asRGB()))) .append(Component.text(" > ").color(TextColor.color(Color.GRAY.asRGB())))
.append(message).color(TextColor.color(Color.SILVER.asRGB())) .append(message).color(TextColor.color(Color.SILVER.asRGB()))
); );
} }
@EventHandler @EventHandler(priority = EventPriority.HIGH)
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
event.joinMessage(null); event.joinMessage(null);
IteratorUtil.onlinePlayers(player -> { IteratorUtil.onlinePlayers(player -> {
@ -35,7 +36,7 @@ public class ChatMessagesListener extends ApplianceListener<ChatMessages> {
player.sendMessage( player.sendMessage(
Component Component
.text(">>> ").color(NamedTextColor.GREEN) .text(">>> ").color(NamedTextColor.GREEN)
.append(getAppliance().getReportablePlayerName(event.getPlayer())) .append(this.getAppliance().getReportablePlayerName(event.getPlayer()))
); );
}); });
} }
@ -48,7 +49,7 @@ public class ChatMessagesListener extends ApplianceListener<ChatMessages> {
player.sendMessage( player.sendMessage(
Component Component
.text("<<< ").color(NamedTextColor.RED) .text("<<< ").color(NamedTextColor.RED)
.append(getAppliance().getReportablePlayerName(event.getPlayer())) .append(this.getAppliance().getReportablePlayerName(event.getPlayer()))
); );
}); });
} }

View File

@ -1,9 +1,9 @@
package eu.mhsl.craftattack.spawn.appliances.chatMessages; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.chatMessages;
import eu.mhsl.craftattack.spawn.appliances.settings.CategorizedSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.CategorizedSetting;
import eu.mhsl.craftattack.spawn.appliances.settings.SettingCategory; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.SettingCategory;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.BoolSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.datatypes.BoolSetting;
import org.bukkit.Material; import org.bukkit.Material;
public class ShowJoinAndLeaveMessagesSetting extends BoolSetting implements CategorizedSetting { public class ShowJoinAndLeaveMessagesSetting extends BoolSetting implements CategorizedSetting {

View File

@ -0,0 +1,75 @@
package eu.mhsl.craftattack.spawn.appliances.metaGameplay.displayName;
import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliances.gameplay.outlawed.Outlawed;
import eu.mhsl.craftattack.spawn.appliances.metaGameplay.adminMarker.AdminMarker;
import eu.mhsl.craftattack.spawn.appliances.metaGameplay.afkTag.AfkTag;
import eu.mhsl.craftattack.spawn.appliances.metaGameplay.sleepTag.SleepTag;
import eu.mhsl.craftattack.spawn.appliances.metaGameplay.yearRank.YearRank;
import eu.mhsl.craftattack.spawn.util.server.Floodgate;
import eu.mhsl.craftattack.spawn.util.text.ComponentUtil;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentBuilder;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextColor;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;
import java.util.logging.Level;
public class DisplayName extends Appliance {
public interface Prefixed {
@Nullable
Component getNamePrefix(Player player);
}
public void update(Player player) {
TextColor playerColor = this.queryAppliance(AdminMarker.class).getPlayerColor(player);
List<Supplier<Prefixed>> prefixes = List.of(
() -> this.queryAppliance(Outlawed.class),
() -> this.queryAppliance(YearRank.class),
() -> this.queryAppliance(AfkTag.class),
() -> this.queryAppliance(SleepTag.class)
);
ComponentBuilder<TextComponent, TextComponent.Builder> playerName = Component.text();
prefixes.stream()
.map(prefixed -> prefixed.get().getNamePrefix(player))
.filter(Objects::nonNull)
.forEach(prefix -> playerName
.append(prefix)
.append(ComponentUtil.clearedSpace())
);
if(Floodgate.isBedrock(player)) {
playerName
.append(
Component.text("\uD83C\uDFAE", NamedTextColor.GRAY)
.hoverEvent(HoverEvent.showText(Component.text(
String.format("%s spielt die Minecraft: Bedrock Edition", player.getName())
)))
)
.append(ComponentUtil.clearedSpace());
}
playerName.append(Component.text(player.getName(), playerColor));
this.setGlobal(player, playerName.build());
}
private void setGlobal(Player player, Component component) {
try {
player.customName(component);
player.displayName(component);
player.playerListName(component);
} catch(Exception e) {
Main.instance().getLogger().log(Level.SEVERE, e, e::getMessage);
}
}
}

View File

@ -0,0 +1,13 @@
package eu.mhsl.craftattack.spawn.appliances.metaGameplay.displayName;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerJoinEvent;
class DisplayNameUpdateListener extends ApplianceListener<DisplayName> {
@EventHandler(priority = EventPriority.LOW)
public void onJoin(PlayerJoinEvent event) {
this.getAppliance().update(event.getPlayer());
}
}

View File

@ -0,0 +1,12 @@
package eu.mhsl.craftattack.spawn.appliances.metaGameplay.event;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
class ApplyPendingRewardsListener extends ApplianceListener<Event> {
@EventHandler
public void onJoin(PlayerJoinEvent event) {
this.getAppliance().applyPendingRewards(event.getPlayer());
}
}

View File

@ -1,15 +1,16 @@
package eu.mhsl.craftattack.spawn.appliances.event; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.event;
import com.google.gson.Gson;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.api.HttpServer; import eu.mhsl.craftattack.spawn.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.api.client.repositories.EventRepository;
import eu.mhsl.craftattack.spawn.api.server.HttpServer;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.customAdvancements.Advancements; import eu.mhsl.craftattack.spawn.appliances.gameplay.customAdvancements.Advancements;
import eu.mhsl.craftattack.spawn.appliances.customAdvancements.CustomAdvancements; import eu.mhsl.craftattack.spawn.appliances.gameplay.customAdvancements.CustomAdvancements;
import eu.mhsl.craftattack.spawn.appliances.event.command.*; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.event.command.*;
import eu.mhsl.craftattack.spawn.appliances.event.listener.ApplyPendingRewardsListener;
import eu.mhsl.craftattack.spawn.util.IteratorUtil; import eu.mhsl.craftattack.spawn.util.IteratorUtil;
import eu.mhsl.craftattack.spawn.util.api.HttpStatus;
import eu.mhsl.craftattack.spawn.util.entity.DisplayVillager; import eu.mhsl.craftattack.spawn.util.entity.DisplayVillager;
import eu.mhsl.craftattack.spawn.util.listener.DismissInventoryOpenFromHolder; import eu.mhsl.craftattack.spawn.util.listener.DismissInventoryOpenFromHolder;
import eu.mhsl.craftattack.spawn.util.listener.PlayerInteractAtEntityEventListener; import eu.mhsl.craftattack.spawn.util.listener.PlayerInteractAtEntityEventListener;
@ -27,12 +28,6 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.*; import java.util.*;
public class Event extends Appliance { public class Event extends Appliance {
@ -57,7 +52,6 @@ public class Event extends Appliance {
private boolean isOpen = false; private boolean isOpen = false;
private AdvertisementStatus advertiseStatus = AdvertisementStatus.BEFORE; private AdvertisementStatus advertiseStatus = AdvertisementStatus.BEFORE;
private UUID roomId; private UUID roomId;
private final HttpClient eventServerClient = HttpClient.newHttpClient();
private final List<Reward> pendingRewards = new ArrayList<>(); private final List<Reward> pendingRewards = new ArrayList<>();
record RewardConfiguration(String memorialMaterial, String memorialTitle, String memorialLore, List<UUID> memorials, record RewardConfiguration(String memorialMaterial, String memorialTitle, String memorialLore, List<UUID> memorials,
@ -74,85 +68,67 @@ public class Event extends Appliance {
@Override @Override
public void onEnable() { public void onEnable() {
this.villager = new DisplayVillager.ConfigBound( this.villager = new DisplayVillager.ConfigBound(
localConfig(), this.localConfig(),
villager -> { villager -> {
villager.customName(Component.text("Events", NamedTextColor.GOLD)); villager.customName(Component.text("Events", NamedTextColor.GOLD));
villager.setProfession(Villager.Profession.LIBRARIAN); villager.setProfession(Villager.Profession.LIBRARIAN);
villager.setVillagerType(Villager.Type.SNOW); villager.setVillagerType(Villager.Type.SNOW);
} }
); );
this.isOpen = localConfig().getBoolean("enabled", false); this.isOpen = this.localConfig().getBoolean("enabled", false);
if(this.isOpen) this.roomId = UUID.fromString(localConfig().getString("roomId", "")); if(this.isOpen) this.roomId = UUID.fromString(this.localConfig().getString("roomId", ""));
} }
public void openEvent() throws URISyntaxException, IOException, InterruptedException { public void openEvent() {
if(isOpen) throw new ApplianceCommand.Error("Es läuft derzeit bereits ein Event!"); if(this.isOpen) throw new ApplianceCommand.Error("Es läuft derzeit bereits ein Event!");
HttpRequest createRoomRequest = HttpRequest.newBuilder()
.uri(new URI(localConfig().getString("api") + "/room"))
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> rawResponse = eventServerClient.send(createRoomRequest, HttpResponse.BodyHandlers.ofString()); Bukkit.getScheduler().runTaskAsynchronously(Main.instance(), () -> {
if(rawResponse.statusCode() != 200) ReqResp<EventRepository.CreatedRoom> sessionResponse = this.queryRepository(EventRepository.class).createSession();
throw new ApplianceCommand.Error("Event-Server meldet Fehler: " + rawResponse.statusCode());
record Response(UUID uuid) { if(sessionResponse.status() != HttpStatus.OK)
} throw new ApplianceCommand.Error("Event-Server meldet Fehler: " + sessionResponse.status());
Response response = new Gson().fromJson(rawResponse.body(), Response.class);
isOpen = true; this.isOpen = true;
roomId = response.uuid; this.roomId = sessionResponse.data().uuid();
});
} }
public void joinEvent(Player p) { public void joinEvent(Player p) {
if(!isOpen) { if(!this.isOpen) {
p.sendMessage(Component.text("Zurzeit ist kein Event geöffnet.", NamedTextColor.RED)); p.sendMessage(Component.text("Zurzeit ist kein Event geöffnet.", NamedTextColor.RED));
return; return;
} }
if(!p.hasPermission("admin") && advertiseStatus == AdvertisementStatus.BEFORE) { if(!p.hasPermission("admin") && this.advertiseStatus == AdvertisementStatus.BEFORE) {
p.sendMessage(Component.text("Die Event befinden sich noch in der Vorbereitung.", NamedTextColor.RED)); p.sendMessage(Component.text("Die Event befinden sich noch in der Vorbereitung.", NamedTextColor.RED));
return; return;
} }
if(!p.hasPermission("admin") && advertiseStatus == AdvertisementStatus.DONE) { if(!p.hasPermission("admin") && this.advertiseStatus == AdvertisementStatus.DONE) {
p.sendMessage(Component.text("Die Events laufen bereits. Ein nachträgliches Beitreten ist nicht möglich.", NamedTextColor.RED)); p.sendMessage(Component.text("Die Events laufen bereits. Ein nachträgliches Beitreten ist nicht möglich.", NamedTextColor.RED));
return; return;
} }
try {
Main.instance().getLogger().info("Verbinde mit eventserver: " + p.getName()); Main.instance().getLogger().info("Verbinde mit eventserver: " + p.getName());
p.sendMessage(Component.text("Authentifiziere...", NamedTextColor.GREEN)); p.sendMessage(Component.text("Authentifiziere...", NamedTextColor.GREEN));
record Request(UUID player, UUID room) {
}
Request request = new Request(p.getUniqueId(), this.roomId);
HttpRequest queueRoomRequest = HttpRequest.newBuilder()
.uri(new URI(localConfig().getString("api") + "/queueRoom"))
.POST(HttpRequest.BodyPublishers.ofString(new Gson().toJson(request)))
.build();
record Response(String error) { Bukkit.getScheduler().runTaskAsynchronously(Main.instance(), () -> {
} ReqResp<EventRepository.QueueRoom.Response> queueResponse = this.queryRepository(EventRepository.class)
HttpResponse<String> rawResponse = eventServerClient.send(queueRoomRequest, HttpResponse.BodyHandlers.ofString()); .queueRoom(new EventRepository.QueueRoom(p.getUniqueId(), this.roomId));
Main.instance().getLogger().info("Response: " + rawResponse.body());
Response response = new Gson().fromJson(rawResponse.body(), Response.class);
if(rawResponse.statusCode() != 200 || response.error != null) { if(queueResponse.status() != HttpStatus.OK || queueResponse.data().error() != null) {
p.sendMessage(Component.text("Fehler beim Betreten: " + response.error, NamedTextColor.RED)); p.sendMessage(Component.text("Fehler beim Betreten: " + queueResponse.data().error(), NamedTextColor.RED));
return; return;
} }
p.sendMessage(Component.text("Betrete...", NamedTextColor.GREEN)); p.sendMessage(Component.text("Betrete...", NamedTextColor.GREEN));
PluginMessage.connect(p, localConfig().getString("connect-server-name")); PluginMessage.connect(p, this.localConfig().getString("connect-server-name"));
});
} catch(URISyntaxException | IOException | InterruptedException e) {
throw new RuntimeException(e);
}
} }
public void endEvent() { public void endEvent() {
if(!isOpen) throw new ApplianceCommand.Error("Es läuft derzeit kein Event!"); if(!this.isOpen) throw new ApplianceCommand.Error("Es läuft derzeit kein Event!");
isOpen = false; this.isOpen = false;
} }
private void rewardPlayers(RewardConfiguration rewardConfiguration) { private void rewardPlayers(RewardConfiguration rewardConfiguration) {
@ -160,10 +136,10 @@ public class Event extends Appliance {
Reward reward = new Reward(uuid, new ItemStack(Objects.requireNonNull(Material.matchMaterial(rewardConfiguration.material)), amount)); Reward reward = new Reward(uuid, new ItemStack(Objects.requireNonNull(Material.matchMaterial(rewardConfiguration.material)), amount));
if(Bukkit.getPlayer(uuid) == null) { if(Bukkit.getPlayer(uuid) == null) {
pendingRewards.add(reward); this.pendingRewards.add(reward);
return; return;
} }
giveReward(reward); this.giveReward(reward);
}); });
rewardConfiguration.memorials.forEach(uuid -> { rewardConfiguration.memorials.forEach(uuid -> {
@ -177,10 +153,10 @@ public class Event extends Appliance {
Main.instance().getAppliance(CustomAdvancements.class).grantAdvancement(Advancements.participateEvent, uuid); Main.instance().getAppliance(CustomAdvancements.class).grantAdvancement(Advancements.participateEvent, uuid);
if(Bukkit.getPlayer(uuid) == null) { if(Bukkit.getPlayer(uuid) == null) {
pendingRewards.add(memorial); this.pendingRewards.add(memorial);
return; return;
} }
giveReward(memorial); this.giveReward(memorial);
}); });
rewardConfiguration.rewards.keySet().stream() rewardConfiguration.rewards.keySet().stream()
@ -208,7 +184,7 @@ public class Event extends Appliance {
} }
public void advertise() { public void advertise() {
advertiseCountdown.cancelIfRunning(); this.advertiseCountdown.cancelIfRunning();
this.advertiseStatus = AdvertisementStatus.ADVERTISED; this.advertiseStatus = AdvertisementStatus.ADVERTISED;
IteratorUtil.onlinePlayers(player -> player.sendMessage( IteratorUtil.onlinePlayers(player -> player.sendMessage(
Component.text() Component.text()
@ -219,7 +195,7 @@ public class Event extends Appliance {
.append(Component.text(", um dem Event beizutreten!")).appendNewline() .append(Component.text(", um dem Event beizutreten!")).appendNewline()
.append(Component.text("-".repeat(10), NamedTextColor.GRAY)).appendNewline() .append(Component.text("-".repeat(10), NamedTextColor.GRAY)).appendNewline()
)); ));
advertiseCountdown.start(); this.advertiseCountdown.start();
} }
@Override @Override
@ -247,7 +223,7 @@ public class Event extends Appliance {
protected List<Listener> listeners() { protected List<Listener> listeners() {
return List.of( return List.of(
new ApplyPendingRewardsListener(), new ApplyPendingRewardsListener(),
new PlayerInteractAtEntityEventListener(this.villager.getUniqueId(), playerInteractAtEntityEvent -> joinEvent(playerInteractAtEntityEvent.getPlayer())), new PlayerInteractAtEntityEventListener(this.villager.getUniqueId(), playerInteractAtEntityEvent -> this.joinEvent(playerInteractAtEntityEvent.getPlayer())),
new DismissInventoryOpenFromHolder(this.villager.getUniqueId()) new DismissInventoryOpenFromHolder(this.villager.getUniqueId())
); );
} }

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.event.command; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.event.command;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.event.Event; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.event.Event;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -13,6 +13,6 @@ public class EventAdvertiseCommand extends ApplianceCommand<Event> {
@Override @Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception {
getAppliance().advertise(); this.getAppliance().advertise();
} }
} }

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.event.command; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.event.command;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.event.Event; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.event.Event;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -13,6 +13,6 @@ public class EventCommand extends ApplianceCommand.PlayerChecked<Event> {
@Override @Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception {
getAppliance().joinEvent(getPlayer()); this.getAppliance().joinEvent(this.getPlayer());
} }
} }

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.event.command; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.event.command;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.event.Event; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.event.Event;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -13,6 +13,6 @@ public class EventEndSessionCommand extends ApplianceCommand<Event> {
@Override @Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
getAppliance().endEvent(); this.getAppliance().endEvent();
} }
} }

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.event.command; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.event.command;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.event.Event; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.event.Event;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -15,7 +15,7 @@ public class EventOpenSessionCommand extends ApplianceCommand<Event> {
@Override @Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception {
getAppliance().openEvent(); this.getAppliance().openEvent();
sender.sendMessage(Component.text("Event-Server erfolgreich gestartet!", NamedTextColor.GREEN)); sender.sendMessage(Component.text("Event-Server gestartet!", NamedTextColor.GREEN));
} }
} }

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.event.command; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.event.command;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.event.Event; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.event.Event;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -13,6 +13,6 @@ public class MoveEventVillagerCommand extends ApplianceCommand.PlayerChecked<Eve
@Override @Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
getAppliance().villager.updateLocation(getPlayer().getLocation()); this.getAppliance().villager.updateLocation(this.getPlayer().getLocation());
} }
} }

View File

@ -0,0 +1,77 @@
package eu.mhsl.craftattack.spawn.appliances.metaGameplay.feedback;
import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.api.client.ReqResp;
import eu.mhsl.craftattack.spawn.api.client.repositories.FeedbackRepository;
import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.util.api.HttpStatus;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentBuilder;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class Feedback extends Appliance {
public Feedback() {
super("feedback");
}
public void requestFeedback(String eventName, List<Player> receivers, @Nullable String question) {
ReqResp<Map<UUID, String>> response = this.queryRepository(FeedbackRepository.class).createFeedbackUrls(
new FeedbackRepository.Request(eventName, receivers.stream().map(Entity::getUniqueId).toList())
);
System.out.println(response.toString());
System.out.println(response.status());
if(response.status() != HttpStatus.CREATED) throw new RuntimeException();
Component border = Component.text("-".repeat(40), NamedTextColor.GRAY);
receivers.forEach(player -> {
String feedbackUrl = response.data().get(player.getUniqueId());
if(feedbackUrl == null) {
Main.logger().warning(String.format("FeedbackUrl not found for player '%s' from backend!", player.getUniqueId()));
return;
}
ComponentBuilder<TextComponent, TextComponent.Builder> message = Component.text()
.append(border)
.appendNewline();
if(question != null) {
message
.append(Component.text(question, NamedTextColor.GREEN))
.appendNewline()
.appendNewline();
}
message
.append(Component.text("Klicke hier und gib uns Feedback, damit wir dein Spielerlebnis verbessern können!", NamedTextColor.DARK_GREEN)
.clickEvent(ClickEvent.openUrl(feedbackUrl)))
.hoverEvent(HoverEvent.showText(Component.text("Klicke, um Feedback zu geben.")))
.appendNewline()
.append(border);
player.sendMessage(message.build());
});
}
@Override
protected @NotNull List<ApplianceCommand<?>> commands() {
return List.of(
new FeedbackCommand(),
new RequestFeedbackCommand()
);
}
}

View File

@ -0,0 +1,30 @@
package eu.mhsl.craftattack.spawn.appliances.metaGameplay.feedback;
import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.util.text.ComponentUtil;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.List;
class FeedbackCommand extends ApplianceCommand.PlayerChecked<Feedback> {
public FeedbackCommand() {
super("feedback");
}
@Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception {
sender.sendMessage(ComponentUtil.pleaseWait());
Bukkit.getScheduler().runTaskAsynchronously(
Main.instance(),
() -> this.getAppliance().requestFeedback(
"self-issued-ingame",
List.of(this.getPlayer()),
null
)
);
}
}

View File

@ -0,0 +1,27 @@
package eu.mhsl.craftattack.spawn.appliances.metaGameplay.feedback;
import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
class RequestFeedbackCommand extends ApplianceCommand<Feedback> {
public RequestFeedbackCommand() {
super("requestFeedback");
}
@Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception {
Bukkit.getScheduler().runTaskAsynchronously(
Main.instance(),
() -> this.getAppliance().requestFeedback(
"admin-issued-ingame",
new ArrayList<>(Bukkit.getOnlinePlayers()), String.join(" ", args)
)
);
}
}

View File

@ -1,11 +1,11 @@
package eu.mhsl.craftattack.spawn.appliances.help; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.help;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.help.command.DiscordCommand; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.help.command.DiscordCommand;
import eu.mhsl.craftattack.spawn.appliances.help.command.HelpCommand; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.help.command.HelpCommand;
import eu.mhsl.craftattack.spawn.appliances.help.command.SpawnCommand; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.help.command.SpawnCommand;
import eu.mhsl.craftattack.spawn.appliances.help.command.TeamspeakCommand; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.help.command.TeamspeakCommand;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;

View File

@ -1,8 +1,9 @@
package eu.mhsl.craftattack.spawn.appliances.help.command; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.help.command;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.help.Help; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.help.Help;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -13,11 +14,14 @@ public class DiscordCommand extends ApplianceCommand<Help> {
super("discord"); super("discord");
} }
private final static String discordLink = "https://discord.gg/TXxspGVanq";
@Override @Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception {
sender.sendMessage( sender.sendMessage(
Component.text("Einen offiziellen Discord Server gibt es nicht, aber Du kannst gerne unserem Teamspeak joinen: ", NamedTextColor.GOLD) Component.text("Offizieller Discord Server: ", NamedTextColor.GOLD)
.append(Component.text("mhsl.eu", NamedTextColor.AQUA)) .append(Component.text(discordLink, NamedTextColor.AQUA))
.clickEvent(ClickEvent.openUrl(discordLink))
); );
} }
} }

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.help.command; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.help.command;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.help.Help; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.help.Help;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -18,7 +18,8 @@ public class HelpCommand extends ApplianceCommand<Help> {
sender.sendMessage( sender.sendMessage(
Component.text("Willkommen auf Craftattack!", NamedTextColor.GOLD) Component.text("Willkommen auf Craftattack!", NamedTextColor.GOLD)
.appendNewline() .appendNewline()
.append(Component.text("Hier ist ein Hilfetext!", NamedTextColor.GRAY)) .append(Component.text("Wenn du hilfe benötigst kannst du dich jederzeit an einen Admin wenden." +
" Weitere Informationen zu Funktionen und Befehlen erhältst du zudem im Turm am Spawn.", NamedTextColor.GRAY))
); );
} }
} }

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.help.command; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.help.command;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.help.Help; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.help.Help;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -19,8 +19,8 @@ public class SpawnCommand extends ApplianceCommand<Help> {
@Override @Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(!getAppliance().localConfig().isString(spawnKey)) if(!this.getAppliance().localConfig().isString(spawnKey))
throw new ApplianceCommand.Error("Es wurde kein Spawnbereich hinterlegt!"); throw new ApplianceCommand.Error("Es wurde kein Spawnbereich hinterlegt!");
sender.sendMessage(Component.text(Objects.requireNonNull(getAppliance().localConfig().getString(spawnKey)), NamedTextColor.GOLD)); sender.sendMessage(Component.text(Objects.requireNonNull(this.getAppliance().localConfig().getString(spawnKey)), NamedTextColor.GOLD));
} }
} }

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.help.command; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.help.command;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.help.Help; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.help.Help;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -17,12 +17,12 @@ public class TeamspeakCommand extends ApplianceCommand<Help> {
@Override @Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(!getAppliance().localConfig().isString(teamspeakKey)) if(!this.getAppliance().localConfig().isString(teamspeakKey))
throw new ApplianceCommand.Error("Es wurde kein Teamspeak hinterlegt!"); throw new ApplianceCommand.Error("Es wurde kein Teamspeak hinterlegt!");
sender.sendMessage( sender.sendMessage(
Component.text() Component.text()
.append(Component.text("Joine unserem Teamspeak: ", NamedTextColor.GOLD)) .append(Component.text("Joine unserem Teamspeak: ", NamedTextColor.GOLD))
.append(getTeamspeakIp(getAppliance().localConfig().getString(teamspeakKey))) .append(this.getTeamspeakIp(this.getAppliance().localConfig().getString(teamspeakKey)))
); );
} }

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.infoBars; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.infoBars;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.bossbar.BossBar;
@ -56,7 +56,9 @@ public abstract class Bar {
return Math.clamp(this.progress(), 0, 1); return Math.clamp(this.progress(), 0, 1);
} }
protected void beforeRefresh() {} protected void beforeRefresh() {
}
protected abstract Duration refresh(); protected abstract Duration refresh();
protected abstract String name(); protected abstract String name();

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.infoBars; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.infoBars;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import org.bukkit.command.Command; import org.bukkit.command.Command;
@ -8,7 +8,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.List; import java.util.List;
public class InfoBarCommand extends ApplianceCommand.PlayerChecked<InfoBars> { class InfoBarCommand extends ApplianceCommand.PlayerChecked<InfoBars> {
public InfoBarCommand() { public InfoBarCommand() {
super("infobar"); super("infobar");
} }
@ -17,9 +17,9 @@ public class InfoBarCommand extends ApplianceCommand.PlayerChecked<InfoBars> {
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception {
if(args.length == 0) throw new Error("<show|hide|hideall> [bar name]"); if(args.length == 0) throw new Error("<show|hide|hideall> [bar name]");
switch(args[0]) { switch(args[0]) {
case "hideAll" -> getAppliance().hideAll(getPlayer()); case "hideAll" -> this.getAppliance().hideAll(this.getPlayer());
case "show" -> getAppliance().show(getPlayer(), args[1]); case "show" -> this.getAppliance().show(this.getPlayer(), args[1]);
case "hide" -> getAppliance().hide(getPlayer(), args[1]); case "hide" -> this.getAppliance().hide(this.getPlayer(), args[1]);
default -> throw new Error("Erlaubte Optionen sind 'show', 'hide', 'hideAll'!"); default -> throw new Error("Erlaubte Optionen sind 'show', 'hide', 'hideAll'!");
} }
} }
@ -27,6 +27,6 @@ public class InfoBarCommand extends ApplianceCommand.PlayerChecked<InfoBars> {
@Override @Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(args.length == 1) return List.of("show", "hide", "hideAll"); if(args.length == 1) return List.of("show", "hide", "hideAll");
return getAppliance().getInfoBars().stream().map(Bar::name).toList(); return this.getAppliance().getInfoBars().stream().map(Bar::name).toList();
} }
} }

View File

@ -1,11 +1,11 @@
package eu.mhsl.craftattack.spawn.appliances.infoBars; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.infoBars;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.infoBars.bars.MsptBar; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.infoBars.bars.MsptBar;
import eu.mhsl.craftattack.spawn.appliances.infoBars.bars.PlayerCounterBar; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.infoBars.bars.PlayerCounterBar;
import eu.mhsl.craftattack.spawn.appliances.infoBars.bars.TpsBar; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.infoBars.bars.TpsBar;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@ -51,32 +51,33 @@ public class InfoBars extends Appliance {
private List<String> getStoredBars(Player player) { private List<String> getStoredBars(Player player) {
PersistentDataContainer container = player.getPersistentDataContainer(); PersistentDataContainer container = player.getPersistentDataContainer();
if(!container.has(infoBarKey)) return List.of(); if(!container.has(this.infoBarKey)) return List.of();
return container.get(infoBarKey, PersistentDataType.LIST.strings()); return container.get(this.infoBarKey, PersistentDataType.LIST.strings());
} }
private void setStoredBars(Player player, List<String> bars) { private void setStoredBars(Player player, List<String> bars) {
player.getPersistentDataContainer().set(infoBarKey, PersistentDataType.LIST.strings(), bars); player.getPersistentDataContainer().set(this.infoBarKey, PersistentDataType.LIST.strings(), bars);
} }
private Bar getBarByName(String name) { private Bar getBarByName(String name) {
return infoBars.stream() return this.infoBars.stream()
.filter(bar -> bar.name().equalsIgnoreCase(name)) .filter(bar -> bar.name().equalsIgnoreCase(name))
.findFirst() .findFirst()
.orElse(null); .orElse(null);
} }
private void validateBarName(String name) { private void validateBarName(String name) {
if(getBarByName(name) == null) throw new ApplianceCommand.Error(String.format("Ungültiger infobar name '%s'", name)); if(this.getBarByName(name) == null)
throw new ApplianceCommand.Error(String.format("Ungültiger infobar name '%s'", name));
} }
public List<Bar> getInfoBars() { public List<Bar> getInfoBars() {
return infoBars; return this.infoBars;
} }
@Override @Override
public void onDisable() { public void onDisable() {
infoBars.forEach(Bar::stopUpdate); this.infoBars.forEach(Bar::stopUpdate);
} }
@Override @Override

View File

@ -1,12 +1,12 @@
package eu.mhsl.craftattack.spawn.appliances.infoBars; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.infoBars;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
public class ShowPreviousBarsListener extends ApplianceListener<InfoBars> { class ShowPreviousBarsListener extends ApplianceListener<InfoBars> {
@EventHandler @EventHandler
public void onJoin(PlayerJoinEvent event) { public void onJoin(PlayerJoinEvent event) {
getAppliance().showAll(event.getPlayer()); // this.getAppliance().showAll(event.getPlayer());
} }
} }

View File

@ -1,6 +1,6 @@
package eu.mhsl.craftattack.spawn.appliances.infoBars.bars; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.infoBars.bars;
import eu.mhsl.craftattack.spawn.appliances.infoBars.Bar; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.infoBars.Bar;
import eu.mhsl.craftattack.spawn.util.statistics.ServerMonitor; import eu.mhsl.craftattack.spawn.util.statistics.ServerMonitor;
import eu.mhsl.craftattack.spawn.util.text.ColorUtil; import eu.mhsl.craftattack.spawn.util.text.ColorUtil;
import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.bossbar.BossBar;

View File

@ -1,8 +1,8 @@
package eu.mhsl.craftattack.spawn.appliances.infoBars.bars; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.infoBars.bars;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliances.infoBars.Bar; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.infoBars.Bar;
import eu.mhsl.craftattack.spawn.appliances.playerlimit.PlayerLimit; import eu.mhsl.craftattack.spawn.appliances.tooling.playerlimit.PlayerLimit;
import eu.mhsl.craftattack.spawn.util.text.ColorUtil; import eu.mhsl.craftattack.spawn.util.text.ColorUtil;
import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;

View File

@ -1,6 +1,6 @@
package eu.mhsl.craftattack.spawn.appliances.infoBars.bars; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.infoBars.bars;
import eu.mhsl.craftattack.spawn.appliances.infoBars.Bar; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.infoBars.Bar;
import eu.mhsl.craftattack.spawn.util.text.ColorUtil; import eu.mhsl.craftattack.spawn.util.text.ColorUtil;
import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.optionLinks; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.optionLinks;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
@ -17,10 +17,17 @@ import java.util.logging.Level;
@SuppressWarnings("UnstableApiUsage") @SuppressWarnings("UnstableApiUsage")
public class OptionLinks extends Appliance { public class OptionLinks extends Appliance {
record ComponentSupplier() {} record ComponentSupplier() {
record UriSupplier(Player player) {} }
record UriConsumer(String uri) {}
record SuppliedLink(Function<ComponentSupplier, Component> component, Function<UriSupplier, UriConsumer> uri) {} record UriSupplier(Player player) {
}
record UriConsumer(String uri) {
}
record SuppliedLink(Function<ComponentSupplier, Component> component, Function<UriSupplier, UriConsumer> uri) {
}
List<SuppliedLink> links = List.of( List<SuppliedLink> links = List.of(
new SuppliedLink( new SuppliedLink(

View File

@ -1,12 +1,12 @@
package eu.mhsl.craftattack.spawn.appliances.optionLinks; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.optionLinks;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
public class UpdateLinksListener extends ApplianceListener<OptionLinks> { class UpdateLinksListener extends ApplianceListener<OptionLinks> {
@EventHandler @EventHandler
public void onJoin(PlayerJoinEvent event) { public void onJoin(PlayerJoinEvent event) {
getAppliance().setServerLinks(event.getPlayer()); this.getAppliance().setServerLinks(event.getPlayer());
} }
} }

View File

@ -1,18 +1,19 @@
package eu.mhsl.craftattack.spawn.appliances.packSelect; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class ChangePackCommand extends ApplianceCommand.PlayerChecked<PackSelect> { class ChangePackCommand extends ApplianceCommand.PlayerChecked<PackSelect> {
public static final String commandName = "texturepack"; public static final String commandName = "texturepack";
public ChangePackCommand() { public ChangePackCommand() {
super(commandName); super(commandName);
} }
@Override @Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception {
getAppliance().openPackInventory(getPlayer()); this.getAppliance().openPackInventory(this.getPlayer());
} }
} }

View File

@ -1,6 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.packSelect; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect;
import com.google.gson.*; import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import eu.mhsl.craftattack.spawn.appliance.CachedApplianceSupplier; import eu.mhsl.craftattack.spawn.appliance.CachedApplianceSupplier;
import eu.mhsl.craftattack.spawn.util.inventory.HeadBuilder; import eu.mhsl.craftattack.spawn.util.inventory.HeadBuilder;
import eu.mhsl.craftattack.spawn.util.text.ComponentUtil; import eu.mhsl.craftattack.spawn.util.text.ComponentUtil;
@ -17,15 +18,15 @@ import java.util.stream.Collectors;
public class PackConfiguration extends CachedApplianceSupplier<PackSelect> { public class PackConfiguration extends CachedApplianceSupplier<PackSelect> {
public record Pack(UUID id, String name, String description, String author, ResourcePackInfo info, String icon) { public record Pack(UUID id, String name, String description, String author, ResourcePackInfo info, String icon) {
public ItemStack buildItem() { public ItemStack buildItem() {
ItemStack stack = HeadBuilder.getCustomTextureHead(icon); ItemStack stack = HeadBuilder.getCustomTextureHead(this.icon);
ItemMeta meta = stack.getItemMeta(); ItemMeta meta = stack.getItemMeta();
meta.itemName(Component.text(id.toString())); meta.itemName(Component.text(this.id.toString()));
meta.displayName(Component.text(name(), NamedTextColor.GOLD)); meta.displayName(Component.text(this.name(), NamedTextColor.GOLD));
List<Component> lore = new ArrayList<>(); List<Component> lore = new ArrayList<>();
lore.add(Component.text("Autor: ", NamedTextColor.DARK_GRAY).append(Component.text(author))); lore.add(Component.text("Autor: ", NamedTextColor.DARK_GRAY).append(Component.text(this.author)));
lore.add(Component.text(" ")); lore.add(Component.text(" "));
lore.addAll( lore.addAll(
ComponentUtil.lineBreak(description()) ComponentUtil.lineBreak(this.description())
.map(s -> Component.text(s, NamedTextColor.GRAY)) .map(s -> Component.text(s, NamedTextColor.GRAY))
.toList() .toList()
); );
@ -38,20 +39,23 @@ public class PackConfiguration extends CachedApplianceSupplier<PackSelect> {
public boolean equalsItem(ItemStack other) { public boolean equalsItem(ItemStack other) {
String itemName = PlainTextComponentSerializer.plainText().serialize(other.getItemMeta().itemName()); String itemName = PlainTextComponentSerializer.plainText().serialize(other.getItemMeta().itemName());
try { try {
return UUID.fromString(itemName).equals(id); return UUID.fromString(itemName).equals(this.id);
} catch(IllegalArgumentException ignored) { } catch(IllegalArgumentException ignored) {
return false; return false;
} }
} }
} }
public record PackList(List<Pack> packs) { public record PackList(List<Pack> packs) {
public Optional<Pack> findFromItem(ItemStack itemStack) { public Optional<Pack> findFromItem(ItemStack itemStack) {
return packs.stream() return this.packs.stream()
.filter(pack -> pack.equalsItem(itemStack)) .filter(pack -> pack.equalsItem(itemStack))
.findFirst(); .findFirst();
} }
} }
public record SerializedPackList(List<UUID> packs) {}
public record SerializedPackList(List<UUID> packs) {
}
private final PackList packList; private final PackList packList;
private final Gson gson = new GsonBuilder().create(); private final Gson gson = new GsonBuilder().create();
@ -61,9 +65,9 @@ public class PackConfiguration extends CachedApplianceSupplier<PackSelect> {
} }
private PackConfiguration(String data) { private PackConfiguration(String data) {
SerializedPackList serializedData = gson.fromJson(data, SerializedPackList.class); SerializedPackList serializedData = this.gson.fromJson(data, SerializedPackList.class);
var availablePackMap = getAppliance().availablePacks.packs().stream() var availablePackMap = this.getAppliance().availablePacks.packs().stream()
.collect(Collectors.toMap(PackConfiguration.Pack::id, pack -> pack)); .collect(Collectors.toMap(PackConfiguration.Pack::id, pack -> pack));
this.packList = new PackList( this.packList = new PackList(
@ -73,7 +77,8 @@ public class PackConfiguration extends CachedApplianceSupplier<PackSelect> {
.collect(Collectors.toList()) .collect(Collectors.toList())
); );
if (this.packList.packs().isEmpty()) throw new IllegalArgumentException("Serialized data does not contain any valid data!"); if(this.packList.packs().isEmpty())
throw new IllegalArgumentException("Serialized data does not contain any valid data!");
} }
public static PackConfiguration deserialize(String data) { public static PackConfiguration deserialize(String data) {
@ -85,10 +90,10 @@ public class PackConfiguration extends CachedApplianceSupplier<PackSelect> {
} }
public String serialize() { public String serialize() {
return gson.toJson(new SerializedPackList(this.packList.packs().stream().map(Pack::id).toList())); return this.gson.toJson(new SerializedPackList(this.packList.packs().stream().map(Pack::id).toList()));
} }
public List<Pack> getPackList() { public List<Pack> getPackList() {
return packList.packs(); return this.packList.packs();
} }
} }

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.packSelect; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.CachedApplianceSupplier; import eu.mhsl.craftattack.spawn.appliance.CachedApplianceSupplier;
@ -58,99 +58,99 @@ public class PackConfigurationInventory extends CachedApplianceSupplier<PackSele
} }
public Inventory getInventory() { public Inventory getInventory() {
return inventory; return this.inventory;
} }
public void handleClick(@Nullable ItemStack clickedItem, int slot, ClickType clickType) { public void handleClick(@Nullable ItemStack clickedItem, int slot, ClickType clickType) {
if(clickedItem == null) return; if(clickedItem == null) return;
if(clickedItem.equals(reset)) reset(); if(clickedItem.equals(this.reset)) this.reset();
if(clickedItem.equals(save)) apply(); if(clickedItem.equals(this.save)) this.apply();
if(slot >= 9 && slot < 9 * 4) { if(slot >= 9 && slot < 9 * 4) {
getAppliance().availablePacks.findFromItem(clickedItem) this.getAppliance().availablePacks.findFromItem(clickedItem)
.ifPresent(this::toggle); .ifPresent(this::toggle);
} }
if(slot >= 9 * 5) { if(slot >= 9 * 5) {
getAppliance().availablePacks.findFromItem(clickedItem) this.getAppliance().availablePacks.findFromItem(clickedItem)
.ifPresent(pack -> { .ifPresent(pack -> {
switch(clickType) { switch(clickType) {
case RIGHT -> move(pack, true); case RIGHT -> this.move(pack, true);
case LEFT -> move(pack, false); case LEFT -> this.move(pack, false);
case MIDDLE -> toggle(pack); case MIDDLE -> this.toggle(pack);
} }
}); });
} }
} }
private void move(PackConfiguration.Pack pack, boolean moveToRight) { private void move(PackConfiguration.Pack pack, boolean moveToRight) {
List<PackConfiguration.Pack> packs = packConfiguration.getPackList(); List<PackConfiguration.Pack> packs = this.packConfiguration.getPackList();
int index = packs.indexOf(pack); int index = packs.indexOf(pack);
if (index != -1) { if(index != -1) {
int newIndex = moveToRight ? index + 1 : index - 1; int newIndex = moveToRight ? index + 1 : index - 1;
if (newIndex >= 0 && newIndex < packs.size()) Collections.swap(packs, index, newIndex); if(newIndex >= 0 && newIndex < packs.size()) Collections.swap(packs, index, newIndex);
} }
InteractSounds.of(inventoryOwner).click(); InteractSounds.of(this.inventoryOwner).click();
draw(); this.draw();
} }
private void toggle(PackConfiguration.Pack pack) { private void toggle(PackConfiguration.Pack pack) {
if(packConfiguration.getPackList().contains(pack)) { if(this.packConfiguration.getPackList().contains(pack)) {
packConfiguration.getPackList().remove(pack); this.packConfiguration.getPackList().remove(pack);
} else { } else {
packConfiguration.getPackList().add(pack); this.packConfiguration.getPackList().add(pack);
} }
InteractSounds.of(inventoryOwner).click(); InteractSounds.of(this.inventoryOwner).click();
draw(); this.draw();
} }
private void reset() { private void reset() {
packConfiguration.getPackList().clear(); this.packConfiguration.getPackList().clear();
InteractSounds.of(inventoryOwner).delete(); InteractSounds.of(this.inventoryOwner).delete();
draw(); this.draw();
} }
private void apply() { private void apply() {
inventoryOwner.closeInventory(); this.inventoryOwner.closeInventory();
InteractSounds.of(inventoryOwner).success(); InteractSounds.of(this.inventoryOwner).success();
Bukkit.getScheduler().runTask(Main.instance(), () -> getAppliance().setPack(inventoryOwner, packConfiguration)); Bukkit.getScheduler().runTask(Main.instance(), () -> this.getAppliance().setPack(this.inventoryOwner, this.packConfiguration));
} }
private void draw() { private void draw() {
inventory.clear(); this.inventory.clear();
inventory.setItem(0, packConfiguration.getPackList().isEmpty() ? PlaceholderItems.grayStainedGlassPane : reset); this.inventory.setItem(0, this.packConfiguration.getPackList().isEmpty() ? PlaceholderItems.grayStainedGlassPane : this.reset);
IteratorUtil.times(3, () -> inventory.addItem(PlaceholderItems.grayStainedGlassPane)); IteratorUtil.times(3, () -> this.inventory.addItem(PlaceholderItems.grayStainedGlassPane));
inventory.setItem(4, info); this.inventory.setItem(4, this.info);
IteratorUtil.times(3, () -> inventory.addItem(PlaceholderItems.grayStainedGlassPane)); IteratorUtil.times(3, () -> this.inventory.addItem(PlaceholderItems.grayStainedGlassPane));
inventory.setItem(8, save); this.inventory.setItem(8, this.save);
IteratorUtil.iterateListInGlobal( IteratorUtil.iterateListInGlobal(
9, 9,
getAppliance().availablePacks.packs().stream() this.getAppliance().availablePacks.packs().stream()
.filter(pack -> !packConfiguration.getPackList().contains(pack)) .filter(pack -> !this.packConfiguration.getPackList().contains(pack))
.limit(9 * 3) .limit(9 * 3)
.map(pack -> { .map(pack -> {
ItemBuilder stack = ItemBuilder.of(pack.buildItem()); ItemBuilder stack = ItemBuilder.of(pack.buildItem());
if(packConfiguration.getPackList().contains(pack)) stack.glint(); if(this.packConfiguration.getPackList().contains(pack)) stack.glint();
return stack.build(); return stack.build();
}) })
.toList(), .toList(),
inventory::setItem this.inventory::setItem
); );
IntStream.range(9 * 4, 9 * 5) IntStream.range(9 * 4, 9 * 5)
.forEach(slot -> inventory.setItem(slot, PlaceholderItems.grayStainedGlassPane)); .forEach(slot -> this.inventory.setItem(slot, PlaceholderItems.grayStainedGlassPane));
IteratorUtil.iterateListInGlobal( IteratorUtil.iterateListInGlobal(
9 * 5, 9 * 5,
IteratorUtil.expandList( IteratorUtil.expandList(
IntStream.range(0, Math.min(packConfiguration.getPackList().size(), 9)) IntStream.range(0, Math.min(this.packConfiguration.getPackList().size(), 9))
.mapToObj(i -> { .mapToObj(i -> {
PackConfiguration.Pack pack = packConfiguration.getPackList().get(i); PackConfiguration.Pack pack = this.packConfiguration.getPackList().get(i);
ItemBuilder builder = ItemBuilder.of(pack.buildItem()); ItemBuilder builder = ItemBuilder.of(pack.buildItem());
builder builder
@ -162,9 +162,9 @@ public class PackConfigurationInventory extends CachedApplianceSupplier<PackSele
}) })
.toList(), .toList(),
9, 9,
unusedSlot this.unusedSlot
), ),
inventory::setItem this.inventory::setItem
); );
} }

View File

@ -1,12 +1,12 @@
package eu.mhsl.craftattack.spawn.appliances.packSelect; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.packSelect.listeners.ClosePackInventoryListener; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect.listeners.ClickPackInventoryListener;
import eu.mhsl.craftattack.spawn.appliances.packSelect.listeners.ClickPackInventoryListener; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect.listeners.ClosePackInventoryListener;
import eu.mhsl.craftattack.spawn.appliances.packSelect.listeners.SetPacksOnJoinListener; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect.listeners.SetPacksOnJoinListener;
import eu.mhsl.craftattack.spawn.appliances.settings.Settings; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.Settings;
import net.kyori.adventure.resource.ResourcePackInfo; import net.kyori.adventure.resource.ResourcePackInfo;
import net.kyori.adventure.resource.ResourcePackRequest; import net.kyori.adventure.resource.ResourcePackRequest;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -37,7 +37,7 @@ public class PackSelect extends Appliance {
public void onEnable() { public void onEnable() {
Settings.instance().declareSetting(PackSelectSetting.class); Settings.instance().declareSetting(PackSelectSetting.class);
List<Map<?, ?>> packs = localConfig().getMapList("packs"); List<Map<?, ?>> packs = this.localConfig().getMapList("packs");
Bukkit.getScheduler().runTaskAsynchronously( Bukkit.getScheduler().runTaskAsynchronously(
Main.instance(), Main.instance(),
() -> packs.stream() () -> packs.stream()
@ -58,8 +58,8 @@ public class PackSelect extends Appliance {
resourcePackInfo, resourcePackInfo,
packData.get("icon") packData.get("icon")
); );
availablePacks.packs().add(packToAdd); this.availablePacks.packs().add(packToAdd);
} catch (Exception e) { } catch(Exception e) {
Main.logger().warning(String.format("Failed to add pack %s: %s", packData.get("name"), e.getMessage())); Main.logger().warning(String.format("Failed to add pack %s: %s", packData.get("name"), e.getMessage()));
} }
}) })
@ -78,9 +78,9 @@ public class PackSelect extends Appliance {
} }
public void openPackInventory(Player player) { public void openPackInventory(Player player) {
PackConfigurationInventory packInventory = new PackConfigurationInventory(getPackConfigurationForPlayer(player), player); PackConfigurationInventory packInventory = new PackConfigurationInventory(this.getPackConfigurationForPlayer(player), player);
player.openInventory(packInventory.getInventory()); player.openInventory(packInventory.getInventory());
openInventories.put(player, packInventory); this.openInventories.put(player, packInventory);
} }
public void setPack(Player player, PackConfiguration packConfiguration) { public void setPack(Player player, PackConfiguration packConfiguration) {

View File

@ -1,9 +1,9 @@
package eu.mhsl.craftattack.spawn.appliances.packSelect; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliances.settings.CategorizedSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.CategorizedSetting;
import eu.mhsl.craftattack.spawn.appliances.settings.SettingCategory; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.SettingCategory;
import eu.mhsl.craftattack.spawn.appliances.settings.datatypes.ActionSetting; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.settings.datatypes.ActionSetting;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;

View File

@ -1,4 +1,4 @@
package eu.mhsl.craftattack.spawn.appliances.packSelect; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import net.kyori.adventure.resource.ResourcePackInfo; import net.kyori.adventure.resource.ResourcePackInfo;
@ -12,14 +12,14 @@ import java.security.MessageDigest;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class ResourcePackInfoFactory { class ResourcePackInfoFactory {
private static boolean isValidHash(@Nullable String hash) { private static boolean isValidHash(@Nullable String hash) {
return hash != null && hash.length() == 40; return hash != null && hash.length() == 40;
} }
public static @NotNull CompletableFuture<ResourcePackInfo> createResourcePackInfo(@NotNull URI resourcePackUrl, @Nullable String hash) { public static @NotNull CompletableFuture<ResourcePackInfo> createResourcePackInfo(@NotNull URI resourcePackUrl, @Nullable String hash) {
if (isValidHash(hash)) { if(isValidHash(hash)) {
return CompletableFuture.completedFuture( return CompletableFuture.completedFuture(
ResourcePackInfo.resourcePackInfo(UUID.nameUUIDFromBytes(hash.getBytes()), resourcePackUrl, hash) ResourcePackInfo.resourcePackInfo(UUID.nameUUIDFromBytes(hash.getBytes()), resourcePackUrl, hash)
); );
@ -32,11 +32,11 @@ public class ResourcePackInfoFactory {
connection.setRequestMethod("GET"); connection.setRequestMethod("GET");
connection.connect(); connection.connect();
try (InputStream inputStream = connection.getInputStream()) { try(InputStream inputStream = connection.getInputStream()) {
MessageDigest sha1Digest = MessageDigest.getInstance("SHA-1"); MessageDigest sha1Digest = MessageDigest.getInstance("SHA-1");
byte[] buffer = new byte[1024]; byte[] buffer = new byte[1024];
int bytesRead; int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) { while((bytesRead = inputStream.read(buffer)) != -1) {
sha1Digest.update(buffer, 0, bytesRead); sha1Digest.update(buffer, 0, bytesRead);
} }
String sha1Hex = bytesToHex(sha1Digest.digest()); String sha1Hex = bytesToHex(sha1Digest.digest());
@ -44,7 +44,7 @@ public class ResourcePackInfoFactory {
Main.logger().info(String.format("Calculating SHA1 Hash of %s completed: %s", resourcePackUrl, sha1Hex)); Main.logger().info(String.format("Calculating SHA1 Hash of %s completed: %s", resourcePackUrl, sha1Hex));
return ResourcePackInfo.resourcePackInfo(UUID.nameUUIDFromBytes(sha1Hex.getBytes()), resourcePackUrl, sha1Hex); return ResourcePackInfo.resourcePackInfo(UUID.nameUUIDFromBytes(sha1Hex.getBytes()), resourcePackUrl, sha1Hex);
} }
} catch (Exception e) { } catch(Exception e) {
String error = String.format("Error whilst SHA1 calculation of %s: %s", resourcePackUrl, e.getMessage()); String error = String.format("Error whilst SHA1 calculation of %s: %s", resourcePackUrl, e.getMessage());
Main.logger().warning(error); Main.logger().warning(error);
throw new RuntimeException(error); throw new RuntimeException(error);
@ -54,7 +54,7 @@ public class ResourcePackInfoFactory {
private static String bytesToHex(byte[] bytes) { private static String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder(bytes.length * 2); StringBuilder hexString = new StringBuilder(bytes.length * 2);
for (byte b : bytes) { for(byte b : bytes) {
hexString.append(String.format("%02x", b)); hexString.append(String.format("%02x", b));
} }
return hexString.toString(); return hexString.toString();

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.packSelect.listeners; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect.listeners;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import eu.mhsl.craftattack.spawn.appliances.packSelect.PackSelect; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect.PackSelect;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
@ -10,10 +10,10 @@ public class ClickPackInventoryListener extends ApplianceListener<PackSelect> {
@EventHandler @EventHandler
public void interact(InventoryClickEvent event) { public void interact(InventoryClickEvent event) {
if(!(event.getWhoClicked() instanceof Player player)) return; if(!(event.getWhoClicked() instanceof Player player)) return;
if(getAppliance().isNotPackInventory(player, event.getInventory())) return; if(this.getAppliance().isNotPackInventory(player, event.getInventory())) return;
event.setCancelled(true); event.setCancelled(true);
getAppliance().openInventories.get(player).handleClick( this.getAppliance().openInventories.get(player).handleClick(
event.getCurrentItem(), event.getCurrentItem(),
event.getSlot(), event.getSlot(),
event.getClick() event.getClick()

View File

@ -1,7 +1,7 @@
package eu.mhsl.craftattack.spawn.appliances.packSelect.listeners; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect.listeners;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import eu.mhsl.craftattack.spawn.appliances.packSelect.PackSelect; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect.PackSelect;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryCloseEvent;
@ -10,7 +10,7 @@ public class ClosePackInventoryListener extends ApplianceListener<PackSelect> {
@EventHandler @EventHandler
public void onClose(InventoryCloseEvent event) { public void onClose(InventoryCloseEvent event) {
if(!(event.getPlayer() instanceof Player player)) return; if(!(event.getPlayer() instanceof Player player)) return;
if(getAppliance().isNotPackInventory(player, event.getInventory())) return; if(this.getAppliance().isNotPackInventory(player, event.getInventory())) return;
getAppliance().openInventories.remove(player); this.getAppliance().openInventories.remove(player);
} }
} }

View File

@ -1,8 +1,8 @@
package eu.mhsl.craftattack.spawn.appliances.packSelect.listeners; package eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect.listeners;
import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import eu.mhsl.craftattack.spawn.appliances.packSelect.PackSelect; import eu.mhsl.craftattack.spawn.appliances.metaGameplay.packSelect.PackSelect;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
@ -12,7 +12,7 @@ public class SetPacksOnJoinListener extends ApplianceListener<PackSelect> {
public void onJoin(PlayerJoinEvent event) { public void onJoin(PlayerJoinEvent event) {
Bukkit.getScheduler().runTask( Bukkit.getScheduler().runTask(
Main.instance(), Main.instance(),
() -> getAppliance().setPack(event.getPlayer(), getAppliance().getPackConfigurationForPlayer(event.getPlayer())) () -> this.getAppliance().setPack(event.getPlayer(), this.getAppliance().getPackConfigurationForPlayer(event.getPlayer()))
); );
} }
} }

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