private static IEnumerable <string> ScanForGameDataFiles() { return(from id in AssetDatabase.FindAssets("t:DefaultAsset") let path = FileAndPathUtils.MakeProjectRelative(AssetDatabase.GUIDToAssetPath(id)) where path != null && IsGameDataFile(path) select path); }
static MonoRuntimeInformation() { if (RuntimeInformation.IsWindows) { MonoExecutableName = "mono.exe"; MonoDefaultLocation = Path.Combine(FileAndPathUtils.GetProgramFilesx86(), @"Mono\bin"); } else if (RuntimeInformation.IsOsx) { MonoExecutableName = "mono"; MonoDefaultLocation = @"/Library/Frameworks/Mono.framework/Commands"; } else { MonoExecutableName = "mono"; MonoDefaultLocation = @"/usr/bin"; } }
private static IEnumerable DownloadCharonAsync(Action <string, float> progressCallback = null) { var checkRequirements = CharonCli.CheckRequirementsAsync(); yield return(checkRequirements); var checkResult = checkRequirements.GetResult(); if (checkResult == RequirementsCheckResult.MissingRuntime) { yield return(UpdateRuntimeWindow.ShowAsync()); } var currentVersion = default(Version); var charonPath = Path.GetFullPath(Settings.CharonPath); var toolName = Path.GetFileNameWithoutExtension(Path.GetFileName(charonPath)); if (File.Exists(charonPath)) { if (progressCallback != null) { progressCallback(Resources.UI_UNITYPLUGIN_PROGRESS_CHECKING_TOOLS_VERSION, 0.05f); } var checkToolsVersion = CharonCli.GetVersionAsync(); yield return(checkToolsVersion.IgnoreFault()); currentVersion = checkToolsVersion.HasErrors ? default(Version) : checkToolsVersion.GetResult(); } if (progressCallback != null) { progressCallback(Resources.UI_UNITYPLUGIN_PROGRESS_GETTING_AVAILABLE_BUILDS, 0.10f); } var getBuildsAsync = UpdateServerCli.GetBuilds(UpdateServerCli.PRODUCT_CHARON); yield return(getBuildsAsync.IgnoreFault()); if (getBuildsAsync.HasErrors) { if (progressCallback != null) { progressCallback(Resources.UI_UNITYPLUGIN_PROGRESS_DONE, 1.0f); } Debug.LogError(string.Format("Failed to get builds list from server. Error: {0}", getBuildsAsync.Error.Unwrap().Message)); yield break; } var builds = getBuildsAsync.GetResult(); var buildsByVersion = builds.ToDictionary(b => b.Version); var lastBuild = builds.OrderByDescending(b => b.Version).FirstOrDefault(); if (lastBuild == null) { if (progressCallback != null) { progressCallback(Resources.UI_UNITYPLUGIN_PROGRESS_DONE, 1.0f); } if (Settings.Current.Verbose) { Debug.Log(string.Format("No builds of {0} are available.", toolName)); } yield break; } var currentBuild = currentVersion != null?builds.FirstOrDefault(b => b.Version == currentVersion) : null; var lastVersion = lastBuild.Version; var isMissing = File.Exists(charonPath); var actualHash = isMissing || currentBuild == null ? null : FileAndPathUtils.ComputeHash(charonPath, currentBuild.HashAlgorithm); var isCorrupted = currentBuild != null && string.Equals(currentBuild.Hash, actualHash, StringComparison.OrdinalIgnoreCase) == false; var expectedVersion = string.IsNullOrEmpty(Settings.Current.EditorVersion) ? default(Version) : new Version(Settings.Current.EditorVersion); if (!isMissing && !isCorrupted && expectedVersion == currentVersion && currentVersion != null) { if (progressCallback != null) { progressCallback(Resources.UI_UNITYPLUGIN_PROGRESS_DONE, 1.0f); } if (Settings.Current.Verbose) { Debug.Log(string.Format("{0} version '{1}' is expected and file is not corrupted.", toolName, currentVersion)); } yield break; } var versionToDownload = expectedVersion ?? lastVersion; if (buildsByVersion.ContainsKey(versionToDownload) == false) { if (progressCallback != null) { progressCallback(Resources.UI_UNITYPLUGIN_PROGRESS_DONE, 1.0f); } Debug.LogError(string.Format("Build of {0} with version '{1}' is not available to download.", toolName, versionToDownload)); yield break; } if (progressCallback != null) { progressCallback(string.Format(Resources.UI_UNITYPLUGIN_PROGRESS_DOWNLOADINGS, 0, 0), 0.10f); } var downloadPath = Path.GetTempFileName(); var downloadAsync = UpdateServerCli.DownloadBuild(UpdateServerCli.PRODUCT_CHARON, versionToDownload, downloadPath, progressCallback); yield return(downloadAsync.IgnoreFault()); if (downloadAsync.HasErrors) { if (progressCallback != null) { progressCallback(Resources.UI_UNITYPLUGIN_PROGRESS_DONE, 1.0f); } Debug.LogError(string.Format("Failed to download build of {0} with version '{1}'.{2}{3}", toolName, versionToDownload, Environment.NewLine, downloadAsync.Error.Unwrap())); yield break; } GameDataEditorWindow.FindAllAndClose(); try { if (File.Exists(charonPath)) { File.Delete(charonPath); } if (Directory.Exists(charonPath)) { Directory.Delete(charonPath); } var toolsDirectory = Path.GetDirectoryName(charonPath) ?? ""; if (Directory.Exists(toolsDirectory) == false) { Directory.CreateDirectory(toolsDirectory); } File.Move(downloadPath, charonPath); // ensure config file var charonConfigPath = charonPath + ".config"; if (File.Exists(charonConfigPath) == false) { var embeddedConfigStream = typeof(Menu).Assembly.GetManifestResourceStream("GameDevWare.Charon.Charon.exe.config"); if (embeddedConfigStream != null) { using (embeddedConfigStream) using (var configFileStream = File.Create(charonConfigPath, 8 * 1024, FileOptions.SequentialScan)) { var buffer = new byte[8 * 1024]; var read = 0; while ((read = embeddedConfigStream.Read(buffer, 0, buffer.Length)) > 0) { configFileStream.Write(buffer, 0, read); } } } } } catch (Exception moveError) { Debug.LogWarning(string.Format("Failed to move downloaded file from '{0}' to {1}. {2}.", downloadPath, charonPath, moveError.Message)); Debug.LogError(moveError); } finally { try { if (File.Exists(downloadPath)) { File.Delete(downloadPath); } } catch { /* ignore */ } } if (File.Exists(charonPath)) { if (progressCallback != null) { progressCallback(Resources.UI_UNITYPLUGIN_PROGRESS_CHECKING_TOOLS_VERSION, 0.95f); } var checkToolsVersion = CharonCli.GetVersionAsync(); yield return(checkToolsVersion.IgnoreFault()); currentVersion = checkToolsVersion.HasErrors ? default(Version) : checkToolsVersion.GetResult(); } Settings.Current.EditorVersion = currentVersion != null?currentVersion.ToString() : null; Settings.Current.Save(); Debug.Log(string.Format("{1} version is '{0}'. Download is complete.", currentVersion, Path.GetFileName(charonPath))); if (progressCallback != null) { progressCallback(Resources.UI_UNITYPLUGIN_PROGRESS_DONE, 1.0f); } }
internal static Promise <Process> Listen(string gameDataPath, string lockFilePath, int port, bool shadowCopy = true, Action <string, float> progressCallback = null) { if (string.IsNullOrEmpty(gameDataPath)) { throw new ArgumentException("Value cannot be null or empty.", "gameDataPath"); } if (string.IsNullOrEmpty(lockFilePath)) { throw new ArgumentException("Value cannot be null or empty.", "lockFilePath"); } if (port <= 0 || port > ushort.MaxValue) { throw new ArgumentOutOfRangeException("port"); } var charonPath = Path.GetFullPath(Settings.CharonPath); if (File.Exists(gameDataPath) == false) { throw new IOException(string.Format("File '{0}' doesn't exists.", gameDataPath)); } if (File.Exists(charonPath) == false) { throw new IOException(string.Format("File '{0}' doesn't exists.", charonPath)); } if (shadowCopy) { if (progressCallback != null) { progressCallback(Resources.UI_UNITYPLUGIN_WINDOW_EDITOR_COPYING_EXECUTABLE, 0.10f); } var charonMd5 = FileAndPathUtils.ComputeHash(charonPath); var shadowDirectory = Path.GetFullPath(Path.Combine(TempDirectory, charonMd5)); if (Directory.Exists(shadowDirectory) == false) { if (Settings.Current.Verbose) { Debug.Log("Making shadow copy of '" + Path.GetFileName(charonPath) + "' to '" + shadowDirectory + "'."); } Directory.CreateDirectory(shadowDirectory); var shadowCharonPath = Path.Combine(shadowDirectory, Path.GetFileName(charonPath)); File.Copy(charonPath, shadowCharonPath, overwrite: true); var configPath = charonPath + ".config"; var configShadowPath = shadowCharonPath + ".config"; if (File.Exists(configPath)) { if (Settings.Current.Verbose) { Debug.Log("Making shadow copy of '" + Path.GetFileName(configPath) + "' to '" + shadowDirectory + "'."); } File.Copy(configPath, configShadowPath); } else { Debug.LogWarning("Missing required configuration file at '" + configPath + "'."); } charonPath = shadowCharonPath; } else { charonPath = Path.Combine(shadowDirectory, Path.GetFileName(charonPath)); } } if (progressCallback != null) { progressCallback(Resources.UI_UNITYPLUGIN_WINDOW_EDITOR_LAUNCHING_EXECUTABLE, 0.30f); } var unityPid = Process.GetCurrentProcess().Id; var scriptingAssemblies = FindAndLoadScriptingAssemblies(gameDataPath); var runTask = CommandLine.Run( new RunOptions ( charonPath, RunOptions.FlattenArguments( "SERVE", Path.GetFullPath(gameDataPath), "--port", port.ToString(), "--watchPid", unityPid.ToString(), "--lockFile", Path.GetFullPath(lockFilePath), "--environment", "Unity", "--extensions", Settings.SupportedExtensions, "--scriptAssemblies", scriptingAssemblies, Settings.Current.Verbose ? "--verbose" : "" ) ) { RequireDotNetRuntime = true, CaptureStandardError = false, CaptureStandardOutput = false, ExecutionTimeout = TimeSpan.Zero, WaitForExit = false, StartInfo = { EnvironmentVariables = { { "CHARON_APP_DATA", Settings.GetLocalUserDataPath() }, { "CHARON_SERVER", Settings.Current.ServerAddress } } } } ); if (progressCallback != null) { runTask.ContinueWith(_ => progressCallback(Resources.UI_UNITYPLUGIN_WINDOW_EDITOR_LAUNCHING_EXECUTABLE, 1.0f)); } return(runTask.ContinueWith(t => t.GetResult().Process)); }