├── src └── main │ ├── resources │ ├── plugin.yml │ └── config.yml │ └── java │ └── me │ └── moomoo │ └── worldstats │ ├── Expansions.java │ ├── Main.java │ └── Commands.java ├── .github └── workflows │ └── maven.yml ├── README.md ├── .gitignore └── pom.xml /src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: Worldstats 2 | version: ${project.version} 3 | main: me.moomoo.worldstats.Main 4 | softdepend: [ PlaceholderAPI ] 5 | commands: 6 | worldstats: 7 | usage: / 8 | description: stats 9 | aliases: [ worldstats, info, stats, icanhazstats ] -------------------------------------------------------------------------------- /src/main/resources/config.yml: -------------------------------------------------------------------------------- 1 | # supports placeholderapi 2 | message: 3 | - '&7-----------------------------------------------------' 4 | - '&6%totalPlayers% &3player(s) have spawned at least once in the world. ' 5 | - '&3The World is &6%years% years, %months% months and %days% days old &3and has a file 6 | size of &6%fileSize% GB' 7 | - '&7-----------------------------------------------------' 8 | # %fileSize_spoof% for spoofed filesize 9 | filesizeupdate_in_ticks: 72000 10 | spoofsize: 0 # Specify how many gb should be added on top of the filesize, will be %fileSize_spoof%. Useful for if you shrink your world (deleting useless chunks) 11 | Worlds: 12 | - "./world/region" 13 | - "./world_nether/DIM-1/region" 14 | - "./world_the_end/DIM1/region" -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: Build and upload jar 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Set up JDK 1.8 17 | uses: actions/setup-java@v1 18 | with: 19 | java-version: 1.8 20 | - name: Build with Maven 21 | run: mvn -B package --file pom.xml 22 | - name: Upload a Build Artifact 23 | uses: actions/upload-artifact@v2.1.4 24 | with: 25 | # Artifact name 26 | name: WorldStats 27 | # A file, directory or wildcard pattern that describes what to upload 28 | path: target/worldstats-*.jar 29 | -------------------------------------------------------------------------------- /src/main/java/me/moomoo/worldstats/Expansions.java: -------------------------------------------------------------------------------- 1 | package me.moomoo.worldstats; 2 | 3 | import me.clip.placeholderapi.expansion.PlaceholderExpansion; 4 | import org.bukkit.entity.Player; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import java.text.DecimalFormat; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | public class Expansions extends PlaceholderExpansion { 11 | private final Main plugin; 12 | 13 | public Expansions(Main plugin) { 14 | this.plugin = plugin; 15 | } 16 | 17 | @Override 18 | public boolean persist() { 19 | return true; 20 | } 21 | 22 | @Override 23 | public boolean canRegister() { 24 | return true; 25 | } 26 | 27 | @Override 28 | public @NotNull String getAuthor() { 29 | return "moo"; 30 | } 31 | 32 | @Override 33 | public @NotNull String getIdentifier() { 34 | return "worldstats"; 35 | } 36 | 37 | @Override 38 | public @NotNull String getVersion() { 39 | return plugin.getDescription().getVersion(); 40 | } 41 | 42 | @Override 43 | public String onPlaceholderRequest(Player player, @NotNull String identifier) { 44 | if (identifier.equals("filesize")) { 45 | return String.valueOf(new DecimalFormat("#.##").format(plugin.size)); 46 | } 47 | if (identifier.equals("filesizespoof")) { 48 | return String.valueOf(new DecimalFormat("#.##").format(plugin.size + plugin.getConfig().getLong("spoofsize"))); 49 | } 50 | if (identifier.equals("players")) { 51 | return String.valueOf(plugin.offlinePlayers); 52 | } 53 | if (identifier.equals("days")) { 54 | return String.valueOf(TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis() - plugin.getConfig().getLong("time"))); 55 | } 56 | return null; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Discord Mine](https://img.shields.io/discord/807380182729228298?label=chat&logo=discord&logoColor=white)](https://discord.gg/JtKJF3Jgwm) 2 | 3 | # NO LONGER SUPPORTED, SUPERSEDED BY https://github.com/xGinko/BetterWorldStats 4 | 5 | ### A better rewrite of the old Worldstats plugin that is more lightweight and doesn't cause lag. 6 | 7 | [![bstats](https://bstats.org/signatures/bukkit/WorldStatsRewritten.svg)](https://bstats.org/plugin/bukkit/WorldStatsRewritten/10319) 8 | 9 | # World time 10 | 11 | For the plugin to calculate world time please convert the date of your map start to epoch milliseconds and set the time 12 | setting in config.yml to the epoch. 13 | 14 | # PlaceholderAPI 15 | 16 | * %worldstats_filesize% - Get the cached file size. 17 | * %worldstats_filesizespoof% - Get the spoofed file size, useful for when you shrink your world. 18 | * %worldstats_players% - Get the cached unique players amount. 19 | * %worldstats_days% - Get how old the map is in DAYS 20 | 21 | Additionally, all placeholders are supported in the /stats message. 22 | 23 | # Commands 24 | 25 | * /worldstats, /info, /stats, /icanhazstats reload - Reload the config 26 | * /worldstats, /info, /stats, /icanhazstats - Display world stats message 27 | 28 | # Support 29 | 30 | Join my support discord if you have any issues. 31 |
32 | Discord: https://discord.gg/HfuyuqhXdb 33 | 34 | # Config 35 | 36 |
37 | config.yml 38 | 39 | ```yml 40 | # supports placeholderapi 41 | message: 42 | - '&7-----------------------------------------------------' 43 | - '&6%totalPlayers% &3player(s) have spawned at least once in the world. ' 44 | - '&3The World is &6%years% years, %months% months and %days% days old &3and has a file 45 | size of &6%fileSize% GB' 46 | - '&7-----------------------------------------------------' 47 | filesizeupdate_in_ticks: 72000 48 | Worlds: 49 | - "./world/region" 50 | - "./world_nether/DIM-1/region" 51 | - "./world_the_end/DIM1/region" 52 | time: 0 53 | ``` 54 | 55 |
56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific stuff 2 | .idea/ 3 | 4 | *.iml 5 | *.ipr 6 | *.iws 7 | 8 | # IntelliJ 9 | out/ 10 | 11 | # Compiled class file 12 | *.class 13 | 14 | # Log file 15 | *.log 16 | 17 | # BlueJ files 18 | *.ctxt 19 | 20 | # Package Files # 21 | *.jar 22 | *.war 23 | *.nar 24 | *.ear 25 | *.zip 26 | *.tar.gz 27 | *.rar 28 | 29 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 30 | hs_err_pid* 31 | 32 | *~ 33 | 34 | # temporary files which can be created if a process still has a handle open of a deleted file 35 | .fuse_hidden* 36 | 37 | # KDE directory preferences 38 | .directory 39 | 40 | # Linux trash folder which might appear on any partition or disk 41 | .Trash-* 42 | 43 | # .nfs files are created when an open file is removed but is still being accessed 44 | .nfs* 45 | 46 | # General 47 | .DS_Store 48 | .AppleDouble 49 | .LSOverride 50 | 51 | # Icon must end with two \r 52 | Icon 53 | 54 | # Thumbnails 55 | ._* 56 | 57 | # Files that might appear in the root of a volume 58 | .DocumentRevisions-V100 59 | .fseventsd 60 | .Spotlight-V100 61 | .TemporaryItems 62 | .Trashes 63 | .VolumeIcon.icns 64 | .com.apple.timemachine.donotpresent 65 | 66 | # Directories potentially created on remote AFP share 67 | .AppleDB 68 | .AppleDesktop 69 | Network Trash Folder 70 | Temporary Items 71 | .apdisk 72 | 73 | # Windows thumbnail cache files 74 | Thumbs.db 75 | Thumbs.db:encryptable 76 | ehthumbs.db 77 | ehthumbs_vista.db 78 | 79 | # Dump file 80 | *.stackdump 81 | 82 | # Folder config file 83 | [Dd]esktop.ini 84 | 85 | # Recycle Bin used on file shares 86 | $RECYCLE.BIN/ 87 | 88 | # Windows Installer files 89 | *.cab 90 | *.msi 91 | *.msix 92 | *.msm 93 | *.msp 94 | 95 | # Windows shortcuts 96 | *.lnk 97 | 98 | target/ 99 | 100 | pom.xml.tag 101 | pom.xml.releaseBackup 102 | pom.xml.versionsBackup 103 | pom.xml.next 104 | 105 | release.properties 106 | dependency-reduced-pom.xml 107 | buildNumber.properties 108 | .mvn/timing.properties 109 | .mvn/wrapper/maven-wrapper.jar 110 | .flattened-pom.xml 111 | 112 | # Common working directory 113 | run/ 114 | -------------------------------------------------------------------------------- /src/main/java/me/moomoo/worldstats/Main.java: -------------------------------------------------------------------------------- 1 | // Plugin originally by HandsChrift however his plugin is the worst plugin I've ever seen so I remade it. https://read-my-man.ga/F1dlq6OUeA.png 2 | package me.moomoo.worldstats; 3 | 4 | import org.bstats.bukkit.Metrics; 5 | import org.bstats.charts.SingleLineChart; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.plugin.java.JavaPlugin; 8 | 9 | import java.io.File; 10 | import java.util.Objects; 11 | import java.util.concurrent.TimeUnit; 12 | 13 | public final class Main extends JavaPlugin { 14 | public double size; 15 | public int offlinePlayers; 16 | 17 | @Override 18 | public void onEnable() { 19 | Metrics metrics = new Metrics(this, 10319); 20 | getLogger().info("WorldStats enabled"); 21 | saveDefaultConfig(); 22 | if (getConfig().get("time") == null) { 23 | getConfig().set("time", System.currentTimeMillis()); 24 | saveConfig(); 25 | } 26 | getCommand("worldstats").setExecutor(new Commands(this)); 27 | // Check every 1 hour. 28 | Bukkit.getScheduler().runTaskTimer(this, () -> new Thread(() -> { 29 | size = list() / 1048576.0D / 1000.0D; 30 | offlinePlayers = Bukkit.getOfflinePlayers().length; 31 | getLogger().info("[WorldStats] Finished checking file size: " + size); 32 | }).start(), 0L, getConfig().getLong("filesizeupdate_in_ticks")); // 72000 33 | Bukkit.getScheduler().runTaskLater(this, () -> { 34 | metrics.addCustomChart(new SingleLineChart("total_world_size", () -> (int) size)); 35 | metrics.addCustomChart(new SingleLineChart("total_unique_players", () -> offlinePlayers)); 36 | metrics.addCustomChart(new SingleLineChart("total_map_age", () -> Math.toIntExact(TimeUnit.MILLISECONDS.toDays(System.currentTimeMillis() - getConfig().getLong("time"))))); 37 | }, 12000L); 38 | 39 | if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { 40 | new Expansions(this).register(); 41 | } 42 | } 43 | 44 | @Override 45 | public void onDisable() { 46 | getLogger().info("WorldStats disabled"); 47 | } 48 | 49 | private long list() { 50 | long l = 0L; 51 | for (String s : getConfig().getStringList("Worlds")) { 52 | for (File file : Objects.requireNonNull(new File(s).listFiles())) { 53 | if (file.isFile()) { 54 | l += file.length(); 55 | } 56 | } 57 | } 58 | return l; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/me/moomoo/worldstats/Commands.java: -------------------------------------------------------------------------------- 1 | package me.moomoo.worldstats; 2 | 3 | import me.clip.placeholderapi.PlaceholderAPI; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.ChatColor; 6 | import org.bukkit.OfflinePlayer; 7 | import org.bukkit.command.Command; 8 | import org.bukkit.command.CommandExecutor; 9 | import org.bukkit.command.CommandSender; 10 | import org.bukkit.entity.Player; 11 | import org.bukkit.event.Listener; 12 | 13 | import java.text.DecimalFormat; 14 | import java.util.Calendar; 15 | 16 | public class Commands implements CommandExecutor, Listener { 17 | private final Main plugin; 18 | 19 | public Commands(Main plugin) { 20 | this.plugin = plugin; 21 | } 22 | 23 | @Override 24 | public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { 25 | if (args.length < 1 || !args[0].equals("reload")) { 26 | Calendar c = Calendar.getInstance(); 27 | c.setTimeInMillis(System.currentTimeMillis() - plugin.getConfig().getLong("time")); 28 | int mYear = c.get(Calendar.YEAR) - 1970; 29 | int mMonth = c.get(Calendar.MONTH); 30 | int mDay = c.get(Calendar.DAY_OF_MONTH) - 1; 31 | if (mYear < 0) { 32 | mYear = 0; 33 | mMonth = 0; 34 | mDay = 0; 35 | } 36 | for (String s : plugin.getConfig().getStringList("message")) { 37 | if (sender instanceof Player && Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { 38 | sender.sendMessage(PlaceholderAPI.setPlaceholders((OfflinePlayer) sender, ChatColor.translateAlternateColorCodes('&', s) 39 | .replace("%years%", String.valueOf(mYear)) 40 | .replace("%months%", String.valueOf(mMonth)) 41 | .replace("%days%", String.valueOf(mDay)) 42 | .replace("%fileSize%", new DecimalFormat("#.##").format(plugin.size)) 43 | .replace("%fileSize_spoof%", new DecimalFormat("#.##").format(plugin.size + plugin.getConfig().getLong("spoofsize"))) 44 | .replace("%totalPlayers%", String.valueOf(plugin.offlinePlayers)))); 45 | } else { 46 | sender.sendMessage(ChatColor.translateAlternateColorCodes('&', s) 47 | .replace("%years%", String.valueOf(mYear)) 48 | .replace("%months%", String.valueOf(mMonth)) 49 | .replace("%days%", String.valueOf(mDay)) 50 | .replace("%fileSize%", new DecimalFormat("#.##").format(plugin.size)) 51 | .replace("%fileSize_spoof%", new DecimalFormat("#.##").format(plugin.size + plugin.getConfig().getLong("spoofsize"))) 52 | .replace("%totalPlayers%", String.valueOf(plugin.offlinePlayers))); 53 | } 54 | } 55 | } else { 56 | plugin.reloadConfig(); 57 | sender.sendMessage(ChatColor.GOLD + "WorldStats config reloaded."); 58 | } 59 | return true; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | me.moomoo 8 | worldstats 9 | 1.8 10 | jar 11 | 12 | Worldstats 13 | 14 | 15 | 1.8 16 | UTF-8 17 | 18 | 19 | 20 | 21 | 22 | org.apache.maven.plugins 23 | maven-compiler-plugin 24 | 3.8.1 25 | 26 | ${java.version} 27 | ${java.version} 28 | 29 | 30 | 31 | org.apache.maven.plugins 32 | maven-shade-plugin 33 | 3.2.4 34 | 35 | 36 | package 37 | 38 | shade 39 | 40 | 41 | 42 | 43 | org.bstats 44 | me.moomoo.worldstats.bstats 45 | 46 | 47 | false 48 | true 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | src/main/resources 57 | true 58 | 59 | 60 | 61 | 62 | 63 | 64 | papermc-repo 65 | https://papermc.io/repo/repository/maven-public/ 66 | 67 | 68 | sonatype 69 | https://oss.sonatype.org/content/groups/public/ 70 | 71 | 72 | nms-repo 73 | https://repo.codemc.io/repository/nms/ 74 | 75 | 76 | placeholderapi 77 | https://repo.extendedclip.com/content/repositories/placeholderapi/ 78 | 79 | 80 | 81 | 82 | 83 | com.destroystokyo.paper 84 | paper-api 85 | 1.12.2-R0.1-SNAPSHOT 86 | provided 87 | 88 | 89 | org.spigotmc 90 | spigot 91 | 1.12.2-R0.1-SNAPSHOT 92 | provided 93 | 94 | 95 | me.clip 96 | placeholderapi 97 | 2.10.9 98 | provided 99 | 100 | 101 | org.bstats 102 | bstats-bukkit 103 | 2.2.1 104 | 105 | 106 | 107 | --------------------------------------------------------------------------------