Jump to content

CShopManager::Sell (game.core) GDB Results (chw-down)


Recommended Posts

Hi CH-Down Problems.

GDB Results:

zvLUMnZ.png

Shop_Manager.CPP/Sell: Functions

void CShopManager::Sell(LPCHARACTER ch, BYTE bCell, BYTE bCount)
{
	if (!ch->GetShop())
		return;

	if (!ch->GetShopOwner())
		return;

	if (!ch->CanHandleItem())
		return;

	if (ch->GetShop()->IsPCShop())
		return;

	if (DISTANCE_APPROX(ch->GetX()-ch->GetShopOwner()->GetX(), ch->GetY()-ch->GetShopOwner()->GetY())>2000)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상점과의 거리가 너무 멀어 물건을 팔 수 없습니다."));
		return;
	}
	
	LPITEM item = ch->GetInventoryItem(bCell);
    // special code (Ken) //
	if (item->GetType() == ITEM_WEAPON || item->GetType() == ITEM_ARMOR || item->GetType() == ITEM_BELT)
	{
			char szEventFlag[30];
			snprintf(szEventFlag, sizeof(szEventFlag), "%d.Engel", item->GetID());
			if (*szEventFlag)
			{
					if (quest::CQuestManager::instance().GetEventFlag(szEventFlag))
					{
							ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("item_engel"));
							return;
					}
			}
	}
    // special code (Ken) //
	
	if (!item)
		return;

	if (item->IsEquipped() == true)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("착용 중인 아이템은 판매할 수 없습니다."));
		return;
	}

	if (true == item->isLocked())
	{
		return;
	}

	if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_SELL))
		return;

	DWORD dwPrice;

	if (bCount == 0 || bCount > item->GetCount())
		bCount = item->GetCount();
	
	dwPrice = item->GetShopBuyPrice();

	if (IS_SET(item->GetFlag(), ITEM_FLAG_COUNT_PER_1GOLD))
	{
		if (dwPrice == 0)
			dwPrice = bCount;
		else
			dwPrice = bCount / dwPrice;
	}
	else
		dwPrice *= bCount;

	dwPrice /= 5;
	
	//세금 계산
	DWORD dwTax = 0;
	int iVal = 0;
	
	if (LC_IsYMIR() ||  LC_IsKorea())
	{
		dwTax = dwPrice * iVal / 100;
		dwPrice -= dwTax;
	}
	else
	{
		dwTax = dwPrice * iVal/100;
		dwPrice -= dwTax;
	}

	if (test_server)
		sys_log(0, "Sell Item price id %d %s itemid %d", ch->GetPlayerID(), ch->GetName(), item->GetID());

	const int64_t nTotalMoney = static_cast<int64_t>(ch->GetGold()) + static_cast<int64_t>(dwPrice);

	if (GOLD_MAX <= nTotalMoney)
	{
		sys_err("[OVERFLOW_GOLD] id %u name %s gold %u", ch->GetPlayerID(), ch->GetName(), ch->GetGold());
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("20억냥이 초과하여 물품을 팔수 없습니다."));
		return;
	}

	// 20050802.myevan.상점 판매 로그에 아이템 ID 추가
	sys_log(0, "SHOP: SELL: %s item name: %s(x%d):%u price: %u", ch->GetName(), item->GetName(), bCount, item->GetID(), dwPrice);

	if (iVal > 0)
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("판매금액의 %d %% 가 세금으로 나가게됩니다"), iVal);

	DBManager::instance().SendMoneyLog(MONEY_LOG_SHOP, item->GetVnum(), dwPrice);

	if (bCount == item->GetCount())
	{
		// 한국에는 아이템을 버리고 복구해달라는 진상유저들이 많아서
		// 상점 판매시 속성로그를 남긴다.
		if (LC_IsYMIR())
			item->AttrLog();

		ITEM_MANAGER::instance().RemoveItem(item, "SELL");
	}
	else
		item->SetCount(item->GetCount() - bCount);

	//군주 시스템 : 세금 징수
	CMonarch::instance().SendtoDBAddMoney(dwTax, ch->GetEmpire(), ch);

	ch->PointChange(POINT_GOLD, dwPrice, false);
}

