mirror of
https://github.com/Facepunch/Facepunch.Steamworks.git
synced 2025-01-13 23:28:11 +03:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
19e64429c4
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -211,7 +211,7 @@ namespace Steamworks
|
||||
//
|
||||
// EUserHasLicenseForAppResult
|
||||
//
|
||||
internal enum UserHasLicenseForAppResult : int
|
||||
public enum UserHasLicenseForAppResult : int
|
||||
{
|
||||
HasLicense = 0,
|
||||
DoesNotHaveLicense = 1,
|
||||
@ -585,7 +585,7 @@ namespace Steamworks
|
||||
//
|
||||
// EFriendFlags
|
||||
//
|
||||
internal enum FriendFlags : int
|
||||
public enum FriendFlags : int
|
||||
{
|
||||
None = 0,
|
||||
Blocked = 1,
|
||||
|
@ -111,21 +111,23 @@ namespace Steamworks
|
||||
OnChatMessage( friend, typeName, message );
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<Friend> GetFriendsWithFlag(FriendFlags flag)
|
||||
{
|
||||
for ( int i=0; i<Internal.GetFriendCount( (int)flag); i++ )
|
||||
{
|
||||
yield return new Friend( Internal.GetFriendByIndex( i, (int)flag ) );
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<Friend> GetFriends()
|
||||
{
|
||||
for ( int i=0; i<Internal.GetFriendCount( (int) FriendFlags.Immediate ); i++ )
|
||||
{
|
||||
yield return new Friend( Internal.GetFriendByIndex( i, (int)FriendFlags.Immediate ) );
|
||||
}
|
||||
return GetFriendsWithFlag(FriendFlags.Immediate);
|
||||
}
|
||||
|
||||
public static IEnumerable<Friend> GetBlocked()
|
||||
{
|
||||
for ( int i = 0; i < Internal.GetFriendCount( (int)FriendFlags.Blocked ); i++ )
|
||||
{
|
||||
yield return new Friend( Internal.GetFriendByIndex( i, (int)FriendFlags.Blocked) );
|
||||
}
|
||||
return GetFriendsWithFlag(FriendFlags.Blocked);
|
||||
}
|
||||
|
||||
public static IEnumerable<Friend> GetPlayedWith()
|
||||
|
@ -91,10 +91,10 @@ namespace Steamworks
|
||||
var buffer = Helpers.TakeBuffer( (int) size );
|
||||
|
||||
fixed ( byte* p = buffer )
|
||||
{
|
||||
SteamId steamid = 1;
|
||||
if ( !Internal.ReadP2PPacket( (IntPtr)p, (uint) buffer.Length, ref size, ref steamid, channel ) || size == 0 )
|
||||
return null;
|
||||
{
|
||||
SteamId steamid = 1;
|
||||
if ( !Internal.ReadP2PPacket( (IntPtr)p, (uint) buffer.Length, ref size, ref steamid, channel ) || size == 0 )
|
||||
return null;
|
||||
|
||||
var data = new byte[size];
|
||||
Array.Copy( buffer, 0, data, 0, size );
|
||||
@ -104,7 +104,25 @@ namespace Steamworks
|
||||
SteamId = steamid,
|
||||
Data = data
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads in a packet that has been sent from another user via SendP2PPacket..
|
||||
/// </summary>
|
||||
public unsafe static bool ReadP2PPacket( byte[] buffer, ref uint size, ref SteamId steamid, int channel = 0 )
|
||||
{
|
||||
fixed (byte* p = buffer) {
|
||||
return Internal.ReadP2PPacket( (IntPtr)p, (uint)buffer.Length, ref size, ref steamid, channel );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads in a packet that has been sent from another user via SendP2PPacket..
|
||||
/// </summary>
|
||||
public unsafe static bool ReadP2PPacket( byte* buffer, uint cbuf, ref uint size, ref SteamId steamid, int channel = 0 )
|
||||
{
|
||||
return Internal.ReadP2PPacket( (IntPtr)buffer, cbuf, ref size, ref steamid, channel );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -123,6 +141,15 @@ namespace Steamworks
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a P2P packet to the specified user.
|
||||
/// This is a session-less API which automatically establishes NAT-traversing or Steam relay server connections.
|
||||
/// NOTE: The first packet send may be delayed as the NAT-traversal code runs.
|
||||
/// </summary>
|
||||
public static unsafe bool SendP2PPacket( SteamId steamid, byte* data, uint length, int nChannel = 1, P2PSend sendType = P2PSend.Reliable )
|
||||
{
|
||||
return Internal.SendP2PPacket( steamid, (IntPtr)data, (uint)length, (P2PSend)sendType, nChannel );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -464,6 +464,14 @@ namespace Steamworks
|
||||
public static unsafe void HandleIncomingPacket( IntPtr ptr, int size, uint address, ushort port )
|
||||
{
|
||||
Internal.HandleIncomingPacket( ptr, size, address, port );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does the user own this app (which could be DLC)
|
||||
/// </summary>
|
||||
public static UserHasLicenseForAppResult UserHasLicenseForApp( SteamId steamid, AppId appid )
|
||||
{
|
||||
return Internal.UserHasLicenseForApp( steamid, appid );
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Steamworks.Data;
|
||||
|
||||
@ -254,10 +255,46 @@ namespace Steamworks.Ugc
|
||||
return result?.Result == Result.OK;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows the user to unsubscribe from this item
|
||||
/// </summary>
|
||||
public async Task<bool> Unsubscribe ()
|
||||
/// <summary>
|
||||
/// Allows the user to subscribe to this item and wait for it to be downloaded
|
||||
/// If CancellationToken is default then there is 60 seconds timeout
|
||||
/// Progress will be set to 0-1
|
||||
/// </summary>
|
||||
public async Task<bool> SubscribeDownloadAsync( Action<float> progress = null, CancellationToken ct = default, int milisecondsUpdateDelay = 60 )
|
||||
{
|
||||
if ( ct == default )
|
||||
ct = new CancellationTokenSource( TimeSpan.FromSeconds( 60 ) ).Token;
|
||||
|
||||
progress?.Invoke( 0 );
|
||||
|
||||
var subResult = await SteamUGC.Internal.SubscribeItem( _id );
|
||||
if ( subResult?.Result != Result.OK )
|
||||
return false;
|
||||
|
||||
var downloading = Download( true );
|
||||
if ( !downloading )
|
||||
return State.HasFlag( ItemState.Installed );
|
||||
|
||||
while ( true )
|
||||
{
|
||||
if ( ct.IsCancellationRequested )
|
||||
break;
|
||||
|
||||
progress?.Invoke( DownloadAmount );
|
||||
|
||||
if ( !IsDownloading && State.HasFlag( ItemState.Installed ) )
|
||||
break;
|
||||
|
||||
await Task.Delay( milisecondsUpdateDelay );
|
||||
}
|
||||
|
||||
return State.HasFlag( ItemState.Installed );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allows the user to unsubscribe from this item
|
||||
/// </summary>
|
||||
public async Task<bool> Unsubscribe ()
|
||||
{
|
||||
var result = await SteamUGC.Internal.UnsubscribeItem( _id );
|
||||
return result?.Result == Result.OK;
|
||||
|
@ -15,26 +15,53 @@ namespace Steamworks
|
||||
// private static readonly byte A2S_PLAYER = 0x55;
|
||||
private static readonly byte A2S_RULES = 0x56;
|
||||
|
||||
internal static async Task<Dictionary<string, string>> GetRules( ServerInfo server )
|
||||
{
|
||||
try
|
||||
{
|
||||
var endpoint = new IPEndPoint( server.Address, server.QueryPort );
|
||||
private static readonly Dictionary<IPEndPoint, Task<Dictionary<string, string>>> PendingQueries =
|
||||
new Dictionary<IPEndPoint, Task<Dictionary<string, string>>>();
|
||||
|
||||
using ( var client = new UdpClient() )
|
||||
{
|
||||
client.Client.SendTimeout = 3000;
|
||||
client.Client.ReceiveTimeout = 3000;
|
||||
client.Connect( endpoint );
|
||||
internal static Task<Dictionary<string, string>> GetRules( ServerInfo server )
|
||||
{
|
||||
var endpoint = new IPEndPoint(server.Address, server.QueryPort);
|
||||
|
||||
return await GetRules( client );
|
||||
}
|
||||
}
|
||||
catch ( System.Exception e )
|
||||
{
|
||||
Console.Error.WriteLine( e.Message );
|
||||
return null;
|
||||
}
|
||||
lock (PendingQueries)
|
||||
{
|
||||
if (PendingQueries.TryGetValue(endpoint, out var pending))
|
||||
return pending;
|
||||
|
||||
var task = GetRulesImpl(endpoint, server)
|
||||
.ContinueWith(t =>
|
||||
{
|
||||
lock (PendingQueries)
|
||||
{
|
||||
PendingQueries.Remove(endpoint);
|
||||
}
|
||||
|
||||
return t;
|
||||
})
|
||||
.Unwrap();
|
||||
|
||||
PendingQueries.Add(endpoint, task);
|
||||
return task;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<Dictionary<string, string>> GetRulesImpl( IPEndPoint endpoint, ServerInfo server )
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var client = new UdpClient())
|
||||
{
|
||||
client.Client.SendTimeout = 3000;
|
||||
client.Client.ReceiveTimeout = 3000;
|
||||
client.Connect(endpoint);
|
||||
|
||||
return await GetRules(client);
|
||||
}
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
//Console.Error.WriteLine( e.Message );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static async Task<Dictionary<string, string>> GetRules( UdpClient client )
|
||||
@ -54,14 +81,14 @@ namespace Steamworks
|
||||
var numRules = br.ReadUInt16();
|
||||
for ( int index = 0; index < numRules; index++ )
|
||||
{
|
||||
rules.Add( br.ReadNullTerminatedUTF8String( readBuffer ), br.ReadNullTerminatedUTF8String( readBuffer ) );
|
||||
rules.Add( br.ReadNullTerminatedUTF8String(), br.ReadNullTerminatedUTF8String() );
|
||||
}
|
||||
}
|
||||
|
||||
return rules;
|
||||
}
|
||||
|
||||
static byte[] readBuffer = new byte[1024 * 8];
|
||||
|
||||
|
||||
static async Task<byte[]> Receive( UdpClient client )
|
||||
{
|
||||
@ -120,10 +147,10 @@ namespace Steamworks
|
||||
return challengeData;
|
||||
}
|
||||
|
||||
static byte[] sendBuffer = new byte[1024];
|
||||
|
||||
static async Task Send( UdpClient client, byte[] message )
|
||||
{
|
||||
var sendBuffer = new byte[message.Length + 4];
|
||||
|
||||
sendBuffer[0] = 0xFF;
|
||||
sendBuffer[1] = 0xFF;
|
||||
sendBuffer[2] = 0xFF;
|
||||
|
@ -80,20 +80,22 @@ namespace Steamworks
|
||||
}
|
||||
}
|
||||
|
||||
public static string ReadNullTerminatedUTF8String( this BinaryReader br, byte[] buffer = null )
|
||||
static byte[] readBuffer = new byte[1024 * 8];
|
||||
|
||||
public static string ReadNullTerminatedUTF8String( this BinaryReader br )
|
||||
{
|
||||
if ( buffer == null )
|
||||
buffer = new byte[1024];
|
||||
|
||||
byte chr;
|
||||
int i = 0;
|
||||
while ( (chr = br.ReadByte()) != 0 && i < buffer.Length )
|
||||
lock ( readBuffer )
|
||||
{
|
||||
buffer[i] = chr;
|
||||
i++;
|
||||
}
|
||||
byte chr;
|
||||
int i = 0;
|
||||
while ( (chr = br.ReadByte()) != 0 && i < readBuffer.Length )
|
||||
{
|
||||
readBuffer[i] = chr;
|
||||
i++;
|
||||
}
|
||||
|
||||
return Encoding.UTF8.GetString( buffer, 0, i );
|
||||
return Encoding.UTF8.GetString( readBuffer, 0, i );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ public static class Cleanup
|
||||
internal static string Expose( string name )
|
||||
{
|
||||
if ( name == "FriendState" ) return "public";
|
||||
if (name == "FriendFlags") return "public";
|
||||
if ( name == "MusicStatus" ) return "public";
|
||||
if ( name == "ParentalFeature" ) return "public";
|
||||
if ( name == "AuthResponse" ) return "public";
|
||||
@ -86,6 +87,7 @@ public static class Cleanup
|
||||
if ( name == "P2PSessionError" ) return "public";
|
||||
if ( name == "InputType" ) return "public";
|
||||
if ( name == "InputSourceMode" ) return "public";
|
||||
if ( name == "UserHasLicenseForAppResult" ) return "public";
|
||||
|
||||
return "internal";
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user