public override IEnumerator Run()
        {
            return(Cmds.Get <CmdAhornRunJuliaTask>().Run(@"
env = ENV[""AHORN_ENV""]

logfilePath = joinpath(dirname(env), ""log-install-ahorn.txt"")
println(""Logging to "" * logfilePath)
logfile = open(logfilePath, ""w"")

flush(stdout)
flush(stderr)

stdoutReal = stdout
(rd, wr) = redirect_stdout()
redirect_stderr(stdout)

@async while !eof(rd)
    data = String(readavailable(rd))
    print(stdoutReal, data)
    flush(stdoutReal)
    print(logfile, data)
    flush(logfile)
end


if VERSION < v""1.3""
    println(""Outdated version of Julia - $VERSION installed, 1.3+ needed."")
    exit(1)
end

using Logging
logger = SimpleLogger(stdout, Logging.Debug)
loggerPrev = Logging.global_logger(logger)

using Pkg
Pkg.activate(ENV[""AHORN_ENV""])

install_or_update(url::String, pkg::String) = if ""Ahorn"" ∈ keys(Pkg.Types.Context().env.project.deps)
    println(""Updating $pkg..."")
    Pkg.update(pkg)
else
    println(""Adding $pkg..."")
    Pkg.add(PackageSpec(url = url))
end

try
    println(""#OLYMPUS# TIMEOUT START"")

    Pkg.instantiate()

    install_or_update(""https://github.com/CelestialCartographers/Maple.git"", ""Maple"")
    install_or_update(""https://github.com/CelestialCartographers/Ahorn.git"", ""Ahorn"")

    Pkg.instantiate()
    Pkg.API.precompile()

    import Ahorn

    println(""#OLYMPUS# TIMEOUT END"")
catch e
    println(""FATAL ERROR"")
    println(sprint(showerror, e, catch_backtrace()))
    exit(1)
end

exit(0)
", null));
        }
Esempio n. 2
0
        public override IEnumerator Run(string root, string artifactBase)
        {
            // MiniInstaller reads orig/Celeste.exe and copies Celeste.exe into it but only if missing.
            // Olympus can help out and delete the orig folder if the existing Celeste.exe isn't modded.
            string installedVersion = Cmds.Get <CmdGetVersionString>().Run(root);

            if (installedVersion.StartsWith("Celeste ") && !installedVersion.Contains("Everest"))
            {
                string orig = Path.Combine(root, "orig");
                if (Directory.Exists(orig))
                {
                    yield return(Status("Deleting previous backup", false, "", false));

                    Directory.Delete(orig, true);
                }
            }

            if (artifactBase.StartsWith("file://"))
            {
                artifactBase = artifactBase.Substring("file://".Length);
                yield return(Status($"Unzipping {Path.GetFileName(artifactBase)}", false, "download", false));

                using (FileStream wrapStream = File.Open(artifactBase, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete))
                    using (ZipArchive wrap = new ZipArchive(wrapStream, ZipArchiveMode.Read)) {
                        ZipArchiveEntry zipEntry = wrap.GetEntry("olympus-build/build.zip");
                        if (zipEntry == null)
                        {
                            yield return(Unpack(wrap, root, "main/"));
                        }
                        else
                        {
                            using (Stream zipStream = zipEntry.Open())
                                using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Read))
                                    yield return(Unpack(zip, root));
                        }
                    }
            }
            else
            {
                // Only new builds offer olympus-meta and olympus-build artifacts.
                yield return(Status("Downloading metadata", false, "", false));

                int size;

                try {
                    byte[] zipData;
                    using (WebClient wc = new WebClient())
                        zipData = wc.DownloadData(artifactBase + "olympus-meta");
                    using (MemoryStream zipStream = new MemoryStream(zipData))
                        using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Read)) {
                            using (Stream sizeStream = zip.GetEntry("olympus-meta/size.txt").Open())
                                using (StreamReader sizeReader = new StreamReader(sizeStream))
                                    size = int.Parse(sizeReader.ReadToEnd().Trim());
                        }
                } catch (Exception) {
                    size = 0;
                }

                if (size > 0)
                {
                    yield return(Status("Downloading olympus-build.zip", false, "download", false));

                    using (MemoryStream wrapStream = new MemoryStream()) {
                        yield return(Download(artifactBase + "olympus-build", size, wrapStream));

                        yield return(Status("Unzipping olympus-build.zip", false, "download", false));

                        wrapStream.Seek(0, SeekOrigin.Begin);
                        using (ZipArchive wrap = new ZipArchive(wrapStream, ZipArchiveMode.Read)) {
                            using (Stream zipStream = wrap.GetEntry("olympus-build/build.zip").Open())
                                using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Read)) {
                                    yield return(Unpack(zip, root));
                                }
                        }
                    }
                }
                else
                {
                    yield return(Status("Downloading main.zip", false, "download", false));

                    using (MemoryStream zipStream = new MemoryStream()) {
                        yield return(Download(artifactBase + "main", size, zipStream));

                        yield return(Status("Unzipping main.zip", false, "download", false));

                        zipStream.Seek(0, SeekOrigin.Begin);
                        using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Read)) {
                            yield return(Unpack(zip, root, "main/"));
                        }
                    }
                }
            }

            yield return(Status("Starting MiniInstaller", false, "monomod", false));

            yield return(Install(root));
        }
