Skip to content

Instantly share code, notes, and snippets.

@winny-
Last active December 20, 2015 00:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save winny-/6043044 to your computer and use it in GitHub Desktop.
Save winny-/6043044 to your computer and use it in GitHub Desktop.
Because using a Bukkit plugin just to edit a NBT file is ridiculous! Tested on 1.5.x, see /setworldspawn on recent Minecraft releases.
#!/usr/bin/env python
#
# This file is placed in the public domain.
import struct
coordinate_name_map = {'x': 'SpawnX', 'X': 'SpawnX', 'SpawnX': 'SpawnX',
'y': 'SpawnY', 'Y': 'SpawnY', 'SpawnY': 'SpawnY',
'z': 'SpawnZ', 'Z': 'SpawnZ', 'SpawnZ': 'SpawnZ'}
def change_coordinate(nbt, coordinate, value):
name = coordinate_name_map[coordinate]
location = get_coordinate(nbt, name)[0]
assert location
first_half = nbt[:location]
second_half = nbt[location+4:]
return first_half + struct.pack('>i', value) + second_half
def get_coordinate(nbt, coordinate):
name = coordinate_name_map[coordinate]
found = nbt.find(name)
assert found > -1
location = found + len(name)
bytes_ = nbt[location:location+4]
value = struct.unpack('>i', bytes_)[0]
return (location, value)
def get_all_coordinates(nbt):
return {
'x': get_coordinate(nbt, 'x')[1],
'y': get_coordinate(nbt, 'y')[1],
'z': get_coordinate(nbt, 'z')[1]
}
def change_all_coordinates(nbt, x, y ,z):
nbt = change_coordinate(nbt, 'x', x)
nbt = change_coordinate(nbt, 'y', y)
nbt = change_coordinate(nbt, 'z', z)
return nbt
def file_is_gzipped(file_):
try:
magic = file_.read(2)
except AttributeError:
with open(file_, 'rb') as f:
magic = f.read(2)
return magic == '\x1f\x8b'
if __name__ == '__main__':
import gzip
import sys
if len(sys.argv) != 5:
sys.stderr.write('Usage: {0} level.dat X Y Z\n'.format(sys.argv[0]))
exit(1)
level_dat = sys.argv[1]
x = int(sys.argv[2])
y = int(sys.argv[3])
z = int(sys.argv[4])
if file_is_gzipped(level_dat):
o = gzip.open
else:
o = open
with o(level_dat, 'rb') as f:
nbt = f.read()
nbt = change_all_coordinates(nbt, x, y, z)
with o(level_dat, 'wb') as f:
f.write(nbt)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment