[Steam] Add native callback interface
This commit is contained in:
parent
e70a289b97
commit
c8a41139cf
@ -30,4 +30,79 @@ namespace Steam
|
||||
virtual void ActivateGameOverlayToStore(unsigned int nAppID);
|
||||
virtual void SetPlayedWith(SteamID steamIDUserPlayedWith);
|
||||
};
|
||||
|
||||
class Friends15
|
||||
{
|
||||
public:
|
||||
virtual const char *GetPersonaName() = 0;
|
||||
virtual uint64_t SetPersonaName(const char *pchPersonaName) = 0;
|
||||
virtual int GetPersonaState() = 0;
|
||||
virtual int GetFriendCount(int iFriendFlags) = 0;
|
||||
virtual SteamID GetFriendByIndex(int iFriend, int iFriendFlags) = 0;
|
||||
virtual int GetFriendRelationship(SteamID steamIDFriend) = 0;
|
||||
virtual int GetFriendPersonaState(SteamID steamIDFriend) = 0;
|
||||
virtual const char *GetFriendPersonaName(SteamID steamIDFriend) = 0;
|
||||
virtual bool GetFriendGamePlayed(SteamID steamID, void *pGamePlayInfo) = 0;
|
||||
virtual const char *GetFriendPersonaNameHistory(SteamID steamIDFriend, int iPersonaName) = 0;
|
||||
virtual int GetFriendSteamLevel(SteamID steamIDFriend) = 0;
|
||||
virtual const char *GetPlayerNickname(SteamID steamIDPlayer) = 0;
|
||||
virtual int16_t GetFriendsGroupCount() = 0;
|
||||
virtual int16_t GetFriendsGroupIDByIndex(int32_t) = 0;
|
||||
virtual const char * GetFriendsGroupName(int16_t) = 0;
|
||||
virtual int GetFriendsGroupMembersCount(int16_t) = 0;
|
||||
virtual int GetFriendsGroupMembersList(int16_t, SteamID *, int32_t) = 0;
|
||||
virtual bool HasFriend(SteamID steamIDFriend, int iFriendFlags) = 0;
|
||||
virtual int GetClanCount() = 0;
|
||||
virtual SteamID GetClanByIndex(int iClan) = 0;
|
||||
virtual const char *GetClanName(SteamID steamIDClan) = 0;
|
||||
virtual const char *GetClanTag(SteamID steamIDClan) = 0;
|
||||
virtual bool GetClanActivityCounts(SteamID steamID, int *pnOnline, int *pnInGame, int *pnChatting) = 0;
|
||||
virtual uint64_t DownloadClanActivityCounts(SteamID groupIDs[], int nIds) = 0;
|
||||
virtual int GetFriendCountFromSource(SteamID steamIDSource) = 0;
|
||||
virtual SteamID GetFriendFromSourceByIndex(SteamID steamIDSource, int iFriend) = 0;
|
||||
virtual bool IsUserInSource(SteamID steamIDUser, SteamID steamIDSource) = 0;
|
||||
virtual void SetInGameVoiceSpeaking(SteamID steamIDUser, bool bSpeaking) = 0;
|
||||
virtual void ActivateGameOverlay(const char *pchDialog) = 0;
|
||||
virtual void ActivateGameOverlayToUser(const char *pchDialog, SteamID steamID) = 0;
|
||||
virtual void ActivateGameOverlayToWebPage(const char *pchURL) = 0;
|
||||
virtual void ActivateGameOverlayToStore(uint32_t nAppID, int eFlag) = 0;
|
||||
virtual void SetPlayedWith(SteamID steamIDUserPlayedWith) = 0;
|
||||
virtual void ActivateGameOverlayInviteDialog(SteamID steamIDLobby) = 0;
|
||||
virtual int GetSmallFriendAvatar(SteamID steamIDFriend) = 0;
|
||||
virtual int GetMediumFriendAvatar(SteamID steamIDFriend) = 0;
|
||||
virtual int GetLargeFriendAvatar(SteamID steamIDFriend) = 0;
|
||||
virtual bool RequestUserInformation(SteamID steamIDUser, bool bRequireNameOnly) = 0;
|
||||
virtual uint64_t RequestClanOfficerList(SteamID steamIDClan) = 0;
|
||||
virtual SteamID GetClanOwner(SteamID steamIDClan) = 0;
|
||||
virtual int GetClanOfficerCount(SteamID steamIDClan) = 0;
|
||||
virtual SteamID GetClanOfficerByIndex(SteamID steamIDClan, int iOfficer) = 0;
|
||||
virtual int GetUserRestrictions() = 0;
|
||||
virtual bool SetRichPresence(const char *pchKey, const char *pchValue) = 0;
|
||||
virtual void ClearRichPresence() = 0;
|
||||
virtual const char *GetFriendRichPresence(SteamID steamIDFriend, const char *pchKey) = 0;
|
||||
virtual int GetFriendRichPresenceKeyCount(SteamID steamIDFriend) = 0;
|
||||
virtual const char *GetFriendRichPresenceKeyByIndex(SteamID steamIDFriend, int iKey) = 0;
|
||||
virtual void RequestFriendRichPresence(SteamID steamIDFriend) = 0;
|
||||
virtual bool InviteUserToGame(SteamID steamIDFriend, const char *pchConnectString) = 0;
|
||||
virtual int GetCoplayFriendCount() = 0;
|
||||
virtual SteamID GetCoplayFriend(int iCoplayFriend) = 0;
|
||||
virtual int GetFriendCoplayTime(SteamID steamIDFriend) = 0;
|
||||
virtual uint32_t GetFriendCoplayGame(SteamID steamIDFriend) = 0;
|
||||
virtual uint64_t JoinClanChatRoom(SteamID steamIDClan) = 0;
|
||||
virtual bool LeaveClanChatRoom(SteamID steamIDClan) = 0;
|
||||
virtual int GetClanChatMemberCount(SteamID steamIDClan) = 0;
|
||||
virtual SteamID GetChatMemberByIndex(SteamID steamIDClan, int iUser) = 0;
|
||||
virtual bool SendClanChatMessage(SteamID steamIDClanChat, const char *pchText) = 0;
|
||||
virtual int GetClanChatMessage(SteamID steamIDClanChat, int iMessage, void *prgchText, int cchTextMax, int *peChatEntryType, SteamID *pSteamIDChatter) = 0;
|
||||
virtual bool IsClanChatAdmin(SteamID steamIDClanChat, SteamID steamIDUser) = 0;
|
||||
virtual bool IsClanChatWindowOpenInSteam(SteamID steamIDClanChat) = 0;
|
||||
virtual bool OpenClanChatWindowInSteam(SteamID steamIDClanChat) = 0;
|
||||
virtual bool CloseClanChatWindowInSteam(SteamID steamIDClanChat) = 0;
|
||||
virtual bool SetListenForFriendsMessages(bool bInterceptEnabled) = 0;
|
||||
virtual bool ReplyToFriendMessage(SteamID steamIDFriend, const char *pchMsgToSend) = 0;
|
||||
virtual int GetFriendMessage(SteamID steamIDFriend, int iMessageID, void *pvData, int cubData, int *peChatEntryType) = 0;
|
||||
virtual uint64_t GetFollowerCount(SteamID steamID) = 0;
|
||||
virtual uint64_t IsFollowing(SteamID steamID) = 0;
|
||||
virtual uint64_t EnumerateFollowingList(uint32_t unStartIndex) = 0;
|
||||
};
|
||||
}
|
||||
|
@ -12,11 +12,19 @@ namespace Steam
|
||||
void* Proxy::SteamPipe;
|
||||
void* Proxy::SteamUser;
|
||||
|
||||
Friends* Proxy::SteamFriends;
|
||||
Friends15* Proxy::SteamFriends;
|
||||
Utils* Proxy::SteamUtils;
|
||||
|
||||
uint32_t Proxy::AppId;
|
||||
|
||||
std::recursive_mutex Proxy::CallMutex;
|
||||
std::vector<Proxy::CallContainer> Proxy::Calls;
|
||||
std::unordered_map<int32_t, void*> Proxy::Callbacks;
|
||||
|
||||
std::function<Proxy::SteamBGetCallbackFn> Proxy::SteamBGetCallback;
|
||||
std::function<Proxy::SteamFreeLastCallbackFn> Proxy::SteamFreeLastCallback;
|
||||
std::function<Proxy::SteamGetAPICallResultFn> Proxy::SteamGetAPICallResult;
|
||||
|
||||
void Proxy::SetGame(uint32_t appId)
|
||||
{
|
||||
Proxy::AppId = appId;
|
||||
@ -73,6 +81,125 @@ namespace Steam
|
||||
}
|
||||
}
|
||||
|
||||
void Proxy::RegisterCall(int32_t callId, uint32_t size, uint64_t call)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Proxy::CallMutex);
|
||||
|
||||
Proxy::CallContainer contianer;
|
||||
contianer.call = call;
|
||||
contianer.dataSize = size;
|
||||
contianer.callId = callId;
|
||||
contianer.handled = false;
|
||||
|
||||
Proxy::Calls.push_back(contianer);
|
||||
}
|
||||
|
||||
void Proxy::UnregisterCalls()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Proxy::CallMutex);
|
||||
|
||||
for(auto i = Proxy::Calls.begin(); i != Proxy::Calls.end(); ++i)
|
||||
{
|
||||
if(i->handled)
|
||||
{
|
||||
i = Proxy::Calls.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Proxy::RegisterCallback(int32_t callId, void* callback)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Proxy::CallMutex);
|
||||
Proxy::Callbacks[callId] = callback;
|
||||
}
|
||||
|
||||
void Proxy::UnregisterCallback(int32_t callId)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Proxy::CallMutex);
|
||||
Proxy::Callbacks.erase(callId);
|
||||
}
|
||||
|
||||
void Proxy::RunCallback(int32_t callId, void* data)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Proxy::CallMutex);
|
||||
|
||||
auto callback = Proxy::Callbacks.find(callId);
|
||||
if (callback != Proxy::Callbacks.end())
|
||||
{
|
||||
::Utils::Hook::Call<void(void*)>(callback->second)(data);
|
||||
}
|
||||
}
|
||||
|
||||
void Proxy::RunFrame()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Proxy::CallMutex);
|
||||
|
||||
if (Proxy::SteamUtils)
|
||||
{
|
||||
Proxy::SteamUtils->RunFrame();
|
||||
}
|
||||
|
||||
Proxy::CallbackMsg message;
|
||||
while (Proxy::SteamBGetCallback(Proxy::SteamPipe, &message))
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Components::Logger::Print("Steam::Proxy: Callback dispatched: %d\n", message.m_iCallback);
|
||||
#endif
|
||||
|
||||
Steam::Callbacks::RunCallback(message.m_iCallback, message.m_pubParam);
|
||||
Proxy::RunCallback(message.m_iCallback, message.m_pubParam);
|
||||
Proxy::SteamFreeLastCallback(Proxy::SteamPipe);
|
||||
}
|
||||
|
||||
if (Proxy::SteamUtils)
|
||||
{
|
||||
for (auto &call : Proxy::Calls)
|
||||
{
|
||||
bool failed = false;
|
||||
if (Proxy::SteamUtils->IsAPICallCompleted(call.call, &failed))
|
||||
{
|
||||
::Utils::Memory::Allocator allocator;
|
||||
|
||||
#ifdef DEBUG
|
||||
Components::Logger::Print("Steam::Proxy: Handling call: %d\n", call.callId);
|
||||
#endif
|
||||
|
||||
call.handled = true;
|
||||
|
||||
if (failed)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
auto error = Proxy::SteamUtils->GetAPICallFailureReason(call.call);
|
||||
Components::Logger::Print("Steam::Proxy: API call failed: %X Handle: %llX\n", error, call.call);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
char* buffer = allocator.allocateArray<char>(call.dataSize);
|
||||
Proxy::SteamUtils->GetAPICallResult(call.call, buffer, call.dataSize, call.callId, &failed);
|
||||
|
||||
if (failed)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
auto error = Proxy::SteamUtils->GetAPICallFailureReason(call.call);
|
||||
Components::Logger::Print("Steam::Proxy: GetAPICallResult failed: %X Handle: %llX\n", error, call.call);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
Proxy::RunCallback(call.callId, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Proxy::UnregisterCalls();
|
||||
}
|
||||
|
||||
bool Proxy::Inititalize()
|
||||
{
|
||||
std::string directoy = Proxy::GetSteamDirectory();
|
||||
@ -87,6 +214,18 @@ namespace Steam
|
||||
Proxy::SteamClient = Proxy::Client.get<ISteamClient008*(const char*, int*)>("CreateInterface")("SteamClient008", nullptr);
|
||||
if(!Proxy::SteamClient) return false;
|
||||
|
||||
Proxy::SteamBGetCallback = Proxy::Client.get<Proxy::SteamBGetCallbackFn>("Steam_BGetCallback");
|
||||
if (!Proxy::SteamBGetCallback) return false;
|
||||
|
||||
Proxy::SteamFreeLastCallback = Proxy::Client.get<Proxy::SteamFreeLastCallbackFn>("Steam_FreeLastCallback");
|
||||
if (!Proxy::SteamFreeLastCallback) return false;
|
||||
|
||||
Proxy::SteamGetAPICallResult = Proxy::Client.get<Proxy::SteamGetAPICallResultFn>("Steam_GetAPICallResult");
|
||||
if (!Proxy::SteamGetAPICallResult) return false;
|
||||
|
||||
Proxy::SteamClient = Proxy::Client.get<ISteamClient008*(const char*, int*)>("CreateInterface")("SteamClient008", nullptr);
|
||||
if (!Proxy::SteamClient) return false;
|
||||
|
||||
Proxy::SteamPipe = Proxy::SteamClient->CreateSteamPipe();
|
||||
if (!Proxy::SteamPipe) return false;
|
||||
|
||||
@ -99,7 +238,7 @@ namespace Steam
|
||||
Proxy::ClientUser = Proxy::ClientEngine->GetIClientUser(Proxy::SteamUser, Proxy::SteamPipe, "CLIENTUSER_INTERFACE_VERSION001");
|
||||
if (!Proxy::ClientUser) return false;
|
||||
|
||||
Proxy::SteamFriends = reinterpret_cast<Friends*>(Proxy::SteamClient->GetISteamFriends(Proxy::SteamUser, Proxy::SteamPipe, "SteamFriends005"));
|
||||
Proxy::SteamFriends = reinterpret_cast<Friends15*>(Proxy::SteamClient->GetISteamFriends(Proxy::SteamUser, Proxy::SteamPipe, "SteamFriends015"));
|
||||
if (!Proxy::SteamFriends) return false;
|
||||
|
||||
Proxy::SteamUtils = reinterpret_cast<Utils*>(Proxy::SteamClient->GetISteamFriends(Proxy::SteamUser, Proxy::SteamPipe, "SteamUtils005"));
|
||||
|
@ -346,10 +346,38 @@ namespace Steam
|
||||
static bool IsOverlayEnabled();
|
||||
static bool BOverlayNeedsPresent();
|
||||
|
||||
static Friends* SteamFriends;
|
||||
static void RunFrame();
|
||||
|
||||
static void RegisterCall(int32_t callId, uint32_t size, uint64_t call);
|
||||
|
||||
static void RegisterCallback(int32_t callId, void* callback);
|
||||
static inline void RegisterCallback(int32_t callId, void(*callback)(void*)) { RegisterCallback(callId, static_cast<void*>(callback)); }
|
||||
static void UnregisterCallback(int32_t callId);
|
||||
|
||||
static Friends15* SteamFriends;
|
||||
static Utils* SteamUtils;
|
||||
|
||||
private:
|
||||
typedef bool(SteamBGetCallbackFn)(void* hpipe, void *pCallbackMsg);
|
||||
typedef void(SteamFreeLastCallbackFn)(void* hpipe);
|
||||
typedef bool(SteamGetAPICallResultFn)(void* hpipe, uint64_t hSteamAPICall, void* pCallback, int cubCallback, int iCallbackExpected, bool* pbFailed);
|
||||
|
||||
struct CallContainer
|
||||
{
|
||||
uint64_t call;
|
||||
bool handled;
|
||||
int32_t callId;
|
||||
uint32_t dataSize;
|
||||
};
|
||||
|
||||
struct CallbackMsg
|
||||
{
|
||||
int32_t m_hSteamUser;
|
||||
int m_iCallback;
|
||||
uint8_t *m_pubParam;
|
||||
int m_cubParam;
|
||||
};
|
||||
|
||||
static ::Utils::Library Client;
|
||||
static ::Utils::Library Overlay;
|
||||
|
||||
@ -362,6 +390,18 @@ namespace Steam
|
||||
|
||||
static uint32_t AppId;
|
||||
|
||||
static std::recursive_mutex CallMutex;
|
||||
static std::vector<CallContainer> Calls;
|
||||
static std::unordered_map<int32_t, void*> Callbacks;
|
||||
|
||||
static std::function<SteamBGetCallbackFn> SteamBGetCallback;
|
||||
static std::function<SteamFreeLastCallbackFn> SteamFreeLastCallback;
|
||||
static std::function<SteamGetAPICallResultFn> SteamGetAPICallResult;
|
||||
|
||||
static void RunCallback(int32_t callId, void* data);
|
||||
|
||||
static void UnregisterCalls();
|
||||
|
||||
static std::string GetSteamDirectory();
|
||||
};
|
||||
}
|
||||
|
@ -74,6 +74,19 @@ namespace Steam
|
||||
}
|
||||
}
|
||||
|
||||
void Callbacks::RunCallback(int32_t callback, void* data)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Callbacks::Mutex);
|
||||
|
||||
for (auto cb : Callbacks::CallbackList)
|
||||
{
|
||||
if (cb && cb->GetICallback() == callback)
|
||||
{
|
||||
cb->Run(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Callbacks::Uninitialize()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> _(Callbacks::Mutex);
|
||||
@ -94,9 +107,9 @@ namespace Steam
|
||||
bool SteamAPI_Init()
|
||||
{
|
||||
#ifndef DISABLE_STEAM_GAME
|
||||
if (!Components::Flags::HasFlag("-nosteam"))
|
||||
if (!Components::Flags::HasFlag("nosteam"))
|
||||
{
|
||||
Proxy::SetGame(10190);
|
||||
//Proxy::SetGame(10190);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -107,9 +120,9 @@ namespace Steam
|
||||
else
|
||||
{
|
||||
#ifndef DISABLE_STEAM_GAME
|
||||
if (!Components::Flags::HasFlag("-nosteam"))
|
||||
if (!Components::Flags::HasFlag("nosteam"))
|
||||
{
|
||||
Proxy::SetMod("IW4x - Modern Warfare 2");
|
||||
//Proxy::SetMod("IW4x - Modern Warfare 2");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -130,6 +143,7 @@ namespace Steam
|
||||
void SteamAPI_RunCallbacks()
|
||||
{
|
||||
Callbacks::RunCallbacks();
|
||||
Proxy::RunFrame();
|
||||
}
|
||||
|
||||
void SteamAPI_Shutdown()
|
||||
|
@ -81,6 +81,8 @@ namespace Steam
|
||||
static void ReturnCall(void* data, int size, int type, uint64_t call);
|
||||
static void RunCallbacks();
|
||||
|
||||
static void RunCallback(int32_t callback, void* data);
|
||||
|
||||
static void Uninitialize();
|
||||
|
||||
private:
|
||||
|
@ -76,6 +76,11 @@ namespace Utils
|
||||
return Call<T>(reinterpret_cast<DWORD>(function));
|
||||
}
|
||||
|
||||
template <typename T> static std::function<T> Call(void* function)
|
||||
{
|
||||
return Call<T>(reinterpret_cast<DWORD>(function));
|
||||
}
|
||||
|
||||
static void SetString(void* place, const char* string, size_t length);
|
||||
static void SetString(DWORD place, const char* string, size_t length);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user