Last active
December 20, 2015 00:39
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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