LuaJIT FFI:上传 Steamworks 排行榜

LuaJIT FFI: Uploading Steamworks leaderboards

如何在 LuaJIT FFI 中使用 SteamAPICall_t 和 SteamLeaderboard_t 句柄?
我用 LÖVE2D framework & Steamworks Lua Integration (SLI)

链接:FindLeaderboard / UploadLeaderboardScore / Typedef

function UploadLeaderboards(score)
local char = ffi.new('const char*', 'Leaderboard name')
local leaderboardFound = steamworks.userstats.FindLeaderboard(char) -- Returns SteamAPICall_t
local leaderboardCurrent = ?? -- Use SteamAPICall_t with typedef SteamLeaderboard_t somehow.
local c = ffi.new("enum SteamWorks_ELeaderboardUploadScoreMethod", "k_ELeaderboardUploadScoreMethodKeepBest")
score = ffi.cast('int',math.round(score))
return steamworks.userstats.UploadLeaderboardScore(leaderboardCurrent, c, score, ffi.cast('int *', 0), 0ULL)
end


leaderboardCurrent = ffi.cast("SteamLeaderboard_t", leaderboardFound) -- No declaration error

SteamAPICall_t 只是一个符合您要求的数字。 这意味着在 Steam API 中与 CCallback 一起使用。 lua 集成遗漏了 CCallbackSTEAM_CALLBACK.

SteamLeaderboard_t 响应是通过调用 FindLeaderboard 生成的。 在这种情况下,您正在向 Steam 发出请求,而 Steam 需要以异步方式响应。

所以你要做的是定义一个 Listener 对象(在 C++ 中),它将监听响应(将以 SteamLeaderboard_t 的形式)并为其编写 C-like 函数,所以ffi可以看懂。

这意味着您的程序必须能够做到这一点:

  1. 为排行榜注册监听器。
  2. 提交排行榜请求。 ( 查找排行榜 )
  3. 等待消息(SteamLeaderboard_t)
  4. 使用SteamLeaderboard_t

简而言之,您需要用 C++ 为事件编写代码并为它们添加 C-like 接口并将其全部编译成一个 DLL,然后 link 该 DLL lua 使用外国金融机构。这可能很棘手,因此请谨慎行事。

在 C 中(ffi.cdef 和 dll):

//YOU have to write a DLL that defines these
typedef struct LeaderboardEvents{
    void(*onLeaderboardFound)(SteamLeaderboard_t id);
} LeaderboardEvents;
void MySteamLib_attachListener(LeaderboardEvents* events);

然后在lua.

local lib = --load your DLL library here
local Handler = ffi.new("LeaderboardEvents")

Handler.onLeaderboardFound = function(id)
   -- do your stuff here.
end

lib.MySteamLib_attachListener(Handler)

在编写 DLL 时,我强烈建议您通读 Steam api 提供的 SpaceWar 示例,以便了解如何注册回调。