GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/mumblemanager.cpp Lines: 0 108 0.0 %
Date: 2017-11-29 Branches: 0 44 0.0 %

Line Branch Exec Source
1
/*
2
 *  Code taken from: http://mumble.sourceforge.net/Link
3
 *
4
 *  All code listed below is in the public domain and can be used, shared or
5
 *  modified freely
6
 *
7
 *  Copyright (C) 2011-2017  The ManaPlus Developers
8
 */
9
10
#ifdef USE_MUMBLE
11
12
#include "mumblemanager.h"
13
14
#include "configuration.h"
15
#include "logger.h"
16
17
#include "utils/mathutils.h"
18
19
#ifdef __OpenBSD__
20
#include <sys/param.h>
21
#endif  // __OpenBSD__
22
#include <wchar.h>
23
#include <cctype>
24
25
#include <fcntl.h>
26
#include <unistd.h>
27
#include <sys/types.h>
28
29
PRAGMA48(GCC diagnostic push)
30
PRAGMA48(GCC diagnostic ignored "-Wshadow")
31
#include <SDL_syswm.h>
32
PRAGMA48(GCC diagnostic pop)
33
34
#ifndef WIN32
35
#include <sys/mman.h>
36
#endif  // WIN32
37
38
#include "debug.h"
39
40
#ifdef USE_MUMBLE
41
MumbleManager *mumbleManager = nullptr;
42
#endif  // USE_MUMBLE
43
44
MumbleManager::MumbleManager() :
45
    mLinkedMem(nullptr),
46
    mLinkedMemCache()
