mirror of
https://github.com/Facepunch/Facepunch.Steamworks.git
synced 2024-12-25 14:15:47 +03:00
Steam inventory baseline
This commit is contained in:
parent
b206eb88a2
commit
afb1277d62
@ -131,5 +131,49 @@ public void GetServers()
|
|||||||
Console.WriteLine( "Unresponsive: " + query.Unresponsive.Count.ToString() );
|
Console.WriteLine( "Unresponsive: " + query.Unresponsive.Count.ToString() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void InventoryDefinitions()
|
||||||
|
{
|
||||||
|
using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
|
||||||
|
{
|
||||||
|
Assert.IsNotNull( client.Inventory.Definitions );
|
||||||
|
Assert.AreNotEqual( 0, client.Inventory.Definitions.Length );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void InventoryItemList()
|
||||||
|
{
|
||||||
|
using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
|
||||||
|
{
|
||||||
|
bool CallbackCalled = false;
|
||||||
|
|
||||||
|
// OnUpdate hsould be called when we receive a list of our items
|
||||||
|
client.Inventory.OnUpdate = () => { CallbackCalled = true; };
|
||||||
|
|
||||||
|
// tell steam to download the items
|
||||||
|
client.Inventory.Refresh();
|
||||||
|
|
||||||
|
// Wait for the items
|
||||||
|
while ( client.Inventory.Items == null )
|
||||||
|
{
|
||||||
|
client.Update();
|
||||||
|
System.Threading.Thread.Sleep( 10 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure callback was called
|
||||||
|
Assert.IsTrue( CallbackCalled );
|
||||||
|
|
||||||
|
// Make sure items are valid
|
||||||
|
foreach ( var item in client.Inventory.Items )
|
||||||
|
{
|
||||||
|
Assert.IsNotNull( item );
|
||||||
|
Assert.IsNotNull( item.Definition );
|
||||||
|
|
||||||
|
Console.WriteLine( item.Definition.Name + " - " + item.Id );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ public partial class Client : IDisposable
|
|||||||
internal Valve.Steamworks.ISteamUser _user;
|
internal Valve.Steamworks.ISteamUser _user;
|
||||||
internal Valve.Steamworks.ISteamFriends _friends;
|
internal Valve.Steamworks.ISteamFriends _friends;
|
||||||
internal Valve.Steamworks.ISteamMatchmakingServers _servers;
|
internal Valve.Steamworks.ISteamMatchmakingServers _servers;
|
||||||
|
internal Valve.Steamworks.ISteamInventory _inventory;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current running program's AppId
|
/// Current running program's AppId
|
||||||
@ -60,6 +61,7 @@ public Client( uint appId )
|
|||||||
_friends = _client.GetISteamFriends( _huser, _hpipe, "SteamFriends015" );
|
_friends = _client.GetISteamFriends( _huser, _hpipe, "SteamFriends015" );
|
||||||
_user = _client.GetISteamUser( _huser, _hpipe, "SteamUser019" );
|
_user = _client.GetISteamUser( _huser, _hpipe, "SteamUser019" );
|
||||||
_servers = _client.GetISteamMatchmakingServers( _huser, _hpipe, "SteamMatchMakingServers002" );
|
_servers = _client.GetISteamMatchmakingServers( _huser, _hpipe, "SteamMatchMakingServers002" );
|
||||||
|
_inventory = _client.GetISteamInventory( _huser, _hpipe, "STEAMINVENTORY_INTERFACE_V001" );
|
||||||
|
|
||||||
AppId = appId;
|
AppId = appId;
|
||||||
Username = _friends.GetPersonaName();
|
Username = _friends.GetPersonaName();
|
||||||
@ -103,11 +105,20 @@ public void Update()
|
|||||||
{
|
{
|
||||||
Valve.Steamworks.SteamAPI.RunCallbacks();
|
Valve.Steamworks.SteamAPI.RunCallbacks();
|
||||||
Voice.Update();
|
Voice.Update();
|
||||||
|
Inventory.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Valid
|
public bool Valid
|
||||||
{
|
{
|
||||||
get { return _client != null; }
|
get { return _client != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal Action InstallCallback<T>( int type, Action<T> action )
|
||||||
|
{
|
||||||
|
var ptr = Marshal.GetFunctionPointerForDelegate( action );
|
||||||
|
Valve.Steamworks.SteamAPI.RegisterCallback( ptr, type );
|
||||||
|
|
||||||
|
return () => Valve.Steamworks.SteamAPI.UnregisterCallback( ptr );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
221
Facepunch.Steamworks/Client/Inventory.cs
Normal file
221
Facepunch.Steamworks/Client/Inventory.cs
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Facepunch.Steamworks
|
||||||
|
{
|
||||||
|
public partial class Client : IDisposable
|
||||||
|
{
|
||||||
|
Inventory _inv;
|
||||||
|
|
||||||
|
public Inventory Inventory
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if ( _inv == null )
|
||||||
|
_inv = new Inventory( this );
|
||||||
|
|
||||||
|
return _inv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Inventory
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the items are first retrieved, and when they change
|
||||||
|
/// </summary>
|
||||||
|
public Action OnUpdate;
|
||||||
|
|
||||||
|
internal Client client;
|
||||||
|
private int updateRequest = 0;
|
||||||
|
|
||||||
|
internal Inventory( Client c )
|
||||||
|
{
|
||||||
|
client = c;
|
||||||
|
|
||||||
|
LoadItemDefinitions();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call this to retrieve the items.
|
||||||
|
/// Note that if this has already been called it won't
|
||||||
|
/// trigger a call to OnUpdate unless the items have changed
|
||||||
|
/// </summary>
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
// Pending
|
||||||
|
if ( updateRequest != 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
client._inventory.GetAllItems( ref updateRequest );
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void LoadItemDefinitions()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Make sure item definitions are loaded, because we're going to be using them.
|
||||||
|
//
|
||||||
|
client._inventory.LoadItemDefinitions();
|
||||||
|
|
||||||
|
int[] ids;
|
||||||
|
if ( !client._inventory.GetItemDefinitionIDs( out ids ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Definitions = ids.Select( x =>
|
||||||
|
{
|
||||||
|
var d = new Definition()
|
||||||
|
{
|
||||||
|
client = client,
|
||||||
|
Id = x
|
||||||
|
};
|
||||||
|
|
||||||
|
d.SetupCommonProperties();
|
||||||
|
return d;
|
||||||
|
|
||||||
|
} ).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal T DefinitionProperty<T>( int i, string name )
|
||||||
|
{
|
||||||
|
string val = string.Empty;
|
||||||
|
client._inventory.GetItemDefinitionProperty( i, name, out val );
|
||||||
|
return (T) Convert.ChangeType( val, typeof( T) );
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void DestroyResult()
|
||||||
|
{
|
||||||
|
if ( updateRequest != 0 )
|
||||||
|
{
|
||||||
|
client._inventory.DestroyResult( updateRequest );
|
||||||
|
updateRequest = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal void Update()
|
||||||
|
{
|
||||||
|
UpdateRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateRequest()
|
||||||
|
{
|
||||||
|
if ( updateRequest == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
var status = (Valve.Steamworks.EResult) client._inventory.GetResultStatus( updateRequest );
|
||||||
|
|
||||||
|
if ( status == Valve.Steamworks.EResult.k_EResultPending )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( status == Valve.Steamworks.EResult.k_EResultOK || status == Valve.Steamworks.EResult.k_EResultExpired )
|
||||||
|
{
|
||||||
|
RetrieveInventory();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some other error
|
||||||
|
// Lets just retry.
|
||||||
|
DestroyResult();
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of items owned by this user. You should call Refresh() before trying to access this,
|
||||||
|
/// and then wait until it's non null or listen to OnUpdate to find out immediately when it's populated.
|
||||||
|
/// </summary>
|
||||||
|
public Item[] Items;
|
||||||
|
|
||||||
|
private void RetrieveInventory()
|
||||||
|
{
|
||||||
|
Valve.Steamworks.SteamItemDetails_t[] items = null;
|
||||||
|
client._inventory.GetResultItems( updateRequest, out items );
|
||||||
|
|
||||||
|
Items = items.Select( x =>
|
||||||
|
{
|
||||||
|
return new Item()
|
||||||
|
{
|
||||||
|
client = client,
|
||||||
|
Quantity = x.m_unQuantity,
|
||||||
|
Id = x.m_itemId,
|
||||||
|
DefinitionId = x.m_iDefinition,
|
||||||
|
TradeLocked = ( (int)x.m_unFlags & (int)Valve.Steamworks.ESteamItemFlags.k_ESteamItemNoTrade ) != 0,
|
||||||
|
Definition = Definitions.FirstOrDefault( y => y.Id == x.m_iDefinition )
|
||||||
|
};
|
||||||
|
} ).ToArray();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tell everyone we've got new items!
|
||||||
|
//
|
||||||
|
OnUpdate?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An item in your inventory.
|
||||||
|
/// </summary>
|
||||||
|
public class Item
|
||||||
|
{
|
||||||
|
internal Client client;
|
||||||
|
|
||||||
|
public ulong Id;
|
||||||
|
public int Quantity;
|
||||||
|
|
||||||
|
public int DefinitionId;
|
||||||
|
public Definition Definition;
|
||||||
|
|
||||||
|
public bool TradeLocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A list of items defined for this app.
|
||||||
|
/// This should be immediately populated and available.
|
||||||
|
/// </summary>
|
||||||
|
public Definition[] Definitions;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An item definition. This describes an item in your Steam inventory, but is
|
||||||
|
/// not unique to that item. For example, this might be a tshirt, but you might be able to own
|
||||||
|
/// multiple tshirts.
|
||||||
|
/// </summary>
|
||||||
|
public class Definition
|
||||||
|
{
|
||||||
|
internal Client client;
|
||||||
|
|
||||||
|
public int Id;
|
||||||
|
public string Name;
|
||||||
|
public string Description;
|
||||||
|
|
||||||
|
public DateTime Created;
|
||||||
|
public DateTime Modified;
|
||||||
|
|
||||||
|
public T GetProperty<T>( string name )
|
||||||
|
{
|
||||||
|
string val = string.Empty;
|
||||||
|
|
||||||
|
if ( !client._inventory.GetItemDefinitionProperty( Id, name, out val ) )
|
||||||
|
return default( T );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return (T)Convert.ChangeType( val, typeof( T ) );
|
||||||
|
}
|
||||||
|
catch( System.Exception )
|
||||||
|
{
|
||||||
|
return default( T );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SetupCommonProperties()
|
||||||
|
{
|
||||||
|
Name = GetProperty<string>( "name" );
|
||||||
|
Description = GetProperty<string>( "description" );
|
||||||
|
Created = GetProperty<DateTime>( "timestamp" );
|
||||||
|
Modified = GetProperty<DateTime>( "modified" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -119,6 +119,7 @@
|
|||||||
<Compile Include="Client.Voice.cs" />
|
<Compile Include="Client.Voice.cs" />
|
||||||
<Compile Include="Client.Auth.cs" />
|
<Compile Include="Client.Auth.cs" />
|
||||||
<Compile Include="Client.cs" />
|
<Compile Include="Client.cs" />
|
||||||
|
<Compile Include="Client\Inventory.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="steam_api_interop.cs" />
|
<Compile Include="steam_api_interop.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -2558,7 +2558,7 @@ internal override ISteamInventory GetISteamInventory( uint hSteamuser, uint hSte
|
|||||||
{
|
{
|
||||||
CheckIfUsable();
|
CheckIfUsable();
|
||||||
IntPtr result = NativeEntrypoints.SteamAPI_ISteamClient_GetISteamInventory(m_pSteamClient,hSteamuser,hSteamPipe,pchVersion);
|
IntPtr result = NativeEntrypoints.SteamAPI_ISteamClient_GetISteamInventory(m_pSteamClient,hSteamuser,hSteamPipe,pchVersion);
|
||||||
return (ISteamInventory)Marshal.PtrToStructure( result, typeof( ISteamInventory ) );
|
return new CSteamInventory( result );
|
||||||
}
|
}
|
||||||
internal override ISteamVideo GetISteamVideo( uint hSteamuser, uint hSteamPipe, string pchVersion )
|
internal override ISteamVideo GetISteamVideo( uint hSteamuser, uint hSteamPipe, string pchVersion )
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user