Add Player World settings storage implementation

Add Visit permissions
Add Edit Permissions
Add Interact Permissions
TODO: Banning members, adding members to world, removing all non-members from world if visit is set to nobody
This commit is contained in:
Taah 2024-05-03 16:27:35 -07:00
parent a2f63a54d3
commit 6a655dfc2c
6 changed files with 208 additions and 28 deletions

View File

@ -115,6 +115,9 @@ public class TFMExtras extends PlexModule
addDefaultMessage("playerWorldNotFound", "<red>Hey! This player's world does not seem to exist. Are they online?"); addDefaultMessage("playerWorldNotFound", "<red>Hey! This player's world does not seem to exist. Are they online?");
addDefaultMessage("worldLoadError", "<red>Hey! It looks like something went wrong when this world was being loaded in, please try asking the player (or if it is yours, then rejoin) to rejoin and if not, tell the world owner to contact support on our <click:open_url:https://discord.gg/6QcT7K2Bkw><bold>Discord</bold></click>"); addDefaultMessage("worldLoadError", "<red>Hey! It looks like something went wrong when this world was being loaded in, please try asking the player (or if it is yours, then rejoin) to rejoin and if not, tell the world owner to contact support on our <click:open_url:https://discord.gg/6QcT7K2Bkw><bold>Discord</bold></click>");
addDefaultMessage("cannotAccessIsland", "<red>Unfortunately you cannot access this player's island!"); addDefaultMessage("cannotAccessIsland", "<red>Unfortunately you cannot access this player's island!");
addDefaultMessage("islandPermissionUpdated", "<green>Your island permission for {0} has been updated to {1}.", "0 - Permission name", "1 - New value");
addDefaultMessage("cantModifyIsland", "<red>You can't modify this player's island!");
addDefaultMessage("cantVisitIsland", "<red>You can't visit this player's island!");
} }
@Override @Override

View File

@ -9,9 +9,11 @@ import dev.plex.extras.TFMExtras;
import dev.plex.extras.island.PlayerWorld; import dev.plex.extras.island.PlayerWorld;
import dev.plex.extras.island.info.IslandPermissions; import dev.plex.extras.island.info.IslandPermissions;
import dev.plex.util.PlexUtils; import dev.plex.util.PlexUtils;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Sound; import org.bukkit.Sound;
@ -87,6 +89,36 @@ public class MyWorldCommand extends PlexCommand
player.playSound(player.getLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 1f, 1f); player.playSound(player.getLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 1f, 1f);
return null; return null;
} }
case "settings" ->
{
if (!TFMExtras.getModule().getSlimeWorldHook().isWorldLoaded(player.getUniqueId().toString()))
{
return messageComponent("selfPlayerWorldNotFound");
}
if (args.length == 1)
{
return usage("/myworld settings <interact | edit | visit> <nobody | anyone | members>");
}
if (!args[1].equalsIgnoreCase("interact") && !args[1].equalsIgnoreCase("edit") && !args[1].equalsIgnoreCase("visit"))
{
return usage("/myworld settings <interact | edit | visit> <nobody | anyone | members>");
}
final PlayerWorld playerWorld = TFMExtras.getModule().getIslandHandler().loadedIslands().get(player.getUniqueId());
try {
final IslandPermissions permissions = IslandPermissions.valueOf(args[2].toUpperCase());
switch (args[1].toLowerCase())
{
case "interact" -> playerWorld.interactPermission(permissions);
case "edit" -> playerWorld.editPermission(permissions);
case "visit" -> playerWorld.visitPermission(permissions);
}
return messageComponent("islandPermissionUpdated", args[1].toUpperCase(), permissions.name());
} catch (IllegalArgumentException e)
{
return usage("/myworld settings <interact | edit | visit> <nobody | anyone | members>");
}
}
} }
return null; return null;
} }

View File

