[3.1.0] Merge pull request #86 from Rsl1122/Version-3.1.0

3.1.0 Pull request
This commit is contained in:
Rsl1122 2017-05-12 13:06:25 +03:00 committed by GitHub
commit 8b659a44d0
110 changed files with 4127 additions and 6241 deletions

3
.gitignore vendored
View File

@ -5,5 +5,4 @@
/Plan/target/
/Plan/temporaryTestFolder/
/Debugger/nbproject/private/
/PlanDebugger/
/Plan Lite/
/PlanDebugger/

View File

@ -1,73 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="PlanLite" default="default" basedir=".">
<description>Builds, tests, and runs the project PlanLite.</description>
<import file="nbproject/build-impl.xml"/>
<!--
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. They are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-single: called before javac compilation of single file
-post-compile-single: called after javac compilation of single file
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-compile-test-single: called before javac compilation of single JUnit test
-post-compile-test-single: called after javac compilation of single JUunit test
-pre-jar: called before JAR building
-post-jar: called after JAR building
-post-clean: called after cleaning build products
(Targets beginning with '-' are not intended to be called on their own.)
Example of inserting an obfuscator after compilation could look like this:
<target name="-post-compile">
<obfuscate>
<fileset dir="${build.classes.dir}"/>
</obfuscate>
</target>
For list of available properties check the imported
nbproject/build-impl.xml file.
Another way to customize the build is by overriding existing main targets.
The targets of interest are:
-init-macrodef-javac: defines macro for javac compilation
-init-macrodef-junit: defines macro for junit execution
-init-macrodef-debug: defines macro for class debugging
-init-macrodef-java: defines macro for class execution
-do-jar: JAR building
run: execution of project
-javadoc-build: Javadoc generation
test-report: JUnit report generation
An example of overriding the target for project execution could look like this:
<target name="run" depends="PlanLite-impl.jar">
<exec dir="bin" executable="launcher.exe">
<arg file="${dist.jar}"/>
</exec>
</target>
Notice that the overridden target depends on the jar target and not only on
the compile target as the regular run target does. Again, for a list of available
properties which you can use, check the target you are overriding in the
nbproject/build-impl.xml file.
-->
</project>

View File

@ -1,2 +0,0 @@
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +0,0 @@
build.xml.data.CRC32=f0bf6c4b
build.xml.script.CRC32=42f31611
build.xml.stylesheet.CRC32=8064a381@1.79.1.48
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=f0bf6c4b
nbproject/build-impl.xml.script.CRC32=ca4555e3
nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48

View File

@ -1,98 +0,0 @@
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.processors.list=
annotation.processing.run.all.processors=true
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
application.title=PlanLite
application.vendor=Risto
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=\
${run.classpath}
debug.test.classpath=\
${run.test.classpath}
# Files in build.classes.dir which should be excluded from distribution jar
dist.archive.excludes=
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/PlanLite.jar
dist.javadoc.dir=${dist.dir}/javadoc
endorsed.classpath=
excludes=
file.reference.AdvancedAchievements-4.0.2.jar=C:\\Users\\Risto\\Documents\\NetBeansProjects\\AdvancedAchievements\\target\\AdvancedAchievements-4.0.2.jar
file.reference.craftbukkit-1.11.2.jar=D:\\Minecraft Servers\\Buildtools\\craftbukkit-1.11.2.jar
file.reference.Factions.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Uusi kansio\\Factions.jar
file.reference.MassiveCore.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Uusi kansio\\MassiveCore.jar
file.reference.mcMMO.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Uusi kansio\\mcMMO.jar
file.reference.PlaceholderAPI.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Uusi kansio\\PlaceholderAPI.jar
file.reference.PlayerLogger_v1.0_.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Uusi kansio\\PlayerLogger[v1.0].jar
file.reference.SuperbVote-0.3.2.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Uusi kansio\\SuperbVote-0.3.2.jar
file.reference.Towny.jar=D:\\Downloads\\Towny.jar
file.reference.Vault.jar=D:\\Minecraft Servers\\TestServer\\plugins\\Vault.jar
includes=**
jar.compress=true
javac.classpath=\
${file.reference.OnTime.jar}:\
${file.reference.EssentialsX-2.0.1.jar}:\
${file.reference.Towny.jar}:\
${file.reference.Vault.jar}:\
${file.reference.Factions.jar}:\
${file.reference.MassiveCore.jar}:\
${file.reference.mcMMO.jar}:\
${file.reference.SuperbVote-0.3.2.jar}:\
${file.reference.PlaceholderAPI.jar}:\
${file.reference.AdvancedAchievements-4.0.2.jar}:\
${file.reference.PlayerLogger_v1.0_.jar}:\
${file.reference.craftbukkit-1.11.2.jar}
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.external.vm=true
javac.processorpath=\
${javac.classpath}
javac.source=1.8
javac.target=1.8
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}
javac.test.processorpath=\
${javac.test.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
main.class=player.analytics.main.Main
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
mkdist.disabled=false
platform.active=default_platform
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project.
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
# To set system properties for unit tests define test-sys-prop.name=value:
run.jvmargs=
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
source.encoding=UTF-8
src.dir=src
test.src.dir=test

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>PlanLite</name>
<source-roots>
<root id="src.dir"/>
</source-roots>
<test-roots>
<root id="test.src.dir"/>
</test-roots>
</data>
</configuration>
</project>

View File

@ -1,50 +0,0 @@
package com.djrapitops.planlite;
import org.bukkit.ChatColor;
/**
*
* @author Rsl1122
*/
public enum Phrase {
USERNAME_NOT_VALID(ChatColor.RED + "This Player doesn't exist."),
USERNAME_NOT_SEEN(ChatColor.RED + "This Player has not played on this server."),
USERNAME_NOT_KNOWN(ChatColor.RED + "Player not found from the database."),
COLOR_MAIN(ChatColor.DARK_GREEN),
COLOR_SEC(ChatColor.GRAY),
COLOR_TER(ChatColor.WHITE),
ARROWS_RIGHT("»"),
BALL(""),
ERROR_NO_HOOKS(ChatColor.RED + "[PlanLite] No Hooks enabled - Reload plugin!"),
COMMAND_SENDER_NOT_PLAYER(ChatColor.RED + "[PlanLite] This command can be only used as a player."),
COMMAND_REQUIRES_ARGUMENTS(ChatColor.RED + "[PlanLite] Command requires arguments."),
COMMAND_REQUIRES_ARGUMENTS_ONE(ChatColor.RED + "[PlanLite] Command requires one argument."),
COMMAND_NO_PERMISSION(ChatColor.RED + "[PlanLite] You do not have the required permmission.");
private final String text;
private final ChatColor color;
private Phrase(final String text) {
this.text = text;
this.color = null;
}
private Phrase(final ChatColor color) {
this.color = color;
this.text = "";
}
@Override
public String toString() {
return text;
}
/**
* @return Color of the COLOR_ENUM
*/
public ChatColor color() {
return color;
}
}

View File

@ -1,179 +0,0 @@
package com.djrapitops.planlite;
import com.djrapitops.planlite.api.API;
import com.djrapitops.planlite.command.hooks.EssentialsHook;
import com.djrapitops.planlite.command.hooks.FactionsHook;
import com.djrapitops.planlite.command.hooks.OnTimeHook;
import com.djrapitops.planlite.api.Hook;
import com.djrapitops.planlite.command.hooks.SuperbVoteHook;
import com.djrapitops.planlite.command.hooks.TownyHook;
import com.djrapitops.planlite.command.hooks.VaultHook;
import com.djrapitops.planlite.command.hooks.AdvancedAchievementsHook;
import com.djrapitops.planlite.command.hooks.BukkitDataHook;
import com.djrapitops.planlite.command.hooks.PlayerLoggerHook;
import com.djrapitops.planlite.command.utils.DataUtils;
import com.djrapitops.planlite.command.utils.MiscUtils;
import org.bukkit.plugin.java.JavaPlugin;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
public class PlanLite extends JavaPlugin {
private final Map<String, Hook> hooks;
private API api;
private final Map<String, Hook> extraHooks;
private PlanLiteCommand planCommand;
public PlanLite() {
this.hooks = new HashMap<>();
this.extraHooks = new HashMap<>();
}
public Map<String, Hook> getHooks() {
return this.hooks;
}
@Override
public void onEnable() {
getDataFolder().mkdirs();
getConfig().options().copyDefaults(true);
getConfig().options().header("PlanLite Config\n"
+ "debug - Errors are saved in errorlog.txt when they occur\n"
+ "visible - Plugin's data is accessable with /plan inspect command"
);
saveConfig();
List<String> hookFail = hookInit();
if (this.hooks.isEmpty()) {
logError("Found no plugins to get data (or config set to false). Disabling plugin..");
logToFile("MAIN\nNo Hooks found. Plugin Disabled.");
getServer().getPluginManager().disablePlugin(this);
return;
}
this.api = new API(this);
log(MiscUtils.checkVersion());
String loadedMsg = "Hooked into: ";
for (String key : this.hooks.keySet()) {
loadedMsg += ChatColor.GREEN + key + " ";
}
String failedMsg = "Not Hooked: ";
for (String string : hookFail) {
failedMsg += ChatColor.RED + string + " ";
}
Bukkit.getServer().getConsoleSender().sendMessage("[PlanLite] " + loadedMsg);
if (!hookFail.isEmpty()) {
Bukkit.getServer().getConsoleSender().sendMessage("[PlanLite] " + failedMsg);
}
planCommand = new PlanLiteCommand(this);
getCommand("planlite").setExecutor(planCommand);
log("Player Analytics Lite Enabled.");
}
public List<String> hookInit() {
this.hooks.clear();
List<String> hookFail = new ArrayList<>();
String[] pluginsArray = {"OnTime", "Essentials", "Towny", "Vault", "Factions", "SuperbVote",
"AdvancedAchievements", "BukkitData", "PlayerLogger"};
List<String> plugins = new ArrayList<>();
plugins.addAll(Arrays.asList(pluginsArray));
StringBuilder errors = new StringBuilder();
errors.append("MAIN-HOOKINIT\n");
plugins.parallelStream().forEach((pluginName) -> {
if (getConfig().getBoolean("visible." + pluginName.toLowerCase())) {
try {
String className = "com.djrapitops.planlite.command.hooks." + pluginName + "Hook";
Class<Hook> clazz = (Class<Hook>) Hook.class.forName(className);
this.hooks.put(pluginName, clazz.getConstructor(PlanLite.class).newInstance(this));
} catch (Exception | NoClassDefFoundError e) {
hookFail.add(pluginName);
errors.append("Failed to hook ").append(pluginName).append("\n").append(e);
errors.append("\n").append(e.getCause());
}
} else {
hookFail.add(ChatColor.YELLOW + pluginName);
}
});
if (!errors.toString().equals("MAIN-HOOKINIT\n")) {
logToFile(errors.toString());
}
for (String extraHook : this.extraHooks.keySet()) {
this.hooks.put(extraHook, this.extraHooks.get(extraHook));
}
return hookFail;
}
@Override
public void onDisable() {
log("Player Analytics Lite Disabled.");
}
public void log(String message) {
getLogger().info(message);
}
public void logError(String message) {
getLogger().severe(message);
}
public void logToFile(String message) {
if (getConfig().getBoolean("debug")) {
File folder = getDataFolder();
if (!folder.exists()) {
folder.mkdir();
}
File log = new File(getDataFolder(), "errorlog.txt");
try {
if (!log.exists()) {
log.createNewFile();
}
FileWriter fw = new FileWriter(log, true);
try (PrintWriter pw = new PrintWriter(fw)) {
pw.println(message + "\n");
pw.flush();
}
} catch (IOException e) {
logError("Failed to create log.txt file");
}
}
}
public API getAPI() {
return api;
}
/**
*
* @param name
* @param hook
*/
public void addExtraHook(String name, Hook hook) {
try {
this.extraHooks.put(name, hook);
this.hooks.put(name, hook);
log("Registered additional hook: " + name);
} catch (Exception | NoClassDefFoundError e) {
logToFile("Failed to hook " + name + "\n" + e);
}
}
public PlanLiteCommand getPlanCommand() {
return planCommand;
}
}

View File

@ -1,103 +0,0 @@
package com.djrapitops.planlite;
import com.djrapitops.planlite.command.CommandType;
import com.djrapitops.planlite.command.SubCommand;
import com.djrapitops.planlite.command.commands.AnalyzeCommand;
import com.djrapitops.planlite.command.commands.HelpCommand;
import com.djrapitops.planlite.command.commands.InfoCommand;
import com.djrapitops.planlite.command.commands.InspectCommand;
import com.djrapitops.planlite.command.commands.ReloadCommand;
import com.djrapitops.planlite.command.commands.SearchCommand;
import com.djrapitops.planlite.command.utils.MiscUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import java.util.List;
import java.util.ArrayList;
import org.bukkit.entity.Player;
public class PlanLiteCommand implements CommandExecutor {
private final List<SubCommand> commands;
public PlanLiteCommand(PlanLite plugin) {
commands = new ArrayList<>();
commands.add(new HelpCommand(plugin, this));
commands.add(new InspectCommand(plugin));
commands.add(new AnalyzeCommand(plugin));
commands.add(new SearchCommand(plugin));
commands.add(new InfoCommand(plugin));
commands.add(new ReloadCommand(plugin));
}
public List<SubCommand> getCommands() {
return this.commands;
}
public SubCommand getCommand(String name) {
for (SubCommand command : commands) {
String[] aliases = command.getName().split(",");
for (String alias : aliases) {
if (alias.equalsIgnoreCase(name)) {
return command;
}
}
}
return null;
}
private void sendDefaultCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
String command = "inspect";
if (args.length < 1) {
command = "help";
}
onCommand(sender, cmd, commandLabel, MiscUtils.mergeArrays(new String[]{command}, args));
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
if (args.length < 1) {
sendDefaultCommand(sender, cmd, commandLabel, args);
return true;
}
SubCommand command = getCommand(args[0]);
if (command == null) {
sendDefaultCommand(sender, cmd, commandLabel, args);
return true;
}
boolean console = !(sender instanceof Player);
if (!sender.hasPermission(command.getPermission())) {
sender.sendMessage(Phrase.COMMAND_NO_PERMISSION.toString());
return true;
}
if (console && args.length < 2 && command.getCommandType() == CommandType.CONSOLE_WITH_ARGUMENTS) {
sender.sendMessage(Phrase.COMMAND_REQUIRES_ARGUMENTS.toString());
return true;
}
if (console && command.getCommandType() == CommandType.PLAYER) {
sender.sendMessage(Phrase.COMMAND_SENDER_NOT_PLAYER.toString());
return true;
}
String[] realArgs = new String[args.length - 1];
for (int i = 1; i < args.length; i++) {
realArgs[i - 1] = args[i];
}
command.onCommand(sender, cmd, commandLabel, realArgs);
return true;
}
}

View File

