expressobits / steam-multiplayer-peer

Steam Sockets Multiplayer Peer for Godot 4 via GDExtension
MIT License
199 stars 13 forks source link

A C# wrapper class #20

Open brogan89 opened 4 months ago

brogan89 commented 4 months ago

I'm using GodotSteam C# bindings and saw there wasn't a C# wrapper for SteamMultiplayerPeer. Not sure if there is one already but I've made a start but its missing a lot.

Its not establishing a connection to the host though. I thought it was maybe an issue with my project, but when I checkout the demo its also not establishing a connection with the host.

using System;
using System.Collections.Generic;
using Godot;
using Array = Godot.Collections.Array;

public sealed partial class SteamMultiplayerPeer : MultiplayerPeerExtension
{
    /// <summary>
    /// Reference to the Godot class in gdscript.
    /// </summary>
    private readonly GodotObject _classReference;

    /// <summary>
    /// Cached string names for calling methods.
    /// </summary>
    private readonly Dictionary<string, StringName> _stringNames = [];

    public SteamMultiplayerPeer()
    {
        var stringName = new StringName(nameof(SteamMultiplayerPeer));

        if (!ClassDB.ClassExists(stringName))
            throw new NotSupportedException("SteamMultiplayerPeer class doesn't exist");
        if (!ClassDB.CanInstantiate(stringName))
            throw new Exception("GodotSteam cannot be instantiated.");
        _classReference = ClassDB.Instantiate(stringName).AsGodotObject();
    }

    private Variant CallMethod(string method, params Variant[] args)
    {
        // cache the string name, so it doesn't allocate memory every time
        if (!_stringNames.ContainsKey(method))
            _stringNames[method] = new StringName(method);

        return _classReference.Call(_stringNames[method], args);
    }

    public Error CreateServer(ushort port, Array options)
    {
        return CallMethod("create_host", [port, options]).As<Error>();
    }

    public Error CreateClient(ulong steamId, ushort port, Array options)
    {
        return CallMethod("create_client", [steamId, port, options]).As<Error>();
    }

    public override ConnectionStatus _GetConnectionStatus()
    {
        return CallMethod("get_connection_status").As<ConnectionStatus>();
    }

    public override int _GetUniqueId()
    {
        return CallMethod("get_unique_id").As<int>();
    }

    public override int _GetAvailablePacketCount()
    {
        return CallMethod("get_available_packet_count").As<int>();
    }

    public override void _Poll()
    {
        CallMethod("poll");
    }

    public override void _SetTransferChannel(int pChannel)
    {
        CallMethod("set_transfer_channel", [pChannel]);
    }

    public override void _SetTransferMode(TransferModeEnum pMode)
    {
        CallMethod("set_transfer_mode", [(long)pMode]);
    }
}
brogan89 commented 4 months ago

Regarding can not connect is related to issue #9

scriptsengineer commented 4 months ago

Your work is incredible! I don't have that knowledge of C# bindings to work on this, so I really appreciate the help! Are you using Mac?

brogan89 commented 4 months ago

Your work is incredible! I don't have that knowledge of C# bindings to work on this, so I really appreciate the help! Are you using Mac?

Yeah I use mac, linux, and windows. I don't know C++ though so I can't help with the mac stuff unfortunately. But I'm happy to test out of you if you need confirmation. I have a M1 Max.

brogan89 commented 4 months ago

I can also finish off the C# wrapper and make a PR if you want. It can just be an optional file people can drag n drop into their project, it doesn't need to be apart of the addon its self.