Jump to content

Recommended Posts

  • 1 month later...
On 6/13/2021 at 12:37 PM, Exille said:

Hi, I have a little problem. The system works, but when the server is restarted, all players in the database get -1077945576 check. You can help? Where could the error be?

Check one more time all changes what you have done in *(serve/db/src) ClientMagagerPlayer.cpp

I think you have done something wrong.

Link to comment
Share on other sites

  • 1 month later...

Can someone who installed this paste theyr ClientManagerPlayer.cpp?

How in seven hells are you supposed to add this part?

/*Search in:
void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoadPacket * packet)

This:
												"horse_skill_point "

Add after:
*/
#ifdef ENABLE_CHEQUE_SYSTEM
												", cheque "
#endif
/*--------------------------------------------------*/

It just does not make any sense. (for me maybe)

Here is the way I did it and I get a bunch of compilation errors.

snprintf(queryStr, sizeof(queryStr),
				"SELECT "
				"id,name,job,voice,dir,x,y,z,map_index,exit_x,exit_y,exit_map_index,hp,mp,stamina,random_hp,random_sp,playtime,"
				"gold,level,level_step,st,ht,dx,iq,exp,"
				"stat_point,skill_point,sub_skill_point,stat_reset_count,part_base,part_hair,"
				"skill_level,quickslot,skill_group,alignment,mobile,horse_level,horse_riding,horse_hp,horse_hp_droptime,horse_stamina,"
				"UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(last_play),horse_skill_point FROM player%s WHERE id=%d",
#ifdef ENABLE_CHEQUE_SYSTEM
			", cheque "
#endif
				GetTablePostfix(), packet->player_id);

How did you guys do it?

Edited by narcisxb
Link to comment
Share on other sites

  • Contributor
5 minutes ago, narcisxb said:

Can someone who installed this paste theyr ClientManagerPlayer.cpp?

How in seven hells are you supposed to add this part?

/*Search in:
void CClientManager::QUERY_PLAYER_LOAD(CPeer * peer, DWORD dwHandle, TPlayerLoadPacket * packet)

This:
												"horse_skill_point "

Add after:
*/
#ifdef ENABLE_CHEQUE_SYSTEM
												", cheque "
#endif
/*--------------------------------------------------*/

It just does not make any sense. (for me maybe)

Here is the way I did it and I get a bunch of compilation errors.

snprintf(queryStr, sizeof(queryStr),
				"SELECT "
				"id,name,job,voice,dir,x,y,z,map_index,exit_x,exit_y,exit_map_index,hp,mp,stamina,random_hp,random_sp,playtime,"
				"gold,level,level_step,st,ht,dx,iq,exp,"
				"stat_point,skill_point,sub_skill_point,stat_reset_count,part_base,part_hair,"
				"skill_level,quickslot,skill_group,alignment,mobile,horse_level,horse_riding,horse_hp,horse_hp_droptime,horse_stamina,"
				"UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(last_play),horse_skill_point FROM player%s WHERE id=%d",
#ifdef ENABLE_CHEQUE_SYSTEM
			", cheque "
#endif
				GetTablePostfix(), packet->player_id);

How did you guys do it?

Try this:

snprintf(queryStr, sizeof(queryStr),
				"SELECT "
				"id,name,job,voice,dir,x,y,z,map_index,exit_x,exit_y,exit_map_index,hp,mp,stamina,random_hp,random_sp,playtime,"
				"gold,level,level_step,st,ht,dx,iq,exp,"
				"stat_point,skill_point,sub_skill_point,stat_reset_count,part_base,part_hair,"
				"skill_level,quickslot,skill_group,alignment,mobile,horse_level,horse_riding,horse_hp,horse_hp_droptime,horse_stamina,"
				"UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(last_play),horse_skill_point"
#ifdef ENABLE_CHEQUE_SYSTEM
			", cheque"
#endif
				" FROM player%s WHERE id=%d",
				GetTablePostfix(), packet->player_id);

 

Edited by TMP4
  • Good 1
Link to comment
Share on other sites

2 minutes ago, TMP4 said:

Try this:

snprintf(queryStr, sizeof(queryStr),
				"SELECT "
				"id,name,job,voice,dir,x,y,z,map_index,exit_x,exit_y,exit_map_index,hp,mp,stamina,random_hp,random_sp,playtime,"
				"gold,level,level_step,st,ht,dx,iq,exp,"
				"stat_point,skill_point,sub_skill_point,stat_reset_count,part_base,part_hair,"
				"skill_level,quickslot,skill_group,alignment,mobile,horse_level,horse_riding,horse_hp,horse_hp_droptime,horse_stamina,"
				"UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(last_play),horse_skill_point"
#ifdef ENABLE_CHEQUE_SYSTEM
			", cheque "
#endif
"FROM player%s WHERE id=%d"
				,GetTablePostfix(), packet->player_id);

 

It still makes 0 sense. Why would you use quote marks around , and cheque?

I will give it a try tho. Thx!

Edited by narcisxb
Link to comment
Share on other sites

I managed to get past db, but now I got a new game compilation error.  It reads as follows:

 

char.cpp:3373:23: use of undeclared identifier 'nTotalCheque'

Thing is I have this variable defined beforehand but it is inside the preprocessor directive. Any help would be greatly appreciated.

Here it s the way it s defined:

	int64_t nTotalMoney = 0;
	#ifdef ENABLE_CHEQUE_SYSTEM
	int64_t nTotalCheque = 0;
	#endif

EDIT: SOLVED. 

Edited by narcisxb
issue was solved
Link to comment
Share on other sites

  • Management
1 minute ago, narcisxb said:

Where do I put the data from ¨CommonDefines.h¨ if I don t have a file named like that in my src/common folder? Also do you compile common or just edit stuff in there? (sorry fore dumb ass questions, I m a newbie to all of this)

Service.h === CommonDefines.h

  • Good 1
Link to comment
Share on other sites

5 minutes ago, ασικοο said:

Service.h === CommonDefines.h

