~ubuntu-branches/ubuntu/raring/mumble/raring

« back to all changes in this revision

Viewing changes to plugins/etqw/etqw.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Thorvald Natvig
  • Date: 2010-01-09 19:28:50 UTC
  • mfrom: (9.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100109192850-zs4g5vwrrpd71kob
Tags: 1.2.1-2
Fix upgrade failure when upgrading mumble-server directly from 1.1.x
to 1.2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2009-2010, Snares <snares@users.sourceforge.net>
 
2
   Copyright (C) 2009-2010, Stefan Hacker <dD0t@users.sourceforge.net>
 
3
   Copyright (C) 2005-2010, Thorvald Natvig <thorvald@natvig.com>
 
4
 
 
5
   All rights reserved.
 
6
 
 
7
   Redistribution and use in source and binary forms, with or without
 
8
   modification, are permitted provided that the following conditions
 
9
   are met:
 
10
 
 
11
   - Redistributions of source code must retain the above copyright notice,
 
12
     this list of conditions and the following disclaimer.
 
13
   - Redistributions in binary form must reproduce the above copyright notice,
 
14
     this list of conditions and the following disclaimer in the documentation
 
15
     and/or other materials provided with the distribution.
 
16
   - Neither the name of the Mumble Developers nor the names of its
 
17
     contributors may be used to endorse or promote products derived from this
 
18
     software without specific prior written permission.
 
19
 
 
20
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
21
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
22
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
23
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
 
24
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
25
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
26
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
27
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 
28
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 
29
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
30
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
31
*/
 
32
 
 
33
#define _USE_MATH_DEFINES
 
34
 
 
35
#include <stdio.h>
 
36
#include <stdlib.h>
 
37
#include <windows.h>
 
38
#include <tlhelp32.h>
 
39
#include <math.h>
 
40
#include <string>
 
41
#include <sstream>
 
42
 
 
43
#include "../mumble_plugin.h"
 
44
 
 
45
HANDLE h = NULL;
 
46
 
 
47
using namespace std;
 
48
 
 
49
BYTE *pos1ptr;
 
50
BYTE *pos2ptr;
 
51
BYTE *pos3ptr;
 
52
BYTE *rot1ptr;
 
53
BYTE *rot2ptr;
 
54
 
 
55
static DWORD getProcess(const wchar_t *exename) {
 
56
        PROCESSENTRY32 pe;
 
57
        DWORD pid = 0;
 
58
 
 
59
        pe.dwSize = sizeof(pe);
 
60
        HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 
61
        if (hSnap != INVALID_HANDLE_VALUE) {
 
62
                BOOL ok = Process32First(hSnap, &pe);
 
63
 
 
64
                while (ok) {
 
65
                        if (wcscmp(pe.szExeFile, exename)==0) {
 
66
                                pid = pe.th32ProcessID;
 
67
                                break;
 
68
                        }
 
69
                        ok = Process32Next(hSnap, &pe);
 
70
                }
 
71
                CloseHandle(hSnap);
 
72
        }
 
73
        return pid;
 
74
}
 
75
 
 
76
static BYTE *getModuleAddr(DWORD pid, const wchar_t *modname) {
 
77
        MODULEENTRY32 me;
 
78
        BYTE *addr = NULL;
 
79
        me.dwSize = sizeof(me);
 
80
        HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
 
81
        if (hSnap != INVALID_HANDLE_VALUE) {
 
82
                BOOL ok = Module32First(hSnap, &me);
 
83
 
 
84
                while (ok) {
 
85
                        if (wcscmp(me.szModule, modname)==0) {
 
86
                                addr = me.modBaseAddr;
 
87
                                break;
 
88
                        }
 
89
                        ok = Module32Next(hSnap, &me);
 
90
                }
 
91
                CloseHandle(hSnap);
 
92
        }
 
93
        return addr;
 
94
}
 
95
 
 
96
 
 
97
static bool peekProc(VOID *base, VOID *dest, SIZE_T len) {
 
98
        SIZE_T r;
 
99
        BOOL ok=ReadProcessMemory(h, base, dest, len, &r);
 
100
        return (ok && (r == len));
 
101
}
 
102
 
 
103
static DWORD peekProc(VOID *base) {
 
104
        DWORD v = 0;
 
105
        peekProc(base, reinterpret_cast<BYTE *>(&v), sizeof(DWORD));
 
106
        return v;
 
107
}
 
108
 
 
109
static BYTE *peekProcPtr(VOID *base) {
 
110
        DWORD v = peekProc(base);
 
111
        return reinterpret_cast<BYTE *>(v);
 
112
}
 
113
 
 
114
static void about(HWND h) {
 
115
        ::MessageBox(h, L"Reads audio position information from Enemy Territory: Quake Wars (v1.50). IP:Port context support.", L"Mumble ETQW plugin", MB_OK);
 
116
}
 
117
 
 
118
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) {
 
119
        char menustate;
 
120
        char ccontext[128];
 
121
 
 
122
        float viewHor, viewVer;
 
123
        for (int i=0;i<3;i++)
 
124
                avatar_pos[i]=avatar_front[i]=avatar_top[i]=0.0f;
 
125
 
 
126
        bool ok;
 
127
 
 
128
        /*
 
129
                This plugin uses the following Variables:
 
130
 
 
131
                        Address                 Type    Description
 
132
                        ===================================
 
133
                        0x013F79CC              float   Y-Coordinate
 
134
                        0x013E8CF4              float   X-Coordinate
 
135
                        0x013E8CF8              float   Z-Coordinate
 
136
                        0x013F9E20              float   Horizontal view
 
137
                        0x013F9E1C              float   Vertical view
 
138
                        0x013E8D18              byte    Magic value (32 ingame / 0 spectating)
 
139
        */
 
140
        ok = peekProc((BYTE *) 0x00801BA4, &menustate, 1);
 
141
        if (! ok)
 
142
                return false;
 
143
        if (menustate == 0)
 
144
                return true;
 
145
 
 
146
        ok = peekProc(pos1ptr, avatar_pos+1, 4) &&      //Y
 
147
             peekProc(pos2ptr, avatar_pos, 4) &&        //X
 
148
             peekProc(pos3ptr, avatar_pos+2, 4) && //Z
 
149
             peekProc(rot1ptr, &viewHor, 4) && //Hor
 
150
             peekProc(rot2ptr, &viewVer, 4) && //Ver
 
151
             peekProc((BYTE *) 0x0122E0B8, ccontext, 128);
 
152
 
 
153
        if (! ok)
 
154
                return false;
 
155
 
 
156
        avatar_top[2] = -1; // Head movement is in front vector
 
157
 
 
158
        ccontext[127] = 0;
 
159
        context = std::string(ccontext);
 
160
 
 
161
        if (context.find(':')==string::npos)
 
162
                context.append(":27733");
 
163
 
 
164
        /*
 
165
           Z-Value is increasing when heading north
 
166
                                  decreasing when heading south
 
167
           X-Value is increasing when heading east
 
168
                                  decreasing when heading west
 
169
           Y-Value is increasing when going up
 
170
                                  decreasing when going down
 
171
           1 unit = 1 meter (not confirmed)
 
172
        */
 
173
 
 
174
        // Calculate view unit vector
 
175
        /*
 
176
           Vertical view 0 when centered
 
177
                                   ~+271 when looking up
 
178
                                   ~+88 when looking down
 
179
           Increasing when looking down.
 
180
 
 
181
           Horizontal is +90 when facing north
 
182
                                           0 when facing east
 
183
                                        +270 when facing south
 
184
                                        +180 when facing west
 
185
           Increasing when turning left.
 
186
        */
 
187
        viewVer *= static_cast<float>(M_PI / 180.0f);
 
188
        viewHor *= static_cast<float>(M_PI / 180.0f);
 
189
 
 
190
        avatar_front[0] = -sin(viewHor) * cos(viewVer);
 
191
        avatar_front[1] = -sin(viewVer);
 
192
        avatar_front[2] = cos(viewHor) * cos(viewVer);
 
193
 
 
194
        for (int i=0;i<3;i++) {
 
195
                camera_pos[i] = avatar_pos[i];
 
196
                camera_front[i] = avatar_front[i];
 
197
                camera_top[i] = avatar_top[i];
 
198
        }
 
199
 
 
200
        return ok;
 
201
}
 