@ -1,5 +1,6 @@
package dev.plex.extras.hook; package dev.plex.extras.hook;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.infernalsuite.aswm.api.SlimePlugin; import com.infernalsuite.aswm.api.SlimePlugin;
import com.infernalsuite.aswm.api.exceptions.CorruptedWorldException; import com.infernalsuite.aswm.api.exceptions.CorruptedWorldException;
@ -11,13 +12,20 @@ import com.infernalsuite.aswm.api.loaders.SlimeLoader;
import com.infernalsuite.aswm.api.world.SlimeWorld; import com.infernalsuite.aswm.api.world.SlimeWorld;
import com.infernalsuite.aswm.api.world.properties.SlimeProperties; import com.infernalsuite.aswm.api.world.properties.SlimeProperties;
import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap; import com.infernalsuite.aswm.api.world.properties.SlimePropertyMap;
import dev.plex.Plex;
import dev.plex.extras.TFMExtras; import dev.plex.extras.TFMExtras;
import dev.plex.extras.island.PlayerWorld;
import dev.plex.extras.island.info.IslandPermissions;
import dev.plex.util.PlexLog; import dev.plex.util.PlexLog;
import java.io.IOException; import java.io.IOException;
import java.sql.*;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import lombok.Getter; import lombok.Getter;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -56,6 +64,17 @@ public class SlimeWorldHook implements IHook<SlimePlugin>
this.loader = plugin().getLoader("mysql"); this.loader = plugin().getLoader("mysql");
this.loadAllWorlds(); this.loadAllWorlds();
try (Connection connection = Plex.get().getSqlConnection().getCon())
{
connection.prepareStatement("ALTER TABLE `islands` ADD COLUMN IF NOT EXISTS `interactPermission` VARCHAR(10);").execute();
} catch (SQLException e)
{
throw new RuntimeException(e);
}
TFMExtras.getModule().getIslandHandler().createTables();
TFMExtras.getModule().getIslandHandler().loadIslands(); TFMExtras.getModule().getIslandHandler().loadIslands();
} }
@ -76,7 +95,8 @@ public class SlimeWorldHook implements IHook<SlimePlugin>
loadedWorlds.clear(); loadedWorlds.clear();
CompletableFuture.runAsync(() -> { CompletableFuture.runAsync(() ->
{
TFMExtras.getModule().getIslandHandler().loadedIslands().values().forEach(playerWorld -> TFMExtras.getModule().getIslandHandler().updateIsland(playerWorld)); TFMExtras.getModule().getIslandHandler().loadedIslands().values().forEach(playerWorld -> TFMExtras.getModule().getIslandHandler().updateIsland(playerWorld));
TFMExtras.getModule().getIslandHandler().loadedIslands().clear(); TFMExtras.getModule().getIslandHandler().loadedIslands().clear();
}); });
@ -97,13 +117,11 @@ public class SlimeWorldHook implements IHook<SlimePlugin>
SlimeWorld world = this.plugin().loadWorld(this.loader, s, false, slimePropertyMap); SlimeWorld world = this.plugin().loadWorld(this.loader, s, false, slimePropertyMap);
this.plugin().loadWorld(world); this.plugin().loadWorld(world);
this.loader.unlockWorld(s); this.loader.unlockWorld(s);
} } catch (UnknownWorldException | WorldLockedException | CorruptedWorldException | NewerFormatException |
catch (UnknownWorldException | WorldLockedException | CorruptedWorldException | NewerFormatException |
IllegalArgumentException ex) IllegalArgumentException ex)
{ {
PlexLog.error(ex.getMessage()); PlexLog.error(ex.getMessage());
} } catch (IOException e)
catch (IOException e)
{ {
PlexLog.error(STORAGE_FAILURE); PlexLog.error(STORAGE_FAILURE);
return; return;
@ -129,10 +147,12 @@ public class SlimeWorldHook implements IHook<SlimePlugin>
world.getWorldBorder().setSize(configuratedSize == 0 ? 500 : configuratedSize); world.getWorldBorder().setSize(configuratedSize == 0 ? 500 : configuratedSize);
world.getWorldBorder().setDamageAmount(0); world.getWorldBorder().setDamageAmount(0);
world.getWorldBorder().setDamageBuffer(0); world.getWorldBorder().setDamageBuffer(0);
Bukkit.getPluginManager().callEvent(new WorldLoadEvent(world));
PlexLog.debug("Loaded {0}", s); PlexLog.debug("Loaded {0}", s);
}); });
} } catch (IOException | IllegalArgumentException ex)
catch (IOException | IllegalArgumentException ex)
{ {
PlexLog.error(ex.getMessage()); PlexLog.error(ex.getMessage());
} }
@ -152,8 +172,7 @@ public class SlimeWorldHook implements IHook<SlimePlugin>
Bukkit.unloadWorld(world, false); Bukkit.unloadWorld(world, false);
} }
this.loader.deleteWorld(world); this.loader.deleteWorld(world);
} } catch (UnknownWorldException | IOException e)
catch (UnknownWorldException | IOException e)
{ {
PlexLog.error(e.getMessage()); PlexLog.error(e.getMessage());
} }
@ -173,27 +192,23 @@ public class SlimeWorldHook implements IHook<SlimePlugin>
final SlimeWorld slimeWorld = this.plugin().createEmptyWorld(this.loader, uuid.toString(), false, slimePropertyMap); final SlimeWorld slimeWorld = this.plugin().createEmptyWorld(this.loader, uuid.toString(), false, slimePropertyMap);
this.plugin().loadWorld(slimeWorld); this.plugin().loadWorld(slimeWorld);
newWorld = true; newWorld = true;
} } catch (WorldAlreadyExistsException e)
catch (WorldAlreadyExistsException e)
{ {
try try
{ {
SlimeWorld world = this.plugin().loadWorld(this.loader, uuid.toString(), false, slimePropertyMap); SlimeWorld world = this.plugin().loadWorld(this.loader, uuid.toString(), false, slimePropertyMap);
this.plugin().loadWorld(world); this.plugin().loadWorld(world);
this.loader.unlockWorld(uuid.toString()); this.loader.unlockWorld(uuid.toString());
} } catch (WorldLockedException | CorruptedWorldException | NewerFormatException | UnknownWorldException |
catch (WorldLockedException | CorruptedWorldException | NewerFormatException | UnknownWorldException |
IOException | IllegalArgumentException ex) IOException | IllegalArgumentException ex)
{ {
PlexLog.error(ex.getMessage()); PlexLog.error(ex.getMessage());
} }
} } catch (IOException e)
catch (IOException e)
{ {
PlexLog.error(STORAGE_FAILURE); PlexLog.error(STORAGE_FAILURE);
} } catch (WorldLockedException | UnknownWorldException e)
catch (WorldLockedException | UnknownWorldException e)
{ {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -227,6 +242,11 @@ public class SlimeWorldHook implements IHook<SlimePlugin>
final WorldLoadEvent event = new WorldLoadEvent(world); final WorldLoadEvent event = new WorldLoadEvent(world);
Bukkit.getServer().getPluginManager().callEvent(event); Bukkit.getServer().getPluginManager().callEvent(event);
final PlayerWorld playerWorld = new PlayerWorld(uuid, Lists.newArrayList(), IslandPermissions.NOBODY, IslandPermissions.ANYONE, IslandPermissions.ANYONE);
TFMExtras.getModule().getIslandHandler().insertIsland(playerWorld);
TFMExtras.getModule().getIslandHandler().loadedIslands().put(uuid, playerWorld);
return Pair.of(world, newWorld); return Pair.of(world, newWorld);
} }

