Skip to content

Fix translate: working default backend, settings UI, outgoing translation - #206

Open
MaikCZE wants to merge 3 commits into
TaterClient:master_newfrom
MaikCZE:translate-fixes-v2
Open

Fix translate: working default backend, settings UI, outgoing translation#206
MaikCZE wants to merge 3 commits into
TaterClient:master_newfrom
MaikCZE:translate-fixes-v2

Conversation

@MaikCZE

@MaikCZE MaikCZE commented Aug 17, 2026

Copy link
Copy Markdown

Summary

Follow-up to #203, rebased onto master_new and addressing every point from SollyBunny's review there:

  • The translate feature (translate.cpp) had no settings UI at all (config-var only), no way to translate your own outgoing messages, and its default backend was silently dead (ftapi.pythonanywhere.com now 404s to a generic placeholder page).
  • Adds a working google backend (talks directly to the same free, unofficial Google Translate endpoint FTApi used to wrap), a full Translate section in the settings menu, and outgoing-message translation.

Changes since #203

  • Google backend now POSTs in the body, not the URL query string (application/x-www-form-urlencoded) -- keeps CHttpRequest::m_aUrl's fixed 256-byte buffer well within bounds regardless of message length, instead of risking truncation on a long chat message.
  • Removed the FreeTranslateAPI (ftapi) backend entirely -- its hosting is gone, and anyone wanting a self-hosted option already has the LibreTranslate backend. Removed its stale "hosting is dead" comment and its ftapi-specific auto-translate guard along with it.
  • No more duplicated backend names: g_aTranslateBackends[] (translate.h/.cpp) is now the single source of truth for each backend's config value + display name, used by both CreateTranslateBackend() dispatch and the settings-menu dropdown -- the dropdown previously hardcoded its own copy of these strings.
  • No more magic-number English fallback: TranslateLanguageIndex() finds English by comparing language codes instead of a hardcoded return 5, so it stays correct regardless of how a language list is edited/reordered.
  • Language dropdowns are backend-scoped: Google and LibreTranslate now have their own language lists (g_aTranslateBackends[i].m_pLanguages) instead of one shared list, since Google genuinely supports far more languages than a typical self-hosted LibreTranslate instance.
  • chat.cpp diff reduced to one line: outgoing translation is now CTranslate::ChatDoTranslateOutgoing(), returning bool and chained as another else if alongside ChatDoBinds/ChatDoSpecId instead of a separate nested if/else block.
  • Simplified the "too many jobs in flight" comment that read oddly in the original PR.

Test plan

  • Compiled clean with MSVC 19.51 (Release, Ninja) -- full DDNet.exe build, zero errors/warnings from any touched file
  • Rebased cleanly onto master_new (cherry-picked with no conflicts)
  • Would appreciate a look at the Google endpoint-in-body change specifically, since I can't independently confirm the endpoint accepts POST the same way it accepts GET query params

Supersedes #203.

🤖 Generated with Claude Code

…orking default backend

- FreeTranslateAPI's hosting (ftapi.pythonanywhere.com) is defunct, so the
  default backend never worked. Add a new "google" backend that talks
  directly to the free, unofficial Google Translate endpoint FTAPI itself
  used to wrap, and make it the default.
- Add a full Translate section to the TClient settings menu (previously the
  feature was config-var only, with no UI at all): backend/language
  dropdowns, incoming auto-translate toggle, and a LibreTranslate
  endpoint/key section shown only when relevant.
- Add outgoing translation: optionally translate your own messages into
  another language before sending, via a new tc_translate_outgoing /
  tc_translate_outgoing_target config pair and CTranslate::TranslateOutgoing().
  Falls back to sending the original text if translation fails, and skips
  "/"-prefixed messages so it doesn't mangle commands like /w.
