File: Game.cpp

package info (click to toggle)
mumble 1.5.735-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 90,036 kB
  • sloc: cpp: 556,923; ansic: 81,662; python: 3,606; sh: 659; makefile: 506; asm: 371; cs: 306; sql: 228; javascript: 143; perl: 80; xml: 13
file content (86 lines) | stat: -rw-r--r-- 3,029 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Copyright 2021-2023 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>.

#include "Game.h"

#include <sstream>

Game::Game(const procid_t id, const std::string &name) : m_proc(id, name) {
}

bool Game::setupPointers(const Module &module) {
	// 48 8B 0D ?? ?? ?? ??    mov    rcx, cs:off_????????
	const std::vector< uint8_t > playerMgrPattern = { 0x48, 0x8B, 0x0D, '?', '?',  '?',  '?',  0x8A, 0xD3, 0x48, 0x8B,
													  0x01, 0xFF, 0x50, '?', 0x4C, 0x8B, 0x07, 0x48, 0x8B, 0xCF };

	m_playerMgr = m_proc.findPattern(playerMgrPattern, module);
	if (!m_playerMgr) {
		return false;
	}

	// 48 8B 05 ?? ?? ?? ??    mov    rax, cs:qword_????????
	const std::vector< uint8_t > cameraMgrPattern = { 0x48, 0x8B, 0x05, '?', '?', '?', '?', 0x4A, 0x8B, 0x1C, 0xF0 };
	m_cameraMgr                                   = m_proc.findPattern(cameraMgrPattern, module);
	if (!m_cameraMgr) {
		return false;
	}

	m_playerMgr = m_proc.peekPtr(m_proc.peekRIP(m_playerMgr + 3));
	m_cameraMgr = m_proc.peekRIP(m_cameraMgr + 3);

	return true;
}

Mumble_PositionalDataErrorCode Game::init() {
	if (!m_proc.isOk()) {
		return MUMBLE_PDEC_ERROR_TEMP;
	}

	const Modules &modules = m_proc.modules();
	const auto iter        = modules.find("GTA5.exe");
	if (iter == modules.cend()) {
		return MUMBLE_PDEC_ERROR_TEMP;
	}

	if (!setupPointers(iter->second)) {
		// TODO: Return MUMBLE_PDEC_ERROR_PERM.
		// The game process is spawned by its launcher, but it takes at least a few seconds to unpack.
		// We have to figure out a way to detect that state.
		return MUMBLE_PDEC_ERROR_TEMP;
	}

	if (!m_playerMgr || !m_cameraMgr) {
		return MUMBLE_PDEC_ERROR_TEMP;
	}

	return MUMBLE_PDEC_OK;
}

CPlayerAngles Game::playerAngles() const {
	const auto gameCameraAngles    = m_proc.peek< CGameCameraAngles >(m_cameraMgr);
	const auto cameraManagerAngles = m_proc.peek< CCameraManagerAngles >(gameCameraAngles.cameraManagerAngles);
	const auto cameraAngles        = m_proc.peek< CCameraAngles >(cameraManagerAngles.cameraAngles);

	return m_proc.peek< CPlayerAngles >(cameraAngles.playerAngles);
}

const std::string &Game::identity(const CNetGamePlayer &player, const CPlayerInfo &info, const CPed &entity) {
	std::ostringstream stream;

	stream << "ID: " << std::to_string(player.id) << '\n';
	stream << "Name: " << info.netData.name << '\n';
	stream << "Health: " << entity.health << '\n';
	stream << "Max health: " << entity.maxHealth << '\n';
	stream << "Armor: " << entity.armor << '\n';
	stream << "Wanted level: " << info.wantedLevel << '\n';
	stream << "State: "
		   << std::to_string(static_cast< std::underlying_type_t< decltype(info.gameState) > >(info.gameState)) << '\n';
	stream << "Peer ID: " << std::to_string(info.netData.peerID) << '\n';
	stream << "Host token: " << std::to_string(info.netData.hostToken);

	m_identity = stream.str();

	return m_identity;
}