Kills, Deaths, Combined locale files, Security, bugfixes [2.5.0]

More info in the change log 2.5.0
This commit is contained in:
Rsl1122 2017-02-11 00:11:43 +02:00
parent 06bbc50df2
commit 7f29d3dcc1
27 changed files with 398 additions and 120 deletions

View File

@ -1,19 +0,0 @@
WARN_INACCURATE <> <div class="warn">Data might be inaccurate, player has just registered.</div>
ERROR_TABLE <> <p class="red">Error Calcuclating Table (No data)</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>
TOWN <> <p>Town: REPLACE0</p>
PLOT_OPTIONS <> <p>Plot options: REPLACE0</p>
FRIENDS <> <p>Friends with REPLACE0</p>
FACTION <> <p>Faction: REPLACE0</p>
BALANCE <> <p>Balance: REPLACE0</p>
VOTES <> <p>Player has voted REPLACE0 times.</p>
BANNED <> | <span class="darkred">Banned</span>
OPERATOR <> , Operator (Op)
ONLINE <> | <span class="darkgreen">Online</span>
OFFLINE <> | <span class="darkred">Offline</span>
ACTIVE <> | Player is Active
INACTIVE <> | Player is inactive
ERROR_LIST <> Error Creating List</p>

View File

@ -1,19 +0,0 @@
WARN_INACCURATE <> <div class="warn">Tiedot voivat olla viallisia, pelaaja rekisteröityi vasta</div>
ERROR_TABLE <> <p class="red">Virhe tehdessä taulukkoa (Ei dataa)</p>
TOP_TOWNS <> <p><b>Top 20 Kylää</b></p>
TOP_FACTIONS <> <p><b>Top 20 Kiltaa</b></p>
TOTAL_BALANCE <> <p>Palvelimen rahan kokonaismäärä: REPLACE0</p>
TOTAL_VOTES <> <p>Pelaajat ovat äänestäneet REPLACE0 kertaa.</p>
TOWN <> <p>Kylä: REPLACE0</p>
PLOT_OPTIONS <> <p>Plot asetukset: REPLACE0</p>
FRIENDS <> <p>Kaverit: REPLACE0</p>
FACTION <> <p>Kilta: REPLACE0</p>
BALANCE <> <p>Rahamäärä: REPLACE0</p>
VOTES <> <p>Pelaaja on äänestänyt REPLACE0 kertaa.</p>
BANNED <> | <span class="darkred">Banned</span>
OPERATOR <> , Operator (Op)
ONLINE <> | <span class="darkgreen">Online</span>
OFFLINE <> | <span class="darkred">Offline</span>
ACTIVE <> | Pelaaja on aktiivinen
INACTIVE <> | Pelaaja on inaktiivinen
ERROR_LIST <> Virhe luodessa listaa</p>

View File

@ -97,3 +97,23 @@ COMMAND_REQUIRES_ARGUMENTS <> §c[Plan] Command requires arguments. REPLACE0
COMMAND_ADD_CONFIRMATION_ARGUMENT <> §c[Plan] Add -a to confirm execution! REPLACE0
COMMAND_REQUIRES_ARGUMENTS_ONE <> §c[Plan] Command requires one argument.
COMMAND_NO_PERMISSION <> §c[Plan] You do not have the required permmission.
<<<<<<HTML>>>>>>
WARN_INACCURATE <> <div class="warn">Data might be inaccurate, player has just registered.</div>
ERROR_TABLE <> <p class="red">Error Calcuclating Table (No data)</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>
TOWN <> <p>Town: REPLACE0</p>
PLOT_OPTIONS <> <p>Plot options: REPLACE0</p>
FRIENDS <> <p>Friends with REPLACE0</p>
FACTION <> <p>Faction: REPLACE0</p>
BALANCE <> <p>Balance: REPLACE0</p>
VOTES <> <p>Player has voted REPLACE0 times.</p>
BANNED <> | <span class="darkred">Banned</span>
OPERATOR <> , Operator (Op)
ONLINE <> | <span class="darkgreen">Online</span>
OFFLINE <> | <span class="darkred">Offline</span>
ACTIVE <> | Player is Active
INACTIVE <> | Player is inactive
ERROR_LIST <> Error Creating List</p>

View File

