Struct cleanups and testing

This commit is contained in:
Garry Newman 2019-05-02 20:41:45 +01:00
parent 270b3f0300
commit ce3525bf1d
12 changed files with 291 additions and 193 deletions

View File

@ -91,6 +91,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="FriendsTest.cs" />
<Compile Include="NetworkingSockets.cs" />
<Compile Include="SteamMatchmakingTest.cs" />
<Compile Include="RemoteStorageTest.cs" />
<Compile Include="InventoryTest.cs" />

View File

@ -0,0 +1,69 @@
using System;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Steamworks
{
[TestClass]
[DeploymentItem( "steam_api64.dll" )]
public class NetworkingSocketsTest
{
[TestMethod]
public async Task CreateRelayServer()
{
var socket = SteamNetworkingSockets.CreateRelaySocket();
Console.WriteLine( $"{socket}" );
// Give it a second for something to happen
await Task.Delay( 5000 );
Console.WriteLine( $"{socket}" );
socket.Close();
}
[TestMethod]
public async Task CreateNormalServer()
{
var socket = SteamNetworkingSockets.CreateNormalSocket( Data.NetworkAddress.AnyIp( 21893 ) );
Console.WriteLine( $"{socket}" );
// Give it a second for something to happen
await Task.Delay( 5000 );
Console.WriteLine( $"{socket}" );
socket.Close();
}
[TestMethod]
public async Task ConnectToRelayServer()
{
var socket = SteamNetworkingSockets.CreateRelaySocket( 7788 );
Console.WriteLine( $"Created {socket}" );
//await Task.Delay( 1000 );
var connection = SteamNetworkingSockets.ConnectRelay( SteamClient.SteamId, 7788 );
connection.ConnectionName = "Connected To Self";
connection.UserData = 69;
// Give it a second for something to happen
await Task.Delay( 5000 );
connection.Close();
Console.WriteLine( $"{socket}" );
socket.Close();
}
}
}

View File

