ValidateAuthTicektResponce_t doesn't callback on servers
When we initialize as SteamGameServer and call BeginAuthSession The ValidateAuthTicektResponce_t never responds
We have been doing a lot of troublshooting on this and I finally took the mind to check the definitions ... I noted that there is no SteamGameServer version of this callback there is only the one ValidateAuthTicektResponce_t defined in SteamCallbacks.cs and that definition sets the callback ID as
public const int k_iCallback = Constants.k_iSteamUserCallbacks + 43;
should there be a GameServerValidateAuthTicketResponce_t where in
public const int k_iCallback = Constants.k_iSteamGameServerCallbacks + 43;
If that is the case it would explain why we dont get the callback as expected and would sugest there is also an issue with GetAuthSessionTicketResponse_t similar thing ... should have a GameServer variant
Then again I could be insain and something else is preventing the callback from returning but this works perfrectly on the Client API should be the same code for Server the only difference being
SteamGameServer.BeginAuthSession
as oppsed to
SteamUser.BeginAuthSession
@rlabrecque Think I have 5 clients now effected by this.
In all cases its down to the SteamGameServer.BeginAuthSession not getting the ValidateAuthTicektResponce_t
The SteamUser.BeginAuthSession does get the ValidateAuthTicektResponce_t callback
Highly waiting to know how to fix that also ! :)
Also having this problem, will be waiting, thanks.
Me too! 👍
Might as well throw my name in there ;)
I won't be able to check this out for at least a couple more days, but if you duplicate ValidateAuthTicektResponce_t (even into your project) and change the k_iCallback, then register that new callback, does that work?
All the users on my side would be using Package Manager install They can modify the code but need to do that in the package cashe within the project ... half the point of Package Manager is no in advertently changing the code :)
I'll check with a couple of them in our Discord see how it goes and update you
For anyone looking to do it
You simply need to create a new responce type such as
[StructLayout(LayoutKind.Sequential, Pack = 4)]
[CallbackIdentity(Constants.k_iSteamGameServerCallbacks + 43)]
public struct GameServerValidateAuthTicketResponse_t
{
public const int k_iCallback = Constants.k_iSteamGameServerCallbacks + 43;
public CSteamID m_SteamID;
public EAuthSessionResponse m_eAuthSessionResponse;
public CSteamID m_OwnerSteamID; // different from m_SteamID if borrowed
}
Then you need to modify Heathen's Authentication API as follows
On line 40 change this
private static Callback<ValidateAuthTicketResponse_t> m_ValidateAuthSessionTicketResponceServer;
to this
private static Callback<GameServerValidateAuthTicketResponse_t> m_ValidateAuthSessionTicketResponceServer;
then on line 138 change this
m_ValidateAuthSessionTicketResponceServer = Callback<ValidateAuthTicketResponse_t>.Create(HandleValidateAuthTicketResponse);
to this
m_ValidateAuthSessionTicketResponceServer = Callback<GameServerValidateAuthTicketResponse_t>.Create(HandleGameServerValidateAuthTicketResponse);
finally add the following method above line 184
private static void HandleGameServerValidateAuthTicketResponse(GameServerValidateAuthTicketResponse_t param)
{
if (ActiveSessions != null && ActiveSessions.Any(p => p.User == param.m_SteamID))
{
var session = ActiveSessions.First(p => p.User == param.m_SteamID);
session.Authenticate(param);
if (SteamSettings.current != null && SteamSettings.current.isDebugging)
Debug.Log("Processing session request data for " + param.m_SteamID.m_SteamID.ToString() + " status = " + param.m_eAuthSessionResponse);
if (param.m_eAuthSessionResponse != EAuthSessionResponse.k_EAuthSessionResponseOK)
ActiveSessions.Remove(session);
if (session.OnStartCallback != null)
session.OnStartCallback.Invoke(session);
}
else
{
if (SteamSettings.current != null && SteamSettings.current.isDebugging)
Debug.LogWarning("Recieved an authentication ticket responce for user " + param.m_SteamID.m_SteamID + " no matching session was found for this user.");
}
}
Those steps are untested at current, I am working with others in a ticket on the Discord server to get this tested out. If you do this and have any issues ... or find it works please let us know.
Initial testing isn't a hit .. yet ... still playing with it @rlabrecque
where is it exsactly that you source the value to add to the constant ... e.g. in the following
[StructLayout(LayoutKind.Sequential, Pack = 4)]
[CallbackIdentity(Constants.k_iSteamUserCallbacks + 43)]
public struct ValidateAuthTicketResponse_t {
public const int k_iCallback = Constants.k_iSteamUserCallbacks + 43;
public CSteamID m_SteamID;
public EAuthSessionResponse m_eAuthSessionResponse;
public CSteamID m_OwnerSteamID; // different from m_SteamID if borrowed
}
Where did you get 43 from?
We are assuming that the GameServer version will be a + 43 just like the client but that is a blind assumption
I'm starting to wonder if I've just lost it or what. I want to make sure with y'all I'm understanding the documentation correctly so we're not going down the wrong path(still lacking a callback being called either way though). It actually says 2 different things when you read it.
Important Links: https://partner.steamgames.com/doc/features/auth https://partner.steamgames.com/doc/api/ISteamUser#BeginAuthSession https://partner.steamgames.com/doc/api/steam_api#EBeginAuthSessionResult https://partner.steamgames.com/doc/api/ISteamUser#ValidateAuthTicketResponse_t
So basic order of things should be:
- Client gets a ticket
- Client passes ticket to the server
- Server calls BeginAuthSession
- EBeginAuthSessionResult is immediately returned (no callback like auth page mentions).
- It then registers the callback for ISteamUser:ValidateAuthTicketResponse in the event a user goes offline/cancels ticket
- As long as we get k_EBeginAuthSessionResulOK then the user is approved to move forward.
When a user disconnects we call EndAuthSession and the callback above is supposed to be called right?
Here is where things got weird in the docs -- The auth page says it will perform the check and then call ISteamUser:ValidateAuthTicketResponse with the results. But then the BeginAuthSession page says it returns a EBeginAuthSessionResult(which is working properly) and that ValidateAuthTicketResponse_t is used if a entity goes offline or cancels the ticket(does not work).
For now I'm assuming the BeginAuthSession page is correct and that the auth page is misleading/wrong. As I keep poking around I'll update this with anything I think might be helpful.
The workflow is this
- entity (user) generates a ticket
- entity sends said ticket along with the entiteis CSteamID to that which is going to validate them (can be a server or another user)
- That authenticating entity (server or other user) calls BeginSession ... now which is called depends on if this authenticating entity is a Steam Game Server or a user e.g.
SteamUser.BeginAuthSession(authTicket, authTicket.Length, user);would be called by the client e.g. when a user is validating another user andSteamGameServer.BeginAuthSession(authTicket, authTicket.Length, user);would be called by a Steam Game Server when authenticating a user
So the callbacks need to already be registered
That is the entity doing the authenticating (server or client) needs to already have registered the callback on Callback<ValidateAuthTicketResponse_t>.Create(handler); before the BeginAuthSession is called
PS the whole reason for this issue is that the Steam Game Server isn't getting the callback ... so it wont work there
It does work when you have a user authenticate a user that is the
SteamUser.BeginAuthSession(authTicket, authTicket.Length, user); does result in ValidateAuthTicketResponse_t callback
but
SteamGameServer.BeginAuthSession(authTicket, authTicket.Length, user); does not result in callback
This all works as expected and as documented
I think your getting confused in that BeginAuthSession does return a EBeginAuthSessionResult that simply indicates a fundamental issue/error ... the callback on ValidateAuthTicketResponse_t will still occur and will carry additional data in the ValidateAuthTicketResponse_t mainly the EAuthSessionResponse note that EAuthSessionResponse is the response to the request and tells you more than EBeginAuthSessionResult
Or at least this is how I have been using it for some time now though I typically and authenticating a user vai another user such as in P2P networking sessions so I haven't previously ran into the issue with Steam Game Server where it does not get the ValidateAuthTicketResponse_t response
Point is the EBeginAuthSessionResult is not the same as the EAuthSessionResponse
EBeginAuthSessionResult is returned immeadtly when you call BeginAUthSession and simply indicates that the request was sent off to Steam API or if not why not
EAuthSessionResponse is present in the response ValidateAuthTicketResponse_t which comes as a callback when the Auth Session has been processed
Just to reword that
EBeginAuthSessionResult.k_EBeginAuthSessionResultOK = Ticket is valid for this game and this Steam ID.
so this is just saying yes this ticket is structurally a valid ticket for this game
in contrast
EAuthSessionResponse.k_EAuthSessionResponseOK which comes in on the callback is Steam has verified the user is online, the ticket is valid and ticket has not been reused.
so this is saying the ticket is valid, belongs to this user for this game and this user is online ... e.g. everything is legit here drive on
@rlabrecque So I did some more digging to understand what k_iCallback was/is
I think I understand that it simply needs to be a unique ID such that when registering a callback no 2 callbacks have the same ID.
If that is the case then Constants.k_iSteamGameServerCallbacks and the client equivalent values of 100 and 200 are arbitrary and are not responsible for the issue we are seeing in Steam Game Server where the callback is not being returned. So long as the ID is unique which of course it will be since only 1 is ever registered either client or server but never both ... then we know its always unique.
Also I did more digging in the Valve documents
The SteamUser API references that it will trigger the ValidateAuthTicketResponse_t callback
The SteamGameServer API simply says
This registers for ValidateAuthTicketResponse_t callbacks if the entity goes offline or cancels the ticket. See EAuthSessionResponse for more information.
So then is it intended behaviour that Steam Game Server Begin Auth Session does not raise the ValidateAuthTicketResponse_t callback. And if that is the case is that not a glaring issue?
I looked through the Steam Game Server interface callback documentation and do not see a variant of ValidateAuthTicketResponse_t. When I check the header file for SteamUser interface I see the ValidateAuthTicketResponse_t when I check the header for SteamGameServer I do not see an equivalent ... this is really leading me to believe that SteamGameServer BeginAuthSession is just fundamentally different than the workflow seen with SteamUser BeginAuthSession
This really does feel like a bug on Valve's part to me ... but best case its broken documentation on Valve's part
Accordingly to the documentation there is no ValidateAuthTicketResponse_t for SteamGameServer interface's BeginAuthSession though it is referenced it is not said it outright triggers it. Without this callback though you cant know if the session is valid and that the user is logged on and how the user is licensed e.g. barrowing, etc. ... unless I am missing something
Some more reading and working on this
I am fairly well convinced now that this is a bug with Steam API ... though not sure how we could be the first to complain about it :)

