getBySlug(@NotNull String slug) {
+
+ return switch (slug.toLowerCase()) {
+ case "loading", "l", "enabling" -> Optional.of(LOADING);
+ case "waiting", "w", "wait", "lobby" -> Optional.of(WAITING);
+ case "starting", "s", "start" -> Optional.of(STARTING);
+ case "in_game", "in game", "started", "ig", "g", "playing", "p" -> Optional.of(IN_GAME);
+ case "celebrating", "celebrate", "c", "finishing", "ending", "closing" -> Optional.of(CELEBRATING);
+ case "saving", "done", "stopping" -> Optional.of(STOPPING);
+ default -> Optional.empty();
+ };
+ }
+ }
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/database/DatabaseAdapter.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/database/DatabaseAdapter.java
new file mode 100644
index 000000000..869e7e4bc
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/database/DatabaseAdapter.java
@@ -0,0 +1,101 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.database;
+
+import com.google.gson.JsonArray;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+public interface DatabaseAdapter {
+
+ /**
+ * Called when this adapter needs to be disabled because the server is stopping
+ * or because it is being replaced with a new adapter.
+ */
+ void disable();
+
+ /**
+ * Create stats table if not exists.
+ */
+ void initStatsTable();
+
+ /**
+ * Create player language preference table if not exists.
+ */
+ void initLocaleTable();
+
+ /**
+ * Create private games table.
+ */
+ void initPrivateGamesTable();
+
+ /**
+ * Get player's stats.
+ * @param player target user.
+ * @return stats object.
+ */
+ @Nullable
+ PlayerStats getPlayerStats(UUID player);
+
+ /**
+ * Save player stats to your data source.
+ * @param playerStats cached stats from the server.
+ */
+ void savePlayerStats(PlayerStats playerStats);
+
+ /**
+ * Retrieve player language.
+ * @param player given user.
+ * @return iso code.
+ */
+ @Nullable
+ String getPlayerLocale(UUID player);
+
+ /**
+ * Save language selection to db.
+ * @param player target.
+ * @param iso language code.
+ */
+ void savePlayerLocale(UUID player, @Nullable String iso);
+
+ /**
+ * Check if the given player has an active private games session.
+ * Works in combination with parties.
+ */
+ boolean hasActivePrivateGames(UUID player);
+
+ /**
+ * Toggle private games for a player.
+ */
+ void setActivePrivateGames(UUID player, boolean toggle);
+
+ /**
+ * Get private games settings for the given player.
+ * Newly added settings will be added to the list in the manager.
+ *
+ * Can be null. List (that can be empty) if active;
+ */
+ @Nullable JsonArray getPrivateGamesSettings(UUID player) throws IllegalAccessException;
+
+ /**
+ * Save replace current settings to db.
+ */
+ void setPrivateGamesSettings(UUID player, JsonArray settingList);
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/database/DatabaseHandler.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/database/DatabaseHandler.java
new file mode 100644
index 000000000..17a05cf8f
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/database/DatabaseHandler.java
@@ -0,0 +1,37 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.database;
+
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+public interface DatabaseHandler {
+ DatabaseAdapter getDatabase();
+
+ /**
+ * Null to restore to server's default.
+ */
+ boolean setDatabaseAdapter(@Nullable DatabaseAdapter adapter);
+
+ /**
+ * Get the folder that contains the database yml configuration file.
+ */
+ File getDatabaseConfigurationPath();
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/database/PlayerStats.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/database/PlayerStats.java
new file mode 100644
index 000000000..4564e9fec
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/database/PlayerStats.java
@@ -0,0 +1,54 @@
+package dev.andrei1058.bedwars.common.api.database;
+
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Date;
+import java.util.UUID;
+
+/***
+ * Do not cache this please.
+ * This is a read only object used to map data from your database source.
+ * The plugin will handle cache itself.
+ */
+// todo I'd actually like to make stats as objects. this is kind of hard coded. similar to the session stats we introduced in 23.11
+public interface PlayerStats {
+
+ /**
+ * Player first game.
+ * @return date.
+ */
+ @Nullable
+ Date getFirstPlay();
+
+ /**
+ * @return user identifier.
+ */
+ UUID getPlayer();
+
+ /**
+ * @return last gameplay.
+ */
+ Date getLastPlay();
+
+ /**
+ * @return total of games played.
+ */
+ int getGamesPlayed();
+
+ /**
+ * @return total of abandoned games.
+ */
+ int getGamesAbandoned();
+
+ /**
+ * @return total of games won.
+ */
+ int getGamesWon();
+
+ /**
+ * @return games lost count.
+ */
+ int getGamesLost();
+
+ //todo sync method names with PlayerStatsCache
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/locale/CommonLocale.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/locale/CommonLocale.java
new file mode 100644
index 000000000..0f59da4df
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/locale/CommonLocale.java
@@ -0,0 +1,128 @@
+package dev.andrei1058.bedwars.common.api.locale;
+
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Date;
+import java.util.List;
+
+public interface CommonLocale {
+ /**
+ * Color color translated message.
+ *
+ * @param message message.
+ * @param player if requesting a player message. Used to parse placeholders.
+ * @return Chat color translated message at given path.
+ */
+ String getMsg(@Nullable Player player, CommonMessage message);
+
+ /**
+ * Color color translated message.
+ *
+ * @param message message.
+ * @param sender if requesting a player message. Used to parse placeholders.
+ * @return Chat color translated message at given path.
+ */
+ String getMsg(@Nullable CommandSender sender, CommonMessage message);
+
+ /**
+ * Color color translated message.
+ *
+ * @param message message.
+ * @param player if requesting a player message. Used to parse placeholders.
+ * @return Chat color translated message at given path.
+ */
+ @SuppressWarnings("unused")
+ List getMsgList(@Nullable Player player, CommonMessage message);
+
+ /**
+ * Color color translated message.
+ *
+ * @param path message path.
+ * @param player if requesting a player message. Used to parse placeholders.
+ * @return Chat color translated message at given path.
+ */
+ default List getMsgList(@Nullable Player player, CommonMessage path, @Nullable String[] replacements) {
+ return getMsgList(player, path.toString(), replacements);
+ }
+
+ /**
+ * Color color translated message.
+ *
+ * @param path message path.
+ * @param player if requesting a player message. Used to parse placeholders.
+ * @return Chat color translated message at given path.
+ */
+ List getMsgList(@Nullable Player player, String path, @Nullable String[] replacements);
+
+ /**
+ * Set a string in the language file.
+ *
+ * @param path msg path.
+ * @param value msg.
+ */
+ void setMsg(String path, String value);
+
+ /**
+ * Set a string in the language file.
+ *
+ * @param path msg path.
+ * @param value msg.
+ */
+ void setList(String path, List value);
+
+ /**
+ * @param path message path.
+ * @return True if the given path exists.
+ */
+ boolean hasPath(String path);
+
+ /**
+ * Color color translated message.
+ *
+ * @param path message path.
+ * @param player if requesting a player message. Used to parse placeholders.
+ * @return Chat color translated message at given path.
+ */
+ String getMsg(@Nullable Player player, String path);
+
+ /**
+ * Color color translated message.
+ *
+ * @param path message path.
+ * @param player if requesting a player message. Used to parse placeholders.
+ * @return Chat color translated message at given path.
+ */
+ List getMsgList(@Nullable Player player, String path);
+
+ /**
+ * Get language iso code.
+ * Languages are identified by this code.
+ */
+ String getIsoCode();
+
+ /**
+ * This will check if the language file is enabled via {@link CommonMessage#ENABLE}.
+ */
+ boolean isEnabled();
+
+ /**
+ * Get a raw message. No color translation.
+ * No placeholder parsing.
+ */
+ String getRawMsg(String path);
+
+ /**
+ * Get a raw message list. No color translation.
+ * No placeholder parsing.
+ */
+ List getRawList(String path);
+
+ /**
+ * Format date.
+ *
+ * @param date date to be formatted;
+ */
+ String formatDate(Date date);
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/locale/CommonLocaleHandler.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/locale/CommonLocaleHandler.java
new file mode 100644
index 000000000..373542d37
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/locale/CommonLocaleHandler.java
@@ -0,0 +1,165 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+package dev.andrei1058.bedwars.common.api.locale;
+
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.sql.Date;
+import java.util.List;
+import java.util.UUID;
+
+public interface CommonLocaleHandler {
+ /**
+ * Get enabled languages by iso.
+ */
+ List getEnabledCommonLocales();
+
+ /**
+ * Get a translated message.
+ *
+ * @param path message path.
+ * @param player player language.
+ */
+ String getMsg(Player player, CommonMessage path);
+
+ /**
+ * Get a translated message.
+ *
+ * @param path message path.
+ * @param sender sender language.
+ */
+ String getMsg(CommandSender sender, CommonMessage path);
+
+ /**
+ * Get player's language.
+ *
+ * @param player target player.
+ */
+ CommonLocale getLocale(Player player);
+
+ /**
+ * Get sender's language.
+ *
+ * @param sender target.
+ */
+ CommonLocale getLocale(CommandSender sender);
+
+ /**
+ * Get a player language.
+ *
+ * @param player target player.
+ * @return player language of if he does not have any, return default language.
+ */
+ @NotNull
+ CommonLocale getLocale(UUID player);
+
+ /**
+ * Get server default language.
+ */
+ CommonLocale getDefaultLocale();
+
+ /**
+ * Get language by iso code.
+ */
+ CommonLocale getLocale(String langIso);
+
+ /**
+ * Get language folder.
+ * This is where language files are retrieved from.
+ */
+ File getLocalesFolder();
+
+ /**
+ * Add a new language to the enabled languages list.
+ *
+ * @param translation language to be registered.
+ * @return true if successfully added.
+ * Will return false if could not validate messages paths.
+ * It may return false if adding this language or languages in general is not allowed.
+ * Will return false if language is already loaded for example.
+ * Will return false if language is disabled from config.
+ */
+ @SuppressWarnings({"unused", "UnusedReturnValue"})
+ boolean addLocale(CommonLocale translation);
+
+ /**
+ * Remove a language from the languages list.
+ *
+ * @param translation language to be removed.
+ * @return true if removed successfully.
+ * Will return false if given language is the default language.
+ */
+ @SuppressWarnings({"unused", "UnusedReturnValue"})
+ boolean removeLocale(CommonLocale translation);
+
+ /**
+ * Change a player language.
+ * It is not recommended to do it during the game.
+ * The player must be online. If you want to "pre-load" player languages use
+ * your own system and add the player here only when he is online.
+ * WILL SAVE THE LANGUAGE TO THE DATABASE AS WELL (ASYNC).
+ *
+ * @param uuid player uuid. He must be online.
+ * @param translation language. Null to restore to default server language. If the language is not registered will return false.
+ * @param triggerEvent true if you want to trigger language change event. Usually false at join.
+ * @return true if switched successfully. False if language is not registered,
+ * if uuid is not on the server, if switch not allowed at this moment or other.
+ */
+ @SuppressWarnings("UnusedReturnValue")
+ boolean setPlayerLocale(UUID uuid, @Nullable CommonLocale translation, boolean triggerEvent);
+
+ /**
+ * Set server default language.
+ *
+ * @param translation language.
+ * @return true if set successfully.
+ * Will return false if the language is not registered,
+ * if cannot be validated or other.
+ */
+ @SuppressWarnings("unused")
+ boolean setDefaultLocale(CommonLocale translation);
+
+ /**
+ * Check if a language exists (is enabled and loaded) by its iso code.
+ *
+ * @param isoCode iso code to be checked.
+ * @return true if translation exists.
+ */
+ @SuppressWarnings("unused")
+ boolean isLocaleExist(@Nullable String isoCode);
+
+ /**
+ * Format a date using player's time-zone.
+ *
+ * @param player player used to retrieve time-zone.
+ * @param date date to be formatted.
+ */
+ @SuppressWarnings("unused")
+ String formatDate(Player player, Date date);
+
+ /**
+ * Clear cached locale on player leave.
+ */
+ void clearOnLeave(Player player);
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/locale/CommonMessage.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/locale/CommonMessage.java
new file mode 100644
index 000000000..1b2472a07
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/locale/CommonMessage.java
@@ -0,0 +1,83 @@
+package dev.andrei1058.bedwars.common.api.locale;
+
+import lombok.Getter;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.jetbrains.annotations.NotNull;
+
+@Getter
+public enum CommonMessage {
+ ENABLE("enable", true),
+
+ ;
+
+ private final String path;
+ /**
+ * Get default message value.
+ */
+ private final Object defaultMsg;
+ /**
+ * Check if this message needs manual saving.
+ * Returns false when it is saved by {@link #saveDefaults(YamlConfiguration)}.
+ */
+ private final boolean manual;
+
+ /**
+ * Create a common message used in the main mini-game and connector plugin.
+ *
+ * @param manual true if this path requires manual saving to yml.
+ * If message path has placeholders like this: my-path-{name}-lore.
+ * @param path message path.
+ * @param defaultMsg default message for path.
+ */
+ CommonMessage(boolean manual, String path, Object defaultMsg) {
+ this.path = "cm-" + path;
+ this.defaultMsg = defaultMsg;
+ this.manual = manual;
+ }
+
+ /**
+ * Create a common message used in the main mini-game and connector plugin.
+ *
+ * @param path message path.
+ * @param defaultMsg default message for path.
+ */
+ CommonMessage(String path, Object defaultMsg) {
+ this.path = "cm-" + path;
+ this.defaultMsg = defaultMsg;
+ this.manual = false;
+ }
+
+ @Override
+ public String toString() {
+ return path;
+ }
+
+ /**
+ * Save this message to a yml file.
+ *
+ * @param yml language file where to save.
+ * @param pathReplacements placeholders to be replaced in message path.
+ * @param value message value.
+ */
+ public void addDefault(YamlConfiguration yml, String @NotNull [] pathReplacements, Object value) {
+ String path = this.toString();
+ for (int i = 0; i < pathReplacements.length; i += 2) {
+ path = path.replace(pathReplacements[i], pathReplacements[i + 1]);
+ }
+ yml.addDefault(path, value);
+ }
+
+ /**
+ * Save messages that are not {@link #isManual()} to the given yml.
+ *
+ * @param yml language file where to save.
+ */
+ public static void saveDefaults(YamlConfiguration yml) {
+ for (CommonMessage message : values()) {
+ if (message.isManual()) {
+ continue;
+ }
+ yml.addDefault(message.path, message.getDefaultMsg());
+ }
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/AbstractMessagingPacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/AbstractMessagingPacket.java
new file mode 100644
index 000000000..e66182b9c
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/AbstractMessagingPacket.java
@@ -0,0 +1,18 @@
+package dev.andrei1058.bedwars.common.api.messaging;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.Nullable;
+
+@Getter
+@Setter
+public class AbstractMessagingPacket implements MessagingPacket, TargetedPacket {
+
+ private String sender;
+ private String target;
+
+ public AbstractMessagingPacket(@Nullable String sender, @Nullable String target) {
+ this.sender = sender;
+ this.target = target;
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/DefaultChannels.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/DefaultChannels.java
new file mode 100644
index 000000000..af778b3f9
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/DefaultChannels.java
@@ -0,0 +1,60 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging;
+
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * List of default messaging channel IDs.
+ */
+@Getter
+public enum DefaultChannels {
+ ARENA_FULL_DATA("arena_full_data"),
+ PLAYER_COUNT_UPDATE("arena_player_count_update"),
+ PLAYER_COUNT_CHANNEL("arena_player_count"),
+ ARENA_STATUS_UPDATE("arena_status_update"),
+ GAME_DROP("arena_game_drop"),
+ PING("arena_keep_alive"),
+ ARENA_QUERY("arena_query"),
+ PLAYER_JOIN("arena_player_join"),
+ SLAVE_WAKE_UP("slave_wake_up"),
+ PRIVATE_TAKE_OVER("arena_private_game_take_over"),
+ POST_REJOIN_CREATED("arena_rejoin_create"),
+ POST_REJOIN_DELETED("arena_rejoin_deny"),
+ QUERY_TELEPORT("teleport"),
+ POST_TELEPORT_RESPONSE("teleport_response"),
+ PLAY_AGAIN_REQUEST("play_again_request"),
+ PLAY_AGAIN_RESPONSE("play_again_response");
+
+ private static final String PREFIX = "bw_";
+ private final String name;
+
+ DefaultChannels(@NotNull String name) {
+ if (name.length() > 8) {
+ throw new RuntimeException("Channel id length exceeded!");
+ }
+ this.name = PREFIX+name;
+ }
+
+ @Override
+ public String toString() {
+ return this.name;
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/GroupCategorisedPacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/GroupCategorisedPacket.java
new file mode 100644
index 000000000..503537477
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/GroupCategorisedPacket.java
@@ -0,0 +1,23 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging;
+
+public interface GroupCategorisedPacket {
+ String getGameGroup();
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/ISlaveServer.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/ISlaveServer.java
new file mode 100644
index 000000000..478b929e1
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/ISlaveServer.java
@@ -0,0 +1,26 @@
+package dev.andrei1058.bedwars.common.api.messaging;
+
+/**
+ * Interface for message producers.
+ * This is used in a form of heart beat.
+ */
+public interface ISlaveServer {
+ /**
+ * Bungee name.
+ */
+ String getName();
+
+ /**
+ * Update the latest pong received.
+ * Using {@link DefaultChannels#PING}
+ */
+ void pong();
+
+ long getLastPacket();
+
+ /**
+ * Check if dead.
+ */
+ @SuppressWarnings("unused")
+ boolean isTimedOut();
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/MessagingChannel.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/MessagingChannel.java
new file mode 100644
index 000000000..af5753712
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/MessagingChannel.java
@@ -0,0 +1,33 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging;
+
+/**
+ * A channel is a message bus used for reading data passing through it.
+ */
+public interface MessagingChannel {
+ void read(T message);
+
+ Class getType();
+
+ /**
+ * @return char limited to 32.
+ */
+ String getName();
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/MessagingHandler.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/MessagingHandler.java
new file mode 100644
index 000000000..669dbb315
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/MessagingHandler.java
@@ -0,0 +1,77 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging;
+
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * Responsible for slave-lobby messaging.
+ */
+public interface MessagingHandler {
+
+ /**
+ * Register incoming packet listener.
+ * Incoming packet channel from lobby servers.
+ * You should check first if a channel is already registered with {@link #isChannelRegistered(String)}.
+ * You cannot listen to someone else's packet id.
+ * This is used only when server type is bungee.
+ *
+ * @param channel incoming packets from remote lobbies' listener.
+ * @return true if registered successfully.
+ */
+ boolean registerIncomingPacketChannel(MessagingChannel> channel);
+
+ /**
+ * Check if there is a registered packet listener with the given name.
+ *
+ * @param channel channel name.
+ */
+ boolean isChannelRegistered(String channel);
+
+ /**
+ * Send a packet to remote sockets.
+ * Json based. Packets should be sent async.
+ *
+ * @param channel remote channel that will handle this packet.
+ * @param message your custom Json data.
+ * @param async true if you want to send it async or false if you're already sending it from an async task or u know if you know what you're doing.
+ */
+ void sendPacket(String channel, MessagingPacket message, boolean async);
+
+ /**
+ * Send a packet to remote sockets.
+ * Json based. Packets should be sent async.
+ *
+ * @param channel remote channel that will handle this packet.
+ * @param message your custom Json data.
+ * @param async true if you want to send it async or false if you're already sending it from an async task or u know if you know what you're doing.
+ */
+ void sendPackets(String channel, List message, boolean async);
+
+ /**
+ * Retrieve a channel by id.
+ *
+ * @param name channel id.
+ * @return null if not found.
+ */
+ @Nullable
+ MessagingChannel> getChannelByName(String name);
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/MessagingPacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/MessagingPacket.java
new file mode 100644
index 000000000..392d17b08
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/MessagingPacket.java
@@ -0,0 +1,23 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging;
+
+public interface MessagingPacket {
+
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/MessagingType.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/MessagingType.java
new file mode 100644
index 000000000..aa047424a
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/MessagingType.java
@@ -0,0 +1,7 @@
+package dev.andrei1058.bedwars.common.api.messaging;
+
+public enum MessagingType {
+ REDIS,
+ NONE,
+ CUSTOM,
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/TargetedPacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/TargetedPacket.java
new file mode 100644
index 000000000..ec4b3c288
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/TargetedPacket.java
@@ -0,0 +1,22 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging;
+
+public interface TargetedPacket {
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PlayAgainRequestPacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PlayAgainRequestPacket.java
new file mode 100644
index 000000000..9ce9cb640
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PlayAgainRequestPacket.java
@@ -0,0 +1,49 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import dev.andrei1058.bedwars.common.api.messaging.GroupCategorisedPacket;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+@Getter
+@Setter
+public class PlayAgainRequestPacket extends AbstractMessagingPacket implements GroupCategorisedPacket {
+
+ private final String gameGroup;
+ private boolean privateGame;
+ private int vipJoins, partySize;
+ private UUID player;
+
+ public PlayAgainRequestPacket(
+ @Nullable String sender, @Nullable String target, @Nullable String gameGroup,
+ boolean privateGame, int vipJoins, int partySize, UUID player
+ ) {
+ super(sender, target);
+ this.gameGroup = gameGroup;
+ this.privateGame = privateGame;
+ this.vipJoins = vipJoins;
+ this.partySize = partySize;
+ this.player = player;
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PlayAgainResponsePacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PlayAgainResponsePacket.java
new file mode 100644
index 000000000..08191df32
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PlayAgainResponsePacket.java
@@ -0,0 +1,58 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+@Getter
+@Setter
+public class PlayAgainResponsePacket extends AbstractMessagingPacket {
+
+ private String slaveGameHolder;
+ private Integer gameId;
+ private UUID player;
+ private boolean privateGame;
+
+ /**
+ * In response for {@link PlayAgainRequestPacket}.
+ *
+ * @param sender the lobby as master responding to the request.
+ * @param target slave that made the request. Must not be null in this case.
+ * @param slaveGameHolder the slave holding the new game, null if not found.
+ * @param gameId null if no game was found.
+ * @param player requester.
+ * @param privateGame if it is a private game.
+ */
+ public PlayAgainResponsePacket(
+ @Nullable String sender, @Nullable String target, @Nullable String slaveGameHolder,
+ @Nullable Integer gameId, UUID player, boolean privateGame
+ ) {
+ super(sender, target);
+ this.slaveGameHolder = slaveGameHolder;
+ this.gameId = gameId;
+ this.player = player;
+ this.privateGame = privateGame;
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameDataPacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameDataPacket.java
new file mode 100644
index 000000000..e508fa0ba
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameDataPacket.java
@@ -0,0 +1,89 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.arena.DisplayableArena;
+import dev.andrei1058.bedwars.common.api.arena.GameState;
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import dev.andrei1058.bedwars.common.api.messaging.GroupCategorisedPacket;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+@Getter
+@Setter
+public class PostGameDataPacket extends AbstractMessagingPacket implements GroupCategorisedPacket {
+
+ private boolean privateGame;
+ private UUID gameId;
+ private GameState gameState;
+ private boolean full;
+ private String spectatePermission;
+ private String displayName;
+ private int maxPlayers, minPlayers, currentPlayers, currentSpectators;
+ private String templateWorld, tag;
+ private int vips;
+ private long startTime;
+ private String gameGroup;
+ private byte displayData;
+ private boolean displayEnchantment;
+ private String displayMaterial;
+ private String replyChannel;
+
+
+ public PostGameDataPacket(
+ @Nullable String sender, @NotNull DisplayableArena arena
+ ) {
+ this(sender, null, arena, (byte) 0, null, false);
+ }
+
+ public PostGameDataPacket(
+ @Nullable String sender, @Nullable String target, @NotNull DisplayableArena arena,
+ byte displayData, String displayMaterial, boolean displayEnchantment
+ ) {
+ super(sender, target);
+ this.gameId = arena.getGameId();
+ this.gameState = arena.getGameState();
+ this.full = arena.isFull();
+ this.spectatePermission = arena.getSpectatePermission();
+ this.displayName = arena.getDisplayName();
+ this.maxPlayers = arena.getMaxPlayers();
+ this.minPlayers = arena.getMinPlayers();
+ this.currentPlayers = arena.getCurrentPlayers();
+ this.currentSpectators = arena.getCurrentSpectators();
+ this.templateWorld = arena.getTemplate();
+ this.vips = arena.getCurrentVips();
+ this.startTime = arena.getStartTime() == null ? -1 : arena.getStartTime().toEpochMilli();
+ this.gameGroup = arena.getGroup();
+ this.displayData = displayData;
+ this.displayMaterial = displayMaterial;
+ this.displayEnchantment = displayEnchantment;
+ }
+
+ public String getDisplayMaterial() {
+ return displayMaterial == null ? null : displayMaterial.trim().toUpperCase();
+ }
+
+ public String getGameGroup() {
+ return gameGroup;
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameDropPacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameDropPacket.java
new file mode 100644
index 000000000..a4a23415a
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameDropPacket.java
@@ -0,0 +1,41 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.Nullable;
+
+@Getter
+public class PostGameDropPacket extends AbstractMessagingPacket {
+
+ @Setter
+ private int gameId;
+
+ /**
+ * @param sender slave sending the message. Must not be null in this case.
+ * @param target if it is targeted to a single listener. But should be null for all in this case.
+ * @param gameId game ended or restarted.
+ */
+ public PostGameDropPacket(@Nullable String sender, @Nullable String target, int gameId) {
+ super(sender, target);
+ this.gameId = gameId;
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameJoinPacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameJoinPacket.java
new file mode 100644
index 000000000..381a49f3b
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameJoinPacket.java
@@ -0,0 +1,58 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+@Getter
+@Setter
+public class PostGameJoinPacket extends AbstractMessagingPacket {
+
+ private UUID player;
+ private int gameId;
+ private boolean spectator;
+ private String langIso;
+ private String partyOrSpectateTarget;
+
+ /**
+ * Used when a player has selected a game from lobby. We are letting the slave the player is joining.
+ *
+ * @param target slave where the packet is going to.
+ * @param sender packet sender.
+ * @param player player joining the server.
+ * @param gameId the game where the player must be assigned.
+ * @param spectator in case is joining as spectator or admin teleport.
+ * @param langIso if selected another language than default.
+ * @param partyOrSpectateTarget if joining via party must specify the party over. Can be used as spectating target.
+ */
+ public PostGameJoinPacket(@Nullable String sender, @Nullable String target, UUID player,
+ int gameId, boolean spectator, String langIso, String partyOrSpectateTarget) {
+ super(sender, target);
+ this.player = player;
+ this.gameId = gameId;
+ this.spectator = spectator;
+ this.langIso = langIso;
+ this.partyOrSpectateTarget = partyOrSpectateTarget;
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGamePlayerCountPacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGamePlayerCountPacket.java
new file mode 100644
index 000000000..0b0d59c39
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGamePlayerCountPacket.java
@@ -0,0 +1,56 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.arena.DisplayableArena;
+import dev.andrei1058.bedwars.common.api.arena.GameState;
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+@Getter
+@Setter
+public class PostGamePlayerCountPacket extends AbstractMessagingPacket {
+
+ private GameState gameState;
+ private UUID gameId;
+ private int maxPlayers, currentPlayers, currentSpectators, currentVips;
+
+ /**
+ * Used when a game changes player count. In case of start provide start time as well.
+ *
+ * @param sender slave identifier sending the update.
+ * @param target if targeted to a certain master. In this case should be null.
+ * @param arena arena being updated.
+ */
+ public PostGamePlayerCountPacket(
+ @Nullable String sender, @Nullable String target,
+ @NotNull DisplayableArena arena) {
+ super(sender, target);
+ this.gameState = arena.getGameState();
+ this.gameId = arena.getGameId();
+ this.maxPlayers = arena.getMaxPlayers();
+ this.currentSpectators = arena.getCurrentSpectators();
+ this.currentVips = arena.getCurrentVips();
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameStatePacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameStatePacket.java
new file mode 100644
index 000000000..6a3b1eb52
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameStatePacket.java
@@ -0,0 +1,71 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.arena.DisplayableArena;
+import dev.andrei1058.bedwars.common.api.arena.GameState;
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+@Getter
+@Setter
+public class PostGameStatePacket extends AbstractMessagingPacket {
+
+ private UUID gameId;
+ private GameState gameState;
+ private long startTime;
+ private byte displayData;
+ private boolean displayEnchanted;
+ private String displayMaterial;
+
+ public PostGameStatePacket(
+ @Nullable String sender, @NotNull DisplayableArena arena
+ ) {
+ this(sender, null, arena, (byte) 0, null, false);
+ }
+
+ /**
+ * Used when a game changes its state. In case of start provide start time as well.
+ *
+ * @param sender slave identifier sending the update.
+ * @param target if targeted to a certain master. In this case should be null.
+ * @param arena arena being updated.
+ */
+ public PostGameStatePacket(
+ @Nullable String sender, @Nullable String target, @NotNull DisplayableArena arena,
+ byte displayData, @Nullable String displayMaterial, boolean displayEnchanted
+ ) {
+ super(sender, target);
+ this.gameId = arena.getGameId();
+ this.gameState = arena.getGameState();
+ this.startTime = arena.getStartTime() == null ? -1 : arena.getStartTime().toEpochMilli();
+ this.displayMaterial = displayMaterial;
+ this.displayEnchanted = displayEnchanted;
+ this.displayData = displayData;
+ }
+
+ public String getDisplayMaterial() {
+ return displayMaterial == null ? null : displayMaterial.trim().toUpperCase();
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameTakeOverPacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameTakeOverPacket.java
new file mode 100644
index 000000000..835bbff26
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostGameTakeOverPacket.java
@@ -0,0 +1,50 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+@Getter
+@Setter
+public class PostGameTakeOverPacket extends AbstractMessagingPacket {
+
+ private UUID host;
+ private int gameId;
+
+ /**
+ * Tell masters that a PRIVATE game was taken.
+ *
+ * @param target should be null so all masters listening will receive the update.
+ * @param sender server sending the message.
+ * @param gameId game that is being taking over.
+ * @param host player that owns the private game.
+ */
+ public PostGameTakeOverPacket(
+ @Nullable String sender, @Nullable String target, int gameId, UUID host
+ ) {
+ super(sender, target);
+ this.gameId = gameId;
+ this.host = host;
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostQueryPlayerPacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostQueryPlayerPacket.java
new file mode 100644
index 000000000..6824d39cc
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostQueryPlayerPacket.java
@@ -0,0 +1,51 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+@Getter
+@Setter
+public class PostQueryPlayerPacket extends AbstractMessagingPacket {
+
+ private UUID playerRequester;
+ private String playerQueried;
+
+ /**
+ * Used to search a player.
+ *
+ * @param sender server sending the message.
+ * @param target target server where to search for this player or null for all listener.
+ * @param playerRequester player requester.
+ * @param playerQueried player looking for.
+ */
+ public PostQueryPlayerPacket(
+ @Nullable String sender, @Nullable String target, UUID playerRequester, String playerQueried
+ ) {
+ super(sender, target);
+ this.playerQueried = playerQueried;
+ this.playerRequester = playerRequester;
+ }
+
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostQueryPlayerResponsePacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostQueryPlayerResponsePacket.java
new file mode 100644
index 000000000..fb34194a1
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostQueryPlayerResponsePacket.java
@@ -0,0 +1,44 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+@Getter
+@Setter
+public class PostQueryPlayerResponsePacket extends AbstractMessagingPacket {
+
+ private String playerQueried;
+ private UUID playerRequester;
+ private Integer gameId;
+ public PostQueryPlayerResponsePacket(
+ @Nullable String sender, @Nullable String target, @NotNull PostQueryPlayerPacket queryPacket,
+ @Nullable Integer gameId
+ ) {
+ super(sender, target);
+ this.playerQueried = queryPacket.getPlayerQueried();
+ this.playerRequester = queryPacket.getPlayerRequester();
+ }
+}
\ No newline at end of file
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostQuerySlaveGamesPacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostQuerySlaveGamesPacket.java
new file mode 100644
index 000000000..eecdd79f9
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostQuerySlaveGamesPacket.java
@@ -0,0 +1,44 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.Nullable;
+
+@Getter
+@Setter
+public class PostQuerySlaveGamesPacket extends AbstractMessagingPacket {
+
+ private String replyChannel;
+ /**
+ * Query a slave for its active games.
+ *
+ * @param sender server requester.
+ * @param target slave queried.
+ * @param replyChannel asking for response via this channel.
+ */
+ public PostQuerySlaveGamesPacket(
+ @Nullable String sender, @Nullable String target, String replyChannel
+ ) {
+ super(sender, target);
+ this.replyChannel = replyChannel;
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostReJoinCreatePacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostReJoinCreatePacket.java
new file mode 100644
index 000000000..a2f890df7
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostReJoinCreatePacket.java
@@ -0,0 +1,50 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+@Getter
+@Setter
+public class PostReJoinCreatePacket extends AbstractMessagingPacket {
+
+ private int gameId;
+ private UUID player;
+
+ /**
+ * Slave informing masters listening that a new re-join session has been created.
+ *
+ * @param sender slave sending the message.
+ * @param target should be null so all masters listening will receive the message.
+ * @param gameId gameId where the re-join is referring to.
+ * @param player player that left the game.
+ */
+ public PostReJoinCreatePacket(
+ @Nullable String sender, @Nullable String target, int gameId, UUID player
+ ) {
+ super(sender, target);
+ this.gameId = gameId;
+ this.player = player;
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostReJoinDeletePacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostReJoinDeletePacket.java
new file mode 100644
index 000000000..ef0b2e860
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostReJoinDeletePacket.java
@@ -0,0 +1,50 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import lombok.Getter;
+import lombok.Setter;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+
+@Getter
+@Setter
+public class PostReJoinDeletePacket extends AbstractMessagingPacket {
+
+ private int gameId;
+ private UUID player;
+
+ /**
+ * Informing listeners that a re-join session has expired.
+ *
+ * @param sender slave or lobby sending the message.
+ * @param target should be null so all listeners will receive the message.
+ * @param gameId gameId where the re-join is referring to.
+ * @param player player owing the re-join session.
+ */
+ public PostReJoinDeletePacket(
+ @Nullable String sender, @Nullable String target, int gameId, UUID player
+ ) {
+ super(sender, target);
+ this.gameId = gameId;
+ this.player = player;
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostSlavePongPacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostSlavePongPacket.java
new file mode 100644
index 000000000..3f2b0f720
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostSlavePongPacket.java
@@ -0,0 +1,31 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * We keep alive slave data by using this keep alive response.
+ */
+public class PostSlavePongPacket extends AbstractMessagingPacket {
+ public PostSlavePongPacket(@Nullable String sender, @Nullable String target) {
+ super(sender, target);
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostSlaveWakeUpPacket.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostSlaveWakeUpPacket.java
new file mode 100644
index 000000000..9fed45d7a
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/messaging/packet/PostSlaveWakeUpPacket.java
@@ -0,0 +1,34 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.messaging.packet;
+
+import dev.andrei1058.bedwars.common.api.messaging.AbstractMessagingPacket;
+import org.jetbrains.annotations.Nullable;
+
+public class PostSlaveWakeUpPacket extends AbstractMessagingPacket {
+ /**
+ * Tell listeners a new slave is waking up.
+ *
+ * @param sender slave waking up.
+ * @param target should be null so all can receive this message.
+ */
+ public PostSlaveWakeUpPacket(@Nullable String sender, @Nullable String target) {
+ super(sender, target);
+ }
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/party/PartyAdapter.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/party/PartyAdapter.java
new file mode 100644
index 000000000..410787db4
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/party/PartyAdapter.java
@@ -0,0 +1,126 @@
+package dev.andrei1058.bedwars.common.api.party;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.UUID;
+
+public interface PartyAdapter {
+
+ /**
+ * Party adapter name.
+ *
+ * @return party adapter name or plugin owner name.
+ */
+ String getName();
+
+ /**
+ * Check if the given player has a party.
+ *
+ * @param player player to be checked.
+ * @return true if the player is in a party.
+ */
+ boolean hasParty(@Nullable UUID player);
+
+ /**
+ * Add a member to an existing party.
+ *
+ * @param partyOwner party owner used to find the party.
+ * @param toBeAdded player to be added.
+ * @return true if added to the party.
+ */
+ boolean addMember(UUID partyOwner, UUID toBeAdded);
+
+ /**
+ * Create a party or add members to an existing one.
+ * You have to check if the given members are already in party yourself.
+ *
+ * @param partyOwner party owner (eventually used to find the party).
+ * @param members party members.
+ * @return true if created.
+ */
+ boolean createParty(UUID partyOwner, List members);
+
+ /**
+ * Remove a player from existing party.
+ * If the given use is the owner, disband.
+ *
+ * @param player to be removed.
+ * @return true if party got disbanded.
+ */
+ @SuppressWarnings("UnusedReturnValue")
+ boolean removeFromParty(UUID player);
+
+ /**
+ * Get how many parties are loaded locally.
+ * This is used when someone tries to replace the current party adapter and if this is greater than 0 the action is denied.
+ *
+ * @return amount of parties loaded locally.
+ */
+ int getLoadedParties();
+
+ /**
+ * Check if player is owner of a party.
+ *
+ * @param player player to be checked.
+ * @return true if owner of a party.
+ */
+ boolean isOwner(UUID player);
+
+ /**
+ * Get members from a party.
+ * Will return an empty list if the player has not a party or if there are no members in that party.
+ * Including the party owner in that list is not a must.
+ *
+ * @param partyMemberOrOwner party member or owner.
+ * @return party members list. Empty if the given player is not in a party.
+ */
+ @NotNull
+ List getMembers(UUID partyMemberOrOwner);
+
+ /**
+ * Get owner of a party.
+ *
+ * @param member party member.
+ * @return party owner. Null if the given player is not in a party.
+ */
+ @Nullable
+ UUID getOwner(UUID member);
+
+ /**
+ * Disband a party.
+ *
+ * @param player party owner or member.
+ */
+ void disband(UUID player);
+
+ /**
+ * Set this to false if you want to let the plugin team-up players that join from a remote lobby.
+ * True if you want to handle it yourself.
+ *
+ * @return true if this adapter is able to team-up itself players across bungee-network.
+ */
+ boolean isSelfTeamUpAtRemoteJoin();
+
+ /**
+ * Transfer party ownership.
+ *
+ * @param partyOwner party owner.
+ * @param partyMember member to become owner.
+ * @return true if transferred successfully.
+ */
+ boolean transferOwnership(UUID partyOwner, UUID partyMember);
+
+ /**
+ * Check if this party has reached its size limit.
+ *
+ * @param partyOwnerOrMember player used to retrieve the party instance. Will return false as well if party not found.
+ */
+ boolean isPartySizeLimitReached(UUID partyOwnerOrMember);
+
+ /**
+ * Triggered when current adapter is being replaced by another one.
+ */
+ void disableAdapter();
+}
diff --git a/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/party/PartyHandler.java b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/party/PartyHandler.java
new file mode 100644
index 000000000..7b251346a
--- /dev/null
+++ b/bedwars-common/bedwars-common-api/src/main/java/dev/andrei1058/bedwars/common/api/party/PartyHandler.java
@@ -0,0 +1,37 @@
+/*
+ * BedWars1058 - A bed wars mini-game.
+ * Copyright (C) 2023 Andrei Dascălu
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package dev.andrei1058.bedwars.common.api.party;
+
+public interface PartyHandler {
+ /**
+ * Get party support interface.
+ *
+ * @return current party adapter.
+ */
+ PartyAdapter getPartyAdapter();
+
+ /**
+ * Change server party adapter.
+ * This is only possible if there aren't any created parties on the existing adapter.
+ *
+ * @param partyAdapter new adapter. Null to revert to default.
+ * @return true if changed successfully.
+ */
+ boolean setPartyAdapter(PartyAdapter partyAdapter);
+}
diff --git a/bedwars-common/bedwars-common-impl/pom.xml b/bedwars-common/bedwars-common-impl/pom.xml
new file mode 100644
index 000000000..40aa579d7
--- /dev/null
+++ b/bedwars-common/bedwars-common-impl/pom.xml
@@ -0,0 +1,29 @@
+
+
+ 4.0.0
+
+ com.andrei1058.bedwars.common
+ bedwars-common
+ 23.10.1-SNAPSHOT
+
+
+ bedwars-common-impl
+
+
+ 21
+ 21
+ UTF-8
+
+
+
+
+ com.andrei1058.bedwars.common.api
+ bedwars-common-api
+ ${project.version}
+ compile
+
+
+
+
\ No newline at end of file
diff --git a/bedwars-common/bedwars-common-impl/src/main/java/com/andrei1058/bedwars/common/util/platform/ServerVersion.java b/bedwars-common/bedwars-common-impl/src/main/java/com/andrei1058/bedwars/common/util/platform/ServerVersion.java
new file mode 100644
index 000000000..a234f49bc
--- /dev/null
+++ b/bedwars-common/bedwars-common-impl/src/main/java/com/andrei1058/bedwars/common/util/platform/ServerVersion.java
@@ -0,0 +1,34 @@
+package com.andrei1058.bedwars.common.util.platform;
+
+import lombok.Getter;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+
+@Getter
+public enum ServerVersion {
+ V1_8_8("v1_8_R3", "1.8.9", 8),
+ V1_12_2("v1_12_R2", "1.12.2", 12),
+ V1_13("v1_13_R1", "1.13", 13);
+
+
+ private final String packageName;
+ private final String displayName;
+ private final int numeric;
+
+ ServerVersion(String packageName, String displayName, int numeric) {
+ this.packageName = packageName;
+ this.displayName = displayName;
+ this.numeric = numeric;
+ }
+
+ @Contract(pure = true)
+ public boolean greaterThan(@NotNull ServerVersion serverVersion) {
+ return this.numeric > serverVersion.numeric;
+ }
+
+ @Contract(pure = true)
+ public boolean smallerThan(@NotNull ServerVersion serverVersion) {
+ return this.numeric < serverVersion.numeric;
+ }
+
+}
\ No newline at end of file
diff --git a/bedwars-common/bedwars-common-impl/src/main/java/com/andrei1058/bedwars/common/util/platform/VersionChecker.java b/bedwars-common/bedwars-common-impl/src/main/java/com/andrei1058/bedwars/common/util/platform/VersionChecker.java
new file mode 100644
index 000000000..8b5d9deca
--- /dev/null
+++ b/bedwars-common/bedwars-common-impl/src/main/java/com/andrei1058/bedwars/common/util/platform/VersionChecker.java
@@ -0,0 +1,48 @@
+package com.andrei1058.bedwars.common.util.platform;
+
+import org.bukkit.Bukkit;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.function.Consumer;
+
+public final class VersionChecker {
+
+ private VersionChecker(){}
+
+ /**
+ * @param supportedVersions collection of supported versions.
+ * @return true if server version is not supported.
+ */
+ public static boolean performVersionCheck(Collection supportedVersions) {
+ return inCollection(getPackageVersion(), supportedVersions);
+ }
+
+ /**
+ * @param supportedVersions collection of supported versions.
+ * @param callback logic applied when server version is not supported.
+ * It returns the version package name. E.g. v1_8_R1.
+ * @return true if server version is not supported.
+ */
+ public static boolean performVersionCheck(
+ @NotNull Collection supportedVersions,
+ Consumer callback
+ ) {
+ String packageVersion = getPackageVersion();
+
+ if (inCollection(packageVersion, supportedVersions)) {
+ return false;
+ }
+
+ callback.accept(packageVersion);
+ return true;
+ }
+
+ private static boolean inCollection(String packageName, @NotNull Collection supportedVersions) {
+ return supportedVersions.stream().anyMatch(version -> version.getPackageName().equals(packageName));
+ }
+
+ private static String getPackageVersion() {
+ return Bukkit.getServer().getClass().getName().split("\\.")[3];
+ }
+}
diff --git a/bedwars-common/pom.xml b/bedwars-common/pom.xml
new file mode 100644
index 000000000..053d88ad7
--- /dev/null
+++ b/bedwars-common/pom.xml
@@ -0,0 +1,40 @@
+
+
+ 4.0.0
+
+ com.andrei1058.bedwars
+ BedWars1058
+ 23.10.1-SNAPSHOT
+
+
+ com.andrei1058.bedwars.common
+ bedwars-common
+ pom
+
+ bedwars-common-api
+ bedwars-common-impl
+
+
+
+ 11
+ 11
+ UTF-8
+
+
+
+
+ org.spigotmc
+ spigot-api
+ 1.8.8-R0.1-SNAPSHOT
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+ provided
+
+
+
+
\ No newline at end of file
diff --git a/bedwars-connector/bedwars-connector-api/pom.xml b/bedwars-connector/bedwars-connector-api/pom.xml
new file mode 100644
index 000000000..ce5c9de0e
--- /dev/null
+++ b/bedwars-connector/bedwars-connector-api/pom.xml
@@ -0,0 +1,31 @@
+
+
+ 4.0.0
+
+ com.andrei1058.bedwars
+ BedWars1058
+ 23.10.1-SNAPSHOT
+ ../../pom.xml
+
+
+ com.andrei1058.bedwars.connector.api
+ bedwars-connector-api
+
+
+ 11
+ 11
+ UTF-8
+
+
+
+
+ com.andrei1058.bedwars.common.api
+ bedwars-common-api
+ ${project.version}
+ provided
+
+
+
+
\ No newline at end of file
diff --git a/bedwars-connector/bedwars-connector-api/src/main/java/com/andrei1058/bedwars/connector/api/IBedWarsConnector.java b/bedwars-connector/bedwars-connector-api/src/main/java/com/andrei1058/bedwars/connector/api/IBedWarsConnector.java
new file mode 100644
index 000000000..0b8a9a875
--- /dev/null
+++ b/bedwars-connector/bedwars-connector-api/src/main/java/com/andrei1058/bedwars/connector/api/IBedWarsConnector.java
@@ -0,0 +1,4 @@
+package com.andrei1058.bedwars.connector.api;
+
+public interface IBedWarsConnector {
+}
diff --git a/bedwars-connector/bedwars-connector-plugin/pom.xml b/bedwars-connector/bedwars-connector-plugin/pom.xml
new file mode 100644
index 000000000..557c018b5
--- /dev/null
+++ b/bedwars-connector/bedwars-connector-plugin/pom.xml
@@ -0,0 +1,48 @@
+
+
+ 4.0.0
+
+ com.andrei1058.bedwars
+ BedWars1058
+ 23.10.1-SNAPSHOT
+ ../../pom.xml
+
+
+ com.andrei1058.bedwars.connector.api
+ bedwars-connector-plugin
+
+
+ 11
+ 11
+ UTF-8
+
+
+
+
+ com.andrei1058.bedwars.connector.api
+ bedwars-connector-api
+ ${project.version}
+
+
+ org.spigotmc
+ spigot-api
+ 1.8.8-R0.1-SNAPSHOT
+ provided
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+ provided
+
+
+ com.andrei1058.bedwars.common
+ bedwars-common-impl
+ ${project.version}
+ compile
+
+
+
+
\ No newline at end of file
diff --git a/bedwars-connector/bedwars-connector-plugin/src/main/java/dev/andrei1058/bedwars/connector/BedWarsConnector.java b/bedwars-connector/bedwars-connector-plugin/src/main/java/dev/andrei1058/bedwars/connector/BedWarsConnector.java
new file mode 100644
index 000000000..bc88877e6
--- /dev/null
+++ b/bedwars-connector/bedwars-connector-plugin/src/main/java/dev/andrei1058/bedwars/connector/BedWarsConnector.java
@@ -0,0 +1,51 @@
+package dev.andrei1058.bedwars.connector;
+
+import com.andrei1058.bedwars.common.util.platform.ServerVersion;
+import com.andrei1058.bedwars.common.util.platform.VersionChecker;
+import org.bukkit.Bukkit;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.logging.Logger;
+
+public class BedWarsConnector extends JavaPlugin {
+
+ private static final Collection SUPPORTED_VERSIONS = List.of(
+ ServerVersion.V1_8_8,
+ ServerVersion.V1_12_2,
+ ServerVersion.V1_13
+ );
+
+ public void onLoad() {
+ // define logger
+ var out = Bukkit.getLogger();
+
+ if (versionNotSupportedCheck(out)) {
+ return;
+ }
+
+ // todo init stuff
+ }
+
+ public void onEnable() {
+ // define logger
+ var out = Bukkit.getLogger();
+
+ if (versionNotSupportedCheck(out)) {
+ Bukkit.getPluginManager().disablePlugin(this);
+ return;
+ }
+
+ // todo init stuff
+ }
+
+ /**
+ * @return true when the platform is not supported.
+ */
+ private static boolean versionNotSupportedCheck(Logger out) {
+ return VersionChecker.performVersionCheck(SUPPORTED_VERSIONS,
+ (pack) -> out.severe("Your server version is not supported: "+pack)
+ );
+ }
+}
diff --git a/bedwars-connector/bedwars-connector-plugin/src/main/resources/plugin.yml b/bedwars-connector/bedwars-connector-plugin/src/main/resources/plugin.yml
new file mode 100644
index 000000000..52d396b7c
--- /dev/null
+++ b/bedwars-connector/bedwars-connector-plugin/src/main/resources/plugin.yml
@@ -0,0 +1,7 @@
+name: BedWars1058-Connector
+api-version: '1.13'
+version: ${project.version}
+author: andrei1058
+description: Proxy connector for BedWars1058
+main: dev.andrei1058.bedwars.connector.BedWarsConnector
+softdepend: [Vault,PlaceholderAPI,Citizens,Parties,VipFeatures,PartyAndFriends,Spigot-Party-API-PAF]
diff --git a/bedwars-connector/pom.xml b/bedwars-connector/pom.xml
new file mode 100644
index 000000000..bcdca86a1
--- /dev/null
+++ b/bedwars-connector/pom.xml
@@ -0,0 +1,20 @@
+
+
+ 4.0.0
+
+ com.andrei1058.bedwars
+ BedWars1058
+ 23.10.1-SNAPSHOT
+
+
+ bedwars-connector
+
+
+ 11
+ 11
+ UTF-8
+
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index f60d95297..a3c951bf3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -113,6 +113,10 @@
versionsupport_v1_19_R3
versionsupport_v1_20_R1
versionsupport_v1_20_R2
+ bedwars-connector
+ bedwars-connector/bedwars-connector-api
+ bedwars-connector/bedwars-connector-plugin
+ bedwars-common