mirror of
https://github.com/Facepunch/Facepunch.Steamworks.git
synced 2024-12-24 13:45:37 +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() );
|
||||
}
|
||||
}
|
||||
|
||||
[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.ISteamFriends _friends;
|
||||
internal Valve.Steamworks.ISteamMatchmakingServers _servers;
|
||||
internal Valve.Steamworks.ISteamInventory _inventory;
|
||||
|
||||
/// <summary>
|
||||
/// Current running program's AppId
|
||||
@ -60,6 +61,7 @@ public Client( uint appId )
|
||||
_friends = _client.GetISteamFriends( _huser, _hpipe, "SteamFriends015" );
|
||||
_user = _client.GetISteamUser( _huser, _hpipe, "SteamUser019" );
|
||||
_servers = _client.GetISteamMatchmakingServers( _huser, _hpipe, "SteamMatchMakingServers002" );
|
||||
_inventory = _client.GetISteamInventory( _huser, _hpipe, "STEAMINVENTORY_INTERFACE_V001" );
|
||||
|
||||
AppId = appId;
|
||||
Username = _friends.GetPersonaName();
|
||||
@ -103,11 +105,20 @@ public void Update()
|
||||
{
|
||||
Valve.Steamworks.SteamAPI.RunCallbacks();
|
||||
Voice.Update();
|
||||
Inventory.Update();
|
||||
}
|
||||
|
||||
public bool Valid
|
||||
{
|
||||
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.Auth.cs" />
|
||||
<Compile Include="Client.cs" />
|
||||
<Compile Include="Client\Inventory.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="steam_api_interop.cs" />
|
||||
</ItemGroup>
|
||||
|
@ -2558,7 +2558,7 @@ internal override ISteamInventory GetISteamInventory( uint hSteamuser, uint hSte
|
||||
{
|
||||
CheckIfUsable();
|
||||
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 )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user