Skip to content

Commit 44e04a6

Browse files
committed
translate?
1 parent 48112dd commit 44e04a6

File tree

5 files changed

+24983
-13
lines changed

5 files changed

+24983
-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

+136
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
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>
49

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

rpc/_rpc.h

+17
Original file line numberDiff line numberDiff line change
@@ -477,4 +477,21 @@ 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+
std::string source;
484+
std::string message;
485+
public:
486+
RpcTranslateMessage(std::string source, std::string message);
487+
virtual void Process() override;
488+
};
489+
490+
class RpcTranslatedMessage : public RPCInterface {
491+
PlayerSelection target;
492+
std::string source;
493+
std::string message;
494+
public:
495+
RpcTranslatedMessage(PlayerSelection target, std::string source, std::string message);
496+
virtual void Process() override;
480497
};

0 commit comments

Comments
 (0)