Skip to content

Commit

Permalink
Merge pull request DonoA#3 from Faxmachinen/1.14.4
Browse files Browse the repository at this point in the history
Make it work on 1.14.4 with mods
  • Loading branch information
DonoA authored Jun 2, 2020
2 parents 883906f + b2d71b5 commit 58ad282
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 28 deletions.
6 changes: 6 additions & 0 deletions pyanvil/biomes.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ class Biome:
modified_wooded_badlands_plateau = 'modified_wooded_badlands_plateau'
modified_badlands_plateau = 'modified_badlands_plateau'

@staticmethod
def from_index(i):
if i < len(Biome.biome_list):
return Biome.biome_list[i]
return i # Otherwise it's a mod biome with unknown name, so just return the index.

biome_list = [
'ocean',
'plains',
Expand Down
66 changes: 38 additions & 28 deletions pyanvil/world.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import sys, math, gzip, zlib, time, os
from pathlib import Path
import pyanvil.nbt as nbt
import pyanvil.stream as stream
from pyanvil.biomes import Biome
Expand Down Expand Up @@ -108,13 +109,12 @@ def _serialize_blockstates(self, state_mapping):
return serial_states

class Chunk:

def __init__(self, xpos, zpos, sections, raw_nbt, orig_size):
self.xpos = xpos
self.zpos = zpos
self.sections = sections
self.raw_nbt = raw_nbt
self.biomes = [Biome.biome_list[i] for i in self.raw_nbt.get('Level').get('Biomes').get()]
self.biomes = [Biome.from_index(i) for i in self.raw_nbt.get('Level').get('Biomes').get()]
self.orig_size = orig_size

def get_block(self, block_pos):
Expand Down Expand Up @@ -149,24 +149,34 @@ def find_like(self, string):
def unpack(raw_nbt):
sections = {}
for section in raw_nbt.get('Level').get('Sections').children:
flatstates = [c.get() for c in section.get('BlockStates').children]
pack_size = int((len(flatstates) * 64) / (16**3))
states = [
Chunk._read_width_from_loc(flatstates, pack_size, i) for i in range(16**3)
]
palette = [
BlockState(
state.get('Name').get(),
state.get('Properties').to_dict() if state.has('Properties') else {}
) for state in section.get('Palette').children
]
block_lights = Chunk._divide_nibbles(section.get('BlockLight').get())
sky_lights = Chunk._divide_nibbles(section.get('SkyLight').get())
blocks = [
Block(palette[states[i]], block_lights[i], sky_lights[i]) for i in range(len(states))
]
if section.has('BlockStates'):
flatstates = [c.get() for c in section.get('BlockStates').children]
pack_size = int((len(flatstates) * 64) / (16**3))
states = [
Chunk._read_width_from_loc(flatstates, pack_size, i) for i in range(16**3)
]
else:
# Sections which contain only air have no states.
states = []
if section.has('Palette'):
palette = [
BlockState(
state.get('Name').get(),
state.get('Properties').to_dict() if state.has('Properties') else {}
) for state in section.get('Palette').children
]
else:
# Nor any palette entries.
palette = None
block_lights = Chunk._divide_nibbles(section.get('BlockLight').get()) if section.has('BlockLight') else None
sky_lights = Chunk._divide_nibbles(section.get('SkyLight').get()) if section.has('SkyLight') else None
blocks = []
for i in range(len(states)):
state = palette[states[i]]
block_light = block_lights[i] if block_lights else 0
sky_light = sky_lights[i] if sky_lights else 0
blocks.append(Block(state, block_light, sky_light))
sections[section.get('Y').get()] = ChunkSection(blocks, section, section.get('Y').get())

return sections

def _divide_nibbles(arry):
Expand Down Expand Up @@ -221,14 +231,14 @@ def __str__(self):
return f'Chunk({str(self.xpos)},{str(self.zpos)})'

class World:
def __init__(self, file_name, save_location='', debug=False, read=True, write=True):
def __init__(self, world_folder, save_location=None, debug=False, read=True, write=True):
self.debug = debug
self.file_name = file_name
self.save_location = save_location
if not os.path.exists(save_location):
raise FileNotFoundError('No such folder ' + save_location)
if not os.path.exists(save_location + '/' + file_name):
raise FileNotFoundError('No such save ' + save_location)
if save_location is not None:
self.world_folder = Path(save_location) / world_folder
else:
self.world_folder = Path(world_folder)
if not self.world_folder.is_dir():
raise FileNotFoundError(f'No such folder \"{self.world_folder}\"')
self.chunks = {}

def __enter__(self):
Expand All @@ -251,7 +261,7 @@ def close(self):
chunks_by_region[region].append(chunk)

for region_name, chunks in chunks_by_region.items():
with open(self.save_location + '/' + self.file_name + '/region/' + region_name, mode='r+b') as region:
with open(self.world_folder / 'region' / region_name, mode='r+b') as region:
region.seek(0)
locations = [[
int.from_bytes(region.read(3), byteorder='big', signed=False) * 4096,
Expand Down Expand Up @@ -333,7 +343,7 @@ def get_canvas(self):
return Canvas(self)

def _load_chunk(self, chunk_pos):
with open(self.save_location + '/' + self.file_name + '/region/' + self._get_region_file(chunk_pos), mode='rb') as region:
with open(self.world_folder / 'region' / self._get_region_file(chunk_pos), mode='rb') as region:
locations = [[
int.from_bytes(region.read(3), byteorder='big', signed=False) * 4096,
int.from_bytes(region.read(1), byteorder='big', signed=False) * 4096
Expand Down

0 comments on commit 58ad282

Please sign in to comment.