Go Back   EQEmulator Home > EQEmulator Forums > Development > Development::Server Code Submissions

Reply
 
Thread Tools Display Modes
  #1  
Old 07-30-2008, 09:43 PM
Theeper
Discordant
 
Join Date: May 2004
Posts: 290
Default

I was thinking about shared plat the other night and how to keep people from duping shared plat on servers that allow more than one login per account like Knightly mentioned. I wrote up a simple hack to make it use the account table, but it does allow duping when you login two toons on the same account, as expected.

I thought I'd post this and see what you guys think is the best way to fix it.

Basically, it's two functions which get and set the shared plat value in the profile from the shared_plat field in the account table. When you zone or click on coins in the shared bank slot, the profile value is updated prior to the 'move coin' action happening. The plat is still stored in the profile, it's just updated from the DB before calculating how much to move.

This all works fine for single logins, but again, will allow duping with multiple logins. I tested it with 1018 and 1019 and it seems to work fine. Don't run this on your live server though, as it will set everyone's shared plat to whatever is in their shared_plat field in the DB.

To eliminate duping, I'm thinking we need to send a packet telling the client to delete the coins on the cursor when the server says the count is wrong. I'm guessing that the reason shared items go poof if you try to dupe them in the bank window is because they are instanced in the DB. For coins, the client seems to ignore what is in the profile and will 'pick up' whatever amount the bank window shows even if the shared plat value is zero.


1. Prototype the two new functions. Add the parts in red into common/shareddb.h at line 40.

Code:
	sint32	DeleteStalePlayerCorpses();
	sint32	DeleteStalePlayerBackups();
	bool	SetSharedPlatinum(uint32 account_id, sint32 amount_to_add);
	uint32	GetSharedPlatinum(uint32 account_id);
2. Then add the functions to common/shareddb.cpp at line 46

Code:

uint32 SharedDatabase::GetSharedPlatinum(int32 account_id)
{
	char errbuf[MYSQL_ERRMSG_SIZE];
	char *query = 0;
	MYSQL_RES *result;
	MYSQL_ROW row;
	if (RunQuery(query, MakeAnyLenString(&query, "SELECT sharedplat FROM account WHERE id='%i'", account_id), errbuf, &result)) {
		safe_delete_array(query);
		if (mysql_num_rows(result) == 1)
		{
			row = mysql_fetch_row(result);
			uint32 shared_platinum = atoi(row[0]);
			mysql_free_result(result);
			return shared_platinum;
		}
		else
		{
			mysql_free_result(result);
			return 0;
		}
		mysql_free_result(result);
	}
	else
	{
		
		cerr << "Error in GetSharedPlatinum query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
		return false;
	}
	
	return 0;
}

bool SharedDatabase::SetSharedPlatinum(uint32 account_id, sint32 amount_to_add)
{
	char errbuf[MYSQL_ERRMSG_SIZE];
    char *query = 0;

	if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE account SET sharedplat = sharedplat + %i WHERE id = %i", amount_to_add, account_id), errbuf)) {
		cerr << "Error in SetSharedPlatinum query '" << query << "' " << errbuf << endl;
		safe_delete_array(query);
		return false;
	}
	
	safe_delete_array(query);
	return true;
}
3. In zone/clientprocess.cpp at line 1280, add
Code:
	if(to_bucket)
	{
		if(*to_bucket + amount_to_add > *to_bucket)	// overflow check
			*to_bucket += amount_to_add;

		if (to_bucket == &m_pp.platinum_shared || from_bucket == &m_pp.platinum_shared)
		{
			if (from_bucket == &m_pp.platinum_shared) 
				amount_to_add = 0 - amount_to_take;

			database.SetSharedPlatinum(AccountID(),amount_to_add);
		}

	}

4. In zone/zonedb.cpp at line 706, add
Code:
		uint32 char_id = atoi(row[0]);
		pp->platinum_shared = database.GetSharedPlatinum(GetAccountIDByChar(char_id));

Any thoughts ?
Reply With Quote
  #2  
Old 10-22-2008, 09:50 PM
AndMetal
Developer
 
Join Date: Mar 2007
Location: Ohio
Posts: 648
Default

Compiled, verified, & committed in SVN Revision 129.

Warning: pretty sure we can still dupe plat (but is a pita to test), so it's turned off by default.
__________________
GM-Impossible of 'A work in progress'
A non-legit PEQ DB server
How to create your own non-legit server

My Contributions to the Wiki
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 08:58 PM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3