While the documentation for SteamGameServer.BeginAuthSession doesn't explicitly say it triggers the ValidateAuthTicketResponce_t callback ... the EAuthSessionResponce does
So it seems like SteamGameServer.BeginAuthSession is using the ValidateAuthTicketResponce_t which is defined in the SteamUser.h ... which why ... but okay
Also this unless I am mistaken means there is nothing Steamworks.NET is doing wrong here. Its simply that Steam API isn't invoking the callback for SteamGameServer but it does for SteamUser
I have a ticket off to Steam my self but haven't heard back yet
This is still a problem for us and the rest of our users as far as I am aware. Does anyone else have any progress they can share?
Hey James, sorry I haven't really been able to get to this much.
The callback numbers themselves are defined by Steam and are available via the Steamworks API here:
https://github.com/rlabrecque/Steamworks.NET/blob/master/CodeGen/steam/steam_api_internal.h#L247-L290=
It looks like all of the k_iSteamGameServerCallbacks callbacks are defined in isteamgameserver.h:
https://github.com/rlabrecque/Steamworks.NET/blob/f5c8f33c4fc4493f47d9a15c904b7025843c4fc7/CodeGen/steam/isteamgameserver.h#L283=
The callback Id is pretty arbitrary but -- it must match on both sides, it's basically the key to lookup what type of struct to use because Steam basically just sends (callbackId, binaryDataBlob, binaryDataBlobSize) to games, but then we (Steamworks code in the game) have to do deserialization from that blob into an actual struct.
I think one thing to try is enabling log_callbacks in Steam as documented here, would be interesting to see what kind of callbacks are /attempted/ to be sent when we call these functions:
https://partner.steamgames.com/doc/sdk/api/debugging
I can try this on Thursday night and let y'all know what happens.
@rlabrecque
Taking a look at the istemgameserver.h again and nothing, it still looks like a bug either with the code which I get is unlikely someone would have hit this by now ... more likely with the documentation
// Authenticate ticket ( from GetAuthSessionTicket ) from entity steamID to be sure it is valid and isnt reused
// Registers for callbacks if the entity goes offline or cancels the ticket ( see ValidateAuthTicketResponse_t callback and EAuthSessionResponse )
virtual EBeginAuthSessionResult BeginAuthSession( const void *pAuthTicket, int cbAuthTicket, CSteamID steamID ) = 0;
That is the comment in the server about the method in question. That notes the ValidateAuthTicketResponce_t callback which doesn't exist in this header. It only exists in the SteamUser header and starts with 100 being the steam user segment of call-back IDs
The closest thing we have is
struct GSClientApprove_t
{
enum { k_iCallback = k_iSteamGameServerCallbacks + 1 };
CSteamID m_SteamID; // SteamID of approved player
CSteamID m_OwnerSteamID; // SteamID of original owner for game license
};
// client has been denied to connection to this game server
struct GSClientDeny_t
{
enum { k_iCallback = k_iSteamGameServerCallbacks + 2 };
CSteamID m_SteamID;
EDenyReason m_eDenyReason;
char m_rgchOptionalText[128];
};
These are documented as belonging to SendUserConnectAndAuthenticate which has the note
NOTE: This is part of the old user authentication API and should not be mixed with the new API.
This tells me I shouldn't be using this with the AuthSession system ... will have to wait and see what @TXMerc finds in his test
I think worst case we see a callback ID 201 which would be GSClientApprove_t or ID 202 which would be GSClientDeny_t I call this worst case as these do not have the information we would expect and get from the session callback
The other option is we see a callback ID that isn't listed in iSteamGameServerCallbacks ... we know the server callbacks segment on 200 and that 9 are listed covering 1 to 11 skipping 4 and 5.
PS: I noticed something odd in the header ... This is in the isteamgameserver header ... but its using a callback ID on the user segment
// received when the game server requests to be displayed as secure (VAC protected)
// m_bSecure is true if the game server should display itself as secure to users, false otherwise
struct GSPolicyResponse_t
{
enum { k_iCallback = k_iSteamUserCallbacks + 15 };
uint8 m_bSecure;
};
Also of those structures that are prefixed with k_iSteamGameServerCallbacks they count { 1, 2, 3, 6, 7, 8, 9, 10, 11 }
So 4 and 5 are skipped and we see a "15" in the game server header that is just out of place all together.
@rlabrecque log_callbacks is a Steam Client command line, the issue is the Steam Game Server callback ... so far we haven't been able to find a way to log the callbacks for the server
We gave it a go with Steam CMD and aren't seeing any thing from the log_callback command ... any ideas?
Still nothing on this one, no response from Valve, no results from attempting to log callbacks
I have had a ticket open with Valve for 20 days now and no response :) that's a record for me.
I have started a forum post ... course Steamworks developer forum is in my experience completely useless generally no one responds https://steamcommunity.com/groups/steamworks/discussions/1/3409802983878249925/
I am completely out of ideas on this one
Still looking for any support we can on this one.
Its been exactly one month since I reached out to Valve ... still no initial response from them. Posted on the Steamworks Developer forum and no response there at all either
Any ideas at all are welcome
Just checking in on this one again
Still no word from Valve on my side nor the Steamworks Developer community
Help me @rlabrecque your our only hope :) Star Wars reference but seriously any help you can offer or maybe any ideas on where else to search would be greatly appreciated
Yep kinda annoying that Valve etc putting this issue under the carpet
Coming up on 2months now no response from Valve not even an initial response, to the point I submitted a support case about my support case to see if Valve even does support anymore.
Anyway
I think from our point of view we are going to have to say Steamworks.NET doesn't support Steam Game Server at least not fully.
Would be very happy to help work on this in the future if anyone is keen to engage, happy to pay as well.
I just added another comment to my ticket as well. I'll let y'all know if I get anything but so far I've been surprised, even wowed at how unresponsive they are.
It is an unusual level of unresponsiveness. I am used to them taking a few days maybe a week but this is 2 months and not even an initial response
@rlabrecque ? any news ?
I poked around Facepunch and best I can see they aren't doing anyhting different but I am told it works through them
I confirmed the callback ID as well 143 rather its on client server that is just the callback ID
@rlabrecque any idea why Valve has stopped responding to support requests. I submitted a ticket well more than 2 months ago at this point. I have updated it just once a week or so with new testing results, etc. but I still haven't gotten an initial response from them.
To my knowledge none of the devs I have been working with on this issue has gotten a response either.
I haven't been able to look deeper yet unfortunately.
Do we have a minimal repro of this, and has anyone tried recreating it with the C++ SDK?