Example #1
0
bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {

	if (GetAccountID() == 0) {
		clog(WORLD__CLIENT_ERR,"Enter world with no logged in account");
		eqs->Close();
		return true;
	}

	if(GetAdmin() < 0)
	{
		clog(WORLD__CLIENT,"Account banned or suspended.");
		eqs->Close();
		return true;
	}

	if (RuleI(World, MaxClientsPerIP) >= 0) {
		client_list.GetCLEIP(this->GetIP()); //Check current CLE Entry IPs against incoming connection
	}

	EnterWorld_Struct *ew=(EnterWorld_Struct *)app->pBuffer;
	strn0cpy(char_name, ew->name, 64);

	EQApplicationPacket *outapp;
	uint32 tmpaccid = 0;
	charid = database.GetCharacterInfo(char_name, &tmpaccid, &zoneID, &instanceID);
	if (charid == 0 || tmpaccid != GetAccountID()) {
		clog(WORLD__CLIENT_ERR,"Could not get CharInfo for '%s'",char_name);
		eqs->Close();
		return true;
	}

	// Make sure this account owns this character
	if (tmpaccid != GetAccountID()) {
		clog(WORLD__CLIENT_ERR,"This account does not own the character named '%s'",char_name);
		eqs->Close();
		return true;
	}

	if(!pZoning && ew->return_home && !ew->tutorial)
	{
		CharacterSelect_Struct* cs = new CharacterSelect_Struct;
		memset(cs, 0, sizeof(CharacterSelect_Struct));
		database.GetCharSelectInfo(GetAccountID(), cs);
		bool home_enabled = false;

		for(int x = 0; x < 10; ++x)
		{
			if(strcasecmp(cs->name[x], char_name) == 0)
			{
				if(cs->gohome[x] == 1)
				{
					home_enabled = true;
					break;
				}
			}
		}
		safe_delete(cs);

		if(home_enabled)
		{
			zoneID = database.MoveCharacterToBind(charid,4);
		}
		else
		{
			clog(WORLD__CLIENT_ERR,"'%s' is trying to go home before they're able...",char_name);
			database.SetHackerFlag(GetAccountName(), char_name, "MQGoHome: player tried to go home before they were able.");
			eqs->Close();
			return true;
		}
	}

	if(!pZoning && (RuleB(World, EnableTutorialButton) && (ew->tutorial || StartInTutorial))) {
		CharacterSelect_Struct* cs = new CharacterSelect_Struct;
		memset(cs, 0, sizeof(CharacterSelect_Struct));
		database.GetCharSelectInfo(GetAccountID(), cs);
		bool tutorial_enabled = false;

		for(int x = 0; x < 10; ++x)
		{
			if(strcasecmp(cs->name[x], char_name) == 0)
			{
				if(cs->tutorial[x] == 1)
				{
					tutorial_enabled = true;
					break;
				}
			}
		}
		safe_delete(cs);

		if(tutorial_enabled)
		{
			zoneID = RuleI(World, TutorialZoneID);
			database.MoveCharacterToZone(charid, database.GetZoneName(zoneID));
		}
		else
		{
			clog(WORLD__CLIENT_ERR,"'%s' is trying to go to tutorial but are not allowed...",char_name);
			database.SetHackerFlag(GetAccountName(), char_name, "MQTutorial: player tried to enter the tutorial without having tutorial enabled for this character.");
			eqs->Close();
			return true;
		}
	}

	if (zoneID == 0 || !database.GetZoneName(zoneID)) {
		// This is to save people in an invalid zone, once it's removed from the DB
		database.MoveCharacterToZone(charid, "arena");
		clog(WORLD__CLIENT_ERR, "Zone not found in database zone_id=%i, moveing char to arena character:%s", zoneID, char_name);
	}

	if(instanceID > 0)
	{
		if(!database.VerifyInstanceAlive(instanceID, GetCharID()))
		{
			zoneID = database.MoveCharacterToBind(charid);
			instanceID = 0;
		}
		else
		{
			if(!database.VerifyZoneInstance(zoneID, instanceID))
			{
				zoneID = database.MoveCharacterToBind(charid);
				instanceID = 0;
			}
		}
	}

	if(!pZoning) {
		database.SetGroupID(char_name, 0, charid);
		database.SetFirstLogon(charid, 1);

		if (RuleB(World, AnnounceJoinQuits) == true) //this is having an issue, its not taking a true false swap, only takes default.
		{
			zoneserver_list.SendEmoteMessage(0, 0, 0, 15, "%s is logging on!", GetCharName());
			clog(WORLD__CLIENT_ERR, "Character is logging on: %s", GetCharName());
		}
	}
	else{
		uint32 groupid=database.GetGroupID(char_name);
		if(groupid>0){
			char* leader=0;
			char leaderbuf[64]={0};
			if((leader=database.GetGroupLeaderForLogin(char_name,leaderbuf)) && strlen(leader)>1){
				EQApplicationPacket* outapp3 = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
				GroupJoin_Struct* gj=(GroupJoin_Struct*)outapp3->pBuffer;
				gj->action=8;
				strcpy(gj->yourname,char_name);
				strcpy(gj->membername,leader);
				QueuePacket(outapp3);
				safe_delete(outapp3);
			}
		}
	}

	outapp = new EQApplicationPacket(OP_MOTD);
	char tmp[500] = {0};
	if (database.GetVariable("MOTD", tmp, 500)) {
		outapp->size = strlen(tmp)+1;
		outapp->pBuffer = new uchar[outapp->size];
		memset(outapp->pBuffer,0,outapp->size);
		strcpy((char*)outapp->pBuffer, tmp);

	} else {
		// Null Message of the Day. :)
		outapp->size = 1;
		outapp->pBuffer = new uchar[outapp->size];
		outapp->pBuffer[0] = 0;
	}
	QueuePacket(outapp);
	safe_delete(outapp);

	int MailKey = MakeRandomInt(1, INT_MAX);

	database.SetMailKey(charid, GetIP(), MailKey);

	char ConnectionType;

	ConnectionType = 'C';

	EQApplicationPacket *outapp2 = new EQApplicationPacket(OP_SetChatServer);
	char buffer[112];

	const WorldConfig *Config = WorldConfig::get();

	sprintf(buffer,"%s,%i,%s.%s,%c%08X",
		Config->ChatHost.c_str(),
		Config->ChatPort,
		Config->ShortName.c_str(),
		this->GetCharName(), ConnectionType, MailKey
	);
	outapp2->size=strlen(buffer)+1;
	outapp2->pBuffer = new uchar[outapp2->size];
	memcpy(outapp2->pBuffer,buffer,outapp2->size);
	QueuePacket(outapp2);
	safe_delete(outapp2);

	EnterWorld();

	return true;
}
Example #2
0
/* Takes care of incoming packets */
void HandleMessage(aocConnection *aoc, aocMessage *msg)
{
	char *charname, *pgrp_name, *grp_name;
	unsigned char *text, *blob;
	int text_len, blob_len;
	uint32_t uid, pgrp_uid;
	unsigned char *group_id;
	


	switch(msg->type)
	{
	/*
		This is the first packet you receive after establishing a connection
		to the chat server. The message contains a 32 byte human readable hex
		string, which you should pass to the aocKeyexGenerateKey() function to
		generate a login key, and then reply with aocSendLoginResponse().

		Packet contents:
			msg->argv[0] = (String) LoginSeed
	*/
	case AOC_SRV_LOGIN_SEED:
		{
			char *key;

			/* Generate a valid login key. */
			key = aocKeyexGenerateKey(AOC_STR(msg->argv[0]), conf_username, conf_username);
			if(key == NULL)
			{
				printf("Could not generate login key.\n");
				running = 0;
				break;
			}

			/* Send authenticate packet */
			aocSendLoginResponse(aoc, 0, conf_username, key);

			aocFree(key);
		}
		break;


	/*
		This packet is received is your username or password is incorrect.
		It contains a human readable error string. The server will disconnect
		you after sending this message.

		Packet contents:
			msg->argv[0] = (String) ErrorMessage
	*/
	case AOC_SRV_LOGIN_ERROR:
		printf("Server said: %s\n", AOC_STR(msg->argv[0]));
		running = 0;
		break;


	/*
		This packet is received after you have successfully authenticated
		yourself with aocSendLoginResponse(). The packet contains a list
		of all characters on the account. You should reply with
		aocSendLoginSelectChar().

		Packet contents: (4 arrays)
			msg->argv[...] = (Integer) UserID
			msg->argv[...] = (String)  Charname
			msg->argv[...] = (Integer) Level
			msg->argv[...] = (Integer) Online Status (0 or 1)

			All 4 arrays have the same size in this packet.
			(Though you should probably handle cases where they
			 have different sizes... as the following code does)
	*/
	case AOC_SRV_LOGIN_CHARLIST:
		{
			int nchars, i;

			/* The number of characters (taken from the length of the first array) */
			nchars = aocMsgArraySize(msg, 0);

			/* Decode the packet. */
			for(i=0; i<nchars; i++)
			{
				void *user_id, *charname, *level, *status;

				/* Get values from all 4 arrays */
				user_id		= aocMsgArrayValue(msg, 0, i, NULL, NULL);
				charname	= aocMsgArrayValue(msg, 1, i, NULL, NULL);
				level		= aocMsgArrayValue(msg, 2, i, NULL, NULL);
				status		= aocMsgArrayValue(msg, 3, i, NULL, NULL);

				if(charname == NULL)
					continue;

				/* Compare char name with conf_charname */
				if(strcmp(AOC_STR(charname), aocNameLowerCase(conf_charname)) != 0)
					continue;

				printf("Logging in as %s... (UserID %d, Level %d, Status %d)\n",
					AOC_STR(charname),
					user_id	? AOC_INT(user_id)	: (int)AOC_INVALID_UID,
					level	? AOC_INT(level)		: 0,
					status	? AOC_INT(status)	: 0);

				aocSendLoginSelectChar(aoc, AOC_INT(user_id));
				my_user_id = AOC_INT(user_id);
				break;
			}

			if(my_user_id == AOC_INVALID_UID)
			{
				printf("No character named '%s' was found.\n", ao_char);
				running = 0;
			}
		}
		break;


	/*
		This packet is received after you have selected a character.

		Packet contents: None
	*/
	case AOC_SRV_LOGIN_OK:
		printf("Logged in!\n");
		break;


	case AOC_SRV_CLIENT_UNKNOWN:
		uid = AOC_INT(msg->argv[0]);

		printf("UserID %d does not exist.\n", uid);
		break;


	case AOC_SRV_CLIENT_NAME:
		uid			= AOC_INT(msg->argv[0]);
		charname	= AOC_STR(msg->argv[1]);

		aocNameListInsert(namelist, uid, charname, NULL);
		break;


	case AOC_SRV_LOOKUP_RESULT:
		uid = AOC_INT(msg->argv[0]);
		charname = AOC_STR(msg->argv[1]);

		if(uid == AOC_INVALID_UID)
		{
			printf("Character '%s' does not exist.\n", charname);
			break;
		}

		/* Add the charname / user id to the name list */
		aocNameListInsert(namelist, uid, charname, NULL);
		break;


	case AOC_SRV_PRIVATE_MSG:
		uid			= AOC_INT(msg->argv[0]);
		charname	= GetCharName(uid);
		text		= AOC_STR(msg->argv[1]);
		text_len	= msg->argl[1];
		blob		= AOC_STR(msg->argv[2]);
		blob_len	= msg->argl[2];

		/* Remove color styles, etc.. */
		aocStripStyles(text, text_len, 0);

		/* Remove unprintable characters */
		for(i=0; i<text_len; i++)
			if(text[i] < 32) text[i] = '.';

		printf("[%s]: %s\n", charname, text);
		break;


	/*
		To receive this packet you must be in-game, hence you will
		never receive it with libaochat.

		Packet contents:
			msg->argv[0] = (Integer) UserID
			msg->argv[1] = (String) Text
			msg->argv[2] = (String) Blob
	*/
	case AOC_SRV_VICINITY_MSG:
		break;


	/*
		This is usually used for broadcast messages, such as information about
		upcoming downtimes, when people "ding" 220, etc...

		Packet contents:
			msg->argv[0] = (String) Sender
			msg->argv[1] = (String) Text
			msg->argv[2] = (String) Blob
	*/
	case AOC_SRV_ANONVICINITY_MSG:
		break;


	/*
		System message.

		Packet contents:
			msg->argv[0] = (String) Message
	*/
	case AOC_SRV_SYSTEM_MSG:
		printf("System message: %s\n", AOC_STR(msg->argv[0]));
		break;


	/*
		This packet contains information about buddy status and type.
		You will receive it when you log on, when one of your buddies change
		status, and when you add/change a buddy with aocSendBuddyAdd().
		It is sent once per buddy. :)

		Packet contents:
			msg->argv[0] = (Integer) UserID
			msg->argv[1] = (Integer) Status (0 = Offline, 1 = Online)
			msg->argv[2] = (String) Buddy type ('\0' = Temp, '\1' = Perm)
							(AOC_BUDDY_TEMPORARY, AOC_BUDDY_PERMANENT)
	*/
	case AOC_SRV_BUDDY_STATUS:
		printf("%s buddy %s changed his/her status to %s.\n",
				AOC_STR(msg->argv[2])[0] ? "Permanent" : "Temporary",
				GetCharName(uid),
				AOC_INT(msg->argv[1]) ? "online" : "offline" );
		break;


	/*
		This packet is sent in reply to buddy remove packets.

		Packet contents:
			msg->argv[0] = (Integer) UserID
	*/
	case AOC_SRV_BUDDY_REMOVED:
		uid = AOC_INT(msg->argv[0]);

		printf("%s was removed from your buddy list.\n", GetCharName(uid));
		break;


	/*
		This packet is sent when you receive an invite to someone's
		private group.

		Packet contents:
			msg->argv[0] = (Integer) UserID (aka PrivateGroupID)
	*/
	case AOC_SRV_PRIVGRP_INVITE:
		break;


	/*
		This packet is sent when you have been kicked from someone's
		private group.

		Packet contents:
			msg->argv[0] = (Integer) UserID (aka PrivateGroupID)
	*/
	case AOC_SRV_PRIVGRP_KICK:
		break;


	/*
		This packet is sent when you have left someone's private group.
		Note however that there is no way to actually part a group.
		I guess funcom's programmers have a weird sense of humor...

		Packet contents:
			msg->argv[0] = (Integer) UserID (aka PrivateGroupID)
	*/
	case AOC_SRV_PRIVGRP_PART:
		break;


	/*
		This packet is sent when someone joins a private group that you
		are currently in.

		Packet contents:
			msg->argv[0] = (Integer) UserID (aka PrivateGroupID)
			msg->argv[1] = (Integer) UserID
	*/
	case AOC_SRV_PRIVGRP_CLIJOIN:
		break;


	/*
		This packet is sent when someone leaves a private group that you
		are currently in. (ie. was kicked by the private group owner)

		Packet contents:
			msg->argv[0] = (Integer) UserID (aka PrivateGroupID)
			msg->argv[1] = (Integer) UserID
	*/
	case AOC_SRV_PRIVGRP_CLIPART:
		break;


	/*
		Private group message.

		Packet contents:
			msg->argv[0] = (Integer) UserID (aka PrivateGroupID)
			msg->argv[1] = (Integer) UserID
			msg->argv[2] = (String) Text
			msg->argv[3] = (String) Blob
	*/
	case AOC_SRV_PRIVGRP_MSG:
		break;


	case AOC_SRV_GROUP_INFO:
		break;


	case AOC_SRV_GROUP_PART:
		break;


	case AOC_SRV_GROUP_MSG:
		break;


	/*
		This packet is sent in reply to pings.

		Packet contents:
			msg->argv[0] = (String) UserData
	*/
	case AOC_SRV_PONG:
		printf("Pong!\n");
		break;


	/*
		This packet is sent to you if someone types "/cc info yourcharname" in game.

		Packet contents:
			msg->argv[0] = (Raw) Binary Data
	*/
	case AOC_SRV_FORWARD:
		break;


	/*
		Unknown.
	*/
	case AOC_SRV_AMD_MUX_INFO:
		break;

	}

	return;
}