Ejemplo n.º 1
0
Archivo: gobj.c Proyecto: 8l/golang
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;
    }
}
Ejemplo n.º 3
0
Archivo: gobj.c Proyecto: 8l/golang
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;
}
Ejemplo n.º 4
0
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);
		}*/
	}
Ejemplo n.º 5
0
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());
  }

} 
Ejemplo n.º 6
0
/*
 * 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;
	}
}