Пример #1
0
        public static Promise <RunResult> CreateDocumentAsync(string gameDataPath, string entity, CommandInput input, CommandOutput output)
        {
            if (gameDataPath == null)
            {
                throw new ArgumentNullException("gameDataPath");
            }
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            if (output == null)
            {
                throw new ArgumentNullException("output");
            }

            if (File.Exists(gameDataPath) == false)
            {
                throw new IOException(string.Format("GameData file '{0}' doesn't exists.", gameDataPath));
            }

            var runTask = RunInternal
                          (
                RunOptions.FlattenArguments(
                    "DATA", "CREATE", gameDataPath,
                    "--entity", entity,
                    "--input", input.Source,
                    "--inputFormat", input.Format,
                    "--inputFormattingOptions", input.FormattingOptions,
                    "--output", output.Target,
                    "--outputFormat", output.Format,
                    "--outputFormattingOptions", output.FormattingOptions
                    )
                          );

            input.StickWith(runTask);
            return(output.Capture(runTask));
        }
Пример #2
0
        public RunResult(RunOptions options, Process process)
        {
            this.Process   = process;
            this.ProcessId = process.Id;
            this.ExitCode  = int.MinValue;

            if (options.StartInfo.RedirectStandardOutput)
            {
                this.standardStreamOpenStatus |= STANDARD_OUTPUT_OPENED;
                this.standardOutputBuffer      = new StringBuilder();
                process.OutputDataReceived    += this.OnOutputDataReceived;
                process.BeginOutputReadLine();
            }
            if (options.StartInfo.RedirectStandardError)
            {
                this.standardErrorBuffer       = new StringBuilder();
                this.standardStreamOpenStatus |= STANDARD_ERROR_OPENED;
                process.ErrorDataReceived     += this.OnErrorDataReceived;
                process.BeginErrorReadLine();
            }
        }
Пример #3
0
        public static Promise <RunResult> ImportAsync(string gameDataPath, string[] entities, CommandInput input, ImportMode mode)
        {
            if (gameDataPath == null)
            {
                throw new ArgumentNullException("gameDataPath");
            }
            if (entities == null)
            {
                throw new ArgumentNullException("entities");
            }
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }

            if (Enum.IsDefined(typeof(ImportMode), mode) == false)
            {
                throw new ArgumentException("Unknown import mode.", "mode");
            }
            if (File.Exists(gameDataPath) == false)
            {
                throw new IOException(string.Format("GameData file '{0}' doesn't exists.", gameDataPath));
            }

            var runTask = RunInternal
                          (
                RunOptions.FlattenArguments(
                    "DATA", "IMPORT", gameDataPath,
                    "--entities", entities,
                    "--mode", mode,
                    "--input", input.Source,
                    "--inputFormat", input.Format,
                    "--inputFormattingOptions", input.FormattingOptions
                    )
                          );

            input.StickWith(runTask);
            return(runTask);
        }
Пример #4
0
        public static Promise <RunResult> GetDocumentAsync(string gameDataPath, string entity, string id, CommandOutput output)
        {
            if (gameDataPath == null)
            {
                throw new ArgumentNullException("gameDataPath");
            }
            if (entity == null)
            {
                throw new ArgumentNullException("entity");
            }
            if (id == null)
            {
                throw new ArgumentNullException("id");
            }
            if (output == null)
            {
                throw new ArgumentNullException("output");
            }

            if (File.Exists(gameDataPath) == false)
            {
                throw new IOException(String.Format("GameData file '{0}' doesn't exists.", gameDataPath));
            }

            var runTask = RunInternal
                          (
                RunOptions.FlattenArguments(
                    "DATA", "FIND", gameDataPath,
                    "--entity", entity,
                    "--id", id,
                    "--output", output.Target,
                    "--outputFormat", output.Format,
                    "--outputFormattingOptions", output.FormattingOptions
                    )
                          );

            return(output.Capture(runTask));
        }