View File

@ -29,6 +29,7 @@ public class PlayerWorld
private final List<UUID> members; private final List<UUID> members;
private IslandPermissions editPermission; private IslandPermissions editPermission;
private IslandPermissions visitPermission; private IslandPermissions visitPermission;
private IslandPermissions interactPermission;
public boolean addMember(UUID member) public boolean addMember(UUID member)
{ {

View File

@ -25,16 +25,29 @@ public class IslandHandler
//TODO: Create Table statements //TODO: Create Table statements
private static final String LOAD_ISLANDS = "SELECT * FROM `islands`;"; private static final String LOAD_ISLANDS = "SELECT * FROM `islands`;";
private static final String LOAD_MEMBERS = "SELECT * FROM `island_members`;"; private static final String LOAD_MEMBERS = "SELECT * FROM `island_members`;";
private static final String INSERT_ISLAND = "INSERT INTO `islands` (`owner`, `editPermission`, `visitPermission`) VALUES(?, ?, ?);"; private static final String INSERT_ISLAND = "INSERT INTO `islands` (`owner`, `editPermission`, `visitPermission`, `interactPermission`) VALUES(?, ?, ?, ?);";
private static final String INSERT_MEMBER = "INSERT INTO `island_members` (`uuid`, `island_owner_uuid`) VALUES(?, ?);"; private static final String INSERT_MEMBER = "INSERT INTO `island_members` (`uuid`, `island_owner_uuid`) VALUES(?, ?);";
private static final String DELETE_ISLAND = "DELETE FROM `islands` WHERE `owner`=?;"; private static final String DELETE_ISLAND = "DELETE FROM `islands` WHERE `owner`=?;";
private static final String DELETE_MEMBER = "DELETE FROM `island_members` WHERE `uuid`=? AND `island_owner_uuid`=?;"; private static final String DELETE_MEMBER = "DELETE FROM `island_members` WHERE `uuid`=? AND `island_owner_uuid`=?;";
private static final String UPDATE_ISLAND = "UPDATE `islands` SET `editPermission`=?, `visitPermission`=? WHERE `owner`=?;"; private static final String UPDATE_ISLAND = "UPDATE `islands` SET `editPermission`=?, `visitPermission`=?, `interactPermission`=? WHERE `owner`=?;";
private static final String CREATE_ISLANDS_TABLE = "CREATE TABLE IF NOT EXISTS `islands` (`owner` VARCHAR(36) NOT NULL PRIMARY KEY, `editPermission` VARCHAR(10), `visitPermission` VARCHAR(10), `interactPermission` VARCHAR(10));";
private static final String CREATE_MEMBERS_TABLE = "CREATE TABLE IF NOT EXISTS `island_members` (`uuid` VARCHAR(36), `island_owner_uuid` VARCHAR(36));";
@Getter @Getter
@Accessors(fluent = true) @Accessors(fluent = true)
private final Map<UUID, PlayerWorld> loadedIslands = Maps.newHashMap(); private final Map<UUID, PlayerWorld> loadedIslands = Maps.newHashMap();
public void createTables()
{
try (Connection connection = Plex.get().getSqlConnection().getCon())
{
connection.prepareStatement(CREATE_ISLANDS_TABLE).execute();
connection.prepareStatement(CREATE_MEMBERS_TABLE).execute();
} catch (SQLException e)
{
throw new RuntimeException(e);
}
}
public void loadIslands() public void loadIslands()
{ {
// Member to Islands Mapping // Member to Islands Mapping
@ -62,7 +75,11 @@ public class IslandHandler
final List<UUID> members = mappedMembers.entrySet().stream().filter(uuiduuidEntry -> uuiduuidEntry.getValue().stream().anyMatch(owners -> owners.equals(owner))).map(Map.Entry::getKey).toList(); final List<UUID> members = mappedMembers.entrySet().stream().filter(uuiduuidEntry -> uuiduuidEntry.getValue().stream().anyMatch(owners -> owners.equals(owner))).map(Map.Entry::getKey).toList();
final IslandPermissions editPerm = IslandPermissions.valueOf(islandsQuery.getString("editPermission").toUpperCase()); final IslandPermissions editPerm = IslandPermissions.valueOf(islandsQuery.getString("editPermission").toUpperCase());
final IslandPermissions visitPerm = IslandPermissions.valueOf(islandsQuery.getString("visitPermission").toUpperCase()); final IslandPermissions visitPerm = IslandPermissions.valueOf(islandsQuery.getString("visitPermission").toUpperCase());
loadedIslands.put(owner, new PlayerWorld(owner, members, editPerm, visitPerm));
final String interactPermission = islandsQuery.getString("interactPermission");
final IslandPermissions interactPerm = interactPermission == null ? IslandPermissions.NOBODY : IslandPermissions.valueOf(interactPermission.toUpperCase());
loadedIslands.put(owner, new PlayerWorld(owner, members, editPerm, visitPerm, interactPerm));
} }
} }
catch (SQLException e) catch (SQLException e)
@ -79,6 +96,7 @@ public class IslandHandler
statement.setString(1, world.owner().toString()); statement.setString(1, world.owner().toString());
statement.setString(2, world.editPermission().name()); statement.setString(2, world.editPermission().name());
statement.setString(3, world.visitPermission().name()); statement.setString(3, world.visitPermission().name());
statement.setString(4, world.interactPermission().name());
statement.execute(); statement.execute();
@ -143,7 +161,8 @@ public class IslandHandler
final PreparedStatement statement = connection.prepareStatement(UPDATE_ISLAND); final PreparedStatement statement = connection.prepareStatement(UPDATE_ISLAND);
statement.setString(1, world.editPermission().name()); statement.setString(1, world.editPermission().name());
statement.setString(2, world.visitPermission().name()); statement.setString(2, world.visitPermission().name());
statement.setString(3, world.owner().toString()); statement.setString(3, world.interactPermission().name());
statement.setString(4, world.owner().toString());
statement.executeUpdate(); statement.executeUpdate();

