//Returns the chunk at the coordinates, also returns if the chunk existed //before this func (mw *MsgpackSystem) Chunk(x, z int) (*Chunk, bool) { reg := mw.region(x>>5, z>>5) reg.RLock() rx := x & 0x1F rz := z & 0x1F idx := rx | (rz << 5) offset := reg.Offsets[idx] count := reg.SectionCounts[idx] reg.RUnlock() if offset == 0 { return &Chunk{X: x, Z: z}, false } section := io.NewSectionReader(reg.file, int64(offset)*regionSectionSize, int64(count)*regionSectionSize) gz, err := gzip.NewReader(section) if err != nil { panic(err) } chunk := &Chunk{} err = msgpack.NewDecoder(gz).Decode(chunk) gz.Close() if err != nil { panic(err) } return chunk, true }
//Reads key into the passed struct pointer func (mw *MsgpackSystem) Read(key string, v interface{}) error { f, err := os.Open(filepath.Join(mw.path, "data", key+".nether")) if err != nil { return err } defer f.Close() return msgpack.NewDecoder(f).Decode(v) }
func (mw *MsgpackSystem) readLevel(level string) { f, err := os.Open(level) if err != nil { panic(err) } defer f.Close() err = msgpack.NewDecoder(f).Decode(mw) if err != nil { panic(err) } }
func (mw *MsgpackSystem) region(x, z int) *region { key := (uint64(int32(x)) & 0xFFFFFFFF) | ((uint64(int32(z)) & 0xFFFFFFFF) << 32) mw.regionLock.RLock() reg, ok := mw.regions[key] mw.regionLock.RUnlock() if ok { return reg } mw.regionLock.Lock() reg, ok = mw.regions[key] if ok { mw.regionLock.Unlock() return reg } reg = ®ion{} file, err := os.OpenFile(filepath.Join(mw.path, "regions", fmt.Sprintf("%016X.region", key)), os.O_RDWR|os.O_CREATE, 0666) if err != nil { panic(err) } msgpack.NewDecoder(file).Decode(reg) reg.file = file reg.usedLocations = []bool{true, true, true} for i, off := range reg.Offsets { if off == 0 { continue } count := reg.SectionCounts[i] if len(reg.usedLocations) < off+count { temp := reg.usedLocations reg.usedLocations = make([]bool, off+count) copy(reg.usedLocations, temp) } for j := off; j < off+count; j++ { reg.usedLocations[j] = true } } reg.Save() mw.regions[key] = reg mw.regionLock.Unlock() return reg }
//Loads the world by name func GetWorld(name string, tryClose chan TryClose) *World { root := filepath.Join("./worlds/", name) f, err := os.Open(filepath.Join(root, "netherrack.meta")) if err != nil { return nil } defer f.Close() meta := netherrackMeta{} msgpack.NewDecoder(f).Decode(&meta) sys, ok := systems[meta.SystemName] if !ok { panic("Unknown world system") } system := sys() gen, ok := generators[meta.GeneratorName] if !ok { panic("Unknown world generator") } generator := gen() w := &World{ Name: name, system: system, generator: generator, tryClose: tryClose, } w.init() w.system.Init(filepath.Join("./worlds/", w.Name)) w.system.Read("levelData", &w.worldData) go w.run() return w }