1 // Copyright 2005-2019 The Mumble Developers. All rights reserved.
2 // Use of this source code is governed by a BSD-style license
3 // that can be found in the LICENSE file at the root of the
4 // Mumble source tree or at <https://www.mumble.info/LICENSE>.
5 
6 /* Copyright (C) 2011, Mike <mike@flomp.net>
7    Copyright (C) 2005-2012, Thorvald Natvig <thorvald@natvig.com>
8 
9    All rights reserved.
10 
11    Redistribution and use in source and binary forms, with or without
12    modification, are permitted provided that the following conditions
13    are met:
14 
15    - Redistributions of source code must retain the above copyright notice,
16      this list of conditions and the following disclaimer.
17    - Redistributions in binary form must reproduce the above copyright notice,
18      this list of conditions and the following disclaimer in the documentation
19      and/or other materials provided with the distribution.
20    - Neither the name of the Mumble Developers nor the names of its
21      contributors may be used to endorse or promote products derived from this
22      software without specific prior written permission.
23 
24    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
28    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36 
37 #include "../mumble_plugin_win32.h"
38 
39 static unsigned int playerid;
40 static procptr_t base_address;
41 static procptr_t cvecptr;
42 static procptr_t displayptr;
43 
setuppointers()44 static int setuppointers() {
45 	procptr_t playerptr, charptr;
46 
47 	// Player stuff
48 	if (!peekProc(base_address + 0xF1CC68, playerid))
49 		return false;
50 
51 	if (!peekProc(base_address + 0x11A7008 + (playerid * 4), &playerptr, 4) || !playerptr)
52 		return false;
53 
54 	if (!peekProc(playerptr + 0x58C, &charptr, 4) || !charptr)
55 		return false;
56 
57 	if (!peekProc(charptr + 0x20, &cvecptr, 4) || !cvecptr)
58 		return false;
59 
60 	return true;
61 }
62 
fetch(float * avatar_pos,float * avatar_front,float * avatar_top,float * camera_pos,float * camera_front,float * camera_top,std::string &,std::wstring &)63 static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front, float *camera_top,
64                  std::string &, std::wstring &) {
65 	unsigned int playerid_check;
66 	if (!peekProc(base_address + 0xF1CC68, playerid_check))
67 		return false;
68 	if (playerid_check != playerid) {
69 		if (!setuppointers())
70 			return false;
71 	}
72 
73 	for (int i=0;i<3;i++)
74 		avatar_pos[i]=avatar_front[i]=avatar_top[i]=0.0f;
75 
76 	bool ok;
77 
78 	float pos_corrector[3];
79 	float front_corrector[3];
80 	float top_corrector[3];
81 
82 	float campos_corrector[3];
83 	float camfront_corrector[3];
84 	float camtop_corrector[3];
85 
86 	// Peekproc and assign game addresses to our containers, so we can retrieve positional data
87 	ok = peekProc(cvecptr + 0x30, &pos_corrector, 12) &&
88 	     peekProc(cvecptr + 0x20, &top_corrector, 12) &&
89 	     peekProc(cvecptr + 0x10, &front_corrector, 12) &&
90 	     peekProc(displayptr + 0x30, &campos_corrector, 12) &&
91 	     peekProc(displayptr + 0x10, &camtop_corrector, 12) &&
92 	     peekProc(displayptr + 0x20, &camfront_corrector, 12);
93 
94 	if (!ok)
95 		return false;
96 
97 	// Convert to left-handed coordinate system
98 	avatar_pos[0] = pos_corrector[0];
99 	avatar_pos[1] = pos_corrector[2];
100 	avatar_pos[2] = pos_corrector[1];
101 
102 	avatar_front[0] = front_corrector[0];
103 	avatar_front[1] = front_corrector[2];
104 	avatar_front[2] = front_corrector[1];
105 
106 	avatar_top[0] = top_corrector[0];
107 	avatar_top[1] = top_corrector[2];
108 	avatar_top[2] = top_corrector[1];
109 
110 	camera_pos[0] = campos_corrector[0];
111 	camera_pos[1] = campos_corrector[2];
112 	camera_pos[2] = campos_corrector[1];
113 
114 	camera_front[0] = -camfront_corrector[0];
115 	camera_front[1] = -camfront_corrector[2];
116 	camera_front[2] = -camfront_corrector[1];
117 
118 	camera_top[0] = camtop_corrector[0];
119 	camera_top[1] = camtop_corrector[2];
120 	camera_top[2] = camtop_corrector[1];
121 
122 	return true;
123 }
124 
trylock(const std::multimap<std::wstring,unsigned long long int> & pids)125 static int trylock(const std::multimap<std::wstring, unsigned long long int> &pids) {
126 	if (!initialize(pids, L"GTAIV.exe"))
127 		return false;
128 
129 	// Check if we can get meaningful data from it
130 	float apos[3], afront[3], atop[3];
131 	float cpos[3], cfront[3], ctop[3];
132 	std::wstring sidentity;
133 	std::string scontext;
134 	procptr_t viewportptr;
135 
136 	base_address = pModule - 0x400000;
137 
138 	if (!peekProc(base_address + 0x10F47F0, &viewportptr, 4) || !viewportptr)
139 		return false;
140 
141 	displayptr = viewportptr + 0x50;
142 
143 	if (setuppointers() && fetch(apos, afront, atop, cpos, cfront, ctop, scontext, sidentity)) {
144 		return true;
145 	} else {
146 		generic_unlock();
147 		return false;
148 	}
149 }
150 
longdesc()151 static const std::wstring longdesc() {
152 	return std::wstring(L"Supports Grand Theft Auto IV (v1.0.7.0). No identity support.");
153 }
154 
155 static std::wstring description(L"Grand Theft Auto IV v1.0.7.0");
156 static std::wstring shortname(L"GTA IV");
157 
trylock1()158 static int trylock1() {
159 	return trylock(std::multimap<std::wstring, unsigned long long int>());
160 }
161 
162 static MumblePlugin gtaivplug = {
163 	MUMBLE_PLUGIN_MAGIC,
164 	description,
165 	shortname,
166 	NULL,
167 	NULL,
168 	trylock1,
169 	generic_unlock,
170 	longdesc,
171 	fetch
172 };
173 
174 static MumblePlugin2 gtaivplug2 = {
175 	MUMBLE_PLUGIN_MAGIC_2,
176 	MUMBLE_PLUGIN_VERSION,
177 	trylock
178 };
179 
getMumblePlugin()180 extern "C" MUMBLE_PLUGIN_EXPORT MumblePlugin *getMumblePlugin() {
181 	return &gtaivplug;
182 }
183 
getMumblePlugin2()184 extern "C" MUMBLE_PLUGIN_EXPORT MumblePlugin2 *getMumblePlugin2() {
185 	return &gtaivplug2;
186 }
187