Workshop result can return more than 50 items per page

This commit is contained in:
Garry Newman 2016-10-17 13:49:33 +01:00
parent 49df734392
commit c5f22d6470
2 changed files with 149 additions and 13 deletions

View File

@ -231,6 +231,85 @@ public void QueryFiles()
} }
} }
[TestMethod]
public void Query_255()
{
using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
{
Assert.IsTrue( client.IsValid );
using ( var Query = client.Workshop.CreateQuery() )
{
Query.PerPage = 255;
Query.Run();
Assert.IsTrue( Query.IsRunning );
Query.Block();
Assert.IsFalse( Query.IsRunning );
Assert.AreEqual( Query.Items.Length, 255 );
Console.WriteLine( "Query.TotalResults: {0}", Query.TotalResults );
Console.WriteLine( "Query.Items.Length: {0}", Query.Items.Length );
}
}
}
[TestMethod]
public void Query_28()
{
using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
{
Assert.IsTrue( client.IsValid );
using ( var Query = client.Workshop.CreateQuery() )
{
Query.PerPage = 28;
Query.Run();
Query.Block();
var firstPage = Query.Items;
Assert.AreEqual( firstPage.Length, 28 );
Console.WriteLine( "Page 2" );
Query.Page++;
Query.Run();
Query.Block();
var secondPage = Query.Items;
Assert.AreEqual( secondPage.Length, 28 );
Console.WriteLine( "Page 3" );
Query.Page++;
Query.Run();
Query.Block();
var thirdPage = Query.Items;
Assert.AreEqual( thirdPage.Length, 28 );
foreach ( var i in firstPage )
{
Assert.IsFalse( secondPage.Any( x => x.Id == i.Id ) );
Assert.IsFalse( thirdPage.Any( x => x.Id == i.Id ) );
}
foreach ( var i in secondPage )
{
Assert.IsFalse( firstPage.Any( x => x.Id == i.Id ) );
Assert.IsFalse( thirdPage.Any( x => x.Id == i.Id ) );
}
foreach ( var i in thirdPage )
{
Assert.IsFalse( secondPage.Any( x => x.Id == i.Id ) );
Assert.IsFalse( firstPage.Any( x => x.Id == i.Id ) );
}
}
}
}
[TestMethod] [TestMethod]
public void DownloadFile() public void DownloadFile()
{ {

View File

@ -15,6 +15,8 @@ public partial class Workshop
{ {
public class Query : IDisposable public class Query : IDisposable
{ {
internal const int SteamResponseSize = 50;
internal ulong Handle; internal ulong Handle;
internal QueryCompleted Callback; internal QueryCompleted Callback;
@ -47,11 +49,16 @@ public class Query : IDisposable
/// </summary> /// </summary>
public int Page { get; set; } = 1; public int Page { get; set; } = 1;
public int PerPage { get; set; } = 50; public int PerPage { get; set; } = SteamResponseSize;
internal Workshop workshop; internal Workshop workshop;
public unsafe void Run() private int _resultPage = 0;
private int _resultsRemain = 0;
private int _resultSkip = 0;
private List<Item> _results;
public void Run()
{ {
if ( Callback != null ) if ( Callback != null )
return; return;
@ -59,9 +66,27 @@ public unsafe void Run()
if ( Page <= 0 ) if ( Page <= 0 )
throw new System.Exception( "Page should be 1 or above" ); throw new System.Exception( "Page should be 1 or above" );
var actualOffset = ((Page-1) * PerPage);
TotalResults = 0;
_resultSkip = actualOffset % SteamResponseSize;
_resultsRemain = PerPage;
_resultPage = (int) Math.Floor( (float) actualOffset / (float)SteamResponseSize );
_results = new List<Item>();
Console.WriteLine( "_resultPage = " + _resultPage );
Console.WriteLine( "_resultSkip = " + _resultSkip );
RunInternal();
}
unsafe void RunInternal()
{
if ( FileId.Count != 0 ) if ( FileId.Count != 0 )
{ {
var fileArray = FileId.ToArray(); var fileArray = FileId.ToArray();
_resultsRemain = fileArray.Length;
fixed ( ulong* array = fileArray ) fixed ( ulong* array = fileArray )
{ {
@ -71,11 +96,11 @@ public unsafe void Run()
else if ( UserId.HasValue ) else if ( UserId.HasValue )
{ {
uint accountId = (uint)( UserId.Value & 0xFFFFFFFFul ); uint accountId = (uint)( UserId.Value & 0xFFFFFFFFul );
Handle = workshop.ugc.CreateQueryUserUGCRequest( accountId, (uint) UserQueryType, (uint)QueryType, (uint)Order, UploaderAppId, AppId, (uint)Page ); Handle = workshop.ugc.CreateQueryUserUGCRequest( accountId, (uint)UserQueryType, (uint)QueryType, (uint)Order, UploaderAppId, AppId, (uint)_resultPage + 1 );
} }
else else
{ {
Handle = workshop.ugc.CreateQueryAllUGCRequest( (uint)Order, (uint)QueryType, UploaderAppId, AppId, (uint)Page ); Handle = workshop.ugc.CreateQueryAllUGCRequest( (uint)Order, (uint)QueryType, UploaderAppId, AppId, (uint)_resultPage + 1 );
} }
if ( !string.IsNullOrEmpty( SearchText ) ) if ( !string.IsNullOrEmpty( SearchText ) )
@ -98,29 +123,61 @@ public unsafe void Run()
void OnResult( QueryCompleted.Data data ) void OnResult( QueryCompleted.Data data )
{ {
Items = new Item[data.NumResultsReturned];
for ( int i = 0; i < data.NumResultsReturned; i++ ) for ( int i = 0; i < data.NumResultsReturned; i++ )
{ {
if ( _resultSkip > 0 )
{
Console.WriteLine( "{0} Skipping result", _resultPage );
_resultSkip--;
continue;
}
else
{
Console.WriteLine( "{0} Adding result {1}", _resultPage, _results.Count );
}
SteamUGCDetails_t details = new SteamUGCDetails_t(); SteamUGCDetails_t details = new SteamUGCDetails_t();
workshop.ugc.GetQueryUGCResult( data.Handle, (uint)i, ref details ); workshop.ugc.GetQueryUGCResult( data.Handle, (uint)i, ref details );
Items[i] = Item.From( details, workshop ); // We already have this file, so skip it
if ( _results.Any( x => x.Id == details.m_nPublishedFileId ) )
continue;
Items[i].SubscriptionCount = GetStat( data.Handle, i, ItemStatistic.NumSubscriptions ); var item = Item.From( details, workshop );
Items[i].FavouriteCount = GetStat( data.Handle, i, ItemStatistic.NumFavorites );
Items[i].FollowerCount = GetStat( data.Handle, i, ItemStatistic.NumFollowers ); item.SubscriptionCount = GetStat( data.Handle, i, ItemStatistic.NumSubscriptions );
Items[i].WebsiteViews = GetStat( data.Handle, i, ItemStatistic.NumUniqueWebsiteViews ); item.FavouriteCount = GetStat( data.Handle, i, ItemStatistic.NumFavorites );
Items[i].ReportScore = GetStat( data.Handle, i, ItemStatistic.ReportScore ); item.FollowerCount = GetStat( data.Handle, i, ItemStatistic.NumFollowers );
item.WebsiteViews = GetStat( data.Handle, i, ItemStatistic.NumUniqueWebsiteViews );
item.ReportScore = GetStat( data.Handle, i, ItemStatistic.ReportScore );
string url = null; string url = null;
if ( workshop.ugc.GetQueryUGCPreviewURL( data.Handle, (uint)i, out url ) ) if ( workshop.ugc.GetQueryUGCPreviewURL( data.Handle, (uint)i, out url ) )
Items[i].PreviewImageUrl = url; item.PreviewImageUrl = url;
_results.Add( item );
_resultsRemain--;
if ( _resultsRemain <= 0 )
break;
} }
TotalResults = (int)data.TotalMatchingResults; TotalResults = TotalResults > data.TotalMatchingResults ? TotalResults : (int)data.TotalMatchingResults;
Callback.Dispose(); Callback.Dispose();
Callback = null; Callback = null;
_resultPage++;
if ( _resultsRemain > 0 && data.NumResultsReturned > 0 )
{
RunInternal();
}
else
{
Items = _results.ToArray();
}
} }
private int GetStat( ulong handle, int index, ItemStatistic stat ) private int GetStat( ulong handle, int index, ItemStatistic stat )