/forge-1.13.2/src/main/java/org/dynmap/forge_1_13_2/DynmapPlugin.java
Java | 2133 lines | 1653 code | 164 blank | 316 comment | 293 complexity | 2b0108a84a709acdbb624dfbe628957a MD5 | raw file
Possible License(s): Apache-2.0
Large files files are truncated, but you can click here to view the full file
- package org.dynmap.forge_1_13_2;
- import java.io.File;
- import java.io.InputStream;
- import java.lang.reflect.Field;
- import java.net.InetSocketAddress;
- import java.net.SocketAddress;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import java.util.Map.Entry;
- import java.util.Optional;
- import java.util.PriorityQueue;
- import java.util.Set;
- import java.util.UUID;
- import java.util.concurrent.Callable;
- import java.util.concurrent.CancellationException;
- import java.util.concurrent.ConcurrentLinkedQueue;
- import java.util.concurrent.ExecutionException;
- import java.util.concurrent.Future;
- import java.util.concurrent.FutureTask;
- import java.util.regex.Pattern;
- import net.minecraft.block.Block;
- import net.minecraft.block.BlockFlowingFluid;
- import net.minecraft.block.material.Material;
- import net.minecraft.block.state.IBlockState;
- import net.minecraft.command.CommandException;
- import net.minecraft.command.CommandSource;
- import net.minecraft.command.Commands;
- import net.minecraft.entity.Entity;
- import net.minecraft.entity.player.EntityPlayer;
- import net.minecraft.entity.player.EntityPlayerMP;
- import net.minecraft.fluid.IFluidState;
- import net.minecraft.init.Blocks;
- import net.minecraft.item.Item;
- import net.minecraft.network.NetHandlerPlayServer;
- import net.minecraft.network.NetworkManager;
- import net.minecraft.network.play.server.SPacketTitle;
- import net.minecraft.particles.IParticleData;
- import net.minecraft.server.MinecraftServer;
- import net.minecraft.server.management.UserListBans;
- import net.minecraft.server.management.UserListIPBans;
- import net.minecraft.server.management.UserListOps;
- import net.minecraft.server.management.PlayerProfileCache;
- import net.minecraft.util.ObjectIntIdentityMap;
- import net.minecraft.util.ResourceLocation;
- import net.minecraft.util.SoundCategory;
- import net.minecraft.util.SoundEvent;
- import net.minecraft.util.math.BlockPos;
- import net.minecraft.util.math.ChunkPos;
- import net.minecraft.util.registry.IRegistry;
- import net.minecraft.util.registry.RegistryNamespaced;
- import net.minecraft.util.text.ITextComponent;
- import net.minecraft.util.text.TextComponentString;
- import net.minecraft.world.IBlockReader;
- import net.minecraft.world.IWorld;
- import net.minecraft.world.IWorldEventListener;
- import net.minecraft.world.World;
- import net.minecraft.world.WorldServer;
- import net.minecraft.world.biome.Biome;
- import net.minecraft.world.chunk.Chunk;
- import net.minecraft.world.chunk.ChunkSection;
- import net.minecraft.world.chunk.IChunk;
- import net.minecraftforge.common.MinecraftForge;
- import net.minecraftforge.event.ServerChatEvent;
- import net.minecraftforge.event.world.ChunkEvent;
- import net.minecraftforge.event.world.WorldEvent;
- import net.minecraftforge.fml.ModList;
- import net.minecraftforge.fml.ModContainer;
- import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerChangedDimensionEvent;
- import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent;
- import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedOutEvent;
- import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerRespawnEvent;
- import net.minecraftforge.registries.ForgeRegistries;
- import net.minecraftforge.registries.ForgeRegistry;
- import net.minecraftforge.registries.RegistryManager;
- import net.minecraftforge.fml.common.gameevent.TickEvent;
- import net.minecraftforge.fml.common.registry.GameRegistry;
- import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo;
- import net.minecraftforge.fml.loading.moddiscovery.ModInfo;
- import net.minecraftforge.forgespi.language.IModInfo;
- import org.apache.commons.codec.Charsets;
- import org.apache.commons.codec.binary.Base64;
- import org.apache.logging.log4j.LogManager;
- import org.apache.logging.log4j.Logger;
- import org.apache.maven.artifact.versioning.ArtifactVersion;
- import org.dynmap.ConfigurationNode;
- import org.dynmap.DynmapChunk;
- import org.dynmap.DynmapCommonAPIListener;
- import org.dynmap.DynmapCore;
- import org.dynmap.DynmapLocation;
- import org.dynmap.DynmapWorld;
- import org.dynmap.Log;
- import org.dynmap.MapManager;
- import org.dynmap.PlayerList;
- import org.dynmap.common.BiomeMap;
- import org.dynmap.common.DynmapCommandSender;
- import org.dynmap.common.DynmapPlayer;
- import org.dynmap.common.DynmapServerInterface;
- import org.dynmap.common.DynmapListenerManager.EventType;
- import org.dynmap.debug.Debug;
- import org.dynmap.forge_1_13_2.DmapCommand;
- import org.dynmap.forge_1_13_2.DmarkerCommand;
- import org.dynmap.forge_1_13_2.DynmapCommand;
- import org.dynmap.forge_1_13_2.DynmapMod;
- import org.dynmap.forge_1_13_2.permissions.FilePermissions;
- import org.dynmap.forge_1_13_2.permissions.OpPermissions;
- import org.dynmap.forge_1_13_2.permissions.PermissionProvider;
- import org.dynmap.permissions.PermissionsHandler;
- import org.dynmap.renderer.DynmapBlockState;
- import org.dynmap.utils.DynIntHashMap;
- import org.dynmap.utils.DynmapLogger;
- import org.dynmap.utils.MapChunkCache;
- import org.dynmap.utils.VisibilityLimit;
- import com.google.common.collect.Iterables;
- import com.google.gson.Gson;
- import com.google.gson.GsonBuilder;
- import com.google.gson.JsonParseException;
- import com.mojang.authlib.GameProfile;
- import com.mojang.authlib.properties.Property;
- import com.mojang.brigadier.CommandDispatcher;
- import com.mojang.brigadier.arguments.StringArgumentType;
- import com.mojang.brigadier.builder.LiteralArgumentBuilder;
- import com.mojang.brigadier.builder.RequiredArgumentBuilder;
- import com.mojang.brigadier.exceptions.CommandSyntaxException;
- import net.minecraft.state.IProperty;
- import net.minecraftforge.eventbus.api.SubscribeEvent;
- public class DynmapPlugin
- {
- private DynmapCore core;
- private PermissionProvider permissions;
- private boolean core_enabled;
- public SnapshotCache sscache;
- public PlayerList playerList;
- private MapManager mapManager;
- private net.minecraft.server.MinecraftServer server;
- public static DynmapPlugin plugin;
- private ChatHandler chathandler;
- private HashMap<String, Integer> sortWeights = new HashMap<String, Integer>();
- // Drop world load ticket after 30 seconds
- private long worldIdleTimeoutNS = 30 * 1000000000L;
- private HashMap<String, ForgeWorld> worlds = new HashMap<String, ForgeWorld>();
- private IWorld last_world;
- private ForgeWorld last_fworld;
- private Map<String, ForgePlayer> players = new HashMap<String, ForgePlayer>();
- //TODO private ForgeMetrics metrics;
- private HashSet<String> modsused = new HashSet<String>();
- private ForgeServer fserver = new ForgeServer();
- private boolean tickregistered = false;
- // TPS calculator
- private double tps;
- private long lasttick;
- private long avgticklen;
- // Per tick limit, in nsec
- private long perTickLimit = (50000000); // 50 ms
- private boolean isMCPC = false;
- private boolean useSaveFolder = true;
-
- private static final int SIGNPOST_ID = 63;
- private static final int WALLSIGN_ID = 68;
- private static final String[] TRIGGER_DEFAULTS = { "blockupdate", "chunkpopulate", "chunkgenerate" };
- private static final Pattern patternControlCode = Pattern.compile("(?i)\\u00A7[0-9A-FK-OR]");
- public static class BlockUpdateRec {
- IWorld w;
- String wid;
- int x, y, z;
- }
- ConcurrentLinkedQueue<BlockUpdateRec> blockupdatequeue = new ConcurrentLinkedQueue<BlockUpdateRec>();
- public static DynmapBlockState[] stateByID;
-
- /**
- * Initialize block states (org.dynmap.blockstate.DynmapBlockState)
- */
- public void initializeBlockStates() {
- stateByID = new DynmapBlockState[512*32]; // Simple map - scale as needed
- Arrays.fill(stateByID, DynmapBlockState.AIR); // Default to air
- ObjectIntIdentityMap<IBlockState> bsids = Block.BLOCK_STATE_IDS;
- DynmapBlockState basebs = null;
- Block baseb = null;
- int baseidx = 0;
-
- Iterator<IBlockState> iter = bsids.iterator();
- while (iter.hasNext()) {
- IBlockState bs = iter.next();
- int idx = bsids.get(bs);
- if (idx >= stateByID.length) {
- int plen = stateByID.length;
- stateByID = Arrays.copyOf(stateByID, idx*11/10); // grow array by 10%
- Arrays.fill(stateByID, plen, stateByID.length, DynmapBlockState.AIR);
- }
- Block b = bs.getBlock();
- // If this is new block vs last, it's the base block state
- if (b != baseb) {
- basebs = null;
- baseidx = idx;
- baseb = b;
- }
-
- ResourceLocation ui = b.getRegistryName();
- if (ui == null) {
- continue;
- }
- String bn = ui.getNamespace() + ":" + ui.getPath();
- // Only do defined names, and not "air"
- if (!bn.equals(DynmapBlockState.AIR_BLOCK)) {
- Material mat = bs.getMaterial();
- String statename = "";
- for(IProperty p : bs.getProperties()) {
- if (statename.length() > 0) {
- statename += ",";
- }
- statename += p.getName() + "=" + bs.get(p).toString();
- }
- //Log.info("bn=" + bn + ", statenme=" + statename + ",idx=" + idx + ",baseidx=" + baseidx);
- DynmapBlockState dbs = new DynmapBlockState(basebs, idx - baseidx, bn, statename, mat.toString(), idx);
- stateByID[idx] = dbs;
- if (basebs == null) { basebs = dbs; }
- if (mat.isSolid()) {
- dbs.setSolid();
- }
- if (mat == Material.AIR) {
- dbs.setAir();
- }
- if (mat == Material.WOOD) {
- dbs.setLog();
- }
- if (mat == Material.LEAVES) {
- dbs.setLeaves();
- }
- if ((!bs.getFluidState().isEmpty()) && !(bs.getBlock() instanceof BlockFlowingFluid)) {
- dbs.setWaterlogged();
- }
- }
- }
- for (int gidx = 0; gidx < DynmapBlockState.getGlobalIndexMax(); gidx++) {
- DynmapBlockState bs = DynmapBlockState.getStateByGlobalIndex(gidx);
- //Log.info(gidx + ":" + bs.toString() + ", gidx=" + bs.globalStateIndex + ", sidx=" + bs.stateIndex);
- }
- }
- public static final Item getItemByID(int id) {
- return Item.getItemById(id);
- }
-
- public static final String getBlockUnlocalizedName(Block b) {
- return b.getNameTextComponent().getString();
- }
-
- private static Biome[] biomelist = null;
-
- public static final Biome[] getBiomeList() {
- if (biomelist == null) {
- biomelist = new Biome[256];
- Iterator<Biome> iter = ForgeRegistries.BIOMES.iterator();
- while (iter.hasNext()) {
- Biome b = iter.next();
- int bidx = RegistryNamespaced.BIOME.getId(b);
- if (bidx >= biomelist.length) {
- biomelist = Arrays.copyOf(biomelist, bidx + biomelist.length);
- }
- biomelist[bidx] = b;
- }
- }
- return biomelist;
- }
- public static final NetworkManager getNetworkManager(NetHandlerPlayServer nh) {
- return nh.netManager;
- }
-
- private ForgePlayer getOrAddPlayer(EntityPlayer p) {
- String name = p.getEntity().getName().getString();
- ForgePlayer fp = players.get(name);
- if(fp != null) {
- fp.player = p;
- }
- else {
- fp = new ForgePlayer(p);
- players.put(name, fp);
- }
- return fp;
- }
-
- private static class TaskRecord implements Comparable<Object>
- {
- private long ticktorun;
- private long id;
- private FutureTask<?> future;
- @Override
- public int compareTo(Object o)
- {
- TaskRecord tr = (TaskRecord)o;
- if (this.ticktorun < tr.ticktorun)
- {
- return -1;
- }
- else if (this.ticktorun > tr.ticktorun)
- {
- return 1;
- }
- else if (this.id < tr.id)
- {
- return -1;
- }
- else if (this.id > tr.id)
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- }
- private class ChatMessage {
- String message;
- EntityPlayer sender;
- }
- private ConcurrentLinkedQueue<ChatMessage> msgqueue = new ConcurrentLinkedQueue<ChatMessage>();
-
- public class ChatHandler {
- @SubscribeEvent
- public void handleChat(ServerChatEvent event) {
- String msg = event.getMessage();
- if(!msg.startsWith("/")) {
- ChatMessage cm = new ChatMessage();
- cm.message = msg;
- cm.sender = event.getPlayer();
- msgqueue.add(cm);
- }
- }
- }
- /** TODO: depends on forge chunk manager
- private static class WorldBusyRecord {
- long last_ts;
- Ticket ticket;
- }
- private static HashMap<Integer, WorldBusyRecord> busy_worlds = new HashMap<Integer, WorldBusyRecord>();
-
- private void setBusy(World w) {
- setBusy(w, null);
- }
- static void setBusy(World w, Ticket t) {
- if(w == null) return;
- if (!DynmapMod.useforcedchunks) return;
- WorldBusyRecord wbr = busy_worlds.get(w.provider.getDimension());
- if(wbr == null) { // Not busy, make ticket and keep spawn loaded
- Debug.debug("World " + w.getWorldInfo().getWorldName() + "/"+ w.provider.getDimensionType().getName() + " is busy");
- wbr = new WorldBusyRecord();
- if(t != null)
- wbr.ticket = t;
- else
- wbr.ticket = ForgeChunkManager.requestTicket(DynmapMod.instance, w, ForgeChunkManager.Type.NORMAL);
- if(wbr.ticket != null) {
- BlockPos cc = w.getSpawnPoint();
- ChunkPos ccip = new ChunkPos(cc.getX() >> 4, cc.getZ() >> 4);
- ForgeChunkManager.forceChunk(wbr.ticket, ccip);
- busy_worlds.put(w.provider.getDimension(), wbr); // Add to busy list
- }
- }
- wbr.last_ts = System.nanoTime();
- }
-
- private void doIdleOutOfWorlds() {
- if (!DynmapMod.useforcedchunks) return;
- long ts = System.nanoTime() - worldIdleTimeoutNS;
- for(Iterator<WorldBusyRecord> itr = busy_worlds.values().iterator(); itr.hasNext();) {
- WorldBusyRecord wbr = itr.next();
- if(wbr.last_ts < ts) {
- World w = wbr.ticket.world;
- Debug.debug("World " + w.getWorldInfo().getWorldName() + "/" + wbr.ticket.world.provider.getDimensionType().getName() + " is idle");
- if (wbr.ticket != null)
- ForgeChunkManager.releaseTicket(wbr.ticket); // Release hold on world
- itr.remove();
- }
- }
- }
- */
-
- public static class OurLog implements DynmapLogger {
- Logger log;
- public static final String DM = "[Dynmap] ";
- OurLog() {
- log = LogManager.getLogger("Dynmap");
- }
- @Override
- public void info(String s) {
- log.info(DM + s);
- }
- @Override
- public void severe(Throwable t) {
- log.fatal(t);
- }
- @Override
- public void severe(String s) {
- log.fatal(DM + s);
- }
- @Override
- public void severe(String s, Throwable t) {
- log.fatal(DM + s, t);
- }
- @Override
- public void verboseinfo(String s) {
- log.info(DM + s);
- }
- @Override
- public void warning(String s) {
- log.warn(DM + s);
- }
- @Override
- public void warning(String s, Throwable t) {
- log.warn(DM + s, t);
- }
- }
-
- public DynmapPlugin(MinecraftServer srv)
- {
- plugin = this;
- this.server = srv;
- }
- public boolean isOp(String player) {
- String[] ops = server.getPlayerList().getOppedPlayers().getKeys();
- for (String op : ops) {
- if (op.equalsIgnoreCase(player)) {
- return true;
- }
- }
- return (server.isSinglePlayer() && player.equalsIgnoreCase(server.getServerOwner()));
- }
-
- private boolean hasPerm(EntityPlayer psender, String permission) {
- PermissionsHandler ph = PermissionsHandler.getHandler();
- if((psender != null) && (ph != null) && ph.hasPermission(psender.getEntity().getName().getString(), permission)) {
- return true;
- }
- return permissions.has(psender, permission);
- }
-
- private boolean hasPermNode(EntityPlayer psender, String permission) {
- PermissionsHandler ph = PermissionsHandler.getHandler();
- if((psender != null) && (ph != null) && ph.hasPermissionNode(psender.getEntity().getName().getString(), permission)) {
- return true;
- }
- return permissions.hasPermissionNode(psender, permission);
- }
- private Set<String> hasOfflinePermissions(String player, Set<String> perms) {
- Set<String> rslt = null;
- PermissionsHandler ph = PermissionsHandler.getHandler();
- if(ph != null) {
- rslt = ph.hasOfflinePermissions(player, perms);
- }
- Set<String> rslt2 = hasOfflinePermissions(player, perms);
- if((rslt != null) && (rslt2 != null)) {
- Set<String> newrslt = new HashSet<String>(rslt);
- newrslt.addAll(rslt2);
- rslt = newrslt;
- }
- else if(rslt2 != null) {
- rslt = rslt2;
- }
- return rslt;
- }
- private boolean hasOfflinePermission(String player, String perm) {
- PermissionsHandler ph = PermissionsHandler.getHandler();
- if(ph != null) {
- if(ph.hasOfflinePermission(player, perm)) {
- return true;
- }
- }
- return permissions.hasOfflinePermission(player, perm);
- }
- /**
- * Server access abstraction class
- */
- public class ForgeServer extends DynmapServerInterface
- {
- /* Server thread scheduler */
- private Object schedlock = new Object();
- private long cur_tick;
- private long next_id;
- private long cur_tick_starttime;
- private PriorityQueue<TaskRecord> runqueue = new PriorityQueue<TaskRecord>();
- public ForgeServer() {
- }
- private GameProfile getProfileByName(String player) {
- PlayerProfileCache cache = server.getPlayerProfileCache();
- return cache.getGameProfileForUsername(player);
- }
-
- @Override
- public int getBlockIDAt(String wname, int x, int y, int z) {
- return -1;
- }
-
- @Override
- public int isSignAt(String wname, int x, int y, int z) {
- return -1;
- }
- @Override
- public void scheduleServerTask(Runnable run, long delay)
- {
- TaskRecord tr = new TaskRecord();
- tr.future = new FutureTask<Object>(run, null);
- /* Add task record to queue */
- synchronized (schedlock)
- {
- tr.id = next_id++;
- tr.ticktorun = cur_tick + delay;
- runqueue.add(tr);
- }
- }
- @Override
- public DynmapPlayer[] getOnlinePlayers()
- {
- if(server.getPlayerList() == null)
- return new DynmapPlayer[0];
- List<?> playlist = server.getPlayerList().getPlayers();
- int pcnt = playlist.size();
- DynmapPlayer[] dplay = new DynmapPlayer[pcnt];
- for (int i = 0; i < pcnt; i++)
- {
- EntityPlayer p = (EntityPlayer)playlist.get(i);
- dplay[i] = getOrAddPlayer(p);
- }
- return dplay;
- }
- @Override
- public void reload()
- {
- plugin.onDisable();
- plugin.onEnable();
- plugin.onStart();
- }
- @Override
- public DynmapPlayer getPlayer(String name)
- {
- List<?> players = server.getPlayerList().getPlayers();
- for (Object o : players)
- {
- EntityPlayer p = (EntityPlayer)o;
- if (p.getEntity().getName().getString().equalsIgnoreCase(name))
- {
- return getOrAddPlayer(p);
- }
- }
- return null;
- }
- @Override
- public Set<String> getIPBans()
- {
- UserListIPBans bl = server.getPlayerList().getBannedIPs();
- Set<String> ips = new HashSet<String>();
- for (String s : bl.getKeys()) {
- ips.add(s);
- }
-
- return ips;
- }
- @Override
- public <T> Future<T> callSyncMethod(Callable<T> task) {
- return callSyncMethod(task, 0);
- }
- public <T> Future<T> callSyncMethod(Callable<T> task, long delay)
- {
- TaskRecord tr = new TaskRecord();
- FutureTask<T> ft = new FutureTask<T>(task);
- tr.future = ft;
- /* Add task record to queue */
- synchronized (schedlock)
- {
- tr.id = next_id++;
- tr.ticktorun = cur_tick + delay;
- runqueue.add(tr);
- }
- return ft;
- }
- @Override
- public String getServerName()
- {
- String sn;
- if (server.isSinglePlayer())
- sn = "Integrated";
- else
- sn = server.getServerHostname();
- if(sn == null) sn = "Unknown Server";
- return sn;
- }
- @Override
- public boolean isPlayerBanned(String pid)
- {
- UserListBans bl = server.getPlayerList().getBannedPlayers();
- return bl.isBanned(getProfileByName(pid));
- }
-
- @Override
- public String stripChatColor(String s)
- {
- return patternControlCode.matcher(s).replaceAll("");
- }
- private Set<EventType> registered = new HashSet<EventType>();
- @Override
- public boolean requestEventNotification(EventType type)
- {
- if (registered.contains(type))
- {
- return true;
- }
- switch (type)
- {
- case WORLD_LOAD:
- case WORLD_UNLOAD:
- /* Already called for normal world activation/deactivation */
- break;
- case WORLD_SPAWN_CHANGE:
- /*TODO
- pm.registerEvents(new Listener() {
- @EventHandler(priority=EventPriority.MONITOR)
- public void onSpawnChange(SpawnChangeEvent evt) {
- DynmapWorld w = new BukkitWorld(evt.getWorld());
- core.listenerManager.processWorldEvent(EventType.WORLD_SPAWN_CHANGE, w);
- }
- }, DynmapPlugin.this);
- */
- break;
- case PLAYER_JOIN:
- case PLAYER_QUIT:
- /* Already handled */
- break;
- case PLAYER_BED_LEAVE:
- /*TODO
- pm.registerEvents(new Listener() {
- @EventHandler(priority=EventPriority.MONITOR)
- public void onPlayerBedLeave(PlayerBedLeaveEvent evt) {
- DynmapPlayer p = new BukkitPlayer(evt.getPlayer());
- core.listenerManager.processPlayerEvent(EventType.PLAYER_BED_LEAVE, p);
- }
- }, DynmapPlugin.this);
- */
- break;
- case PLAYER_CHAT:
- if (chathandler == null) {
- chathandler = new ChatHandler();
- MinecraftForge.EVENT_BUS.register(chathandler);
- }
- break;
- case BLOCK_BREAK:
- /*TODO
- pm.registerEvents(new Listener() {
- @EventHandler(priority=EventPriority.MONITOR)
- public void onBlockBreak(BlockBreakEvent evt) {
- if(evt.isCancelled()) return;
- Block b = evt.getBlock();
- if(b == null) return;
- Location l = b.getLocation();
- core.listenerManager.processBlockEvent(EventType.BLOCK_BREAK, b.getType().getId(),
- BukkitWorld.normalizeWorldName(l.getWorld().getName()), l.getBlockX(), l.getBlockY(), l.getBlockZ());
- }
- }, DynmapPlugin.this);
- */
- break;
- case SIGN_CHANGE:
- /*TODO
- pm.registerEvents(new Listener() {
- @EventHandler(priority=EventPriority.MONITOR)
- public void onSignChange(SignChangeEvent evt) {
- if(evt.isCancelled()) return;
- Block b = evt.getBlock();
- Location l = b.getLocation();
- String[] lines = evt.getLines();
- DynmapPlayer dp = null;
- Player p = evt.getPlayer();
- if(p != null) dp = new BukkitPlayer(p);
- core.listenerManager.processSignChangeEvent(EventType.SIGN_CHANGE, b.getType().getId(),
- BukkitWorld.normalizeWorldName(l.getWorld().getName()), l.getBlockX(), l.getBlockY(), l.getBlockZ(), lines, dp);
- }
- }, DynmapPlugin.this);
- */
- break;
- default:
- Log.severe("Unhandled event type: " + type);
- return false;
- }
- registered.add(type);
- return true;
- }
- @Override
- public boolean sendWebChatEvent(String source, String name, String msg)
- {
- return DynmapCommonAPIListener.fireWebChatEvent(source, name, msg);
- }
- @Override
- public void broadcastMessage(String msg)
- {
- ITextComponent component = new TextComponentString(msg);
- server.getPlayerList().sendMessage(component);
- Log.info(stripChatColor(msg));
- }
- @Override
- public String[] getBiomeIDs()
- {
- BiomeMap[] b = BiomeMap.values();
- String[] bname = new String[b.length];
- for (int i = 0; i < bname.length; i++)
- {
- bname[i] = b[i].toString();
- }
- return bname;
- }
- @Override
- public double getCacheHitRate()
- {
- if(sscache != null)
- return sscache.getHitRate();
- return 0.0;
- }
- @Override
- public void resetCacheStats()
- {
- if(sscache != null)
- sscache.resetStats();
- }
- @Override
- public DynmapWorld getWorldByName(String wname)
- {
- return DynmapPlugin.this.getWorldByName(wname);
- }
- @Override
- public DynmapPlayer getOfflinePlayer(String name)
- {
- /*
- OfflinePlayer op = getServer().getOfflinePlayer(name);
- if(op != null) {
- return new BukkitPlayer(op);
- }
- */
- return null;
- }
- @Override
- public Set<String> checkPlayerPermissions(String player, Set<String> perms)
- {
- net.minecraft.server.management.PlayerList scm = server.getPlayerList();
- if (scm == null) return Collections.emptySet();
- UserListBans bl = scm.getBannedPlayers();
- if (bl == null) return Collections.emptySet();
- if(bl.isBanned(getProfileByName(player))) {
- return Collections.emptySet();
- }
- Set<String> rslt = hasOfflinePermissions(player, perms);
- if (rslt == null) {
- rslt = new HashSet<String>();
- if(plugin.isOp(player)) {
- rslt.addAll(perms);
- }
- }
- return rslt;
- }
- @Override
- public boolean checkPlayerPermission(String player, String perm)
- {
- net.minecraft.server.management.PlayerList scm = server.getPlayerList();
- if (scm == null) return false;
- UserListBans bl = scm.getBannedPlayers();
- if (bl == null) return false;
- if(bl.isBanned(getProfileByName(player))) {
- return false;
- }
- return hasOfflinePermission(player, perm);
- }
- /**
- * Render processor helper - used by code running on render threads to request chunk snapshot cache from server/sync thread
- */
- @Override
- public MapChunkCache createMapChunkCache(DynmapWorld w, List<DynmapChunk> chunks,
- boolean blockdata, boolean highesty, boolean biome, boolean rawbiome)
- {
- ForgeMapChunkCache c = (ForgeMapChunkCache) w.getChunkCache(chunks);
- if(c == null) {
- return null;
- }
- if (w.visibility_limits != null)
- {
- for (VisibilityLimit limit: w.visibility_limits)
- {
- c.setVisibleRange(limit);
- }
- c.setHiddenFillStyle(w.hiddenchunkstyle);
- }
- if (w.hidden_limits != null)
- {
- for (VisibilityLimit limit: w.hidden_limits)
- {
- c.setHiddenRange(limit);
- }
- c.setHiddenFillStyle(w.hiddenchunkstyle);
- }
- if (c.setChunkDataTypes(blockdata, biome, highesty, rawbiome) == false)
- {
- Log.severe("CraftBukkit build does not support biome APIs");
- }
- if (chunks.size() == 0) /* No chunks to get? */
- {
- c.loadChunks(0);
- return c;
- }
-
- //Now handle any chunks in server thread that are already loaded (on server thread)
- final ForgeMapChunkCache cc = c;
- Future<Boolean> f = this.callSyncMethod(new Callable<Boolean>() {
- public Boolean call() throws Exception {
- // Update busy state on world
- ForgeWorld fw = (ForgeWorld)cc.getWorld();
- //TODO
- //setBusy(fw.getWorld());
- cc.getLoadedChunks();
- return true;
- }
- }, 0);
- try {
- f.get();
- }
- catch (CancellationException cx) {
- return null;
- }
- catch (ExecutionException xx) {
- Log.severe("Exception while loading chunks", xx.getCause());
- return null;
- }
- catch (Exception ix) {
- Log.severe(ix);
- return null;
- }
- if(w.isLoaded() == false) {
- return null;
- }
- // Now, do rest of chunk reading from calling thread
- c.readChunks(chunks.size());
-
- return c;
- }
- @Override
- public int getMaxPlayers()
- {
- return server.getMaxPlayers();
- }
- @Override
- public int getCurrentPlayers()
- {
- return server.getPlayerList().getCurrentPlayerCount();
- }
- @SubscribeEvent
- public void tickEvent(TickEvent.ServerTickEvent event) {
- if (event.phase == TickEvent.Phase.START) {
- return;
- }
- cur_tick_starttime = System.nanoTime();
- long elapsed = cur_tick_starttime - lasttick;
- lasttick = cur_tick_starttime;
- avgticklen = ((avgticklen * 99) / 100) + (elapsed / 100);
- tps = (double)1E9 / (double)avgticklen;
- // Tick core
- if (core != null) {
- core.serverTick(tps);
- }
- boolean done = false;
- TaskRecord tr = null;
- while(!blockupdatequeue.isEmpty()) {
- BlockUpdateRec r = blockupdatequeue.remove();
- IBlockState bs = r.w.getBlockState(new BlockPos(r.x, r.y, r.z));
- int idx = Block.BLOCK_STATE_IDS.get(bs);
- if(!org.dynmap.hdmap.HDBlockModels.isChangeIgnoredBlock(stateByID[idx])) {
- if(onblockchange_with_id)
- mapManager.touch(r.wid, r.x, r.y, r.z, "blockchange[" + idx + "]");
- else
- mapManager.touch(r.wid, r.x, r.y, r.z, "blockchange");
- }
- }
- long now;
- synchronized(schedlock) {
- cur_tick++;
- now = System.nanoTime();
- tr = runqueue.peek();
- /* Nothing due to run */
- if((tr == null) || (tr.ticktorun > cur_tick) || ((now - cur_tick_starttime) > perTickLimit)) {
- done = true;
- }
- else {
- tr = runqueue.poll();
- }
- }
- while (!done) {
- tr.future.run();
- synchronized(schedlock) {
- tr = runqueue.peek();
- now = System.nanoTime();
- /* Nothing due to run */
- if((tr == null) || (tr.ticktorun > cur_tick) || ((now - cur_tick_starttime) > perTickLimit)) {
- done = true;
- }
- else {
- tr = runqueue.poll();
- }
- }
- }
- while(!msgqueue.isEmpty()) {
- ChatMessage cm = msgqueue.poll();
- DynmapPlayer dp = null;
- if(cm.sender != null)
- dp = getOrAddPlayer(cm.sender);
- else
- dp = new ForgePlayer(null);
- core.listenerManager.processChatEvent(EventType.PLAYER_CHAT, dp, cm.message);
- }
- /* Check for idle worlds */
- if((cur_tick % 20) == 0) {
- //TODO
- //doIdleOutOfWorlds();
- }
- }
- @Override
- public boolean isModLoaded(String name) {
- boolean loaded = ModList.get().isLoaded(name);
- if (loaded) {
- modsused.add(name);
- }
- return loaded;
- }
- @Override
- public String getModVersion(String name) {
- Optional<? extends ModContainer> mod = ModList.get().getModContainerById(name); // Try case sensitive lookup
- if (mod.isPresent()) {
- ArtifactVersion vi = mod.get().getModInfo().getVersion();
- return vi.getMajorVersion() + "." + vi.getMinorVersion() + "." + vi.getIncrementalVersion();
- }
- return null;
- }
- @Override
- public double getServerTPS() {
- return tps;
- }
-
- @Override
- public String getServerIP() {
- if (server.isSinglePlayer())
- return "0.0.0.0";
- else
- return server.getServerHostname();
- }
- @Override
- public File getModContainerFile(String name) {
- ModFileInfo mfi = ModList.get().getModFileById(name); // Try case sensitive lookup
- if (mfi != null) {
- File f = mfi.getFile().getFilePath().toFile();
- return f;
- }
- return null;
- }
- @Override
- public List<String> getModList() {
- List<ModInfo> mil = ModList.get().getMods();
- List<String> lst = new ArrayList<String>();
- for (ModInfo mi : mil) {
- lst.add(mi.getModId());
- }
- return lst;
- }
- @Override
- public Map<Integer, String> getBlockIDMap() {
- Map<Integer, String> map = new HashMap<Integer, String>();
- return map;
- }
- @Override
- public InputStream openResource(String modid, String rname) {
- if (modid != null) {
- Optional<? extends ModContainer> mc = ModList.get().getModContainerById(modid);
- Object mod = (mc.isPresent()) ? mc.get().getMod() : null;
- if (mod != null) {
- InputStream is = mod.getClass().getClassLoader().getResourceAsStream(rname);
- if (is != null) {
- return is;
- }
- }
- }
- List<ModInfo> mcl = ModList.get().getMods();
- for (ModInfo mci : mcl) {
- Optional<? extends ModContainer> mc = ModList.get().getModContainerById(mci.getModId());
- Object mod = (mc.isPresent()) ? mc.get().getMod() : null;
- if (mod == null) continue;
- InputStream is = mod.getClass().getClassLoader().getResourceAsStream(rname);
- if (is != null) {
- return is;
- }
- }
- return null;
- }
- /**
- * Get block unique ID map (module:blockid)
- */
- @Override
- public Map<String, Integer> getBlockUniqueIDMap() {
- HashMap<String, Integer> map = new HashMap<String, Integer>();
- return map;
- }
- /**
- * Get item unique ID map (module:itemid)
- */
- @Override
- public Map<String, Integer> getItemUniqueIDMap() {
- HashMap<String, Integer> map = new HashMap<String, Integer>();
- return map;
- }
- }
- private static final Gson gson = new GsonBuilder().create();
- public class TexturesPayload {
- public long timestamp;
- public String profileId;
- public String profileName;
- public boolean isPublic;
- public Map<String, ProfileTexture> textures;
- }
- public class ProfileTexture {
- public String url;
- }
-
- /**
- * Player access abstraction class
- */
- public class ForgePlayer extends ForgeCommandSender implements DynmapPlayer
- {
- private EntityPlayer player;
- private final String skinurl;
- private final UUID uuid;
- public ForgePlayer(EntityPlayer p)
- {
- player = p;
- String url = null;
- if (player != null) {
- uuid = player.getUniqueID();
- GameProfile prof = player.getGameProfile();
- if (prof != null) {
- Property textureProperty = Iterables.getFirst(prof.getProperties().get("textures"), null);
- if (textureProperty != null) {
- TexturesPayload result = null;
- try {
- String json = new String(Base64.decodeBase64(textureProperty.getValue()), Charsets.UTF_8);
- result = gson.fromJson(json, TexturesPayload.class);
- } catch (JsonParseException e) {
- }
- if ((result != null) && (result.textures != null) && (result.textures.containsKey("SKIN"))) {
- url = result.textures.get("SKIN").url;
- }
- }
- }
- }
- else {
- uuid = null;
- }
- skinurl = url;
- }
- @Override
- public boolean isConnected()
- {
- return true;
- }
- @Override
- public String getName()
- {
- if(player != null) {
- String n = player.getEntity().getName().getString();;
- return n;
- }
- else
- return "[Server]";
- }
- @Override
- public String getDisplayName()
- {
- if(player != null) {
- String n = player.getDisplayName().getString();
- return n;
- }
- else
- return "[Server]";
- }
- @Override
- public boolean isOnline()
- {
- return true;
- }
- @Override
- public DynmapLocation getLocation()
- {
- if (player == null)
- {
- return null;
- }
- return toLoc(player.world, player.posX, player.posY, player.posZ);
- }
- @Override
- public String getWorld()
- {
- if (player == null)
- {
- return null;
- }
- if (player.world != null)
- {
- return DynmapPlugin.this.getWorld(player.world).getName();
- }
- return null;
- }
- @Override
- public InetSocketAddress getAddress()
- {
- if((player != null) && (player instanceof EntityPlayerMP)) {
- NetHandlerPlayServer nsh = ((EntityPlayerMP)player).connection;
- if((nsh != null) && (getNetworkManager(nsh) != null)) {
- SocketAddress sa = getNetworkManager(nsh).getRemoteAddress();
- if(sa instanceof InetSocketAddress) {
- return (InetSocketAddress)sa;
- }
- }
- }
- return null;
- }
- @Override
- public boolean isSneaking()
- {
- if (player != null)
- {
- return player.isSneaking();
- }
- return false;
- }
- @Override
- public double getHealth()
- {
- if (player != null)
- {
- double h = player.getHealth();
- if(h > 20) h = 20;
- return h; // Scale to 20 range
- }
- else
- {
- return 0;
- }
- }
- @Override
- public int getArmorPoints()
- {
- if (player != null)
- {
- return player.getTotalArmorValue();
- }
- else
- {
- return 0;
- }
- }
- @Override
- public DynmapLocation getBedSpawnLocation()
- {
- return null;
- }
- @Override
- public long getLastLoginTime()
- {
- return 0;
- }
- @Override
- public long getFirstLoginTime()
- {
- return 0;
- }
- @Override
- public boolean hasPrivilege(String privid)
- {
- if(player != null)
- return hasPerm(player, privid);
- return false;
- }
- @Override
- public boolean isOp()
- {
- return DynmapPlugin.this.isOp(player.getEntity().getName().getString());
- }
- @Override
- public void sendMessage(String msg)
- {
- ITextComponent ichatcomponent = new TextComponentString(msg);
- player.sendMessage(ichatcomponent);
- }
- @Override
- public boolean isInvisible() {
- if(player != null) {
- return player.isInvisible();
- }
- return false;
- }
- @Override
- public int getSortWeight() {
- Integer wt = sortWeights.get(getName());
- if (wt != null)
- return wt;
- return 0;
- }
- @Override
- public void setSortWeight(int wt) {
- if (wt == 0) {
- sortWeights.remove(getName());
- }
- else {
- sortWeights.put(getName(), wt);
- }
- }
- @Override
- public boolean hasPermissionNode(String node) {
- if(player != null)
- return hasPermNode(player, node);
- return false;
- }
- @Override
- public String getSkinURL() {
- return skinurl;
- }
- @Override
- public UUID getUUID() {
- return uuid;
- }
- /**
- * Send title and subtitle text (called from server thread)
- */
- @Override
- public void sendTitleText(String title, String subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks) {
- if (player instanceof EntityPlayerMP) {
- EntityPlayerMP mp = (EntityPlayerMP) player;
- SPacketTitle times = new SPacketTitle(fadeInTicks, stayTicks, fadeOutTicks);
- mp.connection.sendPacket(times);
- if (title != null) {
- SPacketTitle titlepkt = new SPacketTitle(SPacketTitle.Type.TITLE, new TextComponentString(title));
- mp.connection.sendPacket(titlepkt);
- }
- if (subtitle != null) {
- SPacketTitle subtitlepkt = new SPacketTitle(SPacketTitle.Type.SUBTITLE, new TextComponentString(subtitle));
- mp.connection.sendPacket(subtitlepkt);
- }
- }
- }
- }
- /* Handler for generic console command sender */
- public class ForgeCommandSender implements DynmapCommandSender
- {
- private CommandSource sender;
- protected ForgeCommandSender() {
- sender = null;
- }
- public ForgeCommandSender(CommandSource send)
- {
- sender = send;
- }
- @Override
- public boolean hasPrivilege(String privid)
- {
- return true;
- }
- @Override
- public void sendMessage(String msg)
- {
- if(sender != null) {
- ITextComponent ichatcomponent = new TextComponentString(msg);
- sender.sendFeedback(ichatcomponent, false);
- }
- }
- @Override
- public boolean isConnected()
- {
- return false;
- }
- @Override
- public boolean isOp()
- {
- return true;
- }
- @Override
- public boolean hasPermissionNode(String node) {
- return true;
- }
- }
- public void loadExtraBiomes(String mcver) {
- int cnt = 0;
- BiomeMap.loadWellKnownByVersion(mcver);
- Biome[] list = getBiomeList();
-
- for(int i = 0; i < list.length; i++) {
- Biome bb = list[i];
- if(bb != null) {
- String id = bb.getRegistryName().getPath();
- float tmp = bb.getDefaultTemperature(), hum = bb.getDownfall();
- int watermult = bb.getWaterColor();
- Log.verboseinfo("biome[" + i + "]: hum=" + hum + ", tmp=" + tmp + ", mult=" + Integer.toHexString(watermult));
- BiomeMap bmap = BiomeMap.byBiomeID(i);
- if (bmap.isDefault()) {
- bmap = new BiomeMap(i, id, tmp, hum);
- Log.verboseinfo("Add custom biome [" + bmap.toString() + "] (" + i + ")");
- cnt++;
- }
- else {
- bmap.setTemperature(tmp);
- bmap.setRainfall(hum);
- }
- if (watermult != -1) {
- bmap.setWaterColorMultiplier(watermult);
- Log.verboseinfo("Set watercolormult for " + bmap.toString() + " (" + i + ") to " + Integer.toHexString(watermult));
- }
- }
- }
- if(cnt > 0)
- Log.info("Added " + cnt + " custom biome mappings");
- }
- private String[] getBiomeNames() {
- Biome[] list = getBiomeList();
- String[] lst = new String[list.length];
- for(int i = 0; i < list.length; i++) {
- Biome bb = list[i];
- if (bb != null) {
- lst[i] = bb.getRegistryName().getPath();
- }
- }
- return lst;
- }
- public void onEnable()
- {
- /* Get MC version */
- String mcver = server.getMinecraftVersion();
- /* Load extra biomes */
- loadExtraBiomes(mcver);
- /* Set up player login/quit event handler */
- registerPlayerLoginListener();
- /* Initialize permissions handler */
- permissions = FilePermissions.create();
- if(permissions == null) {
- permissions = new OpPermissions(new String[] { "webchat", "marker.icons", "marker.list", "webregister", "stats", "hide.self", "show.self" });
- }
- /* Get and initialize data folder */
- File dataDirectory = new File("dynmap");
- if (dataDirectory.exists() == false)
- {
- dataDirectory.mkdirs();
- }
- /* Instantiate core */
- if (core == null)
- {
- core = new DynmapCore();
- }
- /* Inject dependencies */
- core.setPluginJarFile(DynmapMod.jarfile);
- core.setPluginVersion(DynmapMod.ver);
- core.setMinecraftVersion(mcver);
- core.setDataFolder(dataDirectory);
- core.setServer(fserver);
- ForgeMapChunkCache.init();
- core.setTriggerDefault(TRIGGER_DEFAULTS);
- core.setBiomeNames(getBiomeNames());
- if(!core.initConfiguration(null))
- {
- return;
- }
- // Extract default permission example, if needed
- File filepermexample = new File(core.getDataFolder(), "permissions.yml.example");
- core.createDefaultFileFromResource("/permissions.yml.example", filepermexample);
- DynmapCommonAPIListener.apiInitialized(core);
- }
-
- private static int test(CommandSource source) throws CommandSyntaxException
- {
- System.out.println(source.toString());
- return 1;
- }
-
- private DynmapCommand dynmapCmd;
- private DmapCommand dmapCmd;
- private DmarkerCommand dmarkerCmd;
- private DynmapExpCommand dynmapexpCmd;
- public void onStarting(CommandDispatcher<CommandSource> cd) {
- /* Register command hander */
- dynmapC…
Large files files are truncated, but you can click here to view the full file