İtem.H/68;

imzmAZ7.png

 

İnput_Main.CPP/1094 : 

QNwSdue.png

İnput_Main.CPP/3171:

S39p6XZ.png

İnput.CPP/102:

waEMXNA.png

Edited by Metin2 Dev
Core X - External 2 Internal
Link to comment
Share on other sites

  • Premium

Change         case SHOP_SUBHEADER_CG_SELL2:

 

 

With this one:

 

		case SHOP_SUBHEADER_CG_SELL2:
			{
				if (uiBytes < sizeof(BYTE) + sizeof(BYTE))
					return -1;

				BYTE pos = *(c_pData++);
				BYTE count = *(c_pData);

				sys_log(0, "INPUT: %s SHOP: SELL2", ch->GetName());
				CShopManager::instance().Sell(ch, pos, count);
				return sizeof(BYTE) + sizeof(BYTE);
			}

 

Link to comment
Share on other sites

Change         case SHOP_SUBHEADER_CG_SELL2:

 

 

With this one:

 

		case SHOP_SUBHEADER_CG_SELL2:
			{
				if (uiBytes < sizeof(BYTE) + sizeof(BYTE))
					return -1;

				BYTE pos = *(c_pData++);
				BYTE count = *(c_pData);

				sys_log(0, "INPUT: %s SHOP: SELL2", ch->GetName());
				CShopManager::instance().Sell(ch, pos, count);
				return sizeof(BYTE) + sizeof(BYTE);
			}

 

the problem continues.
Link to comment
Share on other sites

  • Premium

Its from this :

This make core to crash....

    const TItemTable * item_table = item->GetProto();
    DWORD item_idd = item->GetID();
    char item_id[1000];
    sprintf(item_id, "%d", item_idd);
    const char * engel = ".Engel";
    char * yeni = (char *) malloc(1 + strlen(item_id)+ strlen(engel) );
    strcpy(yeni, item_id);
    strcat(yeni, engel);
    if(item_idd != NULL and yeni != "\n")
    {
        if (int(quest::CQuestManager::instance().GetEventFlag(yeni)) == 1)
        {
            ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("item_engel"));
            return;
        }
    }

 

This is useless

   const TItemTable * item_table = item->GetProto();

This copy item_idd to string item_id

    DWORD item_idd = item->GetID();
    char item_id[1000];
    sprintf(item_id, "%d", item_idd);
 

And this wft.....why you dont use: strcat(item_id, engel);

    char * yeni = (char *) malloc(1 + strlen(item_id)+ strlen(engel) );
    strcpy(yeni, item_id);
    strcat(yeni, engel);

 

 

  • Love 1
Link to comment
Share on other sites

 LPITEM item = ch->GetInventoryItem(bCell);

    const TItemTable * item_table = item->GetProto();

This is clearly unsecure code! What happens if the result of ch->GetInventoryItem(bCell) == nullptr?

If that is the case, then you can't execute it like a pointer!

Between those two lines you'd add:

if(nullptr == item)

  return;

Note that this also already exists in another form:

if(!item)

 return;

But it's just too late. You'd have those lines right after you initialize the item variable.

 

 

Also.. Why are you using malloc when we're in c++?

You'd change:

char * yeni = (char*) malloc(1+ strlen(item_id) + strlen(engel));

to:

char* yeni = new char(1 + strlen(item_id) + strlen(engel));

Also don't forget to run free() (c) or delete[] (c++) on dynamically allocated variables. In your case:

free(yeni);

Ooor when you use the c++ method:

delete[] yeni;

 

But you'd also forget the char chaos if we have strings here.

std::string yeni = str(item_id);

yeni.copy(engel);

That'll also do and you won't have to deal with free() or delete[].

 

 

So. What should you do? I suggest you to first move the check if your item pointer is a nullptr above your code so your program doesn't crash. Then you'd fix up the mess with your dynamic allocated memory with your char*. Otherwise you'll soon have memory corruption if you don't free the memory or use strings.

After that, please check if the error still persists :)

  • Love 2
