HubCore rewrite for PS v3.1

This commit is contained in:
OpenSource 2022-12-04 03:09:16 +01:00
parent a676c1e400
commit 48801fc1c5
30 changed files with 1449 additions and 996 deletions

View File

@ -0,0 +1,72 @@
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>PSHubCore</groupId>
<artifactId>PSHubCore</artifactId>
<version>v3-dev</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<finalName>PSHubCore</finalName>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>placeholderapi</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.18.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId>
<version>2.9.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.1.5.Final</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

32
pom.xml
View File

@ -10,8 +10,23 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<configuration> <configuration>
<source>11</source> <source>17</source>
<target>11</target> <target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<finalName>PSHubCore</finalName>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
@ -30,10 +45,6 @@
<id>placeholderapi</id> <id>placeholderapi</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url> <url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository> </repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories> </repositories>
<dependencies> <dependencies>
@ -61,12 +72,12 @@
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<version>2.0.1</version> <version>2.0.5</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId> <artifactId>slf4j-simple</artifactId>
<version>2.0.0</version> <version>2.0.5</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.moandjiezana.toml</groupId> <groupId>com.moandjiezana.toml</groupId>
@ -90,6 +101,11 @@
<version>2.9.2</version> <version>2.9.2</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.1.5.Final</version>
</dependency>
</dependencies> </dependencies>
<groupId>PSHubCore</groupId> <groupId>PSHubCore</groupId>

View File

@ -1,106 +0,0 @@
package os.arcadiadevs.playerservers.hubcore;
import com.samjakob.spigui.SpiGUI;
import lombok.Getter;
import lombok.SneakyThrows;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import os.arcadiadevs.playerservers.hubcore.commands.CommandManager;
import os.arcadiadevs.playerservers.hubcore.database.DataBase;
import os.arcadiadevs.playerservers.hubcore.database.DataSource;
import os.arcadiadevs.playerservers.hubcore.events.ClickEvent;
import os.arcadiadevs.playerservers.hubcore.events.HubEvents;
import os.arcadiadevs.playerservers.hubcore.events.JoinEvent;
import os.arcadiadevs.playerservers.hubcore.objects.ServerCache;
import os.arcadiadevs.playerservers.hubcore.placeholders.PlayerCount;
import java.io.*;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class PSHubCore extends JavaPlugin {
private static PSHubCore PSH;
@Getter
private static DataBase dataBase;
@Getter
public YamlConfiguration multinode;
@Getter
private SpiGUI spiGUI;
@Getter
public ServerCache serverCache;
@SneakyThrows
@Override
public void onEnable() {
PSH = this;
getConfig().options().copyDefaults(true);
saveConfig();
createMultiNodeConfig();
DataSource ds = new DataSource();
ds.registerDataSource();
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
/*
* We register the EventListeneres here, when PlaceholderAPI is installed.
* Since all events are in the main class (this class), we simply use "this"
*/
new PlayerCount(this).register();
}
Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
Bukkit.getPluginManager().registerEvents(new ClickEvent(), this);
Bukkit.getPluginManager().registerEvents(new JoinEvent(), this);
Bukkit.getPluginManager().registerEvents(new HubEvents(), this);
Objects.requireNonNull(getCommand("servers")).setExecutor(new CommandManager());
// Initialize SpiGUI
spiGUI = new SpiGUI(this);
// Initialize ServerCache
serverCache = new ServerCache();
// Create ServerCache refreshing task
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(serverCache, 1, getConfig().getInt("cache-time"), TimeUnit.SECONDS);
}
private void createMultiNodeConfig() throws IOException {
if (!getConfig().getBoolean("multi-node")) {
return;
}
File configFile = new File(this.getDataFolder(), "multinode.yml");
if (!configFile.exists()) {
InputStream inputStream = getClass().getResourceAsStream("/multinode.yml");
OutputStream outputStream = new FileOutputStream(configFile);
int read;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
inputStream.close();
outputStream.close();
}
multinode = YamlConfiguration.loadConfiguration(configFile);
}
public static PSHubCore getInstance() {
return PSH;
}
@Override
public void onDisable() {
super.onDisable();
getServer().getMessenger().unregisterIncomingPluginChannel(this, "BungeeCord");
}
}

View File

@ -0,0 +1,122 @@
package os.arcadiadevs.playerservers.hubcore;
import com.samjakob.spigui.SpiGUI;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Objects;
import lombok.Getter;
import lombok.SneakyThrows;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.hibernate.SessionFactory;
import os.arcadiadevs.playerservers.hubcore.commands.CommandManager;
import os.arcadiadevs.playerservers.hubcore.controllers.NodesController;
import os.arcadiadevs.playerservers.hubcore.controllers.ServersController;
import os.arcadiadevs.playerservers.hubcore.events.ClickEvent;
import os.arcadiadevs.playerservers.hubcore.events.HubEvents;
import os.arcadiadevs.playerservers.hubcore.events.JoinEvent;
import os.arcadiadevs.playerservers.hubcore.models.Node;
import os.arcadiadevs.playerservers.hubcore.models.Server;
import os.arcadiadevs.playerservers.hubcore.placeholders.PlayerCount;
public class PsHubCore extends JavaPlugin {
@Getter
private static PsHubCore instance;
@Getter
private SpiGUI spiGui;
@Getter
private SessionFactory sessionFactory;
@Getter
private ServersController serversController;
@Getter
private NodesController nodesController;
@SneakyThrows
@Override
public void onEnable() {
instance = this;
getConfig().options().copyDefaults(true);
saveConfig();
extractFile("hibernate.cfg.xml");
sessionFactory =
new org.hibernate.cfg.Configuration()
.configure(new File(this.getDataFolder().getAbsolutePath() + "/" + "hibernate.cfg.xml"))
.addAnnotatedClass(Server.class)
.addAnnotatedClass(Node.class)
.buildSessionFactory();
// Initialize the controllers
serversController = new ServersController(sessionFactory);
nodesController = new NodesController(sessionFactory);
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
/*
* We register the EventListeneres here, when PlaceholderAPI is installed.
* Since all events are in the main class (this class), we simply use "this"
*/
new PlayerCount(serversController).register();
}
Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
Bukkit.getPluginManager().registerEvents(new ClickEvent(this), this);
Bukkit.getPluginManager().registerEvents(new JoinEvent(this), this);
Bukkit.getPluginManager().registerEvents(new HubEvents(getConfig()), this);
Objects.requireNonNull(getCommand("servers")).setExecutor(new CommandManager());
// Initialize SpiGUI
spiGui = new SpiGUI(this);
// Initialize ServerCache
//serverCache = new ServerCache();
// Create ServerCache refreshing task
//ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
//executor.scheduleAtFixedRate(serverCache, 1, getConfig().getInt("cache-time"), TimeUnit.SECONDS);
}
/**
* Extracts a file from the jar to the data folder.
*
* @param name The name of the file.
* @return The file
* @throws IOException If the file cannot be extracted.
*/
private File extractFile(String name) throws IOException {
var configFile = new File(this.getDataFolder(), name);
//noinspection ResultOfMethodCallIgnored
getDataFolder().mkdirs();
if (configFile.createNewFile()) {
try (
var fis = getClass().getResourceAsStream("/" + name);
var fos = new FileOutputStream(configFile)
) {
var buf = new byte[1024];
int i;
while ((i = Objects.requireNonNull(fis).read(buf)) != -1) {
fos.write(buf, 0, i);
}
} catch (Exception e) {
Bukkit.getLogger()
.warning(String.format("Error extracting %s: %s", name, e.getMessage()));
}
}
return configFile;
}
@Override
public void onDisable() {
super.onDisable();
getServer().getMessenger().unregisterIncomingPluginChannel(this, "BungeeCord");
}
}

View File

@ -4,27 +4,33 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import os.arcadiadevs.playerservers.hubcore.PSHubCore; import os.arcadiadevs.playerservers.hubcore.PsHubCore;
import os.arcadiadevs.playerservers.hubcore.guis.SelectorGui;
import os.arcadiadevs.playerservers.hubcore.utils.ChatUtil; import os.arcadiadevs.playerservers.hubcore.utils.ChatUtil;
import os.arcadiadevs.playerservers.hubcore.utils.GUIUtils; import os.arcadiadevs.playerservers.hubcore.guis.PlayerMenuGui;
public class CommandManager implements CommandExecutor { public class CommandManager implements CommandExecutor {
@SuppressWarnings("NullableProblems") @Override
@Override public boolean onCommand(CommandSender commandSender, Command command, String s,
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) { String[] strings) {
if (commandSender instanceof Player) { if (!(commandSender instanceof Player player)) {
if (!PSHubCore.getInstance().getConfig().getBoolean("gui.selector.item.enabled")) { ChatUtil.sendMessage(commandSender,
commandSender.sendMessage(ChatUtil.translate("&9PlayerServers> &7Oops, gui isn't enabled in config file!")); "&9Error> &cYou must be a player to execute this command.");
return true; return true;
}
if (PSHubCore.getInstance().getConfig().getBoolean("gui.selector.item.enabled")) {
if (command.getName().equalsIgnoreCase("servers") || command.getName().equalsIgnoreCase("menu") || command.getName().equalsIgnoreCase("opengui")) {
Player player = (Player) commandSender;
GUIUtils.openSelector(player);
}
}
}
return true;
} }
if (!PsHubCore.getInstance().getConfig().getBoolean("gui.selector.enabled")) {
ChatUtil.sendMessage(player, "&9PlayerServers> &7Oops, this feature is disabled.");
return true;
}
if (command.getName().equalsIgnoreCase("servers") ||
command.getName().equalsIgnoreCase("menu") ||
command.getName().equalsIgnoreCase("opengui")) {
SelectorGui.openGui(player);
}
return true;
}
} }

