// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Text.Json;
#nullable disable
namespace HordeServer.Utilities
{
static class AgentUtilities
{
///
/// Reads the version number from an archive
///
/// The archive data
///
public static string ReadVersion(byte[] data)
{
MemoryStream inputStream = new MemoryStream(data);
using (ZipArchive inputArchive = new ZipArchive(inputStream, ZipArchiveMode.Read, true))
{
foreach (ZipArchiveEntry inputEntry in inputArchive.Entries)
{
if (inputEntry.FullName.Equals("HordeAgent.dll", StringComparison.OrdinalIgnoreCase))
{
string tempFile = Path.GetTempFileName();
try
{
inputEntry.ExtractToFile(tempFile, true);
return FileVersionInfo.GetVersionInfo(tempFile).ProductVersion;
}
finally
{
File.Delete(tempFile);
}
}
}
}
throw new Exception("Unable to find HordeAgent.dll in archive");
}
///
/// Updates the agent app settings within the archive data
///
/// Data for the zip archive
/// The settings to update
/// New agent app data
public static byte[] UpdateAppSettings(byte[] data, Dictionary settings)
{
bool writtenClientId = false;
MemoryStream outputStream = new MemoryStream();
using (ZipArchive outputArchive = new ZipArchive(outputStream, ZipArchiveMode.Create, true))
{
MemoryStream inputStream = new MemoryStream(data);
using (ZipArchive inputArchive = new ZipArchive(inputStream, ZipArchiveMode.Read, true))
{
foreach (ZipArchiveEntry inputEntry in inputArchive.Entries)
{
ZipArchiveEntry outputEntry = outputArchive.CreateEntry(inputEntry.FullName);
using System.IO.Stream inputEntryStream = inputEntry.Open();
using System.IO.Stream outputEntryStream = outputEntry.Open();
if (inputEntry.FullName.Equals("appsettings.json", StringComparison.OrdinalIgnoreCase))
{
using MemoryStream memoryStream = new MemoryStream();
inputEntryStream.CopyTo(memoryStream);
Dictionary> document = JsonSerializer.Deserialize>>(memoryStream.ToArray());
foreach (KeyValuePair pair in settings)
{
document["Horde"][pair.Key] = pair.Value;
}
using Utf8JsonWriter writer = new Utf8JsonWriter(outputEntryStream, new JsonWriterOptions { Indented = true });
JsonSerializer.Serialize>>(writer, document, new JsonSerializerOptions { WriteIndented = true });
writtenClientId = true;
}
else
{
inputEntryStream.CopyTo(outputEntryStream);
}
}
}
}
if (!writtenClientId)
{
throw new InvalidDataException("Missing appsettings.json file from zip archive");
}
return outputStream.ToArray();
}
}
}