Exemplo n.º 1
0
void ConnectionGraph::OnConnectionGraphRequest(Packet *packet)
{
	char password[256];
	RakNet::BitStream inBitstream(packet->data, packet->length, false);
	inBitstream.IgnoreBits(8);
	stringCompressor->DecodeString(password,256,&inBitstream);
	if (pw && pw[0] && strcmp(pw, password)!=0)
		return;

#ifdef _CONNECTION_GRAPH_DEBUG_PRINT
	RAKNET_DEBUG_PRINTF("ID_CONNECTION_GRAPH_REPLY ");
#endif

	RakNet::BitStream outBitstream;
	outBitstream.Write((MessageID)ID_CONNECTION_GRAPH_REPLY);
	stringCompressor->EncodeString(pw,256,&outBitstream);
	SerializeWeightedGraph(&outBitstream, graph);
	SendUnified(&outBitstream, LOW_PRIORITY, RELIABLE_ORDERED, connectionGraphChannel, packet->systemAddress, false);

#ifdef _CONNECTION_GRAPH_DEBUG_PRINT
	RAKNET_DEBUG_PRINTF("from %i to %i\n", peer->GetInternalID().port, packet->systemAddress.port);
#endif

	// Add packet->systemAddress to the participant list if it is not already there
	AddParticipant(packet->systemAddress);
}
void LightweightDatabaseServer::OnQueryRequest(RakPeerInterface *peer, Packet *packet)
{
	RakNet::BitStream inBitstream(packet->data, packet->length, false);
	LightweightDatabaseServer::DatabaseTable *databaseTable = DeserializeClientHeader(&inBitstream, peer, packet, 0);
	if (databaseTable==0)
		return;
	if (databaseTable->allowRemoteQuery==false)
		return;
	unsigned char numColumnSubset;
	RakNet::BitStream outBitstream;
	unsigned i;
	if (inBitstream.Read(numColumnSubset)==false)
		return;
	unsigned columnSubset[256];
	for (i=0; i < numColumnSubset; i++)
		inBitstream.Read(columnSubset[i]);
	unsigned char numNetworkedFilters;
	if (inBitstream.Read(numNetworkedFilters)==false)
		return;
	DatabaseFilter networkedFilters[256];
	for (i=0; i < numNetworkedFilters; i++)
	{
		if (networkedFilters[i].Deserialize(&inBitstream)==false)
			return;
	}

	unsigned rowIds[256];
	unsigned char numRowIDs;
	if (inBitstream.Read(numRowIDs)==false)
		return;
	for (i=0; i < numRowIDs; i++)
		inBitstream.Read(rowIds[i]);

	// Convert the safer and more robust networked database filter to the more efficient form the table actually uses.
	DataStructures::Table::FilterQuery tableFilters[256];
	unsigned numTableFilters=0;
	for (i=0; i < numNetworkedFilters; i++)
	{	
		tableFilters[numTableFilters].columnIndex=databaseTable->table.ColumnIndex(networkedFilters[i].columnName);
		if (tableFilters[numTableFilters].columnIndex==(unsigned)-1)
			continue;
		if (networkedFilters[i].columnType!=databaseTable->table.GetColumns()[tableFilters[numTableFilters].columnIndex].columnType)
			continue;
		tableFilters[numTableFilters].operation=networkedFilters[i].operation;
		// It's important that I store a pointer to the class here or the destructor of the class will deallocate the cell twice
		tableFilters[numTableFilters++].cellValue=&(networkedFilters[i].cellValue);
	}
    
	DataStructures::Table queryResult;
	databaseTable->table.QueryTable(columnSubset, numColumnSubset, tableFilters, numTableFilters, rowIds, numRowIDs, &queryResult);
	outBitstream.Write((unsigned char)ID_DATABASE_QUERY_REPLY);
	TableSerializer::SerializeTable(&queryResult, &outBitstream);
	peer->Send(&outBitstream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->playerId, false);			

}
void LightweightDatabaseServer::OnRemoveRow(RakPeerInterface *peer, Packet *packet)
{
	RakNet::BitStream inBitstream(packet->data, packet->length, false);
	LightweightDatabaseServer::DatabaseTable *databaseTable = DeserializeClientHeader(&inBitstream, peer, packet, 0);
	if (databaseTable==0)
		return;
	if (databaseTable->allowRemoteRemove==false)
		return;
	unsigned rowId;
	inBitstream.Read(rowId);
	databaseTable->table.RemoveRow(rowId);
}
Exemplo n.º 4
0
bool ConnectionGraph::OnConnectionLostInternal(Packet *packet, unsigned char packetId)
{
	// Only accept from participants
	if (participantList.HasData(packet->systemAddress)==false)
		return false;

	SystemAddress node1, node2;
	RakNet::BitStream inBitstream(packet->data, packet->length, false);
	inBitstream.IgnoreBits(8);
	// This is correct - group IDs are not written for removal, only addition.
	inBitstream.Read(node1);
	if (inBitstream.Read(node2)==false)
		return false;
	DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
	DeserializeIgnoreList(ignoreList, &inBitstream);
	ignoreList.Insert(packet->systemAddress, packet->systemAddress, false, __FILE__, __LINE__);
	
	return RemoveAndRelayConnection(ignoreList, packetId, node1, node2, rakPeerInterface);
}
Exemplo n.º 5
0
void ConnectionGraph::OnConnectionGraphUpdate(Packet *packet)
{
	// Only accept from participants
	if (participantList.HasData(packet->systemAddress)==false)
		return;

	RakNet::BitStream inBitstream(packet->data, packet->length, false);
	inBitstream.IgnoreBits(8);
	
	if (DeserializeWeightedGraph(&inBitstream, rakPeerInterface)==false)
		return;

	DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
	DeserializeIgnoreList(ignoreList, &inBitstream);

	// Forward the updated graph to all participants.
	ignoreList.Insert(packet->systemAddress,packet->systemAddress, false, __FILE__, __LINE__);
	BroadcastGraphUpdate(ignoreList, rakPeerInterface);
}
Exemplo n.º 6
0
void ConnectionGraph::OnConnectionGraphReply(Packet *packet)
{
	unsigned char password[256];
	RakNet::BitStream inBitstream(packet->data, packet->length, false);
	inBitstream.IgnoreBits(8);
	stringCompressor->DecodeString((char*)password,256,&inBitstream);
	if (pw && pw[0] && strcmp(pw, (const char*)password)!=0)
		return;

	// Serialize the weighted graph and send it to them
	RakNet::BitStream outBitstream;
	outBitstream.Write((MessageID)ID_CONNECTION_GRAPH_UPDATE);

#ifdef _CONNECTION_GRAPH_DEBUG_PRINT
	RAKNET_DEBUG_PRINTF("ID_CONNECTION_GRAPH_UPDATE ");
#endif

	// Send our current graph to the sender
	SerializeWeightedGraph(&outBitstream, graph);


	// Write the systems that have processed this graph so we don't resend to these systems
	outBitstream.Write((unsigned short) 1);
	outBitstream.Write(rakPeerInterface->GetExternalID(packet->systemAddress));

#ifdef _CONNECTION_GRAPH_DEBUG_PRINT
	RAKNET_DEBUG_PRINTF("from %i to %i\n", peer->GetInternalID().port, packet->systemAddress.port);
#endif

	SendUnified(&outBitstream, LOW_PRIORITY, RELIABLE_ORDERED, connectionGraphChannel, packet->systemAddress, false);

	// Add packet->systemAddress to the participant list if it is not already there
	AddParticipant(packet->systemAddress);

	if (DeserializeWeightedGraph(&inBitstream, rakPeerInterface)==false)
		return;

	// Forward the updated graph to all current participants
	DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
	ignoreList.Insert(packet->systemAddress,packet->systemAddress, true, __FILE__, __LINE__);
	BroadcastGraphUpdate(ignoreList, rakPeerInterface);
}
Exemplo n.º 7
0
void ConnectionGraph::OnNewConnectionInternal(Packet *packet)
{
	// Only accept from participants
	if (participantList.HasData(packet->systemAddress)==false)
		return;

	SystemAddressAndGroupId node1, node2;
	unsigned short ping;
	RakNet::BitStream inBitstream(packet->data, packet->length, false);
	inBitstream.IgnoreBits(8);
	inBitstream.Read(node1.systemAddress);
	inBitstream.Read(node1.groupId);
	inBitstream.Read(node1.guid);
	inBitstream.Read(node2.systemAddress);
	inBitstream.Read(node2.groupId);
	inBitstream.Read(node2.guid);
	if (inBitstream.Read(ping)==false)
		return;
	DataStructures::OrderedList<SystemAddress,SystemAddress> ignoreList;
	DeserializeIgnoreList(ignoreList, &inBitstream);
	ignoreList.Insert(packet->systemAddress,packet->systemAddress, false, __FILE__, __LINE__);
	AddAndRelayConnection(ignoreList, node1, node2, ping, rakPeerInterface);	
}
Exemplo n.º 8
0
PluginReceiveResult ReplicaManager::OnReceive(RakPeerInterface *peer, Packet *packet)
{
	unsigned char packetIdentifier;
	if ( ( unsigned char ) packet->data[ 0 ] == ID_TIMESTAMP )
	{
		if ( packet->length > sizeof( unsigned char ) + sizeof( unsigned int ) )
			packetIdentifier = ( unsigned char ) packet->data[ sizeof( unsigned char ) + sizeof( unsigned int ) ];
		else
			return RR_STOP_PROCESSING_AND_DEALLOCATE;
	}
	else
		packetIdentifier = ( unsigned char ) packet->data[ 0 ];

	switch (packetIdentifier)
	{
	case ID_NEW_INCOMING_CONNECTION:
	case ID_CONNECTION_REQUEST_ACCEPTED:
		if (autoParticipateNewConnections)
			AddParticipant(packet->playerId);
		return RR_CONTINUE_PROCESSING;
	case ID_DISCONNECTION_NOTIFICATION:
	case ID_CONNECTION_LOST:
		OnCloseConnection(peer, packet->playerId);
		return RR_CONTINUE_PROCESSING;
	case ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE:
		if (_receiveDownloadCompleteCB==0)
		{
			return RR_STOP_PROCESSING_AND_DEALLOCATE;
		}
	case ID_REPLICA_MANAGER_CONSTRUCTION:
	case ID_REPLICA_MANAGER_DESTRUCTION:
	case ID_REPLICA_MANAGER_SCOPE_CHANGE:
	case ID_REPLICA_MANAGER_SERIALIZE:
		{
			ParticipantStruct *participantStruct;
			bool hasNetworkId;
			ReceivedCommand receivedCommand;
			bool b=true;
			RakNet::BitStream inBitstream(packet->data, packet->length, false);
			// SetWriteOffset is used here to get around a design flaw, where I should have had the bitstream constructor take bits, rather than bytes
			// It sets the actual number of bits in the packet
			inBitstream.SetWriteOffset(packet->bitSize);
			receivedCommand.playerId=packet->playerId;
			receivedCommand.command=packetIdentifier;

			if ( ( unsigned char ) packet->data[ 0 ] == ID_TIMESTAMP )
			{
				inBitstream.IgnoreBits(8);
				b=inBitstream.Read(receivedCommand.u1);
			}
			else
				receivedCommand.u1=0;
			inBitstream.IgnoreBits(8); // Ignore the packet id
			receivedCommand.networkID=UNASSIGNED_NETWORK_ID;
			if (packetIdentifier==ID_REPLICA_MANAGER_CONSTRUCTION) // ID_REPLICA_MANAGER_CONSTRUCTION has an optional networkID
			{
				b=inBitstream.Read(hasNetworkId);
				if (hasNetworkId)
					b=inBitstream.Read(receivedCommand.networkID);
			}
			else if (packetIdentifier!=ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE)
			{
				b=inBitstream.Read(receivedCommand.networkID); // Other packets always have an networkID
			}

			if (b==false)
			{
				// Invalid packet
#ifdef _DEBUG
				assert(0);
#endif
				return RR_STOP_PROCESSING_AND_DEALLOCATE;
			}
			receivedCommand.userData=&inBitstream;
			participantStruct=GetParticipantByPlayerID(receivedCommand.playerId);
			if (participantStruct)
			{
				// .Size()>0 is because commands are always processed in order.  If a command is delayed, no further commands are processed.
				// ProcessReceivedCommand(...)==false means that the use signaled to delay a command
				if (participantStruct->pendingCommands.Size()>0 || ProcessReceivedCommand(participantStruct, &receivedCommand)==REPLICA_PROCESS_LATER)
				{
					// Copy the data and add this to a queue that will call ProcessReceivedCommand again in Update.

					// Allocate and copy structure
					ReceivedCommand *rc = new ReceivedCommand;
					memcpy(rc, &receivedCommand, sizeof(ReceivedCommand));

					// Allocate and copy inBitstream remaining data
					rc->userData = new RakNet::BitStream;
					rc->userData->Write(&inBitstream, inBitstream.GetNumberOfBitsUsed());

					participantStruct->pendingCommands.Push(rc);
				}
			}

			return RR_STOP_PROCESSING_AND_DEALLOCATE;
		}
	}

	return RR_CONTINUE_PROCESSING;
}
void LightweightDatabaseServer::OnUpdateRow(RakPeerInterface *peer, Packet *packet)
{
	RakNet::BitStream inBitstream(packet->data, packet->length, false);
	LightweightDatabaseServer::DatabaseTable *databaseTable = DeserializeClientHeader(&inBitstream, peer, packet, 1);
	if (databaseTable==0)
		return;
	if (databaseTable->allowRemoteUpdate==false)
		return;
	unsigned char updateMode;
	bool hasRowId;
	unsigned rowId;
	unsigned i;
	DataStructures::Table::Row *row;
	inBitstream.Read(updateMode);
	inBitstream.Read(hasRowId);
	if (hasRowId)
		inBitstream.Read(rowId);
	else
		rowId=(unsigned) -1; // Not used here but remove the debugging check
	unsigned char numCellUpdates;
	if (inBitstream.Read(numCellUpdates)==false)
		return;
	// Read the updates for the row
	DatabaseCellUpdate cellUpdates[256];
	for (i=0; i < numCellUpdates; i++)
	{
		if (cellUpdates[i].Deserialize(&inBitstream)==false)
			return;
	}

	if ((RowUpdateMode)updateMode==RUM_UPDATE_EXISTING_ROW)
	{
		if (hasRowId==false)
			return;

		row = databaseTable->table.GetRowByID(rowId);
		if (row==0 || databaseTable->onlyUpdateOwnRows && RowHasIP(row, packet->playerId, databaseTable->systemIdColumnIndex)==false)
			return; // You can't update some other system's row
	}
	else if ((RowUpdateMode)updateMode==RUM_UPDATE_OR_ADD_ROW)
	{
		if (hasRowId)
			row = databaseTable->table.GetRowByID(rowId);
		else
			row=0;

		if (row==0)
		{
			row=AddRow(databaseTable, packet->playerId, hasRowId, rowId);
			if (row==0)
				return;
		}
		else
		{
			// Existing row
			if (databaseTable->onlyUpdateOwnRows && RowHasIP(row, packet->playerId, databaseTable->systemIdColumnIndex)==false)
				return; // You can't update some other system's row
		}	
	}
	else
	{
		RakAssert((RowUpdateMode)updateMode==RUM_ADD_NEW_ROW);

		row=AddRow(databaseTable, packet->playerId, hasRowId, rowId);
		if (row==0)
			return;
	}

	unsigned columnIndex;
	for (i=0; i < numCellUpdates; i++)
	{
		columnIndex=databaseTable->table.ColumnIndex(cellUpdates[i].columnName);
		if (columnIndex!=(unsigned)-1 && columnIndex!=databaseTable->lastPingResponseColumnIndex && columnIndex!=databaseTable->nextPingSendColumnIndex && columnIndex!=databaseTable->systemIdColumnIndex)
		{
			if (cellUpdates[i].cellValue.isEmpty)
				row->cells[columnIndex]->Clear();
			else if (cellUpdates[i].columnType==databaseTable->table.GetColumnType(columnIndex))
			{
				if (cellUpdates[i].columnType==DataStructures::Table::NUMERIC)
				{
					row->UpdateCell(columnIndex, cellUpdates[i].cellValue.i);
				}
				else if (cellUpdates[i].columnType==DataStructures::Table::BINARY)
				{
					row->UpdateCell(columnIndex, cellUpdates[i].cellValue.i, cellUpdates[i].cellValue.c);
				}
				else
				{
					RakAssert(cellUpdates[i].columnType==DataStructures::Table::STRING);
					row->UpdateCell(columnIndex, cellUpdates[i].cellValue.c);
				}
			}
		}
	}
}
Exemplo n.º 10
0
void LightweightDatabaseServer::OnUpdateRow(Packet *packet)
	{
	RakNet::BitStream inBitstream(packet->data, packet->length, false);
	LightweightDatabaseServer::DatabaseTable *databaseTable = DeserializeClientHeader(&inBitstream, rakPeerInterface, packet, 1);
	if (databaseTable==0)
		{
		printf("ERROR: LightweightDatabaseServer::OnUpdateRow databaseTable==0\n");
		return;
		}
	if (databaseTable->allowRemoteUpdate==false)
		{
		printf("Warning: LightweightDatabaseServer::OnUpdateRow databaseTable->allowRemoteUpdate==false\n");
		return;
		}
	unsigned char updateMode;
	bool hasRowId=false;
	unsigned rowId;
	unsigned i;
	DataStructures::Table::Row *row;
	inBitstream.Read(updateMode);
	inBitstream.Read(hasRowId);
	if (hasRowId)
		inBitstream.Read(rowId);
	else
		rowId=(unsigned) -1; // Not used here but remove the debugging check
	unsigned char numCellUpdates;
	if (inBitstream.Read(numCellUpdates)==false)
		return;
	// Read the updates for the row
	DatabaseCellUpdate cellUpdates[256];
	for (i=0; i < numCellUpdates; i++)
		{
		if (cellUpdates[i].Deserialize(&inBitstream)==false)
			{
			printf("ERROR: LightweightDatabaseServer::OnUpdateRow cellUpdates deserialize failed i=%i numCellUpdates=%i\n",i,numCellUpdates);
			return;
			}
		}

	if ((RowUpdateMode)updateMode==RUM_UPDATE_EXISTING_ROW)
	{
		if (hasRowId==false)
		{
			unsigned rowKey;
			row = GetRowFromIP(databaseTable, packet->systemAddress, &rowKey);
			if (row==0)
				printf("ERROR: LightweightDatabaseServer::OnUpdateRow updateMode==RUM_UPDATE_EXISTING_ROW hasRowId==false");
		}
		else
		{

			row = databaseTable->table.GetRowByID(rowId);
			if (row==0 || (databaseTable->onlyUpdateOwnRows && RowHasIP(row, packet->systemAddress, databaseTable->SystemAddressColumnIndex)==false))
			{
				if (row==0)
					printf("ERROR: LightweightDatabaseServer::OnUpdateRow row = databaseTable->table.GetRowByID(rowId); row==0\n");
				else
					printf("ERROR: LightweightDatabaseServer::OnUpdateRow row = databaseTable->table.GetRowByID(rowId); databaseTable->onlyUpdateOwnRows && RowHasIP\n");

				return; // You can't update some other system's row
			}
		}
	}
	else if ((RowUpdateMode)updateMode==RUM_UPDATE_OR_ADD_ROW)
		{
		if (hasRowId)
			row = databaseTable->table.GetRowByID(rowId);
		else
			{
			unsigned rowKey;
			row = GetRowFromIP(databaseTable, packet->systemAddress, &rowKey);
			}

		if (row==0)
			{
			row=AddRow(databaseTable, packet->systemAddress, packet->guid, hasRowId, rowId);
			if (row==0)
				{
				printf("ERROR: LightweightDatabaseServer::OnUpdateRow updateMode==RUM_UPDATE_OR_ADD_ROW; row=AddRow; row==0\n");
				return;
				}
			}
		else
			{
			// Existing row
			if (databaseTable->onlyUpdateOwnRows && RowHasIP(row, packet->systemAddress, databaseTable->SystemAddressColumnIndex)==false)
				{
				SystemAddress sysAddr;
				memcpy(&sysAddr, row->cells[databaseTable->SystemAddressColumnIndex]->c, SystemAddress::size());

				char str1[64], str2[64];
				packet->systemAddress.ToString(true, str1);
				sysAddr.ToString(true, str2);
				printf("ERROR: LightweightDatabaseServer::OnUpdateRow updateMode==RUM_UPDATE_OR_ADD_ROW; databaseTable->onlyUpdateOwnRows && RowHasIP. packet->systemAddress=%s sysAddr=%s\n",
					str1, str2);

				return; // You can't update some other system's row
				}
			}
		}
	else
		{
		RakAssert((RowUpdateMode)updateMode==RUM_ADD_NEW_ROW);

		row=AddRow(databaseTable, packet->systemAddress, packet->guid, hasRowId, rowId);
		if (row==0)
			{
			printf("ERROR: LightweightDatabaseServer::OnUpdateRow updateMode==RUM_ADD_NEW_ROW; row==0\n");
			return;
			}
		}

	unsigned columnIndex;
	for (i=0; i < numCellUpdates; i++)
		{
		columnIndex=databaseTable->table.ColumnIndex(cellUpdates[i].columnName);
		RakAssert(columnIndex!=(unsigned)-1); // Unknown column name
		if (columnIndex!=(unsigned)-1 &&
			(databaseTable->onlyUpdateOwnRows==false ||
			(columnIndex!=databaseTable->lastPingResponseColumnIndex &&
			columnIndex!=databaseTable->nextPingSendColumnIndex &&
			columnIndex!=databaseTable->SystemAddressColumnIndex &&
			columnIndex!=databaseTable->SystemGuidColumnIndex)))
			{
			if (cellUpdates[i].cellValue.isEmpty)
				row->cells[columnIndex]->Clear();
			else if (cellUpdates[i].columnType==databaseTable->table.GetColumnType(columnIndex))
				{
				if (cellUpdates[i].columnType==DataStructures::Table::NUMERIC)
					{
					row->UpdateCell(columnIndex, cellUpdates[i].cellValue.i);
					}
				else if (cellUpdates[i].columnType==DataStructures::Table::BINARY)
					{
					row->UpdateCell(columnIndex, (int) cellUpdates[i].cellValue.i, cellUpdates[i].cellValue.c);
					}
				else
					{
					RakAssert(cellUpdates[i].columnType==DataStructures::Table::STRING);
					row->UpdateCell(columnIndex, cellUpdates[i].cellValue.c);
					}
				}
			}
		}
	}