2023-06-10 01:23:40 +00:00
#if ! DISABLESTEAMWORKS
using Steamworks ;
2023-06-09 22:57:11 +00:00
using System ;
2023-06-10 01:23:40 +00:00
using System.IO ;
2023-06-09 22:57:11 +00:00
using UnityEngine ;
2023-06-10 01:23:40 +00:00
namespace Mirror.FizzySteam
2023-06-09 22:57:11 +00:00
{
2023-06-10 01:23:40 +00:00
[HelpURL("https://github.com/Chykary/FizzySteamworks")]
public class FizzySteamworks : Transport
{
private const string STEAM_SCHEME = "steam" ;
private static IClient client ;
private static IServer server ;
[SerializeField]
public EP2PSend [ ] Channels = new EP2PSend [ 2 ] { EP2PSend . k_EP2PSendReliable , EP2PSend . k_EP2PSendUnreliableNoDelay } ;
[Tooltip("Timeout for connecting in seconds.")]
public int Timeout = 25 ;
[Tooltip("Allow or disallow P2P connections to fall back to being relayed through the Steam servers if a direct connection or NAT-traversal cannot be established.")]
public bool AllowSteamRelay = true ;
[Tooltip("Use SteamSockets instead of the (deprecated) SteamNetworking. This will always use Relay.")]
public bool UseNextGenSteamNetworking = true ;
private void OnEnable ( )
{
Debug . Assert ( Channels ! = null & & Channels . Length > 0 , "No channel configured for FizzySteamworks." ) ;
Invoke ( nameof ( InitRelayNetworkAccess ) , 1f ) ;
}
public override void ClientEarlyUpdate ( )
{
if ( enabled )
{
client ? . ReceiveData ( ) ;
}
}
public override void ServerEarlyUpdate ( )
{
if ( enabled )
{
server ? . ReceiveData ( ) ;
}
}
public override void ClientLateUpdate ( )
{
if ( enabled )
{
client ? . FlushData ( ) ;
}
}
public override void ServerLateUpdate ( )
{
if ( enabled )
{
server ? . FlushData ( ) ;
}
}
public override bool ClientConnected ( ) = > ClientActive ( ) & & client . Connected ;
public override void ClientConnect ( string address )
{
try
{
#if UNITY_SERVER
SteamGameServerNetworkingUtils . InitRelayNetworkAccess ( ) ;
#else
SteamNetworkingUtils . InitRelayNetworkAccess ( ) ;
#endif
InitRelayNetworkAccess ( ) ;
if ( ServerActive ( ) )
{
Debug . LogError ( "Transport already running as server!" ) ;
return ;
}
if ( ! ClientActive ( ) | | client . Error )
{
if ( UseNextGenSteamNetworking )
{
Debug . Log ( $"Starting client [SteamSockets], target address {address}." ) ;
client = NextClient . CreateClient ( this , address ) ;
}
else
{
Debug . Log ( $"Starting client [DEPRECATED SteamNetworking], target address {address}. Relay enabled: {AllowSteamRelay}" ) ;
SteamNetworking . AllowP2PPacketRelay ( AllowSteamRelay ) ;
client = LegacyClient . CreateClient ( this , address ) ;
}
}
else
{
Debug . LogError ( "Client already running!" ) ;
}
}
catch ( Exception ex )
{
Debug . LogError ( "Exception: " + ex . Message + ". Client could not be started." ) ;
OnClientDisconnected . Invoke ( ) ;
}
}
public override void ClientConnect ( Uri uri )
{
if ( uri . Scheme ! = STEAM_SCHEME )
throw new ArgumentException ( $"Invalid url {uri}, use {STEAM_SCHEME}://SteamID instead" , nameof ( uri ) ) ;
ClientConnect ( uri . Host ) ;
}
public override void ClientSend ( ArraySegment < byte > segment , int channelId )
{
byte [ ] data = new byte [ segment . Count ] ;
Array . Copy ( segment . Array , segment . Offset , data , 0 , segment . Count ) ;
client . Send ( data , channelId ) ;
}
public override void ClientDisconnect ( )
{
if ( ClientActive ( ) )
{
Shutdown ( ) ;
}
}
public bool ClientActive ( ) = > client ! = null ;
public override bool ServerActive ( ) = > server ! = null ;
public override void ServerStart ( )
{
try
{
#if UNITY_SERVER
SteamGameServerNetworkingUtils . InitRelayNetworkAccess ( ) ;
#else
SteamNetworkingUtils . InitRelayNetworkAccess ( ) ;
#endif
InitRelayNetworkAccess ( ) ;
if ( ClientActive ( ) )
{
Debug . LogError ( "Transport already running as client!" ) ;
return ;
}
if ( ! ServerActive ( ) )
{
if ( UseNextGenSteamNetworking )
{
Debug . Log ( $"Starting server [SteamSockets]." ) ;
server = NextServer . CreateServer ( this , NetworkManager . singleton . maxConnections ) ;
}
else
{
Debug . Log ( $"Starting server [DEPRECATED SteamNetworking]. Relay enabled: {AllowSteamRelay}" ) ;
#if UNITY_SERVER
SteamGameServerNetworking . AllowP2PPacketRelay ( AllowSteamRelay ) ;
#else
SteamNetworking . AllowP2PPacketRelay ( AllowSteamRelay ) ;
#endif
server = LegacyServer . CreateServer ( this , NetworkManager . singleton . maxConnections ) ;
}
}
else
{
Debug . LogError ( "Server already started!" ) ;
}
}
catch ( Exception ex )
{
Debug . LogException ( ex ) ;
return ;
}
}
public override Uri ServerUri ( )
{
var steamBuilder = new UriBuilder
{
Scheme = STEAM_SCHEME ,
#if UNITY_SERVER
Host = SteamGameServer . GetSteamID ( ) . m_SteamID . ToString ( )
#else
Host = SteamUser . GetSteamID ( ) . m_SteamID . ToString ( )
#endif
} ;
return steamBuilder . Uri ;
}
public override void ServerSend ( int connectionId , ArraySegment < byte > segment , int channelId )
{
if ( ServerActive ( ) )
{
byte [ ] data = new byte [ segment . Count ] ;
Array . Copy ( segment . Array , segment . Offset , data , 0 , segment . Count ) ;
server . Send ( connectionId , data , channelId ) ;
}
}
public override void ServerDisconnect ( int connectionId )
{
if ( ServerActive ( ) )
{
server . Disconnect ( connectionId ) ;
}
}
public override string ServerGetClientAddress ( int connectionId ) = > ServerActive ( ) ? server . ServerGetClientAddress ( connectionId ) : string . Empty ;
public override void ServerStop ( )
{
if ( ServerActive ( ) )
{
Shutdown ( ) ;
}
}
public override void Shutdown ( )
{
if ( server ! = null )
{
server . Shutdown ( ) ;
server = null ;
Debug . Log ( "Transport shut down - was server." ) ;
}
if ( client ! = null )
{
client . Disconnect ( ) ;
client = null ;
Debug . Log ( "Transport shut down - was client." ) ;
}
}
public override int GetMaxPacketSize ( int channelId )
{
if ( UseNextGenSteamNetworking )
{
return Constants . k_cbMaxSteamNetworkingSocketsMessageSizeSend ;
}
else
{
if ( channelId > = Channels . Length )
{
Debug . LogError ( "Channel Id exceeded configured channels! Please configure more channels." ) ;
return 1200 ;
}
switch ( Channels [ channelId ] )
{
case EP2PSend . k_EP2PSendUnreliable :
case EP2PSend . k_EP2PSendUnreliableNoDelay :
return 1200 ;
case EP2PSend . k_EP2PSendReliable :
case EP2PSend . k_EP2PSendReliableWithBuffering :
return 1048576 ;
default :
throw new NotSupportedException ( ) ;
}
}
}
public override bool Available ( )
{
try
{
#if UNITY_SERVER
SteamGameServerNetworkingUtils . InitRelayNetworkAccess ( ) ;
#else
SteamNetworkingUtils . InitRelayNetworkAccess ( ) ;
#endif
return true ;
}
catch
{
return false ;
}
}
private void InitRelayNetworkAccess ( )
{
try
{
if ( UseNextGenSteamNetworking )
{
#if UNITY_SERVER
SteamGameServerNetworkingUtils . InitRelayNetworkAccess ( ) ;
#else
SteamNetworkingUtils . InitRelayNetworkAccess ( ) ;
#endif
}
}
catch { }
}
private void OnDestroy ( )
{
Shutdown ( ) ;
}
}
2023-06-09 22:57:11 +00:00
}
2023-06-10 01:23:40 +00:00
#endif // !DISABLESTEAMWORKS