47
{
48
    mMapBase[0] = mMapBase[1] = mMapBase[2] = 0.;
49
    init();
50
}
51
52
MumbleManager::~MumbleManager()
53
{
54
    if (mLinkedMem)
55
    {
56
#ifdef WIN32
57
        UnmapViewOfFile(mLinkedMem);
58
#elif defined BSD4_4
59
#else  // WIN32
60
61
        munmap(mLinkedMem, sizeof(LinkedMem));
62
#endif  // WIN32
63
64
        mLinkedMem = nullptr;
65
    }
66
}
67
68
uint16_t MumbleManager::getMapId(std::string mapName)
69
{
70
    uint16_t res = 0;
71
    if (mapName.size() != 5 || mapName[3] != '-')
72
    {
73
        res = getCrc16(mapName);
74
    }
75
    else
76
    {
77
        mapName = mapName.substr(0, 3) + mapName[4];
78
        res = CAST_U16(atoi(mapName.c_str()));
79
    }
80
    return res;
81
}
82
83
void MumbleManager::setMapBase(uint16_t mapid)
84
{
85
    mMapBase[0] = 10000.0F * (mapid & 0x1F);
86
    mapid >>= 5;
87
    mMapBase[1] = 1000.0F * (mapid & 0x3F);
88
    mapid >>= 6;
89
    mMapBase[2] = 10000.0F * (mapid & 0x1F);
90
}
91
92
void MumbleManager::init()
93
{
94
#if defined BSD4_4
95
    return;
96
#endif  // defined BSD4_4
97
98
    if (mLinkedMem || !config.getBoolValue("enableMumble"))
99
        return;
100
101
    logger->log1("MumbleManager::init");
102
#ifdef WIN32
103
    HANDLE hMapObject = OpenFileMappingW(FILE_MAP_ALL_ACCESS,
104
                                         FALSE, L"MumbleLink");
105
    if (!hMapObject)
106
    {
107
        logger->log1("MumbleManager::init can't open MumbleLink");
108
        return;
109
    }
110
111
    mLinkedMem = reinterpret_cast<LinkedMem *>(MapViewOfFile(hMapObject,
112
        FILE_MAP_ALL_ACCESS, 0, 0, sizeof(LinkedMem)));
113
114
    if (!mLinkedMem)
115
    {
116
        CloseHandle(hMapObject);
117
        hMapObject = nullptr;
118
        logger->log1("MumbleManager::init can't map MumbleLink");
119
        return;
120
    }
121
#elif defined BSD4_4
122
#else  // WIN32
123
124
    char memName[256];
125
    snprintf(memName, sizeof(memName), "/MumbleLink.%u", getuid());
126
127
    const int shmfd = shm_open(memName, O_RDWR, S_IRUSR | S_IWUSR);
128
129
    if (shmfd < 0)
130
    {
131
        logger->log1("MumbleManager::init can't"
132
            " open shared memory MumbleLink");
133
        return;
134
    }
135
136
    mLinkedMem = static_cast<LinkedMem *>(mmap(nullptr,
137
        sizeof(LinkedMem), PROT_READ | PROT_WRITE,
138
        MAP_SHARED, shmfd, 0));
139
140
    if (mLinkedMem == reinterpret_cast<void *>(-1))
141
    {
142
        mLinkedMem = nullptr;
143
        logger->log1("MumbleManager::init can't map MumbleLink");
144
        return;
145
    }
146
147
#endif  // WIN32
148
149
    wcsncpy(mLinkedMemCache.name, L"ManaPlus", 256);
150
    wcsncpy(mLinkedMemCache.description, L"ManaPlus Plugin", 2048);
151
    mLinkedMemCache.uiVersion = 2;
152
153
    // Left handed coordinate system.
154
    // X positive towards "left".
155
    // Y positive towards "up".
156
    // Z positive towards "into screen".
157
    //
158
    // 1 unit = 1 meter
159
160
    // Unit vector pointing out of the avatars eyes
161
    // (here Front looks into scene).
162
    /* no way to look "up", 2d */
163
    mLinkedMemCache.fAvatarFront[1] = 0.0F;
164
165
    // Unit vector pointing out of the top of the avatars head
166
    // (here Top looks straight up).
167
    /* no way to change this in tmw */
168
    mLinkedMemCache.fAvatarTop[0] = 0.0F;
169
    mLinkedMemCache.fAvatarTop[1] = 1.0F;
170
    mLinkedMemCache.fAvatarTop[2] = 0.0F;
171
172
    mLinkedMemCache.fCameraFront[0] = 0.0F;
173
    mLinkedMemCache.fCameraFront[1] = 0.0F;
174
    mLinkedMemCache.fCameraFront[2] = 1.0F;
175
176
    mLinkedMemCache.fCameraTop[0] = 0.0F;
177
    mLinkedMemCache.fCameraTop[1] = 1.0F;
178
    mLinkedMemCache.fCameraTop[2] = 0.0F;
179
180
    mLinkedMemCache.uiTick++;
181
}
182
183
void MumbleManager::setPlayer(const std::string &userName)
184
{
185
    if (!mLinkedMem)
186
        return;
187
188
    // Identifier which uniquely identifies a certain player in a context
189
    // (e.g. the ingame Name).
190
    mbstowcs(mLinkedMemCache.identity, userName.c_str(), 256);
191
    mLinkedMemCache.uiTick ++;
192
PRAGMA8(GCC diagnostic push)
193
PRAGMA8(GCC diagnostic ignored "-Wclass-memaccess")
194
    memcpy(mLinkedMem, &mLinkedMemCache, sizeof(mLinkedMemCache));
195
PRAGMA8(GCC diagnostic pop)
196
}
197
198
void MumbleManager::setAction(const int action)
199
{
200
    if (!mLinkedMem)
201
        return;
202
203
    switch (action)
204
    {
205
        case 0: /* STAND */
206
        case 1: /* WALK */
207
        case 2: /* ATTACK */
208
        case 5: /* HURT */
209
            mLinkedMemCache.fAvatarPosition[1] = 1.5F;
210
            break;
211
        case 3: /* SIT */
212
            mLinkedMemCache.fAvatarPosition[1] = 1.0F;
213
            break;
214
        case 4: /* DEAD */
215
        default:
216
            mLinkedMemCache.fAvatarPosition[1] = 0.0F;
217
            break;
218
    }
219
    mLinkedMemCache.fAvatarPosition[1] += mMapBase[1];
220
    mLinkedMemCache.fCameraPosition[1] = mLinkedMemCache.fAvatarPosition[1];
221
222
    mLinkedMemCache.uiTick++;
223
PRAGMA8(GCC diagnostic push)
224
PRAGMA8(GCC diagnostic ignored "-Wclass-memaccess")
225
    memcpy(mLinkedMem, &mLinkedMemCache, sizeof(mLinkedMemCache));
226
PRAGMA8(GCC diagnostic pop)
227
}
228
229
void MumbleManager::setPos(const int tileX, const int tileY,
230
                           const int direction)
