Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavide Beatrici <git@davidebeatrici.dev>2020-10-28 01:21:44 +0300
committerDavide Beatrici <git@davidebeatrici.dev>2020-10-28 21:27:01 +0300
commit13cbf728775cee0b6c963d642193192dd57f24e1 (patch)
tree9411a64df0e96dcee8ec2f91629860a104a519cc /plugins
parent0968efa7b4011a099c40449f894d0886becbc334 (diff)
REFAC(plugins): Use new C++ classes in Source Engine plugin
Diffstat (limited to 'plugins')
-rw-r--r--plugins/se/CMakeLists.txt13
-rw-r--r--plugins/se/client.h34
-rw-r--r--plugins/se/common.h20
-rw-r--r--plugins/se/engine.h32
-rw-r--r--plugins/se/se.cpp86
5 files changed, 108 insertions, 77 deletions
diff --git a/plugins/se/CMakeLists.txt b/plugins/se/CMakeLists.txt
index 348abcaa7..aaf63ac7d 100644
--- a/plugins/se/CMakeLists.txt
+++ b/plugins/se/CMakeLists.txt
@@ -3,4 +3,15 @@
# that can be found in the LICENSE file at the root of the
# Mumble source tree or at <https://www.mumble.info/LICENSE>.
-add_library(se SHARED "se.cpp")
+add_library(se SHARED
+ "se.cpp"
+
+ "../Process.cpp"
+ "../ProcessWindows.cpp"
+)
+
+if(WIN32)
+ target_sources(se PRIVATE "../HostWindows.cpp")
+else()
+ target_sources(se PRIVATE "../HostLinux.cpp" "../ProcessLinux.cpp")
+endif()
diff --git a/plugins/se/client.h b/plugins/se/client.h
index 583e971f7..c470dd859 100644
--- a/plugins/se/client.h
+++ b/plugins/se/client.h
@@ -42,20 +42,20 @@ struct EntityCacheInfo {
static int32_t getDataVar(const std::string &name, procptr_t predMap) {
while (predMap) {
DataMap dataMap;
- if (!peekProc(predMap, dataMap)) {
+ if (!proc->peek(predMap, dataMap)) {
return 0;
}
// The structure is 4 bytes bigger on Linux.
const size_t realStructSize = isWin32 ? sizeof(TypeDescription) : sizeof(TypeDescription) + 4;
- const auto descs = peekProcVector< TypeDescription >(dataMap.dataDesc, dataMap.dataNumFields, realStructSize);
+ const auto descs = proc->peekVector< TypeDescription >(dataMap.dataDesc, dataMap.dataNumFields, realStructSize);
for (const auto &desc : descs) {
if (!desc.fieldName) {
continue;
}
- const auto fieldName = peekProcString(desc.fieldName);
+ const auto fieldName = proc->peekString(desc.fieldName);
if (fieldName == name) {
return desc.fieldOffset;
@@ -80,9 +80,9 @@ static int32_t getDataVarFromEntity(const std::string &name, const procptr_t ent
// Brute-force virtual function index.
for (uint8_t i = 20; i > 16; --i) {
- GetPredDescMap = getVirtualFunction(entity, i);
+ GetPredDescMap = proc->virtualFunction(entity, i);
- if (peekProc< uint8_t >(GetPredDescMap + (isWin32 ? 0 : 1)) == 0xB8) {
+ if (proc->peek< uint8_t >(GetPredDescMap + (isWin32 ? 0 : 1)) == 0xB8) {
break;
}
}
@@ -97,11 +97,11 @@ static int32_t getDataVarFromEntity(const std::string &name, const procptr_t ent
// 89 E5 mov ebp, esp
// 5D pop ebp
// C3 retn
- return getDataVar(name, peekProc< uint32_t >(GetPredDescMap + (isWin32 ? 1 : 2)));
+ return getDataVar(name, proc->peek< uint32_t >(GetPredDescMap + (isWin32 ? 1 : 2)));
}
static procptr_t getLocalPlayer(const procptr_t localClient, procptr_t clientEntityList, const procptr_t engineClient) {
- const auto GetLocalPlayer = getVirtualFunction(engineClient, 12);
+ const auto GetLocalPlayer = proc->virtualFunction(engineClient, 12);
// Windows:
// 6A FF push 0FFFFFFFFh
@@ -121,10 +121,10 @@ static procptr_t getLocalPlayer(const procptr_t localClient, procptr_t clientEnt
// C9 leave
// 83 C0 01 add eax, 1
// C3 retn
- const auto localPlayerIndexOffset = peekProc< int32_t >(GetLocalPlayer + (isWin32 ? 9 : 14));
- const auto localPlayerIndex = peekProc< uint32_t >(localClient + localPlayerIndexOffset) + 1;
+ const auto localPlayerIndexOffset = proc->peek< int32_t >(GetLocalPlayer + (isWin32 ? 9 : 14));
+ const auto localPlayerIndex = proc->peek< uint32_t >(localClient + localPlayerIndexOffset) + 1;
- auto GetClientNetworkable = getVirtualFunction(clientEntityList, 0);
+ auto GetClientNetworkable = proc->virtualFunction(clientEntityList, 0);
// Left 4 Dead:
// 8B 44 24 04 mov eax, [esp+arg_0]
@@ -143,8 +143,8 @@ static procptr_t getLocalPlayer(const procptr_t localClient, procptr_t clientEnt
// 81 6C 24 04 ?? ?? ?? ?? sub [esp+arg_0], ????????
// EB ?? jmp short GetClientNetworkable
if (!isWin32) {
- clientEntityList -= peekProc< int32_t >(GetClientNetworkable + 4);
- GetClientNetworkable = GetClientNetworkable + 10 + peekProc< int8_t >(GetClientNetworkable + 9);
+ clientEntityList -= proc->peek< int32_t >(GetClientNetworkable + 4);
+ GetClientNetworkable = GetClientNetworkable + 10 + proc->peek< int8_t >(GetClientNetworkable + 9);
// 55 push ebp
// 89 E5 mov ebp, esp
@@ -158,17 +158,17 @@ static procptr_t getLocalPlayer(const procptr_t localClient, procptr_t clientEnt
procptr_t entityCacheInfo;
if (isWin32) {
- if (peekProc< uint8_t >(GetClientNetworkable + 6) == 0xC1) {
+ if (proc->peek< uint8_t >(GetClientNetworkable + 6) == 0xC1) {
// Left 4 Dead
- entityCacheInfo = clientEntityList + peekProc< int8_t >(GetClientNetworkable + 7);
+ entityCacheInfo = clientEntityList + proc->peek< int8_t >(GetClientNetworkable + 7);
} else {
- entityCacheInfo = clientEntityList + peekProc< int8_t >(GetClientNetworkable + 9);
+ entityCacheInfo = clientEntityList + proc->peek< int8_t >(GetClientNetworkable + 9);
}
} else {
- entityCacheInfo = clientEntityList + peekProc< int32_t >(GetClientNetworkable + 13);
+ entityCacheInfo = clientEntityList + proc->peek< int32_t >(GetClientNetworkable + 13);
}
- const auto entity = peekProc< EntityCacheInfo >(entityCacheInfo + sizeof(EntityCacheInfo) * localPlayerIndex);
+ const auto entity = proc->peek< EntityCacheInfo >(entityCacheInfo + sizeof(EntityCacheInfo) * localPlayerIndex);
// We subtract 8 bytes in order to cast from IClientNetworkable to IClientEntity.
return entity.networkable ? (entity.networkable - 8) : 0;
diff --git a/plugins/se/common.h b/plugins/se/common.h
index d0e020938..0ae2e1785 100644
--- a/plugins/se/common.h
+++ b/plugins/se/common.h
@@ -18,16 +18,16 @@ static Interfaces getInterfaces(const procptr_t module) {
Interfaces interfaces;
// s_pInterfaceRegs is exported on Linux
- auto s_pInterfaceRegs = getExportedSymbol("s_pInterfaceRegs", module);
+ auto s_pInterfaceRegs = proc->exportedSymbol("s_pInterfaceRegs", module);
if (!s_pInterfaceRegs) {
- const auto CreateInterface = getExportedSymbol("CreateInterface", module);
+ const auto CreateInterface = proc->exportedSymbol("CreateInterface", module);
if (CreateInterface == 0) {
return interfaces;
}
bool jmpOnly;
- if (peekProc< uint8_t >(CreateInterface) == 0xE9) {
+ if (proc->peek< uint8_t >(CreateInterface) == 0xE9) {
// Left 4 Dead:
// E9 ?? ?? ?? ?? jmp CreateInterface_0
jmpOnly = true;
@@ -40,7 +40,7 @@ static Interfaces getInterfaces(const procptr_t module) {
jmpOnly = false;
}
- const auto jmpTarget = peekProc< int32_t >(CreateInterface + (jmpOnly ? 1 : 5));
+ const auto jmpTarget = proc->peek< int32_t >(CreateInterface + (jmpOnly ? 1 : 5));
const auto jmpInstructionEnd = CreateInterface + (jmpOnly ? 5 : 9);
const auto CreateInterfaceInternal = jmpInstructionEnd + jmpTarget;
@@ -55,21 +55,21 @@ static Interfaces getInterfaces(const procptr_t module) {
// 8B EC mov ebp, esp
// 56 push esi
// 8B 35 ?? ?? ?? ?? mov esi, s_pInterfaceRegs
- if (peekProc< uint16_t >(CreateInterfaceInternal + (jmpOnly ? 1 : 4)) != 0x358B) {
+ if (proc->peek< uint16_t >(CreateInterfaceInternal + (jmpOnly ? 1 : 4)) != 0x358B) {
return interfaces;
}
- s_pInterfaceRegs = peekProc< uint32_t >(CreateInterfaceInternal + (jmpOnly ? 3 : 6));
+ s_pInterfaceRegs = proc->peek< uint32_t >(CreateInterfaceInternal + (jmpOnly ? 3 : 6));
}
- auto iface = peekProc< InterfaceReg >(peekProcPtr(s_pInterfaceRegs));
+ auto iface = proc->peek< InterfaceReg >(proc->peekPtr(s_pInterfaceRegs));
do {
- const auto name = peekProcString(iface.name);
- const auto address = peekProc< uint32_t >(iface.createFunction + (isWin32 ? 1 : 2));
+ const auto name = proc->peekString(iface.name);
+ const auto address = proc->peek< uint32_t >(iface.createFunction + (isWin32 ? 1 : 2));
interfaces.insert(Interfaces::value_type(name, address));
- } while (iface.next && peekProc(iface.next, iface));
+ } while (iface.next && proc->peek(iface.next, iface));
return interfaces;
}
diff --git a/plugins/se/engine.h b/plugins/se/engine.h
index 77f9a90fd..2a0cf35cc 100644
--- a/plugins/se/engine.h
+++ b/plugins/se/engine.h
@@ -17,7 +17,7 @@ static procptr_t getLocalClient(const procptr_t engineClient) {
// GetLocalClient() gets the client from an array at the index passed to the function.
// There are multiple clients because of the split screen feature.
- const auto GetNetChannelInfo = getVirtualFunction(engineClient, 74);
+ const auto GetNetChannelInfo = proc->virtualFunction(engineClient, 74);
// Windows:
// E8 ?? ?? ?? ?? call GetBaseLocalClient
@@ -32,7 +32,7 @@ static procptr_t getLocalClient(const procptr_t engineClient) {
// 8B 40 ?? mov eax, [eax+?]
// C9 leave
// C3 retn
- const auto callTarget = peekProc< int32_t >(GetNetChannelInfo + (isWin32 ? 1 : 7));
+ const auto callTarget = proc->peek< int32_t >(GetNetChannelInfo + (isWin32 ? 1 : 7));
const auto callInstructionEnd = GetNetChannelInfo + (isWin32 ? 5 : 11);
const auto GetBaseLocalClient = callInstructionEnd + callTarget;
@@ -41,7 +41,8 @@ static procptr_t getLocalClient(const procptr_t engineClient) {
// 83 C0 ?? add eax, ?
// C3 retn
if (isWin32) {
- return peekProcPtr(peekProc< uint32_t >(GetBaseLocalClient + 1)) + peekProc< int8_t >(GetBaseLocalClient + 7);
+ return proc->peekPtr(proc->peek< uint32_t >(GetBaseLocalClient + 1))
+ + proc->peek< int8_t >(GetBaseLocalClient + 7);
}
// Linux:
@@ -85,11 +86,11 @@ static procptr_t getLocalClient(const procptr_t engineClient) {
//
// Its purpose seem to be to iterate over the clients array, which is done directly by GetBaseLocalClient() and
// GetLocalClient() on Windows.
- return peekProcPtr(peekProc< uint32_t >(GetBaseLocalClient + 17) + 4) + 4;
+ return proc->peekPtr(proc->peek< uint32_t >(GetBaseLocalClient + 17) + 4) + 4;
}
static int8_t getSignOnStateOffset(const procptr_t engineClient) {
- const auto IsInGame = getVirtualFunction(engineClient, 26);
+ const auto IsInGame = proc->virtualFunction(engineClient, 26);
// Windows:
// E8 ?? ?? ?? ?? call GetBaseLocalClient
@@ -107,11 +108,11 @@ static int8_t getSignOnStateOffset(const procptr_t engineClient) {
// C9 leave
// 0F 94 C0 setz al
// C3 retn
- return peekProc< int8_t >(IsInGame + (isWin32 ? 9 : 13));
+ return proc->peek< int8_t >(IsInGame + (isWin32 ? 9 : 13));
}
static int32_t getLevelNameOffset(const procptr_t engineClient) {
- const auto GetLevelNameShort = getVirtualFunction(engineClient, 53);
+ const auto GetLevelNameShort = proc->virtualFunction(engineClient, 53);
// Windows:
// ...
@@ -128,19 +129,19 @@ static int32_t getLevelNameOffset(const procptr_t engineClient) {
// 05 ?? ?? ?? ?? add eax, ?
// C3 retn
if (isWin32) {
- if (peekProc< uint8_t >(GetLevelNameShort + 37) == 0x05) {
+ if (proc->peek< uint8_t >(GetLevelNameShort + 37) == 0x05) {
// Left 4 Dead
- return peekProc< int32_t >(GetLevelNameShort + 38);
+ return proc->peek< int32_t >(GetLevelNameShort + 38);
} else {
- return peekProc< int32_t >(GetLevelNameShort + 40);
+ return proc->peek< int32_t >(GetLevelNameShort + 40);
}
}
- return peekProc< int32_t >(GetLevelNameShort + 57);
+ return proc->peek< int32_t >(GetLevelNameShort + 57);
}
static int32_t getNetInfoOffset(const procptr_t localClient, const procptr_t engineClient) {
- const auto GetNetChannelInfo = getVirtualFunction(engineClient, 74);
+ const auto GetNetChannelInfo = proc->virtualFunction(engineClient, 74);
// Windows:
// E8 ?? ?? ?? ?? call GetBaseLocalClient
@@ -155,8 +156,9 @@ static int32_t getNetInfoOffset(const procptr_t localClient, const procptr_t eng
// 8B 40 ?? mov eax, [eax+?]
// C9 leave
// C3 retn
- const auto NetChannelInfo = peekProcPtr(localClient + peekProc< int8_t >(GetNetChannelInfo + (isWin32 ? 7 : 13)));
- const auto GetAddress = getVirtualFunction(NetChannelInfo, 1);
+ const auto NetChannelInfo =
+ proc->peekPtr(localClient + proc->peek< int8_t >(GetNetChannelInfo + (isWin32 ? 7 : 13)));
+ const auto GetAddress = proc->virtualFunction(NetChannelInfo, 1);
// Windows:
// 6A 00 push 0
@@ -175,7 +177,7 @@ static int32_t getNetInfoOffset(const procptr_t localClient, const procptr_t eng
// E8 ?? ?? ?? ?? call ToString
// C9 leave
// C3 retn
- const auto netInfo = NetChannelInfo + peekProc< int32_t >(GetAddress + (isWin32 ? 4 : 18));
+ const auto netInfo = NetChannelInfo + proc->peek< int32_t >(GetAddress + (isWin32 ? 4 : 18));
return static_cast< int32_t >(netInfo - localClient);
}
diff --git a/plugins/se/se.cpp b/plugins/se/se.cpp
index b84363e3a..4560046e5 100644
--- a/plugins/se/se.cpp
+++ b/plugins/se/se.cpp
@@ -3,8 +3,20 @@
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
-#include "../mumble_plugin_main.h"
-#include "../mumble_plugin_utils.h"
+#include "mumble_plugin.h"
+#include "mumble_plugin_utils.h"
+
+#ifdef OS_LINUX
+# include "ProcessLinux.h"
+#endif
+#include "ProcessWindows.h"
+
+#include <cstring>
+#include <sstream>
+
+std::unique_ptr< Process > proc;
+
+static bool isWin32 = false;
#include "client.h"
#include "common.h"
@@ -40,7 +52,7 @@ int32_t signOnStateOffset, deadFlagOffset, rotationOffset, originPositionOffset,
static int fetch(float *avatarPos, float *avatarFront, float *avatarTop, float *cameraPos, float *cameraFront,
float *cameraTop, std::string &context, std::wstring &identity) {
- const auto signOnState = peekProc< uint32_t >(localClient + signOnStateOffset);
+ const auto signOnState = proc->peek< uint32_t >(localClient + signOnStateOffset);
// 0: SIGNONSTATE_NONE
// 1: SIGNONSTATE_CHALLENGE
@@ -54,7 +66,7 @@ static int fetch(float *avatarPos, float *avatarFront, float *avatarTop, float *
return false;
}
- const auto isPlayerDead = peekProc< bool >(localPlayer + deadFlagOffset);
+ const auto isPlayerDead = proc->peek< bool >(localPlayer + deadFlagOffset);
if (isPlayerDead) {
context.clear();
identity.clear();
@@ -67,22 +79,22 @@ static int fetch(float *avatarPos, float *avatarFront, float *avatarTop, float *
}
float rotation[3];
- if (!peekProc(localPlayer + rotationOffset, rotation, sizeof(rotation))) {
+ if (!proc->peek(localPlayer + rotationOffset, rotation, sizeof(rotation))) {
return false;
}
float originPosition[3];
- if (!peekProc(localPlayer + originPositionOffset, originPosition, sizeof(originPosition))) {
+ if (!proc->peek(localPlayer + originPositionOffset, originPosition, sizeof(originPosition))) {
return false;
}
float eyesPositionOffset[3];
- if (!peekProc(localPlayer + eyesPositionOffsetOffset, eyesPositionOffset, sizeof(eyesPositionOffset))) {
+ if (!proc->peek(localPlayer + eyesPositionOffsetOffset, eyesPositionOffset, sizeof(eyesPositionOffset))) {
return false;
}
NetInfo ni;
- if (!peekProc(localClient + netInfoOffset, ni)) {
+ if (!proc->peek(localClient + netInfoOffset, ni)) {
return false;
}
@@ -112,7 +124,7 @@ static int fetch(float *avatarPos, float *avatarFront, float *avatarTop, float *
// 40 is the size of the char array in the engine's code
char map[40];
- if (!peekProc(localClient + levelNameOffset, map, sizeof(map))) {
+ if (!proc->peek(localClient + levelNameOffset, map, sizeof(map))) {
map[0] = '\0';
}
@@ -168,18 +180,31 @@ static int fetch(float *avatarPos, float *avatarFront, float *avatarTop, float *
}
static bool tryInit(const std::multimap< std::wstring, unsigned long long int > &pids) {
+ const std::vector< std::string > names{
#ifdef OS_LINUX
- if (initialize(pids, L"hl2_linux")) {
- return true;
- }
+ "hl2_linux",
#endif
+ "left4dead2.exe", "left4dead.exe"
+ };
- if (initialize(pids, L"left4dead2.exe")) {
- return true;
- }
-
- if (initialize(pids, L"left4dead.exe")) {
- return true;
+ for (const auto &name : names) {
+ const auto id = Process::find(name, pids);
+ if (!id) {
+ continue;
+ }
+#ifdef OS_WINDOWS
+ proc.reset(new ProcessWindows(id, name));
+#else
+ isWin32 = HostLinux::isWine(id);
+ if (isWin32) {
+ proc.reset(new ProcessWindows(id, name));
+ } else {
+ proc.reset(new ProcessLinux(id, name));
+ }
+#endif
+ if (proc->isOk()) {
+ return true;
+ }
}
return false;
@@ -190,12 +215,12 @@ static int tryLock(const std::multimap< std::wstring, unsigned long long int > &
return false;
}
- const auto engine = getModuleAddr(isWin32 ? L"engine.dll" : L"engine.so");
+ const auto engine = proc->module(isWin32 ? "engine.dll" : "engine.so");
if (!engine) {
return false;
}
- const auto client = getModuleAddr(isWin32 ? L"client.dll" : L"client.so");
+ const auto client = proc->module(isWin32 ? "client.dll" : "client.so");
if (!client) {
return false;
}
@@ -217,7 +242,7 @@ static int tryLock(const std::multimap< std::wstring, unsigned long long int > &
return false;
}
- const auto signOnState = peekProc< uint32_t >(localClient + signOnStateOffset);
+ const auto signOnState = proc->peek< uint32_t >(localClient + signOnStateOffset);
if (signOnState != 6) {
return false;
}
@@ -273,17 +298,7 @@ static int tryLock(const std::multimap< std::wstring, unsigned long long int > &
return false;
}
- float avatarPos[3], avatarFront[3], avatarTop[3];
- float cameraPos[3], cameraFront[3], cameraTop[3];
- std::string context;
- std::wstring identity;
-
- if (fetch(avatarPos, avatarFront, avatarTop, cameraPos, cameraFront, cameraTop, context, identity)) {
- return true;
- } else {
- generic_unlock();
- return false;
- }
+ return true;
}
static const std::wstring longDesc() {
@@ -297,8 +312,11 @@ static int tryLock1() {
return tryLock(std::multimap< std::wstring, unsigned long long int >());
}
-static MumblePlugin sePlug = { MUMBLE_PLUGIN_MAGIC, description, shortName, NULL, NULL, tryLock1,
- generic_unlock, longDesc, fetch };
+static void nullUnlock() {
+}
+
+static MumblePlugin sePlug = { MUMBLE_PLUGIN_MAGIC, description, shortName, nullptr, nullptr, tryLock1,
+ nullUnlock, longDesc, fetch };
static MumblePlugin2 sePlug2 = { MUMBLE_PLUGIN_MAGIC_2, MUMBLE_PLUGIN_VERSION, tryLock };