Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e393a7999b | ||
|
|
8048e804f6 | ||
|
|
3c76de9bdb | ||
|
|
0994fe4e08 | ||
|
|
f261c3be29 | ||
|
|
750fe8a2e5 | ||
|
|
aa9412d7c2 | ||
|
|
d0aff5e95a | ||
|
|
2a10763dac | ||
|
|
9449080788 | ||
|
|
bbe8fe2b83 | ||
|
|
5a8fd856b9 | ||
|
|
c0d297c3b9 | ||
|
|
1fb85ac7ea | ||
|
|
34ca3f6b83 | ||
|
|
79d0744b33 | ||
|
|
89efe5795d | ||
|
|
374b69dc2d | ||
|
|
2aa16fbbc1 | ||
|
|
4fe7cfd406 | ||
|
|
d3a2c1f842 | ||
|
|
3918f1da67 | ||
|
|
d2bf4c0883 | ||
|
|
22ee3b3970 | ||
|
|
cf1aa736ef | ||
|
|
503103179d | ||
|
|
36391f1ea9 |
@@ -72,18 +72,20 @@ jobs:
|
|||||||
dist/WowPresence.zip
|
dist/WowPresence.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Create GitHub Release v1.3
|
- name: Create GitHub Release v1.2
|
||||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.event.head_commit.message == 'release v1.3' }}
|
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' && github.event.head_commit.message == 'release v1.2' }}
|
||||||
uses: softprops/action-gh-release@v3
|
uses: softprops/action-gh-release@v3
|
||||||
with:
|
with:
|
||||||
tag_name: v1.3
|
tag_name: v1.2
|
||||||
target_commitish: ${{ github.sha }}
|
target_commitish: ${{ github.sha }}
|
||||||
files: |
|
files: |
|
||||||
|
dist/WowPresence.dll
|
||||||
|
dist/WowPresence.exe
|
||||||
dist/WowPresence.zip
|
dist/WowPresence.zip
|
||||||
fail_on_unmatched_files: true
|
fail_on_unmatched_files: true
|
||||||
name: "WowPresence v1.3"
|
name: "WowPresence v1.2"
|
||||||
body_path: RELEASE_NOTES.md
|
body_path: RELEASE_NOTES.md
|
||||||
generate_release_notes: false
|
generate_release_notes: true
|
||||||
make_latest: true
|
make_latest: true
|
||||||
|
|
||||||
- name: Create GitHub Release
|
- name: Create GitHub Release
|
||||||
@@ -91,6 +93,8 @@ jobs:
|
|||||||
uses: softprops/action-gh-release@v3
|
uses: softprops/action-gh-release@v3
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
|
dist/WowPresence.dll
|
||||||
|
dist/WowPresence.exe
|
||||||
dist/WowPresence.zip
|
dist/WowPresence.zip
|
||||||
fail_on_unmatched_files: true
|
fail_on_unmatched_files: true
|
||||||
name: "WowPresence ${{ github.ref_name }}"
|
name: "WowPresence ${{ github.ref_name }}"
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ After extraction, the relevant files should look like this:
|
|||||||
|
|
||||||
The runtime JSON and log files are created automatically inside the same `WowPresence` folder.
|
The runtime JSON and log files are created automatically inside the same `WowPresence` folder.
|
||||||
|
|
||||||
When WowPresence is installed through the **[Modernization Tool](https://github.com/Dusk-92/Modernization-Tool)**, the same binaries automatically use:
|
When WowPresence is installed through **Modernization Tool**, the same binaries automatically use:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
<WoW folder>\.modernization_tool\WowPresence\
|
<WoW folder>\.modernization_tool\WowPresence\
|
||||||
@@ -54,7 +54,9 @@ instead. No separate build is required.
|
|||||||
|
|
||||||
## 🛰️ Discord Application ID
|
## 🛰️ Discord Application ID
|
||||||
|
|
||||||
To configure your own Discord Application ID:
|
WowPresence intentionally does **not** include a server-specific Discord Application ID.
|
||||||
|
|
||||||
|
To create yours:
|
||||||
|
|
||||||
1. Open the **Discord Developer Portal**: https://discord.com/developers/applications
|
1. Open the **Discord Developer Portal**: https://discord.com/developers/applications
|
||||||
2. Create a **New Application**.
|
2. Create a **New Application**.
|
||||||
@@ -73,14 +75,6 @@ Example:
|
|||||||
123456789012345678
|
123456789012345678
|
||||||
```
|
```
|
||||||
|
|
||||||
For **OctoWoW**, you can use the preconfigured Discord Application ID:
|
|
||||||
|
|
||||||
```text
|
|
||||||
1544072796098011176
|
|
||||||
```
|
|
||||||
|
|
||||||
This is the same Application ID automatically configured by **Modernization Tool**.
|
|
||||||
|
|
||||||
No Discord Client Secret, bot token or bot account is used or required.
|
No Discord Client Secret, bot token or bot account is used or required.
|
||||||
|
|
||||||
If `discord_application_id` is missing or invalid, Rich Presence remains disabled and the reason is written to `WowPresence\WowPresence.log`.
|
If `discord_application_id` is missing or invalid, Rich Presence remains disabled and the reason is written to `WowPresence\WowPresence.log`.
|
||||||
@@ -161,75 +155,29 @@ Runtime files are kept together in one of these locations:
|
|||||||
|
|
||||||
If the Modernization Tool managed folder exists, WowPresence automatically prefers it. Otherwise it uses the standalone `WowPresence` folder.
|
If the Modernization Tool managed folder exists, WowPresence automatically prefers it. Otherwise it uses the standalone `WowPresence` folder.
|
||||||
|
|
||||||
## 🔒 Discord Rich Presence privacy
|
## 🔒 Privacy flags
|
||||||
|
|
||||||
WowPresence lets you choose exactly which character details are shown on Discord.
|
The included file:
|
||||||
|
|
||||||
For a standalone installation, edit:
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
WowPresence\discord_broadcast_flags
|
WowPresence\discord_broadcast_flags
|
||||||
```
|
```
|
||||||
|
|
||||||
When WowPresence is installed through **Modernization Tool**, the equivalent file is stored in:
|
controls which character details are published to Discord.
|
||||||
|
|
||||||
```text
|
|
||||||
.modernization_tool\WowPresence\discord_broadcast_flags
|
|
||||||
```
|
|
||||||
|
|
||||||
Modernization Tool provides checkboxes for these options, so manual bitmask editing is normally only needed for standalone WowPresence installations.
|
|
||||||
|
|
||||||
### Available fields
|
|
||||||
|
|
||||||
Each field has its own value:
|
|
||||||
|
|
||||||
| Value | Field |
|
| Value | Field |
|
||||||
| ---: | --- |
|
| ---: | --- |
|
||||||
| 1 | Character Name |
|
| 1 | Name |
|
||||||
| 2 | Guild |
|
| 2 | Guild |
|
||||||
| 4 | Faction |
|
| 4 | Faction |
|
||||||
| 8 | Class |
|
| 8 | Class |
|
||||||
| 16 | Level |
|
| 16 | Level |
|
||||||
| 32 | Zone |
|
| 32 | Zone |
|
||||||
| 64 | Race |
|
| 63 | All fields |
|
||||||
|
|
||||||
To display multiple fields, **add their values together** and put the result in `discord_broadcast_flags`.
|
The release package uses `63` by default.
|
||||||
|
|
||||||
### Examples
|
If the file is deleted, WowPresence also defaults to all supported fields.
|
||||||
|
|
||||||
| Display | Value |
|
|
||||||
| --- | ---: |
|
|
||||||
| Nothing | 0 |
|
|
||||||
| Character Name only | 1 |
|
|
||||||
| Faction + Class | 12 |
|
|
||||||
| Race only | 64 |
|
|
||||||
| Race + Faction + Class | 76 |
|
|
||||||
| Character Name + Level + Zone | 49 |
|
|
||||||
| All character details | 127 |
|
|
||||||
|
|
||||||
Example — to display **Race + Faction + Class**:
|
|
||||||
|
|
||||||
```text
|
|
||||||
Race = 64
|
|
||||||
Faction = 4
|
|
||||||
Class = 8
|
|
||||||
|
|
||||||
64 + 4 + 8 = 76
|
|
||||||
```
|
|
||||||
|
|
||||||
Then set:
|
|
||||||
|
|
||||||
```text
|
|
||||||
76
|
|
||||||
```
|
|
||||||
|
|
||||||
inside `discord_broadcast_flags`.
|
|
||||||
|
|
||||||
The default configuration uses `127`, which enables all supported character details.
|
|
||||||
|
|
||||||
WowPresence reads this setting while the game is running, so changes should normally appear on Discord automatically within a few seconds.
|
|
||||||
|
|
||||||
If the file is missing or contains an invalid value, WowPresence falls back to all supported fields.
|
|
||||||
|
|
||||||
## 🛡️ Administrator privileges
|
## 🛡️ Administrator privileges
|
||||||
|
|
||||||
@@ -258,16 +206,26 @@ GitHub Actions builds:
|
|||||||
|
|
||||||
The ZIP includes the ready-to-edit `WowPresence` configuration folder.
|
The ZIP includes the ready-to-edit `WowPresence` configuration folder.
|
||||||
|
|
||||||
Tags matching `v*` publish `WowPresence.zip` as the GitHub Release asset.
|
Tags matching `v*` can publish these files as a GitHub Release.
|
||||||
|
|
||||||
## 📜 Project identity
|
## 📜 Project identity & licensing
|
||||||
|
|
||||||
WowPresence is an **independent community project**.
|
WowPresence is an **independent community project**.
|
||||||
|
|
||||||
Compatibility with **World of Warcraft**, **Discord**, **OctoWoW**, **VanillaFixes**, or other referenced projects does not imply affiliation, endorsement, sponsorship or ownership by their respective rights holders or maintainers.
|
Compatibility with **World of Warcraft**, **Discord**, **OctoWoW**, **VanillaFixes**, **IchaLaunch**, or other referenced projects does not imply affiliation, endorsement, sponsorship or ownership by their respective rights holders or maintainers.
|
||||||
|
|
||||||
**World of Warcraft**, **Warcraft**, **Blizzard Entertainment**, **Discord**, and related names and marks remain the property of their respective rights holders.
|
**World of Warcraft**, **Warcraft**, **Blizzard Entertainment**, **Discord**, and related names and marks remain the property of their respective rights holders.
|
||||||
|
|
||||||
|
This repository does not currently declare a software license.
|
||||||
|
|
||||||
|
For detailed provenance and third-party information, see:
|
||||||
|
|
||||||
|
- [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)
|
||||||
|
|
||||||
## 🙏 Credits
|
## 🙏 Credits
|
||||||
|
|
||||||
WowPresence is maintained by **Dusk-92**.
|
WowPresence is maintained by **Dusk-92**.
|
||||||
|
|
||||||
|
The project was inspired in part by the WoW character-status / Discord Rich Presence implementation in **IchaLaunch** by **brutaliccus**.
|
||||||
|
|
||||||
|
The current WowPresence implementation is maintained separately and does not include IchaLaunch binaries.
|
||||||
|
|||||||
+11
-17
@@ -1,22 +1,16 @@
|
|||||||
# WowPresence v1.3
|
# WowPresence v1.2
|
||||||
|
|
||||||
## What's New
|
## Changes
|
||||||
|
|
||||||
- Added independent privacy control for:
|
- Reworked zone detection to use the player's real AreaTable ID.
|
||||||
- Character Name
|
- Zone names are now resolved from `AreaTable.dbc` instead of selecting the first plausible string from several client addresses.
|
||||||
- Guild
|
- Prevents internal map/area tokens such as `H32D` and `HLVA` from being published as Discord zone names.
|
||||||
- Race
|
- Uses the client's active localized AreaTable name when available, with a safe populated-locale fallback.
|
||||||
- Faction
|
- Keeps WowPresence fully standalone; ClassicAPI is not required.
|
||||||
- Class
|
- Modernization Tool installations continue to use `.modernization_tool\WowPresence\` automatically.
|
||||||
- Level
|
|
||||||
- Zone
|
|
||||||
- Added a dedicated Race flag.
|
|
||||||
- Full detail mask is now `127`.
|
|
||||||
- Fixed Discord Rich Presence combinations that previously failed when Name, Zone or Level were not shared.
|
|
||||||
- Race is no longer always shown and can now be disabled independently.
|
|
||||||
- Improved handling of empty Discord Rich Presence fields.
|
|
||||||
- Updated README with standalone privacy configuration examples.
|
|
||||||
|
|
||||||
## Included
|
## Included
|
||||||
|
|
||||||
- `WowPresence.zip` — ready-to-install package containing `WowPresence.dll`, `WowPresence.exe`, and the WowPresence configuration folder.
|
- `WowPresence.dll`
|
||||||
|
- `WowPresence.exe`
|
||||||
|
- `WowPresence.zip` ready-to-install standalone package
|
||||||
|
|||||||
@@ -2,6 +2,20 @@
|
|||||||
|
|
||||||
WowPresence contains original project code maintained by Dusk-92 and uses compatibility knowledge related to World of Warcraft 1.12.1 and Discord local Rich Presence IPC.
|
WowPresence contains original project code maintained by Dusk-92 and uses compatibility knowledge related to World of Warcraft 1.12.1 and Discord local Rich Presence IPC.
|
||||||
|
|
||||||
|
## IchaLaunch
|
||||||
|
|
||||||
|
The development of WowPresence was inspired in part by the character-status / Discord Rich Presence implementation in:
|
||||||
|
|
||||||
|
- Project: IchaLaunch
|
||||||
|
- Author / maintainer: brutaliccus
|
||||||
|
- Repository: https://github.com/brutaliccus/IchaLaunch
|
||||||
|
|
||||||
|
IchaLaunch was used as a technical reference during development, particularly for understanding a working WoW 1.12.1 character-status sampling approach.
|
||||||
|
|
||||||
|
The current WowPresence implementation is maintained separately and has been independently reworked. No IchaLaunch binary is included in this repository.
|
||||||
|
|
||||||
|
At the historical IchaLaunch revision reviewed during development, no explicit LICENSE, LICENSE.md, or COPYING file was present. This notice therefore records provenance and credit; it should not be interpreted as granting rights on behalf of the IchaLaunch author.
|
||||||
|
|
||||||
## ClassicAPI technical reference
|
## ClassicAPI technical reference
|
||||||
|
|
||||||
AreaTable and current-player-area client layout details were cross-checked against:
|
AreaTable and current-player-area client layout details were cross-checked against:
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
127
|
63
|
||||||
|
|||||||
+2
-4
@@ -75,8 +75,7 @@
|
|||||||
#define SHARE_CLASS 8u
|
#define SHARE_CLASS 8u
|
||||||
#define SHARE_LEVEL 16u
|
#define SHARE_LEVEL 16u
|
||||||
#define SHARE_ZONE 32u
|
#define SHARE_ZONE 32u
|
||||||
#define SHARE_RACE 64u
|
#define SHARE_ALL 63u
|
||||||
#define SHARE_ALL 127u
|
|
||||||
|
|
||||||
static const uintptr_t kPlayerNameLocations[] = {
|
static const uintptr_t kPlayerNameLocations[] = {
|
||||||
0x00C27FC8u, 0x00C27D88u, 0x00C27FD8u, 0
|
0x00C27FC8u, 0x00C27D88u, 0x00C27FD8u, 0
|
||||||
@@ -752,8 +751,7 @@ static void publish_character_snapshot(void) {
|
|||||||
|
|
||||||
collect_character_snapshot(&snapshot);
|
collect_character_snapshot(&snapshot);
|
||||||
mask = load_share_mask();
|
mask = load_share_mask();
|
||||||
race_text = (snapshot.in_world && (mask & SHARE_RACE))
|
race_text = snapshot.in_world ? label_for_id(kRaceLabels, snapshot.race_id) : "";
|
||||||
? label_for_id(kRaceLabels, snapshot.race_id) : "";
|
|
||||||
class_text = (snapshot.in_world && (mask & SHARE_CLASS))
|
class_text = (snapshot.in_world && (mask & SHARE_CLASS))
|
||||||
? label_for_id(kClassLabels, snapshot.class_id) : "";
|
? label_for_id(kClassLabels, snapshot.class_id) : "";
|
||||||
faction_text = (snapshot.in_world && (mask & SHARE_FACTION))
|
faction_text = (snapshot.in_world && (mask & SHARE_FACTION))
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* - is started automatically by WowPresence.dll after WoW is running
|
* - is started automatically by WowPresence.dll after WoW is running
|
||||||
* - reads the standalone WowPresence folder or the Modernization Tool managed folder
|
* - reads the standalone WowPresence folder or the Modernization Tool managed folder
|
||||||
* - publishes Discord Rich Presence over the local Discord IPC named pipe
|
* - publishes Discord Rich Presence over the local Discord IPC named pipe
|
||||||
* - exits when the target WoW process exits
|
* - exits when WoW_Modernized.exe exits
|
||||||
*/
|
*/
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@@ -293,9 +293,7 @@ static int load_status(Status *status) {
|
|||||||
json_string(json, "class", status->class_name, sizeof(status->class_name));
|
json_string(json, "class", status->class_name, sizeof(status->class_name));
|
||||||
json_string(json, "race", status->race, sizeof(status->race));
|
json_string(json, "race", status->race, sizeof(status->race));
|
||||||
json_int(json, "level", &status->level);
|
json_int(json, "level", &status->level);
|
||||||
return status->name[0] || status->zone[0] || status->level > 0 ||
|
return status->name[0] || status->zone[0] || status->level > 0;
|
||||||
status->guild[0] || status->faction[0] || status->class_name[0] ||
|
|
||||||
status->race[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rpc_read_packet(HANDLE pipe, char *payload, size_t payload_size) {
|
static int rpc_read_packet(HANDLE pipe, char *payload, size_t payload_size) {
|
||||||
@@ -404,26 +402,9 @@ static void format_activity(const Status *s, char *out, size_t out_size, long lo
|
|||||||
lstrcpynA(details, extra, sizeof(details));
|
lstrcpynA(details, extra, sizeof(details));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Discord rejects empty string values for Rich Presence text fields.
|
_snprintf(out, out_size,
|
||||||
* Omit a field entirely when the user did not choose anything that maps
|
"{\"details\":\"%s\",\"state\":\"%s\",\"timestamps\":{\"start\":%lld}}",
|
||||||
* to it, so Race/Class/Faction/Guild-only and Zone-only combinations work. */
|
details, s->zone, session_start);
|
||||||
if (details[0] && s->zone[0]) {
|
|
||||||
_snprintf(out, out_size,
|
|
||||||
"{\"details\":\"%s\",\"state\":\"%s\",\"timestamps\":{\"start\":%lld}}",
|
|
||||||
details, s->zone, session_start);
|
|
||||||
} else if (details[0]) {
|
|
||||||
_snprintf(out, out_size,
|
|
||||||
"{\"details\":\"%s\",\"timestamps\":{\"start\":%lld}}",
|
|
||||||
details, session_start);
|
|
||||||
} else if (s->zone[0]) {
|
|
||||||
_snprintf(out, out_size,
|
|
||||||
"{\"state\":\"%s\",\"timestamps\":{\"start\":%lld}}",
|
|
||||||
s->zone, session_start);
|
|
||||||
} else {
|
|
||||||
_snprintf(out, out_size,
|
|
||||||
"{\"timestamps\":{\"start\":%lld}}",
|
|
||||||
session_start);
|
|
||||||
}
|
|
||||||
out[out_size - 1] = 0;
|
out[out_size - 1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,11 +470,10 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE prev, LPSTR cmdline, int show)
|
|||||||
|
|
||||||
while (!pid && wait_loops++ < 25) {
|
while (!pid && wait_loops++ < 25) {
|
||||||
pid = find_process("WoW_Modernized.exe");
|
pid = find_process("WoW_Modernized.exe");
|
||||||
if (!pid) pid = find_process("WoW.exe");
|
|
||||||
if (!pid) Sleep(200);
|
if (!pid) Sleep(200);
|
||||||
}
|
}
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
log_line("No running WoW process found; WowPresence exiting.");
|
log_line("No running WoW_Modernized.exe found; WowPresence exiting.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,7 +483,7 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE prev, LPSTR cmdline, int show)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_line("WoW process detected.");
|
log_line("WoW_Modernized.exe detected.");
|
||||||
/* Fixed for the lifetime of this WoW process. Text updates, character
|
/* Fixed for the lifetime of this WoW process. Text updates, character
|
||||||
* changes and loading states reuse the same Discord elapsed-time origin. */
|
* changes and loading states reuse the same Discord elapsed-time origin. */
|
||||||
session_start = (long long)time(NULL);
|
session_start = (long long)time(NULL);
|
||||||
|
|||||||
Reference in New Issue
Block a user