access mmap with tagname in wine from linux

Questions about Wine on Linux
Locked
redartist
Newbie
Newbie
Posts: 4
Joined: Thu May 06, 2021 5:59 am

access mmap with tagname in wine from linux

Post by redartist »

So, i am trying to create an cross platform overlay for Guild wars 2 game. The game exposes some live data like character position/name/race etc.. via a mumble link api as shown in https://wiki.guildwars2.com/wiki/API:MumbleLink .

The game uses mmap on windows with a tagname "MumbleLink". I would like to access that mumble link from linux so that i can use it for my overlay. and as far as i can find, tagname does not exist in linux mmap.

I am kinda desperate as i have been stuck on this issue since 2 days, and could not find any way. Any help is appreciated :)
redartist
Newbie
Newbie
Posts: 4
Joined: Thu May 06, 2021 5:59 am

Re: access mmap with tagname in wine from linux

Post by redartist »

just posting more info in case someone needs it.

this is a working example implementation of the mumble api client in python. really short and clear. https://wiki.guildwars2.com/wiki/API:Mu ... n_(Python)
another working example that i was successfully able to use on windows in cpp. https://pastebin.com/nCjkNckX . if i compile it and try to run on wine, i get a lot of missing dll errors like uacrt.dll or user32.dll etc..

if i could have gotten the windows version working in wine, i could just expose a socket or something, and make the linux overlay connect to it and read stuff. clunkier than directly accessing via mmap though :(
redartist
Newbie
Newbie
Posts: 4
Joined: Thu May 06, 2021 5:59 am

Re: access mmap with tagname in wine from linux

Post by redartist »

progress made. after some guidance in winehq irc and other old forum posts about ipc between linux/wine processes, i started experimenting.

by compiling the https://pastebin.com/nCjkNckX on windows in x86 release mode, i was able to run the generated exe and game in the same wine prefix with the same wine runner and successfully use the shared memory MumbleLink. wine/linux ipc with shared memory seems to be really really complicated, and from old forum threads it was recommended to use sockets instead.

So, for now, i plan to just use the previous code and extend it to write MumbleLink into a socket, and as both local sockets have literally GB/s range of speed, i think it is more than enough to be used by the linux native overlay. in the next comment, I will post the full code of that pastebin link both for the purposes of archiving for future visitors and for anyone who would like to point out any improvements like using a winelib (idk what winelib actually is properly) :)
redartist
Newbie
Newbie
Posts: 4
Joined: Thu May 06, 2021 5:59 am

Re: access mmap with tagname in wine from linux

Post by redartist »

Code: Select all

// mmgw.h : Include file for standard system include files,
// or project specific include files.

#pragma once

#include <iostream>

struct LinkedMem {
    uint32_t uiVersion;
    uint32_t 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_t context_len; // Despite the actual context containing more data, this value is always 48. See "context" section below.
    unsigned char context[256];
    wchar_t description[2048];
};

struct MumbleContext {
    unsigned char serverAddress[28]; // contains sockaddr_in or sockaddr_in6
    uint32_t mapId;
    uint32_t mapType;
    uint32_t shardId;
    uint32_t instance;
    uint32_t buildId;
    // Additional data beyond the 48 bytes Mumble uses for identification
    uint32_t uiState; // Bitmask: Bit 1 = IsMapOpen, Bit 2 = IsCompassTopRight, Bit 3 = DoesCompassHaveRotationEnabled, Bit 4 = Game has focus, Bit 5 = Is in Competitive game mode, Bit 6 = Textbox has focus, Bit 7 = Is in Combat
    uint16_t compassWidth; // pixels
    uint16_t compassHeight; // pixels
    float compassRotation; // radians
    float playerX; // continentCoords
    float playerY; // continentCoords
    float mapCenterX; // continentCoords
    float mapCenterY; // continentCoords
    float mapScale;
    uint32_t processId;
    uint8_t mountIndex;
};
// mmgw.cpp : Defines the entry point for the application.
//

#include "mmgw.h"
#include <Windows.h>

int main()
{
	LinkedMem* lm = nullptr;
	LPCSTR mumblepath = "MumbleLink";
	HANDLE hMapObject = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(LinkedMem), mumblepath);

	if (hMapObject == NULL)
	{
		std::cout << "failed to create mumble link file" << std::endl;
		return EXIT_FAILURE;
	}

	lm = (LinkedMem*)MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(LinkedMem));
	if (lm == NULL)
	{
		std::cout << "mumble link file closed" << std::endl;
		CloseHandle(hMapObject);
		hMapObject = NULL;
		return EXIT_FAILURE;
	}
	std::wcout << lm->identity << "\n";
	std::string temp;
	std::cin >> temp;//just to wait before closing the prompt

	return EXIT_SUCCESS;
}
Locked