Esempio n. 3
0
        public static void ReadLoop(Process parentProc, MessageContext ctx, StreamReader reader, bool verbose, char delimiter = '\0')
        {
            // JsonTextReader would be neat here but Newtonsoft.Json is unaware of NetworkStreams and tries to READ PAST STRINGS
            while (!(parentProc?.HasExited ?? false))
            {
                // Commands from Olympus come in pairs of two objects:

                if (verbose)
                {
                    Console.Error.WriteLine("[sharp] Awaiting next command");
                }

                // Unique ID
                string uid = JsonConvert.DeserializeObject <string>(reader.ReadTerminatedString(delimiter));
                if (verbose)
                {
                    Console.Error.WriteLine($"[sharp] Receiving command {uid}");
                }

                // Command ID
                string cid = JsonConvert.DeserializeObject <string>(reader.ReadTerminatedString(delimiter)).ToLowerInvariant();
                if (cid == "_ack")
                {
                    reader.ReadTerminatedString(delimiter);
                    if (verbose)
                    {
                        Console.Error.WriteLine($"[sharp] Ack'd command {uid}");
                    }
                    lock (Cache)
                        if (Cache.ContainsKey(uid))
                        {
                            Cache.Remove(uid);
                        }
                        else
                        {
                            Console.Error.WriteLine($"[sharp] Ack'd command that was already ack'd {uid}");
                        }
                    continue;
                }

                if (cid == "_stop")
                {
                    // Let's hope that everyone knows how to handle this.
                    Environment.Exit(0);
                    continue;
                }

                Message msg = new Message()
                {
                    UID = uid,
                    CID = cid
                };

                Cmd cmd = Cmds.Get(cid);
                if (cmd == null)
                {
                    reader.ReadTerminatedString(delimiter);
                    Console.Error.WriteLine($"[sharp] Unknown command {cid}");
                    msg.Error = "cmd failed running: not found: " + cid;
                    ctx.Reply(msg);
                    continue;
                }

                if (verbose)
                {
                    Console.Error.WriteLine($"[sharp] Parsing args for {cid}");
                }

                // Payload
                object input = JsonConvert.DeserializeObject(reader.ReadTerminatedString(delimiter), cmd.InputType);
                object output;
                try {
                    if (verbose || cmd.LogRun)
                    {
                        Console.Error.WriteLine($"[sharp] Executing {cid}");
                    }
                    if (cmd.Taskable)
                    {
                        output = Task.Run(() => cmd.Run(input));
                    }
                    else
                    {
                        output = cmd.Run(input);
                    }
                } catch (Exception e) {
                    Console.Error.WriteLine($"[sharp] Failed running {cid}: {e}");
                    msg.Error = "cmd failed running: " + e;
                    ctx.Reply(msg);
                    continue;
                }

                if (output is Task <object> task)
                {
                    task.ContinueWith(t => {
                        if (task.Exception != null)
                        {
                            Exception e = task.Exception;
                            Console.Error.WriteLine($"[sharp] Failed running task {cid}: {e}");
                            msg.Error = "cmd task failed running: " + e;
                            ctx.Reply(msg);
                            return;
                        }

                        msg.Value = t.Result;
                        lock (Cache)
                            Cache[uid] = msg;
                        ctx.Reply(msg);
                    });
                }
                else
                {
                    msg.Value = output;
                    lock (Cache)
                        Cache[uid] = msg;
                    ctx.Reply(msg);
                }
            }
        }
