hnPoint hnPoint::operator-(const hnPoint &b) const { return hnPoint(x - b.x, y - b.y, z - b.z); }
#include "HN_Point.h" #include "HN_Enum.h" hnPoint offsetVector[DIR_MAX] = { hnPoint(0, -1, 0), hnPoint(1, -1, 0), hnPoint(1, 0, 0), hnPoint(1, 1, 0), hnPoint(0, 1, 0), hnPoint(-1, 1, 0), hnPoint(-1, 0, 0), hnPoint(-1, -1, 0), hnPoint(0, 0, -1), hnPoint(0, 0, 1) }; hnPoint::hnPoint() : x(0), y(0), z(0) { } hnPoint::hnPoint(sint8 x, sint8 y, sint8 z) : x(x), y(y), z(z) { } hnPoint::~hnPoint() { } void hnPoint::Increment(hnDirection dir) { x += offsetVector[dir].x; y += offsetVector[dir].y; z += offsetVector[dir].z; } hnPoint hnPoint::operator+(const hnPoint &b) const {
hnPoint hnPoint::operator+(const hnPoint &b) const { return hnPoint(x + b.x, y + b.y, z + b.z); }
void netClient::Go() { mapClientTile tile; // for use in map updates netMapTile tileData; netMapEntity entityData; netMapUpdateBBox bbox; netMapReset mapReset; netGroupData groupData; netClientLocation clientLoc; hnPoint point; sint8 levelCount; netInventory inven; netInventoryItem item; objDescription *objList; uint16 objectID; objType objectType; m_display->TextMessage("Trying to connect to server...\n"); if ( connect( m_socket, (sockaddr *)m_serverAddress, sizeof(sockaddr) ) == -1 ) { perror("connect"); cleanexit(1); } m_display->TextMessage("Connected!\n"); // Now that we're connected, send the server our name. SendName( m_display->GetName() ); // now that we've connected, we wait for packets from the server or a key from our hnClient... m_display->Go(); while(!m_done){ // do stuff here until we quit. short readSizeBytesLeft = sizeof(sint16); short incomingBytes; char * incomingBuffer = (char *)&incomingBytes; // Emulate functionality of MSG_WAITALL, 'cause some architectures don't support it. while ( readSizeBytesLeft > 0 ) { #ifdef __DEBUGGING_NETWORK__ printf("Waiting for %d bytes of packet size data..\n", readSizeBytesLeft); #endif int bytesRead = recv( m_socket, incomingBuffer, readSizeBytesLeft, 0 ); #ifdef __DEBUGGING_NETWORK__ printf("Received %d bytes.\n",bytesRead); #endif if ( bytesRead == -1 ) { perror("recv"); cleanexit(1); } incomingBuffer += bytesRead; readSizeBytesLeft -= bytesRead; } incomingBytes = ntohs(incomingBytes); int remainingBytes = incomingBytes; //printf("Receiving %d bytes...\n", incomingBytes); char buffer[incomingBytes]; char *bufferPointer = buffer; // Emulate functionality of MSG_WAITALL, 'cause some architectures don't support it. while ( remainingBytes > 0 ) { #ifdef __DEBUGGING_NETWORK__ printf("Waiting for %d bytes of packet data..\n", remainingBytes ); #endif int bytesRead = recv( m_socket, bufferPointer, remainingBytes, 0 ); #ifdef __DEBUGGING_NETWORK__ printf("Received %d bytes.\n", bytesRead); #endif if ( bytesRead == -1 ) { perror("recv"); cleanexit(1); } bufferPointer += bytesRead; remainingBytes -= bytesRead; } #ifdef __DISPLAY_PACKET_CONTENT__ printf("Packet of %d bytes:\n", incomingBytes ); char *bufferstart = buffer; for ( int i = 0; i < incomingBytes; i++ ) { printf("Value: %d\n",*(bufferstart + i)); } printf("\n"); #endif netMetaPacketInput *packet = new netMetaPacketInput(buffer, incomingBytes); while ( !packet->Done() ) { sint8 type = packet->PeekSint8(); #define MAX_MESSAGE_BYTES (256) char messageBuffer[MAX_MESSAGE_BYTES]; sint16 messageBufferLength = MAX_MESSAGE_BYTES; switch ( type ) { case SPT_ClientLocation: packet->ClientLocation(clientLoc); m_display->UpdateLocation( clientLoc.loc ); break; case SPT_GroupData: packet->GroupData(groupData); m_display->UpdateGroupData(groupData.memberCount, groupData.memberTurns, groupData.haveTurnFromClient ); break; case SPT_ClientStatistics: case SPT_ClientHitPoints: case SPT_ClientSpellPoints: case SPT_ClientExperience: m_display->GetStatus()->ReceiveChanges( packet ); break; case SPT_MapTile: packet->MapTile(tileData); if ( m_display->isMapReady( tileData.loc.z ) ) { tile.material = (hnMaterialType)tileData.material; tile.wall = (hnWallType)tileData.wall; m_display->UpdateMapTile(tileData.loc, tile); } break; case SPT_Message: packet->TextMessage(messageBuffer, messageBufferLength); m_display->TextMessage(messageBuffer); break; case SPT_ObjectStats: packet->ObjectStats(objectID); m_display->SetObjectStats(objectID); break; case SPT_ObjectName: packet->ObjectName(objectID, objectType, messageBuffer, messageBufferLength); m_display->SetObjectName(objectID, objectType, messageBuffer); break; case SPT_MapEntity: packet->MapEntity(entityData); if ( m_display->isMapReady( bbox.loc.z ) ) m_display->UpdateMapCreature(entityData.loc, entityData.objectType); break; case SPT_DungeonReset: packet->DungeonReset(levelCount); m_display->DungeonReset(levelCount); case SPT_MapReset: packet->MapReset(mapReset); m_display->MapReset(mapReset.width, mapReset.height, mapReset.depth); break; case SPT_MapUpdateBBox: packet->MapUpdateBBox(bbox); // If we haven't prepared this map yet, ask for a full refresh of // this map, so we can initialise our map structures. if ( !m_display->isMapReady( bbox.loc.z ) ) { SendRefreshRequest( bbox.loc.z ); break; } for ( int i = 0; i < bbox.width; i++ ) for ( int j = 0; j < bbox.height; j++ ) { tile.material = bbox.material[i+(j*bbox.width)]; tile.wall = bbox.wall[i+(j*bbox.width)]; point.Set(bbox.loc.x+i, bbox.loc.y+j, 0); tile.entity = bbox.entityType[i+(j*bbox.width)]; tile.objectCount = bbox.objectCount[i+(j*bbox.width)]; tile.object = new objDescription[tile.objectCount]; for ( int k = 0; k < tile.objectCount; k++ ) tile.object[k] = bbox.object[i+(j*bbox.width)][k]; m_display->UpdateMapTile( hnPoint(bbox.loc.x+i, bbox.loc.y+j, bbox.loc.z), tile); delete [] tile.object; } break; case SPT_Inventory: packet->Inventory(inven); objList = new objDescription[inven.GetObjectCount()]; for ( int i = 0; i < inven.GetObjectCount(); i++ ) objList[i] = inven.GetObject(i); m_display->UpdateInventory(inven.GetObjectCount(), objList); delete [] objList; break; case SPT_InventoryItem: packet->InventoryItem(item); m_display->UpdateInventoryItem(item.object, item.inventorySlot); break; case SPT_TakenItem: packet->TakenItem(item); m_display->TakenItem(item.object, item.inventorySlot); break; case SPT_DroppedItem: packet->DroppedItem(item); m_display->DroppedItem(item.object); break; case SPT_WieldedItem: packet->WieldedItem(item); m_display->WieldedItem(item.object, item.inventorySlot); break; case SPT_BadPacketNotice: packet->BadPacketNotice(); delete m_display; printf("Server killed us for sending an unknown packet. Version mismatch?\n"); m_done = true; //exit(1); break; case SPT_QuitConfirm: packet->QuitConfirm(); m_done = true; break; default: printf("Unknown packet type %d!! :(\n", type); break; } } m_display->Refresh(); // do a screen refresh if we need it. } close( m_socket ); }