Link to comment
Share on other sites

 LPITEM item = ch->GetInventoryItem(bCell);

    const TItemTable * item_table = item->GetProto();

This is clearly unsecure code! What happens if the result of ch->GetInventoryItem(bCell) == nullptr?

If that is the case, then you can't execute it like a pointer!

Between those two lines you'd add:

if(nullptr == item)

  return;

Note that this also already exists in another form:

if(!item)

 return;

But it's just too late. You'd have those lines right after you initialize the item variable.

 

 

Also.. Why are you using malloc when we're in c++?

You'd change:

char * yeni = (char*) malloc(1+ strlen(item_id) + strlen(engel));

to:

char* yeni = new char(1 + strlen(item_id) + strlen(engel));

Also don't forget to run free() (c) or delete[] (c++) on dynamically allocated variables. In your case:

free(yeni);

Ooor when you use the c++ method:

delete[] yeni;

 

But you'd also forget the char chaos if we have strings here.

std::string yeni = str(item_id);

yeni.copy(engel);

That'll also do and you won't have to deal with free() or delete[].

 

 

So. What should you do? I suggest you to first move the check if your item pointer is a nullptr above your code so your program doesn't crash. Then you'd fix up the mess with your dynamic allocated memory with your char*. Otherwise you'll soon have memory corruption if you don't free the memory or use strings.

After that, please check if the error still persists :)

​i tried this nullptr but i cant compile game  nullptr not declaredi changed nullptr to NULL is it right?

and i'll use this code :

	if(item->GetType() == ITEM_WEAPON || item->GetType() == ITEM_ARMOR || item->GetType() == ITEM_BELT )
	{
		DWORD item_idd = item->GetID();
		char item_id[1000];
		sprintf(item_id, "%d", item_idd);
		const char * engel = ".Engel";
		// char * yeni = (char *) malloc(1 + strlen(item_id)+ strlen(engel) );
		char* yeni = new char(1 + strlen(item_id) + strlen(engel));
		strcpy(yeni, item_id);
		strcat(yeni, engel);
		if(item_idd != NULL and yeni != "\n" and item_id != "\n")
		{
			if (int(quest::CQuestManager::instance().GetEventFlag(yeni)) == 1)
			{
				ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("item_engel"));
				delete[] yeni;
				return;
			}
		}
	}

 

Link to comment
Share on other sites

you can change it to NULL or simply use:

if(!item)

like it's in the source ;)

https://metin2.download/picture/r3F9504x09DVmF8K988YXgTtGTP6KMUj/.gif ( game.core ) you code....

				ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("item_engel"));
				delete[] yeni;
				return;
Edited by Metin2 Dev
Core X - External 2 Internal
Link to comment
Share on other sites

  • Bronze

 LPITEM item = ch->GetInventoryItem(bCell);

    const TItemTable * item_table = item->GetProto();

This is clearly unsecure code! What happens if the result of ch->GetInventoryItem(bCell) == nullptr?

If that is the case, then you can't execute it like a pointer!

Between those two lines you'd add:

if(nullptr == item)

  return;

Note that this also already exists in another form:

if(!item)

 return;

But it's just too late. You'd have those lines right after you initialize the item variable.

 

 

Also.. Why are you using malloc when we're in c++?

You'd change:

char * yeni = (char*) malloc(1+ strlen(item_id) + strlen(engel));

to:

char* yeni = new char(1 + strlen(item_id) + strlen(engel));

Also don't forget to run free() (c) or delete[] (c++) on dynamically allocated variables. In your case:

free(yeni);

Ooor when you use the c++ method:

delete[] yeni;

 

But you'd also forget the char chaos if we have strings here.

std::string yeni = str(item_id);

yeni.copy(engel);

That'll also do and you won't have to deal with free() or delete[].

 

 

So. What should you do? I suggest you to first move the check if your item pointer is a nullptr above your code so your program doesn't crash. Then you'd fix up the mess with your dynamic allocated memory with your char*. Otherwise you'll soon have memory corruption if you don't free the memory or use strings.

After that, please check if the error still persists :)

​i tried this nullptr but i cant compile game  nullptr not declaredi changed nullptr to NULL is it right?

and i'll use this code :

	if(item->GetType() == ITEM_WEAPON || item->GetType() == ITEM_ARMOR || item->GetType() == ITEM_BELT )
	{
		DWORD item_idd = item->GetID();
		char item_id[1000];
		sprintf(item_id, "%d", item_idd);
		const char * engel = ".Engel";
		// char * yeni = (char *) malloc(1 + strlen(item_id)+ strlen(engel) );
		char* yeni = new char(1 + strlen(item_id) + strlen(engel));
		strcpy(yeni, item_id);
		strcat(yeni, engel);
		if(item_idd != NULL and yeni != "\n" and item_id != "\n")
		{
			if (int(quest::CQuestManager::instance().GetEventFlag(yeni)) == 1)
			{
				ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("item_engel"));
				delete[] yeni;
				return;
			}
		}
	}

 

​What the? I wanted to leave programming language right now. Please don't code those things.

if (item->GetType() == ITEM_WEAPON || item->GetType() == ITEM_ARMOR || item->GetType() == ITEM_BELT)
{
        char szEventFlag[30];
        snprintf(szEventFlag, sizeof(szEventFlag), "%lu.Engel", item->GetID());
        if (*szEventFlag)
        {
                if (quest::CQuestManager::instance().GetEventFlag(szEventFlag))
                {
                        ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("item_engel"));
                        return;
                }
        }
}

Kind Regards

Ken

Edited by Ken

Do not be sorry, be better.

Link to comment
Share on other sites

If you're using malloc then you have to use free() to deallocate the memory.

If you're using the c++ 'version' with new char then you only have to use the delete instruction.

delete var; //This is for simple variables without multidimensional values

delete[] var; //This is for things like arrays. Note: You're having a char array. Guess what you'll have to use then.

 

So in your case you only had to use delete[] yeni;

If you're first trying to free() it and then delete it, then you're not only misusing free() but also trying to deallocate the memory twice. You know, the memory could also have been reallocated and then you're trying to access memory you shouldn't be able to have.

 

Simplest solution, like I said, is provided by Ken. Just use a string and you won't have to deal with all that trouble.

  • Love 1
Link to comment
Share on other sites

The problem continues.
 
Ken You Code:
if (item->GetType() == ITEM_WEAPON || item->GetType() == ITEM_ARMOR || item->GetType() == ITEM_BELT) (game.core?)
{
        char szEventFlag[30];
        snprintf(szEventFlag, sizeof(szEventFlag), "%lu.Engel", item->GetID());
        if (*szEventFlag)
        {
                if (quest::CQuestManager::instance().GetEventFlag(szEventFlag))
                {
                        ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("item_engel"));
                        return;
                }
        }
}
 
GDB Results : 
 
zvLUMnZ.png
 
İtem.H  - 68 
 
ZpKYK5L.png
 
@Ken @Alina @Denis
Edited by Metin2 Dev
Core X - External 2 Internal
Link to comment
Share on other sites

please post your new

CShopManager::Sell()

function. Additionally we need the functions of  input_main.cpp at line 1094 and  3171 and input.cpp at line 102

It's seems like nullptr. Are you sure about item pointer or show CShopManager::Sell() to us.

Kind Regards

Ken

GDB Results:

zvLUMnZ.png

Shop_Manager.CPP/Sell: Functions

