-
-
Notifications
You must be signed in to change notification settings - Fork 20
feat: Add filter registration option for random teleport locations #1292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| package com.eternalcode.core.feature.randomteleport; | ||
|
|
||
| import org.bukkit.Location; | ||
|
|
||
| /** | ||
| * Filter for validating random teleport locations. | ||
| * <p> | ||
| * Allows external plugins to add custom validation logic for random teleport locations. | ||
| * For example, a plot plugin could implement this to prevent teleporting into claimed plots. | ||
| * <p> | ||
| * Example usage: | ||
| * <pre>{@code | ||
| * public class PlotFilter implements RandomTeleportLocationFilter { | ||
| * @Override | ||
| * public boolean isValid(Location location) { | ||
| * // Check if location is inside a claimed plot | ||
| * return !plotAPI.isPlotClaimed(location); | ||
| * } | ||
| * | ||
| * @Override | ||
| * public String getFilterName() { | ||
| * return "PlotFilter"; | ||
| * } | ||
| * } | ||
| * | ||
| * // Register the filter | ||
| * EternalCoreApi api = EternalCoreApiProvider.provide(); | ||
| * api.getRandomTeleportService().registerFilter(new PlotFilter()); | ||
| * }</pre> | ||
| */ | ||
| public interface RandomTeleportLocationFilter { | ||
|
|
||
| /** | ||
| * Checks if the given location is valid for random teleportation. | ||
| * | ||
| * @param location The location to validate | ||
| * @return true if the location is valid, false otherwise | ||
| */ | ||
| boolean isValid(Location location); | ||
|
|
||
| /** | ||
| * Gets the name of this filter for debugging and logging purposes. | ||
| * | ||
| * @return The filter name | ||
| */ | ||
| String getFilterName(); | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,10 +9,12 @@ | |||||||||||||||||
| import com.eternalcode.core.injector.annotations.component.Service; | ||||||||||||||||||
| import io.papermc.lib.PaperLib; | ||||||||||||||||||
| import java.util.Collection; | ||||||||||||||||||
| import java.util.Collections; | ||||||||||||||||||
| import java.util.List; | ||||||||||||||||||
| import java.util.Map; | ||||||||||||||||||
| import java.util.Map.Entry; | ||||||||||||||||||
| import java.util.concurrent.CompletableFuture; | ||||||||||||||||||
| import java.util.concurrent.ConcurrentHashMap; | ||||||||||||||||||
| import java.util.stream.Collectors; | ||||||||||||||||||
| import org.bukkit.Location; | ||||||||||||||||||
| import org.bukkit.World; | ||||||||||||||||||
|
|
@@ -25,6 +27,7 @@ class RandomTeleportServiceImpl implements RandomTeleportService { | |||||||||||||||||
| private final RandomTeleportSettings randomTeleportSettings; | ||||||||||||||||||
| private final RandomTeleportSafeLocationService safeLocationService; | ||||||||||||||||||
| private final EventCaller eventCaller; | ||||||||||||||||||
| private final Map<String, RandomTeleportLocationFilter> registeredFilters; | ||||||||||||||||||
|
|
||||||||||||||||||
| @Inject | ||||||||||||||||||
| RandomTeleportServiceImpl( | ||||||||||||||||||
|
|
@@ -34,6 +37,7 @@ class RandomTeleportServiceImpl implements RandomTeleportService { | |||||||||||||||||
| this.randomTeleportSettings = randomTeleportSettings; | ||||||||||||||||||
| this.safeLocationService = safeLocationService; | ||||||||||||||||||
| this.eventCaller = eventCaller; | ||||||||||||||||||
| this.registeredFilters = new ConcurrentHashMap<>(); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| @Override | ||||||||||||||||||
|
|
@@ -150,4 +154,40 @@ private RandomTeleportRadius getWorldBorderRadius(World world) { | |||||||||||||||||
| int borderRadius = (int) (worldBorder.getSize() / 2); | ||||||||||||||||||
| return RandomTeleportRadius.of(-borderRadius, borderRadius, -borderRadius, borderRadius); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| @Override | ||||||||||||||||||
| public void registerFilter(RandomTeleportLocationFilter filter) { | ||||||||||||||||||
| if (filter == null) { | ||||||||||||||||||
| throw new IllegalArgumentException("Filter cannot be null"); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| String filterName = filter.getFilterName(); | ||||||||||||||||||
| if (filterName == null || filterName.isEmpty()) { | ||||||||||||||||||
| throw new IllegalArgumentException("Filter name cannot be null or empty"); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| if (this.registeredFilters.containsKey(filterName)) { | ||||||||||||||||||
| throw new IllegalArgumentException("Filter with name '" + filterName + "' is already registered"); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| this.registeredFilters.put(filterName, filter); | ||||||||||||||||||
|
Comment on lines
+169
to
+173
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current implementation for checking if a filter is already registered and then adding it is not an atomic operation. While
Suggested change
|
||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| @Override | ||||||||||||||||||
| public boolean unregisterFilter(String filterName) { | ||||||||||||||||||
| if (filterName == null || filterName.isEmpty()) { | ||||||||||||||||||
| return false; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| return this.registeredFilters.remove(filterName) != null; | ||||||||||||||||||
| } | ||||||||||||||||||
|
Comment on lines
+177
to
+183
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||||||||||||||||||
|
|
||||||||||||||||||
| @Override | ||||||||||||||||||
| public Collection<RandomTeleportLocationFilter> getRegisteredFilters() { | ||||||||||||||||||
| return Collections.unmodifiableCollection(this.registeredFilters.values()); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| Collection<RandomTeleportLocationFilter> getRegisteredFiltersInternal() { | ||||||||||||||||||
| return this.registeredFilters.values(); | ||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Injecting
RandomTeleportServiceImplhere introduces a circular dependency, asRandomTeleportServiceImplalready depends onRandomTeleportSafeLocationService. This is a significant design flaw that can lead to issues with object instantiation and makes the code harder to understand, maintain, and test.To resolve this, you should break the cycle. A good approach is to pass the required data (the collection of filters) from
RandomTeleportServiceImplto the methods ofRandomTeleportSafeLocationServicethat need it, instead of injecting the entire service.For example, you could modify
getSafeRandomLocation:Then,
RandomTeleportServiceImplwould pass the filters when calling the method:This refactoring would eliminate the circular dependency and also allow you to remove the package-private
getRegisteredFiltersInternal()method.