MCStats / Plugin Metrics (R7) - Easy & advanced Plugin Statistics

Discussion in 'Resources' started by Hidendra, May 25, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    Hidendra

    Hey,

    My apologies for the lack of update(s) (for those of you that were in IRC likely found out when it happened). I haven't been getting notifications for this thread. Looking at my options, notifications when a reply was made was disabled for some reason!

    Now first of all to address the data loss a few weeks ago about 2 weeks ago. That was caused by me making a mistake and having to restore "column -> graph" associations from a backup -- this was caused by a late night and as a result I've stopped using a MySQL console past 1 am :)

    Secondly, re: the waits to get a plugin added to your author account, that's slack on my part and as of a few days ago I'm checking it much more actively (I may look into blackmailing some people into helping, but as of this moment it is just myself)

    Now the more current news, there will be 30-60 minutes of downtime later on this evening (depends on how long MySQL takes to shutdown, probably a long time) due to switching to hardware that's in the same DC, almost half the cost, and almost 1.5x as powerful! No servers should see errors but the website will be unavailable. It is some of the brand new 2013 OVH hardware in Montreal. I am also removing ESXi and going to just FreeBSD (because of how awesome FreeBSD is, it's insanely easy to clone jails across machines when using ZFS, so everything "just worked"!)

    Any questions / comments let me know (I should be getting notifications now!)
     
  2. When is the Graph generating going to be back up ? All the other services are.
     
  3. Offline

    Hidendra

    They will start generating again in (most likely) 30 minutes.

    The story behind that one is long so just a tip: if you need files off of an ESXi vm that has no IP anymore (i.e can't be accessed at all) just give up.
     

  4. Finally :D The graphs generated... You are boss
     
  5. Offline

    Jacob Marshall

    Just wanted to alert you, not that you havent been already, that MCStats.org is currently throwing an error: "An error occurred while connecting to the database (master). This has been logged."

    I do hope, for your sake, that the issue is resolved as soon as possible.
     
  6. Offline

    Hidendra

    Indeed, MySQL crashed for whatever reason, and unfortunately for me, MySQL takes forever to startup (gladly not as long as it takes to shutdown)
     
  7. Offline

    superpeanut911

    Is graph generation down? It does not have the time until next graph counter and it's showing odd numbers for servers who use the plugin, like essentials shows 0 servers are running it. My plugin shows 5 servers are running it. I'm positive that's wrong :p
     
  8. Offline

    Hidendra

    Hello,

    MCStats / Plugin Metrics R6 is now available. This version is highly recommended as it includes new features and fixes. No method or return signatures have changed in this release and is fully compatible with all versions before this.

    Changelog
    • Enhanced support for graphs similar to what Minecraft's Snooper sniffs out. This includes: OS name, architecture, and version; available cpu cores; and if the server is in online mode
    • runTaskTimerAsynchronously is used in place of the deprecated scheduleAsyncRepeatingTask
    • Suppress error messages in the server console unless debug is enabled inside of Metrics' config.yml
    Additionally, porting MCStats / Plugin Metrics to other platforms should be easier. Places where server software specific code is used is clumped together to allow easy modifications without having to change core code. However, there is still a reliance on Bukkit's configuration and task APIs so these are still spread out over the file and still require manual changes.

    Graphs are currently not available for the added fields. These will be added in the future once more plugins have updated.
     
    xGhOsTkiLLeRx likes this.
  9. Offline

    YoFuzzy3

    Hi Hidendra, thanks for the amazing tool.

    I'm trying to make some custom graphs for the first time, but I'm not quite understanding it. So I want to make a custom graph, with 3 different values in it, so I put that in my onEnable. Then there's an Event in another class which has 3 possible outcomes, and for each outcome I want it to add the data in the custom graph. Data type is integer, +1 to the graph every time there's an outcome.

    Can you please point me on the right track?
    Thanks.
     
  10. Offline

    Hidendra

    Do you want the graph to be the change in data? e.g the amount of occurrences in the 30 minute interval between graph generations, or the total [since the server started]? For the former, you'll want to use a class mbaxter made

    Code:
    public class Tracker extends Metrics.Plotter {
     
        private final String name;
        private int value, last;
     
        public Tracker(String name) {
            this.name = name;
            this.value = 0;
            this.last = 0;
        }
     
        @Override
        public String getColumnName() {
            return this.name;
        }
     
        @Override
        public int getValue() {
            this.last = this.value;
            return this.value;
        }
     
        public void increment() {
            this.value++;
        }
     
        @Override
        public void reset() {
            this.value = this.value - this.last;
        }
     
    }
    
    So you would keep 3 Tracker objects (which is a Plotter) and everything the event occurs, you would call the outcome's tracker.increment().

    The class handles resetting the value so that it's only the change in occurrences since the last graph generation. reset() is called the first time after the plugin submits data (every 10 minutes) after a graph generation
     
  11. Offline

    YoFuzzy3

    So I did that successfully, but it just throws a NullPointerException when it tries to increment the Plotter. I feel a bit silly, not quite understanding this. :(

    Main class:
    Code:java
    1. package com.fuzzoland.SkullDrops;
    2.  
    3. import java.io.IOException;
    4. import java.util.logging.Level;
    5. import java.util.logging.Logger;
    6.  
    7. import org.bukkit.Bukkit;
    8. import org.bukkit.event.Listener;
    9. import org.bukkit.plugin.java.JavaPlugin;
    10.  
    11. import com.fuzzoland.SkullDrops.Metrics;
    12.  
    13. public class Main extends JavaPlugin{
    14.  
    15. private final Logger logger = Bukkit.getLogger();
    16.  
    17. @Override
    18. public void onEnable(){
    19. getServer().getPluginManager().registerEvents((Listener) new EventListener(this), this);
    20. logger.log(Level.INFO, "[SkullDrops] Events registered!");
    21.  
    22. try{
    23. Metrics metrics = new Metrics(this);
    24. metrics.start();
    25. logger.log(Level.INFO, "[SkullDrops] Metrics initiated!");
    26. }catch(IOException e){
    27. }
    28. }
    29. }


    EventListener class:
    Code:java
    1. package com.fuzzoland.SkullDrops;
    2.  
    3. import java.util.Random;
    4.  
    5. import org.bukkit.Location;
    6. import org.bukkit.Material;
    7. import org.bukkit.enchantments.Enchantment;
    8. import org.bukkit.enchantments.EnchantmentWrapper;
    9. import org.bukkit.entity.Entity;
    10. import org.bukkit.entity.EntityType;
    11. import org.bukkit.entity.Player;
    12. import org.bukkit.event.EventHandler;
    13. import org.bukkit.event.EventPriority;
    14. import org.bukkit.event.Listener;
    15. import org.bukkit.event.entity.EntityDeathEvent;
    16. import org.bukkit.inventory.ItemStack;
    17.  
    18. public class EventListener implements Listener{
    19.  
    20. @SuppressWarnings("unused")
    21. private Main plugin;
    22. private Tracker tracker;
    23.  
    24. public EventListener(Main plugin){
    25. this.plugin = plugin;
    26. }
    27.  
    28. public EventListener(Tracker tracker){
    29. this.tracker = tracker;
    30. }
    31.  
    32. public Enchantment LOOT_BONUS_MOBS = new EnchantmentWrapper(21);
    33.  
    34. Random random = new Random();
    35.  
    36. @EventHandler(priority = EventPriority.MONITOR)
    37. public void onEntityDeath(EntityDeathEvent event){
    38. if(event.getEntity().getKiller() instanceof Player){
    39. Player player = event.getEntity().getKiller();
    40. Entity entity = event.getEntity();
    41. ItemStack itemInHand = player.getItemInHand();
    42. float chance = random.nextFloat();
    43. if(itemInHand.containsEnchantment(LOOT_BONUS_MOBS)){
    44. int level = (itemInHand.getEnchantmentLevel(LOOT_BONUS_MOBS) / 200);
    45. if(chance < (0.025f + level)){
    46. if(entity.getType() == EntityType.SKELETON){
    47. if(player.hasPermission("SkullDrops.Skeleton")){
    48. dropSkull(entity.getLocation(), 0);
    49. tracker.increment();
    50. }
    51. }else if(entity.getType() == EntityType.ZOMBIE){
    52. if(player.hasPermission("SkullDrops.Zombie")){
    53. dropSkull(entity.getLocation(), 2);
    54. tracker.increment();
    55. }
    56. }else if(entity.getType() == EntityType.CREEPER){
    57. if(player.hasPermission("SkullDrops.Creeper")){
    58. dropSkull(entity.getLocation(), 4);
    59. tracker.increment();
    60. }
    61. }
    62. }
    63. }else{
    64. if(chance < 0.025f){
    65. if(entity.getType() == EntityType.SKELETON){
    66. if(player.hasPermission("SkullDrops.Skeleton")){
    67. dropSkull(entity.getLocation(), 0);
    68. tracker.increment();
    69. }
    70. }else if(entity.getType() == EntityType.ZOMBIE){
    71. if(player.hasPermission("SkullDrops.Zombie")){
    72. dropSkull(entity.getLocation(), 2);
    73. tracker.increment();
    74. }
    75. }else if(entity.getType() == EntityType.CREEPER){
    76. if(player.hasPermission("SkullDrops.Creeper")){
    77. dropSkull(entity.getLocation(), 4);
    78. tracker.increment();
    79. }
    80. }
    81. }
    82. }
    83. }
    84. }
    85.  
    86. private void dropSkull(Location loc, int type){
    87. loc.getWorld().dropItemNaturally(loc, new ItemStack(Material.SKULL_ITEM, 1, (byte) type));
    88. }
    89. }


    Tracker class:
    Code:java
    1. package com.fuzzoland.SkullDrops;
    2.  
    3. public class Tracker extends Metrics.Plotter{
    4.  
    5. private final String name;
    6. private int value, last;
    7.  
    8. public Tracker(String name){
    9. this.name = name;
    10. this.value = 0;
    11. this.last = 0;
    12. }
    13.  
    14. @Override
    15. public String getColumnName(){
    16. return this.name;
    17. }
    18.  
    19. @Override
    20. public int getValue(){
    21. this.last = this.value;
    22. return this.value;
    23. }
    24.  
    25. public void increment(){
    26. this.value++;
    27. }
    28.  
    29. @Override
    30. public void reset(){
    31. this.value = this.value - this.last;
    32. }
    33. }
     
  12. Offline

    Hidendra

    I'm sorry for the delay. It looks like your tracker is always null because you're using the other constructor. and as well, you'd want a tracker per event you have (or whatever you had Plotters for before -- a Tracker is essentially just a Plotter)
     
  13. Offline

    Hidendra

    I am working on a new plugin ranking formula dubbed the "plugin index" which will represent the plugin's current standing alongside the numerical rank. Currently plugins are only ranked by the number of servers in the last 24 hours.

    This formula takes into account player:server ratios as well as total player count (these are averaged over the last 24 hours). The server count is still the most important factor. If all goes well this will come into effect by/at the end of the month.

    So, does anyone have any thoughts on this? This will determine how plugins are forever ranked. If you have any thoughts as to what should be weighted into this (or even how) please feel free to share :)

    Here is a sample set of the top 100 plugins with a test formula which seems to work not too shabbily. The formula is not going to be listed for now (but will be once finalized). The large number is the calculated Plugin Index. Plugins with large amounts of players (and/or a high player:server ratio) are rewarded.

    Code:
    #1 (old: #1) -> 14505: Essentials
    #2 (old: #2) -> 14054: Vault
    #3 (old: #3) -> 13811: ChestShop
    #4 (old: #4) -> 13159: LWC
    #5 (old: #7) -> 13093: NoCheatPlus
    #6 (old: #5) -> 13036: AuthMe
    #7 (old: #9) -> 12413: DisguiseCraft
    #8 (old: #15) -> 12346: AutoMessage
    #9 (old: #8) -> 12271: mcMMO
    #10 (old: #11) -> 12269: OpenInv
    #11 (old: #12) -> 12117: VanishNoPacket
    #12 (old: #6) -> 12061: dynmap
    #13 (old: #42) -> 11934: Spigot
    #14 (old: #22) -> 11709: LogBlock
    #15 (old: #10) -> 11677: Citizens
    #16 (old: #13) -> 11661: AntiCheat
    #17 (old: #24) -> 11600: Multiverse-Core
    #18 (old: #26) -> 11574: SurvivalGames
    #19 (old: #36) -> 11526: TagAPI
    #20 (old: #40) -> 11520: SpamGuard
    #21 (old: #31) -> 11304: PlotMe
    #22 (old: #16) -> 11284: ColorMe
    #23 (old: #28) -> 11257: Orebfuscator
    #24 (old: #32) -> 11204: PlayerHeads
    #25 (old: #30) -> 11194: ShowCaseStandalone
    #26 (old: #88) -> 11136: HideStream
    #27 (old: #14) -> 11119: Lift
    #28 (old: #21) -> 11030: MultiWorld
    #29 (old: #20) -> 10999: Jail
    #30 (old: #17) -> 10951: CraftBookMechanisms
    #31 (old: #43) -> 10905: ProtocolLib
    #32 (old: #35) -> 10902: FoundDiamonds
    #33 (old: #34) -> 10887: MobHealth
    #34 (old: #23) -> 10867: VoxelSniper
    #35 (old: #29) -> 10832: Backup
    #36 (old: #25) -> 10802: SafeCreeper
    #37 (old: #18) -> 10743: CraftBookCircuits
    #38 (old: #33) -> 10648: CraftBookCommon
    #39 (old: #19) -> 10522: CraftBookVehicles
    #40 (old: #41) -> 10343: ServerSigns
    #41 (old: #65) -> 10335: CreativeControl
    #42 (old: #59) -> 10200: PlugMan
    #43 (old: #50) -> 10166: MobBountyReloaded
    #44 (old: #63) -> 10163: SimpleClans
    #45 (old: #38) -> 10152: WeatherMan
    #46 (old: #56) -> 10132: MobCatcher
    #47 (old: #61) -> 10009: Paintball
    #48 (old: #49) -> 9985: MobRider
    #49 (old: #44) -> 9984: Stargate
    #50 (old: #27) -> 9962: PermissionsBukkit
    #51 (old: #57) -> 9927: CommandSigns
    #52 (old: #46) -> 9909: MultiInv
    #53 (old: #60) -> 9857: pvparena
    #54 (old: #94) -> 9849: MotdManager
    #55 (old: #62) -> 9848: PerformanceMonitor
    #56 (old: #58) -> 9845: EpicBoss
    #57 (old: #64) -> 9822: NoWeather
    #58 (old: #53) -> 9788: SimpleFly
    #59 (old: #51) -> 9755: MagicCarpet
    #60 (old: #37) -> 9730: AdminCmd
    #61 (old: #112) -> 9704: AZRank
    #62 (old: #127) -> 9654: WhatIsIt
    #63 (old: #48) -> 9638: SignShop
    #64 (old: #98) -> 9609: PreciousStones
    #65 (old: #52) -> 9582: MagicSpells
    #66 (old: #54) -> 9578: Dynmap-WorldGuard
    #67 (old: #69) -> 9575: SignEdit
    #68 (old: #313) -> 9569: BungeeCord
    #69 (old: #166) -> 9553: boosCooldowns
    #70 (old: #200) -> 9428: BanManager
    #71 (old: #95) -> 9397: Reservations
    #72 (old: #39) -> 9351: WirelessRedstone
    #73 (old: #121) -> 9279: ColoredTablist
    #74 (old: #149) -> 9278: ReportRTS
    #75 (old: #145) -> 9275: floAuction
    #76 (old: #73) -> 9265: uHome
    #77 (old: #101) -> 9264: AntiShare
    #78 (old: #102) -> 9262: CustomServerMessages
    #79 (old: #100) -> 9224: FrameProtect
    #80 (old: #84) -> 9206: CountryLoginMessage
    #81 (old: #82) -> 9174: AntiBot
    #82 (old: #70) -> 9159: iChat
    #83 (old: #116) -> 9131: LinksOnSigns
    #84 (old: #99) -> 9107: tekkitrestrict
    #85 (old: #129) -> 9077: NoItem
    #86 (old: #47) -> 9060: CCTV Camera
    #87 (old: #90) -> 8970: CustomJoinMessage
    #88 (old: #85) -> 8955: JoinMessage
    #89 (old: #67) -> 8944: HerobrineAI
    #90 (old: #55) -> 8920: LoginSecurity
    #91 (old: #103) -> 8918: QuickShop
    #92 (old: #104) -> 8914: FirstJoinPlus
    #93 (old: #68) -> 8849: SWatchdog
    #94 (old: #142) -> 8836: MelooonCensor
    #95 (old: #180) -> 8823: IPLog
    #96 (old: #175) -> 8814: VirtualChest
    #97 (old: #111) -> 8802: ecoCreature
    #98 (old: #130) -> 8790: uSkyBlock
    #99 (old: #81) -> 8782: CraftBukkitPlusPlus
    #100 (old: #77) -> 8743: BattleNight
    
    md_5
     
    Comphenix likes this.
  14. Offline

    md_5

    Thanks Hidendra , keen to see my plugins ranked ~350 to get a boost when they have 11x more players than the #50 plugin (but 10x less servers :p)
     
  15. Offline

    Tux2

    Definitely more accurate, although my plugin, MultiInv slipped down the list with the new ranking system.
     
  16. Offline

    Hidendra

    A plethora of new graphs are now available for all plugins. This for the most part copies some of what Minecraft's own Snooper sends and because this data doesn't appear to be public anymore MCStats has replicated it.
    • Java Version - Version of Java on the server. Uses a donut graph with the Major Java version in the middle with the minor version number on the outer rings
    • Operating System - OS the server is running. Another donut graph with the OS name in the middle with OS version on the outside edge (for Windows, the major release e.g XP, 7, and Server 2008 R2 and for Linux, the kernel version usually)
    • Auth Mode - The auth mode the server is using in a pie graph. Currently Online or Offline
    • System Arch - The architecture of Java that is running, pie graph. amd64 and x86_64 are combined into x86_64.
    • System Cores - The number of cores available to the server, pie graph. This includes hyperthreading and does not differentiate so this does not necessarily represent real cores.
    Please note that as of this post only about 12.8k active servers are running R6 which are what feed data for these graphs. This sample isn't too bad on a whole but accuracy of these graphs may vary wildy depending on the plugin i.e if a plugin has a low amount of servers but those servers run at least 1 plugin on R6, all is well but if none of them run R6 these graphs could be very far off ;)

    P.S Auth Mode is disabled until I can investigate more why it appears to be off by a bit. Should have been fixed earlier but still seems to be a tad "inaccurate"

    P.P.S before anyone asks, Donut graphs CAN be used by any plugin but require you to send specially formatted data. Ping me in a PM or IRC if you want more info before I throw more info somewhere.
     
  17. Offline

    md_5

    As far as I know the system is not live and that was just a demo of the results.
     
  18. Offline

    korikisulda

    Ah... I've only just realised that the licence this is under appears to be incompatible with the GNU GPL, I'll remove it from my plugin immediately.
     
  19. Offline

    YoFuzzy3

    But so many people use that license.. including me! :O
     
  20. Offline

    korikisulda

    Then you can't use Metrics, unfortunately.
     
  21. Offline

    ToastHelmi

    mcstats.org down ?
     
  22. Offline

    YoFuzzy3

    Seems like it.
     
  23. Offline

    Jozeth

    Hidendra is this true?

    View attachment 12192
    "the original BSD license isn't compatible with GPL but I don't use that" - Hidendra

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Oct 29, 2015
  24. Offline

    YoFuzzy3

    Good to hear.
     
    Jozeth likes this.
  25. Offline

    Hidendra

    The entire website has been redesigned (I do not take credit for the layout itself).

    Some things to note:
    • There is now a search bar at the top of almost every page to search for plugins at long last. This works just as you would expect.
    • The Plugin List and Global Statistics (all servers graphs) pages are now on two separate pages
    • There is now a reports section on the website showing monthly reports of various statistics which some of you should enjoy. This is the first time they have been shown.
    • Mobile support is now a lot better. You should be able to navigate the website much more easily on a tablet or phone.
    • Caching has been improved all around. Site performance should be much improved. Amazon CloudFront is powering the static content now as well :)

    If you spot any issues please do let me know.

    P.S: This marks MCStats / Plugin Metrics being around for an entire year! \o/

    Happy New Years!
     
    Dark_Balor, LaxWasHere and YoFuzzy3 like this.
  26. Offline

    korikisulda

    More like

    How so? it's even more restrictive and significantly less compatible...

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Oct 29, 2015
  27. Offline

    Hidendra

    What do you mean? I'm using BSD 2-clause, you only quoted the first line.

    http://www.gnu.org/licenses/license-list.html#FreeBSD
     
  28. Offline

    korikisulda

    I mentioned that line, because it's the line I have a problem with; and I can't see how that could possibly ever be included in a GPL licence header.
     
  29. Offline

    Comphenix

    That's just how copyleft works though.

    You're not technically yielding any rights, you're simply giving explicit permission to reuse and modify the work under a certain set of conditions. For instance, GPL requires you to make your changes available in the form and under the same license, while other open source/free software licenses may be less stringent.

    So, copyleft is "implemented" on top of copyright. It's not a separate legal concept.
     
    Jozeth likes this.
  30. Offline

    korikisulda

    I understand what copyleft is, and I never claimed that there was any separate legal concept for it, so I'm not entirely sure what you mean; my problem is simply being forced to include a line that says (incorrectly) that all rights are reserved, even if I can state that this is not the case below.

    On reflection though, I can now see that it is compatible with the GNU GPL, so I was wrong on that point, although I would still say that it's not right to include the line in question in a GPL header.
     
Thread Status:
Not open for further replies.

Share This Page