ok, but what am I missing? I did everything and my server now won t let me connect to it. It worked just fine before this. Now I get an error when typing in correct account and a ¨user or pwd is wrong¨ when typing in wrong login data. Also why my cheque code won t highlight the right way (it s like cheque_system is not enabled). What do I do wrong? Does common get compiled or I just edit stuff in there and it gets read or linked at some point during game/db compilation?

 

EDIT: it also worked fine before adding the code to the server source (client and client binary part was fine).

 

Edited by narcisxb
Link to comment
Share on other sites

6 hours ago, narcisxb said:

ok, but what am I missing? I did everything and my server now won t let me connect to it. It worked just fine before this. Now I get an error when typing in correct account and a ¨user or pwd is wrong¨ when typing in wrong login data. Also why my cheque code won t highlight the right way (it s like cheque_system is not enabled). What do I do wrong? Does common get compiled or I just edit stuff in there and it gets read or linked at some point during game/db compilation?

 

EDIT: it also worked fine before adding the code to the server source (client and client binary part was fine).

 

Check one more time in surce/db/src - ClientManagerPlayer.cpp / 

Im thinking you have just miss a part or you have doing wrong. + ProtoReader.cpp and to the end you need to have the colum *Won* on your navicat you need to run the sql file from the arhive.

Link to comment
Share on other sites

2 minutes ago, Rokco said:

Check one more time in surce/db/src - ClientManagerPlayer.cpp / 

Im thinking you have just miss a part or you have doing wrong. + ProtoReader.cpp and to the end you need to have the colum *Won* on your navicat you need to run the sql file from the arhive.

I did and I managed to get the server started but only if I deleted the preprocessor directive (ifdef) from tables.h variables. If I use with directive I m getting a db compile error saying that my variables are missing from SPlayerTable (a struct that contains DWORD cheque). Any ideea?

Link to comment
Share on other sites

1 hour ago, narcisxb said:

I did and I managed to get the server started but only if I deleted the preprocessor directive (ifdef) from tables.h variables. If I use with directive I m getting a db compile error saying that my variables are missing from SPlayerTable (a struct that contains DWORD cheque). Any ideea?

Go back in Tables.h and check for the line 

typedef struct SPlayerTable

