diff --git a/Steamless.CLI/App.config b/Steamless.CLI/App.config new file mode 100644 index 0000000..88fa402 --- /dev/null +++ b/Steamless.CLI/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Steamless.CLI/Program.cs b/Steamless.CLI/Program.cs new file mode 100644 index 0000000..053cc5f --- /dev/null +++ b/Steamless.CLI/Program.cs @@ -0,0 +1,250 @@ +/** + * Steamless - Copyright (c) 2015 - 2022 atom0s [atom0s@live.com] + * + * This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/ or send a letter to + * Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. + * + * By using Steamless, you agree to the above license and its terms. + * + * Attribution - You must give appropriate credit, provide a link to the license and indicate if changes were + * made. You must do so in any reasonable manner, but not in any way that suggests the licensor + * endorses you or your use. + * + * Non-Commercial - You may not use the material (Steamless) for commercial purposes. + * + * No-Derivatives - If you remix, transform, or build upon the material (Steamless), you may not distribute the + * modified material. You are, however, allowed to submit the modified works back to the original + * Steamless project in attempt to have it added to the original project. + * + * You may not apply legal terms or technological measures that legally restrict others + * from doing anything the license permits. + * + * No warranties are given. + */ + +namespace Steamless.CLI +{ + using Steamless.API; + using Steamless.API.Events; + using Steamless.API.Model; + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Reflection; + + internal class Program + { + /// + /// Steamless API Version + /// + /// Main define for this is within DataService.cs and should match that value. + /// + private static readonly Version SteamlessApiVersion = new Version(1, 0); + + /// + /// Steamless logging service. + /// + private static readonly API.Services.LoggingService LoggingService = new API.Services.LoggingService(); + + /// + /// Prints the Steamless header information. + /// + static void PrintHeader() + { + Console.WriteLine(" _________ __ .__ "); + Console.WriteLine(" / _____// |_ ____ _____ _____ | | ____ ______ ______"); + Console.WriteLine(" \\_____ \\\\ __\\/ __ \\\\__ \\ / \\| | _/ __ \\ / ___// ___/"); + Console.WriteLine(" / \\| | \\ ___/ / __ \\| Y Y \\ |_\\ ___/ \\___ \\ \\___ \\ "); + Console.WriteLine("/_______ /|__| \\___ >____ /__|_| /____/\\___ >____ >____ >"); + Console.WriteLine(" \\/ \\/ \\/ \\/ \\/ \\/ \\/ \n"); + Console.WriteLine("Steamless - SteamStub DRM Remover"); + Console.WriteLine("by atom0s\n"); + Console.WriteLine("GitHub : https://github.com/atom0s/Steamless"); + Console.WriteLine("Homepage : https://atom0s.com"); + Console.WriteLine("Donations : https://paypal.me/atom0s"); + Console.WriteLine("Donations : https://github.com/sponsors/atom0s"); + Console.WriteLine("Donations : https://patreon.com/atom0s\n"); + } + + /// + /// Prints the Steamless command line help information. + /// + static void PrintHelp() + { + Console.WriteLine("Usage:"); + Console.WriteLine(" Steamless.CLI.exe [options] [file]\n"); + Console.WriteLine("Options:"); + Console.WriteLine(" --quiet"); + Console.WriteLine(" --keepbind - Keeps the .bind section in the unpacked file."); + Console.WriteLine(" --keepstub - Keeps the DOS stub in the unpacked file."); + Console.WriteLine(" --dumppayload - Dumps the stub payload to disk."); + Console.WriteLine(" --dumpdrmp - Dumps the SteamDRMP.dll to disk."); + Console.WriteLine(" --realign - Realigns the unpacked file sections."); + Console.WriteLine(" --recalcchecksum - Recalculates the unpacked file checksum."); + Console.WriteLine(" --exp - Use experimental features."); + } + + /// + /// Obtains a list of available Steamless plugins. + /// + /// + static List GetSteamlessPlugins() + { + try + { + // The list of valid plugins.. + var plugins = new List(); + + // Build a path to the plugins folder.. + var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins"); + + // Loop the DLL files and attempt to load them.. + foreach (var dll in Directory.GetFiles(path, "*.dll")) + { + // Skip the Steamless.API.dll file.. + if (dll.ToLower().Contains("steamless.api.dll")) + continue; + + try + { + // Load the assembly.. + var asm = Assembly.Load(File.ReadAllBytes(dll)); + + // Locate the class inheriting the plugin base.. + var baseClass = asm.GetTypes().SingleOrDefault(t => t.BaseType == typeof(SteamlessPlugin)); + if (baseClass == null) + continue; + + // Locate the SteamlessApiVersion attribute on the base class.. + var baseAttr = baseClass.GetCustomAttributes(typeof(SteamlessApiVersionAttribute), false); + if (baseAttr.Length == 0) + continue; + + // Validate the interface version.. + var apiVersion = (SteamlessApiVersionAttribute)baseAttr[0]; + if (apiVersion.Version != SteamlessApiVersion) + continue; + + // Create an instance of the plugin.. + var plugin = (SteamlessPlugin)Activator.CreateInstance(baseClass); + if (!plugin.Initialize(LoggingService)) + continue; + + plugins.Add(plugin); + } + catch + { + } + } + + // Order the plugins by their name.. + return plugins.OrderBy(p => p.Name).ToList(); + } + catch + { + return new List(); + } + } + + /// + /// Application entry point. + /// + /// + static int Main(string[] args) + { + PrintHeader(); + + var opts = new SteamlessOptions(); + var file = string.Empty; + + // Process command line arguments for the various Steamless options.. + foreach (var arg in args) + { + if (arg.ToLower() == "--quiet") + opts.VerboseOutput = false; + if (arg.ToLower() == "--keepbind") + opts.KeepBindSection = true; + if (arg.ToLower() == "--keepstub") + opts.ZeroDosStubData = false; + if (arg.ToLower() == "--dumppayload") + opts.DumpPayloadToDisk = true; + if (arg.ToLower() == "--dumpdrmp") + opts.DumpSteamDrmpToDisk = true; + if (arg.ToLower() == "--realign") + opts.DontRealignSections = false; + if (arg.ToLower() == "--recalcchecksum") + opts.RecalculateFileChecksum = true; + if (arg.ToLower() == "--exp") + opts.UseExperimentalFeatures = true; + if (!arg.StartsWith("--")) + file = arg; + } + + // Prepare the logging service.. + LoggingService.AddLogMessage += (sender, e) => + { + if (!opts.VerboseOutput && e.MessageType == LogMessageType.Debug) + return; + + try + { + if (sender != null) + e.Message = $"[{sender.GetType().Assembly.GetName().Name}] {e.Message}"; + else + e.Message = $"[Steamless] {e.Message}"; + } + catch + { + } + + Console.WriteLine(e.Message); + }; + + // Ensure an input file was given.. + if (string.IsNullOrEmpty(file)) + { + PrintHelp(); + return 1; + } + + // Ensure the input file exists.. + if (!File.Exists(file)) + { + LoggingService.OnAddLogMessage(null, new LogMessageEventArgs("Invalid input file given; cannot continue.", LogMessageType.Error)); + return 1; + } + + // Collect the list of available plugins.. + var plugins = GetSteamlessPlugins(); + plugins.ForEach(p => LoggingService.OnAddLogMessage(null, new LogMessageEventArgs($"Loaded plugin: {p.Name} - by {p.Author} (v.{p.Version})", LogMessageType.Success))); + + // Ensure plugins were found and loaded.. + if (plugins.Count == 0) + { + LoggingService.OnAddLogMessage(null, new LogMessageEventArgs("No plugins were loaded; be sure to fully extract Steamless before running!", LogMessageType.Error)); + return 1; + } + + // Loop through the plugins and try to unpack the file.. + foreach (var p in plugins) + { + // Check if the plugin can process the file.. + if (p.CanProcessFile(file)) + { + var ret = p.ProcessFile(file, opts); + + LoggingService.OnAddLogMessage(null, !ret + ? new LogMessageEventArgs("Failed to unpack file.", LogMessageType.Error) + : new LogMessageEventArgs("Successfully unpacked file!", LogMessageType.Success)); + + if (ret) return 0; + } + } + + LoggingService.OnAddLogMessage(null, new LogMessageEventArgs("All unpackers failed to unpack file.", LogMessageType.Error)); + return 1; + } + } +} \ No newline at end of file diff --git a/Steamless.CLI/Properties/AssemblyInfo.cs b/Steamless.CLI/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9717d32 --- /dev/null +++ b/Steamless.CLI/Properties/AssemblyInfo.cs @@ -0,0 +1,40 @@ +/** + * Steamless - Copyright (c) 2015 - 2022 atom0s [atom0s@live.com] + * + * This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/ or send a letter to + * Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. + * + * By using Steamless, you agree to the above license and its terms. + * + * Attribution - You must give appropriate credit, provide a link to the license and indicate if changes were + * made. You must do so in any reasonable manner, but not in any way that suggests the licensor + * endorses you or your use. + * + * Non-Commercial - You may not use the material (Steamless) for commercial purposes. + * + * No-Derivatives - If you remix, transform, or build upon the material (Steamless), you may not distribute the + * modified material. You are, however, allowed to submit the modified works back to the original + * Steamless project in attempt to have it added to the original project. + * + * You may not apply legal terms or technological measures that legally restrict others + * from doing anything the license permits. + * + * No warranties are given. + */ + +using System.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("Steamless.CLI")] +[assembly: AssemblyDescription("Removes the SteamStub DRM protection from Steam applications.")] +[assembly: AssemblyConfiguration("Release")] +[assembly: AssemblyCompany("atom0s")] +[assembly: AssemblyProduct("Steamless")] +[assembly: AssemblyCopyright("Copyright © atom0s 2015 - 2022")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] +[assembly: Guid("d128d7ad-2e6f-43bd-ba36-bea3b9b77437")] +[assembly: AssemblyVersion("3.0.0.15")] +[assembly: AssemblyFileVersion("3.0.0.15")] \ No newline at end of file diff --git a/Steamless.CLI/Steamless.CLI.csproj b/Steamless.CLI/Steamless.CLI.csproj new file mode 100644 index 0000000..0bed712 --- /dev/null +++ b/Steamless.CLI/Steamless.CLI.csproj @@ -0,0 +1,65 @@ + + + + + Debug + AnyCPU + {D128D7AD-2E6F-43BD-BA36-BEA3B9B77437} + Exe + Steamless.CLI + Steamless.CLI + v4.5.2 + 512 + true + true + + + x86 + true + full + false + ..\Steamless\bin\x86\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + ..\Steamless\bin\x86\Debug\ + TRACE + prompt + 4 + + + steam.ico + + + + + + + + + + + + + + + + + + + + + {56c95629-3b34-47fe-b988-04274409294f} + Steamless.API + + + + + + + \ No newline at end of file diff --git a/Steamless.CLI/steam.ico b/Steamless.CLI/steam.ico new file mode 100644 index 0000000..13ce382 Binary files /dev/null and b/Steamless.CLI/steam.ico differ diff --git a/Steamless.sln b/Steamless.sln index 8baeba8..fb5b69e 100644 --- a/Steamless.sln +++ b/Steamless.sln @@ -23,6 +23,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Steamless.Unpacker.Variant2 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Steamless.Unpacker.Variant10.x86", "Steamless.Unpacker.Variant10.x86\Steamless.Unpacker.Variant10.x86.csproj", "{02B58AB0-9B00-4B31-8D61-9D22D13D2C4A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Steamless.CLI", "Steamless.CLI\Steamless.CLI.csproj", "{D128D7AD-2E6F-43BD-BA36-BEA3B9B77437}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -111,6 +113,14 @@ Global {02B58AB0-9B00-4B31-8D61-9D22D13D2C4A}.Release|Any CPU.Build.0 = Release|Any CPU {02B58AB0-9B00-4B31-8D61-9D22D13D2C4A}.Release|x86.ActiveCfg = Release|Any CPU {02B58AB0-9B00-4B31-8D61-9D22D13D2C4A}.Release|x86.Build.0 = Release|Any CPU + {D128D7AD-2E6F-43BD-BA36-BEA3B9B77437}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D128D7AD-2E6F-43BD-BA36-BEA3B9B77437}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D128D7AD-2E6F-43BD-BA36-BEA3B9B77437}.Debug|x86.ActiveCfg = Debug|Any CPU + {D128D7AD-2E6F-43BD-BA36-BEA3B9B77437}.Debug|x86.Build.0 = Debug|Any CPU + {D128D7AD-2E6F-43BD-BA36-BEA3B9B77437}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D128D7AD-2E6F-43BD-BA36-BEA3B9B77437}.Release|Any CPU.Build.0 = Release|Any CPU + {D128D7AD-2E6F-43BD-BA36-BEA3B9B77437}.Release|x86.ActiveCfg = Release|Any CPU + {D128D7AD-2E6F-43BD-BA36-BEA3B9B77437}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Steamless/Properties/AssemblyInfo.cs b/Steamless/Properties/AssemblyInfo.cs index 37114f7..5641ccf 100644 --- a/Steamless/Properties/AssemblyInfo.cs +++ b/Steamless/Properties/AssemblyInfo.cs @@ -37,5 +37,5 @@ using System.Windows; [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] -[assembly: AssemblyVersion("3.0.0.14")] -[assembly: AssemblyFileVersion("3.0.0.14")] \ No newline at end of file +[assembly: AssemblyVersion("3.0.0.15")] +[assembly: AssemblyFileVersion("3.0.0.15")] \ No newline at end of file