Project1

标题: 在使用Steam API过程中出现了回调问题 [打印本页]

作者: 零教授    时间: 2020-12-3 06:01
标题: 在使用Steam API过程中出现了回调问题
Steam API用的是
https://rpg.blue/thread-396612-1-1.html
这个帖子的,ruby的Steam API接口,亲测里面的每一个函数都可以成功调用

于是我往里面加了若干个新的API调用函数

第一个函数“寻找或创建排行榜”成功执行了


但是第二个函数“上传玩家分数”
https://partner.steamgames.com/d ... oadLeaderboardScore

总是无法成功调用

以下是代码
RUBY 代码复制
  1. # 寻找或创建排行榜 ISteamUserStats::FindOrCreateLeaderboard(name, int=2, int=1)
  2.   def find_or_create_leaderboard(name)
  3.     if initted?
  4.       @@dll_SteamAPI_ISteamUserStats_FindOrCreateLeaderboard.call(@i_user_stats, name, 2, 1) #% 256 != 0
  5.     else
  6.       nil
  7.     end
  8.   end
  9.   def find_leaderboard(name)
  10.     if initted?
  11.       @@dll_SteamAPI_ISteamUserStats_FindLeaderboard.call(@i_user_stats, name) #% 256 != 0
  12.     else
  13.       nil
  14.     end
  15.   end
  16.   # 上传用户分数 ISteamUserStats::UploadLeaderboardScore(steamleaderboard_t, int=2, newScore)
  17.   def upload_leaderboard_score(name, score)
  18.     if initted?
  19.       handle = find_or_create_leaderboard(name)
  20.       if !handle.nil?
  21.         p handle
  22.         #handle = handle.unpack('L')
  23.         #p handle
  24.         #handle = handle[0]
  25.         @@dll_SteamAPI_ISteamUserStats_UploadLeaderboardScore.call(@i_user_stats,
  26.         @@dll_SteamAPI_ISteamUserStats_FindLeaderboard.call(@i_user_stats, name),
  27.         1, score, ' ', 0)
  28.       else
  29.         nil
  30.       end
  31.     else
  32.       nil
  33.     end
  34.   end
  35.   #
  36. ###############################################################
  37.   # 2020.12.3 新增  零教授
  38.   ###############################################################
  39.   # 排行榜功能
  40.   ###############################################################
  41.   # 寻找或创建排行榜 ISteamUserStats::FindOrCreateLeaderboard(name, int=2, int=1)
  42.   @@dll_SteamAPI_ISteamUserStats_FindOrCreateLeaderboard = Win32API.new(self.steam_dll_name, 'SteamAPI_ISteamUserStats_FindOrCreateLeaderboard', 'PPII', 'L')
  43.   @@dll_SteamAPI_ISteamUserStats_FindLeaderboard = Win32API.new(self.steam_dll_name, 'SteamAPI_ISteamUserStats_FindLeaderboard', 'PP', 'L')
  44.   # 上传用户分数 ISteamUserStats::UploadLeaderboardScore(name, int=2, newScore)
  45.   @@dll_SteamAPI_ISteamUserStats_UploadLeaderboardScore = Win32API.new(self.steam_dll_name, 'SteamAPI_ISteamUserStats_UploadLeaderboardScore', 'PLIIPI', 'L')
  46.   ###############################################################
  47.   #
  48.   ###############################################################




文献中写到这个函数需要传入第一个函数回调的排行榜句柄



但是我查阅了文献
我觉得它应该是个uint64,但是文档却在暗示它是个带两个成员的指针
恋野迷踪_零教授Prof.Zero(854923362)  5:10:21

然后这个函数要这个指针的第一个成员

恋野迷踪_零教授Prof.Zero(854923362)  5:10:44
我每次都能拿到一个不一样的int64,非常神奇,我觉得这肯定不是正确的句柄,所以每次传给第二个函数都毫无反应

然后我就把回调从L改成了P

但是这样则会导致进程崩掉

一时间无从下手
作者: guoxiaomi    时间: 2020-12-3 06:01
来看看这个:https://rpg.blue/thread-491526-1-1.html
作者: 零教授    时间: 2020-12-3 06:11
本帖最后由 零教授 于 2020-12-3 06:12 编辑

FindOrCreateLeaderboard函数返回的绝对是个Int64
我能用I或者L接受,但是每次接收到的Int64都是个不一样的数
我觉得一个固定的排行榜不应该句柄会浮动变化,那样不就不能异步更新了吗?

FindOrCreateLeaderboard的return描述是:
Returns: SteamAPICall_t to be used with a LeaderboardFindResult_t call result.


SteamAPICall_t这玩意的Base_Type是 uint64

LeaderboardFindResult_t则是上图中的SteamLeaderboard_t和一个uint8的组合
SteamLeaderboard_t的描述则是 uint64  Handle to a single leaderboard.

那不就间接说明返回值是一个带着Handle 和 一个是否返回成功的布尔值的 指针了么

但是我用取指针的方式又取不到第一个函数的返回值,它确实是个Int64(但是不是uint64,会是负数,搞不懂)

那我就不懂了,文献说第二个函数要用第一个函数的返回值,第一个函数它100%成功执行了(毕竟Create了一个排行榜)到底返回了个啥

我究竟如何获得第二个函数所需要的 SteamLeaderboard_t
作者: SixRC    时间: 2020-12-5 00:45
首先 rmva是32位的 它是不可能取得64位的返回值的 而且win32api取到的表现形式必然是有符号32位整数
然后 win32api 返回值设为"p" 并不是用来取指针内容的 是拿来取字符串的 而且必须是'0'结尾的字符串
最后 这个 SteamAPICall_t 是用来设置回调函数的
正确的做法是用它设置一个回调并等待回调 通过 CCallResult 类
解决
1.我不知道这个文档是只对64位还是64/32位通用 如果32位依旧返回64位整数 那么win32api是不可能取到完整64位整数的
它只能取低32位 所以必须在c/c++端调用 或者用汇编取 edx:eax
2.回调函数也是编译的回调函数 不是ruby函数 所以不能用CCallResult 除非c++ 或写汇编
当无法使用CCallResult时
NOTE: If you can't use the CCallResult system, then you may be able to use ISteamUtils::IsAPICallCompleted, ISteamUtils::GetAPICallResult and ISteamUtils::GetAPICallFailureReason to track the status of a call result.
用这三个函数就行了 查询 取结果/错误信息
计算好回调返回的结构体大小送进去送出来就行

结论 确定32位steam dll的接口类型 选择利用回调的方案 以及开工
我不懂steam 文档也是刚查的 看看就行




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1