mirror of
https://github.com/mumble-voip/mumble.git
synced 2025-03-14 12:43:05 +00:00

Keeping these up-to-date is just super tedious and they don't really fulfill any purpose these days.
229 lines
8.4 KiB
C++
229 lines
8.4 KiB
C++
// Copyright The Mumble Developers. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license
|
|
// that can be found in the LICENSE file at the root of the
|
|
// Mumble source tree or at <https://www.mumble.info/LICENSE>.
|
|
|
|
#define MUMBLE_ALLOW_DEPRECATED_LEGACY_PLUGIN_API
|
|
#include "mumble_legacy_plugin.h"
|
|
|
|
#include "mumble_positional_audio_main.h" // Include standard positional audio header.
|
|
#include "mumble_positional_audio_utils.h" // Include positional audio header for special functions, like "escape".
|
|
|
|
#include <cmath>
|
|
|
|
// Offset values can be obtained from:
|
|
// http://xivapp.com/api/structures?patchVersion=latest&platform=x86
|
|
// http://xivapp.com/api/structures?patchVersion=latest&platform=x64
|
|
// Y is North/South, South is increasing values
|
|
// X is East/West, West is increasing values
|
|
// Heading is in radians, 0 faces south
|
|
|
|
#ifdef FFXIV_USE_x64
|
|
// Memory offsets
|
|
const procptr_t camera_ptr = 0x1673350;
|
|
const procptr_t avatar_ptr = 0x1674950;
|
|
const procptr_t state_offset = 0x1641990;
|
|
const procptr_t map_id_offset = 0x16409E8;
|
|
// Avatar struct offsets
|
|
const procptr_t identity_offset = 48; // Name
|
|
const procptr_t avatar_pos_offset = 176; // X, Z, Y
|
|
const procptr_t avatar_azimuth_offset = 192; // Heading (-pi to pi)
|
|
// Camera struct offsets
|
|
const procptr_t camera_is_free_offset = 272; // 0: First person mode; 1: 3rd person
|
|
const procptr_t camera_pos_offset = 80; // X, Z, Y
|
|
const procptr_t camera_azimuth_offset = 304; // (-pi to pi)
|
|
const procptr_t camera_elevation_offset = 308; // (-pi to pi)
|
|
// Module names
|
|
const wchar_t *exe_name = L"ffxiv_dx11.exe";
|
|
// Plugin long description
|
|
static const std::wstring longdesc() {
|
|
return std::wstring(
|
|
L"Supports Final Fantasy XIV X64 version 2016.11.11.0000.0000 with context and identity support.");
|
|
}
|
|
// Plugin short description
|
|
static std::wstring description(L"Final Fantasy XIV X64 (2016.11.11.0000.0000)");
|
|
#else
|
|
// Memory offsets
|
|
const procptr_t camera_ptr = 0x1045C40;
|
|
const procptr_t avatar_ptr = 0x10468EC;
|
|
const procptr_t state_offset = 0x1048C60;
|
|
const procptr_t map_id_offset = 0x10210B0;
|
|
// Avatar struct offsets
|
|
const procptr_t identity_offset = 48; // Name
|
|
const procptr_t avatar_pos_offset = 160; // X, Z, Y
|
|
const procptr_t avatar_azimuth_offset = 176; // Heading (-pi to pi)
|
|
// Camera struct offsets
|
|
const procptr_t camera_is_free_offset = 256; // 0: First person mode; 1: 3rd person
|
|
const procptr_t camera_pos_offset = 64; // X, Z, Y
|
|
const procptr_t camera_azimuth_offset = 288; // (-pi to pi)
|
|
const procptr_t camera_elevation_offset = 292; // (-pi to pi)
|
|
// Module names
|
|
const wchar_t *exe_name = L"ffxiv.exe";
|
|
// Plugin long description
|
|
static const std::wstring longdesc() {
|
|
return std::wstring(L"Supports Final Fantasy XIV version 2016.11.11.0000.0000 with context and identity support.");
|
|
}
|
|
// Plugin short description
|
|
static std::wstring description(L"Final Fantasy XIV (2016.11.11.0000.0000)");
|
|
#endif
|
|
// Plugin short name
|
|
static std::wstring shortname(L"Final Fantasy XIV");
|
|
|
|
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 trylock(const std::multimap< std::wstring, unsigned long long int > &pids) {
|
|
if (!initialize(pids, exe_name)) { // Retrieve "exe_name" module's memory address
|
|
return false;
|
|
}
|
|
|
|
// Check if we can get meaningful data from it
|
|
float apos[3], afront[3], atop[3], 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 int trylock1() {
|
|
return trylock(std::multimap< std::wstring, unsigned long long int >());
|
|
}
|
|
|
|
static MumblePlugin ffxivplug = { MUMBLE_PLUGIN_MAGIC, description, shortname, nullptr, nullptr, trylock1,
|
|
generic_unlock, longdesc, fetch };
|
|
|
|
static MumblePlugin2 ffxivplug2 = { MUMBLE_PLUGIN_MAGIC_2, MUMBLE_PLUGIN_VERSION, trylock };
|
|
|
|
extern "C" MUMBLE_PLUGIN_EXPORT MumblePlugin *getMumblePlugin() {
|
|
return &ffxivplug;
|
|
}
|
|
|
|
extern "C" MUMBLE_PLUGIN_EXPORT MumblePlugin2 *getMumblePlugin2() {
|
|
return &ffxivplug2;
|
|
}
|