148
build.gradle.kts
|
@ -1,8 +1,10 @@
|
|||
import net.minecrell.pluginyml.bukkit.BukkitPluginDescription
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
id("io.papermc.paperweight.userdev") version "1.7.1"
|
||||
id("io.github.goooler.shadow") version "8.1.7"
|
||||
id("org.sonarqube") version "4.4.1.3373"
|
||||
id("io.papermc.paperweight.userdev") version "1.7.2"
|
||||
id("org.sonarqube") version "5.1.0.4882"
|
||||
id("net.minecrell.plugin-yml.paper") version "0.6.0"
|
||||
}
|
||||
|
||||
// from 1.20.5+ upward, spigot is not supported
|
||||
|
@ -13,23 +15,42 @@ group = "me.unurled.sacredrealms"
|
|||
version = "0.1.0"
|
||||
description = "The main SR plugin."
|
||||
|
||||
val mcVersion = "1.21-R0.1-SNAPSHOT"
|
||||
val redisVersion = "5.2.0-beta2"
|
||||
val invuiVersion = "1.32"
|
||||
val mcVersion = "1.21.1-R0.1-SNAPSHOT"
|
||||
val redisVersion = "5.2.0-beta4"
|
||||
val invuiVersion = "1.36"
|
||||
val gsonVersion = "2.11.0"
|
||||
|
||||
val javaVersion = 21
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://repo.xenondevs.xyz/releases")
|
||||
maven {
|
||||
name = "invui"
|
||||
url = uri("https://repo.xenondevs.xyz/releases/")
|
||||
}
|
||||
maven {
|
||||
name = "packetevents"
|
||||
url = uri("https://repo.codemc.io/repository/maven-releases/")
|
||||
}
|
||||
maven {
|
||||
name = "unurled"
|
||||
url = uri("https://repo.unurled.me/releases")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
paperweight.paperDevBundle(mcVersion)
|
||||
|
||||
implementation("redis.clients:jedis:${redisVersion}")
|
||||
|
||||
compileOnly("xyz.xenondevs.invui:invui:${invuiVersion}")
|
||||
|
||||
paperLibrary("com.google.code.gson", "gson", gsonVersion)
|
||||
|
||||
paperLibrary("redis.clients", "jedis", redisVersion)
|
||||
|
||||
|
||||
paperLibrary("com.github.retrooper", "packetevents-spigot", "2.4.0")
|
||||
|
||||
paperLibrary("me.unurled", "SR-Core", "0.1.0")
|
||||
}
|
||||
|
||||
java {
|
||||
|
@ -45,33 +66,6 @@ tasks {
|
|||
javadoc {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
}
|
||||
processResources {
|
||||
filteringCharset = Charsets.UTF_8.name()
|
||||
val props = mapOf(
|
||||
"name" to project.name,
|
||||
"version" to project.version,
|
||||
"description" to project.description,
|
||||
"apiVersion" to "1.20"
|
||||
)
|
||||
inputs.properties(props)
|
||||
filesMatching("paper-plugin.yml") {
|
||||
expand(props)
|
||||
}
|
||||
}
|
||||
build {
|
||||
dependsOn(shadowJar)
|
||||
}
|
||||
shadowJar {
|
||||
archiveClassifier.set("")
|
||||
relocate("com.google", "libs.com.google")
|
||||
relocate("org.apache", "libs.org.apache")
|
||||
relocate("org.intellij", "libs.org.intellij")
|
||||
relocate("org.jetbrains", "libs.org.jetbrains")
|
||||
relocate("org.json", "libs.org.json")
|
||||
relocate("redis", "libs.redis")
|
||||
// relocate("xyz.xenondevs", "libs.xyz.xenondevs")
|
||||
exclude("org.slf4j")
|
||||
}
|
||||
sonar {
|
||||
properties {
|
||||
property("sonar.projectKey", "Sacred-Realms")
|
||||
|
@ -79,3 +73,85 @@ tasks {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
paper {
|
||||
main = "me.unurled.sacredrealms.sr.SR"
|
||||
|
||||
bootstrapper = "me.unurled.sacredrealms.sr.SRBootstrap"
|
||||
loader = "me.unurled.sacredrealms.sr.SRLoader"
|
||||
hasOpenClassloader = false
|
||||
|
||||
generateLibrariesJson = true
|
||||
foliaSupported = false
|
||||
|
||||
apiVersion = "1.21"
|
||||
|
||||
load = BukkitPluginDescription.PluginLoadOrder.STARTUP
|
||||
author = "unurled"
|
||||
|
||||
prefix = "SR"
|
||||
|
||||
defaultPermission = BukkitPluginDescription.Permission.Default.OP
|
||||
|
||||
permissions {
|
||||
register("sr.*") {
|
||||
children = listOf(
|
||||
"sr.tutorial",
|
||||
"sr.spawn",
|
||||
"sr.attributes",
|
||||
"sr.clientbuild",
|
||||
"sr.level",
|
||||
"sr.entitytype",
|
||||
"sr.spawnentity",
|
||||
"sr.admin.item",
|
||||
"sr.resetadventure",
|
||||
"sr.treasure.manage",
|
||||
"sr.difficulty.*",
|
||||
"sr.cutscene"
|
||||
)
|
||||
description = "Gives access to all Sacred Realms permissions."
|
||||
}
|
||||
register("sr.tutorial") {
|
||||
description = "Gives access to the tutorial command."
|
||||
default = BukkitPluginDescription.Permission.Default.NOT_OP
|
||||
}
|
||||
register("sr.spawn") {
|
||||
description = "Gives access to the spawn command."
|
||||
default = BukkitPluginDescription.Permission.Default.NOT_OP
|
||||
}
|
||||
register("sr.attributes") {
|
||||
description = "Gives access to the attributes command."
|
||||
}
|
||||
register("sr.clientbuild") {
|
||||
description = "Gives access to the clientbuild command."
|
||||
}
|
||||
register("sr.level") {
|
||||
description = "Gives access to the level command."
|
||||
}
|
||||
register("sr.entitytype") {
|
||||
description = "Gives access to the entitytype command."
|
||||
}
|
||||
register("sr.spawnentity") {
|
||||
description = "Gives access to the spawnentity command."
|
||||
}
|
||||
register("sr.admin.item") {
|
||||
description = "Gives access to the admin item command."
|
||||
}
|
||||
register("sr.resetadventure") {
|
||||
description = "Gives access to the resetadventure command."
|
||||
}
|
||||
register("sr.treasure.manage") {
|
||||
description = "Gives access to the treasure manage command."
|
||||
}
|
||||
register("sr.difficulty.*") {
|
||||
description = "Gives access to all difficulty commands."
|
||||
children = listOf(
|
||||
"sr.difficulty.self",
|
||||
"sr.difficulty.manage"
|
||||
)
|
||||
}
|
||||
register("sr.cutscene") {
|
||||
description = "Gives access to the cutscene command."
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +1,2 @@
|
|||
systemProp.sonar.gradle.skipCompile=true
|
||||
org.gradle.jvmargs=-Xmx16384M
|
|
@ -1,34 +1,73 @@
|
|||
package me.unurled.sacredrealms.sr;
|
||||
|
||||
import me.unurled.sacredrealms.sr.managers.Managers;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
|
||||
import java.util.List;
|
||||
import me.unurled.sacredrealms.sr.components.block.BlockManager;
|
||||
import me.unurled.sacredrealms.sr.components.clientbuild.ClientBuildManager;
|
||||
import me.unurled.sacredrealms.sr.components.combat.CombatManager;
|
||||
import me.unurled.sacredrealms.sr.components.entity.EntityManager;
|
||||
import me.unurled.sacredrealms.sr.components.item.ItemManager;
|
||||
import me.unurled.sacredrealms.sr.components.npc.NPCManager;
|
||||
import me.unurled.sacredrealms.sr.components.pack.ResourcePackManager;
|
||||
import me.unurled.sacredrealms.sr.components.pack.animatedjava.AnimatedJavaManager;
|
||||
import me.unurled.sacredrealms.sr.components.pack.background.BackgroundManager;
|
||||
import me.unurled.sacredrealms.sr.components.player.PlayerManager;
|
||||
import me.unurled.sacredrealms.sr.components.treasure.TreasureManager;
|
||||
import me.unurled.sacredrealms.sr.config.ConfigManager;
|
||||
import me.unurled.sacredrealms.sr.data.DataManager;
|
||||
import me.unurled.srcore.SRCore;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import xyz.xenondevs.invui.InvUI;
|
||||
|
||||
public final class SR extends JavaPlugin {
|
||||
|
||||
private static SR instance;
|
||||
private Managers managers;
|
||||
private static SR plugin;
|
||||
|
||||
public static SR getInstance() {
|
||||
return instance;
|
||||
public static SR getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this));
|
||||
// On Bukkit, calling this here is essential, hence the name "load"
|
||||
PacketEvents.getAPI().load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
plugin = this;
|
||||
|
||||
SRCore.getInstance().setPlugin(this);
|
||||
|
||||
PacketEvents.getAPI().init();
|
||||
|
||||
SRCore.getInstance()
|
||||
.getManagers()
|
||||
.register(
|
||||
List.of(
|
||||
ConfigManager.class,
|
||||
DataManager.class,
|
||||
AnimatedJavaManager.class,
|
||||
PlayerManager.class,
|
||||
CombatManager.class,
|
||||
ItemManager.class,
|
||||
EntityManager.class,
|
||||
NPCManager.class,
|
||||
BlockManager.class,
|
||||
ClientBuildManager.class,
|
||||
TreasureManager.class,
|
||||
BackgroundManager.class,
|
||||
ResourcePackManager.class));
|
||||
|
||||
InvUI.getInstance().setPlugin(this);
|
||||
|
||||
managers = new Managers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
managers.unload();
|
||||
managers = null;
|
||||
}
|
||||
SRCore.getInstance().unload();
|
||||
|
||||
public Managers getManagers() {
|
||||
return managers;
|
||||
PacketEvents.getAPI().terminate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
package me.unurled.sacredrealms.sr;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.papermc.paper.plugin.loader.PluginClasspathBuilder;
|
||||
import io.papermc.paper.plugin.loader.PluginLoader;
|
||||
import io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
import org.eclipse.aether.artifact.DefaultArtifact;
|
||||
import org.eclipse.aether.graph.Dependency;
|
||||
import org.eclipse.aether.repository.RemoteRepository;
|
||||
|
@ -12,15 +19,37 @@ public class SRLoader implements PluginLoader {
|
|||
|
||||
@Override
|
||||
public void classloader(@NotNull PluginClasspathBuilder classpathBuilder) {
|
||||
|
||||
MavenLibraryResolver resolver = new MavenLibraryResolver();
|
||||
resolver.addDependency(
|
||||
new Dependency(new DefaultArtifact("xyz.xenondevs.invui:inventory-access-r20:1.32"), null));
|
||||
resolver.addDependency(
|
||||
new Dependency(new DefaultArtifact("xyz.xenondevs.invui:invui-core:1.32"), null));
|
||||
new Dependency(new DefaultArtifact("xyz.xenondevs.invui:invui:pom:1.36"), null));
|
||||
resolver.addRepository(
|
||||
new RemoteRepository.Builder("invui", "default", "https://repo.xenondevs.xyz/releases/")
|
||||
.build());
|
||||
classpathBuilder.addLibrary(resolver);
|
||||
|
||||
PluginLibraries pluginLibraries = load();
|
||||
pluginLibraries.asDependencies().forEach(resolver::addDependency);
|
||||
pluginLibraries.asRepositories().forEach(resolver::addRepository);
|
||||
classpathBuilder.addLibrary(resolver);
|
||||
}
|
||||
|
||||
public PluginLibraries load() {
|
||||
try (var in = getClass().getResourceAsStream("/paper-libraries.json")) {
|
||||
return new Gson()
|
||||
.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), PluginLibraries.class);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private record PluginLibraries(Map<String, String> repositories, List<String> dependencies) {
|
||||
public Stream<Dependency> asDependencies() {
|
||||
return dependencies.stream().map(d -> new Dependency(new DefaultArtifact(d), null));
|
||||
}
|
||||
|
||||
public Stream<RemoteRepository> asRepositories() {
|
||||
return repositories.entrySet().stream()
|
||||
.map(e -> new RemoteRepository.Builder(e.getKey(), "default", e.getValue()).build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
package me.unurled.sacredrealms.sr.commands;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.log;
|
||||
|
||||
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||
import io.papermc.paper.command.brigadier.Commands;
|
||||
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
|
||||
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
|
||||
import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import me.unurled.sacredrealms.sr.commands.admin.AttributeCommand;
|
||||
import me.unurled.sacredrealms.sr.commands.admin.ClientBuildCommand;
|
||||
import me.unurled.sacredrealms.sr.commands.admin.CutsceneCommand;
|
||||
import me.unurled.sacredrealms.sr.commands.admin.EntityTypeCommand;
|
||||
import me.unurled.sacredrealms.sr.commands.admin.ItemCommand;
|
||||
import me.unurled.sacredrealms.sr.commands.admin.LevelCommand;
|
||||
|
@ -17,12 +19,22 @@ import me.unurled.sacredrealms.sr.commands.admin.SpawnEntityCommand;
|
|||
import me.unurled.sacredrealms.sr.commands.admin.TreasureCommand;
|
||||
import me.unurled.sacredrealms.sr.commands.player.DifficultyCommand;
|
||||
import me.unurled.sacredrealms.sr.commands.player.ResetAdventureCommand;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CommandManager extends Manager {
|
||||
|
||||
private static <T extends BasicCommand> void registerCommand(
|
||||
String command, String description, BootstrapContext ctx, Class<T> clazz) {
|
||||
String command, String description, @NotNull BootstrapContext ctx, Class<T> clazz) {
|
||||
registerCommand(command, description, List.of(), ctx, clazz);
|
||||
}
|
||||
|
||||
private static <T extends BasicCommand> void registerCommand(
|
||||
String command,
|
||||
String description,
|
||||
@NotNull Collection<String> aliases,
|
||||
@NotNull BootstrapContext ctx,
|
||||
Class<T> clazz) {
|
||||
LifecycleEventManager<BootstrapContext> man = ctx.getLifecycleManager();
|
||||
|
||||
try {
|
||||
|
@ -31,9 +43,8 @@ public class CommandManager extends Manager {
|
|||
LifecycleEvents.COMMANDS,
|
||||
event -> {
|
||||
final Commands commands = event.registrar();
|
||||
commands.register(command, description, instance);
|
||||
commands.register(command, description, aliases, instance);
|
||||
});
|
||||
log("Registered command: " + command);
|
||||
} catch (Exception e) {
|
||||
error("Failed to register command: " + command + " - " + e.getMessage());
|
||||
}
|
||||
|
@ -54,5 +65,7 @@ public class CommandManager extends Manager {
|
|||
"resetadventure", "Reset the adventure of the player.", ctx, ResetAdventureCommand.class);
|
||||
registerCommand(
|
||||
"difficulty", "Set the difficulty of the player.", ctx, DifficultyCommand.class);
|
||||
|
||||
registerCommand("cutscene", "Cutscene commands.", List.of("cs"), ctx, CutsceneCommand.class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
|||
import me.unurled.sacredrealms.sr.components.player.PlayerManager;
|
||||
import me.unurled.sacredrealms.sr.components.player.SRPlayer;
|
||||
import me.unurled.sacredrealms.sr.gui.attributes.AttributesGUI;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -256,8 +256,8 @@ public class AttributeCommand implements BasicCommand {
|
|||
* @return a collection of suggestions
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Collection<String> suggest(@NotNull CommandSourceStack commandSourceStack,
|
||||
@NotNull String[] args) {
|
||||
public @NotNull Collection<String> suggest(
|
||||
@NotNull CommandSourceStack commandSourceStack, @NotNull String[] args) {
|
||||
CommandSender sender = commandSourceStack.getSender();
|
||||
if (!sender.hasPermission("sr.attributes")) {
|
||||
return List.of();
|
||||
|
|
|
@ -16,7 +16,7 @@ import me.unurled.sacredrealms.sr.components.clientbuild.ClientBuild;
|
|||
import me.unurled.sacredrealms.sr.components.clientbuild.ClientBuildManager;
|
||||
import me.unurled.sacredrealms.sr.components.player.PlayerManager;
|
||||
import me.unurled.sacredrealms.sr.components.player.SRPlayer;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
@ -179,6 +179,7 @@ public class ClientBuildCommand implements BasicCommand, Listener {
|
|||
if (build != null) sender.sendMessage(build.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockPlace(@NotNull BlockPlaceEvent e) {
|
||||
Player p = e.getPlayer();
|
||||
|
@ -286,8 +287,8 @@ public class ClientBuildCommand implements BasicCommand, Listener {
|
|||
* @return a collection of suggestions
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Collection<String> suggest(@NotNull CommandSourceStack commandSourceStack,
|
||||
@NotNull String[] args) {
|
||||
public @NotNull Collection<String> suggest(
|
||||
@NotNull CommandSourceStack commandSourceStack, @NotNull String @NotNull [] args) {
|
||||
if (args.length == 1) {
|
||||
return List.of("create", DELETE, "list", MODIFY, "save", DISPLAY);
|
||||
} else if (args.length == 2
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
package me.unurled.sacredrealms.sr.commands.admin;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
||||
|
||||
import io.papermc.paper.command.brigadier.BasicCommand;
|
||||
import io.papermc.paper.command.brigadier.CommandSourceStack;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.Cutscene;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.CutsceneManager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class CutsceneCommand implements BasicCommand {
|
||||
|
||||
private CutsceneManager cutsceneManager;
|
||||
|
||||
/**
|
||||
* Returns the permission for the root command used in {@link #canUse(CommandSender)} by default.
|
||||
*
|
||||
* @return the permission for the root command used in {@link #canUse(CommandSender)}
|
||||
*/
|
||||
@Override
|
||||
public @Nullable String permission() {
|
||||
return "cutscenes.admin";
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the command with the given {@link CommandSourceStack} and arguments.
|
||||
*
|
||||
* @param sender the commandSourceStack of the command
|
||||
* @param args the arguments of the command ignoring repeated spaces
|
||||
*/
|
||||
@Override
|
||||
public void execute(@NotNull CommandSourceStack sender, @NotNull String @NotNull [] args) {
|
||||
if (cutsceneManager == null) {
|
||||
cutsceneManager = Manager.getInstance(CutsceneManager.class);
|
||||
}
|
||||
// /cs stop, list, reload, play, create, remove
|
||||
if (args.length == 1) {
|
||||
if (args[0].equals("stop")) {
|
||||
if (sender.getSender() instanceof Player p) {
|
||||
cutsceneManager.stopCutscene(p);
|
||||
} else {
|
||||
sender
|
||||
.getSender()
|
||||
.sendMessage(
|
||||
textComp("<red>You must be a player to stop a cutscene. Use /cs stop <player>"));
|
||||
}
|
||||
} else if (args[0].equals("list")) {
|
||||
sender
|
||||
.getSender()
|
||||
.sendMessage(
|
||||
textComp("<yellow>Cutscenes: " + cutsceneManager.getCutscenesId().toString()));
|
||||
} else if (args[0].equals("reload")) {
|
||||
|
||||
}
|
||||
} else if (args.length == 2) {
|
||||
if (args[0].equals("play")) {
|
||||
if (sender.getSender() instanceof Player p) {
|
||||
Cutscene cutscene = cutsceneManager.getCutscene(args[1]);
|
||||
cutsceneManager.playCutscene(cutscene, p);
|
||||
} else {
|
||||
sender
|
||||
.getSender()
|
||||
.sendMessage(
|
||||
textComp(
|
||||
"<red>You must be a player to play a cutscene. Use /cs play <cutscene_id> <player>"));
|
||||
}
|
||||
} else if (args[0].equals("stop")) {
|
||||
Player p = Bukkit.getPlayer(args[1]);
|
||||
if (p != null) {
|
||||
cutsceneManager.stopCutscene(p);
|
||||
}
|
||||
} else if (args[0].equals("create")) {
|
||||
String name = args[1];
|
||||
cutsceneManager.createCutscene(name);
|
||||
sender.getSender().sendMessage(textComp("<green>Created cutscene " + name));
|
||||
} else if (args[0].equals("remove")) {
|
||||
String name = args[1];
|
||||
cutsceneManager.removeCutscene(name);
|
||||
sender.getSender().sendMessage(textComp("<red>Removed cutscene " + name));
|
||||
}
|
||||
} else if (args.length == 3) {
|
||||
if (args[0].equals("play")) {
|
||||
Player p = Bukkit.getPlayer(args[2]);
|
||||
if (p != null) {
|
||||
Cutscene cutscene = cutsceneManager.getCutscene(args[1]);
|
||||
cutsceneManager.playCutscene(cutscene, p);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sender
|
||||
.getSender()
|
||||
.sendMessage(
|
||||
textComp(
|
||||
"<yellow>Usage: /cs <play|stop|reload|list> <cutscene_id|player (only play and stop)> <player (only possible if play with an id before)>"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Suggests possible completions for the given command {@link CommandSourceStack} and arguments.
|
||||
*
|
||||
* @param sender the commandSourceStack of the command
|
||||
* @param args the arguments of the command including repeated spaces
|
||||
* @return a collection of suggestions
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Collection<String> suggest(
|
||||
@NotNull CommandSourceStack sender, @NotNull String[] args) {
|
||||
if (cutsceneManager == null) {
|
||||
cutsceneManager = Manager.getInstance(CutsceneManager.class);
|
||||
}
|
||||
List<String> complete = new ArrayList<>();
|
||||
complete.add("stop");
|
||||
if (sender.getSender().hasPermission("cutscenes.admin")) {
|
||||
complete.add("play");
|
||||
complete.add("list");
|
||||
complete.add("reload");
|
||||
complete.add("create");
|
||||
complete.add("remove");
|
||||
}
|
||||
List<String> result = new ArrayList<>();
|
||||
if (args.length == 1) {
|
||||
for (String s : complete) {
|
||||
if (s.toLowerCase().startsWith(args[0].toLowerCase())) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else if (args.length == 2) {
|
||||
if (sender.getSender().hasPermission("cutscenes.admin")) {
|
||||
if (args[0].equalsIgnoreCase("stop")) {
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
if (p.getName().toLowerCase().startsWith(args[1].toLowerCase())) {
|
||||
result.add(p.getName());
|
||||
}
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("play") || args[0].equalsIgnoreCase("remove")) {
|
||||
for (String s : cutsceneManager.getCutscenesId()) {
|
||||
if (s.toLowerCase().startsWith(args[1].toLowerCase())) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else if (args.length == 3) {
|
||||
if (sender.getSender().hasPermission("cutscenes.admin")) {
|
||||
if (args[0].equalsIgnoreCase("play")) {
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
if (p.getName().toLowerCase().startsWith(args[2].toLowerCase())) {
|
||||
result.add(p.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ import java.util.List;
|
|||
import me.unurled.sacredrealms.sr.components.entity.EntityManager;
|
||||
import me.unurled.sacredrealms.sr.components.entity.SREntityType;
|
||||
import me.unurled.sacredrealms.sr.gui.entitytype.EntityTypeGUI;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -33,7 +33,7 @@ public class EntityTypeCommand implements BasicCommand {
|
|||
}
|
||||
|
||||
Window window =
|
||||
Window.single().setViewer(p).setTitle(args[1]).setGui(EntityTypeGUI.listGui()).build();
|
||||
Window.single().setViewer(p).setTitle("List").setGui(EntityTypeGUI.listGui()).build();
|
||||
window.open();
|
||||
}
|
||||
|
||||
|
@ -74,8 +74,7 @@ public class EntityTypeCommand implements BasicCommand {
|
|||
try {
|
||||
EntityType type = EntityType.valueOf(args[4]);
|
||||
EntityManager em = Manager.getInstance(EntityManager.class);
|
||||
if (setType(sender, args, em, type)) {
|
||||
}
|
||||
if (setType(sender, args, em, type)) {}
|
||||
} catch (IllegalArgumentException e) {
|
||||
sender.sendMessage("Invalid entity type.");
|
||||
}
|
||||
|
@ -91,7 +90,7 @@ public class EntityTypeCommand implements BasicCommand {
|
|||
if (!em.getTypes().stream().map(SREntityType::getId).toList().contains(args[1])) {
|
||||
sender.sendMessage("Invalid entity type.");
|
||||
}
|
||||
// em.removeEntityType(em.getType(args[1]));
|
||||
// em.removeEntityType(em.getType(args[1]));
|
||||
}
|
||||
|
||||
private static void create(@NotNull CommandSender sender, @NotNull String @NotNull [] args) {
|
||||
|
@ -169,8 +168,8 @@ public class EntityTypeCommand implements BasicCommand {
|
|||
* @return a collection of suggestions
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Collection<String> suggest(@NotNull CommandSourceStack commandSourceStack,
|
||||
@NotNull String[] args) {
|
||||
public @NotNull Collection<String> suggest(
|
||||
@NotNull CommandSourceStack commandSourceStack, @NotNull String[] args) {
|
||||
CommandSender sender = commandSourceStack.getSender();
|
||||
if (sender.hasPermission("sr.entitytype")) {
|
||||
if (args.length == 1) {
|
||||
|
|
|
@ -15,7 +15,7 @@ import me.unurled.sacredrealms.sr.components.item.ItemType;
|
|||
import me.unurled.sacredrealms.sr.components.item.Rarity;
|
||||
import me.unurled.sacredrealms.sr.components.item.abilities.Ability;
|
||||
import me.unurled.sacredrealms.sr.components.item.enchantments.Enchantment;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
@ -380,7 +380,7 @@ public class ItemCommand implements BasicCommand {
|
|||
.map(
|
||||
name -> {
|
||||
if (name.name().startsWith(args[3].toUpperCase())) return name.name();
|
||||
return null;
|
||||
return "";
|
||||
})
|
||||
.toList();
|
||||
}
|
||||
|
@ -392,8 +392,8 @@ public class ItemCommand implements BasicCommand {
|
|||
p.getInventory().setItemInMainHand(newItem.toItemStack());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static List<String> modifyCompletion(@NotNull String @NotNull [] args) {
|
||||
private static @NotNull List<String> modifyCompletion(@NotNull String @NotNull [] args) {
|
||||
if (args.length < 3) return List.of();
|
||||
if (args[2].equalsIgnoreCase(RARITY)) {
|
||||
return Arrays.stream(Rarity.values()).map(Enum::name).toList();
|
||||
} else if (args[2].equalsIgnoreCase("type")) {
|
||||
|
@ -403,7 +403,7 @@ public class ItemCommand implements BasicCommand {
|
|||
.map(
|
||||
name -> {
|
||||
if (name.name().startsWith(args[3].toUpperCase())) return name.name();
|
||||
return null;
|
||||
return "";
|
||||
})
|
||||
.toList();
|
||||
} else if (args[2].equalsIgnoreCase(ENCHANTMENTS)) {
|
||||
|
@ -414,12 +414,12 @@ public class ItemCommand implements BasicCommand {
|
|||
return List.of("add", REMOVE);
|
||||
} else if (args[2].equalsIgnoreCase(CUSTOMMODELDATA)) {
|
||||
try {
|
||||
Integer.parseInt(args[3]);
|
||||
if (args.length == 4) Integer.parseInt(args[3]);
|
||||
} catch (NumberFormatException e) {
|
||||
return List.of("1");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -507,7 +507,7 @@ public class ItemCommand implements BasicCommand {
|
|||
return List.of("");
|
||||
}
|
||||
|
||||
if (args.length == 1) {
|
||||
if (args.length <= 1) {
|
||||
return List.of("list", "create", DELETE, "give", MODIFY);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.util.Collection;
|
|||
import java.util.List;
|
||||
import me.unurled.sacredrealms.sr.components.player.PlayerManager;
|
||||
import me.unurled.sacredrealms.sr.components.player.SRPlayer;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.util.Collection;
|
|||
import java.util.List;
|
||||
import me.unurled.sacredrealms.sr.components.entity.EntityManager;
|
||||
import me.unurled.sacredrealms.sr.components.entity.SREntityType;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -28,11 +28,12 @@ public class SpawnEntityCommand implements BasicCommand {
|
|||
return;
|
||||
}
|
||||
SREntityType eType = em.getType(type);
|
||||
if (type == null) {
|
||||
if (eType == null) {
|
||||
sender.sendMessage("Invalid entity type.");
|
||||
return;
|
||||
}
|
||||
em.spawnEntity(eType, amount, x, y, z, world);
|
||||
sender.sendMessage("Spawned " + amount + " " + eType.getName() + "s.");
|
||||
}
|
||||
|
||||
private int getAmount(CommandSender sender, String @NotNull [] args) {
|
||||
|
@ -81,7 +82,7 @@ public class SpawnEntityCommand implements BasicCommand {
|
|||
}
|
||||
}
|
||||
if (args[3].equals("~")) {
|
||||
y = p.getLocation().getX();
|
||||
y = p.getLocation().getY();
|
||||
} else {
|
||||
try {
|
||||
y = Double.parseDouble(args[3]);
|
||||
|
@ -91,7 +92,7 @@ public class SpawnEntityCommand implements BasicCommand {
|
|||
}
|
||||
}
|
||||
if (args[4].equals("~")) {
|
||||
z = p.getLocation().getX();
|
||||
z = p.getLocation().getZ();
|
||||
} else {
|
||||
try {
|
||||
z = Double.parseDouble(args[4]);
|
||||
|
@ -142,8 +143,8 @@ public class SpawnEntityCommand implements BasicCommand {
|
|||
* @return a collection of suggestions
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Collection<String> suggest(@NotNull CommandSourceStack commandSourceStack,
|
||||
@NotNull String[] args) {
|
||||
public @NotNull Collection<String> suggest(
|
||||
@NotNull CommandSourceStack commandSourceStack, @NotNull String[] args) {
|
||||
CommandSender sender = commandSourceStack.getSender();
|
||||
if (sender.hasPermission("sr.spawn-entity")) {
|
||||
if (args.length == 1) {
|
||||
|
|
|
@ -11,7 +11,7 @@ import java.util.Set;
|
|||
import me.unurled.sacredrealms.sr.components.treasure.Treasure;
|
||||
import me.unurled.sacredrealms.sr.components.treasure.TreasureManager;
|
||||
import me.unurled.sacredrealms.sr.gui.treasure.TreasureGUI;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
|
@ -54,11 +54,10 @@ public class TreasureCommand implements BasicCommand {
|
|||
for (Treasure treasure : instance.getTreasures()) {
|
||||
String s =
|
||||
String.format(
|
||||
"<click:run_command:tp %s %s %s>%s</click>x: %s, y: %s, z: %s",
|
||||
"<click:run_command:tp %s %s %s>x: %s, y: %s, z: %s</click>",
|
||||
treasure.getLocation().getBlockX(),
|
||||
treasure.getLocation().getBlockY(),
|
||||
treasure.getLocation().getBlockZ(),
|
||||
treasure.getLocation().toString(),
|
||||
treasure.getLocation().getBlockX(),
|
||||
treasure.getLocation().getBlockY(),
|
||||
treasure.getLocation().getBlockZ());
|
||||
|
@ -85,10 +84,12 @@ public class TreasureCommand implements BasicCommand {
|
|||
Window window =
|
||||
Window.single()
|
||||
.setViewer(p)
|
||||
.setTitle("Attributes")
|
||||
.setTitle("Modifiy Treasure Chest")
|
||||
.setGui(TreasureGUI.createGui(treasure))
|
||||
.build();
|
||||
window.open();
|
||||
} else {
|
||||
p.sendMessage(textComp("<red>Target block is not a chest."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +113,10 @@ public class TreasureCommand implements BasicCommand {
|
|||
} else {
|
||||
treasure = new Treasure(instance.getNextId(), block.getLocation());
|
||||
}
|
||||
block.setBlockData(Material.AIR.createBlockData());
|
||||
instance.addTreasure(treasure);
|
||||
} else {
|
||||
p.sendMessage(textComp("<red>Target block is not a chest."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,7 +127,8 @@ public class TreasureCommand implements BasicCommand {
|
|||
* @param args the arguments of the command ignoring repeated spaces
|
||||
*/
|
||||
@Override
|
||||
public void execute(@NotNull CommandSourceStack commandSourceStack, @NotNull String @NotNull [] args) {
|
||||
public void execute(
|
||||
@NotNull CommandSourceStack commandSourceStack, @NotNull String @NotNull [] args) {
|
||||
CommandSender sender = commandSourceStack.getSender();
|
||||
if (args.length == 0) {
|
||||
sender.sendMessage("Usage: /treasure <create|modify|list|delete>");
|
||||
|
@ -147,8 +152,8 @@ public class TreasureCommand implements BasicCommand {
|
|||
* @return a collection of suggestions
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Collection<String> suggest(@NotNull CommandSourceStack commandSourceStack,
|
||||
@NotNull String[] args) {
|
||||
public @NotNull Collection<String> suggest(
|
||||
@NotNull CommandSourceStack commandSourceStack, @NotNull String @NotNull [] args) {
|
||||
if (args.length == 0) {
|
||||
return List.of(CREATE, MODIFY, LIST, DELETE);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import me.unurled.sacredrealms.sr.components.difficulty.Difficulty;
|
|||
import me.unurled.sacredrealms.sr.components.player.PlayerManager;
|
||||
import me.unurled.sacredrealms.sr.components.player.SRPlayer;
|
||||
import me.unurled.sacredrealms.sr.gui.difficulty.DifficultyGUI;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
|
@ -184,8 +184,8 @@ public class DifficultyCommand implements BasicCommand {
|
|||
* @return a collection of suggestions
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Collection<String> suggest(@NotNull CommandSourceStack commandSourceStack,
|
||||
@NotNull String[] args) {
|
||||
public @NotNull Collection<String> suggest(
|
||||
@NotNull CommandSourceStack commandSourceStack, @NotNull String[] args) {
|
||||
CommandSender sender = commandSourceStack.getSender();
|
||||
if (args.length == 0 && sender.hasPermission(DIFFICULTY_MANAGE)) {
|
||||
return Bukkit.getOnlinePlayers().stream().map(Player::getName).toList();
|
||||
|
|
|
@ -12,7 +12,7 @@ import java.util.Objects;
|
|||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.sacredrealms.sr.components.player.PlayerManager;
|
||||
import me.unurled.sacredrealms.sr.data.DataManager;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
@ -39,7 +39,7 @@ public class ResetAdventureCommand implements BasicCommand {
|
|||
}
|
||||
return;
|
||||
}
|
||||
OfflinePlayer player = SR.getInstance().getServer().getOfflinePlayer(args[0]);
|
||||
OfflinePlayer player = SR.getPlugin().getServer().getOfflinePlayer(args[0]);
|
||||
|
||||
boolean status = resetAdventure(player);
|
||||
if (status) {
|
||||
|
@ -62,7 +62,6 @@ public class ResetAdventureCommand implements BasicCommand {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Executes the command with the given {@link CommandSourceStack} and arguments.
|
||||
*
|
||||
|
@ -111,8 +110,8 @@ public class ResetAdventureCommand implements BasicCommand {
|
|||
* @return a collection of suggestions
|
||||
*/
|
||||
@Override
|
||||
public @NotNull Collection<String> suggest(@NotNull CommandSourceStack commandSourceStack,
|
||||
@NotNull String[] args) {
|
||||
public @NotNull Collection<String> suggest(
|
||||
@NotNull CommandSourceStack commandSourceStack, @NotNull String[] args) {
|
||||
CommandSender sender = commandSourceStack.getSender();
|
||||
if (sender.hasPermission("sr.resetadventure")) {
|
||||
if (args.length == 1) {
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
package me.unurled.sacredrealms.sr.components.block;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.ItemDisplay;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Block {
|
||||
|
||||
private final Material BROKEN_MATERIAL = Material.AIR;
|
||||
private final Material HITBOX_MATERIAL = Material.BARRIER;
|
||||
|
||||
private Location location;
|
||||
|
||||
private ItemDisplay entity;
|
||||
|
||||
private BlockItem item;
|
||||
|
||||
public Block(@NotNull Location location, @NotNull BlockItem blockItem) {
|
||||
this.placeBlock(location, blockItem);
|
||||
}
|
||||
|
||||
private void placeBlock(@NotNull Location location, BlockItem blockItem) {
|
||||
World world = location.getWorld();
|
||||
|
||||
world.setBlockData(location, HITBOX_MATERIAL.createBlockData());
|
||||
Location entityLocation = getLocationFromBlock(location);
|
||||
|
||||
world.spawn(
|
||||
entityLocation,
|
||||
ItemDisplay.class,
|
||||
entity -> {
|
||||
ItemStack item = blockItem.getItem(1);
|
||||
entity.setItemStack(item);
|
||||
entity.setPersistent(true);
|
||||
entity.setInvulnerable(true);
|
||||
|
||||
this.entity = entity;
|
||||
this.location = location;
|
||||
this.item = blockItem;
|
||||
});
|
||||
}
|
||||
|
||||
public void breakBlock() {
|
||||
this.entity.remove();
|
||||
World world = this.location.getWorld();
|
||||
world.setBlockData(this.location, BROKEN_MATERIAL.createBlockData());
|
||||
}
|
||||
|
||||
public BlockItem getBlockItem() {
|
||||
return this.item;
|
||||
}
|
||||
|
||||
private @NotNull Location getLocationFromBlock(@NotNull Location location) {
|
||||
Location entityLocation = location.clone();
|
||||
entityLocation.setX(location.getX() + 0.5);
|
||||
entityLocation.setY(location.getY() + 0.5);
|
||||
entityLocation.setZ(location.getZ() + 0.5);
|
||||
|
||||
return entityLocation;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package me.unurled.sacredrealms.sr.components.block;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import me.unurled.sacredrealms.sr.constants.Keys;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BlockItem {
|
||||
|
||||
private static final Material BLOCK_MATERIAL = Material.STONE;
|
||||
|
||||
private final Component displayName;
|
||||
private final List<Component> lore;
|
||||
private final int customModelData;
|
||||
|
||||
public BlockItem(@NotNull ItemStack itemStack) {
|
||||
this.displayName = itemStack.getItemMeta().displayName();
|
||||
this.lore = itemStack.getItemMeta().lore();
|
||||
this.customModelData = itemStack.getItemMeta().getCustomModelData();
|
||||
}
|
||||
|
||||
public BlockItem(@NotNull Map<?, ?> configObject) {
|
||||
String rawDisplayName = (String) configObject.get(Keys.BLOCK_DISPLAYNAME);
|
||||
List<String> rawLore = new ArrayList<>();
|
||||
if (configObject.get(Keys.BLOCK_LORE) instanceof List) {
|
||||
try {
|
||||
rawLore = (List<String>) configObject.get(Keys.BLOCK_LORE);
|
||||
} catch (ClassCastException e) {
|
||||
error("Failed to cast lore to List<String> " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
this.displayName = textComp(rawDisplayName);
|
||||
this.customModelData = (int) configObject.get(Keys.BLOCK_CUSTOMMODELDATA);
|
||||
this.lore = new ArrayList<>();
|
||||
|
||||
for (String loreItem : rawLore) {
|
||||
this.lore.add(textComp(loreItem));
|
||||
}
|
||||
}
|
||||
|
||||
public BlockItem(Component displayName, List<Component> lore, int customModelData) {
|
||||
this.displayName = displayName;
|
||||
this.lore = lore;
|
||||
this.customModelData = customModelData;
|
||||
}
|
||||
|
||||
public Component getDisplayName() {
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
public ItemStack getItem(int amount) {
|
||||
ItemStack item = new ItemStack(BLOCK_MATERIAL, amount);
|
||||
ItemMeta itemMeta = item.getItemMeta();
|
||||
|
||||
itemMeta.displayName(this.displayName);
|
||||
itemMeta.lore(this.lore);
|
||||
itemMeta.setCustomModelData(this.customModelData);
|
||||
|
||||
item.setItemMeta(itemMeta);
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package me.unurled.sacredrealms.sr.components.block;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Items.locationToString;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.ItemDisplay;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BlockManager extends Manager {
|
||||
|
||||
private final Map<String, Block> blocks = new HashMap<>();
|
||||
|
||||
public void addBlock(@NotNull Location location, @NotNull BlockItem blockItem) {
|
||||
Block block = new Block(location, blockItem);
|
||||
blocks.put(locationToString(location), block);
|
||||
}
|
||||
|
||||
public void removeBlock(@NotNull Location location) {
|
||||
String blockID = locationToString(location);
|
||||
|
||||
if (blocks.containsKey(blockID)) {
|
||||
Block block = blocks.get(blockID);
|
||||
block.breakBlock();
|
||||
blocks.remove(blockID);
|
||||
}
|
||||
}
|
||||
|
||||
public void breakBlock(Location loc, Player player) {
|
||||
String blockID = locationToString(loc);
|
||||
if (blocks.containsKey(blockID)) {
|
||||
Block block = blocks.get(blockID);
|
||||
block.breakBlock();
|
||||
|
||||
player.playSound(loc, Sound.BLOCK_STONE_BREAK, 1, 1);
|
||||
|
||||
if (player.getGameMode() == GameMode.SURVIVAL) {
|
||||
World world = loc.getWorld();
|
||||
world.dropItemNaturally(loc, block.getBlockItem().getItem(1));
|
||||
}
|
||||
|
||||
blocks.remove(blockID);
|
||||
}
|
||||
}
|
||||
|
||||
private @NotNull Location getLocationFromEntity(@NotNull Location location) {
|
||||
Location entityLocation = location.clone();
|
||||
entityLocation.setX(location.getX() - 0.5);
|
||||
entityLocation.setY(location.getY() - 0.5);
|
||||
entityLocation.setZ(location.getZ() - 0.5);
|
||||
|
||||
return entityLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
Bukkit.getScheduler()
|
||||
.runTask(
|
||||
SR.getPlugin(),
|
||||
() -> {
|
||||
for (World world : SR.getPlugin().getServer().getWorlds()) {
|
||||
if (world == null) {
|
||||
continue;
|
||||
}
|
||||
for (ItemDisplay entity : world.getEntitiesByClass(ItemDisplay.class)) {
|
||||
Location location = getLocationFromEntity(entity.getLocation());
|
||||
ItemStack itemStack = entity.getItemStack();
|
||||
BlockItem blockItem = new BlockItem(itemStack);
|
||||
entity.remove();
|
||||
this.addBlock(location, blockItem);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -2,15 +2,17 @@ package me.unurled.sacredrealms.sr.components.clientbuild;
|
|||
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import java.lang.reflect.Type;
|
||||
import me.unurled.sacredrealms.sr.utils.gson.LocationSerializer;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ClientBuildDeserializer implements JsonDeserializer<ClientBuild> {
|
||||
|
||||
|
@ -31,28 +33,18 @@ public class ClientBuildDeserializer implements JsonDeserializer<ClientBuild> {
|
|||
* @throws JsonParseException if json is not in the expected format of {@code typeofT}
|
||||
*/
|
||||
@Override
|
||||
public ClientBuild deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
public ClientBuild deserialize(
|
||||
@NotNull JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
String[] data = json.getAsString().split(";");
|
||||
ClientBuild build = new ClientBuild(data[0]);
|
||||
LocationSerializer locDes = new LocationSerializer();
|
||||
for (String block : data[1].split(",")) {
|
||||
String[] spl = block.replace("{", "").replace("}", "").split("\\|");
|
||||
World world = Bukkit.getWorld(spl[0]);
|
||||
if (world == null) {
|
||||
error("World " + spl[0] + " does not exist");
|
||||
return build;
|
||||
}
|
||||
Location loc;
|
||||
Location loc = locDes.deserialize(new Gson().toJsonTree(spl[0]), Location.class, context);
|
||||
BlockData bData;
|
||||
try {
|
||||
loc =
|
||||
new Location(
|
||||
world,
|
||||
Integer.parseInt(spl[1]),
|
||||
Integer.parseInt(spl[2]),
|
||||
Integer.parseInt(spl[3]));
|
||||
|
||||
bData = Bukkit.createBlockData(spl[4]);
|
||||
bData = Bukkit.createBlockData(spl[1]);
|
||||
} catch (NumberFormatException e) {
|
||||
error("Invalid block data: " + block);
|
||||
continue;
|
||||
|
|
|
@ -15,7 +15,7 @@ import me.unurled.sacredrealms.sr.SR;
|
|||
import me.unurled.sacredrealms.sr.commands.admin.ClientBuildCommand;
|
||||
import me.unurled.sacredrealms.sr.data.DataHandler;
|
||||
import me.unurled.sacredrealms.sr.data.DataManager;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
@ -41,7 +41,7 @@ public class ClientBuildManager extends Manager {
|
|||
@Override
|
||||
public void load() {
|
||||
super.load();
|
||||
Bukkit.getPluginManager().registerEvents(new ClientBuildCommand(), SR.getInstance());
|
||||
Bukkit.getPluginManager().registerEvents(new ClientBuildCommand(), SR.getPlugin());
|
||||
}
|
||||
|
||||
public List<ClientBuild> getBuilds() {
|
||||
|
@ -83,7 +83,7 @@ public class ClientBuildManager extends Manager {
|
|||
if (dh == null) {
|
||||
error("Failed to get DataHandler instance, can't load client builds.");
|
||||
error("Retrying in 10 seconds.");
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(SR.getInstance(), this::loadData, 200L);
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(SR.getPlugin(), this::loadData, 200L);
|
||||
return;
|
||||
}
|
||||
List<String> keys = dh.getKeysAll("sr.clientbuild");
|
||||
|
@ -130,7 +130,7 @@ public class ClientBuildManager extends Manager {
|
|||
}
|
||||
Bukkit.getScheduler()
|
||||
.runTaskAsynchronously(
|
||||
SR.getInstance(),
|
||||
SR.getPlugin(),
|
||||
() -> {
|
||||
for (String name : names) {
|
||||
ClientBuild build = getBuild(name);
|
||||
|
|
|
@ -6,8 +6,10 @@ import com.google.gson.JsonSerializationContext;
|
|||
import com.google.gson.JsonSerializer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map.Entry;
|
||||
import me.unurled.sacredrealms.sr.utils.gson.LocationSerializer;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ClientBuildSerializer implements JsonSerializer<ClientBuild> {
|
||||
|
||||
|
@ -27,19 +29,16 @@ public class ClientBuildSerializer implements JsonSerializer<ClientBuild> {
|
|||
* @return a JsonElement corresponding to the specified object.
|
||||
*/
|
||||
@Override
|
||||
public JsonElement serialize(ClientBuild src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
public JsonElement serialize(
|
||||
@NotNull ClientBuild src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append(src.getName());
|
||||
s.append(";");
|
||||
LocationSerializer locSer = new LocationSerializer();
|
||||
for (Entry<Location, BlockData> entry : src.getBlocks().entrySet()) {
|
||||
s.append("{");
|
||||
s.append(entry.getKey().getWorld().getName());
|
||||
s.append("|");
|
||||
s.append(entry.getKey().getBlockX());
|
||||
s.append("|");
|
||||
s.append(entry.getKey().getBlockY());
|
||||
s.append("|");
|
||||
s.append(entry.getKey().getBlockZ());
|
||||
JsonElement j = locSer.serialize(entry.getKey(), Location.class, context);
|
||||
s.append(j);
|
||||
s.append("|");
|
||||
s.append(entry.getValue().getAsString());
|
||||
s.append("},");
|
||||
|
|
|
@ -12,10 +12,12 @@ import java.util.UUID;
|
|||
import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
||||
import me.unurled.sacredrealms.sr.components.entity.EntityManager;
|
||||
import me.unurled.sacredrealms.sr.components.entity.SREntity;
|
||||
import me.unurled.sacredrealms.sr.components.entity.SREntityType;
|
||||
import me.unurled.sacredrealms.sr.components.player.PlayerManager;
|
||||
import me.unurled.sacredrealms.sr.components.player.SRPlayer;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.sacredrealms.sr.utils.Items;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Mob;
|
||||
|
@ -23,6 +25,7 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityDamageByBlockEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -33,7 +36,10 @@ public class CombatManager extends Manager {
|
|||
private final Map<UUID, Map<UUID, Double>> historyMobDamage = new HashMap<>();
|
||||
|
||||
private static void playerVictim(
|
||||
@NotNull EntityDamageByEntityEvent e, Player player, @NotNull Mob mob, PlayerManager pm) {
|
||||
@NotNull EntityDamageByEntityEvent e,
|
||||
Player player,
|
||||
@NotNull Mob mob,
|
||||
@NotNull PlayerManager pm) {
|
||||
// get equipment of damager
|
||||
EntityEquipment equipment = mob.getEquipment();
|
||||
Double dStrength = Items.getTotalAttribute(equipment, Attribute.STRENGTH);
|
||||
|
@ -92,7 +98,7 @@ public class CombatManager extends Manager {
|
|||
if (player1.getHealth() <= 0) {
|
||||
player.damage(player.getHealth());
|
||||
}
|
||||
updateActionBar(player, player1);
|
||||
updateActionBar(player);
|
||||
}
|
||||
|
||||
spawnIndicator(player, false, damage);
|
||||
|
@ -100,6 +106,14 @@ public class CombatManager extends Manager {
|
|||
// TODO: check for status effects (apply status effects depending item of damager)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDamage(@NotNull EntityDamageEvent e) {
|
||||
if (e.getCause() != DamageCause.ENTITY_ATTACK || !(e.getEntity() instanceof Player)) {
|
||||
e.setDamage(0.0);
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDamage(@NotNull EntityDamageByBlockEvent e) {
|
||||
// TODO: Implement
|
||||
|
@ -190,6 +204,16 @@ public class CombatManager extends Manager {
|
|||
} else if (luck > 0 && luck < 1000 && RANDOM.nextBoolean()) {
|
||||
// chance of critical hit
|
||||
d.playSound(d, Sound.ENTITY_PLAYER_ATTACK_CRIT, 1.0f, 1.0f);
|
||||
for (int i = 0; i < 10; i++) {
|
||||
d.spawnParticle(
|
||||
Particle.CRIT,
|
||||
entity.getLocation(),
|
||||
10,
|
||||
0.5 + (double) i / 10,
|
||||
0.5 + (double) i / 10,
|
||||
0.5 + (double) i / 10,
|
||||
0.1);
|
||||
}
|
||||
// damage * 2
|
||||
damage = damage * 2;
|
||||
}
|
||||
|
@ -201,17 +225,31 @@ public class CombatManager extends Manager {
|
|||
EntityManager em = Manager.getInstance(EntityManager.class);
|
||||
SREntity ent = em.getEntity(entity.getUniqueId());
|
||||
|
||||
if (ent != null) {
|
||||
ent.setHealth(ent.getHealth() - damage);
|
||||
}
|
||||
|
||||
if (entity.getHealth() <= 0) {
|
||||
die(entity, d, pm, ent);
|
||||
return;
|
||||
}
|
||||
|
||||
// change entity health in name
|
||||
if (ent != null) {
|
||||
SREntityType type = em.getType(ent.getTypeId());
|
||||
|
||||
if (type != null) {
|
||||
ent.applyName(type, entity);
|
||||
}
|
||||
}
|
||||
|
||||
spawnIndicator(entity, false, damage);
|
||||
// TODO: check for status effects (apply status effects depending item of damager)
|
||||
}
|
||||
|
||||
private void die(
|
||||
LivingEntity entity, @NotNull Player d, @NotNull PlayerManager pm, SREntity ent) {
|
||||
@NotNull LivingEntity entity, @NotNull Player d, @NotNull PlayerManager pm, SREntity ent) {
|
||||
entity.setHealth(0.0);
|
||||
// entity is dead, give experience to player
|
||||
SRPlayer player1 = pm.getPlayer(d.getUniqueId());
|
||||
if (player1 != null && ent != null) {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
public enum Action {
|
||||
IDLE(),
|
||||
MOVE(Location.class),
|
||||
TELEPORT(Location.class),
|
||||
SPAWN(Location.class),
|
||||
DESPAWN(),
|
||||
HIT(Entity.class),
|
||||
SNEAK(),
|
||||
JUMP(),
|
||||
PLACE(Location.class, BlockData.class),
|
||||
INTERACT(Location.class, org.bukkit.event.block.Action.class),
|
||||
BREAK(Location.class);
|
||||
|
||||
private final List<Class> types;
|
||||
|
||||
Action(Class... types) {
|
||||
this.types = List.of(types);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,239 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
||||
import static me.unurled.sacredrealms.sr.utils.CutsceneUtil.showBlackScreen;
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Cutscene class
|
||||
*
|
||||
* <p>Represents a cutscene
|
||||
*
|
||||
* <pre>{@code
|
||||
* {
|
||||
* "id": "cutscene1",
|
||||
* "name": "Cutscene 1",
|
||||
* "markers": [1, 2, 3], // Marker IDs
|
||||
* "start": {
|
||||
* "world": "world",
|
||||
* "x": 0,
|
||||
* "y": 0,
|
||||
* "z": 0,
|
||||
* "yaw": 0,
|
||||
* "pitch": 0
|
||||
* },
|
||||
* "end": {
|
||||
* "world": "world",
|
||||
* "x": 0,
|
||||
* "y": 0,
|
||||
* "z": 0,
|
||||
* "yaw": 0,
|
||||
* "pitch": 0
|
||||
* }
|
||||
* "blackBorders": true,
|
||||
* "startFadeToBlack": true,
|
||||
* "endFadeToBlack": true
|
||||
* }
|
||||
* }</pre>
|
||||
*/
|
||||
public class Cutscene {
|
||||
|
||||
private final String id;
|
||||
private final String name;
|
||||
private final List<Marker> markers;
|
||||
private final List<Integer> markerIds;
|
||||
private CutsceneManager cutsceneManager;
|
||||
private Location start;
|
||||
private Location end;
|
||||
private Map<UUID, BukkitTask> tasks;
|
||||
private boolean blackBorders;
|
||||
private boolean startFadeToBlack;
|
||||
private boolean endFadeToBlack;
|
||||
|
||||
public Cutscene(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.markers = new ArrayList<>();
|
||||
this.markerIds = new ArrayList<>();
|
||||
this.tasks = new HashMap<>();
|
||||
cutsceneManager = Manager.getInstance(CutsceneManager.class);
|
||||
if (cutsceneManager == null) {
|
||||
error("CutsceneManager is null, could not create a Cutscene");
|
||||
}
|
||||
}
|
||||
|
||||
public Cutscene(@NotNull String id, String name, @NotNull ArrayList<Marker> markers) {
|
||||
this.id = id.toUpperCase();
|
||||
this.name = name;
|
||||
this.markers = markers;
|
||||
markerIds = new ArrayList<>();
|
||||
for (Marker marker : markers) {
|
||||
markerIds.add(marker.getId());
|
||||
}
|
||||
if (markers.isEmpty()) return;
|
||||
if (markers.getFirst().getFrames().isEmpty()) return;
|
||||
start = markers.getFirst().getFrames().getFirst().getLocation();
|
||||
end = markers.getLast().getFrames().getLast().getLocation();
|
||||
this.tasks = new HashMap<>();
|
||||
cutsceneManager = Manager.getInstance(CutsceneManager.class);
|
||||
if (cutsceneManager == null) {
|
||||
error("CutsceneManager is null, could not create a Cutscene");
|
||||
}
|
||||
}
|
||||
|
||||
public void setMarkers() {
|
||||
for (Integer i : markerIds) {
|
||||
markers.add(Marker.getMarker(i));
|
||||
}
|
||||
}
|
||||
|
||||
public void addMarker(Marker marker) {
|
||||
this.markers.add(marker);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id.toUpperCase();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public List<Marker> getMarkers() {
|
||||
return this.markers;
|
||||
}
|
||||
|
||||
public Location getStart() {
|
||||
return this.start;
|
||||
}
|
||||
|
||||
public void setStart(Location start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public Location getEnd() {
|
||||
return this.end;
|
||||
}
|
||||
|
||||
public void setEnd(Location end) {
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public void addMarkerId(Integer id) {
|
||||
this.markerIds.add(id);
|
||||
}
|
||||
|
||||
public long time() {
|
||||
long time = 0;
|
||||
for (Marker marker : this.markers) {
|
||||
if (marker.getOverAllTime() != null) time += marker.getOverAllTime();
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
public void play(@NotNull Player p) {
|
||||
if (cutsceneManager.isPlayingCutscene(p)) {
|
||||
p.sendMessage(textComp("You are already playing a cutscene!"));
|
||||
}
|
||||
cutsceneManager.addCurrentPlayingCutscene(this, p);
|
||||
|
||||
// hide toolbar and make it spectate entity
|
||||
p.setGameMode(GameMode.SPECTATOR);
|
||||
|
||||
// set black borders
|
||||
if (blackBorders) {
|
||||
p.getInventory().setHelmet(new ItemStack(Material.PUMPKIN));
|
||||
p.updateInventory();
|
||||
}
|
||||
|
||||
if (startFadeToBlack) {
|
||||
showBlackScreen(p, 2, 1, 1);
|
||||
}
|
||||
|
||||
BukkitTask task =
|
||||
Bukkit.getScheduler()
|
||||
.runTaskAsynchronously(
|
||||
SR.getPlugin(),
|
||||
() -> {
|
||||
int finalI = 0;
|
||||
for (Marker marker : markers) {
|
||||
for (int i = 0; i < marker.getFrames().size(); i++) {
|
||||
int finalI1 = i;
|
||||
Bukkit.getScheduler()
|
||||
.runTaskLater(
|
||||
SR.getPlugin(),
|
||||
() -> {
|
||||
p.teleport(marker.getFrames().get(finalI1).getLocation());
|
||||
marker.getFrames().get(finalI1).play();
|
||||
},
|
||||
(marker.getTimeBetweenFrames() * finalI) / 50);
|
||||
finalI++;
|
||||
}
|
||||
}
|
||||
if (endFadeToBlack) {
|
||||
Bukkit.getScheduler()
|
||||
.runTask(SR.getPlugin(), () -> showBlackScreen(p, 2, 1, 1));
|
||||
}
|
||||
});
|
||||
Bukkit.getScheduler()
|
||||
.runTaskAsynchronously(
|
||||
SR.getPlugin(),
|
||||
() -> {
|
||||
try {
|
||||
Thread.sleep(time());
|
||||
} catch (InterruptedException e) {
|
||||
error("Error while playing cutscene: " + e.getMessage());
|
||||
}
|
||||
Bukkit.getScheduler().runTask(SR.getPlugin(), () -> stop(p));
|
||||
});
|
||||
tasks.put(p.getUniqueId(), task);
|
||||
}
|
||||
|
||||
public void stop(UUID player) {
|
||||
Player p = Bukkit.getPlayer(player);
|
||||
if (p == null) return;
|
||||
stop(p);
|
||||
}
|
||||
|
||||
public void stop(@NotNull Player p) {
|
||||
if (cutsceneManager.isPlayingCutscene(p)) {
|
||||
if (cutsceneManager.getPlayingCutscene(p).equals(this.id)) {
|
||||
cutsceneManager.removeCurrentPlayingCutscene(this, p);
|
||||
tasks.get(p.getUniqueId()).cancel();
|
||||
p.sendMessage(Component.text("You stopped playing the cutscene!"));
|
||||
}
|
||||
} else {
|
||||
p.sendMessage(Component.text("You are not playing a cutscene!"));
|
||||
}
|
||||
}
|
||||
|
||||
public void calculateMarkers() {
|
||||
if (markers.isEmpty()) return;
|
||||
for (int i = 0; i < markers.size(); i++) {
|
||||
if (i < markers.size() - 1) {
|
||||
markers.get(i).calculateFrames(markers.get(i + 1));
|
||||
} else {
|
||||
ArrayList<Frame> frames = new ArrayList<>();
|
||||
frames.add(new Frame(markers.get(i).getStart()));
|
||||
markers.get(i).setFrames(frames);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class CutsceneManager extends Manager {
|
||||
// TODO: spectator to hide toolbar (make it ride an invisible entity to prevent movement)
|
||||
// TODO: save modifications if any
|
||||
// TODO: do you set player back to original position ?
|
||||
// TODO: make a system to easily create cutscenesw
|
||||
|
||||
private List<Cutscene> cutscenes;
|
||||
|
||||
// cutscene id, player uuid
|
||||
private Map<String, UUID> currentPlayingCutscenes;
|
||||
|
||||
private Map<UUID, PlayerOrigin> playerOrigins;
|
||||
|
||||
private List<String> cutsceneIds;
|
||||
|
||||
/** Load the manager */
|
||||
@Override
|
||||
public void load() {
|
||||
super.load();
|
||||
cutscenes = new ArrayList<>();
|
||||
currentPlayingCutscenes = new HashMap<>();
|
||||
playerOrigins = new HashMap<>();
|
||||
cutsceneIds = new ArrayList<>();
|
||||
}
|
||||
|
||||
/** Unload the manager */
|
||||
@Override
|
||||
public void unload() {
|
||||
super.unload();
|
||||
cutscenes.clear();
|
||||
currentPlayingCutscenes.clear();
|
||||
playerOrigins.clear();
|
||||
cutsceneIds.clear();
|
||||
}
|
||||
|
||||
public void createCutscene(String id) {
|
||||
Cutscene cutscene = new Cutscene(id, id);
|
||||
addCutscene(cutscene);
|
||||
}
|
||||
|
||||
public void removeCutscene(String id) {
|
||||
Cutscene cutscene = getCutscene(id);
|
||||
removeCutscene(cutscene);
|
||||
}
|
||||
|
||||
public void addCutscene(Cutscene cutscene) {
|
||||
cutscenes.add(cutscene);
|
||||
cutsceneIds.add(cutscene.getId());
|
||||
}
|
||||
|
||||
public void removeCutscene(Cutscene cutscene) {
|
||||
cutscenes.remove(cutscene);
|
||||
cutsceneIds.remove(cutscene.getId().toUpperCase());
|
||||
}
|
||||
|
||||
public void addCurrentPlayingCutscene(@NotNull Cutscene cutscene, @NotNull Player p) {
|
||||
currentPlayingCutscenes.put(cutscene.getId(), p.getUniqueId());
|
||||
}
|
||||
|
||||
public void removeCurrentPlayingCutscene(@NotNull Cutscene cutscene, @NotNull Player p) {
|
||||
currentPlayingCutscenes.remove(cutscene.getId(), p.getUniqueId());
|
||||
}
|
||||
|
||||
public List<String> getCutscenesId() {
|
||||
return cutsceneIds;
|
||||
}
|
||||
|
||||
public void stopCutscene(Player p) {
|
||||
for (String string : currentPlayingCutscenes.keySet()) {
|
||||
if (currentPlayingCutscenes.get(string).equals(p.getUniqueId())) {
|
||||
currentPlayingCutscenes.remove(string, p.getUniqueId());
|
||||
Cutscene cutscene = getCutscene(string);
|
||||
if (cutscene != null) {
|
||||
cutscene.stop(p);
|
||||
PlayerOrigin.restore(playerOrigins.get(p.getUniqueId()), p);
|
||||
playerOrigins.remove(p.getUniqueId());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stopCutscenesForAllPlayers() {
|
||||
for (String string : currentPlayingCutscenes.keySet()) {
|
||||
Cutscene cutscene = getCutscene(string);
|
||||
if (cutscene != null) {
|
||||
UUID uuid = currentPlayingCutscenes.get(string);
|
||||
cutscene.stop(uuid);
|
||||
currentPlayingCutscenes.remove(cutscene.getId(), uuid);
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
if (player == null) return;
|
||||
PlayerOrigin.restore(playerOrigins.get(uuid), player);
|
||||
playerOrigins.remove(uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void playCutscene(Cutscene cutscene, Player p) {
|
||||
if (cutscene == null) {
|
||||
p.sendMessage(textComp("<red>There was an error with the cutscene!"));
|
||||
return;
|
||||
}
|
||||
if (cutscenes.contains(cutscene) && !currentPlayingCutscenes.containsValue(p.getUniqueId())) {
|
||||
currentPlayingCutscenes.put(cutscene.getId(), p.getUniqueId());
|
||||
setPlayerOrigins(p);
|
||||
cutscene.play(p);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Cutscene getCutscene(Player p) {
|
||||
for (Entry<String, UUID> entry : currentPlayingCutscenes.entrySet()) {
|
||||
if (entry.getValue().equals(p.getUniqueId())) return getCutscene(entry.getKey());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Cutscene getCutscene(@NotNull String id) {
|
||||
if (!cutsceneIds.contains(id.toUpperCase())) {
|
||||
return null;
|
||||
}
|
||||
for (Cutscene cutscene : cutscenes) {
|
||||
if (cutscene.getId().equalsIgnoreCase(id.toUpperCase())) return cutscene;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isPlayingCutscene(@NotNull Player p) {
|
||||
return currentPlayingCutscenes.containsValue(p.getUniqueId());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getPlayingCutscene(@NotNull Player p) {
|
||||
for (Entry<String, UUID> entry : currentPlayingCutscenes.entrySet()) {
|
||||
if (entry.getValue().equals(p.getUniqueId())) return entry.getKey();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setPlayerOrigins(@NotNull Player p) {
|
||||
playerOrigins.put(
|
||||
p.getUniqueId(),
|
||||
new PlayerOrigin(
|
||||
p.getLocation(),
|
||||
p.getAllowFlight(),
|
||||
p.isFlying(),
|
||||
p.getWalkSpeed(),
|
||||
p.getFlySpeed(),
|
||||
p.getGameMode()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class EntityCinematicAction {
|
||||
private Player p;
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import java.util.Map;
|
||||
import me.unurled.sacredrealms.sr.utils.gson.LocationSerializer;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Frame class
|
||||
*
|
||||
* <p>example of serializable frame:
|
||||
*
|
||||
* <pre>{@code
|
||||
* {
|
||||
* "id": 1,
|
||||
* "entities": "entities serializable",
|
||||
* "blocks": "blocks serializable",
|
||||
* "action": "action", // if type is entity
|
||||
* "location": {
|
||||
* "world": "world",
|
||||
* "x": 0,
|
||||
* "y": 0,
|
||||
* "z": 0,
|
||||
* "yaw": 0,
|
||||
* "pitch": 0
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
*/
|
||||
public class Frame {
|
||||
private static int idCounter = 0;
|
||||
private final Location location;
|
||||
private final int id;
|
||||
@Nullable private Map<Location, BlockData> blocks;
|
||||
|
||||
public Frame(Location location) {
|
||||
this.location = location;
|
||||
id = idCounter;
|
||||
idCounter++;
|
||||
blocks = null;
|
||||
}
|
||||
|
||||
public Frame(Location location, int ID) {
|
||||
this.location = location;
|
||||
this.id = ID;
|
||||
blocks = null;
|
||||
}
|
||||
|
||||
@Contract("_ -> new")
|
||||
public static @NotNull Frame deserialize(@NotNull JsonElement jsonElement) {
|
||||
int id = jsonElement.getAsJsonObject().get("id").getAsInt();
|
||||
Location loc = null;
|
||||
try {
|
||||
LocationSerializer locationDeserializer = new LocationSerializer();
|
||||
loc =
|
||||
locationDeserializer.deserialize(
|
||||
jsonElement.getAsJsonObject().get("location"), Location.class, null);
|
||||
} catch (Exception e) {
|
||||
error("Error deserializing location in Frame with ID: " + id);
|
||||
}
|
||||
|
||||
Frame frame = new Frame(loc, id);
|
||||
|
||||
try {
|
||||
frame.setBlocks((Map<Location, BlockData>) jsonElement.getAsJsonObject().get("blocks"));
|
||||
} catch (Exception e) {
|
||||
error("Error deserializing blocks in Frame with ID: " + id);
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/** Play the frame aka move stuff around :shrug: */
|
||||
public void play() {}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public @Nullable Map<Location, BlockData> getBlocks() {
|
||||
return blocks;
|
||||
}
|
||||
|
||||
public void setBlocks(@Nullable Map<Location, BlockData> blocks) {
|
||||
this.blocks = blocks;
|
||||
}
|
||||
|
||||
public JsonElement serialize() {
|
||||
String s =
|
||||
"{"
|
||||
+ "\"id\":"
|
||||
+ id
|
||||
+ ","
|
||||
+ ","
|
||||
+ "\"blocks\":"
|
||||
+ blocks
|
||||
+ ","
|
||||
+ "\"location\":"
|
||||
+ location.serialize()
|
||||
+ "}";
|
||||
return new JsonPrimitive(s);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.CutsceneUtil.interpolateFrames;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.bukkit.Location;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Marker class
|
||||
*
|
||||
* <pre>{@code
|
||||
* {
|
||||
* "id": 1,
|
||||
* "frames": [ 1, 2, 3 ], // Frame IDs
|
||||
* "timeBetweenFrames": 20,
|
||||
* "overAllTime": 60,
|
||||
* "start": {
|
||||
* "world": "world",
|
||||
* "x": 0,
|
||||
* "y": 0,
|
||||
* "z": 0,
|
||||
* "yaw": 0,
|
||||
* "pitch": 0
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
*/
|
||||
public class Marker {
|
||||
|
||||
private static int idCounter = 0;
|
||||
private static List<Marker> markers = new ArrayList<>();
|
||||
private final int id;
|
||||
private List<Frame> frames;
|
||||
private Long timeBetweenFrames;
|
||||
private Long overAllTime;
|
||||
private Location start;
|
||||
|
||||
public Marker(Integer id) {
|
||||
frames = new ArrayList<>();
|
||||
timeBetweenFrames = 0L;
|
||||
overAllTime = 0L;
|
||||
if (id == null) {
|
||||
this.id = idCounter;
|
||||
idCounter++;
|
||||
} else {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
public Marker(@NotNull List<Frame> frames, long timeBetweenFrames, Location start) {
|
||||
this.frames = frames;
|
||||
this.timeBetweenFrames = timeBetweenFrames;
|
||||
this.overAllTime = timeBetweenFrames * frames.size();
|
||||
this.start = start;
|
||||
id = idCounter;
|
||||
idCounter++;
|
||||
}
|
||||
|
||||
public static List<Marker> getMarkers() {
|
||||
return markers;
|
||||
}
|
||||
|
||||
public static void setMarkers(List<Marker> markers) {
|
||||
Marker.markers = markers;
|
||||
}
|
||||
|
||||
public static @Nullable Marker getMarker(int ID) {
|
||||
for (Marker marker : markers) {
|
||||
if (marker.getId() == ID) {
|
||||
return marker;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Frame> getFrames() {
|
||||
return frames;
|
||||
}
|
||||
|
||||
public void setFrames(List<Frame> frames) {
|
||||
this.frames = frames;
|
||||
}
|
||||
|
||||
public Long getTimeBetweenFrames() {
|
||||
return timeBetweenFrames;
|
||||
}
|
||||
|
||||
public void setTimeBetweenFrames(Long timeBetweenFrames) {
|
||||
this.timeBetweenFrames = timeBetweenFrames;
|
||||
}
|
||||
|
||||
public Long getOverAllTime() {
|
||||
return overAllTime;
|
||||
}
|
||||
|
||||
public void setOverAllTime(Long overAllTime) {
|
||||
this.overAllTime = overAllTime;
|
||||
}
|
||||
|
||||
public Location getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public void setStart(Location start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public void calculateFrames(Marker endMarker) {
|
||||
frames = interpolateFrames(this, endMarker, timeBetweenFrames);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void addFrame(Frame frame) {
|
||||
frames.add(frame);
|
||||
}
|
||||
|
||||
public void removeFrame(Frame frame) {
|
||||
frames.remove(frame);
|
||||
}
|
||||
|
||||
public void removeFrame(int index) {
|
||||
frames.remove(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Marker{"
|
||||
+ "ID="
|
||||
+ id
|
||||
+ ", frames="
|
||||
+ frames
|
||||
+ ", timeBetweenFrames="
|
||||
+ timeBetweenFrames
|
||||
+ ", overAllTime="
|
||||
+ overAllTime
|
||||
+ ", start="
|
||||
+ start
|
||||
+ '}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record PlayerOrigin(
|
||||
Location location,
|
||||
boolean allowFlight,
|
||||
boolean flying,
|
||||
float walkSpeed,
|
||||
float flySpeed,
|
||||
GameMode gameMode) {
|
||||
public static void restore(@NotNull PlayerOrigin origin, @NotNull Player p) {
|
||||
p.teleport(origin.location());
|
||||
p.setAllowFlight(origin.allowFlight());
|
||||
p.setFlying(origin.flying());
|
||||
p.setWalkSpeed(origin.walkSpeed());
|
||||
p.setFlySpeed(origin.flySpeed());
|
||||
p.setGameMode(origin.gameMode());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
|
||||
import io.papermc.paper.event.player.PlayerArmSwingEvent;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.npc.ArmSwing;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.npc.EntityFrame;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Pose;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.PlayerInventory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PlayerRecording {
|
||||
private final Player player;
|
||||
private final EntityFrame entityFrame;
|
||||
private ArmSwing swing;
|
||||
|
||||
public PlayerRecording(Player player, EntityFrame entityFrame) {
|
||||
this.player = player;
|
||||
this.entityFrame = entityFrame;
|
||||
}
|
||||
|
||||
private static EntityPose toEntityPose(Pose pose) {
|
||||
return pose == Pose.SNEAKING ? EntityPose.SITTING : EntityPose.valueOf(pose.name());
|
||||
}
|
||||
|
||||
private static Pose toBukkitPose(EntityPose pose) {
|
||||
return pose == EntityPose.SITTING ? Pose.SNEAKING : Pose.valueOf(pose.name());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onArmSwing(@NotNull PlayerArmSwingEvent e) {
|
||||
if (e.getPlayer().getUniqueId() != player.getUniqueId()) {
|
||||
return;
|
||||
}
|
||||
addSwing(
|
||||
e.getHand() == EquipmentSlot.HAND
|
||||
? ArmSwing.RIGHT
|
||||
: (e.getHand() == EquipmentSlot.OFF_HAND ? ArmSwing.LEFT : ArmSwing.BOTH));
|
||||
}
|
||||
|
||||
private void addSwing(ArmSwing swing) {
|
||||
if (this.swing != null && this.swing != swing) {
|
||||
this.swing = ArmSwing.BOTH;
|
||||
return;
|
||||
}
|
||||
|
||||
this.swing = swing;
|
||||
}
|
||||
|
||||
public EntityFrame captureFrame() {
|
||||
PlayerInventory inv = player.getInventory();
|
||||
Pose pose = player.isInsideVehicle() ? Pose.SITTING : player.getPose();
|
||||
EntityFrame data =
|
||||
new EntityFrame(
|
||||
player.getLocation(),
|
||||
toEntityPose(pose),
|
||||
swing,
|
||||
inv.getItemInMainHand().isEmpty() ? null : inv.getItemInMainHand(),
|
||||
inv.getItemInOffHand().isEmpty() ? null : inv.getItemInOffHand(),
|
||||
inv.getHelmet(),
|
||||
inv.getChestplate(),
|
||||
inv.getLeggings(),
|
||||
inv.getBoots());
|
||||
swing = null;
|
||||
return data;
|
||||
}
|
||||
|
||||
public void applyState(@NotNull EntityFrame value) {
|
||||
player.teleport(value.location());
|
||||
player.setPose(toBukkitPose(value.pose()));
|
||||
PlayerInventory inv = player.getInventory();
|
||||
inv.setItemInMainHand(value.mainHand());
|
||||
inv.setItemInOffHand(value.offHand());
|
||||
inv.setHelmet(value.helmet());
|
||||
inv.setChestplate(value.chestplate());
|
||||
inv.setLeggings(value.leggings());
|
||||
inv.setBoots(value.boots());
|
||||
player.updateInventory();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene.gson;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import java.lang.reflect.Type;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.Action;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ActionGson {
|
||||
public class Deserializer implements JsonDeserializer<Action> {
|
||||
|
||||
/**
|
||||
* Gson invokes this call-back method during deserialization when it encounters a field of the
|
||||
* specified type.
|
||||
*
|
||||
* <p>In the implementation of this call-back method, you should consider invoking {@link
|
||||
* JsonDeserializationContext#deserialize(JsonElement, Type)} method to create objects for any
|
||||
* non-trivial field of the returned object. However, you should never invoke it on the same
|
||||
* type passing {@code json} since that will cause an infinite loop (Gson will call your
|
||||
* call-back method again).
|
||||
*
|
||||
* @param json The Json data being deserialized
|
||||
* @param typeOfT The type of the Object to deserialize to
|
||||
* @param context
|
||||
* @return a deserialized object of the specified type typeOfT which is a subclass of {@code T}
|
||||
* @throws JsonParseException if json is not in the expected format of {@code typeofT}
|
||||
*/
|
||||
@Override
|
||||
public Action deserialize(
|
||||
@NotNull JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
return Action.valueOf(json.getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
public class Serializer implements JsonSerializer<Action> {
|
||||
|
||||
/**
|
||||
* Gson invokes this call-back method during serialization when it encounters a field of the
|
||||
* specified type.
|
||||
*
|
||||
* <p>In the implementation of this call-back method, you should consider invoking {@link
|
||||
* JsonSerializationContext#serialize(Object, Type)} method to create JsonElements for any
|
||||
* non-trivial field of the {@code src} object. However, you should never invoke it on the
|
||||
* {@code src} object itself since that will cause an infinite loop (Gson will call your
|
||||
* call-back method again).
|
||||
*
|
||||
* @param src the object that needs to be converted to Json.
|
||||
* @param typeOfSrc the actual type (fully genericized version) of the source object.
|
||||
* @param context
|
||||
* @return a JsonElement corresponding to the specified object.
|
||||
*/
|
||||
@Override
|
||||
public JsonElement serialize(Action src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return new JsonPrimitive(src.name());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene.gson;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.Action;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
public class EntityActionGson {
|
||||
public class Deserializer implements JsonDeserializer<Map<Entity, Action>> {
|
||||
|
||||
/**
|
||||
* Gson invokes this call-back method during deserialization when it encounters a field of the
|
||||
* specified type.
|
||||
*
|
||||
* <p>In the implementation of this call-back method, you should consider invoking {@link
|
||||
* JsonDeserializationContext#deserialize(JsonElement, Type)} method to create objects for any
|
||||
* non-trivial field of the returned object. However, you should never invoke it on the same
|
||||
* type passing {@code json} since that will cause an infinite loop (Gson will call your
|
||||
* call-back method again).
|
||||
*
|
||||
* @param json The Json data being deserialized
|
||||
* @param typeOfT The type of the Object to deserialize to
|
||||
* @param context
|
||||
* @return a deserialized object of the specified type typeOfT which is a subclass of {@code T}
|
||||
* @throws JsonParseException if json is not in the expected format of {@code typeofT}
|
||||
*/
|
||||
@Override
|
||||
public Map<Entity, Action> deserialize(
|
||||
JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class Serializer implements JsonSerializer<Map<Entity, Action>> {
|
||||
|
||||
/**
|
||||
* Gson invokes this call-back method during serialization when it encounters a field of the
|
||||
* specified type.
|
||||
*
|
||||
* <p>In the implementation of this call-back method, you should consider invoking {@link
|
||||
* JsonSerializationContext#serialize(Object, Type)} method to create JsonElements for any
|
||||
* non-trivial field of the {@code src} object. However, you should never invoke it on the
|
||||
* {@code src} object itself since that will cause an infinite loop (Gson will call your
|
||||
* call-back method again).
|
||||
*
|
||||
* @param src the object that needs to be converted to Json.
|
||||
* @param typeOfSrc the actual type (fully genericized version) of the source object.
|
||||
* @param context
|
||||
* @return a JsonElement corresponding to the specified object.
|
||||
*/
|
||||
@Override
|
||||
public JsonElement serialize(
|
||||
Map<Entity, Action> src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene.npc;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.components.packet.PacketManager.sendPacketTo;
|
||||
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityAnimation;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityAnimation.EntityAnimationType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public enum ArmSwing {
|
||||
LEFT,
|
||||
RIGHT,
|
||||
BOTH;
|
||||
|
||||
public static void swingArm(@NotNull ArmSwing arm, Player p, int entityId) {
|
||||
// Swing the arm
|
||||
if (arm.isLeft()) {
|
||||
sendPacketTo(
|
||||
new WrapperPlayServerEntityAnimation(entityId, EntityAnimationType.SWING_OFF_HAND), p);
|
||||
}
|
||||
if (arm.isRight()) {
|
||||
sendPacketTo(
|
||||
new WrapperPlayServerEntityAnimation(entityId, EntityAnimationType.SWING_MAIN_ARM), p);
|
||||
}
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
public @NotNull Boolean isLeft() {
|
||||
return this == LEFT || this == BOTH;
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
public @NotNull Boolean isRight() {
|
||||
return this == RIGHT || this == BOTH;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package me.unurled.sacredrealms.sr.components.cutscene.npc;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.pose.EntityPose;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import me.unurled.sacredrealms.sr.utils.Items;
|
||||
import me.unurled.sacredrealms.sr.utils.gson.LocationSerializer;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record EntityFrame(
|
||||
Location location,
|
||||
EntityPose pose,
|
||||
ArmSwing swing,
|
||||
ItemStack mainHand,
|
||||
ItemStack offHand,
|
||||
ItemStack helmet,
|
||||
ItemStack chestplate,
|
||||
ItemStack leggings,
|
||||
ItemStack boots) {
|
||||
|
||||
public static @NotNull EntityFrame deserialize(@NotNull JsonElement jsonElement) {
|
||||
Location location =
|
||||
new LocationSerializer()
|
||||
.deserialize(jsonElement.getAsJsonObject().get("location"), Location.class, null);
|
||||
EntityPose pose = EntityPose.valueOf(jsonElement.getAsJsonObject().get("pose").getAsString());
|
||||
ArmSwing swing = ArmSwing.valueOf(jsonElement.getAsJsonObject().get("swing").getAsString());
|
||||
ItemStack mainHand = Items.deserialize(jsonElement.getAsJsonObject().get("mainHand"));
|
||||
ItemStack offHand = Items.deserialize(jsonElement.getAsJsonObject().get("offHand"));
|
||||
ItemStack helmet = Items.deserialize(jsonElement.getAsJsonObject().get("helmet"));
|
||||
ItemStack chestplate = Items.deserialize(jsonElement.getAsJsonObject().get("chestplate"));
|
||||
ItemStack leggings = Items.deserialize(jsonElement.getAsJsonObject().get("leggings"));
|
||||
ItemStack boots = Items.deserialize(jsonElement.getAsJsonObject().get("boots"));
|
||||
return new EntityFrame(
|
||||
location, pose, swing, mainHand, offHand, helmet, chestplate, leggings, boots);
|
||||
}
|
||||
|
||||
public @NotNull JsonElement serialize() {
|
||||
String s =
|
||||
"""
|
||||
{
|
||||
"location": %s,
|
||||
"pose": %s,
|
||||
"swing": %s,
|
||||
"mainHand": %s,
|
||||
"offHand": %s,
|
||||
"helmet": %s,
|
||||
"chestplate": %s,
|
||||
"leggings": %s,
|
||||
"boots": %s
|
||||
}
|
||||
"""
|
||||
.formatted(
|
||||
location.serialize(),
|
||||
pose.name(),
|
||||
swing.name(),
|
||||
mainHand.serialize(),
|
||||
offHand.serialize(),
|
||||
helmet.serialize(),
|
||||
chestplate.serialize(),
|
||||
leggings.serialize(),
|
||||
boots.serialize());
|
||||
return new JsonPrimitive(s);
|
||||
}
|
||||
}
|
|
@ -8,18 +8,23 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
||||
import me.unurled.sacredrealms.sr.components.item.ItemStackDeserializer;
|
||||
import me.unurled.sacredrealms.sr.components.item.ItemStackSerializer;
|
||||
import me.unurled.sacredrealms.sr.components.player.PotionEffectDeserializer;
|
||||
import me.unurled.sacredrealms.sr.data.DataHandler;
|
||||
import me.unurled.sacredrealms.sr.data.DataManager;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Mob;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
|
||||
import org.bukkit.event.entity.EntityCombustEvent;
|
||||
import org.bukkit.event.entity.EntitySpawnEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
@ -70,6 +75,25 @@ public class EntityManager extends Manager {
|
|||
});
|
||||
}
|
||||
|
||||
/** Save the data */
|
||||
@Override
|
||||
public void saveData() {
|
||||
// for every entity if not player kill it
|
||||
killAllEntities();
|
||||
}
|
||||
|
||||
public void killAllEntities() {
|
||||
entities.forEach(
|
||||
(uuid, srEntity) -> {
|
||||
Entity e = Bukkit.getEntity(uuid);
|
||||
if (e instanceof LivingEntity liv && !(e instanceof Player)) {
|
||||
liv.setHealth(0.0);
|
||||
e.remove();
|
||||
}
|
||||
});
|
||||
entities.clear();
|
||||
}
|
||||
|
||||
public void saveType(@NotNull SREntityType type) {
|
||||
// save type
|
||||
DataManager dm = Manager.getInstance(DataManager.class);
|
||||
|
@ -100,8 +124,11 @@ public class EntityManager extends Manager {
|
|||
entities.put(entity.getUuid(), entity);
|
||||
}
|
||||
|
||||
public void addEntity(@NotNull Entity e) {
|
||||
entities.put(e.getUniqueId(), new SREntity(e));
|
||||
public void addEntity(@NotNull SREntityType type, @NotNull Entity e) {
|
||||
entities.put(
|
||||
e.getUniqueId(),
|
||||
new SREntity(
|
||||
e, type.getAttributes().get(Attribute.HEALTH), type.getExperience(), type.getId()));
|
||||
}
|
||||
|
||||
public boolean isSREntity(@NotNull UUID uuid) {
|
||||
|
@ -131,7 +158,8 @@ public class EntityManager extends Manager {
|
|||
// spawn entity
|
||||
List<SREntity> srEntities = new ArrayList<>();
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Entity e = world.spawnEntity(new Location(world, x, y, z), type.getType());
|
||||
Entity e =
|
||||
world.spawnEntity(new Location(world, x, y, z), type.getType(), SpawnReason.CUSTOM);
|
||||
if (e instanceof Mob mob) {
|
||||
if (type.getHandItem() != null) {
|
||||
mob.getEquipment().setItemInMainHand(type.getHandItem());
|
||||
|
@ -143,7 +171,13 @@ public class EntityManager extends Manager {
|
|||
mob.getEquipment().setItemInOffHand(type.getSecondHandItem());
|
||||
}
|
||||
}
|
||||
SREntity srEntity = new SREntity(e);
|
||||
SREntity srEntity =
|
||||
new SREntity(
|
||||
e, type.getAttributes().get(Attribute.HEALTH), type.getExperience(), type.getId());
|
||||
|
||||
if (type.getName() != null && !type.getName().isEmpty()) {
|
||||
srEntity.applyName(type, e);
|
||||
}
|
||||
addEntity(srEntity);
|
||||
srEntities.add(srEntity);
|
||||
}
|
||||
|
@ -153,12 +187,19 @@ public class EntityManager extends Manager {
|
|||
|
||||
@EventHandler
|
||||
public void onEntitySpawn(@NotNull EntitySpawnEvent e) {
|
||||
if (e.getEntity() instanceof Player) return;
|
||||
|
||||
if (isSREntity(e.getEntity().getUniqueId())) return;
|
||||
|
||||
if (!(e.getEntity() instanceof Mob)) return;
|
||||
if (e.getEntity().getEntitySpawnReason() != SpawnReason.CUSTOM
|
||||
&& e.getEntity().getEntitySpawnReason() != SpawnReason.COMMAND) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cancel entity burn
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
@EventHandler
|
||||
public void onEntityBurn(@NotNull EntityCombustEvent e) {
|
||||
e.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
package me.unurled.sacredrealms.sr.components.entity;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
||||
|
||||
import java.util.UUID;
|
||||
import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SREntity {
|
||||
private final UUID uuid;
|
||||
private double health = 100;
|
||||
private Long experience = 0L;
|
||||
private final String typeId;
|
||||
private double health;
|
||||
private Long experience;
|
||||
|
||||
public SREntity(@NotNull Entity e) {
|
||||
public SREntity(@NotNull Entity e, double health, Long exp, String typeId) {
|
||||
uuid = e.getUniqueId();
|
||||
this.health = health;
|
||||
this.experience = exp;
|
||||
this.typeId = typeId;
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
|
@ -32,4 +39,23 @@ public class SREntity {
|
|||
public void setHealth(double health) {
|
||||
this.health = health;
|
||||
}
|
||||
|
||||
public String getTypeId() {
|
||||
return typeId;
|
||||
}
|
||||
|
||||
public void applyName(@NotNull SREntityType type, @NotNull Entity e) {
|
||||
e.customName(
|
||||
textComp(
|
||||
"<green>Lv."
|
||||
+ type.getLevel()
|
||||
+ " <gold>"
|
||||
+ type.getName()
|
||||
+ "<red>"
|
||||
+ health
|
||||
+ "/"
|
||||
+ type.getAttributes().get(Attribute.HEALTH)
|
||||
+ "❤"));
|
||||
e.setCustomNameVisible(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ public class SREntityType {
|
|||
}
|
||||
|
||||
public EntityType getType() {
|
||||
return type = type == null ? EntityType.ZOMBIE : type;
|
||||
return type == null ? EntityType.ZOMBIE : type;
|
||||
}
|
||||
|
||||
public void setType(EntityType type) {
|
||||
|
@ -144,7 +144,7 @@ public class SREntityType {
|
|||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
return item == null ? new ItemStack(Material.BARRIER) : item;
|
||||
return item == null ? new ItemStack(Material.AIR) : item;
|
||||
}
|
||||
|
||||
public void setItem(ItemStack item) {
|
||||
|
@ -153,10 +153,10 @@ public class SREntityType {
|
|||
|
||||
public List<ItemStack> getArmor() {
|
||||
if (armor.isEmpty()) {
|
||||
armor.add(new ItemStack(Material.BARRIER));
|
||||
armor.add(new ItemStack(Material.BARRIER));
|
||||
armor.add(new ItemStack(Material.BARRIER));
|
||||
armor.add(new ItemStack(Material.BARRIER));
|
||||
armor.add(new ItemStack(Material.AIR));
|
||||
armor.add(new ItemStack(Material.AIR));
|
||||
armor.add(new ItemStack(Material.AIR));
|
||||
armor.add(new ItemStack(Material.AIR));
|
||||
}
|
||||
return armor;
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ public class SREntityType {
|
|||
}
|
||||
|
||||
public ItemStack getHandItem() {
|
||||
return handItem == null ? new ItemStack(Material.BARRIER) : handItem;
|
||||
return handItem == null ? new ItemStack(Material.AIR) : handItem;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
@ -176,7 +176,7 @@ public class SREntityType {
|
|||
}
|
||||
|
||||
public ItemStack getSecondHandItem() {
|
||||
return secondHandItem == null ? new ItemStack(Material.BARRIER) : secondHandItem;
|
||||
return secondHandItem == null ? new ItemStack(Material.AIR) : secondHandItem;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
|
|
@ -150,7 +150,7 @@ public class Item {
|
|||
}
|
||||
|
||||
public Double getAttribute(Attribute attribute) {
|
||||
return attributes.get(attribute);
|
||||
return attributes.getOrDefault(attribute, 0.0);
|
||||
}
|
||||
|
||||
public void addAttribute(Attribute attribute, double value) {
|
||||
|
@ -244,7 +244,7 @@ public class Item {
|
|||
+ description
|
||||
+ "\", \"customModelData\": "
|
||||
+ customModelData
|
||||
+ "\", \"rarity\": \""
|
||||
+ ", \"rarity\": \""
|
||||
+ rarity
|
||||
+ "\", \"type\": \""
|
||||
+ type
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
package me.unurled.sacredrealms.sr.components.item;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.sacredrealms.sr.data.DataHandler;
|
||||
import me.unurled.sacredrealms.sr.data.DataManager;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
@ -42,7 +43,7 @@ public class ItemManager extends Manager {
|
|||
DataHandler dh = dm.getDataHandler();
|
||||
|
||||
if (dh == null) {
|
||||
SR.getInstance().getLogger().severe("DataHandler is null in ItemManager.loadData()!");
|
||||
error("DataHandler is null in ItemManager.loadData()!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -69,10 +70,12 @@ public class ItemManager extends Manager {
|
|||
items.put(item.getId(), item);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Item getItem(String id) {
|
||||
return items.get(id);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Item getItem(ItemStack item) {
|
||||
if (item == null) return null;
|
||||
if (item.getItemMeta() == null) return null;
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package me.unurled.sacredrealms.sr.components.npc;
|
||||
|
||||
public class NPCEntity {
|
||||
|
||||
private final int id;
|
||||
|
||||
public NPCEntity(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package me.unurled.sacredrealms.sr.components.npc;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.sacredrealms.sr.utils.ChunkWrapper;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class NPCManager extends Manager {
|
||||
|
||||
private final Map<ChunkWrapper, HashSet<NPCEntity>> npcPerChunk = new HashMap<>();
|
||||
public Map<UUID, NPCEntity> npcs = new HashMap<>();
|
||||
|
||||
public void register(@NotNull NPCEntity entity) {
|
||||
// TODO: Register the entity
|
||||
/*ChunkWrapper cw = new ChunkWrapper(entity.getClonedLocation().getChunk());
|
||||
if (!npcPerChunk.containsKey(cw)) {
|
||||
npcPerChunk.put(cw, new HashSet<>());
|
||||
}
|
||||
npcPerChunk.get(cw).add(entity);
|
||||
entity.spawn();*/
|
||||
}
|
||||
|
||||
public void removeEntity(NPCEntity entity) {
|
||||
/*try {
|
||||
entity.despawn();
|
||||
} catch (Exception e) {
|
||||
error("Failed to despawn entity: " + entity.getId());
|
||||
}
|
||||
ChunkWrapper cw = new ChunkWrapper(entity.getClonedLocation().getChunk());
|
||||
if (npcPerChunk.containsKey(cw)) {
|
||||
npcPerChunk.get(cw).remove(entity);
|
||||
}*/
|
||||
}
|
||||
|
||||
public void addEntity(NPCEntity entity) {
|
||||
// npcs.put(entity.getEntity().getUniqueId(), entity);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onChunkLoad(@NotNull ChunkLoadEvent e) {
|
||||
ChunkWrapper cw = new ChunkWrapper(e.getChunk());
|
||||
if (!npcPerChunk.containsKey(cw)) {
|
||||
return;
|
||||
}
|
||||
Bukkit.getScheduler()
|
||||
.scheduleSyncDelayedTask(
|
||||
SR.getPlugin(),
|
||||
() -> {
|
||||
HashSet<NPCEntity> npc = npcPerChunk.get(cw);
|
||||
for (NPCEntity entity : npc) {
|
||||
register(entity);
|
||||
}
|
||||
},
|
||||
20L * 2);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
package me.unurled.sacredrealms.sr.components.pack;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.File.getFileChecksum;
|
||||
import static me.unurled.sacredrealms.sr.utils.File.zipDirectory;
|
||||
import static me.unurled.sacredrealms.sr.utils.File.zipFile;
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.UUID;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.sacredrealms.sr.components.pack.hosts.HostingProvider;
|
||||
import me.unurled.sacredrealms.sr.components.pack.hosts.RustProvider;
|
||||
import me.unurled.sacredrealms.sr.config.Settings;
|
||||
import me.unurled.sacredrealms.sr.data.DataHandler;
|
||||
import me.unurled.sacredrealms.sr.data.DataManager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ResourcePackManager extends Manager {
|
||||
|
||||
private static final String RESOURCE_PACK_ZIP = "resource_pack.zip";
|
||||
private final HostingProvider hostingProvider;
|
||||
|
||||
public ResourcePackManager() {
|
||||
this.hostingProvider =
|
||||
new RustProvider(
|
||||
Settings.RESOURCE_PACK_URL.toString(), Settings.RESOURCE_PACK_API.toString());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static File packFile(String fileName) {
|
||||
try {
|
||||
new File(SR.getPlugin().getDataFolder(), "pack").mkdirs();
|
||||
|
||||
String[] filesInclude = {"assets", "pack.mcmeta"};
|
||||
|
||||
FileOutputStream fos =
|
||||
new FileOutputStream(new File(SR.getPlugin().getDataFolder(), fileName));
|
||||
ZipOutputStream zipOut = new ZipOutputStream(fos);
|
||||
|
||||
zipOut.setLevel(9);
|
||||
|
||||
for (String filePath : filesInclude) {
|
||||
File fileToZip = new File(SR.getPlugin().getDataFolder() + "/pack", filePath);
|
||||
if (fileToZip.isDirectory()) {
|
||||
zipDirectory(fileToZip, fileToZip.getName(), zipOut);
|
||||
} else {
|
||||
zipFile(fileToZip, fileToZip.getName(), zipOut);
|
||||
}
|
||||
}
|
||||
zipOut.close();
|
||||
fos.close();
|
||||
log("ZIP file created successfully!");
|
||||
} catch (IOException e) {
|
||||
error("Failed to create resource pack");
|
||||
}
|
||||
return new File(SR.getPlugin().getDataFolder(), fileName);
|
||||
}
|
||||
|
||||
/** Save the data */
|
||||
@Override
|
||||
public void saveData() {
|
||||
super.saveData();
|
||||
DataManager dm = Manager.getInstance(DataManager.class);
|
||||
DataHandler dh = dm.getDataHandler();
|
||||
dh.set("pack.url", hostingProvider.getMinecraftPackURL());
|
||||
dh.set("pack.uuid", hostingProvider.getPackUUID().toString());
|
||||
dh.set("pack.sha1", hostingProvider.getPackUUID().toString());
|
||||
}
|
||||
|
||||
/** Load the data */
|
||||
@Override
|
||||
public void loadData() {
|
||||
super.loadData();
|
||||
DataManager dm = Manager.getInstance(DataManager.class);
|
||||
DataHandler dh = dm.getDataHandler();
|
||||
String packUUID = dh.get("pack.uuid");
|
||||
if (packUUID == null) {
|
||||
return;
|
||||
}
|
||||
hostingProvider.setPackUUID(UUID.fromString(packUUID));
|
||||
hostingProvider.setPackURL(dh.get("pack.url"));
|
||||
hostingProvider.setSHA1(dh.get("pack.sha1").getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* upload a file to the hosting provider and return the url
|
||||
*
|
||||
* @param file the file to upload
|
||||
*/
|
||||
public void uploadAsync(final File file) {
|
||||
Bukkit.getScheduler()
|
||||
.runTaskAsynchronously(
|
||||
SR.getPlugin(),
|
||||
() -> {
|
||||
// start the call
|
||||
boolean success;
|
||||
try {
|
||||
success = hostingProvider.uploadPack(file);
|
||||
} catch (Exception e) {
|
||||
error("Failed to upload resource pack (exception) " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
if (!success) {
|
||||
error("Failed to upload resource pack.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Load the manager */
|
||||
@Override
|
||||
public void load() {
|
||||
super.load();
|
||||
String zipPath = SR.getPlugin().getDataFolder() + "/" + RESOURCE_PACK_ZIP;
|
||||
|
||||
Bukkit.getScheduler()
|
||||
.runTaskAsynchronously(
|
||||
SR.getPlugin(),
|
||||
() -> {
|
||||
if (new File(SR.getPlugin().getDataFolder(), "pack").exists()
|
||||
&& new File(zipPath).exists()) {
|
||||
log("Resource pack exists");
|
||||
// create a new zip with files
|
||||
|
||||
File tmpFile = packFile("tmp.zip");
|
||||
try {
|
||||
String tmpSHA = getFileChecksum(tmpFile.getAbsolutePath());
|
||||
String rpSHA = getFileChecksum(zipPath);
|
||||
|
||||
if (tmpSHA.equals(rpSHA)) {
|
||||
log("Resource pack is up to date");
|
||||
return;
|
||||
} else {
|
||||
log("Resource pack is outdated");
|
||||
log(tmpSHA + " " + rpSHA);
|
||||
}
|
||||
} catch (IOException | NoSuchAlgorithmException e) {
|
||||
error("Failed to check resource pack hash");
|
||||
}
|
||||
}
|
||||
// create the resource pack
|
||||
File rp = packFile(RESOURCE_PACK_ZIP);
|
||||
|
||||
// upload the resource pack
|
||||
uploadAsync(rp);
|
||||
});
|
||||
}
|
||||
|
||||
public HostingProvider getHostingProvider() {
|
||||
return hostingProvider;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package me.unurled.sacredrealms.sr.components.pack.animatedjava;
|
||||
|
||||
import me.unurled.srcore.api.Manager;
|
||||
|
||||
public class AnimatedJavaManager extends Manager {}
|
|
@ -0,0 +1,223 @@
|
|||
package me.unurled.sacredrealms.sr.components.pack.background;
|
||||
|
||||
import me.unurled.sacredrealms.sr.utils.character.CharRepo;
|
||||
import me.unurled.sacredrealms.sr.utils.character.ConfiguredChar;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Background {
|
||||
private ConfiguredChar left,
|
||||
offset1,
|
||||
offset2,
|
||||
offset4,
|
||||
offset8,
|
||||
offset16,
|
||||
offset32,
|
||||
offset64,
|
||||
offset128,
|
||||
right;
|
||||
private int leftMargin, rightMargin;
|
||||
|
||||
private Background() {}
|
||||
|
||||
public Background(
|
||||
ConfiguredChar left,
|
||||
ConfiguredChar offset1,
|
||||
ConfiguredChar offset2,
|
||||
ConfiguredChar offset4,
|
||||
ConfiguredChar offset8,
|
||||
ConfiguredChar offset16,
|
||||
ConfiguredChar offset32,
|
||||
ConfiguredChar offset64,
|
||||
ConfiguredChar offset128,
|
||||
ConfiguredChar right,
|
||||
int leftMargin,
|
||||
int rightMargin,
|
||||
boolean removeShadow) {
|
||||
this.left = left;
|
||||
this.offset1 = offset1;
|
||||
this.offset2 = offset2;
|
||||
this.offset4 = offset4;
|
||||
this.offset8 = offset8;
|
||||
this.offset16 = offset16;
|
||||
this.offset32 = offset32;
|
||||
this.offset64 = offset64;
|
||||
this.offset128 = offset128;
|
||||
this.right = right;
|
||||
this.leftMargin = leftMargin;
|
||||
this.rightMargin = rightMargin;
|
||||
}
|
||||
|
||||
@Contract(value = " -> new", pure = true)
|
||||
public static @NotNull Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public ConfiguredChar getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset1() {
|
||||
return offset1;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset2() {
|
||||
return offset2;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset4() {
|
||||
return offset4;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset8() {
|
||||
return offset8;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset16() {
|
||||
return offset16;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset32() {
|
||||
return offset32;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset64() {
|
||||
return offset64;
|
||||
}
|
||||
|
||||
public ConfiguredChar getOffset128() {
|
||||
return offset128;
|
||||
}
|
||||
|
||||
public ConfiguredChar getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
public String getBackGroundImage(int n) {
|
||||
String offset = CharRepo.getShortestNegChars(n + rightMargin + 2);
|
||||
n = n + leftMargin + rightMargin + 2;
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.append(left.getCharacter());
|
||||
while (n >= 128) {
|
||||
stringBuilder.append(CharRepo.NEG1.getCh());
|
||||
stringBuilder.append(offset128.getCharacter());
|
||||
n -= 128;
|
||||
}
|
||||
if (n - 64 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG1.getCh());
|
||||
stringBuilder.append(offset64.getCharacter());
|
||||
n -= 64;
|
||||
}
|
||||
if (n - 32 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG1.getCh());
|
||||
stringBuilder.append(offset32.getCharacter());
|
||||
n -= 32;
|
||||
}
|
||||
if (n - 16 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG1.getCh());
|
||||
stringBuilder.append(offset16.getCharacter());
|
||||
n -= 16;
|
||||
}
|
||||
if (n - 8 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG1.getCh());
|
||||
stringBuilder.append(offset8.getCharacter());
|
||||
n -= 8;
|
||||
}
|
||||
if (n - 4 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG1.getCh());
|
||||
stringBuilder.append(offset4.getCharacter());
|
||||
n -= 4;
|
||||
}
|
||||
if (n - 2 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG1.getCh());
|
||||
stringBuilder.append(offset2.getCharacter());
|
||||
n -= 2;
|
||||
}
|
||||
if (n - 1 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG1.getCh());
|
||||
stringBuilder.append(offset1.getCharacter());
|
||||
}
|
||||
stringBuilder.append(CharRepo.NEG1.getCh());
|
||||
stringBuilder.append(right.getCharacter());
|
||||
stringBuilder.append(offset);
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final Background background;
|
||||
|
||||
public Builder() {
|
||||
this.background = new Background();
|
||||
}
|
||||
|
||||
@Contract(value = " -> new", pure = true)
|
||||
public static @NotNull Builder of() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder left(ConfiguredChar configuredChar) {
|
||||
background.left = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder right(ConfiguredChar configuredChar) {
|
||||
background.right = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset1(ConfiguredChar configuredChar) {
|
||||
background.offset1 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset2(ConfiguredChar configuredChar) {
|
||||
background.offset2 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset4(ConfiguredChar configuredChar) {
|
||||
background.offset4 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset8(ConfiguredChar configuredChar) {
|
||||
background.offset8 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset16(ConfiguredChar configuredChar) {
|
||||
background.offset16 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset32(ConfiguredChar configuredChar) {
|
||||
background.offset32 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset64(ConfiguredChar configuredChar) {
|
||||
background.offset64 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset128(ConfiguredChar configuredChar) {
|
||||
background.offset128 = configuredChar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder leftMargin(int margin) {
|
||||
background.leftMargin = margin;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder rightMargin(int margin) {
|
||||
background.rightMargin = margin;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Background build() {
|
||||
return background;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
package me.unurled.sacredrealms.sr.components.pack.background;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.warn;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.sacredrealms.sr.utils.character.CharacterArranger;
|
||||
import me.unurled.sacredrealms.sr.utils.character.ConfiguredChar;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BackgroundManager extends Manager {
|
||||
|
||||
private final Map<String, Background> backgroundMap;
|
||||
|
||||
public BackgroundManager() {
|
||||
this.backgroundMap = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadData() {
|
||||
File bgFolder = new File(SR.getPlugin().getDataFolder(), "backgrounds");
|
||||
if (!bgFolder.exists() && bgFolder.mkdirs()) {
|
||||
saveDefaultBackgrounds();
|
||||
}
|
||||
|
||||
int height = 14;
|
||||
int ascent = 8;
|
||||
|
||||
String key = "b0";
|
||||
|
||||
Background background =
|
||||
Background.builder()
|
||||
.leftMargin(1)
|
||||
.rightMargin(1)
|
||||
.left(
|
||||
ConfiguredChar.builder()
|
||||
.character(CharacterArranger.getAndIncrease())
|
||||
.png("b0")
|
||||
.height(14)
|
||||
.ascent(7)
|
||||
.width(1)
|
||||
.build())
|
||||
.offset1(
|
||||
ConfiguredChar.builder()
|
||||
.character(CharacterArranger.getAndIncrease())
|
||||
.png("b1")
|
||||
.height(height)
|
||||
.ascent(ascent)
|
||||
.width(1)
|
||||
.build())
|
||||
.offset2(
|
||||
ConfiguredChar.builder()
|
||||
.character(CharacterArranger.getAndIncrease())
|
||||
.png("b2")
|
||||
.height(height)
|
||||
.ascent(ascent)
|
||||
.width(1)
|
||||
.build())
|
||||
.offset4(
|
||||
ConfiguredChar.builder()
|
||||
.character(CharacterArranger.getAndIncrease())
|
||||
.png("b4")
|
||||
.height(height)
|
||||
.ascent(ascent)
|
||||
.width(1)
|
||||
.build())
|
||||
.offset8(
|
||||
ConfiguredChar.builder()
|
||||
.character(CharacterArranger.getAndIncrease())
|
||||
.png("b8")
|
||||
.height(height)
|
||||
.ascent(ascent)
|
||||
.width(1)
|
||||
.build())
|
||||
.offset16(
|
||||
ConfiguredChar.builder()
|
||||
.character(CharacterArranger.getAndIncrease())
|
||||
.png("b16")
|
||||
.height(height)
|
||||
.ascent(ascent)
|
||||
.width(1)
|
||||
.build())
|
||||
.offset32(
|
||||
ConfiguredChar.builder()
|
||||
.character(CharacterArranger.getAndIncrease())
|
||||
.png("b32")
|
||||
.height(height)
|
||||
.ascent(ascent)
|
||||
.width(1)
|
||||
.build())
|
||||
.offset64(
|
||||
ConfiguredChar.builder()
|
||||
.character(CharacterArranger.getAndIncrease())
|
||||
.png("b64")
|
||||
.height(height)
|
||||
.ascent(ascent)
|
||||
.width(1)
|
||||
.build())
|
||||
.offset128(
|
||||
ConfiguredChar.builder()
|
||||
.character(CharacterArranger.getAndIncrease())
|
||||
.png("b128")
|
||||
.height(height)
|
||||
.ascent(ascent)
|
||||
.width(1)
|
||||
.build())
|
||||
.right(
|
||||
ConfiguredChar.builder()
|
||||
.character(CharacterArranger.getAndIncrease())
|
||||
.png("b0")
|
||||
.height(14)
|
||||
.ascent(7)
|
||||
.width(1)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
if (!registerBackGround(key, background)) {
|
||||
warn("Found duplicated background: " + key);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean registerBackGround(@NotNull String key, @NotNull Background backGround) {
|
||||
if (backgroundMap.containsKey(key)) {
|
||||
return false;
|
||||
}
|
||||
backgroundMap.put(key, backGround);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void saveDefaultBackgrounds() {
|
||||
String[] bgList = new String[] {"b0", "b1", "b2", "b4", "b8", "b16", "b32", "b64", "b128"};
|
||||
for (String bg : bgList) {
|
||||
SR.getPlugin().saveResource("backgrounds" + File.separator + bg + ".png", false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package me.unurled.sacredrealms.sr.components.pack.hosts;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface HostingProvider {
|
||||
|
||||
boolean uploadPack(File resourcePack) throws InterruptedException;
|
||||
|
||||
String getPackURL();
|
||||
|
||||
void setPackURL(String packURL);
|
||||
|
||||
String getMinecraftPackURL();
|
||||
|
||||
void setMinecraftPackURL(String minecraftPackURL);
|
||||
|
||||
byte[] getSHA1();
|
||||
|
||||
void setSHA1(byte[] sha1);
|
||||
|
||||
String getOriginalSHA1();
|
||||
|
||||
void setOriginalSHA1(String originalSHA1);
|
||||
|
||||
UUID getPackUUID();
|
||||
|
||||
void setPackUUID(UUID packUUID);
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
package me.unurled.sacredrealms.sr.components.pack.hosts;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
|
||||
import java.io.File;
|
||||
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.UUID;
|
||||
import me.unurled.sacredrealms.sr.utils.HTTPRequestMultipartBody;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class RustProvider implements HostingProvider {
|
||||
|
||||
public static final String FAILED = "Failed to upload pack to Rust server: ";
|
||||
public static final String HTTPS = "https://";
|
||||
private final String address;
|
||||
private final String APIKEY;
|
||||
private String packUrl;
|
||||
private String minecraftPackURL;
|
||||
private String sha1;
|
||||
private UUID packUUID;
|
||||
|
||||
public RustProvider(@NotNull String address, @NotNull String apiKey) {
|
||||
String address1;
|
||||
if (address.startsWith(HTTPS) || address.startsWith("http://")) {
|
||||
address1 = address;
|
||||
} else {
|
||||
address1 = HTTPS + address;
|
||||
}
|
||||
address1 += address.endsWith("/") ? "" : "/";
|
||||
this.address = address1;
|
||||
this.APIKEY = apiKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean uploadPack(File resourcePack) throws InterruptedException {
|
||||
try (HttpClient httpClient = HttpClient.newHttpClient()) {
|
||||
HTTPRequestMultipartBody multipartBody =
|
||||
new HTTPRequestMultipartBody.Builder()
|
||||
.addPart("file", resourcePack, null, resourcePack.getName())
|
||||
.build();
|
||||
|
||||
HttpRequest httpRequest =
|
||||
HttpRequest.newBuilder()
|
||||
.header(
|
||||
"Content-Type", "multipart/form-data; boundary=" + multipartBody.getBoundary())
|
||||
.header("API_KEY", APIKEY)
|
||||
.uri(new URI(this.address + "post"))
|
||||
.POST(HttpRequest.BodyPublishers.ofByteArray(multipartBody.getBody()))
|
||||
.build();
|
||||
|
||||
HttpResponse<String> response =
|
||||
httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
|
||||
|
||||
if (response.statusCode() != 200) {
|
||||
error(FAILED + response.body());
|
||||
return false;
|
||||
}
|
||||
|
||||
String stringRes = response.body();
|
||||
|
||||
if (stringRes.startsWith("[") && stringRes.endsWith("]")) {
|
||||
stringRes = stringRes.substring(1, stringRes.length() - 1);
|
||||
}
|
||||
|
||||
String[] split = stringRes.split(",");
|
||||
if (split.length != 2) {
|
||||
error(FAILED + response.body());
|
||||
return false;
|
||||
}
|
||||
|
||||
String path = split[0].split(":")[1].replace("\"", "").trim();
|
||||
sha1 = split[1].split(":")[1].replace("\"", "").trim().replace("}", "");
|
||||
packUrl = this.address + "files/" + path;
|
||||
|
||||
minecraftPackURL = packUrl.replace(HTTPS, "http://");
|
||||
|
||||
packUUID = UUID.nameUUIDFromBytes(sha1.getBytes());
|
||||
|
||||
} catch (IOException | URISyntaxException e) {
|
||||
error(FAILED + e.getMessage());
|
||||
return false;
|
||||
} catch (InterruptedException e) {
|
||||
error(FAILED + e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPackURL() {
|
||||
return packUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPackURL(String packURL) {
|
||||
this.packUrl = packURL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMinecraftPackURL() {
|
||||
return minecraftPackURL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMinecraftPackURL(String minecraftPackURL) {
|
||||
this.minecraftPackURL = minecraftPackURL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getSHA1() {
|
||||
int len = sha1.length();
|
||||
byte[] data = new byte[len / 2];
|
||||
for (int i = 0; i < len; i += 2) {
|
||||
data[i / 2] =
|
||||
(byte)
|
||||
((Character.digit(sha1.charAt(i), 16) << 4)
|
||||
+ Character.digit(sha1.charAt(i + 1), 16));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSHA1(byte[] sha1) {
|
||||
this.sha1 = new String(sha1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOriginalSHA1() {
|
||||
return sha1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOriginalSHA1(String originalSHA1) {
|
||||
this.sha1 = originalSHA1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getPackUUID() {
|
||||
return packUUID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPackUUID(UUID packUUID) {
|
||||
this.packUUID = packUUID;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package me.unurled.sacredrealms.sr.components.packet;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PacketManager extends Manager {
|
||||
public static <T extends PacketWrapper> void sendPacketTo(T packet, Player player) {
|
||||
PacketEvents.getAPI().getPlayerManager().sendPacket(player, packet);
|
||||
}
|
||||
}
|
|
@ -2,19 +2,24 @@ package me.unurled.sacredrealms.sr.components.player;
|
|||
|
||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.log;
|
||||
import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.updateActionBar;
|
||||
|
||||
import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.sacredrealms.sr.components.pack.ResourcePackManager;
|
||||
import me.unurled.sacredrealms.sr.data.DataHandler;
|
||||
import me.unurled.sacredrealms.sr.data.DataManager;
|
||||
import me.unurled.sacredrealms.sr.events.player.PlayerLevelUpEvent;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.sacredrealms.sr.utils.Items;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import net.kyori.adventure.resource.ResourcePackInfo;
|
||||
import net.kyori.adventure.resource.ResourcePackRequest;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
@ -22,6 +27,7 @@ import org.bukkit.event.entity.FoodLevelChangeEvent;
|
|||
import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerResourcePackStatusEvent.Status;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
|
@ -134,10 +140,36 @@ public class PlayerManager extends Manager {
|
|||
BukkitTask task =
|
||||
Bukkit.getScheduler()
|
||||
.runTaskTimerAsynchronously(
|
||||
SR.getInstance(), () -> updateActionBar(e.getPlayer()), 0, 20L);
|
||||
SR.getPlugin(), () -> updateActionBar(e.getPlayer()), 0, 20L);
|
||||
|
||||
actionBarTasks.put(e.getPlayer().getUniqueId(), task);
|
||||
e.getPlayer().updateInventory();
|
||||
|
||||
// player resource pack give
|
||||
ResourcePackManager rpm = Manager.getInstance(ResourcePackManager.class);
|
||||
if (rpm == null) {
|
||||
error("ResourcePackManager is null, Can't give player resource pack.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
URI uri = new URI(rpm.getHostingProvider().getMinecraftPackURL());
|
||||
ResourcePackRequest request =
|
||||
ResourcePackRequest.addingRequest(
|
||||
ResourcePackInfo.resourcePackInfo(
|
||||
rpm.getHostingProvider().getPackUUID(),
|
||||
uri,
|
||||
rpm.getHostingProvider().getOriginalSHA1()));
|
||||
e.getPlayer().sendResourcePacks(request);
|
||||
if (e.getPlayer().getResourcePackStatus() != null
|
||||
&& !e.getPlayer().getResourcePackStatus().equals(Status.ACCEPTED)) {
|
||||
e.getPlayer().kick(textComp("You must accept the resource pack."));
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
error("Failed to send resource pack to player. " + ex.getMessage());
|
||||
log(rpm.getHostingProvider().getOriginalSHA1());
|
||||
log(rpm.getHostingProvider().getPackUUID().toString());
|
||||
log(rpm.getHostingProvider().getMinecraftPackURL());
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -225,7 +257,7 @@ public class PlayerManager extends Manager {
|
|||
|
||||
public void levelUp(SRPlayer p, int previousLevel) {
|
||||
PlayerLevelUpEvent event = new PlayerLevelUpEvent(p, previousLevel);
|
||||
event.callEvent();
|
||||
Bukkit.getScheduler().runTaskAsynchronously(SR.getPlugin(), event::callEvent);
|
||||
Player player = Bukkit.getPlayer(p.getUuid());
|
||||
if (player != null) {
|
||||
player.sendMessage(event.getMessage());
|
||||
|
|
|
@ -14,7 +14,7 @@ import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
|||
import me.unurled.sacredrealms.sr.components.difficulty.Difficulty;
|
||||
import me.unurled.sacredrealms.sr.components.item.Item;
|
||||
import me.unurled.sacredrealms.sr.events.player.PlayerKillEvent;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
|
@ -31,15 +31,15 @@ public class SRPlayer {
|
|||
private static final List<Long> levelRequirements =
|
||||
List.of(100L, 200L, 400L, 800L, 1600L, 3200L, 6400L, 12800L, 25600L, 51200L);
|
||||
|
||||
@Expose private UUID uuid;
|
||||
@Expose private final UUID uuid;
|
||||
@Expose private final Map<Attribute, Double> attributes = new EnumMap<>(Attribute.class);
|
||||
@Expose private final List<Integer> treasuresOpened = new ArrayList<>();
|
||||
@Expose private int level = 1;
|
||||
@Expose private Long experience = 0L;
|
||||
private double health = 100;
|
||||
@Expose private Map<Attribute, Double> attributes = new EnumMap<>(Attribute.class);
|
||||
private double health = -1;
|
||||
private Map<Attribute, Map<ItemStack, Double>> itemAttributes = new EnumMap<>(Attribute.class);
|
||||
@Expose private List<PotionEffect> potionEffects = new ArrayList<>();
|
||||
@Expose private Inventory inventory;
|
||||
@Expose private List<Integer> treasuresOpened = new ArrayList<>();
|
||||
@Expose private Difficulty difficulty;
|
||||
private boolean isClientBuilder = false;
|
||||
private boolean firstTime = true;
|
||||
|
@ -238,6 +238,9 @@ public class SRPlayer {
|
|||
}
|
||||
|
||||
public double getHealth() {
|
||||
if (health == -1) {
|
||||
health = getAttribute(Attribute.HEALTH);
|
||||
}
|
||||
return health;
|
||||
}
|
||||
|
||||
|
@ -257,6 +260,7 @@ public class SRPlayer {
|
|||
|
||||
public void setExperience(Long experience) {
|
||||
// checks if experience is above next level requirements
|
||||
if (difficulty == null) difficulty = Difficulty.NORMAL;
|
||||
if (experience >= levelRequirements.get(level - 1) * difficulty.getXpMultiplier()) {
|
||||
PlayerManager pm = Manager.getInstance(PlayerManager.class);
|
||||
setLevel(level + 1);
|
||||
|
|
|
@ -2,7 +2,7 @@ package me.unurled.sacredrealms.sr.components.player.listener;
|
|||
|
||||
import me.unurled.sacredrealms.sr.components.player.PlayerManager;
|
||||
import me.unurled.sacredrealms.sr.components.player.SRPlayer;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package me.unurled.sacredrealms.sr.components.treasure;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import me.unurled.sacredrealms.sr.components.item.ItemStackDeserializer;
|
||||
import me.unurled.sacredrealms.sr.components.item.ItemStackSerializer;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ItemStackMapSerializer
|
||||
implements JsonSerializer<Map<Integer, ItemStack>>,
|
||||
JsonDeserializer<Map<Integer, org.bukkit.inventory.ItemStack>> {
|
||||
|
||||
@Override
|
||||
public Map<Integer, ItemStack> deserialize(
|
||||
@NotNull JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
Map<Integer, ItemStack> map = new HashMap<>();
|
||||
JsonObject jsonObject = json.getAsJsonObject();
|
||||
|
||||
Gson gson =
|
||||
new GsonBuilder()
|
||||
.registerTypeAdapter(ItemStack.class, new ItemStackDeserializer())
|
||||
.create();
|
||||
|
||||
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
|
||||
Integer key = Integer.parseInt(entry.getKey());
|
||||
ItemStack itemStack = gson.fromJson(entry.getValue(), ItemStack.class);
|
||||
map.put(key, itemStack);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(
|
||||
@NotNull Map<Integer, ItemStack> src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
|
||||
Gson gson =
|
||||
new GsonBuilder().registerTypeAdapter(ItemStack.class, new ItemStackSerializer()).create();
|
||||
|
||||
for (Map.Entry<Integer, ItemStack> entry : src.entrySet()) {
|
||||
JsonElement itemStackJson = gson.toJsonTree(entry.getValue(), ItemStack.class);
|
||||
jsonObject.add(entry.getKey().toString(), itemStackJson);
|
||||
}
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
|
@ -12,9 +12,8 @@ import io.leangen.geantyref.TypeToken;
|
|||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import me.unurled.sacredrealms.sr.components.item.ItemStackDeserializer;
|
||||
import org.bukkit.Bukkit;
|
||||
import me.unurled.sacredrealms.sr.utils.gson.LocationSerializer;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class TreasureDeserializer implements JsonDeserializer<Treasure> {
|
||||
|
@ -42,34 +41,31 @@ public class TreasureDeserializer implements JsonDeserializer<Treasure> {
|
|||
new GsonBuilder()
|
||||
.registerTypeAdapter(ItemStack.class, new ItemStackDeserializer())
|
||||
.create();
|
||||
|
||||
try {
|
||||
Integer id = gson.fromJson("id", Integer.class);
|
||||
String loc = gson.fromJson("location", String.class);
|
||||
String[] parts = loc.split(",");
|
||||
if (parts.length != 6) {
|
||||
return null;
|
||||
}
|
||||
World world = Bukkit.getServer().getWorld(parts[0]);
|
||||
double x = Double.parseDouble(parts[1]);
|
||||
double y = Double.parseDouble(parts[2]);
|
||||
double z = Double.parseDouble(parts[3]);
|
||||
float pitch = Float.parseFloat(parts[4]);
|
||||
float yaw = Float.parseFloat(parts[5]);
|
||||
Location location = new Location(world, x, y, z, pitch, yaw);
|
||||
String permission = gson.fromJson("permission", String.class);
|
||||
String items = gson.fromJson("items", String.class);
|
||||
Integer id = json.getAsJsonObject().get("id").getAsInt();
|
||||
Gson locGson =
|
||||
new GsonBuilder()
|
||||
.registerTypeAdapter(Location.class, new LocationSerializer())
|
||||
.registerTypeAdapter(
|
||||
new TypeToken<Map<Integer, ItemStack>>() {}.getType(),
|
||||
new ItemStackMapSerializer())
|
||||
.create();
|
||||
Location location = locGson.fromJson(json.getAsJsonObject().get("location"), Location.class);
|
||||
String permission = json.getAsJsonObject().get("permission").getAsString();
|
||||
String items = json.getAsJsonObject().get("items").getAsString();
|
||||
Type hash = new TypeToken<Map<Integer, ItemStack>>() {}.getType();
|
||||
Map<Integer, ItemStack> item = gson.fromJson(items, hash);
|
||||
|
||||
if (permission == null || item == null) {
|
||||
error("Error deserializing treasure: " + id + " is missing required fields");
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Treasure(id, location, item, permission);
|
||||
|
||||
} catch (Exception e) {
|
||||
error("Error deserializing treasure: " + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import me.unurled.sacredrealms.sr.components.item.Item;
|
|||
import me.unurled.sacredrealms.sr.components.item.ItemManager;
|
||||
import me.unurled.sacredrealms.sr.components.item.Rarity;
|
||||
import me.unurled.sacredrealms.sr.components.player.SRPlayer;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package me.unurled.sacredrealms.sr.components.treasure;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.log;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
@ -15,7 +17,7 @@ import me.unurled.sacredrealms.sr.components.player.PlayerManager;
|
|||
import me.unurled.sacredrealms.sr.components.player.SRPlayer;
|
||||
import me.unurled.sacredrealms.sr.data.DataHandler;
|
||||
import me.unurled.sacredrealms.sr.data.DataManager;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
|
@ -34,16 +36,20 @@ public class TreasureManager extends Manager {
|
|||
|
||||
private int nextId = 0;
|
||||
|
||||
private void saveTreasure(@NotNull Treasure treasure) {
|
||||
DataHandler dh = Manager.getInstance(DataManager.class).getDataHandler();
|
||||
Gson gson =
|
||||
new GsonBuilder().registerTypeAdapter(Treasure.class, new TreasureSerializer()).create();
|
||||
dh.set("treasures." + treasure.getId(), gson.toJson(treasure));
|
||||
}
|
||||
|
||||
/** Save the data */
|
||||
@Override
|
||||
public void saveData() {
|
||||
// save all treasures
|
||||
for (Treasure treasure : treasures.values()) {
|
||||
// serialize treasure
|
||||
DataHandler dh = Manager.getInstance(DataManager.class).getDataHandler();
|
||||
Gson gson =
|
||||
new GsonBuilder().registerTypeAdapter(Treasure.class, new TreasureSerializer()).create();
|
||||
dh.set("treasures." + treasure.getId(), gson.toJson(treasure));
|
||||
saveTreasure(treasure);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,9 +60,15 @@ public class TreasureManager extends Manager {
|
|||
DataHandler dh = Manager.getInstance(DataManager.class).getDataHandler();
|
||||
Gson gson =
|
||||
new GsonBuilder().registerTypeAdapter(Treasure.class, new TreasureDeserializer()).create();
|
||||
|
||||
log("Loading " + dh.getKeysAll("treasures").size() + " treasures");
|
||||
for (String key : dh.getKeysAll("treasures")) {
|
||||
// deserialize treasure
|
||||
addTreasure(gson.fromJson(dh.get("treasures." + key), Treasure.class));
|
||||
Treasure treasure = gson.fromJson(dh.get(key), Treasure.class);
|
||||
if (treasure == null) {
|
||||
error("Error loading treasure with id " + key);
|
||||
continue;
|
||||
}
|
||||
addTreasure(treasure);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,6 +130,15 @@ public class TreasureManager extends Manager {
|
|||
treasures.remove(treasure.getId());
|
||||
}
|
||||
|
||||
public void setBlocks(int id, @NotNull Map<Integer, ItemStack> items) {
|
||||
Treasure treasure = getTreasureById(id);
|
||||
if (treasure == null) {
|
||||
return;
|
||||
}
|
||||
treasure.setItems(items);
|
||||
saveTreasure(treasure);
|
||||
}
|
||||
|
||||
public int getNextId() {
|
||||
return nextId++;
|
||||
}
|
||||
|
@ -159,8 +180,17 @@ public class TreasureManager extends Manager {
|
|||
if (sr == null) {
|
||||
return;
|
||||
}
|
||||
if (sr.hasOpenedTreasure(treasure.getId())) {
|
||||
p.sendMessage("You have already opened this chest");
|
||||
p.playSound(p.getLocation(), Sound.BLOCK_ANVIL_BREAK, 1f, 0.5f);
|
||||
return;
|
||||
}
|
||||
if (treasure.getItems().isEmpty()) { // it generates items if not already set
|
||||
treasure = TreasureGenerator.generateTreasure(treasure, sr);
|
||||
}
|
||||
log(treasure.getItems().toString());
|
||||
p.openInventory(treasure.getInventory());
|
||||
p.playSound(p.getLocation(), Sound.BLOCK_CHEST_OPEN, 1f, 1f);
|
||||
SRPlayer srPlayer = Manager.getInstance(PlayerManager.class).getPlayer(p.getUniqueId());
|
||||
if (srPlayer != null) {
|
||||
srPlayer.addTreasureOpened(treasure.getId());
|
||||
|
|
|
@ -7,9 +7,14 @@ import com.google.gson.JsonObject;
|
|||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import io.leangen.geantyref.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import me.unurled.sacredrealms.sr.components.item.ItemStackSerializer;
|
||||
import me.unurled.sacredrealms.sr.utils.gson.LocationSerializer;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class TreasureSerializer implements JsonSerializer<Treasure> {
|
||||
|
||||
|
@ -29,14 +34,21 @@ public class TreasureSerializer implements JsonSerializer<Treasure> {
|
|||
* @return a JsonElement corresponding to the specified object.
|
||||
*/
|
||||
@Override
|
||||
public JsonElement serialize(Treasure src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
public JsonElement serialize(
|
||||
@NotNull Treasure src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject obj = new JsonObject();
|
||||
obj.add("id", new JsonPrimitive(src.getId()));
|
||||
obj.add("location", new JsonPrimitive(src.getLocation().toString()));
|
||||
LocationSerializer locSer = new LocationSerializer();
|
||||
obj.add("location", locSer.serialize(src.getLocation(), Location.class, context));
|
||||
obj.add("permission", new JsonPrimitive(src.getPermission()));
|
||||
Gson gson =
|
||||
new GsonBuilder().registerTypeAdapter(ItemStack.class, new ItemStackSerializer()).create();
|
||||
obj.add("items", new JsonPrimitive(gson.toJson(src.getItems())));
|
||||
new GsonBuilder()
|
||||
.registerTypeAdapter(ItemStack.class, new ItemStackSerializer())
|
||||
.registerTypeAdapter(
|
||||
new TypeToken<Map<Integer, ItemStack>>() {}.getType(), new ItemStackMapSerializer())
|
||||
.create();
|
||||
Type hash = new TypeToken<Map<Integer, ItemStack>>() {}.getType();
|
||||
obj.add("items", gson.toJsonTree(src.getItems(), hash));
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package me.unurled.sacredrealms.sr.config;
|
||||
|
||||
import java.io.File;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
public class ConfigManager extends Manager {
|
||||
|
||||
public static final String CONFIG_YML = "config.yml";
|
||||
private FileConfiguration config;
|
||||
|
||||
/** Load the data */
|
||||
@Override
|
||||
public void loadData() {
|
||||
if (!SR.getPlugin().getDataFolder().exists()) {
|
||||
SR.getPlugin().getDataFolder().mkdirs();
|
||||
}
|
||||
File configFile = new File(SR.getPlugin().getDataFolder(), CONFIG_YML);
|
||||
if (!configFile.exists()) {
|
||||
SR.getPlugin().saveResource(CONFIG_YML, false);
|
||||
config = YamlConfiguration.loadConfiguration(configFile);
|
||||
}
|
||||
config = YamlConfiguration.loadConfiguration(configFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveData() {
|
||||
if (!new File(SR.getPlugin().getDataFolder() + CONFIG_YML).exists()) {
|
||||
SR.getPlugin().saveDefaultConfig();
|
||||
} else {
|
||||
SR.getPlugin().saveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
public FileConfiguration getConfig() {
|
||||
return config;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package me.unurled.sacredrealms.sr.config;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public enum Settings {
|
||||
REDIS_HOST("redis.host"),
|
||||
REDIS_PORT("redis.port"),
|
||||
RESOURCE_PACK_URL("resource_pack"),
|
||||
RESOURCE_PACK_API("resource_pack_api");
|
||||
|
||||
private final String path;
|
||||
|
||||
Settings(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public @Nullable Object getValue() {
|
||||
ConfigManager cm = Manager.getInstance(ConfigManager.class);
|
||||
if (cm != null) {
|
||||
return cm.getConfig().get(path);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setValue(Object value) {
|
||||
SR.getPlugin().getConfig().set(path, value);
|
||||
try {
|
||||
SR.getPlugin().getConfig().save(new File(SR.getPlugin().getDataFolder(), "config.yml"));
|
||||
} catch (Exception e) {
|
||||
error("Failed to save config.yml");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
try {
|
||||
return (String) getValue();
|
||||
|
||||
} catch (NullPointerException e) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer toInt() {
|
||||
try {
|
||||
return (int) getValue();
|
||||
} catch (NullPointerException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public @NotNull Component toComponent() {
|
||||
Object value = getValue();
|
||||
if (value != null) {
|
||||
return MiniMessage.miniMessage().deserialize(value.toString());
|
||||
} else {
|
||||
return Component.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public Boolean toBool() {
|
||||
return (Boolean) getValue();
|
||||
}
|
||||
|
||||
public List<String> toStringList() {
|
||||
ConfigManager cm = Manager.getInstance(ConfigManager.class);
|
||||
if (cm != null) {
|
||||
return cm.getConfig().getStringList(path);
|
||||
}
|
||||
return List.of();
|
||||
}
|
||||
|
||||
public @Nullable ConfigurationSection toConfigSection() {
|
||||
ConfigManager cm = Manager.getInstance(ConfigManager.class);
|
||||
if (cm != null) {
|
||||
return cm.getConfig().getConfigurationSection(path);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package me.unurled.sacredrealms.sr.constants;
|
||||
|
||||
public class Keys {
|
||||
|
||||
public static final String BLOCK_KEY = "key";
|
||||
public static final String BLOCK_DISPLAYNAME = "displayName";
|
||||
public static final String BLOCK_LORE = "lore";
|
||||
public static final String BLOCK_CUSTOMMODELDATA = "customModelData";
|
||||
}
|
|
@ -1,18 +1,10 @@
|
|||
package me.unurled.sacredrealms.sr.data;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
|
||||
/** The data and config manager */
|
||||
public class DataManager extends Manager {
|
||||
|
||||
private FileConfiguration config;
|
||||
|
||||
private DataHandler dh;
|
||||
|
||||
/** Load the manager */
|
||||
|
@ -22,33 +14,6 @@ public class DataManager extends Manager {
|
|||
dh = new Redis();
|
||||
}
|
||||
|
||||
/** Save the data */
|
||||
@Override
|
||||
public void saveData() {
|
||||
try {
|
||||
if (config != null) config.save(new File(SR.getInstance().getDataFolder(), "config.yml"));
|
||||
} catch (IOException e) {
|
||||
error("Failed to save config.yml");
|
||||
}
|
||||
}
|
||||
|
||||
/** Load the data */
|
||||
@Override
|
||||
public void loadData() {
|
||||
SR.getInstance().saveConfig();
|
||||
SR.getInstance().reloadConfig();
|
||||
config = SR.getInstance().getConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the config
|
||||
*
|
||||
* @return The config
|
||||
*/
|
||||
public FileConfiguration getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data handler
|
||||
*
|
||||
|
|
|
@ -4,7 +4,9 @@ import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
|||
|
||||
import java.util.List;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.sacredrealms.sr.config.ConfigManager;
|
||||
import me.unurled.sacredrealms.sr.config.Settings;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import redis.clients.jedis.JedisPooled;
|
||||
|
||||
|
@ -13,20 +15,25 @@ public class Redis implements DataHandler {
|
|||
JedisPooled client;
|
||||
|
||||
public Redis() {
|
||||
DataManager dm = Manager.getInstance(DataManager.class);
|
||||
if (dm != null) {
|
||||
String host = dm.getConfig().getString("redis.host", "127.0.0.1");
|
||||
int port = dm.getConfig().getInt("redis.port", 6379);
|
||||
ConfigManager cm = Manager.getInstance(ConfigManager.class);
|
||||
if (cm != null) {
|
||||
String host = Settings.REDIS_HOST.toString();
|
||||
Integer port = Settings.REDIS_PORT.toInt();
|
||||
if (host == null || port == null) {
|
||||
error("Failed to get Redis host or port from config, shutting down server.");
|
||||
SR.getPlugin().getServer().shutdown();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
client = new JedisPooled(host, port);
|
||||
client.get("test");
|
||||
} catch (Exception e) {
|
||||
error("Failed to connect to Redis, shutting down server.");
|
||||
SR.getInstance().getServer().shutdown();
|
||||
SR.getPlugin().getServer().shutdown();
|
||||
}
|
||||
} else {
|
||||
error("Failed to get DataManager instance. Can't connect to Redis, shutting down server.");
|
||||
SR.getInstance().getServer().shutdown();
|
||||
SR.getPlugin().getServer().shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ public class BackItem extends PageItem {
|
|||
public ItemProvider getItemProvider(PagedGui<?> gui) {
|
||||
ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE);
|
||||
builder
|
||||
.setDisplayName("$7Previous Page")
|
||||
.setDisplayName("§cPrevious Page")
|
||||
.addLoreLines(
|
||||
gui.hasPreviousPage()
|
||||
? "§7Go to page §e" + gui.getCurrentPage() + "§7/§e" + gui.getPageAmount()
|
||||
|
|
|
@ -6,7 +6,7 @@ import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.syncSRToPlayer;
|
|||
import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
||||
import me.unurled.sacredrealms.sr.components.player.PlayerManager;
|
||||
import me.unurled.sacredrealms.sr.components.player.SRPlayer;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
|
|
|
@ -3,7 +3,7 @@ package me.unurled.sacredrealms.sr.gui.difficulty;
|
|||
import me.unurled.sacredrealms.sr.components.difficulty.Difficulty;
|
||||
import me.unurled.sacredrealms.sr.components.player.PlayerManager;
|
||||
import me.unurled.sacredrealms.sr.components.player.SRPlayer;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
|
@ -18,7 +18,7 @@ import xyz.xenondevs.invui.window.Window;
|
|||
|
||||
public class DifficultyItem extends AbstractItem {
|
||||
|
||||
private Difficulty difficulty;
|
||||
private final Difficulty difficulty;
|
||||
|
||||
public DifficultyItem(Difficulty difficulty) {
|
||||
this.difficulty = difficulty;
|
||||
|
@ -90,6 +90,8 @@ public class DifficultyItem extends AbstractItem {
|
|||
SRPlayer sr = pm.getPlayer(player.getUniqueId());
|
||||
if (sr != null) {
|
||||
sr.setDifficulty(difficulty);
|
||||
player.closeInventory();
|
||||
player.sendMessage("Set difficulty to " + difficulty.name() + "!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
package me.unurled.sacredrealms.sr.gui.entitytype;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Items.name;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import me.unurled.sacredrealms.sr.components.entity.SREntityType;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
|
@ -14,17 +19,43 @@ import xyz.xenondevs.invui.window.Window;
|
|||
|
||||
public class EntityArmorItem extends AbstractItem {
|
||||
|
||||
private static final ItemStack MAINHAND = name(new ItemStack(Material.BARRIER), "Main Hand");
|
||||
private static final ItemStack SECONDHAND = name(new ItemStack(Material.BARRIER), "Off Hand");
|
||||
private static final List<ItemStack> ARMOR = new ArrayList<>();
|
||||
private final ItemStack stack;
|
||||
|
||||
public EntityArmorItem(SREntityType type, int armorSlot) {
|
||||
if (armorSlot == 4) {
|
||||
public EntityArmorItem(@NotNull SREntityType type, int armorSlot) {
|
||||
|
||||
ARMOR.add(name(new ItemStack(Material.BARRIER), "Helmet"));
|
||||
ARMOR.add(name(new ItemStack(Material.BARRIER), "Chestplate"));
|
||||
ARMOR.add(name(new ItemStack(Material.BARRIER), "Leggings"));
|
||||
ARMOR.add(name(new ItemStack(Material.BARRIER), "Boots"));
|
||||
|
||||
switch (armorSlot) {
|
||||
case 4 -> {
|
||||
if (type.getHandItem().getType().equals(Material.AIR)) {
|
||||
stack = MAINHAND;
|
||||
} else {
|
||||
stack = type.getHandItem();
|
||||
} else if (armorSlot == 5) {
|
||||
}
|
||||
}
|
||||
case 5 -> {
|
||||
if (type.getSecondHandItem().getType().equals(Material.AIR)) {
|
||||
stack = SECONDHAND;
|
||||
} else {
|
||||
stack = type.getSecondHandItem();
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
if (type.getArmor().size() <= armorSlot
|
||||
|| type.getArmor().get(armorSlot).getType().equals(Material.AIR)) {
|
||||
stack = ARMOR.get(armorSlot);
|
||||
} else {
|
||||
stack = type.getArmor().get(armorSlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link ItemProvider}. This method gets called every time a {@link Window} is notified
|
||||
|
|
|
@ -6,7 +6,7 @@ import me.unurled.sacredrealms.sr.components.entity.EntityManager;
|
|||
import me.unurled.sacredrealms.sr.components.entity.SREntityType;
|
||||
import me.unurled.sacredrealms.sr.gui.BackItem;
|
||||
import me.unurled.sacredrealms.sr.gui.ForwardItem;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Material;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.xenondevs.invui.gui.Gui;
|
||||
|
@ -48,13 +48,13 @@ public class EntityTypeGUI {
|
|||
return Gui.normal()
|
||||
.setStructure(
|
||||
"# # # # # # # # #",
|
||||
"# T B O I S N L #", // Type, Behavior, lOot, Item display, Stats, Name, Level
|
||||
"# T V O I S N L #", // Type, behaVior, lOot, Item display, Stats, Name, Level
|
||||
"# X X X P X X X #", // exPerience
|
||||
"# H C E B X M A #", // Helmet, Chestplate, lEgging, Boots, Main hand, second hAnd
|
||||
"# # # # # # # # #")
|
||||
.addIngredient('#', border)
|
||||
.addIngredient('T', new EntityTypeItem(type))
|
||||
.addIngredient('B', new EntityBehaviorItem(type))
|
||||
.addIngredient('V', new EntityBehaviorItem(type))
|
||||
.addIngredient('O', new EntityLootItem())
|
||||
.addIngredient('I', new EntityItemDisplay(type))
|
||||
.addIngredient('S', new EntityStatsItem(type))
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package me.unurled.sacredrealms.sr.gui.treasure;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Items.cancelItem;
|
||||
|
||||
import me.unurled.sacredrealms.sr.components.treasure.Treasure;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.xenondevs.invui.item.Item;
|
||||
import xyz.xenondevs.invui.item.ItemProvider;
|
||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||
import xyz.xenondevs.invui.item.impl.AbstractItem;
|
||||
import xyz.xenondevs.invui.window.Window;
|
||||
|
||||
public class CancelItem extends AbstractItem {
|
||||
|
||||
public CancelItem() {}
|
||||
|
||||
/**
|
||||
* Gets the {@link ItemProvider}. This method gets called every time a {@link Window} is notified
|
||||
* ({@link #notifyWindows()}).
|
||||
*
|
||||
* @return The {@link ItemProvider}
|
||||
*/
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
return new ItemBuilder(cancelItem());
|
||||
}
|
||||
|
||||
/**
|
||||
* A method called if the {@link ItemStack} associated to this {@link Item} has been clicked by a
|
||||
* player.
|
||||
*
|
||||
* @param clickType The {@link ClickType} the {@link Player} performed.
|
||||
* @param player The {@link Player} who clicked on the {@link ItemStack}.
|
||||
* @param event The {@link InventoryClickEvent} associated with this click.
|
||||
*/
|
||||
@Override
|
||||
public void handleClick(
|
||||
@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
player.closeInventory();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package me.unurled.sacredrealms.sr.gui.treasure;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.log;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import me.unurled.sacredrealms.sr.components.treasure.Treasure;
|
||||
import me.unurled.sacredrealms.sr.components.treasure.TreasureManager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.xenondevs.invui.item.Item;
|
||||
import xyz.xenondevs.invui.item.ItemProvider;
|
||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||
import xyz.xenondevs.invui.item.impl.AbstractItem;
|
||||
import xyz.xenondevs.invui.window.Window;
|
||||
|
||||
public class ConfirmItem extends AbstractItem {
|
||||
|
||||
private final Treasure treasure;
|
||||
|
||||
public ConfirmItem(Treasure treasure) {
|
||||
this.treasure = treasure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link ItemProvider}. This method gets called every time a {@link Window} is notified
|
||||
* ({@link #notifyWindows()}).
|
||||
*
|
||||
* @return The {@link ItemProvider}
|
||||
*/
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
ItemStack confirm = new ItemStack(Material.GREEN_STAINED_GLASS_PANE);
|
||||
ItemMeta confirmMeta = confirm.getItemMeta();
|
||||
confirmMeta.displayName(textComp("<b><green>Confirm</green></b>"));
|
||||
confirm.setItemMeta(confirmMeta);
|
||||
return new ItemBuilder(confirm);
|
||||
}
|
||||
|
||||
/**
|
||||
* A method called if the {@link ItemStack} associated to this {@link Item} has been clicked by a
|
||||
* player.
|
||||
*
|
||||
* @param clickType The {@link ClickType} the {@link Player} performed.
|
||||
* @param player The {@link Player} who clicked on the {@link ItemStack}.
|
||||
* @param event The {@link InventoryClickEvent} associated with this click.
|
||||
*/
|
||||
@Override
|
||||
public void handleClick(
|
||||
@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
Map<Integer, ItemStack> items = new HashMap<>();
|
||||
for (int i = 0; i < player.getInventory().getContents().length; i++) {
|
||||
if (i < 9 || i > 35) {
|
||||
log("Skipping slot " + i);
|
||||
continue;
|
||||
}
|
||||
if (event.getClickedInventory() == null) {
|
||||
log("Clicked inventory is null");
|
||||
continue;
|
||||
}
|
||||
ItemStack content = event.getClickedInventory().getItem(i);
|
||||
if (content != null && content.getType() != Material.AIR) {
|
||||
items.put(i, content);
|
||||
log("Added item to items: " + content + " at slot " + i);
|
||||
}
|
||||
}
|
||||
log("Items: " + items);
|
||||
TreasureManager tm = Manager.getInstance(TreasureManager.class);
|
||||
tm.setBlocks(treasure.getId(), items);
|
||||
|
||||
player.closeInventory();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package me.unurled.sacredrealms.sr.gui.treasure;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
||||
|
||||
import me.unurled.sacredrealms.sr.components.treasure.Treasure;
|
||||
import me.unurled.sacredrealms.sr.components.treasure.TreasureManager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.xenondevs.invui.item.Item;
|
||||
import xyz.xenondevs.invui.item.ItemProvider;
|
||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||
import xyz.xenondevs.invui.item.impl.AbstractItem;
|
||||
import xyz.xenondevs.invui.window.Window;
|
||||
|
||||
public class DeleteItem extends AbstractItem {
|
||||
|
||||
private final Treasure treasure;
|
||||
|
||||
public DeleteItem(Treasure treasure) {
|
||||
this.treasure = treasure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link ItemProvider}. This method gets called every time a {@link Window} is notified
|
||||
* ({@link #notifyWindows()}).
|
||||
*
|
||||
* @return The {@link ItemProvider}
|
||||
*/
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
ItemStack delete = new ItemStack(Material.RED_STAINED_GLASS_PANE);
|
||||
ItemMeta deleteMeta = delete.getItemMeta();
|
||||
deleteMeta.displayName(textComp("<b><red>Delete</red></b>"));
|
||||
delete.setItemMeta(deleteMeta);
|
||||
return new ItemBuilder(delete);
|
||||
}
|
||||
|
||||
/**
|
||||
* A method called if the {@link ItemStack} associated to this {@link Item} has been clicked by a
|
||||
* player.
|
||||
*
|
||||
* @param clickType The {@link ClickType} the {@link Player} performed.
|
||||
* @param player The {@link Player} who clicked on the {@link ItemStack}.
|
||||
* @param event The {@link InventoryClickEvent} associated with this click.
|
||||
*/
|
||||
@Override
|
||||
public void handleClick(
|
||||
@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
// delete treasure
|
||||
if (!player.hasPermission("sr.treasure.delete")) {
|
||||
return;
|
||||
}
|
||||
TreasureManager treasureManager = Manager.getInstance(TreasureManager.class);
|
||||
treasureManager.removeTreasure(treasure);
|
||||
player.sendMessage(textComp("<red>Treasure deleted!"));
|
||||
player.closeInventory();
|
||||
}
|
||||
}
|
|
@ -1,16 +1,15 @@
|
|||
package me.unurled.sacredrealms.sr.gui.treasure;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
||||
import static me.unurled.sacredrealms.sr.utils.Items.cancelItem;
|
||||
import static me.unurled.sacredrealms.sr.utils.Items.glassPane;
|
||||
|
||||
import java.util.Map;
|
||||
import me.unurled.sacredrealms.sr.components.treasure.Treasure;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.xenondevs.invui.gui.Gui;
|
||||
import xyz.xenondevs.invui.gui.Gui.Builder.Normal;
|
||||
import xyz.xenondevs.invui.inventory.Inventory;
|
||||
import xyz.xenondevs.invui.inventory.VirtualInventory;
|
||||
import xyz.xenondevs.invui.inventory.event.UpdateReason;
|
||||
import xyz.xenondevs.invui.item.Item;
|
||||
import xyz.xenondevs.invui.item.impl.SimpleItem;
|
||||
|
||||
|
@ -22,36 +21,31 @@ public class TreasureGUI {
|
|||
public static Gui createGui(@NotNull Treasure treasure) {
|
||||
ItemStack itemStack = glassPane();
|
||||
Item pane = new SimpleItem(itemStack);
|
||||
Normal gui =
|
||||
Gui.normal()
|
||||
.setStructure(".........", "abcdefghi", "jklmnopqr", "stuvwxyz$", "...123...")
|
||||
.addIngredient('.', pane);
|
||||
if (!treasure.getItems().isEmpty()) {
|
||||
for (int i = 0; i < treasure.getItems().size(); i++) {
|
||||
Item item = new SimpleItem(treasure.getItems().get(i));
|
||||
if (i == 28) {
|
||||
gui.addIngredient('$', item);
|
||||
} else {
|
||||
gui.addIngredient((char) (i + 'a'), item);
|
||||
}
|
||||
|
||||
Inventory inventory = new VirtualInventory(27);
|
||||
inventory.setPreUpdateHandler(
|
||||
(itemPreUpdateEvent) -> {
|
||||
if (itemPreUpdateEvent.isAdd()
|
||||
|| itemPreUpdateEvent.isRemove()
|
||||
|| itemPreUpdateEvent.isSwap()) {
|
||||
itemPreUpdateEvent.setCancelled(false);
|
||||
}
|
||||
});
|
||||
|
||||
Map<Integer, ItemStack> items = treasure.getItems();
|
||||
if (!items.isEmpty()) {
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
inventory.setItem(UpdateReason.SUPPRESSED, i, items.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
ItemStack cancel = cancelItem();
|
||||
Gui gui = Gui.empty(9, 5);
|
||||
gui.fill(pane, true);
|
||||
gui.fillRectangle(0, 1, 9, inventory, true);
|
||||
gui.setItem(39, new DeleteItem(treasure));
|
||||
gui.setItem(40, new CancelItem());
|
||||
gui.setItem(41, new ConfirmItem(treasure));
|
||||
|
||||
ItemStack confirm = new ItemStack(Material.GREEN_STAINED_GLASS_PANE);
|
||||
ItemMeta confirmMeta = confirm.getItemMeta();
|
||||
confirmMeta.displayName(textComp("<b><green>Confirm</green></b>"));
|
||||
confirm.setItemMeta(confirmMeta);
|
||||
|
||||
ItemStack delete = new ItemStack(Material.RED_STAINED_GLASS_PANE);
|
||||
ItemMeta deleteMeta = delete.getItemMeta();
|
||||
deleteMeta.displayName(textComp("<b><red>Delete</red></b>"));
|
||||
delete.setItemMeta(deleteMeta);
|
||||
|
||||
gui.addIngredient('1', new SimpleItem(delete));
|
||||
gui.addIngredient('2', new SimpleItem(cancel));
|
||||
gui.addIngredient('3', new SimpleItem(confirm));
|
||||
return gui.build();
|
||||
return gui;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
package me.unurled.sacredrealms.sr.managers;
|
||||
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
public class Manager implements Listener {
|
||||
|
||||
/** Constructor for the Manager class */
|
||||
public Manager() {
|
||||
SR.getInstance().getManagers().addManager(this);
|
||||
Bukkit.getScheduler()
|
||||
.runTaskAsynchronously(
|
||||
SR.getInstance(),
|
||||
() -> {
|
||||
load();
|
||||
Bukkit.getPluginManager().registerEvents(this, SR.getInstance());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of a manager
|
||||
*
|
||||
* @param clazz The class of the manager
|
||||
* @return The instance of the manager
|
||||
* @param <T> The type of the manager
|
||||
*/
|
||||
public static <T extends Manager> T getInstance(Class<T> clazz) {
|
||||
return clazz.cast(SR.getInstance().getManagers().getManager(clazz));
|
||||
}
|
||||
|
||||
/** Load the manager */
|
||||
public void load() {
|
||||
loadData();
|
||||
}
|
||||
|
||||
/** Unload the manager */
|
||||
public void unload() {
|
||||
saveData();
|
||||
}
|
||||
|
||||
/** Save the data */
|
||||
public void saveData() {
|
||||
/* method empty, so it isn't required by the extended child to implement it */
|
||||
}
|
||||
|
||||
/** Load the data */
|
||||
public void loadData() {
|
||||
/* method empty, so it isn't required by the extended child to implement it */
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
package me.unurled.sacredrealms.sr.managers;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.sacredrealms.sr.components.clientbuild.ClientBuildManager;
|
||||
import me.unurled.sacredrealms.sr.components.combat.CombatManager;
|
||||
import me.unurled.sacredrealms.sr.components.entity.EntityManager;
|
||||
import me.unurled.sacredrealms.sr.components.item.ItemManager;
|
||||
import me.unurled.sacredrealms.sr.components.player.PlayerManager;
|
||||
import me.unurled.sacredrealms.sr.components.treasure.TreasureManager;
|
||||
import me.unurled.sacredrealms.sr.data.DataManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class Managers {
|
||||
|
||||
private final List<Manager> managers;
|
||||
|
||||
public Managers() {
|
||||
managers = new ArrayList<>();
|
||||
// register managers here (like a new instance of them)
|
||||
|
||||
register(
|
||||
List.of(
|
||||
DataManager.class,
|
||||
PlayerManager.class,
|
||||
CombatManager.class,
|
||||
ItemManager.class,
|
||||
EntityManager.class,
|
||||
ClientBuildManager.class,
|
||||
TreasureManager.class));
|
||||
}
|
||||
|
||||
private void register(@NotNull List<Class<? extends Manager>> clazz) {
|
||||
int i = 0;
|
||||
for (Class<? extends Manager> c : clazz) {
|
||||
Bukkit.getScheduler()
|
||||
.runTaskLater(
|
||||
SR.getInstance(),
|
||||
() -> {
|
||||
try {
|
||||
c.getDeclaredConstructor().newInstance();
|
||||
} catch (InstantiationException
|
||||
| IllegalAccessException
|
||||
| InvocationTargetException
|
||||
| NoSuchMethodException e) {
|
||||
error("Failed to register manager: " + c.getSimpleName());
|
||||
}
|
||||
},
|
||||
10L * i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
public void addManager(Manager manager) {
|
||||
managers.add(manager);
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
for (Manager manager : managers) {
|
||||
manager.unload();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Manager getManager(Class<? extends Manager> clazz) {
|
||||
for (Manager manager : managers) {
|
||||
if (manager.getClass().equals(clazz)) {
|
||||
return manager;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package me.unurled.sacredrealms.sr.utils;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ChunkWrapper {
|
||||
|
||||
private int x;
|
||||
private int z;
|
||||
private World world;
|
||||
|
||||
public ChunkWrapper(@NotNull Chunk chunk) {
|
||||
this.x = chunk.getX();
|
||||
this.z = chunk.getZ();
|
||||
this.world = chunk.getWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 17;
|
||||
hash = hash * 31 + x;
|
||||
hash = hash * 31 + z;
|
||||
hash = hash * 31 + world.hashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) return false;
|
||||
if (!(obj instanceof ChunkWrapper)) return false;
|
||||
return ((ChunkWrapper) obj).x == this.x
|
||||
&& ((ChunkWrapper) obj).z == this.z
|
||||
&& ((ChunkWrapper) obj).world.equals(this.world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + x + ", " + z + ") [" + world + "]";
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public void setX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public void setZ(int z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public void setWorld(World world) {
|
||||
this.world = world;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package me.unurled.sacredrealms.sr.utils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -29,4 +31,9 @@ public class Component {
|
|||
}
|
||||
return (TextComponent) miniMessage.deserialize(msg);
|
||||
}
|
||||
|
||||
public static List<net.kyori.adventure.text.Component> fromStringList(
|
||||
@NotNull List<String> list) {
|
||||
return list.stream().map(Component::comp).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package me.unurled.sacredrealms.sr.utils;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.Frame;
|
||||
import me.unurled.sacredrealms.sr.components.cutscene.Marker;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.title.Title;
|
||||
import net.kyori.adventure.title.Title.Times;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CutsceneUtil {
|
||||
|
||||
private static final String FONT = "custom";
|
||||
|
||||
private CutsceneUtil() {}
|
||||
|
||||
public static void showBlackScreen(@NotNull Player p, int duration, int fadeIn, int fadeOut) {
|
||||
// /title @s title {"text":"\uE000","color":"black"}
|
||||
Title title =
|
||||
Title.title(
|
||||
textComp("\uE000").font(Key.key(FONT)),
|
||||
textComp(""),
|
||||
Times.times(
|
||||
Duration.ofSeconds(fadeIn),
|
||||
Duration.ofSeconds(duration),
|
||||
Duration.ofSeconds(fadeOut)));
|
||||
p.showTitle(title);
|
||||
}
|
||||
|
||||
public static @NotNull List<Frame> interpolateFrames(
|
||||
@NotNull Marker startMarker, @NotNull Marker endMarker, long stepMillis) {
|
||||
long duration = startMarker.getOverAllTime();
|
||||
|
||||
int numFrames = (int) (duration / stepMillis);
|
||||
|
||||
double xDiff = (endMarker.getStart().getX() - startMarker.getStart().getX()) / numFrames;
|
||||
double yDiff = (endMarker.getStart().getY() - startMarker.getStart().getY()) / numFrames;
|
||||
double zDiff = (endMarker.getStart().getZ() - startMarker.getStart().getZ()) / numFrames;
|
||||
double yawDiff = (endMarker.getStart().getYaw() - startMarker.getStart().getYaw()) / numFrames;
|
||||
double pitchDiff =
|
||||
(endMarker.getStart().getPitch() - startMarker.getStart().getPitch()) / numFrames;
|
||||
|
||||
ArrayList<Frame> frames = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < numFrames; i++) {
|
||||
|
||||
double x = startMarker.getStart().getX() + xDiff * i;
|
||||
double y = startMarker.getStart().getY() + yDiff * i;
|
||||
double z = startMarker.getStart().getZ() + zDiff * i;
|
||||
double yaw = startMarker.getStart().getYaw() + yawDiff * i;
|
||||
double pitch = startMarker.getStart().getPitch() + pitchDiff * i;
|
||||
|
||||
Frame frame =
|
||||
new Frame(
|
||||
new Location(startMarker.getStart().getWorld(), x, y, z, (float) yaw, (float) pitch));
|
||||
|
||||
frames.add(frame);
|
||||
}
|
||||
return frames;
|
||||
}
|
||||
}
|
70
src/main/java/me/unurled/sacredrealms/sr/utils/File.java
Normal file
|
@ -0,0 +1,70 @@
|
|||
package me.unurled.sacredrealms.sr.utils;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class File {
|
||||
|
||||
private File() {}
|
||||
|
||||
public static @NotNull String getFileChecksum(String filePath)
|
||||
throws IOException, NoSuchAlgorithmException {
|
||||
MessageDigest sha = MessageDigest.getInstance("MD5");
|
||||
|
||||
try (FileInputStream fis = new FileInputStream(filePath)) {
|
||||
DigestInputStream dis = new DigestInputStream(fis, sha);
|
||||
while (dis.read() != -1)
|
||||
;
|
||||
dis.close();
|
||||
}
|
||||
|
||||
// Convert the byte array to a hexadecimal string
|
||||
byte[] bytes = sha.digest();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte aByte : bytes) {
|
||||
sb.append(String.format("%02x", aByte));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static void zipFile(
|
||||
@NotNull java.io.File fileToZip, String fileName, ZipOutputStream zipOut) throws IOException {
|
||||
if (fileToZip.isHidden()) {
|
||||
return;
|
||||
}
|
||||
try (FileInputStream fis = new FileInputStream(fileToZip)) {
|
||||
ZipEntry zipEntry = new ZipEntry(fileName);
|
||||
zipEntry.setTime(0);
|
||||
zipOut.putNextEntry(zipEntry);
|
||||
byte[] bytes = new byte[1024];
|
||||
int length;
|
||||
while ((length = fis.read(bytes)) >= 0) {
|
||||
zipOut.write(bytes, 0, length);
|
||||
}
|
||||
zipOut.closeEntry();
|
||||
}
|
||||
}
|
||||
|
||||
public static void zipDirectory(
|
||||
@NotNull java.io.File folderToZip, String folderName, ZipOutputStream zipOut)
|
||||
throws IOException {
|
||||
java.io.File[] children = folderToZip.listFiles();
|
||||
if (children == null) {
|
||||
return;
|
||||
}
|
||||
for (java.io.File childFile : children) {
|
||||
if (childFile.isDirectory()) {
|
||||
zipDirectory(childFile, folderName + "/" + childFile.getName(), zipOut);
|
||||
} else {
|
||||
zipFile(childFile, folderName + "/" + childFile.getName(), zipOut);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
package me.unurled.sacredrealms.sr.utils;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class HTTPRequestMultipartBody {
|
||||
private final byte[] bytes;
|
||||
private String boundary;
|
||||
|
||||
private HTTPRequestMultipartBody(byte[] bytes, String boundary) {
|
||||
this.bytes = bytes;
|
||||
this.boundary = boundary;
|
||||
}
|
||||
|
||||
public String getBoundary() {
|
||||
return boundary;
|
||||
}
|
||||
|
||||
public void setBoundary(String boundary) {
|
||||
this.boundary = boundary;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return "multipart/form-data; boundary=" + this.getBoundary();
|
||||
}
|
||||
|
||||
public byte[] getBody() {
|
||||
return this.bytes;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
public static final String CONTENT_TYPE = "Content-Type: application/octet-stream\r\n\r\n";
|
||||
List<MultiPartRecord> parts;
|
||||
|
||||
public Builder() {
|
||||
this.parts = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Builder addPart(String fieldName, String fieldValue) {
|
||||
MultiPartRecord part = new MultiPartRecord();
|
||||
part.setFieldName(fieldName);
|
||||
part.setContent(fieldValue);
|
||||
String defaultMimetype = "text/plain";
|
||||
part.setContentType(defaultMimetype);
|
||||
this.parts.add(part);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addPart(String fieldName, String fieldValue, String contentType) {
|
||||
MultiPartRecord part = new MultiPartRecord();
|
||||
part.setFieldName(fieldName);
|
||||
part.setContent(fieldValue);
|
||||
part.setContentType(contentType);
|
||||
this.parts.add(part);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addPart(
|
||||
String fieldName, Object fieldValue, String contentType, String fileName) {
|
||||
MultiPartRecord part = new MultiPartRecord();
|
||||
part.setFieldName(fieldName);
|
||||
part.setContent(fieldValue);
|
||||
part.setContentType(contentType);
|
||||
part.setFilename(fileName);
|
||||
this.parts.add(part);
|
||||
return this;
|
||||
}
|
||||
|
||||
public HTTPRequestMultipartBody build() throws IOException {
|
||||
String boundary = new BigInteger(256, new SecureRandom()).toString();
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
for (MultiPartRecord multiPartRecord : parts) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder
|
||||
.append("--")
|
||||
.append(boundary)
|
||||
.append("\r\n")
|
||||
.append("Content-Disposition: form-data; name=\"")
|
||||
.append(multiPartRecord.getFieldName());
|
||||
if (multiPartRecord.getFilename() != null) {
|
||||
stringBuilder.append("\"; filename=\"").append(multiPartRecord.getFilename());
|
||||
}
|
||||
out.write(stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
|
||||
out.write(("\"\r\n").getBytes(StandardCharsets.UTF_8));
|
||||
Object content = multiPartRecord.getContent();
|
||||
if (content instanceof String cont) {
|
||||
out.write(("\r\n\r\n").getBytes(StandardCharsets.UTF_8));
|
||||
out.write(cont.getBytes(StandardCharsets.UTF_8));
|
||||
} else if (content instanceof byte[] cont) {
|
||||
out.write(CONTENT_TYPE.getBytes(StandardCharsets.UTF_8));
|
||||
out.write(cont);
|
||||
} else if (content instanceof File file) {
|
||||
out.write(CONTENT_TYPE.getBytes(StandardCharsets.UTF_8));
|
||||
Files.copy(file.toPath(), out);
|
||||
} else {
|
||||
out.write(CONTENT_TYPE.getBytes(StandardCharsets.UTF_8));
|
||||
ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
|
||||
objectOutputStream.writeObject(content);
|
||||
objectOutputStream.flush();
|
||||
}
|
||||
out.write("\r\n".getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
out.write(("--" + boundary + "--\r\n").getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
return new HTTPRequestMultipartBody(out.toByteArray(), boundary);
|
||||
}
|
||||
|
||||
public static class MultiPartRecord {
|
||||
private String fieldName;
|
||||
private String filename;
|
||||
private String contentType;
|
||||
private Object content;
|
||||
|
||||
public String getFieldName() {
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
public void setFieldName(String fieldName) {
|
||||
this.fieldName = fieldName;
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
public void setFilename(String filename) {
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public void setContentType(String contentType) {
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
public Object getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(Object content) {
|
||||
this.content = content;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
|||
import static me.unurled.sacredrealms.sr.utils.Component.textComp;
|
||||
import static me.unurled.sacredrealms.sr.utils.SRPlayerUtils.syncSRToPlayer;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
@ -11,9 +12,12 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
||||
import me.unurled.sacredrealms.sr.components.item.Item;
|
||||
import me.unurled.sacredrealms.sr.components.item.ItemManager;
|
||||
import me.unurled.sacredrealms.sr.components.item.ItemStackDeserializer;
|
||||
import me.unurled.sacredrealms.sr.components.item.ItemStackSerializer;
|
||||
import me.unurled.sacredrealms.sr.components.player.PlayerManager;
|
||||
import me.unurled.sacredrealms.sr.components.player.SRPlayer;
|
||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
|
@ -68,21 +72,10 @@ public class Items {
|
|||
ItemManager im = Manager.getInstance(ItemManager.class);
|
||||
if (im == null) return 0.0;
|
||||
if (item == null) return 0.0;
|
||||
if (item.getType().equals(Material.AIR)) return 0.0;
|
||||
PersistentDataContainer p = item.getItemMeta().getPersistentDataContainer();
|
||||
if (p.has(ItemManager.ID, PersistentDataType.STRING)) {
|
||||
Item i = im.getItem(p.get(ItemManager.ID, PersistentDataType.STRING));
|
||||
if (i != null) {
|
||||
return i.getAttribute(attribute);
|
||||
}
|
||||
}
|
||||
if (p.has(attribute.getKey(), PersistentDataType.DOUBLE)) {
|
||||
try {
|
||||
return p.get(attribute.getKey(), PersistentDataType.DOUBLE);
|
||||
} catch (Exception e) {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
Item it = im.getItem(item);
|
||||
if (it != null) return it.getAttribute(attribute);
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
@ -171,4 +164,29 @@ public class Items {
|
|||
|
||||
syncSRToPlayer(p, player);
|
||||
}
|
||||
|
||||
public static @NotNull ItemStack name(@NotNull ItemStack stack, String name) {
|
||||
ItemMeta meta = stack.getItemMeta();
|
||||
meta.displayName(textComp(name));
|
||||
stack.setItemMeta(meta);
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static @NotNull String locationToString(@NotNull Location location) {
|
||||
return location.getWorld().getName()
|
||||
+ "_z"
|
||||
+ location.getBlockX()
|
||||
+ "y"
|
||||
+ location.getBlockY()
|
||||
+ "z"
|
||||
+ location.getBlockZ();
|
||||
}
|
||||
|
||||
public static JsonElement serialize(ItemStack itemStack) {
|
||||
return new ItemStackSerializer().serialize(itemStack, ItemStack.class, null);
|
||||
}
|
||||
|
||||
public static @NotNull ItemStack deserialize(@NotNull JsonElement jsonElement) {
|
||||
return new ItemStackDeserializer().deserialize(jsonElement, ItemStack.class, null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,12 @@ package me.unurled.sacredrealms.sr.utils;
|
|||
import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import me.unurled.sacredrealms.sr.SR;
|
||||
import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
||||
import me.unurled.sacredrealms.sr.components.player.PlayerManager;
|
||||
import me.unurled.sacredrealms.sr.components.player.SRPlayer;
|
||||
import me.unurled.srcore.api.Manager;
|
||||
import org.bukkit.attribute.AttributeInstance;
|
||||
import org.bukkit.entity.Display;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
@ -18,6 +21,8 @@ import org.jetbrains.annotations.NotNull;
|
|||
|
||||
public class SRPlayerUtils {
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
private SRPlayerUtils() {}
|
||||
|
||||
public static void syncPlayerToSR(@NotNull Player p, @NotNull SRPlayer sr) {
|
||||
|
@ -58,7 +63,11 @@ public class SRPlayerUtils {
|
|||
p.updateInventory();
|
||||
}
|
||||
|
||||
public static void updateActionBar(@NotNull Player p, @NotNull SRPlayer sr) {
|
||||
public static void updateActionBar(@NotNull Player p) {
|
||||
PlayerManager pm = Manager.getInstance(PlayerManager.class);
|
||||
if (pm == null) return;
|
||||
SRPlayer sr = pm.getPlayer(p.getUniqueId());
|
||||
if (sr == null) return;
|
||||
int maxHealth = (int) sr.getAttribute(Attribute.HEALTH);
|
||||
int health = (int) sr.getHealth();
|
||||
int mana = (int) sr.getAttribute(Attribute.MANA);
|
||||
|
@ -80,11 +89,17 @@ public class SRPlayerUtils {
|
|||
Vector spawnVector = location.add(facingVector.multiply(0.75));
|
||||
|
||||
// summon entity
|
||||
|
||||
double randomX = RANDOM.nextDouble() * 0.5 - 0.25;
|
||||
double randomZ = RANDOM.nextDouble() * 0.5 - 0.25;
|
||||
spawnVector.add(new Vector(randomX, 0, randomZ));
|
||||
|
||||
TextDisplay indicators =
|
||||
eventEntity
|
||||
.getWorld()
|
||||
.spawn(
|
||||
spawnVector.toLocation(eventEntity.getWorld()).add(0, 0.7, 0), TextDisplay.class);
|
||||
spawnVector.toLocation(eventEntity.getWorld()).add(0.0, 0.5, 0.0),
|
||||
TextDisplay.class);
|
||||
String prefix = "<red>-";
|
||||
if (isHeal) prefix = "<green>+";
|
||||
|
||||
|
@ -114,6 +129,6 @@ public class SRPlayerUtils {
|
|||
}
|
||||
height++;
|
||||
}
|
||||
}.runTaskTimer(SR.getInstance(), 0, 1);
|
||||
}.runTaskTimer(SR.getPlugin(), 0, 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,235 @@
|
|||
package me.unurled.sacredrealms.sr.utils.character;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public enum CharRepo {
|
||||
A('A', 5),
|
||||
a('a', 5),
|
||||
B('B', 5),
|
||||
b('b', 5),
|
||||
C('C', 5),
|
||||
c('c', 5),
|
||||
D('D', 5),
|
||||
d('d', 5),
|
||||
E('E', 5),
|
||||
e('e', 5),
|
||||
F('F', 5),
|
||||
f('f', 4),
|
||||
G('G', 5),
|
||||
g('g', 5),
|
||||
H('H', 5),
|
||||
h('h', 5),
|
||||
I('I', 3),
|
||||
i('i', 1),
|
||||
J('J', 5),
|
||||
j('j', 5),
|
||||
K('K', 5),
|
||||
k('k', 4),
|
||||
L('L', 5),
|
||||
l('l', 1),
|
||||
M('M', 5),
|
||||
m('m', 5),
|
||||
N('N', 5),
|
||||
n('n', 5),
|
||||
O('O', 5),
|
||||
o('o', 5),
|
||||
P('P', 5),
|
||||
p('p', 5),
|
||||
Q('Q', 5),
|
||||
q('q', 5),
|
||||
R('R', 5),
|
||||
r('r', 5),
|
||||
S('S', 5),
|
||||
s('s', 5),
|
||||
T('T', 5),
|
||||
t('t', 4),
|
||||
U('U', 5),
|
||||
u('u', 5),
|
||||
V('V', 5),
|
||||
v('v', 5),
|
||||
W('W', 5),
|
||||
w('w', 5),
|
||||
X('X', 5),
|
||||
x('x', 5),
|
||||
Y('Y', 5),
|
||||
y('y', 5),
|
||||
Z('Z', 5),
|
||||
z('z', 5),
|
||||
NUM_1('1', 5),
|
||||
NUM_2('2', 5),
|
||||
NUM_3('3', 5),
|
||||
NUM_4('4', 5),
|
||||
NUM_5('5', 5),
|
||||
NUM_6('6', 5),
|
||||
NUM_7('7', 5),
|
||||
NUM_8('8', 5),
|
||||
NUM_9('9', 5),
|
||||
NUM_0('0', 5),
|
||||
EXCLAMATION_POINT('!', 1),
|
||||
AT_SYMBOL('@', 6),
|
||||
NUM_SIGN('#', 5),
|
||||
DOLLAR_SIGN('$', 5),
|
||||
PERCENT('%', 5),
|
||||
UP_ARROW('^', 5),
|
||||
AMPERSAND('&', 5),
|
||||
ASTERISK('*', 5),
|
||||
LEFT_PARENTHESIS('(', 4),
|
||||
RIGHT_PERENTHESIS(')', 4),
|
||||
MINUS('-', 5),
|
||||
UNDERSCORE('_', 5),
|
||||
PLUS_SIGN('+', 5),
|
||||
EQUALS_SIGN('=', 5),
|
||||
LEFT_CURL_BRACE('{', 4),
|
||||
RIGHT_CURL_BRACE('}', 4),
|
||||
LEFT_BRACKET('[', 3),
|
||||
RIGHT_BRACKET(']', 3),
|
||||
COLON(':', 1),
|
||||
SEMI_COLON(';', 1),
|
||||
DOUBLE_QUOTE('"', 3),
|
||||
SINGLE_QUOTE('\'', 1),
|
||||
LEFT_ARROW('<', 4),
|
||||
RIGHT_ARROW('>', 4),
|
||||
QUESTION_MARK('?', 5),
|
||||
SLASH('/', 5),
|
||||
BACK_SLASH('\\', 5),
|
||||
LINE('|', 1),
|
||||
TILDE('~', 5),
|
||||
TICK('`', 2),
|
||||
PERIOD('.', 1),
|
||||
COMMA(',', 1),
|
||||
SPACE(' ', 3),
|
||||
DEFAULT('\u0000', 0),
|
||||
|
||||
// spacing
|
||||
|
||||
NEG1('\uF801', -1, -3),
|
||||
NEG2('\uF802', -2, -4),
|
||||
NEG3('\uF803', -3, -5),
|
||||
NEG4('\uF804', -4, -5),
|
||||
NEG5('\uF805', -5, -7),
|
||||
NEG6('\uF806', -6, -8),
|
||||
NEG7('\uF807', -7, -9),
|
||||
NEG8('\uF808', -8, -10),
|
||||
NEG16('\uF809', -16, -18),
|
||||
NEG32('\uF80A', -32, -34),
|
||||
NEG64('\uF80B', -64, -66),
|
||||
NEG128('\uF80C', -128, -130),
|
||||
NEG256('\uF80D', -256, -258),
|
||||
NEG512('\uF80E', -512, -514),
|
||||
NEG1024('\uF80F', -1024, -1026),
|
||||
|
||||
POS1('\uF821', 1, 0),
|
||||
POS2('\uF822', 2, 1),
|
||||
POS4('\uF824', 4, 3),
|
||||
POS8('\uF828', 8, 7),
|
||||
POS16('\uF829', 16, 15),
|
||||
POS32('\uF82A', 32, 31),
|
||||
POS64('\uF82B', 64, 63),
|
||||
POS128('\uF82C', 128, 127),
|
||||
POS256('\uF82D', 256, 255),
|
||||
POS512('\uF82E', 512, 511),
|
||||
POS1024('\uF82F', 1024, 1023);
|
||||
|
||||
private final char ch;
|
||||
private final int width;
|
||||
private final int effectiveWidth;
|
||||
|
||||
CharRepo(char ch, int width) {
|
||||
this.ch = ch;
|
||||
this.width = width;
|
||||
this.effectiveWidth = width;
|
||||
}
|
||||
|
||||
CharRepo(char ch, int width, int effectiveWidth) {
|
||||
this.ch = ch;
|
||||
this.width = width;
|
||||
this.effectiveWidth = effectiveWidth;
|
||||
}
|
||||
|
||||
public static CharRepo getDefaultFontInfo(char c) {
|
||||
for (CharRepo dFI : CharRepo.values()) {
|
||||
if (dFI.getCh() == c) return dFI;
|
||||
}
|
||||
return CharRepo.DEFAULT;
|
||||
}
|
||||
|
||||
public static int getPixelWidth(@NotNull String str) {
|
||||
int val = 0;
|
||||
for (char ch : str.toCharArray()) {
|
||||
val += CharRepo.getDefaultFontInfo(ch).getEffectiveWidth();
|
||||
val += 1; // acount for spacing
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* get negative characters
|
||||
*
|
||||
* @param n n > 0
|
||||
* @return chars
|
||||
*/
|
||||
public static String getShortestNegChars(int n) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
while (n >= 128) {
|
||||
stringBuilder.append(CharRepo.NEG128.getCh());
|
||||
n -= 128;
|
||||
}
|
||||
if (n - 64 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG64.getCh());
|
||||
n -= 64;
|
||||
}
|
||||
if (n - 32 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG32.getCh());
|
||||
n -= 32;
|
||||
}
|
||||
if (n - 16 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG16.getCh());
|
||||
n -= 16;
|
||||
}
|
||||
if (n - 8 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG8.getCh());
|
||||
n -= 8;
|
||||
}
|
||||
if (n - 7 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG7.getCh());
|
||||
n -= 7;
|
||||
}
|
||||
if (n - 6 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG6.getCh());
|
||||
n -= 6;
|
||||
}
|
||||
if (n - 5 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG5.getCh());
|
||||
n -= 5;
|
||||
}
|
||||
if (n - 4 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG4.getCh());
|
||||
n -= 4;
|
||||
}
|
||||
if (n - 3 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG3.getCh());
|
||||
n -= 3;
|
||||
}
|
||||
if (n - 2 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG2.getCh());
|
||||
n -= 2;
|
||||
}
|
||||
if (n - 1 >= 0) {
|
||||
stringBuilder.append(CharRepo.NEG1.getCh());
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
public char getCh() {
|
||||
return ch;
|
||||
}
|
||||
|
||||
public int getEffectiveWidth() {
|
||||
return effectiveWidth;
|
||||
}
|
||||
|
||||
public int getBoldLength() {
|
||||
if (this == CharRepo.SPACE) return this.width;
|
||||
return this.width + 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package me.unurled.sacredrealms.sr.utils.character;
|
||||
|
||||
public class CharacterArranger {
|
||||
public static char currentChar;
|
||||
|
||||
public static void increase() {
|
||||
currentChar = (char) (currentChar + '\u0001');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and increase the char arranged automatically by the plugin
|
||||
*
|
||||
* @return char
|
||||
*/
|
||||
public static char getAndIncrease() {
|
||||
char temp = currentChar;
|
||||
increase();
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase and get the char arranged automatically by the plugin
|
||||
*
|
||||
* @return char
|
||||
*/
|
||||
public static char increaseAndGet() {
|
||||
increase();
|
||||
return currentChar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the initial char
|
||||
*
|
||||
* @param c char
|
||||
*/
|
||||
public static void reset(char c) {
|
||||
currentChar = c;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package me.unurled.sacredrealms.sr.utils.character;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.warn;
|
||||
|
||||
public class ConfiguredChar {
|
||||
private char character;
|
||||
private String pngFile;
|
||||
private int height;
|
||||
private int width;
|
||||
private int ascent;
|
||||
|
||||
private ConfiguredChar() {}
|
||||
|
||||
public ConfiguredChar(char character, String pngFile, int height, int width, int ascent) {
|
||||
this.character = character;
|
||||
this.pngFile = pngFile;
|
||||
this.height = height;
|
||||
this.width = width;
|
||||
this.ascent = ascent;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public char getCharacter() {
|
||||
return character;
|
||||
}
|
||||
|
||||
public String getPngFile() {
|
||||
return pngFile;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getAscent() {
|
||||
return ascent;
|
||||
}
|
||||
|
||||
public String getFile() {
|
||||
return pngFile + ".png";
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final ConfiguredChar configuredChar;
|
||||
|
||||
public Builder() {
|
||||
this.configuredChar = new ConfiguredChar();
|
||||
}
|
||||
|
||||
public static Builder of() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder character(char character) {
|
||||
configuredChar.character = character;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder png(String png) {
|
||||
configuredChar.pngFile = png;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder height(int height) {
|
||||
configuredChar.height = height;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder ascent(int ascent) {
|
||||
configuredChar.ascent = ascent;
|
||||
if (ascent >= configuredChar.height) {
|
||||
warn("Invalid config for " + configuredChar.pngFile);
|
||||
warn("Ascent " + ascent + " should be no higher than Height " + configuredChar.height);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder descent(int descent) {
|
||||
if (descent < 0) {
|
||||
warn("Invalid config for " + configuredChar.pngFile);
|
||||
warn("Descent " + descent + " should be no lower than 0");
|
||||
}
|
||||
configuredChar.ascent = configuredChar.height - descent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder width(int width) {
|
||||
configuredChar.width = width;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfiguredChar build() {
|
||||
return configuredChar;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package me.unurled.sacredrealms.sr.utils.gson;
|
||||
|
||||
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import java.lang.reflect.Type;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.TagParser;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.entity.CraftEntity;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class EntityGson {
|
||||
public class Deserializer implements JsonDeserializer<Entity> {
|
||||
|
||||
/**
|
||||
* Gson invokes this call-back method during deserialization when it encounters a field of the
|
||||
* specified type.
|
||||
*
|
||||
* <p>In the implementation of this call-back method, you should consider invoking {@link
|
||||
* JsonDeserializationContext#deserialize(JsonElement, Type)} method to create objects for any
|
||||
* non-trivial field of the returned object. However, you should never invoke it on the same
|
||||
* type passing {@code json} since that will cause an infinite loop (Gson will call your
|
||||
* call-back method again).
|
||||
*
|
||||
* @param json The Json data being deserialized
|
||||
* @param typeOfT The type of the Object to deserialize to
|
||||
* @param context
|
||||
* @return a deserialized object of the specified type typeOfT which is a subclass of {@code T}
|
||||
* @throws JsonParseException if json is not in the expected format of {@code typeofT}
|
||||
*/
|
||||
@Override
|
||||
public Entity deserialize(
|
||||
@NotNull JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||
throws JsonParseException {
|
||||
// get type from json, get location from json, then create entity and paste nbt data
|
||||
EntityType type = EntityType.valueOf(json.getAsJsonObject().get("type").getAsString());
|
||||
Location location =
|
||||
new LocationSerializer()
|
||||
.deserialize(json.getAsJsonObject().get("location"), Location.class, context);
|
||||
Entity e = location.getWorld().spawnEntity(location, type);
|
||||
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) e).getHandle();
|
||||
try {
|
||||
nmsEntity.load(TagParser.parseTag(json.getAsJsonObject().get("entity").getAsString()));
|
||||
} catch (CommandSyntaxException ex) {
|
||||
error("Failed to parse entity NBT data " + ex.getMessage());
|
||||
}
|
||||
e.teleportAsync(location);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
public class Serializer implements JsonSerializer<Entity> {
|
||||
|
||||
/**
|
||||
* Gson invokes this call-back method during serialization when it encounters a field of the
|
||||
* specified type.
|
||||
*
|
||||
* <p>In the implementation of this call-back method, you should consider invoking {@link
|
||||
* JsonSerializationContext#serialize(Object, Type)} method to create JsonElements for any
|
||||
* non-trivial field of the {@code src} object. However, you should never invoke it on the
|
||||
* {@code src} object itself since that will cause an infinite loop (Gson will call your
|
||||
* call-back method again).
|
||||
*
|
||||
* @param src the object that needs to be converted to Json.
|
||||
* @param typeOfSrc the actual type (fully genericized version) of the source object.
|
||||
* @param context
|
||||
* @return a JsonElement corresponding to the specified object.
|
||||
*/
|
||||
@Override
|
||||
public JsonElement serialize(
|
||||
@NotNull Entity src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
net.minecraft.world.entity.Entity nmsEntity = ((CraftEntity) src).getHandle();
|
||||
CompoundTag nbt = new CompoundTag();
|
||||
nmsEntity.save(nbt);
|
||||
LocationSerializer locationSerializer = new LocationSerializer();
|
||||
String s =
|
||||
"{\"type\":"
|
||||
+ src.getType().name()
|
||||
+ ", \"location\":"
|
||||
+ locationSerializer.serialize(src.getLocation(), Location.class, context)
|
||||
+ ", \"entity\":"
|
||||
+ nbt.getAsString()
|
||||
+ "}";
|
||||
return new JsonPrimitive(s);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package me.unurled.sacredrealms.sr.utils.gson;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import io.leangen.geantyref.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import org.bukkit.Location;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class LocationSerializer implements JsonSerializer<Location>, JsonDeserializer<Location> {
|
||||
|
||||
/**
|
||||
* Gson invokes this call-back method during serialization when it encounters a field of the
|
||||
* specified type.
|
||||
*
|
||||
* <p>In the implementation of this call-back method, you should consider invoking {@link
|
||||
* JsonSerializationContext#serialize(Object, Type)} method to create JsonElements for any
|
||||
* non-trivial field of the {@code src} object. However, you should never invoke it on the {@code
|
||||
* src} object itself since that will cause an infinite loop (Gson will call your call-back method
|
||||
* again).
|
||||
*
|
||||
* @param src the object that needs to be converted to Json.
|
||||
* @param typeOfSrc the actual type (fully genericized version) of the source object.
|
||||
* @param context
|
||||
* @return a JsonElement corresponding to the specified object.
|
||||
*/
|
||||
@Override
|
||||
public JsonElement serialize(
|
||||
@NotNull Location src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
Gson gson = new Gson();
|
||||
|
||||
return gson.toJsonTree(src.serialize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location deserialize(
|
||||
JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext)
|
||||
throws JsonParseException {
|
||||
Gson gson = new Gson();
|
||||
|
||||
Type typ = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
|
||||
return Location.deserialize(gson.fromJson(jsonElement, typ));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package me.unurled.sacredrealms.sr.utils.gson;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import io.leangen.geantyref.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
|
||||
public class MapSerializer
|
||||
implements JsonSerializer<Map<String, Object>>, JsonDeserializer<Map<String, Object>> {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> deserialize(
|
||||
JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext)
|
||||
throws JsonParseException {
|
||||
|
||||
Type typ = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
|
||||
return new Gson().fromJson(jsonElement, typ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(
|
||||
Map<String, Object> stringObjectMap,
|
||||
Type type,
|
||||
JsonSerializationContext jsonSerializationContext) {
|
||||
return new Gson().toJsonTree(stringObjectMap);
|
||||
}
|
||||
}
|
BIN
src/main/resources/backgrounds/b0.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/main/resources/backgrounds/b1.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/main/resources/backgrounds/b128.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/main/resources/backgrounds/b16.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/main/resources/backgrounds/b2.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/main/resources/backgrounds/b32.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/main/resources/backgrounds/b4.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/main/resources/backgrounds/b64.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/main/resources/backgrounds/b8.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
|
@ -1,3 +1,6 @@
|
|||
redis:
|
||||
host: "127.0.0.1"
|
||||
port: 6379
|
||||
|
||||
resource_pack: "http://127.0.0.1:8080"
|
||||
resource_pack_api: "your_api_key_here"
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
name: $name
|
||||
version: $version
|
||||
main: me.unurled.sacredrealms.sr.SR
|
||||
api-version: "$apiVersion"
|
||||
description: $description
|
||||
loader: me.unurled.sacredrealms.sr.SRLoader
|
||||
bootstrapper: me.unurled.sacredrealms.sr.SRBootstrap
|
||||
|
||||
permissions:
|
||||
sr.*:
|
||||
description: Gives access to all Sacred Realms permissions
|
||||
default: op
|
||||
children:
|
||||
sr.tutorial: true
|
||||
sr.spawn: true
|
||||
sr.attributes: true
|
||||
sr.clientbuild: true
|
||||
sr.level: true
|
||||
sr.entitytype: true
|
||||
sr.spawn-entity: true
|
||||
sr.admin.item: true
|
||||
sr.resetadventure: true
|
||||
sr.treasure.manage: true
|
||||
sr.difficulty.*: true
|
||||
sr.tutorial:
|
||||
default: not op
|
||||
description: When the player joins and doesn't have finished the tutorial.
|
||||
sr.spawn:
|
||||
default: not op
|
||||
description: When the player have discovered the spawn.
|
||||
sr.attributes:
|
||||
default: op
|
||||
description: When the player has permission for the command /attributes set
|
||||
sr.clientbuild:
|
||||
default: op
|
||||
description: When the player has permission for the command /clientbuild
|
||||
sr.level:
|
||||
default: op
|
||||
description: When the player has permission for the command /level
|
||||
sr.entitytype:
|
||||
default: op
|
||||
description: When the player has permission for the command /entitytype
|
||||
sr.spawn-entity:
|
||||
default: op
|
||||
description: When the player has permission for the command /spawn
|
||||
sr.admin.item:
|
||||
default: op
|
||||
description: When the player has permission for the command /item
|
||||
sr.resetadventure:
|
||||
default: op
|
||||
description: When the player has permission for the command /resetadventure
|
||||
sr.treasure.manage:
|
||||
default: op
|
||||
description: When the player has permission for the command /treasure create
|
||||
sr.difficulty.*:
|
||||
description: gives permission for all difficulty commands
|
||||
children:
|
||||
sr.difficulty.manage: true
|
||||
sr.difficulty.self: true
|
1
src/main/resources/rp/assets.ajmeta
Normal file
|
@ -0,0 +1 @@
|
|||
{"sr":{"files":["assets/animated_java/models/empty.json","assets/animated_java/models/item/sr/top.json","assets/animated_java/models/item/sr/bottom.json","assets/animated_java/textures/item/sr/treasure_chest_top.png","assets/animated_java/textures/item/sr/treasure_chest_bottom.png","assets/animated_java/textures/item/sr/treasure_chest_metal.png","assets/animated_java/textures/item/transparent.png"]}}
|
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -0,0 +1 @@
|
|||
{"textures":{"1":"animated_java:item/sr/treasure_chest_bottom"},"elements":[{"from":[2,8,2],"to":[14,16,14],"faces":{"north":{"uv":[6,0,12,4],"texture":"#1"},"east":{"uv":[6,4,12,8],"texture":"#1"},"south":{"uv":[6,8,12,12],"texture":"#1"},"west":{"uv":[0,12,6,16],"texture":"#1"},"up":{"uv":[6,6,0,0],"texture":"#1"},"down":{"uv":[6,6,0,12],"texture":"#1"}}}],"display":{"head":{"rotation":[0,180,0]}}}
|
|
@ -0,0 +1 @@
|
|||
{"textures":{"0":"animated_java:item/sr/treasure_chest_top","2":"animated_java:item/sr/treasure_chest_metal"},"elements":[{"from":[7,6,20],"to":[9,10,22],"rotation":{"angle":0,"axis":"y","origin":[8,6,21]},"faces":{"north":{"uv":[0,0,2,4],"texture":"#2"},"east":{"uv":[2,0,4,4],"texture":"#2"},"south":{"uv":[0,4,2,8],"texture":"#2"},"west":{"uv":[4,0,6,4],"texture":"#2"},"up":{"uv":[4,6,2,4],"texture":"#2"},"down":{"uv":[6,4,4,6],"texture":"#2"}}},{"from":[2,8,8],"to":[14,12,20],"rotation":{"angle":0,"axis":"y","origin":[3,8,9]},"faces":{"north":{"uv":[6,0,12,2],"texture":"#0"},"east":{"uv":[6,2,12,4],"texture":"#0"},"south":{"uv":[6,4,12,6],"texture":"#0"},"west":{"uv":[6,6,12,8],"texture":"#0"},"up":{"uv":[6,6,0,0],"texture":"#0"},"down":{"uv":[6,6,0,12],"texture":"#0"}}}],"display":{"head":{"rotation":[0,180,0]}}}
|