菜单中文化: 全 UI 改中文, 加载微软雅黑字体 fallback, 扫描器消息中文化

This commit is contained in:
kedou 2026-08-05 22:19:49 +08:00
parent 71d89a6a06
commit c3e9737d20
3 changed files with 110 additions and 92 deletions

View File

@ -354,7 +354,7 @@ void CFramework::ScanRotationOffset()
if (!tarkov->IsInRaid() || local.m_address == 0)
{
strcpy_s(m_scanResult, "In Raid でのみスキャンできます (メニューを閉じて raid に入る)");
strcpy_s(m_scanResult, "仅限局内扫描 (先进 raid 再点)");
m_scanPhase = 0;
return;
}
@ -391,14 +391,14 @@ void CFramework::ScanRotationOffset()
if (s_cands.empty())
{
strcpy_s(m_scanResult, "候補が見つかりません。範囲を広げて再試行 (0x100-0x700)");
strcpy_s(m_scanResult, "未找到候选,请扩大扫描范围 (0x100-0x700)");
m_scanPhase = 0;
return;
}
m_scanPhase = 1;
snprintf(m_scanResult, sizeof(m_scanResult),
"Step1 OK: %zu candidates. マウスを水平に大きく回してから、もう一度ボタンを押す",
"第一步完成: %zu 个候选。水平转动鼠标后,再次点击",
s_cands.size());
}
else
@ -435,13 +435,13 @@ void CFramework::ScanRotationOffset()
g.g_AimRotOffset = (int)best.rotOff;
snprintf(m_scanResult, sizeof(m_scanResult),
"Found! Player+0x%X -> +0x%X (yaw delta %.2f rad). 適用済み。Offset.h にも書いて固定する事。",
"找到! Player+0x%X -> +0x%X (水平变化 %.2f 弧度)。已自动应用,建议写入 Offset.h 固定。",
(unsigned)best.mcOff, (unsigned)best.rotOff, bestDelta);
}
else
{
snprintf(m_scanResult, sizeof(m_scanResult),
"変化が小さい (max %.2f rad)。マウスを大きく回してもう一度。",
"变化过小 (最大 %.2f 弧度)。请更大幅度转动鼠标后重试。",
bestDelta);
}
}

View File

@ -1,11 +1,11 @@
#include "Framework.h"
// ImGui::Combo/ImGui::List等で使う文字列群
const char* BoxTypeList[] = { "Simple", "Cornered" };
const char* CrosshairList[] = { "Cross", "Circle" };
const char* AimMethodList[] = { "Memory", "Mouse" };
const char* AimBoneList[] = { "Head", "Neck", "Body" };
std::vector<const char*> MenuStringList = { "AimBot", "Visual", "Misc", "Setting" };
const char* BoxTypeList[] = { "简单", "棱角" };
const char* CrosshairList[] = { "十字", "圆圈" };
const char* AimMethodList[] = { "内存", "鼠标" };
const char* AimBoneList[] = { "头部", "颈部", "身体" };
std::vector<const char*> MenuStringList = { "自瞄", "视觉", "功能", "设置" };
std::vector<const char*> MenuIconList = { ICON_FA_CROSSHAIRS, ICON_FA_EYE, ICON_FA_BARS, ICON_FA_GEAR };
void CFramework::RenderMenu()
@ -15,7 +15,7 @@ void CFramework::RenderMenu()
ImGui::SetNextWindowBgAlpha(0.975f);
ImGui::SetNextWindowSize(ImVec2(725.f, 450.f));
ImGui::Begin("Tarkov PvE [ EXTERNAL ]", &g.ShowMenu, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
ImGui::Begin("塔科夫 PvE [ 外部辅助 ]", &g.ShowMenu, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
//---// Clild 0 //-----------------------------------//
ImGui::BeginChild("##SelectChild", ImVec2(150.f, ImGui::GetContentRegionAvail().y), false);
@ -49,79 +49,79 @@ void CFramework::RenderMenu()
case 0: // AimBot
ImGui::BeginChild("##C000", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y / 2.f), true);
ImGui::Text("AimBot (自瞄)");
ImGui::Text("自瞄");
ImGui::Separator();
ImGui::Spacing();
ImGui::Checkbox("Enable", &g.g_Aim);
ImGui::Combo("Method", &g.g_AimMethod, AimMethodList, IM_ARRAYSIZE(AimMethodList));
ImGui::CustomSliderFloat("FOV", "##AimFov", &g.g_AimFov, 10.f, 500.f);
ImGui::CustomSliderFloat("Smooth", "##AimSmooth", &g.g_AimSmooth, 0.f, 1.f);
ImGui::CustomSliderFloat("MaxDist", "##AimDist", &g.g_AimMaxDist, 50.f, 2000.f);
ImGui::Combo("Bone", &g.g_AimBone, AimBoneList, IM_ARRAYSIZE(AimBoneList));
ImGui::Checkbox("启用", &g.g_Aim);
ImGui::Combo("方式", &g.g_AimMethod, AimMethodList, IM_ARRAYSIZE(AimMethodList));
ImGui::CustomSliderFloat("锁定范围", "##AimFov", &g.g_AimFov, 10.f, 500.f);
ImGui::CustomSliderFloat("平滑", "##AimSmooth", &g.g_AimSmooth, 0.f, 1.f);
ImGui::CustomSliderFloat("最大距离", "##AimDist", &g.g_AimMaxDist, 50.f, 2000.f);
ImGui::Combo("瞄准部位", &g.g_AimBone, AimBoneList, IM_ARRAYSIZE(AimBoneList));
ImGui::EndChild();
ImGui::BeginChild("##C001", ImVec2(ImGui::GetContentRegionAvail()), true);
ImGui::Text("Mouse Mode");
ImGui::Text("鼠标模式");
ImGui::Separator();
ImGui::Spacing();
ImGui::CustomSliderFloat("Sens", "##AimSens", &g.g_AimSens, 0.1f, 5.f);
ImGui::CustomSliderFloat("MaxSpeed", "##AimMaxSpeed", &g.g_AimMaxSpeed, 1.f, 300.f);
ImGui::CustomSliderFloat("灵敏度", "##AimSens", &g.g_AimSens, 0.1f, 5.f);
ImGui::CustomSliderFloat("最大速度", "##AimMaxSpeed", &g.g_AimMaxSpeed, 1.f, 300.f);
ImGui::Separator();
ImGui::Spacing();
ImGui::Text("Recoil (压枪)");
ImGui::Text("压枪");
ImGui::Separator();
ImGui::Spacing();
ImGui::Checkbox("Enable", &g.g_Recoil);
ImGui::CustomSliderFloat("Strength", "##RecStr", &g.g_RecoilStrength, 0.f, 20.f);
ImGui::CustomSliderInt("Interval(ms)", "##RecInt", &g.g_RecoilInterval, 1, 100);
ImGui::Checkbox("启用", &g.g_Recoil);
ImGui::CustomSliderFloat("力度", "##RecStr", &g.g_RecoilStrength, 0.f, 20.f);
ImGui::CustomSliderInt("间隔(ms)", "##RecInt", &g.g_RecoilInterval, 1, 100);
ImGui::EndChild();
break;
case 1: // Visual
ImGui::BeginChild("##C010", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y / 3.f), true);
ImGui::Text("Visual");
ImGui::Text("视觉");
ImGui::Separator();
ImGui::Spacing();
ImGui::Checkbox("ESP", &g.g_ESP);
ImGui::Checkbox("Item ESP", &g.g_ESP_Item);
ImGui::Checkbox("Corpse ESP", &g.g_ESP_Item);
ImGui::Checkbox("Exfil ESP", &g.g_ESP_Exfil);
ImGui::Checkbox("Grenade ESP", &g.g_ESP_Grenade);
ImGui::Checkbox("物资ESP", &g.g_ESP_Item);
ImGui::Checkbox("尸体ESP", &g.g_ESP_Item);
ImGui::Checkbox("撤离点ESP", &g.g_ESP_Exfil);
ImGui::Checkbox("手雷ESP", &g.g_ESP_Grenade);
ImGui::EndChild();
ImGui::BeginChild("##C011", ImVec2(ImGui::GetContentRegionAvail()), true);
ImGui::Text("ESP Options");
ImGui::Text("ESP选项");
ImGui::Separator();
ImGui::Spacing();
ImGui::Checkbox("Line", &g.g_ESP_Line);
ImGui::Checkbox("Box", &g.g_ESP_Box);
ImGui::Checkbox("BoxFilled", &g.g_ESP_BoxFilled);
ImGui::Checkbox("Skeleton", &g.g_ESP_Skeleton);
ImGui::Checkbox("Distance", &g.g_ESP_Distance);
ImGui::Checkbox("Name", &g.g_ESP_Name);
ImGui::Checkbox("HealthBar", &g.g_ESP_HealthBar);
ImGui::Checkbox("连线", &g.g_ESP_Line);
ImGui::Checkbox("方框", &g.g_ESP_Box);
ImGui::Checkbox("填充方框", &g.g_ESP_BoxFilled);
ImGui::Checkbox("骨骼", &g.g_ESP_Skeleton);
ImGui::Checkbox("距离", &g.g_ESP_Distance);
ImGui::Checkbox("名称", &g.g_ESP_Name);
ImGui::Checkbox("血条", &g.g_ESP_HealthBar);
ImGui::EndChild();
break;
case 2: // Misc
ImGui::BeginChild("##C020", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y / 3.f), true);
ImGui::Text("Misc");
ImGui::Text("功能");
ImGui::Separator();
ImGui::Spacing();
ImGui::Checkbox("NoSway", &g.g_NoSway);
ImGui::Checkbox("Inf. Stamina", &g.g_InfStamina);
ImGui::Checkbox("No FallDamage", &g.g_NoFallDmg);
ImGui::Checkbox("无摆动", &g.g_NoSway);
ImGui::Checkbox("无限耐力", &g.g_InfStamina);
ImGui::Checkbox("无掉落伤害", &g.g_NoFallDmg);
ImGui::EndChild();
ImGui::BeginChild("##C021", ImVec2(ImGui::GetContentRegionAvail()), true);
@ -130,23 +130,23 @@ void CFramework::RenderMenu()
break;
case 3: // Setting
ImGui::BeginChild("##C030", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y / 3.f), true);
ImGui::Text("System");
ImGui::Text("系统");
ImGui::Separator();
ImGui::Spacing();
ImGui::Checkbox("StreamProof", &g.g_StreamProof);
ImGui::Checkbox("串流隐藏", &g.g_StreamProof);
ImGui::EndChild();
ImGui::BeginChild("##C031", ImVec2(ImGui::GetContentRegionAvail()), true);
ImGui::Text("Crosshair");
ImGui::Text("准星");
ImGui::Separator();
ImGui::Spacing();
ImGui::Checkbox("Crosshair", &g.g_Crosshair);
ImGui::CustomSliderInt("CrosshairSize", "##SizeCH", &g.g_CrosshairSize, 1, 10);
ImGui::ColorEdit4("Color##C", &CrosshairColor.Value.x);
ImGui::Combo("Type##C", &g.g_CrosshairType, CrosshairList, IM_ARRAYSIZE(CrosshairList));
ImGui::Checkbox("准星", &g.g_Crosshair);
ImGui::CustomSliderInt("准星大小", "##SizeCH", &g.g_CrosshairSize, 1, 10);
ImGui::ColorEdit4("颜色##C", &CrosshairColor.Value.x);
ImGui::Combo("类型##C", &g.g_CrosshairType, CrosshairList, IM_ARRAYSIZE(CrosshairList));
ImGui::EndChild();
break;
@ -171,38 +171,38 @@ void CFramework::RenderMenu()
case 0: // AimBot
ImGui::BeginChild("##C100", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y / 2.f), true);
ImGui::Text("Target Filter");
ImGui::Text("目标过滤");
ImGui::Separator();
ImGui::Spacing();
ImGui::Checkbox("PMC", &g.g_AimTargetPMC);
ImGui::Checkbox("Scav", &g.g_AimTargetScav);
ImGui::Checkbox("Boss", &g.g_AimTargetBoss);
ImGui::Checkbox("Ignore Health", &g.g_AimIgnoreHealth);
ImGui::Checkbox("Draw FOV", &g.g_AimDrawFov);
ImGui::Checkbox("Draw Target", &g.g_AimDrawTarget);
ImGui::Checkbox("SCAV", &g.g_AimTargetScav);
ImGui::Checkbox("BOSS", &g.g_AimTargetBoss);
ImGui::Checkbox("忽略血量", &g.g_AimIgnoreHealth);
ImGui::Checkbox("显示范围圈", &g.g_AimDrawFov);
ImGui::Checkbox("显示目标线", &g.g_AimDrawTarget);
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
// 数据链路状态: 哪一环断了看这里
ImGui::Text("Aim Status");
ImGui::Text("InRaid : %s", tarkov->IsInRaid() ? "YES" : "NO");
ImGui::Text("Local : 0x%llX", (unsigned long long)local.m_address);
ImGui::Text("Entity : %zu", GetEntityList().size());
ImGui::Text("Scan : %d ent / %d health / %d skip", m_diagTotal, m_diagHealth, m_diagSkipped);
ImGui::Text("Target : %s (d=%.0fpx)", m_diagBestAddr ? "LOCK" : "NONE", m_diagBestDist);
ImGui::Text("自瞄状态");
ImGui::Text("局内 : %s", tarkov->IsInRaid() ? "是" : "否");
ImGui::Text("本地 : 0x%llX", (unsigned long long)local.m_address);
ImGui::Text("实体 : %zu", GetEntityList().size());
ImGui::Text("扫描 : %d 实体 / %d 血量 / %d 跳过", m_diagTotal, m_diagHealth, m_diagSkipped);
ImGui::Text("目标 : %s (距 %0.fpx)", m_diagBestAddr ? "锁定" : "无", m_diagBestDist);
{
bool k0 = (GetAsyncKeyState(g.g_AimKey0) & 0x8000) != 0;
bool k1 = (GetAsyncKeyState(g.g_AimKey1) & 0x8000) != 0;
ImGui::Text("Key : %s", (k0 || k1) ? "HOLD" : "---");
ImGui::Text("按键 : %s", (k0 || k1) ? "按住" : "---");
}
ImGui::EndChild();
ImGui::BeginChild("##C101", ImVec2(ImGui::GetContentRegionAvail()), true);
ImGui::Text("Offset Debug (Memory)");
ImGui::Text("偏移调试(内存)");
ImGui::Separator();
ImGui::Spacing();
@ -212,40 +212,40 @@ void CFramework::RenderMenu()
if (mc)
{
Vector2 rot = m.Read<Vector2>(mc + (uintptr_t)g.g_AimRotOffset);
ImGui::Text("yaw : %.3f", rot.x);
ImGui::Text("pitch : %.3f", rot.y);
ImGui::TextDisabled("Move mouse to verify the offset");
ImGui::Text("水平 : %.3f", rot.x);
ImGui::Text("俯仰 : %.3f", rot.y);
ImGui::TextDisabled("移动鼠标验证偏移是否正确");
}
else
{
ImGui::TextDisabled("MC null (bad g_AimMcOffset?)");
ImGui::TextDisabled("MC 为空 (偏移错误?)");
}
}
else
{
ImGui::TextDisabled("In Raid のみ表示");
ImGui::TextDisabled("仅限局内显示");
}
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
ImGui::Text("Offset (hex)");
ImGui::Text("偏移(十六进制)");
ImGui::InputInt("MC", &g.g_AimMcOffset, 8, 8, ImGuiInputTextFlags_CharsHexadecimal);
ImGui::InputInt("Rot", &g.g_AimRotOffset, 4, 4, ImGuiInputTextFlags_CharsHexadecimal);
ImGui::InputInt("旋转", &g.g_AimRotOffset, 4, 4, ImGuiInputTextFlags_CharsHexadecimal);
// 误改输入框会直接导致 Memory 模式失效, 一键恢复默认
if (ImGui::Button("Reset MC/Rot (0x170/0x2C0)", ImVec2(ImGui::GetContentRegionAvail().x, 0.f)))
if (ImGui::Button("重置偏移 (0x170/0x2C0)", ImVec2(ImGui::GetContentRegionAvail().x, 0.f)))
{
g.g_AimMcOffset = 0x170;
g.g_AimRotOffset = 0x2C0;
}
if (ImGui::Button("Scan Rotation (2-step)", ImVec2(ImGui::GetContentRegionAvail().x, 0.f)))
if (ImGui::Button("扫描旋转偏移(两步)", ImVec2(ImGui::GetContentRegionAvail().x, 0.f)))
ScanRotationOffset();
if (m_scanPhase == 1)
ImGui::TextColored(TEXT_COLOR_ATTENTION.Value, "Now turn the mouse (yaw) then click again");
ImGui::TextColored(TEXT_COLOR_ATTENTION.Value, "水平转动鼠标后,再点一次扫描");
if (m_scanResult[0])
ImGui::TextWrapped("%s", m_scanResult);
@ -255,47 +255,47 @@ void CFramework::RenderMenu()
case 1: // Visual
ImGui::BeginChild("##C110", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y / 2.5f), true);
ImGui::Text("ESP Setting");
ImGui::Text("ESP设置");
ImGui::Separator();
ImGui::Spacing();
ImGui::CustomSliderFloat("Player", "##Dist", &g.g_ESP_MaxDistance, 100.f, 2000.f);
ImGui::CustomSliderFloat("Item", "##ItemDist", &g.g_ESP_MaxItemDistance, 10.f, 1000.f);
ImGui::CustomSliderFloat("玩家", "##Dist", &g.g_ESP_MaxDistance, 100.f, 2000.f);
ImGui::CustomSliderFloat("物资", "##ItemDist", &g.g_ESP_MaxItemDistance, 10.f, 1000.f);
ImGui::Spacing();
ImGui::Spacing();
ImGui::Combo("BoxType", &g.g_ESP_BoxStyle, BoxTypeList, IM_ARRAYSIZE(BoxTypeList));
ImGui::Combo("方框样式", &g.g_ESP_BoxStyle, BoxTypeList, IM_ARRAYSIZE(BoxTypeList));
ImGui::EndChild();
ImGui::BeginChild("##C111", ImVec2(ImGui::GetContentRegionAvail()), true);
ImGui::Text("ESP Colors");
ImGui::Text("ESP颜色");
ImGui::Separator();
ImGui::Spacing();
if (ImGui::TreeNode("Player/Scav"))
if (ImGui::TreeNode("玩家/SCAV"))
{
ImGui::ColorEdit4("PMC", &Col_ESP_PMC.Value.x);
ImGui::ColorEdit4("Scav", &Col_ESP_Scav.Value.x);
ImGui::ColorEdit4("P-Scav", &Col_ESP_pScav.Value.x);
ImGui::ColorEdit4("Scav++", &Col_ESP_SpecialScav.Value.x);
ImGui::ColorEdit4("Boss", &Col_ESP_Boss.Value.x);
ImGui::ColorEdit4("BoxFilled", &Col_ESP_Filled.Value.x);
ImGui::ColorEdit4("SCAV", &Col_ESP_Scav.Value.x);
ImGui::ColorEdit4("玩家SCAV", &Col_ESP_pScav.Value.x);
ImGui::ColorEdit4("精英SCAV", &Col_ESP_SpecialScav.Value.x);
ImGui::ColorEdit4("BOSS", &Col_ESP_Boss.Value.x);
ImGui::ColorEdit4("填充", &Col_ESP_Filled.Value.x);
ImGui::TreePop();
}
if (ImGui::TreeNode("Game"))
if (ImGui::TreeNode("游戏"))
{
ImGui::Text("[+] Item");
ImGui::ColorEdit4("Rare", &Col_ESP_RareItem.Value.x);
ImGui::Text("[+] 物资");
ImGui::ColorEdit4("稀有", &Col_ESP_RareItem.Value.x);
ImGui::NewLine();
ImGui::Spacing();
ImGui::Text("[+] Exfil");
ImGui::ColorEdit4("Open", &Col_ESP_ExfilOpen.Value.x);
ImGui::ColorEdit4("Close", &Col_ESP_ExfilClose.Value.x);
ImGui::Text("[+] 撤离点");
ImGui::ColorEdit4("开启", &Col_ESP_ExfilOpen.Value.x);
ImGui::ColorEdit4("关闭", &Col_ESP_ExfilClose.Value.x);
ImGui::TreePop();
}
@ -310,10 +310,10 @@ void CFramework::RenderMenu()
case 3: // Setting
ImGui::BeginChild("##C300", ImVec2(ImGui::GetContentRegionAvail()), true);
ImGui::Text("Exit");
ImGui::Text("退出");
ImGui::Separator();
ImGui::Spacing();
if (ImGui::Button("Exit", ImVec2(ImGui::GetContentRegionAvail().x, 30.f)))
if (ImGui::Button("退出", ImVec2(ImGui::GetContentRegionAvail().x, 30.f)))
g.process_active = false;
ImGui::EndChild();

