1 /* Copyright (C) 2007 The SpringLobby Team. All rights reserved. */
2 //
3 // Class: ServerEvents
4 //
5
6 #ifdef _MSC_VER
7 #ifndef NOMINMAX
8 #define NOMINMAX
9 #endif // NOMINMAX
10 #include <winsock2.h>
11 #endif // _MSC_VER
12
13 #include <wx/intl.h>
14 #include <stdexcept>
15
16 #include "serverevents.h"
17 #include "mainwindow.h"
18 #include "ui.h"
19 #include "channel/channel.h"
20 #include "user.h"
21 #include "utils/debug.h"
22 #include "uiutils.h"
23 #include "server.h"
24 #include <downloader/httpdownloader.h>
25 #include "settings.h"
26 #include "utils/customdialogs.h"
27 #include "utils/tasutil.h"
28 #include "utils/uievents.h"
29
30 #include <lslutils/globalsmanager.h>
31
BEGIN_EVENT_TABLE(ServerEvents,wxEvtHandler)32 BEGIN_EVENT_TABLE(ServerEvents, wxEvtHandler)
33 EVT_COMMAND(wxID_ANY, httpDownloadEvtComplete, ServerEvents::OnSpringDownloadEvent)
34 EVT_COMMAND(wxID_ANY, httpDownloadEvtFailed, ServerEvents::OnSpringDownloadEvent)
35 END_EVENT_TABLE()
36
37 void ServerEvents::OnConnected( const wxString& server_name, const wxString& server_ver, bool supported, const wxString& server_spring_ver, bool /*unused*/ )
38 {
39 wxLogDebugFunc( server_ver + _T(" ") + server_spring_ver );
40 //Server version will include patchlevel from release 89 onwards
41 m_serv.SetRequiredSpring( server_spring_ver.BeforeFirst('.') );
42 ui().OnConnected( m_serv, server_name, server_ver, supported );
43 m_serv.Login();
44 }
45
46
OnDisconnected(bool wasonline)47 void ServerEvents::OnDisconnected( bool wasonline )
48 {
49 wxLogDebugFunc( wxEmptyString );
50 m_serv.SetRequiredSpring (wxEmptyString);
51 ui().OnDisconnected( m_serv, wasonline );
52 }
53
54
OnLogin()55 void ServerEvents::OnLogin()
56 {
57 }
58
59
OnLoginInfoComplete()60 void ServerEvents::OnLoginInfoComplete()
61 {
62 wxLogDebugFunc( wxEmptyString );
63 wxString nick = m_serv.GetMe().GetNick();
64 wxArrayString highlights = sett().GetHighlightedWords();
65 if ( highlights.Index( nick ) == -1 )
66 {
67 highlights.Add( nick );
68 sett().SetHighlightedWords( highlights );
69 }
70 //m_serv.RequestChannels();
71 GlobalEvent::Send(GlobalEvent::OnLogin);
72 std::vector<ChannelJoinInfo> autojoin = sett().GetChannelsJoin();
73 for ( std::vector<ChannelJoinInfo>::const_iterator itor = autojoin.begin(); itor != autojoin.end(); ++itor )
74 {
75 if ( itor->name.IsEmpty() )
76 continue;
77 Channel& chan = m_serv._AddChannel( itor->name );
78 chan.SetPassword( itor->password );
79 ui().OnJoinedChannelSuccessful( chan, itor == autojoin.begin() );
80 }
81 for ( std::vector<ChannelJoinInfo>::const_iterator itor = autojoin.begin(); itor != autojoin.end(); ++itor )
82 m_serv.JoinChannel( itor->name, itor->password );
83
84 ui().OnLoggedIn( );
85 }
86
87
OnLogout()88 void ServerEvents::OnLogout()
89 {
90 //wxLogDebugFunc( wxEmptyString );
91 }
92
93
OnUnknownCommand(const wxString & command,const wxString & params)94 void ServerEvents::OnUnknownCommand( const wxString& command, const wxString& params )
95 {
96 wxLogDebugFunc( wxEmptyString );
97 ui().OnUnknownCommand( m_serv, command, params );
98 }
99
100
OnSocketError(const Sockerror &)101 void ServerEvents::OnSocketError( const Sockerror& /*unused*/ )
102 {
103 //wxLogDebugFunc( wxEmptyString );
104 }
105
106
OnProtocolError(const Protocolerror)107 void ServerEvents::OnProtocolError( const Protocolerror /*unused*/ )
108 {
109 //wxLogDebugFunc( wxEmptyString );
110 }
111
112
OnMotd(const wxString & msg)113 void ServerEvents::OnMotd( const wxString& msg )
114 {
115 wxLogDebugFunc( wxEmptyString );
116 ui().OnMotd( m_serv, msg );
117 }
118
119
OnPong(wxLongLong ping_time)120 void ServerEvents::OnPong( wxLongLong ping_time )
121 {
122 //wxLongLong is non-POD and cannot be passed to wxFormat as such. use c-string rep instead. converting to long might loose precision
123 UiEvents::StatusData data( wxString::Format( _("ping: %s ms"), ping_time.ToString().c_str() ), 2 );
124 UiEvents::GetStatusEventSender( UiEvents::addStatusMessage ).SendEvent( data );
125 }
126
127
OnNewUser(const wxString & nick,const wxString & country,int cpu,const wxString & id)128 void ServerEvents::OnNewUser( const wxString& nick, const wxString& country, int cpu, const wxString& id )
129 {
130 wxLogDebugFunc( wxEmptyString );
131 try
132 {
133 ASSERT_LOGIC( !m_serv.UserExists( nick ), _T("New user from server, but already exists!") );
134 }
135 catch (...)
136 {
137 return;
138 }
139 User& user = m_serv._AddUser( nick );
140 if ( useractions().DoActionOnUser( UserActions::ActNotifLogin, nick ) )
141 actNotifBox( SL_MAIN_ICON, nick + _(" is online") );
142 user.SetCountry( country );
143 user.SetCpu( cpu );
144 user.SetID( id );
145 ui().OnUserOnline( user );
146 }
147
148
OnUserStatus(const wxString & nick,UserStatus status)149 void ServerEvents::OnUserStatus( const wxString& nick, UserStatus status )
150 {
151 wxLogDebugFunc( wxEmptyString );
152 try
153 {
154 wxLogMessage( _T("calling m_serv.GetUser( nick ) ") );
155 User& user = m_serv.GetUser( nick );
156 wxLogMessage( _T("calling user.SetStatus( status ) ") );
157
158 UserStatus oldStatus = user.GetStatus();
159 user.SetStatus( status );
160 if ( useractions().DoActionOnUser( UserActions::ActNotifStatus, nick ) )
161 {
162 wxString diffString = status.GetDiffString( oldStatus ) ;
163 if ( diffString != wxEmptyString )
164 actNotifBox( SL_MAIN_ICON, nick + _(" is now ") + diffString );
165 }
166
167 wxLogMessage( _T("calling ui().OnUserStatusChanged( user ) ") );
168 ui().OnUserStatusChanged( user );
169 wxLogMessage( _T("updating battles ") );
170
171 if ( user.GetBattle() != 0 )
172 {
173 Battle& battle = *user.GetBattle();
174 try
175 {
176 if ( battle.GetFounder().GetNick() == user.GetNick() )
177 {
178 if ( status.in_game != battle.GetInGame() )
179 {
180 battle.SetInGame( status.in_game );
181 if ( status.in_game ) battle.StartSpring();
182 else
183 BattleEvents::GetBattleEventSender( BattleEvents::BattleInfoUpdate ).SendEvent( std::make_pair(user.GetBattle(),wxString()) );
184 }
185 }
186 }catch(...){}
187 }
188 }
189 catch (...)
190 {
191 wxLogWarning( _("OnUserStatus() failed ! (exception)") );
192 }
193 }
194
195
OnUserQuit(const wxString & nick)196 void ServerEvents::OnUserQuit( const wxString& nick )
197 {
198 wxLogDebugFunc( wxEmptyString );
199 try
200 {
201 User &user=m_serv.GetUser( nick );
202 Battle* userbattle = user.GetBattle();
203 if ( userbattle )
204 {
205 int battleid = userbattle->GetID();
206 try
207 {
208 if ( &userbattle->GetFounder() == &user )
209 {
210 for ( int i = 0; i < int(userbattle->GetNumUsers()); i ++ )
211 {
212 User& battleuser = userbattle->GetUser( i );
213 OnUserLeftBattle( battleid, battleuser.GetNick() );
214 }
215 OnBattleClosed( battleid );
216 }
217 else OnUserLeftBattle( battleid, user.GetNick() );
218 }catch(...){}
219 }
220 ui().OnUserOffline( user );
221 m_serv._RemoveUser( nick );
222 if ( useractions().DoActionOnUser( UserActions::ActNotifLogin, nick ) )
223 actNotifBox( SL_MAIN_ICON, nick + _(" just went offline") );
224 }
225 catch (std::runtime_error &except)
226 {
227 }
228 }
229
230
OnBattleOpenedEx(int id,BattleType type,NatType nat,const wxString & nick,const wxString & host,int port,int maxplayers,bool haspass,int rank,const wxString & maphash,const wxString & engineName,const wxString & engineVersion,const wxString & map,const wxString & title,const wxString & mod)231 void ServerEvents::OnBattleOpenedEx( int id, BattleType type, NatType nat, const wxString& nick,
232 const wxString& host, int port, int maxplayers,
233 bool haspass, int rank, const wxString& maphash, const wxString& engineName, const wxString& engineVersion, const wxString& map,
234 const wxString& title, const wxString& mod )
235 {
236 wxLogDebugFunc( wxEmptyString );
237 try
238 {
239 ASSERT_EXCEPTION( !m_serv.BattleExists( id ), _T("New battle from server, but already exists!") );
240 Battle& battle = m_serv._AddBattle( id );
241
242 User& user = m_serv.GetUser( nick );
243 battle.OnUserAdded( user );
244
245 battle.SetBattleType( type );
246 battle.SetNatType( nat );
247 battle.SetFounder( nick );
248 battle.SetHostIp( host );
249 battle.SetHostPort( port );
250 battle.SetMaxPlayers( maxplayers );
251 battle.SetIsPassworded( haspass );
252 battle.SetRankNeeded( rank );
253 battle.SetHostMap( map, maphash );
254 battle.SetDescription( title );
255 battle.SetHostMod( mod, wxEmptyString );
256 battle.SetEngineName(engineName);
257 battle.SetEngineVersion(engineVersion);
258
259 if ( useractions().DoActionOnUser( UserActions::ActNotifBattle, user.GetNick() ) )
260 actNotifBox( SL_MAIN_ICON, user.GetNick() + _(" opened battle ") + title );
261
262 ui().OnBattleOpened( battle );
263 if ( user.Status().in_game )
264 {
265 battle.SetInGame( true );
266 battle.StartSpring();
267 }
268 }
269 catch (std::runtime_error &except)
270 {
271 }
272 }
273
274
OnJoinedBattle(int battleid,const wxString & hash)275 void ServerEvents::OnJoinedBattle( int battleid, const wxString& hash )
276 {
277 wxLogDebugFunc( wxEmptyString );
278 try
279 {
280 Battle& battle = m_serv.GetBattle( battleid );
281
282 battle.SetHostMod( battle.GetHostModName(), hash );
283 UserBattleStatus& bs = m_serv.GetMe().BattleStatus();
284 bs.spectator = false;
285
286 if ( !battle.IsFounderMe() || battle.IsProxy() )
287 {
288 battle.CustomBattleOptions().loadOptions(LSL::OptionsWrapper::MapOption, STD_STRING(battle.GetHostMapName()));
289 battle.CustomBattleOptions().loadOptions(LSL::OptionsWrapper::ModOption, STD_STRING(battle.GetHostModName()));
290 }
291
292 ui().OnJoinedBattle( battle );
293 }
294 catch (std::runtime_error &except)
295 {
296 }
297 }
298
299
OnHostedBattle(int battleid)300 void ServerEvents::OnHostedBattle( int battleid )
301 {
302 wxLogDebugFunc( wxEmptyString );
303 try
304 {
305 Battle& battle = m_serv.GetBattle( battleid );
306
307 if ( battle.GetBattleType() == BT_Played )
308 {
309 battle.CustomBattleOptions().loadOptions(LSL::OptionsWrapper::MapOption, STD_STRING(battle.GetHostMapName()));
310 battle.CustomBattleOptions().loadOptions(LSL::OptionsWrapper::ModOption, STD_STRING(battle.GetHostModName()));
311 }
312 else
313 {
314 battle.GetBattleFromScript( true );
315 }
316
317
318 wxString presetname = sett().GetModDefaultPresetName( battle.GetHostModName() );
319 if ( !presetname.IsEmpty() )
320 {
321 battle.LoadOptionsPreset( presetname );
322 }
323
324 battle.LoadMapDefaults( battle.GetHostMapName() );
325
326 m_serv.SendHostInfo( IBattle::HI_Send_All_opts );
327
328 ui().OnHostedBattle( battle );
329 }
330 catch (assert_exception) {}
331 }
332
333
OnStartHostedBattle(int battleid)334 void ServerEvents::OnStartHostedBattle( int battleid )
335 {
336 wxLogDebugFunc( wxEmptyString );
337 Battle& battle = m_serv.GetBattle( battleid );
338 battle.SetInGame( true );
339 battle.StartSpring();
340 }
341
342
OnClientBattleStatus(int battleid,const wxString & nick,UserBattleStatus status)343 void ServerEvents::OnClientBattleStatus( int battleid, const wxString& nick, UserBattleStatus status )
344 {
345 try
346 {
347 Battle& battle = m_serv.GetBattle( battleid );
348 User& user = battle.GetUser( nick );
349
350 //if ( battle.IsFounderMe() ) AutoCheckCommandSpam( battle, user );
351
352 status.color_index = user.BattleStatus().color_index;
353 battle.OnUserBattleStatusUpdated( user, status );
354 }
355 catch (std::runtime_error &except)
356 {
357 }
358 }
359
360
OnUserJoinedBattle(int battleid,const wxString & nick,const wxString & userScriptPassword)361 void ServerEvents::OnUserJoinedBattle( int battleid, const wxString& nick, const wxString& userScriptPassword )
362 {
363 try
364 {
365 wxLogDebugFunc( wxEmptyString );
366 User& user = m_serv.GetUser( nick );
367 Battle& battle = m_serv.GetBattle( battleid );
368
369 battle.OnUserAdded( user );
370 user.BattleStatus().scriptPassword = userScriptPassword;
371 ui().OnUserJoinedBattle( battle, user );
372 try
373 {
374 if ( &user == &battle.GetFounder() )
375 {
376 if ( user.Status().in_game )
377 {
378 battle.SetInGame( true );
379 battle.StartSpring();
380 }
381 }
382 }catch(...){}
383 }
384 catch (std::runtime_error &except)
385 {
386 }
387 }
388
389
OnUserLeftBattle(int battleid,const wxString & nick)390 void ServerEvents::OnUserLeftBattle( int battleid, const wxString& nick )
391 {
392 wxLogDebugFunc( wxEmptyString );
393 try
394 {
395 Battle& battle = m_serv.GetBattle( battleid );
396 User& user = battle.GetUser( nick );
397 // this is necessary since the user will be deleted when the gui function is called
398 bool isbot = user.BattleStatus().IsBot();
399 user.BattleStatus().scriptPassword.Clear();
400 battle.OnUserRemoved( user );
401 ui().OnUserLeftBattle( battle, user, isbot );
402 }
403 catch (std::runtime_error &except)
404 {
405 }
406
407 }
408
409
OnBattleInfoUpdated(int battleid,int spectators,bool locked,const wxString & maphash,const wxString & map)410 void ServerEvents::OnBattleInfoUpdated( int battleid, int spectators, bool locked, const wxString& maphash, const wxString& map )
411 {
412 wxLogDebugFunc( wxEmptyString );
413 try
414 {
415 Battle& battle = m_serv.GetBattle( battleid );
416
417 battle.SetSpectators( spectators );
418 battle.SetIsLocked( locked );
419
420 wxString oldmap = battle.GetHostMapName();
421
422 battle.SetHostMap( map, maphash );
423
424 if ( (oldmap != map) && (battle.UserExists( m_serv.GetMe().GetNick())) )
425 {
426 battle.SendMyBattleStatus();
427 battle.CustomBattleOptions().loadOptions(LSL::OptionsWrapper::MapOption, STD_STRING(map));
428 battle.Update( wxString::Format( _T("%d_mapname"), LSL::OptionsWrapper::PrivateOptions ) );
429 }
430
431 BattleEvents::GetBattleEventSender( BattleEvents::BattleInfoUpdate ).SendEvent( std::make_pair(&battle,wxString()) );
432 }
433 catch (assert_exception) {}
434 }
435
OnSetBattleInfo(int battleid,const wxString & param,const wxString & value)436 void ServerEvents::OnSetBattleInfo( int battleid, const wxString& param, const wxString& value )
437 {
438 wxLogDebugFunc( param + _T(", ") + value );
439 try
440 {
441 Battle& battle = m_serv.GetBattle( battleid );
442 battle.m_script_tags[param] = value;
443 wxString key = param;
444 if ( key.Left( 5 ) == _T("game/") )
445 {
446 key = key.AfterFirst( '/' );
447 if ( key.Left( 11 ) == _T( "mapoptions/" ) )
448 {
449 key = key.AfterFirst( '/' );
450 battle.CustomBattleOptions().setSingleOption(STD_STRING(key), STD_STRING(value), LSL::OptionsWrapper::MapOption );
451 battle.Update( wxString::Format(_T("%d_%s"), LSL::OptionsWrapper::MapOption, key.c_str() ) );
452 }
453 else if ( key.Left( 11 ) == _T( "modoptions/" ) )
454 {
455 key = key.AfterFirst( '/' );
456 battle.CustomBattleOptions().setSingleOption(STD_STRING(key), STD_STRING(value), LSL::OptionsWrapper::ModOption );
457 battle.Update( wxString::Format(_T("%d_%s"), LSL::OptionsWrapper::ModOption, key.c_str() ) );
458 }
459 else if ( key.Left( 8 ) == _T( "restrict" ) )
460 {
461 OnBattleDisableUnit( battleid, key.AfterFirst(_T('/')), s2l(value) );
462 }
463 else if ( key.Left( 4 ) == _T( "team" ) && key.Find( _T("startpos") ) != wxNOT_FOUND )
464 {
465 int team = s2l( key.BeforeFirst(_T('/')).Mid( 4 ) );
466 if ( key.Find( _T("startposx") ) != wxNOT_FOUND )
467 {
468 int numusers = battle.GetNumUsers();
469 for ( int i = 0; i < numusers; i++ )
470 {
471 User& usr = battle.GetUser( i );
472 UserBattleStatus& status = usr.BattleStatus();
473 if ( status.team == team )
474 {
475 status.pos.x = s2l( value );
476 battle.OnUserBattleStatusUpdated( usr, status );
477 }
478 }
479 }
480 else if ( key.Find( _T("startposy") ) != wxNOT_FOUND )
481 {
482 int numusers = battle.GetNumUsers();
483 for ( int i = 0; i < numusers; i++ )
484 {
485 User& usr = battle.GetUser( i );
486 UserBattleStatus& status = usr.BattleStatus();
487 if ( status.team == team )
488 {
489 status.pos.y = s2l( value );
490 battle.OnUserBattleStatusUpdated( usr, status );
491 }
492 }
493 }
494 }
495 else
496 {
497 battle.CustomBattleOptions().setSingleOption( STD_STRING(key), STD_STRING(value), LSL::OptionsWrapper::EngineOption );
498 battle.Update( wxString::Format(_T("%d_%s"), LSL::OptionsWrapper::EngineOption, key.c_str() ) );
499 }
500 }
501 }
502 catch (assert_exception) {}
503 }
504
OnUnsetBattleInfo(int battleid,const wxString & param)505 void ServerEvents::OnUnsetBattleInfo( int battleid, const wxString& param)
506 {
507 //FIXME: implement this
508 }
509
510
OnBattleInfoUpdated(int battleid)511 void ServerEvents::OnBattleInfoUpdated( int battleid )
512 {
513 wxLogDebugFunc( wxEmptyString );
514 try
515 {
516 Battle& battle = m_serv.GetBattle( battleid );
517 BattleEvents::GetBattleEventSender( BattleEvents::BattleInfoUpdate ).SendEvent( std::make_pair(&battle,wxString()) );
518 }
519 catch ( assert_exception ) {}
520 }
521
522
OnBattleClosed(int battleid)523 void ServerEvents::OnBattleClosed( int battleid )
524 {
525 wxLogDebugFunc( wxEmptyString );
526 try
527 {
528 Battle& battle = m_serv.GetBattle( battleid );
529
530 ui().OnBattleClosed( battle );
531
532 m_serv._RemoveBattle( battleid );
533 }
534 catch ( assert_exception ) {}
535 }
536
537
OnBattleDisableUnit(int battleid,const wxString & unitname,int count)538 void ServerEvents::OnBattleDisableUnit( int battleid, const wxString& unitname, int count )
539 {
540 wxLogDebugFunc( wxEmptyString );
541 try
542 {
543 Battle& battle = m_serv.GetBattle( battleid );
544 battle.RestrictUnit( unitname, count );
545 battle.Update( wxString::Format( _T("%d_restrictions"), LSL::OptionsWrapper::PrivateOptions ) );
546 }
547 catch ( assert_exception ) {}
548 }
549
550
OnBattleEnableUnit(int battleid,const wxString & unitname)551 void ServerEvents::OnBattleEnableUnit( int battleid, const wxString& unitname )
552 {
553 wxLogDebugFunc( wxEmptyString );
554 try
555 {
556 Battle& battle = m_serv.GetBattle( battleid );
557 battle.UnrestrictUnit( unitname );
558 battle.Update( wxString::Format( _T("%d_restrictions"), LSL::OptionsWrapper::PrivateOptions ) );
559 }
560 catch ( assert_exception ) {}
561 }
562
563
OnBattleEnableAllUnits(int battleid)564 void ServerEvents::OnBattleEnableAllUnits( int battleid )
565 {
566 wxLogDebugFunc( wxEmptyString );
567 try
568 {
569 Battle& battle = m_serv.GetBattle( battleid );
570 battle.UnrestrictAllUnits();
571 battle.Update( wxString::Format( _T("%d_restrictions"), LSL::OptionsWrapper::PrivateOptions ) );
572 }
573 catch ( assert_exception ) {}
574 }
575
576
OnJoinChannelResult(bool success,const wxString & channel,const wxString & reason)577 void ServerEvents::OnJoinChannelResult( bool success, const wxString& channel, const wxString& reason )
578 {
579 wxLogDebugFunc( wxEmptyString );
580 if ( success )
581 {
582 Channel& chan = m_serv._AddChannel( channel );
583 chan.SetPassword( m_serv.m_channel_pw[channel] );
584 ui().OnJoinedChannelSuccessful( chan );
585
586 }
587 else
588 {
589 ui().ShowMessage( _("Join channel failed"), _("Could not join channel ") + channel + _(" because: ") + reason );
590 }
591 }
592
593
OnChannelSaid(const wxString & channel,const wxString & who,const wxString & message)594 void ServerEvents::OnChannelSaid( const wxString& channel, const wxString& who, const wxString& message )
595 {
596 wxLogDebugFunc( wxEmptyString );
597 try
598 {
599 if ( ( m_serv.GetMe().GetNick() == who ) || !useractions().DoActionOnUser( UserActions::ActIgnoreChat, who ) )
600 m_serv.GetChannel( channel ).Said( m_serv.GetUser( who ), message );
601 }
602 catch (std::runtime_error &except)
603 {
604 }
605 }
606
607
OnChannelJoin(const wxString & channel,const wxString & who)608 void ServerEvents::OnChannelJoin( const wxString& channel, const wxString& who )
609 {
610 wxLogDebugFunc( wxEmptyString );
611 try
612 {
613 m_serv.GetChannel( channel ).OnChannelJoin( m_serv.GetUser( who ) );
614 }
615 catch (std::runtime_error &except)
616 {
617 }
618 }
619
620
OnChannelPart(const wxString & channel,const wxString & who,const wxString & message)621 void ServerEvents::OnChannelPart( const wxString& channel, const wxString& who, const wxString& message )
622 {
623 wxLogDebugFunc( wxEmptyString );
624 try
625 {
626 m_serv.GetChannel( channel ).Left( m_serv.GetUser( who ), message );
627 }
628 catch (std::runtime_error &except)
629 {
630 }
631 }
632
633
OnChannelTopic(const wxString & channel,const wxString & who,const wxString & message,int)634 void ServerEvents::OnChannelTopic( const wxString& channel, const wxString& who, const wxString& message, int /*unused*/ )
635 {
636 wxLogDebugFunc( wxEmptyString );
637 try
638 {
639 m_serv.GetChannel( channel ).SetTopic( message, who );
640 }
641 catch (std::runtime_error &except)
642 {
643 }
644 }
645
646
OnChannelAction(const wxString & channel,const wxString & who,const wxString & action)647 void ServerEvents::OnChannelAction( const wxString& channel, const wxString& who, const wxString& action )
648 {
649 wxLogDebugFunc( wxEmptyString );
650 try
651 {
652 if ( ( m_serv.GetMe().GetNick() == who ) || !useractions().DoActionOnUser( UserActions::ActIgnoreChat, who ) )
653 m_serv.GetChannel( channel ).DidAction( m_serv.GetUser( who ), action );
654 }
655 catch (std::runtime_error &except)
656 {
657 }
658 }
659
660
OnPrivateMessage(const wxString & user,const wxString & message,bool fromme)661 void ServerEvents::OnPrivateMessage( const wxString& user, const wxString& message, bool fromme )
662 {
663 wxLogDebugFunc( wxEmptyString );
664 try
665 {
666 User& who = m_serv.GetUser( user );
667 if (!useractions().DoActionOnUser( UserActions::ActIgnorePM, who.GetNick() ) )
668 ui().OnUserSaid( who, message, fromme );
669 }
670 catch (std::runtime_error &except)
671 {
672 }
673 }
674
OnPrivateMessageEx(const wxString & user,const wxString & action,bool fromme)675 void ServerEvents::OnPrivateMessageEx( const wxString& user, const wxString& action, bool fromme )
676 {
677 wxLogDebugFunc( wxEmptyString );
678 try
679 {
680 User& who = m_serv.GetUser( user );
681 if (!useractions().DoActionOnUser( UserActions::ActIgnorePM, who.GetNick() ) )
682 ui().OnUserSaidEx( who, action, fromme );
683 }
684 catch (std::runtime_error &except)
685 {
686 }
687 }
688
OnChannelList(const wxString & channel,const int & numusers,const wxString & topic)689 void ServerEvents::OnChannelList( const wxString& channel, const int& numusers, const wxString& topic )
690 {
691 ui().mw().OnChannelList( channel, numusers, topic );
692 }
693
694
OnUserJoinChannel(const wxString & channel,const wxString & who)695 void ServerEvents::OnUserJoinChannel( const wxString& channel, const wxString& who )
696 {
697 wxLogDebugFunc( wxEmptyString );
698 try
699 {
700 m_serv.GetChannel( channel ).Joined( m_serv.GetUser( who ) );
701 }
702 catch (std::runtime_error &except)
703 {
704 }
705 }
706
707
OnRequestBattleStatus(int battleid)708 void ServerEvents::OnRequestBattleStatus( int battleid )
709 {
710 try
711 {
712 Battle& battle = m_serv.GetBattle( battleid );
713 ui().OnRequestBattleStatus( battle );
714 }
715 catch (assert_exception) {}
716 }
717
718
OnSaidBattle(int battleid,const wxString & nick,const wxString & msg)719 void ServerEvents::OnSaidBattle( int battleid, const wxString& nick, const wxString& msg )
720 {
721 try
722 {
723 Battle& battle = m_serv.GetBattle( battleid );
724 if ( ( m_serv.GetMe().GetNick() == nick ) || !useractions().DoActionOnUser( UserActions::ActIgnoreChat, nick ) )
725 {
726 ui().OnSaidBattle( battle, nick, msg );
727 }
728 battle.GetAutoHost().OnSaidBattle( nick, msg );
729 }
730 catch (assert_exception) {}
731 }
732
OnBattleAction(int,const wxString & nick,const wxString & msg)733 void ServerEvents::OnBattleAction( int /*battleid*/, const wxString& nick, const wxString& msg )
734 {
735 try
736 {
737 UiEvents::GetUiEventSender( UiEvents::OnBattleActionEvent ).SendEvent(
738 UiEvents::OnBattleActionData( nick, msg )
739 );
740 }
741 catch (assert_exception) {}
742 }
743
744
OnBattleStartRectAdd(int battleid,int allyno,int left,int top,int right,int bottom)745 void ServerEvents::OnBattleStartRectAdd( int battleid, int allyno, int left, int top, int right, int bottom )
746 {
747 try
748 {
749 Battle& battle = m_serv.GetBattle( battleid );
750 battle.AddStartRect( allyno, left, top, right, bottom );
751 battle.StartRectAdded( allyno );
752 battle.Update( wxString::Format( _T("%d_mapname"), LSL::OptionsWrapper::PrivateOptions ) );
753 }
754 catch (assert_exception) {}
755 }
756
757
OnBattleStartRectRemove(int battleid,int allyno)758 void ServerEvents::OnBattleStartRectRemove( int battleid, int allyno )
759 {
760 try
761 {
762 Battle& battle = m_serv.GetBattle( battleid );
763 battle.RemoveStartRect( allyno );
764 battle.StartRectRemoved( allyno );
765 battle.Update( wxString::Format( _T("%d_mapname"), LSL::OptionsWrapper::PrivateOptions ) );
766 }
767 catch (assert_exception) {}
768 }
769
770
OnBattleAddBot(int battleid,const wxString & nick,UserBattleStatus status)771 void ServerEvents::OnBattleAddBot( int battleid, const wxString& nick, UserBattleStatus status )
772 {
773 wxLogDebugFunc( wxEmptyString );
774 try
775 {
776 Battle& battle = m_serv.GetBattle( battleid );
777 battle.OnBotAdded( nick, status );
778 User& bot = battle.GetUser( nick );
779 ASSERT_LOGIC( &bot != 0, _T("Bot null after add.") );
780 ui().OnUserJoinedBattle( battle, bot );
781 }
782 catch (assert_exception) {}
783 }
784
OnBattleUpdateBot(int battleid,const wxString & nick,UserBattleStatus status)785 void ServerEvents::OnBattleUpdateBot( int battleid, const wxString& nick, UserBattleStatus status )
786 {
787 OnClientBattleStatus( battleid, nick, status );
788 }
789
790
OnBattleRemoveBot(int battleid,const wxString & nick)791 void ServerEvents::OnBattleRemoveBot( int battleid, const wxString& nick )
792 {
793 wxLogDebugFunc( wxEmptyString );
794 try
795 {
796 Battle& battle = m_serv.GetBattle( battleid );
797 User& user = battle.GetUser( nick );
798 bool isbot = user.BattleStatus().IsBot();
799 ui().OnUserLeftBattle( battle, user, isbot );
800 battle.OnUserRemoved( user );
801 }
802 catch (std::runtime_error &except)
803 {
804 }
805 }
806
807
OnAcceptAgreement(const wxString & agreement)808 void ServerEvents::OnAcceptAgreement( const wxString& agreement )
809 {
810 ui().OnAcceptAgreement( agreement );
811 }
812
813
OnRing(const wxString & from)814 void ServerEvents::OnRing( const wxString& from )
815 {
816 ui().OnRing( from );
817 }
818
OnServerBroadcast(const wxString & message)819 void ServerEvents::OnServerBroadcast( const wxString& message )
820 {
821 ui().OnServerBroadcast( m_serv, message );
822 }
823
OnServerMessage(const wxString & message)824 void ServerEvents::OnServerMessage( const wxString& message )
825 {
826 ui().OnServerMessage( m_serv, message );
827 }
828
829
OnServerMessageBox(const wxString & message)830 void ServerEvents::OnServerMessageBox( const wxString& message )
831 {
832 ui().ShowMessage( _("Server Message"), message );
833 }
834
835
OnChannelMessage(const wxString & channel,const wxString & msg)836 void ServerEvents::OnChannelMessage( const wxString& channel, const wxString& msg )
837 {
838 ui().OnChannelMessage( channel, msg );
839 }
840
841
OnHostExternalUdpPort(const unsigned int udpport)842 void ServerEvents::OnHostExternalUdpPort( const unsigned int udpport )
843 {
844 if ( !m_serv.GetCurrentBattle() ) return;
845 if ( m_serv.GetCurrentBattle()->GetNatType() == NAT_Hole_punching || m_serv.GetCurrentBattle()->GetNatType() == NAT_Fixed_source_ports ) m_serv.GetCurrentBattle()->SetHostPort( udpport );
846 }
847
848
OnMyInternalUdpSourcePort(const unsigned int udpport)849 void ServerEvents::OnMyInternalUdpSourcePort( const unsigned int udpport )
850 {
851 if ( !m_serv.GetCurrentBattle() ) return;
852 m_serv.GetCurrentBattle()->SetMyInternalUdpSourcePort(udpport);
853 }
854
855
OnMyExternalUdpSourcePort(const unsigned int udpport)856 void ServerEvents::OnMyExternalUdpSourcePort( const unsigned int udpport )
857 {
858 if ( !m_serv.GetCurrentBattle() ) return;
859 m_serv.GetCurrentBattle()->SetMyExternalUdpSourcePort(udpport);
860 }
861
OnClientIPPort(const wxString & username,const wxString & ip,unsigned int udpport)862 void ServerEvents::OnClientIPPort( const wxString &username, const wxString &ip, unsigned int udpport )
863 {
864 wxLogMessage(_T("OnClientIPPort(%s,%s,%d)"),username.c_str(),ip.c_str(),udpport);
865 if ( !m_serv.GetCurrentBattle() )
866 {
867 wxLogMessage(_T("GetCurrentBattle() returned null"));
868 return;
869 }
870 try
871 {
872 User &user=m_serv.GetCurrentBattle()->GetUser( username );
873
874 user.BattleStatus().ip=ip;
875 user.BattleStatus().udpport=udpport;
876 wxLogMessage(_T("set to %s %d "),user.BattleStatus().ip.c_str(),user.BattleStatus().udpport);
877
878 if (sett().GetShowIPAddresses()) {
879 UiEvents::GetUiEventSender( UiEvents::OnBattleActionEvent ).SendEvent(
880 UiEvents::OnBattleActionData( username,wxString::Format(_(" has ip=%s"),ip.c_str()) )
881 );
882 }
883
884 if (m_serv.GetCurrentBattle()->GetNatType() != NAT_None && (udpport==0))
885 {
886 // todo: better warning message
887 //something.OutputLine( _T(" ** ") + who.GetNick() + _(" does not support nat traversal! ") + GetChatTypeStr() + _T("."), sett().GetChatColorJoinPart(), sett().GetChatFont() );
888 UiEvents::GetUiEventSender( UiEvents::OnBattleActionEvent ).SendEvent(
889 UiEvents::OnBattleActionData( username,_(" does not really support nat traversal") )
890 );
891
892 }
893 m_serv.GetCurrentBattle()->CheckBan(user);
894 }
895 catch (std::runtime_error)
896 {
897 wxLogMessage(_T("runtime_error inside OnClientIPPort()"));
898 }
899 }
900
901
OnKickedFromBattle()902 void ServerEvents::OnKickedFromBattle()
903 {
904 customMessageBoxNoModal(SL_MAIN_ICON,_("You were kicked from the battle!"),_("Kicked by Host"));
905 }
906
907
OnRedirect(const wxString & address,unsigned int port,const wxString & CurrentNick,const wxString & CurrentPassword)908 void ServerEvents::OnRedirect( const wxString& address, unsigned int port, const wxString& CurrentNick, const wxString& CurrentPassword )
909 {
910 wxString name = address + _T(":") + TowxString(port);
911 sett().SetServer( name, address, port );
912 ui().DoConnect( name, CurrentNick, CurrentPassword );
913 }
914
915
AutoCheckCommandSpam(Battle & battle,User & user)916 void ServerEvents::AutoCheckCommandSpam( Battle& battle, User& user )
917 {
918 wxString nick = user.GetNick();
919 MessageSpamCheck info = m_spam_check[nick];
920 time_t now = time( 0 );
921 if ( info.lastmessage == now ) info.count++;
922 else info.count = 0;
923 info.lastmessage = now;
924 m_spam_check[nick] = info;
925 if ( info.count == 7 )
926 {
927 battle.DoAction( _T("is autokicking ") + nick + _T(" due to command spam.") );
928 battle.KickPlayer( user );
929 }
930 }
931
OnMutelistBegin(const wxString & channel)932 void ServerEvents::OnMutelistBegin( const wxString& channel )
933 {
934 mutelistWindow( _("Begin mutelist for ") + channel, wxString::Format( _("%s mutelist"), channel.c_str() ) );
935 }
936
OnMutelistItem(const wxString &,const wxString & mutee,const wxString & description)937 void ServerEvents::OnMutelistItem( const wxString& /*unused*/, const wxString& mutee, const wxString& description )
938 {
939 wxString message = mutee;
940 wxString desc = description;
941 wxString mutetime = GetWordParam( desc );
942 long time;
943 if ( mutetime == _T("indefinite") ) message << _(" indefinite time remaining");
944 else if ( mutetime.ToLong(&time) ) message << wxString::Format( _(" %d minutes remaining"), time/60 + 1 );
945 else message << mutetime;
946 if ( !desc.IsEmpty() ) message << _T(", ") << desc;
947 mutelistWindow( message );
948 }
949
OnMutelistEnd(const wxString & channel)950 void ServerEvents::OnMutelistEnd( const wxString& channel )
951 {
952 mutelistWindow( _("End mutelist for ") + channel );
953 }
954
OnScriptStart(int battleid)955 void ServerEvents::OnScriptStart( int battleid )
956 {
957 if ( !m_serv.BattleExists( battleid ) )
958 {
959 return;
960 }
961 m_serv.GetBattle( battleid ).ClearScript();
962 }
963
OnScriptLine(int battleid,const wxString & line)964 void ServerEvents::OnScriptLine( int battleid, const wxString& line )
965 {
966 if ( !m_serv.BattleExists( battleid ) )
967 {
968 return;
969 }
970 m_serv.GetBattle( battleid ).AppendScriptLine( line );
971 }
972
OnScriptEnd(int battleid)973 void ServerEvents::OnScriptEnd( int battleid )
974 {
975 if ( !m_serv.BattleExists( battleid ) )
976 {
977 return;
978 }
979 m_serv.GetBattle( battleid ).GetBattleFromScript( true );
980 }
981
OnSpringDownloadEvent(wxCommandEvent & event)982 void ServerEvents::OnSpringDownloadEvent( wxCommandEvent& event )
983 {
984 int code = event.GetInt();
985 wxLogMessage(event.GetString());
986 if ( code != 0)
987 {
988 customMessageBox(SL_MAIN_ICON, _("There was an error downloading for the latest version.\n"), _("Error"));
989 wxString err;
990 switch (code)
991 {
992 case wxPROTO_NETERR:
993 err = _("Network Error");
994 break;
995 case wxPROTO_PROTERR:
996 err = _("Negotiation error");
997 break;
998 case wxPROTO_CONNERR:
999 err = _T("Failed to connect to server");
1000 break;
1001 case wxPROTO_INVVAL:
1002 err = _("Invalid Value");
1003 break;
1004 case wxPROTO_NOHNDLR:
1005 err = _("No Handler");
1006 break;
1007 case wxPROTO_NOFILE:
1008 err = _("File doesn't exit");
1009 break;
1010 case wxPROTO_ABRT:
1011 err = _("Action Aborted");
1012 break;
1013 case wxPROTO_RCNCT:
1014 err = _("Reconnection Error");
1015 break;
1016 default:
1017 err = _("Unknown Error");
1018 break;
1019 }
1020
1021 wxLogDebugFunc(_T("Error connecting! Error is: ") + err);
1022 customMessageBoxNoModal(SL_MAIN_ICON, _T("Error connecting! (") + err + _T(")\nPlease update manually from http://springrts.com"), wxEmptyString);
1023
1024 }
1025 else
1026 {
1027 wxString text = _("Download complete, location is: ") + m_savepath;
1028 if ( m_autoclose ) text += _("\nlobby will get closed now.");
1029 customMessageBox(SL_MAIN_ICON, text, _("Download complete.") );
1030 if ( m_autolaunch )
1031 {
1032 if ( !wxExecute( _T("\"") + m_savepath + _T("\""), wxEXEC_ASYNC ) )
1033 {
1034 customMessageBoxNoModal(SL_MAIN_ICON, _("Couldn't launch installer. File location is: ") + m_savepath, _("Couldn't launch installer.") );
1035 }
1036 }
1037 if ( m_autoclose )
1038 {
1039 ui().mw().Close();
1040 }
1041 }
1042 }
1043
OnForceJoinBattle(int battleid,const wxString & scriptPW)1044 void ServerEvents::OnForceJoinBattle(int battleid, const wxString &scriptPW)
1045 {
1046 if ( m_serv.GetCurrentBattle() )
1047 m_serv.GetCurrentBattle()->Leave();
1048 m_serv.JoinBattle( battleid, scriptPW );
1049 UiEvents::GetStatusEventSender( UiEvents::addStatusMessage ).SendEvent(
1050 UiEvents::StatusData( _("Automatically moved to new battle"), 1 ) );
1051 }
1052