Esempio n. 4
0
        public override IEnumerator Run()
        {
            yield return(Status("Preparing installation of Ahorn-VHD", false, "", false));

            if (!PlatformHelper.Is(Platform.Windows | Platform.Bits64))
            {
                yield return(Status("Unsupported platform.", 1f, "error", false));

                throw new PlatformNotSupportedException($"Platform not supported: {PlatformHelper.Current}");
            }

            string vhd = AhornHelper.VHDPath;

            if (File.Exists(vhd))
            {
                yield return(Status("Ahorn-VHD already exists - please delete it before reinstalling.", 1f, "error", false));

                throw new Exception("Ahorn-VHD already exists.");
            }

            string archive = vhd + ".7z";
            bool   tmpPerm = File.Exists(archive);

            try {
                if (tmpPerm)
                {
                    yield return(Status($"{Path.GetFileName(archive)} already exists - reusing and preserving", false, "", false));
                }
                else
                {
                    const string url = "https://0x0ade.ga/ahornvhd/files/ahornvhd.7z";
                    yield return(Status($"Downloading {url} to {archive}", false, "download", false));

                    string tmp = archive + ".part";
                    if (File.Exists(tmp))
                    {
                        File.Delete(tmp);
                    }
                    using (FileStream stream = File.Open(tmp, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
                        yield return(Download(url, 0, stream));

                    File.Move(tmp, archive);
                }

                string sevenzip = Path.Combine(Program.RootDirectory, "7zr.exe");

                if (!File.Exists(sevenzip))
                {
                    const string url = "https://raw.githubusercontent.com/EverestAPI/Olympus/main/lib-windows/7zr.exe";
                    yield return(Status($"Couldn't find 7zr.exe, downloading from {url}", false, "download", false));

                    using (FileStream stream = File.Open(sevenzip, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
                        yield return(Download(url, 0, stream));
                }

                yield return(Status("Extracting ahornvhd.7z", false, "download", false));

                using (Process process = ProcessHelper.Wrap(sevenzip, $"x \"{archive}\" \"-o{Path.GetDirectoryName(vhd)}\" {Path.GetFileName(vhd)} -bb3")) {
                    process.Start();
                    for (string line; (line = process.StandardOutput.ReadLine()) != null;)
                    {
                        yield return(Status(line, false, "download", false));
                    }
                    process.WaitForExit();
                    if (process.ExitCode != 0)
                    {
                        throw new Exception("7zr encountered a fatal error:\n" + process.StandardError.ReadToEnd());
                    }
                    if (!File.Exists(vhd))
                    {
                        throw new Exception($"File not extracted: {vhd}");
                    }
                    yield return(Status("ahornvhd.7z extracted", false, "download", false));
                }
            } finally {
                if (!tmpPerm && File.Exists(archive))
                {
                    File.Delete(archive);
                }
            }

            yield return(Cmds.Get <CmdAhornMountAhornVHD>().Run());

            yield return(Cmds.Get <CmdAhornInstallAhorn>().Run());
        }