Add Forge 1.21.10
This commit is contained in:
parent
4d2a1d738d
commit
1f385c6af8
11 changed files with 2981 additions and 0 deletions
|
|
@ -0,0 +1,6 @@
|
||||||
|
package org.dynmap.forge_1_21_10;
|
||||||
|
|
||||||
|
public class ClientProxy extends Proxy {
|
||||||
|
public ClientProxy() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,112 @@
|
||||||
|
package org.dynmap.forge_1_21_10;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.dynmap.DynmapCommonAPI;
|
||||||
|
import org.dynmap.DynmapCommonAPIListener;
|
||||||
|
import org.dynmap.Log;
|
||||||
|
import org.dynmap.forge_1_21_10.DynmapPlugin.OurLog;
|
||||||
|
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
|
import net.minecraftforge.event.server.ServerAboutToStartEvent;
|
||||||
|
import net.minecraftforge.event.server.ServerStartedEvent;
|
||||||
|
import net.minecraftforge.event.server.ServerStartingEvent;
|
||||||
|
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.bus.BusGroup;
|
||||||
|
import net.minecraftforge.eventbus.api.bus.EventBus;
|
||||||
|
import net.minecraftforge.eventbus.api.listener.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
import net.minecraftforge.fml.IExtensionPoint;
|
||||||
|
import net.minecraftforge.fml.ModList;
|
||||||
|
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||||
|
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||||
|
|
||||||
|
@Mod("dynmap")
|
||||||
|
public class DynmapMod
|
||||||
|
{
|
||||||
|
// The instance of your mod that Forge uses.
|
||||||
|
public static DynmapMod instance;
|
||||||
|
public static BusGroup modBusGroup;
|
||||||
|
|
||||||
|
// Says where the client and server 'proxy' code is loaded.
|
||||||
|
public static Proxy proxy = DistExecutor.runForDist(() -> ClientProxy::new, () -> Proxy::new);
|
||||||
|
|
||||||
|
public static DynmapPlugin plugin;
|
||||||
|
public static File jarfile;
|
||||||
|
public static String ver;
|
||||||
|
public static boolean useforcedchunks;
|
||||||
|
|
||||||
|
public class APICallback extends DynmapCommonAPIListener {
|
||||||
|
@Override
|
||||||
|
public void apiListenerAdded() {
|
||||||
|
if(plugin == null) {
|
||||||
|
plugin = proxy.startServer(server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void apiEnabled(DynmapCommonAPI api) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DynmapMod(FMLJavaModLoadingContext context) {
|
||||||
|
instance = this;
|
||||||
|
|
||||||
|
modBusGroup = context.getModBusGroup();
|
||||||
|
|
||||||
|
// Register the commonSetup method for modloading
|
||||||
|
FMLCommonSetupEvent.getBus(modBusGroup).addListener(this::setup);
|
||||||
|
|
||||||
|
ServerStartedEvent.BUS.addListener(this::onServerStarted);
|
||||||
|
ServerAboutToStartEvent.BUS.addListener(this::onServerStarting);
|
||||||
|
ServerStoppingEvent.BUS.addListener(this::onServerStopping);
|
||||||
|
|
||||||
|
context.registerExtensionPoint(IExtensionPoint.DisplayTest.class,
|
||||||
|
()->new IExtensionPoint.DisplayTest(()->IExtensionPoint.DisplayTest.IGNORESERVERONLY, (remote, isServer)-> true));
|
||||||
|
|
||||||
|
Log.setLogger(new OurLog());
|
||||||
|
org.dynmap.modsupport.ModSupportImpl.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setup(final FMLCommonSetupEvent event)
|
||||||
|
{
|
||||||
|
//TOOO
|
||||||
|
jarfile = ModList.get().getModFileById("dynmap").getFile().getFilePath().toFile();
|
||||||
|
|
||||||
|
ver = ModList.get().getModContainerById("dynmap").get().getModInfo().getVersion().toString();
|
||||||
|
|
||||||
|
//// Load configuration file - use suggested (config/WesterosBlocks.cfg)
|
||||||
|
//Configuration cfg = new Configuration(event.getSuggestedConfigurationFile());
|
||||||
|
//try {
|
||||||
|
// cfg.load();
|
||||||
|
//
|
||||||
|
// useforcedchunks = cfg.get("Settings", "UseForcedChunks", true).getBoolean(true);
|
||||||
|
//}
|
||||||
|
//finally
|
||||||
|
//{
|
||||||
|
// cfg.save();
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MinecraftServer server;
|
||||||
|
|
||||||
|
public void onServerStarting(ServerAboutToStartEvent event) {
|
||||||
|
server = event.getServer();
|
||||||
|
if(plugin == null)
|
||||||
|
plugin = proxy.startServer(server);
|
||||||
|
plugin.onStarting(server.getCommands().getDispatcher());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onServerStarted(ServerStartedEvent event) {
|
||||||
|
DynmapCommonAPIListener.register(new APICallback());
|
||||||
|
plugin.serverStarted();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onServerStopping(ServerStoppingEvent event)
|
||||||
|
{
|
||||||
|
proxy.stopServer(plugin);
|
||||||
|
plugin = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,110 @@
|
||||||
|
package org.dynmap.forge_1_21_10;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.biome.Biome;
|
||||||
|
import net.minecraft.world.level.biome.BiomeSpecialEffects;
|
||||||
|
import org.dynmap.DynmapChunk;
|
||||||
|
import org.dynmap.Log;
|
||||||
|
import org.dynmap.common.BiomeMap;
|
||||||
|
import org.dynmap.common.chunk.GenericChunk;
|
||||||
|
import org.dynmap.common.chunk.GenericChunkCache;
|
||||||
|
import org.dynmap.common.chunk.GenericMapChunkCache;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.server.level.ServerChunkCache;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.ChunkPos;
|
||||||
|
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||||
|
import net.minecraft.world.level.chunk.storage.SerializableChunkData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container for managing chunks - dependent upon using chunk snapshots, since
|
||||||
|
* rendering is off server thread
|
||||||
|
*/
|
||||||
|
public class ForgeMapChunkCache extends GenericMapChunkCache {
|
||||||
|
private ServerLevel w;
|
||||||
|
private ServerChunkCache cps;
|
||||||
|
/**
|
||||||
|
* Construct empty cache
|
||||||
|
*/
|
||||||
|
public ForgeMapChunkCache(GenericChunkCache cc) {
|
||||||
|
super(cc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load generic chunk from existing and already loaded chunk
|
||||||
|
protected GenericChunk getLoadedChunk(DynmapChunk chunk) {
|
||||||
|
GenericChunk gc = null;
|
||||||
|
ChunkAccess ch = cps.getChunk(chunk.x, chunk.z, ChunkStatus.FULL, false);
|
||||||
|
if (ch != null) {
|
||||||
|
SerializableChunkData sc = SerializableChunkData.copyOf(w, cps.getChunk(chunk.x, chunk.z, false));
|
||||||
|
CompoundTag nbt = sc.write();
|
||||||
|
if (nbt != null) {
|
||||||
|
gc = parseChunkFromNBT(new NBT.NBTCompound(nbt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gc;
|
||||||
|
}
|
||||||
|
// Load generic chunk from unloaded chunk
|
||||||
|
protected GenericChunk loadChunk(DynmapChunk chunk) {
|
||||||
|
GenericChunk gc = null;
|
||||||
|
CompoundTag nbt = readChunk(chunk.x, chunk.z);
|
||||||
|
// If read was good
|
||||||
|
if (nbt != null) {
|
||||||
|
gc = parseChunkFromNBT(new NBT.NBTCompound(nbt));
|
||||||
|
}
|
||||||
|
return gc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChunks(ForgeWorld dw, List<DynmapChunk> chunks) {
|
||||||
|
this.w = dw.getWorld();
|
||||||
|
if (dw.isLoaded()) {
|
||||||
|
/* Check if world's provider is ServerChunkProvider */
|
||||||
|
cps = this.w.getChunkSource();
|
||||||
|
}
|
||||||
|
super.setChunks(dw, chunks);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompoundTag readChunk(int x, int z) {
|
||||||
|
try {
|
||||||
|
CompoundTag rslt = cps.chunkMap.read(new ChunkPos(x, z)).join().get();
|
||||||
|
if (rslt != null) {
|
||||||
|
CompoundTag lev = rslt;
|
||||||
|
if (lev.contains("Level")) {
|
||||||
|
lev = lev.getCompoundOrEmpty("Level");
|
||||||
|
}
|
||||||
|
// Don't load uncooked chunks
|
||||||
|
String stat = lev.getStringOr("Status", null);
|
||||||
|
ChunkStatus cs = ChunkStatus.byName(stat);
|
||||||
|
if ((stat == null) ||
|
||||||
|
// Needs to be at least lighted
|
||||||
|
(!cs.isOrAfter(ChunkStatus.LIGHT))) {
|
||||||
|
rslt = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Log.info(String.format("loadChunk(%d,%d)=%s", x, z, (rslt != null) ?
|
||||||
|
// rslt.toString() : "null"));
|
||||||
|
return rslt;
|
||||||
|
} catch (NoSuchElementException nsex) {
|
||||||
|
return null;
|
||||||
|
} catch (Exception exc) {
|
||||||
|
Log.severe(String.format("Error reading chunk: %s,%d,%d", dw.getName(), x, z), exc);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getFoliageColor(BiomeMap bm, int[] colormap, int x, int z) {
|
||||||
|
return bm.<Biome>getBiomeObject().map(Biome::getSpecialEffects).
|
||||||
|
flatMap(BiomeSpecialEffects::getFoliageColorOverride)
|
||||||
|
.orElse(colormap[bm.biomeLookup()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getGrassColor(BiomeMap bm, int[] colormap, int x, int z) {
|
||||||
|
BiomeSpecialEffects effects = bm.<Biome>getBiomeObject().map(Biome::getSpecialEffects).orElse(null);
|
||||||
|
if (effects == null) return colormap[bm.biomeLookup()];
|
||||||
|
return effects.getGrassColorModifier().modifyColor(x, z, effects.getGrassColorOverride().orElse(colormap[bm.biomeLookup()]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,249 @@
|
||||||
|
package org.dynmap.forge_1_21_10;
|
||||||
|
/**
|
||||||
|
* Forge specific implementation of DynmapWorld
|
||||||
|
*/
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.ServerLevelAccessor;
|
||||||
|
import net.minecraft.world.level.border.WorldBorder;
|
||||||
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.LightLayer;
|
||||||
|
|
||||||
|
import org.dynmap.DynmapChunk;
|
||||||
|
import org.dynmap.DynmapLocation;
|
||||||
|
import org.dynmap.DynmapWorld;
|
||||||
|
import org.dynmap.utils.MapChunkCache;
|
||||||
|
import org.dynmap.utils.Polygon;
|
||||||
|
|
||||||
|
public class ForgeWorld extends DynmapWorld
|
||||||
|
{
|
||||||
|
private ServerLevelAccessor world;
|
||||||
|
private final boolean skylight;
|
||||||
|
private final boolean isnether;
|
||||||
|
private final boolean istheend;
|
||||||
|
private final String env;
|
||||||
|
private DynmapLocation spawnloc = new DynmapLocation();
|
||||||
|
private static int maxWorldHeight = 320; // Maximum allows world height
|
||||||
|
|
||||||
|
public static int getMaxWorldHeight() {
|
||||||
|
return maxWorldHeight;
|
||||||
|
}
|
||||||
|
public static void setMaxWorldHeight(int h) {
|
||||||
|
maxWorldHeight = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getWorldName(ServerLevelAccessor w) {
|
||||||
|
ResourceKey<Level> rk = w.getLevel().dimension();
|
||||||
|
String id = rk.location().getNamespace() + "_" + rk.location().getPath();
|
||||||
|
if (id.equals("minecraft_overworld")) { // Overworld?
|
||||||
|
return w.getLevel().serverLevelData.getLevelName();
|
||||||
|
}
|
||||||
|
else if (id.equals("minecraft_the_end")) {
|
||||||
|
return "DIM1";
|
||||||
|
}
|
||||||
|
else if (id.equals("minecraft_the_nether")) {
|
||||||
|
return "DIM-1";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateWorld(ServerLevelAccessor w) {
|
||||||
|
this.updateWorldHeights(w.getLevel().getHeight(), w.getLevel().dimensionType().minY(), w.getLevel().getSeaLevel());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ForgeWorld(ServerLevelAccessor w)
|
||||||
|
{
|
||||||
|
this(getWorldName(w),
|
||||||
|
w.getLevel().getHeight(),
|
||||||
|
w.getLevel().getSeaLevel(),
|
||||||
|
w.getLevel().dimension() == Level.NETHER,
|
||||||
|
w.getLevel().dimension() == Level.END,
|
||||||
|
getWorldName(w),
|
||||||
|
w.getLevel().dimensionType().minY());
|
||||||
|
setWorldLoaded(w);
|
||||||
|
}
|
||||||
|
public ForgeWorld(String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle, int miny)
|
||||||
|
{
|
||||||
|
super(name, (height > maxWorldHeight)?maxWorldHeight:height, sealevel, miny);
|
||||||
|
world = null;
|
||||||
|
setTitle(deftitle);
|
||||||
|
isnether = nether;
|
||||||
|
istheend = the_end;
|
||||||
|
skylight = !(isnether || istheend);
|
||||||
|
|
||||||
|
if (isnether)
|
||||||
|
{
|
||||||
|
env = "nether";
|
||||||
|
}
|
||||||
|
else if (istheend)
|
||||||
|
{
|
||||||
|
env = "the_end";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
env = "normal";
|
||||||
|
}
|
||||||
|
//Log.info(getName() + ": skylight=" + skylight + ", height=" + this.worldheight + ", isnether=" + isnether + ", istheend=" + istheend);
|
||||||
|
}
|
||||||
|
/* Test if world is nether */
|
||||||
|
@Override
|
||||||
|
public boolean isNether()
|
||||||
|
{
|
||||||
|
return isnether;
|
||||||
|
}
|
||||||
|
public boolean isTheEnd()
|
||||||
|
{
|
||||||
|
return istheend;
|
||||||
|
}
|
||||||
|
/* Get world spawn location */
|
||||||
|
@Override
|
||||||
|
public DynmapLocation getSpawnLocation()
|
||||||
|
{
|
||||||
|
if(world != null) {
|
||||||
|
BlockPos p = world.getLevel().getRespawnData().pos();
|
||||||
|
spawnloc.x = p.getX();
|
||||||
|
spawnloc.y = p.getY();
|
||||||
|
spawnloc.z = p.getZ();
|
||||||
|
spawnloc.world = this.getName();
|
||||||
|
}
|
||||||
|
return spawnloc;
|
||||||
|
}
|
||||||
|
/* Get world time */
|
||||||
|
@Override
|
||||||
|
public long getTime()
|
||||||
|
{
|
||||||
|
if(world != null)
|
||||||
|
return world.getLevel().getDayTime();
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* World is storming */
|
||||||
|
@Override
|
||||||
|
public boolean hasStorm()
|
||||||
|
{
|
||||||
|
if(world != null)
|
||||||
|
return world.getLevel().isRaining();
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* World is thundering */
|
||||||
|
@Override
|
||||||
|
public boolean isThundering()
|
||||||
|
{
|
||||||
|
if(world != null)
|
||||||
|
return world.getLevel().isThundering();
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* World is loaded */
|
||||||
|
@Override
|
||||||
|
public boolean isLoaded()
|
||||||
|
{
|
||||||
|
return (world != null);
|
||||||
|
}
|
||||||
|
/* Set world to unloaded */
|
||||||
|
@Override
|
||||||
|
public void setWorldUnloaded()
|
||||||
|
{
|
||||||
|
getSpawnLocation();
|
||||||
|
world = null;
|
||||||
|
}
|
||||||
|
/* Set world to loaded */
|
||||||
|
public void setWorldLoaded(ServerLevelAccessor w) {
|
||||||
|
world = w;
|
||||||
|
this.sealevel = w.getLevel().getSeaLevel(); // Read actual current sealevel from world
|
||||||
|
// Update lighting table
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
// Algorithm based on LightmapTextureManager.getBrightness()
|
||||||
|
// We can't call that method because it's client-only.
|
||||||
|
// This means the code below can stop being correct if Mojang ever
|
||||||
|
// updates the curve; in that case we should reflect the changes.
|
||||||
|
float value = (float) i / 15.0f;
|
||||||
|
float brightness = value / (4.0f - 3.0f * value);
|
||||||
|
this.setBrightnessTableEntry(i, brightness);
|
||||||
|
//Log.info(getName() + ": light " + i + " = " + light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Get light level of block */
|
||||||
|
@Override
|
||||||
|
public int getLightLevel(int x, int y, int z)
|
||||||
|
{
|
||||||
|
if(world != null)
|
||||||
|
return world.getLevel().getLightEngine().getRawBrightness(new BlockPos(x, y, z), 0);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* Get highest Y coord of given location */
|
||||||
|
@Override
|
||||||
|
public int getHighestBlockYAt(int x, int z)
|
||||||
|
{
|
||||||
|
if(world != null) {
|
||||||
|
return world.getLevel().getChunk(x >> 4, z >> 4).getHeight(Heightmap.Types.MOTION_BLOCKING, x & 15, z & 15);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* Test if sky light level is requestable */
|
||||||
|
@Override
|
||||||
|
public boolean canGetSkyLightLevel()
|
||||||
|
{
|
||||||
|
return skylight;
|
||||||
|
}
|
||||||
|
/* Return sky light level */
|
||||||
|
@Override
|
||||||
|
public int getSkyLightLevel(int x, int y, int z)
|
||||||
|
{
|
||||||
|
if(world != null) {
|
||||||
|
return world.getLevel().getBrightness(LightLayer.SKY, new BlockPos(x, y, z));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get world environment ID (lower case - normal, the_end, nether)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getEnvironment()
|
||||||
|
{
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get map chunk cache for world
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public MapChunkCache getChunkCache(List<DynmapChunk> chunks)
|
||||||
|
{
|
||||||
|
if (world != null) {
|
||||||
|
ForgeMapChunkCache c = new ForgeMapChunkCache(DynmapPlugin.plugin.sscache);
|
||||||
|
c.setChunks(this, chunks);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerLevel getWorld()
|
||||||
|
{
|
||||||
|
return world.getLevel();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Polygon getWorldBorder() {
|
||||||
|
if (world != null) {
|
||||||
|
WorldBorder wb = world.getWorldBorder();
|
||||||
|
if ((wb != null) && (wb.getSize() < 5.9E7)) {
|
||||||
|
Polygon p = new Polygon();
|
||||||
|
p.addVertex(wb.getMinX(), wb.getMinZ());
|
||||||
|
p.addVertex(wb.getMinX(), wb.getMaxZ());
|
||||||
|
p.addVertex(wb.getMaxX(), wb.getMaxZ());
|
||||||
|
p.addVertex(wb.getMaxX(), wb.getMinZ());
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
138
forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/NBT.java
Normal file
138
forge-1.21.10/src/main/java/org/dynmap/forge_1_21_10/NBT.java
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
package org.dynmap.forge_1_21_10;
|
||||||
|
|
||||||
|
import org.dynmap.common.chunk.GenericBitStorage;
|
||||||
|
import org.dynmap.common.chunk.GenericNBTCompound;
|
||||||
|
import org.dynmap.common.chunk.GenericNBTList;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.nbt.ListTag;
|
||||||
|
import net.minecraft.nbt.Tag;
|
||||||
|
import net.minecraft.util.SimpleBitStorage;
|
||||||
|
|
||||||
|
public class NBT {
|
||||||
|
|
||||||
|
public static class NBTCompound implements GenericNBTCompound {
|
||||||
|
private final CompoundTag obj;
|
||||||
|
public NBTCompound(CompoundTag t) {
|
||||||
|
this.obj = t;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Set<String> getAllKeys() {
|
||||||
|
return obj.keySet();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean contains(String s) {
|
||||||
|
return obj.contains(s);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean contains(String s, int i) {
|
||||||
|
// Like contains, but with an extra constraint on type
|
||||||
|
Tag base = obj.get(s);
|
||||||
|
if (base == null)
|
||||||
|
return false;
|
||||||
|
byte type = base.getId();
|
||||||
|
if (type == (byte) i)
|
||||||
|
return true;
|
||||||
|
else if (i != TAG_ANY_NUMERIC)
|
||||||
|
return false;
|
||||||
|
return type == TAG_BYTE || type == TAG_SHORT || type == TAG_INT || type == TAG_LONG || type == TAG_FLOAT
|
||||||
|
|| type == TAG_DOUBLE;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public byte getByte(String s) {
|
||||||
|
return obj.getByteOr(s, (byte)0);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public short getShort(String s) {
|
||||||
|
return obj.getShortOr(s, (short)0);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getInt(String s) {
|
||||||
|
return obj.getIntOr(s, (int)0);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public long getLong(String s) {
|
||||||
|
return obj.getLongOr(s, (long)0);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public float getFloat(String s) {
|
||||||
|
return obj.getFloatOr(s, (float)0);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public double getDouble(String s) {
|
||||||
|
return obj.getDoubleOr(s, (double)0);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getString(String s) {
|
||||||
|
return obj.getStringOr(s, "");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public byte[] getByteArray(String s) {
|
||||||
|
return obj.getByteArray(s).orElseGet(() -> new byte[0]);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int[] getIntArray(String s) {
|
||||||
|
return obj.getIntArray(s).orElseGet(() -> new int[0]);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public long[] getLongArray(String s) {
|
||||||
|
return obj.getLongArray(s).orElseGet(() -> new long[0]);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public GenericNBTCompound getCompound(String s) {
|
||||||
|
return new NBTCompound(obj.getCompoundOrEmpty(s));
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public GenericNBTList getList(String s, int i) {
|
||||||
|
// i argument used to be used to constrain list type, but nbt lists no longer have types as of 1.21.5
|
||||||
|
return new NBTList(obj.getListOrEmpty(s));
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean getBoolean(String s) {
|
||||||
|
return obj.getBooleanOr(s, false);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getAsString(String s) {
|
||||||
|
return obj.get(s).asString().orElse("");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public GenericBitStorage makeBitStorage(int bits, int count, long[] data) {
|
||||||
|
return new OurBitStorage(bits, count, data);
|
||||||
|
}
|
||||||
|
public String toString() {
|
||||||
|
return obj.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static class NBTList implements GenericNBTList {
|
||||||
|
private final ListTag obj;
|
||||||
|
public NBTList(ListTag t) {
|
||||||
|
obj = t;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return obj.size();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public String getString(int idx) {
|
||||||
|
return obj.getStringOr(idx, "");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public GenericNBTCompound getCompound(int idx) {
|
||||||
|
return new NBTCompound(obj.getCompoundOrEmpty(idx));
|
||||||
|
}
|
||||||
|
public String toString() {
|
||||||
|
return obj.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static class OurBitStorage implements GenericBitStorage {
|
||||||
|
private final SimpleBitStorage bs;
|
||||||
|
public OurBitStorage(int bits, int count, long[] data) {
|
||||||
|
bs = new SimpleBitStorage(bits, count, data);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int get(int idx) {
|
||||||
|
return bs.get(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package org.dynmap.forge_1_21_10;
|
||||||
|
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server side proxy - methods for creating and cleaning up plugin
|
||||||
|
*/
|
||||||
|
public class Proxy
|
||||||
|
{
|
||||||
|
public Proxy()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public DynmapPlugin startServer(MinecraftServer srv) {
|
||||||
|
DynmapPlugin plugin = DynmapPlugin.plugin;
|
||||||
|
if (plugin == null) {
|
||||||
|
plugin = new DynmapPlugin(srv);
|
||||||
|
plugin.onEnable();
|
||||||
|
}
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
public void stopServer(DynmapPlugin plugin) {
|
||||||
|
plugin.onDisable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
package org.dynmap.forge_1_21_10;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.dynmap.DynmapCore;
|
||||||
|
import org.dynmap.Log;
|
||||||
|
|
||||||
|
public class VersionCheck {
|
||||||
|
private static final String VERSION_URL = "http://mikeprimm.com/dynmap/releases.php";
|
||||||
|
public static void runCheck(final DynmapCore core) {
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
doCheck(core);
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getReleaseVersion(String s) {
|
||||||
|
int index = s.lastIndexOf('-');
|
||||||
|
if(index < 0)
|
||||||
|
index = s.lastIndexOf('.');
|
||||||
|
if(index >= 0)
|
||||||
|
s = s.substring(0, index);
|
||||||
|
String[] split = s.split("\\.");
|
||||||
|
int v = 0;
|
||||||
|
try {
|
||||||
|
for(int i = 0; (i < split.length) && (i < 3); i++) {
|
||||||
|
v += Integer.parseInt(split[i]) << (8 * (2 - i));
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException nfx) {}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getBuildNumber(String s) {
|
||||||
|
int index = s.lastIndexOf('-');
|
||||||
|
if(index < 0)
|
||||||
|
index = s.lastIndexOf('.');
|
||||||
|
if(index >= 0)
|
||||||
|
s = s.substring(index+1);
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(s);
|
||||||
|
} catch (NumberFormatException nfx) {
|
||||||
|
return 99999999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void doCheck(DynmapCore core) {
|
||||||
|
String pluginver = core.getDynmapPluginVersion();
|
||||||
|
String platform = core.getDynmapPluginPlatform();
|
||||||
|
String platver = core.getDynmapPluginPlatformVersion();
|
||||||
|
if((pluginver == null) || (platform == null) || (platver == null))
|
||||||
|
return;
|
||||||
|
HttpURLConnection conn = null;
|
||||||
|
String loc = VERSION_URL;
|
||||||
|
int cur_ver = getReleaseVersion(pluginver);
|
||||||
|
int cur_bn = getBuildNumber(pluginver);
|
||||||
|
try {
|
||||||
|
while((loc != null) && (!loc.isEmpty())) {
|
||||||
|
URL url = new URL(loc);
|
||||||
|
conn = (HttpURLConnection) url.openConnection();
|
||||||
|
conn.setRequestProperty("User-Agent", "Dynmap (" + platform + "/" + platver + "/" + pluginver);
|
||||||
|
conn.connect();
|
||||||
|
loc = conn.getHeaderField("Location");
|
||||||
|
}
|
||||||
|
BufferedReader rdr = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||||
|
String line = null;
|
||||||
|
while((line = rdr.readLine()) != null) {
|
||||||
|
String[] split = line.split(":");
|
||||||
|
if(split.length < 4) continue;
|
||||||
|
/* If our platform and version, or wildcard platform version */
|
||||||
|
if(split[0].equals(platform) && (split[1].equals("*") || split[1].equals(platver))) {
|
||||||
|
int recommended_ver = getReleaseVersion(split[2]);
|
||||||
|
int recommended_bn = getBuildNumber(split[2]);
|
||||||
|
if((recommended_ver > cur_ver) || ((recommended_ver == cur_ver) && (recommended_bn > cur_bn))) { /* Newer recommended build */
|
||||||
|
Log.info("Version obsolete: new recommended version " + split[2] + " is available.");
|
||||||
|
}
|
||||||
|
else if(cur_ver > recommended_ver) { /* Running dev or prerelease? */
|
||||||
|
int prerel_ver = getReleaseVersion(split[3]);
|
||||||
|
int prerel_bn = getBuildNumber(split[3]);
|
||||||
|
if((prerel_ver > cur_ver) || ((prerel_ver == cur_ver) && (prerel_bn > cur_bn))) {
|
||||||
|
Log.info("Version obsolete: new prerelease version " + split[3] + " is available.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception x) {
|
||||||
|
Log.info("Error checking for latest version");
|
||||||
|
} finally {
|
||||||
|
if(conn != null) {
|
||||||
|
conn.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
package org.dynmap.forge_1_21_10.permissions;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.dynmap.ConfigurationNode;
|
||||||
|
import org.dynmap.Log;
|
||||||
|
import org.dynmap.forge_1_21_10.DynmapPlugin;
|
||||||
|
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
|
||||||
|
public class FilePermissions implements PermissionProvider {
|
||||||
|
private HashMap<String, Set<String>> perms;
|
||||||
|
private Set<String> defperms;
|
||||||
|
|
||||||
|
public static FilePermissions create() {
|
||||||
|
File f = new File("dynmap/permissions.yml");
|
||||||
|
if(!f.exists())
|
||||||
|
return null;
|
||||||
|
ConfigurationNode cfg = new ConfigurationNode(f);
|
||||||
|
cfg.load();
|
||||||
|
|
||||||
|
Log.info("Using permissions.yml for access control");
|
||||||
|
|
||||||
|
return new FilePermissions(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FilePermissions(ConfigurationNode cfg) {
|
||||||
|
perms = new HashMap<String,Set<String>>();
|
||||||
|
for(String k : cfg.keySet()) {
|
||||||
|
List<String> p = cfg.getStrings(k, null);
|
||||||
|
if(p != null) {
|
||||||
|
k = k.toLowerCase();
|
||||||
|
HashSet<String> pset = new HashSet<String>();
|
||||||
|
for(String perm : p) {
|
||||||
|
pset.add(perm.toLowerCase());
|
||||||
|
}
|
||||||
|
perms.put(k, pset);
|
||||||
|
if(k.equals("defaultuser")) {
|
||||||
|
defperms = pset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasPerm(String player, String perm) {
|
||||||
|
Set<String> ps = perms.get(player);
|
||||||
|
if((ps != null) && (ps.contains(perm))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(defperms.contains(perm)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public Set<String> hasOfflinePermissions(String player, Set<String> perms) {
|
||||||
|
player = player.toLowerCase();
|
||||||
|
HashSet<String> rslt = new HashSet<String>();
|
||||||
|
if(DynmapPlugin.plugin.isOp(player)) {
|
||||||
|
rslt.addAll(perms);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for(String p : perms) {
|
||||||
|
if(hasPerm(player, p)) {
|
||||||
|
rslt.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rslt;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean hasOfflinePermission(String player, String perm) {
|
||||||
|
player = player.toLowerCase();
|
||||||
|
if(DynmapPlugin.plugin.isOp(player)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return hasPerm(player, perm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean has(ServerPlayer psender, String permission) {
|
||||||
|
if(psender != null) {
|
||||||
|
String n = psender.getName().getString().toLowerCase();
|
||||||
|
return hasPerm(n, permission);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean hasPermissionNode(ServerPlayer psender, String permission) {
|
||||||
|
if(psender != null) {
|
||||||
|
String player = psender.getName().getString().toLowerCase();
|
||||||
|
return DynmapPlugin.plugin.isOp(player);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package org.dynmap.forge_1_21_10.permissions;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.dynmap.Log;
|
||||||
|
import org.dynmap.forge_1_21_10.DynmapPlugin;
|
||||||
|
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
|
||||||
|
public class OpPermissions implements PermissionProvider {
|
||||||
|
public HashSet<String> usrCommands = new HashSet<String>();
|
||||||
|
|
||||||
|
public OpPermissions(String[] usrCommands) {
|
||||||
|
for (String usrCommand : usrCommands) {
|
||||||
|
this.usrCommands.add(usrCommand);
|
||||||
|
}
|
||||||
|
Log.info("Using ops.txt for access control");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> hasOfflinePermissions(String player, Set<String> perms) {
|
||||||
|
HashSet<String> rslt = new HashSet<String>();
|
||||||
|
if(DynmapPlugin.plugin.isOp(player)) {
|
||||||
|
rslt.addAll(perms);
|
||||||
|
}
|
||||||
|
return rslt;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean hasOfflinePermission(String player, String perm) {
|
||||||
|
return DynmapPlugin.plugin.isOp(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean has(ServerPlayer psender, String permission) {
|
||||||
|
if(psender != null) {
|
||||||
|
if(usrCommands.contains(permission)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return DynmapPlugin.plugin.isOp(psender.getName().getString());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean hasPermissionNode(ServerPlayer psender, String permission) {
|
||||||
|
if(psender != null) {
|
||||||
|
return DynmapPlugin.plugin.isOp(psender.getName().getString());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package org.dynmap.forge_1_21_10.permissions;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
|
||||||
|
public interface PermissionProvider {
|
||||||
|
boolean has(ServerPlayer sender, String permission);
|
||||||
|
boolean hasPermissionNode(ServerPlayer sender, String permission);
|
||||||
|
|
||||||
|
Set<String> hasOfflinePermissions(String player, Set<String> perms);
|
||||||
|
|
||||||
|
boolean hasOfflinePermission(String player, String perm);
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue