void csPacketPartyTellAllMessage::send( NXWCLIENT ps )
{
	if( ps==NULL ) return;
	NXWSOCKET s = ps->toInt();

	size = headerSize + message->size()*sizeof(UI16)+sizeof(UI16);
	Xsend( s, getBeginValid(), headerSize );

	Xsend( s, *message, true );
}
void csPacketRemovePartyMembers::send( NXWCLIENT ps )
{
	if( ps==NULL ) return;
	NXWSOCKET s = ps->toInt();

	count = members->size();
	size = headerSize + count*sizeof(eSERIAL);
	Xsend( s, getBeginValid(), headerSize );

	std::vector<P_PARTY_MEMBER>::iterator iter( members->begin() ), end( members->end () );
	for( ; iter!=end; ++iter ) {
		eSERIAL b = (*iter)->serial;
		Xsend( s, &b, sizeof( eSERIAL ) );
	}
}
Beispiel #3
0
void cCharStuff::DeleteChar (P_CHAR pc_k) // Delete character
{
	int j;//,serial; //Zippy lag
	//int ptr,ci;

	LongToCharPtr(pc_k->serial, &removeitem[1]);

	if (pc_k->spawnregion>0 && pc_k->spawnregion<1024)
	{
		spawnregion[pc_k->spawnregion].current--;
	}


	if (pc_k->spawnserial != INVALID_SERIAL) 
		cspawnsp.remove(pc_k->spawnserial, pc_k->serial);
	if (pc_k->ownserial != INVALID_SERIAL) 
		cownsp.remove(pc_k->ownserial, pc_k->serial);
	
	for (j=0;j<now;j++)
	{
		if (perm[j]) 
			Xsend(j, removeitem, 5);		
	}
	
	if (pc_k != NULL) 
		mapRegions->Remove(pc_k); // taking it out of mapregions BEFORE x,y changed, LB
	
	pc_k->free = true;
	cCharsManager::getInstance()->deleteChar( pc_k );
}
void csPacketPartyInvite::send( NXWCLIENT ps )
{
	if( ps==NULL )
		return;

	size=headerSize;
	Xsend( ps->toInt(), getBeginValid(), headerSize );
}
// sends a page of new readonly book to the client
void cBooks::readbook_readonly(UOXSOCKET s, P_ITEM pBook, int p) 
{

    unsigned char bookpage[14]="\x66\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x08";
	int bytes=0,a,c;
	char seite[8][33];
	char fileName[13];
	char line[33];
	FILE *file = NULL;
	
	sprintf( fileName, "%8x.bok", pBook->serial);
    file = fopen( fileName, "r+b"); // open existing file for read/write

    if (file == NULL) 
		return;
	else
	{
		fclose(file);
		file = NULL;
	}

	bytes=13;
	for (a=1;a<=8;a++)
	{
		read_line(pBook, p,a,line);
		c=strlen(line)+1;        
		strcpy(seite[a-1],line);
		bytes+=c;
	}
    
	bookpage[1]=bytes>>8;
	bookpage[2]=bytes%256;

	LongToCharPtr(pBook->serial, &bookpage[3]);

	bookpage[9]=p>>8;
	bookpage[10]=p%256;

	Xsend(s, bookpage, 13);

	for (int j=0;j<8;j++)
	{
		Xsend(s, seite[j], strlen(seite[j])+1);
	}
	
}
Beispiel #6
0
static void Sndbounce5( NXWSOCKET socket )
{
	if ( socket >= 0 && socket < now)
	{
		unsigned char bounce[2]= { 0x27, 0x00 };
		bounce[1] = 5;
		Xsend(socket, bounce, 2);
	}
}
// opens old (readonly) books == old, bugfixed readbook function
void cBooks::openbook_old(UOXSOCKET s, P_ITEM pBook)
{
	unsigned char bookopen[10]="\x93\x40\x01\x02\x03\x00\x00\x00\x02"; //LB 7'th dec 1999, making it client 1.26 complaint
	unsigned char booktitle[61]="\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
	unsigned char bookauthor[31]="\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
	unsigned long loopexit=0;
	
	openscript("misc.scp");
	sprintf((char*)temp, "BOOK %i",	calcserial(pBook->more1, pBook->more2, pBook->more3, pBook->more4));
	if (!i_scripts[misc_script]->find((char*)temp))
	{
		closescript();
		return;
	}
	LongToCharPtr(pBook->serial, &bookopen[1]);
	do
	{
		read2();
	}
	while ( (strcmp((char*)script1, "PAGES")) && (++loopexit < MAXLOOPS) );
	bookopen[8] = (char) str2num(script2); // LB, bugfixing old code

	loopexit=0;
	do
	{
		read2();
	}
	while ( (strcmp((char*)script1, "TITLE")) && (++loopexit < MAXLOOPS) );

	strcpy((char*)(booktitle), script2);

	loopexit=0;
	do
	{
		read2();
	}
	while ( (strcmp((char*)script1, "AUTHOR")) && (++loopexit < MAXLOOPS) );

	strcpy((char*)(bookauthor), script2);
	Xsend(s, bookopen, 9); // LB, bugfixing of old code
	Xsend(s, booktitle, 60);
	Xsend(s, bookauthor, 30);
	closescript();
}
// TESTED: OKAY (fine fine.. now proove that it really works.. )
// guildtitle(viewing character socket, clicked character) displays players title string, over the name
// of clicked character, name color gets calculated from the guild relationship of both players
// Called by: textflags()
void GuildTitle(int s, P_CHAR pc_player2)
{
	char title[150];
	char abbreviation[5];
	char guildtype[10];
	int tl;

	if ( pc_player2 == NULL )
		return;

	if ( pc_player2->guildstone() != INVALID_SERIAL && pc_player2->guildtoggle() )
	{
		cGuildStone* pStone = dynamic_cast<cGuildStone*>(FindItemBySerial( pc_player2->guildstone() ));
		strcpy(abbreviation, pStone->abbreviation.c_str());
		
		if (!(strcmp(abbreviation,"")))
			strcpy(abbreviation,"none");
		switch (pStone->guildType)
		{
		case cGuildStone::order:	strcpy(guildtype, "Order");		break;
		case cGuildStone::chaos:	strcpy(guildtype, "Chaos");		break;
		default:													break;		
		}

		if (!pc_player2->guildtitle().isEmpty()) 
			sprintf(title,"[%s, %s] [%s]",pc_player2->guildtitle().latin1(),abbreviation,guildtype);
		else 
			sprintf(title,"[%s] [%s]",abbreviation, guildtype);

		tl=44+strlen(title)+1;
		talk[1]=tl>>8;
		talk[2]=tl%256;
		LongToCharPtr(pc_player2->serial, &talk[3]);
		talk[7]=1;
		talk[8]=1;
		talk[9]=0;
		ShortToCharPtr(pc_player2->emotecolor, &talk[10]);
		talk[12]=0;
		talk[13]=3;
		Xsend(s, talk, 14);
		Xsend(s, sysname, 30);
		Xsend(s, title, strlen(title)+1);
	}
Beispiel #9
0
/*
** get data from the client and return it
** run in a child process that was forked off from the main process.
*/
void process(int sock)
{
	char buf[XIA_MAXBUF + 1];
	int n;
	pid_t pid = getpid();

	fd_set fds;
	FD_ZERO(&fds);
	FD_SET(sock, &fds);

#ifdef USE_SELECT
	struct timeval tv;
	tv.tv_sec = WAIT_FOR_DATA;
	tv.tv_usec = 0;
#endif
   	while (1) {
		memset(buf, 0, sizeof(buf));
#ifdef USE_SELECT
		tv.tv_sec = WAIT_FOR_DATA;
		tv.tv_usec = 0;
		 if ((n = Xselect(sock + 1, &fds, NULL, NULL, &tv)) < 0) {
			 warn("%5d Select failed, closing...\n", pid);
			 break;

		 } else if (n == 0) {
			 // we timed out, close the socket
			 say("%5d timed out on recv\n", pid);
			 break;
		 } else if (!FD_ISSET(sock, &fds)) {
			 // this shouldn't happen!
			 die(-4, "something is really wrong, exiting\n");
		 }
#endif

		if ((n = Xrecv(sock, buf, sizeof(buf), 0)) < 0) {
			warn("Recv error on socket %d, closing connection\n", pid);
			break;
		} else if (n == 0) {
			warn("%d client closed the connection\n", pid);
			break;
		}

		say("%5d received %d bytes\n", pid, n);

		if ((n = Xsend(sock, buf, n, 0)) < 0) {
			warn("%5d send error\n", pid);
			break;
		}

		say("%5d sent %d bytes\n", pid, n);
   	}
	say("%5d closing\n", pid);
	Xclose(sock);
}
Beispiel #10
0
int sendCmd(int sock, const char *cmd)
{
	int n;

	if ((n = Xsend(sock, cmd,  strlen(cmd), 0)) < 0) {
		Xclose(sock);
		 die(-1, "Unable to communicate with the server\n");
	}

	return n;
}
Beispiel #11
0
int sendCmd(int sock, const char *cmd)
{ 
	int n;
 	warn("Sending Command: %s \n", cmd);
	if ((n = Xsend(sock, cmd,  strlen(cmd), 0)) < 0) {
		Xclose(sock);
		 die(-1, "Unable to communicate\n");
	}

	return n;
}
Beispiel #12
0
// old readbook function
void cBooks::readbook_readonly_old(UOXSOCKET s, P_ITEM pBook, int p)
{
	int x, y, pos, j;
	unsigned char bookpage[14]="\x66\x01\x02\x40\x01\x02\x03\x00\x01\x00\x01\x00\x01";
	unsigned long loopexit=0,loopexit2=0;
	
	openscript("misc.scp");
	sprintf((char*)temp, "BOOK %i", calcserial(pBook->more1, pBook->more2, pBook->more3, pBook->more4));
	if (!i_scripts[misc_script]->find((char*)temp))
	{
		closescript();
		return;
	}
	x=p;

	do
	{
		loopexit=0;
		do
		{
			read2();
		}
		while ( (strcmp((char*)script1, "PAGE")) && (++loopexit < MAXLOOPS) );
		x--;
	}
	while ( (x>0) && (++loopexit2 < 6666 ));

	closescript();
	openscript("misc.scp");
	sprintf((char*)temp, "PAGE %s", script2);
	if (!i_scripts[misc_script]->find((char*)temp))
	{
		closescript();
		return;
	}
	pos=ftell(scpfile);
	x=-1;
	y=-2;
	loopexit=0;
	do
	{
		read1();
		x++;
		y+=strlen((char*)script1)+1;
	}
	while ( (strcmp((char*)script1, "}")) && (++loopexit < MAXLOOPS) );
	y+=13;
	fseek(scpfile, pos, SEEK_SET);
	bookpage[1]=y>>8;
	bookpage[2]=y%256;
	LongToCharPtr(pBook->serial, &bookpage[3]);
	bookpage[9]=p>>8;
	bookpage[10]=p%256;
	bookpage[11]=x>>8;
	bookpage[12]=x%256;
	Xsend(s, bookpage, 13);
	for (j=0;j<x;j++)
	{
		read1();
		Xsend(s, script1, strlen((char*)script1)+1);
	}
	closescript();
}
Beispiel #13
0
void cPacketStatWindow::sendExtended( NXWCLIENT ps ) {
	if( ps == NULL ) return; //after error here
	sendBasic( ps, 0x03 );
	Xsend( ps->toInt(), (char*)(&this->sex), 0x1B );
};
Beispiel #14
0
// opens new books
// writeable 1 -> open new books in writable mode
//           0 -> open new books in readonly mode
void cBooks::openbook_new(UOXSOCKET s, P_ITEM pBook, char writeable)
{
	unsigned char bookopen[10]= "\x93\x40\x01\x02\x03\x01\x01\x00\x02"; //LB 7'th dec 1999, making it client 1.26 complaint
	
	int a,b;
	short pages, bytes;
	char line[33];
	char buch[256][8][33];
	char fileName[13];
	bool bookexists = false;

	FILE *file;

	// I dont know what that new client 1.26 byte does, but it needs to be set to 1 or 2 or writing doesnt work
    // wild guess: rune books ...

	char booktitle[61]={0x00,};
	char bookauthor[31]={0x00,};

	sprintf( fileName, "%8x.bok", pBook->serial);
    file = fopen( fileName, "r+b"); // open existing file for read/write

    bookexists = (file!=NULL);

	if (bookexists)
	{
		fclose(file);
		file = NULL;
		read_author ( pBook, bookauthor ); // fetch author if existing
		read_title  ( pBook, booktitle  ); // fetch title if existing
		pages = read_number_of_pages(pBook);
	}
	else 
	{ 
		pages = pBook->morey;              // if new book get number of maxpages ...
		if (pages<1 || pages>255) 
			pages = 16;
	}
	
	// clear all buffers from previous book openings
	memset( &authorbuffer[s], '~', 32 );
	memset( &titlebuffer[s], '~', 62 );
	memset( &pagebuffer[s], '~', 511 );
	
	LongToCharPtr(pBook->serial, &bookopen[1]);
	ShortToCharPtr(pages, &bookopen[7]);

	if (writeable) 
		bookopen[5] = 1;
	else
		bookopen[5] = 0;

	Xsend(s, bookopen, 9);
	Xsend(s, booktitle, 60);
	Xsend(s, bookauthor, 30);
	
	if (!bookexists) return; // dont send book contents if the file doesnt exist (yet)!

	if (!writeable) 
		return; // if readonly book return !!

    //////////////////////////////////////////////////////////////
	// Now we HAVE to send the ENTIRE Book                     / /
	// Cauz in writeable mode the client only sends out packets  /
	// if something  gets changed                                /
	// this also means -> for each bookopening in writeable mode /
	// lots of data has to be send.                              /
	//////////////////////////////////////////////////////////////

	unsigned char bookpage_pre[10]="\x66\x01\x02\x40\x01\x02\x03\x00\x01";
	unsigned char bookpage[5]="\x00\x00\x00\x08";

    // we have to know the total size "in advance"
	// thats why i save the book data in a temporaray array to 
	// avoid reading it twice from (slow) hd

	bytes = 9;
	for (a = 1; a <= pages; a++)
	{
		bytes+=4; // 4 bytes for each page
		for (b=1;b<=8;b++)
		{
			read_line(pBook, a,b, line);
			strcpy(buch[a-1][b-1],line);
			bytes += static_cast<short>(strlen(line)+1); // plus the stringlength+null terminator per(!) row
		}
	}
	
	ShortToCharPtr(bytes, &bookpage_pre[1]);
	LongToCharPtr(pBook->serial, &bookpage_pre[3]);
	ShortToCharPtr(pages, &bookpage_pre[7]);

	Xsend(s, bookpage_pre, 9);

	for (a=1;a<=pages;a++)
	{
		
		ShortToCharPtr(a, &bookpage[0]);
		
		Xsend(s, bookpage, 4);
		
		for (int j=0;j<8;j++)
		{
			Xsend(s, buch[a-1][j], strlen(buch[a-1][j])+1);
		}
	}
}
Beispiel #15
0
int main(int argc, char **argv)
{
	struct addrinfo *ai;
	sockaddr_x *sa;
	int seq = 0;

// FIXME: put signal handlers back into code once Xselect is working
//	signal(SIGINT, handler);
//	signal(SIGTERM, handler);
	getConfig(argc, argv);

	if (Xgetaddrinfo(NAME, NULL, NULL, &ai) < 0)
		die("Unable to lookup address for  %s\n", NAME);
	sa = (sockaddr_x*)ai->ai_addr;

	if ((sock = Xsocket(AF_XIA, SOCK_STREAM, 0)) < 0)
		die("Unable to create a socket\n");

	say("Opening firehose: %s\n", NAME);
	if (Xconnect(sock, (struct sockaddr*)sa, sizeof(sockaddr_x)) < 0) {
		Xclose(sock);
		die("Unable to connect to %s\n", NAME);
	}

	// tell firehose how many packets we expect
	if (Xsend(sock, &fhc, sizeof(fhc), 0) < 0) {
		Xclose(sock);
		die("Unable to send config information to the firehose\n");
	}

	int count = 0;
	char  *buf = (char *)malloc(pktSize);

	while (!timetodie) {
		int n;
		fd_set fds;
		FD_ZERO(&fds);
		FD_SET(sock, &fds);

		struct timeval tv;
		tv.tv_sec = 2;
		tv.tv_usec = 0;

		if ((n = Xselect(sock + 1, &fds, NULL, NULL, &tv)) < 0) {
			printf("select failed\n");
			break;

		} else if (n == 0) {
			printf("recv timeout\n");
			break;
		} else if (!FD_ISSET(sock, &fds)) {
			// this shouldn't happen!
			printf("something is really wrong, exiting\n");
			break;
		}

		int rc = Xrecv(sock, buf, sizeof(buf), 0);
		if (rc < 0)
			die("Receive failure\n");
		memcpy(&seq, buf, sizeof(int));

		say("expecting %d, got %d", count, seq);
		if (count == seq)
			say("\n");
		else
			say(" lost %d\n", seq - count);
		count++;
		if (count == numPkts)
			break;
		if (delay)
			usleep(delay);
	}

	seq++;
	if (count != seq)
		printf("lost %d packets, received %d, expected %d\n", seq - count, count, seq); 
	else
		printf("success!\n");
	Xclose(sock);
}
void cSpeech::talking(int s, QString speech) // PC speech
{
/*
	Unicode speech format
	byte = char, short = char[2], int = char[4], wchar = char[2] = unicode character

	Message Sent By Client:
	0xAD - Unicode Speech Request
	BYTE cmd(0xAD)
	short msgsize 1, 2
	byte type(0 = say, 2 = emote, 8 = whisper, 9 = yell) 3
	short color 4, 5
	short font 6, 7
	BYTE[4] lang(null terminated, "enu " for US english.) 8, 9, 10, 11
	wchar[?] text(null terminated, ?=(msgsize - 12)/2) 13
  
	Message Sent By Server:
	0xAE - Unicode Speech Message
	BYTE cmd(0xAE) 0
	short msgsize 1, 2
	BYTE[4] ser(ser of speaker, all 0xFF if none) 3, 4, 5, 6
	BYTE[2] model(id of speaker, all 0xFF if none)7, 8
	BYTE type 9
	short color 10, 11
	short font 12, 13
	BYTE[4] language(same as before) 14, 15, 16, 17
	BYTE[30] speaker's name(normal chars, not wchars) 18 - 48
	WCHAR[?] text(null terminated, ?=(msgsize - 48)/2

    Importnat note regarding 0xAD: since 2.0.7 clients send between lang and text 0...10 bytes. (we can ignore them safely)
	Those bytes get cut out in network.cpp correctly, so the buffer THIS functions sees is actualy what is written above.
    The actual data the client sends is differently though.
	Just noted this to prevent from debugging if somebody finds out client data doesn't fit to this description (LB) 

*/
	
	//char nonuni[512];
	unsigned char talk2[19];
	QByteArray unicodetext;
	char lang[4];
	char name[50] = {0,};	// it **IS** important to 0 out the remaining gaps
	
	P_CHAR pc_currchar = currchar[s];	
//	strcpy(nonuni, speech.latin1());

	// len+font+color+type = same postion for non unicode and unicode speech packets
	// but 8 ... x DIFFER a lot for unicode and non unicode packets !!!

	strncpy(name, pc_currchar->name.c_str(), 50);

	char speech_type       = buffer[s][3]; 
	UI16 speech_color	   = ShortFromCharPtr(&buffer[s][4]);
	char speech_fontbyte1  = buffer[s][6];
	char speech_fontbyte2  = buffer[s][7];

	int ucl = ( speech.length() * 2 ) + 2;
	int tl = ucl + 48 ;

	if (pc_currchar->unicode)
	{
		lang[0]=buffer[s][8];
		lang[1]=buffer[s][9];
		lang[2]=buffer[s][10];
		lang[3]=buffer[s][11];
		
		unicodetext.duplicate( (char*)&buffer[s][12], ucl );
	}
	else
	{
		lang[0]='E';
		lang[1]='N';
		lang[2]='U';
		lang[3]=0;
		
		char2wchar(speech.latin1());		// we are sending unicode response no matter if the speech request was non unicode or not
											// so convert to uni-text in case of non unicode
		unicodetext.duplicate( (char*)&temp, ucl );
	}

	/*
	clConsole.send("speech: %s\n",nonuni);
	clConsole.send("unicode speech:\n");
	for ( a=0; a < tl-48; a++) clConsole.send("%02i ",unicodetext[a]);
	clConsole.send("\n");*/




	//// Very important: do not use buffer[s][] anymore in this function !!!!
	//// unicode text that gets send is in unicodetext, nonunicode text for normal string processing in non uni code
//	string punt(nonuni);
	if (InputSpeech(speech, pc_currchar, s))	// handle things like renaming or describing an item
		return;

	if (pc_currchar->squelched)					// not allowed to talk
	{
		sysmessage(s, "You have been squelched.");
		return;
	}
			
	// AntiChrist
	pc_currchar->unhide();
		
	if (speech[0] == (char)SrvParams->commandPrefix() )
	{
		Commands->Command(s, speech.latin1());
		return;
	}

	if ( speech_type == '\x09' && pc_currchar->canBroadcast() )
	{
		broadcast(s);
		return;
	}
	
	talk2[0] = 0xAE;
	ShortToCharPtr(tl, &talk2[1]);
	LongToCharPtr(pc_currchar->serial, &talk2[3]);
	ShortToCharPtr(pc_currchar->id(), &talk2[7]);
	talk2[9] =  speech_type;
	ShortToCharPtr(speech_color, &talk2[10]);
	talk2[12] = speech_fontbyte1;
	talk2[13] = speech_fontbyte2;
	
	talk2[14] = lang[0];
	talk2[15] = lang[1];
	talk2[16] = lang[2];
	talk2[17] = lang[3];
	
	Xsend(s, talk2, 18);
	Xsend(s, name, 30);   
	Xsend(s, unicodetext.data(), unicodetext.size());   
	
	if (speech_type == 0 || speech_type == 2)
	{
		pc_currchar->saycolor = speech_color;
	}
	if (SrvParams->speechLog()) // Logging bugfixed by LB
	{
		char temp2[512];
		sprintf(temp2, "%s.speech_log", pc_currchar->name.c_str());
		sprintf((char*)temp, "%s [%x] [%i] said:\n%s\n", pc_currchar->name.c_str(), pc_currchar->serial, pc_currchar->account, speech.latin1());
		savelog((char*)temp, (char*)temp2);
	}
	
	//char SpeechUpr[512];
	//strcpy(SpeechUpr, nonuni);
	//strupr(SpeechUpr);
	QString SpeechUpr = speech.upper();
	//transform(SpeechUpr.begin(), SpeechUpr.end(), SpeechUpr.begin(), ::toupper);
	//if (!strcmp(SpeechUpr, "I RESIGN FROM MY GUILD"))
	if (SpeechUpr == "I RESIGN FROM MY GUILD")
	{
		GuildResign(s);
	}
	
	if (response(s,pc_currchar, SpeechUpr))
		return;  // Vendor responded already
	
	//if (strstr(SpeechUpr, "GUARDS"))
	if (SpeechUpr.contains("GUARDS"))
		callguards(currchar[s]);
	
	if (Boats->Speech(s, SpeechUpr))
		return;
	
	house_speech(s, SpeechUpr); // houses crackerjack 8/12/99			
	
	int i, j;
	for (i = 0; i < now; i++)
	{
		// AntiChrist - don't check line of sight for talking!!!
		if (inrange1(i, s) && perm[i] && i!=s)//&&line_of_sight(s, pc_currchar->pos.x, pc_currchar->pos.y, pc_currchar->pos.z, chars[currchar[i]].x, chars[currchar[i]].y, chars[currchar[i]].z, WALLS_CHIMNEYS + DOORS + FLOORS_FLAT_ROOFING))
		{
			Xsend(i, talk2, 18);
			Xsend(i, name, 30);
			if (pc_currchar->dead				// a ghost is talking
				&& !currchar[i]->dead		// Ghost can talk normally to other ghosts
				&& !currchar[i]->isGMorCounselor()// GM/Counselors can see ghosts talking always  Seers?
				&& currchar[i]->spiritspeaktimer == 0)
			{
				unsigned char ghostspeech[512];
				memcpy(&ghostspeech, unicodetext.data(), unicodetext.size());
				for (j = 1; j < ucl-2 ; j += 2)	// -2: dont override /0 /0 terminator !
				{
					if (ghostspeech[j] != 32)	// keep the blanks
						ghostspeech[j] = (ghostspeech[j]%2) ? 'O' : 'o';
				}
				Xsend(i, ghostspeech, ucl);		// send 'ghostified' speech "OOoooOo  Ooo"
			}
			else
				Xsend(i, unicodetext.data(), unicodetext.size());   
		}
	}
	
	if (pc_currchar->dead) return; // this makes it so npcs do not respond to dead people
	
	cChar* pc=NULL;
	cChar* pNpc=NULL;
	cRegion::RegionIterator4Chars ri(pc_currchar->pos);
	for (ri.Begin(); !ri.atEnd(); ri++)
	{	
		pc = ri.GetData();
		if (!pc->isSameAs(pc_currchar) 
			&& pc->isNpc()
			&& pc->dist(pc_currchar) <= 2)
		{
			pNpc=pc;
			break;
		}
	}
	if (pNpc && pNpc->speech)
	{
		Script *pScp=i_scripts[speech_script];
		if (!pScp->Open())
			return;
		char sect[512];
		sprintf(sect, "SPEECH %i", pNpc->speech);
		if (!pScp->find(sect)) 
		{
			pScp->Close();
			return;
		}
		int match = 0;
		strcpy(sect, "NO DEFAULT TEXT DEFINED");
		unsigned long loopexit = 0;
		do
		{
			pScp->NextLineSplitted();
			if (script1[0] != '}')
			{
				if (!(strcmp("DEFAULT", (char*)script1)))
				{
					strcpy(sect, (char*)script2);
				}
				if (!(strcmp("ON", (char*)script1)))
				{
					char scpUpr[500];
					strcpy(scpUpr,script2);
					strupr(scpUpr);
					if (SpeechUpr.find(scpUpr)!= string::npos)
						match=1;
				}
				if (!(strcmp("SAY", (char*)script1)))
				{
					if (match == 1)
					{
						npctalk(s, pNpc, (char*)script2, 0);
						match = 2;
					}
				}
				
				if (!(strcmp("TRG", (char*)script1))) // Added by Magius(CHE) §
				{							  
					if (match == 1)
					{
						pNpc->trigger = str2num(script2);
						scpMark m=pScp->Suspend();
						
						Trig->triggernpc(s, pNpc, 1);
						
						pScp->Resume(m);
						strcpy((char*)script1, "DUMMY");
						
						match = 2;
					}
				}
			}
		}
		while (script1[0] != '}'  && (++loopexit < MAXLOOPS));
		if (match == 0)
		{
			npctalk(s, pNpc, sect, 0);
		}
		pScp->Close();
	}
}
Beispiel #17
0
void cTrade::buyaction(int s)
{
	char clearmsg[8];
	int clear, i, j;
	P_ITEM buyit[256];
	int amount[512];
	int layer[512];
	int playergoldtotal;
	int goldtotal;
	int itemtotal;
	int soldout;
	int tmpvalue=0; // Fixed for adv trade system -- Magius(CHE) §
//	CHARACTER cc=currchar[s];
	P_CHAR pc_currchar = currchar[s];
	P_ITEM pi_pack = Packitem(pc_currchar);
	if (pi_pack == NULL)
		return; //LB no player-pack - no buy action possible - and no crash too ;-)
	P_CHAR npc = FindCharBySerial(calcserial(buffer[s][3], buffer[s][4], buffer[s][5], buffer[s][6]));

	if (npc <= 0) return;

	clear=0;
	goldtotal=0;
	soldout=0;
	itemtotal=(((256*(buffer[s][1]))+buffer[s][2])-8)/7;
	if (itemtotal>256) return; //LB

	for(i = 0; i < itemtotal; i++)
	{
		layer[i]=buffer[s][8+(7*i)];
		buyit[i] = FindItemBySerial(calcserial(buffer[s][8+(7*i)+1], buffer[s][8+(7*i)+2], buffer[s][8+(7*i)+3], buffer[s][8+(7*i)+4]));
		amount[i]=(256*(buffer[s][8+(7*i)+5]))+buffer[s][8+(7*i)+6];

		if (buyit[i] != NULL)
		{
			buyit[i]->rank=10;
			// Fixed for adv trade system -- Magius(CHE) §
			tmpvalue = buyit[i]->value;
			tmpvalue = calcValue(buyit[i], tmpvalue);
			if (SrvParams->trade_system()==1)
				tmpvalue = calcGoodValue(pc_currchar, buyit[i], tmpvalue,0);
			goldtotal += (amount[i]*tmpvalue);
			// End Fix for adv trade system -- Magius(CHE) §
		}
	}

	bool useBank;
	useBank = (goldtotal >= SrvParams->checkBank() );

	if( useBank )
		playergoldtotal = GetBankCount( pc_currchar, 0x0EED );
	else
		playergoldtotal = pc_currchar->CountGold();

	if ((playergoldtotal>=goldtotal)||(pc_currchar->isGM()))
	{
		for (i = 0; i < itemtotal; i++)
		{
			if (buyit[i] != NULL)
			{
				if (buyit[i]->amount < amount[i])
				{
					soldout = 1;
				}
			}
		}
		if (soldout)
		{
			npctalk(s, npc, "Alas, I no longer have all those goods in stock. Let me know if there is something else thou wouldst buy.",0);
			clear = 1;
		}
		else
		{
			if (pc_currchar->isGM())
			{
				sprintf((char*)temp, "Here you are, %s. Someone as special as thee will receive my wares for free of course.", pc_currchar->name.c_str());
			}
			else
			{
				if(useBank)
				{
					sprintf((char*)temp, "Here you are, %s. %d gold coin%s will be deducted from your bank account.  I thank thee for thy business.",
					pc_currchar->name.c_str(), goldtotal, (goldtotal==1) ? "" : "s");
				    goldsfx(s, goldtotal);
				}
			    else
				{
				    sprintf((char*)temp, "Here you are, %s.  That will be %d gold coin%s.  I thank thee for thy business.",
					pc_currchar->name.c_str(), goldtotal, (goldtotal==1) ? "" : "s");
				    goldsfx(s, goldtotal);	// Dupois, SFX for gold movement. Added Oct 08, 1998
				}
			}
			npctalkall(npc, (char*)temp, 0);
			npcaction(npc, 0x20);		// bow (Duke, 17.3.2001)

			clear = 1;
			if( !(pc_currchar->isGM() ) )
			{
				if( useBank )
					DeleBankItem( pc_currchar, 0x0EED, 0, goldtotal );
				else
					delequan( pc_currchar, 0x0EED, goldtotal, NULL );
			}
			for (i=0;i<itemtotal;i++)
			{
				P_ITEM pi = buyit[i];
				if (pi != NULL)
				{
					if (pi->amount>amount[i])
					{
						if (pi->pileable)
						{
							Commands->DupeItem(s, buyit[i], amount[i]);
						}
						else
						{
							for (j=0;j<amount[i];j++)
							{
								Commands->DupeItem(s, buyit[i], 1);
							}
						}
						pi->amount-=amount[i];
						pi->restock+=amount[i];
					}
					else
					{
						switch(layer[i])
						{
						case 0x1A:
							if (pi->pileable)
							{
								Commands->DupeItem(s, buyit[i], amount[i]);
							}
							else
							{
								for (j=0;j<amount[i];j++)
								{
									Commands->DupeItem(s, buyit[i], 1);
								}
							}
							pi->amount=pi->amount-amount[i];
							pi->restock=pi->restock+amount[i];
							break;
						case 0x1B:
							if (pi->pileable)
							{
								pi->SetContSerial(pi_pack->serial);
								RefreshItem(buyit[i]);//AntiChrist
							}
							else
							{
								for (j=0;j<amount[i]-1;j++)
								{
									Commands->DupeItem(s, buyit[i], 1);
								}
								pi->SetContSerial(pi_pack->serial);
								pi->amount = 1;
								RefreshItem(buyit[i]);//AntiChrist
							}
							break;
						default:
							clConsole.send("ERROR: Fallout of switch statement without default. wolfpack.cpp, buyaction()\n"); //Morrolan
						}
					}
				}
			}
		}
	}
	else
	{
		npctalkall(npc, "Alas, thou dost not possess sufficient gold for this purchase!",0);
	}

	if (clear)
	{
		clearmsg[0]=0x3B;
		clearmsg[1]=0x00;
		clearmsg[2]=0x08;
		clearmsg[3]=buffer[s][3];
		clearmsg[4]=buffer[s][4];
		clearmsg[5]=buffer[s][5];
		clearmsg[6]=buffer[s][6];
		clearmsg[7]=0x00;
		Xsend(s, clearmsg, 8);
	}
	Weight->NewCalc(pc_currchar);	// Ison 2-20-99
	statwindow(s, pc_currchar);
}
Beispiel #18
0
void process(int peer)
{
	fhConfig fhc;
	char *buf = NULL;
	uint32_t count = 0;
	int n;

	signal(SIGINT, handler);

	fd_set fds;
	FD_ZERO(&fds);
	FD_SET(peer, &fds);

	struct timeval tv;
	tv.tv_sec = 5;
	tv.tv_usec = 0;

	n = Xselect(peer + 1, &fds, NULL, NULL, &tv);
	if (n < 0) {
		printf("select failed\n");
		goto done;
	
	} else if (n == 0) {
		printf("recv timeout\n");
		goto done;
	
	} else if (!FD_ISSET(peer, &fds)) {
		// this shouldn't happen!
		printf("something is really wrong, exiting\n");
		goto done;
	}

	if (Xrecv(peer, &fhc, sizeof(fhc), 0) < 0) {
		printf("Unable to get configuration block\n");
		goto done;
	}

	fhc.numPkts = ntohl(fhc.numPkts);
	fhc.delay   = ntohl(fhc.delay);
	fhc.pktSize = ntohl(fhc.pktSize);
	// need to have at least enough room for the sequence #
	fhc.pktSize = MAX(fhc.pktSize, sizeof(unsigned));
	if (fhc.numPkts == 0)
		say("packet count = non-stop\n");
	else
		say("packet count = %d\n", fhc.numPkts);
	say("packet size = %d\n", fhc.pktSize);
	say("inter-packet delay = %d\n", fhc.delay);


	if (!(buf = (char *)malloc(fhc.pktSize))) {
		printf("Memory error\n");
		goto done;
	}
		
	while (!timetodie) {
		if (fhc.numPkts > 0 && count == fhc.numPkts)
			break;
		printf("sending packet %d\n", count);
		data(count, buf, sizeof(buf));
		Xsend(peer, buf, sizeof(buf), 0);
		count++;
		if (fhc.delay != 0)
			usleep(fhc.delay);
	}
done:
	say("done\n");
	if (buf) 
		free(buf);
	Xclose(peer);
}
Beispiel #19
0
void cTrade::sellaction(int s)
{
	int i, amt, value=0, totgold=0;

	P_ITEM pRestock = NULL;
	P_ITEM pNoRestock = NULL;
	P_ITEM pSellCont = NULL;

	if (buffer[s][8]!=0)
	{
		P_CHAR pc_n = FindCharBySerial(calcserial(buffer[s][3], buffer[s][4], buffer[s][5], buffer[s][6]));
		if (pc_n == NULL) return;

		P_ITEM pi;
		unsigned int ci;
		vector<SERIAL> vecContainer = contsp.getData(pc_n->serial);
		for ( ci = 0; ci < vecContainer.size(); ci++)
		{
			pi = FindItemBySerial(vecContainer[ci]);
			if (pi->layer==0x1A) pRestock = pi;				// Buy Restock container
			else if (pi->layer==0x1B) pNoRestock = pi;		// Buy no restock container
			else if (pi->layer==0x1C) pSellCont = pi;		// Sell container
		}

		// Pre Calculate Total Amount of selling items to STOPS if the items if greater than SELLMAXITEM - Magius(CHE)
		int maxsell=0;
		i=buffer[s][8];
		if (i>256) return;
		for (i=0;i<buffer[s][8];i++)
		{
			amt=ShortFromCharPtr(buffer[s]+9+(6*i)+4);
			maxsell+=amt;
		}
		if (maxsell>SrvParams->sellmaxitem())
		{
			char tmpmsg[256];
			sprintf(tmpmsg,"Sorry %s but i can buy only %i items at time!",currchar[s]->name.c_str(),SrvParams->sellmaxitem());
			npctalkall(pc_n, tmpmsg,0);
			return;
		}

		for (i=0;i<buffer[s][8];i++)
		{
			P_ITEM pSell=FindItemBySerPtr(buffer[s]+9+(6*i));	// the item to sell
			if (!pSell) continue;
			amt=ShortFromCharPtr(buffer[s]+9+(6*i)+4);
			
			// player may have taken items out of his bp while the sell menu was up ;-)
			if (pSell->amount<amt)
			{
				npctalkall(pc_n, "Cheating scum! Leave now, before I call the guards!",0);
				return;
			}

			// Search the buy restock Container
			P_ITEM join = NULL;
			ci=0;
			P_ITEM pi;
			vector<SERIAL> vecContainer = contsp.getData(pRestock->serial);
			for ( ci = 0; ci < vecContainer.size(); ci++)
			{
				pi = FindItemBySerial(vecContainer[ci]);
				if (items_match(pi,pSell))
					join = pi;
			}

			// Search the sell Container to determine the price
			ci=0;
			vecContainer.clear();
			vecContainer = contsp.getData(pSellCont->serial);
			for ( ci = 0; ci < vecContainer.size(); ci++)
			{
				pi = FindItemBySerial(vecContainer[ci]);
				if (items_match(pi,pSell))
				{
					value=pi->value;
					value=calcValue(pSell, value);
					if (SrvParams->trade_system()==1)
						value=calcGoodValue(currchar[s], pSell, value, 1); // Fixed for adv trade --- by Magius(CHE) §
					break;	// let's take the first match
				}
			}
			totgold+=(amt*value);	// add to the bill

			if (join != NULL)	// The item goes to the container with restockable items
			{
				join->amount+=amt;
				join->restock-=amt;
				pSell->ReduceAmount(amt);
			}
			else
			{
				pSell->SetContSerial(pNoRestock->serial);
				SndRemoveitem(pSell->serial);
				if (pSell->amount!=amt)
					Commands->DupeItem(s, pSell, pSell->amount-amt);
			}
		}
		addgold(s, totgold);
		goldsfx(s, totgold);	// Dupois, SFX for gold movement	// Added Oct 08, 1998
	}

	char clearmsg[9];
	clearmsg[0]=0x3B;
	clearmsg[1]=0x00;
	clearmsg[2]=0x08;
	clearmsg[3]=buffer[s][3];
	clearmsg[4]=buffer[s][4];
	clearmsg[5]=buffer[s][5];
	clearmsg[6]=buffer[s][6];
	clearmsg[7]=0x00;
	Xsend(s, clearmsg, 8);
}
void cDragdrop::get_item(P_CLIENT ps) // Client grabs an item
{
	int npc=-1, amount, update = 0, serial;
	UOXSOCKET s = ps->GetSocket();
	int cc = ps->GetCurrChar();
	P_CHAR pc_currchar = MAKE_CHARREF_LR(cc);
	
	
	serial = calcserial(buffer[s][1], buffer[s][2], buffer[s][3], buffer[s][4]);
	if (serial == INVALID_SERIAL || buffer[s][1] < 0x40)
		return;	// landscape or a character
	P_ITEM pi = FindItemBySerial(serial);
	if (pi == NULL)
		return;
	
	pc_currchar->disturbMed(s); // Meditation
	
	// Zippy's stealing changes  
	P_ITEM px = pi;
	if (!px->isInWorld())  // Find character owning item
	{
		unsigned long loopexit = 0;
		do  // Find character owning item
		{
			if (isCharSerial(px->contserial))
			{
				npc = calcCharFromSer(px->contserial);
			}
			else  // its an item
			{
				if (px->isInWorld())
				{
					npc=-1;
					break;
				}
				px = FindItemBySerial(px->contserial);
				// ANTICHRIST -- SECURE TRADE FIX
				if (px != NULL) // LB overwriting x is essential here, dont change it!!!
				{
					if (px->layer == 0 && px->id() == 0x1E5E)
					{
						// Trade window???
						serial = calcserial(px->moreb1, px->moreb2, px->moreb3, px->moreb4);
						if (serial == INVALID_SERIAL)
							return;
						P_ITEM pi_z = FindItemBySerial(serial);
						if ( pi_z != NULL )
							if ((pi_z->morez || px->morez))
							{
								pi_z->morez = 0;
								px->morez = 0;
								sendtradestatus(pi_z, px);
							}
					}
					// Blackwinds Looting is crime implementation
					// changed slightly by Ripper
					if (px->corpse != 0 && !pc_currchar->Owns(px)) 
					{ 
						P_CHAR co = FindCharBySerial(px->ownserial);
						if (px->more2 == 1 && Guilds->Compare(DEREF_P_CHAR(pc_currchar), DEREF_P_CHAR(co)) == 0) 
						{ 
							pc_currchar->karma -= 5; 
							criminal(DEREF_P_CHAR(pc_currchar));
							sysmessage(s, "You lost some karma!"); 
						} 
						npc = 0;
					} // Criminal stuff
					if (px->corpse != 0)
						npc = 0;
				} // end if x!=-1
				
				if (px == NULL)
					npc = 0; 
			}
		} while ((npc==-1) &&(++loopexit < MAXLOOPS));
	}
	
	if (npc>0) // 0=corpse, hence >0 ..
	{
		if (!(pc_currchar->isGM()) && npc != DEREF_P_CHAR(pc_currchar) && ! pc_currchar->Owns(&chars[npc]))
		{// Own serial stuff by Zippy -^ Pack aniamls and vendors.
			bounce[1] = 0;
			Xsend(s, bounce, 2);
			if (ps->IsDragging())
			{
				ps->ResetDragging();
				item_bounce3(pi);
				pi->magic = 3;
			} 
			return;
		}
	}
	// End Zippy's change
	
	// Boats->
	if (px != NULL && npc!=-1)
	{
		if (px->multis>0)
			imultisp.remove(px->multis, px->serial);
		px->startDecay();
		// End Boats Change
		
		// AntiChrist -- for poisoned items
		if (px->layer>0)
		{
			chars[npc].removeItemBonus(px);	// remove BONUS STATS given by equipped special items
		}
		if ((px->trigon==1) && (px->layer != 0) && (px->layer != 15) && (px->layer < 19))// -Frazurbluu- Trigger Type 2 is my new trigger type *-
		{
			Trig->triggerwitem(s, pi, 1); // trigger is fired
		}	
	}
	if (pi != NULL)
	{
		if (pi->corpse != 1)
		{
			UpdateStatusWindow(s, pi);
			if (!pc_currchar->canPickUp(pi))
			{
				bounce[1] = 0;
				Xsend(s, bounce, 2);
				if (ps->IsDragging()) // only restore item if it got draggged before !!!
				{
					ps->ResetDragging();
					item_bounce4(s, pi);
				}
			}
			else
			{
				// AntiChrist bugfix for the bad bouncing bug ( disappearing items when bouncing )
				DRAGGED[s] = 1;
				
				pi->oldx = pi->pos.x;	// first let's save the position
				pi->oldy = pi->pos.y;
				pi->oldz = pi->pos.z;
				pi->oldcontserial = pi->contserial;	// then let's save the container
				pi->oldlayer = pi->layer;	// then the layer
				
				pi->layer = 0;
				if (!pi->isInWorld())
					soundeffect(s, 0x00, 0x57);
				if (pi->amount>1)
				{
					amount = (buffer[s][5] << 8) + buffer[s][6];
					if (amount>pi->amount)
						amount = pi->amount;
					if (amount < pi->amount)
					{
						P_ITEM pi_c = Items->MemItemFree();
						//	pi_c->Init(0);
#pragma note("Replace by a copy constructor before finishing items[]")
						memcpy(pi_c, pi, sizeof(cItem));  // Tauriel reduce code faster too
						pi_c->SetSerial(cItemsManager::getItemsManager().getUnusedSerial());

						pi_c->amount = pi->amount - amount;
						pi_c->SetContSerial(pi_c->contserial);
						pi_c->SetOwnSerial(pi_c->ownserial);
						pi_c->SetSpawnSerial(pi_c->spawnserial);
						
						statwindow(s,DEREF_P_CHAR(pc_currchar));
						RefreshItem(pi_c);//AntiChrist
					}
					
					if (pi->id() == 0x0EED) // gold coin
					{
						P_ITEM packnum = packitem(currchar[s]);
						if (packnum != NULL) // lb
							if (pi->contserial == packnum->serial)
								update = 1;
					}
					
					pi->amount = amount;
					
				}
				
			/*	int amt = 0, wgt; bool tooheavy=false;				
				wgt = (int)Weight->LockeddownWeight(pi, &amt, 0);
				if(pi->contserial>0)
				{
					if (( (pc_currchar->weight+wgt) > (pc_currchar->st*WEIGHT_PER_STR)+30)) // LB -> added: drop item if too heavy
					{
					  float res=float( (pc_currchar->weight+wgt) - ((pc_currchar->st*WEIGHT_PER_STR)+30))*2;
					  int diff = pc_currchar->st;
					  diff -= (int)res;
					  if (diff<=0 && !pc_currchar->isGM() )					   
					  {
						 tooheavy=true;						 						 

						 bounce[1] = 0;
						 Xsend(s, bounce, 2);
						 if (ps->IsDragging()) // only restore item if it got dragged before !!!
						 {
						   ps->ResetDragging();
						   item_bounce4(s, pi);
						 }
						 sysmessage(s, "you can't pick this up, this is too heavy");					 
						 return;
					 }
					}
				} 

                if (!tooheavy) pc_currchar->weight+=wgt;				   
				update = 1;	*/				

				// LB remark: drop item if too heavy is a good solution,
				// but there's still a small bug remaining.
				// added weight from items picked up, but not put to bp, pd,  in other words hold in ones hand, 
				// is NOT subtracted when being dropped again to ground/other chars/other chars' bp's.
				// but this bug doesnt show up becasue weight is re-calculated automatically all 10 secs.
				// without adding weight of the item curently carrying in hand.
				// a correct solutions need the weight of item in hand being stored
				// , added to auto-re-calculation all x-secs code, and being subtracted if dropped.
				// because it's now only happening for leight weight items, because heavy weight itms cant be picke up anymore
				// I haven't corrected this yet. 			
				
				// Tauriel remove item from world mapcells
				mapRegions->Remove(pi); // remove this item from a map cell				
				pi->pos.x = 0;
				pi->pos.y = 0;
				pi->pos.z = 0;
				
				pi->flags.isBeeingDragged=true;
				pi->SetContSerial(-1);
			
			
			}
		}
	} // end of if i!=-1
	if (update) statwindow(s, DEREF_P_CHAR(pc_currchar));
}
Beispiel #21
0
void *recvCmd (void *socketid)
{
	int i, n, count = 0;
	ChunkInfo *info = NULL;
	char command[XIA_MAXBUF];
	char reply[XIA_MAXBUF];
	int sock = *((int*)socketid);
	char *fname;
	
	//ChunkContext contains size, ttl, policy, and contextID which for now is PID
	ChunkContext *ctx = XallocCacheSlice(POLICY_FIFO|POLICY_REMOVE_ON_EXIT, 0, 20000000);
	if (ctx == NULL)
		die(-2, "Unable to initilize the chunking system\n");

	while (1) {
		say("waiting for server command\n");
		memset(command, '\0', strlen(command));
		memset(reply, '\0', strlen(reply));
		if ((n = Xrecv(sock, command, 1024, 0))  < 0) {
			warn("socket error while waiting for data, closing connection\n");
			break;
		}
		//Sender does the chunking and then should start the sending commands
		if (strncmp(command, "get", 3) == 0) {
			fname = &command[4];
			say("Server requested file %s\n", fname);

			if (info) {
				// clean up the existing chunks first
			}
		
			info = NULL;
			count = 0;
			
			say("chunking file %s\n", fname);
			
			//Chunking is done by the XputFile which itself uses XputChunk, and fills out the info
			if ((count = XputFile(ctx, fname, CHUNKSIZE, &info)) < 0) {
				warn("unable to serve the file: %s\n", fname);
				sprintf(reply, "FAIL: File (%s) not found", fname);

			} else {
				sprintf(reply, "OK: %d", count);
			}
			say("%s\n", reply);
			
			
			//Just tells the receiver how many chunks it should expect.
			if (Xsend(sock, reply, strlen(reply), 0) < 0) {
				warn("unable to send reply to client\n");
				break;
			}
		//Sending the blocks cids
		} else if (strncmp(command, "block", 5) == 0) {
			char *start = &command[6];
			char *end = strchr(start, ':');
			if (!end) {
				// we have an invalid command, return error to client
				sprintf(reply, "FAIL: invalid block command");
			} else {
				*end = 0;
				end++;
				// FIXME: clean up naming, e is now a count
				int s = atoi(start);
				int e = s + atoi(end);
				strcpy(reply, "OK:");
				for(i = s; i < e && i < count; i++) {
					strcat(reply, " ");
					strcat(reply, info[i].cid);
				}
			}
			printf("%s\n", reply);
			if (Xsend(sock, reply, strlen(reply), 0) < 0) {
				warn("unable to send reply to client\n");
				break;
			}

		} else if (strncmp(command, "done", 4) == 0) {
			say("done sending file: removing the chunks from the cache\n");
			for (int i = 0; i < count; i++)
				XremoveChunk(ctx, info[i].cid);
			XfreeChunkInfo(info);
			info = NULL;
			count = 0;
			break;
		
		}
		else {
			sprintf(reply, "FAIL: invalid command (%s)\n", command);
			warn(reply);
			if (Xsend(sock, reply, strlen(reply), 0) < 0) {
				warn("unable to send reply to client\n");
				break;
			}
		}
	}
	
	if (info)
		XfreeChunkInfo(info);
	XfreeCacheSlice(ctx);
	return (void *)1;
}
Beispiel #22
0
void cBoat::Move(UOXSOCKET s, int dir, P_ITEM pBoat)
{//Move the boat and all it's items 1 square
	int tx=0,ty=0;
	int serial;
     
	if (pBoat == NULL)
		return;

	serial = calcserial(pBoat->moreb1, pBoat->moreb2, pBoat->moreb3, pBoat->moreb4);
	if (serial == INVALID_SERIAL) return;
	P_ITEM pTiller = FindItemBySerial( serial );
	if(pTiller == NULL)
		return;
	
	P_ITEM pi_p1 = FindItemBySerial( pBoat->morex );
	if(pi_p1 == NULL) 
		return;

	P_ITEM pi_p2 = FindItemBySerial( pBoat->morey );
	if(pi_p2 == NULL) 
		return;

	P_ITEM pHold = FindItemBySerial( pBoat->morez );
	if(pHold == NULL) 
		return;

	Xsend(s,wppause,2);

	switch(dir&0x0F)//Which DIR is it going in?
	{
	case '\x00' : 
		ty--;
		break;
	case '\x01' : 
		tx++; 
		ty--;
		break;
	case '\x02' :
		tx++;
		break;
	case '\x03' :
		tx++;
		ty++;
		break;
	case '\x04' : 
		ty++;
		break;
	case '\x05' :
		tx--;
		ty++;
		break;
	case '\x06' : 
		tx--;
		break;
	case '\x07' : 
		tx--; 
		ty--;
		break;
	default:
		{
		  sprintf((char*)temp,"warning: Boat direction error: %i int boat %i\n",pBoat->dir&0x0F,pBoat->serial);
		  LogWarning((char*)temp);
		  break;
		}
	}

	if((pBoat->pos.x+tx<=200 || pBoat->pos.x+tx>=6000) && (pBoat->pos.y+ty<=200 || pBoat->pos.y+ty>=4900)) //bugfix LB
	{
		pBoat->type2=0;
		itemtalk(s, pTiller, "Arr, Sir, we've hit rough waters!");
		Xsend(s,restart,2);
		return;
	}
	if(Block(pBoat,tx,ty,dir))
	{
		pBoat->type2=0;
		itemtalk(s, pTiller, "Arr, somethings in the way!");
		Xsend(s,restart,2);
		return;
	}

	//Move all the special items
	Coord_cl desloc(tx, ty, 0);
	pBoat->moveTo(pBoat->pos + desloc);
	pTiller->moveTo(pTiller->pos + desloc);
	pi_p1->moveTo(pi_p1->pos + desloc);
	pi_p2->moveTo(pi_p2->pos + desloc);
	pHold->moveTo(pHold->pos + desloc);

    serial = pBoat->serial;
	
	unsigned int a;
	vector<SERIAL> vecEntries = imultisp.getData(pBoat->serial);
	for (a = 0; a < vecEntries.size(); a++)
	{
		P_ITEM pi = FindItemBySerial(vecEntries[a]);
		if(pi != NULL)
		{
			pi->MoveTo(pi->pos.x+=tx, pi->pos.y+=ty, pi->pos.z);
			sendinrange(pi);
		}
	}

	vecEntries.clear();
	vecEntries = cmultisp.getData(pBoat->serial);
	for (a = 0; a < vecEntries.size(); a++)
	{
		P_CHAR pc_c = FindCharBySerial(vecEntries[a]);
		if (pc_c != NULL)
		{
			pc_c->moveTo(pc_c->pos + desloc);
			teleport((pc_c));
		}
	}
	Xsend(s,restart,2);
}
void cDragdrop::wear_item(P_CLIENT ps) // Item is dropped on paperdoll
{
	int j, k;
	tile_st tile;
	int serial, serhash, ci, letsbounce=0; // AntiChrist (5) - new ITEMHAND system
	UOXSOCKET s=ps->GetSocket();
	int cc=ps->GetCurrChar();
	P_CHAR pc_currchar = MAKE_CHARREF_LR(cc);

	int cserial=calcserial(buffer[s][6],buffer[s][7],buffer[s][8],buffer[s][9]);
	if(cserial==-1) return;
	k=calcCharFromSer( cserial );
	
	if( chars[k].dead )  //Exploit fix: Dead ppl can't equip anything.
		return;
	
	P_ITEM pi=FindItemBySerPtr(buffer[s]+1);
	if (!pi) return;
	pi->flags.isBeeingDragged=false;

//	if (clientDimension[s]==3)
//	{
	Map->SeekTile(pi->id(), &tile);
		
	// sprintf(temp, "Tiledata: name: %s flag1: %i flag2: %i flag3: %i flag4: %i layer: %i\n", tile.name, tile.flag1, tile.flag2, tile.flag3, tile.flag4, tile.layer);
	// clConsole.send(temp);
		
	if (tile.layer==0)
	{
		sysmessage(s,"You can't wear that");
		Sndbounce5(s);
		if (ps->IsDragging())
		{
			ps->ResetDragging();
			item_bounce4(s,pi);
			UpdateStatusWindow(s,pi);
		}
		return;
	}
//	}

	if (pi->id1>=0x40) return; // LB, client crashfix if multi-objects are moved to PD

	if (k==DEREF_P_CHAR(pc_currchar) || pc_currchar->isGM()) 
	{
		if (k!=-1) //lb
			if (k==DEREF_P_CHAR(pc_currchar) && pi->st>chars[k].st)
			{
				sysmessage(s,"You are not strong enough to use that.");
				Sndbounce5(s);
				if (ps->IsDragging())
				{
					ps->ResetDragging();
					item_bounce4(s,pi);
					UpdateStatusWindow(s,pi);
				}
				return;
			}
			
			if (pc_currchar->id1==0x01 && pc_currchar->id2==0x90) // Ripper...so males cant wear female armor
			if (pi->id1==0x1c && ( pi->id2==0x00 || pi->id2==0x02 || pi->id2==0x04 ||
                pi->id2==0x06 || pi->id2==0x08 || pi->id2==0x0a || pi->id2==0x0c))
			{
				sysmessage(s,"You cant wear female armor!");
				Sndbounce5(s);
				if (ps->IsDragging())
                {
					ps->ResetDragging();
					item_bounce4(s,pi);				  
					UpdateStatusWindow(s,pi);
				}
				return;
			}

//			if (clientDimension[s]==2) Map->SeekTile(pi->id(), &tile);
			if ((((pi->magic==2)||((tile.weight==255)&&(pi->magic!=1)))&&((pc_currchar->priv2&1)==0)) ||
				( (pi->magic==3|| pi->magic==4) && !pc_currchar->Owns(pi)))
			{
				item_bounce6(ps,pi);
				return;
			}
		

		// - AntiChrist (4) - checks for new ITEMHAND system
		// - now you can't equip 2 hnd weapons with 1hnd weapons nor shields!!
		serial=pc_currchar->serial;
		vector<SERIAL> vecContainer = contsp.getData(serial);
		for (ci=0;ci<vecContainer.size();ci++)
		{
			P_ITEM pi2 = FindItemBySerial(vecContainer[ci]);
			if (pi2 != NULL && pi2->contserial == serial)
			{
				if (pi2->itmhand==1 && pi->itmhand==1)
				{
					sysmessage(s,"You already have a weapon equipped!");
					letsbounce=1;
				}
				else if (pi2->itmhand==2 && pi->itmhand==1)
				{
					sysmessage(s,"Your hands are both occupied!");
					letsbounce=1;
				}
				else if (pi2->itmhand==1 && pi->itmhand==2)
				{
					sysmessage(s,"You cannot equip a two handed weapon with a weapon equipped!");
					letsbounce=1;
				}
				else if (pi2->itmhand==2 && pi->itmhand==2)
				{
					sysmessage(s,"You cannot equip a two handed weapon with a two handed weapon equipped!");
					letsbounce=1;
				}
				else if (pi2->itmhand==2 && pi->itmhand==3)
				{
					sysmessage(s,"You cannot equip a shield with a two handed weapon equipped!");
					letsbounce=1;
				}
				else if (pi2->itmhand==3 && pi->itmhand==2)
				{
					sysmessage(s,"You cannot equip a two handed weapon with a shield equipped!");
					letsbounce=1;
				}
				else if (pi2->layer == tile.layer) 
				{
 					sysmessage(s, "You already have an armor equipped!");
					letsbounce = 1;
				}
			}
			if(letsbounce)//Let's bounce the item
			{
				Sndbounce5(s);
				if (ps->IsDragging())
				{
					ps->ResetDragging();
					item_bounce4(s,pi);
					UpdateStatusWindow(s,pi);
					itemsfx(s, pi->id());		// antichrist
				}
				return;
			} 
		}
		if (!(pc_currchar->isGM())) //Ripper..players cant equip items on other players or npc`s paperdolls.
		{
			if ((k != DEREF_P_CHAR(pc_currchar)) && (!chars[k].isNpc()))
			{
				sysmessage(s, "You cant put items on other players!");
				item_bounce6(ps,pi);
				return;
			}
		}
		pi->SetContSerial(LongFromCharPtr(buffer[s]+6));
		pi->layer=buffer[s][5];
		// AntiChrist - now the STAT BONUS works -
		pc_currchar->st = (pc_currchar->st + pi->st2);
		pc_currchar->chgDex(pi->dx2);
		pc_currchar->in = (pc_currchar->in + pi->in2);
		if (pi->trigtype==2) // -Frazurbluu- Trigger Type 2 is my new trigger type *-
		{
			Trig->triggerwitem(s, pi, 1); // trigger is fired
		}	
		// AntiChrist -- for poisoned items
		if (showlayer)	clConsole.send("Item equipped on layer %i.\n",pi->layer);
		
		SndRemoveitem(pi->serial);
		
		LongToCharPtr(pi->serial,wearitem+1);
		ShortToCharPtr(pi->id(),wearitem+5);
		wearitem[8]=pi->layer;
		LongToCharPtr(pi->contserial,wearitem+9);
		wearitem[13]=pi->color1;
		wearitem[14]=pi->color2;
		Xsend(s, wearitem, 15);
		wornitems(s, k);//send update to current socket
		// -Frazurbluu- Worn item triggers will need code here
		// Trigger cod ewill also need the adjustments made for skill adding
		// An apply/unapply type of variable must be added for skill gains
		// Spell Item will have to be considered, like a necklace of reflection

		for (j=0;j<now;j++)
		{
			if (perm[j] && inrange1p(k, currchar[j]) && (j!=s))//and to all inrange sockets (without re-sending to current socket)//AntiChrist
				wornitems(j, k);
		}
		
		itemsfx(s, pi->id());	// Dupois - see itemsfx() for details	// Added Oct 09, 1998
		Weight->NewCalc(DEREF_P_CHAR(pc_currchar));	// Ison 2-20-99
		statwindow(s,DEREF_P_CHAR(pc_currchar));
		
		if (pi->glow>0)
		{
			pc_currchar->removeHalo(pi); // if gm equips on differnt player it needs to be deleted out of the hashteble
			chars[k].addHalo(pi);
			chars[k].glowHalo(pi);
		}
    }
}
Beispiel #24
0
/**
* @brief Initiate an XSSL connection with server.
*
* @param xssl
*
* @return 1 on success, <1 on failure
*/
int XSSL_connect(XSSL *xssl) {

	char buf[XIA_MAXBUF];
	int n;

	/* Send CLIENT HELLO */
	sprintf(buf, "CLIENT HELLO");
	if ((n = Xsend(xssl->sockfd, buf, strlen(buf), 0)) != strlen(buf)) {
		ERROR("ERROR sending CLIENT HELLO");
		return 0;
	}

	/* Wait for SERVER HELLO */
	// Receive public key + temporary public key signed by server's long-term private key
	// Continue receiving until we see "SERVER DONE"
	int offset = 0;
	while ( offset < 11 || strcmp("SERVER DONE", &buf[offset-11]) != 0 ) {
		n = Xrecv(xssl->sockfd, &buf[offset], sizeof(buf)-offset, 0);
		if (n < 0) {
			ERROR("ERROR receiving SERVER HELLO");
			return n;
		}
		if (n == 0) {
			ERROR("ERROR: server closed connection during SERVER HELLO");
			return n;
		}

		offset += n;
	}

	/* Parse public keys from SERVER HELLO */
	offset = strlen("SERVER HELLO");
	char *keys = &buf[offset];  // start of signed portion of message

	uint32_t *keybufsizeptr = (uint32_t*)&buf[offset];
	uint32_t keybufsize = *keybufsizeptr; // TODO: error checking here
	offset += sizeof(uint32_t);
	RSA *pubkey = deserialize_rsa_pub_key(&buf[offset], keybufsize);
	offset += keybufsize;

	uint32_t *tempkeybufsizeptr = (uint32_t*)&buf[offset];
	uint32_t tempkeybufsize = *tempkeybufsizeptr;
	offset += sizeof(uint32_t);
	RSA *sessionPubkey = deserialize_rsa_pub_key(&buf[offset], tempkeybufsize);
	offset += tempkeybufsize;

	uint32_t *siglenptr = (uint32_t*)&buf[offset];
	uint32_t siglen = *siglenptr;
	offset += sizeof(uint32_t);
	char* sig = &buf[offset];
	offset += siglen;
	DBGF("Received keys:\n\tkeylen: %d\n\ttempkeylen: %d\n\tsiglen: %d", keybufsize, tempkeybufsize, siglen);

	/* Verify two things:
	 *	1) hash(key) == SID so we trust the signature
	 *	2) verify the sig so we trust the temp key
	 */
	sockaddr_x *sa = (sockaddr_x*)malloc(sizeof(sockaddr_x));
	socklen_t len = sizeof(sockaddr_x);
	if (Xgetpeername(xssl->sockfd, (struct sockaddr*)sa, &len) < 0) {
		ERRORF("Error in Xgetpeername on socket %d: %s", xssl->sockfd, strerror(errno));
		return 0;
	}	
	Graph g(sa);
	Node sid_node = g.get_final_intent();
	DBGF("SID:          %s", sid_node.to_string().c_str());
	char *sid_from_key_hash = SID_from_keypair(pubkey);
	DBGF("Pub key hash: %s", sid_from_key_hash);
	if (strcmp(sid_node.to_string().c_str(), sid_from_key_hash) != 0) {
		WARN("Hash of received public key does not match SID! Closing connection.");
		return 0;
	}
	if (verify(pubkey, keys, keybufsize+tempkeybufsize+2*sizeof(uint32_t), sig, siglen) != 1) {
		WARN("Unable to verify signature on temporary RSA keypair! Closing connection.");
		return 0;
	}


	/* Generate pre-master secret and send to server, encrypted with sessionPubKey */
	unsigned char* pms = (unsigned char*)malloc(PRE_MASTER_SECRET_LENGTH);
    if (RAND_bytes(pms, PRE_MASTER_SECRET_LENGTH) != 1) {
        ERROR("ERROR: Couldn't generate pre-master secret");
		return 0;
    }
	if (VERBOSITY >= V_DEBUG) {
		DBG("Pre-Master Secret:");
		print_bytes(pms, PRE_MASTER_SECRET_LENGTH);
	}

	int ciphertext_len;
	if ( (ciphertext_len = pub_encrypt(sessionPubkey, 
							pms, PRE_MASTER_SECRET_LENGTH, 
							buf, XIA_MAXBUF)) == -1 ) {
		ERROR("ERROR: Unable to encrypt session key");
		return 0;
	}
    
	n = 0;
	offset = 0;
	while (offset < ciphertext_len) {
		if ((n = Xsend(xssl->sockfd, &buf[offset], ciphertext_len-offset, 0)) < 0) {
			ERROR("ERROR sending pre-master secret");
			return 0;
		}
		offset += n;
	}
	

	/* Init symmetric session ciphers with pre-master secret.
	   Client encrypt context initialized with same key data as
	   server decrypt context and vice versa. */
	uint32_t salt[] = SALT;
	if (aes_init(pms, PRE_MASTER_SECRET_LENGTH/2, 
				 &pms[PRE_MASTER_SECRET_LENGTH/2], PRE_MASTER_SECRET_LENGTH/2, 
				 (unsigned char *)&salt, xssl->en, xssl->de)) {
		ERROR("ERROR initializing AES ciphers");
		return 0;
	}
	free(pms);

	
	/* For now, omitting CLIENT DONE */


	return 1;
}
Beispiel #25
0
void cPacketStatWindow::sendBasic( NXWCLIENT ps, UI08 flag  ) {
	if( ps == NULL ) return; //after error here
	this->flag = flag;
	Xsend( ps->toInt(), this->getBeginValid(), this->headerSize );
};
Beispiel #26
0
P_ITEM cTrade::tradestart(UOXSOCKET s, P_CHAR pc_i)
{
	P_CHAR pc_currchar = currchar[s];
	unsigned char msg[90];

	P_ITEM pi_bps = Packitem(pc_currchar);
	P_ITEM pi_bpi = Packitem(pc_i);
	UOXSOCKET s2 = calcSocketFromChar(pc_i);

	if (pi_bps == NULL) //LB
	{
		sysmessage(s, "Time to buy a backpack!");
		sysmessage(s2, "%s doesnt have a backpack!", pc_currchar->name.c_str());
		return 0;
	}
	if (pi_bpi == NULL)
	{
		sysmessage(s2, "Time to buy a backpack!");
		sysmessage(s, "%s doesnt have a backpack!", pc_i->name.c_str());
		return 0;
	}

	P_ITEM pi_ps = Items->SpawnItem(s2, pc_currchar, 1, "#", 0, 0x1E, 0x5E, 0, 0, 0);
	if(pi_ps == NULL)
		return 0;
	pi_ps->pos = Coord_cl(26, 0, 0);
	pi_ps->SetContSerial(pc_currchar->serial);
	pi_ps->layer=0;
	pi_ps->type=1;
	pi_ps->dye=0;
	sendbpitem(s, pi_ps);
	if (s2 != INVALID_UOXSOCKET)
		sendbpitem(s2, pi_ps);

	P_ITEM pi_pi = Items->SpawnItem(s2,pc_i,1,"#",0,0x1E,0x5E,0,0,0);
	if (pi_pi == NULL)
		return 0;
	pi_pi->pos = Coord_cl(26, 0, 0);
	pi_pi->SetContSerial(pc_i->serial);
	pi_pi->layer=0;
	pi_pi->type=1;
	pi_pi->dye=0;
	sendbpitem(s, pi_pi);
	if (s2 != INVALID_UOXSOCKET)
		sendbpitem(s2, pi_pi);

	pi_pi->moreb1 = static_cast<unsigned char>((pi_ps->serial&0xFF000000)>>24);
	pi_pi->moreb2 = static_cast<unsigned char>((pi_ps->serial&0x00FF0000)>>16);
	pi_pi->moreb3 = static_cast<unsigned char>((pi_ps->serial&0x0000FF00)>>8);
	pi_pi->moreb4 = static_cast<unsigned char>((pi_ps->serial&0x000000FF));
	pi_ps->more1 = static_cast<unsigned char>((pi_pi->serial&0xFF000000)>>24);
	pi_ps->more2 = static_cast<unsigned char>((pi_pi->serial&0x00FF0000)>>16);
	pi_ps->more3 = static_cast<unsigned char>((pi_pi->serial&0x0000FF00)>>8);
	pi_ps->more4 = static_cast<unsigned char>((pi_pi->serial&0x000000FF));
	pi_ps->morez  = 0;
	pi_pi->morez  = 0;

	msg[0] = 0x6F; // Header Byte
	msg[1] = 0; // Size
	msg[2] = 47; // Size
	msg[3] = 0; // Initiate
	LongToCharPtr(pc_i->serial,msg+4);
	LongToCharPtr(pi_ps->serial,msg+8);
	LongToCharPtr(pi_pi->serial,msg+12);
	msg[16]=1;
	strcpy((char*)&(msg[17]), pc_i->name.c_str());
	Xsend(s, msg, 47);

	if (s2 != INVALID_UOXSOCKET)
	{
		msg[0]=0x6F; // Header Byte
		msg[1]=0;    // Size
		msg[2]=47;   // Size
		msg[3]=0;    // Initiate
		LongToCharPtr(pc_currchar->serial,msg+4);
		LongToCharPtr(pi_pi->serial,msg+8);
		LongToCharPtr(pi_ps->serial,msg+12);
		msg[16]=1;
		strcpy((char*)&(msg[17]), pc_currchar->name.c_str());

		Xsend(s2, msg, 47);
	}
	return pi_ps;
}
// guildstonemenu() : Opens the guild menu for a player
// Recognizes Guildmaster with the owner fields of the stone.
// Ofcourse checks for membership before opening any gump ;)
void cGuildStone::Menu(UOXSOCKET s, int page)
{
	//int total,i, counter,guild,recruit,war,member;
	int counter = 1;
	int lentext;
	int gumpnum = 0;
	char guildfealty[60],guildt[16],toggle[6];
	static char mygump[MAXMEMRECWAR][257];

	P_CHAR pc = currchar[s];

	if (!isMember( pc ) && !pc->isGM())
	{
		sysmessage(s, "You are not a member of this guild. Ask an existing guildmember to invite you into this guild.");
		return;
	}

	strcpy(guildfealty, "yourself");
	if ((pc->guildfealty() != pc->serial)&&(pc->guildfealty() != INVALID_SERIAL))
	{
		vector<SERIAL>::iterator it = find(member.begin(), member.end(), pc->guildfealty());
		if ( it != member.end())
		{
			strcpy(guildfealty, FindCharBySerial(*it)->name.c_str());
		}
	}
	else 
		pc->setGuildfealty( pc->serial );
	if (this->ownserial == INVALID_SERIAL) 
		CalcMaster();
	
	P_CHAR guildmaster = FindCharBySerial(this->ownserial);

	switch (this->guildType) 
	{
		case standard:		strcpy(guildt, " Standard");	break;
		case order:			strcpy(guildt, "n Order");		break;
		case chaos:			strcpy(guildt, " Chaos");		break;
	}
	
	if (pc->guildtoggle()) 
		strcpy(toggle, "On");
	else
		strcpy(toggle, "Off");

	// our prefix is 0xFE (darkstorm)
	gmprefix[7] = 0xFE;

	switch(page)
	{
	case 1:
		gumpnum=9;
		gmprefix[8] = 1;

		if (guildmaster<0) return;

		lentext = sprintf(mygump[0], "%s (%s %s)", this->guildName.c_str(), guildmaster->guildtitle().latin1(), guildmaster->name.c_str());
		strcpy(mygump[1],"Recruit someone into the guild.");
		strcpy(mygump[2],"View the current roster.");
		strcpy(mygump[3],"View the guild's charter.");
		sprintf(mygump[4],"Declare your fealty. You are currently loyal to %s.",guildfealty);
		sprintf(mygump[5],"Toggle showing the guild's abbreviation in your name to unguilded people. Currently %s.",toggle);
		strcpy(mygump[6],"Resign from the guild.");
		strcpy(mygump[7],"View list of candidates who have been sponsored to the guild.");
	    if ((pc->serial == this->ownserial)|| (pc->isGM()))							// Guildmaster Access?
		{															
			gumpnum=10;
			gmprefix[8] = 0;
			sprintf(mygump[8],"Access %s functions.", guildmaster->guildtitle().latin1());
			sprintf(mygump[9],"View list of guild that %s has declared war on.", this->guildName.c_str());
			sprintf(mygump[10],"View list of guilds that have declared war on %s.",this->guildName.c_str());
		} else {													// Normal Members access!
			sprintf(mygump[8],"View list of guilds that %s have declared war on.",this->guildName.c_str());
			sprintf(mygump[9],"View list of guilds that have declared war on %s.",this->guildName.c_str());
		}
		break;
	case 2:														// guildmaster menu
		gumpnum=14;
		lentext = sprintf(mygump[0], "%s, %s functions", this->guildName.c_str(), guildmaster->guildtitle().latin1());
		strcpy(mygump[1], "Set the guild name.");
		strcpy(mygump[2], "Set the guild's abbreviation.");
		sprintf(mygump[3], "Change the type of the guild. (Currently a%s guild.)",guildt);
		strcpy(mygump[4], "Set the guild's charter.");
		strcpy(mygump[5], "Dismiss a member.");
		strcpy(mygump[6], "Declare war from menu.");
		strcpy(mygump[7], "Declare war from targeting enemy.");
		strcpy(mygump[8], "Declare peace.");
		strcpy(mygump[9], "Accept a candidate seeking membership.");
		strcpy(mygump[10],"Refuse a candidate seeking membership.");
		strcpy(mygump[11],"Set the guildmaster's title.");
		strcpy(mygump[12],"Grant a title to another member.");
		strcpy(mygump[13],"Move this guildstone.");
		strcpy(mygump[14],"Return to the main menu.");

		gmprefix[8] = 2;
		break;
	case 3:														// guild type
		gumpnum=4;
		lentext=sprintf(mygump[0], "Please select the type you want your guild to be related to.");
		strcpy(mygump[1], "Select this to return to main menu.");
		strcpy(mygump[2], "Set to Standard.");
		strcpy(mygump[3], "Set to Order.");
		strcpy(mygump[4], "Set to Chaos.");
		gmprefix[8] = 3;
		break;
	case 4:														// edit charter
		gumpnum=3;
		lentext=sprintf(mygump[0], "Set %s charter.", this->guildName.c_str());
		strcpy(mygump[1], "Select this to return to main menu.");
		strcpy(mygump[2], "Set the charter.");
		strcpy(mygump[3], "Set the webpage.");
		gmprefix[8] = 4;
		break;
	case 5:														// view charter
		gumpnum=2;
		lentext=sprintf(mygump[0], "%s charter.", this->guildName.c_str());
		sprintf(mygump[1], "%s. Select this to return to the main menu.", this->charter.c_str());
		sprintf(mygump[2], "Visit the guild website at %s", this->webpage.c_str());
		gmprefix[8] = 5;
		break;
	case 6:
	{														// Candidates list
		gumpnum = this->recruit.size();
		lentext=sprintf(mygump[0], "%s list of candidates.", this->guildName.c_str());
		sprintf(mygump[1], "Select this to return to the menu.");
		unsigned int i;
		for (i = 0; i < recruit.size(); ++i)
		{
			strcpy(mygump[counter++], FindCharBySerial(this->recruit[i])->name.c_str());
		}
		gmprefix[8] = 6;
		break;
	}
	case 7:
	{														// roster
		gumpnum = this->member.size();
		lentext=sprintf(mygump[0], "%s members roster.", this->guildName.c_str());
		strcpy(mygump[1], "Select this to return to the menu.");
		counter=1;
		unsigned int i;
		for (i = 0; i < member.size(); ++i)
		{
			counter++;
			strcpy(mygump[counter], FindCharBySerial(this->member[i])->name.c_str());
		}
		gmprefix[8] = 7;
		break;
	}
	case 8:
	{													// member dismiss
		gumpnum = this->member.size();
		lentext=sprintf(mygump[0], "Dismiss what member?");
		strcpy(mygump[1], "Select this to return to the menu.");
		counter=1;
		unsigned int i;
		for ( i = 0; i < member.size(); ++i)
		{
			counter++;
			strcpy(mygump[counter], FindCharBySerial(this->member[i])->name.c_str());
		}
		gmprefix[8] = 8;
		break;
	}
	case 9:	
	{													// Refuse Candidates
		gumpnum = this->recruit.size();
		lentext=sprintf(mygump[0], "Refuse what candidate? %s", this->guildName.c_str());
		strcpy(mygump[1], "Select this to return to the menu.");
		counter=1;
		unsigned int i;
		for ( i = 0; i < recruit.size(); ++i)
		{
			counter++;
			strcpy(mygump[counter], FindCharBySerial(this->recruit[i])->name.c_str());
		}
		gmprefix[8] = 9;
		break;
	}
	case 10:														// Accept Candidates
	{
		gumpnum = this->recruit.size();
		lentext=sprintf(mygump[0], "Accept what candidate?.%s", this->guildName.c_str());
		strcpy(mygump[1], "Select this to return to the menu.");
		counter=1;
		unsigned int i;
		for ( i = 0; i < recruit.size(); ++i)
		{
			counter++;
			strcpy(mygump[counter], FindCharBySerial(this->recruit[i])->name.c_str());
		}
		gmprefix[8] = 10;
		break;
	}
	case 11:														// War list
	{
		gumpnum = this->war.size();
		lentext=sprintf(mygump[0], "Guild that %s has declared war on.", this->guildName.c_str());
		strcpy(mygump[1], "Select this to return to the menu.");
		counter=1;
		unsigned int i;
		for ( i = 0; i < war.size(); ++i )
		{
			counter++;
			cGuildStone* pStone = dynamic_cast<cGuildStone*>(FindItemBySerial(this->war[i]));
			strcpy(mygump[counter], pStone->guildName.c_str());
		}
		gmprefix[8] = 11;
		break;
	}
	case 12:
	{														// grant title
		gumpnum = this->member.size();
		lentext=sprintf(mygump[0], "Grant a title to whom?");
		strcpy(mygump[1], "Select this to return to the menu.");
		counter = 1;
		unsigned int i;
		for (i = 0; i < this->member.size(); ++i)
		{
			counter++;
			strcpy(mygump[counter], FindCharBySerial(this->member[i])->name.c_str());
		}
		gmprefix[8] = 12;
		break;
	}
	case 13:	
	{													// fealty
		gumpnum = this->member.size();
		lentext = sprintf(mygump[0], "Whom do you wish to be loyal to?");
		strcpy(mygump[1], "Select this to return to the menu.");
		counter=1;
		unsigned int i;
		for (i = 0; i < this->member.size(); ++i)
		{
			counter++;
			strcpy(mygump[counter], FindCharBySerial(this->member[i])->name.c_str());
		}
		
		gmprefix[8] = 13;
		break;
	}
	case 14:														// declare War list
	{
		gumpnum=1;
		lentext=sprintf(mygump[0], "What guilds do you with to declare war?");
		strcpy(mygump[1], "Select this to return to the menu.");
		counter=1;
		list<SERIAL>::iterator it;
		for (it = guilds.begin(); it != guilds.end(); ++it)
		{
			if ( !this->free && this->serial != *it )
			{
				unsigned int i;
				for (i = 0; i < this->war.size(); ++i)
				{
					if (this->war[i] == *it) 
					{
						++gumpnum;
						P_ITEM pStone = FindItemBySerial(*it);
						strcpy(mygump[++counter], pStone->name().ascii());
					}
				}
			}
		}

		gmprefix[8] = 14;
		break;
	}
	case 15:														// declare peace list
	{
		gumpnum = this->war.size();
		lentext = sprintf(mygump[0], "What guilds do you with to declare peace?");
		strcpy(mygump[1], "Select this to return to the menu.");
		counter = 1;
		unsigned int i;
		for (i = 0; i < this->war.size(); ++i)
		{
			if ( this->war[i] != INVALID_SERIAL)
			{
				P_ITEM pStone = FindItemBySerial( this->war[i] );
				strcpy(mygump[++counter], pStone->name().ascii());
			}
		}
		gmprefix[8] = 15;
		break;
	}
	case 16:														// War list 2
		{
		gumpnum=1;
		lentext=sprintf(mygump[0], "Guilds that have decalred war on %s.", this->name().ascii());
		strcpy(mygump[1], "Select this to return to the menu.");
		counter=1;
		list<SERIAL>::iterator it;
		for (it = guilds.begin(); it != guilds.end(); ++it)
		{
			if ((*it) != INVALID_SERIAL)
			{
				unsigned int i;
				for ( i = 0; i < this->war.size(); ++i)
				{
					if (this->war[i] == *it)
					{
						++gumpnum;
						P_ITEM pStone = FindItemBySerial(*it);
						strcpy(mygump[++counter], pStone->name().ascii() );
					}
				}
			}
		}
		gmprefix[8] = 16;
		break;
		}
	}
	
	int total=9+1+lentext+1;
	int i;
	for (i = 1; i <= gumpnum; i++)
	{
		total+=4+1+strlen(mygump[i]);
	}
	gmprefix[1] = total>>8;
	gmprefix[2] = total%256;
	LongToCharPtr(pc->serial, &gmprefix[3]);
	Xsend(s, gmprefix, 9);
	Xsend(s, &lentext, 1);
	Xsend(s, mygump[0], lentext);
	lentext = gumpnum;
	Xsend(s, &lentext, 1);
	for (i = 1; i <= gumpnum; i++)
	{
		gmmiddle[0]=0;
		gmmiddle[1]=0;
		Xsend(s,gmmiddle,4);
		lentext=strlen(mygump[i]);
		Xsend(s,&lentext,1);
		Xsend(s,mygump[i],lentext);
	}
	return;
}
static void Sndbounce5(UOXSOCKET s)
{
	bounce[1]=5;
	Xsend(s, bounce, 2);
}
Beispiel #29
0
void cBoat::Turn(P_ITEM pBoat, int turn)//Turn the boat item, and send all the people/items on the boat to turnboatstuff()
{
	if (pBoat == NULL) return; 
	
	int id2 = pBoat->id2 ,olddir = pBoat->dir;
	unsigned short int Send[MAXCLIENT];
	SERIAL serial;
	int a,dir, d=0;
	
	
	for (a = 0; a < now; ++a)
	{
		if (iteminrange(a, pBoat, BUILDRANGE) && perm[a])
		{
			Send[d]=a;
			Xsend(a,wppause,2);
			d++; 
		} 
		
	}
	
	//Of course we need the boat items!
	serial = calcserial(pBoat->moreb1,pBoat->moreb2,pBoat->moreb3,pBoat->moreb4);
	if(serial == INVALID_SERIAL) return;
	P_ITEM pTiller = FindItemBySerial( serial );
	if(pTiller == NULL) return;
	P_ITEM pi_p1 = FindItemBySerial( pBoat->morex );
	if(pi_p1 == NULL) return;
	P_ITEM pi_p2 = FindItemBySerial( pBoat->morey );
	if(pi_p2 == NULL) return;
	P_ITEM pi_hold = FindItemBySerial( pBoat->morez );
	if(pi_hold == NULL) return;
	
	if(turn)//Right
	{
		pBoat->dir+=2;
		id2++;
	} else {//Left
		pBoat->dir-=2;
		id2--;
	}
	if(pBoat->dir>7) pBoat->dir-=4;//Make sure we dont have any DIR errors
	//if(pBoat->dir<0) pBoat->dir+=4;
	if(id2<pBoat->more1) id2+=4;//make sure we don't have any id errors either
	if(id2>pBoat->more2) id2-=4;//Now you know what the min/max id is for :-)
	
	pBoat->id2=id2;//set the id
	
	if(pBoat->id2==pBoat->more1) pBoat->dir=0;//extra DIR error checking
	if(pBoat->id2==pBoat->more2) pBoat->dir=6;
	
	
	if( Block( pBoat, 0, 0, pBoat->dir ) )
	{
		pBoat->dir = olddir;
		for( a = 0; a < d; a++ )
		{
			Xsend( Send[a], restart, 2 );
			itemtalk( Send[a], pTiller, "Arr, something's in the way!" );
		}
		return;
	}
	pBoat->id2=id2;//set the id
	
	if(pBoat->id2==pBoat->more1) pBoat->dir=0;//extra DIR error checking
	if(pBoat->id2==pBoat->more2) pBoat->dir=6;    
	
	
	
	
    serial=pBoat->serial; // lb !!!

	unsigned int ci;	
	vector<SERIAL> vecEntries = imultisp.getData(serial);
    for (ci = 0; ci < vecEntries.size(); ci++)
	{
		P_ITEM pi = FindItemBySerial(vecEntries[ci]);
		if (pi != NULL)
			TurnStuff(pBoat, pi, turn);
	}
	
	vecEntries.clear();
	vecEntries = cmultisp.getData(serial);
	for (ci = 0; ci < vecEntries.size(); ci++)
	{
		P_CHAR pc = FindCharBySerial(vecEntries[ci]);
		if (pc != NULL)
			TurnStuff(pBoat, pc, turn);
	}
	
	//Set the DIR for use in the Offsets/IDs array
	dir = (pBoat->dir&0x0F)/2;
	
	//set it's Z to 0,0 inside the boat
	
	pi_p1->MoveTo(pBoat->pos.x,pBoat->pos.y,pi_p1->pos.z);
	pi_p1->id2 = cShipItems[dir][PORT_P_C];//change the ID
	
	pi_p2->MoveTo(pBoat->pos.x,pBoat->pos.y,pi_p2->pos.z);
	pi_p2->id2=cShipItems[dir][STAR_P_C];
	
	pTiller->MoveTo(pBoat->pos.x,pBoat->pos.y, pTiller->pos.z);
	pTiller->id2=cShipItems[dir][TILLERID];
	
	pi_hold->MoveTo(pBoat->pos.x,pBoat->pos.y, pi_hold->pos.z);
	pi_hold->id2=cShipItems[dir][HOLDID];
	
	switch(pBoat->more1)//Now set what size boat it is and move the specail items
	{
	case 0x00:
	case 0x04:
		pi_p1->moveTo(pi_p1->pos + Coord_cl(iSmallShipOffsets[dir][PORT_PLANK][X], iSmallShipOffsets[dir][PORT_PLANK][Y], 0));
		pi_p2->moveTo(pi_p2->pos + Coord_cl(iSmallShipOffsets[dir][STARB_PLANK][X], iSmallShipOffsets[dir][STARB_PLANK][Y], 0));
		pTiller->moveTo(pTiller->pos + Coord_cl(iSmallShipOffsets[dir][TILLER][X], iSmallShipOffsets[dir][TILLER][Y], 0));
		pi_hold->moveTo(pi_hold->pos + Coord_cl(iSmallShipOffsets[dir][HOLD][X], iSmallShipOffsets[dir][HOLD][Y], 0));
		break;
	case 0x08:
	case 0x0C:
		pi_p1->moveTo(pi_p1->pos + Coord_cl(iMediumShipOffsets[dir][PORT_PLANK][X], iMediumShipOffsets[dir][PORT_PLANK][Y], 0) );
		pi_p2->moveTo(pi_p2->pos + Coord_cl(iMediumShipOffsets[dir][STARB_PLANK][X], iMediumShipOffsets[dir][STARB_PLANK][Y], 0) );
		pTiller->moveTo(pTiller->pos + Coord_cl(iMediumShipOffsets[dir][TILLER][X], iMediumShipOffsets[dir][TILLER][Y], 0) );
		pi_hold->moveTo(pi_hold->pos + Coord_cl(iMediumShipOffsets[dir][HOLD][X], iMediumShipOffsets[dir][HOLD][Y], 0) );
		
		break;
	case 0x10:
	case 0x14:
		pi_p1->moveTo(pi_p1->pos + Coord_cl(iLargeShipOffsets[dir][PORT_PLANK][X], iLargeShipOffsets[dir][PORT_PLANK][Y], 0) );
        pi_p2->moveTo(pi_p2->pos + Coord_cl(iLargeShipOffsets[dir][STARB_PLANK][X], iLargeShipOffsets[dir][STARB_PLANK][Y], 0 ) );
		pTiller->moveTo(pTiller->pos + Coord_cl(iLargeShipOffsets[dir][TILLER][X], iLargeShipOffsets[dir][TILLER][Y], 0 ) );
		pi_hold->moveTo(pi_hold->pos + Coord_cl(iLargeShipOffsets[dir][HOLD][X], iLargeShipOffsets[dir][HOLD][Y], 0 ) );
		
		break;
		
	default: 
		{ 
			sprintf((char*)temp,"Turnboatstuff() more1 error! more1 = %c not found!\n",pBoat->more1); 
			LogWarning((char*)temp);
		}  
	}
	
	sendinrange(pi_p1);
	sendinrange(pi_p2);
	sendinrange(pi_hold);
	sendinrange(pTiller);
	
	for (a = 0; a < d; ++a) 
	{ 
		Xsend(Send[a],restart,2);
	}
}
/*!
\brief Double click
\author Ripper, rewrite by Endymion
\param ps client of player dbclick
\note Completely redone by Morrolan 20-07-99
\warning I use a define CASE for make more readable the code, if you change name of P_ITEM pi chage also the macro
\todo los
*/
void doubleclick(NXWCLIENT ps)
{

	if(ps==NULL) return;
	P_CHAR pc = ps->currChar();
	VALIDATEPC( pc );
	NXWSOCKET s = ps->toInt();

	// the 0x80 bit in the first byte is used later for "keyboard" and should be ignored
	SERIAL serial = LongFromCharPtr(buffer[s] +1) & 0x7FFFFFFF;

	if (isCharSerial(serial))
	{
		P_CHAR pd=pointers::findCharBySerial(serial);
		if(ISVALIDPC(pd))
			dbl_click_character(ps, pd);
		return;
	}

	P_ITEM pi = pointers::findItemBySerial(serial);
	VALIDATEPI(pi);

	if (pi->amxevents[EVENT_IONDBLCLICK]!=NULL) {
		g_bByPass = false;
		pi->amxevents[EVENT_IONDBLCLICK]->Call( pi->getSerial32(), pc->getSerial32() );
		if (g_bByPass==true)
			return;
	}
	/*
	g_bByPass = false;
	pi->runAmxEvent( EVENT_IONDBLCLICK, pi->getSerial32(), s );
	if (g_bByPass==true)
		return;
	*/

	if (!checkItemUsability(pc , pi, ITEM_USE_DBLCLICK))
		return;

	Location charpos= pc->getPosition();

	if (pc->IsHiddenBySpell()) return;	//Luxor: cannot use items if under invisible spell

	if ( !pc->IsGM() && pc->objectdelay >= uiCurrentTime )
	{
		pc->sysmsg(TRANSLATE("You must wait to perform another action."));
		return;
	}
	else
		pc->objectdelay = SrvParms->objectdelay * MY_CLOCKS_PER_SEC + uiCurrentTime;

	///MODIFY, CANT CLICK ITEM AT DISTANCE >2//////////////
	if ( (pc->distFrom(pi)>2) && !pc->IsGM() && !(pc->nxwflags[0] & cChar::flagSpellTelekinesys) ) //Luxor: let's check also for the telekinesys spell
	{
		pc->sysmsg( TRANSLATE("Must be closer to use this!"));
		pc->objectdelay=0;
		return;
	}


//<Anthalir> VARIAIBLI

	tile_st item;

	P_ITEM pack= pc->getBackpack();
	VALIDATEPI( pack );


	data::seekTile( pi->getId(), item );
//////FINEVARIABILI
	if ( ServerScp::g_nEquipOnDclick )
	{
		// equip the item only if it is in the backpack of the player
		if ((pi->getContSerial() == pack->getSerial32()) && (item.quality != 0) && (item.quality != LAYER_BACKPACK) && (item.quality != LAYER_MOUNT))
		{
			int drop[2]= {-1, -1};	// list of items to drop, there no reason for it to be larger
			int curindex= 0;

			NxwItemWrapper wea;
			wea.fillItemWeared( pc, true, true, true );
			for( wea.rewind(); !wea.isEmpty(); wea++ )
			{

				P_ITEM pj=wea.getItem();
				if(!ISVALIDPI(pj))
					continue;
				if ((item.quality == LAYER_1HANDWEAPON) || (item.quality == LAYER_2HANDWEAPON))// weapons
				{
					if (pi->itmhand == 2) // two handed weapons or shield
					{
						if (pj->itmhand == 2)
							drop[curindex++]= DEREF_P_ITEM(pj);
						if ( (pj->itmhand == 1) || (pj->itmhand == 3) )
							drop[curindex++]= DEREF_P_ITEM(pj);
					}
					if (pi->itmhand == 3)
					{
						if ((pj->itmhand == 2) || pj->itmhand == 3)
							drop[curindex++]= DEREF_P_ITEM(pj);
					}
					if ((pi->itmhand == 1) && ((pj->itmhand == 2) || (pj->itmhand == 1)))
						drop[curindex++]= DEREF_P_ITEM(pj);
				}
				else	// not a weapon
				{
					if (pj->layer == item.quality)
						drop[curindex++]= DEREF_P_ITEM(pj);
				}
			}

			if (ServerScp::g_nUnequipOnReequip)
			{
				if (drop[0] > -1)	// there is at least one item to drop
				{
					for (int i= 0; i< 2; i++)
					{
						if (drop[i] > -1)

						{

							P_ITEM p_drop=MAKE_ITEM_REF(drop[i]);

							if(ISVALIDPI(p_drop))
								pc->UnEquip( p_drop );

						}
					}
				}
				pc->playSFX( itemsfx(pi->getId()) );
				pc->Equip( pi );
			}
			else
			{
				if (drop[0] == -1)
				{
					pc->playSFX( itemsfx(pi->getId()) );
					pc->Equip( pi );
				}
			}
			return;
		}
	} // </Anthalir>


	//<Luxor>: Circle of transparency bug fix
	P_ITEM pCont;
	Location dst;

	pCont = pi->getOutMostCont();

	if(pCont->isInWorld()) {
		dst = pCont->getPosition();
	} else {
		P_CHAR pg_dst = pointers::findCharBySerial( pCont->getContSerial() );
		VALIDATEPC(pg_dst);
		dst = pg_dst->getPosition();
	}

	Location charPos = pc->getPosition();
	charPos.z = dst.z;
	charPos.dispz = dst.dispz;

	if ( !pc->IsGM() && !lineOfSight( charPos, dst ) && !(pc->nxwflags[0] & cChar::flagSpellTelekinesys) ) {
		pc->sysmsg( TRANSLATE( "You cannot reach the item" ) );
		return;
	}
	//</Luxor>

	P_CHAR itmowner = pi->getPackOwner();

	if(!pi->isInWorld()) {
		if (isItemSerial(pi->getContSerial()) && pi->type != ITYPE_CONTAINER)
		{// Cant use stuff that isn't in your pack.

			if ( ISVALIDPC(itmowner) && (itmowner->getSerial32()!=pc->getSerial32()) )
					return;
		}
		else
			if (isCharSerial(pi->getContSerial()) && pi->type!=(UI32)INVALID)
			{// in a character.
				P_CHAR wearedby = pointers::findCharBySerial(pi->getContSerial());
				if (ISVALIDPC(wearedby))
					if (wearedby->getSerial32()!=pc->getSerial32() && pi->layer!=LAYER_UNUSED_BP && pi->type!=ITYPE_CONTAINER)
						return;
			}
	}

	if ((pi->magic==4) && (pi->secureIt==1))
	{
		if (!pc->isOwnerOf(pi) || !pc->IsGMorCounselor())
		{
			pc->sysmsg( TRANSLATE("That is a secured chest!"));
			return;
		}
	}

	if (pi->magic == 4)
	{
		pc->sysmsg( TRANSLATE("That item is locked down."));
		return;
	}

	if (pc->dead && pi->type!=ITYPE_RESURRECT) // if you are dead and it's not an ankh, FORGET IT!
	{
		pc->sysmsg(TRANSLATE("You may not do that as a ghost."));
		return;
	}
	else if (!pc->IsGMorCounselor() && pi->layer!=0 && !pc->IsWearing(pi))
	{// can't use other people's things!
		if (!(pi->layer==LAYER_BACKPACK  && SrvParms->rogue==1)) // bugfix for snooping not working, LB
		{
			pc->sysmsg(TRANSLATE("You cannot use items equipped by other players."));
			return;
		}
	}


	// Begin checking objects that we force an object delay for (std objects)
	// start trigger stuff
	if (pi->trigger > 0)
	{
		if (pi->trigtype == 0)
		{
			if ( TIMEOUT( pi->disabled ) ) // changed by Magius(CHE) §
			{
				triggerItem(s, pi, TRIGTYPE_DBLCLICK); // if players uses trigger
				return;
			}
			else
			{
				if ( pi->disabledmsg!=NULL )
					pc->sysmsg("%s", pi->disabledmsg->c_str());
				else
					pc->sysmsg(TRANSLATE("That doesnt seem to work right now."));
				return;
			}
		}
		else
		{
			pc->sysmsg( TRANSLATE("You are not close enough to use that."));
			return;
		}
	}

	// check this on trigger in the event that the .trigger property is not set on the item
	// trigger code.  Check to see if item is envokable by id
	else if (checkenvoke( pi->getId() ))
	{
		pc->envokeitem = pi->getSerial32();
		pc->envokeid = pi->getId();
		P_TARGET targ = clientInfo[s]->newTarget( new cObjectTarget() );
		targ->code_callback=target_envoke;
		targ->send( ps );
		ps->sysmsg( TRANSLATE("What will you use this on?"));
		return;
	}
	// end trigger stuff
	// BEGIN Check items by type

	int los = 0;


	BYTE map1[20] = "\x90\x40\x01\x02\x03\x13\x9D\x00\x00\x00\x00\x13\xFF\x0F\xFF\x01\x90\x01\x90";
	BYTE map2[12] = "\x56\x40\x01\x02\x03\x05\x00\x00\x00\x00\x00";
	// By Polygon: This one is needed to show the location on treasure maps
	BYTE map3[12] = "\x56\x40\x01\x02\x03\x01\x00\x00\x00\x00\x00";


	P_TARGET targ = NULL;

	switch (pi->type)
	{
	case ITYPE_RESURRECT:
		// Check for 'resurrect item type' this is the ONLY type one can use if dead.
		if (pc->dead)
		{
			pc->resurrect();
			pc->sysmsg(TRANSLATE("You have been resurrected."));
			return;
		}
		else
		{
			pc->sysmsg(TRANSLATE("You are already living!"));
			return;
		}
	case ITYPE_BOATS:// backpacks - snooping a la Zippy - add check for SrvParms->rogue later- Morrolan

		if (pi->type2 == 3)
		{
			switch( pi->getId() & 0xFF ) {
				case 0x84:
				case 0xD5:
				case 0xD4:
				case 0x89:
					Boats->PlankStuff(pc, pi);
					break;
				default:
					pc->sysmsg( TRANSLATE("That is locked."));
					break;
			}
			return;
		}
	case ITYPE_CONTAINER: // bugfix for snooping not working, lb
	case ITYPE_UNLOCKED_CONTAINER:
		// Wintermute: GMs or Counselors should be able to open trapped containers always
		if (pi->moreb1 > 0 && !pc->IsGMorCounselor()) {
			magic::castAreaAttackSpell(pi->getPosition("x"), pi->getPosition("y"), magic::SPELL_EXPLOSION);
			pi->moreb1--;
		}
		//Magic->MagicTrap(currchar[s], pi); // added by AntiChrist
		// only 1 and 63 can be trapped, so pleaz leave it here :) - Anti
	case ITYPE_NODECAY_ITEM_SPAWNER: // nodecay item spawner..Ripper
	case ITYPE_DECAYING_ITEM_SPAWNER: // decaying item spawner..Ripper
		if (pi->isInWorld() || (pc->IsGMorCounselor()) || // Backpack in world - free access to everyone
			( isCharSerial(pi->getContSerial()) && pi->getContSerial()==pc->getSerial32()))	// primary pack
		{
			pc->showContainer(pi);
			pc->objectdelay=0;
			return;
		}
		else if( isItemSerial(pi->getContSerial()) )
		{
			P_ITEM pio = pi->getOutMostCont();
			if (pio->getContSerial()==pc->getSerial32() || pio->isInWorld() )
			{
				pc->showContainer(pi);
				pc->objectdelay=0;
				return;
			}
		}
		if(ISVALIDPC(itmowner))
			snooping(pc, pi );
		return;
	case ITYPE_TELEPORTRUNE:
		targ = clientInfo[s]->newTarget( new cLocationTarget() );
		targ->code_callback = target_tele;
		targ->send( ps );
		ps->sysmsg( TRANSLATE("Select teleport target."));
		return;
	case ITYPE_KEY:
		targ = clientInfo[s]->newTarget( new cItemTarget() );
		targ->code_callback = target_key;
		targ->buffer[0]= pi->more1;
		targ->buffer[1]= pi->more2;
		targ->buffer[2]= pi->more3;
		targ->buffer[3]= pi->more4;
		targ->send( ps );
		ps->sysmsg( TRANSLATE("Select item to use the key on."));
		return;
	case ITYPE_LOCKED_ITEM_SPAWNER:
	case ITYPE_LOCKED_CONTAINER:

		// Added traps effects by AntiChrist
		// Wintermute: GMs or Counselors should be able to open locked containers always
		if ( !pc->IsGMorCounselor() )
		{
			if (pi->moreb1 > 0 ) {
				magic::castAreaAttackSpell(pi->getPosition().x, pi->getPosition().y, magic::SPELL_EXPLOSION);
				pi->moreb1--;
			}

			pc->sysmsg(TRANSLATE("This item is locked."));
			return;
		}
		else
		{
			pc->showContainer(pi);
 			return;
		}
	case ITYPE_SPELLBOOK:
		if (ISVALIDPI(pack)) // morrolan
			if(pi->getContSerial()==pack->getSerial32() || pc->IsWearing(pi))
				ps->sendSpellBook(pi);
			else
				pc->sysmsg(TRANSLATE("If you wish to open a spellbook, it must be equipped or in your main backpack."));
			return;
	case ITYPE_MAP:
		LongToCharPtr(pi->getSerial32(), map1 +1);
		map2[1] = map1[1];
		map2[2] = map1[2];
		map2[3] = map1[3];
		map2[4] = map1[4];
/*
		By Polygon:
		Assign areas and map size before sending
*/
		map1[7] = pi->more1;	// Assign topleft x
		map1[8] = pi->more2;
		map1[9] = pi->more3;	// Assign topleft y
		map1[10] = pi->more4;
		map1[11] = pi->moreb1;	// Assign lowright x
		map1[12] = pi->moreb2;
		map1[13] = pi->moreb3;	// Assign lowright y
		map1[14] = pi->moreb4;
		int width, height;		// Tempoary storage for w and h;
		width = 134 + (134 * pi->morez);	// Calculate new w and h
		height = 134 + (134 * pi->morez);
		ShortToCharPtr(width, map1 +15);
		ShortToCharPtr(height, map1 +17);
//		END OF: By Polygon

		Xsend(s, map1, 19);
//AoS/		Network->FlushBuffer(s);
		Xsend(s, map2, 11);
//AoS/		Network->FlushBuffer(s);
		return;
	case ITYPE_BOOK:
		Books::DoubleClickBook(s, pi);
		return;
	case ITYPE_DOOR:
		dooruse(s, pi);
		return;
	case ITYPE_LOCKED_DOOR:
		// Wintermute: GMs or Counselors should be able to open locked doors always
		if ( pc->IsGMorCounselor())
 		{
 			dooruse(s, pi);
 			return;
 		}

		if (ISVALIDPI(pack))
		{
			NxwItemWrapper si;
			si.fillItemsInContainer( pack );
			for( si.rewind(); !si.isEmpty(); si++ )
			{
				P_ITEM pj = si.getItem();
				if (ISVALIDPI(pj) && pj->type==ITYPE_KEY)
					if (((pj->more1 == pi->more1) && (pj->more2 == pi->more2) &&
						 (pj->more3 == pi->more3) && (pj->more4 == pi->more4)) )
					{
						pc->sysmsg(TRANSLATE("You quickly unlock, use, and then relock the door."));
						dooruse(s, pi);
						return;
					}
			}
		}
		pc->sysmsg(TRANSLATE("This door is locked."));
		return;
	case ITYPE_FOOD:

		if (pc->hunger >= 6)
		{
			pc->sysmsg( TRANSLATE("You are simply too full to eat any more!"));
			return;
		}
		else
		{
			switch (RandomNum(0, 2))
			{
				case 0: pc->playSFX(0x3A); break;
				case 1: pc->playSFX(0x3B); break;
				case 2: pc->playSFX(0x3C); break;
			}

			switch (pc->hunger)
			{
				case 0:  pc->sysmsg( TRANSLATE("You eat the food, but are still extremely hungry.")); break;
				case 1:  pc->sysmsg( TRANSLATE("You eat the food, but are still extremely hungry.")); break;
				case 2:  pc->sysmsg( TRANSLATE("After eating the food, you feel much less hungry.")); break;
				case 3:  pc->sysmsg( TRANSLATE("You eat the food, and begin to feel more satiated.")); break;
				case 4:  pc->sysmsg( TRANSLATE("You feel quite full after consuming the food.")); break;
				case 5:  pc->sysmsg( TRANSLATE("You are nearly stuffed, but manage to eat the food."));	break;
				default: pc->sysmsg( TRANSLATE("You are simply too full to eat any more!")); break;
			}

			if (pi->poisoned)
			{
				pc->sysmsg(TRANSLATE("The food was poisoned!"));
				pc->applyPoison(PoisonType(pi->poisoned));

			}

			pi->ReduceAmount(1);
		    pc->hunger++;
		}
		return;
	case ITYPE_WAND: // -Fraz- Modified and tuned up, Wands must now be equipped or in pack
	case ITYPE_MANAREQ_WAND: // magic items requiring mana (xan)
		if (ISVALIDPI(pack))
		{
			if (pi->getContSerial() == pack->getSerial32() || pc->IsWearing(pi))
			{
				if (pi->morez != 0)
				{
					pi->morez--;
					if (magic::beginCasting(
						static_cast<magic::SpellId>((8*(pi->morex - 1)) + pi->morey - 1),
						ps,
						(pi->type==ITYPE_WAND) ? magic::CASTINGTYPE_ITEM : magic::CASTINGTYPE_NOMANAITEM))
						{
							if (pi->morez == 0)
							{
								pi->type = pi->type2;
								pi->morex = 0;
								pi->morey = 0;
								pi->offspell = 0;
							}
						}
				}
			}
			else
			{
				pc->sysmsg(TRANSLATE("If you wish to use this, it must be equipped or in your backpack."));
			}
		}
		return; // case 15 (magic items)
/*////////////////////REMOVE/////////////////////////////////////
	case 18: // crystal ball?
		switch (RandomNum(0, 9))
		{
		case 0: itemmessage(s, TRANSLATE("Seek out the mystic llama herder."), pi->getSerial32());									break;
		case 1: itemmessage(s, TRANSLATE("Wherever you go, there you are."), pi->getSerial32());									break;
		case 4: itemmessage(s, TRANSLATE("The message appears to be too cloudy to make anything out of it."), pi->getSerial32());	break;
		case 5: itemmessage(s, TRANSLATE("You have just lost five strength.. not!"), pi->getSerial32());							break;
		case 6: itemmessage(s, TRANSLATE("You're really playing a game you know"), pi->getSerial32());								break;
		case 7: itemmessage(s, TRANSLATE("You will be successful in all you do."), pi->getSerial32());								break;
		case 8: itemmessage(s, TRANSLATE("You are a person of culture."), pi->getSerial32());										break;
		default: itemmessage(s, TRANSLATE("Give me a break! How much good fortune do you expect!"), pi->getSerial32());				break;
		}// switch
		soundeffect2(pc_currchar, 0x01EC);
		return;// case 18 (crystal ball?)
*/////////////////////ENDREMOVE/////////////////////////////////////
	case ITYPE_POTION: // potions
			if (pi->morey != 3)
				pc->drink(pi);   //Luxor: delayed potions drinking
			else    //explosion potion
				usepotion(pc, pi);
			return;
	case ITYPE_RUNE:
			if (pi->morex==0 && pi->morey==0 && pi->morez==0)
			{
				pc->sysmsg( TRANSLATE("That rune is not yet marked!"));
			}
			else
			{
				pc->runeserial = pi->getSerial32();
				pc->sysmsg( TRANSLATE("Enter new rune name."));
			}
			return;
	case ITYPE_SMOKE:
			pc->smoketimer = pi->morex*MY_CLOCKS_PER_SEC + getclock();
			pi->ReduceAmount(1);
			return;
	case ITYPE_RENAME_DEED:
			pc->namedeedserial = pi->getSerial32();
			pc->sysmsg( TRANSLATE("Enter your new name."));
			pi->ReduceAmount(1);
			return;
	case ITYPE_POLYMORPH:
			pc->setId( pi->morex );
			pc->teleport();
			pi->type = ITYPE_POLYMORPH_BACK;
			return;
	case ITYPE_POLYMORPH_BACK:
			pc->setId( pc->getOldId() );
			pc->teleport();
			pi->type = ITYPE_POLYMORPH;
			return;
	case ITYPE_ARMY_ENLIST:
			enlist(s, pi->morex);
			pi->Delete();
			return;
	case ITYPE_TELEPORT:
			pc->MoveTo( pi->morex,pi->morey,pi->morez );
			pc->teleport();
			return;
	case ITYPE_DRINK:
			switch (rand()%2)
			{
				case 0: pc->playSFX(0x0031); break;
				case 1: pc->playSFX(0x0030); break;
			}
			pi->ReduceAmount(1);
			pc->sysmsg( TRANSLATE("Gulp !"));
			return;
	case ITYPE_GUILDSTONE:
			if ( pi->getId() == 0x14F0  ||  pi->getId() == 0x1869 )	// Check for Deed/Teleporter + Guild Type
			{
				pc->fx1 = DEREF_P_ITEM(pi);
				Guilds->StonePlacement(s);
				return;
			}
			else if (pi->getId() == 0x0ED5)	// Check for Guildstone + Guild Type
			{
				pc->fx1 = DEREF_P_ITEM(pi);
				Guilds->Menu(s, 1);
				return;
			}
			else
				WarnOut("Unhandled guild item type named: %s with ID of: %X\n", pi->getCurrentNameC(), pi->getId());
			return;
	case ITYPE_PLAYER_VENDOR_DEED:			// PlayerVendors deed
			{
			P_CHAR vendor = npcs::AddNPCxyz(-1, 2117, charpos.x, charpos.y, charpos.z);
			if ( !ISVALIDPC(vendor) )
			{
				WarnOut("npc-script couldnt find vendor !\n");
				return;
			}

			los = 0;
			vendor->npcaitype = NPCAI_PLAYERVENDOR;
			vendor->MakeInvulnerable();
			vendor->unHide();
			vendor->stealth=INVALID;
			vendor->dir = pc->dir;
			vendor->npcWander = WANDER_NOMOVE;
			vendor->SetInnocent();
			vendor->setOwnerSerial32( pc->getSerial32() );
			vendor->tamed = false;
			pi->Delete();
			vendor->teleport();
			char temp[TEMP_STR_SIZE]; //xan -> this overrides the global temp var
			sprintf( temp, TRANSLATE("Hello sir! My name is %s and i will be working for you."), vendor->getCurrentNameC());
			vendor->talk(s, temp, 0);

			return;
			}
	case ITYPE_TREASURE_MAP:
			Skills::Decipher(pi, s);
			return;

	case ITYPE_DECIPHERED_MAP:
			map1[ 1] = map2[1] = map3[1] = pi->getSerial().ser1;
			map1[ 2] = map2[2] = map3[2] = pi->getSerial().ser2;
			map1[ 3] = map2[3] = map3[3] = pi->getSerial().ser3;
			map1[ 4] = map2[4] = map3[4] = pi->getSerial().ser4;
			map1[ 7] = pi->more1;	// Assign topleft x
			map1[ 8] = pi->more2;
			map1[ 9] = pi->more3;	// Assign topleft y
			map1[10] = pi->more4;
			map1[11] = pi->moreb1;	// Assign lowright x
			map1[12] = pi->moreb2;
			map1[13] = pi->moreb3;	// Assign lowright y
			map1[14] = pi->moreb4;
			ShortToCharPtr(0x0100, map1 +15);			// Let width and height be 256
			ShortToCharPtr(0x0100, map1 +17);
			Xsend(s, map1, 19);
//AoS/			Network->FlushBuffer(s);

			Xsend(s, map2, 11);
//AoS/			Network->FlushBuffer(s);

			// Generate message to add a map point
			SI16 posx, posy;					// tempoary storage for map point
			SI16 tlx, tly, lrx, lry;				// tempoary storage for map extends
			tlx = (pi->more1 << 8) | pi->more2;
			tly = (pi->more3 << 8) | pi->more4;
			lrx = (pi->moreb1 << 8) | pi->moreb2;
			lry = (pi->moreb3 << 8) | pi->moreb4;
			posx = (256 * (pi->morex - tlx)) / (lrx - tlx);		// Generate location for point
			posy = (256 * (pi->morey - tly)) / (lry - tly);
			ShortToCharPtr(posx, map3 +7);				// Store the point position
			ShortToCharPtr(posy, map3 +9);
			Xsend(s, map3, 11);					// Fire data to client :D
//AoS/			Network->FlushBuffer(s);
			return;
		default:
			break;
	}
	///END IDENTIFICATION BY TYPE

/////////////////READ UP :D////////////////////////////////

	///BEGIN IDENTIFICATION BY ID
	if (pi->IsSpellScroll())
	{
		if (ISVALIDPI(pack))
			if( pi->getContSerial()==pack->getSerial32()) {
				magic::SpellId spn = magic::spellNumberFromScrollId(pi->getId());	// avoid reactive armor glitch
				if ((spn>=0)&&(magic::beginCasting(spn, ps, magic::CASTINGTYPE_SCROLL)))
					pi->ReduceAmount(1);							// remove scroll if successful
			}
			else pc->sysmsg(TRANSLATE("The scroll must be in your backpack to envoke its magic."));
	}
	CASE(IsAnvil) {
		targ = clientInfo[s]->newTarget( new cItemTarget() );
		targ->code_callback=Skills::target_repair;
		targ->send( ps );
		ps->sysmsg( TRANSLATE("Select item to be repaired."));
	}
	CASE(IsAxe) {
		targ = clientInfo[s]->newTarget( new cTarget() );
		targ->code_callback=target_axe;
		targ->buffer[0]=pi->getSerial32();
		targ->send( ps );
		ps->sysmsg( TRANSLATE("What would you like to use that on ?"));
	}
	CASEOR(IsFeather, IsShaft) {
		targ = clientInfo[s]->newTarget( new cItemTarget() );
		targ->buffer[0]= pi->getSerial32();
		targ->code_callback=Skills::target_fletching;
		targ->send( ps );
		ps->sysmsg( TRANSLATE("What would you like to use this with?"));
	}