Skip to content

Commit

Permalink
Merge branch 'master' of /~https://github.com/xdnw/locutus
Browse files Browse the repository at this point in the history
  • Loading branch information
xdnw committed Jan 10, 2024
2 parents ca55b27 + ba28f09 commit 6ea7676
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import net.dv8tion.jda.api.entities.channel.attribute.ICategorizableChannel;
import net.dv8tion.jda.api.entities.channel.attribute.IMemberContainer;
import net.dv8tion.jda.api.entities.channel.concrete.Category;
import net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel;
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;
Expand Down Expand Up @@ -1409,7 +1410,13 @@ public String mailCommandOutput(NationPlaceholders placeholders, ValueStore stor
"Other bulk mail commands forward to this command")
@HasApi
@RolePermission(Roles.ADMIN)
public String mailSheet(@Me GuildDB db, @Me JSONObject command, @Me IMessageIO io, @Me User author, SpreadSheet sheet, @Switch("f") boolean confirm) {
public String mailSheet(@Me GuildDB db, @Me JSONObject command, @Me IMessageIO io, @Me User author, SpreadSheet sheet, @Switch("f") boolean force, @Switch("d") boolean dm, @Switch("m") boolean skipMail) {
if (skipMail && !dm) {
throw new IllegalArgumentException("Must specify `dm` if `skipMail` is true");
}
if (dm && !Roles.MAIL.hasOnRoot(author)) {
throw new IllegalArgumentException("Missing role: " + Roles.MAIL.toDiscordRoleNameElseInstructions(Locutus.imp().getServer()));
}
List<List<Object>> data = sheet.fetchAll(null);

List<Object> nationNames = sheet.findColumn(0, "nation", "id");
Expand Down Expand Up @@ -1461,7 +1468,7 @@ public String mailSheet(@Me GuildDB db, @Me JSONObject command, @Me IMessageIO i
return "Max allowed: 1000 messages.";
}

if (!confirm) {
if (!force) {
String title = "Send " + messageMap.size() + " to nations in " + alliances.size() + " alliances";
StringBuilder body = new StringBuilder("Messages:");
IMessageBuilder msg = io.create();
Expand All @@ -1473,7 +1480,7 @@ public String mailSheet(@Me GuildDB db, @Me JSONObject command, @Me IMessageIO i
if (applicants > 0) body.append("applicant receivers: " + applicants + "\n");

body.append("\nPress to confirm");
msg.confirmation(title, body.toString(), command, "confirm").send();
msg.confirmation(title, body.toString(), command, "force").send();
return null;
}

Expand All @@ -1489,19 +1496,35 @@ public String mailSheet(@Me GuildDB db, @Me JSONObject command, @Me IMessageIO i
String subject = msgEntry.getKey();
String body = msgEntry.getValue();

String result;
try {
JsonObject json = nation.sendMail(keys, subject, body, false);
result = json + "";
} catch (IOException e) {
errors++;
if (errors > 50) {
throw new IllegalArgumentException(">50 Errors. Aborting at `" + nation.getNation() + "`");
List<String> result = new ArrayList<>();
if (!skipMail) {
try {
JsonObject json = nation.sendMail(keys, subject, body, false);
result.add(json + "");
} catch (IOException e) {
errors++;
if (errors > 50) {
throw new IllegalArgumentException(">50 Errors. Aborting at `" + nation.getNation() + "`");
}
e.printStackTrace();
result.add("IOException: " + e.getMessage());
}
}
if (dm) {
User user = nation.getUser();
if (user == null) {
result.add("\n- **dm**: No discord user set. See " + CM.register.cmd.toSlashMention());
} else {
try {
PrivateChannel channel = RateLimitUtil.complete(user.openPrivateChannel());
RateLimitUtil.queue(channel.sendMessage(body.toString()));
result.add("\n- **dm**: Sent dm");
} catch (Throwable e) {
result.add("\n- **dm**: Failed to send dm (`" + e.getMessage() + "`)");
}
}
e.printStackTrace();
result = "IOException: " + e.getMessage();
}
response.add(nation.getNationUrl() + " -> " + result);
response.add(nation.getNationUrl() + " -> " + StringMan.getString(result));
}
return "Done!\n- " + StringMan.join(response, "\n- ");
}
Expand Down
1 change: 0 additions & 1 deletion src/main/java/link/locutus/discord/db/NationDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -2268,7 +2268,6 @@ public void createTables() {

executeStmt("CREATE TABLE IF NOT EXISTS ALLIANCE_METRICS (alliance_id INT NOT NULL, metric INT NOT NULL, turn BIGINT NOT NULL, value DOUBLE NOT NULL, PRIMARY KEY(alliance_id, metric, turn))");
executeStmt("CREATE TABLE IF NOT EXISTS RADIATION_BY_TURN (continent INT NOT NULL, radiation INT NOT NULL, turn BIGINT NOT NULL, PRIMARY KEY(continent, turn))");

executeStmt("CREATE TABLE IF NOT EXISTS NATION_DESCRIPTIONS (id INT NOT NULL PRIMARY KEY, description TEXT NOT NULL)");

// executeStmt("DROP TABLE IF EXISTS TREASURES4"); // Remove after restart
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ public void run() {
NationPlaceholders ph = Locutus.imp().getCommandManager().getV2().getNationPlaceholders();
String subjectFormat = ph.format2(db.getGuild(), null, null, subject, nation, false);
String bodyFormat = ph.format2(db.getGuild(), null, null, body, nation, false);
String message = getTitle();
String message = getTitle() + "\n- To: " + nation.getMarkdownUrl();
if (sendEnabled) {
JsonObject result = nation.sendMail(mailKey, subjectFormat, bodyFormat, false);
message += "\n" + result.toString();
} else {
message += "\n- Sending disabled. Use TODO CM REF";
message += "\n- Sending disabled. `/admin queue custom_messages setmeta:True sendmessages:True run:true`";
}
RateLimitUtil.queue(output.sendMessage(message));
} catch (IOException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ public Double apply(DBAlliance alliance) {
int currentCity = nation.getCities();
int previousCities = nation.getCitiesSince(ms);
if (currentCity > previousCities) {
total += PnwUtil.cityCost(nation, previousCities, currentCity);
total += PnwUtil.cityCost(nation, currentCity - previousCities, currentCity);
}
}
return total;
Expand Down Expand Up @@ -686,15 +686,15 @@ public void consume(Long day, DataDumpParser.CityHeader cityHeader, ParsedRow pa
Integer allianceId = allianceByNationId.get(nationId);
if (allianceId == null || allianceId == 0) return;
long dayJoinedAlliance = nationJoinDay.get(nationId);
long joinedAllianceMs = TimeUtil.getTimeFromDay(dayJoinedAlliance);

long joinedAllianceMs = TimeUtil.getTimeFromDay(Math.max(dayJoinedAlliance, day - 10));
String dateStr = parsedRow.get(cityHeader.date_created, String::toString);
try {
Date date = TimeUtil.YYYY_MM_DD_FORMAT.parse(dateStr);
long createdMs = date.getTime();
if (createdMs < joinedAllianceMs) return;
} catch (ParseException e) {
throw new RuntimeException(e);
} catch (ParseException| ArrayIndexOutOfBoundsException e) {
System.out.println("Invalid date: " + dateStr);
return;
}
citiesBuyByNation.merge(nationId, 1, Integer::sum);
}
Expand Down Expand Up @@ -779,15 +779,15 @@ public void consume(Long day, DataDumpParser.CityHeader cityHeader, ParsedRow pa
Integer allianceId = allianceByNationId.get(nationId);
if (allianceId == null || allianceId == 0) return;
long dayJoinedAlliance = nationJoinDay.get(nationId);
long joinedAllianceMs = TimeUtil.getTimeFromDay(dayJoinedAlliance);

long joinedAllianceMs = TimeUtil.getTimeFromDay(Math.max(dayJoinedAlliance, day - 10));
String dateStr = parsedRow.get(cityHeader.date_created, String::toString);
try {
Date date = TimeUtil.YYYY_MM_DD_FORMAT.parse(dateStr);
long createdMs = date.getTime();
if (createdMs < joinedAllianceMs) return;
} catch (ParseException e) {
throw new RuntimeException(e);
} catch (ParseException | ArrayIndexOutOfBoundsException e) {
System.out.println("Invalid date: " + dateStr);
return;
}
cities10D.merge(allianceId, 1, Integer::sum);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.common.eventbus.Subscribe;
import it.unimi.dsi.fastutil.longs.LongArraySet;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import link.locutus.discord.Locutus;
import link.locutus.discord.apiv1.core.ApiKeyPool;
import link.locutus.discord.apiv1.enums.Rank;
Expand Down Expand Up @@ -43,9 +44,8 @@ public class GuildCustomMessageHandler implements Runnable {
public GuildCustomMessageHandler() {
// get the scheduler
// schedule this to run every 5 minutes
this.sendEnabled = false;
this.updateMeta = false;

this.sendEnabled = true;
this.updateMeta = true;
}

public void init() {
Expand All @@ -66,7 +66,7 @@ public void init() {
private void updateMessages() {
Map<Long, List<CustomConditionMessage>> newMessagesByGuild = new ConcurrentHashMap<>();
for (GuildDB db : Locutus.imp().getGuildDatabases().values()) {
List<CustomConditionMessage> messages = GuildKey.TIMED_MESSAGES.getOrNull(db);
List<CustomConditionMessage> messages = GuildKey.TIMED_MESSAGES.getOrNull(db, false);
if (messages == null || messages.isEmpty()) continue;
// ensure output channel is set
MessageChannel output = GuildKey.RECRUIT_MESSAGE_OUTPUT.getOrNull(db);
Expand Down Expand Up @@ -100,6 +100,7 @@ private void updateMessages() {
// sort messages by delay desc
messages.sort(Comparator.comparingLong(CustomConditionMessage::getDelay).reversed());
newMessagesByGuild.put(db.getIdLong(), messages);
System.out.println("Messages " + messages.size() + " " + db.getGuild());
}
messagesByGuild = newMessagesByGuild;
}
Expand Down Expand Up @@ -210,24 +211,37 @@ public Map<MessageTrigger, List<Map.Entry<GuildDB, CustomConditionMessage>>> get
}

public List<Map.Entry<GuildDB, CustomConditionMessage>> getMessagesBetween(List<Map.Entry<GuildDB, CustomConditionMessage>> messages, long min, long max) {
int start = ArrayUtil.binarySearchGreater(messages, o -> o.getValue().getDelay() >= min);
if (start == -1) {
return Collections.emptyList();
}
if (max == Long.MAX_VALUE) {
return messages.subList(start, messages.size());
}
int end = ArrayUtil.binarySearchGreater(messages, o -> o.getValue().getDelay() <= max, start, messages.size());
if (end == -1) {
return messages.subList(start, messages.size());
List<Map.Entry<GuildDB, CustomConditionMessage>> result = new ObjectArrayList<>();
for (Map.Entry<GuildDB, CustomConditionMessage> message : messages) {
long delay = message.getValue().getDelay();
if (delay >= min && delay <= max) {
result.add(message);
}
}
return messages.subList(start, end);
return result;

// return messages.stream().filter(f -> f.getValue().getDelay() >= min && f.getValue().getDelay() <= max).toList();
// int start = ArrayUtil.binarySearchGreater(messages, o -> o.getValue().getDelay() >= min);
// if (start == -1) {
// return Collections.emptyList();
// }
// if (max == Long.MAX_VALUE) {
// return new ObjectArrayList<>(messages.subList(start, messages.size()));
// }
// int end = ArrayUtil.binarySearchGreater(messages, o -> o.getValue().getDelay() <= max, start, messages.size());
// if (end == -1) {
// return new ObjectArrayList<>(messages.subList(start, messages.size()));
// }
// return new ObjectArrayList<>(messages.subList(start, end));
}

@Override
public void run() {
// Check it is NOT near turn change
if (TimeUtil.checkTurnChange()) return;
if (!TimeUtil.checkTurnChange()) {
System.out.println("Turn change");
return;
}
updateMessages();
// creation messages
long now = System.currentTimeMillis();
Expand All @@ -240,15 +254,18 @@ public void run() {

List<DBNation> nationsNone = new ArrayList<>(Locutus.imp().getNationDB().getNationsMatching(f -> f.getAlliance_id() == 0 && f.active_m() < 1440 && f.getVm_turns() == 0));

List<DBNation> nationsCreated = nationsNone.stream().filter(f -> f.getDate() < createCutoff).toList();
List<DBNation> nationsCreated = nationsNone.stream().filter(f -> f.getDate() > createCutoff).toList();

System.out.println("Creation = " + nationsCreated.size());
for (DBNation nation : nationsCreated) {
long date = nation.getDate();
long ageMs = now - date;

// get the messages which are below ageMs but above the lastSent
List<Map.Entry<GuildDB, CustomConditionMessage>> messages = getMessagesBetween(creation, 0, ageMs);
messages.removeIf(f -> f.getValue().getOriginDate() > date || Math.abs(date - ageMs) > TimeUnit.DAYS.toMillis(7));
System.out.println("Messages 1 = " + messages.size());
messages.removeIf(f -> f.getValue().getOriginDate() > date || Math.abs(ageMs - f.getValue().getDelay()) > TimeUnit.DAYS.toMillis(7));
System.out.println("Messages 2 = " + messages.size());
if (!messages.isEmpty()) {
Set<Long> guildsSent = new LongArraySet();
for (Map.Entry<GuildDB, CustomConditionMessage> entry : messages) {
Expand All @@ -259,8 +276,12 @@ public void run() {

long lastMs = getMeta(nation, db, NationMeta.LAST_SENT_CREATION, -1L);
long lastAge = Math.max(lastMs - date + 1, 0);
if (lastAge > message.getDelay()) continue;
if (lastAge > message.getDelay()) {
System.out.println("Last sent > delay");
continue;
}

System.out.println("Send 1");
message.send(db, nation, sendEnabled);
} finally {
if (updateMeta) {
Expand All @@ -274,7 +295,7 @@ public void run() {
List<DBNation> nationsLeave = nationsNone.stream().filter(f -> {
Long leftDate = allianceLeave.get(f.getId());
if (leftDate == null) return false;
if (leftDate < now - TimeUnit.DAYS.toMillis(30)) {
if (leftDate > now - TimeUnit.DAYS.toMillis(30)) {
if (f.getDate() == 0 || f.getAgeDays() <= 3) return false;
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,7 @@ public List<List<Object>> fetchAll(String tab) {
if (values == null) {
return Collections.emptyList();
}
valuesByTab.put(tab.toLowerCase(Locale.ROOT), values);
return values;
} catch (IOException e) {
throw new RuntimeException(e);
Expand Down

0 comments on commit 6ea7676

Please sign in to comment.