├── .gitattributes
├── .gitignore
├── ConfigDownloader.sln
├── LICENSE
├── README.md
└── configdownloader
├── App.config
├── ConfigItem.cs
├── Game.cs
├── Program.cs
├── Properties
├── AssemblyInfo.cs
├── DataSources
│ └── ConfigItem.datasource
├── Resources.Designer.cs
├── Resources.resx
├── Settings.Designer.cs
└── Settings.settings
├── SteamWorkshop.cs
├── configdownloader.csproj
├── games.txt
├── main.Designer.cs
├── main.cs
├── main.resx
├── packages.config
├── steamGuard.Designer.cs
├── steamGuard.cs
├── steamGuard.resx
├── steamLogin.Designer.cs
├── steamLogin.cs
└── steamLogin.resx
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | build/
21 | bld/
22 | [Bb]in/
23 | [Oo]bj/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 |
28 | # MSTest test Results
29 | [Tt]est[Rr]esult*/
30 | [Bb]uild[Ll]og.*
31 |
32 | # NUNIT
33 | *.VisualState.xml
34 | TestResult.xml
35 |
36 | # Build Results of an ATL Project
37 | [Dd]ebugPS/
38 | [Rr]eleasePS/
39 | dlldata.c
40 |
41 | # DNX
42 | project.lock.json
43 | artifacts/
44 |
45 | *_i.c
46 | *_p.c
47 | *_i.h
48 | *.ilk
49 | *.meta
50 | *.obj
51 | *.pch
52 | *.pdb
53 | *.pgc
54 | *.pgd
55 | *.rsp
56 | *.sbr
57 | *.tlb
58 | *.tli
59 | *.tlh
60 | *.tmp
61 | *.tmp_proj
62 | *.log
63 | *.vspscc
64 | *.vssscc
65 | .builds
66 | *.pidb
67 | *.svclog
68 | *.scc
69 |
70 | # Chutzpah Test files
71 | _Chutzpah*
72 |
73 | # Visual C++ cache files
74 | ipch/
75 | *.aps
76 | *.ncb
77 | *.opensdf
78 | *.sdf
79 | *.cachefile
80 |
81 | # Visual Studio profiler
82 | *.psess
83 | *.vsp
84 | *.vspx
85 |
86 | # TFS 2012 Local Workspace
87 | $tf/
88 |
89 | # Guidance Automation Toolkit
90 | *.gpState
91 |
92 | # ReSharper is a .NET coding add-in
93 | _ReSharper*/
94 | *.[Rr]e[Ss]harper
95 | *.DotSettings.user
96 |
97 | # JustCode is a .NET coding add-in
98 | .JustCode
99 |
100 | # TeamCity is a build add-in
101 | _TeamCity*
102 |
103 | # DotCover is a Code Coverage Tool
104 | *.dotCover
105 |
106 | # NCrunch
107 | _NCrunch_*
108 | .*crunch*.local.xml
109 |
110 | # MightyMoose
111 | *.mm.*
112 | AutoTest.Net/
113 |
114 | # Web workbench (sass)
115 | .sass-cache/
116 |
117 | # Installshield output folder
118 | [Ee]xpress/
119 |
120 | # DocProject is a documentation generator add-in
121 | DocProject/buildhelp/
122 | DocProject/Help/*.HxT
123 | DocProject/Help/*.HxC
124 | DocProject/Help/*.hhc
125 | DocProject/Help/*.hhk
126 | DocProject/Help/*.hhp
127 | DocProject/Help/Html2
128 | DocProject/Help/html
129 |
130 | # Click-Once directory
131 | publish/
132 |
133 | # Publish Web Output
134 | *.[Pp]ublish.xml
135 | *.azurePubxml
136 | ## TODO: Comment the next line if you want to checkin your
137 | ## web deploy settings but do note that will include unencrypted
138 | ## passwords
139 | #*.pubxml
140 |
141 | *.publishproj
142 |
143 | # NuGet Packages
144 | *.nupkg
145 | # The packages folder can be ignored because of Package Restore
146 | **/packages/*
147 | # except build/, which is used as an MSBuild target.
148 | !**/packages/build/
149 | # Uncomment if necessary however generally it will be regenerated when needed
150 | #!**/packages/repositories.config
151 |
152 | # Windows Azure Build Output
153 | csx/
154 | *.build.csdef
155 |
156 | # Windows Store app package directory
157 | AppPackages/
158 |
159 | # Visual Studio cache files
160 | # files ending in .cache can be ignored
161 | *.[Cc]ache
162 | # but keep track of directories ending in .cache
163 | !*.[Cc]ache/
164 |
165 | # Others
166 | ClientBin/
167 | [Ss]tyle[Cc]op.*
168 | ~$*
169 | *~
170 | *.dbmdl
171 | *.dbproj.schemaview
172 | *.pfx
173 | *.publishsettings
174 | node_modules/
175 | orleans.codegen.cs
176 |
177 | # RIA/Silverlight projects
178 | Generated_Code/
179 |
180 | # Backup & report files from converting an old project file
181 | # to a newer Visual Studio version. Backup files are not needed,
182 | # because we have git ;-)
183 | _UpgradeReport_Files/
184 | Backup*/
185 | UpgradeLog*.XML
186 | UpgradeLog*.htm
187 |
188 | # SQL Server files
189 | *.mdf
190 | *.ldf
191 |
192 | # Business Intelligence projects
193 | *.rdl.data
194 | *.bim.layout
195 | *.bim_*.settings
196 |
197 | # Microsoft Fakes
198 | FakesAssemblies/
199 |
200 | # Node.js Tools for Visual Studio
201 | .ntvs_analysis.dat
202 |
203 | # Visual Studio 6 build log
204 | *.plg
205 |
206 | # Visual Studio 6 workspace options file
207 | *.opt
208 |
209 | # LightSwitch generated files
210 | GeneratedArtifacts/
211 | _Pvt_Extensions/
212 | ModelManifest.xml
213 |
--------------------------------------------------------------------------------
/ConfigDownloader.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.23107.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "configdownloader", "configdownloader\configdownloader.csproj", "{C46A9BA4-F73A-4D6A-A0FE-D2769E7463AE}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {C46A9BA4-F73A-4D6A-A0FE-D2769E7463AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {C46A9BA4-F73A-4D6A-A0FE-D2769E7463AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {C46A9BA4-F73A-4D6A-A0FE-D2769E7463AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {C46A9BA4-F73A-4D6A-A0FE-D2769E7463AE}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Niko Pahajoki
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is pretty outdated, check forks like:
2 |
3 | https://github.com/gryffyn/SCConfigDownloader
4 |
5 | # Steam Controller Config Downloader
6 |
7 | Simple tool to download configuration files for non-steam versions of games.
8 |
9 |
--------------------------------------------------------------------------------
/configdownloader/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/configdownloader/ConfigItem.cs:
--------------------------------------------------------------------------------
1 | using SteamKit2.Unified.Internal;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace configdownloader
9 | {
10 | public class ConfigItem
11 | {
12 | public string App { get; set; }
13 |
14 | public string Name { get; set; }
15 |
16 | public string URL { get; set; }
17 |
18 | public string FileName { get; set; }
19 |
20 | public uint RatesUp { get; set; }
21 |
22 | public uint RatesDown { get; set; }
23 |
24 | public PublishedFileDetails Details { get; set; }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/configdownloader/Game.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace configdownloader
8 | {
9 | public class Game
10 | {
11 | public uint AppID { get; set; }
12 |
13 | public string Name { get; set; }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/configdownloader/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Windows.Forms;
6 |
7 | namespace configdownloader
8 | {
9 | static class Program
10 | {
11 | ///
12 | /// The main entry point for the application.
13 | ///
14 | [STAThread]
15 | static void Main()
16 | {
17 | Application.EnableVisualStyles();
18 | Application.SetCompatibleTextRenderingDefault(false);
19 | Application.Run(new main());
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/configdownloader/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Steam Controller Config Downloader")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Steam Controller Config Downloader")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("c46a9ba4-f73a-4d6a-a0fe-d2769e7463ae")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.2.0")]
36 | [assembly: AssemblyFileVersion("1.0.2.0")]
37 |
--------------------------------------------------------------------------------
/configdownloader/Properties/DataSources/ConfigItem.datasource:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 | configdownloader.ConfigItem, configdownloader, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
10 |
--------------------------------------------------------------------------------
/configdownloader/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace configdownloader.Properties
12 | {
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources
26 | {
27 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// Returns the cached ResourceManager instance used by this class.
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ((resourceMan == null))
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("configdownloader.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// Overrides the current thread's CurrentUICulture property for all
56 | /// resource lookups using this strongly typed resource class.
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/configdownloader/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/configdownloader/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace configdownloader.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/configdownloader/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/configdownloader/SteamWorkshop.cs:
--------------------------------------------------------------------------------
1 | using SteamKit2;
2 | using SteamKit2.Internal;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace configdownloader
10 | {
11 | public class SteamWorkshop : ClientMsgHandler
12 | {
13 | public class WorkshopInfoCallback : CallbackMsg
14 | {
15 |
16 | public class WorkshopItem
17 | {
18 | public ulong PublishedFileID { get; set; }
19 |
20 | public ulong ManifestID { get; set; }
21 | }
22 |
23 | public List Items { get; } = new List();
24 |
25 | internal WorkshopInfoCallback(JobID job, EResult result, IEnumerable items)
26 | {
27 | JobID = job;
28 |
29 | Items.AddRange(items);
30 | }
31 | }
32 |
33 | public AsyncJob RequestInfo(uint app, ulong workshopid)
34 | {
35 | var msg = new ClientMsgProtobuf(EMsg.ClientWorkshopItemInfoRequest);
36 | msg.SourceJobID = Client.GetNextJobID();
37 | msg.Body.app_id = app;
38 | msg.Body.last_time_updated = 0;
39 | msg.Body.workshop_items.Add(new CMsgClientWorkshopItemInfoRequest.WorkshopItem() { published_file_id = workshopid, time_updated = 0 });
40 |
41 | Client.Send(msg);
42 |
43 | return new AsyncJob(Client, msg.SourceJobID);
44 | }
45 |
46 | public override void HandleMsg(IPacketMsg packetMsg)
47 | {
48 | switch (packetMsg.MsgType)
49 | {
50 | case EMsg.ClientWorkshopItemInfoResponse:
51 | HandleWorkshopItemInfoResponse(packetMsg);
52 | break;
53 | }
54 | }
55 |
56 | private void HandleWorkshopItemInfoResponse(IPacketMsg packetMsg)
57 | {
58 | var msg = new ClientMsgProtobuf(packetMsg);
59 |
60 | EResult err = (EResult)msg.Body.eresult;
61 |
62 | var items = msg.Body.workshop_items.Select(x => new WorkshopInfoCallback.WorkshopItem()
63 | {
64 | PublishedFileID = x.published_file_id,
65 | ManifestID = x.manifest_id
66 | });
67 |
68 | Client.PostCallback(new WorkshopInfoCallback(msg.TargetJobID, (EResult) msg.Body.eresult, items));
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/configdownloader/configdownloader.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {C46A9BA4-F73A-4D6A-A0FE-D2769E7463AE}
8 | WinExe
9 | Properties
10 | configdownloader
11 | configdownloader
12 | v4.5.2
13 | 512
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 | ..\packages\protobuf-net.2.0.0.668\lib\net40\protobuf-net.dll
38 | True
39 |
40 |
41 | ..\packages\SteamKit2.1.7.0\lib\net45\SteamKit2.dll
42 | True
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | Form
61 |
62 |
63 | main.cs
64 |
65 |
66 |
67 |
68 | Form
69 |
70 |
71 | steamLogin.cs
72 |
73 |
74 | Form
75 |
76 |
77 | steamGuard.cs
78 |
79 |
80 |
81 | main.cs
82 |
83 |
84 | ResXFileCodeGenerator
85 | Resources.Designer.cs
86 | Designer
87 |
88 |
89 | True
90 | Resources.resx
91 |
92 |
93 | steamLogin.cs
94 |
95 |
96 | steamGuard.cs
97 |
98 |
99 |
100 |
101 | SettingsSingleFileGenerator
102 | Settings.Designer.cs
103 |
104 |
105 | True
106 | Settings.settings
107 | True
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 | Always
116 |
117 |
118 |
119 |
126 |
--------------------------------------------------------------------------------
/configdownloader/main.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace configdownloader
2 | {
3 | partial class main
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.components = new System.ComponentModel.Container();
32 | this.inputAppID = new System.Windows.Forms.TextBox();
33 | this.label1 = new System.Windows.Forms.Label();
34 | this.get = new System.Windows.Forms.Button();
35 | this.datagridConfigs = new System.Windows.Forms.DataGridView();
36 | this.appDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
37 | this.nameDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
38 | this.RatesUp = new System.Windows.Forms.DataGridViewTextBoxColumn();
39 | this.RatesDown = new System.Windows.Forms.DataGridViewTextBoxColumn();
40 | this.configItemBindingSource = new System.Windows.Forms.BindingSource(this.components);
41 | this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
42 | this.statusStrip1 = new System.Windows.Forms.StatusStrip();
43 | this.currentStatus = new System.Windows.Forms.ToolStripStatusLabel();
44 | ((System.ComponentModel.ISupportInitialize)(this.datagridConfigs)).BeginInit();
45 | ((System.ComponentModel.ISupportInitialize)(this.configItemBindingSource)).BeginInit();
46 | this.statusStrip1.SuspendLayout();
47 | this.SuspendLayout();
48 | //
49 | // inputAppID
50 | //
51 | this.inputAppID.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
52 | | System.Windows.Forms.AnchorStyles.Right)));
53 | this.inputAppID.Location = new System.Drawing.Point(55, 6);
54 | this.inputAppID.Name = "inputAppID";
55 | this.inputAppID.Size = new System.Drawing.Size(659, 20);
56 | this.inputAppID.TabIndex = 0;
57 | this.inputAppID.TextChanged += new System.EventHandler(this.inputAppID_TextChanged);
58 | this.inputAppID.KeyUp += new System.Windows.Forms.KeyEventHandler(this.inputAppID_KeyUp);
59 | //
60 | // label1
61 | //
62 | this.label1.AutoSize = true;
63 | this.label1.Location = new System.Drawing.Point(12, 9);
64 | this.label1.Name = "label1";
65 | this.label1.Size = new System.Drawing.Size(37, 13);
66 | this.label1.TabIndex = 1;
67 | this.label1.Text = "AppID";
68 | //
69 | // get
70 | //
71 | this.get.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
72 | this.get.Location = new System.Drawing.Point(720, 6);
73 | this.get.Name = "get";
74 | this.get.Size = new System.Drawing.Size(75, 20);
75 | this.get.TabIndex = 2;
76 | this.get.Text = "Get";
77 | this.get.UseVisualStyleBackColor = true;
78 | this.get.Click += new System.EventHandler(this.get_Click);
79 | //
80 | // datagridConfigs
81 | //
82 | this.datagridConfigs.AllowUserToAddRows = false;
83 | this.datagridConfigs.AllowUserToDeleteRows = false;
84 | this.datagridConfigs.AllowUserToResizeRows = false;
85 | this.datagridConfigs.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
86 | | System.Windows.Forms.AnchorStyles.Left)
87 | | System.Windows.Forms.AnchorStyles.Right)));
88 | this.datagridConfigs.AutoGenerateColumns = false;
89 | this.datagridConfigs.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.Disable;
90 | this.datagridConfigs.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
91 | this.datagridConfigs.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
92 | this.appDataGridViewTextBoxColumn,
93 | this.nameDataGridViewTextBoxColumn,
94 | this.RatesUp,
95 | this.RatesDown});
96 | this.datagridConfigs.DataSource = this.configItemBindingSource;
97 | this.datagridConfigs.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
98 | this.datagridConfigs.Location = new System.Drawing.Point(12, 32);
99 | this.datagridConfigs.MultiSelect = false;
100 | this.datagridConfigs.Name = "datagridConfigs";
101 | this.datagridConfigs.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
102 | this.datagridConfigs.RowHeadersVisible = false;
103 | this.datagridConfigs.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
104 | this.datagridConfigs.Size = new System.Drawing.Size(783, 302);
105 | this.datagridConfigs.TabIndex = 3;
106 | this.datagridConfigs.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellDoubleClick);
107 | //
108 | // appDataGridViewTextBoxColumn
109 | //
110 | this.appDataGridViewTextBoxColumn.DataPropertyName = "App";
111 | this.appDataGridViewTextBoxColumn.HeaderText = "App";
112 | this.appDataGridViewTextBoxColumn.Name = "appDataGridViewTextBoxColumn";
113 | //
114 | // nameDataGridViewTextBoxColumn
115 | //
116 | this.nameDataGridViewTextBoxColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
117 | this.nameDataGridViewTextBoxColumn.DataPropertyName = "Name";
118 | this.nameDataGridViewTextBoxColumn.HeaderText = "Name";
119 | this.nameDataGridViewTextBoxColumn.Name = "nameDataGridViewTextBoxColumn";
120 | //
121 | // RatesUp
122 | //
123 | this.RatesUp.DataPropertyName = "RatesUp";
124 | this.RatesUp.HeaderText = "RatesUp";
125 | this.RatesUp.Name = "RatesUp";
126 | //
127 | // RatesDown
128 | //
129 | this.RatesDown.DataPropertyName = "RatesDown";
130 | this.RatesDown.HeaderText = "RatesDown";
131 | this.RatesDown.Name = "RatesDown";
132 | //
133 | // configItemBindingSource
134 | //
135 | this.configItemBindingSource.DataSource = typeof(configdownloader.ConfigItem);
136 | //
137 | // saveFileDialog1
138 | //
139 | this.saveFileDialog1.Filter = "Config|*.vdf";
140 | //
141 | // statusStrip1
142 | //
143 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
144 | this.currentStatus});
145 | this.statusStrip1.Location = new System.Drawing.Point(0, 342);
146 | this.statusStrip1.Name = "statusStrip1";
147 | this.statusStrip1.Size = new System.Drawing.Size(803, 22);
148 | this.statusStrip1.TabIndex = 4;
149 | this.statusStrip1.Text = "statusStrip1";
150 | //
151 | // currentStatus
152 | //
153 | this.currentStatus.Name = "currentStatus";
154 | this.currentStatus.Size = new System.Drawing.Size(128, 17);
155 | this.currentStatus.Text = "Connecting to Steam...";
156 | //
157 | // main
158 | //
159 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
160 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
161 | this.ClientSize = new System.Drawing.Size(803, 364);
162 | this.Controls.Add(this.statusStrip1);
163 | this.Controls.Add(this.datagridConfigs);
164 | this.Controls.Add(this.get);
165 | this.Controls.Add(this.label1);
166 | this.Controls.Add(this.inputAppID);
167 | this.Name = "main";
168 | this.Text = "Steam Controller Config Downloader";
169 | this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.main_FormClosed);
170 | this.Load += new System.EventHandler(this.main_Load);
171 | ((System.ComponentModel.ISupportInitialize)(this.datagridConfigs)).EndInit();
172 | ((System.ComponentModel.ISupportInitialize)(this.configItemBindingSource)).EndInit();
173 | this.statusStrip1.ResumeLayout(false);
174 | this.statusStrip1.PerformLayout();
175 | this.ResumeLayout(false);
176 | this.PerformLayout();
177 |
178 | }
179 |
180 | #endregion
181 |
182 | private System.Windows.Forms.TextBox inputAppID;
183 | private System.Windows.Forms.Label label1;
184 | private System.Windows.Forms.Button get;
185 | private System.Windows.Forms.DataGridView datagridConfigs;
186 | private System.Windows.Forms.DataGridViewTextBoxColumn appDataGridViewTextBoxColumn;
187 | private System.Windows.Forms.DataGridViewTextBoxColumn nameDataGridViewTextBoxColumn;
188 | private System.Windows.Forms.BindingSource configItemBindingSource;
189 | private System.Windows.Forms.SaveFileDialog saveFileDialog1;
190 | private System.Windows.Forms.DataGridViewTextBoxColumn RatesUp;
191 | private System.Windows.Forms.DataGridViewTextBoxColumn RatesDown;
192 | private System.Windows.Forms.StatusStrip statusStrip1;
193 | private System.Windows.Forms.ToolStripStatusLabel currentStatus;
194 | }
195 | }
196 |
197 |
--------------------------------------------------------------------------------
/configdownloader/main.cs:
--------------------------------------------------------------------------------
1 | using SteamKit2;
2 | using SteamKit2.Unified.Internal;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.ComponentModel;
6 | using System.Data;
7 | using System.Drawing;
8 | using System.IO;
9 | using System.Linq;
10 | using System.Net;
11 | using System.Security.Cryptography;
12 | using System.Text;
13 | using System.Threading;
14 | using System.Threading.Tasks;
15 | using System.Windows.Forms;
16 |
17 | namespace configdownloader
18 | {
19 | public partial class main : Form
20 | {
21 | bool isRunning = true;
22 |
23 | bool isReady = false;
24 |
25 | bool requestOnGoing = false;
26 |
27 | uint appidCurrent = 0;
28 |
29 | ///
30 | /// Items to requests per query, 100 is maximum allowed by Steam
31 | ///
32 | uint itemsPerPage = 100;
33 |
34 | List Games = new List();
35 |
36 | BindingList items = new BindingList();
37 |
38 | List names = new List();
39 |
40 | #region "Steam Connection"
41 | Thread steamThread;
42 |
43 | SteamClient steamClient;
44 | CallbackManager manager;
45 | SteamUser steamUser;
46 | SteamWorkshop steamWorkshop;
47 |
48 | string username = "";
49 | string password = "";
50 | string loginkey = "";
51 | string steamguard;
52 | string twofactor;
53 | bool doReconnect = true;
54 | bool rememberLogin = false;
55 |
56 | void steam_connection()
57 | {
58 | SteamDirectory.Initialize();
59 |
60 | steamClient = new SteamClient();
61 | steamWorkshop = new SteamWorkshop();
62 |
63 | steamClient.AddHandler(steamWorkshop);
64 |
65 | manager = new CallbackManager(steamClient);
66 |
67 | steamUser = steamClient.GetHandler();
68 |
69 | manager.Subscribe(OnConnected);
70 | manager.Subscribe(OnLoggedOn);
71 | manager.Subscribe(OnLoggedOff);
72 | manager.Subscribe(OnDisconnect);
73 | manager.Subscribe(OnMachineAuth);
74 | manager.Subscribe(OnLoginKey);
75 |
76 | steamClient.Connect();
77 |
78 | while (isRunning)
79 | {
80 | try {
81 | manager.RunWaitCallbacks(TimeSpan.FromSeconds(1));
82 | }
83 | catch (Exception)
84 | {
85 | }
86 | }
87 | }
88 |
89 | void OnConnected(SteamClient.ConnectedCallback callback)
90 | {
91 | setStatus("Connected to Steam!");
92 |
93 | if (callback.Result != EResult.OK)
94 | {
95 | MessageBox.Show("Failed to connect to steam");
96 | Application.Exit();
97 | }
98 |
99 | if (string.IsNullOrEmpty(username))
100 | steamUser.LogOnAnonymous();
101 | else
102 | {
103 | byte[] sentryHash = null;
104 |
105 | if (File.Exists("steamguard.bin"))
106 | {
107 | // if we have a saved sentry file, read and sha-1 hash it
108 | byte[] sentryFile = File.ReadAllBytes("steamguard.bin");
109 | sentryHash = CryptoHelper.SHAHash(sentryFile);
110 | }
111 |
112 | steamUser.LogOn(new SteamUser.LogOnDetails()
113 | {
114 | Username = username,
115 | Password = password,
116 | LoginKey = loginkey,
117 | AuthCode = steamguard,
118 | TwoFactorCode = twofactor,
119 | ShouldRememberPassword = rememberLogin,
120 | LoginID = 1
121 | });
122 | }
123 | }
124 |
125 | void OnDisconnect(SteamClient.DisconnectedCallback callback)
126 | {
127 | setStatus("Disconnected from Steam!");
128 |
129 | if (doReconnect && !callback.UserInitiated)
130 | {
131 | Task.Delay(TimeSpan.FromSeconds(5)).ContinueWith(x=>steamClient.Connect());
132 | }
133 | else if (callback.UserInitiated)
134 | isRunning = false;
135 | }
136 |
137 | void OnLoggedOn(SteamUser.LoggedOnCallback callback)
138 | {
139 | if (callback.Result != EResult.OK)
140 | {
141 | doReconnect = false;
142 |
143 | if (callback.Result == EResult.AccountLogonDenied)
144 | {
145 | using (var dialog = new steamGuard())
146 | {
147 | if (dialog.ShowDialog() == DialogResult.OK)
148 | {
149 | steamguard = dialog.codeInput.Text;
150 | steamClient.Connect();
151 | return;
152 | }
153 | }
154 | }
155 | else if (callback.Result == EResult.AccountLoginDeniedNeedTwoFactor || callback.Result == EResult.TwoFactorCodeMismatch)
156 | {
157 | using (var dialog = new steamGuard())
158 | {
159 | if (dialog.ShowDialog() == DialogResult.OK)
160 | {
161 | twofactor = dialog.codeInput.Text;
162 | steamClient.Connect();
163 | return;
164 | }
165 | }
166 | }
167 |
168 | MessageBox.Show("Failed to connect to steam");
169 | Application.Exit();
170 | }
171 |
172 | isReady = true;
173 | doReconnect = true;
174 | steamguard = twofactor = "";
175 |
176 | setStatus("Logged to Steam!");
177 | }
178 |
179 | private void OnLoginKey(SteamUser.LoginKeyCallback callback)
180 | {
181 | if (rememberLogin)
182 | File.WriteAllText("login.dat", $"{username}|{callback.LoginKey}");
183 | }
184 |
185 | void OnLoggedOff(SteamUser.LoggedOffCallback callback)
186 | {
187 | }
188 |
189 | void OnMachineAuth(SteamUser.UpdateMachineAuthCallback callback)
190 | {
191 | int fileSize;
192 | byte[] sentryHash;
193 | using (var fs = File.Open("steamguard.bin", FileMode.OpenOrCreate, FileAccess.ReadWrite))
194 | {
195 | fs.Seek(callback.Offset, SeekOrigin.Begin);
196 | fs.Write(callback.Data, 0, callback.BytesToWrite);
197 | fileSize = (int)fs.Length;
198 |
199 | fs.Seek(0, SeekOrigin.Begin);
200 | using (var sha = new SHA1CryptoServiceProvider())
201 | {
202 | sentryHash = sha.ComputeHash(fs);
203 | }
204 | }
205 |
206 | // inform the steam servers that we're accepting this sentry file
207 | steamUser.SendMachineAuthResponse(new SteamUser.MachineAuthDetails
208 | {
209 | JobID = callback.JobID,
210 |
211 | FileName = callback.FileName,
212 |
213 | BytesWritten = callback.BytesToWrite,
214 | FileSize = fileSize,
215 | Offset = callback.Offset,
216 |
217 | Result = EResult.OK,
218 | LastError = 0,
219 |
220 | OneTimePassword = callback.OneTimePassword,
221 |
222 | SentryFileHash = sentryHash,
223 | });
224 | }
225 | #endregion
226 |
227 | void setStatus(string text)
228 | {
229 | try
230 | {
231 | Invoke(new MethodInvoker(delegate
232 | {
233 | currentStatus.Text = text;
234 | }));
235 | }
236 | catch (Exception)
237 | {
238 | }
239 | }
240 |
241 | void setStatus(string text, params object[] args)
242 | {
243 | setStatus(string.Format(text, args));
244 | }
245 |
246 | async void startNewRequest()
247 | {
248 | if (!isReady)
249 | {
250 | MessageBox.Show("Waiting for connection!");
251 | return;
252 | }
253 |
254 | if (requestOnGoing)
255 | {
256 | MessageBox.Show("Waiting for results");
257 | return;
258 | }
259 |
260 | if (!string.IsNullOrWhiteSpace(inputAppID.Text))
261 | {
262 | if (!uint.TryParse(inputAppID.Text.Trim(), out appidCurrent))
263 | {
264 | var game = Games.Where(x => x.Name == inputAppID.Text).FirstOrDefault();
265 |
266 | if (game != null)
267 | appidCurrent = game.AppID;
268 | else
269 | {
270 | MessageBox.Show("Invalid AppID");
271 | return;
272 | }
273 | }
274 | }
275 | else
276 | {
277 | appidCurrent = 0;
278 | }
279 |
280 | requestOnGoing = true;
281 |
282 | items.Clear();
283 |
284 | await sendRequest();
285 | }
286 |
287 | ///
288 | /// Sends request for controller configs
289 | ///
290 | async Task sendRequest(bool is_new = true)
291 | {
292 | requestOnGoing = true;
293 |
294 | try
295 | {
296 | uint pageCurrent = 1;
297 | uint totalPages = 0;
298 |
299 | var service = steamClient.GetHandler().CreateService();
300 |
301 | do
302 | {
303 | if (totalPages > 0)
304 | setStatus("Requesting page {0} of {1}", pageCurrent, totalPages);
305 | else
306 | setStatus("Requesting page {0}", pageCurrent, totalPages);
307 |
308 | var query = new CPublishedFile_QueryFiles_Request
309 | {
310 | return_vote_data = true,
311 | return_children = true,
312 | return_for_sale_data = true,
313 | return_kv_tags = true,
314 | return_metadata = true,
315 | return_tags = true,
316 | return_previews = true,
317 | appid = is_new ? 241100 : appidCurrent,
318 | page = pageCurrent,
319 | numperpage = itemsPerPage,
320 | query_type = 11,
321 | filetype = (uint)EWorkshopFileType.GameManagedItem,
322 | };
323 |
324 | if (is_new)
325 | {
326 | if (appidCurrent > 0)
327 | query.required_kv_tags.Add(new CPublishedFile_QueryFiles_Request.KVTag() { key = "app", value = appidCurrent.ToString() });
328 |
329 | query.required_kv_tags.Add(new CPublishedFile_QueryFiles_Request.KVTag() { key = "visibility", value = "public" });
330 | }
331 |
332 | var callback = await service.SendMessage(x => x.QueryFiles(query));
333 | var response = callback.GetDeserializedResponse();
334 |
335 | totalPages = (uint)Math.Ceiling(response.total / (double)itemsPerPage);
336 | pageCurrent++;
337 |
338 | foreach (var item in response.publishedfiledetails)
339 | {
340 | var info = new ConfigItem
341 | {
342 | App = item.app_name,
343 | Name = item.title,
344 | FileName = item.filename.Split('/').Last(),
345 | URL = item.file_url,
346 | RatesUp = item.vote_data != null ? item.vote_data.votes_up : 0,
347 | RatesDown = item.vote_data != null ? item.vote_data.votes_down : 0,
348 | Details = item
349 | };
350 |
351 | foreach (var tag in item.kvtags)
352 | {
353 | if (tag.key == "app" || tag.key == "appid")
354 | {
355 | uint app = 0;
356 |
357 | if (!uint.TryParse(tag.value, out app))
358 | {
359 | info.App = $"(NON-STEAM) {tag.value}";
360 | }
361 | else
362 | {
363 | var game = Games.Where(x => x.AppID == app).FirstOrDefault();
364 |
365 | if (game != null)
366 | {
367 | info.App = game.Name;
368 | }
369 | // We don't know actual name
370 | else
371 | {
372 | info.App = $"AppID {app}";
373 | }
374 | }
375 | }
376 | else if (tag.key == "visibility" || tag.key == "deleted" || tag.key == "owner" || tag.key == "autosave")
377 | continue;
378 | else
379 | {
380 |
381 | }
382 | }
383 |
384 | Invoke(new MethodInvoker(delegate
385 | {
386 | items.Add(info);
387 | }));
388 | }
389 | }
390 | while (pageCurrent <= totalPages);
391 | }
392 | catch (Exception)
393 | {
394 | return false;
395 | }
396 | finally
397 | {
398 | setStatus("Complete!");
399 |
400 | requestOnGoing = false;
401 | }
402 |
403 | return true;
404 | }
405 |
406 | public main()
407 | {
408 | InitializeComponent();
409 |
410 | if (File.Exists("login.dat"))
411 | {
412 | var f = File.ReadAllText("login.dat").Split('|');
413 | username = f[0];
414 | loginkey = f[1];
415 | rememberLogin = true;
416 | }
417 | else
418 | {
419 | using (var dialog = new steamLogin())
420 | {
421 | if (dialog.ShowDialog() == DialogResult.OK)
422 | {
423 | username = dialog.usernameInput.Text;
424 | password = dialog.passwordInput.Text;
425 | rememberLogin = dialog.rememberLogin.Checked;
426 | }
427 | }
428 | }
429 |
430 | steamThread = new Thread(steam_connection);
431 | steamThread.Start();
432 |
433 | if (File.Exists("games.txt"))
434 | {
435 | foreach (var line in File.ReadAllLines("games.txt"))
436 | {
437 | var parts = line.Split(new char[] { '\t' }, 2);
438 |
439 | Games.Add(new Game
440 | {
441 | AppID = uint.Parse(parts[0]),
442 | Name = parts[1]
443 | });
444 | }
445 | }
446 | }
447 |
448 | private void main_Load(object sender, EventArgs e)
449 | {
450 | configItemBindingSource.DataSource = items;
451 |
452 | var source = new AutoCompleteStringCollection();
453 | source.AddRange(Games.Select(x => x.Name).ToArray());
454 |
455 | inputAppID.AutoCompleteCustomSource = source;
456 | inputAppID.AutoCompleteSource = AutoCompleteSource.CustomSource;
457 | inputAppID.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
458 | }
459 |
460 | private void get_Click(object sender, EventArgs e)
461 | {
462 | startNewRequest();
463 | }
464 |
465 | async private void dataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
466 | {
467 | if (e.RowIndex < 0)
468 | return;
469 |
470 | try
471 | {
472 | ConfigItem item = datagridConfigs.Rows[e.RowIndex].DataBoundItem as ConfigItem;
473 |
474 | if (item != null)
475 | {
476 | if (item.URL == "")
477 | {
478 | var callback = await steamWorkshop.RequestInfo(241100, item.Details.publishedfileid);
479 |
480 | var itemInfo = callback.Items.FirstOrDefault();
481 |
482 | var ticket = await steamClient.GetHandler().GetAppOwnershipTicket(241100);
483 |
484 | var decryptKey = await steamClient.GetHandler().GetDepotDecryptionKey(241100, 241100);
485 |
486 | var cdn = new CDNClient(steamClient, ticket.Ticket);
487 |
488 | var servers = cdn.FetchServerList();
489 |
490 | cdn.Connect(servers.First());
491 | cdn.AuthenticateDepot(241100, decryptKey.DepotKey);
492 |
493 | var manifest = cdn.DownloadManifest(241100, itemInfo.ManifestID);
494 | manifest.DecryptFilenames(decryptKey.DepotKey);
495 |
496 | if (manifest.Files.First().TotalSize == 0)
497 | {
498 | MessageBox.Show("Steam Refused Download Request");
499 | return;
500 | }
501 |
502 | var chunk = cdn.DownloadDepotChunk(241100, manifest.Files.First().Chunks.First());
503 |
504 | if (saveFileDialog1.ShowDialog() == DialogResult.OK)
505 | {
506 | using (var wc = new WebClient())
507 | {
508 | using (var io = saveFileDialog1.OpenFile())
509 | {
510 | io.Write(chunk.Data, 0, chunk.Data.Length);
511 | MessageBox.Show("Download Done!");
512 | }
513 | }
514 | }
515 | }
516 | else
517 | {
518 | if (saveFileDialog1.ShowDialog() == DialogResult.OK)
519 | {
520 | using (var wc = new WebClient())
521 | {
522 | wc.DownloadFile(new Uri(item.URL), saveFileDialog1.FileName);
523 | MessageBox.Show("Download Done!");
524 | }
525 | }
526 | }
527 | }
528 | }
529 | catch (TaskCanceledException)
530 | {
531 | MessageBox.Show("Timeout! This can happen if you're using anonymous account and trying to download.");
532 | }
533 | catch (Exception ex)
534 | {
535 | MessageBox.Show($"Error Downloading Config: {ex.ToString()}");
536 | }
537 | }
538 |
539 | private void main_FormClosed(object sender, FormClosedEventArgs e)
540 | {
541 | steamClient.Disconnect();
542 | }
543 |
544 | private void inputAppID_TextChanged(object sender, EventArgs e)
545 | {
546 | }
547 |
548 | private void inputAppID_KeyUp(object sender, KeyEventArgs e)
549 | {
550 | if (e.KeyCode == Keys.Enter)
551 | {
552 | startNewRequest();
553 | }
554 | }
555 | }
556 | }
557 |
--------------------------------------------------------------------------------
/configdownloader/main.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | True
122 |
123 |
124 | True
125 |
126 |
127 | 153, 17
128 |
129 |
130 | 206, 17
131 |
132 |
133 | 342, 17
134 |
135 |
--------------------------------------------------------------------------------
/configdownloader/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/configdownloader/steamGuard.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace configdownloader
2 | {
3 | partial class steamGuard
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.codeInput = new System.Windows.Forms.TextBox();
32 | this.button1 = new System.Windows.Forms.Button();
33 | this.SuspendLayout();
34 | //
35 | // codeInput
36 | //
37 | this.codeInput.Font = new System.Drawing.Font("Microsoft Sans Serif", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
38 | this.codeInput.Location = new System.Drawing.Point(12, 12);
39 | this.codeInput.Name = "codeInput";
40 | this.codeInput.Size = new System.Drawing.Size(328, 44);
41 | this.codeInput.TabIndex = 0;
42 | //
43 | // button1
44 | //
45 | this.button1.DialogResult = System.Windows.Forms.DialogResult.OK;
46 | this.button1.Location = new System.Drawing.Point(265, 62);
47 | this.button1.Name = "button1";
48 | this.button1.Size = new System.Drawing.Size(75, 23);
49 | this.button1.TabIndex = 1;
50 | this.button1.Text = "OK";
51 | this.button1.UseVisualStyleBackColor = true;
52 | //
53 | // steamGuard
54 | //
55 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
56 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
57 | this.ClientSize = new System.Drawing.Size(352, 89);
58 | this.Controls.Add(this.button1);
59 | this.Controls.Add(this.codeInput);
60 | this.Name = "steamGuard";
61 | this.Text = "Steam Guard Code";
62 | this.Load += new System.EventHandler(this.steamGuard_Load);
63 | this.ResumeLayout(false);
64 | this.PerformLayout();
65 |
66 | }
67 |
68 | #endregion
69 | private System.Windows.Forms.Button button1;
70 | internal System.Windows.Forms.TextBox codeInput;
71 | }
72 | }
--------------------------------------------------------------------------------
/configdownloader/steamGuard.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | namespace configdownloader
12 | {
13 | public partial class steamGuard : Form
14 | {
15 | public steamGuard()
16 | {
17 | InitializeComponent();
18 | }
19 |
20 | private void steamGuard_Load(object sender, EventArgs e)
21 | {
22 |
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/configdownloader/steamGuard.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/configdownloader/steamLogin.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace configdownloader
2 | {
3 | partial class steamLogin
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.usernameInput = new System.Windows.Forms.TextBox();
32 | this.button1 = new System.Windows.Forms.Button();
33 | this.passwordInput = new System.Windows.Forms.TextBox();
34 | this.rememberLogin = new System.Windows.Forms.CheckBox();
35 | this.button2 = new System.Windows.Forms.Button();
36 | this.label1 = new System.Windows.Forms.Label();
37 | this.SuspendLayout();
38 | //
39 | // usernameInput
40 | //
41 | this.usernameInput.Font = new System.Drawing.Font("Microsoft Sans Serif", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
42 | this.usernameInput.Location = new System.Drawing.Point(8, 38);
43 | this.usernameInput.Name = "usernameInput";
44 | this.usernameInput.Size = new System.Drawing.Size(328, 44);
45 | this.usernameInput.TabIndex = 0;
46 | this.usernameInput.TextChanged += new System.EventHandler(this.usernameInput_TextChanged);
47 | //
48 | // button1
49 | //
50 | this.button1.DialogResult = System.Windows.Forms.DialogResult.OK;
51 | this.button1.Location = new System.Drawing.Point(261, 138);
52 | this.button1.Name = "button1";
53 | this.button1.Size = new System.Drawing.Size(75, 23);
54 | this.button1.TabIndex = 1;
55 | this.button1.Text = "OK";
56 | this.button1.UseVisualStyleBackColor = true;
57 | //
58 | // passwordInput
59 | //
60 | this.passwordInput.Font = new System.Drawing.Font("Microsoft Sans Serif", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
61 | this.passwordInput.Location = new System.Drawing.Point(8, 88);
62 | this.passwordInput.Name = "passwordInput";
63 | this.passwordInput.PasswordChar = '*';
64 | this.passwordInput.Size = new System.Drawing.Size(328, 44);
65 | this.passwordInput.TabIndex = 2;
66 | this.passwordInput.TextChanged += new System.EventHandler(this.passwordInput_TextChanged);
67 | //
68 | // rememberLogin
69 | //
70 | this.rememberLogin.AutoSize = true;
71 | this.rememberLogin.Location = new System.Drawing.Point(11, 138);
72 | this.rememberLogin.Name = "rememberLogin";
73 | this.rememberLogin.Size = new System.Drawing.Size(106, 17);
74 | this.rememberLogin.TabIndex = 3;
75 | this.rememberLogin.Text = "Remember Login";
76 | this.rememberLogin.UseVisualStyleBackColor = true;
77 | //
78 | // button2
79 | //
80 | this.button2.DialogResult = System.Windows.Forms.DialogResult.Cancel;
81 | this.button2.Location = new System.Drawing.Point(145, 138);
82 | this.button2.Name = "button2";
83 | this.button2.Size = new System.Drawing.Size(110, 23);
84 | this.button2.TabIndex = 4;
85 | this.button2.Text = "Login anonymously";
86 | this.button2.UseVisualStyleBackColor = true;
87 | this.button2.Click += new System.EventHandler(this.button2_Click);
88 | //
89 | // label1
90 | //
91 | this.label1.AutoSize = true;
92 | this.label1.ForeColor = System.Drawing.Color.Red;
93 | this.label1.Location = new System.Drawing.Point(9, 9);
94 | this.label1.Name = "label1";
95 | this.label1.Size = new System.Drawing.Size(327, 26);
96 | this.label1.TabIndex = 5;
97 | this.label1.Text = "Anonymous accounts can list items, but download requires login. \r\nGame ownership " +
98 | "is not required, so you should use dummy account.";
99 | this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
100 | //
101 | // steamLogin
102 | //
103 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
104 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
105 | this.ClientSize = new System.Drawing.Size(342, 169);
106 | this.Controls.Add(this.label1);
107 | this.Controls.Add(this.button2);
108 | this.Controls.Add(this.rememberLogin);
109 | this.Controls.Add(this.passwordInput);
110 | this.Controls.Add(this.button1);
111 | this.Controls.Add(this.usernameInput);
112 | this.Name = "steamLogin";
113 | this.Text = "Login";
114 | this.Load += new System.EventHandler(this.steamLogin_Load);
115 | this.ResumeLayout(false);
116 | this.PerformLayout();
117 |
118 | }
119 |
120 | #endregion
121 | private System.Windows.Forms.Button button1;
122 | internal System.Windows.Forms.TextBox usernameInput;
123 | internal System.Windows.Forms.TextBox passwordInput;
124 | private System.Windows.Forms.Button button2;
125 | internal System.Windows.Forms.CheckBox rememberLogin;
126 | private System.Windows.Forms.Label label1;
127 | }
128 | }
--------------------------------------------------------------------------------
/configdownloader/steamLogin.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | namespace configdownloader
12 | {
13 | public partial class steamLogin : Form
14 | {
15 | public steamLogin()
16 | {
17 | InitializeComponent();
18 | }
19 |
20 | private void steamLogin_Load(object sender, EventArgs e)
21 | {
22 |
23 | }
24 |
25 | private void button2_Click(object sender, EventArgs e)
26 | {
27 | }
28 |
29 | void updateInputs()
30 | {
31 | button2.Enabled = usernameInput.Text == "" && passwordInput.Text == "";
32 | }
33 |
34 | private void usernameInput_TextChanged(object sender, EventArgs e)
35 | {
36 | updateInputs();
37 | }
38 |
39 | private void passwordInput_TextChanged(object sender, EventArgs e)
40 | {
41 | updateInputs();
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/configdownloader/steamLogin.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------