Jump to content

Recommended Posts

Hello, I'm back with the problem related to selling to NPCs.

To explain again, I added special inventory on the K key, it works perfectly and i can sell items to NPC, then I extended the item stack from 200 to 2000 and that works perfectly but now I can't sell to NPCs anymore, when I try to sell to NPCs something disconnects me from the server at the login page.

Initially I thought it was from the client but I was wrong, it seems the problem is from the server side.

After other tests I tend to believe that the problem is coming from input_main.cpp more precisely from the function  int CInputMain::Shop(LPCHARACTER ch, const char * data, size_t uiBytes) 

In this file I modified as follows:
 

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

				TfckOFF*p2 = (TfckOFF*)c_pData;
				const WORD wPos = *reinterpret_cast<const WORD*>(c_pData);
				const BYTE bCount = *(c_pData + sizeof(WORD));
				const BYTE bType = *(c_pData + sizeof(WORD) + sizeof(BYTE));

				sys_log(0, "INPUT: %s SHOP: SELL2", ch->GetName());

				CShopManager::instance().Sell(ch, wPos, p2->bySlot, p2->byCount);
				return sizeof(WORD) + sizeof(BYTE) + sizeof(BYTE);
			}

 

I've tried different adaptations for SHOP_SUBHEADER_CG_SELL2: but none of them work.

In one case I have to sell an item several times to be disconnected.
In another case, as soon as I sell an item I'm disconnected.
In another case, it doesn't disconnect me at all, but I can't sell anything either, basically nothing happens...

I've tried to get this piece of code from another serverfile but I haven't found anything that works so far...

This is case SHOP_SUBHEADER_CG_SELL2:  after I add specila inventory and the FIX to be able to sell items to NPC:
 

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

				const WORD wPos = *reinterpret_cast<const WORD*>(c_pData);
				const BYTE bCount = *(c_pData + sizeof(WORD));
				const BYTE bType = *(c_pData + sizeof(WORD) + sizeof(BYTE));

				sys_log(0, "INPUT: %s SHOP: SELL2", ch->GetName());

				CShopManager::instance().Sell(ch, wPos, bCount, bType);
				return sizeof(WORD) + sizeof(BYTE) + sizeof(BYTE);
			}

This is case SHOP_SUBHEADER_CG_SELL2:  after I add extended stack items and in installation tutorial it's ask me to change it as follow:

Spoiler
		case SHOP_SUBHEADER_CG_SELL2:
			{
				if (uiBytes < sizeof(TfckOFF))
					return -1;
				TfckOFF*p2 = (TfckOFF*)c_pData;
				/*BYTE pos = *(c_pData++);
				WORD count = *(c_pData);*/

				sys_log(0, "INPUT: %s SHOP: SELL2", ch->GetName());
				CShopManager::instance().Sell(ch, p2->bySlot, p2->byCount);
				return sizeof(TfckOFF);
			}

And finally this is my result when i try to merge them:
 

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

				TfckOFF*p2 = (TfckOFF*)c_pData;
				const WORD wPos = *reinterpret_cast<const WORD*>(c_pData);
				const WORD bCount = *(c_pData + sizeof(WORD));
				const BYTE bType = *(c_pData + sizeof(WORD) + sizeof(BYTE));

				sys_log(0, "INPUT: %s SHOP: SELL2", ch->GetName());

				CShopManager::instance().Sell(ch, wPos, p2->bySlot, p2->byCount);
				return sizeof(WORD) + sizeof(BYTE) + sizeof(BYTE);
			}


None of them works.

NOTE: Serverfile is TMP4 if needed.

  • muscle 1
  • Love 1
Link to comment
https://metin2.dev/topic/33808-sell-to-npc/
Share on other sites

  • Premium

Drop the manual passing through the data to not get confused, use the same struct instead, both on client and server:

 

// Server: input_main.cpp -> int CInputMain::Shop

		case SHOP_SUBHEADER_CG_SELL2:
		{
			const TPacketCGShopSell* p = reinterpret_cast<const TPacketCGShopSell*>(c_pData);

			sys_log(0, "INPUT: %s SHOP: SELL2", ch->GetName());

			CShopManager::instance().Sell(ch, p->wPos, p->wCount, p->bType);
			return sizeof(TPacketCGShopSell);
		}

// Server & Client: packet.h

typedef struct command_shop_sell
{
	WORD wPos;
	WORD wCount;
	BYTE bType;
} TPacketCGShopSell;

// Client: PythonNetworkStreamPhaseGameItem.cpp

bool CPythonNetworkStream::SendShopSellPacketNew(WORD wSlot, WORD wCount, BYTE byType)
{
	if (!__CanActMainInstance())
		return true;

	TPacketCGShop PacketShop;
	PacketShop.header = HEADER_CG_SHOP;
	PacketShop.subheader = SHOP_SUBHEADER_CG_SELL2;

	if (!Send(sizeof(TPacketCGShop), &PacketShop))
	{
		Tracef("PacketCGShop Error\n");
		return false;
	}

	TPacketCGShopSell SellPacket;
	SellPacket.bType = byType;
	SellPacket.wCount = wCount;
	SellPacket.wPos = wSlot;
	
	if (!Send(sizeof(TPacketCGShopSell), &SellPacket))
	{
		Tracef("PacketCGShopSell Error\n");
		return false;
	}

	Tracef(" SendShopSellPacketNew(wSlot=%d, byCount=%d, byType=%d)\n", wSlot, wCount, byType);

	return SendSequence();
}

// Client: PythonNetworkStreamModule.cpp

PyObject* netSendShopSellPacketNew(PyObject* poSelf, PyObject* poArgs)
{
	int iSlotNumber;
	if (!PyTuple_GetInteger(poArgs, 0, &iSlotNumber))
		return Py_BuildException();
	int iCount;
	if (!PyTuple_GetInteger(poArgs, 1, &iCount))
		return Py_BuildException();
	int iType;
	if (!PyTuple_GetInteger(poArgs, 2, &iType))
		return Py_BuildException();

	CPythonNetworkStream& rkNetStream = CPythonNetworkStream::Instance();
	rkNetStream.SendShopSellPacketNew(iSlotNumber, iCount, iType);
	return Py_BuildNone();
}

[...]

void initnet()
{
	static PyMethodDef s_methods[] =
	{

[...]

		{ "SendShopSellPacketNew", netSendShopSellPacketNew, METH_VARARGS },

[...]

		{ NULL, NULL, NULL },
	};


And double-check the way you're calling the function from python, make sure to pass the correct inventory type inside iType

Link to comment
https://metin2.dev/topic/33808-sell-to-npc/#findComment-171288
Share on other sites

Don't use any images from : imgur, turkmmop, freakgamers, inforge, hizliresim... Or your content will be deleted without notice...
Use : https://metin2.download/media/add/

Please use https://metin2.download/ when uploading files smaller than 100MB, otherwise the approval will take longer due to manual upload.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • 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.