From f051ce2392bc0bfae52945e8f53fe38f2d095637 Mon Sep 17 00:00:00 2001 From: Kevin Chabowski Date: Sat, 21 Sep 2013 00:48:59 +0200 Subject: Deleting chunks implemented. --- README.markdown | 1 - mcmap/chunk.go | 5 +++++ mcmap/examples/delchunk/.gitignore | 1 + mcmap/examples/delchunk/main.go | 41 ++++++++++++++++++++++++++++++++++++++ mcmap/region.go | 27 +++++++++++++++++-------- 5 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 mcmap/examples/delchunk/.gitignore create mode 100644 mcmap/examples/delchunk/main.go diff --git a/README.markdown b/README.markdown index 3a06e1f..3e493b7 100644 --- a/README.markdown +++ b/README.markdown @@ -20,7 +20,6 @@ Although I tested the library with some maps, I can't guarantee that everything ## Wishlist / TODO -* Removing chunks. * Recalculating light data. * Reading and modifying level.dat and other files (currently only the region files are used). * Test compatibility with older versions of Minecraft. diff --git a/mcmap/chunk.go b/mcmap/chunk.go index 9196776..dfac5a7 100644 --- a/mcmap/chunk.go +++ b/mcmap/chunk.go @@ -54,6 +54,8 @@ type Chunk struct { blocks []Block // Ordered YZX biomes []Biome // Ordered ZX + deleted bool + reg *Region } @@ -132,6 +134,9 @@ func (c *Chunk) SetBiome(x, z int, bio Biome) { c.biomes[z*ChunkSizeXZ+x] = bio // If the chunk was modified, call MarkModified BEFORE. func (c *Chunk) MarkUnused() error { return c.reg.unloadChunk(int(c.x), int(c.z)) } +// MarkDeleted marks this chunk as deleted. After marking it as unused, it will be deleted and can no longer be used. +func (c *Chunk) MarkDeleted() { c.deleted = true } + // RecalcHeightMap recalculates the internal height map. // // You should use this function before marking the chunk as unused, if you modified the chunk diff --git a/mcmap/examples/delchunk/.gitignore b/mcmap/examples/delchunk/.gitignore new file mode 100644 index 0000000..732afb9 --- /dev/null +++ b/mcmap/examples/delchunk/.gitignore @@ -0,0 +1 @@ +delchunk diff --git a/mcmap/examples/delchunk/main.go b/mcmap/examples/delchunk/main.go new file mode 100644 index 0000000..c8996a5 --- /dev/null +++ b/mcmap/examples/delchunk/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "flag" + "fmt" + "github.com/kch42/gomcmap/mcmap" + "os" +) + +func main() { + path := flag.String("path", "", "Path to region directory") + flag.Parse() + + if *path == "" { + flag.Usage() + os.Exit(1) + } + + region, err := mcmap.OpenRegion(*path, false) + if err != nil { + fmt.Fprintf(os.Stderr, "Could not open region: %s\n", err) + os.Exit(1) + } + + chunk, err := region.Chunk(200, 200) + if err != nil { + fmt.Fprintf(os.Stderr, "Error getting chunk 200,200: %s\n", err) + os.Exit(1) + } + + chunk.MarkDeleted() + if err := chunk.MarkUnused(); err != nil { + fmt.Fprintf(os.Stderr, "Could not mark chunk as unused: %s\n", err) + os.Exit(1) + } + + if err := region.Save(); err != nil { + fmt.Fprintf(os.Stderr, "Could not save region: %s\n", err) + os.Exit(1) + } +} diff --git a/mcmap/region.go b/mcmap/region.go index 34b3334..93c8693 100644 --- a/mcmap/region.go +++ b/mcmap/region.go @@ -157,15 +157,23 @@ func (reg *Region) cleanSuperchunks(forceSave bool) error { if !(reg.autosave || forceSave) { continue } + fn := fmt.Sprintf("%s%cr.%d.%d.mca", reg.path, os.PathSeparator, scPos.X, scPos.Z) - f, err := os.Create(fn) - if err != nil { - return err - } - defer f.Close() - if err := writeRegionFile(f, sc.preChunks); err != nil { - return err + if len(sc.preChunks) == 0 { + if err := os.Remove(fn); err != nil { + return err + } + } else { + f, err := os.Create(fn) + if err != nil { + return err + } + defer f.Close() + + if err := writeRegionFile(f, sc.preChunks); err != nil { + return err + } } } @@ -239,7 +247,10 @@ func (reg *Region) unloadChunk(x, z int) error { return nil } - if chunk.modified { + if chunk.deleted { + delete(sc.preChunks, cPos) + sc.modified = true + } else if chunk.modified { pc, err := chunk.toPreChunk() if err != nil { return err -- cgit v1.2.3-70-g09d2