mirror of
https://github.com/Facepunch/Facepunch.Steamworks.git
synced 2025-02-03 17:20:45 +03:00
GameServer baseline
This commit is contained in:
parent
90d9ae8c4c
commit
3255135df1
@ -196,7 +196,7 @@ namespace Facepunch.Steamworks.Test
|
||||
|
||||
Assert.IsNotNull( client.Inventory.SerializedItems );
|
||||
Assert.IsTrue( client.Inventory.SerializedItems.Length > 4 );
|
||||
|
||||
/*
|
||||
using ( var server = new Facepunch.Steamworks.Server( 252490, new ServerInit( "rust", "Rust" ) ) )
|
||||
{
|
||||
server.LogOnAnonymous();
|
||||
@ -223,6 +223,7 @@ namespace Facepunch.Steamworks.Test
|
||||
Console.WriteLine( "Item: {0} ({1})", item.Id, item.DefinitionId );
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
/*
|
||||
namespace Facepunch.Steamworks.Test
|
||||
{
|
||||
[DeploymentItem( "steam_api64.dll" )]
|
||||
@ -148,3 +148,4 @@ namespace Facepunch.Steamworks.Test
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
@ -2,7 +2,7 @@
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
/*
|
||||
namespace Facepunch.Steamworks.Test
|
||||
{
|
||||
public partial class Server
|
||||
@ -40,3 +40,4 @@ namespace Facepunch.Steamworks.Test
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
@ -30,12 +30,6 @@
|
||||
<Compile Remove="*AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Server.cs">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="steam_api64.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
|
@ -9,6 +9,10 @@ namespace Steamworks.Internal
|
||||
{
|
||||
public class ISteamApps : BaseSteamInterface
|
||||
{
|
||||
public ISteamApps( bool server = false ) : base( server )
|
||||
{
|
||||
}
|
||||
|
||||
public override string InterfaceName => "STEAMAPPS_INTERFACE_VERSION008";
|
||||
|
||||
public override void InitInternals()
|
||||
|
@ -9,6 +9,10 @@ namespace Steamworks.Internal
|
||||
{
|
||||
public class ISteamFriends : BaseSteamInterface
|
||||
{
|
||||
public ISteamFriends( bool server = false ) : base( server )
|
||||
{
|
||||
}
|
||||
|
||||
public override string InterfaceName => "SteamFriends017";
|
||||
|
||||
public override void InitInternals()
|
||||
|
563
Facepunch.Steamworks/Generated/Interfaces/ISteamGameServer.cs
Normal file
563
Facepunch.Steamworks/Generated/Interfaces/ISteamGameServer.cs
Normal file
@ -0,0 +1,563 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SteamNative;
|
||||
|
||||
|
||||
namespace Steamworks.Internal
|
||||
{
|
||||
public class ISteamGameServer : BaseSteamInterface
|
||||
{
|
||||
public ISteamGameServer( bool server = false ) : base( server )
|
||||
{
|
||||
}
|
||||
|
||||
public override string InterfaceName => "SteamGameServer012";
|
||||
|
||||
public override void InitInternals()
|
||||
{
|
||||
InitGameServerDelegatePointer = Marshal.GetDelegateForFunctionPointer<InitGameServerDelegate>( Marshal.ReadIntPtr( VTable, 0) );
|
||||
SetProductDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetProductDelegate>( Marshal.ReadIntPtr( VTable, 8) );
|
||||
SetGameDescriptionDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetGameDescriptionDelegate>( Marshal.ReadIntPtr( VTable, 16) );
|
||||
SetModDirDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetModDirDelegate>( Marshal.ReadIntPtr( VTable, 24) );
|
||||
SetDedicatedServerDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetDedicatedServerDelegate>( Marshal.ReadIntPtr( VTable, 32) );
|
||||
LogOnDelegatePointer = Marshal.GetDelegateForFunctionPointer<LogOnDelegate>( Marshal.ReadIntPtr( VTable, 40) );
|
||||
LogOnAnonymousDelegatePointer = Marshal.GetDelegateForFunctionPointer<LogOnAnonymousDelegate>( Marshal.ReadIntPtr( VTable, 48) );
|
||||
LogOffDelegatePointer = Marshal.GetDelegateForFunctionPointer<LogOffDelegate>( Marshal.ReadIntPtr( VTable, 56) );
|
||||
BLoggedOnDelegatePointer = Marshal.GetDelegateForFunctionPointer<BLoggedOnDelegate>( Marshal.ReadIntPtr( VTable, 64) );
|
||||
BSecureDelegatePointer = Marshal.GetDelegateForFunctionPointer<BSecureDelegate>( Marshal.ReadIntPtr( VTable, 72) );
|
||||
GetSteamIDDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetSteamIDDelegate>( Marshal.ReadIntPtr( VTable, 80) );
|
||||
WasRestartRequestedDelegatePointer = Marshal.GetDelegateForFunctionPointer<WasRestartRequestedDelegate>( Marshal.ReadIntPtr( VTable, 88) );
|
||||
SetMaxPlayerCountDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetMaxPlayerCountDelegate>( Marshal.ReadIntPtr( VTable, 96) );
|
||||
SetBotPlayerCountDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetBotPlayerCountDelegate>( Marshal.ReadIntPtr( VTable, 104) );
|
||||
SetServerNameDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetServerNameDelegate>( Marshal.ReadIntPtr( VTable, 112) );
|
||||
SetMapNameDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetMapNameDelegate>( Marshal.ReadIntPtr( VTable, 120) );
|
||||
SetPasswordProtectedDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetPasswordProtectedDelegate>( Marshal.ReadIntPtr( VTable, 128) );
|
||||
SetSpectatorPortDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetSpectatorPortDelegate>( Marshal.ReadIntPtr( VTable, 136) );
|
||||
SetSpectatorServerNameDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetSpectatorServerNameDelegate>( Marshal.ReadIntPtr( VTable, 144) );
|
||||
ClearAllKeyValuesDelegatePointer = Marshal.GetDelegateForFunctionPointer<ClearAllKeyValuesDelegate>( Marshal.ReadIntPtr( VTable, 152) );
|
||||
SetKeyValueDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetKeyValueDelegate>( Marshal.ReadIntPtr( VTable, 160) );
|
||||
SetGameTagsDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetGameTagsDelegate>( Marshal.ReadIntPtr( VTable, 168) );
|
||||
SetGameDataDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetGameDataDelegate>( Marshal.ReadIntPtr( VTable, 176) );
|
||||
SetRegionDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetRegionDelegate>( Marshal.ReadIntPtr( VTable, 184) );
|
||||
SendUserConnectAndAuthenticateDelegatePointer = Marshal.GetDelegateForFunctionPointer<SendUserConnectAndAuthenticateDelegate>( Marshal.ReadIntPtr( VTable, 192) );
|
||||
CreateUnauthenticatedUserConnectionDelegatePointer = Marshal.GetDelegateForFunctionPointer<CreateUnauthenticatedUserConnectionDelegate>( Marshal.ReadIntPtr( VTable, 200) );
|
||||
SendUserDisconnectDelegatePointer = Marshal.GetDelegateForFunctionPointer<SendUserDisconnectDelegate>( Marshal.ReadIntPtr( VTable, 208) );
|
||||
BUpdateUserDataDelegatePointer = Marshal.GetDelegateForFunctionPointer<BUpdateUserDataDelegate>( Marshal.ReadIntPtr( VTable, 216) );
|
||||
GetAuthSessionTicketDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetAuthSessionTicketDelegate>( Marshal.ReadIntPtr( VTable, 224) );
|
||||
BeginAuthSessionDelegatePointer = Marshal.GetDelegateForFunctionPointer<BeginAuthSessionDelegate>( Marshal.ReadIntPtr( VTable, 232) );
|
||||
EndAuthSessionDelegatePointer = Marshal.GetDelegateForFunctionPointer<EndAuthSessionDelegate>( Marshal.ReadIntPtr( VTable, 240) );
|
||||
CancelAuthTicketDelegatePointer = Marshal.GetDelegateForFunctionPointer<CancelAuthTicketDelegate>( Marshal.ReadIntPtr( VTable, 248) );
|
||||
UserHasLicenseForAppDelegatePointer = Marshal.GetDelegateForFunctionPointer<UserHasLicenseForAppDelegate>( Marshal.ReadIntPtr( VTable, 256) );
|
||||
RequestUserGroupStatusDelegatePointer = Marshal.GetDelegateForFunctionPointer<RequestUserGroupStatusDelegate>( Marshal.ReadIntPtr( VTable, 264) );
|
||||
GetGameplayStatsDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetGameplayStatsDelegate>( Marshal.ReadIntPtr( VTable, 272) );
|
||||
GetServerReputationDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetServerReputationDelegate>( Marshal.ReadIntPtr( VTable, 280) );
|
||||
GetPublicIPDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetPublicIPDelegate>( Marshal.ReadIntPtr( VTable, 288) );
|
||||
HandleIncomingPacketDelegatePointer = Marshal.GetDelegateForFunctionPointer<HandleIncomingPacketDelegate>( Marshal.ReadIntPtr( VTable, 296) );
|
||||
GetNextOutgoingPacketDelegatePointer = Marshal.GetDelegateForFunctionPointer<GetNextOutgoingPacketDelegate>( Marshal.ReadIntPtr( VTable, 304) );
|
||||
EnableHeartbeatsDelegatePointer = Marshal.GetDelegateForFunctionPointer<EnableHeartbeatsDelegate>( Marshal.ReadIntPtr( VTable, 312) );
|
||||
SetHeartbeatIntervalDelegatePointer = Marshal.GetDelegateForFunctionPointer<SetHeartbeatIntervalDelegate>( Marshal.ReadIntPtr( VTable, 320) );
|
||||
ForceHeartbeatDelegatePointer = Marshal.GetDelegateForFunctionPointer<ForceHeartbeatDelegate>( Marshal.ReadIntPtr( VTable, 328) );
|
||||
AssociateWithClanDelegatePointer = Marshal.GetDelegateForFunctionPointer<AssociateWithClanDelegate>( Marshal.ReadIntPtr( VTable, 336) );
|
||||
ComputeNewPlayerCompatibilityDelegatePointer = Marshal.GetDelegateForFunctionPointer<ComputeNewPlayerCompatibilityDelegate>( Marshal.ReadIntPtr( VTable, 344) );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
[return: MarshalAs( UnmanagedType.I1 )]
|
||||
public delegate bool InitGameServerDelegate( IntPtr self, uint unIP, ushort usGamePort, ushort usQueryPort, uint unFlags, AppId_t nGameAppId, string pchVersionString );
|
||||
private InitGameServerDelegate InitGameServerDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public bool InitGameServer( uint unIP, ushort usGamePort, ushort usQueryPort, uint unFlags, AppId_t nGameAppId, string pchVersionString )
|
||||
{
|
||||
return InitGameServerDelegatePointer( Self, unIP, usGamePort, usQueryPort, unFlags, nGameAppId, pchVersionString );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetProductDelegate( IntPtr self, string pszProduct );
|
||||
private SetProductDelegate SetProductDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetProduct( string pszProduct )
|
||||
{
|
||||
SetProductDelegatePointer( Self, pszProduct );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetGameDescriptionDelegate( IntPtr self, string pszGameDescription );
|
||||
private SetGameDescriptionDelegate SetGameDescriptionDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetGameDescription( string pszGameDescription )
|
||||
{
|
||||
SetGameDescriptionDelegatePointer( Self, pszGameDescription );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetModDirDelegate( IntPtr self, string pszModDir );
|
||||
private SetModDirDelegate SetModDirDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetModDir( string pszModDir )
|
||||
{
|
||||
SetModDirDelegatePointer( Self, pszModDir );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetDedicatedServerDelegate( IntPtr self, [MarshalAs( UnmanagedType.U1 )] bool bDedicated );
|
||||
private SetDedicatedServerDelegate SetDedicatedServerDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetDedicatedServer( [MarshalAs( UnmanagedType.U1 )] bool bDedicated )
|
||||
{
|
||||
SetDedicatedServerDelegatePointer( Self, bDedicated );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void LogOnDelegate( IntPtr self, string pszToken );
|
||||
private LogOnDelegate LogOnDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void LogOn( string pszToken )
|
||||
{
|
||||
LogOnDelegatePointer( Self, pszToken );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void LogOnAnonymousDelegate( IntPtr self );
|
||||
private LogOnAnonymousDelegate LogOnAnonymousDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void LogOnAnonymous()
|
||||
{
|
||||
LogOnAnonymousDelegatePointer( Self );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void LogOffDelegate( IntPtr self );
|
||||
private LogOffDelegate LogOffDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void LogOff()
|
||||
{
|
||||
LogOffDelegatePointer( Self );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
[return: MarshalAs( UnmanagedType.I1 )]
|
||||
public delegate bool BLoggedOnDelegate( IntPtr self );
|
||||
private BLoggedOnDelegate BLoggedOnDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public bool BLoggedOn()
|
||||
{
|
||||
return BLoggedOnDelegatePointer( Self );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
[return: MarshalAs( UnmanagedType.I1 )]
|
||||
public delegate bool BSecureDelegate( IntPtr self );
|
||||
private BSecureDelegate BSecureDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public bool BSecure()
|
||||
{
|
||||
return BSecureDelegatePointer( Self );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void GetSteamIDDelegate( IntPtr self, ref CSteamID retVal );
|
||||
private GetSteamIDDelegate GetSteamIDDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public CSteamID GetSteamID()
|
||||
{
|
||||
var retVal = default( CSteamID );
|
||||
GetSteamIDDelegatePointer( Self, ref retVal );
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
[return: MarshalAs( UnmanagedType.I1 )]
|
||||
public delegate bool WasRestartRequestedDelegate( IntPtr self );
|
||||
private WasRestartRequestedDelegate WasRestartRequestedDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public bool WasRestartRequested()
|
||||
{
|
||||
return WasRestartRequestedDelegatePointer( Self );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetMaxPlayerCountDelegate( IntPtr self, int cPlayersMax );
|
||||
private SetMaxPlayerCountDelegate SetMaxPlayerCountDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetMaxPlayerCount( int cPlayersMax )
|
||||
{
|
||||
SetMaxPlayerCountDelegatePointer( Self, cPlayersMax );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetBotPlayerCountDelegate( IntPtr self, int cBotplayers );
|
||||
private SetBotPlayerCountDelegate SetBotPlayerCountDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetBotPlayerCount( int cBotplayers )
|
||||
{
|
||||
SetBotPlayerCountDelegatePointer( Self, cBotplayers );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetServerNameDelegate( IntPtr self, string pszServerName );
|
||||
private SetServerNameDelegate SetServerNameDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetServerName( string pszServerName )
|
||||
{
|
||||
SetServerNameDelegatePointer( Self, pszServerName );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetMapNameDelegate( IntPtr self, string pszMapName );
|
||||
private SetMapNameDelegate SetMapNameDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetMapName( string pszMapName )
|
||||
{
|
||||
SetMapNameDelegatePointer( Self, pszMapName );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetPasswordProtectedDelegate( IntPtr self, [MarshalAs( UnmanagedType.U1 )] bool bPasswordProtected );
|
||||
private SetPasswordProtectedDelegate SetPasswordProtectedDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetPasswordProtected( [MarshalAs( UnmanagedType.U1 )] bool bPasswordProtected )
|
||||
{
|
||||
SetPasswordProtectedDelegatePointer( Self, bPasswordProtected );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetSpectatorPortDelegate( IntPtr self, ushort unSpectatorPort );
|
||||
private SetSpectatorPortDelegate SetSpectatorPortDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetSpectatorPort( ushort unSpectatorPort )
|
||||
{
|
||||
SetSpectatorPortDelegatePointer( Self, unSpectatorPort );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetSpectatorServerNameDelegate( IntPtr self, string pszSpectatorServerName );
|
||||
private SetSpectatorServerNameDelegate SetSpectatorServerNameDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetSpectatorServerName( string pszSpectatorServerName )
|
||||
{
|
||||
SetSpectatorServerNameDelegatePointer( Self, pszSpectatorServerName );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void ClearAllKeyValuesDelegate( IntPtr self );
|
||||
private ClearAllKeyValuesDelegate ClearAllKeyValuesDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void ClearAllKeyValues()
|
||||
{
|
||||
ClearAllKeyValuesDelegatePointer( Self );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetKeyValueDelegate( IntPtr self, string pKey, string pValue );
|
||||
private SetKeyValueDelegate SetKeyValueDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetKeyValue( string pKey, string pValue )
|
||||
{
|
||||
SetKeyValueDelegatePointer( Self, pKey, pValue );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetGameTagsDelegate( IntPtr self, string pchGameTags );
|
||||
private SetGameTagsDelegate SetGameTagsDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetGameTags( string pchGameTags )
|
||||
{
|
||||
SetGameTagsDelegatePointer( Self, pchGameTags );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetGameDataDelegate( IntPtr self, string pchGameData );
|
||||
private SetGameDataDelegate SetGameDataDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetGameData( string pchGameData )
|
||||
{
|
||||
SetGameDataDelegatePointer( Self, pchGameData );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetRegionDelegate( IntPtr self, string pszRegion );
|
||||
private SetRegionDelegate SetRegionDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetRegion( string pszRegion )
|
||||
{
|
||||
SetRegionDelegatePointer( Self, pszRegion );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
[return: MarshalAs( UnmanagedType.I1 )]
|
||||
public delegate bool SendUserConnectAndAuthenticateDelegate( IntPtr self, uint unIPClient, IntPtr pvAuthBlob, uint cubAuthBlobSize, ref CSteamID pSteamIDUser );
|
||||
private SendUserConnectAndAuthenticateDelegate SendUserConnectAndAuthenticateDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public bool SendUserConnectAndAuthenticate( uint unIPClient, IntPtr pvAuthBlob, uint cubAuthBlobSize, ref CSteamID pSteamIDUser )
|
||||
{
|
||||
return SendUserConnectAndAuthenticateDelegatePointer( Self, unIPClient, pvAuthBlob, cubAuthBlobSize, ref pSteamIDUser );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void CreateUnauthenticatedUserConnectionDelegate( IntPtr self, ref CSteamID retVal );
|
||||
private CreateUnauthenticatedUserConnectionDelegate CreateUnauthenticatedUserConnectionDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public CSteamID CreateUnauthenticatedUserConnection()
|
||||
{
|
||||
var retVal = default( CSteamID );
|
||||
CreateUnauthenticatedUserConnectionDelegatePointer( Self, ref retVal );
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SendUserDisconnectDelegate( IntPtr self, CSteamID steamIDUser );
|
||||
private SendUserDisconnectDelegate SendUserDisconnectDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SendUserDisconnect( CSteamID steamIDUser )
|
||||
{
|
||||
SendUserDisconnectDelegatePointer( Self, steamIDUser );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
[return: MarshalAs( UnmanagedType.I1 )]
|
||||
public delegate bool BUpdateUserDataDelegate( IntPtr self, CSteamID steamIDUser, string pchPlayerName, uint uScore );
|
||||
private BUpdateUserDataDelegate BUpdateUserDataDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public bool BUpdateUserData( CSteamID steamIDUser, string pchPlayerName, uint uScore )
|
||||
{
|
||||
return BUpdateUserDataDelegatePointer( Self, steamIDUser, pchPlayerName, uScore );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate HAuthTicket GetAuthSessionTicketDelegate( IntPtr self, IntPtr pTicket, int cbMaxTicket, ref uint pcbTicket );
|
||||
private GetAuthSessionTicketDelegate GetAuthSessionTicketDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public HAuthTicket GetAuthSessionTicket( IntPtr pTicket, int cbMaxTicket, ref uint pcbTicket )
|
||||
{
|
||||
return GetAuthSessionTicketDelegatePointer( Self, pTicket, cbMaxTicket, ref pcbTicket );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate BeginAuthSessionResult BeginAuthSessionDelegate( IntPtr self, IntPtr pAuthTicket, int cbAuthTicket, CSteamID steamID );
|
||||
private BeginAuthSessionDelegate BeginAuthSessionDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public BeginAuthSessionResult BeginAuthSession( IntPtr pAuthTicket, int cbAuthTicket, CSteamID steamID )
|
||||
{
|
||||
return BeginAuthSessionDelegatePointer( Self, pAuthTicket, cbAuthTicket, steamID );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void EndAuthSessionDelegate( IntPtr self, CSteamID steamID );
|
||||
private EndAuthSessionDelegate EndAuthSessionDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void EndAuthSession( CSteamID steamID )
|
||||
{
|
||||
EndAuthSessionDelegatePointer( Self, steamID );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void CancelAuthTicketDelegate( IntPtr self, HAuthTicket hAuthTicket );
|
||||
private CancelAuthTicketDelegate CancelAuthTicketDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void CancelAuthTicket( HAuthTicket hAuthTicket )
|
||||
{
|
||||
CancelAuthTicketDelegatePointer( Self, hAuthTicket );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate UserHasLicenseForAppResult UserHasLicenseForAppDelegate( IntPtr self, CSteamID steamID, AppId_t appID );
|
||||
private UserHasLicenseForAppDelegate UserHasLicenseForAppDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public UserHasLicenseForAppResult UserHasLicenseForApp( CSteamID steamID, AppId_t appID )
|
||||
{
|
||||
return UserHasLicenseForAppDelegatePointer( Self, steamID, appID );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
[return: MarshalAs( UnmanagedType.I1 )]
|
||||
public delegate bool RequestUserGroupStatusDelegate( IntPtr self, CSteamID steamIDUser, CSteamID steamIDGroup );
|
||||
private RequestUserGroupStatusDelegate RequestUserGroupStatusDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public bool RequestUserGroupStatus( CSteamID steamIDUser, CSteamID steamIDGroup )
|
||||
{
|
||||
return RequestUserGroupStatusDelegatePointer( Self, steamIDUser, steamIDGroup );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void GetGameplayStatsDelegate( IntPtr self );
|
||||
private GetGameplayStatsDelegate GetGameplayStatsDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void GetGameplayStats()
|
||||
{
|
||||
GetGameplayStatsDelegatePointer( Self );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate SteamAPICall_t GetServerReputationDelegate( IntPtr self );
|
||||
private GetServerReputationDelegate GetServerReputationDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public async Task<GSReputation_t?> GetServerReputation()
|
||||
{
|
||||
return await (new Result<GSReputation_t>( GetServerReputationDelegatePointer( Self ) )).GetResult();
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate uint GetPublicIPDelegate( IntPtr self );
|
||||
private GetPublicIPDelegate GetPublicIPDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public uint GetPublicIP()
|
||||
{
|
||||
return GetPublicIPDelegatePointer( Self );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
[return: MarshalAs( UnmanagedType.I1 )]
|
||||
public delegate bool HandleIncomingPacketDelegate( IntPtr self, IntPtr pData, int cbData, uint srcIP, ushort srcPort );
|
||||
private HandleIncomingPacketDelegate HandleIncomingPacketDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public bool HandleIncomingPacket( IntPtr pData, int cbData, uint srcIP, ushort srcPort )
|
||||
{
|
||||
return HandleIncomingPacketDelegatePointer( Self, pData, cbData, srcIP, srcPort );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate int GetNextOutgoingPacketDelegate( IntPtr self, IntPtr pOut, int cbMaxOut, ref uint pNetAdr, ref ushort pPort );
|
||||
private GetNextOutgoingPacketDelegate GetNextOutgoingPacketDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public int GetNextOutgoingPacket( IntPtr pOut, int cbMaxOut, ref uint pNetAdr, ref ushort pPort )
|
||||
{
|
||||
return GetNextOutgoingPacketDelegatePointer( Self, pOut, cbMaxOut, ref pNetAdr, ref pPort );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void EnableHeartbeatsDelegate( IntPtr self, [MarshalAs( UnmanagedType.U1 )] bool bActive );
|
||||
private EnableHeartbeatsDelegate EnableHeartbeatsDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void EnableHeartbeats( [MarshalAs( UnmanagedType.U1 )] bool bActive )
|
||||
{
|
||||
EnableHeartbeatsDelegatePointer( Self, bActive );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void SetHeartbeatIntervalDelegate( IntPtr self, int iHeartbeatInterval );
|
||||
private SetHeartbeatIntervalDelegate SetHeartbeatIntervalDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void SetHeartbeatInterval( int iHeartbeatInterval )
|
||||
{
|
||||
SetHeartbeatIntervalDelegatePointer( Self, iHeartbeatInterval );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate void ForceHeartbeatDelegate( IntPtr self );
|
||||
private ForceHeartbeatDelegate ForceHeartbeatDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public void ForceHeartbeat()
|
||||
{
|
||||
ForceHeartbeatDelegatePointer( Self );
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate SteamAPICall_t AssociateWithClanDelegate( IntPtr self, CSteamID steamIDClan );
|
||||
private AssociateWithClanDelegate AssociateWithClanDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public async Task<AssociateWithClanResult_t?> AssociateWithClan( CSteamID steamIDClan )
|
||||
{
|
||||
return await (new Result<AssociateWithClanResult_t>( AssociateWithClanDelegatePointer( Self, steamIDClan ) )).GetResult();
|
||||
}
|
||||
|
||||
#region FunctionMeta
|
||||
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||
public delegate SteamAPICall_t ComputeNewPlayerCompatibilityDelegate( IntPtr self, CSteamID steamIDNewPlayer );
|
||||
private ComputeNewPlayerCompatibilityDelegate ComputeNewPlayerCompatibilityDelegatePointer;
|
||||
|
||||
#endregion
|
||||
public async Task<ComputeNewPlayerCompatibilityResult_t?> ComputeNewPlayerCompatibility( CSteamID steamIDNewPlayer )
|
||||
{
|
||||
return await (new Result<ComputeNewPlayerCompatibilityResult_t>( ComputeNewPlayerCompatibilityDelegatePointer( Self, steamIDNewPlayer ) )).GetResult();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -9,6 +9,10 @@ namespace Steamworks.Internal
|
||||
{
|
||||
public class ISteamMatchmakingServers : BaseSteamInterface
|
||||
{
|
||||
public ISteamMatchmakingServers( bool server = false ) : base( server )
|
||||
{
|
||||
}
|
||||
|
||||
public override string InterfaceName => "SteamMatchMakingServers002";
|
||||
|
||||
public override void InitInternals()
|
||||
|
@ -9,6 +9,10 @@ namespace Steamworks.Internal
|
||||
{
|
||||
public class ISteamMusic : BaseSteamInterface
|
||||
{
|
||||
public ISteamMusic( bool server = false ) : base( server )
|
||||
{
|
||||
}
|
||||
|
||||
public override string InterfaceName => "STEAMMUSIC_INTERFACE_VERSION001";
|
||||
|
||||
public override void InitInternals()
|
||||
|
@ -9,6 +9,10 @@ namespace Steamworks.Internal
|
||||
{
|
||||
public class ISteamParentalSettings : BaseSteamInterface
|
||||
{
|
||||
public ISteamParentalSettings( bool server = false ) : base( server )
|
||||
{
|
||||
}
|
||||
|
||||
public override string InterfaceName => "STEAMPARENTALSETTINGS_INTERFACE_VERSION001";
|
||||
|
||||
public override void InitInternals()
|
||||
|
@ -9,6 +9,10 @@ namespace Steamworks.Internal
|
||||
{
|
||||
public class ISteamUser : BaseSteamInterface
|
||||
{
|
||||
public ISteamUser( bool server = false ) : base( server )
|
||||
{
|
||||
}
|
||||
|
||||
public override string InterfaceName => "SteamUser020";
|
||||
|
||||
public override void InitInternals()
|
||||
|
@ -9,6 +9,10 @@ namespace Steamworks.Internal
|
||||
{
|
||||
public class ISteamUtils : BaseSteamInterface
|
||||
{
|
||||
public ISteamUtils( bool server = false ) : base( server )
|
||||
{
|
||||
}
|
||||
|
||||
public override string InterfaceName => "SteamUtils009";
|
||||
|
||||
public override void InitInternals()
|
||||
|
@ -9,6 +9,10 @@ namespace Steamworks.Internal
|
||||
{
|
||||
public class ISteamVideo : BaseSteamInterface
|
||||
{
|
||||
public ISteamVideo( bool server = false ) : base( server )
|
||||
{
|
||||
}
|
||||
|
||||
public override string InterfaceName => "STEAMVIDEO_INTERFACE_V002";
|
||||
|
||||
public override void InitInternals()
|
||||
|
@ -13,6 +13,9 @@ public static class SteamApi
|
||||
[DllImport( "Steam_api64", EntryPoint = "SteamAPI_GetHSteamUser", CallingConvention = CallingConvention.Cdecl )]
|
||||
public static extern int GetHSteamUser();
|
||||
|
||||
[DllImport( "Steam_api64", EntryPoint = "SteamGameServer_GetHSteamUser", CallingConvention = CallingConvention.Cdecl )]
|
||||
public static extern int SteamGameServer_GetHSteamUser();
|
||||
|
||||
[DllImport( "Steam_api64", EntryPoint = "SteamAPI_RunCallbacks", CallingConvention = CallingConvention.Cdecl )]
|
||||
public static extern int RunCallbacks();
|
||||
|
||||
|
@ -8,4 +8,8 @@ public static class SteamInternal
|
||||
{
|
||||
[DllImport( "Steam_api64", EntryPoint = "SteamInternal_FindOrCreateUserInterface", CallingConvention = CallingConvention.Cdecl )]
|
||||
public static extern IntPtr FindOrCreateUserInterface( int hSteamUser, [MarshalAs( UnmanagedType.LPStr )] string pszVersion );
|
||||
|
||||
|
||||
[DllImport( "Steam_api64", EntryPoint = "SteamInternal_FindOrCreateGameServerInterface", CallingConvention = CallingConvention.Cdecl )]
|
||||
public static extern IntPtr FindOrCreateGameServerInterface( int hSteamUser, [MarshalAs( UnmanagedType.LPStr )] string pszVersion );
|
||||
}
|
||||
|
@ -31,9 +31,6 @@ namespace Facepunch.Steamworks.Interop
|
||||
|
||||
internal bool InitClient( BaseSteamworks steamworks )
|
||||
{
|
||||
if ( Steamworks.Server.Instance != null )
|
||||
throw new System.Exception("Steam client should be initialized before steam server - or there's big trouble.");
|
||||
|
||||
isServer = false;
|
||||
|
||||
api = new SteamNative.SteamApi();
|
||||
|
334
Facepunch.Steamworks/Redux/GameServer.cs
Normal file
334
Facepunch.Steamworks/Redux/GameServer.cs
Normal file
@ -0,0 +1,334 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Facepunch.Steamworks;
|
||||
using SteamNative;
|
||||
|
||||
namespace Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides the core of the Steam Game Servers API
|
||||
/// </summary>
|
||||
public static partial class GameServer
|
||||
{
|
||||
static Internal.ISteamGameServer _internal;
|
||||
internal static Internal.ISteamGameServer Internal
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( _internal == null )
|
||||
_internal = new Internal.ISteamGameServer( true );
|
||||
|
||||
return _internal;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void InstallEvents()
|
||||
{
|
||||
new Event<ValidateAuthTicketResponse_t>( x => OnValidateAuthTicketResponse?.Invoke( x.SteamID, x.OwnerSteamID, x.AuthSessionResponse ), true );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// User has been authed or rejected
|
||||
/// </summary>
|
||||
public static event Action<CSteamID, CSteamID, AuthSessionResponse> OnValidateAuthTicketResponse;
|
||||
|
||||
public static bool Init( AppId appid, ServerInit init )
|
||||
{
|
||||
uint ipaddress = 0; // Any Port
|
||||
|
||||
if ( init.SteamPort == 0 )
|
||||
init = init.WithRandomSteamPort();
|
||||
|
||||
if ( init.IpAddress != null )
|
||||
ipaddress = Utility.IpToInt32( init.IpAddress );
|
||||
|
||||
//
|
||||
// Get other interfaces
|
||||
//
|
||||
if ( !Internal.InitGameServer( ipaddress, init.GamePort, init.QueryPort, (uint)( init.Secure ? 3 : 2 ), appid.Value, init.VersionString ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Initial settings
|
||||
//
|
||||
Internal.EnableHeartbeats( true );
|
||||
MaxPlayers = 32;
|
||||
BotCount = 0;
|
||||
Product = $"{appid.Value}";
|
||||
ModDir = init.ModDir;
|
||||
GameDescription = init.GameDescription;
|
||||
Passworded = false;
|
||||
DedicatedServer = true;
|
||||
|
||||
|
||||
InstallEvents();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets whether this should be marked as a dedicated server.
|
||||
/// If not, it is assumed to be a listen server.
|
||||
/// </summary>
|
||||
public static bool DedicatedServer
|
||||
{
|
||||
get => _dedicatedServer;
|
||||
set { if ( _dedicatedServer == value ) return; Internal.SetDedicatedServer( value ); _dedicatedServer = value; }
|
||||
}
|
||||
private static bool _dedicatedServer;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current MaxPlayers.
|
||||
/// This doesn't enforce any kind of limit, it just updates the master server.
|
||||
/// </summary>
|
||||
public static int MaxPlayers
|
||||
{
|
||||
get => _maxplayers;
|
||||
set { if ( _maxplayers == value ) return; Internal.SetMaxPlayerCount( value ); _maxplayers = value; }
|
||||
}
|
||||
private static int _maxplayers = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current BotCount.
|
||||
/// This doesn't enforce any kind of limit, it just updates the master server.
|
||||
/// </summary>
|
||||
public static int BotCount
|
||||
{
|
||||
get => _botcount;
|
||||
set { if ( _botcount == value ) return; Internal.SetBotPlayerCount( value ); _botcount = value; }
|
||||
}
|
||||
private static int _botcount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current Map Name.
|
||||
/// </summary>
|
||||
public static string MapName
|
||||
{
|
||||
get => _mapname;
|
||||
set { if ( _mapname == value ) return; Internal.SetMapName( value ); _mapname = value; }
|
||||
}
|
||||
private static string _mapname;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current ModDir
|
||||
/// </summary>
|
||||
public static string ModDir
|
||||
{
|
||||
get => _modDir;
|
||||
internal set { if ( _modDir == value ) return; Internal.SetModDir( value ); _modDir = value; }
|
||||
}
|
||||
private static string _modDir = "";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current product
|
||||
/// </summary>
|
||||
public static string Product
|
||||
{
|
||||
get => _product;
|
||||
internal set { if ( _product == value ) return; Internal.SetProduct( value ); _product = value; }
|
||||
}
|
||||
private static string _product = "";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current Product
|
||||
/// </summary>
|
||||
public static string GameDescription
|
||||
{
|
||||
get => _gameDescription;
|
||||
internal set { if ( _gameDescription == value ) return; Internal.SetGameDescription( value ); _gameDescription = value; }
|
||||
}
|
||||
private static string _gameDescription = "";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current ServerName
|
||||
/// </summary>
|
||||
public static string ServerName
|
||||
{
|
||||
get => _serverName;
|
||||
set { if ( _serverName == value ) return; Internal.SetServerName( value ); _serverName = value; }
|
||||
}
|
||||
private static string _serverName = "";
|
||||
|
||||
/// <summary>
|
||||
/// Set whether the server should report itself as passworded
|
||||
/// </summary>
|
||||
public static bool Passworded
|
||||
{
|
||||
get => _passworded;
|
||||
set { if ( _passworded == value ) return; Internal.SetPasswordProtected( value ); _passworded = value; }
|
||||
}
|
||||
private static bool _passworded;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current GameTags. This is a comma seperated list of tags for this server.
|
||||
/// When querying the server list you can filter by these tags.
|
||||
/// </summary>
|
||||
public static string GameTags
|
||||
{
|
||||
get => _gametags;
|
||||
set { if ( _gametags == value ) return; Internal.SetGameTags( value ); _gametags = value; }
|
||||
}
|
||||
private static string _gametags = "";
|
||||
|
||||
/// <summary>
|
||||
/// Log onto Steam anonymously.
|
||||
/// </summary>
|
||||
public static void LogOnAnonymous()
|
||||
{
|
||||
Internal.LogOnAnonymous();
|
||||
ForceHeartbeat();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the server is connected and registered with the Steam master server
|
||||
/// You should have called LogOnAnonymous etc on startup.
|
||||
/// </summary>
|
||||
public static bool LoggedOn => Internal.BLoggedOn();
|
||||
|
||||
/// <summary>
|
||||
/// To the best of its ability this tries to get the server's
|
||||
/// current public ip address. Be aware that this is likely to return
|
||||
/// null for the first few seconds after initialization.
|
||||
/// </summary>
|
||||
public static System.Net.IPAddress PublicIp
|
||||
{
|
||||
get
|
||||
{
|
||||
var ip = Internal.GetPublicIP();
|
||||
if ( ip == 0 ) return null;
|
||||
|
||||
return Utility.Int32ToIp( ip );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable or disable heartbeats, which are sent regularly to the master server.
|
||||
/// Enabled by default.
|
||||
/// </summary>
|
||||
public static bool AutomaticHeartbeats
|
||||
{
|
||||
set { Internal.EnableHeartbeats( value ); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set heartbeat interval, if automatic heartbeats are enabled.
|
||||
/// You can leave this at the default.
|
||||
/// </summary>
|
||||
public static int AutomaticHeartbeatRate
|
||||
{
|
||||
set { Internal.SetHeartbeatInterval( value ); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Force send a heartbeat to the master server instead of waiting
|
||||
/// for the next automatic update (if you've left them enabled)
|
||||
/// </summary>
|
||||
public static void ForceHeartbeat()
|
||||
{
|
||||
Internal.ForceHeartbeat();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update this connected player's information. You should really call this
|
||||
/// any time a player's name or score changes. This keeps the information shown
|
||||
/// to server queries up to date.
|
||||
/// </summary>
|
||||
public static void UpdatePlayer( ulong steamid, string name, int score )
|
||||
{
|
||||
Internal.BUpdateUserData( steamid, name, (uint)score );
|
||||
}
|
||||
|
||||
static Dictionary<string, string> KeyValue = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Sets a Key Value. These can be anything you like, and are accessible
|
||||
/// when querying servers from the server list.
|
||||
///
|
||||
/// Information describing gamemodes are common here.
|
||||
/// </summary>
|
||||
public static void SetKey( string Key, string Value )
|
||||
{
|
||||
if ( KeyValue.ContainsKey( Key ) )
|
||||
{
|
||||
if ( KeyValue[Key] == Value )
|
||||
return;
|
||||
|
||||
KeyValue[Key] = Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyValue.Add( Key, Value );
|
||||
}
|
||||
|
||||
Internal.SetKeyValue( Key, Value );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start authorizing a ticket. This user isn't authorized yet. Wait for a call to OnAuthChange.
|
||||
/// </summary>
|
||||
public static unsafe bool BeginAuthSession( byte[] data, ulong steamid )
|
||||
{
|
||||
fixed ( byte* p = data )
|
||||
{
|
||||
var result = Internal.BeginAuthSession( (IntPtr)p, data.Length, steamid );
|
||||
|
||||
if ( result == SteamNative.BeginAuthSessionResult.OK )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forget this guy. They're no longer in the game.
|
||||
/// </summary>
|
||||
public static void EndSession( ulong steamid )
|
||||
{
|
||||
Internal.EndAuthSession( steamid );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If true, Steam wants to send a packet. You should respond by sending
|
||||
/// this packet in an unconnected way to the returned Address and Port.
|
||||
/// </summary>
|
||||
/// <param name="packet">Packet to send. The Data passed is pooled - so use it immediately.</param>
|
||||
/// <returns>True if we want to send a packet</returns>
|
||||
public static unsafe bool GetOutgoingPacket( out OutgoingPacket packet )
|
||||
{
|
||||
var buffer = Helpers.TakeBuffer( 1024 * 32 );
|
||||
packet = new OutgoingPacket();
|
||||
|
||||
fixed ( byte* ptr = buffer )
|
||||
{
|
||||
uint addr = 0;
|
||||
ushort port = 0;
|
||||
|
||||
var size = Internal.GetNextOutgoingPacket( (IntPtr)ptr, buffer.Length, ref addr, ref port );
|
||||
if ( size == 0 )
|
||||
return false;
|
||||
|
||||
packet.Size = size;
|
||||
packet.Data = buffer;
|
||||
packet.Address = addr;
|
||||
packet.Port = port;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We have received a server query on our game port. Pass it to Steam to handle.
|
||||
/// </summary>
|
||||
public static unsafe void HandleIncomingPacket( byte[] data, int size, uint address, ushort port )
|
||||
{
|
||||
fixed ( byte* ptr = data )
|
||||
{
|
||||
Internal.HandleIncomingPacket( (IntPtr)ptr, size, address, port );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
Facepunch.Steamworks/Redux/Structs/OutgoingPacket.cs
Normal file
30
Facepunch.Steamworks/Redux/Structs/OutgoingPacket.cs
Normal file
@ -0,0 +1,30 @@
|
||||
namespace Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// A server query packet.
|
||||
/// </summary>
|
||||
public struct OutgoingPacket
|
||||
{
|
||||
/// <summary>
|
||||
/// Target IP address
|
||||
/// </summary>
|
||||
public uint Address { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Target port
|
||||
/// </summary>
|
||||
public ushort Port { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// This data is pooled. Make a copy if you don't use it immediately.
|
||||
/// This buffer is also quite large - so pay attention to Size.
|
||||
/// </summary>
|
||||
public byte[] Data { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Size of the data
|
||||
/// </summary>
|
||||
public int Size { get; internal set; }
|
||||
}
|
||||
|
||||
}
|
@ -5,48 +5,56 @@ using System.Net;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
namespace Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to set up the server.
|
||||
/// The variables in here are all required to be set, and can't be changed once the server is created.
|
||||
/// </summary>
|
||||
public class ServerInit
|
||||
public struct ServerInit
|
||||
{
|
||||
public IPAddress IpAddress;
|
||||
public ushort SteamPort;
|
||||
public ushort GamePort = 27015;
|
||||
public ushort QueryPort = 27016;
|
||||
public bool Secure = true;
|
||||
public ushort GamePort;
|
||||
public ushort QueryPort;
|
||||
public bool Secure;
|
||||
|
||||
/// <summary>
|
||||
/// The version string is usually in the form x.x.x.x, and is used by the master server to detect when the server is out of date.
|
||||
/// If you go into the dedicated server tab on steamworks you'll be able to server the latest version. If this version number is
|
||||
/// less than that latest version then your server won't show.
|
||||
/// </summary>
|
||||
public string VersionString = "2.0.0.0";
|
||||
public string VersionString;
|
||||
|
||||
/// <summary>
|
||||
/// This should be the same directory game where gets installed into. Just the folder name, not the whole path. I.e. "Rust", "Garrysmod".
|
||||
/// </summary>
|
||||
public string ModDir = "unset";
|
||||
/// <summary>
|
||||
/// This should be the same directory game where gets installed into. Just the folder name, not the whole path. I.e. "Rust", "Garrysmod".
|
||||
/// </summary>
|
||||
public string ModDir;
|
||||
|
||||
/// <summary>
|
||||
/// The game description. Setting this to the full name of your game is recommended.
|
||||
/// </summary>
|
||||
public string GameDescription = "unset";
|
||||
public string GameDescription;
|
||||
|
||||
|
||||
public ServerInit( string modDir, string gameDesc )
|
||||
{
|
||||
ModDir = modDir;
|
||||
GameDescription = gameDesc;
|
||||
}
|
||||
GamePort = 27015;
|
||||
QueryPort = 27016;
|
||||
Secure = true;
|
||||
VersionString = "1.0.0.0";
|
||||
ModDir = "unset";
|
||||
GameDescription = "unset";
|
||||
IpAddress = null;
|
||||
SteamPort = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the Steam quert port
|
||||
/// </summary>
|
||||
public ServerInit RandomSteamPort()
|
||||
public ServerInit WithRandomSteamPort()
|
||||
{
|
||||
SteamPort = (ushort)new Random().Next( 10000, 60000 );
|
||||
return this;
|
||||
@ -59,7 +67,7 @@ namespace Facepunch.Steamworks
|
||||
///
|
||||
/// More info about this here: https://partner.steamgames.com/doc/api/ISteamGameServer#HandleIncomingPacket
|
||||
/// </summary>
|
||||
public ServerInit QueryShareGamePort()
|
||||
public ServerInit WithQueryShareGamePort()
|
||||
{
|
||||
QueryPort = 0xFFFF;
|
||||
return this;
|
@ -1,338 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialize this class for Game Servers.
|
||||
///
|
||||
/// Game servers offer a limited amount of Steam functionality - and don't require the Steam client.
|
||||
/// </summary>
|
||||
public partial class Server : BaseSteamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// A singleton accessor to get the current client instance.
|
||||
/// </summary>
|
||||
public static Server Instance { get; private set; }
|
||||
|
||||
internal override bool IsGameServer { get { return true; } }
|
||||
|
||||
public ServerQuery Query { get; internal set; }
|
||||
public ServerStats Stats { get; internal set; }
|
||||
public ServerAuth Auth { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a Steam Server instance
|
||||
/// </summary>
|
||||
public Server( uint appId, ServerInit init) : base( appId )
|
||||
{
|
||||
if ( Instance != null )
|
||||
{
|
||||
throw new System.Exception( "Only one Facepunch.Steamworks.Server can exist - dispose the old one before trying to create a new one." );
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
native = new Interop.NativeInterface();
|
||||
uint ipaddress = 0; // Any Port
|
||||
|
||||
if ( init.SteamPort == 0 ) init.RandomSteamPort();
|
||||
if ( init.IpAddress != null ) ipaddress = Utility.IpToInt32( init.IpAddress );
|
||||
|
||||
//
|
||||
// Get other interfaces
|
||||
//
|
||||
if ( !native.InitServer( this, ipaddress, init.SteamPort, init.GamePort, init.QueryPort, init.Secure ? 3 : 2, init.VersionString ) )
|
||||
{
|
||||
native.Dispose();
|
||||
native = null;
|
||||
Instance = null;
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Register Callbacks
|
||||
//
|
||||
|
||||
SteamNative.Callbacks.RegisterCallbacks( this );
|
||||
|
||||
//
|
||||
// Setup interfaces that client and server both have
|
||||
//
|
||||
SetupCommonInterfaces();
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Initial settings
|
||||
//
|
||||
native.gameServer.EnableHeartbeats( true );
|
||||
MaxPlayers = 32;
|
||||
BotCount = 0;
|
||||
Product = $"{AppId}";
|
||||
ModDir = init.ModDir;
|
||||
GameDescription = init.GameDescription;
|
||||
Passworded = false;
|
||||
DedicatedServer = true;
|
||||
|
||||
//
|
||||
// Child classes
|
||||
//
|
||||
Query = new ServerQuery( this );
|
||||
Stats = new ServerStats( this );
|
||||
Auth = new ServerAuth( this );
|
||||
|
||||
//
|
||||
// Run update, first call does some initialization
|
||||
//
|
||||
Update();
|
||||
}
|
||||
|
||||
~Server()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Should be called at least once every frame
|
||||
/// </summary>
|
||||
public override void Update()
|
||||
{
|
||||
if ( !IsValid )
|
||||
return;
|
||||
|
||||
native.api.SteamGameServer_RunCallbacks();
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets whether this should be marked as a dedicated server.
|
||||
/// If not, it is assumed to be a listen server.
|
||||
/// </summary>
|
||||
public bool DedicatedServer
|
||||
{
|
||||
get { return _dedicatedServer; }
|
||||
set { if ( _dedicatedServer == value ) return; native.gameServer.SetDedicatedServer( value ); _dedicatedServer = value; }
|
||||
}
|
||||
private bool _dedicatedServer;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current MaxPlayers.
|
||||
/// This doesn't enforce any kind of limit, it just updates the master server.
|
||||
/// </summary>
|
||||
public int MaxPlayers
|
||||
{
|
||||
get { return _maxplayers; }
|
||||
set { if ( _maxplayers == value ) return; native.gameServer.SetMaxPlayerCount( value ); _maxplayers = value; }
|
||||
}
|
||||
private int _maxplayers = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current BotCount.
|
||||
/// This doesn't enforce any kind of limit, it just updates the master server.
|
||||
/// </summary>
|
||||
public int BotCount
|
||||
{
|
||||
get { return _botcount; }
|
||||
set { if ( _botcount == value ) return; native.gameServer.SetBotPlayerCount( value ); _botcount = value; }
|
||||
}
|
||||
private int _botcount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current Map Name.
|
||||
/// </summary>
|
||||
public string MapName
|
||||
{
|
||||
get { return _mapname; }
|
||||
set { if ( _mapname == value ) return; native.gameServer.SetMapName( value ); _mapname = value; }
|
||||
}
|
||||
private string _mapname;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current ModDir
|
||||
/// </summary>
|
||||
public string ModDir
|
||||
{
|
||||
get { return _modDir; }
|
||||
internal set { if ( _modDir == value ) return; native.gameServer.SetModDir( value ); _modDir = value; }
|
||||
}
|
||||
private string _modDir = "";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current product
|
||||
/// </summary>
|
||||
public string Product
|
||||
{
|
||||
get { return _product; }
|
||||
internal set { if ( _product == value ) return; native.gameServer.SetProduct( value ); _product = value; }
|
||||
}
|
||||
private string _product = "";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current Product
|
||||
/// </summary>
|
||||
public string GameDescription
|
||||
{
|
||||
get { return _gameDescription; }
|
||||
internal set { if ( _gameDescription == value ) return; native.gameServer.SetGameDescription( value ); _gameDescription = value; }
|
||||
}
|
||||
private string _gameDescription = "";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current ServerName
|
||||
/// </summary>
|
||||
public string ServerName
|
||||
{
|
||||
get { return _serverName; }
|
||||
set { if ( _serverName == value ) return; native.gameServer.SetServerName( value ); _serverName = value; }
|
||||
}
|
||||
private string _serverName = "";
|
||||
|
||||
/// <summary>
|
||||
/// Set whether the server should report itself as passworded
|
||||
/// </summary>
|
||||
public bool Passworded
|
||||
{
|
||||
get { return _passworded; }
|
||||
set { if ( _passworded == value ) return; native.gameServer.SetPasswordProtected( value ); _passworded = value; }
|
||||
}
|
||||
private bool _passworded;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current GameTags. This is a comma seperated list of tags for this server.
|
||||
/// When querying the server list you can filter by these tags.
|
||||
/// </summary>
|
||||
public string GameTags
|
||||
{
|
||||
get { return _gametags; }
|
||||
set { if ( _gametags == value ) return; native.gameServer.SetGameTags( value ); _gametags = value; }
|
||||
}
|
||||
private string _gametags = "";
|
||||
|
||||
/// <summary>
|
||||
/// Log onto Steam anonymously.
|
||||
/// </summary>
|
||||
public void LogOnAnonymous()
|
||||
{
|
||||
native.gameServer.LogOnAnonymous();
|
||||
ForceHeartbeat();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the server is connected and registered with the Steam master server
|
||||
/// You should have called LogOnAnonymous etc on startup.
|
||||
/// </summary>
|
||||
public bool LoggedOn => native.gameServer.BLoggedOn();
|
||||
|
||||
Dictionary<string, string> KeyValue = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Sets a Key Value. These can be anything you like, and are accessible
|
||||
/// when querying servers from the server list.
|
||||
///
|
||||
/// Information describing gamemodes are common here.
|
||||
/// </summary>
|
||||
public void SetKey( string Key, string Value )
|
||||
{
|
||||
if ( KeyValue.ContainsKey( Key ) )
|
||||
{
|
||||
if ( KeyValue[Key] == Value )
|
||||
return;
|
||||
|
||||
KeyValue[Key] = Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyValue.Add( Key, Value );
|
||||
}
|
||||
|
||||
native.gameServer.SetKeyValue( Key, Value );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update this connected player's information. You should really call this
|
||||
/// any time a player's name or score changes. This keeps the information shown
|
||||
/// to server queries up to date.
|
||||
/// </summary>
|
||||
public void UpdatePlayer( ulong steamid, string name, int score )
|
||||
{
|
||||
native.gameServer.BUpdateUserData( steamid, name, (uint) score );
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Shutdown interface, disconnect from Steam
|
||||
/// </summary>
|
||||
public override void Dispose()
|
||||
{
|
||||
if ( disposed ) return;
|
||||
|
||||
if ( Query != null )
|
||||
{
|
||||
Query = null;
|
||||
}
|
||||
|
||||
if ( Stats != null )
|
||||
{
|
||||
Stats = null;
|
||||
}
|
||||
|
||||
if ( Auth != null )
|
||||
{
|
||||
Auth = null;
|
||||
}
|
||||
|
||||
if ( Instance == this )
|
||||
{
|
||||
Instance = null;
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// To the best of its ability this tries to get the server's
|
||||
/// current public ip address. Be aware that this is likely to return
|
||||
/// null for the first few seconds after initialization.
|
||||
/// </summary>
|
||||
public System.Net.IPAddress PublicIp
|
||||
{
|
||||
get
|
||||
{
|
||||
var ip = native.gameServer.GetPublicIP();
|
||||
if ( ip == 0 ) return null;
|
||||
|
||||
return Utility.Int32ToIp( ip );
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enable or disable heartbeats, which are sent regularly to the master server.
|
||||
/// Enabled by default.
|
||||
/// </summary>
|
||||
public bool AutomaticHeartbeats
|
||||
{
|
||||
set { native.gameServer.EnableHeartbeats( value ); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set heartbeat interval, if automatic heartbeats are enabled.
|
||||
/// You can leave this at the default.
|
||||
/// </summary>
|
||||
public int AutomaticHeartbeatRate
|
||||
{
|
||||
set { native.gameServer.SetHeartbeatInterval( value ); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Force send a heartbeat to the master server instead of waiting
|
||||
/// for the next automatic update (if you've left them enabled)
|
||||
/// </summary>
|
||||
public void ForceHeartbeat()
|
||||
{
|
||||
native.gameServer.ForceHeartbeat();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
public class ServerAuth
|
||||
{
|
||||
internal Server server;
|
||||
|
||||
/// <summary>
|
||||
/// Steamid, Ownerid, Status
|
||||
/// </summary>
|
||||
public Action<ulong, ulong, Status> OnAuthChange;
|
||||
|
||||
/// <summary>
|
||||
/// Steam authetication statuses
|
||||
/// </summary>
|
||||
public enum Status : int
|
||||
{
|
||||
OK = 0,
|
||||
UserNotConnectedToSteam = 1,
|
||||
NoLicenseOrExpired = 2,
|
||||
VACBanned = 3,
|
||||
LoggedInElseWhere = 4,
|
||||
VACCheckTimedOut = 5,
|
||||
AuthTicketCanceled = 6,
|
||||
AuthTicketInvalidAlreadyUsed = 7,
|
||||
AuthTicketInvalid = 8,
|
||||
PublisherIssuedBan = 9,
|
||||
}
|
||||
|
||||
internal ServerAuth( Server s )
|
||||
{
|
||||
server = s;
|
||||
|
||||
server.RegisterCallback<SteamNative.ValidateAuthTicketResponse_t>( OnAuthTicketValidate );
|
||||
}
|
||||
|
||||
void OnAuthTicketValidate( SteamNative.ValidateAuthTicketResponse_t data )
|
||||
{
|
||||
if ( OnAuthChange != null )
|
||||
OnAuthChange( data.SteamID, data.OwnerSteamID, (Status) data.AuthSessionResponse );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start authorizing a ticket. This user isn't authorized yet. Wait for a call to OnAuthChange.
|
||||
/// </summary>
|
||||
public unsafe bool StartSession( byte[] data, ulong steamid )
|
||||
{
|
||||
fixed ( byte* p = data )
|
||||
{
|
||||
var result = server.native.gameServer.BeginAuthSession( (IntPtr)p, data.Length, steamid );
|
||||
|
||||
if ( result == SteamNative.BeginAuthSessionResult.OK )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Forget this guy. They're no longer in the game.
|
||||
/// </summary>
|
||||
public void EndSession( ulong steamid )
|
||||
{
|
||||
server.native.gameServer.EndAuthSession( steamid );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
/// If you're manually processing the server queries, you should use this class.
|
||||
/// </summary>
|
||||
public class ServerQuery
|
||||
{
|
||||
internal Server server;
|
||||
internal static byte[] buffer = new byte[64*1024];
|
||||
|
||||
internal ServerQuery( Server s )
|
||||
{
|
||||
server = s;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A server query packet.
|
||||
/// </summary>
|
||||
public struct Packet
|
||||
{
|
||||
/// <summary>
|
||||
/// Target IP address
|
||||
/// </summary>
|
||||
public uint Address { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Target port
|
||||
/// </summary>
|
||||
public ushort Port { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// This data is pooled. Make a copy if you don't use it immediately.
|
||||
/// This buffer is also quite large - so pay attention to Size.
|
||||
/// </summary>
|
||||
public byte[] Data { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Size of the data
|
||||
/// </summary>
|
||||
public int Size { get; internal set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If true, Steam wants to send a packet. You should respond by sending
|
||||
/// this packet in an unconnected way to the returned Address and Port.
|
||||
/// </summary>
|
||||
/// <param name="packet">Packet to send. The Data passed is pooled - so use it immediately.</param>
|
||||
/// <returns>True if we want to send a packet</returns>
|
||||
public unsafe bool GetOutgoingPacket( out Packet packet )
|
||||
{
|
||||
packet = new Packet();
|
||||
|
||||
fixed ( byte* ptr = buffer )
|
||||
{
|
||||
uint addr = 0;
|
||||
ushort port = 0;
|
||||
|
||||
var size = server.native.gameServer.GetNextOutgoingPacket( (IntPtr)ptr, buffer.Length, out addr, out port );
|
||||
if ( size == 0 )
|
||||
return false;
|
||||
|
||||
packet.Size = size;
|
||||
packet.Data = buffer;
|
||||
packet.Address = addr;
|
||||
packet.Port = port;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We have received a server query on our game port. Pass it to Steam to handle.
|
||||
/// </summary>
|
||||
public unsafe void Handle( byte[] data, int size, uint address, ushort port )
|
||||
{
|
||||
fixed ( byte* ptr = data )
|
||||
{
|
||||
server.native.gameServer.HandleIncomingPacket( (IntPtr)ptr, size, address, port );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
#if false
|
||||
namespace Facepunch.Steamworks
|
||||
{
|
||||
/// <summary>
|
||||
@ -144,3 +145,4 @@ namespace Facepunch.Steamworks
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -326,9 +326,6 @@ namespace SteamNative
|
||||
|
||||
if ( Facepunch.Steamworks.Client.Instance != null )
|
||||
Facepunch.Steamworks.Client.Instance.OnCallback<T>( value );
|
||||
|
||||
if ( Facepunch.Steamworks.Server.Instance != null )
|
||||
Facepunch.Steamworks.Server.Instance.OnCallback<T>( value );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,14 +16,25 @@ namespace Steamworks.Internal
|
||||
|
||||
public virtual string InterfaceName => null;
|
||||
|
||||
public BaseSteamInterface()
|
||||
public BaseSteamInterface( bool server = false )
|
||||
{
|
||||
if ( Steamworks.Steam.HUser == 0 )
|
||||
var hUser = server ? SteamApi.SteamGameServer_GetHSteamUser() : SteamApi.GetHSteamUser();
|
||||
|
||||
if ( hUser == 0 )
|
||||
throw new System.Exception( "Steamworks is uninitialized" );
|
||||
|
||||
Self = SteamInternal.FindOrCreateUserInterface( Steamworks.Steam.HUser, InterfaceName );
|
||||
if ( server )
|
||||
{
|
||||
Self = SteamInternal.FindOrCreateUserInterface( hUser, InterfaceName );
|
||||
}
|
||||
else
|
||||
{
|
||||
Self = SteamInternal.FindOrCreateUserInterface( hUser, InterfaceName );
|
||||
}
|
||||
|
||||
if ( Self == IntPtr.Zero )
|
||||
throw new System.Exception( $"Couldn't find interface {InterfaceName}" );
|
||||
throw new System.Exception( $"Couldn't find interface {InterfaceName} (server:{server})" );
|
||||
|
||||
|
||||
VTable = Marshal.ReadIntPtr( Self, 0 );
|
||||
if ( Self == IntPtr.Zero )
|
||||
|
@ -27,6 +27,12 @@ namespace Generator
|
||||
{
|
||||
StartBlock( $"public class {clss.Name} : BaseSteamInterface" );
|
||||
{
|
||||
StartBlock( $"public {clss.Name}( bool server = false ) : base( server )" );
|
||||
{
|
||||
|
||||
}
|
||||
EndBlock();
|
||||
WriteLine();
|
||||
|
||||
WriteLine( $"public override string InterfaceName => \"{clss.InterfaceString}\";" );
|
||||
WriteLine();
|
||||
|
@ -100,6 +100,7 @@ namespace Generator
|
||||
GenerateVTableClass( "ISteamUser", $"{folder}../Generated/Interfaces/ISteamUser.cs" );
|
||||
GenerateVTableClass( "ISteamMatchmakingServers", $"{folder}../Generated/Interfaces/ISteamMatchmakingServers.cs" );
|
||||
GenerateVTableClass( "ISteamFriends", $"{folder}../Generated/Interfaces/ISteamFriends.cs" );
|
||||
GenerateVTableClass( "ISteamGameServer", $"{folder}../Generated/Interfaces/ISteamGameServer.cs" );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ internal class BaseType
|
||||
return new BaseType { NativeType = type, VarName = varname };
|
||||
}
|
||||
|
||||
public virtual string AsArgument() => IsVector? $"[In,Out] {Ref}{TypeName.Trim( '*', ' ' )}[] {VarName}" : $"{Ref}{TypeName.Trim( '*', ' ' )} {VarName}";
|
||||
public virtual string AsArgument() => IsVector ? $"[In,Out] {Ref}{TypeName.Trim( '*', ' ' )}[] {VarName}" : $"{Ref}{TypeName.Trim( '*', ' ' )} {VarName}";
|
||||
public virtual string AsCallArgument() => $"{Ref}{VarName}";
|
||||
|
||||
public virtual string Return( string varname ) => $"return {varname};";
|
||||
@ -49,9 +49,26 @@ internal class BaseType
|
||||
public virtual string ReturnType => TypeName;
|
||||
|
||||
public virtual string Ref => !IsVector && NativeType.EndsWith( "*" ) || NativeType.EndsWith( "**" ) ? "ref " : "";
|
||||
public virtual bool IsVector => (NativeType.EndsWith( "*" ) && (VarName.StartsWith( "pvec" ) || VarName.StartsWith( "pub" ) || VarName.StartsWith( "pOut" )))
|
||||
|| NativeType.EndsWith( "**" )
|
||||
|| VarName == "psteamIDClans";
|
||||
public virtual bool IsVector
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( VarName == "pOut" ) return false;
|
||||
|
||||
if ( VarName == "psteamIDClans" ) return true;
|
||||
if ( NativeType.EndsWith( "**" ) ) return true;
|
||||
|
||||
if ( NativeType.EndsWith( "*" ) )
|
||||
{
|
||||
if ( VarName.StartsWith( "pvec" ) ) return true;
|
||||
if ( VarName.StartsWith( "pub" ) ) return true;
|
||||
if ( VarName.StartsWith( "pOut" ) ) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual bool IsVoid => false;
|
||||
public virtual bool IsReturnedWeird => false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user