{


After(    short    horse_skill_point;) ADD:
    #ifdef ENABLE_CHEQUE_SYSTEM
    int        cheque;
    #endif
----------------------------------------------------------
After that check

typedef struct SShopItemTable
{

After (    DWORD        price;)

#ifdef ENABLE_CHEQUE_SYSTEM
    DWORD        cheque;
#endif

Link to comment
Share on other sites

16 hours ago, Rokco said:

Go back in Tables.h and check for the line 

typedef struct SPlayerTable

{


After(    short    horse_skill_point;) ADD:
    #ifdef ENABLE_CHEQUE_SYSTEM
    int        cheque;
    #endif
----------------------------------------------------------
After that check

typedef struct SShopItemTable
{

After (    DWORD        price;)

#ifdef ENABLE_CHEQUE_SYSTEM
    DWORD        cheque;
#endif

If I add #ifdef ENABLE_CHEQUE_SYSTEM I get this error when I compile db:

ClientManagerPlayer.cpp:165:12: error: no member named 'cheque' in SPlayerTable' ,pkTab-cheque
ClietnManagerPlayer.cpp:536:23: erro: no member named 'cheque' in SPlayerTable' str_to_number(pkTab-»cheque, rowăcol++])

If I do it without the #ifdef I don t get the error? Why?

I have ENABLE_CHEQUE_SYSTEM defined in my Service.h file in common. 

Link to comment
Share on other sites

23 hours ago, narcisxb said:

If I add #ifdef ENABLE_CHEQUE_SYSTEM I get this error when I compile db:

ClientManagerPlayer.cpp:165:12: error: no member named 'cheque' in SPlayerTable' ,pkTab-cheque
ClietnManagerPlayer.cpp:536:23: erro: no member named 'cheque' in SPlayerTable' str_to_number(pkTab-»cheque, rowăcol++])

If I do it without the #ifdef I don t get the error? Why?

I have ENABLE_CHEQUE_SYSTEM defined in my Service.h file in common. 

 

Check if you have put all import's for exemple ((( Table.h = #include "service.h" )))

ClientManagerPlayer.cpp   =    #include "../../common/service.h"

Edited by Rokco
Link to comment
Share on other sites

3 hours ago, Rokco said:

 

Check if you have put all import's for exemple ((( Table.h = #include "service.h" )))

ClientManagerPlayer.cpp   =    #include "../../common/service.h"

I don t have #include "service.h" in any of those files. Should I add it to every source file I modified? I don t think I have it in game source files either. 

Edited by narcisxb
Link to comment
Share on other sites

I got it to work finally, but no matter what I did you can t use won in shop. You will be able to buy things for normal (pc_shops) without paying wons. It works fine for yang but won won t work.

Ex: If I ve got 10 wons and I buy something worth 1 won from a shop it won t take 1 won from me.

or

If something is sold for 10 wons and I only got 1 won I can buy the item from the shop and IT WON T TAKE MY 1 WON at all let alone tell me that I m 9 wons short of the selling price.

I saw this problem above - and OP said it solved it - but seems that it is not solved. This is a MAJOR BUG. 

Another issue: after I drop some Wons they won t show up on the ground like yangs. 

Everything else seems to work, exchange quest, trades, they seem to go fine.

Any takes on these issues?

Here is my shop.cpp:

#include "stdafx.h"
#include "../../libgame/include/grid.h"
#include "constants.h"
#include "utils.h"
#include "config.h"
#include "shop.h"
#include "desc.h"
#include "desc_manager.h"
#include "char.h"
#include "char_manager.h"
#include "item.h"
#include "item_manager.h"
#include "buffer_manager.h"
#include "packet.h"
#include "log.h"
#include "db.h"
#include "questmanager.h"
#include "monarch.h"
#include "mob_manager.h"
#include "locale_service.h"
#include "../../common/service.h"

/* ------------------------------------------------------------------------------------ */
CShop::CShop()
	: m_dwVnum(0), m_dwNPCVnum(0), m_pkPC(NULL)
{
	m_pGrid = M2_NEW CGrid(5, 9);
}

CShop::~CShop()
{
	TPacketGCShop pack;

	pack.header		= HEADER_GC_SHOP;
	pack.subheader	= SHOP_SUBHEADER_GC_END;
	pack.size		= sizeof(TPacketGCShop);

	Broadcast(&pack, sizeof(pack));

	GuestMapType::iterator it;

	it = m_map_guest.begin();

	while (it != m_map_guest.end())
	{
		LPCHARACTER ch = it->first;
		ch->SetShop(NULL);
		++it;
	}

	M2_DELETE(m_pGrid);
}

void CShop::SetPCShop(LPCHARACTER ch)
{
	m_pkPC = ch;
}

#ifdef ENABLE_PRIVATE_SHOP_AUTO_CLOSE
bool CShop::IsSoldOut() const
{
	for (size_t i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
	{
		const SHOP_ITEM& r_item = m_itemVector[i];
		if (r_item.pkItem)
			return false;
	}
	return true;
}
#endif

bool CShop::Create(DWORD dwVnum, DWORD dwNPCVnum, TShopItemTable * pTable)
{
	/*
	   if (NULL == CMobManager::instance().Get(dwNPCVnum))
	   {
	   sys_err("No such a npc by vnum %d", dwNPCVnum);
	   return false;
	   }
	 */
	sys_log(0, "SHOP #%d (Shopkeeper %d)", dwVnum, dwNPCVnum);

	m_dwVnum = dwVnum;
	m_dwNPCVnum = dwNPCVnum;

	BYTE bItemCount;

	for (bItemCount = 0; bItemCount < SHOP_HOST_ITEM_MAX_NUM; ++bItemCount)
		if (0 == (pTable + bItemCount)->vnum)
			break;

	SetShopItems(pTable, bItemCount);
	return true;
}

void CShop::SetShopItems(TShopItemTable * pTable, BYTE bItemCount)
{
	if (bItemCount > SHOP_HOST_ITEM_MAX_NUM)
		return;

	m_pGrid->Clear();

	m_itemVector.resize(SHOP_HOST_ITEM_MAX_NUM);
	memset(&m_itemVector[0], 0, sizeof(SHOP_ITEM) * m_itemVector.size());

	for (int i = 0; i < bItemCount; ++i)
	{
		LPITEM pkItem = NULL;
		const TItemTable * item_table;

		if (m_pkPC)
		{
			pkItem = m_pkPC->GetItem(pTable->pos);

			if (!pkItem)
			{
				sys_err("cannot find item on pos (%d, %d) (name: %s)", pTable->pos.window_type, pTable->pos.cell, m_pkPC->GetName());
				continue;
			}

			item_table = pkItem->GetProto();
		}
		else
		{
			if (!pTable->vnum)
				continue;

			item_table = ITEM_MANAGER::instance().GetTable(pTable->vnum);
		}

		if (!item_table)
		{
			sys_err("Shop: no item table by item vnum #%d", pTable->vnum);
			continue;
		}

		int iPos;

		if (IsPCShop())
		{
			sys_log(0, "MyShop: use position %d", pTable->display_pos);
			iPos = pTable->display_pos;
		}
		else
			iPos = m_pGrid->FindBlank(1, item_table->bSize);

		if (iPos < 0)
		{
			sys_err("not enough shop window");
			continue;
		}

		if (!m_pGrid->IsEmpty(iPos, 1, item_table->bSize))
		{
			if (IsPCShop())
			{
				sys_err("not empty position for pc shop %s[%d]", m_pkPC->GetName(), m_pkPC->GetPlayerID());
			}
			else
			{
				sys_err("not empty position for npc shop");
			}
			continue;
		}

		m_pGrid->Put(iPos, 1, item_table->bSize);

		SHOP_ITEM & item = m_itemVector[iPos];

		item.pkItem = pkItem;
		item.itemid = 0;

		if (item.pkItem)
		{
			item.vnum = pkItem->GetVnum();
			item.count = pkItem->GetCount(); // PC ¼¥ÀÇ °æ¿ì ¾ÆÀÌÅÛ °³¼ö´Â ÁøÂ¥ ¾ÆÀÌÅÛÀÇ °³¼ö¿©¾ß ÇÑ´Ù.
			item.price = pTable->price; // °¡°Ýµµ »ç¿ëÀÚ°¡ Á¤ÇÑ´ë·Î..
			item.itemid	= pkItem->GetID();
			#ifdef ENABLE_CHEQUE_SYSTEM
			item.cheque = pTable->cheque;
			#endif
		}
		else
		{
			item.vnum = pTable->vnum;
			item.count = pTable->count;

			if (IS_SET(item_table->dwFlags, ITEM_FLAG_COUNT_PER_1GOLD))
			{
				if (item_table->dwGold == 0)
					item.price = item.count;
				else
					item.price = item.count / item_table->dwGold;
			}
			else
			{	item.price = item_table->dwGold * item.count;
				#ifdef ENABLE_CHEQUE_SYSTEM
				item.cheque = 0;
				#endif
			}
		}

		char name[36];
		snprintf(name, sizeof(name), "%-20s(#%-5d) (x %d)", item_table->szName, (int) item.vnum, item.count);

		sys_log(0, "SHOP_ITEM: %-36s PRICE %-5d", name, item.price);
		++pTable;
	}
}

int CShop::Buy(LPCHARACTER ch, BYTE pos)
{
	if (pos >= m_itemVector.size())
	{
		sys_log(0, "Shop::Buy : invalid position %d : %s", pos, ch->GetName());
		return SHOP_SUBHEADER_GC_INVALID_POS;
	}

	sys_log(0, "Shop::Buy : name %s pos %d", ch->GetName(), pos);

	GuestMapType::iterator it = m_map_guest.find(ch);

	if (it == m_map_guest.end())
		return SHOP_SUBHEADER_GC_END;

	SHOP_ITEM& r_item = m_itemVector[pos];

	// if (r_item.price <= 0)
	if (r_item.price < 0) // Fix
	{
		LogManager::instance().HackLog("SHOP_BUY_GOLD_OVERFLOW", ch);
		return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY;
	}
	
	#ifdef ENABLE_SHOP_USE_CHEQUE
	if (r_item.cheque < 0)
	{
		LogManager::instance().HackLog("SHOP_BUY_CHEQUE_OVERFLOW", ch);
		return SHOP_SUBHEADER_GC_NOT_ENOUGH_CHEQUE;
	}
	#endif

	LPITEM pkSelectedItem = ITEM_MANAGER::instance().Find(r_item.itemid);

	if (IsPCShop())
	{
		if (!pkSelectedItem)
		{
			sys_log(0, "Shop::Buy : Critical: This user seems to be a hacker : invalid pcshop item : BuyerPID:%d SellerPID:%d",
					ch->GetPlayerID(),
					m_pkPC->GetPlayerID());

			return false;
		}

		if ((pkSelectedItem->GetOwner() != m_pkPC))
		{
			sys_log(0, "Shop::Buy : Critical: This user seems to be a hacker : invalid pcshop item : BuyerPID:%d SellerPID:%d",
					ch->GetPlayerID(),
					m_pkPC->GetPlayerID());

			return false;
		}
	}

	DWORD dwPrice = r_item.price;
	#ifdef ENABLE_SHOP_USE_CHEQUE
	DWORD dwCheque = r_item.cheque;
	#endif

	if (it->second)	// if other empire, price is triple
		dwPrice *= 3;

	//#ifdef ENABLE_SHOP_USE_CHEQUE
	if ((int)dwPrice>0 && (int)dwCheque > 0) // Yang-Cheque
	{
		if (ch->GetGold() < (int)dwPrice || ch->GetCheque() < (int)dwCheque)
			return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY_CHEQUE;
	}
	else if ((int)dwPrice>0 && (int)dwCheque <= 0) // Yang
	{
		if (ch->GetGold() < (int)dwPrice)
			return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY;
	}
	else if ((int)dwPrice<=0 && (int)dwCheque > 0) // cheque
	{
		if (ch->GetCheque() < (int)dwCheque)
			return SHOP_SUBHEADER_GC_NOT_ENOUGH_CHEQUE;
	}
	/*#else
	if (ch->GetGold() < (int)dwPrice)
	{
		sys_log(1, "Shop::Buy : Not enough money : %s has %d, price %d", ch->GetName(), ch->GetGold(), dwPrice);
		return SHOP_SUBHEADER_GC_NOT_ENOUGH_MONEY;
	}
	#endif*/

	LPITEM item;

	if (m_pkPC) // ÇǾ¾°¡ ¿î¿µÇÏ´Â ¼¥Àº ÇǾ¾°¡ ½ÇÁ¦ ¾ÆÀÌÅÛÀ» °¡Áö°íÀÖ¾î¾ß ÇÑ´Ù.
		item = r_item.pkItem;
	else
		item = ITEM_MANAGER::instance().CreateItem(r_item.vnum, r_item.count);

	if (!item)
		return SHOP_SUBHEADER_GC_SOLD_OUT;

	if (!m_pkPC)
	{
		if (quest::CQuestManager::instance().GetEventFlag("hivalue_item_sell") == 0)
		{
			//ÃູÀÇ ±¸½½ && ¸¸³âÇÑö À̺¥Æ® 
			if (item->GetVnum() == 70024 || item->GetVnum() == 70035)
			{
				return SHOP_SUBHEADER_GC_END;
			}
		}
	}

	int iEmptyPos;
	if (item->IsDragonSoul())
	{
		iEmptyPos = ch->GetEmptyDragonSoulInventory(item);
	}
	else
	{
		iEmptyPos = ch->GetEmptyInventory(item->GetSize());
	}

	if (iEmptyPos < 0)
	{
		if (m_pkPC)
		{
			sys_log(1, "Shop::Buy at PC Shop : Inventory full : %s size %d", ch->GetName(), item->GetSize());
			return SHOP_SUBHEADER_GC_INVENTORY_FULL;
		}
		else
		{
			sys_log(1, "Shop::Buy : Inventory full : %s size %d", ch->GetName(), item->GetSize());
			M2_DESTROY_ITEM(item);
			return SHOP_SUBHEADER_GC_INVENTORY_FULL;
		}
	}

	ch->PointChange(POINT_GOLD, -dwPrice, false);
	#ifdef ENABLE_SHOP_USE_CHEQUE
	ch->PointChange(POINT_CHEQUE, -dwCheque, false);
	#endif

	//¼¼±Ý °è»ê
	DWORD dwTax = 0;
	int iVal = 0;

	if (LC_IsYMIR() ||  LC_IsKorea())
	{
		if (0 < (iVal = quest::CQuestManager::instance().GetEventFlag("trade_tax")))
		{
			if (iVal > 100)
				iVal = 100;

			dwTax = dwPrice * iVal / 100;
			dwPrice = dwPrice - dwTax;
		}
		else
		{
			iVal = 3;
			dwTax = dwPrice * iVal / 100;
			dwPrice = dwPrice - dwTax;			
		}
	}
	else
	{
		iVal = quest::CQuestManager::instance().GetEventFlag("personal_shop");

		if (0 < iVal)
		{
			if (iVal > 100)
				iVal = 100;

			dwTax = dwPrice * iVal / 100;
			dwPrice = dwPrice - dwTax;
		}
		else
		{
			iVal = 0;
			dwTax = 0;
		}
	}

	// »óÁ¡¿¡¼­ »ì‹š ¼¼±Ý 5%
	if (!m_pkPC) 
	{
		CMonarch::instance().SendtoDBAddMoney(dwTax, ch->GetEmpire(), ch);
	}

	// ±ºÁÖ ½Ã½ºÅÛ : ¼¼±Ý ¡¼ö
	if (m_pkPC)
	{
		m_pkPC->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255);

		if (item->GetVnum() == 90008 || item->GetVnum() == 90009) // VCARD
		{
			VCardUse(m_pkPC, ch, item);
			item = NULL;
		}
		else
		{
			char buf[512];

			if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007)
			{
				snprintf(buf, sizeof(buf), "%s FROM: %u TO: %u PRICE: %u", item->GetName(), ch->GetPlayerID(), m_pkPC->GetPlayerID(), dwPrice);
				LogManager::instance().GoldBarLog(ch->GetPlayerID(), item->GetID(), SHOP_BUY, buf);
				LogManager::instance().GoldBarLog(m_pkPC->GetPlayerID(), item->GetID(), SHOP_SELL, buf);
			}
			
			item->RemoveFromCharacter();
			if (item->IsDragonSoul())
				item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
			else
				item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
			ITEM_MANAGER::instance().FlushDelayedSave(item);
			

			snprintf(buf, sizeof(buf), "%s %u(%s) %u %u", item->GetName(), m_pkPC->GetPlayerID(), m_pkPC->GetName(), dwPrice, item->GetCount());
			LogManager::instance().ItemLog(ch, item, "SHOP_BUY", buf);

			snprintf(buf, sizeof(buf), "%s %u(%s) %u %u", item->GetName(), ch->GetPlayerID(), ch->GetName(), dwPrice, item->GetCount());
			LogManager::instance().ItemLog(m_pkPC, item, "SHOP_SELL", buf);
		}

		r_item.pkItem = NULL;
		BroadcastUpdateItem(pos);

		m_pkPC->PointChange(POINT_GOLD, dwPrice, false);
		#ifdef ENABLE_SHOP_USE_CHEQUE
		m_pkPC->PointChange(POINT_CHEQUE, dwCheque, false);
		#endif

		if (iVal > 0)
			m_pkPC->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ÆǸűݾ×ÀÇ %d %% °¡ ¼¼±ÝÀ¸·Î ³ª°¡°ÔµË´Ï´Ù"), iVal);

		CMonarch::instance().SendtoDBAddMoney(dwTax, m_pkPC->GetEmpire(), m_pkPC);
	}
	else
	{
		if (item->IsDragonSoul())
			item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
		else
			item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
		ITEM_MANAGER::instance().FlushDelayedSave(item);
		LogManager::instance().ItemLog(ch, item, "BUY", item->GetName());

		if (item->GetVnum() >= 80003 && item->GetVnum() <= 80007)
		{
			LogManager::instance().GoldBarLog(ch->GetPlayerID(), item->GetID(), PERSONAL_SHOP_BUY, "");
		}

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

	if (item)
		sys_log(0, "SHOP: BUY: name %s %s(x %d):%u price %u", ch->GetName(), item->GetName(), item->GetCount(), item->GetID(), dwPrice);

    ch->Save();

#ifdef ENABLE_PRIVATE_SHOP_AUTO_CLOSE
	if (IsPCShop() && IsSoldOut())
	{
		m_pkPC->CloseMyShop();
		m_pkPC->ChatPacket(CHAT_TYPE_NOTICE, "Magazinul tau a fost inchis automat deoarece ai vandut tot din el.");
	}
#endif

    return (SHOP_SUBHEADER_GC_OK);
}

bool CShop::AddGuest(LPCHARACTER ch, DWORD owner_vid, bool bOtherEmpire)
{
	if (!ch)
		return false;

	if (ch->GetExchange())
		return false;

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

	ch->SetShop(this);

	m_map_guest.insert(GuestMapType::value_type(ch, bOtherEmpire));

	TPacketGCShop pack;

	pack.header		= HEADER_GC_SHOP;
	pack.subheader	= SHOP_SUBHEADER_GC_START;

	TPacketGCShopStart pack2;

	memset(&pack2, 0, sizeof(pack2));
	pack2.owner_vid = owner_vid;

	for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
	{
		const SHOP_ITEM & item = m_itemVector[i];

		//HIVALUE_ITEM_EVENT
		if (quest::CQuestManager::instance().GetEventFlag("hivalue_item_sell") == 0)
		{
			//ÃູÀÇ ±¸½½ && ¸¸³âÇÑö À̺¥Æ® 
			if (item.vnum == 70024 || item.vnum == 70035)
			{				
				continue;
			}
		}
		//END_HIVALUE_ITEM_EVENT
		if (m_pkPC && !item.pkItem)
			continue;

		pack2.items[i].vnum = item.vnum;

		if (bOtherEmpire) // no empire price penalty for pc shop
			pack2.items[i].price = item.price * 3;
		else
		{
			pack2.items[i].price = item.price;
			#ifdef ENABLE_CHEQUE_SYSTEM
			pack2.items[i].cheque = item.cheque;
			#endif
		}
		pack2.items[i].count = item.count;

		if (item.pkItem)
		{
			thecore_memcpy(pack2.items[i].alSockets, item.pkItem->GetSockets(), sizeof(pack2.items[i].alSockets));
			thecore_memcpy(pack2.items[i].aAttr, item.pkItem->GetAttributes(), sizeof(pack2.items[i].aAttr));
		}
	}

	pack.size = sizeof(pack) + sizeof(pack2);

	ch->GetDesc()->BufferedPacket(&pack, sizeof(TPacketGCShop));
	ch->GetDesc()->Packet(&pack2, sizeof(TPacketGCShopStart));
	return true;
}

void CShop::RemoveGuest(LPCHARACTER ch)
{
	if (ch->GetShop() != this)
		return;

	m_map_guest.erase(ch);
	ch->SetShop(NULL);

	TPacketGCShop pack;

	pack.header		= HEADER_GC_SHOP;
	pack.subheader	= SHOP_SUBHEADER_GC_END;
	pack.size		= sizeof(TPacketGCShop);

	ch->GetDesc()->Packet(&pack, sizeof(pack));
}

void CShop::Broadcast(const void * data, int bytes)
{
	sys_log(1, "Shop::Broadcast %p %d", data, bytes);

	GuestMapType::iterator it;

	it = m_map_guest.begin();

	while (it != m_map_guest.end())
	{
		LPCHARACTER ch = it->first;

		if (ch->GetDesc())
			ch->GetDesc()->Packet(data, bytes);

		++it;
	}
}

void CShop::BroadcastUpdateItem(BYTE pos)
{
	TPacketGCShop pack;
	TPacketGCShopUpdateItem pack2;

	TEMP_BUFFER	buf;

	pack.header		= HEADER_GC_SHOP;
	pack.subheader	= SHOP_SUBHEADER_GC_UPDATE_ITEM;
	pack.size		= sizeof(pack) + sizeof(pack2);

	pack2.pos		= pos;

	if (m_pkPC && !m_itemVector[pos].pkItem)
		pack2.item.vnum = 0;
	else
	{
		pack2.item.vnum	= m_itemVector[pos].vnum;
		if (m_itemVector[pos].pkItem)
		{
			thecore_memcpy(pack2.item.alSockets, m_itemVector[pos].pkItem->GetSockets(), sizeof(pack2.item.alSockets));
			thecore_memcpy(pack2.item.aAttr, m_itemVector[pos].pkItem->GetAttributes(), sizeof(pack2.item.aAttr));
		}
		else
		{
			memset(pack2.item.alSockets, 0, sizeof(pack2.item.alSockets));
			memset(pack2.item.aAttr, 0, sizeof(pack2.item.aAttr));
		}
	}

	pack2.item.price	= m_itemVector[pos].price;
	#ifdef ENABLE_CHEQUE_SYSTEM
	pack2.item.cheque = m_itemVector[pos].cheque;
	#endif
	pack2.item.count	= m_itemVector[pos].count;

	buf.write(&pack, sizeof(pack));
	buf.write(&pack2, sizeof(pack2));

	Broadcast(buf.read_peek(), buf.size());
}

int CShop::GetNumberByVnum(DWORD dwVnum)
{
	int itemNumber = 0;

	for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
	{
		const SHOP_ITEM & item = m_itemVector[i];

		if (item.vnum == dwVnum)
		{
			itemNumber += item.count;
		}
	}

	return itemNumber;
}

bool CShop::IsSellingItem(DWORD itemID)
{
	bool isSelling = false;

	for (DWORD i = 0; i < m_itemVector.size() && i < SHOP_HOST_ITEM_MAX_NUM; ++i)
	{
		if (m_itemVector[i].itemid == itemID)
		{
			isSelling = true;
			break;
		}
	}

	return isSelling;

}

If anyone could help I d be more than gratefull!

 

 

Edited by narcisxb
Link to comment
Share on other sites

  • 2 weeks later...

Thanks for the system, but if you have Decoration and search items maybe you have a problems to compile, when i can solved i put fix 🙂

okey for my the fix is commonDefines or service.h replace this:

Quote

#define ENABLE_CHEQUE_SYSTEM

#if defined(ENABLE_OFFLINE_SHOP) && defined(ENABLE_CHEQUE_SYSTEM)

# define ENABLE_OFFLINE_SHOP_USE_CHEQUE

#else

# define ENABLE_SHOP_USE_CHEQUE

#endif

to:

Quote

#define ENABLE_CHEQUE_SYSTEM //Cheque Won
#define ENABLE_OFFLINE_SHOP_USE_CHEQUE //Won for Offline
#define ENABLE_SHOP_USE_CHEQUE //Won Cheque use
#define OFFLINE_SHOP //Offline Shop by Great

Thanks for the system!

Edited by nazox

KH.jpg

Nicks: Nazox Krone Nagato Yahiko Yakiro
Proyecto: Trabajando en el.
Compañeros & firma: DreamHQ  - 2009-2015 [Nostalgia]

Link to comment
Share on other sites

 Hello again !, I want to ask something, first thanks for the system again, PrivateShop and OfflineShop work very well

https://metin2.download/picture/W5B8gOG55t91TGiPq48y4ixN5R3824wW/.gif

But i can see a little problems (syssers Clean and not game.core)

========================Problems================================

1-#Solved (solution in end of post)

2-#Solved (solution in end of post)

3-#Solved (solution in end of post)

4-#Solved (solution in end of post)

5-#Solved (solution in end of post)

6-#Solved (solution in end of post)

=================End Problems=================================

Putting that aside, the system works great, so thanks really, can you give me any ideas? 🙂

=====================Fix====================================

Edit with fixes:

1 & 2. When you have 1 won or 99 or 999 you can see wons, but when you change PJ or teleport, in your inventory you have "0" wons, this visual bug you can fix it, go to char.cpp and search ;

Quote

#ifdef ENABLE_CHEQUE_SYSTEM

case POINT_CHEQUE:

{

const int64_t nTotalCheque = static_cast<int64_t>(GetCheque()) + static_cast<int64_t>(amount);

if (CHEQUE_MAX <= nTotalCheque)

{

sys_err("[OVERFLOW_CHEQUE] OriCheque %d AddedCheque %d id %u Name %s ", GetCheque(), amount, GetPlayerID(), GetName());

LogManager::instance().CharLog(this, GetCheque() + amount, "OVERFLOW_CHEQUE", "");

return;

}

SetCheque(GetCheque() + amount);

val = GetCheque();

}

break;

#endif

and replace function with this :

Quote

#ifdef ENABLE_CHEQUE_SYSTEM
        case POINT_CHEQUE:
            {
                const int64_t nTotalCheque = static_cast<int64_t>(GetCheque()) + static_cast<int64_t>(amount);
                if (CHEQUE_MAX <= nTotalCheque)
                {
                    sys_err("[OVERFLOW_CHEQUE] OriCheque %d AddedCheque %d id %u Name %s ", GetCheque(), amount, GetPlayerID(), GetName());
                    LogManager::instance().CharLog(this, GetCheque() + amount, "OVERFLOW_CHEQUE", "");
                    return;
                }
                
                if (nTotalCheque < 0)
                {
                    sys_err("Won. PID::[%d]", GetPlayerID());
                    return;
                }
                
                if (g_bChinaIntoxicationCheck && amount > 0)
                {
                    if (IsOverTime(OT_NONE))
                    {
                        dev_log(LOG_DEB0, "<CHEQUE_LOG> %s = NONE", GetName());
                    }
                    else if (IsOverTime(OT_3HOUR))
                    {
                        amount = (amount / 2);
                        dev_log(LOG_DEB0, "<CHEQUE_LOG> %s = 3HOUR", GetName());
                    }
                    else if (IsOverTime(OT_5HOUR))
                    {
                        amount = 0;
                        dev_log(LOG_DEB0, "<CHEQUE_LOG> %s = 5HOUR", GetName());
                    }
                }

                SetCheque(GetCheque() + amount);
                val = GetCheque();
            }
            break;
#endif

Automatically you solved the  2 problem 🙂

3.Fix you can't trade Wons: go to exchange.cpp and search;

Revelación

#ifdef ENABLE_CHEQUE_SYSTEM
    if (m_lCheque)
    {
        GetOwner()->PointChange(POINT_CHEQUE, -m_lCheque, true);
        victim->PointChange(POINT_CHEQUE, m_lCheque, true);

#end

Now replace:

Revelación

#ifdef ENABLE_CHEQUE_SYSTEM
    if (m_lCheque)
    {
        GetOwner()->PointChange(POINT_CHEQUE, -m_lCheque, true);
        victim->PointChange(POINT_CHEQUE, m_lCheque, true);
        
        if (m_lCheque > 1000)
        {
            char exchange_buf[51];
            snprintf(exchange_buf, sizeof(exchange_buf), "%u %s", GetOwner()->GetPlayerID(), GetOwner()->GetName());
            LogManager::instance().CharLog(victim, m_lCheque, "EXCHANGE_GOLD_TAKE", exchange_buf);

            snprintf(exchange_buf, sizeof(exchange_buf), "%u %s", victim->GetPlayerID(), victim->GetName());
            LogManager::instance().CharLog(GetOwner(), m_lCheque, "EXCHANGE_GOLD_GIVE", exchange_buf);
        }
    }
#endif

4-For solved problem drop yang/won "you have many arguments (give 2 blabla), check if you use other system, or others pythons like uiPickMoney.py and PickMoney.py, for example in my case i use a system with names, "uiPickItem.py" and "PickItem.py" and have the same functions like "uiPickMoney.py" and "PickMoney.py" so i need add the same on the 4 functions for working, so now you can drop Yang and Won.

5-If you can't Open Panel Offline you need open locale_interface.txt on your locale, and add:

Spoiler

SHOP_EARNED_CHEQUE    Recieved Wons
SHOP_NOT_EARNED_CHEQUE    No Won to collect!
SHOP_GET_CHEQUE    Won

6-If you write "1.999" in the section "Won -> Yang" you will receive 199kk, about the double of its real value and problems with yang/won on general

Quote

--[[
    Quest of CHEQUE_SYSTEM for Storekeeper
    Released by: WLsj24
--]]
quest cheque_system begin
    state start begin

        when 9005.chat."Casa de Cambio" begin --10043
            local menu = select("Won a Yang", "Yang a Won", "Cancel") --10045, 10046, 10044
            if menu == 3 then return end
            if menu == 1 then
                say("Won a Yang") --10050
                say("¿Cuanto Won quieres cambiar a Yang?[ENTER]1 Won = 100,000,000 Yang") --10048
                say("Min. 1 Won - Max. 19 Won") --10049
                local amount = tonumber(math.floor(input()))
                if ((amount < 1) or (amount >19) or (amount == nil) or (math.floor(amount) ~= amount)) then
                    say("Comprueba las cifras e intentalo de nuevo.[ENTER][ENTER]Max. Cantidad de Won = 99[ENTER]Max. Cantidad de Yang = 1 999 999 999") --10032
                    return
                else
                    say("Won a Yang") --10045
                    local yang = 100000000
                    local total = amount*yang
                    say(string.format("¿Estás seguro de cambiar %d Won en %d Yang?", amount, total)) --10033
                    local s = select("Cambiar", "Cancelar") --10034, 10035
                    if s == 2 then return end
                    if pc.get_cheque() >= amount then
                        if pc.get_gold() + total < 2000000000 then
                            pc.set_cheque(-amount)
                            pc.change_gold(total)
                            return
                        else
                            syschat("No puedes sobrepasar el límite.")
                            return
                        end
                    else
                        syschat("No tienes suficiente Won.")
                        return
                    end
                end
            elseif menu == 2 then
                say("Yang a Won") --10036
                say("¿Cuantos Wons quieres obtener?[ENTER]1 Won = 100,000,000 Yang") --10037
                say("Min. 1 Won - Max. 19 Won") --10038
                local amount = tonumber(math.floor(input()))
                if ((amount < 1) or (amount >19) or (amount == nil) or (math.floor(amount) ~= amount)) then
                    say("Comprueba las cifras e intentalo de nuevo.[ENTER][ENTER]Max. cantidad de Won = 99[ENTER]Max. de Yang = 1 999 999 999") --10032
                    return
                else
                    say("Yang a Won") --10036
                    local won = 100000000
                    local tax = amount*won*0.03
                    local total = ((amount*won)+tax)
                    say("Tax: 3%")
                    say(string.format("¿Quieres cambiar %d Yang a %d Won?", total, amount)) --10041
                    local s = select("Cambiar", "Cancelar") --10042, 10044
                    if s == 2 then return end
                    if pc.get_gold() >= total then
                        if pc.get_cheque() + amount < 100 then
                            pc.change_money(-total)
                            pc.set_cheque(amount)
                            syschat(string.format("Has recibido %d Won.", amount))
                            return
                        else
                            syschat("No puedes pasar el límite de Wons")
                            return
                        end
                    else
                        syschat("No tienes suficiente Yang.") --716
                        return
                    end
                end
            end --menu
        end --when

    end --state
end --quest

if you don't want use my quest translated and only want functions, search ;

Quote

if ((amount < 1) or (amount >19) or (amount == nil)  then

and replace all :

Quote

if ((amount < 1) or (amount >19) or (amount == nil) or (math.floor(amount) ~= amount)) then

Now search;

Quote

local amount = tonumber(input())

and replace :

Quote

local amount = tonumber(math.floor(input()))

tx for apporting math.floor fix to @narcisxb

=======================End Fix==============================

#Now you can Trade with Yang and Won :)

#Now you can drop Won/Yang 🙂

#Now you can open Offline Shop Panel

#Now you can change Won/Yang on warehouse and not problems

#Now you don't have a visual bug any more so, you have full Won System 🙂 !

#Full System

thanks 🙂

Edited by Metin2 Dev
Core X - External 2 Internal

KH.jpg

Nicks: Nazox Krone Nagato Yahiko Yakiro
Proyecto: Trabajando en el.
Compañeros & firma: DreamHQ  - 2009-2015 [Nostalgia]

Link to comment
Share on other sites

3 hours ago, nazox said:

 Hello again !, I want to ask something, first thanks for the system again, PrivateShop and OfflineShop work very well

https://metin2.download/picture/W5B8gOG55t91TGiPq48y4ixN5R3824wW/.gif

But i can see a little problems (syssers Clean and not game.core)

========================Problems================================

1-When you change player/teleport others maps, your Won is put in "0", not metter when wons you have, if you don't pay for more wons or someone trade you, you can't update wons in your inventory, basicaly don't update in real time, i read the "fix" is this:

963aecf9c01e5efd2f4a0bc552c5842f.png

but for my not work so... if you can give me any idea i appreciate.

2-For example, mi Pj1 have 3 wons, and PJ2 too, but in my mysql in player "cheque"  takes time to update and not show you Wons correctly ( i think is not a problem, because if i can solved the first all work)

207c7b34514729ccb56068a845f3b9db.png

3- #Solved (solution in end of post)

4-#Solved (solution in end of post)

=================End Problems=================================

Putting that aside, the system works great, so thanks really, can you give me any ideas? 🙂

=====================Fix====================================

Edit with fixes:

3.Fix you can't trade Wons: go to exchange.cpp and search;

  Hide contents

#ifdef ENABLE_CHEQUE_SYSTEM
    if (m_lCheque)
    {
        GetOwner()->PointChange(POINT_CHEQUE, -m_lCheque, true);
        victim->PointChange(POINT_CHEQUE, m_lCheque, true);

#end

Now replace:

  Hide contents

#ifdef ENABLE_CHEQUE_SYSTEM
    if (m_lCheque)
    {
        GetOwner()->PointChange(POINT_CHEQUE, -m_lCheque, true);
        victim->PointChange(POINT_CHEQUE, m_lCheque, true);
        
        if (m_lCheque > 1000)
        {
            char exchange_buf[51];
            snprintf(exchange_buf, sizeof(exchange_buf), "%u %s", GetOwner()->GetPlayerID(), GetOwner()->GetName());
            LogManager::instance().CharLog(victim, m_lCheque, "EXCHANGE_GOLD_TAKE", exchange_buf);

            snprintf(exchange_buf, sizeof(exchange_buf), "%u %s", victim->GetPlayerID(), victim->GetName());
            LogManager::instance().CharLog(GetOwner(), m_lCheque, "EXCHANGE_GOLD_GIVE", exchange_buf);
        }
    }
#endif

4-For solved problem drop yang/won "you have many arguments (give 2 blabla), check if you use other system, or others pythons like uiPickMoney.py and PickMoney.py, for example in my case i use a system with names, "uiPickItem.py" and "PickItem.py" and have the same functions like "uiPickMoney.py" and "PickMoney.py" so i need add the same on the 4 functions for working, so now you can drop Yang and Won.

=======================End Fix==============================

#Now you can Trade with Yang and Won :)

#Now you can drop Won/Yang 🙂

#Working in problem 1 and 2.

thanks 🙂

You don t really need these fixes unless you have a different source. It works perfectly as it is. I added it as Mali put it and it works 100%.

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

1 minute ago, narcisxb said:

Realmente no necesita estas correcciones a menos que tenga una fuente diferente. Funciona perfectamente como está. Lo agregué como lo dijo Mali y funciona al 100%.

Logically, we all have different fonts, I use MartySama, but if someone else has these problems because I am giving the solution, the system works well but still has errors, the question is to help us, but there is still no solution for that problem, when have I will put it and if someone can give me an idea then I'll look at it!  regards and thanks for your comment :)!

KH.jpg

Nicks: Nazox Krone Nagato Yahiko Yakiro
Proyecto: Trabajando en el.
Compañeros & firma: DreamHQ  - 2009-2015 [Nostalgia]

Link to comment
Share on other sites

5 minutes ago, nazox said:

Logically, we all have different fonts, I use MartySama, but if someone else has these problems because I am giving the solution, the system works well but still has errors, the question is to help us, but there is still no solution for that problem, when have I will put it and if someone can give me an idea then I'll look at it!  regards and thanks for your comment :)!

Of course. I just wanted to point out that Malis code is 100% correct for normal source. PS: there is a MAJOR bug that you might want to correct in the quest. My hotfix is this: 

local amount = tonumber(math.floor(input()))

 

Edited by narcisxb
  • Good 1
Link to comment
Share on other sites

Justo ahora, narcisxb dijo:

Por supuesto. Solo quería señalar éso. PD: hay un error MAYOR que quizás quieras corregir en la misión. Mi revisión es esta: cantidad local = tonumber (math.floor (input ()))

If I have noticed, thanks if you give me permission I will add it later in my other comment, I will put the mission with the fix

KH.jpg

Nicks: Nazox Krone Nagato Yahiko Yakiro
Proyecto: Trabajando en el.
Compañeros & firma: DreamHQ  - 2009-2015 [Nostalgia]

Link to comment
Share on other sites

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.