mirror of
https://github.com/plexusorg/Module-Guilds.git
synced 2026-06-04 02:36:54 +00:00
Update Guilds module (wip)
This commit is contained in:
@@ -7,7 +7,7 @@ import dev.plex.handler.ChatHandlerImpl;
|
||||
import dev.plex.module.PlexModule;
|
||||
import dev.plex.api.storage.ModuleStorage;
|
||||
import dev.plex.storage.GuildRepository;
|
||||
import dev.plex.storage.OrmGuildRepository;
|
||||
import dev.plex.storage.JdbiGuildRepository;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.sql.SQLException;
|
||||
@@ -45,7 +45,7 @@ public class Guilds extends PlexModule
|
||||
{
|
||||
throw new IllegalStateException("Failed to run Guilds migrations", e);
|
||||
}
|
||||
guildRepository = new OrmGuildRepository(storage);
|
||||
guildRepository = new JdbiGuildRepository(storage);
|
||||
guildRepository.loadGuilds().whenComplete((guilds, throwable) ->
|
||||
{
|
||||
if (throwable != null)
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.Locale;
|
||||
|
||||
public class GuildCommand extends SimplePlexCommand
|
||||
{
|
||||
private final List<SimplePlexCommand> subCommands = Lists.newArrayList();
|
||||
private final List<GuildSubCommand> subCommands = Lists.newArrayList();
|
||||
|
||||
public GuildCommand()
|
||||
{
|
||||
@@ -70,7 +70,7 @@ public class GuildCommand extends SimplePlexCommand
|
||||
.append(mmString("<gold>Permission: <yellow>" + subCommand.getPermission())).append(Component.newline())
|
||||
.append(mmString("<gold>Required Source: <yellow>" + subCommand.getRequiredSource().name()));
|
||||
}
|
||||
SimplePlexCommand subCommand = getSubCommand(args[0]);
|
||||
GuildSubCommand subCommand = getSubCommand(args[0]);
|
||||
if (subCommand == null)
|
||||
{
|
||||
return messageComponent("guildCommandNotFound", args[0]);
|
||||
@@ -88,10 +88,10 @@ public class GuildCommand extends SimplePlexCommand
|
||||
|
||||
checkPermission(commandSender, subCommand.getPermission());
|
||||
|
||||
return subCommand.execute(commandSender, player, Arrays.copyOfRange(args, 1, args.length));
|
||||
return subCommand.executeSubCommand(commandSender, player, Arrays.copyOfRange(args, 1, args.length));
|
||||
}
|
||||
|
||||
private SimplePlexCommand getSubCommand(String label)
|
||||
private GuildSubCommand getSubCommand(String label)
|
||||
{
|
||||
return subCommands.stream()
|
||||
.filter(cmd -> cmd.getName().equalsIgnoreCase(label) || cmd.getAliases().stream().anyMatch(alias -> alias.equalsIgnoreCase(label)))
|
||||
@@ -99,7 +99,7 @@ public class GuildCommand extends SimplePlexCommand
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private void registerSubCommand(SimplePlexCommand subCommand)
|
||||
private void registerSubCommand(GuildSubCommand subCommand)
|
||||
{
|
||||
if (Guilds.get() != null)
|
||||
{
|
||||
@@ -132,10 +132,10 @@ public class GuildCommand extends SimplePlexCommand
|
||||
}
|
||||
if (args.length >= 2)
|
||||
{
|
||||
SimplePlexCommand subCommand = getSubCommand(args[0]);
|
||||
GuildSubCommand subCommand = getSubCommand(args[0]);
|
||||
if (subCommand != null)
|
||||
{
|
||||
return subCommand.suggestions(sender, alias, Arrays.copyOfRange(args, 1, args.length));
|
||||
return subCommand.suggestSubCommand(sender, alias, Arrays.copyOfRange(args, 1, args.length));
|
||||
}
|
||||
}
|
||||
return ImmutableList.of();
|
||||
|
||||
@@ -2,7 +2,6 @@ package dev.plex.command.sub;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import dev.plex.guild.Guild;
|
||||
import dev.plex.guild.data.GuildRole;
|
||||
@@ -19,7 +18,7 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class AcceptSubCommand extends SimplePlexCommand
|
||||
public class AcceptSubCommand extends GuildSubCommand
|
||||
{
|
||||
public AcceptSubCommand()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.plex.command.sub;
|
||||
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import dev.plex.guild.data.Member;
|
||||
import java.util.Collections;
|
||||
@@ -16,7 +15,7 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ChatSubCommand extends SimplePlexCommand
|
||||
public class ChatSubCommand extends GuildSubCommand
|
||||
{
|
||||
public ChatSubCommand()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.plex.command.sub;
|
||||
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import dev.plex.guild.Guild;
|
||||
import java.util.Collections;
|
||||
@@ -13,7 +12,7 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class CreateSubCommand extends SimplePlexCommand
|
||||
public class CreateSubCommand extends GuildSubCommand
|
||||
{
|
||||
public CreateSubCommand()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.plex.command.sub;
|
||||
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import dev.plex.storage.entity.GuildInviteEntity;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@@ -12,7 +11,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class DenySubCommand extends SimplePlexCommand
|
||||
public class DenySubCommand extends GuildSubCommand
|
||||
{
|
||||
public DenySubCommand()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.plex.command.sub;
|
||||
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -9,7 +8,7 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class DisbandSubCommand extends SimplePlexCommand
|
||||
public class DisbandSubCommand extends GuildSubCommand
|
||||
{
|
||||
public DisbandSubCommand()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package dev.plex.command.sub;
|
||||
|
||||
import dev.plex.command.CommandSpec;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import java.util.List;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class GuildSubCommand extends SimplePlexCommand
|
||||
{
|
||||
protected GuildSubCommand(CommandSpec commandSpec)
|
||||
{
|
||||
super(commandSpec);
|
||||
}
|
||||
|
||||
public final Component executeSubCommand(@NotNull CommandSender sender, @Nullable Player player, @NotNull String[] args)
|
||||
{
|
||||
return execute(sender, player, args);
|
||||
}
|
||||
|
||||
public final @NotNull List<String> suggestSubCommand(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args)
|
||||
{
|
||||
return suggestions(sender, alias, args);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.plex.command.sub;
|
||||
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -11,7 +10,7 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class HomeSubCommand extends SimplePlexCommand
|
||||
public class HomeSubCommand extends GuildSubCommand
|
||||
{
|
||||
public HomeSubCommand()
|
||||
{
|
||||
|
||||
@@ -2,7 +2,6 @@ package dev.plex.command.sub;
|
||||
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.api.player.PlexPlayerView;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import dev.plex.guild.Guild;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
@@ -16,7 +15,7 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class InfoSubCommand extends SimplePlexCommand
|
||||
public class InfoSubCommand extends GuildSubCommand
|
||||
{
|
||||
public InfoSubCommand()
|
||||
{
|
||||
|
||||
@@ -2,7 +2,6 @@ package dev.plex.command.sub;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -14,7 +13,7 @@ import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.List;
|
||||
|
||||
public class InviteSubCommand extends SimplePlexCommand
|
||||
public class InviteSubCommand extends GuildSubCommand
|
||||
{
|
||||
public InviteSubCommand()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.plex.command.sub;
|
||||
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import dev.plex.guild.data.Member;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@@ -12,7 +11,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class LeaveSubCommand extends SimplePlexCommand
|
||||
public class LeaveSubCommand extends GuildSubCommand
|
||||
{
|
||||
public LeaveSubCommand()
|
||||
{
|
||||
|
||||
@@ -2,7 +2,6 @@ package dev.plex.command.sub;
|
||||
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.api.player.PlexPlayerView;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import dev.plex.guild.data.GuildRole;
|
||||
import dev.plex.guild.data.Member;
|
||||
@@ -14,7 +13,7 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class OwnerSubCommand extends SimplePlexCommand
|
||||
public class OwnerSubCommand extends GuildSubCommand
|
||||
{
|
||||
public OwnerSubCommand()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.plex.command.sub;
|
||||
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import dev.plex.util.GuildUtil;
|
||||
import java.util.Collections;
|
||||
@@ -13,7 +12,7 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PrefixSubCommand extends SimplePlexCommand
|
||||
public class PrefixSubCommand extends GuildSubCommand
|
||||
{
|
||||
public PrefixSubCommand()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.plex.command.sub;
|
||||
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import dev.plex.util.CustomLocation;
|
||||
import java.util.Collections;
|
||||
@@ -12,7 +11,7 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class SetHomeSubCommand extends SimplePlexCommand
|
||||
public class SetHomeSubCommand extends GuildSubCommand
|
||||
{
|
||||
public SetHomeSubCommand()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.plex.command.sub;
|
||||
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import dev.plex.util.CustomLocation;
|
||||
import java.util.Collections;
|
||||
@@ -14,7 +13,7 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class SetWarpSubCommand extends SimplePlexCommand
|
||||
public class SetWarpSubCommand extends GuildSubCommand
|
||||
{
|
||||
public SetWarpSubCommand()
|
||||
{
|
||||
|
||||
@@ -2,7 +2,6 @@ package dev.plex.command.sub;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import dev.plex.guild.Guild;
|
||||
import java.util.Collections;
|
||||
@@ -14,7 +13,7 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class WarpListSubCommand extends SimplePlexCommand
|
||||
public class WarpListSubCommand extends GuildSubCommand
|
||||
{
|
||||
public WarpListSubCommand()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package dev.plex.command.sub;
|
||||
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.command.SimplePlexCommand;
|
||||
import dev.plex.command.source.RequiredCommandSource;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -12,7 +11,7 @@ import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class WarpSubCommand extends SimplePlexCommand
|
||||
public class WarpSubCommand extends GuildSubCommand
|
||||
{
|
||||
public WarpSubCommand()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,638 @@
|
||||
package dev.plex.storage;
|
||||
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.api.storage.ModuleStorage;
|
||||
import dev.plex.guild.Guild;
|
||||
import dev.plex.guild.data.GuildRole;
|
||||
import dev.plex.guild.data.Member;
|
||||
import dev.plex.storage.entity.GuildEntity;
|
||||
import dev.plex.storage.entity.GuildInviteEntity;
|
||||
import dev.plex.storage.entity.GuildMemberEntity;
|
||||
import dev.plex.storage.entity.GuildWarpEntity;
|
||||
import dev.plex.util.CustomLocation;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jdbi.v3.core.Handle;
|
||||
import org.jdbi.v3.core.Jdbi;
|
||||
import org.jdbi.v3.core.JdbiException;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class JdbiGuildRepository implements GuildRepository
|
||||
{
|
||||
private final Jdbi jdbi;
|
||||
private final Executor executor;
|
||||
private final String guildsTable;
|
||||
private final String membersTable;
|
||||
private final String warpsTable;
|
||||
private final String invitesTable;
|
||||
|
||||
public JdbiGuildRepository(ModuleStorage storage)
|
||||
{
|
||||
this.jdbi = storage.jdbi();
|
||||
this.executor = Guilds.get().api().scheduler().asyncExecutor();
|
||||
this.guildsTable = storage.table("guilds");
|
||||
this.membersTable = storage.table("members");
|
||||
this.warpsTable = storage.table("warps");
|
||||
this.invitesTable = storage.table("invites");
|
||||
ensureSchema();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<Guild>> loadGuilds()
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
return jdbi.withHandle(h ->
|
||||
{
|
||||
List<GuildEntity> guilds = h.createQuery("SELECT * FROM " + guildsTable)
|
||||
.map((rs, ctx) -> guildMapRow(rs)).list();
|
||||
Map<String, List<GuildMemberEntity>> membersByGuild = h.createQuery("SELECT * FROM " + membersTable)
|
||||
.map((rs, ctx) -> memberMapRow(rs)).list().stream()
|
||||
.collect(Collectors.groupingBy(GuildMemberEntity::getGuildUuid));
|
||||
Map<String, List<GuildWarpEntity>> warpsByGuild = h.createQuery("SELECT * FROM " + warpsTable)
|
||||
.map((rs, ctx) -> warpMapRow(rs)).list().stream()
|
||||
.collect(Collectors.groupingBy(GuildWarpEntity::getGuildUuid));
|
||||
return guilds.stream().map(entity ->
|
||||
{
|
||||
Guild guild = toGuildBase(entity);
|
||||
membersByGuild.getOrDefault(entity.getGuildUuid(), List.of())
|
||||
.forEach(member -> guild.addMember(toMember(member)));
|
||||
warpsByGuild.getOrDefault(entity.getGuildUuid(), List.of())
|
||||
.forEach(warp -> guild.getWarps().put(warp.getName(), toLocation(warp)));
|
||||
return guild;
|
||||
}).toList();
|
||||
});
|
||||
}
|
||||
catch (JdbiException e)
|
||||
{
|
||||
throw new IllegalStateException("Failed to load guilds", e);
|
||||
}
|
||||
}, executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Guild> createGuild(Player owner, String name)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
Guild guild = Guild.create(owner, name);
|
||||
GuildEntity e = toEntity(guild);
|
||||
jdbi.useTransaction(h ->
|
||||
{
|
||||
h.createUpdate("INSERT INTO " + guildsTable + " (guild_uuid, name, prefix, owner_uuid, created_at, " +
|
||||
"home_world, home_x, home_y, home_z, home_yaw, home_pitch, motd, tag_enabled, is_public) " +
|
||||
"VALUES (:guildUuid, :name, :prefix, :ownerUuid, :createdAt, :homeWorld, :homeX, :homeY, :homeZ, " +
|
||||
":homeYaw, :homePitch, :motd, :tagEnabled, :isPublic)")
|
||||
.bind("guildUuid", e.getGuildUuid())
|
||||
.bind("name", e.getName())
|
||||
.bind("prefix", e.getPrefix())
|
||||
.bind("ownerUuid", e.getOwnerUuid())
|
||||
.bind("createdAt", e.getCreatedAt())
|
||||
.bind("homeWorld", e.getHomeWorld())
|
||||
.bind("homeX", e.getHomeX())
|
||||
.bind("homeY", e.getHomeY())
|
||||
.bind("homeZ", e.getHomeZ())
|
||||
.bind("homeYaw", e.getHomeYaw())
|
||||
.bind("homePitch", e.getHomePitch())
|
||||
.bind("motd", e.getMotd())
|
||||
.bind("tagEnabled", e.isTagEnabled())
|
||||
.bind("isPublic", e.isPublicGuild())
|
||||
.execute();
|
||||
insertMember(h, guild.getGuildUuid(), owner.getUniqueId(), GuildRole.OWNER);
|
||||
});
|
||||
return guild;
|
||||
}
|
||||
catch (JdbiException e)
|
||||
{
|
||||
throw new IllegalStateException("Failed to create guild", e);
|
||||
}
|
||||
}, executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteGuild(UUID guildUuid)
|
||||
{
|
||||
return runAsync(() -> jdbi.useTransaction(h ->
|
||||
{
|
||||
h.createUpdate("DELETE FROM " + membersTable + " WHERE guild_uuid = :g").bind("g", guildUuid.toString()).execute();
|
||||
h.createUpdate("DELETE FROM " + warpsTable + " WHERE guild_uuid = :g").bind("g", guildUuid.toString()).execute();
|
||||
h.createUpdate("DELETE FROM " + invitesTable + " WHERE guild_uuid = :g").bind("g", guildUuid.toString()).execute();
|
||||
h.createUpdate("DELETE FROM " + guildsTable + " WHERE guild_uuid = :g").bind("g", guildUuid.toString()).execute();
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> addMember(UUID guildUuid, UUID playerUuid, GuildRole role)
|
||||
{
|
||||
return runAsync(() -> jdbi.useTransaction(h -> upsertMember(h, guildUuid, playerUuid, role)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeMember(UUID guildUuid, UUID playerUuid)
|
||||
{
|
||||
return runAsync(() -> jdbi.useHandle(h -> h.createUpdate("DELETE FROM " + membersTable + " WHERE guild_uuid = :g AND player_uuid = :p")
|
||||
.bind("g", guildUuid.toString())
|
||||
.bind("p", playerUuid.toString())
|
||||
.execute()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> transferOwner(UUID guildUuid, UUID newOwnerUuid, UUID oldOwnerUuid)
|
||||
{
|
||||
return runAsync(() -> jdbi.useTransaction(h ->
|
||||
{
|
||||
h.createUpdate("UPDATE " + guildsTable + " SET owner_uuid = :o WHERE guild_uuid = :g")
|
||||
.bind("o", newOwnerUuid.toString())
|
||||
.bind("g", guildUuid.toString())
|
||||
.execute();
|
||||
upsertMember(h, guildUuid, oldOwnerUuid, GuildRole.MEMBER);
|
||||
upsertMember(h, guildUuid, newOwnerUuid, GuildRole.OWNER);
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> updatePrefix(UUID guildUuid, String prefix)
|
||||
{
|
||||
return runAsync(() -> jdbi.useHandle(h -> h.createUpdate("UPDATE " + guildsTable + " SET prefix = :p WHERE guild_uuid = :g")
|
||||
.bind("p", prefix)
|
||||
.bind("g", guildUuid.toString())
|
||||
.execute()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> updateHome(UUID guildUuid, CustomLocation home)
|
||||
{
|
||||
return runAsync(() -> jdbi.useHandle(h -> h.createUpdate("UPDATE " + guildsTable +
|
||||
" SET home_world = :w, home_x = :x, home_y = :y, home_z = :z, home_yaw = :yaw, home_pitch = :pitch " +
|
||||
"WHERE guild_uuid = :g")
|
||||
.bind("w", home == null ? null : home.getWorldName())
|
||||
.bind("x", home == null ? null : home.getX())
|
||||
.bind("y", home == null ? null : home.getY())
|
||||
.bind("z", home == null ? null : home.getZ())
|
||||
.bind("yaw", home == null ? null : home.getYaw())
|
||||
.bind("pitch", home == null ? null : home.getPitch())
|
||||
.bind("g", guildUuid.toString())
|
||||
.execute()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> upsertWarp(UUID guildUuid, String name, CustomLocation location)
|
||||
{
|
||||
return runAsync(() -> jdbi.useTransaction(h ->
|
||||
{
|
||||
String lowerName = name.toLowerCase(Locale.ROOT);
|
||||
GuildWarpEntity entity = h.createQuery("SELECT * FROM " + warpsTable + " WHERE guild_uuid = :g AND name = :n")
|
||||
.bind("g", guildUuid.toString())
|
||||
.bind("n", lowerName)
|
||||
.map((rs, ctx) -> warpMapRow(rs))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (entity == null)
|
||||
{
|
||||
entity = new GuildWarpEntity();
|
||||
entity.setGuildUuid(guildUuid.toString());
|
||||
entity.setName(lowerName);
|
||||
setWarpLocation(entity, location);
|
||||
h.createUpdate("INSERT INTO " + warpsTable + " (guild_uuid, name, world, x, y, z, yaw, pitch) " +
|
||||
"VALUES (:g, :n, :w, :x, :y, :z, :yaw, :pitch)")
|
||||
.bind("g", entity.getGuildUuid())
|
||||
.bind("n", entity.getName())
|
||||
.bind("w", entity.getWorld())
|
||||
.bind("x", entity.getX())
|
||||
.bind("y", entity.getY())
|
||||
.bind("z", entity.getZ())
|
||||
.bind("yaw", entity.getYaw())
|
||||
.bind("pitch", entity.getPitch())
|
||||
.execute();
|
||||
return;
|
||||
}
|
||||
setWarpLocation(entity, location);
|
||||
h.createUpdate("UPDATE " + warpsTable + " SET world = :w, x = :x, y = :y, z = :z, yaw = :yaw, pitch = :pitch " +
|
||||
"WHERE guild_uuid = :g AND name = :n")
|
||||
.bind("w", entity.getWorld())
|
||||
.bind("x", entity.getX())
|
||||
.bind("y", entity.getY())
|
||||
.bind("z", entity.getZ())
|
||||
.bind("yaw", entity.getYaw())
|
||||
.bind("pitch", entity.getPitch())
|
||||
.bind("g", guildUuid.toString())
|
||||
.bind("n", lowerName)
|
||||
.execute();
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteWarp(UUID guildUuid, String name)
|
||||
{
|
||||
return runAsync(() -> jdbi.useHandle(h -> h.createUpdate("DELETE FROM " + warpsTable + " WHERE guild_uuid = :g AND name = :n")
|
||||
.bind("g", guildUuid.toString())
|
||||
.bind("n", name.toLowerCase(Locale.ROOT))
|
||||
.execute()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> createInvite(UUID guildUuid, UUID inviterUuid, UUID inviteeUuid, Instant expiresAt)
|
||||
{
|
||||
return runAsync(() -> jdbi.useTransaction(h ->
|
||||
{
|
||||
deleteInviteSync(h, guildUuid, inviteeUuid);
|
||||
h.createUpdate("INSERT INTO " + invitesTable + " (guild_uuid, inviter_uuid, invitee_uuid, expires_at) " +
|
||||
"VALUES (:g, :inviter, :invitee, :expires)")
|
||||
.bind("g", guildUuid.toString())
|
||||
.bind("inviter", inviterUuid.toString())
|
||||
.bind("invitee", inviteeUuid.toString())
|
||||
.bind("expires", expiresAt.toEpochMilli())
|
||||
.execute();
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteInvite(UUID guildUuid, UUID inviteeUuid)
|
||||
{
|
||||
return runAsync(() -> jdbi.useHandle(h -> deleteInviteSync(h, guildUuid, inviteeUuid)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<GuildInviteEntity>> invitesFor(UUID inviteeUuid)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
long now = Instant.now().toEpochMilli();
|
||||
return jdbi.withHandle(h -> h.createQuery("SELECT * FROM " + invitesTable + " WHERE invitee_uuid = :i")
|
||||
.bind("i", inviteeUuid.toString())
|
||||
.map((rs, ctx) -> inviteMapRow(rs))
|
||||
.list()).stream()
|
||||
.filter(invite -> invite.getExpiresAt() >= now)
|
||||
.toList();
|
||||
}
|
||||
catch (JdbiException e)
|
||||
{
|
||||
throw new IllegalStateException("Failed to load guild invites", e);
|
||||
}
|
||||
}, executor);
|
||||
}
|
||||
|
||||
private static GuildEntity guildMapRow(java.sql.ResultSet rs) throws java.sql.SQLException
|
||||
{
|
||||
GuildEntity e = new GuildEntity();
|
||||
e.setGuildUuid(rs.getString("guild_uuid"));
|
||||
e.setName(rs.getString("name"));
|
||||
e.setPrefix(rs.getString("prefix"));
|
||||
e.setOwnerUuid(rs.getString("owner_uuid"));
|
||||
e.setCreatedAt(rs.getLong("created_at"));
|
||||
e.setHomeWorld(rs.getString("home_world"));
|
||||
e.setHomeX(rs.getObject("home_x", Double.class));
|
||||
e.setHomeY(rs.getObject("home_y", Double.class));
|
||||
e.setHomeZ(rs.getObject("home_z", Double.class));
|
||||
e.setHomeYaw(rs.getObject("home_yaw", Float.class));
|
||||
e.setHomePitch(rs.getObject("home_pitch", Float.class));
|
||||
e.setMotd(rs.getString("motd"));
|
||||
e.setTagEnabled(rs.getBoolean("tag_enabled"));
|
||||
e.setPublicGuild(rs.getBoolean("is_public"));
|
||||
return e;
|
||||
}
|
||||
|
||||
private static GuildMemberEntity memberMapRow(java.sql.ResultSet rs) throws java.sql.SQLException
|
||||
{
|
||||
GuildMemberEntity e = new GuildMemberEntity();
|
||||
e.setId(rs.getLong("id"));
|
||||
e.setGuildUuid(rs.getString("guild_uuid"));
|
||||
e.setPlayerUuid(rs.getString("player_uuid"));
|
||||
e.setRole(rs.getString("role"));
|
||||
e.setJoinedAt(rs.getLong("joined_at"));
|
||||
return e;
|
||||
}
|
||||
|
||||
private static GuildWarpEntity warpMapRow(java.sql.ResultSet rs) throws java.sql.SQLException
|
||||
{
|
||||
GuildWarpEntity e = new GuildWarpEntity();
|
||||
e.setId(rs.getLong("id"));
|
||||
e.setGuildUuid(rs.getString("guild_uuid"));
|
||||
e.setName(rs.getString("name"));
|
||||
e.setWorld(rs.getString("world"));
|
||||
e.setX(rs.getDouble("x"));
|
||||
e.setY(rs.getDouble("y"));
|
||||
e.setZ(rs.getDouble("z"));
|
||||
e.setYaw(rs.getFloat("yaw"));
|
||||
e.setPitch(rs.getFloat("pitch"));
|
||||
return e;
|
||||
}
|
||||
|
||||
private static GuildInviteEntity inviteMapRow(java.sql.ResultSet rs) throws java.sql.SQLException
|
||||
{
|
||||
GuildInviteEntity e = new GuildInviteEntity();
|
||||
e.setId(rs.getLong("id"));
|
||||
e.setGuildUuid(rs.getString("guild_uuid"));
|
||||
e.setInviterUuid(rs.getString("inviter_uuid"));
|
||||
e.setInviteeUuid(rs.getString("invitee_uuid"));
|
||||
e.setExpiresAt(rs.getLong("expires_at"));
|
||||
return e;
|
||||
}
|
||||
|
||||
private void ensureSchema()
|
||||
{
|
||||
try
|
||||
{
|
||||
jdbi.useHandle(h ->
|
||||
{
|
||||
String productName = h.getConnection().getMetaData().getDatabaseProductName().toLowerCase(Locale.ROOT);
|
||||
schemaStatements(productName).forEach(sql -> h.createUpdate(sql).execute());
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IllegalStateException("Failed to create guild tables", e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> schemaStatements(String productName)
|
||||
{
|
||||
if (productName.contains("sqlite"))
|
||||
{
|
||||
return List.of(
|
||||
"CREATE TABLE IF NOT EXISTS " + guildsTable + " (" +
|
||||
"guild_uuid VARCHAR(46) NOT NULL PRIMARY KEY, " +
|
||||
"name VARCHAR(64) NOT NULL UNIQUE, " +
|
||||
"prefix VARCHAR(64), " +
|
||||
"owner_uuid VARCHAR(46) NOT NULL, " +
|
||||
"created_at BIGINT NOT NULL, " +
|
||||
"home_world VARCHAR(128), " +
|
||||
"home_x DOUBLE, " +
|
||||
"home_y DOUBLE, " +
|
||||
"home_z DOUBLE, " +
|
||||
"home_yaw FLOAT, " +
|
||||
"home_pitch FLOAT, " +
|
||||
"motd VARCHAR(3000), " +
|
||||
"tag_enabled BOOLEAN NOT NULL DEFAULT 1, " +
|
||||
"is_public BOOLEAN NOT NULL DEFAULT 0" +
|
||||
")",
|
||||
"CREATE TABLE IF NOT EXISTS " + membersTable + " (" +
|
||||
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
|
||||
"guild_uuid VARCHAR(46) NOT NULL, " +
|
||||
"player_uuid VARCHAR(46) NOT NULL, " +
|
||||
"role VARCHAR(20) NOT NULL, " +
|
||||
"joined_at BIGINT NOT NULL, " +
|
||||
"UNIQUE (guild_uuid, player_uuid)" +
|
||||
")",
|
||||
"CREATE TABLE IF NOT EXISTS " + warpsTable + " (" +
|
||||
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
|
||||
"guild_uuid VARCHAR(46) NOT NULL, " +
|
||||
"name VARCHAR(16) NOT NULL, " +
|
||||
"world VARCHAR(128) NOT NULL, " +
|
||||
"x DOUBLE NOT NULL, " +
|
||||
"y DOUBLE NOT NULL, " +
|
||||
"z DOUBLE NOT NULL, " +
|
||||
"yaw FLOAT NOT NULL, " +
|
||||
"pitch FLOAT NOT NULL, " +
|
||||
"UNIQUE (guild_uuid, name)" +
|
||||
")",
|
||||
"CREATE TABLE IF NOT EXISTS " + invitesTable + " (" +
|
||||
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
|
||||
"guild_uuid VARCHAR(46) NOT NULL, " +
|
||||
"inviter_uuid VARCHAR(46) NOT NULL, " +
|
||||
"invitee_uuid VARCHAR(46) NOT NULL, " +
|
||||
"expires_at BIGINT NOT NULL, " +
|
||||
"UNIQUE (guild_uuid, invitee_uuid)" +
|
||||
")"
|
||||
);
|
||||
}
|
||||
if (productName.contains("postgres"))
|
||||
{
|
||||
return List.of(
|
||||
"CREATE TABLE IF NOT EXISTS " + guildsTable + " (" +
|
||||
"guild_uuid VARCHAR(46) NOT NULL PRIMARY KEY, " +
|
||||
"name VARCHAR(64) NOT NULL UNIQUE, " +
|
||||
"prefix VARCHAR(64), " +
|
||||
"owner_uuid VARCHAR(46) NOT NULL, " +
|
||||
"created_at BIGINT NOT NULL, " +
|
||||
"home_world VARCHAR(128), " +
|
||||
"home_x DOUBLE PRECISION, " +
|
||||
"home_y DOUBLE PRECISION, " +
|
||||
"home_z DOUBLE PRECISION, " +
|
||||
"home_yaw REAL, " +
|
||||
"home_pitch REAL, " +
|
||||
"motd VARCHAR(3000), " +
|
||||
"tag_enabled BOOLEAN NOT NULL DEFAULT TRUE, " +
|
||||
"is_public BOOLEAN NOT NULL DEFAULT FALSE" +
|
||||
")",
|
||||
"CREATE TABLE IF NOT EXISTS " + membersTable + " (" +
|
||||
"id BIGSERIAL PRIMARY KEY, " +
|
||||
"guild_uuid VARCHAR(46) NOT NULL, " +
|
||||
"player_uuid VARCHAR(46) NOT NULL, " +
|
||||
"role VARCHAR(20) NOT NULL, " +
|
||||
"joined_at BIGINT NOT NULL, " +
|
||||
"CONSTRAINT uq_members_guild_player UNIQUE (guild_uuid, player_uuid)" +
|
||||
")",
|
||||
"CREATE TABLE IF NOT EXISTS " + warpsTable + " (" +
|
||||
"id BIGSERIAL PRIMARY KEY, " +
|
||||
"guild_uuid VARCHAR(46) NOT NULL, " +
|
||||
"name VARCHAR(16) NOT NULL, " +
|
||||
"world VARCHAR(128) NOT NULL, " +
|
||||
"x DOUBLE PRECISION NOT NULL, " +
|
||||
"y DOUBLE PRECISION NOT NULL, " +
|
||||
"z DOUBLE PRECISION NOT NULL, " +
|
||||
"yaw REAL NOT NULL, " +
|
||||
"pitch REAL NOT NULL, " +
|
||||
"CONSTRAINT uq_warps_guild_name UNIQUE (guild_uuid, name)" +
|
||||
")",
|
||||
"CREATE TABLE IF NOT EXISTS " + invitesTable + " (" +
|
||||
"id BIGSERIAL PRIMARY KEY, " +
|
||||
"guild_uuid VARCHAR(46) NOT NULL, " +
|
||||
"inviter_uuid VARCHAR(46) NOT NULL, " +
|
||||
"invitee_uuid VARCHAR(46) NOT NULL, " +
|
||||
"expires_at BIGINT NOT NULL, " +
|
||||
"CONSTRAINT uq_invites_guild_invitee UNIQUE (guild_uuid, invitee_uuid)" +
|
||||
")"
|
||||
);
|
||||
}
|
||||
return List.of(
|
||||
"CREATE TABLE IF NOT EXISTS " + guildsTable + " (" +
|
||||
"`guild_uuid` VARCHAR(46) NOT NULL, " +
|
||||
"`name` VARCHAR(64) NOT NULL, " +
|
||||
"`prefix` VARCHAR(64), " +
|
||||
"`owner_uuid` VARCHAR(46) NOT NULL, " +
|
||||
"`created_at` BIGINT NOT NULL, " +
|
||||
"`home_world` VARCHAR(128), " +
|
||||
"`home_x` DOUBLE, " +
|
||||
"`home_y` DOUBLE, " +
|
||||
"`home_z` DOUBLE, " +
|
||||
"`home_yaw` FLOAT, " +
|
||||
"`home_pitch` FLOAT, " +
|
||||
"`motd` VARCHAR(3000), " +
|
||||
"`tag_enabled` BOOLEAN NOT NULL DEFAULT TRUE, " +
|
||||
"`is_public` BOOLEAN NOT NULL DEFAULT FALSE, " +
|
||||
"PRIMARY KEY (`guild_uuid`), " +
|
||||
"UNIQUE KEY `uq_guilds_name` (`name`)" +
|
||||
")",
|
||||
"CREATE TABLE IF NOT EXISTS " + membersTable + " (" +
|
||||
"`id` BIGINT NOT NULL AUTO_INCREMENT, " +
|
||||
"`guild_uuid` VARCHAR(46) NOT NULL, " +
|
||||
"`player_uuid` VARCHAR(46) NOT NULL, " +
|
||||
"`role` VARCHAR(20) NOT NULL, " +
|
||||
"`joined_at` BIGINT NOT NULL, " +
|
||||
"PRIMARY KEY (`id`), " +
|
||||
"UNIQUE KEY `uq_members_guild_player` (`guild_uuid`, `player_uuid`)" +
|
||||
")",
|
||||
"CREATE TABLE IF NOT EXISTS " + warpsTable + " (" +
|
||||
"`id` BIGINT NOT NULL AUTO_INCREMENT, " +
|
||||
"`guild_uuid` VARCHAR(46) NOT NULL, " +
|
||||
"`name` VARCHAR(16) NOT NULL, " +
|
||||
"`world` VARCHAR(128) NOT NULL, " +
|
||||
"`x` DOUBLE NOT NULL, " +
|
||||
"`y` DOUBLE NOT NULL, " +
|
||||
"`z` DOUBLE NOT NULL, " +
|
||||
"`yaw` FLOAT NOT NULL, " +
|
||||
"`pitch` FLOAT NOT NULL, " +
|
||||
"PRIMARY KEY (`id`), " +
|
||||
"UNIQUE KEY `uq_warps_guild_name` (`guild_uuid`, `name`)" +
|
||||
")",
|
||||
"CREATE TABLE IF NOT EXISTS " + invitesTable + " (" +
|
||||
"`id` BIGINT NOT NULL AUTO_INCREMENT, " +
|
||||
"`guild_uuid` VARCHAR(46) NOT NULL, " +
|
||||
"`inviter_uuid` VARCHAR(46) NOT NULL, " +
|
||||
"`invitee_uuid` VARCHAR(46) NOT NULL, " +
|
||||
"`expires_at` BIGINT NOT NULL, " +
|
||||
"PRIMARY KEY (`id`), " +
|
||||
"UNIQUE KEY `uq_invites_guild_invitee` (`guild_uuid`, `invitee_uuid`)" +
|
||||
")"
|
||||
);
|
||||
}
|
||||
|
||||
private Guild toGuildBase(GuildEntity entity)
|
||||
{
|
||||
String timezone = Guilds.get().api().configuration().mainConfig().getString("server.timezone", "Etc/UTC");
|
||||
Guild guild = new Guild(UUID.fromString(entity.getGuildUuid()), ZonedDateTime.ofInstant(Instant.ofEpochMilli(entity.getCreatedAt()), ZoneId.of(timezone)));
|
||||
guild.setName(entity.getName());
|
||||
guild.setOwnerUuid(UUID.fromString(entity.getOwnerUuid()));
|
||||
guild.setPrefix(entity.getPrefix());
|
||||
guild.setMotd(entity.getMotd());
|
||||
guild.setTagEnabled(entity.isTagEnabled());
|
||||
guild.setPublic(entity.isPublicGuild());
|
||||
guild.setHome(toLocation(entity));
|
||||
return guild;
|
||||
}
|
||||
|
||||
private GuildEntity toEntity(Guild guild)
|
||||
{
|
||||
GuildEntity entity = new GuildEntity();
|
||||
entity.setGuildUuid(guild.getGuildUuid().toString());
|
||||
entity.setName(guild.getName());
|
||||
entity.setOwnerUuid(guild.getOwnerUuid().toString());
|
||||
entity.setCreatedAt(guild.getCreatedAt().toInstant().toEpochMilli());
|
||||
entity.setPrefix(guild.getPrefix());
|
||||
entity.setMotd(guild.getMotd());
|
||||
entity.setTagEnabled(guild.isTagEnabled());
|
||||
entity.setPublicGuild(guild.isPublic());
|
||||
setHome(entity, guild.getHome());
|
||||
return entity;
|
||||
}
|
||||
|
||||
private Member toMember(GuildMemberEntity entity)
|
||||
{
|
||||
return new Member(UUID.fromString(entity.getPlayerUuid()), GuildRole.valueOf(entity.getRole()));
|
||||
}
|
||||
|
||||
private GuildMemberEntity memberEntity(UUID guildUuid, UUID playerUuid, GuildRole role)
|
||||
{
|
||||
GuildMemberEntity entity = new GuildMemberEntity();
|
||||
entity.setGuildUuid(guildUuid.toString());
|
||||
entity.setPlayerUuid(playerUuid.toString());
|
||||
entity.setRole(role.name());
|
||||
entity.setJoinedAt(Instant.now().toEpochMilli());
|
||||
return entity;
|
||||
}
|
||||
|
||||
private void insertMember(Handle h, UUID guildUuid, UUID playerUuid, GuildRole role)
|
||||
{
|
||||
GuildMemberEntity entity = memberEntity(guildUuid, playerUuid, role);
|
||||
h.createUpdate("INSERT INTO " + membersTable + " (guild_uuid, player_uuid, role, joined_at) " +
|
||||
"VALUES (:g, :p, :r, :j)")
|
||||
.bind("g", entity.getGuildUuid())
|
||||
.bind("p", entity.getPlayerUuid())
|
||||
.bind("r", entity.getRole())
|
||||
.bind("j", entity.getJoinedAt())
|
||||
.execute();
|
||||
}
|
||||
|
||||
private void upsertMember(Handle h, UUID guildUuid, UUID playerUuid, GuildRole role)
|
||||
{
|
||||
GuildMemberEntity existing = h.createQuery("SELECT * FROM " + membersTable + " WHERE guild_uuid = :g AND player_uuid = :p")
|
||||
.bind("g", guildUuid.toString())
|
||||
.bind("p", playerUuid.toString())
|
||||
.map((rs, ctx) -> memberMapRow(rs))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (existing == null)
|
||||
{
|
||||
insertMember(h, guildUuid, playerUuid, role);
|
||||
return;
|
||||
}
|
||||
h.createUpdate("UPDATE " + membersTable + " SET role = :r WHERE guild_uuid = :g AND player_uuid = :p")
|
||||
.bind("r", role.name())
|
||||
.bind("g", guildUuid.toString())
|
||||
.bind("p", playerUuid.toString())
|
||||
.execute();
|
||||
}
|
||||
|
||||
private void deleteInviteSync(Handle h, UUID guildUuid, UUID inviteeUuid)
|
||||
{
|
||||
h.createUpdate("DELETE FROM " + invitesTable + " WHERE guild_uuid = :g AND invitee_uuid = :i")
|
||||
.bind("g", guildUuid.toString())
|
||||
.bind("i", inviteeUuid.toString())
|
||||
.execute();
|
||||
}
|
||||
|
||||
private void setHome(GuildEntity entity, CustomLocation home)
|
||||
{
|
||||
entity.setHomeWorld(home == null ? null : home.getWorldName());
|
||||
entity.setHomeX(home == null ? null : home.getX());
|
||||
entity.setHomeY(home == null ? null : home.getY());
|
||||
entity.setHomeZ(home == null ? null : home.getZ());
|
||||
entity.setHomeYaw(home == null ? null : home.getYaw());
|
||||
entity.setHomePitch(home == null ? null : home.getPitch());
|
||||
}
|
||||
|
||||
private CustomLocation toLocation(GuildEntity entity)
|
||||
{
|
||||
if (entity.getHomeWorld() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new CustomLocation(entity.getHomeWorld(), entity.getHomeX(), entity.getHomeY(), entity.getHomeZ(), entity.getHomeYaw(), entity.getHomePitch());
|
||||
}
|
||||
|
||||
private void setWarpLocation(GuildWarpEntity entity, CustomLocation location)
|
||||
{
|
||||
entity.setWorld(location.getWorldName());
|
||||
entity.setX(location.getX());
|
||||
entity.setY(location.getY());
|
||||
entity.setZ(location.getZ());
|
||||
entity.setYaw(location.getYaw());
|
||||
entity.setPitch(location.getPitch());
|
||||
}
|
||||
|
||||
private CustomLocation toLocation(GuildWarpEntity entity)
|
||||
{
|
||||
return new CustomLocation(entity.getWorld(), entity.getX(), entity.getY(), entity.getZ(), entity.getYaw(), entity.getPitch());
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> runAsync(Runnable runnable)
|
||||
{
|
||||
return CompletableFuture.runAsync(runnable, executor);
|
||||
}
|
||||
}
|
||||
@@ -1,372 +0,0 @@
|
||||
package dev.plex.storage;
|
||||
|
||||
import com.j256.ormlite.dao.Dao;
|
||||
import com.j256.ormlite.stmt.DeleteBuilder;
|
||||
import dev.plex.Guilds;
|
||||
import dev.plex.api.storage.ModuleStorage;
|
||||
import dev.plex.guild.Guild;
|
||||
import dev.plex.guild.data.GuildRole;
|
||||
import dev.plex.guild.data.Member;
|
||||
import dev.plex.storage.entity.GuildEntity;
|
||||
import dev.plex.storage.entity.GuildInviteEntity;
|
||||
import dev.plex.storage.entity.GuildMemberEntity;
|
||||
import dev.plex.storage.entity.GuildWarpEntity;
|
||||
import dev.plex.util.CustomLocation;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public class OrmGuildRepository implements GuildRepository
|
||||
{
|
||||
private final ModuleStorage moduleStorage;
|
||||
private final Executor executor;
|
||||
private final Dao<GuildEntity, String> guilds;
|
||||
private final Dao<GuildMemberEntity, Long> members;
|
||||
private final Dao<GuildWarpEntity, Long> warps;
|
||||
private final Dao<GuildInviteEntity, Long> invites;
|
||||
|
||||
public OrmGuildRepository(ModuleStorage moduleStorage)
|
||||
{
|
||||
this.moduleStorage = moduleStorage;
|
||||
this.executor = Guilds.get().api().scheduler().asyncExecutor();
|
||||
try
|
||||
{
|
||||
this.guilds = moduleStorage.orm().dao(GuildEntity.class, "guilds");
|
||||
this.members = moduleStorage.orm().dao(GuildMemberEntity.class, "members");
|
||||
this.warps = moduleStorage.orm().dao(GuildWarpEntity.class, "warps");
|
||||
this.invites = moduleStorage.orm().dao(GuildInviteEntity.class, "invites");
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new IllegalStateException("Failed to create guild DAOs", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<Guild>> loadGuilds()
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
return guilds.queryForAll().stream().map(this::toGuild).toList();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new IllegalStateException("Failed to load guilds", e);
|
||||
}
|
||||
}, executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Guild> createGuild(Player owner, String name)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
Guild guild = Guild.create(owner, name);
|
||||
moduleStorage.transaction(() ->
|
||||
{
|
||||
guilds.create(toEntity(guild));
|
||||
members.create(memberEntity(guild.getGuildUuid(), owner.getUniqueId(), GuildRole.OWNER));
|
||||
return null;
|
||||
});
|
||||
return guild;
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new IllegalStateException("Failed to create guild", e);
|
||||
}
|
||||
}, executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteGuild(UUID guildUuid)
|
||||
{
|
||||
return runAsync(() -> moduleStorage.transaction(() ->
|
||||
{
|
||||
deleteByGuild(members, guildUuid);
|
||||
deleteByGuild(warps, guildUuid);
|
||||
deleteByGuild(invites, guildUuid);
|
||||
guilds.deleteById(guildUuid.toString());
|
||||
return null;
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> addMember(UUID guildUuid, UUID playerUuid, GuildRole role)
|
||||
{
|
||||
return runAsync(() -> upsertMember(guildUuid, playerUuid, role));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> removeMember(UUID guildUuid, UUID playerUuid)
|
||||
{
|
||||
return runAsync(() ->
|
||||
{
|
||||
DeleteBuilder<GuildMemberEntity, Long> delete = members.deleteBuilder();
|
||||
delete.where().eq("guild_uuid", guildUuid.toString()).and().eq("player_uuid", playerUuid.toString());
|
||||
delete.delete();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> transferOwner(UUID guildUuid, UUID newOwnerUuid, UUID oldOwnerUuid)
|
||||
{
|
||||
return runAsync(() -> moduleStorage.transaction(() ->
|
||||
{
|
||||
GuildEntity guild = guilds.queryForId(guildUuid.toString());
|
||||
if (guild != null)
|
||||
{
|
||||
guild.setOwnerUuid(newOwnerUuid.toString());
|
||||
guilds.update(guild);
|
||||
}
|
||||
upsertMember(guildUuid, oldOwnerUuid, GuildRole.MEMBER);
|
||||
upsertMember(guildUuid, newOwnerUuid, GuildRole.OWNER);
|
||||
return null;
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> updatePrefix(UUID guildUuid, String prefix)
|
||||
{
|
||||
return runAsync(() ->
|
||||
{
|
||||
GuildEntity guild = guilds.queryForId(guildUuid.toString());
|
||||
if (guild != null)
|
||||
{
|
||||
guild.setPrefix(prefix);
|
||||
guilds.update(guild);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> updateHome(UUID guildUuid, CustomLocation home)
|
||||
{
|
||||
return runAsync(() ->
|
||||
{
|
||||
GuildEntity guild = guilds.queryForId(guildUuid.toString());
|
||||
if (guild != null)
|
||||
{
|
||||
setHome(guild, home);
|
||||
guilds.update(guild);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> upsertWarp(UUID guildUuid, String name, CustomLocation location)
|
||||
{
|
||||
return runAsync(() ->
|
||||
{
|
||||
GuildWarpEntity entity = warps.queryBuilder().where()
|
||||
.eq("guild_uuid", guildUuid.toString()).and().eq("name", name.toLowerCase(Locale.ROOT))
|
||||
.queryForFirst();
|
||||
if (entity == null)
|
||||
{
|
||||
entity = new GuildWarpEntity();
|
||||
entity.setGuildUuid(guildUuid.toString());
|
||||
entity.setName(name.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
setWarpLocation(entity, location);
|
||||
warps.createOrUpdate(entity);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteWarp(UUID guildUuid, String name)
|
||||
{
|
||||
return runAsync(() ->
|
||||
{
|
||||
DeleteBuilder<GuildWarpEntity, Long> delete = warps.deleteBuilder();
|
||||
delete.where().eq("guild_uuid", guildUuid.toString()).and().eq("name", name.toLowerCase(Locale.ROOT));
|
||||
delete.delete();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> createInvite(UUID guildUuid, UUID inviterUuid, UUID inviteeUuid, Instant expiresAt)
|
||||
{
|
||||
return runAsync(() ->
|
||||
{
|
||||
deleteInviteSync(guildUuid, inviteeUuid);
|
||||
GuildInviteEntity invite = new GuildInviteEntity();
|
||||
invite.setGuildUuid(guildUuid.toString());
|
||||
invite.setInviterUuid(inviterUuid.toString());
|
||||
invite.setInviteeUuid(inviteeUuid.toString());
|
||||
invite.setExpiresAt(expiresAt.toEpochMilli());
|
||||
invites.create(invite);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteInvite(UUID guildUuid, UUID inviteeUuid)
|
||||
{
|
||||
return runAsync(() -> deleteInviteSync(guildUuid, inviteeUuid));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<GuildInviteEntity>> invitesFor(UUID inviteeUuid)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
long now = Instant.now().toEpochMilli();
|
||||
return invites.queryForEq("invitee_uuid", inviteeUuid.toString()).stream()
|
||||
.filter(invite -> invite.getExpiresAt() >= now)
|
||||
.toList();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new IllegalStateException("Failed to load guild invites", e);
|
||||
}
|
||||
}, executor);
|
||||
}
|
||||
|
||||
private Guild toGuild(GuildEntity entity)
|
||||
{
|
||||
String timezone = Guilds.get().api().configuration().mainConfig().getString("server.timezone", "Etc/UTC");
|
||||
Guild guild = new Guild(UUID.fromString(entity.getGuildUuid()), ZonedDateTime.ofInstant(Instant.ofEpochMilli(entity.getCreatedAt()), ZoneId.of(timezone)));
|
||||
guild.setName(entity.getName());
|
||||
guild.setOwnerUuid(UUID.fromString(entity.getOwnerUuid()));
|
||||
guild.setPrefix(entity.getPrefix());
|
||||
guild.setMotd(entity.getMotd());
|
||||
guild.setTagEnabled(entity.isTagEnabled());
|
||||
guild.setPublic(entity.isPublicGuild());
|
||||
guild.setHome(toLocation(entity));
|
||||
try
|
||||
{
|
||||
members.queryForEq("guild_uuid", entity.getGuildUuid()).forEach(member -> guild.addMember(toMember(member)));
|
||||
warps.queryForEq("guild_uuid", entity.getGuildUuid()).forEach(warp -> guild.getWarps().put(warp.getName(), toLocation(warp)));
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new IllegalStateException("Failed to load guild relations", e);
|
||||
}
|
||||
return guild;
|
||||
}
|
||||
|
||||
private GuildEntity toEntity(Guild guild)
|
||||
{
|
||||
GuildEntity entity = new GuildEntity();
|
||||
entity.setGuildUuid(guild.getGuildUuid().toString());
|
||||
entity.setName(guild.getName());
|
||||
entity.setOwnerUuid(guild.getOwnerUuid().toString());
|
||||
entity.setCreatedAt(guild.getCreatedAt().toInstant().toEpochMilli());
|
||||
entity.setPrefix(guild.getPrefix());
|
||||
entity.setMotd(guild.getMotd());
|
||||
entity.setTagEnabled(guild.isTagEnabled());
|
||||
entity.setPublicGuild(guild.isPublic());
|
||||
setHome(entity, guild.getHome());
|
||||
return entity;
|
||||
}
|
||||
|
||||
private Member toMember(GuildMemberEntity entity)
|
||||
{
|
||||
return new Member(UUID.fromString(entity.getPlayerUuid()), GuildRole.valueOf(entity.getRole()));
|
||||
}
|
||||
|
||||
private GuildMemberEntity memberEntity(UUID guildUuid, UUID playerUuid, GuildRole role)
|
||||
{
|
||||
GuildMemberEntity entity = new GuildMemberEntity();
|
||||
entity.setGuildUuid(guildUuid.toString());
|
||||
entity.setPlayerUuid(playerUuid.toString());
|
||||
entity.setRole(role.name());
|
||||
entity.setJoinedAt(Instant.now().toEpochMilli());
|
||||
return entity;
|
||||
}
|
||||
|
||||
private void upsertMember(UUID guildUuid, UUID playerUuid, GuildRole role) throws SQLException
|
||||
{
|
||||
GuildMemberEntity entity = members.queryBuilder().where()
|
||||
.eq("guild_uuid", guildUuid.toString()).and().eq("player_uuid", playerUuid.toString())
|
||||
.queryForFirst();
|
||||
if (entity == null)
|
||||
{
|
||||
members.create(memberEntity(guildUuid, playerUuid, role));
|
||||
return;
|
||||
}
|
||||
entity.setRole(role.name());
|
||||
members.update(entity);
|
||||
}
|
||||
|
||||
private void deleteInviteSync(UUID guildUuid, UUID inviteeUuid) throws SQLException
|
||||
{
|
||||
DeleteBuilder<GuildInviteEntity, Long> delete = invites.deleteBuilder();
|
||||
delete.where().eq("guild_uuid", guildUuid.toString()).and().eq("invitee_uuid", inviteeUuid.toString());
|
||||
delete.delete();
|
||||
}
|
||||
|
||||
private <T> void deleteByGuild(Dao<T, Long> dao, UUID guildUuid) throws SQLException
|
||||
{
|
||||
DeleteBuilder<T, Long> delete = dao.deleteBuilder();
|
||||
delete.where().eq("guild_uuid", guildUuid.toString());
|
||||
delete.delete();
|
||||
}
|
||||
|
||||
private void setHome(GuildEntity entity, CustomLocation home)
|
||||
{
|
||||
entity.setHomeWorld(home == null ? null : home.getWorldName());
|
||||
entity.setHomeX(home == null ? null : home.getX());
|
||||
entity.setHomeY(home == null ? null : home.getY());
|
||||
entity.setHomeZ(home == null ? null : home.getZ());
|
||||
entity.setHomeYaw(home == null ? null : home.getYaw());
|
||||
entity.setHomePitch(home == null ? null : home.getPitch());
|
||||
}
|
||||
|
||||
private CustomLocation toLocation(GuildEntity entity)
|
||||
{
|
||||
if (entity.getHomeWorld() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new CustomLocation(entity.getHomeWorld(), entity.getHomeX(), entity.getHomeY(), entity.getHomeZ(), entity.getHomeYaw(), entity.getHomePitch());
|
||||
}
|
||||
|
||||
private void setWarpLocation(GuildWarpEntity entity, CustomLocation location)
|
||||
{
|
||||
entity.setWorld(location.getWorldName());
|
||||
entity.setX(location.getX());
|
||||
entity.setY(location.getY());
|
||||
entity.setZ(location.getZ());
|
||||
entity.setYaw(location.getYaw());
|
||||
entity.setPitch(location.getPitch());
|
||||
}
|
||||
|
||||
private CustomLocation toLocation(GuildWarpEntity entity)
|
||||
{
|
||||
return new CustomLocation(entity.getWorld(), entity.getX(), entity.getY(), entity.getZ(), entity.getYaw(), entity.getPitch());
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> runAsync(SqlRunnable runnable)
|
||||
{
|
||||
return CompletableFuture.runAsync(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
runnable.run();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new IllegalStateException("Guild storage operation failed", e);
|
||||
}
|
||||
}, executor);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface SqlRunnable
|
||||
{
|
||||
void run() throws SQLException;
|
||||
}
|
||||
}
|
||||
@@ -1,55 +1,25 @@
|
||||
package dev.plex.storage.entity;
|
||||
|
||||
import com.j256.ormlite.field.DatabaseField;
|
||||
import com.j256.ormlite.table.DatabaseTable;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@DatabaseTable
|
||||
public class GuildEntity
|
||||
{
|
||||
@DatabaseField(id = true, columnName = "guild_uuid", width = 46)
|
||||
private String guildUuid;
|
||||
|
||||
@DatabaseField(columnName = "name", width = 64, canBeNull = false)
|
||||
private String name;
|
||||
|
||||
@DatabaseField(columnName = "prefix", width = 64)
|
||||
private String prefix;
|
||||
|
||||
@DatabaseField(columnName = "owner_uuid", width = 46, canBeNull = false)
|
||||
private String ownerUuid;
|
||||
|
||||
@DatabaseField(columnName = "created_at")
|
||||
private long createdAt;
|
||||
|
||||
@DatabaseField(columnName = "home_world", width = 128)
|
||||
private String homeWorld;
|
||||
|
||||
@DatabaseField(columnName = "home_x")
|
||||
private Double homeX;
|
||||
|
||||
@DatabaseField(columnName = "home_y")
|
||||
private Double homeY;
|
||||
|
||||
@DatabaseField(columnName = "home_z")
|
||||
private Double homeZ;
|
||||
|
||||
@DatabaseField(columnName = "home_yaw")
|
||||
private Float homeYaw;
|
||||
|
||||
@DatabaseField(columnName = "home_pitch")
|
||||
private Float homePitch;
|
||||
|
||||
@DatabaseField(columnName = "motd", width = 3000)
|
||||
private String motd;
|
||||
|
||||
@DatabaseField(columnName = "tag_enabled")
|
||||
private boolean tagEnabled = true;
|
||||
|
||||
@DatabaseField(columnName = "public")
|
||||
private boolean publicGuild;
|
||||
|
||||
public GuildEntity()
|
||||
|
||||
@@ -1,28 +1,16 @@
|
||||
package dev.plex.storage.entity;
|
||||
|
||||
import com.j256.ormlite.field.DatabaseField;
|
||||
import com.j256.ormlite.table.DatabaseTable;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@DatabaseTable
|
||||
public class GuildInviteEntity
|
||||
{
|
||||
@DatabaseField(generatedId = true, columnName = "id")
|
||||
private long id;
|
||||
|
||||
@DatabaseField(columnName = "guild_uuid", width = 46, canBeNull = false)
|
||||
private String guildUuid;
|
||||
|
||||
@DatabaseField(columnName = "inviter_uuid", width = 46, canBeNull = false)
|
||||
private String inviterUuid;
|
||||
|
||||
@DatabaseField(columnName = "invitee_uuid", width = 46, canBeNull = false)
|
||||
private String inviteeUuid;
|
||||
|
||||
@DatabaseField(columnName = "expires_at")
|
||||
private long expiresAt;
|
||||
|
||||
public GuildInviteEntity()
|
||||
|
||||
@@ -1,28 +1,16 @@
|
||||
package dev.plex.storage.entity;
|
||||
|
||||
import com.j256.ormlite.field.DatabaseField;
|
||||
import com.j256.ormlite.table.DatabaseTable;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@DatabaseTable
|
||||
public class GuildMemberEntity
|
||||
{
|
||||
@DatabaseField(generatedId = true, columnName = "id")
|
||||
private long id;
|
||||
|
||||
@DatabaseField(columnName = "guild_uuid", width = 46, canBeNull = false)
|
||||
private String guildUuid;
|
||||
|
||||
@DatabaseField(columnName = "player_uuid", width = 46, canBeNull = false)
|
||||
private String playerUuid;
|
||||
|
||||
@DatabaseField(columnName = "role", width = 20, canBeNull = false)
|
||||
private String role;
|
||||
|
||||
@DatabaseField(columnName = "joined_at")
|
||||
private long joinedAt;
|
||||
|
||||
public GuildMemberEntity()
|
||||
|
||||
@@ -1,40 +1,20 @@
|
||||
package dev.plex.storage.entity;
|
||||
|
||||
import com.j256.ormlite.field.DatabaseField;
|
||||
import com.j256.ormlite.table.DatabaseTable;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@DatabaseTable
|
||||
public class GuildWarpEntity
|
||||
{
|
||||
@DatabaseField(generatedId = true, columnName = "id")
|
||||
private long id;
|
||||
|
||||
@DatabaseField(columnName = "guild_uuid", width = 46, canBeNull = false)
|
||||
private String guildUuid;
|
||||
|
||||
@DatabaseField(columnName = "name", width = 16, canBeNull = false)
|
||||
private String name;
|
||||
|
||||
@DatabaseField(columnName = "world", width = 128, canBeNull = false)
|
||||
private String world;
|
||||
|
||||
@DatabaseField(columnName = "x")
|
||||
private double x;
|
||||
|
||||
@DatabaseField(columnName = "y")
|
||||
private double y;
|
||||
|
||||
@DatabaseField(columnName = "z")
|
||||
private double z;
|
||||
|
||||
@DatabaseField(columnName = "yaw")
|
||||
private float yaw;
|
||||
|
||||
@DatabaseField(columnName = "pitch")
|
||||
private float pitch;
|
||||
|
||||
public GuildWarpEntity()
|
||||
|
||||
@@ -12,7 +12,7 @@ CREATE TABLE IF NOT EXISTS {{table:guilds}} (
|
||||
`home_pitch` FLOAT,
|
||||
`motd` VARCHAR(3000),
|
||||
`tag_enabled` BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
`public` BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
`is_public` BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY (`guild_uuid`),
|
||||
UNIQUE KEY `uq_guilds_name` (`name`)
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ CREATE TABLE IF NOT EXISTS {{table:guilds}} (
|
||||
home_pitch REAL,
|
||||
motd VARCHAR(3000),
|
||||
tag_enabled BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
public BOOLEAN NOT NULL DEFAULT FALSE
|
||||
is_public BOOLEAN NOT NULL DEFAULT FALSE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS {{table:members}} (
|
||||
|
||||
@@ -12,7 +12,7 @@ CREATE TABLE IF NOT EXISTS {{table:guilds}} (
|
||||
home_pitch FLOAT,
|
||||
motd VARCHAR(3000),
|
||||
tag_enabled BOOLEAN NOT NULL DEFAULT 1,
|
||||
public BOOLEAN NOT NULL DEFAULT 0
|
||||
is_public BOOLEAN NOT NULL DEFAULT 0
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS {{table:members}} (
|
||||
|
||||
Reference in New Issue
Block a user