Monday, August 09, 2021

NEW: Goldberg Emulator - a libsteam_api drop-in replacement to improve game compatibility

diff --git a/Makefile b/Makefile
index 6e970fe..bd0e075 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ LBITS := $(shell getconf LONG_BIT)

UNAME := $(shell uname)

-CFLAGS = -Wall -O3 -I src -I native/include -fPIC -I ../sdk/public
+CFLAGS = -Wall -O3 -I src -I native/include -fPIC -I ../sdk/public -I/usr/local/include

ifndef ARCH
ARCH = $(LBITS)
@@ -18,7 +18,7 @@ OS=linux
CFLAGS += -std=c++0x
endif

-LFLAGS = -lhl -lsteam_api -lstdc++ -L native/lib/$(OS)$(LIBARCH) -L ../sdk/redistributable_bin/$(OS)$(ARCH)
+LFLAGS = -lhl -lsteam_api -lstdc++ -L/usr/local/lib

SRC = native/cloud.o native/common.o native/controller.o native/friends.o native/gameserver.o \
native/matchmaking.o native/networking.o native/stats.o native/ugc.o
diff --git a/native/gameserver.cpp b/native/gameserver.cpp
index 165d4ec..f69827e 100644
--- a/native/gameserver.cpp
+++ b/native/gameserver.cpp
@@ -124,7 +124,7 @@ vuid HL_NAME(gameserver_get_steam_id)() {
}

int HL_NAME(gameserver_get_public_ip)() {
- return (int)SteamGameServer()->GetPublicIP();
+ return (int)SteamGameServer()->GetPublicIP().m_unIPv4;
}

DEFINE_PRIM(_BOOL, gameserver_init, _I32 _I32 _I32 _I32 _I32 _BYTES);
@@ -196,4 +196,4 @@ HL_PRIM void HL_NAME(request_internet_server_list)( int appId, varray *filters,

DEFINE_PRIM(_VOID, request_internet_server_list, _I32 _ARR _FUN(_VOID, _DYN));

-// ---------
\ No newline at end of file
+// ---------
diff --git a/native/steamwrap.h b/native/steamwrap.h
index 70f64fc..506cc5d 100644
--- a/native/steamwrap.h
+++ b/native/steamwrap.h
@@ -11,9 +11,9 @@
#include <iostream>
#include <map>

-#include <steam/steam_api.h>
-#include <steam/steam_gameserver.h>
-#include <steam/isteamappticket.h>
+#include <goldberg_emulator/sdk_includes/steam_api.h>
+#include <goldberg_emulator/sdk_includes/steam_gameserver.h>
+#include <goldberg_emulator/sdk_includes/isteamappticket.h>

typedef vbyte * vuid;
#define _UID _BYTES
Hi,

Please find attached a port of the "Goldberg Emulator." This is a
drop-in replacement for libsteam_api.so, the base steam interface on
Linux. It has been designed to allow Steam online features for LAN and
offline use without needing a Steam connection. This makes it useful for
game compatibility beyond what the current collection of stubs in the
port games/steamworks-nosteam is capable of. It is LGPLv3+ licensed.

This came to be because of the problems I encountered with running
recent versions of the game Northgard that ship Linux' libsteam_api.so
even with the GOG.com version and only offer limited functionality with
the stub of steam.hdll in steamworks-nosteam.

With this port, there is no need anymore to stub Steam wrapper
libraries for most scenarios, as libsteam_api.so will take care of
everything.

For those who own one of the hashlink games that can run with this
(Northgard, Evoland Legendary Edition, Darksburg, Wartales Demo), you
can test this port by installing it and building a "full-fat"
steam.hdll that you drop into the game's directory. Remove all other
*.hdll, *.dll, and *.so{,.*} in there. Then run one of:

$ hl # Northgard
$ hl sdlboot.dat # Evoland Legendary Edition, Wartales Demo
$ hl hlboot.dat # Darksburg

Note this will need the recent update to hashlink-1.11pl0 (NOT p0!).

To build the full steam.hdll _after_ installing the goldberg_emulator
port, clone https://github.com/HeapsIO/hlsteam, apply the attached diff
(diff based on checkout 24265f62c0499a0c4f37d42b33548c24061c2bd7), and
build with gmake.

With this port, it will be possible to replace the stub collection in
steamworks-nosteam with simple, non-stubbed ports of the upstream
libraries, as libsteam_api.so from the Goldberg Emulator will take care
of all Steam API calls. The benefits will be less maintenance and
overall better compatibility.

A few notes about the port:

- I've used GL_* variables similar to GH_*, as upstream is on GitLab.
- Headers are in ${PREFIX}/include/goldberg_emulator/sdk_includes
- get_lib_path is set to return "." which works with all use cases that
I tested.
- A few linux functions have to be substituted in wrap.cpp. Among them,
replacing dlmopen with dlopen seems the worst offender, but I am not
aware of a better workaround for Linux' Lmid_t/dlmopen stuff and so
far this has not caused problems.

comments? oks?

No comments:

Post a Comment