From c74eff07d7b51eea0f48e4c536a30325911e68f8 Mon Sep 17 00:00:00 2001 From: ryanhamshire Date: Tue, 21 Apr 2015 21:05:05 -0700 Subject: [PATCH] Added abridged logs. For server owners to very quickly and conveniently review chat logs by day, and optionally GP administrative activity. Also a debug mode for log entries that would be too noisy for the standard server log. --- .../GriefPrevention/BlockEventHandler.java | 4 +- .../CleanupUnusedClaimsTask.java | 6 +- .../GriefPrevention/CustomLogger.java | 183 ++++++++++++++++++ .../GriefPrevention/DataStore.java | 7 - .../DeliverClaimBlocksTask.java | 10 +- .../GriefPrevention/GriefPrevention.java | 70 +++++-- .../GriefPrevention/PlayerData.java | 12 ++ .../GriefPrevention/PlayerEventHandler.java | 88 ++++++--- 8 files changed, 327 insertions(+), 53 deletions(-) create mode 100644 src/me/ryanhamshire/GriefPrevention/CustomLogger.java diff --git a/src/me/ryanhamshire/GriefPrevention/BlockEventHandler.java b/src/me/ryanhamshire/GriefPrevention/BlockEventHandler.java index 44af0df..368991f 100644 --- a/src/me/ryanhamshire/GriefPrevention/BlockEventHandler.java +++ b/src/me/ryanhamshire/GriefPrevention/BlockEventHandler.java @@ -132,7 +132,7 @@ public class BlockEventHandler implements Listener PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId()); if(notEmpty && playerData.lastMessage != null && !playerData.lastMessage.equals(signMessage)) { - GriefPrevention.AddLogEntry("[Sign Placement] <" + player.getName() + "> " + " @ " + GriefPrevention.getfriendlyLocationString(event.getBlock().getLocation()) + ": " + lines.toString().replace("\n ", ";")); + GriefPrevention.AddLogEntry("[Sign Placement] <" + player.getName() + "> " + " @ " + GriefPrevention.getfriendlyLocationString(event.getBlock().getLocation()) + ": " + lines.toString().replace("\n ", ";"), CustomLogEntryTypes.SocialActivity); playerData.lastMessage = signMessage; if(!player.hasPermission("griefprevention.eavesdrop")) @@ -538,7 +538,7 @@ public class BlockEventHandler implements Listener } catch(NoSuchMethodError exception) { - GriefPrevention.AddLogEntry("Your server is running an outdated version of 1.8 which has a griefing vulnerability. Update your server (reruns buildtools.jar to get an updated server JAR file) to ensure playres can't steal claimed blocks using pistons."); + GriefPrevention.AddLogEntry("Your server is running an outdated version of 1.8 which has a griefing vulnerability. Update your server (reruns buildtools.jar to get an updated server JAR file) to ensure players can't steal claimed blocks using pistons."); } } diff --git a/src/me/ryanhamshire/GriefPrevention/CleanupUnusedClaimsTask.java b/src/me/ryanhamshire/GriefPrevention/CleanupUnusedClaimsTask.java index b9383d8..bc4a210 100644 --- a/src/me/ryanhamshire/GriefPrevention/CleanupUnusedClaimsTask.java +++ b/src/me/ryanhamshire/GriefPrevention/CleanupUnusedClaimsTask.java @@ -98,7 +98,7 @@ class CleanupUnusedClaimsTask implements Runnable GriefPrevention.instance.restoreClaim(claim, 0); } - GriefPrevention.AddLogEntry(" " + claim.getOwnerName() + "'s new player claim expired."); + GriefPrevention.AddLogEntry(" " + claim.getOwnerName() + "'s new player claim expired.", CustomLogEntryTypes.AdminActivity); } } @@ -120,7 +120,7 @@ class CleanupUnusedClaimsTask implements Runnable //delete them GriefPrevention.instance.dataStore.deleteClaimsForPlayer(claim.ownerID, true); - GriefPrevention.AddLogEntry(" All of " + claim.getOwnerName() + "'s claims have expired."); + GriefPrevention.AddLogEntry(" All of " + claim.getOwnerName() + "'s claims have expired.", CustomLogEntryTypes.AdminActivity); for(int i = 0; i < claims.size(); i++) { @@ -156,7 +156,7 @@ class CleanupUnusedClaimsTask implements Runnable if(claimExpired) { GriefPrevention.instance.dataStore.deleteClaim(claim, true); - GriefPrevention.AddLogEntry("Removed " + claim.getOwnerName() + "'s unused claim @ " + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner())); + GriefPrevention.AddLogEntry("Removed " + claim.getOwnerName() + "'s unused claim @ " + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner()), CustomLogEntryTypes.AdminActivity); //restore the claim area to natural state GriefPrevention.instance.restoreClaim(claim, 0); diff --git a/src/me/ryanhamshire/GriefPrevention/CustomLogger.java b/src/me/ryanhamshire/GriefPrevention/CustomLogger.java new file mode 100644 index 0000000..f6ea5a9 --- /dev/null +++ b/src/me/ryanhamshire/GriefPrevention/CustomLogger.java @@ -0,0 +1,183 @@ +/* + GriefPrevention Server Plugin for Minecraft + Copyright (C) 2015 Ryan Hamshire + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +package me.ryanhamshire.GriefPrevention; + +import java.io.File; +import java.nio.charset.Charset; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import org.bukkit.scheduler.BukkitScheduler; + +import com.google.common.io.Files; + +class CustomLogger +{ + private final SimpleDateFormat timestampFormat = new SimpleDateFormat("HH:mm"); + private final SimpleDateFormat filenameFormat = new SimpleDateFormat("yyyy_MM_dd"); + private final String logFolderPath = DataStore.dataLayerFolderPath + File.separator + "Logs"; + private final int secondsBetweenWrites = 300; + + //stringbuilder is not thread safe, stringbuffer is + private StringBuffer queuedEntries = new StringBuffer(); + + CustomLogger() + { + //ensure log folder exists + File logFolder = new File(this.logFolderPath); + logFolder.mkdirs(); + + //delete any outdated log files immediately + this.DeleteExpiredLogs(); + + //unless disabled, schedule recurring tasks + int daysToKeepLogs = GriefPrevention.instance.config_logs_daysToKeep; + if(daysToKeepLogs > 0) + { + BukkitScheduler scheduler = GriefPrevention.instance.getServer().getScheduler(); + final long ticksPerSecond = 20L; + final long ticksPerDay = ticksPerSecond * 60 * 60 * 24; + scheduler.runTaskTimerAsynchronously(GriefPrevention.instance, new EntryWriter(), this.secondsBetweenWrites * ticksPerSecond, this.secondsBetweenWrites * ticksPerSecond); + scheduler.runTaskTimerAsynchronously(GriefPrevention.instance, new ExpiredLogRemover(), ticksPerDay, ticksPerDay); + } + } + + void AddEntry(String entry, CustomLogEntryTypes entryType) + { + //if disabled, do nothing + int daysToKeepLogs = GriefPrevention.instance.config_logs_daysToKeep; + if(daysToKeepLogs == 0) return; + + //if entry type is not enabled, do nothing + if(!this.isEnabledType(entryType)) return; + + //otherwise write to the in-memory buffer + String timestamp = this.timestampFormat.format(new Date()); + this.queuedEntries.append(timestamp + " " + entry + "\n"); + } + + private boolean isEnabledType(CustomLogEntryTypes entryType) + { + if(entryType == CustomLogEntryTypes.SocialActivity && !GriefPrevention.instance.config_logs_socialEnabled) return false; + if(entryType == CustomLogEntryTypes.SuspiciousActivity && !GriefPrevention.instance.config_logs_suspiciousEnabled) return false; + if(entryType == CustomLogEntryTypes.AdminActivity && !GriefPrevention.instance.config_logs_adminEnabled) return false; + if(entryType == CustomLogEntryTypes.Debug && !GriefPrevention.instance.config_logs_debugEnabled) return false; + + return true; + } + + void WriteEntries() + { + try + { + //if nothing to write, stop here + if(this.queuedEntries.length() == 0) return; + + //determine filename based on date + String filename = this.filenameFormat.format(new Date()) + ".log"; + String filepath = this.logFolderPath + File.separator + filename; + File logFile = new File(filepath); + + //dump content + Files.append(this.queuedEntries.toString(), logFile, Charset.forName("UTF-8")); + + //in case of a failure to write the above due to exception, + //the unwritten entries will remain the buffer for the next write to retry + this.queuedEntries.setLength(0); + } + catch(Exception e) + { + e.printStackTrace(); + } + } + + private void DeleteExpiredLogs() + { + try + { + //get list of log files + File logFolder = new File(this.logFolderPath); + File [] files = logFolder.listFiles(); + + //delete any created before x days ago + int daysToKeepLogs = GriefPrevention.instance.config_logs_daysToKeep; + Calendar expirationBoundary = Calendar.getInstance(); + expirationBoundary.add(Calendar.DATE, -daysToKeepLogs); + for(int i = 0; i < files.length; i++) + { + File file = files[i]; + if(file.isDirectory()) continue; //skip any folders + + String filename = file.getName().replace(".log", ""); + String [] dateParts = filename.split("_"); //format is yyyy_MM_dd + if(dateParts.length != 3) continue; + + try + { + int year = Integer.parseInt(dateParts[0]); + int month = Integer.parseInt(dateParts[1]) - 1; + int day = Integer.parseInt(dateParts[2]); + + Calendar filedate = Calendar.getInstance(); + filedate.set(year, month, day); + if(filedate.before(expirationBoundary)) + { + file.delete(); + } + } + catch(NumberFormatException e) + { + //throw this away - effectively ignoring any files without the correct filename format + GriefPrevention.AddLogEntry("Ignoring an unexpected file in the abridged logs folder: " + file.getName(), CustomLogEntryTypes.Debug, true); + } + } + } + catch(Exception e) + { + e.printStackTrace(); + } + } + + //transfers the internal buffer to a log file + private class EntryWriter implements Runnable + { + @Override + public void run() + { + WriteEntries(); + } + } + + private class ExpiredLogRemover implements Runnable + { + @Override + public void run() + { + DeleteExpiredLogs(); + } + } +} + +enum CustomLogEntryTypes +{ + SocialActivity, + SuspiciousActivity, + AdminActivity, + Debug +} diff --git a/src/me/ryanhamshire/GriefPrevention/DataStore.java b/src/me/ryanhamshire/GriefPrevention/DataStore.java index 9ec5070..9707c08 100644 --- a/src/me/ryanhamshire/GriefPrevention/DataStore.java +++ b/src/me/ryanhamshire/GriefPrevention/DataStore.java @@ -31,13 +31,6 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import com.sk89q.worldedit.BlockVector; -import com.sk89q.worldguard.LocalPlayer; -import com.sk89q.worldguard.bukkit.WorldGuardPlugin; -import com.sk89q.worldguard.protection.ApplicableRegionSet; -import com.sk89q.worldguard.protection.managers.RegionManager; -import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; - //singleton class which manages all GriefPrevention data (except for config options) public abstract class DataStore { diff --git a/src/me/ryanhamshire/GriefPrevention/DeliverClaimBlocksTask.java b/src/me/ryanhamshire/GriefPrevention/DeliverClaimBlocksTask.java index 0f8d3f6..b539481 100644 --- a/src/me/ryanhamshire/GriefPrevention/DeliverClaimBlocksTask.java +++ b/src/me/ryanhamshire/GriefPrevention/DeliverClaimBlocksTask.java @@ -41,6 +41,8 @@ class DeliverClaimBlocksTask implements Runnable //if no player specified, this task will create a player-specific task for each online player, scheduled one tick apart if(this.player == null && GriefPrevention.instance.config_claims_blocksAccruedPerHour > 0) { + GriefPrevention.AddLogEntry("Delivering claim blocks to active players...", CustomLogEntryTypes.Debug, true); + Collection players = (Collection)GriefPrevention.instance.getServer().getOnlinePlayers(); long i = 0; @@ -76,11 +78,17 @@ class DeliverClaimBlocksTask implements Runnable int accruedBlocks = GriefPrevention.instance.config_claims_blocksAccruedPerHour / 12; if(accruedBlocks < 0) accruedBlocks = 1; + GriefPrevention.AddLogEntry(accruedBlocks + " for " + player.getName(), CustomLogEntryTypes.Debug, true); + playerData.accrueBlocks(accruedBlocks); //intentionally NOT saving data here to reduce overall secondary storage access frequency //many other operations will cause this players data to save, including his eventual logout - //dataStore.savePlayerData(player.getName(), playerData); + //dataStore.savePlayerData(player.getUniqueIdentifier(), playerData); + } + else + { + GriefPrevention.AddLogEntry(player.getName() + " isn't active enough.", CustomLogEntryTypes.Debug, true); } } catch(IllegalArgumentException e) //can't measure distance when to/from are different worlds diff --git a/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java b/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java index 8402e2c..e47d973 100644 --- a/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java +++ b/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java @@ -46,7 +46,6 @@ import org.bukkit.block.BlockFace; import org.bukkit.command.*; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; @@ -68,6 +67,9 @@ public class GriefPrevention extends JavaPlugin //this tracks item stacks expected to drop which will need protection ArrayList pendingItemWatchList = new ArrayList(); + + //log entry manager for GP's custom log files + CustomLogger customLogger; //configuration variables, loaded/saved from a config.yml @@ -164,6 +166,13 @@ public class GriefPrevention extends JavaPlugin public boolean config_limitTreeGrowth; //whether trees should be prevented from growing into a claim from outside public boolean config_pistonsInClaimsOnly; //whether pistons are limited to only move blocks located within the piston's land claim + //custom log settings + public int config_logs_daysToKeep; + public boolean config_logs_socialEnabled; + public boolean config_logs_suspiciousEnabled; + public boolean config_logs_adminEnabled; + public boolean config_logs_debugEnabled; + private String databaseUrl; private String databaseUserName; private String databasePassword; @@ -178,20 +187,36 @@ public class GriefPrevention extends JavaPlugin public static final int NOTIFICATION_SECONDS = 20; //adds a server log entry - public static synchronized void AddLogEntry(String entry) + public static synchronized void AddLogEntry(String entry, CustomLogEntryTypes customLogType, boolean excludeFromServerLogs) { - log.info("GriefPrevention: " + entry); + if(customLogType != null && GriefPrevention.instance.customLogger != null) + { + GriefPrevention.instance.customLogger.AddEntry(entry, customLogType); + } + if(!excludeFromServerLogs) log.info("GriefPrevention: " + entry); } + public static synchronized void AddLogEntry(String entry, CustomLogEntryTypes customLogType) + { + AddLogEntry(entry, customLogType, false); + } + + public static synchronized void AddLogEntry(String entry) + { + AddLogEntry(entry, CustomLogEntryTypes.Debug); + } + //initializes well... everything public void onEnable() { - AddLogEntry("Grief Prevention boot start."); - - instance = this; + instance = this; + + AddLogEntry("Grief Prevention boot start."); this.loadConfig(); + this.customLogger = new CustomLogger(); + AddLogEntry("Finished loading configuration."); //when datastore initializes, it loads player and claim data, and posts some stats to the log @@ -330,7 +355,7 @@ public class GriefPrevention extends JavaPlugin private void loadConfig() { - //load the config if it exists + //load the config if it exists FileConfiguration config = YamlConfiguration.loadConfiguration(new File(DataStore.configFilePath)); FileConfiguration outConfig = new YamlConfiguration(); @@ -658,6 +683,13 @@ public class GriefPrevention extends JavaPlugin this.databaseUserName = config.getString("GriefPrevention.Database.UserName", ""); this.databasePassword = config.getString("GriefPrevention.Database.Password", ""); + //custom logger settings + this.config_logs_daysToKeep = config.getInt("GriefPrevention.Abridged Logs.Days To Keep", 7); + this.config_logs_socialEnabled = config.getBoolean("GriefPrevention.Abridged Logs.Included Entry Types.Social Activity", true); + this.config_logs_suspiciousEnabled = config.getBoolean("GriefPrevention.Abridged Logs.Included Entry Types.Suspicious Activity", true); + this.config_logs_adminEnabled = config.getBoolean("GriefPrevention.Abridged Logs.Included Entry Types.Administrative Activity", false); + this.config_logs_debugEnabled = config.getBoolean("GriefPrevention.Abridged Logs.Included Entry Types.Debug", false); + //claims mode by world for(World world : this.config_claims_worldModes.keySet()) { @@ -758,6 +790,13 @@ public class GriefPrevention extends JavaPlugin outConfig.set("GriefPrevention.Mods.BlockIdsRequiringContainerTrust", containerTrustStrings); outConfig.set("GriefPrevention.Mods.BlockIdsExplodable", explodableStrings); + //custom logger settings + outConfig.set("GriefPrevention.Abridged Logs.Days To Keep", this.config_logs_daysToKeep); + outConfig.set("GriefPrevention.Abridged Logs.Included Entry Types.Social Activity", this.config_logs_socialEnabled); + outConfig.set("GriefPrevention.Abridged Logs.Included Entry Types.Suspicious Activity", this.config_logs_suspiciousEnabled); + outConfig.set("GriefPrevention.Abridged Logs.Included Entry Types.Administrative Activity", this.config_logs_adminEnabled); + outConfig.set("GriefPrevention.Abridged Logs.Included Entry Types.Debug", this.config_logs_debugEnabled); + try { outConfig.save(DataStore.configFilePath); @@ -1002,7 +1041,7 @@ public class GriefPrevention extends JavaPlugin //confirm GriefPrevention.sendMessage(player, TextMode.Success, Messages.TransferSuccess); - GriefPrevention.AddLogEntry(player.getName() + " transferred a claim at " + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner()) + " to " + ownerName + "."); + GriefPrevention.AddLogEntry(player.getName() + " transferred a claim at " + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner()) + " to " + ownerName + ".", CustomLogEntryTypes.AdminActivity); return true; } @@ -1477,7 +1516,7 @@ public class GriefPrevention extends JavaPlugin } GriefPrevention.sendMessage(player, TextMode.Success, Messages.DeleteSuccess); - GriefPrevention.AddLogEntry(player.getName() + " deleted " + claim.getOwnerName() + "'s claim at " + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner())); + GriefPrevention.AddLogEntry(player.getName() + " deleted " + claim.getOwnerName() + "'s claim at " + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner()), CustomLogEntryTypes.AdminActivity); //revert any current visualization Visualization.Revert(player); @@ -1548,7 +1587,7 @@ public class GriefPrevention extends JavaPlugin GriefPrevention.sendMessage(player, TextMode.Success, Messages.DeleteAllSuccess, otherPlayer.getName()); if(player != null) { - GriefPrevention.AddLogEntry(player.getName() + " deleted all claims belonging to " + otherPlayer.getName() + "."); + GriefPrevention.AddLogEntry(player.getName() + " deleted all claims belonging to " + otherPlayer.getName() + ".", CustomLogEntryTypes.AdminActivity); //revert any current visualization Visualization.Revert(player); @@ -1641,7 +1680,7 @@ public class GriefPrevention extends JavaPlugin GriefPrevention.sendMessage(player, TextMode.Success, Messages.AllAdminDeleted); if(player != null) { - GriefPrevention.AddLogEntry(player.getName() + " deleted all administrative claims."); + GriefPrevention.AddLogEntry(player.getName() + " deleted all administrative claims.", CustomLogEntryTypes.AdminActivity); //revert any current visualization Visualization.Revert(player); @@ -1693,7 +1732,7 @@ public class GriefPrevention extends JavaPlugin this.dataStore.savePlayerData(targetPlayer.getUniqueId(), playerData); GriefPrevention.sendMessage(player, TextMode.Success, Messages.AdjustBlocksSuccess, targetPlayer.getName(), String.valueOf(adjustment), String.valueOf(playerData.getBonusClaimBlocks())); - if(player != null) GriefPrevention.AddLogEntry(player.getName() + " adjusted " + targetPlayer.getName() + "'s bonus claim blocks by " + adjustment + "."); + if(player != null) GriefPrevention.AddLogEntry(player.getName() + " adjusted " + targetPlayer.getName() + "'s bonus claim blocks by " + adjustment + ".", CustomLogEntryTypes.AdminActivity); return true; } @@ -1729,7 +1768,7 @@ public class GriefPrevention extends JavaPlugin this.dataStore.savePlayerData(targetPlayer.getUniqueId(), playerData); GriefPrevention.sendMessage(player, TextMode.Success, Messages.SetClaimBlocksSuccess); - if(player != null) GriefPrevention.AddLogEntry(player.getName() + " set " + targetPlayer.getName() + "'s accrued claim blocks to " + newAmount + "."); + if(player != null) GriefPrevention.AddLogEntry(player.getName() + " set " + targetPlayer.getName() + "'s accrued claim blocks to " + newAmount + ".", CustomLogEntryTypes.AdminActivity); return true; } @@ -2243,7 +2282,7 @@ public class GriefPrevention extends JavaPlugin //helper method to resolve a player by name ConcurrentHashMap playerNameToIDMap = new ConcurrentHashMap(); - //thread to build the above cache + //thread to build the above cache private class CacheOfflinePlayerNamesThread extends Thread { private OfflinePlayer [] offlinePlayers; @@ -2369,6 +2408,9 @@ public class GriefPrevention extends JavaPlugin this.dataStore.close(); + //dump any remaining unwritten log entries + this.customLogger.WriteEntries(); + AddLogEntry("GriefPrevention disabled."); } diff --git a/src/me/ryanhamshire/GriefPrevention/PlayerData.java b/src/me/ryanhamshire/GriefPrevention/PlayerData.java index 8441f00..098b7c1 100644 --- a/src/me/ryanhamshire/GriefPrevention/PlayerData.java +++ b/src/me/ryanhamshire/GriefPrevention/PlayerData.java @@ -31,6 +31,7 @@ import me.ryanhamshire.GriefPrevention.Visualization; import org.bukkit.Location; import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; //holds all of GriefPrevention's player-tied data public class PlayerData @@ -291,6 +292,17 @@ public class PlayerData int totalBlocks = this.accruedClaimBlocks + this.getBonusClaimBlocks() + GriefPrevention.instance.dataStore.getGroupBonusBlocks(this.playerID); if(totalBlocks < totalClaimsArea) { + Player player = GriefPrevention.instance.getServer().getPlayer(this.playerID); + GriefPrevention.AddLogEntry(player.getName() + "has more claimed land than blocks available. Adding blocks to fix.", CustomLogEntryTypes.Debug); + GriefPrevention.AddLogEntry("Total blocks: " + totalBlocks + " Total claimed area: " + totalClaimsArea, CustomLogEntryTypes.Debug); + for(Claim claim : this.claims) + { + GriefPrevention.AddLogEntry( + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner()) + " // " + + GriefPrevention.getfriendlyLocationString(claim.getGreaterBoundaryCorner()) + " = " + + claim.getArea()); + } + //try to fix it by adding to accrued blocks this.accruedClaimBlocks = totalClaimsArea; if(this.accruedClaimBlocks > GriefPrevention.instance.config_claims_maxAccruedBlocks) diff --git a/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java b/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java index 6711e14..6cbbd18 100644 --- a/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java +++ b/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java @@ -27,7 +27,6 @@ import java.util.List; import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import java.util.regex.Matcher; import java.util.regex.Pattern; import org.bukkit.Achievement; @@ -115,6 +114,7 @@ class PlayerEventHandler implements Listener //soft muted messages go out to all soft muted players else if(this.dataStore.isSoftMuted(player.getUniqueId())) { + String notificationMessage = "(Muted " + player.getName() + "): " + message; Set recipientsToKeep = new HashSet(); for(Player recipient : recipients) { @@ -124,11 +124,19 @@ class PlayerEventHandler implements Listener } else if(recipient.hasPermission("griefprevention.eavesdrop")) { - recipient.sendMessage(ChatColor.GRAY + "(Muted " + player.getName() + "): " + message); + recipient.sendMessage(ChatColor.GRAY + notificationMessage); } } recipients.clear(); recipients.addAll(recipientsToKeep); + + GriefPrevention.AddLogEntry(notificationMessage, CustomLogEntryTypes.Debug, true); + } + + //unfiltered messages go to the abridged chat logs + else + { + this.makeSocialLogEntry(player.getName(), message); } } @@ -300,7 +308,7 @@ class PlayerEventHandler implements Listener if(GriefPrevention.instance.config_spam_banOffenders) { //log entry - GriefPrevention.AddLogEntry("Banning " + player.getName() + " for spam."); + GriefPrevention.AddLogEntry("Banning " + player.getName() + " for spam.", CustomLogEntryTypes.AdminActivity); //kick and ban PlayerKickBanTask task = new PlayerKickBanTask(player, GriefPrevention.instance.config_spam_banMessage); @@ -309,7 +317,7 @@ class PlayerEventHandler implements Listener else { //log entry - GriefPrevention.AddLogEntry("Banning " + player.getName() + " for spam."); + GriefPrevention.AddLogEntry("Kicking " + player.getName() + " for spam.", CustomLogEntryTypes.AdminActivity); //just kick PlayerKickBanTask task = new PlayerKickBanTask(player, null); @@ -330,7 +338,7 @@ class PlayerEventHandler implements Listener if(!playerData.spamWarned) { GriefPrevention.sendMessage(player, TextMode.Warn, GriefPrevention.instance.config_spam_warningMessage, 10L); - GriefPrevention.AddLogEntry("Warned " + player.getName() + " about spam penalties."); + GriefPrevention.AddLogEntry("Warned " + player.getName() + " about spam penalties.", CustomLogEntryTypes.Debug, true); playerData.spamWarned = true; } } @@ -339,6 +347,7 @@ class PlayerEventHandler implements Listener { //make a log entry GriefPrevention.AddLogEntry("Muted " + mutedReason + "."); + GriefPrevention.AddLogEntry("Muted " + player.getName() + " " + mutedReason + ":" + message, CustomLogEntryTypes.Debug, true); //cancelling the event guarantees other players don't receive the message return true; @@ -442,28 +451,40 @@ class PlayerEventHandler implements Listener return; } - //if anti spam enabled, check for spam - if(GriefPrevention.instance.config_spam_enabled) + //if the slash command used is in the list of monitored commands, treat it like a chat message (see above) + boolean isMonitoredCommand = false; + for(String monitoredCommand : GriefPrevention.instance.config_spam_monitorSlashCommands) { - //if the slash command used is in the list of monitored commands, treat it like a chat message (see above) - boolean isMonitoredCommand = false; - for(String monitoredCommand : GriefPrevention.instance.config_spam_monitorSlashCommands) - { - if(args[0].equalsIgnoreCase(monitoredCommand)) - { - isMonitoredCommand = true; - break; - } - } - - if(isMonitoredCommand) - { - event.setCancelled(this.handlePlayerChat(event.getPlayer(), event.getMessage(), event)); - } + if(args[0].equalsIgnoreCase(monitoredCommand)) + { + isMonitoredCommand = true; + break; + } + } + + if(isMonitoredCommand) + { + //if anti spam enabled, check for spam + if(GriefPrevention.instance.config_spam_enabled) + { + event.setCancelled(this.handlePlayerChat(event.getPlayer(), event.getMessage(), event)); + } + + //unless cancelled, log in abridged logs + if(!event.isCancelled()) + { + StringBuilder builder = new StringBuilder(); + for(String arg : args) + { + builder.append(arg + " "); + } + + this.makeSocialLogEntry(event.getPlayer().getName(), builder.toString()); + } } //if requires access trust, check for permission - boolean isMonitoredCommand = false; + isMonitoredCommand = false; for(String monitoredCommand : GriefPrevention.instance.config_claims_commandsRequiringAccessTrust) { if(args[0].equalsIgnoreCase(monitoredCommand)) @@ -490,7 +511,22 @@ class PlayerEventHandler implements Listener } } - private ConcurrentHashMap lastLoginThisServerSessionMap = new ConcurrentHashMap(); + private int longestNameLength = 10; + private void makeSocialLogEntry(String name, String message) + { + StringBuilder entryBuilder = new StringBuilder(name); + for(int i = name.length(); i < longestNameLength; i++) + { + entryBuilder.append(' '); + } + entryBuilder.append(": " + message); + + this.longestNameLength = Math.max(longestNameLength, name.length()); + + GriefPrevention.AddLogEntry(entryBuilder.toString(), CustomLogEntryTypes.SocialActivity, true); + } + + private ConcurrentHashMap lastLoginThisServerSessionMap = new ConcurrentHashMap(); //when a player attempts to join the server... @EventHandler(priority = EventPriority.HIGHEST) @@ -619,7 +655,7 @@ class PlayerEventHandler implements Listener //otherwise if that account is still banned, ban this account, too else { - GriefPrevention.AddLogEntry("Auto-banned " + player.getName() + " because that account is using an IP address very recently used by banned player " + info.bannedAccountName + " (" + info.address.toString() + ")."); + GriefPrevention.AddLogEntry("Auto-banned " + player.getName() + " because that account is using an IP address very recently used by banned player " + info.bannedAccountName + " (" + info.address.toString() + ").", CustomLogEntryTypes.AdminActivity); //notify any online ops Collection players = (Collection)GriefPrevention.instance.getServer().getOnlinePlayers(); @@ -1268,7 +1304,7 @@ class PlayerEventHandler implements Listener if(makeLogEntry) { - GriefPrevention.AddLogEntry(player.getName() + " placed suspicious " + bucketEvent.getBucket().name() + " @ " + GriefPrevention.getfriendlyLocationString(block.getLocation())); + GriefPrevention.AddLogEntry(player.getName() + " placed suspicious " + bucketEvent.getBucket().name() + " @ " + GriefPrevention.getfriendlyLocationString(block.getLocation()), CustomLogEntryTypes.SuspiciousActivity); } } }