larsiusprime / SteamWrap

Haxe native extension for the Steam API
MIT License
106 stars 44 forks source link

Getting the user's Steam ID #11

Closed anpShawn closed 7 years ago

anpShawn commented 7 years ago

Hi, I attempted to add this on my own and encountered a bit of an issue. So in the Steam SDK you can retrieve a user's id with:

SteamUser()->GetSteamID();

I wrapped this inside of a function inside of SteamWrap.cpp:

value SteamWrap_GetUserId()
{
  if (!CheckInit()) return alloc_int(0);

  uint64 id = SteamUser()->GetSteamID();
  return alloc_int((int)id);
}
DEFINE_PRIM(SteamWrap_GetUserId, 0);

Then I hooked up a function for it inside of Steam.hx:

private static var SteamWrap_GetUserId:Void->Int64;
SteamWrap_GetUserId = Lib.load("steamwrap", "SteamWrap_GetUserId", 0);

public static function getUserId():Int64 {
        if (!active) return 0;
        return SteamWrap_GetUserId();
    }

But, when compiling I receive the error:

Could not find primitive SteamWrap_GetUserId__0.

I'm assuming that I need a header definition for my new function somewhere, but I could not find header definitions for any of the other SteamWrap functions to place it with.

larsiusprime commented 7 years ago

I'll try and test it in a function, so far looks pretty good, and I don't think you actually need to put any headers anywhere, just the definition body.

That said, there is one error I see -- standard CFFI has trouble passing 64-bit integers across the haxe/c++ divide. The workaround I've been using is to convert it into a string and pass that back instead.

anpShawn commented 7 years ago

I tried changing the cpp function to:

value SteamWrap_GetUserId()
{
  if (!CheckInit()) return alloc_string("");

  uint64 id = SteamUser()->GetSteamID();

  std::ostringstream data;
  data << id;
  return alloc_string(data.str().c_str());
}
DEFINE_PRIM(SteamWrap_GetUserId, 0);

But I still receive

Could not find primitive SteamWrap_GetUserId__0.

I also tried rebuilding via

lime rebuild steamwrap windows

but no change

larsiusprime commented 7 years ago

private static var SteamWrap_GetUserId:Void->Int64;

the return type should be :Dynamic, at least if you're following the convention in SteamWrap, I'm not sure if that is the issue.

SteamWrap_GetUserId = Lib.load("steamwrap", "SteamWrap_GetUserId", 0);

that should probably be cpp.Lib.load( to be on the safe side.

Your new C++ function looks okay.

Did you try building from the build.bat or build.sh script?

anpShawn commented 7 years ago

I updated the type to Dynamic. Added 'cpp' to the front of Lib.load. Have tried building both from build.bat and lime rebuild steamwrap. Did a clean windows build. Same error :(

larsiusprime commented 7 years ago

Hmm, wonder if it's a regression on my side. Anyways, I'll try to compile your code myself in a bit, should have this solved by tomorrow.

anpShawn commented 7 years ago

Fixed.

So while the Steam User ID is a 64 bit int, the API actually returns it as type "CSteamId". That type has a built in conversion function to int64, so the updated function for steamwrap.cpp is:

value SteamWrap_GetUserId()
{
  if (!CheckInit()) return alloc_string("");

  CSteamID id = SteamUser()->GetSteamID();
  uint64 intId = id.ConvertToUint64();

  std::ostringstream data;
  data << intId;
  return alloc_string(data.str().c_str());
}

The Steamwrap build.bat process was actually outputting an error that hinted at this, but the output window was closing so fast I didn't see it. It wasn't until I took a screenshot that I noticed it. So this is closed, but now I'm off to add an extra event listener. I might be back tomorrow -_-