mirror of
https://github.com/Facepunch/Facepunch.Steamworks.git
synced 2024-12-26 22:55:55 +03:00
Refactoring
This commit is contained in:
parent
e6126a0e40
commit
5fa72a0275
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
@ -27,6 +28,17 @@ public void PeerToPeerSend()
|
|||||||
OutputReceived = true;
|
OutputReceived = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
client.Networking.OnIncomingConnection = ( steamid ) =>
|
||||||
|
{
|
||||||
|
Console.WriteLine( "Incoming P2P Connection: " + steamid );
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
client.Networking.OnConnectionFailed = ( steamid, error ) =>
|
||||||
|
{
|
||||||
|
Console.WriteLine( "Connection Error: " + steamid + " - " + error );
|
||||||
|
};
|
||||||
|
|
||||||
client.Networking.SendP2PPacket( client.SteamId, data, data.Length );
|
client.Networking.SendP2PPacket( client.SteamId, data, data.Length );
|
||||||
|
|
||||||
while( true )
|
while( true )
|
||||||
@ -39,5 +51,58 @@ public void PeerToPeerSend()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void PeerToPeerFailure()
|
||||||
|
{
|
||||||
|
using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
|
||||||
|
{
|
||||||
|
var TestString = "This string will be transformed to bytes, sent over the Steam P2P network, then converted back to a string.";
|
||||||
|
var TimeoutReceived = false;
|
||||||
|
var data = Encoding.UTF8.GetBytes( TestString );
|
||||||
|
|
||||||
|
client.Networking.OnIncomingConnection = ( steamid ) =>
|
||||||
|
{
|
||||||
|
Console.WriteLine( "Incoming P2P Connection: " + steamid );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
client.Networking.OnConnectionFailed = ( steamid, error ) =>
|
||||||
|
{
|
||||||
|
Console.WriteLine( "Connection Error: " + steamid + " - " + error );
|
||||||
|
TimeoutReceived = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
ulong rand = (ulong) new Random().Next( 1024 * 16 );
|
||||||
|
|
||||||
|
// Send to an invalid, not listening steamid
|
||||||
|
if ( !client.Networking.SendP2PPacket( client.SteamId + rand, data, data.Length ) )
|
||||||
|
{
|
||||||
|
Console.WriteLine( "Couldn't send packet" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sw = Stopwatch.StartNew();
|
||||||
|
|
||||||
|
while ( true )
|
||||||
|
{
|
||||||
|
Thread.Sleep( 10 );
|
||||||
|
client.Update();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Timout is usually around 15 seconds
|
||||||
|
//
|
||||||
|
if ( TimeoutReceived )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ( sw.Elapsed.TotalSeconds > 30 )
|
||||||
|
{
|
||||||
|
Assert.Fail( "Didn't time out" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,12 +31,8 @@ public void AuthCallback()
|
|||||||
|
|
||||||
using ( var server = new Facepunch.Steamworks.Server( 252490, 30001, 30002, 30003, true, "VersionString" ) )
|
using ( var server = new Facepunch.Steamworks.Server( 252490, 30001, 30002, 30003, true, "VersionString" ) )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
server.LogOnAnonymous();
|
server.LogOnAnonymous();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Assert.IsTrue( server.Valid );
|
Assert.IsTrue( server.Valid );
|
||||||
|
|
||||||
var auth = server.Auth;
|
var auth = server.Auth;
|
||||||
|
47
Facepunch.Steamworks/BaseSteamworks.cs
Normal file
47
Facepunch.Steamworks/BaseSteamworks.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Facepunch.Steamworks
|
||||||
|
{
|
||||||
|
public class BaseSteamworks : IDisposable
|
||||||
|
{
|
||||||
|
public virtual void Dispose()
|
||||||
|
{
|
||||||
|
foreach ( var d in Disposables )
|
||||||
|
{
|
||||||
|
d.Dispose();
|
||||||
|
}
|
||||||
|
Disposables.Clear();
|
||||||
|
|
||||||
|
if ( native != null )
|
||||||
|
{
|
||||||
|
native.Dispose();
|
||||||
|
native = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Interop.NativeInterface native;
|
||||||
|
internal virtual bool IsGameServer { get { return false; } }
|
||||||
|
|
||||||
|
private List<IDisposable> Disposables = new List<IDisposable>();
|
||||||
|
|
||||||
|
public enum MessageType : int
|
||||||
|
{
|
||||||
|
Message = 0,
|
||||||
|
Warning = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called with a message from Steam
|
||||||
|
/// </summary>
|
||||||
|
public Action<MessageType, string> OnMessage;
|
||||||
|
|
||||||
|
internal void AddCallback<T>( Action<T> Callback, int id )
|
||||||
|
{
|
||||||
|
var callback = new Facepunch.Steamworks.Interop.Callback<T>( IsGameServer, id, Callback );
|
||||||
|
Disposables.Add( callback );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
Facepunch.Steamworks/Callbacks/Index.cs
Normal file
14
Facepunch.Steamworks/Callbacks/Index.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Facepunch.Steamworks.Callbacks
|
||||||
|
{
|
||||||
|
internal static class Index
|
||||||
|
{
|
||||||
|
internal const int User = 100;
|
||||||
|
internal const int Networking = 1200;
|
||||||
|
internal const int RemoteStorage = 1300;
|
||||||
|
}
|
||||||
|
}
|
27
Facepunch.Steamworks/Callbacks/Networking.cs
Normal file
27
Facepunch.Steamworks/Callbacks/Networking.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Facepunch.Steamworks.Callbacks.Networking
|
||||||
|
{
|
||||||
|
[StructLayout( LayoutKind.Sequential )]
|
||||||
|
internal class P2PSessionRequest
|
||||||
|
{
|
||||||
|
public ulong SteamID;
|
||||||
|
|
||||||
|
public const int CallbackId = Index.Networking + 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
[StructLayout( LayoutKind.Sequential )]
|
||||||
|
internal class P2PSessionConnectFail
|
||||||
|
{
|
||||||
|
public ulong SteamID;
|
||||||
|
public Steamworks.Networking.SessionError Error;
|
||||||
|
|
||||||
|
public const int CallbackId = Index.Networking + 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -30,8 +30,5 @@ public enum Response : int
|
|||||||
public const int CallbackId = Index.User + 43;
|
public const int CallbackId = Index.User + 43;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal static class Index
|
|
||||||
{
|
|
||||||
internal const int User = 100;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,86 +5,8 @@
|
|||||||
|
|
||||||
namespace Facepunch.Steamworks
|
namespace Facepunch.Steamworks
|
||||||
{
|
{
|
||||||
public partial class Client : IDisposable
|
public partial class Client : BaseSteamworks
|
||||||
{
|
{
|
||||||
internal class Internal : IDisposable
|
|
||||||
{
|
|
||||||
private int _hpipe;
|
|
||||||
private int _huser;
|
|
||||||
|
|
||||||
internal Valve.Steamworks.ISteamClient client;
|
|
||||||
internal Valve.Steamworks.ISteamUser user;
|
|
||||||
internal Valve.Steamworks.ISteamApps apps;
|
|
||||||
internal Valve.Steamworks.ISteamFriends friends;
|
|
||||||
internal Valve.Steamworks.ISteamMatchmakingServers servers;
|
|
||||||
internal Valve.Steamworks.ISteamInventory inventory;
|
|
||||||
internal Valve.Steamworks.ISteamNetworking networking;
|
|
||||||
internal Valve.Steamworks.ISteamUserStats userstats;
|
|
||||||
internal Valve.Steamworks.ISteamUtils utils;
|
|
||||||
internal Valve.Steamworks.ISteamScreenshots screenshots;
|
|
||||||
|
|
||||||
internal bool Init()
|
|
||||||
{
|
|
||||||
_huser = Valve.Interop.NativeEntrypoints.Extended.SteamAPI_GetHSteamUser();
|
|
||||||
_hpipe = Valve.Interop.NativeEntrypoints.Extended.SteamAPI_GetHSteamPipe();
|
|
||||||
if ( _hpipe == 0 )
|
|
||||||
throw new System.Exception( "Couldn't get Steam Pipe" );
|
|
||||||
|
|
||||||
var clientPtr = Valve.Interop.NativeEntrypoints.Extended.SteamInternal_CreateInterface( "SteamClient017" );
|
|
||||||
if ( clientPtr == IntPtr.Zero )
|
|
||||||
{
|
|
||||||
throw new System.Exception( "Steam Client: Couldn't load SteamClient017" );
|
|
||||||
}
|
|
||||||
|
|
||||||
client = new Valve.Steamworks.CSteamClient( clientPtr );
|
|
||||||
|
|
||||||
if ( client.GetIntPtr() == IntPtr.Zero )
|
|
||||||
{
|
|
||||||
client = null;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
friends = client.GetISteamFriends( _huser, _hpipe, "SteamFriends015" );
|
|
||||||
if ( friends.GetIntPtr() == IntPtr.Zero ) throw new System.Exception( "Couldn't load SteamFriends015" );
|
|
||||||
|
|
||||||
user = client.GetISteamUser( _huser, _hpipe, "SteamUser019" );
|
|
||||||
servers = client.GetISteamMatchmakingServers( _huser, _hpipe, "SteamMatchMakingServers002" );
|
|
||||||
inventory = client.GetISteamInventory( _huser, _hpipe, "STEAMINVENTORY_INTERFACE_V001" );
|
|
||||||
networking = client.GetISteamNetworking( _huser, _hpipe, "SteamNetworking005" );
|
|
||||||
apps = client.GetISteamApps( _huser, _hpipe, "STEAMAPPS_INTERFACE_VERSION008" );
|
|
||||||
userstats = client.GetISteamUserStats( _huser, _hpipe, "STEAMUSERSTATS_INTERFACE_VERSION011" );
|
|
||||||
screenshots = client.GetISteamScreenshots( _huser, _hpipe, "STEAMSCREENSHOTS_INTERFACE_VERSION002" );
|
|
||||||
|
|
||||||
utils = client.GetISteamUtils( _hpipe, "SteamUtils008" );
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if ( _hpipe > 0 && client != null )
|
|
||||||
{
|
|
||||||
// if ( _huser > 0 )
|
|
||||||
// client.ReleaseUser( _hpipe, _huser );
|
|
||||||
|
|
||||||
// client.BReleaseSteamPipe( _hpipe );
|
|
||||||
|
|
||||||
_huser = 0;
|
|
||||||
_hpipe = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( client != null )
|
|
||||||
{
|
|
||||||
client.BShutdownIfAllPipesClosed();
|
|
||||||
client = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Valve.Interop.NativeEntrypoints.Extended.SteamAPI_Shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Internal native;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current running program's AppId
|
/// Current running program's AppId
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -105,33 +27,27 @@ public void Dispose()
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string BetaName { get; private set; }
|
public string BetaName { get; private set; }
|
||||||
|
|
||||||
public enum MessageType : int
|
|
||||||
{
|
|
||||||
Message = 0,
|
|
||||||
Warning = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called with a message from Steam
|
|
||||||
/// </summary>
|
|
||||||
public Action<MessageType, string> OnMessage;
|
|
||||||
|
|
||||||
public Client( uint appId )
|
public Client( uint appId )
|
||||||
{
|
{
|
||||||
Valve.Steamworks.SteamAPIInterop.SteamAPI_Init();
|
Valve.Steamworks.SteamAPIInterop.SteamAPI_Init();
|
||||||
|
|
||||||
native = new Internal();
|
native = new Interop.NativeInterface();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get other interfaces
|
// Get other interfaces
|
||||||
//
|
//
|
||||||
if ( !native.Init() )
|
if ( !native.InitClient() )
|
||||||
{
|
{
|
||||||
native.Dispose();
|
native.Dispose();
|
||||||
native = null;
|
native = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Networking = new Steamworks.Networking( this, native.networking );
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set up warning hook callback
|
// Set up warning hook callback
|
||||||
//
|
//
|
||||||
@ -152,13 +68,15 @@ public Client( uint appId )
|
|||||||
Update();
|
Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
if ( native != null)
|
if ( native != null)
|
||||||
{
|
{
|
||||||
native.Dispose();
|
native.Dispose();
|
||||||
native = null;
|
native = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnmanagedFunctionPointer( CallingConvention.Cdecl )]
|
[UnmanagedFunctionPointer( CallingConvention.Cdecl )]
|
||||||
@ -208,5 +126,7 @@ internal Action InstallCallback( int type, Delegate action )
|
|||||||
//return () => Valve.Steamworks.SteamAPI.UnregisterCallback( ptr );
|
//return () => Valve.Steamworks.SteamAPI.UnregisterCallback( ptr );
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Networking Networking { get; internal set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,10 +113,12 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="BaseSteamworks.cs" />
|
||||||
|
<Compile Include="Callbacks\Index.cs" />
|
||||||
<Compile Include="Callbacks\User.cs" />
|
<Compile Include="Callbacks\User.cs" />
|
||||||
<Compile Include="Client\Inventory.Item.cs" />
|
<Compile Include="Client\Inventory.Item.cs" />
|
||||||
<Compile Include="Client\Inventory.Result.cs" />
|
<Compile Include="Client\Inventory.Result.cs" />
|
||||||
<Compile Include="Client\Networking.cs" />
|
<Compile Include="Interfaces\Networking.cs" />
|
||||||
<Compile Include="Client\Overlay.cs" />
|
<Compile Include="Client\Overlay.cs" />
|
||||||
<Compile Include="Client\ServerList.cs" />
|
<Compile Include="Client\ServerList.cs" />
|
||||||
<Compile Include="Client\ServerList.Request.cs" />
|
<Compile Include="Client\ServerList.Request.cs" />
|
||||||
@ -132,7 +134,9 @@
|
|||||||
<Compile Include="Client\Inventory.Definition.cs" />
|
<Compile Include="Client\Inventory.Definition.cs" />
|
||||||
<Compile Include="Client\Voice.cs" />
|
<Compile Include="Client\Voice.cs" />
|
||||||
<Compile Include="Config.cs" />
|
<Compile Include="Config.cs" />
|
||||||
|
<Compile Include="Callbacks\Networking.cs" />
|
||||||
<Compile Include="Interop\Callback.cs" />
|
<Compile Include="Interop\Callback.cs" />
|
||||||
|
<Compile Include="Interop\Native.cs" />
|
||||||
<Compile Include="Interop\ServerRules.cs" />
|
<Compile Include="Interop\ServerRules.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Interop\steam_api_interop.cs" />
|
<Compile Include="Interop\steam_api_interop.cs" />
|
||||||
|
@ -3,51 +3,25 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Facepunch.Steamworks.Callbacks.Networking;
|
||||||
using Valve.Steamworks;
|
using Valve.Steamworks;
|
||||||
|
|
||||||
namespace Facepunch.Steamworks
|
namespace Facepunch.Steamworks
|
||||||
{
|
{
|
||||||
public partial class Client : IDisposable
|
|
||||||
{
|
|
||||||
private Networking _net;
|
|
||||||
|
|
||||||
public Networking Networking
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if ( _net == null )
|
|
||||||
_net = new Networking( this );
|
|
||||||
|
|
||||||
return _net;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Networking
|
public class Networking
|
||||||
{
|
{
|
||||||
public Action<ulong, MemoryStream, int> OnP2PData;
|
public Action<ulong, MemoryStream, int> OnP2PData;
|
||||||
|
public Func<ulong, bool> OnIncomingConnection;
|
||||||
|
public Action<ulong, SessionError> OnConnectionFailed;
|
||||||
|
|
||||||
internal Client client;
|
internal ISteamNetworking networking;
|
||||||
|
|
||||||
internal class Callback
|
internal Networking( BaseSteamworks sw, ISteamNetworking networking )
|
||||||
{
|
{
|
||||||
internal delegate void P2PSessionRequest( P2PSessionRequest_t a );
|
this.networking = networking;
|
||||||
internal delegate void P2PSessionConnectFail( P2PSessionConnectFail_t a );
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Networking( Client c )
|
sw.AddCallback<P2PSessionRequest>( onP2PConnectionRequest, P2PSessionRequest.CallbackId );
|
||||||
{
|
sw.AddCallback<P2PSessionConnectFail>( onP2PConnectionFailed, P2PSessionConnectFail.CallbackId );
|
||||||
client = c;
|
|
||||||
|
|
||||||
{
|
|
||||||
Callback.P2PSessionRequest cb = onP2PConnectionRequest;
|
|
||||||
client.InstallCallback( Valve.Steamworks.SteamAPI.k_iSteamNetworkingCallbacks + 2, cb );
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
Callback.P2PSessionConnectFail cb = onP2PConnectionFailed;
|
|
||||||
client.InstallCallback( Valve.Steamworks.SteamAPI.k_iSteamNetworkingCallbacks + 2, cb );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Update()
|
internal void Update()
|
||||||
@ -65,17 +39,51 @@ internal void Update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onP2PConnectionRequest( P2PSessionRequest_t o )
|
private void onP2PConnectionRequest( P2PSessionRequest o )
|
||||||
{
|
{
|
||||||
Console.WriteLine( "onP2PConnectionRequest " + o.m_steamIDRemote );
|
if ( OnIncomingConnection != null )
|
||||||
|
{
|
||||||
|
var accept = OnIncomingConnection( o.SteamID );
|
||||||
|
|
||||||
|
if ( accept )
|
||||||
|
{
|
||||||
|
networking.AcceptP2PSessionWithUser( o.SteamID );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
networking.CloseP2PSessionWithUser( o.SteamID );
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Default is to reject the session
|
||||||
|
//
|
||||||
|
networking.CloseP2PSessionWithUser( o.SteamID );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onP2PConnectionFailed( P2PSessionConnectFail_t o )
|
public enum SessionError : byte
|
||||||
{
|
{
|
||||||
Console.WriteLine( "onP2PConnectionFailed " + o.m_steamIDRemote );
|
None = 0,
|
||||||
|
NotRunningApp = 1, // target is not running the same game
|
||||||
|
NoRightsToApp = 2, // local user doesn't own the app that is running
|
||||||
|
DestinationNotLoggedIn = 3, // target user isn't connected to Steam
|
||||||
|
Timeout = 4, // target isn't responding, perhaps not calling AcceptP2PSessionWithUser()
|
||||||
|
// corporate firewalls can also block this (NAT traversal is not firewall traversal)
|
||||||
|
// make sure that UDP ports 3478, 4379, and 4380 are open in an outbound direction
|
||||||
|
Max = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
private void onP2PConnectionFailed( P2PSessionConnectFail o )
|
||||||
|
{
|
||||||
|
if ( OnConnectionFailed != null )
|
||||||
|
{
|
||||||
|
OnConnectionFailed( o.SteamID, o.Error );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum EP2PSend : int
|
public enum SendType : int
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Basic UDP send. Packets can't be bigger than 1200 bytes (your typical MTU size). Can be lost, or arrive out of order (rare).
|
/// Basic UDP send. Packets can't be bigger than 1200 bytes (your typical MTU size). Can be lost, or arrive out of order (rare).
|
||||||
@ -109,11 +117,11 @@ public enum EP2PSend : int
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe bool SendP2PPacket( ulong steamid, byte[] data, int length, EP2PSend eP2PSendType = EP2PSend.Reliable, int nChannel = 0 )
|
public unsafe bool SendP2PPacket( ulong steamid, byte[] data, int length, SendType eP2PSendType = SendType.Reliable, int nChannel = 0 )
|
||||||
{
|
{
|
||||||
fixed ( byte* p = data )
|
fixed ( byte* p = data )
|
||||||
{
|
{
|
||||||
return client.native.networking.SendP2PPacket( steamid, (IntPtr) p, (uint)length, (uint)eP2PSendType, nChannel );
|
return networking.SendP2PPacket( steamid, (IntPtr) p, (uint)length, (uint)eP2PSendType, nChannel );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +129,7 @@ private unsafe bool ReadP2PPacket( MemoryStream ms, int channel = 0 )
|
|||||||
{
|
{
|
||||||
uint DataAvailable = 0;
|
uint DataAvailable = 0;
|
||||||
|
|
||||||
if ( !client.native.networking.IsP2PPacketAvailable( ref DataAvailable, channel ) || DataAvailable == 0 )
|
if ( !networking.IsP2PPacketAvailable( ref DataAvailable, channel ) || DataAvailable == 0 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( ms.Capacity < DataAvailable )
|
if ( ms.Capacity < DataAvailable )
|
||||||
@ -133,7 +141,7 @@ private unsafe bool ReadP2PPacket( MemoryStream ms, int channel = 0 )
|
|||||||
fixed ( byte* p = ms.GetBuffer() )
|
fixed ( byte* p = ms.GetBuffer() )
|
||||||
{
|
{
|
||||||
ulong steamid = 1;
|
ulong steamid = 1;
|
||||||
if ( !client.native.networking.ReadP2PPacket( (IntPtr)p, (uint)DataAvailable, ref DataAvailable, ref steamid, channel ) || DataAvailable == 0 )
|
if ( !networking.ReadP2PPacket( (IntPtr)p, (uint)DataAvailable, ref DataAvailable, ref steamid, channel ) || DataAvailable == 0 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ms.SetLength( DataAvailable );
|
ms.SetLength( DataAvailable );
|
@ -99,7 +99,7 @@ void InitVTable()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//vTablePtr = VTable.CDecl.Callback.Get( OnRunCallback, GetSize );
|
throw new System.NotImplementedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
91
Facepunch.Steamworks/Interop/Native.cs
Normal file
91
Facepunch.Steamworks/Interop/Native.cs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Facepunch.Steamworks.Interop
|
||||||
|
{
|
||||||
|
internal class NativeInterface : IDisposable
|
||||||
|
{
|
||||||
|
internal Valve.Steamworks.ISteamClient client;
|
||||||
|
internal Valve.Steamworks.ISteamUser user;
|
||||||
|
internal Valve.Steamworks.ISteamApps apps;
|
||||||
|
internal Valve.Steamworks.ISteamFriends friends;
|
||||||
|
internal Valve.Steamworks.ISteamMatchmakingServers servers;
|
||||||
|
internal Valve.Steamworks.ISteamInventory inventory;
|
||||||
|
internal Valve.Steamworks.ISteamNetworking networking;
|
||||||
|
internal Valve.Steamworks.ISteamUserStats userstats;
|
||||||
|
internal Valve.Steamworks.ISteamUtils utils;
|
||||||
|
internal Valve.Steamworks.ISteamScreenshots screenshots;
|
||||||
|
internal Valve.Steamworks.ISteamHTTP http;
|
||||||
|
internal Valve.Steamworks.ISteamUGC ugc;
|
||||||
|
internal Valve.Steamworks.ISteamGameServer gameServer;
|
||||||
|
internal Valve.Steamworks.ISteamGameServerStats gameServerStats;
|
||||||
|
|
||||||
|
internal bool InitClient()
|
||||||
|
{
|
||||||
|
var user = Valve.Interop.NativeEntrypoints.Extended.SteamAPI_GetHSteamUser();
|
||||||
|
var pipe = Valve.Interop.NativeEntrypoints.Extended.SteamAPI_GetHSteamPipe();
|
||||||
|
if ( pipe == 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
FillInterfaces( user, pipe );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool InitServer()
|
||||||
|
{
|
||||||
|
var user = Valve.Interop.NativeEntrypoints.Extended.SteamGameServer_GetHSteamUser();
|
||||||
|
var pipe = Valve.Interop.NativeEntrypoints.Extended.SteamGameServer_GetHSteamPipe();
|
||||||
|
if ( pipe == 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
FillInterfaces( pipe, user );
|
||||||
|
|
||||||
|
if ( gameServer.GetIntPtr() == IntPtr.Zero )
|
||||||
|
{
|
||||||
|
gameServer = null;
|
||||||
|
throw new System.Exception( "Steam Server: Couldn't load SteamGameServer012" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FillInterfaces( int hpipe, int huser )
|
||||||
|
{
|
||||||
|
var clientPtr = Valve.Interop.NativeEntrypoints.Extended.SteamInternal_CreateInterface( "SteamClient017" );
|
||||||
|
if ( clientPtr == IntPtr.Zero )
|
||||||
|
{
|
||||||
|
throw new System.Exception( "Steam Server: Couldn't load SteamClient017" );
|
||||||
|
}
|
||||||
|
|
||||||
|
client = new Valve.Steamworks.CSteamClient( clientPtr );
|
||||||
|
|
||||||
|
user = client.GetISteamUser( huser, hpipe, "SteamUser019" );
|
||||||
|
utils = client.GetISteamUtils( hpipe, "SteamUtils008" );
|
||||||
|
networking = client.GetISteamNetworking( huser, hpipe, "SteamNetworking005" );
|
||||||
|
gameServerStats = client.GetISteamGameServerStats( huser, hpipe, "SteamGameServerStats001" );
|
||||||
|
http = client.GetISteamHTTP( huser, hpipe, "STEAMHTTP_INTERFACE_VERSION002" );
|
||||||
|
inventory = client.GetISteamInventory( huser, hpipe, "STEAMINVENTORY_INTERFACE_V001" );
|
||||||
|
ugc = client.GetISteamUGC( huser, hpipe, "STEAMUGC_INTERFACE_VERSION008" );
|
||||||
|
apps = client.GetISteamApps( huser, hpipe, "STEAMAPPS_INTERFACE_VERSION008" );
|
||||||
|
gameServer = client.GetISteamGameServer( huser, hpipe, "SteamGameServer012" );
|
||||||
|
friends = client.GetISteamFriends( huser, hpipe, "SteamFriends015" );
|
||||||
|
servers = client.GetISteamMatchmakingServers( huser, hpipe, "SteamMatchMakingServers002" );
|
||||||
|
userstats = client.GetISteamUserStats( huser, hpipe, "STEAMUSERSTATS_INTERFACE_VERSION011" );
|
||||||
|
screenshots = client.GetISteamScreenshots( huser, hpipe, "STEAMSCREENSHOTS_INTERFACE_VERSION002" );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if ( client != null )
|
||||||
|
{
|
||||||
|
client.BShutdownIfAllPipesClosed();
|
||||||
|
client = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Valve.Interop.NativeEntrypoints.Extended.SteamAPI_Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,76 +6,8 @@
|
|||||||
|
|
||||||
namespace Facepunch.Steamworks
|
namespace Facepunch.Steamworks
|
||||||
{
|
{
|
||||||
public partial class Server : IDisposable
|
public partial class Server : BaseSteamworks
|
||||||
{
|
{
|
||||||
internal class Internal : IDisposable
|
|
||||||
{
|
|
||||||
internal Valve.Steamworks.ISteamClient client;
|
|
||||||
internal Valve.Steamworks.ISteamGameServer gameServer;
|
|
||||||
internal Valve.Steamworks.ISteamUtils utils;
|
|
||||||
internal Valve.Steamworks.ISteamNetworking networking;
|
|
||||||
internal Valve.Steamworks.ISteamGameServerStats stats;
|
|
||||||
internal Valve.Steamworks.ISteamHTTP http;
|
|
||||||
internal Valve.Steamworks.ISteamInventory inventory;
|
|
||||||
internal Valve.Steamworks.ISteamUGC ugc;
|
|
||||||
internal Valve.Steamworks.ISteamApps apps;
|
|
||||||
|
|
||||||
internal bool Init()
|
|
||||||
{
|
|
||||||
var user = Valve.Interop.NativeEntrypoints.Extended.SteamGameServer_GetHSteamUser();
|
|
||||||
var pipe = Valve.Interop.NativeEntrypoints.Extended.SteamGameServer_GetHSteamPipe();
|
|
||||||
if ( pipe == 0 )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
var clientPtr = Valve.Interop.NativeEntrypoints.Extended.SteamInternal_CreateInterface( "SteamClient017" );
|
|
||||||
if ( clientPtr == IntPtr.Zero )
|
|
||||||
{
|
|
||||||
throw new System.Exception( "Steam Server: Couldn't load SteamClient017" );
|
|
||||||
}
|
|
||||||
|
|
||||||
client = new Valve.Steamworks.CSteamClient( clientPtr );
|
|
||||||
|
|
||||||
|
|
||||||
gameServer = client.GetISteamGameServer( user, pipe, "SteamGameServer012" );
|
|
||||||
|
|
||||||
if ( gameServer.GetIntPtr() == IntPtr.Zero )
|
|
||||||
{
|
|
||||||
gameServer = null;
|
|
||||||
throw new System.Exception( "Steam Server: Couldn't load SteamGameServer012" );
|
|
||||||
}
|
|
||||||
|
|
||||||
utils = client.GetISteamUtils( pipe, "SteamUtils008" );
|
|
||||||
networking = client.GetISteamNetworking( user, pipe, "SteamNetworking005" );
|
|
||||||
stats = client.GetISteamGameServerStats( user, pipe, "SteamGameServerStats001" );
|
|
||||||
http = client.GetISteamHTTP( user, pipe, "STEAMHTTP_INTERFACE_VERSION002" );
|
|
||||||
inventory = client.GetISteamInventory( user, pipe, "STEAMINVENTORY_INTERFACE_V001" );
|
|
||||||
ugc = client.GetISteamUGC( user, pipe, "STEAMUGC_INTERFACE_VERSION008" );
|
|
||||||
apps = client.GetISteamApps( user, pipe, "STEAMAPPS_INTERFACE_VERSION008" );
|
|
||||||
|
|
||||||
if ( ugc.GetIntPtr() == IntPtr.Zero )
|
|
||||||
throw new System.Exception( "Steam Server: Couldn't load STEAMUGC_INTERFACE_VERSION008" );
|
|
||||||
|
|
||||||
if ( apps.GetIntPtr() == IntPtr.Zero )
|
|
||||||
throw new System.Exception( "Steam Server: Couldn't load STEAMAPPS_INTERFACE_VERSION008" );
|
|
||||||
|
|
||||||
if ( inventory.GetIntPtr() == IntPtr.Zero )
|
|
||||||
throw new System.Exception( "Steam Server: Couldn't load STEAMINVENTORY_INTERFACE_V001" );
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if ( client != null )
|
|
||||||
{
|
|
||||||
client.BShutdownIfAllPipesClosed();
|
|
||||||
client = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Internal native;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current running program's AppId
|
/// Current running program's AppId
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -91,27 +23,18 @@ public void Dispose()
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ulong SteamId { get; private set; }
|
public ulong SteamId { get; private set; }
|
||||||
|
|
||||||
public enum MessageType : int
|
internal override bool IsGameServer { get { return true; } }
|
||||||
{
|
|
||||||
Message = 0,
|
|
||||||
Warning = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Called with a message from Steam
|
|
||||||
/// </summary>
|
|
||||||
public Action<MessageType, string> OnMessage;
|
|
||||||
|
|
||||||
public Server( uint appId, uint IpAddress, ushort GamePort, ushort QueryPort, bool Secure, string VersionString )
|
public Server( uint appId, uint IpAddress, ushort GamePort, ushort QueryPort, bool Secure, string VersionString )
|
||||||
{
|
{
|
||||||
Valve.Interop.NativeEntrypoints.Extended.SteamInternal_GameServer_Init( IpAddress, 0, GamePort, QueryPort, Secure ? 3 : 2, VersionString );
|
Valve.Interop.NativeEntrypoints.Extended.SteamInternal_GameServer_Init( IpAddress, 0, GamePort, QueryPort, Secure ? 3 : 2, VersionString );
|
||||||
|
|
||||||
native = new Internal();
|
native = new Interop.NativeInterface();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Get other interfaces
|
// Get other interfaces
|
||||||
//
|
//
|
||||||
if ( !native.Init() )
|
if ( !native.InitServer() )
|
||||||
{
|
{
|
||||||
native.Dispose();
|
native.Dispose();
|
||||||
native = null;
|
native = null;
|
||||||
@ -153,21 +76,6 @@ public Server( uint appId, uint IpAddress, ushort GamePort, bool Secure, string
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
if ( native != null)
|
|
||||||
{
|
|
||||||
native.Dispose();
|
|
||||||
native = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ( var d in Disposables )
|
|
||||||
{
|
|
||||||
d.Dispose();
|
|
||||||
}
|
|
||||||
Disposables.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnmanagedFunctionPointer( CallingConvention.Cdecl )]
|
[UnmanagedFunctionPointer( CallingConvention.Cdecl )]
|
||||||
public delegate void SteamAPIWarningMessageHook( int nSeverity, string pchDebugText );
|
public delegate void SteamAPIWarningMessageHook( int nSeverity, string pchDebugText );
|
||||||
|
|
||||||
@ -206,28 +114,6 @@ public bool Valid
|
|||||||
get { return native != null; }
|
get { return native != null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Action InstallCallback<T>( Action<T> action )
|
|
||||||
{
|
|
||||||
// var del = Marshal.GetFunctionPointerForDelegate( action );
|
|
||||||
|
|
||||||
// var ptr = Marshal.GetFunctionPointerForDelegate( action );
|
|
||||||
// Valve.Steamworks.SteamAPI.RegisterCallback( del, type );
|
|
||||||
|
|
||||||
// Valve.Steamworks.SteamAPI.UnregisterCallback( del );
|
|
||||||
|
|
||||||
//return () => Valve.Steamworks.SteamAPI.UnregisterCallback( ptr );
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<IDisposable> Disposables = new List<IDisposable>();
|
|
||||||
|
|
||||||
internal void CallResult<T>( Action<T> Callback, int id )
|
|
||||||
{
|
|
||||||
var callback = new Facepunch.Steamworks.Interop.Callback<T>( true, id, Callback );
|
|
||||||
Disposables.Add( callback );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the current MaxPlayers.
|
/// Gets or sets the current MaxPlayers.
|
||||||
/// This doesn't enforce any kind of limit, it just updates the master server.
|
/// This doesn't enforce any kind of limit, it just updates the master server.
|
||||||
|
@ -55,7 +55,7 @@ internal ServerAuth( Server s )
|
|||||||
{
|
{
|
||||||
server = s;
|
server = s;
|
||||||
|
|
||||||
server.CallResult<ValidateAuthTicketResponse>( OnAuthTicketValidate, ValidateAuthTicketResponse.CallbackId );
|
server.AddCallback<ValidateAuthTicketResponse>( OnAuthTicketValidate, ValidateAuthTicketResponse.CallbackId );
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnAuthTicketValidate( ValidateAuthTicketResponse data )
|
void OnAuthTicketValidate( ValidateAuthTicketResponse data )
|
||||||
|
@ -43,12 +43,12 @@ public struct StatsReceived
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Refresh( ulong steamid )
|
public void Refresh( ulong steamid )
|
||||||
{
|
{
|
||||||
var handle = server.native.stats.RequestUserStats( steamid );
|
var handle = server.native.gameServerStats.RequestUserStats( steamid );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Commit( ulong steamid )
|
public void Commit( ulong steamid )
|
||||||
{
|
{
|
||||||
server.native.stats.StoreUserStats( steamid );
|
server.native.gameServerStats.StoreUserStats( steamid );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -56,7 +56,7 @@ public void Commit( ulong steamid )
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Set( ulong steamid, string name, int stat )
|
public bool Set( ulong steamid, string name, int stat )
|
||||||
{
|
{
|
||||||
return server.native.stats.SetUserStat( steamid, name, stat );
|
return server.native.gameServerStats.SetUserStat( steamid, name, stat );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -64,7 +64,7 @@ public bool Set( ulong steamid, string name, int stat )
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Set( ulong steamid, string name, float stat )
|
public bool Set( ulong steamid, string name, float stat )
|
||||||
{
|
{
|
||||||
return server.native.stats.SetUserStat0( steamid, name, stat );
|
return server.native.gameServerStats.SetUserStat0( steamid, name, stat );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -74,7 +74,7 @@ public int GetInt( ulong steamid, string name, int defaultValue = 0 )
|
|||||||
{
|
{
|
||||||
int data = defaultValue;
|
int data = defaultValue;
|
||||||
|
|
||||||
if ( !server.native.stats.GetUserStat( steamid, name, ref data ) )
|
if ( !server.native.gameServerStats.GetUserStat( steamid, name, ref data ) )
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
@ -87,7 +87,7 @@ public float GetFloat( ulong steamid, string name, float defaultValue = 0 )
|
|||||||
{
|
{
|
||||||
float data = defaultValue;
|
float data = defaultValue;
|
||||||
|
|
||||||
if ( !server.native.stats.GetUserStat0( steamid, name, ref data ) )
|
if ( !server.native.gameServerStats.GetUserStat0( steamid, name, ref data ) )
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
Loading…
Reference in New Issue
Block a user