Skip to content

Latest commit

Β 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Steamworks.NET Transport for PigeonNetworking

License: MIT Unity C#

Disclaimer

This library is a work-in-progress and not battle-tested yet. Use it at your own discretion.

✨ Features

Uses SteamNetworkingSockets with Steam Datagram Relay, to bypass port forwarding and NAT issues.

Note: This library requires the core PigeonNetworking library to work.

πŸ“¦ Dependencies

If you use Facepunch Steamworks, use the Facepunch Steamworks Transport instead:


πŸš€ Getting Started

πŸ–₯️ Create a Server in Unity

   public static Server server;

    private bool SteamInit = false;
    private void StartServer()
    {
        SteamInit = GameServer.Init(0, 5555, 27016, EServerMode.eServerModeAuthentication, "1");
        SteamGameServerNetworkingUtils.InitRelayNetworkAccess();
        if(!SteamInit)
            CLog.Warning("Failed to init Steam game Server");
        
        SteamGameServer.SetServerName("Demo server");
        SteamGameServer.SetModDir("480");
        SteamGameServer.SetProduct("480");
        SteamGameServer.LogOnAnonymous();
        
        server = new SteamServer(); // for SDR Transport
        //server = new UdpServer(); // for UDP Transport
        server.Start(0); // use port 0 for SDR Transport
        server.OnClientConnected += OnPlayerConnected;
        server.OnClientDisconnected += OnPlayerDisconnected;
    }
    
    private void Update()
    {
        if(SteamInit)
            GameServer.RunCallbacks();
        
        server?.Tick();
    }
    
    private void OnPlayerConnected(object sender, ClientConnectedEvent connectedEvent)
    {
        Debug.Log("[Unity] Client connected");
    }
    private void OnPlayerDisconnected(object sender, ClientDisconnectedEvent connectedEvent)
    {
        Debug.Log("[Unity] Client disconnected");
    }

Note: If you want to run a server through the Steamworks Client API, use the SteamClientServer class instead. It works exactly like the SteamServer class, except that the SteamServer class uses the Steamworks GameServer API. If you use the Steam Client API, you cannot connect to yourself from the same machine, except from within the same game instance. With the GameServer API, however, this does work.

Create a Client in Unity

  private bool _steamInit = false;
    [SerializeField] private TMP_InputField _inputField;
    
    public static Client client;
    private void StartClient()
    {
        // init Steam stuff (only needed for SDR Transport)
        _steamInit = SteamAPI.Init();
        if(!_steamInit)
            Debug.LogWarning("Failed to Init Steam Client");
        SteamNetworkingUtils.InitRelayNetworkAccess();
        
        client = new SteamClient();
        //client = new UdpClientManager();
      
        client.OnConnectedToServer += OnConnectedToServer;
        client.OnDisconnectedFromServer += OnDisconnectedFromServer;
        client.OnOtherClientConnected += OnPlayerConnected;
        client.OnOtherClientDisconnected += OnPlayerDisconnected;
        client.OnConnectionRejected += OnConnectionRejectedFromServer;
        client.Start();
        Debug.Log("Client start called");
    }
    private void OnConnectionRejectedFromServer(object sender, ConnectionRejectedFromServerEvent callback)
    {
        Debug.Log($"Connection Rejected from server - Reason {callback.RejectionReason}");
    }
    private void OnConnectedToServer(object sender, ConnectedToServerEvent callback)
    {
        Debug.Log($"Connected to the Server ");
    }
    private void OnDisconnectedFromServer(object sender, DisconnectedFromServerEvent callback)
    {
        Debug.Log($"Disconnected from the Server - reason {callback.Reason}");
    }
    
    private void OnPlayerConnected(object sender, OtherClientConnectedEvent connectedEvent)
    {
        Debug.Log($"Other Player joined - Id: {connectedEvent.ClientId}");
    }
    
    private void OnPlayerDisconnected(object sender, OtherClientDisconnectedEvent connectedEvent)
    {
        Debug.Log($"Other Player left - Id: {connectedEvent.ClientId}");
    }

    public void TryConnect()
    {
        if (ulong.TryParse(_inputField.text, out ulong id))
        {
            CSteamID serverId = new CSteamID(id);
            client.Connect(new SteamSocketInfo(serverId, 0)); // connect to SDR server
        }
        else
        {
            client.Connect(new SocketInfo(_inputField.text)); // or connect UDP server
        }
    }

    public void Disconnect()
    {
        client.Disconnect();
    }

Send and Receive a message

	// send message on the server to the client
    private static void GrantPlayerAccess(ushort clientId)
    {
        Message message = Message.Create(EChannel.Reliable, (ushort)EServerToClientPacketId.GrantAccess);
        message.WriteBool(true);
        server.Send(message, clientId);
    }

	// receive message on the client
    [MessageHandler((ushort)EServerToClientPacketId.GrantAccess)]
    private static void HandleAccessGrant(Message rMessage)
    {
        bool granted = rMessage.ReadBool();
        Debug.Log("Granted access by server: "+ granted);

        Message message = Message.Create(EChannel.Unreliable, (ushort)EClientToServerPacketId.TestUnreliable1);
        message.WriteFloat(200.5f);
        message.WriteDouble(25.5d);
        message.WriteSmartString("Hello there!");
        message.WriteByte(20);
        message.WriteInt(50);
        client.Send(message);
    }

    // send message from client to server
    private static void SendStuffToServer()
    {
        Message message = Message.Create(EChannel.Unreliable, (ushort)EClientToServerPacketId.HelloServer);
        message.WriteFloat(200.5f);
        message.WriteDouble(25.5d);
        message.WriteSmartString("Unreliable Test: Big!");
        message.WriteByte(20);
        message.WriteInt(50);
        client.Send(message);
    }

    // handle message on the server
    [MessageHandler((ushort)EServerToClientPacketId.HelloServer)]
    private static void HandleAccessGrant(ushort peerId, Message message)
    {
        float f =  message.ReadFloat();
        double d = message.ReadDouble();
        string s = message.ReadSmartString();
        byte b = message.ReadByte();
        int i = message.ReadInt();
        Debug.Log($"[Unity] Received unreliable test message, data: f{f}, d{d}, s{s}, b{b}, i{i}");
    }

πŸ“„ License

This project is licensed under the MIT License.

Releases

Packages

Contributors

Languages