Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/lobby/XmppClient.cpp
Show First 20 Lines • Show All 567 Lines • ▼ Show 20 Lines | void XmppClient::GUIGetGameList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) | ||||
JSContext* cx = scriptInterface.GetContext(); | JSContext* cx = scriptInterface.GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
ScriptInterface::CreateArray(cx, ret); | ScriptInterface::CreateArray(cx, ret); | ||||
int j = 0; | int j = 0; | ||||
const char* stats[] = { "name", "ip", "port", "stunIP", "stunPort", "hostUsername", "state", | const char* stats[] = { "name", "ip", "port", "stunIP", "stunPort", "hostUsername", "state", | ||||
"nbp", "maxnbp", "players", "mapName", "niceMapName", "mapSize", "mapType", | "nbp", "maxnbp", "players", "mapName", "niceMapName", "mapSize", "mapType", | ||||
"victoryCondition", "startTime", "mods" }; | "victoryConditions", "startTime", "mods" }; | ||||
for(const glooxwrapper::Tag* const& t : m_GameList) | for(const glooxwrapper::Tag* const& t : m_GameList) | ||||
{ | { | ||||
JS::RootedValue game(cx); | JS::RootedValue game(cx); | ||||
ScriptInterface::CreateObject(cx, &game); | ScriptInterface::CreateObject(cx, &game); | ||||
for (size_t i = 0; i < ARRAY_SIZE(stats); ++i) | for (size_t i = 0; i < ARRAY_SIZE(stats); ++i) | ||||
scriptInterface.SetProperty(game, stats[i], t->findAttribute(stats[i])); | scriptInterface.SetProperty(game, stats[i], t->findAttribute(stats[i])); | ||||
▲ Show 20 Lines • Show All 97 Lines • ▼ Show 20 Lines | void XmppClient::CreateGUIMessage( | ||||
JS::RootedObject messageObj(cx, message.toObjectOrNull()); | JS::RootedObject messageObj(cx, message.toObjectOrNull()); | ||||
SetGUIMessageProperty(cx, messageObj, args...); | SetGUIMessageProperty(cx, messageObj, args...); | ||||
m_ScriptInterface->FreezeObject(message, true); | m_ScriptInterface->FreezeObject(message, true); | ||||
m_GuiMessageQueue.push_back(JS::Heap<JS::Value>(message)); | m_GuiMessageQueue.push_back(JS::Heap<JS::Value>(message)); | ||||
} | } | ||||
bool XmppClient::GuiPollHasPlayerListUpdate() | bool XmppClient::GuiPollHasPlayerListUpdate() | ||||
{ | { | ||||
// The initial playerlist will be received in multiple messages | |||||
// Only inform the GUI after all of these playerlist fragments were received. | |||||
if (!m_initialLoadComplete) | |||||
return false; | |||||
bool hasUpdate = m_PlayerMapUpdate; | bool hasUpdate = m_PlayerMapUpdate; | ||||
m_PlayerMapUpdate = false; | m_PlayerMapUpdate = false; | ||||
return hasUpdate; | return hasUpdate; | ||||
} | } | ||||
JS::Value XmppClient::GuiPollNewMessage(const ScriptInterface& scriptInterface) | JS::Value XmppClient::GuiPollNewMessages(const ScriptInterface& scriptInterface) | ||||
{ | { | ||||
if (m_GuiMessageQueue.empty()) | if (!m_initialLoadComplete || m_GuiMessageQueue.empty()) | ||||
return JS::UndefinedValue(); | return JS::UndefinedValue(); | ||||
JSContext* cx = scriptInterface.GetContext(); | JSContext* cx = scriptInterface.GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
JS::RootedValue message(cx, m_GuiMessageQueue.front()); | // Optimize for batch message processing that is more | ||||
m_GuiMessageQueue.pop_front(); | // performance demanding than processing a lone message. | ||||
JS::RootedValue messages(cx); | |||||
ScriptInterface::CreateArray(cx, &messages); | |||||
JS::RootedValue messageCopy(cx); | int j = 0; | ||||
if (JS_StructuredClone(cx, message, &messageCopy, nullptr, nullptr)) | |||||
for (const JS::Heap<JS::Value>& message : m_GuiMessageQueue) | |||||
{ | { | ||||
scriptInterface.SetProperty(messageCopy, "historic", true); | scriptInterface.SetPropertyInt(messages, j++, message); | ||||
scriptInterface.FreezeObject(messageCopy, true); | |||||
m_HistoricGuiMessages.push_back(JS::Heap<JS::Value>(messageCopy)); | // Store historic chat messages. | ||||
// Only store relevant messages to minimize memory footprint. | |||||
JS::RootedValue rootedMessage(cx, message); | |||||
std::string type; | |||||
scriptInterface.GetProperty(rootedMessage, "type", type); | |||||
if (type != "chat") | |||||
continue; | |||||
std::string level; | |||||
scriptInterface.GetProperty(rootedMessage, "level", level); | |||||
if (level != "room-message" && level != "private-message") | |||||
continue; | |||||
JS::RootedValue historicMessage(cx); | |||||
if (JS_StructuredClone(cx, rootedMessage, &historicMessage, nullptr, nullptr)) | |||||
{ | |||||
scriptInterface.SetProperty(historicMessage, "historic", true); | |||||
scriptInterface.FreezeObject(historicMessage, true); | |||||
m_HistoricGuiMessages.push_back(JS::Heap<JS::Value>(historicMessage)); | |||||
} | } | ||||
else | else | ||||
LOGERROR("Could not clone historic lobby GUI message!"); | LOGERROR("Could not clone historic lobby GUI message!"); | ||||
} | |||||
return message; | m_GuiMessageQueue.clear(); | ||||
return messages; | |||||
} | } | ||||
JS::Value XmppClient::GuiPollHistoricMessages(const ScriptInterface& scriptInterface) | JS::Value XmppClient::GuiPollHistoricMessages(const ScriptInterface& scriptInterface) | ||||
{ | { | ||||
if (m_HistoricGuiMessages.empty()) | |||||
return JS::UndefinedValue(); | |||||
JSContext* cx = scriptInterface.GetContext(); | JSContext* cx = scriptInterface.GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
JS::RootedValue ret(cx); | JS::RootedValue messages(cx); | ||||
ScriptInterface::CreateArray(cx, &ret); | ScriptInterface::CreateArray(cx, &messages); | ||||
int j = 0; | int j = 0; | ||||
for (const JS::Heap<JS::Value>& message : m_HistoricGuiMessages) | for (const JS::Heap<JS::Value>& message : m_HistoricGuiMessages) | ||||
scriptInterface.SetPropertyInt(ret, j++, message); | scriptInterface.SetPropertyInt(messages, j++, message); | ||||
return ret; | return messages; | ||||
} | } | ||||
/** | /** | ||||
* Send a standard MUC textual message. | * Send a standard MUC textual message. | ||||
*/ | */ | ||||
void XmppClient::SendMUCMessage(const std::string& message) | void XmppClient::SendMUCMessage(const std::string& message) | ||||
{ | { | ||||
m_mucRoom->send(message); | m_mucRoom->send(message); | ||||
▲ Show 20 Lines • Show All 342 Lines • ▼ Show 20 Lines | const char* XmppClient::GetRole(const std::string& nick) | ||||
const PlayerMap::iterator it = m_PlayerMap.find(nick); | const PlayerMap::iterator it = m_PlayerMap.find(nick); | ||||
if (it == m_PlayerMap.end()) | if (it == m_PlayerMap.end()) | ||||
return ""; | return ""; | ||||
return GetRoleString(it->second.m_Role); | return GetRoleString(it->second.m_Role); | ||||
} | } | ||||
/** | |||||
* Get the most recent received rating of the given nick. | |||||
* Notice that this doesn't request a rating profile if it hasn't been received yet. | |||||
*/ | |||||
std::wstring XmppClient::GetRating(const std::string& nick) | |||||
{ | |||||
const PlayerMap::iterator it = m_PlayerMap.find(nick); | |||||
if (it == m_PlayerMap.end()) | |||||
return std::wstring(); | |||||
return wstring_from_utf8(it->second.m_Rating.to_string()); | |||||
} | |||||
/***************************************************** | /***************************************************** | ||||
* Utilities * | * Utilities * | ||||
*****************************************************/ | *****************************************************/ | ||||
/** | /** | ||||
* Parse and return the timestamp of a historic chat message and return the current time for new chat messages. | * Parse and return the timestamp of a historic chat message and return the current time for new chat messages. | ||||
* Historic chat messages are implement as DelayedDelivers as specified in XEP-0203. | * Historic chat messages are implement as DelayedDelivers as specified in XEP-0203. | ||||
* Hence, their timestamp MUST be in UTC and conform to the DateTime format XEP-0082. | * Hence, their timestamp MUST be in UTC and conform to the DateTime format XEP-0082. | ||||
▲ Show 20 Lines • Show All 239 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator