Adds island history for team members adding and removing

Adds placeholder for the historical number of players
This commit is contained in:
tastybento 2024-11-11 12:45:16 -08:00
parent d339edfe21
commit b135484f3c
11 changed files with 83 additions and 13 deletions

View File

@ -15,6 +15,7 @@ import world.bentobox.bentobox.api.commands.ConfirmableCommand;
import world.bentobox.bentobox.api.events.island.IslandEvent; import world.bentobox.bentobox.api.events.island.IslandEvent;
import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.logs.LogEntry; import world.bentobox.bentobox.api.logs.LogEntry;
import world.bentobox.bentobox.api.logs.LogEntry.LogType;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.managers.RanksManager;
@ -115,10 +116,10 @@ public class AdminUnregisterCommand extends ConfirmableCommand {
// Remove all island players that reference this island // Remove all island players that reference this island
targetIsland.getMembers().clear(); targetIsland.getMembers().clear();
if (user.isPlayer()) { if (user.isPlayer()) {
targetIsland.log(new LogEntry.Builder("UNREGISTER").data("player", targetUUID.toString()) targetIsland.log(new LogEntry.Builder(LogType.UNREGISTER).data("player", targetUUID.toString())
.data("admin", user.getUniqueId().toString()).build()); .data("admin", user.getUniqueId().toString()).build());
} else { } else {
targetIsland.log(new LogEntry.Builder("UNREGISTER").data("player", targetUUID.toString()) targetIsland.log(new LogEntry.Builder(LogType.UNREGISTER).data("player", targetUUID.toString())
.data("admin", "console").build()); .data("admin", "console").build());
} }
user.sendMessage("commands.admin.unregister.unregistered-island", TextVariables.XYZ, Util.xyz(targetIsland.getCenter().toVector()), user.sendMessage("commands.admin.unregister.unregistered-island", TextVariables.XYZ, Util.xyz(targetIsland.getCenter().toVector()),

View File

@ -9,6 +9,8 @@ import world.bentobox.bentobox.api.events.IslandBaseEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent; import world.bentobox.bentobox.api.events.island.IslandEvent;
import world.bentobox.bentobox.api.events.team.TeamEvent; import world.bentobox.bentobox.api.events.team.TeamEvent;
import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.logs.LogEntry;
import world.bentobox.bentobox.api.logs.LogEntry.LogType;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.database.objects.TeamInvite; import world.bentobox.bentobox.database.objects.TeamInvite;
@ -120,6 +122,9 @@ public class IslandTeamInviteAcceptCommand extends ConfirmableCommand {
user.sendMessage("commands.island.team.trust.you-are-trusted", TextVariables.NAME, inviter.getName(), user.sendMessage("commands.island.team.trust.you-are-trusted", TextVariables.NAME, inviter.getName(),
TextVariables.DISPLAY_NAME, inviter.getDisplayName()); TextVariables.DISPLAY_NAME, inviter.getDisplayName());
} }
// Add historu record
island.log(new LogEntry.Builder(LogType.TRUSTED).data(user.getUniqueId().toString(), "trusted")
.data(invite.getInviter().toString(), "trusted by").build());
} }
} }

View File

@ -12,6 +12,8 @@ import world.bentobox.bentobox.api.events.IslandBaseEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent; import world.bentobox.bentobox.api.events.island.IslandEvent;
import world.bentobox.bentobox.api.events.team.TeamEvent; import world.bentobox.bentobox.api.events.team.TeamEvent;
import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.logs.LogEntry;
import world.bentobox.bentobox.api.logs.LogEntry.LogType;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.managers.RanksManager;
@ -91,6 +93,9 @@ public class IslandTeamSetownerCommand extends CompositeCommand {
IslandEvent.builder().island(island).involvedPlayer(user.getUniqueId()).admin(false) IslandEvent.builder().island(island).involvedPlayer(user.getUniqueId()).admin(false)
.reason(IslandEvent.Reason.RANK_CHANGE).rankChange(RanksManager.OWNER_RANK, RanksManager.SUB_OWNER_RANK) .reason(IslandEvent.Reason.RANK_CHANGE).rankChange(RanksManager.OWNER_RANK, RanksManager.SUB_OWNER_RANK)
.build(); .build();
// Add historu record
island.log(new LogEntry.Builder(LogType.NEWOWNER).data(targetUUID2.toString(), "new owner")
.data(user.getUniqueId().toString(), "old owner").build());
return true; return true;
} }

View File

@ -9,6 +9,8 @@ import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.logs.LogEntry;
import world.bentobox.bentobox.api.logs.LogEntry.LogType;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.database.objects.TeamInvite.Type; import world.bentobox.bentobox.database.objects.TeamInvite.Type;
@ -110,6 +112,10 @@ public class IslandTeamTrustCommand extends CompositeCommand {
island.setRank(target, RanksManager.TRUSTED_RANK); island.setRank(target, RanksManager.TRUSTED_RANK);
user.sendMessage("commands.island.team.trust.success", TextVariables.NAME, target.getName(), TextVariables.DISPLAY_NAME, target.getDisplayName()); user.sendMessage("commands.island.team.trust.success", TextVariables.NAME, target.getName(), TextVariables.DISPLAY_NAME, target.getDisplayName());
target.sendMessage("commands.island.team.trust.you-are-trusted", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName()); target.sendMessage("commands.island.team.trust.you-are-trusted", TextVariables.NAME, user.getName(), TextVariables.DISPLAY_NAME, user.getDisplayName());
// Add historu record
island.log(new LogEntry.Builder(LogType.TRUSTED).data(targetUUID.toString(), "trusted")
.data(user.getUniqueId().toString(), "trusted by").build());
} }
return true; return true;
} else { } else {

View File

@ -15,16 +15,21 @@ import com.google.gson.annotations.Expose;
* An {@link world.bentobox.bentobox.database.objects.adapters.AdapterInterface AdapterInterface} is provided to be able to save/retrieve * An {@link world.bentobox.bentobox.database.objects.adapters.AdapterInterface AdapterInterface} is provided to be able to save/retrieve
* a list of instances of this object to/from the database: {@link world.bentobox.bentobox.database.objects.adapters.LogEntryListAdapter LogEntryListAdapter}. * a list of instances of this object to/from the database: {@link world.bentobox.bentobox.database.objects.adapters.LogEntryListAdapter LogEntryListAdapter}.
* *
* @author Poslovitch * @author Poslovitch, tastybento
*
*/ */
public class LogEntry { public class LogEntry {
@Expose @Expose
private final long timestamp; private final long timestamp;
@Expose @Expose
private final String type; private final LogType type;
@Expose @Expose
private final Map<String, String> data; private final Map<String, String> data;
public enum LogType {
REMOVE, ADD, UNREGISTER, BAN, UNOWNED, SPAWN, UNBAN, JOINED, NEWOWNER, TRUSTED, UNKNOWN
}
private LogEntry(@NonNull Builder builder) { private LogEntry(@NonNull Builder builder) {
this.timestamp = builder.timestamp; this.timestamp = builder.timestamp;
this.type = builder.type; this.type = builder.type;
@ -36,7 +41,7 @@ public class LogEntry {
} }
@NonNull @NonNull
public String getType() { public LogType getType() {
return type; return type;
} }
@ -47,12 +52,12 @@ public class LogEntry {
public static class Builder { public static class Builder {
private long timestamp; private long timestamp;
private final String type; private final LogType type;
private Map<String, String> data; private Map<String, String> data;
public Builder(@NonNull String type) { public Builder(LogType type) {
this.timestamp = System.currentTimeMillis(); this.timestamp = System.currentTimeMillis();
this.type = type.toUpperCase(Locale.ENGLISH); this.type = type;
this.data = new LinkedHashMap<>(); this.data = new LinkedHashMap<>();
} }

View File

@ -37,6 +37,7 @@ import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.configuration.WorldSettings; import world.bentobox.bentobox.api.configuration.WorldSettings;
import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.logs.LogEntry; import world.bentobox.bentobox.api.logs.LogEntry;
import world.bentobox.bentobox.api.logs.LogEntry.LogType;
import world.bentobox.bentobox.api.metadata.MetaDataAble; import world.bentobox.bentobox.api.metadata.MetaDataAble;
import world.bentobox.bentobox.api.metadata.MetaDataValue; import world.bentobox.bentobox.api.metadata.MetaDataValue;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
@ -327,7 +328,7 @@ public class Island implements DataObject, MetaDataAble {
public boolean ban(@NonNull UUID issuer, @NonNull UUID target) { public boolean ban(@NonNull UUID issuer, @NonNull UUID target) {
if (getRank(target) != RanksManager.BANNED_RANK) { if (getRank(target) != RanksManager.BANNED_RANK) {
setRank(target, RanksManager.BANNED_RANK); setRank(target, RanksManager.BANNED_RANK);
log(new LogEntry.Builder("BAN").data("player", target.toString()).data("issuer", issuer.toString()) log(new LogEntry.Builder(LogType.BAN).data("player", target.toString()).data("issuer", issuer.toString())
.build()); .build());
setChanged(); setChanged();
} }
@ -360,7 +361,7 @@ public class Island implements DataObject, MetaDataAble {
*/ */
public boolean unban(@NonNull UUID issuer, @NonNull UUID target) { public boolean unban(@NonNull UUID issuer, @NonNull UUID target) {
if (members.remove(target) != null) { if (members.remove(target) != null) {
log(new LogEntry.Builder("UNBAN").data("player", target.toString()).data("issuer", issuer.toString()) log(new LogEntry.Builder(LogType.UNBAN).data("player", target.toString()).data("issuer", issuer.toString())
.build()); .build());
return true; return true;
} }
@ -1132,7 +1133,7 @@ public class Island implements DataObject, MetaDataAble {
this.owner = owner; this.owner = owner;
if (owner == null) { if (owner == null) {
log(new LogEntry.Builder("UNOWNED").build()); log(new LogEntry.Builder(LogType.UNOWNED).build());
return; return;
} }
// Defensive code: demote any previous owner // Defensive code: demote any previous owner
@ -1281,7 +1282,7 @@ public class Island implements DataObject, MetaDataAble {
setFlagsDefaults(); setFlagsDefaults();
setFlag(Flags.LOCK, RanksManager.VISITOR_RANK); setFlag(Flags.LOCK, RanksManager.VISITOR_RANK);
} }
log(new LogEntry.Builder("SPAWN").data("value", String.valueOf(isSpawn)).build()); log(new LogEntry.Builder(LogType.SPAWN).data("value", String.valueOf(isSpawn)).build());
setChanged(); setChanged();
} }

View File

@ -5,7 +5,10 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.google.common.base.Enums;
import world.bentobox.bentobox.api.logs.LogEntry; import world.bentobox.bentobox.api.logs.LogEntry;
import world.bentobox.bentobox.api.logs.LogEntry.LogType;
/** /**
* @author Poslovitch * @author Poslovitch
@ -41,7 +44,7 @@ public class LogEntryListAdapter implements AdapterInterface<List<LogEntry>, Lis
List<Map<String, Object>> serialized = (List<Map<String, Object>>) object; List<Map<String, Object>> serialized = (List<Map<String, Object>>) object;
for (Map<String, Object> entry : serialized) { for (Map<String, Object> entry : serialized) {
long timestamp = (long) entry.get(TIMESTAMP); long timestamp = (long) entry.get(TIMESTAMP);
String type = (String) entry.get(TYPE); LogType type = Enums.getIfPresent(LogType.class, (String) entry.get(TYPE)).or(LogType.UNKNOWN);
Map<String, String> data = (Map<String, String>) entry.get(DATA); Map<String, String> data = (Map<String, String>) entry.get(DATA);
result.add(new LogEntry.Builder(type).timestamp(timestamp).data(data).build()); result.add(new LogEntry.Builder(type).timestamp(timestamp).data(data).build());

View File

@ -3,7 +3,10 @@ package world.bentobox.bentobox.lists;
import java.text.DateFormat; import java.text.DateFormat;
import java.time.Instant; import java.time.Instant;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNull;
@ -11,6 +14,8 @@ import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.logs.LogEntry;
import world.bentobox.bentobox.api.logs.LogEntry.LogType;
import world.bentobox.bentobox.api.placeholders.GameModePlaceholderReplacer; import world.bentobox.bentobox.api.placeholders.GameModePlaceholderReplacer;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
@ -120,6 +125,14 @@ public enum GameModePlaceholder {
* @since 1.5.0 * @since 1.5.0
*/ */
ISLAND_MEMBERS_COUNT("island_members_count", (addon, user, island) -> island == null ? "" : String.valueOf(island.getMemberSet().size())), ISLAND_MEMBERS_COUNT("island_members_count", (addon, user, island) -> island == null ? "" : String.valueOf(island.getMemberSet().size())),
/**
* Returns the number of players that are or have ever been a MEMBER on this island.
* @since 3.0.0
*/
ISLAND_HISTORICAL_MEMBERS_COUNT("island_historical_members_count",
(addon, user, island) -> island == null ? "" : getHistoricalMembers(island)),
/** /**
* Returns a comma separated list of player names that are at least MEMBER on this island. * Returns a comma separated list of player names that are at least MEMBER on this island.
* @since 1.13.0 * @since 1.13.0
@ -395,6 +408,24 @@ public enum GameModePlaceholder {
this.replacer = replacer; this.replacer = replacer;
} }
/**
* Provides a count of how many players have ever joined the island as a member including the owner
* @param island island
* @return String count of the number of members
*/
private static String getHistoricalMembers(@Nullable Island island) {
Set<String> uniqueMembers = new HashSet<>();
for (LogEntry le : island.getHistory()) {
if (le.getType() == LogType.JOINED) {
Iterator<String> it = le.getData().keySet().iterator();
while (it.hasNext()) {
uniqueMembers.add(it.next());
}
}
}
return String.valueOf(uniqueMembers.size());
}
/** /**
* Get the visited island * Get the visited island
* @param addon - game mode addon * @param addon - game mode addon

View File

@ -47,6 +47,8 @@ import world.bentobox.bentobox.api.events.island.IslandEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason; import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.logs.LogEntry;
import world.bentobox.bentobox.api.logs.LogEntry.LogType;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.Database; import world.bentobox.bentobox.database.Database;
import world.bentobox.bentobox.database.json.BentoboxTypeAdapterFactory; import world.bentobox.bentobox.database.json.BentoboxTypeAdapterFactory;
@ -1189,6 +1191,7 @@ public class IslandsManager {
* *
* @param player player * @param player player
*/ */
@SuppressWarnings("deprecation")
private void readyPlayer(@NonNull Player player) { private void readyPlayer(@NonNull Player player) {
// Stop any gliding // Stop any gliding
player.setGliding(false); player.setGliding(false);
@ -1537,6 +1540,8 @@ public class IslandsManager {
// Add player to new island // Add player to new island
teamIsland.addMember(playerUUID); teamIsland.addMember(playerUUID);
islandCache.addPlayer(playerUUID, teamIsland); islandCache.addPlayer(playerUUID, teamIsland);
// Add historu record
teamIsland.log(new LogEntry.Builder(LogType.JOINED).data(playerUUID.toString(), "player").build());
// Save the island // Save the island
updateIsland(teamIsland); updateIsland(teamIsland);
} }

View File

@ -23,6 +23,8 @@ import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.logs.LogEntry;
import world.bentobox.bentobox.api.logs.LogEntry.LogType;
import world.bentobox.bentobox.database.Database; import world.bentobox.bentobox.database.Database;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.bentobox.managers.RanksManager;
@ -431,6 +433,8 @@ public class IslandCache {
} }
island.removeMember(uuid); island.removeMember(uuid);
island.removePrimary(uuid); island.removePrimary(uuid);
// Add historu record
island.log(new LogEntry.Builder(LogType.REMOVE).data(uuid.toString(), "player").build());
} }
/** /**

View File

@ -15,6 +15,8 @@ import world.bentobox.bentobox.api.events.IslandBaseEvent;
import world.bentobox.bentobox.api.events.island.IslandCreateEvent; import world.bentobox.bentobox.api.events.island.IslandCreateEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent; import world.bentobox.bentobox.api.events.island.IslandEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason; import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
import world.bentobox.bentobox.api.logs.LogEntry;
import world.bentobox.bentobox.api.logs.LogEntry.LogType;
import world.bentobox.bentobox.api.events.island.IslandResetEvent; import world.bentobox.bentobox.api.events.island.IslandResetEvent;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island; import world.bentobox.bentobox.database.objects.Island;
@ -217,6 +219,8 @@ public class NewIsland {
island.setFlagsDefaults(); island.setFlagsDefaults();
// Register metrics // Register metrics
plugin.getMetrics().ifPresent(BStats::increaseIslandsCreatedCount); plugin.getMetrics().ifPresent(BStats::increaseIslandsCreatedCount);
// Add historu record
island.log(new LogEntry.Builder(LogType.JOINED).data(user.getUniqueId().toString(), "owner").build());
// Save island // Save island
IslandsManager.updateIsland(island); IslandsManager.updateIsland(island);
} }