Refactor anchor manager with varv and fix checkstyles

This commit is contained in:
Ben Woo 2023-09-21 17:32:47 +08:00
parent 65288f4037
commit 913ceb3006
No known key found for this signature in database
GPG Key ID: FB2A3645536E12C8
2 changed files with 112 additions and 97 deletions

View File

@ -368,7 +368,7 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
// TODO: Make this all Try<Void> // TODO: Make this all Try<Void>
return configProvider.get().save().isSuccess() return configProvider.get().save().isSuccess()
&& worldManagerProvider.get().saveWorldsConfig() && worldManagerProvider.get().saveWorldsConfig()
&& anchorManagerProvider.get().saveAnchors(); && anchorManagerProvider.get().saveAnchors().isSuccess();
} }
/** /**

View File

@ -16,126 +16,126 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import com.dumptruckman.minecraft.util.Logging; import com.dumptruckman.minecraft.util.Logging;
import io.vavr.control.Try;
import jakarta.inject.Inject; import jakarta.inject.Inject;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jvnet.hk2.annotations.Service; import org.jvnet.hk2.annotations.Service;
import org.mvplugins.multiverse.core.MultiverseCore; import org.mvplugins.multiverse.core.MultiverseCore;
import org.mvplugins.multiverse.core.api.LocationManipulation; import org.mvplugins.multiverse.core.api.LocationManipulation;
import org.mvplugins.multiverse.core.config.MVCoreConfig; import org.mvplugins.multiverse.core.world.WorldManager;
import org.mvplugins.multiverse.core.world.entrycheck.WorldEntryCheckerProvider;
/** /**
* Manages anchors. * Manages anchors.
*/ */
@Service @Service
public class AnchorManager { public class AnchorManager {
private Map<String, Location> anchors; private static final String ANCHORS_SECTION_NAME = "anchors";
private FileConfiguration anchorConfig; private static final String ANCHORS_FILE_NAME = "anchors.yml";
private final Plugin plugin; private final Map<String, Location> anchors;
private final File anchorsFile;
private final FileConfiguration anchorConfig;
private final LocationManipulation locationManipulation; private final LocationManipulation locationManipulation;
private final MVCoreConfig config; private final WorldManager worldManager;
private final WorldEntryCheckerProvider worldEntryCheckerProvider;
@Inject @Inject
public AnchorManager( AnchorManager(
MultiverseCore plugin, @NotNull MultiverseCore plugin,
LocationManipulation locationManipulation, @NotNull LocationManipulation locationManipulation,
MVCoreConfig config @NotNull WorldManager worldManager,
) { @NotNull WorldEntryCheckerProvider worldEntryCheckerProvider) {
this.plugin = plugin; this.anchors = new HashMap<>();
this.anchorsFile = new File(plugin.getDataFolder(), ANCHORS_FILE_NAME);
this.anchorConfig = new YamlConfiguration();
this.locationManipulation = locationManipulation; this.locationManipulation = locationManipulation;
this.config = config; this.worldManager = worldManager;
this.worldEntryCheckerProvider = worldEntryCheckerProvider;
this.anchors = new HashMap<String, Location>();
} }
/** /**
* Loads all anchors. * Loads all anchors.
*
* @return Empty {@link Try} if all anchors were successfully loaded, or the exception if an error occurred.
*/ */
public void loadAnchors() { public Try<Void> loadAnchors() {
this.anchors = new HashMap<String, Location>(); return Try.run(() -> {
this.anchorConfig = YamlConfiguration.loadConfiguration(new File(this.plugin.getDataFolder(), "anchors.yml")); anchors.clear();
this.ensureConfigIsPrepared(); anchorConfig.load(anchorsFile);
ConfigurationSection anchorsSection = this.anchorConfig.getConfigurationSection("anchors"); ConfigurationSection anchorsSection = getAnchorConfigSection();
Set<String> anchorKeys = anchorsSection.getKeys(false); Set<String> anchorKeys = anchorsSection.getKeys(false);
for (String key : anchorKeys) { anchorKeys.forEach(key -> {
//world:x,y,z:pitch:yaw //world:x,y,z:pitch:yaw
Location anchorLocation = this.locationManipulation.stringToLocation(anchorsSection.getString(key, "")); String locationString = anchorsSection.getString(key, "");
if (anchorLocation != null) { Location anchorLocation = this.locationManipulation.stringToLocation(locationString);
Logging.config("Loading anchor: '%s'...", key); if (anchorLocation == null) {
Logging.warning("The location for anchor '%s' is INVALID.", key);
return;
}
this.anchors.put(key, anchorLocation); this.anchors.put(key, anchorLocation);
} else { });
Logging.warning("The location for anchor '%s' is INVALID.", key); });
}
}
}
private void ensureConfigIsPrepared() {
if (this.anchorConfig.getConfigurationSection("anchors") == null) {
this.anchorConfig.createSection("anchors");
}
} }
/** /**
* Saves all anchors. * Saves all anchors.
*
* @return True if all anchors were successfully saved. * @return True if all anchors were successfully saved.
*/ */
public boolean saveAnchors() { public Try<Void> saveAnchors() {
try { return Try.run(() -> anchorConfig.save(anchorsFile));
this.anchorConfig.save(new File(this.plugin.getDataFolder(), "anchors.yml"));
return true;
} catch (IOException e) {
Logging.severe("Failed to save anchors.yml. Please check your file permissions.");
return false;
}
} }
/** /**
* Gets the {@link Location} associated with an anchor. * Gets the {@link Location} associated with an anchor.
* @param anchor The name of the anchor. *
* @param anchorName The name of the anchor.
* @return The {@link Location}. * @return The {@link Location}.
*/ */
public Location getAnchorLocation(String anchor) { public Location getAnchorLocation(@Nullable String anchorName) {
if (this.anchors.containsKey(anchor)) { return this.anchors.getOrDefault(anchorName, null);
return this.anchors.get(anchor);
}
return null;
} }
/** /**
* Saves an anchor. * Saves an anchor.
* @param anchor The name of the anchor. *
* @param location The location of the anchor as string. * @param anchorName The name of the anchor.
* @return True if the anchor was successfully saved. * @param locationString The location of the anchor as string.
* @return Empty {@link Try} if all anchors were successfully loaded, or the exception if an error occurred.
*/ */
public boolean saveAnchorLocation(String anchor, String location) { public Try<Location> saveAnchorLocation(String anchorName, String locationString) {
Location parsed = this.locationManipulation.stringToLocation(location); Location parsed = this.locationManipulation.stringToLocation(locationString);
return parsed != null && this.saveAnchorLocation(anchor, parsed); if (parsed == null) {
return Try.failure(new IOException("Invalid location string: " + locationString));
}
return this.saveAnchorLocation(anchorName, parsed).map(ignore -> getAnchorLocation(anchorName));
} }
/** /**
* Saves an anchor. * Saves an anchor.
* @param anchor The name of the anchor. *
* @param l The {@link Location} of the anchor. * @param anchorName The name of the anchor.
* @return True if the anchor was successfully saved. * @param location The {@link Location} of the anchor.
* @return Empty {@link Try} if all anchors were successfully loaded, or the exception if an error occurred.
*/ */
public boolean saveAnchorLocation(String anchor, Location l) { public Try<Void> saveAnchorLocation(@NotNull String anchorName, @NotNull Location location) {
if (l == null) { getAnchorConfigSection().set(anchorName, this.locationManipulation.locationToString(location));
return false; this.anchors.put(anchorName, location);
} return saveAnchors();
this.anchorConfig.set("anchors." + anchor, this.locationManipulation.locationToString(l));
this.anchors.put(anchor, l);
return this.saveAnchors();
} }
/** /**
* Gets all anchors. * Gets all anchors.
*
* @return An unmodifiable {@link Set} containing all anchors. * @return An unmodifiable {@link Set} containing all anchors.
*/ */
public Set<String> getAllAnchors() { public Set<String> getAllAnchors() {
@ -144,46 +144,61 @@ public class AnchorManager {
/** /**
* Gets all anchors that the specified {@link Player} can access. * Gets all anchors that the specified {@link Player} can access.
* @param p The {@link Player}. *
* @param player The {@link Player}.
* @return An unmodifiable {@link Set} containing all anchors the specified {@link Player} can access. * @return An unmodifiable {@link Set} containing all anchors the specified {@link Player} can access.
*/ */
public Set<String> getAnchors(Player p) { public Set<String> getAnchors(@Nullable Player player) {
if (p == null) { if (player == null) {
return this.anchors.keySet(); return getAllAnchors();
} }
Set<String> myAnchors = new HashSet<String>();
for (String anchor : this.anchors.keySet()) { Set<String> myAnchors = new HashSet<>();
Location ancLoc = this.anchors.get(anchor);
if (ancLoc == null) { this.anchors.forEach((anchorName, anchorLocation) -> {
continue; World anchorWorld = anchorLocation.getWorld();
if (anchorWorld == null) {
return;
} }
String worldPerm = "multiverse.access." + ancLoc.getWorld().getName();
// Add to the list if we're not enforcing access worldManager.getWorld(anchorWorld)
// OR .map(world -> worldEntryCheckerProvider.forSender(player).canAccessWorld(world).isSuccess())
// We are enforcing access and the user has the permission. .peek(success -> {
if (!config.getEnforceAccess() || if (success) {
(config.getEnforceAccess() && p.hasPermission(worldPerm))) { myAnchors.add(anchorName);
myAnchors.add(anchor); } else {
} else { Logging.finer("Player '%s' cannot access anchor '%s'.",
Logging.finer(String.format("Not adding anchor %s to the list, user %s doesn't have the %s " + player.getName(), anchorName);
"permission and 'enforceaccess' is enabled!", }
anchor, p.getName(), worldPerm)); })
} .onEmpty(() -> {
} Logging.finer("Anchor '%s' located in world '%s is not in a Multiverse world.",
return Collections.unmodifiableSet(myAnchors); anchorName, anchorLocation.getWorld().getName());
});
});
return myAnchors;
} }
/** /**
* Deletes the specified anchor. * Deletes the specified anchor.
* @param s The name of the anchor. *
* @param anchorName The name of the anchor.
* @return True if the anchor was successfully deleted. * @return True if the anchor was successfully deleted.
*/ */
public boolean deleteAnchor(String s) { public Try<Void> deleteAnchor(String anchorName) {
if (this.anchors.containsKey(s)) { if (this.anchors.containsKey(anchorName)) {
this.anchors.remove(s); this.anchors.remove(anchorName);
this.anchorConfig.set("anchors." + s, null); getAnchorConfigSection().set(anchorName, null);
return this.saveAnchors(); return this.saveAnchors();
} }
return false; return Try.failure(new Exception("Anchor " + anchorName + " not found."));
}
private ConfigurationSection getAnchorConfigSection() {
ConfigurationSection anchorsSection = anchorConfig.getConfigurationSection(ANCHORS_SECTION_NAME);
return anchorsSection == null
? anchorConfig.createSection(ANCHORS_SECTION_NAME)
: anchorsSection;
} }
} }