Skip to content

Commit

Permalink
Various
Browse files Browse the repository at this point in the history
Wiki settings page.
Add description to all guild setting requirements
work on optimizing conflict loading
Add conflict purge commands for both deleted and user generated conflicts
  • Loading branch information
xdnw committed May 16, 2024
1 parent 1213ac8 commit a558a9d
Show file tree
Hide file tree
Showing 17 changed files with 329 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
import link.locutus.discord.apiv1.enums.SuccessType;
import link.locutus.discord.apiv3.enums.AttackTypeSubCategory;
import link.locutus.discord.config.Settings;
import link.locutus.discord.db.entities.DBNation;
import link.locutus.discord.db.entities.DBWar;
import link.locutus.discord.util.PW;
import link.locutus.discord.util.update.WarUpdateProcessor;

import java.util.Collections;
import java.util.List;
import java.util.function.BiFunction;

public interface IAttack {
/*
Expand Down Expand Up @@ -171,7 +173,7 @@ default AbstractCursor getPriorAttack(boolean onlySameAttacker, boolean load) {

DBWar getWar();

default AttackTypeSubCategory getSubCategory(boolean checkActive) {
return WarUpdateProcessor.subCategorize(this, checkActive);
default AttackTypeSubCategory getSubCategory(BiFunction<DBNation, Long, Integer> checkActiveM) {
return WarUpdateProcessor.subCategorize(this, checkActiveM);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,6 @@ public static String getSlashCommand(String path, Map<String, String> arguments,
StringBuilder builder = new StringBuilder();
builder.append("/").append(path.toLowerCase(Locale.ROOT));
if (!arguments.isEmpty()) {
// join on " "
for (Map.Entry<String, String> entry : arguments.entrySet()) {
if (entry.getValue() == null) continue;
builder.append(" ").append(entry.getKey().toLowerCase(Locale.ROOT)).append(": ").append(entry.getValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ public CommandManager2 registerDefaults() {
getCommands().registerMethod(new VirtualConflictCommands(), List.of("conflict"), "createTemporary", "create_temp");
getCommands().registerMethod(new ConflictCommands(), List.of("conflict"), "deleteConflict", "delete");
getCommands().registerMethod(new ConflictCommands(), List.of("conflict"), "addConflict", "create");
getCommands().registerMethod(new ConflictCommands(), List.of("conflict", "purge"), "purgeFeatured", "featured");
getCommands().registerMethod(new ConflictCommands(), List.of("conflict", "purge"), "purgeTemporaryConflicts", "user_generated");

getCommands().registerMethod(new ConflictCommands(), List.of("conflict", "edit"), "setConflictEnd", "end");
getCommands().registerMethod(new ConflictCommands(), List.of("conflict", "edit"), "setConflictStart", "start");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package link.locutus.discord.commands.manager.v2.impl.pw.commands;

import com.amazonaws.services.s3.model.S3ObjectSummary;
import link.locutus.discord.commands.manager.v2.binding.annotation.*;
import link.locutus.discord.commands.manager.v2.binding.annotation.Timestamp;
import link.locutus.discord.commands.manager.v2.command.IMessageBuilder;
Expand Down Expand Up @@ -781,6 +782,7 @@ public String removeFeature(ConflictManager manager, @Me GuildDB db, @Default Se

@Command(desc = "List the ruleset for which conflicts are featured by this guild (if any are set)\n" +
"This consists of a list of either guilds that created the conflict, or individual conflicts")
@CoalitionPermission(Coalition.MANAGE_CONFLICTS)
public String listFeaturedRuleset(ConflictManager manager, @Me GuildDB db) {
List<Long> config = manager.getSourceSets().get(db.getIdLong());
if (config == null || config.isEmpty()) {
Expand All @@ -803,4 +805,96 @@ public String listFeaturedRuleset(ConflictManager manager, @Me GuildDB db) {
}
return "Featured conflicts:\n" + StringMan.join(items, "\n");
}

@Command(desc = "Purge permenent conflicts that aren't in the database")
@RolePermission(Roles.MILCOM)
@CoalitionPermission(Coalition.MANAGE_CONFLICTS)
public String purgeFeatured(ConflictManager manager, @Me IMessageIO io, @Me JSONObject command, @Default @Timestamp Long olderThan, @Switch("f") boolean force) {
Set<String> deleted = new LinkedHashSet<>();
Set<String> kept = new LinkedHashSet<>();
for (S3ObjectSummary object : manager.getAws().getObjects()) {
Date date = object.getLastModified();
if (olderThan != null && olderThan < date.getTime()) {
continue;
}
String key = object.getKey();
boolean matches = key.matches("conflict/graphs/[0-9]+\\.gzip") || key.matches("conflict/[0-9]+\\.gzip");
if (!matches) continue;
int id = Integer.parseInt(key.replaceAll("[^0-9]", ""));
Conflict conflict = manager.getConflictById(id);
if (conflict == null) {
deleted.add(id + "");
if (force) {
manager.getAws().deleteObject(key);
}
} else {
kept.add(id + "");
}
}
if (deleted.isEmpty()) {
if (kept.isEmpty()) {
return "No featured conflicts found on the website matching the database";
} else {
return "No featured conflicts found on the website missing from the database\n" +
"Kept: " + StringMan.join(kept, ", ");
}
}
if (force) {
return "**Deleted:**\n- " + StringMan.join(deleted, "\n- ") + "\n" +
"**Kept:**\n- " + StringMan.join(kept, "\n- ");
} else {
StringBuilder body = new StringBuilder();
body.append("Deleted " + deleted.size() + " conflicts\n");
body.append("Kept: " + kept.size() + "/" + manager.getConflictMap().size() + "\n");
io.create().confirmation("Deleted " + deleted.size() + " conflicts", body.toString(), command)
.file("deleted.txt", StringMan.join(deleted, "\n"))
.send();
return null;
}
}

@Command(desc = "Purge permenent conflicts that aren't in the database")
@RolePermission(Roles.MILCOM)
@CoalitionPermission(Coalition.MANAGE_CONFLICTS)
public String purgeTemporaryConflicts(ConflictManager manager, @Me IMessageIO io, @Me JSONObject command, @Timestamp long olderThan, @Switch("f") boolean force) {
List<String> deleted = new ArrayList<>();
List<String> kept = new ArrayList<>();
for (S3ObjectSummary object : manager.getAws().getObjects()) {
String key = object.getKey();
boolean matches = key.matches("conflicts/n/[0-9]+/[a-z0-9]+\\.gzip") || key.matches("conflicts/graphs/n/[0-9]+/[a-z0-9]+\\.gzip");
if (!matches) continue;
int nationId = Integer.parseInt(key.replaceAll("[^0-9]", ""));
String uuidStr = key.substring(key.lastIndexOf("/") + 1, key.lastIndexOf("."));
String nameStr = PW.getMarkdownUrl(nationId, false) + "/" + uuidStr;
Date date = object.getLastModified();
if (olderThan < date.getTime()) {
kept.add(nameStr);
continue;
}
deleted.add(nameStr);
if (force) {
manager.getAws().deleteObject(key);
}
}
if (deleted.isEmpty()) {
if (kept.isEmpty()) {
return "No featured conflicts found on the website matching the database";
} else {
return "No featured conflicts found on the website missing from the database\n" +
"Kept: " + StringMan.join(kept, ", ");
}
}
if (force) {
return "**Deleted:**\n- " + StringMan.join(deleted, "\n- ") + "\n" +
"**Kept:**\n- " + StringMan.join(kept, "\n- ");
} else {
StringBuilder body = new StringBuilder();
body.append("Deleted " + deleted.size() + " conflicts\n");
body.append("Kept: " + kept.size() + "/" + manager.getConflictMap().size() + "\n");
io.create().confirmation("Deleted " + deleted.size() + " conflicts", body.toString(), command)
.file("deleted.txt", StringMan.join(deleted, "\n"))
.send();
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2375,7 +2375,7 @@ public void attackBreakdownSheet(@Me IMessageIO io, @Me GuildDB db, Set<NationOr
for (AbstractCursor attack : allAttacks) {
if (!isAttacker.test(attack)) continue;
attacksByNation.merge(attack.getAttacker_id(), 1, Integer::sum);
AttackTypeSubCategory subType = attack.getSubCategory(true);
AttackTypeSubCategory subType = attack.getSubCategory(DBNation::getActive_m);
if (subType == null) continue;
if (allowedTypes[subType.ordinal()]) {
countsByNation.computeIfAbsent(attack.getAttacker_id(), f -> new EnumMap<>(AttackTypeSubCategory.class)).merge(subType, 1, Integer::sum);
Expand Down
30 changes: 25 additions & 5 deletions src/main/java/link/locutus/discord/db/NationDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@
import com.ptsmods.mysqlw.table.TablePreset;
import it.unimi.dsi.fastutil.bytes.ByteArrayList;
import it.unimi.dsi.fastutil.ints.*;
import it.unimi.dsi.fastutil.longs.Long2DoubleLinkedOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2IntLinkedOpenHashMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectArrayMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.longs.*;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectArraySet;
Expand Down Expand Up @@ -3690,6 +3686,30 @@ public Set<Long> getActivityByDay(int nationId, long minTurn) {
return result;
}

public Map<Integer, Set<Long>> getActivityByDay(long minDate, long maxDate) {
// dates are inclusive
long minTurn = TimeUtil.getTurn(minDate);
long maxTurn = TimeUtil.getTurn(maxDate);
try (PreparedStatement stmt = prepareQuery("select nation, (`turn`/12) FROM ACTIVITY WHERE turn >= ? AND turn <= ?")) {
stmt.setLong(1, minTurn);
stmt.setLong(2, maxTurn);

Map<Integer, Set<Long>> result = new Int2ObjectOpenHashMap<>();

try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
int id = rs.getInt(1);
long day = rs.getLong(2);
result.computeIfAbsent(id, f -> new LongOpenHashSet()).add(day);
}
}
return result;
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}

public Map<Long, Set<Integer>> getActivityByDay(long minDate, Predicate<Integer> allowNation) {
long minTurn = TimeUtil.getTurn(minDate);
try (PreparedStatement stmt = prepareQuery("select nation, (`turn`/12) FROM ACTIVITY WHERE turn > ?")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -313,7 +314,7 @@ public void updateWar(DBWar previous, DBWar current, boolean isAttacker) {
}
}

public void updateAttack(DBWar war, AbstractCursor attack, boolean isAttacker, boolean checkActivity) {
public void updateAttack(DBWar war, AbstractCursor attack, boolean isAttacker, BiFunction<DBNation, Long, Integer> checkActivity) {
AttackTypeSubCategory subCategory = attack.getSubCategory(checkActivity);
int attackerAA, attackerId, cities;
long day = TimeUtil.getDay(attack.getDate());
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/link/locutus/discord/db/conflict/Conflict.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -501,7 +502,7 @@ public boolean updateWar(DBWar previous, DBWar current, long turn) {
return true;
}

public void updateAttack(DBWar war, AbstractCursor attack, long turn, boolean checkActivity) {
public void updateAttack(DBWar war, AbstractCursor attack, long turn, BiFunction<DBNation, Long, Integer> checkActivity) {
int attackerAA, defenderAA;
if (attack.getAttacker_id() == war.getAttacker_id()) {
attackerAA = war.getAttacker_aa();
Expand Down
38 changes: 28 additions & 10 deletions src/main/java/link/locutus/discord/db/conflict/ConflictManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import link.locutus.discord.config.Settings;
import link.locutus.discord.db.WarDB;
import link.locutus.discord.db.entities.DBAlliance;
import link.locutus.discord.db.entities.DBNation;
import link.locutus.discord.db.entities.DBTopic;
import link.locutus.discord.db.entities.DBWar;
import link.locutus.discord.db.entities.conflict.ConflictCategory;
Expand Down Expand Up @@ -51,6 +52,7 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
Expand Down Expand Up @@ -228,14 +230,14 @@ public void onAttack(AttackEvent event) {
AbstractCursor attack = event.getAttack();
DBWar war = attack.getWar();
if (war != null) {
updateAttack(war, attack, f -> true);
updateAttack(war, attack, f -> true, DBNation::getActive_m);
}
}

public void updateAttack(DBWar war, AbstractCursor attack, Predicate<Integer> allowed) {
public void updateAttack(DBWar war, AbstractCursor attack, Predicate<Integer> allowed, BiFunction<DBNation, Long, Integer> checkActivity) {
long turn = TimeUtil.getTurn(war.getDate());
if (turn > lastTurn) initTurn();
applyConflicts(allowed, turn, war.getAttacker_aa(), war.getDefender_aa(), f -> f.updateAttack(war, attack, turn, true));
applyConflicts(allowed, turn, war.getAttacker_aa(), war.getDefender_aa(), f -> f.updateAttack(war, attack, turn, checkActivity));
}

@Subscribe
Expand Down Expand Up @@ -432,7 +434,7 @@ public void loadVirtualConflict(Conflict conflict, boolean clearBeforeUpdate) {
db.iterateWarAttacks(wars, f -> true, f -> true, (war, attack) -> {
long turn = TimeUtil.getTurn(attack.getDate());
if (TimeUtil.getTurn(war.getDate()) <= turn) {
conflict.updateAttack(war, attack, turn, false);
conflict.updateAttack(war, attack, turn, null);
}
});
}
Expand Down Expand Up @@ -491,12 +493,28 @@ public void loadConflictWars(Collection<Conflict> conflicts, boolean clearBefore
}

System.out.println("Loaded wars in " + ((-start) + (start = System.currentTimeMillis()) + "ms"));

db.iterateWarAttacks(wars, f -> true, f -> true, (war, attack) -> {
if (TimeUtil.getTurn(war.getDate()) <= TimeUtil.getTurn(attack.getDate())) {
updateAttack(war, attack, allowedConflicts);
}
});
if (!wars.isEmpty()) {
Map<Integer, Set<Long>> activity = Locutus.imp().getNationDB().getActivityByDay(startMs - TimeUnit.DAYS.toMillis(10), endMs);
System.out.println("Loaded activity in " + ((-start) + (start = System.currentTimeMillis()) + "ms"));
db.iterateWarAttacks(wars, f -> true, f -> true, (war, attack) -> {
if (TimeUtil.getTurn(war.getDate()) <= TimeUtil.getTurn(attack.getDate())) {
updateAttack(war, attack, allowedConflicts, new BiFunction<DBNation, Long, Integer>() {
@Override
public Integer apply(DBNation nation, Long dateMs) {
Set<Long> natAct = activity.get(nation.getId());
if (natAct == null) return Integer.MAX_VALUE;
long currDay = TimeUtil.getDay(dateMs);
for (long day = currDay; day >= currDay - 10; day--) {
if (natAct.contains(day)) {
return Math.toIntExact(TimeUnit.DAYS.toMinutes((int) (currDay - day)));
}
}
return Integer.MAX_VALUE;
}
});
}
});
}

if (conflicts == null || conflicts.stream().anyMatch(f -> f.getId() != -1)) {
db.query("SELECT * FROM conflict_graphs2", stmt -> {
Expand Down
32 changes: 16 additions & 16 deletions src/main/java/link/locutus/discord/db/entities/DBWar.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class DBWar {
private byte warStatusType;
private final long date;
private char attDefCities;
private byte attDefActiveFlag;
// private byte attDefActiveFlag;

public int getTurnsLeft() {
return (int) (TimeUtil.getTurn() - TimeUtil.getTurn(getDate()) + 60);
Expand All @@ -50,21 +50,21 @@ public DBWar(int warId, int attacker_id, int defender_id, int attacker_aa, int d
this.attDefCities = (char) (attCities | (defCities << 8));
}

public boolean isAttActive() {
return (attDefActiveFlag & 0x01) == 1;
}

public boolean isDefActive() {
return (attDefActiveFlag & 0x02) == 2;
}

public void setAttActive(boolean value) {
attDefActiveFlag = (byte) (value ? attDefActiveFlag | 0x01 : attDefActiveFlag & 0xFE);
}

public void setDefActive(boolean value) {
attDefActiveFlag = (byte) (value ? attDefActiveFlag | 0x02 : attDefActiveFlag & 0xFD);
}
// public boolean isAttActive() {
// return (attDefActiveFlag & 0x01) == 1;
// }
//
// public boolean isDefActive() {
// return (attDefActiveFlag & 0x02) == 2;
// }
//
// public void setAttActive(boolean value) {
// attDefActiveFlag = (byte) (value ? attDefActiveFlag | 0x01 : attDefActiveFlag & 0xFE);
// }
//
// public void setDefActive(boolean value) {
// attDefActiveFlag = (byte) (value ? attDefActiveFlag | 0x02 : attDefActiveFlag & 0xFD);
// }

public int getAttCities() {
return attDefCities & 0xFF;
Expand Down
Loading

0 comments on commit a558a9d

Please sign in to comment.