Commit ec6f8a29 authored by insert's avatar insert

Pushing source to GitHub.

parent be48d242
node_modules/
build/
\ No newline at end of file
{
"files.associations": {
"array": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"initializer_list": "cpp",
"list": "cpp",
"vector": "cpp",
"xhash": "cpp",
"xstring": "cpp",
"xutility": "cpp"
}
}
\ No newline at end of file
# gw2mumblelink
Guild Wars 2 Mumble Link
# Guild Wars 2 Mumble Link
Retrieve data from the GW2 client through the data exposed for Mumble.
[![NPM](https://nodei.co/npm/gw2mumblelink.png)](https://nodei.co/npm/gw2mumblelink/)
[![npm](https://img.shields.io/npm/dt/gw2mumblelink.svg)](https://www.npmjs.com/package/gw2mumblelink)
## Quick Start
Below is a short snippet, I recommend looking through the examples folder to find what you're looking for.
```javascript
const MumbleLink = require('gw2mumblelink');
let mumbleLink = new MumbleLink();
if (!mumbleLink.init()) return console.error("Failed to initialise!");
mumbleLink.getName(); // Should be Guild Wars 2
let identity = mumbleLink.getIdentity();
console.log(identity.name); // Your character's name =)
```
## To-Do
- Create documentation for module
- Finish support for [ML struct](https://wiki.guildwars2.com/wiki/API:MumbleLink#MumbleLink_structure), this includes: f* vars, the context, desc and other variables.
\ No newline at end of file
# Automatically generated file. Edits will be lost.
# Based on: autogypi.json
{
"includes": [
"node_modules\\nbind\\src\\nbind-common.gypi"
]
}
# Automatically generated file. Edits will be lost.
# Based on: autogypi.json
{
"include_dirs": [
"node_modules\\nan"
],
"includes": [
"node_modules\\nbind\\src\\nbind.gypi"
]
}
{
"dependencies": [
"nbind"
],
"includes": []
}
{
"targets": [
{
"includes": [
"auto.gypi"
],
"sources": [
"src\\MumbleLink.cpp"
]
}
],
"includes": [
"auto-top.gypi"
]
}
const MumbleLink = require('../');
const mumbleLink = new MumbleLink();
if (!mumbleLink.init()) {
console.log('Could not create shared memory location!');
process.exit(1);
}
let identity = mumbleLink.getIdentity();
console.log(`Hi, ${identity.name}!
I see you are a ${MumbleLink.RaceEnum.getKey(identity.race)} ${MumbleLink.ProfessionEnum.getKey(identity.profession)}.
You are on map ${identity.map_id}, world ${identity.world_id}.
You ${identity.commander ? 'do' : 'do not'} currently have a commander tag.
Your fov is ${identity.fov} and your ui is ${MumbleLink.UISizeEnum.getKey(identity.uisz)}.`);
\ No newline at end of file
{
"folders": [
{
"path": "."
}
],
"settings": {
"files.associations": {
"array": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"initializer_list": "cpp",
"list": "cpp",
"vector": "cpp",
"xhash": "cpp",
"xstring": "cpp",
"xutility": "cpp"
}
}
}
\ No newline at end of file
const TextDecoder = require('text-encoding').TextDecoder;
const nbind = require('nbind');
const textDecoder = new TextDecoder("utf-8");
const lib = nbind.init(__dirname).lib;
Object.prototype.getKey = function(value) {
let object = this;
return Object.keys(object).find(key => object[key] === value);
};
const collectWChar = (mL, attribute) => {
let arr = new Uint8Array(256);
mL['get' + attribute](arr);
return textDecoder.decode(arr);
};
/**
* @typedef {Object} identity
* @property {string} name Character Name
* @property {int} profession Character's Profession
* @property {int} race Character's Race
* @property {int} map_id ID of the character's current map (See API:2/maps)
* @property {int} world_id ID of the character's current world (See API:2/worlds)
* @property {int} team_color_id ID of the character's team color (See API:2/colors)
* @property {boolean} commander Whether the character has a commander tag
* @property {int} fov Vertical Field of View
* @property {int} uisz User's current UI scaling
*/
/**
* Mumble Link Class
* @class
*/
class MumbleLink {
constructor() {
this.mL = new lib.MumbleLink();
}
/**
* Initiates the Mumble Link.
* @returns {boolean} Whether it has worked or not.
*/
init() {
return this.mL.init();
}
/**
* Get the current link name.
* @returns {string} Should be 'Guild Wars 2'.
*/
getName() {
return collectWChar(this.mL, "Name");
}
/**
* Get the character's identity.
* @returns {Identity} Identity object
*/
getIdentity() {
let data = collectWChar(this.mL, "Identity");
/**
* Remove all whitespaces because JSON.parse dosen't like them.
*/
let end = 0;
for (let i=data.length-1;i>0;i--) {
if (data[i].charCodeAt() != 0) {
end = i+1;
break;
}
}
return JSON.parse(data.substring(0, end));
}
}
module.exports = MumbleLink;
module.exports.ProfessionEnum = {
GUARDIAN: 1,
WARRIOR: 2,
ENGINEER: 3,
RANGER: 4,
THEIF: 5,
ELEMENTALIST: 6,
MESMER: 7,
NECROMANCER: 8,
REVENANT: 9
};
module.exports.RaceEnum = {
ASURA: 0,
CHARR: 1,
HUMAN: 2,
NORN: 3,
SYLVARI: 4
};
module.exports.UISizeEnum = {
SMALL: 0,
NORMAL: 1,
LARGE: 2,
LARGER: 3
};
\ No newline at end of file
This diff is collapsed.
{
"name": "gw2mumblelink",
"version": "1.0.0",
"description": "Guild Wars 2 Mumble Link integration for Node.js",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"autogypi": "autogypi",
"node-gyp": "node-gyp",
"emcc-path": "emcc-path",
"copyasm": "copyasm",
"ndts": "ndts",
"install": "autogypi && node-gyp configure build",
"rebuild": "node-gyp configure build"
},
"author": "insertish <[email protected]>",
"license": "ISC",
"dependencies": {
"autogypi": "^0.2.2",
"nbind": "^0.3.15",
"node-gyp": "^3.6.2",
"text-encoding": "^0.6.4"
},
"homepage": "https://github.com/mcrocks999/gw2mumblelink"
}
#include <stdio.h>
#include <iostream>
#include <locale>
#include <stdint.h>
// weird stuff happens with nbind, include line below to prevent redefinitions
#define _WINSOCKAPI_
#include <Windows.h>
#include "nbind/api.h"
class MumbleLink {
private:
struct LinkedMem {
UINT32 uiVersion;
DWORD uiTick;
float fAvatarPosition[3];
float fAvatarFront[3];
float fAvatarTop[3];
wchar_t name[256];
float fCameraPosition[3];
float fCameraFront[3];
float fCameraTop[3];
wchar_t identity[256];
UINT32 context_len;
unsigned char context[256];
wchar_t description[2048];
};
LinkedMem *lm = NULL;
inline void pushDataToBuffer(nbind::Buffer dest, wchar_t* src) {
size_t length = dest.length();
unsigned char *data = dest.data();
if (!data || !length) return;
for (size_t pos = 0; pos < length; ++pos) {
data[pos] = src[pos];
}
dest.commit();
}
public:
inline bool init() {
HANDLE mapObj = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(LinkedMem), L"MumbleLink");
if (mapObj == NULL) return false;
lm = (LinkedMem*)MapViewOfFile(mapObj, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(LinkedMem));
if (lm == NULL) {
CloseHandle(mapObj);
mapObj = NULL;
return false;
}
return true; // We are now ready to recieve information.
};
inline void getName(nbind::Buffer buf) {
pushDataToBuffer(buf, lm->name);
};
inline void getIdentity(nbind::Buffer buf) {
pushDataToBuffer(buf, lm->identity);
};
};
#include "nbind/nbind.h"
NBIND_CLASS(MumbleLink) {
construct<>();
method(init);
method(getName);
method(getIdentity);
};
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment