Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
fb125ac
Bumped version to 2.4.0-pre1
NonSwag Jul 14, 2025
9d7f001
Added `CurrencyHolder` interface
NonSwag Jul 14, 2025
8d50900
Added `Currency` interface and improved currency handling
NonSwag Jul 14, 2025
908476e
Refactored to use `Currency` for balance operations
NonSwag Jul 14, 2025
458dea5
Added TODOs for improving `ServiceConvertCommand`
NonSwag Jul 14, 2025
02edc93
Bumped version to 3.0.0-pre1
NonSwag Jul 15, 2025
96bab02
Added `@Contract` annotations for API methods
NonSwag Jul 15, 2025
b27b4c2
Added support for nullable `World` parameters
NonSwag Jul 15, 2025
ff91a1d
Added `hasMultiWorldSupport` to controllers
NonSwag Jul 15, 2025
80df3df
Updated Javadocs for method clarity
NonSwag Jul 15, 2025
0749e7e
Removed `@ApiStatus.NonExtendable` from `Currency` methods
NonSwag Jul 15, 2025
de4f97a
Renamed `getController` to `getHolder`
NonSwag Jul 15, 2025
f38559f
Removed redundant exception handling in bank methods
NonSwag Jul 15, 2025
50519fb
Removed redundant `deleteAccounts` method
NonSwag Jul 15, 2025
7631866
Commented out incomplete conversion logic
NonSwag Jul 15, 2025
5b9efdf
Added `@since` annotations across API interfaces
NonSwag Jul 15, 2025
6899af7
Added nullable `World` support to controllers
NonSwag Jul 15, 2025
829511b
Added methods for singular and plural locale mappings
NonSwag Jul 16, 2025
0d681d0
Refactored currency and account APIs for flexibility
NonSwag Jul 19, 2025
333ab3b
[ci skip] Improved Javadoc parameter descriptions
NonSwag Jul 19, 2025
b134c71
Enhanced currency and account APIs for precision and flexibility
NonSwag Jul 19, 2025
2018199
Added exception to `editCurrency` method in `Currency`
NonSwag Jul 19, 2025
f082e47
Added `deleteCurrency(Currency)` method to `CurrencyHolder`
NonSwag Jul 19, 2025
190ddb5
Reintroduced `toBuilder` method in `Currency`
NonSwag Jul 19, 2025
0be8651
Decoupled `CurrencyHolder` from controllers and services
NonSwag Jul 19, 2025
f9b38e5
Added `hasBank` methods and improved `Currency` linkage
NonSwag Jul 19, 2025
9816748
Implemented `createCurrency` in `CurrencyHolder`
NonSwag Jul 22, 2025
d752fd3
Improved Javadoc and parameter handling in banking APIs
NonSwag Jul 22, 2025
75f6fa4
Added `canDeposit`, `canWithdraw`, and `canHold` methods
NonSwag Jul 22, 2025
7b15785
[ci skip] Added `@since 3.0.0` annotations to API methods
NonSwag Jul 22, 2025
c7adaa3
[ci skip] Bump version to 3.0.0-pre6
NonSwag Jul 22, 2025
0d7b2c9
[ci skip] Bumped version to 3.0.0-pre7
NonSwag Aug 1, 2025
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
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ plugins {
}

group = "net.thenextlvl.services"
version = "2.3.1"
version = "3.0.0-pre7"

