[C++] Pet Name Change

11/29/2015 12:21 kralcocuk#1
Hi.


Note: For all codes: [Only registered and activated users can see links. Click Here To Register...]

open petsystem.cpp

find:
Code:
#include "item.h"
add

Code:
#include "db.h"
find:

Code:
void CPetActor::SetName(const char* name)
change code block:

Code:
void CPetActor::SetName(const char* name)
{
	std::string petName = m_pkOwner->GetName();

	if (0 != m_pkOwner && 
		0 == name && 
		0 != m_pkOwner->GetName())
	{
		petName += "'s Pet";
	}
	else
		petName += name;
	
	char sorgu[512];
	snprintf(sorgu, sizeof(sorgu), "SELECT name FROM pet_name WHERE id = %u", m_pkOwner->GetPlayerID());
	std::auto_ptr<SQLMsg> cekgelsin( DBManager::instance().DirectQuery(sorgu) );
	if (cekgelsin->Get()->uiNumRows != 0)
	{
		MYSQL_ROW row = mysql_fetch_row(cekgelsin->Get()->pSQLResult);
		char petad[CHARACTER_NAME_MAX_LEN + 1];
		strlcpy(petad, row[0], sizeof(petad));
		petName = petad;
	}
	
	if (true == IsSummoned())
		m_pkChar->SetName(petName);
	
	m_name = petName;
}
open questlua_pet.cpp

find:
Code:
#include "PetSystem.h"
add
Code:
#include "db.h"

find

Code:
	int pet_spawn_effect(lua_State* L)
add code block

Code:
	int pet_namever(lua_State* L)
	{
		LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr()  ;

		if ( lua_isstring(L, 1) != true )
		{
			lua_pushnumber(L, 1);
			return 1;
		}
		
		const char * szName = lua_tostring(L, 1);
		
		char sorgu[512];
		snprintf(sorgu, sizeof(sorgu), "REPLACE INTO pet_name VALUES(%u, '%s')", ch->GetPlayerID(), szName);
		std::auto_ptr<SQLMsg> yolla( DBManager::instance().DirectQuery(sorgu) );
		if (yolla->Get()->uiAffectedRows != 0)
		{
			lua_pushnumber(L, 3);
			return 3;
		}
		
		return 4;
	}
find

Code:
			{ "spawn_effect",	pet_spawn_effect	},
add

Code:
			{ "adver",			pet_namever			},



Navicat mysql query :

Open Navicat > Click to "Query":

Code:
DROP TABLE IF EXISTS `pet_name`;
CREATE TABLE `pet_name` (
  `id` int(11) NOT NULL DEFAULT '0',
  `name` varchar(24) CHARACTER SET utf8 COLLATE utf8_turkish_ci NOT NULL DEFAULT 'NONAME',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_turkish_ci;
add to in Quest_functions

Code:
pet.adver
Quest:

Code:
quest ademin begin
    state start begin
        when 71115.use begin
			say_title("yeni isim ver")
			local str = input()
			if str == "" or str == nill then
				say_title("Kutuyu bos birakma")
				return
			end

			if string.len(str) <= 0 or string.len(str) > 12 then
				say_title("isim en fazla 12 karakter olabilir")
				return
			end
			
			local tt = "%'"
			local ct = "%:"
			local nk = "%."
			local vg = "%,"
			if string.find(str, tt) or string.find(str, ct) or string.find(str, nk) or string.find(str, vg) then
				say_title("ozel isaret kullanamazsin")
				return
			end
			
			local t = pet.adver(str)
			say_title("pet adi degistirildi. peti gonder")
			if t == 1 then
				say_title("kutuyu bos bırakma")
				return
			elseif t == 2 then
				say_title("12 karakteri gecme")
				return
			elseif t == 3 then
				say_title("isim degisti")
			end
		end
	end
end
Code:
local tt = "%'"
			local ct = "%:"
			local nk = "%."
			local vg = "%,"

Yukarıda :
tt > '
ct > :
nk > .
vg > ,


Pet name given apply to all pets.


Note: Pet name > max 24 characters
11/29/2015 13:06 Mr. 'Avenue™#2
Thank you yavsak :)
Very useful
11/29/2015 13:16 Cyber36#3
Thank you!
11/29/2015 22:58 Crvena#4
Quote:
Originally Posted by Mr. 'Avenue™ View Post
Thank you yavsak :)
Very useful
lol :D
11/29/2015 23:51 filipw1#5
Hmm, useful. Thanks, I'll take this.
11/30/2015 00:33 Ken™#6
At first, your method is totally wrong. I want to explain what does mean REPLACE INTO to you.

Code:
REPLACE INTO
It means, If the query is not exist, insert it. Otherwise replace it with new one. Your vulnerability starts here.

If I've more pet in the game, the system is only call first column. So that means, my pet's name is Julia but it returns Adam because of this.

Also, if you're not using pet_name.sql to store the pet names, you don't need to create extra codes to set pet name. You can insert a new column in player.sql and you can call it easily too.

Code:
strlcpy(petad, row[0], sizeof(petad));
Everything will be good with item id.

Here are new codes.

Don't forget to add those things in your questlua_pet.cpp
Code:
#include "db.h"
#include "item.h"
Code:
	int pet_set_name(lua_State * L)
	{
		if (!lua_isstring(L, 1))
		{
			lua_pushnumber(L, 1);
			return 1;
		}

		LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
		LPITEM pItem = CQuestManager::instance().GetCurrentItem();
		if (!ch || !pItem) return 1;
		
		const char * c_pszPetName = lua_tostring(L, 1);

		char szPetName[CHARACTER_NAME_MAX_LEN + 1];
		DBManager::Instance().EscapeString(szPetName, sizeof(szPetName), c_pszPetName, strlen(c_pszPetName));

		if (strlen(szPetName) == 0)		
		{
			lua_pushnumber(L, 2);
			return 2;
		}

		std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("REPLACE INTO %spet_name VALUES(%u, '%s')", get_table_postfix(), pItem->GetID(), szPetName));
		if (pMsg->Get()->uiAffectedRows != 0)
			lua_pushnumber(L, 3);
		
		return 0;
	}
