Skip to content

Commit 9d6d187

Browse files
committed
translate?
1 parent 48112dd commit 9d6d187

File tree

5 files changed

+25000
-13
lines changed

5 files changed

+25000
-13
lines changed

hooks/Chat.cpp

+62-13
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,72 @@ void dChatController_AddChat(ChatController* __this, PlayerControl* sourcePlayer
3434
auto player = GetPlayerData(sourcePlayer);
3535
auto local = GetPlayerData(*Game::pLocalPlayer);
3636
std::string message = RemoveHtmlTags(convert_from_string(chatText));
37-
if (State.ReadGhostMessages) {
38-
bool wasDead = false;
39-
40-
if (player != NULL && player->fields.IsDead && local != NULL && !local->fields.IsDead) {
41-
local->fields.IsDead = true;
42-
wasDead = true;
43-
}
37+
if (State.ReadGhostMessages && (player != NULL && player->fields.IsDead && local != NULL && !local->fields.IsDead)) {
38+
local->fields.IsDead = true;
4439
ChatController_AddChat(__this, sourcePlayer, chatText, censor, method);
40+
local->fields.IsDead = false;
41+
}
42+
else ChatController_AddChat(__this, sourcePlayer, chatText, censor, method);
43+
44+
if (!State.translatePlayers.empty()) {
45+
if (IsInGame()) State.rpcQueue.push(new RpcTranslateMessage(RemoveHtmlTags(convert_from_string(NetworkedPlayerInfo_get_PlayerName(player, NULL))), message));
46+
if (IsInLobby()) State.lobbyRpcQueue.push(new RpcTranslateMessage(RemoveHtmlTags(convert_from_string(NetworkedPlayerInfo_get_PlayerName(player, NULL))), message));
47+
}
4548

46-
std::string playerName = convert_from_string(NetworkedPlayerInfo_get_PlayerName(player, nullptr));
47-
auto outfit = GetPlayerOutfit(player);
48-
uint32_t colorId = outfit->fields.ColorId;
49-
if (wasDead) {
50-
local->fields.IsDead = false;
49+
try {
50+
if (message.rfind("/reg ", 0) == 0) {
51+
if (message == "/reg trans clear") {
52+
State.translatePlayers.erase(convert_from_string(player->fields.FriendCode));
53+
} else if (message.rfind("/reg trans ", 0) == 0) {
54+
auto friendCode = convert_from_string(player->fields.FriendCode);
55+
std::stringstream ss;
56+
ss << message.substr(11);
57+
std::string t;
58+
ss >> t;
59+
std::string fromlang = t;
60+
ss >> t;
61+
std::string tolang = t;
62+
auto findt = State.translatePlayers.find(friendCode);
63+
if (findt != State.translatePlayers.end()) {
64+
findt->second.first = fromlang;
65+
findt->second.second = tolang;
66+
} else {
67+
std::pair<std::string, std::string> p = std::make_pair(fromlang, tolang);
68+
State.translatePlayers.emplace(friendCode, p);
69+
}
70+
}
71+
else if (sourcePlayer == (*Game::pLocalPlayer)) {
72+
if (message.rfind("/reg trans-for clear ", 0) == 0) {
73+
std::stringstream ss;
74+
ss << message.substr(21);
75+
std::string t;
76+
ss >> t;
77+
std::string friendCode = t;
78+
State.translatePlayers.erase(friendCode);
79+
} else if (message.rfind("/reg trans-for ", 0) == 0) {
80+
std::stringstream ss;
81+
ss << message.substr(15);
82+
std::string t;
83+
ss >> t;
84+
std::string friendCode = t;
85+
ss >> t;
86+
std::string fromlang = t;
87+
ss >> t;
88+
std::string tolang = t;
89+
auto findt = State.translatePlayers.find(friendCode);
90+
if (findt != State.translatePlayers.end()) {
91+
findt->second.first = fromlang;
92+
findt->second.second = tolang;
93+
} else {
94+
std::pair<std::string, std::string> p = std::make_pair(fromlang, tolang);
95+
State.translatePlayers.emplace(friendCode, p);
96+
}
97+
}
98+
}
5199
}
100+
} catch (...) {
52101
}
53-
else ChatController_AddChat(__this, sourcePlayer, chatText, censor, method);
102+
54103
if (State.Enable_SMAC) {
55104
if (State.SMAC_CheckChat && ((IsInGame() && !State.InMeeting && !player->fields.IsDead) || chatText->fields.m_stringLength > 120)) {
56105
SMAC_OnCheatDetected(sourcePlayer, "Abnormal Chat");

rpc/RpcSnapTo.cpp

+152
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
#include "pch-il2cpp.h"
22
#include "_rpc.h"
33
#include "game.h"
4+
#include "state.hpp"
5+
#include "json.hpp"
6+
#include <stdio.h>
7+
#include <queue>
8+
#include <future>
9+
#include <codecvt>
10+
#include <windows.h>
411

512
RpcSnapTo::RpcSnapTo(Vector2 targetVector)
613
{
@@ -68,3 +75,148 @@ void RpcGoneForTarget::Process()
6875
}
6976
}
7077
}
78+
79+
RpcTranslateMessage::RpcTranslateMessage(PlayerSelection sourcePlayer, std::string source, std::string message)
80+
{
81+
this->sourcePlayer = sourcePlayer;
82+
this->source = source;
83+
this->message = message;
84+
}
85+
86+
std::string UTF8ToGBK(const std::string& utf8Data)
87+
{
88+
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
89+
std::wstring wString = conv.from_bytes(utf8Data); // utf-8 => wstring
90+
91+
std::wstring_convert<std::codecvt< wchar_t, char, std::mbstate_t>>
92+
convert(new std::codecvt< wchar_t, char, std::mbstate_t>("CHS"));
93+
std::string str = convert.to_bytes(wString); // wstring => string
94+
95+
return str;
96+
}
97+
98+
int translate_from_deeplx(PlayerSelection target, std::string source, std::string message, std::string sourcelang, std::string targetlang)
99+
{
100+
try {
101+
nlohmann::json j = {
102+
{"text", message},
103+
{"source_lang", sourcelang},
104+
{"target_lang", targetlang}
105+
};
106+
std::string prefix = "curl -X POST http://localhost:1188/translate -H \"Content-Type: application/json\" -d ";
107+
std::ostringstream o;
108+
o << "\"";
109+
std::string s = j.dump();
110+
for (auto c = s.cbegin(); c != s.cend(); c++) {
111+
switch (*c) {
112+
case '\\': o << "\\\\"; break;
113+
case '"': o << "\\\""; break;
114+
default: o << *c;
115+
}
116+
}
117+
o << "\"";
118+
prefix += o.str();
119+
FILE *fp = NULL;
120+
char buf[1024];
121+
char result[33000] = {0};
122+
auto console = GetConsoleWindow();
123+
if (console == NULL) {
124+
AllocConsole();
125+
console = GetConsoleWindow();
126+
}
127+
ShowWindow(console, SW_HIDE);
128+
if ((fp = _popen(UTF8ToGBK(prefix).c_str(), "r")) != NULL) {
129+
while (fgets(buf, 1024, fp) != NULL) {
130+
strcat_s(result, 33000, buf);
131+
}
132+
_pclose(fp);
133+
fp = NULL;
134+
}
135+
LOG_ERROR("Translate 0");
136+
if (!target.validate().has_value()) return 0;
137+
auto j2 = nlohmann::json::parse(result);
138+
if (j2.find("code") == j2.end()) return 0;
139+
auto code = j2.at("code");
140+
LOG_ERROR("Translate 1");
141+
if (code.is_number_integer() && 200 == code.get<int>()) {
142+
if (j2.find("data") == j2.end()) return 0;
143+
auto data = j2.at("data");
144+
if (data.is_string()) {
145+
LOG_ERROR("Translate 2");
146+
std::string translated = data.get<std::string>();
147+
if (translated == message) {
148+
LOG_ERROR("Translate duplicated");
149+
return 0;
150+
}
151+
std::queue<RPCInterface*>* queue = nullptr;
152+
if (IsInGame())
153+
queue = &State.rpcQueue;
154+
else if (IsInLobby())
155+
queue = &State.lobbyRpcQueue;
156+
else return 0;
157+
queue->push(new RpcTranslatedMessage(target, source, translated));
158+
LOG_ERROR("Translated ok");
159+
}
160+
}
161+
} catch (...) {
162+
LOG_ERROR("Translate error");
163+
}
164+
return 0;
165+
}
166+
167+
static std::queue<std::shared_ptr<std::future<int>>> asyncQueue;
168+
169+
void RpcTranslateMessage::Process()
170+
{
171+
while (!asyncQueue.empty()) {
172+
std::shared_ptr<std::future<int>> task = asyncQueue.front();
173+
if (!task->valid()) {
174+
asyncQueue.pop();
175+
task.reset();
176+
} else {
177+
break;
178+
}
179+
}
180+
for (auto p : GetAllPlayerControl()) {
181+
if (sourcePlayer.validate().has_value() && p == sourcePlayer.validate().get_PlayerControl()) continue;
182+
auto friendCode = convert_from_string(GetPlayerData(p)->fields.FriendCode);
183+
auto search = State.translatePlayers.find(friendCode);
184+
if (search == State.translatePlayers.end()) continue;
185+
std::string fromlang = search->second.first;
186+
std::string tolang = search->second.second;
187+
asyncQueue.push(std::make_shared<std::future<int>>(std::async(std::launch::async, translate_from_deeplx, PlayerSelection(p), source, message, fromlang, tolang)));
188+
}
189+
}
190+
191+
RpcTranslatedMessage::RpcTranslatedMessage(PlayerSelection target, std::string source, std::string message)
192+
{
193+
this->target = target;
194+
this->source = source;
195+
this->message = message;
196+
}
197+
198+
void RpcTranslatedMessage::Process()
199+
{
200+
if (!target.validate().has_value()) return;
201+
std::string finalmessage = "Translated from =" + source + "=: \n" + message;
202+
if (target.validate().get_PlayerControl() != (*Game::pLocalPlayer)) {
203+
if (State.ChatCooldown < 3.f) return;
204+
State.ChatCooldown = 0.f;
205+
ChatController_AddChat(Game::HudManager.GetInstance()->fields.Chat, (*Game::pLocalPlayer), convert_to_string(finalmessage), false, NULL);
206+
if (finalmessage.length() > 100) {
207+
finalmessage = "=" + source + "=: \n" + message;
208+
if (finalmessage.length() > 100) {
209+
finalmessage = message;
210+
}
211+
}
212+
auto writer = InnerNetClient_StartRpcImmediately((InnerNetClient*)(*Game::pAmongUsClient), (*Game::pLocalPlayer)->fields._.NetId,
213+
uint8_t(RpcCalls__Enum::SendChat), SendOption__Enum::None, target.validate().get_PlayerControl()->fields._.OwnerId, NULL);
214+
MessageWriter_WriteString(writer, convert_to_string(finalmessage), NULL);
215+
InnerNetClient_FinishRpcImmediately((InnerNetClient*)(*Game::pAmongUsClient), writer, NULL);
216+
LOG_ERROR("Other");
217+
} else {
218+
ChatController_AddChat(Game::HudManager.GetInstance()->fields.Chat, (*Game::pLocalPlayer), convert_to_string(finalmessage), false, NULL);
219+
LOG_ERROR("Self");
220+
}
221+
LOG_ERROR("Message sent");
222+
}

rpc/_rpc.h

+18
Original file line numberDiff line numberDiff line change
@@ -477,4 +477,22 @@ class RpcGoneForTarget : public RPCInterface {
477477
public:
478478
RpcGoneForTarget(PlayerSelection target, uint8_t back);
479479
virtual void Process() override;
480+
};
481+
482+
class RpcTranslateMessage : public RPCInterface {
483+
PlayerSelection sourcePlayer;
484+
std::string source;
485+
std::string message;
486+
public:
487+
RpcTranslateMessage(PlayerSelection sourcePlayer, std::string source, std::string message);
488+
virtual void Process() override;
489+
};
490+
491+
class RpcTranslatedMessage : public RPCInterface {
492+
PlayerSelection target;
493+
std::string source;
494+
std::string message;
495+
public:
496+
RpcTranslatedMessage(PlayerSelection target, std::string source, std::string message);
497+
virtual void Process() override;
480498
};

0 commit comments

Comments
 (0)