diff --git a/pom.xml b/pom.xml
index 910b3e1..311e33b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -45,6 +45,12 @@
4.7.0
provided
+
+ org.mongodb
+ mongo-java-driver
+ 3.8.2
+ compile
+
diff --git a/src/main/java/dev/lugami/otaku/Main.java b/src/main/java/dev/lugami/otaku/Main.java
index 8516a21..d7f144d 100644
--- a/src/main/java/dev/lugami/otaku/Main.java
+++ b/src/main/java/dev/lugami/otaku/Main.java
@@ -1,5 +1,10 @@
package dev.lugami.otaku;
+import com.mongodb.MongoClient;
+import com.mongodb.MongoClientOptions;
+import com.mongodb.MongoCredential;
+import com.mongodb.ServerAddress;
+import com.mongodb.client.MongoDatabase;
import com.qrakn.honcho.Honcho;
import dev.lugami.otaku.board.Board;
import dev.lugami.otaku.commands.*;
@@ -8,11 +13,12 @@ import dev.lugami.otaku.essentials.Essentials;
import dev.lugami.otaku.hotbar.Hotbar;
import dev.lugami.otaku.kit.Kit;
import dev.lugami.otaku.listener.FFAListener;
-import dev.lugami.otaku.listener.Listeners;
+import dev.lugami.otaku.listener.GeneralListeners;
import dev.lugami.otaku.profile.Profile;
import dev.lugami.otaku.profile.ProfileListener;
import dev.lugami.otaku.utils.CombatManager;
import dev.lugami.otaku.utils.EnderpearlManager;
+import dev.lugami.otaku.utils.SaveMethodType;
import dev.lugami.otaku.utils.board.Assemble;
import dev.lugami.otaku.utils.board.AssembleStyle;
import dev.lugami.otaku.utils.config.BasicConfigurationFile;
@@ -41,7 +47,8 @@ public class Main extends JavaPlugin {
@Getter private Assemble board;
@Getter private CombatManager combatManager;
@Getter private EnderpearlManager enderpearlManager;
-
+ @Getter private MongoDatabase mongoDatabase;
+ @Getter private SaveMethodType saveMethodType;
public void onEnable() {
setInstance(this);
honcho = new Honcho(this);
@@ -51,13 +58,22 @@ public class Main extends JavaPlugin {
profileConfig = new BasicConfigurationFile(this, "profiles");
kitsConfig = new BasicConfigurationFile(this, "kits");
board = new Assemble(this, new Board(), 2, false, AssembleStyle.MODIFIED, true);
+ try {
+ saveMethodType = SaveMethodType.valueOf(mainConfig.getString("SAVE_METHOD"));
+ } catch (Exception ex) {
+ saveMethodType = SaveMethodType.defaultTo();
+ }
combatManager = new CombatManager();
combatManager.runTaskTimer(this, 0, 2);
enderpearlManager = new EnderpearlManager();
enderpearlManager.runTaskTimer(this, 0, 2);
+ if (saveMethodType == SaveMethodType.MONGO) {
+ loadMongo();
+ }
Kit.init();
Hotbar.init();
- Arrays.asList(new FFAListener(), new Listeners(), new ProfileListener(), new MenuListener()).forEach(listener -> Bukkit.getPluginManager().registerEvents(listener, this));
+ Profile.init();
+ Arrays.asList(new FFAListener(), new GeneralListeners(), new ProfileListener(), new MenuListener()).forEach(listener -> Bukkit.getPluginManager().registerEvents(listener, this));
Arrays.asList(new FFACommand(), new FFASetSpawnCommand(), new KitSetIconCommand(), new KitCreateCommand(), new KitDeleteCommand(), new KitGetLoadoutCommand(), new KitSetLoadoutCommand(), new KitsCommand(), new KitSetLocationCommand(), new MainMenuCommand(), new FFAJoinCommand(), new FFAQuitCommand(), new KitCommand(), new ReKitCommand()).forEach(command -> honcho.registerCommand(command));
getServer().getWorlds().forEach(essentials::clearEntities);
}
@@ -68,7 +84,25 @@ public class Main extends JavaPlugin {
player.kickPlayer("Server restarting");
}
Kit.saveAll();
- //Profile.saveAll();
Profile.removeAll();
}
+
+ private void loadMongo() {
+ if (mainConfig.getBoolean("MONGO.AUTHENTICATION.ENABLED")) {
+ mongoDatabase = new MongoClient(
+ new ServerAddress(
+ mainConfig.getString("MONGO.HOST"),
+ mainConfig.getInteger("MONGO.PORT")
+ ),
+ MongoCredential.createCredential(
+ mainConfig.getString("MONGO.AUTHENTICATION.USERNAME"),
+ "admin", mainConfig.getString("MONGO.AUTHENTICATION.PASSWORD").toCharArray()
+ ),
+ MongoClientOptions.builder().build()
+ ).getDatabase(mainConfig.getString("MONGO.DATABASE"));
+ } else {
+ mongoDatabase = new MongoClient(mainConfig.getString("MONGO.HOST"), mainConfig.getInteger("MONGO.PORT"))
+ .getDatabase(mainConfig.getString("MONGO.DATABASE"));
+ }
+ }
}
\ No newline at end of file
diff --git a/src/main/java/dev/lugami/otaku/listener/FFAListener.java b/src/main/java/dev/lugami/otaku/listener/FFAListener.java
index 3b1a66c..b3a3474 100644
--- a/src/main/java/dev/lugami/otaku/listener/FFAListener.java
+++ b/src/main/java/dev/lugami/otaku/listener/FFAListener.java
@@ -9,8 +9,8 @@ import dev.lugami.otaku.hotbar.HotbarItem;
import dev.lugami.otaku.kit.Kit;
import dev.lugami.otaku.kit.KitLoadout;
import dev.lugami.otaku.profile.Profile;
-import dev.lugami.otaku.profile.data.ProfileState;
import dev.lugami.otaku.profile.data.ProfileKitData;
+import dev.lugami.otaku.profile.data.ProfileState;
import dev.lugami.otaku.utils.*;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@@ -20,6 +20,8 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
+import org.bukkit.event.entity.EntityDamageByEntityEvent;
+import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
@@ -193,5 +195,29 @@ public class FFAListener implements Listener {
}
}
+ @EventHandler
+ public void onDamage(EntityDamageEvent event) {
+ if (event.getEntity() instanceof Player) {
+ Player player = (Player) event.getEntity();
+ if (event.getCause() == EntityDamageEvent.DamageCause.FALL) {
+ if (Profile.getOrCreate(player).getState() == ProfileState.PLAYING) {
+ event.setCancelled(Profile.getOrCreate(player).getFFA().getKitRules().isNoFall());
+ }
+ }
+ } else {
+ return;
+ }
+ }
+
+ @EventHandler
+ public void onDamage2(EntityDamageByEntityEvent event) {
+ if (event.getEntity() instanceof Player) {
+ Player player = (Player) event.getEntity();
+ if (Profile.getOrCreate(player).getFFA().getKitRules().isNoDamage()) {
+ event.setDamage(0.0);
+ }
+ }
+ }
+
}
diff --git a/src/main/java/dev/lugami/otaku/listener/Listeners.java b/src/main/java/dev/lugami/otaku/listener/GeneralListeners.java
similarity index 99%
rename from src/main/java/dev/lugami/otaku/listener/Listeners.java
rename to src/main/java/dev/lugami/otaku/listener/GeneralListeners.java
index 419c6cb..e38121b 100644
--- a/src/main/java/dev/lugami/otaku/listener/Listeners.java
+++ b/src/main/java/dev/lugami/otaku/listener/GeneralListeners.java
@@ -22,7 +22,7 @@ import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.player.*;
import org.bukkit.inventory.ItemStack;
-public class Listeners implements Listener {
+public class GeneralListeners implements Listener {
@EventHandler
public void drop(PlayerDropItemEvent event) {
diff --git a/src/main/java/dev/lugami/otaku/profile/Profile.java b/src/main/java/dev/lugami/otaku/profile/Profile.java
index 3ba7fd3..8ea278d 100644
--- a/src/main/java/dev/lugami/otaku/profile/Profile.java
+++ b/src/main/java/dev/lugami/otaku/profile/Profile.java
@@ -1,17 +1,24 @@
package dev.lugami.otaku.profile;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.model.Filters;
+import com.mongodb.client.model.ReplaceOptions;
import dev.lugami.otaku.Main;
import dev.lugami.otaku.kit.Kit;
import dev.lugami.otaku.profile.data.ProfileKitData;
import dev.lugami.otaku.profile.data.ProfileSettings;
import dev.lugami.otaku.profile.data.ProfileState;
+import dev.lugami.otaku.utils.CC;
import dev.lugami.otaku.utils.Cooldown;
import dev.lugami.otaku.utils.FFACache;
+import dev.lugami.otaku.utils.SaveMethodType;
import lombok.Data;
import lombok.Getter;
+import org.bson.Document;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
import java.io.IOException;
import java.util.*;
@@ -21,6 +28,7 @@ public class Profile {
@Getter
private static List profiles = new ArrayList<>();
+ @Getter private static MongoCollection collection;
private Player player;
private ProfileState state;
@@ -28,6 +36,35 @@ public class Profile {
private ProfileSettings settings;
private Cooldown reKitCooldown;
+ public static void init() {
+ if (Main.getInstance().getSaveMethodType() == SaveMethodType.MONGO) {
+ collection = Main.getInstance().getMongoDatabase().getCollection("profiles");
+ }
+
+ // Players might have joined before the plugin finished loading
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ Profile profile = new Profile(player.getUniqueId());
+
+ try {
+ profile.load();
+ } catch (Exception e) {
+ player.kickPlayer(CC.RED + "The server is loading...");
+ continue;
+ }
+ new Profile(player.getUniqueId());
+ }
+
+ // Save every 5 minutes to prevent data loss
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ for (Profile profile : Profile.getProfiles()) {
+ profile.save();
+ }
+ }
+ }.runTaskTimerAsynchronously(Main.getInstance(), 6000L, 6000L);
+ }
+
public Profile(UUID uuid) {
player = Bukkit.getPlayer(uuid);
state = ProfileState.LOBBY;
@@ -81,37 +118,93 @@ public class Profile {
}
void load() {
- ConfigurationSection mainSection = Main.getInstance().getProfileConfig().getConfiguration().getConfigurationSection("stats." + getPlayer().getName());
- for (Kit kit : Kit.getKits()) {
- if (mainSection.getConfigurationSection(kit.getName()) != null) {
- ConfigurationSection kitSection = mainSection.getConfigurationSection(kit.getName());
- ProfileKitData profileKitData = new ProfileKitData();
- profileKitData.kills(kitSection.getInt("kills", 0));
- profileKitData.deaths(kitSection.getInt("deaths", 0));
- profileKitData.killstreak(kitSection.getInt("killstreak", 0));
- kitData.put(kit, profileKitData);
+ if (Main.getInstance().getSaveMethodType() == SaveMethodType.MONGO && collection != null) {
+ Document document = collection.find(Filters.eq("uuid", player.getUniqueId().toString())).first();
+
+ if (document == null) {
+ this.save();
+ return;
}
+
+ Document opts = (Document) document.get("settings");
+ this.settings.scoreboard(opts.getBoolean("scoreboard"));
+ this.settings.autoRekit(opts.getBoolean("autoRekit"));
+ this.settings.dropProtect(opts.getBoolean("dropProtect"));
+
+ Document kitStatistics = (Document) document.get("kitStatistics");
+
+ for (String key : kitStatistics.keySet()) {
+ Document kitDocument = (Document) kitStatistics.get(key);
+ Kit kit = Kit.getByName(key);
+
+ if (kit != null) {
+ ProfileKitData profileKitData = new ProfileKitData();
+ profileKitData.kills(kitDocument.getInteger("kills"));
+ profileKitData.deaths(kitDocument.getInteger("deaths"));
+ profileKitData.killstreak(kitDocument.getInteger("killstreak"));
+
+ kitData.put(kit, profileKitData);
+ }
+ }
+ } else {
+ ConfigurationSection mainSection = Main.getInstance().getProfileConfig().getConfiguration().getConfigurationSection("stats." + getPlayer().getName());
+ for (Kit kit : Kit.getKits()) {
+ if (mainSection.getConfigurationSection(kit.getName()) != null) {
+ ConfigurationSection kitSection = mainSection.getConfigurationSection(kit.getName());
+ ProfileKitData profileKitData = new ProfileKitData();
+ profileKitData.kills(kitSection.getInt("kills", 0));
+ profileKitData.deaths(kitSection.getInt("deaths", 0));
+ profileKitData.killstreak(kitSection.getInt("killstreak", 0));
+ kitData.put(kit, profileKitData);
+ }
+ }
+ settings.scoreboard(Main.getInstance().getProfileConfig().getConfiguration().getBoolean("settings." + getPlayer().getName() + ".scoreboard", true));
+ settings.autoRekit(Main.getInstance().getProfileConfig().getConfiguration().getBoolean("settings." + getPlayer().getName() + ".autoRekit", true));
+ settings.dropProtect(Main.getInstance().getProfileConfig().getConfiguration().getBoolean("settings." + getPlayer().getName() + ".dropProtect", true));
+ if (Main.getInstance().getSaveMethodType() == SaveMethodType.MONGO && collection == null) Bukkit.getLogger().warning("Profile#getCollection was null, so " + player.getName() + "'s profile was loaded using the fallback flatfile method.");
}
- settings.scoreboard(Main.getInstance().getProfileConfig().getConfiguration().getBoolean("settings." + getPlayer().getName() + ".scoreboard", true));
- settings.autoRekit(Main.getInstance().getProfileConfig().getConfiguration().getBoolean("settings." + getPlayer().getName() + ".autoRekit", true));
- settings.dropProtect(Main.getInstance().getProfileConfig().getConfiguration().getBoolean("settings." + getPlayer().getName() + ".dropProtect", true));
}
public void save() {
- for (Kit kit : Kit.getKits()) {
- ProfileKitData profileKitData = kitData.get(kit);
- if (profileKitData == null) profileKitData = new ProfileKitData();
- Main.getInstance().getProfileConfig().getConfiguration().set("stats." + getPlayer().getName() + "." + kit.getName() + ".kills", profileKitData.kills());
- Main.getInstance().getProfileConfig().getConfiguration().set("stats." + getPlayer().getName() + "." + kit.getName() + ".deaths", profileKitData.deaths());
- Main.getInstance().getProfileConfig().getConfiguration().set("stats." + getPlayer().getName() + "." + kit.getName() + ".killstreak", profileKitData.killstreak());
- }
- Main.getInstance().getProfileConfig().getConfiguration().set("settings." + getPlayer().getName() + ".scoreboard", settings.scoreboard());
- Main.getInstance().getProfileConfig().getConfiguration().set("settings." + getPlayer().getName() + ".autoRekit", settings.autoRekit());
- Main.getInstance().getProfileConfig().getConfiguration().set("settings." + getPlayer().getName() + ".dropProtect", settings.dropProtect());
- try {
- Main.getInstance().getProfileConfig().getConfiguration().save(Main.getInstance().getProfileConfig().getFile());
- } catch (IOException e) {
- e.printStackTrace();
+ if (Main.getInstance().getSaveMethodType() == SaveMethodType.MONGO && collection != null) {
+ Document document = new Document();
+ document.put("uuid", player.getUniqueId().toString());
+
+ Document optionsDocument = new Document();
+ optionsDocument.put("scoreboard", settings.scoreboard());
+ optionsDocument.put("autoRekit", settings.autoRekit());
+ optionsDocument.put("dropProtect", settings.dropProtect());
+ document.put("settings", optionsDocument);
+
+ Document kitStatisticsDocument = new Document();
+
+ for (Map.Entry entry : kitData.entrySet()) {
+ Document kitDocument = new Document();
+ kitDocument.put("kills", entry.getValue().kills());
+ kitDocument.put("deaths", entry.getValue().deaths());
+ kitDocument.put("killstreak", entry.getValue().killstreak());
+ kitStatisticsDocument.put(entry.getKey().getName(), kitDocument);
+ }
+
+ document.put("kitStatistics", kitStatisticsDocument);
+ collection.replaceOne(Filters.eq("uuid", player.getUniqueId().toString()), document, new ReplaceOptions().upsert(true));
+ } else {
+ for (Kit kit : Kit.getKits()) {
+ ProfileKitData profileKitData = kitData.get(kit);
+ if (profileKitData == null) profileKitData = new ProfileKitData();
+ Main.getInstance().getProfileConfig().getConfiguration().set("stats." + getPlayer().getName() + "." + kit.getName() + ".kills", profileKitData.kills());
+ Main.getInstance().getProfileConfig().getConfiguration().set("stats." + getPlayer().getName() + "." + kit.getName() + ".deaths", profileKitData.deaths());
+ Main.getInstance().getProfileConfig().getConfiguration().set("stats." + getPlayer().getName() + "." + kit.getName() + ".killstreak", profileKitData.killstreak());
+ }
+ Main.getInstance().getProfileConfig().getConfiguration().set("settings." + getPlayer().getName() + ".scoreboard", settings.scoreboard());
+ Main.getInstance().getProfileConfig().getConfiguration().set("settings." + getPlayer().getName() + ".autoRekit", settings.autoRekit());
+ Main.getInstance().getProfileConfig().getConfiguration().set("settings." + getPlayer().getName() + ".dropProtect", settings.dropProtect());
+ try {
+ Main.getInstance().getProfileConfig().getConfiguration().save(Main.getInstance().getProfileConfig().getFile());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ if (Main.getInstance().getSaveMethodType() == SaveMethodType.MONGO && collection == null) Bukkit.getLogger().warning("Profile#getCollection was null, so " + player.getName() + "'s profile was saved using the fallback flatfile method.");
}
}
@@ -123,8 +216,4 @@ public class Profile {
profiles.clear();
}
- public static void saveAll() {
- for (Profile profile : profiles) profile.save();
- }
-
}
diff --git a/src/main/java/dev/lugami/otaku/utils/SaveMethodType.java b/src/main/java/dev/lugami/otaku/utils/SaveMethodType.java
new file mode 100644
index 0000000..e4cdc99
--- /dev/null
+++ b/src/main/java/dev/lugami/otaku/utils/SaveMethodType.java
@@ -0,0 +1,12 @@
+package dev.lugami.otaku.utils;
+
+public enum SaveMethodType {
+
+ MONGO, FLATFILE;
+
+
+ public static SaveMethodType defaultTo() {
+ return FLATFILE;
+ }
+
+}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index 236f8d6..ed57692 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -1,3 +1,15 @@
+MONGO:
+ HOST: "127.0.0.1"
+ PORT: 27017
+ DATABASE: otaku
+ AUTHENTICATION:
+ ENABLED: false
+ USERNAME: ""
+ PASSWORD: ""
+
+# Possible values: MONGO, FLATFILE
+SAVE_METHOD: "MONGO"
+
HOTBAR_ITEMS:
MAIN_MENU:
MATERIAL: "NETHER_STAR"