View File

@ -0,0 +1,67 @@
package os.arcadiadevs.playerservers.hubcore.controllers;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import os.arcadiadevs.playerservers.hubcore.models.Node;
/**
* A class that handles all the database operations for node object.
*
* @author ArcadiaDevs
*/
public class NodesController {
private final SessionFactory sessionFactory;
public NodesController(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
/**
* Create a new node in the database.
*
* @param node The node to create
*/
public void createNode(Node node) {
try (Session session = sessionFactory.openSession()) {
session.beginTransaction();
session.persist(node);
session.getTransaction().commit();
}
}
/**
* Gets all the nodes from the database.
*
* @return A list of all the nodes
*/
public List<Node> getNodes() {
try (Session session = sessionFactory.openSession()) {
return session.createQuery("from Node", Node.class).list();
}
}
/**
* Gets the next available node.
*
* @return The next available node
*/
public Node getNextNode() {
List<Node> nodes = getNodes();
if (nodes.isEmpty()) {
return null;
}
Node emptiestNode = nodes.get(0);
for (Node node : nodes) {
if (node.getServers().size() < emptiestNode.getServers().size()) {
emptiestNode = node;
}
}
return emptiestNode;
}
}

View File

@ -0,0 +1,152 @@
package os.arcadiadevs.playerservers.hubcore.controllers;
import java.util.List;
import java.util.UUID;
import org.bukkit.entity.Player;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import os.arcadiadevs.playerservers.hubcore.models.Server;
/**
* A class that handles all the database operations for the servers object.
*
* @author ArcadiaDevs
*/
public class ServersController {
private final SessionFactory sessionFactory;
/**
* Creates a new instance of the servers controller.
*
* @param sessionFactory The session factory
*/
public ServersController(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
/**
* Create a new server in the database.
*
* @param server The server to create
*/
public void createServer(Server server) {
Session session = this.sessionFactory.getCurrentSession();
session.beginTransaction();
session.persist(server);
session.getTransaction().commit();
}
/**
* Gets all the servers from the database.
*
* @return A list of all the servers
*/
public List<Server> getServers() {
Session session = this.sessionFactory.getCurrentSession();
session.beginTransaction();
List<Server> servers = session.createQuery("from Server", Server.class).list();
session.getTransaction().commit();
return servers;
}
/**
* Gets the server by the server id.
*
* @param ownerId The owner id
* @return The server
*/
public Server getServer(UUID ownerId) {
Session session = this.sessionFactory.getCurrentSession();
session.beginTransaction();
Server server = session
.createQuery("from Server where owner = :owner", Server.class)
.setParameter("owner", ownerId)
.uniqueResult();
session.getTransaction().commit();
return server;
}
public Server getServer(Player player) {
return getServer(player.getUniqueId());
}
/**
* Checks if the player has a server.
*
* @param owner The player to check
* @return True if the player has a server, false otherwise
*/
public boolean hasServer(UUID owner) {
Session session = this.sessionFactory.getCurrentSession();
session.beginTransaction();
Server server = session
.createQuery("from Server where owner = :owner", Server.class)
.setParameter("owner", owner)
.uniqueResult();
session.getTransaction().commit();
return server != null;
}
public boolean hasServer(Player player) {
return hasServer(player.getUniqueId());
}
/**
* Checks if a server exists by the server id.
*
* @param id The server id
* @return True if the server exists, false otherwise
*/
public boolean serverExists(String id) {
Session session = this.sessionFactory.getCurrentSession();
session.beginTransaction();
Server server = session
.createQuery("from Server where id = :id", Server.class)
.setParameter("id", id)
.uniqueResult();
session.getTransaction().commit();
return server != null;
}
/**
* Renames the server.
*
* @param owner The owner of the server
* @param id The new id (name)
*/
public void renameServer(UUID owner, String id) {
Session session = this.sessionFactory.getCurrentSession();
session.beginTransaction();
Server server = session
.createQuery("from Server where owner = :owner", Server.class)
.setParameter("owner", owner)
.uniqueResult();
server.setId(id);
session.getTransaction().commit();
}
public void renameServer(Player player, String id) {
renameServer(player.getUniqueId(), id);
}
/**
* Deletes the server.
*
* @param owner The owner of the server
*/
public void removePlayer(UUID owner) {
Session session = this.sessionFactory.getCurrentSession();
session.beginTransaction();
Server server = session
.createQuery("from Server where owner = :owner", Server.class)
.setParameter("owner", owner)
.uniqueResult();
session.remove(server);
session.getTransaction().commit();
}
public void removePlayer(Player player) {
removePlayer(player.getUniqueId());
}
}

View File

@ -1,107 +0,0 @@
package os.arcadiadevs.playerservers.hubcore.database;
import org.bukkit.entity.Player;
import os.arcadiadevs.playerservers.hubcore.objects.Server;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class DataBase {
private static final ExecutorService executor = Executors.newFixedThreadPool(10);
public static boolean containsPort(String port) {
try (Connection connection = DataSource.getConnection()) {
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM PlayerServers");
ResultSet rs = stmt.executeQuery();
while(rs.next()) {
if (rs.getString("Port").equals(port))
return true;
}
return false;
}
catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static Future<Server> getServer(Player player) {
return executor.submit(() -> {
try (Connection connection = DataSource.getConnection()) {
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM PlayerServers WHERE UUID = ?");
stmt.setString(1, player.getUniqueId().toString());
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
return new Server()
.setServerId(rs.getString("ServerID"))
.setPort(rs.getInt("Port"))
.setPlayerName(rs.getString("PlayerName"))
.setNode(rs.getString("Node"));
}
return null;
}
catch (Exception e) {
e.printStackTrace();
return null;
}
});
}
public static Future<List<Server>> getServersInfo() {
return executor.submit(() -> {
try (Connection connection = DataSource.getConnection()) {
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM PlayerServers");
ResultSet rs = stmt.executeQuery();
List<Server> servers = new ArrayList<>();
while (rs.next()) {
servers.add(new Server()
.setServerId(rs.getString("ServerID"))
.setPort(rs.getInt("Port"))
.setPlayerName(rs.getString("PlayerName"))
.setNode(rs.getString("Node")));
}
return servers;
}
catch (Exception e) {
e.printStackTrace();
return null;
}
});
}
public static String getPortByUUID(String UUID) {
try (Connection connection = DataSource.getConnection()) {
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM PlayerServers WHERE UUID='" + UUID + "'");
ResultSet rs = stmt.executeQuery(); rs.next();
return rs.getString("Port");
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static boolean containsServer(String UUID) {
try (Connection connection = DataSource.getConnection()) {
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM PlayerServers");
ResultSet rs = stmt.executeQuery();
while(rs.next()) {
if (rs.getString("UUID").equals(UUID))
return true;
}
return false;
}
catch (Exception e) {
e.printStackTrace();
return false;
}
}
}

View File

@ -1,43 +0,0 @@
package os.arcadiadevs.playerservers.hubcore.database;
import com.zaxxer.hikari.HikariDataSource;
import os.arcadiadevs.playerservers.hubcore.PSHubCore;
import java.sql.Connection;
import java.sql.SQLException;
public class DataSource
{
public static HikariDataSource hikari;
@SuppressWarnings("ConstantConditions")
public void registerDataSource() throws SQLException {
final var pl = PSHubCore.getInstance();
final var address = pl.getConfig().getString("mysql.hostname");
final var name = pl.getConfig().getString("mysql.database");
final var username = pl.getConfig().getString("mysql.username");
final var password = pl.getConfig().getString("mysql.password");
final var useSSL = pl.getConfig().getBoolean("mysql.useSSL");
hikari = new HikariDataSource();
hikari.setPoolName("PSHubCore");
hikari.setMaximumPoolSize(10);
hikari.setLoginTimeout(10);
hikari.setConnectionTimeout(10000);
hikari.setDataSourceClassName("com.mysql.cj.jdbc.MysqlDataSource");
hikari.addDataSourceProperty("serverName", address);
hikari.addDataSourceProperty("port", "3306");
hikari.addDataSourceProperty("databaseName", name);
hikari.addDataSourceProperty("user", username);
hikari.addDataSourceProperty("password", password);
hikari.addDataSourceProperty("useSSL", useSSL);
}
public static Connection getConnection() throws SQLException {
return hikari.getConnection();
}
}

View File

@ -0,0 +1,6 @@
package os.arcadiadevs.playerservers.hubcore.enums;
public enum PowerAction {
START,
STOP,
}

View File

@ -9,69 +9,102 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import os.arcadiadevs.playerservers.hubcore.PSHubCore; import os.arcadiadevs.playerservers.hubcore.PsHubCore;
import os.arcadiadevs.playerservers.hubcore.guis.SelectorGui;
import os.arcadiadevs.playerservers.hubcore.utils.ChatUtil; import os.arcadiadevs.playerservers.hubcore.utils.ChatUtil;
import os.arcadiadevs.playerservers.hubcore.utils.GUIUtils; import os.arcadiadevs.playerservers.hubcore.guis.PlayerMenuGui;
public class ClickEvent implements Listener { public class ClickEvent implements Listener {
@EventHandler private final PsHubCore instance;
public void onClick(PlayerInteractEvent event) {
final PSHubCore PSH = PSHubCore.getInstance();
final var player = event.getPlayer();
if (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK) { public ClickEvent(PsHubCore instance) {
return; this.instance = instance;
} }
if (PSH.getConfig().getBoolean("gui.selector.item.enabled") && player.getInventory().getHeldItemSlot() == PSHubCore.getInstance().getConfig().getInt("gui.selector.item.location")) { /**
if (!player.hasPermission("hubcore.selector")) { * Executes action on player interact event.
player.sendMessage(ChatUtil.translate(PSH.getConfig().getString("messages.no-permission"))); *
return; * @param event the event
} */
GUIUtils.openSelector(player); @EventHandler
event.setCancelled(true); public void onClick(PlayerInteractEvent event) {
} final var player = event.getPlayer();
if (PSH.getConfig().getBoolean("gui.player-menu.item.enabled") && player.getInventory().getHeldItemSlot() == PSHubCore.getInstance().getConfig().getInt("gui.player-menu.item.location")) { if (event.getAction() != Action.RIGHT_CLICK_AIR
if (!player.hasPermission("hubcore.player-menu")) { && event.getAction() != Action.RIGHT_CLICK_BLOCK) {
player.sendMessage(ChatUtil.translate(PSH.getConfig().getString("messages.no-permission"))); return;
return;
}
GUIUtils.openMenu(player);
event.setCancelled(true);
}
} }
@EventHandler if (instance.getConfig().getBoolean("gui.selector.item.enabled")
public void inventory(InventoryClickEvent event) { && player.getInventory().getHeldItemSlot()
if (!(event.getWhoClicked() instanceof Player)) { == PsHubCore.getInstance().getConfig().getInt("gui.selector.item.location")) {
return; if (!player.hasPermission("hubcore.selector")) {
} ChatUtil.sendMessage(player, instance.getConfig().getString("messages.no-permission"));
return;
final var player = (Player) event.getWhoClicked(); }
final var inventoryType = event.getInventory().getType(); SelectorGui.openGui(player);
final var selectorItemSlot = PSHubCore.getInstance().getConfig().getInt("gui.selector.item.location"); event.setCancelled(true);
final var menuItemSlot = PSHubCore.getInstance().getConfig().getInt("gui.player-menu.item.location");
if (event.getSlot() == selectorItemSlot && (inventoryType == InventoryType.PLAYER || inventoryType == InventoryType.CRAFTING)
|| event.getSlot() == menuItemSlot && (inventoryType == InventoryType.PLAYER || inventoryType == InventoryType.CRAFTING)) {
if (player.getGameMode() == GameMode.CREATIVE) {
player.closeInventory();
}
event.setCancelled(true);
}
} }
@EventHandler if (instance.getConfig().getBoolean("gui.player-menu.item.enabled")
public void drop(PlayerDropItemEvent event) { && player.getInventory().getHeldItemSlot()
final var player = event.getPlayer(); == PsHubCore.getInstance().getConfig().getInt("gui.player-menu.item.location")) {
if (!player.hasPermission("hubcore.player-menu")) {
ChatUtil.sendMessage(player, instance.getConfig().getString("messages.no-permission"));
return;
}
if (player.getInventory().getHeldItemSlot() == PSHubCore.getInstance().getConfig().getInt("gui.selector.item.location") || PlayerMenuGui.openGui(player);
player.getInventory().getHeldItemSlot() == PSHubCore.getInstance().getConfig().getInt("gui.player-menu.item.location")) { event.setCancelled(true);
event.setCancelled(true);
}
} }
}
/**
* Prevents player from moving items in their inventory.
*
* @param event The event.
*/
@EventHandler
public void inventory(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof final Player player)) {
return;
}
final var inventoryType = event.getInventory().getType();
final var selectorItemSlot =
PsHubCore.getInstance().getConfig().getInt("gui.selector.item.location");
final var menuItemSlot =
PsHubCore.getInstance().getConfig().getInt("gui.player-menu.item.location");
if (event.getSlot() == selectorItemSlot
&& (inventoryType == InventoryType.PLAYER || inventoryType == InventoryType.CRAFTING)
|| event.getSlot() == menuItemSlot
&& (inventoryType == InventoryType.PLAYER || inventoryType == InventoryType.CRAFTING)) {
if (player.getGameMode() == GameMode.CREATIVE) {
player.closeInventory();
}
event.setCancelled(true);
}
}
/**
* Prevents players from dropping the selector item.
*
* @param event The event.
*/
@EventHandler
public void drop(PlayerDropItemEvent event) {
final var player = event.getPlayer();
if (player.getInventory().getHeldItemSlot()
== PsHubCore.getInstance().getConfig().getInt("gui.selector.item.location")
|| player.getInventory().getHeldItemSlot()
== PsHubCore.getInstance().getConfig().getInt("gui.player-menu.item.location")
) {
event.setCancelled(true);
}
}
} }

View File

@ -1,25 +1,34 @@
package os.arcadiadevs.playerservers.hubcore.events; package os.arcadiadevs.playerservers.hubcore.events;
import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.weather.WeatherChangeEvent; import org.bukkit.event.weather.WeatherChangeEvent;
import os.arcadiadevs.playerservers.hubcore.PSHubCore; import os.arcadiadevs.playerservers.hubcore.PsHubCore;
public class HubEvents implements Listener { public class HubEvents implements Listener {
@EventHandler private final Configuration config;
public void weatherChange(WeatherChangeEvent e) {
if (PSHubCore.getInstance().getConfig().getBoolean("miscellaneous.disable-weather")) {
e.setCancelled(true);
}
}
@EventHandler public HubEvents(FileConfiguration config) {
public void entityDamage(EntityDamageEvent e) { this.config = config;
if (e.getEntity() instanceof Player && PSHubCore.getInstance().getConfig().getBoolean("miscellaneous.disable-damage")) }
e.setCancelled(true);
@EventHandler
public void weatherChange(WeatherChangeEvent e) {
if (config.getBoolean("miscellaneous.disable-weather")) {
e.setCancelled(true);
} }
}
@EventHandler
public void entityDamage(EntityDamageEvent e) {
if (e.getEntity() instanceof Player && config.getBoolean("miscellaneous.disable-damage")) {
e.setCancelled(true);
}
}
} }

View File

@ -6,73 +6,83 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import os.arcadiadevs.playerservers.hubcore.PSHubCore; import os.arcadiadevs.playerservers.hubcore.PsHubCore;
import os.arcadiadevs.playerservers.hubcore.utils.ChatUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import os.arcadiadevs.playerservers.hubcore.utils.ChatUtil;
public class JoinEvent implements Listener { public class JoinEvent implements Listener {
final PSHubCore PSH = PSHubCore.getInstance(); private final PsHubCore instance;
@EventHandler public JoinEvent(PsHubCore instance) {
public void onJoin(PlayerJoinEvent e) { this.instance = instance;
}
final var selectorConfigMaterial = PSH.getConfig().getString("gui.selector.item.material"); @EventHandler
final var menuConfigMaterial = PSH.getConfig().getString("gui.player-menu.item.material"); public void onJoin(PlayerJoinEvent e) {
final var selectorMaterial = XMaterial.matchXMaterial(selectorConfigMaterial).orElse(XMaterial.COMPASS).parseMaterial();
final var menuMaterial = XMaterial.matchXMaterial(menuConfigMaterial).orElse(XMaterial.EMERALD).parseMaterial();
final var player = e.getPlayer();
if (!PSH.getConfig().getBoolean("gui.selector.item.enabled")) { final var selectorConfigMaterial = instance.getConfig().getString("gui.selector.item.material");
player.getInventory().forEach(item -> { final var menuConfigMaterial = instance.getConfig().getString("gui.player-menu.item.material");
if (item != null && item.getType() == selectorMaterial) { final var selectorMaterial =
player.getInventory().remove(item); XMaterial.matchXMaterial(selectorConfigMaterial).orElse(XMaterial.COMPASS).parseMaterial();
} final var menuMaterial =
}); XMaterial.matchXMaterial(menuConfigMaterial).orElse(XMaterial.EMERALD).parseMaterial();
final var player = e.getPlayer();
if (!instance.getConfig().getBoolean("gui.selector.item.enabled")) {
player.getInventory().forEach(item -> {
if (item != null && item.getType() == selectorMaterial) {
player.getInventory().remove(item);
} }
});
if (!PSH.getConfig().getBoolean("gui.player-menu.item.enabled")) {
player.getInventory().forEach(item -> {
if (item != null && item.getType() == menuMaterial) {
player.getInventory().remove(item);
}
});
}
new Thread(() -> {
final var selectorItemStack = new ItemStack(selectorMaterial);
final var menuItemStack = new ItemStack(menuMaterial);
final var selectorItemMeta = selectorItemStack.getItemMeta();
final var menuItemMeta = menuItemStack.getItemMeta();
selectorItemMeta.setDisplayName(ChatUtil.translate(PSH.getConfig().getString("gui.selector.item.name")));
menuItemMeta.setDisplayName(ChatUtil.translate(PSH.getConfig().getString("gui.player-menu.item.name")));
final List<String> lore = PSH.getConfig().getStringList("gui.selector.item.description")
.stream()
.map(ChatUtil::translate)
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
final List<String> lore1 = PSH.getConfig().getStringList("gui.player-menu.item.description")
.stream()
.map(ChatUtil::translate)
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
selectorItemMeta.setLore(lore);
menuItemMeta.setLore(lore1);
selectorItemStack.setItemMeta(selectorItemMeta);
menuItemStack.setItemMeta(menuItemMeta);
if (PSH.getConfig().getBoolean("gui.selector.item.enabled")) {
Bukkit.getScheduler().runTask(PSH, () -> player.getInventory().setItem(PSH.getConfig().getInt("gui.selector.item.location"), selectorItemStack));
}
if (PSH.getConfig().getBoolean("gui.player-menu.item.enabled")) {
Bukkit.getScheduler().runTask(PSH, () -> player.getInventory().setItem(PSH.getConfig().getInt("gui.player-menu.item.location"), menuItemStack));
}
}).start();
} }
if (!instance.getConfig().getBoolean("gui.player-menu.item.enabled")) {
player.getInventory().forEach(item -> {
if (item != null && item.getType() == menuMaterial) {
player.getInventory().remove(item);
}
});
}
new Thread(() -> {
final var selectorItemStack = new ItemStack(selectorMaterial);
final var menuItemStack = new ItemStack(menuMaterial);
final var selectorItemMeta = selectorItemStack.getItemMeta();
final var menuItemMeta = menuItemStack.getItemMeta();
selectorItemMeta.setDisplayName(
ChatUtil.translate(instance.getConfig().getString("gui.selector.item.name")));
menuItemMeta.setDisplayName(
ChatUtil.translate(instance.getConfig().getString("gui.player-menu.item.name")));
final List<String> lore = instance.getConfig().getStringList("gui.selector.item.description")
.stream()
.map(ChatUtil::translate)
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
final List<String> lore1 = instance.getConfig().getStringList("gui.player-menu.item.description")
.stream()
.map(ChatUtil::translate)
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
selectorItemMeta.setLore(lore);
menuItemMeta.setLore(lore1);
selectorItemStack.setItemMeta(selectorItemMeta);
menuItemStack.setItemMeta(menuItemMeta);
if (instance.getConfig().getBoolean("gui.selector.item.enabled")) {
Bukkit.getScheduler().runTask(instance, () -> player.getInventory()
.setItem(instance.getConfig().getInt("gui.selector.item.location"), selectorItemStack));
}
if (instance.getConfig().getBoolean("gui.player-menu.item.enabled")) {
Bukkit.getScheduler().runTask(instance, () -> player.getInventory()
.setItem(instance.getConfig().getInt("gui.player-menu.item.location"), menuItemStack));
}
}).start();
}
} }

View File

@ -0,0 +1,227 @@
package os.arcadiadevs.playerservers.hubcore.guis;
import com.cryptomorin.xseries.XMaterial;
import com.cryptomorin.xseries.XSound;
import com.samjakob.spigui.buttons.SGButton;
import com.samjakob.spigui.item.ItemBuilder;
import java.util.ArrayList;
import org.bukkit.entity.Player;
import os.arcadiadevs.playerservers.hubcore.PsHubCore;
import os.arcadiadevs.playerservers.hubcore.enums.PowerAction;
import os.arcadiadevs.playerservers.hubcore.enums.ServerStatus;
import os.arcadiadevs.playerservers.hubcore.models.Server;
import os.arcadiadevs.playerservers.hubcore.utils.BungeeUtil;
import os.arcadiadevs.playerservers.hubcore.utils.ChatUtil;
import os.arcadiadevs.playerservers.hubcore.utils.GuiUtils;
public class PlayerMenuGui {
public static void openGui(Player player) {
final var instance = PsHubCore.getInstance();
final var serversController = instance.getServersController();
if (!serversController.hasServer(player)) {
final var menu = instance.getSpiGui().create(
ChatUtil.translate(instance.getConfig().getString("gui.player-menu.menu.name")), 3);
menu.setAutomaticPaginationEnabled(false);
menu.setBlockDefaultInteractions(true);
for (int i = 0; i < 9 * 4; i++) {
menu.setButton(
i,
new SGButton(new ItemBuilder(XMaterial.GRAY_STAINED_GLASS_PANE.parseItem()).build())
);
}
var itemCreate = new ItemBuilder(XMaterial.DIAMOND_BLOCK.parseMaterial())
.name(instance.getConfig().getString("gui.player-menu.menu.create.name"))
.lore(instance.getConfig().getStringList("gui.player-menu.menu.create.lore"))
.build();
menu.setButton(0, 13, new SGButton(itemCreate).withListener(
listener -> {
BungeeUtil.createServer(player);
XSound.ENTITY_EXPERIENCE_ORB_PICKUP.play(player);
}));
player.openInventory(menu.getInventory());
return;
}
final var rows = 5;
final var menu = instance.getSpiGui()
.create(ChatUtil.translate(instance.getConfig().getString("gui.player-menu.menu.name")),
rows);
menu.setAutomaticPaginationEnabled(false);
menu.setBlockDefaultInteractions(true);
GuiUtils.addBorder(menu, rows);
final var server = serversController.getServer(player);
if (server == null) {
player.sendMessage(ChatUtil.translate("&9Error> &cCould not find your server!"));
return;
}
final var online = server.getStatus() == ServerStatus.ONLINE;
var lore = instance.getConfig().getStringList(online
? "gui.player-menu.menu.info.online.lore"
: "gui.player-menu.menu.info.offline.lore"
);
lore = lore.stream()
.map(s -> s.replaceAll("%server%", server.getId()))
.map(s -> s.replaceAll("%status%", online ? "&aOnline" : "&cOffline"))
.map(s -> s.replaceAll("%players%", online ? server.getInfo().players() + "" : "0"))
.map(s -> s.replaceAll("%maxplayers%", online ? server.getInfo().maxPlayers() + "" : "0"))
.map(s -> s.replaceAll("%port%", server.getPort() + ""))
.map(s -> s.replaceAll("%motd%", online ? server.getInfo().motd() : "&cOffline"))
.map(s -> s.replaceAll("%node%", server.getNode().getName()))
.map(s -> s.replaceAll("%owner%", server.getOfflinePlayer().getName()))
.map(s -> s.replaceAll("%ip%", server.getNode().getIp()))
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
final var itemPlayer = new SGButton(
new ItemBuilder(XMaterial.PLAYER_HEAD.parseMaterial())
.name(ChatUtil.translate(instance.getConfig().getString(online
? "gui.player-menu.menu.info.online.name"
: "gui.player-menu.menu.info.offline.name")
.replaceAll("%server%", server.getId())))
.skullOwner(player.getName())
.lore(lore)
.build()
);
final var itemDelete = new SGButton(new ItemBuilder(XMaterial.BARRIER.parseMaterial())
.name(ChatUtil.translate(
instance.getConfig().getString("gui.player-menu.menu.delete.name")))
.lore(instance.getConfig().getStringList("gui.player-menu.menu.delete.lore"))
.build())
.withListener(listener -> openDeleteConfirmation(player, server));
if (online) {
final var itemJoin = new SGButton(new ItemBuilder(XMaterial.DARK_OAK_DOOR.parseItem())
.name(ChatUtil.translate(
instance.getConfig().getString("gui.player-menu.menu.join.name")))
.lore(instance.getConfig().getStringList("gui.player-menu.menu.join.lore"))
.build())
.withListener(listener -> server.connect());
final var itemStop = new SGButton(new ItemBuilder(XMaterial.RED_TERRACOTTA.parseItem())
.name(ChatUtil.translate(
instance.getConfig().getString("gui.player-menu.menu.stop.name")))
.lore(instance.getConfig().getStringList("gui.player-menu.menu.stop.lore"))
.build())
.withListener(listener -> openStopConfirmation(player, server));
menu.setButton(22, itemJoin);
menu.setButton(20, itemStop);
}
if (!online) {
final var itemStart = new SGButton(new ItemBuilder(XMaterial.GREEN_TERRACOTTA.parseItem())
.name(ChatUtil.translate(
instance.getConfig().getString("gui.player-menu.menu.start.name")))
.lore(instance.getConfig().getStringList("gui.player-menu.menu.start.lore"))
.build())
.withListener(listener -> server.executePowerAction(PowerAction.START));
menu.setButton(20, itemStart);
}
menu.setButton(0, 24, itemDelete);
menu.setButton(0, 4, itemPlayer);
XSound.BLOCK_NOTE_BLOCK_BASS.play(player);
player.openInventory(menu.getInventory());
}
public static void openDeleteConfirmation(Player player, Server server) {
XSound.BLOCK_NOTE_BLOCK_BASS.play(player);
final var instance = PsHubCore.getInstance();
final var deleteConfirmationMenu = instance.getSpiGui().create(ChatUtil.translate(
instance.getConfig().getString("gui.player-menu.menu.delete.confirmation.name")), 3);
deleteConfirmationMenu.setAutomaticPaginationEnabled(false);
deleteConfirmationMenu.setBlockDefaultInteractions(true);
final var yesButton = new SGButton(new ItemBuilder(XMaterial.GREEN_TERRACOTTA.parseItem())
.name(ChatUtil.translate(
instance.getConfig()
.getString("gui.player-menu.menu.delete.confirmation.accept.name")))
.lore(
instance.getConfig()
.getStringList("gui.player-menu.menu.delete.confirmation.accept.lore"))
.build())
.withListener(listener2 -> {
XSound.ENTITY_EXPERIENCE_ORB_PICKUP.play(player);
server.delete();
player.closeInventory();
});
final var noButton = new SGButton(new ItemBuilder(XMaterial.RED_TERRACOTTA.parseItem())
.name(ChatUtil.translate(
instance.getConfig()
.getString("gui.player-menu.menu.delete.confirmation.decline.name")))
.lore(instance.getConfig()
.getStringList("gui.player-menu.menu.delete.confirmation.decline.lore"))
.build())
.withListener(listener -> {
player.closeInventory();
XSound.BLOCK_NOTE_BLOCK_BASS.play(player);
});
deleteConfirmationMenu.setButton(0, 11, yesButton);
deleteConfirmationMenu.setButton(0, 15, noButton);
player.openInventory(deleteConfirmationMenu.getInventory());
}
public static void openStopConfirmation(Player player, Server server) {
final var instance = PsHubCore.getInstance();
final var stopConfirmationMenu = instance.getSpiGui().create(ChatUtil.translate(
instance.getConfig().getString("gui.player-menu.menu.stop.confirmation.name")), 3);
stopConfirmationMenu.setAutomaticPaginationEnabled(false);
stopConfirmationMenu.setBlockDefaultInteractions(true);
final var yesButton = new SGButton(new ItemBuilder(XMaterial.GREEN_TERRACOTTA.parseItem())
.name(ChatUtil.translate(
instance.getConfig().getString("gui.player-menu.menu.stop.confirmation.accept.name")))
.lore(instance.getConfig()
.getStringList("gui.player-menu.menu.stop.confirmation.accept.lore"))
.build())
.withListener(listener2 -> {
XSound.ENTITY_EXPERIENCE_ORB_PICKUP.play(player);
server.executePowerAction(PowerAction.STOP);
player.closeInventory();
});
final var noButton = new SGButton(new ItemBuilder(XMaterial.RED_TERRACOTTA.parseItem())
.name(ChatUtil.translate(
instance.getConfig()
.getString("gui.player-menu.menu.stop.confirmation.decline.name")))
.lore(
instance.getConfig()
.getStringList("gui.player-menu.menu.stop.confirmation.decline.lore"))
.build())
.withListener(listener -> {
XSound.BLOCK_NOTE_BLOCK_BASS.play(player);
player.closeInventory();
});
stopConfirmationMenu.setButton(0, 11, yesButton);
stopConfirmationMenu.setButton(0, 15, noButton);
player.openInventory(stopConfirmationMenu.getInventory());
}
}

View File

@ -0,0 +1,80 @@
package os.arcadiadevs.playerservers.hubcore.guis;
import com.cryptomorin.xseries.XMaterial;
import com.samjakob.spigui.buttons.SGButton;
import com.samjakob.spigui.item.ItemBuilder;
import java.util.ArrayList;
import org.bukkit.entity.Player;
import os.arcadiadevs.playerservers.hubcore.PsHubCore;
import os.arcadiadevs.playerservers.hubcore.enums.ServerStatus;
import os.arcadiadevs.playerservers.hubcore.utils.BungeeUtil;
import os.arcadiadevs.playerservers.hubcore.utils.ChatUtil;
public class SelectorGui {
public static void openGui(Player player) {
final var instance = PsHubCore.getInstance();
final var menu = instance.getSpiGui()
.create(ChatUtil.translate(instance.getConfig().getString("gui.selector.menu.name")), 5);
menu.setAutomaticPaginationEnabled(true);
menu.setBlockDefaultInteractions(true);
final var onlinexMaterial =
XMaterial.matchXMaterial(instance.getConfig().getString("gui.selector.menu.online.block"))
.orElse(XMaterial.PLAYER_HEAD).parseMaterial();
final var offlinexMaterial =
XMaterial.matchXMaterial(instance.getConfig().getString("gui.selector.menu.offline.block"))
.orElse(XMaterial.RED_TERRACOTTA).parseMaterial();
final var servers = PsHubCore.getInstance()
.getServersController()
.getServers();
servers.forEach(server -> {
final var itemBuilder = new ItemBuilder(
server.getStatus() == ServerStatus.ONLINE ? onlinexMaterial : offlinexMaterial);
final var online = server.getStatus() == ServerStatus.ONLINE;
var lore = instance.getConfig().getStringList(
server.getStatus() == ServerStatus.ONLINE ? "gui.selector.menu.online.lore" :
"gui.selector.menu.offline.lore");
lore = lore.stream()
.map(s -> s.replaceAll("%server%", server.getId()))
.map(s -> s.replaceAll("%status%", online ? "&aOnline" : "&cOffline"))
.map(s -> s.replaceAll("%players%", online ? server.getInfo().players() + "" : "0"))
.map(s -> s.replaceAll("%maxplayers%", online ? server.getInfo().maxPlayers() + "" : "0"))
.map(s -> s.replaceAll("%port%", server.getPort() + ""))
.map(s -> s.replaceAll("%motd%", online ? server.getInfo().motd() : "&cOffline"))
.map(s -> s.replaceAll("%node%", server.getNode().getName()))
.map(s -> s.replaceAll("%owner%", server.getOfflinePlayer().getName()))
.map(s -> s.replaceAll("%ip%", server.getNode().getIp()))
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
var item = itemBuilder
.name(ChatUtil.translate(instance.getConfig().getString(
online ? "gui.selector.menu.online.name" : "gui.selector.menu.offline.name")
.replaceAll("%server%", server.getId())
.replaceAll("%status%", online ? "&aOnline" : "&cOffline")
.replaceAll("%players%", online ? server.getInfo().players() + "" : "0")
.replaceAll("%maxplayers%", online ? server.getInfo().maxPlayers() + "" : "0")
.replaceAll("%port%", server.getPort() + "")
.replaceAll("%motd%", online ? server.getInfo().motd() : "&cOffline")
.replaceAll("%node%", server.getNode().getName())
.replaceAll("%owner%", server.getOfflinePlayer().getName())
.replaceAll("%ip%", server.getNode().getIp())
))
.lore(lore)
.build();
menu.setButton(0, menu.getInventory().firstEmpty(), new SGButton(item).withListener(
listener -> BungeeUtil.connectPlayer(player)));
});
player.openInventory(menu.getInventory());
}
}

View File

@ -0,0 +1,79 @@
package os.arcadiadevs.playerservers.hubcore.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.net.InetSocketAddress;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
/**
* The node object.
*
* @author ArcadiaDevs
*/
@Entity
@Table(name = "nodes")
@Getter
@Setter
public class Node {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "name")
private String name;
@Column(name = "ip")
private String ip;
@Column(name = "port")
private int port;
@Column(name = "min_port")
private int minPort;
@Column(name = "max_port")
private int maxPort;
@Column(name = "max_servers")
private short maxServers;
@Column(name = "token")
private String token;
@Column(name = "servers")
@OneToMany(mappedBy = "node", fetch = FetchType.EAGER)
private List<Server> servers;
/**
* Get the full address of the server as ip:port.
*
* @return The full address
*/
public String getFullAddress() {
return this.ip + ":" + this.port;
}
/**
* Get the address of the node as InetSocketAddress.
*
* @return The address
*/
public InetSocketAddress getInetAddress() {
return new InetSocketAddress(this.ip, this.port);
}
public String getNumericAddress() {
return getIp().replaceAll("localhost", "127.0.0.1");
}
}

View File

@ -0,0 +1,140 @@
package os.arcadiadevs.playerservers.hubcore.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import os.arcadiadevs.playerservers.hubcore.enums.PowerAction;
import os.arcadiadevs.playerservers.hubcore.enums.ServerStatus;
import os.arcadiadevs.playerservers.hubcore.utils.BungeeUtil;
import os.arcadiadevs.playerservers.hubcore.utils.ServerPinger;
/**
* The model of a server.
*
* @author ArcadiaDevs
*/
@Entity
@Table(name = "servers")
@Getter
@Setter
public class Server {
@Id
@Column(name = "id")
private String id;
@Column(name = "owner")
private UUID owner;
@Column(name = "port")
private Integer port;
@ManyToOne
@JoinColumn(name = "node", nullable = false)
private Node node;
public String getFullAddress() {
return (this.node.getIp() + ":" + this.port)
.replaceAll("localhost", "127.0.0.1");
}
/**
* Gets the owner of the server as a OfflinePlayer.
*
* @return The owner of the server
*/
public OfflinePlayer getOfflinePlayer() {
return Bukkit.getOfflinePlayer(owner);
}
/**
* Gets the owner of the server as a player.
*
* @return The owner of the server
*/
public Player getPlayer() {
return Bukkit.getPlayer(owner);
}
public void connect() {
BungeeUtil.connectPlayer(getPlayer());
}
/**
* Gets the InetSocketAddress of the server.
*
* @return The InetSocketAddress
*/
public InetSocketAddress getInetAddress() {
return new InetSocketAddress(this.node.getIp(), this.port);
}
/**
* Gets the status of the server.
*
* @return The status of the server
*/
public ServerStatus getStatus() {
final var address = node.getNumericAddress();
var status = ServerStatus.UNKNOWN;
try {
Socket s = new Socket(address, port);
if (s.isConnected()) {
status = ServerStatus.ONLINE;
}
s.close();
} catch (IOException ignored) {
status = ServerStatus.OFFLINE;
}
return status;
}
/**
* Gets the MOTD and player count of the server.
*
* @return The status of the server
*/
public ServerPinger.PingResult getInfo() {
try {
return ServerPinger.ping(this.getInetAddress(), 1000).get();
} catch (InterruptedException | ExecutionException e) {
return null;
}
}
/**
* Execute a power action on the server.
*
* @param action The action to execute
*/
public void executePowerAction(PowerAction action) {
switch (action) {
case START -> BungeeUtil.startServer(getPlayer());
case STOP -> BungeeUtil.stopServer(getPlayer());
default -> throw new IllegalStateException("Unexpected value: " + action);
}
}
/**
* Deletes the server.
*/
public void delete() {
BungeeUtil.deleteServer(getPlayer());
}
}

View File

@ -1,36 +0,0 @@
package os.arcadiadevs.playerservers.hubcore.objects;
import lombok.Getter;
@Getter
public class Node {
private String name;
private String hostname;
private String token;
private int port;
public String getFullAddress() {
return hostname + ":" + port;
}
public Node setName(String name) {
this.name = name;
return this;
}
public Node setHostname(String hostname) {
this.hostname = hostname;
return this;
}
public Node setToken(String token) {
this.token = token;
return this;
}
public Node setPort(int port) {
this.port = port;
return this;
}
}

View File

@ -1,26 +0,0 @@
package os.arcadiadevs.playerservers.hubcore.objects;
public class PingInfoStructure {
private final int online;
private final int max;
private final String MOTD;
public PingInfoStructure(int online, int max, String MOTD) {
this.online = online;
this.max = max;
this.MOTD = MOTD;
}
public int getMax() {
return max;
}
public int getOnline() {
return online;
}
public String getMOTD() {
return MOTD;
}
}

View File

@ -1,137 +0,0 @@
package os.arcadiadevs.playerservers.hubcore.objects;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import org.bukkit.entity.Player;
import os.arcadiadevs.playerservers.hubcore.PSHubCore;
import os.arcadiadevs.playerservers.hubcore.database.DataBase;
import os.arcadiadevs.playerservers.hubcore.enums.ServerStatus;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicBoolean;
@Getter
public class Server {
private String serverId;
private String playerName;
private String node;
private Integer port;
@Setter private PingInfoStructure cachedData;
@Setter private ServerStatus cachedStatus;
public String getShortId() {
return serverId.split("-")[0];
}
public Server() {}
@SneakyThrows
public Server(Player player) {
final var server = DataBase.getServer(player).get();
this.serverId = server.getServerId();
this.playerName = server.getPlayerName();
this.node = server.getNode();
this.port = server.getPort();
}
@SuppressWarnings("ResultOfMethodCallIgnored")
public ServerStatus getServerStatus() {
AtomicBoolean isOnline = new AtomicBoolean(false);
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(1);
executor.execute(() -> {
try {
Socket socket = new Socket(getHostname(), port);
isOnline.set(true);
socket.close();
} catch (IOException e) {
isOnline.set(false);
}
});
try {
Thread.sleep(200);
executor.shutdown();
executor.awaitTermination(1, java.util.concurrent.TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return isOnline.get() ? ServerStatus.ONLINE : ServerStatus.OFFLINE;
}
public Node getNodeObject() {
final var config = PSHubCore
.getInstance()
.getMultinode()
.getConfigurationSection("nodes." + this.node);
return new Node()
.setName(this.node)
.setHostname(config.getString("host"))
.setToken(config.getString("token"))
.setPort(config.getInt("port"));
}
public PingInfoStructure getData() {
try (Socket sock = new Socket(getHostname(), port)) {
DataOutputStream out = new DataOutputStream(sock.getOutputStream());
DataInputStream in = new DataInputStream(sock.getInputStream());
out.write(0xFE);
int b;
StringBuilder str = new StringBuilder();
while ((b = in.read()) != -1) {
if (b > 16 && b != 255 && b != 23 && b != 24) {
str.append((char) b);
}
}
String[] data = str.toString().split("§");
String serverMotd = data[0];
int onlinePlayers = Integer.parseInt(data[1]);
int maxPlayers = Integer.parseInt(data[2]);
return new PingInfoStructure(onlinePlayers, maxPlayers, serverMotd);
} catch (IOException e) {
return null;
}
}
public String getHostname() {
return node.equalsIgnoreCase("local") ? "localhost" : getNodeObject().getHostname();
}
public Server setServerId(String serverId) {
this.serverId = serverId;
return this;
}
public Server setPlayerName(String playerName) {
this.playerName = playerName;
return this;
}
public Server setNode(String node) {
this.node = node;
return this;
}
public Server setPort(int port) {
this.port = port;
return this;
}
}

View File

@ -1,48 +0,0 @@
package os.arcadiadevs.playerservers.hubcore.objects;
import lombok.Getter;
import lombok.Setter;
import os.arcadiadevs.playerservers.hubcore.database.DataBase;
import os.arcadiadevs.playerservers.hubcore.enums.ServerStatus;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class ServerCache implements Runnable {
@Getter @Setter
private List<Server> servers;
@Override
public void run() {
final List<Server> servers;
try {
servers = DataBase.getServersInfo().get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
return;
}
servers.forEach(server -> {
server.setCachedData(server.getData());
server.setCachedStatus(server.getServerStatus());
});
servers.sort((s1, s2) -> {
final var p1 = s1.getServerStatus() == ServerStatus.ONLINE;
final var p2 = s2.getServerStatus() == ServerStatus.ONLINE;
if (p1 && !p2) {
return -1;
} else if (!p1 && p2) {
return 1;
} else {
return 0;
}
});
setServers(servers);
}
}

View File

@ -3,62 +3,59 @@ package os.arcadiadevs.playerservers.hubcore.placeholders;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.plugin.Plugin; import os.arcadiadevs.playerservers.hubcore.controllers.ServersController;
import os.arcadiadevs.playerservers.hubcore.database.DataBase;
import os.arcadiadevs.playerservers.hubcore.enums.ServerStatus; import os.arcadiadevs.playerservers.hubcore.enums.ServerStatus;
import os.arcadiadevs.playerservers.hubcore.objects.Server;
public class PlayerCount extends PlaceholderExpansion { public class PlayerCount extends PlaceholderExpansion {
Plugin plugin; private final ServersController controller;
public PlayerCount(Plugin plugin){ public PlayerCount(ServersController controller) {
this.plugin = plugin; this.controller = controller;
} }
@Override @Override
public boolean canRegister() { public boolean canRegister() {
return true; return true;
} }
@Override @Override
public String getIdentifier() { public String getIdentifier() {
return "playerservers"; return "playerservers";
} }
@Override @Override
public String getName() { public String getName() {
return "placeholders"; return "placeholders";
} }
@Override @Override
public String getAuthor() { public String getAuthor() {
return "OpenSource/Cuftica"; return "OpenSource/Cuftica";
} }
@Override @Override
public String getVersion() { public String getVersion() {
return "1.0.0"; return "1.0.0";
} }
@SneakyThrows @SneakyThrows
@Override @Override
public String onRequest(OfflinePlayer p, String params) { public String onRequest(OfflinePlayer player, String params) {
switch (params) { return switch (params) {
case "online": case "online" -> {
final var server = new Server(p.getPlayer()); final var server = controller.getServer(player.getUniqueId());
return server.getServerStatus() == ServerStatus.ONLINE ? "Online" : "Offline"; yield server.getStatus() == ServerStatus.ONLINE ? "Online" : "Offline";
case "serveronline": }
final var online = (int) DataBase case "serveronline" -> {
.getServersInfo() final var online = (int) controller.getServers()
.get() .stream()
.stream() .filter(server -> server.getStatus() == ServerStatus.ONLINE)
.filter(_server -> _server.getServerStatus() == ServerStatus.ONLINE) .count();
.count();
return String.valueOf(online); yield String.valueOf(online);
} }
default -> throw new IllegalArgumentException("Invalid placeholder: " + params);
return null; };
} }
} }

View File

@ -5,82 +5,70 @@ import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams; import com.google.common.io.ByteStreams;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import os.arcadiadevs.playerservers.hubcore.PSHubCore; import os.arcadiadevs.playerservers.hubcore.PsHubCore;
@SuppressWarnings("UnstableApiUsage") @SuppressWarnings("UnstableApiUsage")
public class BungeeUtil { public class BungeeUtil {
public static void connectPlayer(InventoryClickEvent event, Player player, String server) { public static void connectPlayer(Player player) {
if (event.getCurrentItem().getType() == XMaterial.REDSTONE_BLOCK.parseMaterial()) { ByteArrayDataOutput out = ByteStreams.newDataOutput();
player.sendMessage(ChatUtil.translate("&9PlayerServers> &7Oops, the server you tried to connect to is offline."));
return;
}
ByteArrayDataOutput out = ByteStreams.newDataOutput(); try {
out.writeUTF("Connect");
try { } catch (Exception e) {
out.writeUTF("Connect"); e.printStackTrace();
out.writeUTF(server);
} catch (Exception e) {
e.printStackTrace();
}
player.sendPluginMessage(PSHubCore.getInstance(), "BungeeCord", out.toByteArray());
event.getWhoClicked().closeInventory();
} }
public static void stopServer(InventoryClickEvent event, Player player, String server) { player.sendPluginMessage(PsHubCore.getInstance(), "BungeeCord", out.toByteArray());
player.closeInventory();
}
ByteArrayDataOutput out = ByteStreams.newDataOutput(); public static void stopServer(Player player) {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
try { try {
out.writeUTF("stop"); out.writeUTF("stop");
out.writeUTF(server); } catch (Exception e) {
} catch (Exception e) { e.printStackTrace();
e.printStackTrace();
}
player.sendPluginMessage(PSHubCore.getInstance(), "BungeeCord", out.toByteArray());
event.getWhoClicked().closeInventory();
} }
player.sendPluginMessage(PsHubCore.getInstance(), "BungeeCord", out.toByteArray());
player.closeInventory();
}
public static void deleteServer(InventoryClickEvent event, Player player, String server) { public static void deleteServer(Player player) {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
ByteArrayDataOutput out = ByteStreams.newDataOutput(); try {
out.writeUTF("delete");
try { } catch (Exception e) {
out.writeUTF("delete"); e.printStackTrace();
out.writeUTF(server);
} catch (Exception e) {
e.printStackTrace();
}
player.sendPluginMessage(PSHubCore.getInstance(), "BungeeCord", out.toByteArray());
event.getWhoClicked().closeInventory();
} }
player.sendPluginMessage(PsHubCore.getInstance(), "BungeeCord", out.toByteArray());
player.closeInventory();
}
public static void createServer(InventoryClickEvent event, Player player, String server) { public static void createServer(Player player) {
ByteArrayDataOutput out = ByteStreams.newDataOutput(); ByteArrayDataOutput out = ByteStreams.newDataOutput();
try { try {
out.writeUTF("create"); out.writeUTF("create");
out.writeUTF(server); } catch (Exception e) {
} catch (Exception e) { e.printStackTrace();
e.printStackTrace();
}
player.sendPluginMessage(PSHubCore.getInstance(), "BungeeCord", out.toByteArray());
event.getWhoClicked().closeInventory();
} }
player.sendPluginMessage(PsHubCore.getInstance(), "BungeeCord", out.toByteArray());
player.closeInventory();
}
public static void startServer(InventoryClickEvent event, Player player, String server) { public static void startServer(Player player) {
ByteArrayDataOutput out = ByteStreams.newDataOutput(); ByteArrayDataOutput out = ByteStreams.newDataOutput();
try { try {
out.writeUTF("start"); out.writeUTF("start");
out.writeUTF(server); } catch (Exception e) {
} catch (Exception e) { e.printStackTrace();
e.printStackTrace();
}
player.sendPluginMessage(PSHubCore.getInstance(), "BungeeCord", out.toByteArray());
event.getWhoClicked().closeInventory();
} }
player.sendPluginMessage(PsHubCore.getInstance(), "BungeeCord", out.toByteArray());
player.closeInventory();
}
} }

View File

@ -1,11 +1,22 @@
package os.arcadiadevs.playerservers.hubcore.utils; package os.arcadiadevs.playerservers.hubcore.utils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
public class ChatUtil { public class ChatUtil {
public static String translate(String text) { public static String translate(String s) {
return ChatColor.translateAlternateColorCodes('&', text); return ChatColor.translateAlternateColorCodes('&', s);
}
public static void sendMessage(CommandSender sender, String message) {
sender.sendMessage(translate(message));
}
public static void sendMessage(CommandSender sender, String... message) {
for (String s : message) {
sender.sendMessage(translate(s));
} }
}
} }

View File

@ -1,238 +0,0 @@
package os.arcadiadevs.playerservers.hubcore.utils;
import com.cryptomorin.xseries.XMaterial;
import com.samjakob.spigui.buttons.SGButton;
import com.samjakob.spigui.item.ItemBuilder;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import os.arcadiadevs.playerservers.hubcore.PSHubCore;
import os.arcadiadevs.playerservers.hubcore.database.DataBase;
import os.arcadiadevs.playerservers.hubcore.enums.ServerStatus;
import java.util.ArrayList;
public class GUIUtils {
public static void openSelector(Player player) {
final var PSH = PSHubCore.getInstance();
final var menu = PSH.getSpiGUI().create(ChatUtil.translate(PSH.getConfig().getString("gui.selector.menu.name")), 5);
menu.setAutomaticPaginationEnabled(true);
menu.setBlockDefaultInteractions(true);
final var onlineXMaterialOptional = XMaterial.matchXMaterial(PSH.getConfig().getString("gui.selector.menu.online.block"));
final var offlineXMaterialOptional = XMaterial.matchXMaterial(PSH.getConfig().getString("gui.selector.menu.offline.block"));
final var onlineXMaterial = onlineXMaterialOptional.orElse(XMaterial.EMERALD_BLOCK).parseMaterial();
final var offlineXMaterial = offlineXMaterialOptional.orElse(XMaterial.REDSTONE_BLOCK).parseMaterial();
new Thread(() -> {
final var servers = PSHubCore.getInstance().getServerCache().getServers();
servers.forEach(server -> {
final var itemBuilder = new ItemBuilder(server.getCachedStatus() == ServerStatus.ONLINE ? onlineXMaterial : offlineXMaterial);
var lore = PSH.getConfig().getStringList(server.getCachedStatus() == ServerStatus.ONLINE ? "gui.selector.menu.online.lore" : "gui.selector.menu.offline.lore");
lore = lore.stream()
.map(s -> s.replaceAll("%server%", server.getPlayerName()))
.map(s -> s.replaceAll("%status%", server.getCachedStatus() == ServerStatus.ONLINE ? "&aOnline" : "&cOffline"))
.map(s -> s.replaceAll("%players%", server.getCachedStatus() == ServerStatus.ONLINE ? server.getCachedData().getOnline() + "" : "0"))
.map(s -> s.replaceAll("%maxplayers%", server.getCachedStatus() == ServerStatus.ONLINE ? server.getCachedData().getMax() + "" : "0"))
.map(s -> s.replaceAll("%port%", server.getPort() + ""))
.map(s -> s.replaceAll("%motd%", server.getCachedStatus() == ServerStatus.ONLINE ? server.getCachedData().getMOTD() : "&cOffline"))
.map(s -> s.replaceAll("%node%", server.getNode()))
.map(s -> s.replaceAll("%owner%", server.getPlayerName()))
.map(s -> s.replaceAll("%ip%", server.getHostname()))
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
var item = itemBuilder
.name(ChatUtil.translate(PSH.getConfig().getString(server.getCachedStatus() == ServerStatus.ONLINE ? "gui.selector.menu.online.name" : "gui.selector.menu.offline.name")
.replaceAll("%server%", server.getPlayerName())
.replaceAll("%status%", server.getCachedStatus() == ServerStatus.ONLINE ? "&aOnline" : "&cOffline"))
.replaceAll("%players%", server.getCachedStatus() == ServerStatus.ONLINE ? server.getCachedData().getOnline() + "" : "0")
.replaceAll("%maxplayers%", server.getCachedStatus() == ServerStatus.ONLINE ? server.getCachedData().getMax() + "" : "0")
.replaceAll("%port%", server.getPort() + "")
.replaceAll("%motd%", server.getCachedStatus() == ServerStatus.ONLINE ? server.getCachedData().getMOTD() : "&cOffline")
.replaceAll("%node%", server.getNode())
.replaceAll("%owner%", server.getPlayerName())
.replaceAll("%ip%", server.getHostname())
)
.lore(lore)
.build();
menu.setButton(0, menu.getInventory().firstEmpty(), new SGButton(item).withListener(listener -> BungeeUtil.connectPlayer(listener, player, server.getPlayerName())));
});
Bukkit.getScheduler().runTask(PSHubCore.getInstance(), () -> player.openInventory(menu.getInventory()));
}).start();
}
public static void openMenu(Player player) {
final var PSH = PSHubCore.getInstance();
new Thread(() -> {
if (!DataBase.containsServer(player.getUniqueId().toString())) {
final var menu = PSH.getSpiGUI().create(ChatUtil.translate(PSH.getConfig().getString("gui.player-menu.menu.name")), 3);
menu.setAutomaticPaginationEnabled(false);
menu.setBlockDefaultInteractions(true);
var itemCreate = new ItemBuilder(XMaterial.DIAMOND_BLOCK.parseMaterial())
.name(PSH.getConfig().getString("gui.player-menu.menu.create.name"))
.lore(PSH.getConfig().getStringList("gui.player-menu.menu.create.lore"))
.build();
menu.setButton(0, 13, new SGButton(itemCreate).withListener(listener -> BungeeUtil.createServer(listener, player, player.getDisplayName())));
for (int i = 0; i < 9 * 4; i++) {
if (menu.getButton(i) == null) {
menu.setButton(i, new SGButton(new ItemBuilder(XMaterial.GRAY_STAINED_GLASS_PANE.parseItem()).name(" ").build()));
}
}
Bukkit.getScheduler().runTask(PSHubCore.getInstance(), () -> player.openInventory(menu.getInventory()));
return;
}
final var menu = PSH.getSpiGUI().create(ChatUtil.translate(PSH.getConfig().getString("gui.player-menu.menu.name")), 4);
menu.setAutomaticPaginationEnabled(false);
menu.setBlockDefaultInteractions(true);
final var deleteConfirmationMenu = PSH.getSpiGUI().create(ChatUtil.translate(PSH.getConfig().getString("gui.player-menu.menu.delete.confirmation.name")), 3);
deleteConfirmationMenu.setAutomaticPaginationEnabled(false);
deleteConfirmationMenu.setBlockDefaultInteractions(true);
final var stopConfirmationMenu = PSH.getSpiGUI().create(ChatUtil.translate(PSH.getConfig().getString("gui.player-menu.menu.stop.confirmation.name")), 3);
stopConfirmationMenu.setAutomaticPaginationEnabled(false);
stopConfirmationMenu.setBlockDefaultInteractions(true);
final var server = PSH
.getServerCache()
.getServers()
.stream()
.filter(_server -> _server.getPlayerName().equals(player.getName()))
.findFirst()
.orElse(null);
if (server == null) {
player.sendMessage(ChatUtil.translate("&9Error> &cCould not find your server!"));
return;
}
var lore = PSH.getConfig().getStringList(server.getCachedStatus() == ServerStatus.ONLINE ? "gui.player-menu.menu.info.online.lore" : "gui.player-menu.menu.info.offline.lore");
lore = lore.stream()
.map(s -> s.replaceAll("%server%", server.getPlayerName()))
.map(s -> s.replaceAll("%status%", server.getCachedStatus() == ServerStatus.ONLINE ? "&aOnline" : "&cOffline"))
.map(s -> s.replaceAll("%players%", server.getCachedStatus() == ServerStatus.ONLINE ? server.getCachedData().getOnline() + "" : "0"))
.map(s -> s.replaceAll("%maxplayers%", server.getCachedStatus() == ServerStatus.ONLINE ? server.getCachedData().getMax() + "" : "0"))
.map(s -> s.replaceAll("%port%", server.getPort() + ""))
.map(s -> s.replaceAll("%motd%", server.getCachedStatus() == ServerStatus.ONLINE ? server.getCachedData().getMOTD() : "&cOffline"))
.map(s -> s.replaceAll("%node%", server.getNode()))
.map(s -> s.replaceAll("%owner%", server.getPlayerName()))
.map(s -> s.replaceAll("%ip%", server.getHostname()))
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
final var itemPlayer = new ItemBuilder(XMaterial.OAK_SIGN.parseMaterial())
.name(ChatUtil.translate(PSH.getConfig().getString(server.getCachedStatus() == ServerStatus.ONLINE ? "gui.player-menu.menu.info.online.name" : "gui.player-menu.menu.info.offline.name")
.replaceAll("%server%", server.getPlayerName())))
.lore(lore)
.build();
final var itemDelete = new ItemBuilder(XMaterial.BARRIER.parseMaterial())
.name(ChatUtil.translate(PSH.getConfig().getString("gui.player-menu.menu.delete.name")))
.lore(PSH.getConfig().getStringList("gui.player-menu.menu.delete.lore"))
.build();
final var itemDeleteQuestionYes = new ItemBuilder(XMaterial.EMERALD_BLOCK.parseMaterial())
.name(ChatUtil.translate(PSH.getConfig().getString("gui.player-menu.menu.delete.confirmation.accept.name")))
.lore(PSH.getConfig().getStringList("gui.player-menu.menu.delete.confirmation.accept.lore"))
.build();
final var itemDeleteQuestionNo = new ItemBuilder(XMaterial.REDSTONE_BLOCK.parseMaterial())
.name(ChatUtil.translate(PSH.getConfig().getString("gui.player-menu.menu.delete.confirmation.decline.name")))
.lore(PSH.getConfig().getStringList("gui.player-menu.menu.delete.confirmation.decline.lore"))
.build();
final var itemStopQuestionYes = new ItemBuilder(XMaterial.EMERALD_BLOCK.parseMaterial())
.name(ChatUtil.translate(PSH.getConfig().getString("gui.player-menu.menu.stop.confirmation.accept.name")))
.lore(PSH.getConfig().getStringList("gui.player-menu.menu.stop.confirmation.accept.lore"))
.build();
final var itemStopQuestionNo = new ItemBuilder(XMaterial.REDSTONE_BLOCK.parseMaterial())
.name(ChatUtil.translate(PSH.getConfig().getString("gui.player-menu.menu.stop.confirmation.decline.name")))
.lore(PSH.getConfig().getStringList("gui.player-menu.menu.stop.confirmation.decline.lore"))
.build();
if (server.getCachedStatus() == ServerStatus.ONLINE) {
final var itemJoin = new ItemBuilder(XMaterial.OAK_DOOR.parseMaterial())
.name(ChatUtil.translate(PSH.getConfig().getString("gui.player-menu.menu.join.name")))
.lore(PSH.getConfig().getStringList("gui.player-menu.menu.join.lore"))
.build();
final var itemStop = new ItemBuilder(XMaterial.REDSTONE_BLOCK.parseMaterial())
.name(ChatUtil.translate(PSH.getConfig().getString("gui.player-menu.menu.stop.name")))
.lore(PSH.getConfig().getStringList("gui.player-menu.menu.stop.lore"))
.build();
menu.setButton(0, 22, new SGButton(itemJoin).withListener(listener -> BungeeUtil.connectPlayer(listener, player, player.getDisplayName())));
menu.setButton(0, 20, new SGButton(itemStop).withListener(listener -> {
stopConfirmationMenu.setButton(0, 11, new SGButton(itemStopQuestionYes).withListener(listener2 -> {
BungeeUtil.stopServer(listener2, player, player.getDisplayName());
player.closeInventory();
}));
stopConfirmationMenu.setButton(0, 15, new SGButton(itemStopQuestionNo).withListener(listener2 -> {
player.closeInventory();
}));
for (int i = 0; i < 9 * 4; i++) {
if (stopConfirmationMenu.getButton(i) == null) {
stopConfirmationMenu.setButton(i, new SGButton(new ItemBuilder(XMaterial.GRAY_STAINED_GLASS_PANE.parseItem()).name(" ").build()));
}
}
player.openInventory(stopConfirmationMenu.getInventory());
}));
}
if (server.getCachedStatus() == ServerStatus.OFFLINE) {
final var itemStart = new ItemBuilder(XMaterial.EMERALD_BLOCK.parseMaterial())
.name(ChatUtil.translate(PSH.getConfig().getString("gui.player-menu.menu.start.name")))
.lore(PSH.getConfig().getStringList("gui.player-menu.menu.start.lore"))
.build();
menu.setButton(0, 20, new SGButton(itemStart).withListener(listener -> BungeeUtil.startServer(listener, player, player.getDisplayName())));
}
menu.setButton(0, 24, new SGButton(itemDelete).withListener(listener -> {
deleteConfirmationMenu.setButton(0, 11, new SGButton(itemDeleteQuestionYes).withListener(listener2 -> {
BungeeUtil.deleteServer(listener2, player, player.getDisplayName());
player.closeInventory();
}));
deleteConfirmationMenu.setButton(0, 15, new SGButton(itemDeleteQuestionNo).withListener(listener2 -> {
player.closeInventory();
}));
for (int i = 0; i < 9 * 4; i++) {
if (deleteConfirmationMenu.getButton(i) == null) {
deleteConfirmationMenu.setButton(i, new SGButton(new ItemBuilder(XMaterial.GRAY_STAINED_GLASS_PANE.parseItem()).name(" ").build()));
}
}
player.openInventory(deleteConfirmationMenu.getInventory());
}));
menu.setButton(0, 4, new SGButton(itemPlayer));
// Fill all empty slots with glass pane
for (int i = 0; i < 9 * 4; i++) {
if (menu.getButton(i) == null) {
menu.setButton(i, new SGButton(new ItemBuilder(XMaterial.GRAY_STAINED_GLASS_PANE.parseItem()).name(" ").build()));
}
}
Bukkit.getScheduler().runTask(PSHubCore.getInstance(), () -> player.openInventory(menu.getInventory()));
}).start();
}
}

View File

@ -0,0 +1,40 @@
package os.arcadiadevs.playerservers.hubcore.utils;
import com.cryptomorin.xseries.XMaterial;
import com.samjakob.spigui.SGMenu;
import com.samjakob.spigui.buttons.SGButton;
import com.samjakob.spigui.item.ItemBuilder;
public class GuiUtils {
public static void addBorder(SGMenu menu, int rows) {
for (int i = 0; i < 9; i++) {
menu.setButton(
i,
new SGButton(new ItemBuilder(XMaterial.WHITE_STAINED_GLASS_PANE.parseItem()).build())
);
}
for (int i = 0; i < rows; i++) {
menu.setButton(
i * 9,
new SGButton(new ItemBuilder(XMaterial.WHITE_STAINED_GLASS_PANE.parseItem()).build())
);
}
for (int i = 0; i < rows; i++) {
menu.setButton(
i * 9 + 8,
new SGButton(new ItemBuilder(XMaterial.WHITE_STAINED_GLASS_PANE.parseItem()).build())
);
}
for (int i = (rows - 1) * 9; i < ((rows - 1) * 9) + 9; i++) {
menu.setButton(
i,
new SGButton(new ItemBuilder(XMaterial.WHITE_STAINED_GLASS_PANE.parseItem()).build())
);
}
}
}

View File

@ -0,0 +1,100 @@
/*
* MIT License.
*
* Copyright (c) 2021 MrMicky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package os.arcadiadevs.playerservers.hubcore.utils;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture;
import os.arcadiadevs.playerservers.hubcore.enums.ServerStatus;
/**
* Simple tool to ping a Minecraft server to get MOTD, online players and max players.
*
* @author MrMicky
*/
public class ServerPinger {
public static CompletableFuture<PingResult> ping(InetSocketAddress address, int timeout) {
return CompletableFuture.supplyAsync(() -> {
try (Socket socket = new Socket()) {
socket.setSoTimeout(timeout);
socket.connect(address, timeout);
try (DataOutputStream out = new DataOutputStream(socket.getOutputStream());
InputStream in = socket.getInputStream();
InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_16BE)) {
out.write(new byte[] {(byte) 0xFE, 0x01});
int packetId = in.read();
int length = reader.read();
if (packetId != 0xFF) {
return new PingResult(ServerStatus.UNKNOWN, null, null, null);
}
if (length <= 0) {
return new PingResult(ServerStatus.UNKNOWN, null, null, null);
}
char[] chars = new char[length];
if (reader.read(chars, 0, length) != length) {
return new PingResult(ServerStatus.UNKNOWN, null, null, null);
}
String string = new String(chars);
if (!string.startsWith("§")) {
return new PingResult(ServerStatus.UNKNOWN, null, null, null);
}
String[] data = string.split("\000");
int players = Integer.parseInt(data[4]);
int maxPlayers = Integer.parseInt(data[5]);
return new PingResult(ServerStatus.ONLINE, players, maxPlayers, data[3]);
}
} catch (IOException e) {
return new PingResult(ServerStatus.OFFLINE, null, null, null);
}
});
}
public record PingResult(ServerStatus status, Integer players, Integer maxPlayers, String motd) {
@Override
public String toString() {
return "PingResult{players=" + this.players + ", maxPlayers=" + this.maxPlayers + '}';
}
}
}

View File

@ -13,6 +13,8 @@ messages:
gui: gui:
selector: selector:
enabled: true
item: item:
enabled: true enabled: true
name: "&aQuick Compass" name: "&aQuick Compass"
@ -44,6 +46,8 @@ gui:
- '&7Ip: &c%ip%&8:&c%port%' - '&7Ip: &c%ip%&8:&c%port%'
player-menu: player-menu:
enabled: true
item: item:
enabled: true enabled: true
name: "&eMy Server" name: "&eMy Server"

View File

@ -0,0 +1,35 @@
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- JDBC Database connection settings -->
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/my_prod_db?useSSL=false&amp;serverTimezone=UTC</property>
<property name="connection.username">prod</property>
<property name="connection.password">prod</property>
<!-- JDBC connection pool settings -->
<property name="connection.pool_size">1</property>
<!-- Select our SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Echo the SQL to stdout -->
<property name="show_sql">false</property>
<!-- Format the SQL -->
<property name="format_sql">false</property>
<!-- Set the current session context -->
<property name="current_session_context_class">thread</property>
<!-- Handles the entity table changes -->
<property name="hibernate.hbm2ddl.auto">update</property>
</session-factory>
</hibernate-configuration>

View File

@ -1,5 +1,5 @@
name: PSHubCore name: PSHubCore
main: os.arcadiadevs.playerservers.hubcore.PSHubCore main: os.arcadiadevs.playerservers.hubcore.PsHubCore
version: 3-dev version: 3-dev
author: OpenSource author: OpenSource