Forgot some files. Also... Hacks.
[dolphin.git] / Source / Core / DolphinWX / Src / NetPlayClient.cpp
blob13a42f8bb0480c445491ee77e6d20c3af7872170
1 #include "NetPlay.h"
2 #include "NetWindow.h"
4 // called from ---GUI--- thread
5 NetPlayClient::~NetPlayClient()
7 if (is_connected)
9 m_do_loop = false;
10 m_thread->WaitForDeath();
11 delete m_thread;
15 // called from ---GUI--- thread
16 NetPlayClient::NetPlayClient(const std::string& address, const u16 port, const std::string& name, NetPlayDiag* const npd)
18 m_dialog = npd;
19 is_connected = false;
21 // why is false successful? documentation says true is
22 if (0 == m_socket.Connect(port, address))
24 // send connect message
25 sf::Packet spac;
26 spac << NETPLAY_VERSION;
27 spac << NETPLAY_DOLPHIN_VER;
28 spac << name;
29 m_socket.Send(spac);
31 sf::Packet rpac;
32 // TODO: make this not hang
33 m_socket.Receive(rpac);
34 MessageId error;
35 rpac >> error;
37 // got error message
38 if (error)
40 switch (error)
42 case CON_ERR_SERVER_FULL :
43 PanicAlert("The server is full!");
44 break;
45 case CON_ERR_VERSION_MISMATCH :
46 PanicAlert("The server and client's NetPlay versions are incompatible!");
47 break;
48 case CON_ERR_GAME_RUNNING :
49 PanicAlert("The server responded: the game is currently running!");
50 break;
51 default :
52 PanicAlert("The server sent an unknown error message!");
53 break;
55 m_socket.Close();
57 else
59 rpac >> m_pid;
61 Player player;
62 player.name = name;
63 player.pid = m_pid;
64 player.revision = NETPLAY_DOLPHIN_VER;
66 // add self to player list
67 m_players[m_pid] = player;
68 m_local_player = &m_players[m_pid];
70 UpdateGUI();
72 //PanicAlert("Connection successful: assigned player id: %d", m_pid);
73 is_connected = true;
75 m_selector.Add(m_socket);
76 m_thread = new Common::Thread(NetPlayThreadFunc, this);
79 else
80 PanicAlert("Failed to Connect!");
84 // called from ---NETPLAY--- thread
85 unsigned int NetPlayClient::OnData(sf::Packet& packet)
87 MessageId mid;
88 packet >> mid;
90 switch (mid)
92 case NP_MSG_PLAYER_JOIN :
94 Player player;
95 packet >> player.pid;
96 packet >> player.name;
97 packet >> player.revision;
99 m_crit.players.Enter(); // lock players
100 m_players[player.pid] = player;
101 m_crit.players.Leave();
103 UpdateGUI();
105 break;
107 case NP_MSG_PLAYER_LEAVE :
109 PlayerId pid;
110 packet >> pid;
112 m_crit.players.Enter(); // lock players
113 m_players.erase(m_players.find(pid));
114 m_crit.players.Leave();
116 UpdateGUI();
118 break;
120 case NP_MSG_CHAT_MESSAGE :
122 PlayerId pid;
123 packet >> pid;
124 std::string msg;
125 packet >> msg;
127 // don't need lock to read in this thread
128 const Player& player = m_players[pid];
130 // add to gui
131 std::ostringstream ss;
132 ss << player.name << '[' << (char)(pid+'0') << "]: " << msg;
134 AppendChatGUI(ss.str());
136 break;
138 case NP_MSG_PAD_MAPPING :
140 PlayerId pid;
141 packet >> pid;
143 m_crit.players.Enter(); // lock players
144 Player& player = m_players[pid];
146 for (unsigned int i=0; i<4; ++i)
147 packet >> player.pad_map[i];
148 m_crit.players.Leave();
150 UpdateGUI();
152 break;
154 case NP_MSG_PAD_DATA :
156 PadMapping map = 0;
157 NetPad np;
158 packet >> map >> np.nHi >> np.nLo;
160 // trusting server for good map value (>=0 && <4)
161 // add to pad buffer
162 m_crit.buffer.Enter(); // lock buffer
163 m_pad_buffer[(unsigned)map].push(np);
164 m_crit.buffer.Leave();
166 break;
168 case NP_MSG_PAD_BUFFER :
170 u32 size = 0;
171 packet >> size;
173 m_crit.buffer.Enter(); // lock buffer
174 m_target_buffer_size = size;
175 m_crit.buffer.Leave();
177 break;
179 case NP_MSG_CHANGE_GAME :
181 // lock here?
182 m_crit.game.Enter(); // lock game state
183 packet >> m_selected_game;
184 m_crit.game.Leave();
186 // update gui
187 wxCommandEvent evt(wxEVT_THREAD, NP_GUI_EVT_CHANGE_GAME);
188 // TODO: using a wxString in AddPendingEvent from another thread is unsafe i guess?
189 evt.SetString(wxString(m_selected_game.c_str(), *wxConvCurrent));
190 m_dialog->GetEventHandler()->AddPendingEvent(evt);
192 break;
194 case NP_MSG_START_GAME :
196 packet >> m_on_game;
198 wxCommandEvent evt(wxEVT_THREAD, NP_GUI_EVT_START_GAME);
199 m_dialog->GetEventHandler()->AddPendingEvent(evt);
201 break;
203 case NP_MSG_STOP_GAME :
205 wxCommandEvent evt(wxEVT_THREAD, NP_GUI_EVT_STOP_GAME);
206 m_dialog->GetEventHandler()->AddPendingEvent(evt);
208 break;
210 case NP_MSG_DISABLE_GAME :
212 PanicAlert("Other client disconnected while game is running!! NetPlay is disabled. You must manually stop the game.");
213 CritLocker game_lock(m_crit.game); // lock game state
214 m_is_running = false;
215 NetPlay_Disable();
217 break;
219 case NP_MSG_PING :
221 u32 ping_key = 0;
222 packet >> ping_key;
224 sf::Packet spac;
225 spac << (MessageId)NP_MSG_PONG;
226 spac << ping_key;
228 CritLocker send_lock(m_crit.send);
229 m_socket.Send(spac);
231 break;
233 default :
234 PanicAlert("Unknown message received with id : %d", mid);
235 break;
239 return 0;
242 // called from ---NETPLAY--- thread
243 void NetPlayClient::Entry()
245 while (m_do_loop)
247 if (m_selector.Wait(0.01f))
249 sf::Packet rpac;
250 switch (m_socket.Receive(rpac))
252 case sf::Socket::Done :
253 OnData(rpac);
254 break;
256 //case sf::Socket::Disconnected :
257 default :
258 m_is_running = false;
259 NetPlay_Disable();
260 AppendChatGUI("< LOST CONNECION TO SERVER >");
261 PanicAlert("Lost connection to server!");
262 m_do_loop = false;
263 break;
268 m_socket.Close();
270 return;
273 // called from ---GUI--- thread
274 void NetPlayClient::GetPlayerList(std::string &list)
276 CritLocker player_lock(m_crit.players); // lock players
278 std::ostringstream ss;
280 std::map<PlayerId, Player>::const_iterator
281 i = m_players.begin(),
282 e = m_players.end();
283 for ( ; i!=e; ++i)
284 ss << i->second.ToString() << '\n';
286 list = ss.str();
290 // called from ---GUI--- thread
291 void NetPlayClient::SendChatMessage(const std::string& msg)
293 sf::Packet spac;
294 spac << (MessageId)NP_MSG_CHAT_MESSAGE;
295 spac << msg;
297 m_crit.send.Enter(); // lock send
298 m_socket.Send(spac);
299 m_crit.send.Leave();
302 // called from ---CPU--- thread
303 void NetPlayClient::SendPadState(const PadMapping local_nb, const NetPad& np)
305 // send to server
306 sf::Packet spac;
307 spac << (MessageId)NP_MSG_PAD_DATA;
308 spac << local_nb; // local pad num
309 spac << np.nHi << np.nLo;
311 m_crit.send.Enter(); // lock send
312 m_socket.Send(spac);
313 m_crit.send.Leave();
316 // called from ---GUI--- thread
317 bool NetPlayClient::StartGame(const std::string &path)
319 m_crit.buffer.Enter(); // lock buffer
321 if (false == NetPlay::StartGame(path))
322 return false;
324 // TODO: i dont like this here
325 ClearBuffers();
326 m_crit.buffer.Leave();
328 // tell server i started the game
329 sf::Packet spac;
330 spac << (MessageId)NP_MSG_START_GAME;
331 spac << m_on_game;
333 m_crit.send.Enter(); // lock send
334 m_socket.Send(spac);
335 m_crit.send.Leave();
337 return true;
340 // called from ---GUI--- thread
341 bool NetPlayClient::ChangeGame(const std::string &game)
343 // warning removal
344 game.size();
346 return true;