2021-11-06 13:55:37 +05:00
|
|
|
|
using Gameloop.Vdf;
|
|
|
|
|
using Gameloop.Vdf.Linq;
|
2021-11-11 12:29:59 +05:00
|
|
|
|
using System;
|
2021-10-29 13:20:27 +05:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.IO.Compression;
|
2021-11-06 14:25:25 +05:00
|
|
|
|
using System.Linq;
|
2021-10-29 13:20:27 +05:00
|
|
|
|
using System.Net;
|
|
|
|
|
|
|
|
|
|
namespace CreamInstaller
|
|
|
|
|
{
|
|
|
|
|
public static class SteamCMD
|
|
|
|
|
{
|
|
|
|
|
public static string DirectoryPath = Path.GetTempPath() + "CreamInstaller";
|
2021-11-05 10:42:25 +05:00
|
|
|
|
public static string FilePath = DirectoryPath + @"\steamcmd.exe";
|
|
|
|
|
public static string ArchivePath = DirectoryPath + @"\steamcmd.zip";
|
|
|
|
|
public static string DllPath = DirectoryPath + @"\steamclient.dll";
|
2021-11-11 12:29:59 +05:00
|
|
|
|
public static string AppCachePath = DirectoryPath + @"\appcache";
|
|
|
|
|
public static string AppCacheAppInfoPath = AppCachePath + @"\appinfo.vdf";
|
|
|
|
|
public static string AppInfoPath = DirectoryPath + @"\appinfo";
|
2021-10-29 13:20:27 +05:00
|
|
|
|
|
2021-11-05 10:42:25 +05:00
|
|
|
|
public static bool Run(string command, out string output)
|
2021-10-29 13:20:27 +05:00
|
|
|
|
{
|
2021-11-05 10:42:25 +05:00
|
|
|
|
bool success = true;
|
|
|
|
|
List<string> logs = new();
|
|
|
|
|
ProcessStartInfo processStartInfo = new()
|
|
|
|
|
{
|
|
|
|
|
FileName = FilePath,
|
|
|
|
|
RedirectStandardOutput = true,
|
|
|
|
|
RedirectStandardInput = true,
|
|
|
|
|
RedirectStandardError = true,
|
|
|
|
|
UseShellExecute = false,
|
|
|
|
|
Arguments = command,
|
|
|
|
|
CreateNoWindow = true
|
|
|
|
|
};
|
|
|
|
|
using (Process process = Process.Start(processStartInfo))
|
2021-10-29 13:20:27 +05:00
|
|
|
|
{
|
2021-11-05 10:42:25 +05:00
|
|
|
|
process.OutputDataReceived += (object sender, DataReceivedEventArgs e) => logs.Add(e.Data);
|
|
|
|
|
process.BeginOutputReadLine();
|
|
|
|
|
process.ErrorDataReceived += (object sender, DataReceivedEventArgs e) => logs.Add(e.Data);
|
|
|
|
|
process.BeginErrorReadLine();
|
|
|
|
|
process.WaitForExit();
|
2021-10-29 13:20:27 +05:00
|
|
|
|
}
|
2021-11-05 10:42:25 +05:00
|
|
|
|
output = string.Join("\r\n", logs);
|
|
|
|
|
return success;
|
2021-10-29 13:20:27 +05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Setup()
|
|
|
|
|
{
|
|
|
|
|
Kill();
|
|
|
|
|
if (!File.Exists(FilePath))
|
|
|
|
|
{
|
2021-11-05 10:42:25 +05:00
|
|
|
|
using (WebClient webClient = new()) webClient.DownloadFile("https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip", ArchivePath);
|
2021-10-29 13:20:27 +05:00
|
|
|
|
ZipFile.ExtractToDirectory(ArchivePath, DirectoryPath);
|
|
|
|
|
File.Delete(ArchivePath);
|
|
|
|
|
}
|
2021-11-11 12:29:59 +05:00
|
|
|
|
if (File.Exists(AppCacheAppInfoPath)) File.Delete(AppCacheAppInfoPath);
|
2021-11-05 10:42:25 +05:00
|
|
|
|
if (!File.Exists(DllPath)) Run($@"+quit", out _);
|
2021-10-29 13:20:27 +05:00
|
|
|
|
}
|
|
|
|
|
|
2021-11-11 12:29:59 +05:00
|
|
|
|
public static bool GetAppInfo(int appId, out VProperty appInfo, string branch = "public", int buildId = 0)
|
2021-10-29 13:20:27 +05:00
|
|
|
|
{
|
2021-11-06 13:55:37 +05:00
|
|
|
|
appInfo = null;
|
2021-10-29 13:20:27 +05:00
|
|
|
|
if (Program.Canceled) return false;
|
2021-11-06 07:37:54 +05:00
|
|
|
|
string output;
|
2021-11-11 12:29:59 +05:00
|
|
|
|
string appUpdatePath = $@"{AppInfoPath}\{appId}";
|
2021-11-05 10:42:25 +05:00
|
|
|
|
string appUpdateFile = $@"{appUpdatePath}\appinfo.txt";
|
2021-11-11 12:29:59 +05:00
|
|
|
|
restart:
|
2021-11-06 13:55:37 +05:00
|
|
|
|
if (Directory.Exists(appUpdatePath) && File.Exists(appUpdateFile)) output = File.ReadAllText(appUpdateFile);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Run($@"+@ShutdownOnFailedCommand 0 +login anonymous +app_info_print {appId} +force_install_dir {appUpdatePath} +app_update 4 +quit", out _);
|
|
|
|
|
Run($@"+@ShutdownOnFailedCommand 0 +login anonymous +app_info_print {appId} +quit", out output);
|
|
|
|
|
int openBracket = output.IndexOf("{");
|
|
|
|
|
int closeBracket = output.LastIndexOf("}");
|
2021-11-06 14:25:25 +05:00
|
|
|
|
if (openBracket != -1 && closeBracket != -1)
|
|
|
|
|
{
|
|
|
|
|
output = $"\"{appId}\"\n" + output.Substring(openBracket, 1 + closeBracket - openBracket);
|
|
|
|
|
File.WriteAllText(appUpdateFile, output);
|
|
|
|
|
}
|
2021-11-06 13:55:37 +05:00
|
|
|
|
}
|
2021-11-05 10:42:25 +05:00
|
|
|
|
if (Program.Canceled || output is null) return false;
|
2021-11-11 12:29:59 +05:00
|
|
|
|
try { appInfo = VdfConvert.Deserialize(output); }
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
if (File.Exists(appUpdateFile))
|
|
|
|
|
{
|
|
|
|
|
File.Delete(appUpdateFile);
|
|
|
|
|
goto restart;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!(appInfo is null) && appInfo.Value is VValue) goto restart;
|
2021-11-09 11:12:46 +05:00
|
|
|
|
if (appInfo is null || (!(appInfo.Value is VValue) && appInfo.Value.Children().ToList().Count == 0)) return true;
|
2021-11-07 05:18:22 +05:00
|
|
|
|
VToken type = appInfo.Value is VValue ? null : appInfo.Value?["common"]?["type"];
|
2021-11-06 14:25:25 +05:00
|
|
|
|
if (type is null || type.ToString() == "Game")
|
2021-10-29 13:20:27 +05:00
|
|
|
|
{
|
2021-11-11 12:29:59 +05:00
|
|
|
|
string buildid = appInfo.Value is VValue ? null : appInfo.Value["depots"]?["branches"]?[branch]?["buildid"]?.ToString();
|
2021-11-06 14:55:21 +05:00
|
|
|
|
if (buildid is null && !(type is null)) return true;
|
2021-11-06 15:28:53 +05:00
|
|
|
|
if (type is null || int.Parse(buildid) < buildId)
|
2021-10-29 13:20:27 +05:00
|
|
|
|
{
|
2021-11-11 12:29:59 +05:00
|
|
|
|
if (File.Exists(appUpdateFile)) File.Delete(appUpdateFile);
|
|
|
|
|
goto restart;
|
2021-10-29 13:20:27 +05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Kill()
|
|
|
|
|
{
|
2021-11-05 10:42:25 +05:00
|
|
|
|
foreach (Process process in Process.GetProcessesByName("steamcmd")) process.Kill();
|
2021-10-29 13:20:27 +05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Dispose()
|
|
|
|
|
{
|
|
|
|
|
Kill();
|
|
|
|
|
if (Directory.Exists(DirectoryPath)) Directory.Delete(DirectoryPath, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|