Files
HellionChat/PRIVACY.md
T
JonKazama-Hellion 9ea9e96145 fix: close what the style review found, starting with a gate the metadata skipped
The real defect first. RefreshDatabaseMetadata was the one worker of six
that never took the shared lock, and its flag was the one of six missing
from the tab's busy state. It calls MessageCount, which holds the read
lock, so a wipe could start while it was in there -- and the tab would
not have known to grey the button, because it could not see the worker.
Both halves fixed. The pattern is why: seven near-copies of one worker
skeleton, and each copy decided something slightly different.

The clear button failed silently when its thread could not start. The
most destructive control in the plugin, pressed, and nothing happens,
with no way to tell that from a wipe that worked -- while the three
harmless workers beside it do report. Maintenance was the mirror: its
comment promises refusals are said out loud, and then swallowed the
actual failure. Three start-failure paths also bypassed the notify
helper that carries the teardown check, three weeks after it was added
for exactly that.

The database numbers now wait for a real read, like the clear hint
already did. Zero bytes and zero messages read as an empty database, not
as a number nobody has fetched.

SelectionAfterDelete is gone, with its three tests. The accordion has no
selection, so its return value went into a discard -- a function
answering a question the interface does not ask, with green tests
guarding nothing. The project's own self-test README calls that the
anti-pattern of record.

Six new keys replaced by the translated orphans that already said the
same thing. A commit earlier in this cycle is literally called "stop
duplicating a key" and these went past it. The duplicate button also had
the label "Add", which is the one string out of ninety-four that was
never written.

Tests: CleanupDeleteTypes had none, and with the failsafe on -- how a
fresh config ships -- it is the path every cleanup takes. Four now,
including the one that matters: an empty list deletes nothing rather
than everything.

And a self-test for the gate wiring, which is what would have caught the
metadata worker. The unit tests prove the gate works; nothing proved the
workers use it.
2026-08-19 07:09:54 +02:00

13 KiB

Privacy notice

HellionChat is a Dalamud plugin for FINAL FANTASY XIV, focused on giving the user explicit control over what their chat client stores locally. This document describes what the plugin does with your data, what it does not do, and how you exercise the rights the GDPR gives you over data you generate yourself.

This document is informational. The maintainer of HellionChat is not a controller or processor of your data in the GDPR sense, because no data ever leaves your machine on the maintainer's infrastructure. Independently of that, the plugin is built so that you can act on your own data the way the GDPR expects.

Last reviewed: 2026-08-18 (HellionChat v1.12.0).


TL;DR

  • All chat data the plugin stores stays on your machine, in your Dalamud pluginConfigs/HellionChat/ directory.
  • The plugin does not phone home. No telemetry, no analytics, no crash reporter, no usage counter, no remote update check beyond what Dalamud itself does.
  • One outbound network call exists by design: the BetterTTV emote service (for chat emotes). It is documented in detail below and can be reasoned about per request.
  • You can export every message the plugin has stored, in Markdown, JSON or CSV. You can delete it by channel, by age, or all of it at once.

What the plugin stores locally

HellionChat keeps three kinds of state on your machine, all under %appdata%\XIVLauncher\pluginConfigs\HellionChat\ on Windows (~/.xlcore/pluginConfigs/HellionChat/ on Linux/macOS via XIVLauncher Core):

  1. Configuration (HellionChat.json). Plugin settings, channel whitelist, retention values, layout state, theme colours. Contains no chat content.

  2. Message database (SQLite file in the same directory). Chat messages from the channels on your whitelist, stored as MessagePack-encoded blobs. The default whitelist out of the box covers only your own conversations: tells, party, free company, linkshells, cross-world linkshells, alliance, ExtraChat. Public chat, NPC dialogue, system messages and battle logs are dropped on the storage layer and never written to disk.

  3. Cached emote images (EmoteCacheV1/ directory). Image files downloaded from BetterTTV when an emote appears in a message you receive. See "Outbound network calls" below.

There is no shared state with the upstream Chat 2 plugin. pluginConfigs/HellionChat/ is independent from pluginConfigs/ChatTwo/.

Retention defaults

  • Tells: 365 days
  • Your-conversation channels (party, FC, linkshells, cross-world LS, alliance, ExtraChat): 90 days
  • Global default for anything else: 30 days

Retention is off by default. The plugin does not delete anything on its own until you explicitly turn the retention sweep on in the settings. Until then, stored messages stay until you clear them.


What the plugin does not store

  • Public chat (/say, /yell, /shout), NPC dialogue, system messages and battle logs. These are filtered before they reach the storage layer.
  • Anything from channels you remove from the whitelist. The privacy filter runs on the way in, not on the way out.
  • Login credentials, character IDs, account IDs. The plugin uses whatever Dalamud already exposes about the local character to attribute messages. Nothing of that is sent anywhere or persisted beyond the message itself.

Outbound network calls

HellionChat makes one kind of automatic outbound network request, inherited from upstream Chat 2 and documented here because "GDPR-by-design" means you should know what your client does on your behalf. The second one this section used to list, the Lodestone font download, was removed in v1.0.4 and the font is bundled instead.

1. BetterTTV emote service (api.betterttv.net, cdn.betterttv.net)

  • What it does: When a chat message arrives that references a BetterTTV emote, the plugin asks the BetterTTV API for the emote metadata and downloads the image from the BetterTTV CDN to display it inline.
  • What is sent: A standard HTTPS GET request. Your IP address reaches BetterTTV (unavoidable for any HTTPS request); the request itself contains no identifying user data, no character name, no message text. Only the emote ID being looked up is in the URL path.
  • When it triggers:
    • The emote list (global emotes plus the top-1500 community emotes over fifteen API pages) is fetched from api.betterttv.net once per session at plugin startup, provided the Show emotes option is on. This first list-fetch happens before any chat message has arrived. BetterTTV's edge therefore sees your IP as soon as the plugin loads, not only after an emote is mentioned.
    • The individual emote images on cdn.betterttv.net are fetched on demand, only when an incoming chat message contains a token matching one of the cached IDs. These are cached locally (EmoteCacheV1/) and reused across sessions.
  • Cached: Yes, in EmoteCacheV1/. A given emote is downloaded once per machine and reused.
  • How to opt out: Turn off the Show emotes option in Settings → Chat → Display modes. With it disabled, the emote cache does not load and no requests to BetterTTV are made for the rest of the session.
  • BetterTTV's privacy policy: https://betterttv.com/privacy

Source: HellionChat/EmoteCache.cs.

2. Square Enix Lodestone font (removed in v1.0.4)

Earlier versions of HellionChat (and upstream Chat 2) downloaded FFXIV_Lodestone_SSF.ttf from img.finalfantasyxiv.com once during font setup. That code path was a leftover from upstream's removed webinterface feature and was no longer consumed anywhere. The in-game symbol glyphs (job icons, item glyphs, status effects) come from Dalamud's bundled symbol-font helper, not from the downloaded TTF.

The download was removed in v1.0.4. As of that version HellionChat makes no automatic network call to Square Enix or to any finalfantasyxiv.com host.

Cached FFXIV_Lodestone_SSF.ttf files left over from earlier versions remain in pluginConfigs/HellionChat/ until manually deleted. They are no longer read.

The About tab contains buttons that open external pages in your browser when you click them: the Hellion Forge Discord invite, the HellionChat Gitea repository, its custom-repo manifest, and -- when the Honorific integration row is shown -- that plugin's GitHub repository and its author's profile. Nothing happens until you click. They are documented here for completeness, not because they generate background traffic.


What the plugin does not do

  • No telemetry. Source verified: no calls to AppInsights, Sentry, PostHog, Plausible, Google Analytics, Microsoft Clarity or any comparable service exist in the codebase, nor in the direct dependencies the plugin pulls in. See docs/THIRD_PARTY_NOTICES.md.
  • No crash reporting. Crashes go to Dalamud's local xllog, not to a remote endpoint controlled by HellionChat.
  • No usage counters. The plugin does not count installs, sessions, feature usage, channel activity or anything else for the maintainer.
  • No phone-home update check. Updates are delivered through Dalamud's plugin installer, which polls the custom-repo repo.json on GitHub. That is GitHub's traffic and falls under GitHub's privacy policy. The plugin code does no separate update check.
  • No background sync. Messages stay on your machine. No cloud backup, no sharing feature, no remote viewer.

Your data, your rights

The GDPR gives you specific rights over data about you. Because HellionChat stores everything locally, those rights translate directly into plugin features:

Right to access (Art. 15)

Settings → Data & Privacy → Export. You can export to Markdown, JSON or CSV, narrowed by channel group, by age in days, or by a substring of the sender's name. The export goes through a Dalamud file dialog and writes wherever you point it, on your machine. It reads the database on its own connection and writes to a temporary file first, so a run that is interrupted leaves the previous export in place rather than a file that looks complete and is not.

A note on the v1.12.0 filter correction

Before v1.12.0 the privacy filter applied the unknown-channel failsafe to known channels as well, so a channel you had unticked was still stored whenever that failsafe was on -- which is its default. That is fixed: an unticked channel stays out.

One consequence is worth stating plainly. A configuration that had the filter on, the failsafe on and no channel selected was storing everything through that hole. The corrected rule would store nothing at all, so the upgrade turns the filter off for exactly those configurations and writes a line to /xllog saying so. Nothing changes about what is stored; it is now stated where you can see it. Pick your channels and switch the filter back on whenever you like.

Right to erasure (Art. 17)

Two options:

  1. Targeted deletion. Settings → Data & Privacy → Cleanup applies your current channel list to the messages already stored. It shows a preview of what will be removed before you confirm with Ctrl+Shift, runs in the background, and calls VACUUM afterwards to actually shrink the file. Channels this build does not recognise -- ones a game patch added after the plugin was released -- survive the cleanup while "save unknown channel types" is on, for the same reason they are stored in the first place: so the decision about them stays yours.

    The cleanup is only offered when it can mean something. With the privacy filter off, every channel is stored and nothing contradicts your settings; with no channel selected, a cleanup would delete everything, and that is what the clear button is for. Both cases say so instead of offering a button that does not do what it looks like.

  2. Full deletion. Close the game and delete the pluginConfigs/HellionChat/ directory. The next plugin start will produce a fresh, empty configuration.

Right to portability (Art. 20)

The JSON and CSV exports are open formats. The Markdown export is human-readable and machine-parseable. Nothing is locked into a proprietary container.

Right to object / restrict processing (Art. 21, 18)

Adjust the channel whitelist or set retention to a low value. Both take effect immediately on new messages. Existing data needs the retroactive cleanup to apply retroactively, by design.


Third parties involved

Party Why they appear What reaches them Their privacy policy
BetterTTV (NightDev LLC) Optional emote rendering HTTPS request for an emote ID; your IP https://betterttv.com/privacy
Hellion Forge (Gitea, self-hosted by Hellion Online Media) Plugin distribution via custom repo, issue tracker Whatever the Gitea instance sees from any HTTPS request to a public repo https://hellion-media.de/datenschutz
Dalamud / XIVLauncher (goatcorp) Plugin loader, font subsystem, repo polling Whatever Dalamud reports for itself; out of HellionChat's scope https://github.com/goatcorp/Dalamud

The Hellion Forge Gitea instance and the Dalamud/XIVLauncher loader are unavoidable for anyone using HellionChat through Dalamud at all. BetterTTV is the only third party HellionChat introduces on top of that baseline, and it is opt-out via settings.


Dependencies that touch the network

For a full dependency inventory see docs/THIRD_PARTY_NOTICES.md. Of the direct dependencies the plugin pulls in:

  • MessagePack: local serialisation, no network.
  • Microsoft.Data.Sqlite: local SQLite access, no network.
  • morelinq: LINQ helpers, no network.
  • Pidgin: parser combinators, no network.
  • SixLabors.ImageSharp: image decoding (used for the BetterTTV emote pipeline), no network on its own.

The single network call listed under "Outbound network calls" is written directly in HellionChat's own source, not delegated to a dependency.


Changes to this notice

If a future release changes what HellionChat stores, sends or caches, this document will be updated and the change called out in the changelog block of that release. The "Last reviewed" date at the top tracks the version this document is accurate for.


Questions

For privacy-related questions specific to HellionChat:

  • Email: kontakt@hellion-media.de
  • Discord DM: @j.j_kazama

Security-relevant findings (for example, the plugin storing or sending something this document says it does not) go through the private advisory in SECURITY.md, not a public issue.


Maintained under Hellion Forge, the modding and plugin line of Hellion Online Media | Bad Harzburg | hellion-media.de