231
{
232
    if (!mLinkedMem)
233
        return;
234
235
    // Position of the avatar (here standing slightly off the origin)
236
    // lm->fAvatarPosition
237
238
    /* tmw coordinates work exactly the other way round */
239
    mLinkedMemCache.fAvatarPosition[0] = static_cast<float>(tileX)
240
        + mMapBase[0];
241
    mLinkedMemCache.fAvatarPosition[2] = static_cast<float>(tileY)
242
        + mMapBase[2];
243
244
    // Same as avatar but for the camera.
245
    // lm->fCameraPosition, fCameraFront, fCameraTop
246
247
    // Same as avatar but for the camera.
248
    mLinkedMemCache.fCameraPosition[0] = mLinkedMemCache.fAvatarPosition[0];
249
    mLinkedMemCache.fCameraPosition[2] = mLinkedMemCache.fAvatarPosition[2];
250
251
    // Unit vector pointing out of the avatars eyes
252
    // (here Front looks into scene).
253
    switch (direction)
254
    {
255
        case 4: /* UP */
256
            mLinkedMemCache.fAvatarFront[0] = 0.0F;
257
            mLinkedMemCache.fAvatarFront[2] = 1.0F;
258
            break;
259
        case 1: /* DOWN */
260
            mLinkedMemCache.fAvatarFront[0] = 0.0F;
261
            mLinkedMemCache.fAvatarFront[2] = -1.0F;
262
            break;
263
        case 2: /* LEFT */
264
            mLinkedMemCache.fAvatarFront[0] = 1.0F;
265
            mLinkedMemCache.fAvatarFront[2] = 0.0F;
266
            break;
267
        case 8: /* RIGHT */
268
            mLinkedMemCache.fAvatarFront[0] = -1.0F;
269
            mLinkedMemCache.fAvatarFront[2] = 0.0F;
270
            break;
271
        default:
272
            break;
273
    }
274
275
    mLinkedMemCache.uiTick ++;
276
PRAGMA8(GCC diagnostic push)
277
PRAGMA8(GCC diagnostic ignored "-Wclass-memaccess")
278
    memcpy(mLinkedMem, &mLinkedMemCache, sizeof(mLinkedMemCache));
279
PRAGMA8(GCC diagnostic pop)
280
}
281
282
void MumbleManager::setMap(const std::string &mapName)
283
{
284
    if (!mLinkedMem)
285
        return;
286
287
    // Context should be equal for players which should be able to hear each
288
    // other positional and differ for those who shouldn't
289
    // (e.g. it could contain the server+port and team)
290
291
    setMapBase(getMapId(mapName));
292
    setAction(0); /* update y coordinate */
293
}
294
295
void MumbleManager::setServer(const std::string &serverName)
296
{
297
    if (!mLinkedMem)
298
        return;
299
300
    unsigned size = CAST_U32(serverName.size());
301
    if (size > sizeof(mLinkedMemCache.context) - 1)
302
        size = sizeof(mLinkedMemCache.context) - 1;
303
304
    memset(mLinkedMemCache.context, 0, sizeof(mLinkedMemCache.context));
305
PRAGMA8(GCC diagnostic push)
306
PRAGMA8(GCC diagnostic ignored "-Wclass-memaccess")
307
    memcpy(mLinkedMemCache.context, serverName.c_str(), size);
308
PRAGMA8(GCC diagnostic pop)
309
    mLinkedMemCache.context[size] = '\0';
310
    mLinkedMemCache.context_len = size;
311
    mLinkedMemCache.uiTick ++;
312
PRAGMA8(GCC diagnostic push)
313
PRAGMA8(GCC diagnostic ignored "-Wclass-memaccess")
314
    memcpy(mLinkedMem, &mLinkedMemCache, sizeof(mLinkedMemCache));
315
PRAGMA8(GCC diagnostic pop)
316
}
317
318
#endif  // USE_MUMBLE