├── .gitignore ├── README.md ├── pom.xml └── src ├── mcstats └── Metrics.java ├── me └── neatmonster │ └── spacebukkit │ ├── PanelListener.java │ ├── SpaceBukkit.java │ ├── actions │ ├── PlayerActions.java │ ├── ServerActions.java │ └── SystemActions.java │ ├── events │ └── RequestEvent.java │ ├── players │ ├── PlayerLogger.java │ └── SBListener.java │ ├── plugins │ ├── PluginsManager.java │ └── PluginsRequester.java │ ├── system │ └── PerformanceMonitor.java │ └── utilities │ ├── ANSI.java │ ├── PropertiesFile.java │ └── Utilities.java └── plugin.yml /.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | /.classpath 3 | /.project 4 | /.settings 5 | 6 | # Netbeans 7 | /nbproject 8 | 9 | # Maven 10 | /build.xml 11 | /target 12 | 13 | # Mac files 14 | /.DS_Store 15 | 16 | # Intellij 17 | *.iml 18 | *.ipr 19 | *.iws 20 | .idea/ 21 | 22 | # Vim 23 | *.swp 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SpaceBukkit - the awesome way! 2 | A powerful yet simple web panel for administering your Bukkit Minecraft servers with ease. 3 | 4 | ## Description 5 | SpaceBukkit is a project developed over the last 6 months aiming to bring an advanced and powerful web administration framework to Bukkit. What makes it unique is, on one hand, it's graphical user interface, and on the other hand some nifty features enlisted just below. 6 | 7 | ## Features 8 | - General 9 | * Attractive Interface 10 | * Non lethal doses of awesomeness 11 | * Multiple Servers 12 | * Multi-user access with role setting 13 | * Theme Support for extra commiseration 14 | * Per server - per user role settings 15 | * Console access 16 | - Dashboard 17 | * Pretty and quick statistics about your server 18 | * Activity feed - who did what, and when 19 | * Chat - talk with your players 20 | - Players 21 | * Player management - kick, kill, feed, heal, ban, op and more! 22 | * Whitelist 23 | * Bans 24 | - Plugins 25 | * Plugin management 26 | * Config editor 27 | * Installing and Deinstalling 28 | * Updating and disabling 29 | * Bukget integration 30 | - Worlds 31 | * World management 32 | * Multiworld support 33 | * Backups 34 | * Chunkster 35 | * MapAutoTrim 36 | - Servers 37 | * Craftbukkit one-click installing and updating 38 | * Server Properties saving 39 | * Schedules 40 | 41 | ## Credits 42 | * [Antariano](https://github.com/Antariano/) - SpaceCP. 43 | * [JamyDev](https://github.com/JamyDev/) - SpaceCP. 44 | * [NeatMonster](https://github.com/NeatMonster/) - SpaceModule, SpaceRTK and SpaceBukkit. 45 | * [Drdanick](https://github.com/Drdanick/) - RemoteToolkit, SpaceModule, SpaceRTK and Spacebukkit. 46 | 47 | ## Links 48 | - Website: [http://spacebukkit.xereo.net/](http://spacebukkit.xereo.net/). 49 | - Forums: [http://forums.xereo.net/](http://forums.xereo.net/). 50 | - Wiki: [http://spacebukkit.xereo.net/wiki](http://spacebukkit.xereo.net/wiki). 51 | 52 | ## License 53 | SpaceBukkit is free software: you can redistribute it and/or modify it under 54 | the terms of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) 55 | license as published by the Creative Common organization, either version 3.0 of 56 | the license, or (at your option) any later version. 57 | 58 | SpaceBukkit is distributed in the hope that it will be useful, but WITHOUT ANY 59 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 60 | PARTICULAR PURPOSE. See the Attribution-NonCommercial-ShareAlike Unported (CC 61 | BY-NC-SA) license for more details. 62 | 63 | You should have received a copy of the Attribution-NonCommercial-ShareAlike 64 | Unported (CC BY-NC-SA) license along with this program. If not, see 65 | [http://creativecommons.org/licenses/by-nc-sa/3.0/](http://creativecommons.org/licenses/by-nc-sa/3.0/). -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | me.neatmonster 7 | spacebukkit 8 | 1.2-SNAPSHOT 9 | SpaceBukkit 10 | http://spacebukkit.xereo.net/ 11 | A powerful yet simple web panel for administering your Minecraft servers with ease. 12 | 13 | 14 | UTF-8 15 | 16 | 17 | 18 | 19 | 20 | Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) 21 | http://creativecommons.org/licenses/by-nc-sa/3.0/ 22 | repo 23 | 24 | 25 | 26 | 27 | 28 | scm:git:git@github.com:SpaceDev/${project.name}.git 29 | scm:git:git://github.com/SpaceDev/${project.name}.git 30 | https://github.com/SpaceDev/${project.name} 31 | 32 | 33 | 34 | 35 | jenkins 36 | http://dev.drdanick.com/jenkins/ 37 | 38 | 39 | 40 | 41 | 42 | 43 | sb-snapshots 44 | Snapshots 45 | http://dev.drdanick.com/repo/content/repositories/sb-snapshots 46 | 47 | 48 | 49 | thirdparty 50 | 3rd party 51 | http://dev.drdanick.com/repo/content/repositories/thirdparty 52 | 53 | 54 | 55 | bukkit 56 | Bukkit 57 | http://repo.bukkit.org/content/groups/public/ 58 | 59 | 60 | 61 | 62 | 63 | 64 | com.drdanick.McRKit 65 | McRKitLauncher 66 | R10A12 67 | compile 68 | 69 | 70 | 71 | me.neatmonster 72 | spacemodule 73 | 1.2-SNAPSHOT 74 | compile 75 | 76 | 77 | 78 | me.neatmonster 79 | spacertk 80 | 1.2-SNAPSHOT 81 | compile 82 | 83 | 84 | 85 | org.bukkit 86 | bukkit 87 | RELEASE 88 | compile 89 | 90 | 91 | 92 | com.googlecode.json-simple 93 | json-simple 94 | 1.1 95 | compile 96 | 97 | 98 | 99 | javasysmon 100 | javasysmon 101 | 0.3.3 102 | compile 103 | 104 | 105 | 106 | net.milkbowl.vault 107 | Vault 108 | 1.2.17 109 | compile 110 | 111 | 112 | 113 | 114 | clean package install 115 | ${basedir}/src/ 116 | 117 | 118 | . 119 | true 120 | ${basedir}/src/ 121 | 122 | plugin.yml 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | org.apache.maven.plugins 131 | maven-compiler-plugin 132 | 2.3.2 133 | 134 | 1.6 135 | 1.6 136 | 137 | 138 | 139 | org.apache.maven.plugins 140 | maven-jar-plugin 141 | 2.3.1 142 | 143 | 144 | false 145 | false 146 | 147 | false 148 | false 149 | 150 | 151 | 152 | 153 | 154 | org.apache.maven.plugins 155 | maven-shade-plugin 156 | 1.6 157 | 158 | 159 | package 160 | 161 | shade 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | *:* 173 | 174 | META-INF/*.SF 175 | META-INF/*.DSA 176 | 177 | 178 | 179 | 180 | me.neatmonster:spacertk 181 | 182 | ** 183 | 184 | 185 | 186 | 187 | 188 | me.neatmonster:spacemodule 189 | 190 | com/thoughtworks/xstream/** 191 | org/xmlpull/** 192 | 193 | 194 | 195 | 196 | true 197 | 198 | 199 | 200 | 201 | 202 | -------------------------------------------------------------------------------- /src/mcstats/Metrics.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 Tyler Blair. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are 5 | * permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list of 8 | * conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 | * of conditions and the following disclaimer in the documentation and/or other materials 12 | * provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED 15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 16 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR 17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 21 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 22 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | * 24 | * The views and conclusions contained in the software and documentation are those of the 25 | * authors and contributors and should not be interpreted as representing official policies, 26 | * either expressed or implied, of anybody else. 27 | */ 28 | 29 | package mcstats; 30 | 31 | import org.bukkit.Bukkit; 32 | import org.bukkit.configuration.file.YamlConfiguration; 33 | import org.bukkit.configuration.InvalidConfigurationException; 34 | import org.bukkit.plugin.Plugin; 35 | import org.bukkit.plugin.PluginDescriptionFile; 36 | 37 | import java.io.BufferedReader; 38 | import java.io.File; 39 | import java.io.IOException; 40 | import java.io.InputStreamReader; 41 | import java.io.OutputStreamWriter; 42 | import java.io.UnsupportedEncodingException; 43 | import java.net.Proxy; 44 | import java.net.URL; 45 | import java.net.URLConnection; 46 | import java.net.URLEncoder; 47 | import java.util.Collections; 48 | import java.util.HashSet; 49 | import java.util.Iterator; 50 | import java.util.LinkedHashSet; 51 | import java.util.Set; 52 | import java.util.UUID; 53 | import java.util.logging.Level; 54 | 55 | /** 56 | *

57 | * The metrics class obtains data about a plugin and submits statistics about it to the metrics backend. 58 | *

59 | *

60 | * Public methods provided by this class: 61 | *

