Last active
December 22, 2015 04:38
-
-
Save celestefox/6417953 to your computer and use it in GitHub Desktop.
Python in Javascript in Minecraft oh my!
This file contains 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
//Start python script engine integration | |
var __system__; | |
var __file__; | |
var __pathJoiner__; | |
var engineManager; | |
var engine; | |
var execPyString; | |
var execPyStream; | |
var execPyFile; | |
/** | |
* Sets up the python script engine. | |
* Might need Java 7+ | |
* Currently depends on both Jython (probably needs 2.7, has to be standalone) and guava being in the classpath. | |
* If you are using Forge/FML, guava is already suplied from at least 1.4 on. | |
* To get a working jython.jar is a bit harder. | |
* Download http://search.maven.org/remotecontent?filepath=org/python/jython-installer/2.7-b1/jython-installer-2.7-b1.jar | |
* (for 2.7) and run it. Select english, agree to the agreement. | |
* MAKE SURE TO SELECT STANDALONE INSTALLATION. Set the location to say a empty folder on your desktop. | |
* Leave the java home alone, unless you know you are running MC with a different JRE than default (hint you probably are not) | |
* Say next on the confirmation screen, wait, say next until it exits. Fin the directory you told it to install to, copy the jython.jar in there | |
* to your mods folder (not coremods, not libs, etc). This SHOULD make FML insert it into your classpath, probably with MC1.4+, but I'm not sure about 1.6 | |
* | |
* After this block, you should be able to do whatever with the Python Script engine fairly easily with execPyString, execPyStream, and execPyFile | |
* Pass any string to execPyString to execute it in the python script engine | |
* execPyStream is more of a helper function for execPyFile, you probably will only use it if you HAVE to have some python file out of the "msePy" directory | |
* execPyFile takes an arbitrary filename and executes the file, assuming it is in config/msePy, a folder that is set as set as the python "home", | |
* prepended to the python path, and had a basic registry file for jython added to it. The python "home" setting makes Jython look for that registry file there. | |
*/ | |
(function () | |
{ | |
__system__ = Packages.java.lang.System; | |
__file__ = Packages.java.io.File; | |
__pathJoiner__ = Packages.com.google.common.base.Joiner.on(__file__.pathSeparator).skipNulls(); | |
__file__(__api.__getConfigDir(), "msePy").mkdirs(); | |
if (!__file__(__file__(__api.__getConfigDir(), "msePy"), "registry").isFile()) | |
{ | |
//Registry file does not exist, first run | |
var __regfile__ = __file__(__file__(__api.__getConfigDir(), "msePy"), "registry"); | |
__regfile__.createNewFile(); | |
var __regwriter__ = java.io.FileWriter(__regfile__, false); | |
__regwriter__.write("python.security.respectJavaAccessibility = false" + __system__.lineSeparator + "python.options.caseok = false"); | |
__regwriter__.flush(); | |
__regwriter__.close(); | |
} | |
/** I need to override this to get several things working. */ | |
__system__.setProperty("python.home", __file__(__api.__getConfigDir(), "msePy").toString()); | |
var __pythonPath__ = __system__.getProperty("python.path"); | |
if (!isEmpty(__pythonPath__))//I use this because typeof on null returns "object" but trying to iterate it throws so yay reuse! | |
{ | |
//Pythonpath already has some entries somehow, prepend our msePy directory. | |
var __pythonPathEntries__ = java.util.ArrayList(java.util.Arrays.asList(__pythonPath__.split(__file__.pathSeparator))); | |
__pythonPathEntries__.add(0, __file__(__api.__getConfigDir(), "msePy").toString()); | |
__pythonPath__ = __pathJoiner__.join(__pythonPathEntries__); | |
} else { | |
__pythonPath__ = __file__(__api.__getConfigDir(), "msePy").toString(); | |
} | |
__system__.setProperty("python.path", __pythonPath__); | |
engineManager = new Packages.javax.script.ScriptEngineManager(); | |
engine = engineManager.getEngineByName("python"); | |
engine.put("__api__", __api); | |
execPyString = function execPyString (str)//Exec's any old string, with the filename set to "UNKNOWN" to represent this. | |
{ | |
engine.put(Packages.javax.script.ScriptEngine.FILENAME, "UNKNOWN"); | |
engine.exec(stream); | |
engine.put(Packages.javax.script.ScriptEngine.FILENAME, null); | |
}; | |
/** | |
* Takes a class implementing Reader and executes it inside the Jython script engine. | |
* @param stream the class implementing Reader | |
* @param filename the name of the file that goes with the Stream or a placeholder | |
* @return undefined Returns nothing, logs on error instead of throwing | |
*/ | |
execPyStream = function execPyStream (stream, filename) | |
{ | |
try | |
{ | |
engine.put(Packages.javax.script.ScriptEngine.FILENAME, filename.toString()); | |
engine.exec(stream); | |
} catch (e) {log("Python stream execution failed with filename:" + ((typeof filename != "null")&&(typeof filename != "undefined")?filename.toString():"undefined"), logLevel.error)} finally { | |
engine.put(Packages.javax.script.ScriptEngine.FILENAME, null); | |
} | |
}; | |
execPyFile = function execPyFile (filename)//Reads and execs a file in MSEConfigDir/msePy(or lower), which is usually .minecraft/config/msePy | |
{ | |
var file = new __file__(__file__(__api.__getConfigDir(), "msePy"), filename); | |
var reader = new Packages.java.io.InputStreamReader(new Packages.java.io.FileInputStream(file), "UTF-8"); | |
execPyStream(reader, file.toString()); | |
reader.close(); | |
}; | |
}) (); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment