void gdatastring(Node *nam, Strlit *sval) { Prog *p; Node nod1; p = gins(ADATA, nam, N); datastring(sval->s, sval->len, &p->to); p->from.scale = types[tptr]->width; p->to.index = p->to.type; p->to.type = D_ADDR; //print("%P\n", p); nodconst(&nod1, types[TINT], sval->len); p = gins(ADATA, nam, &nod1); p->from.scale = widthint; p->from.offset += widthptr; }
void UDPServer::processDatagram(const QByteArray &datagram) { QString datastring(datagram); switch (datastring.section(';',0,0).toInt()) { case 1: // set the correct IP to send to otherNode->setAddress(datastring.section(';',1,1)); qDebug() << "otherNode adress set to: " << datastring.section(';',1,1); // reply to SYN msg sendSYNACK(); qDebug() << "processed Datagram case 1"; break; case 3: // reply to ACK msg stopTimeOutTimer(); sendAME(); qDebug() << "processed Datagram case 3: Handshake complete"; break; case 5: // intern reply to the 'alive' msg of the client if (!connected) setConnected(true); resetAliveTimer(); qDebug() << "processed Datagram case 5"; break; case 11: // incomming request for data from server handleDataRequest(datagram); qDebug() << "processed Datagram case 11"; break; default: // Just break on everything else break; } }
int dstringptr(Sym *s, int off, char *str) { Prog *p; off = rnd(off, widthptr); p = gins(ADATA, N, N); p->from.type = D_EXTERN; p->from.index = D_NONE; p->from.sym = linksym(s); p->from.offset = off; p->from.scale = widthptr; datastring(str, strlen(str)+1, &p->to); p->to.index = p->to.type; p->to.type = D_ADDR; p->to.etype = simtype[TINT]; off += widthptr; return off; }
void TableView3D::keyPressEvent(QKeyEvent *event) { if(event->key() == Qt::Key_C && event->modifiers() & Qt::ControlModifier) { //Copy if (ui.tableWidget->selectedItems().size() == 0) { return; } QByteArray itembytes; //int row = ui.tableWidget->selectedItems()[0]->row(); QMap<int,QMap<int,QString> > tablemap; int maxrow = 0; int maxcolumn = 0; int minrow = 255; int mincolumn = 255; /*foreach(QTableWidgetItem* item,ui.tableWidget->selectedItems()) { tablemap[item->row()][item->column()] = item->text(); if (item->row() > maxrow) maxrow = item->row(); if (item->column() > maxcolumn) maxcolumn = item->column(); if (item->row() < minrow) minrow = item->row(); if (item->column() < mincolumn) mincolumn = item->column(); }*/ for (int i=minrow;i<=maxrow;i++) { for (int j=mincolumn;j<=maxcolumn;j++) { if (tablemap.contains(i)) { if (tablemap[i].contains(j)) { itembytes.append(tablemap[i][j]); itembytes.append("\t"); } else { itembytes.append("\t"); } } else { //itembytes.append("\n"); } } itembytes = itembytes.mid(0,itembytes.length()-1); itembytes.append("\n"); } QMimeData * mime = new QMimeData(); mime->setData("text/plain",itembytes); QApplication::clipboard()->setMimeData(mime); } else if(event->key() == Qt::Key_V && event->modifiers() & Qt::ControlModifier) { //Paste if (ui.tableWidget->selectedItems().size() == 0) { //Can't paste when we don't know where to paste! return; } if (ui.tableWidget->selectedItems().size() != 1) { QMessageBox::information(0,"Error","Pasting to a selection group is not supported yet. Please select the top left cell you wish to paste from"); return; } int rowindex = ui.tableWidget->selectedItems()[0].y(); int columnindex = ui.tableWidget->selectedItems()[0].x(); int newrow = 0; int newcolumn = 0; QByteArray data = QApplication::clipboard()->mimeData()->data("text/plain"); QString datastring(data); QStringList datastringsplit = datastring.split("\n"); //Check to make sure we're in-bounds first if (datastringsplit.size() + rowindex > ui.tableWidget->rowCount()+1) { QMessageBox::information(0,"Error","Attempted to paste a block that does not fit!"); return; } foreach(QString line,datastringsplit) { if (line.split("\t").size() + columnindex > ui.tableWidget->columnCount()+1) { QMessageBox::information(0,"Error","Attempted to paste a block that does not fit!"); return; } } //Disable signals, so we can write the table all at once //bool valid = true; QMap<int,QMap<int,QString> > tmpvaluemap; QStringList invalidreasons; QList<QPair<QPair<int,int>,double> > valuelist; //setRange foreach(QString line,datastringsplit) { QStringList linesplit = line.split("\t"); foreach (QString item,linesplit) { if (item != "") { if (!tmpvaluemap.contains(rowindex+newrow)) { tmpvaluemap[rowindex+newrow] = QMap<int,QString>(); } //newvallist.append(item.toDouble()); QPair<QPair<int,int>,double> val; val.first = QPair<int,int>(rowindex+newrow,columnindex+newcolumn); val.second = item.toDouble(); valuelist.append(val); //tmpvaluemap[rowindex+newrow][columnindex+newcolumn] = ui.tableWidget->item(rowindex+newrow,columnindex+newcolumn)->text(); QString verifystr = verifyValue(rowindex+newrow,columnindex+newcolumn,item); if (verifystr != "GOOD") { invalidreasons.append(verifystr); //valid = false; } //ui.tableWidget->item(rowindex+newrow,columnindex+newcolumn)->setText(item); } newcolumn++; } newcolumn=0; newrow++; } setRange(valuelist); /* //Write the values, and re-enable the signals. if (valid) { writeTable(true); } else { for (QMap<int,QMap<int,QString> >::const_iterator i=tmpvaluemap.constBegin();i!=tmpvaluemap.constEnd();i++) { for (QMap<int,QString>::const_iterator j=i.value().constBegin();j!=i.value().constEnd();j++) { ui.tableWidget->item(i.key(),j.key())->setText(j.value()); } } QString errorstr = ""; foreach(QString reason,invalidreasons) { errorstr += reason + ","; } QMessageBox::information(0,"Error",errorstr); }*/ }
void CV(const char* fileName, const char* type, double A, double v1, double v2, double v3, double v4, double &vdepl, double &evdepl, double &neff, double &eneff, double &w, double &ew, bool savePlots=false) { TString simsstring("SIMU"); TString datastring("DATA"); int NMAX = 1001; if ( ! (simsstring.EqualTo(type) || datastring.EqualTo(type) ) ) { std::cerr << "type must be either SIMU or DATA, not -> " << type << "\n"; exit(2); } double *C = new double[NMAX]; double *V = new double[NMAX]; double *logC = new double[NMAX]; double *logV = new double[NMAX]; double *C2 = new double[NMAX]; double c,v; int i = 0; std::ifstream file; file.open(fileName); if ( !file.good() ) { std::cerr << "Problems opening file " << fileName << "\n"; std::cerr << "rdstate = " << file.rdstate() << "\n"; exit(3); } while(1) { file >> v >> c; if (file.eof()) break; if (! (c>0) ) continue; c=fabs(c); v=fabs(v); C[i]=c; V[i]=v; logC[i]=TMath::Log10(c); logV[i]=TMath::Log10(v); C2[i]=1./c/c; i++; if ( i > NMAX ) { std::cerr << "Too many lines: " << i << "\n"; std::cerr << "Maximum is : " << NMAX << "\n"; exit(4); } } TGraph* grCV = new TGraph(i,V,C); grCV->SetName("grCV"); grCV->SetTitle(""); TCanvas *c1 = new TCanvas("c1","",2000,1000); c1->cd(); grCV->SetMarkerColor(kBlue); grCV->SetMarkerStyle(24); grCV->SetMarkerSize(1.2); grCV->SetLineColor(kBlue); grCV->Draw("AP"); grCV->GetYaxis()->SetTitle("C [F]"); grCV->GetXaxis()->SetTitle("V_{bias} [V]"); c1->SetTicks(1); c1->SetGrid(1,1); TCanvas *c2 = new TCanvas("c2","",2000,1000); c2->cd(); TGraph* grlogClogV = new TGraph(i,logV,logC); grlogClogV->SetName("grlogClogV"); grlogClogV->SetTitle(""); grlogClogV->SetMarkerColor(kBlack); grlogClogV->SetMarkerStyle(24); grlogClogV->SetMarkerSize(1.2); grlogClogV->SetLineColor(kBlack); grlogClogV->Draw("AP"); grlogClogV->GetYaxis()->SetTitle("log_{10}(C/F)"); grlogClogV->GetXaxis()->SetTitle("log_{10}(V_{bias}/V)"); c2->SetTicks(1); c2->SetGrid(1,1); double logv1 = TMath::Log10(v1); double logv2 = TMath::Log10(v2); double logv3 = TMath::Log10(v3); double logv4 = TMath::Log10(v4); TF1 *loglin1 = new TF1("loglin1","[0]+[1]*x",logv1,logv2); TF1 *loglin2 = new TF1("loglin2","[0]+[1]*x",logv3,logv4); loglin1->SetLineColor(kRed); loglin2->SetLineColor(kBlue); grlogClogV->Fit("loglin1","R","",logv1,logv2); grlogClogV->Fit("loglin2","R+","",logv3,logv4); double logq1 = loglin1->GetParameter(0); double logq2 = loglin2->GetParameter(0); double logm1 = loglin1->GetParameter(1); double logm2 = loglin2->GetParameter(1); double elogq1 = loglin1->GetParError(0); double elogq2 = loglin2->GetParError(0); double elogm1 = loglin1->GetParError(1); double elogm2 = loglin2->GetParError(1); assert((logm1-logm2)!=0); double logvdep = (logq1-logq2)/(logm2-logm1); vdepl = TMath::Power(10.,logvdep); double Deltam = sqrt(TMath::Power(elogm1,2.)+TMath::Power(elogm2,2.)); double Deltaq = sqrt(TMath::Power(elogq1,2.)+TMath::Power(elogq2,2.)); evdepl = sqrt(TMath::Power(Deltaq,2.)/TMath::Power((logm2-logm1),2.) + TMath::Power(Deltam,2.)*TMath::Power((logq1-logq2),2.)/TMath::Power((logm2-logm1),2.)); evdepl = TMath::Power(10.,evdepl); TF1 *flog1 = new TF1("flog1","[0]+[1]*x",logv1*0.8,logv2*1.2); TF1 *flog2 = new TF1("flog2","[0]+[1]*x",logv3*0.8,logv4*1.2); flog1->SetParameters(logq1,logm1); flog2->SetParameters(logq2,logm2); flog1->SetLineStyle(7); flog1->SetLineColor(loglin1->GetLineColor()); flog2->SetLineStyle(kDashed); flog2->SetLineColor(loglin2->GetLineColor()); grlogClogV->Draw("AP"); flog1->Draw("same"); flog2->Draw("same"); loglin1->Draw("same"); loglin2->Draw("same"); TCanvas *c3 = new TCanvas("c3","",2000,1000); c3->cd(); TGraph *grC2V = new TGraph(i,V,C2); grC2V->SetName("grC2V"); grC2V->SetTitle(""); grC2V->SetMarkerColor(kBlue); grC2V->SetMarkerStyle(24); grC2V->SetMarkerSize(1.2); grC2V->SetLineColor(kBlue); grC2V->Draw("AP"); grC2V->GetYaxis()->SetTitle("C^{-2} [F^{-2}]"); grC2V->GetXaxis()->SetTitle("V_{bias} [V]"); c3->SetTicks(1); c3->SetGrid(1,1); grC2V->Fit("pol1","R","",v1,v2); TF1 *lin = (TF1*)gROOT->GetFunction("pol1"); lin->SetLineColor(kRed); double C2der = lin->GetParameter(1); double eC2der = lin->GetParError(1); neff = 2./A/A/q0/eR/e0/C2der; eneff = 2./A/A/q0/eR/e0/C2der/C2der*eC2der; w = TMath::Power(2.*eR*e0*vdepl/q0/neff,0.5); double ewA = 2*eR*e0/q0; ewA = TMath::Power(ewA,0.5); double ewNeff = 0.5*ewA*TMath::Power(vdepl,0.5)*TMath::Power(neff,-1.5)*eneff; double ewV = 0.5*ewA*TMath::Power(vdepl,-0.5)*TMath::Power(neff,-0.5)*evdepl; ew = TMath::Sqrt(ewNeff*ewNeff+ewV*ewV); std::cout << "v1 = " << v1 << " V\n"; std::cout << "v2 = " << v2 << " V\n"; std::cout << "v3 = " << v3 << " V\n"; std::cout << "v4 = " << v4 << " V\n"; std::cout << "vdepl = " << vdepl << " V \n"; std::cout << "evdepl = " << evdepl << " V \n"; std::cout << "neff = " << neff << " 1./cm^3\n"; std::cout << "eneff = " << eneff << " 1./cm^3\n"; std::cout << "w = " << w*1e+4 << " um\n"; std::cout << "ew = " << ew*1e+4 << " um\n"; file.close(); if ( savePlots == true ) { std::cout << "I will save plots\n"; TString saveFile(fileName); TString cvFile = saveFile; cvFile.ReplaceAll(".dat","_CV.png"); TString c2vFile = saveFile; c2vFile.ReplaceAll(".dat","_C2V.png"); TString logclogvFile = saveFile; logclogvFile.ReplaceAll(".dat","_logClogV.png"); c1->Draw(); c1->SaveAs(cvFile.Data()); c2->Draw(); c2->SaveAs(logclogvFile.Data()); c3->Draw(); c3->SaveAs(c2vFile.Data()); } }
/* * make a refer to the string sval, * emitting DATA if needed. */ void datagostring(Strlit *sval, Addr *a) { Prog *p; Addr ac, ao, ap; int32 wi, wp; static int gen; memset(&ac, 0, sizeof(ac)); memset(&ao, 0, sizeof(ao)); memset(&ap, 0, sizeof(ap)); // constant ac.type = D_CONST; ac.name = D_NONE; ac.offset = 0; // fill in ac.reg = NREG; // string len+ptr ao.type = D_OREG; ao.name = D_STATIC; // fill in ao.etype = TINT32; ao.sym = nil; // fill in ao.reg = NREG; // $string len+ptr datastring(sval->s, sval->len, &ap); ap.type = D_CONST; ap.etype = TINT32; wi = types[TUINT32]->width; wp = types[tptr]->width; if(ap.name == D_STATIC) { // huge strings are made static to avoid long names snprint(namebuf, sizeof(namebuf), ".gostring.%d", ++gen); ao.sym = lookup(namebuf); ao.name = D_STATIC; } else { // small strings get named by their contents, // so that multiple modules using the same string // can share it. snprint(namebuf, sizeof(namebuf), "\"%Z\"", sval); ao.sym = pkglookup(namebuf, gostringpkg); ao.name = D_EXTERN; } *a = ao; if(ao.sym->flags & SymUniq) return; ao.sym->flags |= SymUniq; data(); // DATA gostring, wp, $cstring p = pc; gins(ADATA, N, N); p->from = ao; p->reg = wp; p->to = ap; // DATA gostring+wp, wi, $len p = pc; gins(ADATA, N, N); p->from = ao; p->from.offset = wp; p->reg = wi; p->to = ac; p->to.offset = sval->len; p = pc; ggloblsym(ao.sym, types[TSTRING]->width, ao.name == D_EXTERN); if(ao.name == D_STATIC) p->from.name = D_STATIC; text(); }
/* sender_peer_id given to this shall be quaranteed to be a valid peer */ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) { DSTACK(__FUNCTION_NAME); // Ignore packets that don't even fit a command if(datasize < 2) { m_packetcounter.add(60000); return; } ToClientCommand command = (ToClientCommand)readU16(&data[0]); //infostream<<"Client: received command="<<command<<std::endl; m_packetcounter.add((u16)command); /* If this check is removed, be sure to change the queue system to know the ids */ if(sender_peer_id != PEER_ID_SERVER) { infostream<<"Client::ProcessData(): Discarding data not " "coming from server: peer_id="<<sender_peer_id <<std::endl; return; } u8 ser_version = m_server_ser_ver; //infostream<<"Client received command="<<(int)command<<std::endl; if(command == TOCLIENT_INIT) { if(datasize < 3) return; u8 deployed = data[2]; infostream<<"Client: TOCLIENT_INIT received with " "deployed="<<((int)deployed&0xff)<<std::endl; if(deployed < SER_FMT_VER_LOWEST || deployed > SER_FMT_VER_HIGHEST) { infostream<<"Client: TOCLIENT_INIT: Server sent " <<"unsupported ser_fmt_ver"<<std::endl; return; } m_server_ser_ver = deployed; // Get player position v3s16 playerpos_s16(0, BS*2+BS*20, 0); if(datasize >= 2+1+6) playerpos_s16 = readV3S16(&data[2+1]); v3f playerpos_f = intToFloat(playerpos_s16, BS) - v3f(0, BS/2, 0); { //envlock //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out // Set player position Player *player = m_env.getLocalPlayer(); assert(player != NULL); player->setPosition(playerpos_f); } if(datasize >= 2+1+6+8) { // Get map seed m_map_seed = readU64(&data[2+1+6]); infostream<<"Client: received map seed: "<<m_map_seed<<std::endl; } // Reply to server u32 replysize = 2; SharedBuffer<u8> reply(replysize); writeU16(&reply[0], TOSERVER_INIT2); // Send as reliable m_con.Send(PEER_ID_SERVER, 1, reply, true); return; } if(command == TOCLIENT_ACCESS_DENIED) { // The server didn't like our password. Note, this needs // to be processed even if the serialisation format has // not been agreed yet, the same as TOCLIENT_INIT. m_access_denied = true; m_access_denied_reason = L"Unknown"; if(datasize >= 4) { std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); m_access_denied_reason = deSerializeWideString(is); } return; } if(ser_version == SER_FMT_VER_INVALID) { infostream<<"Client: Server serialization" " format invalid or not initialized." " Skipping incoming command="<<command<<std::endl; return; } // Just here to avoid putting the two if's together when // making some copypasta {} if(command == TOCLIENT_REMOVENODE) { if(datasize < 8) return; v3s16 p; p.X = readS16(&data[2]); p.Y = readS16(&data[4]); p.Z = readS16(&data[6]); //TimeTaker t1("TOCLIENT_REMOVENODE"); // This will clear the cracking animation after digging ((ClientMap&)m_env.getMap()).clearTempMod(p); removeNode(p); } else if(command == TOCLIENT_ADDNODE) { if(datasize < 8 + MapNode::serializedLength(ser_version)) return; v3s16 p; p.X = readS16(&data[2]); p.Y = readS16(&data[4]); p.Z = readS16(&data[6]); //TimeTaker t1("TOCLIENT_ADDNODE"); MapNode n; n.deSerialize(&data[8], ser_version); addNode(p, n); } else if(command == TOCLIENT_BLOCKDATA) { // Ignore too small packet if(datasize < 8) return; v3s16 p; p.X = readS16(&data[2]); p.Y = readS16(&data[4]); p.Z = readS16(&data[6]); /*infostream<<"Client: Thread: BLOCKDATA for (" <<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/ /*infostream<<"Client: Thread: BLOCKDATA for (" <<p.X<<","<<p.Y<<","<<p.Z<<")"<<std::endl;*/ std::string datastring((char*)&data[8], datasize-8); std::istringstream istr(datastring, std::ios_base::binary); MapSector *sector; MapBlock *block; v2s16 p2d(p.X, p.Z); sector = m_env.getMap().emergeSector(p2d); assert(sector->getPos() == p2d); //TimeTaker timer("MapBlock deSerialize"); // 0ms block = sector->getBlockNoCreateNoEx(p.Y); if(block) { /* Update an existing block */ //infostream<<"Updating"<<std::endl; block->deSerialize(istr, ser_version); } else { /* Create a new block */ //infostream<<"Creating new"<<std::endl; block = new MapBlock(&m_env.getMap(), p); block->deSerialize(istr, ser_version); sector->insertBlock(block); //DEBUG /*NodeMod mod; mod.type = NODEMOD_CHANGECONTENT; mod.param = CONTENT_MESE; block->setTempMod(v3s16(8,10,8), mod); block->setTempMod(v3s16(8,9,8), mod); block->setTempMod(v3s16(8,8,8), mod); block->setTempMod(v3s16(8,7,8), mod); block->setTempMod(v3s16(8,6,8), mod);*/ } #if 0 /* Acknowledge block */ /* [0] u16 command [2] u8 count [3] v3s16 pos_0 [3+6] v3s16 pos_1 ... */ u32 replysize = 2+1+6; SharedBuffer<u8> reply(replysize); writeU16(&reply[0], TOSERVER_GOTBLOCKS); reply[2] = 1; writeV3S16(&reply[3], p); // Send as reliable m_con.Send(PEER_ID_SERVER, 1, reply, true); #endif /* Update Mesh of this block and blocks at x-, y- and z-. Environment should not be locked as it interlocks with the main thread, from which is will want to retrieve textures. */ //m_env.getClientMap().updateMeshes(block->getPos(), getDayNightRatio()); /* Add it to mesh update queue and set it to be acknowledged after update. */ //infostream<<"Adding mesh update task for received block"<<std::endl; addUpdateMeshTaskWithEdge(p, true); } else if(command == TOCLIENT_PLAYERPOS) { infostream<<"Received deprecated TOCLIENT_PLAYERPOS" <<std::endl; /*u16 our_peer_id; { //JMutexAutoLock lock(m_con_mutex); //bulk comment-out our_peer_id = m_con.GetPeerID(); } // Cancel if we don't have a peer id if(our_peer_id == PEER_ID_INEXISTENT){ infostream<<"TOCLIENT_PLAYERPOS cancelled: " "we have no peer id" <<std::endl; return; }*/ { //envlock //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out u32 player_size = 2+12+12+4+4; u32 player_count = (datasize-2) / player_size; u32 start = 2; for(u32 i=0; i<player_count; i++) { u16 peer_id = readU16(&data[start]); Player *player = m_env.getPlayer(peer_id); // Skip if player doesn't exist if(player == NULL) { start += player_size; continue; } // Skip if player is local player if(player->isLocal()) { start += player_size; continue; } v3s32 ps = readV3S32(&data[start+2]); v3s32 ss = readV3S32(&data[start+2+12]); s32 pitch_i = readS32(&data[start+2+12+12]); s32 yaw_i = readS32(&data[start+2+12+12+4]); /*infostream<<"Client: got " <<"pitch_i="<<pitch_i <<" yaw_i="<<yaw_i<<std::endl;*/ f32 pitch = (f32)pitch_i / 100.0; f32 yaw = (f32)yaw_i / 100.0; v3f position((f32)ps.X/100., (f32)ps.Y/100., (f32)ps.Z/100.); v3f speed((f32)ss.X/100., (f32)ss.Y/100., (f32)ss.Z/100.); player->setPosition(position); player->setSpeed(speed); player->setPitch(pitch); player->setYaw(yaw); /*infostream<<"Client: player "<<peer_id <<" pitch="<<pitch <<" yaw="<<yaw<<std::endl;*/ start += player_size; } } //envlock } else if(command == TOCLIENT_PLAYERINFO) { u16 our_peer_id; { //JMutexAutoLock lock(m_con_mutex); //bulk comment-out our_peer_id = m_con.GetPeerID(); } // Cancel if we don't have a peer id if(our_peer_id == PEER_ID_INEXISTENT){ infostream<<"TOCLIENT_PLAYERINFO cancelled: " "we have no peer id" <<std::endl; return; } //infostream<<"Client: Server reports players:"<<std::endl; { //envlock //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out u32 item_size = 2+PLAYERNAME_SIZE; u32 player_count = (datasize-2) / item_size; u32 start = 2; // peer_ids core::list<u16> players_alive; for(u32 i=0; i<player_count; i++) { // Make sure the name ends in '\0' data[start+2+20-1] = 0; u16 peer_id = readU16(&data[start]); players_alive.push_back(peer_id); /*infostream<<"peer_id="<<peer_id <<" name="<<((char*)&data[start+2])<<std::endl;*/ // Don't update the info of the local player if(peer_id == our_peer_id) { start += item_size; continue; } Player *player = m_env.getPlayer(peer_id); // Create a player if it doesn't exist if(player == NULL) { player = new RemotePlayer( m_device->getSceneManager()->getRootSceneNode(), m_device, -1); player->peer_id = peer_id; m_env.addPlayer(player); infostream<<"Client: Adding new player " <<peer_id<<std::endl; } player->updateName((char*)&data[start+2]); start += item_size; } /* Remove those players from the environment that weren't listed by the server. */ //infostream<<"Removing dead players"<<std::endl; core::list<Player*> players = m_env.getPlayers(); core::list<Player*>::Iterator ip; for(ip=players.begin(); ip!=players.end(); ip++) { // Ingore local player if((*ip)->isLocal()) continue; // Warn about a special case if((*ip)->peer_id == 0) { infostream<<"Client: Removing " "dead player with id=0"<<std::endl; } bool is_alive = false; core::list<u16>::Iterator i; for(i=players_alive.begin(); i!=players_alive.end(); i++) { if((*ip)->peer_id == *i) { is_alive = true; break; } } /*infostream<<"peer_id="<<((*ip)->peer_id) <<" is_alive="<<is_alive<<std::endl;*/ if(is_alive) continue; infostream<<"Removing dead player "<<(*ip)->peer_id <<std::endl; m_env.removePlayer((*ip)->peer_id); } } //envlock } else if(command == TOCLIENT_SECTORMETA) { infostream<<"Client received DEPRECATED TOCLIENT_SECTORMETA"<<std::endl; #if 0 /* [0] u16 command [2] u8 sector count [3...] v2s16 pos + sector metadata */ if(datasize < 3) return; //infostream<<"Client received TOCLIENT_SECTORMETA"<<std::endl; { //envlock //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); u8 buf[4]; is.read((char*)buf, 1); u16 sector_count = readU8(buf); //infostream<<"sector_count="<<sector_count<<std::endl; for(u16 i=0; i<sector_count; i++) { // Read position is.read((char*)buf, 4); v2s16 pos = readV2S16(buf); /*infostream<<"Client: deserializing sector at " <<"("<<pos.X<<","<<pos.Y<<")"<<std::endl;*/ // Create sector assert(m_env.getMap().mapType() == MAPTYPE_CLIENT); ((ClientMap&)m_env.getMap()).deSerializeSector(pos, is); } } //envlock #endif } else if(command == TOCLIENT_INVENTORY) { if(datasize < 3) return; //TimeTaker t1("Parsing TOCLIENT_INVENTORY", m_device); { //envlock //TimeTaker t2("mutex locking", m_device); //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out //t2.stop(); //TimeTaker t3("istringstream init", m_device); std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); //t3.stop(); //m_env.printPlayers(infostream); //TimeTaker t4("player get", m_device); Player *player = m_env.getLocalPlayer(); assert(player != NULL); //t4.stop(); //TimeTaker t1("inventory.deSerialize()", m_device); player->inventory.deSerialize(is); //t1.stop(); m_inventory_updated = true; //infostream<<"Client got player inventory:"<<std::endl; //player->inventory.print(infostream); } } //DEBUG else if(command == TOCLIENT_OBJECTDATA) { // Strip command word and create a stringstream std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); u8 buf[12]; /* Read players */ is.read((char*)buf, 2); u16 playercount = readU16(buf); for(u16 i=0; i<playercount; i++) { is.read((char*)buf, 2); u16 peer_id = readU16(buf); is.read((char*)buf, 12); v3s32 p_i = readV3S32(buf); is.read((char*)buf, 12); v3s32 s_i = readV3S32(buf); is.read((char*)buf, 4); s32 pitch_i = readS32(buf); is.read((char*)buf, 4); s32 yaw_i = readS32(buf); Player *player = m_env.getPlayer(peer_id); // Skip if player doesn't exist if(player == NULL) { continue; } // Skip if player is local player if(player->isLocal()) { continue; } f32 pitch = (f32)pitch_i / 100.0; f32 yaw = (f32)yaw_i / 100.0; v3f position((f32)p_i.X/100., (f32)p_i.Y/100., (f32)p_i.Z/100.); v3f speed((f32)s_i.X/100., (f32)s_i.Y/100., (f32)s_i.Z/100.); player->setPosition(position); player->setSpeed(speed); player->setPitch(pitch); player->setYaw(yaw); } /* Read block objects NOTE: Deprecated stuff */ // Read active block count u16 blockcount = readU16(is); if(blockcount != 0){ infostream<<"TOCLIENT_OBJECTDATA: blockcount != 0 " "not supported"<<std::endl; return; } } else if(command == TOCLIENT_TIME_OF_DAY) { if(datasize < 4) return; u16 time_of_day = readU16(&data[2]); time_of_day = time_of_day % 24000; //infostream<<"Client: time_of_day="<<time_of_day<<std::endl; /* time_of_day: 0 = midnight 12000 = midday */ { m_env.setTimeOfDay(time_of_day); u32 dr = m_env.getDayNightRatio(); infostream<<"Client: time_of_day="<<time_of_day <<", dr="<<dr <<std::endl; } } else if(command == TOCLIENT_CHAT_MESSAGE) { /* u16 command u16 length wstring message */ u8 buf[6]; std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); // Read stuff is.read((char*)buf, 2); u16 len = readU16(buf); std::wstring message; for(u16 i=0; i<len; i++) { is.read((char*)buf, 2); message += (wchar_t)readU16(buf); } /*infostream<<"Client received chat message: " <<wide_to_narrow(message)<<std::endl;*/ m_chat_queue.push_back(message); } else if(command == TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD) { //if(g_settings->getBool("enable_experimental")) { /* u16 command u16 count of removed objects for all removed objects { u16 id } u16 count of added objects for all added objects { u16 id u8 type u32 initialization data length string initialization data } */ char buf[6]; // Get all data except the command number std::string datastring((char*)&data[2], datasize-2); // Throw them in an istringstream std::istringstream is(datastring, std::ios_base::binary); // Read stuff // Read removed objects is.read(buf, 2); u16 removed_count = readU16((u8*)buf); for(u16 i=0; i<removed_count; i++) { is.read(buf, 2); u16 id = readU16((u8*)buf); // Remove it { //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out m_env.removeActiveObject(id); } } // Read added objects is.read(buf, 2); u16 added_count = readU16((u8*)buf); for(u16 i=0; i<added_count; i++) { is.read(buf, 2); u16 id = readU16((u8*)buf); is.read(buf, 1); u8 type = readU8((u8*)buf); std::string data = deSerializeLongString(is); // Add it { //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out m_env.addActiveObject(id, type, data); } } } } else if(command == TOCLIENT_ACTIVE_OBJECT_MESSAGES) { //if(g_settings->getBool("enable_experimental")) { /* u16 command for all objects { u16 id u16 message length string message } */ char buf[6]; // Get all data except the command number std::string datastring((char*)&data[2], datasize-2); // Throw them in an istringstream std::istringstream is(datastring, std::ios_base::binary); while(is.eof() == false) { // Read stuff is.read(buf, 2); u16 id = readU16((u8*)buf); if(is.eof()) break; is.read(buf, 2); u16 message_size = readU16((u8*)buf); std::string message; message.reserve(message_size); for(u16 i=0; i<message_size; i++) { is.read(buf, 1); message.append(buf, 1); } // Pass on to the environment { //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out m_env.processActiveObjectMessage(id, message); } } } } else if(command == TOCLIENT_HP) { std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); Player *player = m_env.getLocalPlayer(); assert(player != NULL); u8 hp = readU8(is); player->hp = hp; } else if(command == TOCLIENT_MOVE_PLAYER) { std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); Player *player = m_env.getLocalPlayer(); assert(player != NULL); v3f pos = readV3F1000(is); f32 pitch = readF1000(is); f32 yaw = readF1000(is); player->setPosition(pos); /*player->setPitch(pitch); player->setYaw(yaw);*/ infostream<<"Client got TOCLIENT_MOVE_PLAYER" <<" pos=("<<pos.X<<","<<pos.Y<<","<<pos.Z<<")" <<" pitch="<<pitch <<" yaw="<<yaw <<std::endl; /* Add to ClientEvent queue. This has to be sent to the main program because otherwise it would just force the pitch and yaw values to whatever the camera points to. */ ClientEvent event; event.type = CE_PLAYER_FORCE_MOVE; event.player_force_move.pitch = pitch; event.player_force_move.yaw = yaw; m_client_event_queue.push_back(event); // Ignore damage for a few seconds, so that the player doesn't // get damage from falling on ground m_ignore_damage_timer = 3.0; } else if(command == TOCLIENT_PLAYERITEM) { std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); u16 count = readU16(is); for (u16 i = 0; i < count; ++i) { u16 peer_id = readU16(is); Player *player = m_env.getPlayer(peer_id); if (player == NULL) { infostream<<"Client: ignoring player item " << deSerializeString(is) << " for non-existing peer id " << peer_id << std::endl; continue; } else if (player->isLocal()) { infostream<<"Client: ignoring player item " << deSerializeString(is) << " for local player" << std::endl; continue; } else { InventoryList *inv = player->inventory.getList("main"); std::string itemstring(deSerializeString(is)); if (itemstring.empty()) { inv->deleteItem(0); infostream <<"Client: empty player item for peer " << peer_id << std::endl; } else { std::istringstream iss(itemstring); delete inv->changeItem(0, InventoryItem::deSerialize(iss)); infostream<<"Client: player item for peer " << peer_id << ": "; player->getWieldItem()->serialize(infostream); infostream<<std::endl; } } } } else if(command == TOCLIENT_DEATHSCREEN) { std::string datastring((char*)&data[2], datasize-2); std::istringstream is(datastring, std::ios_base::binary); bool set_camera_point_target = readU8(is); v3f camera_point_target = readV3F1000(is); ClientEvent event; event.type = CE_DEATHSCREEN; event.deathscreen.set_camera_point_target = set_camera_point_target; event.deathscreen.camera_point_target_x = camera_point_target.X; event.deathscreen.camera_point_target_y = camera_point_target.Y; event.deathscreen.camera_point_target_z = camera_point_target.Z; m_client_event_queue.push_back(event); } else { infostream<<"Client: Ignoring unknown command " <<command<<std::endl; } }