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