void CShopManager::Sell(LPCHARACTER ch, BYTE bCell, BYTE bCount)
{
	if (!ch->GetShop())
		return;

	if (!ch->GetShopOwner())
		return;

	if (!ch->CanHandleItem())
		return;

	if (ch->GetShop()->IsPCShop())
		return;

	if (DISTANCE_APPROX(ch->GetX()-ch->GetShopOwner()->GetX(), ch->GetY()-ch->GetShopOwner()->GetY())>2000)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상점과의 거리가 너무 멀어 물건을 팔 수 없습니다."));
		return;
	}
	
	LPITEM item = ch->GetInventoryItem(bCell);
    // special code (Ken) //
	if (item->GetType() == ITEM_WEAPON || item->GetType() == ITEM_ARMOR || item->GetType() == ITEM_BELT)
	{
			char szEventFlag[30];
			snprintf(szEventFlag, sizeof(szEventFlag), "%d.Engel", item->GetID());
			if (*szEventFlag)
			{
					if (quest::CQuestManager::instance().GetEventFlag(szEventFlag))
					{
							ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("item_engel"));
							return;
					}
			}
	}
    // special code (Ken) //
	
	if (!item)
		return;

	if (item->IsEquipped() == true)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("착용 중인 아이템은 판매할 수 없습니다."));
		return;
	}

	if (true == item->isLocked())
	{
		return;
	}

	if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_SELL))
		return;

	DWORD dwPrice;

	if (bCount == 0 || bCount > item->GetCount())
		bCount = item->GetCount();
	
	dwPrice = item->GetShopBuyPrice();

	if (IS_SET(item->GetFlag(), ITEM_FLAG_COUNT_PER_1GOLD))
	{
		if (dwPrice == 0)
			dwPrice = bCount;
		else
			dwPrice = bCount / dwPrice;
	}
	else
		dwPrice *= bCount;

	dwPrice /= 5;
	
	//세금 계산
	DWORD dwTax = 0;
	int iVal = 0;
	
	if (LC_IsYMIR() ||  LC_IsKorea())
	{
		dwTax = dwPrice * iVal / 100;
		dwPrice -= dwTax;
	}
	else
	{
		dwTax = dwPrice * iVal/100;
		dwPrice -= dwTax;
	}

	if (test_server)
		sys_log(0, "Sell Item price id %d %s itemid %d", ch->GetPlayerID(), ch->GetName(), item->GetID());

	const int64_t nTotalMoney = static_cast<int64_t>(ch->GetGold()) + static_cast<int64_t>(dwPrice);

	if (GOLD_MAX <= nTotalMoney)
	{
		sys_err("[OVERFLOW_GOLD] id %u name %s gold %u", ch->GetPlayerID(), ch->GetName(), ch->GetGold());
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("20억냥이 초과하여 물품을 팔수 없습니다."));
		return;
	}

	// 20050802.myevan.상점 판매 로그에 아이템 ID 추가
	sys_log(0, "SHOP: SELL: %s item name: %s(x%d):%u price: %u", ch->GetName(), item->GetName(), bCount, item->GetID(), dwPrice);

	if (iVal > 0)
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("판매금액의 %d %% 가 세금으로 나가게됩니다"), iVal);

	DBManager::instance().SendMoneyLog(MONEY_LOG_SHOP, item->GetVnum(), dwPrice);

	if (bCount == item->GetCount())
	{
		// 한국에는 아이템을 버리고 복구해달라는 진상유저들이 많아서
		// 상점 판매시 속성로그를 남긴다.
		if (LC_IsYMIR())
			item->AttrLog();

		ITEM_MANAGER::instance().RemoveItem(item, "SELL");
	}
	else
		item->SetCount(item->GetCount() - bCount);

	//군주 시스템 : 세금 징수
	CMonarch::instance().SendtoDBAddMoney(dwTax, ch->GetEmpire(), ch);

	ch->PointChange(POINT_GOLD, dwPrice, false);
}

İtem.H/68;

imzmAZ7.png

 

İnput_Main.CPP/1094 : 

QNwSdue.png

İnput_Main.CPP/3171:

S39p6XZ.png

İnput.CPP/102:

waEMXNA.png

Edited by Metin2 Dev
Core X - External 2 Internal
Link to comment
Share on other sites

why didn't you move

if(!item)

  return;

above ken's code as we suggested earlier? :D You'd move that a top of his code and then the nullpointer error won't occur anymore.

    // special code (Ken) //
	if (item->GetType() == ITEM_WEAPON || item->GetType() == ITEM_ARMOR || item->GetType() == ITEM_BELT)
	{
			char szEventFlag[30];
			snprintf(szEventFlag, sizeof(szEventFlag), "%d.Engel", item->GetID());
			if (*szEventFlag)
			{
					if (quest::CQuestManager::instance().GetEventFlag(szEventFlag))
					{
							ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("item_engel"));
							return;
					}
			}
	}
    // special code (Ken) //