Code:
void CPetActor::SetName(const char * name)
{
	if (!IsSummoned()) return;
	
	if (m_dwSummonItemVID == 0)
	{
		std::string petName = m_pkOwner->GetName();
		petName += m_pkOwner != 0 && name == 0 &&  m_pkOwner->GetName() != 0 ? "'s Pet" : name;		
		m_pkChar->SetName(petName);		
		m_name = petName;		
	}
	else
	{
		LPITEM pSummonItem = ITEM_MANAGER::instance().FindByVID(m_dwSummonItemVID);
		if (!pSummonItem)
		{
			std::string petName = m_pkOwner->GetName();
			petName += m_pkOwner != 0 && name == 0 &&  m_pkOwner->GetName() != 0 ? "'s Pet" : name;							
			m_pkChar->SetName(petName);
			m_name = petName;
		}
		else
		{
			std::auto_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT name FROM %spet_name WHERE id = %u", get_table_postfix(), pSummonItem->GetID()));
			if (pMsg->Get()->uiNumRows == 0)
			{
				std::string petName = m_pkOwner->GetName();
				petName += m_pkOwner != 0 && name == 0 &&  m_pkOwner->GetName() != 0 ? "'s Pet" : name;				
				m_pkChar->SetName(petName);
				m_name = petName;				
			}
			else
			{
				MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
				char szPetName[CHARACTER_NAME_MAX_LEN + 1];
				strlcpy(szPetName, row[0], sizeof(szPetName));				
				m_pkChar->SetName(szPetName);
				m_name = szPetName;
			}
		}
	}
}
Code:
			local t = pet.adver(str)
			say_title("pet adi degistirildi. peti gonder")
			if t == 1 then
				say_title("kutuyu bos bırakma")
				return
			elseif t == 2 then
				say_title("12 karakteri gecme")
				return
			elseif t == 3 then
				say_title("isim degisti")
			end
that variable will never return 2 with your function and that condition is useless too.

Code:
quest pet_name_change begin
	state start begin
		when 71115.use begin
			say_title("Pet name change:")
			say("")
			---"1234567890"
			local petName = input()
			if (petName == "" or tostring(petName) == nil) then
				say("Enter a pet name!")
				return
			elseif (string.len(petName) <= 0 or string.len(petName) > 12) then
				say("Your pet name is very long.")
				return
			end
			
			local ret = pet.set_name(petName)
			if (ret == 3) then
				say("You changed your pet name.")
				say("You just need to recall him!")
			elseif (ret == 2) then
				say("Your pet name is very short.")
			else
				say("Error code 0x100")
				say("Please contact the administrator!")
			end
		end
	end
end
Change CPetActor::Summon with that


Kind Regards ~ Ken
11/30/2015 07:28 rollback#7
I would search for "%W", which matches all non-alphanumeric characters. Matching only a few blacklisted characters doesnt seem good for me.

Use like below:
Code:
if string.find(petName, "%W") then
--Error msg
return
end
11/30/2015 11:09 Ken™#8
Quote:
Originally Posted by Seחsi View Post
I would search for "%W", which matches all non-alphanumeric characters. Matching only a few blacklisted characters doesnt seem good for me.

Use like below:
Code:
if string.find(petName, "%W") then
--Error msg
return
end
Yeah, it's an option for Lua but I'd prefer to use c++ for this job.

Code:
const char * c_pszPetName = lua_tostring(L, 1);

char szPetName[CHARACTER_NAME_MAX_LEN + 1];
DBManager::Instance().EscapeString(szPetName, sizeof(szPetName), c_pszPetName, strlen(c_pszPetName));

if (strlen(szPetName) == 0)
{
	// Return value
}
or we can use this :)

Code:
char szPetName[24+1];
_snprintf(szPetName, sizeof(szPetName), "Kralco:cuk");

std::string stPetName = szPetName;
stPetName.erase(std::remove_if(stPetName.begin(), stPetName.end(), std::not1(std::ptr_fun(std::isalnum))), stPetName.end());

std::cout << stPetName << std::endl; // Return value would be "Kralcocuk"
12/08/2015 00:17 naosou#9
Quote:
Originally Posted by kralcocuk View Post
Hi.
Note: Pet name > max 24 characters
That's the only part i don't really like.
Other than that, thanks.
12/08/2015 02:32 kralcocuk#10
Quote:
Originally Posted by naosou View Post
That's the only part i don't really like.
Other than that, thanks.
Short ?
Quote:
DROP TABLE IF EXISTS `pet_name`;
CREATE TABLE `pet_name` (
`id` int(11) NOT NULL DEFAULT '0',
`name` varchar(24) CHARACTER SET utf8 COLLATE utf8_turkish_ci NOT NULL DEFAULT 'NONAME',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_turkish_ci;

varchar(24) <= Change
12/08/2015 03:35 naosou#11
Quote:
Originally Posted by kralcocuk View Post
Short ?
varchar(24) <= Change
Sorry my bad, I meant this part.
Quote:
Originally Posted by kralcocuk View Post
Pet name given apply to all pets.
12/10/2015 00:18 Rofelmau#12
doesn't even matter because his quest dose not allow u to enter a name with more then 12 Charakters

PHP Code:
if string.len(str) <= or string.len(str) > 12 then
                say_title
("isim en fazla 12 karakter olabilir")
                return
            
end