-
-
Save cb109/1d9996b0f7b4371a70a78dafc3ed4ce9 to your computer and use it in GitHub Desktop.
""" | |
Displays WoW health and mana status on a Razer Chroma keyboard. | |
Installation (Windows): | |
$ virtualenv venv | |
$ pip install requests | |
$ easy_install pillow | |
Usage: | |
- Run WoW client fullscreen on main monitor | |
- $ python wow_chroma.py | |
""" | |
import math | |
import sys | |
import time | |
import requests | |
from PIL import ImageGrab | |
# How often to screenshot and update the keyboard. | |
interval_seconds = 0.5 | |
# Colors | |
black = (0, 0, 0) | |
blue = (0, 0, 255) | |
dimmed = (4, 4, 4) | |
green = (0, 255, 0) | |
red = (255, 0, 0) | |
white = (255, 255, 255) | |
yellow = (255, 255, 0) | |
# Bounding boxes measured on a 1650x1080 screen. | |
healthbar_bbox = [114, 61, 252, 62] | |
manabar_bbox = [114, 74, 252, 75] | |
chroma_sdk_url = "http://localhost:54235/razer/chromasdk" | |
chroma_sdk_initial = { | |
"title": "Razer Chroma - Visualiser Sample", | |
"description": "Razer Chroma SDK Sample Application", | |
"author": { | |
"name": "Chroma Developer", | |
"contact": "www.razerzone.com", | |
}, | |
"device_supported": [ | |
"keyboard", | |
], | |
"category": "application", | |
} | |
def get_percentage_from_image(what, img): | |
channel = "B" if what == "mana" else "G" | |
img = img.getchannel(channel) | |
img = img.point(lambda px: 0 if px < 127 else 255) | |
colors = img.getcolors() | |
max_color_sum = img.width * 255 | |
actual_color_sum = sum([count * value for count, value in colors]) | |
percentage = actual_color_sum / (max_color_sum / 100.0) | |
return percentage | |
def get_health(): | |
img = ImageGrab.grab(healthbar_bbox) | |
return get_percentage_from_image("health", img) | |
def get_mana(): | |
img = ImageGrab.grab(manabar_bbox) | |
return get_percentage_from_image("mana", img) | |
def rgb_to_bgr(color): | |
red, green, blue = color | |
hexstring = "%02x%02x%02x" % (blue, green, red) | |
bgr = int(hexstring, 16) | |
return bgr | |
def get_health_color(health): | |
if health <= 33: | |
return red | |
if health <= 66: | |
return yellow | |
return green | |
def get_mana_color(mana): | |
return blue | |
def make_row(num, color, fallback=dimmed): | |
max_num = 22 | |
rest = max_num - num | |
row = [rgb_to_bgr(color) for i in range(num)] | |
row += [rgb_to_bgr(fallback) for i in range(rest)] | |
return row | |
def bars_to_keyboard(uri, health, mana, keys_max=22): | |
num_health_keys = int((keys_max / 100.0) * health) | |
num_mana_keys = int((keys_max / 100.0) * mana) | |
health_color = get_health_color(health) | |
mana_color = get_mana_color(mana) | |
# The chroma API expects 6 rows of 22 colors each which it maps | |
# directly to the keyboard keys. | |
data = { | |
"effect": "CHROMA_CUSTOM", | |
"param": [ | |
make_row(keys_max, dimmed), | |
make_row(num_health_keys, health_color), | |
make_row(num_health_keys, health_color), | |
make_row(num_mana_keys, mana_color), | |
make_row(num_mana_keys, mana_color), | |
make_row(keys_max, dimmed), | |
] | |
} | |
requests.put(uri + "/keyboard", json=data).json() | |
def main(): | |
response = requests.post(chroma_sdk_url, json=chroma_sdk_initial) | |
uri = response.json()["uri"] | |
try: | |
while True: | |
health = math.ceil(get_health()) | |
mana = math.ceil(get_mana()) | |
sys.stdout.write("health: {:.0f}%\tmana: {:.0f}%\r" | |
.format(health, mana)) | |
sys.stdout.flush() | |
bars_to_keyboard(uri, health, mana) | |
time.sleep(interval_seconds) | |
finally: | |
# Make sure to tell Synapse to close down our current API instance. | |
requests.delete(uri) | |
main() |
Hello question PY = Python right
How does that communicate with WoW ??
It does not communicate, not really. He set an area to check "visualy" when the game is launched, a box. Two in fact, one for the health and the other for the mana and calculate a colour depending on the % remaining on the filling of the box. It's smart but you must know where are your health and mana bars and modify this code with thoses infos.
@Tankyspanky @kornelion is right, there is no direct communication with the WoW client, all I do is take screenshots of a hardcoded screen area repeatedly, make a black and white image from that and count pixels to calculate how much percentage of life/mana is left. It's pretty much a fun experiment, not something I really used. Blizzard unfortunately is very adamant in allowing any real time communication between the WoW client and external software or even Lua scripts that run custom plugin, best you can get is data dumps from time to time e.g. after a combat has finished.
To make this script work on a screen that differs from my 1650x1080 resolution, you'd have to measure where the life/mana bars are and update the healthbar_bbox
and manabar_bbox
variables accordingly.
Hello question PY = Python right
How does that communicate with WoW ??