Compare commits

...

107 Commits

Author SHA1 Message Date
Mike Primm f7d2dac826 Add permissions and help for /dynmap quiet command 2013-12-30 01:46:29 -06:00
Mike Primm 3cb7ba342c Add setting for periodic save of pending jobs 2013-12-30 01:45:17 -06:00
Mike Primm d2ab466dc0 Update server interface for mod-supplied texture/model files 2013-12-28 23:56:22 -06:00
Mike Primm d03ed7a461 Bump to 1.9.2 2013-12-24 10:52:17 -06:00
Mike Primm c8469d7aba Strip version check 2013-12-05 00:11:40 -06:00
Mike Primm e7c92096b2 Turn off version check (dev.bukkit.org doesn't like it...) 2013-12-02 16:12:11 -06:00
Mike Primm 0c9d397144 Update to support CB 1.7.2-R0.1 2013-12-01 08:32:16 -06:00
Mike Primm b4a3b61c11 Start mod support API 2013-11-30 22:51:48 -06:00
Mike Primm 564c38b44a Back to 1.9.1 2013-11-16 23:27:35 -06:00
Mike Primm 664e7da659 Bump to 2.0 2013-10-21 19:33:37 -05:00
Mike Primm 9046212a47 Update for mod image loading support 2013-09-18 17:17:23 -05:00
Mike Primm b6ee68c9b0 Fix comment typo 2013-09-14 16:38:38 -05:00
Mike Primm 7854568d88 Fix typo in security flag for dynmap.webregister.other 2013-09-14 15:56:24 -05:00
Mike Primm f1c9417237 Add support for web server bindaddress to be set to match MC server-ip setting 2013-09-08 00:00:25 -05:00
Mike Primm 336f8302c4 Have spout code handle renderdata not being defined yet 2013-09-07 23:11:35 -05:00
Mike Primm d8ccc26109 Add mod version check code 2013-08-16 02:17:10 -05:00
Mike Primm d396046249 Add block-id-alias setting 2013-08-04 18:07:36 -05:00
Mike Primm 1793d910d4 Straighten out GroupManager offline permissions 2013-07-18 08:44:33 -05:00
Mike Primm f0f881d126 Bump to 1.9 2013-07-07 22:01:02 -05:00
Mike Primm 5482ddaa89 Add 2 tick delay to player join processing - allows nicknames to be set before we send message to web 2013-07-05 10:57:19 -05:00
Mike Primm 47455eb912 Add 'hidenames' option, and supporting messages 2013-07-05 09:31:32 -05:00
Mike Primm 32a1c20fd0 Bandaid for MrApple's CB 1.6.1 2013-07-01 19:31:59 -05:00
Mike Primm b85c38e3a7 Add softref option for chunk snapshot cache 2013-06-25 01:09:25 -05:00
Mike Primm 5bc4de6a8b Add zoomout-min-tps setting 2013-06-24 21:44:01 -05:00
Mike Primm 2d20fd11f7 Update dev version format 2013-06-24 20:24:05 -05:00
Mike Primm 6a4bb59d60 Add permission node for /dynmap purgeworld command 2013-06-23 15:11:32 -05:00
Mike Primm ab45edb82c Add settings for TPS limits and per-tick msec limits 2013-06-19 23:20:38 -05:00
Mike Primm 4f6bc05180 Add help for /dynmap purgequeue <world> 2013-06-15 18:10:50 -05:00
Mike Primm 076681e188 Add help and permission node for /dynmap purgemap 2013-06-15 18:07:45 -05:00
Mike Primm b7abfe7c06 Add settings for player-sort-permission-nodes support 2013-06-14 01:49:49 -05:00
Mike Primm 3a88ac66a6 Add use-name-colors setting to control option to use name color markup 2013-06-02 19:28:03 -05:00
Mike Primm d3b9367794 Add 'updateplayerlimit' setting default 2013-06-02 16:31:35 -05:00
Mike Primm 666840fc8b Add help and permissions for /dmarker importdesc, importlabel, getlabel 2013-05-27 09:09:49 -05:00
Mike Primm 62f4c12147 Bump bukkit dependency to 1.4.7 2013-05-27 08:33:49 -05:00
Mike Primm 4b3f2280b6 Add command help and permissions for /dmarker description commands 2013-05-26 14:03:46 -05:00
Mike Primm df55606023 Add method for discovering all chunks in world 2013-05-24 23:59:08 -05:00
Mike Primm 6fc5fddd44 Back to 1.8 2013-05-15 20:53:56 -05:00
Mike Primm dea285c160 Back to 1.7.1 for bug fix 2013-05-15 19:35:06 -05:00
Mike Primm 204641a4b0 Bump to 1.8 2013-05-14 22:06:00 -05:00
Mike Primm d4aaa1d1fd Revert chunk load change - but still make sure they don't unload under us 2013-05-10 17:36:27 -05:00
Mike Primm fe83a7d1cc Revert "Additional check on loaded chunks : avoid getChunkAt rare exception"
This reverts commit 3efe3c3d3d.
2013-05-10 17:00:52 -05:00
Mike Primm d4e24e9d26 Add GroupManager specific permissions support 2013-05-10 01:31:30 -05:00
Mike Primm 734937884a Repackage to single JAR, no ZIP - make other files self-extracting 2013-05-09 00:55:07 -05:00
Mike Primm 3efe3c3d3d Additional check on loaded chunks : avoid getChunkAt rare exception 2013-05-08 19:35:45 -05:00
Mike Primm 46ab344197 Switch to smooth lighting by default 2013-05-02 23:12:25 -05:00
Mike Primm 9270ce853d Update author contact info 2013-05-01 23:23:49 -05:00
Mike Primm 04a2019e9d Add comments for boost-enabled templates 2013-05-01 00:26:28 -05:00
Mike Primm 8daf95891d Add comment for disabling join/quit message 2013-04-29 15:07:54 -05:00
Mike Primm 5396d0b823 Add full support for CTM material connection method 2013-04-28 10:12:01 -05:00
Mike Primm a2ab8c4f2f Tune performance on map iterator 2013-04-26 21:44:29 -05:00
Mike Primm e7efbe193a Add Custom Colors support for texture packs 2013-04-22 23:03:07 -05:00
Mike Primm 99ea38d02a Avoid shutdown exception due to bukkit 'improvements' 2013-04-21 21:05:12 -05:00
Mike Primm 7c6e660cf0 Add supporting code to help with CTM support (block names, biome names) 2013-04-18 01:20:59 -05:00
Mike Primm bcd0acec33 Bump to 1.7 2013-04-07 21:34:37 -05:00
Mike Primm 7e07bff71f Remove MCPC-Plus support from Bukkit version - add notice to use Forge 2013-03-29 21:46:06 -05:00
Mike Primm 2d95548d25 Add default setting for initial zoomout validate option 2013-03-26 23:50:54 -05:00
Mike Primm 3ac67ce2c5 Update for new API listener 2013-03-20 23:59:50 -05:00
Mike Primm 0d25fd2edc Make sure chunk unload queue is processed quickly enough on MCPC 2013-03-18 20:30:13 -05:00
Mike Primm bee16ef331 Switch MCPC+ to using unloadChunkRequest - unloadChunk() seems to not clean up properly 2013-03-17 23:43:11 -05:00
Mike Primm bf16d18371 Bump to 1.6 2013-03-02 16:00:58 -06:00
Mike Primm e57634ebb3 Add BukkitForge handler - doesn't work right due to BukkitForge API bugs 2013-03-01 23:51:45 -06:00
Mike Primm 55a5aacfce Drop autogenerate option 2013-02-24 20:24:05 -06:00
mikeprimm e6fe29f0c5 Merge pull request #1148 from dejavecu/master
Added support of round visibility limits
2013-02-24 16:15:16 -08:00
Mike Primm 34712e27f0 Put in some protextion logic for apparently broken SpoutPlugin 2013-02-24 18:04:20 -06:00
dejavecu 6a5eebcc00 Added support of round visibility limits 2013-02-16 03:59:07 +04:00
Mike Primm c8b1f71949 Add settings for image update command exits 2013-02-03 17:11:35 -06:00
Mike Primm dc11ef3507 Bump to 1.5 2013-01-29 13:52:25 -06:00
Mike Primm d0bbb78e98 Add upgrade version check 2013-01-29 11:49:22 -06:00
Mike Primm 9144bff25b Add support for MCPC-Plus 2013-01-21 23:54:13 -06:00
Mike Primm 18325c2b33 Switch version check to core version 2013-01-15 11:33:51 -06:00
Mike Primm f1a686eaf8 Hack to work around broken jenkins 2013-01-15 08:45:49 -06:00
Mike Primm b3c32456ca Revert "Test to try to fix jenkins f-up"
This reverts commit 3483b19cef.
2013-01-15 08:23:31 -06:00
Mike Primm be16ac089f Revert "Revert - no help"
This reverts commit 9ad5a7e4f7.
2013-01-15 08:23:11 -06:00
Mike Primm 44a8bfa38d Revert "Try to workaround Jenkins/Maven packaging issue"
This reverts commit 443d64f7da.
2013-01-15 08:22:55 -06:00
Mike Primm 443d64f7da Try to workaround Jenkins/Maven packaging issue 2013-01-15 08:17:31 -06:00
Mike Primm 9ad5a7e4f7 Revert - no help 2013-01-15 03:31:33 -06:00
Mike Primm 3483b19cef Test to try to fix jenkins f-up 2013-01-15 03:26:03 -06:00
Mike Primm 44c5d51c4e Fix v1.2.5 support, broken by API change in metrics 2013-01-15 00:30:08 -06:00
Mike Primm 56d1bcf3eb Show details on execution exceptions - better info on cause 2013-01-11 15:59:55 -06:00
Mike Primm f43027f02f Add tileupdatedelay setting, compute more accurate bounding box for new chunks 2013-01-08 00:10:53 -06:00
Mike Primm bd12420edd Add option to hide players on map that have invisibility potion effects 2013-01-03 21:58:58 -06:00
Mike Primm 3c01aff411 Drop obsolete file 2013-01-02 21:25:17 -06:00
Mike Primm 4d664de250 Bump to 1.4 2012-12-31 15:58:32 -06:00
Mike Primm 278fa36f94 Add call needed for sign block checks 2012-12-31 12:29:28 -06:00
Mike Primm 1a2f63bcfb Switch weather display to be on by default 2012-12-30 11:23:21 -06:00
Mike Primm 344d9bf1c9 Add support for configuing which proxy addresses to trust X-Forwarded-For from 2012-12-30 11:03:28 -06:00
Mike Primm 70b27b8034 Remove debug message 2012-12-30 10:14:05 -06:00
Mike Primm abe7fc8405 Update metrics agent 2012-12-30 09:17:35 -06:00
Mike Primm 4fa62993f4 Scrub system dependencies - shifted to repository 2012-12-24 15:10:24 -06:00
Mike Primm 08a920694b Switch to new repo 2012-12-24 14:52:00 -06:00
Mike Primm 4bdb331eb0 Switch mod use to features graph - doesn't look like we get a 3rd one.. 2012-12-17 21:55:23 -06:00
Mike Primm cb7c9061e8 Update stats to collect mod usage data 2012-12-17 21:08:39 -06:00
Mike Primm 29cb155534 Revert "Fix to bukkit API 1.2.5 - avoid accidental breaks of backward compat"
This reverts commit ada85ed960.
2012-12-16 17:12:09 -06:00
Mike Primm ada85ed960 Fix to bukkit API 1.2.5 - avoid accidental breaks of backward compat 2012-12-16 15:02:19 -06:00
Mike Primm bfb12aa0f3 Bump to 1.3 2012-12-10 22:52:02 -06:00
Mike Primm 3342977a92 Add cyrillic setting back in to configuration.txt 2012-12-10 00:21:58 -06:00
Mike Primm 07cbd84d44 Combine support for pre 1.4.5 versions and new 1.4.x packaging crud 2012-12-09 22:28:21 -06:00
Mike Primm da5e2cf24a Add transparent-leaves setting : workaround for borked lighting in some SpoutPlugin versions 2012-12-09 13:04:44 -06:00
Mike Primm c6d345d8f1 Add tile entity data collection 2012-11-22 00:50:55 -06:00
Mike Primm 3a57261120 First pass of custom renderer support 2012-11-19 15:56:55 -06:00
Mike Primm a39f99cab8 Back to 1.2 2012-11-16 18:46:34 -06:00
Mike Primm f0885abea2 Back to 1.1 for patch 2012-11-16 18:39:44 -06:00
Mike Primm 2b17cb215b Bump to 1.2 2012-11-16 18:06:22 -06:00
Mike Primm 68f0c17f70 Support world loading/unloading - allow viewing while world unloaded 2012-11-10 23:47:40 -06:00
Mike Primm a20e55beab Add support for handling custom biomes (ExtraBiomes XL) 2012-11-09 21:01:11 -06:00
Mike Primm 413542fe61 Add permissions.jar to project - not on repo anymore 2012-11-08 14:25:32 -06:00
Mike Primm a250732d31 Bump to v1.1 2012-10-29 22:37:55 -05:00
20 changed files with 1776 additions and 533 deletions
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
-6
View File
@@ -1,6 +0,0 @@
dynmap.render # Render current chunk
dynmap.fullrender # Issue a full render
dynmap.hide.self # Hide self from map
dynmap.hide.others # Hide others from map
dynmap.show.self # Reveal self on map
dynmap.show.others # Reveal others on map
+19 -65
View File
@@ -4,8 +4,10 @@
<artifactId>dynmap</artifactId>
<name>dynmap</name>
<properties>
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<BUILD_NUMBER>dev</BUILD_NUMBER>
<BUILD_NUMBER>Dev${timestamp}</BUILD_NUMBER>
</properties>
<url>http://github.com/webbukkit/dynmap/</url>
<issueManagement>
@@ -41,31 +43,6 @@
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals><goal>unpack</goal></goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.dynmap</groupId>
<artifactId>DynmapCore</artifactId>
<version>${project.version}</version>
<classifier>bin</classifier>
<type>zip</type>
<outputDirectory>${project.build.directory}/core</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -88,29 +65,6 @@
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/package.xml</descriptor>
</descriptors>
<!-- Hack for bug in maven-assembly: http://jira.codehaus.org/browse/MASSEMBLY-449 -->
<archiverConfig>
<fileMode>420</fileMode> <!-- 420(dec) = 644(oct) -->
<directoryMode>493</directoryMode> <!-- 493(dec) = 755(oct) -->
<defaultDirectoryMode>493</defaultDirectoryMode>
</archiverConfig>
</configuration>
<executions>
<execution>
<id>build</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
@@ -119,22 +73,28 @@
</releases>
<snapshots>
</snapshots>
<id>spout-repo</id>
<url>http://repo.spout.org</url>
<id>bukkit-repo</id>
<url>http://repo.bukkit.org/content/repositories/releases/</url>
</repository>
<repository>
<releases>
</releases>
<snapshots>
</snapshots>
<id>dynmap-repo</id>
<url>http://repo.mikeprimm.com/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.nijikokun.bukkit</groupId>
<artifactId>Permissions</artifactId>
<version>[2.5.4,)</version>
<version>3.1.6</version>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>[1.2.5-R4.0,1.7)</version>
<type>jar</type>
<scope>compile</scope>
<version>1.4.7-R1.0</version>
</dependency>
<dependency>
<groupId>org.dynmap</groupId>
@@ -161,28 +121,22 @@
<groupId>ru.tehkode</groupId>
<artifactId>PermissionsEx</artifactId>
<version>1.19.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/PermissionsEx.jar</systemPath>
</dependency>
<dependency>
<groupId>de.bananaco</groupId>
<artifactId>bPermissions</artifactId>
<version>2.9.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/bpermissions.jar</systemPath>
</dependency>
<dependency>
<groupId>com.platymuus.bukkit.permissions</groupId>
<artifactId>PermissionsBukkit</artifactId>
<version>1.6</version>
<scope>system</scope>
<systemPath>${project.basedir}/PermissionsBukkit.jar</systemPath>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>craftbukkit</artifactId>
<version>1.2.5-R5.1-SNAPSHOT</version>
<groupId>org.anjocaido</groupId>
<artifactId>EssentialsGroupManager</artifactId>
<version>2.10.1</version>
</dependency>
</dependencies>
<version>1.0</version>
<version>1.9.2</version>
</project>
+1 -9
View File
@@ -7,15 +7,7 @@
<fileSets>
<fileSet>
<directory>${project.build.directory}/core</directory>
<outputDirectory>/dynmap</outputDirectory>
<excludes>
<exclude>web/version.js</exclude></excludes></fileSet>
<fileSet>
<directory>${project.build.directory}/core/web</directory>
<outputDirectory>/dynmap/web</outputDirectory>
<includes>
<include>version.js</include></includes>
<filtered>true</filtered></fileSet>
<outputDirectory>/dynmap</outputDirectory></fileSet>
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory>/dynmap</outputDirectory>
@@ -0,0 +1,131 @@
package org.dynmap.bukkit;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.ChunkSnapshot;
import org.bukkit.Server;
import org.bukkit.World;
import org.dynmap.Log;
/**
* Helper for isolation of bukkit version specific issues
*/
public abstract class BukkitVersionHelper {
private static BukkitVersionHelper helper = null;
public static final BukkitVersionHelper getHelper() {
if(helper == null) {
if(Bukkit.getServer().getVersion().contains("MCPC")) {
Log.severe("*********************************************************************************");
Log.severe("* MCPC-Plus is no longer supported via the Bukkit version of Dynmap. *");
Log.severe("* Install the appropriate Forge version of Dynmap. *");
Log.severe("* Add the DynmapCBBridge plugin to enable support for Dynmap-compatible plugins *");
Log.severe("*********************************************************************************");
}
else if(Bukkit.getServer().getVersion().contains("BukkitForge")) {
Log.severe("*********************************************************************************");
Log.severe("* BukkitForge is not supported via the Bukkit version of Dynmap. *");
Log.severe("* Install the appropriate Forge version of Dynmap. *");
Log.severe("* Add the DynmapCBBridge plugin to enable support for Dynmap-compatible plugins *");
Log.severe("*********************************************************************************");
}
else {
helper = new BukkitVersionHelperCB();
}
}
return helper;
}
protected BukkitVersionHelper() {
}
/**
* Get list of defined biomebase objects
*/
public abstract Object[] getBiomeBaseList();
/**
* Get temperature from biomebase
*/
public abstract float getBiomeBaseTemperature(Object bb);
/**
* Get humidity from biomebase
*/
public abstract float getBiomeBaseHumidity(Object bb);
/**
* Get ID string from biomebase
*/
public abstract String getBiomeBaseIDString(Object bb);
/**
* Get ID from biomebase
*/
public abstract int getBiomeBaseID(Object bb);
/**
* Get net.minecraft.server.world for given world
*/
public abstract Object getNMSWorld(World w);
/**
* Get unload queue for given NMS world
*/
public abstract Object getUnloadQueue(Object nmsworld);
/**
* For testing unload queue for presence of givne chunk
*/
public abstract boolean isInUnloadQueue(Object unloadqueue, int x, int z);
/**
* Read raw biome ID from snapshot
*/
public abstract Object[] getBiomeBaseFromSnapshot(ChunkSnapshot css);
/**
* Test if normal chunk snapshot
*/
public abstract boolean isCraftChunkSnapshot(ChunkSnapshot css);
/**
* Remove entities from given chunk
*/
public abstract void removeEntitiesFromChunk(Chunk c);
/**
* Get tile entities map from chunk
*/
public abstract Map getTileEntitiesForChunk(Chunk c);
/**
* Get X coordinate of tile entity
*/
public abstract int getTileEntityX(Object te);
/**
* Get Y coordinate of tile entity
*/
public abstract int getTileEntityY(Object te);
/**
* Get Z coordinate of tile entity
*/
public abstract int getTileEntityZ(Object te);
/**
* Read tile entity NBT
*/
public abstract Object readTileEntityNBT(Object te);
/**
* Get field value from NBT compound
*/
public abstract Object getFieldValue(Object nbt, String field);
/**
* Unload chunk no save needed
*/
public abstract void unloadChunkNoSave(World w, Chunk c, int cx, int cz);
/**
* Get block short name list
*/
public abstract String[] getBlockShortNames();
/**
* Get biome name list
*/
public abstract String[] getBiomeNames();
/**
* Get block material index list
*/
public abstract int[] getBlockMaterialMap();
}
@@ -0,0 +1,218 @@
package org.dynmap.bukkit;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Server;
import org.bukkit.World;
import org.dynmap.Log;
import org.dynmap.common.BiomeMap;
/**
* Helper for isolation of bukkit version specific issues
*/
public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric {
private Class<?> nmsblock;
private Class<?> nmsblockarray;
private Class<?> nmsmaterial;
private Field blockbyid;
private Field blockname;
private Field material;
private Method blockbyidfunc; // 1.7+ method for getting block by id
BukkitVersionHelperCB() {
}
@Override
protected String getNMSPackage() {
Server srv = Bukkit.getServer();
/* Get getHandle() method */
try {
Method m = srv.getClass().getMethod("getHandle");
Object scm = m.invoke(srv); /* And use it to get SCM (nms object) */
return scm.getClass().getPackage().getName();
} catch (Exception x) {
Log.severe("Error finding net.minecraft.server packages");
return null;
}
}
@Override
protected void loadNMS() {
// Get block fields
nmsblock = getNMSClass("net.minecraft.server.Block");
nmsblockarray = getNMSClass("[Lnet.minecraft.server.Block;");
nmsmaterial = getNMSClass("net.minecraft.server.Material");
blockbyid = getFieldNoFail(nmsblock, new String[] { "byId" }, nmsblockarray);
if (blockbyid == null) {
blockbyidfunc = getMethod(nmsblock, new String[] { "e" }, new Class[] { int.class });
}
blockname = getPrivateField(nmsblock, new String[] { "name", "b" }, String.class);
material = getPrivateField(nmsblock, new String[] { "material" }, nmsmaterial);
/* Set up biomebase fields */
biomebase = getNMSClass("net.minecraft.server.BiomeBase");
biomebasearray = getNMSClass("[Lnet.minecraft.server.BiomeBase;");
biomebaselist = getPrivateField(biomebase, new String[] { "biomes" }, biomebasearray);
biomebasetemp = getField(biomebase, new String[] { "temperature", "F" }, float.class);
biomebasehumi = getField(biomebase, new String[] { "humidity", "G" }, float.class);
biomebaseidstring = getField(biomebase, new String[] { "y", "af" }, String.class);
biomebaseid = getField(biomebase, new String[] { "id" }, int.class);
/* n.m.s.World */
nmsworld = getNMSClass("net.minecraft.server.WorldServer");
chunkprovserver = getNMSClass("net.minecraft.server.ChunkProviderServer");
nmsw_chunkproviderserver = getField(nmsworld, new String[] { "chunkProviderServer" }, chunkprovserver);
longhashset = getOBCClassNoFail("org.bukkit.craftbukkit.util.LongHashSet");
if(longhashset != null) {
lhs_containskey = getMethod(longhashset, new String[] { "contains" }, new Class[] { int.class, int.class });
}
else {
longhashset = getOBCClass("org.bukkit.craftbukkit.util.LongHashset");
lhs_containskey = getMethod(longhashset, new String[] { "containsKey" }, new Class[] { int.class, int.class });
}
cps_unloadqueue = getFieldNoFail(chunkprovserver, new String[] { "unloadQueue" }, longhashset);
if(cps_unloadqueue == null) {
Log.info("Unload queue not found - default to unload all chunks");
}
/** n.m.s.Chunk */
nmschunk = getNMSClass("net.minecraft.server.Chunk");
nmsc_removeentities = getMethod(nmschunk, new String[] { "removeEntities" }, new Class[0]);
nmsc_tileentities = getField(nmschunk, new String[] { "tileEntities" }, Map.class);
/** nbt classes */
nbttagcompound = getNMSClass("net.minecraft.server.NBTTagCompound");
nbttagbyte = getNMSClass("net.minecraft.server.NBTTagByte");
nbttagshort = getNMSClass("net.minecraft.server.NBTTagShort");
nbttagint = getNMSClass("net.minecraft.server.NBTTagInt");
nbttaglong = getNMSClass("net.minecraft.server.NBTTagLong");
nbttagfloat = getNMSClass("net.minecraft.server.NBTTagFloat");
nbttagdouble = getNMSClass("net.minecraft.server.NBTTagDouble");
nbttagbytearray = getNMSClass("net.minecraft.server.NBTTagByteArray");
nbttagstring = getNMSClass("net.minecraft.server.NBTTagString");
nbttagintarray = getNMSClass("net.minecraft.server.NBTTagIntArray");
compound_get = getMethod(nbttagcompound, new String[] { "get" }, new Class[] { String.class });
nbttagbyte_val = getPrivateField(nbttagbyte, new String[] { "data" }, byte.class);
nbttagshort_val = getPrivateField(nbttagshort, new String[] { "data" }, short.class);
nbttagint_val = getPrivateField(nbttagint, new String[] { "data" }, int.class);
nbttaglong_val = getPrivateField(nbttaglong, new String[] { "data" }, long.class);
nbttagfloat_val = getPrivateField(nbttagfloat, new String[] { "data" }, float.class);
nbttagdouble_val = getPrivateField(nbttagdouble, new String[] { "data" }, double.class);
nbttagbytearray_val = getPrivateField(nbttagbytearray, new String[] { "data" }, byte[].class);
nbttagstring_val = getPrivateField(nbttagstring, new String[] { "data" }, String.class);
nbttagintarray_val = getPrivateField(nbttagintarray, new String[] { "data" }, int[].class);
/** Tile entity */
nms_tileentity = getNMSClass("net.minecraft.server.TileEntity");
nmst_readnbt = getMethod(nms_tileentity, new String[] { "b" }, new Class[] { nbttagcompound });
nmst_x = getField(nms_tileentity, new String[] { "x" }, int.class);
nmst_y = getField(nms_tileentity, new String[] { "y" }, int.class);
nmst_z = getField(nms_tileentity, new String[] { "z" }, int.class);
}
@Override
public void unloadChunkNoSave(World w, Chunk c, int cx, int cz) {
this.removeEntitiesFromChunk(c);
w.unloadChunk(cx, cz, false, false);
}
/**
* Get block short name list
*/
@Override
public String[] getBlockShortNames() {
try {
String[] names = new String[4096];
if (blockbyid != null) {
Object[] byid = (Object[])blockbyid.get(nmsblock);
for (int i = 0; i < names.length; i++) {
if (byid[i] != null) {
names[i] = (String)blockname.get(byid[i]);
}
}
}
else {
for (int i = 0; i < names.length; i++) {
Object blk = blockbyidfunc.invoke(nmsblock, i);
if (blk != null) {
names[i] = (String)blockname.get(blk);
}
}
}
return names;
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
return new String[0];
}
/**
* Get biome name list
*/
@Override
public String[] getBiomeNames() {
String[] names;
/* Find array of biomes in biomebase */
Object[] biomelist = getBiomeBaseList();
names = new String[biomelist.length];
/* Loop through list, starting afer well known biomes */
for(int i = 0; i < biomelist.length; i++) {
Object bb = biomelist[i];
if(bb != null) {
names[i] = getBiomeBaseIDString(bb);
}
}
return names;
}
/**
* Get block material index list
*/
public int[] getBlockMaterialMap() {
try {
int[] map = new int[4096];
if (blockbyid != null) {
Object[] byid = (Object[])blockbyid.get(nmsblock);
ArrayList<Object> mats = new ArrayList<Object>();
for (int i = 0; i < map.length; i++) {
if (byid[i] != null) {
Object mat = (Object)material.get(byid[i]);
if (mat != null) {
map[i] = mats.indexOf(mat);
if (map[i] < 0) {
map[i] = mats.size();
mats.add(mat);
}
}
else {
map[i] = -1;
}
}
}
}
else {
ArrayList<Object> mats = new ArrayList<Object>();
for (int i = 0; i < map.length; i++) {
Object blk = blockbyidfunc.invoke(nmsblock, i);
if (blk != null) {
Object mat = (Object)material.get(blk);
if (mat != null) {
map[i] = mats.indexOf(mat);
if (map[i] < 0) {
map[i] = mats.size();
mats.add(mat);
}
}
else {
map[i] = -1;
}
}
}
}
return map;
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
return new int[0];
}
}
@@ -0,0 +1,372 @@
package org.dynmap.bukkit;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.ChunkSnapshot;
import org.bukkit.Server;
import org.bukkit.World;
import org.dynmap.Log;
/**
* Helper for isolation of bukkit version specific issues
*/
public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
private String obc_package; // Package used for org.bukkit.craftbukkit
protected String nms_package; // Package used for net.minecraft.server
private boolean failed;
private static final Object[] nullargs = new Object[0];
private static final Map nullmap = Collections.emptyMap();
/** CraftChunkSnapshot */
private Class<?> craftchunksnapshot;
private Field ccss_biome;
/** CraftChunk */
private Class<?> craftchunk;
private Method cc_gethandle;
/** CraftWorld */
private Class<?> craftworld;
private Method cw_gethandle;
/** BiomeBase related helpers */
protected Class<?> biomebase;
protected Class<?> biomebasearray;
protected Field biomebaselist;
protected Field biomebasetemp;
protected Field biomebasehumi;
protected Field biomebaseidstring;
protected Field biomebaseid;
/** n.m.s.World */
protected Class<?> nmsworld;
protected Class<?> chunkprovserver;
protected Class<?> longhashset;
protected Field nmsw_chunkproviderserver;
protected Field cps_unloadqueue;
protected Method lhs_containskey;
/** n.m.s.Chunk */
protected Class<?> nmschunk;
protected Method nmsc_removeentities;
protected Field nmsc_tileentities;
/** nbt classes */
protected Class<?> nbttagcompound;
protected Class<?> nbttagbyte;
protected Class<?> nbttagshort;
protected Class<?> nbttagint;
protected Class<?> nbttaglong;
protected Class<?> nbttagfloat;
protected Class<?> nbttagdouble;
protected Class<?> nbttagbytearray;
protected Class<?> nbttagstring;
protected Class<?> nbttagintarray;
protected Method compound_get;
protected Field nbttagbyte_val;
protected Field nbttagshort_val;
protected Field nbttagint_val;
protected Field nbttaglong_val;
protected Field nbttagfloat_val;
protected Field nbttagdouble_val;
protected Field nbttagbytearray_val;
protected Field nbttagstring_val;
protected Field nbttagintarray_val;
/** Tile entity */
protected Class<?> nms_tileentity;
protected Method nmst_readnbt;
protected Field nmst_x;
protected Field nmst_y;
protected Field nmst_z;
BukkitVersionHelperGeneric() {
failed = false;
Server srv = Bukkit.getServer();
/* Look up base classname for bukkit server - tells us OBC package */
obc_package = Bukkit.getServer().getClass().getPackage().getName();
/* Get NMS package */
nms_package = getNMSPackage();
if(nms_package == null) {
failed = true;
}
/* Craftworld fields */
craftworld = getOBCClass("org.bukkit.craftbukkit.CraftWorld");
cw_gethandle = getMethod(craftworld, new String[] { "getHandle" }, new Class[0]);
/* CraftChunkSnapshot */
craftchunksnapshot = getOBCClass("org.bukkit.craftbukkit.CraftChunkSnapshot");
ccss_biome = getPrivateField(craftchunksnapshot, new String[] { "biome" }, biomebasearray);
/* CraftChunk */
craftchunk = getOBCClass("org.bukkit.craftbukkit.CraftChunk");
cc_gethandle = getMethod(craftchunk, new String[] { "getHandle" }, new Class[0]);
/* Get NMS classes and fields */
if(!failed)
loadNMS();
if(failed)
throw new IllegalArgumentException("Error initializing dynmap - bukkit version incompatible!");
}
protected abstract void loadNMS();
protected abstract String getNMSPackage();
protected Class<?> getOBCClass(String classname) {
return getClassByName(classname, "org.bukkit.craftbukkit", obc_package, false);
}
protected Class<?> getOBCClassNoFail(String classname) {
return getClassByName(classname, "org.bukkit.craftbukkit", obc_package, true);
}
protected Class<?> getNMSClass(String classname) {
return getClassByName(classname, "net.minecraft.server", nms_package, false);
}
protected Class<?> getClassByName(String classname, String base, String mapping, boolean nofail) {
String n = classname;
int idx = classname.indexOf(base);
if(idx >= 0) {
n = classname.substring(0, idx) + mapping + classname.substring(idx + base.length());
}
try {
return Class.forName(n);
} catch (ClassNotFoundException cnfx) {
try {
return Class.forName(classname);
} catch (ClassNotFoundException cnfx2) {
if(!nofail) {
Log.severe("Cannot find " + classname);
failed = true;
}
return null;
}
}
}
/**
* Get field
*/
protected Field getField(Class<?> cls, String[] ids, Class<?> type) {
return getField(cls, ids, type, false);
}
protected Field getFieldNoFail(Class<?> cls, String[] ids, Class<?> type) {
return getField(cls, ids, type, true);
}
/**
* Get field
*/
private Field getField(Class<?> cls, String[] ids, Class<?> type, boolean nofail) {
if((cls == null) || (type == null)) return null;
for(String id : ids) {
try {
Field f = cls.getField(id);
if(f.getType().isAssignableFrom(type)) {
return f;
}
} catch (NoSuchFieldException nsfx) {
}
}
if(!nofail) {
Log.severe("Unable to find field " + ids[0] + " for " + cls.getName());
failed = true;
}
return null;
}
/**
* Get private field
*/
protected Field getPrivateField(Class<?> cls, String[] ids, Class<?> type) {
if((cls == null) || (type == null)) return null;
for(String id : ids) {
try {
Field f = cls.getDeclaredField(id);
if(f.getType().isAssignableFrom(type)) {
f.setAccessible(true);
return f;
}
} catch (NoSuchFieldException nsfx) {
}
}
Log.severe("Unable to find field " + ids[0] + " for " + cls.getName());
failed = true;
return null;
}
protected Object getFieldValue(Object obj, Field field, Object def) {
if((obj != null) && (field != null)) {
try {
return field.get(obj);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
}
}
return def;
}
/**
* Get method
*/
protected Method getMethod(Class<?> cls, String[] ids, Class[] args) {
if(cls == null) return null;
for(String id : ids) {
try {
return cls.getMethod(id, args);
} catch (SecurityException e) {
} catch (NoSuchMethodException e) {
}
}
Log.severe("Unable to find method " + ids[0] + " for " + cls.getName());
failed = true;
return null;
}
private Object callMethod(Object obj, Method meth, Object[] args, Object def) {
if((obj == null) || (meth == null)) {
return def;
}
try {
return meth.invoke(obj, args);
} catch (IllegalArgumentException iax) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
return def;
}
/**
* Get list of defined biomebase objects
*/
public Object[] getBiomeBaseList() {
return (Object[]) getFieldValue(biomebase, biomebaselist, new Object[0]);
}
/** Get temperature from biomebase */
public float getBiomeBaseTemperature(Object bb) {
return (Float) getFieldValue(bb, biomebasetemp, 0.5F);
}
/** Get humidity from biomebase */
public float getBiomeBaseHumidity(Object bb) {
return (Float) getFieldValue(bb, biomebasehumi, 0.5F);
}
/** Get ID string from biomebase */
public String getBiomeBaseIDString(Object bb) {
return (String) getFieldValue(bb, biomebaseidstring, null);
}
/** Get ID from biomebase */
public int getBiomeBaseID(Object bb) {
return (Integer) getFieldValue(bb, biomebaseid, -1);
}
/* Get net.minecraft.server.world for given world */
public Object getNMSWorld(World w) {
return callMethod(w, cw_gethandle, nullargs, null);
}
/* Get unload queue for given NMS world */
public Object getUnloadQueue(Object nmsworld) {
Object cps = getFieldValue(nmsworld, nmsw_chunkproviderserver, null); // Get chunkproviderserver
if(cps != null) {
return getFieldValue(cps, cps_unloadqueue, null);
}
return null;
}
/* For testing unload queue for presence of givne chunk */
public boolean isInUnloadQueue(Object unloadqueue, int x, int z) {
if(unloadqueue != null) {
return (Boolean)callMethod(unloadqueue, lhs_containskey, new Object[] { x, z }, true);
}
return true;
}
public Object[] getBiomeBaseFromSnapshot(ChunkSnapshot css) {
return (Object[])getFieldValue(css, ccss_biome, null);
}
public boolean isCraftChunkSnapshot(ChunkSnapshot css) {
if(craftchunksnapshot != null) {
return craftchunksnapshot.isAssignableFrom(css.getClass());
}
return false;
}
/** Remove entities from given chunk */
public void removeEntitiesFromChunk(Chunk c) {
Object omsc = callMethod(c, cc_gethandle, nullargs, null);
if(omsc != null) {
callMethod(omsc, nmsc_removeentities, nullargs, null);
}
}
/** Get tile entities map from chunk */
public Map getTileEntitiesForChunk(Chunk c) {
Object omsc = callMethod(c, cc_gethandle, nullargs, null);
if(omsc != null) {
return (Map)getFieldValue(omsc, nmsc_tileentities, nullmap);
}
return nullmap;
}
/**
* Get X coordinate of tile entity
*/
public int getTileEntityX(Object te) {
return (Integer)getFieldValue(te, nmst_x, 0);
}
/**
* Get Y coordinate of tile entity
*/
public int getTileEntityY(Object te) {
return (Integer)getFieldValue(te, nmst_y, 0);
}
/**
* Get Z coordinate of tile entity
*/
public int getTileEntityZ(Object te) {
return (Integer)getFieldValue(te, nmst_z, 0);
}
/**
* Read tile entity NBT
*/
public Object readTileEntityNBT(Object te) {
if(nbttagcompound == null) return null;
Object nbt = null;
try {
nbt = nbttagcompound.newInstance();
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
}
if(nbt != null) {
callMethod(te, nmst_readnbt, new Object[] { nbt }, null);
}
return nbt;
}
/**
* Get field value from NBT compound
*/
public Object getFieldValue(Object nbt, String field) {
Object val = callMethod(nbt, compound_get, new Object[] { field }, null);
if(val == null) return null;
Class<?> valcls = val.getClass();
if(valcls.equals(nbttagbyte)) {
return getFieldValue(val, nbttagbyte_val, null);
}
else if(valcls.equals(nbttagshort)) {
return getFieldValue(val, nbttagshort_val, null);
}
else if(valcls.equals(nbttagint)) {
return getFieldValue(val, nbttagint_val, null);
}
else if(valcls.equals(nbttaglong)) {
return getFieldValue(val, nbttaglong_val, null);
}
else if(valcls.equals(nbttagfloat)) {
return getFieldValue(val, nbttagfloat_val, null);
}
else if(valcls.equals(nbttagdouble)) {
return getFieldValue(val, nbttagdouble_val, null);
}
else if(valcls.equals(nbttagbytearray)) {
return getFieldValue(val, nbttagbytearray_val, null);
}
else if(valcls.equals(nbttagstring)) {
return getFieldValue(val, nbttagstring_val, null);
}
else if(valcls.equals(nbttagintarray)) {
return getFieldValue(val, nbttagintarray_val, null);
}
return null;
}
}
+138 -17
View File
@@ -2,8 +2,13 @@ package org.dynmap.bukkit;
/**
* Bukkit specific implementation of DynmapWorld
*/
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.List;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.permissions.Permission;
@@ -12,18 +17,42 @@ import org.dynmap.DynmapChunk;
import org.dynmap.DynmapLocation;
import org.dynmap.DynmapWorld;
import org.dynmap.utils.MapChunkCache;
import org.dynmap.utils.TileFlags;
public class BukkitWorld extends DynmapWorld {
private World world;
private World.Environment env;
private boolean skylight;
private DynmapLocation spawnloc = new DynmapLocation();
public BukkitWorld(World w) {
super(w.getName(), w.getMaxHeight(), w.getSeaLevel());
this(w.getName(), w.getMaxHeight(), w.getSeaLevel(), w.getEnvironment());
setWorldLoaded(w);
new Permission("dynmap.world." + getName(), "Dynmap access for world " + getName(), PermissionDefault.OP);
}
public BukkitWorld(String name, int height, int sealevel, World.Environment env) {
super(name, height, sealevel);
world = null;
this.env = env;
skylight = (env == World.Environment.NORMAL);
new Permission("dynmap.world." + getName(), "Dynmap access for world " + getName(), PermissionDefault.OP);
}
/**
* Set world online
* @param w - loaded world
*/
public void setWorldLoaded(World w) {
world = w;
env = world.getEnvironment();
skylight = (env == World.Environment.NORMAL);
new Permission("dynmap.world." + getName(), "Dynmap access for world " + getName(), PermissionDefault.OP);
}
/**
* Set world unloaded
*/
@Override
public void setWorldUnloaded() {
getSpawnLocation(); /* Remember spawn location before unload */
world = null;
}
/* Test if world is nether */
@Override
@@ -33,26 +62,44 @@ public class BukkitWorld extends DynmapWorld {
/* Get world spawn location */
@Override
public DynmapLocation getSpawnLocation() {
DynmapLocation dloc = new DynmapLocation();
Location sloc = world.getSpawnLocation();
dloc.x = sloc.getBlockX(); dloc.y = sloc.getBlockY();
dloc.z = sloc.getBlockZ(); dloc.world = normalizeWorldName(sloc.getWorld().getName());
return dloc;
if(world != null) {
Location sloc = world.getSpawnLocation();
spawnloc.x = sloc.getBlockX();
spawnloc.y = sloc.getBlockY();
spawnloc.z = sloc.getBlockZ();
spawnloc.world = normalizeWorldName(sloc.getWorld().getName());
}
return spawnloc;
}
/* Get world time */
@Override
public long getTime() {
return world.getTime();
if(world != null) {
return world.getTime();
}
else {
return -1;
}
}
/* World is storming */
@Override
public boolean hasStorm() {
return world.hasStorm();
if(world != null) {
return world.hasStorm();
}
else {
return false;
}
}
/* World is thundering */
@Override
public boolean isThundering() {
return world.isThundering();
if(world != null) {
return world.isThundering();
}
else {
return false;
}
}
/* World is loaded */
@Override
@@ -62,22 +109,37 @@ public class BukkitWorld extends DynmapWorld {
/* Get light level of block */
@Override
public int getLightLevel(int x, int y, int z) {
return world.getBlockAt(x, y, z).getLightLevel();
if(world != null) {
return world.getBlockAt(x, y, z).getLightLevel();
}
else {
return -1;
}
}
/* Get highest Y coord of given location */
@Override
public int getHighestBlockYAt(int x, int z) {
return world.getHighestBlockYAt(x, z);
if(world != null) {
return world.getHighestBlockYAt(x, z);
}
else {
return -1;
}
}
/* Test if sky light level is requestable */
@Override
public boolean canGetSkyLightLevel() {
return skylight;
return skylight && (world != null);
}
/* Return sky light level */
@Override
public int getSkyLightLevel(int x, int y, int z) {
return world.getBlockAt(x, y, z).getLightFromSky();
if(world != null) {
return world.getBlockAt(x, y, z).getLightFromSky();
}
else {
return -1;
}
}
/**
* Get world environment ID (lower case - normal, the_end, nether)
@@ -91,12 +153,71 @@ public class BukkitWorld extends DynmapWorld {
*/
@Override
public MapChunkCache getChunkCache(List<DynmapChunk> chunks) {
NewMapChunkCache c = new NewMapChunkCache();
c.setChunks(this, chunks);
return c;
if(isLoaded()) {
NewMapChunkCache c = new NewMapChunkCache();
c.setChunks(this, chunks);
return c;
}
else {
return null;
}
}
public World getWorld() {
return world;
}
// Return false if unimplemented
@Override
public int getChunkMap(TileFlags map) {
map.clear();
if (world == null) return -1;
int cnt = 0;
// Mark loaded chunks
for(Chunk c : world.getLoadedChunks()) {
map.setFlag(c.getX(), c.getZ(), true);
cnt++;
}
File f = world.getWorldFolder();
File regiondir = new File(f, "region");
File[] lst = regiondir.listFiles();
if(lst != null) {
byte[] hdr = new byte[4096];
for(File rf : lst) {
if(!rf.getName().endsWith(".mca")) {
continue;
}
String[] parts = rf.getName().split("\\.");
if((!parts[0].equals("r")) && (parts.length != 4)) continue;
RandomAccessFile rfile = null;
int x = 0, z = 0;
try {
x = Integer.parseInt(parts[1]);
z = Integer.parseInt(parts[2]);
rfile = new RandomAccessFile(rf, "r");
rfile.read(hdr, 0, hdr.length);
} catch (IOException iox) {
Arrays.fill(hdr, (byte)0);
} catch (NumberFormatException nfx) {
Arrays.fill(hdr, (byte)0);
} finally {
if(rfile != null) {
try { rfile.close(); } catch (IOException iox) {}
}
}
for (int i = 0; i < 1024; i++) {
int v = hdr[4*i] | hdr[4*i + 1] | hdr[4*i + 2] | hdr[4*i + 3];
if (v == 0) continue;
int xx = (x << 5) | (i & 0x1F);
int zz = (z << 5) | ((i >> 5) & 0x1F);
if (!map.setFlag(xx, zz, true)) {
cnt++;
}
}
}
}
return cnt;
}
}
File diff suppressed because it is too large Load Diff
+103 -79
View File
@@ -25,7 +25,6 @@
* authors and contributors and should not be interpreted as representing official policies,
* either expressed or implied, of anybody else.
*/
package org.dynmap.bukkit;
import org.bukkit.Bukkit;
@@ -33,6 +32,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.scheduler.BukkitTask;
import java.io.BufferedReader;
import java.io.File;
@@ -53,15 +53,11 @@ import java.util.UUID;
import java.util.logging.Level;
/**
* <p>
* The metrics class obtains data about a plugin and submits statistics about it to the metrics backend.
* </p>
* <p>
* Public methods provided by this class:
* </p>
* <p> The metrics class obtains data about a plugin and submits statistics about it to the metrics backend. </p> <p>
* Public methods provided by this class: </p>
* <code>
* Graph createGraph(String name); <br/>
* void addCustomData(Metrics.Plotter plotter); <br/>
* void addCustomData(BukkitMetrics.Plotter plotter); <br/>
* void start(); <br/>
* </code>
*/
@@ -70,68 +66,60 @@ public class Metrics {
/**
* The current revision number
*/
private final static int REVISION = 5;
private final static int REVISION = 6;
/**
* The base url of the metrics domain
*/
private static final String BASE_URL = "http://mcstats.org";
/**
* The url used to report a server's status
*/
private static final String REPORT_URL = "/report/%s";
/**
* The separator to use for custom data. This MUST NOT change unless you are hosting your own
* version of metrics and want to change it.
* The separator to use for custom data. This MUST NOT change unless you are hosting your own version of metrics and
* want to change it.
*/
private static final String CUSTOM_DATA_SEPARATOR = "~~";
/**
* Interval of time to ping (in minutes)
*/
private static final int PING_INTERVAL = 10;
/**
* The plugin this metrics submits for
*/
private final Plugin plugin;
/**
* All of the custom graphs to submit to metrics
*/
private final Set<Graph> graphs = Collections.synchronizedSet(new HashSet<Graph>());
/**
* The default graph, used for addCustomData when you don't want a specific graph
*/
private final Graph defaultGraph = new Graph("Default");
/**
* The plugin configuration file
*/
private final YamlConfiguration configuration;
/**
* The plugin configuration file
*/
private final File configurationFile;
/**
* Unique server id
*/
private final String guid;
/**
* Debug mode
*/
private final boolean debug;
/**
* Lock for synchronization
*/
private final Object optOutLock = new Object();
/**
* Id of the scheduled task
* The scheduled task
*/
private volatile int taskId = -1;
private volatile BukkitTask task = null;
public Metrics(final Plugin plugin) throws IOException {
if (plugin == null) {
@@ -147,6 +135,7 @@ public class Metrics {
// add some defaults
configuration.addDefault("opt-out", false);
configuration.addDefault("guid", UUID.randomUUID().toString());
configuration.addDefault("debug", false);
// Do we need to create the file?
if (configuration.get("guid", null) == null) {
@@ -156,11 +145,12 @@ public class Metrics {
// Load the guid then
guid = configuration.getString("guid");
debug = configuration.getBoolean("debug", false);
}
/**
* Construct and create a Graph that can be used to separate specific plotters to their own graphs
* on the metrics website. Plotters can be added to the graph object returned.
* Construct and create a Graph that can be used to separate specific plotters to their own graphs on the metrics
* website. Plotters can be added to the graph object returned.
*
* @param name The name of the graph
* @return Graph object created. Will never return NULL under normal circumstances unless bad parameters are given
@@ -181,7 +171,7 @@ public class Metrics {
}
/**
* Add a Graph object to Metrics that represents data for the plugin that should be sent to the backend
* Add a Graph object to BukkitMetrics that represents data for the plugin that should be sent to the backend
*
* @param graph The name of the graph
*/
@@ -211,9 +201,9 @@ public class Metrics {
}
/**
* Start measuring statistics. This will immediately create an async repeating task as the plugin and send
* the initial data to the metrics backend, and then after that it will post in increments of
* PING_INTERVAL * 1200 ticks.
* Start measuring statistics. This will immediately create an async repeating task as the plugin and send the
* initial data to the metrics backend, and then after that it will post in increments of PING_INTERVAL * 1200
* ticks.
*
* @return True if statistics measuring is running, otherwise false.
*/
@@ -225,12 +215,13 @@ public class Metrics {
}
// Is metrics already running?
if (taskId >= 0) {
if (task != null) {
return true;
}
// Begin hitting the server with glorious data
taskId = plugin.getServer().getScheduler().scheduleAsyncRepeatingTask(plugin, new Runnable() {
try {
task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() {
private boolean firstPost = true;
@@ -239,11 +230,11 @@ public class Metrics {
// This has to be synchronized or it can collide with the disable method.
synchronized (optOutLock) {
// Disable Task, if it is running and the server owner decided to opt-out
if (isOptOut() && taskId > 0) {
plugin.getServer().getScheduler().cancelTask(taskId);
taskId = -1;
if (isOptOut() && task != null) {
task.cancel();
task = null;
// Tell all plotters to stop gathering information.
for (Graph graph : graphs){
for (Graph graph : graphs) {
graph.onOptOut();
}
}
@@ -258,10 +249,16 @@ public class Metrics {
// Each post thereafter will be a ping
firstPost = false;
} catch (IOException e) {
//Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
}
}
}
}, 0, PING_INTERVAL * 1200);
}, 0, PING_INTERVAL * 1200);
} catch (NoSuchMethodError nsme) {
// Handle deprecated scheduler API stupidity
return false;
}
return true;
}
@@ -273,15 +270,19 @@ public class Metrics {
* @return true if metrics should be opted out of it
*/
public boolean isOptOut() {
synchronized(optOutLock) {
synchronized (optOutLock) {
try {
// Reload the metrics file
configuration.load(getConfigFile());
} catch (IOException ex) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
} catch (InvalidConfigurationException ex) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
}
return configuration.getBoolean("opt-out", false);
@@ -289,30 +290,30 @@ public class Metrics {
}
/**
* Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task.
*
* @throws IOException
*/
* Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task.
*
* @throws java.io.IOException
*/
public void enable() throws IOException {
// This has to be synchronized or it can collide with the check in the task.
synchronized (optOutLock) {
// Check if the server owner has already set opt-out, if not, set it.
if (isOptOut()) {
configuration.set("opt-out", false);
configuration.save(configurationFile);
}
// Check if the server owner has already set opt-out, if not, set it.
if (isOptOut()) {
configuration.set("opt-out", false);
configuration.save(configurationFile);
}
// Enable Task, if it is not running
if (taskId < 0) {
start();
}
// Enable Task, if it is not running
if (task == null) {
start();
}
}
}
/**
* Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task.
*
* @throws IOException
* @throws java.io.IOException
*/
public void disable() throws IOException {
// This has to be synchronized or it can collide with the check in the task.
@@ -324,9 +325,9 @@ public class Metrics {
}
// Disable Task, if it is running
if (taskId > 0) {
this.plugin.getServer().getScheduler().cancelTask(taskId);
taskId = -1;
if (task != null) {
task.cancel();
task = null;
}
}
}
@@ -352,17 +353,45 @@ public class Metrics {
* Generic method that posts a plugin to the metrics website
*/
private void postPlugin(final boolean isPing) throws IOException {
// The plugin's description file containg all of the plugin data such as name, version, author, etc
final PluginDescriptionFile description = plugin.getDescription();
// Server software specific section
PluginDescriptionFile description = plugin.getDescription();
String pluginName = description.getName();
boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled
String pluginVersion = description.getVersion();
String serverVersion = Bukkit.getVersion();
int playersOnline = Bukkit.getServer().getOnlinePlayers().length;
// END server software specific section -- all code below does not use any code outside of this class / Java
// Construct the post data
final StringBuilder data = new StringBuilder();
// The plugin's description file containg all of the plugin data such as name, version, author, etc
data.append(encode("guid")).append('=').append(encode(guid));
encodeDataPair(data, "version", description.getVersion());
encodeDataPair(data, "server", Bukkit.getVersion());
encodeDataPair(data, "players", Integer.toString(Bukkit.getServer().getOnlinePlayers().length));
encodeDataPair(data, "version", pluginVersion);
encodeDataPair(data, "server", serverVersion);
encodeDataPair(data, "players", Integer.toString(playersOnline));
encodeDataPair(data, "revision", String.valueOf(REVISION));
// New data as of R6
String osname = System.getProperty("os.name");
String osarch = System.getProperty("os.arch");
String osversion = System.getProperty("os.version");
String java_version = System.getProperty("java.version");
int coreCount = Runtime.getRuntime().availableProcessors();
// normalize os arch .. amd64 -> x86_64
if (osarch.equals("amd64")) {
osarch = "x86_64";
}
encodeDataPair(data, "osname", osname);
encodeDataPair(data, "osarch", osarch);
encodeDataPair(data, "osversion", osversion);
encodeDataPair(data, "cores", Integer.toString(coreCount));
encodeDataPair(data, "online-mode", Boolean.toString(onlineMode));
encodeDataPair(data, "java_version", java_version);
// If we're pinging, append it
if (isPing) {
encodeDataPair(data, "ping", "true");
@@ -393,7 +422,7 @@ public class Metrics {
}
// Create the url
URL url = new URL(BASE_URL + String.format(REPORT_URL, encode(plugin.getDescription().getName())));
URL url = new URL(BASE_URL + String.format(REPORT_URL, encode(pluginName)));
// Connect to the website
URLConnection connection;
@@ -456,8 +485,8 @@ public class Metrics {
}
/**
* <p>Encode a key/value data pair to be used in a HTTP post request. This INCLUDES a & so the first
* key/value pair MUST be included manually, e.g:</p>
* <p>Encode a key/value data pair to be used in a HTTP post request. This INCLUDES a & so the first key/value pair
* MUST be included manually, e.g:</p>
* <code>
* StringBuffer data = new StringBuffer();
* data.append(encode("guid")).append('=').append(encode(guid));
@@ -488,11 +517,10 @@ public class Metrics {
public static class Graph {
/**
* The graph's name, alphanumeric and spaces only :)
* If it does not comply to the above when submitted, it is rejected
* The graph's name, alphanumeric and spaces only :) If it does not comply to the above when submitted, it is
* rejected
*/
private final String name;
/**
* The set of plotters that are contained within this graph
*/
@@ -532,7 +560,7 @@ public class Metrics {
/**
* Gets an <b>unmodifiable</b> set of the plotter objects in the graph
*
* @return an unmodifiable {@link Set} of the plotter objects
* @return an unmodifiable {@link java.util.Set} of the plotter objects
*/
public Set<Plotter> getPlotters() {
return Collections.unmodifiableSet(plotters);
@@ -554,11 +582,10 @@ public class Metrics {
}
/**
* Called when the server owner decides to opt-out of Metrics while the server is running.
* Called when the server owner decides to opt-out of BukkitMetrics while the server is running.
*/
protected void onOptOut() {
}
}
/**
@@ -588,10 +615,9 @@ public class Metrics {
}
/**
* Get the current value for the plotted point. Since this function defers to an external function
* it may or may not return immediately thus cannot be guaranteed to be thread friendly or safe.
* This function can be called from any thread so care should be taken when accessing resources
* that need to be synchronized.
* Get the current value for the plotted point. Since this function defers to an external function it may or may
* not return immediately thus cannot be guaranteed to be thread friendly or safe. This function can be called
* from any thread so care should be taken when accessing resources that need to be synchronized.
*
* @return the current value for the point to be plotted.
*/
@@ -626,7 +652,5 @@ public class Metrics {
final Plotter plotter = (Plotter) object;
return plotter.name.equals(name) && plotter.getValue() == getValue();
}
}
}
File diff suppressed because it is too large Load Diff
@@ -3,20 +3,28 @@ package org.dynmap.bukkit;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.ref.SoftReference;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import org.bukkit.ChunkSnapshot;
import org.dynmap.utils.DynIntHashMap;
public class SnapshotCache {
public static class SnapshotRec {
public ChunkSnapshot ss;
public DynIntHashMap tileData;
};
private CacheHashMap snapcache;
private ReferenceQueue<ChunkSnapshot> refqueue;
private ReferenceQueue<SnapshotRec> refqueue;
private long cache_attempts;
private long cache_success;
private boolean softref;
private static class CacheRec {
WeakReference<ChunkSnapshot> ref;
Reference<SnapshotRec> ref;
boolean hasbiome;
boolean hasrawbiome;
boolean hasblockdata;
@@ -26,12 +34,12 @@ public class SnapshotCache {
@SuppressWarnings("serial")
public class CacheHashMap extends LinkedHashMap<String, CacheRec> {
private int limit;
private IdentityHashMap<WeakReference<ChunkSnapshot>, String> reverselookup;
private IdentityHashMap<Reference<SnapshotRec>, String> reverselookup;
public CacheHashMap(int lim) {
super(16, (float)0.75, true);
limit = lim;
reverselookup = new IdentityHashMap<WeakReference<ChunkSnapshot>, String>();
reverselookup = new IdentityHashMap<Reference<SnapshotRec>, String>();
}
protected boolean removeEldestEntry(Map.Entry<String, CacheRec> last) {
boolean remove = (size() >= limit);
@@ -45,9 +53,10 @@ public class SnapshotCache {
/**
* Create snapshot cache
*/
public SnapshotCache(int max_size) {
public SnapshotCache(int max_size, boolean softref) {
snapcache = new CacheHashMap(max_size);
refqueue = new ReferenceQueue<ChunkSnapshot>();
refqueue = new ReferenceQueue<SnapshotRec>();
this.softref = softref;
}
private String getKey(String w, int cx, int cz) {
return w + ":" + cx + ":" + cz;
@@ -83,11 +92,11 @@ public class SnapshotCache {
/**
* Look for chunk snapshot in cache
*/
public ChunkSnapshot getSnapshot(String w, int chunkx, int chunkz,
public SnapshotRec getSnapshot(String w, int chunkx, int chunkz,
boolean blockdata, boolean biome, boolean biomeraw, boolean highesty) {
String key = getKey(w, chunkx, chunkz);
processRefQueue();
ChunkSnapshot ss = null;
SnapshotRec ss = null;
CacheRec rec = snapcache.get(key);
if(rec != null) {
ss = rec.ref.get();
@@ -112,7 +121,7 @@ public class SnapshotCache {
/**
* Add chunk snapshot to cache
*/
public void putSnapshot(String w, int chunkx, int chunkz, ChunkSnapshot ss,
public void putSnapshot(String w, int chunkx, int chunkz, SnapshotRec ss,
boolean blockdata, boolean biome, boolean biomeraw, boolean highesty) {
String key = getKey(w, chunkx, chunkz);
processRefQueue();
@@ -121,7 +130,10 @@ public class SnapshotCache {
rec.hasbiome = biome;
rec.hasrawbiome = biomeraw;
rec.hashighesty = highesty;
rec.ref = new WeakReference<ChunkSnapshot>(ss, refqueue);
if (softref)
rec.ref = new SoftReference<SnapshotRec>(ss, refqueue);
else
rec.ref = new WeakReference<SnapshotRec>(ss, refqueue);
CacheRec prevrec = snapcache.put(key, rec);
if(prevrec != null) {
snapcache.reverselookup.remove(prevrec.ref);
@@ -132,7 +144,7 @@ public class SnapshotCache {
* Process reference queue
*/
private void processRefQueue() {
Reference<? extends ChunkSnapshot> ref;
Reference<? extends SnapshotRec> ref;
while((ref = refqueue.poll()) != null) {
String k = snapcache.reverselookup.remove(ref);
if(k != null) {
@@ -115,7 +115,12 @@ public class SpoutPluginBlocks {
/* Loop through blocks - try to freshen files, if needed */
for(CustomBlock b : cb) {
BlockDesign bd = b.getBlockDesign();
String blkid = bd.getTexturePlugin() + "." + fixIDString(b.getName());
if(bd == null) continue;
String txtplug = bd.getTexturePlugin();
if(txtplug == null) continue;
String blkname = b.getName();
if(blkname == null) continue;
String blkid = txtplug + "." + fixIDString(blkname);
/* If not GenericCubiodBlockDesign, we don't handle it */
if((bd instanceof GenericCuboidBlockDesign) == false) {
Log.info("Block " + blkid + " not suppored - only cubiod blocks");
@@ -223,7 +228,10 @@ public class SpoutPluginBlocks {
}
String rslt = sb.toString();
/* Now, generate spout texture file - see if changed */
File st = new File(datadir, "renderdata/spout-texture.txt");
File renderdata = new File(datadir, "renderdata");
if (renderdata.exists() == false)
renderdata.mkdirs();
File st = new File(renderdata, "spout-texture.txt");
if(st.exists()) {
FileReader fr = null;
StringBuilder sbold = new StringBuilder();
@@ -39,7 +39,7 @@ public class BukkitPermissions implements PermissionProvider {
}
@Override
public Set<String> hasOfflinePermissions(String player, Set<String> perms) {
Player p = Bukkit.getPlayerExact(name);
Player p = Bukkit.getPlayerExact(player);
HashSet<String> hasperms = null;
if (p != null) {
hasperms = new HashSet<String>();
@@ -0,0 +1,66 @@
package org.dynmap.bukkit.permissions;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.dynmap.Log;
import org.anjocaido.groupmanager.GroupManager;
import org.anjocaido.groupmanager.dataholder.worlds.WorldsHolder;
import org.anjocaido.groupmanager.permissions.AnjoPermissionsHandler;
public class GroupManagerPermissions implements PermissionProvider {
String name;
GroupManager gm;
WorldsHolder wh;
public static GroupManagerPermissions create(Server server, String name) {
Plugin permissionsPlugin = server.getPluginManager().getPlugin("GroupManager");
if (permissionsPlugin == null)
return null;
server.getPluginManager().enablePlugin(permissionsPlugin);
if(permissionsPlugin.isEnabled() == false)
return null;
Log.info("Using GroupManager " + permissionsPlugin.getDescription().getVersion() + " for access control");
return new GroupManagerPermissions(name, permissionsPlugin);
}
public GroupManagerPermissions(String name, Plugin permissionsPlugin) {
this.name = name;
gm = (GroupManager)permissionsPlugin;
wh = gm.getWorldsHolder();
}
@Override
public boolean has(CommandSender sender, String permission) {
Player player = sender instanceof Player ? (Player) sender : null;
boolean rslt = (player != null) ? gm.getWorldsHolder().getDefaultWorld().getPermissionsHandler().permission(player, name + "." + permission) : true;
return rslt;
}
@Override
public Set<String> hasOfflinePermissions(String player, Set<String> perms) {
HashSet<String> hasperms = new HashSet<String>();
AnjoPermissionsHandler apm = gm.getWorldsHolder().getDefaultWorld().getPermissionsHandler();
if (apm != null) {
for (String pp : perms) {
if (apm.permission(player, name + "." + pp)) {
hasperms.add(pp);
}
}
}
return hasperms;
}
@Override
public boolean hasOfflinePermission(String player, String perm) {
AnjoPermissionsHandler apm = gm.getWorldsHolder().getDefaultWorld().getPermissionsHandler();
boolean rslt = false;
if(apm != null) {
rslt = apm.permission(player, name + "." + perm);
}
return rslt;
}
}
@@ -24,8 +24,9 @@ public class PEXPermissions implements PermissionProvider {
server.getPluginManager().enablePlugin(permissionsPlugin);
if(permissionsPlugin.isEnabled() == false)
return null;
if(PermissionsEx.isAvailable() == false)
return null;
//Broken in new dev builds, apparently
//if(PermissionsEx.isAvailable() == false)
// return null;
Log.info("Using PermissionsEx " + permissionsPlugin.getDescription().getVersion() + " for access control");
return new PEXPermissions(name);
}
+92 -13
View File
@@ -1,14 +1,18 @@
# All paths in this configuration file are relative to Dynmap's data-folder: minecraft_server/plugins/dynmap/
# All map templates are defined in the templates directory
# The 'classic' FlatMap and KzedMap templates are used, which can be found in normal.txt, nether.txt, and skylands.txt
# To use these, do not set deftemplatesuffix (make sure deftemplatesuffix is commented, below)
# To use the HDMap very-low-res map templates as world defaults (normal-vlowres, nether-vlowres and skylands-vlowres), set value to vlowres
# The definitions of these templates are in normal-vlowres.txt, nether-vlowres.txt, and skylands-vlowres.txt
# To use the HDMap low-res map templates as world defaults (normal-lowres, nether-lowres and skylands-lowres), set value to lowres
# The definitions of these templates are in normal-lowres.txt, nether-lowres.txt, and skylands-lowres.txt
# To use the HDMap hi-res map templates (these can take a VERY long time for initial fullrender), set value to hires
# The definitions of these templates are in normal-hires.txt, nether-hires.txt, and skylands-hires.txt
# To use the HDMap very-low-res (2 ppb) map templates as world defaults, set value to vlowres
# The definitions of these templates are in normal-vlowres.txt, nether-vlowres.txt, and the_end-vlowres.txt
# To use the HDMap low-res (4 ppb) map templates as world defaults, set value to lowres
# The definitions of these templates are in normal-lowres.txt, nether-lowres.txt, and the_end-lowres.txt
# To use the HDMap hi-res (16 ppb) map templates (these can take a VERY long time for initial fullrender), set value to hires
# The definitions of these templates are in normal-hires.txt, nether-hires.txt, and the_end-hires.txt
# To use the HDMap low-res (4 ppb) map templates, with support for boosting resolution selectively to hi-res (16 ppb), set value to low_boost_hi
# The definitions of these templates are in normal-low_boost_hi.txt, nether-low_boost_hi.txt, and the_end-low_boost_hi.txt
# To use the HDMap hi-res (16 ppb) map templates, with support for boosting resolution selectively to vhi-res (32 ppb), set value to hi_boost_vhi
# The definitions of these templates are in normal-hi_boost_vhi.txt, nether-hi_boost_vhi.txt, and the_end-hi_boost_vhi.txt
# To use the HDMap hi-res (16 ppb) map templates, with support for boosting resolution selectively to xhi-res (64 ppb), set value to hi_boost_xhi
# The definitions of these templates are in normal-hi_boost_xhi.txt, nether-hi_boost_xhi.txt, and the_end-hi_boost_xhi.txt
deftemplatesuffix: vlowres
components:
@@ -22,6 +26,8 @@ components:
hidewebchatip: false
trustclientname: false
includehiddenplayers: false
# (optional) if true, color codes in player display names are used
use-name-colors: false
# (optional) if true, player login IDs will be used for web chat when their IPs match
use-player-login-ip: true
# (optional) if use-player-login-ip is true, setting this to true will cause chat messages not matching a known player IP to be ignored
@@ -42,14 +48,19 @@ components:
hideifsneaking: false
# If true, player positions/status is protected (login with ID with dynmap.playermarkers.seeall permission required for info other than self)
protected-player-info: false
# If true, hide players with invisibility potion effects active
hide-if-invisiblity-potion: true
# If true, player names are not shown on map, chat, list
hidenames: false
#- class: org.dynmap.JsonFileClientUpdateComponent
# writeinterval: 1
# sendhealth: true
# sendposition: true
# allowwebchat: false
# allowwebchat: true
# webchat-interval: 5
# hidewebchatip: false
# includehiddenplayers: false
# use-name-colors: false
# use-player-login-ip: false
# require-player-login-ip: false
# block-banned-player-chat: true
@@ -62,6 +73,8 @@ components:
# webchat-permissions: false
# # Limit length of single chat messages
# chatlengthlimit: 256
# hide-if-invisiblity-potion: true
# hidenames: false
- class: org.dynmap.SimpleWebChatComponent
allowchat: true
@@ -131,7 +144,7 @@ components:
- class: org.dynmap.ClientComponent
type: timeofdayclock
showdigitalclock: true
#showweather: true
showweather: true
# Mouse pointer world coordinate display
- class: org.dynmap.ClientComponent
type: coord
@@ -180,9 +193,20 @@ usenormalthreadpriority: true
# Save and restore pending tile renders - prevents their loss on server shutdown or /reload
saverestorepending: true
# Save period for pending jobs (in seconds): periodic saving for crash recovery of jobs
save-pending-period: 900
# Zoom-out tile update period - how often to scan for and process tile updates into zoom-out tiles (in seconds)
zoomoutperiod: 30
# Control whether zoom out tiles are validated on startup (can be needed if zoomout processing is interrupted, but can be expensive on large maps)
initial-zoomout-validate: true
# Default delay on processing of updated tiles, in seconds. This can reduce potentially expensive re-rendering
# of frequently updated tiles (such as due to machines, pistons, quarries or other automation). Values can
# also be set on individual worlds and individual maps.
tileupdatedelay: 30
# Tile hashing is used to minimize tile file updates when no changes have occurred - set to false to disable
enabletilehash: true
@@ -193,16 +217,30 @@ enabletilehash: true
#better-grass: true
# Optional - enable smooth lighting by default on all maps supporting it (can be set per map as lighting option)
smooth-lighting: false
smooth-lighting: true
# Optional - render specific block IDs using the texures and models of another block ID: can be used to hide/disguise specific
# blocks (e.g. make ores look like stone, hide chests) or to provide simple support for rendering unsupported custom blocks
block-id-alias:
# "14": 1
# "15": 1
# "16": 1
# Default image format for HDMaps (png, jpg, jpg-q75, jpg-q80, jpg-q85, jpg-q90, jpg-q95, jpg-q100)
# Has no effect on maps with explicit format settings
image-format: png
# use-generated-textures: if true, use generated textures (same as client); false is static water/lava textures
# correct-water-lighting: if true, use corrected water lighting (same as client); false is legacy water (darker)
# transparent-leaves: if true, leaves are transparent (lighting-wise): false is needed for some Spout versions that break lighting on leaf blocks
use-generated-textures: true
correct-water-lighting: true
transparent-leaves: true
# ctm-support: if true, Connected Texture Mod (CTM) in texture packs is enabled (default)
ctm-support: true
# custom-colors-support: if true, Custom Colors in texture packs is enabled (default)
custom-colors-support: true
# Control loading of player faces (if set to false, skins are never fetched)
#fetchskins: false
@@ -247,7 +285,8 @@ tilespath: web/tiles
webpath: web
# The network-interface the webserver will bind to (0.0.0.0 for all interfaces, 127.0.0.1 for only local access).
webserver-bindaddress: 0.0.0.0
# If not set, uses same setting as server in server.properties (or 0.0.0.0 if not specified)
#webserver-bindaddress: 0.0.0.0
# The TCP-port the webserver will listen on.
webserver-port: 8123
@@ -283,14 +322,29 @@ progressloginterval: 100
# Interval the browser should poll for updates.
updaterate: 2000
# If nonzero, server will pause fullrender/radiusrender processing when 'fullrenderplayerlimit' or more user's are logged in
# If nonzero, server will pause fullrender/radiusrender processing when 'fullrenderplayerlimit' or more users are logged in
fullrenderplayerlimit: 0
# If nonzero, server will pause update render processing when 'updateplayerlimit' or more users are logged in
updateplayerlimit: 0
# Target limit on server thread use - msec per tick
per-tick-time-limit: 50
# If TPS of server is below this setting, update renders processing is paused
update-min-tps: 18.0
# If TPS of server is below this setting, full/radius renders processing is paused
fullrender-min-tps: 18.0
# If TPS of server is below this setting, zoom out processing is paused
zoomout-min-tps: 18.0
showplayerfacesinmenu: true
# Control whether players that are hidden or not on current map are grayed out (true=yes)
grayplayerswhenhidden: true
# Use player permissions to order player list: first to last, players are ordered by first permission listed that they have
# That is, anyone with first listed permission goes before anyone with second, etc, with users with none of the nodes going last
player-sort-permission-nodes:
- bukkit.command.op
# Set sidebaropened: 'true' to pin menu sidebar opened permanently, 'pinned' to default the sidebar to pinned, but allow it to unpin
#sidebaropened: true
@@ -299,8 +353,15 @@ grayplayerswhenhidden: true
# Access-Control-Allow-Origin: "my-domain.com"
# X-Custom-Header-Of-Mine: "MyHeaderValue"
# Trusted proxies for web server - which proxy addresses are trusted to supply valid X-Forwarded-For fields
trusted-proxies:
- "127.0.0.1"
- "0:0:0:0:0:0:0:1"
# Join/quit message format for web chat: set to "" to disable notice on web UI
joinmessage: "%playername% joined"
quitmessage: "%playername% quit"
spammessage: "You may only chat once every %interval% seconds."
# format for messages from web: %playername% substitutes sender ID (typically IP), %message% includes text
webmsgformat: "&color;2[WEB] %playername%: &color;f%message%"
@@ -322,12 +383,17 @@ defaultmap: flat
# If true, make persistent record of IP addresses used by player logins, to support web IP to player matching
persist-ids-by-ip: true
# If true, map text to cyrillic
cyrillic-support: false
# Messages to customize
msg:
maptypes: "Map Types"
players: "Players"
chatrequireslogin: "Chat Requires Login"
chatnotallowed: "You are not permitted to send chat messages"
hiddennamejoin: "Player joined"
hiddennamequit: "Player quit"
# URL for client configuration (only need to be tailored for proxies or other non-standard configurations)
url:
@@ -355,6 +421,19 @@ spout:
# to clean cached textures and force reload on next startup)
use-existing-textures: true
# Customization commands - allows scripts to be run before/after certain events
custom-commands:
image-updates:
# Command run just before any image file is written or updated: run with single parameter with fully qualified file name
preupdatecommand: ""
# Command run just after any image file is written or updated: run with single parameter with fully qualified file name
postupdatecommand: ""
# Snapshot cache size, in chunks
snapshotcachesize: 500
# Snapshot cache uses soft references (true), else weak references (false)
soft-ref-cache: true
# Set to true to enable verbose startup messages - can help with debugging map configuration problems
# Set to false for a much quieter startup log
verbose: false
+55 -3
View File
@@ -1,8 +1,9 @@
name: dynmap
main: org.dynmap.bukkit.DynmapPlugin
version: "${project.version}-${BUILD_NUMBER}"
authors: [FrozenCow, mikeprimm]
softdepend: [ Permissions, PermissionEx, bPermissions, PermissionsBukkit ]
authors: [mikeprimm]
website: "http://www.minecraftforum.net/topic/1543523-dynmap-dynamic-web-based-maps-for-minecraft/"
softdepend: [ Permissions, PermissionEx, bPermissions, PermissionsBukkit, GroupManager ]
commands:
dynmap:
description: Controls Dynmap.
@@ -29,8 +30,12 @@ commands:
/<command> resetstats - Reset render statistics.
/<command> sendtoweb msg - Send message to web users
/<command> purgequeue - Set tile update queue to empty
/<command> purgequeue worldname - Set tile update queue to empty for world 'worldname'
/<command> purgemap worldname mapname - Delete all the tiles for map 'mapname' of world 'worldname'
/<command> purgeworld worldname - Delete all the files for world 'worldname'
/<command> pause - Show render pause state
/<command> pause <all|none|full|update> - Set render pause state
/<command> quiet - Stop progress messages from active jobs
/<command> ids-for-ip <ipaddress> - Show player IDs that have logged in from given IP address
/<command> ips-for-id <playerid> - Show IP addresses that have been used for the given player ID
/<command> add-id-for-ip <playerid> <ipaddress> - Add player ID to given IP address
@@ -86,6 +91,17 @@ commands:
/<command> listcircles - list details of all circles
/<command> updatecircle <label> <arg>:<value> ... - update attributes of circle with given label
/<command> updatecircle id:<id> <arg>:<value> ... - update attributes of circle with given ID
/<command> getdesc id:<id> type:<icon|area|circle|line> - get description for marker with given ID
/<command> getdesc <label> type:<icon|area|circle|line> - get description for marker with given label
/<command> resetdesc id:<id> type:<icon|area|circle|line> - clear description for marker with given ID
/<command> resetdesc <label> type:<icon|area|circle|line> - clear description for marker with given label
/<command> appenddesc id:<id> type:<icon|area|circle|line> desc:"text" - append text line to description for marker with given ID
/<command> appenddesc <label> type:<icon|area|circle|line> desc:"text" - append text line to description for marker with given label
/<command> importdesc id:<id> type:<icon|area|circle|line> file:<filename> - import description from given file for marker with given ID
/<command> importdesc <label> type:<icon|area|circle|line> file:<filename> - import description from given file for marker with given label
/<command> importlabel id:<id> type:<icon|area|circle|line> file:<filename> - import label with markup from given file for marker with given ID
/<command> importlabel <label> type:<icon|area|circle|line> file:<filename> - import label with markup from given file for marker with given label
/<command> getlabel id:<id> type:<icon|area|circle|line> - get label for marker with given ID
dmap:
description: List and modify dynmap configuration
@@ -119,6 +135,9 @@ permissions:
dynmap.resetstats: true
dynmap.sendtoweb: true
dynmap.purgequeue: true
dynmap.purgemap: true
dynmap.purgeworld: true
dynmap.quiet: true
dynmap.ids-for-ip: true
dynmap.ips-for-id: true
dynmap.webregister: true
@@ -146,6 +165,12 @@ permissions:
dynmap.marker.updatecircle: true
dynmap.marker.listcircles: true
dynmap.marker.deletecircle: true
dynmap.marker.getdesc: true
dynmap.marker.resetdesc: true
dynmap.marker.appenddesc: true
dynmap.marker.importdesc: true
dynmap.marker.getlabel: true
dynmap.marker.importlabel: true
dynmap.dmap.worldlist: true
dynmap.dmap.worldset: true
dynmap.dmap.worldreset: true
@@ -198,9 +223,18 @@ permissions:
dynmap.purgequeue:
description: Allows /dynmap purgequeue
default: op
dynmap.purgemap:
description: Allows /dynmap purgemap
default: op
dynmap.purgeworld:
description: Allows /dynmap purgeworld
default: op
dynmap.pause:
description: Allows /dynmap pause
default: op
dynmap.quiet:
description: Allows /dynmap quiet
default: true
dynmap.ids-for-ip:
description: Allows /dynmap ids-for-ip
default: op
@@ -210,7 +244,7 @@ permissions:
dynmap.webregister:
description: Allows /dynmap webregister
default: true
dynmao,webregister.other:
dynmap.webregister.other:
description: Allows /dynmap webregister userid
default: op
dynmap.marker.add:
@@ -291,6 +325,24 @@ permissions:
dynmap.marker.deletecircle:
description: Allows /dmarker deletecircle
default: op
dynmap.marker.getdesc:
description: Allows /dmarker getdesc
default: op
dynmap.marker.resetdesc:
description: Allows /dmarker resetdesc
default: op
dynmap.marker.appenddesc:
description: Allows /dmarker appenddesc
default: op
dynmap.marker.importdesc:
description: Allows /dmarker importdesc
default: op
dynmap.marker.getlabel:
description: Allows /dmarker getlabel
default: op
dynmap.marker.importlabel:
description: Allows /dmarker importlabel
default: op
dynmap.dmap.worldlist:
description: Allows /dmap worldlist
default: op