Skip to content

Instantly share code, notes, and snippets.

@scy
Last active September 20, 2022 15:08
Show Gist options
  • Save scy/f6fdca0481de564639a8b2bfbdcfa1b0 to your computer and use it in GitHub Desktop.
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.
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)
}
}
@coderedart
Copy link

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