diff --git a/dot.sln.DotSettings b/dot.sln.DotSettings
index 24a4bdd..e0c09a2 100644
--- a/dot.sln.DotSettings
+++ b/dot.sln.DotSettings
@@ -1,8 +1,4 @@
- True
- True
- True
- True
False
1
1
@@ -16,7 +12,6 @@
<Policy Inspect="True" Prefix="_" Suffix="" Style="AA_BB" />
<Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" />
<Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
-
<?xml version="1.0" encoding="utf-16"?>
<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
<TypePattern>
@@ -57,5 +52,4 @@
</Entry>
</TypePattern>
</Patterns>
-
\ No newline at end of file
diff --git a/src/Color/MouseHook.cs b/src/Color/MouseHook.cs
deleted file mode 100644
index 0d410f5..0000000
--- a/src/Color/MouseHook.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-// ReSharper disable ClassNeverInstantiated.Global
-
-#if NET7_0_WINDOWS
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-
-namespace Dot.Color;
-
-internal sealed class MouseHook : IDisposable
-{
- private const int _WH_MOUSE_LL = 14;
- private const int _WM_LBUTTONDOWN = 0x0201;
- private const int _WM_MOUSEMOVE = 0x0200;
- private readonly nint _hookId;
- private bool _disposed;
-
- public MouseHook()
- {
- _hookId = SetHook(HookCallback);
- }
-
- ~MouseHook()
- {
- Dispose(false);
- }
-
- public event MouseEventHandler MouseEvent;
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- private static nint SetHook(Func proc)
- {
- using var curProcess = Process.GetCurrentProcess();
- using var curModule = curProcess.MainModule!;
- return Win32.SetWindowsHookEx(_WH_MOUSE_LL, proc, Win32.GetModuleHandle(curModule.ModuleName), 0);
- }
-
- private void Dispose(bool disposing)
- {
- if (_disposed) {
- return;
- }
-
- if (disposing) {
- //
- }
-
- if (_hookId != default) {
- Win32.UnhookWindowsHookEx(_hookId);
- }
-
- _disposed = true;
- }
-
- private nint HookCallback(int nCode, nint wParam, nint lParam)
- {
- if (nCode < 0 || (wParam != _WM_MOUSEMOVE && wParam != _WM_LBUTTONDOWN)) {
- return Win32.CallNextHookEx(_hookId, nCode, wParam, lParam);
- }
-
- var hookStruct = (Msllhookstruct)Marshal.PtrToStructure(lParam, typeof(Msllhookstruct))!;
- MouseEvent?.Invoke(null, new MouseEventArgs( //
- wParam == _WM_MOUSEMOVE ? MouseButtons.None : MouseButtons.Left //
- , 0 //
- , hookStruct.X //
- , hookStruct.Y //
- , 0));
- return Win32.CallNextHookEx(_hookId, nCode, wParam, lParam);
- }
-
- [StructLayout(LayoutKind.Explicit)]
- private readonly struct Msllhookstruct
- {
- [FieldOffset(0)] public readonly int X;
- [FieldOffset(4)] public readonly int Y;
- }
-}
-#endif
\ No newline at end of file
diff --git a/src/Color/WinMain.cs b/src/Color/WinMain.cs
index 78dfe70..82c5d76 100644
--- a/src/Color/WinMain.cs
+++ b/src/Color/WinMain.cs
@@ -1,6 +1,7 @@
#if NET7_0_WINDOWS
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
+using Dot.Native;
using TextCopy;
namespace Dot.Color;
diff --git a/src/Native/MouseHook.cs b/src/Native/MouseHook.cs
new file mode 100644
index 0000000..15a8d57
--- /dev/null
+++ b/src/Native/MouseHook.cs
@@ -0,0 +1,73 @@
+// ReSharper disable ClassNeverInstantiated.Global
+
+#if NET7_0_WINDOWS
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace Dot.Native;
+
+internal sealed class MouseHook : IDisposable
+{
+ private readonly nint _hookId;
+ private bool _disposed;
+
+ public MouseHook()
+ {
+ _hookId = SetHook(HookCallback);
+ }
+
+ ~MouseHook()
+ {
+ Dispose(false);
+ }
+
+ public event MouseEventHandler MouseMoveEvent;
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private static nint SetHook(Win32.HookProc lpfn)
+ {
+ using var process = Process.GetCurrentProcess();
+ using var module = process.MainModule;
+ return Win32.SetWindowsHookExA(Win32.WH_MOUSE_LL, lpfn, module!.BaseAddress, 0);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (_disposed) {
+ return;
+ }
+
+ if (disposing) {
+ //
+ }
+
+ if (_hookId != default) {
+ Win32.UnhookWindowsHookExA(_hookId);
+ }
+
+ _disposed = true;
+ }
+
+ private nint HookCallback(int nCode, nint wParam, nint lParam)
+ {
+ if (wParam == Win32.WM_MOUSEMOVE) {
+ var hookStruct = (Msllhookstruct)Marshal.PtrToStructure(lParam, typeof(Msllhookstruct))!;
+ MouseMoveEvent?.Invoke(null, new MouseEventArgs(MouseButtons.None, 0, hookStruct.X, hookStruct.Y, 0));
+ }
+
+ return Win32.CallNextHookEx(_hookId, nCode, wParam, lParam);
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ private readonly struct Msllhookstruct
+ {
+ [FieldOffset(0)] public readonly int X;
+ [FieldOffset(4)] public readonly int Y;
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/Win32.cs b/src/Native/Win32.cs
similarity index 65%
rename from src/Win32.cs
rename to src/Native/Win32.cs
index c9b6e6a..3f91e6c 100644
--- a/src/Win32.cs
+++ b/src/Native/Win32.cs
@@ -3,17 +3,23 @@
using System.Runtime.InteropServices;
-namespace Dot;
+namespace Dot.Native;
internal static partial class Win32
{
- public const int SW_HIDE = 0;
- public const int WM_CHANGECBCHAIN = 0x030D;
- public const int WM_DRAWCLIPBOARD = 0x308;
+ public const int CS_DROP_SHADOW = 0x20000;
+ public const int GCL_STYLE = -26;
+ public const int SW_HIDE = 0;
+ public const int WH_MOUSE_LL = 14;
+ public const int WM_CHANGECBCHAIN = 0x030D;
+ public const int WM_DRAWCLIPBOARD = 0x308;
+ public const int WM_LBUTTONDOWN = 0x0201;
+ public const int WM_MOUSEMOVE = 0x0200;
+ private const string _GDI32_DLL = "gdi32.dll";
+ private const string _KERNEL32_DLL = "kernel32.dll";
+ private const string _USER32_DLL = "user32.dll";
- private const string _GDI32_DLL = "gdi32.dll";
- private const string _KERNEL32_DLL = "kernel32.dll";
- private const string _USER32_DLL = "user32.dll";
+ public delegate nint HookProc(int nCode, nint wParam, nint lParam);
[LibraryImport(_USER32_DLL)]
internal static partial nint CallNextHookEx(nint hhk, int nCode, nint wParam, nint lParam);
@@ -22,6 +28,9 @@ internal static partial class Win32
[return: MarshalAs(UnmanagedType.Bool)]
internal static partial bool ChangeClipboardChain(nint hWndRemove, nint hWndNewNext);
+ [LibraryImport(_USER32_DLL)]
+ internal static partial int GetClassLongA(nint hWnd, int nIndex);
+
[LibraryImport(_KERNEL32_DLL)]
internal static partial nint GetConsoleWindow();
@@ -29,7 +38,7 @@ internal static partial class Win32
internal static partial nint GetDesktopWindow();
[LibraryImport(_KERNEL32_DLL, StringMarshalling = StringMarshalling.Utf16)]
- internal static partial nint GetModuleHandle(string lpModuleName);
+ internal static partial nint GetModuleHandleA(string lpModuleName);
[LibraryImport(_GDI32_DLL)]
internal static partial uint GetPixel(nint dc, int x, int y);
@@ -43,6 +52,9 @@ internal static partial class Win32
[LibraryImport(_USER32_DLL)]
internal static partial int SendMessageA(nint hwnd, uint wMsg, nint wParam, nint lParam);
+ [LibraryImport(_USER32_DLL)]
+ internal static partial int SetClassLongA(nint hWnd, int nIndex, int dwNewLong);
+
[LibraryImport(_USER32_DLL)]
internal static partial int SetClipboardViewer(nint hWnd);
@@ -50,8 +62,7 @@ internal static partial class Win32
internal static partial void SetLocalTime(Systemtime st);
[LibraryImport(_USER32_DLL)]
- internal static partial nint SetWindowsHookEx(int idHook, Func lpfn, nint hMod
- , uint dwThreadId);
+ internal static partial nint SetWindowsHookExA(int idHook, HookProc lpfn, nint hMod, uint dwThreadId);
[LibraryImport(_USER32_DLL)]
[return: MarshalAs(UnmanagedType.Bool)]
@@ -59,7 +70,7 @@ internal static partial class Win32
[LibraryImport(_USER32_DLL)]
[return: MarshalAs(UnmanagedType.Bool)]
- internal static partial bool UnhookWindowsHookEx(nint hhk);
+ internal static partial bool UnhookWindowsHookExA(nint hhk);
[StructLayout(LayoutKind.Explicit)]
internal ref struct Systemtime
diff --git a/src/Time/Main.cs b/src/Time/Main.cs
index dace916..e224413 100644
--- a/src/Time/Main.cs
+++ b/src/Time/Main.cs
@@ -1,6 +1,7 @@
// ReSharper disable ClassNeverInstantiated.Global
using System.Net.Sockets;
+using Dot.Native;
namespace Dot.Time;
diff --git a/src/Tran/BaiduSignCracker.cs b/src/Tran/BaiduSignCracker.cs
new file mode 100644
index 0000000..6f90da0
--- /dev/null
+++ b/src/Tran/BaiduSignCracker.cs
@@ -0,0 +1,60 @@
+using NSExt.Extensions;
+
+namespace Dot.Tran;
+
+internal static class BaiduSignCracker
+{
+ private const int _MAGIC_NUMBER_1 = 320305;
+ private const int _MAGIC_NUMBER_2 = 131321201;
+
+ public static string Sign(string text)
+ {
+ var e = new List(text.Length);
+ for (var i = 0; i < text.Length; i++) {
+ var k = (int)text[i];
+ switch (k) {
+ case < 128:
+ e.Add(k);
+ break;
+ case < 2048:
+ e.Add((k >> 6) | 192);
+ break;
+ default: {
+ if ((k & 64512) == 55296 && i + 1 < text.Length && (text[i + 1] & 64512) == 56320) {
+ k = 65536 + ((k & 1023) << 10) + (text[++i] & 1023);
+ e.Add((k >> 18) | 240);
+ e.Add(((k >> 12) & 63) | 128);
+ }
+ else {
+ e.Add((k >> 12) | 224);
+ e.Add(((k >> 6) & 63) | 128);
+ e.Add((k & 63) | 128);
+ }
+
+ break;
+ }
+ }
+ }
+
+ var ret = e.Aggregate(_MAGIC_NUMBER_1, (accumulator, source) => Compute(accumulator + source, "+-a^+6"));
+ ret = Compute(ret, "+-3^+b+-f");
+ ret ^= _MAGIC_NUMBER_2;
+ var longRet = ret < 0 ? 1L + (ret & int.MaxValue) + int.MaxValue : ret;
+ longRet %= 1_000_000;
+ return $"{longRet}.{longRet ^ _MAGIC_NUMBER_1}";
+ }
+
+ private static int Compute(int number, string password)
+ {
+ unchecked {
+ for (var i = 0; i < password.Length - 2; i += 3) {
+ var c = password[i + 2];
+ var moveBit = c >= 'a' ? c - 87 : c.ToString().Int32();
+ var d = password[i + 1] == '+' ? number >>> moveBit : number << moveBit;
+ number = password[i] == '+' ? (number + d) & (int)uint.MaxValue : number ^ d;
+ }
+ }
+
+ return number;
+ }
+}
\ No newline at end of file
diff --git a/src/Tran/Dto/BaiduTranslateResultDto.cs b/src/Tran/Dto/BaiduTranslateResultDto.cs
new file mode 100644
index 0000000..da1031f
--- /dev/null
+++ b/src/Tran/Dto/BaiduTranslateResultDto.cs
@@ -0,0 +1,62 @@
+// ReSharper disable InconsistentNaming
+// ReSharper disable ClassNeverInstantiated.Global
+
+#pragma warning disable IDE1006,SA1300
+namespace Dot.Tran.Dto;
+
+internal sealed record BaiduTranslateResultDto
+{
+ public sealed record DataItem
+ {
+ public string dst { get; set; }
+
+ public int prefixWrap { get; set; }
+
+ public string result { get; set; }
+
+ public string src { get; set; }
+ }
+
+ public sealed record PhoneticItem
+ {
+ public string src_str { get; set; }
+
+ public string trg_str { get; set; }
+ }
+
+ public sealed record Root
+ {
+ public string errmsg { get; set; }
+
+ public int errno { get; set; }
+
+ public int error { get; set; }
+
+ public string errShowMsg { get; set; }
+
+ public string from { get; set; }
+
+ public long logid { get; set; }
+
+ public string query { get; set; }
+
+ public string to { get; set; }
+
+ public Trans_result trans_result { get; set; }
+ }
+
+ public sealed record Trans_result
+ {
+ public List data { get; set; }
+
+ public string from { get; set; }
+
+ public List phonetic { get; set; }
+
+ public int status { get; set; }
+
+ public string to { get; set; }
+
+ public int type { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Tran/FrmMain.cs b/src/Tran/FrmMain.cs
index b164407..f8b9365 100644
--- a/src/Tran/FrmMain.cs
+++ b/src/Tran/FrmMain.cs
@@ -1,37 +1,38 @@
#if NET7_0_WINDOWS
+using System.Net;
+using System.Text.RegularExpressions;
+using Dot.Native;
+using Dot.Tran.Dto;
using NSExt.Extensions;
-using Colors = System.Drawing.Color;
-using Padding = System.Windows.Forms.Padding;
+using TextCopy;
using Size = System.Drawing.Size;
namespace Dot.Tran;
-internal sealed class FrmMain : Form
+internal sealed partial class FrmMain : Form
{
- private const int _HIDING_MIL_SECS = 1000; // 鼠标离开超过此时间后隐藏窗体
- private const string _TOKEN_URL = "https://fanyi.qq.com/api/reauth12f";
- private const string _URL = "https://fanyi.qq.com/api/translate";
- private static ManualResetEvent _mre = new(false); // 隐藏窗体侦测线程信号
+ private const int _HIDING_MIL_SECS = 5000; // 隐藏窗体时间(秒
+ private const int _RETRY_WAIT_MIL_SEC = 1000; // 重试等待时间(秒)
+ private const string _TRANSLATE_API_URL = "https://fanyi.baidu.com/v2transapi";
+ private const string _TRANSLATE_HOME_URL = "https://fanyi.baidu.com";
+ private const double _WINDOW_OPACITY = .5; // 窗体透明度
+ private static ManualResetEvent _mre = new(false); // 隐藏窗体侦测线程信号
+ private readonly HttpClient _httpClient = new();
+ private readonly Label _labelDest = new(); // 显示翻译内容的文本框
- private readonly Colors _bgColor // 背景颜色
- = Colors.FromArgb(0xff, 0x1e, 0x1e, 0x1e);
-
- private readonly Colors _foreColor = Colors.White; // 字体颜色
-
- private readonly HttpClient _httpClient = new();
- private readonly RichTextBox _richTextSource = new(); // 显示剪贴板内容的富文本框
- private readonly TextBox _textDest = new(); // 显示翻译内容的文本框
- private readonly Padding _windowPadding = new(10, 10, 10, 10); // 窗体边距
- private readonly Size _windowSize = new(640, 360); // 窗体大小
- private DateTime? _mouseLeaveTime; // 鼠标离开窗体时间
- private nint _nextHwnd; // 下一个剪贴板监视链对象句柄
+ private readonly MouseHook _mouseHook = new();
+ private readonly Size _mouseMargin = new(10, 10);
+ private bool _disposed;
+ private DateTime? _latestActiveTime; // 窗体最后激活时间
+ private nint _nextHwnd; // 下一个剪贴板监视链对象句柄
+ private string _token = "ae72ebad4113270fd26ada5125301268";
public FrmMain()
{
InitForm();
-
- InitTextSource();
- InitTextDest();
+ InitHook();
+ InitLabelDest();
+ InitHttpClient();
_nextHwnd = Win32.SetClipboardViewer(Handle);
@@ -40,35 +41,27 @@ internal sealed class FrmMain : Form
~FrmMain()
{
- _mre?.Dispose();
- _richTextSource?.Dispose();
+ Dispose(false);
}
- protected override void OnClosed(EventArgs e)
+ protected override void Dispose(bool disposing)
{
- base.OnClosed(e);
+ base.Dispose(disposing);
- // 结束定时隐藏窗体线程
- _mre = null;
-
- // 从剪贴板监视链移除本窗体
- Win32.ChangeClipboardChain(Handle, _nextHwnd);
- }
-
- protected override void OnMouseEnter(EventArgs e)
- {
- base.OnMouseEnter(e);
- _mouseLeaveTime = null;
- }
-
- protected override void OnMouseLeave(EventArgs e)
- {
- base.OnMouseLeave(e);
- if (ClientRectangle.Contains(PointToClient(MousePosition))) {
+ if (_disposed) {
return;
}
- _mouseLeaveTime = DateTime.Now;
+ if (disposing) {
+ _mre = null; // 结束定时隐藏窗体线程
+ _mre?.Dispose();
+ _httpClient?.Dispose();
+ _labelDest?.Dispose();
+ _mouseHook?.Dispose();
+ }
+
+ Win32.ChangeClipboardChain(Handle, _nextHwnd); // 从剪贴板监视链移除本窗体
+ _disposed = true;
}
protected override void WndProc(ref Message m)
@@ -84,6 +77,7 @@ internal sealed class FrmMain : Form
SendToNext(m);
break;
case Win32.WM_CHANGECBCHAIN:
+ Console.WriteLine(Win32.WM_CHANGECBCHAIN);
if (m.WParam == _nextHwnd) {
_nextHwnd = m.LParam;
}
@@ -98,61 +92,44 @@ internal sealed class FrmMain : Form
}
}
+ [GeneratedRegex("token: '(\\w+)'")]
+ private static partial Regex MyRegex();
+
///
/// 显示剪贴板内容.
///
private void DisplayClipboardData()
{
- var clipData = Clipboard.GetDataObject();
- if (clipData is null) {
+ var clipText = ClipboardService.GetText();
+ if (clipText.NullOrWhiteSpace()) {
return;
}
- if (clipData.GetDataPresent(DataFormats.Rtf)) {
- _richTextSource.Rtf = clipData.GetData(DataFormats.Rtf) as string;
- }
- else if (clipData.GetDataPresent(DataFormats.Text)) {
- _richTextSource.Text = clipData.GetData(DataFormats.Text) as string;
- }
- else {
- return;
- }
+ _labelDest.Text = Str.Translating;
+ Task.Run(() => {
+ var translateText = _labelDest.Text = TranslateText(clipText);
+ Invoke(() => { _labelDest.Text = translateText; });
+ });
- var mousePos = Cursor.Position;
- mousePos.Offset(-_windowPadding.Left, -_windowPadding.Top);
- Location = mousePos;
- Visible = true;
- _mouseLeaveTime = null;
+ var point = Cursor.Position;
+ point.Offset(new Point(_mouseMargin));
+ Location = point;
+ Show();
+ _latestActiveTime = DateTime.Now;
_mre.Set();
}
- private TokenStruct GetTranslateToken()
- {
- using var rsp = _httpClient.PostAsync(_TOKEN_URL, new StringContent(string.Empty)).Result;
- var rspStr = rsp.Content.ReadAsStringAsync().Result;
- return rspStr.Object();
- }
-
- private int HalfHeight()
- {
- return (_windowSize.Height - _windowPadding.Top - _windowPadding.Bottom) / 2 - _windowPadding.Top / 2;
- }
-
private async Task HideWindow()
{
while (_mre is not null) {
while (Visible) {
await Task.Delay(100);
- if (_mouseLeaveTime is null ||
- !((DateTime.Now - _mouseLeaveTime.Value).TotalMilliseconds > _HIDING_MIL_SECS)) {
+ if (_latestActiveTime is null ||
+ !((DateTime.Now - _latestActiveTime.Value).TotalMilliseconds > _HIDING_MIL_SECS)) {
continue;
}
- Invoke(() => {
- Visible = false;
- _richTextSource.Clear();
- _textDest.Clear();
- });
+ Invoke(Hide);
}
_mre.WaitOne();
@@ -161,73 +138,74 @@ internal sealed class FrmMain : Form
private void InitForm()
{
- BackColor = _bgColor;
+ AutoSize = true;
+ AutoSizeMode = AutoSizeMode.GrowAndShrink;
FormBorderStyle = FormBorderStyle.None;
- Padding = _windowPadding;
- Size = _windowSize;
+ Opacity = _WINDOW_OPACITY;
TopMost = true;
Visible = false;
}
- private void InitTextDest()
+ private void InitHook()
{
- _textDest.BackColor = _bgColor;
- _textDest.BorderStyle = BorderStyle.None;
- _textDest.Dock = DockStyle.Bottom;
- _textDest.ForeColor = _foreColor;
- _textDest.Height = HalfHeight();
- _textDest.Margin = new Padding(0, _windowPadding.Top / 2, 0, 0);
- _textDest.MouseEnter += (_, e) => OnMouseEnter(e);
- _textDest.Multiline = true;
- _textDest.ScrollBars = ScrollBars.None;
- Controls.Add(_textDest);
+ _mouseHook.MouseMoveEvent += (_, e) => {
+ var point = new Point(e.X, e.Y);
+ point.Offset(new Point(_mouseMargin));
+ Location = point;
+ };
}
- private void InitTextSource()
+ private void InitHttpClient()
{
- _richTextSource.TextChanged += (sender, e) => {
- if (_richTextSource.Text.NullOrWhiteSpace()) {
- return;
- }
+ _httpClient.DefaultRequestHeaders.Add( //
+ "User-Agent"
+ , " Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36");
+ }
- _textDest.Text = Str.Translating;
- _textDest.Text = TranslateText(_richTextSource.Text);
- };
- _richTextSource.BackColor = _bgColor;
- _richTextSource.BorderStyle = BorderStyle.None;
- _richTextSource.Dock = DockStyle.Top;
- _richTextSource.ForeColor = _foreColor;
- _richTextSource.Height = HalfHeight();
- _richTextSource.Margin = new Padding(0, 0, 0, _windowPadding.Top / 2);
- _richTextSource.MouseEnter += (_, e) => OnMouseEnter(e);
- _richTextSource.ScrollBars = RichTextBoxScrollBars.None;
- Controls.Add(_richTextSource);
+ private void InitLabelDest()
+ {
+ _labelDest.BorderStyle = BorderStyle.None;
+ _labelDest.Dock = DockStyle.Fill;
+ _labelDest.AutoSize = true;
+ Controls.Add(_labelDest);
}
private string TranslateText(string sourceText)
{
- var token = GetTranslateToken();
- var content = new FormUrlEncodedContent(new List> {
- new("source", "auto")
- , new("target", "zh")
- , new("qtv", token.Qtv.Url())
- , new("qtk", token.Qtk.Url())
- , new("sourceText", sourceText.Url())
- });
- var rsp = _httpClient.PostAsync(_URL, content).Result;
- var ret = rsp.Content.ReadAsStringAsync().Result;
+ while (true) {
+ var hash = sourceText.Length > 30
+ ? string.Concat(sourceText.AsSpan()[..10], sourceText.AsSpan(sourceText.Length / 2 - 5, 10)
+ , sourceText.AsSpan()[^10..])
+ : sourceText;
+ var sign = BaiduSignCracker.Sign(hash);
+ var content = new FormUrlEncodedContent(new List> {
+ new("from", "auto")
+ , new("to", "zh")
+ , new("query", sourceText)
+ , new("simple_means_flag", "3")
+ , new("sign", sign)
+ , new("token", _token)
+ , new("domain", "common")
+ });
- return ret;
- }
+ var rsp = _httpClient.PostAsync(_TRANSLATE_API_URL, content).Result;
+ var rspObj = rsp.Content.ReadAsStringAsync().Result.Object();
+ if (rspObj.error == 0) {
+ return string.Join(Environment.NewLine, rspObj.trans_result.data.Select(x => x.dst));
+ }
- private readonly struct TokenStruct
- {
- // ReSharper disable UnusedAutoPropertyAccessor.Local
- public string Qtk { get; init; }
+ Console.Error.WriteLine(rspObj.Json().UnicodeDe());
+ Console.Error.WriteLine(rsp.Headers.Json());
- public string Qtv { get; init; }
-
- // ReSharper restore UnusedAutoPropertyAccessor.Local
+ //cookie or token invalid
+ Task.Delay(_RETRY_WAIT_MIL_SEC).Wait();
+ var cookie = string.Join(
+ ';', rsp.Headers.First(x => x.Key == "Set-Cookie").Value.Select(x => x.Split(';').First()));
+ _httpClient.DefaultRequestHeaders.Remove(nameof(Cookie));
+ _httpClient.DefaultRequestHeaders.Add(nameof(Cookie), cookie);
+ var html = _httpClient.GetStringAsync(_TRANSLATE_HOME_URL).Result;
+ _token = MyRegex().Match(html).Groups[1].Value;
+ }
}
}
#endif
\ No newline at end of file
diff --git a/src/Tran/Main.cs b/src/Tran/Main.cs
index e4713e5..a00f763 100644
--- a/src/Tran/Main.cs
+++ b/src/Tran/Main.cs
@@ -9,7 +9,10 @@ internal sealed class Main : ToolBase