Skip to content

Commit

Permalink
placeholders
Browse files Browse the repository at this point in the history
  • Loading branch information
xdnw committed Jul 28, 2024
1 parent 7671602 commit ddf9b1f
Show file tree
Hide file tree
Showing 11 changed files with 248 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,11 @@ public static Map<ResourceType, Double> parseResources(String arg, boolean allow
if (MathMan.isInteger(arg)) {
throw new IllegalArgumentException("Please use `$" + arg + "` or `money=" + arg + "` for money, not `" + arg + "`");
}
if (arg.contains(" AM ") || arg.contains(" PM ")) {
arg = arg.replaceAll("([0-9]{1,2}:[0-9]{2})[ ](AM|PM)", "")
.replace("\n", " ")
.replaceAll("[ ]+", " ");
}
if (arg.contains("---+") && arg.contains("-+-")) {
arg = arg.replace("-+-", "---");
int start = arg.indexOf("---+");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.json.JSONObject;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -689,7 +690,16 @@ private IllegalArgumentException throwUnknownCommand(String command) {
}
Placeholders<T> placeholders = this;
if (previousFunc != null) {
placeholders = Locutus.cmd().getV2().getPlaceholders().get((Class) previousFunc.getType());
Type type = previousFunc.getType();
if (type instanceof Class) {
placeholders = Locutus.cmd().getV2().getPlaceholders().get((Class) type);
} else {
TypedFunction<T, ?> result = handleParameterized(store, functionName, argumentString, previousFunc, depth, throwError);
if (result != null) {
previousFunc = result;
continue;
}
}
if (placeholders == null) {
throw new IllegalArgumentException("Cannot call `" + arg + "` on function: `" + previousFunc.getName() + "` as return type is not public: `" + ((Class<?>) previousFunc.getType()).getSimpleName() + "`");
}
Expand Down Expand Up @@ -730,6 +740,34 @@ private IllegalArgumentException throwUnknownCommand(String command) {
return previousFunc;
}

private TypedFunction<T, ?> handleParameterized(ValueStore store, String functionName, String argumentString, TypedFunction<T, ?> previousFunc, int depth, boolean throwError) {
if (argumentString != null && !argumentString.isEmpty()) return null;
Type type = previousFunc.getType();
if (!(type instanceof ParameterizedType pt)) return null;
Type rawType = pt.getRawType();
if (!(rawType instanceof Class rawClass)) return null;
// if (Map.class.isAssignableFrom(rawClass)) {
if (!rawClass.isAssignableFrom(Map.class)) return null;
Type[] args = pt.getActualTypeArguments();
Type keyType = args[0];
Type valueType = args[1];
if (!(keyType instanceof Class keyClass && keyClass.isEnum())) return null;
// get enum options
Enum<?>[] enumConstants = (Enum<?>[]) keyClass.getEnumConstants();
// if any enum constant equals ignore case
for (Enum<?> enumConstant : enumConstants) {
if (enumConstant.name().equalsIgnoreCase(functionName)) {
Function<T, Object> getValue = f -> {
Object key = enumConstant;
Map<T, ?> map = (Map<T, ?>) previousFunc.applyCached(f);
return map.get(key);
};
return TypedFunction.createParent(valueType, getValue, functionName, previousFunc);
}
}
return null;
}

private TypedFunction<T, ?> format(ValueStore store, ParametricCallable command, Map<String, TypedFunction<T, ?>> arguments) {
Map<String, Object> resolvedArgs = new Object2ObjectLinkedOpenHashMap<>();
Map<T, Map<String, Object>> resolvedByEntity = new Object2ObjectLinkedOpenHashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,11 +238,13 @@ public static Map<String, String> parseArguments(Set<String> params, String inpu

public CommandManager2 registerDefaults() {
// this.commands.registerMethod(new TestCommands(), List.of("test"), "test", "test");
getCommands().registerMethod(new AdminCommands(), List.of("admin", "unset"), "unsetNews", "settings");
getCommands().registerMethod(new AdminCommands(), List.of("admin", "unset"), "unsetKeys", "news");
getCommands().registerMethod(new AdminCommands(), List.of("admin", "settings"), "unsetNews", "subscribe");
getCommands().registerMethod(new AdminCommands(), List.of("admin", "settings"), "unsetKeys", "unset");
getCommands().registerMethod(new AdminCommands(), List.of("admin", "settings"), "infoBulk", "info_servers");

getCommands().registerMethod(new WarCommands(), List.of("alerts", "beige"), "testBeigeAlertAuto", "test_auto");
getCommands().registerMethod(new UtilityCommands(), List.of("nation", "history"), "vmHistory", "vm");
getCommands().registerMethod(new UtilityCommands(), List.of("nation", "history"), "gray_streak", "gray_streak");
getCommands().registerMethod(new UtilityCommands(), List.of("nation", "history"), "grayStreak", "gray_streak");
getCommands().registerMethod(new UtilityCommands(), List.of("tax"), "setBracketBulk", "set_from_sheet");
getCommands().registerMethod(new StatCommands(), List.of("stats_other", "global_metrics"), "orbisStatByDay", "by_time");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import link.locutus.discord.db.entities.newsletter.NewsletterManager;
import link.locutus.discord.db.guild.GuildSetting;
import link.locutus.discord.db.guild.GuildKey;
import link.locutus.discord.db.guild.GuildSettingCategory;
import link.locutus.discord.event.mail.MailReceivedEvent;
import link.locutus.discord.pnw.AllianceList;
import link.locutus.discord.pnw.BeigeReason;
Expand Down Expand Up @@ -229,6 +230,11 @@ public DBLoan.Status LoanStatus(String input) {
return emum(DBLoan.Status.class, input);
}

@Binding(value = "The guild setting category")
public GuildSettingCategory GuildSettingCategory(String input) {
return emum(GuildSettingCategory.class, input);
}

@Binding(value = "The success type of an attack")
public SuccessType SuccessType(String input) {
return emum(SuccessType.class, input);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.entities.channel.unions.DefaultGuildChannelUnion;
import net.dv8tion.jda.api.exceptions.InsufficientPermissionException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
Expand All @@ -104,6 +105,7 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -410,6 +412,7 @@ public String unsetKeys(@Me IMessageIO io, @Me JSONObject command,
@Switch("g") boolean unset_invalid_aa,
@Switch("a") boolean unset_all,
@Switch("v") boolean unset_validate,
@Switch("m") String unsetMessage,
@Switch("f") boolean force) {
Map<Guild, Map<GuildSetting, Set<String>>> unsetReasons = new LinkedHashMap<>();

Expand All @@ -424,6 +427,29 @@ public String unsetKeys(@Me IMessageIO io, @Me JSONObject command,
}
}
for (GuildDB otherDb : guilds) {
Map<GuildSetting, Boolean> isUnset = new LinkedHashMap<>();
BiConsumer<GuildSetting, String> unset = (setting, reason) -> {
if (force) {
if (isUnset.getOrDefault(setting, false)) return;
isUnset.put(setting, true);
String previousValue = setting.getRaw(otherDb, false);
Object value = setting.getOrNull(otherDb, false);

otherDb.deleteInfo(setting);

String message = reason + ": " + (unsetMessage == null ? "" : unsetMessage) + "\nPrevious value: `" + previousValue + "`";
TextChannel sendTo = null;
if (value instanceof TextChannel tc && tc.canTalk()) sendTo = tc;
if (sendTo == null) sendTo = otherDb.getNotifcationChannel();
if (sendTo != null) {
try {
RateLimitUtil.queue(sendTo.sendMessage(message));
} catch (Exception ignore) {
}
}
}
};

Guild otherGuild = otherDb.getGuild();
Map<GuildSetting, Set<String>> byGuild = unsetReasons.computeIfAbsent(otherGuild, k -> new LinkedHashMap<>());
// only channel modes
Expand All @@ -432,7 +458,7 @@ public String unsetKeys(@Me IMessageIO io, @Me JSONObject command,
if (channel == null) continue;
if (unset_cant_talk) {
if (!channel.canTalk()) {
if (force) otherDb.deleteInfo(setting);
if (force) unset.accept(setting, "No Talk Permissions in " + channel.getAsMention());
byGuild.computeIfAbsent(setting, k -> new LinkedHashSet<>()).add("Can't talk");
continue;
}
Expand All @@ -449,7 +475,7 @@ public String unsetKeys(@Me IMessageIO io, @Me JSONObject command,
Object value = setting.getOrNull(otherDb);
if (unset_null) {
if (value == null) {
if (force) otherDb.deleteInfo(setting);
if (force) unset.accept(setting, "Invalid value (null)");
byGuild.computeIfAbsent(setting, k -> new LinkedHashSet<>()).add("Null");
continue;
}
Expand All @@ -463,13 +489,13 @@ public String unsetKeys(@Me IMessageIO io, @Me JSONObject command,
notAllowedReason = e.getMessage();
}
if (!allowed) {
if (force) otherDb.deleteInfo(setting);
if (force) unset.accept(setting, notAllowedReason);
byGuild.computeIfAbsent(setting, k -> new LinkedHashSet<>()).add(notAllowedReason);
continue;
}
}
if (unset_validate) {
String validateReason = "Invalid";
String validateReason = "Invalid Value (validation error)";
boolean valid = false;
try {
setting.validate(otherDb, null, value);
Expand All @@ -478,21 +504,23 @@ public String unsetKeys(@Me IMessageIO io, @Me JSONObject command,
validateReason = e.getMessage();
}
if (!valid) {
if (force) otherDb.deleteInfo(setting);
if (force) unset.accept(setting, validateReason);
byGuild.computeIfAbsent(setting, k -> new LinkedHashSet<>()).add(validateReason);
continue;
}

}
if (unset_invalid_aa) {
if (!otherDb.isValidAlliance()) {
if (force) otherDb.deleteInfo(setting);
// if (force) otherDb.deleteInfo(setting);
if (force) unset.accept(setting, "No valid Alliance registered");
byGuild.computeIfAbsent(setting, k -> new LinkedHashSet<>()).add("Invalid AA");
continue;
}
}
if (unset_all) {
if (force) otherDb.deleteInfo(setting);
// if (force) otherDb.deleteInfo(setting);
if (force) unset.accept(setting, "Setting removed by administrator.");
byGuild.computeIfAbsent(setting, k -> new LinkedHashSet<>()).add("All");
}
}
Expand Down Expand Up @@ -527,7 +555,75 @@ public String unsetKeys(@Me IMessageIO io, @Me JSONObject command,
return null;
}

// todo unset invalid
@Command
@RolePermission(value = Roles.ADMIN, root = true)
public String infoBulk(@Me GuildDB db, @Me IMessageIO io, GuildSetting setting, Set<GuildDB> guilds, @Switch("s") SpreadSheet sheet) throws GeneralSecurityException, IOException {
if (sheet == null) {
sheet = SpreadSheet.create(db, SheetKey.SETTINGS_SERVERS);
}

// admin bulk_setting key
//- include alliances registered column (alliance ids)
//- have column for coalitions guild is in
//- have column for isValidAlliance
//- have column for number of active members 7200 in the alliance

List<String> header = new ArrayList<>(Arrays.asList(
"guild",
"guild_id",
"owner",
"owner_id",
"setting",
"raw",
"readable",
"is_invalid",
"lack_perms",
"root_col",
"alliances",
"aa_valid",
"active_aa_members"
));

sheet.setHeader(header);

GuildDB root = Locutus.imp().getRootDb();


for (GuildDB otherDb : guilds) {
String raw = setting.getRaw(otherDb, false);
if (raw == null) continue;
Object value = setting.getOrNull(otherDb, false);
String readable = value == null ? "![NULL]" : setting.toReadableString(db, value);
boolean noPerms = !setting.allowed(db);

header.set(0, otherDb.getGuild().getName());
header.set(1, otherDb.getIdLong() + "");
long ownerId = otherDb.getGuild().getOwnerIdLong();
header.set(2, DiscordUtil.getUserName(ownerId));
header.set(3, ownerId + "");
header.set(4, setting.name());
header.set(5, raw);
header.set(6, readable);
header.set(7, value == null ? "true" : "false");
header.set(8, noPerms ? "true" : "false");
Set<Coalition> hasOnRoot = Arrays.stream(Coalition.values()).filter(otherDb::hasCoalitionPermsOnRoot).collect(Collectors.toSet());
header.set(9, hasOnRoot.stream().map(Coalition::name).collect(Collectors.joining(",")));
Set<Integer> aaIds = otherDb.getAllianceIds();
header.set(10, aaIds == null ? "" : aaIds.toString());
header.set(11, otherDb.isValidAlliance() ? "true" : "false");
AllianceList aaList = otherDb.getAllianceList();
int activeMembers = aaList == null ? -1 : aaList.getNations(true, 7200, true).size();
header.set(12, activeMembers + "");

sheet.addRow(header);
}

sheet.updateClearCurrentTab();
sheet.updateWrite();

sheet.attach(io.create(), "setting_servers").send();
return null;
}

@Command
@RolePermission(value = Roles.ADMIN, root = true)
Expand Down
23 changes: 22 additions & 1 deletion src/main/java/link/locutus/discord/db/GuildDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
import link.locutus.discord.apiv1.enums.AccessType;
import link.locutus.discord.apiv1.enums.DepositType;
import link.locutus.discord.apiv3.enums.AlliancePermission;
import link.locutus.discord.commands.manager.v2.binding.annotation.Command;
import link.locutus.discord.commands.manager.v2.binding.annotation.Me;
import link.locutus.discord.commands.manager.v2.impl.discord.permission.RolePermission;
import link.locutus.discord.commands.manager.v2.impl.pw.refs.CM;
import link.locutus.discord.commands.manager.v2.impl.pw.NationFilter;
import link.locutus.discord.commands.war.WarCategory;
import link.locutus.discord.commands.manager.Command;
import link.locutus.discord.commands.manager.v2.impl.pw.TaxRate;
import link.locutus.discord.commands.rankings.builder.RankBuilder;
import link.locutus.discord.config.Settings;
Expand Down Expand Up @@ -58,6 +59,7 @@
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.entities.channel.concrete.Category;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.entities.channel.unions.DefaultGuildChannelUnion;
Expand Down Expand Up @@ -3159,4 +3161,23 @@ public Role getRole(Roles role, Long allianceOrNull) {
}
return null;
}

///

@Command
public TextChannel getNotifcationChannel() {
TextChannel sendTo = guild.getSystemChannel();
if (sendTo != null && !sendTo.canTalk()) sendTo = null;
if (sendTo == null) sendTo = guild.getCommunityUpdatesChannel();
if (sendTo != null && !sendTo.canTalk()) sendTo = null;
if (sendTo == null) sendTo = guild.getRulesChannel();
if (sendTo != null && !sendTo.canTalk()) sendTo = null;
if (sendTo == null) {
DefaultGuildChannelUnion df = guild.getDefaultChannel();
if (df != null && df instanceof TextChannel tc && tc.canTalk()) {
sendTo = tc;
}
}
return sendTo;
}
}
17 changes: 17 additions & 0 deletions src/main/java/link/locutus/discord/db/NationDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -2704,6 +2704,23 @@ public synchronized void createTreasuresDB(Collection<DBTreasure> treasures) {
}
}

public int countTreasures(int allianceId) {
synchronized (nationsByAlliance) {
Map<Integer, DBNation> nations = nationsByAlliance.get(allianceId);
if (nations == null || nations.isEmpty()) return 0;
int count = 0;
for (DBNation nation : nations.values()) {
if (nation.getPositionEnum().id <= Rank.APPLICANT.id || nation.getVm_turns() == 0) continue;
synchronized (treasuresByNation) {
Set<DBTreasure> treasures = treasuresByNation.get(nation.getId());
if (treasures == null) continue;
count += treasures.size();
}
}
return count;
}
}

public Set<DBTreasure> getTreasure(int nationId) {
synchronized (treasuresByNation) {
Set<DBTreasure> treasures = treasuresByNation.get(nationId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,8 @@ public DBAlliance(DBAlliance other) {

@Command(desc = "Number of treasures in the alliance")
public int getNumTreasures() {
int num = 0;
for (DBNation nation : getNations()) {
if (nation.getVm_turns() == 0) {
num += nation.getTreasures().size();
}
}
return num;
if (allianceId == 0) return 0;
return Locutus.imp().getNationDB().countTreasures(allianceId);
}

@Command(desc = "Treasure bonus (decimal percent between 0-1)")
Expand Down
Loading

0 comments on commit ddf9b1f

Please sign in to comment.