Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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: 5 additions & 0 deletions buildSrc/src/main/kotlin/realty-conventions.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ val targetJavaVersion = 21
java.toolchain.languageVersion.set(JavaLanguageVersion.of(targetJavaVersion))

repositories {
mavenLocal()
mavenCentral()
maven {
name = "papermc-repo"
Expand All @@ -27,6 +28,10 @@ repositories {
name = "essentialsx"
url = uri("https://repo.essentialsx.net/releases/")
}
maven {
name = "paradaux-snapshots"
url = uri("https://repo.paradaux.io/snapshots")
}
}

dependencies {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package io.github.md5sha256.realty.database.entity;

import java.util.UUID;

public record PlotOwnerCount(UUID titleHolderId, int plotCount) {}
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package io.github.md5sha256.realty.database.mapper;

import io.github.md5sha256.realty.database.entity.FreeholdContractEntity;
import io.github.md5sha256.realty.database.entity.PlotOwnerCount;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.UUID;

/**
Expand Down Expand Up @@ -144,4 +146,10 @@ int atomicBuy(@NotNull String worldGuardRegionId,

double averagePrice();

/**
* Returns the number of freehold plots owned (as title holder) by each player.
* Only players with at least one plot are included.
*/
@NotNull List<PlotOwnerCount> selectPlotCountsByTitleHolder();

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.md5sha256.realty.database.maria.mapper;

import io.github.md5sha256.realty.database.entity.FreeholdContractEntity;
import io.github.md5sha256.realty.database.entity.PlotOwnerCount;
import io.github.md5sha256.realty.database.mapper.FreeholdContractMapper;
import org.apache.ibatis.annotations.Arg;
import org.apache.ibatis.annotations.ConstructorArgs;
Expand All @@ -10,6 +11,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.UUID;


Expand Down Expand Up @@ -202,4 +204,17 @@ SELECT COALESCE(AVG(price), 0)
""")
double averagePrice();

@Override
@Select("""
SELECT titleHolderId, COUNT(*) AS plotCount
FROM FreeholdContract
WHERE titleHolderId IS NOT NULL
GROUP BY titleHolderId
""")
@ConstructorArgs({
@Arg(column = "titleHolderId", javaType = UUID.class),
@Arg(column = "plotCount", javaType = int.class)
})
@NotNull List<PlotOwnerCount> selectPlotCountsByTitleHolder();

}
1 change: 1 addition & 0 deletions realty-paper/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ dependencies {
exclude(group = "org.bukkit", module = "bukkit")
exclude(group = "org.spigotmc", module = "spigot-api")
}
compileOnly("net.democracycraft:treasury-api:2.0.0-SNAPSHOT")
compileOnly("org.jetbrains:annotations:26.0.2-1")
implementation("org.incendo:cloud-paper:2.0.0-beta.10")
implementation("org.spongepowered:configurate-yaml:4.2.0")
Expand Down
51 changes: 48 additions & 3 deletions realty-paper/src/main/java/io/github/md5sha256/realty/Realty.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import io.github.md5sha256.realty.database.RealtyBackendImpl;
import io.github.md5sha256.realty.database.SqlSessionWrapper;
import io.github.md5sha256.realty.database.maria.MariaDatabase;
import io.github.md5sha256.realty.listener.PropertyTaxListener;
import io.github.md5sha256.realty.listener.SignInteractionListener;
import io.github.md5sha256.realty.localisation.MessageContainer;
import io.github.md5sha256.realty.localisation.MessageKeys;
Expand All @@ -64,6 +65,7 @@
import io.github.md5sha256.realty.settings.RealtyTags;
import io.github.md5sha256.realty.settings.RegionTagSettings;
import io.github.md5sha256.realty.settings.Settings;
import io.github.md5sha256.realty.settings.TaxSettings;
import io.github.md5sha256.realty.util.ComponentSerializer;
import io.github.md5sha256.realty.util.DateFormatter;
import io.github.md5sha256.realty.util.EssentialsNotificationService;
Expand All @@ -73,6 +75,9 @@
import io.papermc.paper.util.Tick;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import io.github.md5sha256.realty.economy.EconomyProvider;
import io.github.md5sha256.realty.economy.TreasuryEconomyProvider;
import io.github.md5sha256.realty.economy.VaultEconomyProvider;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
Expand All @@ -89,6 +94,7 @@
import org.incendo.cloud.paper.util.sender.PaperSimpleSenderMapper;
import org.incendo.cloud.paper.util.sender.Source;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.yaml.NodeStyle;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
Expand Down Expand Up @@ -122,6 +128,7 @@ public final class Realty extends JavaPlugin {
private final AtomicReference<Settings> settings = new AtomicReference<>();
private final AtomicReference<RegionProfileSettings> regionFlagSettings = new AtomicReference<>();
private final AtomicReference<RealtyTags> realtyTags = new AtomicReference<>();
private final AtomicReference<TaxSettings> taxSettings = new AtomicReference<>();
private final RegionProfileService regionProfileService = new RegionProfileService(getLogger());
private final SignCache signCache = new SignCache();
private ExecutorState executorState;
Expand Down Expand Up @@ -166,18 +173,24 @@ public RealtyTags realtyTags() {
return this.realtyTags.get();
}

public TaxSettings taxSettings() {
return this.taxSettings.get();
}

@Override
public void onLoad() {
try {
initDataFolder();
copyResourceTemplate("messages.yml", "defaults/default-messages.yml");
copyResourceTemplate("settings.yml", "defaults/default-settings.yml");
copyResourceTemplate("profiles.yml", "defaults/default-profiles.yml");
copyResourceTemplate("taxes.yml", "defaults/default-taxes.yml");
reloadMessages();
this.databaseSettings = loadDatabaseSettings();
this.settings.set(loadSettings());
this.regionFlagSettings.set(loadRegionFlagSettings());
this.realtyTags.set(new RealtyTags(loadRegionTagSettings()));
this.taxSettings.set(loadTaxSettings());
registerTagPermissions(this.realtyTags.get());
configureRegionFlagService(this.regionFlagSettings.get());

Expand Down Expand Up @@ -223,9 +236,9 @@ public void onEnable() {
return player.getName() != null ? player.getName() : uuid.toString();
}, dateTime -> DateFormatter.format(this.settings.get(), dateTime),
() -> this.settings.get().offerPaymentDurationSeconds());
var economyProvider = getServer().getServicesManager().getRegistration(Economy.class);
EconomyProvider economyProvider = resolveEconomyProvider();
if (economyProvider == null) {
getLogger().severe("Economy not found, plugin will now disable!");
getLogger().severe("No economy found (neither Treasury nor Vault), plugin will now disable!");
getServer().getPluginManager().disablePlugin(this);
return;
}
Expand All @@ -250,8 +263,16 @@ public void onEnable() {
new SignInteractionListener(this.database, this.logic,
this.regionProfileService, this.executorState, this.signCache,
this.signTextApplicator, this.messageContainer), this);
var treasuryRegistration = getServer().getServicesManager()
.getRegistration(net.democracycraft.treasury.api.TreasuryApi.class);
if (treasuryRegistration != null) {
getServer().getPluginManager().registerEvents(
new PropertyTaxListener(this.database, treasuryRegistration.getProvider(),
this.taxSettings, getLogger()), this);
getLogger().info("Registered property tax listener (daily cycle)");
}
this.paperApi = new RealtyPaperApiImpl(
this.logic, economyProvider.getProvider(), this.executorState, this.database,
this.logic, economyProvider, this.executorState, this.database,
this.regionProfileService, this.signTextApplicator, this.signCache);
scheduleTasks();
registerCommands(this.paperApi,
Expand Down Expand Up @@ -294,6 +315,24 @@ public void onDisable() {
getLogger().info("Plugin disabled successfully");
}

private @Nullable EconomyProvider resolveEconomyProvider() {
if (getServer().getPluginManager().isPluginEnabled("Treasury")) {
var registration = getServer().getServicesManager()
.getRegistration(net.democracycraft.treasury.api.TreasuryApi.class);
if (registration != null) {
getLogger().info("Detected Treasury, using Treasury as the economy provider (full ledger support)");
return new TreasuryEconomyProvider(registration.getProvider());
}
getLogger().warning("Treasury plugin is loaded but TreasuryApi service is not registered; falling back to Vault");
}
var registration = getServer().getServicesManager().getRegistration(Economy.class);
if (registration != null) {
getLogger().info("Using Vault as the economy provider");
return new VaultEconomyProvider(registration.getProvider());
}
return null;
}

private void scheduleTasks() {
BukkitScheduler scheduler = getServer().getScheduler();
long intervalTicks = Tick.tick().fromDuration(Duration.ofMinutes(1));
Expand Down Expand Up @@ -400,6 +439,11 @@ private RegionTagSettings loadRegionTagSettings() throws IOException {
return settingsRoot.get(RegionTagSettings.class);
}

private TaxSettings loadTaxSettings() throws IOException {
ConfigurationNode settingsRoot = copyDefaultsYaml("taxes");
return settingsRoot.get(TaxSettings.class);
}

private void unregisterTagPermissions(@NotNull RealtyTags realtyTags) {
PluginManager pluginManager = getServer().getPluginManager();
for (ConfigRegionTag tag : realtyTags.values()) {
Expand Down Expand Up @@ -493,6 +537,7 @@ private void performReload() throws IOException {
registerTagPermissions(this.realtyTags.get());
configureRegionFlagService(this.regionFlagSettings.get());
this.profileApplicator.applyAll(this.settings.get().profileReapplyPerTick());
this.taxSettings.set(loadTaxSettings());
reloadMessages();
warnOrphanedTags();
}
Expand Down
Loading