Beispiel #1
0
int RespondPrefGet(PreferenceContainer *prefSet, char *SendBuf,
		SimulatorQuery *query) {
	//Helper function for the "pref.getA" and "pref.get" queries.
	//Since the both accounts and characters use the same class to store
	//preferences, the query handlers will call this function with the
	//appropriate pointer.

	int WritePos = 0;
	WritePos += PutByte(&SendBuf[WritePos], 1);          //_handleQueryResultMsg
	WritePos += PutShort(&SendBuf[WritePos], 0);           //Message size
	WritePos += PutInteger(&SendBuf[WritePos], query->ID); //Query response index

	//Each preference request will have a matching response field.
	WritePos += PutShort(&SendBuf[WritePos], query->argCount);

	for (unsigned int i = 0; i < query->argCount; i++) {
		const char * pref = prefSet->GetPrefValue(query->args[i].c_str());

		//One string for each preference result.
		WritePos += PutByte(&SendBuf[WritePos], 1);
		if (pref != NULL) {
			WritePos += PutStringUTF(&SendBuf[WritePos], pref);
		} else {
			WritePos += PutStringUTF(&SendBuf[WritePos], "");
		}
	}

	PutShort(&SendBuf[1], WritePos - 3);

	return WritePos;
}
Beispiel #2
0
int PartyManager :: WriteLootRoll(char *outbuf, const char *itemDefName, char roll, const char *bidder)
{
	int wpos = 0;
	wpos += PutByte(&outbuf[wpos], 6);     //_handlePartyUpdateMsg
	wpos += PutShort(&outbuf[wpos], 0);

	wpos += PutByte(&outbuf[wpos], PartyUpdateOpTypes::LOOT_ROLL);
	wpos += PutStringUTF(&outbuf[wpos], itemDefName);
	wpos += PutByte(&outbuf[wpos], roll);
	wpos += PutStringUTF(&outbuf[wpos], bidder);
	PutShort(&outbuf[1], wpos - 3);       //Set message size
	return wpos;
}
Beispiel #3
0
int PrepExt_QueryResponseString2(char *buffer, int queryIndex, const char *strData1, const char *strData2)
{
	int wpos = 0;
	wpos += PutByte(&buffer[wpos], 1);              //_handleQueryResultMsg
	wpos += PutShort(&buffer[wpos], 0);             //Placeholder for message size
	wpos += PutInteger(&buffer[wpos], queryIndex);  //Query response index
	wpos += PutShort(&buffer[wpos], 1);             //Row count
	wpos += PutByte(&buffer[wpos], 2);              //String count
	wpos += PutStringUTF(&buffer[wpos], strData1);   //String data
	wpos += PutStringUTF(&buffer[wpos], strData2);   //String data
	PutShort(&buffer[1], wpos - 3);                 //Message size
	return wpos;
}
Beispiel #4
0
int PrepExt_CreatureEventPortalRequest(char *buffer, int actorID, const char *casterName, const char *locationName)
{
	int wpos = 0;
	wpos += PutByte(&buffer[wpos], 4);  //_handleCreatureEventMsg
	wpos += PutShort(&buffer[wpos], 0);

	wpos += PutInteger(&buffer[wpos], actorID);
	wpos += PutByte(&buffer[wpos], 24);             //event to request a portal

	wpos += PutStringUTF(&buffer[wpos], casterName);
	wpos += PutStringUTF(&buffer[wpos], locationName);

	PutShort(&buffer[1], wpos - 3);       //Set message size
	return wpos;
}
Beispiel #5
0
int PartyManager :: WriteLootWin(char *outbuf, const char *lootTag, const char *originalTag, const char *winner, int creatureId, int slotIndex)
{
	int wpos = 0;
	wpos += PutByte(&outbuf[wpos], 6);     //_handlePartyUpdateMsg
	wpos += PutShort(&outbuf[wpos], 0);

	wpos += PutByte(&outbuf[wpos], PartyUpdateOpTypes::LOOT_WIN);
	wpos += PutStringUTF(&outbuf[wpos], lootTag);
	wpos += PutStringUTF(&outbuf[wpos], originalTag);
	wpos += PutStringUTF(&outbuf[wpos], winner);
	char buf[34];
	Util::SafeFormat(buf, sizeof(buf), "%d:%d", creatureId, slotIndex);
	wpos += PutStringUTF(&outbuf[wpos], buf);
	PutShort(&outbuf[1], wpos - 3);       //Set message size
	return wpos;
}
Beispiel #6
0
int PrepExt_QueryResponseMultiString(char *buffer, int queryIndex, const MULTISTRING &strData)
{
	int wpos = 0;
	wpos += PutByte(&buffer[wpos], 1);              //_handleQueryResultMsg
	wpos += PutShort(&buffer[wpos], 0);             //Placeholder for message size
	wpos += PutInteger(&buffer[wpos], queryIndex);  //Query response index

	size_t rowCount = strData.size();
	size_t stringCount;
	wpos += PutShort(&buffer[wpos], rowCount);
	for(size_t rows = 0; rows < rowCount; rows++)
	{
		stringCount = strData[rows].size();
		if(stringCount > 255)
		{
			g_Logs.server->warn("PrepExt_QueryResponseMultiString too many strings: %v", stringCount);
			stringCount = 255;
		}
		wpos += PutByte(&buffer[wpos], stringCount);
		for(size_t str = 0; str < stringCount; str++)
		{
			//g_Log.AddMessageFormat("[DEBUG] [%d][%d]=%s", rows, str, strData[rows][str].c_str());
			wpos += PutStringUTF(&buffer[wpos], strData[rows][str].c_str());   //String data
		}
	}
	PutShort(&buffer[1], wpos - 3);
	return wpos;
}
Beispiel #7
0
int PartyManager :: WriteMemberList(char *outbuf, ActiveParty *party, int memberID)
{
	//memberID is the creature ID that is requesting the list.
	//The client needs this to determine if it's leading the party.
	int wpos = 0;
	wpos += PutByte(&outbuf[wpos], 6);     //_handlePartyUpdateMsg
	wpos += PutShort(&outbuf[wpos], 0);

	wpos += PutByte(&outbuf[wpos], PartyUpdateOpTypes::JOINED_PARTY);

	//wpos += PutByte(&outbuf[wpos], party->mMemberList.size());
	int countLoc = wpos;
	wpos += PutByte(&outbuf[wpos], 0);
	wpos += PutInteger(&outbuf[wpos], party->mLeaderID);
	wpos += PutInteger(&outbuf[wpos], memberID);  //memberId

	int count = 0;
	for(size_t i = 0; i < party->mMemberList.size(); i++)
	{
		if(party->mMemberList[i].mCreatureID != memberID)
		{
			wpos += PutInteger(&outbuf[wpos], party->mMemberList[i].mCreatureID);
			wpos += PutStringUTF(&outbuf[wpos], party->mMemberList[i].mDisplayName.c_str());
			count++;
		}
	}
	PutByte(&outbuf[countLoc], count);
	PutShort(&outbuf[1], wpos - 3);       //Set message size
	return wpos;
}
Beispiel #8
0
int PartyManager :: WriteProposeInvite(char *outbuf, int proposeeId, const char *proposeeName, int proposerId, const char *proposerName)
{
	int wpos = 0;
	wpos += PutByte(&outbuf[wpos], 6);     //_handlePartyUpdateMsg
	wpos += PutShort(&outbuf[wpos], 0);

	wpos += PutByte(&outbuf[wpos], PartyUpdateOpTypes::PROPOSE_INVITE);
	
	wpos += PutInteger(&outbuf[wpos], proposeeId);
	wpos += PutStringUTF(&outbuf[wpos], proposeeName);

	wpos += PutInteger(&outbuf[wpos], proposerId);
	wpos += PutStringUTF(&outbuf[wpos], proposerName);

	PutShort(&outbuf[1], wpos - 3);       //Set message size
	return wpos;
}
Beispiel #9
0
int PrepExt_SendTimeOfDayMsg(char *buffer, const char *envType)
{
	int wpos = 0;
	wpos += PutByte(&buffer[wpos], 42);   //_handleEnvironmentUpdateMsg
	wpos += PutShort(&buffer[wpos], 0);

	wpos += PutByte(&buffer[wpos], 2);   //Mask: Time of day update event

	wpos += PutStringUTF(&buffer[wpos], "");    //zoneIDString
	wpos += PutInteger(&buffer[wpos], 0);      //zoneDefID
	wpos += PutShort(&buffer[wpos], 0);  //zonePageSize
	wpos += PutStringUTF(&buffer[wpos], "");   //Terrain
	wpos += PutStringUTF(&buffer[wpos], envType);   //envtype
	wpos += PutStringUTF(&buffer[wpos], "");   //mapName

	PutShort(&buffer[1], wpos - 3);       //Set message size
	return wpos;
}
Beispiel #10
0
int PartyManager :: WriteRejectInvite(char *outbuf, const char *memberDenied)
{
	int wpos = 0;
	wpos += PutByte(&outbuf[wpos], 6);     //_handlePartyUpdateMsg
	wpos += PutShort(&outbuf[wpos], 0);
	wpos += PutByte(&outbuf[wpos], PartyUpdateOpTypes::INVITE_REJECTED);
	wpos += PutStringUTF(&outbuf[wpos], memberDenied);
	PutShort(&outbuf[1], wpos - 3);       //Set message size
	return wpos;
}
Beispiel #11
0
int PrepExt_GenericChatMessage(char *buffer, int creatureID, const char *name, const char *channel, const char *message)
{
	//Handles a "communicate" (0x04) message containing a channel and string
	//Sends back a "_handleCommunicationMsg" (50 = 0x32) to the client
	//Ideally this function should broadcast the message to all active player threads
	//in the future so that all players can receive the communication message.

	int wpos = 0;
	wpos += PutByte(&buffer[wpos], 0x32);       //_handleCommunicationMsg
	wpos += PutShort(&buffer[wpos], 0);         //Placeholder for size

	wpos += PutInteger(&buffer[wpos], creatureID);    //Character ID who's sending the message
	wpos += PutStringUTF(&buffer[wpos], name);     //Character name
	wpos += PutStringUTF(&buffer[wpos], channel);  //channel type
	wpos += PutStringUTF(&buffer[wpos], message);  //message body

	PutShort(&buffer[1], wpos - 3);     //Set size
	return wpos;
}
Beispiel #12
0
int PrepExt_QueryResponseError(char *buffer, int queryIndex, const char *message)
{
	int wpos = 0;
	wpos += PutByte(&buffer[wpos], 1);              //_handleQueryResultMsg
	wpos += PutShort(&buffer[wpos], 0);             //Placeholder for message size
	wpos += PutInteger(&buffer[wpos], queryIndex);  //Query response index
	wpos += PutShort(&buffer[wpos], 0x7000);        //Negative number indicates error
	wpos += PutStringUTF(&buffer[wpos], message);   //String data
	PutShort(&buffer[1], wpos - 3);                 //Message size
	return wpos;
}
Beispiel #13
0
int PartyManager :: WriteInCharge(char *outbuf, ActiveParty *party)
{
	int wpos = 0;
	wpos += PutByte(&outbuf[wpos], 6);     //_handlePartyUpdateMsg
	wpos += PutShort(&outbuf[wpos], 0);
	wpos += PutByte(&outbuf[wpos], PartyUpdateOpTypes::IN_CHARGE);
	wpos += PutInteger(&outbuf[wpos], party->mLeaderID);
	wpos += PutStringUTF(&outbuf[wpos], party->mLeaderName.c_str());
	PutShort(&outbuf[1], wpos - 3);       //Set message size
	return wpos;
}
Beispiel #14
0
int PrepExt_SetTimeOfDay(char *buffer, char *envType)
{
	int wpos = 0;

	wpos += PutByte(&buffer[wpos], 42);   //_handleEnvironmentUpdateMsg
	wpos += PutShort(&buffer[wpos], 0);

	wpos += PutByte(&buffer[wpos], 2);   //Mask for time of day update

	wpos += PutStringUTF(&buffer[wpos], "");    //zoneID
	wpos += PutInteger(&buffer[wpos], 0);   //zoneDefID
	wpos += PutShort(&buffer[wpos], 0);  //zonePageSize
	wpos += PutStringUTF(&buffer[wpos], "");   //Terrain
	wpos += PutStringUTF(&buffer[wpos], envType);   //envtype
	//When the mask is 2, the function changes the time of day using the EnvironmentType string
	//the function returns from that point and never gets to the rest of the map stuff.

	PutShort(&buffer[1], wpos - 3);       //Set message size
	return wpos;
}
Beispiel #15
0
int PartyManager :: WriteQuestInvite(char *outbuf, const char* questName, int questID)
{
	int wpos = 0;
	wpos += PutByte(&outbuf[wpos], 6);     //_handlePartyUpdateMsg
	wpos += PutShort(&outbuf[wpos], 0);
	wpos += PutByte(&outbuf[wpos], PartyUpdateOpTypes::QUEST_INVITE);
	wpos += PutStringUTF(&outbuf[wpos], questName);
	wpos += PutInteger(&outbuf[wpos], questID);
	PutShort(&outbuf[1], wpos - 3);       //Set message size
	return wpos;
}
Beispiel #16
0
int PrepExt_SendInfoMessage(char *buffer, const char *message, unsigned char eventID)
{
	int wpos = 0;
	wpos += PutByte(&buffer[wpos], 0);       //_handleInfoMsg
	wpos += PutShort(&buffer[wpos], 0);      //Placeholder for size

	wpos += PutStringUTF(&buffer[wpos], message);
	wpos += PutByte(&buffer[wpos], eventID);       //Event type for error message

	PutShort(&buffer[1], wpos - 3);     //Set size
	return wpos;
}
Beispiel #17
0
int PrepExt_CancelUseEvent(char *buffer, int CreatureID)
{
	int wpos = 0;
	wpos += PutByte(&buffer[wpos], 4);  //_handleCreatureEventMsg
	wpos += PutShort(&buffer[wpos], 0);  //size
	wpos += PutInteger(&buffer[wpos], CreatureID);
	wpos += PutByte(&buffer[wpos], 11);  //creature "used" event
	wpos += PutStringUTF(&buffer[wpos], "");
	wpos += PutFloat(&buffer[wpos], -1.0F);  //A delay of -1 will interrupt the action
	PutShort(&buffer[1], wpos - 3);  //size
	return wpos;
}
Beispiel #18
0
int PrepExt_Broadcast(char *buffer, const char *message)
{
	int wpos = 0;
	wpos += PutByte(&buffer[wpos], 0);       //_handleInfoMsg
	wpos += PutShort(&buffer[wpos], 0);      //Placeholder for size

	wpos += PutStringUTF(&buffer[wpos], message);
	wpos += PutByte(&buffer[wpos], 14);       //Event type for broadcast

	PutShort(&buffer[1], wpos - 3);     //Set size
	return wpos;
}
Beispiel #19
0
int PrepExt_SendFallDamage(char *buffer, int damage)
{
	int wpos = 0;
	wpos += PutByte(&buffer[wpos], 0);       //_handleInfoMsg
	wpos += PutShort(&buffer[wpos], 0);      //Placeholder for size

	wpos += PutStringUTF(&buffer[wpos], "");  //Unused?
	wpos += PutByte(&buffer[wpos], 11);       //Event type for fall damage message
	wpos += PutInteger(&buffer[wpos], damage);

	PutShort(&buffer[1], wpos - 3);     //Set size
	return wpos;
}
Beispiel #20
0
int PartyManager :: OfferLoot(char *outbuf, int itemDefID, const char *lootTag, bool needed)
{
	int wpos = 0;
	wpos += PutByte(&outbuf[wpos], 6);     //_handlePartyUpdateMsg
	wpos += PutShort(&outbuf[wpos], 0);

	wpos += PutByte(&outbuf[wpos], PartyUpdateOpTypes::OFFER_LOOT);
	wpos += PutStringUTF(&outbuf[wpos], lootTag);
	wpos += PutInteger(&outbuf[wpos], itemDefID);;
	wpos += PutByte(&outbuf[wpos], needed ? 1 : 0);

	PutShort(&outbuf[1], wpos - 3);       //Set message size
	return wpos;
}
Beispiel #21
0
int PrepExt_CooldownExpired(char *buffer, long actor, const char *cooldownCategory)
{
	int wpos = 0;
	wpos += PutByte(&buffer[wpos], 4);  //_handleCreatureEventMsg
	wpos += PutShort(&buffer[wpos], 0);

	wpos += PutInteger(&buffer[wpos], actor);   //actorID
	wpos += PutByte(&buffer[wpos], 22);     //22 = Cooldown category expired

	wpos += PutStringUTF(&buffer[wpos], cooldownCategory);

	PutShort(&buffer[1], wpos - 3);       //Set message size
	return wpos;
}
Beispiel #22
0
int PrepExt_SendAdvancedEmote(char *buffer, int creatureID, const char *emoteName, float emoteSpeed, int loop)
{
	int wpos = 0;
	wpos += PutByte(&buffer[wpos], 100);   //_handleModMessage   REQUIRES MODDED CLIENT
	wpos += PutShort(&buffer[wpos], 0);    //Reserve for size

	wpos += PutByte(&buffer[wpos], MODMESSAGE_EVENT_EMOTE);   //event for advanced emote

	wpos += PutInteger(&buffer[wpos], creatureID);
	wpos += PutStringUTF(&buffer[wpos], emoteName);
	wpos += PutFloat(&buffer[wpos], emoteSpeed);
	wpos += PutByte(&buffer[wpos], (loop != 0));

	PutShort(&buffer[1], wpos - 3);       //Set message size
	return wpos;
}
Beispiel #23
0
void PartyManager :: BroadcastAddMember(CreatureInstance* member)
{
	//Generates a packet for a new member notification and broadcasts it to
	//all other players in the party.
	ActiveParty *party = GetPartyByID(member->PartyID);
	if(party == NULL)
		return;

	int wpos = 0;
	wpos += PutByte(&WriteBuf[wpos], 6);     //_handlePartyUpdateMsg
	wpos += PutShort(&WriteBuf[wpos], 0);
	wpos += PutByte(&WriteBuf[wpos], PartyUpdateOpTypes::ADD_MEMBER);
	wpos += PutInteger(&WriteBuf[wpos], member->CreatureID);
	wpos += PutStringUTF(&WriteBuf[wpos], member->css.display_name);
	PutShort(&WriteBuf[1], wpos - 3);       //Set message size

	party->BroadCastExcept(WriteBuf, wpos, member->CreatureDefID);
}
Beispiel #24
0
int PrepExt_SendEffect(char *buffer, int sourceID, const char *effectName, int targetID)
{
	//Send an effect to the client.  Send as a single target effect
	//unless targetID is nonzero.

	int wpos = 0;
	wpos += PutByte(&buffer[wpos], 4);       //_handleCreatureEventMsg
	wpos += PutShort(&buffer[wpos], 0);      //Reserve for size

	wpos += PutInteger(&buffer[wpos], sourceID);

	wpos += PutByte(&buffer[wpos], (targetID == 0) ? 4 : 12);  //Cue effect
	wpos += PutStringUTF(&buffer[wpos], effectName);
	if(targetID != 0)
		wpos += PutInteger(&buffer[wpos], targetID);

	PutShort(&buffer[1], wpos - 3);       //Set message size
	return wpos;
}
Beispiel #25
0
int PrepExt_QueryResponseStringList(char *buffer, int queryIndex, const STRINGLIST &strData)
{
	int wpos = 0;
	wpos += PutByte(&buffer[wpos], 1);              //_handleQueryResultMsg
	wpos += PutShort(&buffer[wpos], 0);             //Placeholder for message size
	wpos += PutInteger(&buffer[wpos], queryIndex);  //Query response index
	wpos += PutShort(&buffer[wpos], 1);             //Row count

	int count = strData.size();
	if(count > 255)
	{
		g_Logs.server->warn("PrepExt_QueryResponseStringList too many strings: %v", count);
		count = 255;
	}
	wpos += PutByte(&buffer[wpos], count); //String count
	for(int a = 0; a < count; a++)
		wpos += PutStringUTF(&buffer[wpos], strData[a].c_str());   //String data
	PutShort(&buffer[1], wpos - 3);                 //Message size
	return wpos;
}
Beispiel #26
0
bool ChatManager::DeliverChatMessage(ChatMessage &message, CreatureInstance *sendingCreatureInstance) {

	message.mTime =  time(NULL);

	int wpos = 0;
	wpos += PutByte(&SendBuf[wpos], 50);       //_handleCommunicationMsg
	wpos += PutShort(&SendBuf[wpos], 0);         //Placeholder for size
	wpos += PutInteger(&SendBuf[wpos], message.mSenderCreatureID);    //Character ID who's sending the message
	wpos += PutStringUTF(&SendBuf[wpos], message.mSender.c_str()); //pld.charPtr->cdef.css.display_name);  //Character name
	wpos += PutStringUTF(&SendBuf[wpos], message.mTell ? "t/" : message.mChannel->channel);
	wpos += PutStringUTF(&SendBuf[wpos], message.mMessage.c_str());
	PutShort(&SendBuf[1], wpos - 3);     //Set size

	bool found = false;
	bool log = !message.mTell && ( message.mChannel->chatScope == CHAT_SCOPE_REGION || message.mChannel->chatScope == CHAT_SCOPE_SERVER );

	bool breakLoop = false;
	SIMULATOR_IT it;
	for(it = Simulator.begin(); it != Simulator.end(); ++it)
	{
		if(breakLoop == true)
			break;

		if(it->ProtocolState == 0)
		{
			//LogMessageL(MSG_ERROR, "[WARNING] Cannot not send chat to lobby protocol simulator");
			continue;
		}

		if(it->isConnected == false)
			continue;

		if(it->pld.charPtr == NULL)
			continue;

		bool send = false;
		if(message.mTell == true)
		{
			if(strcmp(it->pld.charPtr->cdef.css.display_name, message.mRecipient.c_str()) == 0)
			{
				send = true;
				found = true;
			}
		}
		else
		{
			switch(message.mChannel->chatScope)
			{
			case CHAT_SCOPE_LOCAL:
				if(sendingCreatureInstance == NULL || it->pld.CurrentInstanceID != message.mSendingInstance)
					break;
				if(ActiveInstance::GetPlaneRange(it->creatureInst, sendingCreatureInstance, LOCAL_CHAT_RANGE) > LOCAL_CHAT_RANGE)
					break;

				send = true;
				break;

			case CHAT_SCOPE_REGION:
				if(it->pld.CurrentInstanceID != message.mSendingInstance)
					break;
				send = true;
				break;
			case CHAT_SCOPE_SERVER:
				send = true;

				if(message.mChannelName.compare("gm/earthsages") == 0 && !it->pld.accPtr->HasPermission(Perm_Account, Permission_GMChat) && !it->pld.accPtr->HasPermission(Perm_Account, Permission_Admin)) {
					send = false;
				}

				break;
			case CHAT_SCOPE_FRIEND:
				if(it->pld.CreatureDefID == message.mSenderCreatureDefID)  //Send to self
					send = true;
				else if(g_FriendListManager.IsMutualFriendship(it->pld.CreatureDefID, message.mSenderCreatureDefID) ==true)
					send = true;
				break;
			case CHAT_SCOPE_CHANNEL:
			{
				PrivateChannel *privateChannelData = g_ChatChannelManager.GetChannelForMessage(message.mSimulatorID, message.mChannelName.c_str() + 3);
				if(privateChannelData != NULL) {
					for(size_t i = 0; i < privateChannelData->mMemberList.size(); i++)
						if(it->InternalID == privateChannelData->mMemberList[i].mSimulatorID)
							send = true;
				}
				break;
			}
			case CHAT_SCOPE_PARTY:
				if(sendingCreatureInstance == NULL)
					break;
				g_PartyManager.BroadCastPacket(sendingCreatureInstance->PartyID, sendingCreatureInstance->CreatureDefID, SendBuf, wpos);
				breakLoop = true;
				break;
			case CHAT_SCOPE_CLAN:
			{

				Clans::Clan c = g_ClanManager.GetClan(message.mSenderClanID);
				if(it->pld.CreatureDefID == message.mSenderCreatureDefID)  //Send to self
					send = true;
				else {
					if(c.mId > 0 && it->pld.charPtr->clan == c.mId)
						send = true;
					else if(g_GuildManager.IsMutualGuild(it->pld.CreatureDefID, message.mSenderCreatureDefID) ==true)
						send = true;
				}
				break;
			}
			default:
				break;
			}
		}

		if(send == true) {
			found = true;
			it->AttemptSend(SendBuf, wpos);
		}
	}

	if(log == true)
		LogChatMessage(message);

	return found;
}
Beispiel #27
0
int ChatManager :: handleCommunicationMsg(char *channel, char *message, char *name)
{
	//Returns the number of bytes composing the message data.

	//Mostly copied from the Simulator function with the same name, but without permissions
	//checks.  To be used internally by the server when it needs to send arbitrary messages
	//to clients.  Should not be used for /tell messages.

	//Handles a "communicate" (0x04) message containing a channel and string
	//Sends back a "_handleCommunicationMsg" (50 = 0x32) to the client
	//Ideally this function should broadcast the message to all active player threads
	//in the future so that all players can receive the communication message.
	
	char ComBuf[1024];
	char LogBuffer[1024];
	
	if(strlen(channel) == 0 || strlen(message) == 0)
		return 0;

	//LogMessageL("[%s]:[%s]", channel, message);

	/*
	bool log = false;
	char *prefix = NULL;
	if(strcmp(channel, "s") == 0)
	{
		log = true;
		prefix = ChatPrefix_Say;
	}
	else if(strcmp(channel, "gm/earthsages") == 0)
	{
		log = true;
		prefix = ChatPrefix_GM;
	}
	else if(strcmp(channel, "*SysChat") == 0)
	{
		log = true;
		prefix = ChatPrefix_SysChat;
	}
	else if(strcmp(channel, "rc/") == 0)
	{
		log = true;
		prefix = ChatPrefix_Region;
	}

	if(log == true)
	{
		if(prefix != NULL)
			sprintf(LogBuffer, "%s %s: %s", prefix, name, message);
		else
			sprintf(LogBuffer, "%s: %s", name, message);
		LogChatMessage(LogBuffer);
	}
	else
	{
		sprintf(LogBuffer, "%s: %s", name, message);
		LogChatMessage(LogBuffer);
	}*/

	int found = 0;
	int a;
	for(a = 1; a < NumValidChatChannel; a++)
	{
		if(strcmp(ValidChatChannel[a].channel, channel) == 0)
		{
			found = a;
			break;
		}
	}

	int wpos = 0;
	if(ValidChatChannel[found].prefix != NULL)
		wpos += sprintf(&LogBuffer[wpos], "%s ", ValidChatChannel[found].prefix);
	if(ValidChatChannel[found].name == true)
		wpos += sprintf(&LogBuffer[wpos], "%s: ", name);
	else
		name[0] = 0;   //Disable name from showing in the data buffer

	wpos += sprintf(&LogBuffer[wpos], "%s", message);
	ChatMessage cm(message);
	LogChatMessage(cm);

	wpos = 0;
	wpos += PutByte(&ComBuf[wpos], 0x32);       //_handleCommunicationMsg
	wpos += PutShort(&ComBuf[wpos], 0);         //Placeholder for size

	wpos += PutInteger(&ComBuf[wpos], 0);    //Character ID who's sending the message
	wpos += PutStringUTF(&ComBuf[wpos], name);  //Character name
	wpos += PutStringUTF(&ComBuf[wpos], channel);  //return the channel type
	wpos += PutStringUTF(&ComBuf[wpos], message);  //return the message

	PutShort(&ComBuf[1], wpos - 3);     //Set size

	SIMULATOR_IT it;
	for(it = Simulator.begin(); it != Simulator.end(); ++it)
	{
		if(it->isConnected == true)
			it->AttemptSend(ComBuf, wpos);
	}
	return wpos;
}
Beispiel #28
0
int PersonaListHandler::handleQuery(SimulatorThread *sim,
		CharacterServerData *pld, SimulatorQuery *query,
		CreatureInstance *creatureInstance) {
	/* Query: persona.list
	 Args : [none]
	 Notes: First query sent to the server.
	 Response: Send back the list of characters available on this account.
	 */

	//Seems to be a rare condition when the account can indeed be NULL at this point.  Possibly
	//disconnecting after the query is sent, but before it's processed?
	if (pld->accPtr == NULL) {
		g_Logs.simulator->error("[%v] persona.list null account", sim->InternalID);
		return 0;
	}

	g_Logs.simulator->info("Retrieving persona list for account:%v",
			pld->accPtr->ID);
	//TODO: Fix a potential buffer overflow.

	int WritePos = 0;
	WritePos += PutByte(&sim->SendBuf[WritePos], 1);     //_handleQueryResultMsg
	WritePos += PutShort(&sim->SendBuf[WritePos], 0);           //Message size
	WritePos += PutInteger(&sim->SendBuf[WritePos], query->ID);  //Query ID

	//Character row count
	int charCount = pld->accPtr->GetCharacterCount();
	if (g_ProtocolVersion >= 38) {
		//Version 0.8.9 has a an extra row in the beginning
		//with one string, the number of characters following.
		WritePos += PutShort(&sim->SendBuf[WritePos], charCount + 1);

		WritePos += PutByte(&sim->SendBuf[WritePos], 1);
		sprintf(sim->Aux3, "%d", charCount + 1);
		WritePos += PutStringUTF(&sim->SendBuf[WritePos], sim->Aux3);
	} else {
		WritePos += PutShort(&sim->SendBuf[WritePos], charCount);
	}

	g_CharacterManager.GetThread("SimulatorThread::handle_query_persona_list");

	int b;
	for (b = 0; b < AccountData::MAX_CHARACTER_SLOTS; b++) {
		if (pld->accPtr->CharacterSet[b] != 0) {
			int cdefid = pld->accPtr->CharacterSet[b];
			CharacterCacheEntry *cce =
					pld->accPtr->characterCache.ForceGetCharacter(cdefid);
			if (cce == NULL) {
				g_Logs.simulator->error("[%v] Could not request character: %v", sim->InternalID, cdefid);
				sim->ForceErrorMessage("Critical: could not load a character.",
						INFOMSG_ERROR);
				sim->Disconnect("SimulatorThread::handle_query_persona_list");
				return 0;
			}

			if (g_Config.AprilFools != 0) {
				WritePos += PutByte(&sim->SendBuf[WritePos], 6); //6 character data strings
				WritePos += PutStringUTF(&sim->SendBuf[WritePos],
						cce->display_name.c_str()); //Seems to be sent twice in 0.8.9.  Unknown purpose.
				WritePos += PutStringUTF(&sim->SendBuf[WritePos],
						cce->display_name.c_str());
				WritePos += PutStringUTF(&sim->SendBuf[WritePos],
						cce->appearance.c_str());

				const char *eqApp = cce->eq_appearance.c_str();
				switch (cce->profession) {
				case 1:
					eqApp =
							"{[1]=3163,[0]=141760,[6]=3019,[10]=3008,[11]=2831}";
					break;
				case 2:
					eqApp =
							"{[0]=141763,[1]=141764,[6]=2107,[10]=2442,[11]=2898}";
					break;
				case 3:
					eqApp = "{[6]=2810,[10]=1980,[11]=2108,[2]=141765}";
					break;
				case 4:
					eqApp = "{[2]=143609,[6]=3160,[10]=3161,[11]=3162}";
					break;
				}
				WritePos += PutStringUTF(&sim->SendBuf[WritePos], eqApp);

				//sprintf(Aux3, "%d", cce->level);
				WritePos += PutStringUTF(&sim->SendBuf[WritePos], "1");

				sprintf(sim->Aux3, "%d", cce->profession);
				WritePos += PutStringUTF(&sim->SendBuf[WritePos], sim->Aux3);
				if (WritePos >= (int) sizeof(sim->SendBuf))
					g_Logs.server->error("Buffer overflow in persona.list");
			} else {
				//Normal stuff.
				WritePos += PutByte(&sim->SendBuf[WritePos], 6); //6 character data strings
				WritePos += PutStringUTF(&sim->SendBuf[WritePos],
						cce->display_name.c_str()); //Seems to be sent twice in 0.8.9.  Unknown purpose.
				WritePos += PutStringUTF(&sim->SendBuf[WritePos],
						cce->display_name.c_str());
				WritePos += PutStringUTF(&sim->SendBuf[WritePos],
						cce->appearance.c_str());
				WritePos += PutStringUTF(&sim->SendBuf[WritePos],
						cce->eq_appearance.c_str());

				sprintf(sim->Aux3, "%d", cce->level);
				WritePos += PutStringUTF(&sim->SendBuf[WritePos], sim->Aux3);

				sprintf(sim->Aux3, "%d", cce->profession);
				WritePos += PutStringUTF(&sim->SendBuf[WritePos], sim->Aux3);
				if (WritePos >= (int) sizeof(sim->SendBuf))
					g_Logs.server->error("Buffer overflow in persona.list");
			}
		}
	}
	PutShort(&sim->SendBuf[1], WritePos - 3);       //Set message size
	g_CharacterManager.ReleaseThread();

	return WritePos;
}
Beispiel #29
0
void SceneryManager::SendPageRequest(const SceneryPageRequest& request, std::list<PacketManager::PACKET_PAIR>& outgoingPackets)
{
	TimeObject to("SceneryManager::SendPageRequest");

	STRINGLIST queryRows;
	Packet data;
	int wpos = 0;
	char idBuf[32];

	GetThread("SceneryManager::HandlePageRequests[page]");

	SceneryPage *page = GetOrCreatePage(request.zone, request.x, request.y);

	if(page == NULL)
	{
		g_Log.AddMessageFormat("[ERROR] SendPageRequest retrieved NULL page");
		
		wpos = PrepExt_QueryResponseNull(prepBuf, request.queryID);
		data.Assign(prepBuf, wpos);
		outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data));

		ReleaseThread();
		return;
	}

	SceneryPage::SCENERY_IT it;
	for(it = page->mSceneryList.begin(); it != page->mSceneryList.end(); ++it)
	{
		//Build the list of scenery ID strings to form the response to the scenery.list query.
		//No need to save row data unless the query is required.
		if(request.skipQuery == false)
		{
			sprintf(idBuf, "%d", it->second.ID);
			queryRows.push_back(idBuf);
		}
		
		wpos += PrepExt_UpdateScenery(&prepBuf[wpos], &it->second);
		if(wpos > Global::MAX_SEND_CHUNK_SIZE)
		{
			data.Assign(prepBuf, wpos);
			outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data));
			wpos = 0;
		}
	}
	if(wpos > 0)
	{
		data.Assign(prepBuf, wpos);
		outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data));
	}

	//Done accessing the scenery data itself, no need to hold the thread any longer.
	//All the remaining stuff is using a resident list of query IDs to form into a response
	//packet.
	ReleaseThread();

	//Now build the query response if the client has requested it.
	if(request.skipQuery == true)
		return;

	//Reset the packet buffer and data.
	wpos = 0;
	data.Clear();

	//Get the size of the response
	int sizeReq = 6;  //Query ID (4 bytes) + row count (2 bytes)
	for(size_t s = 0; s < queryRows.size(); s++)
	{
		sizeReq++;  //1 string per row
		sizeReq += PutStringReq(queryRows[s].c_str());
	}

	wpos += PutByte(&prepBuf[wpos], 1);         //_handleQueryResultMsg
	wpos += PutShort(&prepBuf[wpos], sizeReq);  //Message size

	wpos += PutInteger(&prepBuf[wpos], request.queryID);
	wpos += PutShort(&prepBuf[wpos], queryRows.size());
	for(size_t s = 0; s < queryRows.size(); s++)
	{
		wpos += PutByte(&prepBuf[wpos], 1);
		wpos += PutStringUTF(&prepBuf[wpos], queryRows[s].c_str());
		if(wpos > Global::MAX_SEND_CHUNK_SIZE)
		{
			data.Append(prepBuf, wpos);
			wpos = 0;
		}
	}
	if(wpos > 0)
		data.Append(prepBuf, wpos);

	outgoingPackets.push_back(PacketManager::PACKET_PAIR(request.socket, data));
}
Beispiel #30
0
int PrepExt_ItemDef(char *SendBuf, ItemDef *item, int ProtocolState)
{
	int WritePos = 0;

	//_handleItemDefUpdateMsg is [4] for lobby, [71] for play (most common) protocol
	char message = 71;
	if(ProtocolState == 0)
		message = 4;

	WritePos += PutByte(&SendBuf[WritePos], message);
	WritePos += PutShort(&SendBuf[WritePos], 0);      //Message size

	WritePos += PutInteger(&SendBuf[WritePos], item->mID);

	//Fill the item properties
	WritePos += PutByte(&SendBuf[WritePos], item->mType);
	WritePos += PutStringUTF(&SendBuf[WritePos], item->mDisplayName.c_str());
	WritePos += PutStringUTF(&SendBuf[WritePos], item->mAppearance.c_str());
	WritePos += PutStringUTF(&SendBuf[WritePos], item->mIcon.c_str());

	WritePos += PutByte(&SendBuf[WritePos], item->mIvType1);
	WritePos += PutShort(&SendBuf[WritePos], item->mIvMax1);
	WritePos += PutByte(&SendBuf[WritePos], item->mIvType2);
	WritePos += PutShort(&SendBuf[WritePos], item->mIvMax2);
	WritePos += PutStringUTF(&SendBuf[WritePos], item->mSv1.c_str());

	if(g_ProtocolVersion < 5)
		WritePos += PutInteger(&SendBuf[WritePos], item->_mCopper);

	WritePos += PutShort(&SendBuf[WritePos], item->mContainerSlots);
	WritePos += PutByte(&SendBuf[WritePos], item->mAutoTitleType);
	WritePos += PutShort(&SendBuf[WritePos], item->mLevel);
	WritePos += PutByte(&SendBuf[WritePos], item->mBindingType);
	WritePos += PutByte(&SendBuf[WritePos], item->mEquipType);

	WritePos += PutByte(&SendBuf[WritePos], item->mWeaponType);
	if(item->mWeaponType != 0)
	{
		if(g_ProtocolVersion == 7)
		{
			WritePos += PutByte(&SendBuf[WritePos], item->mWeaponDamageMin);
			WritePos += PutByte(&SendBuf[WritePos], item->mWeaponDamageMax);
			WritePos += PutByte(&SendBuf[WritePos], item->_mSpeed);
			WritePos += PutByte(&SendBuf[WritePos], item->mWeaponExtraDamangeRating);
			WritePos += PutByte(&SendBuf[WritePos], item->mWeaponExtraDamageType);
		}
		else
		{
			WritePos += PutInteger(&SendBuf[WritePos], item->mWeaponDamageMin);
			WritePos += PutInteger(&SendBuf[WritePos], item->mWeaponDamageMax);
			WritePos += PutByte(&SendBuf[WritePos], item->mWeaponExtraDamangeRating);
			WritePos += PutByte(&SendBuf[WritePos], item->mWeaponExtraDamageType);
		}
	}

	WritePos += PutInteger(&SendBuf[WritePos], item->mEquipEffectId);
	WritePos += PutInteger(&SendBuf[WritePos], item->mUseAbilityId);
	WritePos += PutInteger(&SendBuf[WritePos], item->mActionAbilityId);
	WritePos += PutByte(&SendBuf[WritePos], item->mArmorType);
	if(item->mArmorType != 0)
	{
		if(g_ProtocolVersion == 7)
		{
			WritePos += PutByte(&SendBuf[WritePos], item->mArmorResistMelee);
			WritePos += PutByte(&SendBuf[WritePos], item->mArmorResistFire);
			WritePos += PutByte(&SendBuf[WritePos], item->mArmorResistFrost);
			WritePos += PutByte(&SendBuf[WritePos], item->mArmorResistMystic);
			WritePos += PutByte(&SendBuf[WritePos], item->mArmorResistDeath);
		}
		else
		{
			WritePos += PutInteger(&SendBuf[WritePos], item->mArmorResistMelee);
			WritePos += PutInteger(&SendBuf[WritePos], item->mArmorResistFire);
			WritePos += PutInteger(&SendBuf[WritePos], item->mArmorResistFrost);
			WritePos += PutInteger(&SendBuf[WritePos], item->mArmorResistMystic);
			WritePos += PutInteger(&SendBuf[WritePos], item->mArmorResistDeath);
		}
	}
	if(g_ProtocolVersion == 7)
	{
		WritePos += PutByte(&SendBuf[WritePos], item->mBonusStrength);
		WritePos += PutByte(&SendBuf[WritePos], item->mBonusDexterity);
		WritePos += PutByte(&SendBuf[WritePos], item->mBonusConstitution);
		WritePos += PutByte(&SendBuf[WritePos], item->mBonusPsyche);
		WritePos += PutByte(&SendBuf[WritePos], item->mBonusSpirit);
		WritePos += PutByte(&SendBuf[WritePos], item->_mBonusHealth);
		WritePos += PutByte(&SendBuf[WritePos], item->mBonusWill);
	}
	else
	{
		WritePos += PutInteger(&SendBuf[WritePos], item->mBonusStrength);
		WritePos += PutInteger(&SendBuf[WritePos], item->mBonusDexterity);
		WritePos += PutInteger(&SendBuf[WritePos], item->mBonusConstitution);
		WritePos += PutInteger(&SendBuf[WritePos], item->mBonusPsyche);
		WritePos += PutInteger(&SendBuf[WritePos], item->mBonusSpirit);

		if(g_ProtocolVersion < 32)
			WritePos += PutInteger(&SendBuf[WritePos], item->_mBonusHealth);
		WritePos += PutInteger(&SendBuf[WritePos], item->mBonusWill);
	}

	if(g_ProtocolVersion >= 4)
	{
		WritePos += PutByte(&SendBuf[WritePos], item->isCharm);
		if(item->isCharm != 0)
		{
			WritePos += PutFloat(&SendBuf[WritePos], item->mMeleeHitMod);
			WritePos += PutFloat(&SendBuf[WritePos], item->mMeleeCritMod);
			WritePos += PutFloat(&SendBuf[WritePos], item->mMagicHitMod);
			WritePos += PutFloat(&SendBuf[WritePos], item->mMagicCritMod);
			WritePos += PutFloat(&SendBuf[WritePos], item->mParryMod);
			WritePos += PutFloat(&SendBuf[WritePos], item->mBlockMod);
			WritePos += PutFloat(&SendBuf[WritePos], item->mRunSpeedMod);
			WritePos += PutFloat(&SendBuf[WritePos], item->mRegenHealthMod);
			WritePos += PutFloat(&SendBuf[WritePos], item->mAttackSpeedMod);
			WritePos += PutFloat(&SendBuf[WritePos], item->mCastSpeedMod);
			WritePos += PutFloat(&SendBuf[WritePos], item->mHealingMod);
		}
	}

	if(g_ProtocolVersion >= 5)
	{
		WritePos += PutInteger(&SendBuf[WritePos], item->mValue);
		WritePos += PutByte(&SendBuf[WritePos], item->mValueType);
	}

	bool ItemUpdateDefMsgCraft = false;
	if(g_ProtocolVersion >= 7)
		ItemUpdateDefMsgCraft = true;
	if(ItemUpdateDefMsgCraft == true)
	{
		WritePos += PutInteger(&SendBuf[WritePos], item->resultItemId);
		WritePos += PutInteger(&SendBuf[WritePos], item->keyComponentId);
		WritePos += PutInteger(&SendBuf[WritePos], item->numberOfItems);
		for(size_t i = 0; i < item->craftItemDefId.size(); i++)
			WritePos += PutInteger(&SendBuf[WritePos], item->craftItemDefId[i]);

		if(item->numberOfItems != item->craftItemDefId.size())
			g_Logs.server->error("Crafting material item count mismatch for ID: %v", item->mID);
	}

	if(g_ProtocolVersion >= 9)
		WritePos += PutStringUTF(&SendBuf[WritePos], item->mFlavorText.c_str());

	if(g_ProtocolVersion >= 18)
		WritePos += PutByte(&SendBuf[WritePos], item->mSpecialItemType);

	if(g_ProtocolVersion >= 30)
		WritePos += PutByte(&SendBuf[WritePos], item->mOwnershipRestriction);

	if(g_ProtocolVersion >= 31)
	{
		WritePos += PutByte(&SendBuf[WritePos], item->mQualityLevel);
		WritePos += PutShort(&SendBuf[WritePos], item->mMinUseLevel);
	}

	PutShort(&SendBuf[1], WritePos - 3);
	return WritePos;
}