#wine #linux #wars #guild #file #x11 #json-file

bin+lib jokolink

A crate to copy MumbleLink of Guild Wars 2 by running in wine and copying it to linux filesystem for native access by linux apps

13 releases

0.4.0 Aug 26, 2022
0.3.0 Sep 25, 2021
0.2.6 Sep 25, 2021
0.2.1 Jul 21, 2021
0.1.23 Jun 26, 2021

#134 in Games


Used in jokolay

MIT license

67KB
1K SLoC

jokolink

A crate to extract info from Guild Wars 2 MumbleLink and copy it to a file /dev/shm in linux for native linux apps (primarily jokolay).

it will also get the x11 window id of the gw2 window and paste it at the end of the mumblelink data in /dev/shm. the format is simply 1193 bytes of useful mumblelink data AND an isize (for x11 window id of gw2). will sleep for 5 ms every frame (configurable), so will copy upto 200 times per second.

CMD Line

Takes the path to configuration json file as argument. example: ./jokolink.exe ./config.json assuming both jokolink.exe and config.json are in current directory.

Configuration

Jokolink configuration is stored in json format.

* loglevel: 
  default: "info"
  type: string
  possible_values: ["trace", "debug", "info", "warn", "error"]
  help: the log level of the application. 

* logdir: 
    default: "." // current working directory 
    type: directory path
    help: a path to a directory, where jokolink will create jokolink.log file

* mumble_link_names:
    default: ["MumbleLink"]
    type: array of strings
    help: names of mumble links to create and listen for. useful if you provide `-mumble` option to Guild Wars 2 for custom link name or if you use multi-boxing within the same prefix

* interval
    default: 5
    type: unsigned integer (positive integer)
    help: the interval to sleep after updating mumble link data. in milliseconds. 5 milliseconds is roughly 200 times per second which should be enough. 

* copy_dest_dir: 
    default: "z:\\dev\\shm"
    type: directory path
    help: the directory under which we will create files with the provided `mumble_link_names` and write the mumble data from the shared memory inside wine. lutris uses "z" drive to represent linux root "/". and /dev/shm is an in memory directory, so writing to files is basically just writing bytes to ram (not cached to disk filesystem).

sample script provided as run_jokolink.sh

#!/bin/bash
# WARNING!!! Jokolink will run forever unless someone else force closes it. 
# This behavior is necessary because gw2 might crash/restart itself within the same wine / lutris session. 
# so, we have no way of knowing when gw2 has quit completely within the same wine session or just restarting. 
# fortunately, lutris force closes all scripts when game exits. 


# copy this script and jokolink.exe into the wine prefix folder of gw2. and set it as the prelaunch script for gw2 in lutris. 
# lutris uses wine prefix folder as the current working directory, so keeping 
# everything relative to that will make things simpler. 

# We use a json file for configuration. if the path to config file provided doesn't exist, we just create a new config file in that place.
# Users can edit that configuration file as they see fit. documentation for the configuration can be found on the README page
# path to config file for jokolink. current directory is wine prefix, so a json file under that directory.
export config_path=./jokolink_config.json

# if jokolink crashes before initailizing logging (eg: due to bad config file), we have no way of getting errors from lutris, so 
# we output the crash stderr to this file, for easier debugging. 
# this command will use $WINE (set by lutris) and use the above options to run jokolink in background.
# remember that current directory is wine prefix, so jokolink.exe should be in that directory and the jokolink_cmd_output.txt will be created in that directory too.
$WINE './jokolink.exe' $config_path &>  jokolink_cmd_output.txt

Lutris Instructions:

  1. right click Guild Wars 2 in Lutris, and click on Browse Files to open the prefix folder.
  2. Copy jokolink.exe and run_jokolink.sh to that folder.
  3. right click Guild Wars 2 in Lutris again, and click on configure. make sure Show Advanced Options is checked at the bottom of the window.
  4. go to System options tab, go down until you find the Pre-launch script, click on browse and select the run_jokolink.sh file that we pasted in prefix folder.
  5. start Guild Wars 2 and you should see a /dev/shm/{link_name} file with link_name replaced by the mumble link name (default is "MumbleLink" ).
  6. if you can't find any such file, it means jokolink probably failed to start, you can go check the prefix folder for a jokolink.log file.
  7. raise an issue along with that log.

Quirks:

the Jokolink.exe will keep on running in the background until gw2 is closed. then, all the prelaunch scripts and their child process will be killed by lutris with SIGTERM signal.

Wine without Lutris

Jokolink needs to run with the same runner, prefix, env as guild-wars-2.

  1. runner. this is the wine executable that you will use to run gw2.
  2. prefix. this is the wine prefix folder of gw2, and if you use a same prefix but different runner for jokolink while gw2 is already running, it will crash.
  3. environment. primarily, the variables like WINE_FSYNC. these must also match or jokolink will crash when used in the same prefix.

For best results, just use extract command like lutris guild-wars-2 --output-script ./gw2env.sh which will output the script to a file named gw2env.sh I posted mine here for completion. username is puppy. I was able to delete most stuff except the WINE, WINEPREFIX, WINEFSYNC variables and launch the jokolink separately from gw2 and it worked fine. so, use those variables from your wine launching script. replace the last line for jokolink.exe instead of guild wars 2.

#!/bin/bash


# Environment variables
export SDL_VIDEO_FULLSCREEN_DISPLAY="off"
export VK_ICD_FILENAMES="/usr/share/vulkan/icd.d/nvidia_icd.json"
export STEAM_RUNTIME="/home/puppy/.local/share/lutris/runtime/steam"
export LD_LIBRARY_PATH="/home/puppy/.local/share/lutris/runners/wine/lutris-gw2-6.14-3-x86_64/lib:/home/puppy/.local/share/lutris/runners/wine/lutris-gw2-6.14-3-x86_64/lib64:/usr/lib/libfakeroot:/usr/lib/opencollada:/usr/lib/openmpi:/usr/lib32:/usr/lib:/usr/lib64:/home/puppy/.local/share/lutris/runtime/lib32:/home/puppy/.local/share/lutris/runtime/steam/i386/lib/i386-linux-gnu:/home/puppy/.local/share/lutris/runtime/steam/i386/lib:/home/puppy/.local/share/lutris/runtime/steam/i386/usr/lib/i386-linux-gnu:/home/puppy/.local/share/lutris/runtime/steam/i386/usr/lib:/home/puppy/.local/share/lutris/runtime/lib64:/home/puppy/.local/share/lutris/runtime/steam/amd64/lib/x86_64-linux-gnu:/home/puppy/.local/share/lutris/runtime/steam/amd64/lib:/home/puppy/.local/share/lutris/runtime/steam/amd64/usr/lib/x86_64-linux-gnu:/home/puppy/.local/share/lutris/runtime/steam/amd64/usr/lib:$LD_LIBRARY_PATH"
export DXVK_HUD="0"
export DXVK_LOG_LEVEL="none"
export STAGING_SHARED_MEMORY="1"
export __GL_SHADER_DISK_CACHE_PATH="/home/puppy/game/guild-wars-2"
export __NV_PRIME_RENDER_OFFLOAD="1"
export WINEDEBUG="-all"
export WINEARCH="win64"
export WINE="/home/puppy/.local/share/lutris/runners/wine/lutris-gw2-6.14-3-x86_64/bin/wine"
export GST_PLUGIN_SYSTEM_PATH_1_0="/home/puppy/.local/share/lutris/runners/wine/lutris-gw2-6.14-3-x86_64/lib64/gstreamer-1.0/:/home/puppy/.local/share/lutris/runners/wine/lutris-gw2-6.14-3-x86_64/lib/gstreamer-1.0/"
export WINEPREFIX="/home/puppy/game/guild-wars-2"
export WINEESYNC="1"
export WINEFSYNC="1"
export WINEDLLOVERRIDES="winemenubuilder.exe=d"
export WINE_LARGE_ADDRESS_AWARE="1"
export TERM="xterm"

# Command
/home/puppy/.local/share/lutris/runners/wine/lutris-gw2-6.14-3-x86_64/bin/wine '/home/puppy/game/guild-wars-2/drive_c/Program Files/Guild Wars 2/GW2-64.exe' -autologin -Windowed%       

Quirk for Wine without Lutris

jokolink will keep on running forever unless someone force closes it. so, if you are running it in background in a script, make sure to wait for gw2 to quit and kill jokolink before exiting.

Development

remember to make sure to run cargo check --target=x86_64-pc-windows-gnu to check if windows stuff is working well (if developing on linux) and cargo check --target=x86_64-unknown-linux-gnu to check if linux stuff is good.

I set the default target to x86_64-pc-windows-gnu in the .cargo/config.toml along with options for linkers to mingw toolchain. in case, you use another distro and find any compile issues, that's where you need to check for issues.

Linux

you will need to install the mingw toolchain to crosscompile the jokolink.exe . I already set the options in .cargo/config.toml and usually should be good as long as you installed mingw packages. edit the run_jokolink.sh pre-launch script in lutris so that it points ./jokolink.exe path to the ./target/x86_64-pc-windows-gnu/release/jokolink.exe or the debug one, so that you an just do cargo build --release to compile it fast and launch gw2 to test if it works. or symlink them. try to log everything so that you can check the logs, instead of bothering with getting logs from lutris.

Windows

you will need to edit the .cargo/config.toml and comment out everything. you will probably want to use the msvc toolchain instead of the gnu one. x86_64-pc-windows-msvc is the default target usually if you commented out the stuff as mentioned above. you will probably not run the binary part of crate as that's for wine usage, you will mostly be interested in the library part, so don't touch main.rs. if you want to develop for wine, use linux as its faster to check for errors live rather than dual booting back and forth to run it in wine.

Dependencies

~16–61MB
~1M SLoC