QList<AutoUpdater::UpdateFileMeta> AutoUpdater::parseFlist(QByteArray flistData) { QList<UpdateFileMeta> flist; if (flistData.isEmpty()) { qWarning() << "AutoUpdater::parseflist: Empty data"; return flist; } // Check version if (flistData[0] != '1') { qWarning() << "AutoUpdater: parseflist: Bad version "<<(uint8_t)flistData[0]; return flist; } flistData = flistData.mid(1); // Check signature if (flistData.size() < (int)(crypto_sign_BYTES)) { qWarning() << "AutoUpdater::parseflist: Truncated data"; return flist; } else { QByteArray msgData = flistData.mid(crypto_sign_BYTES); unsigned char* msg = (unsigned char*)msgData.data(); if (crypto_sign_verify_detached((unsigned char*)flistData.data(), msg, msgData.size(), key) != 0) { qCritical() << "AutoUpdater: parseflist: FORGED FLIST FILE"; return flist; } flistData = flistData.mid(crypto_sign_BYTES); } // Parse. We assume no errors handling needed since the signature is valid. while (!flistData.isEmpty()) { UpdateFileMeta newFile; memcpy(newFile.sig, flistData.data(), crypto_sign_BYTES); flistData = flistData.mid(crypto_sign_BYTES); newFile.id = dataToString(flistData); flistData = flistData.mid(newFile.id.size() + getVUint32Size(flistData)); newFile.installpath = dataToString(flistData); flistData = flistData.mid(newFile.installpath.size() + getVUint32Size(flistData)); newFile.size = dataToUint64(flistData); flistData = flistData.mid(8); flist += newFile; } return flist; }
// Load a set of splotch colour palettes int LoadColourPalette(Parameter param, std::vector<COLOURMAP>& colourMaps) { paramfile* splotchParams = param.GetParamFileReference(); // Get number of particle types int ptypes = splotchParams->find<int>("ptypes",1); // Resize colourmap vec appropriately colourMaps.resize(ptypes); // For each type for (int i=0; i<ptypes; i++) { // Check if colour is vector, if so there will be no colourmap to load if (splotchParams->find<bool>("color_is_vector"+dataToString(i),false)) std::cout << " color of ptype " << i << " is vector, so no colormap to load ..." << std::endl; else { // Read palette file std::ifstream infile (splotchParams->find<std::string>("palette"+dataToString(i)).c_str()); if(!infile) { std::cout << "Could not open palette file "<< splotchParams->find<std::string>("palette"+dataToString(i)).c_str() << " for " << "palette"+dataToString(i) << std::endl; return 0; } // Get number of colours in palette std::string dummy; int nColours; infile >> dummy >> dummy >> nColours; std::cout << " loading " << nColours << " entries of color table of ptype " << i << std::endl; // Load double step = 1./(nColours-1); for (int j=0; j<nColours; j++) { float rrr,ggg,bbb; infile >> rrr >> ggg >> bbb; colourMaps[i].addVal(j*step,COLOUR(rrr/255,ggg/255,bbb/255)); } } // Sort colourMaps[i].sortMap(); } return 1; }
void Pony::saveInventory() { win.logMsg(QObject::tr("%1 UDP: Saving Inventory for %2 (%3)").arg(LOG_INFO).arg(QString().setNum(netviewId)).arg(owner->name)); QDir playerPath(QDir::currentPath()); playerPath.cd("data"); playerPath.cd("players"); playerPath.mkdir(owner->name.toLatin1()); QFile file(QDir::currentPath()+"/data/players/"+owner->name.toLatin1()+"/inventory.lpd"); if (!file.open(QIODevice::ReadWrite)) { win.logMsg(QObject::tr("%1 UDP: Error Saving Inventory for %2 (%3)").arg(LOG_SEVERE).arg(QString().setNum(netviewId)).arg(owner->name)); return; } QByteArray invData = file.readAll(); // Try to find an existing entry for this pony, if found delete it. Then go at the end. for (int i=0; i<invData.size();) { // Read the name QString entryName = dataToString(invData.mid(i)); int nameSize = entryName.size()+getVUint32Size(invData.mid(i)); //win.logMessage("saveInventory : Reading entry "+entryName); quint8 invSize = invData[i+nameSize+4]; quint8 wornSize = invData[i+nameSize+4+1+invSize*9]; // Serialized sizeof InventoryItem is 9 if (entryName == this->name) // Delete the entry, we'll rewrite it at the end { invData.remove(i,nameSize+4+1+invSize*9+1+wornSize*5); break; } else // Skip this entry i += nameSize+4+1+invSize*9+1+wornSize*5; } // Now add our data at the end of the file QByteArray newEntry = stringToData(this->name); newEntry += uint32ToData(nBits); newEntry += uint8ToData(inv.size()); for (const InventoryItem& item : inv) { newEntry += uint8ToData(item.index); newEntry += uint32ToData(item.id); newEntry += uint32ToData(item.amount); } newEntry += uint8ToData(wornItm.size()); for (const WearableItem& item : wornItm) { newEntry += uint8ToData(item.index); newEntry += uint32ToData(item.id); } invData += newEntry; file.resize(0); file.write(invData); file.close(); }
void Pony::saveQuests() { win.logMessage("UDP: Saving quests for "+QString().setNum(netviewId)+" ("+owner->name+")", udpTag); QDir playerPath(QDir::currentPath()); playerPath.cd("data"); playerPath.cd("players"); playerPath.mkdir(owner->name.toLatin1()); QFile file(QDir::currentPath()+"/data/players/"+owner->name.toLatin1()+"/quests.dat"); if (!file.open(QIODevice::ReadWrite)) { win.logMessage("Error saving quests for "+QString().setNum(netviewId)+" ("+owner->name+")", udpTag); return; } QByteArray questData = file.readAll(); // Try to find an existing entry for this pony, if found delete it. Then go at the end. for (int i=0; i<questData.size();) { // Read the name QString entryName = dataToString(questData.mid(i)); int nameSize = entryName.size()+getVUint32Size(questData.mid(i)); //win.logMessage("saveQuests : Reading entry "+entryName); quint16 entryDataSize = 4 * dataToUint16(questData.mid(i+nameSize)); if (entryName == this->name) // Delete the entry, we'll rewrite it at the end { questData.remove(i,nameSize+entryDataSize+2); break; } else i += nameSize+entryDataSize+2; } // Now add our data at the end of the file QByteArray newEntry = stringToData(this->name); newEntry += (quint8)(quests.size() & 0xFF); newEntry += (quint8)((quests.size() >> 8) & 0xFF); for (const Quest& quest : quests) { newEntry += (quint8)(quest.id & 0xFF); newEntry += (quint8)((quest.id >> 8) & 0xFF); newEntry += (quint8)(quest.state & 0xFF); newEntry += (quint8)((quest.state >> 8) & 0xFF); } questData += newEntry; file.resize(0); file.write(questData); file.close(); }
void Pony::loadQuests() { win.logMessage("UDP: Loading quests for "+QString().setNum(netviewId)+" ("+owner->name+")", udpTag); QDir playerPath(QDir::currentPath()); playerPath.cd("data"); playerPath.cd("players"); playerPath.mkdir(owner->name.toLatin1()); QFile file(QDir::currentPath()+"/data/players/"+owner->name.toLatin1()+"/quests.dat"); if (!file.open(QIODevice::ReadOnly)) { win.logMessage("Error loading quests for "+QString().setNum(netviewId)+" ("+owner->name+")", sysTag); return; } QByteArray questData = file.readAll(); file.close(); // Try to find an existing entry for this pony and load it. for (int i=0; i<questData.size();) { // Read the name QString entryName = dataToString(questData.mid(i)); int nameSize = entryName.size()+getVUint32Size(questData.mid(i)); i+=nameSize; //win.logMessage("loadQuests : Reading entry "+entryName); quint16 nquests = dataToUint16(questData.mid(i)); i+=2; if (entryName == this->name) // Read the entry { for (int j=0; j<nquests; j++) { quint16 questId = dataToUint16(questData.mid(i)); quint16 questState = dataToUint16(questData.mid(i+2)); i+=4; for (Quest& quest : quests) { if (quest.id == questId) { quest.state = questState; break; } } } return; } else i += nquests * 4; } }
int main2(int argc, char** argv) { options* opt = initProgram(argc, argv); data d; printf("Row size = %lu\n", sizeof(data)); int fd = OpenFile(opt->data_file, O_RDONLY); for(int i=0; i<30; i++) { printf("Bytes read = %d\n", SafeRead(fd, (char*)&d, sizeof(data))); printf("Data[%d]: %s\n", i, dataToString(&d)); } CHECK_ERROR( CloseFile(fd) ); exit(0); }
void WindowUSART::serialReceived() { // this->ui->data->setText(serial->readAll()); QByteArray dane; char a; dane=serial->readAll(); a=dane.at(0); this->ui->data->setText(dataToString(a)); leds(a); }
const std::string DataTree::dataToString(DataTree* treeNode, int depth) { std::string data = std::string(); if (treeNode->children.empty()) { return treeNode->value + "\n"; } else { const std::vector<std::string> keySet = treeNode->getKeySet(); int count = 0; for (const auto key : keySet) { int childrenCount = treeNode->children[key]->getChildrenSize(); if (childrenCount != 0) { data += (key + " " + treeNode->children[key]->value + "\n"); for (unsigned int i = 0; i <= depth; i++) { data += "\t"; } } else { data += (key + " "); } data += dataToString(treeNode->children[key], depth + 1); if (count < keySet.size() - 1) { for (unsigned int i = 0; i < depth; i++) { data += "\t"; } } count++; } return data; } }
void work(int info_fd, int log_fd) { data pcData = getData(); // Write to info file as binary serialized data ssize_t charWritten = SafeWrite(info_fd, (char*)&pcData, sizeof(data)); if (charWritten != sizeof(data)) FILE_ERR("Not all data written to info file"); // Write to log file in csv format char* pdDataText = dataToString(&pcData); size_t expected_size = strlen(pdDataText)*sizeof(char); charWritten = SafeWriteLine(log_fd, pdDataText, expected_size); if (charWritten != expected_size) FILE_ERR("Not all data written to log file"); free(pdDataText); }
void print_record(const QJDns::Record &r) { switch(r.type) { case QJDns::A: printf(" A: [%s] (ttl=%d)\n", qPrintable(r.address.toString()), r.ttl); break; case QJDns::Aaaa: printf(" AAAA: [%s] (ttl=%d)\n", qPrintable(r.address.toString()), r.ttl); break; case QJDns::Mx: printf(" MX: [%s] priority=%d (ttl=%d)\n", r.name.data(), r.priority, r.ttl); break; case QJDns::Srv: printf(" SRV: [%s] port=%d priority=%d weight=%d (ttl=%d)\n", r.name.data(), r.port, r.priority, r.weight, r.ttl); break; case QJDns::Cname: printf(" CNAME: [%s] (ttl=%d)\n", r.name.data(), r.ttl); break; case QJDns::Ptr: printf(" PTR: [%s] (ttl=%d)\n", r.name.data(), r.ttl); break; case QJDns::Txt: { printf(" TXT: count=%d (ttl=%d)\n", r.texts.count(), r.ttl); for(int n = 0; n < r.texts.count(); ++n) printf(" len=%d [%s]\n", r.texts[n].size(), qPrintable(dataToString(r.texts[n]))); break; } case QJDns::Hinfo: printf(" HINFO: [%s] [%s] (ttl=%d)\n", r.cpu.data(), r.os.data(), r.ttl); break; case QJDns::Ns: printf(" NS: [%s] (ttl=%d)\n", r.name.data(), r.ttl); break; default: printf(" (Unknown): type=%d, size=%d (ttl=%d)\n", r.type, r.rdata.size(), r.ttl); break; } }
void receiveChatMessage(QByteArray msg, Player* player) { QString txt = dataToString(msg.mid(7)); QString author = player->pony.name; //logMessage("Chat "+author+":"+txt); if (txt.startsWith("/stuck") || txt.startsWith("unstuck me")) { sendLoadSceneRPC(player, player->pony.sceneName); } else if (txt == ":anhero") { QTimer *anheroTimer = new QTimer(); anheroTimer->setSingleShot(true); QString deadPlayerName = player->name; QObject::connect(anheroTimer, &QTimer::timeout, [=]() { // Find player again instead of reusing pointer, in case they disconnect Player* deadPlayer = Player::findPlayer(Player::udpPlayers, deadPlayerName); if (deadPlayer->connected && deadPlayer->pony.dead) { sendSetStatRPC(deadPlayer, 1, deadPlayer->pony.health); Scene* scene = findScene(deadPlayer->pony.sceneName); for (Player* other : scene->players) sendNetviewInstantiate(&deadPlayer->pony, other); deadPlayer->pony.dead = false; } delete anheroTimer; // Don't delete deadPlayer here. That kills the player's session } ); if (!player->pony.dead) { player->pony.dead = true; sendSetStatRPC(player, 1, 0); anheroTimer->start(5000); Scene* scene = findScene(player->pony.sceneName); for (Player* other : scene->players) sendNetviewRemove(other, player->pony.netviewId, NetviewRemoveReasonKill); } } else if (txt == ":commands") { sendChatMessage(player, "<span color=\"yellow\">List of Commands:</span><br /><em>:roll</em><br /><span color=\"yellow\">Rolls a random number between 00 and 99</span><br /><em>:msg player message</em><br /><span color=\"yellow\">Sends a private message to a player</span><br /><em>:names</em><br /><span color=\"yellow\">Lists all players on the server</span><br /><em>:me action</em><br /><span color=\"yellow\">States your current action</span><br /><em>:tp location</em><br /><span color=\"yellow\">Teleports your pony to the specified region</span>", "[Server]", ChatLocal); } else if (txt.startsWith(":msg")) { if(txt.count(" ") < 2) sendChatMessage(player, ":msg<br /><span color=\"yellow\">Usage:</span><br /><em>:msg player message</em><br /><span color=\"yellow\">Player names are case-insensitive, ignore spaces and you do not need to type out their full name.</span>", author, ChatLocal); else { for (int i=0; i<Player::udpPlayers.size(); i++) { if (Player::udpPlayers[i]->inGame>=2 && Player::udpPlayers[i]->pony.name.toLower().remove(" ") .startsWith(txt.toLower().section(" ", 1, 1))) { txt = txt.remove(0, txt.indexOf(" ", 5) + 1); sendChatMessage(Player::udpPlayers[i], "<span color=\"yellow\">[PM] </span>" + txt, author, ChatLocal); sendChatMessage(player, "<span color=\"yellow\">[PM to " + Player::udpPlayers[i]->pony.name + "] </span>" + txt, author, ChatLocal); } } } } else if (txt.startsWith(":names")) { QString namesmsg = "<span color=\"yellow\">Players currently in game:</span>"; for (int i=0; i<Player::udpPlayers.size(); i++) if (Player::udpPlayers[i]->inGame>=2) namesmsg += "<br />#b" + Player::udpPlayers[i]->pony.name + "#b<br /><span color=\"yellow\"> - in " + Player::udpPlayers[i]->pony.sceneName + "</span>"; sendChatMessage(player, namesmsg, "[Server]", ChatLocal); } else if (txt.startsWith(":tp")) { if (txt.count(" ") < 1) { QString msgtosend = ":tp<br /><span color=\"yellow\">Usage:</span><br /><em>:tp location</em><br /><span color=\"yellow\">Available locations:</span><em>"; for (int i=0; i<Scene::scenes.size(); i++) msgtosend += "<br />" + Scene::scenes[i].name; sendChatMessage(player, msgtosend + "</em>", author, ChatLocal); } else sendLoadSceneRPC(player, txt.remove(0, 4)); } else if (txt == ":me") { sendChatMessage(player, ":me<br /><span color=\"yellow\">Usage:</span><br /><em>:me action</em>", author, ChatLocal); } else // Broadcast the message { int rollnum = -1; QString rollstr; bool actmsg = false; if (txt == ":roll") { if (player->chatRollCooldownEnd < QDateTime::currentDateTime()) { rollnum = qrand() % 100; rollstr.sprintf("<span color=\"yellow\">#b%s#b rolls %02d</span>", author.toLocal8Bit().data(), rollnum); player->chatRollCooldownEnd = QDateTime::currentDateTime().addSecs(10); } } if (txt.startsWith(":me ")) { actmsg = true; txt.remove(0, 3); txt = "<em>#b* " + author + "#b" + txt + "</em>"; } if ((quint8)msg[6] == 8) // Local chat only { Scene* scene = findScene(player->pony.sceneName); if (scene->name.isEmpty()) logMessage(QObject::tr("UDP: Can't find the scene for chat message, aborting")); else { for (int i=0; i<scene->players.size(); i++) { if (scene->players[i]->inGame>=2) { if (rollnum > -1) sendChatMessage(scene->players[i], rollstr, "[Server]", ChatLocal); else if (actmsg) sendChatMessage(scene->players[i], txt, "", ChatLocal); else if (txt.startsWith(">")) sendChatMessage(scene->players[i], "<span color=\"green\">" + txt + "</span>", author, ChatLocal); else sendChatMessage(scene->players[i], txt, author, ChatLocal); } } } } else // Send globally { for (int i=0; i<Player::udpPlayers.size(); i++) { if (Player::udpPlayers[i]->inGame>=2) { if (rollnum > -1) sendChatMessage(Player::udpPlayers[i], rollstr, "[Server]", ChatGeneral); else if (actmsg) sendChatMessage(Player::udpPlayers[i], txt, "", ChatGeneral); else if (txt.startsWith(">")) sendChatMessage(Player::udpPlayers[i], "<span color=\"green\">" + txt + "</span>", author, ChatGeneral); else sendChatMessage(Player::udpPlayers[i], txt, author, ChatGeneral); } } } } }
void Widget::udpProcessPendingDatagrams() { while (udpSocket->hasPendingDatagrams()) { QHostAddress rAddr; quint16 rPort; QByteArray datagram; qint64 dataRead = 0; int datagramSize = udpSocket->pendingDatagramSize(); datagram.resize(datagramSize); while(dataRead < datagram.size()) { qint64 readNow = udpSocket->readDatagram(datagram.data()+dataRead, datagramSize, &rAddr, &rPort); // le +dataRead sur un tableau, ça décale le pointeur d'un offset de taille dataRead ! if(readNow != -1) { dataRead += readNow; // Remember the total number of bytes read, so we know when to stop if (datagramSize > (datagram.size() - dataRead)) // Make sure we don't overflow datagramSize = (datagram.size() - dataRead); } else { logStatusMessage(QString("Socket error : ").arg(udpSocket->errorString())); return; } } // Add player on connection if ((unsigned char)datagram[0]==MsgConnect && (unsigned char)datagram[1]==0 && (unsigned char)datagram[2]==0 && datagram.size()>=22) { QString name = dataToString(datagram.right(datagram.size()-22)); int nameFullSize = getVUint32Size(datagram.right(datagram.size()-22))+name.size(); QString sesskey = dataToString(datagram.right(datagram.size()-22-nameFullSize)); //logMessage(QString("UDP: Connect detected with name : ")+name); //logMessage(QString("UDP: Connect detected with sesskey : ")+sesskey); //logMessage(QString("UDP: Datagram was : ")+datagram.toHex()); bool is_sesskey_valid = true; if (enableSessKeyValidation) { is_sesskey_valid = QCryptographicHash::hash(QString(sesskey.right(40) + saltPassword).toLatin1(), QCryptographicHash::Md5).toHex() == sesskey.left(32); } if (is_sesskey_valid) { //logMessage("Sesskey token accepted"); // Create new player if needed, else just update player Player* newPlayer = Player::findPlayer(udpPlayers, rAddr.toString(),rPort); if (newPlayer->IP != rAddr.toString()) // IP:Port not found in player list { newPlayer->resetNetwork(); //newPlayer->connected = true; // Not really connected until we finish the handshake newPlayer->name = name; newPlayer->IP = rAddr.toString(); newPlayer->port = rPort; // Check if we have too many players connected int n=0; for (int i=0;i<udpPlayers.size();i++) if (udpPlayers[i]->connected) n++; if (n>=maxConnected) { sendMessage(newPlayer, MsgDisconnect, "Error : Too many players connected. Try again later."); } else // If not add the player udpPlayers << newPlayer; } else // IP:Port found in player list { if (newPlayer->connected) // TODO: Error, player already connected { sendMessage(newPlayer, MsgDisconnect, "Error : Player already connected."); return; } // Check if we have too many players connected int n=0; for (int i=0;i<udpPlayers.size();i++) if (udpPlayers[i]->connected) n++; if (n>=maxConnected) { sendMessage(newPlayer, MsgDisconnect, "Error : Too many players connected. Try again later."); } newPlayer->resetNetwork(); newPlayer->name = name; newPlayer->IP = rAddr.toString(); newPlayer->port = rPort; //newPlayer->connected = true; // We're not really connected until we finish the handshake } } else { QString badHash = QCryptographicHash::hash((QString(sesskey.right(40)) +saltPassword).toLatin1(), QCryptographicHash::Md5).toHex(); logMessage("UDP: Sesskey rejected: got '"+badHash+"' instead of '"+sesskey.left(32) +"', passhash was '"+QString(sesskey.right(40))); Player* newPlayer = new Player; newPlayer->IP = rAddr.toString(); newPlayer->port = rPort; sendMessage(newPlayer, MsgDisconnect, "Error : Wrong sesskey hash."); return; } } Player* player = Player::findPlayer(udpPlayers, rAddr.toString(), rPort); if (player->IP == rAddr.toString() && player->port == rPort) { // Acquire datas player->receivedDatas->append(datagram); // Process data receiveMessage(player); } else // You need to connect with TCP first { logMessage("UDP: Request from unknown peer rejected : "+rAddr.toString()+":"+QString().setNum(rPort)); // Send disconnect message manually QString data("You're not connected, please login first. (aka the server has no idea who the hell you are)"); QByteArray msg(6,0); msg[0] = MsgDisconnect; msg[3] = (quint8)(((data.size()+1)*8)&0xFF); msg[4] = (quint8)((((data.size()+1)*8)>>8)&0xFF); msg[5] = (quint8)data.size(); msg += data; win.udpSocket->writeDatagram(msg,rAddr,rPort); } } }
bool Pony::loadInventory() { win.logMsg(QObject::tr("%1 UDP: Loading Inventory for %2 (%3)").arg(LOG_INFO).arg(QString().setNum(netviewId)).arg(owner->name)); QDir playerPath(QDir::currentPath()); playerPath.cd("data"); playerPath.cd("players"); playerPath.mkdir(owner->name.toLatin1()); QFile file(QDir::currentPath()+"/data/players/"+owner->name.toLatin1()+"/inventory.lpd"); if (!file.open(QIODevice::ReadOnly)) { win.logMsg(QObject::tr("%1 UDP: Error Loading Inventory for %2 (%3)").arg(LOG_SEVERE).arg(QString().setNum(netviewId)).arg(owner->name)); return false; } QByteArray invData = file.readAll(); file.close(); // Try to find an existing entry for this pony, if found load it. for (int i=0; i<invData.size();) { // Read the name QString entryName = dataToString(invData.mid(i)); int nameSize = entryName.size()+getVUint32Size(invData.mid(i)); //win.logMessage("loadInventory : Reading entry "+entryName); quint8 invSize = invData[i+nameSize+4]; quint8 wornSize = invData[i+nameSize+4+1+invSize*9]; // Serialized sizeof InventoryItem is 9 if (entryName == this->name) { i += nameSize; nBits = dataToUint32(invData.mid(i)); i+=5; // Skip nBits and invSize inv.clear(); for (int j=0; j<invSize; j++) { InventoryItem item; item.index = invData[i]; i++; item.id = dataToUint32(invData.mid(i)); i+=4; item.amount = dataToUint32(invData.mid(i)); i+=4; inv.append(item); } i++; // Skip wornSize wornItm.clear(); wornSlots = 0; for (int j=0; j<wornSize; j++) { WearableItem item; item.index = invData[i]; i++; item.id = dataToUint32(invData.mid(i)); i+=4; wornItm.append(item); wornSlots |= loe.wearablePositionsMap[item.id]; } return true; } else // Skip this entry i += nameSize+4+1+invSize*9+1+wornSize*5; } return false; // Entry not found }
void receiveChatMessage(QByteArray msg, Player* player) { QString txt = dataToString(msg.mid(7)); QString author = player->pony.name; //win.logMessage("Chat "+author+":"+txt); if (txt.startsWith("/stuck") || txt.startsWith("unstuck me")) { sendLoadSceneRPC(player, player->pony.sceneName); } else if (txt == ":commands") { sendChatMessage(player, "<span color=\"yellow\">List of Commands:</span><br /><em>:roll</em><br /><span color=\"yellow\">Rolls a random number between 00 and 99</span><br /><em>:msg player message</em><br /><span color=\"yellow\">Sends a private message to a player</span><br /><em>:names</em><br /><span color=\"yellow\">Lists all players on the server</span><br /><em>:me action</em><br /><span color=\"yellow\">States your current action</span><br /><em>:tp location</em><br /><span color=\"yellow\">Teleports your pony to the specified region</span>", "[Server]", ChatLocal); } else if (txt.startsWith(":msg")) { if(txt.count(" ") < 2) sendChatMessage(player, ":msg<br /><span color=\"yellow\">Usage:</span><br /><em>:msg player message</em><br /><span color=\"yellow\">Player names are case-insensitive, ignore spaces and you do not need to type out their full name.</span>", author, ChatLocal); else { for (int i=0; i<win.udpPlayers.size(); i++) { if (win.udpPlayers[i]->inGame>=2 && win.udpPlayers[i]->pony.name.toLower().remove(" ").startsWith(txt.toLower().section(" ", 1, 1))) { txt = txt.remove(0, txt.indexOf(" ", 5) + 1); sendChatMessage(win.udpPlayers[i], "<span color=\"yellow\">[PM] </span>" + txt, author, ChatLocal); sendChatMessage(player, "<span color=\"yellow\">[PM to " + win.udpPlayers[i]->pony.name + "] </span>" + txt, author, ChatLocal); } } } } else if (txt.startsWith(":names")) { QString namesmsg = "<span color=\"yellow\">Players currently in game:</span>"; for (int i=0; i<win.udpPlayers.size(); i++) if (win.udpPlayers[i]->inGame>=2) namesmsg += "<br />#b" + win.udpPlayers[i]->pony.name + "#b<br /><span color=\"yellow\"> - in " + win.udpPlayers[i]->pony.sceneName + "</span>"; sendChatMessage(player, namesmsg, "[Server]", ChatLocal); } else if (txt.startsWith(":tp")) { if (txt.count(" ") < 1) { QString msgtosend = ":tp<br /><span color=\"yellow\">Usage:</span><br /><em>:tp location</em><br /><span color=\"yellow\">Available locations:</span><em>"; for (int i=0; i<win.scenes.size(); i++) msgtosend += "<br />" + win.scenes[i].name; sendChatMessage(player, msgtosend + "</em>", author, ChatLocal); } else sendLoadSceneRPC(player, txt.remove(0, 4)); } else if (txt == ":me") { sendChatMessage(player, ":me<br /><span color=\"yellow\">Usage:</span><br /><em>:me action</em>", author, ChatLocal); } else // Broadcast the message { int rollnum = -1; QString rollstr; bool actmsg = false; if (txt == ":roll") { if (player->chatRollCooldownEnd < QDateTime::currentDateTime()) { rollnum = qrand() % 100; rollstr.sprintf("<span color=\"yellow\">#b%s#b rolls %02d</span>", author.toLocal8Bit().data(), rollnum); player->chatRollCooldownEnd = QDateTime::currentDateTime().addSecs(10); } } if (txt.startsWith(":me ")) { actmsg = true; txt.remove(0, 3); txt = "<em>#b* " + author + "#b" + txt + "</em>"; } if ((quint8)msg[6] == 8) // Local chat only { Scene* scene = findScene(player->pony.sceneName); if (scene->name.isEmpty()) win.logMessage("UDP: Can't find the scene for chat message, aborting"); else { for (int i=0; i<scene->players.size(); i++) { if (scene->players[i]->inGame>=2) { if (rollnum > -1) sendChatMessage(scene->players[i], rollstr, "[Server]", ChatLocal); else if (actmsg) sendChatMessage(scene->players[i], txt, "", ChatLocal); else if (txt.startsWith(">")) sendChatMessage(scene->players[i], "<span color=\"green\">" + txt + "</span>", author, ChatLocal); else sendChatMessage(scene->players[i], txt, author, ChatLocal); } } } } else // Send globally { for (int i=0; i<win.udpPlayers.size(); i++) { if (win.udpPlayers[i]->inGame>=2) { if (rollnum > -1) sendChatMessage(win.udpPlayers[i], rollstr, "[Server]", ChatGeneral); else if (actmsg) sendChatMessage(win.udpPlayers[i], txt, "", ChatGeneral); else if (txt.startsWith(">")) sendChatMessage(win.udpPlayers[i], "<span color=\"green\">" + txt + "</span>", author, ChatGeneral); else sendChatMessage(win.udpPlayers[i], txt, author, ChatGeneral); } } } } }
void Widget::udpProcessPendingDatagrams() { while (udpSocket->hasPendingDatagrams()) { QHostAddress rAddr; quint16 rPort; QByteArray datagram; qint64 dataRead = 0; int datagramSize = udpSocket->pendingDatagramSize(); datagram.resize(datagramSize); while(dataRead < datagram.size()) { qint64 readNow = udpSocket->readDatagram(datagram.data()+dataRead, datagramSize, &rAddr, &rPort); // le +dataRead sur un tableau, ça décale le pointeur d'un offset de taille dataRead ! if(readNow != -1) { dataRead += readNow; // Counts the number of bytes read in total, stop when DataRead reached pendingDatagramSize if (datagramSize > (datagram.size() - dataRead)) // Evite de lire après la fin du tableau en mode fragmenté, evite donc que dataSent dépasse datagramSize, sinon Overflow et envoi de données inutiles et aléatoires !! datagramSize = (datagram.size() - dataRead); //QMessageBox::information(NULL,"SenderInfo",QString("DatagramSize : %1 sentNow : %2 dataSent : %3 Sizeof(datagram->data()) : %4").arg(QString().setNum(datagramSize),QString().setNum(sentNow),QString().setNum(dataSent),QString().setNum(datagram->size()))); } else { // Here, we add a message to the udpMessages for filtering later. logStatusMessage(QString("Socket error: ").arg(udpSocket->errorString()), udpTag); return; } } // Add player on connection if ((unsigned char)datagram[0]==MsgConnect && (unsigned char)datagram[1]==0 && (unsigned char)datagram[2]==0 && datagram.size()>=22) { QString name = dataToString(datagram.right(datagram.size()-22)); int nameFullSize = getVUint32Size(datagram.right(datagram.size()-22))+name.size(); QString sesskey = dataToString(datagram.right(datagram.size()-22-nameFullSize)); //logMessage(QString("UDP: Connect detected with name : ")+name, udpTag); //logMessage(QString("UDP: Connect detected with sesskey : ")+sesskey, udpTag); //logMessage(QString("UDP: Datagram was : ")+datagram.toHex(), udpTag); bool is_sesskey_valid = true; if (enableSessKeyValidation) { is_sesskey_valid = QCryptographicHash::hash(QString(sesskey.right(40) + saltPassword).toLatin1(), QCryptographicHash::Md5).toHex() == sesskey.left(32); } if (is_sesskey_valid) { //logMessage("Sesskey token accepted", udpTag); // Create new player if needed, else just update player Player* newPlayer = Player::findPlayer(udpPlayers, rAddr.toString(),rPort); if (newPlayer->IP != rAddr.toString()) // IP:Port not found in player list { newPlayer->resetNetwork(); //newPlayer->connected = true; // Not really connected until we finish the handshake newPlayer->name = name; newPlayer->IP = rAddr.toString(); newPlayer->port = rPort; // Check if we have too many players connected int n=0; for (int i=0;i<udpPlayers.size();i++) if (udpPlayers[i]->connected) n++; if (n>=maxConnected) { sendMessage(newPlayer, MsgDisconnect, "Error: Too many players connected. Try again later."); } else // If not add the player udpPlayers << newPlayer; } else // IP:Port found in player list { if (newPlayer->connected) // TODO: Error, player already connected { sendMessage(newPlayer, MsgDisconnect, "Error: Player already connected."); return; } // Check if we have too many players connected int n=0; for (int i=0;i<udpPlayers.size();i++) if (udpPlayers[i]->connected) n++; if (n>=maxConnected) { sendMessage(newPlayer, MsgDisconnect, "Error: Too many players connected. Try again later."); } newPlayer->resetNetwork(); newPlayer->name = name; newPlayer->IP = rAddr.toString(); newPlayer->port = rPort; //newPlayer->connected = true; // We're not really connected until we finish the handshake } } else { QString badHash = QCryptographicHash::hash((QString(sesskey.right(40)) +saltPassword).toLatin1(), QCryptographicHash::Md5).toHex(); logMessage("UDP: Sesskey rejected: got '"+badHash+"' instead of '"+sesskey.left(32)+"', passhash was '"+QString(sesskey.right(40)), udpTag); Player* newPlayer = new Player; newPlayer->IP = rAddr.toString(); newPlayer->port = rPort; sendMessage(newPlayer, MsgDisconnect, "Error : Wrong sesskey hash."); return; } } Player* player = Player::findPlayer(udpPlayers, rAddr.toString(), rPort); if (player->IP == rAddr.toString() && player->port == rPort) { // Acquire data player->receivedDatas->append(datagram); // Process data receiveMessage(player); } else // You need to connect with TCP first { logMessage("UDP: Request from unknown peer rejected : "+rAddr.toString()+":"+QString().setNum(rPort), udpTag); // Send disconnect message manually, with an appropriate message. QString data("BITCH, YOU ARE EITHER A HACKER OR THE SERVER JUST HATES THE F**K OUT OF YOU. RELOG OR YOU AINT GETTIN ON THIS SERVER, K?"); QByteArray msg(6,0); msg[0] = MsgDisconnect; msg[3] = (quint8)(((data.size()+1)*8)&0xFF); msg[4] = (quint8)((((data.size()+1)*8)>>8)&0xFF); msg[5] = (quint8)data.size(); msg += data; win.udpSocket->writeDatagram(msg,rAddr,rPort); } } }
QList<Pony> Player::loadPonies(Player* player) { QList<Pony> ponies; QFile file(QDir::currentPath()+"/data/players/"+player->name.toLatin1()+"/ponies.dat"); if (!file.open(QIODevice::ReadOnly)) return ponies; QByteArray data = file.readAll(); int i=0; while (i<data.size()) { Pony pony{player}; // Read the ponyData unsigned strlen; unsigned lensize=0; { unsigned char num3; int num=0, num2=0; do { num3 = data[i+lensize]; lensize++; num |= (num3 & 0x7f) << num2; num2 += 7; } while ((num3 & 0x80) != 0); strlen = (uint) num; } int ponyDataSize = strlen+lensize+43; pony.ponyData = data.mid(i,ponyDataSize); pony.name = dataToString(pony.ponyData); // The name is the first elem //win.logMessage("Found pony : "+pony.name); i+=ponyDataSize; // Read pos UVector pos = dataToVector(data.mid(i,12)); pony.pos = pos; i+=12; // Read sceneName unsigned strlen2; unsigned lensize2=0; { unsigned char num3; int num=0, num2=0; do { num3 = data[i+lensize2]; lensize2++; num |= (num3 & 0x7f) << num2; num2 += 7; } while ((num3 & 0x80) != 0); strlen2 = (uint) num; } pony.sceneName = data.mid(i+lensize2, strlen2).toLower(); i+=strlen2+lensize2; // Create quests for (int i=0; i<win.quests.size(); i++) { Quest quest = win.quests[i]; quest.setOwner(player); pony.quests << quest; } ponies << pony; } return ponies; }
const std::string DataTree::toString() { return dataToString(this, 0); }
/***************************************************************************//** * @brief Updates LCD buffer and sends buffer to LCD module * * +-----------------------------------------+ * |_____________ SIGFOX DEMO_______________| * | UL: XX XX XX XX XX XX | * | XX XX XX XX XX XX | * | | * | DL: XX XX XX XX XX XX | * | XX XX | * |_________________________________________| * | (c) Texas Instruments | * +-----------------------------------------+ * *******************************************************************************/ static void updateLCD(void) { char ulmsg[36] = {0}; char dlmsg[24] = {0}; char ulmsg1[18] = {0}; char ulmsg2[18] = {0}; char dlmsg1[18] = {0}; char dlmsg2[6] = {0}; dataToString((unsigned char*) message, ulmsg, 24); dataToString((unsigned char*) ReceivedPayload, dlmsg, 16); // Format the converted string to display on LCD unsigned char n; unsigned char m = 0; for(n=0;n<12;n++) { if(m % 3 == 0) { ulmsg1[m] = ' '; ulmsg2[m] = ' '; dlmsg1[m] = ' '; if(n<4) { dlmsg2[m] = ' '; } m++; } ulmsg1[m] = ulmsg[n]; ulmsg2[m] = ulmsg[12+n]; dlmsg1[m] = dlmsg[n]; if(n<4) { dlmsg2[m] = dlmsg[12+n]; } m++; } // Clear LCD lcdBufferClear(0); lcdSendBuffer(0); // Load status buffer lcdBufferPrintStringAligned(0, "Sigfox Demo", eLcdAlignCenter, eLcdPage0); lcdBufferSetHLine(0, 0, LCD_COLS-1, 7); lcdBufferInvertPage(0, 0, LCD_COLS, eLcdPage0); lcdSendBufferPart(0, 0, 127, eLcdPage0,eLcdPage0); lcdBufferClearPart(0, 0, 127, eLcdPage1, eLcdPage6); lcdBufferPrintString(0, "UL:", 0, eLcdPage1); lcdBufferPrintString(0, ulmsg1, 20, eLcdPage1); lcdSendBufferPart(0, 0, 127, eLcdPage1,eLcdPage1); lcdBufferPrintString(0, ulmsg2, 20, eLcdPage2); lcdSendBufferPart(0, 20, 127, eLcdPage2,eLcdPage2); lcdBufferClearPart(0, 0, 127, eLcdPage3, eLcdPage6); lcdBufferPrintString(0, "DL:", 0, eLcdPage4); lcdBufferPrintString(0, dlmsg1, 20, eLcdPage4); lcdSendBufferPart(0, 0, 127, eLcdPage4,eLcdPage4); lcdBufferPrintString(0, dlmsg2, 20, eLcdPage5); lcdSendBufferPart(0, 20, 55, eLcdPage5,eLcdPage5); lcdBufferPrintString(0, "(c) Texas Instruments" , 0, eLcdPage7); lcdBufferSetHLine(0, 0, LCD_COLS-1, 55); lcdBufferInvertPage(0, 0, LCD_COLS, eLcdPage7); // Send the buffer to the LCD screen lcdSendBufferPart(0, 0, 127, eLcdPage7, eLcdPage7); }