void CUser::ExchangeReq(Packet & pkt)
{
	Packet result(WIZ_EXCHANGE);
	if (isDead())
		goto fail_return;
	else if (isTrading())
	{
		ExchangeCancel();
		return;
	}

	uint16 destid = pkt.read<uint16>();
	CUser* pUser = g_pMain->GetUserPtr(destid);
	if (pUser == NULL
		|| pUser->isTrading()
		|| (pUser->GetNation() != GetNation() && pUser->GetZoneID() != 21 && GetZoneID() != 21)
		|| pUser->GetZoneID() != GetZoneID())
		goto fail_return;

	m_sExchangeUser = destid;
	pUser->m_sExchangeUser = GetSocketID();

	result << uint8(EXCHANGE_REQ) << GetSocketID();
	pUser->Send(&result);
	return;

fail_return:
	result << uint8(EXCHANGE_CANCEL);
	Send(&result);
}
void CGameSocket::RecvUserInfoAllData(Packet & pkt)
{
	uint8 byCount = pkt.read<uint8>();
	pkt.SByte();
	for (int i = 0; i < byCount; i++)
	{
		CUser* pUser = new CUser();

		pUser->Initialize();

		pkt >> pUser->m_iUserId >> pUser->m_strUserID >> pUser->m_bZone
			>> pUser->m_bNation >> pUser->m_bLevel 
			>> pUser->m_sHP >> pUser->m_sMP
			>> pUser->m_sHitDamage >> pUser->m_sAC
			>> pUser->m_fHitrate >> pUser->m_fAvoidrate
			>> pUser->m_sPartyNumber >> pUser->m_byIsOP
			>> pUser->m_bInvisibilityType;

		if (pUser->GetName().empty() || pUser->GetName().length() > MAX_ID_SIZE)
		{
			TRACE("###  RecvUserInfoAllData() Fail ---> uid = %d, name=%s, len=%d  ### \n", 
				pUser->GetID(), pUser->GetName().c_str(), pUser->GetName().length());

			delete pUser;
			continue;
		}

		pUser->m_pMap = g_pMain->GetZoneByID(pUser->GetZoneID());
		pUser->m_bLive = AI_USER_LIVE;
		if (pUser->m_sPartyNumber != -1)
			pUser->m_byNowParty = 1;

		TRACE("****  RecvUserInfoAllData()---> uid = %d, %s, party_number=%d  ******\n", 
			pUser->GetID(), pUser->GetName().c_str(), pUser->m_sPartyNumber);

		if (pUser->GetID() < MAX_USER)
		{
			// Does a user already exist? Free them (I know, tacky...)
			if (g_pMain->m_pUser[pUser->GetID()] != nullptr)
				delete g_pMain->m_pUser[pUser->GetID()];

			g_pMain->m_pUser[pUser->GetID()] = pUser;
		}
		else
		{
			delete pUser;
		}
	}
}
void CUser::ExchangeReq(Packet & pkt)
{
	Packet result(WIZ_EXCHANGE);
	CUser * pUser;
	uint16 destid;

	if (isDead() || isStoreOpen() || isMerchanting())
		goto fail_return;

	else if (isTrading())
	{
		ExchangeCancel();
		return;
	}

	destid = pkt.read<uint16>();
	pUser = g_pMain->GetUserPtr(destid);
	if (pUser == nullptr
		|| pUser->isTrading()
		|| pUser->GetZoneID() != GetZoneID()
		|| (GetNation() != GetNation() && GetMap()->canTradeWithOtherNation()))
		goto fail_return;

	m_sExchangeUser = destid;
	pUser->m_sExchangeUser = GetSocketID();

	if (pUser->isDead() || pUser->isStoreOpen() || pUser->isMerchanting())
		goto fail_return;

	result << uint8(EXCHANGE_REQ) << GetSocketID();
	pUser->Send(&result);
	return;

fail_return:
	result << uint8(EXCHANGE_CANCEL);
	Send(&result);
}