Commits

Ryan Kistner  committed 8ab0bc0

Started work on callbacks

  • Participants
  • Parent commits 4a23cae

Comments (0)

Files changed (9)

File Open Steamworks/CCallback.h

 	uint8 m_nCallbackFlags;
 	int m_iCallback;
 	friend class CCallbackMgr;
+	friend class CallbackManager;
 };
 
 //-----------------------------------------------------------------------------

File Open Steamworks/Steamclient.h

 
 S_API void STEAM_CALL SteamAPI_RunCallbacks();
 
+// functions used by the utility CCallback objects to receive callbacks
 S_API void STEAM_CALL SteamAPI_RegisterCallback( class CCallbackBase *pCallback, int iCallback );
 S_API void STEAM_CALL SteamAPI_UnregisterCallback( class CCallbackBase *pCallback );
-
+// functions used by the utility CCallResult objects to receive async call results
+S_API void STEAM_CALL SteamAPI_RegisterCallResult( class CCallbackBase *pCallback, SteamAPICall_t hAPICall );
+S_API void STEAM_CALL SteamAPI_UnregisterCallResult( class CCallbackBase *pCallback, SteamAPICall_t hAPICall );
 //----------------------------------------------------------------------------------------------------------------------------------------------------------//
 //	steamclient.dll private wrapper functions
 //

File steam_api/apitest/main.cpp

 
 int main(int argc, char *argv[])
 {
-	SteamAPI_Init();
+	SetEnvironmentVariableA("SteamAppId", "500");
+
+	if(!SteamAPI_Init())
+		return 0;
+
+	((ISteamMatchmaking007 *)SteamMatchmaking())->RequestLobbyList();
+
+	while(true)
+	{
+		SteamAPI_RunCallbacks();
+	}
 
 	SteamAPI_Shutdown();
 	return 0;

File steam_api/callbacks.cpp

 	provider.Set(module);
 }
 
+void CallbackManager::RunCallbacks(HSteamPipe pipe, bool bGameServer)
+{
+	CallbackMsg_t callbackMsg;
+	HSteamCall steamCall;
+
+	steamclient->RunFrame();
+
+	if( provider.Steam_BGetCallback(pipe, &callbackMsg, &steamCall) )
+	{
+		currentUser = callbackMsg.m_hSteamUser;
+
+		int32 callBack = callbackMsg.m_iCallback;
+		ECallbackType type = (ECallbackType)((callBack / 100) * 100);
+		std::cout << "[DEBUG] Callback: " << callBack << ", Type: " << EnumString<ECallbackType>::From(type) << ", Size: " << callbackMsg.m_cubParam << std::endl;
+
+		std::pair<CallbacksMap::iterator, CallbacksMap::iterator> range = callbacks.equal_range(callbackMsg.m_iCallback);
+		for(CallbacksMap::const_iterator iter = range.first; iter != range.second; ++iter)
+		{
+			CCallbackBase *callback = iter->second;
+
+			if(bGameServer && !(callback->m_nCallbackFlags & CCallbackBase::k_ECallbackFlagsGameServer))
+				continue;
+
+			callback->Run(callbackMsg.m_pubParam);
+		}
+
+		provider.Steam_FreeLastCallback(pipe);
+	}
+}
+
+
+
+
+void CallbackManager::RegisterCallback(int iCallback, CCallbackBase *callback)
+{
+	// since the property is there I'm going to set it so we have it for unregister, I'm not sure if the real steam_api uses it
+	// it has to be safe because if you were to register a CCallback with multiple callback numbers, who knows what one would be erased
+	callback->m_iCallback = iCallback;
+
+	callbacks.insert(CallbacksMap::value_type(iCallback, callback));
+}
+
+void CallbackManager::UnRegisterCallback(CCallbackBase *callback)
+{
+	std::pair<CallbacksMap::iterator, CallbacksMap::iterator> range = callbacks.equal_range( callback->m_iCallback );
+
+	CallbacksMap::const_iterator iter = range.first;
+	while(iter != range.second)
+	{
+		if(iter->second == callback)
+			iter = callbacks.erase(iter);
+		else
+			++iter;
+	}
+}
+
+
+
+
+void CallbackManager::RegisterAPICallResult(SteamAPICall_t apiCall, CCallbackBase *callback)
+{
+	apicalls.insert(APICallsMap::value_type(apiCall, callback));
+}
+
+void CallbackManager::UnRegisterAPICallResult(SteamAPICall_t apiCall, CCallbackBase *callback)
+{
+	std::pair<APICallsMap::iterator, APICallsMap::iterator> range = apicalls.equal_range( apiCall );
+
+	APICallsMap::const_iterator iter = range.first;
+	while(iter != range.second)
+	{
+		if(iter->second == callback)
+			iter = apicalls.erase(iter);
+		else
+			++iter;
+	}
+}
+
+
+
+
+S_API void STEAM_CALL SteamAPI_RegisterCallback( class CCallbackBase *pCallback, int iCallback )
+{
+	callbackmanager.RegisterCallback(iCallback, pCallback);
+}
+
+S_API void STEAM_CALL SteamAPI_UnregisterCallback( class CCallbackBase *pCallback )
+{
+	callbackmanager.UnRegisterCallback(pCallback);
+}
+
+
+
+
+S_API void STEAM_CALL SteamAPI_RegisterCallResult( class CCallbackBase *pCallback, SteamAPICall_t hAPICall )
+{
+	callbackmanager.RegisterAPICallResult(hAPICall, pCallback);
+}
+
+S_API void STEAM_CALL SteamAPI_UnregisterCallResult( class CCallbackBase *pCallback, SteamAPICall_t hAPICall )
+{
+	callbackmanager.UnRegisterAPICallResult(hAPICall, pCallback);
+}
+
+
+
+
+S_API void STEAM_CALL Steam_RunCallbacks( HSteamPipe hSteamPipe, bool bGameServerCallbacks )
+{
+	callbackmanager.RunCallbacks(hSteamPipe, bGameServerCallbacks);
+}
+
 S_API void STEAM_CALL Steam_RegisterInterfaceFuncs(void *hModule)
 {
 	callbackmanager.SetCallbackProvider((HMODULE)hModule);
+}
+
+
+
+S_API HSteamUser STEAM_CALL Steam_GetHSteamUserCurrent()
+{
+	return callbackmanager.currentUser;
 }