View File

@ -59,12 +59,30 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
// Load Font
io.Fonts->AddFontFromMemoryCompressedTTF(RobotoRegular_compressed_data, RobotoRegular_compressed_size, 13.f, nullptr);
// 中文字体 fallback (微软雅黑, 菜单中文化用)
static const ImWchar cjk_ranges[] = { 0x4E00, 0x9FFF, 0 };
if (GetFileAttributesA("C:\\Windows\\Fonts\\msyh.ttc") != INVALID_FILE_ATTRIBUTES)
{
ImFontConfig cjk_config;
cjk_config.MergeMode = true;
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\msyh.ttc", 13.f, &cjk_config, io.Fonts->GetGlyphRangesChineseSimplifiedCommon());
}
// Load Icon
static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
ImFontConfig icons_config;
icons_config.MergeMode = true;
icons_config.GlyphOffset.y = 2.f;
cheat->icon = io.Fonts->AddFontFromMemoryCompressedTTF(FA_compressed_data, FA_compressed_size, 16.f, &icons_config, icons_ranges);
// 图标字体也挂中文 (菜单按钮是 icon 字体渲染)
if (GetFileAttributesA("C:\\Windows\\Fonts\\msyh.ttc") != INVALID_FILE_ATTRIBUTES)
{
ImFontConfig cjk_icon_config;
cjk_icon_config.MergeMode = true;
cjk_icon_config.GlyphOffset.y = 2.f;
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\msyh.ttc", 16.f, &cjk_icon_config, io.Fonts->GetGlyphRangesChineseSimplifiedCommon());
}
io.Fonts->Build();
// スレッドを作成