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