Compare commits

...

126 Commits

Author SHA1 Message Date
Luke Street c5899d6234 CraftBukkit 1.9 compatibility 2016-02-29 22:03:34 -05:00
mikeprimm 20320c578f Merge pull request #1851 from starlis/dupeRemoveEntities
Remove duplicate removeEntities - Fixes #1838
2016-01-21 18:30:39 -06:00
mikeprimm 829a02b636 Merge pull request #1839 from Black-Hole/clear-cache
clear the affected cache if triggerRender...() is called
2016-01-21 18:29:39 -06:00
Aikar 0253a644bf Remove duplicate removeEntities - Fixes #1838
This is handled by unloadChunk
2015-11-03 21:22:19 -05:00
BlackHole 96a11c4711 clear the affected cache if triggerRender...() is called 2015-09-21 15:53:00 +02:00
mikeprimm 9d2755cab1 Merge pull request #1821 from mg-1999/patch-1
Minor Grammar Fix in the config
2015-09-04 22:33:06 -05:00
Mike Primm e69fc065cd Remove javadoc build - not needed here 2015-09-04 22:23:06 -05:00
Matthijs f440e3948f Whoop 2015-08-08 20:31:38 +02:00
Matthijs ffc950d33a Minor grammer fix 2015-08-08 20:29:54 +02:00
Mike Primm d579879fbc Bump to 2.3-SNAPSHOT 2015-07-12 22:55:06 -05:00
Mike Primm 3126de8eec Bump to 2.2 GA 2015-07-12 20:29:37 -05:00
mikeprimm 4292d8540e Merge pull request #1736 from NotWoods/patch-2
Changed default "skin-url" value
2015-02-26 21:30:00 -06:00
Mike Primm 0a4b1fd14b Add showworldborder setting, 1.8 vanilla world border support 2015-02-15 12:40:30 -06:00
Tiger Oakes ac1d4a8af0 Changed default "skin-url" value
With the new skin system introduced in 1.7.10/1.8, Mojang now hosts skins under the minecraft.net domain instead of Amazon's. Since the Amazon link now only provides outdated skins, it would be better to use the new skins.minecraft.net URL as default.
2015-02-03 09:08:55 -10:00
Mike Primm 2e5d27d0d5 Bump to 2.2 2015-01-09 18:38:52 -06:00
Mike Primm f80b456b2c Shift marker persistence off of server thread (lag reduction) 2015-01-05 23:02:09 -06:00
Mike Primm 41d1de1fbb Fix biome temp/humidity on newer biomes 2015-01-03 17:23:40 -06:00
Mike Primm 274a363a97 Avoid trap in Spigot for light levels outside max height 2014-12-14 20:49:38 -06:00
Mike Primm b0d9f5541a Start Spigot 1.8 support (doesn't work yet....) 2014-11-28 11:08:44 -06:00
Mike Primm 0f722da05d Update to use Bukkit 1.7.10-R0.1 API, rip out old SpoutPlugin support 2014-10-13 09:41:14 -05:00
Mike Primm af1bcd1094 Bump to 2.1 2014-10-13 09:12:01 -05:00
Mike Primm a7f0218d0f Prepare for 2.0.0. release 2014-10-12 17:40:14 -05:00
Mike Primm 3fd4ac7373 Update to fix Glowstone support 2014-09-13 21:17:37 -05:00
Mike Primm ac0f756fae More Glowstone fixes 2014-09-06 22:25:56 -05:00
Mike Primm 551f35f3f9 Add initial support for Glowstone server 2014-09-06 19:19:20 -05:00
Mike Primm ec9ebf2dbb Add well known 1.7 biomes only when appropriate version 2014-08-22 23:48:12 -05:00
Mike Primm 3702918a6f Add well known 1.7.x biomes only when version is appropriate 2014-08-22 23:15:57 -05:00
Mike Primm 8085221087 Add prefix setting for MySQL table names 2014-08-22 01:50:47 -05:00
mikeprimm 7de967f1c2 Merge pull request #1603 from KovuTheHusky/roundcoords
Add option to round coordinates to nearest integer
2014-08-20 18:10:10 -05:00
mikeprimm f6e127b7f0 Merge pull request #1601 from KovuTheHusky/master
Fix javadoc errors for building with Java SE 8
2014-08-20 18:08:20 -05:00
Mike Primm 22d1923ad5 Add support for 1.7.10 2014-07-09 22:20:33 -05:00
Mike Primm d8d3061696 Add config defaults for MySQL map storage 2014-06-08 21:59:32 -05:00
Kevin Breslin 14da080d52 Add option to round coordinates to nearest integer 2014-05-27 01:34:11 -04:00
Kevin Breslin 10ce166b54 Fix javadoc errors for building with Java SE 8 2014-05-26 22:37:53 -04:00
Mike Primm cb9f964348 Update default suffix 2014-05-10 14:36:50 -05:00
Mike Primm 9850a03945 More comments on storage config 2014-05-10 13:47:14 -05:00
Mike Primm 8abfae3d79 Add storage/type settings to control file tree vs sqlite storage 2014-05-10 00:42:02 -05:00
Mike Primm f486ad75f1 Bump to 2.0.0-SNAPSHOT 2014-05-05 00:30:03 -05:00
Mike Primm 54b3fb429c Switch to SNAPSHOT 2014-04-20 11:47:57 -05:00
Mike Primm 86547f8d78 Bump to 1.9.5 2014-04-20 11:09:49 -05:00
Mike Primm 8ec80937e3 Add plugin versions for sources and javadoc plugins 2014-04-17 08:59:38 -05:00
Mike Primm 0e5e602a90 Add plugin versions for javadocs and sources 2014-04-16 23:02:35 -05:00
Mike Primm 3239d539c0 Add sources and javadoc generation to POM 2014-04-16 22:28:29 -05:00
Mike Primm 05bd2544fd Switch to groupID us.dynmap (owned domain) - sonatype central repo prep 2014-04-16 19:46:47 -05:00
Mike Primm 252da2a5c6 Add exportpath, default-sign-set settings 2014-03-12 00:10:17 -05:00
Mike Primm 5d83ebf8aa Add sign change API to help with marker sign support on MCPC+ 2014-03-11 23:58:01 -05:00
Mike Primm 026cc72233 Bump to 1.9.4 2014-03-08 02:31:06 -06:00
Mike Primm 0d2cceea4b Add /dynmapexp command (for OBJ exporter support) 2014-02-24 00:27:05 -06:00
Mike Primm a1dfae7f79 Bump to 1.9.2 2014-02-06 08:37:24 -06:00
Mike Primm d6eb822b26 Rework chunk loading timing stats - simpler, more useful 2014-02-04 07:05:24 -06:00
Mike Primm d4f161ca99 Remove unneeded synchronized() 2014-02-03 22:29:00 -06:00
Mike Primm 376ec447ed Revert "Add more metrics to chunk loading (for testing)"
This reverts commit 926d2a3dbc.
2014-02-03 22:27:04 -06:00
Mike Primm 926d2a3dbc Add more metrics to chunk loading (for testing) 2014-02-03 21:36:43 -06:00
Mike Primm eeffa4f98d Add stubs for block unique ID support 2014-02-01 01:16:15 -06:00
Mike Primm 8350727a73 Fix inhabitedTime field lookup 2014-01-17 23:05:54 -06:00
Mike Primm 3b79890166 Add getInhabitedTime() 2014-01-17 17:40:39 -06:00
Mike Primm 17174c177c Handle textures loading from other mods 2014-01-11 23:41:23 -06:00
Mike Primm 07e7d53a93 Add debug option for dumping IDs of blocks with no render data 2014-01-06 21:41:12 -06:00
Mike Primm 76863aeb71 Add use-brightness-table setting, and support for world-specific brightness tables 2014-01-04 21:16:29 -06:00
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
17 changed files with 1618 additions and 896 deletions
+23 -61
View File
@@ -1,11 +1,14 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.dynmap</groupId>
<groupId>us.dynmap</groupId>
<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>
@@ -42,31 +45,6 @@
</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>
<artifactId>maven-shade-plugin</artifactId>
@@ -80,8 +58,8 @@
<configuration>
<artifactSet>
<includes>
<include>org.dynmap:dynmap-api:jar:*</include>
<include>org.dynmap:DynmapCore:jar:*</include>
<include>us.dynmap:dynmap-api:jar:*</include>
<include>us.dynmap:DynmapCore:jar:*</include>
</includes>
</artifactSet>
</configuration>
@@ -89,39 +67,22 @@
</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>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>build</id>
<phase>package</phase>
<id>attach-sources</id>
<goals>
<goal>single</goal>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<releases>
</releases>
<snapshots>
</snapshots>
<id>bukkit-repo</id>
<url>http://repo.bukkit.org/content/repositories/releases/</url>
</repository>
<repository>
<releases>
</releases>
@@ -140,22 +101,18 @@
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.3.2-R3.0</version>
<version>1.7.10-R0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.dynmap</groupId>
<groupId>us.dynmap</groupId>
<artifactId>dynmap-api</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.dynmap</groupId>
<groupId>us.dynmap</groupId>
<artifactId>DynmapCore</artifactId>
<version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.getspout</groupId>
@@ -178,6 +135,11 @@
<artifactId>PermissionsBukkit</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>org.anjocaido</groupId>
<artifactId>EssentialsGroupManager</artifactId>
<version>2.10.1</version>
</dependency>
</dependencies>
<version>1.4</version>
<version>2.3-SNAPSHOT</version>
</project>
@@ -5,12 +5,15 @@ 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.bukkit.entity.Player;
import org.dynmap.Log;
import org.dynmap.utils.Polygon;
/**
* Helper for isolation of bukkit version specific issues
@@ -21,9 +24,24 @@ public abstract class BukkitVersionHelper {
public static final BukkitVersionHelper getHelper() {
if(helper == null) {
Log.info("version=" + Bukkit.getServer().getVersion());
if(Bukkit.getServer().getVersion().contains("MCPC")) {
Log.info("Loader version helper for MCPC");
helper = new BukkitVersionHelperMCPC();
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 if(Bukkit.getServer().getClass().getName().contains("GlowServer")) {
Log.info("Loading Glowstone support");
helper = new BukkitVersionHelperGlowstone();
}
else {
helper = new BukkitVersionHelperCB();
@@ -54,14 +72,10 @@ public abstract class BukkitVersionHelper {
* 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);
public abstract Object getUnloadQueue(World world);
/**
* For testing unload queue for presence of givne chunk
*/
@@ -73,11 +87,11 @@ public abstract class BukkitVersionHelper {
/**
* Test if normal chunk snapshot
*/
public abstract boolean isCraftChunkSnapshot(ChunkSnapshot css);
/**
* Remove entities from given chunk
// public abstract boolean isCraftChunkSnapshot(ChunkSnapshot css);
/**
* Get inhabited ticks count from chunk
*/
public abstract void removeEntitiesFromChunk(Chunk c);
public abstract long getInhabitedTicks(Chunk c);
/**
* Get tile entities map from chunk
*/
@@ -102,4 +116,32 @@ public abstract class BukkitVersionHelper {
* 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();
/**
* Get list of online players
*/
public abstract Player[] getOnlinePlayers();
/**
* Get player health
*/
public abstract double getHealth(Player p);
/**
* Get world border
*/
public Polygon getWorldBorder(World world) { return null; }
}
@@ -3,20 +3,36 @@ 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.ArrayList;
import java.util.Map;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.ChunkSnapshot;
import org.bukkit.Server;
import org.bukkit.World;
import org.dynmap.Log;
import org.dynmap.common.BiomeMap;
import org.dynmap.utils.Polygon;
/**
* 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
private Method getworldborder; // 1.8+ method for getting world border
private Class<?> nmsworldborder;
private Method worldborderminx;
private Method worldbordermaxx;
private Method worldborderminz;
private Method worldbordermaxz;
BukkitVersionHelperCB() {
}
@Override
@@ -34,26 +50,66 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric {
}
@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[] { "getById", "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 = getField(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" }, String.class);
biomebaseid = getField(biomebase, new String[] { "id" }, int.class);
biomebasearray = getNMSClass("[Lnet.minecraft.server.BiomeBase;");
biomebaselist = getPrivateFieldNoFail(biomebase, new String[] { "biomes" }, biomebasearray);
if (biomebaselist == null) {
biomebaseset = getPrivateField(biomebase, new String[] { "i" }, Set.class); // 1.9
}
biomebasetemp = getPrivateField(biomebase, new String[] { "temperature", "C", "F" }, float.class);
biomebasehumi = getPrivateField(biomebase, new String[] { "humidity", "D", "G" }, float.class);
biomebaseidstring = getPrivateField(biomebase, new String[] { "z", "y", "af", "ah" }, String.class);
biomebaseid = getPrivateField(biomebase, new String[] { "id", "E" }, 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);
nmsw_chunkproviderserver = getFieldNoFail(nmsworld, new String[] { "chunkProviderServer" }, chunkprovserver);
if (nmsw_chunkproviderserver == null) {
nmsw_getchunkproviderserver = getMethod(nmsworld, new String[] { "getChunkProviderServer" }, nulltypes); // 1.9
}
getworldborder = getMethodNoFail(nmsworld, new String[] { "getWorldBorder", "af" }, nulltypes);
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);
nmsc_tileentities = getField(nmschunk, new String[] { "tileEntities" }, Map.class);
nmsc_inhabitedticks = getPrivateFieldNoFail(nmschunk, new String[] { "v", "s", "q", "u" }, long.class);
if (nmsc_inhabitedticks == null) {
Log.info("inhabitedTicks field not found - inhabited shader not functional");
}
/** n.m.s.WorldBorder */
nmsworldborder = getNMSClassNoFail("net.minecraft.server.WorldBorder");
if (nmsworldborder != null) {
worldborderminx = getMethod(nmsworldborder, new String[] { "b" }, nulltypes);
worldborderminz = getMethod(nmsworldborder, new String[] { "c" }, nulltypes);
worldbordermaxx = getMethod(nmsworldborder, new String[] { "d" }, nulltypes);
worldbordermaxz = getMethod(nmsworldborder, new String[] { "e" }, nulltypes);
}
/** nbt classes */
nbttagcompound = getNMSClass("net.minecraft.server.NBTTagCompound");
nbttagbyte = getNMSClass("net.minecraft.server.NBTTagByte");
@@ -66,21 +122,157 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric {
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 = getField(nbttagbyte, new String[] { "data" }, byte.class);
nbttagshort_val = getField(nbttagshort, new String[] { "data" }, short.class);
nbttagint_val = getField(nbttagint, new String[] { "data" }, int.class);
nbttaglong_val = getField(nbttaglong, new String[] { "data" }, long.class);
nbttagfloat_val = getField(nbttagfloat, new String[] { "data" }, float.class);
nbttagdouble_val = getField(nbttagdouble, new String[] { "data" }, double.class);
nbttagbytearray_val = getField(nbttagbytearray, new String[] { "data" }, byte[].class);
nbttagstring_val = getField(nbttagstring, new String[] { "data" }, String.class);
nbttagintarray_val = getField(nbttagintarray, new String[] { "data" }, int[].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);
nmst_readnbt = getMethod(nms_tileentity, new String[] { "a", "b" }, new Class[] { nbttagcompound });
nmst_getposition = getMethodNoFail(nms_tileentity, new String[] { "getPosition" }, new Class[0]); // Try 1.8 method
if (nmst_getposition == null) {
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);
}
else { /* BlockPosition */
nms_blockposition = getNMSClass("net.minecraft.server.BlockPosition");
nmsbp_getx = getMethod(nms_blockposition, new String[] { "getX" }, new Class[0]);
nmsbp_gety = getMethod(nms_blockposition, new String[] { "getY" }, new Class[0]);
nmsbp_getz = getMethod(nms_blockposition, new String[] { "getZ" }, new Class[0]);
}
}
@Override
public void unloadChunkNoSave(World w, Chunk c, int cx, int cz) {
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];
}
@Override
public Polygon getWorldBorder(World world) {
Polygon p = null;
if ((getworldborder == null) || (world == null)) {
return null;
}
Object cw = getNMSWorld(world);
if (cw == null) return null;
Object wb = callMethod(cw, getworldborder, nullargs, null);
if (wb != null) {
double minx = (Double) callMethod(wb, worldborderminx, nullargs, Double.MIN_VALUE);
double minz = (Double) callMethod(wb, worldborderminz, nullargs, Double.MIN_VALUE);
double maxx = (Double) callMethod(wb, worldbordermaxx, nullargs, Double.MAX_VALUE);
double maxz = (Double) callMethod(wb, worldbordermaxz, nullargs, Double.MAX_VALUE);
if (maxx < 1E7) {
p = new Polygon();
p.addVertex(minx, minz);
p.addVertex(minx, maxz);
p.addVertex(maxx, maxz);
p.addVertex(maxx, minz);
}
}
return p;
}
}
@@ -3,13 +3,18 @@ package org.dynmap.bukkit;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.ChunkSnapshot;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.dynmap.Log;
/**
@@ -19,7 +24,8 @@ 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];
protected static final Object[] nullargs = new Object[0];
protected static final Class[] nulltypes = new Class[0];
private static final Map nullmap = Collections.emptyMap();
/** CraftChunkSnapshot */
@@ -36,6 +42,7 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
protected Class<?> biomebase;
protected Class<?> biomebasearray;
protected Field biomebaselist;
protected Field biomebaseset;
protected Field biomebasetemp;
protected Field biomebasehumi;
protected Field biomebaseidstring;
@@ -45,12 +52,13 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
protected Class<?> chunkprovserver;
protected Class<?> longhashset;
protected Field nmsw_chunkproviderserver;
protected Method nmsw_getchunkproviderserver;
protected Field cps_unloadqueue;
protected Method lhs_containskey;
/** n.m.s.Chunk */
protected Class<?> nmschunk;
protected Method nmsc_removeentities;
protected Field nmsc_tileentities;
protected Field nmsc_inhabitedticks;
/** nbt classes */
protected Class<?> nbttagcompound;
protected Class<?> nbttagbyte;
@@ -78,6 +86,17 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
protected Field nmst_x;
protected Field nmst_y;
protected Field nmst_z;
protected Method nmst_getposition;
/** BlockPosition */
protected Class<?> nms_blockposition;
protected Method nmsbp_getx;
protected Method nmsbp_gety;
protected Method nmsbp_getz;
/** Server */
protected Method server_getonlineplayers;
/** Player */
protected Method player_gethealth;
BukkitVersionHelperGeneric() {
failed = false;
@@ -92,20 +111,18 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
/* Craftworld fields */
craftworld = getOBCClass("org.bukkit.craftbukkit.CraftWorld");
cw_gethandle = getMethod(craftworld, new String[] { "getHandle" }, new Class[0]);
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 });
}
/* 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]);
/** Server */
server_getonlineplayers = getMethod(Server.class, new String[] { "getOnlinePlayers" }, new Class[0]);
/** Player */
player_gethealth = getMethod(Player.class, new String[] { "getHealth" }, new Class[0]);
/* Get NMS classes and fields */
if(!failed)
loadNMS();
@@ -129,7 +146,11 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
protected Class<?> getNMSClass(String classname) {
return getClassByName(classname, "net.minecraft.server", nms_package, false);
}
protected Class<?> getNMSClassNoFail(String classname) {
return getClassByName(classname, "net.minecraft.server", nms_package, true);
}
protected Class<?> getClassByName(String classname, String base, String mapping, boolean nofail) {
String n = classname;
int idx = classname.indexOf(base);
@@ -182,7 +203,13 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
/**
* Get private field
*/
private Field getPrivateField(Class<?> cls, String[] ids, Class<?> type) {
protected Field getPrivateField(Class<?> cls, String[] ids, Class<?> type) {
return getPrivateField(cls, ids, type, false);
}
protected Field getPrivateFieldNoFail(Class<?> cls, String[] ids, Class<?> type) {
return getPrivateField(cls, ids, type, true);
}
private Field getPrivateField(Class<?> cls, String[] ids, Class<?> type, boolean nofail) {
if((cls == null) || (type == null)) return null;
for(String id : ids) {
try {
@@ -194,11 +221,13 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
} catch (NoSuchFieldException nsfx) {
}
}
Log.severe("Unable to find field " + ids[0] + " for " + cls.getName());
failed = true;
if(!nofail) {
Log.severe("Unable to find field " + ids[0] + " for " + cls.getName());
failed = true;
}
return null;
}
private Object getFieldValue(Object obj, Field field, Object def) {
protected Object getFieldValue(Object obj, Field field, Object def) {
if((obj != null) && (field != null)) {
try {
return field.get(obj);
@@ -224,7 +253,18 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
failed = true;
return null;
}
private Object callMethod(Object obj, Method meth, Object[] args, Object def) {
protected Method getMethodNoFail(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) {
}
}
return null;
}
protected Object callMethod(Object obj, Method meth, Object[] args, Object def) {
if((obj == null) || (meth == null)) {
return def;
}
@@ -242,7 +282,11 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
* Get list of defined biomebase objects
*/
public Object[] getBiomeBaseList() {
return (Object[]) getFieldValue(biomebase, biomebaselist, new Object[0]);
if (biomebaselist != null) {
return (Object[]) getFieldValue(biomebase, biomebaselist, new Object[0]);
} else {
return ((Set) getFieldValue(biomebase, biomebaselist, Collections.emptySet())).toArray();
}
}
/** Get temperature from biomebase */
public float getBiomeBaseTemperature(Object bb) {
@@ -262,13 +306,18 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
}
/* Get net.minecraft.server.world for given world */
public Object getNMSWorld(World w) {
protected 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
public Object getUnloadQueue(World world) {
Object cps = null;
if (nmsw_chunkproviderserver != null) {
cps = getFieldValue(getNMSWorld(world), nmsw_chunkproviderserver, null);
} else {
cps = callMethod(getNMSWorld(world), nmsw_getchunkproviderserver, nullargs, null);
}
if(cps != null) {
return getFieldValue(cps, cps_unloadqueue, null);
}
@@ -286,19 +335,28 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
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());
// public boolean isCraftChunkSnapshot(ChunkSnapshot css) {
// if(craftchunksnapshot != null) {
// return craftchunksnapshot.isAssignableFrom(css.getClass());
// }
// return false;
// }
/**
* Get inhabited ticks count from chunk
*/
private static final Long zero = new Long(0);
public long getInhabitedTicks(Chunk c) {
if (nmsc_inhabitedticks == null) {
return 0;
}
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);
return (Long)getFieldValue(omsc, nmsc_inhabitedticks, zero);
}
return 0;
}
/** Get tile entities map from chunk */
public Map getTileEntitiesForChunk(Chunk c) {
Object omsc = callMethod(c, cc_gethandle, nullargs, null);
@@ -311,19 +369,37 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
* Get X coordinate of tile entity
*/
public int getTileEntityX(Object te) {
return (Integer)getFieldValue(te, nmst_x, 0);
if (nmst_getposition == null) {
return (Integer)getFieldValue(te, nmst_x, 0);
}
else {
Object pos = callMethod(te, nmst_getposition, nullargs, null);
return (Integer) callMethod(pos, nmsbp_getx, nullargs, null);
}
}
/**
* Get Y coordinate of tile entity
*/
public int getTileEntityY(Object te) {
return (Integer)getFieldValue(te, nmst_y, 0);
if (nmst_getposition == null) {
return (Integer)getFieldValue(te, nmst_y, 0);
}
else {
Object pos = callMethod(te, nmst_getposition, nullargs, null);
return (Integer) callMethod(pos, nmsbp_gety, nullargs, null);
}
}
/**
* Get Z coordinate of tile entity
*/
public int getTileEntityZ(Object te) {
return (Integer)getFieldValue(te, nmst_z, 0);
if (nmst_getposition == null) {
return (Integer)getFieldValue(te, nmst_z, 0);
}
else {
Object pos = callMethod(te, nmst_getposition, nullargs, null);
return (Integer) callMethod(pos, nmsbp_getz, nullargs, null);
}
}
/**
* Read tile entity NBT
@@ -377,4 +453,32 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper {
}
return null;
}
/**
* Get list of online players
*/
public Player[] getOnlinePlayers() {
Object players = callMethod(Bukkit.getServer(), server_getonlineplayers, nullargs, null);
if (players instanceof Player[]) { /* Pre 1.7.10 */
return (Player[]) players;
}
else {
@SuppressWarnings("unchecked")
Collection<? extends Player> p = (Collection<? extends Player>) players;
return p.toArray(new Player[0]);
}
}
/**
* Get player health
*/
@Override
public double getHealth(Player p) {
Object health = callMethod(p, player_gethealth, nullargs, null);
if (health instanceof Integer) {
return (Integer) health;
}
else {
return ((Double) health).intValue();
}
}
}
@@ -0,0 +1,445 @@
package org.dynmap.bukkit;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
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.bukkit.entity.Player;
public class BukkitVersionHelperGlowstone extends BukkitVersionHelper {
private Method rawbiome;
private Method server_getonlineplayers;
public BukkitVersionHelperGlowstone() {
try {
Class<?> c = Class.forName("net.glowstone.GlowChunkSnapshot");
rawbiome = c.getMethod("getRawBiomes", new Class[0]);
/** Server */
server_getonlineplayers = Server.class.getMethod("getOnlinePlayers", new Class[0]);
} catch (SecurityException e) {
} catch (NoSuchMethodException e) {
} catch (ClassNotFoundException e) {
}
if ((rawbiome == null) && (server_getonlineplayers == null)) {
throw new IllegalArgumentException("Error initializing dynmap - Glowstone version incompatible!");
}
}
@Override
public Object[] getBiomeBaseList() {
return new Object[0];
}
@Override
public float getBiomeBaseTemperature(Object bb) {
return 0;
}
@Override
public float getBiomeBaseHumidity(Object bb) {
return 0;
}
@Override
public String getBiomeBaseIDString(Object bb) {
return "";
}
@Override
public int getBiomeBaseID(Object bb) {
if (bb != null)
return (Integer) bb;
else
return 0;
}
@Override
public Object getUnloadQueue(World world) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isInUnloadQueue(Object unloadqueue, int x, int z) {
// TODO Auto-generated method stub
return false;
}
@Override
public Object[] getBiomeBaseFromSnapshot(ChunkSnapshot css) {
Integer b[] = new Integer[256];
byte[] rb = null;
try {
rb = (byte[]) rawbiome.invoke(css, new Object[0]);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
if (rb != null) {
for (int i = 0; i < 256; i++) {
b[i] = Integer.valueOf(255 & (int)rb[i]);
}
}
return b;
}
@Override
public long getInhabitedTicks(Chunk c) {
// TODO Auto-generated method stub
return 0;
}
@Override
public Map getTileEntitiesForChunk(Chunk c) {
// TODO Auto-generated method stub
return Collections.emptyMap();
}
@Override
public int getTileEntityX(Object te) {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getTileEntityY(Object te) {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getTileEntityZ(Object te) {
// TODO Auto-generated method stub
return 0;
}
@Override
public Object readTileEntityNBT(Object te) {
// TODO Auto-generated method stub
return null;
}
@Override
public Object getFieldValue(Object nbt, String field) {
// TODO Auto-generated method stub
return null;
}
@Override
public void unloadChunkNoSave(World w, Chunk c, int cx, int cz) {
// TODO Auto-generated method stub
}
@Override
public String[] getBlockShortNames() {
// TODO Auto-generated method stub
return null;
}
private static final String[] bnames = {
"Ocean",
"Plains",
"Desert",
"Extreme Hills",
"Forest",
"Taiga",
"Swampland",
"River",
"Hell",
"Sky",
"FrozenOcean",
"FrozenRiver",
"Ice Plains",
"Ice Mountains",
"MushroomIsland",
"MushroomIslandShore",
"Beach",
"DesertHills",
"ForestHills",
"TaigaHills",
"Extreme Hills Edge",
"Jungle",
"JungleHills",
"JungleEdge",
"Deep Ocean",
"Stone Beach",
"Cold Beach",
"Birch Forest",
"Birch Forest Hills",
"Roofed Forest",
"Cold Taiga",
"Cold Taiga Hills",
"Mega Taiga",
"Mega Taiga Hills",
"Extreme Hills+",
"Savanna",
"Savanna Plateau",
"Mesa",
"Mesa Plateau F",
"Mesa Plateau",
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
"Sunflower Plains",
"Desert M",
"Extreme Hills M",
"Flower Forest",
"Taiga M",
"Swampland M",
null,
null,
null,
null,
null,
"Ice Plains Spikes",
null,
null,
null,
null,
null,
null,
null,
null,
"Jungle M",
null,
"JungleEdge M",
null,
null,
null,
"Birch Forest M",
"Birch Forest Hills M",
"Roofed Forest M",
"Cold Taiga M",
null,
"Mega Spruce Taiga",
"Mega Spruce Taiga",
"Extreme Hills+ M",
"Savanna M",
"Savanna Plateau M",
"Mesa (Bryce)",
"Mesa Plateau F M",
"Mesa Plateau M",
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null
};
@Override
public String[] getBiomeNames() {
return bnames;
}
@Override
public int[] getBlockMaterialMap() {
// TODO Auto-generated method stub
return null;
}
/**
* Get list of online players
*/
public Player[] getOnlinePlayers() {
Object players;
try {
players = server_getonlineplayers.invoke(Bukkit.getServer(), new Object[0]);
if (players instanceof Player[]) { /* Pre 1.7.10 */
return (Player[]) players;
}
else {
@SuppressWarnings("unchecked")
Collection<? extends Player> p = (Collection<? extends Player>) players;
return p.toArray(new Player[0]);
}
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
return new Player[0];
}
@Override
public double getHealth(Player p) {
return p.getHealth();
}
}
@@ -1,81 +0,0 @@
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 class BukkitVersionHelperMCPC extends BukkitVersionHelperGeneric {
BukkitVersionHelperMCPC() {
}
@Override
protected String getNMSPackage() {
return "";
}
@Override
protected void loadNMS() {
/* biomebase */
biomebase = getNMSClass("yy");
biomebasearray = getNMSClass("[Lyy;");
/* world */
nmsworld = getNMSClass("in");
/* chunk */
chunkprovserver = getNMSClass("im");
nmschunk = getNMSClass("zz");
/* nbt */
nbttagcompound = getNMSClass("bq");
nbttagbyte = getNMSClass("bp");
nbttagshort = getNMSClass("cb");
nbttagint = getNMSClass("bx");
nbttaglong = getNMSClass("bz");
nbttagfloat = getNMSClass("bv");
nbttagdouble = getNMSClass("bt");
nbttagbytearray = getNMSClass("bo");
nbttagstring = getNMSClass("cc");
nbttagintarray = getNMSClass("bw");
/* tileentity */
nms_tileentity = getNMSClass("any");
/** Set up NMS fields **/
/* biomebase */
biomebaselist = getField(biomebase, new String[] { "a" }, biomebasearray);
biomebasetemp = getField(biomebase, new String[] { "F" }, float.class);
biomebasehumi = getField(biomebase, new String[] { "G" }, float.class);
biomebaseidstring = getField(biomebase, new String[] { "y" }, String.class);
biomebaseid = getField(biomebase, new String[] { "N" }, int.class);
/* chunk */
nmsw_chunkproviderserver = getField(nmsworld, new String[] { "b" }, chunkprovserver);
cps_unloadqueue = getFieldNoFail(chunkprovserver, new String[] { "b" }, longhashset);
if(cps_unloadqueue == null) {
Log.info("Unload queue not found - default to unload all chunks");
}
nmsc_removeentities = getMethod(nmschunk, new String[] { "d" }, new Class[0]);
nmsc_tileentities = getField(nmschunk, new String[] { "i" }, Map.class);
/* nbt */
compound_get = getMethod(nbttagcompound, new String[] { "a" }, new Class[] { String.class });
nbttagbyte_val = getField(nbttagbyte, new String[] { "a" }, byte.class);
nbttagshort_val = getField(nbttagshort, new String[] { "a" }, short.class);
nbttagint_val = getField(nbttagint, new String[] { "a" }, int.class);
nbttaglong_val = getField(nbttaglong, new String[] { "a" }, long.class);
nbttagfloat_val = getField(nbttagfloat, new String[] { "a" }, float.class);
nbttagdouble_val = getField(nbttagdouble, new String[] { "a" }, double.class);
nbttagbytearray_val = getField(nbttagbytearray, new String[] { "a" }, byte[].class);
nbttagstring_val = getField(nbttagstring, new String[] { "a" }, String.class);
nbttagintarray_val = getField(nbttagintarray, new String[] { "a" }, int[].class);
/* tileentity */
nmst_readnbt = getMethod(nms_tileentity, new String[] { "b" }, new Class[] { nbttagcompound });
nmst_x = getField(nms_tileentity, new String[] { "l" }, int.class);
nmst_y = getField(nms_tileentity, new String[] { "m" }, int.class);
nmst_z = getField(nms_tileentity, new String[] { "n" }, int.class);
}
}
@@ -2,16 +2,24 @@ 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.block.Block;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;
import org.dynmap.DynmapChunk;
import org.dynmap.DynmapLocation;
import org.dynmap.DynmapWorld;
import org.dynmap.utils.MapChunkCache;
import org.dynmap.utils.Polygon;
import org.dynmap.utils.TileFlags;
public class BukkitWorld extends DynmapWorld {
private World world;
@@ -30,6 +38,20 @@ public class BukkitWorld extends DynmapWorld {
this.env = env;
skylight = (env == World.Environment.NORMAL);
new Permission("dynmap.world." + getName(), "Dynmap access for world " + getName(), PermissionDefault.OP);
// Generate non-default environment lighting table
switch (env) {
case NETHER:
{
float f = 0.1F;
for (int i = 0; i <= 15; ++i) {
float f1 = 1.0F - (float)i / 15.0F;
this.setBrightnessTableEntry(i, (1.0F - f1) / (f1 * 3.0F + 1.0F) * (1.0F - f) + f);
}
}
break;
default:
break;
}
}
/**
* Set world online
@@ -104,7 +126,10 @@ public class BukkitWorld extends DynmapWorld {
@Override
public int getLightLevel(int x, int y, int z) {
if(world != null) {
return world.getBlockAt(x, y, z).getLightLevel();
if ((y >= 0) && (y < this.worldheight)) {
return world.getBlockAt(x, y, z).getLightLevel();
}
return 0;
}
else {
return -1;
@@ -129,7 +154,12 @@ public class BukkitWorld extends DynmapWorld {
@Override
public int getSkyLightLevel(int x, int y, int z) {
if(world != null) {
return world.getBlockAt(x, y, z).getLightFromSky();
if ((y >= 0) && (y < this.worldheight)) {
return world.getBlockAt(x, y, z).getLightFromSky();
}
else {
return 15;
}
}
else {
return -1;
@@ -160,4 +190,61 @@ public class BukkitWorld extends DynmapWorld {
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;
}
@Override
public Polygon getWorldBorder() {
return DynmapPlugin.plugin.getWorldBorder(world);
}
}
File diff suppressed because it is too large Load Diff
+8 -4
View File
@@ -56,9 +56,9 @@ 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>
* <code>
* Graph createGraph(String name); <br/>
* void addCustomData(BukkitMetrics.Plotter plotter); <br/>
* void start(); <br/>
* Graph createGraph(String name); <br>
* void addCustomData(BukkitMetrics.Plotter plotter); <br>
* void start(); <br>
* </code>
*/
public class Metrics {
@@ -121,6 +121,8 @@ public class Metrics {
*/
private volatile BukkitTask task = null;
private BukkitVersionHelper helper;
public Metrics(final Plugin plugin) throws IOException {
if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null");
@@ -146,6 +148,8 @@ public class Metrics {
// Load the guid then
guid = configuration.getString("guid");
debug = configuration.getBoolean("debug", false);
helper = BukkitVersionHelper.getHelper();
}
/**
@@ -359,7 +363,7 @@ public class Metrics {
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;
int playersOnline = helper.getOnlinePlayers().length;
// END server software specific section -- all code below does not use any code outside of this class / Java
File diff suppressed because it is too large Load Diff
@@ -3,6 +3,7 @@ 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;
@@ -13,6 +14,7 @@ import org.dynmap.utils.DynIntHashMap;
public class SnapshotCache {
public static class SnapshotRec {
public ChunkSnapshot ss;
public long inhabitedTicks;
public DynIntHashMap tileData;
};
@@ -20,9 +22,10 @@ public class SnapshotCache {
private ReferenceQueue<SnapshotRec> refqueue;
private long cache_attempts;
private long cache_success;
private boolean softref;
private static class CacheRec {
WeakReference<SnapshotRec> ref;
Reference<SnapshotRec> ref;
boolean hasbiome;
boolean hasrawbiome;
boolean hasblockdata;
@@ -32,12 +35,12 @@ public class SnapshotCache {
@SuppressWarnings("serial")
public class CacheHashMap extends LinkedHashMap<String, CacheRec> {
private int limit;
private IdentityHashMap<WeakReference<SnapshotRec>, String> reverselookup;
private IdentityHashMap<Reference<SnapshotRec>, String> reverselookup;
public CacheHashMap(int lim) {
super(16, (float)0.75, true);
limit = lim;
reverselookup = new IdentityHashMap<WeakReference<SnapshotRec>, String>();
reverselookup = new IdentityHashMap<Reference<SnapshotRec>, String>();
}
protected boolean removeEldestEntry(Map.Entry<String, CacheRec> last) {
boolean remove = (size() >= limit);
@@ -51,9 +54,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<SnapshotRec>();
this.softref = softref;
}
private String getKey(String w, int cx, int cz) {
return w + ":" + cx + ":" + cz;
@@ -127,7 +131,10 @@ public class SnapshotCache {
rec.hasbiome = biome;
rec.hasrawbiome = biomeraw;
rec.hashighesty = highesty;
rec.ref = new WeakReference<SnapshotRec>(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);
@@ -1,260 +0,0 @@
package org.dynmap.bukkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import javax.imageio.ImageIO;
import org.bukkit.Material;
import org.bukkit.plugin.Plugin;
import org.dynmap.DynmapCore;
import org.dynmap.Log;
import org.getspout.spoutapi.block.design.BlockDesign;
import org.getspout.spoutapi.block.design.GenericBlockDesign;
import org.getspout.spoutapi.block.design.GenericCuboidBlockDesign;
import org.getspout.spoutapi.block.design.Texture;
import org.getspout.spoutapi.material.CustomBlock;
import org.getspout.spoutapi.material.MaterialData;
/**
* Handler for pulling spout-defined custom blocks into dynmap
*
* Generates and maintains custom render data file (renderdata/spout-texture.txt) and
* directory of downloaded image files (texturepacks/standard/spout/plugin.blockid.png)
*/
public class SpoutPluginBlocks {
private Field textXPosField; /* float[][] textXPos */
private Field textYPosField; /* float[][] textYPos */
private HashSet<String> plugins_pending = new HashSet<String>();
public SpoutPluginBlocks(Plugin plugin) {
/* First, see if any spout plugins that need to be enabled */
for(Plugin p : plugin.getServer().getPluginManager().getPlugins()) {
List<String> dep = p.getDescription().getDepend();
if((dep != null) && (dep.contains("Spout"))) {
Log.info("Found Spout plugin: " + p.getName());
if(p.isEnabled() == false) {
plugins_pending.add(p.getName());
}
}
}
}
public boolean isReady() {
return plugins_pending.isEmpty();
}
public void markPluginEnabled(Plugin p) {
plugins_pending.remove(p.getName());
}
private boolean initSpoutAccess() {
boolean success = false;
try {
textXPosField = GenericBlockDesign.class.getDeclaredField("textXPos");
textXPosField.setAccessible(true);
textYPosField = GenericBlockDesign.class.getDeclaredField("textYPos");
textYPosField.setAccessible(true);
success = true;
} catch (NoSuchFieldException nsfx) {
Log.severe("Cannot access needed Spout custom block fields!");
Log.severe(nsfx);
}
return success;
}
private void addDefaultBlock(StringBuilder sb, CustomBlock blk) {
if(blk.isOpaque())
sb.append("block:id=" + blk.getCustomId() + ",data=*,allfaces=1\n");
else
sb.append("block:id=" + blk.getCustomId() + ",allfaces=12049,transparency=TRANSPARENT\n");
}
private static String fixIDString(String id) {
StringBuilder sb = new StringBuilder();
int len = id.length();
sb.setLength(len);
for(int i = 0; i < len; i++) {
char c = id.charAt(i);
if(Character.isJavaIdentifierStart(c)) {
sb.setCharAt(i, c);
}
else {
sb.setCharAt(i, '_');
}
}
return sb.toString();
}
/* Process spout blocks - return true if something changed */
public boolean processSpoutBlocks(DynmapPlugin plugin, DynmapCore core) {
File datadir = core.getDataFolder();
if(textYPosField == null) {
if(initSpoutAccess() == false)
return false;
}
HashMap<String, String> texturelist = new HashMap<String, String>();
boolean use_existing_texture = core.configuration.getBoolean("spout/use-existing-textures", true);
int cnt = 0;
File f = new File(datadir, "texturepacks/standard/spout");
if(f.exists() == false)
f.mkdirs();
List<CustomBlock> blks = new ArrayList<CustomBlock>();
CustomBlock[] cb = MaterialData.getCustomBlocks();
/* Build new texture file as string */
StringBuilder sb = new StringBuilder();
/* 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 not GenericCubiodBlockDesign, we don't handle it */
if((bd instanceof GenericCuboidBlockDesign) == false) {
Log.info("Block " + blkid + " not suppored - only cubiod blocks");
addDefaultBlock(sb, b);
continue;
}
/* Get texture info */
Texture txt = bd.getTexture();
int w = txt.getWidth();
int h = txt.getHeight();
int sz = txt.getSpriteSize();
GenericCuboidBlockDesign gbd = (GenericCuboidBlockDesign)bd;
int[] txtidx = new int[6];
/* Fetch quad fields - figure out which texture for which side */
try {
float[][] textXPos = (float[][])textXPosField.get(gbd);
float[][] textYPos = (float[][])textYPosField.get(gbd);
/* Quads on cuboid are bottom, west, south, east, north, top */
for(int i = 0; i < 6; i++) {
float minx = 1.0F;
float miny = 1.0F;
for(int j = 0; j < 4; j++) {
minx = Math.min(minx, textXPos[i][j]);
miny = Math.min(miny, textYPos[i][j]);
}
txtidx[i] = (int)((minx * w)/sz) + (w/sz)*(int)((miny * h)/sz);
}
} catch (Exception iax) {
addDefaultBlock(sb, b);
continue;
}
String txname = bd.getTexureURL();
String txtid = texturelist.get(txname); /* Get texture */
if(txtid == null) { /* Not found yet */
File imgfile = new File(f, blkid + ".png");
/* If not reusing loaded textures OR not previously loaded */
if((!use_existing_texture) || (!imgfile.exists())) {
BufferedImage img = null;
boolean urlloaded = false;
try {
URL url = new URL(txname);
img = ImageIO.read(url); /* Load skin for player */
urlloaded = true;
} catch (IOException iox) {
if(txname.startsWith("http") == false) { /* Not URL - try file */
File tf = new File(txname);
if(tf.exists() == false) {
/* Horrible hack - try to find temp file (some SpoutMaterials versions) */
try {
File tmpf = File.createTempFile("dynmap", "test");
tf = new File(tmpf.getParent(), txname);
tmpf.delete();
} catch (IOException iox2) {}
}
if(tf.exists()) {
try {
img = ImageIO.read(tf);
urlloaded = true;
} catch (IOException iox3) {
}
}
}
if(img == null) {
Log.severe("Error loading texture for custom block '" + blkid + "' (" + b.getCustomId() + ") from " + txname + "(" + iox.getMessage() + ")");
if(imgfile.exists()) {
try {
img = ImageIO.read(imgfile); /* Load existing */
Log.info("Loaded cached texture file for " + blkid);
} catch (IOException iox2) {
Log.severe("Error loading cached texture file for " + blkid + " - " + iox2.getMessage());
}
}
}
}
if(img != null) {
try {
if(urlloaded)
ImageIO.write(img, "png", imgfile);
} catch (IOException iox) {
Log.severe("Error writing " + blkid + ".png");
} finally {
img.flush();
}
}
}
if(imgfile.exists()) { /* If exists now, log it */
String tfid = "txtid" + texturelist.size();
sb.append("texturefile:id=" + tfid + ",filename=spout/" + blkid + ".png,xcount=" + w/sz + ",ycount=" + h/sz + "\n");
texturelist.put(txname, tfid);
}
}
String txfileid = texturelist.get(txname);
if(txfileid != null) {
blks.add(b);
sb.append("block:id=" + b.getCustomId() + ",data=*,bottom=" + txtidx[0] + ",west=" +txtidx[1] + ",south=" + txtidx[2] + ",east=" + txtidx[3] + ",north="+txtidx[4]+",top="+txtidx[5]);
if(b.getBlockId() == Material.GLASS.getId())
sb.append(",transparency=TRANSPARENT");
sb.append(",txtid=" + txfileid + "\n");
cnt++;
}
}
String rslt = sb.toString();
/* Now, generate spout texture file - see if changed */
File st = new File(datadir, "renderdata/spout-texture.txt");
if(st.exists()) {
FileReader fr = null;
StringBuilder sbold = new StringBuilder();
try {
fr = new FileReader(st);
int len;
char[] buf = new char[512];
while((len = fr.read(buf)) > 0) {
sbold.append(buf, 0, len);
}
} catch (IOException iox) {
} finally {
if(fr != null) { try { fr.close(); } catch (IOException iox) {} }
}
/* If same, no changes */
if(sbold.equals(rslt)) {
Log.info("Loaded " + cnt + " Spout custom blocks");
return false;
}
}
FileWriter fw = null;
try {
fw = new FileWriter(st);
fw.write(rslt);
} catch (IOException iox) {
Log.severe("Error opening spout texture file - " + st.getPath());
return false;
} finally {
if(fw != null) { try { fw.close(); } catch (IOException iox) {} }
}
Log.info("Loaded " + cnt + " Spout custom blocks");
return false;
}
}
@@ -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);
}
+109 -13
View File
@@ -1,16 +1,39 @@
# 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
deftemplatesuffix: vlowres
# 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: hires
# Map storage scheme: only uncomment one 'type' value
# filetree: classic and default scheme: tree of files, with all map data under the directory indicated by 'tilespath' setting
# sqlite: single SQLite database file (this can get VERY BIG), located at 'dbfile' setting (default is file dynmap.db in data directory)
# mysql: MySQL database, at hostname:port in database, accessed via userid with password
storage:
# Filetree storage (standard tree of image files for maps)
type: filetree
# SQLite db for map storage (uses dbfile as storage location)
#type: sqlite
#dbfile: dynmap.db
# MySQL DB for map storage (at 'hostname':'port' in database 'database' using user 'userid' password 'password' and table prefix 'prefix'
#type: mysql
#hostname: localhost
#port: 3306
#database: dynmap
#userid: dynmap
#password: dynmap
#prefix: ""
components:
- class: org.dynmap.ClientConfigurationComponent
@@ -22,6 +45,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
@@ -44,6 +69,8 @@ components:
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
@@ -52,6 +79,7 @@ components:
# 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
@@ -65,6 +93,7 @@ components:
# # Limit length of single chat messages
# chatlengthlimit: 256
# hide-if-invisiblity-potion: true
# hidenames: false
- class: org.dynmap.SimpleWebChatComponent
allowchat: true
@@ -76,6 +105,8 @@ components:
type: markers
showlabel: false
enablesigns: false
# Default marker set for sign markers
default-sign-set: markers
# (optional) add spawn point markers to standard marker layer
showspawn: true
spawnicon: world
@@ -94,6 +125,8 @@ components:
spawnbedhidebydefault: true
spawnbedminzoom: 0
spawnbedformat: "%name%'s bed"
# (optional) show world border (vanilla 1.8+)
showworldborder: true
- class: org.dynmap.ClientComponent
type: chat
@@ -183,9 +216,15 @@ 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.
@@ -201,8 +240,19 @@ 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 - use world provider lighting table (good for custom worlds with custom lighting curves, like nether)
# false=classic Dynmap lighting curve
use-brightness-table: 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
@@ -214,6 +264,11 @@ 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
@@ -221,7 +276,7 @@ transparent-leaves: true
#refreshskins: false
# Customize URL used for fetching player skins (%player% is macro for name)
skin-url: "http://s3.amazonaws.com/MinecraftSkins/%player%.png"
skin-url: "http://skins.minecraft.net/MinecraftSkins/%player%.png"
# Control behavior for new (1.0+) compass orientation (sunrise moved 90 degrees: east is now what used to be south)
# default is 'newrose' (preserve pre-1.0 maps, rotate rose)
@@ -256,8 +311,12 @@ tilespath: web/tiles
# The path where the web-files are located.
webpath: web
# The path were the /dynmapexp command exports OBJ ZIP files
exportpath: export
# 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
@@ -293,14 +352,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
@@ -314,8 +388,10 @@ 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%"
@@ -340,12 +416,17 @@ persist-ids-by-ip: true
# If true, map text to cyrillic
cyrillic-support: false
# If true, coordinates will be rounded
round-coordinates: true
# 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:
@@ -373,6 +454,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
@@ -380,3 +474,5 @@ verbose: false
# Enables debugging.
#debuggers:
# - class: org.dynmap.debug.LogDebugger
# Debug: dump blocks missing render data
dump-missing-blocks: false
+59 -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
@@ -100,6 +116,10 @@ commands:
/<command> mapset worldname:mapname attrib:value attrib:value - update given map on given world with given attributes
/<command> worldreset worldname - reset given world to default template for world type
/<command> worldreset worldname templatename - reset given world to given template
dynmapexp:
description: Map export commands
usage: |
/<command> shader <shadername> - Export material library for shader <shadername>
permissions:
dynmap.*:
@@ -119,6 +139,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 +169,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 +227,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 +248,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 +329,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