static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &context, std::wstring &identity) { /* clear position */ for (int i=0; i<3; i++) { avatar_pos[i]=avatar_front[i]=avatar_top[i]=camera_pos[i]=camera_front[i]=camera_top[i]=0.0; } /* are we still looking at the right object? */ uint64_t peekGUID, tempGUID; peekGUID=getInt64(p_playerBase+0x30); if (g_playerGUID != peekGUID) { /* no? Try to resynch to the new address. Happens when walking through portals quickly (aka no or short loading screen) */ tempGUID = g_playerGUID; p_playerBase=getPlayerBase(); if (tempGUID != g_playerGUID) { /* GUID of actor changed, likely a character and/or realm change */ wow.refresh(); } peekGUID=getInt64(p_playerBase+0x30); if (g_playerGUID != peekGUID) { /* no? we are still getting the expected GUID for our avatar, but we don't have it's current position */ return true; } } context.clear(); std::wstringstream identityStream; identityStream << wow.getNameAvatar(); identity = identityStream.str(); BOOL ok = true; // Wow stores as // North/South (+ North) // East/West (+ West) // Up/Down (+Up) // ... which isn't a right-hand coordinate system. float pos[3]; ok = ok && peekProc((BYTE *) p_playerBase + 0x798, pos, sizeof(float)*3); if (! ok) { if (g_playerGUID == 0xffffffffffffffff) { return false; } else if (g_playerGUID == 0) { return true; } else { /* FIXME need a better way to mark PlayerBase invalid */ g_playerGUID=0; return true; /* we got a good reference for an avatar, but no good position */ } } /* convert wow -> right hand coordinate system */ avatar_pos[0] = -pos[1]; avatar_pos[1] = pos[2]; avatar_pos[2] = pos[0]; float heading=0.0; ok = ok && peekProc((BYTE *) p_playerBase + 0x7A8, &heading, sizeof(heading)); if (! ok) return false; float pitch=0.0; ok = ok && peekProc((BYTE *) p_playerBase + 0x7AC, &pitch, sizeof(pitch)); if (! ok) return false; /* TODO use yaw (heading) and pitch angles */ /* FIXME sin/cos (heading) is right from the numbers, but (-heading) is right from the sound position */ avatar_front[0]=-sin(heading); avatar_front[1]=0.0; avatar_front[2]=cos(heading); // Dummy top vector, can't tilt your head sideways in wow. avatar_top[0]= 0.0; avatar_top[1]= 1.0; avatar_top[2]= 0.0; getCamera(camera_pos, camera_front, camera_top); if (! ok) return false; // printf("P %f %f %f -- %f %f %f \n", avatar_pos[0], avatar_pos[1], avatar_pos[2], avatar_front[0], avatar_front[1], avatar_front[2]); // is it a unit length vector? if (fabs((avatar_front[0]*avatar_front[0]+avatar_front[1]*avatar_front[1]+avatar_front[2]*avatar_front[2])-1.0)>0.5) { // printf("F %f %f %f\n", front[0], front[1], front[2]); return false; } // are we around 0/0/0 if ((fabs(avatar_pos[0])<0.1) && (fabs(avatar_pos[1])<0.1) && (fabs(avatar_pos[2])<0.1)) { // printf("P %f %f %f\n", avatar_pos[0], avatar_pos[1], avatar_pos[2]); return false; } return true; }
static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &context, std::wstring &/*identity*/) { for (int i=0;i<3;i++) avatar_pos[i]=avatar_front[i]=avatar_top[i]=0.0f; char state; bool ok; ok = peekProc((BYTE *) pModule+0x290557, state); // Magical state value if (! ok) return false; if (state != 8) { context.clear(); return true; // This results in all vectors beeing zero which tells Mumble to ignore them. } // Create containers to stuff our raw data into, so we can convert it to Mumble's coordinate system float pos_corrector[3]; float front_corrector[3]; float top_corrector[3]; // Peekproc and assign game addresses to our containers, so we can retrieve positional data ok = peekProc((BYTE *) posptr, pos_corrector) && peekProc((BYTE *) frtptr, front_corrector) && peekProc((BYTE *) topptr, top_corrector); if (! ok) return false; // Convert to left-handed coordinate system avatar_pos[0] = -pos_corrector[0]; avatar_pos[1] = pos_corrector[2]; avatar_pos[2] = pos_corrector[1]; for (int i=0;i<3;i++) avatar_pos[i] /= 64.0f; // Scale to meters avatar_front[0] = -front_corrector[1]; avatar_front[1] = front_corrector[2]; avatar_front[2] = -front_corrector[0]; avatar_top[0] = top_corrector[0]; avatar_top[1] = -top_corrector[2]; avatar_top[2] = -top_corrector[1]; correctFront(avatar_front, avatar_top); for (int i=0;i<3;i++) { camera_pos[i] = avatar_pos[i]; camera_front[i] = avatar_front[i]; camera_top[i] = avatar_top[i]; } // Read server name BYTE *cbase = peekProc<BYTE *> ((BYTE *) pModule + 0x00290550); BYTE *cptr0 = peekProc<BYTE *> ((BYTE *) cbase + 0x30); BYTE *cptr1 = peekProc<BYTE *> ((BYTE *) cptr0 + 0x73C); BYTE *cptr2 = peekProc<BYTE *> ((BYTE *) cptr1 + 0x244); wchar_t wservername[60]; ok = peekProc((BYTE *) cptr2, wservername); if (! ok) return false; wservername[sizeof(wservername)/sizeof(wservername[0]) - 1] = '\0'; std::string servername; wcsToMultibyteStdString(wservername, servername); std::ostringstream contextss; contextss << "{" << "\"servername\":\"" << servername << "\"" << "}"; context = contextss.str(); return true; }
static int trylock(const std::multimap<std::wstring, unsigned long long int> &pids) { if (!initialize(pids, L"Borderlands2.exe")) { return false; } unsigned char detected_version[32]; // Note for further versions: // The "version" string above change. However, it looks like it will always start // with "WILLOW2-". Everything after this can change between versions. // Position vectors are read as triplet (X,Y,Z). The tree triplet are in this order: // front, top, position. // When entering the game, in Sanctuary (after liftoff), with the character Zero, // the reading are the following (rounded): // front.X = 0 // front.Y = 0 // front.Z = 1 // top.X = 0 // top.Y = 1 // top.Z = 0 // pos.X = -8109 // pos.Y = 3794 // pos.Z = 2930 // The "state" ptr is just a value that reliably alternate between 0 (in main menu) // and 1 (not in main menu). There is a lot of value that keep reliably changing even // across restart, change of characters... // Note that I couldn't find an address that would do this reliably with the game "pause" // menu, only the main menu (when you initially start the game, or completely exit your // current game) // VERSION_EQ safely checks whether the content of `buf' // (a buffer in the form of a C-style array of unsigned char) // contains the byte-level content of the string literal `strlit'. // // The NUL terminator of the string literal is not considered in // this equality check. #define VERSION_EQ(buf, strlit) \ memcmp(buf, strlit, std::min(sizeof(buf), sizeof(strlit)-1)) == 0 // 1.3.1 if (peekProc(pModule + 0x1E6D048, detected_version) && VERSION_EQ(detected_version, "WILLOW2-PCSAGE-28-CL697606")) { vects_ptr = pModule + 0x1E792B0; state_ptr = pModule + 0x1E79BC8; character_name_ptr_loc = pModule + 0x1E7302C; } // 1.4.0 else if (peekProc(pModule + 0x1E8D1D8, detected_version) && VERSION_EQ(detected_version, "WILLOW2-PCSAGE-77-CL711033")) { vects_ptr = pModule + 0x1E993F0; state_ptr = pModule + 0x1E99D08; character_name_ptr_loc = pModule + 0x1E93194; } // 1.5.0 else if (peekProc(pModule + 0x01E9F338, detected_version) && VERSION_EQ(detected_version, "WILLOW2-PCLILAC-60-CL721220")) { vects_ptr = pModule + 0x1EAB650; state_ptr = pModule + 0x1EABF68; character_name_ptr_loc = pModule + 0x01EA5384; } // 1.7.0 else if (peekProc(pModule + 0x01ED53A8, detected_version) && VERSION_EQ(detected_version, "WILLOW2-PCALLIUM-55-CL770068")) { vects_ptr = pModule + 0x1EE18E0; state_ptr = pModule + 0x1EE21F8; character_name_ptr_loc = pModule + 0x01EDB5B4; } // 1.8.3 else if (peekProc(pModule + 0x1EE63C8, detected_version) && VERSION_EQ(detected_version, "WILLOW2-PCCHINA-29-CL827556")) { vects_ptr = pModule + 0x1EF2930; state_ptr = pModule + 0x1EF3248; character_name_ptr_loc = pModule + 0x01EEC5D4; } else { generic_unlock(); return false; } // Check if we can get meaningful data from it float apos[3], afront[3], atop[3]; float cpos[3], cfront[3], ctop[3]; std::wstring sidentity; std::string scontext; if (fetch(apos, afront, atop, cpos, cfront, ctop, scontext, sidentity)) { return true; } else { generic_unlock(); return false; } }
static DWORD peekProc(VOID *base) { DWORD v = 0; peekProc(base, reinterpret_cast<BYTE *>(&v), sizeof(DWORD)); return v; }
static BYTE *peekProcPtr(VOID *base) { DWORD v = peekProc(base); return reinterpret_cast<BYTE *>(v); }
static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &context, std::wstring &identity) { for (int i=0;i<3;i++) { avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; } // Boolean value to check if game addresses retrieval is successful bool ok; // Create containers to stuff our raw data into, so we can convert it to Mumble's coordinate system float avatar_pos_corrector[3], camera_pos_corrector[3], avatar_azimuth, camera_azimuth, camera_elevation; // Values for extra features char player[64]; unsigned int map_id; // State unsigned char state, camera_is_free; // Retrieve Avatar and Camera addresses #ifdef FFXIV_USE_x64 procptr_t avatar_address = peekProcPtr(pModule + avatar_ptr); procptr_t camera_address = peekProcPtr(pModule + camera_ptr); #else procptr_t avatar_address = peekProcPtr(pModule + avatar_ptr); procptr_t camera_address = peekProcPtr(pModule + camera_ptr); #endif if (!avatar_address || !camera_address) return false; // Peekproc and assign game addresses to our containers, so we can retrieve positional data ok = peekProc(pModule + state_offset, &state, 1) && // Magical state value: 0 or 255 when in main menu and 1 when in-game. peekProc(camera_address + camera_pos_offset, &camera_pos_corrector, 12) && // Camera Position values (X, Z and Y). peekProc(camera_address + camera_azimuth_offset, &camera_azimuth, 4) && // Camera azimuth float. peekProc(camera_address + camera_elevation_offset, &camera_elevation, 4) && // Camera elevation float. peekProc(camera_address + camera_is_free_offset, &camera_is_free, 1) && // Camera is in first person mode peekProc(avatar_address + avatar_pos_offset, &avatar_pos_corrector, 12) && // Avatar Position values (X, Z and Y). peekProc(avatar_address + avatar_azimuth_offset, &avatar_azimuth, 4) && // Avatar azimuth float. peekProc(pModule + map_id_offset, &map_id, 4) && // Map id. peekProc(avatar_address + identity_offset, player); // Player name. // This prevents the plugin from linking to the game in case something goes wrong during values retrieval from memory addresses. if (! ok) return false; // State if (state != 1) { // If not in-game context.clear(); // Clear context identity.clear(); // Clear identity // Set vectors values to 0. for (int i=0;i<3;i++) { avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; } return true; // This tells Mumble to ignore all vectors. } // Begin context std::ostringstream ocontext; ocontext << "{"; // Map id ocontext << "Map: " << map_id << ""; // Set map id in identity. ocontext << "}"; context = ocontext.str(); // End context // Begin identity std::wostringstream oidentity; oidentity << "{"; // Map id oidentity << "Map: " << map_id << ", "; // Set map id in identity. // Player name escape(player, sizeof(player)); if (strcmp(player, "") != 0) { oidentity << "Player: \"" << player << "\""; // Set player name in identity. } else { oidentity << "Player: null"; } oidentity << "}"; identity = oidentity.str(); // End identity /* Mumble | Game (in L hand coordinate system) X | -X Y | Y Z | Z */ avatar_pos[0] = -avatar_pos_corrector[0]; avatar_pos[1] = avatar_pos_corrector[1]; avatar_pos[2] = avatar_pos_corrector[2]; camera_pos[0] = -camera_pos_corrector[0]; camera_pos[1] = camera_pos_corrector[1]; camera_pos[2] = camera_pos_corrector[2]; avatar_front[0] = static_cast<float>(std::sin(-avatar_azimuth)); avatar_front[1] = 0.0f; avatar_front[2] = static_cast<float>(std::cos(-avatar_azimuth)); camera_front[0] = static_cast<float>(std::cos(camera_elevation) * std::sin(-camera_azimuth)); camera_front[1] = static_cast<float>(std::sin(camera_elevation)); camera_front[2] = static_cast<float>(std::cos(camera_elevation) * std::cos(-camera_azimuth)); if (camera_is_free) { camera_front[0] *= -1; camera_front[2] *= -1; } // Convert from yards (yalms) to meters for (int i=0;i<3;i++) { avatar_pos[i]*=0.9144f; camera_pos[i]*=0.9144f; } return true; }
static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &context, std::wstring &identity) { for (int i=0;i<3;i++) { avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; } // To update visit http://www.ownedcore.com/forums/world-of-warcraft/world-of-warcraft-bots-programs/wow-memory-editing // and look for a thread called "[WoW] [Version] Release Info Dump Thread". // http://www.ownedcore.com/forums/world-of-warcraft/world-of-warcraft-bots-programs/wow-memory-editing/578228-wow-7-0-3-22522-release-info-dump-thread-post3584506.html#post3584506 // Avatar pointer procptr32_t avatar_offset = peekProc<procptr32_t>(pModule + 0xDE545C); // "LocalPlayer" in the thread. if (!avatar_offset) return false; // Camera pointer procptr32_t camera_base = peekProc<procptr32_t>(pModule + 0xEB9F1C); // "CameraStruct" in the thread. if (!camera_base) return false; procptr32_t camera_offset = peekProc<procptr32_t>(camera_base + 0x3264); // "CameraOffset" in the thread. if (!camera_offset) return false; // Realm pointer procptr32_t realm_offset = peekProc<procptr32_t>(pModule + 0xF3AD7C); // Not available in the thread. if (!realm_offset) return false; // Memory addresses procptr32_t state_address = 0xE5BB19; // "GameState" in the thread. procptr32_t avatar_pos_address = 0xAF8; // "UnitOrigin" in the thread. procptr32_t camera_pos_address = 0x08; // "CameraOrigin" in the thread. procptr32_t camera_front_address = 0x14; // "CameraMatrix" in the thread. procptr32_t camera_top_address = 0x2C; // "CameraMatrix" + 0x18. procptr32_t avatar_heading_address = 0xB08; // "UnitAngle" in the thread. procptr32_t realm_address = 0x384; // Not available in the thread. procptr32_t player_address = 0xF3B088; // Not available in the thread. // Boolean value to check if game addresses retrieval is successful bool ok; // Create containers to stuff our raw data into, so we can convert it to Mumble's coordinate system float avatar_pos_corrector[3], camera_pos_corrector[3], avatar_heading, camera_front_corrector[3], camera_top_corrector[3]; // Char values for extra features char state, player[50], realm[50]; // Peekproc and assign game addresses to our containers, so we can retrieve positional data ok = peekProc(pModule + state_address, &state, 1) && // Magical state value: 1 when in-game, 0 when not. peekProc(avatar_offset + avatar_pos_address, avatar_pos_corrector, 12) && // Avatar Position values (Z, -X and Y). peekProc(camera_offset + camera_pos_address, camera_pos_corrector, 12) && // Camera Position values (Z, -X and Y). peekProc(avatar_offset + avatar_heading_address, avatar_heading) && // Avatar heading. peekProc(camera_offset + camera_front_address, camera_front_corrector, 12) && // Camera Front Vector values (Z, -X and Y). peekProc(camera_offset + camera_top_address, camera_top_corrector, 12) && // Camera Top Vector values (Z, -X and Y). peekProc(realm_offset + realm_address, realm) && // Realm name. peekProc(pModule + player_address, player); // Player nickname. // This prevents the plugin from linking to the game in case something goes wrong during values retrieval from memory addresses. if (! ok) return false; // State if (state != 1) { // If not in-game context.clear(); // Clear context identity.clear(); // Clear identity // Set vectors values to 0. for (int i=0;i<3;i++) avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; return true; // This tells Mumble to ignore all vectors. } // Begin context std::ostringstream ocontext; // Realm realm[sizeof(realm)-1] = 0; // NUL terminate queried C strings. We do this to ensure the strings from the game are NUL terminated. They should be already, but we can't take any chances. escape(realm); if (strcmp(realm, "") != 0) { // Set Realm string only if not empty ocontext << " {\"Realm\": \"" << realm << "\"}"; // Set context with Realm's name } context = ocontext.str(); // End context // Begin identity std::wostringstream oidentity; oidentity << "{"; // Player player[sizeof(player)-1] = 0; // NUL terminate queried C strings. We do this to ensure the strings from the game are NUL terminated. They should be already, but we can't take any chances. escape(player); if (strcmp(player, "") != 0) { oidentity << std::endl; oidentity << "\"Player\": \"" << player << "\""; // Set player nickname in identity. } else { oidentity << std::endl << "\"Player\": null"; } oidentity << std::endl << "}"; identity = oidentity.str(); // End identity /* Mumble | Game X | Z Y | -X Z | Y */ avatar_pos[0] = -avatar_pos_corrector[1]; avatar_pos[1] = avatar_pos_corrector[2]; avatar_pos[2] = avatar_pos_corrector[0]; camera_pos[0] = -camera_pos_corrector[1]; camera_pos[1] = camera_pos_corrector[2]; camera_pos[2] = camera_pos_corrector[0]; avatar_front[0] = -sin(avatar_heading); avatar_front[1] = 0.0f; avatar_front[2] = cos(avatar_heading); avatar_top[2] = -1; // Dummy top vector, you can't tilt your head sideways in WoW. camera_front[0] = -camera_front_corrector[1]; camera_front[1] = camera_front_corrector[2]; camera_front[2] = camera_front_corrector[0]; camera_top[0] = -camera_top_corrector[1]; camera_top[1] = camera_top_corrector[2]; camera_top[2] = camera_top_corrector[0]; return true; }
static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &, std::wstring &) { float viewHor, viewVer; char state; for (int i=0;i<3;i++) avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; bool ok; /* This plugin uses the following Variables: Address Type Description =================================== 0x01516608 float Z-Coordinate (=0 out-of-game) 0x0151660C float X-Coordinate (=0 out-of-game) 0x01516610 float Y-Coordinate (=0 out-of-game) 0x0151A114 float Horizontal view (degrees) (=0 out-of-game) 0x0151A110 float Vertical view (degrees) (=0 out-of-game) 0x0096B688 byte Magic value (0=ingame/out-of-game, 4=spectator) */ ok = peekProc((BYTE *) 0x0096B688, &state, 1); if (! ok) return false; if (state == 4) return true; // If this magic value is 4 we are spectating, so switch of PA ok = peekProc((BYTE *) 0x01516608, avatar_pos+2, 4) && //Z peekProc((BYTE *) 0x0151660C, avatar_pos, 4) && //X peekProc((BYTE *) 0x01516610, avatar_pos+1, 4) && //Y peekProc((BYTE *) 0x0151A114, &viewHor, 4) && //Hor peekProc((BYTE *) 0x0151A110, &viewVer, 4); //Ver if (! ok) return false; // Scale Coordinates /* Z-Value is increasing when heading north decreasing when heading south X-Value is increasing when heading west decreasing when heading east Y-Value is increasing when going up decreasing when going down 40 units = 1 meter (not confirmed) */ for (int i=0;i<3;i++) avatar_pos[i]/=40.0f; // Scale to meters avatar_pos[0]*=(-1.0f); // Convert right to left handed avatar_top[2] = -1; // Head movement is in front vector // Calculate view unit vector /* Vertical view 0 when centered 85 when looking down 275 when looking up Decreasing when looking up. Horizontal is 0 when facing North 90 when facing West 180 when facing South 270 when facing East Increasing when turning left. */ viewVer *= static_cast<float>(M_PI / 180.0f); viewHor *= static_cast<float>(M_PI / 180.0f); avatar_front[0] = -sin(viewHor) * cos(viewVer); avatar_front[1] = -sin(viewVer); avatar_front[2] = cos(viewHor) * cos(viewVer); return true; }
static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &context, std::wstring &identity) { for (int i=0;i<3;i++) { avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; } // Boolean value to check if game addresses retrieval is successful bool ok; // Create containers to stuff our raw data into, so we can convert it to Mumble's coordinate system float avatar_pos_corrector[3], camera_pos_corrector[3], camera_front_corrector[3], camera_top_corrector[3]; // Char values for extra features char serverid[22], host[22], map[30], playerid[22]; // State bool state; // State pointers procptr32_t state_base = peekProc<procptr32_t>(pModule + 0x5A7354); if (state_base == 0) return false; procptr32_t state_offset = peekProc<procptr32_t>(state_base + 0x5C); if (state_offset == 0) return false; // Peekproc and assign game addresses to our containers, so we can retrieve positional data ok = peekProc(state_offset + 0x8, state) && // Magical state value: 0 when not playing and 1 when in-game. peekProc(pModule + 0x512264, avatar_pos_corrector) && // Avatar position values (X, Z and Y). peekProc(pModule + 0x5943B0, camera_pos_corrector) && // Camera position values (X, Z and Y). peekProc(pModule + 0x594410, camera_front_corrector) && // Front vector values (X, Z and Y). peekProc(pModule + 0x594440, camera_top_corrector) && // Top vector values (X, Z and Y). peekProc(steamclient + 0x95E56D, serverid) && // Unique server Steam ID. peekProc(engine + 0x61F5D8, host) && // Server value: "IP:Port" (xxx.xxx.xxx.xxx:yyyyy) when in a remote server and "loopback" when on a local server. peekProc(pModule + 0x5A7A29, map) && // Map name. peekProc(engine + 0x40CF00, playerid); // Unique player Steam ID. // This prevents the plugin from linking to the game in case something goes wrong during values retrieval from memory addresses. if (! ok) return false; // State if (!state) { // If not in-game context.clear(); // Clear context identity.clear(); // Clear identity // Set vectors values to 0. for (int i=0;i<3;i++) { avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; } return true; // This tells Mumble to ignore all vectors. } // Begin context escape(serverid, sizeof(serverid)); escape(host, sizeof(host)); std::ostringstream ocontext; if (strcmp(serverid, "") != 0) { ocontext << " {\"Server ID\": \"" << serverid << "\"}"; // Set context with server ID } else { ocontext << " {\"Host\": \"" << host << "\"}"; // Set context with IP address and port } context = ocontext.str(); // End context // Begin identity std::wostringstream oidentity; oidentity << "{"; // Host if (strcmp(host, "") != 0 && strstr(host, "loopback") == NULL) { // Only include host (IP:Port) if it is not empty and does not include the string "loopback" (which means it's a local server). oidentity << std::endl << "\"Host\": \"" << host << "\","; // Set host address in identity. } else { oidentity << std::endl << "\"Host\": null,"; } // Map escape(map, sizeof(map)); if (strcmp(map, "") != 0) { oidentity << std::endl << "\"Map\": \"" << map << "\","; // Set map name in identity. } else { oidentity << std::endl << "\"Map\": null,"; } // Player ID escape(playerid, sizeof(playerid)); if (strcmp(playerid, "") != 0) { oidentity << std::endl << "\"Player ID\": \"" << playerid << "\""; // Set player ID in identity. } else { oidentity << std::endl << "\"Player ID\": null"; } oidentity << std::endl << "}"; identity = oidentity.str(); // End identity /* Mumble | Game X | X Y | Z Z | Y */ avatar_pos[0] = avatar_pos_corrector[0]; avatar_pos[1] = avatar_pos_corrector[2]; avatar_pos[2] = avatar_pos_corrector[1]; camera_pos[0] = camera_pos_corrector[0]; camera_pos[1] = camera_pos_corrector[2]; camera_pos[2] = camera_pos_corrector[1]; camera_front[0] = camera_front_corrector[0]; camera_front[1] = camera_front_corrector[2]; camera_front[2] = camera_front_corrector[1]; camera_top[0] = camera_top_corrector[0]; camera_top[1] = camera_top_corrector[2]; camera_top[2] = camera_top_corrector[1]; // Convert from inches to meters and sync avatar vectors with camera ones for (int i=0;i<3;i++) { avatar_pos[i]/=39.37f; camera_pos[i]/=39.37f; avatar_front[i] = camera_front[i]; avatar_top[i] = camera_top[i]; } return true; }
static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &, std::wstring &) { float viewHor, viewVer; char state; char specops; for (int i=0;i<3;i++) avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; bool ok; /* This plugin uses the following Variables: Address Type Description =================================== 0x00783A64 float Z-Coordinate 0x00783A68 float X-Coordinate 0x00783A6C float Y-Coordinate 0x00783A34 float Horizontal view (degrees) 0x00783A30 float Vertical view (degrees) 0x019713F0 byte SO game identifier 0x009270F0 byte Magical state value */ ok = peekProc((BYTE *) 0x019713F0, &specops, 1); // Magical state value if (! ok) return false; if (specops != 2) return false; // 2 value indicates you are playing Special Ops, 1 indicates SP, 0 indicates at three-way selection menu ok = peekProc((BYTE *) 0x009270F0, &state, 1); // Magical state value if (! ok) return false; // /* // state value is: // 0 while not in game // 4 while playing // This value is used for disabling pa for spectators // or people not on a server. // */ if (state == 0) return true; // This results in all vectors beeing zero which tells mumble to ignore them. ok = peekProc((BYTE *) 0x00783A64, avatar_pos+2, 4) && //Z peekProc((BYTE *) 0x00783A68, avatar_pos, 4) && //X peekProc((BYTE *) 0x00783A6C, avatar_pos+1, 4) && //Y peekProc((BYTE *) 0x00783A34, &viewHor, 4) && //Hor peekProc((BYTE *) 0x00783A30, &viewVer, 4); //Ver if (! ok) return false; // Scale Coordinates /* Z-Value is increasing when heading north decreasing when heading south X-Value is increasing when heading west decreasing when heading east Y-Value is increasing when going up decreasing when going down 40 units = 1 meter (not confirmed) */ for (int i=0;i<3;i++) avatar_pos[i]/=40.0f; // Scale to meters avatar_pos[0]*=(-1.0f); // Convert right to left handed avatar_top[2] = -1; // Head movement is in front vector // Calculate view unit vector /* Vertical view 0° when centered 85° when looking down 275° when looking up Decreasing when looking up. Horizontal is 0° when facing North 90° when facing West 180° when facing South 270° when facing East Increasing when turning left. */ viewVer *= static_cast<float>(M_PI / 180.0f); viewHor *= static_cast<float>(M_PI / 180.0f); avatar_front[0] = -sin(viewHor) * cos(viewVer); avatar_front[1] = -sin(viewVer); avatar_front[2] = cos(viewHor) * cos(viewVer); for (int i=0;i<3;i++) { camera_pos[i] = avatar_pos[i]; camera_front[i] = avatar_front[i]; camera_top[i] = avatar_top[i]; } return true; }
static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &context, std::wstring &identity) { for (int i=0;i<3;i++) { avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; } // Boolean value to check if game addresses retrieval is successful bool ok; // Create containers to stuff our raw data into, so we can convert it to Mumble's coordinate system float avatar_pos_corrector[3], camera_pos_corrector[3], avatar_front_corrector[3], avatar_top_corrector[3]; // Char values for extra features char serverid[22], host[22], servername[50], map[30], player[33], playerid[22]; // State unsigned char state; // Peekproc and assign game addresses to our containers, so we can retrieve positional data ok = peekProc(pModule + state_offset, &state, 1) && // Magical state value: 0 or 255 when in main menu and 1 when in-game. peekProc(pModule + avatar_pos_offset, avatar_pos_corrector, 12) && // Avatar Position values (X, Z and Y). peekProc(pModule + camera_pos_offset, camera_pos_corrector, 12) && // Camera Position values (X, Z and Y). peekProc(pModule + avatar_front_offset, avatar_front_corrector, 12) && // Front vector values (X, Z and Y). peekProc(pModule + avatar_top_offset, avatar_top_corrector, 12) && // Top vector values (Z, X and Y). peekProc(steamclient + serverid_steamclient_offset, serverid) && // Unique server Steam ID. peekProc(pModule + host_offset, host) && // Server value: "IP:Port" (xxx.xxx.xxx.xxx:yyyyy) when in a remote server, "loopback:0" when on a local server and empty when not playing. peekProc(pModule + servername_offset, servername) && // Server name. peekProc(pModule + map_offset, map) && // Map name. peekProc(server + player_server_offset, player) && // Player nickname. peekProc(engine + playerid_engine_offset, playerid); // Unique player Steam ID. // This prevents the plugin from linking to the game in case something goes wrong during values retrieval from memory addresses. if (! ok) return false; // State if (state != 1) { // If not in-game context.clear(); // Clear context identity.clear(); // Clear identity // Set vectors values to 0. for (int i=0;i<3;i++) { avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; } return true; // This tells Mumble to ignore all vectors. } // Begin context escape(serverid, sizeof(serverid)); std::ostringstream ocontext; if (strcmp(serverid, "") != 0) { ocontext << " {\"Server ID\": \"" << serverid << "\"}"; // Set context with IP address and port } context = ocontext.str(); // End context // Begin identity std::wostringstream oidentity; oidentity << "{"; // Host escape(host, sizeof(host)); if (strcmp(host, "") != 0 && strstr(host, "loopback") == NULL) { // Only include host (IP:Port) if it is not empty and does not include the string "loopback" (which means it's a local server). oidentity << std::endl << "\"Host\": \"" << host << "\","; // Set host address in identity. } else { oidentity << std::endl << "\"Host\": null,"; } // Server name escape(servername, sizeof(servername)); if (strcmp(servername, "") != 0) { oidentity << std::endl << "\"Server name\": \"" << servername << "\","; // Set server name in identity. } else { oidentity << std::endl << "\"Server name\": null,"; } // Map escape(map, sizeof(map)); if (strcmp(map, "") != 0) { oidentity << std::endl << "\"Map\": \"" << map << "\","; // Set map name in identity. } else { oidentity << std::endl << "\"Map\": null,"; } // Player nickname escape(player, sizeof(player)); if (strcmp(player, "") != 0) { oidentity << std::endl << "\"Player\": \"" << player << "\","; // Set player nickname in identity. } else { oidentity << std::endl << "\"Player\": null,"; } // Player ID escape(playerid, sizeof(playerid)); if (strcmp(playerid, "") != 0) { oidentity << std::endl << "\"Player ID\": \"" << playerid << "\""; // Set player ID in identity. } else { oidentity << std::endl << "\"Player ID\": null"; } oidentity << std::endl << "}"; identity = oidentity.str(); // End identity /* Mumble | Game X | X Y | Z Z | Y */ avatar_pos[0] = avatar_pos_corrector[0]; avatar_pos[1] = avatar_pos_corrector[2]; avatar_pos[2] = avatar_pos_corrector[1]; camera_pos[0] = camera_pos_corrector[0]; camera_pos[1] = camera_pos_corrector[2]; camera_pos[2] = camera_pos_corrector[1]; avatar_front[0] = avatar_front_corrector[0]; avatar_front[1] = avatar_front_corrector[2]; avatar_front[2] = avatar_front_corrector[1]; avatar_top[0] = avatar_top_corrector[0]; avatar_top[1] = avatar_top_corrector[2]; avatar_top[2] = avatar_top_corrector[1]; // Convert from inches to meters and sync camera vectors with avatar ones for (int i=0;i<3;i++) { avatar_pos[i]/=39.37f; camera_pos[i]/=39.37f; camera_front[i] = avatar_front[i]; camera_top[i] = avatar_top[i]; } return true; }
static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &context, std::wstring &identity) { for (int i=0;i<3;i++) { avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; } bool ok, state, spec; char host[22]; BYTE team; // Create containers to stuff our raw data into, so we can convert it to Mumble's coordinate system float avatar_pos_corrector[3], camera_pos_corrector[3], viewHor, viewVer; // Peekproc and assign game addresses to our containers, so we can retrieve positional data ok = peekProc((BYTE *) pModule + 0x0188248, &state, 1) && // Magical state value: 1 when in-game and 0 when in main menu. peekProc((BYTE *) pModule + 0x1041CAC, &spec, 1) && // Spectator state value: 1 when spectating and 0 when playing. peekProc((BYTE *) pModule + 0x0EB8950, &avatar_pos_corrector, 12) && // Avatar Position values (Z, X and Y, respectively). peekProc((BYTE *) pModule + 0x0E6093C, &camera_pos_corrector, 12) && // Camera Position values (Z, X and Y, respectively). peekProc((BYTE *) pModule + 0x1072954, &viewHor, 4) && // Changes in a range from 87.890625 (looking down) to -87.890625 (looking up). peekProc((BYTE *) pModule + 0x1072950, &viewVer, 4) && // Changes in a range from 180 to -180 when moving the view to left/right. peekProc((BYTE *) pModule + 0x0E4A638, host) && // Server value: "IP:Port" when in a remote server, "loopback" when on a local server. peekProc((BYTE *) pModule + 0x106CE6C, team); // Team value: 0 when in a FFA game (no team); 1 when in Red team; 2 when in Blue team; 3 when in Spectators. if (! ok) { return false; } if (! state) { // If not in-game context.clear(); // Clear context identity.clear(); // Clear identity return true; // This results in all vectors beeing zero which tells Mumble to ignore them. } if (state && spec) { // If in-game as spectator // Set to 0 avatar and camera values. for (int i=0;i<3;i++) { avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; } // Set team to SPEC. std::wostringstream oidentity; oidentity << "{\"team\": \"SPEC\"}"; identity = oidentity.str(); return true; // This results in all vectors beeing zero which tells Mumble to ignore them. } host[sizeof(host) - 1] = '\0'; std::string Server(host); // This string can be either "xxx.xxx.xxx.xxx:yyyyy" (or shorter), "loopback" or "" (empty) when loading. Hence 22 size for char. if (!Server.empty()) { if (Server.find("loopback") == std::string::npos) { std::ostringstream newcontext; newcontext << "{\"ipport\": \"" << Server << "\"}"; context = newcontext.str(); } std::wostringstream oidentity; if (team == 0) oidentity << "{\"team\": \"FFA\"}"; else if (team == 1) oidentity << "{\"team\": \"RED\"}"; else if (team == 2) oidentity << "{\"team\": \"BLUE\"}"; else if (team == 3) oidentity << "{\"team\": \"SPEC\"}"; identity = oidentity.str(); } /* Game | Mumble X | Y Y | Z Z | X */ avatar_pos[0] = avatar_pos_corrector[1]; avatar_pos[1] = avatar_pos_corrector[2]; avatar_pos[2] = avatar_pos_corrector[0]; camera_pos[0] = camera_pos_corrector[1]; camera_pos[1] = camera_pos_corrector[2]; camera_pos[2] = camera_pos_corrector[0]; // Scale to meters for (int i=0;i<3;i++) { avatar_pos[i]/=70.0f; camera_pos[i]/=70.0f; } viewVer *= static_cast<float>(M_PI / 180.0f); viewHor *= static_cast<float>(M_PI / 180.0f); avatar_front[0] = camera_front[0] = -sin(viewHor) * cos(viewVer); avatar_front[1] = camera_front[1] = -sin(viewVer); avatar_front[2] = camera_front[2] = cos(viewHor) * cos(viewVer); avatar_top[0] = camera_top[0] = -sin(viewHor) * cos(viewVer); avatar_top[1] = camera_top[1] = -sin(viewVer); avatar_top[2] = camera_top[2] = cos(viewHor) * cos(viewVer); return true; }
static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &, std::wstring &) { for (int i=0;i<3;i++) avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; // char state; bool ok; /* float front_corrector1; float front_corrector2; float front_corrector3; float top_corrector1; float top_corrector2; float top_corrector3; */ /* value is 0 when one is not in a game, 4 when one is ok = peekProc((BYTE *) 0x, &state, 1); // Magical state value if (! ok) return false; if (state == 0) return true; // This results in all vectors beeing zero which tells Mumble to ignore them. */ ok = peekProc(posptr, avatar_pos, 12) && peekProc(frontptr, avatar_front, 12) && peekProc(topptr, avatar_top, 12); if (avatar_pos[1] > 999000000.0) return false; /* peekProc(frontptr, &front_corrector1, 4) && peekProc(frontptr + 0xC, &front_corrector2, 4) && peekProc(frontptr + 0x18, &front_corrector3, 4) && peekProc(topptr, &top_corrector1, 4) && peekProc(topptr + 0xC, &top_corrector2, 4) && peekProc(topptr + 0x18, &top_corrector3, 4); */ if (! ok) return false; /* avatar_front[0] = front_corrector1; avatar_front[1] = front_corrector2; avatar_front[2] = front_corrector3; avatar_top[0] = top_corrector1; avatar_top[1] = top_corrector2; avatar_top[2] = top_corrector3; */ for (int i=0;i<3;i++) { camera_pos[i] = avatar_pos[i]; camera_front[i] = avatar_front[i]; camera_top[i] = avatar_top[i]; } return true; }
static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &context, std::wstring &identity) { for (int i=0;i<3;i++) { avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; } // Memory addresses char game_name[20]; procptr64_t state_address, in_game_address, avatar_pos_address, camera_pos_address, avatar_base_address, camera_front_address, camera_top_address, player_address, vehicle_address, location_address, street_address; #define VERSION_EQ(buf, strlit) \ memcmp(buf, strlit, std::min(sizeof(buf), sizeof(strlit)-1)) == 0 // Steam version if (peekProc(pModule + 0x18064D8, game_name) && VERSION_EQ(game_name, "Grand Theft Auto V")) { state_address = pModule + 0x272B9E0; in_game_address = pModule + 0x2453730; avatar_pos_address = pModule + 0x1F76F40; camera_pos_address = pModule + 0x1F73840; avatar_base_address = pModule + 0x1B8E670; camera_front_address = pModule + 0x1F76130; camera_top_address = pModule + 0x1F76120; player_address = pModule + 0x273615C; vehicle_address = pModule + 0x2329D00; location_address = pModule + 0x23296CB; street_address = pModule + 0x2326410; // Retail version } else if (peekProc(pModule + 0x17C3280, game_name) && VERSION_EQ(game_name, "Grand Theft Auto V")) { state_address = pModule + 0x2688DB0; in_game_address = pModule + 0x1B73ED4; avatar_pos_address = pModule + 0x1F01E40; camera_pos_address = pModule + 0x1C06950; avatar_base_address = pModule + 0x1B433D0; camera_front_address = pModule + 0x1C06960; camera_top_address = pModule + 0x1ED6FF0; player_address = pModule + 0x26934AC; vehicle_address = pModule + 0x228A9A0; location_address = pModule + 0x228A38B; street_address = pModule + 0x22870C0; // Unknown version } else { generic_unlock(); return false; } // Avatar pointer procptr64_t avatar_base = peekProc<procptr64_t>(avatar_base_address); if (!avatar_base) return false; // Boolean value to check if game addresses retrieval is successful bool ok; // Create containers to stuff our raw data into, so we can convert it to Mumble's coordinate system float avatar_pos_corrector[3], camera_pos_corrector[3], avatar_front_corrector[3], avatar_top_corrector[3], camera_front_corrector[3], camera_top_corrector[3]; // Char values for extra features char state, in_game, player[50], vehicle[50], location[50], street[50]; // Peekproc and assign game addresses to our containers, so we can retrieve positional data ok = peekProc(state_address, &state, 1) && // Magical state value: 0 when in single player, 2 when online and 3 when in a lobby. peekProc(in_game_address, &in_game, 1) && // 0 when loading or not in-game, 1 when in-game. peekProc(avatar_pos_address, avatar_pos_corrector, 12) && // Avatar Position values (X, Z and Y). peekProc(camera_pos_address, camera_pos_corrector, 12) && // Camera Position values (X, Z and Y). peekProc(avatar_base + 0x70, avatar_front_corrector, 12) && // Avatar Front Vector values (X, Z and Y). peekProc(avatar_base + 0x80, avatar_top_corrector, 12) && // Avatar Top Vector values (X, Z and Y). peekProc(camera_front_address, camera_front_corrector, 12) && // Camera Front Vector values (X, Z and Y). peekProc(camera_top_address, camera_top_corrector, 12) && // Camera Top Vector values (X, Z and Y). peekProc(player_address, player) && // Player nickname. peekProc(vehicle_address, vehicle) && // Vehicle name if in a vehicle, empty if not. peekProc(location_address, location) && // Location name. peekProc(street_address, street); // Street name if on a street, empty if not. // This prevents the plugin from linking to the game in case something goes wrong during values retrieval from memory addresses. if (! ok) return false; // State if (state != 2 || in_game == 0) { // If not in-game context.clear(); // Clear context identity.clear(); // Clear identity // Set vectors values to 0. for (int i=0;i<3;i++) avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; return true; // This tells Mumble to ignore all vectors. } /* // Begin context std::ostringstream ocontext; // Host escape(host); if (strcmp(host, "") != 0 && strstr(host, "127.0.0.1") == NULL) { // Set host string as empty if "127.0.0.1" is found in it. ocontext << " {\"Host\": \"" << host << "\"}"; // Set context with IP address and port } context = ocontext.str(); // End context */ // Begin identity std::wostringstream oidentity; oidentity << "{"; // Player escape(player, sizeof(player)); if (strcmp(player, "") != 0) { oidentity << std::endl; oidentity << "\"Player\": \"" << player << "\","; // Set player nickname in identity. } else { oidentity << std::endl << "\"Player\": null,"; } // Vehicle escape(vehicle, sizeof(vehicle)); if (strcmp(vehicle, "") != 0) { oidentity << std::endl; oidentity << "\"Vehicle\": \"" << vehicle << "\","; // Set vehicle name in identity. } else { oidentity << std::endl << "\"Vehicle\": null,"; } // Location escape(location, sizeof(location)); if (strcmp(location, "") != 0) { oidentity << std::endl; oidentity << "\"Location\": \"" << location << "\","; // Set location name in identity. } else { oidentity << std::endl << "\"Location\": null,"; } // Street escape(street, sizeof(street)); if (strcmp(street, "") != 0) { oidentity << std::endl; oidentity << "\"Street\": \"" << street << "\""; // Set street name in identity. } else { oidentity << std::endl << "\"Street\": null"; } oidentity << std::endl << "}"; identity = oidentity.str(); // End identity /* Mumble | Game X | X Y | Z Z | Y */ avatar_pos[0] = avatar_pos_corrector[0]; avatar_pos[1] = avatar_pos_corrector[2]; avatar_pos[2] = avatar_pos_corrector[1]; camera_pos[0] = camera_pos_corrector[0]; camera_pos[1] = camera_pos_corrector[2]; camera_pos[2] = camera_pos_corrector[1]; avatar_front[0] = avatar_front_corrector[0]; avatar_front[1] = avatar_front_corrector[2]; avatar_front[2] = avatar_front_corrector[1]; avatar_top[0] = avatar_top_corrector[0]; avatar_top[1] = avatar_top_corrector[2]; avatar_top[2] = avatar_top_corrector[1]; camera_front[0] = camera_front_corrector[0]; camera_front[1] = camera_front_corrector[2]; camera_front[2] = camera_front_corrector[1]; camera_top[0] = camera_top_corrector[0]; camera_top[1] = camera_top_corrector[2]; camera_top[2] = camera_top_corrector[1]; return true; }
static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &, std::wstring &) { float viewHor, viewVer; char state; for (int i=0;i<3;i++) avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; bool ok; /* This plugin uses the following Variables: Address Type Description =================================== 0x008DE23C float Z-Coordinate 0x008DE234 float X-Coordinate 0x008DE238 float Y-Coordinate 0x008DE244 float Horizontal view (degrees) 0x008DE240 float Vertical view (degrees) 0x0098FD2C byte Magical state value */ ok = peekProc(0x0098FD2C, &state, 1); // Magical state value if (! ok) return false; /* state value is: 0 while not in game 4 while playing 8 while spectating This value is used for disabling pa for spectators or people not on a server. */ if (state != 4) return true; // This results in all vectors beeing zero which tells mumble to ignore them. ok = peekProc(0x008DE23C, avatar_pos+2, 4) && //Z peekProc(0x008DE234, avatar_pos, 4) && //X peekProc(0x008DE238, avatar_pos+1, 4) && //Y peekProc(0x008DE244, &viewHor, 4) && //Hor peekProc(0x008DE240, &viewVer, 4); //Ver if (! ok) return false; // Scale Coordinates /* Z-Value is increasing when heading north decreasing when heading south X-Value is increasing when heading west decreasing when heading east Y-Value is increasing when going up decreasing when going down 40 units = 1 meter (not confirmed) */ for (int i=0;i<3;i++) avatar_pos[i]/=40.0f; // Scale to meters avatar_pos[0]*=(-1.0f); // Convert right to left handed avatar_top[2] = -1; // Head movement is in front vector // Calculate view unit vector /* Vertical view 0° when centered 85° when looking down 275° when looking up Decreasing when looking up. Horizontal is 0° when facing North 90° when facing West 180° when facing South 270° when facing East Increasing when turning left. */ viewVer *= static_cast<float>(M_PI / 180.0f); viewHor *= static_cast<float>(M_PI / 180.0f); avatar_front[0] = -sin(viewHor) * cos(viewVer); avatar_front[1] = -sin(viewVer); avatar_front[2] = cos(viewHor) * cos(viewVer); for (int i=0;i<3;i++) { camera_pos[i] = avatar_pos[i]; camera_front[i] = avatar_front[i]; camera_top[i] = avatar_top[i]; } return true; }
static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &context, std::wstring &) { for (int i=0;i<3;i++) avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; bool ok; byte l[2]; byte r,i; float o[3]; procptr_t hPtr; float h; /* Position as represented by /loc command lx, ly = 8 * (byte)l; ox, oy, oz = (float)o; 0 < ox < 160 x = west->east y = south->north z = altitude r = region i = instance nr nPtr = pointer to character name (unique on a server) */ ok = peekProc(0x01272D34, o, 12) && peekProc(0x01272D2C, l, 2) && peekProc(0x01272D28, &r, 1) && peekProc(0x01272D20, &i, 1) && peekProc(pModule + 0x00A138A4, &hPtr, 4); if (! ok) return false; ok = peekProc((procptr_t)(hPtr + 0x0000046F), &h, 4); if (! ok) return false; // Set identity //if(nPtr3 > 0) // identity.assign(nPtr3); // Use region as context since each region has its own coordinate system if (r == 1) context = "Eriador"; else if (r == 2) context = "Rhovannion"; else return true; // If we're in an instance, append the instance id if (i != 0) context += i; // Heading should be between 0 and 360 if (h < 0 || h > 360) return true; // Limit coordinates to byte-values, otherwise we probably have a read error if (l[0] == 255 && l[1] == 255) return true; avatar_pos[0] = (float)l[0] * 160.0f + o[0]; avatar_pos[1] = o[2]; avatar_pos[2] = (float)l[1] * 160.0f + o[1]; avatar_front[0] = sinf(h * static_cast<float>(M_PI) / 180.0f); avatar_front[1] = 0.0f; avatar_front[2] = cosf(h * static_cast<float>(M_PI) / 180.0f); avatar_top[0] = 0.0; avatar_top[1] = 1.0; avatar_top[2] = 0.0; // TODO: 3rd person camera support for (int i=0;i<3;i++) { camera_pos[i] = avatar_pos[i]; camera_front[i] = avatar_front[i]; camera_top[i] = avatar_top[i]; } return true; }
static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &context, std::wstring &identity) { for (int i=0;i<3;i++) { avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; } bool ok, state; char serverid[37], host[22], team[3]; BYTE squad, squad_leader, squad_state; // Server ID pointers procptr64_t serverid_base = peekProc<procptr64_t>(pModule + 0x02210658); if (!serverid_base) return false; procptr64_t serverid_offset_0 = peekProc<procptr64_t>(serverid_base + 0x18); if (!serverid_offset_0) return false; procptr64_t serverid_offset_1 = peekProc<procptr64_t>(serverid_offset_0 + 0x28); if (!serverid_offset_1) return false; procptr64_t serverid_offset = peekProc<procptr64_t>(serverid_offset_1 + 0x350); if (!serverid_offset) return false; // Squad pointers procptr64_t squad_base = peekProc<procptr64_t>(pModule + 0x02210718); if (!squad_base) return false; procptr64_t squad_offset_0 = peekProc<procptr64_t>(squad_base + 0xD8); if (!squad_offset_0) return false; procptr64_t squad_offset_1 = peekProc<procptr64_t>(squad_offset_0 + 0x100); if (!squad_offset_1) return false; procptr64_t squad_offset_2 = peekProc<procptr64_t>(squad_offset_1 + 0x58); if (!squad_offset_2) return false; // Peekproc and assign game addresses to our containers, so we can retrieve positional data ok = peekProc(pModule + 0x21CAFF0, state) && // Magical state value: 0 when in-game and 1 when in menu/dead. peekProc(pModule + 0x21C6D40, avatar_pos) && // Avatar Position values (X, Y and Z). peekProc(pModule + 0x21CAF80, camera_pos) && // Camera Position values (X, Y and Z). peekProc(pModule + 0x21CAF60, avatar_top) && // Avatar Top Vector values (X, Y and Z). peekProc(pModule + 0x21CAF70, avatar_front) && // Avatar Front Vector values (X, Y and Z). peekProc(serverid_offset, serverid) && // Server ID (36 characters). peekProc(pModule + 0x21B80C0, host) && // Host value: "IP:Port" when in a server, "bot" when loading and empty when it's hidden. peekProc(pModule + 0x24AFAE5, team) && // Team value: US (United States); RU (Russia); CH (China). peekProc(squad_offset_2 + 0x230, squad) && // Squad value: 0 (not in a squad); 1 (Alpha); 2 (Bravo); 3 (Charlie)... 26 (Zulu). peekProc(squad_offset_2 + 0x234, squad_leader) && // Squad leader value: 0 (False); 1 (True). peekProc(squad_offset_2 + 0x235, squad_state); // Squad state value: 0 (Public); 1 (Private). // This prevents the plugin from linking to the game in case something goes wrong during values retrieval from memory addresses. if (! ok) { return false; } if (state) { // If not in-game context.clear(); // Clear context identity.clear(); // Clear identity // Set vectors values to 0. for (int i=0;i<3;i++) { avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; } return true; // This tells Mumble to ignore all vectors. } escape(serverid, sizeof(serverid)); std::ostringstream ocontext; ocontext << " {\"Server ID\": \"" << serverid << "\"}"; // Set context with server ID context = ocontext.str(); std::wostringstream oidentity; oidentity << "{"; escape(host, sizeof(host)); // Only include host (IP:port) if it is not empty and does not include the string "bot" (which means it's a local server). if (strcmp(host, "") != 0 && strstr(host, "bot") == NULL) { oidentity << std::endl << "\"Host\": \"" << host << "\","; } std::string Team(team); if (!Team.empty()) { oidentity << std::endl; if (Team == "US") oidentity << "\"Team\": \"United States\","; // If team value is US, set "United States" as team in identity. else if (Team == "CH") oidentity << "\"Team\": \"China\","; // If team value is CH, set "China" as team in identity. else if (Team == "RU") oidentity << "\"Team\": \"Russia\","; // If team value is RU, set "Russia" as team in identity. } // If squad value is in a value between 1 and 26, set squad name in identity using NATO Phonetic alphabet. if (squad > 0 && squad < 27) { if (squad == 1) oidentity << std::endl << "\"Squad\": \"Alpha\","; else if (squad == 2) oidentity << std::endl << "\"Squad\": \"Bravo\","; else if (squad == 3) oidentity << std::endl << "\"Squad\": \"Charlie\","; else if (squad == 4) oidentity << std::endl << "\"Squad\": \"Delta\","; else if (squad == 5) oidentity << std::endl << "\"Squad\": \"Echo\","; else if (squad == 6) oidentity << std::endl << "\"Squad\": \"Foxtrot\","; else if (squad == 7) oidentity << std::endl << "\"Squad\": \"Golf\","; else if (squad == 8) oidentity << std::endl << "\"Squad\": \"Hotel\","; else if (squad == 9) oidentity << std::endl << "\"Squad\": \"India\","; else if (squad == 10) oidentity << std::endl << "\"Squad\": \"Juliet\","; else if (squad == 11) oidentity << std::endl << "\"Squad\": \"Kilo\","; else if (squad == 12) oidentity << std::endl << "\"Squad\": \"Lima\","; else if (squad == 13) oidentity << std::endl << "\"Squad\": \"Mike\","; else if (squad == 14) oidentity << std::endl << "\"Squad\": \"November\","; else if (squad == 15) oidentity << std::endl << "\"Squad\": \"Oscar\","; else if (squad == 16) oidentity << std::endl << "\"Squad\": \"Papa\","; else if (squad == 17) oidentity << std::endl << "\"Squad\": \"Quebec\","; else if (squad == 18) oidentity << std::endl << "\"Squad\": \"Romeo\","; else if (squad == 19) oidentity << std::endl << "\"Squad\": \"Sierra\","; else if (squad == 20) oidentity << std::endl << "\"Squad\": \"Tango\","; else if (squad == 21) oidentity << std::endl << "\"Squad\": \"Uniform\","; else if (squad == 22) oidentity << std::endl << "\"Squad\": \"Victor\","; else if (squad == 23) oidentity << std::endl << "\"Squad\": \"Whiskey\","; else if (squad == 24) oidentity << std::endl << "\"Squad\": \"X-ray\","; else if (squad == 25) oidentity << std::endl << "\"Squad\": \"Yankee\","; else if (squad == 26) oidentity << std::endl << "\"Squad\": \"Zulu\","; // Squad leader if (squad_leader == 1) oidentity << std::endl << "\"Squad leader\": true,"; // If squad leader value is true, set squad leader state to "True" in identity. else oidentity << std::endl << "\"Squad leader\": false,"; // If squad leader value is false, set squad leader state to "False" in identity. // Squad state if (squad_state == 1) oidentity << std::endl << "\"Squad state\": \"Private\""; // If squad state value is true, set squad state to "Private" in identity. else oidentity << std::endl << "\"Squad state\": \"Public\""; // If squad state value is false, set squad state to "Public" in identity. // When not in a squad } else { oidentity << std::endl << "\"Squad\": null,"; // If squad value isn't between 1 and 26, set squad to "null" in identity. oidentity << std::endl << "\"Squad leader\": null,"; // If not in a squad, set squad leader state to "null" in identity. oidentity << std::endl << "\"Squad state\": null"; // If not in a squad, set squad state to "null" in identity. } oidentity << std::endl << "}"; identity = oidentity.str(); // Flip the front vector for (int i=0;i<3;i++) { avatar_front[i] = -avatar_front[i]; } // Convert from right to left handed avatar_pos[0] = -avatar_pos[0]; camera_pos[0] = -camera_pos[0]; avatar_front[0] = -avatar_front[0]; avatar_top[0] = -avatar_top[0]; // Sync camera front and top vectors with avatar ones for (int i=0;i<3;i++) { camera_front[i] = avatar_front[i]; camera_top[i] = avatar_top[i]; } return true; }
static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top, std::string &context, std::wstring &) { static bool loggedin = false; static BYTE *contextptr; bool ok; // Zeroing the floats for (int i=0;i<3;i++) avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f; // When you log in the context pointer needs to be set. char login; ok = peekProc(loginaddress, &login, sizeof(login)); if (! ok) return false; if (login == 0) { loggedin = false; } else if (!loggedin) { BYTE *ptr1 = peekProc<BYTE *>(contextptraddress); BYTE *ptr2 = peekProc<BYTE *>(ptr1 + 0x28c); BYTE *ptr3 = peekProc<BYTE *>(ptr2 + 0x210); if (ptr3 != 0) loggedin = true; //pointer set contextptr = ptr3 + 0x2c; } // Magic State value char state; ok = peekProc(stateaddress, &state, sizeof(state)); if (! ok) return false; // State is 0 when you are in the main menu and 1 when your are not. if (state == 0) return true; // This results in all vectors beeing zero which tells Mumble to ignore them. float pos_corrector[3]; float front_corrector[3]; float top_corrector[3]; ok = peekProc(posptr, &pos_corrector, 12) && peekProc(frontptr, &front_corrector, 12) && peekProc(topptr, &top_corrector, 12); if (! ok) return false; // coordinate systems: // "ENU" "Mumble" "In game" // East x+ [0] z+ [2] // North z+ [2] x+ [0] // Up y+ [1] y+ [1] avatar_pos[0] = pos_corrector[2]; avatar_pos[1] = pos_corrector[1]; avatar_pos[2] = pos_corrector[0]; for (int i=0;i<3;i++) avatar_pos[i]/=100.0f; // Unreal Unit is set to centimeters avatar_front[0] = front_corrector[2]; avatar_front[1] = front_corrector[1]; avatar_front[2] = front_corrector[0]; avatar_top[0] = top_corrector[2]; avatar_top[1] = top_corrector[1]; avatar_top[2] = top_corrector[0]; for (int i=0;i<3;i++) { camera_pos[i] = avatar_pos[i]; camera_front[i] = avatar_front[i]; camera_top[i] = avatar_top[i]; } if (loggedin) { char ccontext[64]; ok = peekProc(contextptr, &ccontext, sizeof(ccontext)); if (! ok) return false; std::string new_context; new_context.assign(ccontext, sizeof(ccontext)); if (new_context.find("bderlandspc") != std::string::npos) new_context.erase(0, new_context.find("bderlandspc")); if (new_context.find(":7777") != std::string::npos) new_context.erase(new_context.find(":7777") + 5); context = new_context; } return ok; }