@@ -92,12 +92,18 @@ class CHTTPServerThread : public CThread
9292 " getingame"
9393 },
9494 m_UnprivilegedEvents{
95- " closedmenu"
95+ " ingame" ,
96+ " gsi"
9697 }
9798 {
9899 SetName (" GameStateHTTPThread" );
99100 }
100101
102+ int64_t GetClientId ( crow::websocket::connection& conn )
103+ {
104+ return *static_cast <int64_t *>( conn.userdata () );
105+ }
106+
101107 // Return 0 for success
102108 virtual int Run () OVERRIDE
103109 {
@@ -122,7 +128,7 @@ class CHTTPServerThread : public CThread
122128 AUTO_LOCK ( m_clientsMutex )
123129 int64_t clientId = m_iNextClientId++;
124130 *userdata = new int64_t (clientId);
125- if ( m_iPrivilegedClientId == - 1 )
131+ if ( m_iPrivilegedClientId == 0 )
126132 {
127133 m_iPrivilegedClientId = clientId;
128134 }
@@ -145,8 +151,9 @@ class CHTTPServerThread : public CThread
145151 int64_t clientId = *userdata;
146152 if ( m_iPrivilegedClientId == clientId )
147153 {
148- m_iPrivilegedClientId = - 1 ;
154+ m_iPrivilegedClientId = 0 ;
149155 }
156+ m_SubscribedClientIds.erase ( clientId );
150157 for ( std::size_t i = 0 ; i < size; i++ )
151158 {
152159 if ( *static_cast <int64_t *>( m_connectedClients[i]->userdata () ) == clientId )
@@ -207,16 +214,43 @@ class CHTTPServerThread : public CThread
207214 Assert ( 0 );
208215 m_connectedClients.push_back ( &conn );
209216 }
217+ int64_t clientId = GetClientId ( conn );
210218 if ( !V_strcmp (strCommand.c_str (), " disconnect" ) )
211219 {
212220 // immediately send back a message for closing
213- crow::json::wvalue dcResp;
214- dcResp[" i" ] = id;
215- conn.send_text ( dcResp.dump () );
216- m_iPrivilegedClientId = -1 ;
221+ crow::json::wvalue resp;
222+ resp[" i" ] = id;
223+ conn.send_text ( resp.dump () );
224+ m_iPrivilegedClientId = 0 ;
225+ return ;
226+ }
227+ if ( !V_strcmp ( strCommand.c_str (), " subscribe" ) )
228+ {
229+ // immediately send back a message for subscribing
230+ crow::json::wvalue resp;
231+ resp[" i" ] = id;
232+ conn.send_text ( resp.dump () );
233+ if ( m_iPrivilegedClientId != clientId )
234+ {
235+ m_SubscribedClientIds.insert ( clientId );
236+ }
237+ GetGameStateManager ()->InitSubscriptions ();
217238 return ;
218239 }
219- bIsPrivileged = m_iPrivilegedClientId == *static_cast <int64_t *>( conn.userdata () );
240+ if ( !V_strcmp ( strCommand.c_str (), " unsubscribe" ) )
241+ {
242+ // immediately send back a message for unsubscribing
243+ crow::json::wvalue resp;
244+ resp[" i" ] = id;
245+ conn.send_text ( resp.dump () );
246+ m_SubscribedClientIds.erase ( clientId );
247+ if ( m_SubscribedClientIds.size () < 1 )
248+ {
249+ GetGameStateManager ()->StopSubscriptions ();
250+ }
251+ return ;
252+ }
253+ bIsPrivileged = m_iPrivilegedClientId == clientId;
220254 }
221255
222256 std::string params;
@@ -425,8 +459,10 @@ class CHTTPServerThread : public CThread
425459 std::unordered_set<std::string> m_UnprivilegedMethods;
426460 std::unordered_set<std::string> m_UnprivilegedEvents;
427461
462+ std::unordered_set<int64_t > m_SubscribedClientIds;
463+
428464 int64_t m_iNextClientId = 1 ;
429- int64_t m_iPrivilegedClientId = - 1 ;
465+ int64_t m_iPrivilegedClientId = 0 ;
430466
431467 std::vector<crow::websocket::connection*> m_connectedClients;
432468 CThreadMutex m_clientsMutex;
@@ -636,8 +672,17 @@ void CGameStateManager::Shutdown()
636672 m_pServerThread = NULL ;
637673}
638674
675+ void CGameStateManager::FireGameEvent (IGameEvent* event)
676+ {
677+ const char * pszEvent = event->GetName ();
678+ std::string data = pszEvent;
679+ data += " " ;
680+ KeyValuesDumpAsString ( event->GetDataKeys (), &data );
681+ QueueEvent ( " gsi" , data );
682+ }
683+
639684void CGameStateManager::RegisterMethod (std::string methodName,
640- const std::function<std::string(const std::string& params)>& method)
685+ const std::function<std::string(const std::string& params)>& method)
641686{
642687 if (!m_bInit)
643688 return ;
@@ -666,3 +711,59 @@ void CGameStateManager::QueueEvent(const std::string& strEvent, const std::strin
666711
667712 m_pServerThread->QueueEvent (strEvent, strParams);
668713}
714+
715+ void CGameStateManager::InitSubscriptions ()
716+ {
717+ if ( m_bListeningToEvents )
718+ return ;
719+
720+ m_bListeningToEvents = true ;
721+
722+ ListenForGameEvent ( " game_newmap" );
723+ ListenForGameEvent ( " player_connect" );
724+ ListenForGameEvent ( " player_disconnect" );
725+ ListenForGameEvent ( " player_changeclass" );
726+ ListenForGameEvent ( " player_team" );
727+ ListenForGameEvent ( " player_info" );
728+ ListenForGameEvent ( " player_death" );
729+ ListenForGameEvent ( " player_spawn" );
730+ ListenForGameEvent ( " player_hurt" );
731+ ListenForGameEvent ( " round_start" );
732+ ListenForGameEvent ( " round_end" );
733+ ListenForGameEvent ( " server_spawn" );
734+ ListenForGameEvent ( " client_disconnect" );
735+ ListenForGameEvent ( " controlpoint_starttouch" );
736+ ListenForGameEvent ( " controlpoint_endtouch" );
737+ ListenForGameEvent ( " ctf_flag_captured" );
738+ ListenForGameEvent ( " teamplay_broadcast_audio" );
739+ ListenForGameEvent ( " teamplay_capture_blocked" );
740+ ListenForGameEvent ( " teamplay_flag_event" );
741+ ListenForGameEvent ( " teamplay_game_over" );
742+ ListenForGameEvent ( " teamplay_point_captured" );
743+ ListenForGameEvent ( " teamplay_round_stalemate" );
744+ ListenForGameEvent ( " teamplay_round_start" );
745+ ListenForGameEvent ( " teamplay_round_win" );
746+ ListenForGameEvent ( " teamplay_timer_time_added" );
747+ ListenForGameEvent ( " teamplay_update_timer" );
748+ ListenForGameEvent ( " teamplay_win_panel" );
749+ ListenForGameEvent ( " teamplay_setup_finished" );
750+ ListenForGameEvent ( " teamplay_alert" );
751+ ListenForGameEvent ( " teamplay_teambalanced_player" );
752+ ListenForGameEvent ( " teamplay_point_startcapture" );
753+ ListenForGameEvent ( " teamplay_round_active" );
754+ ListenForGameEvent ( " tf_game_over" );
755+ ListenForGameEvent ( " object_destroyed" );
756+ ListenForGameEvent ( " object_detonated" );
757+ ListenForGameEvent ( " tournament_stateupdate" );
758+ ListenForGameEvent ( " num_cappers_changed" );
759+ }
760+
761+ void CGameStateManager::StopSubscriptions ()
762+ {
763+ if ( !m_bListeningToEvents )
764+ return ;
765+
766+ m_bListeningToEvents = false ;
767+
768+ StopListeningForAllEvents ();
769+ }
0 commit comments