2022-01-16 17:45:43 +00:00
using Steamworks ;
using System ;
using System.IO ;
using UnityEngine ;
namespace Mirror.FizzySteam
{
2022-01-31 19:33:55 +00:00
[HelpURL("https://github.com/Chykary/FizzyFacepunch")]
public class FizzyFacepunch : Transport
{
private const string STEAM_SCHEME = "steam" ;
private static IClient client ;
private static IServer server ;
[SerializeField]
public P2PSend [ ] Channels = new P2PSend [ 2 ] { P2PSend . Reliable , P2PSend . UnreliableNoDelay } ;
[Tooltip("Timeout for connecting in seconds.")]
public int Timeout = 25 ;
[Tooltip("The Steam ID for your application.")]
public string SteamAppID = "480" ;
[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 ;
[Tooltip("Check this if you want the transport to initialise Facepunch.")]
public bool InitFacepunch = true ;
[Header("Info")]
[Tooltip("This will display your Steam User ID when you start or connect to a server.")]
public ulong SteamUserID ;
public Action < string > SetTransportError ;
private void Awake ( )
{
const string fileName = "steam_appid.txt" ;
if ( File . Exists ( fileName ) )
{
var content = File . ReadAllText ( fileName ) ;
if ( content ! = SteamAppID )
{
File . WriteAllText ( fileName , SteamAppID . ToString ( ) ) ;
Debug . Log ( $"Updating {fileName}. Previous: {content}, new SteamAppID {SteamAppID}" ) ;
}
}
else
{
File . WriteAllText ( fileName , SteamAppID . ToString ( ) ) ;
Debug . Log ( $"New {fileName} written with SteamAppID {SteamAppID}" ) ;
}
Debug . Assert ( Channels ! = null & & Channels . Length > 0 , "No channel configured for FizzySteamworks." ) ;
if ( InitFacepunch )
{
SteamClient . Init ( uint . Parse ( SteamAppID ) , true ) ;
}
Invoke ( nameof ( FetchSteamID ) , 1f ) ;
}
2022-01-16 17:45:43 +00:00
2022-01-17 21:04:02 +00:00
public override void ClientEarlyUpdate ( )
2022-01-31 19:33:55 +00:00
{
if ( enabled & & client ! = null & & ! client . Error )
{
client ? . ReceiveData ( ) ;
}
}
public override void ServerEarlyUpdate ( )
{
if ( enabled )
{
server ? . ReceiveData ( ) ;
}
}
public override void ClientLateUpdate ( )
{
if ( enabled & & client ! = null & & ! client . Error )
{
client ? . FlushData ( ) ;
}
}
public override void ServerLateUpdate ( )
{
if ( enabled )
{
server ? . FlushData ( ) ;
}
}
public override bool ClientConnected ( ) = > ClientActive ( ) & & client . Connected ;
public override void ClientConnect ( string address )
{
if ( ! SteamClient . IsValid )
{
Debug . LogError ( "SteamWorks not initialized. Client could not be started." ) ;
OnClientDisconnected . Invoke ( ) ;
return ;
}
FetchSteamID ( ) ;
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!" ) ;
}
}
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 )
{
var 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 ( )
{
if ( ! SteamClient . IsValid )
{
Debug . LogError ( "SteamWorks not initialized. Server could not be started." ) ;
return ;
}
FetchSteamID ( ) ;
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}" ) ;
SteamNetworking . AllowP2PPacketRelay ( AllowSteamRelay ) ;
server = LegacyServer . CreateServer ( this , NetworkManager . singleton . maxConnections ) ;
}
}
else
{
Debug . LogError ( "Server already started!" ) ;
}
}
public override Uri ServerUri ( )
{
var steamBuilder = new UriBuilder
{
Scheme = STEAM_SCHEME ,
Host = SteamClient . SteamId . Value . ToString ( )
} ;
return steamBuilder . Uri ;
}
public override void ServerSend ( int connectionId , ArraySegment < byte > segment , int channelId )
{
if ( ServerActive ( ) )
{
var 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 ( channelId > = Channels . Length )
{
Debug . LogError ( "Channel Id exceeded configured channels! Please configure more channels." ) ;
return 1200 ;
}
switch ( Channels [ channelId ] )
{
case P2PSend . Unreliable :
case P2PSend . UnreliableNoDelay :
return 1200 ;
case P2PSend . Reliable :
case P2PSend . ReliableWithBuffering :
return 1048576 ;
default :
throw new NotSupportedException ( ) ;
}
}
public override bool Available ( )
{
try
{
return SteamClient . IsValid ;
}
catch
{
return false ;
}
}
private void FetchSteamID ( )
{
if ( SteamClient . IsValid )
{
if ( UseNextGenSteamNetworking )
{
SteamNetworkingUtils . InitRelayNetworkAccess ( ) ;
}
SteamUserID = SteamClient . SteamId ;
}
}
private void OnDestroy ( ) = > Shutdown ( ) ;
}
2022-01-16 17:45:43 +00:00
}