java {
toolchain.languageVersion = JavaLanguageVersion.of(21)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ private void loadServiceEconomyWrapper() {
services.register(EconomyController.class, wrapper, economy.getPlugin(), economy.getPriority());

if (!economy.getProvider().hasBankSupport()) return;
var banks = new BankServiceWrapper(economy.getProvider(), economy.getPlugin(), this);
var banks = new BankServiceWrapper(wrapper.getCurrencyHolder(), economy.getProvider(), economy.getPlugin(), this);
services.register(BankController.class, banks, economy.getPlugin(), economy.getPriority());
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ LiteralArgumentBuilder<CommandSourceStack> create() {
.then(Commands.literal("permissions").then(permissions()));
}

// todo: clean this whole mess up
// create a proper conversion api
// compare source and target and warn about potential data loss
// implement proper error handling
// add progress tracking

private ArgumentBuilder<CommandSourceStack, ?> banks() {
return Commands.argument("source", new ControllerArgumentType<>(plugin, BankController.class, (c, e) -> true))
.then(Commands.argument("target", new ControllerArgumentType<>(plugin, BankController.class, (context, controller) ->
Expand Down Expand Up @@ -128,13 +134,17 @@ private int convertPermissions(CommandContext<CommandSourceStack> context) {
private final class BankConverter extends PlayerConverter<BankController> {
@Override
public CompletableFuture<Void> convert(OfflinePlayer player, BankController source, BankController target) {
return source.loadBanks().thenAccept(banks -> banks.forEach(bank ->
bank.getWorld().map(world -> target.createBank(bank.getOwner(), bank.getName(), world))
.orElseGet(() -> target.createBank(bank.getOwner(), bank.getName()))
.thenAccept(targetBank -> {
targetBank.setBalance(bank.getBalance());
bank.getMembers().forEach(targetBank::addMember);
})));
return CompletableFuture.completedFuture(null);
// todo: convert all currencies
// todo: convert balance with currencies
// fixme:
// return source.loadBanks().thenAccept(banks -> banks.forEach(bank ->
// bank.getWorld().map(world -> target.createBank(bank.getOwner(), bank.getName(), world))
// .orElseGet(() -> target.createBank(bank.getOwner(), bank.getName()))
// .thenAccept(targetBank -> {
// targetBank.setBalance(bank.getBalance());
// bank.getMembers().forEach(targetBank::addMember);
// })));
}
}

Expand Down Expand Up @@ -185,14 +195,16 @@ public CompletableFuture<Void> convert(EconomyController source, EconomyControll
}

public CompletableFuture<Void> convert(Account account, EconomyController source, EconomyController target) {
return account.getWorld().map(world -> target.tryGetAccount(account.getOwner(), world)
.thenCompose(account1 -> account1.map(CompletableFuture::completedFuture)
.orElseGet(() -> target.createAccount(account.getOwner(), world)))
.thenAccept(account1 -> account1.setBalance(account.getBalance())))
.orElseGet(() -> target.tryGetAccount(account.getOwner())
.thenCompose(account1 -> account1.map(CompletableFuture::completedFuture)
.orElseGet(() -> target.createAccount(account.getOwner())))
.thenAccept(account1 -> account1.setBalance(account.getBalance())));
return CompletableFuture.completedFuture(null);
// fixme
// return account.getWorld().map(world -> target.tryGetAccount(account.getOwner(), world)
// .thenCompose(account1 -> account1.map(CompletableFuture::completedFuture)
// .orElseGet(() -> target.createAccount(account.getOwner(), world)))
// .thenAccept(account1 -> account1.setBalance(account.getBalance())))
// .orElseGet(() -> target.tryGetAccount(account.getOwner())
// .thenCompose(account1 -> account1.map(CompletableFuture::completedFuture)
// .orElseGet(() -> target.createAccount(account.getOwner())))
// .thenAccept(account1 -> account1.setBalance(account.getBalance())));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import net.thenextlvl.service.api.chat.ChatProfile;
import net.thenextlvl.service.model.chat.GroupManagerChatProfile;
import org.anjocaido.groupmanager.GroupManager;
import org.anjocaido.groupmanager.dataholder.OverloadedWorldHolder;
import org.anjocaido.groupmanager.dataholder.WorldDataHolder;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
Expand All @@ -21,55 +21,20 @@ public class GroupManagerChatController implements ChatController {
private final GroupManager groupManager = JavaPlugin.getPlugin(GroupManager.class);

@Override
public CompletableFuture<ChatProfile> loadProfile(OfflinePlayer player) {
return getProfile(player)
.map(CompletableFuture::completedFuture)
.orElseGet(() -> CompletableFuture.completedFuture(null));
}

@Override
public CompletableFuture<ChatProfile> loadProfile(OfflinePlayer player, World world) {
return getProfile(player, world)
.map(CompletableFuture::completedFuture)
.orElseGet(() -> CompletableFuture.completedFuture(null));
}

@Override
public CompletableFuture<ChatProfile> loadProfile(UUID uuid) {
return getProfile(uuid)
.map(CompletableFuture::completedFuture)
.orElseGet(() -> CompletableFuture.completedFuture(null));
}

@Override
public CompletableFuture<ChatProfile> loadProfile(UUID uuid, World world) {
public CompletableFuture<ChatProfile> loadProfile(UUID uuid, @Nullable World world) {
return getProfile(uuid, world)
.map(CompletableFuture::completedFuture)
.orElseGet(() -> CompletableFuture.completedFuture(null));
}

@Override
public Optional<ChatProfile> getProfile(OfflinePlayer player) {
var holder = groupManager.getWorldsHolder().getDefaultWorld();
return getProfile(holder, player.getUniqueId(), player.getName());
public Optional<ChatProfile> getProfile(UUID uuid, @Nullable World world) {
return getProfile(getHolder(world), uuid, null);
}

@Override
public Optional<ChatProfile> getProfile(OfflinePlayer player, World world) {
var holder = groupManager.getWorldsHolder().getWorldData(world.getName());
return getProfile(holder, player.getUniqueId(), player.getName());
}

@Override
public Optional<ChatProfile> getProfile(UUID uuid) {
var holder = groupManager.getWorldsHolder().getDefaultWorld();
return getProfile(holder, uuid, null);
}

@Override
public Optional<ChatProfile> getProfile(UUID uuid, World world) {
var holder = groupManager.getWorldsHolder().getWorldData(world.getName());
return getProfile(holder, uuid, null);
private @Nullable OverloadedWorldHolder getHolder(@Nullable World world) {
if (world == null) return groupManager.getWorldsHolder().getDefaultWorld();
return groupManager.getWorldsHolder().getWorldData(world.getName());
}

private Optional<ChatProfile> getProfile(@Nullable WorldDataHolder holder, UUID uuid, @Nullable String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.bukkit.World;
import org.bukkit.plugin.Plugin;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

import java.util.Optional;
import java.util.UUID;
Expand All @@ -25,33 +26,24 @@ public LuckPermsChatController(Plugin plugin) {
}

@Override
public CompletableFuture<ChatProfile> loadProfile(UUID uuid) {
return luckPerms.getUserManager().loadUser(uuid).thenApply(user ->
new LuckPermsChatProfile(user, QueryOptions.defaultContextualOptions()));
}

@Override
public CompletableFuture<ChatProfile> loadProfile(UUID uuid, World world) {
public CompletableFuture<ChatProfile> loadProfile(UUID uuid, @Nullable World world) {
return luckPerms.getUserManager().loadUser(uuid).thenApply(user -> {
var options = QueryOptions.contextual(ImmutableContextSet.of("world", world.getName()));
return new LuckPermsChatProfile(user, options);
return new LuckPermsChatProfile(user, getOptions(world));
});
}

@Override
public Optional<ChatProfile> getProfile(UUID uuid) {
return Optional.ofNullable(luckPerms.getUserManager().getUser(uuid)).map(user ->
new LuckPermsChatProfile(user, QueryOptions.defaultContextualOptions()));
}

@Override
public Optional<ChatProfile> getProfile(UUID uuid, World world) {
public Optional<ChatProfile> getProfile(UUID uuid, @Nullable World world) {
return Optional.ofNullable(luckPerms.getUserManager().getUser(uuid)).map(user -> {
var options = QueryOptions.contextual(ImmutableContextSet.of("world", world.getName()));
return new LuckPermsChatProfile(user, options);
return new LuckPermsChatProfile(user, getOptions(world));
});
}

private QueryOptions getOptions(@Nullable World world) {
if (world == null) return QueryOptions.defaultContextualOptions();
return QueryOptions.contextual(ImmutableContextSet.of("world", world.getName()));
}

@Override
public Plugin getPlugin() {
return plugin;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import net.thenextlvl.service.model.group.GroupManagerGroup;
import net.thenextlvl.service.model.permission.GroupManagerPermissionHolder;
import org.anjocaido.groupmanager.GroupManager;
import org.anjocaido.groupmanager.dataholder.OverloadedWorldHolder;
import org.anjocaido.groupmanager.dataholder.WorldDataHolder;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
Expand All @@ -32,59 +32,30 @@ public CompletableFuture<Group> createGroup(String name) {
}

@Override
public CompletableFuture<Group> createGroup(String name, World world) {
public CompletableFuture<Group> createGroup(String name, @Nullable World world) {
if (world == null) return createGroup(name);
var holder = groupManager.getWorldsHolder().getWorldData(world.getName());
if (holder == null) return CompletableFuture.completedFuture(null);
return CompletableFuture.completedFuture(new GroupManagerGroup(holder.createGroup(name)));
}

@Override
public CompletableFuture<Group> loadGroup(String name) {
return CompletableFuture.completedFuture(getGroup(name).orElse(null));
}

@Override
public CompletableFuture<Group> loadGroup(String name, World world) {
public CompletableFuture<Group> loadGroup(String name, @Nullable World world) {
return CompletableFuture.completedFuture(getGroup(name, world).orElse(null));
}

@Override
public CompletableFuture<GroupHolder> loadGroupHolder(OfflinePlayer player) {
return CompletableFuture.completedFuture(getGroupHolder(player).orElse(null));
}

@Override
public CompletableFuture<GroupHolder> loadGroupHolder(OfflinePlayer player, World world) {
return CompletableFuture.completedFuture(getGroupHolder(player, world).orElse(null));
}

@Override
public CompletableFuture<GroupHolder> loadGroupHolder(UUID uuid) {
return CompletableFuture.completedFuture(getGroupHolder(uuid).orElse(null));
}

@Override
public CompletableFuture<GroupHolder> loadGroupHolder(UUID uuid, World world) {
public CompletableFuture<GroupHolder> loadGroupHolder(UUID uuid, @Nullable World world) {
return CompletableFuture.completedFuture(getGroupHolder(uuid, world).orElse(null));
}

@Override
public CompletableFuture<Set<Group>> loadGroups() {
return CompletableFuture.completedFuture(getGroups());
}

@Override
public CompletableFuture<Set<Group>> loadGroups(World world) {
public CompletableFuture<Set<Group>> loadGroups(@Nullable World world) {
return CompletableFuture.completedFuture(getGroups(world));
}

@Override
public CompletableFuture<Boolean> deleteGroup(Group group) {
return deleteGroup(group.getName());
}

@Override
public CompletableFuture<Boolean> deleteGroup(Group group, World world) {
public CompletableFuture<Boolean> deleteGroup(Group group, @Nullable World world) {
return deleteGroup(group.getName(), world);
}

Expand All @@ -94,7 +65,8 @@ public CompletableFuture<Boolean> deleteGroup(String name) {
}

@Override
public CompletableFuture<Boolean> deleteGroup(String name, World world) {
public CompletableFuture<Boolean> deleteGroup(String name, @Nullable World world) {
if (world == null) return deleteGroup(name);
var holder = groupManager.getWorldsHolder().getWorldData(world.getName());
if (holder != null) CompletableFuture.completedFuture(holder.removeGroup(name));
return CompletableFuture.completedFuture(null);
Expand All @@ -107,35 +79,17 @@ public Optional<Group> getGroup(String name) {
}

@Override
public Optional<Group> getGroup(String name, World world) {
public Optional<Group> getGroup(String name, @Nullable World world) {
if (world == null) return getGroup(name);
var holder = groupManager.getWorldsHolder().getWorldData(world.getName());
return Optional.ofNullable(holder)
.map(holder1 -> holder1.getGroup(name))
.map(GroupManagerGroup::new);
}

@Override
public Optional<GroupHolder> getGroupHolder(OfflinePlayer player) {
var holder = groupManager.getWorldsHolder().getDefaultWorld();
return getHolder(holder, player.getUniqueId(), player.getName());
}

@Override
public Optional<GroupHolder> getGroupHolder(OfflinePlayer player, World world) {
var holder = groupManager.getWorldsHolder().getWorldData(world.getName());
return getHolder(holder, player.getUniqueId(), player.getName());
}

@Override
public Optional<GroupHolder> getGroupHolder(UUID uuid) {
var holder = groupManager.getWorldsHolder().getDefaultWorld();
return getHolder(holder, uuid, null);
}

@Override
public Optional<GroupHolder> getGroupHolder(UUID uuid, World world) {
var holder = groupManager.getWorldsHolder().getWorldData(world.getName());
return getHolder(holder, uuid, null);
public Optional<GroupHolder> getGroupHolder(UUID uuid, @Nullable World world) {
return getHolder(getHolder(world), uuid, null);
}

@Override
Expand All @@ -146,14 +100,20 @@ public Set<Group> getGroups() {
}

@Override
public Set<Group> getGroups(World world) {
var holder = groupManager.getWorldsHolder().getWorldData(world.getName());
public Set<Group> getGroups(@Nullable World world) {
if (world == null) return getGroups();
var holder = getHolder(world);
if (holder == null) return Set.of();
return holder.getGroups().values().stream()
.map(GroupManagerGroup::new)
.collect(Collectors.toUnmodifiableSet());
}

private @Nullable OverloadedWorldHolder getHolder(@Nullable World world) {
if (world == null) return groupManager.getWorldsHolder().getDefaultWorld();
return groupManager.getWorldsHolder().getWorldData(world.getName());
}

private Optional<GroupHolder> getHolder(@Nullable WorldDataHolder holder, UUID uuid, @Nullable String name) {
if (holder == null) return Optional.empty();
var user = name != null ? holder.getUser(uuid.toString(), name) : holder.getUser(uuid.toString());
Expand Down
Loading