void CUser::GetUserInfo(Packet & pkt)
{
	CKnights *pKnights = NULL;
	pkt.SByte();

	pkt		<< GetName()
			<< uint16(GetNation()) << GetClanID() << getFame();

	pKnights = g_pMain->GetClanPtr(GetClanID());
	if (pKnights == NULL)
	{
		pkt	<< uint32(0) << uint16(0) << uint8(0) << uint16(-1) << uint32(0) << uint8(0);
	}
	else
	{
		pkt	<< uint16(pKnights->m_sAlliance)
				<< pKnights->m_strName
				<< pKnights->m_byGrade << pKnights->m_byRanking
				<< uint16(pKnights->m_sMarkVersion) // symbol/mark version
				<< uint16(pKnights->m_sCape) // cape ID
				<< pKnights->m_bCapeR << pKnights->m_bCapeG << pKnights->m_bCapeB << uint8(0) // this is stored in 4 bytes after all.
				// not sure what this is, but it (just?) enables the clan symbol on the cape 
				// value in dump was 9, but everything tested seems to behave as equally well...
				// we'll probably have to implement logic to respect requirements.
				<< uint8(1); 
	}

	pkt	<< GetLevel() << m_bRace << m_sClass
		<< GetSPosX() << GetSPosZ() << GetSPosY()
		<< m_bFace << m_nHair
		<< m_bResHpType << uint32(m_bAbnormalType)
		<< m_bNeedParty
		<< m_bAuthority
		<< m_bPartyLeader // is party leader (bool)
		<< m_bInvisibilityType // visibility state
		<< uint8(0) // team colour (i.e. in soccer, 0=none, 1=blue, 2=red)
		<< m_bIsHidingHelmet // either this is correct and items are super buggy, or it causes baldness. You choose.
		<< m_sDirection // direction 
		<< m_bIsChicken // chicken/beginner flag
		<< m_bRank // king flag
		<< m_bPersonalRank << m_bKnightsRank // NP ranks (total, monthly)
		<< m_sItemArray[BREAST].nNum << m_sItemArray[BREAST].sDuration << uint8(0)
		<< m_sItemArray[LEG].nNum << m_sItemArray[LEG].sDuration << uint8(0)
		<< m_sItemArray[HEAD].nNum << m_sItemArray[HEAD].sDuration << uint8(0)
		<< m_sItemArray[GLOVE].nNum << m_sItemArray[GLOVE].sDuration << uint8(0)
		<< m_sItemArray[FOOT].nNum << m_sItemArray[FOOT].sDuration << uint8(0)
		<< m_sItemArray[SHOULDER].nNum << m_sItemArray[SHOULDER].sDuration << uint8(0)
		<< m_sItemArray[RIGHTHAND].nNum << m_sItemArray[RIGHTHAND].sDuration << uint8(0)
		<< m_sItemArray[LEFTHAND].nNum << m_sItemArray[LEFTHAND].sDuration << uint8(0)
		<< m_sItemArray[CWING].nNum << m_sItemArray[CWING].sDuration << uint8(0)
		<< m_sItemArray[CTOP].nNum << m_sItemArray[CTOP].sDuration << uint8(0)
		<< m_sItemArray[CHELMET].nNum << m_sItemArray[CHELMET].sDuration << uint8(0)
		<< m_sItemArray[CRIGHT].nNum << m_sItemArray[CRIGHT].sDuration << uint8(0)
		<< m_sItemArray[CLEFT].nNum << m_sItemArray[CLEFT].sDuration << uint8(0)
		<< GetZoneID() << uint8(-1) << uint8(-1) << uint16(0) << uint16(0) << uint16(0);
}
Example #2
0
void CUser::Chat(Packet & pkt)
{
	Packet result;
	uint16 sessID;
	uint8 type = pkt.read<uint8>(), bNation;
	string chatstr, finalstr, strSender, * strMessage;

	bool isAnnouncement = false;

	if (isMuted())
		return;	

	pkt >> chatstr;
	if (chatstr.empty() || chatstr.size() > 128)
		return;

	// Process GM commands
	if (isGM() && ProcessChatCommand(chatstr))
		return;

#if 0 // Removed this - all it seems to do is cause chat to break for GMs (is it 19xx+ only?)
	if( isGM() && type == GENERAL_CHAT)
		type = 0x14;
#endif

	// Handle GM notice & announcement commands
	if (type == PUBLIC_CHAT || type == ANNOUNCEMENT_CHAT)
	{
		// Trying to use a GM command without authorisation? Bad player!
		if (!isGM())
			return;

		if (type == ANNOUNCEMENT_CHAT)
			type = WAR_SYSTEM_CHAT;

		// This is horrible, but we'll live with it for now.
		// Pull the notice string (#### NOTICE : %s ####) from the database.
		// Format the chat string around it, so our chat data is within the notice
		g_pMain->GetServerResource(IDP_ANNOUNCEMENT, &finalstr, chatstr.c_str());
		isAnnouncement = true;
	}


	if (isAnnouncement)
	{
		// GM notice/announcements show no name, so don't bother setting it.
		strMessage = &finalstr; // use the formatted message from the user
		bNation = KARUS; // arbitrary nation
		sessID = -1;
	}
	else
	{
		strMessage = &chatstr; // use the raw message from the user
		strSender = GetName(); // everything else uses a name, so set it
		bNation = GetNation();
		sessID = GetSocketID();
	}

	ChatPacket::Construct(&result, type, strMessage, &strSender, bNation, sessID);

	switch (type) 
	{
	case GENERAL_CHAT:
		g_pMain->Send_NearRegion(&result, GetMap(), GetRegionX(), GetRegionZ(), GetX(), GetZ());
		break;

	case PRIVATE_CHAT:
	{
		CUser *pUser = g_pMain->GetUserPtr(m_sPrivateChatUser);
		if (pUser != NULL) 
			pUser->Send(&result);
	} break;

	case PARTY_CHAT:
		if (isInParty())
			g_pMain->Send_PartyMember(m_sPartyIndex, &result);
		break;

	case SHOUT_CHAT:
		if (m_sMp < (m_iMaxMp / 5))
			break;

		// Characters under level 35 require 3,000 coins to shout.
		if (!isGM()
			&& GetLevel() < 35
			&& !GoldLose(SHOUT_COIN_REQUIREMENT))
			break;

		MSpChange(-(m_iMaxMp / 5));
		SendToRegion(&result);
		break;

	case KNIGHTS_CHAT:
		if (isInClan())
			g_pMain->Send_KnightsMember(GetClanID(), &result);
		break;
	case PUBLIC_CHAT:
	case ANNOUNCEMENT_CHAT:
		if (isGM())
			g_pMain->Send_All(&result);
		break;
	case COMMAND_CHAT:
		if (getFame() == COMMAND_CAPTAIN)
			g_pMain->Send_CommandChat(&result, m_bNation, this);
		break;
	case MERCHANT_CHAT:
		if (isMerchanting())
			SendToRegion(&result);
		break;
	case ALLIANCE_CHAT:
		if (isInClan())
		{
			CKnights *pKnights = g_pMain->GetClanPtr(GetClanID());
			if (pKnights != NULL && pKnights->m_sAlliance > 0)
				g_pMain->Send_KnightsAlliance(pKnights->m_sAlliance, &result);
		}
		break;
	case WAR_SYSTEM_CHAT:
		if (isGM())
			g_pMain->Send_All(&result);
		break;
	}
}
Example #3
0
void Player::save(){
	char sql[10000];
	sprintf_s(sql, 10000, "update keymap set ");
	for(int i=0; i<90; i++){
		char temp[100];
		if(i!=89)
			sprintf_s(temp, 100, "pos%d=%d, ", i, keys[i]);
		else
			sprintf_s(temp, 100, "pos%d=%d where charid=%d; ", i, keys[i], getPlayerid());
		strcat_s(sql, 10000, temp);
	}
	MySQL::insert(sql);
	sprintf_s(sql, 10000, "update characters set level=%d, job=%d, str=%d, dex=%d, intt=%d, luk=%d, chp=%d, mhp=%d, cmp=%d, mmp=%d, ap=%d, sp=%d, exp=%d, fame=%d, map=%d, gender=%d, skin=%d, eyes=%d, hair=%d, mesos=%d where id=%d", getLevel(), getJob(), getStr(), getDex(), getInt(), getLuk(), getHP(), getRMHP(), getMP(), getRMMP(), getAp(), getSp(), getExp(), getFame(), getMap(), getGender(), getSkin(), getEyes(), getHair(), inv->getMesos() ,getPlayerid());
	MySQL::insert(sql);
	char temp[1000];
	sprintf_s(sql, 10000, "delete from equip where charid=%d;", getPlayerid());
	MySQL::insert(sql);
	bool firstrun = true;
	for(int i=0; i<inv->getEquipNum(); i++){
		if(firstrun == true){
			sprintf_s(sql, 10000, "INSERT INTO equip VALUES (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", inv->getEquip(i)->id, Drops::equips[inv->getEquip(i)->id].type ,getPlayerid(), inv->getEquipPos(i), inv->getEquip(i)->slots, inv->getEquip(i)->scrolls,
				inv->getEquip(i)->istr, inv->getEquip(i)->idex, inv->getEquip(i)->iint, inv->getEquip(i)->iluk, inv->getEquip(i)->ihp, inv->getEquip(i)->imp, inv->getEquip(i)->iwatk, inv->getEquip(i)->imatk, inv->getEquip(i)->iwdef, 
				inv->getEquip(i)->imdef, inv->getEquip(i)->iacc, inv->getEquip(i)->iavo, inv->getEquip(i)->ihand, inv->getEquip(i)->ijump, inv->getEquip(i)->ispeed);
			firstrun = false;
		}
		else{
			sprintf_s(temp, 1000, ",(%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", inv->getEquip(i)->id, Drops::equips[inv->getEquip(i)->id].type ,getPlayerid(), inv->getEquipPos(i), inv->getEquip(i)->slots, inv->getEquip(i)->scrolls,
				inv->getEquip(i)->istr, inv->getEquip(i)->idex, inv->getEquip(i)->iint, inv->getEquip(i)->iluk, inv->getEquip(i)->ihp, inv->getEquip(i)->imp, inv->getEquip(i)->iwatk, inv->getEquip(i)->imatk, inv->getEquip(i)->iwdef, 
				inv->getEquip(i)->imdef, inv->getEquip(i)->iacc, inv->getEquip(i)->iavo, inv->getEquip(i)->ihand, inv->getEquip(i)->ijump, inv->getEquip(i)->ispeed);
			strcat_s(sql, 10000, temp);
		}
	}
	MySQL::insert(sql);
	sprintf_s(sql, 10000, "delete from skills where charid=%d;", getPlayerid());
	MySQL::insert(sql);
	firstrun = true;
	for(int i=0; i<skills->getSkillsNum(); i++){
		if(firstrun == true){
			sprintf_s(sql, 10000, "INSERT INTO skills VALUES (%d, %d, %d)", getPlayerid(), skills->getSkillID(i), skills->getSkillLevel(skills->getSkillID(i)));
			firstrun = false;
		}
		else{
			sprintf_s(temp, 1000, ",(%d, %d, %d)", getPlayerid(), skills->getSkillID(i), skills->getSkillLevel(skills->getSkillID(i)));
			strcat_s(sql, 10000, temp);
		}
	}
	MySQL::insert(sql);
	sprintf_s(sql, 10000, "DELETE FROM items WHERE charid=%d;", getPlayerid());
	MySQL::insert(sql);
	firstrun = true;
	for(int i=0; i<inv->getItemNum(); i++){
		if(firstrun == true){
			sprintf_s(sql, 10000, "INSERT INTO items VALUES (%d, %d, %d, %d, %d)", inv->getItem(i)->id, getPlayerid() ,inv->getItem(i)->inv, inv->getItem(i)->pos, inv->getItem(i)->amount);
			firstrun = false;
		}
		else{
			sprintf_s(temp, 1000, ",(%d, %d, %d, %d, %d)", inv->getItem(i)->id, getPlayerid() ,inv->getItem(i)->inv, inv->getItem(i)->pos, inv->getItem(i)->amount);
			strcat_s(sql, 10000, temp);
		}
	}
	MySQL::insert(sql);
}
void CUser::SelectCharacter(Packet & pkt)
{
	Packet result(WIZ_SEL_CHAR);
	uint8 bResult, bInit;

	if (isBanned())
	{
		Disconnect();
		return;
	}

	pkt >> bResult >> bInit;
	result << bResult;

	if (bResult == 0 || !GetZoneID()) 
		goto fail_return;

	m_pMap = g_pMain->GetZoneByID(GetZoneID());
	if (GetMap() == NULL)
		goto fail_return;

	// Temporarily convert the old quest storage format to the new one.
	// This won't be necessary when Aujard's out of the picture.
	m_questMap.clear();
	for (int i = 0, index = 0; i < m_pUserData->m_sQuestCount; i++)
	{
		uint16	sQuestID	= GetShort(m_pUserData->m_bstrQuest, index);
		uint8	bQuestState	= GetByte(m_pUserData->m_bstrQuest, index);

		m_questMap.insert(std::make_pair(sQuestID, bQuestState));
	}

	if (g_pMain->m_nServerNo != GetMap()->m_nServerNo)
	{
		_ZONE_SERVERINFO *pInfo = g_pMain->m_ServerArray.GetData(GetMap()->m_nServerNo);
		if (pInfo == NULL) 
			goto fail_return;

		SendServerChange(pInfo->strServerIP, bInit);
		return;
	}

	if (g_pMain->m_byBattleOpen == NO_BATTLE && getFame() == COMMAND_CAPTAIN)
		m_pUserData->m_bFame = CHIEF;

	if ((GetZoneID() != GetNation() && GetZoneID() < 3 && !g_pMain->m_byBattleOpen)
		|| (GetZoneID() == ZONE_BATTLE && (g_pMain->m_byBattleOpen != NATION_BATTLE))
		|| (GetZoneID() == ZONE_SNOW_BATTLE && (g_pMain->m_byBattleOpen != SNOW_BATTLE))
		|| (GetZoneID() == ZONE_FRONTIER && g_pMain->m_byBattleOpen))
	{
		NativeZoneReturn();
		Disconnect();
		return;
	}

	SetLogInInfoToDB(bInit);

	result << GetZoneID() << GetSPosX() << GetSPosZ() << GetSPosY() << g_pMain->m_byOldVictory;
	m_bSelectedCharacter = true;
	Send(&result);

	SetSlotItemValue();
	SetUserAbility(false);

	if (GetLevel() > MAX_LEVEL) 
	{
		Disconnect();
		return;
	}

	m_iMaxExp = g_pMain->GetExpByLevel(GetLevel());
	SetRegion(GetNewRegionX(), GetNewRegionZ());

	if (GetClanID() == -1)
	{
		SetClanID(0);
		m_pUserData->m_bFame = 0;
		return;
	}
	else if (GetClanID() != 0)
	{
		CKnights* pKnights = g_pMain->GetClanPtr( GetClanID() );
		if (pKnights != NULL)
		{
			g_pMain->m_KnightsManager.SetKnightsUser( GetClanID(), m_pUserData->m_id );
		}
		else if (GetZoneID() > 2)
		{
			result.Initialize(WIZ_KNIGHTS_PROCESS);
			result << uint8(KNIGHTS_LIST_REQ) << GetClanID();
			g_pMain->m_LoggerSendQueue.PutData(&result, GetSocketID());
		}
	}
	return;

fail_return:
	Send(&result);
}
void CUser::Chat(Packet & pkt)
{
	Packet result(WIZ_CHAT);
	uint8 type = pkt.read<uint8>();
	char finalstr[1024] = ""; 
	std::string buff, chatstr;
	bool isAnnouncement = false;

	if (isMuted())
		return;	

	pkt >> chatstr;
	if (chatstr.empty() || chatstr.size() > 128)
		return;

	// Process GM commands
	if (isGM() && ProcessChatCommand(chatstr))
		return;

#if 0 // Removed this - all it seems to do is cause chat to break for GMs (is it 19xx+ only?)
	if( isGM() && type == GENERAL_CHAT)
		type = 0x14;
#endif

	uint8 bNation = GetNation();
	uint16 sessID = GetSocketID();

	// Handle GM notice & announcement commands
	if (type == PUBLIC_CHAT || type == ANNOUNCEMENT_CHAT)
	{
		// Trying to use a GM command without authorisation? Bad player!
		if (!isGM())
			return;

		if (type == ANNOUNCEMENT_CHAT)
			type = WAR_SYSTEM_CHAT;

		// This is horrible, but we'll live with it for now.
		// Pull the notice string (#### NOTICE : %s ####) from the database.
		CString noticeText = g_pMain->GetServerResource(IDP_ANNOUNCEMENT);
		
		// Format the chat string around it, so our chat data is within the notice
		sprintf_s(finalstr, sizeof(finalstr), noticeText, chatstr.c_str());

		bNation = KARUS; // arbitrary nation
		sessID = -1;
		isAnnouncement = true;
	}

	result.SByte();
	result << type << bNation << sessID;
	if (isAnnouncement)
	{
		result << uint8(0); // GM notice/announcements show no name (so specify length of 0)
		result.DByte();
		result << finalstr; // now tack on the formatted message from the user
	}
	else
	{
		result << m_pUserData.m_id; // everything else provides a name
		result.DByte();
		result << chatstr; // now tack on the chat message from the user
	}

	switch (type) 
	{
	case GENERAL_CHAT:
		g_pMain->Send_NearRegion(&result, GetMap(), GetRegionX(), GetRegionZ(), GetX(), GetZ());
		break;

	case PRIVATE_CHAT:
	{
		if (m_sPrivateChatUser == GetSocketID()) 
			break;

		CUser *pUser = g_pMain->GetUserPtr(m_sPrivateChatUser);
		if (pUser != NULL) 
			pUser->Send(&result);
	} break;

	case PARTY_CHAT:
		if (isInParty())
			g_pMain->Send_PartyMember(m_sPartyIndex, &result);
		break;

	case SHOUT_CHAT:
		if (m_pUserData.m_sMp < (m_iMaxMp / 5))
			break;

		// Characters under level 35 require 3,000 coins to shout.
		if (!isGM()
			&& GetLevel() < 35
			&& !GoldLose(SHOUT_COIN_REQUIREMENT))
			break;

		MSpChange(-(m_iMaxMp / 5));
		SendToRegion(&result);
		break;

	case KNIGHTS_CHAT:
		if (isInClan())
			g_pMain->Send_KnightsMember(GetClanID(), &result);
		break;
	case PUBLIC_CHAT:
	case ANNOUNCEMENT_CHAT:
		if (isGM())
			g_pMain->Send_All(&result);
		break;
	case COMMAND_CHAT:
		if (getFame() == COMMAND_CAPTAIN)
			g_pMain->Send_CommandChat(&result, m_pUserData.m_bNation, this);
		break;
	case MERCHANT_CHAT:
		if (isMerchanting())
			SendToRegion(&result);
		break;
	case WAR_SYSTEM_CHAT:
		if (isGM())
			g_pMain->Send_All(&result);
		break;
	}
}