mirror of
https://github.com/mmvanheusden/SteamDepotDownloaderGUI.git
synced 2026-02-11 16:50:54 +01:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33d575b334 | ||
|
|
13bb1d57b9 | ||
|
|
6c980628f1 | ||
|
|
ff3c7d2cff | ||
|
|
dc5f38d39e | ||
|
|
65793aa6dc | ||
|
|
1cb7a4f667 | ||
|
|
7d143bbff7 | ||
|
|
f1bec83c03 | ||
|
|
3b187dc717 | ||
|
|
54def97c38 | ||
|
|
6296d62089 | ||
|
|
36f7432330 | ||
|
|
4d4d17df75 |
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
custom: ['https://en.cryptobadges.io/donate/19sE9mHShbag5WiBwZ75nG21BSFZ1UnjpZ']
|
||||
67
.github/workflows/codeql-analysis.yml
vendored
67
.github/workflows/codeql-analysis.yml
vendored
@@ -1,67 +0,0 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '22 23 * * 5'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'csharp' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||
# Learn more:
|
||||
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
||||
[submodule "DepotDownloader"]
|
||||
path = DepotDownloader
|
||||
url = https://github.com/SteamRE/DepotDownloader
|
||||
12
App.config
12
App.config
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
|
||||
</startup>
|
||||
</configuration>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
|
||||
@@ -1,86 +1,88 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{9FE2AF44-2D88-43DB-9B8F-EA410552D8CE}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>DepotDownloaderGUI</RootNamespace>
|
||||
<AssemblyName>DepotDownloaderGUI</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.DirectoryServices" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Form1.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Form1.Designer.cs">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="Form1.resx">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Resources\Poppins-Medium.ttf" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{9FE2AF44-2D88-43DB-9B8F-EA410552D8CE}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>DepotDownloaderGUI</RootNamespace>
|
||||
<AssemblyName>DepotDownloaderGUI</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.DirectoryServices" />
|
||||
<Reference Include="System.IO.Compression.FileSystem" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="downloadGUI.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="downloadGUI.Designer.cs">
|
||||
<DependentUpon>downloadGUI.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="downloadGUI.resx">
|
||||
<DependentUpon>downloadGUI.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Resources\Poppins-Medium.ttf" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -1,25 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30907.101
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DepotDownloaderGUI", "DepotDownloaderGUI.csproj", "{9FE2AF44-2D88-43DB-9B8F-EA410552D8CE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{9FE2AF44-2D88-43DB-9B8F-EA410552D8CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9FE2AF44-2D88-43DB-9B8F-EA410552D8CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9FE2AF44-2D88-43DB-9B8F-EA410552D8CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9FE2AF44-2D88-43DB-9B8F-EA410552D8CE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B49312C0-32E2-42A5-9DC8-892A707C0EF8}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30907.101
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DepotDownloaderGUI", "DepotDownloaderGUI.csproj", "{9FE2AF44-2D88-43DB-9B8F-EA410552D8CE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{9FE2AF44-2D88-43DB-9B8F-EA410552D8CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9FE2AF44-2D88-43DB-9B8F-EA410552D8CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9FE2AF44-2D88-43DB-9B8F-EA410552D8CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9FE2AF44-2D88-43DB-9B8F-EA410552D8CE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {B49312C0-32E2-42A5-9DC8-892A707C0EF8}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
302
Form1.Designer.cs
generated
302
Form1.Designer.cs
generated
@@ -1,302 +0,0 @@
|
||||
|
||||
namespace DepotDownloaderGUI
|
||||
{
|
||||
partial class Form1
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.label8 = new System.Windows.Forms.Label();
|
||||
this.textBox1 = new System.Windows.Forms.TextBox();
|
||||
this.textBox2 = new System.Windows.Forms.TextBox();
|
||||
this.textBox3 = new System.Windows.Forms.TextBox();
|
||||
this.textBox4 = new System.Windows.Forms.TextBox();
|
||||
this.textBox5 = new System.Windows.Forms.TextBox();
|
||||
this.textBox8 = new System.Windows.Forms.TextBox();
|
||||
this.button1 = new System.Windows.Forms.Button();
|
||||
this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
|
||||
this.numericUpDown2 = new System.Windows.Forms.NumericUpDown();
|
||||
this.button2 = new System.Windows.Forms.Button();
|
||||
this.button3 = new System.Windows.Forms.Button();
|
||||
this.button4 = new System.Windows.Forms.Button();
|
||||
this.label9 = new System.Windows.Forms.Label();
|
||||
this.label10 = new System.Windows.Forms.Label();
|
||||
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
resources.ApplyResources(this.label1, "label1");
|
||||
this.label1.Name = "label1";
|
||||
this.toolTip1.SetToolTip(this.label1, resources.GetString("label1.ToolTip"));
|
||||
//
|
||||
// label2
|
||||
//
|
||||
resources.ApplyResources(this.label2, "label2");
|
||||
this.label2.Name = "label2";
|
||||
this.toolTip1.SetToolTip(this.label2, resources.GetString("label2.ToolTip"));
|
||||
//
|
||||
// label3
|
||||
//
|
||||
resources.ApplyResources(this.label3, "label3");
|
||||
this.label3.Name = "label3";
|
||||
this.toolTip1.SetToolTip(this.label3, resources.GetString("label3.ToolTip"));
|
||||
//
|
||||
// label4
|
||||
//
|
||||
resources.ApplyResources(this.label4, "label4");
|
||||
this.label4.Name = "label4";
|
||||
this.toolTip1.SetToolTip(this.label4, resources.GetString("label4.ToolTip"));
|
||||
//
|
||||
// label5
|
||||
//
|
||||
resources.ApplyResources(this.label5, "label5");
|
||||
this.label5.Name = "label5";
|
||||
this.toolTip1.SetToolTip(this.label5, resources.GetString("label5.ToolTip"));
|
||||
//
|
||||
// label6
|
||||
//
|
||||
resources.ApplyResources(this.label6, "label6");
|
||||
this.label6.Name = "label6";
|
||||
this.toolTip1.SetToolTip(this.label6, resources.GetString("label6.ToolTip"));
|
||||
//
|
||||
// label7
|
||||
//
|
||||
resources.ApplyResources(this.label7, "label7");
|
||||
this.label7.Name = "label7";
|
||||
this.toolTip1.SetToolTip(this.label7, resources.GetString("label7.ToolTip"));
|
||||
//
|
||||
// label8
|
||||
//
|
||||
resources.ApplyResources(this.label8, "label8");
|
||||
this.label8.Name = "label8";
|
||||
this.toolTip1.SetToolTip(this.label8, resources.GetString("label8.ToolTip"));
|
||||
//
|
||||
// textBox1
|
||||
//
|
||||
resources.ApplyResources(this.textBox1, "textBox1");
|
||||
this.textBox1.Name = "textBox1";
|
||||
//
|
||||
// textBox2
|
||||
//
|
||||
resources.ApplyResources(this.textBox2, "textBox2");
|
||||
this.textBox2.Name = "textBox2";
|
||||
//
|
||||
// textBox3
|
||||
//
|
||||
resources.ApplyResources(this.textBox3, "textBox3");
|
||||
this.textBox3.Name = "textBox3";
|
||||
//
|
||||
// textBox4
|
||||
//
|
||||
resources.ApplyResources(this.textBox4, "textBox4");
|
||||
this.textBox4.Name = "textBox4";
|
||||
//
|
||||
// textBox5
|
||||
//
|
||||
resources.ApplyResources(this.textBox5, "textBox5");
|
||||
this.textBox5.Name = "textBox5";
|
||||
//
|
||||
// textBox8
|
||||
//
|
||||
resources.ApplyResources(this.textBox8, "textBox8");
|
||||
this.textBox8.Name = "textBox8";
|
||||
//
|
||||
// button1
|
||||
//
|
||||
resources.ApplyResources(this.button1, "button1");
|
||||
this.button1.Name = "button1";
|
||||
this.toolTip1.SetToolTip(this.button1, resources.GetString("button1.ToolTip"));
|
||||
this.button1.UseVisualStyleBackColor = true;
|
||||
this.button1.Click += new System.EventHandler(this.button1_Click);
|
||||
//
|
||||
// numericUpDown1
|
||||
//
|
||||
resources.ApplyResources(this.numericUpDown1, "numericUpDown1");
|
||||
this.numericUpDown1.Increment = new decimal(new int[] {
|
||||
5,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numericUpDown1.Maximum = new decimal(new int[] {
|
||||
1000,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numericUpDown1.Minimum = new decimal(new int[] {
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numericUpDown1.Name = "numericUpDown1";
|
||||
this.numericUpDown1.Value = new decimal(new int[] {
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// numericUpDown2
|
||||
//
|
||||
resources.ApplyResources(this.numericUpDown2, "numericUpDown2");
|
||||
this.numericUpDown2.Increment = new decimal(new int[] {
|
||||
5,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numericUpDown2.Maximum = new decimal(new int[] {
|
||||
1000,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numericUpDown2.Minimum = new decimal(new int[] {
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numericUpDown2.Name = "numericUpDown2";
|
||||
this.numericUpDown2.Value = new decimal(new int[] {
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// button2
|
||||
//
|
||||
resources.ApplyResources(this.button2, "button2");
|
||||
this.button2.Name = "button2";
|
||||
this.button2.UseVisualStyleBackColor = true;
|
||||
this.button2.Click += new System.EventHandler(this.button2_Click);
|
||||
//
|
||||
// button3
|
||||
//
|
||||
resources.ApplyResources(this.button3, "button3");
|
||||
this.button3.Name = "button3";
|
||||
this.toolTip1.SetToolTip(this.button3, resources.GetString("button3.ToolTip"));
|
||||
this.button3.UseVisualStyleBackColor = true;
|
||||
this.button3.Click += new System.EventHandler(this.button3_Click);
|
||||
//
|
||||
// button4
|
||||
//
|
||||
resources.ApplyResources(this.button4, "button4");
|
||||
this.button4.Name = "button4";
|
||||
this.toolTip1.SetToolTip(this.button4, resources.GetString("button4.ToolTip"));
|
||||
this.button4.UseVisualStyleBackColor = true;
|
||||
this.button4.Click += new System.EventHandler(this.button4_Click);
|
||||
//
|
||||
// label9
|
||||
//
|
||||
resources.ApplyResources(this.label9, "label9");
|
||||
this.label9.Name = "label9";
|
||||
//
|
||||
// label10
|
||||
//
|
||||
resources.ApplyResources(this.label10, "label10");
|
||||
this.label10.Name = "label10";
|
||||
this.toolTip1.SetToolTip(this.label10, resources.GetString("label10.ToolTip"));
|
||||
//
|
||||
// toolTip1
|
||||
//
|
||||
this.toolTip1.AutomaticDelay = 0;
|
||||
this.toolTip1.AutoPopDelay = 0;
|
||||
this.toolTip1.InitialDelay = 0;
|
||||
this.toolTip1.IsBalloon = true;
|
||||
this.toolTip1.ReshowDelay = 600;
|
||||
this.toolTip1.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Info;
|
||||
this.toolTip1.ToolTipTitle = "Info";
|
||||
//
|
||||
// Form1
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.label10);
|
||||
this.Controls.Add(this.label9);
|
||||
this.Controls.Add(this.button4);
|
||||
this.Controls.Add(this.button3);
|
||||
this.Controls.Add(this.button2);
|
||||
this.Controls.Add(this.numericUpDown2);
|
||||
this.Controls.Add(this.numericUpDown1);
|
||||
this.Controls.Add(this.button1);
|
||||
this.Controls.Add(this.textBox8);
|
||||
this.Controls.Add(this.textBox5);
|
||||
this.Controls.Add(this.textBox4);
|
||||
this.Controls.Add(this.textBox3);
|
||||
this.Controls.Add(this.textBox2);
|
||||
this.Controls.Add(this.textBox1);
|
||||
this.Controls.Add(this.label8);
|
||||
this.Controls.Add(this.label7);
|
||||
this.Controls.Add(this.label6);
|
||||
this.Controls.Add(this.label5);
|
||||
this.Controls.Add(this.label4);
|
||||
this.Controls.Add(this.label3);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Name = "Form1";
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.Label label8;
|
||||
private System.Windows.Forms.TextBox textBox1;
|
||||
private System.Windows.Forms.TextBox textBox2;
|
||||
private System.Windows.Forms.TextBox textBox3;
|
||||
private System.Windows.Forms.TextBox textBox4;
|
||||
private System.Windows.Forms.TextBox textBox5;
|
||||
private System.Windows.Forms.TextBox textBox8;
|
||||
private System.Windows.Forms.Button button1;
|
||||
private System.Windows.Forms.NumericUpDown numericUpDown1;
|
||||
private System.Windows.Forms.NumericUpDown numericUpDown2;
|
||||
private System.Windows.Forms.Button button2;
|
||||
private System.Windows.Forms.Button button3;
|
||||
private System.Windows.Forms.Button button4;
|
||||
private System.Windows.Forms.Label label9;
|
||||
private System.Windows.Forms.Label label10;
|
||||
private System.Windows.Forms.ToolTip toolTip1;
|
||||
}
|
||||
}
|
||||
|
||||
71
Form1.cs
71
Form1.cs
@@ -1,71 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Drawing.Text;
|
||||
|
||||
namespace DepotDownloaderGUI
|
||||
{
|
||||
public partial class Form1 : Form
|
||||
{
|
||||
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
|
||||
private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont,
|
||||
IntPtr pdv, [System.Runtime.InteropServices.In] ref uint pcFonts);
|
||||
|
||||
private PrivateFontCollection fonts = new PrivateFontCollection();
|
||||
|
||||
Font Poppins;
|
||||
|
||||
string Command;
|
||||
public Form1()
|
||||
{
|
||||
InitializeComponent();
|
||||
byte[] fontData = Properties.Resources.Poppins_Medium;
|
||||
IntPtr fontPtr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(fontData.Length);
|
||||
System.Runtime.InteropServices.Marshal.Copy(fontData, 0, fontPtr, fontData.Length);
|
||||
uint dummy = 0;
|
||||
fonts.AddMemoryFont(fontPtr, Properties.Resources.Poppins_Medium.Length);
|
||||
AddFontMemResourceEx(fontPtr, (uint)Properties.Resources.Poppins_Medium.Length, IntPtr.Zero, ref dummy);
|
||||
System.Runtime.InteropServices.Marshal.FreeCoTaskMem(fontPtr);
|
||||
Poppins = new Font(fonts.Families[0], 18.0F);
|
||||
Directory.SetCurrentDirectory("./depotdownloader/");
|
||||
textBox2.PasswordChar = '*';
|
||||
label9.Font = Poppins;
|
||||
FormBorderStyle = FormBorderStyle.FixedSingle;
|
||||
MaximizeBox = false;
|
||||
}
|
||||
|
||||
|
||||
private void button1_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (textBox2.Text == "")
|
||||
Command = $"/k dotnet DepotDownloader.dll -app {textBox3.Text} -depot {textBox4.Text} -manifest {textBox5.Text} -max-servers {numericUpDown1.Value} -max-downloads {numericUpDown2.Value} -dir ../YourGame {textBox8.Text}";
|
||||
else
|
||||
Command = $"/k dotnet DepotDownloader.dll -app {textBox3.Text} -depot {textBox4.Text} -manifest {textBox5.Text} -username {textBox1.Text} -password {textBox2.Text} -max-servers {numericUpDown1.Value} -max-downloads {numericUpDown2.Value} -dir ../YourGame {textBox8.Text}";
|
||||
System.Diagnostics.Process.Start("cmd.exe", Command);
|
||||
}
|
||||
|
||||
|
||||
private void button2_Click(object sender, EventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start("https://github.com/mmvanheusden/SteamDepotDownloaderGUI/discussions/5");
|
||||
}
|
||||
|
||||
private void button3_Click(object sender, EventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start("https://steamdb.info/instantsearch/");
|
||||
}
|
||||
|
||||
private void button4_Click(object sender, EventArgs e)
|
||||
{
|
||||
System.Diagnostics.Process.Start("https://github.com/mmvanheusden/SteamDepotDownloaderGUI");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
1348
LICENSE.md
1348
LICENSE.md
File diff suppressed because it is too large
Load Diff
44
Program.cs
44
Program.cs
@@ -1,22 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace DepotDownloaderGUI
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new Form1());
|
||||
}
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace DepotDownloaderGUI
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new downloadGUI());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("DepotDownloaderGUI")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("DepotDownloaderGUI")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("9fe2af44-2d88-43db-9b8f-ea410552d8ce")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("DepotDownloaderGUI")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("DepotDownloaderGUI")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2021")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("9fe2af44-2d88-43db-9b8f-ea410552d8ce")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
||||
146
Properties/Resources.Designer.cs
generated
146
Properties/Resources.Designer.cs
generated
@@ -1,73 +1,73 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace DepotDownloaderGUI.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DepotDownloaderGUI.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] Poppins_Medium {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Poppins_Medium", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace DepotDownloaderGUI.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DepotDownloaderGUI.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Byte[].
|
||||
/// </summary>
|
||||
internal static byte[] Poppins_Medium {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("Poppins_Medium", resourceCulture);
|
||||
return ((byte[])(obj));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,124 +1,124 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="Poppins_Medium" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Poppins-Medium.ttf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="Poppins_Medium" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\Poppins-Medium.ttf;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
</root>
|
||||
55
Properties/Settings.Designer.cs
generated
55
Properties/Settings.Designer.cs
generated
@@ -1,29 +1,26 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
namespace DepotDownloaderGUI.Properties
|
||||
{
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace DepotDownloaderGUI.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
|
||||
154
README.md
154
README.md
@@ -1,78 +1,76 @@
|
||||
|
||||
|
||||
<img src="https://socialify.git.ci/mmvanheusden/SteamDepotDownloaderGUI/image?description=1&font=Inter&forks=1&issues=1&language=1&owner=1&pattern=Floating%20Cogs&pulls=1&stargazers=1&theme=Light" alt="Banner" width="768"/>
|
||||
|
||||
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/status-Beta-blue" />
|
||||
<img alt="GitHub all releases" src="https://img.shields.io/github/downloads/mmvanheusden/SteamDepotDownloaderGUI/total?color=orange&label=downloads">
|
||||
<img alt="GitHub release (latest by date including pre-releases)" src="https://img.shields.io/github/v/release/mmvanheusden/SteamDepotDownloaderGUI?color=seagreen&include_prereleases">
|
||||
<img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/mmvanheusden/SteamDepotDownloaderGUI?color=crimson">
|
||||
<a href="https://wakatime.com/badge/github/mmvanheusden/SteamDepotDownloaderGUI"><img src="https://wakatime.com/badge/github/mmvanheusden/SteamDepotDownloaderGUI.svg"></a>
|
||||
<img alt="Visitor Count" src="https://visitor-badge.glitch.me/badge?page_id=mmvanheusden.SteamDepotDownloaderGUI">
|
||||
</p>
|
||||
|
||||
# SteamDepotDownloaderGUI
|
||||
|
||||
A simple GUI tool based on [**DepotDownloader**][depotdownloader] for downloading older versions of Steam games.
|
||||
|
||||

|
||||
|
||||
## What can you do with the program?
|
||||
You can download older versions of Steam games and software :sunglasses:
|
||||
|
||||
## Want an example?
|
||||
Take a look at [**This**][subnauticawiki] example.
|
||||
|
||||
## YouTube Tutorial
|
||||
<a href="https://www.youtube.com/watch?v=X-tzW5ywCgU">
|
||||
<img border="0" alt="YouTube Tutorial" src="/src/readme.md/youtube.png" width="768">
|
||||
</a>
|
||||
|
||||
## How use the program?
|
||||
|
||||
### step 1:
|
||||
Download [**.NET Core 2.0**][dotnet] It is required for the program to work properly.
|
||||
### step 2:
|
||||
Download and unzip the program. (You can download it [**Here**][latest])
|
||||
### step 3:
|
||||
Run DepotDownloaderGUI.exe.
|
||||
### step 4:
|
||||
First enter your Steam credentials at "Username" and "Password" (Don't worry, it's safe!)
|
||||
### step 5:
|
||||
Click on "SteamDB Instant Search".
|
||||
### step 6:
|
||||
Enter your game of choice at the search bar and select the game.
|
||||
### step 7:
|
||||
Copy the App ID and paste it in the program at "App ID"
|
||||
### step 8:
|
||||
Click on "Depots" in the sidebar.
|
||||
### step 9:
|
||||
Select the Windows depot (usually it is Win32)
|
||||
### step 10:
|
||||
Copy the Depot ID and paste it in the program at "Depot ID"
|
||||
### step 11:
|
||||
Click on "Manifests" in the sidebar
|
||||
### step 12:
|
||||
Choose a Manifest(game version) of choice and copy its ID and paste it in the program at "Manifest ID"
|
||||
### step 13:
|
||||
If you want a faster download speed, increase the max servers and max chunks.
|
||||
### step 14:
|
||||
Click on "Start Download", a terminal will pop up and will show the download progress.
|
||||
### step 15:
|
||||
Once the download is done, close the program.
|
||||
The downloaded game is stored in the folder "YourGame"
|
||||
> :warning: **Once the download progress is complete, Move the downloaded files to a different folder, Or else your next game download will mix with your old download!**
|
||||
### Enjoy your game!
|
||||
|
||||
## Need help?
|
||||
Just place your cursor on a text label or button and a help balloon will appear!
|
||||
### If you have any questions, use the shiny new ✨GitHub Discussions✨ page!
|
||||
|
||||
|
||||
[latest]: https://github.com/mmvanheusden/SteamDepotDownloaderGUI/releases/latest
|
||||
[steamdb]: https://steamdb.info/
|
||||
[depotdownloader]: https://github.com/SteamRE/DepotDownloader
|
||||
[subnauticawiki]: https://github.com/mmvanheusden/SteamDepotDownloaderGUI/wiki/How-to-Download-older-versions-of-Subnautica
|
||||
[dotnet]: https://dotnet.microsoft.com/download/dotnet-core/thank-you/runtime-2.0.9-windows-x64-installer
|
||||
|
||||
|
||||
<img src="https://socialify.git.ci/mmvanheusden/SteamDepotDownloaderGUI/image?description=1&font=Inter&forks=1&issues=1&language=1&owner=1&pattern=Floating%20Cogs&pulls=1&stargazers=1&theme=Light" alt="Banner" width="768"/>
|
||||
|
||||
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/status-Beta-blue" />
|
||||
<img alt="GitHub all releases" src="https://img.shields.io/github/downloads/mmvanheusden/SteamDepotDownloaderGUI/total?color=orange&label=downloads">
|
||||
<img alt="GitHub release (latest by date including pre-releases)" src="https://img.shields.io/github/v/release/mmvanheusden/SteamDepotDownloaderGUI?color=seagreen&include_prereleases">
|
||||
<img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/mmvanheusden/SteamDepotDownloaderGUI?color=crimson">
|
||||
<a href="https://en.cryptobadges.io/donate/19sE9mHShbag5WiBwZ75nG21BSFZ1UnjpZ"><img src="https://en.cryptobadges.io/badge/small/19sE9mHShbag5WiBwZ75nG21BSFZ1UnjpZ"></a>
|
||||
<img alt="Visitor Count" src="https://visitor-badge.glitch.me/badge?page_id=mmvanheusden.SteamDepotDownloaderGUI">
|
||||
</p>
|
||||
|
||||
# SteamDepotDownloaderGUI
|
||||
|
||||
A simple GUI tool based on [**DepotDownloader**][depotdownloader] for downloading older versions of Steam games.
|
||||
|
||||

|
||||
|
||||
## What can you do with the program?
|
||||
You can download older builds of Steam games and software
|
||||
|
||||
## Want an example?
|
||||
Take a look at [**This**][subnauticawiki] example.
|
||||
|
||||
## YouTube Tutorial
|
||||
<a href="https://www.youtube.com/watch?v=X-tzW5ywCgU">
|
||||
<img border="0" alt="YouTube Tutorial" src="/src/readme.md/youtube.png" width="768">
|
||||
</a>
|
||||
|
||||
## How use the program?
|
||||
|
||||
### step 1:
|
||||
Download [**.NET Core 2.0**][dotnet] It is required for the program to work properly.
|
||||
### step 2:
|
||||
Download and unzip the program. (You can download the latest version [**here**][latest])
|
||||
### step 3:
|
||||
Run DepotDownloaderGUI.exe.
|
||||
### step 4:
|
||||
First enter your Steam credentials at "Username" and "Password"
|
||||
### step 5:
|
||||
Click on "SteamDB Instant Search".
|
||||
### step 6:
|
||||
Enter your game/software of choice at the search bar and select the game.
|
||||
### step 7:
|
||||
Copy the App ID and paste it in the program at "App ID"
|
||||
### step 8:
|
||||
Click on "Depots" in the sidebar.
|
||||
### step 9:
|
||||
Select the Windows depot (usually Win32)
|
||||
### step 10:
|
||||
Copy the Depot ID and paste it in the program at "Depot ID"
|
||||
### step 11:
|
||||
Click on "Manifests" in the sidebar
|
||||
### step 12:
|
||||
Choose a Manifest(build) of choice and copy its ID and paste it in the program at "Manifest ID"
|
||||
### step 13:
|
||||
If you want a faster download speed, increase the max servers and max chunks.
|
||||
### step 14:
|
||||
Click on "Start Download", choose the location and a terminal window will pop up and will show the download progress.
|
||||
### step 15:
|
||||
Once the download is done, close the program.
|
||||
The downloaded game is stored in the specified location
|
||||
### Enjoy your game!
|
||||
|
||||
## Need help?
|
||||
Open an issue.
|
||||
|
||||
|
||||
[latest]: https://github.com/mmvanheusden/SteamDepotDownloaderGUI/releases/latest
|
||||
[steamdb]: https://steamdb.info/
|
||||
[depotdownloader]: https://github.com/SteamRE/DepotDownloader
|
||||
[subnauticawiki]: https://github.com/mmvanheusden/SteamDepotDownloaderGUI/wiki/How-to-Download-older-versions-of-Subnautica
|
||||
[dotnet]: https://dotnet.microsoft.com/download/dotnet-core/thank-you/runtime-2.0.9-windows-x64-installer
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
; EditorConfig: http://EditorConfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
37
depotdownloader/.github/workflows/build.yml
vendored
37
depotdownloader/.github/workflows/build.yml
vendored
@@ -1,37 +0,0 @@
|
||||
name: .NET Core CI
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- '.github/*'
|
||||
- '.github/*_TEMPLATE/**'
|
||||
- '*.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '.github/*'
|
||||
- '.github/*_TEMPLATE/**'
|
||||
- '*.md'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: .NET on ${{ matrix.os }} (${{ matrix.configuration }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-latest, windows-latest]
|
||||
configuration: [Release, Debug]
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v1
|
||||
- name: Build
|
||||
run: dotnet publish -c ${{ matrix.configuration }} -o artifacts
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
if: matrix.configuration == 'Release'
|
||||
with:
|
||||
name: DepotDownloader-${{ runner.os }}
|
||||
path: artifacts
|
||||
if-no-files-found: error
|
||||
120
depotdownloader/.gitignore
vendored
120
depotdownloader/.gitignore
vendored
@@ -1,120 +0,0 @@
|
||||
# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# mstest test results
|
||||
TestResults
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.sln.docstates
|
||||
.vs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Rr]elease/
|
||||
x64/
|
||||
*_i.c
|
||||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*
|
||||
|
||||
# NCrunch
|
||||
*.ncrunch*
|
||||
.*crunch*.local.xml
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish
|
||||
|
||||
# Publish Web Output
|
||||
*.Publish.xml
|
||||
|
||||
# NuGet Packages Directory
|
||||
packages
|
||||
*.nupkg
|
||||
|
||||
# Windows Azure Build Output
|
||||
csx
|
||||
*.build.csdef
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
|
||||
# Others
|
||||
[Bb]in
|
||||
[Oo]bj
|
||||
sql
|
||||
TestResults
|
||||
[Tt]est[Rr]esult*
|
||||
*.Cache
|
||||
ClientBin
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*.dbmdl
|
||||
Generated_Code #added for RIA/Silverlight projects
|
||||
|
||||
# Backup & report files from converting an old project file to a newer
|
||||
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
|
||||
# third party libs
|
||||
boost/
|
||||
google/
|
||||
zlib/
|
||||
protobuf/
|
||||
cryptopp/
|
||||
|
||||
# misc
|
||||
Thumbs.db
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26228.4
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DepotDownloader", "DepotDownloader\DepotDownloader.csproj", "{39159C47-ACD3-449F-96CA-4F30C8ED147A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{39159C47-ACD3-449F-96CA-4F30C8ED147A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{39159C47-ACD3-449F-96CA-4F30C8ED147A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{39159C47-ACD3-449F-96CA-4F30C8ED147A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{39159C47-ACD3-449F-96CA-4F30C8ED147A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,90 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ProtoBuf;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.IO.IsolatedStorage;
|
||||
using System.Linq;
|
||||
using SteamKit2;
|
||||
using SteamKit2.Discovery;
|
||||
|
||||
namespace DepotDownloader
|
||||
{
|
||||
[ProtoContract]
|
||||
class AccountSettingsStore
|
||||
{
|
||||
[ProtoMember(1, IsRequired=false)]
|
||||
public Dictionary<string, byte[]> SentryData { get; private set; }
|
||||
|
||||
[ProtoMember(2, IsRequired = false)]
|
||||
public System.Collections.Concurrent.ConcurrentDictionary<string, int> ContentServerPenalty { get; private set; }
|
||||
|
||||
[ProtoMember(3, IsRequired = false)]
|
||||
public Dictionary<string, string> LoginKeys { get; private set; }
|
||||
|
||||
string FileName = null;
|
||||
|
||||
AccountSettingsStore()
|
||||
{
|
||||
SentryData = new Dictionary<string, byte[]>();
|
||||
ContentServerPenalty = new System.Collections.Concurrent.ConcurrentDictionary<string, int>();
|
||||
LoginKeys = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
static bool Loaded
|
||||
{
|
||||
get { return Instance != null; }
|
||||
}
|
||||
|
||||
public static AccountSettingsStore Instance = null;
|
||||
static readonly IsolatedStorageFile IsolatedStorage = IsolatedStorageFile.GetUserStoreForAssembly();
|
||||
|
||||
public static void LoadFromFile(string filename)
|
||||
{
|
||||
if (Loaded)
|
||||
throw new Exception("Config already loaded");
|
||||
|
||||
if (IsolatedStorage.FileExists(filename))
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var fs = IsolatedStorage.OpenFile(filename, FileMode.Open, FileAccess.Read))
|
||||
using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Decompress))
|
||||
{
|
||||
Instance = ProtoBuf.Serializer.Deserialize<AccountSettingsStore>(ds);
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Console.WriteLine("Failed to load account settings: {0}", ex.Message);
|
||||
Instance = new AccountSettingsStore();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Instance = new AccountSettingsStore();
|
||||
}
|
||||
|
||||
Instance.FileName = filename;
|
||||
}
|
||||
|
||||
public static void Save()
|
||||
{
|
||||
if (!Loaded)
|
||||
throw new Exception("Saved config before loading");
|
||||
|
||||
try
|
||||
{
|
||||
using (var fs = IsolatedStorage.OpenFile(Instance.FileName, FileMode.Create, FileAccess.Write))
|
||||
using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Compress))
|
||||
{
|
||||
ProtoBuf.Serializer.Serialize<AccountSettingsStore>(ds, Instance);
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
Console.WriteLine("Failed to save account settings: {0}", ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,196 +0,0 @@
|
||||
using SteamKit2;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DepotDownloader
|
||||
{
|
||||
/// <summary>
|
||||
/// CDNClientPool provides a pool of connections to CDN endpoints, requesting CDN tokens as needed
|
||||
/// </summary>
|
||||
class CDNClientPool
|
||||
{
|
||||
private const int ServerEndpointMinimumSize = 8;
|
||||
|
||||
private readonly Steam3Session steamSession;
|
||||
private readonly uint appId;
|
||||
public CDNClient CDNClient { get; }
|
||||
#if STEAMKIT_UNRELEASED
|
||||
public CDNClient.Server ProxyServer { get; private set; }
|
||||
#endif
|
||||
|
||||
private readonly ConcurrentStack<CDNClient.Server> activeConnectionPool;
|
||||
private readonly BlockingCollection<CDNClient.Server> availableServerEndpoints;
|
||||
|
||||
private readonly AutoResetEvent populatePoolEvent;
|
||||
private readonly Task monitorTask;
|
||||
private readonly CancellationTokenSource shutdownToken;
|
||||
public CancellationTokenSource ExhaustedToken { get; set; }
|
||||
|
||||
public CDNClientPool(Steam3Session steamSession, uint appId)
|
||||
{
|
||||
this.steamSession = steamSession;
|
||||
this.appId = appId;
|
||||
CDNClient = new CDNClient(steamSession.steamClient);
|
||||
|
||||
activeConnectionPool = new ConcurrentStack<CDNClient.Server>();
|
||||
availableServerEndpoints = new BlockingCollection<CDNClient.Server>();
|
||||
|
||||
populatePoolEvent = new AutoResetEvent(true);
|
||||
shutdownToken = new CancellationTokenSource();
|
||||
|
||||
monitorTask = Task.Factory.StartNew(ConnectionPoolMonitorAsync).Unwrap();
|
||||
}
|
||||
|
||||
public void Shutdown()
|
||||
{
|
||||
shutdownToken.Cancel();
|
||||
monitorTask.Wait();
|
||||
}
|
||||
|
||||
private async Task<IReadOnlyCollection<CDNClient.Server>> FetchBootstrapServerListAsync()
|
||||
{
|
||||
var backoffDelay = 0;
|
||||
|
||||
while (!shutdownToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cdnServers = await ContentServerDirectoryService.LoadAsync(this.steamSession.steamClient.Configuration, ContentDownloader.Config.CellID, shutdownToken.Token);
|
||||
if (cdnServers != null)
|
||||
{
|
||||
return cdnServers;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Failed to retrieve content server list: {0}", ex.Message);
|
||||
|
||||
if (ex is SteamKitWebRequestException e && e.StatusCode == (HttpStatusCode)429)
|
||||
{
|
||||
// If we're being throttled, add a delay to the next request
|
||||
backoffDelay = Math.Min(5, ++backoffDelay);
|
||||
await Task.Delay(TimeSpan.FromSeconds(backoffDelay));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private async Task ConnectionPoolMonitorAsync()
|
||||
{
|
||||
bool didPopulate = false;
|
||||
|
||||
while (!shutdownToken.IsCancellationRequested)
|
||||
{
|
||||
populatePoolEvent.WaitOne(TimeSpan.FromSeconds(1));
|
||||
|
||||
// We want the Steam session so we can take the CellID from the session and pass it through to the ContentServer Directory Service
|
||||
if (availableServerEndpoints.Count < ServerEndpointMinimumSize && steamSession.steamClient.IsConnected)
|
||||
{
|
||||
var servers = await FetchBootstrapServerListAsync().ConfigureAwait(false);
|
||||
|
||||
if (servers == null || servers.Count == 0)
|
||||
{
|
||||
ExhaustedToken?.Cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
#if STEAMKIT_UNRELEASED
|
||||
ProxyServer = servers.Where(x => x.UseAsProxy).FirstOrDefault();
|
||||
#endif
|
||||
|
||||
var weightedCdnServers = servers
|
||||
.Where(server =>
|
||||
{
|
||||
#if STEAMKIT_UNRELEASED
|
||||
var isEligibleForApp = server.AllowedAppIds == null || server.AllowedAppIds.Contains(appId);
|
||||
return isEligibleForApp && (server.Type == "SteamCache" || server.Type == "CDN");
|
||||
#else
|
||||
return server.Type == "SteamCache" || server.Type == "CDN";
|
||||
#endif
|
||||
})
|
||||
.Select(server =>
|
||||
{
|
||||
AccountSettingsStore.Instance.ContentServerPenalty.TryGetValue(server.Host, out var penalty);
|
||||
|
||||
return (server, penalty);
|
||||
})
|
||||
.OrderBy(pair => pair.penalty).ThenBy(pair => pair.server.WeightedLoad);
|
||||
|
||||
foreach (var (server, weight) in weightedCdnServers)
|
||||
{
|
||||
for (var i = 0; i < server.NumEntries; i++)
|
||||
{
|
||||
availableServerEndpoints.Add(server);
|
||||
}
|
||||
}
|
||||
|
||||
didPopulate = true;
|
||||
}
|
||||
else if (availableServerEndpoints.Count == 0 && !steamSession.steamClient.IsConnected && didPopulate)
|
||||
{
|
||||
ExhaustedToken?.Cancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CDNClient.Server BuildConnection(CancellationToken token)
|
||||
{
|
||||
if (availableServerEndpoints.Count < ServerEndpointMinimumSize)
|
||||
{
|
||||
populatePoolEvent.Set();
|
||||
}
|
||||
|
||||
return availableServerEndpoints.Take(token);
|
||||
}
|
||||
|
||||
public CDNClient.Server GetConnection(CancellationToken token)
|
||||
{
|
||||
if (!activeConnectionPool.TryPop(out var connection))
|
||||
{
|
||||
connection = BuildConnection(token);
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
public async Task<string> AuthenticateConnection(uint appId, uint depotId, CDNClient.Server server)
|
||||
{
|
||||
var host = steamSession.ResolveCDNTopLevelHost(server.Host);
|
||||
var cdnKey = $"{depotId:D}:{host}";
|
||||
|
||||
steamSession.RequestCDNAuthToken(appId, depotId, host, cdnKey);
|
||||
|
||||
if (steamSession.CDNAuthTokens.TryGetValue(cdnKey, out var authTokenCallbackPromise))
|
||||
{
|
||||
var result = await authTokenCallbackPromise.Task;
|
||||
return result.Token;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Failed to retrieve CDN token for server {server.Host} depot {depotId}");
|
||||
}
|
||||
}
|
||||
|
||||
public void ReturnConnection(CDNClient.Server server)
|
||||
{
|
||||
if (server == null) return;
|
||||
|
||||
activeConnectionPool.Push(server);
|
||||
}
|
||||
|
||||
public void ReturnBrokenConnection(CDNClient.Server server)
|
||||
{
|
||||
if (server == null) return;
|
||||
|
||||
// Broken connections are not returned to the pool
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,58 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ProtoBuf;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace DepotDownloader
|
||||
{
|
||||
[ProtoContract]
|
||||
class DepotConfigStore
|
||||
{
|
||||
[ProtoMember(1)]
|
||||
public Dictionary<uint, ulong> InstalledManifestIDs { get; private set; }
|
||||
|
||||
string FileName = null;
|
||||
|
||||
DepotConfigStore()
|
||||
{
|
||||
InstalledManifestIDs = new Dictionary<uint, ulong>();
|
||||
}
|
||||
|
||||
static bool Loaded
|
||||
{
|
||||
get { return Instance != null; }
|
||||
}
|
||||
|
||||
public static DepotConfigStore Instance = null;
|
||||
|
||||
public static void LoadFromFile(string filename)
|
||||
{
|
||||
if (Loaded)
|
||||
throw new Exception("Config already loaded");
|
||||
|
||||
if (File.Exists(filename))
|
||||
{
|
||||
using (FileStream fs = File.Open(filename, FileMode.Open))
|
||||
using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Decompress))
|
||||
Instance = ProtoBuf.Serializer.Deserialize<DepotConfigStore>(ds);
|
||||
}
|
||||
else
|
||||
{
|
||||
Instance = new DepotConfigStore();
|
||||
}
|
||||
|
||||
Instance.FileName = filename;
|
||||
}
|
||||
|
||||
public static void Save()
|
||||
{
|
||||
if (!Loaded)
|
||||
throw new Exception("Saved config before loading");
|
||||
|
||||
using (FileStream fs = File.Open(Instance.FileName, FileMode.Create))
|
||||
using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Compress))
|
||||
ProtoBuf.Serializer.Serialize<DepotConfigStore>(ds, Instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="protobuf-net" Version="3.0.73" />
|
||||
<PackageReference Include="SteamKit2" Version="2.3.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,33 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace DepotDownloader
|
||||
{
|
||||
class DownloadConfig
|
||||
{
|
||||
public int CellID { get; set; }
|
||||
public bool DownloadAllPlatforms { get; set; }
|
||||
public bool DownloadAllLanguages { get; set; }
|
||||
public bool DownloadManifestOnly { get; set; }
|
||||
public string InstallDirectory { get; set; }
|
||||
|
||||
public bool UsingFileList { get; set; }
|
||||
public List<string> FilesToDownload { get; set; }
|
||||
public List<Regex> FilesToDownloadRegex { get; set; }
|
||||
|
||||
public bool UsingExclusionList { get; set; }
|
||||
|
||||
public string BetaPassword { get; set; }
|
||||
|
||||
public bool VerifyAll { get; set; }
|
||||
|
||||
public int MaxServers { get; set; }
|
||||
public int MaxDownloads { get; set; }
|
||||
|
||||
public string SuppliedPassword { get; set; }
|
||||
public bool RememberPassword { get; set; }
|
||||
|
||||
// A Steam LoginID to allow multiple concurrent connections
|
||||
public uint? LoginID {get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,416 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using SteamKit2;
|
||||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Linq;
|
||||
|
||||
namespace DepotDownloader
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static int Main( string[] args )
|
||||
=> MainAsync( args ).GetAwaiter().GetResult();
|
||||
|
||||
static async Task<int> MainAsync( string[] args )
|
||||
{
|
||||
if ( args.Length == 0 )
|
||||
{
|
||||
PrintUsage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
DebugLog.Enabled = false;
|
||||
|
||||
AccountSettingsStore.LoadFromFile( "account.config" );
|
||||
|
||||
#region Common Options
|
||||
|
||||
if ( HasParameter( args, "-debug" ) )
|
||||
{
|
||||
DebugLog.Enabled = true;
|
||||
DebugLog.AddListener( ( category, message ) =>
|
||||
{
|
||||
Console.WriteLine( "[{0}] {1}", category, message );
|
||||
});
|
||||
}
|
||||
|
||||
string username = GetParameter<string>( args, "-username" ) ?? GetParameter<string>( args, "-user" );
|
||||
string password = GetParameter<string>( args, "-password" ) ?? GetParameter<string>( args, "-pass" );
|
||||
ContentDownloader.Config.RememberPassword = HasParameter( args, "-remember-password" );
|
||||
|
||||
ContentDownloader.Config.DownloadManifestOnly = HasParameter( args, "-manifest-only" );
|
||||
|
||||
int cellId = GetParameter<int>( args, "-cellid", -1 );
|
||||
if ( cellId == -1 )
|
||||
{
|
||||
cellId = 0;
|
||||
}
|
||||
|
||||
ContentDownloader.Config.CellID = cellId;
|
||||
|
||||
string fileList = GetParameter<string>( args, "-filelist" );
|
||||
string[] files = null;
|
||||
|
||||
if ( fileList != null )
|
||||
{
|
||||
try
|
||||
{
|
||||
string fileListData = File.ReadAllText(fileList);
|
||||
files = fileListData.Split( new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries );
|
||||
|
||||
ContentDownloader.Config.UsingFileList = true;
|
||||
ContentDownloader.Config.FilesToDownload = new List<string>();
|
||||
ContentDownloader.Config.FilesToDownloadRegex = new List<Regex>();
|
||||
|
||||
var isWindows = RuntimeInformation.IsOSPlatform( OSPlatform.Windows );
|
||||
foreach ( var fileEntry in files )
|
||||
{
|
||||
try
|
||||
{
|
||||
string fileEntryProcessed;
|
||||
if ( isWindows )
|
||||
{
|
||||
// On Windows, ensure that forward slashes can match either forward or backslashes in depot paths
|
||||
fileEntryProcessed = fileEntry.Replace( "/", "[\\\\|/]" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// On other systems, treat / normally
|
||||
fileEntryProcessed = fileEntry;
|
||||
}
|
||||
Regex rgx = new Regex( fileEntryProcessed, RegexOptions.Compiled | RegexOptions.IgnoreCase );
|
||||
ContentDownloader.Config.FilesToDownloadRegex.Add( rgx );
|
||||
}
|
||||
catch
|
||||
{
|
||||
// For anything that can't be processed as a Regex, allow both forward and backward slashes to match
|
||||
// on Windows
|
||||
if( isWindows )
|
||||
{
|
||||
ContentDownloader.Config.FilesToDownload.Add( fileEntry.Replace( "/", "\\" ) );
|
||||
}
|
||||
ContentDownloader.Config.FilesToDownload.Add( fileEntry );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine( "Using filelist: '{0}'.", fileList );
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine( "Warning: Unable to load filelist: {0}", ex.ToString() );
|
||||
}
|
||||
}
|
||||
|
||||
ContentDownloader.Config.InstallDirectory = GetParameter<string>( args, "-dir" );
|
||||
|
||||
ContentDownloader.Config.VerifyAll = HasParameter( args, "-verify-all" ) || HasParameter( args, "-verify_all" ) || HasParameter( args, "-validate" );
|
||||
ContentDownloader.Config.MaxServers = GetParameter<int>( args, "-max-servers", 20 );
|
||||
ContentDownloader.Config.MaxDownloads = GetParameter<int>( args, "-max-downloads", 8 );
|
||||
ContentDownloader.Config.MaxServers = Math.Max( ContentDownloader.Config.MaxServers, ContentDownloader.Config.MaxDownloads );
|
||||
ContentDownloader.Config.LoginID = HasParameter( args, "-loginid" ) ? (uint?)GetParameter<uint>( args, "-loginid" ) : null;
|
||||
|
||||
#endregion
|
||||
|
||||
uint appId = GetParameter<uint>( args, "-app", ContentDownloader.INVALID_APP_ID );
|
||||
if ( appId == ContentDownloader.INVALID_APP_ID )
|
||||
{
|
||||
Console.WriteLine( "Error: -app not specified!" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
ulong pubFile = GetParameter<ulong>( args, "-pubfile", ContentDownloader.INVALID_MANIFEST_ID );
|
||||
ulong ugcId = GetParameter<ulong>( args, "-ugc", ContentDownloader.INVALID_MANIFEST_ID );
|
||||
if ( pubFile != ContentDownloader.INVALID_MANIFEST_ID )
|
||||
{
|
||||
#region Pubfile Downloading
|
||||
|
||||
if ( InitializeSteam( username, password ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
await ContentDownloader.DownloadPubfileAsync( appId, pubFile ).ConfigureAwait( false );
|
||||
}
|
||||
catch ( Exception ex ) when (
|
||||
ex is ContentDownloaderException
|
||||
|| ex is OperationCanceledException )
|
||||
{
|
||||
Console.WriteLine( ex.Message );
|
||||
return 1;
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
Console.WriteLine( "Download failed to due to an unhandled exception: {0}", e.Message );
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
ContentDownloader.ShutdownSteam3();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine( "Error: InitializeSteam failed" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
else if ( ugcId != ContentDownloader.INVALID_MANIFEST_ID )
|
||||
{
|
||||
#region UGC Downloading
|
||||
|
||||
if ( InitializeSteam( username, password ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
await ContentDownloader.DownloadUGCAsync( appId, ugcId ).ConfigureAwait( false );
|
||||
}
|
||||
catch ( Exception ex ) when (
|
||||
ex is ContentDownloaderException
|
||||
|| ex is OperationCanceledException )
|
||||
{
|
||||
Console.WriteLine( ex.Message );
|
||||
return 1;
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
Console.WriteLine( "Download failed to due to an unhandled exception: {0}", e.Message );
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
ContentDownloader.ShutdownSteam3();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine( "Error: InitializeSteam failed" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
else
|
||||
{
|
||||
#region App downloading
|
||||
|
||||
string branch = GetParameter<string>( args, "-branch" ) ?? GetParameter<string>( args, "-beta" ) ?? ContentDownloader.DEFAULT_BRANCH;
|
||||
ContentDownloader.Config.BetaPassword = GetParameter<string>( args, "-betapassword" );
|
||||
|
||||
ContentDownloader.Config.DownloadAllPlatforms = HasParameter( args, "-all-platforms" );
|
||||
string os = GetParameter<string>( args, "-os", null );
|
||||
|
||||
if ( ContentDownloader.Config.DownloadAllPlatforms && !String.IsNullOrEmpty( os ) )
|
||||
{
|
||||
Console.WriteLine("Error: Cannot specify -os when -all-platforms is specified.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
string arch = GetParameter<string>( args, "-osarch", null );
|
||||
|
||||
ContentDownloader.Config.DownloadAllLanguages = HasParameter( args, "-all-languages" );
|
||||
string language = GetParameter<string>( args, "-language", null );
|
||||
|
||||
if ( ContentDownloader.Config.DownloadAllLanguages && !String.IsNullOrEmpty( language ) )
|
||||
{
|
||||
Console.WriteLine( "Error: Cannot specify -language when -all-languages is specified." );
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool lv = HasParameter( args, "-lowviolence" );
|
||||
|
||||
List<(uint, ulong)> depotManifestIds = new List<(uint, ulong)>();
|
||||
bool isUGC = false;
|
||||
|
||||
List<uint> depotIdList = GetParameterList<uint>( args, "-depot" );
|
||||
List<ulong> manifestIdList = GetParameterList<ulong>( args, "-manifest" );
|
||||
if ( manifestIdList.Count > 0 )
|
||||
{
|
||||
if ( depotIdList.Count != manifestIdList.Count )
|
||||
{
|
||||
Console.WriteLine( "Error: -manifest requires one id for every -depot specified" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
var zippedDepotManifest = depotIdList.Zip( manifestIdList, ( depotId, manifestId ) => ( depotId, manifestId ) );
|
||||
depotManifestIds.AddRange( zippedDepotManifest );
|
||||
}
|
||||
else
|
||||
{
|
||||
depotManifestIds.AddRange( depotIdList.Select( depotId => ( depotId, ContentDownloader.INVALID_MANIFEST_ID ) ) );
|
||||
}
|
||||
|
||||
if ( InitializeSteam( username, password ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
await ContentDownloader.DownloadAppAsync( appId, depotManifestIds, branch, os, arch, language, lv, isUGC ).ConfigureAwait( false );
|
||||
}
|
||||
catch ( Exception ex ) when (
|
||||
ex is ContentDownloaderException
|
||||
|| ex is OperationCanceledException )
|
||||
{
|
||||
Console.WriteLine( ex.Message );
|
||||
return 1;
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
Console.WriteLine( "Download failed to due to an unhandled exception: {0}", e.Message );
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
ContentDownloader.ShutdownSteam3();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine( "Error: InitializeSteam failed" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool InitializeSteam( string username, string password )
|
||||
{
|
||||
if ( username != null && password == null && ( !ContentDownloader.Config.RememberPassword || !AccountSettingsStore.Instance.LoginKeys.ContainsKey( username ) ) )
|
||||
{
|
||||
do
|
||||
{
|
||||
Console.Write( "Enter account password for \"{0}\": ", username );
|
||||
if ( Console.IsInputRedirected )
|
||||
{
|
||||
password = Console.ReadLine();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Avoid console echoing of password
|
||||
password = Util.ReadPassword();
|
||||
}
|
||||
Console.WriteLine();
|
||||
} while ( String.Empty == password );
|
||||
}
|
||||
else if ( username == null )
|
||||
{
|
||||
Console.WriteLine( "No username given. Using anonymous account with dedicated server subscription." );
|
||||
}
|
||||
|
||||
// capture the supplied password in case we need to re-use it after checking the login key
|
||||
ContentDownloader.Config.SuppliedPassword = password;
|
||||
|
||||
return ContentDownloader.InitializeSteam3( username, password );
|
||||
}
|
||||
|
||||
static int IndexOfParam( string[] args, string param )
|
||||
{
|
||||
for ( int x = 0; x < args.Length; ++x )
|
||||
{
|
||||
if ( args[ x ].Equals( param, StringComparison.OrdinalIgnoreCase ) )
|
||||
return x;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
static bool HasParameter( string[] args, string param )
|
||||
{
|
||||
return IndexOfParam( args, param ) > -1;
|
||||
}
|
||||
|
||||
static T GetParameter<T>( string[] args, string param, T defaultValue = default( T ) )
|
||||
{
|
||||
int index = IndexOfParam( args, param );
|
||||
|
||||
if ( index == -1 || index == ( args.Length - 1 ) )
|
||||
return defaultValue;
|
||||
|
||||
string strParam = args[ index + 1 ];
|
||||
|
||||
var converter = TypeDescriptor.GetConverter( typeof( T ) );
|
||||
if ( converter != null )
|
||||
{
|
||||
return ( T )converter.ConvertFromString( strParam );
|
||||
}
|
||||
|
||||
return default( T );
|
||||
}
|
||||
|
||||
static List<T> GetParameterList<T>(string[] args, string param)
|
||||
{
|
||||
List<T> list = new List<T>();
|
||||
int index = IndexOfParam(args, param);
|
||||
|
||||
if (index == -1 || index == (args.Length - 1))
|
||||
return list;
|
||||
|
||||
index++;
|
||||
|
||||
while (index < args.Length)
|
||||
{
|
||||
string strParam = args[index];
|
||||
|
||||
if (strParam[0] == '-') break;
|
||||
|
||||
var converter = TypeDescriptor.GetConverter(typeof(T));
|
||||
if (converter != null)
|
||||
{
|
||||
list.Add((T)converter.ConvertFromString(strParam));
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static void PrintUsage()
|
||||
{
|
||||
Console.WriteLine();
|
||||
Console.WriteLine( "Usage - downloading one or all depots for an app:" );
|
||||
Console.WriteLine( "\tdepotdownloader -app <id> [-depot <id> [-manifest <id>]]" );
|
||||
Console.WriteLine( "\t\t[-username <username> [-password <password>]] [other options]" );
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Usage - downloading a workshop item using pubfile id");
|
||||
Console.WriteLine( "\tdepotdownloader -app <id> -pubfile <id> [-username <username> [-password <password>]]" );
|
||||
Console.WriteLine("Usage - downloading a workshop item using ugc id");
|
||||
Console.WriteLine("\tdepotdownloader -app <id> -ugc <id> [-username <username> [-password <password>]]");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine( "Parameters:" );
|
||||
Console.WriteLine( "\t-app <#>\t\t\t\t- the AppID to download." );
|
||||
Console.WriteLine( "\t-depot <#>\t\t\t\t- the DepotID to download." );
|
||||
Console.WriteLine( "\t-manifest <id>\t\t\t- manifest id of content to download (requires -depot, default: current for branch)." );
|
||||
Console.WriteLine( "\t-beta <branchname>\t\t\t- download from specified branch if available (default: Public)." );
|
||||
Console.WriteLine( "\t-betapassword <pass>\t\t- branch password if applicable." );
|
||||
Console.WriteLine( "\t-all-platforms\t\t\t- downloads all platform-specific depots when -app is used." );
|
||||
Console.WriteLine( "\t-os <os>\t\t\t\t- the operating system for which to download the game (windows, macos or linux, default: OS the program is currently running on)" );
|
||||
Console.WriteLine( "\t-osarch <arch>\t\t\t\t- the architecture for which to download the game (32 or 64, default: the host's architecture)" );
|
||||
Console.WriteLine( "\t-all-languages\t\t\t\t- download all language-specific depots when -app is used." );
|
||||
Console.WriteLine( "\t-language <lang>\t\t\t\t- the language for which to download the game (default: english)" );
|
||||
Console.WriteLine( "\t-lowviolence\t\t\t\t- download low violence depots when -app is used." );
|
||||
Console.WriteLine();
|
||||
Console.WriteLine( "\t-ugc <#>\t\t\t\t- the UGC ID to download." );
|
||||
Console.WriteLine( "\t-pubfile <#>\t\t\t- the PublishedFileId to download. (Will automatically resolve to UGC id)" );
|
||||
Console.WriteLine();
|
||||
Console.WriteLine( "\t-username <user>\t\t- the username of the account to login to for restricted content.");
|
||||
Console.WriteLine( "\t-password <pass>\t\t- the password of the account to login to for restricted content." );
|
||||
Console.WriteLine( "\t-remember-password\t\t- if set, remember the password for subsequent logins of this user." );
|
||||
Console.WriteLine();
|
||||
Console.WriteLine( "\t-dir <installdir>\t\t- the directory in which to place downloaded files." );
|
||||
Console.WriteLine( "\t-filelist <file.txt>\t- a list of files to download (from the manifest). Can optionally use regex to download only certain files." );
|
||||
Console.WriteLine( "\t-validate\t\t\t\t- Include checksum verification of files already downloaded" );
|
||||
Console.WriteLine();
|
||||
Console.WriteLine( "\t-manifest-only\t\t\t- downloads a human readable manifest for any depots that would be downloaded." );
|
||||
Console.WriteLine( "\t-cellid <#>\t\t\t\t- the overridden CellID of the content server to download from." );
|
||||
Console.WriteLine( "\t-max-servers <#>\t\t- maximum number of content servers to use. (default: 20)." );
|
||||
Console.WriteLine( "\t-max-downloads <#>\t\t- maximum number of chunks to download concurrently. (default: 8)." );
|
||||
Console.WriteLine( "\t-loginid <#>\t\t- a unique 32-bit integer Steam LogonID in decimal, required if running multiple instances of DepotDownloader concurrently." );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle( "DepotDownloader" )]
|
||||
[assembly: AssemblyDescription("Steam Downloading Utility")]
|
||||
[assembly: AssemblyConfiguration( "" )]
|
||||
[assembly: AssemblyCompany("SteamRE Team")]
|
||||
[assembly: AssemblyProduct( "DepotDownloader" )]
|
||||
[assembly: AssemblyCopyright("Copyright © SteamRE Team 2017")]
|
||||
[assembly: AssemblyTrademark( "" )]
|
||||
[assembly: AssemblyCulture( "" )]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible( false )]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid( "df2ab32a-923c-46e3-a1b4-c901ee92ec94" )]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("2.3.0.0")]
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"profiles": {
|
||||
"DepotDownloader": {
|
||||
"commandName": "Project"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
|
||||
using ProtoBuf;
|
||||
using SteamKit2;
|
||||
|
||||
namespace DepotDownloader
|
||||
{
|
||||
[ProtoContract()]
|
||||
class ProtoManifest
|
||||
{
|
||||
// Proto ctor
|
||||
private ProtoManifest()
|
||||
{
|
||||
Files = new List<FileData>();
|
||||
}
|
||||
|
||||
public ProtoManifest(DepotManifest sourceManifest, ulong id) : this()
|
||||
{
|
||||
sourceManifest.Files.ForEach(f => Files.Add(new FileData(f)));
|
||||
ID = id;
|
||||
CreationTime = sourceManifest.CreationTime;
|
||||
}
|
||||
|
||||
[ProtoContract()]
|
||||
public class FileData
|
||||
{
|
||||
// Proto ctor
|
||||
private FileData()
|
||||
{
|
||||
Chunks = new List<ChunkData>();
|
||||
}
|
||||
|
||||
public FileData(DepotManifest.FileData sourceData) : this()
|
||||
{
|
||||
FileName = sourceData.FileName;
|
||||
sourceData.Chunks.ForEach(c => Chunks.Add(new ChunkData(c)));
|
||||
Flags = sourceData.Flags;
|
||||
TotalSize = sourceData.TotalSize;
|
||||
FileHash = sourceData.FileHash;
|
||||
}
|
||||
|
||||
[ProtoMember(1)]
|
||||
public string FileName { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the chunks that this file is composed of.
|
||||
/// </summary>
|
||||
[ProtoMember(2)]
|
||||
public List<ChunkData> Chunks { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file flags
|
||||
/// </summary>
|
||||
[ProtoMember(3)]
|
||||
public EDepotFileFlag Flags { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total size of this file.
|
||||
/// </summary>
|
||||
[ProtoMember(4)]
|
||||
public ulong TotalSize { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the hash of this file.
|
||||
/// </summary>
|
||||
[ProtoMember(5)]
|
||||
public byte[] FileHash { get; private set; }
|
||||
}
|
||||
|
||||
[ProtoContract(SkipConstructor = true)]
|
||||
public class ChunkData
|
||||
{
|
||||
public ChunkData(DepotManifest.ChunkData sourceChunk)
|
||||
{
|
||||
ChunkID = sourceChunk.ChunkID;
|
||||
Checksum = sourceChunk.Checksum;
|
||||
Offset = sourceChunk.Offset;
|
||||
CompressedLength = sourceChunk.CompressedLength;
|
||||
UncompressedLength = sourceChunk.UncompressedLength;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SHA-1 hash chunk id.
|
||||
/// </summary>
|
||||
[ProtoMember(1)]
|
||||
public byte[] ChunkID { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the expected Adler32 checksum of this chunk.
|
||||
/// </summary>
|
||||
[ProtoMember(2)]
|
||||
public byte[] Checksum { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the chunk offset.
|
||||
/// </summary>
|
||||
[ProtoMember(3)]
|
||||
public ulong Offset { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the compressed length of this chunk.
|
||||
/// </summary>
|
||||
[ProtoMember(4)]
|
||||
public uint CompressedLength { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the decompressed length of this chunk.
|
||||
/// </summary>
|
||||
[ProtoMember(5)]
|
||||
public uint UncompressedLength { get; private set; }
|
||||
}
|
||||
|
||||
[ProtoMember(1)]
|
||||
public List<FileData> Files { get; private set; }
|
||||
|
||||
[ProtoMember(2)]
|
||||
public ulong ID { get; private set; }
|
||||
|
||||
[ProtoMember(3)]
|
||||
public DateTime CreationTime { get; private set; }
|
||||
|
||||
public static ProtoManifest LoadFromFile(string filename, out byte[] checksum)
|
||||
{
|
||||
if (!File.Exists(filename))
|
||||
{
|
||||
checksum = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
using (FileStream fs = File.Open(filename, FileMode.Open))
|
||||
using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Decompress))
|
||||
ds.CopyTo(ms);
|
||||
|
||||
checksum = Util.SHAHash(ms.ToArray());
|
||||
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
return ProtoBuf.Serializer.Deserialize<ProtoManifest>(ms);
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveToFile(string filename, out byte[] checksum)
|
||||
{
|
||||
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
ProtoBuf.Serializer.Serialize<ProtoManifest>(ms, this);
|
||||
|
||||
checksum = Util.SHAHash(ms.ToArray());
|
||||
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
using (FileStream fs = File.Open(filename, FileMode.Create))
|
||||
using (DeflateStream ds = new DeflateStream(fs, CompressionMode.Compress))
|
||||
ms.CopyTo(ds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,771 +0,0 @@
|
||||
using SteamKit2;
|
||||
using SteamKit2.Internal;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DepotDownloader
|
||||
{
|
||||
|
||||
class Steam3Session
|
||||
{
|
||||
public class Credentials
|
||||
{
|
||||
public bool LoggedOn { get; set; }
|
||||
public ulong SessionToken { get; set; }
|
||||
|
||||
public bool IsValid
|
||||
{
|
||||
get { return LoggedOn; }
|
||||
}
|
||||
}
|
||||
|
||||
public ReadOnlyCollection<SteamApps.LicenseListCallback.License> Licenses
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Dictionary<uint, byte[]> AppTickets { get; private set; }
|
||||
public Dictionary<uint, ulong> AppTokens { get; private set; }
|
||||
public Dictionary<uint, ulong> PackageTokens { get; private set; }
|
||||
public Dictionary<uint, byte[]> DepotKeys { get; private set; }
|
||||
public ConcurrentDictionary<string, TaskCompletionSource<SteamApps.CDNAuthTokenCallback>> CDNAuthTokens { get; private set; }
|
||||
public Dictionary<uint, SteamApps.PICSProductInfoCallback.PICSProductInfo> AppInfo { get; private set; }
|
||||
public Dictionary<uint, SteamApps.PICSProductInfoCallback.PICSProductInfo> PackageInfo { get; private set; }
|
||||
public Dictionary<string, byte[]> AppBetaPasswords { get; private set; }
|
||||
|
||||
public SteamClient steamClient;
|
||||
public SteamUser steamUser;
|
||||
SteamApps steamApps;
|
||||
SteamCloud steamCloud;
|
||||
SteamUnifiedMessages.UnifiedService<IPublishedFile> steamPublishedFile;
|
||||
|
||||
CallbackManager callbacks;
|
||||
|
||||
bool authenticatedUser;
|
||||
bool bConnected;
|
||||
bool bConnecting;
|
||||
bool bAborted;
|
||||
bool bExpectingDisconnectRemote;
|
||||
bool bDidDisconnect;
|
||||
bool bDidReceiveLoginKey;
|
||||
int connectionBackoff;
|
||||
int seq; // more hack fixes
|
||||
DateTime connectTime;
|
||||
|
||||
// input
|
||||
SteamUser.LogOnDetails logonDetails;
|
||||
|
||||
// output
|
||||
Credentials credentials;
|
||||
|
||||
static readonly TimeSpan STEAM3_TIMEOUT = TimeSpan.FromSeconds( 30 );
|
||||
|
||||
|
||||
public Steam3Session( SteamUser.LogOnDetails details )
|
||||
{
|
||||
this.logonDetails = details;
|
||||
|
||||
this.authenticatedUser = details.Username != null;
|
||||
this.credentials = new Credentials();
|
||||
this.bConnected = false;
|
||||
this.bConnecting = false;
|
||||
this.bAborted = false;
|
||||
this.bExpectingDisconnectRemote = false;
|
||||
this.bDidDisconnect = false;
|
||||
this.bDidReceiveLoginKey = false;
|
||||
this.seq = 0;
|
||||
|
||||
this.AppTickets = new Dictionary<uint, byte[]>();
|
||||
this.AppTokens = new Dictionary<uint, ulong>();
|
||||
this.PackageTokens = new Dictionary<uint, ulong>();
|
||||
this.DepotKeys = new Dictionary<uint, byte[]>();
|
||||
this.CDNAuthTokens = new ConcurrentDictionary<string, TaskCompletionSource<SteamApps.CDNAuthTokenCallback>>();
|
||||
this.AppInfo = new Dictionary<uint, SteamApps.PICSProductInfoCallback.PICSProductInfo>();
|
||||
this.PackageInfo = new Dictionary<uint, SteamApps.PICSProductInfoCallback.PICSProductInfo>();
|
||||
this.AppBetaPasswords = new Dictionary<string, byte[]>();
|
||||
|
||||
this.steamClient = new SteamClient();
|
||||
|
||||
this.steamUser = this.steamClient.GetHandler<SteamUser>();
|
||||
this.steamApps = this.steamClient.GetHandler<SteamApps>();
|
||||
this.steamCloud = this.steamClient.GetHandler<SteamCloud>();
|
||||
var steamUnifiedMessages = this.steamClient.GetHandler<SteamUnifiedMessages>();
|
||||
this.steamPublishedFile = steamUnifiedMessages.CreateService<IPublishedFile>();
|
||||
|
||||
this.callbacks = new CallbackManager( this.steamClient );
|
||||
|
||||
this.callbacks.Subscribe<SteamClient.ConnectedCallback>( ConnectedCallback );
|
||||
this.callbacks.Subscribe<SteamClient.DisconnectedCallback>( DisconnectedCallback );
|
||||
this.callbacks.Subscribe<SteamUser.LoggedOnCallback>( LogOnCallback );
|
||||
this.callbacks.Subscribe<SteamUser.SessionTokenCallback>( SessionTokenCallback );
|
||||
this.callbacks.Subscribe<SteamApps.LicenseListCallback>( LicenseListCallback );
|
||||
this.callbacks.Subscribe<SteamUser.UpdateMachineAuthCallback>( UpdateMachineAuthCallback );
|
||||
this.callbacks.Subscribe<SteamUser.LoginKeyCallback>( LoginKeyCallback );
|
||||
|
||||
Console.Write( "Connecting to Steam3..." );
|
||||
|
||||
if ( authenticatedUser )
|
||||
{
|
||||
FileInfo fi = new FileInfo( String.Format( "{0}.sentryFile", logonDetails.Username ) );
|
||||
if ( AccountSettingsStore.Instance.SentryData != null && AccountSettingsStore.Instance.SentryData.ContainsKey( logonDetails.Username ) )
|
||||
{
|
||||
logonDetails.SentryFileHash = Util.SHAHash( AccountSettingsStore.Instance.SentryData[ logonDetails.Username ] );
|
||||
}
|
||||
else if ( fi.Exists && fi.Length > 0 )
|
||||
{
|
||||
var sentryData = File.ReadAllBytes( fi.FullName );
|
||||
logonDetails.SentryFileHash = Util.SHAHash( sentryData );
|
||||
AccountSettingsStore.Instance.SentryData[ logonDetails.Username ] = sentryData;
|
||||
AccountSettingsStore.Save();
|
||||
}
|
||||
}
|
||||
|
||||
Connect();
|
||||
}
|
||||
|
||||
public delegate bool WaitCondition();
|
||||
private object steamLock = new object();
|
||||
|
||||
public bool WaitUntilCallback( Action submitter, WaitCondition waiter )
|
||||
{
|
||||
while ( !bAborted && !waiter() )
|
||||
{
|
||||
lock (steamLock)
|
||||
{
|
||||
submitter();
|
||||
}
|
||||
|
||||
int seq = this.seq;
|
||||
do
|
||||
{
|
||||
lock (steamLock)
|
||||
{
|
||||
WaitForCallbacks();
|
||||
}
|
||||
}
|
||||
while ( !bAborted && this.seq == seq && !waiter() );
|
||||
}
|
||||
|
||||
return bAborted;
|
||||
}
|
||||
|
||||
public Credentials WaitForCredentials()
|
||||
{
|
||||
if ( credentials.IsValid || bAborted )
|
||||
return credentials;
|
||||
|
||||
WaitUntilCallback( () => { }, () => { return credentials.IsValid; } );
|
||||
|
||||
return credentials;
|
||||
}
|
||||
|
||||
public void RequestAppInfo( uint appId, bool bForce = false )
|
||||
{
|
||||
if ( ( AppInfo.ContainsKey( appId ) && !bForce ) || bAborted )
|
||||
return;
|
||||
|
||||
bool completed = false;
|
||||
Action<SteamApps.PICSTokensCallback> cbMethodTokens = ( appTokens ) =>
|
||||
{
|
||||
completed = true;
|
||||
if ( appTokens.AppTokensDenied.Contains( appId ) )
|
||||
{
|
||||
Console.WriteLine( "Insufficient privileges to get access token for app {0}", appId );
|
||||
}
|
||||
|
||||
foreach ( var token_dict in appTokens.AppTokens )
|
||||
{
|
||||
this.AppTokens[ token_dict.Key ] = token_dict.Value;
|
||||
}
|
||||
};
|
||||
|
||||
WaitUntilCallback( () =>
|
||||
{
|
||||
callbacks.Subscribe( steamApps.PICSGetAccessTokens( new List<uint>() { appId }, new List<uint>() { } ), cbMethodTokens );
|
||||
}, () => { return completed; } );
|
||||
|
||||
completed = false;
|
||||
Action<SteamApps.PICSProductInfoCallback> cbMethod = ( appInfo ) =>
|
||||
{
|
||||
completed = !appInfo.ResponsePending;
|
||||
|
||||
foreach ( var app_value in appInfo.Apps )
|
||||
{
|
||||
var app = app_value.Value;
|
||||
|
||||
Console.WriteLine( "Got AppInfo for {0}", app.ID );
|
||||
AppInfo[ app.ID ] = app;
|
||||
}
|
||||
|
||||
foreach ( var app in appInfo.UnknownApps )
|
||||
{
|
||||
AppInfo[ app ] = null;
|
||||
}
|
||||
};
|
||||
|
||||
SteamApps.PICSRequest request = new SteamApps.PICSRequest( appId );
|
||||
if ( AppTokens.ContainsKey( appId ) )
|
||||
{
|
||||
request.AccessToken = AppTokens[ appId ];
|
||||
request.Public = false;
|
||||
}
|
||||
|
||||
WaitUntilCallback( () =>
|
||||
{
|
||||
callbacks.Subscribe( steamApps.PICSGetProductInfo( new List<SteamApps.PICSRequest>() { request }, new List<SteamApps.PICSRequest>() { } ), cbMethod );
|
||||
}, () => { return completed; } );
|
||||
}
|
||||
|
||||
public void RequestPackageInfo( IEnumerable<uint> packageIds )
|
||||
{
|
||||
List<uint> packages = packageIds.ToList();
|
||||
packages.RemoveAll( pid => PackageInfo.ContainsKey( pid ) );
|
||||
|
||||
if ( packages.Count == 0 || bAborted )
|
||||
return;
|
||||
|
||||
bool completed = false;
|
||||
Action<SteamApps.PICSProductInfoCallback> cbMethod = ( packageInfo ) =>
|
||||
{
|
||||
completed = !packageInfo.ResponsePending;
|
||||
|
||||
foreach ( var package_value in packageInfo.Packages )
|
||||
{
|
||||
var package = package_value.Value;
|
||||
PackageInfo[ package.ID ] = package;
|
||||
}
|
||||
|
||||
foreach ( var package in packageInfo.UnknownPackages )
|
||||
{
|
||||
PackageInfo[package] = null;
|
||||
}
|
||||
};
|
||||
|
||||
var packageRequests = new List<SteamApps.PICSRequest>();
|
||||
|
||||
foreach ( var package in packages )
|
||||
{
|
||||
var request = new SteamApps.PICSRequest( package );
|
||||
|
||||
if ( PackageTokens.TryGetValue( package, out var token ) )
|
||||
{
|
||||
request.AccessToken = token;
|
||||
request.Public = false;
|
||||
}
|
||||
|
||||
packageRequests.Add( request );
|
||||
}
|
||||
|
||||
WaitUntilCallback( () =>
|
||||
{
|
||||
callbacks.Subscribe( steamApps.PICSGetProductInfo( new List<SteamApps.PICSRequest>(), packageRequests ), cbMethod );
|
||||
}, () => { return completed; } );
|
||||
}
|
||||
|
||||
public bool RequestFreeAppLicense( uint appId )
|
||||
{
|
||||
bool success = false;
|
||||
bool completed = false;
|
||||
Action<SteamApps.FreeLicenseCallback> cbMethod = ( resultInfo ) =>
|
||||
{
|
||||
completed = true;
|
||||
success = resultInfo.GrantedApps.Contains( appId );
|
||||
};
|
||||
|
||||
WaitUntilCallback( () =>
|
||||
{
|
||||
callbacks.Subscribe( steamApps.RequestFreeLicense( appId ), cbMethod );
|
||||
}, () => { return completed; } );
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public void RequestAppTicket( uint appId )
|
||||
{
|
||||
if ( AppTickets.ContainsKey( appId ) || bAborted )
|
||||
return;
|
||||
|
||||
|
||||
if ( !authenticatedUser )
|
||||
{
|
||||
AppTickets[ appId ] = null;
|
||||
return;
|
||||
}
|
||||
|
||||
bool completed = false;
|
||||
Action<SteamApps.AppOwnershipTicketCallback> cbMethod = ( appTicket ) =>
|
||||
{
|
||||
completed = true;
|
||||
|
||||
if ( appTicket.Result != EResult.OK )
|
||||
{
|
||||
Console.WriteLine( "Unable to get appticket for {0}: {1}", appTicket.AppID, appTicket.Result );
|
||||
Abort();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine( "Got appticket for {0}!", appTicket.AppID );
|
||||
AppTickets[ appTicket.AppID ] = appTicket.Ticket;
|
||||
}
|
||||
};
|
||||
|
||||
WaitUntilCallback( () =>
|
||||
{
|
||||
callbacks.Subscribe( steamApps.GetAppOwnershipTicket( appId ), cbMethod );
|
||||
}, () => { return completed; } );
|
||||
}
|
||||
|
||||
public void RequestDepotKey( uint depotId, uint appid = 0 )
|
||||
{
|
||||
if ( DepotKeys.ContainsKey( depotId ) || bAborted )
|
||||
return;
|
||||
|
||||
bool completed = false;
|
||||
|
||||
Action<SteamApps.DepotKeyCallback> cbMethod = ( depotKey ) =>
|
||||
{
|
||||
completed = true;
|
||||
Console.WriteLine( "Got depot key for {0} result: {1}", depotKey.DepotID, depotKey.Result );
|
||||
|
||||
if ( depotKey.Result != EResult.OK )
|
||||
{
|
||||
Abort();
|
||||
return;
|
||||
}
|
||||
|
||||
DepotKeys[ depotKey.DepotID ] = depotKey.DepotKey;
|
||||
};
|
||||
|
||||
WaitUntilCallback( () =>
|
||||
{
|
||||
callbacks.Subscribe( steamApps.GetDepotDecryptionKey( depotId, appid ), cbMethod );
|
||||
}, () => { return completed; } );
|
||||
}
|
||||
|
||||
public string ResolveCDNTopLevelHost(string host)
|
||||
{
|
||||
// SteamPipe CDN shares tokens with all hosts
|
||||
if (host.EndsWith( ".steampipe.steamcontent.com" ) )
|
||||
{
|
||||
return "steampipe.steamcontent.com";
|
||||
}
|
||||
else if (host.EndsWith(".steamcontent.com"))
|
||||
{
|
||||
return "steamcontent.com";
|
||||
}
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
public void RequestCDNAuthToken( uint appid, uint depotid, string host, string cdnKey )
|
||||
{
|
||||
if ( CDNAuthTokens.ContainsKey( cdnKey ) || bAborted )
|
||||
return;
|
||||
|
||||
if ( !CDNAuthTokens.TryAdd( cdnKey, new TaskCompletionSource<SteamApps.CDNAuthTokenCallback>() ) )
|
||||
return;
|
||||
|
||||
bool completed = false;
|
||||
var timeoutDate = DateTime.Now.AddSeconds( 10 );
|
||||
Action<SteamApps.CDNAuthTokenCallback> cbMethod = ( cdnAuth ) =>
|
||||
{
|
||||
completed = true;
|
||||
Console.WriteLine( "Got CDN auth token for {0} result: {1} (expires {2})", host, cdnAuth.Result, cdnAuth.Expiration );
|
||||
|
||||
if ( cdnAuth.Result != EResult.OK )
|
||||
{
|
||||
Abort();
|
||||
return;
|
||||
}
|
||||
|
||||
CDNAuthTokens[cdnKey].TrySetResult( cdnAuth );
|
||||
};
|
||||
|
||||
WaitUntilCallback( () =>
|
||||
{
|
||||
callbacks.Subscribe( steamApps.GetCDNAuthToken( appid, depotid, host ), cbMethod );
|
||||
}, () => { return completed || DateTime.Now >= timeoutDate; } );
|
||||
}
|
||||
|
||||
public void CheckAppBetaPassword( uint appid, string password )
|
||||
{
|
||||
bool completed = false;
|
||||
Action<SteamApps.CheckAppBetaPasswordCallback> cbMethod = ( appPassword ) =>
|
||||
{
|
||||
completed = true;
|
||||
|
||||
Console.WriteLine( "Retrieved {0} beta keys with result: {1}", appPassword.BetaPasswords.Count, appPassword.Result );
|
||||
|
||||
foreach ( var entry in appPassword.BetaPasswords )
|
||||
{
|
||||
AppBetaPasswords[ entry.Key ] = entry.Value;
|
||||
}
|
||||
};
|
||||
|
||||
WaitUntilCallback( () =>
|
||||
{
|
||||
callbacks.Subscribe( steamApps.CheckAppBetaPassword( appid, password ), cbMethod );
|
||||
}, () => { return completed; } );
|
||||
}
|
||||
|
||||
public CPublishedFile_GetItemInfo_Response.WorkshopItemInfo GetPubfileItemInfo( uint appId, PublishedFileID pubFile )
|
||||
{
|
||||
var pubFileRequest = new CPublishedFile_GetItemInfo_Request() { app_id = appId };
|
||||
pubFileRequest.workshop_items.Add( new CPublishedFile_GetItemInfo_Request.WorkshopItem() { published_file_id = pubFile } );
|
||||
|
||||
bool completed = false;
|
||||
CPublishedFile_GetItemInfo_Response.WorkshopItemInfo details = null;
|
||||
|
||||
Action<SteamUnifiedMessages.ServiceMethodResponse> cbMethod = callback =>
|
||||
{
|
||||
completed = true;
|
||||
if ( callback.Result == EResult.OK )
|
||||
{
|
||||
var response = callback.GetDeserializedResponse<CPublishedFile_GetItemInfo_Response>();
|
||||
details = response.workshop_items.FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception( $"EResult {(int)callback.Result} ({callback.Result}) while retrieving UGC id for pubfile {pubFile}.");
|
||||
}
|
||||
};
|
||||
|
||||
WaitUntilCallback(() =>
|
||||
{
|
||||
callbacks.Subscribe( steamPublishedFile.SendMessage( api => api.GetItemInfo( pubFileRequest ) ), cbMethod );
|
||||
}, () => { return completed; });
|
||||
|
||||
return details;
|
||||
}
|
||||
|
||||
public PublishedFileDetails GetPublishedFileDetails(uint appId, PublishedFileID pubFile)
|
||||
{
|
||||
var pubFileRequest = new CPublishedFile_GetDetails_Request() { appid = appId };
|
||||
pubFileRequest.publishedfileids.Add( pubFile );
|
||||
|
||||
bool completed = false;
|
||||
PublishedFileDetails details = null;
|
||||
|
||||
Action<SteamUnifiedMessages.ServiceMethodResponse> cbMethod = callback =>
|
||||
{
|
||||
completed = true;
|
||||
if (callback.Result == EResult.OK)
|
||||
{
|
||||
var response = callback.GetDeserializedResponse<CPublishedFile_GetDetails_Response>();
|
||||
details = response.publishedfiledetails.FirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"EResult {(int)callback.Result} ({callback.Result}) while retrieving file details for pubfile {pubFile}.");
|
||||
}
|
||||
};
|
||||
|
||||
WaitUntilCallback(() =>
|
||||
{
|
||||
callbacks.Subscribe(steamPublishedFile.SendMessage(api => api.GetDetails(pubFileRequest)), cbMethod);
|
||||
}, () => { return completed; });
|
||||
|
||||
return details;
|
||||
}
|
||||
|
||||
|
||||
public SteamCloud.UGCDetailsCallback GetUGCDetails(UGCHandle ugcHandle)
|
||||
{
|
||||
bool completed = false;
|
||||
SteamCloud.UGCDetailsCallback details = null;
|
||||
|
||||
Action<SteamCloud.UGCDetailsCallback> cbMethod = callback =>
|
||||
{
|
||||
completed = true;
|
||||
if (callback.Result == EResult.OK)
|
||||
{
|
||||
details = callback;
|
||||
}
|
||||
else if (callback.Result == EResult.FileNotFound)
|
||||
{
|
||||
details = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"EResult {(int)callback.Result} ({callback.Result}) while retrieving UGC details for {ugcHandle}.");
|
||||
}
|
||||
};
|
||||
|
||||
WaitUntilCallback(() =>
|
||||
{
|
||||
callbacks.Subscribe(steamCloud.RequestUGCDetails(ugcHandle), cbMethod);
|
||||
}, () => { return completed; });
|
||||
|
||||
return details;
|
||||
}
|
||||
|
||||
void Connect()
|
||||
{
|
||||
bAborted = false;
|
||||
bConnected = false;
|
||||
bConnecting = true;
|
||||
connectionBackoff = 0;
|
||||
bExpectingDisconnectRemote = false;
|
||||
bDidDisconnect = false;
|
||||
bDidReceiveLoginKey = false;
|
||||
this.connectTime = DateTime.Now;
|
||||
this.steamClient.Connect();
|
||||
}
|
||||
|
||||
private void Abort( bool sendLogOff = true )
|
||||
{
|
||||
Disconnect( sendLogOff );
|
||||
}
|
||||
public void Disconnect( bool sendLogOff = true )
|
||||
{
|
||||
if ( sendLogOff )
|
||||
{
|
||||
steamUser.LogOff();
|
||||
}
|
||||
|
||||
steamClient.Disconnect();
|
||||
bConnected = false;
|
||||
bConnecting = false;
|
||||
bAborted = true;
|
||||
|
||||
// flush callbacks until our disconnected event
|
||||
while ( !bDidDisconnect )
|
||||
{
|
||||
callbacks.RunWaitAllCallbacks( TimeSpan.FromMilliseconds( 100 ) );
|
||||
}
|
||||
}
|
||||
|
||||
public void TryWaitForLoginKey()
|
||||
{
|
||||
if ( logonDetails.Username == null || !credentials.LoggedOn || !ContentDownloader.Config.RememberPassword ) return;
|
||||
|
||||
var totalWaitPeriod = DateTime.Now.AddSeconds( 3 );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
if ( now >= totalWaitPeriod ) break;
|
||||
|
||||
if ( bDidReceiveLoginKey ) break;
|
||||
|
||||
callbacks.RunWaitAllCallbacks( TimeSpan.FromMilliseconds( 100 ) );
|
||||
}
|
||||
}
|
||||
|
||||
private void WaitForCallbacks()
|
||||
{
|
||||
callbacks.RunWaitCallbacks( TimeSpan.FromSeconds( 1 ) );
|
||||
|
||||
TimeSpan diff = DateTime.Now - connectTime;
|
||||
|
||||
if ( diff > STEAM3_TIMEOUT && !bConnected )
|
||||
{
|
||||
Console.WriteLine( "Timeout connecting to Steam3." );
|
||||
Abort();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void ConnectedCallback( SteamClient.ConnectedCallback connected )
|
||||
{
|
||||
Console.WriteLine( " Done!" );
|
||||
bConnecting = false;
|
||||
bConnected = true;
|
||||
if ( !authenticatedUser )
|
||||
{
|
||||
Console.Write( "Logging anonymously into Steam3..." );
|
||||
steamUser.LogOnAnonymous();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Write( "Logging '{0}' into Steam3...", logonDetails.Username );
|
||||
steamUser.LogOn( logonDetails );
|
||||
}
|
||||
}
|
||||
|
||||
private void DisconnectedCallback( SteamClient.DisconnectedCallback disconnected )
|
||||
{
|
||||
bDidDisconnect = true;
|
||||
|
||||
if ( disconnected.UserInitiated || bExpectingDisconnectRemote )
|
||||
{
|
||||
Console.WriteLine( "Disconnected from Steam" );
|
||||
}
|
||||
else if ( connectionBackoff >= 10 )
|
||||
{
|
||||
Console.WriteLine( "Could not connect to Steam after 10 tries" );
|
||||
Abort( false );
|
||||
}
|
||||
else if ( !bAborted )
|
||||
{
|
||||
if ( bConnecting )
|
||||
{
|
||||
Console.WriteLine( "Connection to Steam failed. Trying again" );
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine( "Lost connection to Steam. Reconnecting" );
|
||||
}
|
||||
|
||||
Thread.Sleep( 1000 * ++connectionBackoff );
|
||||
steamClient.Connect();
|
||||
}
|
||||
}
|
||||
|
||||
private void LogOnCallback( SteamUser.LoggedOnCallback loggedOn )
|
||||
{
|
||||
bool isSteamGuard = loggedOn.Result == EResult.AccountLogonDenied;
|
||||
bool is2FA = loggedOn.Result == EResult.AccountLoginDeniedNeedTwoFactor;
|
||||
bool isLoginKey = ContentDownloader.Config.RememberPassword && logonDetails.LoginKey != null && loggedOn.Result == EResult.InvalidPassword;
|
||||
|
||||
if ( isSteamGuard || is2FA || isLoginKey )
|
||||
{
|
||||
bExpectingDisconnectRemote = true;
|
||||
Abort( false );
|
||||
|
||||
if ( !isLoginKey )
|
||||
{
|
||||
Console.WriteLine( "This account is protected by Steam Guard." );
|
||||
}
|
||||
|
||||
if ( is2FA )
|
||||
{
|
||||
Console.Write( "Please enter your 2 factor auth code from your authenticator app: " );
|
||||
logonDetails.TwoFactorCode = Console.ReadLine();
|
||||
}
|
||||
else if ( isLoginKey )
|
||||
{
|
||||
AccountSettingsStore.Instance.LoginKeys.Remove( logonDetails.Username );
|
||||
AccountSettingsStore.Save();
|
||||
|
||||
logonDetails.LoginKey = null;
|
||||
|
||||
if ( ContentDownloader.Config.SuppliedPassword != null )
|
||||
{
|
||||
Console.WriteLine( "Login key was expired. Connecting with supplied password." );
|
||||
logonDetails.Password = ContentDownloader.Config.SuppliedPassword;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Write( "Login key was expired. Please enter your password: " );
|
||||
logonDetails.Password = Util.ReadPassword();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Write( "Please enter the authentication code sent to your email address: " );
|
||||
logonDetails.AuthCode = Console.ReadLine();
|
||||
}
|
||||
|
||||
Console.Write( "Retrying Steam3 connection..." );
|
||||
Connect();
|
||||
|
||||
return;
|
||||
}
|
||||
else if ( loggedOn.Result == EResult.ServiceUnavailable )
|
||||
{
|
||||
Console.WriteLine( "Unable to login to Steam3: {0}", loggedOn.Result );
|
||||
Abort( false );
|
||||
|
||||
return;
|
||||
}
|
||||
else if ( loggedOn.Result != EResult.OK )
|
||||
{
|
||||
Console.WriteLine( "Unable to login to Steam3: {0}", loggedOn.Result );
|
||||
Abort();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine( " Done!" );
|
||||
|
||||
this.seq++;
|
||||
credentials.LoggedOn = true;
|
||||
|
||||
if ( ContentDownloader.Config.CellID == 0 )
|
||||
{
|
||||
Console.WriteLine( "Using Steam3 suggested CellID: " + loggedOn.CellID );
|
||||
ContentDownloader.Config.CellID = ( int )loggedOn.CellID;
|
||||
}
|
||||
}
|
||||
|
||||
private void SessionTokenCallback( SteamUser.SessionTokenCallback sessionToken )
|
||||
{
|
||||
Console.WriteLine( "Got session token!" );
|
||||
credentials.SessionToken = sessionToken.SessionToken;
|
||||
}
|
||||
|
||||
private void LicenseListCallback( SteamApps.LicenseListCallback licenseList )
|
||||
{
|
||||
if ( licenseList.Result != EResult.OK )
|
||||
{
|
||||
Console.WriteLine( "Unable to get license list: {0} ", licenseList.Result );
|
||||
Abort();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine( "Got {0} licenses for account!", licenseList.LicenseList.Count );
|
||||
Licenses = licenseList.LicenseList;
|
||||
|
||||
foreach ( var license in licenseList.LicenseList )
|
||||
{
|
||||
if ( license.AccessToken > 0 )
|
||||
{
|
||||
PackageTokens.TryAdd( license.PackageID, license.AccessToken );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateMachineAuthCallback( SteamUser.UpdateMachineAuthCallback machineAuth )
|
||||
{
|
||||
byte[] hash = Util.SHAHash( machineAuth.Data );
|
||||
Console.WriteLine( "Got Machine Auth: {0} {1} {2} {3}", machineAuth.FileName, machineAuth.Offset, machineAuth.BytesToWrite, machineAuth.Data.Length, hash );
|
||||
|
||||
AccountSettingsStore.Instance.SentryData[ logonDetails.Username ] = machineAuth.Data;
|
||||
AccountSettingsStore.Save();
|
||||
|
||||
var authResponse = new SteamUser.MachineAuthDetails
|
||||
{
|
||||
BytesWritten = machineAuth.BytesToWrite,
|
||||
FileName = machineAuth.FileName,
|
||||
FileSize = machineAuth.BytesToWrite,
|
||||
Offset = machineAuth.Offset,
|
||||
|
||||
SentryFileHash = hash, // should be the sha1 hash of the sentry file we just wrote
|
||||
|
||||
OneTimePassword = machineAuth.OneTimePassword, // not sure on this one yet, since we've had no examples of steam using OTPs
|
||||
|
||||
LastError = 0, // result from win32 GetLastError
|
||||
Result = EResult.OK, // if everything went okay, otherwise ~who knows~
|
||||
|
||||
JobID = machineAuth.JobID, // so we respond to the correct server job
|
||||
};
|
||||
|
||||
// send off our response
|
||||
steamUser.SendMachineAuthResponse( authResponse );
|
||||
}
|
||||
|
||||
private void LoginKeyCallback( SteamUser.LoginKeyCallback loginKey )
|
||||
{
|
||||
Console.WriteLine( "Accepted new login key for account {0}", logonDetails.Username );
|
||||
|
||||
AccountSettingsStore.Instance.LoginKeys[ logonDetails.Username ] = loginKey.LoginKey;
|
||||
AccountSettingsStore.Save();
|
||||
|
||||
steamUser.AcceptNewLoginKey( loginKey );
|
||||
|
||||
bDidReceiveLoginKey = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,170 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DepotDownloader
|
||||
{
|
||||
static class Util
|
||||
{
|
||||
public static string GetSteamOS()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
return "windows";
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
return "macos";
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
return "linux";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
public static string GetSteamArch()
|
||||
{
|
||||
return Environment.Is64BitOperatingSystem ? "64" : "32";
|
||||
}
|
||||
|
||||
public static string ReadPassword()
|
||||
{
|
||||
ConsoleKeyInfo keyInfo;
|
||||
StringBuilder password = new StringBuilder();
|
||||
|
||||
do
|
||||
{
|
||||
keyInfo = Console.ReadKey( true );
|
||||
|
||||
if ( keyInfo.Key == ConsoleKey.Backspace )
|
||||
{
|
||||
if ( password.Length > 0 )
|
||||
password.Remove( password.Length - 1, 1 );
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Printable ASCII characters only */
|
||||
char c = keyInfo.KeyChar;
|
||||
if ( c >= ' ' && c <= '~' )
|
||||
password.Append( c );
|
||||
} while ( keyInfo.Key != ConsoleKey.Enter );
|
||||
|
||||
return password.ToString();
|
||||
}
|
||||
|
||||
// Validate a file against Steam3 Chunk data
|
||||
public static List<ProtoManifest.ChunkData> ValidateSteam3FileChecksums(FileStream fs, ProtoManifest.ChunkData[] chunkdata)
|
||||
{
|
||||
var neededChunks = new List<ProtoManifest.ChunkData>();
|
||||
int read;
|
||||
|
||||
foreach (var data in chunkdata)
|
||||
{
|
||||
byte[] chunk = new byte[data.UncompressedLength];
|
||||
fs.Seek((long)data.Offset, SeekOrigin.Begin);
|
||||
read = fs.Read(chunk, 0, (int)data.UncompressedLength);
|
||||
|
||||
byte[] tempchunk;
|
||||
if (read < data.UncompressedLength)
|
||||
{
|
||||
tempchunk = new byte[read];
|
||||
Array.Copy(chunk, 0, tempchunk, 0, read);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempchunk = chunk;
|
||||
}
|
||||
|
||||
byte[] adler = AdlerHash(tempchunk);
|
||||
if (!adler.SequenceEqual(data.Checksum))
|
||||
{
|
||||
neededChunks.Add(data);
|
||||
}
|
||||
}
|
||||
|
||||
return neededChunks;
|
||||
}
|
||||
|
||||
public static byte[] AdlerHash(byte[] input)
|
||||
{
|
||||
uint a = 0, b = 0;
|
||||
for (int i = 0; i < input.Length; i++)
|
||||
{
|
||||
a = (a + input[i]) % 65521;
|
||||
b = (b + a) % 65521;
|
||||
}
|
||||
return BitConverter.GetBytes(a | (b << 16));
|
||||
}
|
||||
|
||||
public static byte[] SHAHash( byte[] input )
|
||||
{
|
||||
using (var sha = SHA1.Create())
|
||||
{
|
||||
var output = sha.ComputeHash( input );
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] DecodeHexString( string hex )
|
||||
{
|
||||
if ( hex == null )
|
||||
return null;
|
||||
|
||||
int chars = hex.Length;
|
||||
byte[] bytes = new byte[ chars / 2 ];
|
||||
|
||||
for ( int i = 0 ; i < chars ; i += 2 )
|
||||
bytes[ i / 2 ] = Convert.ToByte( hex.Substring( i, 2 ), 16 );
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static string EncodeHexString( byte[] input )
|
||||
{
|
||||
return input.Aggregate( new StringBuilder(),
|
||||
( sb, v ) => sb.Append( v.ToString( "x2" ) )
|
||||
).ToString();
|
||||
}
|
||||
|
||||
public static async Task InvokeAsync(IEnumerable<Func<Task>> taskFactories, int maxDegreeOfParallelism)
|
||||
{
|
||||
if (taskFactories == null) throw new ArgumentNullException(nameof(taskFactories));
|
||||
if (maxDegreeOfParallelism <= 0) throw new ArgumentException(nameof(maxDegreeOfParallelism));
|
||||
|
||||
Func<Task>[] queue = taskFactories.ToArray();
|
||||
|
||||
if (queue.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<Task> tasksInFlight = new List<Task>(maxDegreeOfParallelism);
|
||||
int index = 0;
|
||||
|
||||
do
|
||||
{
|
||||
while (tasksInFlight.Count < maxDegreeOfParallelism && index < queue.Length)
|
||||
{
|
||||
Func<Task> taskFactory = queue[index++];
|
||||
|
||||
tasksInFlight.Add(taskFactory());
|
||||
}
|
||||
|
||||
Task completedTask = await Task.WhenAny(tasksInFlight).ConfigureAwait(false);
|
||||
|
||||
await completedTask.ConfigureAwait(false);
|
||||
|
||||
tasksInFlight.Remove(completedTask);
|
||||
}
|
||||
while (index < queue.Length || tasksInFlight.Count != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
|
||||
</startup>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="protobuf-net" publicKeyToken="257b51d87d2e4d67" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.0.640" newVersion="2.0.0.640"/>
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"rollForwardOnNoCandidateFx": 2
|
||||
}
|
||||
@@ -1,339 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
@@ -1,55 +0,0 @@
|
||||
DepotDownloader
|
||||
===============
|
||||
|
||||
Steam depot downloader utilizing the SteamKit2 library. Supports .NET Core 2.0
|
||||
|
||||
### Downloading one or all depots for an app
|
||||
```
|
||||
dotnet DepotDownloader.dll -app <id> [-depot <id> [-manifest <id>]]
|
||||
[-username <username> [-password <password>]] [other options]
|
||||
```
|
||||
|
||||
For example: `dotnet DepotDownloader.dll -app 730 -depot 731 -manifest 7617088375292372759`
|
||||
|
||||
### Downloading a workshop item using pubfile id
|
||||
```
|
||||
dotnet DepotDownloader.dll -app <id> -pubfile <id> [-username <username> [-password <password>]]
|
||||
```
|
||||
|
||||
For example: `dotnet DepotDownloader.dll -app 730 -pubfile 1885082371`
|
||||
|
||||
### Downloading a workshop item using ugc id
|
||||
```
|
||||
dotnet DepotDownloader.dll -app <id> -ugc <id> [-username <username> [-password <password>]]
|
||||
```
|
||||
|
||||
For example: `dotnet DepotDownloader.dll -app 730 -ugc 770604181014286929`
|
||||
|
||||
## Parameters
|
||||
|
||||
Parameter | Description
|
||||
--------- | -----------
|
||||
-app \<#> | the AppID to download.
|
||||
-depot \<#> | the DepotID to download.
|
||||
-manifest \<id> | manifest id of content to download (requires -depot, default: current for branch).
|
||||
-ugc \<#> | the UGC ID to download.
|
||||
-beta \<branchname> | download from specified branch if available (default: Public).
|
||||
-betapassword \<pass> | branch password if applicable.
|
||||
-all-platforms | downloads all platform-specific depots when -app is used.
|
||||
-os \<os> | the operating system for which to download the game (windows, macos or linux, default: OS the program is currently running on)
|
||||
-osarch \<arch> | the architecture for which to download the game (32 or 64, default: the host's architecture)
|
||||
-all-languages | download all language-specific depots when -app is used.
|
||||
-language \<lang> | the language for which to download the game (default: english)
|
||||
-lowviolence | download low violence depots when -app is used.
|
||||
-pubfile \<#> | the PublishedFileId to download. (Will automatically resolve to UGC id)
|
||||
-username \<user> | the username of the account to login to for restricted content.
|
||||
-password \<pass> | the password of the account to login to for restricted content.
|
||||
-remember-password | if set, remember the password for subsequent logins of this user.
|
||||
-dir \<installdir> | the directory in which to place downloaded files.
|
||||
-filelist \<file.txt> | a list of files to download (from the manifest). Can optionally use regex to download only certain files.
|
||||
-validate | Include checksum verification of files already downloaded
|
||||
-manifest-only | downloads a human readable manifest for any depots that would be downloaded.
|
||||
-cellid \<#> | the overridden CellID of the content server to download from.
|
||||
-max-servers \<#> | maximum number of content servers to use. (default: 20).
|
||||
-max-downloads \<#> | maximum number of chunks to download concurrently. (default: 8).
|
||||
-loginid \<#> | a unique 32-bit integer Steam LogonID in decimal, required if running multiple instances of DepotDownloader concurrently.
|
||||
325
downloadGUI.Designer.cs
generated
Normal file
325
downloadGUI.Designer.cs
generated
Normal file
@@ -0,0 +1,325 @@
|
||||
|
||||
namespace DepotDownloaderGUI
|
||||
{
|
||||
partial class downloadGUI
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(downloadGUI));
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.label7 = new System.Windows.Forms.Label();
|
||||
this.label8 = new System.Windows.Forms.Label();
|
||||
this.textBoxUsername = new System.Windows.Forms.TextBox();
|
||||
this.textBoxPassword = new System.Windows.Forms.TextBox();
|
||||
this.textBoxAppID = new System.Windows.Forms.TextBox();
|
||||
this.textBoxDepotID = new System.Windows.Forms.TextBox();
|
||||
this.textBoxManifestID = new System.Windows.Forms.TextBox();
|
||||
this.textBoxArgs = new System.Windows.Forms.TextBox();
|
||||
this.buttonDownload = new System.Windows.Forms.Button();
|
||||
this.numericUpDownMaxServers = new System.Windows.Forms.NumericUpDown();
|
||||
this.numericUpDownMaxChunks = new System.Windows.Forms.NumericUpDown();
|
||||
this.buttonHelp = new System.Windows.Forms.Button();
|
||||
this.buttonSearch = new System.Windows.Forms.Button();
|
||||
this.buttonRepo = new System.Windows.Forms.Button();
|
||||
this.labelTitle = new System.Windows.Forms.Label();
|
||||
this.labelIssue = new System.Windows.Forms.Label();
|
||||
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDownMaxServers)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDownMaxChunks)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
resources.ApplyResources(this.label1, "label1");
|
||||
this.label1.Name = "label1";
|
||||
this.toolTip1.SetToolTip(this.label1, resources.GetString("label1.ToolTip"));
|
||||
//
|
||||
// label2
|
||||
//
|
||||
resources.ApplyResources(this.label2, "label2");
|
||||
this.label2.Name = "label2";
|
||||
this.toolTip1.SetToolTip(this.label2, resources.GetString("label2.ToolTip"));
|
||||
//
|
||||
// label3
|
||||
//
|
||||
resources.ApplyResources(this.label3, "label3");
|
||||
this.label3.Name = "label3";
|
||||
this.toolTip1.SetToolTip(this.label3, resources.GetString("label3.ToolTip"));
|
||||
//
|
||||
// label4
|
||||
//
|
||||
resources.ApplyResources(this.label4, "label4");
|
||||
this.label4.Name = "label4";
|
||||
this.toolTip1.SetToolTip(this.label4, resources.GetString("label4.ToolTip"));
|
||||
//
|
||||
// label5
|
||||
//
|
||||
resources.ApplyResources(this.label5, "label5");
|
||||
this.label5.Name = "label5";
|
||||
this.toolTip1.SetToolTip(this.label5, resources.GetString("label5.ToolTip"));
|
||||
//
|
||||
// label6
|
||||
//
|
||||
resources.ApplyResources(this.label6, "label6");
|
||||
this.label6.Name = "label6";
|
||||
this.toolTip1.SetToolTip(this.label6, resources.GetString("label6.ToolTip"));
|
||||
//
|
||||
// label7
|
||||
//
|
||||
resources.ApplyResources(this.label7, "label7");
|
||||
this.label7.Name = "label7";
|
||||
this.toolTip1.SetToolTip(this.label7, resources.GetString("label7.ToolTip"));
|
||||
//
|
||||
// label8
|
||||
//
|
||||
resources.ApplyResources(this.label8, "label8");
|
||||
this.label8.Name = "label8";
|
||||
this.toolTip1.SetToolTip(this.label8, resources.GetString("label8.ToolTip"));
|
||||
//
|
||||
// textBoxUsername
|
||||
//
|
||||
resources.ApplyResources(this.textBoxUsername, "textBoxUsername");
|
||||
this.textBoxUsername.BackColor = System.Drawing.Color.Black;
|
||||
this.textBoxUsername.ForeColor = System.Drawing.Color.White;
|
||||
this.textBoxUsername.Name = "textBoxUsername";
|
||||
//
|
||||
// textBoxPassword
|
||||
//
|
||||
resources.ApplyResources(this.textBoxPassword, "textBoxPassword");
|
||||
this.textBoxPassword.BackColor = System.Drawing.Color.Black;
|
||||
this.textBoxPassword.ForeColor = System.Drawing.Color.White;
|
||||
this.textBoxPassword.Name = "textBoxPassword";
|
||||
//
|
||||
// textBoxAppID
|
||||
//
|
||||
resources.ApplyResources(this.textBoxAppID, "textBoxAppID");
|
||||
this.textBoxAppID.BackColor = System.Drawing.Color.Black;
|
||||
this.textBoxAppID.ForeColor = System.Drawing.Color.White;
|
||||
this.textBoxAppID.Name = "textBoxAppID";
|
||||
//
|
||||
// textBoxDepotID
|
||||
//
|
||||
resources.ApplyResources(this.textBoxDepotID, "textBoxDepotID");
|
||||
this.textBoxDepotID.BackColor = System.Drawing.Color.Black;
|
||||
this.textBoxDepotID.ForeColor = System.Drawing.Color.White;
|
||||
this.textBoxDepotID.Name = "textBoxDepotID";
|
||||
//
|
||||
// textBoxManifestID
|
||||
//
|
||||
resources.ApplyResources(this.textBoxManifestID, "textBoxManifestID");
|
||||
this.textBoxManifestID.BackColor = System.Drawing.Color.Black;
|
||||
this.textBoxManifestID.ForeColor = System.Drawing.Color.White;
|
||||
this.textBoxManifestID.Name = "textBoxManifestID";
|
||||
//
|
||||
// textBoxArgs
|
||||
//
|
||||
resources.ApplyResources(this.textBoxArgs, "textBoxArgs");
|
||||
this.textBoxArgs.BackColor = System.Drawing.Color.Black;
|
||||
this.textBoxArgs.ForeColor = System.Drawing.Color.White;
|
||||
this.textBoxArgs.Name = "textBoxArgs";
|
||||
//
|
||||
// buttonDownload
|
||||
//
|
||||
resources.ApplyResources(this.buttonDownload, "buttonDownload");
|
||||
this.buttonDownload.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.buttonDownload.Name = "buttonDownload";
|
||||
this.toolTip1.SetToolTip(this.buttonDownload, resources.GetString("buttonDownload.ToolTip"));
|
||||
this.buttonDownload.UseVisualStyleBackColor = true;
|
||||
this.buttonDownload.Click += new System.EventHandler(this.buttonDownload_Click);
|
||||
//
|
||||
// numericUpDownMaxServers
|
||||
//
|
||||
resources.ApplyResources(this.numericUpDownMaxServers, "numericUpDownMaxServers");
|
||||
this.numericUpDownMaxServers.BackColor = System.Drawing.Color.Black;
|
||||
this.numericUpDownMaxServers.ForeColor = System.Drawing.Color.White;
|
||||
this.numericUpDownMaxServers.Increment = new decimal(new int[] {
|
||||
5,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numericUpDownMaxServers.Maximum = new decimal(new int[] {
|
||||
1000,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numericUpDownMaxServers.Minimum = new decimal(new int[] {
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numericUpDownMaxServers.Name = "numericUpDownMaxServers";
|
||||
this.numericUpDownMaxServers.Value = new decimal(new int[] {
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// numericUpDownMaxChunks
|
||||
//
|
||||
resources.ApplyResources(this.numericUpDownMaxChunks, "numericUpDownMaxChunks");
|
||||
this.numericUpDownMaxChunks.BackColor = System.Drawing.Color.Black;
|
||||
this.numericUpDownMaxChunks.ForeColor = System.Drawing.Color.White;
|
||||
this.numericUpDownMaxChunks.Increment = new decimal(new int[] {
|
||||
5,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numericUpDownMaxChunks.Maximum = new decimal(new int[] {
|
||||
1000,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numericUpDownMaxChunks.Minimum = new decimal(new int[] {
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.numericUpDownMaxChunks.Name = "numericUpDownMaxChunks";
|
||||
this.numericUpDownMaxChunks.Value = new decimal(new int[] {
|
||||
10,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// buttonHelp
|
||||
//
|
||||
resources.ApplyResources(this.buttonHelp, "buttonHelp");
|
||||
this.buttonHelp.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.buttonHelp.Name = "buttonHelp";
|
||||
this.buttonHelp.UseVisualStyleBackColor = true;
|
||||
this.buttonHelp.Click += new System.EventHandler(this.buttonHelp_Click);
|
||||
//
|
||||
// buttonSearch
|
||||
//
|
||||
resources.ApplyResources(this.buttonSearch, "buttonSearch");
|
||||
this.buttonSearch.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.buttonSearch.Name = "buttonSearch";
|
||||
this.toolTip1.SetToolTip(this.buttonSearch, resources.GetString("buttonSearch.ToolTip"));
|
||||
this.buttonSearch.UseVisualStyleBackColor = true;
|
||||
this.buttonSearch.Click += new System.EventHandler(this.buttonSearch_Click);
|
||||
//
|
||||
// buttonRepo
|
||||
//
|
||||
resources.ApplyResources(this.buttonRepo, "buttonRepo");
|
||||
this.buttonRepo.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.buttonRepo.Name = "buttonRepo";
|
||||
this.toolTip1.SetToolTip(this.buttonRepo, resources.GetString("buttonRepo.ToolTip"));
|
||||
this.buttonRepo.UseVisualStyleBackColor = true;
|
||||
this.buttonRepo.Click += new System.EventHandler(this.buttonRepo_Click);
|
||||
//
|
||||
// labelTitle
|
||||
//
|
||||
resources.ApplyResources(this.labelTitle, "labelTitle");
|
||||
this.labelTitle.Name = "labelTitle";
|
||||
//
|
||||
// labelIssue
|
||||
//
|
||||
resources.ApplyResources(this.labelIssue, "labelIssue");
|
||||
this.labelIssue.Name = "labelIssue";
|
||||
//
|
||||
// toolTip1
|
||||
//
|
||||
this.toolTip1.AutomaticDelay = 0;
|
||||
this.toolTip1.AutoPopDelay = 0;
|
||||
this.toolTip1.InitialDelay = 0;
|
||||
this.toolTip1.IsBalloon = true;
|
||||
this.toolTip1.ReshowDelay = 600;
|
||||
this.toolTip1.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Info;
|
||||
this.toolTip1.ToolTipTitle = "Info";
|
||||
//
|
||||
// downloadGUI
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.Color.Black;
|
||||
this.Controls.Add(this.labelIssue);
|
||||
this.Controls.Add(this.labelTitle);
|
||||
this.Controls.Add(this.buttonRepo);
|
||||
this.Controls.Add(this.buttonSearch);
|
||||
this.Controls.Add(this.buttonHelp);
|
||||
this.Controls.Add(this.numericUpDownMaxChunks);
|
||||
this.Controls.Add(this.numericUpDownMaxServers);
|
||||
this.Controls.Add(this.buttonDownload);
|
||||
this.Controls.Add(this.textBoxArgs);
|
||||
this.Controls.Add(this.textBoxManifestID);
|
||||
this.Controls.Add(this.textBoxDepotID);
|
||||
this.Controls.Add(this.textBoxAppID);
|
||||
this.Controls.Add(this.textBoxPassword);
|
||||
this.Controls.Add(this.textBoxUsername);
|
||||
this.Controls.Add(this.label8);
|
||||
this.Controls.Add(this.label7);
|
||||
this.Controls.Add(this.label6);
|
||||
this.Controls.Add(this.label5);
|
||||
this.Controls.Add(this.label4);
|
||||
this.Controls.Add(this.label3);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.label1);
|
||||
this.ForeColor = System.Drawing.Color.White;
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
|
||||
this.MaximizeBox = false;
|
||||
this.Name = "downloadGUI";
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDownMaxServers)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.numericUpDownMaxChunks)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.Label label6;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.Label label8;
|
||||
private System.Windows.Forms.TextBox textBoxUsername;
|
||||
private System.Windows.Forms.TextBox textBoxPassword;
|
||||
private System.Windows.Forms.TextBox textBoxAppID;
|
||||
private System.Windows.Forms.TextBox textBoxDepotID;
|
||||
private System.Windows.Forms.TextBox textBoxManifestID;
|
||||
private System.Windows.Forms.TextBox textBoxArgs;
|
||||
private System.Windows.Forms.Button buttonDownload;
|
||||
private System.Windows.Forms.NumericUpDown numericUpDownMaxServers;
|
||||
private System.Windows.Forms.NumericUpDown numericUpDownMaxChunks;
|
||||
private System.Windows.Forms.Button buttonHelp;
|
||||
private System.Windows.Forms.Button buttonSearch;
|
||||
private System.Windows.Forms.Button buttonRepo;
|
||||
private System.Windows.Forms.Label labelTitle;
|
||||
private System.Windows.Forms.Label labelIssue;
|
||||
private System.Windows.Forms.ToolTip toolTip1;
|
||||
}
|
||||
}
|
||||
|
||||
98
downloadGUI.cs
Normal file
98
downloadGUI.cs
Normal file
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using System.IO;
|
||||
using System.Drawing.Text;
|
||||
using System.Net;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace DepotDownloaderGUI
|
||||
{
|
||||
public partial class downloadGUI : Form
|
||||
{
|
||||
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
|
||||
private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont,
|
||||
IntPtr pdv, [System.Runtime.InteropServices.In] ref uint pcFonts);
|
||||
|
||||
private PrivateFontCollection fonts = new PrivateFontCollection();
|
||||
|
||||
Font Poppins;
|
||||
|
||||
string Command;
|
||||
public downloadGUI()
|
||||
{
|
||||
InitializeComponent();
|
||||
if (!Directory.Exists("DepotDownloader"))
|
||||
{
|
||||
//Download
|
||||
string Download = "https://github.com/SteamRE/DepotDownloader/releases/download/DepotDownloader_2.4.5/depotdownloader-2.4.5.zip";
|
||||
string zipname = "depotdownloader-2.4.5.zip";
|
||||
string extractPath = "DepotDownloader";
|
||||
WebClient ZipDownloader = new WebClient();
|
||||
ZipDownloader.DownloadFile(Download, zipname);
|
||||
//Extract
|
||||
ZipFile.ExtractToDirectory(zipname, extractPath);
|
||||
//Delete
|
||||
File.Delete(zipname);
|
||||
}
|
||||
byte[] fontData = Properties.Resources.Poppins_Medium;
|
||||
IntPtr fontPtr = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(fontData.Length);
|
||||
System.Runtime.InteropServices.Marshal.Copy(fontData, 0, fontPtr, fontData.Length);
|
||||
uint dummy = 0;
|
||||
fonts.AddMemoryFont(fontPtr, Properties.Resources.Poppins_Medium.Length);
|
||||
AddFontMemResourceEx(fontPtr, (uint)Properties.Resources.Poppins_Medium.Length, IntPtr.Zero, ref dummy);
|
||||
System.Runtime.InteropServices.Marshal.FreeCoTaskMem(fontPtr);
|
||||
Poppins = new Font(fonts.Families[0], 18.0F);
|
||||
Directory.SetCurrentDirectory("./DepotDownloader/");
|
||||
labelTitle.Font = Poppins;
|
||||
}
|
||||
|
||||
|
||||
private void buttonDownload_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(textBoxAppID.Text) || string.IsNullOrEmpty(textBoxDepotID.Text) || string.IsNullOrEmpty(textBoxManifestID.Text))
|
||||
{
|
||||
MessageBox.Show("Please fill all required fields.");
|
||||
}
|
||||
else
|
||||
{
|
||||
FolderBrowserDialog folderDlg = new FolderBrowserDialog();
|
||||
DialogResult result = folderDlg.ShowDialog();
|
||||
if (result == DialogResult.OK & result != DialogResult.Cancel)
|
||||
{
|
||||
string selectedpath = folderDlg.SelectedPath;
|
||||
if (textBoxPassword.Text.Length <= 0)
|
||||
{
|
||||
//Todo Remember Password tick
|
||||
Command = $"/k dotnet DepotDownloader.dll -app {textBoxAppID.Text} -depot {textBoxDepotID.Text} -manifest {textBoxManifestID.Text} -max-servers {numericUpDownMaxServers.Value} -max-downloads {numericUpDownMaxChunks.Value} -dir " + '"' + selectedpath + '"' + " " + textBoxArgs.Text;
|
||||
}
|
||||
else
|
||||
{
|
||||
Command = $"/k dotnet DepotDownloader.dll -app {textBoxAppID.Text} -depot {textBoxDepotID.Text} -manifest {textBoxManifestID.Text} -username {textBoxUsername.Text} -password {textBoxPassword.Text} -max-servers {numericUpDownMaxServers.Value} -max-downloads {numericUpDownMaxChunks.Value} -dir " + '"' + selectedpath + '"' + " " + textBoxArgs.Text;
|
||||
}
|
||||
|
||||
open("cmd.exe", Command);
|
||||
}
|
||||
}
|
||||
}
|
||||
private void open(string url, string args = "")
|
||||
{
|
||||
System.Diagnostics.Process.Start(url, args);
|
||||
}
|
||||
|
||||
private void buttonHelp_Click(object sender, EventArgs e)
|
||||
{
|
||||
open("https://github.com/mmvanheusden/SteamDepotDownloaderGUI/discussions/5");
|
||||
}
|
||||
|
||||
private void buttonSearch_Click(object sender, EventArgs e)
|
||||
{
|
||||
open("https://steamdb.info/instantsearch/");
|
||||
}
|
||||
|
||||
private void buttonRepo_Click(object sender, EventArgs e)
|
||||
{
|
||||
open("https://github.com/mmvanheusden/SteamDepotDownloaderGUI");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,7 +126,7 @@
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="label1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>12, 44</value>
|
||||
<value>13, 60</value>
|
||||
</data>
|
||||
<data name="label1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>87, 23</value>
|
||||
@@ -162,7 +162,7 @@
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="label2.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>12, 72</value>
|
||||
<value>13, 96</value>
|
||||
</data>
|
||||
<data name="label2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>80, 23</value>
|
||||
@@ -195,7 +195,7 @@
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="label3.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>12, 100</value>
|
||||
<value>13, 132</value>
|
||||
</data>
|
||||
<data name="label3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>63, 23</value>
|
||||
@@ -228,7 +228,7 @@
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="label4.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>11, 127</value>
|
||||
<value>13, 168</value>
|
||||
</data>
|
||||
<data name="label4.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>79, 23</value>
|
||||
@@ -262,7 +262,7 @@ SteamDB website at 'Depots' in the sidebar.</value>
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="label5.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>11, 158</value>
|
||||
<value>13, 204</value>
|
||||
</data>
|
||||
<data name="label5.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>97, 23</value>
|
||||
@@ -296,7 +296,7 @@ SteamDB website at 'Manifests' in the sidebar.</value>
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="label6.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>11, 192</value>
|
||||
<value>13, 239</value>
|
||||
</data>
|
||||
<data name="label6.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>101, 23</value>
|
||||
@@ -330,7 +330,7 @@ Speeds up download drastically</value>
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="label7.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>12, 223</value>
|
||||
<value>13, 275</value>
|
||||
</data>
|
||||
<data name="label7.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>103, 23</value>
|
||||
@@ -364,7 +364,7 @@ Speeds up download drastically</value>
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="label8.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>11, 249</value>
|
||||
<value>13, 312</value>
|
||||
</data>
|
||||
<data name="label8.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>165, 23</value>
|
||||
@@ -391,373 +391,431 @@ For advanced users</value>
|
||||
<data name=">>label8.ZOrder" xml:space="preserve">
|
||||
<value>14</value>
|
||||
</data>
|
||||
<data name="textBox1.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="textBoxUsername.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
<data name="textBoxUsername.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="textBox1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>117, 44</value>
|
||||
<data name="textBoxUsername.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>187, 57</value>
|
||||
</data>
|
||||
<data name="textBox1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>209, 30</value>
|
||||
<data name="textBoxUsername.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>180, 30</value>
|
||||
</data>
|
||||
<data name="textBox1.TabIndex" type="System.Int32, mscorlib">
|
||||
<data name="textBoxUsername.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name=">>textBox1.Name" xml:space="preserve">
|
||||
<value>textBox1</value>
|
||||
<data name=">>textBoxUsername.Name" xml:space="preserve">
|
||||
<value>textBoxUsername</value>
|
||||
</data>
|
||||
<data name=">>textBox1.Type" xml:space="preserve">
|
||||
<data name=">>textBoxUsername.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>textBox1.Parent" xml:space="preserve">
|
||||
<data name=">>textBoxUsername.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>textBox1.ZOrder" xml:space="preserve">
|
||||
<data name=">>textBoxUsername.ZOrder" xml:space="preserve">
|
||||
<value>13</value>
|
||||
</data>
|
||||
<data name="textBox2.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<data name="textBoxPassword.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
<data name="textBoxPassword.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="textBox2.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>117, 73</value>
|
||||
<data name="textBoxPassword.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>187, 93</value>
|
||||
</data>
|
||||
<data name="textBox2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>209, 30</value>
|
||||
<data name="textBoxPassword.PasswordChar" type="System.Char, mscorlib" xml:space="preserve">
|
||||
<value>*</value>
|
||||
</data>
|
||||
<data name="textBox2.TabIndex" type="System.Int32, mscorlib">
|
||||
<data name="textBoxPassword.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>180, 30</value>
|
||||
</data>
|
||||
<data name="textBoxPassword.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name=">>textBox2.Name" xml:space="preserve">
|
||||
<value>textBox2</value>
|
||||
<data name=">>textBoxPassword.Name" xml:space="preserve">
|
||||
<value>textBoxPassword</value>
|
||||
</data>
|
||||
<data name=">>textBox2.Type" xml:space="preserve">
|
||||
<data name=">>textBoxPassword.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>textBox2.Parent" xml:space="preserve">
|
||||
<data name=">>textBoxPassword.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>textBox2.ZOrder" xml:space="preserve">
|
||||
<data name=">>textBoxPassword.ZOrder" xml:space="preserve">
|
||||
<value>12</value>
|
||||
</data>
|
||||
<data name="textBox3.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<data name="textBoxAppID.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
<data name="textBoxAppID.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="textBox3.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>117, 101</value>
|
||||
<data name="textBoxAppID.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>187, 129</value>
|
||||
</data>
|
||||
<data name="textBox3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>209, 30</value>
|
||||
<data name="textBoxAppID.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>180, 30</value>
|
||||
</data>
|
||||
<data name="textBox3.TabIndex" type="System.Int32, mscorlib">
|
||||
<data name="textBoxAppID.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name=">>textBox3.Name" xml:space="preserve">
|
||||
<value>textBox3</value>
|
||||
<data name=">>textBoxAppID.Name" xml:space="preserve">
|
||||
<value>textBoxAppID</value>
|
||||
</data>
|
||||
<data name=">>textBox3.Type" xml:space="preserve">
|
||||
<data name=">>textBoxAppID.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>textBox3.Parent" xml:space="preserve">
|
||||
<data name=">>textBoxAppID.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>textBox3.ZOrder" xml:space="preserve">
|
||||
<data name=">>textBoxAppID.ZOrder" xml:space="preserve">
|
||||
<value>11</value>
|
||||
</data>
|
||||
<data name="textBox4.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<data name="textBoxDepotID.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
<data name="textBoxDepotID.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="textBox4.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>117, 130</value>
|
||||
<data name="textBoxDepotID.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>187, 165</value>
|
||||
</data>
|
||||
<data name="textBox4.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>209, 30</value>
|
||||
<data name="textBoxDepotID.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>180, 30</value>
|
||||
</data>
|
||||
<data name="textBox4.TabIndex" type="System.Int32, mscorlib">
|
||||
<data name="textBoxDepotID.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name=">>textBox4.Name" xml:space="preserve">
|
||||
<value>textBox4</value>
|
||||
<data name=">>textBoxDepotID.Name" xml:space="preserve">
|
||||
<value>textBoxDepotID</value>
|
||||
</data>
|
||||
<data name=">>textBox4.Type" xml:space="preserve">
|
||||
<data name=">>textBoxDepotID.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>textBox4.Parent" xml:space="preserve">
|
||||
<data name=">>textBoxDepotID.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>textBox4.ZOrder" xml:space="preserve">
|
||||
<data name=">>textBoxDepotID.ZOrder" xml:space="preserve">
|
||||
<value>10</value>
|
||||
</data>
|
||||
<data name="textBox5.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<data name="textBoxManifestID.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
<data name="textBoxManifestID.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="textBox5.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>117, 159</value>
|
||||
<data name="textBoxManifestID.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>187, 201</value>
|
||||
</data>
|
||||
<data name="textBox5.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>209, 30</value>
|
||||
<data name="textBoxManifestID.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>180, 30</value>
|
||||
</data>
|
||||
<data name="textBox5.TabIndex" type="System.Int32, mscorlib">
|
||||
<data name="textBoxManifestID.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name=">>textBox5.Name" xml:space="preserve">
|
||||
<value>textBox5</value>
|
||||
<data name=">>textBoxManifestID.Name" xml:space="preserve">
|
||||
<value>textBoxManifestID</value>
|
||||
</data>
|
||||
<data name=">>textBox5.Type" xml:space="preserve">
|
||||
<data name=">>textBoxManifestID.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>textBox5.Parent" xml:space="preserve">
|
||||
<data name=">>textBoxManifestID.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>textBox5.ZOrder" xml:space="preserve">
|
||||
<data name=">>textBoxManifestID.ZOrder" xml:space="preserve">
|
||||
<value>9</value>
|
||||
</data>
|
||||
<data name="textBox8.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<data name="textBoxArgs.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
<data name="textBoxArgs.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="textBox8.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>182, 249</value>
|
||||
<data name="textBoxArgs.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>187, 309</value>
|
||||
</data>
|
||||
<data name="textBox8.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>144, 30</value>
|
||||
<data name="textBoxArgs.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>180, 30</value>
|
||||
</data>
|
||||
<data name="textBox8.TabIndex" type="System.Int32, mscorlib">
|
||||
<data name="textBoxArgs.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name=">>textBox8.Name" xml:space="preserve">
|
||||
<value>textBox8</value>
|
||||
<data name=">>textBoxArgs.Name" xml:space="preserve">
|
||||
<value>textBoxArgs</value>
|
||||
</data>
|
||||
<data name=">>textBox8.Type" xml:space="preserve">
|
||||
<data name=">>textBoxArgs.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>textBox8.Parent" xml:space="preserve">
|
||||
<data name=">>textBoxArgs.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>textBox8.ZOrder" xml:space="preserve">
|
||||
<data name=">>textBoxArgs.ZOrder" xml:space="preserve">
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name="button1.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<data name="buttonDownload.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Left, Right</value>
|
||||
</data>
|
||||
<data name="buttonDownload.FlatStyle" type="System.Windows.Forms.FlatStyle, System.Windows.Forms">
|
||||
<value>Flat</value>
|
||||
</data>
|
||||
<data name="buttonDownload.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<value>Segoe UI Semibold, 9.75pt, style=Bold</value>
|
||||
</data>
|
||||
<data name="button1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>209, 307</value>
|
||||
<data name="buttonDownload.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>188, 355</value>
|
||||
</data>
|
||||
<data name="button1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>117, 25</value>
|
||||
<data name="buttonDownload.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>179, 57</value>
|
||||
</data>
|
||||
<data name="button1.TabIndex" type="System.Int32, mscorlib">
|
||||
<data name="buttonDownload.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>11</value>
|
||||
</data>
|
||||
<data name="button1.Text" xml:space="preserve">
|
||||
<data name="buttonDownload.Text" xml:space="preserve">
|
||||
<value>Start Download</value>
|
||||
</data>
|
||||
<data name="button1.ToolTip" xml:space="preserve">
|
||||
<data name="buttonDownload.ToolTip" xml:space="preserve">
|
||||
<value>Starts the download</value>
|
||||
</data>
|
||||
<data name=">>button1.Name" xml:space="preserve">
|
||||
<value>button1</value>
|
||||
<data name=">>buttonDownload.Name" xml:space="preserve">
|
||||
<value>buttonDownload</value>
|
||||
</data>
|
||||
<data name=">>button1.Type" xml:space="preserve">
|
||||
<data name=">>buttonDownload.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>button1.Parent" xml:space="preserve">
|
||||
<data name=">>buttonDownload.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>button1.ZOrder" xml:space="preserve">
|
||||
<data name=">>buttonDownload.ZOrder" xml:space="preserve">
|
||||
<value>7</value>
|
||||
</data>
|
||||
<data name="numericUpDown1.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<data name="numericUpDownMaxServers.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
<data name="numericUpDownMaxServers.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="numericUpDown1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>117, 188</value>
|
||||
<data name="numericUpDownMaxServers.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>187, 237</value>
|
||||
</data>
|
||||
<data name="numericUpDown1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>209, 30</value>
|
||||
<data name="numericUpDownMaxServers.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>180, 30</value>
|
||||
</data>
|
||||
<data name="numericUpDown1.TabIndex" type="System.Int32, mscorlib">
|
||||
<data name="numericUpDownMaxServers.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name=">>numericUpDown1.Name" xml:space="preserve">
|
||||
<value>numericUpDown1</value>
|
||||
<data name=">>numericUpDownMaxServers.Name" xml:space="preserve">
|
||||
<value>numericUpDownMaxServers</value>
|
||||
</data>
|
||||
<data name=">>numericUpDown1.Type" xml:space="preserve">
|
||||
<data name=">>numericUpDownMaxServers.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>numericUpDown1.Parent" xml:space="preserve">
|
||||
<data name=">>numericUpDownMaxServers.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>numericUpDown1.ZOrder" xml:space="preserve">
|
||||
<data name=">>numericUpDownMaxServers.ZOrder" xml:space="preserve">
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name="numericUpDown2.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<data name="numericUpDownMaxChunks.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
<data name="numericUpDownMaxChunks.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<value>Segoe UI, 12.75pt</value>
|
||||
</data>
|
||||
<data name="numericUpDown2.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>117, 216</value>
|
||||
<data name="numericUpDownMaxChunks.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>187, 273</value>
|
||||
</data>
|
||||
<data name="numericUpDown2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>209, 30</value>
|
||||
<data name="numericUpDownMaxChunks.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>180, 30</value>
|
||||
</data>
|
||||
<data name="numericUpDown2.TabIndex" type="System.Int32, mscorlib">
|
||||
<data name="numericUpDownMaxChunks.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>7</value>
|
||||
</data>
|
||||
<data name=">>numericUpDown2.Name" xml:space="preserve">
|
||||
<value>numericUpDown2</value>
|
||||
<data name=">>numericUpDownMaxChunks.Name" xml:space="preserve">
|
||||
<value>numericUpDownMaxChunks</value>
|
||||
</data>
|
||||
<data name=">>numericUpDown2.Type" xml:space="preserve">
|
||||
<data name=">>numericUpDownMaxChunks.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.NumericUpDown, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>numericUpDown2.Parent" xml:space="preserve">
|
||||
<data name=">>numericUpDownMaxChunks.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>numericUpDown2.ZOrder" xml:space="preserve">
|
||||
<data name=">>numericUpDownMaxChunks.ZOrder" xml:space="preserve">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="button2.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<data name="buttonHelp.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Left, Right</value>
|
||||
</data>
|
||||
<data name="buttonHelp.FlatStyle" type="System.Windows.Forms.FlatStyle, System.Windows.Forms">
|
||||
<value>Flat</value>
|
||||
</data>
|
||||
<data name="buttonHelp.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<value>Segoe UI Semibold, 9.75pt, style=Bold</value>
|
||||
</data>
|
||||
<data name="button2.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>209, 280</value>
|
||||
<data name="buttonHelp.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>13, 387</value>
|
||||
</data>
|
||||
<data name="button2.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>117, 23</value>
|
||||
<data name="buttonHelp.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>165, 25</value>
|
||||
</data>
|
||||
<data name="button2.TabIndex" type="System.Int32, mscorlib">
|
||||
<data name="buttonHelp.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>9</value>
|
||||
</data>
|
||||
<data name="button2.Text" xml:space="preserve">
|
||||
<data name="buttonHelp.Text" xml:space="preserve">
|
||||
<value>Need Help?</value>
|
||||
</data>
|
||||
<data name=">>button2.Name" xml:space="preserve">
|
||||
<value>button2</value>
|
||||
<data name=">>buttonHelp.Name" xml:space="preserve">
|
||||
<value>buttonHelp</value>
|
||||
</data>
|
||||
<data name=">>button2.Type" xml:space="preserve">
|
||||
<data name=">>buttonHelp.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>button2.Parent" xml:space="preserve">
|
||||
<data name=">>buttonHelp.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>button2.ZOrder" xml:space="preserve">
|
||||
<data name=">>buttonHelp.ZOrder" xml:space="preserve">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name="button3.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<data name="buttonSearch.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Left, Right</value>
|
||||
</data>
|
||||
<data name="buttonSearch.FlatStyle" type="System.Windows.Forms.FlatStyle, System.Windows.Forms">
|
||||
<value>Flat</value>
|
||||
</data>
|
||||
<data name="buttonSearch.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<value>Segoe UI Semibold, 9.75pt, style=Bold</value>
|
||||
</data>
|
||||
<data name="button3.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>12, 280</value>
|
||||
<data name="buttonSearch.ImeMode" type="System.Windows.Forms.ImeMode, System.Windows.Forms">
|
||||
<value>NoControl</value>
|
||||
</data>
|
||||
<data name="button3.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>164, 26</value>
|
||||
<data name="buttonSearch.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>13, 355</value>
|
||||
</data>
|
||||
<data name="button3.TabIndex" type="System.Int32, mscorlib">
|
||||
<data name="buttonSearch.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>165, 25</value>
|
||||
</data>
|
||||
<data name="buttonSearch.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>8</value>
|
||||
</data>
|
||||
<data name="button3.Text" xml:space="preserve">
|
||||
<data name="buttonSearch.Text" xml:space="preserve">
|
||||
<value>SteamDB Instant Search</value>
|
||||
</data>
|
||||
<data name="button3.ToolTip" xml:space="preserve">
|
||||
<data name="buttonSearch.ToolTip" xml:space="preserve">
|
||||
<value>Brings you to the SteamDB Instant game search page.</value>
|
||||
</data>
|
||||
<data name=">>button3.Name" xml:space="preserve">
|
||||
<value>button3</value>
|
||||
<data name=">>buttonSearch.Name" xml:space="preserve">
|
||||
<value>buttonSearch</value>
|
||||
</data>
|
||||
<data name=">>button3.Type" xml:space="preserve">
|
||||
<data name=">>buttonSearch.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>button3.Parent" xml:space="preserve">
|
||||
<data name=">>buttonSearch.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>button3.ZOrder" xml:space="preserve">
|
||||
<data name=">>buttonSearch.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="button4.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<data name="buttonRepo.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Left, Right</value>
|
||||
</data>
|
||||
<data name="buttonRepo.FlatStyle" type="System.Windows.Forms.FlatStyle, System.Windows.Forms">
|
||||
<value>Flat</value>
|
||||
</data>
|
||||
<data name="buttonRepo.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<value>Segoe UI Semibold, 9.75pt, style=Bold</value>
|
||||
</data>
|
||||
<data name="button4.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>12, 309</value>
|
||||
<data name="buttonRepo.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>13, 418</value>
|
||||
</data>
|
||||
<data name="button4.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>164, 23</value>
|
||||
<data name="buttonRepo.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>165, 25</value>
|
||||
</data>
|
||||
<data name="button4.TabIndex" type="System.Int32, mscorlib">
|
||||
<data name="buttonRepo.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>10</value>
|
||||
</data>
|
||||
<data name="button4.Text" xml:space="preserve">
|
||||
<data name="buttonRepo.Text" xml:space="preserve">
|
||||
<value>GitHub Repo</value>
|
||||
</data>
|
||||
<data name="button4.ToolTip" xml:space="preserve">
|
||||
<data name="buttonRepo.ToolTip" xml:space="preserve">
|
||||
<value>Brings you to the GitHub Repository page.</value>
|
||||
</data>
|
||||
<data name=">>button4.Name" xml:space="preserve">
|
||||
<value>button4</value>
|
||||
<data name=">>buttonRepo.Name" xml:space="preserve">
|
||||
<value>buttonRepo</value>
|
||||
</data>
|
||||
<data name=">>button4.Type" xml:space="preserve">
|
||||
<data name=">>buttonRepo.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>button4.Parent" xml:space="preserve">
|
||||
<data name=">>buttonRepo.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>button4.ZOrder" xml:space="preserve">
|
||||
<data name=">>buttonRepo.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<data name="label9.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
<data name="labelTitle.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Left, Right</value>
|
||||
</data>
|
||||
<data name="label9.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<data name="labelTitle.Font" type="System.Drawing.Font, System.Drawing">
|
||||
<value>Segoe UI Semibold, 18pt, style=Bold</value>
|
||||
</data>
|
||||
<data name="label9.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>7, -1</value>
|
||||
<data name="labelTitle.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>12, 9</value>
|
||||
</data>
|
||||
<data name="label9.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>296, 32</value>
|
||||
<data name="labelTitle.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>355, 32</value>
|
||||
</data>
|
||||
<data name="label9.TabIndex" type="System.Int32, mscorlib">
|
||||
<data name="labelTitle.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>13</value>
|
||||
</data>
|
||||
<data name="label9.Text" xml:space="preserve">
|
||||
<data name="labelTitle.Text" xml:space="preserve">
|
||||
<value>Steam Depot Downloader</value>
|
||||
</data>
|
||||
<data name=">>label9.Name" xml:space="preserve">
|
||||
<value>label9</value>
|
||||
<data name="labelTitle.TextAlign" type="System.Drawing.ContentAlignment, System.Drawing">
|
||||
<value>TopCenter</value>
|
||||
</data>
|
||||
<data name=">>label9.Type" xml:space="preserve">
|
||||
<data name=">>labelTitle.Name" xml:space="preserve">
|
||||
<value>labelTitle</value>
|
||||
</data>
|
||||
<data name=">>labelTitle.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>label9.Parent" xml:space="preserve">
|
||||
<data name=">>labelTitle.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>label9.ZOrder" xml:space="preserve">
|
||||
<data name=">>labelTitle.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="label10.AutoSize" type="System.Boolean, mscorlib">
|
||||
<data name="labelIssue.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Bottom, Left, Right</value>
|
||||
</data>
|
||||
<data name="labelIssue.AutoSize" type="System.Boolean, mscorlib">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="label10.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>200, 335</value>
|
||||
<data name="labelIssue.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>186, 425</value>
|
||||
</data>
|
||||
<data name="label10.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>134, 13</value>
|
||||
<data name="labelIssue.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>182, 13</value>
|
||||
</data>
|
||||
<data name="label10.TabIndex" type="System.Int32, mscorlib">
|
||||
<data name="labelIssue.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>14</value>
|
||||
</data>
|
||||
<data name="label10.Text" xml:space="preserve">
|
||||
<value>Star this project on GitHub!</value>
|
||||
<data name="labelIssue.Text" xml:space="preserve">
|
||||
<value>If something is broken open an issue!</value>
|
||||
</data>
|
||||
<data name="label10.ToolTip" xml:space="preserve">
|
||||
<value>Don't forget!!</value>
|
||||
<data name=">>labelIssue.Name" xml:space="preserve">
|
||||
<value>labelIssue</value>
|
||||
</data>
|
||||
<data name=">>label10.Name" xml:space="preserve">
|
||||
<value>label10</value>
|
||||
</data>
|
||||
<data name=">>label10.Type" xml:space="preserve">
|
||||
<data name=">>labelIssue.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>label10.Parent" xml:space="preserve">
|
||||
<data name=">>labelIssue.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>label10.ZOrder" xml:space="preserve">
|
||||
<data name=">>labelIssue.ZOrder" xml:space="preserve">
|
||||
<value>0</value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
@@ -767,7 +825,10 @@ For advanced users</value>
|
||||
<value>6, 13</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>334, 351</value>
|
||||
<value>379, 452</value>
|
||||
</data>
|
||||
<data name="$this.StartPosition" type="System.Windows.Forms.FormStartPosition, System.Windows.Forms">
|
||||
<value>CenterScreen</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>Steam Depot Downloader</value>
|
||||
@@ -779,7 +840,7 @@ For advanced users</value>
|
||||
<value>System.Windows.Forms.ToolTip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>$this.Name" xml:space="preserve">
|
||||
<value>Form1</value>
|
||||
<value>downloadGUI</value>
|
||||
</data>
|
||||
<data name=">>$this.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 19 KiB |
Reference in New Issue
Block a user