File steam_api/callbacks.h

 public:
 	void Set(HMODULE mod);
 	void ResolveExports();
+
+	inline bool Steam_BGetCallback( HSteamPipe hSteamPipe, CallbackMsg_t *pCallbackMsg, HSteamCall *phSteamCall ) { return getcallback(hSteamPipe, pCallbackMsg, phSteamCall); }
+	inline void Steam_FreeLastCallback( HSteamPipe hSteamPipe ) { freelastcallback(hSteamPipe); }
+	inline bool Steam_GetAPICallResult( HSteamPipe hSteamPipe, SteamAPICall_t hSteamAPICall, void *pCallback, int cubCallback, int iCallbackExpected, bool *pbFailed) { return getapicallresult(hSteamPipe, hSteamAPICall, pCallback, cubCallback, iCallbackExpected, pbFailed); }
+
 private:
 	HMODULE module;
 	SteamBGetCallbackFn getcallback;
 {
 public:
 	void SetCallbackProvider(HMODULE module);
+	void RunCallbacks(HSteamPipe pipe, bool bGameServer);
+
+	void RegisterCallback(int iCallback, CCallbackBase *callback);
+	void UnRegisterCallback(CCallbackBase *callback);
+
+	void RegisterAPICallResult(SteamAPICall_t apiCall, CCallbackBase *callback);
+	void UnRegisterAPICallResult(SteamAPICall_t apiCall, CCallbackBase *callback);
+
+	HSteamUser currentUser;
 private:
 	bool callbackTryCatch;
+	
+	typedef boost::unordered_multimap<int, CCallbackBase *> CallbacksMap;
+	CallbacksMap callbacks;
+	typedef boost::unordered_multimap<SteamAPICall_t, CCallbackBase *> APICallsMap;
+	APICallsMap apicalls;
 
 	CallbackProvider provider;
 };
 
 extern CallbackManager callbackmanager;
 
-S_API void STEAM_CALL Steam_RegisterInterfaceFuncs(void *hModule);
+S_API void STEAM_CALL SteamAPI_RegisterCallback( class CCallbackBase *pCallback, int iCallback );
+S_API void STEAM_CALL SteamAPI_UnregisterCallback( class CCallbackBase *pCallback );
+
+S_API void STEAM_CALL SteamAPI_RegisterCallResult( class CCallbackBase *pCallback, SteamAPICall_t hAPICall );
+S_API void STEAM_CALL SteamAPI_UnregisterCallResult( class CCallbackBase *pCallback, SteamAPICall_t hAPICall );
+
+S_API void STEAM_CALL Steam_RunCallbacks( HSteamPipe hSteamPipe, bool bGameServerCallbacks );
+S_API void STEAM_CALL Steam_RegisterInterfaceFuncs(void *hModule);
+
+S_API HSteamUser STEAM_CALL Steam_GetHSteamUserCurrent();

File steam_api/interfaces.cpp

 DEFINE_CURRENT_VERSION( STEAMMATCHMAKINGSERVERS,	002, ISteamMatchmakingServers,	SteamMatchmakingServers)
 DEFINE_CURRENT_VERSION( STEAMREMOTESTORAGE,			002, ISteamRemoteStorage,		SteamRemoteStorage)
 
