Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
1d4561e
Adding the DataManager interface and removing the old DataManager
TurboJax Feb 7, 2026
2cbb4c9
More database implementation stuff...
duffmansjnr-hub Feb 8, 2026
06f37c3
Fixing compilation errors regarding the locations of classes
TurboJax Feb 9, 2026
1f39f5e
Merge main branch into database
TurboJax Feb 13, 2026
b846152
renaming DataManager#createFile to runSetup
TurboJax Feb 16, 2026
aff8730
Removing runSetup and save from DataManager because they aren't neede…
TurboJax Feb 17, 2026
ff3efc1
Making H2Database implement DataManager and implementing DataManager#…
TurboJax Feb 17, 2026
7dc4f57
Adding H2 as a dependency for the project
TurboJax Feb 17, 2026
8b146a1
Removing save from H2Database
TurboJax Feb 17, 2026
5f1ea5b
Making the trust getters and setters use Sets instead of Lists.
TurboJax Feb 18, 2026
ad0b831
Using a SLF4J logger specific to the H2Database instance. Also removi…
TurboJax Feb 18, 2026
7d30a14
Implementing H2Database#getTrusted
TurboJax Feb 18, 2026
e84bf67
Merge branch 'main' of https://github.com/CatAdmirer/Infuse into data…
TurboJax Feb 18, 2026
7f24dcc
Moving the DataManager implementations out of that database folder
TurboJax Feb 18, 2026
b3e0f5b
Adding default implementations for DataManager#addTrust and DataManag…
TurboJax Feb 18, 2026
8954b12
Implementing more trust-related sql queries
TurboJax Feb 18, 2026
c1c6a87
Adding integer serialization methods to EffectMapping
TurboJax Feb 18, 2026
1451f84
Resolving merge conflicts with upstream/main
TurboJax Jun 9, 2026
9d23ed4
Using OfflinePlayers instead of UUIDs for getters/setters and updatin…
TurboJax Jun 12, 2026
2624ca3
Updating the PlayerData class with getters and setters for each bit o…
TurboJax Jun 12, 2026
4404d62
Removing PlayerData due to worries about desync.
TurboJax Jun 12, 2026
30a38ce
Removing add/set trust overrides from YamlDataManager
TurboJax Jun 12, 2026
0ef0dc5
Validating slot in setEffect
TurboJax Jun 12, 2026
ec93125
removing hasEffect override in YamlDataManager
TurboJax Jun 12, 2026
e31cb7a
updating the params in YamlDataManager
TurboJax Jun 12, 2026
4c32a33
using default removeEffect in YamlDataManager
TurboJax Jun 12, 2026
7996b60
changing the default control mode to "command"
TurboJax Jun 12, 2026
dea86b7
Finishing the first version of the h2 database implementation
TurboJax Jun 12, 2026
fef4f50
removing some extra comments and updating logging
TurboJax Jun 12, 2026
1325497
Removing plugin enabled checks and fixing YamlDataManager#createFile
TurboJax Jun 12, 2026
6fc7b1f
Adding a config for the storage mode
TurboJax Jun 12, 2026
e02286e
Adding the storage_mode config to the MainConfig class and parsing it…
TurboJax Jun 12, 2026
1294fbc
Resolving various ide warnings and fixing some DataManager usage errors
TurboJax Jun 12, 2026
2f67945
Adding the DataCache class for in-memory storage
TurboJax Jun 12, 2026
ee5c672
Implementing the DataCache in the h2 data manager
TurboJax Jun 12, 2026
4dcdb66
exposing internal datacache storage objects publicly bc i dont have a…
TurboJax Jun 12, 2026
9ed0717
quick todo
TurboJax Jun 12, 2026
7a5c541
Loading data into the cache on load
TurboJax Jun 13, 2026
e885202
Making a class that helps with async data handling
TurboJax Jun 13, 2026
bfbd8d9
Using the AsyncDataManager in the H2DataManager class
TurboJax Jun 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ repositories {
dependencies {
compileOnly(libs.placeholderapi)
paperweight.paperDevBundle("${libs.versions.minecraft.get()}+")
compileOnly(libs.h2)
}

tasks.runServer {
Expand All @@ -38,7 +39,8 @@ tasks.withType<JavaCompile>().configureEach {

tasks.processResources {
val props = mapOf("version" to version,
"mcVersion" to libs.versions.minecraft.get())
"mcVersion" to libs.versions.minecraft.get(),
"h2Version" to libs.versions.h2.get())
filesMatching("plugin.yml") {
expand(props)
}
Expand All @@ -47,4 +49,5 @@ tasks.processResources {
tasks.register("resetAndRun") {
delete("run/plugins/$rootProject.name")
finalizedBy("runServer")
description = "Resets the plugin's data directory and then runs a server"
}
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ minecraft = "26.1.2"
placeholderapi = "2.11.6"
run-paper = "3.0.2"
paperweight = "2.0.0-beta.21"
h2 = "2.4.240"

[plugins]
paperweight = { id = "io.papermc.paperweight.userdev", version.ref = "paperweight" }
run-paper = { id = "xyz.jpenilla.run-paper", version.ref = "run-paper" }

[libraries]
placeholderapi = { module = "me.clip:placeholderapi", version.ref = "placeholderapi" }
h2 = { module = "com.h2database:h2", version.ref = "h2" }
40 changes: 20 additions & 20 deletions src/main/java/com/catadmirer/infuseSMP/EffectConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ public static Material menuBackgroundColor(int effectId) {
case EffectIds.EMERALD -> Material.LIME_STAINED_GLASS_PANE;
case EffectIds.ENDER -> Material.PURPLE_STAINED_GLASS_PANE;
case EffectIds.FEATHER -> Material.WHITE_STAINED_GLASS_PANE;
case EffectIds.FIRE -> Material.ORANGE_STAINED_GLASS_PANE;
case EffectIds.FROST -> Material.LIGHT_BLUE_STAINED_GLASS_PANE;
case EffectIds.HASTE -> Material.ORANGE_STAINED_GLASS_PANE;
case EffectIds.HEART -> Material.RED_STAINED_GLASS_PANE;
case EffectIds.FIRE,
EffectIds.HASTE -> Material.ORANGE_STAINED_GLASS_PANE;
case EffectIds.FROST,
EffectIds.SPEED -> Material.LIGHT_BLUE_STAINED_GLASS_PANE;
case EffectIds.HEART,
EffectIds.REGEN,
EffectIds.STRENGTH,
EffectIds.THIEF -> Material.RED_STAINED_GLASS_PANE;
case EffectIds.INVIS -> Material.LIGHT_GRAY_STAINED_GLASS_PANE;
case EffectIds.OCEAN -> Material.BLUE_STAINED_GLASS_PANE;
case EffectIds.REGEN -> Material.RED_STAINED_GLASS_PANE;
case EffectIds.SPEED -> Material.LIGHT_BLUE_STAINED_GLASS_PANE;
case EffectIds.STRENGTH -> Material.RED_STAINED_GLASS_PANE;
case EffectIds.THIEF -> Material.RED_STAINED_GLASS_PANE;
case EffectIds.THUNDER -> Material.YELLOW_STAINED_GLASS_PANE;
default -> null;
};
Expand Down Expand Up @@ -88,21 +88,21 @@ public static Color potionColor(int effectId) {
*/
public static BossBar.Color ritualColor(int effectId) {
return switch (effectId) {
case EffectIds.APOPHIS -> BossBar.Color.PURPLE;
case EffectIds.APOPHIS,
EffectIds.ENDER,
EffectIds.INVIS -> BossBar.Color.PURPLE;
case EffectIds.EMERALD -> BossBar.Color.GREEN;
case EffectIds.ENDER -> BossBar.Color.PURPLE;
case EffectIds.FEATHER -> BossBar.Color.WHITE;
case EffectIds.FIRE -> BossBar.Color.RED;
case EffectIds.FROST -> BossBar.Color.BLUE;
case EffectIds.HASTE -> BossBar.Color.YELLOW;
case EffectIds.HEART -> BossBar.Color.RED;
case EffectIds.INVIS -> BossBar.Color.PURPLE;
case EffectIds.OCEAN -> BossBar.Color.BLUE;
case EffectIds.FIRE,
EffectIds.HEART,
EffectIds.STRENGTH,
EffectIds.THIEF -> BossBar.Color.RED;
case EffectIds.FROST,
EffectIds.OCEAN -> BossBar.Color.BLUE;
case EffectIds.HASTE,
EffectIds.SPEED,
EffectIds.THUNDER -> BossBar.Color.YELLOW;
case EffectIds.REGEN -> BossBar.Color.PINK;
case EffectIds.SPEED -> BossBar.Color.YELLOW;
case EffectIds.STRENGTH -> BossBar.Color.RED;
case EffectIds.THIEF -> BossBar.Color.RED;
case EffectIds.THUNDER -> BossBar.Color.YELLOW;
default -> null;
};
}
Expand Down
16 changes: 8 additions & 8 deletions src/main/java/com/catadmirer/infuseSMP/EquipEffect.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ public void safeEquip(Player player, InfuseEffect effect) {
*/
private boolean equipEffect(Player player, InfuseEffect effect, String slot) {
// Checking for an effect in the slot.
InfuseEffect currentEffect = plugin.getDataManager().getEffect(player.getUniqueId(), slot);
InfuseEffect currentEffect = plugin.getDataManager().getEffect(player, slot);
if (currentEffect != null) return false;

// Equipping the effect to the slot.
plugin.getDataManager().setEffect(player.getUniqueId(), slot, effect);
plugin.getDataManager().setEffect(player, slot, effect);
new EffectEquipEvent(player, effect, slot).callEvent();

Message msg = new Message(MessageType.EFFECT_EQUIPPED);
Expand Down Expand Up @@ -111,8 +111,8 @@ public void onPlayerConsume(PlayerItemConsumeEvent event) {
@EventHandler
public void onPlayerDeath(PlayerDeathEvent event) {
Player player = event.getEntity();
InfuseEffect effect1 = plugin.getDataManager().getEffect(player.getUniqueId(), "1");
InfuseEffect effect2 = plugin.getDataManager().getEffect(player.getUniqueId(), "2");
InfuseEffect effect1 = plugin.getDataManager().getEffect(player, "1");
InfuseEffect effect2 = plugin.getDataManager().getEffect(player, "2");
String dropMode = plugin.getMainConfig().effectDrops();
Random rand = new Random();
switch (dropMode.toLowerCase()) {
Expand Down Expand Up @@ -153,10 +153,10 @@ public void onPlayerDeath(PlayerDeathEvent event) {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
InfuseEffect effect = plugin.getDataManager().getEffect(player.getUniqueId(), "1");
InfuseEffect effect = plugin.getDataManager().getEffect(player, "1");
if (effect != null) new EffectEquipEvent(player, effect, "1").callEvent();

effect = plugin.getDataManager().getEffect(player.getUniqueId(), "2");
effect = plugin.getDataManager().getEffect(player, "2");
if (effect != null) new EffectEquipEvent(player, effect, "2").callEvent();
}

Expand All @@ -168,11 +168,11 @@ public void onPlayerJoin(PlayerJoinEvent event) {
*/
private void dropEffect(Player player, String slot) {
// Getting the equipped effect from the data file.
InfuseEffect effect = plugin.getDataManager().getEffect(player.getUniqueId(), slot);
InfuseEffect effect = plugin.getDataManager().getEffect(player, slot);
if (effect == null) return;

// Removing the effect from the player.
plugin.getDataManager().removeEffect(player.getUniqueId(), slot);
plugin.getDataManager().removeEffect(player, slot);
new EffectUnequipEvent(player, effect, slot).callEvent();

// Dropping the effect item at the player's location
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/catadmirer/infuseSMP/GlobalLoop.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ public void stop() {
public void run() {
for (Player player : Bukkit.getOnlinePlayers()) {
// Getting the player's equipped effects
InfuseEffect lEffect = plugin.getDataManager().getEffect(player.getUniqueId(), "1");
InfuseEffect rEffect = plugin.getDataManager().getEffect(player.getUniqueId(), "2");
InfuseEffect lEffect = plugin.getDataManager().getEffect(player, "1");
InfuseEffect rEffect = plugin.getDataManager().getEffect(player, "2");

// Applying passive effects to the player
if (lEffect != null) {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/catadmirer/infuseSMP/HitTracker.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
public class HitTracker implements Listener {
private final Infuse plugin;
private final Map<UUID,Integer> hitTracker = new HashMap<>();
Queue<Runnable> decayQueue = new ConcurrentLinkedQueue<>();
final Queue<Runnable> decayQueue = new ConcurrentLinkedQueue<>();

public HitTracker(Infuse plugin) {
this.plugin = plugin;
Expand Down Expand Up @@ -89,7 +89,7 @@ public void onPlayerHit(EntityDamageByEntityEvent event) {
decayQueue.remove();
decayTask.run();
}
}, hitCounterDecaySeconds * 20);
}, hitCounterDecaySeconds * 20L);
}

/**
Expand Down
44 changes: 27 additions & 17 deletions src/main/java/com/catadmirer/infuseSMP/Infuse.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import com.catadmirer.infuseSMP.extraeffects.*;
import com.catadmirer.infuseSMP.managers.*;
import com.catadmirer.infuseSMP.placeholders.InfusePlaceholders;
import com.catadmirer.infuseSMP.playerdata.DataManager;
import com.catadmirer.infuseSMP.playerdata.H2DataManager;
import com.catadmirer.infuseSMP.playerdata.YamlDataManager;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
Expand Down Expand Up @@ -41,7 +44,7 @@ public class Infuse extends JavaPlugin implements Listener {
public static final Logger LOGGER = LoggerFactory.getLogger("Infuse");
public static final NamespacedKey EFFECT_KEY = new NamespacedKey("infuse", "effect_key");

private final DataManager dataManager;
private DataManager dataManager;
private final MainConfig mainConfig;
private final GlobalLoop loop;
private final RecipeManager recipeManager;
Expand All @@ -54,7 +57,6 @@ public static Infuse getInstance() {
public Infuse() {
new ApophisManager(this);
this.mainConfig = new MainConfig(this);
this.dataManager = new DataManager(this);
this.loop = new GlobalLoop(this);
this.recipeManager = new RecipeManager(this);
this.particleManager = new ParticleManager(this);
Expand All @@ -74,13 +76,26 @@ public void onEnable() {

// Loading the config
mainConfig.load();

// Loading the data manager
dataManager.load();

// Applying config updates
MessageConfig.applyUpdates();
mainConfig.applyUpdates();

// Loading the data manager
// If no valid data manager is found, disable the plugin
dataManager = switch (mainConfig.storageMode().toLowerCase()) {
case "h2" -> new H2DataManager(this);
case "yaml" -> new YamlDataManager(this);
default -> null;
};

if (dataManager == null) {
LOGGER.error("Could not read a valid storage type from the config! Disabling Infuse.");
Bukkit.getPluginManager().disablePlugin(this);
return;
}

dataManager.load();
dataManager.applyUpdates();

// Initializing the recipe manager
Expand Down Expand Up @@ -139,7 +154,7 @@ private void registerCommands() {

getCommand("draw").setExecutor(new Draw());

getCommand("controls").setExecutor((sender, command, label, args) -> {
getCommand("controls").setExecutor((sender, _, _, args) -> {
// Making sure only players can run the command
if (!(sender instanceof Player player)) {
sender.sendMessage(new Message(MessageType.ERROR_NOT_PLAYER).toComponent());
Expand All @@ -162,11 +177,11 @@ private void registerCommands() {
}

// Setting the control mode for the player
dataManager.setControlMode(player.getUniqueId(), choice);
dataManager.setControlMode(player, choice);
player.addAttachment(this, "ability.use", choice.equals("command"));
return true;
});
getCommand("controls").setTabCompleter((sender, command, label, args) -> {
getCommand("controls").setTabCompleter((_, _, _, args) -> {
if (args.length == 1) {
return Stream.of("command", "offhand").filter(opt -> opt.startsWith(args[0])).toList();
}
Expand Down Expand Up @@ -242,9 +257,7 @@ public void onPlayerDeath(PlayerDeathEvent event) {

if (dropHead) {
ItemStack playerHead = new ItemStack(Material.PLAYER_HEAD);
playerHead.editMeta(SkullMeta.class, meta -> {
meta.setOwningPlayer(player);
});
playerHead.editMeta(SkullMeta.class, meta -> meta.setOwningPlayer(player));
player.getWorld().dropItem(player.getLocation(), playerHead);
}
}
Expand All @@ -261,9 +274,7 @@ private String getLatestVersion() {
.uri(URI.create("https://api.modrinth.com/v2/project/infusesmp/version"))
.build();

HttpClient client = HttpClient.newHttpClient();

try {
try (HttpClient client = HttpClient.newHttpClient()) {
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());

// Handling http error codes
Expand Down Expand Up @@ -303,9 +314,8 @@ private void onJoin(PlayerJoinEvent event) {
InfuseEffect.getRegisteredEffects().values().stream().map(recipeManager::getRecipeKey).forEach(player::discoverRecipe);

// Telling the player their current control mode
String controlMode = dataManager.getControlMode(player.getUniqueId());
if (controlMode == null) controlMode = "Offhand";
boolean offhandEnabled = controlMode.equalsIgnoreCase("Offhand");
String controlMode = dataManager.getControlMode(player);
boolean offhandEnabled = controlMode.equalsIgnoreCase("offhand");
player.addAttachment(this, "ability.use", !offhandEnabled);

Message msg = new Message(MessageType.JOIN_ABILITY_NOTIFY);
Expand Down
57 changes: 32 additions & 25 deletions src/main/java/com/catadmirer/infuseSMP/MainConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;

import java.io.File;
import java.io.IOException;
Expand All @@ -24,8 +23,6 @@ public MainConfig(Infuse plugin) {

/**
* Reloads the configuration.
*
* @return Whether the configuration was loaded successfully.
*/
public boolean load() {
// Not doing anything if the plugin isn't enabled
Expand All @@ -48,17 +45,14 @@ public boolean load() {
} catch (InvalidConfigurationException e) {
Infuse.LOGGER.warn("{} contains an invalid YAML configuration. Verify the contents of the file.", file.getName());
} catch (IOException e) {
Infuse.LOGGER.error("Could not find {}. Check that it exists.", file.getName());
e.printStackTrace();
Infuse.LOGGER.error("Could not find {}. Check that it exists.", file.getName(), e);
}

return false;
}

/**
* Writes the config to the file.
*
* @return Whether or not the config was successfully written.
*/
public boolean save() {
// Not doing anything if the plugin isn't enabled
Expand Down Expand Up @@ -150,9 +144,8 @@ public boolean enableThief() {

/**
* Gets the amount of each effect that can be crafted
*
*
* @param effect The effect to check
*
* @return The number of effects that can be crafted of the specified {@link InfuseEffect}.
*/
public int getCraftLimit(InfuseEffect effect) {
Expand Down Expand Up @@ -224,22 +217,6 @@ public float emeraldPercentExpToShare() {
return Math.clamp((float) config.getDouble("emerald.percent_xp_to_share"), 0, 1);
}

public void applyUpdates() {
if (!config.contains("invis_deaths")) config.set("invis_deaths", null);
if (!config.contains("invis.hide_kills")) config.set("invis.hide_kills", false);
if (!config.contains("invis.hide_deaths")) config.set("invis.hide_deaths", false);
if (!config.contains("haste.enchantment.looting_level")) config.set("haste.enchantment.looting_level", 5);
if (!config.contains("haste.enchantment.fortune_level")) config.set("haste.enchantment.fortune_level", 5);
if (!config.contains("haste.enchantment.efficiency_level")) config.set("haste.enchantment.efficiency_level", 10);
if (!config.contains("haste.enchantment.unbreaking_level")) config.set("haste.enchantment.unbreaking_level", 5);
if (!config.contains("hit_counter_decay_seconds")) config.set("hit_counter_decay_seconds", 15);
if (!config.contains("emerald.xp_stolen_per_hit")) config.set("emerald.xp_stolen_per_hit", 15);
if (!config.contains("emerald.xp_stolen_percent")) config.set("emerald.xp_stolen_percent", 1);
if (!config.contains("emerald.percent_xp_to_share")) config.set("emerald.percent_xp_to_share", 0.5);

save();
}

public int emeraldLootingLevel() {
return config.getInt("emerald.enchantment.looting_level");
}
Expand All @@ -255,4 +232,34 @@ public int hasteEfficiencyLevel() {
public int hasteUnbreakingLevel() {
return config.getInt("haste.enchantment.unbreaking_level");
}

public String storageMode() {
return config.getString("storage_mode", "yaml");
}

public void applyUpdates() {
if (!config.contains("invis_deaths")) config.set("invis_deaths", null);
if (!config.contains("invis.hide_kills")) config.set("invis.hide_kills", false);
if (!config.contains("invis.hide_deaths")) config.set("invis.hide_deaths", false);
if (!config.contains("haste.enchantment.looting_level")) config.set("haste.enchantment.looting_level", 5);
if (!config.contains("haste.enchantment.fortune_level")) config.set("haste.enchantment.fortune_level", 5);
if (!config.contains("haste.enchantment.efficiency_level")) config.set("haste.enchantment.efficiency_level", 10);
if (!config.contains("haste.enchantment.unbreaking_level")) config.set("haste.enchantment.unbreaking_level", 5);
if (!config.contains("hit_counter_decay_seconds")) config.set("hit_counter_decay_seconds", 15);
if (!config.contains("emerald.xp_stolen_per_hit")) config.set("emerald.xp_stolen_per_hit", 15);
if (!config.contains("emerald.xp_stolen_percent")) config.set("emerald.xp_stolen_percent", 1);
if (!config.contains("emerald.percent_xp_to_share")) config.set("emerald.percent_xp_to_share", 0.5);
if (!config.contains("storage_mode")) {
config.set("storage_mode", "YAML");
config.setComments("storage_mode", List.of("# Sets where the data will be stored.",
"# IMPORTANT: Data is not transferred between nodes. To move data to different storage types, export it to YAML then import it.",
"# (Exported data is the same format as the YAML storage mode, so no exporting is needed if you already use the YAML config.)",
"# This config IS NOT UPDATED when you use `/infuse reload`. You need to RESTART THE SERVER to change this config",
"# Supported values:",
"# - \"H2\"",
"# - \"YAML\""));
}

save();
}
}
Loading