trim the fat, hostname matching will bee too hard to set up for average user anyway
This commit is contained in:
@@ -5,7 +5,6 @@ public record DiscordInvite(
|
||||
Long guildId,
|
||||
Long expiresAt
|
||||
) {
|
||||
|
||||
public DiscordInvite {
|
||||
if (code == null) {
|
||||
throw new IllegalArgumentException("Code cannot be null");
|
||||
@@ -15,14 +14,4 @@ public record DiscordInvite(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the invite is expired.
|
||||
* The invite is considered expired if the current time is more than 5 seconds before the expiration time.
|
||||
*
|
||||
* @return true if the invite is expired, false otherwise
|
||||
*/
|
||||
public boolean isExpired() {
|
||||
return System.currentTimeMillis() + 5000 > expiresAt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.time.temporal.ChronoUnit;
|
||||
public class DiscordInviteManager {
|
||||
|
||||
private final Cache<String, DiscordInvite> cache = Caffeine.newBuilder()
|
||||
.expireAfterWrite(Duration.of(60, ChronoUnit.SECONDS))
|
||||
.expireAfterWrite(Duration.of(55, ChronoUnit.SECONDS))
|
||||
.build();
|
||||
|
||||
private final JDA jda;
|
||||
@@ -26,7 +26,7 @@ public class DiscordInviteManager {
|
||||
@Nullable
|
||||
public DiscordInvite getInvite(long guildId) {
|
||||
DiscordInvite discordInvite = cache.getIfPresent(String.valueOf(guildId));
|
||||
if (discordInvite == null || discordInvite.isExpired()) {
|
||||
if (discordInvite == null) {
|
||||
Guild guild = jda.getGuildById(guildId);
|
||||
if (guild == null) {
|
||||
return null; // Guild not found
|
||||
@@ -48,4 +48,8 @@ public class DiscordInviteManager {
|
||||
return discordInvite;
|
||||
}
|
||||
|
||||
public void removeFromCache(long guildId) {
|
||||
cache.invalidate(String.valueOf(guildId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package me.youhavetrouble.inviter.discord;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public record GuildSettings(
|
||||
long guildId,
|
||||
boolean apiEnabled,
|
||||
@Nullable String apiHostname
|
||||
boolean apiEnabled
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
@@ -19,14 +19,14 @@ public class ApiStatusChangeCommand extends Command {
|
||||
|
||||
@Nullable
|
||||
public String getName() {
|
||||
return "api";
|
||||
return "invites";
|
||||
}
|
||||
|
||||
public void register(JDA jda, String name) {
|
||||
jda.upsertCommand(Commands.slash("api", "Change if Inviter API should allow to retrieve this server's invites.")
|
||||
jda.upsertCommand(Commands.slash("invites", "Change or see if Inviter should create invites for this guild.")
|
||||
.setIntegrationTypes(IntegrationType.GUILD_INSTALL)
|
||||
.addOptions(
|
||||
new OptionData(OptionType.BOOLEAN, "status", "Status of the api availability for this guild", false)
|
||||
new OptionData(OptionType.BOOLEAN, "status", "Enable or disable Inviter to work for this guild", false)
|
||||
)
|
||||
.setContexts(InteractionContextType.GUILD)
|
||||
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MANAGE_SERVER))
|
||||
@@ -49,8 +49,8 @@ public class ApiStatusChangeCommand extends Command {
|
||||
GuildSettings setings = Main.getStorage().getGuildSettings(guild.getIdLong());
|
||||
|
||||
String message = setings.apiEnabled() ?
|
||||
"Inviter API is currently __**enabled**__ for this server." :
|
||||
"Inviter API is currently __**disabled**__ for this server.";
|
||||
"Inviter is currently __**enabled**__ for this server." :
|
||||
"Inviter is currently __**disabled**__ for this server.";
|
||||
|
||||
event.getHook().editOriginal(message).queue();
|
||||
return;
|
||||
@@ -59,8 +59,8 @@ public class ApiStatusChangeCommand extends Command {
|
||||
boolean status = statusMapping.getAsBoolean();
|
||||
long guildId = guild.getIdLong();
|
||||
|
||||
Main.getStorage().updateDiscordApiEnabled(guildId, status);
|
||||
String message = status ? "Inviter API is now __**enabled**__ for this server." : "Inviter API is now __**disabled**__ for this server.";
|
||||
Main.getStorage().updateInvitesEnabled(guildId, status);
|
||||
String message = status ? "Inviter is now __**enabled**__ for this server." : "Inviter API is now __**disabled**__ for this server.";
|
||||
event.getHook().editOriginal(message).queue();
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -19,9 +19,9 @@ public class GuildJoinAndLeaveListener extends ListenerAdapter {
|
||||
|
||||
@Override
|
||||
public void onGuildLeave(@NotNull GuildLeaveEvent event) {
|
||||
Storage storage = Main.getStorage();
|
||||
long guildId = event.getGuild().getIdLong();
|
||||
storage.removeGuildSettings(guildId);
|
||||
Main.getDiscordInviteMenager().removeFromCache(guildId);
|
||||
Main.getStorage().removeGuildSettings(guildId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package me.youhavetrouble.inviter.dns;
|
||||
|
||||
import me.youhavetrouble.inviter.Main;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.naming.directory.Attribute;
|
||||
import javax.naming.directory.Attributes;
|
||||
import javax.naming.directory.DirContext;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Set;
|
||||
|
||||
public class DNSLookup {
|
||||
|
||||
public static Set<String> getTxtRecords(@NotNull String hostname) throws Exception {
|
||||
Hashtable<String, String> env = new Hashtable<>();
|
||||
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
|
||||
env.put("java.naming.provider.url", "dns://1.1.1.1");
|
||||
env.put("com.sun.jndi.dns.cache.ttl", "0");
|
||||
Set<String> txtRecords = new HashSet<>();
|
||||
|
||||
DirContext ctx = new InitialDirContext(env);
|
||||
Attributes attrs = ctx.getAttributes(hostname, new String[]{"TXT"});
|
||||
Attribute txtAttr = attrs.get("TXT");
|
||||
|
||||
if (txtAttr != null) {
|
||||
for (int i = 0; i < txtAttr.size(); i++) {
|
||||
Object record = txtAttr.get(i);
|
||||
if (record instanceof String recordString) {
|
||||
txtRecords.add(recordString);
|
||||
} else if (record instanceof byte[]) {
|
||||
txtRecords.add(new String((byte[]) record));
|
||||
} else {
|
||||
txtRecords.add(record.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return txtRecords;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -11,7 +11,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
public class GetDiscordInviteByGuildId implements EndpointHandler {
|
||||
|
||||
private final Pattern pathPattern = Pattern.compile("^/api/v1/discord/\\d{10,18}$");
|
||||
private final Pattern pathPattern = Pattern.compile("^/invite/\\d{10,18}$");
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
package me.youhavetrouble.inviter.http.endpoints;
|
||||
|
||||
import com.sun.net.httpserver.HttpExchange;
|
||||
import me.youhavetrouble.inviter.Main;
|
||||
import me.youhavetrouble.inviter.discord.DiscordInvite;
|
||||
import me.youhavetrouble.inviter.discord.DiscordInviteManager;
|
||||
import me.youhavetrouble.inviter.discord.GuildSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class MainEndpoint implements EndpointHandler {
|
||||
|
||||
private final Pattern pathPattern = Pattern.compile("^/$");
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Pattern pathPattern() {
|
||||
return pathPattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(@NotNull HttpExchange exchange) throws IOException {
|
||||
if (!exchange.getRequestMethod().equals("GET")) {
|
||||
exchange.sendResponseHeaders(405, -1); // Method Not Allowed
|
||||
return;
|
||||
}
|
||||
|
||||
String host = exchange.getRemoteAddress().getHostName();
|
||||
|
||||
GuildSettings guildSettings = Main.getStorage().getGuildSettings(host);
|
||||
if (guildSettings == null) {
|
||||
exchange.sendResponseHeaders(404, -1); // Not Found
|
||||
return;
|
||||
}
|
||||
|
||||
DiscordInviteManager inviteManager = Main.getDiscordInviteMenager();
|
||||
DiscordInvite invite = inviteManager.getInvite(guildSettings.guildId());
|
||||
|
||||
if (invite == null) {
|
||||
exchange.sendResponseHeaders(404, -1); // Not Found
|
||||
return;
|
||||
}
|
||||
|
||||
exchange.getResponseHeaders().set("Location", "https://discord.gg/" + invite.code());
|
||||
exchange.sendResponseHeaders(307, -1);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import me.youhavetrouble.inviter.discord.GuildSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.File;
|
||||
@@ -12,7 +11,6 @@ import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
public class SqliteStorage implements Storage {
|
||||
|
||||
@@ -39,18 +37,10 @@ public class SqliteStorage implements Storage {
|
||||
connection.createStatement().execute("""
|
||||
CREATE TABLE IF NOT EXISTS guild_settings (
|
||||
guild_id LONG PRIMARY KEY,
|
||||
api_enabled BOOLEAN NOT NULL DEFAULT FALSE
|
||||
invites_enabled BOOLEAN NOT NULL DEFAULT FALSE
|
||||
);
|
||||
"""
|
||||
);
|
||||
connection.createStatement().execute("""
|
||||
CREATE TABLE IF NOT EXISTS hostnames (
|
||||
hostname VARCHAR(256) PRIMARY KEY,
|
||||
guild_id LONG NOT NULL,
|
||||
failed_checks INTEGER NOT NULL DEFAULT 0,
|
||||
FOREIGN KEY (guild_id) REFERENCES guild_settings(guild_id) ON DELETE CASCADE
|
||||
)
|
||||
""");
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("Failed to initialize database", e);
|
||||
}
|
||||
@@ -69,39 +59,16 @@ public class SqliteStorage implements Storage {
|
||||
ResultSet resultSet = statement.executeQuery();
|
||||
|
||||
if (resultSet.next()) {
|
||||
boolean apiEnabled = resultSet.getBoolean("api_enabled");
|
||||
String apiHostname = resultSet.getString("hostname");
|
||||
return new GuildSettings(guildId, apiEnabled, apiHostname);
|
||||
boolean invitesEnabled = resultSet.getBoolean("invites_enabled");
|
||||
return new GuildSettings(guildId, invitesEnabled);
|
||||
}
|
||||
return new GuildSettings(guildId,false, null);
|
||||
return new GuildSettings(guildId,false);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("Failed to retrieve guild settings", e);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public GuildSettings getGuildSettings(@NotNull String hostname) {
|
||||
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
PreparedStatement statement = connection.prepareStatement(
|
||||
"SELECT * FROM guild_settings WHERE hostname = ?"
|
||||
);
|
||||
statement.setString(1, hostname);
|
||||
ResultSet resultSet = statement.executeQuery();
|
||||
|
||||
if (resultSet.next()) {
|
||||
long guildId = resultSet.getLong("guild_id");
|
||||
boolean apiEnabled = resultSet.getBoolean("api_enabled");
|
||||
return new GuildSettings(guildId, apiEnabled, hostname);
|
||||
}
|
||||
return null; // No settings found for the given hostname
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("Failed to retrieve guild settings by hostname", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveDefaultGuildSettings(long guildId) {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
@@ -129,10 +96,10 @@ public class SqliteStorage implements Storage {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDiscordApiEnabled(long guildId, boolean enabled) {
|
||||
public void updateInvitesEnabled(long guildId, boolean enabled) {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
PreparedStatement statement = connection.prepareStatement(
|
||||
"UPDATE guild_settings SET api_enabled = ? WHERE guild_id = ?"
|
||||
"UPDATE guild_settings SET invites_enabled = ? WHERE guild_id = ?"
|
||||
);
|
||||
statement.setBoolean(1, enabled);
|
||||
statement.setLong(2, guildId);
|
||||
@@ -143,63 +110,4 @@ public class SqliteStorage implements Storage {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHostname(long guildId, @Nullable String hostname) {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
PreparedStatement statement = connection.prepareStatement(
|
||||
"INSERT OR IGNORE INTO hostnames (hostname, guild_id) VALUES (?, ?)"
|
||||
);
|
||||
statement.setString(1, hostname);
|
||||
statement.setLong(2, guildId);
|
||||
statement.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("Failed to add hostname", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeHostname(@NotNull String hostname) {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
PreparedStatement statement = connection.prepareStatement(
|
||||
"DELETE FROM hostnames WHERE hostname = ?"
|
||||
);
|
||||
statement.setString(1, hostname);
|
||||
statement.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("Failed to remove hostname", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listHostnames(long guildId) {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
PreparedStatement statement = connection.prepareStatement(
|
||||
"SELECT hostname FROM hostnames WHERE guild_id = ?"
|
||||
);
|
||||
statement.setLong(1, guildId);
|
||||
ResultSet resultSet = statement.executeQuery();
|
||||
|
||||
List<String> hostnames = new java.util.ArrayList<>();
|
||||
while (resultSet.next()) {
|
||||
hostnames.add(resultSet.getString("hostname"));
|
||||
}
|
||||
return hostnames;
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("Failed to list hostnames", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUpHostnames() {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
PreparedStatement statement = connection.prepareStatement(
|
||||
"DELETE FROM hostnames WHERE failed_checks >= 3"
|
||||
);
|
||||
statement.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("Failed to clean up hostnames", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,28 +3,15 @@ package me.youhavetrouble.inviter.storage;
|
||||
|
||||
import me.youhavetrouble.inviter.discord.GuildSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface Storage {
|
||||
|
||||
@NotNull GuildSettings getGuildSettings(long guildId);
|
||||
|
||||
@Nullable GuildSettings getGuildSettings(@NotNull String hostname);
|
||||
|
||||
void saveDefaultGuildSettings(long guildId);
|
||||
|
||||
void removeGuildSettings(long guildId);
|
||||
|
||||
void updateDiscordApiEnabled(long guildId, boolean enabled);
|
||||
|
||||
void addHostname(long guildId, @Nullable String hostname);
|
||||
|
||||
void removeHostname(@NotNull String hostname);
|
||||
|
||||
List<String> listHostnames(long guildId);
|
||||
|
||||
void cleanUpHostnames();
|
||||
void updateInvitesEnabled(long guildId, boolean enabled);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user