Link to comment
Share on other sites

void CShopManager::Sell(LPCHARACTER ch, BYTE bCell, BYTE bCount)
{
	if (!ch->GetShop())
		return;

	if (!ch->GetShopOwner())
		return;

	if (!ch->CanHandleItem())
		return;

	if (ch->GetShop()->IsPCShop())
		return;

	if (DISTANCE_APPROX(ch->GetX()-ch->GetShopOwner()->GetX(), ch->GetY()-ch->GetShopOwner()->GetY())>2000)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상점과의 거리가 너무 멀어 물건을 팔 수 없습니다."));
		return;
	}
    
	LPITEM item = ch->GetInventoryItem(bCell);
    
        if(!item)
            return;
    
    // special code (Ken) //
	if (item->GetType() == ITEM_WEAPON || item->GetType() == ITEM_ARMOR || item->GetType() == ITEM_BELT)
	{
			char szEventFlag[30];
			snprintf(szEventFlag, sizeof(szEventFlag), "%d.Engel", item->GetID());
			if (*szEventFlag)
			{
					if (quest::CQuestManager::instance().GetEventFlag(szEventFlag))
					{
							ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("item_engel"));
							return;
					}
			}
	}
    // special code (Ken) //

	if (item->IsEquipped() == true)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("착용 중인 아이템은 판매할 수 없습니다."));
		return;
	}

	if (true == item->isLocked())
	{
		return;
	}

	if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_SELL))
		return;

	DWORD dwPrice;

	if (bCount == 0 || bCount > item->GetCount())
		bCount = item->GetCount();
	
	dwPrice = item->GetShopBuyPrice();

	if (IS_SET(item->GetFlag(), ITEM_FLAG_COUNT_PER_1GOLD))
	{
		if (dwPrice == 0)
			dwPrice = bCount;
		else
			dwPrice = bCount / dwPrice;
	}
	else
		dwPrice *= bCount;

	dwPrice /= 5;
	
	//세금 계산
	DWORD dwTax = 0;
	int iVal = 0;
	
	if (LC_IsYMIR() ||  LC_IsKorea())
	{
		dwTax = dwPrice * iVal / 100;
		dwPrice -= dwTax;
	}
	else
	{
		dwTax = dwPrice * iVal/100;
		dwPrice -= dwTax;
	}

	if (test_server)
		sys_log(0, "Sell Item price id %d %s itemid %d", ch->GetPlayerID(), ch->GetName(), item->GetID());

	const int64_t nTotalMoney = static_cast<int64_t>(ch->GetGold()) + static_cast<int64_t>(dwPrice);

	if (GOLD_MAX <= nTotalMoney)
	{
		sys_err("[OVERFLOW_GOLD] id %u name %s gold %u", ch->GetPlayerID(), ch->GetName(), ch->GetGold());
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("20억냥이 초과하여 물품을 팔수 없습니다."));
		return;
	}

	// 20050802.myevan.상점 판매 로그에 아이템 ID 추가
	sys_log(0, "SHOP: SELL: %s item name: %s(x%d):%u price: %u", ch->GetName(), item->GetName(), bCount, item->GetID(), dwPrice);

	if (iVal > 0)
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("판매금액의 %d %% 가 세금으로 나가게됩니다"), iVal);

	DBManager::instance().SendMoneyLog(MONEY_LOG_SHOP, item->GetVnum(), dwPrice);

	if (bCount == item->GetCount())
	{
		// 한국에는 아이템을 버리고 복구해달라는 진상유저들이 많아서
		// 상점 판매시 속성로그를 남긴다.
		if (LC_IsYMIR())
			item->AttrLog();

		ITEM_MANAGER::instance().RemoveItem(item, "SELL");
	}
	else
		item->SetCount(item->GetCount() - bCount);

	//군주 시스템 : 세금 징수
	CMonarch::instance().SendtoDBAddMoney(dwTax, ch->GetEmpire(), ch);

	ch->PointChange(POINT_GOLD, dwPrice, false);
}

 

This is your fixed function.

