Пример #1
0
// Spawns a player at a particular spawn point
void _Server::SpawnPlayer(_Object *Player, NetworkIDType MapID, uint32_t EventType) {
	if(!ValidatePeer(Player->Peer) || !Player->Peer->CharacterID || !MapID)
	   return;

	// Get map
	_Map *Map = MapManager->GetObject(MapID);

	// Load map
	if(!Map) {
		Map = MapManager->CreateWithID(MapID);
		Map->Clock = Clock;
		Map->Server = this;
		Map->Load(Stats->GetMap(MapID)->File);
	}

	// Get old map
	_Map *OldMap = Player->Map;

	// Place player in new map
	if(Map != OldMap) {
		if(OldMap) {
			OldMap->RemoveObject(Player);
		}

		Player->Map = Map;

		// Find spawn point in map
		uint32_t SpawnPoint = Player->SpawnPoint;
		if(EventType == _Map::EVENT_MAPENTRANCE)
			SpawnPoint = OldMap->NetworkID;

		// Default to mapchange event if entrance not found
		if(!Map->FindEvent(_Event(EventType, SpawnPoint), Player->Position))
			Map->FindEvent(_Event(_Map::EVENT_MAPCHANGE, SpawnPoint), Player->Position);

		// Add player to map
		Map->AddObject(Player);

		// Send new map id
		_Buffer Packet;
		Packet.Write<PacketType>(PacketType::WORLD_CHANGEMAPS);
		Packet.Write<uint32_t>(MapID);
		Packet.Write<double>(Clock);
		Network->SendPacket(Packet, Player->Peer);

		// Set player object list
		Map->SendObjectList(Player->Peer);

		// Set full player data to peer
		SendPlayerInfo(Player->Peer);
	}
	else {
		Map->FindEvent(_Event(EventType, Player->SpawnPoint), Player->Position);
		SendPlayerPosition(Player->Peer);
		SendHUD(Player->Peer);
	}
}
Пример #2
0
void TClient::OnDataReceived(const QByteArray &data)
{
    EPacketType packetType;
    quint16 packedDataSize;
    quint16 originDataSize;
    QByteArray content;
    QByteArray receivedPacket = data;
    const int midSize = sizeof(quint16);
    const int posOrigin = sizeof(char);
    const int posPacked = posOrigin + midSize;
    const int posContent = posPacked + midSize;

    try {
        while (receivedPacket.size() > 0) {
            packetType = (EPacketType)(char)(receivedPacket[0]);
            originDataSize = qFromBigEndian<quint16>(
                (const uchar*)receivedPacket.mid(posOrigin, midSize).constData());
            packedDataSize = qFromBigEndian<quint16>(
                (const uchar*)receivedPacket.mid(posPacked, midSize).constData());
            content = qUncompress(receivedPacket.mid(posContent, packedDataSize));

            if( content.isEmpty() && (originDataSize || packedDataSize) )
                throw UException("Wrong packet: cannot unpack data");

            // Retrieve another packet from current.
            // We can receive more than one packet at once
            receivedPacket = receivedPacket.mid(
                packedDataSize + sizeof(char) + 2*midSize);

            switch (packetType) {
            case PT_Control: {
            if (!(PlayerStatus == PS_Spawned || PlayerStatus == PS_Dead)) {
                    throw UException("Player not spawned!");
                }
                Epsilon5::Control control;

                if (control.ParseFromArray(content.data(), content.size())) {
                    size_t currentPacket = control.packet_number();
                    if (control.has_need_full()) {
                        if (control.need_full()) {
                            Server()->NeedFullPacket(Id);
                        }
                    }
                    Server()->Application()->GetWorld()->SetPingForPlayer(Id, currentPacket);
                    SetSeen();
                    emit ControlReceived(control);
                } else {
                    throw UException("Parse error: control packet");
                }
            }
                break;
            case PT_PlayerAuth: {
                if (PlayerStatus != PS_AuthWait) {
                    throw UException("Player not waiting for auth!");
                }
                Epsilon5::Auth auth;
                if (auth.ParseFromArray(content.data(), content.size())) {
                    try {
                        SetSeen();
                        NickName = auth.name().c_str();
                        SendPlayerInfo();

                        QTime dieTime= QTime::currentTime().addSecs(1);
                        while( QTime::currentTime() < dieTime ) {
                            QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
                        }

                    qDebug() << "Player " << NickName << "("
                             << Addr.toString() << ") connected";

                    Team = rand() % 2 == 1 ? T_One : T_Second; // throw to random team
                    ETeam NewTeam = Server()->AutoBalance();
                    if (NewTeam != T_Neutral) {
                        Team = NewTeam;
                    }

                    emit PlayerConnected();
                    ReSpawn(true);

                    } catch (const std::exception& e){
                    qDebug() << "Exceptiong: " << Q_FUNC_INFO
                             << ": Error spawning player: " << e.what();
                    }
                } else {
                    throw UException("Parse error: auth packet");
                }
            }
                break;
            default:
                throw UException("Unknown packet type!");
                break;
            }
        }
    } catch (const UException& e) {
        qDebug() << "Exceptiong: " << Q_FUNC_INFO << ": " << e.what();
    }
}