Example #1
0
 /**
  * Get scaled set of models for all modelled blocks
  *
  * @param scale
  * @return
  */
 public static HDScaledBlockModels getModelsForScale(int scale) {
   HDScaledBlockModels model = scaled_models_by_scale.get(Integer.valueOf(scale));
   if (model == null) {
     model = new HDScaledBlockModels();
     short[][][] blockmodels = new short[256][][];
     for (HDBlockModels m : models_by_id_data.values()) {
       short[][] row = blockmodels[m.blockid];
       if (row == null) {
         row = new short[16][];
         blockmodels[m.blockid] = row;
       }
       short[] smod = null;
       for (int i = 0; i < 16; i++) {
         if ((m.databits & (1 << i)) != 0) {
           if (smod == null) smod = m.getScaledMap(scale);
           row[i] = smod;
         }
       }
     }
     model.modelvectors = blockmodels;
     scaled_models_by_scale.put(scale, model);
   }
   return model;
 }
Example #2
0
  public IsoHDPerspective(ConfigurationNode configuration) {
    name = configuration.getString("name", null);
    if (name == null) {
      Log.severe("Perspective definition missing name - must be defined and unique");
      return;
    }
    azimuth =
        configuration.getDouble("azimuth", 135.0); /* Get azimuth (default to classic kzed POV */
    inclination = configuration.getDouble("inclination", 60.0);
    if (inclination > MAX_INCLINATION) inclination = MAX_INCLINATION;
    if (inclination < MIN_INCLINATION) inclination = MIN_INCLINATION;
    scale = configuration.getDouble("scale", MIN_SCALE);
    if (scale < MIN_SCALE) scale = MIN_SCALE;
    if (scale > MAX_SCALE) scale = MAX_SCALE;
    /* Get max and min height */
    maxheight = configuration.getInteger("maximumheight", 127);
    if (maxheight > 127) maxheight = 127;
    minheight = configuration.getInteger("minimumheight", 0);
    if (minheight < 0) minheight = 0;

    /* Generate transform matrix for world-to-tile coordinate mapping */
    /* First, need to fix basic coordinate mismatches before rotation - we want zero azimuth to have north to top
     * (world -X -> tile +Y) and east to right (world -Z to tile +X), with height being up (world +Y -> tile +Z)
     */
    Matrix3D transform = new Matrix3D(0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    /* Next, rotate world counterclockwise around Z axis by azumuth angle */
    transform.rotateXY(180 - azimuth);
    /* Next, rotate world by (90-inclination) degrees clockwise around +X axis */
    transform.rotateYZ(90.0 - inclination);
    /* Finally, shear along Z axis to normalize Z to be height above map plane */
    transform.shearZ(0, Math.tan(Math.toRadians(90.0 - inclination)));
    /* And scale Z to be same scale as world coordinates, and scale X and Y based on setting */
    transform.scale(scale, scale, Math.sin(Math.toRadians(inclination)));
    world_to_map = transform;
    /* Now, generate map to world tranform, by doing opposite actions in reverse order */
    transform = new Matrix3D();
    transform.scale(1.0 / scale, 1.0 / scale, 1 / Math.sin(Math.toRadians(inclination)));
    transform.shearZ(0, -Math.tan(Math.toRadians(90.0 - inclination)));
    transform.rotateYZ(-(90.0 - inclination));
    transform.rotateXY(-180 + azimuth);
    Matrix3D coordswap = new Matrix3D(0.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 0.0);
    transform.multiply(coordswap);
    map_to_world = transform;
    /* Scaled models for non-cube blocks */
    modscale = (int) Math.ceil(scale);
    scalemodels = HDBlockModels.getModelsForScale(modscale);
    ;
  }
Example #3
0
  @Override
  public void onEnable() {
    /* Start with clean events */
    events = new Events();

    permissions = NijikokunPermissions.create(getServer(), "dynmap");
    if (permissions == null) permissions = BukkitPermissions.create("dynmap");
    if (permissions == null)
      permissions =
          new OpPermissions(
              new String[] {
                "fullrender", "cancelrender", "radiusrender", "resetstats", "reload", "purgequeue"
              });

    dataDirectory = this.getDataFolder();
    if (dataDirectory.exists() == false) dataDirectory.mkdirs();

    /* Initialize confguration.txt if needed */
    File f = new File(this.getDataFolder(), "configuration.txt");
    if (!createDefaultFileFromResource("/configuration.txt", f)) {
      this.setEnabled(false);
      return;
    }
    /* Load configuration.txt */
    org.bukkit.util.config.Configuration bukkitConfiguration =
        new org.bukkit.util.config.Configuration(f);
    bukkitConfiguration.load();
    configuration = new ConfigurationNode(bukkitConfiguration);

    /* Load block models */
    HDBlockModels.loadModels(dataDirectory, configuration);
    /* Load texture mappings */
    TexturePack.loadTextureMapping(dataDirectory, configuration);

    /* Now, process worlds.txt - merge it in as an override of existing values (since it is only user supplied values) */
    f = new File(this.getDataFolder(), "worlds.txt");
    if (!createDefaultFileFromResource("/worlds.txt", f)) {
      this.setEnabled(false);
      return;
    }
    org.bukkit.util.config.Configuration cfg = new org.bukkit.util.config.Configuration(f);
    cfg.load();
    ConfigurationNode cn = new ConfigurationNode(cfg);
    mergeConfigurationBranch(cn, "worlds", true, true);

    /* Now, process templates */
    loadTemplates();

    Log.verbose = configuration.getBoolean("verbose", true);
    deftemplatesuffix = configuration.getString("deftemplatesuffix", "");
    /* Default swamp shading off for 1.8, on after */
    swampshading =
        configuration.getBoolean("swampshaded", !getServer().getVersion().contains("(MC: 1.8"));
    /* Default water biome shading off for 1.8, on after */
    waterbiomeshading =
        configuration.getBoolean(
            "waterbiomeshaded", !getServer().getVersion().contains("(MC: 1.8"));
    /* Default fence-to-block-join off for 1.8, on after */
    fencejoin =
        configuration.getBoolean(
            "fence-to-block-join", !getServer().getVersion().contains("(MC: 1.8"));
    /* Default compassmode to pre19, to newrose after */
    String cmode =
        configuration.getString(
            "compass-mode", getServer().getVersion().contains("(MC: 1.8") ? "pre19" : "newrose");
    if (cmode.equals("newnorth")) compassmode = CompassMode.NEWNORTH;
    else if (cmode.equals("newrose")) compassmode = CompassMode.NEWROSE;
    else compassmode = CompassMode.PRE19;

    loadDebuggers();

    tilesDirectory = getFile(configuration.getString("tilespath", "web/tiles"));
    if (!tilesDirectory.isDirectory() && !tilesDirectory.mkdirs()) {
      Log.warning("Could not create directory for tiles ('" + tilesDirectory + "').");
    }

    playerList = new PlayerList(getServer(), getFile("hiddenplayers.txt"), configuration);
    playerList.load();
    PlayerListener pl =
        new PlayerListener() {
          public void onPlayerJoin(PlayerJoinEvent evt) {
            playerList.updateOnlinePlayers(null);
          }

          public void onPlayerQuit(PlayerQuitEvent evt) {
            playerList.updateOnlinePlayers(evt.getPlayer());
          }
        };
    registerEvent(Type.PLAYER_JOIN, pl);
    registerEvent(Type.PLAYER_QUIT, pl);

    mapManager = new MapManager(this, configuration);
    mapManager.startRendering();

    playerfacemgr = new PlayerFaces(this);

    loadWebserver();

    enabledTriggers.clear();
    List<String> triggers = configuration.getStrings("render-triggers", new ArrayList<String>());
    if (triggers != null) {
      for (Object trigger : triggers) {
        enabledTriggers.add((String) trigger);
      }
    }

    // Load components.
    for (Component component :
        configuration.<Component>createInstances(
            "components", new Class<?>[] {DynmapPlugin.class}, new Object[] {this})) {
      componentManager.add(component);
    }
    Log.verboseinfo("Loaded " + componentManager.components.size() + " components.");

    registerEvents();

    if (!configuration.getBoolean("disable-webserver", false)) {
      startWebserver();
    }

    /* Print version info */
    PluginDescriptionFile pdfFile = this.getDescription();
    Log.info("version " + pdfFile.getVersion() + " is enabled");

    events.<Object>trigger("initialized", null);
  }
 @Override
 public RenderPatchFactory getPatchFactory() {
   return HDBlockModels.getPatchDefinitionFactory();
 }
Example #5
0
 /** Load models from file */
 private static void loadModelFile(InputStream in, String fname) {
   LineNumberReader rdr = null;
   int cnt = 0;
   try {
     String line;
     ArrayList<HDBlockModels> modlist = new ArrayList<HDBlockModels>();
     int layerbits = 0;
     int rownum = 0;
     int scale = 0;
     rdr = new LineNumberReader(new InputStreamReader(in));
     while ((line = rdr.readLine()) != null) {
       if (line.startsWith("block:")) {
         ArrayList<Integer> blkids = new ArrayList<Integer>();
         int databits = 0;
         scale = 0;
         line = line.substring(6);
         String[] args = line.split(",");
         for (String a : args) {
           String[] av = a.split("=");
           if (av.length < 2) continue;
           if (av[0].equals("id")) {
             blkids.add(Integer.parseInt(av[1]));
           } else if (av[0].equals("data")) {
             if (av[1].equals("*")) databits = 0xFFFF;
             else databits |= (1 << Integer.parseInt(av[1]));
           } else if (av[0].equals("scale")) {
             scale = Integer.parseInt(av[1]);
           }
         }
         /* If we have everything, build block */
         if ((blkids.size() > 0) && (databits != 0) && (scale > 0)) {
           modlist.clear();
           for (Integer id : blkids) {
             modlist.add(new HDBlockModels(id.intValue(), databits, scale, new long[0]));
             cnt++;
           }
         } else {
           Log.severe(
               "Block model missing required parameters = line "
                   + rdr.getLineNumber()
                   + " of "
                   + fname);
         }
         layerbits = 0;
       } else if (line.startsWith("layer:")) {
         line = line.substring(6);
         String args[] = line.split(",");
         layerbits = 0;
         rownum = 0;
         for (String a : args) {
           layerbits |= (1 << Integer.parseInt(a));
         }
       } else if (line.startsWith("rotate:")) {
         line = line.substring(7);
         String args[] = line.split(",");
         int id = -1;
         int data = -1;
         int rot = -1;
         for (String a : args) {
           String[] av = a.split("=");
           if (av.length < 2) continue;
           if (av[0].equals("id")) {
             id = Integer.parseInt(av[1]);
           }
           if (av[0].equals("data")) {
             data = Integer.parseInt(av[1]);
           }
           if (av[0].equals("rot")) {
             rot = Integer.parseInt(av[1]);
           }
         }
         /* get old model to be rotated */
         HDBlockModels mod = models_by_id_data.get((id << 4) + data);
         if ((mod != null) && ((rot % 90) == 0)) {
           for (int x = 0; x < scale; x++) {
             for (int y = 0; y < scale; y++) {
               for (int z = 0; z < scale; z++) {
                 if (mod.isSubblockSet(x, y, z) == false) continue;
                 switch (rot) {
                   case 0:
                     for (HDBlockModels bm : modlist) bm.setSubblock(x, y, z, true);
                     break;
                   case 90:
                     for (HDBlockModels bm : modlist) bm.setSubblock(scale - z - 1, y, x, true);
                     break;
                   case 180:
                     for (HDBlockModels bm : modlist)
                       bm.setSubblock(scale - x - 1, y, scale - z - 1, true);
                     break;
                   case 270:
                     for (HDBlockModels bm : modlist) bm.setSubblock(z, y, scale - x - 1, true);
                     break;
                 }
               }
             }
           }
         }
       } else if (line.startsWith("#") || line.startsWith(";")) {
       } else if (layerbits != 0) {
           /* If we're working pattern lines */
         /* Layerbits determine Y, rows count from North to South (X=0 to X=N-1), columns Z are West to East (N-1 to 0) */
         for (int i = 0; (i < scale) && (i < line.length()); i++) {
           if (line.charAt(i) == '*') {
               /* If an asterix, set flag */
             for (int y = 0; y < scale; y++) {
               if ((layerbits & (1 << y)) != 0) {
                 for (HDBlockModels mod : modlist) {
                   mod.setSubblock(rownum, y, scale - i - 1, true);
                 }
               }
             }
           }
         }
         /* See if we're done with layer */
         rownum++;
         if (rownum >= scale) {
           rownum = 0;
           layerbits = 0;
         }
       }
     }
     Log.verboseinfo("Loaded " + cnt + " block models from " + fname);
   } catch (IOException iox) {
     Log.severe("Error reading models.txt - " + iox.toString());
   } catch (NumberFormatException nfx) {
     Log.severe("Format error - line " + rdr.getLineNumber() + " of " + fname);
   } finally {
     if (rdr != null) {
       try {
         rdr.close();
         rdr = null;
       } catch (IOException e) {
       }
     }
   }
 }
Example #6
0
  public int loadChunks(int max_to_load) {
    if (dw.isLoaded() == false) return 0;
    long t0 = System.nanoTime();
    Object queue = helper.getUnloadQueue(helper.getNMSWorld(w));

    int cnt = 0;
    if (iterator == null) iterator = chunks.listIterator();

    DynmapCore.setIgnoreChunkLoads(true);
    // boolean isnormral = w.getEnvironment() == Environment.NORMAL;
    // Load the required chunks.
    while ((cnt < max_to_load) && iterator.hasNext()) {
      DynmapChunk chunk = iterator.next();
      boolean vis = true;
      if (visible_limits != null) {
        vis = false;
        for (VisibilityLimit limit : visible_limits) {
          if ((chunk.x >= limit.x0)
              && (chunk.x <= limit.x1)
              && (chunk.z >= limit.z0)
              && (chunk.z <= limit.z1)) {
            vis = true;
            break;
          }
        }
      }
      if (vis && (hidden_limits != null)) {
        for (VisibilityLimit limit : hidden_limits) {
          if ((chunk.x >= limit.x0)
              && (chunk.x <= limit.x1)
              && (chunk.z >= limit.z0)
              && (chunk.z <= limit.z1)) {
            vis = false;
            break;
          }
        }
      }
      /* Check if cached chunk snapshot found */
      ChunkSnapshot ss = null;
      DynIntHashMap tileData = null;
      SnapshotRec ssr =
          DynmapPlugin.plugin.sscache.getSnapshot(
              dw.getName(), chunk.x, chunk.z, blockdata, biome, biomeraw, highesty);
      if (ssr != null) {
        ss = ssr.ss;
        if (!vis) {
          if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) ss = STONE;
          else if (hidestyle == HiddenChunkStyle.FILL_OCEAN) ss = OCEAN;
          else ss = EMPTY;
        }
        int idx = (chunk.x - x_min) + (chunk.z - z_min) * x_dim;
        snaparray[idx] = ss;
        snaptile[idx] = ssr.tileData;

        continue;
      }
      chunks_attempted++;
      boolean wasLoaded = w.isChunkLoaded(chunk.x, chunk.z);
      boolean didload = false;
      boolean isunloadpending = false;
      if (queue != null) {
        isunloadpending = helper.isInUnloadQueue(queue, chunk.x, chunk.z);
      }
      if (isunloadpending) {
          /* Workaround: can't be pending if not loaded */
        wasLoaded = true;
      }
      try {
        if (!wasLoaded) {
          didload = w.loadChunk(chunk.x, chunk.z, false);
        } else {
            /* If already was loaded, no need to load */
          didload = true;
        }
      } catch (Throwable t) {
          /* Catch chunk error from Bukkit */
        Log.warning("Bukkit error loading chunk " + chunk.x + "," + chunk.z + " on " + w.getName());
        if (!wasLoaded) {
            /* If wasn't loaded, we loaded it if it now is */
          didload = w.isChunkLoaded(chunk.x, chunk.z);
        }
      }
      boolean didgenerate = false;
      /* If we didn't load, and we're supposed to generate, do it */
      if ((!didload) && do_generate && vis)
        didgenerate = didload = w.loadChunk(chunk.x, chunk.z, true);
      /* If it did load, make cache of it */
      if (didload) {
        tileData = new DynIntHashMap();

        Chunk c = w.getChunkAt(chunk.x, chunk.z); /* Get the chunk */
        /* Test if chunk isn't populated */
        boolean populated = true;
        // TODO: figure out why this doesn't appear to be reliable in Bukkit
        // if((nmschunk != null) && (doneflag != null)) {
        //    try {
        //        populated = doneflag.getBoolean(nmschunk);
        //    } catch (IllegalArgumentException e) {
        //    } catch (IllegalAccessException e) {
        //    }
        // }
        if (!vis) {
          if (hidestyle == HiddenChunkStyle.FILL_STONE_PLAIN) ss = STONE;
          else if (hidestyle == HiddenChunkStyle.FILL_OCEAN) ss = OCEAN;
          else ss = EMPTY;
        } else if (!populated) {
            /* If not populated, treat as empty */
          ss = EMPTY;
        } else {
          if (blockdata || highesty) {
            ss = c.getChunkSnapshot(highesty, biome, biomeraw);
            if (use_spout) {
              ss = checkSpoutData(c, ss);
            }
            /* Get tile entity data */
            List<Object> vals = new ArrayList<Object>();
            Map tileents = helper.getTileEntitiesForChunk(c);
            for (Object t : tileents.values()) {
              int te_x = helper.getTileEntityX(t);
              int te_y = helper.getTileEntityY(t);
              int te_z = helper.getTileEntityZ(t);
              int cx = te_x & 0xF;
              int cz = te_z & 0xF;
              int blkid = ss.getBlockTypeId(cx, te_y, cz);
              int blkdat = ss.getBlockData(cx, te_y, cz);
              String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(blkid, blkdat);
              if (te_fields != null) {
                Object nbtcompound = helper.readTileEntityNBT(t);

                vals.clear();
                for (String id : te_fields) {
                  Object val = helper.getFieldValue(nbtcompound, id);
                  if (val != null) {
                    vals.add(id);
                    vals.add(val);
                  }
                }
                if (vals.size() > 0) {
                  Object[] vlist = vals.toArray(new Object[vals.size()]);
                  tileData.put(getIndexInChunk(cx, te_y, cz), vlist);
                }
              }
            }
          } else ss = w.getEmptyChunkSnapshot(chunk.x, chunk.z, biome, biomeraw);
          if (ss != null) {
            ssr = new SnapshotRec();
            ssr.ss = ss;
            ssr.tileData = tileData;
            DynmapPlugin.plugin.sscache.putSnapshot(
                dw.getName(), chunk.x, chunk.z, ssr, blockdata, biome, biomeraw, highesty);
          }
        }
        snaparray[(chunk.x - x_min) + (chunk.z - z_min) * x_dim] = ss;
        snaptile[(chunk.x - x_min) + (chunk.z - z_min) * x_dim] = tileData;

        /* If wasn't loaded before, we need to do unload */
        if (!wasLoaded) {
          chunks_read++;
          /* It looks like bukkit "leaks" entities - they don't get removed from the world-level table
           * when chunks are unloaded but not saved - removing them seems to do the trick */
          if (!(didgenerate && do_save)) {
            helper.removeEntitiesFromChunk(c);
          }
          /* Since we only remember ones we loaded, and we're synchronous, no player has
           * moved, so it must be safe (also prevent chunk leak, which appears to happen
           * because isChunkInUse defined "in use" as being within 256 blocks of a player,
           * while the actual in-use chunk area for a player where the chunks are managed
           * by the MC base server is 21x21 (or about a 160 block radius).
           * Also, if we did generate it, need to save it */
          w.unloadChunk(chunk.x, chunk.z, didgenerate && do_save, false);
        } else if (isunloadpending) {
            /* Else, if loaded and unload is pending */
          w.unloadChunkRequest(chunk.x, chunk.z); /* Request new unload */
        }
      }
      cnt++;
    }
    DynmapCore.setIgnoreChunkLoads(false);

    if (iterator.hasNext() == false) {
        /* If we're done */
      isempty = true;
      /* Fill missing chunks with empty dummy chunk */
      for (int i = 0; i < snaparray.length; i++) {
        if (snaparray[i] == null) snaparray[i] = EMPTY;
        else if (snaparray[i] != EMPTY) isempty = false;
      }
    }
    total_loadtime += System.nanoTime() - t0;

    return cnt;
  }