Jump to content
!-->
  • Join-Us

    https://metin2.dev is the 1st international community on Metin2 development. Join us to develop your skills and share your knowledge with the community, respectful and ethical forum.

  • 0

Weird crash server


Zonni

Question

  • Premium

Hello everyone. I have this function.

 

 

void Achievement::Login(Achievement::keyA name)
{

	if(test_server)
		sys_log(0, "Achievement::Login Start ");

	if (m_set_loginName.find(name) != m_set_loginName.end())
	{
		sys_log(0, "Achievement::Login 2nd if return ");
		return;
	}

/* 	DBManager::instance().FuncQuery(std::bind1st(std::mem_fun(&Achievement::LoadList), this),
			"SELECT name, achievement FROM achievement%s WHERE name='%s'", get_table_postfix(), name.c_str()); */
			
	if(test_server)
		sys_log(0, "Achievement::Login Query ");
			
	char szQueryA[1024+1];
	snprintf(szQueryA, sizeof(szQueryA), "SELECT name, achievement FROM achievement%s WHERE name='%s'", get_table_postfix(), name.c_str());
	
	if(test_server)
		sys_log(0, "Achievement::Login snprintf %s", szQueryA);
	
	std::auto_ptr<SQLMsg> msg(DBManager::instance().DirectQuery(szQueryA));
	
	if(test_server)
		sys_log(0, "Achievement::Login DBManager ");

	if (msg->Get()->uiNumRows == 0)
		return;

	std::string namea;

	sys_log(1, "Achievement::LoadList");

	for (uint i = 0; i < msg->Get()->uiNumRows; ++i)
	{
		MYSQL_ROW row = mysql_fetch_row(msg->Get()->pSQLResult);

		if (row[0] && row[1])
		{
			if (namea.length() == 0)
				namea = row[0];

			m_Achievements[row[0]].insert(row[1]);
		}
	}

	SendList(namea);

	std::set<Achievement::keyT>::iterator it;

	m_set_loginName.insert(namea);
	
	if(test_server)
		sys_log(0, "Achievement::Login End ");
}
 

When i call it from CInputLogin::Entergame like this:

 

Achievement::instance().Login(ch->GetName());
 

my channel crash. Someone know what's error? My syslog says only Achievement::Login Start but compiler doesn't snow any error. I think error it's in

 

if (m_set_loginAccount.find(name) != m_set_loginAccount.end())
but this if is right, used for example in messenger_manager.cpp

 

Maybe i must extend character buffer or something (where i can find it btw.)? Seriously i don't know. I tried a lot.

Link to comment
Share on other sites

8 answers to this question

Recommended Posts

  • 0
  • Premium

AchievementManager::instance().Initialize();
after

MessengerManager::instance().Initialize();
and

 

AchievementManager	achievement_manager;
after

MessengerManager	messenger_manager;

Any ideas? Of course when i remove call to function from files everything works fine.

  • Love 1
Link to comment
Share on other sites

  • 0
  • Premium

Did you tried to debug it?

 

Edit: You can just use one function without a brackets:

if (m_set_loginAccount.find(name) != m_set_loginAccount.end())
  sys_log(0, "Thats weird ");
  return;

->

if (m_set_loginAccount.find(name) != m_set_loginAccount.end())
{
  sys_log(0, "Thats weird ");
  return;
}
  • Love 1
Link to comment
Share on other sites

  • 0
if (m_set_loginAccount.find(name) != m_set_loginAccount.end())
  sys_log(0, "Thats weird ");
  return;

Take a closer look there. You are always returning from your function! This is most likely not the problem, but it's worth noting that it is probably the reason why it doesn't go any further.

  • Love 1
Link to comment
Share on other sites

  • 0
  • Premium

It isn't a solution, at all - i commented this before and function passed to sys_log(0, "Achievement::Login DBManager ");

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 28c04300 (LWP 100122/game)]
std::_Rb_tree<std::string, std::string, std::_Identity<std::string>, std::less<std::string>, std::allocator<std::string> >::find (this=0x4, [email protected])
    at stl_tree.h:493
493           { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
(gdb) up
#1  0x0826230b in Achievement::Login (this=0x0, [email protected])
    at stl_set.h:430
430           { return _M_t.find(__x); }
(gdb) up
#2  0x08149820 in CInputLogin::Entergame (this=0x2a12c86c, d=0x2a12c800,
    data=0x2e776000 "n▒etin2client.exe") at input_login.cpp:636
636             Achievement::instance().Login(ch->GetName());
(gdb) down
#1  0x0826230b in Achievement::Login (this=0x0, [email protected])
    at stl_set.h:430
430           { return _M_t.find(__x); }
(gdb) p name
$1 = (const string &) @0xbfbfa06c: {static npos = 4294967295,
  _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x2e775c8c "Zonni"}}
(gdb) p __x
No symbol "__x" in current context.
(gdb) down
#0  std::_Rb_tree<std::string, std::string, std::_Identity<std::string>, std::less<std::string>, std::allocator<std::string> >::find (this=0x4,
    [email protected]) at stl_tree.h:493
493           { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
(gdb) p __k
$2 = (
    const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &) @0xbfbfa06c: {static npos = 4294967295,
  _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x2e775c8c "Zonni"}}
(gdb) down
Bottom (i.e., innermost) frame selected; you cannot go down.
(gdb)

Gdb result.
 
As i said - it's find function error and seriously i don't know how to pass that ...
 
my include files:
 

#include "stdafx.h"
#include "constants.h"
#include "gm.h"
#include "achievement.h"
#include "buffer_manager.h"
#include "desc_client.h"
#include "log.h"
#include "config.h"
#include "p2p.h"
#include "crc32.h"
#include "char.h"
#include "char_manager.h"
#include "questmanager.h"

 
and my header...
 

#ifndef __INC_ACHIEVEMENT_H
#define __INC_ACHIEVEMENT_H
#include "db.h"
class Achievement : public singleton<Achievement>
{
public:
  typedef std::string keyT;
  typedef const std::string & keyA;
 
  Achievement();
  virtual ~Achievement();

public:
  void Initialize();

  void Login(keyA name);
  void Logout(keyA name);
 
  void AddAchievement(keyA name, keyA id);
  void RemoveAllList(keyA name);
 
private:
  void LoadList(SQLMsg * msg);
  void SendList(keyA name);
 
  void SendGuildRank();
 
  void Destroy();
 
  std::set<keyT> m_set_loginName;
  std::map<keyT, std::set<keyT> > m_Achievements; // 1st is name, 2nd is value of earned achievement
};
#endif

I think i have std related type error because when i set std::string = "asd"; at beggining of login server crashes too.

Link to comment
Share on other sites

  • 0

You cannot do this:

std::string = "asd"

