1 /* Copyright (C) 2018 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef XXXMPPCLIENT_H
19 #define XXXMPPCLIENT_H
20 
21 #include "IXmppClient.h"
22 
23 #include <deque>
24 
25 #include "glooxwrapper/glooxwrapper.h"
26 #include "scriptinterface/ScriptVal.h"
27 
28 class ScriptInterface;
29 
30 namespace glooxwrapper
31 {
32 	class Client;
33 	struct CertInfo;
34 }
35 
36 class XmppClient : public IXmppClient, public glooxwrapper::ConnectionListener, public glooxwrapper::MUCRoomHandler, public glooxwrapper::IqHandler, public glooxwrapper::RegistrationHandler, public glooxwrapper::MessageHandler, public glooxwrapper::Jingle::SessionHandler
37 {
38 	NONCOPYABLE(XmppClient);
39 
40 private:
41 	// Components
42 	glooxwrapper::Client* m_client;
43 	glooxwrapper::MUCRoom* m_mucRoom;
44 	glooxwrapper::Registration* m_registration;
45 	glooxwrapper::SessionManager* m_sessionManager;
46 
47 	// Account infos
48 	std::string m_username;
49 	std::string m_password;
50 	std::string m_server;
51 	std::string m_room;
52 	std::string m_nick;
53 	std::string m_xpartamuppId;
54 	std::string m_echelonId;
55 
56 	// State
57 	gloox::CertStatus m_certStatus;
58 	bool m_initialLoadComplete;
59 	bool m_isConnected;
60 
61 public:
62 	// Basic
63 	XmppClient(const std::string& sUsername, const std::string& sPassword, const std::string& sRoom, const std::string& sNick, const int historyRequestSize = 0, const bool regOpt = false);
64 	virtual ~XmppClient();
65 
66 	// Network
67 	void connect();
68 	void disconnect();
69 	bool isConnected();
70 	void recv();
71 	void SendIqGetBoardList();
72 	void SendIqGetProfile(const std::string& player);
73 	void SendIqGameReport(const ScriptInterface& scriptInterface, JS::HandleValue data);
74 	void SendIqRegisterGame(const ScriptInterface& scriptInterface, JS::HandleValue data);
75 	void SendIqUnregisterGame();
76 	void SendIqChangeStateGame(const std::string& nbp, const std::string& players);
77 	void SendIqLobbyAuth(const std::string& to, const std::string& token);
78 	void SetNick(const std::string& nick);
79 	void GetNick(std::string& nick);
80 	void kick(const std::string& nick, const std::string& reason);
81 	void ban(const std::string& nick, const std::string& reason);
82 	void SetPresence(const std::string& presence);
83 	void GetPresence(const std::string& nickname, std::string& presence);
84 	void GetRole(const std::string& nickname, std::string& role);
85 	void GetSubject(std::string& subject);
86 
87 	void GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
88 	void GUIGetGameList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
89 	void GUIGetBoardList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
90 	void GUIGetProfile(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
91 
92 	void SendStunEndpointToHost(StunClient::StunEndpoint* stunEndpoint, const std::string& hostJID);
93 
94 protected:
95 	/* Xmpp handlers */
96 	/* MUC handlers */
97 	virtual void handleMUCParticipantPresence(glooxwrapper::MUCRoom*, const glooxwrapper::MUCRoomParticipant, const glooxwrapper::Presence&);
98 	virtual void handleMUCError(glooxwrapper::MUCRoom*, gloox::StanzaError);
99 	virtual void handleMUCMessage(glooxwrapper::MUCRoom* room, const glooxwrapper::Message& msg, bool priv);
100 	virtual void handleMUCSubject(glooxwrapper::MUCRoom*, const glooxwrapper::string& nick, const glooxwrapper::string& subject);
101 	/* MUC handlers not supported by glooxwrapper */
102 	// virtual bool handleMUCRoomCreation(glooxwrapper::MUCRoom*) {return false;}
103 	// virtual void handleMUCInviteDecline(glooxwrapper::MUCRoom*, const glooxwrapper::JID&, const std::string&) {}
104 	// virtual void handleMUCInfo(glooxwrapper::MUCRoom*, int, const std::string&, const glooxwrapper::DataForm*) {}
105 	// virtual void handleMUCItems(glooxwrapper::MUCRoom*, const std::list<gloox::Disco::Item*, std::allocator<gloox::Disco::Item*> >&) {}
106 
107 	/* Log handler */
108 	virtual void handleLog(gloox::LogLevel level, gloox::LogArea area, const std::string& message);
109 
110 	/* ConnectionListener handlers*/
111 	virtual void onConnect();
112 	virtual void onDisconnect(gloox::ConnectionError e);
113 	virtual bool onTLSConnect(const glooxwrapper::CertInfo& info);
114 
115 	/* Iq Handlers */
116 	virtual bool handleIq(const glooxwrapper::IQ& iq);
handleIqID(const glooxwrapper::IQ &,int)117 	virtual void handleIqID(const glooxwrapper::IQ&, int) {}
118 
119 	/* Registration Handlers */
120 	virtual void handleRegistrationFields(const glooxwrapper::JID& /*from*/, int fields, glooxwrapper::string instructions );
121 	virtual void handleRegistrationResult(const glooxwrapper::JID& /*from*/, gloox::RegistrationResult result);
122 	virtual void handleAlreadyRegistered(const glooxwrapper::JID& /*from*/);
123 	virtual void handleDataForm(const glooxwrapper::JID& /*from*/, const glooxwrapper::DataForm& /*form*/);
124 	virtual void handleOOB(const glooxwrapper::JID& /*from*/, const glooxwrapper::OOB& oob);
125 
126 	/* Message Handler */
127 	virtual void handleMessage(const glooxwrapper::Message& msg, glooxwrapper::MessageSession* session);
128 
129 	/* Session Handler */
130 	virtual void handleSessionAction(gloox::Jingle::Action action, glooxwrapper::Jingle::Session* UNUSED(session), const glooxwrapper::Jingle::Session::Jingle* jingle);
131 	virtual void handleSessionInitiation(const glooxwrapper::Jingle::Session::Jingle* jingle);
132 
133 	// Helpers
134 	void GetPresenceString(const gloox::Presence::PresenceType p, std::string& presence) const;
135 	void GetRoleString(const gloox::MUCRoomRole r, std::string& role) const;
136 	std::string TLSErrorToString(gloox::CertStatus status) const;
137 	std::string StanzaErrorToString(gloox::StanzaError err) const;
138 	std::string ConnectionErrorToString(gloox::ConnectionError err) const;
139 	std::string RegistrationResultToString(gloox::RegistrationResult res) const;
140 	std::time_t ComputeTimestamp(const glooxwrapper::Message& msg) const;
141 
142 public:
143 	/* Messages */
144 	struct GUIMessage
145 	{
146 		std::string type;
147 		std::string level;
148 		std::string property1_name;
149 		std::string property1_value;
150 		std::string property2_name;
151 		std::string property2_value;
152 		std::time_t time;
153 	};
154 	JS::Value GuiMessageToJSVal(const ScriptInterface& scriptInterface, const GUIMessage& message, const bool historic);
155 	JS::Value GuiPollNewMessage(const ScriptInterface& scriptInterface);
156 	JS::Value GuiPollHistoricMessages(const ScriptInterface& scriptInterface);
157 	void SendMUCMessage(const std::string& message);
158 	void ClearPresenceUpdates();
159 protected:
160 	void CreateGUIMessage(
161 		const std::string& type,
162 		const std::string& level = "",
163 		const std::string& property1_name = "",
164 		const std::string& property1_value = "",
165 		const std::string& property2_name = "",
166 		const std::string& property2_value = "",
167 		const std::time_t time = std::time(nullptr));
168 
169 private:
170 	/// Map of players
171 	std::map<std::string, std::vector<std::string> > m_PlayerMap;
172 	/// List of games
173 	std::vector<const glooxwrapper::Tag*> m_GameList;
174 	/// List of rankings
175 	std::vector<const glooxwrapper::Tag*> m_BoardList;
176 	/// Profile data
177 	std::vector<const glooxwrapper::Tag*> m_Profile;
178 	/// Queue of messages for the GUI
179 	std::deque<GUIMessage> m_GuiMessageQueue;
180 	/// Cache of all GUI messages received since the login
181 	std::vector<GUIMessage> m_HistoricGuiMessages;
182 	/// Current room subject/topic.
183 	std::string m_Subject;
184 };
185 
186 #endif // XMPPCLIENT_H
187