diff --git a/src/main/java/me/totalfreedom/totalfreedommod/admin/ActivityLog.java b/src/main/java/me/totalfreedom/totalfreedommod/admin/ActivityLog.java new file mode 100644 index 00000000..e42e6543 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/admin/ActivityLog.java @@ -0,0 +1,192 @@ +package me.totalfreedom.totalfreedommod.admin; + +import com.google.common.collect.Maps; +import java.util.Map; +import lombok.Getter; +import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.TotalFreedomMod; +import me.totalfreedom.totalfreedommod.util.FLog; +import net.pravian.aero.config.YamlConfig; +import net.pravian.aero.util.Ips; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class ActivityLog extends FreedomService +{ + + public static final String FILENAME = "activitylog.yml"; + + @Getter + private final Map allActivityLogs = Maps.newHashMap(); + private final Map nameTable = Maps.newHashMap(); + private final Map ipTable = Maps.newHashMap(); + + private final YamlConfig config; + + public ActivityLog(TotalFreedomMod plugin) + { + super(plugin); + + this.config = new YamlConfig(plugin, FILENAME, true); + } + + @Override + protected void onStart() + { + load(); + } + + @Override + protected void onStop() + { + save(); + } + + public void load() + { + config.load(); + + allActivityLogs.clear(); + nameTable.clear(); + ipTable.clear(); + for (String key : config.getKeys(false)) + { + ConfigurationSection section = config.getConfigurationSection(key); + if (section == null) + { + logger.warning("Invalid activity log format: " + key); + continue; + } + + ActivityLogEntry activityLogEntry = new ActivityLogEntry(key); + activityLogEntry.loadFrom(section); + + if (!activityLogEntry.isValid()) + { + FLog.warning("Could not load activity log: " + key + ". Missing details!"); + continue; + } + + allActivityLogs.put(key, activityLogEntry); + } + + updateTables(); + FLog.info("Loaded " + allActivityLogs.size() + " activity logs"); + } + + public void save() + { + // Clear the config + for (String key : config.getKeys(false)) + { + config.set(key, null); + } + + for (ActivityLogEntry activityLog : allActivityLogs.values()) + { + activityLog.saveTo(config.createSection(activityLog.getConfigKey())); + } + + config.save(); + } + + public ActivityLogEntry getActivityLog(CommandSender sender) + { + if (sender instanceof Player) + { + return getActivityLog((Player)sender); + } + + return getEntryByName(sender.getName()); + } + + public ActivityLogEntry getActivityLog(Player player) + { + ActivityLogEntry activityLog = getEntryByName(player.getName()); + if (activityLog == null) + { + String ip = Ips.getIp(player); + activityLog = getEntryByIp(ip); + if (activityLog != null) + { + // Set the new username + activityLog.setName(player.getName()); + save(); + updateTables(); + } + else + { + activityLog = new ActivityLogEntry(player); + allActivityLogs.put(activityLog.getConfigKey(), activityLog); + updateTables(); + + activityLog.saveTo(config.createSection(activityLog.getConfigKey())); + config.save(); + } + } + String ip = Ips.getIp(player); + if (!activityLog.getIps().contains(ip)) + { + activityLog.addIp(ip); + save(); + updateTables(); + } + return activityLog; + } + + public ActivityLogEntry getEntryByName(String name) + { + return nameTable.get(name.toLowerCase()); + } + + public ActivityLogEntry getEntryByIp(String ip) + { + return ipTable.get(ip); + } + + public void updateTables() + { + nameTable.clear(); + ipTable.clear(); + + for (ActivityLogEntry activityLog : allActivityLogs.values()) + { + nameTable.put(activityLog.getName().toLowerCase(), activityLog); + + for (String ip : activityLog.getIps()) + { + ipTable.put(ip, activityLog); + } + + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerJoin(PlayerJoinEvent event) + { + Player player = event.getPlayer(); + if (plugin.al.isAdmin(player)) + { + getActivityLog(event.getPlayer()).addLogin(); + plugin.acl.save(); + plugin.acl.updateTables(); + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerQuit(PlayerQuitEvent event) + { + Player player = event.getPlayer(); + if (plugin.al.isAdmin(player)) + { + getActivityLog(event.getPlayer()).addLogout(); + plugin.acl.save(); + plugin.acl.updateTables(); + } + } +} diff --git a/src/main/java/me/totalfreedom/totalfreedommod/admin/ActivityLogEntry.java b/src/main/java/me/totalfreedom/totalfreedommod/admin/ActivityLogEntry.java new file mode 100644 index 00000000..85b3be18 --- /dev/null +++ b/src/main/java/me/totalfreedom/totalfreedommod/admin/ActivityLogEntry.java @@ -0,0 +1,130 @@ +package me.totalfreedom.totalfreedommod.admin; + +import com.google.common.collect.Lists; +import java.time.Instant; +import java.util.Date; +import java.util.List; +import lombok.Getter; +import lombok.Setter; +import me.totalfreedom.totalfreedommod.util.FUtil; +import net.pravian.aero.base.ConfigLoadable; +import net.pravian.aero.base.ConfigSavable; +import net.pravian.aero.base.Validatable; +import org.apache.commons.lang3.Validate; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; + +public class ActivityLogEntry implements ConfigLoadable, ConfigSavable, Validatable +{ + + @Getter + private String configKey; + @Getter + @Setter + private String name; + @Getter + private final List ips = Lists.newArrayList(); + @Getter + @Setter + private List timestamps = Lists.newArrayList(); + @Getter + @Setter + private List durations = Lists.newArrayList(); + + public static final String FILENAME = "activitylog.yml"; + + public ActivityLogEntry(Player player) + { + this.configKey = player.getName().toLowerCase(); + this.name = player.getName(); + } + + public ActivityLogEntry(String configKey) + { + this.configKey = configKey; + } + + public void loadFrom(Player player) + { + configKey = player.getName().toLowerCase(); + name = player.getName(); + } + + @Override + public void loadFrom(ConfigurationSection cs) + { + name = cs.getString("username", configKey); + ips.clear(); + ips.addAll(cs.getStringList("ips")); + timestamps.clear(); + timestamps.addAll(cs.getStringList("timestamps")); + durations.clear(); + durations.addAll(cs.getStringList("durations")); + } + + @Override + public void saveTo(ConfigurationSection cs) + { + Validate.isTrue(isValid(), "Could not save activity entry: " + name + ". Entry not valid!"); + cs.set("username", name); + cs.set("ips", Lists.newArrayList(ips)); + cs.set("timestamps", Lists.newArrayList(timestamps)); + cs.set("durations", Lists.newArrayList(durations)); + } + + public void addLogin() + { + Date currentTime = Date.from(Instant.now()); + timestamps.add("Login: " + FUtil.dateToString(currentTime)); + } + public void addLogout() + { + String lastLoginString = timestamps.get(timestamps.size() - 1); + Date currentTime = Date.from(Instant.now()); + timestamps.add("Logout: " + FUtil.dateToString(currentTime)); + lastLoginString = lastLoginString.replace("Login: ", ""); + Date lastLogin = FUtil.stringToDate(lastLoginString); + + long duration = currentTime.getTime() - lastLogin.getTime(); + long seconds = duration / 1000 % 60; + long minutes = duration / (60 * 1000) % 60; + long hours = duration / (60 * 60 * 1000); + durations.add(hours + " hours, " + minutes + " minutes, and " + seconds + " seconds"); + } + + public void addIp(String ip) + { + if (!ips.contains(ip)) + { + ips.add(ip); + } + } + + public void addIps(List ips) + { + for (String ip : ips) + { + addIp(ip); + } + } + + public void removeIp(String ip) + { + if (ips.contains(ip)) + { + ips.remove(ip); + } + } + + public void clearIPs() + { + ips.clear(); + } + + @Override + public boolean isValid() + { + return configKey != null + && name != null; + } +}