mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-13 03:33:48 +00:00
Preliminary IPV6 Support
This commit is contained in:
parent
1a851f167d
commit
704577e051
22 changed files with 1712 additions and 592 deletions
|
|
@ -177,7 +177,7 @@ static Vector<Ping> gQueryList(__FILE__, __LINE__);
|
|||
|
||||
struct PacketStatus
|
||||
{
|
||||
U8 index;
|
||||
U16 index;
|
||||
S32 key;
|
||||
U32 time;
|
||||
U32 tryCount;
|
||||
|
|
@ -191,6 +191,9 @@ struct PacketStatus
|
|||
time = _time;
|
||||
tryCount = gPacketRetryCount;
|
||||
}
|
||||
|
||||
inline U8 getOldIndex() { return (U8)index; }
|
||||
inline U16 getIndex() { return index; }
|
||||
};
|
||||
|
||||
static Vector<PacketStatus> gPacketStatusList(__FILE__, __LINE__);
|
||||
|
|
@ -212,6 +215,7 @@ struct ServerFilter
|
|||
OnlineQuery = 0, // Authenticated with master
|
||||
OfflineQuery = BIT(0), // On our own
|
||||
NoStringCompress = BIT(1),
|
||||
NewStyleResponse = BIT(2), // Include IPV6 servers
|
||||
};
|
||||
|
||||
enum // Filter flags:
|
||||
|
|
@ -222,6 +226,14 @@ struct ServerFilter
|
|||
CurrentVersion = BIT(7),
|
||||
NotXenon = BIT(6)
|
||||
};
|
||||
|
||||
enum // Region mask flags
|
||||
{
|
||||
RegionIsIPV4Address = BIT(30),
|
||||
RegionIsIPV6Address = BIT(31),
|
||||
|
||||
RegionAddressMask = RegionIsIPV4Address | RegionIsIPV6Address
|
||||
};
|
||||
|
||||
//Rearranging the fields according to their sizes
|
||||
char* gameType;
|
||||
|
|
@ -241,7 +253,7 @@ struct ServerFilter
|
|||
ServerFilter()
|
||||
{
|
||||
type = Normal;
|
||||
queryFlags = 0;
|
||||
queryFlags = NewStyleResponse;
|
||||
gameType = NULL;
|
||||
missionType = NULL;
|
||||
minPlayers = 0;
|
||||
|
|
@ -401,10 +413,17 @@ void queryLanServers(U32 port, U8 flags, const char* gameType, const char* missi
|
|||
|
||||
NetAddress addr;
|
||||
char addrText[256];
|
||||
|
||||
// IPV4
|
||||
dSprintf( addrText, sizeof( addrText ), "IP:BROADCAST:%d", port );
|
||||
Net::stringToAddress( addrText, &addr );
|
||||
pushPingBroadcast( &addr );
|
||||
|
||||
// IPV6
|
||||
dSprintf(addrText, sizeof(addrText), "IP6:MULTICAST:%d", port);
|
||||
Net::stringToAddress(addrText, &addr);
|
||||
pushPingBroadcast(&addr);
|
||||
|
||||
Con::executef("onServerQueryStatus", "start", "Querying LAN servers", "0");
|
||||
processPingsAndQueries( gPingSession );
|
||||
}
|
||||
|
|
@ -502,7 +521,7 @@ void queryMasterServer(U8 flags, const char* gameType, const char* missionType,
|
|||
dStrcpy( sActiveFilter.missionType, missionType );
|
||||
}
|
||||
|
||||
sActiveFilter.queryFlags = flags;
|
||||
sActiveFilter.queryFlags = flags | ServerFilter::NewStyleResponse;
|
||||
sActiveFilter.minPlayers = minPlayers;
|
||||
sActiveFilter.maxPlayers = maxPlayers;
|
||||
sActiveFilter.maxBots = maxBots;
|
||||
|
|
@ -519,6 +538,7 @@ void queryMasterServer(U8 flags, const char* gameType, const char* missionType,
|
|||
sActiveFilter.type = ServerFilter::Buddy;
|
||||
sActiveFilter.buddyCount = buddyCount;
|
||||
sActiveFilter.buddyList = (U32*) dRealloc( sActiveFilter.buddyList, buddyCount * 4 );
|
||||
sActiveFilter.queryFlags = ServerFilter::NewStyleResponse;
|
||||
dMemcpy( sActiveFilter.buddyList, buddyList, buddyCount * 4 );
|
||||
clearServerList();
|
||||
}
|
||||
|
|
@ -775,7 +795,7 @@ Vector<MasterInfo>* getMasterServerList()
|
|||
U32 region = 1; // needs to default to something > 0
|
||||
dSscanf(master,"%d:",®ion);
|
||||
const char* madd = dStrchr(master,':') + 1;
|
||||
if (region && Net::stringToAddress(madd,&address)) {
|
||||
if (region && Net::stringToAddress(madd,&address) == Net::NoError) {
|
||||
masterList.increment();
|
||||
MasterInfo& info = masterList.last();
|
||||
info.address = address;
|
||||
|
|
@ -1171,10 +1191,13 @@ static void processMasterServerQuery( U32 session )
|
|||
// Send a request to the master server for the server list:
|
||||
BitStream *out = BitStream::getPacketStream();
|
||||
out->clearStringBuffer();
|
||||
|
||||
out->write( U8( NetInterface::MasterServerListRequest ) );
|
||||
|
||||
out->write( U8( sActiveFilter.queryFlags) );
|
||||
out->write( ( gMasterServerPing.session << 16 ) | ( gMasterServerPing.key & 0xFFFF ) );
|
||||
out->write( U8( 255 ) );
|
||||
|
||||
writeCString( out, sActiveFilter.gameType );
|
||||
writeCString( out, sActiveFilter.missionType );
|
||||
out->write( sActiveFilter.minPlayers );
|
||||
|
|
@ -1359,23 +1382,35 @@ static void processServerListPackets( U32 session )
|
|||
if ( !p.tryCount )
|
||||
{
|
||||
// Packet timed out :(
|
||||
Con::printf( "Server list packet #%d timed out.", p.index + 1 );
|
||||
Con::printf( "Server list packet #%d timed out.", p.getIndex() + 1 );
|
||||
gPacketStatusList.erase( i );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try again...
|
||||
Con::printf( "Rerequesting server list packet #%d...", p.index + 1 );
|
||||
Con::printf( "Rerequesting server list packet #%d...", p.getIndex() + 1 );
|
||||
p.tryCount--;
|
||||
p.time = currentTime;
|
||||
p.key = gKey++;
|
||||
|
||||
BitStream *out = BitStream::getPacketStream();
|
||||
bool extendedPacket = (sActiveFilter.queryFlags & ServerFilter::NewStyleResponse) != 0;
|
||||
|
||||
out->clearStringBuffer();
|
||||
out->write( U8( NetInterface::MasterServerListRequest ) );
|
||||
|
||||
if ( extendedPacket )
|
||||
out->write( U8( NetInterface::MasterServerExtendedListRequest ) );
|
||||
else
|
||||
out->write( U8( NetInterface::MasterServerListRequest ) );
|
||||
|
||||
out->write( U8( sActiveFilter.queryFlags ) ); // flags
|
||||
out->write( ( session << 16) | ( p.key & 0xFFFF ) );
|
||||
out->write( p.index ); // packet index
|
||||
|
||||
if ( extendedPacket )
|
||||
out->write( p.getOldIndex() ); // packet index
|
||||
else
|
||||
out->write( p.getIndex() ); // packet index
|
||||
|
||||
out->write( U8( 0 ) ); // game type
|
||||
out->write( U8( 0 ) ); // mission type
|
||||
out->write( U8( 0 ) ); // minPlayers
|
||||
|
|
@ -1569,6 +1604,98 @@ static void handleMasterServerListResponse( BitStream* stream, U32 key, U8 /*fla
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void handleExtendedMasterServerListResponse(BitStream* stream, U32 key, U8 /*flags*/)
|
||||
{
|
||||
U16 packetIndex, packetTotal;
|
||||
U32 i;
|
||||
U16 serverCount, port;
|
||||
U8 netNum[16];
|
||||
char addressBuffer[256];
|
||||
NetAddress addr;
|
||||
|
||||
stream->read(&packetIndex);
|
||||
// Validate the packet key:
|
||||
U32 packetKey = gMasterServerPing.key;
|
||||
if (gGotFirstListPacket)
|
||||
{
|
||||
for (i = 0; i < gPacketStatusList.size(); i++)
|
||||
{
|
||||
if (gPacketStatusList[i].index == packetIndex)
|
||||
{
|
||||
packetKey = gPacketStatusList[i].key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U32 testKey = (gPingSession << 16) | (packetKey & 0xFFFF);
|
||||
if (testKey != key)
|
||||
return;
|
||||
|
||||
stream->read(&packetTotal);
|
||||
stream->read(&serverCount);
|
||||
|
||||
Con::printf("Received server list packet %d of %d from the master server (%d servers).", (packetIndex + 1), packetTotal, serverCount);
|
||||
|
||||
// Enter all of the servers in this packet into the ping list:
|
||||
for (i = 0; i < serverCount; i++)
|
||||
{
|
||||
U8 type;
|
||||
stream->read(&type);
|
||||
dMemset(&addr, '\0', sizeof(NetAddress));
|
||||
|
||||
if (type == 0)
|
||||
{
|
||||
// IPV4
|
||||
addr.type = NetAddress::IPAddress;
|
||||
stream->read(4, &addr.address.ipv4.netNum[0]);
|
||||
stream->read(&addr.port);
|
||||
}
|
||||
else
|
||||
{
|
||||
// IPV6
|
||||
addr.type = NetAddress::IPV6Address;
|
||||
stream->read(16, &addr.address.ipv6.netNum[0]);
|
||||
stream->read(&addr.port);
|
||||
}
|
||||
|
||||
pushPingRequest(&addr);
|
||||
}
|
||||
|
||||
// If this is the first list packet we have received, fill the packet status list
|
||||
// and start processing:
|
||||
if (!gGotFirstListPacket)
|
||||
{
|
||||
gGotFirstListPacket = true;
|
||||
gMasterServerQueryAddress = gMasterServerPing.address;
|
||||
U32 currentTime = Platform::getVirtualMilliseconds();
|
||||
for (i = 0; i < packetTotal; i++)
|
||||
{
|
||||
if (i != packetIndex)
|
||||
{
|
||||
PacketStatus* p = new PacketStatus(i, gMasterServerPing.key, currentTime);
|
||||
gPacketStatusList.push_back(*p);
|
||||
}
|
||||
}
|
||||
|
||||
processServerListPackets(gPingSession);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove the packet we just received from the status list:
|
||||
for (i = 0; i < gPacketStatusList.size(); i++)
|
||||
{
|
||||
if (gPacketStatusList[i].index == packetIndex)
|
||||
{
|
||||
gPacketStatusList.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void handleGameMasterInfoRequest( const NetAddress* address, U32 key, U8 flags )
|
||||
{
|
||||
if ( GNet->doesAllowConnections() )
|
||||
|
|
@ -1585,7 +1712,7 @@ static void handleGameMasterInfoRequest( const NetAddress* address, U32 key, U8
|
|||
for(U32 i = 0; i < masterList->size(); i++)
|
||||
{
|
||||
masterAddr = &(*masterList)[i].address;
|
||||
if (*(U32*)(masterAddr->netNum) == *(U32*)(address->netNum))
|
||||
if (masterAddr->isSameAddress(*address))
|
||||
{
|
||||
fromMaster = true;
|
||||
break;
|
||||
|
|
@ -2098,6 +2225,10 @@ void DemoNetInterface::handleInfoPacket( const NetAddress* address, U8 packetTyp
|
|||
case GameMasterInfoRequest:
|
||||
handleGameMasterInfoRequest( address, key, flags );
|
||||
break;
|
||||
|
||||
case MasterServerExtendedListResponse:
|
||||
handleExtendedMasterServerListResponse(stream, key, flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue