Facepunch / Facepunch.Steamworks

Another fucking c# Steamworks implementation
MIT License
2.92k stars 350 forks source link

Accessing "SteamNetworkingUtils003" before "SteamAPI_Init" succeeded error #630

Open Chillu1 opened 2 years ago

Chillu1 commented 2 years ago

Describe the bug [S_API FAIL] Tried to access Steam interface SteamNetworkingUtils003 before SteamAPI_Init succeeded.

Build version prints this error, but Unity editor doesn't. It doesn't break the server, but it makes it, so I can't query rules from that server. I've tried building the newest release, but get errors about net46 (am on Linux). So I settled with https://github.com/Crytilis/Facepunch.Steamworks fork instead. It didn't help.

Server is functioning, at least the basic query is. But the QueryRulesAsync() doesn't give any results.

I have identified, that the error comes from "SteamServer.Init(AppId, serverInit);", and it's not "bool asyncCallbacks".

It might be because the steamclient.so is wrong on both my PC and my VPS (tried it on both machines). Since I'm linking it usually from linux64/. Linking it, copying it, using 32bit instead (wrong elfclass error), didn't fix it, neither did adding a steam_appid.txt.

I tried removing all other Steamworks functionality to see if I'm calling it somewhere I shouldn't, but it also didn't help.

Google didn't help me either. So finally coming here.

Also my game is supposed to release in 1 week, so that's fun.

To Reproduce Steps to reproduce the behavior:

  1. Start server with server-only build
  2. "Tried to access Steam interface SteamNetworkingUtils003 before SteamAPI_Init succeeded." error
  3. Not being able to get server rules results from query

Calling Code

private IEnumerator StartServer()
{
    try
    {
        _isDedicatedServer = true;
        var serverInit = new SteamServerInit("TagHop", "TagHop");
        serverInit.GamePort = _gamePort;
        serverInit.Secure = true;
        serverInit.QueryPort = _queryPort;
        serverInit.SteamPort = 27016;
        serverInit.VersionString = _gameController.Version.ToStringSteam();//"0.1.3.0";
        SteamServer.Init(AppId, serverInit);//LINE THAT TRIGGERS THE ERROR
        SteamServer.ServerName = "Test Server";
        SteamServer.LogOnAnonymous();
    }
    catch (Exception e)
    {
        Log.Error("Failed making a steam server");
        Log.Exception(e);
    }

    if (!SteamServer.IsValid)
    {
        yield return new WaitForSeconds(1f);
        Log.Error("Steam server isn't valid");
    }
}

Desktop (please complete the following information):

Additional context Here's the log (removed the redundant lines):

Preloaded 'libsteam_api.so' Initialize engine version: 2020.3.25f1 (9b9180224418) Begin MonoManager ReloadAssembly - Completed reload, in 0.066 seconds ... UnloadTime: 0.497467 ms ... dlopen failed trying to load: steamclient.so with error: steamclient.so: cannot open shared object file: No such file or directory [S_API] SteamAPI_Init(): Loaded '/home/hostname/.local/share/Steam/linux64/steamclient.so' OK. (First tried local 'steamclient.so') CAppInfoCacheReadFromDiskThread took 11 milliseconds to initialize Setting breakpad minidump AppID = 1625330 [S_API FAIL] Tried to access Steam interface SteamNetworkingUtils003 before SteamAPI_Init succeeded. ... UnloadTime: 3.921835 ms Finished loading scene in server-only mode.

Unloading 78 unused Assets to reduce memory usage. Loaded Objects now: 4942. Total: 11.692430 ms (FindLiveObjects: 0.185797 ms CreateObjectMapping: 0.082222 ms MarkObjects: 11.256767 ms DeleteObjects: 0.167282 ms)

Chillu1 commented 2 years ago

I managed to make a temporary fix, without the use of rules.

It seems that the ServerName, is the only property that's available publically, and can be changed after server creation.

So I save all the needed server rules/info in ServerName instead: string infoName = _serverName+" "+mapName+" "+gamemode+" "+playerAmount.ToString()+" "+roundTime.ToString(); SteamServer.ServerName = infoName; And then read it by splitting whitespace (could probably have had a better character here, but it was a fast fix) string[] infos = info.ServerInfo.Name.Split(' ');

This is not ideal, but it works. Not sure how efficient it is changing "server name" every second.

rgarlik commented 2 years ago

Hey, looks like you were having trouble opening the steamclient.so shared object, judging from the "steamclient.so: cannot open shared object file: No such file or directory" line. I fixed this by creating a symlink of steamclient.so from my steamcmd installation folder, in ~/.steam/sdk64/steamclient.so (because apparently that's where the Steam API is looking for that particular file).

I did it like this (in my case, the user I'm installing starting the server under is called steam cause running steamcmd as root is a security risk):

ln -s /home/steam/steamcmd/linux64/steamclient.so /home/steam/.steam/sdk64/steamclient.so
Chillu1 commented 2 years ago

Hey, looks like you were having trouble opening the steamclient.so shared object, judging from the "steamclient.so: cannot open shared object file: No such file or directory" line. I fixed this by creating a symlink of steamclient.so from my steamcmd installation folder, in ~/.steam/sdk64/steamclient.so (because apparently that's where the Steam API is looking for that particular file).

I did it like this (in my case, the user I'm installing starting the server under is called steam cause running steamcmd as root is a security risk):

ln -s /home/steam/steamcmd/linux64/steamclient.so /home/steam/.steam/sdk64/steamclient.so

Linking it, copying it, using 32bit instead (wrong elfclass error), didn't fix it

rgarlik commented 2 years ago

Did it remove the "steamclient.so: cannot open shared object file: No such file or directory" error at least?

Chillu1 commented 2 years ago

Nope, that's why the error is so weird, and it seems to be a niche internal one.

But it's not a big problem for me anymore, because of the temporary fix that works:

I managed to make a temporary fix, without the use of rules.

It seems that the ServerName, is the only property that's available publically, and can be changed after server creation.

So I save all the needed server rules/info in ServerName instead: string infoName = _serverName+" "+mapName+" "+gamemode+" "+playerAmount.ToString()+" "+roundTime.ToString(); SteamServer.ServerName = infoName; And then read it by splitting whitespace (could probably have had a better character here, but it was a fast fix) string[] infos = info.ServerInfo.Name.Split(' ');

This is not ideal, but it works. Not sure how efficient it is changing "server name" every second.

Would be nice to find out why and how this happens internally at some point. But it also might be related to some niche interaction in my specific scenario? Not prio anyway, hopefully others don't get the same problem

rgarlik commented 2 years ago

I've found this question because I encountered a similar problem, however this is my output:

[S_API] SteamAPI_Init(): Loaded local 'steamclient.so' OK.
[S_API FAIL] Tried to access Steam interface SteamNetworkingUtils003 before SteamAPI_Init succeeded.

Calling SteamServer.Init causes this. Note that it does manage to find steamclient.so and despite this crashes. Haven't yet gotten a workaround.

When you talked about your temporary fix, could you show me what your whole server setup code looks like please? Everything around SteamServer.Init

Chillu1 commented 2 years ago

My memory is foggy, but I think I also might have gotten "Loaded local 'steamclient.so' OK." before, and still got the same error.

Calling SteamServer.Init causes this Yeah: I have identified, that the error comes from "SteamServer.Init(AppId, serverInit);", and it's not "bool asyncCallbacks

What kind of crash is it? The one I get is that I can't query for rules, and some additional extra logic.

The code hasn't really changed since. The workaround doesn't make the error go away, or fix the issue. It's a way to get "rules"(extra info) without being able to query for them. I basically store all the data in SteamServer.ServerName instead.

private IEnumerator StartServer()
{
    try
    {
        _isDedicatedServer = true;
        var serverInit = new SteamServerInit("TagHop", "TagHop");
        serverInit.GameDescription = "TagHop";
        serverInit.GamePort = _gamePort;
        serverInit.Secure = true;
        serverInit.QueryPort = _queryPort;
        serverInit.SteamPort = 27016;
        serverInit.VersionString = _gameController.Version.ToStringSteam();
        SteamServer.Init(AppId, serverInit);

        if (File.Exists(Application.dataPath + "/serverconfig.txt"))
            SteamServer.ServerName = File.ReadAllText(Application.dataPath + "/serverconfig.txt");
        else
            SteamServer.ServerName = "Test_Server";

        _serverName = SteamServer.ServerName;
        SteamServer.LogOnAnonymous();
    }
    catch (Exception e)
    {
        Log.Error("Failed making a steam server");
        Log.Exception(e);
    }

    if (!SteamServer.IsValid)
    {
        yield return new WaitForSeconds(1f);
        Log.Error("Steam server isn't valid");
    }
}