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);
				}
			}
		}
	}
}
Ejemplo n.º 2
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);
					}
				}
			}
		}
	}