@ -46,44 +46,44 @@ public override void InitInternals()
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
private delegate HSteamListenSocket FCreateListenSocketIP( IntPtr self, ref SteamNetworkingIPAddr localAddress );
private delegate Socket FCreateListenSocketIP( IntPtr self, ref NetworkAddress localAddress );
private FCreateListenSocketIP _CreateListenSocketIP;
#endregion
internal HSteamListenSocket CreateListenSocketIP( ref SteamNetworkingIPAddr localAddress )
internal Socket CreateListenSocketIP( ref NetworkAddress localAddress )
{
return _CreateListenSocketIP( Self, ref localAddress );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
private delegate NetConnection FConnectByIPAddress( IntPtr self, ref SteamNetworkingIPAddr address );
private delegate NetConnection FConnectByIPAddress( IntPtr self, ref NetworkAddress address );
private FConnectByIPAddress _ConnectByIPAddress;
#endregion
internal NetConnection ConnectByIPAddress( ref SteamNetworkingIPAddr address )
internal NetConnection ConnectByIPAddress( ref NetworkAddress address )
{
return _ConnectByIPAddress( Self, ref address );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
private delegate HSteamListenSocket FCreateListenSocketP2P( IntPtr self, int nVirtualPort );
private delegate Socket FCreateListenSocketP2P( IntPtr self, int nVirtualPort );
private FCreateListenSocketP2P _CreateListenSocketP2P;
#endregion
internal HSteamListenSocket CreateListenSocketP2P( int nVirtualPort )
internal Socket CreateListenSocketP2P( int nVirtualPort )
{
return _CreateListenSocketP2P( Self, nVirtualPort );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
private delegate NetConnection FConnectP2P( IntPtr self, ref SteamNetworkingIdentity identityRemote, int nVirtualPort );
private delegate NetConnection FConnectP2P( IntPtr self, ref NetworkIdentity identityRemote, int nVirtualPort );
private FConnectP2P _ConnectP2P;
#endregion
internal NetConnection ConnectP2P( ref SteamNetworkingIdentity identityRemote, int nVirtualPort )
internal NetConnection ConnectP2P( ref NetworkIdentity identityRemote, int nVirtualPort )
{
return _ConnectP2P( Self, ref identityRemote, nVirtualPort );
}
@ -114,11 +114,11 @@ internal bool CloseConnection( NetConnection hPeer, int nReason, string pszDebug
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
[return: MarshalAs( UnmanagedType.I1 )]
private delegate bool FCloseListenSocket( IntPtr self, HSteamListenSocket hSocket );
private delegate bool FCloseListenSocket( IntPtr self, Socket hSocket );
private FCloseListenSocket _CloseListenSocket;
#endregion
internal bool CloseListenSocket( HSteamListenSocket hSocket )
internal bool CloseListenSocket( Socket hSocket )
{
return _CloseListenSocket( Self, hSocket );
}
@ -204,11 +204,11 @@ internal int ReceiveMessagesOnConnection( NetConnection hConn, [In,Out] ref Stea
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
private delegate int FReceiveMessagesOnListenSocket( IntPtr self, HSteamListenSocket hSocket, [In,Out] ref SteamNetworkingMessage_t[] ppOutMessages, int nMaxMessages );
private delegate int FReceiveMessagesOnListenSocket( IntPtr self, Socket hSocket, [In,Out] ref SteamNetworkingMessage_t[] ppOutMessages, int nMaxMessages );
private FReceiveMessagesOnListenSocket _ReceiveMessagesOnListenSocket;
#endregion
internal int ReceiveMessagesOnListenSocket( HSteamListenSocket hSocket, [In,Out] ref SteamNetworkingMessage_t[] ppOutMessages, int nMaxMessages )
internal int ReceiveMessagesOnListenSocket( Socket hSocket, [In,Out] ref SteamNetworkingMessage_t[] ppOutMessages, int nMaxMessages )
{
return _ReceiveMessagesOnListenSocket( Self, hSocket, ref ppOutMessages, nMaxMessages );
}
@ -251,11 +251,11 @@ internal int GetDetailedConnectionStatus( NetConnection hConn, StringBuilder psz
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
[return: MarshalAs( UnmanagedType.I1 )]
private delegate bool FGetListenSocketAddress( IntPtr self, HSteamListenSocket hSocket, ref SteamNetworkingIPAddr address );
private delegate bool FGetListenSocketAddress( IntPtr self, Socket hSocket, ref NetworkAddress address );
private FGetListenSocketAddress _GetListenSocketAddress;
#endregion
internal bool GetListenSocketAddress( HSteamListenSocket hSocket, ref SteamNetworkingIPAddr address )
internal bool GetListenSocketAddress( Socket hSocket, ref NetworkAddress address )
{
return _GetListenSocketAddress( Self, hSocket, ref address );
}
@ -263,11 +263,11 @@ internal bool GetListenSocketAddress( HSteamListenSocket hSocket, ref SteamNetwo
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
[return: MarshalAs( UnmanagedType.I1 )]
private delegate bool FCreateSocketPair( IntPtr self, [In,Out] NetConnection[] pOutConnection1, [In,Out] NetConnection[] pOutConnection2, [MarshalAs( UnmanagedType.U1 )] bool bUseNetworkLoopback, ref SteamNetworkingIdentity pIdentity1, ref SteamNetworkingIdentity pIdentity2 );
private delegate bool FCreateSocketPair( IntPtr self, [In,Out] NetConnection[] pOutConnection1, [In,Out] NetConnection[] pOutConnection2, [MarshalAs( UnmanagedType.U1 )] bool bUseNetworkLoopback, ref NetworkIdentity pIdentity1, ref NetworkIdentity pIdentity2 );
private FCreateSocketPair _CreateSocketPair;
#endregion
internal bool CreateSocketPair( [In,Out] NetConnection[] pOutConnection1, [In,Out] NetConnection[] pOutConnection2, [MarshalAs( UnmanagedType.U1 )] bool bUseNetworkLoopback, ref SteamNetworkingIdentity pIdentity1, ref SteamNetworkingIdentity pIdentity2 )
internal bool CreateSocketPair( [In,Out] NetConnection[] pOutConnection1, [In,Out] NetConnection[] pOutConnection2, [MarshalAs( UnmanagedType.U1 )] bool bUseNetworkLoopback, ref NetworkIdentity pIdentity1, ref NetworkIdentity pIdentity2 )
{
return _CreateSocketPair( Self, pOutConnection1, pOutConnection2, bUseNetworkLoopback, ref pIdentity1, ref pIdentity2 );
}
@ -275,11 +275,11 @@ internal bool CreateSocketPair( [In,Out] NetConnection[] pOutConnection1, [In,O
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
[return: MarshalAs( UnmanagedType.I1 )]
private delegate bool FGetIdentity( IntPtr self, ref SteamNetworkingIdentity pIdentity );
private delegate bool FGetIdentity( IntPtr self, ref NetworkIdentity pIdentity );
private FGetIdentity _GetIdentity;
#endregion
internal bool GetIdentity( ref SteamNetworkingIdentity pIdentity )
internal bool GetIdentity( ref NetworkIdentity pIdentity )
{
return _GetIdentity( Self, ref pIdentity );
}
@ -298,22 +298,22 @@ internal bool ReceivedRelayAuthTicket( IntPtr pvTicket, int cbTicket, [In,Out] S
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
private delegate int FFindRelayAuthTicketForServer( IntPtr self, ref SteamNetworkingIdentity identityGameServer, int nVirtualPort, [In,Out] SteamDatagramRelayAuthTicket[] pOutParsedTicket );
private delegate int FFindRelayAuthTicketForServer( IntPtr self, ref NetworkIdentity identityGameServer, int nVirtualPort, [In,Out] SteamDatagramRelayAuthTicket[] pOutParsedTicket );
private FFindRelayAuthTicketForServer _FindRelayAuthTicketForServer;
#endregion
internal int FindRelayAuthTicketForServer( ref SteamNetworkingIdentity identityGameServer, int nVirtualPort, [In,Out] SteamDatagramRelayAuthTicket[] pOutParsedTicket )
internal int FindRelayAuthTicketForServer( ref NetworkIdentity identityGameServer, int nVirtualPort, [In,Out] SteamDatagramRelayAuthTicket[] pOutParsedTicket )
{
return _FindRelayAuthTicketForServer( Self, ref identityGameServer, nVirtualPort, pOutParsedTicket );
}
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
private delegate NetConnection FConnectToHostedDedicatedServer( IntPtr self, ref SteamNetworkingIdentity identityTarget, int nVirtualPort );
private delegate NetConnection FConnectToHostedDedicatedServer( IntPtr self, ref NetworkIdentity identityTarget, int nVirtualPort );
private FConnectToHostedDedicatedServer _ConnectToHostedDedicatedServer;
#endregion
internal NetConnection ConnectToHostedDedicatedServer( ref SteamNetworkingIdentity identityTarget, int nVirtualPort )
internal NetConnection ConnectToHostedDedicatedServer( ref NetworkIdentity identityTarget, int nVirtualPort )
{
return _ConnectToHostedDedicatedServer( Self, ref identityTarget, nVirtualPort );
}
@ -354,11 +354,11 @@ internal bool GetHostedDedicatedServerAddress( ref SteamDatagramHostedAddress pR
#region FunctionMeta
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
private delegate HSteamListenSocket FCreateHostedDedicatedServerListenSocket( IntPtr self, int nVirtualPort );
private delegate Socket FCreateHostedDedicatedServerListenSocket( IntPtr self, int nVirtualPort );
private FCreateHostedDedicatedServerListenSocket _CreateHostedDedicatedServerListenSocket;
#endregion
internal HSteamListenSocket CreateHostedDedicatedServerListenSocket( int nVirtualPort )
internal Socket CreateHostedDedicatedServerListenSocket( int nVirtualPort )
{
return _CreateHostedDedicatedServerListenSocket( Self, nVirtualPort );
}

View File

@ -43,6 +43,7 @@ public static void Init( uint appid )
SteamNetworking.InstallEvents();
SteamMatchmaking.InstallEvents();
SteamParties.InstallEvents();
SteamNetworkingSockets.InstallEvents();
RunCallbacksAsync();
}

View File

@ -18,7 +18,7 @@ internal static ISteamNetworkingSockets Internal
if ( _internal == null )
{
_internal = new ISteamNetworkingSockets();
_internal.InitUserless();
_internal.InitClient();
}
return _internal;
@ -32,14 +32,23 @@ internal static void Shutdown()
internal static void InstallEvents()
{
SteamNetConnectionStatusChangedCallback_t.Install( x => OnConnectionStatusChanged( x ) );
}
private static void OnConnectionStatusChanged( SteamNetConnectionStatusChangedCallback_t data )
{
Console.WriteLine( $"data.Conn: {data.Conn.ToString()}" );
Console.WriteLine( $"data.Conn.UserData: {data.Conn.UserData}" );
Console.WriteLine( $"data.Conn.ConnectionName: {data.Conn.ConnectionName}" );
Console.WriteLine( $"States: {data.Nfo.state} {data.OldState}" );
}
/// <summary>
/// Creates a "server" socket that listens for clients to connect to by calling
/// Connect, over ordinary UDP (IPv4 or IPv6)
/// </summary>
public static HSteamListenSocket CreateExposedSocket( SteamNetworkingIPAddr address )
public static Socket CreateNormalSocket( NetworkAddress address )
{
return Internal.CreateListenSocketIP( ref address );
}
@ -47,7 +56,7 @@ public static HSteamListenSocket CreateExposedSocket( SteamNetworkingIPAddr addr
/// <summary>
/// Connect to a socket created via <method>CreateListenSocketIP</method>
/// </summary>
public static NetConnection ConnectExposed( SteamNetworkingIPAddr address )
public static NetConnection ConnectNormal( NetworkAddress address )
{
return Internal.ConnectByIPAddress( ref address );
}
@ -55,7 +64,7 @@ public static NetConnection ConnectExposed( SteamNetworkingIPAddr address )
/// <summary>
/// Creates a server that will be relayed via Valve's network (hiding the IP and improving ping)
/// </summary>
public static HSteamListenSocket CreateSocket( int virtualport = 0 )
public static Socket CreateRelaySocket( int virtualport = 0 )
{
return Internal.CreateListenSocketP2P( virtualport );
}
@ -63,8 +72,9 @@ public static HSteamListenSocket CreateSocket( int virtualport = 0 )
/// <summary>
/// Connect to a relay server
/// </summary>
public static NetConnection Connect( SteamNetworkingIdentity identity, int virtualport = 0 )
public static NetConnection ConnectRelay( SteamId serverId, int virtualport = 0 )
{
NetworkIdentity identity = serverId;
return Internal.ConnectP2P( ref identity, virtualport );
}
}

View File

@ -0,0 +1,47 @@
using System.Runtime.InteropServices;
namespace Steamworks.Data
{
[StructLayout( LayoutKind.Explicit )]
public struct NetworkAddress
{
[FieldOffset( 0 )]
internal IPV4 ip;
[FieldOffset( 16 )]
internal ushort port;
internal struct IPV4
{
internal ulong m_8zeros;
internal ushort m_0000;
internal ushort m_ffff;
internal byte ip0;
internal byte ip1;
internal byte ip2;
internal byte ip3;
}
/// <summary>
/// Any IP, specific port
/// </summary>
public static NetworkAddress AnyIp( ushort port )
{
return new NetworkAddress
{
ip = new IPV4
{
m_8zeros = 0,
m_0000 = 0,
m_ffff = 0,
ip0 = 0,
ip1 = 0,
ip2 = 0,
ip3 = 1,
},
port = port
};
}
}
}

View File

@ -0,0 +1,36 @@
using System.Runtime.InteropServices;
namespace Steamworks.Data
{
[StructLayout( LayoutKind.Explicit, Size = 136 )]
public struct NetworkIdentity
{
[FieldOffset( 0 )]
internal IdentityType type;
[FieldOffset( 4 )]
internal int m_cbSize;
[FieldOffset( 8 )]
internal SteamId steamID;
public static implicit operator NetworkIdentity( SteamId value )
{
return new NetworkIdentity { steamID = value, type = IdentityType.SteamID, m_cbSize = 8 };
}
public static implicit operator SteamId( NetworkIdentity value )
{
return value.steamID;
}
internal enum IdentityType
{
Invalid = 0,
IPAddress = 1,
GenericString = 2,
GenericBytes = 3,
SteamID = 16
}
}
}

View File

@ -0,0 +1,68 @@
using System.Runtime.InteropServices;
namespace Steamworks.Data
{
/// <summary>
///
/// Object that describes a "location" on the Internet with sufficient
/// detail that we can reasonably estimate an upper bound on the ping between
/// the two hosts, even if a direct route between the hosts is not possible,
/// and the connection must be routed through the Steam Datagram Relay network.
/// This does not contain any information that identifies the host. Indeed,
/// if two hosts are in the same building or otherwise have nearly identical
/// networking characteristics, then it's valid to use the same location
/// object for both of them.
///
/// NOTE: This object should only be used in the same process! Do not serialize it,
/// send it over the wire, or persist it in a file or database! If you need
/// to do that, convert it to a string representation using the methods in
/// ISteamNetworkingUtils().
///
/// </summary>
[StructLayout( LayoutKind.Explicit, Size = 512 )]
public struct PingLocation
{
public static PingLocation? TryParseFromString( string str )
{
var result = default( PingLocation );
if ( !SteamNetworkingUtils.Internal.ParsePingLocationString( str, ref result ) )
return null;
return result;
}
public override string ToString()
{
var sb = Helpers.TakeStringBuilder();
SteamNetworkingUtils.Internal.ConvertPingLocationToString( ref this, sb, sb.Capacity );
return sb.ToString();
}
/// Estimate the round-trip latency between two arbitrary locations, in
/// milliseconds. This is a conservative estimate, based on routing through
/// the relay network. For most basic relayed connections, this ping time
/// will be pretty accurate, since it will be based on the route likely to
/// be actually used.
///
/// If a direct IP route is used (perhaps via NAT traversal), then the route
/// will be different, and the ping time might be better. Or it might actually
/// be a bit worse! Standard IP routing is frequently suboptimal!
///
/// But even in this case, the estimate obtained using this method is a
/// reasonable upper bound on the ping time. (Also it has the advantage
/// of returning immediately and not sending any packets.)
///
/// In a few cases we might not able to estimate the route. In this case
/// a negative value is returned. k_nSteamNetworkingPing_Failed means
/// the reason was because of some networking difficulty. (Failure to
/// ping, etc) k_nSteamNetworkingPing_Unknown is returned if we cannot
/// currently answer the question for some other reason.
///
/// Do you need to be able to do this from a backend/matchmaking server?
/// You are looking for the "ticketgen" library.
public int EstimatePingTo( PingLocation target )
{
return SteamNetworkingUtils.Internal.EstimatePingTimeBetweenTwoLocations( ref this, ref target );
}
}
}

View File

@ -0,0 +1,21 @@
namespace Steamworks.Data
{
public struct Socket
{
internal uint Id;
public override string ToString() => Id.ToString();
/// <summary>
/// Destroy a listen socket. All the connections that were accepting on the listen
/// socket are closed ungracefully.
/// </summary>
public bool Close()
{
return SteamNetworkingSockets.Internal.CloseListenSocket( this );
}
// GetListenSocketAddress
}
}

View File

@ -41,103 +41,13 @@ public static implicit operator uint( SteamNetworkingPOPID value )
public override string ToString() => Value.ToString();
}
public struct HSteamListenSocket
{
public uint Value;
public static implicit operator HSteamListenSocket( uint value )
{
return new HSteamListenSocket { Value = value };
}
public static implicit operator uint( HSteamListenSocket value )
{
return value.Value;
}
public override string ToString() => Value.ToString();
}
public enum IdentityType
{
Invalid = 0,
IPAddress = 1,
GenericString = 2,
GenericBytes = 3,
SteamID = 16
}
[StructLayout( LayoutKind.Explicit, Size = 136 )]
public struct SteamNetworkingIdentity
{
[FieldOffset( 0 )]
public IdentityType type;
/*
public bool IsInvalid
{
get
{
return Native.SteamAPI_SteamNetworkingIdentity_IsInvalid( this );
}
}
public ulong GetSteamID()
{
return Native.SteamAPI_SteamNetworkingIdentity_GetSteamID64( this );
}
public void SetSteamID( ulong steamID )
{
Native.SteamAPI_SteamNetworkingIdentity_SetSteamID64( ref this, steamID );
}
public bool EqualsTo( NetworkingIdentity identity )
{
return Native.SteamAPI_SteamNetworkingIdentity_EqualTo( this, identity );
}*/
}
[StructLayout( LayoutKind.Sequential )]
public struct SteamNetworkingIPAddr
{
[MarshalAs( UnmanagedType.ByValArray, SizeConst = 16 )]
public byte[] ip;
public ushort port;
/*
public bool IsLocalHost
{
get
{
return Native.SteamAPI_SteamNetworkingIPAddr_IsLocalHost( ref this );
}
}
public string GetIP()
{
return ip.ParseIP();
}
public void SetLocalHost( ushort port )
{
Native.SteamAPI_SteamNetworkingIPAddr_SetIPv6LocalHost( ref this, port );
}
public void SetAddress( string ip, ushort port )
{
if ( !ip.Contains( ":" ) )
Native.SteamAPI_SteamNetworkingIPAddr_SetIPv4( ref this, ip.ParseIPv4(), port );
else
Native.SteamAPI_SteamNetworkingIPAddr_SetIPv6( ref this, ip.ParseIPv6(), port );
}*/
}
[StructLayout( LayoutKind.Sequential )]
public struct SteamNetworkingMessage_t
{
public IntPtr data;
public int length;
public NetConnection connection;
public SteamNetworkingIdentity identity;
public NetworkIdentity identity;
public long userData;
public SteamNetworkingMicroseconds timeReceived;
public long messageNumber;
@ -165,10 +75,10 @@ public void Destroy()
[StructLayout( LayoutKind.Sequential )]
public struct SteamNetConnectionInfo_t
{
public SteamNetworkingIdentity identity;
public NetworkIdentity identity;
public long userData;
public HSteamListenSocket listenSocket;
public SteamNetworkingIPAddr address;
public Socket listenSocket;
public NetworkAddress address;
private ushort pad;
private SteamNetworkingPOPID popRemote;
private SteamNetworkingPOPID popRelay;
@ -180,75 +90,6 @@ public struct SteamNetConnectionInfo_t
public string connectionDescription;
}
/// <summary>
///
/// Object that describes a "location" on the Internet with sufficient
/// detail that we can reasonably estimate an upper bound on the ping between
/// the two hosts, even if a direct route between the hosts is not possible,
/// and the connection must be routed through the Steam Datagram Relay network.
/// This does not contain any information that identifies the host. Indeed,
/// if two hosts are in the same building or otherwise have nearly identical
/// networking characteristics, then it's valid to use the same location
/// object for both of them.
///
/// NOTE: This object should only be used in the same process! Do not serialize it,
/// send it over the wire, or persist it in a file or database! If you need
/// to do that, convert it to a string representation using the methods in
/// ISteamNetworkingUtils().
///
/// </summary>
public struct PingLocation
{
[MarshalAs( UnmanagedType.ByValArray, SizeConst = 512, ArraySubType = UnmanagedType.U8 )]
public ushort[] Data;
public static PingLocation? TryParseFromString( string str )
{
var result = default( PingLocation );
if ( !SteamNetworkingUtils.Internal.ParsePingLocationString( str, ref result ) )
return null;
return result;
}
public override string ToString()
{
var sb = Helpers.TakeStringBuilder();
SteamNetworkingUtils.Internal.ConvertPingLocationToString( ref this, sb, sb.Capacity );
return sb.ToString();
}
/// Estimate the round-trip latency between two arbitrary locations, in
/// milliseconds. This is a conservative estimate, based on routing through
/// the relay network. For most basic relayed connections, this ping time
/// will be pretty accurate, since it will be based on the route likely to
/// be actually used.
///
/// If a direct IP route is used (perhaps via NAT traversal), then the route
/// will be different, and the ping time might be better. Or it might actually
/// be a bit worse! Standard IP routing is frequently suboptimal!
///
/// But even in this case, the estimate obtained using this method is a
/// reasonable upper bound on the ping time. (Also it has the advantage
/// of returning immediately and not sending any packets.)
///
/// In a few cases we might not able to estimate the route. In this case
/// a negative value is returned. k_nSteamNetworkingPing_Failed means
/// the reason was because of some networking difficulty. (Failure to
/// ping, etc) k_nSteamNetworkingPing_Unknown is returned if we cannot
/// currently answer the question for some other reason.
///
/// Do you need to be able to do this from a backend/matchmaking server?
/// You are looking for the "ticketgen" library.
public int EstimatePingTo( PingLocation target )
{
return SteamNetworkingUtils.Internal.EstimatePingTimeBetweenTwoLocations( ref this, ref target );
}
}
[StructLayout( LayoutKind.Sequential )]
public struct SteamNetworkingQuickConnectionStatus
{

View File

@ -31,6 +31,9 @@ public static string ConvertType( string type )
type = type.Replace( "SteamNetworkingConfigScope", "NetScope" );
type = type.Replace( "SteamNetworkingConfigDataType", "NetConfigType" );
type = type.Replace( "HSteamNetConnection", "NetConnection" );
type = type.Replace( "HSteamListenSocket", "Socket" );
type = type.Replace( "SteamNetworkingIPAddr", "NetworkAddress" );
type = type.Replace( "SteamNetworkingIdentity", "NetworkIdentity" );
return type;
}

View File

@ -50,7 +50,8 @@ public static BaseType Parse( string type, string varname = null )
if ( basicType == "InventoryDefId" ) return new StructType { NativeType = type, VarName = varname, StructName = basicType };
if ( basicType == "PingLocation" ) return new StructType { NativeType = type, VarName = varname, StructName = basicType };
if ( basicType == "SteamNetworkingIPAddr" ) return new StructType { NativeType = type, VarName = varname, StructName = basicType };
if ( basicType == "SteamNetworkingIdentity" ) return new StructType { NativeType = type, VarName = varname, StructName = basicType };
if ( basicType == "NetworkIdentity" ) return new StructType { NativeType = type, VarName = varname, StructName = basicType };
if ( basicType == "NetworkAddress" ) return new StructType { NativeType = type, VarName = varname, StructName = basicType };
if ( basicType.StartsWith( "E" ) && char.IsUpper( basicType[1] ) ) return new EnumType { NativeType = type.Substring( 1 ), VarName = varname };
return new BaseType { NativeType = type, VarName = varname };