Merge branch 'master' of github.com:MightyPirates/OpenComputers into master-MC1.7.10

Conflicts:
	src/main/scala/li/cil/oc/common/tileentity/traits/power/IndustrialCraft2Classic.scala
	src/main/scala/li/cil/oc/common/tileentity/traits/power/IndustrialCraft2Experimental.scala
	src/main/scala/li/cil/oc/util/LuaStateFactory.scala
This commit is contained in:
Florian Nücke 2014-08-25 22:10:22 +02:00
commit 9d335b4711
2 changed files with 133 additions and 117 deletions

View File

@ -92,7 +92,7 @@ public class LuaState {
/** /**
* Registry pseudo-index. * Registry pseudo-index.
*/ */
public static int REGISTRYINDEX; public static final int REGISTRYINDEX;
/** /**
* OK status. * OK status.
@ -128,9 +128,9 @@ public class LuaState {
/** /**
* The Lua version. The format is <major>.<minor>. * The Lua version. The format is <major>.<minor>.
*/ */
public static String LUA_VERSION; public static final String LUA_VERSION;
public static void initializeNative() { static {
NativeSupport.getInstance().getLoader().load(); NativeSupport.getInstance().getLoader().load();
REGISTRYINDEX = lua_registryindex(); REGISTRYINDEX = lua_registryindex();
LUA_VERSION = lua_version(); LUA_VERSION = lua_version();

View File

@ -29,15 +29,30 @@ object LuaStateFactory {
/** Set to true in initialization code below if available. */ /** Set to true in initialization code below if available. */
private var haveNativeLibrary = false private var haveNativeLibrary = false
private val isWindows = SystemUtils.IS_OS_WINDOWS
private var _is64Bit = false
private var currentLib = "" private var currentLib = ""
private val libraryName = {
if (!Strings.isNullOrEmpty(Settings.get.forceNativeLib)) Settings.get.forceNativeLib
else if (SystemUtils.IS_OS_FREE_BSD && Architecture.IS_OS_X86) "native.32.bsd.so"
else if (SystemUtils.IS_OS_FREE_BSD && Architecture.IS_OS_X64) "native.64.bsd.so"
else if (SystemUtils.IS_OS_LINUX && Architecture.IS_OS_ARM) "native.32.arm.so"
else if (SystemUtils.IS_OS_LINUX && Architecture.IS_OS_X86) "native.32.so"
else if (SystemUtils.IS_OS_LINUX && Architecture.IS_OS_X64) "native.64.so"
else if (SystemUtils.IS_OS_MAC && Architecture.IS_OS_X86) "native.32.dylib"
else if (SystemUtils.IS_OS_MAC && Architecture.IS_OS_X64) "native.64.dylib"
else if (SystemUtils.IS_OS_WINDOWS && Architecture.IS_OS_X86) "native.32.dll"
else if (SystemUtils.IS_OS_WINDOWS && Architecture.IS_OS_X64) "native.64.dll"
else null
}
def isAvailable = haveNativeLibrary def isAvailable = haveNativeLibrary
def is64Bit = _is64Bit val is64Bit = Architecture.IS_OS_X64
// Register a custom library loader with JNLua. We have to trigger // Register a custom library loader with JNLua. We have to trigger
// library loads through JNLua to ensure the LuaState class is the // library loads through JNLua to ensure the LuaState class is the
@ -58,7 +73,11 @@ object LuaStateFactory {
// shared libraries somewhere so that we can load them, because we cannot // shared libraries somewhere so that we can load them, because we cannot
// load them directly from a JAR. // load them directly from a JAR.
def init() { def init() {
if (isWindows && !Settings.get.alwaysTryNative) { if (libraryName == null) {
return
}
if (SystemUtils.IS_OS_WINDOWS && !Settings.get.alwaysTryNative) {
if (SystemUtils.IS_OS_WINDOWS_XP) { if (SystemUtils.IS_OS_WINDOWS_XP) {
OpenComputers.log.warn("Sorry, but Windows XP isn't supported. I'm afraid you'll have to use a newer Windows. I very much recommend upgrading your Windows, anyway, since Microsoft has stopped supporting Windows XP in April 2014.") OpenComputers.log.warn("Sorry, but Windows XP isn't supported. I'm afraid you'll have to use a newer Windows. I very much recommend upgrading your Windows, anyway, since Microsoft has stopped supporting Windows XP in April 2014.")
return return
@ -70,134 +89,115 @@ object LuaStateFactory {
} }
} }
val sunArch = System.getProperty("sun.arch.data.model") val libraryUrl = classOf[Machine].getResource("/assets/" + Settings.resourceDomain + "/lib/" + libraryName)
val osArch = System.getProperty("os.arch").toLowerCase if (libraryUrl == null) {
_is64Bit = sunArch == "64" || osArch == "amd64" || osArch == "x86_64" OpenComputers.log.warn(s"Native library with name '$libraryName' not found.")
return
}
val libPath = "/assets/" + Settings.resourceDomain + "/lib/" val tmpLibFile = new File({
val libNames = Array(
"native.64.dll",
"native.64.dylib",
"native.64.so",
"native.64.bsd.so",
"native.32.dll",
"native.32.dylib",
"native.32.so",
"native.32.bsd.so",
"native.32.arm.so"
)
val tmpPath = {
val path = System.getProperty("java.io.tmpdir") val path = System.getProperty("java.io.tmpdir")
if (path.endsWith("/") || path.endsWith("\\")) path if (path.endsWith("/") || path.endsWith("\\")) path
else path + "/" else path + "/"
} } + "OpenComputersMod-" + OpenComputers.Version + "-" + libraryName)
// Try to find a working lib. // If the file, already exists, make sure it's the same we need, if it's
for (library <- libNames if !haveNativeLibrary && (Strings.isNullOrEmpty(Settings.get.forceNativeLib) || library == Settings.get.forceNativeLib)) { // not disable use of the natives.
OpenComputers.log.trace(s"Trying native library '$library'...") if (tmpLibFile.exists()) {
val libraryUrl = classOf[Machine].getResource(libPath + library) var matching = true
if (libraryUrl != null) { try {
// Create a temporary file. val inCurrent = libraryUrl.openStream()
val file = new File(tmpPath + "OpenComputersMod-" + OpenComputers.Version + "-" + library) val inExisting = new FileInputStream(tmpLibFile)
// If the file, already exists, make sure it's the same we need, if it's var inCurrentByte = 0
// not disable use of the natives. var inExistingByte = 0
if (file.exists()) { do {
var matching = true inCurrentByte = inCurrent.read()
try { inExistingByte = inExisting.read()
val inCurrent = libraryUrl.openStream() if (inCurrentByte != inExistingByte) {
val inExisting = new FileInputStream(file) matching = false
var inCurrentByte = 0 inCurrentByte = -1
var inExistingByte = 0 inExistingByte = -1
do {
inCurrentByte = inCurrent.read()
inExistingByte = inExisting.read()
if (inCurrentByte != inExistingByte) {
matching = false
inCurrentByte = -1
inExistingByte = -1
}
}
while (inCurrentByte != -1 && inExistingByte != -1)
inCurrent.close()
inExisting.close()
}
catch {
case _: Throwable =>
matching = false
}
if (!matching) {
// Try to delete an old instance of the library, in case we have an update
// and deleteOnExit fails (which it regularly does on Windows it seems).
// Note that this should only ever be necessary for dev-builds, where the
// version number didn't change (since the version number is part of the name).
try {
file.delete()
}
catch {
case t: Throwable => // Ignore.
}
if (file.exists()) {
OpenComputers.log.warn(s"Could not update native library '${file.getName}'!")
}
} }
} }
// Copy the file contents to the temporary file. while (inCurrentByte != -1 && inExistingByte != -1)
inCurrent.close()
inExisting.close()
}
catch {
case _: Throwable =>
matching = false
}
if (!matching) {
// Try to delete an old instance of the library, in case we have an update
// and deleteOnExit fails (which it regularly does on Windows it seems).
// Note that this should only ever be necessary for dev-builds, where the
// version number didn't change (since the version number is part of the name).
try { try {
val in = Channels.newChannel(libraryUrl.openStream()) tmpLibFile.delete()
try {
val out = new FileOutputStream(file).getChannel
try {
out.transferFrom(in, 0, Long.MaxValue)
file.deleteOnExit()
// Set file permissions more liberally for multi-user+instance servers.
file.setReadable(true, false)
file.setWritable(true, false)
file.setExecutable(true, false)
}
finally {
out.close()
}
}
finally {
in.close()
}
} }
catch { catch {
// Java (or Windows?) locks the library file when opening it, so any case t: Throwable => // Ignore.
// further tries to update it while another instance is still running
// will fail. We still want to try each time, since the files may have
// been updated.
// Alternatively, the file could not be opened for reading/writing.
case t: Throwable => // Nothing.
} }
// Try to load the lib. if (tmpLibFile.exists()) {
currentLib = file.getAbsolutePath OpenComputers.log.warn(s"Could not update native library '${tmpLibFile.getName}'!")
try {
LuaState.initializeNative()
new jnlua.LuaState().close()
OpenComputers.log.info(s"Found a compatible native library: '${file.getName}'.")
haveNativeLibrary = true
}
catch {
case t: Throwable =>
if (Settings.get.logFullLibLoadErrors) {
OpenComputers.log.info(s"Could not load native library '${file.getName}'.", t)
}
else {
OpenComputers.log.trace(s"Could not load native library '${file.getName}'.")
}
file.delete()
} }
} }
} }
if (!haveNativeLibrary) { // Copy the file contents to the temporary file.
OpenComputers.log.warn("Unsupported platform, you won't be able to host games with persistent computers.") try {
val in = Channels.newChannel(libraryUrl.openStream())
try {
val out = new FileOutputStream(tmpLibFile).getChannel
try {
out.transferFrom(in, 0, Long.MaxValue)
tmpLibFile.deleteOnExit()
// Set file permissions more liberally for multi-user+instance servers.
tmpLibFile.setReadable(true, false)
tmpLibFile.setWritable(true, false)
tmpLibFile.setExecutable(true, false)
}
finally {
out.close()
}
}
finally {
in.close()
}
}
catch {
// Java (or Windows?) locks the library file when opening it, so any
// further tries to update it while another instance is still running
// will fail. We still want to try each time, since the files may have
// been updated.
// Alternatively, the file could not be opened for reading/writing.
case t: Throwable => // Nothing.
}
// Try to load the lib.
currentLib = tmpLibFile.getAbsolutePath
try {
new jnlua.LuaState().close()
OpenComputers.log.info(s"Found a compatible native library: '${tmpLibFile.getName}'.")
haveNativeLibrary = true
}
catch {
case t: Throwable =>
if (Settings.get.logFullLibLoadErrors) {
OpenComputers.log.trace(s"Could not load native library '${tmpLibFile.getName}'.", t)
}
else {
OpenComputers.log.trace(s"Could not load native library '${tmpLibFile.getName}'.")
}
tmpLibFile.delete()
} }
} }
init() init()
if (!haveNativeLibrary) {
OpenComputers.log.warn("Unsupported platform, you won't be able to host games with persistent computers.")
}
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
// Factory // Factory
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
@ -295,4 +295,20 @@ object LuaStateFactory {
} }
None None
} }
// Inspired by org.apache.commons.lang3.SystemUtils
object Architecture {
val OS_ARCH = try System.getProperty("os.arch") catch {
case ex: SecurityException => null
}
val IS_OS_ARM = isOSArchMatch("arm")
val IS_OS_X86 = isOSArchMatch("x86") || isOSArchMatch("i386")
val IS_OS_X64 = isOSArchMatch("x86_64") || isOSArchMatch("amd64")
private def isOSArchMatch(archPrefix: String): Boolean = OS_ARCH != null && OS_ARCH.startsWith(archPrefix)
}
} }