Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Stokes <mogurijin@gmail.com>2011-01-04 10:48:47 +0300
committerMitchell Stokes <mogurijin@gmail.com>2011-01-04 10:48:47 +0300
commitbf69214f35ae725764ee77ec187c3d8d8c1f229e (patch)
tree34ae89a816f8ca638c0e5365ecee7907abfb1e2e /game_engine_save_as_runtime.py
parent644763410608882824efc105563b3124b7890b45 (diff)
== Save Game As Runtime ==
* Fixed OS X support (finds a good default path for the player and can make runtimes) * Enforce extensions on OS X (.app) and Windows (.exe) * Added Copy Python option to copy the bundled Python to the runtime directory * Added Overwrite 'lib' option to choose whether Copy Python will overwrite a pre-existing 'lib' directory in the runtime directory * Added Copy DLLs option (Win32 only) to copy DLL files from the Blender binary directory to the runtime directory * Cleaned up the code to handle compressed blend files.
Diffstat (limited to 'game_engine_save_as_runtime.py')
-rw-r--r--game_engine_save_as_runtime.py118
1 files changed, 91 insertions, 27 deletions
diff --git a/game_engine_save_as_runtime.py b/game_engine_save_as_runtime.py
index adf84797..eb9e0494 100644
--- a/game_engine_save_as_runtime.py
+++ b/game_engine_save_as_runtime.py
@@ -19,9 +19,9 @@
bl_addon_info = {
'name': 'Save As Runtime',
'author': 'Mitchell Stokes (Moguri)',
- 'version': (0, 2, 2),
- 'blender': (2, 5, 4),
- 'api': 31667,
+ 'version': (0, 3, 0),
+ 'blender': (2, 5, 6),
+ 'api': 34057,
'location': 'File > Export',
'description': 'Bundle a .blend file with the Blenderplayer',
'warning': '',
@@ -33,27 +33,54 @@ bl_addon_info = {
import bpy
import os
+import sys
+import shutil
-def WriteAppleRuntime(player_path, output_path):
+def WriteAppleRuntime(player_path, output_path, copy_python, overwrite_lib):
+ # Enforce the extension
+ if not output_path.endswith('.app'):
+ output_path += '.app'
+
# Use the system's cp command to preserve some meta-data
os.system('cp -R "%s" "%s"' % (player_path, output_path))
- bpy.ops.save_as_mainfile(filepath=output_path+"/Contents/Resources/game.blend", copy=True)
-
-
-def WriteRuntime(player_path, output_path):
+ bpy.ops.wm.save_as_mainfile(filepath=output_path+"/Contents/Resources/game.blend", copy=True)
+
+ # Copy bundled Python
+ blender_dir = os.path.dirname(bpy.app.binary_path)
+
+ if copy_python:
+ print("Copying Python files...", end=" ")
+ src = os.path.join(blender_dir, bpy.app.version_string.split()[0], "python", "lib")
+ dst = os.path.join(output_path, "Contents", "MacOS", "lib")
+
+ if os.path.exists(dst):
+ if overwrite_lib:
+ shutil.rmtree(dst)
+ shutil.copytree(src, dst, ignore=lambda dir, contents: [i for i in contents if i.endswith('.pyc')])
+ else:
+ shutil.copytree(src, dst, ignore=lambda dir, contents: [i for i in contents if i.endswith('.pyc')])
+
+ print("done")
+
+
+def WriteRuntime(player_path, output_path, copy_python, overwrite_lib, copy_dlls):
import struct
# Check the paths
- if not os.path.isfile(player_path):
+ if not os.path.isfile(player_path) and not(os.path.exists(player_path) and player_path.endswith('.app')):
print("The player could not be found! Runtime not saved.")
return
# Check if we're bundling a .app
if player_path.endswith('.app'):
- WriteAppleRuntime(player_path, output_path)
+ WriteAppleRuntime(player_path, output_path, copy_python, overwrite_lib)
return
+
+ # Enforce "exe" extension on Windows
+ if player_path.endswith('.exe') and not output_path.endswith('.exe'):
+ output_path += '.exe'
# Get the player's binary and the offset for the blend
file = open(player_path, 'rb')
@@ -61,24 +88,16 @@ def WriteRuntime(player_path, output_path):
offset = file.tell()
file.close()
- # Create a tmp blend file
+ # Create a tmp blend file (Blenderplayer doesn't like compressed blends)
blend_path = bpy.path.clean_name(output_path)
- bpy.ops.wm.save_as_mainfile(filepath=blend_path, copy=True)
+ bpy.ops.wm.save_as_mainfile(filepath=blend_path, compress=False, copy=True)
blend_path += '.blend'
-
- # Get the blend data (if compressed, uncompress the blend before embedding it)
+ # Get the blend data
blend_file = open(blend_path, 'rb')
- head = blend_file.read(7)
- blend_file.seek(0)
- if head[0:2] == b'\x1f\x8b': # gzip magic
- import gzip
- blend_file.close()
- blend_file = gzip.open(blend_path, 'rb')
blend_d = blend_file.read()
blend_file.close()
-
# Get rid of the tmp blend, we're done with it
os.remove(blend_path)
@@ -86,6 +105,7 @@ def WriteRuntime(player_path, output_path):
output = open(output_path, 'wb')
# Write the player and blend data to the new runtime
+ print("Writing runtime...", end=" ")
output.write(player_d)
output.write(blend_d)
@@ -99,10 +119,39 @@ def WriteRuntime(player_path, output_path):
output.write(b'BRUNTIME')
output.close()
+ print("done")
+
# Make the runtime executable on Linux
if os.name == 'posix':
os.chmod(output_path, 0o755)
-
+
+ # Copy bundled Python
+ blender_dir = os.path.dirname(bpy.app.binary_path)
+ runtime_dir = os.path.dirname(output_path)
+
+ if copy_python:
+ print("Copying Python files...", end=" ")
+ src = os.path.join(blender_dir, bpy.app.version_string.split()[0], "python", "lib")
+ dst = os.path.join(runtime_dir, "lib")
+
+ if os.path.exists(dst):
+ if overwrite_lib:
+ shutil.rmtree(dst)
+ shutil.copytree(src, dst, ignore=lambda dir, contents: [i for i in contents if i.endswith('.pyc')])
+ else:
+ shutil.copytree(src, dst, ignore=lambda dir, contents: [i for i in contents if i.endswith('.pyc')])
+
+ print("done")
+
+ # And DLLs
+ if copy_dlls:
+ print("Copying DLLs...", end=" ")
+ for file in [i for i in os.listdir(blender_dir) if i.endswith('.dll')]:
+ src = os.path.join(blender_dir, file)
+ dst = os.path.join(runtime_dir, file)
+ shutil.copy2(src, dst)
+
+ print("done")
from bpy.props import *
@@ -112,20 +161,35 @@ class SaveAsRuntime(bpy.types.Operator):
bl_label = "Save As Runtime"
bl_options = {'REGISTER'}
- blender_bin_path = bpy.app.binary_path
- blender_bin_dir = os.path.dirname(blender_bin_path)
- ext = os.path.splitext(blender_bin_path)[-1]
+ if sys.platform == 'darwin':
+ blender_bin_dir = '/'+os.path.join(*bpy.app.binary_path.split('/')[0:-4])
+ ext = '.app'
+ else:
+ blender_bin_path = bpy.app.binary_path
+ blender_bin_dir = os.path.dirname(blender_bin_path)
+ ext = os.path.splitext(blender_bin_path)[-1]
default_player_path = os.path.join(blender_bin_dir, 'blenderplayer' + ext)
player_path = StringProperty(name="Player Path", description="The path to the player to use", default=default_player_path)
filepath = StringProperty(name="Output Path", description="Where to save the runtime", default="")
+ copy_python = BoolProperty(name="Copy Python", description="Copy bundle Python with the runtime", default=True)
+ overwrite_lib = BoolProperty(name="Overwrite 'lib' folder", description="Overwrites the lib folder (if one exists) with the bundled Python lib folder", default=False)
+
+ # Only Windows has dlls to copy
+ if ext == '.exe':
+ copy_dlls = BoolProperty(name="Copy DLLs", description="Copy all needed DLLs with the runtime", default=True)
+ else:
+ copy_dlls = False
def execute(self, context):
import time
start_time = time.clock()
print("Saving runtime to", self.properties.filepath)
WriteRuntime(self.properties.player_path,
- self.properties.filepath)
+ self.properties.filepath,
+ self.properties.copy_python,
+ self.properties.overwrite_lib,
+ self.copy_dlls)
print("Finished in %.4fs" % (time.clock()-start_time))
return {'FINISHED'}
@@ -137,7 +201,7 @@ class SaveAsRuntime(bpy.types.Operator):
def menu_func(self, context):
- ext = os.path.splitext(bpy.app.binary_path)[-1]
+ ext = '.app' if sys.platform == 'darwin' else os.path.splitext(bpy.app.binary_path)[-1]
default_blend_path = bpy.data.filepath.replace(".blend", ext)
self.layout.operator(SaveAsRuntime.bl_idname, text=SaveAsRuntime.bl_label).filepath = default_blend_path