202
 
 
203
static int trylock() {
 
204
        h = NULL;
 
205
        pos1ptr = pos2ptr = pos3ptr = rot1ptr = rot2ptr = NULL;
 
206
 
 
207
        DWORD pid=getProcess(L"etqw.exe");
 
208
        if (!pid)
 
209
                return false;
 
210
        BYTE *mod=getModuleAddr(pid, L"gamex86.dll");
 
211
        if (!mod)
 
212
                return false;
 
213
 
 
214
        pos1ptr = mod + 0x74EABC;
 
215
        pos2ptr = mod + 0x74EAB4;
 
216
        pos3ptr = mod + 0x74EAB8;
 
217
        rot1ptr = mod + 0x75D2B4;
 
218
        rot2ptr = mod + 0x75D30C;
 
219
 
 
220
        h=OpenProcess(PROCESS_VM_READ, false, pid);
 
221
        if (!h)
 
222
                return false;
 
223
 
 
224
        float apos[3], afront[3], atop[3], cpos[3], cfront[3], ctop[3];
 
225
        std::string context;
 
226
        std::wstring identity;
 
227
 
 
228
        if (fetch(apos, afront, atop, cpos, cfront, ctop, context, identity))
 
229
                return true;
 
230
 
 
231
        CloseHandle(h);
 
232
        h = NULL;
 
233
        return false;
 
234
}
 
235
 
 
236
static void unlock() {
 
237
        if (h) {
 
238
                CloseHandle(h);
 
239
                h = NULL;
 
240
        }
 
241
}
 
242
 
 
243
static const std::wstring longdesc() {
 
244
        return std::wstring(L"Supports Enemy Territory: Quake Wars v1.50. No identity support yet.");
 
245
}
 
246
 
 
247
static std::wstring description(L"Enemy Territory: Quake Wars v1.50");
 
248
static std::wstring shortname(L"Enemy Territory: Quake Wars");
 
249
 
 
250
static MumblePlugin etqwplug = {
 
251
        MUMBLE_PLUGIN_MAGIC,
 
252
        description,
 
253
        shortname,
 
254
        about,
 
255
        NULL,
 
256
        trylock,
 
257
        unlock,
 
258
        longdesc,
 
259
        fetch
 
260
};
 
261
 
 
262
extern "C" __declspec(dllexport) MumblePlugin *getMumblePlugin() {
 
263
        return &etqwplug;
 
264
}