From d11234034f7d62b02b614721c7deec9e622385a5 Mon Sep 17 00:00:00 2001 From: jamix77 <> Date: Fri, 27 Mar 2020 03:36:23 +0000 Subject: [PATCH 1/2] Statistics system Yay funny number stuff for red! --- .../global/ttrail/ClueScrollPlugin.java | 1 + .../free/gather/GatheringSkillPulse.java | 2 + .../org/crandor/game/node/entity/Entity.java | 4 + .../game/node/entity/player/Player.java | 15 +++ .../player/info/login/PlayerParser.java | 5 + .../statistics/PlayerStatisticsManager.java | 115 ++++++++++++++++++ .../player/link/statistics/Statistic.java | 85 +++++++++++++ .../command/DeveloperCommandPlugin.java | 12 ++ .../plugin/command/PlayerCommandPlugin.java | 43 +++++++ .../plugin/dialogue/BorderGuardDialogue.java | 1 + .../object/FieldPickingPlugin.java | 1 + .../object/TollGateOptionPlugin.java | 1 + 12 files changed, 285 insertions(+) create mode 100644 Server/src/org/crandor/game/node/entity/player/link/statistics/PlayerStatisticsManager.java create mode 100644 Server/src/org/crandor/game/node/entity/player/link/statistics/Statistic.java diff --git a/Server/src/org/crandor/game/content/global/ttrail/ClueScrollPlugin.java b/Server/src/org/crandor/game/content/global/ttrail/ClueScrollPlugin.java index 95a8a6f74..12cb4e3a2 100644 --- a/Server/src/org/crandor/game/content/global/ttrail/ClueScrollPlugin.java +++ b/Server/src/org/crandor/game/content/global/ttrail/ClueScrollPlugin.java @@ -86,6 +86,7 @@ public abstract class ClueScrollPlugin extends MapZone implements Plugin } nextStage(player, clue); if (casket) { + player.getStatisticsManager().getCLUES_COMPLETED().incrementAmount(); player.getInventory().replace(level.getCasket(), clue.getSlot()); } else { player.getInventory().remove(clue); diff --git a/Server/src/org/crandor/game/content/skill/free/gather/GatheringSkillPulse.java b/Server/src/org/crandor/game/content/skill/free/gather/GatheringSkillPulse.java index bc983b197..4c3080b11 100644 --- a/Server/src/org/crandor/game/content/skill/free/gather/GatheringSkillPulse.java +++ b/Server/src/org/crandor/game/content/skill/free/gather/GatheringSkillPulse.java @@ -154,6 +154,7 @@ public final class GatheringSkillPulse extends SkillPulse { Projectile.create(player, null, 1776, 35, 30, 20, 25).transform(player, new Location(player.getLocation().getX() + 2, player.getLocation().getY()), true, 25, 25).send(); player.getSkills().addExperience(Skills.WOODCUTTING, resource.getExperience()); player.getSkills().addExperience(Skills.FIREMAKING, resource.getExperience()); + player.getStatisticsManager().getLOGS_OBTAINED().incrementAmount(); return false; } int reward = resource.getReward(); @@ -176,6 +177,7 @@ public final class GatheringSkillPulse extends SkillPulse { player.getPacketDispatch().sendMessage("You cut a branch from the Dramen tree."); } else { player.getPacketDispatch().sendMessage("You get some " + ItemDefinition.forId(reward).getName().toLowerCase() + "."); + player.getStatisticsManager().getLOGS_OBTAINED().incrementAmount(); } // Calculate if the player should receive a bonus gem or bonus ore or both if (!isMiningEssence && isMining) { diff --git a/Server/src/org/crandor/game/node/entity/Entity.java b/Server/src/org/crandor/game/node/entity/Entity.java index c4549a903..d5f9ef9d4 100644 --- a/Server/src/org/crandor/game/node/entity/Entity.java +++ b/Server/src/org/crandor/game/node/entity/Entity.java @@ -211,6 +211,10 @@ public abstract class Entity extends Node { * @param killer The killer of this entity. */ public void finalizeDeath(Entity killer) { + if (killer.isPlayer()) { + if (!((Player)killer).isArtificial()) + ((Player)killer).getStatisticsManager().getENTITIES_KILLED().incrementAmount(); + } skills.restore(); skills.rechargePrayerPoints(); impactHandler.getImpactQueue().clear(); diff --git a/Server/src/org/crandor/game/node/entity/player/Player.java b/Server/src/org/crandor/game/node/entity/player/Player.java index 750c501d6..f77f26de0 100644 --- a/Server/src/org/crandor/game/node/entity/player/Player.java +++ b/Server/src/org/crandor/game/node/entity/player/Player.java @@ -65,6 +65,7 @@ import org.crandor.game.node.entity.player.link.prayer.PrayerType; import org.crandor.game.node.entity.player.link.quest.QuestRepository; import org.crandor.game.node.entity.player.link.request.RequestManager; import org.crandor.game.node.entity.player.link.skillertasks.SkillerTasks; +import org.crandor.game.node.entity.player.link.statistics.PlayerStatisticsManager; import org.crandor.game.node.item.GroundItem; import org.crandor.game.node.item.GroundItemManager; import org.crandor.game.node.item.Item; @@ -99,6 +100,7 @@ import org.crandor.net.packet.out.SkillLevel; import org.crandor.net.packet.out.UpdateSceneGraph; import org.crandor.plugin.Plugin; import org.crandor.tools.StringUtils; + import plugin.activity.pyramidplunder.PlunderObjectManager; /** @@ -302,6 +304,11 @@ public class Player extends Entity { * The jobs minigame manager. */ private final JobsMinigameManager jobsManager = new JobsMinigameManager(this); + + /** + * The statistics manager. + */ + private final PlayerStatisticsManager statisticsManager = new PlayerStatisticsManager(this); /** * The logout plugins. @@ -534,6 +541,10 @@ public class Player extends Entity { return; } getPacketDispatch().sendMessage("Oh dear, you are dead!"); + + if (!isArtificial()) { + getStatisticsManager().getDEATHS().incrementAmount(); + } //If player was a Hardcore Ironman, announce that they died if (this.getIronmanManager().getMode().equals(IronmanMode.HARDCORE)){ //if this was checkRestriction, ultimate irons would be moved to HARDCORE_DEAD as well @@ -1340,4 +1351,8 @@ public class Player extends Entity { public JobsMinigameManager getJobsManager() { return jobsManager; } + + public PlayerStatisticsManager getStatisticsManager() { + return statisticsManager; + } } \ No newline at end of file diff --git a/Server/src/org/crandor/game/node/entity/player/info/login/PlayerParser.java b/Server/src/org/crandor/game/node/entity/player/info/login/PlayerParser.java index a0656b609..5c19f2705 100644 --- a/Server/src/org/crandor/game/node/entity/player/info/login/PlayerParser.java +++ b/Server/src/org/crandor/game/node/entity/player/info/login/PlayerParser.java @@ -149,6 +149,9 @@ public final class PlayerParser { case 46: player.getSkills().parseExpRate(buffer); break; + case 47: + player.getStatisticsManager().parse(buffer); + break; default: System.err.println("[Player parsing] Unhandled opcode: " + opcode + " for " + player.getName() + " - [log=" + Arrays.toString(opcodeLog) + "]."); break; @@ -302,6 +305,8 @@ public final class PlayerParser { } player.getSkills().saveExpRate(buffer.put((byte) 46)); + + player.getStatisticsManager().save(buffer.put((byte)47)); buffer.put((byte) 0); // EOF opcode buffer.flip(); diff --git a/Server/src/org/crandor/game/node/entity/player/link/statistics/PlayerStatisticsManager.java b/Server/src/org/crandor/game/node/entity/player/link/statistics/PlayerStatisticsManager.java new file mode 100644 index 000000000..8978a5aa9 --- /dev/null +++ b/Server/src/org/crandor/game/node/entity/player/link/statistics/PlayerStatisticsManager.java @@ -0,0 +1,115 @@ +package org.crandor.game.node.entity.player.link.statistics; + +import java.nio.ByteBuffer; +import java.util.ArrayList; + +import org.crandor.game.node.entity.player.Player; +import org.crandor.game.node.entity.player.info.login.SavingModule; + +/** + * Stuff + * @author jamix77 + * + */ +public class PlayerStatisticsManager implements SavingModule { + + /** + * Array of statistics. + */ + private final ArrayList STATISTICS = new ArrayList(); + + + private Statistic + AL_KHARID_GATE_PASSES, + FLAX_PICKED, + CLUES_COMPLETED, + ENTITIES_KILLED, + DEATHS, + LOGS_OBTAINED; + + + /** + * The player instance for this manager. + */ + private final Player player; + + + public PlayerStatisticsManager(Player player) { + this.player = player; + if (!player.isArtificial()) + initStats(); + } + + private void initStats() { + AL_KHARID_GATE_PASSES = new Statistic(player,this); + FLAX_PICKED = new Statistic(player,this); + CLUES_COMPLETED = new Statistic(player,this); + LOGS_OBTAINED = new Statistic(player,this); + ENTITIES_KILLED = new Statistic(player,this); + DEATHS = new Statistic(player,this); + } + + @Override + public void save(ByteBuffer buffer) { + for (int i = 0; i < STATISTICS.size(); i++) { + Statistic s = STATISTICS.get(i); + buffer.put((byte) 1).putInt(i).putInt(s.getStatisticalAmount()); + } + buffer.put((byte)0); + } + + @Override + public void parse(ByteBuffer buffer) { + int opcode; + while ((opcode = buffer.get() & 0xFF) != 0) { + switch (opcode) { + case 1: + int index = buffer.getInt(); + int amount = buffer.getInt(); + STATISTICS.get(index).setStatisticalAmount(amount); + break; + } + } + + } + + /** + * Add a statistic to the arraylist. + * @param statistic + */ + public void addStatistic(Statistic statistic) { + STATISTICS.add(statistic); + } + + + public ArrayList getSTATISTICS() { + return STATISTICS; + } + + public Statistic getAL_KHARID_GATE_PASSES() { + return AL_KHARID_GATE_PASSES; + } + + public Statistic getFLAX_PICKED() { + return FLAX_PICKED; + } + + public Statistic getCLUES_COMPLETED() { + return CLUES_COMPLETED; + } + + public Statistic getLOGS_OBTAINED() { + return LOGS_OBTAINED; + } + + public Statistic getENTITIES_KILLED() { + return ENTITIES_KILLED; + } + + public Statistic getDEATHS() { + return DEATHS; + } + + + +} diff --git a/Server/src/org/crandor/game/node/entity/player/link/statistics/Statistic.java b/Server/src/org/crandor/game/node/entity/player/link/statistics/Statistic.java new file mode 100644 index 000000000..56878b1b5 --- /dev/null +++ b/Server/src/org/crandor/game/node/entity/player/link/statistics/Statistic.java @@ -0,0 +1,85 @@ +package org.crandor.game.node.entity.player.link.statistics; + +import org.crandor.game.node.entity.player.Player; + +/** + * A singular statistic. + * @author jamix77 + * + */ +public class Statistic { + + /** + * The player instance for this manager. + */ + private final Player player; + + /** + * The amount of the statistic. + */ + private int statisticalAmount; + + /** + * + * Constructs a new @{Code Statistic} object. + * @param player + */ + public Statistic(Player player, PlayerStatisticsManager sm) { + this(player,0,sm); + } + + /** + * + * Constructs a new @{Code Statistic} object. + * @param player + * @param amount + */ + public Statistic(Player player,int amount, PlayerStatisticsManager sm) { + this.player = player; + this.statisticalAmount = amount; + sm.addStatistic(this); + } + + /** + * Increase only by one. + */ + public void incrementAmount() { + increaseAmount(1); + } + + /** + * Decrease only by one. + */ + public void decrementAmount() { + decreaseAmount(1); + } + + /** + * Increase by a certain amount. + * @param amount + */ + public void increaseAmount(int amount) { + statisticalAmount += amount; + } + + /** + * Decrease by a certain amount. + * @param amount + */ + public void decreaseAmount(int amount) { + statisticalAmount -= amount; + } + + /** + * @return the amount + */ + public int getStatisticalAmount() { + return statisticalAmount; + } + + public void setStatisticalAmount(int statisticalAmount) { + this.statisticalAmount = statisticalAmount; + } + + +} diff --git a/Server/src/plugin/command/DeveloperCommandPlugin.java b/Server/src/plugin/command/DeveloperCommandPlugin.java index 34d7a0e62..a8b5d3737 100644 --- a/Server/src/plugin/command/DeveloperCommandPlugin.java +++ b/Server/src/plugin/command/DeveloperCommandPlugin.java @@ -26,6 +26,7 @@ import org.crandor.game.node.entity.player.ai.resource.ResourceAIPManager; import org.crandor.game.node.entity.player.info.login.PlayerParser; import org.crandor.game.node.entity.player.link.IronmanMode; import org.crandor.game.node.entity.player.link.appearance.Gender; +import org.crandor.game.node.entity.player.link.music.MusicEntry; import org.crandor.game.node.entity.player.link.quest.Quest; import org.crandor.game.node.entity.player.link.skillertasks.Difficulty; import org.crandor.game.node.entity.state.EntityState; @@ -100,6 +101,17 @@ public final class DeveloperCommandPlugin extends CommandPlugin { @Override public boolean parse(final Player player, String name, String[] args) { switch (name) { + case "unlockmusic": + for (MusicEntry me : MusicEntry.getSongs().values()) { + player.getMusicPlayer().unlock(me.getId()); + } + + break; + + case "playsong": + player.getMusicPlayer().play(MusicEntry.getSongs().get(Integer.parseInt(args[1]))); + player.sendMessage("Playing song: " + MusicEntry.getSongs().get(Integer.parseInt(args[1])).getName()); + break; case "find": try { player.getAttributes().put("spawning_items", true); diff --git a/Server/src/plugin/command/PlayerCommandPlugin.java b/Server/src/plugin/command/PlayerCommandPlugin.java index b8190196f..be9e68f77 100644 --- a/Server/src/plugin/command/PlayerCommandPlugin.java +++ b/Server/src/plugin/command/PlayerCommandPlugin.java @@ -2,8 +2,11 @@ package plugin.command; import org.crandor.ServerConstants; import org.crandor.game.component.Component; +import org.crandor.game.content.skill.Skills; import org.crandor.game.node.entity.player.Player; +import org.crandor.game.node.entity.player.info.PlayerDetails; import org.crandor.game.node.entity.player.info.Rights; +import org.crandor.game.node.entity.player.info.login.PlayerParser; import org.crandor.game.node.entity.player.link.IronmanMode; import org.crandor.game.node.entity.player.link.RunScript; import org.crandor.game.node.entity.player.link.quest.Quest; @@ -53,6 +56,18 @@ public final class PlayerCommandPlugin extends CommandPlugin { TutorialStage.load(player, stage, false); break; */ + + case "stats": + if (arguments.length < 2) { + player.sendMessage("You must enter a name to search!"); + } + try { + Player target = new Player(PlayerDetails.getDetails(arguments[1])); + PlayerParser.parse(target); + if (!target.getDetails().parse()) break; + sendHiscore(player,target); + } catch (Exception e) {} + break; case "shop": CREDIT_STORE.open(player); @@ -254,6 +269,34 @@ public final class PlayerCommandPlugin extends CommandPlugin { player.getPacketDispatch().sendString("::bankresettabs", 275, lineId++); player.getPacketDispatch().sendString("Reset all of your bank tabs.", 275, lineId++); } + + private void sendHiscore(Player player, Player target) { + if (player.getInterfaceManager().isOpened()) { + player.sendMessage("Finish what you're currently doing."); + return; + } + player.getInterfaceManager().open(new Component(275)); + //CLear old data + for (int i = 0; i < 311; i++) { + player.getPacketDispatch().sendString("", 275, i); + } + // Title + player.getPacketDispatch().sendString("" + target.getUsername() + "'s stats.", 275, 2); + + // Content + int lineId = 11; + player.getPacketDispatch().sendString("Total level: " + target.getSkills().getTotalLevel(), 275, lineId++); + player.getPacketDispatch().sendString("Total xp: " + StringUtils.getFormattedNumber(target.getSkills().getTotalXp()), 275, lineId++); + for (int i = 0; i < Skills.SKILL_NAME.length; i++) { + player.getPacketDispatch().sendString("" + Skills.SKILL_NAME[i] + ": " + target.getSkills().getLevel(i) + " (" + StringUtils.getFormattedNumber((int) Math.round(target.getSkills().getExperience(i))) + ")", 275, lineId++); + } + player.getPacketDispatch().sendString("(Since 27/03/2020) Al kharid passes: " + target.getStatisticsManager().getAL_KHARID_GATE_PASSES().getStatisticalAmount(), 275, lineId++); + player.getPacketDispatch().sendString("(Since 27/03/2020) Logs chopped: " + target.getStatisticsManager().getLOGS_OBTAINED().getStatisticalAmount(), 275, lineId++); + player.getPacketDispatch().sendString("(Since 27/03/2020) Flax picked: " + target.getStatisticsManager().getFLAX_PICKED().getStatisticalAmount(), 275, lineId++); + player.getPacketDispatch().sendString("(Since 27/03/2020) Clue scrolls completed: " + target.getStatisticsManager().getCLUES_COMPLETED().getStatisticalAmount(), 275, lineId++); + player.getPacketDispatch().sendString("(Since 27/03/2020) Enemies killed: " + target.getStatisticsManager().getENTITIES_KILLED().getStatisticalAmount(), 275, lineId++); + player.getPacketDispatch().sendString("(Since 27/03/2020) Deaths: " + target.getStatisticsManager().getDEATHS().getStatisticalAmount(), 275, lineId++); + } /** * Sends information about donating. diff --git a/Server/src/plugin/dialogue/BorderGuardDialogue.java b/Server/src/plugin/dialogue/BorderGuardDialogue.java index 7641844ac..6303b87c3 100644 --- a/Server/src/plugin/dialogue/BorderGuardDialogue.java +++ b/Server/src/plugin/dialogue/BorderGuardDialogue.java @@ -103,6 +103,7 @@ public final class BorderGuardDialogue extends DialoguePlugin { } if (player.getInventory().remove(COINS)) { DoorActionHandler.handleAutowalkDoor(player, door); + player.getStatisticsManager().getAL_KHARID_GATE_PASSES().incrementAmount(); } else { player.getPacketDispatch().sendMessage("You need 10 gold coins to pay the toll."); } diff --git a/Server/src/plugin/interaction/object/FieldPickingPlugin.java b/Server/src/plugin/interaction/object/FieldPickingPlugin.java index 7f8eb79a0..34d8dee0e 100644 --- a/Server/src/plugin/interaction/object/FieldPickingPlugin.java +++ b/Server/src/plugin/interaction/object/FieldPickingPlugin.java @@ -120,6 +120,7 @@ public final class FieldPickingPlugin extends OptionHandler { int charge = object.getCharge(); player.getAudioManager().send(2581); player.getPacketDispatch().sendMessage("You pick some flax."); + player.getStatisticsManager().getFLAX_PICKED().incrementAmount(); if (charge > 1000 + RandomFunction.random(2, 8)) { object.setActive(false); object.setCharge(1000); diff --git a/Server/src/plugin/interaction/object/TollGateOptionPlugin.java b/Server/src/plugin/interaction/object/TollGateOptionPlugin.java index 88e3409b7..15197865a 100644 --- a/Server/src/plugin/interaction/object/TollGateOptionPlugin.java +++ b/Server/src/plugin/interaction/object/TollGateOptionPlugin.java @@ -25,6 +25,7 @@ public class TollGateOptionPlugin extends OptionHandler { player.getInventory().remove(new Item(995, 10)); player.getPacketDispatch().sendMessage("You quickly pay the 10 gold toll and go through the gates."); DoorActionHandler.handleAutowalkDoor(player, (GameObject) node); + player.getStatisticsManager().getAL_KHARID_GATE_PASSES().incrementAmount(); return true; } else { player.getPacketDispatch().sendMessage("You need 10 gold to pass through the gates."); From 69e65680ec5df6360c724ad1fd904ed3608e369f Mon Sep 17 00:00:00 2001 From: jamix77 <> Date: Fri, 27 Mar 2020 15:49:56 +0000 Subject: [PATCH 2/2] More statistics!! Added more stuff to the statistics tab. and made it easier to search for players, and wont throw errors if a wrong name is added. Good stuff me. RAWR :3 --- .../plugin/command/PlayerCommandPlugin.java | 41 +++++++++++++++---- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/Server/src/plugin/command/PlayerCommandPlugin.java b/Server/src/plugin/command/PlayerCommandPlugin.java index be9e68f77..7c823f33b 100644 --- a/Server/src/plugin/command/PlayerCommandPlugin.java +++ b/Server/src/plugin/command/PlayerCommandPlugin.java @@ -9,6 +9,7 @@ import org.crandor.game.node.entity.player.info.Rights; import org.crandor.game.node.entity.player.info.login.PlayerParser; import org.crandor.game.node.entity.player.link.IronmanMode; import org.crandor.game.node.entity.player.link.RunScript; +import org.crandor.game.node.entity.player.link.music.MusicEntry; import org.crandor.game.node.entity.player.link.quest.Quest; import org.crandor.game.node.entity.player.link.quest.QuestRepository; import org.crandor.game.system.command.CommandPlugin; @@ -58,15 +59,25 @@ public final class PlayerCommandPlugin extends CommandPlugin { */ case "stats": - if (arguments.length < 2) { - player.sendMessage("You must enter a name to search!"); - } - try { - Player target = new Player(PlayerDetails.getDetails(arguments[1])); - PlayerParser.parse(target); - if (!target.getDetails().parse()) break; - sendHiscore(player,target); - } catch (Exception e) {} + + + player.setAttribute("runscript", new RunScript() { + @Override + public boolean handle() { + try { + Player target = new Player(PlayerDetails.getDetails((String)value)); + PlayerParser.parse(target); + if (!target.getDetails().parse()) return true; + sendHiscore(player,target); + } + catch (Exception e) {player.getDialogueInterpreter().sendPlainMessage(false, "That isn't a valid name.");} + return true; + } + }); + player.getDialogueInterpreter().sendInput(true, "Enter a username:"); + + + break; case "shop": @@ -290,12 +301,24 @@ public final class PlayerCommandPlugin extends CommandPlugin { for (int i = 0; i < Skills.SKILL_NAME.length; i++) { player.getPacketDispatch().sendString("" + Skills.SKILL_NAME[i] + ": " + target.getSkills().getLevel(i) + " (" + StringUtils.getFormattedNumber((int) Math.round(target.getSkills().getExperience(i))) + ")", 275, lineId++); } + + //stats player.getPacketDispatch().sendString("(Since 27/03/2020) Al kharid passes: " + target.getStatisticsManager().getAL_KHARID_GATE_PASSES().getStatisticalAmount(), 275, lineId++); player.getPacketDispatch().sendString("(Since 27/03/2020) Logs chopped: " + target.getStatisticsManager().getLOGS_OBTAINED().getStatisticalAmount(), 275, lineId++); player.getPacketDispatch().sendString("(Since 27/03/2020) Flax picked: " + target.getStatisticsManager().getFLAX_PICKED().getStatisticalAmount(), 275, lineId++); player.getPacketDispatch().sendString("(Since 27/03/2020) Clue scrolls completed: " + target.getStatisticsManager().getCLUES_COMPLETED().getStatisticalAmount(), 275, lineId++); player.getPacketDispatch().sendString("(Since 27/03/2020) Enemies killed: " + target.getStatisticsManager().getENTITIES_KILLED().getStatisticalAmount(), 275, lineId++); player.getPacketDispatch().sendString("(Since 27/03/2020) Deaths: " + target.getStatisticsManager().getDEATHS().getStatisticalAmount(), 275, lineId++); + player.getPacketDispatch().sendString("Music tracks unlocked: " + target.getMusicPlayer().getUnlocked().size() + "/" + MusicEntry.getSongs().size(), 275, lineId++); + + + //quests + player.getPacketDispatch().sendString("", 275, lineId++); + player.getPacketDispatch().sendString("Quests Completed:", 275, lineId++); + for (Quest q : QuestRepository.getQuests().values()) { + player.getPacketDispatch().sendString("" + (q.isCompleted(target) ? "" : "") + q.getName() + " ", 275, lineId++); + } + } /**