Rebased onto master_new (per SollyBunny's review) and addressed every
requested change from the original review:

- Google backend now POSTs client/target-language/text in the request
  body (application/x-www-form-urlencoded) instead of building a long
  query-string URL -- keeps the fixed 256-byte CHttpRequest::m_aUrl
  buffer well within bounds regardless of message length.
- Removed the FreeTranslateAPI (ftapi) backend entirely, including its
  stale "hosting is dead" comment and its ftapi-specific auto-translate
  guard -- anyone who wants a self-hosted option already has
  LibreTranslate.
- Backend display names are no longer duplicated between the backend
  classes and the settings-menu dropdown: each backend exposes a
  StaticName()/StaticValue(), and a single g_aTranslateBackends[] table
  (translate.h/.cpp) is now the one source of truth for both dispatch
  and the menu.
- Removed the magic-number English fallback (previously a hardcoded
  `return 5`): TranslateLanguageIndex() now finds English by comparing
  language codes, so it stays correct regardless of list order/edits.
- Language dropdowns are now backend-scoped instead of one shared list
  for every backend, since Google genuinely supports far more languages
  than a typical self-hosted LibreTranslate instance.
- Outgoing-translate is now CTranslate::ChatDoTranslateOutgoing(), which
  returns bool and is chained as another `else if` in chat.cpp's
  ChatDoBinds/ChatDoSpecId cascade instead of a separate nested
  if/else block -- matches the existing pattern and keeps the chat.cpp
  diff to one line.
- Simplified the "too many jobs in flight" comment that read oddly
  (dropped the "don't make the player wait"/game-vs-chat phrasing).

Compiled clean with MSVC 19.51 (Release, Ninja) -- full DDNet.exe
build, zero errors/warnings from the touched files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

@SollyBunny SollyBunny left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dislike the large number of globals and separate vars for arrays and the size
I suggest:

  1. Keeping g_aTranslateBackends, but using inlining g_NumTranslateBackends
  2. Move the values from the individual classes to this array (so the classes no longer hold it)
  3. Change the language list to be std::vectors

Check style is failing (run scripts/fix_style.py), and also check other CI when it completes

- g_aTranslateBackends stays a fixed array (std::array<STranslateBackendInfo, 2>),
  but the separate g_NumTranslateBackends variable is gone -- callers use
  g_aTranslateBackends.size() directly.
- Backend display name/value no longer live in the individual backend
  classes (removed StaticName()/StaticValue()/the Name() overrides) --
  ITranslateBackend now takes its name once at construction, sourced from
  the matching g_aTranslateBackends entry, so the array is the only place
  that data exists.
- Both language lists (Google, LibreTranslate) are now std::vector<STranslateLanguage>
  instead of raw C arrays, matching STranslateBackendInfo::m_vLanguages.
- Ran scripts/fix_style.py (clang-format 20) to fix check-style -- also
  picked up one pre-existing, unrelated style violation in chat.cpp's
  AddLine() (regex chat-ignore lambda) since formatting runs per-file.

check-clang-tidy's remaining failures (mumble.h, discord.cpp, client.cpp,
menus_start.cpp, menus_settings.cpp) are pre-existing on master_new itself
(confirmed via its own most recent check-runs) and untouched by this PR --
out of scope here.

Rebuilt clean with MSVC 19.51 (Release, Ninja), zero errors/warnings.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@MaikCZE

MaikCZE commented Aug 18, 2026

Copy link
Copy Markdown
Author

Addressed all three points from the review, plus check-style:

  1. g_aTranslateBackends stays as-is (now std::array<STranslateBackendInfo, 2>); g_NumTranslateBackends is gone, callers use g_aTranslateBackends.size() directly.
  2. Backend name/value no longer live in the individual classes -- removed StaticName()/StaticValue()/the Name() overrides. ITranslateBackend now takes its name once at construction (sourced from the matching g_aTranslateBackends entry via CreateTranslateBackend()), so the array is the single place that data exists.
  3. Both language lists are now std::vector<STranslateLanguage> (STranslateBackendInfo::m_vLanguages), not raw C arrays.

check-style: ran scripts/fix_style.py (clang-format 20) -- also picked up one pre-existing, unrelated style issue in chat.cpp's AddLine() (regex chat-ignore lambda) since formatting runs per-file, not per-diff-line.

check-clang-tidy's remaining failures (mumble.h, discord.cpp, client.cpp, menus_start.cpp, menus_settings.cpp) are pre-existing on master_new itself -- confirmed via master_new's own most recent check-runs already showing check-clang-tidy failing, and none of those files are touched by this PR. Left alone as out of scope here.

Rebuilt clean with MSVC 19.51 (Release, Ninja) after each change, zero errors/warnings.

🤖 Addressed by Claude Code

@SollyBunny

Copy link
Copy Markdown
Collaborator

This looks good to me, but I still need to test it #208

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants