From 199ad77406115888097967219e231dd9a5522dda Mon Sep 17 00:00:00 2001 From: Garry Newman Date: Fri, 12 Apr 2019 21:30:13 +0100 Subject: [PATCH] Better vector marshalling --- Facepunch.Steamworks.Test/Client/AppTest.cs | 76 +++++++------------ .../Generated/Interfaces/ISteamApps.cs | 6 +- Facepunch.Steamworks/Redux/Apps.cs | 45 ++++++++++- Facepunch.Steamworks/Redux/Structs/DepotId.cs | 28 +++++++ Generator/CodeWriter/Types/BaseType.cs | 7 +- 5 files changed, 107 insertions(+), 55 deletions(-) create mode 100644 Facepunch.Steamworks/Redux/Structs/DepotId.cs diff --git a/Facepunch.Steamworks.Test/Client/AppTest.cs b/Facepunch.Steamworks.Test/Client/AppTest.cs index bbea645..15d5494 100644 --- a/Facepunch.Steamworks.Test/Client/AppTest.cs +++ b/Facepunch.Steamworks.Test/Client/AppTest.cs @@ -1,64 +1,46 @@ using System; +using System.Linq; using System.Text; using System.Threading; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace Facepunch.Steamworks.Test +namespace Steamworks { [TestClass] [DeploymentItem( "steam_api64.dll" )] - public class App + public class AppTest { - [TestMethod] - public void IsSubscribed() + [AssemblyInitialize] + public static void AssemblyInit( TestContext context ) + { + Steamworks.Steam.Init( 4000 ); + } + + [TestMethod] + public void GameLangauge() { - using ( var client = new Facepunch.Steamworks.Client( 252490 ) ) - { - Console.WriteLine("This test assumes you own Garry's Mod and not Charles III of Spain and the antiquity"); + var gl = Apps.GameLanguage; + Assert.IsNotNull( gl ); + Assert.IsTrue( gl.Length > 3 ); - Assert.IsTrue( client.App.IsSubscribed( 4000 ) ); - Assert.IsFalse( client.App.IsSubscribed( 590440 )); - } - } + Console.WriteLine( $"{gl}" ); + } - [TestMethod] - public void IsInstalled() - { - using (var client = new Facepunch.Steamworks.Client(252490)) - { - Console.WriteLine("This test assumes you have Garry's Mod installed but not Charles III of Spain and the antiquity"); + [TestMethod] + public void InstalledDepots() + { + var depots = Apps.InstalledDepots( 4000 ).ToArray(); - Assert.IsTrue(client.App.IsInstalled(4000)); - Assert.IsFalse(client.App.IsInstalled(590440)); - } - } + Assert.IsNotNull( depots ); + Assert.IsTrue( depots.Length > 0 ); - [TestMethod] - public void PurchaseTime() - { - using (var client = new Facepunch.Steamworks.Client(252490)) - { - Console.WriteLine("This test assumes you own Garry's Mod but not Charles III of Spain and the antiquity"); + foreach ( var depot in depots ) + { + Console.WriteLine( $"{depot.Value}" ); + } - var gmodBuyTime = client.App.PurchaseTime( 4000 ); - Assert.AreNotEqual( gmodBuyTime, DateTime.MinValue ); + + } + } - Console.WriteLine($"You bought Garry's Mod {gmodBuyTime}"); - - var otherBuyTime = client.App.PurchaseTime(590440); - Assert.AreEqual(otherBuyTime, DateTime.MinValue); - } - } - - [TestMethod] - public void AppName() - { - using ( var client = new Facepunch.Steamworks.Client( 252490 ) ) - { - var name = client.App.GetName( 4000 ); - Console.WriteLine( name ); - } - } - - } } diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamApps.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamApps.cs index 26893d5..1172d76 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamApps.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamApps.cs @@ -239,13 +239,13 @@ public bool MarkContentCorrupt( [MarshalAs( UnmanagedType.U1 )] bool bMissingFil #region FunctionMeta [UnmanagedFunctionPointer( CallingConvention.ThisCall )] - public delegate uint GetInstalledDepotsDelegate( IntPtr self, AppId_t appID, ref DepotId_t pvecDepots, uint cMaxDepots ); + public delegate uint GetInstalledDepotsDelegate( IntPtr self, AppId_t appID, [In,Out] DepotId_t[] pvecDepots, uint cMaxDepots ); private GetInstalledDepotsDelegate GetInstalledDepotsDelegatePointer; #endregion - public uint GetInstalledDepots( AppId_t appID, ref DepotId_t pvecDepots, uint cMaxDepots ) + public uint GetInstalledDepots( AppId_t appID, [In,Out] DepotId_t[] pvecDepots, uint cMaxDepots ) { - return GetInstalledDepotsDelegatePointer( Self, appID, ref pvecDepots, cMaxDepots ); + return GetInstalledDepotsDelegatePointer( Self, appID, pvecDepots, cMaxDepots ); } #region FunctionMeta diff --git a/Facepunch.Steamworks/Redux/Apps.cs b/Facepunch.Steamworks/Redux/Apps.cs index f867df9..c5ff7dc 100644 --- a/Facepunch.Steamworks/Redux/Apps.cs +++ b/Facepunch.Steamworks/Redux/Apps.cs @@ -48,7 +48,7 @@ internal static Internal.ISteamApps steamapps /// Gets the current language that the user has set. /// This falls back to the Steam UI language if the user hasn't explicitly picked a language for the title. /// - public static string GameLangauge => steamapps.GetCurrentGameLanguage(); + public static string GameLanguage => steamapps.GetCurrentGameLanguage(); /// /// Gets a list of the languages the current app supports. @@ -84,11 +84,12 @@ internal static Internal.ISteamApps steamapps public static IEnumerable DlcInformation() { var appid = default( SteamNative.AppId_t ); - var sb = new StringBuilder( 512 ); var available = false; for ( int i = 0; i < steamapps.GetDLCCount(); i++ ) { + var sb = SteamNative.Helpers.TakeStringBuilder(); + if ( !steamapps.BGetDLCDataByIndex( i, ref appid, ref available, sb, sb.Capacity ) ) continue; @@ -111,5 +112,45 @@ public static IEnumerable DlcInformation() /// public static void UninstallDlc( AppId appid ) => steamapps.UninstallDLC( appid.Value ); + /// + /// Returns null if we're not on a beta branch, else the name of the branch + /// + public static string CurrentBetaName + { + get + { + var sb = SteamNative.Helpers.TakeStringBuilder(); + + if ( !steamapps.GetCurrentBetaName( sb, sb.Capacity ) ) + return null; + + return sb.ToString(); + } + } + + /// + /// Allows you to force verify game content on next launch. + /// + /// If you detect the game is out-of-date(for example, by having the client detect a version mismatch with a server), + /// you can call use MarkContentCorrupt to force a verify, show a message to the user, and then quit. + /// + public static void MarkContentCorrupt( bool missingFilesOnly ) => steamapps.MarkContentCorrupt( missingFilesOnly ); + + /// + /// Gets a list of all installed depots for a given App ID in mount order + /// + public static IEnumerable InstalledDepots( AppId appid ) + { + var depots = new SteamNative.DepotId_t[32]; + uint count = 0; + + count = steamapps.GetInstalledDepots( appid.Value, depots, (uint) depots.Length ); + + for ( int i = 0; i < count; i++ ) + { + yield return new DepotId { Value = depots[i].Value }; + } + } + } } \ No newline at end of file diff --git a/Facepunch.Steamworks/Redux/Structs/DepotId.cs b/Facepunch.Steamworks/Redux/Structs/DepotId.cs new file mode 100644 index 0000000..166e354 --- /dev/null +++ b/Facepunch.Steamworks/Redux/Structs/DepotId.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + + +namespace Steamworks +{ + public struct DepotId + { + public uint Value; + + public static implicit operator DepotId( uint value ) + { + return new DepotId { Value = value }; + } + + public static implicit operator DepotId( int value ) + { + return new DepotId { Value = (uint) value }; + } + + public static implicit operator uint( DepotId value ) + { + return value.Value; + } + } +} \ No newline at end of file diff --git a/Generator/CodeWriter/Types/BaseType.cs b/Generator/CodeWriter/Types/BaseType.cs index 2cc08dc..2fda0e6 100644 --- a/Generator/CodeWriter/Types/BaseType.cs +++ b/Generator/CodeWriter/Types/BaseType.cs @@ -20,7 +20,7 @@ public static BaseType Parse( string type, string varname = null ) var basicType = type.Trim( ' ', '*' ); - if ( basicType == "int32" ) return new IntType { NativeType = type, VarName = varname }; + if ( basicType == "int32" || basicType == "int" ) return new IntType { NativeType = type, VarName = varname }; if ( basicType == "uint32" ) return new UIntType { NativeType = type, VarName = varname }; if ( basicType == "CSteamID" ) return new CSteamIdType { NativeType = type, VarName = varname }; if ( basicType == "uint64" ) return new ULongType { NativeType = type, VarName = varname }; @@ -31,13 +31,14 @@ public static BaseType Parse( string type, string varname = null ) return new BaseType { NativeType = type, VarName = varname }; } - public virtual string AsArgument() => $"{Ref}{TypeName} {VarName}"; + public virtual string AsArgument() => IsVector? $"[In,Out] {TypeName}[] {VarName}" : $"{Ref}{TypeName} {VarName}"; public virtual string AsCallArgument() => $"{Ref}{VarName}"; public virtual string Return( string varname ) => $"return {varname};"; public virtual string ReturnAttribute => null; - public virtual string Ref => NativeType.EndsWith( "*" ) ? "ref " : ""; + public virtual string Ref => !IsVector && NativeType.EndsWith( "*" ) ? "ref " : ""; + public virtual bool IsVector => NativeType.EndsWith( "*" ) && VarName.Contains( "pvec" ); public virtual bool IsVoid => false; public virtual bool IsReturnedWeird => false;