-
-bool LoadInterfaces()
+bool LoadInterfaces(bool safe)
 {
-	std::ifstream ifcfg("steam_api.cfg");
-
 	options_description desc;
 	variables_map vm;
 
+	std::ifstream ifcfg("steam_api.cfg");
+
 	OptionDefinition *opt = OptionDefinition::front;
 	while(opt != NULL)
 	{
 	store(parse_config_file(ifcfg, desc), vm);
 
 	TRYGET_CURRENT_VERSION_FACTORY( STEAMCLIENT,		SteamClient )
+
+	if(safe)
+		return true;
+
 	TRYGET_CURRENT_VERSION_PIPE( STEAMUTILS,			SteamUtils,					GetISteamUtils )
 	TRYGET_CURRENT_VERSION( STEAMUSER,					SteamUser,					GetISteamUser )
 	TRYGET_CURRENT_VERSION( STEAMFRIENDS,				SteamFriends,				GetISteamFriends )

File steam_api/interfaces.h

 	IFACE##_PTR = (void *)clientFactory(IFACE##_VERSION.c_str(), NULL); \
 	if( IFACE##_PTR == NULL ) return false;
 
-bool LoadInterfaces();
+bool LoadInterfaces(bool safe);
 
 EXPORT_CURRENT_VERSION(ISteamClient,				SteamClient);
 EXPORT_CURRENT_VERSION(ISteamUser,					SteamUser);

File steam_api/steam_api.cpp

 CreateInterfaceFn clientFactory = NULL;
 
 STEAMCLIENT_ICLASS *steamclient = NULL;
+STEAMUTILS_ICLASS *steamutils = NULL;
 
 HSteamPipe pipe = 0;
 HSteamUser user = 0;
 
-S_API bool STEAM_CALL SteamAPI_Init()
-{
-	if(!SteamAPI_InitSafe())
-		return false;
-
-	if(!LoadInterfaces())
-		return false;
-
-	return true;
-}
-
-S_API bool STEAM_CALL SteamAPI_InitSafe()
+HSteamPipe SteamAPI_InitInternal()
 {
 	clientFactory = loader.Load();
 
 	if(clientFactory == NULL)
-		return false;
+		return 0;
 
 	steamclient = (STEAMCLIENT_ICLASS *)clientFactory(STEAMCLIENT_IFACE, NULL);
 
 	if(steamclient == NULL)
-		return false;
+		return 0;
 
-	pipe = steamclient->CreateSteamPipe();
+	HSteamPipe ipipe = steamclient->CreateSteamPipe();
+
+	if(ipipe == NULL)
+		return 0;
+
+	steamutils = (STEAMUTILS_ICLASS *)steamclient->GetISteamUtils(ipipe, STEAMUTILS_IFACE);
+
+	if(steamutils == NULL)
+		return 0;
+
+	return ipipe;
+}
+
+bool SteamAPI_InitInternalUser(bool safe)
+{
+	pipe = SteamAPI_InitInternal();
 
 	if(pipe == NULL)
 		return false;
 	if(user == NULL)
 		return false;
 
+	if(!LoadInterfaces(safe))
+		return false;
+
 	Steam_RegisterInterfaceFuncs(loader.GetSteamModule());
 
+	if(steamutils->GetAppID() == 0)
+	{
+		std::cerr << "[S_API] Load failure. AppID not set!" << std::endl;
+		return false;
+	}
+
 	return true;
 }
 
+
+
+S_API bool STEAM_CALL SteamAPI_Init()
+{
+	return SteamAPI_InitInternalUser(false);
+}
+
+S_API bool STEAM_CALL SteamAPI_InitSafe()
+{
+	return SteamAPI_InitInternalUser(true);
+}
+
+
+
 S_API void SteamAPI_Shutdown()
 {
 	if(user)
 	}
 }
 
+
+
+S_API void STEAM_CALL SteamAPI_RunCallbacks()
+{
+	if(pipe)
+		Steam_RunCallbacks(pipe, false);
+}
+
+
+
 S_API const char* STEAM_CALL SteamAPI_GetSteamInstallPath()
 {
 	return loader.GetSteamDir();
 }
 
+
+
 S_API HSteamPipe STEAM_CALL SteamAPI_GetHSteamPipe()
 {
 	return pipe;

File steam_api/steam_api.h

 #define STEAMCLIENT_ICLASS	ISteamClient008
 #define STEAMCLIENT_IFACE	STEAMCLIENT_INTERFACE_VERSION_008
 
+#define STEAMUTILS_ICLASS	ISteamUtils004
+#define STEAMUTILS_IFACE	STEAMUTILS_INTERFACE_VERSION_004
+
 extern CSteamAPILoader loader;
 extern CreateInterfaceFn clientFactory;
 
 extern STEAMCLIENT_ICLASS *steamclient;
+extern STEAMUTILS_ICLASS *steamutils;
 
 extern HSteamUser user;
 extern HSteamPipe pipe;
 
+HSteamPipe SteamAPI_InitInternal();
+
 S_API bool STEAM_CALL SteamAPI_Init();
 S_API bool STEAM_CALL SteamAPI_InitSafe();
 
 S_API HSteamUser STEAM_CALL SteamAPI_GetHSteamUser();
 S_API HSteamUser STEAM_CALL GetHSteamUser();
 
+S_API void STEAM_CALL SteamAPI_RunCallbacks();