Edited by Alina
  • Love 1
Link to comment
Share on other sites

void CShopManager::Sell(LPCHARACTER ch, BYTE bCell, BYTE bCount)
{
	if (!ch->GetShop())
		return;

	if (!ch->GetShopOwner())
		return;

	if (!ch->CanHandleItem())
		return;

	if (ch->GetShop()->IsPCShop())
		return;

	if (DISTANCE_APPROX(ch->GetX()-ch->GetShopOwner()->GetX(), ch->GetY()-ch->GetShopOwner()->GetY())>2000)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("상점과의 거리가 너무 멀어 물건을 팔 수 없습니다."));
		return;
	}
    
	LPITEM item = ch->GetInventoryItem(bCell);
    
        if(!item)
            return;
    
    // special code (Ken) //
	if (item->GetType() == ITEM_WEAPON || item->GetType() == ITEM_ARMOR || item->GetType() == ITEM_BELT)
	{
			char szEventFlag[30];
			snprintf(szEventFlag, sizeof(szEventFlag), "%d.Engel", item->GetID());
			if (*szEventFlag)
			{
					if (quest::CQuestManager::instance().GetEventFlag(szEventFlag))
					{
							ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("item_engel"));
							return;
					}
			}
	}
    // special code (Ken) //

	if (item->IsEquipped() == true)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("착용 중인 아이템은 판매할 수 없습니다."));
		return;
	}

	if (true == item->isLocked())
	{
		return;
	}

	if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_SELL))
		return;

	DWORD dwPrice;

	if (bCount == 0 || bCount > item->GetCount())
		bCount = item->GetCount();
	
	dwPrice = item->GetShopBuyPrice();

	if (IS_SET(item->GetFlag(), ITEM_FLAG_COUNT_PER_1GOLD))
	{
		if (dwPrice == 0)
			dwPrice = bCount;
		else
			dwPrice = bCount / dwPrice;
	}
	else
		dwPrice *= bCount;

	dwPrice /= 5;
	
	//세금 계산
	DWORD dwTax = 0;
	int iVal = 0;
	
	if (LC_IsYMIR() ||  LC_IsKorea())
	{
		dwTax = dwPrice * iVal / 100;
		dwPrice -= dwTax;
	}
	else
	{
		dwTax = dwPrice * iVal/100;
		dwPrice -= dwTax;
	}

	if (test_server)
		sys_log(0, "Sell Item price id %d %s itemid %d", ch->GetPlayerID(), ch->GetName(), item->GetID());

	const int64_t nTotalMoney = static_cast<int64_t>(ch->GetGold()) + static_cast<int64_t>(dwPrice);

	if (GOLD_MAX <= nTotalMoney)
	{
		sys_err("[OVERFLOW_GOLD] id %u name %s gold %u", ch->GetPlayerID(), ch->GetName(), ch->GetGold());
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("20억냥이 초과하여 물품을 팔수 없습니다."));
		return;
	}

	// 20050802.myevan.상점 판매 로그에 아이템 ID 추가
	sys_log(0, "SHOP: SELL: %s item name: %s(x%d):%u price: %u", ch->GetName(), item->GetName(), bCount, item->GetID(), dwPrice);

	if (iVal > 0)
		ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("판매금액의 %d %% 가 세금으로 나가게됩니다"), iVal);

	DBManager::instance().SendMoneyLog(MONEY_LOG_SHOP, item->GetVnum(), dwPrice);

	if (bCount == item->GetCount())
	{
		// 한국에는 아이템을 버리고 복구해달라는 진상유저들이 많아서
		// 상점 판매시 속성로그를 남긴다.
		if (LC_IsYMIR())
			item->AttrLog();

		ITEM_MANAGER::instance().RemoveItem(item, "SELL");
	}
	else
		item->SetCount(item->GetCount() - bCount);

	//군주 시스템 : 세금 징수
	CMonarch::instance().SendtoDBAddMoney(dwTax, ch->GetEmpire(), ch);

	ch->PointChange(POINT_GOLD, dwPrice, false);
}

 

This is your fixed function.

I'm testing Alina.
I'll let you know.
Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.