forked from mirrors/NBTExplorer
Added purge command to delete chunks
This commit is contained in:
parent
45839d2416
commit
77f0764013
7 changed files with 202 additions and 2 deletions
|
@ -99,6 +99,28 @@ namespace NBToolkit
|
|||
{
|
||||
return _regionMan;
|
||||
}
|
||||
|
||||
public bool DeleteChunk (int cx, int cz)
|
||||
{
|
||||
Region r = GetRegion(cx, cz);
|
||||
if (r == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!r.DeleteChunk(cx & REGION_XMASK, cz & REGION_ZMASK)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ChunkKey k = new ChunkKey(cx, cz);
|
||||
_cache.Remove(k);
|
||||
_dirty.Remove(k);
|
||||
|
||||
if (r.ChunkCount() == 0) {
|
||||
_regionMan.DeleteRegion(r.X, r.Z);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class MissingChunkException : Exception
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
<Compile Include="NDesk\Options.cs" />
|
||||
<Compile Include="NibbleArray.cs" />
|
||||
<Compile Include="Oregen.cs" />
|
||||
<Compile Include="Purge.cs" />
|
||||
<Compile Include="Region.cs" />
|
||||
<Compile Include="RegionEnumerator.cs" />
|
||||
<Compile Include="RegionKey.cs" />
|
||||
|
|
|
@ -28,6 +28,12 @@ namespace NBToolkit
|
|||
options.SetDefaults();
|
||||
filter.Run();
|
||||
}
|
||||
else if (args[0] == "purge") {
|
||||
PurgeOptions options = new PurgeOptions(args);
|
||||
Purge filter = new Purge(options);
|
||||
options.SetDefaults();
|
||||
filter.Run();
|
||||
}
|
||||
else if (args[0] == "help") {
|
||||
if (args.Length < 2) {
|
||||
args = new string[2] { "help", "help" };
|
||||
|
@ -52,6 +58,13 @@ namespace NBToolkit
|
|||
Console.WriteLine();
|
||||
options.PrintUsage();
|
||||
}
|
||||
else if (args[1] == "purge") {
|
||||
options = new PurgeOptions(args);
|
||||
|
||||
WriteBlock("Deletes all chunks matching the chunk filtering options. If no options are specified, all world chunks will be deleted. Region files that have all of their chunks purged will also be deleted from the world directory.");
|
||||
Console.WriteLine();
|
||||
options.PrintUsage();
|
||||
}
|
||||
else {
|
||||
WriteBlock("Prints help and usage information for another command. Available commands are 'oregen' and 'replace'.");
|
||||
Console.WriteLine();
|
||||
|
|
85
NBToolkit/NBToolkit/Purge.cs
Normal file
85
NBToolkit/NBToolkit/Purge.cs
Normal file
|
@ -0,0 +1,85 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NDesk.Options;
|
||||
using NBT;
|
||||
|
||||
namespace NBToolkit
|
||||
{
|
||||
public class PurgeOptions : TKOptions, IChunkFilterable
|
||||
{
|
||||
private OptionSet _filterOpt = null;
|
||||
private ChunkFilter _chunkFilter = null;
|
||||
|
||||
public PurgeOptions ()
|
||||
: base()
|
||||
{
|
||||
_filterOpt = new OptionSet();
|
||||
_chunkFilter = new ChunkFilter();
|
||||
}
|
||||
|
||||
public PurgeOptions (string[] args)
|
||||
: this()
|
||||
{
|
||||
Parse(args);
|
||||
}
|
||||
|
||||
public override void Parse (string[] args)
|
||||
{
|
||||
base.Parse(args);
|
||||
|
||||
_filterOpt.Parse(args);
|
||||
_chunkFilter.Parse(args);
|
||||
}
|
||||
|
||||
public override void PrintUsage ()
|
||||
{
|
||||
Console.WriteLine("Usage: nbtoolkit purge [options]");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Options for command 'purge':");
|
||||
|
||||
_filterOpt.WriteOptionDescriptions(Console.Out);
|
||||
|
||||
Console.WriteLine();
|
||||
_chunkFilter.PrintUsage();
|
||||
|
||||
Console.WriteLine();
|
||||
base.PrintUsage();
|
||||
}
|
||||
|
||||
public override void SetDefaults ()
|
||||
{
|
||||
base.SetDefaults();
|
||||
}
|
||||
|
||||
public IChunkFilter GetChunkFilter ()
|
||||
{
|
||||
return _chunkFilter;
|
||||
}
|
||||
}
|
||||
|
||||
class Purge : TKFilter
|
||||
{
|
||||
private PurgeOptions opt;
|
||||
|
||||
private static Random rand = new Random();
|
||||
|
||||
public Purge (PurgeOptions o)
|
||||
{
|
||||
opt = o;
|
||||
}
|
||||
|
||||
public override void Run ()
|
||||
{
|
||||
World world = new World(opt.OPT_WORLD);
|
||||
|
||||
int affectedChunks = 0;
|
||||
foreach (Chunk chunk in new FilteredChunkList(world.GetChunkManager(), opt.GetChunkFilter())) {
|
||||
affectedChunks++;
|
||||
world.GetChunkManager().DeleteChunk(chunk.X, chunk.Z);
|
||||
}
|
||||
|
||||
Console.WriteLine("Purged Chunks: " + affectedChunks);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,10 +7,11 @@ using NBT;
|
|||
|
||||
namespace NBToolkit
|
||||
{
|
||||
public class Region
|
||||
public class Region : IDisposable
|
||||
{
|
||||
protected int _rx;
|
||||
protected int _rz;
|
||||
protected bool _disposed = false;
|
||||
|
||||
protected RegionManager _regionMan;
|
||||
|
||||
|
@ -58,6 +59,34 @@ namespace NBToolkit
|
|||
}
|
||||
}
|
||||
|
||||
~Region ()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose(true);
|
||||
System.GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
if (!_disposed) {
|
||||
if (disposing) {
|
||||
// Cleanup managed resources
|
||||
RegionFile rf = _regionFile.Target as RegionFile;
|
||||
if (rf != null) {
|
||||
rf.Dispose();
|
||||
rf = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup unmanaged resources
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
public string GetFileName ()
|
||||
{
|
||||
return "r." + _rx + "." + _rz + ".mcr";
|
||||
|
@ -151,5 +180,16 @@ namespace NBToolkit
|
|||
|
||||
return count;
|
||||
}
|
||||
|
||||
public bool DeleteChunk (int lcx, int lcz)
|
||||
{
|
||||
RegionFile rf = GetRegionFile();
|
||||
if (!rf.HasChunk(lcx, lcz)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
rf.DeleteChunk(lcx, lcz);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -371,8 +371,24 @@ namespace NBToolkit
|
|||
file.Write(data, 0, length); // chunk data
|
||||
}
|
||||
|
||||
public void DeleteChunk (int x, int z)
|
||||
{
|
||||
int offset = GetOffset(x, z);
|
||||
int sectorNumber = offset >> 8;
|
||||
int sectorsAllocated = offset & 0xFF;
|
||||
|
||||
file.Seek(sectorNumber * SECTOR_BYTES, SeekOrigin.Begin);
|
||||
for (int i = 0; i < sectorsAllocated; i++) {
|
||||
file.Write(emptySector, 0, SECTOR_BYTES);
|
||||
}
|
||||
|
||||
SetOffset(x, z, 0);
|
||||
SetTimestamp(x, z, 0);
|
||||
}
|
||||
|
||||
/* is this an invalid chunk coordinate? */
|
||||
private bool OutOfBounds(int x, int z) {
|
||||
private bool OutOfBounds (int x, int z)
|
||||
{
|
||||
return x < 0 || x >= 32 || z < 0 || z >= 32;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,5 +49,28 @@ namespace NBToolkit
|
|||
{
|
||||
return _regionPath;
|
||||
}
|
||||
|
||||
public bool DeleteRegion (int rx, int rz)
|
||||
{
|
||||
Region r = GetRegion(rx, rz);
|
||||
if (r == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RegionKey k = new RegionKey(rx, rz);
|
||||
_cache.Remove(k);
|
||||
|
||||
r.Dispose();
|
||||
|
||||
try {
|
||||
File.Delete(r.GetFilePath());
|
||||
}
|
||||
catch (Exception e) {
|
||||
Console.WriteLine("NOTICE: " + e.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue