From bc1b00e4370b688d9a2ce03f13cb2f769a17ad37 Mon Sep 17 00:00:00 2001 From: Charles Lohr Date: Wed, 30 Nov 2005 04:04:21 +0000 Subject: [PATCH] Allow for broadcast reception, so users can see all currently running SMLAN servers on a network easily. This code may be very active in the next few days depending on bugs we find. --- stepmania/src/NetworkSyncManager.cpp | 54 +++++++++++++++++++++++++- stepmania/src/NetworkSyncManager.h | 11 ++++++ stepmania/src/NetworkSyncServer.cpp | 1 + stepmania/src/ScreenNetworkOptions.cpp | 24 +++++++++++- stepmania/src/ScreenNetworkOptions.h | 1 + 5 files changed, 89 insertions(+), 2 deletions(-) diff --git a/stepmania/src/NetworkSyncManager.cpp b/stepmania/src/NetworkSyncManager.cpp index f8c094b7d3..1bf0d21e0c 100644 --- a/stepmania/src/NetworkSyncManager.cpp +++ b/stepmania/src/NetworkSyncManager.cpp @@ -27,6 +27,7 @@ void NetworkSyncManager::SendChat(const CString& message) { } void NetworkSyncManager::SelectUserSong() { } CString NetworkSyncManager::MD5Hex( const CString &sInput ) { return CString(); } int NetworkSyncManager::GetSMOnlineSalt() { return 0; } +void NetworkSyncManager::GetListOfLANServers( vector& AllServers ) { } #else #include "ezsockets.h" #include "ProfileManager.h" @@ -58,6 +59,7 @@ int NetworkSyncManager::GetSMOnlineSalt() NetworkSyncManager::NetworkSyncManager( LoadingWindow *ld ) { LANserver = NULL; //So we know if it has been created yet + BroadcastReception = NULL; if( GetCommandlineArgument( "runserver" )) { @@ -91,7 +93,13 @@ NetworkSyncManager::~NetworkSyncManager () //Close Connection to server nicely. if (useSMserver) NetPlayerClient->close(); - delete NetPlayerClient; + SAFE_DELETE( NetPlayerClient ); + + if ( BroadcastReception ) + { + BroadcastReception->close(); + SAFE_DELETE( BroadcastReception ); + } if( isLanServer ) { @@ -236,6 +244,10 @@ void NetworkSyncManager::StartUp() else if( GetCommandlineArgument( "listen" ) ) PostStartUp("LISTEN"); + BroadcastReception = new EzSockets; + BroadcastReception->create( IPPROTO_UDP ); + BroadcastReception->bind( 8765 ); + BroadcastReception->blocking = false; } @@ -517,6 +529,41 @@ void NetworkSyncManager::Update(float fDeltaTime) if (useSMserver) ProcessInput(); + + PacketFunctions BroadIn; + if ( BroadcastReception->ReadPack( (char*)&BroadIn.Data, 1020 ) ) + { + NetServerInfo ThisServer; + BroadIn.Position = 0; + if ( BroadIn.Read1() == 141 ) + { + ThisServer.Name = BroadIn.ReadNT(); + int port = BroadIn.Read2(); + BroadIn.Read2(); //Num players connected. + unsigned long addy = ntohl(BroadcastReception->fromAddr.sin_addr.S_un.S_addr); + ThisServer.Address = ssprintf( "%d.%d.%d.%d:%d", + (addy<<0)>>24, (addy<<8)>>24, (addy<<16)>>24, (addy<<24)>>24, port ); + + //It's fairly safe to assume that users will not be on networks with more than + //30 or 40 servers. Until this point, maps would be slower than vectors. + //So I am going to use a vector to store all of the servers. + // + //In this situation, I will traverse the vector to find the element that + //contains the corresponding server. + + unsigned int i; + for ( i = 0; i < m_vAllLANServers.size(); i++ ) + { + if ( m_vAllLANServers[i].Address == ThisServer.Address ) + { + m_vAllLANServers[i].Name = ThisServer.Name; + break; + } + } + if ( i >= m_vAllLANServers.size() ) + m_vAllLANServers.push_back( ThisServer ); + } + } } void NetworkSyncManager::ProcessInput() @@ -866,6 +913,11 @@ CString NetworkSyncManager::MD5Hex( const CString &sInput ) return HashedName; } +void NetworkSyncManager::GetListOfLANServers( vector& AllServers ) +{ + AllServers = m_vAllLANServers; +} + static bool ConnectToServer( const CString &t ) { NSMAN->PostStartUp( t ); diff --git a/stepmania/src/NetworkSyncManager.h b/stepmania/src/NetworkSyncManager.h index 71342b9aa7..c7e917f66f 100644 --- a/stepmania/src/NetworkSyncManager.h +++ b/stepmania/src/NetworkSyncManager.h @@ -52,6 +52,12 @@ enum NSScoreBoardColumn }; #define FOREACH_NSScoreBoardColumn( sc ) FOREACH_ENUM( NSScoreBoardColumn, NUM_NSSB_CATEGORIES, sc ) +struct NetServerInfo +{ + CString Name; + CString Address; +}; + class EzSockets; class StepManiaLanServer; @@ -147,6 +153,8 @@ public: int GetSMOnlineSalt(); CString MD5Hex( const CString &sInput ); + + void GetListOfLANServers( vector< NetServerInfo > & AllServers ); private: #if !defined(WITHOUT_NETWORKING) @@ -170,6 +178,9 @@ private: CString m_ServerName; EzSockets *NetPlayerClient; + EzSockets *BroadcastReception; + + vector< NetServerInfo > m_vAllLANServers; int m_ServerVersion; //ServerVersion diff --git a/stepmania/src/NetworkSyncServer.cpp b/stepmania/src/NetworkSyncServer.cpp index 436dd13094..4c346eb106 100644 --- a/stepmania/src/NetworkSyncServer.cpp +++ b/stepmania/src/NetworkSyncServer.cpp @@ -1001,6 +1001,7 @@ void StepManiaLanServer::BroadcastInfo() { PacketFunctions Binfo; Binfo.ClearPacket(); + Binfo.Write1( 141 ); //Code 13 + 128 Binfo.WriteNT( servername ); Binfo.Write2( 8765 ); Binfo.Write2( Client.size() ); diff --git a/stepmania/src/ScreenNetworkOptions.cpp b/stepmania/src/ScreenNetworkOptions.cpp index 368339ad1f..43232630b2 100644 --- a/stepmania/src/ScreenNetworkOptions.cpp +++ b/stepmania/src/ScreenNetworkOptions.cpp @@ -16,6 +16,7 @@ enum { PO_CONNECTION, PO_SERVER, PO_SCOREBOARD, + PO_SERVERS, NUM_NETWORK_OPTIONS_LINES }; @@ -33,7 +34,8 @@ enum OptionRowDefinition g_NetworkOptionsLines[NUM_NETWORK_OPTIONS_LINES] = { OptionRowDefinition( "Connection", true, "PRESS START" ), OptionRowDefinition( "Server", true, "PRESS START" ), - OptionRowDefinition( "Scoreboard", true, "PRESS START" ) + OptionRowDefinition( "Scoreboard", true, "PRESS START" ), + OptionRowDefinition( "Servers", true, "PRESS START" ) }; AutoScreenMessage( SM_DoneConnecting ) @@ -65,6 +67,17 @@ void ScreenNetworkOptions::Init() g_NetworkOptionsLines[PO_SCOREBOARD].m_vsChoices.push_back("Off"); g_NetworkOptionsLines[PO_SCOREBOARD].m_vsChoices.push_back("On"); + //Get info on all received servers from NSMAN. + g_NetworkOptionsLines[PO_SERVERS].m_vsChoices.clear(); + g_NetworkOptionsLines[PO_SERVERS].m_bAllowThemeItems = false; + + NSMAN->GetListOfLANServers( AllServers ); + if ( AllServers.size() == 0 ) + g_NetworkOptionsLines[PO_SERVERS].m_vsChoices.push_back( "-none-" ); + + for ( unsigned int j = 0; j < AllServers.size(); j++ ) + g_NetworkOptionsLines[PO_SERVERS].m_vsChoices.push_back( AllServers[j].Name ); + //Enable all lines for all players for ( unsigned int i = 0; i < NUM_NETWORK_OPTIONS_LINES; i++ ) FOREACH_PlayerNumber( pn ) @@ -154,6 +167,15 @@ void ScreenNetworkOptions::MenuStart( const InputEventPlus &input ) else PREFSMAN->m_bEnableScoreboard.Set(false); break; + case PO_SERVERS: + if ( AllServers.size() != 0 ) + { + string sNewName = AllServers[m_pRows[GetCurrentRow()]->GetOneSharedSelection()].Address; + NSMAN->PostStartUp(sNewName); + NSMAN->DisplayStartupStatus(); + UpdateConnectStatus( ); + } + break; default: ScreenOptions::MenuStart( input ); } diff --git a/stepmania/src/ScreenNetworkOptions.h b/stepmania/src/ScreenNetworkOptions.h index 9f65e00846..6bce88c51b 100644 --- a/stepmania/src/ScreenNetworkOptions.h +++ b/stepmania/src/ScreenNetworkOptions.h @@ -16,6 +16,7 @@ public: private: void ImportOptions( int iRow, const vector &vpns ); void ExportOptions( int iRow, const vector &vpns ); + vector AllServers; void UpdateConnectStatus(); };