1+ #include " MessageHandlers.h"
2+
3+ DWORD WINAPI WaitForNewMessagesThreadProc (LPVOID lpParam)
4+ {
5+ UNREFERENCED_PARAMETER (lpParam);
6+
7+ auto &plugin = Plugin::Get ();
8+ HANDLE events[] = { plugin.handle_mre_cluster , plugin.handle_mre_thread };
9+
10+ bool exit = false ;
11+ while (!exit)
12+ {
13+ auto dwWaitResult = WaitForMultipleObjects (2 , events, FALSE , INFINITE);
14+ switch (dwWaitResult)
15+ {
16+ case WAIT_OBJECT_0 + 0 :
17+ if (ArkApi::GetApiUtils ().GetWorld ())
18+ {
19+ OnNewMessagesFromDatabase ();
20+ }
21+ break ;
22+ case WAIT_OBJECT_0 + 1 :
23+ exit = true ;
24+ break ;
25+ case WAIT_TIMEOUT:
26+ default :
27+ Sleep (1000 ); // todo: ?
28+ }
29+ }
30+
31+ CloseHandle (plugin.handle_mre_cluster );
32+ CloseHandle (plugin.handle_mre_thread );
33+
34+ return 0 ;
35+ }
36+
37+ // when the database has been updated with new messages
38+ void OnNewMessagesFromDatabase ()
39+ {
40+ auto &plugin = Plugin::Get ();
41+ try
42+ {
43+ *plugin.db << " SELECT Id,At,ServerKey,ServerTag,SteamId,PlayerName,CharacterName,TribeName,Message,Type,Rcon,Icon "
44+ " FROM Messages "
45+ " WHERE Id > ? "
46+ " ORDER BY Id ASC;" << plugin.lastRowId >>
47+ [&](long long id,
48+ long long at,
49+ std::string serverKey,
50+ std::string serverTag,
51+ long long steamId,
52+ std::string playerName,
53+ std::u16string characterName,
54+ std::string tribeName,
55+ std::u16string message,
56+ int type,
57+ int rcon,
58+ int icon)
59+ {
60+ HandleMessageFromDatabase (id, at, serverKey, serverTag, steamId, playerName, characterName, tribeName, message, type, rcon, icon);
61+ plugin.lastRowId = id;
62+ };
63+ }
64+ catch (sqlite::sqlite_exception& e)
65+ {
66+ Log::GetLog ()->error (" ({} {}) Unexpected DB error {}" , __FILE__, __FUNCTION__, e.what ());
67+ }
68+ }
69+
70+ void HandleMessageFromDatabase (
71+ long long id,
72+ long long at,
73+ std::string serverKey,
74+ std::string serverTag,
75+ long long steamId,
76+ std::string playerName,
77+ std::u16string characterName,
78+ std::string tribeName,
79+ std::u16string message,
80+ int type,
81+ int rcon,
82+ int icon)
83+ {
84+ auto &plugin = Plugin::Get ();
85+ // send chat message to users
86+ if (rcon == 0 )
87+ {
88+ auto chatIcon = static_cast <ChatIcon>(icon);
89+ UTexture2D *iconTexture = nullptr ;
90+
91+ auto isLocal = serverKey.compare (plugin.serverKey ) == 0 ;
92+
93+ // get chat icon
94+ if (chatIcon == ChatIcon::Admin)
95+ {
96+ auto engine = Globals::GEngine ()();
97+ auto primalglobals = engine->GameSingletonField ()();
98+ auto gamedata = primalglobals->PrimalGameDataOverrideField ()();
99+ if (!gamedata) gamedata = primalglobals->PrimalGameDataField ()();
100+
101+ auto texture = gamedata->NameTagServerAdminField ()();
102+ if (texture) iconTexture = gamedata->NameTagServerAdminField ()();
103+ }
104+
105+ auto name = FString (FromUTF16 (characterName).c_str ());
106+ if (!isLocal || !plugin.hideServerTagOnLocal )
107+ {
108+ // format name with server tag
109+ auto name_with_tag = FString (ArkApi::Tools::ConvertToWideStr (plugin.namePattern ).c_str ());
110+ name_with_tag.ReplaceInline (L" {Name}" , *name);
111+ name_with_tag.ReplaceInline (L" {ServerTag}" , ArkApi::Tools::ConvertToWideStr (serverTag).c_str ());
112+ name = name_with_tag;
113+ }
114+
115+ // get the sender id (to support own name showing in gray for the player)
116+ unsigned int linkedPlayerDataID;
117+ if (serverKey.compare (plugin.serverKey ) == 0 )
118+ {
119+ auto player_controller = ArkApi::GetApiUtils ().FindPlayerFromSteamId (steamId);
120+ if (player_controller)
121+ {
122+ auto player_character = player_controller->GetPlayerCharacter ();
123+ if (player_character) linkedPlayerDataID = player_character->LinkedPlayerDataIDField ()();
124+ }
125+ }
126+
127+ SendChatMessageToAll (
128+ linkedPlayerDataID,
129+ name,
130+ FromUTF8 (playerName).c_str (),
131+ FromUTF8 (tribeName).c_str (),
132+ FromUTF16 (message).c_str (),
133+ iconTexture);
134+ }
135+ else
136+ {
137+ SendRconChatMessageToAll (FromUTF16 (message));
138+ }
139+ }
0 commit comments