Ticket #4877: xmpp struct nuke_v3

File xmpp struct nuke_v3, 24.9 KB (added by elexis, 6 years ago)

last WIP that never worked

Line 
1Index: binaries/data/mods/public/gui/lobby/lobby.js
2===================================================================
3--- binaries/data/mods/public/gui/lobby/lobby.js (revision 20040)
4+++ binaries/data/mods/public/gui/lobby/lobby.js (working copy)
5@@ -133,11 +133,11 @@ var g_NetMessageTypes = {
6
7 if (!g_Kicked)
8 addChatMessage({
9 "from": "system",
10 "time": msg.time,
11- "text": translate("Disconnected.") + " " + msg.text
12+ "text": translate("Disconnected.") + " " + msg.reason
13 });
14 return true;
15 },
16 "error": msg => {
17 addChatMessage({
18@@ -148,17 +148,17 @@ var g_NetMessageTypes = {
19 return false;
20 }
21 },
22 "chat": {
23 "subject": msg => {
24- updateSubject(msg.text);
25+ updateSubject(msg.subject);
26 return false;
27 },
28 "join": msg => {
29 addChatMessage({
30 "text": "/special " + sprintf(translate("%(nick)s has joined."), {
31- "nick": msg.text
32+ "nick": msg.nick
33 }),
34 "time": msg.time,
35 "isSpecial": true
36 });
37 return true;
38@@ -179,12 +179,12 @@ var g_NetMessageTypes = {
39 },
40 "presence": msg => true,
41 "role": msg => {
42 Engine.GetGUIObjectByName("chatInput").hidden = Engine.LobbyGetPlayerRole(g_Username) == "visitor";
43
44- let me = g_Username == msg.text;
45- let role = Engine.LobbyGetPlayerRole(msg.text);
46+ let me = g_Username == msg.nick;
47+ let role = Engine.LobbyGetPlayerRole(msg.role);
48 let txt =
49 role == "visitor" ?
50 me ?
51 translate("You have been muted.") :
52 translate("%(nick)s has been muted.") :
53@@ -199,25 +199,25 @@ var g_NetMessageTypes = {
54 me ?
55 translate("You are not a moderator anymore.") :
56 translate("%(nick)s is not a moderator anymore.");
57
58 addChatMessage({
59- "text": "/special " + sprintf(txt, { "nick": msg.text }),
60+ "text": "/special " + sprintf(txt, { "nick": msg.nick }),
61 "time": msg.time,
62 "isSpecial": true
63 });
64
65- if (g_SelectedPlayer == msg.text)
66+ if (g_SelectedPlayer == msg.nick)
67 updateUserRoleText(g_SelectedPlayer);
68
69 return false;
70 },
71 "nick": msg => {
72 addChatMessage({
73 "text": "/special " + sprintf(translate("%(oldnick)s is now known as %(newnick)s."), {
74- "oldnick": msg.text,
75- "newnick": msg.data
76+ "oldnick": msg.oldnick,
77+ "newnick": msg.newnick
78 }),
79 "time": msg.time,
80 "isSpecial": true
81 });
82 return true;
83@@ -1158,17 +1158,17 @@ function hostGame()
84 function onTick()
85 {
86 updateTimers();
87
88 let updateList = false;
89-
90+let i = 0;
91 while (true)
92 {
93 let msg = Engine.LobbyGuiPollMessage();
94 if (!msg)
95 break;
96-
97+warn(++i + " " + msg.type + " " + msg.level);
98 if (!g_NetMessageTypes[msg.type])
99 {
100 warn("Unrecognised message type: " + msg.type);
101 continue;
102 }
103Index: binaries/data/mods/public/gui/lobby/prelobby.js
104===================================================================
105--- binaries/data/mods/public/gui/lobby/prelobby.js (revision 20040)
106+++ binaries/data/mods/public/gui/lobby/prelobby.js (working copy)
107@@ -162,11 +162,11 @@ function onTick()
108
109 switch(message.level) {
110 case "error":
111 case "disconnected":
112 {
113- Engine.GetGUIObjectByName("feedback").caption = message.text ||
114+ Engine.GetGUIObjectByName("feedback").caption = message.reason ||
115 translate("Unknown error. This usually occurs because the same IP address is not allowed to register more than one account within one hour.");
116 g_DisplayingSystemMessage = true;
117 Engine.StopXmppClient();
118 break;
119 }
120Index: source/lobby/IXmppClient.h
121===================================================================
122--- source/lobby/IXmppClient.h (revision 20040)
123+++ source/lobby/IXmppClient.h (working copy)
124@@ -52,11 +52,11 @@ public:
125 virtual void ClearPresenceUpdates() = 0;
126 virtual void GUIGetGameList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
127 virtual void GUIGetBoardList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
128 virtual void GUIGetProfile(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
129
130- virtual void GuiPollMessage(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
131+ virtual void GuiPollMessage(JS::MutableHandleValue ret) = 0;
132 virtual void SendMUCMessage(const std::string& message) = 0;
133
134 virtual void SendStunEndpointToHost(StunClient::StunEndpoint* stunEndpoint, const std::string& hostJID) = 0;
135 };
136
137Index: source/lobby/XmppClient.cpp
138===================================================================
139--- source/lobby/XmppClient.cpp (revision 20040)
140+++ source/lobby/XmppClient.cpp (working copy)
141@@ -23,10 +23,12 @@
142 # include <winsock2.h>
143 #endif
144
145 #include "i18n/L10n.h"
146
147+#include "gui/GUI.h"
148+#include "gui/GUIManager.h"
149 #include "lib/external_libraries/enet.h"
150 #include "lib/utf8.h"
151 #include "network/NetServer.h"
152 #include "network/StunClient.h"
153 #include "ps/CLogger.h"
154@@ -188,10 +190,78 @@ void XmppClient::recv()
155 void XmppClient::handleLog(gloox::LogLevel level, gloox::LogArea area, const std::string& message)
156 {
157 std::cout << "log: level: " << level << ", area: " << area << ", message: " << message << std::endl;
158 }
159
160+shared_ptr<ScriptInterface> XmppClient::GetScriptInterface()
161+{
162+ return g_GUI->GetActiveGUI()->GetScriptInterface();
163+}
164+
165+// TODO: http://en.cppreference.com/w/cpp/language/parameter_pack
166+#define CREATE_GUI_MESSAGE_0(type, level) \
167+ JSContext* cx = GetScriptInterface()->GetContext(); \
168+ JSAutoRequest rq(cx); \
169+ JS::RootedValue message(cx); \
170+ GetScriptInterface()->Eval("({})", &message); \
171+ GetScriptInterface()->SetProperty(message, "type", std::string(type)); \
172+ GetScriptInterface()->SetProperty(message, "level", std::string(level)); \
173+ GetScriptInterface()->SetProperty(message, "time", (double)std::time(nullptr)); \
174+ m_GuiMessageQueue.push_back(JS::Heap<JS::Value>(message));
175+
176+#define CREATE_GUI_MESSAGE_1(type, level, prop1, val1) \
177+ JSContext* cx = GetScriptInterface()->GetContext(); \
178+ JSAutoRequest rq(cx); \
179+ JS::RootedValue message(cx); \
180+ GetScriptInterface()->Eval("({})", &message); \
181+ GetScriptInterface()->SetProperty(message, "type", std::string(type)); \
182+ GetScriptInterface()->SetProperty(message, "level", std::string(level)); \
183+ GetScriptInterface()->SetProperty(message, prop1, val1); \
184+ GetScriptInterface()->SetProperty(message, "time", (double)std::time(nullptr)); \
185+ m_GuiMessageQueue.push_back(JS::Heap<JS::Value>(message));
186+
187+#define CREATE_GUI_MESSAGE_2(type, level, prop1, val1, prop2, val2) \
188+ JSContext* cx = GetScriptInterface()->GetContext(); \
189+ JSAutoRequest rq(cx); \
190+ JS::RootedValue message(cx); \
191+ GetScriptInterface()->Eval("({})", &message); \
192+ GetScriptInterface()->SetProperty(message, "type", std::string(type)); \
193+ GetScriptInterface()->SetProperty(message, "level", std::string(level)); \
194+ GetScriptInterface()->SetProperty(message, prop1, val1); \
195+ GetScriptInterface()->SetProperty(message, prop2, val2); \
196+ GetScriptInterface()->SetProperty(message, "time", (double)std::time(nullptr)); \
197+ m_GuiMessageQueue.push_back(JS::Heap<JS::Value>(message));
198+
199+#define CREATE_GUI_MESSAGE_SYSTEM(level) \
200+ CREATE_GUI_MESSAGE_0("system", level)
201+
202+#define CREATE_GUI_MESSAGE_GAME(level) \
203+ CREATE_GUI_MESSAGE_0("game", level)
204+
205+#define CREATE_GUI_MESSAGE_CHAT(msg, priv) \
206+ JSContext* cx = GetScriptInterface()->GetContext(); \
207+ JSAutoRequest rq(cx); \
208+ JS::RootedValue message(cx); \
209+ GetScriptInterface()->Eval("({})", &message); \
210+ GetScriptInterface()->SetProperty(message, "type", std::string("chat")); \
211+ GetScriptInterface()->SetProperty(message, "level", std::string(priv ? "private-message" : "room-message")); \
212+ GetScriptInterface()->SetProperty(message, "from", msg.from().resource().to_string()); \
213+ GetScriptInterface()->SetProperty(message, "text", msg.body().to_string()); \
214+ GetScriptInterface()->SetProperty(message, "time", (double)ComputeTimestamp(msg)); \
215+ m_GuiMessageQueue.push_back(JS::Heap<JS::Value>(message));
216+
217+#define CREATE_GUI_MESSAGE_ERROR(text) \
218+ JSContext* cx = GetScriptInterface()->GetContext(); \
219+ JSAutoRequest rq(cx); \
220+ JS::RootedValue message(cx); \
221+ GetScriptInterface()->Eval("({})", &message); \
222+ GetScriptInterface()->SetProperty(message, "type", std::string("system")); \
223+ GetScriptInterface()->SetProperty(message, "level", std::string("error")); \
224+ GetScriptInterface()->SetProperty(message, "text", text); \
225+ GetScriptInterface()->SetProperty(message, "time", (double)std::time(nullptr)); \
226+ m_GuiMessageQueue.push_back(JS::Heap<JS::Value>(message));
227+
228 /*****************************************************
229 * Connection handlers *
230 *****************************************************/
231
232 /**
233@@ -199,11 +269,11 @@ void XmppClient::handleLog(gloox::LogLev
234 */
235 void XmppClient::onConnect()
236 {
237 if (m_mucRoom)
238 {
239- CreateGUIMessage("system", "connected");
240+ CREATE_GUI_MESSAGE_SYSTEM("connected");
241 m_mucRoom->join();
242 }
243
244 if (m_registration)
245 m_registration->fetchRegistrationFields();
246@@ -229,11 +299,11 @@ void XmppClient::onDisconnect(gloox::Con
247 m_BoardList.clear();
248 m_GameList.clear();
249 m_PlayerMap.clear();
250 m_Profile.clear();
251
252- CreateGUIMessage("system", "disconnected", ConnectionErrorToString(error));
253+ CREATE_GUI_MESSAGE_1("system", "disconnected", "reason", ConnectionErrorToString(error));
254 }
255
256 /**
257 * Handle TLS connection
258 */
259@@ -255,11 +325,11 @@ bool XmppClient::onTLSConnect(const gloo
260 /**
261 * Handle MUC room errors
262 */
263 void XmppClient::handleMUCError(glooxwrapper::MUCRoom*, gloox::StanzaError err)
264 {
265- CreateGUIMessage("system", "error", StanzaErrorToString(err));
266+ CREATE_GUI_MESSAGE_ERROR(StanzaErrorToString(err));
267 }
268
269 /*****************************************************
270 * Requests to server *
271 *****************************************************/
272@@ -421,13 +491,18 @@ void XmppClient::handleRegistrationField
273 }
274
275 void XmppClient::handleRegistrationResult(const glooxwrapper::JID&, gloox::RegistrationResult result)
276 {
277 if (result == gloox::RegistrationSuccess)
278- CreateGUIMessage("system", "registered");
279+ { // TODO: why do we need these braces?
280+ CREATE_GUI_MESSAGE_SYSTEM("registered");
281+ }
282 else
283- CreateGUIMessage("system", "error", RegistrationResultToString(result));
284+ {
285+ CREATE_GUI_MESSAGE_ERROR(RegistrationResultToString(result));
286+ }
287+
288 disconnect();
289 }
290
291 void XmppClient::handleAlreadyRegistered(const glooxwrapper::JID&)
292 {
293@@ -550,35 +625,19 @@ void XmppClient::GUIGetProfile(const Scr
294 *****************************************************/
295
296 /**
297 * Send GUI message queue when queried.
298 */
299-void XmppClient::GuiPollMessage(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret)
300+void XmppClient::GuiPollMessage(JS::MutableHandleValue ret)
301 {
302 if (m_GuiMessageQueue.empty())
303 {
304 ret.setUndefined();
305 return;
306 }
307
308- GUIMessage message = m_GuiMessageQueue.front();
309- JSContext* cx = scriptInterface.GetContext();
310- JSAutoRequest rq(cx);
311-
312- scriptInterface.Eval("({})", ret);
313- scriptInterface.SetProperty(ret, "type", message.type);
314- if (!message.from.empty())
315- scriptInterface.SetProperty(ret, "from", message.from);
316- if (!message.text.empty())
317- scriptInterface.SetProperty(ret, "text", message.text);
318- if (!message.level.empty())
319- scriptInterface.SetProperty(ret, "level", message.level);
320- if (!message.data.empty())
321- scriptInterface.SetProperty(ret, "data", message.data);
322-
323- scriptInterface.SetProperty(ret, "time", (double)message.time);
324-
325+ ret.set(m_GuiMessageQueue.front());
326 m_GuiMessageQueue.pop_front();
327 }
328
329 /**
330 * Send a standard MUC textual message.
331@@ -587,65 +646,66 @@ void XmppClient::SendMUCMessage(const st
332 {
333 m_mucRoom->send(message);
334 }
335
336 /**
337- * Push a message onto the GUI queue.
338- *
339- * @param message Message to add to the queue
340- */
341-void XmppClient::PushGuiMessage(XmppClient::GUIMessage message)
342-{
343- m_GuiMessageQueue.push_back(std::move(message));
344-}
345-
346-/**
347 * Clears all presence updates from the message queue.
348 * Used when rejoining the lobby, since we don't need to handle past presence changes.
349 */
350 void XmppClient::ClearPresenceUpdates()
351 {
352+ JSContext* cx = GetScriptInterface()->GetContext();
353+ JSAutoRequest rq(cx);
354+
355+ shared_ptr<ScriptInterface> scriptInterface = GetScriptInterface();
356+
357+ for (std::deque<JS::Heap<JS::Value>>::iterator message = m_GuiMessageQueue.begin(); message != m_GuiMessageQueue.end(); )
358+ {
359+ JS::RootedValue messageVal(cx, message->get());
360+ std::string type, level;
361+
362+ if (scriptInterface->HasProperty(messageVal, "type") &&
363+ scriptInterface->HasProperty(messageVal, "level") &&
364+ scriptInterface->GetProperty(messageVal, "type", type) &&
365+ scriptInterface->GetProperty(messageVal, "level", level) &&
366+ type == "chat" && level == "presence")
367+ message = m_GuiMessageQueue.erase(message);
368+ else
369+ ++message;
370+ }
371+ /*
372 m_GuiMessageQueue.erase(
373 std::remove_if(m_GuiMessageQueue.begin(), m_GuiMessageQueue.end(),
374- [](XmppClient::GUIMessage& message)
375+ [cx, scriptInterface](JS::Heap<JS::Value>& message)
376 {
377- return message.type == L"chat" && message.level == L"presence";
378+ JS::RootedValue message2(cx, JS::ObjectValue(*message));
379+ std::string type, level;
380+ scriptInterface->GetProperty(message2, "type", type);
381+ scriptInterface->GetProperty(message2, "level", level);
382+ return type == "chat" && level == "presence";
383 }
384 ), m_GuiMessageQueue.end());
385+ */
386 }
387
388 /**
389 * Handle a room message.
390 */
391 void XmppClient::handleMUCMessage(glooxwrapper::MUCRoom*, const glooxwrapper::Message& msg, bool priv)
392 {
393 DbgXMPP(msg.from().resource() << " said " << msg.body());
394-
395- GUIMessage message;
396- message.type = L"chat";
397- message.level = priv ? L"private-message" : L"room-message";
398- message.from = wstring_from_utf8(msg.from().resource().to_string());
399- message.text = wstring_from_utf8(msg.body().to_string());
400- message.time = ComputeTimestamp(msg);
401- PushGuiMessage(message);
402+ CREATE_GUI_MESSAGE_CHAT(msg, priv);
403 }
404
405 /**
406 * Handle a private message.
407 */
408 void XmppClient::handleMessage(const glooxwrapper::Message& msg, glooxwrapper::MessageSession *)
409 {
410 DbgXMPP("type " << msg.subtype() << ", subject " << msg.subject()
411 << ", message " << msg.body() << ", thread id " << msg.thread());
412-
413- GUIMessage message;
414- message.type = L"chat";
415- message.level = L"private-message";
416- message.from = wstring_from_utf8(msg.from().username().to_string());
417- message.text = wstring_from_utf8(msg.body().to_string());
418- message.time = ComputeTimestamp(msg);
419- PushGuiMessage(message);
420+ CREATE_GUI_MESSAGE_CHAT(msg, true);
421 }
422
423 /**
424 * Handle portions of messages containing custom stanza extensions.
425 */
426@@ -665,11 +725,11 @@ bool XmppClient::handleIq(const glooxwra
427 m_GameList.clear();
428
429 for (const glooxwrapper::Tag* const& t : gq->m_GameList)
430 m_GameList.emplace_back(t->clone());
431
432- CreateGUIMessage("game", "gamelist");
433+ CREATE_GUI_MESSAGE_GAME("gamelist");
434 }
435 if (bq)
436 {
437 if (bq->m_Command == "boardlist")
438 {
439@@ -678,22 +738,22 @@ bool XmppClient::handleIq(const glooxwra
440 m_BoardList.clear();
441
442 for (const glooxwrapper::Tag* const& t : bq->m_StanzaBoardList)
443 m_BoardList.emplace_back(t->clone());
444
445- CreateGUIMessage("game", "leaderboard");
446+ CREATE_GUI_MESSAGE_0("game", "leaderboard");
447 }
448 else if (bq->m_Command == "ratinglist")
449 {
450 for (const glooxwrapper::Tag* const& t : bq->m_StanzaBoardList)
451 {
452 std::string name = t->findAttribute("name").to_string();
453 if (m_PlayerMap.find(name) != m_PlayerMap.end())
454 m_PlayerMap[name][1] = t->findAttribute("rating").to_string();
455 }
456
457- CreateGUIMessage("game", "ratinglist");
458+ CREATE_GUI_MESSAGE_0("game", "ratinglist");
459 }
460 }
461 if (pq)
462 {
463 for (const glooxwrapper::Tag* const& t : m_Profile)
464@@ -701,46 +761,26 @@ bool XmppClient::handleIq(const glooxwra
465 m_Profile.clear();
466
467 for (const glooxwrapper::Tag* const& t : pq->m_StanzaProfile)
468 m_Profile.emplace_back(t->clone());
469
470- CreateGUIMessage("game", "profile");
471+ CREATE_GUI_MESSAGE_0("game", "profile");
472 }
473 }
474 else if (iq.subtype() == gloox::IQ::Error)
475 {
476 gloox::StanzaError err = iq.error_error();
477- CreateGUIMessage("system", "error", StanzaErrorToString(err));
478+ CREATE_GUI_MESSAGE_ERROR(StanzaErrorToString(err));
479 }
480 else
481 {
482- CreateGUIMessage("system", "error", g_L10n.Translate("unknown subtype (see logs)"));
483- std::string tag = tag_name(iq);
484- LOGMESSAGE("unknown subtype '%s'", tag.c_str());
485+ CREATE_GUI_MESSAGE_ERROR(g_L10n.Translate("unknown subtype (see logs)"));
486+ LOGMESSAGE("unknown subtype '%s'", tag_name(iq).c_str());
487 }
488 return true;
489 }
490
491-/**
492- * Create a new detail message for the GUI.
493- *
494- * @param type General message type
495- * @param level Detailed message type
496- * @param text Body of the message
497- * @param data Optional field, used for auxiliary data
498- */
499-void XmppClient::CreateGUIMessage(const std::string& type, const std::string& level, const std::string& text, const std::string& data)
500-{
501- GUIMessage message;
502- message.type = wstring_from_utf8(type);
503- message.level = wstring_from_utf8(level);
504- message.text = wstring_from_utf8(text);
505- message.data = wstring_from_utf8(data);
506- message.time = std::time(nullptr);
507- PushGuiMessage(message);
508-}
509-
510 /*****************************************************
511 * Presence, nickname, and subject *
512 *****************************************************/
513
514 /**
515@@ -752,37 +792,56 @@ void XmppClient::handleMUCParticipantPre
516 gloox::Presence::PresenceType presenceType = presence.presence();
517 std::string presenceString, roleString;
518 GetPresenceString(presenceType, presenceString);
519 GetRoleString(participant.role, roleString);
520
521+ JSContext* cx = GetScriptInterface()->GetContext();
522+ JSAutoRequest rq(cx);
523+
524+ JS::RootedValue message(cx);
525+ GetScriptInterface()->Eval("({})", &message);
526+ GetScriptInterface()->SetProperty(message, "type", std::string("chat"));
527+ GetScriptInterface()->SetProperty(message, "time", (double)std::time(nullptr));
528+
529 if (presenceType == gloox::Presence::Unavailable)
530 {
531 if (!participant.newNick.empty() && (participant.flags & (gloox::UserNickChanged | gloox::UserSelf)))
532 {
533 // we have a nick change
534 std::string newNick = participant.newNick.to_string();
535 m_PlayerMap[newNick].resize(3);
536 m_PlayerMap[newNick][0] = presenceString;
537 m_PlayerMap[newNick][2] = roleString;
538- CreateGUIMessage("chat", "nick", nick, participant.newNick.to_string());
539+
540+ GetScriptInterface()->SetProperty(message, "text", std::string("nick"));
541+ GetScriptInterface()->SetProperty(message, "oldnick", nick);
542+ GetScriptInterface()->SetProperty(message, "newnick", participant.newNick.to_string());
543+
544 DbgXMPP(nick << " is now known as " << participant.newNick.to_string());
545 }
546 else if (participant.flags & gloox::UserKicked)
547 {
548 DbgXMPP(nick << " was kicked. Reason: " << participant.reason.to_string());
549- CreateGUIMessage("chat", "kicked", nick, participant.reason.to_string());
550+ GetScriptInterface()->SetProperty(message, "text", std::string("kicked"));
551+ GetScriptInterface()->SetProperty(message, "nick", nick);
552+ GetScriptInterface()->SetProperty(message, "reason", participant.reason.to_string());
553+
554 }
555 else if (participant.flags & gloox::UserBanned)
556 {
557 DbgXMPP(nick << " was banned. Reason: " << participant.reason.to_string());
558- CreateGUIMessage("chat", "banned", nick, participant.reason.to_string());
559+ GetScriptInterface()->SetProperty(message, "text", std::string("banned"));
560+ GetScriptInterface()->SetProperty(message, "nick", nick);
561+ GetScriptInterface()->SetProperty(message, "reason", participant.reason.to_string());
562 }
563 else
564 {
565 DbgXMPP(nick << " left the room (flags " << participant.flags << ")");
566- CreateGUIMessage("chat", "leave", nick);
567+ GetScriptInterface()->SetProperty(message, "text", std::string("leave"));
568+ GetScriptInterface()->SetProperty(message, "nick", nick);
569 }
570+ m_GuiMessageQueue.push_back(JS::Heap<JS::Value>(message));
571
572 m_PlayerMap.erase(nick);
573 }
574 else
575 {
576@@ -794,15 +853,21 @@ void XmppClient::handleMUCParticipantPre
577 {
578 if (m_mucRoom->nick().to_string() == nick)
579 m_initialLoadComplete = true;
580 }
581 else if (m_PlayerMap.find(nick) == m_PlayerMap.end())
582- CreateGUIMessage("chat", "join", nick);
583+ {
584+ CREATE_GUI_MESSAGE_1("chat", "join", "nick", nick);
585+ }
586 else if (m_PlayerMap[nick][2] != roleString)
587- CreateGUIMessage("chat", "role", nick, m_PlayerMap[nick][2]);
588+ {
589+ CREATE_GUI_MESSAGE_2("chat", "role", "nick", nick, "role", m_PlayerMap[nick][2]);
590+ }
591 else
592- CreateGUIMessage("chat", "presence", nick);
593+ {
594+ CREATE_GUI_MESSAGE_1("chat", "presence", "nick", nick);
595+ }
596
597 DbgXMPP(nick << " is in the room, presence : " << (int)presenceType);
598 m_PlayerMap[nick].resize(3);
599 m_PlayerMap[nick][0] = presenceString;
600 m_PlayerMap[nick][2] = roleString;
601@@ -813,11 +878,11 @@ void XmppClient::handleMUCParticipantPre
602 * Update local cache when subject changes.
603 */
604 void XmppClient::handleMUCSubject(glooxwrapper::MUCRoom*, const glooxwrapper::string& UNUSED(nick), const glooxwrapper::string& subject)
605 {
606 m_Subject = subject.c_str();
607- CreateGUIMessage("chat", "subject", m_Subject);
608+ CREATE_GUI_MESSAGE_1("chat", "subject", "subject", m_Subject);
609 }
610
611 /**
612 * Get current subject.
613 *
614@@ -1129,5 +1194,11 @@ void XmppClient::handleSessionInitiation
615 return;
616 }
617
618 g_NetServer->SendHolePunchingMessage(candidate.ip.to_string(), candidate.port);
619 }
620+
621+#undef CREATE_GUI_MESSAGE_0
622+#undef CREATE_GUI_MESSAGE_1
623+#undef CREATE_GUI_MESSAGE_2
624+#undef CREATE_GUI_MESSAGE_CHAT
625+#undef CREATE_GUI_MESSAGE_ERROR
626Index: source/lobby/XmppClient.h
627===================================================================
628--- source/lobby/XmppClient.h (revision 20040)
629+++ source/lobby/XmppClient.h (working copy)
630@@ -83,10 +83,11 @@ public:
631 void GUIGetProfile(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
632
633 void SendStunEndpointToHost(StunClient::StunEndpoint* stunEndpoint, const std::string& hostJID);
634
635 protected:
636+ shared_ptr<ScriptInterface>GetScriptInterface();
637 /* Xmpp handlers */
638 /* MUC handlers */
639 virtual void handleMUCParticipantPresence(glooxwrapper::MUCRoom*, const glooxwrapper::MUCRoomParticipant, const glooxwrapper::Presence&);
640 virtual void handleMUCError(glooxwrapper::MUCRoom*, gloox::StanzaError);
641 virtual void handleMUCMessage(glooxwrapper::MUCRoom* room, const glooxwrapper::Message& msg, bool priv);
642@@ -141,16 +142,13 @@ public:
643 std::wstring data;
644 std::wstring from;
645 std::wstring message;
646 std::time_t time;
647 };
648- void GuiPollMessage(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
649 void SendMUCMessage(const std::string& message);
650+ void GuiPollMessage(JS::MutableHandleValue ret);
651 void ClearPresenceUpdates();
652-protected:
653- void PushGuiMessage(XmppClient::GUIMessage message);
654- void CreateGUIMessage(const std::string& type, const std::string& level, const std::string& text = "", const std::string& data = "");
655
656 private:
657 /// Map of players
658 std::map<std::string, std::vector<std::string> > m_PlayerMap;
659 /// List of games
660@@ -158,11 +156,11 @@ private:
661 /// List of rankings
662 std::vector<const glooxwrapper::Tag*> m_BoardList;
663 /// Profile data
664 std::vector<const glooxwrapper::Tag*> m_Profile;
665 /// Queue of messages for the GUI
666- std::deque<GUIMessage> m_GuiMessageQueue;
667+ std::deque<JS::Heap<JS::Value>> m_GuiMessageQueue;
668 /// Current room subject/topic.
669 std::string m_Subject;
670 };
671
672 #endif // XMPPCLIENT_H
673Index: source/lobby/scripting/JSInterface_Lobby.cpp
674===================================================================
675--- source/lobby/scripting/JSInterface_Lobby.cpp (revision 20040)
676+++ source/lobby/scripting/JSInterface_Lobby.cpp (working copy)
677@@ -232,11 +232,11 @@ JS::Value JSI_Lobby::LobbyGuiPollMessage
678
679 JSContext* cx = pCxPrivate->pScriptInterface->GetContext();
680 JSAutoRequest rq(cx);
681
682 JS::RootedValue poll(cx);
683- g_XmppClient->GuiPollMessage(*(pCxPrivate->pScriptInterface), &poll);
684+ g_XmppClient->GuiPollMessage(&poll);
685
686 return poll;
687 }
688
689 void JSI_Lobby::LobbySendMessage(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& message)
690Index: source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp
691===================================================================
692--- source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp (revision 20040)
693+++ source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp (working copy)
694@@ -501,11 +501,11 @@ ScenarioEditor::ScenarioEditor(wxWindow*
695 {
696 wxFFile helpFile(helpPath);
697 wxString helpData;
698 helpFile.ReadAll(&helpData);
699 AtObj data = AtlasObject::LoadFromJSON(std::string(helpData));
700- #define ADD_HELP_ITEM(id) \
701+#define ADD_HELP_ITEM(id) \
702 do { \
703 if (!data[#id].hasContent()) \
704 break; \
705 if (!data[#id]["title"].hasContent() || !data[#id]["url"].hasContent()) \
706 break; \
707@@ -515,11 +515,11 @@ ScenarioEditor::ScenarioEditor(wxWindow*
708 HelpItem(wxString(data[#id]["title"]), wxString(data[#id]["tooltip"]), wxString(data[#id]["url"])) \
709 )); \
710 } while (0)
711 ADD_HELP_ITEM(Manual);
712 ADD_HELP_ITEM(ReportBug);
713- #undef ADD_HELP_ITEM
714+#undef ADD_HELP_ITEM
715 }
716 else
717 wxLogError(_("'%ls' does not exist"), helpPath.c_str());
718 }
719