4 // called from ---GUI--- thread
5 NetPlayClient::~NetPlayClient()
10 m_thread
->WaitForDeath();
15 // called from ---GUI--- thread
16 NetPlayClient::NetPlayClient(const std::string
& address
, const u16 port
, const std::string
& name
, NetPlayDiag
* const npd
)
21 // why is false successful? documentation says true is
22 if (0 == m_socket
.Connect(port
, address
))
24 // send connect message
26 spac
<< NETPLAY_VERSION
;
27 spac
<< NETPLAY_DOLPHIN_VER
;
32 // TODO: make this not hang
33 m_socket
.Receive(rpac
);
42 case CON_ERR_SERVER_FULL
:
43 PanicAlert("The server is full!");
45 case CON_ERR_VERSION_MISMATCH
:
46 PanicAlert("The server and client's NetPlay versions are incompatible!");
48 case CON_ERR_GAME_RUNNING
:
49 PanicAlert("The server responded: the game is currently running!");
52 PanicAlert("The server sent an unknown error message!");
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
];
72 //PanicAlert("Connection successful: assigned player id: %d", m_pid);
75 m_selector
.Add(m_socket
);
76 m_thread
= new Common::Thread(NetPlayThreadFunc
, this);
80 PanicAlert("Failed to Connect!");
84 // called from ---NETPLAY--- thread
85 unsigned int NetPlayClient::OnData(sf::Packet
& packet
)
92 case NP_MSG_PLAYER_JOIN
:
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();
107 case NP_MSG_PLAYER_LEAVE
:
112 m_crit
.players
.Enter(); // lock players
113 m_players
.erase(m_players
.find(pid
));
114 m_crit
.players
.Leave();
120 case NP_MSG_CHAT_MESSAGE
:
127 // don't need lock to read in this thread
128 const Player
& player
= m_players
[pid
];
131 std::ostringstream ss
;
132 ss
<< player
.name
<< '[' << (char)(pid
+'0') << "]: " << msg
;
134 AppendChatGUI(ss
.str());
138 case NP_MSG_PAD_MAPPING
:
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();
154 case NP_MSG_PAD_DATA
:
158 packet
>> map
>> np
.nHi
>> np
.nLo
;
160 // trusting server for good map value (>=0 && <4)
162 m_crit
.buffer
.Enter(); // lock buffer
163 m_pad_buffer
[(unsigned)map
].push(np
);
164 m_crit
.buffer
.Leave();
168 case NP_MSG_PAD_BUFFER
:
173 m_crit
.buffer
.Enter(); // lock buffer
174 m_target_buffer_size
= size
;
175 m_crit
.buffer
.Leave();
179 case NP_MSG_CHANGE_GAME
:
182 m_crit
.game
.Enter(); // lock game state
183 packet
>> m_selected_game
;
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
);
194 case NP_MSG_START_GAME
:
198 wxCommandEvent
evt(wxEVT_THREAD
, NP_GUI_EVT_START_GAME
);
199 m_dialog
->GetEventHandler()->AddPendingEvent(evt
);
203 case NP_MSG_STOP_GAME
:
205 wxCommandEvent
evt(wxEVT_THREAD
, NP_GUI_EVT_STOP_GAME
);
206 m_dialog
->GetEventHandler()->AddPendingEvent(evt
);
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;
225 spac
<< (MessageId
)NP_MSG_PONG
;
228 CritLocker
send_lock(m_crit
.send
);
234 PanicAlert("Unknown message received with id : %d", mid
);
242 // called from ---NETPLAY--- thread
243 void NetPlayClient::Entry()
247 if (m_selector
.Wait(0.01f
))
250 switch (m_socket
.Receive(rpac
))
252 case sf::Socket::Done
:
256 //case sf::Socket::Disconnected :
258 m_is_running
= false;
260 AppendChatGUI("< LOST CONNECION TO SERVER >");
261 PanicAlert("Lost connection to server!");
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(),
284 ss
<< i
->second
.ToString() << '\n';
290 // called from ---GUI--- thread
291 void NetPlayClient::SendChatMessage(const std::string
& msg
)
294 spac
<< (MessageId
)NP_MSG_CHAT_MESSAGE
;
297 m_crit
.send
.Enter(); // lock send
302 // called from ---CPU--- thread
303 void NetPlayClient::SendPadState(const PadMapping local_nb
, const NetPad
& np
)
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
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
))
324 // TODO: i dont like this here
326 m_crit
.buffer
.Leave();
328 // tell server i started the game
330 spac
<< (MessageId
)NP_MSG_START_GAME
;
333 m_crit
.send
.Enter(); // lock send
340 // called from ---GUI--- thread
341 bool NetPlayClient::ChangeGame(const std::string
&game
)