Initial function 1.14.4 Forge build!

This commit is contained in:
Mike Primm 2020-05-23 18:46:29 -05:00
parent f039257e19
commit 1d61efd62a
6 changed files with 168 additions and 339 deletions

View File

@ -18,7 +18,7 @@ allprojects {
apply plugin: 'java' apply plugin: 'java'
group = 'us.dynmap' group = 'us.dynmap'
version = '3.0-RC2' version = '3.0-SNAPSHOT'
} }

View File

@ -18,6 +18,7 @@ ext.buildNumber = System.getenv().BUILD_NUMBER ?: "Dev"
minecraft { minecraft {
mappings channel: 'snapshot', version: '20190719-1.14.3' mappings channel: 'snapshot', version: '20190719-1.14.3'
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
runs { runs {
server { server {
workingDirectory project.file('run').canonicalPath workingDirectory project.file('run').canonicalPath

View File

@ -58,7 +58,9 @@ import net.minecraft.world.World;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkSection; import net.minecraft.world.chunk.ChunkSection;
import net.minecraft.world.chunk.ChunkStatus;
import net.minecraft.world.chunk.IChunk; import net.minecraft.world.chunk.IChunk;
import net.minecraft.world.server.ChunkHolder;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.ServerChatEvent; import net.minecraftforge.event.ServerChatEvent;
@ -67,6 +69,8 @@ import net.minecraftforge.event.entity.player.PlayerEvent.PlayerChangedDimension
import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedInEvent; import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedInEvent;
import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedOutEvent; import net.minecraftforge.event.entity.player.PlayerEvent.PlayerLoggedOutEvent;
import net.minecraftforge.event.entity.player.PlayerEvent.PlayerRespawnEvent; import net.minecraftforge.event.entity.player.PlayerEvent.PlayerRespawnEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.event.world.ChunkDataEvent;
import net.minecraftforge.event.world.ChunkEvent; import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.ModList;
@ -125,7 +129,11 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder; import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSortedSet;
import net.minecraft.state.IProperty; import net.minecraft.state.IProperty;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
public class DynmapPlugin public class DynmapPlugin
@ -156,7 +164,6 @@ public class DynmapPlugin
private long avgticklen; private long avgticklen;
// Per tick limit, in nsec // Per tick limit, in nsec
private long perTickLimit = (50000000); // 50 ms private long perTickLimit = (50000000); // 50 ms
private boolean isMCPC = false;
private boolean useSaveFolder = true; private boolean useSaveFolder = true;
private static final int SIGNPOST_ID = 63; private static final int SIGNPOST_ID = 63;
@ -174,7 +181,31 @@ public class DynmapPlugin
ConcurrentLinkedQueue<BlockUpdateRec> blockupdatequeue = new ConcurrentLinkedQueue<BlockUpdateRec>(); ConcurrentLinkedQueue<BlockUpdateRec> blockupdatequeue = new ConcurrentLinkedQueue<BlockUpdateRec>();
public static DynmapBlockState[] stateByID; public static DynmapBlockState[] stateByID;
private Map<String, LongOpenHashSet> knownloadedchunks = new HashMap<String, LongOpenHashSet>();
private boolean didInitialKnownChunks = false;
private void addKnownChunk(ForgeWorld fw, ChunkPos pos) {
LongOpenHashSet cset = knownloadedchunks.get(fw.getName());
if (cset == null) {
cset = new LongOpenHashSet();
knownloadedchunks.put(fw.getName(), cset);
}
cset.add(pos.asLong());
}
private void removeKnownChunk(ForgeWorld fw, ChunkPos pos) {
LongOpenHashSet cset = knownloadedchunks.get(fw.getName());
if (cset != null) {
cset.remove(pos.asLong());
}
}
private boolean checkIfKnownChunk(ForgeWorld fw, ChunkPos pos) {
LongOpenHashSet cset = knownloadedchunks.get(fw.getName());
if (cset != null) {
return cset.contains(pos.asLong());
}
return false;
}
/** /**
* Initialize block states (org.dynmap.blockstate.DynmapBlockState) * Initialize block states (org.dynmap.blockstate.DynmapBlockState)
*/ */
@ -962,10 +993,8 @@ public class DynmapPlugin
core.listenerManager.processChatEvent(EventType.PLAYER_CHAT, dp, cm.message); core.listenerManager.processChatEvent(EventType.PLAYER_CHAT, dp, cm.message);
} }
/* Check for idle worlds */ // Check for generated chunks
if((cur_tick % 20) == 0) { if((cur_tick % 20) == 0) {
//TODO
//doIdleOutOfWorlds();
} }
} }
@ -1025,22 +1054,26 @@ public class DynmapPlugin
@Override @Override
public InputStream openResource(String modid, String rname) { public InputStream openResource(String modid, String rname) {
if (modid != null) { if (modid == null) modid = "minecraft";
Optional<? extends ModContainer> mc = ModList.get().getModContainerById(modid);
Object mod = (mc.isPresent()) ? mc.get().getMod() : null; Optional<? extends ModContainer> mc = ModList.get().getModContainerById(modid);
if (mod != null) { Object mod = (mc.isPresent()) ? mc.get().getMod() : null;
InputStream is = mod.getClass().getClassLoader().getResourceAsStream(rname); if (mod != null) {
if (is != null) { ClassLoader cl = mod.getClass().getClassLoader();
return is; if (cl == null) cl = ClassLoader.getSystemClassLoader();
} InputStream is = cl.getResourceAsStream(rname);
if (is != null) {
return is;
} }
} }
List<ModInfo> mcl = ModList.get().getMods(); List<ModInfo> mcl = ModList.get().getMods();
for (ModInfo mci : mcl) { for (ModInfo mci : mcl) {
Optional<? extends ModContainer> mc = ModList.get().getModContainerById(mci.getModId()); mc = ModList.get().getModContainerById(mci.getModId());
Object mod = (mc.isPresent()) ? mc.get().getMod() : null; mod = (mc.isPresent()) ? mc.get().getMod() : null;
if (mod == null) continue; if (mod == null) continue;
InputStream is = mod.getClass().getClassLoader().getResourceAsStream(rname); ClassLoader cl = mod.getClass().getClassLoader();
if (cl == null) cl = ClassLoader.getSystemClassLoader();
InputStream is = cl.getResourceAsStream(rname);
if (is != null) { if (is != null) {
return is; return is;
} }
@ -1393,6 +1426,7 @@ public class DynmapPlugin
loadExtraBiomes(mcver); loadExtraBiomes(mcver);
/* Set up player login/quit event handler */ /* Set up player login/quit event handler */
registerPlayerLoginListener(); registerPlayerLoginListener();
/* Initialize permissions handler */ /* Initialize permissions handler */
permissions = FilePermissions.create(); permissions = FilePermissions.create();
if(permissions == null) { if(permissions == null) {
@ -1507,9 +1541,6 @@ public class DynmapPlugin
registerEvents(); registerEvents();
Log.info("Register events"); Log.info("Register events");
/* Submit metrics to mcstats.org */
initMetrics();
//DynmapCommonAPIListener.apiInitialized(core); //DynmapCommonAPIListener.apiInitialized(core);
Log.info("Enabled"); Log.info("Enabled");
@ -1616,7 +1647,7 @@ public class DynmapPlugin
} }
public class WorldTracker { public class WorldTracker {
@SubscribeEvent @SubscribeEvent(priority=EventPriority.LOWEST)
public void handleWorldLoad(WorldEvent.Load event) { public void handleWorldLoad(WorldEvent.Load event) {
if(!core_enabled) return; if(!core_enabled) return;
IWorld w = event.getWorld(); IWorld w = event.getWorld();
@ -1630,7 +1661,7 @@ public class DynmapPlugin
} }
}, 0); }, 0);
} }
@SubscribeEvent @SubscribeEvent(priority=EventPriority.LOWEST)
public void handleWorldUnload(WorldEvent.Unload event) { public void handleWorldUnload(WorldEvent.Unload event) {
if(!core_enabled) return; if(!core_enabled) return;
IWorld w = event.getWorld(); IWorld w = event.getWorld();
@ -1652,153 +1683,138 @@ public class DynmapPlugin
} }
} }
@SubscribeEvent @SubscribeEvent(priority=EventPriority.LOWEST)
public void handleChunkLoad(ChunkEvent.Load event) { public void handleChunkLoad(ChunkEvent.Load event) {
if(!core_enabled) return;
if(!onchunkgenerate) return; if(!onchunkgenerate) return;
IWorld w = event.getWorld(); IWorld w = event.getWorld();
if(!(w instanceof ServerWorld)) return; if(!(w instanceof ServerWorld)) return;
IChunk c = event.getChunk(); IChunk c = event.getChunk();
if((c != null) /*TODO && (!c.isTerrainPopulated())*/) { // If new chunk? if ((c != null) && (c.getStatus() == ChunkStatus.FULL)) {
ForgeWorld fw = getWorld(w, false); ForgeWorld fw = getWorld(w, false);
if(fw == null) { if (fw != null) {
return; addKnownChunk(fw, c.getPos());
}
int ymax = 0;
ChunkSection[] sections = c.getSections();
for(int i = 0; i < sections.length; i++) {
if((sections[i] != null) && (sections[i].isEmpty() == false)) {
ymax = 16*(i+1);
}
}
ChunkPos cp = c.getPos();
int x = cp.x << 4;
int z = cp.z << 4;
if(ymax > 0) {
mapManager.touchVolume(fw.getName(), x, 0, z, x+15, ymax, z+16, "chunkgenerate");
} }
} }
} }
@SubscribeEvent(priority=EventPriority.LOWEST)
public void handleChunkUnload(ChunkEvent.Unload event) {
if(!onchunkgenerate) return;
/*TODO IWorld w = event.getWorld();
@SubscribeEvent
public void handleChunkPopulate(PopulateChunkEvent.Post event) {
if(!core_enabled) return;
if(!onchunkpopulate) return;
World w = event.getWorld();
if(!(w instanceof ServerWorld)) return; if(!(w instanceof ServerWorld)) return;
Chunk c = w.getChunkFromChunkCoords(event.getChunkX(), event.getChunkZ()); IChunk c = event.getChunk();
int ymin = 0, ymax = 0; if ((c != null) && (c.getStatus() == ChunkStatus.FULL)) {
if(c != null) { ForgeWorld fw = getWorld(w, false);
ForgeWorld fw = getWorld(event.getWorld(), false); ChunkPos cp = c.getPos();
if (fw == null) return; if (fw != null) {
if (!checkIfKnownChunk(fw, cp)) {
int ymax = 0;
ChunkSection[] sections = c.getSections();
for(int i = 0; i < sections.length; i++) {
if((sections[i] != null) && (sections[i].isEmpty() == false)) {
ymax = 16*(i+1);
}
}
int x = cp.x << 4;
int z = cp.z << 4;
// If not empty AND not initial scan
if (ymax > 0) {
Log.info("New generated chunk detected at " + cp + " for " + fw.getName());
mapManager.touchVolume(fw.getName(), x, 0, z, x+15, ymax, z+16, "chunkgenerate");
}
}
removeKnownChunk(fw, cp);
}
}
}
@SubscribeEvent(priority=EventPriority.LOWEST)
public void handleChunkDataSave(ChunkDataEvent.Save event) {
if(!onchunkgenerate) return;
ExtendedBlockStorage[] sections = c.getBlockStorageArray(); IWorld w = event.getWorld();
for(int i = 0; i < sections.length; i++) { if(!(w instanceof ServerWorld)) return;
if((sections[i] != null) && (sections[i].isEmpty() == false)) { IChunk c = event.getChunk();
ymax = 16*(i+1); if ((c != null) && (c.getStatus() == ChunkStatus.FULL)) {
ForgeWorld fw = getWorld(w, false);
ChunkPos cp = c.getPos();
if (fw != null) {
if (!checkIfKnownChunk(fw, cp)) {
int ymax = 0;
ChunkSection[] sections = c.getSections();
for(int i = 0; i < sections.length; i++) {
if((sections[i] != null) && (sections[i].isEmpty() == false)) {
ymax = 16*(i+1);
}
}
int x = cp.x << 4;
int z = cp.z << 4;
// If not empty AND not initial scan
if (ymax > 0) {
mapManager.touchVolume(fw.getName(), x, 0, z, x+15, ymax, z+16, "chunkgenerate");
}
addKnownChunk(fw, cp);
} }
} }
int x = c.x << 4;
int z = c.z << 4;
if(ymax > 0)
mapManager.touchVolume(fw.getName(), x, ymin, z, x+15, ymax, z+16, "chunkpopulate");
} }
} }
*/ @SubscribeEvent(priority=EventPriority.LOWEST)
public void handleBlockEvent(BlockEvent event) {
if(!core_enabled) return;
if(!onblockchange) return;
BlockUpdateRec r = new BlockUpdateRec();
r.w = event.getWorld();
ForgeWorld fw = getWorld(r.w, false);
r.wid = fw.getName();
BlockPos p = event.getPos();
r.x = p.getX();
r.y = p.getY();
r.z = p.getZ();
blockupdatequeue.add(r);
}
} }
private WorldTracker worldTracker = null;
private boolean onblockchange = false; private boolean onblockchange = false;
private boolean onlightingchange = false;
private boolean onchunkpopulate = false; private boolean onchunkpopulate = false;
private boolean onchunkgenerate = false; private boolean onchunkgenerate = false;
private boolean onblockchange_with_id = false; private boolean onblockchange_with_id = false;
// TODO: Not in 1.14.4 - need to find equivalent
// public class WorldUpdateTracker implements IWorldEventListener {
// String worldid;
// IWorld world;
// @Override
// public void notifyLightSet(BlockPos pos) {
// if(sscache != null)
// sscache.invalidateSnapshot(worldid, pos.getX(), pos.getY(), pos.getZ());
// if(onlightingchange) {
// mapManager.touch(worldid, pos.getX(), pos.getY(), pos.getZ(), "lightingchange");
// }
// }
// @Override
// public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2) {
// }
// @Override
// public void onEntityAdded(Entity entityIn) {
// }
// @Override
// public void onEntityRemoved(Entity entityIn) {
// }
// @Override
// public void sendBlockBreakProgress(int breakerId, BlockPos pos,
// int progress) {
// }
// @Override
// public void broadcastSound(int p_180440_1_, BlockPos p_180440_2_,
// int p_180440_3_) {
// }
// @Override
// public void playSoundToAllNearExcept(PlayerEntity player,
// SoundEvent soundIn, SoundCategory category, double x, double y,
// double z, float volume, float pitch) {
// }
// @Override
// public void playRecord(SoundEvent soundIn, BlockPos pos) {
// }
// @Override
// public void playEvent(PlayerEntity arg0, int arg1, BlockPos arg2, int arg3) {
// }
// @Override
// public void notifyBlockUpdate(IBlockReader worldIn, BlockPos pos, BlockState oldState, BlockState newState,
// int flags) {
// if(sscache != null)
// sscache.invalidateSnapshot(worldid, pos.getX(), pos.getY(), pos.getZ());
// if(onblockchange) {
// BlockUpdateRec r = new BlockUpdateRec();
// r.w = world;
// r.wid = worldid;
// r.x = pos.getX(); r.y = pos.getY(); r.z = pos.getZ();
// blockupdatequeue.add(r);
// }
// }
// @Override
// public void addParticle(IParticleData particleData, boolean alwaysRender, double x, double y, double z,
// double xSpeed, double ySpeed, double zSpeed) {
// // TODO Auto-generated method stub
//
// }
// @Override
// public void addParticle(IParticleData particleData, boolean ignoreRange, boolean minimizeLevel, double x,
// double y, double z, double xSpeed, double ySpeed, double zSpeed) {
// // TODO Auto-generated method stub
//
// }
// }
// private WorldTracker worldTracker = null;
// private HashMap<String, WorldUpdateTracker> updateTrackers = new HashMap<String, WorldUpdateTracker>();
private void registerEvents() private void registerEvents()
{ {
// if(worldTracker == null) {
// worldTracker = new WorldTracker();
// MinecraftForge.EVENT_BUS.register(worldTracker);
// }
// To trigger rendering. // To trigger rendering.
onblockchange = core.isTrigger("blockupdate"); onblockchange = core.isTrigger("blockupdate");
onlightingchange = core.isTrigger("lightingupdate");
onchunkpopulate = core.isTrigger("chunkpopulate"); onchunkpopulate = core.isTrigger("chunkpopulate");
onchunkgenerate = core.isTrigger("chunkgenerate"); onchunkgenerate = core.isTrigger("chunkgenerate");
onblockchange_with_id = core.isTrigger("blockupdate-with-id"); onblockchange_with_id = core.isTrigger("blockupdate-with-id");
if(onblockchange_with_id) if(onblockchange_with_id)
onblockchange = true; onblockchange = true;
if ((worldTracker == null) && (onblockchange || onchunkpopulate || onchunkgenerate)) {
worldTracker = new WorldTracker();
MinecraftForge.EVENT_BUS.register(worldTracker);
}
// Prime the known full chunks
if (onchunkgenerate && (server.getWorlds() != null)) {
for (ServerWorld world : server.getWorlds()) {
ForgeWorld fw = getWorld(world);
if (fw == null) continue;
Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks = world.getChunkProvider().chunkManager.field_219252_f.clone();
for (Entry<Long, ChunkHolder> k : chunks.long2ObjectEntrySet()) {
long key = k.getKey().longValue();
ChunkHolder ch = k.getValue();
IChunk c = null;
try {
c = ch.func_219302_f().getNow(null);
} catch (Exception x) { }
if (c == null) continue;
ChunkStatus cs = c.getStatus();
ChunkPos pos = ch.getPosition();
if (cs == ChunkStatus.FULL) { // Cooked?
// Add it as known
addKnownChunk(fw, pos);
}
}
}
}
} }
private ForgeWorld getWorldByName(String name) { private ForgeWorld getWorldByName(String name) {
@ -1821,12 +1837,6 @@ public class DynmapPlugin
last_fworld = fw; last_fworld = fw;
if(fw.isLoaded() == false) { if(fw.isLoaded() == false) {
fw.setWorldLoaded(w); fw.setWorldLoaded(w);
// Add tracker
// WorldUpdateTracker wit = new WorldUpdateTracker();
// wit.worldid = fw.getName();
// wit.world = w;
// updateTrackers.put(fw.getName(), wit);
// w.getWorld().addEventListener(wit);
} }
return fw; return fw;
} }
@ -1836,118 +1846,12 @@ public class DynmapPlugin
/* Add to list if not found */ /* Add to list if not found */
fw = new ForgeWorld(w); fw = new ForgeWorld(w);
worlds.put(fw.getName(), fw); worlds.put(fw.getName(), fw);
// Add tracker
// WorldUpdateTracker wit = new WorldUpdateTracker();
// wit.worldid = fw.getName();
// wit.world = w;
// updateTrackers.put(fw.getName(), wit);
// w.getWorld().addEventListener(wit);
} }
last_world = w; last_world = w;
last_fworld = fw; last_fworld = fw;
return fw; return fw;
} }
/*
private void removeWorld(ForgeWorld fw) {
WorldUpdateTracker wit = updateTrackers.remove(fw.getName());
if(wit != null) {
//fw.getWorld().removeWorldAccess(wit);
}
worlds.remove(fw.getName());
if(last_fworld == fw) {
last_world = null;
last_fworld = null;
}
}
*/
private void initMetrics() {
/*
try {
Mod m = DynmapMod.class.getAnnotation(Mod.class);
metrics = new ForgeMetrics(m.name(), m.version());
;
ForgeMetrics.Graph features = metrics.createGraph("Features Used");
features.addPlotter(new ForgeMetrics.Plotter("Internal Web Server") {
@Override
public int getValue() {
if (!core.configuration.getBoolean("disable-webserver", false))
return 1;
return 0;
}
});
features.addPlotter(new ForgeMetrics.Plotter("Login Security") {
@Override
public int getValue() {
if(core.configuration.getBoolean("login-enabled", false))
return 1;
return 0;
}
});
features.addPlotter(new ForgeMetrics.Plotter("Player Info Protected") {
@Override
public int getValue() {
if(core.player_info_protected)
return 1;
return 0;
}
});
ForgeMetrics.Graph maps = metrics.createGraph("Map Data");
maps.addPlotter(new ForgeMetrics.Plotter("Worlds") {
@Override
public int getValue() {
if(core.mapManager != null)
return core.mapManager.getWorlds().size();
return 0;
}
});
maps.addPlotter(new ForgeMetrics.Plotter("Maps") {
@Override
public int getValue() {
int cnt = 0;
if(core.mapManager != null) {
for(DynmapWorld w :core.mapManager.getWorlds()) {
cnt += w.maps.size();
}
}
return cnt;
}
});
maps.addPlotter(new ForgeMetrics.Plotter("HD Maps") {
@Override
public int getValue() {
int cnt = 0;
if(core.mapManager != null) {
for(DynmapWorld w :core.mapManager.getWorlds()) {
for(MapType mt : w.maps) {
if(mt instanceof HDMap) {
cnt++;
}
}
}
}
return cnt;
}
});
for (String mod : modsused) {
features.addPlotter(new ForgeMetrics.Plotter(mod + " Blocks") {
@Override
public int getValue() {
return 1;
}
});
}
metrics.start();
} catch (IOException e) {
// Failed to submit the stats :-(
}
*/
}
private void saveWorlds() { private void saveWorlds() {
File f = new File(core.getDataFolder(), "forgeworlds.yml"); File f = new File(core.getDataFolder(), "forgeworlds.yml");
ConfigurationNode cn = new ConfigurationNode(f); ConfigurationNode cn = new ConfigurationNode(f);
@ -1963,23 +1867,16 @@ public class DynmapPlugin
lst.add(vals); lst.add(vals);
} }
cn.put("worlds", lst); cn.put("worlds", lst);
cn.put("isMCPC", isMCPC);
cn.put("useSaveFolderAsName", useSaveFolder); cn.put("useSaveFolderAsName", useSaveFolder);
cn.put("maxWorldHeight", ForgeWorld.getMaxWorldHeight()); cn.put("maxWorldHeight", ForgeWorld.getMaxWorldHeight());
cn.save(); cn.save();
} }
private void loadWorlds() { private void loadWorlds() {
isMCPC = server.getServerModName().contains("mcpc");
File f = new File(core.getDataFolder(), "forgeworlds.yml"); File f = new File(core.getDataFolder(), "forgeworlds.yml");
if(f.canRead() == false) { if(f.canRead() == false) {
useSaveFolder = true; useSaveFolder = true;
if (isMCPC) { ForgeWorld.setSaveFolderMapping();
ForgeWorld.setMCPCMapping();
}
else {
ForgeWorld.setSaveFolderMapping();
}
return; return;
} }
ConfigurationNode cn = new ConfigurationNode(f); ConfigurationNode cn = new ConfigurationNode(f);
@ -1987,22 +1884,13 @@ public class DynmapPlugin
// If defined, use maxWorldHeight // If defined, use maxWorldHeight
ForgeWorld.setMaxWorldHeight(cn.getInteger("maxWorldHeight", 256)); ForgeWorld.setMaxWorldHeight(cn.getInteger("maxWorldHeight", 256));
// If existing, only switch to save folder if MCPC+
useSaveFolder = isMCPC;
// If setting defined, use it // If setting defined, use it
if (cn.containsKey("useSaveFolderAsName")) { if (cn.containsKey("useSaveFolderAsName")) {
useSaveFolder = cn.getBoolean("useSaveFolderAsName", useSaveFolder); useSaveFolder = cn.getBoolean("useSaveFolderAsName", useSaveFolder);
} }
if (isMCPC) { if (useSaveFolder) {
ForgeWorld.setMCPCMapping();
}
else if (useSaveFolder) {
ForgeWorld.setSaveFolderMapping(); ForgeWorld.setSaveFolderMapping();
} }
// If inconsistent between MCPC and non-MCPC
if (isMCPC != cn.getBoolean("isMCPC", false)) {
return;
}
List<Map<String,Object>> lst = cn.getMapList("worlds"); List<Map<String,Object>> lst = cn.getMapList("worlds");
if(lst == null) { if(lst == null) {
Log.warning("Discarding bad forgeworlds.yml"); Log.warning("Discarding bad forgeworlds.yml");

View File

@ -57,12 +57,9 @@ import org.dynmap.utils.VisibilityLimit;
public class ForgeMapChunkCache extends MapChunkCache public class ForgeMapChunkCache extends MapChunkCache
{ {
private static boolean init = false; private static boolean init = false;
private static Field unloadqueue = null;
private static Field updateEntityTick = null; private static Field updateEntityTick = null;
/* ChunkManager fields */ /* ChunkManager fields */
private static Field chunksToRemove = null; // Map private static Field chunksToRemove = null; // Map
//private static Field pendingAnvilChunksCoordinates = null; // Set
private static Method writechunktonbt = null; // writeChunkToNBT(Chunk c, World w, CompoundNBT nbt)
/* ChunjManager Pending fields */ /* ChunjManager Pending fields */
private static Field chunkCoord = null; private static Field chunkCoord = null;
@ -87,8 +84,8 @@ public class ForgeMapChunkCache extends MapChunkCache
private byte[][] sameneighborbiomecnt; private byte[][] sameneighborbiomecnt;
private BiomeMap[][] biomemap; private BiomeMap[][] biomemap;
private boolean[][] isSectionNotEmpty; /* Indexed by snapshot index, then by section index */ private boolean[][] isSectionNotEmpty; /* Indexed by snapshot index, then by section index */
private it.unimi.dsi.fastutil.longs.LongSet queue = null;
private static final BlockStep unstep[] = { BlockStep.X_MINUS, BlockStep.Y_MINUS, BlockStep.Z_MINUS, private static final BlockStep unstep[] = { BlockStep.X_MINUS, BlockStep.Y_MINUS, BlockStep.Z_MINUS,
BlockStep.X_PLUS, BlockStep.Y_PLUS, BlockStep.Z_PLUS BlockStep.X_PLUS, BlockStep.Y_PLUS, BlockStep.Z_PLUS
}; };
@ -885,15 +882,7 @@ public class ForgeMapChunkCache extends MapChunkCache
if (!init) if (!init)
{ {
Field[] f = ServerChunkProvider.class.getDeclaredFields(); Field[] f = ServerChunkProvider.class.getDeclaredFields();
for(int i = 0; i < f.length; i++) {
if((unloadqueue == null) && f[i].getType().isAssignableFrom(it.unimi.dsi.fastutil.longs.LongSet.class)) {
unloadqueue = f[i];
//Log.info("Found unloadqueue - " + f[i].getName());
unloadqueue.setAccessible(true);
}
}
f = ServerWorld.class.getDeclaredFields(); f = ServerWorld.class.getDeclaredFields();
for(int i = 0; i < f.length; i++) { for(int i = 0; i < f.length; i++) {
if((updateEntityTick == null) && f[i].getType().isAssignableFrom(int.class)) { if((updateEntityTick == null) && f[i].getType().isAssignableFrom(int.class)) {
@ -915,22 +904,6 @@ public class ForgeMapChunkCache extends MapChunkCache
// pendingAnvilChunksCoordinates = f[i]; // pendingAnvilChunksCoordinates = f[i];
// pendingAnvilChunksCoordinates.setAccessible(true); // pendingAnvilChunksCoordinates.setAccessible(true);
// } // }
}
// Get writeChunkToNBT method
Method[] ma = ChunkManager.class.getDeclaredMethods();
for (Method m : ma) {
Class<?>[] p = m.getParameterTypes();
if ((p.length == 3) && (p[0].equals(Chunk.class)) && (p[1].equals(World.class)) && (p[2].equals(CompoundNBT.class))) {
writechunktonbt = m;
Log.info("Found writechunktonbt- " + m.getName());
m.setAccessible(true);
break;
}
}
if ((unloadqueue == null) || (writechunktonbt == null))
{
Log.severe("ERROR: cannot find unload queue or chunk provider field - dynmap cannot load chunks");
} }
if (updateEntityTick == null) { if (updateEntityTick == null) {
Log.severe("ERROR: cannot find updateEntityTick - dynmap cannot drive entity cleanup when no players are active"); Log.severe("ERROR: cannot find updateEntityTick - dynmap cannot drive entity cleanup when no players are active");
@ -1016,20 +989,6 @@ public class ForgeMapChunkCache extends MapChunkCache
snaptile = new DynIntHashMap[snapcnt]; snaptile = new DynIntHashMap[snapcnt];
isSectionNotEmpty = new boolean[snapcnt][]; isSectionNotEmpty = new boolean[snapcnt][];
try
{
if ((unloadqueue != null) && (cps != null))
{
queue = (it.unimi.dsi.fastutil.longs.LongSet) unloadqueue.get(cps);
}
}
catch (IllegalArgumentException iax)
{
}
catch (IllegalAccessException e)
{
}
} }
private static boolean didError = false; private static boolean didError = false;
@ -1038,12 +997,8 @@ public class ForgeMapChunkCache extends MapChunkCache
try { try {
ChunkManager acl = cps.chunkManager; ChunkManager acl = cps.chunkManager;
CompoundNBT rslt = null;
ChunkPos coord = new ChunkPos(x, z); ChunkPos coord = new ChunkPos(x, z);
CompoundNBT rslt = acl.readChunk(coord);
if (rslt == null) {
rslt = acl.readChunk(coord);
}
if(rslt != null) { if(rslt != null) {
rslt = rslt.getCompound("Level"); rslt = rslt.getCompound("Level");
// Don't load uncooked chunks // Don't load uncooked chunks
@ -1187,17 +1142,6 @@ public class ForgeMapChunkCache extends MapChunkCache
return (ssr != null); return (ssr != null);
} }
private boolean isChunkUnloadPending(DynmapChunk chunk) {
boolean isunloadpending = false;
if (queue != null)
{
long coord = ChunkPos.asLong(chunk.x, chunk.z);
isunloadpending = queue.contains(coord);
}
return isunloadpending;
}
// Prep snapshot and add to cache // Prep snapshot and add to cache
private SnapshotRec prepChunkSnapshot(DynmapChunk chunk, CompoundNBT nbt) { private SnapshotRec prepChunkSnapshot(DynmapChunk chunk, CompoundNBT nbt) {
ChunkSnapshot ss = new ChunkSnapshot(nbt, dw.worldheight); ChunkSnapshot ss = new ChunkSnapshot(nbt, dw.worldheight);
@ -1268,11 +1212,12 @@ public class ForgeMapChunkCache extends MapChunkCache
cnt++; cnt++;
} }
// If chunk is loaded and not being unloaded, we're grabbing its NBT data // If chunk is loaded and not being unloaded, we're grabbing its NBT data
else if (cps.chunkExists(chunk.x, chunk.z) && (!isChunkUnloadPending(chunk))) { else if (cps.chunkExists(chunk.x, chunk.z)) {
ChunkSnapshot ss; ChunkSnapshot ss;
DynIntHashMap tileData; DynIntHashMap tileData;
if (vis) { // If visible if (vis) { // If visible
CompoundNBT nbt = ChunkSerializer.write((ServerWorld)w, cps.getChunk(chunk.x, chunk.z, false)); CompoundNBT nbt = ChunkSerializer.write((ServerWorld)w, cps.getChunk(chunk.x, chunk.z, false));
if (nbt != null) nbt = nbt.getCompound("Level");
SnapshotRec ssr = prepChunkSnapshot(chunk, nbt); SnapshotRec ssr = prepChunkSnapshot(chunk, nbt);
ss = ssr.ss; ss = ssr.ss;
tileData = ssr.tileData; tileData = ssr.tileData;

View File

@ -29,13 +29,9 @@ public class ForgeWorld extends DynmapWorld
private final boolean istheend; private final boolean istheend;
private final String env; private final String env;
private DynmapLocation spawnloc = new DynmapLocation(); private DynmapLocation spawnloc = new DynmapLocation();
private static boolean doMCPCMapping = false;
private static boolean doSaveFolderMapping = false; private static boolean doSaveFolderMapping = false;
private static int maxWorldHeight = 256; // Maximum allows world height private static int maxWorldHeight = 256; // Maximum allows world height
public static void setMCPCMapping() {
doMCPCMapping = true;
}
public static void setSaveFolderMapping() { public static void setSaveFolderMapping() {
doSaveFolderMapping = true; doSaveFolderMapping = true;
} }
@ -48,10 +44,7 @@ public class ForgeWorld extends DynmapWorld
public static String getWorldName(IWorld w) { public static String getWorldName(IWorld w) {
String n; String n;
if (doMCPCMapping) { // MCPC+ mapping if (doSaveFolderMapping) { // New vanilla Forge mapping
n = w.getWorldInfo().getWorldName();
}
else if (doSaveFolderMapping) { // New vanilla Forge mapping (consistent with MCPC+)
if (w.getDimension().getType() == DimensionType.OVERWORLD) { if (w.getDimension().getType() == DimensionType.OVERWORLD) {
n = w.getWorldInfo().getWorldName(); n = w.getWorldInfo().getWorldName();
} }
@ -81,9 +74,9 @@ public class ForgeWorld extends DynmapWorld
public ForgeWorld(IWorld w) public ForgeWorld(IWorld w)
{ {
this(getWorldName(w), w.getWorld().getHeight(), w.getSeaLevel(), w.getDimension() instanceof NetherDimension, this(getWorldName(w), w.getWorld().getHeight(), w.getSeaLevel(), w.getDimension().isNether(),
w.getDimension() instanceof EndDimension, w.getDimension() instanceof EndDimension,
w.getWorldInfo().getWorldName() + "/" + w.getDimension().getType().toString()); w.getWorldInfo().getWorldName() + "/" + w.getDimension().getType().getRegistryName().toString());
setWorldLoaded(w); setWorldLoaded(w);
} }
public ForgeWorld(String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle) public ForgeWorld(String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle)

View File

@ -0,0 +1,2 @@
public net.minecraft.world.server.ChunkManager field_219251_e # loaded chunk list
public net.minecraft.world.server.ChunkManager field_219252_f # loaded chunk list