Last active
September 20, 2022 15:08
-
-
Save scy/f6fdca0481de564639a8b2bfbdcfa1b0 to your computer and use it in GitHub Desktop.
Example on how to access the Guild Wars 2 Mumble Link API on Windows using Go. Not supposed to be good Go code, but it works.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"log" | |
"syscall" | |
"time" | |
"unsafe" | |
"unicode/utf16" | |
"unicode/utf8" | |
"bytes" | |
) | |
type MumbleVector [3]float32 | |
type WChar uint16 | |
type MumbleIdentity [256]uint16 | |
func (id MumbleIdentity) String() string { | |
buf := make([]byte, 4) | |
var ret bytes.Buffer | |
runes := utf16.Decode(id[:]) | |
count := 0 | |
for _, rune := range runes { | |
utf8.EncodeRune(buf, rune) | |
ret.WriteString(string(rune)) | |
count++ | |
} | |
return ret.String() | |
} | |
type MumblePosition struct { | |
Position MumbleVector | |
Front MumbleVector | |
Top MumbleVector | |
} | |
type MumbleData struct { | |
Version uint32 | |
Tick uint32 | |
Avatar MumblePosition | |
Name [256]WChar | |
Camera MumblePosition | |
Identity MumbleIdentity | |
ContextLength uint32 | |
Context [256]byte | |
Description [2048]WChar | |
} | |
func main() { | |
file, _ := syscall.UTF16PtrFromString("MumbleLink") | |
size := 100000 // I’ve tried unsafe.Sizeof(MumbleData{}) but that didn’t work. | |
handle, err := syscall.CreateFileMapping(0, nil, syscall.PAGE_READWRITE, 0, uint32(size), file) | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer syscall.CloseHandle(handle) | |
addr, err := syscall.MapViewOfFile(handle, syscall.FILE_MAP_READ, 0, 0, 0) | |
if err != nil { | |
log.Fatal(err) | |
} | |
for { | |
data := (*MumbleData)(unsafe.Pointer(addr)) | |
time.Sleep(1 * time.Second) | |
fmt.Printf("ava %v cam %v id %v\n", data.Avatar.Position, data.Camera, data.Identity) | |
} | |
} |
I've elaborated a bit on this in my knowledge base.
this is great, thank you for sharing this.
@json-m Let me know when you’ve built something based on it ;)
size := 100000 // I’ve tried unsafe.Sizeof(MumbleData{}) but that didn’t work.
I think the size needs to be atleast the size of a page (4096 bytes). it probably won't work for size of mumbleLink as it is only 1050 ish bytes.
quote from https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createfilemappinga :
The maximum size of the file mapping object must be a multiple of the minimum size of a large page returned by the GetLargePageMinimum function.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Please note that you have to run this before starting up GW2. The game won’t enable the API if no one is listening.