refactor(layout): clean packaging
This commit is contained in:
parent
273ffb28ec
commit
575224a69d
80 changed files with 48 additions and 18 deletions
175
core/dependency-reduced-pom.xml
Normal file
175
core/dependency-reduced-pom.xml
Normal file
|
@ -0,0 +1,175 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<parent>
|
||||
<artifactId>nicko-parent</artifactId>
|
||||
<groupId>net.artelnatif</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>nicko-core</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${basedir}/src/main/resources/</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M7</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.3.1-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifactSet>
|
||||
<includes>
|
||||
<include>net.wesjd:anvilgui</include>
|
||||
<include>de.studiocode.invui:*</include>
|
||||
<include>com.github.jsixface:*</include>
|
||||
<include>com.fasterxml.jackson.dataformat</include>
|
||||
<include>com.fasterxml.jackson.core</include>
|
||||
<include>org.mariadb.jdbc</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>net.wesjd.anvilgui</pattern>
|
||||
<shadedPattern>net.artelnatif.libs.anvilgui</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>de.studiocode.invui</pattern>
|
||||
<shadedPattern>net.artelnatif.libs.invui</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.github.jsixface</pattern>
|
||||
<shadedPattern>net.artelnatif.libs.yaml</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.fasterxml.jackson.dataformat</pattern>
|
||||
<shadedPattern>net.artelnatif.libs.jackson.yaml</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.fasterxml.jackson.core</pattern>
|
||||
<shadedPattern>net.artelnatif.libs.jackson.core</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.mariadb.jdbc</pattern>
|
||||
<shadedPattern>net.artelnatif.libs.mariadb</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<minimizeJar>false</minimizeJar>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>papermc</id>
|
||||
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>xenondevs</id>
|
||||
<url>https://repo.xenondevs.xyz/releases</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>bungeecord-repo</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>codemc-snapshots</id>
|
||||
<url>https://repo.codemc.io/repository/maven-snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>placeholderapi</id>
|
||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>me.clip</groupId>
|
||||
<artifactId>placeholderapi</artifactId>
|
||||
<version>2.11.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.19.3-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.18-R0.1-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>31.1-jre</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.seeseemelk</groupId>
|
||||
<artifactId>MockBukkit-v1.19</artifactId>
|
||||
<version>2.29.0</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>hamcrest-library</artifactId>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>adventure-platform-bungeecord</artifactId>
|
||||
<groupId>net.kyori</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>maven-resolver-provider</artifactId>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>maven-resolver-connector-basic</artifactId>
|
||||
<groupId>org.apache.maven.resolver</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>maven-resolver-transport-http</artifactId>
|
||||
<groupId>org.apache.maven.resolver</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
</project>
|
196
core/pom.xml
Normal file
196
core/pom.xml
Normal file
|
@ -0,0 +1,196 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>core</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>net.artelnatif</groupId>
|
||||
<artifactId>nicko-parent</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>papermc</id>
|
||||
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>xenondevs</id>
|
||||
<url>https://repo.xenondevs.xyz/releases</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>bungeecord-repo</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>codemc-snapshots</id>
|
||||
<url>https://repo.codemc.io/repository/maven-snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>placeholderapi</id>
|
||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- PlaceHolder API -->
|
||||
<dependency>
|
||||
<groupId>me.clip</groupId>
|
||||
<artifactId>placeholderapi</artifactId>
|
||||
<version>2.11.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Spigot API -->
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.19.3-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- BungeeCord API -->
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
<version>1.18-R0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!-- Inventory Lib -->
|
||||
<dependency>
|
||||
<groupId>de.studiocode.invui</groupId>
|
||||
<artifactId>InvUI</artifactId>
|
||||
<version>0.10.2</version>
|
||||
</dependency>
|
||||
<!-- AnvilGUI -->
|
||||
<dependency>
|
||||
<groupId>net.wesjd</groupId>
|
||||
<artifactId>anvilgui</artifactId>
|
||||
<version>1.6.3-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!-- Apache Lang3 (LocaleUtils) -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
<!-- Google Guava (GSON) -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>31.1-jre</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- MockBukkit 1.19 (Bukkit Unit Tests) -->
|
||||
<dependency>
|
||||
<groupId>com.github.seeseemelk</groupId>
|
||||
<artifactId>MockBukkit-v1.19</artifactId>
|
||||
<version>2.29.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- MariaDB JDBC Driver -->
|
||||
<dependency>
|
||||
<groupId>org.mariadb.jdbc</groupId>
|
||||
<artifactId>mariadb-java-client</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</dependency>
|
||||
<!-- YAML Reader -->
|
||||
<dependency>
|
||||
<groupId>com.github.jsixface</groupId>
|
||||
<artifactId>yamlconfig</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>2.14.0-rc1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-yaml</artifactId>
|
||||
<version>2.14.0-rc1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.0.0-M7</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.3.1-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<artifactSet>
|
||||
<includes>
|
||||
<include>net.wesjd:anvilgui</include>
|
||||
<include>de.studiocode.invui:*</include>
|
||||
<include>com.github.jsixface:*</include>
|
||||
<include>com.fasterxml.jackson.dataformat</include>
|
||||
<include>com.fasterxml.jackson.core</include>
|
||||
<include>org.mariadb.jdbc</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>net.wesjd.anvilgui</pattern>
|
||||
<shadedPattern>net.artelnatif.libs.anvilgui</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>de.studiocode.invui</pattern>
|
||||
<shadedPattern>net.artelnatif.libs.invui</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.github.jsixface</pattern>
|
||||
<shadedPattern>net.artelnatif.libs.yaml</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.fasterxml.jackson.dataformat</pattern>
|
||||
<shadedPattern>net.artelnatif.libs.jackson.yaml</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>com.fasterxml.jackson.core</pattern>
|
||||
<shadedPattern>net.artelnatif.libs.jackson.core</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.mariadb.jdbc</pattern>
|
||||
<shadedPattern>net.artelnatif.libs.mariadb</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<!-- Prevents breaking AnvilGUI's VersionWrapper. -->
|
||||
<minimizeJar>false</minimizeJar>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${basedir}/src/main/resources/</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
</project>
|
86
core/src/main/java/net/artelnatif/nicko/Nicko.java
Normal file
86
core/src/main/java/net/artelnatif/nicko/Nicko.java
Normal file
|
@ -0,0 +1,86 @@
|
|||
package net.artelnatif.nicko;
|
||||
|
||||
import net.artelnatif.nicko.config.Configuration;
|
||||
import net.artelnatif.nicko.config.ConfigurationManager;
|
||||
import net.artelnatif.nicko.mojang.MojangAPI;
|
||||
import net.artelnatif.nicko.storage.PlayerDataStore;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class Nicko {
|
||||
private boolean bungeecord = false;
|
||||
private ConfigurationManager configManager;
|
||||
private Logger logger;
|
||||
private File dataFolder;
|
||||
private MojangAPI mojangAPI;
|
||||
private Configuration config;
|
||||
|
||||
private PlayerDataStore dataStore;
|
||||
|
||||
public void initBungeecord(Plugin bungee) {
|
||||
logger = bungee.getLogger();
|
||||
dataFolder = bungee.getDataFolder();
|
||||
bungeecord = true;
|
||||
initNicko();
|
||||
}
|
||||
|
||||
public void initBukkit(JavaPlugin bukkit) {
|
||||
logger = bukkit.getLogger();
|
||||
dataFolder = bukkit.getDataFolder();
|
||||
initNicko();
|
||||
}
|
||||
|
||||
private void initNicko() {
|
||||
configManager = new ConfigurationManager(this);
|
||||
configManager.saveDefaultConfig();
|
||||
|
||||
mojangAPI = new MojangAPI(this);
|
||||
dataStore = new PlayerDataStore(this);
|
||||
}
|
||||
|
||||
public Logger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
public PlayerDataStore getDataStore() {
|
||||
return dataStore;
|
||||
}
|
||||
|
||||
public File getDataFolder() {
|
||||
return dataFolder;
|
||||
}
|
||||
|
||||
public MojangAPI getMojangAPI() {
|
||||
return mojangAPI;
|
||||
}
|
||||
|
||||
public ConfigurationManager getConfigManager() {
|
||||
return configManager;
|
||||
}
|
||||
|
||||
public Configuration getConfig() {
|
||||
try {
|
||||
if (config == null) { return config = configManager.load(); }
|
||||
return config;
|
||||
} catch (IOException e) {
|
||||
logger.severe("Failed to load configuration file: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setConfig(Configuration config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public boolean isBungeecord() {
|
||||
return bungeecord;
|
||||
}
|
||||
|
||||
public void setBungeecord(boolean bungeecord) {
|
||||
this.bungeecord = bungeecord;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package net.artelnatif.nicko.bukkit;
|
||||
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
public class BungeeCordSupport {
|
||||
private final NickoBukkit instance;
|
||||
|
||||
public BungeeCordSupport(NickoBukkit instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public void warnNickoNotHookedToBungeeCord() {
|
||||
final Server server = instance.getServer();
|
||||
final YamlConfiguration config = server.spigot().getConfig();
|
||||
if (config.getConfigurationSection("settings").getBoolean("bungeecord") && !instance.getNicko().getConfig().bungeecord()) {
|
||||
instance.getLogger().warning("Hummm. Your server is hooked to BungeeCord, but it seems");
|
||||
instance.getLogger().warning("that BungeeCord support is not enabled inside Nicko.");
|
||||
instance.getLogger().warning("If this is intentional, you can safely ignore this message.");
|
||||
instance.getLogger().warning("Otherwise, you can enable BungeeCord support inside Nicko's configuration file.");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean stopIfBungeeCordIsNotEnabled() {
|
||||
final Server server = instance.getServer();
|
||||
final YamlConfiguration config = server.spigot().getConfig();
|
||||
if (!config.getConfigurationSection("settings").getBoolean("bungeecord") && instance.getNicko().getConfig().bungeecord()) {
|
||||
instance.getLogger().severe("Hummm. You have enabled BungeeCord support inside Nicko,");
|
||||
instance.getLogger().severe("but it seems that your server is not hooked to your BungeeCord instance.");
|
||||
instance.getLogger().severe("Please enable BungeeCord support inside your spigot.yml as well.");
|
||||
instance.getLogger().severe("The plugin will not continue.");
|
||||
instance.getServer().getPluginManager().disablePlugin(instance);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
163
core/src/main/java/net/artelnatif/nicko/bukkit/NickoBukkit.java
Normal file
163
core/src/main/java/net/artelnatif/nicko/bukkit/NickoBukkit.java
Normal file
|
@ -0,0 +1,163 @@
|
|||
package net.artelnatif.nicko.bukkit;
|
||||
|
||||
import de.studiocode.invui.gui.structure.Structure;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.SimpleItem;
|
||||
import net.artelnatif.nicko.Nicko;
|
||||
import net.artelnatif.nicko.bukkit.command.NickoCommand;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.main.ExitGUI;
|
||||
import net.artelnatif.nicko.bukkit.pluginchannel.PluginMessageHandler;
|
||||
import net.artelnatif.nicko.bungee.NickoBungee;
|
||||
import net.artelnatif.nicko.config.Configuration;
|
||||
import net.artelnatif.nicko.bukkit.event.PlayerJoinListener;
|
||||
import net.artelnatif.nicko.bukkit.event.PlayerQuitListener;
|
||||
import net.artelnatif.nicko.bukkit.i18n.Locale;
|
||||
import net.artelnatif.nicko.bukkit.i18n.LocaleFileManager;
|
||||
import net.artelnatif.nicko.impl.Internals;
|
||||
import net.artelnatif.nicko.impl.InternalsProvider;
|
||||
import net.artelnatif.nicko.mojang.MojangAPI;
|
||||
import net.artelnatif.nicko.bukkit.placeholder.PlaceHolderHook;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class NickoBukkit extends JavaPlugin {
|
||||
private static NickoBukkit plugin;
|
||||
|
||||
private final Nicko nicko = new Nicko();
|
||||
private final boolean unitTesting;
|
||||
|
||||
private MojangAPI mojangAPI;
|
||||
private LocaleFileManager localeFileManager;
|
||||
|
||||
public NickoBukkit() { this.unitTesting = false; }
|
||||
|
||||
/**
|
||||
* Used by MockBukkit
|
||||
*/
|
||||
protected NickoBukkit(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file, Configuration config) {
|
||||
super(loader, description, dataFolder, file);
|
||||
unitTesting = true;
|
||||
nicko.setConfig(config);
|
||||
getLogger().info("Unit Testing Mode enabled.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
plugin = this;
|
||||
|
||||
if (isUnitTesting()) {
|
||||
onUnitTestingStartup();
|
||||
} else {
|
||||
onPluginStartup();
|
||||
}
|
||||
}
|
||||
|
||||
public void onUnitTestingStartup() {
|
||||
nicko.initBukkit(this);
|
||||
|
||||
if (!nicko.getDataStore().getStorage().getProvider().init()) {
|
||||
nicko.getDataStore().getStorage().setError(true);
|
||||
getLogger().severe("Failed to open persistence, data will NOT be saved!");
|
||||
}
|
||||
}
|
||||
|
||||
public void onPluginStartup() {
|
||||
nicko.initBukkit(this);
|
||||
|
||||
getLogger().info("Loading internals...");
|
||||
if (getInternals() == null) {
|
||||
getLogger().severe("Nicko could not find a valid implementation for this server version. Is your server supported?");
|
||||
nicko.getDataStore().getStorage().setError(true);
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
}
|
||||
|
||||
if (getServer().getPluginManager().isPluginEnabled(this) && !nicko.getDataStore().getStorage().isError()) {
|
||||
getLogger().info("Loading persistence...");
|
||||
if (!nicko.getDataStore().getStorage().getProvider().init()) {
|
||||
nicko.getDataStore().getStorage().setError(true);
|
||||
getLogger().severe("Failed to open persistence, data will NOT be saved!");
|
||||
}
|
||||
|
||||
mojangAPI = new MojangAPI(nicko);
|
||||
|
||||
localeFileManager = new LocaleFileManager();
|
||||
if (nicko.getConfig().customLocale()) {
|
||||
if (localeFileManager.dumpFromLocale(Locale.ENGLISH)) {
|
||||
getLogger().info("Successfully loaded custom language file.");
|
||||
} else {
|
||||
getLogger().severe("Failed to load custom language file!");
|
||||
}
|
||||
}
|
||||
|
||||
final PluginCommand command = getCommand("nicko");
|
||||
if (command != null) {
|
||||
command.setExecutor(new NickoCommand());
|
||||
}
|
||||
|
||||
Structure.addGlobalIngredient('#', new SimpleItem(new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE).setDisplayName(" ")));
|
||||
Structure.addGlobalIngredient('%', new SimpleItem(new ItemBuilder(Material.ORANGE_STAINED_GLASS_PANE).setDisplayName(" ")));
|
||||
Structure.addGlobalIngredient('E', new ExitGUI());
|
||||
|
||||
new PlaceHolderHook(this).hook();
|
||||
|
||||
getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this);
|
||||
getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this);
|
||||
|
||||
final BungeeCordSupport support = new BungeeCordSupport(this);
|
||||
support.warnNickoNotHookedToBungeeCord();
|
||||
if (nicko.getConfig().bungeecord()) {
|
||||
if (support.stopIfBungeeCordIsNotEnabled()) {
|
||||
getLogger().info("Enabling BungeeCord support...");
|
||||
getServer().getMessenger().registerIncomingPluginChannel(this, NickoBungee.PROXY_UPDATE, new PluginMessageHandler());
|
||||
}
|
||||
}
|
||||
|
||||
getLogger().info("Nicko (Bukkit) has been enabled.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
if (!nicko.getDataStore().getStorage().isError()) {
|
||||
getLogger().info("Closing persistence...");
|
||||
nicko.getDataStore().removeAllNames();
|
||||
Bukkit.getOnlinePlayers().forEach(player -> nicko.getDataStore().saveData(player));
|
||||
if (!nicko.getDataStore().getStorage().getProvider().close()) {
|
||||
getLogger().severe("Failed to close persistence!");
|
||||
}
|
||||
}
|
||||
|
||||
if (nicko.getConfig().bungeecord()) {
|
||||
getServer().getMessenger().unregisterIncomingPluginChannel(this);
|
||||
getServer().getMessenger().unregisterOutgoingPluginChannel(this);
|
||||
}
|
||||
|
||||
getLogger().info("Nicko (Bukkit) has been disabled.");
|
||||
}
|
||||
|
||||
public static NickoBukkit getInstance() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public Nicko getNicko() {
|
||||
return nicko;
|
||||
}
|
||||
|
||||
public LocaleFileManager getLocaleFileManager() {
|
||||
return localeFileManager;
|
||||
}
|
||||
|
||||
public boolean isUnitTesting() {
|
||||
return unitTesting;
|
||||
}
|
||||
|
||||
public Internals getInternals() {
|
||||
return InternalsProvider.getInternals();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package net.artelnatif.nicko.bukkit.anvil;
|
||||
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.bukkit.appearance.AppearanceManager;
|
||||
import net.artelnatif.nicko.disguise.ActionResult;
|
||||
import net.artelnatif.nicko.bukkit.i18n.I18N;
|
||||
import net.artelnatif.nicko.bukkit.i18n.I18NDict;
|
||||
import net.artelnatif.nicko.mojang.MojangUtils;
|
||||
import net.wesjd.anvilgui.AnvilGUI;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class AnvilManager {
|
||||
private final Player player;
|
||||
private final AppearanceManager appearanceManager;
|
||||
|
||||
public AnvilManager(Player player) {
|
||||
this.player = player;
|
||||
this.appearanceManager = AppearanceManager.get(player);
|
||||
}
|
||||
|
||||
public void openNameThenSkinAnvil() {
|
||||
getNameThenSkinAnvil().open(player);
|
||||
}
|
||||
|
||||
public void openSkinAnvil() {
|
||||
getSkinAnvil().open(player);
|
||||
}
|
||||
|
||||
public void openNameAnvil() {
|
||||
getNameAnvil().open(player);
|
||||
}
|
||||
|
||||
public AnvilGUI.Builder getNameThenSkinAnvil() {
|
||||
return new AnvilGUI.Builder()
|
||||
.plugin(NickoBukkit.getInstance())
|
||||
.itemLeft(getLeftItem(false))
|
||||
.interactableSlots(AnvilGUI.Slot.OUTPUT)
|
||||
.onComplete((completion) -> {
|
||||
if (MojangUtils.isUsernameInvalid(completion.getText())) {
|
||||
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
|
||||
} else {
|
||||
appearanceManager.setName(completion.getText());
|
||||
openSkinAnvil();
|
||||
return Collections.singletonList(AnvilGUI.ResponseAction.close());
|
||||
}
|
||||
})
|
||||
.text("New name...");
|
||||
}
|
||||
|
||||
public AnvilGUI.Builder getNameAnvil() {
|
||||
return new AnvilGUI.Builder()
|
||||
.plugin(NickoBukkit.getInstance())
|
||||
.itemLeft(getLeftItem(false))
|
||||
.interactableSlots(AnvilGUI.Slot.OUTPUT)
|
||||
.onComplete((completion) -> {
|
||||
if (MojangUtils.isUsernameInvalid(completion.getText())) {
|
||||
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
|
||||
} else {
|
||||
appearanceManager.setName(completion.getText());
|
||||
final ActionResult<Void> actionResult = appearanceManager.updatePlayer(false);
|
||||
return sendResultAndClose(actionResult);
|
||||
}
|
||||
})
|
||||
.text("New name...");
|
||||
}
|
||||
|
||||
private AnvilGUI.Builder getSkinAnvil() {
|
||||
return new AnvilGUI.Builder()
|
||||
.plugin(NickoBukkit.getInstance())
|
||||
.itemLeft(getLeftItem(true))
|
||||
.interactableSlots(AnvilGUI.Slot.OUTPUT)
|
||||
.onComplete((completion) -> {
|
||||
if (MojangUtils.isUsernameInvalid(completion.getText())) {
|
||||
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
|
||||
} else {
|
||||
appearanceManager.setSkin(completion.getText());
|
||||
final ActionResult<Void> actionResult = appearanceManager.updatePlayer(true);
|
||||
return sendResultAndClose(actionResult);
|
||||
}
|
||||
})
|
||||
.text("New skin...");
|
||||
}
|
||||
|
||||
private List<AnvilGUI.ResponseAction> sendResultAndClose(ActionResult<Void> actionResult) {
|
||||
if (!actionResult.isError()) {
|
||||
player.sendMessage(I18N.translate(player, I18NDict.Event.Disguise.SUCCESS));
|
||||
} else {
|
||||
player.sendMessage(I18N.translate(player, I18NDict.Event.Disguise.FAIL, I18N.translateWithoutPrefix(player, actionResult.getErrorMessage())));
|
||||
}
|
||||
return Collections.singletonList(AnvilGUI.ResponseAction.close());
|
||||
}
|
||||
|
||||
private ItemStack getLeftItem(boolean skin) {
|
||||
final ItemStack item = new ItemStack(Material.PAPER);
|
||||
final ItemMeta meta = item.getItemMeta();
|
||||
meta.setDisplayName("§0New " + (skin ? "skin" : "name") + "...");
|
||||
item.setItemMeta(meta);
|
||||
return item;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package net.artelnatif.nicko.bukkit.appearance;
|
||||
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.disguise.ActionResult;
|
||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||
import net.artelnatif.nicko.storage.PlayerDataStore;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class AppearanceManager {
|
||||
private final NickoProfile profile;
|
||||
private final Player player;
|
||||
private final NickoBukkit instance = NickoBukkit.getInstance();
|
||||
private final PlayerDataStore dataStore = instance.getNicko().getDataStore();
|
||||
|
||||
private AppearanceManager(UUID uuid) {
|
||||
this.player = Bukkit.getPlayer(uuid);
|
||||
this.profile = dataStore.getData(uuid).orElse(NickoProfile.EMPTY_PROFILE.clone());
|
||||
}
|
||||
|
||||
private AppearanceManager(String name) {
|
||||
this.player = null;
|
||||
this.profile = dataStore.getOfflineData(name).orElse(NickoProfile.EMPTY_PROFILE.clone());
|
||||
}
|
||||
|
||||
public static AppearanceManager get(Player player) {
|
||||
return new AppearanceManager(player.getUniqueId());
|
||||
}
|
||||
|
||||
public static AppearanceManager get(String name) {
|
||||
return new AppearanceManager(name);
|
||||
}
|
||||
|
||||
public boolean hasData() {
|
||||
return !profile.isEmpty();
|
||||
}
|
||||
|
||||
public void setSkin(String skin) {
|
||||
profile.setSkin(skin);
|
||||
}
|
||||
|
||||
public String getSkin() {
|
||||
return profile.getSkin();
|
||||
}
|
||||
|
||||
public boolean needsASkinChange() {
|
||||
return profile.getSkin() != null && !profile.getSkin().equals(player.getName());
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
profile.setName(name);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return profile.getName();
|
||||
}
|
||||
|
||||
public NickoProfile getProfile() {
|
||||
return profile;
|
||||
}
|
||||
|
||||
public void setNameAndSkin(String name, String skin) {
|
||||
this.profile.setName(name);
|
||||
this.profile.setSkin(skin);
|
||||
updatePlayer(true);
|
||||
}
|
||||
|
||||
public ActionResult<Void> reset() {
|
||||
final String defaultName = instance.getNicko().getDataStore().getStoredName(player);
|
||||
this.profile.setName(defaultName);
|
||||
this.profile.setSkin(defaultName);
|
||||
final ActionResult<Void> actionResult = resetPlayer();
|
||||
this.profile.setSkin(null);
|
||||
this.profile.setName(null);
|
||||
return actionResult;
|
||||
}
|
||||
|
||||
public ActionResult<Void> resetPlayer() {
|
||||
return NickoBukkit.getInstance().getInternals().updateProfile(player, profile, true, true);
|
||||
}
|
||||
|
||||
public ActionResult<Void> updatePlayer(boolean skinChange) {
|
||||
return NickoBukkit.getInstance().getInternals().updateProfile(player, profile, skinChange, false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package net.artelnatif.nicko.bukkit.command;
|
||||
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.bukkit.command.sub.NickoCheckSubCmd;
|
||||
import net.artelnatif.nicko.bukkit.command.sub.NickoDebugSubCmd;
|
||||
import net.artelnatif.nicko.bukkit.gui.MainGUI;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class NickoCommand implements CommandExecutor {
|
||||
private String helpMessage = """
|
||||
§cNicko §8§o[{version}] §f- §2Help:
|
||||
§6/nicko §f- §7Open the GUI.
|
||||
§6/nicko help §f- §7Print this help message.
|
||||
""";
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (sender instanceof Player player) {
|
||||
if (args.length >= 1) {
|
||||
switch (args[0]) {
|
||||
case "debug" -> new NickoDebugSubCmd().execute(sender, args);
|
||||
case "check" -> new NickoCheckSubCmd().execute(player, args);
|
||||
default -> sendHelpMessage(sender);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
new MainGUI(player).open();
|
||||
return false;
|
||||
}
|
||||
|
||||
sender.sendMessage("This plugin can only be used in-game. Sorry!");
|
||||
return false;
|
||||
}
|
||||
|
||||
public void sendHelpMessage(CommandSender sender) {
|
||||
helpMessage = helpMessage.replace("{version}", NickoBukkit.getInstance().getDescription().getVersion());
|
||||
sender.sendMessage(helpMessage);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package net.artelnatif.nicko.bukkit.command.sub;
|
||||
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.bukkit.appearance.AppearanceManager;
|
||||
import net.artelnatif.nicko.bukkit.i18n.I18N;
|
||||
import net.artelnatif.nicko.bukkit.i18n.I18NDict;
|
||||
import net.artelnatif.nicko.mojang.MojangUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class NickoCheckSubCmd {
|
||||
public void execute(Player player, String[] args) {
|
||||
final String targetName = args[1];
|
||||
final Player target = Bukkit.getPlayerExact(targetName);
|
||||
|
||||
AppearanceManager appearanceManager;
|
||||
if (MojangUtils.isUsernameInvalid(targetName)) {
|
||||
player.sendMessage(I18N.translate(player, I18NDict.Error.INVALID_USERNAME));
|
||||
return;
|
||||
}
|
||||
|
||||
if (target == null) {
|
||||
appearanceManager = AppearanceManager.get(targetName);
|
||||
} else {
|
||||
appearanceManager = AppearanceManager.get(target);
|
||||
}
|
||||
|
||||
final StringJoiner builder = new StringJoiner("\n");
|
||||
builder.add("§c" + NickoBukkit.getInstance().getNicko().getConfig().prefix() + "§6Check for: §f§o" + targetName);
|
||||
if (!appearanceManager.hasData()) {
|
||||
builder.add("§cThis player has not data.");
|
||||
} else {
|
||||
builder.add("§7- §fNicked: §a✔");
|
||||
builder.add("§7- §fName: §6" + appearanceManager.getName());
|
||||
builder.add("§7- §fSkin: §6" + appearanceManager.getSkin());
|
||||
}
|
||||
|
||||
player.sendMessage(builder.toString());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package net.artelnatif.nicko.bukkit.command.sub;
|
||||
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.bukkit.appearance.AppearanceManager;
|
||||
import net.artelnatif.nicko.mojang.MojangUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class NickoDebugSubCmd {
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
final String prefix = NickoBukkit.getInstance().getNicko().getConfig().prefix();
|
||||
|
||||
Player target;
|
||||
String name, skin;
|
||||
if (args.length == 3) {
|
||||
target = (Player) sender;
|
||||
name = args[1];
|
||||
skin = args[2];
|
||||
} else {
|
||||
if (args.length < 3) {
|
||||
sender.sendMessage(prefix + "§cMissing argument.");
|
||||
return;
|
||||
}
|
||||
|
||||
final String playerName = args[1];
|
||||
name = args[2];
|
||||
skin = args[3];
|
||||
|
||||
target = Bukkit.getPlayer(playerName);
|
||||
if (target == null) {
|
||||
sender.sendMessage(prefix + "§cSpecified player is offline.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final AppearanceManager appearanceManager = AppearanceManager.get(target.getPlayer());
|
||||
|
||||
if (MojangUtils.isUsernameInvalid(name) || MojangUtils.isUsernameInvalid(skin)) {
|
||||
sender.sendMessage(prefix + "§cSpecified username is invalid.");
|
||||
}
|
||||
|
||||
appearanceManager.setNameAndSkin(name, skin);
|
||||
target.sendMessage(prefix + "§aWhoosh!");
|
||||
target.playSound(target.getLocation(), Sound.ENTITY_ITEM_FRAME_PLACE, 1, 1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package net.artelnatif.nicko.bukkit.event;
|
||||
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.bukkit.appearance.AppearanceManager;
|
||||
import net.artelnatif.nicko.disguise.ActionResult;
|
||||
import net.artelnatif.nicko.bukkit.i18n.I18N;
|
||||
import net.artelnatif.nicko.bukkit.i18n.I18NDict;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
public class PlayerJoinListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
NickoBukkit.getInstance().getNicko().getDataStore().storeName(player);
|
||||
Bukkit.getScheduler().runTaskLater(NickoBukkit.getInstance(), () -> {
|
||||
final AppearanceManager appearanceManager = AppearanceManager.get(player);
|
||||
|
||||
// TODO: 12/5/22 Update from BungeeCord
|
||||
|
||||
if (appearanceManager.hasData()) {
|
||||
final ActionResult<Void> actionResult = appearanceManager.updatePlayer(appearanceManager.needsASkinChange());
|
||||
if (!actionResult.isError()) {
|
||||
player.sendMessage(I18N.translate(player, I18NDict.Event.PreviousSkin.SUCCESS));
|
||||
} else {
|
||||
player.sendMessage(I18N.translate(player, I18NDict.Event.PreviousSkin.FAIL, I18N.translate(player, actionResult.getErrorMessage())));
|
||||
}
|
||||
}
|
||||
}, 20L);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package net.artelnatif.nicko.bukkit.event;
|
||||
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
public class PlayerQuitListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
NickoBukkit.getInstance().getNicko().getDataStore().saveData(player);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package net.artelnatif.nicko.bukkit.gui;
|
||||
|
||||
import de.studiocode.invui.gui.GUI;
|
||||
import de.studiocode.invui.gui.builder.GUIBuilder;
|
||||
import de.studiocode.invui.gui.builder.guitype.GUIType;
|
||||
import de.studiocode.invui.window.impl.single.SimpleWindow;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.common.GoBack;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.admin.ManageCache;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class AdminGUI {
|
||||
private final Player player;
|
||||
private final GUI gui;
|
||||
|
||||
public AdminGUI(Player player) {
|
||||
this.gui = new GUIBuilder<>(GUIType.NORMAL)
|
||||
.setStructure(
|
||||
"# # # # # # # # #",
|
||||
"# % % X X S % % #",
|
||||
"B # # # # # # # #"
|
||||
)
|
||||
.addIngredient('S', new ManageCache())
|
||||
.addIngredient('B', new GoBack(new MainGUI(player).getGUI()))
|
||||
.build();
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public GUI getGUI() {
|
||||
return gui;
|
||||
}
|
||||
|
||||
public void open() {
|
||||
new SimpleWindow(player, "Nicko", gui).show();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package net.artelnatif.nicko.bukkit.gui;
|
||||
|
||||
import de.studiocode.invui.gui.GUI;
|
||||
import de.studiocode.invui.gui.builder.GUIBuilder;
|
||||
import de.studiocode.invui.gui.builder.guitype.GUIType;
|
||||
import de.studiocode.invui.window.impl.single.SimpleWindow;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.common.GoBack;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.skin.ChangeSkin;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.skin.ChangeName;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.skin.ChangeNameAndSkin;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class AppearanceManagerGUI {
|
||||
private final Player player;
|
||||
private final GUI gui;
|
||||
|
||||
public AppearanceManagerGUI(Player player) {
|
||||
this.gui = new GUIBuilder<>(GUIType.NORMAL)
|
||||
.setStructure(
|
||||
"# # # # # # # # #",
|
||||
"# % % % % % % % #",
|
||||
"# % # N A S # % #",
|
||||
"# % % % % % % % #",
|
||||
"B # # # # # # # #"
|
||||
)
|
||||
.addIngredient('N', new ChangeName())
|
||||
.addIngredient('A', new ChangeNameAndSkin())
|
||||
.addIngredient('S', new ChangeSkin())
|
||||
.addIngredient('B', new GoBack(new MainGUI(player).getGUI()))
|
||||
.build();
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public void open() {
|
||||
new SimpleWindow(player, "Nicko", gui).show();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package net.artelnatif.nicko.bukkit.gui;
|
||||
|
||||
import de.studiocode.invui.gui.GUI;
|
||||
import de.studiocode.invui.gui.builder.GUIBuilder;
|
||||
import de.studiocode.invui.gui.builder.guitype.GUIType;
|
||||
import de.studiocode.invui.window.impl.single.SimpleWindow;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.main.AdminSubGUI;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.main.AppearanceManagerSubGUI;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.main.ResetAppearance;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.main.SettingsSubGUI;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class MainGUI {
|
||||
private final Player player;
|
||||
private final GUI gui;
|
||||
|
||||
public MainGUI(Player player) {
|
||||
final String[] dynamicStructure = new String[]{
|
||||
"# # # # # # # # #",
|
||||
"# % % % A % % % #",
|
||||
"# % # R S P # % #",
|
||||
"# % % % % % % % #",
|
||||
"E # # # # # # # #"};
|
||||
|
||||
if (!player.hasPermission("nicko.admin") || !player.isOp()) {
|
||||
dynamicStructure[3] = dynamicStructure[3].replace("A", "#");
|
||||
}
|
||||
|
||||
this.gui = new GUIBuilder<>(GUIType.NORMAL)
|
||||
.setStructure(dynamicStructure)
|
||||
.addIngredient('R', new ResetAppearance())
|
||||
.addIngredient('S', new AppearanceManagerSubGUI())
|
||||
.addIngredient('P', new SettingsSubGUI())
|
||||
.addIngredient('A', new AdminSubGUI())
|
||||
.build();
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public GUI getGUI() {
|
||||
return gui;
|
||||
}
|
||||
|
||||
public void open() {
|
||||
new SimpleWindow(player, "Nicko", gui).show();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package net.artelnatif.nicko.bukkit.gui;
|
||||
|
||||
import de.studiocode.invui.gui.GUI;
|
||||
import de.studiocode.invui.gui.builder.GUIBuilder;
|
||||
import de.studiocode.invui.gui.builder.guitype.GUIType;
|
||||
import de.studiocode.invui.window.impl.single.SimpleWindow;
|
||||
import net.artelnatif.nicko.Nicko;
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.settings.LanguageCycling;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.common.GoBack;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.settings.BungeeCordCycling;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.settings.OptionUnavailable;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class SettingsGUI {
|
||||
private final Player player;
|
||||
private final GUI gui;
|
||||
|
||||
public SettingsGUI(Player player) {
|
||||
final String[] dynamicStructure = new String[]{
|
||||
"# # # # # # # # #",
|
||||
"# % % L U T % % #",
|
||||
"B # # # # # # # #"
|
||||
};
|
||||
|
||||
final Nicko nicko = NickoBukkit.getInstance().getNicko();
|
||||
if (!nicko.getConfig().bungeecord() && nicko.isBungeecord()) {
|
||||
dynamicStructure[1] = dynamicStructure[1].replace("T", "U");
|
||||
}
|
||||
|
||||
this.gui = new GUIBuilder<>(GUIType.NORMAL)
|
||||
.setStructure(dynamicStructure)
|
||||
.addIngredient('B', new GoBack(new MainGUI(player).getGUI()))
|
||||
.addIngredient('L', new LanguageCycling().get(player))
|
||||
.addIngredient('T', new BungeeCordCycling().get(player))
|
||||
.addIngredient('U', new OptionUnavailable())
|
||||
.build();
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public void open() {
|
||||
new SimpleWindow(player, "Nicko", gui).show();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.admin;
|
||||
|
||||
import de.studiocode.invui.gui.GUI;
|
||||
import de.studiocode.invui.gui.builder.GUIBuilder;
|
||||
import de.studiocode.invui.gui.builder.guitype.GUIType;
|
||||
import de.studiocode.invui.window.impl.single.SimpleWindow;
|
||||
import net.artelnatif.nicko.bukkit.gui.AdminGUI;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.admin.cache.CacheDetailed;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.admin.cache.CacheInvalidate;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.admin.cache.CacheOverview;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.common.GoBack;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class CacheManagementGUI {
|
||||
private final Player player;
|
||||
private final GUI gui;
|
||||
|
||||
public CacheManagementGUI(Player player) {
|
||||
this.gui = new GUIBuilder<>(GUIType.NORMAL)
|
||||
.setStructure("B # S A D")
|
||||
.addIngredient('B', new GoBack(new AdminGUI(player).getGUI()))
|
||||
.addIngredient('S', new CacheOverview())
|
||||
.addIngredient('A', new CacheInvalidate())
|
||||
.addIngredient('D', new CacheDetailed())
|
||||
.build();
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public GUI getGUI() {
|
||||
return gui;
|
||||
}
|
||||
|
||||
public void open() {
|
||||
new SimpleWindow(player, "Nicko", gui).show();
|
||||
}
|
||||
}
|
64
core/src/main/java/net/artelnatif/nicko/bukkit/gui/admin/cache/CacheDetailledGUI.java
vendored
Normal file
64
core/src/main/java/net/artelnatif/nicko/bukkit/gui/admin/cache/CacheDetailledGUI.java
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.admin.cache;
|
||||
|
||||
import de.studiocode.invui.gui.GUI;
|
||||
import de.studiocode.invui.gui.builder.GUIBuilder;
|
||||
import de.studiocode.invui.gui.builder.guitype.GUIType;
|
||||
import de.studiocode.invui.gui.structure.Markers;
|
||||
import de.studiocode.invui.item.Item;
|
||||
import de.studiocode.invui.window.impl.single.SimpleWindow;
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.admin.cache.SkinPlaceholder;
|
||||
import net.artelnatif.nicko.bukkit.gui.admin.CacheManagementGUI;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.common.GoBack;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.common.ScrollDown;
|
||||
import net.artelnatif.nicko.bukkit.gui.items.common.ScrollUp;
|
||||
import net.artelnatif.nicko.mojang.MojangSkin;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CacheDetailledGUI {
|
||||
private final Player player;
|
||||
private final GUI gui;
|
||||
|
||||
public CacheDetailledGUI(Player player) {
|
||||
final ConcurrentMap<String, Optional<MojangSkin>> skins = NickoBukkit.getInstance().getNicko().getMojangAPI().getCache().asMap();
|
||||
final List<String> loadedSkins = skins.entrySet().stream()
|
||||
.filter(entry -> entry.getValue().isPresent())
|
||||
.map(Map.Entry::getKey)
|
||||
.toList();
|
||||
|
||||
final List<Item> items = loadedSkins.stream()
|
||||
.map(SkinPlaceholder::new)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
this.gui = new GUIBuilder<>(GUIType.SCROLL_ITEMS)
|
||||
.setStructure(
|
||||
"% # # # # # # # %",
|
||||
"# x x x x x x U #",
|
||||
"# x x x x x x # #",
|
||||
"# x x x x x x # #",
|
||||
"# x x x x x x D #",
|
||||
"B # # # # # # # %"
|
||||
)
|
||||
.addIngredient('x', Markers.ITEM_LIST_SLOT_HORIZONTAL)
|
||||
.addIngredient('U', new ScrollUp())
|
||||
.addIngredient('D', new ScrollDown())
|
||||
.addIngredient('B', new GoBack(new CacheManagementGUI(player).getGUI()))
|
||||
.setItems(items)
|
||||
.build();
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public GUI getGUI() {
|
||||
return gui;
|
||||
}
|
||||
|
||||
public void open() {
|
||||
new SimpleWindow(player, "Nicko", gui).show();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.admin;
|
||||
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.builder.SkullBuilder;
|
||||
import de.studiocode.invui.item.impl.AsyncItem;
|
||||
import net.artelnatif.nicko.bukkit.gui.admin.CacheManagementGUI;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ManageCache extends AsyncItem {
|
||||
public ManageCache() {
|
||||
super(new ItemBuilder(Material.PAINTING)
|
||||
.setDisplayName("§fManage §6skin §fcache...")
|
||||
.addLoreLines("§7Access the skin cache management panel."),
|
||||
() -> {
|
||||
final SkullBuilder builder = new SkullBuilder("Notch");
|
||||
builder.setDisplayName("§fManage §6skin §fcache...");
|
||||
builder.addLoreLines("§7Access the skin cache management panel.");
|
||||
return builder;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
||||
event.getView().close();
|
||||
new CacheManagementGUI(player).open();
|
||||
}
|
||||
}
|
||||
}
|
29
core/src/main/java/net/artelnatif/nicko/bukkit/gui/items/admin/cache/CacheDetailed.java
vendored
Normal file
29
core/src/main/java/net/artelnatif/nicko/bukkit/gui/items/admin/cache/CacheDetailed.java
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.admin.cache;
|
||||
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import net.artelnatif.nicko.bukkit.gui.admin.cache.CacheDetailledGUI;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CacheDetailed extends BaseItem {
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
final ItemBuilder builder = new ItemBuilder(Material.PAPER);
|
||||
builder.setDisplayName("§6Invalidate specific skin...");
|
||||
builder.addLoreLines("§7Select a specific skin to invalidate.");
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
||||
event.getView().close();
|
||||
new CacheDetailledGUI(player).open();
|
||||
}
|
||||
}
|
||||
}
|
37
core/src/main/java/net/artelnatif/nicko/bukkit/gui/items/admin/cache/CacheInvalidate.java
vendored
Normal file
37
core/src/main/java/net/artelnatif/nicko/bukkit/gui/items/admin/cache/CacheInvalidate.java
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.admin.cache;
|
||||
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.bukkit.i18n.I18N;
|
||||
import net.artelnatif.nicko.bukkit.i18n.I18NDict;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CacheInvalidate extends BaseItem {
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
final ItemBuilder builder = new ItemBuilder(Material.TNT);
|
||||
builder.setDisplayName("§fInvalidate §6skin cache");
|
||||
builder.addLoreLines(
|
||||
"§c§oNOT RECOMMENDED",
|
||||
"§7Invalidates every skin entry present in the cache.",
|
||||
"§7Does not reset player disguises.",
|
||||
"§7Could be useful if a skin has been updated",
|
||||
"§7recently and the cache is now outdated.");
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
||||
event.getView().close();
|
||||
player.sendMessage(I18N.translate(player, I18NDict.Event.Admin.CACHE_CLEAN));
|
||||
NickoBukkit.getInstance().getNicko().getMojangAPI().getCache().invalidateAll();
|
||||
}
|
||||
}
|
||||
}
|
39
core/src/main/java/net/artelnatif/nicko/bukkit/gui/items/admin/cache/CacheOverview.java
vendored
Normal file
39
core/src/main/java/net/artelnatif/nicko/bukkit/gui/items/admin/cache/CacheOverview.java
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.admin.cache;
|
||||
|
||||
import com.google.common.cache.CacheStats;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.mojang.MojangSkin;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class CacheOverview extends BaseItem {
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
final ItemBuilder builder = new ItemBuilder(Material.OAK_SIGN);
|
||||
final LoadingCache<String, Optional<MojangSkin>> cache = NickoBukkit.getInstance().getNicko().getMojangAPI().getCache();
|
||||
final CacheStats stats = cache.stats();
|
||||
builder.setDisplayName("§6Skin cache §foverview:");
|
||||
builder.addLoreLines(
|
||||
"Request Count: §2" + stats.requestCount(),
|
||||
"Skin Cached: §2" + Math.round(cache.size()),
|
||||
"§7§oCache is cleared every 24 hours.",
|
||||
"§7§o(Click to refresh)");
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
||||
notifyWindows();
|
||||
}
|
||||
}
|
||||
}
|
21
core/src/main/java/net/artelnatif/nicko/bukkit/gui/items/admin/cache/SkinPlaceholder.java
vendored
Normal file
21
core/src/main/java/net/artelnatif/nicko/bukkit/gui/items/admin/cache/SkinPlaceholder.java
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.admin.cache;
|
||||
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.builder.SkullBuilder;
|
||||
import de.studiocode.invui.item.impl.AsyncItem;
|
||||
import org.bukkit.Material;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class SkinPlaceholder extends AsyncItem {
|
||||
public SkinPlaceholder(String name) {
|
||||
super(new ItemBuilder(Material.PAINTING).setDisplayName("§7§oLoading..."), () -> {
|
||||
final String stringUUID = name.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5");
|
||||
final UUID uuid = UUID.fromString(stringUUID);
|
||||
final SkullBuilder skull = new SkullBuilder(uuid);
|
||||
skull.setDisplayName("§6Skin Entry");
|
||||
skull.addLoreLines("§7Click to invalidate skin");
|
||||
return skull;
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.common;
|
||||
|
||||
import de.studiocode.invui.gui.GUI;
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import de.studiocode.invui.window.impl.single.SimpleWindow;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class GoBack extends BaseItem {
|
||||
private final GUI gui;
|
||||
|
||||
public GoBack(GUI gui) {
|
||||
this.gui = gui;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
final ItemBuilder builder = new ItemBuilder(Material.ARROW);
|
||||
builder.setDisplayName("Go back");
|
||||
builder.addLoreLines("§7Return to the previous window.");
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
event.getView().close();
|
||||
new SimpleWindow(player, "Nicko", gui).show();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.common;
|
||||
|
||||
import de.studiocode.invui.gui.impl.ScrollGUI;
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.controlitem.ScrollItem;
|
||||
import org.bukkit.Material;
|
||||
|
||||
public class ScrollDown extends ScrollItem {
|
||||
|
||||
public ScrollDown() {
|
||||
super(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemProvider getItemProvider(ScrollGUI gui) {
|
||||
ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE);
|
||||
builder.setDisplayName("§7Scroll down");
|
||||
if (!gui.canScroll(1))
|
||||
builder.addLoreLines("§cYou can't scroll further down");
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.common;
|
||||
|
||||
import de.studiocode.invui.gui.impl.ScrollGUI;
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.controlitem.ScrollItem;
|
||||
import org.bukkit.Material;
|
||||
|
||||
public class ScrollUp extends ScrollItem {
|
||||
|
||||
public ScrollUp() {
|
||||
super(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemProvider getItemProvider(ScrollGUI gui) {
|
||||
ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE);
|
||||
builder.setDisplayName("§7Scroll up");
|
||||
if (!gui.canScroll(-1))
|
||||
builder.addLoreLines("§cYou've reached the top");
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.main;
|
||||
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import net.artelnatif.nicko.bukkit.gui.AdminGUI;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemFlag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class AdminSubGUI extends BaseItem {
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
final ItemBuilder builder = new ItemBuilder(Material.COMMAND_BLOCK);
|
||||
builder.addEnchantment(Enchantment.DAMAGE_ALL, 1, false);
|
||||
builder.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
||||
builder.setDisplayName("§cAdministration panel...");
|
||||
builder.addLoreLines("§7Access the administration panel.");
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
||||
event.getView().close();
|
||||
new AdminGUI(player).open();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.main;
|
||||
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import net.artelnatif.nicko.bukkit.gui.AppearanceManagerGUI;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class AppearanceManagerSubGUI extends BaseItem {
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
final ItemBuilder builder = new ItemBuilder(Material.ENDER_EYE);
|
||||
builder.setDisplayName("§fManage §6appearance§f...");
|
||||
builder.addLoreLines("§7Access the appearance manager.");
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
||||
event.getView().close();
|
||||
new AppearanceManagerGUI(player).open();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.main;
|
||||
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ExitGUI extends BaseItem {
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
return new ItemBuilder(Material.OAK_DOOR).setDisplayName("§fExit");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
||||
event.getView().close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.main;
|
||||
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import net.artelnatif.nicko.bukkit.appearance.AppearanceManager;
|
||||
import net.artelnatif.nicko.bukkit.i18n.I18N;
|
||||
import net.artelnatif.nicko.bukkit.i18n.I18NDict;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ResetAppearance extends BaseItem {
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
final ItemBuilder builder = new ItemBuilder(Material.TNT);
|
||||
builder.setDisplayName("§fReset");
|
||||
builder.addLoreLines("§7Get rid of your disguise.");
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
||||
final AppearanceManager appearanceManager = AppearanceManager.get(player);
|
||||
|
||||
if (!appearanceManager.hasData()) {
|
||||
player.sendMessage(I18N.translate(player, I18NDict.Event.Undisguise.NONE));
|
||||
event.getView().close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!appearanceManager.reset().isError()) {
|
||||
player.sendMessage(I18N.translate(player, I18NDict.Event.Undisguise.SUCCESS));
|
||||
} else {
|
||||
player.sendMessage(I18N.translate(player, I18NDict.Event.Undisguise.FAIL));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.main;
|
||||
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import net.artelnatif.nicko.bukkit.gui.SettingsGUI;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SettingsSubGUI extends BaseItem {
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
final ItemBuilder builder = new ItemBuilder(Material.COMPARATOR);
|
||||
builder.setDisplayName("§fSettings...");
|
||||
builder.addLoreLines("§7Adjust your preferences.");
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
||||
event.getView().close();
|
||||
new SettingsGUI(player).open();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.settings;
|
||||
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import de.studiocode.invui.item.impl.CycleItem;
|
||||
import de.studiocode.invui.item.impl.SimpleItem;
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class BungeeCordCycling {
|
||||
private final ItemProvider[] providers = new ItemProvider[]{
|
||||
getItemProviderForValue(true),
|
||||
getItemProviderForValue(false)
|
||||
};
|
||||
|
||||
public BaseItem get(Player player) {
|
||||
Optional<NickoProfile> profile = NickoBukkit.getInstance().getNicko().getDataStore().getData(player.getUniqueId());
|
||||
if (profile.isPresent()) {
|
||||
final NickoProfile nickoProfile = profile.get();
|
||||
int startingState = nickoProfile.isBungeecordTransfer() ? 0 : 1;
|
||||
return CycleItem.withStateChangeHandler((observer, integer) -> {
|
||||
nickoProfile.setBungeecordTransfer(integer != 1);
|
||||
observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C
|
||||
}, startingState, providers);
|
||||
}
|
||||
|
||||
return new SimpleItem(ItemProvider.EMPTY);
|
||||
}
|
||||
|
||||
private ItemProvider getItemProviderForValue(boolean enabled) {
|
||||
final ItemBuilder builder = new ItemBuilder(Material.COMPASS);
|
||||
builder.setDisplayName("§6BungeeCord transfer:");
|
||||
if (enabled) {
|
||||
builder.addLoreLines("§7> §cDisabled");
|
||||
builder.addLoreLines("§6§l> §a§lEnabled");
|
||||
} else {
|
||||
builder.addLoreLines("§6§l> §c§lDisabled");
|
||||
builder.addLoreLines("§7> §aEnabled");
|
||||
}
|
||||
builder.addLoreLines("§7§oCycle through the values by", "§7§oleft and right clicking.");
|
||||
return builder;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.settings;
|
||||
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import de.studiocode.invui.item.impl.CycleItem;
|
||||
import de.studiocode.invui.item.impl.SimpleItem;
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||
import net.artelnatif.nicko.bukkit.i18n.Locale;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class LanguageCycling {
|
||||
private final ItemProvider[] providers = getItems();
|
||||
|
||||
public BaseItem get(Player player) {
|
||||
final NickoBukkit instance = NickoBukkit.getInstance();
|
||||
Optional<NickoProfile> profile = instance.getNicko().getDataStore().getData(player.getUniqueId());
|
||||
if (profile.isPresent()) {
|
||||
final NickoProfile nickoProfile = profile.get();
|
||||
int localeOrdinal = nickoProfile.getLocale().ordinal();
|
||||
return CycleItem.withStateChangeHandler((observer, integer) -> {
|
||||
nickoProfile.setLocale(Locale.values()[integer]);
|
||||
observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C
|
||||
}, localeOrdinal, providers);
|
||||
}
|
||||
|
||||
return new SimpleItem(ItemProvider.EMPTY);
|
||||
}
|
||||
|
||||
private ItemProvider generateItem(Locale locale, List<Locale> locales) {
|
||||
final ItemBuilder builder = new ItemBuilder(Material.OAK_SIGN);
|
||||
builder.setDisplayName("§6Select your language:");
|
||||
for (Locale value : locales) {
|
||||
if (locale != value) {
|
||||
builder.addLoreLines("§7> " + value.getName());
|
||||
} else {
|
||||
builder.addLoreLines("§6§l> §f" + value.getName());
|
||||
}
|
||||
}
|
||||
builder.addLoreLines("§7§oCycle through the values by", "§7§oleft and right clicking.");
|
||||
return builder;
|
||||
}
|
||||
|
||||
private ItemProvider[] getItems() {
|
||||
final NickoBukkit instance = NickoBukkit.getInstance();
|
||||
final ArrayList<ItemProvider> items = new ArrayList<>();
|
||||
|
||||
final ArrayList<Locale> localesToGenerate = new ArrayList<>();
|
||||
Collections.addAll(localesToGenerate, Locale.values());
|
||||
if (!instance.getNicko().getConfig().customLocale()) {
|
||||
localesToGenerate.remove(Locale.CUSTOM);
|
||||
}
|
||||
localesToGenerate.forEach(locale -> items.add(generateItem(locale, localesToGenerate)));
|
||||
return items.toArray(new ItemProvider[]{});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.settings;
|
||||
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class OptionUnavailable extends BaseItem {
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
final ItemBuilder builder = new ItemBuilder(Material.RED_TERRACOTTA);
|
||||
builder.setDisplayName("§cOption unavailable :(");
|
||||
builder.addLoreLines("§7This option is disabled due to the",
|
||||
"§7feature it controls being disabled.");
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent inventoryClickEvent) { }
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.skin;
|
||||
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import net.artelnatif.nicko.bukkit.anvil.AnvilManager;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ChangeName extends BaseItem {
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
final ItemBuilder builder = new ItemBuilder(Material.NAME_TAG);
|
||||
builder.setDisplayName("§6Name §fchange");
|
||||
builder.addLoreLines("§7Only change your name.");
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
||||
event.getView().close();
|
||||
final AnvilManager manager = new AnvilManager(player);
|
||||
manager.openNameAnvil();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.skin;
|
||||
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import net.artelnatif.nicko.bukkit.anvil.AnvilManager;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ChangeNameAndSkin extends BaseItem {
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
final ItemBuilder builder = new ItemBuilder(Material.ENDER_PEARL);
|
||||
builder.setDisplayName("§6Skin §fand §6name §fchange");
|
||||
builder.addLoreLines("§7Change both your skin and name.");
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
if (clickType.isLeftClick() || clickType.isRightClick()) {
|
||||
event.getView().close();
|
||||
final AnvilManager manager = new AnvilManager(player);
|
||||
manager.openNameThenSkinAnvil();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package net.artelnatif.nicko.bukkit.gui.items.skin;
|
||||
|
||||
import de.studiocode.invui.item.ItemProvider;
|
||||
import de.studiocode.invui.item.builder.ItemBuilder;
|
||||
import de.studiocode.invui.item.impl.BaseItem;
|
||||
import net.artelnatif.nicko.bukkit.anvil.AnvilManager;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ChangeSkin extends BaseItem {
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
final ItemBuilder builder = new ItemBuilder(Material.PAINTING);
|
||||
builder.setDisplayName("§6Skin §fchange");
|
||||
builder.addLoreLines("§7Only change your skin.");
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
if(clickType.isLeftClick() || clickType.isRightClick()) {
|
||||
event.getView().close();
|
||||
final AnvilManager manager = new AnvilManager(player);
|
||||
manager.openSkinAnvil();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package net.artelnatif.nicko.bukkit.i18n;
|
||||
|
||||
import com.github.jsixface.YamlConfig;
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Optional;
|
||||
|
||||
public class I18N {
|
||||
private final static MessageFormat formatter = new MessageFormat("");
|
||||
|
||||
private static Locale getLocale(Player player) {
|
||||
final NickoBukkit instance = NickoBukkit.getInstance();
|
||||
try {
|
||||
final Optional<NickoProfile> profile = instance.getNicko().getDataStore().getData(player.getUniqueId());
|
||||
return profile.isEmpty() ? Locale.FALLBACK_LOCALE : profile.get().getLocale();
|
||||
} catch (IllegalArgumentException exception) {
|
||||
instance.getLogger().severe("Invalid locale provided by " + player.getName() + ", defaulting to " + Locale.FALLBACK_LOCALE.getCode() + ".");
|
||||
return Locale.FALLBACK_LOCALE;
|
||||
}
|
||||
}
|
||||
|
||||
public static String translate(Player player, I18NDict key, Object... arguments) {
|
||||
final NickoBukkit instance = NickoBukkit.getInstance();
|
||||
final String translation = findTranslation(player, key);
|
||||
|
||||
try {
|
||||
formatter.applyPattern(translation);
|
||||
return instance.getNicko().getConfig().prefix() + formatter.format(arguments);
|
||||
} catch (Exception e) {
|
||||
return instance.getNicko().getConfig().prefix() + key.key();
|
||||
}
|
||||
}
|
||||
|
||||
public static String translateWithoutPrefix(Player player, I18NDict key, Object... arguments) {
|
||||
final String translation = findTranslation(player, key);
|
||||
try {
|
||||
formatter.applyPattern(translation);
|
||||
return formatter.format(arguments);
|
||||
} catch (Exception e) {
|
||||
return key.key();
|
||||
}
|
||||
}
|
||||
|
||||
private static String findTranslation(Player player, I18NDict key) {
|
||||
final NickoBukkit instance = NickoBukkit.getInstance();
|
||||
final Locale locale = getLocale(player);
|
||||
String translation;
|
||||
if (locale == Locale.CUSTOM) {
|
||||
translation = instance.getLocaleFileManager().get(key.key());
|
||||
} else {
|
||||
final InputStream resource = instance.getResource(locale.getCode() + ".yml");
|
||||
final YamlConfig yamlConfig = YamlConfig.load(resource);
|
||||
translation = yamlConfig.getString(key.key());
|
||||
}
|
||||
|
||||
return translation;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package net.artelnatif.nicko.bukkit.i18n;
|
||||
|
||||
public record I18NDict(String key) {
|
||||
public static class Event {
|
||||
public static class Admin {
|
||||
public static final I18NDict CACHE_CLEAN = new I18NDict("event.admin.cache_clear");
|
||||
}
|
||||
|
||||
public static class Disguise {
|
||||
public static final I18NDict SUCCESS = new I18NDict("event.disguise.success");
|
||||
public static final I18NDict FAIL = new I18NDict("event.disguise.fail");
|
||||
}
|
||||
|
||||
public static class Undisguise {
|
||||
public static final I18NDict SUCCESS = new I18NDict("event.undisguise.success");
|
||||
public static final I18NDict FAIL = new I18NDict("event.undisguise.fail");
|
||||
public static final I18NDict NONE = new I18NDict("event.undisguise.none");
|
||||
}
|
||||
|
||||
public static class PreviousSkin {
|
||||
public static final I18NDict SUCCESS = new I18NDict("event.previous_skin_applied.success");
|
||||
public static final I18NDict FAIL = new I18NDict("event.previous_skin_applied.fail");
|
||||
}
|
||||
}
|
||||
|
||||
public static class Error {
|
||||
public static final I18NDict PLAYER_OFFLINE = new I18NDict("error.player_offline");
|
||||
public static final I18NDict SKIN_FAIL_MOJANG = new I18NDict("error.couldnt_get_skin_from_mojang");
|
||||
public static final I18NDict SKIN_FAIL_CACHE = new I18NDict("error.couldnt_get_skin_from_cache");
|
||||
public static final I18NDict NAME_FAIL_MOJANG = new I18NDict("error.couldnt_get_name_from_mojang");
|
||||
public static final I18NDict INVALID_USERNAME = new I18NDict("error.invalid_username");
|
||||
public static final I18NDict UNEXPECTED_ERROR = new I18NDict("error.generic");
|
||||
public static final I18NDict SQL_ERROR = new I18NDict("error.sql");
|
||||
public static final I18NDict JSON_ERROR = new I18NDict("error.json");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package net.artelnatif.nicko.bukkit.i18n;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public enum Locale implements Serializable {
|
||||
ENGLISH("en", "English"),
|
||||
FRENCH("fr", "Français"),
|
||||
CUSTOM("custom", "Server Custom");
|
||||
|
||||
public static final Locale FALLBACK_LOCALE = ENGLISH;
|
||||
|
||||
private final String code;
|
||||
private transient final String name;
|
||||
|
||||
Locale(String code, String name) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package net.artelnatif.nicko.bukkit.i18n;
|
||||
|
||||
import com.github.jsixface.YamlConfig;
|
||||
import de.studiocode.invui.util.IOUtils;
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class LocaleFileManager {
|
||||
private final File folder = new File(NickoBukkit.getInstance().getDataFolder() + "/lang/");
|
||||
private final File file = new File(folder, "lang.yml");
|
||||
|
||||
public String get(String key) {
|
||||
if (!file.exists()) return key;
|
||||
try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file))) {
|
||||
final YamlConfig yamlConfig = YamlConfig.load(inputStream);
|
||||
return yamlConfig.getString(key);
|
||||
} catch (IOException e) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean dumpFromLocale(Locale locale) {
|
||||
if (locale == Locale.CUSTOM) return true;
|
||||
if (file.exists()) return true;
|
||||
final InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(locale.getCode() + ".yml");
|
||||
try {
|
||||
if (folder.mkdirs()) {
|
||||
if (file.createNewFile()) {
|
||||
try (FileOutputStream outputStream = new FileOutputStream(file)) {
|
||||
IOUtils.copy(inputStream, outputStream, 8192);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package net.artelnatif.nicko.bukkit.placeholder;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class NickoExpansion extends PlaceholderExpansion {
|
||||
|
||||
private final NickoBukkit instance;
|
||||
|
||||
public NickoExpansion(NickoBukkit instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getIdentifier() {
|
||||
return "nicko";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getAuthor() {
|
||||
return "Aro";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getVersion() {
|
||||
return "1.0.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean persist() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String onPlaceholderRequest(Player player, @NotNull String params) {
|
||||
if (player == null) return null;
|
||||
|
||||
String name, skin, locale;
|
||||
boolean bungeecord;
|
||||
|
||||
name = skin = player.getName();
|
||||
locale = "N/A";
|
||||
bungeecord = true;
|
||||
|
||||
final Optional<NickoProfile> optionalProfile = instance.getNicko().getDataStore().getData(player.getUniqueId());
|
||||
if (optionalProfile.isPresent()) {
|
||||
final NickoProfile profile = optionalProfile.get();
|
||||
if (!profile.isEmpty()) {
|
||||
name = profile.getName();
|
||||
skin = profile.getSkin();
|
||||
}
|
||||
locale = profile.getLocale().getName();
|
||||
bungeecord = profile.isBungeecordTransfer();
|
||||
}
|
||||
|
||||
return switch (params) {
|
||||
case "name" -> name;
|
||||
case "skin" -> skin;
|
||||
case "locale" -> locale;
|
||||
case "bungeecord" -> String.valueOf(bungeecord);
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package net.artelnatif.nicko.bukkit.placeholder;
|
||||
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class PlaceHolderHook {
|
||||
private final NickoBukkit instance;
|
||||
|
||||
public PlaceHolderHook(NickoBukkit instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public void hook() {
|
||||
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
||||
instance.getLogger().info("Enabling PlaceHolderAPI support...");
|
||||
new NickoExpansion(instance).register();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package net.artelnatif.nicko.bukkit.pluginchannel;
|
||||
|
||||
import com.google.common.io.ByteArrayDataInput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.bungee.NickoBungee;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PluginMessageHandler implements PluginMessageListener {
|
||||
@Override
|
||||
public void onPluginMessageReceived(String channel, Player player, byte[] message) {
|
||||
if (!channel.equals(NickoBungee.SERVER_DATA)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ByteArrayDataInput in = ByteStreams.newDataInput(message);
|
||||
final int payloadSize = in.readInt();
|
||||
if (payloadSize == 0 || payloadSize > 4) {
|
||||
NickoBukkit.getInstance().getLogger().severe("Prevented error by skipping malformed payload of size " + payloadSize + "!");
|
||||
NickoBukkit.getInstance().getLogger().severe("This should not have happened, open an issue at https://atnrch.xyz/git/aro/Nicko !");
|
||||
return;
|
||||
}
|
||||
|
||||
final ArrayList<String> decodedPayload = new ArrayList<>(payloadSize);
|
||||
for (int i = 0; i < payloadSize; i++) {
|
||||
decodedPayload.add(in.readUTF());
|
||||
}
|
||||
|
||||
System.out.println("decodedPayload = " + decodedPayload);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package net.artelnatif.nicko.bungee;
|
||||
|
||||
import net.artelnatif.nicko.Nicko;
|
||||
import net.artelnatif.nicko.bungee.event.UpdateMessageListener;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
|
||||
public class NickoBungee extends Plugin {
|
||||
public static final String NICKO_PLUGIN_CHANNEL_BASE = "nicko:";
|
||||
public static final String PROXY_UPDATE = NICKO_PLUGIN_CHANNEL_BASE + "update";
|
||||
public static final String PROXY_FETCH = NICKO_PLUGIN_CHANNEL_BASE + "fetch";
|
||||
public static final String SERVER_DATA = NICKO_PLUGIN_CHANNEL_BASE + "data";
|
||||
|
||||
private final Nicko nicko = new Nicko();
|
||||
|
||||
private static NickoBungee plugin;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
plugin = this;
|
||||
nicko.initBungeecord(this);
|
||||
|
||||
getLogger().info("Loading persistence...");
|
||||
if (!nicko.getDataStore().getStorage().isError()) {
|
||||
if (!nicko.getDataStore().getStorage().getProvider().init()) {
|
||||
getLogger().severe("Failed to load persistence!");
|
||||
getLogger().severe("Nicko can't enable BungeeCord support without SQL storage.");
|
||||
getLogger().severe("The plugin will not continue.");
|
||||
nicko.getDataStore().getStorage().setError(true);
|
||||
nicko.setBungeecord(false);
|
||||
onDisable();
|
||||
return;
|
||||
}
|
||||
|
||||
getLogger().info("Registering channel...");
|
||||
getProxy().registerChannel(SERVER_DATA);
|
||||
|
||||
getLogger().info("Registering listener...");
|
||||
getProxy().getPluginManager().registerListener(this, new UpdateMessageListener());
|
||||
|
||||
getLogger().info("Nicko (Bungee) has been enabled.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
if (!nicko.getDataStore().getStorage().isError()) {
|
||||
getLogger().info("Unregistering channels...");
|
||||
getProxy().unregisterChannel(PROXY_UPDATE);
|
||||
|
||||
getLogger().info("Nicko (Bungee) has been disabled.");
|
||||
}
|
||||
}
|
||||
|
||||
public static NickoBungee getInstance() {
|
||||
return plugin;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package net.artelnatif.nicko.bungee.event;
|
||||
|
||||
import net.artelnatif.nicko.bungee.NickoBungee;
|
||||
import net.artelnatif.nicko.bungee.message.PluginMessageSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
public class FetchMessageListener implements Listener {
|
||||
@EventHandler
|
||||
public void onMessage(PluginMessageEvent event) {
|
||||
if (!event.getTag().equals(NickoBungee.PROXY_FETCH)) { return; }
|
||||
|
||||
try (DataInputStream input = new DataInputStream(new ByteArrayInputStream(event.getData()))) {
|
||||
final ProxyServer proxy = NickoBungee.getInstance().getProxy();
|
||||
|
||||
final String uuid = input.readUTF();
|
||||
final ProxiedPlayer player = proxy.getPlayer(UUID.fromString(uuid));
|
||||
final ServerInfo serverInfo = player.getServer().getInfo();
|
||||
|
||||
// TODO: 1/28/23 FETCH PROFILE
|
||||
final ArrayList<String> payload = new ArrayList<>();
|
||||
payload.add(player.getUniqueId().toString());
|
||||
|
||||
PluginMessageSender.send(serverInfo, NickoBungee.SERVER_DATA, payload);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package net.artelnatif.nicko.bungee.event;
|
||||
|
||||
import net.artelnatif.nicko.bungee.NickoBungee;
|
||||
import net.artelnatif.nicko.bungee.message.MessageDecoder;
|
||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class UpdateMessageListener implements Listener {
|
||||
@EventHandler
|
||||
public void onMessage(PluginMessageEvent event) {
|
||||
if (!event.getTag().equals(NickoBungee.PROXY_UPDATE)) { return; }
|
||||
|
||||
try (DataInputStream input = new DataInputStream(new ByteArrayInputStream(event.getData()))) {
|
||||
final NickoProfile profile = MessageDecoder.decode(input);
|
||||
|
||||
// TODO: 1/28/23 STORE PROFILE
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package net.artelnatif.nicko.bungee.message;
|
||||
|
||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||
import net.artelnatif.nicko.bukkit.i18n.Locale;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class MessageDecoder {
|
||||
public static final int STRING_SIZE = 3;
|
||||
|
||||
public static NickoProfile decode(DataInputStream input) throws IOException {
|
||||
final String[] stringValues = new String[3];
|
||||
for (int i = 1; i < STRING_SIZE; i++) { stringValues[i] = input.readUTF(); }
|
||||
return new NickoProfile(stringValues[0], stringValues[1], Locale.valueOf(stringValues[2]), true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package net.artelnatif.nicko.bungee.message;
|
||||
|
||||
import com.google.common.io.ByteArrayDataOutput;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PluginMessageSender {
|
||||
public static void send(final ServerInfo info, final String channel, final ArrayList<String> payload) {
|
||||
if (info == null) { return; }
|
||||
|
||||
final ByteArrayDataOutput output = ByteStreams.newDataOutput();
|
||||
output.writeInt(payload.size());
|
||||
for (String elt : payload) {
|
||||
output.writeUTF(elt);
|
||||
}
|
||||
info.sendData(channel, output.toByteArray(), true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package net.artelnatif.nicko.config;
|
||||
|
||||
public record Configuration(
|
||||
String address,
|
||||
String username,
|
||||
String password,
|
||||
String prefix,
|
||||
Boolean local,
|
||||
Boolean bungeecord,
|
||||
Boolean customLocale) {
|
||||
public Configuration() {
|
||||
this("", "", "", "", false, false, false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package net.artelnatif.nicko.config;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
import net.artelnatif.nicko.Nicko;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
|
||||
public class ConfigurationManager {
|
||||
private final Nicko nicko;
|
||||
private final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
|
||||
private final File directory;
|
||||
private final File file;
|
||||
|
||||
public ConfigurationManager(Nicko nicko) {
|
||||
this.nicko = nicko;
|
||||
this.directory = nicko.getDataFolder();
|
||||
this.file = new File(directory, "config.yml");
|
||||
}
|
||||
|
||||
public void save(Configuration configuration) throws IOException {
|
||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
|
||||
mapper.writeValue(writer, configuration);
|
||||
writer.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void saveDefaultConfig() {
|
||||
if (!file.exists()) {
|
||||
try {
|
||||
final InputStream input = getClass().getResourceAsStream("/config.yml");
|
||||
if (input != null) {
|
||||
nicko.getLogger().info("Saved default configuration as config.yml");
|
||||
Files.createDirectories(file.getParentFile().toPath());
|
||||
Files.createFile(file.toPath());
|
||||
Files.copy(input, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Configuration load() throws IOException {
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
||||
return mapper.readValue(reader, Configuration.class);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package net.artelnatif.nicko.disguise;
|
||||
|
||||
import net.artelnatif.nicko.bukkit.i18n.I18NDict;
|
||||
|
||||
public class ActionResult<R> {
|
||||
private final I18NDict errorMessage;
|
||||
private boolean error = false;
|
||||
private R result;
|
||||
|
||||
public ActionResult(I18NDict errorMessage) {
|
||||
this.error = true;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
public ActionResult() {
|
||||
this.errorMessage = null;
|
||||
}
|
||||
|
||||
public void setResult(R result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public R getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public I18NDict getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package net.artelnatif.nicko.disguise;
|
||||
|
||||
import net.artelnatif.nicko.bukkit.i18n.Locale;
|
||||
|
||||
public class NickoProfile implements Cloneable {
|
||||
public static final NickoProfile EMPTY_PROFILE = new NickoProfile(null, null, Locale.ENGLISH, true);
|
||||
|
||||
private String name;
|
||||
private String skin;
|
||||
private Locale locale;
|
||||
private boolean bungeecordTransfer;
|
||||
|
||||
public NickoProfile(String name, String skin, Locale locale, boolean bungeecordTransfer) {
|
||||
this.name = name;
|
||||
this.skin = skin;
|
||||
this.locale = locale;
|
||||
this.bungeecordTransfer = bungeecordTransfer;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return name == null && skin == null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getSkin() {
|
||||
return skin;
|
||||
}
|
||||
|
||||
public void setSkin(String skin) {
|
||||
this.skin = skin;
|
||||
}
|
||||
|
||||
public Locale getLocale() { return locale; }
|
||||
|
||||
public void setLocale(Locale locale) { this.locale = locale; }
|
||||
|
||||
public boolean isBungeecordTransfer() {
|
||||
return bungeecordTransfer;
|
||||
}
|
||||
|
||||
public void setBungeecordTransfer(boolean bungeecordTransfer) {
|
||||
this.bungeecordTransfer = bungeecordTransfer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NickoProfile{" +
|
||||
"name='" + name + '\'' +
|
||||
", skin='" + skin + '\'' +
|
||||
", locale=" + locale +
|
||||
", bungeecordTransfer=" + bungeecordTransfer +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public NickoProfile clone() {
|
||||
Object o;
|
||||
try {
|
||||
o = super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return (NickoProfile) o;
|
||||
}
|
||||
}
|
44
core/src/main/java/net/artelnatif/nicko/impl/Internals.java
Normal file
44
core/src/main/java/net/artelnatif/nicko/impl/Internals.java
Normal file
|
@ -0,0 +1,44 @@
|
|||
package net.artelnatif.nicko.impl;
|
||||
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||
import net.artelnatif.nicko.disguise.ActionResult;
|
||||
import net.artelnatif.nicko.bukkit.i18n.I18NDict;
|
||||
import net.artelnatif.nicko.mojang.MojangAPI;
|
||||
import net.artelnatif.nicko.mojang.MojangSkin;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public interface Internals {
|
||||
void updateSelf(Player player);
|
||||
|
||||
void updateOthers(Player player);
|
||||
|
||||
ActionResult<Void> updateProfile(Player player, NickoProfile profile, boolean skinChange, boolean reset);
|
||||
|
||||
default ActionResult<MojangSkin> fetchSkinTextures(NickoProfile profile, boolean reset) {
|
||||
Optional<MojangSkin> skin;
|
||||
try {
|
||||
final MojangAPI mojang = NickoBukkit.getInstance().getNicko().getMojangAPI();
|
||||
final Optional<String> uuid = mojang.getUUID(profile.getSkin());
|
||||
if (uuid.isPresent()) {
|
||||
skin = (reset ? mojang.getSkinWithoutCaching(uuid.get()) : mojang.getSkin(uuid.get()));
|
||||
if (skin.isEmpty()) {
|
||||
return new ActionResult<>(I18NDict.Error.SKIN_FAIL_MOJANG);
|
||||
}
|
||||
|
||||
final ActionResult<MojangSkin> actionResult = new ActionResult<>();
|
||||
actionResult.setResult(skin.get());
|
||||
return actionResult;
|
||||
}
|
||||
return new ActionResult<>(I18NDict.Error.NAME_FAIL_MOJANG);
|
||||
} catch (ExecutionException e) {
|
||||
return new ActionResult<>(I18NDict.Error.SKIN_FAIL_CACHE);
|
||||
} catch (IOException e) {
|
||||
return new ActionResult<>(I18NDict.Error.NAME_FAIL_MOJANG);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package net.artelnatif.nicko.impl;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
public class InternalsProvider {
|
||||
private static Internals internals;
|
||||
|
||||
static {
|
||||
try {
|
||||
final String packageName = Internals.class.getPackage().getName();
|
||||
final String bukkitVersion = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
|
||||
final String fullClassName = packageName + "." + bukkitVersion;
|
||||
internals = (Internals) Class.forName(fullClassName).getConstructors()[0].newInstance();
|
||||
} catch (InvocationTargetException | ClassNotFoundException | InstantiationException | IllegalAccessException |
|
||||
ClassCastException exception) {
|
||||
internals = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Internals getInternals() {
|
||||
return internals;
|
||||
}
|
||||
}
|
124
core/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java
Normal file
124
core/src/main/java/net/artelnatif/nicko/mojang/MojangAPI.java
Normal file
|
@ -0,0 +1,124 @@
|
|||
package net.artelnatif.nicko.mojang;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonParser;
|
||||
import net.artelnatif.nicko.Nicko;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class MojangAPI {
|
||||
public static final String URL_NAME = "https://api.mojang.com/users/profiles/minecraft/{name}";
|
||||
public static final String URL_SKIN = "https://sessionserver.mojang.com/session/minecraft/profile/{uuid}?unsigned=false";
|
||||
|
||||
private final CacheLoader<String, Optional<MojangSkin>> loader = new CacheLoader<>() {
|
||||
@Nonnull
|
||||
public Optional<MojangSkin> load(@Nonnull String uuid) throws Exception {
|
||||
return getSkinFromMojang(uuid);
|
||||
}
|
||||
};
|
||||
|
||||
private final LoadingCache<String, Optional<MojangSkin>> cache = CacheBuilder
|
||||
.newBuilder()
|
||||
.recordStats()
|
||||
.expireAfterWrite(24, TimeUnit.HOURS)
|
||||
.build(loader);
|
||||
|
||||
private final Nicko nicko;
|
||||
|
||||
public MojangAPI(Nicko nicko) {
|
||||
this.nicko = nicko;
|
||||
}
|
||||
|
||||
public Optional<MojangSkin> getSkin(String uuid) throws IOException, ExecutionException {
|
||||
return cache.get(uuid);
|
||||
}
|
||||
|
||||
public Optional<MojangSkin> getSkinWithoutCaching(String uuid) throws IOException {
|
||||
return getSkinFromMojang(uuid);
|
||||
}
|
||||
|
||||
public Optional<String> getUUID(String name) throws IOException {
|
||||
final String parametrizedUrl = URL_NAME.replace("{name}", name);
|
||||
final JsonObject object = getRequestToUrl(parametrizedUrl);
|
||||
if (hasNoError(object)) {
|
||||
return Optional.of(object.get("id").getAsString());
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private Optional<MojangSkin> getSkinFromMojang(String uuid) throws IOException {
|
||||
final String parametrizedUrl = URL_SKIN.replace("{uuid}", uuid);
|
||||
final JsonObject object = getRequestToUrl(parametrizedUrl);
|
||||
if (hasNoError(object)) {
|
||||
final MojangSkin skin = MojangSkin.buildFromJson(object);
|
||||
return Optional.of(skin);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private JsonObject getRequestToUrl(String parametrizedUrl) throws IOException {
|
||||
final URL url = new URL(parametrizedUrl);
|
||||
final HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
|
||||
con.setDoInput(true);
|
||||
con.setRequestMethod("GET");
|
||||
|
||||
switch (con.getResponseCode()) {
|
||||
case 400 -> {
|
||||
nicko.getLogger().warning("Failed to parse request: Invalid Name");
|
||||
return getErrorObject();
|
||||
}
|
||||
case 429 -> {
|
||||
nicko.getLogger().warning("Failed to parse request: The connection is throttled.");
|
||||
return getErrorObject();
|
||||
}
|
||||
case 200 -> {
|
||||
final BufferedReader input = new BufferedReader(new InputStreamReader(con.getInputStream()));
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = input.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
|
||||
try {
|
||||
final JsonElement jsonElt = JsonParser.parseString(builder.toString());
|
||||
return jsonElt.getAsJsonObject();
|
||||
} catch (JsonParseException | IllegalStateException exception) {
|
||||
nicko.getLogger().warning("Failed to parse request (" + parametrizedUrl + ")!");
|
||||
return getErrorObject();
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
nicko.getLogger().warning("Unhandled response code from Mojang: " + con.getResponseCode());
|
||||
return getErrorObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JsonObject getErrorObject() {
|
||||
final JsonObject errorObject = new JsonObject();
|
||||
errorObject.addProperty("error", "An error occurred.");
|
||||
return errorObject;
|
||||
}
|
||||
|
||||
private boolean hasNoError(JsonObject object) {
|
||||
return object.get("error") == null;
|
||||
}
|
||||
|
||||
public LoadingCache<String, Optional<MojangSkin>> getCache() {
|
||||
return cache;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package net.artelnatif.nicko.mojang;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public record MojangSkin(String name, String value, String signature) {
|
||||
public static MojangSkin buildFromJson(JsonObject object) {
|
||||
final String name = object.get("name").getAsString();
|
||||
final JsonObject properties = object.get("properties").getAsJsonArray().get(0).getAsJsonObject();
|
||||
final String value = properties.get("value").getAsString();
|
||||
final String signature = properties.get("signature").getAsString();
|
||||
return new MojangSkin(name, value, signature);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package net.artelnatif.nicko.mojang;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class MojangUtils {
|
||||
public static boolean isUsernameInvalid(String username) {
|
||||
return !Pattern.matches("^\\w{3,16}$", username);
|
||||
}
|
||||
|
||||
public static UUID fromTrimmed(String trimmedUUID) throws IllegalArgumentException {
|
||||
if (trimmedUUID == null) throw new IllegalArgumentException();
|
||||
StringBuilder builder = new StringBuilder(trimmedUUID.trim());
|
||||
/* Backwards adding to avoid index adjustments */
|
||||
try {
|
||||
builder.insert(20, "-");
|
||||
builder.insert(16, "-");
|
||||
builder.insert(12, "-");
|
||||
builder.insert(8, "-");
|
||||
} catch (StringIndexOutOfBoundsException e) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
return UUID.fromString(builder.toString());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package net.artelnatif.nicko.storage;
|
||||
|
||||
import net.artelnatif.nicko.Nicko;
|
||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||
import net.artelnatif.nicko.mojang.MojangUtils;
|
||||
import net.artelnatif.nicko.storage.json.JSONStorage;
|
||||
import net.artelnatif.nicko.storage.sql.SQLStorage;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerDataStore {
|
||||
private final Storage storage;
|
||||
private final Nicko nicko;
|
||||
private final HashMap<UUID, NickoProfile> profiles = new HashMap<>();
|
||||
private final HashMap<UUID, String> names = new HashMap<>();
|
||||
|
||||
public PlayerDataStore(Nicko nicko) {
|
||||
this.nicko = nicko;
|
||||
this.storage = nicko.getConfig().local() && !nicko.isBungeecord() ? new JSONStorage(nicko) : new SQLStorage(nicko);
|
||||
}
|
||||
|
||||
public void storeName(Player player) {
|
||||
if (!isNameStored(player)) {
|
||||
names.put(player.getUniqueId(), player.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public String getStoredName(Player player) {
|
||||
return names.get(player.getUniqueId());
|
||||
}
|
||||
|
||||
private boolean isNameStored(Player player) {
|
||||
return names.containsKey(player.getUniqueId());
|
||||
}
|
||||
|
||||
public void removeAllNames() {
|
||||
names.clear();
|
||||
}
|
||||
|
||||
public Optional<NickoProfile> getData(UUID uuid) {
|
||||
if (storage.isError()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (profiles.containsKey(uuid)) {
|
||||
return Optional.of(profiles.get(uuid));
|
||||
} else if (storage.isStored(uuid)) {
|
||||
final Optional<NickoProfile> retrievedProfile = storage.retrieve(uuid);
|
||||
retrievedProfile.ifPresent(profile -> profiles.put(uuid, profile));
|
||||
return retrievedProfile;
|
||||
} else {
|
||||
final NickoProfile newProfile = NickoProfile.EMPTY_PROFILE.clone();
|
||||
profiles.put(uuid, newProfile);
|
||||
return Optional.of(newProfile);
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<NickoProfile> getOfflineData(String name) {
|
||||
if (storage.isError()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
try {
|
||||
final Optional<String> uuidTrimmed = nicko.getMojangAPI().getUUID(name);
|
||||
if (uuidTrimmed.isPresent()) {
|
||||
final UUID uuid = MojangUtils.fromTrimmed(uuidTrimmed.get());
|
||||
return getData(uuid);
|
||||
}
|
||||
return Optional.empty();
|
||||
} catch (IOException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public void saveData(Player player) {
|
||||
if (storage.isError()) { return; }
|
||||
if (!profiles.containsKey(player.getUniqueId())) { return; }
|
||||
|
||||
storage.store(player.getUniqueId(), profiles.get(player.getUniqueId()));
|
||||
profiles.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
public Storage getStorage() {
|
||||
return storage;
|
||||
}
|
||||
}
|
27
core/src/main/java/net/artelnatif/nicko/storage/Storage.java
Normal file
27
core/src/main/java/net/artelnatif/nicko/storage/Storage.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
package net.artelnatif.nicko.storage;
|
||||
|
||||
import net.artelnatif.nicko.disguise.ActionResult;
|
||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class Storage {
|
||||
private boolean error = false;
|
||||
|
||||
public abstract StorageProvider getProvider();
|
||||
|
||||
public abstract ActionResult<Void> store(UUID uuid, NickoProfile profile);
|
||||
|
||||
public abstract boolean isStored(UUID uuid);
|
||||
|
||||
public abstract Optional<NickoProfile> retrieve(UUID uuid);
|
||||
|
||||
public boolean isError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setError(boolean error) {
|
||||
this.error = error;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package net.artelnatif.nicko.storage;
|
||||
|
||||
public interface StorageProvider {
|
||||
boolean init();
|
||||
|
||||
boolean close();
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package net.artelnatif.nicko.storage.json;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import net.artelnatif.nicko.Nicko;
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.disguise.ActionResult;
|
||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||
import net.artelnatif.nicko.bukkit.i18n.I18NDict;
|
||||
import net.artelnatif.nicko.storage.Storage;
|
||||
import net.artelnatif.nicko.storage.StorageProvider;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class JSONStorage extends Storage {
|
||||
private final Nicko nicko;
|
||||
private final Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create();
|
||||
private final File directory = new File(NickoBukkit.getInstance().getDataFolder() + "/players/");
|
||||
|
||||
private JSONStorageProvider provider;
|
||||
|
||||
public JSONStorage(Nicko nicko) { this.nicko = nicko; }
|
||||
|
||||
@Override
|
||||
public StorageProvider getProvider() {
|
||||
if (provider == null) {
|
||||
provider = new JSONStorageProvider(directory);
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult<Void> store(UUID uuid, NickoProfile profile) {
|
||||
final String profileToJson = gson.toJson(profile);
|
||||
final File file = new File(directory, uuid.toString() + ".json");
|
||||
|
||||
try {
|
||||
if (checkFileExists(file)) {
|
||||
try (FileWriter fileWriter = new FileWriter(file)) {
|
||||
try (BufferedWriter writer = new BufferedWriter(fileWriter)) {
|
||||
writer.write(profileToJson);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
nicko.getLogger().warning("Could not write to file.");
|
||||
return new ActionResult<>(I18NDict.Error.JSON_ERROR);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
nicko.getLogger().warning("Could not create file.");
|
||||
return new ActionResult<>(I18NDict.Error.JSON_ERROR);
|
||||
}
|
||||
|
||||
return new ActionResult<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStored(UUID uuid) {
|
||||
final File directory = new File(NickoBukkit.getInstance().getDataFolder() + "/players/");
|
||||
final File file = new File(directory, uuid.toString() + ".json");
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<NickoProfile> retrieve(UUID uuid) {
|
||||
final File directory = new File(NickoBukkit.getInstance().getDataFolder() + "/players/");
|
||||
final File file = new File(directory, uuid.toString() + ".json");
|
||||
try (FileReader fileReader = new FileReader(file)) {
|
||||
try (BufferedReader reader = new BufferedReader(fileReader)) {
|
||||
final NickoProfile value = gson.fromJson(reader, NickoProfile.class);
|
||||
return Optional.of(value);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkFileExists(File file) throws IOException {
|
||||
if (!file.exists()) {
|
||||
return file.createNewFile();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package net.artelnatif.nicko.storage.json;
|
||||
|
||||
import net.artelnatif.nicko.storage.StorageProvider;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class JSONStorageProvider implements StorageProvider {
|
||||
private final File directory;
|
||||
|
||||
public JSONStorageProvider(File directory) {
|
||||
this.directory = directory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean init()
|
||||
{
|
||||
return directory.exists() || directory.mkdirs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean close() { return true; }
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package net.artelnatif.nicko.storage.sql;
|
||||
|
||||
import net.artelnatif.nicko.Nicko;
|
||||
import net.artelnatif.nicko.disguise.ActionResult;
|
||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||
import net.artelnatif.nicko.bukkit.i18n.I18NDict;
|
||||
import net.artelnatif.nicko.storage.Storage;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SQLStorage extends Storage {
|
||||
private final Nicko nicko;
|
||||
|
||||
private SQLStorageProvider provider;
|
||||
|
||||
public SQLStorage(Nicko nicko) {
|
||||
this.nicko = nicko;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLStorageProvider getProvider() {
|
||||
if (provider == null) {
|
||||
provider = new SQLStorageProvider(nicko);
|
||||
}
|
||||
return provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResult<Void> store(UUID uuid, NickoProfile profile) {
|
||||
final Connection connection = getProvider().getConnection();
|
||||
if (connection == null) return new ActionResult<>(I18NDict.Error.SQL_ERROR);
|
||||
|
||||
try {
|
||||
final String sql = """
|
||||
INSERT IGNORE INTO nicko.DATA
|
||||
(`uuid`, `name`, `skin`, `bungeecord`)
|
||||
VALUES
|
||||
(?, ?, ?, ?)
|
||||
""";
|
||||
|
||||
final PreparedStatement statement = connection.prepareStatement(sql);
|
||||
statement.setObject(1, uuidToBin(uuid));
|
||||
statement.setString(2, profile.getName());
|
||||
statement.setString(3, profile.getSkin());
|
||||
statement.setBoolean(4, profile.isBungeecordTransfer());
|
||||
statement.executeUpdate();
|
||||
return new ActionResult<>();
|
||||
} catch (SQLException e) {
|
||||
nicko.getLogger().warning("Couldn't send SQL Request: " + e.getMessage());
|
||||
return new ActionResult<>(I18NDict.Error.SQL_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStored(UUID uuid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<NickoProfile> retrieve(UUID uuid) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private byte[] uuidToBin(UUID uuid) {
|
||||
final byte[] uuidBytes = new byte[16];
|
||||
final ByteBuffer buffer = ByteBuffer.wrap(uuidBytes)
|
||||
.order(ByteOrder.BIG_ENDIAN)
|
||||
.putLong(uuid.getMostSignificantBits())
|
||||
.putLong(uuid.getLeastSignificantBits());
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
private UUID binToUUID(byte[] array) {
|
||||
final ByteBuffer buffer = ByteBuffer.wrap(array);
|
||||
return new UUID(buffer.getLong(), buffer.getLong());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package net.artelnatif.nicko.storage.sql;
|
||||
|
||||
import net.artelnatif.nicko.Nicko;
|
||||
import net.artelnatif.nicko.config.Configuration;
|
||||
import net.artelnatif.nicko.storage.StorageProvider;
|
||||
import org.mariadb.jdbc.MariaDbDataSource;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class SQLStorageProvider implements StorageProvider {
|
||||
private final Nicko nicko;
|
||||
private Connection connection;
|
||||
private MariaDbDataSource dataSource;
|
||||
|
||||
private final String schemaName = "nicko";
|
||||
|
||||
public SQLStorageProvider(Nicko nicko) {
|
||||
this.nicko = nicko;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean init() {
|
||||
try {
|
||||
final Configuration config = nicko.getConfig();
|
||||
dataSource = new MariaDbDataSource();
|
||||
dataSource.setUrl("jdbc:mariadb://" + config.address());
|
||||
dataSource.setUser(config.username());
|
||||
dataSource.setPassword(config.password());
|
||||
connection = dataSource.getConnection();
|
||||
final boolean initialized = connection != null && !connection.isClosed();
|
||||
|
||||
if (!initialized) return false;
|
||||
|
||||
nicko.getLogger().info("Creating SQL database...");
|
||||
createDatabase();
|
||||
|
||||
nicko.getLogger().info("Creating SQL table...");
|
||||
createTable();
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
nicko.getLogger().severe("Couldn't establish a connection to the MySQL database: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean close() {
|
||||
if (connection == null) { return true; }
|
||||
try {
|
||||
connection.close();
|
||||
return connection.isClosed();
|
||||
} catch (SQLException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void createTable() {
|
||||
final Connection connection = getConnection();
|
||||
|
||||
final String query = """
|
||||
CREATE TABLE IF NOT EXISTS %s.DATA (
|
||||
uuid binary(16) NOT NULL,
|
||||
name varchar(16) NOT NULL,
|
||||
skin varchar(16) NOT NULL,
|
||||
bungeecord boolean NOT NULL,
|
||||
PRIMARY KEY (UUID)
|
||||
)
|
||||
""".formatted(schemaName);
|
||||
|
||||
try {
|
||||
final PreparedStatement statement = connection.prepareStatement(query);
|
||||
statement.executeUpdate();
|
||||
statement.close();
|
||||
} catch (SQLException e) {
|
||||
// TODO: 12/10/22 Handle error
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void createDatabase() {
|
||||
final Connection connection = getConnection();
|
||||
|
||||
final String query = """
|
||||
CREATE DATABASE IF NOT EXISTS %s
|
||||
""".formatted(schemaName);
|
||||
|
||||
try {
|
||||
final PreparedStatement statement = connection.prepareStatement(query);
|
||||
statement.executeUpdate();
|
||||
statement.close();
|
||||
} catch (SQLException e) {
|
||||
// TODO: 12/10/22 Handle error
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public Connection getConnection() {
|
||||
return connection;
|
||||
}
|
||||
}
|
4
core/src/main/resources/bungee.yml
Normal file
4
core/src/main/resources/bungee.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
name: ${project.parent.name}
|
||||
main: net.artelnatif.nicko.bungee.NickoBungee
|
||||
version: ${project.version}
|
||||
author: Aro
|
48
core/src/main/resources/config.yml
Normal file
48
core/src/main/resources/config.yml
Normal file
|
@ -0,0 +1,48 @@
|
|||
# Nicko ${project.version} - Config:
|
||||
|
||||
# This is the Nicko configuration file.
|
||||
# This file contains all the configuration for
|
||||
# the Bukkit AND Bungeecord versions of Nicko.
|
||||
# Nicko is smart and will only read its configuration
|
||||
# section based on what it's enabled as.
|
||||
# For example, if Nicko is enabled as a Bukkit plugin,
|
||||
# it will only read the "Bukkit" section of the config file.
|
||||
# As a result, modifying any other section is useless.
|
||||
|
||||
###########
|
||||
# GENERAL #
|
||||
###########
|
||||
|
||||
# SQL database's address
|
||||
# Accepted values: valid IP address (e.g. localhost, 127.0.0.1)
|
||||
address: "localhost"
|
||||
# SQL database's username.
|
||||
# Accepted values: any string
|
||||
username: "username"
|
||||
# SQL database's password.
|
||||
# Accepted values: any string
|
||||
password: "password"
|
||||
|
||||
#################
|
||||
# BUKKIT/SPIGOT #
|
||||
#################
|
||||
|
||||
# Nicko's messages prefix.
|
||||
# Accepted values: any string
|
||||
prefix: "§8[§6Nicko§8] "
|
||||
|
||||
# Indicates wherever the data will be stored
|
||||
# locally through a .json file or a (My)SQL database.
|
||||
# Accepted values: false (Disabled), true (Enabled)
|
||||
local: true
|
||||
|
||||
# Enables Bungeecord support, switching
|
||||
# servers will transfer player's disguise.
|
||||
# Accepted values: false (Disabled), true (Enabled)
|
||||
bungeecord: false
|
||||
|
||||
# Nicko will copy the English locale as "lang.yml"
|
||||
# and will use the translations in that file when "Server Custom"
|
||||
# is selected as the player's locale.
|
||||
# Accepted values: false (Disabled), true (Enabled)
|
||||
customLocale: false
|
22
core/src/main/resources/en.yml
Normal file
22
core/src/main/resources/en.yml
Normal file
|
@ -0,0 +1,22 @@
|
|||
error:
|
||||
couldnt_get_name_from_mojang: "Failed to get username from Mojang"
|
||||
couldnt_get_skin_from_cache: "Failed to get skin from cache"
|
||||
couldnt_get_skin_from_mojang: "Failed to get skin from Mojang"
|
||||
generic: "Unknown error"
|
||||
invalid_username: "§cThe specified username is not a valid Minecraft username."
|
||||
player_offline: "§c{0} §fis offline, please try again."
|
||||
sql: "SQL Error"
|
||||
json: "JSON Error"
|
||||
event:
|
||||
admin:
|
||||
cache_clear: "§aSkin cache cleaned."
|
||||
disguise:
|
||||
fail: "§cUnable to apply your disguise. §7§o({0})"
|
||||
success: "§aDisguise applied!"
|
||||
previous_skin_applied:
|
||||
fail: "§cFailed to apply your previous disguise back. §7§o({0})"
|
||||
success: "§aYour previous active disguise has been applied back."
|
||||
undisguise:
|
||||
fail: "§cUnable to remove your disguise. It will be set back to default on your next login. Sorry!"
|
||||
none: "§cYou do not have an active disguise."
|
||||
success: "§aDisguise removed."
|
22
core/src/main/resources/fr.yml
Normal file
22
core/src/main/resources/fr.yml
Normal file
|
@ -0,0 +1,22 @@
|
|||
error:
|
||||
couldnt_get_name_from_mojang: "Impossible de récupérer le nom d''utilisateur depuis Mojang"
|
||||
couldnt_get_skin_from_cache: "Impossible de récupérer le skin depuis le cache"
|
||||
couldnt_get_skin_from_mojang: "Impossible de récupérer le skin depuis Mojang"
|
||||
generic: "Erreur inconnue"
|
||||
invalid_username: "§cLe pseudo spécifié n''est pas un pseudo Minecraft valide."
|
||||
player_offline: "§c{0} §fest hors-ligne, veuillez réessayer."
|
||||
sql: "Erreur SQL"
|
||||
json: "Erreur JSON"
|
||||
event:
|
||||
admin:
|
||||
cache_clear: "§aCache des skins nettoyé."
|
||||
disguise:
|
||||
fail: "§cImpossible d''appliquer votre déguisement. §7§o({0})"
|
||||
success: "§aDéguisement appliqué !"
|
||||
previous_skin_applied:
|
||||
fail: "§cImpossible d''appliquer votre déguisement précédent. §7§o({0})"
|
||||
success: "§aVotre précédent déguisement a été réappliqué."
|
||||
undisguise:
|
||||
fail: "§cImpossible de retier votre déguisement. Il sera remis par défaut à votre prochaine reconnexion. Désolé !"
|
||||
none: "§cVous n''avez pas de déguisement."
|
||||
success: "§aDéguisement retiré."
|
17
core/src/main/resources/plugin.yml
Normal file
17
core/src/main/resources/plugin.yml
Normal file
|
@ -0,0 +1,17 @@
|
|||
name: Nicko
|
||||
main: net.artelnatif.nicko.bukkit.NickoBukkit
|
||||
version: 1.0-SNAPSHOT
|
||||
author: Aro
|
||||
api-version: 1.19
|
||||
softdepend: [ PlaceholderAPI ]
|
||||
commands:
|
||||
nicko:
|
||||
description: "Opens Nicko's GUI."
|
||||
permission: nicko.admin
|
||||
permissions:
|
||||
nicko.*:
|
||||
default: op
|
||||
children:
|
||||
- nicko.use
|
||||
nicko.use:
|
||||
default: op
|
|
@ -0,0 +1,36 @@
|
|||
package net.artelnatif.nicko.test;
|
||||
|
||||
import be.seeseemelk.mockbukkit.MockBukkit;
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.config.Configuration;
|
||||
import org.junit.jupiter.api.*;
|
||||
|
||||
public class NickoPluginTest {
|
||||
private static NickoBukkit plugin;
|
||||
|
||||
@BeforeAll
|
||||
public static void setup() {
|
||||
final Configuration config = new Configuration(
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
true,
|
||||
false,
|
||||
false);
|
||||
MockBukkit.mock();
|
||||
plugin = MockBukkit.load(NickoBukkit.class, config);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Plugin Initialization")
|
||||
public void testPluginInitialization() {
|
||||
Assertions.assertNotNull(plugin.getNicko().getDataStore().getStorage().getProvider());
|
||||
Assertions.assertNotNull(plugin.getNicko().getConfig());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void shutdown() {
|
||||
MockBukkit.unmock();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package net.artelnatif.nicko.test.storage;
|
||||
|
||||
import be.seeseemelk.mockbukkit.MockBukkit;
|
||||
import be.seeseemelk.mockbukkit.ServerMock;
|
||||
import be.seeseemelk.mockbukkit.entity.PlayerMock;
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.config.Configuration;
|
||||
import net.artelnatif.nicko.disguise.ActionResult;
|
||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||
import net.artelnatif.nicko.bukkit.i18n.Locale;
|
||||
import org.junit.jupiter.api.*;
|
||||
|
||||
public class BrokenSQLTest {
|
||||
private static ServerMock server;
|
||||
private static NickoBukkit plugin;
|
||||
|
||||
@BeforeAll
|
||||
public static void setup() {
|
||||
final Configuration config = new Configuration(
|
||||
"127.0.0.1",
|
||||
"root",
|
||||
"INVALID_PASSWORD",
|
||||
"",
|
||||
false,
|
||||
false,
|
||||
false);
|
||||
server = MockBukkit.mock();
|
||||
plugin = MockBukkit.load(NickoBukkit.class, config);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Fail to create Tables")
|
||||
public void createSQLTables() {
|
||||
Assertions.assertTrue(plugin.getNicko().getDataStore().getStorage().isError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Fail to Store Player Via SQL")
|
||||
public void storePlayer() {
|
||||
final PlayerMock playerMock = server.addPlayer();
|
||||
final NickoProfile profile = new NickoProfile("Notch", "Notch", Locale.ENGLISH, true);
|
||||
final ActionResult<Void> storeAction = plugin.getNicko().getDataStore().getStorage().store(playerMock.getUniqueId(), profile);
|
||||
Assertions.assertTrue(storeAction.isError());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void shutdown() {
|
||||
MockBukkit.unmock();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package net.artelnatif.nicko.test.storage;
|
||||
|
||||
import be.seeseemelk.mockbukkit.MockBukkit;
|
||||
import be.seeseemelk.mockbukkit.ServerMock;
|
||||
import be.seeseemelk.mockbukkit.entity.PlayerMock;
|
||||
import net.artelnatif.nicko.bukkit.NickoBukkit;
|
||||
import net.artelnatif.nicko.config.Configuration;
|
||||
import net.artelnatif.nicko.disguise.ActionResult;
|
||||
import net.artelnatif.nicko.disguise.NickoProfile;
|
||||
import net.artelnatif.nicko.bukkit.i18n.Locale;
|
||||
import org.junit.jupiter.api.*;
|
||||
|
||||
public class SQLStorageTest {
|
||||
private static ServerMock server;
|
||||
private static NickoBukkit plugin;
|
||||
|
||||
@BeforeAll
|
||||
public static void setup() {
|
||||
final Configuration config = new Configuration(
|
||||
"127.0.0.1",
|
||||
"root",
|
||||
"12345",
|
||||
"",
|
||||
false,
|
||||
false,
|
||||
false);
|
||||
server = MockBukkit.mock();
|
||||
plugin = MockBukkit.load(NickoBukkit.class, config);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Create SQL Tables")
|
||||
public void createSQLTables() {
|
||||
Assertions.assertFalse(plugin.getNicko().getDataStore().getStorage().isError());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Store Player Via SQL")
|
||||
public void storePlayer() {
|
||||
final PlayerMock playerMock = server.addPlayer();
|
||||
final NickoProfile profile = new NickoProfile("Notch", "Notch", Locale.ENGLISH, true);
|
||||
final ActionResult<Void> storeAction = plugin.getNicko().getDataStore().getStorage().store(playerMock.getUniqueId(), profile);
|
||||
Assertions.assertFalse(storeAction.isError());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void shutdown() {
|
||||
MockBukkit.unmock();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue