From 1b63765caa84b8a38dab3079d068763d09ab3aea Mon Sep 17 00:00:00 2001 From: JonKazama-Hellion Date: Sun, 3 May 2026 10:42:07 +0200 Subject: [PATCH] docs: community standards, privacy notice and release-body automation Closes the remaining gaps in GitHub's community-standards check, adds explicit privacy and dependency documentation matching the plugin's "DSGVO-by-design" claim, and removes the stale upstream Crowdin artefact so the repo no longer suggests it ships its own translation pipeline. New community-health files: - CODE_OF_CONDUCT.md: project-specific, short and direct, single reporting path to kontakt@hellion-media.de - CONTRIBUTING.md: scope, accepted vs declined contributions, build and test instructions, EUPL-1.2 contribution terms, translation policy split between Hellion-specific (here) and upstream strings (Chat 2 repo) - SUPPORT.md: routing for bugs, security, privacy and casual feedback - .github/PULL_REQUEST_TEMPLATE.md: summary, change-type checklist, testing notes, compatibility notes for migrations and manifest fields, contribution checklist - .github/FUNDING.yml: comments-only file, no platforms enabled, points donors at the upstream Chat 2 maintainers' Ko-fi pages New privacy and compliance documentation: - PRIVACY.md: what the plugin stores locally (config, SQLite, EmoteCacheV1), retention defaults, the two outbound network calls (BetterTTV API+CDN with ShowEmotes opt-out, Square Enix Lodestone font once-off), explicit no-telemetry statement, GDPR Art. 15/17/18/20/21 rights mapped to plugin features, third-party privacy-policy links - THIRD_PARTY_NOTICES.md: direct NuGet dependencies with versions pinned to v0.5.4 (MessagePack, Microsoft.Data.Sqlite, morelinq, Pidgin, SixLabors.ImageSharp under Six Labors Split License 1.0), Dalamud SDK and .NET tooling, bundled Exo 2 font (OFL-1.1) and plugin icon, network-touch status per component, re-audit commands Crowdin cleanup: - crowdin.yml deleted (was upstream Chat 2's project_id 663694, pointed at /ChatTwo/Resources/Language.resx, never wired to HellionChat strings) - README, CONTRIBUTING and CODE_OF_CONDUCT no longer suggest HellionChat operates a Crowdin project; remaining mentions are explicitly framed as upstream Chat 2's workflow Contact and version consistency: - Maintainer email switched from maintainer@hellion-media.de to kontakt@hellion-media.de in SECURITY.md and NOTICE.md - README version references updated to 0.5.4 (header, project status block) and the update-tag pattern generalised from v0.1.x to v0.X.Y - bug_report.yml version placeholder bumped to 0.5.4 - Project-documents table added to README footer linking all health and reference files in one place Release-body automation: - .github/workflows/release.yml now extracts the matching version block from ChatTwo/HellionChat.yaml's changelog and combines it with a static install / docs footer (custom-repo URL, project document links, licence) before passing the result to softprops/action-gh-release@v3 via body_path - Workflow fails fast if no changelog block exists for the tagged version, automating the existing "yaml + repo.json + release body kept in sync" rule - Tag value passed via env: TAG_NAME with strict ^v\d+\.\d+\.\d+$ validation before any string concatenation, so the tag input cannot break out into shell evaluation --- .github/FUNDING.yml | 13 ++ .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- .github/PULL_REQUEST_TEMPLATE.md | 72 +++++++ .github/workflows/release.yml | 103 +++++++++- CODE_OF_CONDUCT.md | 71 +++++++ CONTRIBUTING.md | 132 +++++++++++++ NOTICE.md | 2 +- PRIVACY.md | 259 ++++++++++++++++++++++++++ README.md | 29 ++- SECURITY.md | 2 +- SUPPORT.md | 50 +++++ THIRD_PARTY_NOTICES.md | 92 +++++++++ crowdin.yml | 13 -- 13 files changed, 815 insertions(+), 25 deletions(-) create mode 100644 .github/FUNDING.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 PRIVACY.md create mode 100644 SUPPORT.md create mode 100644 THIRD_PARTY_NOTICES.md delete mode 100644 crowdin.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..7e973c7 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,13 @@ +# HellionChat is a hobby project and does not solicit funding. +# +# If you want to support the work that made HellionChat possible, +# please consider supporting the upstream Chat 2 maintainers: +# +# Infiziert90 (Infi): https://ko-fi.com/infiii +# Anna Clemens: https://ko-fi.com/lojewalo +# +# Both Ko-fi pages are also linked in the plugin's settings panel. + +# No platforms enabled — keep this file present so GitHub recognises +# the project as having considered funding without showing a Sponsor +# button on the repository page. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 9533f32..6a86c29 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -16,7 +16,7 @@ body: attributes: label: HellionChat version description: From Settings → Information → Version - placeholder: "0.5.1" + placeholder: "0.5.4" validations: required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..f5cf909 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,72 @@ + + +## Summary + + + +## Type of change + + + +- [ ] Bug fix (non-breaking change that fixes an issue) +- [ ] New feature (non-breaking change that adds behaviour) +- [ ] Breaking change (config migration, removed feature, or behaviour + change that user-visible defaults rely on) +- [ ] Documentation only +- [ ] Translation update +- [ ] Build, CI or tooling change +- [ ] Upstream cherry-pick from Chat 2 + +## Linked issue + + + +## How I tested this + + + +## User-visible changes + + + +## Compatibility notes + + + +## Checklist + +- [ ] I have read [CONTRIBUTING.md](../CONTRIBUTING.md) and + [CODE_OF_CONDUCT.md](../CODE_OF_CONDUCT.md). +- [ ] My change matches the existing code style (`.editorconfig`). +- [ ] I added or updated tests where the existing test infrastructure + made that practical, or I have explained why tests are not + applicable. +- [ ] I updated the README, in-plugin strings or documentation if my + change is user-visible. +- [ ] I did not include any AI-generated code without disclosing it + in the PR description (see [AI_DISCLOSURE.md](../AI_DISCLOSURE.md)). +- [ ] I confirm my contribution is released under the + [EUPL-1.2](../LICENSE). diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ec6dd3d..581a9c9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,9 +3,14 @@ name: Release # Triggered when a vX.Y.Z tag is pushed. Builds the plugin against the # current Dalamud staging branch, locates the latest.zip produced by # DalamudPackager and attaches it to the matching GitHub Release. -# Does not consume any user-controlled event payload, only the tag name -# (validated by the on.tags filter) and the steps output of the locate -# step (path string from Get-ChildItem on a controlled directory). +# +# User-controlled inputs touched by this workflow: +# - the tag name (filtered by on.tags = v*, validated again at runtime +# against ^v\d+\.\d+\.\d+$ before being used in any string) +# All other values are either repo-controlled (paths under +# ChatTwo/bin/Release derived from Get-ChildItem) or pinned URLs to +# goatcorp / GitHub. Nothing from a webhook event payload (issue/PR +# titles, commit messages, etc.) flows into a run-step. on: push: @@ -53,9 +58,101 @@ jobs: Write-Host "Found: $($zip.FullName)" "path=$($zip.FullName)" | Out-File -FilePath $env:GITHUB_OUTPUT -Append + # Build a release body from the matching changelog block in + # HellionChat.yaml plus a static install / docs footer. Fails the + # workflow if no block exists for the tagged version, which is the + # automated counterpart to the "yaml + repo.json + release body + # kept in sync" rule. + # + # GITHUB_REF_NAME is read via env: (not ${{ }} interpolation) so the + # tag value is treated as a PowerShell variable, not as inline shell + # text. The strict regex below rejects anything that is not a clean + # semver tag before it is used to build a string. + - name: Generate release body + shell: pwsh + env: + TAG_NAME: ${{ github.ref_name }} + run: | + $tag = $env:TAG_NAME + if ($tag -notmatch '^v\d+\.\d+\.\d+$') { + throw "Refusing to generate release body for non-semver tag: $tag" + } + $version = $tag.Substring(1) + + $yamlPath = "ChatTwo/HellionChat.yaml" + $raw = Get-Content -Path $yamlPath -Raw + + $marker = "changelog: |-" + $idx = $raw.IndexOf($marker) + if ($idx -lt 0) { throw "changelog block not found in $yamlPath" } + + # changelog: is the last top-level key in the manifest, so + # everything after the marker is the literal block. Strip the + # 2-space yaml indent from each line. + $afterMarker = $raw.Substring($idx + $marker.Length) + $changelogBody = (($afterMarker -split "`r?`n") | ForEach-Object { + if ($_ -match '^ ') { $_.Substring(2) } else { $_ } + }) -join "`n" + + $header = "**Hellion Chat $version" + $start = $changelogBody.IndexOf($header) + if ($start -lt 0) { + throw "No changelog entry for version $version found in $yamlPath. Update the changelog block before tagging a release." + } + + $rest = $changelogBody.Substring($start) + $nextHdr = $rest.IndexOf("`n`n**Hellion Chat ", 1) + $trailer = $rest.IndexOf("`n`n---") + + if ($nextHdr -ge 0 -and ($trailer -lt 0 -or $nextHdr -lt $trailer)) { + $currentBlock = $rest.Substring(0, $nextHdr).TrimEnd() + } elseif ($trailer -ge 0) { + $currentBlock = $rest.Substring(0, $trailer).TrimEnd() + } else { + $currentBlock = $rest.TrimEnd() + } + + $footer = @' + +--- + +## How to install + +This release is distributed via the HellionChat custom repository, not the +Dalamud main plugin repo. To install: + +1. In XIVLauncher: **Settings → Experimental → Custom Plugin Repositories** +2. Add the URL: + `https://raw.githubusercontent.com/JonKazama-Hellion/HellionChat/main/repo.json` +3. Enable, save, then `/xlplugins` → search **Hellion Chat** → install + +## Project documents + +- [README](https://github.com/JonKazama-Hellion/HellionChat/blob/main/README.md) — features, architecture, build +- [Privacy notice](https://github.com/JonKazama-Hellion/HellionChat/blob/main/PRIVACY.md) — what the plugin stores and sends +- [Third-party notices](https://github.com/JonKazama-Hellion/HellionChat/blob/main/THIRD_PARTY_NOTICES.md) — dependencies and licences +- [Security policy](https://github.com/JonKazama-Hellion/HellionChat/blob/main/SECURITY.md) — vulnerability reporting +- [Support](https://github.com/JonKazama-Hellion/HellionChat/blob/main/SUPPORT.md) — bug reports, questions, contact paths + +## Licence + +[EUPL-1.2](https://github.com/JonKazama-Hellion/HellionChat/blob/main/LICENSE). +Based on [Chat 2](https://github.com/Infiziert90/ChatTwo) by Infi and Anna, +also EUPL-1.2. +'@ + + $body = $currentBlock + "`n" + $footer + $body | Out-File -FilePath release-body.md -Encoding utf8 -NoNewline + + Write-Host "Generated release body for $tag :" + Write-Host "----------------------------------------" + Write-Host $body + Write-Host "----------------------------------------" + - name: Attach to GitHub release uses: softprops/action-gh-release@v3 with: files: ${{ steps.locate.outputs.path }} + body_path: release-body.md fail_on_unmatched_files: true generate_release_notes: false diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..b029c00 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,71 @@ +# Code of conduct + +HellionChat is a small hobby project. The contributor base is tiny and +the moderation overhead I can afford is equally small, so this document +is short and direct. + +## What I expect from contributors + +- Be respectful in issues, pull requests, discussions and any other + project space (Discord, email). +- Keep feedback focused on the code, the design or the documentation. + Critique the work, not the person. +- Assume good intent. People come from different backgrounds, time + zones and skill levels. A clarifying question is almost always a + better first move than an accusation. +- Stay on topic. This project is about a Dalamud chat plugin. Off-topic + arguments belong elsewhere. +- Respect that I maintain this in my spare time. Replies can take a + few days. Please do not escalate just because a thread is quiet. + +## What is not welcome + +- Personal attacks, slurs, doxxing, sustained disruption of threads. +- Unsolicited private contact after I have asked someone to stop. +- Sharing of private conversations without consent. +- Any content that would put other contributors or end users at risk. + +## Scope + +This applies to every space the project owns or that I run on its +behalf: the GitHub repository, GitHub Discussions, project-related +Discord conversations and the maintainer email address listed in +`SECURITY.md`. + +It also applies when someone is identifiably representing the project +in another space, for example posting as a HellionChat maintainer in +the Dalamud Discord. + +## Reporting + +If something here is being broken, contact me directly. Do not open a +public issue. + +- Email: `kontakt@hellion-media.de` +- Discord DM: `@j.j_kazama` + +Reports stay private. I will acknowledge within a few weekdays +(European business hours) and tell you what I plan to do. + +## Enforcement + +I am the sole maintainer, so enforcement is a single-person process. +Depending on what happened and how the person responds, I will pick +the lightest measure that resolves the issue: + +1. Private note asking the behaviour to stop. +2. Public correction in the affected thread. +3. Edit or removal of the offending content. +4. Temporary block from the repository or related spaces. +5. Permanent block. + +Severe cases skip the lower steps. I will not negotiate over +harassment or threats. + +## Acknowledgement + +This document is intentionally short and project-specific rather than +a copy of a longer template. If you need a more formal reference, the +[Contributor Covenant](https://www.contributor-covenant.org/) is a +widely adopted starting point and the spirit of this document is +compatible with it. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..80410db --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,132 @@ +# Contributing to HellionChat + +Thanks for taking a look. HellionChat is a small, opinionated fork of +[Chat 2](https://github.com/Infiziert90/ChatTwo) maintained by one +person in spare time. This document explains what I am looking for, +what I am not, and how to make a contribution land smoothly. + +## Before you open anything + +- Read the [README](README.md) so you understand the scope: this is a + privacy-focused, EUPL-1.2-licensed Dalamud plugin that intentionally + removes the upstream webinterface and ships smaller defaults. +- Read [UPSTREAM_SYNC.md](UPSTREAM_SYNC.md). Cherry-picks from upstream + Chat 2 are selective and conscious; not everything that lands there + belongs here. +- Read [SECURITY.md](SECURITY.md). Anything security-sensitive goes + through a private advisory, never a public issue or PR. +- Read the [code of conduct](CODE_OF_CONDUCT.md). + +## What I will accept + +- Bug fixes for behaviour documented in the README, the in-plugin + settings or the changelog. +- Translation contributions for Hellion-specific strings via direct + pull requests against `ChatTwo/Resources/HellionStrings.*.resx`. + Translations for the upstream Chat 2 strings (`Language.*.resx`) are + not handled here; they go through the upstream Chat 2 project. +- Documentation improvements (README, comments, this file). +- Performance fixes with a measurable before/after. +- New features that fit the privacy-first scope and do not duplicate + what an existing Dalamud plugin already does well. + +## What I will probably decline + +- Re-introducing the webinterface or any remote-access feature. It was + removed in v0.2.0 on purpose. See README "Was gegenüber Chat 2 fehlt". +- Features that bypass the privacy filter or weaken the default + retention behaviour without an explicit, documented opt-in. +- Sweeping refactors that touch large parts of the upstream codebase. + They make selective upstream cherry-picks much harder and the + maintenance cost outweighs the benefit for a one-person project. +- AI-generated code dropped in without disclosure or human review. See + [AI_DISCLOSURE.md](AI_DISCLOSURE.md) for how I handle AI assistance + on my side; I expect comparable transparency from contributors. + +If you are unsure whether an idea fits, open a feature-request issue +first and ask before writing code. I would rather say "no" to a +proposal than to a finished pull request. + +## Workflow + +1. Open an issue (bug or feature request) using the templates under + `.github/ISSUE_TEMPLATE/`. Skip this step only for trivial typos. +2. Fork the repository and branch off `main`. Branch naming is + informal; something like `fix/auto-tell-history-empty` or + `feat/adblock-light-mode` is plenty. +3. Match the existing code style. The repository ships an + `.editorconfig` that VS Code and Rider pick up automatically. +4. Keep commits focused. Several small commits with clear messages are + easier to review than one big one. Squash-on-merge happens at the + PR level if needed. +5. If your change touches user-visible behaviour, update the README + and/or the changelog block in `ChatTwo/HellionChat.yaml` and + `repo.json` for the next version. I bump the version number myself + at release time, so you do not need to. +6. Open the pull request against `main`. The PR template will ask + you to summarise the change, the testing you did and any + compatibility notes. + +## Build and test + +The project targets `net10.0-windows` against Dalamud SDK 15. To build +locally you need: + +- .NET 10 SDK +- A working Dalamud development environment with `DALAMUD_HOME` set + (XIVLauncher installed and launched once is the simplest path) +- VS Code with the C# Dev Kit, Rider, or Visual Studio + +``` +dotnet restore +dotnet build ChatTwo.sln -c Release +dotnet test ChatTwo.sln -c Release +``` + +The test project is `ChatTwo.Tests`. New behaviour should come with a +test where the existing test infrastructure makes that practical +(privacy filter, configuration migration, message store). + +For a smoke test in-game: build, copy the output into your Dalamud +`devPlugins/HellionChat/` directory and load it through `/xlplugins`. + +## Continuous integration + +Every push and every pull request runs: + +- `build.yml` — `dotnet build` and `dotnet test` +- `codeql.yml` — CodeQL security analysis + +A pull request will not be merged while either of these is failing. +CodeQL findings on changed code need to be addressed; pre-existing +findings on untouched code are tracked separately. + +## Licensing + +By submitting a pull request you confirm that: + +- Your contribution is your own work, or you have the right to + contribute it under the project licence. +- You agree that your contribution will be released under the + [EUPL-1.2](LICENSE), the same licence as the rest of the project. + +There is no separate CLA. + +## Translations + +Hellion-specific strings live in `ChatTwo/Resources/HellionStrings.resx` +(English source) and `HellionStrings..resx` (per-language). +Translations are accepted as direct pull requests against those files. + +The upstream Chat 2 strings in `ChatTwo/Resources/Language.*.resx` are +**not** translated in this repository. They are owned by the upstream +Chat 2 project and synced in via cherry-pick. Please contribute +upstream-string translations to +[Infiziert90/ChatTwo](https://github.com/Infiziert90/ChatTwo) instead. + +## A note on response times + +I respond on weekdays during European business hours and I take +weekends and FFXIV patch days off. A pull request that sits for a few +days has not been ignored; I just have not gotten to it yet. Pinging +once after a week is fine; please do not ping daily. diff --git a/NOTICE.md b/NOTICE.md index feb30ee..c8ba530 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -50,7 +50,7 @@ to Chat 2 or to anything Infi or Anna would want flagged: - **GitHub Issues:** [JonKazama-Hellion/HellionChat/issues](https://github.com/JonKazama-Hellion/HellionChat/issues) - **Discord:** `@j.j_kazama` -- **Email (business):** maintainer@hellion-media.de +- **Email (business):** kontakt@hellion-media.de I respond on weekdays during European business hours. For anything urgent (security, attribution, takedown), email is the fastest path. diff --git a/PRIVACY.md b/PRIVACY.md new file mode 100644 index 0000000..dc9a197 --- /dev/null +++ b/PRIVACY.md @@ -0,0 +1,259 @@ +# Privacy notice + +HellionChat is a Dalamud plugin for FINAL FANTASY XIV that focuses 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-05-03 (HellionChat v0.5.4). + +--- + +## TL;DR + +- All chat data the plugin stores stays on your machine, in your + Dalamud `pluginConfigs/HellionChat/` directory. +- The plugin does not phone home. There is no telemetry, no analytics, + no crash reporter, no usage counter, no remote update check beyond + what Dalamud itself does. +- Two outbound network calls exist by design: the BetterTTV emote + service (for chat emotes) and the Square Enix Lodestone font CDN + (for the in-game symbol font). Both are documented in detail below + and both can be reasoned about per request. +- You can export every message the plugin has stored, in Markdown, + JSON or CSV, and you can wipe stored history per channel, per date + range, or globally. + +--- + +## 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. 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 two kinds of automatic outbound network requests. +Both are inherited from upstream Chat 2 and both are documented here +because "DSGVO-by-design" means you should know what your client does +on your behalf. + +### 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:** Only when an incoming message contains an + emote token that is on the BetterTTV emote list. +- **Cached:** Yes, in `emoteCache/`. A given emote is downloaded once + per machine and reused. +- **How to opt out:** Turn off the **Show emotes** option in + Settings → Chat. 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:** + +Source: `ChatTwo/EmoteCache.cs`. + +### 2. Square Enix Lodestone font (`img.finalfantasyxiv.com`) + +- **What it does:** Downloads the `FFXIV_Lodestone_SSF.ttf` font file + from the official Square Enix Lodestone CDN once during font setup, + so the plugin can render in-game special symbols (job icons, item + glyphs, etc.) inside ImGui. +- **What is sent:** A single HTTPS GET request to the public Square + Enix font URL. Your IP address reaches Square Enix (unavoidable); + no character data, no plugin identifier, no message content. +- **When it triggers:** Once per font initialisation, not per session + if the file is already cached locally. +- **Cached:** Yes, by Dalamud's font subsystem. +- **How to opt out:** This call is part of the font pipeline inherited + from upstream Chat 2 and not toggleable from the settings UI today. + If a user-facing opt-out for this would be useful for you, please + open a feature-request issue. + +Source: `ChatTwo/FontManager.cs`. + +### Links you click yourself (no automatic traffic) + +The settings panel contains a few buttons that open external pages in +your browser when you click them: the upstream Chat 2 GitHub repo, +the upstream maintainers' Ko-fi pages, the HellionChat issue tracker +and `hellion-media.de`. 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 `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. There is 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) + +Use the export feature in the plugin settings. You can export to +**Markdown**, **JSON** or **CSV**, filtered by channel, date range +or sender substring. The export goes through a Dalamud file dialog +and writes wherever you point it, on your machine. + +### Right to erasure (Art. 17) + +Two options: + +1. **Targeted deletion** — the "retroactive cleanup" feature lets you + apply your current whitelist to the existing database. 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. +2. **Full deletion** — close the game and delete the + `pluginConfigs/HellionChat/` directory. 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 | | +| Square Enix | Lodestone font download (once) | HTTPS request for the font file; your IP | | +| GitHub (Microsoft) | Plugin distribution via custom repo, issue tracker | Whatever GitHub sees from any HTTPS request to a public repo | | +| Dalamud / XIVLauncher (goatcorp) | Plugin loader, font subsystem, repo polling | Whatever Dalamud reports for itself; out of HellionChat's scope | | + +Square Enix and GitHub are unavoidable for anyone playing FFXIV +through Dalamud at all. BetterTTV is the only third party HellionChat +introduces on top of the baseline that is not also part of using FFXIV +or Dalamud, and BetterTTV is opt-out via settings. + +--- + +## Dependencies that touch the network + +For a full dependency inventory see `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 two network calls listed under "Outbound network calls" are +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 (e.g. the plugin storing or sending +something this document says it does not) go through the private +advisory in `SECURITY.md`, not a public issue. diff --git a/README.md b/README.md index 752be4a..ab56bb7 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![.NET](https://img.shields.io/badge/.NET-10.0-512BD4)](https://dotnet.microsoft.com/) [![FFXIV](https://img.shields.io/badge/FFXIV-Dawntrail-c3a37f)](https://www.finalfantasyxiv.com/) -**Version 0.5.1** — DSGVO-bewusste Erweiterung von [Chat 2](https://github.com/Infiziert90/ChatTwo) für FINAL FANTASY XIV / Dalamud. +**Version 0.5.4** — DSGVO-bewusste Erweiterung von [Chat 2](https://github.com/Infiziert90/ChatTwo) für FINAL FANTASY XIV / Dalamud. Hellion Chat baut auf Chat 2 auf und ergänzt es um Datenschutz- und Daten-Handling-Kontrollen, die mit den Datenschutz-Regeln in der EU, den USA und Japan im Einklang sind. Alle Chat-2-Funktionen, Befehle und Tastenkürzel funktionieren unverändert. Eigenständiger Plugin-Slot, eigene Konfiguration, eigene Datenbank. @@ -29,7 +29,7 @@ Hellion Chat baut auf [Chat 2](https://github.com/Infiziert90/ChatTwo) von **Inf | Build | Dalamud.NET.Sdk 15.0.0, DalamudPackager 15.0.0 | | UI | Dear ImGui (Dalamud-Bindings) | | Datenbank | SQLite (Microsoft.Data.Sqlite, MessagePack-Storage) | -| Lokalisierung | ResX (HellionStrings.resx, .de.resx) + Crowdin-Sync | +| Lokalisierung | ResX (HellionStrings.resx, .de.resx; PR-basiert) | | Schriftart | Exo 2 (SIL Open Font License 1.1, gebündelt) | | Toolchain | dotnet 10 SDK, VS Code mit C# Dev Kit | | Deployment | GitHub Releases + Custom-Repo (`repo.json`) | @@ -44,6 +44,7 @@ Hellion Chat baut auf [Chat 2](https://github.com/Infiziert90/ChatTwo) von **Inf - **Aufbewahrungsdauer pro Kanal** mit täglicher Background-Bereinigung. Tells 365 Tage, eigene Konversations-Kanäle 90 Tage, globaler Default 30 Tage. Standard ist AUS, das Plugin löscht ohne ausdrückliche Zustimmung nichts. - **Retroaktive Säuberung** mit Vorschau und Strg+Umschalt-Bestätigung. Wendet die aktuelle Whitelist auf eine bestehende Datenbank an, läuft im Hintergrund, ruft danach VACUUM auf. - **Export** nach Markdown, JSON oder CSV via Dalamud-Datei-Dialog (DSGVO Art. 15 Auskunftsrecht). Filter nach Kanal, Datums-Bereich oder Sender-Substring. +- **Vollständige Datenschutz-Übersicht** in [`PRIVACY.md`](PRIVACY.md): was gespeichert wird, welche zwei Outbound-Calls existieren (BetterTTV opt-out, Square-Enix-Lodestone-Font), explizite Telemetry-None-Zusage und das Mapping der DSGVO-Rechte (Art. 15/17/18/20/21) auf konkrete Plugin-Funktionen. ### Onboarding @@ -102,7 +103,7 @@ ChatTwo/ - **Code-Namespace bleibt `ChatTwo.*`** — Cherry-Picks von Upstream-Bugfixes bleiben damit konfliktarm. - **AssemblyName ist `HellionChat`** — eigener Slot in `pluginConfigs/`, eigene Datei-Manifest, kein Shared State mit Chat 2. -- **Hellion-eigene Strings nur in `HellionStrings.*.resx`** — die Upstream-`Language.*.resx` bleiben unverändert für sauberen Crowdin-Sync. +- **Hellion-eigene Strings nur in `HellionStrings.*.resx`** — die Upstream-`Language.*.resx` bleiben unverändert, damit Cherry-Picks aus Chat 2 (inklusive deren Übersetzungs-Updates aus dem Upstream-Crowdin) konfliktarm bleiben. - **Kein Direkt-Eingriff in `Plugin.Interface.UiBuilder.FontAtlas`** außerhalb von `FontManager` — Font-Fallback und Hellion-Font laufen zentral. --- @@ -181,7 +182,7 @@ Spiel starten, Hellion Chat aktivieren, Verlauf ist zurück. ### Updates -Updates erscheinen automatisch in der Plugin-Liste, sobald ein neuer `v0.1.x`-Tag mit GitHub-Release publiziert ist. Keine Neu-Installation nötig. +Updates erscheinen automatisch in der Plugin-Liste, sobald ein neuer `v0.X.Y`-Tag mit GitHub-Release publiziert ist. Keine Neu-Installation nötig. --- @@ -225,7 +226,7 @@ git log --oneline HEAD..upstream/main # Welche Commits gibt es? git cherry-pick -x # Selektiv übernehmen ``` -Konflikte in Upstream-Sprach-Ressourcen (`Language..resx`) kommen häufig vor weil Crowdin sie regelmäßig anfasst. Pragmatisch mit `git checkout --theirs` auflösen, da wir sie selbst nicht editieren. +Konflikte in Upstream-Sprach-Ressourcen (`Language..resx`) kommen häufig vor, weil Upstream-Übersetzungen (über das Chat-2-Crowdin-Projekt, nicht unseres) regelmäßig nachkommen. Pragmatisch mit `git checkout --theirs` auflösen, da wir sie selbst nicht editieren. --- @@ -243,7 +244,7 @@ Konflikte in Upstream-Sprach-Ressourcen (`Language..resx`) kommen häufig ## Projektstatus -**Version 0.3.1** | Stand: Mai 2026 +**Version 0.5.4** | Stand: 2026-05-03 Alle Bootstrap-Phasen abgeschlossen: @@ -298,4 +299,20 @@ Siehe [`AI_DISCLOSURE.md`](AI_DISCLOSURE.md) für die Pair-Level-Disclosure. --- +## Projekt-Dokumente + +| Dokument | Inhalt | +| --- | --- | +| [`PRIVACY.md`](PRIVACY.md) | Datenschutz-Übersicht: lokale Speicherung, Outbound-Calls, Telemetry-Status, DSGVO-Rechte und ihre Plugin-Entsprechungen. | +| [`SECURITY.md`](SECURITY.md) | Vulnerability-Reporting via Private Advisory, Scope und Disclosure-Fenster. | +| [`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md) | NuGet-Dependencies mit Lizenzen, Bundled Assets, Network-Status pro Komponente. | +| [`CONTRIBUTING.md`](CONTRIBUTING.md) | Was ich akzeptiere bzw. ablehne, Workflow, Build-Anleitung, EUPL-1.2-Bestätigung. | +| [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md) | Verhaltens-Erwartungen und Reporting-Pfad. | +| [`SUPPORT.md`](SUPPORT.md) | Wegweiser für Bugs, Security, Privacy, Quick-Questions. | +| [`UPSTREAM_SYNC.md`](UPSTREAM_SYNC.md) | Cherry-Pick-Policy gegenüber Chat 2. | +| [`NOTICE.md`](NOTICE.md) | Attribution an Upstream-Maintainer und Komponenten-Credits. | +| [`AI_DISCLOSURE.md`](AI_DISCLOSURE.md) | Offenlegung der KI-Unterstützung im Entwicklungsprozess. | + +--- + **Hellion Online Media** | Bad Harzburg | [hellion-media.de](https://hellion-media.de) diff --git a/SECURITY.md b/SECURITY.md index a9de120..0e1f4ac 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -12,7 +12,7 @@ through GitHub's Security Advisories. This routes the report directly to me and keeps the conversation off the public timeline. **Alternative:** -- Email: `maintainer@hellion-media.de` +- Email: `kontakt@hellion-media.de` - Discord: `@j.j_kazama` I respond on weekdays during European business hours. For urgent diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 0000000..612306f --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1,50 @@ +# Support + +HellionChat is a small hobby project maintained by one person. There +are a few different paths depending on what you need; please pick the +one that matches. + +## Bugs and feature requests + +GitHub issues, using the templates: + +- [Bug report](https://github.com/JonKazama-Hellion/HellionChat/issues/new?template=bug_report.yml) +- [Feature request](https://github.com/JonKazama-Hellion/HellionChat/issues/new?template=feature_request.yml) + +Please search [existing issues](https://github.com/JonKazama-Hellion/HellionChat/issues?q=is%3Aissue) +first. Duplicates get closed and pointed at the original. + +## Security + +Do **not** open a public issue for security-relevant findings. Use +the private advisory route described in [SECURITY.md](SECURITY.md): + +- [Private vulnerability advisory](https://github.com/JonKazama-Hellion/HellionChat/security/advisories/new) +- Email `kontakt@hellion-media.de` + +## Privacy questions + +Specific questions about what HellionChat does or does not store and +send are covered in [PRIVACY.md](PRIVACY.md). For follow-ups beyond +that document: + +- Email `kontakt@hellion-media.de` + +## Quick questions and casual feedback + +Discord DM `@j.j_kazama`. Bug reports still go through the issue +tracker so they can be tracked, but a quick "is this a bug or am I +holding it wrong" message is fine. + +## Upstream Chat 2 issues + +If the issue exists in upstream Chat 2 too, please report it at +[Infiziert90/ChatTwo](https://github.com/Infiziert90/ChatTwo/issues). +That keeps the original maintainers in the loop and helps everyone +who uses Chat 2 directly. + +## Response times + +Weekdays during European business hours. Weekends and FFXIV patch +days, replies will be slower. A few days of silence on a non-urgent +issue is normal; pinging once after a week is fine. diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md new file mode 100644 index 0000000..f7a8491 --- /dev/null +++ b/THIRD_PARTY_NOTICES.md @@ -0,0 +1,92 @@ +# Third-party notices + +HellionChat ships and depends on a number of third-party components. +This document lists them, their licences and which of them touch the +network. It is the inventory referenced by `PRIVACY.md`. + +Last reviewed: 2026-05-03 (HellionChat v0.5.4). + +--- + +## Direct NuGet dependencies + +Pinned in `ChatTwo/ChatTwo.csproj`. Versions reflect the v0.5.4 build. + +| Package | Version | Licence | Network | Purpose | +| --- | --- | --- | --- | --- | +| [MessagePack](https://github.com/MessagePack-CSharp/MessagePack-CSharp) | 3.1.4 | MIT | no | Binary serialisation for the SQLite message store. | +| [Microsoft.Data.Sqlite](https://learn.microsoft.com/dotnet/standard/data/sqlite/) | 10.0.7 | MIT | no | Local SQLite access for the message database. | +| [morelinq](https://github.com/morelinq/MoreLINQ) | 4.4.0 | Apache-2.0 | no | LINQ helper extensions. | +| [Pidgin](https://github.com/benjamin-hodgson/Pidgin) | 3.3.0 | MIT | no | Parser combinator library used for chat-input parsing. | +| [SixLabors.ImageSharp](https://github.com/SixLabors/ImageSharp) | 3.1.12 | [Six Labors Split License 1.0](https://github.com/SixLabors/ImageSharp/blob/main/LICENSE) (OSI-approved; free for open-source / non-commercial use, commercial licence required for closed-source commercial use) | no | Image decoding for cached emotes. | + +Six Labors note: HellionChat is an EUPL-1.2-licensed open-source +project distributed at no cost. Use of ImageSharp 3.x under the +Six Labors Split License 1.0 is permitted on that basis. Anyone +forking HellionChat for closed-source or commercial redistribution +should review the +[Six Labors licence terms](https://github.com/SixLabors/ImageSharp/blob/main/LICENSE) +and obtain a commercial licence if required. + +## SDK and tooling + +| Component | Licence | Notes | +| --- | --- | --- | +| [Dalamud.NET.Sdk](https://github.com/goatcorp/Dalamud) 15.0.0 | AGPL-3.0 (Dalamud) / SDK terms per goatcorp | Plugin SDK; pulls in DalamudPackager 15.0.0. | +| [.NET 10 SDK](https://dotnet.microsoft.com/) | MIT | Build toolchain. | + +## Bundled assets + +| Asset | Licence | Source | +| --- | --- | --- | +| Exo 2 (`HellionFont.ttf`) | SIL Open Font License 1.1 | [Google Fonts / Natanael Gama](https://fonts.google.com/specimen/Exo+2). The OFL licence text travels embedded next to the font (`HellionFont-OFL.txt`) to satisfy the "licence must be distributed with the font" clause. | +| Hellion plugin icon (`images/icon.png`) | © Hellion Media, included under the project licence (EUPL-1.2). | Original artwork. | + +--- + +## Upstream code + +HellionChat is a fork of [Chat 2](https://github.com/Infiziert90/ChatTwo) +by Infiziert90 (Infi) and Anna Clemens, also licensed under EUPL-1.2. +The bulk of the code, including the message store architecture, the +channel logic, the hook system and the ImGui chat window, originates +from upstream. See `NOTICE.md` and `UPSTREAM_SYNC.md` for the +attribution and the cherry-pick policy. + +--- + +## Components that touch the network + +Of everything listed above, **none** of the bundled or NuGet +components opens network connections on their own. All outbound +traffic is initiated explicitly by HellionChat's own source files +and is documented in `PRIVACY.md` under "Outbound network calls": + +- `ChatTwo/EmoteCache.cs` → BetterTTV API + CDN (opt-out via setting) +- `ChatTwo/FontManager.cs` → Square Enix Lodestone font CDN (one-time + download) + +--- + +## Verifying this list + +To regenerate the dependency inventory after a version bump: + +```bash +dotnet list ChatTwo.sln package --include-transitive +``` + +The "direct NuGet dependencies" table above only lists direct +references. Transitive dependencies pulled in by Dalamud SDK or by +the listed packages are covered by the SDK / package licences and +documented by their respective maintainers. + +To re-audit the network-call inventory: + +```bash +grep -rn -E "HttpClient|HttpRequest|new Uri\(|https?://" \ + --include="*.cs" ChatTwo/ +``` + +Any new hit that is not a click-through (`Util.OpenLink`) or a +payload-parsing call must be added to `PRIVACY.md` before release. diff --git a/crowdin.yml b/crowdin.yml deleted file mode 100644 index e7418ba..0000000 --- a/crowdin.yml +++ /dev/null @@ -1,13 +0,0 @@ -"project_id" : "663694" -"base_path" : "." -"base_url" : "https://api.crowdin.com" -"preserve_hierarchy": true - -files: [ - { - "source" : "/ChatTwo/Resources/Language.resx", - "translation" : "/ChatTwo/Resources/Language.%two_letters_code%.resx", - "dest" : "/Language.resx", - "skip_untranslated_strings": true, - } -]