Skip to content

Commit

Permalink
Add sethome feature
Browse files Browse the repository at this point in the history
  • Loading branch information
md5sha256 committed Feb 25, 2024
1 parent 89114ee commit 788ba7e
Show file tree
Hide file tree
Showing 19 changed files with 498 additions and 24 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,6 @@ gradle-app.setting
### Gradle Patch ###
**/build/

**/run
# End of https://www.toptal.com/developers/gitignore/api/macos,windows,intellij+all,gradle,maven

# End of https://www.toptal.com/developers/gitignore/api/macos,windows,intellij+all,gradle,maven
**/run
51 changes: 30 additions & 21 deletions AreaShop/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,39 +1,26 @@
plugins {
id("com.github.johnrengelman.shadow") version "8.1.1"
id("xyz.jpenilla.run-paper") version "2.2.3"
}

description = "AreaShop"

dependencies {
// Platform
compileOnlyApi(libs.spigot)
compileOnlyApi(libs.worldeditCore) {
exclude("com.google.guava", "guava")
}
compileOnlyApi(libs.worldeditBukkit) {
exclude("com.google.guava", "guava")
}
compileOnlyApi(libs.worldguardCore) {
exclude("com.google.guava", "guava")
}
compileOnlyApi(libs.worldguardBukkit) {
exclude("com.google.guava", "guava")
}
compileOnlyApi("com.github.MilkBowl:VaultAPI:1.7") {
exclude("com.google.guava", "guava")
}
compileOnlyApi(libs.worldeditCore)
compileOnlyApi(libs.worldeditBukkit)
compileOnlyApi(libs.worldguardCore)
compileOnlyApi(libs.worldguardBukkit)
compileOnlyApi("com.github.MilkBowl:VaultAPI:1.7")

// 3rd party libraries
api("io.papermc:paperlib:1.0.8")
api("com.github.NLthijs48:InteractiveMessenger:e7749258ca")
api("com.github.NLthijs48:BukkitDo:819d51ec2b")
api("io.github.baked-libs:dough-data:1.2.0")
api("com.google.inject:guice:7.0.0") {
exclude("com.google.guava", "guava")
}
api("com.google.inject.extensions:guice-assistedinject:7.0.0") {
exclude("com.google.guava", "guava")
}
api("com.google.inject:guice:7.0.0")
api("com.google.inject.extensions:guice-assistedinject:7.0.0")
implementation("net.kyori:adventure-text-minimessage:4.14.0")
implementation("net.kyori:adventure-platform-bukkit:4.3.0")
implementation("org.spongepowered:configurate-yaml:4.1.2")
Expand All @@ -49,6 +36,7 @@ dependencies {
runtimeOnly(projects.adapters.plugins.worldedit)
runtimeOnly(projects.adapters.plugins.worldguard)
runtimeOnly(projects.adapters.plugins.fastasyncworldedit)
runtimeOnly(projects.adapters.plugins.essentials)
runtimeOnly(projects.adapters.platform.bukkitModern)
}
testImplementation("com.github.seeseemelk:MockBukkit-v1.20:3.57.1")
Expand Down Expand Up @@ -115,5 +103,26 @@ tasks {
relocate("javax.annotation", "${base}.javax.annotation")
relocate("jakarta.inject", "${base}.jakarta.inject")
relocate("org.jetbrains.annotations", "${base}.jetbrains.annotations")
relocate("io.leangen.geantyref", "${base}.geantyref")
relocate("net.kyori", "${base}.kyori")
relocate("org.checkerframework", "${base}.checkerframework")
relocate("org.intellij", "${base}.intellij")
relocate("org.spongepowered", "${base}.spongepowered")
relocate("org.yaml.snakeyaml", "${base}.snakeyaml")
}
runServer {
// Configure the Minecraft version for our task.
// This is the only required configuration besides applying the plugin.
// Your plugin's jar (or shadowJar if present) will be used automatically.
minecraftVersion("1.18.2")

downloadPlugins {
github("EssentialsX", "essentials", "2.20.1", "EssentialsX-2.20.1.jar")
github("MilkBowl", "Vault", "1.7.3", "Vault.jar")
// WorldEdit 7.2.19
url("https://mediafilez.forgecdn.net/files/5077/477/worldedit-bukkit-7.2.19.jar")
// WorldGuard 7.0.7
url("https://mediafilez.forgecdn.net/files/3677/516/worldguard-bukkit-7.0.7-dist.jar")
}
}
}
23 changes: 23 additions & 0 deletions AreaShop/src/main/java/me/wiefferink/areashop/AreaShop.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import io.papermc.lib.PaperLib;
import me.wiefferink.areashop.adapters.platform.MinecraftPlatform;
import me.wiefferink.areashop.adapters.platform.paper.PaperPlatform;
import me.wiefferink.areashop.extensions.AreashopExtension;
import me.wiefferink.areashop.features.signs.SignManager;
import me.wiefferink.areashop.interfaces.AreaShopInterface;
import me.wiefferink.areashop.interfaces.WorldEditInterface;
Expand Down Expand Up @@ -56,6 +57,7 @@
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
Expand Down Expand Up @@ -286,6 +288,8 @@ public void onEnable() {
signManager = injector.getInstance(SignManager.class);
managers.add(signManager);

loadExtensions();

// Register the event listeners
getServer().getPluginManager().registerEvents(new PlayerLoginLogoutListener(this, messageBridge), this);

Expand Down Expand Up @@ -342,6 +346,25 @@ private void shutdownOnError() {
getServer().getPluginManager().disablePlugin(this);
}

private void loadExtensions() {
if (this.getServer().getPluginManager().isPluginEnabled("Essentials")) {
loadEssentialsExt().ifPresent(ext -> ext.init(this, this.injector));
}
}

private Optional<AreashopExtension> loadEssentialsExt() {
try {
Class<?> clazz = Class.forName("me.wiefferink.areashop.adapters.plugins.essentials.EssentialsExtension");
Class<? extends AreashopExtension> extClass = clazz.asSubclass(AreashopExtension.class);
AreashopExtension extension = extClass.getConstructor().newInstance();
return Optional.of(extension);
} catch (ReflectiveOperationException ex) {
error("Failed to initialize the essentials extension!");
ex.printStackTrace();
}
return Optional.empty();
}

/**
* Cleanup a version number.
* @param version Version to clean
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package me.wiefferink.areashop.commands;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import me.wiefferink.areashop.MessageBridge;
import me.wiefferink.areashop.features.homeaccess.HomeAccessFeature;
import me.wiefferink.areashop.features.homeaccess.HomeAccessType;
import me.wiefferink.areashop.managers.IFileManager;
import me.wiefferink.areashop.regions.GeneralRegion;
import me.wiefferink.areashop.tools.Utils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;

@Singleton
public final class TogglehomeControlCommand extends CommandAreaShop {

private final IFileManager fileManager;
private final MessageBridge messageBridge;

@Inject
public TogglehomeControlCommand(@Nonnull IFileManager fileManager, @Nonnull MessageBridge messageBridge) {
this.fileManager = fileManager;
this.messageBridge = messageBridge;
}

@Override
public String getCommandStart() {
return "areashop togglehome";
}


@Override
public String getHelp(CommandSender target) {
if (!target.hasPermission("sethomecontrol.control")) {
return null;
}
return "help-togglehome";
}

@Override
public void execute(CommandSender sender, String[] args) {
if (!sender.hasPermission("sethomecontrol.control")) {
this.messageBridge.message(sender, "togglehome-noPermission");
return;
}
if (args.length < 1) {
this.messageBridge.message(sender, "togglehome-help");
return;
}

final String rawAccessType = args[0];
final HomeAccessType accessType;
try {
accessType = HomeAccessType.valueOf(rawAccessType.toUpperCase(Locale.ENGLISH));
} catch (IllegalArgumentException ex) {
this.messageBridge.message(sender, "togglehome-unknownAccessType");
return;
}
final GeneralRegion region;
if (args.length >= 2) {
final String regionName = args[1];
region = this.fileManager.getRegion(regionName);
if (region == null) {
this.messageBridge.message(sender, "cmd-noRegion", regionName);
return;
}
} else if (sender instanceof Player player) {
List<GeneralRegion> regions = Utils.getImportantRegions(player.getLocation());
if (regions.isEmpty()) {
this.messageBridge.message(sender, "cmd-noRegionsAtLocation");
return;
} else if (regions.size() != 1) {
this.messageBridge.message(sender, "cmd-moreRegionsAtLocation");
return;
}
region = regions.get(0);
} else {
this.messageBridge.message(sender, "cmd-automaticRegionOnlyByPlayer");
return;
}

if (!(sender instanceof Player) && !sender.hasPermission("sethome.control.other")) {
return;
}
if (sender instanceof Player player && !region.isOwner(player)) {
this.messageBridge.message(sender, "togglehome-noPermission");
}
region.getOrCreateFeature(HomeAccessFeature.class).homeAccessType(accessType);
this.messageBridge.message(sender, "togglehome-success", accessType.name());
}

@Override
public List<String> getTabCompleteList(int toComplete, String[] start, CommandSender sender) {
if (!sender.hasPermission("sethome.control")) {
return Collections.emptyList();
}
if (start.length == 1) {
Stream<GeneralRegion> stream = this.fileManager.getRegions().stream();
if (!sender.hasPermission("sethome.control.other") && sender instanceof Player player) {
stream = stream.filter(region -> region.isOwner(player.getUniqueId()));
}
return stream.map(GeneralRegion::getName)
.filter(name -> name.startsWith(start[0]))
.sorted(Comparator.reverseOrder())
.toList();
}
if (start.length == 2 && sender instanceof Player player) {
return this.fileManager.getRegions().stream()
.filter(region -> region.isOwner(player.getUniqueId()))
.map(GeneralRegion::getName)
.filter(name -> name.startsWith(start[0]))
.sorted(Comparator.reverseOrder())
.toList();
}
return Collections.emptyList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package me.wiefferink.areashop.extensions;

import com.google.inject.Injector;
import me.wiefferink.areashop.AreaShop;

public interface AreashopExtension {

void init(AreaShop plugin, Injector injector);

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package me.wiefferink.areashop.features;

import me.wiefferink.areashop.features.homeaccess.HomeAccessFeature;
import me.wiefferink.areashop.features.signs.SignsFeature;
import me.wiefferink.areashop.regions.GeneralRegion;

Expand All @@ -16,4 +17,7 @@ public interface FeatureFactory {
@Nonnull
FriendsFeature createFriendsFeature(@Nonnull GeneralRegion generalRegion);

@Nonnull
HomeAccessFeature createHomeAccessFeature(@Nonnull GeneralRegion generalRegion);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package me.wiefferink.areashop.features.homeaccess;

import me.wiefferink.areashop.regions.GeneralRegion;
import org.checkerframework.checker.nullness.qual.NonNull;

import java.util.UUID;

@FunctionalInterface
public interface AccessControlValidator {

/**
* Whether a player can access a given {@link GeneralRegion} via a home
*
* @param player The uuid of the player attempting to access the region via a home
* @param region The region
* @param accessType The type of access permission the player holds
* @return true if a player is permitted to set a home, false otherwise.
*/
boolean canAccess(
@NonNull final UUID player,
@NonNull final GeneralRegion region,
@NonNull final HomeAccessType accessType
);

default AccessControlValidator and(@NonNull final AccessControlValidator other) {
return (player, region, accessType) -> this.canAccess(player, region, accessType)
&& other.canAccess(player, region, accessType);
}

default AccessControlValidator or(@NonNull final AccessControlValidator other) {
return (player, region, accessType) -> this.canAccess(player, region, accessType)
|| other.canAccess(player, region, accessType);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package me.wiefferink.areashop.features.homeaccess;

import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.features.RegionFeature;
import me.wiefferink.areashop.regions.GeneralRegion;

import javax.annotation.Nonnull;
import java.util.Locale;
import java.util.logging.Logger;

public final class HomeAccessFeature extends RegionFeature {
private HomeAccessType homeAccessType;

@AssistedInject
public HomeAccessFeature(
@Assisted final GeneralRegion region,
@Nonnull final AreaShop plugin
) {
super(plugin);
setRegion(region);
this.homeAccessType = parseAccessType();
}

private @Nonnull HomeAccessType parseAccessType() {
String rawAccessType = getRegion().getConfig()
.getString("sethomecontrol.homeaccesstype", HomeAccessType.ANY.name());
try {
return HomeAccessType.valueOf(rawAccessType.toUpperCase(Locale.ENGLISH));
} catch (IllegalArgumentException ex) {
AreaShop.error("Invalid HomeAccessType: " + rawAccessType + " in region: " + getRegion().getName());
return HomeAccessType.ANY;
}
}

private void saveAccessType(@Nonnull final HomeAccessType homeAccessType) {
getRegion().getConfig().set("sethomecontrol.homeaccesstype", homeAccessType.name());
getRegion().saveRequired();
}

public @Nonnull HomeAccessType homeAccessType() {
return this.homeAccessType;
}

public void homeAccessType(@Nonnull final HomeAccessType homeAccessType) {
if (this.homeAccessType != homeAccessType) {
this.homeAccessType = homeAccessType;
saveAccessType(homeAccessType);
}
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package me.wiefferink.areashop.features.homeaccess;

public enum HomeAccessType {

ANY,
MEMBERS,
NONE

}
Loading

0 comments on commit 788ba7e

Please sign in to comment.