62 | * 63 | * Graph createGraph(String name);
64 | * void addCustomData(Metrics.Plotter plotter);
65 | * void start();
66 | *
67 | */ 68 | public class Metrics { 69 | 70 | /** 71 | * The current revision number 72 | */ 73 | private final static int REVISION = 5; 74 | 75 | /** 76 | * The base url of the metrics domain 77 | */ 78 | private static final String BASE_URL = "http://mcstats.org"; 79 | 80 | /** 81 | * The url used to report a server's status 82 | */ 83 | private static final String REPORT_URL = "/report/%s"; 84 | 85 | /** 86 | * The file where guid and opt out is stored in 87 | */ 88 | private static final String CONFIG_FILE = "plugins/PluginMetrics/config.yml"; 89 | 90 | /** 91 | * The separator to use for custom data. This MUST NOT change unless you are hosting your own 92 | * version of metrics and want to change it. 93 | */ 94 | private static final String CUSTOM_DATA_SEPARATOR = "~~"; 95 | 96 | /** 97 | * Interval of time to ping (in minutes) 98 | */ 99 | private static final int PING_INTERVAL = 10; 100 | 101 | /** 102 | * The plugin this metrics submits for 103 | */ 104 | private final Plugin plugin; 105 | 106 | /** 107 | * All of the custom graphs to submit to metrics 108 | */ 109 | private final Set graphs = Collections.synchronizedSet(new HashSet()); 110 | 111 | /** 112 | * The default graph, used for addCustomData when you don't want a specific graph 113 | */ 114 | private final Graph defaultGraph = new Graph("Default"); 115 | 116 | /** 117 | * The plugin configuration file 118 | */ 119 | private final YamlConfiguration configuration; 120 | 121 | /** 122 | * The plugin configuration file 123 | */ 124 | private final File configurationFile; 125 | 126 | /** 127 | * Unique server id 128 | */ 129 | private final String guid; 130 | 131 | /** 132 | * Lock for synchronization 133 | */ 134 | private final Object optOutLock = new Object(); 135 | 136 | /** 137 | * Id of the scheduled task 138 | */ 139 | private volatile int taskId = -1; 140 | 141 | public Metrics(final Plugin plugin) throws IOException { 142 | if (plugin == null) { 143 | throw new IllegalArgumentException("Plugin cannot be null"); 144 | } 145 | 146 | this.plugin = plugin; 147 | 148 | // load the config 149 | configurationFile = new File(CONFIG_FILE); 150 | configuration = YamlConfiguration.loadConfiguration(configurationFile); 151 | 152 | // add some defaults 153 | configuration.addDefault("opt-out", false); 154 | configuration.addDefault("guid", UUID.randomUUID().toString()); 155 | 156 | // Do we need to create the file? 157 | if (configuration.get("guid", null) == null) { 158 | configuration.options().header("http://mcstats.org").copyDefaults(true); 159 | configuration.save(configurationFile); 160 | } 161 | 162 | // Load the guid then 163 | guid = configuration.getString("guid"); 164 | } 165 | 166 | /** 167 | * Construct and create a Graph that can be used to separate specific plotters to their own graphs 168 | * on the metrics website. Plotters can be added to the graph object returned. 169 | * 170 | * @param name 171 | * @return Graph object created. Will never return NULL under normal circumstances unless bad parameters are given 172 | */ 173 | public Graph createGraph(final String name) { 174 | if (name == null) { 175 | throw new IllegalArgumentException("Graph name cannot be null"); 176 | } 177 | 178 | // Construct the graph object 179 | final Graph graph = new Graph(name); 180 | 181 | // Now we can add our graph 182 | graphs.add(graph); 183 | 184 | // and return back 185 | return graph; 186 | } 187 | 188 | /** 189 | * Adds a custom data plotter to the default graph 190 | * 191 | * @param plotter 192 | */ 193 | public void addCustomData(final Plotter plotter) { 194 | if (plotter == null) { 195 | throw new IllegalArgumentException("Plotter cannot be null"); 196 | } 197 | 198 | // Add the plotter to the graph o/ 199 | defaultGraph.addPlotter(plotter); 200 | 201 | // Ensure the default graph is included in the submitted graphs 202 | graphs.add(defaultGraph); 203 | } 204 | 205 | /** 206 | * Start measuring statistics. This will immediately create an async repeating task as the plugin and send 207 | * the initial data to the metrics backend, and then after that it will post in increments of 208 | * PING_INTERVAL * 1200 ticks. 209 | * 210 | * @return True if statistics measuring is running, otherwise false. 211 | */ 212 | public boolean start() { 213 | synchronized (optOutLock) { 214 | // Did we opt out? 215 | if (isOptOut()) { 216 | return false; 217 | } 218 | 219 | // Is metrics already running? 220 | if (taskId >= 0) { 221 | return true; 222 | } 223 | 224 | // Begin hitting the server with glorious data 225 | taskId = plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() { 226 | 227 | private boolean firstPost = true; 228 | 229 | public void run() { 230 | try { 231 | // This has to be synchronized or it can collide with the disable method. 232 | synchronized (optOutLock) { 233 | // Disable Task, if it is running and the server owner decided to opt-out 234 | if (isOptOut() && taskId > 0) { 235 | plugin.getServer().getScheduler().cancelTask(taskId); 236 | taskId = -1; 237 | } 238 | } 239 | 240 | // We use the inverse of firstPost because if it is the first time we are posting, 241 | // it is not a interval ping, so it evaluates to FALSE 242 | // Each time thereafter it will evaluate to TRUE, i.e PING! 243 | postPlugin(!firstPost); 244 | 245 | // After the first post we set firstPost to false 246 | // Each post thereafter will be a ping 247 | firstPost = false; 248 | } catch (IOException e) { 249 | Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage()); 250 | } 251 | } 252 | }, 0, PING_INTERVAL * 1200); 253 | 254 | return true; 255 | } 256 | } 257 | 258 | /** 259 | * Has the server owner denied plugin metrics? 260 | * 261 | * @return 262 | */ 263 | public boolean isOptOut() { 264 | synchronized(optOutLock) { 265 | try { 266 | // Reload the metrics file 267 | configuration.load(CONFIG_FILE); 268 | } catch (IOException ex) { 269 | Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); 270 | return true; 271 | } catch (InvalidConfigurationException ex) { 272 | Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage()); 273 | return true; 274 | } 275 | return configuration.getBoolean("opt-out", false); 276 | } 277 | } 278 | 279 | /** 280 | * Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task. 281 | * 282 | * @throws IOException 283 | */ 284 | public void enable() throws IOException { 285 | // This has to be synchronized or it can collide with the check in the task. 286 | synchronized (optOutLock) { 287 | // Check if the server owner has already set opt-out, if not, set it. 288 | if (isOptOut()) { 289 | configuration.set("opt-out", false); 290 | configuration.save(configurationFile); 291 | } 292 | 293 | // Enable Task, if it is not running 294 | if (taskId < 0) { 295 | start(); 296 | } 297 | } 298 | } 299 | 300 | /** 301 | * Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task. 302 | * 303 | * @throws IOException 304 | */ 305 | public void disable() throws IOException { 306 | // This has to be synchronized or it can collide with the check in the task. 307 | synchronized (optOutLock) { 308 | // Check if the server owner has already set opt-out, if not, set it. 309 | if (!isOptOut()) { 310 | configuration.set("opt-out", true); 311 | configuration.save(configurationFile); 312 | } 313 | 314 | // Disable Task, if it is running 315 | if (taskId > 0) { 316 | this.plugin.getServer().getScheduler().cancelTask(taskId); 317 | taskId = -1; 318 | } 319 | } 320 | } 321 | 322 | /** 323 | * Generic method that posts a plugin to the metrics website 324 | */ 325 | private void postPlugin(final boolean isPing) throws IOException { 326 | // The plugin's description file containg all of the plugin data such as name, version, author, etc 327 | final PluginDescriptionFile description = plugin.getDescription(); 328 | 329 | // Construct the post data 330 | final StringBuilder data = new StringBuilder(); 331 | data.append(encode("guid")).append('=').append(encode(guid)); 332 | encodeDataPair(data, "version", description.getVersion()); 333 | encodeDataPair(data, "server", Bukkit.getVersion()); 334 | encodeDataPair(data, "players", Integer.toString(Bukkit.getServer().getOnlinePlayers().length)); 335 | encodeDataPair(data, "revision", String.valueOf(REVISION)); 336 | 337 | // If we're pinging, append it 338 | if (isPing) { 339 | encodeDataPair(data, "ping", "true"); 340 | } 341 | 342 | // Acquire a lock on the graphs, which lets us make the assumption we also lock everything 343 | // inside of the graph (e.g plotters) 344 | synchronized (graphs) { 345 | final Iterator iter = graphs.iterator(); 346 | 347 | while (iter.hasNext()) { 348 | final Graph graph = iter.next(); 349 | 350 | for (Plotter plotter : graph.getPlotters()) { 351 | // The key name to send to the metrics server 352 | // The format is C-GRAPHNAME-PLOTTERNAME where separator - is defined at the top 353 | // Legacy (R4) submitters use the format Custom%s, or CustomPLOTTERNAME 354 | final String key = String.format("C%s%s%s%s", CUSTOM_DATA_SEPARATOR, graph.getName(), CUSTOM_DATA_SEPARATOR, plotter.getColumnName()); 355 | 356 | // The value to send, which for the foreseeable future is just the string 357 | // value of plotter.getValue() 358 | final String value = Integer.toString(plotter.getValue()); 359 | 360 | // Add it to the http post data :) 361 | encodeDataPair(data, key, value); 362 | } 363 | } 364 | } 365 | 366 | // Create the url 367 | URL url = new URL(BASE_URL + String.format(REPORT_URL, encode(plugin.getDescription().getName()))); 368 | 369 | // Connect to the website 370 | URLConnection connection; 371 | 372 | // Mineshafter creates a socks proxy, so we can safely bypass it 373 | // It does not reroute POST requests so we need to go around it 374 | if (isMineshafterPresent()) { 375 | connection = url.openConnection(Proxy.NO_PROXY); 376 | } else { 377 | connection = url.openConnection(); 378 | } 379 | 380 | connection.setDoOutput(true); 381 | 382 | // Write the data 383 | final OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream()); 384 | writer.write(data.toString()); 385 | writer.flush(); 386 | 387 | // Now read the response 388 | final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); 389 | final String response = reader.readLine(); 390 | 391 | // close resources 392 | writer.close(); 393 | reader.close(); 394 | 395 | if (response == null || response.startsWith("ERR")) { 396 | throw new IOException(response); //Throw the exception 397 | } else { 398 | // Is this the first update this hour? 399 | if (response.contains("OK This is your first update this hour")) { 400 | synchronized (graphs) { 401 | final Iterator iter = graphs.iterator(); 402 | 403 | while (iter.hasNext()) { 404 | final Graph graph = iter.next(); 405 | 406 | for (Plotter plotter : graph.getPlotters()) { 407 | plotter.reset(); 408 | } 409 | } 410 | } 411 | } 412 | } 413 | } 414 | 415 | /** 416 | * Check if mineshafter is present. If it is, we need to bypass it to send POST requests 417 | * 418 | * @return 419 | */ 420 | private boolean isMineshafterPresent() { 421 | try { 422 | Class.forName("mineshafter.MineServer"); 423 | return true; 424 | } catch (Exception e) { 425 | return false; 426 | } 427 | } 428 | 429 | /** 430 | *

Encode a key/value data pair to be used in a HTTP post request. This INCLUDES a & so the first 431 | * key/value pair MUST be included manually, e.g:

432 | * 433 | * StringBuffer data = new StringBuffer(); 434 | * data.append(encode("guid")).append('=').append(encode(guid)); 435 | * encodeDataPair(data, "version", description.getVersion()); 436 | * 437 | * 438 | * @param buffer 439 | * @param key 440 | * @param value 441 | * @return 442 | */ 443 | private static void encodeDataPair(final StringBuilder buffer, final String key, final String value) throws UnsupportedEncodingException { 444 | buffer.append('&').append(encode(key)).append('=').append(encode(value)); 445 | } 446 | 447 | /** 448 | * Encode text as UTF-8 449 | * 450 | * @param text 451 | * @return 452 | */ 453 | private static String encode(final String text) throws UnsupportedEncodingException { 454 | return URLEncoder.encode(text, "UTF-8"); 455 | } 456 | 457 | /** 458 | * Represents a custom graph on the website 459 | */ 460 | public static class Graph { 461 | 462 | /** 463 | * The graph's name, alphanumeric and spaces only :) 464 | * If it does not comply to the above when submitted, it is rejected 465 | */ 466 | private final String name; 467 | 468 | /** 469 | * The set of plotters that are contained within this graph 470 | */ 471 | private final Set plotters = new LinkedHashSet(); 472 | 473 | private Graph(final String name) { 474 | this.name = name; 475 | } 476 | 477 | /** 478 | * Gets the graph's name 479 | * 480 | * @return 481 | */ 482 | public String getName() { 483 | return name; 484 | } 485 | 486 | /** 487 | * Add a plotter to the graph, which will be used to plot entries 488 | * 489 | * @param plotter 490 | */ 491 | public void addPlotter(final Plotter plotter) { 492 | plotters.add(plotter); 493 | } 494 | 495 | /** 496 | * Remove a plotter from the graph 497 | * 498 | * @param plotter 499 | */ 500 | public void removePlotter(final Plotter plotter) { 501 | plotters.remove(plotter); 502 | } 503 | 504 | /** 505 | * Gets an unmodifiable set of the plotter objects in the graph 506 | * 507 | * @return 508 | */ 509 | public Set getPlotters() { 510 | return Collections.unmodifiableSet(plotters); 511 | } 512 | 513 | @Override 514 | public int hashCode() { 515 | return name.hashCode(); 516 | } 517 | 518 | @Override 519 | public boolean equals(final Object object) { 520 | if (!(object instanceof Graph)) { 521 | return false; 522 | } 523 | 524 | final Graph graph = (Graph) object; 525 | return graph.name.equals(name); 526 | } 527 | 528 | } 529 | 530 | /** 531 | * Interface used to collect custom data for a plugin 532 | */ 533 | public static abstract class Plotter { 534 | 535 | /** 536 | * The plot's name 537 | */ 538 | private final String name; 539 | 540 | /** 541 | * Construct a plotter with the default plot name 542 | */ 543 | public Plotter() { 544 | this("Default"); 545 | } 546 | 547 | /** 548 | * Construct a plotter with a specific plot name 549 | * 550 | * @param name 551 | */ 552 | public Plotter(final String name) { 553 | this.name = name; 554 | } 555 | 556 | /** 557 | * Get the current value for the plotted point 558 | * 559 | * @return 560 | */ 561 | public abstract int getValue(); 562 | 563 | /** 564 | * Get the column name for the plotted point 565 | * 566 | * @return the plotted point's column name 567 | */ 568 | public String getColumnName() { 569 | return name; 570 | } 571 | 572 | /** 573 | * Called after the website graphs have been updated 574 | */ 575 | public void reset() { 576 | } 577 | 578 | @Override 579 | public int hashCode() { 580 | return getColumnName().hashCode() + getValue(); 581 | } 582 | 583 | @Override 584 | public boolean equals(final Object object) { 585 | if (!(object instanceof Plotter)) { 586 | return false; 587 | } 588 | 589 | final Plotter plotter = (Plotter) object; 590 | return plotter.name.equals(name) && plotter.getValue() == getValue(); 591 | } 592 | 593 | } 594 | 595 | } -------------------------------------------------------------------------------- /src/me/neatmonster/spacebukkit/PanelListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of SpaceBukkit (http://spacebukkit.xereo.net/). 3 | * 4 | * SpaceBukkit is free software: you can redistribute it and/or modify it under the terms of the 5 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license as published by the Creative Common organization, 6 | * either version 3.0 of the license, or (at your option) any later version. 7 | * 8 | * SpaceBukkit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied 9 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Attribution-NonCommercial-ShareAlike 10 | * Unported (CC BY-NC-SA) license for more details. 11 | * 12 | * You should have received a copy of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license along with 13 | * this program. If not, see . 14 | */ 15 | package me.neatmonster.spacebukkit; 16 | 17 | import java.io.BufferedReader; 18 | import java.io.IOException; 19 | import java.io.InputStreamReader; 20 | import java.io.PrintWriter; 21 | import java.net.*; 22 | import java.util.List; 23 | 24 | import me.neatmonster.spacebukkit.events.RequestEvent; 25 | import me.neatmonster.spacebukkit.utilities.Utilities; 26 | import me.neatmonster.spacemodule.api.InvalidArgumentsException; 27 | import me.neatmonster.spacemodule.api.UnhandledActionException; 28 | 29 | import org.bukkit.Bukkit; 30 | import org.json.simple.JSONValue; 31 | import java.lang.reflect.Field; 32 | 33 | /** 34 | * Listens and accepts requests from the panel 35 | */ 36 | public class PanelListener extends Thread { 37 | 38 | private boolean running = true; 39 | 40 | /** 41 | * Interprets a raw command from the panel 42 | * @param string input from panel 43 | * @return result of the action 44 | * @throws InvalidArgumentsException Thrown when the wrong arguments are used by the panel 45 | * @throws UnhandledActionException Thrown when there is no handler for the action 46 | */ 47 | @SuppressWarnings("unchecked") 48 | private static Object interpret(final String string) throws InvalidArgumentsException, UnhandledActionException { 49 | final int indexOfMethod = string.indexOf("?method="); 50 | final int indexOfArguments = string.indexOf("&args="); 51 | final int indexOfKey = string.indexOf("&key="); 52 | final String method = string.substring(indexOfMethod + 8, indexOfArguments); 53 | final String argumentsString = string.substring(indexOfArguments + 6, indexOfKey); 54 | final List arguments = (List) JSONValue.parse(argumentsString); 55 | try { 56 | if (SpaceBukkit.getInstance().actionsManager.contains(method)) 57 | return SpaceBukkit.getInstance().actionsManager.execute(method, arguments.toArray()); 58 | else { 59 | final RequestEvent event = new RequestEvent(method, arguments.toArray()); 60 | Bukkit.getPluginManager().callEvent(event); 61 | return JSONValue.toJSONString(event.getResult()); 62 | } 63 | } catch (final InvalidArgumentsException e) { 64 | e.printStackTrace(); 65 | } catch (final UnhandledActionException e) { 66 | e.printStackTrace(); 67 | } 68 | return null; 69 | } 70 | /** 71 | * Interprets a raw command from the panel (multiple) 72 | * @param string input from panel 73 | * @return result of the action 74 | * @throws InvalidArgumentsException Thrown when the wrong arguments are used by the panel 75 | * @throws UnhandledActionException Thrown when there is no handler for the action 76 | */ 77 | @SuppressWarnings("unchecked") 78 | private static Object interpretm(final String string) throws InvalidArgumentsException, UnhandledActionException { 79 | final int indexOfMethod = string.indexOf("?method="); 80 | final int indexOfArguments = string.indexOf("&args="); 81 | final int indexOfKey = string.indexOf("&key="); 82 | final String methodString = string.substring(indexOfMethod + 8, indexOfArguments); 83 | final String argumentsString = string.substring(indexOfArguments + 6, indexOfKey); 84 | final List methods = (List) JSONValue.parse(methodString); 85 | final List arguments = (List) JSONValue.parse(argumentsString); 86 | final List result = (List) JSONValue.parse("[]"); 87 | for (int i = 0; i < methods.size(); i++) { 88 | String argsString = arguments.toArray()[i].toString(); 89 | List args = (List) JSONValue.parse(argsString); 90 | try { 91 | if (SpaceBukkit.getInstance().actionsManager.contains(methods.toArray()[i].toString())) 92 | result.add(SpaceBukkit.getInstance().actionsManager.execute(methods.toArray()[i].toString(), args.toArray())); 93 | else { 94 | final RequestEvent event = new RequestEvent(methods.toArray()[i].toString(), args.toArray()); 95 | Bukkit.getPluginManager().callEvent(event); 96 | result.add(JSONValue.toJSONString(event.getResult())); 97 | } 98 | } catch (final InvalidArgumentsException e) { 99 | result.add(null); 100 | e.printStackTrace(); 101 | } catch (final UnhandledActionException e) { 102 | result.add(null); 103 | e.printStackTrace(); 104 | } 105 | 106 | } 107 | return result; 108 | } 109 | 110 | private static final int SO_BACKLOG = 128; 111 | private static final int SO_TIMEOUT = 30000; //30 seconds 112 | private final int mode; 113 | private ServerSocket serverSocket = null; 114 | private Socket socket; 115 | 116 | /** 117 | * Creates a new panel listener, listening for connections from a panel 118 | */ 119 | public PanelListener() { 120 | mode = 0; 121 | start(); 122 | } 123 | 124 | /** 125 | * Creates a new panel listener, listening for input from the socket 126 | * @param socket Socket to listen on 127 | */ 128 | public PanelListener(final Socket socket) { 129 | mode = 1; 130 | this.socket = socket; 131 | start(); 132 | } 133 | 134 | /** 135 | * Gets the mode the panel listener is in 136 | * 0 = Listening for opening connection from a panel 137 | * 1 = Listening for input from a socket 138 | * @return mode panel is in 139 | */ 140 | public int getMode() { 141 | return mode; 142 | } 143 | 144 | @Override 145 | public void run() { 146 | if (mode == 0) { 147 | 148 | try { 149 | serverSocket = new ServerSocket(SpaceBukkit.getInstance().port, SO_BACKLOG, SpaceBukkit.getInstance().bindAddress); 150 | serverSocket.setSoTimeout(SO_TIMEOUT); 151 | } catch(IOException e) { 152 | e.printStackTrace(); 153 | return; 154 | } 155 | 156 | while (running && !serverSocket.isClosed()) { 157 | try { 158 | final Socket clientSocket = serverSocket.accept(); 159 | new PanelListener(clientSocket); 160 | } catch (SocketTimeoutException e) { 161 | // Do nothing. 162 | } catch (IOException e) { 163 | if (!e.getMessage().toLowerCase().contains("socket closed")) 164 | e.printStackTrace(); 165 | } 166 | } 167 | } else { 168 | try { 169 | final BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream())); 170 | String string = input.readLine(); 171 | if (string == null) { 172 | return; 173 | } 174 | string = URLDecoder.decode(string, "UTF-8"); 175 | string = string.substring(5, string.length() - 9); 176 | final PrintWriter output = new PrintWriter(socket.getOutputStream()); 177 | if (string.startsWith("call") && string.contains("?method=") && string.contains("&args=")) { 178 | final String method = string.substring(12, string.indexOf("&args=")); 179 | if (string.contains("&key=" + Utilities.crypt(method + SpaceBukkit.getInstance().salt))) { 180 | final Object result = interpret(string); 181 | if (result != null) 182 | output.println(Utilities.addHeader(JSONValue.toJSONString(result))); 183 | else 184 | output.println(Utilities.addHeader(null)); 185 | } else 186 | output.println(Utilities.addHeader("Incorrect Salt supplied. Access denied!")); 187 | } 188 | else if (string.startsWith("multiple") && string.contains("?method=") && string.contains("&args=")) { 189 | final String method = string.substring(16, string.indexOf("&args=")); 190 | if (string.contains("&key=" + Utilities.crypt(method + SpaceBukkit.getInstance().salt))) { 191 | final Object result = interpretm(string); 192 | if (result != null) 193 | output.println(Utilities.addHeader(JSONValue.toJSONString(result))); 194 | else 195 | output.println(Utilities.addHeader(null)); 196 | } else 197 | output.println(Utilities.addHeader("Incorrect Salt supplied. Access denied!")); 198 | } else if (string.startsWith("ping")) 199 | output.println(Utilities.addHeader("Pong!")); 200 | else 201 | output.println(Utilities.addHeader(null)); 202 | output.flush(); 203 | input.close(); 204 | output.close(); 205 | } catch (final Exception e) { 206 | e.printStackTrace(); 207 | } 208 | } 209 | } 210 | 211 | /** 212 | * Gracefully stops the listener 213 | * @throws IOException If the socket cannot be closed 214 | */ 215 | public void stopServer() throws IOException { 216 | running = false; 217 | if (serverSocket != null) { 218 | serverSocket.close(); 219 | } 220 | } 221 | public static String dump(Object object) { 222 | Field[] fields = object.getClass().getDeclaredFields(); 223 | StringBuilder sb = new StringBuilder(); 224 | sb.append(object.getClass().getSimpleName()).append('{'); 225 | 226 | boolean firstRound = true; 227 | 228 | for (Field field : fields) { 229 | if (!firstRound) { 230 | sb.append(", "); 231 | } 232 | firstRound = false; 233 | field.setAccessible(true); 234 | try { 235 | final Object fieldObj = field.get(object); 236 | final String value; 237 | if (null == fieldObj) { 238 | value = "null"; 239 | } else { 240 | value = fieldObj.toString(); 241 | } 242 | sb.append(field.getName()).append('=').append('\'') 243 | .append(value).append('\''); 244 | } catch (IllegalAccessException ignore) { 245 | //this should never happen 246 | } 247 | 248 | } 249 | 250 | sb.append('}'); 251 | return sb.toString(); 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /src/me/neatmonster/spacebukkit/SpaceBukkit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of SpaceBukkit (http://spacebukkit.xereo.net/). 3 | * 4 | * SpaceBukkit is free software: you can redistribute it and/or modify it under the terms of the 5 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license as published by the Creative Common organization, 6 | * either version 3.0 of the license, or (at your option) any later version. 7 | * 8 | * SpaceBukkit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied 9 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Attribution-NonCommercial-ShareAlike 10 | * Unported (CC BY-NC-SA) license for more details. 11 | * 12 | * You should have received a copy of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license along with 13 | * this program. If not, see . 14 | */ 15 | package me.neatmonster.spacebukkit; 16 | 17 | import java.io.IOException; 18 | import java.net.InetAddress; 19 | import java.net.UnknownHostException; 20 | import java.util.Timer; 21 | import java.util.UUID; 22 | import java.io.File; 23 | 24 | import com.drdanick.rtoolkit.system.EventDispatchWorker; 25 | import com.drdanick.rtoolkit.system.SingleWorkerPool; 26 | import mcstats.Metrics; 27 | import me.neatmonster.spacebukkit.actions.PlayerActions; 28 | import me.neatmonster.spacebukkit.actions.ServerActions; 29 | import me.neatmonster.spacebukkit.actions.SystemActions; 30 | import me.neatmonster.spacebukkit.players.SBListener; 31 | import me.neatmonster.spacebukkit.plugins.PluginsManager; 32 | import me.neatmonster.spacebukkit.system.PerformanceMonitor; 33 | import me.neatmonster.spacemodule.SpaceModule; 34 | import me.neatmonster.spacemodule.api.ActionsManager; 35 | import me.neatmonster.spacertk.SpaceRTK; 36 | 37 | import org.bukkit.Bukkit; 38 | import org.bukkit.configuration.file.YamlConfiguration; 39 | import org.bukkit.plugin.java.JavaPlugin; 40 | 41 | import com.drdanick.rtoolkit.system.EventDispatcher; 42 | import com.drdanick.rtoolkit.event.ToolkitEventHandler; 43 | /** 44 | * Main class of the Plugin 45 | */ 46 | public class SpaceBukkit extends JavaPlugin { 47 | public static SpaceRTK spaceRTK = null; 48 | private static SpaceBukkit spacebukkit; 49 | 50 | public static SpaceBukkit getInstance() { 51 | return spacebukkit; 52 | } 53 | 54 | public int port; 55 | public int rPort; 56 | public int pingPort; 57 | public String salt; 58 | public InetAddress bindAddress; 59 | 60 | public int maxJoins; 61 | public int maxMessages; 62 | public int maxQuits; 63 | 64 | public PluginsManager pluginsManager; 65 | public ActionsManager actionsManager; 66 | public PanelListener panelListener; 67 | public PerformanceMonitor performanceMonitor; 68 | 69 | private YamlConfiguration config; 70 | 71 | private final Timer timer = new Timer("SpaceBukkit Timer Thread", false); 72 | 73 | private EventDispatcher edt; 74 | private ToolkitEventHandler eventHandler; 75 | private EventDispatchWorker toolkitEventWorker; 76 | 77 | @Override 78 | public void onDisable() { 79 | performanceMonitor.infanticide(); 80 | timer.cancel(); 81 | try { 82 | if (panelListener != null) 83 | panelListener.stopServer(); 84 | } catch (final Exception e) { 85 | getLogger().severe(e.getMessage()); 86 | } 87 | edt.setRunning(false); 88 | synchronized (edt) { 89 | edt.notifyAll(); 90 | } 91 | toolkitEventWorker.setEnabled(false); 92 | } 93 | 94 | @Override 95 | public void onEnable() { 96 | spacebukkit = this; 97 | 98 | config = YamlConfiguration.loadConfiguration(new File("SpaceModule", "configuration.yml")); 99 | config.addDefault("General.salt", ""); 100 | config.addDefault("General.worldContainer", Bukkit.getWorldContainer().getPath()); 101 | config.addDefault("General.bindIp", Bukkit.getServer().getIp()); 102 | config.addDefault("SpaceBukkit.port", 2011); 103 | config.addDefault("SpaceRTK.port", 2012); 104 | config.addDefault("SpaceBukkit.maxJoins", 199); 105 | config.addDefault("SpaceBukkit.maxMessages", 199); 106 | config.addDefault("SpaceBukkit.maxQuits", 199); 107 | config.options().copyDefaults(true); 108 | salt = config.getString("General.salt", ""); 109 | if (salt.equals("")) { 110 | salt = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase(); 111 | config.set("General.salt", salt); 112 | } 113 | config.set("General.worldContainer", Bukkit.getWorldContainer().getPath()); 114 | port = config.getInt("SpaceBukkit.port", 2011); 115 | rPort = config.getInt("SpaceRTK.port", 2012); 116 | 117 | 118 | String bindAddressString = config.getString("General.bindIp", "0.0.0.0"); 119 | if(bindAddressString.trim().isEmpty()) 120 | bindAddressString = "0.0.0.0"; 121 | try { 122 | bindAddress = InetAddress.getByName(bindAddressString); 123 | } catch(UnknownHostException e) { 124 | try { 125 | bindAddress = InetAddress.getLocalHost(); 126 | } catch(UnknownHostException e2) {} 127 | System.err.println("Warning: Could not assign bind address " + bindAddressString + ":"); 128 | System.err.println(e.getMessage()); 129 | System.err.println("Will bind to loopback address: " + bindAddress.getHostAddress() + "..."); 130 | } 131 | 132 | pingPort = config.getInt("SpaceBukkit.pingPort", 2014); 133 | maxJoins = config.getInt("SpaceBukkit.maxJoins", 199); 134 | maxMessages = config.getInt("SpaceBukkit.maxMessages", 199); 135 | maxQuits = config.getInt("SpaceBukkit.maxQuits", 199); 136 | try { 137 | config.save(SpaceModule.CONFIGURATION); 138 | } catch (IOException e) { 139 | e.printStackTrace(); 140 | } 141 | 142 | if(edt == null) 143 | edt = new EventDispatcher(new SingleWorkerPool()); 144 | 145 | if(toolkitEventWorker == null) { 146 | toolkitEventWorker = new EventDispatchWorker(); 147 | toolkitEventWorker.setEnabled(true); 148 | edt.registerEventHandler(eventHandler, toolkitEventWorker); 149 | } 150 | 151 | if(!edt.isRunning()) { 152 | synchronized(edt) { 153 | edt.notifyAll(); 154 | } 155 | edt.setRunning(true); 156 | Thread edtThread = new Thread(edt, "SpaceModule EventDispatcher"); 157 | edtThread.setDaemon(true); 158 | edtThread.start(); 159 | } 160 | 161 | if(!toolkitEventWorker.isRunning()) { 162 | toolkitEventWorker.setEnabled(true); 163 | } 164 | 165 | setupMetrics(); 166 | 167 | new SBListener(this); 168 | pluginsManager = new PluginsManager(); 169 | actionsManager = new ActionsManager(); 170 | actionsManager.register(PlayerActions.class); 171 | actionsManager.register(ServerActions.class); 172 | actionsManager.register(SystemActions.class); 173 | panelListener = new PanelListener(); 174 | performanceMonitor = new PerformanceMonitor(); 175 | timer.scheduleAtFixedRate(performanceMonitor, 0L, 1000L); 176 | } 177 | 178 | /** 179 | * Sets up Metrics 180 | */ 181 | private void setupMetrics() { 182 | try { 183 | Metrics metrics = new Metrics(this); 184 | 185 | metrics.start(); 186 | } catch (IOException e) { 187 | e.printStackTrace(); 188 | } 189 | } 190 | 191 | /** 192 | * Gets the RTK event dispatcher 193 | * @return event dispatcher 194 | */ 195 | public EventDispatcher getEdt() { 196 | return edt; 197 | } 198 | 199 | /** 200 | * Gets the RTK event handler 201 | * @return event handler 202 | */ 203 | public ToolkitEventHandler getEventHandler() { 204 | return eventHandler; 205 | } 206 | 207 | /** 208 | * A terrible hack to illegitimately create a ToolkitEventHandler 209 | */ 210 | private class EventHandler extends ToolkitEventHandler { 211 | } 212 | 213 | } 214 | -------------------------------------------------------------------------------- /src/me/neatmonster/spacebukkit/actions/PlayerActions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of SpaceBukkit (http://spacebukkit.xereo.net/). 3 | * 4 | * SpaceBukkit is free software: you can redistribute it and/or modify it under the terms of the 5 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license as published by the Creative 6 | * Common organization, either version 3.0 of the license, or (at your option) any later version. 7 | * 8 | * SpaceBukkit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 9 | * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license for more details. 11 | * 12 | * You should have received a copy of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) 13 | * license along with this program. If not, see . 14 | */ 15 | package me.neatmonster.spacebukkit.actions; 16 | 17 | import java.io.UnsupportedEncodingException; 18 | import java.net.URLDecoder; 19 | import java.util.ArrayList; 20 | import java.util.HashMap; 21 | import java.util.LinkedHashMap; 22 | import java.util.List; 23 | import java.util.Map; 24 | 25 | import me.neatmonster.spacebukkit.players.PlayerLogger; 26 | import me.neatmonster.spacebukkit.utilities.Utilities; 27 | import me.neatmonster.spacemodule.api.Action; 28 | 29 | import me.neatmonster.spacemodule.api.ActionHandler; 30 | import org.bukkit.Bukkit; 31 | import org.bukkit.GameMode; 32 | import org.bukkit.Location; 33 | import org.bukkit.OfflinePlayer; 34 | import org.bukkit.World; 35 | import org.bukkit.entity.Egg; 36 | import org.bukkit.entity.Player; 37 | import org.bukkit.entity.Snowball; 38 | import org.bukkit.event.entity.EntityDamageEvent; 39 | import org.bukkit.inventory.ItemStack; 40 | import org.bukkit.inventory.PlayerInventory; 41 | 42 | /** 43 | * Actions handler for any Player-related actions 44 | */ 45 | public class PlayerActions implements ActionHandler { 46 | 47 | /** 48 | * Throws an egg 49 | * @param playerName Player to throw the egg 50 | * @return If successful 51 | */ 52 | @Action( 53 | aliases = {"throwEgg", "egg"}, 54 | schedulable = false) 55 | public boolean throwEgg(final String playerName) { 56 | final Player player = Bukkit.getPlayer(playerName); 57 | if (player != null) { 58 | player.launchProjectile(Egg.class); 59 | return true; 60 | } 61 | return false; 62 | } 63 | 64 | /** 65 | * Adds a player to the whitelist 66 | * @param playerName Player to add to whitelist 67 | * @return If successful 68 | */ 69 | @Action( 70 | aliases = {"addToWhitelist", "whitelistAdd"}) 71 | public boolean addToWhitelist(final String playerName) { 72 | Bukkit.getOfflinePlayer(playerName).setWhitelisted(true); 73 | PlayerLogger.setCase(playerName); 74 | return true; 75 | } 76 | 77 | /** 78 | * Bans a player 79 | * @param playerName Player to ban 80 | * @return If successful 81 | */ 82 | @Action( 83 | aliases = {"ban", "banPlayer", "bannedAdd"}) 84 | public boolean ban(final String playerName) { 85 | Bukkit.getOfflinePlayer(playerName).setBanned(true); 86 | final Player onlinePlayer = Bukkit.getPlayer(playerName); 87 | if (onlinePlayer != null) 88 | onlinePlayer.kickPlayer("You have been banned!"); 89 | PlayerLogger.setCase(playerName); 90 | return true; 91 | } 92 | 93 | /** 94 | * Sends a message to a player 95 | * @param playerName Player to send the message too 96 | * @param message Message to send to the player 97 | * @return If successful 98 | */ 99 | @Action( 100 | aliases = {"chat", "talk"}, 101 | schedulable = false) 102 | public Object chat(final String playerName, final String message) { 103 | final Player player = Bukkit.getPlayer(playerName); 104 | if (player != null) { 105 | player.chat(Utilities.color(message)); 106 | return true; 107 | } 108 | return false; 109 | } 110 | 111 | /** 112 | * Clears a players inventory slot 113 | * @param playerName Player to clear slot 114 | * @param slotNumber number of slot to clear 115 | * @return If successful 116 | */ 117 | @Action( 118 | aliases = {"clearInventorySlot", "clearPlayerInventorySlot"}, 119 | schedulable = false) 120 | public boolean clearInventorySlot(final String playerName, final int slotNumber) { 121 | final Player player = Bukkit.getPlayer(playerName); 122 | if (player != null) { 123 | final PlayerInventory inventory = player.getInventory(); 124 | final int size = inventory.getSize(); 125 | if (slotNumber == 103) 126 | inventory.clear(size + 3); 127 | else if (slotNumber == 102) 128 | inventory.clear(size + 2); 129 | else if (slotNumber == 101) 130 | inventory.clear(size + 1); 131 | else if (slotNumber == 100) 132 | inventory.clear(size + 0); 133 | else 134 | inventory.clear(slotNumber); 135 | return true; 136 | } 137 | return false; 138 | } 139 | 140 | /** 141 | * DeOP's a player 142 | * @param playerName Player to DeOP 143 | * @return If successful 144 | */ 145 | @Action( 146 | aliases = {"deop", "deopPlayer"}) 147 | public boolean deop(final String playerName) { 148 | Bukkit.getOfflinePlayer(playerName).setOp(false); 149 | final Player onlinePlayer = Bukkit.getPlayer(playerName); 150 | if (onlinePlayer != null) 151 | onlinePlayer.sendMessage("You are no longer OP!"); 152 | return true; 153 | } 154 | 155 | /** 156 | * Gets all the banned players 157 | * @return All banned players 158 | */ 159 | @Action( 160 | aliases = {"getBanned", "banned"}) 161 | public List getBanned() { 162 | final List playersNames = new ArrayList(); 163 | for (final OfflinePlayer player : Bukkit.getBannedPlayers()) 164 | playersNames.add(PlayerLogger.getCase(player.getName())); 165 | return playersNames; 166 | } 167 | 168 | /** 169 | * Gets all the banned ips 170 | * @return All banned ips 171 | */ 172 | @Action( 173 | aliases = {"getBannedIps", "bannedIps"}) 174 | public List getBannedIps() { 175 | final List iplist = new ArrayList(); 176 | for (final String ip : Bukkit.getIPBans()) 177 | iplist.add(ip); 178 | return iplist; 179 | } 180 | 181 | /** 182 | * Gets a players inventory 183 | * @param playerName Inventory to get 184 | * @return Players inventory 185 | */ 186 | @Action( 187 | aliases = {"getInventory", "inventory"}, 188 | schedulable = false) 189 | public LinkedHashMap> getInventory(final String playerName) { 190 | final LinkedHashMap> playerInventory = new LinkedHashMap>(); 191 | final Player player = Bukkit.getPlayer(playerName); 192 | if (player == null) { 193 | return playerInventory; 194 | } 195 | PlayerInventory inv = player.getInventory(); 196 | for (int i = 0; i < player.getInventory().getSize(); i++) { 197 | playerInventory.put(i, inv.getItem(i) == null ? new HashMap() : Utilities.serializeItem(inv.getItem(i))); 198 | } 199 | playerInventory.put(100, inv.getBoots() == null ? new HashMap() : Utilities.serializeItem(inv.getBoots())); 200 | playerInventory.put(101, inv.getLeggings() == null ? new HashMap() : Utilities.serializeItem(inv.getLeggings())); 201 | playerInventory.put(102, inv.getChestplate() == null ? new HashMap() : Utilities.serializeItem(inv.getChestplate())); 202 | playerInventory.put(103, inv.getHelmet() == null ? new HashMap() : Utilities.serializeItem(inv.getHelmet())); 203 | return playerInventory; 204 | } 205 | 206 | /** 207 | * Gets the item of a player at the specified slot 208 | * @param playerName Player of item to get 209 | * @param slot Slot to get the item at 210 | * @return Item at the slot 211 | */ 212 | @Action( 213 | aliases = {"getItem", "getItemAt"}, 214 | schedulable = false) 215 | public Map getItem(final String playerName, final int slot) { 216 | final Player player = Bukkit.getPlayer(playerName); 217 | if (player == null) 218 | return new HashMap(); 219 | final ItemStack itemStack = player.getInventory().getItem(slot); 220 | if (itemStack == null) 221 | return new HashMap(); 222 | return Utilities.serializeItem(itemStack); 223 | } 224 | 225 | /** 226 | * Gets all the OPed players 227 | * @return All OPed players 228 | */ 229 | @Action( 230 | aliases = {"getOps", "ops"}) 231 | public List getOPs() { 232 | final List playerNames = new ArrayList(); 233 | for (final OfflinePlayer player : Bukkit.getOperators()) 234 | playerNames.add(PlayerLogger.getCase(player.getName())); 235 | return playerNames; 236 | } 237 | 238 | /** 239 | * Gets basic information about a player 240 | * @param playerName Player to get information about 241 | * @return Basic information about a player 242 | */ 243 | @Action( 244 | aliases = {"getPlayerInformations", "playerInformations"}, 245 | schedulable = false) 246 | public LinkedHashMap getPlayerInformations(final String playerName) { 247 | final LinkedHashMap playerInformations = new LinkedHashMap(); 248 | final Player player = Bukkit.getPlayer(playerName); 249 | if (player != null) { 250 | playerInformations.put("Name", player.getName()); 251 | playerInformations.put("DisplayName", Utilities.stripColor(player.getDisplayName())); 252 | playerInformations.put("EntityId", player.getEntityId()); 253 | playerInformations.put("World", player.getLocation().getWorld().getName()); 254 | playerInformations.put("IP", player.getAddress().getAddress().getHostAddress()); 255 | playerInformations.put("X", player.getLocation().getX()); 256 | playerInformations.put("Y", player.getLocation().getY()); 257 | playerInformations.put("Z", player.getLocation().getZ()); 258 | playerInformations.put("Exhaustion", player.getExhaustion()); 259 | playerInformations.put("Experience", player.getExp()); 260 | playerInformations.put("FoodLevel", player.getFoodLevel()); 261 | playerInformations.put("GameMode", player.getGameMode().toString()); 262 | playerInformations.put("Health", player.getHealth()); 263 | playerInformations.put("Level", player.getLevel()); 264 | playerInformations.put("RemainingAir", player.getRemainingAir()); 265 | playerInformations.put("TotalExperience", player.getTotalExperience()); 266 | return playerInformations; 267 | } 268 | return new LinkedHashMap(); 269 | } 270 | 271 | /** 272 | * Gets all online players 273 | * @return All online players 274 | */ 275 | @Action( 276 | aliases = {"getPlayers", "getOnlinePlayers", "players"}) 277 | public List getPlayers() { 278 | final List playersNames = new ArrayList(); 279 | for (final Player player : Bukkit.getOnlinePlayers()) 280 | playersNames.add(player.getName()); 281 | return playersNames; 282 | } 283 | 284 | /** 285 | * Gets all whitelisted players 286 | * @return All whitelisted players 287 | */ 288 | @Action( 289 | aliases = {"getWhitelisted", "getWhitelist", "whitelist"}) 290 | public List getWhitelisted() { 291 | Bukkit.reloadWhitelist(); 292 | final List playerNames = new ArrayList(); 293 | for (final OfflinePlayer player : Bukkit.getWhitelistedPlayers()) 294 | playerNames.add(PlayerLogger.getCase(player.getName())); 295 | return playerNames; 296 | } 297 | 298 | /** 299 | * Gives a player an item 300 | * @param playerName Player to give an item too 301 | * @param aID Id of the item to give 302 | * @param aAmount Amount of the item to give 303 | * @return If successful 304 | */ 305 | @Action( 306 | aliases = {"giveItem", "give"}, 307 | schedulable = false) 308 | public boolean giveItem(final String playerName, final int aID, final int aAmount, final byte data) { 309 | final Player player = Bukkit.getPlayer(playerName); 310 | if (player != null) { 311 | final ItemStack stack = new ItemStack(aID, aAmount, (short) 0, data); 312 | final PlayerInventory inventory = player.getInventory(); 313 | final int maxStackSize = stack.getMaxStackSize(); 314 | if (stack.getAmount() <= maxStackSize) 315 | inventory.addItem(stack); 316 | final int amount = stack.getAmount(); 317 | final int quotient = amount / maxStackSize; 318 | final int remainder = amount % maxStackSize; 319 | for (int i = 0; i < quotient; i++) 320 | inventory.addItem(new ItemStack(aID, maxStackSize, (short) 0, data)); 321 | if (remainder > 0) 322 | inventory.addItem(new ItemStack(aID, remainder, (short) 0, data)); 323 | return true; 324 | } 325 | return false; 326 | } 327 | 328 | /** 329 | * Drops and item at a players location 330 | * @param playerName Player whos location is to use 331 | * @param id Id of item to drop 332 | * @param amount Amount of item to drop 333 | * @return If successful 334 | */ 335 | @Action( 336 | aliases = {"giveItemDrop", "giveDrop"}, 337 | schedulable = false) 338 | public boolean giveItemDrop(final String playerName, final int id, final int amount, final byte data) { 339 | final Player player = Bukkit.getPlayer(playerName); 340 | if (player != null) { 341 | final ItemStack stack = new ItemStack(id, amount, (short) 0, data); 342 | player.getWorld().dropItemNaturally(player.getLocation(), stack); 343 | return true; 344 | } 345 | return false; 346 | } 347 | 348 | /** 349 | * Checks if a player has a permission 350 | * @param playerName Player to check 351 | * @param permission Permission to check 352 | * @return If the player has the permission 353 | */ 354 | @Action( 355 | aliases = {"hasPermission", "permission"}, 356 | schedulable = false) 357 | public boolean hasPermission(final String playerName, final String permission) { 358 | final Player player = Bukkit.getPlayer(playerName); 359 | if (player != null && !permission.equals("")) 360 | return player.hasPermission(permission); 361 | return false; 362 | } 363 | 364 | /** 365 | * Kicks a player 366 | * @param playerName Player to kick 367 | * @param message Reason to kick the player 368 | * @return If successful 369 | */ 370 | @Action( 371 | aliases = {"kick", "kickPlayer"}, 372 | schedulable = false) 373 | public boolean kick(final String playerName, final String message) { 374 | final Player player = Bukkit.getPlayer(playerName); 375 | if (player != null) { 376 | player.kickPlayer(message); 377 | return true; 378 | } 379 | return false; 380 | } 381 | 382 | /** 383 | * Kills a player 384 | * @param playerName Player to kill 385 | * @return If successful 386 | */ 387 | @Action( 388 | aliases = {"kill", "killPlayer"}, 389 | schedulable = false) 390 | public boolean killPlayer(final String playerName) { 391 | final Player player = Bukkit.getPlayer(playerName); 392 | if (player != null) { 393 | final EntityDamageEvent event = new EntityDamageEvent(player, EntityDamageEvent.DamageCause.SUICIDE, 1000); 394 | Bukkit.getPluginManager().callEvent(event); 395 | player.setHealth(0); 396 | return true; 397 | } 398 | return false; 399 | } 400 | 401 | /** 402 | * Sends a player a message 403 | * @param playerName Player to message 404 | * @param message Message to send 405 | * @return If successful 406 | */ 407 | @Action( 408 | aliases = {"message", "sendMessage", "msg", "pm"}, 409 | schedulable = false) 410 | public boolean message(final String playerName, String message) { 411 | final Player player = Bukkit.getPlayer(playerName); 412 | if (player != null) { 413 | try { 414 | message = URLDecoder.decode(message, "UTF-8"); 415 | } catch (final UnsupportedEncodingException e) { 416 | e.printStackTrace(); 417 | } 418 | message = Utilities.color(message); 419 | if (!message.isEmpty()) { 420 | player.sendMessage(message); 421 | return true; 422 | } 423 | } 424 | return false; 425 | } 426 | 427 | /** 428 | * OP's a player 429 | * @param playerName Player to OP 430 | * @return If successful 431 | */ 432 | @Action( 433 | aliases = {"op", "opPlayer"}) 434 | public boolean op(final String playerName) { 435 | Bukkit.getOfflinePlayer(playerName).setOp(true); 436 | final Player onlinePlayer = Bukkit.getPlayer(playerName); 437 | if (onlinePlayer != null) 438 | onlinePlayer.sendMessage("You are now OP!"); 439 | PlayerLogger.setCase(playerName); 440 | return true; 441 | } 442 | 443 | /** 444 | * Preforms a command as a player 445 | * @param playerName Player to preform the command as 446 | * @param command Command to preform, without the '/' in front of it 447 | * @return If successful 448 | */ 449 | @Action( 450 | aliases = {"performCommand", "playerCommand"}, 451 | schedulable = false) 452 | public boolean performCommand(final String playerName, final String command) { 453 | final Player player = Bukkit.getPlayer(playerName); 454 | if (player != null) 455 | if (!command.equals("")) 456 | return player.performCommand(command); 457 | return false; 458 | } 459 | 460 | /** 461 | * Removes a player from the whitelist 462 | * @param playerName Player to remove from the whitelist 463 | * @return If successful 464 | */ 465 | @Action( 466 | aliases = {"removeFromWhitelist", "whitelistRemove"}) 467 | public boolean removeFromWhitelist(final String playerName) { 468 | Bukkit.getOfflinePlayer(playerName).setWhitelisted(false); 469 | return true; 470 | } 471 | 472 | /** 473 | * Removes an item from a players inventory 474 | * @param playerName Player to remove the item from 475 | * @param id Id of the item to remove 476 | * @return If successful 477 | */ 478 | @Action( 479 | aliases = {"removeInventoryItem", "remove"}, 480 | schedulable = false) 481 | public boolean removeInventoryItem(final String playerName, final int id) { 482 | final Player player = Bukkit.getPlayer(playerName); 483 | if (player != null) { 484 | player.getInventory().removeItem(new ItemStack(id)); 485 | return true; 486 | } 487 | return false; 488 | } 489 | 490 | /** 491 | * Sets the food level of a player 492 | * @param playerName Player to set the food level of 493 | * @param foodLevel New food level of player 494 | * @return If successful 495 | */ 496 | @Action( 497 | aliases = {"setFoodLevel", "foodLevel", "food"}, 498 | schedulable = false) 499 | public boolean setFoodLevel(final String playerName, final int foodLevel) { 500 | final Player player = Bukkit.getServer().getPlayer(playerName); 501 | if (player != null) { 502 | player.setFoodLevel(foodLevel); 503 | return true; 504 | } 505 | return false; 506 | } 507 | 508 | /** 509 | * Sets the game mode of a player 510 | * 0 = Survival 511 | * 1 = Creative 512 | * @param playerName Player to set the game mode of 513 | * @param gameMode Game mode to set 514 | * @return If successful 515 | */ 516 | @Action( 517 | aliases = {"setGameMode", "gameMode"}, 518 | schedulable = false) 519 | public boolean setGameMode(final String playerName, final int gameMode) { 520 | final Player player = Bukkit.getServer().getPlayer(playerName); 521 | if (player != null) { 522 | if (gameMode == 1) 523 | player.setGameMode(GameMode.CREATIVE); 524 | else 525 | player.setGameMode(GameMode.SURVIVAL); 526 | return true; 527 | } 528 | return false; 529 | } 530 | 531 | /** 532 | * Sets the health of a player 533 | * @param playerName Player to set the health of 534 | * @param health New health of player 535 | * @return If successful 536 | */ 537 | @Action( 538 | aliases = {"setHealth", "health"}, 539 | schedulable = false) 540 | public boolean setHealth(final String playerName, final int health) { 541 | final Player player = Bukkit.getServer().getPlayer(playerName); 542 | if (player != null) { 543 | player.setHealth(health); 544 | return true; 545 | } 546 | return false; 547 | } 548 | 549 | /** 550 | * Sets a slot of a players inventory 551 | * @param playerName Player to set 552 | * @param slotNumber Slot number of the players inventory to set 553 | * @param id Id to slot to set 554 | * @param amount Amount of slot to set 555 | * @param damage Damage of slot to set 556 | * @param data Data of slot to set 557 | * @return If successful 558 | */ 559 | @Action( 560 | aliases = {"setInventorySlot", "setInventory"}, 561 | schedulable = false) 562 | public boolean setInventorySlot(final String playerName, final int slotNumber, final int id, final int amount, final short damage, final byte data) { 563 | final Player player = Bukkit.getPlayer(playerName); 564 | if (player != null) { 565 | final PlayerInventory inventory = player.getInventory(); 566 | final ItemStack stack = new ItemStack(id, amount, damage, data); 567 | if (slotNumber == 103) 568 | inventory.setHelmet(stack); 569 | else if (slotNumber == 102) 570 | inventory.setChestplate(stack); 571 | else if (slotNumber == 101) 572 | inventory.setLeggings(stack); 573 | else if (slotNumber == 100) 574 | inventory.setBoots(stack); 575 | else 576 | inventory.setItem(slotNumber, stack); 577 | return true; 578 | } 579 | return false; 580 | } 581 | 582 | /** 583 | * Throws a snowball as a player 584 | * @param playerName Player to throw the snowball as 585 | * @return If successful 586 | */ 587 | @Action( 588 | aliases = {"throwSnowball", "snowball"}, 589 | schedulable = false) 590 | public boolean snowball(final String playerName) { 591 | final Player player = Bukkit.getPlayer(playerName); 592 | if (player != null) { 593 | player.launchProjectile(Snowball.class); 594 | return true; 595 | } 596 | return false; 597 | } 598 | 599 | /** 600 | * Teleports a player to a location 601 | * @param playerName Player to teleport 602 | * @param worldName World to teleport the player to 603 | * @param x X to teleport the player too 604 | * @param y Y to teleport the player too 605 | * @param z Z to teleport the player too 606 | * @return If successful 607 | */ 608 | @Action( 609 | aliases = {"teleport"}, 610 | schedulable = false) 611 | public boolean teleport(final String playerName, final String worldName, final double x, final double y, 612 | final double z) { 613 | final Player player = Bukkit.getPlayer(playerName); 614 | final World world = Bukkit.getWorld(worldName); 615 | if (player != null && world != null) { 616 | player.teleport(new Location(world, x, y, z)); 617 | return true; 618 | } 619 | return false; 620 | } 621 | 622 | /** 623 | * Unbans a player 624 | * @param playerName Player to unban 625 | * @return If successful 626 | */ 627 | @Action( 628 | aliases = {"unban", "unbanPlayer", "bannedRemove"}) 629 | public boolean unban(final String playerName) { 630 | Bukkit.getOfflinePlayer(playerName).setBanned(false); 631 | return true; 632 | } 633 | 634 | /** 635 | * Updates an inventory slot 636 | * @param playerName Player whos inventory is to update 637 | * @param slotNumber Slot number of the players inventory to update 638 | * @param id Id of the slot to set 639 | * @param amount Amount of the slot to set 640 | * @param damage Damage of the slot to set 641 | * @param data Data of the slot to set 642 | * @return If successful 643 | */ 644 | @Action( 645 | aliases = {"updatePlayerInventorySlot", "update"}, 646 | schedulable = false) 647 | public boolean updateInventorySlot(final String playerName, final int slotNumber, final int id, final int amount, final short damage, final byte data) { 648 | final Player player = Bukkit.getPlayer(playerName); 649 | if (player != null) { 650 | player.getInventory().setItem(slotNumber, new ItemStack(id, amount, damage, data)); 651 | return true; 652 | } 653 | return false; 654 | } 655 | } 656 | -------------------------------------------------------------------------------- /src/me/neatmonster/spacebukkit/actions/ServerActions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of SpaceBukkit (http://spacebukkit.xereo.net/). 3 | * 4 | * SpaceBukkit is free software: you can redistribute it and/or modify it under the terms of the 5 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license as published by the Creative 6 | * Common organization, either version 3.0 of the license, or (at your option) any later version. 7 | * 8 | * SpaceBukkit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 9 | * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license for more details. 11 | * 12 | * You should have received a copy of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) 13 | * license along with this program. If not, see . 14 | */ 15 | package me.neatmonster.spacebukkit.actions; 16 | 17 | import java.io.BufferedReader; 18 | import java.io.File; 19 | import java.io.FileReader; 20 | import java.io.UnsupportedEncodingException; 21 | import java.net.URLDecoder; 22 | import java.util.ArrayList; 23 | import java.util.Arrays; 24 | import java.util.HashMap; 25 | import java.util.LinkedHashMap; 26 | import java.util.LinkedList; 27 | import java.util.List; 28 | import java.util.Map; 29 | import java.util.TreeMap; 30 | 31 | import me.neatmonster.spacebukkit.SpaceBukkit; 32 | import me.neatmonster.spacebukkit.players.PlayerLogger; 33 | import me.neatmonster.spacebukkit.utilities.ANSI; 34 | import me.neatmonster.spacebukkit.utilities.PropertiesFile; 35 | import me.neatmonster.spacebukkit.utilities.Utilities; 36 | import me.neatmonster.spacemodule.api.Action; 37 | import me.neatmonster.spacemodule.api.ActionHandler; 38 | import me.neatmonster.spacemodule.api.UnhandledActionException; 39 | import net.milkbowl.vault.permission.Permission; 40 | import net.milkbowl.vault.permission.plugins.Permission_SuperPerms; 41 | 42 | import org.bukkit.Bukkit; 43 | import org.bukkit.ChatColor; 44 | import org.bukkit.Material; 45 | import org.bukkit.Server; 46 | import org.bukkit.World; 47 | import org.bukkit.entity.Player; 48 | import org.bukkit.plugin.Plugin; 49 | import org.bukkit.plugin.ServicesManager; 50 | 51 | public class ServerActions implements ActionHandler { 52 | 53 | /** 54 | * Bans an IP 55 | * @param ip Ip to ban 56 | * @return If successful 57 | */ 58 | @Action( 59 | aliases = {"banIp", "bannedIpsAdd"}) 60 | public boolean banIp(final String ip) { 61 | Bukkit.getServer().banIP(ip); 62 | return true; 63 | } 64 | 65 | /** 66 | * Broadcasts a message 67 | * @param message Message to broadcast 68 | * @return If successful 69 | * @throws UnsupportedEncodingException If UTF-8 is not supported 70 | */ 71 | @Action( 72 | aliases = {"broadcast", "broadcastMessage", "say", "tell"}) 73 | public boolean broadcast(String message) { 74 | if (!message.equals("")) { 75 | try { 76 | message = URLDecoder.decode(message, "UTF-8"); 77 | } catch (final UnsupportedEncodingException e) { 78 | e.printStackTrace(); 79 | } 80 | message = Utilities.color(message); 81 | Bukkit.getServer().broadcastMessage(message); 82 | try { 83 | PlayerLogger.addPlayerChat("Server", URLDecoder.decode(message, "UTF-8")); 84 | } catch (final UnsupportedEncodingException e) { 85 | e.printStackTrace(); 86 | } 87 | return true; 88 | } 89 | return false; 90 | } 91 | 92 | /** 93 | * Broadcasts a message with a name 94 | * @param name Name to use 95 | * @param message Message to broadcast 96 | * @return If successful 97 | * @throws UnsupportedEncodingException If UTF-8 is not supported 98 | */ 99 | @Action( 100 | aliases = {"broadcastWithName", "sayWithName", "tellWithName"}) 101 | public boolean broadcastWithName(final String name, final String message) { 102 | if (!name.equals("") && !message.equals("")) { 103 | String broadcast = ChatColor.WHITE + "[" + name + ChatColor.WHITE + "] " + message; 104 | try { 105 | broadcast = URLDecoder.decode(broadcast, "UTF-8"); 106 | } catch (final UnsupportedEncodingException e) { 107 | e.printStackTrace(); 108 | } 109 | broadcast = Utilities.color(broadcast); 110 | Bukkit.getServer().broadcastMessage(broadcast); 111 | try { 112 | PlayerLogger.addPlayerChat(name, URLDecoder.decode(message, "UTF-8")); 113 | } catch (final UnsupportedEncodingException e) { 114 | e.printStackTrace(); 115 | } 116 | return true; 117 | } 118 | return false; 119 | } 120 | 121 | /** 122 | * Disables all plugins temporarily 123 | * @return If successful 124 | */ 125 | @Action( 126 | aliases = {"disablePluginsTemporarily"}) 127 | public boolean disablePluginsTemporarily() { 128 | for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) 129 | if (!plugin.getDescription().getName().equalsIgnoreCase("SpaceBukkit") 130 | && !plugin.getDescription().getName().equalsIgnoreCase("RemoteToolkitPlugin")) 131 | Bukkit.getPluginManager().disablePlugin(plugin); 132 | return true; 133 | } 134 | 135 | /** 136 | * Disables a plugin temporarily 137 | * @param pluginName Plugin to disable 138 | * @return If successful 139 | */ 140 | @Action( 141 | aliases = {"disablePluginTemporarily"}) 142 | public boolean disablePluginTemporarily(final String pluginName) { 143 | final Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName); 144 | if (plugin != null) { 145 | Bukkit.getPluginManager().disablePlugin(plugin); 146 | return true; 147 | } 148 | return false; 149 | } 150 | 151 | /** 152 | * Disables the whitelist 153 | * @return If successful 154 | */ 155 | @Action( 156 | aliases = {"disableWhitelisting", "whitelistOff"}) 157 | public boolean disableWhitelisting() { 158 | Bukkit.setWhitelist(false); 159 | return true; 160 | } 161 | 162 | /** 163 | * Edits a property file 164 | * @param name Name of the file 165 | * @param type Type of value 166 | * @param key Key to edit 167 | * @param value Value to set as 168 | * @return If successful 169 | */ 170 | @Action( 171 | aliases = {"editPropertiesFile", "propertiesFile"}) 172 | public boolean editPropertiesFile(final String name, final String type, final String key, final String value) { 173 | if (new File(name + ".properties").exists()) { 174 | final PropertiesFile file = new PropertiesFile(name + ".properties"); 175 | if (type.toLowerCase().equals("boolean")) 176 | file.setBoolean(key, Boolean.valueOf(value.toString())); 177 | else if (type.toLowerCase().equals("long")) 178 | file.setLong(key, Long.valueOf(value.toString())); 179 | else if (type.toLowerCase().equals("int")) 180 | file.setInt(key, Integer.valueOf(value.toString())); 181 | else if (type.toLowerCase().equals("string")) 182 | file.setString(key, value.toString()); 183 | else if (type.toLowerCase().equals("double")) 184 | file.setDouble(key, Double.valueOf(value.toString())); 185 | file.save(); 186 | return true; 187 | } 188 | return false; 189 | } 190 | 191 | /** 192 | * Enables a plugin temporarily 193 | * @param pluginName Plugin to enable 194 | * @return If successful 195 | */ 196 | @Action( 197 | aliases = {"enablePluginTemporarily"}) 198 | public boolean enablePluginTemporarily(final String pluginName) { 199 | final Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName); 200 | if (plugin != null) { 201 | Bukkit.getPluginManager().enablePlugin(plugin); 202 | return true; 203 | } 204 | return false; 205 | } 206 | 207 | /** 208 | * Enables whitelisting 209 | * @return If successful 210 | */ 211 | @Action( 212 | aliases = {"enableWhitelisting", "whitelistOn"}) 213 | public boolean enableWhitelisting() { 214 | Bukkit.setWhitelist(true); 215 | return true; 216 | } 217 | 218 | 219 | 220 | /** 221 | * Gets all disabled plugins 222 | * @return Disabled plugins 223 | */ 224 | @Action( 225 | aliases = {"getDisabledPlugins"}) 226 | public List getDisabledPlugins() { 227 | final List disabledPluginsNames = new ArrayList(); 228 | for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) { 229 | if (!plugin.isEnabled()) 230 | disabledPluginsNames.add(plugin.getDescription().getName()); 231 | } 232 | return disabledPluginsNames; 233 | } 234 | 235 | /** 236 | * Gets the Dynmap host 237 | * @return Dynmap host 238 | */ 239 | @Action( 240 | aliases = {"getDynmapHost", "dynmapHost"}) 241 | public String getDynmapHost() { 242 | final Plugin dynmap = Bukkit.getPluginManager().getPlugin("dynmap"); 243 | if (dynmap != null) 244 | return dynmap.getConfig().getString("webserver-bindaddress", "0.0.0.0"); 245 | else 246 | return ""; 247 | } 248 | 249 | /** 250 | * Gets the Dynmap port 251 | * @return Dynmap port 252 | */ 253 | @Action( 254 | aliases = {"getDynmapPort", "dynmapPort"}) 255 | public String getDynmapPort() { 256 | final Plugin dynmap = Bukkit.getPluginManager().getPlugin("dynmap"); 257 | if (dynmap != null) 258 | return dynmap.getConfig().getString("webserver-port", "8123"); 259 | else 260 | return ""; 261 | } 262 | 263 | /** 264 | * Gets the name of an Item 265 | * @param id Id to get 266 | * @return Item name 267 | */ 268 | @Action( 269 | aliases = {"getItemName", "getName", "name"}) 270 | public String getItemName(final int id) { 271 | String name = ""; 272 | for (final String subname : Material.getMaterial(id).name().split("_")) 273 | name += subname.substring(0, 1).toUpperCase() + subname.substring(1, subname.length()).toLowerCase() + " "; 274 | return name.substring(0, name.length() - 1).replace("Tnt", "TNT"); 275 | } 276 | 277 | /** 278 | * Gets all item names 279 | * @return Item names 280 | */ 281 | @Action( 282 | aliases = {"getItems", "items"}) 283 | public Map getItems() { 284 | final LinkedHashMap items = new LinkedHashMap(); 285 | for (final Material material : Material.values()) { 286 | String name = ""; 287 | for (final String subname : material.name().split("_")) 288 | name += subname.substring(0, 1).toUpperCase() + subname.substring(1, subname.length()).toLowerCase() 289 | + " "; 290 | items.put(material.getId(), name.substring(0, name.length() - 1).replace("Tnt", "TNT")); 291 | } 292 | return items; 293 | } 294 | 295 | /** 296 | * Gets the latest chats 297 | * @return Latest chats 298 | */ 299 | @Action( 300 | aliases = {"getLatestChats", "latestChats"}) 301 | public Map getLatestChats() { 302 | return PlayerLogger.getPlayersChats(50); 303 | } 304 | 305 | /** 306 | * Gets the latest chat with a limit 307 | * @param limit Number of chats to include 308 | * @return Chats 309 | */ 310 | @Action( 311 | aliases = {"getLatestChatsWithLimit", "latestChatsWithLimit"}) 312 | public Map getLatestChatsWithLimit(final int limit) { 313 | return PlayerLogger.getPlayersChats(limit); 314 | } 315 | 316 | /** 317 | * Gets the latest joins 318 | * @return Latest joins 319 | */ 320 | @Action( 321 | aliases = {"getLatestConnections", "latestConnections"}) 322 | public Map getLatestConnections() { 323 | return PlayerLogger.getPlayersJoins(50); 324 | } 325 | 326 | /** 327 | * Gets the latest joins with a limit 328 | * @param limit Number of joins to include 329 | * @return Joins 330 | */ 331 | @Action( 332 | aliases = {"getLatestConnectionsWithLimit", "latestConnectionsWithLimit"}) 333 | public Map getLatestConnectionsWithLimit(final int limit) { 334 | return PlayerLogger.getPlayersJoins(limit); 335 | } 336 | 337 | /** 338 | * Gets the latest logs 339 | * @return Latest logs 340 | */ 341 | @Action( 342 | aliases = {"getLatestConsoleLogs", "latestConsoleLogs"}) 343 | public Map getLatestConsoleLogs() { 344 | return getLatestConsoleLogsWithLimit(50); 345 | } 346 | 347 | /** 348 | * Gets the latest logs with a limit 349 | * @param limit Number of log lines to include 350 | * @return Log 351 | */ 352 | @Action( 353 | aliases = {"getLatestConsoleLogsWithLimit", "latestConsoleLogsWithLimit"}) 354 | public TreeMap getLatestConsoleLogsWithLimit(final int limit) { 355 | try { 356 | BufferedReader bufferedReader = new BufferedReader(new FileReader(new File("server.log"))); 357 | int size = 0; 358 | int loop = 0; 359 | for (String line = bufferedReader.readLine(); line != null; line = bufferedReader.readLine()) 360 | size++; 361 | bufferedReader = new BufferedReader(new FileReader(new File("server.log"))); 362 | final Map lines = new HashMap(); 363 | for (String line = bufferedReader.readLine(); line != null; line = bufferedReader.readLine()) { 364 | if (size - limit < 1) { 365 | final char[] c = line.toCharArray(); 366 | final StringBuilder line_ = new StringBuilder(line); 367 | int off = 0; 368 | try { 369 | for (int i = 0; i < c.length; i++) 370 | if (c[i] == '[' && Character.isDigit(c[i + 1])) 371 | if (Character.isDigit(c[i + 2]) && c[i + 3] == 'm') { 372 | line_.delete(i - (off + 1), i + 4 - off); 373 | off += 5; 374 | } else if (c[i + 2] == 'm') { 375 | line_.delete(i - (off + 1), i + 3 - off); 376 | off += 4; 377 | } 378 | } catch (final IndexOutOfBoundsException e) { 379 | e.printStackTrace(); 380 | } 381 | lines.put(loop++, ANSI.noANSI(line)); 382 | } 383 | size--; 384 | } 385 | bufferedReader.close(); 386 | return new TreeMap(lines); 387 | } catch (final Exception e) { 388 | e.printStackTrace(); 389 | } 390 | return new TreeMap(); 391 | } 392 | 393 | /** 394 | * Gets the latest quits 395 | * @return Latest quits 396 | */ 397 | @Action( 398 | aliases = {"getLatestDeconnections", "latestDeconnections"}) 399 | public Map getLatestDeconnections() { 400 | return PlayerLogger.getPlayersQuits(50); 401 | } 402 | 403 | /** 404 | * Gets the latest quits with a limit 405 | * @param limit Number of quits to include 406 | * @return Quits 407 | */ 408 | @Action( 409 | aliases = {"getLatestDeconnectionsWithLimit", "latestDeconnectionsWithLimit"}) 410 | public Map getLatestDeconnectionsWithLimit(final int limit) { 411 | return PlayerLogger.getPlayersQuits(limit); 412 | } 413 | 414 | /** 415 | * Gets information about a plugin 416 | * @param pluginName Plugin to get 417 | * @return Information about a plugin 418 | */ 419 | @Action( 420 | aliases = {"getPluginInformations", "pluginInformations"}) 421 | public LinkedHashMap getPluginInformations(final String pluginName) { 422 | final LinkedHashMap pluginInformations = new LinkedHashMap(); 423 | final Plugin plugin = Bukkit.getPluginManager().getPlugin(Utilities.decodeEscapeSequences(pluginName)); 424 | 425 | if (plugin != null) { 426 | pluginInformations.put("Name", plugin.getDescription().getName()); 427 | pluginInformations.put("IsEnabled", plugin.isEnabled()); 428 | pluginInformations.put("Commands", plugin.getDescription().getCommands()); 429 | pluginInformations.put("Depend", plugin.getDescription().getDepend()); 430 | if(plugin.getDataFolder() != null) 431 | pluginInformations.put("DataFolder", plugin.getDataFolder().getPath()); 432 | else 433 | pluginInformations.put("DataFolder", ""); 434 | pluginInformations.put("SoftDepend", plugin.getDescription().getSoftDepend()); 435 | pluginInformations.put("Authors", plugin.getDescription().getAuthors()); 436 | pluginInformations.put("Description", plugin.getDescription().getDescription()); 437 | pluginInformations.put("FullName", plugin.getDescription().getFullName()); 438 | pluginInformations.put("Main", plugin.getDescription().getMain()); 439 | if (plugin.getDescription().getPermissions() != null) { 440 | final LinkedList> permissions = new LinkedList>(); 441 | for (final org.bukkit.permissions.Permission permission : plugin.getDescription().getPermissions()) { 442 | final LinkedHashMap permissionInformations = new LinkedHashMap(); 443 | permissionInformations.put("Name", permission.getName()); 444 | permissionInformations.put("Description", permission.getDescription()); 445 | permissionInformations.put("Default", permission.getDefault().name()); 446 | permissions.add(permissionInformations); 447 | } 448 | pluginInformations.put("Permissions", permissions); 449 | } else { 450 | pluginInformations.put("Permissions", "[]"); 451 | } 452 | pluginInformations.put("Version", plugin.getDescription().getVersion()); 453 | pluginInformations.put("Website", plugin.getDescription().getWebsite()); 454 | pluginInformations.put("Bukget", SpaceBukkit.getInstance().pluginsManager.contains(pluginName)); 455 | return pluginInformations; 456 | } 457 | return new LinkedHashMap(); 458 | } 459 | 460 | /** 461 | * Gets all the plugins on the server 462 | * @return All plugins 463 | */ 464 | @Action( 465 | aliases = {"getPlugins", "plugins"}) 466 | public LinkedList getPlugins() { 467 | final LinkedList pluginsNames = new LinkedList(); 468 | for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) { 469 | pluginsNames.add(plugin.getDescription().getName()); 470 | } 471 | return pluginsNames; 472 | } 473 | 474 | /** 475 | * Gets information about the server 476 | * @return Server information 477 | */ 478 | @Action( 479 | aliases = {"getServer", "server"}) 480 | public Map getServer() { 481 | final LinkedHashMap serverInformations = new LinkedHashMap(); 482 | final Server server = Bukkit.getServer(); 483 | serverInformations.put("Name", server.getName()); 484 | serverInformations.put("AllowFlight", server.getAllowFlight()); 485 | serverInformations.put("AllowNether", server.getAllowNether()); 486 | serverInformations.put("DefaultGameMode", server.getDefaultGameMode().toString()); 487 | serverInformations.put("MaxPlayers", server.getMaxPlayers()); 488 | serverInformations.put("OnlineMode", server.getOnlineMode()); 489 | serverInformations.put("Port", server.getPort()); 490 | serverInformations.put("ServerId", server.getServerId()); 491 | serverInformations.put("ServerName", server.getServerName()); 492 | serverInformations.put("SpawnRadius", server.getSpawnRadius()); 493 | serverInformations.put("UpdateFolder", server.getUpdateFolder()); 494 | serverInformations.put("Version", server.getVersion()); 495 | serverInformations.put("ViewDistance", server.getViewDistance()); 496 | serverInformations.put("HasWhitelist", server.hasWhitelist()); 497 | serverInformations.put("OnlinePlayers", server.getOnlinePlayers().length); 498 | return serverInformations; 499 | } 500 | 501 | /** 502 | * Gets information about a world 503 | * @param worldName World to get information about 504 | * @return Information about the world 505 | */ 506 | @Action( 507 | aliases = {"getWorldInformations", "worldInformations"}) 508 | public LinkedHashMap getWorldInformations(final String worldName) { 509 | final LinkedHashMap worldInformations = new LinkedHashMap(); 510 | final World world = Bukkit.getWorld(worldName); 511 | if (world != null) { 512 | worldInformations.put("Name", world.getName()); 513 | worldInformations.put("AllowAnimals", world.getAllowAnimals()); 514 | worldInformations.put("AllowMonsters", world.getAllowMonsters()); 515 | worldInformations.put("Difficulty", world.getDifficulty().toString()); 516 | worldInformations.put("Environment", world.getEnvironment().toString()); 517 | worldInformations.put("FullTime", world.getFullTime()); 518 | worldInformations.put("KeepSpawnInMemory", world.getKeepSpawnInMemory()); 519 | worldInformations.put("MaxHeight", world.getMaxHeight()); 520 | worldInformations.put("PVP", world.getPVP()); 521 | worldInformations.put("SeaLevel", world.getSeaLevel()); 522 | worldInformations.put("Seed", world.getSeed()); 523 | worldInformations.put("ThunderDuration", world.getThunderDuration()); 524 | worldInformations.put("Time", world.getTime()); 525 | worldInformations.put("FullTime", world.getFullTime()); 526 | worldInformations.put("FormattedTime", Utilities.formatTime(world.getTime())); 527 | worldInformations.put("WeatherDuration", world.getWeatherDuration()); 528 | return worldInformations; 529 | } 530 | return new LinkedHashMap(); 531 | } 532 | 533 | /** 534 | * Gets all the worlds 535 | * @return All worlds 536 | */ 537 | @Action( 538 | aliases = {"getWorlds", "worlds"}) 539 | public List getWorlds() { 540 | final List worldsNames = new ArrayList(); 541 | for (final World world : Bukkit.getWorlds()) 542 | worldsNames.add(world.getName()); 543 | return worldsNames; 544 | } 545 | 546 | /** 547 | * Checks if an action is schedulable 548 | * @param actionName Action to check 549 | * @return If the action is schedulable 550 | * @throws UnhandledActionException If the action is not a valid action 551 | */ 552 | @Action( 553 | aliases = {"isSchedulable", "schedulable"}) 554 | public boolean isSchedulable(final String actionName) { 555 | try { 556 | return SpaceBukkit.getInstance().actionsManager.isSchedulable(actionName); 557 | } catch (final UnhandledActionException e) { 558 | e.printStackTrace(); 559 | } 560 | return false; 561 | } 562 | 563 | /** 564 | * Reloads the server 565 | * @return If successful 566 | */ 567 | @Action( 568 | aliases = {"reload", "reloadServer"}) 569 | public boolean reload() { 570 | Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(SpaceBukkit.getInstance(), new Runnable() { 571 | @Override 572 | public void run() { 573 | Bukkit.reload(); 574 | } 575 | }, 20L); 576 | return true; 577 | } 578 | 579 | /** 580 | * Saves all the maps 581 | * @return If successful 582 | */ 583 | @Action( 584 | aliases = {"saveMap", "save"}) 585 | public boolean saveMap() { 586 | for (final World world : Bukkit.getWorlds()) 587 | world.save(); 588 | return true; 589 | } 590 | 591 | /** 592 | * Turns auto saving off 593 | * @return If successful 594 | */ 595 | @Action( 596 | aliases = {"saveOff"}) 597 | public boolean saveOff() { 598 | for (final World world : Bukkit.getWorlds()) 599 | world.setAutoSave(false); 600 | return true; 601 | } 602 | 603 | /** 604 | * Turns auto saving on 605 | * @return If successful 606 | */ 607 | @Action( 608 | aliases = {"saveOn"}) 609 | public boolean saveOn() { 610 | for (final World world : Bukkit.getWorlds()) 611 | world.setAutoSave(true); 612 | return true; 613 | } 614 | 615 | /** 616 | * Sets a worlds weather 617 | * @param worldName World to set 618 | * @param storm If there is a storm 619 | * @param thunder If there is thunder 620 | * @return If successful 621 | */ 622 | @Action( 623 | aliases = {"setWorldWeather", "worldWeather", "weather"}) 624 | public boolean setWorldWeather(final String worldName, final Boolean storm, final Boolean thunder) { 625 | final World world = Bukkit.getWorld(worldName); 626 | if (world == null) 627 | return false; 628 | world.setStorm(storm); 629 | world.setThundering(thunder); 630 | return true; 631 | } 632 | 633 | /** 634 | * Unbans an IP 635 | * @param ip Ip to unban 636 | * @return If successful 637 | */ 638 | @Action( 639 | aliases = {"unbanIp", "bannedIpsRemove"}) 640 | public boolean unbanIp(final String ip) { 641 | if (!ip.equals("")) { 642 | Bukkit.getServer().unbanIP(ip); 643 | return true; 644 | } 645 | return false; 646 | } 647 | 648 | /** 649 | * Checks if there was a connection at a certain time 650 | * @param time Time to check 651 | * @return If the was a connection at a time 652 | */ 653 | @Action( 654 | aliases = {"wasThereAConnection", "connections"}) 655 | public boolean wasThereAConnection(final int time) { 656 | return !(PlayerLogger.getLastJoin() == 0 && PlayerLogger.getLastQuit() == 0 || PlayerLogger.getLastJoin() < System 657 | .currentTimeMillis() - time * 1000 658 | && PlayerLogger.getLastQuit() < System.currentTimeMillis() - time * 1000); 659 | } 660 | 661 | /** 662 | * Checks if permissions are available 663 | * @return If permissions are avaiable 664 | */ 665 | @Action( 666 | aliases = {"permissionsAvailable", "permsAvailable"}) 667 | public boolean permissionsAvailable() { 668 | return !(Bukkit.getServicesManager().getRegistration(Permission.class).getProvider() instanceof Permission_SuperPerms); 669 | } 670 | 671 | /** 672 | * Gets the permissions plugin name 673 | * @return Permissions plugin name 674 | */ 675 | @Action( 676 | aliases = {"permissionsPluginName", "permsPluginName"}) 677 | public String getPermissionsPluginName() { 678 | if (!(permissionsAvailable())) { 679 | return "NULL"; 680 | } 681 | ServicesManager sm = Bukkit.getServicesManager(); 682 | return sm.getRegistration(Permission.class).getProvider().getName(); 683 | } 684 | 685 | /** 686 | * Gets the permissions plugin version 687 | * @return Permissions plugin version 688 | */ 689 | @Action( 690 | aliases = {"permissionsPluginVersion", "permsPluginVersion"}) 691 | public String getPermissionsPluginVersion() { 692 | if (!(permissionsAvailable())) { 693 | return "NULL"; 694 | } 695 | 696 | ServicesManager sm = Bukkit.getServicesManager(); 697 | Plugin p = Bukkit.getPluginManager().getPlugin(sm.getRegistration(Permission.class).getProvider().getName()); 698 | if (p != null) { 699 | return p.getDescription().getVersion(); 700 | } 701 | return "NULL"; 702 | } 703 | 704 | /** 705 | * Get a full list of users under a permissions plugin. 706 | * @return The full list of users under the permissions plugin. 707 | */ 708 | @Action( 709 | aliases = {"permUserNames", "getPermUserNames"}) 710 | public List getPermUserNames() { 711 | if (!(permissionsAvailable())) { 712 | return new ArrayList(0); 713 | } 714 | ServicesManager sm = Bukkit.getServicesManager(); 715 | Permission p = sm.getRegistration(Permission.class).getProvider(); 716 | List result = new ArrayList(); 717 | for (Player player : Bukkit.getOnlinePlayers()) { 718 | if (p.getPlayerGroups(player) != null && p.getPlayerGroups(player)[0] != null) { 719 | result.add(player.getName()); 720 | } 721 | } 722 | return result; 723 | } 724 | 725 | /** 726 | * Get a full list of users under a world. 727 | * @param world the world to get users under. 728 | * @return The full list of users under a world. 729 | */ 730 | @Action( 731 | aliases = {"permUserNamesForWorld", "getPermUserNamesForWorld"}) 732 | public List getPermUserNamesForWorld(String world) { 733 | if (!(permissionsAvailable())) { 734 | return new ArrayList(0); 735 | } 736 | ServicesManager sm = Bukkit.getServicesManager(); 737 | Permission p = sm.getRegistration(Permission.class).getProvider(); 738 | List result = new ArrayList(); 739 | for (Player player : Bukkit.getOnlinePlayers()) { 740 | String playerName = player.getName(); 741 | if (p.getPlayerGroups(world, playerName) != null && p.getPlayerGroups(world, playerName).length > 0) { 742 | result.add(playerName); 743 | } 744 | } 745 | return result; 746 | } 747 | 748 | /** 749 | * Get a list of all permission groups. 750 | * @return A list of permission groups. 751 | */ 752 | @Action( 753 | aliases = {"permGroupNames", "getPermGroupNames"}) 754 | public List getPermGroupNames() { 755 | if (!(permissionsAvailable())) { 756 | return new ArrayList(0); 757 | } 758 | ServicesManager sm = Bukkit.getServicesManager(); 759 | Permission p = sm.getRegistration(Permission.class).getProvider(); 760 | return Arrays.asList(p.getGroups()); 761 | } 762 | 763 | /** 764 | * Get a list of all permission groups under a world. 765 | * @param world the world to get groups under. 766 | * @return A list of permission groups under a world. 767 | */ 768 | @Action( 769 | aliases = {"permGroupNamesForWorld", "getPermGroupNamesForWorld"}) 770 | public List getPermGroupNamesForWorld(String world) { 771 | if (!(permissionsAvailable())) { 772 | return new ArrayList(0); 773 | } 774 | ServicesManager sm = Bukkit.getServicesManager(); 775 | Permission p = sm.getRegistration(Permission.class).getProvider(); 776 | return Arrays.asList(p.getGroups()); 777 | } 778 | 779 | /** 780 | * Get a list of users given their parent group. 781 | * @param groupName The group the users belong to. 782 | * @return A list of usernames in a given group. 783 | */ 784 | @Action( 785 | aliases = {"permGroupUsers", "getPermGroupUsers"}) 786 | public List getPermGroupUsers(String groupName) { 787 | if (!(permissionsAvailable())) { 788 | return new ArrayList(0); 789 | } 790 | ServicesManager sm = Bukkit.getServicesManager(); 791 | Permission p = sm.getRegistration(Permission.class).getProvider(); 792 | List result = new ArrayList(); 793 | for (Player player : Bukkit.getOnlinePlayers()) { 794 | if (p.playerInGroup(player, groupName)) { 795 | result.add(player.getName()); 796 | } 797 | } 798 | return result; 799 | } 800 | 801 | /** 802 | * Get a list of users given their parent group and world name. 803 | * @param groupName The group the users belong to. 804 | * @param worldName the name of the world the group belongs to. 805 | * @return A list of usernames in a given group. 806 | */ 807 | @Action( 808 | aliases = {"permGroupUsersForWorld", "getPermGroupUsersForWorld"}) 809 | public List getPermGroupUsersForWorld(String groupName, String worldName) { 810 | if (!(permissionsAvailable())) { 811 | return new ArrayList(0); 812 | } 813 | ServicesManager sm = Bukkit.getServicesManager(); 814 | Permission p = sm.getRegistration(Permission.class).getProvider(); 815 | List result = new ArrayList(); 816 | for (Player player : Bukkit.getOnlinePlayers()) { 817 | String playerName = player.getName(); 818 | if (p.playerInGroup(worldName, playerName, groupName)) { 819 | result.add(playerName); 820 | } 821 | } 822 | return result; 823 | } 824 | 825 | /** 826 | * Get a list of permissions directly under a given group name. 827 | * @param groupName the group to list permissions under. 828 | * @return The list of permissions under groupName. 829 | */ 830 | @Action( 831 | aliases = {"groupPerms", "getGroupPerms"}) 832 | public List getGroupPerms(String groupName) { 833 | if (!(permissionsAvailable())) { 834 | return new ArrayList(0); 835 | } 836 | ServicesManager sm = Bukkit.getServicesManager(); 837 | Permission p = sm.getRegistration(Permission.class).getProvider(); 838 | List result = new ArrayList(); 839 | for (org.bukkit.permissions.Permission perm : Bukkit.getPluginManager().getPermissions()) { 840 | String permName = perm.getName(); 841 | if (p.groupHas(Bukkit.getWorlds().get(0), groupName, permName)) { 842 | result.add(permName); 843 | } 844 | } 845 | return result; 846 | } 847 | 848 | /** 849 | * Get a list of permissions directly under a given group name in a given world. 850 | * @param groupName the group to list permissions under. 851 | * @param world the name of the world the group belongs to. 852 | * @return The list of permissions under groupName. 853 | */ 854 | @Action( 855 | aliases = {"groupPermsForWorld", "getGroupPermsForWorld"}) 856 | public List getGroupPermsForWorld(String groupName, String world) { 857 | if (!(permissionsAvailable())) { 858 | return new ArrayList(0); 859 | } 860 | ServicesManager sm = Bukkit.getServicesManager(); 861 | Permission p = sm.getRegistration(Permission.class).getProvider(); 862 | List result = new ArrayList(); 863 | for (org.bukkit.permissions.Permission perm : Bukkit.getPluginManager().getPermissions()) { 864 | String permName = perm.getName(); 865 | if (p.groupHas(world, groupName, permName)) { 866 | result.add(permName); 867 | } 868 | } 869 | return result; 870 | } 871 | 872 | /** 873 | * Get a list of permissions given a user name. 874 | * @param userName The name of the user to list permissions for. 875 | * @return The list of permissions this user has. 876 | * Each element of the returned list will be a string in the form "world:permission", where 'world' is 877 | * the world name the permission belongs to. 878 | */ 879 | @Action( 880 | aliases = {"userPerms", "getUserPerms"}) 881 | public List getUserPerms(String userName) { 882 | if (!(permissionsAvailable())) { 883 | return new ArrayList(0); 884 | } 885 | ServicesManager sm = Bukkit.getServicesManager(); 886 | Permission p = sm.getRegistration(Permission.class).getProvider(); 887 | List result = new ArrayList(); 888 | Player ply = Bukkit.getPlayer(userName); 889 | if (ply == null) { 890 | return result; 891 | } 892 | for (org.bukkit.permissions.Permission perm : Bukkit.getPluginManager().getPermissions()) { 893 | String permName = perm.getName(); 894 | if (p.has(ply, permName)) { 895 | result.add(permName); 896 | } 897 | } 898 | return result; 899 | } 900 | 901 | /** 902 | * Get a list of usernames that have a given permission. 903 | * @param permission 904 | * @return the list of users with a given permission. 905 | * Each element of the returned list will be in the form "world:group:permission" where 'world' is 906 | * the world name the permission belongs to, and 'group' is the group the permission belongs to. 907 | */ 908 | @Action( 909 | aliases = {"usersWithPerm","usersWithPermission" , "getUsersWithPerm","getUsersWithPermission"}) 910 | public List getUsersWithPermission(String permission) { 911 | if (!(permissionsAvailable())) { 912 | return new ArrayList(0); 913 | } 914 | ServicesManager sm = Bukkit.getServicesManager(); 915 | Permission p = sm.getRegistration(Permission.class).getProvider(); 916 | List result = new ArrayList(); 917 | for (Player player : Bukkit.getOnlinePlayers()) { 918 | if (p.has(player, permission)) { 919 | result.add(player.getName()); 920 | } 921 | } 922 | return result; 923 | } 924 | 925 | /** 926 | * Check if a user has a given permission. 927 | * @param userName The user to check for a permission. 928 | * @param permission The permission to check. 929 | * @param world the name of the world the permission is under. 930 | * @return true if the user has the permission, false otherwise. 931 | */ 932 | @Action( 933 | aliases = {"userHasPerm", "userHasPermission"}) 934 | public boolean userHasPermission(String userName, String permission, String world) { 935 | if (!(permissionsAvailable())) { 936 | return false; 937 | } 938 | ServicesManager sm = Bukkit.getServicesManager(); 939 | Permission p = sm.getRegistration(Permission.class).getProvider(); 940 | return p.has(world, userName, permission); 941 | } 942 | 943 | /** 944 | * Get a list of worlds a user has a given permission. 945 | * @param userName The user to check for a permission. 946 | * @param permission The permission to check. 947 | * @return A list of worlds the user has a permission under. 948 | */ 949 | @Action( 950 | aliases = {"worldsUserHasPerm", "worldUserHasPermission", "getWorldsUserHasPerm", "getWorldUserHasPermission"}) 951 | public List getWorldsUserHasPermission(String userName, String permission) { 952 | if (!(permissionsAvailable())) { 953 | return new ArrayList(0); 954 | } 955 | ServicesManager sm = Bukkit.getServicesManager(); 956 | Permission p = sm.getRegistration(Permission.class).getProvider(); 957 | List result = new ArrayList(); 958 | for (World world : Bukkit.getWorlds()) { 959 | String name = world.getName(); 960 | if (p.has(name, userName, permission)) { 961 | result.add(name); 962 | } 963 | } 964 | return result; 965 | } 966 | 967 | 968 | } 969 | -------------------------------------------------------------------------------- /src/me/neatmonster/spacebukkit/actions/SystemActions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of SpaceBukkit (http://spacebukkit.xereo.net/). 3 | * 4 | * SpaceBukkit is free software: you can redistribute it and/or modify it under the terms of the 5 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license as published by the Creative 6 | * Common organization, either version 3.0 of the license, or (at your option) any later version. 7 | * 8 | * SpaceBukkit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 9 | * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license for more details. 11 | * 12 | * You should have received a copy of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) 13 | * license along with this program. If not, see . 14 | */ 15 | package me.neatmonster.spacebukkit.actions; 16 | 17 | import java.io.File; 18 | import java.lang.management.GarbageCollectorMXBean; 19 | import java.lang.management.ManagementFactory; 20 | import java.util.LinkedHashMap; 21 | import java.util.LinkedList; 22 | import java.util.List; 23 | 24 | import me.neatmonster.spacebukkit.SpaceBukkit; 25 | import me.neatmonster.spacemodule.api.Action; 26 | import me.neatmonster.spacemodule.api.ActionHandler; 27 | 28 | /** 29 | * Actions handler for any System-related events 30 | */ 31 | public class SystemActions implements ActionHandler { 32 | 33 | /** 34 | * Gets the Operating System of the server machine 35 | * @return Operation System 36 | */ 37 | @Action( 38 | aliases = {"getArch", "arch"}) 39 | public String getArch() { 40 | return ManagementFactory.getOperatingSystemMXBean().getArch(); 41 | } 42 | 43 | /** 44 | * Gets the CPU Frequency 45 | * @return CPU Frequency 46 | */ 47 | @Action( 48 | aliases = {"getCpuFrequency", "cpuFrequency"}) 49 | public double getCpuFrequency() { 50 | return SpaceBukkit.getInstance().performanceMonitor.getCpuFrequency() / 1000000000D; 51 | } 52 | 53 | /** 54 | * Gets the current CPU Usage 55 | * @return CPU Usage 56 | */ 57 | @Action( 58 | aliases = {"getCpuUsage", "cpuUsage"}) 59 | public float getCpuUsage() { 60 | return SpaceBukkit.getInstance().performanceMonitor.getCpuUsage() * 100F; 61 | } 62 | 63 | /** 64 | * Gets the amount of Daemon threads currently created 65 | * @return Dameon threads created 66 | */ 67 | @Action( 68 | aliases = {"getDaemonThreads", "daemonThreads"}) 69 | public int getDaemonThreads() { 70 | return ManagementFactory.getThreadMXBean().getDaemonThreadCount(); 71 | } 72 | 73 | /** 74 | * Gets how much disk space is free on the server 75 | * @return Disk space that is used 76 | */ 77 | @Action( 78 | aliases = {"getDiskFreeSpace", "spaceFree"}) 79 | public long getDiskFreeSpace() { 80 | return new File(".").getFreeSpace(); 81 | } 82 | 83 | /** 84 | * Gets the total disk space on the server 85 | * @return Disk space 86 | */ 87 | @Action( 88 | aliases = {"getDiskSize", "spaceSize"}) 89 | public long getDiskSize() { 90 | return new File(".").getTotalSpace(); 91 | } 92 | 93 | /** 94 | * Gets the total disk usage on the server 95 | * @return Disk space that is free 96 | */ 97 | @Action( 98 | aliases = {"getDiskUsage", "spaceUsed"}) 99 | public long getDiskUsage() { 100 | return new File(".").getTotalSpace() - new File(".").getFreeSpace(); 101 | } 102 | 103 | /** 104 | * Gets the list of garbage collectors 105 | * @return Garbage collectors 106 | */ 107 | @Action( 108 | aliases = {"getGarbageCollectors", "garbageCollectors"}) 109 | public LinkedList> getGarbageCollectors() { 110 | final LinkedList> garbageCollectors = new LinkedList>(); 111 | for (final GarbageCollectorMXBean garbageCollector : ManagementFactory.getGarbageCollectorMXBeans()) { 112 | final LinkedHashMap gc = new LinkedHashMap(); 113 | gc.put("Name", garbageCollector.getName()); 114 | gc.put("CollectionCount", garbageCollector.getCollectionCount()); 115 | gc.put("CollectionTime", garbageCollector.getCollectionTime()); 116 | garbageCollectors.push(gc); 117 | } 118 | return garbageCollectors; 119 | } 120 | 121 | /** 122 | * Gets the input arguments used to start the toolkit 123 | * @return Input arguments 124 | */ 125 | @Action( 126 | aliases = {"getInputArguments", "inputArguments"}) 127 | public List getInputArguments() { 128 | return ManagementFactory.getRuntimeMXBean().getInputArguments(); 129 | } 130 | 131 | /** 132 | * Gets how much memory is currently free on the server 133 | * @return Memory free 134 | */ 135 | @Action( 136 | aliases = {"getJavaMemoryFree", "memoryFree"}) 137 | public long getJavaMemoryFree() { 138 | return Math.round((float)Runtime.getRuntime().freeMemory() / 1048576.0f); 139 | } 140 | 141 | /** 142 | * Gets how much memory will be used by the Java VM 143 | * @return Memory used by the Java VM 144 | */ 145 | @Action( 146 | aliases = {"getJavaMemoryMax", "memoryMax"}) 147 | public long getJavaMemoryMax() { 148 | return Math.round((float)Runtime.getRuntime().maxMemory() / 1048576.0f); 149 | } 150 | 151 | /** 152 | * Gets how much memory is allocated to the Java process 153 | * @return Memory allocated 154 | */ 155 | @Action( 156 | aliases = {"getJavaMemoryTotal", "memoryTotal"}) 157 | public long getJavaMemoryTotal() { 158 | return Math.round((float)Runtime.getRuntime().totalMemory() / 1048576.0f); 159 | } 160 | 161 | /** 162 | * Gets how much memory is currently being used by the Java VM 163 | * @return Memory used 164 | */ 165 | @Action( 166 | aliases = {"getJavaMemoryUsage", "memoryUsage"}) 167 | public long getJavaMemoryUsage() { 168 | return getJavaMemoryTotal() - getJavaMemoryFree(); 169 | } 170 | 171 | /** 172 | * Gets how many threads are currently loaded 173 | * @return Loaded threads 174 | */ 175 | @Action( 176 | aliases = {"getLiveThreads", "liveThreads"}) 177 | public int getLiveThreads() { 178 | return ManagementFactory.getThreadMXBean().getThreadCount(); 179 | } 180 | 181 | /** 182 | * Gets how many classes are currently loaded 183 | * @return Loaded classes 184 | */ 185 | @Action( 186 | aliases = {"getLoadedClasses", "loadedClasses"}) 187 | public int getLoadedClasses() { 188 | return ManagementFactory.getClassLoadingMXBean().getLoadedClassCount(); 189 | } 190 | 191 | /** 192 | * Gets how many CPU's are on the server 193 | * @return CPU's 194 | */ 195 | @Action( 196 | aliases = {"getNumCpus", "numCpus"}) 197 | public int getNumCpus() { 198 | return SpaceBukkit.getInstance().performanceMonitor.getNumCpus(); 199 | } 200 | 201 | /** 202 | * Gets the name of the OS the server is running on 203 | * @return OS Name 204 | */ 205 | @Action( 206 | aliases = {"getOsName", "osName"}) 207 | public String getOsName() { 208 | return SpaceBukkit.getInstance().performanceMonitor.getOsName(); 209 | } 210 | 211 | /** 212 | * Gets how many peak threads are currently active 213 | * @return Peak threads 214 | */ 215 | @Action( 216 | aliases = {"getPeakThreads", "peakThreads"}) 217 | public int getPeakThreads() { 218 | return ManagementFactory.getThreadMXBean().getPeakThreadCount(); 219 | } 220 | 221 | /** 222 | * Gets the amount of physical memory on the server that is free 223 | * @return Physical memory free 224 | */ 225 | @Action( 226 | aliases = {"getPhysicalMemoryFree", "physicalMemoryFree"}) 227 | public long getPhysicalMemoryFree() { 228 | return Math.round((float)SpaceBukkit.getInstance().performanceMonitor.getPhysicalMemoryFree() / 1048576.0f); 229 | } 230 | 231 | /** 232 | * Gets the total amount of physical memory on the server 233 | * @return Physical total memory 234 | */ 235 | @Action( 236 | aliases = {"getPhysicalMemoryTotal", "physicalMemoryTotal"}) 237 | public long getPhysicalMemoryTotal() { 238 | return Math.round((float)SpaceBukkit.getInstance().performanceMonitor.getPhysicalMemoryTotal() / 1048576.0f); 239 | } 240 | 241 | /** 242 | * Gets the amount of physical memory usage on the server 243 | * @return Physical memory usage 244 | */ 245 | @Action( 246 | aliases = {"getPhysicalMemoryUsage", "physicalMemoryUsage"}) 247 | public long getPhysicalMemoryUsage() { 248 | return (SpaceBukkit.getInstance().performanceMonitor.getPhysicalMemoryTotal() - SpaceBukkit 249 | .getInstance().performanceMonitor.getPhysicalMemoryFree()) / 1048576; 250 | } 251 | 252 | /** 253 | * Gets the PID of the process 254 | * @return PID 255 | */ 256 | @Action( 257 | aliases = {"getPid", "pid"}) 258 | public int getPid() { 259 | return SpaceBukkit.getInstance().performanceMonitor.getPid(); 260 | } 261 | 262 | /** 263 | * Gets the clock rate of the CPU 264 | * @return Clock rate 265 | */ 266 | @Action( 267 | aliases = {"getTicks", "ticks"}) 268 | public double getTicks() { 269 | return SpaceBukkit.getInstance().performanceMonitor.getClockRate(); 270 | } 271 | 272 | /** 273 | * Gets how many total classes there are 274 | * @return Total classes 275 | */ 276 | @Action( 277 | aliases = {"getTotalClasses", "totalClasses"}) 278 | public long getTotalClasses() { 279 | return ManagementFactory.getClassLoadingMXBean().getTotalLoadedClassCount(); 280 | } 281 | 282 | /** 283 | * Gets how many total threads there are 284 | * @return Total threads 285 | */ 286 | @Action( 287 | aliases = {"getTotalThreads", "totalThreads"}) 288 | public long getTotalThreads() { 289 | return ManagementFactory.getThreadMXBean().getTotalStartedThreadCount(); 290 | } 291 | 292 | /** 293 | * Gets how many unloaded classes there are 294 | * @return Unloaded classes 295 | */ 296 | @Action( 297 | aliases = {"getUnloadedClasses", "unloadedClasses"}) 298 | public long getUnloadedClasses() { 299 | return ManagementFactory.getClassLoadingMXBean().getUnloadedClassCount(); 300 | } 301 | 302 | /** 303 | * Gets how long the server has been running 304 | * @return Uptime 305 | */ 306 | @Action( 307 | aliases = {"getUpTime", "upTime"}) 308 | public long getUpTime() { 309 | return SpaceBukkit.getInstance().performanceMonitor.getUptime(); 310 | } 311 | 312 | /** 313 | * Runs the garbage collector 314 | * @return If successful 315 | */ 316 | @Action( 317 | aliases = {"runGarbageCollector", "garbageCollector"}) 318 | public boolean runGarbageCollector() { 319 | System.gc(); 320 | return true; 321 | } 322 | } 323 | -------------------------------------------------------------------------------- /src/me/neatmonster/spacebukkit/events/RequestEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of SpaceBukkit (http://spacebukkit.xereo.net/). 3 | * 4 | * SpaceBukkit is free software: you can redistribute it and/or modify it under the terms of the 5 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license as published by the Creative 6 | * Common organization, either version 3.0 of the license, or (at your option) any later version. 7 | * 8 | * SpaceBukkit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 9 | * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license for more details. 11 | * 12 | * You should have received a copy of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) 13 | * license along with this program. If not, see . 14 | */ 15 | package me.neatmonster.spacebukkit.events; 16 | 17 | import org.bukkit.event.Event; 18 | import org.bukkit.event.HandlerList; 19 | 20 | /** 21 | * Called when a object is interpreted 22 | */ 23 | public class RequestEvent extends Event { 24 | private static final HandlerList handlers = new HandlerList(); 25 | 26 | /** 27 | * Gets a list of Event Handlers 28 | * @return Event Handlers 29 | */ 30 | public static HandlerList getHandlerList() { 31 | return handlers; 32 | } 33 | 34 | private Object[] arguments; 35 | private String method; 36 | 37 | private Object result = null; 38 | 39 | /** 40 | * Creates a new RequestEvent 41 | * @param method Method that is being called 42 | * @param arguments Arguments for that method 43 | */ 44 | public RequestEvent(final String method, final Object[] arguments) { 45 | this.method = method; 46 | this.arguments = arguments; 47 | } 48 | 49 | /** 50 | * Gets the arguments of the method 51 | * @return Arguments 52 | */ 53 | public Object[] getArguments() { 54 | return arguments; 55 | } 56 | 57 | @Override 58 | public HandlerList getHandlers() { 59 | return handlers; 60 | } 61 | 62 | /** 63 | * Gets the method being called 64 | * @return Method 65 | */ 66 | public String getMethod() { 67 | return method; 68 | } 69 | 70 | /** 71 | * Gets the result of the method with the specified arguments. May be null 72 | * @return Result 73 | */ 74 | public Object getResult() { 75 | return result; 76 | } 77 | 78 | /** 79 | * Sets the arguments used 80 | * @param arguments New arguments 81 | */ 82 | public void setArguments(final Object[] arguments) { 83 | this.arguments = arguments; 84 | } 85 | 86 | /** 87 | * Sets the method used 88 | * @param method New method 89 | */ 90 | public void setMethod(final String method) { 91 | this.method = method; 92 | } 93 | 94 | /** 95 | * Sets the result 96 | * @param result New result 97 | */ 98 | public void setResult(final Object result) { 99 | this.result = result; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/me/neatmonster/spacebukkit/players/PlayerLogger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of SpaceBukkit (http://spacebukkit.xereo.net/). 3 | * 4 | * SpaceBukkit is free software: you can redistribute it and/or modify it under the terms of the 5 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license as published by the Creative Common organization, 6 | * either version 3.0 of the license, or (at your option) any later version. 7 | * 8 | * SpaceBukkit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied 9 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Attribution-NonCommercial-ShareAlike 10 | * Unported (CC BY-NC-SA) license for more details. 11 | * 12 | * You should have received a copy of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license along with 13 | * this program. If not, see . 14 | */ 15 | package me.neatmonster.spacebukkit.players; 16 | 17 | import java.io.File; 18 | import java.io.IOException; 19 | import java.util.Map; 20 | import java.util.TreeMap; 21 | 22 | import me.neatmonster.spacebukkit.SpaceBukkit; 23 | import me.neatmonster.spacebukkit.utilities.PropertiesFile; 24 | 25 | /** 26 | * Stores information about Player's actions 27 | */ 28 | public class PlayerLogger { 29 | private static TreeMap chats = new TreeMap(); 30 | private static TreeMap joins = new TreeMap(); 31 | private static long lastJoin; 32 | private static long lastQuit; 33 | private static TreeMap messages = new TreeMap(); 34 | private static TreeMap quits = new TreeMap(); 35 | 36 | /** 37 | * Adds a chat to the cache 38 | * @param playerName Player to add 39 | * @param message Message to add 40 | */ 41 | public static void addPlayerChat(final String playerName, final String message) { 42 | if (chats.keySet().size() > SpaceBukkit.getInstance().maxMessages) 43 | cleanPlayersChats(); 44 | final long time = System.currentTimeMillis(); 45 | chats.put(time, playerName); 46 | messages.put(time, message); 47 | } 48 | 49 | /** 50 | * Adds a join to the cache 51 | * @param playerName Player to add 52 | */ 53 | public static void addPlayerJoin(final String playerName) { 54 | lastJoin = System.currentTimeMillis(); 55 | if (joins.keySet().size() > SpaceBukkit.getInstance().maxJoins) 56 | cleanPlayersJoins(); 57 | joins.put(System.currentTimeMillis(), playerName); 58 | } 59 | 60 | /** 61 | * Adds a quit to the cache 62 | * @param playerName Player to add 63 | */ 64 | public static void addPlayerQuit(final String playerName) { 65 | lastQuit = System.currentTimeMillis(); 66 | if (quits.keySet().size() > SpaceBukkit.getInstance().maxQuits) 67 | cleanPlayersQuits(); 68 | quits.put(System.currentTimeMillis(), playerName); 69 | } 70 | 71 | /** 72 | * Clears all the player chats 73 | */ 74 | public static void cleanPlayersChats() { 75 | for (int x = chats.size() - SpaceBukkit.getInstance().maxMessages; x > 0; x--) { 76 | chats.remove(chats.firstKey()); 77 | messages.remove(messages.firstKey()); 78 | } 79 | } 80 | 81 | /** 82 | * Clears all the player joins 83 | */ 84 | public static void cleanPlayersJoins() { 85 | for (int x = joins.size() - SpaceBukkit.getInstance().maxJoins; x > 0; x--) 86 | joins.remove(joins.firstKey()); 87 | } 88 | 89 | /** 90 | * Clears all the player quits 91 | */ 92 | public static void cleanPlayersQuits() { 93 | for (int x = quits.size() - SpaceBukkit.getInstance().maxQuits; x > 0; x--) 94 | quits.remove(quits.firstKey()); 95 | } 96 | 97 | /** 98 | * Gets the case of a player as assigned by the panel 99 | * @param playerName Player to get 100 | * @return Modified name of the player 101 | */ 102 | public static String getCase(final String playerName) { 103 | try { 104 | final PropertiesFile propertiesFile = new PropertiesFile( 105 | new File("SpaceModule", "players.properties").getPath()); 106 | propertiesFile.load(); 107 | final String savedPlayerName = propertiesFile.getString(playerName.toLowerCase()); 108 | propertiesFile.save(); 109 | if (savedPlayerName != null && !savedPlayerName.equals("")) 110 | return savedPlayerName; 111 | } catch (IOException e) { 112 | e.printStackTrace(); 113 | } 114 | return playerName; 115 | } 116 | 117 | /** 118 | * Gets the last time a player joined the server 119 | * @return Last time a player joined 120 | */ 121 | public static long getLastJoin() { 122 | return lastJoin; 123 | } 124 | 125 | /** 126 | * Gets the last time a player quit the server 127 | * @return Last time a player quit 128 | */ 129 | public static long getLastQuit() { 130 | return lastQuit; 131 | } 132 | 133 | /** 134 | * Gets a map of player chats with a limit 135 | * @param limit Number of chats to include 136 | * @return Map of player chats 137 | */ 138 | public static Map getPlayersChats(final int limit) { 139 | final TreeMap results = new TreeMap(); 140 | int x = 0; 141 | for (final Long time : chats.descendingKeySet()) { 142 | if (x < limit) 143 | results.put(time, chats.get(time) + ": " + messages.get(time)); 144 | x++; 145 | } 146 | return results; 147 | } 148 | 149 | /** 150 | * Gets a map of player joins with a limit 151 | * @param limit Number of joins to include 152 | * @return Map of player joins 153 | */ 154 | public static Map getPlayersJoins(final int limit) { 155 | final TreeMap results = new TreeMap(); 156 | int x = 0; 157 | for (final Long time : joins.descendingKeySet()) { 158 | if (x < limit) 159 | results.put(time, joins.get(time)); 160 | x++; 161 | } 162 | return results; 163 | } 164 | 165 | /** 166 | * Gets a map of player quits with a limit 167 | * @param limit Number of quits to include 168 | * @return Map of player quits 169 | */ 170 | public static Map getPlayersQuits(final int limit) { 171 | final TreeMap results = new TreeMap(); 172 | int x = 0; 173 | for (final Long time : quits.descendingKeySet()) { 174 | if (x < limit) 175 | results.put(time, quits.get(time)); 176 | x++; 177 | } 178 | return results; 179 | } 180 | 181 | /** 182 | * Sets the case of a player 183 | * @param playerName Player's new case 184 | */ 185 | public static void setCase(final String playerName) { 186 | try { 187 | final PropertiesFile propertiesFile = new PropertiesFile( 188 | new File("SpaceModule", "players.properties").getPath()); 189 | propertiesFile.load(); 190 | propertiesFile.setString(playerName.toLowerCase(), playerName); 191 | propertiesFile.save(); 192 | } catch (IOException e) { 193 | e.printStackTrace(); 194 | } 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /src/me/neatmonster/spacebukkit/players/SBListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of SpaceBukkit (http://spacebukkit.xereo.net/). 3 | * 4 | * SpaceBukkit is free software: you can redistribute it and/or modify it under the terms of the 5 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license as published by the Creative 6 | * Common organization, either version 3.0 of the license, or (at your option) any later version. 7 | * 8 | * SpaceBukkit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 9 | * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license for more details. 11 | * 12 | * You should have received a copy of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) 13 | * license along with this program. If not, see . 14 | */ 15 | package me.neatmonster.spacebukkit.players; 16 | 17 | import me.neatmonster.spacebukkit.SpaceBukkit; 18 | 19 | import org.bukkit.Bukkit; 20 | import org.bukkit.event.EventHandler; 21 | import org.bukkit.event.Listener; 22 | import org.bukkit.event.player.AsyncPlayerChatEvent; 23 | import org.bukkit.event.player.PlayerJoinEvent; 24 | import org.bukkit.event.player.PlayerQuitEvent; 25 | import org.bukkit.event.server.ServerCommandEvent; 26 | 27 | /** 28 | * SpaceBukkit Event Listener 29 | */ 30 | public class SBListener implements Listener { 31 | 32 | /** 33 | * Creates a new SBListener 34 | * @param plugin Plugin Instance 35 | */ 36 | public SBListener(final SpaceBukkit plugin) { 37 | Bukkit.getPluginManager().registerEvents(this, plugin); 38 | } 39 | 40 | /** 41 | * Called when a player chats 42 | * @param event Relevant event details 43 | */ 44 | @EventHandler(ignoreCancelled = true) 45 | public void onPlayerChat(final AsyncPlayerChatEvent event) { 46 | PlayerLogger.addPlayerChat(event.getPlayer().getName(), event.getMessage()); 47 | } 48 | 49 | /** 50 | * Called when a player joins 51 | * @param event Relevant event details 52 | */ 53 | @EventHandler(ignoreCancelled = true) 54 | public void onPlayerJoin(final PlayerJoinEvent event) { 55 | PlayerLogger.addPlayerJoin(event.getPlayer().getName()); 56 | } 57 | 58 | /** 59 | * Called when a player quits 60 | * @param event Relevant event details 61 | */ 62 | @EventHandler(ignoreCancelled = true) 63 | public void onPlayerQuit(final PlayerQuitEvent event) { 64 | PlayerLogger.addPlayerQuit(event.getPlayer().getName()); 65 | } 66 | 67 | /** 68 | * Called when a server performs a command 69 | * @param event Relevant event details 70 | */ 71 | @EventHandler(ignoreCancelled = true) 72 | public void onServerCommand(final ServerCommandEvent event) { 73 | String cmd = event.getCommand(); 74 | if (cmd.startsWith("say") && !cmd.equalsIgnoreCase("say")) { 75 | final String message = cmd.substring(4); 76 | PlayerLogger.addPlayerChat("Server", message); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/me/neatmonster/spacebukkit/plugins/PluginsManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of SpaceBukkit (http://spacebukkit.xereo.net/). 3 | * 4 | * SpaceBukkit is free software: you can redistribute it and/or modify it under the terms of the 5 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license as published by the Creative Common organization, 6 | * either version 3.0 of the license, or (at your option) any later version. 7 | * 8 | * SpaceBukkit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied 9 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Attribution-NonCommercial-ShareAlike 10 | * Unported (CC BY-NC-SA) license for more details. 11 | * 12 | * You should have received a copy of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license along with 13 | * this program. If not, see . 14 | */ 15 | package me.neatmonster.spacebukkit.plugins; 16 | 17 | import java.io.File; 18 | import java.io.IOException; 19 | import java.lang.reflect.InvocationTargetException; 20 | import java.lang.reflect.Method; 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | import org.bukkit.Bukkit; 25 | import org.bukkit.configuration.file.YamlConfiguration; 26 | import org.bukkit.plugin.Plugin; 27 | import org.bukkit.plugin.java.JavaPlugin; 28 | 29 | /** 30 | * Manages Plugins and interacts with BukGet 31 | */ 32 | public class PluginsManager { 33 | public static final File JARS_FILE = new File("SpaceModule" + File.separator + "SpaceBukkit", 34 | "jars.yml"); 35 | 36 | public static List pluginsNames = new ArrayList(); 37 | 38 | /** 39 | * Gets the Jar of a plugin 40 | * @param p 41 | * @return Jar File the plugin's code is contained in 42 | */ 43 | public static File getJAR(Plugin p) { 44 | JavaPlugin plugin; 45 | if(p instanceof JavaPlugin) 46 | plugin = (JavaPlugin) p; 47 | else 48 | return null; 49 | 50 | try { 51 | final Class[] methodArgs = {}; 52 | final Method method = JavaPlugin.class.getDeclaredMethod("getFile", methodArgs); 53 | method.setAccessible(true); 54 | final Object[] classArgs = {}; 55 | return (File) method.invoke(plugin, classArgs); 56 | } catch (final SecurityException e) { 57 | e.printStackTrace(); 58 | } catch (final NoSuchMethodException e) { 59 | e.printStackTrace(); 60 | } catch (final IllegalArgumentException e) { 61 | e.printStackTrace(); 62 | } catch (final IllegalAccessException e) { 63 | e.printStackTrace(); 64 | } catch (final InvocationTargetException e) { 65 | e.printStackTrace(); 66 | } 67 | return null; 68 | } 69 | 70 | /** 71 | * Creates a new PluginsManager 72 | */ 73 | public PluginsManager() { 74 | new Thread(new PluginsRequester()).start(); 75 | final YamlConfiguration configuration = YamlConfiguration.loadConfiguration(JARS_FILE); 76 | for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) { 77 | if (plugin == null) { 78 | continue; 79 | } 80 | final File jar = getJAR(plugin); 81 | if (jar != null) 82 | configuration.set(plugin.getDescription().getName().toLowerCase().replace(" ", ""), 83 | jar.getName()); 84 | } 85 | try { 86 | configuration.save(JARS_FILE); 87 | } catch (IOException e) { 88 | e.printStackTrace(); 89 | } 90 | } 91 | 92 | /** 93 | * Checks if the manager knows a plugins JAR location 94 | * @param pluginName Plugin to check 95 | * @return If the manager knows where a plugins JAR is 96 | */ 97 | public boolean contains(String pluginName) { 98 | pluginName = pluginName.toLowerCase(); 99 | if (pluginsNames.contains(pluginName)) 100 | return true; 101 | if (pluginsNames.contains(pluginName.replace(" ", ""))) 102 | return true; 103 | if (pluginsNames.contains(pluginName.replace(" ", "_"))) 104 | return true; 105 | if (pluginsNames.contains(pluginName.replace(" ", "-"))) 106 | return true; 107 | Plugin plugin = Bukkit.getPluginManager().getPlugin(pluginName); 108 | if (plugin != null) { 109 | final YamlConfiguration configuration = YamlConfiguration.loadConfiguration(JARS_FILE); 110 | final File jar = getJAR(plugin); 111 | if (jar != null) 112 | configuration.set(plugin.getDescription().getName().toLowerCase().replace(" ", ""), 113 | jar.getName()); 114 | try { 115 | configuration.save(JARS_FILE); 116 | } catch (IOException e) { 117 | e.printStackTrace(); 118 | } 119 | return true; 120 | } 121 | return false; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/me/neatmonster/spacebukkit/plugins/PluginsRequester.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of SpaceBukkit (http://spacebukkit.xereo.net/). 3 | * 4 | * SpaceBukkit is free software: you can redistribute it and/or modify it under the terms of the 5 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license as published by the Creative 6 | * Common organization, either version 3.0 of the license, or (at your option) any later version. 7 | * 8 | * SpaceRTK is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 9 | * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license for more details. 11 | * 12 | * You should have received a copy of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) 13 | * license along with this program. If not, see . 14 | */ 15 | package me.neatmonster.spacebukkit.plugins; 16 | 17 | import java.io.BufferedReader; 18 | import java.io.InputStreamReader; 19 | import java.net.URL; 20 | import java.net.URLConnection; 21 | import java.util.List; 22 | 23 | import me.neatmonster.spacebukkit.SpaceBukkit; 24 | 25 | import org.json.simple.JSONArray; 26 | import org.json.simple.JSONValue; 27 | import org.json.simple.JSONObject; 28 | 29 | /** 30 | * Requests the plugins from BukGet 31 | */ 32 | public class PluginsRequester implements Runnable { 33 | 34 | @Override 35 | @SuppressWarnings("unchecked") 36 | public void run() { 37 | //TODO: Remove class 38 | /*try { 39 | final URLConnection connection = new URL("http://api.bukget.org/api2/bukkit/").openConnection(); 40 | final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream())); 41 | final StringBuffer stringBuffer = new StringBuffer(); 42 | String line; 43 | while ((line = bufferedReader.readLine()) != null) 44 | stringBuffer.append(line); 45 | bufferedReader.close(); 46 | List apiResponse = (JSONArray) JSONValue.parse(stringBuffer.toString()); 47 | 48 | //PluginsManager.pluginsNames = (JSONArray) JSONValue.parse(stringBuffer.toString()); 49 | SpaceBukkit.getInstance().getLogger().info("Database contains " 50 | + PluginsManager.pluginsNames.size() + " plugins."); 51 | } catch (final Exception e) { 52 | e.printStackTrace(); 53 | } 54 | PluginsManager.pluginsNames = new ArrayList(); 55 | */ 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/me/neatmonster/spacebukkit/system/PerformanceMonitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of SpaceBukkit (http://spacebukkit.xereo.net/). 3 | * 4 | * SpaceBukkit is free software: you can redistribute it and/or modify it under the terms of the 5 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license as published by the Creative 6 | * Common organization, either version 3.0 of the license, or (at your option) any later version. 7 | * 8 | * SpaceBukkit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 9 | * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license for more details. 11 | * 12 | * You should have received a copy of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) 13 | * license along with this program. If not, see . 14 | */ 15 | package me.neatmonster.spacebukkit.system; 16 | 17 | import java.util.TimerTask; 18 | 19 | import me.neatmonster.spacebukkit.SpaceBukkit; 20 | 21 | import org.bukkit.Bukkit; 22 | import org.bukkit.World; 23 | 24 | import com.jezhumble.javasysmon.CpuTimes; 25 | import com.jezhumble.javasysmon.JavaSysMon; 26 | 27 | /** 28 | * Performance Monitor 29 | */ 30 | public class PerformanceMonitor extends TimerTask { 31 | private double clockRate = 0D; 32 | private JavaSysMon monitor = null; 33 | 34 | private CpuTimes now = null; 35 | private CpuTimes previous = null; 36 | private final World world = Bukkit.getWorlds().get(0); 37 | 38 | /** 39 | * Creates a new Performance Monitor 40 | */ 41 | public PerformanceMonitor() { 42 | monitor = new JavaSysMon(); 43 | if (!monitor.supportedPlatform()) { 44 | final SpaceBukkit spaceBukkit = SpaceBukkit.getInstance(); 45 | spaceBukkit.getLogger().severe("Performance monitoring unsupported!"); 46 | monitor = null; 47 | } else 48 | now = monitor.cpuTimes(); 49 | } 50 | 51 | /** 52 | * Gets the clock rate of the CPU 53 | * @return Clock rate 54 | */ 55 | public double getClockRate() { 56 | return clockRate; 57 | } 58 | 59 | /** 60 | * Gets the CPU Frequency 61 | * @return CPU Frequency 62 | */ 63 | public long getCpuFrequency() { 64 | if (monitor != null) 65 | return monitor.cpuFrequencyInHz(); 66 | return 0L; 67 | } 68 | 69 | /** 70 | * Gets the current CPU usage 71 | * @return CPU Usage 72 | */ 73 | public float getCpuUsage() { 74 | if (monitor != null && previous != null && now != null) 75 | return now.getCpuUsage(previous); 76 | return 0F; 77 | } 78 | 79 | /** 80 | * Gets the number of CPU's 81 | * @return Number of CPU's 82 | */ 83 | public int getNumCpus() { 84 | if (monitor != null) 85 | return monitor.numCpus(); 86 | return 0; 87 | } 88 | 89 | /** 90 | * Gets the name of the OS 91 | * @return OS Name 92 | */ 93 | public String getOsName() { 94 | if (monitor != null) 95 | return monitor.osName(); 96 | return ""; 97 | } 98 | 99 | /** 100 | * Gets how much Physical Memory is Free 101 | * @return Physical Memory free 102 | */ 103 | public long getPhysicalMemoryFree() { 104 | if (monitor != null) 105 | return monitor.physical().getFreeBytes(); 106 | return 0L; 107 | } 108 | 109 | /** 110 | * Gets how much Physical Memory there is total 111 | * @return Physical Memory total 112 | */ 113 | public long getPhysicalMemoryTotal() { 114 | if (monitor != null) 115 | return monitor.physical().getTotalBytes(); 116 | return 0L; 117 | } 118 | 119 | /** 120 | * Gets the PID of the server 121 | * @return PID 122 | */ 123 | public int getPid() { 124 | if (monitor != null) 125 | return monitor.currentPid(); 126 | return 0; 127 | } 128 | 129 | /** 130 | * Gets the Uptime of the server, in seconds 131 | * @return Uptime of the server 132 | */ 133 | public long getUptime() { 134 | if (monitor != null) 135 | return monitor.uptimeInSeconds(); 136 | return 0L; 137 | } 138 | 139 | /** 140 | * Stops the monitor 141 | */ 142 | public void infanticide() { 143 | if (monitor != null) 144 | monitor.infanticide(); 145 | } 146 | 147 | @Override 148 | public void run() { 149 | final long startMillis = System.currentTimeMillis(); 150 | final long startTicks = world.getFullTime(); 151 | final Runnable task = new Runnable() { 152 | @Override 153 | public void run() { 154 | final long endMillis = System.currentTimeMillis(); 155 | final long endTicks = world.getFullTime(); 156 | final long elapsedMillis = endMillis - startMillis; 157 | final long elapsedTicks = endTicks - startTicks; 158 | clockRate = elapsedTicks / (elapsedMillis / 1000D); 159 | } 160 | }; 161 | Bukkit.getScheduler().scheduleSyncDelayedTask(SpaceBukkit.getInstance(), task, 100); 162 | if (monitor != null) { 163 | previous = now; 164 | now = monitor.cpuTimes(); 165 | } 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/me/neatmonster/spacebukkit/utilities/ANSI.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of SpaceBukkit (http://spacebukkit.xereo.net/). 3 | * 4 | * SpaceBukkit is free software: you can redistribute it and/or modify it under the terms of the 5 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license as published by the Creative Common organization, 6 | * either version 3.0 of the license, or (at your option) any later version. 7 | * 8 | * SpaceBukkit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied 9 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Attribution-NonCommercial-ShareAlike 10 | * Unported (CC BY-NC-SA) license for more details. 11 | * 12 | * You should have received a copy of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license along with 13 | * this program. If not, see . 14 | */ 15 | package me.neatmonster.spacebukkit.utilities; 16 | 17 | import java.util.LinkedList; 18 | import java.util.List; 19 | 20 | /** 21 | * Set of ANSI color strings 22 | */ 23 | public class ANSI { 24 | 25 | /** 26 | * Represents Background Black 27 | */ 28 | public static final String BACKGROUND_BLACK = "\u001B[40m"; 29 | /** 30 | * Represents Background Blue 31 | */ 32 | public static final String BACKGROUND_BLUE = "\u001B[44m"; 33 | /** 34 | * Represents Background Cyan 35 | */ 36 | public static final String BACKGROUND_CYAN = "\u001B[46m"; 37 | /** 38 | * Represents Background Green 39 | */ 40 | public static final String BACKGROUND_GREEN = "\u001B[42m"; 41 | /** 42 | * Represents Background Magenta 43 | */ 44 | public static final String BACKGROUND_MAGENTA = "\u001B[45m"; 45 | /** 46 | * Represents Background Red 47 | */ 48 | public static final String BACKGROUND_RED = "\u001B[41m"; 49 | /** 50 | * Represents Background White 51 | */ 52 | public static final String BACKGROUND_WHITE = "\u001B[47m"; 53 | /** 54 | * Represents Background Yellow 55 | */ 56 | public static final String BACKGROUND_YELLOW = "\u001B[43m"; 57 | /** 58 | * Represents Black 59 | */ 60 | public static final String BLACK = "\u001B[30m"; 61 | /** 62 | * Represents Blink 63 | */ 64 | public static final String BLINK = "\u001B[5m"; 65 | /** 66 | * Represents Blue 67 | */ 68 | public static final String BLUE = "\u001B[34m"; 69 | /** 70 | * Represents Cyan 71 | */ 72 | public static final String CYAN = "\u001B[36m"; 73 | /** 74 | * Represents Green 75 | */ 76 | public static final String GREEN = "\u001B[32m"; 77 | /** 78 | * Represents High Intensity 79 | */ 80 | public static final String HIGH_INTENSITY = "\u001B[1m"; 81 | /** 82 | * Represents Invisible Text 83 | */ 84 | public static final String INVISIBLE_TEXT = "\u001B[8m"; 85 | /** 86 | * Represents Italics 87 | */ 88 | public static final String ITALIC = "\u001B[3m"; 89 | /** 90 | * Represents Low Intensity 91 | */ 92 | public static final String LOW_INTESITY = "\u001B[2m"; 93 | /** 94 | * Represents Magenta 95 | */ 96 | public static final String MAGENTA = "\u001B[35m"; 97 | /** 98 | * Represents Rapid Blink 99 | */ 100 | public static final String RAPID_BLINK = "\u001B[6m"; 101 | /** 102 | * Represents Red 103 | */ 104 | public static final String RED = "\u001B[31m"; 105 | /** 106 | * Represents Reverse Video 107 | */ 108 | public static final String REVERSE_VIDEO = "\u001B[7m"; 109 | /** 110 | * Represents Sane 111 | */ 112 | public static final String SANE = "\u001B[0m"; 113 | /** 114 | * Represents Underline 115 | */ 116 | public static final String UNDERLINE = "\u001B[4m"; 117 | /** 118 | * Represents White 119 | */ 120 | public static final String WHITE = "\u001B[37m"; 121 | /** 122 | * Represents Yellow 123 | */ 124 | public static final String YELLOW = "\u001B[33m"; 125 | 126 | /** 127 | * Converts all colors from ANSI to Non-ANSI 128 | * @param string Input 129 | * @return Non ANSI string 130 | */ 131 | public static String noANSI(String string) { 132 | final List characters = new LinkedList(); 133 | characters.add(SANE); 134 | characters.add(HIGH_INTENSITY); 135 | characters.add(LOW_INTESITY); 136 | characters.add(ITALIC); 137 | characters.add(UNDERLINE); 138 | characters.add(BLINK); 139 | characters.add(RAPID_BLINK); 140 | characters.add(REVERSE_VIDEO); 141 | characters.add(INVISIBLE_TEXT); 142 | characters.add(BLACK); 143 | characters.add(RED); 144 | characters.add(GREEN); 145 | characters.add(YELLOW); 146 | characters.add(BLUE); 147 | characters.add(MAGENTA); 148 | characters.add(CYAN); 149 | characters.add(WHITE); 150 | characters.add(BACKGROUND_BLACK); 151 | characters.add(BACKGROUND_RED); 152 | characters.add(BACKGROUND_GREEN); 153 | characters.add(BACKGROUND_YELLOW); 154 | characters.add(BACKGROUND_BLUE); 155 | characters.add(BACKGROUND_MAGENTA); 156 | characters.add(BACKGROUND_CYAN); 157 | characters.add(BACKGROUND_WHITE); 158 | for (final String ansi : characters) 159 | string = string.replace(ansi, ""); 160 | return string; 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /src/me/neatmonster/spacebukkit/utilities/PropertiesFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of SpaceBukkit (http://spacebukkit.xereo.net/). 3 | * 4 | * SpaceBukkit is free software: you can redistribute it and/or modify it under the terms of the 5 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license as published by the Creative Common organization, 6 | * either version 3.0 of the license, or (at your option) any later version. 7 | * 8 | * SpaceBukkit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied 9 | * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Attribution-NonCommercial-ShareAlike 10 | * Unported (CC BY-NC-SA) license for more details. 11 | * 12 | * You should have received a copy of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license along with 13 | * this program. If not, see . 14 | */ 15 | package me.neatmonster.spacebukkit.utilities; 16 | 17 | import java.io.BufferedReader; 18 | import java.io.File; 19 | import java.io.FileInputStream; 20 | import java.io.FileNotFoundException; 21 | import java.io.FileOutputStream; 22 | import java.io.FileReader; 23 | import java.io.IOException; 24 | import java.io.InputStreamReader; 25 | import java.io.OutputStream; 26 | import java.io.PrintStream; 27 | import java.io.UnsupportedEncodingException; 28 | import java.util.ArrayList; 29 | import java.util.ConcurrentModificationException; 30 | import java.util.HashMap; 31 | import java.util.List; 32 | import java.util.Map; 33 | 34 | import me.neatmonster.spacebukkit.SpaceBukkit; 35 | 36 | /** 37 | * Used for accessing and creating .[properties] files, reads them as utf-8, saves as utf-8. 38 | * Internationalization is key importance especially for character codes. 39 | * 40 | * @author Nijikokun 41 | * @version 1.0.4, %G% 42 | */ 43 | public final class PropertiesFile { 44 | private final String fileName; 45 | private final List lines = new ArrayList(); 46 | private final Map props = new HashMap(); 47 | 48 | /** 49 | * Creates or opens a properties file using specified filename 50 | * 51 | * @param fileName 52 | */ 53 | public PropertiesFile(final String fileName) { 54 | this.fileName = fileName; 55 | final File file = new File(fileName); 56 | 57 | if (file.exists()) 58 | try { 59 | load(); 60 | } catch (final IOException ex) { 61 | SpaceBukkit.getInstance().getLogger().severe("[PropertiesFile] Unable to load " + fileName + "!"); 62 | } 63 | else 64 | save(); 65 | } 66 | 67 | /** 68 | * Checks to see if the .[properties] file contains the given key. 69 | * 70 | * @param var 71 | * The key we are going to be checking the existance of. 72 | * @return Boolean - True if the key exists, false if it cannot be found. 73 | */ 74 | public boolean containsKey(final String var) { 75 | for (final String line : lines) { 76 | if (line.trim().length() == 0) 77 | continue; 78 | 79 | if (line.charAt(0) == '#') 80 | continue; 81 | 82 | if (line.contains("=")) { 83 | final int delimPosition = line.indexOf('='); 84 | final String key = line.substring(0, delimPosition); 85 | 86 | if (key.equals(var)) 87 | return true; 88 | } else 89 | continue; 90 | } 91 | 92 | return false; 93 | } 94 | 95 | /** 96 | * Returns the value of the key given in a Boolean, 97 | * however we do not set a string if no key is found. 98 | * 99 | * @see #getProperty(String var) 100 | * @param key 101 | * The key we will retrieve the property from, if no key is found default to 102 | * false 103 | */ 104 | public boolean getBoolean(final String key) { 105 | if (containsKey(key)) 106 | return Boolean.parseBoolean(getProperty(key)); 107 | 108 | return false; 109 | } 110 | 111 | /** 112 | * Returns the boolean value of a key 113 | * 114 | * @see #setBoolean(String key, boolean value) 115 | * @param key 116 | * The key that we will be grabbing the value from, if no value is found set and return 117 | * value 118 | * @param value 119 | * The default value that we will be setting if no prior key is found. 120 | * @return Boolean - Either we will return the default value or a prior existing value depending on 121 | * existance. 122 | */ 123 | public boolean getBoolean(final String key, final boolean value) { 124 | if (containsKey(key)) 125 | return Boolean.parseBoolean(getProperty(key)); 126 | 127 | setBoolean(key, value); 128 | return value; 129 | } 130 | 131 | /** 132 | * Returns the value of the key given in a Double, 133 | * however we do not set a string if no key is found. 134 | * 135 | * @see #getProperty(String var) 136 | * @param key 137 | * The key we will retrieve the property from, if no key is found default to 138 | * 0.0 139 | */ 140 | public double getDouble(final String key) { 141 | if (containsKey(key)) 142 | return Double.parseDouble(getProperty(key)); 143 | 144 | return 0; 145 | } 146 | 147 | /** 148 | * Returns the double value of a key 149 | * 150 | * @see #setDouble(String key, double value) 151 | * @param key 152 | * The key that we will be grabbing the value from, if no value is found set and return 153 | * value 154 | * @param value 155 | * The default value that we will be setting if no prior key is found. 156 | * @return Double - Either we will return the default value or a prior existing value depending on 157 | * existance. 158 | */ 159 | public double getDouble(final String key, final double value) { 160 | if (containsKey(key)) 161 | return Double.parseDouble(getProperty(key)); 162 | 163 | setDouble(key, value); 164 | return value; 165 | } 166 | 167 | /** 168 | * Returns the value of the key given in a Integer, 169 | * however we do not set a string if no key is found. 170 | * 171 | * @see #getProperty(String var) 172 | * @param key 173 | * The key we will retrieve the property from, if no key is found default to 0 174 | */ 175 | public int getInt(final String key) { 176 | if (containsKey(key)) 177 | return Integer.parseInt(getProperty(key)); 178 | 179 | return 0; 180 | } 181 | 182 | /** 183 | * Returns the int value of a key 184 | * 185 | * @see #setInt(String key, int value) 186 | * @param key 187 | * The key that we will be grabbing the value from, if no value is found set and return 188 | * value 189 | * @param value 190 | * The default value that we will be setting if no prior key is found. 191 | * @return Integer - Either we will return the default value or a prior existing value depending on 192 | * existance. 193 | */ 194 | public int getInt(final String key, final int value) { 195 | if (containsKey(key)) 196 | return Integer.parseInt(getProperty(key)); 197 | 198 | setInt(key, value); 199 | return value; 200 | 201 | } 202 | 203 | /** 204 | * Returns the value of the key given in a Long, 205 | * however we do not set a string if no key is found. 206 | * 207 | * @see #getProperty(String var) 208 | * @param key 209 | * The key we will retrieve the property from, if no key is found default to 0L 210 | */ 211 | public long getLong(final String key) { 212 | if (containsKey(key)) 213 | return Long.parseLong(getProperty(key)); 214 | 215 | return 0; 216 | } 217 | 218 | /** 219 | * Returns the long value of a key 220 | * 221 | * @see #setLong(String key, long value) 222 | * @param key 223 | * The key that we will be grabbing the value from, if no value is found set and return 224 | * value 225 | * @param value 226 | * The default value that we will be setting if no prior key is found. 227 | * @return Long - Either we will return the default value or a prior existing value depending on 228 | * existance. 229 | */ 230 | public long getLong(final String key, final long value) { 231 | if (containsKey(key)) 232 | return Long.parseLong(getProperty(key)); 233 | 234 | setLong(key, value); 235 | return value; 236 | } 237 | 238 | /** 239 | * Checks to see if this key exists in the .[properties] file. 240 | * 241 | * @param var 242 | * The key we are grabbing the value of. 243 | * @return java.lang.String - True if the key exists, false if it cannot be found. 244 | */ 245 | public String getProperty(final String var) { 246 | for (final String line : lines) { 247 | if (line.trim().length() == 0) 248 | continue; 249 | if (line.charAt(0) == '#') 250 | continue; 251 | 252 | if (line.contains("=")) { 253 | final int delimPosition = line.indexOf('='); 254 | final String key = line.substring(0, delimPosition).trim(); 255 | final String value = line.substring(delimPosition + 1); 256 | 257 | if (key.equals(var)) 258 | return value; 259 | } else 260 | continue; 261 | } 262 | 263 | return ""; 264 | } 265 | 266 | /** 267 | * Returns the value of the key given as a String, 268 | * however we do not set a string if no key is found. 269 | * 270 | * @see #getProperty(java.lang.String) 271 | * @param key 272 | * The key we will retrieve the property from, if no key is found default to "" 273 | * or empty. 274 | */ 275 | public String getString(final String key) { 276 | if (containsKey(key)) 277 | return getProperty(key); 278 | 279 | return ""; 280 | } 281 | 282 | /** 283 | * Returns the value of the key given as a String. 284 | * If it is not found, it will invoke saving the default value to the properties file. 285 | * 286 | * @see #setString(java.lang.String, java.lang.String) 287 | * @see #getProperty(java.lang.String) 288 | * @param key 289 | * The key that we will be grabbing the value from, if no value is found set and return 290 | * value 291 | * @param value 292 | * The default value that we will be setting if no prior key is found. 293 | * @return java.lang.String Either we will return the default value or a prior existing value depending on 294 | * existance. 295 | */ 296 | public String getString(final String key, final String value) { 297 | if (containsKey(key)) 298 | return getProperty(key); 299 | 300 | setString(key, value); 301 | return value; 302 | } 303 | 304 | /** 305 | * Checks the existance of a key. 306 | * 307 | * @see #containsKey(java.lang.String) 308 | * @param key 309 | * The key in question of existance. 310 | * @return Boolean - True for existance, false for key found. 311 | */ 312 | public boolean keyExists(final String key) { 313 | try { 314 | return containsKey(key) ? true : false; 315 | } catch (final Exception ex) { 316 | return false; 317 | } 318 | } 319 | 320 | /** 321 | * The loader for property files, it reads the file as UTF8 or converts the string into UTF8. 322 | * Used for simple runthrough's, loading, or reloading of the file. 323 | * 324 | * @throws IOException 325 | */ 326 | public void load() throws IOException { 327 | BufferedReader reader; 328 | reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), "UTF8")); 329 | String line; 330 | 331 | // Clear the file & unwritten properties 332 | lines.clear(); 333 | props.clear(); 334 | 335 | // Begin reading the file. 336 | while ((line = reader.readLine()) != null) { 337 | line = new String(line.getBytes(), "UTF-8"); 338 | char c = 0; 339 | int pos = 0; 340 | 341 | while (pos < line.length() && Character.isWhitespace(c = line.charAt(pos))) 342 | pos++; 343 | 344 | if (line.length() - pos == 0 || line.charAt(pos) == '#' || line.charAt(pos) == '!') { 345 | lines.add(line); 346 | continue; 347 | } 348 | 349 | final int start = pos; 350 | final boolean needsEscape = line.indexOf('\\', pos) != -1; 351 | final StringBuffer key = needsEscape ? new StringBuffer() : null; 352 | 353 | while (pos < line.length() && !Character.isWhitespace(c = line.charAt(pos++)) && c != '=' && c != ':') 354 | if (needsEscape && c == '\\') { 355 | if (pos == line.length()) { 356 | line = reader.readLine(); 357 | 358 | if (line == null) 359 | line = ""; 360 | 361 | pos = 0; 362 | 363 | while (pos < line.length() && Character.isWhitespace(c = line.charAt(pos))) 364 | pos++; 365 | } else { 366 | c = line.charAt(pos++); 367 | 368 | switch (c) { 369 | case 'n': 370 | key.append('\n'); 371 | break; 372 | case 't': 373 | key.append('\t'); 374 | break; 375 | case 'r': 376 | key.append('\r'); 377 | break; 378 | case 'u': 379 | if (pos + 4 <= line.length()) { 380 | final char uni = (char) Integer.parseInt(line.substring(pos, pos + 4), 16); 381 | key.append(uni); 382 | pos += 4; 383 | } 384 | 385 | break; 386 | default: 387 | key.append(c); 388 | break; 389 | } 390 | } 391 | } else if (needsEscape) 392 | key.append(c); 393 | 394 | final boolean isDelim = c == ':' || c == '='; 395 | String keyString; 396 | 397 | if (needsEscape) 398 | keyString = key.toString(); 399 | else if (isDelim || Character.isWhitespace(c)) 400 | keyString = line.substring(start, pos - 1); 401 | else 402 | keyString = line.substring(start, pos); 403 | 404 | while (pos < line.length() && Character.isWhitespace(c = line.charAt(pos))) 405 | pos++; 406 | 407 | if (!isDelim && (c == ':' || c == '=')) { 408 | pos++; 409 | 410 | while (pos < line.length() && Character.isWhitespace(c = line.charAt(pos))) 411 | pos++; 412 | } 413 | 414 | // Short-circuit if no escape chars found. 415 | if (!needsEscape) { 416 | lines.add(line); 417 | continue; 418 | } 419 | 420 | // Escape char found so iterate through the rest of the line. 421 | final StringBuilder element = new StringBuilder(line.length() - pos); 422 | while (pos < line.length()) { 423 | c = line.charAt(pos++); 424 | if (c == '\\') { 425 | if (pos == line.length()) { 426 | line = reader.readLine(); 427 | 428 | if (line == null) 429 | break; 430 | 431 | pos = 0; 432 | while (pos < line.length() && Character.isWhitespace(c = line.charAt(pos))) 433 | pos++; 434 | element.ensureCapacity(line.length() - pos + element.length()); 435 | } else { 436 | c = line.charAt(pos++); 437 | switch (c) { 438 | case 'n': 439 | element.append('\n'); 440 | break; 441 | case 't': 442 | element.append('\t'); 443 | break; 444 | case 'r': 445 | element.append('\r'); 446 | break; 447 | case 'u': 448 | if (pos + 4 <= line.length()) { 449 | final char uni = (char) Integer.parseInt(line.substring(pos, pos + 4), 16); 450 | element.append(uni); 451 | pos += 4; 452 | } 453 | break; 454 | default: 455 | element.append(c); 456 | break; 457 | } 458 | } 459 | } else 460 | element.append(c); 461 | } 462 | lines.add(keyString + "=" + element.toString()); 463 | } 464 | 465 | reader.close(); 466 | } 467 | 468 | /** 469 | * Remove a key from the file if it exists. 470 | * This will save() which will invoke a load() on the file. 471 | * 472 | * @see #save() 473 | * @param var 474 | * The key that will be removed from the file 475 | */ 476 | public void removeKey(final String var) { 477 | Boolean changed = false; 478 | 479 | if (props.containsKey(var)) { 480 | props.remove(var); 481 | changed = true; 482 | } 483 | 484 | try { 485 | for (int i = 0; i < lines.size(); i++) { 486 | final String line = lines.get(i); 487 | 488 | if (line.trim().length() == 0) 489 | continue; 490 | 491 | if (line.charAt(0) == '#') 492 | continue; 493 | 494 | if (line.contains("=")) { 495 | final int delimPosition = line.indexOf('='); 496 | final String key = line.substring(0, delimPosition).trim(); 497 | 498 | if (key.equals(var)) { 499 | lines.remove(i); 500 | changed = true; 501 | } 502 | } else 503 | continue; 504 | } 505 | } catch (final ConcurrentModificationException concEx) { 506 | removeKey(var); 507 | return; 508 | } 509 | 510 | // Save on change 511 | if (changed) 512 | save(); 513 | } 514 | 515 | /** 516 | * Returns a Map of all key=value properties in the file as 517 | * <key (java.lang.String), value (java.lang.String)>
518 | *
519 | * Example: 520 | *
521 | * 522 | *
523 |      * PropertiesFile settings = new PropertiesFile("settings.properties");
524 |      * Map<String, String> mappedSettings;
525 |      *
526 |      * try {
527 |      *     mappedSettings = settings.returnMap();
528 |      * } catch (Exception ex) {
529 |      *     log.info("Failed mapping settings.properties");
530 |      * }
531 |      * 
532 | * 533 | *
534 | * 535 | * @return map - Simple Map HashMap of the entire key=value as 536 | * <key (java.lang.String), value (java.lang.String)> 537 | * @throws Exception 538 | * If the properties file doesn't exist. 539 | */ 540 | public Map returnMap() throws Exception { 541 | final Map map = new HashMap(); 542 | final BufferedReader reader = new BufferedReader(new FileReader(fileName)); 543 | String line; 544 | 545 | while ((line = reader.readLine()) != null) { 546 | if (line.trim().length() == 0) 547 | continue; 548 | 549 | if (line.charAt(0) == '#') 550 | continue; 551 | 552 | if (line.contains("=")) { 553 | final int delimPosition = line.indexOf('='); 554 | final String key = line.substring(0, delimPosition).trim(); 555 | final String value = line.substring(delimPosition + 1).trim(); 556 | map.put(key, value); 557 | } else 558 | continue; 559 | } 560 | 561 | reader.close(); 562 | return map; 563 | } 564 | 565 | /** 566 | * Writes out the key=value properties that were changed into 567 | * a .[properties] file in UTF8. 568 | * 569 | * @see #load() 570 | */ 571 | public void save() { 572 | OutputStream os = null; 573 | 574 | try { 575 | os = new FileOutputStream(new File(fileName)); 576 | } catch (final FileNotFoundException ex) { 577 | SpaceBukkit.getInstance().getLogger().severe("[PropertiesFile] Unable to open " + fileName + "!"); 578 | } 579 | 580 | PrintStream ps = null; 581 | try { 582 | ps = new PrintStream(os, true, "UTF-8"); 583 | } catch (final UnsupportedEncodingException ex) { 584 | SpaceBukkit.getInstance().getLogger().severe("[PropertiesFile] Unable to write to " + fileName + "!"); 585 | } 586 | 587 | // Keep track of properties that were set 588 | final List usedProps = new ArrayList(); 589 | 590 | for (final String line : lines) { 591 | if (line.trim().length() == 0) { 592 | ps.println(line); 593 | continue; 594 | } 595 | 596 | if (line.charAt(0) == '#') { 597 | ps.println(line); 598 | continue; 599 | } 600 | 601 | if (line.contains("=")) { 602 | final int delimPosition = line.indexOf('='); 603 | final String key = line.substring(0, delimPosition).trim(); 604 | 605 | if (props.containsKey(key)) { 606 | final String value = props.get(key); 607 | ps.println(key + "=" + value); 608 | usedProps.add(key); 609 | } else 610 | ps.println(line); 611 | } else 612 | ps.println(line); 613 | } 614 | 615 | // Add any new properties 616 | for (final Map.Entry entry : props.entrySet()) 617 | if (!usedProps.contains(entry.getKey())) 618 | ps.println(entry.getKey() + "=" + entry.getValue()); 619 | 620 | // Exit that stream 621 | ps.flush(); 622 | ps.close(); 623 | try { 624 | os.flush(); 625 | os.close(); 626 | } catch (final IOException e) { 627 | e.printStackTrace(); 628 | } 629 | 630 | // Reload 631 | try { 632 | props.clear(); 633 | lines.clear(); 634 | load(); 635 | } catch (final IOException ex) { 636 | SpaceBukkit.getInstance().getLogger().severe("[PropertiesFile] Unable to load " + fileName + "!"); 637 | } 638 | } 639 | 640 | /** 641 | * Save the value given as a boolean on the specified key. 642 | * 643 | * @see #save() 644 | * @param key 645 | * The key that we will be addressing the value to. 646 | * @param value 647 | * The value we will be setting inside the .[properties] file. 648 | */ 649 | public void setBoolean(final String key, final boolean value) { 650 | props.put(key, String.valueOf(value)); 651 | 652 | save(); 653 | } 654 | 655 | /** 656 | * Save the value given as a double on the specified key. 657 | * 658 | * @see #save() 659 | * @param key 660 | * The key that we will be addressing the value to. 661 | * @param value 662 | * The value we will be setting inside the .[properties] file. 663 | */ 664 | public void setDouble(final String key, final double value) { 665 | props.put(key, String.valueOf(value)); 666 | 667 | save(); 668 | } 669 | 670 | /** 671 | * Save the value given as a int on the specified key. 672 | * 673 | * @see #save() 674 | * @param key 675 | * The key that we will be addressing the value to. 676 | * @param value 677 | * The value we will be setting inside the .[properties] file. 678 | */ 679 | public void setInt(final String key, final int value) { 680 | props.put(key, String.valueOf(value)); 681 | 682 | save(); 683 | } 684 | 685 | /** 686 | * Save the value given as a long on the specified key. 687 | * 688 | * @see #save() 689 | * @param key 690 | * The key that we will be addressing the value to. 691 | * @param value 692 | * The value we will be setting inside the .[properties] file. 693 | */ 694 | public void setLong(final String key, final long value) { 695 | props.put(key, String.valueOf(value)); 696 | 697 | save(); 698 | } 699 | 700 | /** 701 | * Save the value given as a String on the specified key. 702 | * 703 | * @see #save() 704 | * @param key 705 | * The key that we will be addressing the value to. 706 | * @param value 707 | * The value we will be setting inside the .[properties] file. 708 | */ 709 | public void setString(final String key, final String value) { 710 | props.put(key, value); 711 | 712 | save(); 713 | } 714 | } 715 | -------------------------------------------------------------------------------- /src/me/neatmonster/spacebukkit/utilities/Utilities.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of SpaceBukkit (http://spacebukkit.xereo.net/). 3 | * 4 | * SpaceBukkit is free software: you can redistribute it and/or modify it under the terms of the 5 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license as published by the Creative 6 | * Common organization, either version 3.0 of the license, or (at your option) any later version. 7 | * 8 | * SpaceBukkit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 9 | * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) license for more details. 11 | * 12 | * You should have received a copy of the Attribution-NonCommercial-ShareAlike Unported (CC BY-NC-SA) 13 | * license along with this program. If not, see . 14 | */ 15 | package me.neatmonster.spacebukkit.utilities; 16 | 17 | import java.io.BufferedReader; 18 | import java.io.InputStreamReader; 19 | import java.io.UnsupportedEncodingException; 20 | import java.net.ConnectException; 21 | import java.net.URL; 22 | import java.net.URLConnection; 23 | import java.security.MessageDigest; 24 | import java.security.NoSuchAlgorithmException; 25 | import java.util.Map; 26 | import java.util.regex.Matcher; 27 | import java.util.regex.Pattern; 28 | 29 | import me.neatmonster.spacebukkit.SpaceBukkit; 30 | 31 | import org.bukkit.ChatColor; 32 | import org.bukkit.inventory.ItemStack; 33 | 34 | /** 35 | * Various Utility methods 36 | */ 37 | public class Utilities { 38 | 39 | /** 40 | * Adds the HTTP header to a string 41 | * @param string String to add to 42 | * @return String with the header 43 | * @throws UnsupportedEncodingException If the encoding is not UTF-8 44 | */ 45 | public static String addHeader(final String string) throws UnsupportedEncodingException { 46 | String finishedString = ""; 47 | String byteLengthOfFinishedString = ""; 48 | final String newLine = "\r\n"; 49 | if (string != null) { 50 | byteLengthOfFinishedString = Integer.toString(string.getBytes("UTF8").length); 51 | finishedString = finishedString + "HTTP/1.1 200 OK" + newLine; 52 | finishedString = finishedString + "Content-Language:en" + newLine; 53 | finishedString = finishedString + "Content-Length:" + byteLengthOfFinishedString + newLine; 54 | finishedString = finishedString + "Content-Type:text/plain; charset=utf-8" + newLine; 55 | finishedString = finishedString + newLine; 56 | finishedString = finishedString + string; 57 | } else { 58 | finishedString = finishedString + "HTTP/1.1 500 Internal Server Error" + newLine; 59 | finishedString = finishedString + "Content-Language:en" + newLine; 60 | finishedString = finishedString + "Content-Length:0" + newLine; 61 | finishedString = finishedString + "Content-Type:text/html; charset=utf-8" + newLine; 62 | finishedString = finishedString + newLine; 63 | } 64 | return finishedString; 65 | } 66 | 67 | /** 68 | * Converts a String from text colors to color 69 | * @param message Message to color 70 | * @return String with color codes 71 | */ 72 | public static String color(String message) { 73 | int index = 0; 74 | while (true) { 75 | index = message.indexOf("$", index); 76 | if (index >= 0 && index < message.length() - 1) { 77 | final String letter = message.substring(index + 1, index + 2); 78 | String replace = "$" + letter; 79 | if (letter.equals("0")) 80 | replace = ChatColor.BLACK.toString(); 81 | else if (letter.equals("1")) 82 | replace = ChatColor.DARK_BLUE.toString(); 83 | else if (letter.equals("2")) 84 | replace = ChatColor.DARK_GREEN.toString(); 85 | else if (letter.equals("3")) 86 | replace = ChatColor.DARK_AQUA.toString(); 87 | else if (letter.equals("4")) 88 | replace = ChatColor.DARK_RED.toString(); 89 | else if (letter.equals("5")) 90 | replace = ChatColor.DARK_PURPLE.toString(); 91 | else if (letter.equals("6")) 92 | replace = ChatColor.GOLD.toString(); 93 | else if (letter.equals("7")) 94 | replace = ChatColor.GRAY.toString(); 95 | else if (letter.equals("8")) 96 | replace = ChatColor.DARK_GRAY.toString(); 97 | else if (letter.equals("9")) 98 | replace = ChatColor.BLUE.toString(); 99 | else if (letter.equals("a")) 100 | replace = ChatColor.GREEN.toString(); 101 | else if (letter.equals("b")) 102 | replace = ChatColor.AQUA.toString(); 103 | else if (letter.equals("c")) 104 | replace = ChatColor.RED.toString(); 105 | else if (letter.equals("d")) 106 | replace = ChatColor.LIGHT_PURPLE.toString(); 107 | else if (letter.equals("e")) 108 | replace = ChatColor.YELLOW.toString(); 109 | else if (letter.equals("f")) 110 | replace = ChatColor.WHITE.toString(); 111 | message = message.substring(0, index) + replace + message.substring(index + 2); 112 | index += 1; 113 | } else 114 | break; 115 | index += 1; 116 | } 117 | return message; 118 | } 119 | 120 | /** 121 | * Encrypts a string with 122 | * @param string String to encrypt 123 | * @return String encrypted with hex 124 | * @throws NoSuchAlgorithmException If SHA-256 or UTF-8 is not supported 125 | */ 126 | public static String crypt(final String string) throws NoSuchAlgorithmException { 127 | final MessageDigest digest = MessageDigest.getInstance("SHA-256"); 128 | digest.reset(); 129 | byte[] input = null; 130 | try { 131 | input = digest.digest(string.getBytes("UTF-8")); 132 | final StringBuffer hexString = new StringBuffer(); 133 | for (final byte element : input) { 134 | final String hex = Integer.toHexString(0xFF & element); 135 | if (hex.length() == 1) 136 | hexString.append('0'); 137 | hexString.append(hex); 138 | } 139 | return hexString.toString(); 140 | } catch (final UnsupportedEncodingException e) { 141 | e.printStackTrace(); 142 | } 143 | return "UnsupportedEncodingException"; 144 | } 145 | 146 | /** 147 | * Formats time from long to a readable String 148 | * @param time Raw time input 149 | * @return Readable time 150 | */ 151 | public static String formatTime(final long time) { 152 | final int hours = (int) ((time / 1000 + 8) % 24); 153 | final int minutes = (int) (60 * (time % 1000) / 1000); 154 | return String.format("%02d:%02d (%d:%02d %s)", hours, minutes, hours % 12 == 0 ? 12 : hours % 12, minutes, 155 | hours < 12 ? "am" : "pm"); 156 | } 157 | 158 | /** 159 | * Sends a method to the panel from the plugin 160 | * @param method Method to send 161 | * @param arguments Arguments to that method 162 | * @return Result of the method 163 | */ 164 | public static String sendMethod(final String method, final String arguments) { 165 | try { 166 | final URL url = new URL("http://localhost:" + SpaceBukkit.getInstance().rPort + "/call?method=" + method 167 | + "&args=" + arguments + "&key=" + Utilities.crypt(method + SpaceBukkit.getInstance().salt)); 168 | final URLConnection connection = url.openConnection(); 169 | final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream())); 170 | final StringBuffer stringBuffer = new StringBuffer(); 171 | String line; 172 | while ((line = bufferedReader.readLine()) != null) 173 | stringBuffer.append(line); 174 | bufferedReader.close(); 175 | return stringBuffer.toString(); 176 | } catch (final ConnectException e) { 177 | SpaceBukkit.getInstance().getLogger().severe("----------------------------------------------------------"); 178 | SpaceBukkit.getInstance().getLogger().severe("| SpaceRTK cannot be reached, please make sure you have |"); 179 | SpaceBukkit.getInstance().getLogger().severe("| RemoteToolkit installed, SpaceRTK placed in /toolkit |"); 180 | SpaceBukkit.getInstance().getLogger().severe("| /modules. Otherwise report this issue on our issues |"); 181 | SpaceBukkit.getInstance().getLogger().severe("| tracker (http://bit.ly/spacebukkitissues). |"); 182 | SpaceBukkit.getInstance().getLogger().severe("----------------------------------------------------------"); 183 | e.printStackTrace(); 184 | try { 185 | SpaceBukkit.getInstance().getLogger().severe("http://localhost:" + SpaceBukkit.getInstance().rPort + "/call?method=" + method 186 | + "&args=" + arguments + "&key=" + Utilities.crypt(SpaceBukkit.getInstance().salt)); 187 | } catch (final NoSuchAlgorithmException e_) { 188 | e_.printStackTrace(); 189 | } 190 | } catch (final Exception e) { 191 | e.printStackTrace(); 192 | } 193 | return null; 194 | } 195 | 196 | /** 197 | * Strips a string of any color codes 198 | * @param string String to strip 199 | * @return String without color codes 200 | */ 201 | public static String stripColor(String string) { 202 | string = ChatColor.stripColor(string); 203 | int index = 0; 204 | while ((index = string.indexOf('&', index)) >= 0) { 205 | final char char_ = string.charAt(index + 1); 206 | if (char_ == '&') 207 | string = string.substring(0, index) + string.substring(index + 1); 208 | else 209 | string = string.substring(0, index) + string.substring(index + 2); 210 | index++; 211 | } 212 | return string; 213 | } 214 | 215 | public static String decodeEscapeSequences(String s) { 216 | Pattern escapePattern = Pattern.compile("(&#\\d+;)"); 217 | Pattern charValue = Pattern.compile("&#(\\d+);"); 218 | Matcher escapeMatcher = escapePattern.matcher(s); 219 | while(escapeMatcher.find()) { 220 | Matcher m = charValue.matcher(escapeMatcher.group(0)); 221 | if(!m.matches()) 222 | break; 223 | char character = (char)Short.parseShort(m.group(1)); 224 | s = s.replaceFirst("&#\\d+;", ""+character); 225 | } 226 | return s; 227 | } 228 | 229 | /** 230 | * Serializes an item with the extra data "id" which contains the item id 231 | * @param stack Stack to serialize 232 | * @return Serialized item 233 | */ 234 | public static Map serializeItem(ItemStack stack) { 235 | Map result = stack.serialize(); 236 | result.put("type", stack.getType().toString()); 237 | result.put("id", stack.getTypeId()); 238 | result.put("amount", stack.getAmount()); 239 | result.put("data", stack.getData().getData()); 240 | return result; 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /src/plugin.yml: -------------------------------------------------------------------------------- 1 | name: SpaceBukkit 2 | version: 1.2 3 | description: A powerful yet simple web panel for administering your Minecraft servers with ease. 4 | author: The SpaceCP Team 5 | website: http://spacebukkit.xereo.net/ 6 | main: me.neatmonster.spacebukkit.SpaceBukkit 7 | database: false --------------------------------------------------------------------------------