/
MumbleLink.cs
108 lines (94 loc) · 3.7 KB
/
MumbleLink.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
using System;
using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
namespace Gw2Mem
{
class MumbleLink
{
private const string NAME = "MumbleLink";
private const float METER_TO_INCH = 39.3701f;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct LinkedMem
{
public UInt32 uiVersion;
public UInt32 uiTick;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public float[] fAvatarPosition;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public float[] fAvatarFront;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public float[] fAvatarTop;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public float[] fCameraPosition;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public float[] fCameraFront;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public float[] fCameraTop;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string identity;
public UInt32 context_len;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] context;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2048)]
public string description;
};
public struct Coordinate
{
public float x, y, z;
public int world_id;
public int map_id;
}
private readonly int MEM_SIZE;
private byte[] buffer;
private GCHandle bufferHandle;
private MemoryMappedFile mmf;
private MemoryMappedViewStream stream;
public MumbleLink()
{
MEM_SIZE = Marshal.SizeOf(typeof(LinkedMem));
mmf = MemoryMappedFile.CreateOrOpen(NAME, MEM_SIZE);
stream = mmf.CreateViewStream(0, MEM_SIZE);
buffer = new byte[MEM_SIZE];
bufferHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
}
public LinkedMem Read()
{
stream.Position = 0;
stream.Read(buffer, 0, MEM_SIZE);
return (LinkedMem)Marshal.PtrToStructure(bufferHandle.AddrOfPinnedObject(), typeof(LinkedMem));
}
public Coordinate GetCoordinates()
{
LinkedMem l = Read();
/*
* Note that the mumble coordinates differ from the actual in-game coordinates.
* They are in the format x,z,y and z has been negated so that underwater is negative
* rather than positive.
*
* Coordinates are based on a central point (0,0), which may be the center of the zone,
* where traveling west is negative, east is positive, north is positive and south is negative.
*
*/
Coordinate coord = new Coordinate();
coord.x = l.fAvatarPosition[0] * METER_TO_INCH; //west to east
coord.y = l.fAvatarPosition[2] * METER_TO_INCH; //north to south
coord.z = -l.fAvatarPosition[1] * METER_TO_INCH; //altitude
coord.world_id = BitConverter.ToInt32(l.context, 36);
coord.map_id = BitConverter.ToInt32(l.context, 28);
return coord;
}
//public void Dispose()
//{
// if (stream != null)
// stream.Dispose();
// if (bufferHandle != null)
// bufferHandle.Free();
// if (mmf != null)
// {
// mmf.Dispose();
// }
//}
}
}