@ -96,4 +96,24 @@ COMMAND_SENDER_NOT_PLAYER <> §c[Plan] Tätä komentoa voi käyttää vain pelaa
COMMAND_REQUIRES_ARGUMENTS <> §c[Plan] Komento vaatii argumentteja. REPLACE0
COMMAND_ADD_CONFIRMATION_ARGUMENT <> §c[Plan] Lisää -a vahvistaaksesi komennon ajo! REPLACE0
COMMAND_REQUIRES_ARGUMENTS_ONE <> §c[Plan] Komento vaatii yhden argumentin..
COMMAND_NO_PERMISSION <> §c[Plan] Sinulla ei ole lupaa tuohon.
COMMAND_NO_PERMISSION <> §c[Plan] Sinulla ei ole lupaa tuohon.
<<<<<<HTML>>>>>>
WARN_INACCURATE <> <div class="warn">Tiedot voivat olla viallisia, pelaaja rekisteröityi vasta</div>
ERROR_TABLE <> <p class="red">Virhe tehdessä taulukkoa (Ei dataa)</p>
TOP_TOWNS <> <p><b>Top 20 Kylää</b></p>
TOP_FACTIONS <> <p><b>Top 20 Kiltaa</b></p>
TOTAL_BALANCE <> <p>Palvelimen rahan kokonaismäärä: REPLACE0</p>
TOTAL_VOTES <> <p>Pelaajat ovat äänestäneet REPLACE0 kertaa.</p>
TOWN <> <p>Kylä: REPLACE0</p>
PLOT_OPTIONS <> <p>Plot asetukset: REPLACE0</p>
FRIENDS <> <p>Kaverit: REPLACE0</p>
FACTION <> <p>Kilta: REPLACE0</p>
BALANCE <> <p>Rahamäärä: REPLACE0</p>
VOTES <> <p>Pelaaja on äänestänyt REPLACE0 kertaa.</p>
BANNED <> | <span class="darkred">Banned</span>
OPERATOR <> , Operator (Op)
ONLINE <> | <span class="darkgreen">Online</span>
OFFLINE <> | <span class="darkred">Offline</span>
ACTIVE <> | Pelaaja on aktiivinen
INACTIVE <> | Pelaaja on inaktiivinen
ERROR_LIST <> Virhe luodessa listaa</p>

View File

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

View File

