Skip to content

Instantly share code, notes, and snippets.

@KsaRedFx
Forked from Byteflux/uuidconvert.py
Last active August 29, 2015 13:59
Show Gist options
  • Save KsaRedFx/10952290 to your computer and use it in GitHub Desktop.
Save KsaRedFx/10952290 to your computer and use it in GitHub Desktop.
python uuidconvert.py <worldpath>
import sys
import os
import math
import urllib2
import json
import time
import shutil
import uuid
from nbt import nbt # pip install nbt
def convert(path):
if not os.path.isdir(path):
sys.stderr.write('Path is not directory or does not exist:' + path)
return False
max_payload_size = 50
retry_delay = 3
#profile_url = 'https://api.mojang.com/profiles/minecraft'
profile_url = 'http://api.goender.net/api/profiles/minecraft'
if "goender" in profile_url:
max_payload_size = 1000
player_data_path = os.path.join(path, 'players')
target_data_path = os.path.join(path, 'playerdata')
player_files = {}
for player_file in os.listdir(player_data_path):
if os.path.isfile(os.path.join(player_data_path, player_file)) and player_file.endswith('.dat'):
name = os.path.splitext(os.path.basename(player_file))[0].lower()
player_files[name] = os.path.join(player_data_path, player_file)
if not player_files:
sys.stderr.write('No player data found!\n')
return False
else:
try:
os.rename(player_data_path, os.path.join(path, 'players_backup'))
except:
sys.stderr.write('Could not rename player data folder!\n')
if not os.path.isdir(target_data_path):
os.mkdir(target_data_path)
payload = []
current = 0
for name in player_files.keys():
current = current + 1
payload.append(name)
if (float(current) % max_payload_size) != 0 and current != len(player_files):
continue
request = urllib2.Request(profile_url, json.dumps(payload), {'Content-Type': 'application/json'})
retry = False
retry_count = 0
while True:
try:
response = urllib2.urlopen(request)
if retry:
sys.stderr.write('Retry successful! Number of retries: ' + str(retry_count) + '\n')
retry = False
retry_count = 0
break
except Exception as e:
sys.stderr.write(str(e) + " (don't worry, we'll retry until it works!)\n")
retry = True
time.sleep(retry_delay)
retry_count = retry_count + 1
profiles = json.loads(response.read())
if isinstance(profiles, dict): # http://api.goender.net/api/profiles/minecraft
data = profiles
profiles = []
for name in data.keys():
profiles.append({'id': data[name], 'name': name})
if len(profiles) != len(payload):
payload_names = set([name.lower() for name in payload])
response_names = set([profile['name'].lower() for profile in profiles])
sys.stderr.write('Missing profiles from API response: ' + repr(list(payload_names - response_names)) + '\n')
payload = []
for profile in profiles:
name = profile['name'].lower()
if name not in player_files:
continue
src = player_files[name]
dst = os.path.join(target_data_path, str(uuid.UUID(profile['id'])) + '.dat')
try:
nbtfile = nbt.NBTFile(src, 'rb')
except Exception as e:
sys.stderr.write('Error reading NBT file: ' + src + ' (' + str(e) + ')\n')
continue
try:
bukkit = nbtfile['bukkit']
except KeyError:
bukkit = nbt.TAG_Compound()
bukkit.name = 'bukkit'
nbtfile.tags.append(bukkit)
try:
lastKnownName = bukkit['lastKnownName']
except KeyError:
lastKnownName = nbt.TAG_String(name='lastKnownName')
bukkit.tags.append(lastKnownName)
lastKnownName.value = profile['name']
nbtfile.write_file(dst)
return True
if __name__ == '__main__':
path = 'world'
if len(sys.argv) > 1:
path = sys.argv[1]
if convert(path):
print 'Player data has been successfully converted.'
@KsaRedFx
Copy link
Author

Taken from Sir ByteFlux

If like me your player data is not being converted this script may be of some use to you.

First step: Backup your data. If you have any previously created UUID-based player data files, they might be overwritten during conversion.

Next, install the dependency nbt module as root:

pip install nbt

Finally, run the conversion script:

python uuidconvert.py <worldpath>

Note: Replace with the file system path to your main world

The conversion script may take a long time to run and may also print some errors that most likely are harmless,

After the conversion has completed, you may want to rename the players folder inside your world just for good measure. Call it whatever you want, or delete it if you already have backups elsewhere.

This script was tested in Python 2.7. It might work in older versions, but it will most likely not work in Python 3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment