#include "room.h" #include "client.h" #include "utils.h" #include #include #include #include "furnitureprofile.h" #include "furniture.h" void Room::updateHeightMap(bool ber){ // QSqlQuery q; // q.prepare("SELECT x,y,z FROM furniture WHERE inroom=:room ORDER BY z"); // q.bindValue(":room", id, QSql::Out); // if(q.exec()){//43882 // while(q.next()){ // heightmap[q.value(0).toInt()][q.value(1).toInt()] = q.value(2).toInt(); // } // } // if(ber){ // QString hmp = QString("@_"); // for(int erx = 0; erx < 128; erx++){ // for(int ery = 0; ery < 128; ery++){ // switch(heightmap[erx][ery]){ // case 43882:{break;} // case -1:{hmp += "x";break;} // default:{hmp += QString::number(heightmap[erx][ery]);break;} // } // } // hmp += "\r"; // } // broadcastPacket(hmp); // } } Room::Room(int i) { qDebug() << "Loading Room" << i; id = i; connect(&unloader, SIGNAL(timeout()), this, SLOT(cleanup())); // TODO: Load room from Database // also load the room info here // ok, in a bit wana help me test chat? // kk QSqlQuery q; q.prepare("SELECT title, desc, ownerstr, category, model, showowner, maxcount, owner FROM rooms WHERE id=:id"); q.bindValue(":id", id, QSql::Out); valid = q.exec() && q.next(); if(valid){ title = q.value(0).toString(); desc = q.value(1).toString(); ownerstr = q.value(2).toString(); category = q.value(3).toInt(); model = q.value(4).toString(); showowner = q.value(5).toInt(); maxcount = q.value(6).toInt(); oid = q.value(7).toInt(); clients.reserve(maxcount); unloader.start(60*5000); // this way the unloader starts if its just from a query and no one enters QSqlQuery q2; q2.prepare("SELECT map, doorx, doory, doorh FROM heightmaps WHERE model=:m"); q2.bindValue(":m", model, QSql::Out); if(q2.exec() && q2.next()){ doorx = q2.value(1).toInt(); doory = q2.value(2).toInt(); doorh = q2.value(3).toString(); QString hmap = q2.value(0).toString(); QStringList tem = hmap.split("\r"); //printf((QString("Parsing heightmap: ") + hmap.replace("\r", "\n") + "\n").toStdString().c_str()); heightmap = new int*[128]; for (int retew = 0; retew < 128; ++retew) // bad heightmap[retew] = new int[128]; for(int erx = 0; erx < 128; erx++){ for(int ery = 0; ery < 128; ery++){ heightmap[erx][ery] = 43882; } } int x = 0; int y = 0; int tv = 0; foreach(QString str, tem){ foreach(QChar c,str){ tv = 0; switch(c.toLower().unicode()){ case 'x': { tv = -1; printf(" "); break; // will this work? } default: { tv = QString(c).toInt();// do I need to cast? printf(QString(c).toStdString().c_str()); break; } } heightmap[x][y] = tv; x++; } printf("\n"); y++; x = 0; } printf("Parsed heightmap.\n"); } printf("Loading furniture map..."); QSqlQuery sq; sq.prepare("SELECT id, sprite, x, y, z, rot, status FROM furniture WHERE inroom=:irid"); sq.bindValue(":irid", id, QSql::Out); /// forgot to bind if(sq.exec()){ while(sq.next()){ FurnitureProfile* fep = FurnitureProfile::bySprite(sq.value(1).toString()); if(fep == NULL){ printf("INVALID FURNITURE SPRITE: %s\n", sq.value(1).toString().toStdString().c_str()); continue;// whats this for? } Furniture* fe = new Furniture; fe->profile = fep; fe->id = sq.value(0).toInt(); fe->sprite = sq.value(1).toString(); fe->x = sq.value(2).toInt(); fe->y = sq.value(3).toInt(); fe->z = sq.value(4).toDouble(); fe->rot = sq.value(5).toInt(); fe->status = sq.value(0).toString(); furnituremap.insert(fe->id, fe); //furnituremap << fe; // I was about to test this lol, then this retarded thing happened //qDebug() << ""; }// sec ill redo it } printf(" [OK]\n"); } qDebug() << "Loaded room " << i; } Room::~Room(){ // TODO: Save room to Database if(valid){ for (int retew = 0; retew < 128; ++retew) // bad delete[] heightmap[retew]; delete[] heightmap; } } void Room::enterRoom(Client* client){ unloader.stop(); clients << client; client->xlocation = doorx; client->ylocation = doory; client->height = doorh.toDouble(); QString pak = QString("@vHH"); // what does this packet do? it sends some of the room data pak += Utils::encodeVL64(id); pak += ownerstr; pak += "\002"; pak += model; pak += "\002"; pak += title; pak += "\002"; pak += desc; pak += "\002"; pak += Utils::encodeVL64(showowner); // this value I think represents the amount of people in the room pak += "IH"; pak += Utils::encodeVL64(maxcount); // is this one capacity? I think so, look at the query sec oh wow.... it only gets maxcount pak += "QF"; client->sendPacket(pak); client->sendPacket(QString("Eb") + Utils::encodeVL64(category)); // and this one? sends the room's categ pak = QString("@\\"); Client* c; c = client; // and this one sends the player entered packet? yea, but there is another one when you first enter the room that sends all the players data too pak += "i:"+QString::number(c->habboid+1) + "\ra:" +QString::number(c->habboid) + "\rn:" +c->name + "\rf:" +c->figure + "\rl:" + QString::number(c->xlocation) + " " + QString::number(c->ylocation) + " " + QString::number(c->height) + "\rc:" +c->motto + "\rs:" +c->gender + "\rb:"; pak += "\x0d"; broadcastPacket(pak, NoEchoFilter, c); // if I disable the no echo filter, it will send to the local client, but I doubt that will fix it broadcastPacket("@\\", NoEchoFilter, c); } void Room::leaveRoom(Client* client){ qDebug() << client->getID() << " Left Room"; clients.removeAll(client); //broadcastPacket("@R" + QString::number(client->habboid)); broadcastPacket("@]" + QString::number(client->habboid+1)); //broadcastPacket("BKClient Left Room"); if(clients.size() < 1){ unloader.start(60*5000); } } Client* Room::getClientById(int id){ return clients.value(id, NULL); } void Room::cleanup(){ qDebug() << "Room " << id << " Inactive for 5 minutes, destroying"; loaded_rooms.remove(id); deleteLater(); // Queue for Deletion } QList Room::listClients(Filter filter, Client* myself){ if(filter == NoFilter) return QList(clients); QList ret; foreach(Client* client, clients){ if(filter == NoEchoFilter && client == myself) continue; if(filter == AdminFilter && client->getType() != Client::AdminType) continue; ret << client; } return ret; } void Room::broadcastPacket(QString packet, Filter filter, Client* sender){ foreach(Client* client, clients){ if(filter == NoEchoFilter && client == sender) continue; if(filter == AdminFilter && client->getType() != Client::AdminType) continue; client->sendPacket(packet); } } QHash Room::loaded_rooms; Room* Room::byID(int id){ Room* t = loaded_rooms.value(id, NULL); if(t == NULL){ t = new Room(id); if(!t->isValid()){ delete t; return NULL; } loaded_rooms.insert(id, t); // this would help some } return t; }