mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-18 19:56:17 -04:00
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:
commit
9d335b4711
@ -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();
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user