summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--leveldat.go41
-rw-r--r--listmaps.go5
-rw-r--r--main.go31
-rw-r--r--mapwidget.go6
4 files changed, 77 insertions, 6 deletions
diff --git a/leveldat.go b/leveldat.go
new file mode 100644
index 0000000..51344a8
--- /dev/null
+++ b/leveldat.go
@@ -0,0 +1,41 @@
+package main
+
+import (
+ "errors"
+ "fmt"
+ "github.com/kch42/gonbt/nbt"
+ "io"
+)
+
+func invalidLevelDat(err error) error {
+ return fmt.Errorf("Invalid level.dat: %s", err)
+}
+
+func getMapCenter(leveldat io.Reader) (int, int, error) {
+ lvl, _, err := nbt.ReadGzipdNamedTag(leveldat)
+ if err != nil {
+ return 0, 0, err
+ }
+
+ if lvl.Type != nbt.TAG_Compound {
+ return 0, 0, invalidLevelDat(errors.New("Root tag has wrong type"))
+ }
+ root := lvl.Payload.(nbt.TagCompound)
+
+ data, err := root.GetCompound("Data")
+ if err != nil {
+ return 0, 0, invalidLevelDat(err)
+ }
+
+ x, err := data.GetInt("SpawnX")
+ if err != nil {
+ return 0, 0, invalidLevelDat(err)
+ }
+
+ z, err := data.GetInt("SpawnZ")
+ if err != nil {
+ return 0, 0, invalidLevelDat(err)
+ }
+
+ return int(x), int(z), nil
+}
diff --git a/listmaps.go b/listmaps.go
index ad8a0cc..8a1c088 100644
--- a/listmaps.go
+++ b/listmaps.go
@@ -42,12 +42,13 @@ func allMaps() map[string]string {
}
p := path.Join(savesDir, info.Name())
- fi, err := os.Stat(path.Join(p, "level.dat"))
+ leveldat := path.Join(p, "level.dat")
+ fi, err := os.Stat(leveldat)
if (err != nil) || (!fi.Mode().IsRegular()) {
continue
}
- maps[info.Name()] = path.Join(p, "region")
+ maps[info.Name()] = leveldat
}
return maps
diff --git a/main.go b/main.go
index 50a975d..37f1a1e 100644
--- a/main.go
+++ b/main.go
@@ -7,6 +7,7 @@ import (
"github.com/mattn/go-gtk/glib"
"github.com/mattn/go-gtk/gtk"
"os"
+ "path"
)
type GUI struct {
@@ -31,23 +32,45 @@ type GUI struct {
}
func (g *GUI) openWorldDlg() {
- dlg := gtk.NewFileChooserDialog("Open World (region directory)", g.window, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER, "Open Region dir", gtk.RESPONSE_OK, "Cancel", gtk.RESPONSE_CANCEL)
+ dlg := gtk.NewFileChooserDialog("Open World (level.dat)", g.window, gtk.FILE_CHOOSER_ACTION_OPEN, "Open", gtk.RESPONSE_OK, "Cancel", gtk.RESPONSE_CANCEL)
+ filter := gtk.NewFileFilter()
+ filter.AddPattern("level.dat")
+ filter.SetName("level.dat")
+ dlg.AddFilter(filter)
if dlg.Run() == gtk.RESPONSE_OK {
g.openWorld(dlg.GetFilename())
}
dlg.Destroy()
}
-func (g *GUI) openWorld(path string) {
- region, err := mcmap.OpenRegion(path, false)
+func readWorld(p string) (*mcmap.Region, int, int, error) {
+ f, err := os.Open(p)
if err != nil {
- dlg := gtk.NewMessageDialog(g.window, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, "Could not load world %s:\n%s", path, err.Error())
+ return nil, 0, 0, err
+ }
+ defer f.Close()
+
+ x, z, err := getMapCenter(f)
+ if err != nil {
+ return nil, 0, 0, err
+ }
+
+ dir, _ := path.Split(p)
+ region, err := mcmap.OpenRegion(path.Join(dir, "region"), false)
+ return region, x, z, err
+}
+
+func (g *GUI) openWorld(p string) {
+ region, centerX, centerZ, err := readWorld(p)
+ if err != nil {
+ dlg := gtk.NewMessageDialog(g.window, gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, "Could not load world %s:\n%s", p, err.Error())
dlg.Run()
dlg.Destroy()
}
g.menuitemSave.SetSensitive(true)
+ g.mapw.SetCenter(centerX, centerZ)
g.mapw.SetRegion(region)
}
diff --git a/mapwidget.go b/mapwidget.go
index e04b5eb..8fc2b71 100644
--- a/mapwidget.go
+++ b/mapwidget.go
@@ -63,6 +63,12 @@ func (mw *MapWidget) SetTool(t Tool) { mw.regWrap.SetTool(t) }
func (mw *MapWidget) Save() { mw.regWrap.Save() }
+func (mw *MapWidget) SetCenter(x, z int) {
+ mw.offX = x*zoom - mw.w/2
+ mw.offZ = z*zoom - mw.h/2
+ mw.updateChunkBounds()
+}
+
func (mw *MapWidget) updateChunkBounds() {
startX := int(math.Floor(float64(mw.offX) / tileSize))
startZ := int(math.Floor(float64(mw.offZ) / tileSize))