@ -1,133 +0,0 @@
/*
* Copyright (c) 2015 Nate Mortensen
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.djrapitops.planlite;
import com.google.common.collect.ImmutableList;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.Callable;
public class UUIDFetcher implements Callable<Map<String, UUID>>
{
private static final double PROFILES_PER_REQUEST = 100;
private static final String PROFILE_URL = "https://api.mojang.com/profiles/minecraft";
private final JSONParser jsonParser = new JSONParser();
private final List<String> names;
private final boolean rateLimiting;
public UUIDFetcher( List<String> names, boolean rateLimiting )
{
this.names = ImmutableList.copyOf( names );
this.rateLimiting = rateLimiting;
}
public UUIDFetcher( List<String> names )
{
this( names, true );
}
public Map<String, UUID> call() throws Exception
{
Map<String, UUID> uuidMap = new HashMap<String, UUID>();
int requests = ( int ) Math.ceil( names.size() / PROFILES_PER_REQUEST );
for( int i = 0; i < requests; i++ )
{
HttpURLConnection connection = createConnection();
String body = JSONArray.toJSONString( names.subList( i * 100, Math.min( ( i + 1 ) * 100, names.size() ) ) );
writeBody( connection, body );
JSONArray array = ( JSONArray ) jsonParser.parse( new InputStreamReader( connection.getInputStream() ) );
for( Object profile : array )
{
JSONObject jsonProfile = ( JSONObject ) profile;
String id = ( String ) jsonProfile.get( "id" );
String name = ( String ) jsonProfile.get( "name" );
UUID uuid = UUIDFetcher.getUUID( id );
uuidMap.put( name, uuid );
}
if( rateLimiting && i != requests - 1 )
{
Thread.sleep( 100L );
}
}
return uuidMap;
}
private static void writeBody( HttpURLConnection connection, String body ) throws Exception
{
OutputStream stream = connection.getOutputStream();
stream.write( body.getBytes() );
stream.flush();
stream.close();
}
private static HttpURLConnection createConnection() throws Exception
{
URL url = new URL( PROFILE_URL );
HttpURLConnection connection = ( HttpURLConnection ) url.openConnection();
connection.setRequestMethod( "POST" );
connection.setRequestProperty( "Content-Type", "application/json" );
connection.setUseCaches( false );
connection.setDoInput( true );
connection.setDoOutput( true );
return connection;
}
private static UUID getUUID( String id )
{
return UUID.fromString( id.substring( 0, 8 ) + "-" + id.substring( 8, 12 ) + "-" + id.substring( 12, 16 ) + "-" + id.substring( 16, 20 ) + "-" + id.substring( 20, 32 ) );
}
public static byte[] toBytes( UUID uuid )
{
ByteBuffer byteBuffer = ByteBuffer.wrap( new byte[16] );
byteBuffer.putLong( uuid.getMostSignificantBits() );
byteBuffer.putLong( uuid.getLeastSignificantBits() );
return byteBuffer.array();
}
public static UUID fromBytes( byte[] array )
{
if( array.length != 16 )
{
throw new IllegalArgumentException( "Illegal byte array length: " + array.length );
}
ByteBuffer byteBuffer = ByteBuffer.wrap( array );
long mostSignificant = byteBuffer.getLong();
long leastSignificant = byteBuffer.getLong();
return new UUID( mostSignificant, leastSignificant );
}
public static UUID getUUIDOf( String name ) throws Exception
{
return new UUIDFetcher( Arrays.asList( name ) ).call().get( name );
}
}

View File

@ -1,112 +0,0 @@
package com.djrapitops.planlite.api;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.command.utils.DataFormatUtils;
import com.djrapitops.planlite.command.utils.DataUtils;
import java.util.Date;
import java.util.HashMap;
public class API {
private PlanLite plugin;
public API(PlanLite plugin) {
this.plugin = plugin;
}
public boolean getDebug() {
return plugin.getConfig().getBoolean("debug");
}
public boolean getVisibleEssentials() {
return plugin.getConfig().getBoolean("visible.essentials");
}
public boolean getVisibleOnTime() {
return plugin.getConfig().getBoolean("visible.ontime");
}
public boolean getVisibleFactions() {
return plugin.getConfig().getBoolean("visible.factions");
}
public boolean getVisibleSuperbVote() {
return plugin.getConfig().getBoolean("visible.superbvote");
}
public boolean getVisibleTowny() {
return plugin.getConfig().getBoolean("visible.towny");
}
public boolean getVisibleVault() {
return plugin.getConfig().getBoolean("visible.vault");
}
public boolean getVisibleAdvancedAchievements() {
return plugin.getConfig().getBoolean("visible.advancedachievements");
}
public boolean getVisiblePlaceholderAPI() {
return plugin.getConfig().getBoolean("visible.placeholderapi");
}
public HashMap<String, DataPoint> getData(String playerName, boolean dataPoint) {
return DataFormatUtils.removeExtraDataPoints(DataUtils.getData(false, playerName));
}
// Please move to DataPoint system as soon as possible
@Deprecated
public HashMap<String, String> getData(String playerName) {
HashMap<String, String> data = new HashMap<>();
HashMap<String, DataPoint> dataWPoints = getData(playerName, true);
dataWPoints.keySet().parallelStream().forEach((key) -> {
data.put(key, dataWPoints.get(key).data());
});
return data;
}
public HashMap<String, DataPoint> getAllData(String playerName, boolean dataPoint) {
return DataFormatUtils.removeExtraDataPoints(DataUtils.getData(true, playerName));
}
// Please move to DataPoint system as soon as possible
@Deprecated
public HashMap<String, String> getAllData(String playerName) {
HashMap<String, String> data = new HashMap<>();
HashMap<String, DataPoint> dataWPoints = getAllData(playerName, true);
dataWPoints.keySet().parallelStream().forEach((key) -> {
data.put(key, dataWPoints.get(key).data());
});
return data;
}
public HashMap<String, DataPoint> transformOldDataFormat(HashMap<String, String> oldData) {
HashMap<String, DataPoint> data = new HashMap<>();
for (String key : oldData.keySet()) {
data.put(key, new DataPoint(oldData.get(key), DataType.OTHER));
}
return data;
}
// use (new Date) on after parameter for time since moment to now
public static String formatTimeSinceDate(Date before, Date after) {
return DataFormatUtils.formatTimeAmountSinceDate(before, after);
}
// use (new Date) on after parameter for time since moment to now
public static String formatTimeSinceString(String before, Date after) {
return DataFormatUtils.formatTimeAmountSinceString(before, after);
}
public static String formatTimeAmount(String timeInMs) {
return DataFormatUtils.formatTimeAmount(timeInMs);
}
public static String formatTimeStamp(String timeInMs) {
return DataFormatUtils.formatTimeStamp(timeInMs);
}
public void addExtraHook(String name, Hook hook) {
plugin.addExtraHook(name, hook);
}
}

View File

@ -1,26 +0,0 @@
package com.djrapitops.planlite.api;
public class DataPoint {
private String data;
private final DataType type;
public DataPoint(String data, DataType type) {
this.data = data;
this.type = type;
}
public String data() {
return data;
}
public void setData(String data) {
this.data = data;
}
public DataType type() {
return type;
}
}

View File

@ -1,20 +0,0 @@
package com.djrapitops.planlite.api;
public enum DataType {
STRING, // Any preformatted data & words
TIME, // Long in milliseconds
TIME_TIMESTAMP, // Long in milliseconds since Epoch Date 1970, will be subtracted from current time.
DATE, // Long in milliseconds since Epoch Date 1970
LOCATION, // X:# Y:# Z:#
AMOUNT, // Number
AMOUNT_WITH_MAX, // Example: 41 / 44
AMOUNT_WITH_LETTERS, // Example $50
BOOLEAN, // true/false
PERCENT, // Example 50%
OTHER, // Any data not listed here - will not be analyzed
MAP, // An image presentation of array in string format, no format yet
LINK, // Link to a webpage
HEATMAP, // An image presentation of array in string format, no format yet
DEPRECATED // Old data that has been rendered useless
}

View File

@ -1,16 +0,0 @@
package com.djrapitops.planlite.api;
import com.djrapitops.planlite.PlanLite;
import java.util.HashMap;
public interface Hook {
public HashMap<String, DataPoint> getData(String player) throws Exception;
public HashMap<String, DataPoint> getAllData(String player) throws Exception;
public default void setPlan(PlanLite plan) throws Exception {
}
}

View File

@ -1,8 +0,0 @@
package com.djrapitops.planlite.command;
public enum CommandType
{
CONSOLE,
PLAYER,
CONSOLE_WITH_ARGUMENTS
}

View File

@ -1,62 +0,0 @@
package com.djrapitops.planlite.command;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public abstract class SubCommand
{
private final String name;
private final String permission;
private final String usage;
// private final Phrase description;
private final CommandType commandType;
public SubCommand( String name, String permission, String usage, CommandType commandType )
{
this.name = name;
this.permission = permission;
this.usage = usage;
// this.description = description;
this.commandType = commandType;
}
public String getFirstName()
{
return name.split( "," )[0];
}
public String getName()
{
return name;
}
public String getPermission()
{
return permission;
}
public String getUsage()
{
return usage;
}
// public Phrase getDescription()
// {
// return description;
// }
public CommandType getCommandType()
{
return commandType;
}
public abstract boolean onCommand( CommandSender sender, Command cmd, String commandLabel, String[] args );
}

View File

@ -1,76 +0,0 @@
package com.djrapitops.planlite.command.commands;
import com.djrapitops.planlite.Phrase;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.command.CommandType;
import com.djrapitops.planlite.command.SubCommand;
import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.command.utils.DataFormatUtils;
import com.djrapitops.planlite.command.utils.DataUtils;
import com.djrapitops.planlite.command.utils.Analysis;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class AnalyzeCommand extends SubCommand {
private PlanLite plugin;
private HashMap<UUID, HashMap<String, DataPoint>> playerData;
private HashMap<String, DataPoint> analyzedPlayerdata;
private Date refreshDate;
public AnalyzeCommand(PlanLite plugin) {
super("analyze", "planlite.analyze", "Analyze data of players, /planlite analyze [-refresh]", CommandType.CONSOLE);
this.plugin = plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
ChatColor oColor = Phrase.COLOR_MAIN.color();
ChatColor tColor = Phrase.COLOR_SEC.color();
ChatColor hColor = Phrase.COLOR_TER.color();
for (String arg : args) {
if (arg.toLowerCase().equals("-refresh")) {
if (sender.hasPermission("planlite.analyze.refresh") || !(sender instanceof Player)) {
refreshAnalysisData(sender);
} else {
sender.sendMessage(Phrase.COMMAND_NO_PERMISSION.toString());
}
}
}
if (this.playerData == null || this.refreshDate == null || this.analyzedPlayerdata == null || DataFormatUtils.formatTimeAmountSinceDate(refreshDate, new Date()).contains("m")) {
refreshAnalysisData(sender);
}
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString() + oColor + " Player Analytics Lite | Analysis results - refreshed "
+ DataFormatUtils.formatTimeAmountSinceDate(refreshDate, new Date()) + " ago");
List<String[]> dataList = DataFormatUtils.turnDataHashMapToSortedListOfArrays(analyzedPlayerdata);
sender.sendMessage(hColor + Phrase.BALL.toString() + tColor + " Averages for " + hColor + this.playerData.size() + tColor + " player(s)");
for (String[] dataString : dataList) {
sender.sendMessage(" " + tColor + Phrase.BALL + oColor+" "
+ dataString[0].charAt(4) + dataString[0].toLowerCase().substring(5) + ": " + tColor + dataString[1]);
}
sender.sendMessage(hColor + Phrase.BALL.toString());
return true;
}
private void refreshAnalysisData(CommandSender sender) {
ChatColor oColor = Phrase.COLOR_MAIN.color();
ChatColor tColor = Phrase.COLOR_SEC.color();
ChatColor hColor = Phrase.COLOR_TER.color();
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString() + oColor + " Player Analytics Lite " + tColor + "| "
+ "Refreshing playerData, this might take a while..");
this.playerData = DataUtils.getTotalData(DataUtils.getMatchingDisplaynames(true));
this.refreshDate = new Date();
this.analyzedPlayerdata = Analysis.analyze(this.playerData);
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString() + oColor + " Player Analytics Lite " + tColor + "| "
+ "Refreshed, took " + DataFormatUtils.formatTimeAmountSinceDate(refreshDate, new Date()));
}
}

View File

@ -1,55 +0,0 @@
package com.djrapitops.planlite.command.commands;
import com.djrapitops.planlite.Phrase;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.PlanLiteCommand;
import com.djrapitops.planlite.command.CommandType;
import com.djrapitops.planlite.command.SubCommand;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class HelpCommand extends SubCommand {
private final PlanLite plugin;
private final PlanLiteCommand command;
public HelpCommand(PlanLite plugin, PlanLiteCommand command) {
super("help,?", "planlite.?", "Show command list.", CommandType.CONSOLE);
this.plugin = plugin;
this.command = command;
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
ChatColor oColor = Phrase.COLOR_MAIN.color();
ChatColor tColor = Phrase.COLOR_SEC.color();
ChatColor hColor = Phrase.COLOR_TER.color();
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString() + oColor + " Player Analytics Lite");
for (SubCommand command : this.command.getCommands()) {
if (command.getName().equalsIgnoreCase(getName())) {
continue;
}
if (!sender.hasPermission(command.getPermission())) {
continue;
}
if (!(sender instanceof Player) && command.getCommandType() == CommandType.PLAYER) {
continue;
}
sender.sendMessage(" "+Phrase.BALL+oColor + " /planlite " + command.getFirstName() + tColor + " " + command.getUsage());
}
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString());
return true;
}
}

View File

@ -1,37 +0,0 @@
package com.djrapitops.planlite.command.commands;
import com.djrapitops.planlite.Phrase;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.command.CommandType;
import com.djrapitops.planlite.command.SubCommand;
import com.djrapitops.planlite.command.utils.MiscUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class InfoCommand extends SubCommand {
private PlanLite plugin;
public InfoCommand(PlanLite plugin) {
super("info", "planlite.info", "View version and enabled hooks", CommandType.CONSOLE);
this.plugin = plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
plugin.reloadConfig();
ChatColor oColor = Phrase.COLOR_MAIN.color();
ChatColor tColor = Phrase.COLOR_SEC.color();
ChatColor hColor = Phrase.COLOR_TER.color();
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString() + oColor + " Player Analytics Lite | Info");
sender.sendMessage(oColor+"Version: "+tColor+plugin.getDescription().getVersion());
sender.sendMessage(tColor+MiscUtils.checkVersion());
sender.sendMessage(oColor+"Enabled Hooks: "+tColor+plugin.getHooks().keySet());
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString());
return true;
}
}

View File

@ -1,93 +0,0 @@
package com.djrapitops.planlite.command.commands;
import com.djrapitops.planlite.Phrase;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.UUIDFetcher;
import com.djrapitops.planlite.command.CommandType;
import com.djrapitops.planlite.command.SubCommand;
import com.djrapitops.planlite.command.utils.DataFormatUtils;
import com.djrapitops.planlite.command.utils.DataUtils;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.api.DataType;
import java.util.UUID;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class InspectCommand extends SubCommand {
private PlanLite plugin;
public InspectCommand(PlanLite plugin) {
super("inspect", "planlite.inspect", "Inspect data /planlite <player> [-a, -r].", CommandType.CONSOLE_WITH_ARGUMENTS);
this.plugin = plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
String playerName = DataUtils.getPlayerDisplayname(args, sender);
UUID uuid;
try {
uuid = UUIDFetcher.getUUIDOf(playerName);
if (uuid == null) {
throw new Exception("Username doesn't exist.");
}
} catch (Exception e) {
sender.sendMessage(Phrase.USERNAME_NOT_VALID.toString());
return true;
}
OfflinePlayer p = getOfflinePlayer(uuid);
if (!p.hasPlayedBefore()) {
sender.sendMessage(Phrase.USERNAME_NOT_SEEN.toString());
return true;
}
if (this.plugin.getHooks().isEmpty()) {
sender.sendMessage(Phrase.ERROR_NO_HOOKS.toString());
return true;
}
boolean allData = false;
boolean format = true;
for (String arg : args) {
if (arg.toLowerCase().equals("-a")) {
allData = true;
}
if (arg.toLowerCase().equals("-r")) {
format = false;
}
}
Date refreshDate = new Date();
HashMap<String, DataPoint> data = DataUtils.getData(allData, playerName);
if (format && !data.isEmpty()) {
data = DataFormatUtils.removeExtraDataPoints(data);
}
if (data.isEmpty()) {
data.put("ERR-NO RESULTS", new DataPoint("No results were found.", DataType.OTHER));
plugin.logToFile("INSPECT-Results\nNo results were found for: " + playerName);
}
List<String[]> dataList = DataFormatUtils.turnDataHashMapToSortedListOfArrays(data);
ChatColor oColor = Phrase.COLOR_MAIN.color();
ChatColor tColor = Phrase.COLOR_SEC.color();
ChatColor hColor = Phrase.COLOR_TER.color();
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString() + oColor + " Player Analytics Lite | Inspect results: " + playerName);
for (String[] dataString : dataList) {
sender.sendMessage(" " + tColor + Phrase.BALL + oColor+" "+ dataString[0].charAt(4) + dataString[0].toLowerCase().substring(5) + ": " + tColor + dataString[1]);
}
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString());
return true;
}
}

View File

@ -1,47 +0,0 @@
package com.djrapitops.planlite.command.commands;
import com.djrapitops.planlite.Phrase;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.command.CommandType;
import com.djrapitops.planlite.command.SubCommand;
import com.djrapitops.planlite.command.utils.DataUtils;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
public class ReloadCommand extends SubCommand {
private PlanLite plugin;
public ReloadCommand(PlanLite plugin) {
super("reload", "planlite.reload", "Reload plugin config & Hooks", CommandType.CONSOLE);
this.plugin = plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
plugin.reloadConfig();
List<String> hookFail = plugin.hookInit();
ChatColor oColor = Phrase.COLOR_MAIN.color();
ChatColor tColor = Phrase.COLOR_SEC.color();
ChatColor hColor = Phrase.COLOR_TER.color();
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString() + oColor + " Player Analytics Lite | Config & Hooks reloaded.");
String loadedMsg = " Hooked into: ";
for (String key : plugin.getHooks().keySet()) {
loadedMsg += ChatColor.GREEN + key + " ";
}
String failedMsg = " Not Hooked: ";
for (String string : hookFail) {
failedMsg += ChatColor.RED + string + " ";
}
sender.sendMessage(tColor + loadedMsg);
if (!hookFail.isEmpty()) {
sender.sendMessage(tColor + failedMsg);
}
return true;
}
}

View File

@ -1,89 +0,0 @@
package com.djrapitops.planlite.command.commands;
import com.djrapitops.planlite.Phrase;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.command.CommandType;
import com.djrapitops.planlite.command.SubCommand;
import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.api.DataType;
import com.djrapitops.planlite.command.utils.DataFormatUtils;
import com.djrapitops.planlite.command.utils.DataUtils;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import static org.bukkit.Bukkit.getOfflinePlayer;
public class SearchCommand extends SubCommand {
private final PlanLite plugin;
public SearchCommand(PlanLite plugin) {
super("search", "planlite.search", "Inspect specific data /planlite <search terms> [-p]", CommandType.CONSOLE_WITH_ARGUMENTS);
this.plugin = plugin;
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
boolean playerFirst = false;
for (String arg : args) {
if (arg.equals("-p")) {
playerFirst = true;
}
}
Set<OfflinePlayer> matchingPlayers;
if (playerFirst) {
String[] playername = new String[1];
playername[0] = args[0];
matchingPlayers = DataUtils.getMatchingDisplaynames(playername, sender, false);
} else {
matchingPlayers = DataUtils.getMatchingDisplaynames(args, sender, false);
}
args = DataFormatUtils.parseSearchArgs(args);
if (this.plugin.getHooks().isEmpty()) {
sender.sendMessage(Phrase.ERROR_NO_HOOKS.toString());
return true;
}
HashMap<UUID, HashMap<String, DataPoint>> data = DataUtils.getTotalData(matchingPlayers);
Date refreshDate = new Date();
HashMap<String, List<String[]>> dataLists = new HashMap<>();
for (UUID key : data.keySet()) {
OfflinePlayer p = getOfflinePlayer(key);
HashMap<String, DataPoint> dataMap = data.get(key);
if (!dataMap.isEmpty()) {
dataMap = DataFormatUtils.removeExtraDataPointsSearch(dataMap, args);
}
if (dataMap.isEmpty()) {
dataMap.put("ERR-NO RESULTS", new DataPoint("No results were found.", DataType.OTHER));
plugin.logToFile("SEARCH-Results\nNo results were found for: " + p.getName() + Arrays.toString(args));
}
dataLists.put(p.getName(), DataFormatUtils.turnDataHashMapToSortedListOfArrays(dataMap));
}
ChatColor oColor = Phrase.COLOR_MAIN.color();
ChatColor tColor = Phrase.COLOR_SEC.color();
ChatColor hColor = Phrase.COLOR_TER.color();
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString() + oColor + " Player Analytics Lite | Search results: " + Arrays.toString(args));
if (dataLists.isEmpty()) {
sender.sendMessage(" " + tColor + Phrase.BALL + oColor + " No results.");
} else {
for (String playerName : dataLists.keySet()) {
sender.sendMessage(tColor + "Matching player: " + hColor + playerName);
for (String[] dataString : dataLists.get(playerName)) {
sender.sendMessage(" " + tColor + Phrase.BALL + oColor + " "
+ dataString[0].charAt(4) + dataString[0].toLowerCase().substring(5) + ": " + tColor + dataString[1]);
}
}
}
sender.sendMessage(hColor + Phrase.ARROWS_RIGHT.toString());
return true;
}
}

View File

@ -1,107 +0,0 @@
package com.djrapitops.planlite.command.hooks;
import com.djrapitops.planlite.api.Hook;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.UUIDFetcher;
import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.api.DataType;
import com.hm.achievement.AdvancedAchievements;
import com.hm.achievement.category.MultipleAchievements;
import com.hm.achievement.category.NormalAchievements;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Optional;
import java.util.UUID;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
import static org.bukkit.Bukkit.getOfflinePlayer;
public class AdvancedAchievementsHook implements Hook {
private PlanLite plugin;
private AdvancedAchievements aAPlugin;
private int totalAchievements;
private boolean usingUUID;
public AdvancedAchievementsHook(PlanLite plugin) throws Exception, NoClassDefFoundError {
this.plugin = plugin;
this.aAPlugin = getPlugin(AdvancedAchievements.class);
// Version was important because 4.0.3 added required method for Offline players
String[] aAVersion = aAPlugin.getDescription().getVersion().split("\\.");
try {
double versionNumber = Double.parseDouble(aAVersion[0] + "." + aAVersion[1] + aAVersion[2]);
if (versionNumber >= 4.03) {
this.usingUUID = true;
} else {
this.usingUUID = false;
plugin.logError("Advanced Achievements 4.0.3 or above required for Offline players");
}
} catch (Exception e) {
// Some versions were formatted with two numbers
try {
double versionNumber = Double.parseDouble(aAVersion[0] + "." + aAVersion[1]);
if (versionNumber >= 4.03) {
this.usingUUID = true;
} else {
this.usingUUID = false;
plugin.logError("Advanced Achievements 4.0.3 or above required for Offline players");
}
} catch (Exception e2) {
plugin.logToFile("AAHOOK\nError getting version number.\n" + e2 + "\n" + e + "\n"
+ aAPlugin.getDescription().getVersion() + "\n" + Arrays.toString(aAVersion));
}
}
// Get total number of Achievements
for (NormalAchievements category : NormalAchievements.values()) {
String categoryName = category.toString();
if (aAPlugin.getDisabledCategorySet().contains(categoryName)) {
continue;
}
totalAchievements += aAPlugin.getPluginConfig().getConfigurationSection(categoryName).getKeys(false).size();
}
for (MultipleAchievements category : MultipleAchievements.values()) {
String categoryName = category.toString();
if (aAPlugin.getDisabledCategorySet().contains(categoryName)) {
continue;
}
for (String item : aAPlugin.getPluginConfig().getConfigurationSection(categoryName).getKeys(false)) {
totalAchievements += aAPlugin.getPluginConfig().getConfigurationSection(categoryName + '.' + item)
.getKeys(false).size();
}
}
if (!aAPlugin.getDisabledCategorySet().contains("Commands")) {
totalAchievements += aAPlugin.getPluginConfig().getConfigurationSection("Commands").getKeys(false).size();
}
}
@Override
public HashMap<String, DataPoint> getData(String player) throws Exception {
HashMap<String, DataPoint> data = new HashMap<>();
try {
UUID uuid = UUIDFetcher.getUUIDOf(player);
OfflinePlayer p = getOfflinePlayer(uuid);
if (p.hasPlayedBefore()) {
if (totalAchievements > 0) {
if (this.usingUUID) {
data.put("AAC-ACHIEVEMENTS", new DataPoint(aAPlugin.getDb().getPlayerAchievementsAmount(uuid.toString()) + " / " + totalAchievements, DataType.AMOUNT_WITH_MAX));
} else {
plugin.log("You're using outdated version of AdvancedAchievements!");
}
}
}
} catch (IllegalArgumentException e) {
}
return data;
}
@Override
public HashMap<String, DataPoint> getAllData(String player) throws Exception {
return getData(player);
}
public boolean isUsingUUID() {
return usingUUID;
}
}

View File

@ -1,59 +0,0 @@
package com.djrapitops.planlite.command.hooks;
import com.djrapitops.planlite.api.Hook;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.UUIDFetcher;
import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.api.DataType;
import com.google.common.base.Optional;
import java.util.HashMap;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
public class BukkitDataHook implements Hook {
private final PlanLite plugin;
public BukkitDataHook(PlanLite p) throws Exception {
plugin = p;
}
@Override
public HashMap<String, DataPoint> getData(String player) throws Exception {
HashMap<String, DataPoint> data = new HashMap<>();
try {
OfflinePlayer p = getOfflinePlayer(UUIDFetcher.getUUIDOf(player));
if (p.hasPlayedBefore()) {
data.put("BUK-REGISTERED", new DataPoint("" + p.getFirstPlayed(), DataType.DATE));
data.put("BUK-LAST LOGIN", new DataPoint("" + p.getLastPlayed(), DataType.DATE));
if (p.isBanned()) {
data.put("BUK-BANNED", new DataPoint("" + p.isBanned(), DataType.BOOLEAN));
}
data.put("BUK-ONLINE", new DataPoint("" + p.isOnline(), DataType.BOOLEAN));
}
} catch (IllegalArgumentException | NullPointerException e) {
}
return data;
}
@Override
public HashMap<String, DataPoint> getAllData(String player) throws Exception {
HashMap<String, DataPoint> data = new HashMap<>();
data.putAll(getData(player));
try {
OfflinePlayer p = getOfflinePlayer(UUIDFetcher.getUUIDOf(player));
if (p.hasPlayedBefore()) {
Location loc = p.getBedSpawnLocation();
if (Optional.of(loc).isPresent()) {
data.put("BUK-BED LOCATION WORLD", new DataPoint(loc.getWorld().getName(), DataType.STRING));
data.put("BUK-BED LOCATION", new DataPoint(" X:" + loc.getBlockX() + " Y:" + loc.getBlockY() + " Z:" + loc.getBlockZ(), DataType.LOCATION));
}
data.put("BUK-UUID", new DataPoint("" + p.getUniqueId(), DataType.OTHER));
}
} catch (IllegalArgumentException | NullPointerException e) {
}
return data;
}
}

View File

@ -1,103 +0,0 @@
package com.djrapitops.planlite.command.hooks;
import com.djrapitops.planlite.api.Hook;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.UUIDFetcher;
import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.api.DataType;
import java.util.HashMap;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.User;
import net.ess3.api.IEssentials;
import com.earth2me.essentials.craftbukkit.BanLookup;
import java.util.Optional;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
import org.bukkit.BanList;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
public class EssentialsHook implements Hook {
private IEssentials ess;
private final PlanLite plugin;
public EssentialsHook(PlanLite p) throws Exception {
this.ess = getPlugin(Essentials.class);
this.plugin = p;
}
// Gets data with Essentials own User methods
@Override
public HashMap<String, DataPoint> getData(String player) throws Exception {
HashMap<String, DataPoint> data = new HashMap<>();
try {
User user = this.ess.getOfflineUser(player);
OfflinePlayer p = getOfflinePlayer(UUIDFetcher.getUUIDOf(player));
if (p.hasPlayedBefore()) {
if (Optional.of(user).isPresent()) {
if (this.ess.getServer().getBanList(BanList.Type.IP).isBanned(player)
|| BanLookup.isBanned(this.ess, player)) {
data.put("ESS-BANNED", new DataPoint("" + true, DataType.BOOLEAN));
data.put("ESS-BAN REASON", new DataPoint("" + BanLookup.getBanEntry(this.ess, player).getReason(), DataType.STRING));
}
if (user.isJailed()) {
data.put("ESS-JAILED", new DataPoint("" + true, DataType.BOOLEAN));
data.put("ESS-JAIL TIME", new DataPoint("" + user.getJailTimeout(), DataType.TIME_TIMESTAMP));
}
if (user.isMuted()) {
data.put("ESS-MUTED", new DataPoint("" + true, DataType.BOOLEAN));
data.put("ESS-MUTE TIME", new DataPoint("" + user.getMuteTimeout(), DataType.TIME_TIMESTAMP));
}
try {
if (user.isReachable()) {
Location loc = user.getLocation();
data.put("ESS-LOCATION WORLD", new DataPoint(loc.getWorld().getName(), DataType.STRING));
data.put("ESS-LOCATION", new DataPoint(" X:" + loc.getBlockX() + " Y:" + loc.getBlockY() + " Z:" + loc.getBlockZ(), DataType.LOCATION));
} else {
Location loc = user.getLogoutLocation();
data.put("ESS-LOCATION WORLD", new DataPoint(loc.getWorld().getName(), DataType.STRING));
data.put("ESS-LOCATION", new DataPoint("X:" + loc.getBlockX() + " Y:" + loc.getBlockY() + " Z:" + loc.getBlockZ(), DataType.LOCATION));
}
} catch (Exception e) {
this.plugin.logToFile("ESSENTIALSHOOK\n" + e + "\n" + e.getMessage());
}
data.put("ESS-NICKNAME", new DataPoint("" + user.getDisplayName(), DataType.STRING));
if (user.isReachable()) {
data.put("ESS-ONLINE SINCE", new DataPoint("" + user.getLastLogin(), DataType.TIME_TIMESTAMP));
} else {
data.put("ESS-OFFLINE SINCE", new DataPoint("" + user.getLastLogout(), DataType.TIME_TIMESTAMP));
}
}
}
} catch (IllegalArgumentException e) {
}
return data;
}
@Override
public HashMap<String, DataPoint> getAllData(String player) throws Exception {
HashMap<String, DataPoint> data = new HashMap<>();
data.putAll(getData(player));
try {
OfflinePlayer p = getOfflinePlayer(UUIDFetcher.getUUIDOf(player));
if (p.hasPlayedBefore()) {
User user = this.ess.getOfflineUser(player);
if (Optional.of(user).isPresent()) {
data.put("ESS-UUID", new DataPoint("" + user.getBase().getUniqueId().toString(), DataType.OTHER));
data.put("ESS-HEALTH", new DataPoint("" + user.getBase().getHealth(), DataType.AMOUNT));
data.put("ESS-HUNGER", new DataPoint("" + user.getBase().getFoodLevel(), DataType.AMOUNT));
data.put("ESS-XP LEVEL", new DataPoint("" + user.getBase().getLevel(), DataType.AMOUNT));
data.put("ESS-OPPED", new DataPoint("" + user.getBase().isOp(), DataType.BOOLEAN));
data.put("ESS-FLYING", new DataPoint("" + user.getBase().isFlying(), DataType.BOOLEAN));
}
}
} catch (IllegalArgumentException e) {
}
return data;
}
}

View File

@ -1,56 +0,0 @@
package com.djrapitops.planlite.command.hooks;
import com.djrapitops.planlite.api.Hook;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.UUIDFetcher;
import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.api.DataType;
import com.massivecraft.factions.Factions;
import java.util.HashMap;
import com.massivecraft.factions.entity.MPlayer;
import java.util.UUID;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
import static org.bukkit.Bukkit.getOfflinePlayer;
public class FactionsHook implements Hook {
private PlanLite plugin;
private Factions factions;
public FactionsHook(PlanLite plugin) throws Exception {
this.plugin = plugin;
this.factions = getPlugin(Factions.class);
}
@Override
public HashMap<String, DataPoint> getData(String player) throws Exception {
HashMap<String, DataPoint> data = new HashMap<>();
try {
MPlayer mplayer;
UUID uuid = UUIDFetcher.getUUIDOf(player);
OfflinePlayer p = getOfflinePlayer(uuid);
if (p.hasPlayedBefore()) {
mplayer = MPlayer.get(uuid);
if (mplayer.hasFaction()) {
data.put("FAC-FACTION", new DataPoint(mplayer.getFactionName(), DataType.STRING));
if (mplayer.hasTitle()) {
data.put("FAC-TITLE", new DataPoint(mplayer.getTitle(), DataType.STRING));
}
}
data.put("FAC-POWER", new DataPoint(mplayer.getPowerRounded() + " / " + mplayer.getPowerMax(), DataType.AMOUNT_WITH_MAX));
data.put("FAC-POWER PER HOUR", new DataPoint("" + mplayer.getPowerPerHour(), DataType.AMOUNT));
data.put("FAC-POWER PER DEATH", new DataPoint("" + mplayer.getPowerPerDeath(), DataType.AMOUNT));
}
} catch (IllegalArgumentException e) {
}
return data;
}
@Override
public HashMap<String, DataPoint> getAllData(String player) throws Exception {
return getData(player);
}
}

View File

@ -1,53 +0,0 @@
package com.djrapitops.planlite.command.hooks;
import com.djrapitops.planlite.api.Hook;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.UUIDFetcher;
import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.api.DataType;
import java.util.HashMap;
import me.edge209.OnTime.OnTimeAPI;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
public class OnTimeHook implements Hook {
private PlanLite plugin;
public OnTimeHook(PlanLite plugin) throws Exception {
this.plugin = plugin;
if (OnTimeAPI.data.LASTLOGIN == null) {
throw new Exception("Ontime not installed.");
}
}
@Override
public HashMap<String, DataPoint> getData(String player) throws Exception {
HashMap<String, DataPoint> data = new HashMap<>();
try {
OfflinePlayer p = getOfflinePlayer(UUIDFetcher.getUUIDOf(player));
if (p.hasPlayedBefore()) {
try {
data.put("ONT-LAST LOGIN", new DataPoint("" + OnTimeAPI.getPlayerTimeData(player, OnTimeAPI.data.LASTLOGIN), DataType.DEPRECATED));
data.put("ONT-TOTAL PLAY", new DataPoint("" + OnTimeAPI.getPlayerTimeData(player, OnTimeAPI.data.TOTALPLAY), DataType.TIME));
data.put("ONT-TOTAL VOTES", new DataPoint("" + OnTimeAPI.getPlayerTimeData(player, OnTimeAPI.data.TOTALVOTE), DataType.AMOUNT));
data.put("ONT-TOTAL REFERRED", new DataPoint("" + OnTimeAPI.getPlayerTimeData(player, OnTimeAPI.data.TOTALREFER), DataType.AMOUNT));
} catch (NoClassDefFoundError e) {
plugin.logToFile("ONTIME HOOK ERROR"
+ "\nOntimeHook enabled but failing, could not get data."
+ "\n" + e
+ "\n" + e.getMessage());
}
}
} catch (IllegalArgumentException e) {
}
return data;
}
@Override
public HashMap<String, DataPoint> getAllData(String player) throws Exception {
return getData(player);
}
}

View File

@ -1,64 +0,0 @@
package com.djrapitops.planlite.command.hooks;
import com.djrapitops.planlite.api.Hook;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.UUIDFetcher;
import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.api.DataType;
import java.util.HashMap;
import java.util.UUID;
import me.BadBones69.Logger.SettingsManager;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
import org.bukkit.configuration.file.FileConfiguration;
import static org.bukkit.Bukkit.getOfflinePlayer;
public class PlayerLoggerHook implements Hook {
private PlanLite plugin;
public PlayerLoggerHook(PlanLite plugin) throws Exception, NoClassDefFoundError {
this.plugin = plugin;
SettingsManager.getInstance();
}
@Override
public HashMap<String, DataPoint> getData(String player) throws Exception {
HashMap<String, DataPoint> data = new HashMap<>();
FileConfiguration file = SettingsManager.getInstance().getData();
try {
UUID uuid = UUIDFetcher.getUUIDOf(player);
OfflinePlayer p = getOfflinePlayer(uuid);
if (p.hasPlayedBefore()) {
data.put("PLG-REGISTERED", new DataPoint(file.getString("Players." + uuid + ".DateJoined"), DataType.DEPRECATED));
data.put("PLG-LAST LOGIN", new DataPoint(file.getString("Players." + uuid + ".LastSeen"), DataType.DEPRECATED));
data.put("PLG-TIMES JOINED", new DataPoint(file.getString("Players." + uuid + ".TimePlayed"), DataType.AMOUNT));
data.put("PLG-KILLS", new DataPoint(file.getString("Players." + uuid + ".Kills"), DataType.AMOUNT));
data.put("PLG-DEATHS", new DataPoint(file.getString("Players." + uuid + ".Deaths"), DataType.AMOUNT));
data.put("PLG-TIMES KICKED", new DataPoint(file.getString("Players." + uuid + ".Kicks"), DataType.AMOUNT));
}
} catch (IllegalArgumentException e) {
}
return data;
}
@Override
public HashMap<String, DataPoint> getAllData(String player) throws Exception {
HashMap<String, DataPoint> data = new HashMap<>();
data.putAll(getData(player));
try {
UUID uuid = UUIDFetcher.getUUIDOf(player);
OfflinePlayer p = getOfflinePlayer(uuid);
FileConfiguration file = SettingsManager.getInstance().getData();
if (p.hasPlayedBefore()) {
data.put("PLG-STICKS MADE", new DataPoint(file.getString("Players." + uuid + ".Sticks"), DataType.AMOUNT));
data.put("PLG-STEPS", new DataPoint(file.getString("Players." + uuid + ".Steps"), DataType.AMOUNT));
data.put("PLG-CROUCHES", new DataPoint(file.getString("Players." + uuid + ".Twerks"), DataType.AMOUNT));
}
} catch (IllegalArgumentException e) {
}
return data;
}
}

View File

@ -1,43 +0,0 @@
package com.djrapitops.planlite.command.hooks;
import com.djrapitops.planlite.api.Hook;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.UUIDFetcher;
import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.api.DataType;
import io.minimum.minecraft.superbvote.SuperbVote;
import java.util.HashMap;
import java.util.UUID;
import org.bukkit.OfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
public class SuperbVoteHook implements Hook {
private PlanLite plugin;
private SuperbVote hookP;
public SuperbVoteHook(PlanLite plugin) throws Exception {
this.plugin = plugin;
this.hookP = SuperbVote.getPlugin();
}
@Override
public HashMap<String, DataPoint> getData(String player) throws Exception {
HashMap<String, DataPoint> data = new HashMap<>();
try {
UUID uuid = UUIDFetcher.getUUIDOf(player);
OfflinePlayer p = getOfflinePlayer(uuid);
if (p.hasPlayedBefore()) {
data.put("SVO-VOTES", new DataPoint("" + hookP.getVoteStorage().getVotes(uuid), DataType.AMOUNT));
}
} catch (IllegalArgumentException e) {
}
return data;
}
@Override
public HashMap<String, DataPoint> getAllData(String player) throws Exception {
return getData(player);
}
}

View File

@ -1,94 +0,0 @@
package com.djrapitops.planlite.command.hooks;
import com.djrapitops.planlite.api.Hook;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.UUIDFetcher;
import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.api.DataType;
import com.palmergames.bukkit.towny.Towny;
import static com.palmergames.bukkit.towny.TownyFormatter.getFormattedName;
import static com.palmergames.bukkit.towny.TownyFormatter.lastOnlineFormat;
import static com.palmergames.bukkit.towny.TownyFormatter.registeredFormat;
import com.palmergames.bukkit.towny.exceptions.TownyException;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.TownyUniverse;
import com.palmergames.bukkit.util.BukkitTools;
import java.util.HashMap;
import java.util.List;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
import org.bukkit.OfflinePlayer;
import static com.palmergames.bukkit.towny.TownyFormatter.getFormattedResidents;
import static org.bukkit.Bukkit.getOfflinePlayer;
public class TownyHook implements Hook {
private final Towny towny;
private final PlanLite plugin;
public TownyHook(PlanLite p) throws Exception {
this.towny = getPlugin(Towny.class);
this.plugin = p;
}
@Override
public HashMap<String, DataPoint> getData(String player) throws Exception {
HashMap<String, DataPoint> data = new HashMap<>();
try {
OfflinePlayer p = getOfflinePlayer(UUIDFetcher.getUUIDOf(player));
if (p.hasPlayedBefore()) {
try {
Resident resident = TownyUniverse.getDataSource().getResident(player);
if (resident != null) {
data.put("TOW-ONLINE", new DataPoint("" + BukkitTools.isOnline(player), DataType.BOOLEAN));
data.put("TOW-REGISTERED", new DataPoint(registeredFormat.format(resident.getRegistered()), DataType.DEPRECATED));
data.put("TOW-LAST LOGIN", new DataPoint(lastOnlineFormat.format(resident.getLastOnline()), DataType.DEPRECATED));
data.put("TOW-OWNER OF", new DataPoint(resident.getTownBlocks().size() + " plots", DataType.STRING));
try {
if (resident.hasTown()) {
data.put("TOW-TOWN", new DataPoint(getFormattedName(resident.getTown()), DataType.STRING));
}
if (resident.hasNation()) {
if (!resident.getNationRanks().isEmpty()) {
data.put("TOW-NATION", new DataPoint(resident.getTown().getNation().getName(), DataType.STRING));
}
}
} catch (TownyException e) {
plugin.logToFile("TOWNYHOOK\n" + e + "\n" + e.getMessage());
}
}
} catch (TownyException e) {
plugin.logToFile("TOWNYHOOK\n" + e + "\nError resident: " + player);
}
}
} catch (IllegalArgumentException e) {
}
return data;
}
@Override
public HashMap<String, DataPoint> getAllData(String player) throws Exception {
HashMap<String, DataPoint> data = new HashMap<>();
data.putAll(getData(player));
try {
OfflinePlayer p = getOfflinePlayer(UUIDFetcher.getUUIDOf(player));
if (p.hasPlayedBefore()) {
try {
Resident resident = TownyUniverse.getDataSource().getResident(player);
data.put("TOW-PLOT PERMS", new DataPoint(resident.getPermissions().getColourString(), DataType.STRING));
data.put("TOW-PLOT OPTIONS", new DataPoint("PVP: " + ((resident.getPermissions().pvp) ? "ON" : "OFF") + " Explosions: " + ((resident.getPermissions().explosion) ? "ON" : "OFF") + " Firespread: " + ((resident.getPermissions().fire) ? "ON" : "OFF") + " Mob Spawns: " + ((resident.getPermissions().mobs) ? "ON" : "OFF"), DataType.STRING));
List<Resident> friends = resident.getFriends();
data.put("TOW-FRIENDS", new DataPoint(getFormattedResidents("Friends", friends).toString(), DataType.STRING));
} catch (TownyException e) {
plugin.logToFile("TOWNYHOOK-All\n" + e + "\nError resident: " + player);
}
}
} catch (IllegalArgumentException e) {
}
return data;
}
}

View File

@ -1,44 +0,0 @@
package com.djrapitops.planlite.command.hooks;
import com.djrapitops.planlite.api.Hook;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.UUIDFetcher;
import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.api.DataType;
import java.util.HashMap;
import java.util.UUID;
import org.bukkit.OfflinePlayer;
import net.milkbowl.vault.economy.Economy;
import static org.bukkit.Bukkit.getServer;
import static org.bukkit.Bukkit.getOfflinePlayer;
public class VaultHook implements Hook {
private PlanLite plugin;
private Economy econ;
public VaultHook(PlanLite plugin) throws Exception {
this.plugin = plugin;
this.econ = getServer().getServicesManager().getRegistration(Economy.class).getProvider();
}
@Override
public HashMap<String, DataPoint> getData(String player) throws Exception {
HashMap<String, DataPoint> data = new HashMap<>();
try {
UUID uuid = UUIDFetcher.getUUIDOf(player);
OfflinePlayer p = getOfflinePlayer(uuid);
if (p.hasPlayedBefore()) {
data.put("ECO-BALANCE", new DataPoint(this.econ.format(this.econ.getBalance(p)), DataType.AMOUNT_WITH_LETTERS));
}
} catch (IllegalArgumentException e) {
}
return data;
}
@Override
public HashMap<String, DataPoint> getAllData(String player) throws Exception {
return getData(player);
}
}

View File

@ -1,105 +0,0 @@
package com.djrapitops.planlite.command.utils;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.command.hooks.AdvancedAchievementsHook;
import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.api.DataType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.UUID;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
public class Analysis {
public static HashMap<String, DataPoint> analyze(HashMap<UUID, HashMap<String, DataPoint>> playerData) {
PlanLite plugin = getPlugin(PlanLite.class);
HashMap<String, List<String>> playerDataLists = new HashMap<>();
HashMap<String, DataType> dataTypes = new HashMap<>();
// Ignore following keys (Strings, unprocessable or irrelevant data)
DataType[] ignoreType = {DataType.DEPRECATED, DataType.STRING, DataType.LOCATION, DataType.LINK, DataType.HEATMAP,
DataType.MAP, DataType.OTHER, DataType.DATE, DataType.TIME_TIMESTAMP};
String[] ignore = {"ESS-HEALTH", "ESS-HUNGER", "ESS-XP LEVEL", "ESS-OPPED"};
List<String> ignoreKeys = new ArrayList<>();
List<DataType> ignoreTypes = new ArrayList<>();
try {
AdvancedAchievementsHook aaHook = (AdvancedAchievementsHook) plugin.getHooks().get("AdvancedAchievements");
if (!aaHook.isUsingUUID()) {
ignoreKeys.add("AAC-ACHIEVEMENTS");
}
} catch (Exception e) {
ignoreKeys.add("AAC-ACHIEVEMENTS");
}
ignoreKeys.addAll(Arrays.asList(ignore));
ignoreTypes.addAll(Arrays.asList(ignoreType));
// Turn playerData into Hashmap of Lists sorted by keys.
playerData.keySet().parallelStream().forEach((key) -> {
playerData.get(key).keySet().parallelStream()
.filter((dataKey) -> !(ignoreKeys.contains(dataKey)))
.map((dataKey) -> {
if (dataTypes.get(dataKey) == null) {
dataTypes.put(dataKey, playerData.get(key).get(dataKey).type());
}
return dataKey;
})
.filter((dataKey) -> !(ignoreTypes.contains(dataTypes.get(dataKey))))
.map((dataKey) -> {
if (playerDataLists.get(dataKey) == null) {
playerDataLists.put(dataKey, new ArrayList<>());
}
return dataKey;
})
.forEach((dataKey) -> {
playerDataLists.get(dataKey).add(playerData.get(key).get(dataKey).data());
});
});
HashMap<String, DataPoint> analyzedData = new HashMap<>();
// Analyze
playerDataLists.keySet().parallelStream().forEach((dataKey) -> {
DataType type = dataTypes.get(dataKey);
if (type == DataType.AMOUNT
|| type == DataType.AMOUNT_WITH_LETTERS
|| type == DataType.AMOUNT_WITH_MAX
|| type == DataType.PERCENT) {
// Get a clean list of dataPoints with only numbers
List<String> dataPoints = playerDataLists.get(dataKey);
if (null != type) {
switch (type) {
case AMOUNT_WITH_LETTERS:
dataPoints = AnalysisUtils.parseWLetters(playerDataLists.get(dataKey));
break;
case PERCENT:
dataPoints = AnalysisUtils.parseWLetters(playerDataLists.get(dataKey));
break;
case AMOUNT_WITH_MAX:
dataPoints = AnalysisUtils.parseWMax(playerDataLists.get(dataKey));
break;
default:
break;
}
}
if (type == DataType.PERCENT) {
String averageAmount = AnalysisUtils.AmountAverage(dataPoints);
analyzedData.put(dataKey, new DataPoint(averageAmount + "%", DataType.PERCENT));
} else {
String averageAmount = AnalysisUtils.AmountAverage(dataPoints);
analyzedData.put(dataKey, new DataPoint(averageAmount, DataType.AMOUNT));
// String highestAmount = AnalysisUtils.AmountHighest(dataPoints);
// analyzedData.put(dataKey + " (HIGHEST)", new DataPoint(highestAmount, DataType.AMOUNT));
}
} else if (type == DataType.TIME) {
String averageTime = AnalysisUtils.TimeAverage(playerDataLists.get(dataKey));
analyzedData.put(dataKey, new DataPoint(averageTime, DataType.TIME));
} else if (type == DataType.BOOLEAN) {
String percent = AnalysisUtils.BooleanPercent(playerDataLists.get(dataKey));
analyzedData.put(dataKey, new DataPoint(percent, DataType.PERCENT));
}
});
return DataFormatUtils.formatAnalyzed(analyzedData);
}
}

View File

@ -1,76 +0,0 @@
package com.djrapitops.planlite.command.utils;
import java.util.ArrayList;
import java.util.List;
class AnalysisUtils {
static String AmountAverage(List<String> dataPoints) {
double sum = 0;
for (String dataPoint : dataPoints) {
try {
sum += Double.parseDouble(dataPoint);
} catch (Exception e) {
}
}
return "" + (sum * 1.0 / dataPoints.size());
}
static List<String> parseWLetters(List<String> dataPoints) {
List<String> parsed = new ArrayList<>();
dataPoints.parallelStream().forEach((dataPoint) -> {
parsed.add(DataFormatUtils.removeLetters(dataPoint));
});
return parsed;
}
static List<String> parseWMax(List<String> dataPoints) {
List<String> parsed = new ArrayList<>();
dataPoints.parallelStream().forEach((dataPoint) -> {
parsed.add(dataPoint.split(" ")[0]);
});
return parsed;
}
static String TimeAverage(List<String> dataPoints) {
Long time = Long.parseLong("0");
for (String dataPoint : dataPoints) {
try {
time += Long.parseLong(dataPoint);
} catch (Exception e) {
}
}
return "" + (time / dataPoints.size());
}
static String BooleanPercent(List<String> dataPoints) {
int amount = 0;
for (String dataPoint : dataPoints) {
try {
if (Boolean.parseBoolean(dataPoint)) {
amount++;
}
} catch (Exception e) {
}
}
return "" + ((amount * 1.0 / dataPoints.size())*100)+"%";
}
static String AmountHighest(List<String> dataPoints) {
int highest = 0;
for (String dataPoint : dataPoints) {
try {
int value = Integer.parseInt(dataPoint);
if (value > highest) {
highest = value;
}
} catch (Exception e) {
}
}
return ""+highest;
}
}

View File

@ -1,298 +0,0 @@
package com.djrapitops.planlite.command.utils;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.api.DataPoint;
import com.djrapitops.planlite.api.DataType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
public class DataFormatUtils {
public static HashMap<String, DataPoint> removeExtraDataPoints(HashMap<String, DataPoint> data) throws NumberFormatException {
Date dateNow = new Date();
List<String> remove = new ArrayList<>();
PlanLite plugin = getPlugin(PlanLite.class);
data.keySet().parallelStream().forEach((key) -> {
try {
// Process OnTime empty data (returns -1 if empty)
if (key.subSequence(0, 3).equals("ONT")) {
if ((data.get(key)).data().equals("-1") || (data.get(key)).data().equals("-1.0")) {
remove.add(key);
}
}
// Process failed PlaceholderAPI requests (%string%)
if (key.subSequence(0, 3).equals("PHA")) {
if ((data.get(key)).data().contains("%")) {
remove.add(key);
}
}
} catch (Exception e) {
plugin.logToFile("FORMAT-Remove\n" + e + "\n" + key);
}
});
// Remove faulty data to prevent TOW-LAST LOGIN from being removed with empty data
remove.parallelStream().forEach((removedKey) -> {
data.remove(removedKey);
});
remove.clear();
// Process Towny data (Empty returns date with 1970 for REGISTERED)
if (data.get("TOW-REGISTERED") != null) {
if (data.get("TOW-REGISTERED").data().contains("1970")) {
remove.add("TOW-REGISTERED");
remove.add("TOW-ONLINE");
remove.add("TOW-LAST LOGIN");
remove.add("TOW-OWNER OF");
if (data.get("TOW-FRIENDS") != null) {
remove.add("TOW-FRIENDS");
remove.add("TOW-PLOT PERMS");
remove.add("TOW-PLOT OPTIONS");
}
}
}
// If both OnTime and Towny data found, OnTime priority.
if (data.get("ONT-LAST LOGIN") != null) {
remove.add("TOW-LAST LOGIN");
remove.add("PLG-LAST LOGIN");
}
// Remove faulty Towny data
remove.parallelStream().forEach((removeKey) -> {
data.remove(removeKey);
});
// Remove faulty Essentials SINCE data, reload turns data to 0
String[] keysRemoveIfZero = {"ESS-ONLINE SINCE", "ESS-OFFLINE SINCE"};
for (String key : keysRemoveIfZero) {
if (data.get(key) != null) {
if (data.get(key).data().equals("0")) {
data.remove(key);
}
}
}
// Remove OnTime Total Votes if SuperbVote is present
if (data.get("SVO-VOTES") != null) {
if (data.get("ONT-TOTAL VOTES") != null) {
data.remove("ONT-TOTAL VOTES");
}
}
// Remove Bukkit uuid points if essentials present
if (data.get("ESS-UUID") != null) {
data.remove("BUK-UUID");
}
// Remove colliding Player Logger Data
if (data.get("TOW-LAST LOGIN") != null) {
data.remove("PLG-LAST LOGIN");
}
data.keySet().parallelStream()
.filter((key) -> (data.get(key).type() == DataType.DEPRECATED))
.forEach((key) -> {
remove.add(key);
});
remove.parallelStream().forEach((key) -> {
data.remove(key);
});
// Format TimeStamps and Time Amounts
for (String key : data.keySet()) {
DataPoint dataPoint = data.get(key);
if (null != dataPoint.type()) switch (dataPoint.type()) {
case DATE:{
String formatted = formatTimeStamp(dataPoint.data());
dataPoint.setData(formatted);
break;
}
case TIME:{
String formatted = formatTimeAmount(dataPoint.data());
dataPoint.setData(formatted);
break;
}
case TIME_TIMESTAMP:{
String formatted = formatTimeAmountSinceString(dataPoint.data(), dateNow);
dataPoint.setData(formatted);
break;
}
default:
break;
}
}
return data;
}
// Analysis data Formatting, will be updated after more analysis is added
public static HashMap<String, DataPoint> formatAnalyzed(HashMap<String, DataPoint> analyzedData) {
return removeExtraDataPoints(analyzedData);
}
// Format Search Results
public static HashMap<String, DataPoint> removeExtraDataPointsSearch(HashMap<String, DataPoint> dataMap, String[] args) {
if (args.length <= 1) {
return removeExtraDataPoints(dataMap);
}
HashMap<String, DataPoint> returnMap = new HashMap<>();
String errors = "FORMAT-SEARCH\n";
for (String key : dataMap.keySet()) {
for (String arg : args) {
try {
if (key.toLowerCase().contains(arg.toLowerCase())) {
returnMap.put(key, dataMap.get(key));
}
} catch (Exception e) {
if (!errors.contains(Arrays.toString(args))) {
errors += Arrays.toString(args) + "\n";
}
errors += (e + "\n" + key + " " + arg + "\n");
}
}
}
if (!errors.equals("FORMAT-SEARCH\n")) {
PlanLite plugin = getPlugin(PlanLite.class);
plugin.logToFile(errors);
}
return removeExtraDataPoints(returnMap);
}
// Replace certain items of search terms with plugin tags and remove playername if -p
public static String[] parseSearchArgs(String[] args) {
String[] aacTerms = {"aac", "advanced", "achiev"};
String[] svoTerms = {"svo", "superb", "vote"};
String[] ontTerms = {"ont", "onoime", "time"};
String[] ecoTerms = {"eco", "money", "bal"};
String[] towTerms = {"tow", "town", "nation", "res", "plot", "perm"};
List<String> aac = new ArrayList<>();
List<String> svo = new ArrayList<>();
List<String> ont = new ArrayList<>();
List<String> eco = new ArrayList<>();
List<String> tow = new ArrayList<>();
aac.addAll(Arrays.asList(aacTerms));
svo.addAll(Arrays.asList(svoTerms));
ont.addAll(Arrays.asList(ontTerms));
eco.addAll(Arrays.asList(ecoTerms));
tow.addAll(Arrays.asList(towTerms));
String[] returnArray = new String[args.length];
argloop:
for (int i = 0; i < args.length; i++) {
for (String s : aac) {
if (args[i].toLowerCase().contains(s)) {
returnArray[i] = "AAC";
continue argloop;
}
}
for (String s : svo) {
if (args[i].toLowerCase().contains(s)) {
returnArray[i] = "SVO";
continue argloop;
}
}
for (String s : ont) {
if (args[i].toLowerCase().contains(s)) {
returnArray[i] = "ONT";
continue argloop;
}
}
for (String s : eco) {
if (args[i].toLowerCase().contains(s)) {
returnArray[i] = "ECO";
continue argloop;
}
}
for (String s : tow) {
if (args[i].toLowerCase().contains(s)) {
returnArray[i] = "TOW";
continue argloop;
}
}
returnArray[i] = args[i];
if (args[i].equals("-p")) {
returnArray[0] = args[0] + "_(Playername)";
returnArray[i] = "---";
}
}
return returnArray;
}
// Creates a new Date with Epoch second and returns Date and Time String
public static String formatTimeStamp(String string) throws NumberFormatException {
long ms = Long.parseLong(string);
Date sfd = new Date(ms);
return ("" + sfd).substring(4, 19);
}
// Formats Time Since (0 -> string)
public static String formatTimeAmount(String string) throws NumberFormatException {
long ms = Long.parseLong(string);
return turnMsLongToString(ms);
}
// Formats Time Difference String before -> Date now
public static String formatTimeAmountSinceString(String string, Date now) throws NumberFormatException {
long ms = Math.abs((now.toInstant().getEpochSecond() * 1000) - Long.parseLong(string));
return turnMsLongToString(ms);
}
// Formats Time Difference Date before -> Date now
public static String formatTimeAmountSinceDate(Date before, Date now) throws NumberFormatException {
long ms = Math.abs((now.toInstant().getEpochSecond() * 1000) - (before.toInstant().getEpochSecond() * 1000));
return turnMsLongToString(ms);
}
// Formats long in milliseconds into d:h:m:s string
private static String turnMsLongToString(long ms) {
String returnValue = "";
long x = ms / 1000;
long seconds = x % 60;
x /= 60;
long minutes = x % 60;
x /= 60;
long hours = x % 24;
x /= 24;
long days = x;
if (days != 0) {
returnValue += days + "d ";
}
if (hours != 0) {
returnValue += hours + "h ";
}
if (minutes != 0) {
returnValue += minutes + "m ";
}
if (seconds != 0) {
returnValue += seconds + "s";
}
if (returnValue.isEmpty()) {
returnValue += "< 1s";
}
return returnValue;
}
// Removes letters from a string leaving only numbers and dots.
public static String removeLetters(String dataPoint) {
String numbers = "0123456789.";
List<Character> numList = new ArrayList<>();
char[] numberArray = numbers.toCharArray();
for (char c : numberArray) {
numList.add(c);
}
String returnString = "";
for (int i = 0; i < dataPoint.length(); i++) {
if (numList.contains(dataPoint.charAt(i))) {
returnString += dataPoint.charAt(i);
}
}
return returnString;
}
// Sorts HashMap into Sorted List of Arrays
public static List<String[]> turnDataHashMapToSortedListOfArrays(HashMap<String, DataPoint> data) {
List<String[]> dataList = new ArrayList<>();
data.keySet().stream().forEach((key) -> {
dataList.add(new String[]{key, data.get(key).data()});
});
Collections.sort(dataList, (String[] strings, String[] otherStrings) -> strings[0].compareTo(otherStrings[0]));
return dataList;
}
}

View File

@ -1,114 +0,0 @@
package com.djrapitops.planlite.command.utils;
import com.djrapitops.planlite.PlanLite;
import com.djrapitops.planlite.UUIDFetcher;
import com.djrapitops.planlite.api.DataPoint;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
public class DataUtils {
// allData defined by -a argument in InspectCommand
// returns data given by each Hook
public static HashMap<String, DataPoint> getData(boolean allData, String playerName) {
HashMap<String, DataPoint> data = new HashMap<>();
PlanLite plugin = getPlugin(PlanLite.class);
plugin.getHooks().keySet().parallelStream().forEach((hook) -> {
try {
if (allData) {
data.putAll(plugin.getHooks().get(hook).getAllData(playerName));
} else {
data.putAll(plugin.getHooks().get(hook).getData(playerName));
}
} catch (Exception e) {
String toLog = "UTILS-GetData"
+ "\nFailed to getData from " + hook
+ "\n" + e
+ "\ncausing argument: " + playerName;
for (StackTraceElement element : e.getStackTrace()) {
toLog += "\n " + element;
}
plugin.logToFile(toLog);
}
});
return data;
}
// Returns data HashMaps for all pplayers in a HashMap.
public static HashMap<UUID, HashMap<String, DataPoint>> getTotalData(Set<OfflinePlayer> ofPlayers) {
HashMap<UUID, HashMap<String, DataPoint>> playerData = new HashMap<>();
List<OfflinePlayer> players = new ArrayList<>();
players.addAll(ofPlayers);
players.parallelStream()
.filter((player) -> (playerData.get(player.getUniqueId()) == null))
.forEach((player) -> {
playerData.put(player.getUniqueId(), getData(true, player.getName()));
});
return playerData;
}
@Deprecated
public static HashMap<String, DataPoint> analyze(HashMap<UUID, HashMap<String, DataPoint>> playerData) {
return Analysis.analyze(playerData);
}
public static String getPlayerDisplayname(String[] args, CommandSender sender) {
String playerName = "";
PlanLite plugin = getPlugin(PlanLite.class);
if (args.length > 0) {
if ((args[0].equals("-a")) || (args[0].equals("-r"))) {
playerName = "ArgumentGivenError";
plugin.log("No username given, returned empty username.");
plugin.logToFile("INSPECT-GETNAME\nNo username given, returned empty username.\n" + args[0]);
} else if (sender.hasPermission("planlite.inspect.other") || !(sender instanceof Player)) {
playerName = args[0];
}
} else {
try {
Player player = plugin.getServer().getPlayer(UUIDFetcher.getUUIDOf(sender.getName()));
playerName = player.getName();
} catch (Exception e) {
playerName = "ConsoleNotPlayerErr";
}
}
return playerName;
}
public static Set<OfflinePlayer> getMatchingDisplaynames(String[] args, CommandSender sender, boolean all) {
List<OfflinePlayer> players = new ArrayList<>();
players.addAll(Arrays.asList(Bukkit.getOfflinePlayers()));
Set<OfflinePlayer> matches = new HashSet<>();
if (all) {
matches.addAll(players);
} else {
List<String> searchTerms = new ArrayList<>();
searchTerms.addAll(Arrays.asList(args));
players.parallelStream().forEach((p) -> {
searchTerms.stream().filter((searchTerm) -> (p.getName().toLowerCase().contains(searchTerm.toLowerCase()))).forEach((_item) -> {
matches.add(p);
});
});
}
return matches;
}
public static Set<OfflinePlayer> getMatchingDisplaynames(boolean b) {
return getMatchingDisplaynames(new String[0], null, true);
}
}

View File

@ -1,57 +0,0 @@
package com.djrapitops.planlite.command.utils;
import com.djrapitops.planlite.PlanLite;
import java.net.URL;
import java.util.Scanner;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
public class MiscUtils {
// <h1>Plan - Player Analytics <span class="muted">
public static String checkVersion() {
PlanLite plugin = getPlugin(PlanLite.class);
String[] nVersion;
String[] cVersion;
String lineWithVersion;
try {
URL githubUrl = new URL("https://raw.githubusercontent.com/Rsl1122/Plan-PlayerAnalytics/master/Plan%20Lite/src/plugin.yml");
lineWithVersion = "";
Scanner websiteScanner = new Scanner(githubUrl.openStream());
while (websiteScanner.hasNextLine()) {
String line = websiteScanner.nextLine();
if (line.toLowerCase().contains("version")) {
lineWithVersion = line;
break;
}
}
String versionString = lineWithVersion.split(": ")[1];
nVersion = versionString.split("\\.");
double newestVersionNumber = Double.parseDouble(nVersion[0] + "." + nVersion[1] + nVersion[2]);
cVersion = plugin.getDescription().getVersion().split("\\.");
double currentVersionNumber = Double.parseDouble(cVersion[0] + "." + cVersion[1] + cVersion[2]);
if (newestVersionNumber > currentVersionNumber) {
return "New Version (" + versionString + ") is availible at https://www.spigotmc.org/resources/plan-player-analytics.32536/";
} else {
return "You're running the latest version";
}
} catch (Exception e) {
plugin.logToFile("Failed to compare versions.\n"+e);
}
return "Failed to get newest version number.";
}
public static String[] mergeArrays(String[]... arrays) {
int arraySize = 0;
for (String[] array : arrays) {
arraySize += array.length;
}
String[] result = new String[arraySize];
int j = 0;
for (String[] array : arrays) {
for (String string : array) {
result[j++] = string;
}
}
return result;
}
}

View File

@ -1,13 +0,0 @@
debug: true
visible:
bukkitdata: true
ontime: true
essentials: true
factions: true
towny: true
vault: true
superbvote: true
placeholderapi: true
advancedachievements: true
playerlogger: true

View File

@ -1,83 +0,0 @@
name: PlanLite
main: com.djrapitops.planlite.PlanLite
version: 1.6.3
commands:
planlite:
usage: /<command> <name>
description: base command
inspect:
usage: /planlite inspect <name>
description: inspect player data
analyze:
usage: /planlite analyze
description: analyze all players' data, add -refresh to refresh analysis.
reload:
usage: /planlite reload
description: reload plugin config
search:
usage: /planlite <search terms> -p add -p to make not search playername
description: search data of multiple players with search terms
debug:
usage: /planlite debug
description: run commands to debug the plugin.
softdepend:
- OnTime
- EssentialsX
- Towny
- Vault
- Factions
- SuperbVote
- PlaceholderAPI
- AdvancedAchievements
- PlayerLogger
permissions:
planlite.?:
description: Help command
default: true
planlite.inspect:
description: Allows you to check your player data.
default: true
planlite.inspect.other:
description: Allows you to check other players' player data.
default: true
planlite.analyze:
description: Allows you to check analysed data about all players.
default: true
planlite.analyze.refresh:
description: Allows you to refresh the analyse result with -r argument
default: op
planlite.reload:
description: Allows to reload plugin config
default: true
planlite.search:
description: Allows search
default: true
planlite.info:
description: Allows to view info
default: true
planlite.debug:
description: Allows debug command
default: op
planlite.basic:
children:
planlite.?: true
planlite.inspect: true
planlite.info: true
planlite.search: true
planlite.advanced:
childer:
planlite.basic: true
planlite.analyze: true
planlite.staff:
children:
planlite.debug: true
planlite.advanced: true
planlite.inspect.other: true
planlite.analyze.refresh: true
planlite.reload: true
planlite.*:
children:
planlite.staff: true

View File

@ -5,17 +5,28 @@
<artifactId>Plan</artifactId>
<version>2.0.0</version>
<packaging>jar</packaging>
<repositories>
<!-- <repository>
<id>bukkit-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>-->
<repository>
<id>vault-repo</id>
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.10.2-R0.1-SNAPSHOT</version>
<version>1.11.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!-- SoftDepended Plugins-->
<dependency>
<groupId>com.hm</groupId>
<artifactId>advanced.achievements</artifactId>
<version>4.1.5</version>
<version>5.1</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -30,12 +41,6 @@
<version>2.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.minimum</groupId>
<artifactId>superbvote</artifactId>
<version>0.3.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.massivecraft</groupId>
<artifactId>factions</artifactId>
@ -54,6 +59,12 @@
<version>0.91.4.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.milkbowl.vault</groupId>
<artifactId>VaultAPI</artifactId>
<version>1.6</version>
<scope>provided</scope>
</dependency>
<!-- -->
<dependency>
<groupId>org.powermock</groupId>
@ -111,6 +122,7 @@
<scope>test</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>clean package install</defaultGoal>
<finalName>${project.name}</finalName>
@ -126,7 +138,6 @@
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
@ -135,22 +146,6 @@
<target>1.8</target>
</configuration>
</plugin>
<!-- <plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
@ -177,19 +172,6 @@
<configLocation>checkstyle.xml</configLocation>
</configuration>
</plugin>
<!-- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>-->
</plugins>
</build>
<properties>

View File

@ -231,7 +231,7 @@ public enum Phrase {
while (localeScanner.hasNextLine()) {
String line = localeScanner.nextLine();
if (!line.isEmpty()) {
if (line.equals("<<<<<<HTML>>>>>>")) {
if ("<<<<<<HTML>>>>>>".equals(line)) {
break;
}
localeRows.add(line);

View File

@ -26,7 +26,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.concurrent.Executors;
@ -132,7 +131,7 @@ public class Plan extends JavaPlugin {
consoleSender.sendMessage(Phrase.NOTIFY_EMPTY_IP + "");
}
hookHandler = new HookHandler(this);
hookHandler = new HookHandler();
Log.debug("Verboose debug messages are enabled.");
Log.info(Phrase.ENABLED + "");
}
@ -160,15 +159,6 @@ public class Plan extends JavaPlugin {
Log.info(Phrase.DISABLED + "");
}
/**
* Used to access the API.
*
* @return Plan API
*/
public API getAPI() {
return api;
}
private void registerListeners() {
final PluginManager pluginManager = getServer().getPluginManager();
pluginManager.registerEvents(new PlanChatListener(this), this);
@ -312,6 +302,17 @@ public class Plan extends JavaPlugin {
return bootAnalysisTaskID;
}
/**
* Old method for getting the API.
*
* @deprecated Use Plan.getAPI() (static method) instead.
* @return the Plan API.
*/
@Deprecated
public API getAPI() {
return api;
}
private void initLocale() {
String locale = Settings.LOCALE.toString().toUpperCase();
/*// Used to write a new Locale file
@ -367,7 +368,16 @@ public class Plan extends JavaPlugin {
}
Log.info("Using locale: " + usingLocale);
}
/**
* Used to get the current instance of Plan.
*
* Instance is set on the first line of onEnable method.
*
* @return current instance of Plan, Singleton.
* @throws IllegalStateException If onEnable method has not been called &
* the instance is null.
*/
public static Plan getInstance() {
Plan INSTANCE = PlanHolder.INSTANCE;
if (INSTANCE == null) {
@ -376,12 +386,31 @@ public class Plan extends JavaPlugin {
return INSTANCE;
}
/**
* Used to set the current instance of Plan.
*
* @param plan The newly enabled Plan instance.
*/
public static void setInstance(Plan plan) {
PlanHolder.INSTANCE = plan;
}
private static class PlanHolder {
/**
* Used to get the PlanAPI. @see API
*
* @return API of the current instance of Plan.
* @throws IllegalStateException If onEnable method has not been called on
* Plan & the instance is null.
*/
public static API getPlanAPI() throws IllegalStateException {
Plan INSTANCE = PlanHolder.INSTANCE;
if (INSTANCE == null) {
throw new IllegalStateException("Plugin not enabled properly, Singleton instance is null.");
}
return INSTANCE.api;
}
private static class PlanHolder {
private static Plan INSTANCE = null;
}
}

View File

@ -1,5 +1,7 @@
package main.java.com.djrapitops.plan;
import java.util.List;
/**
* This enum contains all of the config settings used by the plugin for easier
* access.
@ -43,6 +45,11 @@ public enum Settings {
COLOR_SEC("Customization.Colors.Commands.Secondary"),
COLOR_TER("Customization.Colors.Commands.Highlight"),
//
HCOLOR_MAIN("Customization.Colors.HTML.UI.Main"),
HCOLOR_MAIN_DARK("Customization.Colors.HTML.UI.MainDark"),
HCOLOR_SEC("Customization.Colors.HTML.UI.Secondary"),
HCOLOR_TER("Customization.Colors.HTML.UI.Tertiary"),
HCOLOR_TER_DARK("Customization.Colors.HTML.UI.TertiaryDark"),
HCOLOR_ACT_ONL("Customization.Colors.HTML.ActivityGraph.OnlinePlayers"),
HCOLOR_ACT_ONL_FILL("Customization.Colors.HTML.ActivityGraph.OnlinePlayersFill"),
HCOLOR_ACTP_ACT("Customization.Colors.HTML.ActivityPie.Active"),
@ -55,7 +62,10 @@ public enum Settings {
HCOLOR_GMP_3("Customization.Colors.HTML.GamemodePie.Spectator"),
HCOLOR_GENP_M("Customization.Colors.HTML.GenderPie.Male"),
HCOLOR_GENP_F("Customization.Colors.HTML.GenderPie.Female"),
HCOLOR_GENP_U("Customization.Colors.HTML.GenderPie.Unknown");
HCOLOR_GENP_U("Customization.Colors.HTML.GenderPie.Unknown"),
// StringList
HIDE_FACTIONS("Customization.Plugins.Factions.HideFactions"),
HIDE_TOWNS("Customization.Plugins.Towny.HideTowns");
private final String configPath;
@ -90,6 +100,10 @@ public enum Settings {
public int getNumber() {
return Plan.getInstance().getConfig().getInt(configPath);
}
public List<String> getStringList() {
return Plan.getInstance().getConfig().getStringList(configPath);
}
/**
* Used to get the String path of a the config setting eg.

View File

@ -5,15 +5,22 @@ import java.util.UUID;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.AnalysisData;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import main.java.com.djrapitops.plan.data.handling.info.HandlingInfo;
import main.java.com.djrapitops.plan.ui.DataRequestHandler;
import main.java.com.djrapitops.plan.ui.webserver.WebSocketServer;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
import main.java.com.djrapitops.plan.utilities.UUIDFetcher;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
/**
* This class contains the API methods.
* <p>
* Revamp incoming in 3.1.0
* Methods can be called from Asyncronous task & are thread safe unless
* otherwise stated.
*
* @author Rsl1122
* @since 2.0.0
@ -32,49 +39,194 @@ public class API {
}
/**
* Returns a user readable format of Time difference between two dates
* Check whether or not the plugin enabled successfully.
*
* @param before Date with long value that is lower
* @param after Date with long value that is higher
* @return String that is easily readable d:h:m:s
* @return true if plugin is enabled correctly.
*/
@Deprecated
public static String formatTimeSinceDate(Date before, Date after) {
return FormatUtils.formatTimeAmountSinceDate(before, after);
public boolean isEnabled() {
return plugin.isEnabled();
}
/**
* Returns a user readable format of Time difference between two dates
* Add a source of plugin data to the Plugins tab on Analysis and/or Inspect
* page.
*
* @param before String of long since Epoch 1970
* @param after Date with long value that is higher
* @return String that is easily readable d:h:m:s
* Refer to documentation on github or Javadoc of PluginData to set-up a
* data source that extends PluginData correctly.
*
* @param dataSource an object that extends PluginData-object, thus allowing
* Analysis & Inspect to manage the data of a plugin correctly.
* @see PluginData
*/
@Deprecated
public static String formatTimeSinceString(String before, Date after) {
return FormatUtils.formatTimeAmountSinceString(before, after);
public void addPluginDataSource(PluginData dataSource) {
if (isEnabled()) {
plugin.getHookHandler().addPluginDataSource(dataSource);
}
}
/**
* Returns a user readable format of Time
* Used to get the link to InspectPage of a player.
*
* @param timeInMs String of long value in milliseconds
* @return String that is easily readable d:h:m:s
* This method is useful if you have a table and want to link to the inspect
* page.
*
* Html.LINK.parse("Link", "Playername") can be used to get a link
* {@code <a href="Link">Playername</a>}
*
* @param name Playername of the player
* @return ip:port/security/player/Playername
*/
@Deprecated
public static String formatTimeAmount(String timeInMs) {
return FormatUtils.formatTimeAmount(timeInMs);
public String getPlayerInspectPageLink(String name) {
return HtmlUtils.getInspectUrl(name);
}
/**
* Returns user readable format of a Date.
* Schedule a UserData object to be fetched from the database or cache if
* the player is online.
*
* @param timeInMs String of long since Epoch 1970
* @return String that is easily readable date.
* The data will not be cached if it is not already cached.
*
* @param uuid UUID of the player.
* @param processor Object implementing DBCallableProcessor, which
* process(UserData data) method will be called.
*/
@Deprecated
public static String formatTimeStamp(String timeInMs) {
return FormatUtils.formatTimeStamp(timeInMs);
public void scheduleForGet(UUID uuid, DBCallableProcessor processor) {
plugin.getHandler().getUserDataForProcessing(processor, uuid, false);
}
/**
* Schedule a HandlingInfo object to be processed.
*
* UserData associated with the UUID of the HandlingInfo object will be
* cached.
*
* @param info object that extends HandlingInfo.
*/
public void scheduleEventHandlingInfo(HandlingInfo info) {
plugin.getHandler().addToPool(info);
}
/**
* Used to cache a UserData object.
*
* If data is already cached it will be overridden.
*
* @param data UserData object. Will be placed to the data.getUuid() key in
* the cache.
*/
public void placeDataToCache(UserData data) {
plugin.getHandler().cache(data);
}
/**
* Used to save the cached data to the database.
*
* Should be only called from an Asyncronous thread.
*/
public void saveCachedData() {
plugin.getHandler().saveCachedUserData();
}
/**
* Check if the UserData is cached to the InspectCache.
*
* @param uuid UUID of the player.
* @return true/false
*/
public boolean isPlayersDataInspectCached(UUID uuid) {
return plugin.getInspectCache().isCached(uuid);
}
/**
* Cache the UserData to InspectCache.
*
* Uses cache if data is cached or database if not. Call from an Asyncronous
* thread.
*
* @param uuid
*/
public void cacheUserDataToInspectCache(UUID uuid) {
plugin.getInspectCache().cache(uuid);
}
/**
* Used to get the full Html of the Inspect page as a string.
*
* Check if the data is cached to InspectCache before calling this.
*
* @param uuid UUID of the player.
* @return player.html with all placeholders replaced.
*/
public String getPlayerHtmlAsString(UUID uuid) {
WebSocketServer server = plugin.getUiServer();
if (server != null) {
return server.getDataReqHandler().getInspectHtml(uuid);
}
DataRequestHandler reqH = new DataRequestHandler(plugin);
return reqH.getInspectHtml(uuid);
}
/**
* Check if the Analysis has been run & is cached to the AnalysisCache.
*
* @return true/false
*/
public boolean isAnalysisCached() {
return plugin.getAnalysisCache().isCached();
}
/**
* Run's the analysis with the current data in the cache & fetches rest from
* the database.
*
* Starts a new Asyncronous task to run the analysis.
*/
public void updateAnalysisCache() {
plugin.getAnalysisCache().updateCache();
}
/**
* Used to get the full Html of the Analysis page as a string.
*
* Check if the data is cached to AnalysisCache before calling this.
*
* @return analysis.html with all placeholders replaced.
*/
public String getAnalysisHtmlAsString() {
WebSocketServer server = plugin.getUiServer();
if (server != null) {
return server.getDataReqHandler().getAnalysisHtml();
}
DataRequestHandler reqH = new DataRequestHandler(plugin);
return reqH.getAnalysisHtml();
}
/**
* Used to get the AnalysisData object.
*
* Check if the data is cached to AnalysisCache before calling this.
*
* @return AnalysisData object.
* @see AnalysisData
*/
public AnalysisData getAnalysisDataFromCache() {
return plugin.getAnalysisCache().getData();
}
/**
* Used to get the playerName of a player who has played on the server.
*
* @param uuid UUID of the player.
* @return Playername, eg "Rsl1122"
* @throws IllegalStateException If the player has not played on the server
* before.
*/
public String getPlayerName(UUID uuid) throws IllegalStateException {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (offlinePlayer.hasPlayedBefore()) {
return offlinePlayer.getName();
}
throw new IllegalStateException("Player has not played on this server before.");
}
/**
@ -88,91 +240,24 @@ public class API {
return UUIDFetcher.getUUIDOf(playerName);
}
/**
* Caches the UserData to the InspectCache for time specified in the Plan
* config, so it can be called by webserver.
*
* Does not cache anything if the player has not joined the server or has no
* data in the database.
*
* @param uuid UUID of the Player
*/
// DEPRECATED METHODS WILL BE REMOVED IN 3.2.0
@Deprecated
public void cacheUserDataToInspectCache(UUID uuid) {
plugin.getInspectCache().cache(uuid);
public static String formatTimeSinceDate(Date before, Date after) {
return FormatUtils.formatTimeAmountSinceDate(before, after);
}
/**
* Returns the ip:port/player/playername html as a string so it can be
* integrated into other webserver plugins.
*
* Should use cacheUserDataToInspectCache(UUID uuid) before using this
* method.
*
* If UserData of the specified player is not in the Cache returns <h1>404
* Data was not found in cache</h1>
*
* @param uuid UUID of the Player
* @return html as a string or a single error line html.
*/
@Deprecated
public String getPlayerHtmlAsString(UUID uuid) {
WebSocketServer server = plugin.getUiServer();
if (server != null) {
return server.getDataReqHandler().getInspectHtml(uuid);
}
DataRequestHandler reqH = new DataRequestHandler(plugin);
return reqH.getInspectHtml(uuid);
public static String formatTimeSinceString(String before, Date after) {
return FormatUtils.formatTimeAmountSinceString(before, after);
}
/**
* Updates the AnalysisCache so the cached data can be called by the
* webserver.
*/
@Deprecated
public void updateAnalysisCache() {
plugin.getAnalysisCache().updateCache();
public static String formatTimeAmount(String timeInMs) {
return FormatUtils.formatTimeAmount(timeInMs);
}
/**
* Returns the ip:port/server html as a string so it can be integrated into
* other webserver plugins.
*
* Should use updateAnalysisCache() before using this method.
*
* If AnalysisData is not in the AnalysisCache: returns <h1>404 Data was not
* found in cache</h1>
*
* @return html as a string or a single error line html.
*/
@Deprecated
public String getAnalysisHtmlAsString() {
WebSocketServer server = plugin.getUiServer();
if (server != null) {
return server.getDataReqHandler().getAnalysisHtml();
}
DataRequestHandler reqH = new DataRequestHandler(plugin);
return reqH.getAnalysisHtml();
}
/**
* Returns UserData from the InspectCache
*
* @param uuid UUID of the Player
* @return UserData of the Player in the InspectCache or null if not found
*/
@Deprecated
public UserData getUserDataFromInspectCache(UUID uuid) {
return plugin.getInspectCache().getFromCache(uuid);
}
/**
* Returns AnalysisData from the AnalysisCache
*
* @return AnalysisData in the AnalysisCache or null if not found
*/
@Deprecated
public AnalysisData getAnalysisDataFromCache() {
return plugin.getAnalysisCache().getData();
public static String formatTimeStamp(String timeInMs) {
return FormatUtils.formatTimeStamp(timeInMs);
}
}

View File

@ -11,11 +11,11 @@ import main.java.com.djrapitops.plan.command.CommandType;
import main.java.com.djrapitops.plan.command.SubCommand;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
import main.java.com.djrapitops.plan.utilities.UUIDFetcher;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
import static org.bukkit.Bukkit.getOfflinePlayer;
/**
* This manage subcommand is used to remove a single player's data from the

View File

@ -1,6 +1,8 @@
package main.java.com.djrapitops.plan.data;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.ui.RecentPlayersButtonsCreator;
@ -24,6 +26,7 @@ import main.java.com.djrapitops.plan.utilities.PlaceholderUtils;
public class AnalysisData {
private long refreshDate;
private Map<String, String> additionalDataReplaceMap;
private long averagePlayTime;
private long totalPlayTime;
@ -79,6 +82,7 @@ public class AnalysisData {
geomapCodes = Html.ERROR_NOT_SET + "";
playersDataArray = new String[]{"[0]", "[\"No data\"]", "[0]", "[\"No data\"]", "[0]", "[\"No data\"]"};
genderData = new int[]{0, 0, 0};
additionalDataReplaceMap = new HashMap<>();
}
@Override
@ -189,6 +193,25 @@ public class AnalysisData {
return true;
}
/**
* Set the additional data replaceMap used with Analysis replacerules.
*
* @param additionalDataReplaceMap Map with placeholder keys %key%, value
* @see PlaceholderUtils
*/
public void setAdditionalDataReplaceMap(Map<String, String> additionalDataReplaceMap) {
this.additionalDataReplaceMap = additionalDataReplaceMap;
}
/**
* Get the additional data replaceMap used with Analysis replacerules.
*
* @return a Map with placeholder keys %key%, value
*/
public Map<String, String> getAdditionalDataReplaceMap() {
return additionalDataReplaceMap;
}
/**
* Used to get the toString representation of a String[] containing all
* countries on the Plotly.js Chloropleth map.
@ -846,9 +869,9 @@ public class AnalysisData {
/**
*
* Set the integer array containing 3 numbers.
*
*
* 0 Male, 1 Female, 2 Unknown.
*
*
* @param genderData for example [0, 4, 5]
*/
public void setGenderData(int[] genderData) {

View File

@ -1,91 +0,0 @@
package main.java.com.djrapitops.plan.data.additional;
import com.hm.achievement.AdvancedAchievements;
import com.hm.achievement.category.MultipleAchievements;
import com.hm.achievement.category.NormalAchievements;
import java.util.UUID;
import main.java.com.djrapitops.plan.Plan;
/**
*
* @author Rsl1122
*/
public class AdvancedAchievementsHook extends Hook {
private final Plan plugin;
private AdvancedAchievements adAc;
private int totalAchievements;
/**
* Hooks the plugin and calculates Total Achievements.
*
* @param plugin
*/
public AdvancedAchievementsHook(Plan plugin) throws NoClassDefFoundError {
super("com.hm.achievement.AdvancedAchievements");
this.plugin = plugin;
if (super.isEnabled()) {
try {
totalAchievements = calcTotalAchievements();
} catch (Exception | NoClassDefFoundError e) {
super.setEnabled(false);
}
}
}
/**
*
*/
public AdvancedAchievementsHook() {
super();
plugin = null;
}
private int calcTotalAchievements() throws Exception, NoClassDefFoundError {
int total = 0;
for (NormalAchievements category : NormalAchievements.values()) {
String categoryName = category.toString();
if (adAc.getDisabledCategorySet().contains(categoryName)) {
// Ignore this type.
continue;
}
total += adAc.getPluginConfig().getConfigurationSection(categoryName).getKeys(false).size();
}
for (MultipleAchievements category : MultipleAchievements.values()) {
String categoryName = category.toString();
if (adAc.getDisabledCategorySet().contains(categoryName)) {
// Ignore this type.
continue;
}
for (String item : adAc.getPluginConfig().getConfigurationSection(categoryName).getKeys(false)) {
total += adAc.getPluginConfig().getConfigurationSection(categoryName + '.' + item)
.getKeys(false).size();
}
}
if (!adAc.getDisabledCategorySet().contains("Commands")) {
total += adAc.getPluginConfig().getConfigurationSection("Commands").getKeys(false).size();
}
return total;
}
/**
* Returns total number of achievements. isEnabled() should be called before
* calling this method
*
* @return Total Achievements calculated during Initialization
*/
public int getTotalAchievements() {
return totalAchievements;
}
/**
* Returns achievement number of a player. isEnabled() should be called
* before calling this method
*
* @param uuid UUID of player
* @return Achievement amount of the Player
*/
public int getPlayerAchievements(UUID uuid) {
return adAc.getDb().getPlayerAchievementsAmount(uuid.toString());
}
}

View File

@ -0,0 +1,146 @@
package main.java.com.djrapitops.plan.data.additional;
import main.java.com.djrapitops.plan.data.additional.advancedachievements.AdvancedAchievementsTable;
import main.java.com.djrapitops.plan.data.additional.factions.FactionsMaxPower;
import main.java.com.djrapitops.plan.data.additional.factions.FactionsPower;
import main.java.com.djrapitops.plan.data.additional.factions.FactionsTable;
import main.java.com.djrapitops.plan.data.additional.towny.TownyTable;
/**
* This class contains Enum values for different types of Analysis that can be
* performed on values of PluginData.
*
* The enum determines what should be done to the return value of
* PluginData.getValue() method when the analysis is run.
*
* Refer to the documentation on github for additional information.
*
* @author Rsl1122
*/
public enum AnalysisType {
/**
* Used when the getValue() method returns an integer & average should be
* calculated.
*
* -1 values will be disregarded from the calculation (size will not grow).
*/
INT_AVG("avgInt_","Average "),
/**
* Used when the getValue() method returns a long & average should be
* calculated.
*
* -1 values will be disregarded from the calculation (size will not grow).
*/
LONG_AVG("avgLong_","Average "),
/**
* Used when the getValue() method returns double & average should be
* calculated.
*
* -1 values will be disregarded from the calculation (size will not grow).
*/
DOUBLE_AVG("avgDouble_", "Average "),
/**
* Used when the getValue() method returns an integer & total should be
* calculated.
*
* -1 values will be disregarded from the calculation (size will not grow).
*/
INT_TOTAL("totalInt_"),
/**
* Used when the getValue() method returns a long & total should be
* calculated.
*
* -1 values will be disregarded from the calculation (size will not grow).
*/
LONG_TOTAL("totalLong_"),
/**
* Used when the getValue() method returns a double & total should be
* calculated.
*
* -1 values will be disregarded from the calculation (size will not grow).
*/
DOUBLE_TOTAL("totalDouble_"),
/**
* Used when the getValue() method returns an amount of milliseconds as long
* & average should be calculated.
*
* -1 values will be disregarded from the calculation (size will not grow).
*/
LONG_TIME_MS_AVG("avgTimeMs_", "Average "),
/**
* Used when the getValue() method returns an amount of milliseconds as long
* & total should be calculated.
*
* -1 values will be disregarded from the calculation (size will not grow).
*/
LONG_TIME_MS_TOTAL("totalTimeMs_"),
/**
* Used when the getValue() method returns an Epoch Millisecond as long &
* average of differences between the millisecond & current millisecond
* should be calculated.
*
* For example if a player has dropped a Foo on epoch ms 1494486504000 &
* that was 5s (5000ms) ago. Now you want to calculate the average
* time-since for all players. Then you use this one.
*
* -1 values will be disregarded from the calculation (size will not grow).
*/
LONG_EPOCH_MS_MINUS_NOW_AVG("avgEpochMsMinusNow_", "Average "),
/**
* Used to calculate %-true for the returned boolean values of getValue().
*/
BOOLEAN_PERCENTAGE("perchBool_","Percentage "),
/**
* Used to calculate number of true values for the returned boolean values
* of getValue().
*
* Will be presented as "n / total".
*/
BOOLEAN_TOTAL("totalBool_"),
/**
* Used to add html tags to the plugins tab.
*
* Can be used to add Tables, Images (for example maps) & other html
* elements.
*
* @see AdvancedAchievementsTable
* @see FactionsTable
* @see TownyTable
*/
HTML;
private final String modifier;
private final String placeholderModifier;
private AnalysisType(String placeholderModifier, String modifier) {
this.placeholderModifier = placeholderModifier;
this.modifier = modifier;
}
private AnalysisType(String placeholderModifier) {
this.placeholderModifier = placeholderModifier;
this.modifier = "";
}
private AnalysisType() {
this.placeholderModifier = "";
this.modifier = "";
}
/**
* Used to get the modifier for the Prefix of the value.
*
* For example: "Average Votes" when INT_AVG is used and Prefix is set as
* "Votes".
*
* @return Modifier, can be empty.
*/
public String getModifier() {
return modifier;
}
public String getPlaceholderModifier() {
return placeholderModifier;
}
}

View File

@ -1,72 +0,0 @@
package main.java.com.djrapitops.plan.data.additional;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.User;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import main.java.com.djrapitops.plan.Plan;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
/**
*
* @author Rsl1122
*/
public class EssentialsHook extends Hook {
private final Plan plugin;
private Essentials ess;
private List<String> warps;
/**
* Hooks to Essentials plugin
*
* @param plugin
*/
public EssentialsHook(Plan plugin) throws NoClassDefFoundError{
super("com.earth2me.essentials.Essentials");
this.plugin = plugin;
if (super.isEnabled()) {
ess = getPlugin(Essentials.class);
}
}
/**
*
*/
public EssentialsHook() {
super();
plugin = null;
}
/**
* Grabs information not provided by Player class or Plan from Essentials.
* isEnabled() should be called before this method.
*
* @param uuid UUID of player
* @return HashMap with boolean, int and string values: JAILED boolean,
* MUTED boolean
*/
public HashMap<String, Serializable> getEssentialsData(UUID uuid) {
HashMap<String, Serializable> essData = new HashMap<>();
User user = ess.getUser(uuid);
if (user != null) {
essData.put("JAILED", user.isJailed());
essData.put("MUTED", user.isMuted());
} else {
essData.put("JAILED", false);
essData.put("MUTED", false);
}
return essData;
}
/**
* @return Warp list
*/
public List<String> getWarps() {
return (ArrayList<String>) ess.getWarps().getList();
}
}

View File

@ -1,116 +0,0 @@
package main.java.com.djrapitops.plan.data.additional;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.FactionColl;
import com.massivecraft.factions.entity.MPlayer;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import main.java.com.djrapitops.plan.Phrase;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.comparators.FactionComparator;
/**
*
* @author Rsl1122
*/
public class FactionsHook extends Hook {
private final Plan plugin;
/**
* Hooks to Factions plugin
*
* @param plugin
*/
public FactionsHook(Plan plugin) {
super("com.massivecraft.factions.Factions");
this.plugin = plugin;
}
/**
*
*/
public FactionsHook() {
super();
plugin = null;
}
/**
* @return List of Faction names sorted by power
*/
public List<String> getTopFactions() {
List<Faction> topFactions = new ArrayList<>();
topFactions.addAll(FactionColl.get().getAll());
topFactions.remove(FactionColl.get().getWarzone());
topFactions.remove(FactionColl.get().getSafezone());
topFactions.remove(FactionColl.get().getNone());
Collections.sort(topFactions, new FactionComparator());
List<String> factionNames = topFactions.stream()
.map(faction -> faction.getName())
.collect(Collectors.toList());
return factionNames;
}
/**
* Grab basic info about Faction. isEnabled() should be called before this
* method.
*
* @param factionName Name of the faction.
* @return HashMap containing boolean, number & string: LEADER String, POWER
* String, LAND int
*/
public HashMap<String, Serializable> getFactionInfo(String factionName) {
HashMap<String, Serializable> info = new HashMap<>();
Faction faction = FactionColl.get().getByName(factionName);
if (faction != null) {
MPlayer leader = faction.getLeader();
if (leader != null) {
info.put("LEADER", leader.getNameAndSomething("", ""));
} else {
info.put("LEADER", Html.FACTION_NO_LEADER.parse());
}
info.put("POWER", FormatUtils.cutDecimals(faction.getPower()));
info.put("LAND", faction.getLandCount());
} else {
info.put("LEADER", Html.FACTION_NOT_FOUND.parse());
info.put("POWER", Html.FACTION_NOT_FOUND.parse());
info.put("LAND", Html.FACTION_NOT_FOUND.parse());
}
return info;
}
/**
* Grab info about a Player. isEnabled() should be called before this
* method.
*
* @param uuid UUID of the player
* @return HashMap containing boolean, number & string: POWER int, MAXPOWER
* int, FACTION String
*/
public HashMap<String, Serializable> getPlayerInfo(UUID uuid) {
HashMap<String, Serializable> info = new HashMap<>();
MPlayer mPlayer = MPlayer.get(uuid);
if (mPlayer != null) {
info.put("POWER", FormatUtils.cutDecimals(mPlayer.getPower()));
info.put("MAXPOWER", mPlayer.getPowerMax());
if (mPlayer.hasFaction()) {
info.put("FACTION", mPlayer.getFactionName());
} else {
info.put("FACTION", Phrase.NOT_IN_FAC + "");
}
} else {
info.put("POWER", 0);
info.put("MAXPOWER", 0);
info.put("FACTION", Phrase.NOT_IN_FAC + "");
}
return info;
}
}

View File

@ -4,16 +4,20 @@ import org.bukkit.plugin.java.JavaPlugin;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
/**
* Abstract class for easy hooking of plugins.
*
* @author Rsl1122
*/
public abstract class Hook {
private boolean enabled;
protected boolean enabled;
/**
* Class constructor.
*
* @param plugin
* Checks if the given plugin (class path) is enabled.
*
* @param plugin Class path string of the plugin's main JavaPlugin class.
*/
public Hook(String plugin) {
try {
@ -24,26 +28,11 @@ public abstract class Hook {
enabled = false;
}
}
/**
*
* Consturctor to set enabled to false.
*/
public Hook() {
enabled = false;
}
/**
* @return Whether or not the plugin was successfully hooked.
*/
public boolean isEnabled() {
return enabled;
}
/**
*
* @param enabled
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}

View File

@ -1,175 +1,182 @@
package main.java.com.djrapitops.plan.data.additional;
import java.io.Serializable;
import main.java.com.djrapitops.plan.data.additional.essentials.EssentialsHook;
import main.java.com.djrapitops.plan.data.additional.advancedachievements.AdvancedAchievementsHook;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.ui.tables.SortableFactionsTableCreator;
import main.java.com.djrapitops.plan.ui.tables.SortableTownTableCreator;
import java.util.stream.Collectors;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.data.additional.factions.FactionsHook;
import main.java.com.djrapitops.plan.data.additional.ontime.OnTimeHook;
import main.java.com.djrapitops.plan.data.additional.towny.TownyHook;
import main.java.com.djrapitops.plan.data.additional.vault.VaultHook;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
/**
* Class responsible for hooking to other plugins & managing the %plugins%
* placeholder on Analysis & Inspect pages.
*
* @author Rsl1122
*/
public class HookHandler {
private Plan plan;
private AdvancedAchievementsHook advancedAchievementsHook;
private EssentialsHook essentialsHook;
private SuperbVoteHook superbVoteHook;
private FactionsHook factionsHook;
private OnTimeHook onTimeHook;
private TownyHook townyHook;
private List<PluginData> additionalDataSources;
/**
*
* @param plan
* Class constructor, hooks to plugins.
*/
public HookHandler(Plan plan) {
this.plan = plan;
public HookHandler() {
additionalDataSources = new ArrayList<>();
hook();
}
/**
* Adds a new PluginData source to the list.
*
* The plugin data will appear on Analysis and/or Inspect pages depending on
* how the extending object is set up.
*
* Refer to documentation on github for more information.
*
* @param dataSource an object extending the PluginData class.
*/
public void reloadHooks() {
hook();
public void addPluginDataSource(PluginData dataSource) {
Log.debug("Registered a new datasource: " + dataSource.getPlaceholder("").replace("%", ""));
additionalDataSources.add(dataSource);
}
/**
* Used to get all PluginData objects currently registered.
*
* @return List of PluginData objects.
*/
public List<PluginData> getAdditionalDataSources() {
return additionalDataSources;
}
private void hook() {
try {
advancedAchievementsHook = new AdvancedAchievementsHook(plan);
AdvancedAchievementsHook advancedAchievementsHook = new AdvancedAchievementsHook(this);
} catch (NoClassDefFoundError e) {
advancedAchievementsHook = new AdvancedAchievementsHook();
}
try {
essentialsHook = new EssentialsHook(plan);
EssentialsHook essentialsHook = new EssentialsHook(this);
} catch (NoClassDefFoundError e) {
essentialsHook = new EssentialsHook();
}
try {
superbVoteHook = new SuperbVoteHook(plan);
FactionsHook factionsHook = new FactionsHook(this);
} catch (NoClassDefFoundError e) {
superbVoteHook = new SuperbVoteHook();
}
try {
factionsHook = new FactionsHook(plan);
OnTimeHook onTimeHook = new OnTimeHook(this);
} catch (NoClassDefFoundError e) {
factionsHook = new FactionsHook();
}
try {
townyHook = new TownyHook(plan);
TownyHook townyHook = new TownyHook(this);
} catch (NoClassDefFoundError e) {
townyHook = new TownyHook();
}
try {
onTimeHook = new OnTimeHook(plan);
VaultHook vaultHook = new VaultHook(this);
} catch (NoClassDefFoundError e) {
onTimeHook = new OnTimeHook();
}
}
/**
* Used to get the Layout with PluginData placeholders to replace %plugins%
* placeholder on analysis.hmtl.
*
* @return
* @return html, getPluginsTabLayout-method
* @see HtmlUtils
*/
public AdvancedAchievementsHook getAdvancedAchievementsHook() {
return advancedAchievementsHook;
public String getPluginsTabLayoutForAnalysis() {
List<String> pluginNames = getPluginNamesAnalysis();
Map<String, List<String>> placeholders = getPlaceholdersAnalysis();
return HtmlUtils.getPluginsTabLayout(pluginNames, placeholders);
}
/**
* Used to get the Layout with PluginData placeholders to replace %plugins%
* placeholder on player.hmtl.
*
* @return
* @return html, getPluginsTabLayout-method
* @see HtmlUtils
*/
public EssentialsHook getEssentialsHook() {
return essentialsHook;
public String getPluginsTabLayoutForInspect() {
List<String> pluginNames = getPluginNamesInspect();
Map<String, List<String>> placeholders = getPlaceholdersInspect();
return HtmlUtils.getPluginsTabLayout(pluginNames, placeholders);
}
private List<String> getPluginNamesAnalysis() {
List<String> pluginNames = additionalDataSources.stream()
.filter(source -> !source.getAnalysisTypes().isEmpty())
.map(source -> source.getSourcePlugin())
.distinct()
.collect(Collectors.toList());
Collections.sort(pluginNames);
return pluginNames;
}
private List<String> getPluginNamesInspect() {
List<String> pluginNames = additionalDataSources.stream()
.filter(source -> !source.analysisOnly())
.map(source -> source.getSourcePlugin())
.distinct()
.collect(Collectors.toList());
Collections.sort(pluginNames);
return pluginNames;
}
private Map<String, List<String>> getPlaceholdersAnalysis() {
Map<String, List<String>> placeholders = new HashMap<>();
for (PluginData source : additionalDataSources) {
List<AnalysisType> analysisTypes = source.getAnalysisTypes();
if (analysisTypes.isEmpty()) {
continue;
}
String pluginName = source.getSourcePlugin();
if (!placeholders.containsKey(pluginName)) {
placeholders.put(pluginName, new ArrayList<>());
}
for (AnalysisType t : analysisTypes) {
placeholders.get(pluginName).add(source.getPlaceholder(t.getPlaceholderModifier()));
}
}
return placeholders;
}
private Map<String, List<String>> getPlaceholdersInspect() {
Map<String, List<String>> placeholders = new HashMap<>();
for (PluginData source : additionalDataSources) {
if (source.analysisOnly()) {
continue;
}
String pluginName = source.getSourcePlugin();
if (!placeholders.containsKey(pluginName)) {
placeholders.put(pluginName, new ArrayList<>());
}
placeholders.get(pluginName).add(source.getPlaceholder(""));
}
return placeholders;
}
/**
* Used to get the replaceMap for inspect page.
*
* @return
*/
public SuperbVoteHook getSuperbVoteHook() {
return superbVoteHook;
}
/**
*
* @return
*/
public FactionsHook getFactionsHook() {
return factionsHook;
}
/**
*
* @return
*/
public TownyHook getTownyHook() {
return townyHook;
}
/**
*
* @return
*/
public OnTimeHook getOnTimeHook() {
return onTimeHook;
}
/**
*
* @return
*/
public Map<String, String> getAdditionalAnalysisReplaceRules() {
Map<String, String> addReplace = new HashMap<>();
AdvancedAchievementsHook aH = advancedAchievementsHook;
EssentialsHook eH = essentialsHook;
SuperbVoteHook sH = superbVoteHook;
FactionsHook fH = factionsHook;
TownyHook tH = townyHook;
addReplace.put("%towntable%", tH.isEnabled() ? SortableTownTableCreator.createSortableTownsTable(tH.getTopTowns(), tH) : "");
addReplace.put("%factionstable%", fH.isEnabled() ? SortableFactionsTableCreator.createSortableFactionsTable(fH.getTopFactions(), fH) : "");
addReplace.put("%essentialswarps%", eH.isEnabled() ? Html.WARPS.parse(eH.getWarps().toString()) : "");
return addReplace;
}
/**
*
* @param uuid
* @return
* @param uuid UUID of the player whose page is being inspected.
* @return Map: key|value - %placeholder%|value
*/
public Map<String, String> getAdditionalInspectReplaceRules(UUID uuid) {
Map<String, String> addReplace = new HashMap<>();
AdvancedAchievementsHook aH = advancedAchievementsHook;
EssentialsHook eH = essentialsHook;
SuperbVoteHook sH = superbVoteHook;
FactionsHook fH = factionsHook;
TownyHook tH = townyHook;
addReplace.put("%achievements%", (aH.isEnabled() ? Html.ACHIEVEMENTS.parse(aH.getPlayerAchievements(uuid) + "", aH.getTotalAchievements() + "") : ""));
if (eH.isEnabled()) {
HashMap<String, Serializable> essData = eH.getEssentialsData(uuid);
addReplace.put("%essentials%", ((boolean) essData.get("JAILED") ? Html.JAILED.parse() : "")
+ " " + ((boolean) essData.get("MUTED") ? Html.MUTED.parse() : ""));
} else {
addReplace.put("%essentials%", "");
}
addReplace.put("%votes%", sH.isEnabled() ? Html.VOTES.parse(sH.getVotes(uuid) + "") : "");
if (fH.isEnabled()) {
HashMap<String, Serializable> facInfo = fH.getPlayerInfo(uuid);
addReplace.put("%faction%", Html.FACTION.parse(facInfo.get("FACTION") + "", facInfo.get("POWER") + "", facInfo.get("MAXPOWER") + ""));
} else {
addReplace.put("%faction%", "");
}
if (tH.isEnabled()) {
HashMap<String, Serializable> townInfo = tH.getPlayerInfo(uuid);
addReplace.put("%town%", Html.TOWN.parse(townInfo.get("TOWN") + ""));
} else {
addReplace.put("%town%", "");
for (PluginData source : additionalDataSources) {
if (source.analysisOnly()) {
continue;
}
addReplace.put(source.getPlaceholder(""), source.getHtmlReplaceValue("", uuid));
}
return addReplace;
}

View File

@ -1,50 +0,0 @@
package main.java.com.djrapitops.plan.data.additional;
import java.io.Serializable;
import java.util.HashMap;
import java.util.UUID;
import main.java.com.djrapitops.plan.Plan;
import me.edge209.OnTime.OnTimeAPI;
import org.bukkit.Bukkit;
/**
*
* @author Rsl1122
*/
public class OnTimeHook extends Hook {
private final Plan plugin;
private OnTimeAPI ontimeAPI;
/**
* Hooks to OnTime plugin
* @param plugin
*/
public OnTimeHook(Plan plugin) throws NoClassDefFoundError{
super("me.edge209.OnTime.OnTime");
this.plugin = plugin;
}
/**
*
*/
public OnTimeHook() {
super();
plugin = null;
}
/**
* Grabs information not provided by Player class or Plan from OnTime.
* isEnabled() should be called before this method.
*
* @param uuid UUID of player
* @return HashMap with boolean, int and string values: VOTES int, REFERRALS int
*/
public HashMap<String, Serializable> getOnTimeData(UUID uuid) {
HashMap<String, Serializable> ontimeData = new HashMap<>();
String name = Bukkit.getOfflinePlayer(uuid).getName();
ontimeData.put("VOTES", OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.TOTALVOTE));
ontimeData.put("REFERRALS", OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.TOTALREFER));
return ontimeData;
}
}

View File

@ -0,0 +1,323 @@
package main.java.com.djrapitops.plan.data.additional;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import main.java.com.djrapitops.plan.ui.Html;
/**
* This is an abstract class that can be used to add data from a plugin to the
* "Plugins"-tab of Analysis & Inspect pages.
*
* API-section of documentation has examples on the usage of this class & how to
* register objects extending this class.
*
* @author Rsl1122
*/
public abstract class PluginData {
/**
* Placeholder string, for example "stepsTaken". This will be used when
* building the structure of the Plugins tab.
*
* The complete placeholder also includes the plugin name & if analysis is
* run, a modifier.
*
* Second parameter of any super constructor.
*/
protected String placeholder;
/**
* Name of the plugin the data is coming from.
*
* All datasources with the same sourcePlugin will be placed in the same
* "box" in the "Plugins" tab.
*
* A box has a max height of 600px, and higher than that will add a
* scrollbar.
*
* First parameter of any super constructor.
*/
protected String sourcePlugin;
/**
* Determines if the datapoint should only be used for the analysis page.
*
* If set to false, the datapoint will be added to the inspect page as well.
*/
protected boolean analysisOnly;
/**
* Font Awesome icon name.
*
* http://fontawesome.io/icons/
*/
protected String icon;
/**
* Prefix shown before the data, for example "Steps taken: ".
*/
protected String prefix;
/**
* Suffix shown after the data, for example " steps".
*/
protected String suffix;
/**
* A list containing the AnalysisType enums that determine what should be
* done with the data on the analysis page.
*/
protected List<AnalysisType> analysisTypes;
/**
* Main constructor.
*
* Defaults analysisOnly to true.
*
* Defaults icon, prefix & suffix to "".
*
* @param sourcePlugin Name of the plugin the data is coming from
* @param placeholder Placeholder string, for example "stepsTaken"
* @param analysisTypes A list containing the AnalysisType enums that
* determine what should be done with the data on the analysis page
*/
public PluginData(String sourcePlugin, String placeholder, List<AnalysisType> analysisTypes) {
this.placeholder = placeholder;
this.sourcePlugin = sourcePlugin;
analysisOnly = true;
this.analysisTypes = analysisTypes;
this.icon = "";
this.prefix = "";
this.suffix = "";
}
/**
* Constructor for accepting single, multiple & arrays of AnalysisType.
*
* @param sourcePlugin Name of the plugin the data is coming from
* @param placeholder Placeholder string, for example "stepsTaken"
* @param analysisTypes AnalysisType enums that determine what should be
* done with the data on the analysis page
*/
public PluginData(String sourcePlugin, String placeholder, AnalysisType... analysisTypes) {
this(sourcePlugin, placeholder, Arrays.asList(analysisTypes));
}
/**
* Constructor for Inspect-page only data point.
*
* analysisOnly will be set to false.
*
* @param sourcePlugin Name of the plugin the data is coming from
* @param placeholder Placeholder string, for example "stepsTaken"
*/
public PluginData(String sourcePlugin, String placeholder) {
this(sourcePlugin, placeholder, new ArrayList<>());
analysisOnly = false;
}
/**
* Returns the list of AnalysisTypes.
*
* Used by Analysis
*
* @return a list.
*/
public final List<AnalysisType> getAnalysisTypes() {
return analysisTypes;
}
/**
* This method should be used with the return values of
* getHtmlReplaceValue(String, UUID).
*
* It will add the div, icon, modifier, prefix & suffix to the value.
* Modifier is for example, if calculating AnalysisType.INT_AVG "Average ",
* it is a text that helps user understand that a calculation has been made.
*
* @param modifier For example "Average " - Determined by value of
* AnalysisType's modifier-variable.
* @param contents The data, number/string/html that should be placed on the
* page.
* @return a proper format for the html.
* @see AnalysisType
*/
public final String parseContainer(String modifier, String contents) {
return "<div class=\"plugin-data\">" + icon + modifier + prefix + contents + suffix + "</div>";
}
/**
* Used to get the full placeholder.
*
* Used to avoid conflicts with existing placeholders & placeholders of
* other plugins.
*
* @param modifier Modifier determined by AnalysisType's
* placeholderModifier-variable.
* @return for example "%StepCounter_stepsTaken_total%"
* @see AnalysisType
*/
public final String getPlaceholder(String modifier) {
return "%" + sourcePlugin + "_" + placeholder + modifier + "%";
}
/**
* Used to get the source plugin's name.
*
* @return for example "StepCounter"
*/
public final String getSourcePlugin() {
return sourcePlugin;
}
/**
* Used to get the string for the html page.
*
* parseContainer(modifierPrefix, value); should be used for all return
* values so that div, icon, prefix & suffix are added.
*
* This method is used when AnalysisType.HTML is set, or while getting the
* value for the inspect page.
*
* When using AnalysisType.HTML a random UUID is given, so it should be
* disregarded. modifierPrefix is empty in that case.
*
* @param modifierPrefix Modifier determined by AnalysisType's
* modifier-variable.
* @param uuid UUID of the player or random UUID if AnalysisType.HTML is
* used.
* @return html for the page.
*/
public abstract String getHtmlReplaceValue(String modifierPrefix, UUID uuid);
/**
* Used to get the value for analysis. The return value is determined by
* AnalysisType you have specified. If the AnalysisType's name has a BOOLEAN
* in it, Analysis will expect boolean values etc.
*
* If the Type & return value mismatch, exception is thrown and the result
* on the analysis page will say that error occurred as the value.
*
* If a player has no value a -1 should be returned in the case of a Number.
* -1 is excluded from the Average calculation's size & total.
*
* @param uuid UUID of the player the value belongs to.
* @return Long, Integer, Double, Boolean or String, return -1 if the player
* has no value.
*/
public abstract Serializable getValue(UUID uuid);
/**
* Used to set the prefix.
*
* @param prefix for example "Steps Taken: " or a Html start tag.
*/
public final void setPrefix(String prefix) {
this.prefix = prefix;
}
/**
* Used to set the suffix.
*
* @param suffix for example " steps" or a html end tag.
*/
public final void setSuffix(String suffix) {
this.suffix = suffix;
}
/**
* Used to set the Font Awesome icon.
*
* @param iconName Icon's name http://fontawesome.io/icons/
*/
public final void setIcon(String iconName) {
this.icon = Html.FONT_AWESOME_ICON.parse(iconName) + " ";
}
/**
* Used to set the analysisOnly parameter.
*
* true: only used for Analysis page false: used for both if AnalysisTypes
* specified, if no AnalysisTypes are specified only used for Inspect page.
*
* @param analysisOnly true/false
*/
public final void setAnalysisOnly(boolean analysisOnly) {
this.analysisOnly = analysisOnly;
}
/**
* Used to get the analysisOnly parameter.
*
* @return true/false
*/
public final boolean analysisOnly() {
return analysisOnly;
}
/**
* Used to get the prefix.
* @return example: "Steps Taken "
*/
public final String getPrefix() {
return prefix;
}
/**
* Used to get the suffix.
* @return example: " steps"
*/
public final String getSuffix() {
return suffix;
}
/**
* If a PluginData object has same placeholder, sourcePlugin &
* analysisTypes, it is considired equal.
*
* @param obj Another Object.
* @return Is current object equal to given object.
*/
@Override
public final boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final PluginData other = (PluginData) obj;
if (this.analysisOnly != other.analysisOnly) {
return false;
}
if (!Objects.equals(this.placeholder, other.placeholder)) {
return false;
}
if (!Objects.equals(this.sourcePlugin, other.sourcePlugin)) {
return false;
}
if (!Objects.equals(this.analysisTypes, other.analysisTypes)) {
return false;
}
return true;
}
@Override
public final int hashCode() {
int hash = 5;
hash = 47 * hash + Objects.hashCode(this.placeholder);
hash = 47 * hash + Objects.hashCode(this.sourcePlugin);
hash = 47 * hash + (this.analysisOnly ? 1 : 0);
hash = 47 * hash + Objects.hashCode(this.prefix);
hash = 47 * hash + Objects.hashCode(this.suffix);
hash = 47 * hash + Objects.hashCode(this.analysisTypes);
return hash;
}
}

View File

@ -1,45 +0,0 @@
package main.java.com.djrapitops.plan.data.additional;
import io.minimum.minecraft.superbvote.storage.VoteStorage;
import java.util.UUID;
import main.java.com.djrapitops.plan.Plan;
/**
*
* @author Rsl1122
*/
public class SuperbVoteHook extends Hook {
private final Plan plugin;
private VoteStorage votes;
/**
* Hooks to SuperbVote plugin
*
* @param plugin
*/
public SuperbVoteHook(Plan plugin) throws NoClassDefFoundError {
super("io.minimum.minecraft.superbvote.SuperbVote");
this.plugin = plugin;
}
/**
*
*/
public SuperbVoteHook() {
super();
plugin = null;
}
/**
* Grabs votes from SuperbVote.
* isEnabled() should be called before this
* method.
*
* @param uuid UUID of player
* @return Amount of votes
*/
public int getVotes(UUID uuid) {
return votes.getVotes(uuid);
}
}

View File

@ -1,100 +0,0 @@
package main.java.com.djrapitops.plan.data.additional;
import com.palmergames.bukkit.towny.Towny;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownyUniverse;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import main.java.com.djrapitops.plan.Phrase;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.utilities.comparators.TownComparator;
import static org.bukkit.Bukkit.getOfflinePlayer;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
/**
*
* @author Rsl1122
*/
public class TownyHook extends Hook {
private final Plan plugin;
private Towny towny;
/**
* Hooks to Factions plugin
*
* @param plugin
*/
public TownyHook(Plan plugin) throws NoClassDefFoundError {
super("com.palmergames.bukkit.towny.Towny");
this.plugin = plugin;
this.towny = getPlugin(Towny.class);
}
/**
*
*/
public TownyHook() {
super();
plugin = null;
}
/**
* @return List of Faction names sorted by power
*/
public List<String> getTopTowns() {
List<Town> topTowns = TownyUniverse.getDataSource().getTowns();
Collections.sort(topTowns, new TownComparator());
List<String> townNames = topTowns.stream()
.map(town -> town.getName())
.collect(Collectors.toList());
return townNames;
}
/**
* Grab basic info about Town. isEnabled() should be called before this
* method.
*
* @param townName Name of the town.
* @return HashMap containing boolean, number & string: RESIDENTS int, MAYOR string, LAND int
*/
public HashMap<String, Serializable> getTownInfo(String townName) {
HashMap<String, Serializable> info = new HashMap<>();
try {
Town town = TownyUniverse.getDataSource().getTown(townName);
info.put("RESIDENTS", town.getNumResidents());
info.put("MAYOR", town.getMayor().getName());
info.put("LAND", town.getPurchasedBlocks());
} catch (Exception ex) {
}
return info;
}
/**
* Grab basic info about Player. isEnabled() should be called before this
* method.
*
* @param uuid UUID of player
* @return HashMap containing boolean, number & string: TOWN string, Friends string
*/
public HashMap<String, Serializable> getPlayerInfo(UUID uuid) {
HashMap<String, Serializable> info = new HashMap<>();
String name = getOfflinePlayer(uuid).getName();
try {
Resident res = TownyUniverse.getDataSource().getResident(name);
if (res.hasTown()) {
info.put("TOWN", res.getTown().getName());
} else {
info.put("TOWN", Phrase.NOT_IN_TOWN+"");
}
info.put("FRIENDS", res.getFriends().toString());
} catch (Exception ex) {
}
return info;
}
}

View File

@ -0,0 +1,35 @@
package main.java.com.djrapitops.plan.data.additional.advancedachievements;
import com.hm.achievement.api.AdvancedAchievementsAPI;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
/**
*
* @author Rsl1122
*/
public class AdvancedAchievementsAchievements extends PluginData {
private AdvancedAchievementsAPI aaAPI;
public AdvancedAchievementsAchievements(AdvancedAchievementsAPI aaAPI) {
super("AdvancedAchievements", "achievements", new AnalysisType[]{AnalysisType.INT_TOTAL, AnalysisType.INT_AVG});
this.aaAPI = aaAPI;
super.setAnalysisOnly(false);
super.setIcon("check-circle-o");
super.setPrefix("Achivements: ");
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
return parseContainer(modifierPrefix, aaAPI.getPlayerTotalAchievements(uuid) + "");
}
@Override
public Serializable getValue(UUID uuid) {
return aaAPI.getPlayerTotalAchievements(uuid);
}
}

View File

@ -0,0 +1,34 @@
package main.java.com.djrapitops.plan.data.additional.advancedachievements;
import main.java.com.djrapitops.plan.data.additional.Hook;
import com.hm.achievement.AdvancedAchievements;
import com.hm.achievement.api.AdvancedAchievementsAPI;
import com.hm.achievement.api.AdvancedAchievementsBukkitAPI;
import main.java.com.djrapitops.plan.data.additional.HookHandler;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
/**
*
* @author Rsl1122
*/
public class AdvancedAchievementsHook extends Hook {
private AdvancedAchievements aa;
/**
* Hooks the plugin and calculates Total Achievements.
*/
public AdvancedAchievementsHook(HookHandler hookH) throws NoClassDefFoundError {
super("com.hm.achievement.AdvancedAchievements");
if (enabled) {
aa = getPlugin(AdvancedAchievements.class);
if (Integer.parseInt(Character.toString(aa.getDescription().getVersion().charAt(0))) >= 5) {
AdvancedAchievementsAPI aaAPI = AdvancedAchievementsBukkitAPI.linkAdvancedAchievements();
hookH.addPluginDataSource(new AdvancedAchievementsAchievements(aaAPI));
hookH.addPluginDataSource(new AdvancedAchievementsTable(aaAPI));
} else {
enabled = false;
}
}
}
}

View File

@ -0,0 +1,54 @@
package main.java.com.djrapitops.plan.data.additional.advancedachievements;
import com.hm.achievement.api.AdvancedAchievementsAPI;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
import static org.bukkit.Bukkit.getOfflinePlayers;
import org.bukkit.OfflinePlayer;
/**
*
* @author Rsl1122
*/
public class AdvancedAchievementsTable extends PluginData {
private AdvancedAchievementsAPI aaAPI;
public AdvancedAchievementsTable(AdvancedAchievementsAPI aaAPI) {
super("AdvancedAchievements", "achievementstable", AnalysisType.HTML);
this.aaAPI = aaAPI;
String player = Html.FONT_AWESOME_ICON.parse("user") + " Player";
String achievements = Html.FONT_AWESOME_ICON.parse("check-circle-o") + " Achievements";
// analysisOnly true by default.
super.setPrefix(Html.TABLE_START_2.parse(player, achievements));
super.setSuffix(Html.TABLE_END.parse());
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
StringBuilder html = new StringBuilder();
List<OfflinePlayer> offlinePlayers = Arrays.stream(getOfflinePlayers()).filter(p -> p.hasPlayedBefore()).collect(Collectors.toList());
if (offlinePlayers.isEmpty()) {
html.append(Html.TABLELINE_2.parse("No Players.",""));
} else {
for (OfflinePlayer p : offlinePlayers) {
String inspectUrl = HtmlUtils.getInspectUrl(p.getName());
String achievements = aaAPI.getPlayerTotalAchievements(p.getUniqueId()) + "";
html.append(Html.TABLELINE_2.parse(Html.LINK.parse(inspectUrl, p.getName()), achievements));
}
}
return parseContainer("", html.toString());
}
@Override
public Serializable getValue(UUID uuid) {
return "";
}
}

View File

@ -0,0 +1,27 @@
package main.java.com.djrapitops.plan.data.additional.essentials;
import main.java.com.djrapitops.plan.data.additional.Hook;
import com.earth2me.essentials.Essentials;
import main.java.com.djrapitops.plan.data.additional.HookHandler;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
/**
*
* @author Rsl1122
*/
public class EssentialsHook extends Hook {
/**
* Hooks to Essentials plugin
*
*/
public EssentialsHook(HookHandler hookH) throws NoClassDefFoundError{
super("com.earth2me.essentials.Essentials");
if (enabled) {
Essentials ess = getPlugin(Essentials.class);
hookH.addPluginDataSource(new EssentialsJailed(ess));
hookH.addPluginDataSource(new EssentialsMuted(ess));
hookH.addPluginDataSource(new EssentialsWarps(ess));
}
}
}

View File

@ -0,0 +1,41 @@
package main.java.com.djrapitops.plan.data.additional.essentials;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.User;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
/**
*
* @author Rsl1122
*/
public class EssentialsJailed extends PluginData {
private Essentials essentials;
public EssentialsJailed(Essentials essentials) {
super("Essentials", "jailed", AnalysisType.BOOLEAN_PERCENTAGE, AnalysisType.BOOLEAN_TOTAL);
this.essentials = essentials;
super.setIcon("ban");
super.setAnalysisOnly(false);
super.setPrefix("Jailed: ");
}
@Override
public String getHtmlReplaceValue(String modifier, UUID uuid) {
User user = essentials.getUser(uuid);
if (user != null) {
return parseContainer(modifier, user.isJailed() ? "Yes" : "No");
}
return "";
}
@Override
public Serializable getValue(UUID uuid) {
User user = essentials.getUser(uuid);
return user != null && user.isJailed();
}
}

View File

@ -0,0 +1,41 @@
package main.java.com.djrapitops.plan.data.additional.essentials;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.User;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
/**
*
* @author Rsl1122
*/
public class EssentialsMuted extends PluginData {
private Essentials essentials;
public EssentialsMuted(Essentials essentials) {
super("Essentials", "muted", AnalysisType.BOOLEAN_PERCENTAGE, AnalysisType.BOOLEAN_TOTAL);
this.essentials = essentials;
super.setIcon("bell-slash-o");
super.setAnalysisOnly(false);
super.setPrefix("Muted: ");
}
@Override
public String getHtmlReplaceValue(String modifier, UUID uuid) {
User user = essentials.getUser(uuid);
if (user != null) {
return parseContainer("", user.isMuted()? "Yes" : "No");
}
return "";
}
@Override
public Serializable getValue(UUID uuid) {
User user = essentials.getUser(uuid);
return user != null && user.isMuted();
}
}

View File

@ -0,0 +1,43 @@
package main.java.com.djrapitops.plan.data.additional.essentials;
import com.earth2me.essentials.Essentials;
import com.earth2me.essentials.Warps;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
/**
*
* @author Rsl1122
*/
public class EssentialsWarps extends PluginData {
private Essentials essentials;
public EssentialsWarps(Essentials essentials) {
super("Essentials", "warps", AnalysisType.HTML);
this.essentials = essentials;
super.setIcon("map-marker");
super.setPrefix("Warps: ");
}
@Override
public String getHtmlReplaceValue(String modifier, UUID uuid) {
Warps warps = essentials.getWarps();
if (!warps.isEmpty()) {
return parseContainer("", warps.getList().toString());
}
return parseContainer("", "No Warps.");
}
@Override
public Serializable getValue(UUID uuid) {
Warps warps = essentials.getWarps();
if (!warps.isEmpty()) {
return warps.getList().toString();
}
return "No Warps.";
}
}

View File

@ -1,4 +1,4 @@
package main.java.com.djrapitops.plan.utilities.comparators;
package main.java.com.djrapitops.plan.data.additional.factions;
import com.massivecraft.factions.entity.Faction;
import java.util.Comparator;

View File

@ -0,0 +1,36 @@
package main.java.com.djrapitops.plan.data.additional.factions;
import com.massivecraft.factions.entity.MPlayer;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.PluginData;
/**
*
* @author Rsl1122
*/
public class FactionsFaction extends PluginData {
public FactionsFaction() {
super("Factions", "faction");
super.setIcon("flag");
super.setPrefix("Faction: ");
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
MPlayer mPlayer = MPlayer.get(uuid);
String faction = mPlayer.getFactionName();
if (faction.isEmpty()) {
return parseContainer("", "No Faction.");
}
return parseContainer("", faction);
}
@Override
public Serializable getValue(UUID uuid) {
MPlayer mPlayer = MPlayer.get(uuid);
return mPlayer.getFactionName();
}
}

View File

@ -0,0 +1,49 @@
package main.java.com.djrapitops.plan.data.additional.factions;
import main.java.com.djrapitops.plan.data.additional.Hook;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.FactionColl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.additional.HookHandler;
/**
*
* @author Rsl1122
*/
public class FactionsHook extends Hook {
/**
* Hooks to Factions plugin
*
*/
public FactionsHook(HookHandler hookH) {
super("com.massivecraft.factions.Factions");
if (enabled) {
hookH.addPluginDataSource(new FactionsFaction());
hookH.addPluginDataSource(new FactionsPower());
hookH.addPluginDataSource(new FactionsMaxPower());
hookH.addPluginDataSource(new FactionsTable(this.getTopFactions()));
}
}
/**
* @return List of Faction names sorted by power
*/
public List<Faction> getTopFactions() {
List<Faction> topFactions = new ArrayList<>();
topFactions.addAll(FactionColl.get().getAll());
topFactions.remove(FactionColl.get().getWarzone());
topFactions.remove(FactionColl.get().getSafezone());
topFactions.remove(FactionColl.get().getNone());
List<String> hide = Settings.HIDE_FACTIONS.getStringList();
Collections.sort(topFactions, new FactionComparator());
List<Faction> factionNames = topFactions.stream()
.filter(faction -> !hide.contains(faction.getName()))
.collect(Collectors.toList());
return factionNames;
}
}

View File

@ -0,0 +1,33 @@
package main.java.com.djrapitops.plan.data.additional.factions;
import com.massivecraft.factions.entity.MPlayer;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
/**
*
* @author Rsl1122
*/
public class FactionsMaxPower extends PluginData {
public FactionsMaxPower() {
super("Factions", "maxpower");
super.setPrefix("Max Power: ");
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
MPlayer mPlayer = MPlayer.get(uuid);
return parseContainer(modifierPrefix, FormatUtils.cutDecimals(mPlayer.getPowerMax()));
}
@Override
public Serializable getValue(UUID uuid) {
MPlayer mPlayer = MPlayer.get(uuid);
return mPlayer.getPowerMax();
}
}

View File

@ -0,0 +1,35 @@
package main.java.com.djrapitops.plan.data.additional.factions;
import com.massivecraft.factions.entity.MPlayer;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
/**
*
* @author Rsl1122
*/
public class FactionsPower extends PluginData {
public FactionsPower() {
super("Factions", "power", AnalysisType.DOUBLE_AVG);
super.setAnalysisOnly(false);
super.setIcon("bolt");
super.setPrefix("Power: ");
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
MPlayer mPlayer = MPlayer.get(uuid);
return parseContainer(modifierPrefix, FormatUtils.cutDecimals(mPlayer.getPower()));
}
@Override
public Serializable getValue(UUID uuid) {
MPlayer mPlayer = MPlayer.get(uuid);
return mPlayer.getPower();
}
}

View File

@ -0,0 +1,64 @@
package main.java.com.djrapitops.plan.data.additional.factions;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MPlayer;
import java.io.Serializable;
import java.util.List;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
/**
*
* @author Rsl1122
*/
public class FactionsTable extends PluginData {
private List<Faction> factions;
public FactionsTable(List<Faction> factions) {
super("Factions", "factionstable", AnalysisType.HTML);
this.factions = factions;
super.setPrefix(Html.TABLE_FACTIONS_START.parse());
super.setSuffix(Html.TABLE_END.parse());
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
StringBuilder html = new StringBuilder();
if (factions.isEmpty()) {
html.append(Html.TABLELINE_4.parse(Html.FACTION_NO_FACTIONS.parse(), "", "", ""));
} else {
for (Faction f : factions) {
String name;
String leader;
String power;
String land;
if (f != null) {
name = f.getName();
MPlayer fLeader = f.getLeader();
leader = fLeader != null ? fLeader.getNameAndSomething("", "") : Html.FACTION_NO_LEADER.parse();
power = FormatUtils.cutDecimals(f.getPower());
land = f.getLandCount() + "";
} else {
name = Html.FACTION_NOT_FOUND.parse();
leader = Html.FACTION_NOT_FOUND.parse();
power = Html.FACTION_NOT_FOUND.parse();
land = Html.FACTION_NOT_FOUND.parse();
}
String leaderPage = Html.LINK.parse(HtmlUtils.getInspectUrl(leader), leader);
html.append(Html.TABLELINE_4.parse(name, power, land, leaderPage));
}
}
return parseContainer(modifierPrefix, html.toString());
}
@Override
public Serializable getValue(UUID uuid) {
MPlayer mPlayer = MPlayer.get(uuid);
return mPlayer.getPower();
}
}

View File

@ -0,0 +1,27 @@
package main.java.com.djrapitops.plan.data.additional.ontime;
import main.java.com.djrapitops.plan.data.additional.Hook;
import main.java.com.djrapitops.plan.data.additional.HookHandler;
/**
*
* @author Rsl1122
*/
public class OnTimeHook extends Hook {
/**
* Hooks to OnTime plugin
*/
public OnTimeHook(HookHandler hookH) throws NoClassDefFoundError {
super("me.edge209.OnTime.OnTime");
if (enabled) {
hookH.addPluginDataSource(new OntimeVotes());
hookH.addPluginDataSource(new OntimeVotesWeek());
hookH.addPluginDataSource(new OntimeVotesMonth());
hookH.addPluginDataSource(new OntimeRefer());
hookH.addPluginDataSource(new OntimeReferWeek());
hookH.addPluginDataSource(new OntimeReferMonth());
}
}
}

View File

@ -0,0 +1,52 @@
package main.java.com.djrapitops.plan.data.additional.ontime;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import me.edge209.OnTime.OnTimeAPI;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
/**
*
* @author Rsl1122
*/
public class OntimeRefer extends PluginData {
public OntimeRefer() {
super("OnTime", "refer", AnalysisType.INT_TOTAL, AnalysisType.INT_AVG);
super.setAnalysisOnly(false);
super.setIcon("commenting-o");
super.setPrefix("Referrals All Time: ");
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (!offlinePlayer.hasPlayedBefore()) {
return "";
}
String name = offlinePlayer.getName();
long referTotal = OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.TOTALREFER);
if (referTotal == -1) {
return parseContainer(modifierPrefix, "No Referrals.");
}
return parseContainer(modifierPrefix, referTotal + "");
}
@Override
public Serializable getValue(UUID uuid) {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (!offlinePlayer.hasPlayedBefore()) {
return 0;
}
String name = offlinePlayer.getName();
long referTotal = OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.TOTALREFER);
if (referTotal == -1) {
return 0;
}
return referTotal;
}
}

View File

@ -0,0 +1,52 @@
package main.java.com.djrapitops.plan.data.additional.ontime;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import me.edge209.OnTime.OnTimeAPI;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
/**
*
* @author Rsl1122
*/
public class OntimeReferMonth extends PluginData {
public OntimeReferMonth() {
super("OnTime", "refer_30d", AnalysisType.INT_TOTAL);
super.setAnalysisOnly(false);
super.setIcon("commenting-o");
super.setPrefix("Referrals Last 30d: ");
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (!offlinePlayer.hasPlayedBefore()) {
return "";
}
String name = offlinePlayer.getName();
long referTotal = OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.MONTHREFER);
if (referTotal == -1) {
return parseContainer(modifierPrefix, "No Referrals.");
}
return parseContainer(modifierPrefix, referTotal + "");
}
@Override
public Serializable getValue(UUID uuid) {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (!offlinePlayer.hasPlayedBefore()) {
return 0;
}
String name = offlinePlayer.getName();
long referTotal = OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.MONTHREFER);
if (referTotal == -1) {
return 0;
}
return referTotal;
}
}

View File

@ -0,0 +1,52 @@
package main.java.com.djrapitops.plan.data.additional.ontime;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import me.edge209.OnTime.OnTimeAPI;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
/**
*
* @author Rsl1122
*/
public class OntimeReferWeek extends PluginData {
public OntimeReferWeek() {
super("OnTime", "refer_7d", AnalysisType.INT_TOTAL);
super.setAnalysisOnly(false);
super.setIcon("commenting-o");
super.setPrefix("Referrals Last 7d: ");
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (!offlinePlayer.hasPlayedBefore()) {
return "";
}
String name = offlinePlayer.getName();
long referTotal = OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.WEEKREFER);
if (referTotal == -1) {
return parseContainer(modifierPrefix, "No Referrals.");
}
return parseContainer(modifierPrefix, referTotal + "");
}
@Override
public Serializable getValue(UUID uuid) {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (!offlinePlayer.hasPlayedBefore()) {
return 0;
}
String name = offlinePlayer.getName();
long referTotal = OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.WEEKREFER);
if (referTotal == -1) {
return 0;
}
return referTotal;
}
}

View File

@ -0,0 +1,52 @@
package main.java.com.djrapitops.plan.data.additional.ontime;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import me.edge209.OnTime.OnTimeAPI;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
/**
*
* @author Rsl1122
*/
public class OntimeVotes extends PluginData {
public OntimeVotes() {
super("OnTime", "votes", AnalysisType.INT_TOTAL, AnalysisType.INT_AVG);
super.setAnalysisOnly(false);
super.setIcon("check");
super.setPrefix("Votes All Time: ");
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (!offlinePlayer.hasPlayedBefore()) {
return "";
}
String name = offlinePlayer.getName();
long votesTotal = OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.TOTALVOTE);
if (votesTotal == -1) {
return parseContainer(modifierPrefix, "No votes.");
}
return parseContainer(modifierPrefix, votesTotal + "");
}
@Override
public Serializable getValue(UUID uuid) {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (!offlinePlayer.hasPlayedBefore()) {
return 0;
}
String name = offlinePlayer.getName();
long votesTotal = OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.TOTALVOTE);
if (votesTotal == -1) {
return 0;
}
return votesTotal;
}
}

View File

@ -0,0 +1,52 @@
package main.java.com.djrapitops.plan.data.additional.ontime;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import me.edge209.OnTime.OnTimeAPI;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
/**
*
* @author Rsl1122
*/
public class OntimeVotesMonth extends PluginData {
public OntimeVotesMonth() {
super("OnTime", "votes_30d", AnalysisType.INT_TOTAL);
super.setAnalysisOnly(false);
super.setIcon("check");
super.setPrefix("Votes Last 30d: ");
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (!offlinePlayer.hasPlayedBefore()) {
return "";
}
String name = offlinePlayer.getName();
long votesTotal = OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.MONTHVOTE);
if (votesTotal == -1) {
return parseContainer(modifierPrefix, "No votes.");
}
return parseContainer(modifierPrefix, votesTotal + "");
}
@Override
public Serializable getValue(UUID uuid) {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (!offlinePlayer.hasPlayedBefore()) {
return 0;
}
String name = offlinePlayer.getName();
long votesTotal = OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.MONTHVOTE);
if (votesTotal == -1) {
return 0;
}
return votesTotal;
}
}

View File

@ -0,0 +1,52 @@
package main.java.com.djrapitops.plan.data.additional.ontime;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import me.edge209.OnTime.OnTimeAPI;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
/**
*
* @author Rsl1122
*/
public class OntimeVotesWeek extends PluginData {
public OntimeVotesWeek() {
super("OnTime", "votes_7d", AnalysisType.INT_TOTAL);
super.setAnalysisOnly(false);
super.setIcon("check");
super.setPrefix("Votes Last 7d: ");
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (!offlinePlayer.hasPlayedBefore()) {
return "";
}
String name = offlinePlayer.getName();
long votesTotal = OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.WEEKVOTE);
if (votesTotal == -1) {
return parseContainer(modifierPrefix, "No votes.");
}
return parseContainer(modifierPrefix, votesTotal + "");
}
@Override
public Serializable getValue(UUID uuid) {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (!offlinePlayer.hasPlayedBefore()) {
return 0;
}
String name = offlinePlayer.getName();
long votesTotal = OnTimeAPI.getPlayerTimeData(name, OnTimeAPI.data.WEEKVOTE);
if (votesTotal == -1) {
return 0;
}
return votesTotal;
}
}

View File

@ -1,4 +1,4 @@
package main.java.com.djrapitops.plan.utilities.comparators;
package main.java.com.djrapitops.plan.data.additional.towny;
import com.palmergames.bukkit.towny.object.Town;
import java.util.Comparator;
@ -9,8 +9,15 @@ import java.util.Comparator;
*/
public class TownComparator implements Comparator<Town> {
// This method should only be used if FactionsHook.isEnabled() returns true.
// Note: this comparator imposes orderings that are inconsistent with equals.
/**
* Used to compare two Town objects.
*
* This method should only be used if TownyHook.isEnabled() returns true.
*
* Note: this comparator imposes orderings that are inconsistent with
* equals.
*
*/
@Override
public int compare(Town tow1, Town tow2) {
if (tow1.equals(tow2)) {

View File

@ -0,0 +1,42 @@
package main.java.com.djrapitops.plan.data.additional.towny;
import main.java.com.djrapitops.plan.data.additional.Hook;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownyUniverse;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.additional.HookHandler;
/**
*
* @author Rsl1122
*/
public class TownyHook extends Hook {
/**
* Hooks to Factions plugin
*
*/
public TownyHook(HookHandler hookH) throws NoClassDefFoundError {
super("com.palmergames.bukkit.towny.Towny");
if (enabled) {
hookH.addPluginDataSource(new TownyTable(getTopTowns()));
hookH.addPluginDataSource(new TownyTown());
}
}
/**
* @return List of Towns sorted by residents
*/
public List<Town> getTopTowns() {
List<Town> topTowns = TownyUniverse.getDataSource().getTowns();
Collections.sort(topTowns, new TownComparator());
List<String> hide = Settings.HIDE_TOWNS.getStringList();
List<Town> townNames = topTowns.stream()
.filter(town -> !hide.contains(town.getName()))
.collect(Collectors.toList());
return townNames;
}
}

View File

@ -0,0 +1,51 @@
package main.java.com.djrapitops.plan.data.additional.towny;
import com.massivecraft.factions.entity.MPlayer;
import com.palmergames.bukkit.towny.object.Town;
import java.io.Serializable;
import java.util.List;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
/**
*
* @author Rsl1122
*/
public class TownyTable extends PluginData {
private List<Town> towns;
public TownyTable(List<Town> towns) {
super("Towny", "townstable", AnalysisType.HTML);
this.towns = towns;
super.setPrefix(Html.TABLE_TOWNS_START.parse());
super.setSuffix(Html.TABLE_END.parse());
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
StringBuilder html = new StringBuilder();
if (towns.isEmpty()) {
html.append(Html.TABLELINE_4.parse(Html.TOWN_NO_TOWNS.parse(), "", "", ""));
} else {
for (Town t : towns) {
String name = t.getName();
String mayor = t.getMayor().getName();
String residents = t.getNumResidents() + "";
String land = t.getPurchasedBlocks() + "";
String leaderPage = Html.LINK.parse(HtmlUtils.getInspectUrl(mayor), mayor);
html.append(Html.TABLELINE_4.parse(name, residents, land, leaderPage));
}
}
return parseContainer(modifierPrefix, html.toString());
}
@Override
public Serializable getValue(UUID uuid) {
MPlayer mPlayer = MPlayer.get(uuid);
return mPlayer.getPower();
}
}

View File

@ -0,0 +1,68 @@
package main.java.com.djrapitops.plan.data.additional.towny;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.TownyUniverse;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.Phrase;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
/**
*
* @author Rsl1122
*/
public class TownyTown extends PluginData {
public TownyTown() {
super("Towny", "town");
super.setAnalysisOnly(false);
super.setIcon("bank");
super.setPrefix("Town: ");
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (!offlinePlayer.hasPlayedBefore()) {
return "";
}
String name = offlinePlayer.getName();
try {
Resident res = TownyUniverse.getDataSource().getResident(name);
String town;
if (res.hasTown()) {
town = res.getTown().getName();
} else {
town = Phrase.NOT_IN_TOWN + "";
}
return parseContainer("", town);
} catch (NotRegisteredException ex) {
return "";
}
}
@Override
public Serializable getValue(UUID uuid) {
OfflinePlayer offlinePlayer = getOfflinePlayer(uuid);
if (!offlinePlayer.hasPlayedBefore()) {
return "";
}
String name = offlinePlayer.getName();
try {
Resident res = TownyUniverse.getDataSource().getResident(name);
String town;
if (res.hasTown()) {
town = res.getTown().getName();
} else {
town = Phrase.NOT_IN_TOWN + "";
}
return town;
} catch (NotRegisteredException ex) {
return "";
}
}
}

View File

@ -0,0 +1,47 @@
package main.java.com.djrapitops.plan.data.additional.vault;
import java.io.Serializable;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import net.milkbowl.vault.economy.Economy;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
/**
*
* @author Rsl1122
*/
public class EconomyBalance extends PluginData {
private Economy econ;
public EconomyBalance(Economy econ) {
super("Vault", "balance", AnalysisType.DOUBLE_TOTAL, AnalysisType.DOUBLE_AVG);
this.econ = econ;
super.setAnalysisOnly(false);
super.setIcon("money");
super.setPrefix("Balance: ");
super.setSuffix(" "+FormatUtils.removeNumbers(econ.format(0)));
}
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
OfflinePlayer p = getOfflinePlayer(uuid);
if (p.hasPlayedBefore()) {
parseContainer(modifierPrefix, this.econ.getBalance(p)+"");
}
return "";
}
@Override
public Serializable getValue(UUID uuid) {
OfflinePlayer p = getOfflinePlayer(uuid);
if (p.hasPlayedBefore()) {
return this.econ.getBalance(p);
}
return -1;
}
}

View File

@ -0,0 +1,39 @@
package main.java.com.djrapitops.plan.data.additional.vault;
import main.java.com.djrapitops.plan.data.additional.Hook;
import main.java.com.djrapitops.plan.data.additional.HookHandler;
import net.milkbowl.vault.economy.Economy;
import static org.bukkit.Bukkit.getServer;
/**
*
* @author Rsl1122
*/
public class VaultHook extends Hook {
private Economy econ;
/**
* Hooks to Vault plugin
*
*/
public VaultHook(HookHandler hookH) throws NoClassDefFoundError {
super("net.milkbowl.vault.Vault");
if (!enabled) {
return;
}
try {
this.econ = getServer().getServicesManager().getRegistration(Economy.class).getProvider();
enabled = true;
} catch (Throwable e) {
enabled = false;
}
if (!enabled) {
return;
}
hookH.addPluginDataSource(new EconomyBalance(econ));
}
}

View File

@ -5,6 +5,7 @@ import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
import main.java.com.djrapitops.plan.data.handling.info.DeathInfo;
import main.java.com.djrapitops.plan.data.handling.info.KillInfo;
import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -42,7 +43,17 @@ public class PlanDeathEventListener implements Listener {
Player killer = dead.getKiller();
boolean killerIsPlayer = killer != null;
if (killerIsPlayer) {
handler.addToPool(new KillInfo(killer.getUniqueId(), time, dead, killer.getInventory().getItemInMainHand().getType().name()));
Material itemInHand;
try {
itemInHand = killer.getInventory().getItemInMainHand().getType();
} catch (Throwable e) {
try {
itemInHand = killer.getInventory().getItemInHand().getType();
} catch (Throwable e2) {
itemInHand = Material.AIR;
}
}
handler.addToPool(new KillInfo(killer.getUniqueId(), time, dead, itemInHand.name()));
}
if (dead instanceof Player) {
handler.addToPool(new DeathInfo(((Player) dead).getUniqueId()));

View File

@ -12,7 +12,6 @@ import main.java.com.djrapitops.plan.Plan;
*/
public class SQLiteDB extends SQLDB {
private final Plan plugin;
private final String dbName;
/**
@ -31,8 +30,6 @@ public class SQLiteDB extends SQLDB {
*/
public SQLiteDB(Plan plugin, String dbName) {
super(plugin, false);
this.plugin = plugin;
this.dbName = dbName;
}

View File

@ -12,9 +12,9 @@ import main.java.com.djrapitops.plan.database.databases.SQLDB;
*/
public abstract class Table {
String tableName;
SQLDB db;
boolean usingMySQL;
protected String tableName;
protected SQLDB db;
protected boolean usingMySQL;
public Table(String name, SQLDB db, boolean usingMySQL) {
this.tableName = name;
@ -24,7 +24,7 @@ public abstract class Table {
public abstract boolean createTable();
public Connection getConnection() throws SQLException {
protected Connection getConnection() throws SQLException {
Connection connection = db.getConnection();
if (connection == null || connection.isClosed()) {
connection = db.getNewConnection();
@ -36,17 +36,17 @@ public abstract class Table {
return db.getVersion();
}
public boolean execute(String sql) throws SQLException {
protected boolean execute(String sql) throws SQLException {
Connection connection = getConnection();
boolean success = connection.createStatement().execute(sql);
return success;
}
public PreparedStatement prepareStatement(String sql) throws SQLException {
protected PreparedStatement prepareStatement(String sql) throws SQLException {
return getConnection().prepareStatement(sql);
}
public void close(AutoCloseable toClose) {
protected void close(AutoCloseable toClose) {
if (toClose != null) {
try {
toClose.close();

View File

@ -32,28 +32,28 @@ public enum Html {
COLOR_d("<span class=\"pink\">"),
COLOR_e("<span class=\"yellow\">"),
COLOR_f("<span class=\"white\">"),
//
FONT_AWESOME_ICON("<i class=\"fa fa-REPLACE0\" aria-hidden=\"true\"></i>"),
SPAN("" + REPLACE0 + "</span>"),
BUTTON("<a class=\"button\" href=\"" + REPLACE0 + "\">" + REPLACE1 + "</a>"),
BUTTON_CLASS("class=\"button\""),
LINK("<a class=\"link\" href=\"" + REPLACE0 + "\">" + REPLACE1 + "</a>"),
LINK_CLASS("class=\"link\""),
IMG("<img src=\"" + REPLACE0 + "\">"),
COLUMNS_DIV_WRAPPER("<div class=\"columns\">" + REPLACE0 + "</div>"),
COLUMN_DIV_WRAPPER("<div class=\"about box column\">" + REPLACE0 + "</div>"),
HEADER("<div class=\"headerbox\" style=\"width: 95%;\"><div class=\"header-icon\"><div class=\"header-label\"><i class=\"fa fa-cube\" aria-hidden=\"true\"></i><span class=\"header-text\"> " + REPLACE0 + "</span></div></div></div>"),
PLUGIN_DATA_WRAPPER("<div class=\"plugin-data\">" + REPLACE0 + "</div>"),
PLUGIN_CONTAINER_START("<div class=\"plugin-container\">"),
NO_PLUGINS("<p>No extra plugins registered.</p>"),
//
TOP_TOWNS("<p><b>Top 20 Towns</b></p>"),
TOP_FACTIONS("<p><b>Top 20 Factions</b></p>"),
TOTAL_BALANCE("<p>Server Total Balance: " + REPLACE0 + "</p>"),
TOTAL_VOTES("<p>Players have voted total of " + REPLACE0 + " times.</p>"),
PLOT_OPTIONS("<p>Plot options: " + REPLACE0 + "</p>"),
FRIENDS("<p>Friends with " + REPLACE0 + "</p>"),
BALANCE("<p>Balance: " + REPLACE0 + "</p>"),
BANNED("| " + SPAN.parse(COLOR_4.parse() + "Banned")),
OPERATOR(", Operator (Op)"),
ONLINE("| " + SPAN.parse(COLOR_2.parse() + "Online")),
OFFLINE("| " + SPAN.parse(COLOR_4.parse() + "Offline")),
ACTIVE("Player is Active"),
INACTIVE("Player is inactive"),
ERROR_LIST("Error Creating List</p>"),
HIDDEN("Hidden (config)"),
ERROR_NOT_SET("Error: Replace rule was not set"),
BALANCE("<p>Balance: " + REPLACE0 + "</p>"),
FACTION_NOT_FOUND("Faction not found"),
FACTION_NO_LEADER("No leader"),
FACTION_NO_FACTIONS("No Factions"),
@ -65,6 +65,17 @@ public enum Html {
FACTION("<br/>Faction: " + REPLACE0 + " | Power: " + REPLACE1 + "/REPLACE2"),
TOWN("<br/>Town: " + REPLACE0),
TOWN_NO_TOWNS("No Towns"),
//
BANNED("| " + SPAN.parse(COLOR_4.parse() + "Banned")),
OPERATOR(", Operator (Op)"),
ONLINE("| " + SPAN.parse(COLOR_2.parse() + "Online")),
OFFLINE("| " + SPAN.parse(COLOR_4.parse() + "Offline")),
ACTIVE("Player is Active"),
INACTIVE("Player is inactive"),
ERROR_LIST("Error Creating List</p>"),
HIDDEN("Hidden (config)"),
ERROR_NOT_SET("Error: Replace rule was not set"),
//
GRAPH_BANNED("Banned"),
GRAPH_UNKNOWN("Unknown"),
GRAPH_INACTIVE("Inactive"),
@ -72,12 +83,14 @@ public enum Html {
GRAPH_ONLINE("Players Online"),
GRAPH_PLAYERS("Players"),
GRAPH_DATE("Date"),
//
TABLE_START_2("<table class=\"sortable table\"><thead><tr><th>REPLACE0</th><th>REPLACE1</th></tr></thead><tbody>"),
TABLE_START_3("<table class=\"sortable table\"><thead><tr><th>REPLACE0</th><th>REPLACE1</th><th>REPLACE2</th></tr></thead><tbody>"),
TABLE_START_4("<table class=\"sortable table\"><thead><tr><th>REPLACE0</th><th>REPLACE1</th><th>REPLACE2</th><th>REPLACE3</th></tr></thead><tbody>"),
TABLE_SESSIONS_START(TABLE_START_3.parse("Session Started", "Session Ended", "Session Length")),
TABLE_KILLS_START(TABLE_START_3.parse("Date", "Killed", "With")),
TABLE_FACTIONS_START(TABLE_START_4.parse("Faction", "Power", "Land", "Leader")),
TABLE_TOWNS_START(TABLE_START_4.parse("Town", "Residents", "Land", "Mayor")),
TABLE_FACTIONS_START(TABLE_START_4.parse(FONT_AWESOME_ICON.parse("flag")+" Faction", FONT_AWESOME_ICON.parse("bolt")+" Power", FONT_AWESOME_ICON.parse("map-o")+" Land", FONT_AWESOME_ICON.parse("user")+" Leader")),
TABLE_TOWNS_START(TABLE_START_4.parse(FONT_AWESOME_ICON.parse("bank")+" Town", FONT_AWESOME_ICON.parse("users")+" Residents", FONT_AWESOME_ICON.parse("map-o")+" Land", FONT_AWESOME_ICON.parse("user")+" Mayor")),
TABLELINE_2("<tr><td><b>" + REPLACE0 + "</b></td><td>" + REPLACE1 + "</td></tr>"),
TABLELINE_3("<tr><td><b>" + REPLACE0 + "</b></td><td>" + REPLACE1 + "</td><td>REPLACE2</td></tr>"),
TABLELINE_4("<tr><td><b>" + REPLACE0 + "</b></td><td>" + REPLACE1 + "</td><td>REPLACE2</td><td>REPLACE3</td></tr>"),

View File

@ -23,7 +23,7 @@ public class PlayerActivityGraphCreator {
public static String[] generateDataArray(List<SessionData> sessionData, long scale, int maxPlayers) {
long now = new Date().toInstant().getEpochSecond() * (long) 1000;
long nowMinusScale = now - scale;
List<List<Long>> s = filterSessions(sessionData, nowMinusScale);
List<List<Long>> s = filterAndTransformSessions(sessionData, nowMinusScale);
List<Long> sessionStarts = s.get(0);
List<Long> sessionEnds = s.get(1);
List<Long> playersOnline = new ArrayList<>();
@ -63,9 +63,10 @@ public class PlayerActivityGraphCreator {
.count();
}
public static List<List<Long>> filterSessions(List<SessionData> sessionData, long nowMinusScale) {
public static List<List<Long>> filterAndTransformSessions(List<SessionData> sessionData, long nowMinusScale) {
List<Long[]> values = sessionData.parallelStream()
.filter(session -> (session != null))
.filter(session -> session.isValid())
.filter((session) -> (session.getSessionStart() >= nowMinusScale || session.getSessionEnd() >= nowMinusScale))
.map(session -> new Long[]{session.getSessionStart(), session.getSessionEnd()})
.collect(Collectors.toList());

View File

@ -1,41 +0,0 @@
package main.java.com.djrapitops.plan.ui.tables;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import main.java.com.djrapitops.plan.data.additional.FactionsHook;
import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
/**
*
* @author Rsl1122
*/
public class SortableFactionsTableCreator {
/**
*
* @param factionList
* @param fHook
* @return
*/
public static String createSortableFactionsTable(Collection<String> factionList, FactionsHook fHook) {
String html = Html.TABLE_FACTIONS_START.parse();
if (factionList.isEmpty()) {
html += Html.TABLELINE_4.parse(Html.FACTION_NO_FACTIONS.parse(), "", "", "");
} else {
for (String factionName : factionList) {
HashMap<String, Serializable> info = fHook.getFactionInfo(factionName);
String leader = (String) info.get("LEADER");
html += Html.TABLELINE_4.parse(
factionName,
info.get("POWER") + "",
info.get("LAND") + "",
Html.LINK.parse(HtmlUtils.getInspectUrl(leader), leader)
);
}
}
html += Html.TABLE_END.parse();
return html;
}
}

View File

@ -1,40 +0,0 @@
package main.java.com.djrapitops.plan.ui.tables;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import main.java.com.djrapitops.plan.data.additional.TownyHook;
import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
/**
*
* @author Rsl1122
*/
public class SortableTownTableCreator {
/**
*
* @param townNames
* @param tHook
* @return
*/
public static String createSortableTownsTable(Collection<String> townNames, TownyHook tHook) {
String html = Html.TABLE_TOWNS_START.parse();
if (townNames.isEmpty()) {
html += Html.TABLELINE_4.parse(Html.TOWN_NO_TOWNS.parse(), "", "", "");
} else {
for (String town : townNames) {
HashMap<String, Serializable> info = tHook.getTownInfo(town);
html += Html.TABLELINE_4.parse(
town,
info.get("RESIDENTS") + "",
info.get("LAND") + "",
Html.LINK.parse(HtmlUtils.getInspectUrl((String) info.get("MAYOR")), (String) info.get("MAYOR"))
);
}
}
html += Html.TABLE_END.parse();
return html;
}
}

View File

@ -81,7 +81,7 @@ public class Response {
try {
String dataHtml = requestHandler.getInspectHtml(uuid);
String htmlDef = "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html; charset=utf-8\r\n"
+ "Content-Type: text/html;\r\n"
+ "Content-Length: " + dataHtml.length() + "\r\n"
+ "\r\n";
output.write((htmlDef + dataHtml).getBytes());
@ -101,7 +101,7 @@ public class Response {
if (requestHandler.checkIfAnalysisIsCached()) {
String analysisHtml = requestHandler.getAnalysisHtml();
String htmlDef = "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html; charset=utf-8\r\n"
+ "Content-Type: text/html;\r\n"
+ "Content-Length: " + analysisHtml.length() + "\r\n"
+ "\r\n";
output.write((htmlDef + analysisHtml).getBytes());

View File

@ -19,6 +19,9 @@ import main.java.com.djrapitops.plan.data.KillData;
import main.java.com.djrapitops.plan.data.RawAnalysisData;
import main.java.com.djrapitops.plan.data.SessionData;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.HookHandler;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import main.java.com.djrapitops.plan.data.cache.AnalysisCacheHandler;
import main.java.com.djrapitops.plan.data.cache.InspectCacheHandler;
import main.java.com.djrapitops.plan.database.Database;
@ -255,6 +258,7 @@ public class Analysis {
analysisData.setTotalmobkills(sorted.getTotalMobKills());
analysisData.setRefreshDate(new Date().getTime());
analysisData.setGenderData(sorted.getGenders());
analysisData.setAdditionalDataReplaceMap(analyzeAdditionalPluginData(uuids));
analysisCache.cache(analysisData);
if (Settings.ANALYSIS_LOG_FINISHED.isTrue()) {
Log.info(Phrase.ANALYSIS_COMPLETE + "");
@ -357,4 +361,51 @@ public class Analysis {
aData.setGeomapZ(z.replace(",]", "]"));
aData.setGeomapCodes(text.replace(",]", "]"));
}
private Map<String, String> analyzeAdditionalPluginData(List<UUID> uuids) {
Map<String, String> replaceMap = new HashMap<>();
HookHandler hookHandler = Plan.getInstance().getHookHandler();
List<PluginData> sources = hookHandler.getAdditionalDataSources();
for (PluginData source : sources) {
Log.debug("Analyzing source: " + source.getPlaceholder("").replace("%", ""));
try {
List<AnalysisType> analysisTypes = source.getAnalysisTypes();
if (analysisTypes.isEmpty()) {
continue;
}
if (analysisTypes.contains(AnalysisType.HTML)) {
replaceMap.put(source.getPlaceholder(AnalysisType.HTML.getPlaceholderModifier()), source.getHtmlReplaceValue(AnalysisType.HTML.getModifier(), uuids.get(0)));
continue;
}
AnalysisType[] totalTypes = new AnalysisType[]{
AnalysisType.INT_TOTAL, AnalysisType.LONG_TOTAL, AnalysisType.LONG_TIME_MS_TOTAL, AnalysisType.DOUBLE_TOTAL
};
for (AnalysisType type : totalTypes) {
if (analysisTypes.contains(type)) {
replaceMap.put(source.getPlaceholder(type.getPlaceholderModifier()), AnalysisUtils.getTotal(type, source, uuids));
}
}
AnalysisType[] avgTypes = new AnalysisType[]{
AnalysisType.INT_AVG, AnalysisType.LONG_AVG, AnalysisType.LONG_TIME_MS_AVG, AnalysisType.LONG_EPOCH_MS_MINUS_NOW_AVG, AnalysisType.DOUBLE_AVG
};
for (AnalysisType type : avgTypes) {
if (analysisTypes.contains(type)) {
replaceMap.put(source.getPlaceholder(type.getPlaceholderModifier()), AnalysisUtils.getAverage(type, source, uuids));
}
}
AnalysisType t = AnalysisType.BOOLEAN_PERCENTAGE;
if (analysisTypes.contains(t)) {
replaceMap.put(source.getPlaceholder(t.getPlaceholderModifier()), AnalysisUtils.getBooleanPercentage(t, source, uuids));
}
t = AnalysisType.BOOLEAN_TOTAL;
if (analysisTypes.contains(t)) {
replaceMap.put(source.getPlaceholder(t.getPlaceholderModifier()), AnalysisUtils.getBooleanTotal(t, source, uuids));
}
} catch (Throwable e) {
Log.error("A PluginData-source caused an exception: " + source.getPlaceholder("").replace("%", ""));
Log.toLog(this.getClass().getName(), e);
}
}
return replaceMap;
}
}

View File

@ -1,13 +1,20 @@
package main.java.com.djrapitops.plan.utilities;
import java.io.Serializable;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.OptionalDouble;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.SessionData;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
import main.java.com.djrapitops.plan.ui.tables.SortableCommandUseTableCreator;
import main.java.com.djrapitops.plan.ui.tables.SortablePlayersTableCreator;
@ -97,4 +104,137 @@ public class AnalysisUtils {
}
return total / list.size();
}
// Refactor to MathUtils class
public static String getTotal(AnalysisType analysisType, PluginData source, List<UUID> uuids) {
try {
if (null != analysisType) {
Number total;
switch (analysisType) {
case INT_TOTAL:
total = getCorrectValues(uuids, source)
.mapToInt(value -> (Integer) value)
.sum();
break;
case LONG_TOTAL:
total = getCorrectValues(uuids, source)
.mapToLong(value -> (Long) value)
.sum();
break;
case LONG_TIME_MS_TOTAL:
total = getCorrectValues(uuids, source)
.mapToLong(value -> (Long) value)
.sum();
return source.parseContainer(analysisType.getModifier(), FormatUtils.formatTimeAmount(total + ""));
case DOUBLE_TOTAL:
total = getCorrectValues(uuids, source)
.mapToDouble(value -> (Double) value)
.sum();
break;
default:
return source.parseContainer("ERROR ", "Wrong Analysistype specified: " + analysisType.name());
}
return source.parseContainer(analysisType.getModifier(), total + "");
}
} catch (Throwable e) {
Log.toLog("com.djrapitops.plan.utilities.AnalysisUtils", e);
}
return source.parseContainer("ERROR ", "Exception during total calculation.");
}
private static Stream<Serializable> getCorrectValues(List<UUID> uuids, PluginData source) {
return uuids.stream()
.map(uuid -> source.getValue(uuid))
.filter(value -> !value.equals(-1));
}
// Refactor to MathUtils class
public static String getAverage(AnalysisType analysisType, PluginData source, List<UUID> uuids) {
try {
if (null != analysisType) {
Number total;
switch (analysisType) {
case LONG_EPOCH_MS_MINUS_NOW_AVG:
final long now = new Date().getTime();
List<Long> longValues = getCorrectValues(uuids, source)
.map(value -> ((long) value) - now)
.collect(Collectors.toList());
return source.parseContainer(analysisType.getModifier(), FormatUtils.formatTimeAmount(average(longValues) + ""));
case INT_AVG:
OptionalDouble avg = getCorrectValues(uuids, source)
.map(value -> (Integer) value)
.mapToInt(i -> i)
.average();
if (!avg.isPresent()) {
total = 0;
} else {
total = avg.getAsDouble();
}
break;
case LONG_AVG:
List<Long> longVal = getCorrectValues(uuids, source)
.map(value -> (Long) value)
.collect(Collectors.toList());
total = average(longVal);
break;
case LONG_TIME_MS_AVG:
List<Long> longVal2 = getCorrectValues(uuids, source)
.map(value -> (Long) value)
.collect(Collectors.toList());
return source.parseContainer(analysisType.getModifier(), FormatUtils.formatTimeAmount(average(longVal2) + ""));
case DOUBLE_AVG:
OptionalDouble average = getCorrectValues(uuids, source)
.mapToDouble(value -> (Double) value)
.average();
if (!average.isPresent()) {
total = 0;
} else {
total = average.getAsDouble();
}
break;
default:
return source.parseContainer("", "Wrong Analysistype specified: " + analysisType.name());
}
return source.parseContainer(analysisType.getModifier(), total + "");
}
} catch (Throwable e) {
Log.error("A PluginData-source caused an exception: "+source.getPlaceholder("").replace("%", ""));
Log.toLog("com.djrapitops.plan.utilities.AnalysisUtils", e);
}
return source.parseContainer("", "Exception during average calculation.");
}
static String getBooleanPercentage(AnalysisType analysisType, PluginData source, List<UUID> uuids) {
if (analysisType == AnalysisType.BOOLEAN_PERCENTAGE) {
try {
List<Boolean> tempList = getCorrectValues(uuids, source)
.map(value -> (boolean) value)
.collect(Collectors.toList());
long count = tempList.stream().filter(value -> value).count();
return source.parseContainer(analysisType.getModifier(), ((double) (count / tempList.size()) * 100) + "%");
} catch (Throwable e) {
Log.error("A PluginData-source caused an exception: "+source.getPlaceholder("").replace("%", ""));
Log.toLog("com.djrapitops.plan.utilities.AnalysisUtils", e);
return source.parseContainer("", "Exception during calculation.");
}
}
return source.parseContainer("", "Wrong Analysistype specified: " + analysisType.name());
}
static String getBooleanTotal(AnalysisType analysisType, PluginData source, List<UUID> uuids) {
if (analysisType == AnalysisType.BOOLEAN_TOTAL) {
try {
List<Boolean> tempList = getCorrectValues(uuids, source)
.map(value -> (boolean) value)
.collect(Collectors.toList());
long count = tempList.stream().filter(value -> value).count();
return source.parseContainer(analysisType.getModifier(), count + " / " + tempList.size());
} catch (Throwable e) {
Log.error("A PluginData-source caused an exception: "+source.getPlaceholder("").replace("%", ""));
Log.toLog("com.djrapitops.plan.utilities.AnalysisUtils", e);
return source.parseContainer("", "Exception during calculation.");
}
}
return source.parseContainer("", "Wrong Analysistype specified: " + analysisType.name());
}
}

View File

@ -72,6 +72,14 @@ public class FormatUtils {
public static String removeLetters(String dataPoint) {
return dataPoint.replaceAll("[^\\d.]", "");
}
public static String removeNumbers(String dataPoint) {
for (char c : removeLetters(dataPoint).toCharArray()) {
dataPoint = dataPoint.replace(c+"", "");
}
dataPoint = dataPoint.replace(" ", "");
return dataPoint;
}
// Formats long in milliseconds into d:h:m:s string
private static String turnMsLongToString(long ms) {

View File

@ -2,10 +2,13 @@ package main.java.com.djrapitops.plan.utilities;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.ui.Html;
/**
*
@ -40,7 +43,7 @@ public class HtmlUtils {
* @param replaceMap
* @return
*/
public static String replacePlaceholders(String html, HashMap<String, String> replaceMap) {
public static String replacePlaceholders(String html, Map<String, String> replaceMap) {
for (String key : replaceMap.keySet()) {
html = html.replace(key, replaceMap.get(key));
}
@ -91,4 +94,49 @@ public class HtmlUtils {
.replace("<script>", "")
.replace("</script>", "");
}
public static String getPluginsTabLayout(List<String> pluginNames, Map<String, List<String>> placeholders) {
boolean sizeIsEvenNumber = pluginNames.size() % 2 == 0;
StringBuilder html = new StringBuilder();
String temp = "";
int evenSize = pluginNames.size() - (pluginNames.size() % 2);
Log.debug("Html parsing for:" + pluginNames + ", " + (evenSize));
for (int i = 0; i < evenSize; i++) {
String name = pluginNames.get(i);
Log.debug("Html parsing: " + name);
if (i % 2 == 0) {
temp = Html.COLUMN_DIV_WRAPPER.parse(getContent(name, placeholders.get(name)));
} else {
html.append(Html.COLUMNS_DIV_WRAPPER.parse(temp + Html.COLUMN_DIV_WRAPPER.parse(getContent(name, placeholders.get(name)))));
}
}
if (!sizeIsEvenNumber) {
int lastIndex = pluginNames.size() - 1;
String name = pluginNames.get(lastIndex);
html.append(Html.COLUMNS_DIV_WRAPPER.parse(Html.COLUMN_DIV_WRAPPER.parse(getContent(name, placeholders.get(name)))+Html.COLUMN_DIV_WRAPPER.parse("")));
}
String returnValue = html.toString();
if (returnValue.isEmpty()) {
return Html.COLUMNS_DIV_WRAPPER.parse(
Html.COLUMN_DIV_WRAPPER.parse(
Html.PLUGIN_DATA_WRAPPER.parse(
Html.NO_PLUGINS.parse()
)
)
);
}
return returnValue;
}
private static String getContent(String name, List<String> placeholders) {
Log.debug("Getting content for: "+name);
StringBuilder html = new StringBuilder();
html.append(Html.HEADER.parse(name));
html.append(Html.PLUGIN_CONTAINER_START.parse());
for (String placeholder : placeholders) {
html.append(placeholder);
}
html.append("</div>");
return html.toString();
}
}

View File

@ -16,9 +16,9 @@ import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
import main.java.com.djrapitops.plan.database.Database;
import main.java.com.djrapitops.plan.database.databases.SQLiteDB;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.GameMode;
import org.bukkit.OfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
/**
*
@ -41,7 +41,8 @@ public class ManageUtils {
final Collection<UUID> uuids = ManageUtils.getUUIDS(copyFromDB);
if (uuids.isEmpty()) {
return false;
}
}
backupDB.init();
return clearAndCopy(backupDB, copyFromDB, uuids);
}
@ -58,7 +59,7 @@ public class ManageUtils {
for (UUID uuid : onTimeData.keySet()) {
OfflinePlayer player = getOfflinePlayer(uuid);
if (!plugin.getDB().wasSeenBefore(uuid)) {
handler.newPlayer(player);
}
DBCallableProcessor importer = new DBCallableProcessor() {

View File

@ -29,7 +29,7 @@ public class PlaceholderUtils {
* @param data AnalysisData used to replace the placeholders with
* @return HashMap that contains string for each placeholder.
*/
public static HashMap<String, String> getAnalysisReplaceRules(AnalysisData data) {
public static Map<String, String> getAnalysisReplaceRules(AnalysisData data) {
HashMap<String, String> replaceMap = new HashMap<>();
replaceMap.put("%gm0%", (int) (data.getGm0Perc() * 100) + "%");
replaceMap.put("%gm1%", (int) (data.getGm1Perc() * 100) + "%");
@ -105,11 +105,20 @@ public class PlaceholderUtils {
+ "\",\"#" + Settings.HCOLOR_GENP_U + "\"");
replaceMap.put("%genderfcolor%", "#" + Settings.HCOLOR_GENP_F);
replaceMap.put("%gendermcolor%", "#" + Settings.HCOLOR_GENP_M);
replaceMap.putAll(plugin.getHookHandler().getAdditionalAnalysisReplaceRules());
replaceMap.put("%sessionaverage%", FormatUtils.formatTimeAmount(data.getSessionAverage() + ""));
replaceMap.put("%geomapcountries%", data.getGeomapCountries());
replaceMap.put("%geomapz%", data.getGeomapZ());
replaceMap.put("%geomapcodes%", data.getGeomapCodes());
String pluginsTabHtml = plugin.getHookHandler().getPluginsTabLayoutForAnalysis();
String replacedOnce = HtmlUtils.replacePlaceholders(pluginsTabHtml, data.getAdditionalDataReplaceMap());
replaceMap.put("%plugins%", HtmlUtils.replacePlaceholders(replacedOnce, data.getAdditionalDataReplaceMap()));
String[] colors = new String[]{Settings.HCOLOR_MAIN.toString(), Settings.HCOLOR_MAIN_DARK.toString(), Settings.HCOLOR_SEC.toString(), Settings.HCOLOR_TER.toString(), Settings.HCOLOR_TER_DARK.toString()};
String[] defaultCols = new String[]{"348e0f", "267F00", "5cb239", "89c471", "5da341"};
for (int i = 0; i < colors.length; i++) {
if (!defaultCols[i].equals(colors[i])) {
replaceMap.put("#"+defaultCols[i], "#"+colors[i]);
}
}
return replaceMap;
}
@ -120,7 +129,7 @@ public class PlaceholderUtils {
* @return HashMap that contains string for each placeholder.
* @throws java.io.FileNotFoundException if planliteplayer.html is not found
*/
public static HashMap<String, String> getInspectReplaceRules(UserData data) throws FileNotFoundException {
public static Map<String, String> getInspectReplaceRules(UserData data) throws FileNotFoundException {
HashMap<String, String> replaceMap = new HashMap<>();
boolean showIPandUUID = Settings.SECURITY_IP_UUID.isTrue();
UUID uuid = data.getUuid();
@ -189,7 +198,10 @@ public class PlaceholderUtils {
replaceMap.put("%gm2col%", Settings.HCOLOR_GMP_2 + "");
replaceMap.put("%gm3col%", Settings.HCOLOR_GMP_3 + "");
replaceMap.put("%inaccuratedatawarning%", (new Date().getTime() - data.getRegistered() < 180000) ? Html.WARN_INACCURATE.parse() : "");
replaceMap.putAll(plugin.getHookHandler().getAdditionalInspectReplaceRules(uuid));
String pluginsTabHtml = plugin.getHookHandler().getPluginsTabLayoutForInspect();
Map<String, String> additionalReplaceRules = plugin.getHookHandler().getAdditionalInspectReplaceRules(uuid);
String replacedOnce = HtmlUtils.replacePlaceholders(pluginsTabHtml, additionalReplaceRules);
replaceMap.put("%plugins%", HtmlUtils.replacePlaceholders(replacedOnce, additionalReplaceRules));
return replaceMap;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -38,6 +38,12 @@ Customization:
Secondary: '&7'
Highlight: '&f'
HTML:
UI:
Main: 348e0f
MainDark: 267F00
Secondary: 5cb239
Tertiary: 89c471
TertiaryDark: 5da341
ActivityGraph:
OnlinePlayers: '1E90FF'
OnlinePlayersFill: '75BBFF'
@ -61,6 +67,13 @@ Customization:
Female: 'female, girl, gurl, woman, gal, mrs, she, miss, feminin, weiblich, mädchen, frau'
Male: 'male, boy, man, boe, sir, mr, guy, he, männlich, maskulin, junge, mann'
IgnoreWhen: 'sure, think, with, are, you, din'
Plugins:
Factions:
HideFactions:
- ExampleFaction
Towny:
HideTowns:
- ExampleTown
database:
type: sqlite

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
name: Plan
author: Rsl1122
main: main.java.com.djrapitops.plan.Plan
version: 3.0.2
version: 3.1.0
softdepend:
- OnTime
@ -9,7 +9,6 @@ softdepend:
- Towny
- Vault
- Factions
- SuperbVote
- AdvancedAchievements
commands:
@ -19,9 +18,15 @@ commands:
inspect:
usage: /plan inspect <name>
description: inspect player data
qinspect:
usage: /plan qinspect <name>
description: inspect player data & view in chatbox
analyze:
usage: /plan analyze
description: analyze all players' data, add -refresh to refresh analysis.
description: analyze all players' data
qanalyze:
usage: /plan qanalyze
description: analyze all players' data & view in chatbox
reload:
usage: /plan reload
description: reload plugin config
@ -42,9 +47,17 @@ permissions:
plan.inspect.other:
description: Allows you to check other players' player data.
default: op
plan.qinspect:
description: Allows you to check your player data.
default: op
plan.qinspect.other:
description: Allows you to check other players' player data.
plan.analyze:
description: Allows you to check analysed data about all players.
default: op
plan.qanalyze:
description: Allows you to check analysed data about all players.
default: op
plan.reload:
description: Allows to reload plugin config
default: op
@ -64,17 +77,20 @@ permissions:
plan.basic:
children:
plan.?: true
plan.inspect: true
plan.inspect: true
plan.qinspect: true
plan.advanced:
childer:
plan.basic: true
plan.info: true
plan.analyze: true
plan.info: true
plan.qanalyze: true
plan.staff:
children:
plan.search: true
plan.advanced: true
plan.analyze: true
plan.inspect.other: true
plan.qinspect.other: true
plan.reload: true
plan.*:
children:

Some files were not shown because too many files have changed in this diff Show More