Пример #5
0
        public static Promise <RunResult> RestoreAsync(string gameDataPath, CommandInput input)
        {
            if (gameDataPath == null)
            {
                throw new ArgumentNullException("gameDataPath");
            }
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }

            var runTask = RunInternal
                          (
                RunOptions.FlattenArguments(
                    "DATA", "RESTORE", gameDataPath,
                    "--input", input.Source,
                    "--inputFormat", input.Format,
                    "--inputFormattingOptions", input.FormattingOptions
                    )
                          );

            input.StickWith(runTask);
            return(runTask);
        }
Пример #6
0
        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));
        }
Пример #7
0
        private static IEnumerable RunAsync(RunOptions options)
        {
            yield return(null);

            var isDotNetInstalled = false;

            if (RuntimeInformation.IsWindows)
            {
                isDotNetInstalled = DotNetRuntimeInformation.GetVersion() != null;
            }

            if (options.RequireDotNetRuntime && isDotNetInstalled == false)
            {
                if (string.IsNullOrEmpty(MonoRuntimeInformation.MonoPath))
                {
                    throw new InvalidOperationException("No .NET runtime found on machine.");
                }

                options.StartInfo.Arguments = RunOptions.ConcatenateArguments(options.StartInfo.FileName) + " " + options.StartInfo.Arguments;
                options.StartInfo.FileName  = MonoRuntimeInformation.MonoPath;
            }

            if (options.CaptureStandardError)
            {
                options.StartInfo.RedirectStandardError = true;
            }
            if (options.CaptureStandardOutput)
            {
                options.StartInfo.RedirectStandardOutput = true;
            }

            if (Settings.Current.Verbose)
            {
                UnityEngine.Debug.Log(string.Format("Starting process '{0}' at '{1}' with arguments '{2}' and environment variables '{3}'.", options.StartInfo.FileName, options.StartInfo.WorkingDirectory, options.StartInfo.Arguments, ConcatenateDictionaryValues(options.StartInfo.EnvironmentVariables)));
            }

            var processStarted = DateTime.UtcNow;
            var timeout        = options.ExecutionTimeout;

            if (timeout <= TimeSpan.Zero)
            {
                timeout = TimeSpan.MaxValue;
            }

            var process = Process.Start(options.StartInfo);

            if (process == null)
            {
                throw new InvalidOperationException("Unknown process start error.");
            }

            var result = new RunResult(options, process);

            if (options.WaitForExit == false)
            {
                //if (Settings.Current.Verbose)
                //	UnityEngine.Debug.Log(string.Format("Yielding started process '{0}' at '{1}' with arguments '{2}'.", options.StartInfo.FileName, options.StartInfo.WorkingDirectory, options.StartInfo.Arguments));
                yield return(result);

                yield break;
            }

            var hasExited = false;

            while (hasExited == false)
            {
                if (DateTime.UtcNow - processStarted > timeout)
                {
                    throw new TimeoutException();
                }

                try
                {
                    process.Refresh();
                    hasExited = process.HasExited;
                }
                catch (InvalidOperationException)
                {
                    // ignored
                }
                catch (System.ComponentModel.Win32Exception)
                {
                    // ignored
                }
                yield return(Promise.Delayed(TimeSpan.FromMilliseconds(50)));
            }

            processStarted = DateTime.UtcNow;
            timeout        = options.TerminationTimeout;
            if (timeout <= TimeSpan.Zero)
            {
                timeout = TimeSpan.MaxValue;
            }

            while (result.HasPendingData)
            {
                if (DateTime.UtcNow - processStarted > timeout)
                {
                    throw new TimeoutException();
                }

                yield return(Promise.Delayed(TimeSpan.FromMilliseconds(50)));
            }

            result.ExitCode = process.ExitCode;

            if (Settings.Current.Verbose)
            {
                UnityEngine.Debug.Log(string.Format("Process #{1} '{0}' has exited with code {2}.", options.StartInfo.FileName, result.ProcessId, result.ExitCode));
            }

            yield return(result);
        }