@ -1,3 +1,23 @@
/*
* Player Analytics Bukkit plugin for monitoring server activity.
* Copyright (C) 2016 Risto Lahtela / Rsl1122
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Plan License. (licence.yml)
* Modified software can only be redistributed if allowed in the licence.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the License
* along with this program.
* If not it should be visible on the distribution page.
* Or here
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/licence.yml
*/
package com.djrapitops.plan;
import com.djrapitops.plan.command.PlanCommand;
@ -23,6 +43,7 @@ import java.util.HashSet;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.listeners.PlanDeathEventListener;
import main.java.com.djrapitops.plan.ui.Html;
import org.bukkit.Bukkit;
import org.bukkit.command.ConsoleCommandSender;
@ -30,23 +51,22 @@ import org.bukkit.plugin.PluginManager;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
/* TODO 2.2.0
/* TODO 2.5.0
Placeholder API
Database cleaning
Play session lenght
- Existing data
- importing
Kills & Deaths 50%
- DB saving & Alter tables
Location Analysis to view meaningful locations on Dynmap (Investigate dynmap api)
Integrate PlanLite features to Plan and discontinue PlanLite
Seperate serverdata and userdata saving
Database Cleaning of useless data
Fix any bugs that come up
Localization
- Combine the two locale files
Security
- UUID to address
- Permission check to Datarequest handler
- Config settings to disable
- Combine the two locale files
Security
*/
/**
*
@ -198,6 +218,7 @@ public class Plan extends JavaPlugin {
pluginManager.registerEvents(new PlanPlayerListener(this), this);
pluginManager.registerEvents(new PlanGamemodeChangeListener(this), this);
pluginManager.registerEvents(new PlanCommandPreprocessListener(this), this);
pluginManager.registerEvents(new PlanDeathEventListener(this), this);
if (Settings.GATHERLOCATIONS.isTrue()) {
pluginManager.registerEvents(new PlanPlayerMoveListener(this), this);
}
@ -234,8 +255,6 @@ public class Plan extends JavaPlugin {
return false;
}
db.setVersion(0);
return true;
}
@ -324,19 +343,14 @@ public class Plan extends JavaPlugin {
private void initLocale() {
String locale = Settings.LOCALE.toString().toUpperCase();
File localeFile = new File(getDataFolder(), "locale.txt");
File htmlLocale = new File(getDataFolder(), "htmlLocale.txt");
boolean skipLoc = false;
boolean skipHtmlLoc = false;
String usingLocale = "";
if (localeFile.exists()) {
Phrase.loadLocale(localeFile);
Html.loadLocale(localeFile);
skipLoc = true;
usingLocale = "locale.txt";
}
if (htmlLocale.exists()) {
Html.loadLocale(htmlLocale);
skipHtmlLoc = true;
}
if (!locale.equals("DEFAULT")) {
try {
if (!skipLoc) {
@ -349,21 +363,10 @@ public class Plan extends JavaPlugin {
outputStream.write(bytes, 0, read);
}
Phrase.loadLocale(localeFile);
Html.loadLocale(localeFile);
usingLocale = locale;
localeFile.delete();
}
if (!skipHtmlLoc) {
URL localeURL = new URL("https://raw.githubusercontent.com/Rsl1122/Plan-PlayerAnalytics/master/Plan/localization/htmlLocale_" + locale + ".txt");
InputStream inputStream = localeURL.openStream();
OutputStream outputStream = new FileOutputStream(htmlLocale);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
Html.loadLocale(htmlLocale);
htmlLocale.delete();
}
} catch (FileNotFoundException ex) {
logError("Attempted using locale that doesn't exist.");
usingLocale = "Default: EN";

View File

@ -16,6 +16,7 @@ public enum Settings {
USE_ALTERNATIVE_UI("Settings.PlanLite.UseAsAlternativeUI"),
PLANLITE_ENABLED("Settings.PlanLite.Enabled"),
GATHERLOCATIONS("Settings.Data.GatherLocations"),
SECURITY_IP_UUID("Settings.WebServer.Security.DisplayIPsAndUUIDs"),
// Integer
ANALYSIS_MINUTES_FOR_ACTIVE("Settings.Analysis.MinutesPlayedUntilConsidiredActive"),
SAVE_CACHE_MIN("Settings.Cache.DataCache.SaveEveryXMinutes"),
@ -31,7 +32,8 @@ public enum Settings {
DEM_FEMALE("Customization.DemographicsTriggers.Female"),
DEM_MALE("Customization.DemographicsTriggers.Male"),
DEM_IGNORE("Customization.DemographicsTriggers.IgnoreWhen"),
LOCALE("Settings.Locale");
LOCALE("Settings.Locale"),
SECURITY_CODE("Settings.WebServer.Security.AddressSecurityCode");
private final String configPath;

View File

@ -7,6 +7,7 @@ import com.djrapitops.plan.command.SubCommand;
import com.djrapitops.plan.data.cache.AnalysisCacheHandler;
import java.util.Date;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandException;
@ -81,6 +82,7 @@ public class AnalyzeCommand extends SubCommand {
}
if (timesrun > 45) {
sender.sendMessage(Phrase.COMMAND_TIMEOUT.parse("Analysis"));
this.cancel();
}
}
}).runTaskTimer(plugin, 1 * 20, 5 * 20);
@ -93,14 +95,11 @@ public class AnalyzeCommand extends SubCommand {
* @throws CommandException
*/
public void sendAnalysisMessage(CommandSender sender) throws CommandException {
final boolean useAlternativeIP = Settings.SHOW_ALTERNATIVE_IP.isTrue();
final int port = Settings.WEBSERVER_PORT.getNumber();
final String alternativeIP = Settings.ALTERNATIVE_IP.toString().replaceAll("%port%", "" + port);
sender.sendMessage(Phrase.CMD_ANALYZE_HEADER+"");
// Link
String url = "http://" + (useAlternativeIP ? alternativeIP : plugin.getServer().getIp() + ":" + port)
+ "/server";
String url = HtmlUtils.getServerAnalysisUrl();
String message = Phrase.CMD_LINK+"";
boolean console = !(sender instanceof Player);
if (console) {

View File

@ -11,6 +11,7 @@ import com.djrapitops.plan.data.cache.InspectCacheHandler;
import com.djrapitops.plan.utilities.MiscUtils;
import java.util.UUID;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
@ -92,8 +93,6 @@ public class InspectCommand extends SubCommand {
}
sender.sendMessage(Phrase.GRABBING_DATA_MESSAGE + "");
inspectCache.cache(uuid);
final int port = Settings.WEBSERVER_PORT.getNumber();
final String alternativeIP = Settings.ALTERNATIVE_IP.toString().replaceAll("%port%", "" + port);
int configValue = Settings.CLEAR_INSPECT_CACHE.getNumber();
if (configValue <= 0) {
configValue = 4;
@ -108,8 +107,7 @@ public class InspectCommand extends SubCommand {
if (inspectCache.isCached(uuid)) {
sender.sendMessage(Phrase.CMD_INSPECT_HEADER + playerName);
// Link
String url = "http://" + (useAlternativeIP ? alternativeIP : plugin.getServer().getIp() + ":" + port)
+ "/player/" + playerName;
String url = HtmlUtils.getInspectUrl(playerName);
String message = Phrase.CMD_LINK+"";
boolean console = !(sender instanceof Player);
if (console) {
@ -129,6 +127,7 @@ public class InspectCommand extends SubCommand {
}
if (timesrun > 45) {
sender.sendMessage(Phrase.COMMAND_TIMEOUT.parse("Inspect"));
this.cancel();
}
}
}).runTaskTimer(plugin, 1 * 20, 5 * 20);

View File

@ -11,6 +11,7 @@ import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
@ -71,9 +72,6 @@ public class SearchCommand extends SubCommand {
}
}
final boolean useAlternativeIP = Settings.SHOW_ALTERNATIVE_IP.isTrue();
final int port = Settings.WEBSERVER_PORT.getNumber();
final String alternativeIP = Settings.ALTERNATIVE_IP.toString().replaceAll("%port%", "" + port);
int configValue = Settings.CLEAR_INSPECT_CACHE.getNumber();
if (configValue <= 0) {
configValue = 4;
@ -92,8 +90,7 @@ public class SearchCommand extends SubCommand {
String name = match.getName();
sender.sendMessage(Phrase.CMD_MATCH + name);
// Link
String url = "http://" + (useAlternativeIP ? alternativeIP : plugin.getServer().getIp() + ":" + port)
+ "/player/" + name;
String url = HtmlUtils.getInspectUrl(name);
String message = Phrase.CMD_LINK+"";
boolean console = !(sender instanceof Player);
if (console) {

View File

@ -40,6 +40,10 @@ public class AnalysisData {
private int totalPlayers;
private long totalLoginTimes;
private int ops;
private long totalkills;
private long totalmobkills;
private long totaldeaths;
private boolean planLiteEnabled;
private PlanLiteAnalyzedData planLiteData;
@ -443,4 +447,28 @@ public class AnalysisData {
public void setNewPlayersDay(int newPlayersDay) {
this.newPlayersDay = newPlayersDay;
}
public long getTotalkills() {
return totalkills;
}
public long getTotalmobkills() {
return totalmobkills;
}
public long getTotaldeaths() {
return totaldeaths;
}
public void setTotalkills(long totalkills) {
this.totalkills = totalkills;
}
public void setTotalmobkills(long totalmobkills) {
this.totalmobkills = totalmobkills;
}
public void setTotaldeaths(long totaldeaths) {
this.totaldeaths = totaldeaths;
}
}

View File

@ -36,6 +36,10 @@ public class UserData {
private boolean isOp;
private boolean isBanned;
private DemographicsData demData;
private int mobKills;
private int playerKills;
private int deaths;
private boolean planLiteFound;
private PlanLitePlayerData planLiteData;
@ -318,4 +322,27 @@ public class UserData {
return isOnline;
}
public int getMobKills() {
return mobKills;
}
public void setMobKills(int mobKills) {
this.mobKills = mobKills;
}
public int getPlayerKills() {
return playerKills;
}
public void setPlayerKills(int playerKills) {
this.playerKills = playerKills;
}
public int getDeaths() {
return deaths;
}
public void setDeaths(int deaths) {
this.deaths = deaths;
}
}

View File

@ -37,6 +37,7 @@ public class DataCacheHandler {
private final ServerData serverData;
private final ServerDataHandler serverDataHandler;
private final PlanLiteHandler planLiteHandler;
private final KillHandler killHandler;
private final Database db;
private final NewPlayerCreator newPlayerCreator;
@ -66,6 +67,7 @@ public class DataCacheHandler {
serverDataHandler = new ServerDataHandler(serverData);
planLiteHandler = new PlanLiteHandler(plugin);
newPlayerCreator = new NewPlayerCreator(plugin, this);
killHandler = new KillHandler(plugin);
timesSaved = 0;
maxPlayers = plugin.getServer().getMaxPlayers();
@ -380,6 +382,10 @@ public class DataCacheHandler {
return planLiteHandler;
}
public KillHandler getKillHandler() {
return killHandler;
}
/**
* Returns the same value as Plan#getDB().
*

View File

@ -0,0 +1,30 @@
package com.djrapitops.plan.data.handlers;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.data.UserData;
/**
*
* @author Rsl1122
*/
public class KillHandler {
private Plan plugin;
public KillHandler(Plan plugin) {
this.plugin = plugin;
}
public void handlePlayerKill(UserData data) {
data.setPlayerKills(data.getPlayerKills()+1);
}
public void handlePlayerDeath(UserData data) {
data.setDeaths(data.getDeaths()+1);
}
public void handleMobKill(UserData data) {
data.setMobKills(data.getMobKills()+1);
}
}

View File

@ -57,6 +57,9 @@ public class NewPlayerCreator {
data.setTimesKicked(0);
data.setLoginTimes(0);
data.setLastGmSwapTime(zero);
data.setDeaths(0);
data.setMobKills(0);
data.setPlayerKills(0);
db.saveUserData(player.getUniqueId(), data);
}

View File

@ -0,0 +1,55 @@
package main.java.com.djrapitops.plan.data.listeners;
import com.djrapitops.plan.Plan;
import com.djrapitops.plan.data.UserData;
import com.djrapitops.plan.data.cache.DataCacheHandler;
import com.djrapitops.plan.data.handlers.KillHandler;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
/**
*
* @author Rsl1122
*/
public class PlanDeathEventListener implements Listener {
private final Plan plugin;
private final DataCacheHandler handler;
private final KillHandler kH;
public PlanDeathEventListener(Plan plugin) {
this.plugin = plugin;
this.handler = plugin.getHandler();
this.kH = this.handler.getKillHandler();
}
/**
* Command use listener.
*
* @param event Fired event.
*/
@EventHandler(priority = EventPriority.MONITOR)
public void onDeath(EntityDeathEvent event) {
LivingEntity dead = event.getEntity();
Player killer = dead.getKiller();
boolean killerIsPlayer = killer != null;
UserData killersData = null;
if (killerIsPlayer) {
killersData = handler.getCurrentData(killer.getUniqueId());
}
if (dead instanceof Player) {
Player killed = (Player) dead;
UserData killedsData = handler.getCurrentData(killed.getUniqueId());
if (killerIsPlayer) {
kH.handlePlayerKill(killersData);
}
kH.handlePlayerDeath(killedsData);
} else if (killerIsPlayer) {
kH.handleMobKill(killersData);
}
}
}

View File

@ -53,6 +53,9 @@ public abstract class SQLDB extends Database {
private String userColumnLastGMSwapTime;
private String userColumnLoginTimes;
private String userColumnLastPlayed;
private String userColumnMobKills;
private String userColumnPlayerKills;
private String userColumnDeaths;
private final String locationColumnUserID;
private String locationColumnID;
private String locationColumnCoordinatesX;
@ -104,6 +107,9 @@ public abstract class SQLDB extends Database {
userColumnPlayTime = "play_time";
userColumnLoginTimes = "login_times";
userColumnLastPlayed = "last_played";
userColumnMobKills = "mob_kills";
userColumnPlayerKills = "player_kills";
userColumnDeaths = "deaths";
locationColumnCoordinatesX = "x";
locationColumnCoordinatesZ = "z";
@ -156,10 +162,14 @@ public abstract class SQLDB extends Database {
if (connection == null || connection.isClosed()) {
return false;
}
boolean usingMySQL = getConfigName().toLowerCase().equals("mysql");
// ResultSet set = connection.prepareStatement(supportsModification ? ("SHOW TABLES LIKE '" + userName + "'") : "SELECT name FROM sqlite_master WHERE type='table' AND name='" + userName + "'").executeQuery();
// boolean newDatabase = set.next();
// set.close();
boolean usingMySQL = supportsModification;
ResultSet set = connection.prepareStatement(supportsModification ? ("SHOW TABLES LIKE '" + userName + "'") : "SELECT name FROM sqlite_master WHERE type='table' AND name='" + userName + "'").executeQuery();
boolean newDatabase = set.next();
set.close();
if (newDatabase) {
setVersion(1);
}
query("CREATE TABLE IF NOT EXISTS " + userName + " ("
+ userColumnID + " integer " + ((usingMySQL) ? "NOT NULL AUTO_INCREMENT" : "PRIMARY KEY") + ", "
+ userColumnUUID + " varchar(36) NOT NULL, "
@ -170,7 +180,10 @@ public abstract class SQLDB extends Database {
+ userColumnLastGMSwapTime + " bigint NOT NULL, "
+ userColumnPlayTime + " bigint NOT NULL, "
+ userColumnLoginTimes + " integer NOT NULL, "
+ userColumnLastPlayed + " bigint NOT NULL"
+ userColumnLastPlayed + " bigint NOT NULL, "
+ userColumnDeaths + " int NOT NULL, "
+ userColumnMobKills + " int NOT NULL, "
+ userColumnPlayerKills + " int NOT NULL"
+ (usingMySQL ? ", PRIMARY KEY (" + userColumnID + ")" : "")
+ ")"
);
@ -227,7 +240,17 @@ public abstract class SQLDB extends Database {
+ "version integer NOT NULL"
+ ")"
);
int version = getVersion();
version = 0;
if (version < 1) {
try {
query("ALTER TABLE " + userName + " ADD " + userColumnDeaths + " integer NOT NULL DEFAULT 0");
query("ALTER TABLE " + userName + " ADD " + userColumnMobKills + " integer NOT NULL DEFAULT 0");
query("ALTER TABLE " + userName + " ADD " + userColumnPlayerKills + " integer NOT NULL DEFAULT 0");
} catch (Exception e) {
}
}
setVersion(1);
}
} catch (SQLException e) {
e.printStackTrace();
@ -544,6 +567,9 @@ public abstract class SQLDB extends Database {
data.setPlayTime(set.getLong(userColumnPlayTime));
data.setLoginTimes(set.getInt(userColumnLoginTimes));
data.setLastPlayed(set.getLong(userColumnLastPlayed));
data.setDeaths(set.getInt(userColumnDeaths));
data.setMobKills(set.getInt(userColumnMobKills));
data.setPlayerKills(set.getInt(userColumnPlayerKills));
}
set.close();
statement.close();
@ -631,7 +657,10 @@ public abstract class SQLDB extends Database {
+ userColumnLastGMSwapTime + "=?, "
+ userColumnPlayTime + "=?, "
+ userColumnLoginTimes + "=?, "
+ userColumnLastPlayed + "=? "
+ userColumnLastPlayed + "=?, "
+ userColumnDeaths + "=?, "
+ userColumnMobKills + "=?, "
+ userColumnPlayerKills + "=? "
+ "WHERE UPPER(" + userColumnUUID + ") LIKE UPPER(?)";
try {
connection.setAutoCommit(false);
@ -658,6 +687,9 @@ public abstract class SQLDB extends Database {
uStatement.setInt(7, uData.getLoginTimes());
uStatement.setLong(8, uData.getLastPlayed());
uStatement.setString(9, uData.getUuid().toString());
uStatement.setInt(10, uData.getDeaths());
uStatement.setInt(11, uData.getMobKills());
uStatement.setInt(12, uData.getPlayerKills());
uStatement.addBatch();
commitRequired = true;
}
@ -700,7 +732,10 @@ public abstract class SQLDB extends Database {
+ userColumnLastGMSwapTime + "=?, "
+ userColumnPlayTime + "=?, "
+ userColumnLoginTimes + "=?, "
+ userColumnLastPlayed + "=? "
+ userColumnLastPlayed + "=?, "
+ userColumnDeaths + "=?, "
+ userColumnMobKills + "=?, "
+ userColumnPlayerKills + "=? "
+ "WHERE UPPER(" + userColumnUUID + ") LIKE UPPER(?)";
PreparedStatement statement = connection.prepareStatement(sql);
@ -718,6 +753,9 @@ public abstract class SQLDB extends Database {
statement.setInt(7, data.getLoginTimes());
statement.setLong(8, data.getLastPlayed());
statement.setString(9, uuid.toString());
statement.setInt(10, data.getDeaths());
statement.setInt(11, data.getMobKills());
statement.setInt(12, data.getPlayerKills());
update = statement.executeUpdate();
}
if (update == 0) {
@ -730,8 +768,11 @@ public abstract class SQLDB extends Database {
+ userColumnLastGMSwapTime + ", "
+ userColumnPlayTime + ", "
+ userColumnLoginTimes + ", "
+ userColumnLastPlayed
+ ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
+ userColumnLastPlayed + ", "
+ userColumnDeaths + ", "
+ userColumnMobKills + ", "
+ userColumnPlayerKills
+ ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
statement.setString(1, uuid.toString());
statement.setInt(2, data.getDemData().getAge());
@ -747,6 +788,9 @@ public abstract class SQLDB extends Database {
statement.setLong(7, data.getPlayTime());
statement.setInt(8, data.getLoginTimes());
statement.setLong(9, data.getLastPlayed());
statement.setInt(10, data.getDeaths());
statement.setInt(11, data.getMobKills());
statement.setInt(12, data.getPlayerKills());
statement.execute();
statement.close();

View File

@ -14,9 +14,9 @@ import main.java.com.djrapitops.plan.utilities.HtmlUtils;
*/
public class DataRequestHandler {
private Plan plugin;
private InspectCacheHandler inspectCache;
private AnalysisCacheHandler analysisCache;
private final Plan plugin;
private final InspectCacheHandler inspectCache;
private final AnalysisCacheHandler analysisCache;
/**
* Class Constructor.

View File

@ -58,7 +58,8 @@ public enum Html {
OFFLINE("| " + SPAN.parse(COLOR_4.parse() + "Offline")),
ACTIVE("| Player is Active"),
INACTIVE("| Player is inactive"),
ERROR_LIST("Error Creating List</p>"),;
ERROR_LIST("Error Creating List</p>"),
HIDDEN("Hidden (config)");
private String html;
@ -86,8 +87,17 @@ public enum Html {
try {
Scanner localeScanner = new Scanner(localeFile, "UTF-8");
List<String> localeRows = new ArrayList<>();
boolean html = false;
while (localeScanner.hasNextLine()) {
localeRows.add(localeScanner.nextLine());
String line = localeScanner.nextLine();
if (line.equals("<<<<<<HTML>>>>>>")) {
html = true;
continue;
}
if (!html) {
continue;
}
localeRows.add(line);
}
for (String localeRow : localeRows) {
try {

View File

@ -5,6 +5,7 @@ import com.djrapitops.plan.utilities.UUIDFetcher;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;
import main.java.com.djrapitops.plan.Settings;
/**
*
@ -15,7 +16,7 @@ public class Response {
private OutputStream output;
private Request request;
private DataRequestHandler requestHandler;
private final DataRequestHandler requestHandler;
/**
* Class Constructor.
@ -42,22 +43,33 @@ public class Response {
return;
}
String[] requestArgs = request.getUri().split("/");
boolean forbidden = false;
String securityCode = "";
if (requestArgs.length < 1) {
forbidden = true;
} else {
securityCode = requestArgs[1];
}
if (!securityCode.equals(Settings.SECURITY_CODE+"")) {
forbidden = true;
}
if (forbidden) {
String errorMessage = "HTTP/1.1 403 Forbidden\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 45\r\n"
+ "Content-Length: 38\r\n"
+ "\r\n"
+ "<h1>403 Forbidden - Direct access not allowed</h1>";
+ "<h1>403 Forbidden - Access Denied</h1>";
output.write(errorMessage.getBytes());
return;
}
String command = requestArgs[1].toLowerCase();
String command = requestArgs[2].toLowerCase();
if (command.equals("player")) {
if (requestArgs.length >= 3) {
UUID uuid = UUIDFetcher.getUUIDOf(requestArgs[2].trim());
String playerName = requestArgs[3].trim();
UUID uuid = UUIDFetcher.getUUIDOf(playerName);
if (uuid == null) {
String errorMessage = "HTTP/1.1 404 UUID not Found\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Type: text/html;\r\n"
+ "Content-Length: 30\r\n"
+ "\r\n"
+ "<h1>404 - Player doesn't exist</h1>";
@ -67,7 +79,7 @@ public class Response {
if (requestHandler.checkIfCached(uuid)) {
String dataHtml = requestHandler.getDataHtml(uuid);
String htmlDef = "HTTP/1.1 OK\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Type: text/html; charset=utf-8\r\n"
+ "Content-Length: " + dataHtml.length() + "\r\n"
+ "\r\n";
output.write((htmlDef + dataHtml).getBytes());
@ -78,7 +90,7 @@ public class Response {
if (requestHandler.checkIfAnalysisIsCached()) {
String analysisHtml = requestHandler.getAnalysisHtml();
String htmlDef = "HTTP/1.1 OK\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Type: text/html; charset=utf-8\r\n"
+ "Content-Length: " + analysisHtml.length() + "\r\n"
+ "\r\n";
output.write((htmlDef + analysisHtml).getBytes());

View File

@ -19,6 +19,7 @@ import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.PlanLiteAnalyzedData;
import main.java.com.djrapitops.plan.data.PlanLitePlayerData;
import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
import org.bukkit.GameMode;
import org.bukkit.OfflinePlayer;
import org.bukkit.scheduler.BukkitRunnable;
@ -29,8 +30,8 @@ import org.bukkit.scheduler.BukkitRunnable;
*/
public class Analysis {
private Plan plugin;
private InspectCacheHandler inspectCache;
private final Plan plugin;
private final InspectCacheHandler inspectCache;
private final List<UserData> rawData;
private HashMap<Long, ServerData> rawServerData;
private final List<UUID> added;
@ -73,10 +74,6 @@ public class Analysis {
plugin.log(Phrase.ANALYSIS_FAIL_NO_DATA + "");
return;
}
// Settings for urls
final boolean useAlternativeIP = Settings.SHOW_ALTERNATIVE_IP.isTrue();
final int port = Settings.WEBSERVER_PORT.getNumber();
final String alternativeIP = Settings.ALTERNATIVE_IP.toString().replaceAll("%port%", "" + port);
// Async task for Analysis
(new BukkitRunnable() {
@Override
@ -116,6 +113,10 @@ public class Analysis {
int joinleaver = 0;
int inactive = 0;
long totalKills = 0;
long totalMobKills = 0;
long totalDeaths = 0;
int ops = 0;
List<Integer> ages = new ArrayList<>();
@ -159,8 +160,7 @@ public class Analysis {
long playTime = uData.getPlayTime();
totalPlaytime += playTime;
String playerName = uData.getName();
String url = "http://" + (useAlternativeIP ? alternativeIP : plugin.getServer().getIp() + ":" + port)
+ "/player/" + playerName;
String url = HtmlUtils.getInspectUrl(playerName);
String html = Html.BUTTON.parse(url, playerName);
latestLogins.put(html, uData.getLastPlayed());
@ -182,6 +182,9 @@ public class Analysis {
} else {
inactive++;
}
totalKills += uData.getPlayerKills();
totalMobKills += uData.getMobKills();
totalDeaths += uData.getDeaths();
}
// Save Dataset to AnalysisData
@ -201,6 +204,10 @@ public class Analysis {
analyzeAverageAge(ages, data);
createGamemodeUsageVisualization(gmZero, gmOne, gmTwo, gmThree, data);
createCommandUseTable(data);
data.setTotaldeaths(totalDeaths);
data.setTotalkills(totalKills);
data.setTotalmobkills(totalMobKills);
data.setRefreshDate(new Date().getTime());
analysisCache.cache(data);

View File

@ -1,9 +1,14 @@
package main.java.com.djrapitops.plan.utilities;
import com.djrapitops.plan.Plan;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import main.java.com.djrapitops.plan.Settings;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
/**
@ -11,10 +16,18 @@ import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
* @author Rsl1122
*/
public class HtmlUtils {
public static String getHtmlStringFromResource(String fileName) {
Plan plugin = getPlugin(Plan.class);
File localFile = new File(plugin.getDataFolder(), fileName);
Scanner scanner = new Scanner(plugin.getResource(fileName));
if (localFile.exists()) {
try {
scanner = new Scanner(localFile, "UTF-8");
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
}
String html = "";
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
@ -22,11 +35,35 @@ public class HtmlUtils {
}
return html;
}
public static String replacePlaceholders(String html, HashMap<String, String> replaceMap) {
for (String key : replaceMap.keySet()) {
html = html.replaceAll(key, replaceMap.get(key));
}
return html;
}
public static String getServerAnalysisUrl() {
int port = Settings.WEBSERVER_PORT.getNumber();
String ip = getPlugin(Plan.class).getServer().getIp() + ":" + port;
String securityCode = Settings.SECURITY_CODE.toString();
boolean useAlternativeIP = Settings.SHOW_ALTERNATIVE_IP.isTrue();
if (useAlternativeIP) {
ip = Settings.ALTERNATIVE_IP.toString().replaceAll("%port%", "" + port);
}
String url = "http://" + ip + "/" + securityCode + "/server";
return url;
}
public static String getInspectUrl(String playerName) {
int port = Settings.WEBSERVER_PORT.getNumber();
String ip = getPlugin(Plan.class).getServer().getIp() + ":" + port;
String securityCode = Settings.SECURITY_CODE.toString();
boolean useAlternativeIP = Settings.SHOW_ALTERNATIVE_IP.isTrue();
if (useAlternativeIP) {
ip = Settings.ALTERNATIVE_IP.toString().replaceAll("%port%", "" + port);
}
String url = "http://" + ip + "/" + securityCode + "/player/" + playerName;
return url;
}
}

View File

@ -1,4 +1,3 @@
package com.djrapitops.plan.utilities;
import com.djrapitops.plan.Phrase;
@ -8,6 +7,7 @@ import com.djrapitops.plan.data.AnalysisData;
import com.djrapitops.plan.data.UserData;
import java.util.Date;
import java.util.HashMap;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.PlanLiteAnalyzedData;
import main.java.com.djrapitops.plan.data.PlanLitePlayerData;
import main.java.com.djrapitops.plan.ui.Html;
@ -55,6 +55,9 @@ public class PlaceholderUtils {
replaceMap.put("%totallogins%", "" + data.getTotalLoginTimes());
replaceMap.put("%top20mostactive%", data.getTop20ActivePlayers());
replaceMap.put("%recentlogins%", data.getRecentPlayers());
replaceMap.put("%deaths%", data.getTotaldeaths()+"");
replaceMap.put("%playerkills%", data.getTotalkills()+"");
replaceMap.put("%mobkills%", data.getTotalmobkills()+"");
Plan plugin = getPlugin(Plan.class);
PlanLiteHook hook = plugin.getPlanLiteHook();
replaceMap.put("%version%", plugin.getDescription().getVersion());
@ -87,7 +90,8 @@ public class PlaceholderUtils {
*/
public static HashMap<String, String> getInspectReplaceRules(UserData data) {
HashMap<String, String> replaceMap = new HashMap<>();
replaceMap.put("%uuid%", "" + data.getUuid());
boolean showIPandUUID = Settings.SECURITY_IP_UUID.isTrue();
replaceMap.put("%uuid%", (showIPandUUID ? "" + data.getUuid() : Html.HIDDEN.parse()));
replaceMap.put("%lastseen%", FormatUtils.formatTimeStamp("" + data.getLastPlayed()));
replaceMap.put("%logintimes%", "" + data.getLoginTimes());
replaceMap.put("%bed%", FormatUtils.formatLocation(data.getBedLocation()));
@ -118,7 +122,7 @@ public class PlaceholderUtils {
replaceMap.put("%gm2%", FormatUtils.formatTimeAmount("" + gmTwo));
replaceMap.put("%gm3%", FormatUtils.formatTimeAmount("" + gmThree));
replaceMap.put("%gmtotal%", FormatUtils.formatTimeAmount("" + total));
replaceMap.put("%ips%", data.getIps().toString());
replaceMap.put("%ips%", (showIPandUUID ? data.getIps().toString() : Html.HIDDEN.parse()));
replaceMap.put("%nicknames%", FormatUtils.swapColorsToSpan(data.getNicknames().toString()));
replaceMap.put("%name%", data.getName());
replaceMap.put("%registered%", FormatUtils.formatTimeStamp("" + data.getRegistered()));
@ -127,6 +131,10 @@ public class PlaceholderUtils {
replaceMap.put("%banned%", data.isBanned() ? Html.BANNED.parse() : "");
replaceMap.put("%op%", data.isOp() ? Html.OPERATOR.parse() : "");
replaceMap.put("%isonline%", (data.isOnline()) ? Html.ONLINE.parse() : Html.OFFLINE.parse());
int deaths = data.getDeaths();
replaceMap.put("%deaths%", deaths+"");
replaceMap.put("%playerkills%", data.getPlayerKills()+"");
replaceMap.put("%mobkills%", data.getMobKills()+"");
Plan plugin = getPlugin(Plan.class);
replaceMap.put("%version%", plugin.getDescription().getVersion());
PlanLiteHook hook = plugin.getPlanLiteHook();
@ -153,14 +161,14 @@ public class PlaceholderUtils {
private static String getPlanLitePlayerHtml(PlanLitePlayerData planLiteData) {
return HtmlUtils.replacePlaceholders(
HtmlUtils.getHtmlStringFromResource("planliteplayer.html"),
HtmlUtils.getHtmlStringFromResource("planliteplayer.html"),
PlaceholderUtils.getPlanLitePlayerReplaceRules(planLiteData)
);
}
private static String getPlanLiteAnalysisHtml(PlanLiteAnalyzedData planLiteData) {
return HtmlUtils.replacePlaceholders(
HtmlUtils.getHtmlStringFromResource("planlite.html"),
HtmlUtils.getHtmlStringFromResource("planlite.html"),
PlaceholderUtils.getPlanLiteAnalysisReplaceRules(planLiteData)
);
}

View File

@ -115,6 +115,8 @@
<p>%activitytotal% players have played on this server.<br/>
A Total of %totalplaytime% has been played with the average of %avgplaytime%<br/>
Players have joined %totallogins% times.<br/>
Players have died %deaths% times, of which %playerkills% were caused by another Player.<br/>
A Total of %mobkills% mobs have been slain.<br/>
The average of known player ages is %avgage%.</p>
<h4>Playerbase composition</h4>
%activitypiechart%

View File

@ -20,6 +20,9 @@ Settings:
Port: 8804
ShowAlternativeServerIP: false
AlternativeIP: your.ip.here:%port%
Security:
DisplayIPsAndUUIDs: true
AddressSecurityCode: bAkEd
PlanLite:
Enabled: true
UseAsAlternativeUI: false

View File

@ -114,6 +114,7 @@
Playtime: %playtime%<br/>
Has logged in %logintimes% times. | Has been kicked %timeskicked% times.<br/>
Age: %age% | Gender: %gender%<br/>
Player kills: %playerkills% | Mob kills: %mobkills% | Deaths: %deaths%<br/>
UUID: %uuid%</p>
%planlite%
</div>

View File

@ -1,7 +1,7 @@
name: Plan
author: Rsl1122
main: com.djrapitops.plan.Plan
version: 2.4.1
version: 2.5.0
commands:
plan: