[Python] How to Wrap SteamAPI_InitFlat in Python without using SteamworksPy

Discussão em 'Python' iniciado por Stack, Março 23, 2025.

  1. Stack

    Stack Membro Participativo

    I am developing my first game for steam, and I am trying to get the basic steam flat file to work in python. The library that did this seems to be dead (steamworkspy), and is not trivial to set up in the first place.

    I have written code that wraps the redistributable dlls in python as shown below.

    import os
    os.environ["SteamAppId"] = "480"
    os.environ["SteamDebug"] = "1"

    import ctypes

    import platform
    import sys
    import time

    def check_steam_restart(dll_path, app_id):
    steam = ctypes.windll.LoadLibrary(dll_path)
    func = steam.SteamAPI_RestartAppIfNecessary
    func.argtypes = [ctypes.c_uint32]
    func.restype = ctypes.c_bool

    result = func(ctypes.c_uint32(app_id))
    print(f"SteamAPI_RestartAppIfNecessary returned: {result}")
    if result:
    print("Steam needs to relaunch the app through Steam — exiting...")
    sys.exit(0)

    class Steam:
    def __init__(self):
    self._dll = self._load_library()
    self._initialize_functions()

    def _check_symbol(self, symbol_name):
    if not hasattr(self._dll, symbol_name):
    raise Exception(f"Function '{symbol_name}' not found in Steamworks library.")

    def _load_library(self):
    """Load the correct platform-specific Steamworks DLL."""
    redistributable_bin_path = {
    'Windows': {
    '64bit': r'steamworks_sdk_162\sdk\redistributable_bin\win64\steam_api64.dll',
    '32bit': r'steamworks_sdk_162\sdk\redistributable_bin\steam_api.dll'
    },
    'Linux': {
    '64bit': r'steamworks_sdk_162/sdk/redistributable_bin/linux64/libsteam_api.so',
    '32bit': r'steamworks_sdk_162/sdk/redistributable_bin/linux32/libsteam_api.so'
    }
    }

    system = platform.system()
    architecture = platform.architecture()[0]

    if system not in redistributable_bin_path or architecture not in redistributable_bin_path[system]:
    raise OSError(f'Unsupported platform or architecture: {system} {architecture}')

    library_path = os.path.join(
    os.path.dirname(os.path.abspath(__file__)),
    redistributable_bin_path[system][architecture]
    )

    if not os.path.exists(library_path):
    raise FileNotFoundError(f"Steamworks library not found at {library_path}")

    print(f"Steamworks library located: {library_path}")

    if system == 'Windows':
    return ctypes.windll.LoadLibrary(library_path)
    else:
    return ctypes.CDLL(library_path)

    def _initialize_functions(self):
    # Step 2: Initialize Steam via InitFlat
    if hasattr(self._dll, "SteamAPI_InitFlat"):
    print("Using SteamAPI_InitFlat")
    self._dll.SteamAPI_InitFlat.argtypes = []
    self._dll.SteamAPI_InitFlat.restype = ctypes.c_bool
    else:
    raise Exception("SteamAPI_InitFlat not found in DLL")

    # Step 3: Register Shutdown (for __exit__)
    if hasattr(self._dll, "SteamAPI_Shutdown"):
    self._dll.SteamAPI_Shutdown.argtypes = []
    self._dll.SteamAPI_Shutdown.restype = None
    else:
    raise Exception("SteamAPI_Shutdown not found in DLL")

    def __enter__(self):
    # Optional: Check if Steam is running
    if hasattr(self._dll, "SteamAPI_IsSteamRunning"):
    self._dll.SteamAPI_IsSteamRunning.restype = ctypes.c_bool
    running = self._dll.SteamAPI_IsSteamRunning()
    print(f"Steam running: {running}")

    print("Initializing Steam API via Flat...")
    if not self._dll.SteamAPI_InitFlat():
    raise Exception("SteamAPI_InitFlat failed")
    print("Steam API initialized successfully.")
    return self

    def __exit__(self, exc_type, exc_val, exc_tb):
    print("Shutting down Steam API...")
    self._dll.SteamAPI_Shutdown()



    if __name__ == "__main__":
    try:
    dll_path = os.path.join(
    os.path.dirname(os.path.abspath(__file__)),
    r"steamworks_sdk_162\sdk\redistributable_bin\win64\steam_api64.dll"
    )

    app_id = int(os.environ["SteamAppId"])
    print(f"Using App ID: {app_id}")
    check_steam_restart(dll_path, app_id)
    with Steam() as steam:
    print("Steam API initialized successfully.")

    # Debugging HSteamPipe and HSteamUser
    # mod_manager = ModManager(steam._dll)
    # print(f"HSteamPipe: {mod_manager._steam_pipe}")
    # print(f"HSteamUser: {mod_manager._steam_user}")

    # # Test ISteamUGC interface retrieval
    # ugc_interface = mod_manager._ugc_interface
    # print(f"ISteamUGC interface retrieved: {ugc_interface}")

    except Exception as e:
    print(f"Error: {e}")


    However, this returns a very unhelpful error, usually something I see in memory management.

    (venv) D:\97cweb\Documents\Projects\SimAntics\py-lua\simantics_SteamworksWrapper\simantics_SteamworksWrapper>python steam.py
    Using App ID: 480
    SteamAPI_RestartAppIfNecessary returned: False
    Steamworks library located: D:\97cweb\Documents\Projects\SimAntics\py-lua\simantics_SteamworksWrapper\simantics_SteamworksWrapper\steamworks_sdk_162\sdk\redistributable_bin\win64\steam_api64.dll
    Using SteamAPI_InitFlat
    Steam running: True
    Initializing Steam API via Flat...
    Setting breakpad minidump AppID = 480
    SteamInternal_SetMinidumpSteamID: Caching Steam ID: 76561198283721268 [API loaded no]
    Error: exception: access violation writing 0x0000000000000001


    Any help getting this to work is greatly appreciated. I did try google and the robot to get this to work as well, so just google it is not the answer.

    Continue reading...

Compartilhe esta Página