View File

@ -0,0 +1,105 @@
package dev.plex.extras.listener;
import dev.plex.extras.TFMExtras;
import dev.plex.extras.island.PlayerWorld;
import dev.plex.extras.island.info.IslandPermissions;
import dev.plex.listener.PlexListener;
import dev.plex.util.PlexUtils;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import java.util.UUID;
public class WorldListener extends PlexListener
{
@EventHandler
public void onBuild(BlockPlaceEvent event)
{
if (!TFMExtras.getModule().getSlimeWorldHook().isWorldLoaded(event.getPlayer().getWorld().getName())) return;
final UUID worldOwner = UUID.fromString(event.getPlayer().getWorld().getName());
final PlayerWorld world = TFMExtras.getModule().getIslandHandler().loadedIslands().get(worldOwner);
if (world.owner().equals(event.getPlayer().getUniqueId())) return;
if (world.editPermission() == IslandPermissions.NOBODY)
{
event.getPlayer().sendMessage(PlexUtils.messageComponent("cantModifyIsland"));
event.setCancelled(true);
event.setBuild(false);
return;
}
if (world.editPermission() == IslandPermissions.MEMBERS && !world.members().contains(event.getPlayer().getUniqueId()))
{
event.getPlayer().sendMessage(PlexUtils.messageComponent("cantModifyIsland"));
event.setCancelled(true);
event.setBuild(false);
}
}
@EventHandler
public void onBreak(BlockBreakEvent event)
{
if (!TFMExtras.getModule().getSlimeWorldHook().isWorldLoaded(event.getPlayer().getWorld().getName())) return;
final UUID worldOwner = UUID.fromString(event.getPlayer().getWorld().getName());
final PlayerWorld world = TFMExtras.getModule().getIslandHandler().loadedIslands().get(worldOwner);
if (world.owner().equals(event.getPlayer().getUniqueId())) return;
if (world.editPermission() == IslandPermissions.NOBODY)
{
event.getPlayer().sendMessage(PlexUtils.messageComponent("cantModifyIsland"));
event.setCancelled(true);
return;
}
if (world.editPermission() == IslandPermissions.MEMBERS && !world.members().contains(event.getPlayer().getUniqueId()))
{
event.getPlayer().sendMessage(PlexUtils.messageComponent("cantModifyIsland"));
event.setCancelled(true);
}
}
@EventHandler
public void onInteract(PlayerInteractEvent event)
{
if (!TFMExtras.getModule().getSlimeWorldHook().isWorldLoaded(event.getPlayer().getWorld().getName())) return;
final UUID worldOwner = UUID.fromString(event.getPlayer().getWorld().getName());
final PlayerWorld world = TFMExtras.getModule().getIslandHandler().loadedIslands().get(worldOwner);
if (world.owner().equals(event.getPlayer().getUniqueId())) return;
if (world.interactPermission() == IslandPermissions.NOBODY)
{
event.getPlayer().sendMessage(PlexUtils.messageComponent("cantModifyIsland"));
event.setCancelled(true);
return;
}
if (world.interactPermission() == IslandPermissions.MEMBERS && !world.members().contains(event.getPlayer().getUniqueId()))
{
event.getPlayer().sendMessage(PlexUtils.messageComponent("cantModifyIsland"));
event.setCancelled(true);
}
}
@EventHandler
public void onWorldChange(PlayerChangedWorldEvent event)
{
if (!TFMExtras.getModule().getSlimeWorldHook().isWorldLoaded(event.getPlayer().getWorld().getName())) return;
final UUID worldOwner = UUID.fromString(event.getPlayer().getWorld().getName());
final PlayerWorld world = TFMExtras.getModule().getIslandHandler().loadedIslands().get(worldOwner);
if (world.owner().equals(event.getPlayer().getUniqueId())) return;
if (world.visitPermission() == IslandPermissions.NOBODY)
{
event.getPlayer().sendMessage(PlexUtils.messageComponent("cantVisitIsland"));
event.getPlayer().teleportAsync(event.getFrom().getSpawnLocation());
return;
}
if (world.visitPermission() == IslandPermissions.MEMBERS && !world.members().contains(event.getPlayer().getUniqueId()))
{
event.getPlayer().sendMessage(PlexUtils.messageComponent("cantVisitIsland"));
event.getPlayer().teleportAsync(event.getFrom().getSpawnLocation());
return;
}
}
}