From 4d415945acfbdfb03f117ea9a539e9e9bf00229f Mon Sep 17 00:00:00 2001 From: Riley Labrecque Date: Sat, 20 Mar 2021 13:21:22 -0700 Subject: [PATCH] v1.51 --- Readme.txt | 19 ++ SteamworksExample/Messages.h | 22 -- SteamworksExample/SpaceWar.h | 3 - SteamworksExample/SpaceWarClient.cpp | 20 +- SteamworksExample/SpaceWarClient.h | 2 +- SteamworksExample/SpaceWarServer.cpp | 118 +++----- public/steam/isteamapplist.h | 4 +- public/steam/isteamcontroller.h | 64 +++- public/steam/isteamfriends.h | 5 +- public/steam/isteamgameserver.h | 15 - public/steam/isteaminput.h | 85 +++++- public/steam/isteamnetworking.h | 8 +- public/steam/isteamnetworkingmessages.h | 91 +++--- public/steam/isteamnetworkingsockets.h | 96 ++++-- public/steam/isteamnetworkingutils.h | 61 ++-- public/steam/isteamremotestorage.h | 2 +- public/steam/isteamugc.h | 6 +- public/steam/isteamutils.h | 11 +- .../lib/linux32/libsdkencryptedappticket.so | Bin 1130574 -> 1130574 bytes .../lib/linux64/libsdkencryptedappticket.so | Bin 1024182 -> 1024182 bytes .../lib/osx/libsdkencryptedappticket.dylib | Bin 1723120 -> 1755472 bytes .../steam/lib/win32/sdkencryptedappticket.dll | Bin 631072 -> 631072 bytes .../lib/win64/sdkencryptedappticket64.dll | Bin 796960 -> 796960 bytes public/steam/steam_api.json | 283 +++++++++++++++--- public/steam/steam_api_flat.h | 31 +- public/steam/steam_gameserver.h | 28 +- public/steam/steamclientpublic.h | 6 +- public/steam/steamnetworkingtypes.h | 80 ++--- redistributable_bin/linux32/libsteam_api.so | Bin 405224 -> 409801 bytes redistributable_bin/linux64/libsteam_api.so | Bin 404222 -> 404759 bytes redistributable_bin/osx/libsteam_api.dylib | Bin 425264 -> 453312 bytes redistributable_bin/steam_api.dll | Bin 239392 -> 239904 bytes redistributable_bin/steam_api.lib | Bin 352036 -> 354776 bytes redistributable_bin/win64/steam_api64.dll | Bin 264480 -> 265504 bytes redistributable_bin/win64/steam_api64.lib | Bin 349016 -> 351730 bytes tools/ContentBuilder/run_build.bat | 2 +- .../ContentBuilder/scripts/app_build_1000.vdf | 21 +- .../scripts/depot_build_1001.vdf | 37 +-- .../scripts/depot_build_1002.vdf | 40 +++ .../scripts/simple_app_build.vdf | 21 ++ tools/drm/drmtool.exe | Bin 1908000 -> 1919776 bytes tools/drm/drmtoolp.exe | Bin 1727776 -> 1741088 bytes tools/drm/ubuntu12_32/drmtoolp | Bin 1804378 -> 1804378 bytes tools/drm/ubuntu12_32/steamdrmp.so | Bin 91474 -> 91474 bytes tools/drm/ubuntu12_64/drmtoolp | Bin 2247073 -> 2247073 bytes tools/drm/ubuntu12_64/steamdrmp.so | Bin 89162 -> 89162 bytes 46 files changed, 807 insertions(+), 374 deletions(-) create mode 100644 tools/ContentBuilder/scripts/depot_build_1002.vdf create mode 100644 tools/ContentBuilder/scripts/simple_app_build.vdf diff --git a/Readme.txt b/Readme.txt index 23b0c33..2fea78d 100644 --- a/Readme.txt +++ b/Readme.txt @@ -9,6 +9,25 @@ Welcome to the Steamworks SDK. For documentation please see our partner website at: http://partner.steamgames.com +---------------------------------------------------------------- +v1.51 8th January 2021 +---------------------------------------------------------------- +ISteamUGC +* Added GetQueryUGCNumTags(), GetQueryUGCTag(), and GetQueryUGCTagDisplayName() for access to an item's tags and the display names (e.g. localized versions) of those tags +* A previous SDK update added (but failed to call out) AddRequiredTagGroup() which allows for matching at least one tag from the group (logical "or") + +ISteamInput & ISteamController +* Added PS5 Action Origins + +ISteamFriends +* Added ActivateGameOverlayInviteDialogConnectString - Activates the game overlay to open an invite dialog that will send the provided Rich Presence connect string to selected friends + +Steamworks Example +* Updated to use latest SteamNetworkingSockets API + +Content Builder +* Updated upload example to use a single script file to upload a simple depot + ---------------------------------------------------------------- v1.50 29th August 2020 ---------------------------------------------------------------- diff --git a/SteamworksExample/Messages.h b/SteamworksExample/Messages.h index 8f7adae..47f8d6e 100644 --- a/SteamworksExample/Messages.h +++ b/SteamworksExample/Messages.h @@ -26,10 +26,8 @@ enum EMessage // Client messages k_EMsgClientBegin = 500, - k_EMsgClientInitiateConnection = k_EMsgClientBegin+1, k_EMsgClientBeginAuthentication = k_EMsgClientBegin+2, k_EMsgClientSendLocalUpdate = k_EMsgClientBegin+3, - k_EMsgClientLeavingServer = k_EMsgClientBegin+4, // P2P authentication messages k_EMsgP2PBegin = 600, @@ -126,16 +124,6 @@ private: const DWORD m_dwMessageType; }; -// Msg from client to server when trying to connect -struct MsgClientInitiateConnection_t -{ - MsgClientInitiateConnection_t() : m_dwMessageType( LittleDWord( k_EMsgClientInitiateConnection ) ) {} - DWORD GetMessageType() { return LittleDWord( m_dwMessageType ); } - -private: - const DWORD m_dwMessageType; -}; - // Msg from client to server when initiating authentication struct MsgClientBeginAuthentication_t { @@ -175,16 +163,6 @@ private: ClientSpaceWarUpdateData_t m_ClientUpdateData; }; -// Msg from the client telling the server it is about to leave -struct MsgClientLeavingServer_t -{ - MsgClientLeavingServer_t() : m_dwMessageType( LittleDWord( k_EMsgClientLeavingServer ) ) {} - DWORD GetMessageType() { return LittleDWord( m_dwMessageType ); } - -private: - const DWORD m_dwMessageType; -}; - // Message sent from one peer to another, so peers authenticate directly with each other. // (In this example, the server is responsible for relaying the messages, but peers // are directly authenticating each other.) diff --git a/SteamworksExample/SpaceWar.h b/SteamworksExample/SpaceWar.h index dcf57d8..e3daafe 100644 --- a/SteamworksExample/SpaceWar.h +++ b/SteamworksExample/SpaceWar.h @@ -32,9 +32,6 @@ // Current game server version #define SPACEWAR_SERVER_VERSION "1.0.0.0" -// UDP port for the spacewar server to do authentication on (ie, talk to Steam on) -#define SPACEWAR_AUTHENTICATION_PORT 8766 - // UDP port for the spacewar server to listen on #define SPACEWAR_SERVER_PORT 27015 diff --git a/SteamworksExample/SpaceWarClient.cpp b/SteamworksExample/SpaceWarClient.cpp index 6ea0681..2d754c2 100644 --- a/SteamworksExample/SpaceWarClient.cpp +++ b/SteamworksExample/SpaceWarClient.cpp @@ -253,9 +253,6 @@ void CSpaceWarClient::DisconnectFromServer() SteamUser()->AdvertiseGame( k_steamIDNil, 0, 0 ); #endif - MsgClientLeavingServer_t msg; - BSendServerData( &msg, sizeof(msg) ); - // tell steam china duration control system that we are no longer in a match SteamUser()->BSetDurationControlOnlineState( k_EDurationControlOnlineState_Offline ); @@ -315,7 +312,7 @@ void CSpaceWarClient::OnReceiveServerInfo( CSteamID steamIDGameServer, bool bVAC if ( msg.GetTokenLen() < 1 ) OutputDebugString( "Warning: Looks like GetAuthSessionTicket didn't give us a good ticket\n" ); - BSendServerData( &msg, sizeof(msg) ); + BSendServerData( &msg, sizeof(msg), k_nSteamNetworkingSend_Reliable ); } @@ -554,9 +551,9 @@ void CSpaceWarClient::SetConnectionFailureText( const char *pchErrorText ) //----------------------------------------------------------------------------- // Purpose: Send data to the current server //----------------------------------------------------------------------------- -bool CSpaceWarClient::BSendServerData( const void *pData, uint32 nSizeOfData ) +bool CSpaceWarClient::BSendServerData( const void *pData, uint32 nSizeOfData, int nSendFlags ) { - EResult res = SteamNetworkingSockets()->SendMessageToConnection( m_hConnServer, pData, nSizeOfData, k_nSteamNetworkingSend_UnreliableNoDelay, nullptr ); + EResult res = SteamNetworkingSockets()->SendMessageToConnection( m_hConnServer, pData, nSizeOfData, nSendFlags, nullptr ); switch (res) { case k_EResultOK: @@ -636,10 +633,6 @@ void CSpaceWarClient::InitiateServerConnection( CSteamID steamIDGameServer ) // Update when we last retried the connection, as well as the last packet received time so we won't timeout too soon, // and so we will retry at appropriate intervals if packets drop m_ulLastNetworkDataReceivedTime = m_ulLastConnectionAttemptRetryTime = m_pGameEngine->GetGameTickCount(); - - // send the packet to the server - MsgClientInitiateConnection_t msg; - BSendServerData( &msg, sizeof( msg ) ); } @@ -1760,9 +1753,12 @@ void CSpaceWarClient::RunFrame() MsgClientSendLocalUpdate_t msg; msg.SetShipPosition( m_uPlayerShipIndex ); - // If this fails, it probably just means its not time to send an update yet + // Send update as unreliable message. This means that if network packets drop, + // the networking system will not attempt retransmission, and our message may not arrive. + // That's OK, because we would rather just send a new, update message, instead of + // retransmitting the old one. if ( m_rgpShips[ m_uPlayerShipIndex ]->BGetClientUpdateData( msg.AccessUpdateData() ) ) - BSendServerData( &msg, sizeof( msg ) ); + BSendServerData( &msg, sizeof( msg ), k_nSteamNetworkingSend_Unreliable ); } if ( m_pP2PAuthedGame ) diff --git a/SteamworksExample/SpaceWarClient.h b/SteamworksExample/SpaceWarClient.h index 56b4c34..8704811 100644 --- a/SteamworksExample/SpaceWarClient.h +++ b/SteamworksExample/SpaceWarClient.h @@ -156,7 +156,7 @@ public: void InitiateServerConnection( uint32 unServerAddress, const int32 nPort ); // Send data to a client at the given ship index - bool BSendServerData( const void *pData, uint32 nSizeOfData ); + bool BSendServerData( const void *pData, uint32 nSizeOfData, int nSendFlags ); // Menu callback handler (handles a bunch of menus that just change state with no extra data) void OnMenuSelection( EClientGameState eState ) { SetGameState( eState ); } diff --git a/SteamworksExample/SpaceWarServer.cpp b/SteamworksExample/SpaceWarServer.cpp index a9d5852..763a36b 100644 --- a/SteamworksExample/SpaceWarServer.cpp +++ b/SteamworksExample/SpaceWarServer.cpp @@ -37,7 +37,7 @@ CSpaceWarServer::CSpaceWarServer( IGameEngine *pGameEngine ) // !FIXME! We need a way to pass the dedicated server flag here! - if ( !SteamGameServer_Init( unIP, SPACEWAR_AUTHENTICATION_PORT, SPACEWAR_SERVER_PORT, usMasterServerUpdaterPort, eMode, SPACEWAR_SERVER_VERSION ) ) + if ( !SteamGameServer_Init( unIP, SPACEWAR_SERVER_PORT, usMasterServerUpdaterPort, eMode, SPACEWAR_SERVER_VERSION ) ) { OutputDebugString( "SteamGameServer_Init call failed\n" ); } @@ -158,47 +158,65 @@ CSpaceWarServer::~CSpaceWarServer() void CSpaceWarServer::OnNetConnectionStatusChanged(SteamNetConnectionStatusChangedCallback_t* pCallback) { /// Connection handle - HSteamNetConnection m_hConn = pCallback->m_hConn; + HSteamNetConnection hConn = pCallback->m_hConn; /// Full connection info - SteamNetConnectionInfo_t m_info = pCallback->m_info; + SteamNetConnectionInfo_t info = pCallback->m_info; /// Previous state. (Current state is in m_info.m_eState) - ESteamNetworkingConnectionState m_eOldState = pCallback->m_eOldState; + ESteamNetworkingConnectionState eOldState = pCallback->m_eOldState; // Parse information to know what was changed // Check if a client has connected - if (m_info.m_hListenSocket && - m_eOldState == k_ESteamNetworkingConnectionState_None && - m_info.m_eState == k_ESteamNetworkingConnectionState_Connecting) + if (info.m_hListenSocket && + eOldState == k_ESteamNetworkingConnectionState_None && + info.m_eState == k_ESteamNetworkingConnectionState_Connecting) { - // Handle connecting a client - // We always accept connectiosn from clients, without even checking for room on the server, - // since we reserve that for the authentication phase of the connection which comes next. - // In production code you probably ned to remember the connection and not let it hang - // around indefinitely - EResult res = SteamGameServerNetworkingSockets()->AcceptConnection(m_hConn); + // Connection from a new client + // Search for an available slot for (uint32 i = 0; i < MAX_PLAYERS_PER_SERVER; ++i) { if (!m_rgClientData[i].m_bActive && !m_rgPendingClientData[i].m_hConn) { - m_rgPendingClientData[i].m_hConn = m_hConn; + + // Found one. "Accept" the connection. + EResult res = SteamGameServerNetworkingSockets()->AcceptConnection( hConn ); + if ( res != k_EResultOK ) + { + char msg[ 256 ]; + sprintf( msg, "AcceptConnection returned %d", res ); + OutputDebugString( msg ); + SteamGameServerNetworkingSockets()->CloseConnection( hConn, k_ESteamNetConnectionEnd_AppException_Generic, "Failed to accept connection", false ); + return; + } + + m_rgPendingClientData[i].m_hConn = hConn; + // add the user to the poll group - SteamGameServerNetworkingSockets()->SetConnectionPollGroup(m_hConn, m_hNetPollGroup); - break; + SteamGameServerNetworkingSockets()->SetConnectionPollGroup(hConn, m_hNetPollGroup); + + // Send them the server info as a reliable message + MsgServerSendInfo_t msg; + msg.SetSteamIDServer(SteamGameServer()->GetSteamID().ConvertToUint64()); + #ifdef USE_GS_AUTH_API + // You can only make use of VAC when using the Steam authentication system + msg.SetSecure(SteamGameServer()->BSecure()); + #endif + msg.SetServerName(m_sServerName.c_str()); + SteamGameServerNetworkingSockets()->SendMessageToConnection( hConn, &msg, sizeof(MsgServerSendInfo_t), k_nSteamNetworkingSend_Reliable, nullptr ); + + return; } } - if ( res != k_EResultOK ) - { - char msg[ 256 ]; - sprintf( msg, "AcceptConnection returned %d", res ); - OutputDebugString("Connection failed: Invalid Param"); - } + + // No empty slots. Server full! + OutputDebugString("Rejecting connection; server full"); + SteamGameServerNetworkingSockets()->CloseConnection( hConn, k_ESteamNetConnectionEnd_AppException_Generic, "Server full!", false ); } // Check if a client has disconnected - else if ((m_eOldState == k_ESteamNetworkingConnectionState_Connecting || m_eOldState == k_ESteamNetworkingConnectionState_Connected) && - m_info.m_eState == k_ESteamNetworkingConnectionState_ClosedByPeer) + else if ((eOldState == k_ESteamNetworkingConnectionState_Connecting || eOldState == k_ESteamNetworkingConnectionState_Connected) && + info.m_eState == k_ESteamNetworkingConnectionState_ClosedByPeer) { // Handle disconnecting a client for (uint32 i = 0; i < MAX_PLAYERS_PER_SERVER; ++i) @@ -207,7 +225,7 @@ void CSpaceWarServer::OnNetConnectionStatusChanged(SteamNetConnectionStatusChang if (!m_rgClientData[i].m_bActive) continue; - if (m_rgClientData[i].m_SteamIDUser == m_info.m_identityRemote.GetSteamID())//pCallback->m_steamIDRemote) + if (m_rgClientData[i].m_SteamIDUser == info.m_identityRemote.GetSteamID())//pCallback->m_steamIDRemote) { OutputDebugString("Disconnected dropped user\n"); RemovePlayerFromServer(i, EDisconnectReason::k_EDRClientDisconnect); @@ -554,21 +572,6 @@ void CSpaceWarServer::ReceiveNetworkData() switch (eMsg) { - case k_EMsgClientInitiateConnection: - { - // We always let clients do this without even checking for room on the server since we reserve that for - // the authentication phase of the connection which comes next - MsgServerSendInfo_t msg; - msg.SetSteamIDServer(SteamGameServer()->GetSteamID().ConvertToUint64()); -#ifdef USE_GS_AUTH_API - // You can only make use of VAC when using the Steam authentication system - msg.SetSecure(SteamGameServer()->BSecure()); -#endif - msg.SetServerName(m_sServerName.c_str()); - int64 messageOut; - SteamGameServerNetworkingSockets()->SendMessageToConnection(connection, &msg, sizeof(MsgServerSendInfo_t), k_nSteamNetworkingSend_Reliable, &messageOut); - } - break; case k_EMsgClientBeginAuthentication: { if (message->GetSize() != sizeof(MsgClientBeginAuthentication_t)) @@ -612,41 +615,6 @@ void CSpaceWarServer::ReceiveNetworkData() OutputDebugString("Got a client data update, but couldn't find a matching client\n"); } break; - case k_EMsgClientLeavingServer: - { - if (message->GetSize() != sizeof(MsgClientLeavingServer_t)) - { - OutputDebugString("Bad leaving server msg\n"); - message->Release(); - message = nullptr; - continue; - } - // Find the connection that should exist for this users address - bool bFound = false; - for (uint32 i = 0; i < MAX_PLAYERS_PER_SERVER; ++i) - { - if (m_rgClientData[i].m_SteamIDUser == steamIDRemote) - { - bFound = true; - RemovePlayerFromServer(i, EDisconnectReason::k_EDRClientDisconnect); - break; - } - - // Also check for pending connections that may match - if (m_rgPendingClientData[i].m_SteamIDUser == steamIDRemote) - { -#ifdef USE_GS_AUTH_API - // Tell the GS the user is leaving the server - SteamGameServer()->SendUserDisconnect(m_rgPendingClientData[i].m_SteamIDUser); -#endif - // Clear our data on the user - memset(&m_rgPendingClientData[i], 0, sizeof(ClientConnectionData_t)); - break; - } - } - if (!bFound) - OutputDebugString("Got a client leaving server msg, but couldn't find a matching client\n"); - } case k_EMsgVoiceChatData: { diff --git a/public/steam/isteamapplist.h b/public/steam/isteamapplist.h index 45441bb..ae018ad 100644 --- a/public/steam/isteamapplist.h +++ b/public/steam/isteamapplist.h @@ -50,7 +50,7 @@ STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamAppList *, SteamAppList, STEAMAPPLIS //--------------------------------------------------------------------------------- // Purpose: Sent when a new app is installed //--------------------------------------------------------------------------------- -STEAM_CALLBACK_BEGIN( SteamAppInstalled_t, k_iSteamAppListCallbacks + 1 ); +STEAM_CALLBACK_BEGIN( SteamAppInstalled_t, k_iSteamAppListCallbacks + 1 ) STEAM_CALLBACK_MEMBER( 0, AppId_t, m_nAppID ) // ID of the app that installs STEAM_CALLBACK_END(1) @@ -58,7 +58,7 @@ STEAM_CALLBACK_END(1) //--------------------------------------------------------------------------------- // Purpose: Sent when an app is uninstalled //--------------------------------------------------------------------------------- -STEAM_CALLBACK_BEGIN( SteamAppUninstalled_t, k_iSteamAppListCallbacks + 2 ); +STEAM_CALLBACK_BEGIN( SteamAppUninstalled_t, k_iSteamAppListCallbacks + 2 ) STEAM_CALLBACK_MEMBER( 0, AppId_t, m_nAppID ) // ID of the app that installs STEAM_CALLBACK_END(1) diff --git a/public/steam/isteamcontroller.h b/public/steam/isteamcontroller.h index c332749..2c5414b 100644 --- a/public/steam/isteamcontroller.h +++ b/public/steam/isteamcontroller.h @@ -310,6 +310,64 @@ enum EControllerActionOrigin k_EControllerActionOrigin_XBox360_DPad_Move, k_EControllerActionOrigin_Switch_DPad_Move, + // Added in SDK 1.51 + k_EControllerActionOrigin_PS5_X, + k_EControllerActionOrigin_PS5_Circle, + k_EControllerActionOrigin_PS5_Triangle, + k_EControllerActionOrigin_PS5_Square, + k_EControllerActionOrigin_PS5_LeftBumper, + k_EControllerActionOrigin_PS5_RightBumper, + k_EControllerActionOrigin_PS5_Option, //Start + k_EControllerActionOrigin_PS5_Create, //Back + k_EControllerActionOrigin_PS5_Mute, + k_EControllerActionOrigin_PS5_LeftPad_Touch, + k_EControllerActionOrigin_PS5_LeftPad_Swipe, + k_EControllerActionOrigin_PS5_LeftPad_Click, + k_EControllerActionOrigin_PS5_LeftPad_DPadNorth, + k_EControllerActionOrigin_PS5_LeftPad_DPadSouth, + k_EControllerActionOrigin_PS5_LeftPad_DPadWest, + k_EControllerActionOrigin_PS5_LeftPad_DPadEast, + k_EControllerActionOrigin_PS5_RightPad_Touch, + k_EControllerActionOrigin_PS5_RightPad_Swipe, + k_EControllerActionOrigin_PS5_RightPad_Click, + k_EControllerActionOrigin_PS5_RightPad_DPadNorth, + k_EControllerActionOrigin_PS5_RightPad_DPadSouth, + k_EControllerActionOrigin_PS5_RightPad_DPadWest, + k_EControllerActionOrigin_PS5_RightPad_DPadEast, + k_EControllerActionOrigin_PS5_CenterPad_Touch, + k_EControllerActionOrigin_PS5_CenterPad_Swipe, + k_EControllerActionOrigin_PS5_CenterPad_Click, + k_EControllerActionOrigin_PS5_CenterPad_DPadNorth, + k_EControllerActionOrigin_PS5_CenterPad_DPadSouth, + k_EControllerActionOrigin_PS5_CenterPad_DPadWest, + k_EControllerActionOrigin_PS5_CenterPad_DPadEast, + k_EControllerActionOrigin_PS5_LeftTrigger_Pull, + k_EControllerActionOrigin_PS5_LeftTrigger_Click, + k_EControllerActionOrigin_PS5_RightTrigger_Pull, + k_EControllerActionOrigin_PS5_RightTrigger_Click, + k_EControllerActionOrigin_PS5_LeftStick_Move, + k_EControllerActionOrigin_PS5_LeftStick_Click, + k_EControllerActionOrigin_PS5_LeftStick_DPadNorth, + k_EControllerActionOrigin_PS5_LeftStick_DPadSouth, + k_EControllerActionOrigin_PS5_LeftStick_DPadWest, + k_EControllerActionOrigin_PS5_LeftStick_DPadEast, + k_EControllerActionOrigin_PS5_RightStick_Move, + k_EControllerActionOrigin_PS5_RightStick_Click, + k_EControllerActionOrigin_PS5_RightStick_DPadNorth, + k_EControllerActionOrigin_PS5_RightStick_DPadSouth, + k_EControllerActionOrigin_PS5_RightStick_DPadWest, + k_EControllerActionOrigin_PS5_RightStick_DPadEast, + k_EControllerActionOrigin_PS5_DPad_Move, + k_EControllerActionOrigin_PS5_DPad_North, + k_EControllerActionOrigin_PS5_DPad_South, + k_EControllerActionOrigin_PS5_DPad_West, + k_EControllerActionOrigin_PS5_DPad_East, + k_EControllerActionOrigin_PS5_Gyro_Move, + k_EControllerActionOrigin_PS5_Gyro_Pitch, + k_EControllerActionOrigin_PS5_Gyro_Yaw, + k_EControllerActionOrigin_PS5_Gyro_Roll, + + k_EControllerActionOrigin_Count, // If Steam has added support for new controllers origins will go here. k_EControllerActionOrigin_MaximumPossibleValue = 32767, // Origins are currently a maximum of 16 bits. }; @@ -362,6 +420,7 @@ enum ESteamInputType k_ESteamInputType_SwitchProController, k_ESteamInputType_MobileTouch, // Steam Link App On-screen Virtual Controller k_ESteamInputType_PS3Controller, // Currently uses PS4 Origins + k_ESteamInputType_PS5Controller, // Added in SDK 151 k_ESteamInputType_Count, k_ESteamInputType_MaximumPossibleValue = 255, }; @@ -540,7 +599,8 @@ public: // If the user is not in Big Picture Mode it will open up the binding in a new window virtual bool ShowBindingPanel( ControllerHandle_t controllerHandle ) = 0; - // Returns the input type for a particular handle + // Returns the input type for a particular handle - unlike EControllerActionOrigin which update with Steam and may return unrecognized values + // ESteamInputType will remain static and only return valid values from your SDK version virtual ESteamInputType GetInputTypeForHandle( ControllerHandle_t controllerHandle ) = 0; // Returns the associated controller handle for the specified emulated gamepad - can be used with the above 2 functions @@ -567,7 +627,7 @@ public: virtual bool GetControllerBindingRevision( ControllerHandle_t controllerHandle, int *pMajor, int *pMinor ) = 0; }; -#define STEAMCONTROLLER_INTERFACE_VERSION "SteamController007" +#define STEAMCONTROLLER_INTERFACE_VERSION "SteamController008" // Global interface accessor inline ISteamController *SteamController(); diff --git a/public/steam/isteamfriends.h b/public/steam/isteamfriends.h index 520a67f..b7ebc73 100644 --- a/public/steam/isteamfriends.h +++ b/public/steam/isteamfriends.h @@ -358,7 +358,7 @@ public: // Rich invite support. // If the target accepts the invite, a GameRichPresenceJoinRequested_t callback is posted containing the connect string. - // (Or you can configure yout game so that it is passed on the command line instead. This is a deprecated path; ask us if you really need this.) + // (Or you can configure your game so that it is passed on the command line instead. This is a deprecated path; ask us if you really need this.) virtual bool InviteUserToGame( CSteamID steamIDFriend, const char *pchConnectString ) = 0; // recently-played-with friends iteration @@ -419,6 +419,9 @@ public: // to your specified protocol (scheme) uris and instead dispatch a OverlayBrowserProtocolNavigation_t callback to your game. // ActivateGameOverlayToWebPage() must have been called with k_EActivateGameOverlayToWebPageMode_Modal virtual bool RegisterProtocolInOverlayBrowser( const char *pchProtocol ) = 0; + + // Activates the game overlay to open an invite dialog that will send the provided Rich Presence connect string to selected friends + virtual void ActivateGameOverlayInviteDialogConnectString( const char *pchConnectString ) = 0; }; #define STEAMFRIENDS_INTERFACE_VERSION "SteamFriends017" diff --git a/public/steam/isteamgameserver.h b/public/steam/isteamgameserver.h index 8fbd9da..612ef3d 100644 --- a/public/steam/isteamgameserver.h +++ b/public/steam/isteamgameserver.h @@ -12,8 +12,6 @@ #include "steam_api_common.h" -#define MASTERSERVERUPDATERPORT_USEGAMESOCKETSHARE ((uint16)-1) - //----------------------------------------------------------------------------- // Purpose: Functions for authenticating users via Steam to play on a game server //----------------------------------------------------------------------------- @@ -256,19 +254,6 @@ public: inline ISteamGameServer *SteamGameServer(); STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( ISteamGameServer *, SteamGameServer, STEAMGAMESERVER_INTERFACE_VERSION ); -// game server flags -const uint32 k_unServerFlagNone = 0x00; -const uint32 k_unServerFlagActive = 0x01; // server has users playing -const uint32 k_unServerFlagSecure = 0x02; // server wants to be secure -const uint32 k_unServerFlagDedicated = 0x04; // server is dedicated -const uint32 k_unServerFlagLinux = 0x08; // linux build -const uint32 k_unServerFlagPassworded = 0x10; // password protected -const uint32 k_unServerFlagPrivate = 0x20; // server shouldn't list on master server and - // won't enforce authentication of users that connect to the server. - // Useful when you run a server where the clients may not - // be connected to the internet but you want them to play (i.e LANs) - - // callbacks #if defined( VALVE_CALLBACK_PACK_SMALL ) #pragma pack( push, 4 ) diff --git a/public/steam/isteaminput.h b/public/steam/isteaminput.h index 84f1b14..66c385b 100644 --- a/public/steam/isteaminput.h +++ b/public/steam/isteaminput.h @@ -329,6 +329,83 @@ enum EInputActionOrigin k_EInputActionOrigin_Switch_Reserved18, k_EInputActionOrigin_Switch_Reserved19, k_EInputActionOrigin_Switch_Reserved20, + + // Added in SDK 1.51 + k_EInputActionOrigin_PS5_X, + k_EInputActionOrigin_PS5_Circle, + k_EInputActionOrigin_PS5_Triangle, + k_EInputActionOrigin_PS5_Square, + k_EInputActionOrigin_PS5_LeftBumper, + k_EInputActionOrigin_PS5_RightBumper, + k_EInputActionOrigin_PS5_Option, //Start + k_EInputActionOrigin_PS5_Create, //Back + k_EInputActionOrigin_PS5_Mute, + k_EInputActionOrigin_PS5_LeftPad_Touch, + k_EInputActionOrigin_PS5_LeftPad_Swipe, + k_EInputActionOrigin_PS5_LeftPad_Click, + k_EInputActionOrigin_PS5_LeftPad_DPadNorth, + k_EInputActionOrigin_PS5_LeftPad_DPadSouth, + k_EInputActionOrigin_PS5_LeftPad_DPadWest, + k_EInputActionOrigin_PS5_LeftPad_DPadEast, + k_EInputActionOrigin_PS5_RightPad_Touch, + k_EInputActionOrigin_PS5_RightPad_Swipe, + k_EInputActionOrigin_PS5_RightPad_Click, + k_EInputActionOrigin_PS5_RightPad_DPadNorth, + k_EInputActionOrigin_PS5_RightPad_DPadSouth, + k_EInputActionOrigin_PS5_RightPad_DPadWest, + k_EInputActionOrigin_PS5_RightPad_DPadEast, + k_EInputActionOrigin_PS5_CenterPad_Touch, + k_EInputActionOrigin_PS5_CenterPad_Swipe, + k_EInputActionOrigin_PS5_CenterPad_Click, + k_EInputActionOrigin_PS5_CenterPad_DPadNorth, + k_EInputActionOrigin_PS5_CenterPad_DPadSouth, + k_EInputActionOrigin_PS5_CenterPad_DPadWest, + k_EInputActionOrigin_PS5_CenterPad_DPadEast, + k_EInputActionOrigin_PS5_LeftTrigger_Pull, + k_EInputActionOrigin_PS5_LeftTrigger_Click, + k_EInputActionOrigin_PS5_RightTrigger_Pull, + k_EInputActionOrigin_PS5_RightTrigger_Click, + k_EInputActionOrigin_PS5_LeftStick_Move, + k_EInputActionOrigin_PS5_LeftStick_Click, + k_EInputActionOrigin_PS5_LeftStick_DPadNorth, + k_EInputActionOrigin_PS5_LeftStick_DPadSouth, + k_EInputActionOrigin_PS5_LeftStick_DPadWest, + k_EInputActionOrigin_PS5_LeftStick_DPadEast, + k_EInputActionOrigin_PS5_RightStick_Move, + k_EInputActionOrigin_PS5_RightStick_Click, + k_EInputActionOrigin_PS5_RightStick_DPadNorth, + k_EInputActionOrigin_PS5_RightStick_DPadSouth, + k_EInputActionOrigin_PS5_RightStick_DPadWest, + k_EInputActionOrigin_PS5_RightStick_DPadEast, + k_EInputActionOrigin_PS5_DPad_North, + k_EInputActionOrigin_PS5_DPad_South, + k_EInputActionOrigin_PS5_DPad_West, + k_EInputActionOrigin_PS5_DPad_East, + k_EInputActionOrigin_PS5_Gyro_Move, + k_EInputActionOrigin_PS5_Gyro_Pitch, + k_EInputActionOrigin_PS5_Gyro_Yaw, + k_EInputActionOrigin_PS5_Gyro_Roll, + k_EInputActionOrigin_PS5_DPad_Move, + k_EInputActionOrigin_PS5_Reserved1, + k_EInputActionOrigin_PS5_Reserved2, + k_EInputActionOrigin_PS5_Reserved3, + k_EInputActionOrigin_PS5_Reserved4, + k_EInputActionOrigin_PS5_Reserved5, + k_EInputActionOrigin_PS5_Reserved6, + k_EInputActionOrigin_PS5_Reserved7, + k_EInputActionOrigin_PS5_Reserved8, + k_EInputActionOrigin_PS5_Reserved9, + k_EInputActionOrigin_PS5_Reserved10, + k_EInputActionOrigin_PS5_Reserved11, + k_EInputActionOrigin_PS5_Reserved12, + k_EInputActionOrigin_PS5_Reserved13, + k_EInputActionOrigin_PS5_Reserved14, + k_EInputActionOrigin_PS5_Reserved15, + k_EInputActionOrigin_PS5_Reserved16, + k_EInputActionOrigin_PS5_Reserved17, + k_EInputActionOrigin_PS5_Reserved18, + k_EInputActionOrigin_PS5_Reserved19, + k_EInputActionOrigin_PS5_Reserved20, k_EInputActionOrigin_Count, // If Steam has added support for new controllers origins will go here. k_EInputActionOrigin_MaximumPossibleValue = 32767, // Origins are currently a maximum of 16 bits. @@ -388,6 +465,7 @@ enum ESteamInputType k_ESteamInputType_SwitchProController, k_ESteamInputType_MobileTouch, // Steam Link App On-screen Virtual Controller k_ESteamInputType_PS3Controller, // Currently uses PS4 Origins + k_ESteamInputType_PS5Controller, // Added in SDK 151 k_ESteamInputType_Count, k_ESteamInputType_MaximumPossibleValue = 255, }; @@ -567,7 +645,8 @@ public: // If the user is not in Big Picture Mode it will open up the binding in a new window virtual bool ShowBindingPanel( InputHandle_t inputHandle ) = 0; - // Returns the input type for a particular handle + // Returns the input type for a particular handle - unlike EInputActionOrigin which update with Steam and may return unrecognized values + // ESteamInputType will remain static and only return valid values from your SDK version virtual ESteamInputType GetInputTypeForHandle( InputHandle_t inputHandle ) = 0; // Returns the associated controller handle for the specified emulated gamepad - can be used with the above 2 functions @@ -600,10 +679,10 @@ public: virtual uint32 GetRemotePlaySessionID( InputHandle_t inputHandle ) = 0; }; -#define STEAMINPUT_INTERFACE_VERSION "SteamInput001" +#define STEAMINPUT_INTERFACE_VERSION "SteamInput002" // Global interface accessor inline ISteamInput *SteamInput(); STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamInput *, SteamInput, STEAMINPUT_INTERFACE_VERSION ); -#endif // ISTEAMINPUT_H +#endif // ISTEAMINPUT_H \ No newline at end of file diff --git a/public/steam/isteamnetworking.h b/public/steam/isteamnetworking.h index 2f14d27..b7e077a 100644 --- a/public/steam/isteamnetworking.h +++ b/public/steam/isteamnetworking.h @@ -17,12 +17,16 @@ enum EP2PSessionError { k_EP2PSessionErrorNone = 0, - k_EP2PSessionErrorNotRunningApp = 1, // target is not running the same game k_EP2PSessionErrorNoRightsToApp = 2, // local user doesn't own the app that is running - k_EP2PSessionErrorDestinationNotLoggedIn = 3, // target user isn't connected to Steam k_EP2PSessionErrorTimeout = 4, // target isn't responding, perhaps not calling AcceptP2PSessionWithUser() // corporate firewalls can also block this (NAT traversal is not firewall traversal) // make sure that UDP ports 3478, 4379, and 4380 are open in an outbound direction + + // The following error codes were removed and will never be sent. + // For privacy reasons, there is no reply if the user is offline or playing another game. + k_EP2PSessionErrorNotRunningApp_DELETED = 1, + k_EP2PSessionErrorDestinationNotLoggedIn_DELETED = 3, + k_EP2PSessionErrorMax = 5 }; diff --git a/public/steam/isteamnetworkingmessages.h b/public/steam/isteamnetworkingmessages.h index a23a386..a12a32f 100644 --- a/public/steam/isteamnetworkingmessages.h +++ b/public/steam/isteamnetworkingmessages.h @@ -5,6 +5,7 @@ #pragma once #include "steamnetworkingtypes.h" +#include "steam_api_common.h" //----------------------------------------------------------------------------- /// The non-connection-oriented interface to send and receive messages @@ -56,7 +57,7 @@ public: /// /// It is guaranteed that reliable messages to the same host on the same channel /// will be be received by the remote host (if they are received at all) exactly once, - /// and in the same order that they were send. + /// and in the same order that they were sent. /// /// NO other order guarantees exist! In particular, unreliable messages may be dropped, /// received out of order with respect to each other and with respect to reliable data, @@ -73,52 +74,55 @@ public: /// Returns: /// - k_EREsultOK on success. /// - k_EResultNoConnection will be returned if the session has failed or was closed by the peer, - /// and k_nSteamNetworkingSend_AutoRestartBrokwnSession is not used. (You can use + /// and k_nSteamNetworkingSend_AutoRestartBrokenSession is not used. (You can use /// GetSessionConnectionInfo to get the details.) In order to acknowledge the broken session /// and start a new one, you must call CloseSessionWithUser - /// - See SendMessageToConnection::SendMessageToConnection for more + /// - See ISteamNetworkingSockets::SendMessageToConnection for more possible return values virtual EResult SendMessageToUser( const SteamNetworkingIdentity &identityRemote, const void *pubData, uint32 cubData, int nSendFlags, int nRemoteChannel ) = 0; /// Reads the next message that has been sent from another user via SendMessageToUser() on the given channel. /// Returns number of messages returned into your list. (0 if no message are available on that channel.) /// - /// When you're done with the message object(s), make sure and call Release()! + /// When you're done with the message object(s), make sure and call SteamNetworkingMessage_t::Release()! virtual int ReceiveMessagesOnChannel( int nLocalChannel, SteamNetworkingMessage_t **ppOutMessages, int nMaxMessages ) = 0; - /// AcceptSessionWithUser() should only be called in response to a SteamP2PSessionRequest_t callback - /// SteamP2PSessionRequest_t will be posted if another user tries to send you a message, and you haven't - /// tried to talk to them. If you don't want to talk to them, just ignore the request. - /// If the user continues to send you messages, SteamP2PSessionRequest_t callbacks will continue to - /// be posted periodically. This may be called multiple times for a single user. + /// Call this in response to a SteamNetworkingMessagesSessionRequest_t callback. + /// SteamNetworkingMessagesSessionRequest_t are posted when a user tries to send you a message, + /// and you haven't tried to talk to them first. If you don't want to talk to them, just ignore + /// the request. If the user continues to send you messages, SteamNetworkingMessagesSessionRequest_t + /// callbacks will continue to be posted periodically. /// - /// Calling SendMessage() on the other user, this implicitly accepts any pending session request. + /// Returns false if there is no session with the user pending or otherwise. If there is an + /// existing active session, this function will return true, even if it is not pending. + /// + /// Calling SendMessageToUser() will implicitly accepts any pending session request to that user. virtual bool AcceptSessionWithUser( const SteamNetworkingIdentity &identityRemote ) = 0; /// Call this when you're done talking to a user to immediately free up resources under-the-hood. - /// If the remote user tries to send data to you again, another P2PSessionRequest_t callback will - /// be posted. + /// If the remote user tries to send data to you again, another SteamNetworkingMessagesSessionRequest_t + /// callback will be posted. /// /// Note that sessions that go unused for a few minutes are automatically timed out. virtual bool CloseSessionWithUser( const SteamNetworkingIdentity &identityRemote ) = 0; /// Call this when you're done talking to a user on a specific channel. Once all /// open channels to a user have been closed, the open session to the user will be - /// closed, and any new data from this user will trigger a SteamP2PSessionRequest_t - /// callback + /// closed, and any new data from this user will trigger a + /// SteamSteamNetworkingMessagesSessionRequest_t callback virtual bool CloseChannelWithUser( const SteamNetworkingIdentity &identityRemote, int nLocalChannel ) = 0; /// Returns information about the latest state of a connection, if any, with the given peer. /// Primarily intended for debugging purposes, but can also be used to get more detailed - /// failure information. (See SendMessageToUser and k_nSteamNetworkingSend_AutoRestartBrokwnSession.) + /// failure information. (See SendMessageToUser and k_nSteamNetworkingSend_AutoRestartBrokenSession.) /// /// Returns the value of SteamNetConnectionInfo_t::m_eState, or k_ESteamNetworkingConnectionState_None /// if no connection exists with specified peer. You may pass nullptr for either parameter if /// you do not need the corresponding details. Note that sessions time out after a while, - /// so if a connection fails, or SendMessageToUser returns SendMessageToUser, you cannot wait + /// so if a connection fails, or SendMessageToUser returns k_EResultNoConnection, you cannot wait /// indefinitely to obtain the reason for failure. virtual ESteamNetworkingConnectionState GetSessionConnectionInfo( const SteamNetworkingIdentity &identityRemote, SteamNetConnectionInfo_t *pConnectionInfo, SteamNetworkingQuickConnectionStatus *pQuickStatus ) = 0; }; -#define STEAMNETWORKINGMESSAGES_VERSION "SteamNetworkingMessages002" +#define STEAMNETWORKINGMESSAGES_INTERFACE_VERSION "SteamNetworkingMessages002" // // Callbacks @@ -139,7 +143,7 @@ struct SteamNetworkingMessagesSessionRequest_t /// SteamNetworkingMessages is primarily intended to make porting UDP code easy.) /// /// Remember: callbacks are asynchronous. See notes on SendMessageToUser, -/// and k_nSteamNetworkingSend_AutoRestartBrokwnSession in particular. +/// and k_nSteamNetworkingSend_AutoRestartBrokenSession in particular. /// /// Also, if a session times out due to inactivity, no callbacks will be posted. The only /// way to detect that this is happening is that querying the session state may return @@ -148,37 +152,48 @@ struct SteamNetworkingMessagesSessionFailed_t { enum { k_iCallback = k_iSteamNetworkingMessagesCallbacks + 2 }; - /// Detailed info about the connection. This will include the + /// Detailed info about the session that failed. + /// SteamNetConnectionInfo_t::m_identityRemote indicates who this session + /// was with. SteamNetConnectionInfo_t m_info; }; #pragma pack(pop) -// -// Global accessor -// +// Global accessors +// Using standalone lib +#ifdef STEAMNETWORKINGSOCKETS_STANDALONELIB -#if defined( STEAMNETWORKINGSOCKETS_PARTNER ) + // Standalone lib. + static_assert( STEAMNETWORKINGMESSAGES_INTERFACE_VERSION[25] == '2', "Version mismatch" ); + STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingMessages *SteamNetworkingMessages_LibV2(); + inline ISteamNetworkingMessages *SteamNetworkingMessages_Lib() { return SteamNetworkingMessages_LibV2(); } - // Standalone lib. Use different symbol name, so that we can dynamically switch between steamclient.dll - // and the standalone lib - STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingMessages *SteamNetworkingMessages_Lib(); - STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingMessages *SteamGameServerNetworkingMessages_Lib(); - inline ISteamNetworkingMessages *SteamNetworkingMessages() { return SteamNetworkingMessages_Lib(); } - inline ISteamNetworkingMessages *SteamGameServerNetworkingMessages() { return SteamGameServerNetworkingMessages_Lib(); } + // If running in context of steam, we also define a gameserver instance. + #ifdef STEAMNETWORKINGSOCKETS_STEAM + STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingMessages *SteamGameServerNetworkingMessages_LibV2(); + inline ISteamNetworkingMessages *SteamGameServerNetworkingMessages_Lib() { return SteamGameServerNetworkingMessages_LibV2(); } + #endif -#elif defined( STEAMNETWORKINGSOCKETS_OPENSOURCE ) + #ifndef STEAMNETWORKINGSOCKETS_STEAMAPI + inline ISteamNetworkingMessages *SteamNetworkingMessages() { return SteamNetworkingMessages_LibV2(); } + #ifdef STEAMNETWORKINGSOCKETS_STEAM + inline ISteamNetworkingMessages *SteamGameServerNetworkingMessages() { return SteamGameServerNetworkingMessages_LibV2(); } + #endif + #endif +#endif - // Opensource GameNetworkingSockets - STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingMessages *SteamNetworkingMessages(); - -#else +// Using Steamworks SDK +#ifdef STEAMNETWORKINGSOCKETS_STEAMAPI // Steamworks SDK - inline ISteamNetworkingMessages *SteamNetworkingMessages(); - STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamNetworkingMessages *, SteamNetworkingMessages, STEAMNETWORKINGMESSAGES_VERSION ); - inline ISteamNetworkingMessages *SteamGameServerNetworkingMessages(); - STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( ISteamNetworkingMessages *, SteamGameServerNetworkingMessages, STEAMNETWORKINGMESSAGES_VERSION ); + STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamNetworkingMessages *, SteamNetworkingMessages_SteamAPI, STEAMNETWORKINGMESSAGES_INTERFACE_VERSION ); + STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( ISteamNetworkingMessages *, SteamGameServerNetworkingMessages_SteamAPI, STEAMNETWORKINGMESSAGES_INTERFACE_VERSION ); + + #ifndef STEAMNETWORKINGSOCKETS_STANDALONELIB + inline ISteamNetworkingMessages *SteamNetworkingMessages() { return SteamNetworkingMessages_SteamAPI(); } + inline ISteamNetworkingMessages *SteamGameServerNetworkingMessages() { return SteamGameServerNetworkingMessages_SteamAPI(); } + #endif #endif #endif // ISTEAMNETWORKINGMESSAGES diff --git a/public/steam/isteamnetworkingsockets.h b/public/steam/isteamnetworkingsockets.h index 904ec4b..685edcd 100644 --- a/public/steam/isteamnetworkingsockets.h +++ b/public/steam/isteamnetworkingsockets.h @@ -2,15 +2,14 @@ #ifndef ISTEAMNETWORKINGSOCKETS #define ISTEAMNETWORKINGSOCKETS -#ifdef _WIN32 #pragma once -#endif #include "steamnetworkingtypes.h" +#include "steam_api_common.h" struct SteamNetAuthenticationStatus_t; -class ISteamNetworkingConnectionCustomSignaling; -class ISteamNetworkingCustomSignalingRecvContext; +class ISteamNetworkingConnectionSignaling; +class ISteamNetworkingSignalingRecvContext; //----------------------------------------------------------------------------- /// Lower level networking API. @@ -84,7 +83,7 @@ public: /// setting the options "immediately" after creation. virtual HSteamNetConnection ConnectByIPAddress( const SteamNetworkingIPAddr &address, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; - /// Like CreateListenSocketIP, but clients will connect using ConnectP2P + /// Like CreateListenSocketIP, but clients will connect using ConnectP2P. /// /// nLocalVirtualPort specifies how clients can connect to this socket using /// ConnectP2P. It's very common for applications to only have one listening socket; @@ -93,7 +92,16 @@ public: /// integer (<1000) unique to each listen socket you create. /// /// If you use this, you probably want to call ISteamNetworkingUtils::InitRelayNetworkAccess() - /// when your app initializes + /// when your app initializes. + /// + /// If you are listening on a dedicated servers in known data center, + /// then you can listen using this function instead of CreateHostedDedicatedServerListenSocket, + /// to allow clients to connect without a ticket. Any user that owns + /// the app and is signed into Steam will be able to attempt to connect to + /// your server. Also, a connection attempt may require the client to + /// be connected to Steam, which is one more moving part that may fail. When + /// tickets are used, then once a ticket is obtained, a client can connect to + /// your server even if they got disconnected from Steam or Steam is offline. /// /// If you need to set any initial config options, pass them here. See /// SteamNetworkingConfigValue_t for more about why this is preferable to @@ -107,6 +115,10 @@ public: /// If you need to set any initial config options, pass them here. See /// SteamNetworkingConfigValue_t for more about why this is preferable to /// setting the options "immediately" after creation. + /// + /// To use your own signaling service, see: + /// - ConnectP2PCustomSignaling + /// - k_ESteamNetworkingConfig_Callback_CreateConnectionSignaling virtual HSteamNetConnection ConnectP2P( const SteamNetworkingIdentity &identityRemote, int nRemoteVirtualPort, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; /// Accept an incoming connection that has been received on a listen socket. @@ -437,11 +449,11 @@ public: /// other connections.) virtual int ReceiveMessagesOnPollGroup( HSteamNetPollGroup hPollGroup, SteamNetworkingMessage_t **ppOutMessages, int nMaxMessages ) = 0; -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR - // // Clients connecting to dedicated servers hosted in a data center, - // using central-authority-granted tickets. + // using tickets issued by your game coordinator. If you are not + // issuing your own tickets to restrict who can attempt to connect + // to your server, then you won't use these functions. // /// Call this when you receive a ticket from your backend / matchmaking system. Puts the @@ -459,7 +471,10 @@ public: virtual int FindRelayAuthTicketForServer( const SteamNetworkingIdentity &identityGameServer, int nRemoteVirtualPort, SteamDatagramRelayAuthTicket *pOutParsedTicket ) = 0; /// Client call to connect to a server hosted in a Valve data center, on the specified virtual - /// port. You must have placed a ticket for this server into the cache, or else this connect attempt will fail! + /// port. You must have placed a ticket for this server into the cache, or else this connect + /// attempt will fail! If you are not issuing your own tickets, then to connect to a dedicated + /// server via SDR in auto-ticket mode, use ConnectP2P. (The server must be configured to allow + /// this type of connection by listening using CreateListenSocketP2P.) /// /// You may wonder why tickets are stored in a cache, instead of simply being passed as an argument /// here. The reason is to make reconnection to a gameserver robust, even if the client computer loses @@ -522,7 +537,11 @@ public: /// will be determined by the SDR_LISTEN_PORT environment variable. If a UDP port is not /// configured, this call will fail. /// - /// Note that this call MUST be made through the SteamGameServerNetworkingSockets() interface + /// This call MUST be made through the SteamGameServerNetworkingSockets() interface. + /// + /// This function should be used when you are using the ticket generator library + /// to issue your own tickets. Clients connecting to the server on this virtual + /// port will need a ticket, and they must connect using ConnectToHostedDedicatedServer. /// /// If you need to set any initial config options, pass them here. See /// SteamNetworkingConfigValue_t for more about why this is preferable to @@ -560,7 +579,6 @@ public: /// NOTE: The routing blob returned here is not encrypted. Send it to your backend /// and don't share it directly with clients. virtual EResult GetGameCoordinatorServerLogin( SteamDatagramGameCoordinatorServerLogin *pLoginInfo, int *pcbSignedBlob, void *pBlob ) = 0; -#endif // #ifndef STEAMNETWORKINGSOCKETS_ENABLE_SDR // @@ -585,10 +603,10 @@ public: /// This function will immediately construct a connection in the "connecting" /// state. Soon after (perhaps before this function returns, perhaps in another thread), /// the connection will begin sending signaling messages by calling - /// ISteamNetworkingConnectionCustomSignaling::SendSignal. + /// ISteamNetworkingConnectionSignaling::SendSignal. /// /// When the remote peer accepts the connection (See - /// ISteamNetworkingCustomSignalingRecvContext::OnConnectRequest), + /// ISteamNetworkingSignalingRecvContext::OnConnectRequest), /// it will begin sending signaling messages. When these messages are received, /// you can pass them to the connection using ReceivedP2PCustomSignal. /// @@ -603,7 +621,7 @@ public: /// If you need to set any initial config options, pass them here. See /// SteamNetworkingConfigValue_t for more about why this is preferable to /// setting the options "immediately" after creation. - virtual HSteamNetConnection ConnectP2PCustomSignaling( ISteamNetworkingConnectionCustomSignaling *pSignaling, const SteamNetworkingIdentity *pPeerIdentity, int nRemoteVirtualPort, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; + virtual HSteamNetConnection ConnectP2PCustomSignaling( ISteamNetworkingConnectionSignaling *pSignaling, const SteamNetworkingIdentity *pPeerIdentity, int nRemoteVirtualPort, int nOptions, const SteamNetworkingConfigValue_t *pOptions ) = 0; /// Called when custom signaling has received a message. When your /// signaling channel receives a message, it should save off whatever @@ -614,7 +632,7 @@ public: /// /// - If the signal is associated with existing connection, it is dealt /// with immediately. If any replies need to be sent, they will be - /// dispatched using the ISteamNetworkingConnectionCustomSignaling + /// dispatched using the ISteamNetworkingConnectionSignaling /// associated with the connection. /// - If the message represents a connection request (and the request /// is not redundant for an existing connection), a new connection @@ -634,7 +652,7 @@ public: /// /// If you expect to be using relayed connections, then you probably want /// to call ISteamNetworkingUtils::InitRelayNetworkAccess() when your app initializes - virtual bool ReceivedP2PCustomSignal( const void *pMsg, int cbMsg, ISteamNetworkingCustomSignalingRecvContext *pContext ) = 0; + virtual bool ReceivedP2PCustomSignal( const void *pMsg, int cbMsg, ISteamNetworkingSignalingRecvContext *pContext ) = 0; // // Certificate provision by the application. On Steam, we normally handle all this automatically @@ -664,28 +682,40 @@ protected: }; #define STEAMNETWORKINGSOCKETS_INTERFACE_VERSION "SteamNetworkingSockets009" -// Global accessor. -#if defined( STEAMNETWORKINGSOCKETS_PARTNER ) +// Global accessors +// Using standalone lib +#ifdef STEAMNETWORKINGSOCKETS_STANDALONELIB - // Standalone lib. Use different symbol name, so that we can dynamically switch between steamclient.dll - // and the standalone lib - STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingSockets *SteamNetworkingSockets_Lib(); - STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingSockets *SteamGameServerNetworkingSockets_Lib(); - inline ISteamNetworkingSockets *SteamNetworkingSockets() { return SteamNetworkingSockets_Lib(); } - inline ISteamNetworkingSockets *SteamGameServerNetworkingSockets() { return SteamGameServerNetworkingSockets_Lib(); } + // Standalone lib. + static_assert( STEAMNETWORKINGSOCKETS_INTERFACE_VERSION[24] == '9', "Version mismatch" ); + STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingSockets *SteamNetworkingSockets_LibV9(); + inline ISteamNetworkingSockets *SteamNetworkingSockets_Lib() { return SteamNetworkingSockets_LibV9(); } -#elif defined( STEAMNETWORKINGSOCKETS_OPENSOURCE ) || defined( STEAMNETWORKINGSOCKETS_STREAMINGCLIENT ) + // If running in context of steam, we also define a gameserver instance. + #ifdef STEAMNETWORKINGSOCKETS_STEAM + STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingSockets *SteamGameServerNetworkingSockets_LibV9(); + inline ISteamNetworkingSockets *SteamGameServerNetworkingSockets_Lib() { return SteamGameServerNetworkingSockets_LibV9(); } + #endif - // Opensource GameNetworkingSockets - STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingSockets *SteamNetworkingSockets(); + #ifndef STEAMNETWORKINGSOCKETS_STEAMAPI + inline ISteamNetworkingSockets *SteamNetworkingSockets() { return SteamNetworkingSockets_LibV9(); } + #ifdef STEAMNETWORKINGSOCKETS_STEAM + inline ISteamNetworkingSockets *SteamGameServerNetworkingSockets() { return SteamGameServerNetworkingSockets_LibV9(); } + #endif + #endif +#endif -#else +// Using Steamworks SDK +#ifdef STEAMNETWORKINGSOCKETS_STEAMAPI // Steamworks SDK - inline ISteamNetworkingSockets *SteamNetworkingSockets(); - STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamNetworkingSockets *, SteamNetworkingSockets, STEAMNETWORKINGSOCKETS_INTERFACE_VERSION ); - inline ISteamNetworkingSockets *SteamGameServerNetworkingSockets(); - STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( ISteamNetworkingSockets *, SteamGameServerNetworkingSockets, STEAMNETWORKINGSOCKETS_INTERFACE_VERSION ); + STEAM_DEFINE_USER_INTERFACE_ACCESSOR( ISteamNetworkingSockets *, SteamNetworkingSockets_SteamAPI, STEAMNETWORKINGSOCKETS_INTERFACE_VERSION ); + STEAM_DEFINE_GAMESERVER_INTERFACE_ACCESSOR( ISteamNetworkingSockets *, SteamGameServerNetworkingSockets_SteamAPI, STEAMNETWORKINGSOCKETS_INTERFACE_VERSION ); + + #ifndef STEAMNETWORKINGSOCKETS_STANDALONELIB + inline ISteamNetworkingSockets *SteamNetworkingSockets() { return SteamNetworkingSockets_SteamAPI(); } + inline ISteamNetworkingSockets *SteamGameServerNetworkingSockets() { return SteamGameServerNetworkingSockets_SteamAPI(); } + #endif #endif /// Callback struct used to notify when a connection has changed state diff --git a/public/steam/isteamnetworkingutils.h b/public/steam/isteamnetworkingutils.h index 0f15f73..2161ec3 100644 --- a/public/steam/isteamnetworkingutils.h +++ b/public/steam/isteamnetworkingutils.h @@ -6,13 +6,11 @@ #ifndef ISTEAMNETWORKINGUTILS #define ISTEAMNETWORKINGUTILS -#ifdef _WIN32 #pragma once -#endif - -#include #include "steamnetworkingtypes.h" +#include "steam_api_common.h" + struct SteamDatagramRelayAuthTicket; struct SteamRelayNetworkStatus_t; @@ -46,8 +44,6 @@ public: // Access to Steam Datagram Relay (SDR) network // -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR - // // Initialization and status check // @@ -196,7 +192,6 @@ public: /// Get list of all POP IDs. Returns the number of entries that were filled into /// your list. virtual int GetPOPList( SteamNetworkingPOPID *list, int nListSz ) = 0; -#endif // #ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR // // Misc @@ -324,18 +319,23 @@ protected: }; #define STEAMNETWORKINGUTILS_INTERFACE_VERSION "SteamNetworkingUtils003" -// Global accessor. +// Global accessors +// Using standalone lib #ifdef STEAMNETWORKINGSOCKETS_STANDALONELIB // Standalone lib - STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingUtils *SteamNetworkingUtils_Lib(); - inline ISteamNetworkingUtils *SteamNetworkingUtils() { return SteamNetworkingUtils_Lib(); } + static_assert( STEAMNETWORKINGUTILS_INTERFACE_VERSION[22] == '3', "Version mismatch" ); + STEAMNETWORKINGSOCKETS_INTERFACE ISteamNetworkingUtils *SteamNetworkingUtils_LibV3(); + inline ISteamNetworkingUtils *SteamNetworkingUtils_Lib() { return SteamNetworkingUtils_LibV3(); } -#else + #ifndef STEAMNETWORKINGSOCKETS_STEAMAPI + inline ISteamNetworkingUtils *SteamNetworkingUtils() { return SteamNetworkingUtils_LibV3(); } + #endif +#endif - // Steamworks SDK - inline ISteamNetworkingUtils *SteamNetworkingUtils(); - STEAM_DEFINE_INTERFACE_ACCESSOR( ISteamNetworkingUtils *, SteamNetworkingUtils, +// Using Steamworks SDK +#ifdef STEAMNETWORKINGSOCKETS_STEAMAPI + STEAM_DEFINE_INTERFACE_ACCESSOR( ISteamNetworkingUtils *, SteamNetworkingUtils_SteamAPI, /* Prefer user version of the interface. But if it isn't found, then use gameserver one. Yes, this is a completely terrible hack */ SteamInternal_FindOrCreateUserInterface( 0, STEAMNETWORKINGUTILS_INTERFACE_VERSION ) ? @@ -344,6 +344,10 @@ protected: "global", STEAMNETWORKINGUTILS_INTERFACE_VERSION ) + + #ifndef STEAMNETWORKINGSOCKETS_STANDALONELIB + inline ISteamNetworkingUtils *SteamNetworkingUtils() { return SteamNetworkingUtils_SteamAPI(); } + #endif #endif /// A struct used to describe our readiness to use the relay network. @@ -404,10 +408,7 @@ private: // // Internal stuff -#ifdef STEAMNETWORKINGSOCKETS_ENABLE_SDR inline void ISteamNetworkingUtils::InitRelayNetworkAccess() { CheckPingDataUpToDate( 1e10f ); } -#endif - inline bool ISteamNetworkingUtils::SetGlobalConfigValueInt32( ESteamNetworkingConfigValue eValue, int32 val ) { return SetConfigValue( eValue, k_ESteamNetworkingConfig_Global, 0, k_ESteamNetworkingConfig_Int32, &val ); } inline bool ISteamNetworkingUtils::SetGlobalConfigValueFloat( ESteamNetworkingConfigValue eValue, float val ) { return SetConfigValue( eValue, k_ESteamNetworkingConfig_Global, 0, k_ESteamNetworkingConfig_Float, &val ); } inline bool ISteamNetworkingUtils::SetGlobalConfigValueString( ESteamNetworkingConfigValue eValue, const char *val ) { return SetConfigValue( eValue, k_ESteamNetworkingConfig_Global, 0, k_ESteamNetworkingConfig_String, val ); } @@ -431,11 +432,27 @@ inline bool ISteamNetworkingUtils::SetConfigValueStruct( const SteamNetworkingCo return SetConfigValue( opt.m_eValue, eScopeType, scopeObj, opt.m_eDataType, pVal ); } -#if !defined( STEAMNETWORKINGSOCKETS_STATIC_LINK ) && defined( STEAMNETWORKINGSOCKETS_STEAMCLIENT ) -inline void SteamNetworkingIPAddr::ToString( char *buf, size_t cbBuf, bool bWithPort ) const { SteamNetworkingUtils()->SteamNetworkingIPAddr_ToString( *this, buf, cbBuf, bWithPort ); } -inline bool SteamNetworkingIPAddr::ParseString( const char *pszStr ) { return SteamNetworkingUtils()->SteamNetworkingIPAddr_ParseString( this, pszStr ); } -inline void SteamNetworkingIdentity::ToString( char *buf, size_t cbBuf ) const { SteamNetworkingUtils()->SteamNetworkingIdentity_ToString( *this, buf, cbBuf ); } -inline bool SteamNetworkingIdentity::ParseString( const char *pszStr ) { return SteamNetworkingUtils()->SteamNetworkingIdentity_ParseString( this, pszStr ); } +// How to get helper functions. +#if defined( STEAMNETWORKINGSOCKETS_STATIC_LINK ) || defined( STEAMNETWORKINGSOCKETS_STANDALONELIB ) + + // Call direct to static functions + STEAMNETWORKINGSOCKETS_INTERFACE void SteamNetworkingIPAddr_ToString( const SteamNetworkingIPAddr *pAddr, char *buf, size_t cbBuf, bool bWithPort ); + STEAMNETWORKINGSOCKETS_INTERFACE bool SteamNetworkingIPAddr_ParseString( SteamNetworkingIPAddr *pAddr, const char *pszStr ); + STEAMNETWORKINGSOCKETS_INTERFACE void SteamNetworkingIdentity_ToString( const SteamNetworkingIdentity *pIdentity, char *buf, size_t cbBuf ); + STEAMNETWORKINGSOCKETS_INTERFACE bool SteamNetworkingIdentity_ParseString( SteamNetworkingIdentity *pIdentity, size_t sizeofIdentity, const char *pszStr ); + inline void SteamNetworkingIPAddr::ToString( char *buf, size_t cbBuf, bool bWithPort ) const { SteamNetworkingIPAddr_ToString( this, buf, cbBuf, bWithPort ); } + inline bool SteamNetworkingIPAddr::ParseString( const char *pszStr ) { return SteamNetworkingIPAddr_ParseString( this, pszStr ); } + inline void SteamNetworkingIdentity::ToString( char *buf, size_t cbBuf ) const { SteamNetworkingIdentity_ToString( this, buf, cbBuf ); } + inline bool SteamNetworkingIdentity::ParseString( const char *pszStr ) { return SteamNetworkingIdentity_ParseString( this, sizeof(*this), pszStr ); } + +#elif defined( STEAMNETWORKINGSOCKETS_STEAMAPI ) + // Using steamworks SDK - go through SteamNetworkingUtils() + inline void SteamNetworkingIPAddr::ToString( char *buf, size_t cbBuf, bool bWithPort ) const { SteamNetworkingUtils()->SteamNetworkingIPAddr_ToString( *this, buf, cbBuf, bWithPort ); } + inline bool SteamNetworkingIPAddr::ParseString( const char *pszStr ) { return SteamNetworkingUtils()->SteamNetworkingIPAddr_ParseString( this, pszStr ); } + inline void SteamNetworkingIdentity::ToString( char *buf, size_t cbBuf ) const { SteamNetworkingUtils()->SteamNetworkingIdentity_ToString( *this, buf, cbBuf ); } + inline bool SteamNetworkingIdentity::ParseString( const char *pszStr ) { return SteamNetworkingUtils()->SteamNetworkingIdentity_ParseString( this, pszStr ); } +#else + #error "Invalid config" #endif #endif // ISTEAMNETWORKINGUTILS diff --git a/public/steam/isteamremotestorage.h b/public/steam/isteamremotestorage.h index f15d952..81fa2c8 100644 --- a/public/steam/isteamremotestorage.h +++ b/public/steam/isteamremotestorage.h @@ -241,7 +241,7 @@ class ISteamRemoteStorage // The following functions are only necessary on the Playstation 3. On PC & Mac, the Steam client will handle these operations for you // On Playstation 3, the game controls which files are stored in the cloud, via FilePersist, FileFetch, and FileForget. -#if defined(_PS3) || defined(_SERVER) +#if defined(_SERVER) // Connect to Steam and get a list of files in the Cloud - results in a RemoteStorageAppSyncStatusCheck_t callback virtual void GetFileListFromServer() = 0; // Indicate this file should be downloaded in the next sync diff --git a/public/steam/isteamugc.h b/public/steam/isteamugc.h index c86f197..e355d16 100644 --- a/public/steam/isteamugc.h +++ b/public/steam/isteamugc.h @@ -220,6 +220,9 @@ public: // Retrieve an individual result after receiving the callback for querying UGC virtual bool GetQueryUGCResult( UGCQueryHandle_t handle, uint32 index, SteamUGCDetails_t *pDetails ) = 0; + virtual uint32 GetQueryUGCNumTags( UGCQueryHandle_t handle, uint32 index ) = 0; + virtual bool GetQueryUGCTag( UGCQueryHandle_t handle, uint32 index, uint32 indexTag, STEAM_OUT_STRING_COUNT( cchValueSize ) char* pchValue, uint32 cchValueSize ) = 0; + virtual bool GetQueryUGCTagDisplayName( UGCQueryHandle_t handle, uint32 index, uint32 indexTag, STEAM_OUT_STRING_COUNT( cchValueSize ) char* pchValue, uint32 cchValueSize ) = 0; virtual bool GetQueryUGCPreviewURL( UGCQueryHandle_t handle, uint32 index, STEAM_OUT_STRING_COUNT(cchURLSize) char *pchURL, uint32 cchURLSize ) = 0; virtual bool GetQueryUGCMetadata( UGCQueryHandle_t handle, uint32 index, STEAM_OUT_STRING_COUNT(cchMetadatasize) char *pchMetadata, uint32 cchMetadatasize ) = 0; virtual bool GetQueryUGCChildren( UGCQueryHandle_t handle, uint32 index, PublishedFileId_t* pvecPublishedFileID, uint32 cMaxEntries ) = 0; @@ -227,7 +230,6 @@ public: virtual uint32 GetQueryUGCNumAdditionalPreviews( UGCQueryHandle_t handle, uint32 index ) = 0; virtual bool GetQueryUGCAdditionalPreview( UGCQueryHandle_t handle, uint32 index, uint32 previewIndex, STEAM_OUT_STRING_COUNT(cchURLSize) char *pchURLOrVideoID, uint32 cchURLSize, STEAM_OUT_STRING_COUNT(cchURLSize) char *pchOriginalFileName, uint32 cchOriginalFileNameSize, EItemPreviewType *pPreviewType ) = 0; virtual uint32 GetQueryUGCNumKeyValueTags( UGCQueryHandle_t handle, uint32 index ) = 0; - virtual bool GetQueryUGCKeyValueTag( UGCQueryHandle_t handle, uint32 index, uint32 keyValueTagIndex, STEAM_OUT_STRING_COUNT(cchKeySize) char *pchKey, uint32 cchKeySize, STEAM_OUT_STRING_COUNT(cchValueSize) char *pchValue, uint32 cchValueSize ) = 0; // Return the first value matching the pchKey. Note that a key may map to multiple values. Returns false if there was an error or no matching value was found. @@ -360,7 +362,7 @@ public: virtual SteamAPICall_t DeleteItem( PublishedFileId_t nPublishedFileID ) = 0; }; -#define STEAMUGC_INTERFACE_VERSION "STEAMUGC_INTERFACE_VERSION014" +#define STEAMUGC_INTERFACE_VERSION "STEAMUGC_INTERFACE_VERSION015" // Global interface accessor inline ISteamUGC *SteamUGC(); diff --git a/public/steam/isteamutils.h b/public/steam/isteamutils.h index b19526f..fe2cde4 100644 --- a/public/steam/isteamutils.h +++ b/public/steam/isteamutils.h @@ -86,8 +86,8 @@ public: // the destination buffer size should be 4 * height * width * sizeof(char) virtual bool GetImageRGBA( int iImage, uint8 *pubDest, int nDestBufferSize ) = 0; - // returns the IP of the reporting server for valve - currently only used in Source engine games - virtual bool GetCSERIPPort( uint32 *unIP, uint16 *usPort ) = 0; + // Deprecated. Do not call this. + STEAM_PRIVATE_API( virtual bool GetCSERIPPort( uint32 *unIP, uint16 *usPort ) = 0; ) // return the amount of battery power left in the current system in % [0..100], 255 for being on AC power virtual uint8 GetCurrentBatteryPower() = 0; @@ -183,9 +183,12 @@ public: // Returns whether this steam client is a Steam China specific client, vs the global client. virtual bool IsSteamChinaLauncher() = 0; - // Initializes text filtering. + // Initializes text filtering, loading dictionaries for the language the game is running in. // unFilterOptions are reserved for future use and should be set to 0 - // Returns false if filtering is unavailable for the language the user is currently running in. + // Returns false if filtering is unavailable for the game's language, in which case FilterText() will act as a passthrough. + // + // Users can customize the text filter behavior in their Steam Account preferences: + // https://store.steampowered.com/account/preferences#CommunityContentPreferences virtual bool InitFilterText( uint32 unFilterOptions = 0 ) = 0; // Filters the provided input message and places the filtered result into pchOutFilteredText, using legally required filtering and additional filtering based on the context and user settings diff --git a/public/steam/lib/linux32/libsdkencryptedappticket.so b/public/steam/lib/linux32/libsdkencryptedappticket.so index d4fef2e4457d2680042771d4603dcbba99341f22..f53085fafaad08a526276390594897c75068327d 100644 GIT binary patch delta 259 zcmX@t;CimXb%P6|NZmZ?p4Z+Yy?_7S?Aof9rd701leIa5u|0wjgqeVt8Hibcm=%cG zfS4VKIe?fGh`E568;E&;m=}oofS4bM1-3^p3Z@CvKZveN3G)eKU}Rum@N*DkICtxM zJktVQ@BE3IHm21WPN~_S!P%en=0l#*bpADqS4Epgt6FZIJHJOmb*7Wx(&Y@sW+4Hb zRXpDWk~aR;`Xn#8>fE^;J8B`cRBO=9nmX@EJbH7eF(WW_qu|0wjgqeVt8Hibcm=%cG zfS4VKIe?fGh`E568;E&;m=}oofS4bM1-3^p3Z@Cvf9|#Y8s-zmz{tSB;O8L75X0^h zFLCMcugh1&&ss}MH>!kWSDx+>U*ME=BG+rqKd09GH4nL$I{iJmU1PKCN$VHujt6;_ z&EMK;Ae^)^O1)z~g#4-v`S|~Hoj}bI|37cjzL+|ES$6X48*%nG@4L57 rkQeOW-o#T8rzM&yu(siCqG;OT_A>GKxCsS~i&U4yZx0d@{G$s1;frR< diff --git a/public/steam/lib/linux64/libsdkencryptedappticket.so b/public/steam/lib/linux64/libsdkencryptedappticket.so index 121ed6f041bb89b0091fd8b02e7dd8ec0ded0ef5..70750fc42d864f6a72de409c3f5b5f1974c2fc33 100644 GIT binary patch delta 251 zcmdmX&~Dp7yA1+NBJ)3Nzp+}#`ij&wxxV}L44vi=ew#I`Ftw{NF#<7&W(HywAZ7(( zHXvpPVh$kY1Y#~A<_2OOAm#;PzU?YZ{E-Ru^EG{J!hFIQ7#SECwk_aiICtxMyw6qt z$X9i|S$gx5jw+tpU^;ErjI`t5nl`cY?Kt9e~GcKe#tA1mik_SJEi`d%q5+a&Fp_WP|Z o%bTL2-#!tYd{*Gn$CruEokC)6)Tf!a7Q1}jCbV5JnSZG*09oy3Pyhe` delta 251 zcmdmX&~Dp7yA1+NBHkV**^{*rK=D#?W=M$P$nA%mC7=ai>GXpUT5VHa? z8xXStF$WNH0x=g5a|1CC5c2{t-*y!y{>X&-LT8S)FrP36Mg|6kZ43ArV%UA+{U6AG zO5)SMv^&W*bn1*x2YkZ%^xhqP6_=vs;;g69=FE{ z%XgK%&0c!pi0Uh5xB nE?ILmR?$=cuCbopZ?(E9ahCG(Cp&l)`@T%_+%A~Rztk20F>+zn diff --git a/public/steam/lib/osx/libsdkencryptedappticket.dylib b/public/steam/lib/osx/libsdkencryptedappticket.dylib index 191d6941e00d6a15b148c1f05070c852208bc897..0816de9b5a82b29243dc0555481d56a491d5d38f 100644 GIT binary patch delta 19248 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 delta 4748 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 Q+_s`OHS5K9=?@G+0G>gkd;kCd delta 961 zcmZ2*NNvF(wFy4;kA-~VTP`p7#F@0&R&P=HVP-pJ#l#1jZ=bG-y?5!XRF_|`r}BHX zvJmO^9?g(I@26#p3~jRcRwaH3Z7lM66R^g4jfnBw-LB1w5A~m3u!{3$<9T&yS!8iq zXopna-RIT5-%|~LYagCf!G6vw&AW^qGg$-{}S98A~r)U!U?Q*3j7@R3= zj0_CTwnsl;w_IZlG$Eb=2$+Dl35b2Rb1?WU@g67TYsRoty7s{^NV$S1`_9Dj1!_(A;Q z^LyIP=6*W8DcIt``lVYO{qJwq`EY)jtI-dQSsUvmg3D)|lsCPs_tU*xYsRYEkJl?d z-tz2wf-Kvez?8XwLS;=4f_pQwJdgj~y)^Ap@qPyeEnT^&9u54p_ zd+~;HX%(Az-VM#Vz+1HeuXE4yG8lCSe#uxJ)Ddt*GmHEOUIZG#B+q|YD zdG~a|`J89!4J?cej0{XI42`1HeU`oF(_SY1(}`S+el@@tB1ivpcq3K0LiB*x<&)H&3lM zb;%1ae)iVwU3%R*^Uk`GbA<;M%`;4OuFo_{+P1hd_V4MeSJof4?Wo(4?0P%xqm=*g ze~!G&_x>Ie<7HX&sQ7Ebx!F^Tlb&v$e#d$-%X^8>Te72l3a5x1e=h36;F&n1tU$87 T&Ou3Lvs0GIHnYjnKOO-9KGmvX diff --git a/public/steam/lib/win64/sdkencryptedappticket64.dll b/public/steam/lib/win64/sdkencryptedappticket64.dll index e7f2a300612a7a4e0b855db05c2fecdca8ad5332..ee3511652d0b59418ad1a972d05d1193176402f1 100644 GIT binary patch delta 972 zcmZ2*$zZ`Hg9$$MoHy^s&);&VwZ)a&ev9nWdD^Cj-Tu2AZf7cd7Qpf6_rHtNUfx=& z_EYuz-jdaE)3dlFuUvIzNDH097~k`_sMeYPz%4g-QQ5aiztp`xG6V$ap7`g+@84>s z7JTe}MMCTw`$;bjwmWS)82r~y_E)1y^4|3-hi)ILBYsE z!8fr|!N|bSa{F;Z&b{}ofd<7h009#acL8yZ2Ny$*5f?~^0Vc--WQzdt51`x+gxvQ1 zf?OLF1l&?PDyM(+@!MV-*DqvrC$zo6h--U;5%IJEaZ0T(8$QZ$k@Ql)G*3G86HZUEQVq%B1bJBNN={1uZjKe=uF3C z5rgKg%r-1RS(fh6wPwZ%u``w(v-rL)W=ptvp>CD@quJLE#D>kgrZoFkYT}WlTP9vN z{hV^VcFXD~-mG#r8XjwGviFjzt-o3*>Hbb%_n98&8o3{LU+;VTJ^I*B*2*W`sdxNE zgZG(FUz$I`e9D3oAHHuat2k%+W1`=uONGyTue859VlP)&FQ#&(BTZOxyeV$4n8|1vMH>u delta 972 zcmZ2*$zZ`Hg9$$M8-#q~D_QHTR{E&Ci9IH>>g()8p@XNiCSK<)RoW`^X4SFZYA1j3 zE&b@!ApKwaN{!}3z0A9vMoc>&mEJh5bzsBF%PUuhi6?I6^$u_AKKtIn*y2+6<^5A4 z_uTBB+~WCno6-LC50S?!CM{hy^XW;3`KROrj2W#`!!eVOFao2wYxs~AC;35c12m<5PgftU@5*@2j2dle(6y#ZgAf`XBm zLU3wSVddYLw&Z<#cY3fs?pcX>ti#&>Q8ylk9WZ60mkc^MfQSs7TG7#UQq ziUysxTXbQ1aI@Fv2md1U4o^F``2DUd>*}V6D}Ro023=arH%+GJk>>dq+*h}JKJMH7 zQ$~w7YG!!W+MLq@M_Vo*`m)t)MN95op`SZzKD(|7T`U;Z(EE3G{gQ1xH?oEK4NNN5 zJEyD&2r0?1^!?LSclFcpg#HYb_;U)g9|%_dzTIjzwcT{tf*g*mR&uWO-2!3{pJ}=k z-eE7?oA~rXl%L8=v5jYVejh%tPgl&aR-7;3fVQQFvKNY;^j*95>oxUGC-hPri zdcE=3JkAsS^Zlj^s`H$wH?S}^FfuSTH!_YgP=<#RCySvNi^x&sC4X0Ph|GOZcEC3y zCZe@U>-1ABLAfC7v2{vX5_9#&lRKrKPvThF%rIHpqHMK!21ClWxbsu)NnGxUi{kc^ zX_pa5UA}X}(g(|Z&d;c=Ub#vCdA;tkBl&w@*{WPwJG-0VCHJdos-~=R3l_-Vs^Lms zJ+Hp!VP=BR@4b&&&bA6Ze#*a1@7C#z|C?SLpV%y$>5$z}80ho4x9-0rV*$6ZK)1^a z{kq^yW>YWzOGx{=Xu_l-tJ*aVS&<DKV(6x+%DBtu%C9@>jkQ}_BRVu) zm;4A={_C{Q%lC@g`hw2uF4?eUn&OsIE(`7NnelwSU~jVMmiFnWmS4Li59P>BJgK(+ b_>5Eh|4%<%Ts-k_%cVDqpY)tii5CL^#6qYL diff --git a/public/steam/steam_api.json b/public/steam/steam_api.json index 5574388..29acc80 100644 --- a/public/steam/steam_api.json +++ b/public/steam/steam_api.json @@ -1891,13 +1891,6 @@ { "constname":"k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Public", "consttype":"int", "constval":"4" }, { "constname":"k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_All", "consttype":"int", "constval":"0x7fffffff" }, { "constname":"k_SteamDatagramPOPID_dev", "consttype":"SteamNetworkingPOPID", "constval":"( ( uint32 ) 'd' << 16U ) | ( ( uint32 ) 'e' << 8U ) | ( uint32 ) 'v'" }, - { "constname":"k_unServerFlagNone", "consttype":"uint32", "constval":"0x00" }, - { "constname":"k_unServerFlagActive", "consttype":"uint32", "constval":"0x01" }, - { "constname":"k_unServerFlagSecure", "consttype":"uint32", "constval":"0x02" }, - { "constname":"k_unServerFlagDedicated", "consttype":"uint32", "constval":"0x04" }, - { "constname":"k_unServerFlagLinux", "consttype":"uint32", "constval":"0x08" }, - { "constname":"k_unServerFlagPassworded", "consttype":"uint32", "constval":"0x10" }, - { "constname":"k_unServerFlagPrivate", "consttype":"uint32", "constval":"0x20" }, { "constname":"k_cbSteamDatagramMaxSerializedTicket", "consttype":"uint32", "constval":"512" }, { "constname":"k_cbMaxSteamDatagramGameCoordinatorServerLoginAppData", "consttype":"uint32", "constval":"2048" }, { "constname":"k_cbMaxSteamDatagramGameCoordinatorServerLoginSerialized", "consttype":"uint32", "constval":"4096" } @@ -2039,7 +2032,10 @@ { "name":"k_EResultCantRemoveItem", "value":"113" }, { "name":"k_EResultAccountDeleted", "value":"114" }, { "name":"k_EResultExistingUserCancelledLicense", "value":"115" }, - { "name":"k_EResultCommunityCooldown", "value":"116" } + { "name":"k_EResultCommunityCooldown", "value":"116" }, + { "name":"k_EResultNoLauncherSpecified", "value":"117" }, + { "name":"k_EResultMustAgreeToSSA", "value":"118" }, + { "name":"k_EResultLauncherMigrated", "value":"119" } ] }, { @@ -2189,7 +2185,7 @@ { "name":"k_EAppType_Comic_UNUSED", "value":"32768" }, { "name":"k_EAppType_Beta", "value":"65536" }, { "name":"k_EAppType_Shortcut", "value":"1073741824" }, - { "name":"k_EAppType_DepotOnly", "value":"-2147483648" } + { "name":"k_EAppType_DepotOnly_DEPRECATED", "value":"-2147483648" } ] }, { @@ -2344,6 +2340,7 @@ { "name":"k_eEVRHMDType_HP_Unknown", "value":"80" }, { "name":"k_eEVRHMDType_HP_WindowsMR", "value":"81" }, { "name":"k_eEVRHMDType_HP_Reverb", "value":"82" }, + { "name":"k_eEVRHMDType_HP_ReverbG2", "value":"1463" }, { "name":"k_eEVRHMDType_Samsung_Unknown", "value":"90" }, { "name":"k_eEVRHMDType_Samsung_Odyssey", "value":"91" }, { "name":"k_eEVRHMDType_Unannounced_Unknown", "value":"100" }, @@ -2790,10 +2787,10 @@ "enumname": "EP2PSessionError", "values": [ { "name":"k_EP2PSessionErrorNone", "value":"0" }, - { "name":"k_EP2PSessionErrorNotRunningApp", "value":"1" }, { "name":"k_EP2PSessionErrorNoRightsToApp", "value":"2" }, - { "name":"k_EP2PSessionErrorDestinationNotLoggedIn", "value":"3" }, { "name":"k_EP2PSessionErrorTimeout", "value":"4" }, + { "name":"k_EP2PSessionErrorNotRunningApp_DELETED", "value":"1" }, + { "name":"k_EP2PSessionErrorDestinationNotLoggedIn_DELETED", "value":"3" }, { "name":"k_EP2PSessionErrorMax", "value":"5" } ] }, @@ -3196,7 +3193,82 @@ { "name":"k_EInputActionOrigin_Switch_Reserved18", "value":"255" }, { "name":"k_EInputActionOrigin_Switch_Reserved19", "value":"256" }, { "name":"k_EInputActionOrigin_Switch_Reserved20", "value":"257" }, - { "name":"k_EInputActionOrigin_Count", "value":"258" }, + { "name":"k_EInputActionOrigin_PS5_X", "value":"258" }, + { "name":"k_EInputActionOrigin_PS5_Circle", "value":"259" }, + { "name":"k_EInputActionOrigin_PS5_Triangle", "value":"260" }, + { "name":"k_EInputActionOrigin_PS5_Square", "value":"261" }, + { "name":"k_EInputActionOrigin_PS5_LeftBumper", "value":"262" }, + { "name":"k_EInputActionOrigin_PS5_RightBumper", "value":"263" }, + { "name":"k_EInputActionOrigin_PS5_Option", "value":"264" }, + { "name":"k_EInputActionOrigin_PS5_Create", "value":"265" }, + { "name":"k_EInputActionOrigin_PS5_Mute", "value":"266" }, + { "name":"k_EInputActionOrigin_PS5_LeftPad_Touch", "value":"267" }, + { "name":"k_EInputActionOrigin_PS5_LeftPad_Swipe", "value":"268" }, + { "name":"k_EInputActionOrigin_PS5_LeftPad_Click", "value":"269" }, + { "name":"k_EInputActionOrigin_PS5_LeftPad_DPadNorth", "value":"270" }, + { "name":"k_EInputActionOrigin_PS5_LeftPad_DPadSouth", "value":"271" }, + { "name":"k_EInputActionOrigin_PS5_LeftPad_DPadWest", "value":"272" }, + { "name":"k_EInputActionOrigin_PS5_LeftPad_DPadEast", "value":"273" }, + { "name":"k_EInputActionOrigin_PS5_RightPad_Touch", "value":"274" }, + { "name":"k_EInputActionOrigin_PS5_RightPad_Swipe", "value":"275" }, + { "name":"k_EInputActionOrigin_PS5_RightPad_Click", "value":"276" }, + { "name":"k_EInputActionOrigin_PS5_RightPad_DPadNorth", "value":"277" }, + { "name":"k_EInputActionOrigin_PS5_RightPad_DPadSouth", "value":"278" }, + { "name":"k_EInputActionOrigin_PS5_RightPad_DPadWest", "value":"279" }, + { "name":"k_EInputActionOrigin_PS5_RightPad_DPadEast", "value":"280" }, + { "name":"k_EInputActionOrigin_PS5_CenterPad_Touch", "value":"281" }, + { "name":"k_EInputActionOrigin_PS5_CenterPad_Swipe", "value":"282" }, + { "name":"k_EInputActionOrigin_PS5_CenterPad_Click", "value":"283" }, + { "name":"k_EInputActionOrigin_PS5_CenterPad_DPadNorth", "value":"284" }, + { "name":"k_EInputActionOrigin_PS5_CenterPad_DPadSouth", "value":"285" }, + { "name":"k_EInputActionOrigin_PS5_CenterPad_DPadWest", "value":"286" }, + { "name":"k_EInputActionOrigin_PS5_CenterPad_DPadEast", "value":"287" }, + { "name":"k_EInputActionOrigin_PS5_LeftTrigger_Pull", "value":"288" }, + { "name":"k_EInputActionOrigin_PS5_LeftTrigger_Click", "value":"289" }, + { "name":"k_EInputActionOrigin_PS5_RightTrigger_Pull", "value":"290" }, + { "name":"k_EInputActionOrigin_PS5_RightTrigger_Click", "value":"291" }, + { "name":"k_EInputActionOrigin_PS5_LeftStick_Move", "value":"292" }, + { "name":"k_EInputActionOrigin_PS5_LeftStick_Click", "value":"293" }, + { "name":"k_EInputActionOrigin_PS5_LeftStick_DPadNorth", "value":"294" }, + { "name":"k_EInputActionOrigin_PS5_LeftStick_DPadSouth", "value":"295" }, + { "name":"k_EInputActionOrigin_PS5_LeftStick_DPadWest", "value":"296" }, + { "name":"k_EInputActionOrigin_PS5_LeftStick_DPadEast", "value":"297" }, + { "name":"k_EInputActionOrigin_PS5_RightStick_Move", "value":"298" }, + { "name":"k_EInputActionOrigin_PS5_RightStick_Click", "value":"299" }, + { "name":"k_EInputActionOrigin_PS5_RightStick_DPadNorth", "value":"300" }, + { "name":"k_EInputActionOrigin_PS5_RightStick_DPadSouth", "value":"301" }, + { "name":"k_EInputActionOrigin_PS5_RightStick_DPadWest", "value":"302" }, + { "name":"k_EInputActionOrigin_PS5_RightStick_DPadEast", "value":"303" }, + { "name":"k_EInputActionOrigin_PS5_DPad_North", "value":"304" }, + { "name":"k_EInputActionOrigin_PS5_DPad_South", "value":"305" }, + { "name":"k_EInputActionOrigin_PS5_DPad_West", "value":"306" }, + { "name":"k_EInputActionOrigin_PS5_DPad_East", "value":"307" }, + { "name":"k_EInputActionOrigin_PS5_Gyro_Move", "value":"308" }, + { "name":"k_EInputActionOrigin_PS5_Gyro_Pitch", "value":"309" }, + { "name":"k_EInputActionOrigin_PS5_Gyro_Yaw", "value":"310" }, + { "name":"k_EInputActionOrigin_PS5_Gyro_Roll", "value":"311" }, + { "name":"k_EInputActionOrigin_PS5_DPad_Move", "value":"312" }, + { "name":"k_EInputActionOrigin_PS5_Reserved1", "value":"313" }, + { "name":"k_EInputActionOrigin_PS5_Reserved2", "value":"314" }, + { "name":"k_EInputActionOrigin_PS5_Reserved3", "value":"315" }, + { "name":"k_EInputActionOrigin_PS5_Reserved4", "value":"316" }, + { "name":"k_EInputActionOrigin_PS5_Reserved5", "value":"317" }, + { "name":"k_EInputActionOrigin_PS5_Reserved6", "value":"318" }, + { "name":"k_EInputActionOrigin_PS5_Reserved7", "value":"319" }, + { "name":"k_EInputActionOrigin_PS5_Reserved8", "value":"320" }, + { "name":"k_EInputActionOrigin_PS5_Reserved9", "value":"321" }, + { "name":"k_EInputActionOrigin_PS5_Reserved10", "value":"322" }, + { "name":"k_EInputActionOrigin_PS5_Reserved11", "value":"323" }, + { "name":"k_EInputActionOrigin_PS5_Reserved12", "value":"324" }, + { "name":"k_EInputActionOrigin_PS5_Reserved13", "value":"325" }, + { "name":"k_EInputActionOrigin_PS5_Reserved14", "value":"326" }, + { "name":"k_EInputActionOrigin_PS5_Reserved15", "value":"327" }, + { "name":"k_EInputActionOrigin_PS5_Reserved16", "value":"328" }, + { "name":"k_EInputActionOrigin_PS5_Reserved17", "value":"329" }, + { "name":"k_EInputActionOrigin_PS5_Reserved18", "value":"330" }, + { "name":"k_EInputActionOrigin_PS5_Reserved19", "value":"331" }, + { "name":"k_EInputActionOrigin_PS5_Reserved20", "value":"332" }, + { "name":"k_EInputActionOrigin_Count", "value":"333" }, { "name":"k_EInputActionOrigin_MaximumPossibleValue", "value":"32767" } ] }, @@ -3257,7 +3329,8 @@ { "name":"k_ESteamInputType_SwitchProController", "value":"10" }, { "name":"k_ESteamInputType_MobileTouch", "value":"11" }, { "name":"k_ESteamInputType_PS3Controller", "value":"12" }, - { "name":"k_ESteamInputType_Count", "value":"13" }, + { "name":"k_ESteamInputType_PS5Controller", "value":"13" }, + { "name":"k_ESteamInputType_Count", "value":"14" }, { "name":"k_ESteamInputType_MaximumPossibleValue", "value":"255" } ] }, @@ -3516,7 +3589,62 @@ { "name":"k_EControllerActionOrigin_XBoxOne_DPad_Move", "value":"242" }, { "name":"k_EControllerActionOrigin_XBox360_DPad_Move", "value":"243" }, { "name":"k_EControllerActionOrigin_Switch_DPad_Move", "value":"244" }, - { "name":"k_EControllerActionOrigin_Count", "value":"245" }, + { "name":"k_EControllerActionOrigin_PS5_X", "value":"245" }, + { "name":"k_EControllerActionOrigin_PS5_Circle", "value":"246" }, + { "name":"k_EControllerActionOrigin_PS5_Triangle", "value":"247" }, + { "name":"k_EControllerActionOrigin_PS5_Square", "value":"248" }, + { "name":"k_EControllerActionOrigin_PS5_LeftBumper", "value":"249" }, + { "name":"k_EControllerActionOrigin_PS5_RightBumper", "value":"250" }, + { "name":"k_EControllerActionOrigin_PS5_Option", "value":"251" }, + { "name":"k_EControllerActionOrigin_PS5_Create", "value":"252" }, + { "name":"k_EControllerActionOrigin_PS5_Mute", "value":"253" }, + { "name":"k_EControllerActionOrigin_PS5_LeftPad_Touch", "value":"254" }, + { "name":"k_EControllerActionOrigin_PS5_LeftPad_Swipe", "value":"255" }, + { "name":"k_EControllerActionOrigin_PS5_LeftPad_Click", "value":"256" }, + { "name":"k_EControllerActionOrigin_PS5_LeftPad_DPadNorth", "value":"257" }, + { "name":"k_EControllerActionOrigin_PS5_LeftPad_DPadSouth", "value":"258" }, + { "name":"k_EControllerActionOrigin_PS5_LeftPad_DPadWest", "value":"259" }, + { "name":"k_EControllerActionOrigin_PS5_LeftPad_DPadEast", "value":"260" }, + { "name":"k_EControllerActionOrigin_PS5_RightPad_Touch", "value":"261" }, + { "name":"k_EControllerActionOrigin_PS5_RightPad_Swipe", "value":"262" }, + { "name":"k_EControllerActionOrigin_PS5_RightPad_Click", "value":"263" }, + { "name":"k_EControllerActionOrigin_PS5_RightPad_DPadNorth", "value":"264" }, + { "name":"k_EControllerActionOrigin_PS5_RightPad_DPadSouth", "value":"265" }, + { "name":"k_EControllerActionOrigin_PS5_RightPad_DPadWest", "value":"266" }, + { "name":"k_EControllerActionOrigin_PS5_RightPad_DPadEast", "value":"267" }, + { "name":"k_EControllerActionOrigin_PS5_CenterPad_Touch", "value":"268" }, + { "name":"k_EControllerActionOrigin_PS5_CenterPad_Swipe", "value":"269" }, + { "name":"k_EControllerActionOrigin_PS5_CenterPad_Click", "value":"270" }, + { "name":"k_EControllerActionOrigin_PS5_CenterPad_DPadNorth", "value":"271" }, + { "name":"k_EControllerActionOrigin_PS5_CenterPad_DPadSouth", "value":"272" }, + { "name":"k_EControllerActionOrigin_PS5_CenterPad_DPadWest", "value":"273" }, + { "name":"k_EControllerActionOrigin_PS5_CenterPad_DPadEast", "value":"274" }, + { "name":"k_EControllerActionOrigin_PS5_LeftTrigger_Pull", "value":"275" }, + { "name":"k_EControllerActionOrigin_PS5_LeftTrigger_Click", "value":"276" }, + { "name":"k_EControllerActionOrigin_PS5_RightTrigger_Pull", "value":"277" }, + { "name":"k_EControllerActionOrigin_PS5_RightTrigger_Click", "value":"278" }, + { "name":"k_EControllerActionOrigin_PS5_LeftStick_Move", "value":"279" }, + { "name":"k_EControllerActionOrigin_PS5_LeftStick_Click", "value":"280" }, + { "name":"k_EControllerActionOrigin_PS5_LeftStick_DPadNorth", "value":"281" }, + { "name":"k_EControllerActionOrigin_PS5_LeftStick_DPadSouth", "value":"282" }, + { "name":"k_EControllerActionOrigin_PS5_LeftStick_DPadWest", "value":"283" }, + { "name":"k_EControllerActionOrigin_PS5_LeftStick_DPadEast", "value":"284" }, + { "name":"k_EControllerActionOrigin_PS5_RightStick_Move", "value":"285" }, + { "name":"k_EControllerActionOrigin_PS5_RightStick_Click", "value":"286" }, + { "name":"k_EControllerActionOrigin_PS5_RightStick_DPadNorth", "value":"287" }, + { "name":"k_EControllerActionOrigin_PS5_RightStick_DPadSouth", "value":"288" }, + { "name":"k_EControllerActionOrigin_PS5_RightStick_DPadWest", "value":"289" }, + { "name":"k_EControllerActionOrigin_PS5_RightStick_DPadEast", "value":"290" }, + { "name":"k_EControllerActionOrigin_PS5_DPad_Move", "value":"291" }, + { "name":"k_EControllerActionOrigin_PS5_DPad_North", "value":"292" }, + { "name":"k_EControllerActionOrigin_PS5_DPad_South", "value":"293" }, + { "name":"k_EControllerActionOrigin_PS5_DPad_West", "value":"294" }, + { "name":"k_EControllerActionOrigin_PS5_DPad_East", "value":"295" }, + { "name":"k_EControllerActionOrigin_PS5_Gyro_Move", "value":"296" }, + { "name":"k_EControllerActionOrigin_PS5_Gyro_Pitch", "value":"297" }, + { "name":"k_EControllerActionOrigin_PS5_Gyro_Yaw", "value":"298" }, + { "name":"k_EControllerActionOrigin_PS5_Gyro_Roll", "value":"299" }, + { "name":"k_EControllerActionOrigin_Count", "value":"300" }, { "name":"k_EControllerActionOrigin_MaximumPossibleValue", "value":"32767" } ] }, @@ -3707,6 +3835,8 @@ { "name":"k_ESteamNetworkingIdentityType_Invalid", "value":"0" }, { "name":"k_ESteamNetworkingIdentityType_SteamID", "value":"16" }, { "name":"k_ESteamNetworkingIdentityType_XboxPairwiseID", "value":"17" }, + { "name":"k_ESteamNetworkingIdentityType_SonyPSN", "value":"18" }, + { "name":"k_ESteamNetworkingIdentityType_GoogleStadia", "value":"19" }, { "name":"k_ESteamNetworkingIdentityType_IPAddress", "value":"1" }, { "name":"k_ESteamNetworkingIdentityType_GenericString", "value":"2" }, { "name":"k_ESteamNetworkingIdentityType_GenericBytes", "value":"3" }, @@ -3837,6 +3967,7 @@ { "name":"k_ESteamNetworkingConfig_Callback_RelayNetworkStatusChanged", "value":"203" }, { "name":"k_ESteamNetworkingConfig_Callback_MessagesSessionRequest", "value":"204" }, { "name":"k_ESteamNetworkingConfig_Callback_MessagesSessionFailed", "value":"205" }, + { "name":"k_ESteamNetworkingConfig_Callback_CreateConnectionSignaling", "value":"206" }, { "name":"k_ESteamNetworkingConfig_P2P_STUN_ServerList", "value":"103" }, { "name":"k_ESteamNetworkingConfig_P2P_Transport_ICE_Enable", "value":"104" }, { "name":"k_ESteamNetworkingConfig_P2P_Transport_ICE_Penalty", "value":"105" }, @@ -5180,6 +5311,14 @@ { "paramname":"pchProtocol", "paramtype":"const char *" } ], "returntype": "bool" + }, + { + "methodname": "ActivateGameOverlayInviteDialogConnectString", + "methodname_flat": "SteamAPI_ISteamFriends_ActivateGameOverlayInviteDialogConnectString", + "params": [ + { "paramname":"pchConnectString", "paramtype":"const char *" } + ], + "returntype": "void" } ], "version_string": "SteamFriends017" @@ -5250,15 +5389,6 @@ ], "returntype": "bool" }, - { - "methodname": "GetCSERIPPort", - "methodname_flat": "SteamAPI_ISteamUtils_GetCSERIPPort", - "params": [ - { "paramname":"unIP", "paramtype":"uint32 *" }, - { "paramname":"usPort", "paramtype":"uint16 *" } - ], - "returntype": "bool" - }, { "methodname": "GetCurrentBatteryPower", "methodname_flat": "SteamAPI_ISteamUtils_GetCurrentBatteryPower", @@ -8538,7 +8668,7 @@ { "kind": "user", "name": "SteamInput", - "name_flat": "SteamAPI_SteamInput_v001" + "name_flat": "SteamAPI_SteamInput_v002" } ], "classname": "ISteamInput", @@ -8869,14 +8999,14 @@ "returntype": "uint32" } ], - "version_string": "SteamInput001" + "version_string": "SteamInput002" }, { "accessors": [ { "kind": "user", "name": "SteamController", - "name_flat": "SteamAPI_SteamController_v007" + "name_flat": "SteamAPI_SteamController_v008" } ], "classname": "ISteamController", @@ -9199,19 +9329,19 @@ "returntype": "bool" } ], - "version_string": "SteamController007" + "version_string": "SteamController008" }, { "accessors": [ { "kind": "user", "name": "SteamUGC", - "name_flat": "SteamAPI_SteamUGC_v014" + "name_flat": "SteamAPI_SteamUGC_v015" }, { "kind": "gameserver", "name": "SteamGameServerUGC", - "name_flat": "SteamAPI_SteamGameServerUGC_v014" + "name_flat": "SteamAPI_SteamGameServerUGC_v015" } ], "classname": "ISteamUGC", @@ -9283,6 +9413,47 @@ ], "returntype": "bool" }, + { + "methodname": "GetQueryUGCNumTags", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCNumTags", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" } + ], + "returntype": "uint32" + }, + { + "methodname": "GetQueryUGCTag", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCTag", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" }, + { "paramname":"indexTag", "paramtype":"uint32" }, + { + "out_string_count": "cchValueSize", + "paramname": "pchValue", + "paramtype": "char *" + }, + { "paramname":"cchValueSize", "paramtype":"uint32" } + ], + "returntype": "bool" + }, + { + "methodname": "GetQueryUGCTagDisplayName", + "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCTagDisplayName", + "params": [ + { "paramname":"handle", "paramtype":"UGCQueryHandle_t" }, + { "paramname":"index", "paramtype":"uint32" }, + { "paramname":"indexTag", "paramtype":"uint32" }, + { + "out_string_count": "cchValueSize", + "paramname": "pchValue", + "paramtype": "char *" + }, + { "paramname":"cchValueSize", "paramtype":"uint32" } + ], + "returntype": "bool" + }, { "methodname": "GetQueryUGCPreviewURL", "methodname_flat": "SteamAPI_ISteamUGC_GetQueryUGCPreviewURL", @@ -10008,7 +10179,7 @@ "returntype": "SteamAPICall_t" } ], - "version_string": "STEAMUGC_INTERFACE_VERSION014" + "version_string": "STEAMUGC_INTERFACE_VERSION015" }, { "accessors": [ @@ -11183,13 +11354,13 @@ "accessors": [ { "kind": "user", - "name": "SteamNetworkingMessages", - "name_flat": "SteamAPI_SteamNetworkingMessages_v002" + "name": "SteamNetworkingMessages_SteamAPI", + "name_flat": "SteamAPI_SteamNetworkingMessages_SteamAPI_v002" }, { "kind": "gameserver", - "name": "SteamGameServerNetworkingMessages", - "name_flat": "SteamAPI_SteamGameServerNetworkingMessages_v002" + "name": "SteamGameServerNetworkingMessages_SteamAPI", + "name_flat": "SteamAPI_SteamGameServerNetworkingMessages_SteamAPI_v002" } ], "classname": "ISteamNetworkingMessages", @@ -11259,13 +11430,13 @@ "accessors": [ { "kind": "user", - "name": "SteamNetworkingSockets", - "name_flat": "SteamAPI_SteamNetworkingSockets_v009" + "name": "SteamNetworkingSockets_SteamAPI", + "name_flat": "SteamAPI_SteamNetworkingSockets_SteamAPI_v009" }, { "kind": "gameserver", - "name": "SteamGameServerNetworkingSockets", - "name_flat": "SteamAPI_SteamGameServerNetworkingSockets_v009" + "name": "SteamGameServerNetworkingSockets_SteamAPI", + "name_flat": "SteamAPI_SteamGameServerNetworkingSockets_SteamAPI_v009" } ], "classname": "ISteamNetworkingSockets", @@ -11594,7 +11765,7 @@ "methodname": "ConnectP2PCustomSignaling", "methodname_flat": "SteamAPI_ISteamNetworkingSockets_ConnectP2PCustomSignaling", "params": [ - { "paramname":"pSignaling", "paramtype":"ISteamNetworkingConnectionCustomSignaling *" }, + { "paramname":"pSignaling", "paramtype":"ISteamNetworkingConnectionSignaling *" }, { "paramname":"pPeerIdentity", "paramtype":"const SteamNetworkingIdentity *" }, { "paramname":"nRemoteVirtualPort", "paramtype":"int" }, { "paramname":"nOptions", "paramtype":"int" }, @@ -11608,7 +11779,7 @@ "params": [ { "paramname":"pMsg", "paramtype":"const void *" }, { "paramname":"cbMsg", "paramtype":"int" }, - { "paramname":"pContext", "paramtype":"ISteamNetworkingCustomSignalingRecvContext *" } + { "paramname":"pContext", "paramtype":"ISteamNetworkingSignalingRecvContext *" } ], "returntype": "bool" }, @@ -11645,8 +11816,8 @@ "accessors": [ { "kind": "global", - "name": "SteamNetworkingUtils", - "name_flat": "SteamAPI_SteamNetworkingUtils_v003" + "name": "SteamNetworkingUtils_SteamAPI", + "name_flat": "SteamAPI_SteamNetworkingUtils_SteamAPI_v003" } ], "classname": "ISteamNetworkingUtils", @@ -12911,6 +13082,34 @@ "params": [], "returntype": "const char *" }, + { + "methodname": "SetPSNID", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_SetPSNID", + "params": [ + { "paramname":"id", "paramtype":"uint64" } + ], + "returntype": "void" + }, + { + "methodname": "GetPSNID", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_GetPSNID", + "params": [], + "returntype": "uint64" + }, + { + "methodname": "SetStadiaID", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_SetStadiaID", + "params": [ + { "paramname":"id", "paramtype":"uint64" } + ], + "returntype": "void" + }, + { + "methodname": "GetStadiaID", + "methodname_flat": "SteamAPI_SteamNetworkingIdentity_GetStadiaID", + "params": [], + "returntype": "uint64" + }, { "methodname": "SetIPAddr", "methodname_flat": "SteamAPI_SteamNetworkingIdentity_SetIPAddr", diff --git a/public/steam/steam_api_flat.h b/public/steam/steam_api_flat.h index 9c19f8c..c71e61c 100644 --- a/public/steam/steam_api_flat.h +++ b/public/steam/steam_api_flat.h @@ -167,6 +167,7 @@ S_API bool SteamAPI_ISteamFriends_IsClanOfficialGameGroup( ISteamFriends* self, S_API int SteamAPI_ISteamFriends_GetNumChatsWithUnreadPriorityMessages( ISteamFriends* self ); S_API void SteamAPI_ISteamFriends_ActivateGameOverlayRemotePlayTogetherInviteDialog( ISteamFriends* self, uint64_steamid steamIDLobby ); S_API bool SteamAPI_ISteamFriends_RegisterProtocolInOverlayBrowser( ISteamFriends* self, const char * pchProtocol ); +S_API void SteamAPI_ISteamFriends_ActivateGameOverlayInviteDialogConnectString( ISteamFriends* self, const char * pchConnectString ); // ISteamUtils S_API ISteamUtils *SteamAPI_SteamUtils_v010(); @@ -178,7 +179,6 @@ S_API uint32 SteamAPI_ISteamUtils_GetServerRealTime( ISteamUtils* self ); S_API const char * SteamAPI_ISteamUtils_GetIPCountry( ISteamUtils* self ); S_API bool SteamAPI_ISteamUtils_GetImageSize( ISteamUtils* self, int iImage, uint32 * pnWidth, uint32 * pnHeight ); S_API bool SteamAPI_ISteamUtils_GetImageRGBA( ISteamUtils* self, int iImage, uint8 * pubDest, int nDestBufferSize ); -S_API bool SteamAPI_ISteamUtils_GetCSERIPPort( ISteamUtils* self, uint32 * unIP, uint16 * usPort ); S_API uint8 SteamAPI_ISteamUtils_GetCurrentBatteryPower( ISteamUtils* self ); S_API uint32 SteamAPI_ISteamUtils_GetAppID( ISteamUtils* self ); S_API void SteamAPI_ISteamUtils_SetOverlayNotificationPosition( ISteamUtils* self, ENotificationPosition eNotificationPosition ); @@ -571,7 +571,7 @@ S_API bool SteamAPI_ISteamHTTP_SetHTTPRequestAbsoluteTimeoutMS( ISteamHTTP* self S_API bool SteamAPI_ISteamHTTP_GetHTTPRequestWasTimedOut( ISteamHTTP* self, HTTPRequestHandle hRequest, bool * pbWasTimedOut ); // ISteamInput -S_API ISteamInput *SteamAPI_SteamInput_v001(); +S_API ISteamInput *SteamAPI_SteamInput_v002(); S_API bool SteamAPI_ISteamInput_Init( ISteamInput* self ); S_API bool SteamAPI_ISteamInput_Shutdown( ISteamInput* self ); S_API void SteamAPI_ISteamInput_RunFrame( ISteamInput* self ); @@ -609,7 +609,7 @@ S_API bool SteamAPI_ISteamInput_GetDeviceBindingRevision( ISteamInput* self, Inp S_API uint32 SteamAPI_ISteamInput_GetRemotePlaySessionID( ISteamInput* self, InputHandle_t inputHandle ); // ISteamController -S_API ISteamController *SteamAPI_SteamController_v007(); +S_API ISteamController *SteamAPI_SteamController_v008(); S_API bool SteamAPI_ISteamController_Init( ISteamController* self ); S_API bool SteamAPI_ISteamController_Shutdown( ISteamController* self ); S_API void SteamAPI_ISteamController_RunFrame( ISteamController* self ); @@ -646,14 +646,17 @@ S_API EControllerActionOrigin SteamAPI_ISteamController_TranslateActionOrigin( I S_API bool SteamAPI_ISteamController_GetControllerBindingRevision( ISteamController* self, ControllerHandle_t controllerHandle, int * pMajor, int * pMinor ); // ISteamUGC -S_API ISteamUGC *SteamAPI_SteamUGC_v014(); -S_API ISteamUGC *SteamAPI_SteamGameServerUGC_v014(); +S_API ISteamUGC *SteamAPI_SteamUGC_v015(); +S_API ISteamUGC *SteamAPI_SteamGameServerUGC_v015(); S_API UGCQueryHandle_t SteamAPI_ISteamUGC_CreateQueryUserUGCRequest( ISteamUGC* self, AccountID_t unAccountID, EUserUGCList eListType, EUGCMatchingUGCType eMatchingUGCType, EUserUGCListSortOrder eSortOrder, AppId_t nCreatorAppID, AppId_t nConsumerAppID, uint32 unPage ); S_API UGCQueryHandle_t SteamAPI_ISteamUGC_CreateQueryAllUGCRequestPage( ISteamUGC* self, EUGCQuery eQueryType, EUGCMatchingUGCType eMatchingeMatchingUGCTypeFileType, AppId_t nCreatorAppID, AppId_t nConsumerAppID, uint32 unPage ); S_API UGCQueryHandle_t SteamAPI_ISteamUGC_CreateQueryAllUGCRequestCursor( ISteamUGC* self, EUGCQuery eQueryType, EUGCMatchingUGCType eMatchingeMatchingUGCTypeFileType, AppId_t nCreatorAppID, AppId_t nConsumerAppID, const char * pchCursor ); S_API UGCQueryHandle_t SteamAPI_ISteamUGC_CreateQueryUGCDetailsRequest( ISteamUGC* self, PublishedFileId_t * pvecPublishedFileID, uint32 unNumPublishedFileIDs ); S_API SteamAPICall_t SteamAPI_ISteamUGC_SendQueryUGCRequest( ISteamUGC* self, UGCQueryHandle_t handle ); S_API bool SteamAPI_ISteamUGC_GetQueryUGCResult( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, SteamUGCDetails_t * pDetails ); +S_API uint32 SteamAPI_ISteamUGC_GetQueryUGCNumTags( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index ); +S_API bool SteamAPI_ISteamUGC_GetQueryUGCTag( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, uint32 indexTag, char * pchValue, uint32 cchValueSize ); +S_API bool SteamAPI_ISteamUGC_GetQueryUGCTagDisplayName( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, uint32 indexTag, char * pchValue, uint32 cchValueSize ); S_API bool SteamAPI_ISteamUGC_GetQueryUGCPreviewURL( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, char * pchURL, uint32 cchURLSize ); S_API bool SteamAPI_ISteamUGC_GetQueryUGCMetadata( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, char * pchMetadata, uint32 cchMetadatasize ); S_API bool SteamAPI_ISteamUGC_GetQueryUGCChildren( ISteamUGC* self, UGCQueryHandle_t handle, uint32 index, PublishedFileId_t * pvecPublishedFileID, uint32 cMaxEntries ); @@ -845,8 +848,8 @@ S_API bool SteamAPI_ISteamRemotePlay_BGetSessionClientResolution( ISteamRemotePl S_API bool SteamAPI_ISteamRemotePlay_BSendRemotePlayTogetherInvite( ISteamRemotePlay* self, uint64_steamid steamIDFriend ); // ISteamNetworkingMessages -S_API ISteamNetworkingMessages *SteamAPI_SteamNetworkingMessages_v002(); -S_API ISteamNetworkingMessages *SteamAPI_SteamGameServerNetworkingMessages_v002(); +S_API ISteamNetworkingMessages *SteamAPI_SteamNetworkingMessages_SteamAPI_v002(); +S_API ISteamNetworkingMessages *SteamAPI_SteamGameServerNetworkingMessages_SteamAPI_v002(); S_API EResult SteamAPI_ISteamNetworkingMessages_SendMessageToUser( ISteamNetworkingMessages* self, const SteamNetworkingIdentity & identityRemote, const void * pubData, uint32 cubData, int nSendFlags, int nRemoteChannel ); S_API int SteamAPI_ISteamNetworkingMessages_ReceiveMessagesOnChannel( ISteamNetworkingMessages* self, int nLocalChannel, SteamNetworkingMessage_t ** ppOutMessages, int nMaxMessages ); S_API bool SteamAPI_ISteamNetworkingMessages_AcceptSessionWithUser( ISteamNetworkingMessages* self, const SteamNetworkingIdentity & identityRemote ); @@ -855,8 +858,8 @@ S_API bool SteamAPI_ISteamNetworkingMessages_CloseChannelWithUser( ISteamNetwork S_API ESteamNetworkingConnectionState SteamAPI_ISteamNetworkingMessages_GetSessionConnectionInfo( ISteamNetworkingMessages* self, const SteamNetworkingIdentity & identityRemote, SteamNetConnectionInfo_t * pConnectionInfo, SteamNetworkingQuickConnectionStatus * pQuickStatus ); // ISteamNetworkingSockets -S_API ISteamNetworkingSockets *SteamAPI_SteamNetworkingSockets_v009(); -S_API ISteamNetworkingSockets *SteamAPI_SteamGameServerNetworkingSockets_v009(); +S_API ISteamNetworkingSockets *SteamAPI_SteamNetworkingSockets_SteamAPI_v009(); +S_API ISteamNetworkingSockets *SteamAPI_SteamGameServerNetworkingSockets_SteamAPI_v009(); S_API HSteamListenSocket SteamAPI_ISteamNetworkingSockets_CreateListenSocketIP( ISteamNetworkingSockets* self, const SteamNetworkingIPAddr & localAddress, int nOptions, const SteamNetworkingConfigValue_t * pOptions ); S_API HSteamNetConnection SteamAPI_ISteamNetworkingSockets_ConnectByIPAddress( ISteamNetworkingSockets* self, const SteamNetworkingIPAddr & address, int nOptions, const SteamNetworkingConfigValue_t * pOptions ); S_API HSteamListenSocket SteamAPI_ISteamNetworkingSockets_CreateListenSocketP2P( ISteamNetworkingSockets* self, int nLocalVirtualPort, int nOptions, const SteamNetworkingConfigValue_t * pOptions ); @@ -892,14 +895,14 @@ S_API SteamNetworkingPOPID SteamAPI_ISteamNetworkingSockets_GetHostedDedicatedSe S_API EResult SteamAPI_ISteamNetworkingSockets_GetHostedDedicatedServerAddress( ISteamNetworkingSockets* self, SteamDatagramHostedAddress * pRouting ); S_API HSteamListenSocket SteamAPI_ISteamNetworkingSockets_CreateHostedDedicatedServerListenSocket( ISteamNetworkingSockets* self, int nLocalVirtualPort, int nOptions, const SteamNetworkingConfigValue_t * pOptions ); S_API EResult SteamAPI_ISteamNetworkingSockets_GetGameCoordinatorServerLogin( ISteamNetworkingSockets* self, SteamDatagramGameCoordinatorServerLogin * pLoginInfo, int * pcbSignedBlob, void * pBlob ); -S_API HSteamNetConnection SteamAPI_ISteamNetworkingSockets_ConnectP2PCustomSignaling( ISteamNetworkingSockets* self, ISteamNetworkingConnectionCustomSignaling * pSignaling, const SteamNetworkingIdentity * pPeerIdentity, int nRemoteVirtualPort, int nOptions, const SteamNetworkingConfigValue_t * pOptions ); -S_API bool SteamAPI_ISteamNetworkingSockets_ReceivedP2PCustomSignal( ISteamNetworkingSockets* self, const void * pMsg, int cbMsg, ISteamNetworkingCustomSignalingRecvContext * pContext ); +S_API HSteamNetConnection SteamAPI_ISteamNetworkingSockets_ConnectP2PCustomSignaling( ISteamNetworkingSockets* self, ISteamNetworkingConnectionSignaling * pSignaling, const SteamNetworkingIdentity * pPeerIdentity, int nRemoteVirtualPort, int nOptions, const SteamNetworkingConfigValue_t * pOptions ); +S_API bool SteamAPI_ISteamNetworkingSockets_ReceivedP2PCustomSignal( ISteamNetworkingSockets* self, const void * pMsg, int cbMsg, ISteamNetworkingSignalingRecvContext * pContext ); S_API bool SteamAPI_ISteamNetworkingSockets_GetCertificateRequest( ISteamNetworkingSockets* self, int * pcbBlob, void * pBlob, SteamNetworkingErrMsg & errMsg ); S_API bool SteamAPI_ISteamNetworkingSockets_SetCertificate( ISteamNetworkingSockets* self, const void * pCertificate, int cbCertificate, SteamNetworkingErrMsg & errMsg ); S_API void SteamAPI_ISteamNetworkingSockets_RunCallbacks( ISteamNetworkingSockets* self ); // ISteamNetworkingUtils -S_API ISteamNetworkingUtils *SteamAPI_SteamNetworkingUtils_v003(); +S_API ISteamNetworkingUtils *SteamAPI_SteamNetworkingUtils_SteamAPI_v003(); S_API SteamNetworkingMessage_t * SteamAPI_ISteamNetworkingUtils_AllocateMessage( ISteamNetworkingUtils* self, int cbAllocateBuffer ); S_API void SteamAPI_ISteamNetworkingUtils_InitRelayNetworkAccess( ISteamNetworkingUtils* self ); S_API ESteamNetworkingAvailability SteamAPI_ISteamNetworkingUtils_GetRelayNetworkStatus( ISteamNetworkingUtils* self, SteamRelayNetworkStatus_t * pDetails ); @@ -1043,6 +1046,10 @@ S_API void SteamAPI_SteamNetworkingIdentity_SetSteamID64( SteamNetworkingIdentit S_API uint64 SteamAPI_SteamNetworkingIdentity_GetSteamID64( SteamNetworkingIdentity* self ); S_API bool SteamAPI_SteamNetworkingIdentity_SetXboxPairwiseID( SteamNetworkingIdentity* self, const char * pszString ); S_API const char * SteamAPI_SteamNetworkingIdentity_GetXboxPairwiseID( SteamNetworkingIdentity* self ); +S_API void SteamAPI_SteamNetworkingIdentity_SetPSNID( SteamNetworkingIdentity* self, uint64 id ); +S_API uint64 SteamAPI_SteamNetworkingIdentity_GetPSNID( SteamNetworkingIdentity* self ); +S_API void SteamAPI_SteamNetworkingIdentity_SetStadiaID( SteamNetworkingIdentity* self, uint64 id ); +S_API uint64 SteamAPI_SteamNetworkingIdentity_GetStadiaID( SteamNetworkingIdentity* self ); S_API void SteamAPI_SteamNetworkingIdentity_SetIPAddr( SteamNetworkingIdentity* self, const SteamNetworkingIPAddr & addr ); S_API const SteamNetworkingIPAddr * SteamAPI_SteamNetworkingIdentity_GetIPAddr( SteamNetworkingIdentity* self ); S_API void SteamAPI_SteamNetworkingIdentity_SetLocalHost( SteamNetworkingIdentity* self ); diff --git a/public/steam/steam_gameserver.h b/public/steam/steam_gameserver.h index bec600d..71f681e 100644 --- a/public/steam/steam_gameserver.h +++ b/public/steam/steam_gameserver.h @@ -22,25 +22,29 @@ enum EServerMode eServerModeAuthenticationAndSecure = 3, // Authenticate users, list on the server list and VAC protect clients }; +/// Pass to SteamGameServer_Init to indicate that the same UDP port will be used for game traffic +/// UDP queries. In this case, Steam will not open up a socket to handle server browser queries, +/// and you must use ISteamGameServer::HandleIncomingPacket and ISteamGameServer::GetNextOutgoingPacket +/// to handle packets related to server discovery on your socket. +#define MASTERSERVERUPDATERPORT_USEGAMESOCKETSHARE ((uint16)-1) + // Initialize SteamGameServer client and interface objects, and set server properties which may not be changed. // // After calling this function, you should set any additional server parameters, and then // call ISteamGameServer::LogOnAnonymous() or ISteamGameServer::LogOn() // -// - usSteamPort is the local port used to communicate with the steam servers. -// NOTE: unless you are using ver old Steam client binaries, this parameter is ignored, and -// you should pass 0. Gameservers now always use WebSockets to talk to Steam. -// This protocol is TCP-based and thus always uses an ephemeral local port. -// Older steam client binaries used UDP to talk to Steam, and this argument was useful. -// A future version of the SDK will remove this argument. -// - usGamePort is the port that clients will connect to for gameplay. +// - unIP will usually be zero. If you are on a machine with multiple IP addresses, you can pass a non-zero +// value here and the relevant sockets will be bound to that IP. This can be used to ensure that +// the IP you desire is the one used in the server browser. +// - usGamePort is the port that clients will connect to for gameplay. You will usually open up your +// own socket bound to this port. // - usQueryPort is the port that will manage server browser related duties and info // pings from clients. If you pass MASTERSERVERUPDATERPORT_USEGAMESOCKETSHARE for usQueryPort, then it // will use "GameSocketShare" mode, which means that the game is responsible for sending and receiving // UDP packets for the master server updater. See references to GameSocketShare in isteamgameserver.h. -// - The version string is usually in the form x.x.x.x, and is used by the master server to detect when the +// - The version string should be in the form x.x.x.x, and is used by the master server to detect when the // server is out of date. (Only servers with the latest version will be listed.) -inline bool SteamGameServer_Init( uint32 unIP, uint16 usSteamPort, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ); +inline bool SteamGameServer_Init( uint32 unIP, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ); // Shutdown SteamGameSeverXxx interfaces, log out, and free resources. S_API void SteamGameServer_Shutdown(); @@ -94,10 +98,10 @@ inline bool CSteamGameServerAPIContext::Init() } #endif -S_API bool S_CALLTYPE SteamInternal_GameServer_Init( uint32 unIP, uint16 usPort, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ); -inline bool SteamGameServer_Init( uint32 unIP, uint16 usSteamPort, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ) +S_API bool S_CALLTYPE SteamInternal_GameServer_Init( uint32 unIP, uint16 usLegacySteamPort, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ); +inline bool SteamGameServer_Init( uint32 unIP, uint16 usGamePort, uint16 usQueryPort, EServerMode eServerMode, const char *pchVersionString ) { - if ( !SteamInternal_GameServer_Init( unIP, usSteamPort, usGamePort, usQueryPort, eServerMode, pchVersionString ) ) + if ( !SteamInternal_GameServer_Init( unIP, 0, usGamePort, usQueryPort, eServerMode, pchVersionString ) ) return false; return true; diff --git a/public/steam/steamclientpublic.h b/public/steam/steamclientpublic.h index f744263..695bb9c 100644 --- a/public/steam/steamclientpublic.h +++ b/public/steam/steamclientpublic.h @@ -142,6 +142,9 @@ enum EResult k_EResultAccountDeleted = 114, // account has been deleted k_EResultExistingUserCancelledLicense = 115, // A license for this already exists, but cancelled k_EResultCommunityCooldown = 116, // access is denied because of a community cooldown (probably from support profile data resets) + k_EResultNoLauncherSpecified = 117, // No launcher was specified, but a launcher was needed to choose correct realm for operation. + k_EResultMustAgreeToSSA = 118, // User must agree to china SSA or global SSA before login + k_EResultLauncherMigrated = 119, // The specified launcher type is no longer supported; the user should be directed elsewhere }; // Error codes for use with the voice functions @@ -311,7 +314,7 @@ enum EAppType k_EAppType_Beta = 0x10000, // this is a beta version of a game k_EAppType_Shortcut = 0x40000000, // just a shortcut, client side only - k_EAppType_DepotOnly = 0x80000000, // placeholder since depots and apps share the same namespace + k_EAppType_DepotOnly_DEPRECATED = 0x80000000, // there shouldn't be any appinfo for depots }; @@ -556,6 +559,7 @@ enum EVRHMDType k_eEVRHMDType_HP_Unknown = 80, // HP unknown HMD k_eEVRHMDType_HP_WindowsMR = 81, // HP Windows MR headset k_eEVRHMDType_HP_Reverb = 82, // HP Reverb Windows MR headset + k_eEVRHMDType_HP_ReverbG2 = 1463, // HP Reverb G2 Windows MR headset k_eEVRHMDType_Samsung_Unknown = 90, // Samsung unknown HMD k_eEVRHMDType_Samsung_Odyssey = 91, // Samsung Odyssey Windows MR headset diff --git a/public/steam/steamnetworkingtypes.h b/public/steam/steamnetworkingtypes.h index 7a70add..5b35a4e 100644 --- a/public/steam/steamnetworkingtypes.h +++ b/public/steam/steamnetworkingtypes.h @@ -6,26 +6,40 @@ #ifndef STEAMNETWORKINGTYPES #define STEAMNETWORKINGTYPES -#ifdef _WIN32 #pragma once -#endif #include #include +#include "steamtypes.h" +#include "steamclientpublic.h" -//---------------------------------------- -// SteamNetworkingSockets library config -// Compiling in Steam public branch. -#define STEAMNETWORKINGSOCKETS_STEAM -#ifdef STEAMNETWORKINGSOCKETS_STATIC_LINK - #define STEAMNETWORKINGSOCKETS_INTERFACE extern +//----------------------------------------------------------------------------- +// SteamNetworkingSockets config. +//#define STEAMNETWORKINGSOCKETS_STANDALONELIB // Comment this in to support compiling/linking with the standalone library / gamenetworkingsockets opensource +#define STEAMNETWORKINGSOCKETS_STEAMAPI // Compiling/link with steam_api.h and Steamworks SDK +//----------------------------------------------------------------------------- + +#if !defined( STEAMNETWORKINGSOCKETS_OPENSOURCE ) && !defined( STEAMNETWORKINGSOCKETS_STREAMINGCLIENT ) + #define STEAMNETWORKINGSOCKETS_STEAM +#endif +#ifdef NN_NINTENDO_SDK // We always static link on Nintendo + #define STEAMNETWORKINGSOCKETS_STATIC_LINK +#endif +#if defined( STEAMNETWORKINGSOCKETS_STATIC_LINK ) + #define STEAMNETWORKINGSOCKETS_INTERFACE extern "C" +#elif defined( STEAMNETWORKINGSOCKETS_FOREXPORT ) + #ifdef _WIN32 + #define STEAMNETWORKINGSOCKETS_INTERFACE extern "C" __declspec( dllexport ) + #else + #define STEAMNETWORKINGSOCKETS_INTERFACE extern "C" __attribute__((visibility("default"))) + #endif +#else + #ifdef _WIN32 + #define STEAMNETWORKINGSOCKETS_INTERFACE extern "C" __declspec( dllimport ) + #else + #define STEAMNETWORKINGSOCKETS_INTERFACE extern "C" + #endif #endif -#define STEAMNETWORKINGSOCKETS_STEAMCLIENT -#define STEAMNETWORKINGSOCKETS_ENABLE_SDR -#include "steam_api_common.h" -// -//---------------------------------------- - #if defined( VALVE_CALLBACK_PACK_SMALL ) #pragma pack( push, 4 ) @@ -195,18 +209,18 @@ struct SteamNetworkingIPAddr /// (This means that you cannot tell if a zero port was explicitly specified.) inline bool ParseString( const char *pszStr ); + /// RFC4038, section 4.2 + struct IPv4MappedAddress { + uint64 m_8zeros; + uint16 m_0000; + uint16 m_ffff; + uint8 m_ip[ 4 ]; // NOTE: As bytes, i.e. network byte order + }; + union { uint8 m_ipv6[ 16 ]; - #ifndef API_GEN // API generator doesn't understand this. The bindings will just use the accessors - struct // IPv4 "mapped address" (rfc4038 section 4.2) - { - uint64 m_8zeros; - uint16 m_0000; - uint16 m_ffff; - uint8 m_ip[ 4 ]; // NOTE: As bytes, i.e. network byte order - } m_ipv4; - #endif + IPv4MappedAddress m_ipv4; }; uint16 m_port; // Host byte order @@ -659,6 +673,9 @@ struct SteamNetConnectionInfo_t /// connection type (and peer information), and any name /// given to the connection by the app. This string is used in various /// internal logging messages. + /// + /// Note that the connection ID *usually* matches the HSteamNetConnection + /// handle, but in certain cases with symmetric connections it might not. char m_szConnectionDescription[ k_cchSteamNetworkingMaxConnectionDescription ]; /// Internal stuff, room to change API easily @@ -1297,6 +1314,12 @@ enum ESteamNetworkingConfigValue /// See: ISteamNetworkingUtils::SetGlobalCallback_MessagesSessionFailed k_ESteamNetworkingConfig_Callback_MessagesSessionFailed = 205, + /// [global FnSteamNetworkingSocketsCreateConnectionSignaling] Callback that will + /// be invoked when we need to create a signaling object for a connection + /// initiated locally. See: ISteamNetworkingSockets::ConnectP2P, + /// ISteamNetworkingMessages. + k_ESteamNetworkingConfig_Callback_CreateConnectionSignaling = 206, + // // P2P settings // @@ -1600,17 +1623,6 @@ inline const uint8 *SteamNetworkingIdentity::GetGenericBytes( int &cbLen ) const inline bool SteamNetworkingIdentity::operator==(const SteamNetworkingIdentity &x ) const { return m_eType == x.m_eType && m_cbSize == x.m_cbSize && memcmp( m_genericBytes, x.m_genericBytes, m_cbSize ) == 0; } inline void SteamNetworkingMessage_t::Release() { (*m_pfnRelease)( this ); } -#if defined( STEAMNETWORKINGSOCKETS_STATIC_LINK ) || !defined( STEAMNETWORKINGSOCKETS_STEAMCLIENT ) -STEAMNETWORKINGSOCKETS_INTERFACE void SteamNetworkingIPAddr_ToString( const SteamNetworkingIPAddr *pAddr, char *buf, size_t cbBuf, bool bWithPort ); -STEAMNETWORKINGSOCKETS_INTERFACE bool SteamNetworkingIPAddr_ParseString( SteamNetworkingIPAddr *pAddr, const char *pszStr ); -STEAMNETWORKINGSOCKETS_INTERFACE void SteamNetworkingIdentity_ToString( const SteamNetworkingIdentity *pIdentity, char *buf, size_t cbBuf ); -STEAMNETWORKINGSOCKETS_INTERFACE bool SteamNetworkingIdentity_ParseString( SteamNetworkingIdentity *pIdentity, size_t sizeofIdentity, const char *pszStr ); -inline void SteamNetworkingIPAddr::ToString( char *buf, size_t cbBuf, bool bWithPort ) const { SteamNetworkingIPAddr_ToString( this, buf, cbBuf, bWithPort ); } -inline bool SteamNetworkingIPAddr::ParseString( const char *pszStr ) { return SteamNetworkingIPAddr_ParseString( this, pszStr ); } -inline void SteamNetworkingIdentity::ToString( char *buf, size_t cbBuf ) const { SteamNetworkingIdentity_ToString( this, buf, cbBuf ); } -inline bool SteamNetworkingIdentity::ParseString( const char *pszStr ) { return SteamNetworkingIdentity_ParseString( this, sizeof(*this), pszStr ); } -#endif - #endif // #ifndef API_GEN #endif // #ifndef STEAMNETWORKINGTYPES diff --git a/redistributable_bin/linux32/libsteam_api.so b/redistributable_bin/linux32/libsteam_api.so index 928c5eea4383818ef583f1b279e5db537b3456a9..bb5d4fe80816a4a11408bc7e21abae8dbf45d3db 100644 GIT binary patch delta 111027 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 z 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