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 /*
7 	This plugin scans the following address locations:
8 
9 		Address         Type      Description
10 		===================================
11 		0x013E8CF4      float     X-Coordinate
12 		0x013E8CF8      float     Y-Coordinate
13 		0x013E8CFC      float     Z-Coordinate
14 		// The XYZ coordinates repeat at 0x013F79C8, 0x013F79CC, 0x013F79D0
15 		// and seem to always hold the same values. It is not the camera vs
16 		// character, as with third person they still hold the same values.
17 		0x013F9E20      float     Horizontal view in degree
18 		0x013F9E1C      float     Vertical view in degree
19 		0x013E8DFC      byte      Team; 0: not in-game (in menu etc), 1: allies, 2: axis, 3: spectator
20 		0x009FFD30      char[40]  last connected to host IP
21 		0x010B4908      char[32]  map shortname only
22 
23 		As reference, as help for future manual mem scanning:
24 		0x010B48C8      char[32]  map fullpath (relative to gamedir)
25 		0x03A54C9C      char[16]  last download host IP (wwwdownload)
26 		There seem to be a ton of memory addresses valid for the team value.
27 
28 		For position coordinates:
29 		X-Value is increasing when heading east
30 		           decreasing when heading west
31 		Y-Value is increasing when heading north
32 		           decreasing when heading south
33 		Z-Value is increasing when going up
34 		           decreasing when going down
35 		1 unit = 1 meter (not confirmed)
36 
37 		For the view angle values:
38 		Vertical view 0 when centered
39 		            -90 when looking up
40 		            +90 when looking down
41 		Increasing when looking down.
42 
43 		Horizontal is 90 when facing north
44 		               0 when facing east
45 		             -90 when facing south
46 		          +/-180 when facing west
47 		Increasing when turning left.
48 */
49 
50 #include "../mumble_plugin_win32.h"
51 
fetch(float * avatar_pos,float * avatar_front,float * avatar_top,float * camera_pos,float * camera_front,float * camera_top,std::string & context,std::wstring &)52 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 &) {
53 	float viewHor, viewVer;
54 	char team;
55 
56 	for (int i=0;i<3;i++)
57 		avatar_pos[i] = avatar_front[i] = avatar_top[i] = camera_pos[i] = camera_front[i] = camera_top[i] = 0.0f;
58 
59 	bool ok;
60 	ok = peekProc(0x013E8DFC, &team, 1);
61 	if (!ok)
62 		return false;
63 
64 	// We dont use pos-audio in menus
65 	if (team == 0 || team == 3)
66 		return true;
67 
68 	ok = peekProc(0x013E8CF4, avatar_pos, 12) &&   // X, Y, Z
69 	     peekProc(0x013F9E20, &viewHor, 4) &&      // Hor-Angle
70 	     peekProc(0x013F9E1C, &viewVer, 4);        // Ver-Angle
71 
72 	if (!ok)
73 		return false;
74 
75 	avatar_top[2] = -1; // Head movement is in front vector
76 
77 	// Calculate view unit vector
78 	viewVer *= static_cast<float>(M_PI / 180.0f);
79 	viewHor *= static_cast<float>(M_PI / 180.0f);
80 
81 	avatar_front[0] = cos(viewVer) * cos(viewHor);
82 	avatar_front[1] = -sin(viewVer);
83 	avatar_front[2] = cos(viewVer) * sin(viewHor);
84 
85 	for (int i=0;i<3;i++) {
86 		camera_pos[i] = avatar_pos[i];
87 		camera_front[i] = avatar_front[i];
88 		camera_top[i] = avatar_top[i];
89 	}
90 
91 	// Context - concatenated server-ip, mapname and team value
92 	char hostip[32];
93 	char mapname[40];
94 	ok = peekProc(0x009FFD30, hostip, sizeof(hostip)) &&
95 	     peekProc(0x010B4908, mapname, sizeof(hostip));
96 	hostip[sizeof(hostip)-1] = '\0';
97 	mapname[sizeof(mapname)-1] = '\0';
98 	// Context in JSON format, {} with fields ipport (server hostname), map, and team (: int)
99 	context = "{\"ipport\":\"" + std::string(hostip) + "\",\"map\":\"" + mapname + "\",\"team\":" + (char)(team + 0x30) + "}";
100 
101 	return true;
102 }
103 
trylock(const std::multimap<std::wstring,unsigned long long int> & pids)104 static int trylock(const std::multimap<std::wstring, unsigned long long int> &pids) {
105 	if (! initialize(pids, L"ET.exe"))
106 		return false;
107 
108 	float apos[3], afront[3], atop[3], cpos[3], cfront[3], ctop[3];
109 	std::string context;
110 	std::wstring identity;
111 
112 	if (fetch(apos, afront, atop, cpos, cfront, ctop, context, identity)) {
113 		return true;
114 	} else {
115 		generic_unlock();
116 		return false;
117 	}
118 }
119 
longdesc()120 static const std::wstring longdesc() {
121 	return std::wstring(L"Supports Wolfenstien: Enemy Territory v2.60b. No context or identity support yet.");
122 }
123 
124 static std::wstring description(L"Wolfenstein: Enemy Territory v2.60b");
125 static std::wstring shortname(L"Wolfenstein: Enemy Territory");
126 
trylock1()127 static int trylock1() {
128 	return trylock(std::multimap<std::wstring, unsigned long long int>());
129 }
130 
131 static MumblePlugin wolfetplug = {
132 	MUMBLE_PLUGIN_MAGIC,
133 	description,
134 	shortname,
135 	NULL,
136 	NULL,
137 	trylock1,
138 	generic_unlock,
139 	longdesc,
140 	fetch
141 };
142 
143 static MumblePlugin2 wolfetplug2 = {
144 	MUMBLE_PLUGIN_MAGIC_2,
145 	MUMBLE_PLUGIN_VERSION,
146 	trylock
147 };
148 
getMumblePlugin()149 extern "C" MUMBLE_PLUGIN_EXPORT MumblePlugin *getMumblePlugin() {
150 	return &wolfetplug;
151 }
152 
getMumblePlugin2()153 extern "C" MUMBLE_PLUGIN_EXPORT MumblePlugin2 *getMumblePlugin2() {
154 	return &wolfetplug2;
155 }
156