Skip to content

Commit

Permalink
Add inactivity_streak
Browse files Browse the repository at this point in the history
  • Loading branch information
xdnw committed Jul 26, 2024
1 parent c1461c4 commit 7671602
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ public CommandManager2 registerDefaults() {
getCommands().registerMethod(new AdminCommands(), List.of("admin", "unset"), "unsetNews", "settings");
getCommands().registerMethod(new AdminCommands(), List.of("admin", "unset"), "unsetKeys", "news");
getCommands().registerMethod(new WarCommands(), List.of("alerts", "beige"), "testBeigeAlertAuto", "test_auto");
getCommands().registerMethod(new UtilityCommands(), List.of("nation"), "vmHistory", "vm_history");
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("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 @@ -2223,6 +2223,91 @@ public String unitCost(Map<MilitaryUnit, Long> units,
return response.toString();
}

// Helper function to check and update inactivity streaks
private void checkAndUpdateStreak(Map<Integer, Long> lastActive, Map<Integer, Long> lastNotGray, Map<Integer, Long> lastStreak, Map<Integer, Integer> countMap, int nationId, long day, int daysInactive) {
long lastActiveDay = lastActive.getOrDefault(nationId, day);
long lastNotGrayDay = lastNotGray.getOrDefault(nationId, day);
long lastActiveAdded = lastStreak.getOrDefault(nationId, 0L);
if (lastActiveAdded == lastActiveDay) return;

if (day - lastNotGrayDay >= daysInactive) {
countMap.put(nationId, countMap.getOrDefault(nationId, 0) + 1);
lastStreak.put(nationId, lastActiveAdded);
}
}

@Command(desc = "Get the inactivity streak of a set of nations over a specified timeframe")
public String grayStreak(@Me GuildDB db, @Me IMessageIO io,
Set<DBNation> nations,
int daysInactive,
@Timestamp long timeframe,
@Switch("s") SpreadSheet sheet) throws IOException, ParseException, GeneralSecurityException {
long minNationAge = Long.MAX_VALUE;
for (DBNation nation : nations) {
minNationAge = Math.min(minNationAge, nation.getDate());
}
minNationAge = Math.max(minNationAge, timeframe);
Set<Integer> nationIds = new IntOpenHashSet(nations.stream().map(DBNation::getNation_id).collect(Collectors.toSet()));

DataDumpParser parser = Locutus.imp().getDataDumper(true);
List<Long> validDays = parser.getDays(true, false);
long today = TimeUtil.getDay();
long finalMinDay = TimeUtil.getDay(minNationAge);

Map<Integer, Long> lastActive = new Int2LongOpenHashMap();
Map<Integer, Long> lastNotGray = new Int2LongOpenHashMap();
Map<Integer, Long> lastStreak = new Int2ObjectOpenHashMap<>();
Map<Integer, Integer> countMap = new Int2ObjectOpenHashMap<>();

parser.iterateAll(f -> f >= finalMinDay, (h, r) -> r.required(h.nation_id).optional(h.vm_turns).required(h.color), null, new BiConsumer<Long, NationHeader>() {
@Override
public void accept(Long day, NationHeader header) {
int nationId = header.nation_id.get();
if (!nationIds.contains(nationId)) return;

NationColor color = header.color.get();
if (color != NationColor.GRAY) {
lastNotGray.put(nationId, day);
if (color != NationColor.BEIGE) {
lastActive.put(nationId, day);
}
checkAndUpdateStreak(lastActive, lastNotGray, lastStreak, countMap, nationId, day, daysInactive);
}
}
}, null, new Consumer<Long>() {
@Override
public void accept(Long day) {
// Called when all nations have been processed for a day
}
});
for (int nationId : nationIds) {
checkAndUpdateStreak(lastActive, lastNotGray, lastStreak, countMap, nationId, today, daysInactive);
}

if (sheet == null) {
sheet = SpreadSheet.create(db, SheetKey.INACTIVITY_STREAK);
}

List<String> header = new ArrayList<>(Arrays.asList("nation", "alliance", "streak"));
sheet.setHeader(header);
for (DBNation nation : nations) {
int nationId = nation.getNation_id();
int streak = countMap.getOrDefault(nationId, 0);
if (streak > 0) {
ArrayList<Object> row = new ArrayList<>();
row.add(MarkupUtil.sheetUrl(nation.getNation(), nation.getUrl()));
row.add(MarkupUtil.sheetUrl(nation.getAllianceName(), nation.getAllianceUrl()));
row.add(streak);
sheet.addRow(row);
}
}
sheet.updateClearCurrentTab();
sheet.updateWrite();
sheet.attach(io.create(), "inactivity").send();
return null;
}


@Command(desc = "Get the VM history of a set of nations")
public static String vmHistory(@Me IMessageIO io, Set<DBNation> nations, @Switch("s") SpreadSheet sheet) throws IOException, ParseException {
if (nations.size() > 1000) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6464,18 +6464,6 @@ public unitHistory page(String value) {
return set("page", value);
}

}
@AutoRegister(clazz=link.locutus.discord.commands.manager.v2.impl.pw.commands.UtilityCommands.class,method="vmHistory")
public static class vm_history extends CommandRef {
public static final vm_history cmd = new vm_history();
public vm_history nations(String value) {
return set("nations", value);
}

public vm_history sheet(String value) {
return set("sheet", value);
}

}
@AutoRegister(clazz=link.locutus.discord.commands.manager.v2.impl.pw.commands.WarCommands.class,method="wars")
public static class wars extends CommandRef {
Expand Down
20 changes: 20 additions & 0 deletions src/main/java/link/locutus/discord/db/entities/DBNation.java
Original file line number Diff line number Diff line change
Expand Up @@ -1854,6 +1854,26 @@ public long daysSinceConsecutiveLogins(long checkPastXDays, int sequentialDays)
return Long.MAX_VALUE;
}

@Command(desc = "Number of times since this nation's creation that they have been inactive for a specified number of days")
public int inactivity_streak(int daysInactive, long checkPastXDays) {
long turns = checkPastXDays * 12 + 11;
List<Long> logins = new ArrayList<>(Locutus.imp().getNationDB().getActivityByDay(nation_id, TimeUtil.getTurn(getSnapshot()) - turns));
Collections.reverse(logins);

int inactivityCount = 0;
long last = 0;

for (long day : logins) {
long diff = last - day;
if (diff > daysInactive) {
inactivityCount++;
}
last = day;
}

return inactivityCount;
}

@Command(desc = "Days since last bank deposit")
public double daysSinceLastBankDeposit() {
return (System.currentTimeMillis() - lastBankDeposit()) / (double) TimeUnit.DAYS.toMillis(1);
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/link/locutus/discord/db/guild/GuildSetting.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import link.locutus.discord.commands.manager.v2.binding.LocalValueStore;
import link.locutus.discord.commands.manager.v2.binding.Parser;
import link.locutus.discord.commands.manager.v2.binding.ValueStore;
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.command.ParameterData;
import link.locutus.discord.commands.manager.v2.command.ParametricCallable;
Expand All @@ -23,6 +24,7 @@
import link.locutus.discord.util.discord.DiscordUtil;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.channel.Channel;
import net.dv8tion.jda.api.entities.channel.ChannelType;
import net.dv8tion.jda.api.entities.channel.concrete.Category;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
Expand Down Expand Up @@ -516,6 +518,7 @@ public String getRaw(GuildDB db, boolean allowDelegate) {
return db.getInfoRaw(this, allowDelegate);
}

@Command(desc = "The setting category")
public GuildSettingCategory getCategory() {
return category;
}
Expand Down Expand Up @@ -564,4 +567,32 @@ public GuildSetting<T> requiresAllies() {
}, msg);
return this;
}

@Command(desc = "Is this a channel setting")
public boolean isChannelType() {
return Channel.class.isAssignableFrom((Class) getType().getType());
}

@Command(desc = "The simple name of the setting class type")
public String getTypeName() {
return getType().getType().getTypeName();
}

@Command(desc = "The name of the setting type key")
public String getKeyName() {
return getType().toSimpleString();
}

@Command(desc = "The name of the setting")
public String getName() {
return name;
}

@Command
public String getValueString(@Me GuildDB db) {
T value = getOrNull(db);
if (value == null) return null;
return toReadableString(db, value);
}

}
1 change: 1 addition & 0 deletions src/main/java/link/locutus/discord/db/guild/SheetKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public enum SheetKey {
MERGES_SHEET,
MILITARY_RANKING,
FORUM_PROFILES,
INACTIVITY_STREAK,


}

0 comments on commit 7671602

Please sign in to comment.