Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "ClientMapManagement.h"
- ClientMapManagement::ClientMapManagement()
- {
- current_map=NULL;
- stopIt=false;
- basePath=QCoreApplication::applicationDirPath()+"/datapack/map/tmx/";
- }
- ClientMapManagement::~ClientMapManagement()
- {
- stopIt=true;
- QMutexLocker lock(&mutex);
- wait_the_end.acquire();
- }
- void ClientMapManagement::setBasePath(const QString &basePath)
- {
- this->basePath=basePath;
- }
- void ClientMapManagement::stop()
- {
- stopIt=true;
- }
- Map_player_info ClientMapManagement::getMapPlayerInfo()
- {
- Map_player_info temp;
- if(current_map==NULL)
- temp.loaded=false;
- else
- {
- temp.map = current_map->map_final;
- temp.map_file_path = current_map->mapName();
- temp.x = x;
- temp.y = y;
- temp.loaded = true;
- }
- return temp;
- }
- void ClientMapManagement::setVariable(QList<Map_custom *> *map_list,EventThreader* map_loader_thread)
- {
- this->map_loader_thread=map_loader_thread;
- this->map_list=map_list;
- }
- void ClientMapManagement::askIfIsReadyToStop()
- {
- stopIt=true;
- QMutexLocker lock(&mutex);
- wait_the_end.release();
- if(current_map==NULL)
- {
- emit isReadyToStop();
- return;
- }
- unloadFromCurrentMap();
- to_send_map_management_insert.clear();
- to_send_map_management_move.clear();
- to_send_map_management_remove.clear();
- //virtual stop the player
- if(last_direction>4)
- last_direction=Direction((quint8)last_direction-4);
- Orientation orientation=(Orientation)last_direction;
- if(current_map->mapName()!=at_start_map_name || x!=at_start_x || y!=at_start_y || orientation!=at_start_orientation)
- {
- emit updatePlayerPosition(current_map->mapName(),x,y,orientation);
- #ifdef DEBUG_MESSAGE_CLIENT_MOVE
- DebugClass::debugConsole(
- QString("current_map->mapName(): %1,x: %2,y: %3, orientation: %4")
- .arg(current_map->mapName())
- .arg(x)
- .arg(y)
- .arg(orientation)
- );
- #endif
- }
- unloadMapIfNeeded(current_map);
- current_map=NULL;
- emit isReadyToStop();
- }
- void ClientMapManagement::unloadFromCurrentMap()
- {
- //remove player to current map
- if(current_map->clients.removeAll(this)!=1)
- //if(!current_map->clients.removeOne(this))
- {
- emit message("unable to remove the player from the map");
- return;
- }
- //tell at all other client the disconnect of this
- if(current_map->map_loaded)
- {
- int index_maps_clients=0;
- QList<ClientMapManagement *> client_near=current_map->clients;
- int list_size_maps_clients=client_near.size();
- while(index_maps_clients<list_size_maps_clients)
- {
- client_near.at(index_maps_clients)->removeClient(player_id);
- index_maps_clients++;
- }
- }
- }
- void ClientMapManagement::unloadMapIfNeeded(Map_custom * map)
- {
- //not more client, can unload the map
- if(map->clients.size()==0)
- {
- map_list->removeOne(map);
- /// \note auto unregistred on other map by destructor
- delete map;
- }
- }
- void ClientMapManagement::put_on_the_map(const quint32 &player_id,const QString & map,const quint16 &x,const quint16 &y,const Orientation &orientation)
- {
- have_diff=false;
- at_start_x=x;
- at_start_y=y;
- at_start_orientation=orientation;
- last_direction=(Direction)orientation;
- at_start_map_name=map;
- this->player_id=player_id;
- this->x=x;
- this->y=y;
- current_map=getMap(map);
- current_map->clients << this;
- propagate();
- }
- void ClientMapManagement::put_on_the_map_by_diff(const QString & map,const quint16 &x,const quint16 &y)
- {
- DebugClass::debugConsole(QString("try load map by diff for for player: %1").arg(player_id));
- have_diff=true;
- this->x=x;
- this->y=y;
- current_map=getMap(map);
- current_map->clients << this;
- propagate();
- //set to 0 or map max size
- //moveThePlayer() to check colision and do real move
- }
- void ClientMapManagement::propagate()
- {
- if(current_map==NULL)
- {
- DebugClass::debugConsole(QString("current_map==NULL and should not: %1").arg(player_id));
- return;
- }
- if(current_map->map_loaded)
- {
- if(have_diff)
- {
- have_diff=false;
- switch(last_direction)
- {
- case 0x05:
- y+=0;//useless but it's y=0 + offset stored into y
- break;
- case 0x06:
- x+=0;//useless but it's x=0 + offset stored into x
- break;
- case 0x07:
- y+=current_map->height;//it's y=height + offset stored into y, then y=y+height
- break;
- case 0x08:
- x+=current_map->height;//it's x=height + offset stored into x, then x=x+height
- break;
- default:
- break;
- }
- }
- else
- {
- current_map->check_client_position(current_map->clients.size()-1);
- int index_maps_clients=0;
- int list_size_map_custom=current_map->clients.size();
- while(index_maps_clients<list_size_map_custom)
- {
- ClientMapManagement *other_client=current_map->clients.at(index_maps_clients);
- if(other_client!=this)
- other_client->insertClient(player_id,current_map->mapName(),x,y,last_direction);
- insertClient(other_client->player_id,
- other_client->current_map->mapName(),
- other_client->x,
- other_client->y,
- other_client->last_direction);
- index_maps_clients++;
- }
- }
- }
- }
- QList<ClientMapManagement *> ClientMapManagement::preMapMove()
- {
- QList<ClientMapManagement *> previousClient;
- if(stopIt)
- return previousClient;
- getNearClient(previousClient);
- unloadFromCurrentMap();
- old_map=current_map;
- return previousClient;
- }
- void ClientMapManagement::postMapMove(const QList<ClientMapManagement *> &previousClient,const quint8 &previousMovedUnit,const Direction &direction)
- {
- if(stopIt)
- return;
- postMapMove_nextClient.clear();
- getNearClient(postMapMove_nextClient);
- #ifdef DEBUG_MESSAGE_CLIENT_COMPLEXITY_LINEARE
- emit message(QString("postMapMove start: %1, getNearClient: %2, previousClient: %3").arg(player_id).arg(postMapMove_nextClient.size()).arg(previousClient.size()));
- #endif // DEBUG_MESSAGE_CLIENT_COMPLEXITY_LINEARE
- index=0;
- list_size=previousClient.size();
- while(index<list_size)
- {
- if(postMapMove_nextClient.contains(previousClient.at(index)))
- {
- previousClient.at(index)->moveClient(player_id,previousMovedUnit,direction);
- postMapMove_nextClient.removeOne(previousClient.at(index));
- }
- else
- previousClient.at(index)->removeClient(player_id);
- index++;
- }
- postMapMove_size=postMapMove_nextClient.size();
- while(postMapMove_size>0)
- {
- postMapMove_nextClient.first()->insertClient(player_id,current_map->mapName(),x,y,(Direction)direction);
- postMapMove_nextClient.removeFirst();
- postMapMove_size--;
- }
- unloadMapIfNeeded(old_map);
- return;
- }
- /// \note The second heavy function
- void ClientMapManagement::moveThePlayer(const quint8 &previousMovedUnit,const Direction &direction)
- {
- if(stopIt)
- return;
- if(current_map==NULL)
- {
- emit message(QString("internal error, map pointer == NULL, for player: %1").arg(player_id));
- return;
- }
- if(current_map->map_loaded)
- {
- #ifdef DEBUG_MESSAGE_CLIENT_COMPLEXITY_SQUARE
- emit message(QString("for player (%1,%2): %3, previousMovedUnit: %4, direction: %5").arg(x).arg(y).arg(player_id).arg(previousMovedUnit).arg(Map_custom::directionToString((Direction)direction)));
- #endif
- moveThePlayer_index_move=0;
- switch(last_direction)
- {
- case Direction_move_at_top:
- if(previousMovedUnit==0)
- emit error(QString("Previous action is moving: %1").arg(last_direction));
- while(moveThePlayer_index_move<previousMovedUnit)
- {
- if(0==y)
- {
- if(current_map->map_border_top.fileName.isEmpty())
- emit error(QString("moveThePlayer(), out of map: %1, file name: \"%2\"").arg(current_map->mapName()).arg(current_map->map_border_top.fileName));
- else
- {
- QList<ClientMapManagement *> previousClient=preMapMove();
- put_on_the_map_by_diff(current_map->map_border_top.fileName,current_map->map_border_top.x_offset+x,-(previousMovedUnit-moveThePlayer_index_move));
- postMapMove(previousClient,previousMovedUnit,direction);
- }
- return;
- }
- y--;
- if(!current_map->is_walkalble(x,y))
- {
- emit error(QString("move at top, can wall at: %1,%2 on map: %3").arg(x).arg(y).arg(current_map->mapName()));
- return;
- }
- moveThePlayer_index_move++;
- }
- break;
- case Direction_look_at_top:
- if(previousMovedUnit>0)
- emit error(QString("Previous action is not moving: %1").arg(last_direction));
- break;
- case Direction_move_at_right:
- if(previousMovedUnit==0)
- emit error(QString("Previous action is moving: %1").arg(last_direction));
- while(moveThePlayer_index_move<previousMovedUnit)
- {
- if(current_map->width==x)
- {
- if(current_map->map_border_right.fileName.isEmpty())
- emit error(QString("moveThePlayer(): move at right, out of map: %1, file name: \"%2\"").arg(current_map->mapName()).arg(current_map->map_border_right.fileName));
- else
- {
- QList<ClientMapManagement *> previousClient=preMapMove();
- put_on_the_map_by_diff(current_map->map_border_right.fileName,current_map->map_border_right.y_offset+y,(previousMovedUnit-moveThePlayer_index_move));
- postMapMove(previousClient,previousMovedUnit,direction);
- }
- return;
- }
- x++;
- if(!current_map->is_walkalble(x,y))
- {
- emit error(QString("move at right, can wall at: %1,%2 on map: %3").arg(x).arg(y).arg(current_map->mapName()));
- return;
- }
- moveThePlayer_index_move++;
- }
- break;
- case Direction_look_at_right:
- if(previousMovedUnit>0)
- emit error(QString("Previous action is not moving: %1").arg(last_direction));
- break;
- case Direction_move_at_bottom:
- if(previousMovedUnit==0)
- emit error(QString("Previous action is moving: %1").arg(last_direction));
- while(moveThePlayer_index_move<previousMovedUnit)
- {
- if(current_map->height==y)
- {
- if(current_map->map_border_bottom.fileName.isEmpty())
- emit error(QString("moveThePlayer(): move at bottom, out of map: %1, file name: \"%2\"").arg(current_map->mapName()).arg(current_map->map_border_bottom.fileName));
- else
- {
- QList<ClientMapManagement *> previousClient=preMapMove();
- put_on_the_map_by_diff(current_map->map_border_bottom.fileName,current_map->map_border_bottom.x_offset+x,(previousMovedUnit-moveThePlayer_index_move));
- postMapMove(previousClient,previousMovedUnit,direction);
- }
- return;
- }
- y++;
- if(!current_map->is_walkalble(x,y))
- {
- emit error(QString("move at bottom, can wall at: %1,%2 on map: %3").arg(x).arg(y).arg(current_map->mapName()));
- return;
- }
- moveThePlayer_index_move++;
- }
- break;
- case Direction_look_at_bottom:
- if(previousMovedUnit>0)
- emit error(QString("Previous action is not moving: %1").arg(last_direction));
- break;
- case Direction_move_at_left:
- if(previousMovedUnit==0)
- emit error(QString("Previous action is moving: %1").arg(last_direction));
- while(moveThePlayer_index_move<previousMovedUnit)
- {
- if(0==x)
- {
- if(current_map->map_border_left.fileName.isEmpty())
- emit error(QString("moveThePlayer(): move at left, out of map: %1, file name: \"%2\"").arg(current_map->mapName()).arg(current_map->map_border_left.fileName));
- else
- {
- QList<ClientMapManagement *> previousClient=preMapMove();
- put_on_the_map_by_diff(current_map->map_border_left.fileName,current_map->map_border_left.y_offset+y,-(previousMovedUnit-moveThePlayer_index_move));
- postMapMove(previousClient,previousMovedUnit,direction);
- }
- return;
- }
- x--;
- if(!current_map->is_walkalble(x,y))
- {
- emit error(QString("can wall at: %1,%2 on map: %3").arg(x).arg(y).arg(current_map->mapName()));
- return;
- }
- moveThePlayer_index_move++;
- }
- break;
- case Direction_look_at_left:
- if(previousMovedUnit>0)
- emit error(QString("Previous action is not moving: %1").arg(last_direction));
- break;
- default:
- break;
- }
- moveThePlayer_returnList.clear();
- getNearClient(moveThePlayer_returnList);
- moveThePlayer_index=0;
- moveThePlayer_list_size=moveThePlayer_returnList.size();
- while(moveThePlayer_index<moveThePlayer_list_size)
- {
- moveThePlayer_returnList[moveThePlayer_index]->moveClient(player_id,previousMovedUnit,(Direction)direction);
- moveThePlayer_index++;
- }
- last_direction=(Direction)direction;
- #ifdef DEBUG_MESSAGE_CLIENT_MOVE
- emit message(QString("after %4: (%1,%2): %3, send at %5 player(s)").arg(x).arg(y).arg(player_id).arg(Map_custom::directionToString((Direction)direction)).arg(moveThePlayer_list_size));
- #endif
- }
- else
- {
- /* map_management_movement temp;
- temp.movedUnit=previousMovedUnit;
- temp.direction=(Direction)direction;
- delayed_map_management_move << temp;*/
- }
- }
- //send client only on near map loaded and not the current player
- void ClientMapManagement::getNearClient(QList<ClientMapManagement *> & returnList)
- {
- if(!current_map->map_loaded)
- return;
- returnList << current_map->clients;
- /// \todo uncomment and fix this code
- /*
- getNearClient_index=0;
- getNearClient_list_size=current_map->clients.size();
- while(getNearClient_index<getNearClient_list_size)
- {
- if(current_map->clients.at(getNearClient_index)!=this)
- returnList << current_map->clients.at(getNearClient_index);
- getNearClient_index++;
- }*/
- }
- void ClientMapManagement::insertClient(const quint32 &player_id,const QString &map,const quint16 &x,const quint16 &y,const Direction &direction)
- {
- if(current_map==NULL)
- {
- emit message("internal error, map pointer == NULL at insertClient()");
- return;
- }
- insertClient_temp.fileName=map;
- insertClient_temp.id=player_id;
- insertClient_temp.direction=direction;
- insertClient_temp.x=x;
- insertClient_temp.y=y;
- to_send_map_management_insert << insertClient_temp;
- }
- /// \note The first heavy function
- void ClientMapManagement::moveClient(const quint32 &player_id,const quint8 &movedUnit,const Direction &direction)
- {
- if(current_map==NULL)
- {
- emit message("internal error, map pointer == NULL at moveClient()");
- return;
- }
- #ifdef DEBUG_MESSAGE_CLIENT_COMPLEXITY_SQUARE
- emit message(QString("moveClient(%1,%2,%3)").arg(player_id).arg(movedUnit).arg(Map_custom::directionToString((Direction)direction)));
- #endif
- moveClient_tempMov.movedUnit=movedUnit;
- moveClient_tempMov.direction=direction;
- //multi-threaded access to to_send_map_management_move ?
- moveClient_list_size=to_send_map_management_move.size();
- moveClient_index=0;
- while(moveClient_index<moveClient_list_size)
- {
- if(to_send_map_management_move[moveClient_index].id==player_id)
- {
- to_send_map_management_move[moveClient_index].movement_list << moveClient_tempMov;
- return;
- }
- moveClient_index++;
- }
- moveClient_temp.id=player_id;
- moveClient_temp.movement_list.clear();
- moveClient_temp.movement_list << moveClient_tempMov;
- to_send_map_management_move << moveClient_temp;
- }
- void ClientMapManagement::removeClient(const quint32 &player_id)
- {
- if(current_map==NULL)
- {
- emit message("internal error, map pointer == NULL at removeClient()");
- return;
- }
- if(stopIt)
- return;
- if(to_send_map_management_remove.contains(player_id))
- emit message("try dual remove");
- else
- {
- list_size=to_send_map_management_move.size();
- index=0;
- while(index<list_size)
- {
- if(to_send_map_management_move.at(index).id==player_id)
- {
- to_send_map_management_move.removeAt(index);
- return;
- }
- index++;
- }
- to_send_map_management_remove << player_id;
- }
- }
- void ClientMapManagement::purgeBuffer()
- {
- if(to_send_map_management_insert.size()==0 && to_send_map_management_move.size()==0 && to_send_map_management_remove.size()==0)
- return;
- if(stopIt)
- return;
- QMutexLocker lock(&mutex);
- #ifdef DEBUG_MESSAGE_CLIENT_COMPLEXITY_LINEARE
- emit message("purgeBuffer() runing....");
- #endif
- purgeBuffer_player_affected=0;
- purgeBuffer_outputData.clear();
- QDataStream out(&purgeBuffer_outputData, QIODevice::WriteOnly);
- out.setVersion(QDataStream::Qt_4_4);
- out << (quint8)0xC0;
- purgeBuffer_outputDataLoop.clear();
- QDataStream outLoop(&purgeBuffer_outputDataLoop, QIODevice::WriteOnly);
- outLoop.setVersion(QDataStream::Qt_4_4);
- purgeBuffer_index=0;
- purgeBuffer_list_size=to_send_map_management_remove.size();
- while(purgeBuffer_index<purgeBuffer_list_size)
- {
- if(stopIt)
- return;
- #ifdef DEBUG_MESSAGE_CLIENT_COMPLEXITY_SQUARE
- emit message(
- QString("player_id to remove: %1, for player: %2")
- .arg(to_send_map_management_remove.at(purgeBuffer_index))
- .arg(player_id)
- );
- #endif
- outLoop << to_send_map_management_remove.at(purgeBuffer_index);
- outLoop << (quint8)0x03;
- purgeBuffer_index++;
- purgeBuffer_player_affected++;
- }
- to_send_map_management_remove.clear();
- purgeBuffer_index=0;
- purgeBuffer_list_size=to_send_map_management_insert.size();
- while(purgeBuffer_index<purgeBuffer_list_size)
- {
- if(stopIt)
- return;
- #ifdef DEBUG_MESSAGE_CLIENT_COMPLEXITY_SQUARE
- emit message(
- QString("insert player_id: %1,mapName %2,x: %3,y: %4,direction: %5, for player: %6")
- .arg(to_send_map_management_insert.at(purgeBuffer_index).id)
- .arg(to_send_map_management_insert.at(purgeBuffer_index).fileName)
- .arg(to_send_map_management_insert.at(purgeBuffer_index).x)
- .arg(to_send_map_management_insert.at(purgeBuffer_index).y)
- .arg(Map_custom::directionToString(to_send_map_management_insert.at(purgeBuffer_index).direction))
- .arg(player_id)
- );
- #endif
- outLoop << to_send_map_management_insert.at(purgeBuffer_index).id;
- outLoop << (quint8)0x01;
- outLoop << to_send_map_management_insert.at(purgeBuffer_index).fileName;
- outLoop << to_send_map_management_insert.at(purgeBuffer_index).x;
- outLoop << to_send_map_management_insert.at(purgeBuffer_index).y;
- outLoop << (quint8)to_send_map_management_insert.at(purgeBuffer_index).direction;
- purgeBuffer_index++;
- purgeBuffer_player_affected++;
- }
- to_send_map_management_insert.clear();
- purgeBuffer_index=0;
- purgeBuffer_list_size=to_send_map_management_move.size();
- purgeBuffer_list_size_internal=0;
- purgeBuffer_indexMovement=0;
- while(purgeBuffer_index<purgeBuffer_list_size)
- {
- if(stopIt)
- return;
- purgeBuffer_move=to_send_map_management_move.at(purgeBuffer_index);
- #ifdef DEBUG_MESSAGE_CLIENT_COMPLEXITY_SQUARE
- emit message(
- QString("move player_id: %1, for player: %2")
- .arg(purgeBuffer_move.id)
- .arg(player_id)
- );
- #endif
- outLoop << purgeBuffer_move.id;
- outLoop << (quint8)0x02;
- purgeBuffer_list_size_internal=purgeBuffer_move.movement_list.size();
- if(purgeBuffer_list_size_internal==0)
- DebugClass::debugConsole(QString("for player: %1, list_size_internal==0").arg(this->player_id));
- outLoop << (quint8)purgeBuffer_list_size_internal;
- purgeBuffer_indexMovement=0;
- while(purgeBuffer_indexMovement<purgeBuffer_list_size_internal)
- {
- if(stopIt)
- return;
- outLoop << purgeBuffer_move.movement_list.at(purgeBuffer_indexMovement).movedUnit;
- outLoop << (quint8)purgeBuffer_move.movement_list.at(purgeBuffer_indexMovement).direction;
- purgeBuffer_indexMovement++;
- }
- purgeBuffer_player_affected++;
- purgeBuffer_index++;
- if(stopIt)
- return;
- }
- if(stopIt)
- return;
- to_send_map_management_move.clear();
- if(stopIt)
- return;
- #ifdef DEBUG_MESSAGE_CLIENT_COMPLEXITY_SQUARE
- emit message(QString("player_affected: %1").arg(purgeBuffer_player_affected));
- #endif
- out << purgeBuffer_player_affected;
- purgeBuffer_outputData+=purgeBuffer_outputDataLoop;
- emit sendPacket(purgeBuffer_outputData);
- }
- Map_custom * ClientMapManagement::getMap(const QString & mapName)
- {
- int index=0;
- int map_list_size=map_list->size();
- while(index<map_list_size)
- {
- //current map found in already loaded
- if(map_list->at(index)->mapName()==mapName)
- return map_list->at(index);
- index++;
- }
- *map_list << new Map_custom(map_loader_thread,map_list);
- map_list->last()->moveToThread(this->thread());
- map_list->last()->loadMap(mapName,basePath);
- return map_list->last();
- }
- void ClientMapManagement::mapError(QString errorString)
- {
- QByteArray outputData;
- QDataStream out(&outputData, QIODevice::WriteOnly);
- out.setVersion(QDataStream::Qt_4_4);
- out << (quint8)0xC2;
- out << (quint32)0x00000008;
- out << (quint8)0x03;
- out << "Unable to load the current map";
- emit sendPacket(outputData);
- emit error(errorString);
- }
Advertisement
Add Comment
Please, Sign In to add comment