11094 Commits

Author SHA1 Message Date
fufesou
383a5c3478 feat: option, enable-privacy-mode & enable-perm-change-in-accept-window (#14875)
* feat: option, privacy mode

Signed-off-by: fufesou <linlong1266@gmail.com>

* feat(privacy mode): update libs/hbb_common

Signed-off-by: fufesou <linlong1266@gmail.com>

* feat(privacy mode): turn off on disable privacy mode

Signed-off-by: fufesou <linlong1266@gmail.com>

* feat(privacy mode): better check if supported

Signed-off-by: fufesou <linlong1266@gmail.com>

* feat(option): enable perm change in accept window

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2026-05-02 00:44:22 +08:00
orbisai0security
d4a1430c27 fix: V-002 security vulnerability (#14924)
Automated security fix generated by Orbis Security AI
2026-04-29 13:15:21 +08:00
KaneBarns
bfd31d21e4 Update build.py (#11341) 2026-04-28 15:08:10 +08:00
Amirhosein Akhlaghpoor
590296b297 fix: iPad mouse down detection for physical mouse input (#14515)
* fix: iPad mouse down detection

Signed-off-by: Amirhossein Akhlaghpour <m9.akhlaghpoor@gmail.com>

* fix(ipad): remove redundant check

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(ipad): Simple refactor

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: Amirhossein Akhlaghpour <m9.akhlaghpoor@gmail.com>
Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: fufesou <linlong1266@gmail.com>
2026-04-28 15:03:41 +08:00
eason
ee8cc0c06b fix(linux): prevent X11 BadWindow crash in get_focused_display (#14561)
* fix(linux): prevent X11 BadWindow crash in get_focused_display

When the active window is destroyed between xdo_get_active_window and
xdo_get_window_location/xdo_get_window_size calls, the default X11
error handler terminates the process with a BadWindow error. This
causes the rustdesk --server process to crash and the remote session
to disconnect and reconnect every time the user closes a window.

Install a custom X error handler around the xdo calls that catches
BadWindow errors and returns gracefully instead of crashing.

Fixes: https://github.com/rustdesk/rustdesk/issues/9003

Co-Authored-By: Claude (claude-opus-4-6) <noreply@anthropic.com>
Signed-off-by: easonysliu <easonysliu@tencent.com>

* fix(linux): prevent BadWindow crash in focus display lookup

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: easonysliu <easonysliu@tencent.com>
Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: easonysliu <easonysliu@tencent.com>
Co-authored-by: Claude (claude-opus-4-6) <noreply@anthropic.com>
Co-authored-by: fufesou <linlong1266@gmail.com>
2026-04-28 11:04:29 +08:00
s1korrrr
99b565ef40 fix(iOS): preserve local pasteboard sync from Windows hosts (#14659)
* fix(ios): accept windows clipboard updates locally

Signed-off-by: Rafal <mrsikorarafal@gmail.com>

* docs: document clipboard text helpers

* fix(iOS): sync clipboard, debug

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: Rafal <mrsikorarafal@gmail.com>
Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: fufesou <linlong1266@gmail.com>
2026-04-28 10:55:28 +08:00
fufesou
1e6a3dc644 fix(android): waiting for image, one cause (#14919)
Signed-off-by: fufesou <linlong1266@gmail.com>
2026-04-27 22:37:22 +08:00
s1korrrr
5b7ad339b8 fix(iPad): keep touch gestures with external mouse (#14652)
* fix(ipad): keep touch gestures with external mouse

Signed-off-by: Rafal <mrsikorarafal@gmail.com>

* fix(mobile): touch gesture on physical mouse connected

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(ipad): revert 9ee100b53e

keep touch gestures with external mouse

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(mobile): align view camera page with remote page

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: Rafal <mrsikorarafal@gmail.com>
Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: fufesou <linlong1266@gmail.com>
2026-04-27 19:44:35 +08:00
Sergiusz Michalik
7308c448f1 fix(client): serialize X11 keyboard grab and debounce focus feedback (#14836)
* fix(client): serialize X11 keyboard grab and debounce focus feedback

When two RustDesk sessions run fullscreen on separate monitors on
Linux/X11, keyboard input gets stuck on the wrong session or stops
working entirely. This happens because each Flutter isolate calls
change_grab_status concurrently, racing on KEYBOARD_HOOKED and the
rdev grab channel.

Additionally, XGrabKeyboard causes a focus-change feedback loop:
grab shifts focus away from the Flutter window, triggering PointerExit,
which releases the grab, restoring focus, triggering PointerEnter,
which re-grabs -- cycling at ~10 Hz and blocking keyboard input.

Fix by:
- Serializing grab transitions with a mutex and tracking the owning
  session (by lc.session_id), so a stale Wait from session A cannot
  clobber session B's freshly acquired grab.
- Debouncing Wait events (300 ms) from the same session that just
  acquired the grab, breaking the X11 focus feedback loop.
- Refreshing the debounce timer on idempotent Run calls (enterView
  while already owner), keeping the grab stable during normal use.

Signed-off-by: Sergiusz Michalik <github@latens.me>

* fix(client): add deferred release and dedup for debounced Wait

When a Wait is debounced (within 300ms of grab acquisition), schedule
a deferred release thread that re-checks after the debounce window.
If no new Run refreshed the grab, the deferred thread releases it,
ensuring a genuine leave within the debounce window is not lost.

Add a deferred_pending flag to GrabOwnerState to prevent spawning
redundant threads during the X11 focus feedback loop.

Signed-off-by: Sergiusz Michalik <github@latens.me>

* fix(client): use window-scoped ID and fix deferred-release re-arming

Address PR review feedback:
- Use per-window UUID instead of connection-scoped lc.session_id so two
  windows viewing the same peer get distinct grab owners
- Reset deferred_pending on both idempotent Run refresh and owner
  handoff, so a subsequent Wait can always spawn a fresh timer
- Replace manual Default impl with derive

* fix(client): recover from poisoned mutex instead of panicking

* docs: clarify cross-platform rationale for GrabOwnerState

* fix(client): only clear deferred_pending when timer snapshot matches

* fix(client): use full u128 window ID, downgrade grab logs to debug

- Widen GrabOwnerState.owner to u128 to avoid theoretical collision
  from truncating a 128-bit UUID to 64 bits
- Downgrade all grab transition log::info! to log::debug! to reduce
  log noise during routine window switches
- Clear deferred_pending on post-debounce release path to maintain
  the "deferred_pending => timer in flight" invariant

* fix(client): gate GRAB_DEBOUNCE_MS with cfg(target_os = "linux")

* fix(grab): release grabbed keys without clobbering new owner state

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(keyboard): Simple refactor

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: Sergiusz Michalik <github@latens.me>
Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: fufesou <linlong1266@gmail.com>
2026-04-26 22:46:41 +08:00
Amirhosein Akhlaghpoor
c8ba99d1a1 flutter: shift after one shot IME capitalization (#14695)
* flutter: shift after one shot IME capitalization

Signed-off-by: Amirhossein Akhlaghpour <m9.akhlaghpoor@gmail.com>

* flutter: clarify stale mobile shift handling

Signed-off-by: Amirhossein Akhlaghpour <m9.akhlaghpoor@gmail.com>

* fix(android): gboard shift stuck

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(android): gboard shift stuck, remove unused param

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(android): gboard shift stuck, release shift before sending events

Signed-off-by: fufesou <linlong1266@gmail.com>

* chore(flutter): document stale mobile shift release flow

Signed-off-by: Amirhossein Akhlaghpour <m9.akhlaghpoor@gmail.com>

---------

Signed-off-by: Amirhossein Akhlaghpour <m9.akhlaghpoor@gmail.com>
Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: fufesou <linlong1266@gmail.com>
2026-04-26 22:44:26 +08:00
Azhar
5ea6714db8 Fix: replace unwrap() with proper error handling in CLI password prompt (#14910)
Signed-off-by: bunnysayzz <stfuazzo@gmail.com>
2026-04-26 21:28:05 +08:00
fufesou
3a1622e8b5 refact(AGENTS.md): code rules, tokio (#14911)
* refact(AGENTS.md): code rules, tokio

Signed-off-by: fufesou <linlong1266@gmail.com>

* Update AGENTS.md

* Update AGENTS.md

* Update AGENTS.md

* Update AGENTS.md

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>
2026-04-26 21:25:31 +08:00
Sergiusz Michalik
38f1300717 fix(linux): enable mouse side buttons in remote sessions (#14848)
* fix(linux): enable mouse side buttons in remote sessions

Flutter's Linux embedder never delivers X11 button 8/9 (back/forward)
events to Dart, so mouse side buttons were silently dropped in remote
sessions.

Intercept these buttons at the GDK level via button-press/release-event
handlers on all windows (main + sub-windows) and forward them through
a dedicated platform channel to the active InputModel session.

Also add a defensive XSetPointerMapping call during enigo init to
extend the X11 core pointer button map to 9 buttons on servers where
it is smaller (e.g. minimal X server configurations).

* fix: address review feedback for side button support

- Use XOpenDisplay/XCloseDisplay instead of reading Display* from
  xdo_t's private struct layout at offset 0 (fragile ABI assumption)
- Track side button down ownership per button via a Map instead of a
  single slot, preventing cross-button mismatch on overlapping presses

* fix: gate side buttons on view-only and fix teardown

- Skip side button events in view-only sessions (consistent with
  other mouse entry points)
- Release held side buttons on session close to avoid stuck buttons
  on the remote
- Drop unpaired 'up' events instead of falling back to the active
  model, which could send to the wrong session

* docs: add clarifying comments from review feedback

- Note global scope of XSetPointerMapping and that it runs once
  via lazy_static singleton
- Clarify sub-window callback is safe on X11-only builds
- Document per-isolate design of initSideButtonChannel

* fix: replace broken XSetPointerMapping with diagnostic check

XSetPointerMapping requires the length to match XGetPointerMapping's
return value - it cannot extend the button count. The previous code
would trigger a BadValue X error on servers with fewer than 9 buttons.

Replace with a diagnostic-only check that logs whether the core
pointer has enough buttons for side button simulation. RustDesk's
uinput "Mouse passthrough" device already provides the needed buttons
in practice.

Also add .catchError to fire-and-forget side button releases during
session teardown to prevent unhandled async errors.

* fix: ensure side button releases bypass permission checks

If permissions change between button down and up (e.g. keyboardPerm
revoked, view-only toggled), sendMouse's early return would suppress
the release, leaving a stuck button on the remote.

Add _sendMouseUnchecked that bypasses permission checks, used for:
- Side button 'up' events (matching a recorded 'down')
- Forced releases during session teardown

Gate all permission checks (isViewOnly, keyboardPerm, isViewCamera)
at the 'down' entry point before recording in _sideButtonDownModels.

* fix: add NULL guards and avoid blocking platform channel handler

- Add NULL checks for FL_VIEW cast and channel creation in
  on_subwindow_created (review feedback from fufesou)
- Use fire-and-forget (unawaited) for _sendMouseUnchecked calls
  inside the platform channel handler to avoid blocking platform
  messages when sessionSendMouse is slow (review feedback from Copilot)

* fix: remove circular import and skip X11 check on Wayland

- Move initSideButtonChannel() call from initEnv() in main.dart to
  the InputModel constructor, removing the circular import between
  main.dart and input_model.dart
- Skip check_x11_button_map() when DISPLAY is not set to avoid
  noisy warnings on pure Wayland environments
2026-04-25 12:46:05 +08:00
Nawer
03e351ac61 feat(i18n): Complete and fix french translations (#14890) 2026-04-24 18:38:34 +08:00
fufesou
6cb323725b fix(sicter): control side, privacy mode (#14880)
Signed-off-by: fufesou <linlong1266@gmail.com>
2026-04-24 14:35:58 +08:00
Aliaksandr Kliujeŭ
5d0533f0d4 Update Balarusian strings (#14842)
* Update Balarusian strings

* BE: fix typos

* BE: fix ў-related typos
2026-04-23 23:52:43 +08:00
Re*Index. (ot_inc)
e0c5e1483e Update Japanese translate (#14838)
* Update ja.rs

* Update ja.rs

* Fix typo
2026-04-23 23:52:21 +08:00
Leo Louis
47e4c65d8e Update print statement from 'Hello' to 'Goodbye' (#14754) 2026-04-22 18:06:37 +08:00
Leo Louis
9bc1ce52af Add Malayalam language support (#14753)
* Add Malayalam language support

* Fix syntax error in language list for Malayalam

---------

Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>
2026-04-22 18:06:10 +08:00
Leo Louis
348d1b46e1 Add Hindi language support with translations (#14746)
* Add Hindi language support with translations

* Update print statement from 'Hello' to 'Goodbye'
2026-04-22 18:04:37 +08:00
Leo Louis
1a41b3ac11 Add Hindi language module and translation support (#14745)
Co-authored-by: RustDesk <71636191+rustdesk@users.noreply.github.com>
2026-04-22 18:04:09 +08:00
rustdesk
b239535009 refactor per code review 2026-04-22 01:41:13 +08:00
RustDesk
5fd20f808c fix safari-oidc https://github.com/rustdesk/rustdesk/issues/14861 (#14867) 2026-04-22 01:29:15 +08:00
rustdesk
803ac8cc4e save cargo build size 2026-04-21 17:34:05 +08:00
John Eismeier
4a50bc6fc2 Propose fix some typos (#14857)
Signed-off-by: John E <jeis4wpi@outlook.com>
2026-04-21 16:27:39 +08:00
fufesou
e8a1b7fe21 fix: build (#14846)
Signed-off-by: fufesou <linlong1266@gmail.com>
2026-04-20 10:05:32 +08:00
21pages
ac124c0680 flutter: improve address book pull error handling (#14813)
* flutter: improve address book pull error handling

Summary:
  - Show error messages when fetching the address book list fails.
  - After the initial fetch, switching back to the AB tab no longer re-fetches it, even if an error occurred or the error banner was dismissed.

  Tested:
  - Self-hosted server:
    - normal
    - 403 responses
    - legacy address book mode
  - Public server
  - Verified that switching tabs no longer re-fetches AB after the initial fetch, regardless of whether an error occurred or the error banner was cleared.

Signed-off-by: 21pages <sunboeasy@gmail.com>

* use resp.statusCode in address book json decoding

Signed-off-by: 21pages <sunboeasy@gmail.com>

* flutter: clear address book list errors on reset

Signed-off-by: 21pages <sunboeasy@gmail.com>

* flutter: clear address book pull errors consistently

Signed-off-by: 21pages <sunboeasy@gmail.com>

---------

Signed-off-by: 21pages <sunboeasy@gmail.com>
2026-04-18 11:19:32 +08:00
Luca-rickrolled-himself
91aff3ffd1 Complete and correct Romanian (ro) translations (#14837)
* Complete and correct Romanian (ro) translations

- Fill in all previously empty translation strings
- Fix plural form: "fișier" → "fișiere" (files)
- Fix "Receive" → "Primește" (was incorrectly using "Acceptă")
- Fix "Too frequent" → "Prea frecvent" (removed erroneous extra word)
- Fix "Note" → "Notă" (was translated as verb instead of noun)
- Fix "Use both passwords" → "Folosește ambele parole" ("programe" typo)
- Fix "Automatically record incoming sessions" → "sesiunile primite" (not "viitoare")
- Fix typo "neautoriztă" → "neautorizată" (Connection not allowed)
- Fix typo "dispozivul" → "dispozitivul" (Restart remote device)
- Fix leading whitespace in "Username" translation
- Fix "FPS" → keep as "FPS" (was incorrectly translated as "CPS")
- Fix "Forget Password" → "Parolă uitată" (command form was grammatically wrong)

* Fix typo in Romanian translation for accessibility tip

* unify informal register and fix subjunctive typo
2026-04-18 10:55:18 +08:00
John Fowler
642c281ad0 Update hu.rs (#14816)
New string translation and fixes.
2026-04-17 12:44:24 +08:00
fufesou
1e9c4d04f1 fix(mobile): deeplink, disable by default (#14824)
Signed-off-by: fufesou <linlong1266@gmail.com>
2026-04-16 23:21:14 +08:00
21pages
9f817714fe fix(client): stop retrying on restricted mobile access errors (#14797)
Treat "Access to mobile devices is restricted in your country"
  as a non-retriable connection error so the error dialog does not
  trigger reconnect attempts.

Signed-off-by: 21pages <sunboeasy@gmail.com>
2026-04-15 21:40:03 +08:00
pallab-js
091f2c6135 impl(cm): implement change_theme and change_language callbacks (#14782)
* docs: fix typos in documentation and code comments

- Fix 'seperated' -> 'separated' in remote_input.dart
- Fix 'seperators' -> 'separators' in fuse/cs.rs
- Update outdated 'OSX' -> 'macOS' in virtual display README

Signed-off-by: pallab-js <sonowalpallabjyoti@gmail.com>

* impl(cm): implement change_theme and change_language callbacks

These callbacks were previously empty TODO stubs.
Now they properly invoke the Sciter UI handlers to notify
the UI when theme or language changes occur.

Signed-off-by: pallab-js <sonowalpallabjyoti@gmail.com>

---------

Signed-off-by: pallab-js <sonowalpallabjyoti@gmail.com>
2026-04-15 17:35:51 +08:00
rustdesk
91de51290d add microsoft oidc logo 2026-04-15 14:39:46 +08:00
rustdesk
68fa0466c8 improved oidc login error 2026-04-15 14:36:03 +08:00
Leo Louis
28e303576c Add support for Gujarati language in lang.rs (#14751) 2026-04-14 14:21:27 +08:00
Leo Louis
2d41b3e80d Add Gujarati language support with translations (#14752) 2026-04-14 14:21:10 +08:00
Andrzej Rudnik
ffd2d26c1a Update pl.rs (#14775) 2026-04-14 14:20:35 +08:00
Leo Louis
a8dc6fc632 Fix capture method return type in Recorder trait (#14748) 2026-04-13 13:04:43 +08:00
Leo Louis
771cb4ebd7 Update capture function return type for PixelProvider (#14747) 2026-04-13 13:03:35 +08:00
fufesou
2f694c0eb2 fix: file transfer, path traversal (#14678)
* fix: file transfer, path traversal

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): remove stale files

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): update_folder_files() after set_files()

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): reduce .clone()

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): undo checking "done message for unkown id"

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): refactor

1. Hide `files` in `new_write()`.
2. Use `set_files()` to validate `files` before writing.

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): comments

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): Remove redundant checks

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(fs): update hbb_common

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2026-04-10 18:00:11 +08:00
21pages
8dea347a21 add brute-force protection for one-time password (#14682)
* add brute-force protection for temporary password

  Rotate the temporary password after repeated failed login attempts
  within one minute, and reset the failure window after successful
  authentication.

Signed-off-by: 21pages <sunboeasy@gmail.com>

* replace LazyLock with lazy_static

Signed-off-by: 21pages <sunboeasy@gmail.com>

* read temporary password after locking failure state

Signed-off-by: 21pages <sunboeasy@gmail.com>

* server: rotate temporary passwords after 10 consecutive failures

Signed-off-by: 21pages <sunboeasy@gmail.com>

* server: clarify temporary password failure counter comment

Signed-off-by: 21pages <sunboeasy@gmail.com>

---------

Signed-off-by: 21pages <sunboeasy@gmail.com>
2026-04-09 17:14:21 +08:00
rustdesk
0cf3e8ed40 improve agent md 2026-04-09 15:12:57 +08:00
21pages
9d3bc7d9e6 fix switch sides for macOS peers (#14661)
Signed-off-by: 21pages <sunboeasy@gmail.com>
2026-04-07 23:39:24 +08:00
🌐 Qusai ALBahri 🌱
e0427bdc77 Translate UI strings to Arabic in ar.rs (#14694) 2026-04-06 18:27:14 +08:00
fufesou
9cf1338dc4 fix(win): exe icon path (#14686)
* fix(win): exe icon path

Signed-off-by: fufesou <linlong1266@gmail.com>

* fix(win): Simple refactor

Signed-off-by: fufesou <linlong1266@gmail.com>

---------

Signed-off-by: fufesou <linlong1266@gmail.com>
2026-04-04 22:54:13 +08:00
RustDesk
4e30ee8d1c tcp proxy (#14633)
* tcp proxy

* fix per review

* fix per review

* Suppress secure_tcp info logs for TCP proxy requests

Signed-off-by: 21pages <sunboeasy@gmail.com>

* copilot review: redact tcp proxy logs, dedupe headers, and avoid body clone

Signed-off-by: 21pages <sunboeasy@gmail.com>

* format common.rs

Signed-off-by: 21pages <sunboeasy@gmail.com>

* copilot review: test function name

Signed-off-by: 21pages <sunboeasy@gmail.com>

* copilot review: format IPv6 tcp proxy log targets correctly

Signed-off-by: 21pages <sunboeasy@gmail.com>

* copilot review: normalize HTTP method before direct request dispatch

Signed-off-by: 21pages <sunboeasy@gmail.com>

* review: extract fallback helper, fix Content-Type override, add overall timeout

- Extract duplicated TCP proxy fallback logic into generic
  `with_tcp_proxy_fallback` helper used by both `post_request` and
  `http_request_sync`, eliminating code drift risk
- Allow caller-supplied Content-Type to override the default in
  `parse_simple_header` instead of silently dropping it
- Take body by reference in `post_request_http` to avoid eager clone
  when no fallback is needed
- Wrap entire `tcp_proxy_request` flow (connect + handshake + send +
  receive) in an overall timeout to prevent indefinite stalls

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* review: make is_public case-insensitive and cover mixed-case rustdesk URLs

Signed-off-by: 21pages <sunboeasy@gmail.com>

* oidc: route auth requests through shared HTTP/tcp-proxy path while keeping TLS warmup

Signed-off-by: 21pages <sunboeasy@gmail.com>

* refactor: replace unused TryFrom<Response> with HbbHttpResponse::parse method

  Remove TryFrom<Response> impl that was never called and replace the
  private parse_hbb_http_response helper in account.rs with a public
  parse() method on HbbHttpResponse, eliminating code duplication.

Signed-off-by: 21pages <sunboeasy@gmail.com>

---------

Signed-off-by: 21pages <sunboeasy@gmail.com>
Co-authored-by: 21pages <sunboeasy@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 23:13:05 +08:00
Alex Rijckaert
cca6a5fe12 Update Dutch translations (#14654) 2026-04-01 18:10:39 +08:00
VenusGirl❤
9e4b7fca4d Update Korean (#14644) 2026-03-31 21:34:35 +08:00
XLion
d135c58ead Update tw.rs (#14643) 2026-03-31 21:26:00 +08:00
Mr-Update
de194417d4 Update de.rs (#14640) 2026-03-31 21:25:05 +08:00