436 lines
14 KiB
Python
436 lines
14 KiB
Python
"""Copyright (c) 2010-2012 David Rio Vierra
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
purpose with or without fee is hereby granted, provided that the above
|
|
copyright notice and this permission notice appear in all copies.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE."""
|
|
from pymclevel.minecraft_server import ServerJarStorage, MCServerChunkGenerator
|
|
|
|
"""
|
|
mcplatform.py
|
|
|
|
Platform-specific functions, folder paths, and the whole fixed/portable nonsense.
|
|
"""
|
|
|
|
import directories
|
|
import os
|
|
from os.path import dirname, exists, join
|
|
import sys
|
|
|
|
enc = sys.getfilesystemencoding()
|
|
|
|
if sys.platform == "win32":
|
|
import platform
|
|
if platform.architecture()[0] == "32bit":
|
|
plat = "win32"
|
|
if platform.architecture()[0] == "64bit":
|
|
plat = "win-amd64"
|
|
sys.path.append(join(directories.dataDir, "pymclevel", "build", "lib." + plat + "-2.6").encode(enc))
|
|
|
|
os.environ["YAML_ROOT"] = join(directories.dataDir, "pymclevel").encode(enc)
|
|
|
|
from pygame import display
|
|
|
|
from albow import request_new_filename, request_old_filename
|
|
from pymclevel import saveFileDir, minecraftDir
|
|
from pymclevel import items
|
|
|
|
import shutil
|
|
|
|
texturePacksDir = os.path.join(minecraftDir, "texturepacks")
|
|
|
|
|
|
def getTexturePacks():
|
|
try:
|
|
return os.listdir(texturePacksDir)
|
|
except:
|
|
return []
|
|
|
|
# for k,v in os.environ.iteritems():
|
|
# try:
|
|
# os.environ[k] = v.decode(sys.getfilesystemencoding())
|
|
# except:
|
|
# continue
|
|
if sys.platform == "win32":
|
|
try:
|
|
from win32 import win32gui
|
|
from win32 import win32api
|
|
|
|
from win32.lib import win32con
|
|
except ImportError:
|
|
import win32gui
|
|
import win32api
|
|
|
|
import win32con
|
|
|
|
try:
|
|
import win32com.client
|
|
from win32com.shell import shell, shellcon # @UnresolvedImport
|
|
except:
|
|
pass
|
|
|
|
AppKit = None
|
|
|
|
if sys.platform.startswith('darwin') or sys.platform.startswith('mac'):
|
|
cmd_name = "Cmd"
|
|
option_name = "Opt"
|
|
else:
|
|
cmd_name = "Ctrl"
|
|
option_name = "Alt"
|
|
|
|
if sys.platform == "darwin":
|
|
try:
|
|
import AppKit
|
|
except ImportError:
|
|
pass
|
|
|
|
|
|
def Lion():
|
|
try:
|
|
import distutils.version
|
|
import platform
|
|
lionver = distutils.version.StrictVersion('10.7')
|
|
curver = distutils.version.StrictVersion(platform.release())
|
|
return curver >= lionver
|
|
except Exception, e:
|
|
print "Error getting system version: ", repr(e)
|
|
return False
|
|
|
|
lastSchematicsDir = None
|
|
lastSaveDir = None
|
|
|
|
|
|
def askOpenFile(title='Select a Minecraft level....', schematics=False):
|
|
global lastSchematicsDir, lastSaveDir
|
|
|
|
initialDir = lastSaveDir or saveFileDir
|
|
if schematics:
|
|
initialDir = lastSchematicsDir or schematicsDir
|
|
|
|
def _askOpen():
|
|
suffixes = ["mclevel", "dat", "mine", "mine.gz"]
|
|
if schematics:
|
|
suffixes.append("schematic")
|
|
suffixes.append("schematic.gz")
|
|
suffixes.append("zip")
|
|
|
|
suffixes.append("inv")
|
|
|
|
if sys.platform == "win32":
|
|
return askOpenFileWin32(title, schematics, initialDir)
|
|
elif sys.platform == "darwin" and AppKit is not None and not Lion():
|
|
|
|
op = AppKit.NSOpenPanel.openPanel()
|
|
op.setPrompt_(title)
|
|
op.setAllowedFileTypes_(suffixes)
|
|
op.setAllowsOtherFileTypes_(True)
|
|
|
|
op.setDirectory_(initialDir)
|
|
if op.runModal() == 0:
|
|
return # pressed cancel
|
|
|
|
AppKit.NSApp.mainWindow().makeKeyWindow()
|
|
|
|
return op.filename()
|
|
|
|
else: # linux
|
|
|
|
return request_old_filename(suffixes=suffixes, directory=initialDir)
|
|
|
|
filename = _askOpen()
|
|
if filename:
|
|
if schematics:
|
|
lastSchematicsDir = dirname(filename)
|
|
else:
|
|
lastSaveDir = dirname(filename)
|
|
|
|
return filename
|
|
|
|
|
|
def askOpenFileWin32(title, schematics, initialDir):
|
|
try:
|
|
# if schematics:
|
|
f = ('Levels and Schematics\0*.mclevel;*.dat;*.mine;*.mine.gz;*.schematic;*.zip;*.schematic.gz;*.inv\0' +
|
|
'*.*\0*.*\0\0')
|
|
# else:
|
|
# f = ('Levels (*.mclevel, *.dat;*.mine;*.mine.gz;)\0' +
|
|
# '*.mclevel;*.dat;*.mine;*.mine.gz;*.zip;*.lvl\0' +
|
|
# '*.*\0*.*\0\0')
|
|
|
|
(filename, customfilter, flags) = win32gui.GetOpenFileNameW(
|
|
hwndOwner=display.get_wm_info()['window'],
|
|
InitialDir=initialDir,
|
|
Flags=(win32con.OFN_EXPLORER
|
|
| win32con.OFN_NOCHANGEDIR
|
|
| win32con.OFN_FILEMUSTEXIST
|
|
| win32con.OFN_LONGNAMES
|
|
# |win32con.OFN_EXTENSIONDIFFERENT
|
|
),
|
|
Title=title,
|
|
Filter=f,
|
|
)
|
|
except Exception, e:
|
|
print "Open File: ", e
|
|
pass
|
|
else:
|
|
return filename
|
|
|
|
|
|
def askSaveSchematic(initialDir, displayName, fileFormat):
|
|
return askSaveFile(initialDir,
|
|
title='Save this schematic...',
|
|
defaultName=displayName + "." + fileFormat,
|
|
filetype='Minecraft Schematics (*.{0})\0*.{0}\0\0'.format(fileFormat),
|
|
suffix=fileFormat,
|
|
)
|
|
|
|
|
|
def askCreateWorld(initialDir):
|
|
defaultName = name = "Untitled World"
|
|
i = 0
|
|
while exists(join(initialDir, name)):
|
|
i += 1
|
|
name = defaultName + " " + str(i)
|
|
|
|
return askSaveFile(initialDir,
|
|
title='Name this new world.',
|
|
defaultName=name,
|
|
filetype='Minecraft World\0*.*\0\0',
|
|
suffix="",
|
|
)
|
|
|
|
|
|
def askSaveFile(initialDir, title, defaultName, filetype, suffix):
|
|
if sys.platform == "win32":
|
|
try:
|
|
(filename, customfilter, flags) = win32gui.GetSaveFileNameW(
|
|
hwndOwner=display.get_wm_info()['window'],
|
|
InitialDir=initialDir,
|
|
Flags=win32con.OFN_EXPLORER | win32con.OFN_NOCHANGEDIR | win32con.OFN_OVERWRITEPROMPT,
|
|
File=defaultName,
|
|
DefExt=suffix,
|
|
Title=title,
|
|
Filter=filetype,
|
|
)
|
|
except Exception, e:
|
|
print "Error getting file name: ", e
|
|
return
|
|
|
|
try:
|
|
filename = filename[:filename.index('\0')]
|
|
filename = filename.decode(sys.getfilesystemencoding())
|
|
except:
|
|
pass
|
|
|
|
elif sys.platform == "darwin" and AppKit is not None:
|
|
sp = AppKit.NSSavePanel.savePanel()
|
|
sp.setDirectory_(initialDir)
|
|
sp.setAllowedFileTypes_([suffix])
|
|
# sp.setFilename_(self.editor.level.displayName)
|
|
|
|
if sp.runModal() == 0:
|
|
return # pressed cancel
|
|
|
|
filename = sp.filename()
|
|
AppKit.NSApp.mainWindow().makeKeyWindow()
|
|
|
|
else:
|
|
filename = request_new_filename(prompt=title,
|
|
suffix=("." + suffix) if suffix else "",
|
|
directory=initialDir,
|
|
filename=defaultName,
|
|
pathname=None)
|
|
|
|
return filename
|
|
|
|
#
|
|
# if sys.platform == "win32":
|
|
# try:
|
|
#
|
|
# (filename, customfilter, flags) = win32gui.GetSaveFileNameW(
|
|
# hwndOwner = display.get_wm_info()['window'],
|
|
# # InitialDir=saveFileDir,
|
|
# Flags=win32con.OFN_EXPLORER | win32con.OFN_NOCHANGEDIR | win32con.OFN_OVERWRITEPROMPT,
|
|
# File=initialDir + os.sep + displayName,
|
|
# DefExt=fileFormat,
|
|
# Title=,
|
|
# Filter=,
|
|
# )
|
|
# except Exception, e:
|
|
# print "Error getting filename: {0!r}".format(e)
|
|
# return
|
|
#
|
|
# elif sys.platform == "darwin" and AppKit is not None:
|
|
# sp = AppKit.NSSavePanel.savePanel()
|
|
# sp.setDirectory_(initialDir)
|
|
# sp.setAllowedFileTypes_([fileFormat])
|
|
# # sp.setFilename_(self.editor.level.displayName)
|
|
#
|
|
# if sp.runModal() == 0:
|
|
# return; # pressed cancel
|
|
#
|
|
# filename = sp.filename()
|
|
# AppKit.NSApp.mainWindow().makeKeyWindow()
|
|
#
|
|
# else:
|
|
#
|
|
# filename = request_new_filename(prompt = "Save this schematic...",
|
|
# suffix = ".{0}".format(fileFormat),
|
|
# directory = initialDir,
|
|
# filename = displayName,
|
|
# pathname = None)
|
|
#
|
|
# return filename
|
|
|
|
|
|
def documents_folder():
|
|
docsFolder = None
|
|
|
|
if sys.platform == "win32":
|
|
try:
|
|
objShell = win32com.client.Dispatch("WScript.Shell")
|
|
docsFolder = objShell.SpecialFolders("MyDocuments")
|
|
|
|
except Exception, e:
|
|
print e
|
|
try:
|
|
docsFolder = shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, 0, 0)
|
|
except Exception, e:
|
|
userprofile = os.environ['USERPROFILE'].decode(sys.getfilesystemencoding())
|
|
docsFolder = os.path.join(userprofile, "Documents")
|
|
|
|
elif sys.platform == "darwin":
|
|
docsFolder = os.path.expanduser(u"~/Documents/")
|
|
else:
|
|
docsFolder = os.path.expanduser(u"~/.mcedit")
|
|
try:
|
|
os.mkdir(docsFolder)
|
|
except:
|
|
pass
|
|
|
|
return docsFolder
|
|
|
|
|
|
def platform_open(path):
|
|
try:
|
|
if sys.platform == "win32":
|
|
os.startfile(path)
|
|
# os.system('start ' + path + '\'')
|
|
elif sys.platform == "darwin":
|
|
# os.startfile(path)
|
|
os.system('open "' + path + '"')
|
|
else:
|
|
os.system('xdg-open "' + path + '"')
|
|
|
|
except Exception, e:
|
|
print "platform_open failed on {0}: {1}".format(sys.platform, e)
|
|
|
|
win32_window_size = True
|
|
|
|
ini = u"mcedit.ini"
|
|
parentDir = dirname(directories.dataDir)
|
|
docsFolder = documents_folder()
|
|
portableConfigFilePath = os.path.join(parentDir, ini)
|
|
portableSchematicsDir = os.path.join(parentDir, u"MCEdit-schematics")
|
|
fixedConfigFilePath = os.path.join(docsFolder, ini)
|
|
fixedSchematicsDir = os.path.join(docsFolder, u"MCEdit-schematics")
|
|
|
|
if sys.platform == "darwin":
|
|
# parentDir is MCEdit.app/Contents/
|
|
folderContainingAppPackage = dirname(dirname(parentDir))
|
|
oldPath = fixedConfigFilePath
|
|
fixedConfigFilePath = os.path.expanduser("~/Library/Preferences/mcedit.ini")
|
|
|
|
if os.path.exists(oldPath):
|
|
try:
|
|
os.rename(oldPath, fixedConfigFilePath)
|
|
except Exception, e:
|
|
print repr(e)
|
|
|
|
portableConfigFilePath = os.path.join(folderContainingAppPackage, ini)
|
|
portableSchematicsDir = os.path.join(folderContainingAppPackage, u"MCEdit-schematics")
|
|
|
|
|
|
def goPortable():
|
|
global configFilePath, schematicsDir, portable
|
|
|
|
if os.path.exists(fixedSchematicsDir):
|
|
move_displace(fixedSchematicsDir, portableSchematicsDir)
|
|
if os.path.exists(fixedConfigFilePath):
|
|
move_displace(fixedConfigFilePath, portableConfigFilePath)
|
|
|
|
configFilePath = portableConfigFilePath
|
|
schematicsDir = portableSchematicsDir
|
|
portable = True
|
|
|
|
|
|
def move_displace(src, dst):
|
|
dstFolder = os.path.basename(os.path.dirname(dst))
|
|
if not os.path.exists(dst):
|
|
|
|
print "Moving {0} to {1}".format(os.path.basename(src), dstFolder)
|
|
shutil.move(src, dst)
|
|
else:
|
|
olddst = dst + ".old"
|
|
i = 0
|
|
while os.path.exists(olddst):
|
|
olddst = dst + ".old" + str(i)
|
|
i += 1
|
|
|
|
print "{0} already found in {1}! Renamed it to {2}.".format(os.path.basename(src), dstFolder, dst)
|
|
os.rename(dst, olddst)
|
|
shutil.move(src, dst)
|
|
|
|
|
|
def goFixed():
|
|
global configFilePath, schematicsDir, portable
|
|
|
|
if os.path.exists(portableSchematicsDir):
|
|
move_displace(portableSchematicsDir, fixedSchematicsDir)
|
|
if os.path.exists(portableConfigFilePath):
|
|
move_displace(portableConfigFilePath, fixedConfigFilePath)
|
|
|
|
configFilePath = fixedConfigFilePath
|
|
schematicsDir = fixedSchematicsDir
|
|
portable = False
|
|
|
|
|
|
def portableConfigExists():
|
|
return (os.path.exists(portableConfigFilePath) # mcedit.ini in MCEdit folder
|
|
or (sys.platform != 'darwin' and not os.path.exists(fixedConfigFilePath))) # no mcedit.ini in Documents folder (except on OS X when we always want it in Library/Preferences
|
|
|
|
if portableConfigExists():
|
|
print "Running in portable mode. MCEdit-schematics and mcedit.ini are stored alongside " + (sys.platform == "darwin" and "the MCEdit app bundle" or "MCEditData")
|
|
portable = True
|
|
schematicsDir = portableSchematicsDir
|
|
configFilePath = portableConfigFilePath
|
|
|
|
else:
|
|
print "Running in fixed install mode. MCEdit-schematics and mcedit.ini are in your Documents folder."
|
|
configFilePath = fixedConfigFilePath
|
|
schematicsDir = fixedSchematicsDir
|
|
portable = False
|
|
|
|
filtersDir = os.path.join(directories.dataDir, "filters")
|
|
if filtersDir not in [s.decode(sys.getfilesystemencoding())
|
|
if isinstance(s, str)
|
|
else s
|
|
for s in sys.path]:
|
|
|
|
sys.path.append(filtersDir.encode(sys.getfilesystemencoding()))
|
|
|
|
if portable:
|
|
serverJarStorageDir = (os.path.join(parentDir, "ServerJarStorage"))
|
|
ServerJarStorage.defaultCacheDir = serverJarStorageDir
|
|
jarStorage = ServerJarStorage(serverJarStorageDir)
|
|
else:
|
|
jarStorage = ServerJarStorage()
|
|
|