/*
* Copyright 2011 Tyler Blair. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and contributors and should not be interpreted as representing official policies,
* either expressed or implied, of anybody else.
*/
package com.griefcraft.util;
import com.griefcraft.cache.MethodCounter;
import com.griefcraft.cache.ProtectionCache;
import com.griefcraft.lwc.LWC;
import com.griefcraft.lwc.LWCInfo;
import com.griefcraft.scripting.MetaData;
import com.griefcraft.sql.Database;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.plugin.Plugin;
import java.text.NumberFormat;
import java.util.List;
import java.util.Map;
public class Statistics {
/**
* Number of queries executed on the database
*/
private static int queries = 0;
/**
* Time when LWC was started
*/
private static long startTime = 0L;
/**
* Add a query
*/
public static void addQuery() {
queries++;
}
/**
* @return the average of a value
*/
public static double getAverage(long value) {
return (double) value / getTimeRunningSeconds();
}
/**
* Obtain an entity count of a Entity class.
*
* @param clazz If null, all entities are counted
* @return
*/
public static int getEntityCount(Class<? extends Entity> clazz) {
int count = 0;
for (World world : Bukkit.getServer().getWorlds()) {
if (clazz == null) {
count += world.getEntities().size();
} else {
for (Entity entity : world.getEntities()) {
if (entity != null && clazz.isInstance(entity)) {
count++;
}
}
}
}
return count;
}
/**
* Send a performance report to a Console Sender
*
* @param sender
*/
public static void sendReport(CommandSender sender) {
LWC lwc = LWC.getInstance();
sender.sendMessage(" ");
sender.sendMessage(Colors.Red + "LWC Report");
sender.sendMessage(" Version: " + Colors.Green + LWCInfo.FULL_VERSION);
sender.sendMessage(" Running time: " + Colors.Green + TimeUtil.timeToString(getTimeRunningSeconds()));
sender.sendMessage(" Players: " + Colors.Green + Bukkit.getServer().getOnlinePlayers().size() + "/" + Bukkit.getServer().getMaxPlayers());
sender.sendMessage(" Item entities: " + Colors.Green + getEntityCount(Item.class) + "/" + getEntityCount(null));
sender.sendMessage(" Permissions API: " + Colors.Green + lwc.getPermissions().getClass().getSimpleName());
sender.sendMessage(" Currency API: " + Colors.Green + lwc.getCurrency().getClass().getSimpleName());
sender.sendMessage(" ");
sender.sendMessage(Colors.Red + " ==== Modules ====");
for (Map.Entry<Plugin, List<MetaData>> entry : lwc.getModuleLoader().getRegisteredModules().entrySet()) {
Plugin plugin = entry.getKey();
List<MetaData> modules = entry.getValue();
// Why?
if (plugin == null) {
continue;
}
sender.sendMessage(" " + Colors.Green + plugin.getDescription().getName() + " v" + plugin.getDescription().getVersion() + Colors.Yellow + " -> " + Colors.Green + modules.size() + Colors.Yellow + " registered modules");
}
sender.sendMessage(" ");
sender.sendMessage(Colors.Red + " ==== Database ====");
sender.sendMessage(" Engine: " + Colors.Green + Database.DefaultType);
sender.sendMessage(" Protections: " + Colors.Green + formatNumber(lwc.getPhysicalDatabase().getProtectionCount()));
sender.sendMessage(" Queries: " + Colors.Green + formatNumber(queries) + " | " + String.format("%.2f", getAverage(queries)) + " / second");
sender.sendMessage(" ");
sender.sendMessage(Colors.Red + " ==== Cache ==== ");
ProtectionCache cache = lwc.getProtectionCache();
double cachePercentFilled = ((double) cache.size() / cache.totalCapacity()) * 100;
String cacheColour = Colors.Green;
if (cachePercentFilled > 75 && cachePercentFilled < 85) {
cacheColour = Colors.Yellow;
} else if (cachePercentFilled > 85 && cachePercentFilled < 95) {
cacheColour = Colors.Rose;
} else if (cachePercentFilled > 95) {
cacheColour = Colors.Red;
}
sender.sendMessage(" Usage: " + cacheColour + String.format("%.2f", cachePercentFilled) + "% " + Colors.White + " ( " + cache.size() + "/" + cache.totalCapacity() + " [" + cache.capacity() + "+" + cache.adaptiveCapacity() + "] )");
sender.sendMessage(" Profile: ");
sendMethodCounter(sender, cache.getMethodCounter());
// sender.sendMessage(" Reads: " + formatNumber(cache.getReads()) + " | " + String.format("%.2f", getAverage(cache.getReads())) + " / second");
// sender.sendMessage(" Writes: " + formatNumber(cache.getWrites()) + " | " + String.format("%.2f", getAverage(cache.getWrites())) + " / second");
}
private static void sendMethodCounter(CommandSender sender, MethodCounter counter) {
Map<String, Integer> sorted = counter.sortByValue();
for (Map.Entry<String, Integer> entry : sorted.entrySet()) {
String method = entry.getKey();
int count = entry.getValue();
sender.sendMessage(" " + method + ": " + formatNumber(count) + " (" + String.format("%.2f", getAverage(count)) + " / second)");
}
}
/**
* Format a number
*
* @param number
* @return
*/
public static String formatNumber(long number) {
return NumberFormat.getInstance().format(number);
}
/**
* @return time in seconds it was being ran
*/
public static int getTimeRunningSeconds() {
return (int) ((System.currentTimeMillis() - startTime) / 1000);
}
/**
* Initialize
*/
public static void init() {
startTime = System.currentTimeMillis();
}
}