From 8b3bc50f6e65dc0a96256c9e23f7e1a7dc9a6c89 Mon Sep 17 00:00:00 2001 From: boy0001 Date: Sun, 28 Jun 2015 10:54:57 +1000 Subject: [PATCH] analysis, rating priority, popularity formula Plot analysis (more progress) - Relevant debug command: /plot debugexec analyze - I've been working on some more interesting plot analysis which will in future give a better indication of quality content rather than blocks changed - The main problem with blocks changes is that if a plot is entirely set to a blob of stone it will pass that requirement, despite the fact that it's a blob of stone - With the plot analysis it will calculate the complexity of the build based on 13 different metrics Rating priority: - Relevant command to teleport to the next plot: /plot rate next - PlotSquared will try to prioritize higher quality plots to receive more ratings - Low quality plots will still be rated, just not as much as higher quality builds Plot popularity: - Relevent command to list popular plots: /plot list top - Will sort the plots based on average rating and number of ratings --- .../plot/PlotSquared.java | 2 + .../plot/commands/DebugExec.java | 22 ++- .../plot/commands/DebugFill.java | 36 +++- .../plot/commands/Info.java | 2 +- .../plot/commands/Rate.java | 61 ++++++- .../plot/commands/Set.java | 16 +- .../plot/commands/list.java | 81 ++++++--- .../intellectualcrafters/plot/config/C.java | 1 + .../plot/config/Settings.java | 1 + .../plot/database/AbstractDB.java | 9 +- .../plot/database/DBFunc.java | 6 +- .../plot/database/SQLManager.java | 58 ++++--- .../plot/generator/BukkitHybridUtils.java | 163 ++++++++++++++---- .../plot/listeners/PlayerEvents.java | 7 +- .../plot/object/PlotAnalysis.java | 27 ++- .../plot/object/PlotSettings.java | 7 + .../plot/util/MainUtil.java | 20 +++ .../plot/util/Permissions.java | 4 +- 18 files changed, 398 insertions(+), 125 deletions(-) diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotSquared.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotSquared.java index 34c8d842d..fa04ac76d 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotSquared.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotSquared.java @@ -839,6 +839,7 @@ public class PlotSquared { // Caching options.put("cache.permissions", Settings.PERMISSION_CACHING); + options.put("cache.ratings", Settings.CACHE_RATINGS); // Titles options.put("titles", Settings.TITLES); @@ -922,6 +923,7 @@ public class PlotSquared { // Caching Settings.PERMISSION_CACHING = config.getBoolean("cache.permissions"); + Settings.CACHE_RATINGS = config.getBoolean("cache.ratings"); // Titles Settings.TITLES = config.getBoolean("titles"); diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugExec.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugExec.java index 1db4579f7..340bdef4d 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugExec.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugExec.java @@ -41,7 +41,9 @@ import com.intellectualcrafters.plot.generator.HybridUtils; import com.intellectualcrafters.plot.object.ChunkLoc; import com.intellectualcrafters.plot.object.OfflinePlotPlayer; import com.intellectualcrafters.plot.object.Plot; +import com.intellectualcrafters.plot.object.PlotAnalysis; import com.intellectualcrafters.plot.object.PlotPlayer; +import com.intellectualcrafters.plot.object.RunnableVal; import com.intellectualcrafters.plot.util.BlockManager; import com.intellectualcrafters.plot.util.ChunkManager; import com.intellectualcrafters.plot.util.ExpireManager; @@ -61,7 +63,24 @@ public class DebugExec extends SubCommand { switch (arg) { case "analyze": { Plot plot = MainUtil.getPlot(player.getLocation()); - HybridUtils.manager.analyzePlot(plot, null); + HybridUtils.manager.analyzePlot(plot, new RunnableVal() { + @Override + public void run() { + System.out.print("changes_sd: " + this.value.changes_sd); + System.out.print("changes_total: " + this.value.changes_total); + System.out.print("data_sd: " + this.value.data_sd); + System.out.print("data_total: " + this.value.data_total); + System.out.print("height_sd: " + this.value.height_sd); + System.out.print("height_total: " + this.value.height_total); + System.out.print("rotations_sd: " + this.value.rotations_sd); + System.out.print("rotations_total: " + this.value.rotations_total); + System.out.print("uniformity_sd: " + this.value.uniformity_sd); + System.out.print("variety_sd: " + this.value.variety_sd); + System.out.print("variety_total: " + this.value.variety_total); + System.out.print("verticies_sd: " + this.value.verticies_sd); + System.out.print("verticies_total: " + this.value.verticies_total); + } + }); return true; } case "stop-expire": { @@ -108,6 +127,7 @@ public class DebugExec extends SubCommand { PlotSquared.log("&cTASK NOT RUNNING!"); return false; } + ((BukkitHybridUtils)(HybridUtils.manager)).task = 0; Bukkit.getScheduler().cancelTask(((BukkitHybridUtils)(HybridUtils.manager)).task); PlotSquared.log("&cCancelling task..."); while (BukkitHybridUtils.chunks.size() > 0) { diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugFill.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugFill.java index f3b38ce1c..3684f29e5 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugFill.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugFill.java @@ -54,9 +54,14 @@ public class DebugFill extends SubCommand { MainUtil.sendMessage(player, C.NO_PLOT_PERMS); return true; } + if (MainUtil.runners.containsKey(plot)) { + MainUtil.sendMessage(player, C.WAIT_FOR_TIMER); + return false; + } final Location bottom = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); final Location top = MainUtil.getPlotTopLoc(plot.world, plot.id); MainUtil.sendMessage(player, "&cPreparing task"); + MainUtil.runners.put(plot, 1); SetBlockQueue.addNotify(new Runnable() { @Override public void run() { @@ -65,16 +70,40 @@ public class DebugFill extends SubCommand { public void run() { MainUtil.sendMessage(player, "&7 - Starting"); if (args[0].equalsIgnoreCase("all")) { - for (int x = bottom.getX(); x <= top.getX(); x++) { - for (int y = 0; y <= 255; y++) { + int height = 255; + PlotBlock block = new PlotBlock((short) 7, (byte) 0); + PlotBlock air = new PlotBlock((short) 0, (byte) 0); + if (args.length > 2) { + try { + block = new PlotBlock(Short.parseShort(args[1]), (byte) 0); + if (args.length == 3) { + height = Integer.parseInt(args[2]); + } + } + catch (Exception e) { + MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot fill all "); + MainUtil.runners.remove(plot); + return; + } + } + for (int y = 0; y <= height; y++) { + for (int x = bottom.getX(); x <= top.getX(); x++) { for (int z = bottom.getZ(); z <= top.getZ(); z++) { - SetBlockQueue.setBlock(plot.world, x, y, z, 7); + SetBlockQueue.setBlock(plot.world, x, y, z, block); + } + } + } + for (int y = height + 1; y <= 255; y++) { + for (int x = bottom.getX(); x <= top.getX(); x++) { + for (int z = bottom.getZ(); z <= top.getZ(); z++) { + SetBlockQueue.setBlock(plot.world, x, y, z, air); } } } SetBlockQueue.addNotify(new Runnable() { @Override public void run() { + MainUtil.runners.remove(plot); MainUtil.sendMessage(player, "&aFill task complete!"); } }); @@ -116,6 +145,7 @@ public class DebugFill extends SubCommand { SetBlockQueue.addNotify(new Runnable() { @Override public void run() { + MainUtil.runners.remove(plot); MainUtil.sendMessage(player, "&aFill task complete!"); SetBlockQueue.setSlow(false); } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Info.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Info.java index 10bf25783..4cd2bb4d0 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Info.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Info.java @@ -191,7 +191,7 @@ public class Info extends SubCommand { TaskManager.runTaskAsync(new Runnable() { @Override public void run() { - String info = newInfo.replaceAll("%rating%", String.format("%.1f", DBFunc.getRatings(plot))); + String info = newInfo.replaceAll("%rating%", String.format("%.1f", MainUtil.getAverageRating(plot))); MainUtil.sendMessage(player, C.PLOT_INFO_HEADER); MainUtil.sendMessage(player, info, false); } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Rate.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Rate.java index d46d18212..192eaf4c5 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Rate.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Rate.java @@ -20,10 +20,17 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// package com.intellectualcrafters.plot.commands; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map.Entry; +import java.util.Set; import java.util.UUID; import org.apache.commons.lang.StringUtils; +import com.intellectualcrafters.plot.PlotSquared; import com.intellectualcrafters.plot.config.C; import com.intellectualcrafters.plot.database.DBFunc; import com.intellectualcrafters.plot.object.Location; @@ -38,7 +45,7 @@ public class Rate extends SubCommand { * alias, CommandCategory category */ public Rate() { - super("rate", "plots.rate", "Rate the plot", "rate {0-10}", "rt", CommandCategory.ACTIONS, true); + super("rate", "plots.rate", "Rate the plot", "rate [#|next]", "rt", CommandCategory.ACTIONS, true); } @Override @@ -61,6 +68,39 @@ public class Rate extends SubCommand { return true; } final String arg = args[0]; + + if (arg.equalsIgnoreCase("next")) { + ArrayList plots = new ArrayList<>(PlotSquared.getPlots()); + Collections.sort(plots, new Comparator() { + @Override + public int compare(Plot p1, Plot p2) { + int v1 = 0; + int v2 = 0; + if (p1.settings.ratings != null) { + for (Entry entry : p1.settings.ratings.entrySet()) { + v1 -= 11 - entry.getValue(); + } + } + if (p2.settings.ratings != null) { + for (Entry entry : p2.settings.ratings.entrySet()) { + v2 -= 11 - entry.getValue(); + } + } + return v2 - v1; + } + }); + UUID uuid = plr.getUUID(); + for (Plot p : plots) { + if (plot.settings.ratings == null || !plot.settings.ratings.containsKey(uuid)) { + MainUtil.teleportPlayer(plr, plr.getLocation(), p); + MainUtil.sendMessage(plr, C.RATE_THIS); + return true; + } + } + MainUtil.sendMessage(plr, C.FOUND_NO_PLOTS); + return false; + } + final int rating; if (StringUtils.isNumeric(arg) && arg.length() < 3 && arg.length() > 0) { rating = Integer.parseInt(arg); @@ -74,18 +114,29 @@ public class Rate extends SubCommand { return false; } final UUID uuid = plr.getUUID(); - // TODO implement check for already rated - TaskManager.runTaskAsync(new Runnable() { + final Runnable run = new Runnable() { @Override public void run() { - if (DBFunc.hasRated(plot.world, plot.id, uuid)) { + if (plot.settings.ratings.containsKey(uuid)) { sendMessage(plr, C.RATING_ALREADY_EXISTS, plot.getId().toString()); return; } + plot.settings.ratings.put(uuid, rating); DBFunc.setRating(plot, uuid, rating); sendMessage(plr, C.RATING_APPLIED, plot.getId().toString()); } - }); + }; + if (plot.settings.ratings == null) { + TaskManager.runTaskAsync(new Runnable() { + @Override + public void run() { + plot.settings.ratings = DBFunc.getRatings(plot); + run.run(); + } + }); + return true; + } + run.run(); return true; } } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Set.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Set.java index 1fa044b8b..168f73572 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Set.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/Set.java @@ -90,10 +90,6 @@ public class Set extends SubCommand { break; } } - if (!Permissions.hasPermission(plr, "plots.set." + args[0].toLowerCase())) { - MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.set." + args[0].toLowerCase()); - return false; - } if (args[0].equalsIgnoreCase("flag")) { if (args.length < 2) { final String message = StringUtils.join(FlagManager.getFlags(plr), "&c, &6"); @@ -150,6 +146,10 @@ public class Set extends SubCommand { } } if (args[0].equalsIgnoreCase("home")) { + if (!Permissions.hasPermission(plr, "plots.set.home")) { + MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.set.home"); + return false; + } if (args.length > 1) { if (args[1].equalsIgnoreCase("none")) { plot.settings.setPosition(null); @@ -169,6 +169,10 @@ public class Set extends SubCommand { return MainUtil.sendMessage(plr, C.POSITION_SET); } if (args[0].equalsIgnoreCase("alias")) { + if (!Permissions.hasPermission(plr, "plots.set.alias")) { + MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.set.alias"); + return false; + } if (args.length < 2) { MainUtil.sendMessage(plr, C.MISSING_ALIAS); return false; @@ -193,6 +197,10 @@ public class Set extends SubCommand { return true; } if (args[0].equalsIgnoreCase("biome")) { + if (!Permissions.hasPermission(plr, "plots.set.biome")) { + MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.set.biome"); + return false; + } if (args.length < 2) { MainUtil.sendMessage(plr, C.NEED_BIOME); return true; diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/list.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/list.java index 83417de9f..ef5bf95d2 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/list.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/list.java @@ -22,10 +22,13 @@ package com.intellectualcrafters.plot.commands; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.UUID; +import java.util.Map.Entry; import org.apache.commons.lang.StringUtils; import org.bukkit.ChatColor; @@ -69,13 +72,13 @@ public class list extends SubCommand { builder.append(C.SUBCOMMAND_SET_OPTIONS_HEADER.s()); if (plr != null) { if (EconHandler.manager != null) { - builder.append(getArgumentList(new String[] { "mine", "shared", "world", "all", "unowned", "unknown", "forsale", "", ""})); + builder.append(getArgumentList(new String[] { "mine", "shared", "world", "all", "unowned", "unknown", "top", "", "", "forsale",})); } else { - builder.append(getArgumentList(new String[] { "mine", "shared", "world", "all", "unowned", "unknown", "", ""})); + builder.append(getArgumentList(new String[] { "mine", "shared", "world", "all", "unowned", "unknown", "top", "", ""})); } } else { - builder.append(getArgumentList(new String[] { "world", "all", "unowned", "unknown", "", ""})); + builder.append(getArgumentList(new String[] { "world", "all", "unowned", "unknown", "top", "", ""})); } MainUtil.sendMessage(plr, builder.toString()); } @@ -99,7 +102,7 @@ public class list extends SubCommand { } } - Collection plots = null; + List plots = null; String world; if (plr != null) { @@ -114,8 +117,8 @@ public class list extends SubCommand { world = worlds.iterator().next(); } } - String arg = args[0].toLowerCase(); + boolean sort = true; switch (arg) { case "mine": { if (plr == null) { @@ -125,7 +128,7 @@ public class list extends SubCommand { MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.list.mine"); return false; } - plots = PlotSquared.getPlots(plr); + plots = new ArrayList<>(PlotSquared.getPlots(plr)); break; } case "shared": { @@ -153,7 +156,7 @@ public class list extends SubCommand { MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.list.world." + world); return false; } - plots = PlotSquared.getPlots(world).values(); + plots = new ArrayList<>(PlotSquared.getPlots(world).values()); break; } case "all": { @@ -161,7 +164,41 @@ public class list extends SubCommand { MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.list.all"); return false; } - plots = PlotSquared.getPlots(); + plots = new ArrayList<>(PlotSquared.getPlots()); + break; + } + case "top": { + if (!Permissions.hasPermission(plr, "plots.list.top")) { + MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.list.top"); + return false; + } + plots = new ArrayList<>(PlotSquared.getPlots()); + Collections.sort(plots, new Comparator() { + @Override + public int compare(Plot p1, Plot p2) { + double v1 = 0; + double v2 = 0; + if (p1.settings.ratings != null && p1.settings.ratings.size() > 0) { + for (Entry entry : p1.settings.ratings.entrySet()) { + v1 += entry.getValue() * entry.getValue(); + } + v1 /= p1.settings.ratings.size(); + v2 += p2.settings.ratings.size(); + } + if (p2.settings.ratings != null && p2.settings.ratings.size() > 0) { + for (Entry entry : p2.settings.ratings.entrySet()) { + v2 += entry.getValue() * entry.getValue(); + } + v2 /= p2.settings.ratings.size(); + v2 += p2.settings.ratings.size(); + } + if (v2 == v1 && v2 != 0) { + return p2.settings.ratings.size() - p1.settings.ratings.size(); + } + return (int) Math.signum(v2 - v1); + } + }); + sort = false; break; } case "forsale": { @@ -172,7 +209,7 @@ public class list extends SubCommand { if (EconHandler.manager == null) { break; } - plots = new HashSet<>(); + plots = new ArrayList<>(); for (Plot plot : PlotSquared.getPlots()) { final Flag price = FlagManager.getPlotFlag(plot, "price"); if (price != null) { @@ -186,7 +223,7 @@ public class list extends SubCommand { MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.list.unowned"); return false; } - plots = new HashSet<>(); + plots = new ArrayList<>(); for (Plot plot : PlotSquared.getPlots()) { if (plot.owner == null) { plots.add(plot); @@ -199,7 +236,7 @@ public class list extends SubCommand { MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.list.unknown"); return false; } - plots = new HashSet<>(); + plots = new ArrayList<>(); for (Plot plot : PlotSquared.getPlots()) { if (plot.owner == null) { continue; @@ -220,7 +257,7 @@ public class list extends SubCommand { MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.list.world." + args[0]); return false; } - plots = PlotSquared.getPlots(args[0]).values(); + plots = new ArrayList<>(PlotSquared.getPlots(args[0]).values()); break; } UUID uuid = UUIDHandler.getUUID(args[0]); @@ -229,7 +266,7 @@ public class list extends SubCommand { MainUtil.sendMessage(plr, C.NO_PERMISSION, "plots.list.player"); return false; } - plots = PlotSquared.getPlots(uuid); + plots = new ArrayList<>(PlotSquared.getPlots(uuid)); break; } } @@ -244,18 +281,18 @@ public class list extends SubCommand { MainUtil.sendMessage(plr, C.FOUND_NO_PLOTS); return false; } - - displayPlots(plr, plots, 12, page, world, args); + displayPlots(plr, plots, 12, page, world, args, sort); return true; } - public void displayPlots(PlotPlayer player, Collection oldPlots, int pageSize, int page, String world, String[] args) { - List plots; - if (world != null) { - plots = PlotSquared.sortPlots(oldPlots, world); - } - else { - plots = PlotSquared.sortPlots(oldPlots); + public void displayPlots(PlotPlayer player, List plots, int pageSize, int page, String world, String[] args, boolean sort) { + if (sort) { + if (world != null) { + plots = PlotSquared.sortPlots(plots, world); + } + else { + plots = PlotSquared.sortPlots(plots); + } } if (page < 0) { page = 0; diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/config/C.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/config/C.java index ecd523426..b2830d850 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/config/C.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/config/C.java @@ -151,6 +151,7 @@ public enum C { /* * Ratings */ + RATE_THIS("$2Rate this plot!", "Ratings"), RATING_NOT_VALID("$2You need to specify a number between 1 and 10", "Ratings"), RATING_ALREADY_EXISTS("$2You have already rated plot $2%s", "Ratings"), RATING_APPLIED("$4You successfully rated plot $2%s", "Ratings"), diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/config/Settings.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/config/Settings.java index 92432f5a3..d1c19b2e0 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/config/Settings.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/config/Settings.java @@ -36,6 +36,7 @@ public class Settings { * Default UUID_FECTHING: false */ public static boolean PERMISSION_CACHING = false; + public static boolean CACHE_RATINGS = true; public static boolean UUID_FROM_DISK = false; /** * PlotMe settings diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/AbstractDB.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/AbstractDB.java index 5a6e5dcd8..64a27b90e 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/AbstractDB.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/AbstractDB.java @@ -286,14 +286,7 @@ public interface AbstractDB { * * @return Plot Ratings (pre-calculated) */ - public double getRatings(final Plot plot); - - /** - * if uuid has rated - * @param uuid - * @return - */ - public boolean hasRated(String world, PlotId id, UUID uuid); + public HashMap getRatings(final Plot plot); /** * Set a rating for a plot diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/DBFunc.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/DBFunc.java index 3c3662b04..f67ad781a 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/DBFunc.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/DBFunc.java @@ -343,14 +343,10 @@ public class DBFunc { dbManager.setDenied(world, plot, uuid); } - public static double getRatings(final Plot plot) { + public static HashMap getRatings(final Plot plot) { return dbManager.getRatings(plot); } - public static boolean hasRated(String world, PlotId id, final UUID uuid) { - return dbManager.hasRated(world, id, uuid); - } - public static void setRating(Plot plot, UUID rater, int value) { dbManager.setRating(plot, rater, value); } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java index 03b95ae1c..53126f659 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java @@ -910,6 +910,29 @@ public class SQLManager implements AbstractDB { p = new Plot(plot_id, user, new ArrayList(), new ArrayList(), new ArrayList(), "", null, null, worldname, new boolean[] { false, false, false, false }); plots.put(id, p); } + + if (Settings.CACHE_RATINGS) { + r = stmt.executeQuery("SELECT `plot_plot_id`, `player`, `rating` FROM `" + this.prefix + "plot_rating`"); + while (r.next()) { + id = r.getInt("plot_plot_id"); + o = r.getString("player"); + user = uuids.get(o); + if (user == null) { + user = UUID.fromString(o); + uuids.put(o, user); + } + final Plot plot = plots.get(id); + if (plot != null) { + if (plot.settings.ratings == null ) { + plot.settings.ratings = new HashMap(); + } + plot.settings.ratings.put(user, r.getInt("rating")); + } else { + PlotSquared.log("&cPLOT " + id + " in plot_helpers does not exist. Please create the plot or remove this entry."); + } + } + } + /* * Getting helpers */ @@ -1624,23 +1647,24 @@ public class SQLManager implements AbstractDB { } @Override - public double getRatings(final Plot plot) { + public HashMap getRatings(final Plot plot) { + HashMap map = new HashMap(); try { - final PreparedStatement statement = this.connection.prepareStatement("SELECT AVG(`rating`) AS `rating` FROM `" + this.prefix + "plot_rating` WHERE `plot_plot_id` = ? "); + final PreparedStatement statement = this.connection.prepareStatement("SELECT `rating`, `player` FROM `" + this.prefix + "plot_rating` WHERE `plot_plot_id` = ? "); statement.setInt(1, getId(plot.world, plot.id)); final ResultSet set = statement.executeQuery(); - double rating = 0; - while (set.next()) { - rating = set.getDouble("rating"); + while(set.next()) { + UUID uuid = UUID.fromString(set.getString("player")); + int rating = set.getInt("rating"); + map.put(uuid, rating); } statement.close(); set.close(); - return rating; } catch (final SQLException e) { PlotSquared.log("&7[WARN] " + "Failed to fetch rating for plot " + plot.getId().toString()); e.printStackTrace(); } - return 0.0d; + return map; } @@ -2185,24 +2209,4 @@ public class SQLManager implements AbstractDB { return false; } } - - @Override - public boolean hasRated(String world, PlotId id, UUID uuid) { - try { - PreparedStatement stmt = SQLManager.this.connection.prepareStatement("SELECT * FROM `" + this.prefix + "plot_rating` WHERE `plot_plot_id` = ? AND `player` = ?"); - stmt.setInt(1, getId(world, id)); - stmt.setString(2, uuid.toString()); - final ResultSet r = stmt.executeQuery(); - if (r.next()) { - stmt.close(); - return true; - } - stmt.close(); - return false; - } - catch (Exception e) { - e.printStackTrace(); - } - return false; - } } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/generator/BukkitHybridUtils.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/generator/BukkitHybridUtils.java index e63b4040c..6636b78c3 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/generator/BukkitHybridUtils.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/generator/BukkitHybridUtils.java @@ -46,6 +46,24 @@ public class BukkitHybridUtils extends HybridUtils { return count / array.length; } + public double getMean(double[] array) { + double count = 0; + for (double i : array) { + count += i; + } + return count / array.length; + } + + public double getSD(double[] array) { + double av = getMean(array); + double sd = 0; + for (int i=0; i whenDone) { + public void analyzePlot(Plot plot, final RunnableVal whenDone) { // TODO Auto-generated method stub // int diff, int variety, int verticies, int rotation, int height_sd @@ -72,33 +97,98 @@ public class BukkitHybridUtils extends HybridUtils { * - recheck each block * */ - World world = Bukkit.getWorld(plot.world); - ChunkGenerator gen = world.getGenerator(); - BiomeGrid base = new BiomeGrid() { @Override public void setBiome(int a, int b, Biome c) {} @Override public Biome getBiome(int a, int b) {return null;}}; + final World world = Bukkit.getWorld(plot.world); + final ChunkGenerator gen = world.getGenerator(); + if (gen == null) { + return; + } + final BiomeGrid base = new BiomeGrid() { @Override public void setBiome(int a, int b, Biome c) {} @Override public Biome getBiome(int a, int b) {return null;}}; ClassicPlotWorld cpw = (ClassicPlotWorld) PlotSquared.getPlotWorld(plot.world); - final Location bot = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1 - cpw.ROAD_WIDTH, 0, 1 - cpw.ROAD_WIDTH); - final Location top = MainUtil.getPlotTopLoc(plot.world, plot.id).add(cpw.ROAD_WIDTH, 0, cpw.ROAD_WIDTH); - int bx = bot.getX() >> 4; - int bz = bot.getZ() >> 4; - int tx = top.getX() >> 4; - int tz = top.getZ() >> 4; - Random r = new Random(); + final Location bot = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1); + final Location top = MainUtil.getPlotTopLoc(plot.world, plot.id).add(1, 0, 1); + final int bx = bot.getX() >> 4; + final int bz = bot.getZ() >> 4; + final int tx = top.getX() >> 4; + final int tz = top.getZ() >> 4; + final Random r = new Random(); AugmentedPopulator.initCache(); - for (int X = bx + 1; X < tx; X++) { - for (int Z = bz + 1; Z < tz; Z++) { + + final PlotAnalysis analysis = new PlotAnalysis(); + + int num_chunks = (tx - bx + 1) * (tz - bz + 1); + + short[][][] oldblocks = new short[256][top.getX() - bot.getX() + 1][top.getZ() - bot.getZ() + 1]; + short[][][] newblocks = new short[256][top.getX() - bot.getX() + 1][top.getZ() - bot.getZ() + 1]; + + final List chunks = new ArrayList<>(); + + for (int X = bx; X <= tx; X++) { + for (int Z = bz; Z <= tz; Z++) { Chunk chunk = world.getChunkAt(X, Z); - short[][] result = gen.generateExtBlockSections(world, r, X, Z, base); + chunks.add(chunk); + } + } + + final double[] changes_sd = new double[num_chunks]; + final double[] rotations_sd = new double[num_chunks]; + final double[] data_sd = new double[num_chunks]; + final double[] variety_sd = new double[num_chunks]; + final double[] uniformity_sd = new double[num_chunks]; + final double[] verticies_sd = new double[num_chunks]; + final double[] height_sd = new double[num_chunks]; + + final HashSet variety = new HashSet<>(); + + TaskManager.index.increment(); + final Integer currentIndex = TaskManager.index.toInteger(); + final Integer task = TaskManager.runTaskRepeat(new Runnable() { + @Override + public void run() { + int index = chunks.size() - 1; + if (index == -1) { + TaskManager.runTaskAsync(new Runnable() { + @Override + public void run() { + PlotSquared.TASK.cancelTask(TaskManager.tasks.get(currentIndex)); + analysis.variety_total = variety.size(); + analysis.changes_sd = getSD(changes_sd); + analysis.rotations_sd = getSD(rotations_sd); + analysis.data_sd = getSD(data_sd); + analysis.uniformity_sd = getSD(uniformity_sd); + analysis.variety_sd = getSD(variety_sd); + analysis.verticies_sd = getSD(verticies_sd); + analysis.height_sd = getSD(height_sd); + whenDone.value = analysis; + whenDone.run(); + } + }); + return; + } + Chunk chunk = chunks.remove(0); + int X = chunk.getX(); + int Z = chunk.getZ(); + short[][] result = gen.generateExtBlockSections(world, r, chunk.getX(), chunk.getZ(), base); short[][] current = new short[16][]; - // load current chunk into a PlotBlock[][] map; + int minX; + int minZ; + int maxX; + int maxZ; + if (X == bx) minX = mod(bot.getX()); + else minX = 0; + if (Z == bz) minZ = mod(bot.getZ()); + else minZ = 0; + if (X == tx) maxX = mod(top.getX()); + else maxX = 16; + if (Z == tz) maxZ = mod(top.getZ()); + else maxZ = 16; long changes = 0; long rotations = 0; long materialdata = 0; - HashSet variety = new HashSet<>(); int[] height = new int[256]; int collumn_index = 0; - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { + for (int x = minX; x < maxX; x++) { + for (int z = minZ; z < maxZ; z++) { int max = 0; for (int y = 0; y < 256; y++) { Block block = chunk.getBlock(x, y, z); @@ -131,16 +221,17 @@ public class BukkitHybridUtils extends HybridUtils { } height[collumn_index] = max; collumn_index++; - // compare blocks - // calculate variety } } long verticies = 0; - for (int x = 1; x < 15; x++) { - for (int z = 1; z < 15; z++) { - for (int y = 1; y < 255; y++) { + int[] uniformity = new int[254]; + for (int y = 1; y < 255; y++) { + HashSet blocks = new HashSet<>(); + for (int x = minX + 1; x < maxX - 1; x++) { + for (int z = minZ + 1; z < maxZ - 1; z++) { short id = current[y >> 4][((y & 0xF) << 8) | (z << 4) | x]; if (id == 0) continue; + blocks.add((int) id); if (current[(y + 1) >> 4][(((y + 1) & 0xF) << 8) | (z << 4) | x] != 0) verticies--; if (current[(y - 1) >> 4][(((y - 1) & 0xF) << 8) | (z << 4) | x] != 0) verticies--; if (current[y >> 4][((y & 0xF) << 8) | ((z + 1) << 4) | x] != 0) verticies--; @@ -150,17 +241,25 @@ public class BukkitHybridUtils extends HybridUtils { verticies += 6; } } + uniformity[y-1] = blocks.size(); } + analysis.changes_total += changes; + analysis.rotations_total += rotations; + analysis.data_total += materialdata; + analysis.verticies_total += verticies; + double tmp = getSD(height); + analysis.height_total += tmp; - System.out.print("==============="); - System.out.print(" - changes: " + changes); - System.out.print(" - rotations: " + rotations); - System.out.print(" - data: " + materialdata); - System.out.print(" - variety: " + variety.size()); - System.out.print(" - sd: " + getSD(height)); - System.out.print(" - verticies: " + verticies); - } - } + changes_sd[index] = changes; + rotations_sd[index] = rotations; + data_sd[index] = materialdata; + uniformity_sd[index] = getSD(uniformity); + variety_sd[index] = variety.size(); + verticies_sd[index] = verticies; + height_sd[index] = tmp; + }; + }, 1); + TaskManager.tasks.put(currentIndex, task); } public void checkModified(final Plot plot, final RunnableVal whenDone) { diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlayerEvents.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlayerEvents.java index cff971a86..3d641e7d0 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlayerEvents.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlayerEvents.java @@ -947,9 +947,10 @@ public class PlayerEvents extends com.intellectualcrafters.plot.listeners.PlotLi public boolean checkEntity(Entity entity, Plot plot) { if (plot != null && plot.owner != null) { Flag entityFlag = FlagManager.getPlotFlag(plot, "entity-cap"); - int[] mobs = ChunkManager.manager.countEntities(plot); + int[] mobs = null; if (entityFlag != null) { int cap = ((Integer) entityFlag.getValue()); + if (mobs == null) mobs = ChunkManager.manager.countEntities(plot); if (mobs[0] >= cap) { return true; } @@ -958,6 +959,7 @@ public class PlayerEvents extends com.intellectualcrafters.plot.listeners.PlotLi Flag mobFlag = FlagManager.getPlotFlag(plot, "mob-cap"); if (mobFlag != null) { int cap = ((Integer) mobFlag.getValue()); + if (mobs == null) mobs = ChunkManager.manager.countEntities(plot); if (mobs[3] >= cap) { return true; } @@ -966,6 +968,7 @@ public class PlayerEvents extends com.intellectualcrafters.plot.listeners.PlotLi Flag animalFlag = FlagManager.getPlotFlag(plot, "animal-cap"); if (animalFlag != null) { int cap = ((Integer) animalFlag.getValue()); + if (mobs == null) mobs = ChunkManager.manager.countEntities(plot); if (mobs[1] >= cap) { return true; } @@ -975,6 +978,7 @@ public class PlayerEvents extends com.intellectualcrafters.plot.listeners.PlotLi Flag monsterFlag = FlagManager.getPlotFlag(plot, "hostile-cap"); if (monsterFlag != null) { int cap = ((Integer) monsterFlag.getValue()); + if (mobs == null) mobs = ChunkManager.manager.countEntities(plot); if (mobs[2] >= cap) { return true; } @@ -985,6 +989,7 @@ public class PlayerEvents extends com.intellectualcrafters.plot.listeners.PlotLi Flag vehicleFlag = FlagManager.getPlotFlag(plot, "vehicle-cap"); if (vehicleFlag != null) { int cap = ((Integer) vehicleFlag.getValue()); + if (mobs == null) mobs = ChunkManager.manager.countEntities(plot); if (mobs[4] >= cap) { return true; } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotAnalysis.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotAnalysis.java index b78183c27..531cd6703 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotAnalysis.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotAnalysis.java @@ -1,19 +1,18 @@ package com.intellectualcrafters.plot.object; public class PlotAnalysis { - public final long diff; - public final long variety; - public final long verticies; - public final long rotation; - public final long height_sd; - public final long regularity; + public int changes_total; + public int rotations_total; + public int data_total; + public int variety_total; + public int verticies_total; + public double height_total; - public PlotAnalysis(int diff, int variety, int verticies, int rotation, int height_sd, int regularity) { - this.diff = diff; - this.variety = variety; - this.verticies = verticies; - this.rotation = rotation; - this.height_sd = height_sd; - this.regularity = regularity; - } + public double changes_sd; + public double rotations_sd; + public double data_sd; + public double variety_sd; + public double uniformity_sd; + public double verticies_sd; + public double height_sd; } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotSettings.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotSettings.java index 5b3df6d1a..c544d7343 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotSettings.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotSettings.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Set; +import java.util.UUID; import com.intellectualcrafters.plot.flag.Flag; import com.intellectualcrafters.plot.flag.FlagManager; @@ -55,6 +56,12 @@ public class PlotSettings { * Comments */ private List comments = null; + + /** + * The ratings for a plot + */ + public HashMap ratings; + /** * Flags */ diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/MainUtil.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/MainUtil.java index 376e2b9e8..90f15bec8 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/MainUtil.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/MainUtil.java @@ -23,6 +23,7 @@ package com.intellectualcrafters.plot.util; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.Map.Entry; import java.util.UUID; import com.intellectualcrafters.plot.PlotSquared; @@ -1552,4 +1553,23 @@ public class MainUtil { } return getPlot(loc.getWorld(), id); } + + public static double getAverageRating(Plot plot) { + HashMap rating; + if (plot.settings.ratings != null) { + rating = plot.settings.ratings; + } + else { + rating = DBFunc.getRatings(plot); + } + if (rating == null || rating.size() == 0) { + return 0; + } + double val = 0; + for (Entry entry : rating.entrySet()) { + val += entry.getValue(); + } + System.out.print(val); + return val / (double) rating.size(); + } } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/Permissions.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/Permissions.java index 491888487..10aeeb9de 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/Permissions.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/Permissions.java @@ -38,10 +38,10 @@ public class Permissions { public static int hasPermissionRange(final PlotPlayer player, final String stub, final int range) { if ((player == null) || player.isOp() || player.hasPermission(ADMIN)) { - return Byte.MAX_VALUE; + return Integer.MAX_VALUE; } if (player.hasPermission(stub + ".*")) { - return Byte.MAX_VALUE; + return Integer.MAX_VALUE; } for (int i = range; i > 0; i--) { if (player.hasPermission(stub + "." + i)) {