You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
9.1 KiB
240 lines
9.1 KiB
using System; |
|
using System.IO; |
|
using System.Linq; |
|
using UnityEngine; |
|
#if UNITY_EDITOR |
|
using UnityEditor; |
|
#endif |
|
|
|
namespace ZenFulcrum.EmbeddedBrowser { |
|
|
|
public static class FileLocations { |
|
public const string SlaveExecutable = "ZFGameBrowser"; |
|
|
|
private static CEFDirs _dirs; |
|
public static CEFDirs Dirs { |
|
get { return _dirs ?? (_dirs = GetCEFDirs()); } |
|
} |
|
|
|
public class CEFDirs { |
|
/** Where to find cef.pak, et al */ |
|
public string resourcesPath; |
|
/** Where to find .dll, .so, natives_blob.bin, etc */ |
|
public string binariesPath; |
|
/** Where to find en-US.pak et al */ |
|
public string localesPath; |
|
/** The executable to run for browser processes. */ |
|
public string subprocessFile; |
|
/** Editor/application log file */ |
|
public string logFile; |
|
/** True if the given log file is also the Unity log. */ |
|
public bool logFileIsUnityLog = true; |
|
} |
|
|
|
/// <summary> |
|
/// Tries to mimic Unity's game/company name to directory name mapping. |
|
/// For log folders at least. |
|
/// </summary> |
|
private static string GetFolderName(string name) { |
|
//Folders: |
|
//Com`~!@#$%^&*()_+-=[ ]\{}|;':",./<>?←→‽pany |
|
// becomes the Windows log folder |
|
//Com`_!@#__^__()_+-=[ ]_{}_;'__,.____←→‽pany |
|
// though it looks like the Editor analytics go to |
|
//Com`~!@#$_^&_()_+-=[ ]_{}_;'__,_____←→‽pany |
|
// And in the registry nothing is escaped and the name literally gets split across sub-folders: |
|
// «Com`~!@#$%^&*()_+-=[ ]» with a folder in it called «{}|;':",./<>?←→‽pany» |
|
// And on Linux the log folder is |
|
//Com`~!@#$_^&_()_+-=[ ]_{}_;'__,_____←→‽pany |
|
// And the Linux analytics folder is |
|
//Com`~!@#$%^&_()_+-=[ ]_{}_;'__,.____←→‽pany |
|
// BUT WAIT THERES MORE! |
|
// Under Linux Unity 2019.2 we get |
|
//Com`_!@#__^__()_+-=[ ]_{}_;'__,.____←→‽pany |
|
|
|
//Game name: |
|
//Gam`~!@#$%^&*()_+-=[ ]\{}|;':",./<>?←→‽e |
|
// get the log folder |
|
//Gam`_!@#__^__()_+-=[ ]_{}_;'__,.____←→‽e |
|
// becomes the executable |
|
//Ga`~!@#$%^&()_+-=[]{};',.←→‽me.exe |
|
// and the Linux the log folder is |
|
//Gam`~!@#$%^&_()_+-=[ ]_{}_;'__,.____←→‽e |
|
// And the Linux analytics folder is |
|
//Gam`~!@#$_^&_()_+-=[ ]_{}_;'__,_____←→‽e |
|
// and Linux Unity 2019.2 |
|
//Gam`_!@#__^__()_+-=[ ]_{}_;'__,.____←→‽e |
|
|
|
|
|
//Gam`~!@#$%^&*()_+-=[ ]\{}|;':",./<>?←→‽e src |
|
//Gam`_!@#__^__()_+-=[ ]_{}_;'__,.____←→‽e Windows |
|
//Gam`~!@#$%^&_()_+-=[ ]_{}_;'__,.____←→‽e Linux |
|
//Gam`_!@#__^__()_+-=[ ]_{}_;'__,.____←→‽e Linux 2019.2+ |
|
char[] nixChars = { |
|
#if (UNITY_EDITOR_WIN || (UNITY_STANDALONE_WIN && !UNITY_EDITOR)) || (UNITY_STANDALONE_LINUX && UNITY_2019_2_OR_NEWER && !UNITY_EDITOR) |
|
'~', '$', '%', '&', |
|
#endif |
|
'*', '\\', '|', ':', '"', '/', '<', '>', '?', |
|
}; |
|
|
|
return nixChars.Aggregate(name, (current, ch) => current.Replace(ch, '_')); |
|
} |
|
|
|
private static CEFDirs GetCEFDirs() { |
|
//Note on "Editor-browser.log" and "Player-browser.log": |
|
//Starting with 2019.1 Unity seems to use a different method to write to the log. It no longer appends |
|
//to the log at the current end, but just keeps writing from the last position. |
|
//This causes our CEF log messages to get written over, so we use a separate file for CEF. |
|
|
|
#if UNITY_EDITOR |
|
//In the editor we don't know exactly where we are at, but we can look up one of our scripts and move from there |
|
var guids = AssetDatabase.FindAssets("EditorWebResources"); |
|
if (guids.Length != 1) throw new FileNotFoundException("Failed to locate a single EditorWebResources file"); |
|
string scriptPath = AssetDatabase.GUIDToAssetPath(guids[0]); |
|
|
|
// ReSharper disable once PossibleNullReferenceException |
|
var baseDir = Directory.GetParent(scriptPath).Parent.FullName + "/Plugins"; |
|
string resourcesPath, localesDir; |
|
var platformDir = baseDir; |
|
|
|
#if UNITY_EDITOR_WIN |
|
#if UNITY_EDITOR_64 |
|
platformDir += "/w64"; |
|
#else |
|
platformDir += "/w32"; |
|
#endif |
|
|
|
resourcesPath = platformDir + "/CEFResources"; |
|
localesDir = resourcesPath + "/locales"; |
|
|
|
//Silly MS. |
|
resourcesPath = resourcesPath.Replace("/", "\\"); |
|
localesDir = localesDir.Replace("/", "\\"); |
|
platformDir = platformDir.Replace("/", "\\"); |
|
|
|
var subprocessFile = platformDir + "/" + SlaveExecutable + ".exe"; |
|
var logFile = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/Unity/Editor/"; |
|
|
|
#elif UNITY_EDITOR_LINUX |
|
platformDir += "/l64"; |
|
|
|
resourcesPath = platformDir + "/CEFResources"; |
|
localesDir = resourcesPath + "/locales"; |
|
|
|
var subprocessFile = platformDir + "/" + SlaveExecutable; |
|
var logFile = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/unity3d/"; |
|
|
|
#elif UNITY_EDITOR_OSX |
|
platformDir += "/m64"; |
|
|
|
resourcesPath = platformDir + "/BrowserLib.app/Contents/Frameworks/Chromium Embedded Framework.framework/Resources"; |
|
localesDir = resourcesPath; |
|
|
|
//Chromium's base::mac::GetAppBundlePath will walk up the tree until it finds an ".app" folder and start |
|
//looking for pieces from there. That's why everything is hidden in a fake "BrowserLib.app" |
|
//folder that's not actually an app. |
|
var subprocessFile = platformDir + "/BrowserLib.app/Contents/Frameworks/" + SlaveExecutable + ".app/Contents/MacOS/" + SlaveExecutable; |
|
|
|
var logFile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "/Library/Logs/Unity/"; |
|
#else |
|
//If you want to build your app without ZFBrowser on some platforms change this to an exception or |
|
//tweak the .asmdef |
|
#error ZFBrowser is not supported on this platform |
|
#endif |
|
|
|
|
|
return new CEFDirs() { |
|
resourcesPath = resourcesPath, |
|
binariesPath = platformDir, |
|
localesPath = localesDir, |
|
subprocessFile = subprocessFile, |
|
#if UNITY_2019_1_OR_NEWER |
|
logFile = logFile + "Editor-browser.log", |
|
logFileIsUnityLog = false, |
|
#else |
|
logFile = logFile + "Editor.log", |
|
#endif |
|
}; |
|
|
|
#elif UNITY_STANDALONE_WIN |
|
var resourcesPath = Application.dataPath + "/Plugins"; |
|
var logFileIsUnityLog = true; |
|
|
|
var logFile = Application.dataPath + "/output_log.txt"; |
|
#if UNITY_2017_2_OR_NEWER |
|
var appLowDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "Low/" + GetFolderName(Application.companyName) + "/" + GetFolderName(Application.productName); |
|
if (Directory.Exists(appLowDir)) { |
|
#if UNITY_2019_1_OR_NEWER |
|
logFile = appLowDir + "/Player-browser.log"; |
|
logFileIsUnityLog = false; |
|
#else |
|
logFile = appLowDir + "/output_log.txt"; |
|
#endif |
|
} |
|
#endif |
|
|
|
return new CEFDirs() { |
|
resourcesPath = resourcesPath, |
|
binariesPath = resourcesPath, |
|
localesPath = resourcesPath + "/locales", |
|
subprocessFile = resourcesPath + "/" + SlaveExecutable + ".exe", |
|
logFile = logFile, |
|
logFileIsUnityLog = logFileIsUnityLog, |
|
}; |
|
#elif UNITY_STANDALONE_LINUX |
|
var resourcesPath = Application.dataPath + "/Plugins"; |
|
|
|
#if !UNITY_2017_2_OR_NEWER // Unity 2017.1 and older |
|
//We can write to a log file of our choice, but that doesn't stop CEF from writing a copy of messages to stderr, |
|
//which Unity puts in the main log file anyway. (And at the start no less - I can't stop this form happening.) |
|
//We'll pass on having a separate log file. |
|
var logFile = "/dev/null"; |
|
var logFileIsUnityLog = false; |
|
#elif !UNITY_2019_1 // Unity 2017.2+, except 2019.1 |
|
//Newer versions of Unity don't copy stderr into the log file. (But they do copy stdout. :-/) |
|
var logFile = Environment.GetEnvironmentVariable("HOME"); |
|
var logFileIsUnityLog = false; |
|
if (string.IsNullOrEmpty(logFile)) logFile = "/dev/null"; |
|
else { |
|
logFile += "/.config/unity3d/" + GetFolderName(Application.companyName) + "/" + GetFolderName(Application.productName) + "/Player-browser.log"; |
|
logFileIsUnityLog = false; |
|
} |
|
#else //Unity 2019.1.0 |
|
//And here Unity just...I'm not sure what's going on. Their log location isn't consistent with their documentation. |
|
var logFile = Environment.GetEnvironmentVariable("HOME"); |
|
var logFileIsUnityLog = false; |
|
if (string.IsNullOrEmpty(logFile)) logFile = "/dev/null"; |
|
else { |
|
logFile += "/.config/unity3d/Editor/Player-browser.log"; |
|
logFileIsUnityLog = false; |
|
} |
|
#endif |
|
|
|
return new CEFDirs() { |
|
resourcesPath = resourcesPath, |
|
binariesPath = resourcesPath, |
|
localesPath = resourcesPath + "/locales", |
|
subprocessFile = resourcesPath + "/" + SlaveExecutable, |
|
logFile = logFile, |
|
logFileIsUnityLog = logFileIsUnityLog, |
|
}; |
|
#elif UNITY_STANDALONE_OSX |
|
return new CEFDirs() { |
|
resourcesPath = Application.dataPath + "/Frameworks/Chromium Embedded Framework.framework/Resources", |
|
binariesPath = Application.dataPath + "/Plugins", |
|
localesPath = Application.dataPath + "/Frameworks/Chromium Embedded Framework.framework/Resources", |
|
subprocessFile = Application.dataPath + "/Frameworks/ZFGameBrowser.app/Contents/MacOS/" + SlaveExecutable, |
|
#if UNITY_2019_1_OR_NEWER |
|
logFile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "/Library/Logs/Unity/Player-browser.log", |
|
logFileIsUnityLog = false, |
|
#else |
|
logFile = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "/Library/Logs/Unity/Player.log", |
|
#endif |
|
}; |
|
#else |
|
#error Web textures are not supported on this platform |
|
#endif |
|
} |
|
} |
|
|
|
}
|
|
|