Beispiel #1
0
 public static boolean clearWorldReference(World world) {
   String worldname = world.getName();
   if (regionfiles == null) return false;
   if (rafField == null) return false;
   ArrayList<Object> removedKeys = new ArrayList<Object>();
   try {
     for (Object o : regionfiles.entrySet()) {
       Map.Entry e = (Map.Entry) o;
       File f = (File) e.getKey();
       if (f.toString().startsWith("." + File.separator + worldname)) {
         SoftReference ref = (SoftReference) e.getValue();
         try {
           RegionFile file = (RegionFile) ref.get();
           if (file != null) {
             RandomAccessFile raf = (RandomAccessFile) rafField.get(file);
             raf.close();
             removedKeys.add(f);
           }
         } catch (Exception ex) {
           ex.printStackTrace();
         }
       }
     }
   } catch (Exception ex) {
     MyWorlds.log(
         Level.WARNING, "Exception while removing world reference for '" + worldname + "'!");
     ex.printStackTrace();
   }
   for (Object key : removedKeys) {
     regionfiles.remove(key);
   }
   return true;
 }
Beispiel #2
0
 public static boolean init() {
   try {
     Field a = net.minecraft.server.RegionFileCache.class.getDeclaredField("a");
     a.setAccessible(true);
     regionfiles = (HashMap) a.get(null);
     rafField = net.minecraft.server.RegionFile.class.getDeclaredField("c");
     rafField.setAccessible(true);
     MyWorlds.log(Level.INFO, "Successfully bound variable to region file cache.");
     MyWorlds.log(Level.INFO, "File references to unloaded worlds will be cleared!");
     return true;
   } catch (Throwable t) {
     MyWorlds.log(Level.WARNING, "Failed to bind to region file cache.");
     MyWorlds.log(Level.WARNING, "Files will stay referenced after being unloaded!");
     t.printStackTrace();
     return false;
   }
 }
Beispiel #3
0
  /**
   * Repairs the chunk region file Returns -1 if the file had to be removed Returns -2 if we had no
   * access Returns -3 if file removal failed (from -1) Returns the amount of changed chunks
   * otherwise
   *
   * @param chunkfile
   * @param backupfolder
   * @return
   */
  public static int repairRegion(File chunkfile, File backupfolder) {
    MyWorlds.log(Level.INFO, "Performing repairs on region file: " + chunkfile.getName());
    RandomAccessFile raf = null;
    try {
      raf = new RandomAccessFile(chunkfile, "rw");
      File backupfile = new File(backupfolder + File.separator + chunkfile.getName());
      int[] locations = new int[1024];
      for (int i = 0; i < 1024; i++) {
        locations[i] = raf.readInt();
      }
      // Validate the data
      int editcount = 0;
      for (int i = 0; i < locations.length; i++) {
        int location = locations[i];
        if (location == 0) continue;
        try {
          int offset = location >> 8;
          int size = location & 255;
          raf.seek((long) (offset * 4096));
          int length = raf.readInt();
          // Read and test the data
          if (length > 4096 * size) {
            editcount++;
            locations[i] = 0;
            MyWorlds.log(Level.WARNING, "Invalid length: " + length + " > 4096 * " + size);
            // Invalid length
          } else if (size > 0 && length > 0) {
            byte version = raf.readByte();
            byte[] data = new byte[length - 1];
            raf.read(data);
            ByteArrayInputStream bais = new ByteArrayInputStream(data);
            // Try to load it all...
            DataInputStream stream;
            if (version == 1) {
              stream = new DataInputStream(new GZIPInputStream(bais));
            } else if (version == 2) {
              stream = new DataInputStream(new InflaterInputStream(bais));
            } else {
              stream = null;
              // Unknown version
              MyWorlds.log(
                  Level.WARNING,
                  "Unknown region version: " + version + " (we probably need an update here!)");
            }
            if (stream != null) {
              // Validate the stream and close
              try {
                NBTBase base = NBTTagCompound.b((DataInput) stream);
                if (base == null) {
                  editcount++;
                  locations[i] = 0;
                  MyWorlds.log(Level.WARNING, "Invalid tag compount at chunk " + i);
                } else if (!(base instanceof NBTTagCompound)) {
                  editcount++;
                  locations[i] = 0;
                  MyWorlds.log(Level.WARNING, "Invalid tag compount at chunk " + i);
                }
              } catch (Exception ex) {
                // Invalid.
                editcount++;
                locations[i] = 0;
                MyWorlds.log(Level.WARNING, "Stream  " + i);
                ex.printStackTrace();
              }
              stream.close();
            }
          }
        } catch (Exception ex) {
          editcount++;
          locations[i] = 0;
          ex.printStackTrace();
        }
      }
      if (editcount > 0) {
        if (backupfolder.mkdirs() && copy(chunkfile, backupfile)) {
          // Write out the new locations
          raf.seek(0);
          for (int location : locations) {
            raf.writeInt(location);
          }
        } else {
          MyWorlds.log(Level.WARNING, "Failed to make a copy of the file, no changes are made.");
          return -2;
        }
      }
      // Done.
      raf.close();
      return editcount;
    } catch (FileNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    try {
      if (raf != null) raf.close();
    } catch (Exception ex) {
    }

    try {
      chunkfile.delete();
      return -1;
    } catch (Exception ex) {
      return -3;
    }
  }
Beispiel #4
0
 public static World createWorld(String worldname, long seed) {
   String gen = getGeneratorPlugin(worldname);
   if (gen == null) {
     MyWorlds.log(Level.INFO, "Loading or creating world: '" + worldname + "' using seed " + seed);
   } else {
     MyWorlds.log(
         Level.INFO,
         "Loading or creating world: '"
             + worldname
             + "' using seed "
             + seed
             + " and chunk generator: '"
             + gen
             + "'");
   }
   final int retrycount = 3;
   World w = null;
   int i = 0;
   ChunkGenerator cgen = null;
   try {
     if (gen != null) {
       cgen = getGenerator(worldname, gen);
     }
   } catch (Exception ex) {
   }
   if (gen != null && cgen == null) {
     MyWorlds.log(
         Level.SEVERE,
         "World '"
             + worldname
             + "' could not be loaded because the chunk generator '"
             + gen
             + "' was not found!");
     return null;
   }
   WorldConfig wc = WorldConfig.get(worldname);
   wc.chunkGeneratorName = gen;
   for (i = 0; i < retrycount + 1; i++) {
     try {
       WorldCreator c = new WorldCreator(worldname);
       c.environment(wc.environment);
       c.seed(seed);
       c.generator(cgen);
       w = c.createWorld();
     } catch (Exception ex) {
       MyWorlds.log(Level.WARNING, "World load issue: " + ex.getMessage());
     }
     if (w != null) break;
   }
   if (w != null) {
     wc.updatePVP(w);
     // Data file is made?
     if (!worldExists(worldname)) {
       w.save();
     }
   }
   if (w == null) {
     MyWorlds.log(Level.WARNING, "Operation failed after " + i + " retries!");
   } else if (i == 1) {
     MyWorlds.log(Level.INFO, "Operation succeeded after 1 retry!");
   } else if (i > 0) {
     MyWorlds.log(Level.INFO, "Operation succeeded after " + i + " retries!");
   }
   return w;
 }