MIT License

项目介绍

Facepunch/Facepunch.Steamworks 是一个托管在 GitHub 上的开源项目,主要使用 C# 编写,采用 MIT License 许可证,目前获得 3.8k 个 Star、444 次 Fork。

仓库全名
Facepunch/Facepunch.Steamworks
开源许可证
MIT License
Star 数
3.8k
Fork 数
444
未关闭 Issue
217

README 摘要

Facepunch.Steamworks Another fucking c# Steamworks implementation Features Feature | Supported | Windows | ✔ | Linux | ✔ | MacOS | ✔ | Unity Support | ✔ | Unity IL2CPP Support | ✔ | Async Callbacks (steam callresults) | ✔ | Events (steam callbacks) | ✔ | Single C# dll (no native requirements apart from Steam) | ✔ | Open Source | ✔ | MIT license | ✔ | Any 32bit OS | ✔ | Why The Steamworks C# implementations I found…

完整内容见 GitHub 原始 README 或本页 。

常见问题

Facepunch.Steamworks 用什么语言开发?

主要使用 C# 编写,采用 MIT License 许可证,目前有 3.8k 个 Star。

Facepunch.Steamworks 可以免费商用吗?

仓库采用 MIT License 许可证,可免费使用与修改,商业使用请遵守许可证条款(例如保留版权声明与许可声明)。

如何获取 Facepunch.Steamworks 的源码?

可以直接克隆仓库:git clone https://github.com/Facepunch/Facepunch.Steamworks.git,默认分支为 master;安装与运行步骤见仓库 README。

Facepunch.Steamworks 最近还在维护吗?

仓库最近一次更新为 3 周前,当前有 217 个未关闭 Issue;Star 数为 3.8k,可作为社区活跃度的参考。

关于

GitHub 原始描述(英文)

Another fucking c# Steamworks implementation

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

简要分析

热度分
4749
价值分
2401
活跃状态
活跃

语言占比

Batchfile
C
C#
C++

Release

README

Facepunch.Steamworks

Another fucking c# Steamworks implementation

Build All

Features

Feature Supported
Windows ✔
Linux ✔
MacOS ✔
Unity Support ✔
Unity IL2CPP Support ✔
Async Callbacks (steam callresults) ✔
Events (steam callbacks) ✔
Single C# dll (no native requirements apart from Steam) ✔
Open Source ✔
MIT license ✔
Any 32bit OS ✔

Why

The Steamworks C# implementations I found that were compatible with Unity have worked for a long time. But I hate them all. For a number of different reasons.

  • They’re not C#, they’re just a collection of functions.
  • They’re not up to date.
  • They require a 3rd party native dll.
  • They can’t be compiled into a standalone dll (in Unity).
  • They’re not free
  • They have a restrictive license.

C# is meant to make things easier. So lets try to wrap it up in a way that makes it all easier.

What

Get your own information

    SteamClient.SteamId // Your SteamId
    SteamClient.Name // Your Name

View your friends list

foreach ( var friend in SteamFriends.GetFriends() )
{
    Console.WriteLine( $"{friend.Id}: {friend.Name}" );
    Console.WriteLine( $"{friend.IsOnline} / {friend.SteamLevel}" );
    
    friend.SendMessage( "Hello Friend" );
}

App Info

    Console.WriteLine( SteamApps.GameLanguage ); // Print the current game language
    var installDir = SteamApps.AppInstallDir( 4000 ); // Get the path to the Garry's Mod install folder

    var fileinfo = await SteamApps.GetFileDetailsAsync( "hl2.exe" ); // async get file details
    DoSomething( fileinfo.SizeInBytes, fileinfo.Sha1 );

Get Avatars

    var image = await SteamFriends.GetLargeAvatarAsync( steamid );
    if ( !image.HasValue ) return DefaultImage;

    return MakeTextureFromRGBA( image.Value.Data, image.Value.Width, image.Value.Height );

Get a list of servers

using ( var list = new ServerList.Internet() )
{
    list.AddFilter( "map", "de_dust" );
    await list.RunQueryAsync();

    foreach ( var server in list.Responsive )
    {
        Console.WriteLine( $"{server.Address} {server.Name}" );
    }
}

Achievements

List them

    foreach ( var a in SteamUserStats.Achievements )
    {
        Console.WriteLine( $"{a.Name} ({a.State})" );
    }	

Unlock them

    var ach = new Achievement( "GM_PLAYED_WITH_GARRY" );
    ach.Trigger();

Voice

    SteamUser.VoiceRecord = KeyDown( "V" );

    if ( SteamUser.HasVoiceData )
    {
        var bytesrwritten = SteamUser.ReadVoiceData( stream );
        // Send Stream Data To Server or Something
    }

Auth

    // Client sends ticket data to server somehow
    var ticket = SteamUser.GetAuthSessionTicket();

    // server listens to event
    SteamServer.OnValidateAuthTicketResponse += ( steamid, ownerid, rsponse ) =>
    {
        if ( rsponse == AuthResponse.OK )
            TellUserTheyCanBeOnServer( steamid );
        else
            KickUser( steamid );
    };

    // server gets ticket data from client, calls this function.. which either returns
    // false straight away, or will issue a TicketResponse.
    if ( !SteamServer.BeginAuthSession( ticketData, clientSteamId ) )
    {
        KickUser( clientSteamId );
    }

    //
    // Client is leaving, cancels their ticket OnValidateAuth is called on the server again
    // this time with AuthResponse.AuthTicketCanceled
    //
    ticket.Cancel();

Utils

    SteamUtils.SecondsSinceAppActive;
    SteamUtils.SecondsSinceComputerActive;
    SteamUtils.IpCountry;
    SteamUtils.UsingBatteryPower;
    SteamUtils.CurrentBatteryPower;
    SteamUtils.AppId;
    SteamUtils.IsOverlayEnabled;
    SteamUtils.IsSteamRunningInVR;
    SteamUtils.IsSteamInBigPictureMode;

Workshop

Download a workshop item by ID

    SteamUGC.Download( 1717844711 );

Get a workshop item information

    var itemInfo = await Ugc.Item.Get( 1720164672 );

    Console.WriteLine( $"Title: {itemInfo?.Title}" );
    Console.WriteLine( $"IsInstalled: {itemInfo?.IsInstalled}" );
    Console.WriteLine( $"IsDownloading: {itemInfo?.IsDownloading}" );
    Console.WriteLine( $"IsDownloadPending: {itemInfo?.IsDownloadPending}" );
    Console.WriteLine( $"IsSubscribed: {itemInfo?.IsSubscribed}" );
    Console.WriteLine( $"NeedsUpdate: {itemInfo?.NeedsUpdate}" );
    Console.WriteLine( $"Description: {itemInfo?.Description}" );

Query a list of workshop items

    var q = Ugc.Query.All
                    .WithTag( "Fun" )
                    .WithTag( "Movie" )
                    .MatchAllTags();

    var result = await q.GetPageAsync( 1 );

    Console.WriteLine( $"ResultCount: {result?.ResultCount}" );
    Console.WriteLine( $"TotalCount: {result?.TotalCount}" );

    foreach ( Ugc.Item entry in result.Value.Entries )
    {
        Console.WriteLine( $"{entry.Title}" );
    }

Query items created by friends

    var q = Ugc.UserQuery.All
                        .CreatedByFriends();

Query items created by yourself

    var q = Ugc.UserQuery.All
                        .FromSelf();

Publish your own file

    var result = await Ugc.Editor.NewCommunityFile
                      .WithTitle( "My New FIle" )
                      .WithDescription( "This is a description" )
                      .WithContent( "c:/folder/addon/location" )
                      .WithTag( "awesome" )
                      .WithTag( "small" )
                      .SubmitAsync( iProgressBar );

Steam Cloud

Write a cloud file

    SteamRemoteStorage.FileWrite( "file.txt", fileContents );

Read a cloud file

    var fileContents = SteamRemoteStorage.FileRead( "file.txt" );

List all files

    foreach ( var file in SteamRemoteStorage.Files )
    {
        Console.WriteLine( $"{file} ({SteamRemoteStorage.FileSize(file)} {SteamRemoteStorage.FileTime( file )})" );
    }

Steam Inventory

Get item definitions

    foreach ( InventoryDef def in SteamInventory.Definitions )
    {
        Console.WriteLine( $"{def.Name}" );
    }

Get items that are for sale in the item shop

    var defs = await SteamInventory.GetDefinitionsWithPricesAsync();

    foreach ( var def in defs )
    {
        Console.WriteLine( $"{def.Name} [{def.LocalPriceFormatted}]" );
    }

Get a list of your items

    var result = await SteamInventory.GetItems();

    // result is disposable, good manners to dispose after use
    using ( result )
    {
        var items = result?.GetItems( bWithProperties );

        foreach ( InventoryItem item in items )
        {
            Console.WriteLine( $"{item.Id} / {item.Quantity} / {item.Def.Name} " );
        }
    }

Getting Started

Client

To initialize a client you can do this.

using Steamworks;

// ...

try 
{
    SteamClient.Init( 4000 );
}
catch ( System.Exception e )
{
    // Couldn't init for some reason (steam is closed etc)
}

Replace 4000 with the appid of your game. You shouldn’t call any Steam functions before you initialize.

When you’re done, when you’re closing your game, just shutdown.

SteamClient.Shutdown();

Server

To create a server do this.

var serverInit = new SteamServerInit( "gmod", "Garry Mode" )
{
    GamePort = 28015,
    Secure = true,
    QueryPort = 28016
};

try
{
    Steamworks.SteamServer.Init( 4000, serverInit );
}
catch ( System.Exception )
{
    // Couldn't init for some reason (dll errors, blocked ports)
}

Help

Wanna help? Go for it, pull requests, bug reports, yes, do it.

You can also hit up the Steamworks Thread for help/discussion.

We also have a wiki you can read and help fill out with examples and advice.

License

MIT - do whatever you want.

评论

暂无评论