change: Finished loading command and added some scripts for extracting world saves
This commit is contained in:
		
							
								
								
									
										21
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					SAVES := imperial-save
 | 
				
			||||||
 | 
					SAVES += skygrid-save
 | 
				
			||||||
 | 
					SAVES += witchcraft-save
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					all: $(SAVES)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					imperial-save:
 | 
				
			||||||
 | 
						mkdir imperial-save
 | 
				
			||||||
 | 
						./spatial-db load worldsave "saves/Imperialcity v14.1/region" --output "imperial-save"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					skygrid-save:
 | 
				
			||||||
 | 
						mkdir skygrid-save
 | 
				
			||||||
 | 
						./spatial-db load worldsave "saves/SkyGrid/region" --output "skygrid-save"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					witchcraft-save:
 | 
				
			||||||
 | 
						mkdir witchcraft-save
 | 
				
			||||||
 | 
						./spatial-db load worldsave "saves/Witchcraft/region" --output "witchcraft-save"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: clean
 | 
				
			||||||
 | 
					clean:
 | 
				
			||||||
 | 
						rm -r $(SAVES)
 | 
				
			||||||
@@ -1,71 +1,46 @@
 | 
				
			|||||||
package loading
 | 
					package loading
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"log"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"path/filepath"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"git.nicholasnovak.io/nnovak/spatial-db/world"
 | 
						"git.nicholasnovak.io/nnovak/spatial-db/world"
 | 
				
			||||||
	"github.com/Tnze/go-mc/save"
 | 
						"github.com/Tnze/go-mc/save"
 | 
				
			||||||
	"github.com/Tnze/go-mc/save/region"
 | 
						"github.com/Tnze/go-mc/save/region"
 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type SectorPos struct {
 | 
					// LoadRegionFile loads a single region file into an array of chunks
 | 
				
			||||||
	x, y int
 | 
					//
 | 
				
			||||||
}
 | 
					// A region is a 32x32 grid of chunks, although the final output can store less
 | 
				
			||||||
 | 
					func LoadRegionFile(fileName string) ([]world.ChunkData, error) {
 | 
				
			||||||
 | 
						regionFile, err := region.Open(fileName)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer regionFile.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var outputDir string
 | 
						// A region file is a 32x32 grid of chunks
 | 
				
			||||||
 | 
						chunks := []world.ChunkData{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
						for i := 0; i < 32; i++ {
 | 
				
			||||||
	LoadRegionFileCommand.Flags().StringVar(&outputDir, "output", ".", "The output directory for the files")
 | 
							for j := 0; j < 32; j++ {
 | 
				
			||||||
}
 | 
								if regionFile.ExistSector(i, j) {
 | 
				
			||||||
 | 
									sectorFile, err := regionFile.ReadSector(i, j)
 | 
				
			||||||
var LoadRegionFileCommand = &cobra.Command{
 | 
									if err != nil {
 | 
				
			||||||
	Use: "load",
 | 
										return nil, err
 | 
				
			||||||
	RunE: func(cmd *cobra.Command, args []string) error {
 | 
					 | 
				
			||||||
		regionFile, err := region.Open(args[0])
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		defer regionFile.Close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		validSectors := []SectorPos{}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for i := 0; i < 32; i++ {
 | 
					 | 
				
			||||||
			for j := 0; j < 32; j++ {
 | 
					 | 
				
			||||||
				if regionFile.ExistSector(i, j) {
 | 
					 | 
				
			||||||
					validSectors = append(validSectors, SectorPos{i, j})
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Read each chunk from disk
 | 
				
			||||||
 | 
									var chunk save.Chunk
 | 
				
			||||||
 | 
									if err := chunk.Load(sectorFile); err != nil {
 | 
				
			||||||
 | 
										return nil, err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Convert each chunk into the database's format
 | 
				
			||||||
 | 
									var chunkData world.ChunkData
 | 
				
			||||||
 | 
									chunkData.FromMCAChunk(chunk)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									chunks = append(chunks, chunkData)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for _, sectorPos := range validSectors {
 | 
						return chunks, nil
 | 
				
			||||||
			data, err := regionFile.ReadSector(sectorPos.x, sectorPos.y)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var chunk save.Chunk
 | 
					 | 
				
			||||||
			if err := chunk.Load(data); err != nil {
 | 
					 | 
				
			||||||
				return err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var chunkData world.ChunkData
 | 
					 | 
				
			||||||
			chunkData.FromMCAChunk(chunk)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			outfile, err := os.OpenFile(filepath.Join(outputDir, fmt.Sprintf("p.%d.%d.chunk", chunkData.Pos.X, chunkData.Pos.Z)), os.O_WRONLY|os.O_CREATE, 0644)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				log.Fatal(err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if err := json.NewEncoder(outfile).Encode(chunkData); err != nil {
 | 
					 | 
				
			||||||
				log.Fatal(err)
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			outfile.Close()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										80
									
								
								loading/load_save.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								loading/load_save.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					package loading
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log "github.com/sirupsen/logrus"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/spf13/cobra"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						saveOutputDir string
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						LoadSaveDirCommand.Flags().StringVar(&saveOutputDir, "output", ".", "Where to place the converted save files")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var LoadSaveDirCommand = &cobra.Command{
 | 
				
			||||||
 | 
						Use:   "worldsave <save-directory>",
 | 
				
			||||||
 | 
						Short: "Loads all the regions in the specified world's save directory",
 | 
				
			||||||
 | 
						Args:  cobra.ExactArgs(1),
 | 
				
			||||||
 | 
						RunE: func(cmd *cobra.Command, args []string) error {
 | 
				
			||||||
 | 
							// First, fetch a list of all the files that are in the specified directory
 | 
				
			||||||
 | 
							regionFiles, err := os.ReadDir(args[0])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							log.Infof("Loading save directory of %s", args[0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for regionIndex, regionFile := range regionFiles {
 | 
				
			||||||
 | 
								if regionFile.IsDir() {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if strings.HasSuffix(regionFile.Name(), ".mcr") {
 | 
				
			||||||
 | 
									log.Warnf("The file %s is in the MCRegion format, skipping", regionFile.Name())
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								log.Infof("Converting region file %s, [%d/%d]",
 | 
				
			||||||
 | 
									regionFile.Name(),
 | 
				
			||||||
 | 
									regionIndex,
 | 
				
			||||||
 | 
									len(regionFiles),
 | 
				
			||||||
 | 
								)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								filePath := filepath.Join(args[0], regionFile.Name())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Load each region file
 | 
				
			||||||
 | 
								chunks, err := LoadRegionFile(filePath)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Save each chunk to a separate file
 | 
				
			||||||
 | 
								for _, chunk := range chunks {
 | 
				
			||||||
 | 
									outfile, err := os.OpenFile(
 | 
				
			||||||
 | 
										filepath.Join(saveOutputDir, chunk.Pos.ToFileName()),
 | 
				
			||||||
 | 
										os.O_WRONLY|os.O_CREATE|os.O_APPEND,
 | 
				
			||||||
 | 
										0664,
 | 
				
			||||||
 | 
									)
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										return err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if err := json.NewEncoder(outfile).Encode(chunk); err != nil {
 | 
				
			||||||
 | 
										return err
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									outfile.Close()
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								main.go
									
									
									
									
									
								
							@@ -14,7 +14,15 @@ func main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	rootCmd.AddCommand(visualization.VisualizeCommand)
 | 
						rootCmd.AddCommand(visualization.VisualizeCommand)
 | 
				
			||||||
	rootCmd.AddCommand(connector.ProxyPortCommand)
 | 
						rootCmd.AddCommand(connector.ProxyPortCommand)
 | 
				
			||||||
	rootCmd.AddCommand(loading.LoadRegionFileCommand)
 | 
					
 | 
				
			||||||
 | 
						loadCmd := &cobra.Command{
 | 
				
			||||||
 | 
							Use:   "load",
 | 
				
			||||||
 | 
							Short: "Loads save files into the database's format",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						loadCmd.AddCommand(loading.LoadSaveDirCommand)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rootCmd.AddCommand(loadCmd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := rootCmd.Execute(); err != nil {
 | 
						if err := rootCmd.Execute(); err != nil {
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user