You need to set a variable name (I don't know if you meant that).

 

Regardless, it might be a library error, but that doesn't sound so likely. Can you post the rest of your code, at least Initialize()?

Also, are you calling Initialize? This is a very pretty nullpointer you have there:

Achievement::Login (this=0x0)
Link to comment
Share on other sites

  • 0
  • Premium

I know i can't do something like std::string = "asd" :D

 

I forget about initialize this in main. But anyway it doesn't work.

 

achievement_manager.cpp

 

#include "stdafx.h"
#include "constants.h"
#include "gm.h"
#include "achievement_manager.h"
#include "buffer_manager.h"
#include "desc_client.h"
#include "log.h"
#include "config.h"
#include "p2p.h"
#include "crc32.h"
#include "char.h"
#include "char_manager.h"
#include "questmanager.h"


AchievementManager::AchievementManager()
{
}

AchievementManager::~AchievementManager()
{
}

void AchievementManager::Initialize()
{
}

void AchievementManager::Destroy()
{
}

void AchievementManager::Login(AchievementManager::keyA player_name)
{

	if(test_server)
		sys_log(0, "AchievementManager::Login Start ");

	if (m_set_loginName.find(player_name) != m_set_loginName.end())
	{
		sys_log(0, "AchievementManager::Login 2nd if return ");
		return;
	}

/* 	DBManager::instance().FuncQuery(std::bind1st(std::mem_fun(&AchievementManager::LoadList), this),
			"SELECT name, achievement FROM achievement%s WHERE name='%s'", get_table_postfix(), name.c_str()); */
			
	if(test_server)
		sys_log(0, "AchievementManager::Login Query ");
			
	char szQueryA[1024+1];
	snprintf(szQueryA, sizeof(szQueryA), "SELECT name, achievement FROM achievement%s WHERE name='%s'", get_table_postfix(), player_name.c_str());
	
	if(test_server)
		sys_log(0, "AchievementManager::Login snprintf %s", szQueryA);
	
	std::auto_ptr<SQLMsg> msg(DBManager::instance().DirectQuery(szQueryA));
	
	if(test_server)
		sys_log(0, "AchievementManager::Login DBManager ");

	if (msg->Get()->uiNumRows == 0)
		return;

	std::string namea;

	sys_log(1, "AchievementManager::LoadList");

	for (uint i = 0; i < msg->Get()->uiNumRows; ++i)
	{
		MYSQL_ROW row = mysql_fetch_row(msg->Get()->pSQLResult);

		if (row[0] && row[1])
		{
			if (namea.length() == 0)
				namea = row[0];

			m_Achievements[row[0]].insert(row[1]);
		}
	}

	SendList(namea);

	std::set<AchievementManager::keyT>::iterator it;

	m_set_loginName.insert(namea);
	
	if(test_server)
		sys_log(0, "AchievementManager::Login End ");
}

void AchievementManager::LoadList(SQLMsg * msg)
{
	if(test_server)
		sys_log(0, "AchievementManager::LoadList Start ");

	if (NULL == msg)
		return;

	if (NULL == msg->Get())
		return;

	if (msg->Get()->uiNumRows == 0)
		return;

	std::string name;

	sys_log(1, "AchievementManager::LoadList");

	for (uint i = 0; i < msg->Get()->uiNumRows; ++i)
	{
		MYSQL_ROW row = mysql_fetch_row(msg->Get()->pSQLResult);

		if (row[0] && row[1])
		{
			if (name.length() == 0)
				name = row[0];

			m_Achievements[row[0]].insert(row[1]);
		}
	}

	SendList(name);

	std::set<AchievementManager::keyT>::iterator it;
	
	if(test_server)
		sys_log(0, "AchievementManager::LoadList End ");
}

void AchievementManager::SendList(AchievementManager::keyA player_name)
{
	if(test_server)
		sys_log(0, "AchievementManager::SendList Start ");
		
	LPCHARACTER ch = CHARACTER_MANAGER::instance().FindPC(player_name.c_str());

	if (!ch)
		return;

	LPDESC d = ch->GetDesc();

	if (!d)
		return;

	if (m_Achievements.find(player_name) == m_Achievements.end())
		return;

	if (m_Achievements[player_name].empty())
		return;

	itertype(m_Achievements[player_name]) it = m_Achievements[player_name].begin(), eit = m_Achievements[player_name].end();

	while (it != eit)
	{
		ch->ChatPacket(CHAT_TYPE_COMMAND, "setachievement %s", it->c_str());
		++it;
	}
	
	SendGuildRank();
	
	if(test_server)
		sys_log(0, "AchievementManager::SendList End ");
}

void AchievementManager::Logout(AchievementManager::keyA player_name)
{
	if(test_server)
		sys_log(0, "AchievementManager::Logout Start ");

	if (m_set_loginName.find(player_name) == m_set_loginName.end())
		return;

	m_set_loginName.erase(player_name);

	std::set<AchievementManager::keyT>::iterator it;

	std::map<keyT, std::set<keyT> >::iterator it2 = m_Achievements.begin();

	while (it2 != m_Achievements.end())
	{
		it2->second.erase(player_name);
		++it2;
	}

	m_Achievements.erase(player_name);
	
	if(test_server)
		sys_log(0, "AchievementManager::Logout End ");
}

void AchievementManager::RemoveAllList(keyA player_name)
{
	if(test_server)
		sys_log(0, "AchievementManager::RemoveAllList Start ");

	std::set<keyT>	company(m_Achievements[player_name]);
	DBManager::instance().Query("DELETE FROM achievement%s WHERE name='%s'",
			get_table_postfix(), player_name.c_str());

	for (std::set<keyT>::iterator iter = company.begin(); iter != company.end()
	{
		company.erase(iter++);
	}
	
	company.clear();
	
	if(test_server)
		sys_log(0, "AchievementManager::RemoveAllList End ");
}

void AchievementManager::AddAchievement(AchievementManager::keyA player_name, AchievementManager::keyA id)
{
	if(test_server)
		sys_log(0, "AchievementManager::AddAchievement Start ");

	if (id.size() == 0)
		return;

	if (m_Achievements[player_name].find(id) != m_Achievements[player_name].end())
		return;

	m_Achievements[player_name].insert(id);
	
	LPCHARACTER ch = CHARACTER_MANAGER::instance().FindPC(player_name.c_str());
	LPDESC d = ch ? ch->GetDesc() : NULL;
	
	if(d)
	{
		ch->ChatPacket(CHAT_TYPE_COMMAND, "setachievement %s", id.c_str());
	}
	
	sys_log(0, "AchievementManager Add %s %s", player_name.c_str(), id.c_str());
	DBManager::instance().Query("INSERT INTO achievement%s VALUES ('%s', '%s')", 
			get_table_postfix(), player_name.c_str(), id.c_str());
			
	if(test_server)
		sys_log(0, "AchievementManager::AddAchievement End ");
}

void AchievementManager::SendGuildRank()
{
	if(test_server)
		sys_log(0, "AchievementManager::SendGuildRank Start ");

	char szQuery[1024+1];
	char szBuf[1024+1];
	char szNew[1024+1];
	char szName[32+1];
	int level = 1;
	int rank_id = 1;
	
	snprintf(szQuery, sizeof(szQuery),
			"SELECT name, level FROM guild%s ORDER BY ladder_point DESC, level DESC, exp DESC LIMIT 10;",
			get_table_postfix());
			
	std::auto_ptr<SQLMsg> msg(DBManager::instance().DirectQuery(szQuery));
	
	if (msg->Get()->uiNumRows == 0)
	{
		return;
	}

	MYSQL_ROW row;
	while ((row = mysql_fetch_row(msg->Get()->pSQLResult))) {
		if (row[0] && *row[0]) snprintf(szName, 25, "%s", row[0]);
		if (row[1] && *row[1]) level = strtoul(row[1], NULL, 10);
		snprintf(szNew, sizeof(szNew), "%d._Lv.%d_%s|", rank_id, level, szName);
		strcat(szBuf,szNew);
		++rank_id;
	}
	
	szBuf[strlen(szBuf) - 1] = '0';
	
	LPCHARACTER ch = CHARACTER_MANAGER::instance().FindPC(szName);
	LPDESC d = ch ? ch->GetDesc() : NULL;
	
	if(d)
	{
		ch->ChatPacket(CHAT_TYPE_COMMAND, "setguildrank %s", szBuf);
		
		if (test_server)
			ch->ChatPacket(CHAT_TYPE_INFO, "setguildrank %s", szBuf);
			
	}
	
	if(test_server)
		sys_log(0, "AchievementManager::SendGuildRank End ");

}


 

 

achievement_manager.h

 

#ifndef __INC_ACHIEVEMENT_MANAGER_H
#define __INC_ACHIEVEMENT_MANAGER_H

#include "db.h"

class AchievementManager : public singleton<AchievementManager>
{
public:
  typedef std::string keyT;
  typedef const std::string & keyA;
 
  AchievementManager();
  virtual ~AchievementManager();

public:
  void Login(keyA player_name);
  void Logout(keyA player_name);
 
  void AddAchievement(keyA player_name, keyA id);
  void RemoveAllList(keyA player_name);
 
  void Initialize();
 
private:
  void LoadList(SQLMsg * msg);
  void SendList(keyA player_name);
 
  void SendGuildRank();
 
  void Destroy();
 
  std::set<keyT> m_set_loginName;
  std::map<keyT, std::set<keyT> > m_Achievements;

};

#endif

It's very smillar to messenger_manager.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

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.