Jump to content
  • 0

Missing values in RecvMainCharacter?


ReFresh

Question

  • Premium
Posted (edited)

Hey guys,

I'm wondering, if this packet function can cause some bug, because there're missing some values:

Spoiler

Client/PythonNetworkStreamPhaseLoading.cpp:

bool CPythonNetworkStream::RecvMainCharacter()
	m_dwMainActorEmpire = 0; // Possible bug?

Client/Packet.h:

typedef struct packet_main_character
{
	BYTE		header;
	DWORD		dwVID;
	WORD		wRaceNum;
	char		szName[CHARACTER_NAME_MAX_LEN + 1];
	long		lX, lY, lZ;
	BYTE		bySkillGroup;
	//Missing BYTE empire or byEmpire;???
} TPacketGCMainCharacter;

Server/Packet.h:

typedef struct packet_main_character
{
	BYTE header;
	DWORD dwVID;
	WORD wRaceNum;
	char szName[CHARACTER_NAME_MAX_LEN + 1];
	long lx, ly, lz;
	BYTE empire; //Exist here. Should be here byEmpire????
	BYTE skill_group;
} TPacketGCMainCharacter;

 

Shouldn't it be like:

Spoiler

Client/PythonNetworkStreamPhaseLoading.cpp:

bool CPythonNetworkStream::RecvMainCharacter()
	m_dwMainActorEmpire = MainChrPacket.empire; //or byEmpire???

Client/Packet.h:

typedef struct packet_main_character
{
	BYTE		header;
	DWORD		dwVID;
	WORD		wRaceNum;
	char		szName[CHARACTER_NAME_MAX_LEN + 1];
	long		lX, lY, lZ;
	BYTE		empire; // or byEmpire??
	BYTE		bySkillGroup;
} TPacketGCMainCharacter;

Server/Packet.h:

typedef struct packet_main_character
{
	BYTE header;
	DWORD dwVID;
	WORD wRaceNum;
	char szName[CHARACTER_NAME_MAX_LEN + 1];
	long lx, ly, lz;
	BYTE empire; //or byEmpire???
	BYTE skill_group;
} TPacketGCMainCharacter;

 

I will be glad, if someone with programming experience can check it and tell me, if I'm right.

Thanks for possible answers!

Sincerely,

ReFresh

Edited by ReFresh

I'll be always helpful! 👊 

Link to comment
Share on other sites

4 answers to this question

Recommended Posts

  • 1
  • Premium
16 hours ago, ReFresh said:
  Reveal hidden contents

Client/PythonNetworkStreamPhaseLoading.cpp:

  Reveal hidden contents
bool CPythonNetworkStream::RecvMainCharacter()
{
	TPacketGCMainCharacter MainChrPacket;
	if (!Recv(sizeof(TPacketGCMainCharacter), &MainChrPacket))
		return false;

	m_dwMainActorVID = MainChrPacket.dwVID;
	m_dwMainActorRace = MainChrPacket.wRaceNum;
	m_dwMainActorEmpire = MainChrPacket.empire; //Here is the change
	m_dwMainActorSkillGroup = MainChrPacket.bySkillGroup;

	m_rokNetActorMgr->SetMainActorVID(m_dwMainActorVID);

	CPythonPlayer& rkPlayer=CPythonPlayer::Instance();
	rkPlayer.SetName(MainChrPacket.szName);
	rkPlayer.SetMainCharacterIndex(GetMainActorVID());

	PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOAD], "LoadData", Py_BuildValue("(ii)", MainChrPacket.lX, MainChrPacket.lY));

	//Tracef(" >> RecvMainCharacter\n");

	SendClientVersionPacket();
	return true;
}

 

Client/Packet.h:

  Reveal hidden contents
typedef struct packet_main_character
{
	BYTE		header;
	DWORD		dwVID;
	WORD		wRaceNum;
	char		szName[CHARACTER_NAME_MAX_LEN + 1];
	long		lX, lY, lZ;
  	BYTE		empire; //Here is the change
	BYTE		bySkillGroup;
} TPacketGCMainCharacter;

 

Server/Packet.h:

  Hide contents
typedef struct packet_main_character
{
	BYTE header;
	DWORD dwVID;
	WORD wRaceNum;
	char szName[CHARACTER_NAME_MAX_LEN + 1];
	long lx, ly, lz;
	BYTE empire; //Here is no change
	BYTE skill_group;
} TPacketGCMainCharacter;

 

Yes, you can have it that way, I was explaining why you shouldn't need to worry about that since the function won't be called in a default way.

  • Metin2 Dev 1
  • Love 1
Link to comment
Share on other sites

!-->
  • 1
  • Premium

Yes, the problem is there and your logical is correct.

However, it shouldn't be an issue.

 

Shal we trace a little bit?

// PythonNetworkPhaseLoading.cpp
HEADER_GC_MAIN_CHARACTER // Header calling the function
bool CPythonNetworkStream::RecvMainCharacter() // Function


// input_db.cpp
void CInputDB::PlayerLoad(LPDESC d, const char * data)
{
	....
	ch->MainCharacterPacket(); // Calling the function
}

// char.cpp
void CHARACTER::MainCharacterPacket()
{
    const unsigned mapIndex = GetMapIndex();
    const BGMInfo& bgmInfo = CHARACTER_GetBGMInfo(mapIndex);

    // SUPPORT_BGM
    if (!bgmInfo.name.empty())
    {
        if (CHARACTER_IsBGMVolumeEnable())
        {
            sys_log(1, "bgm_info.play_bgm_vol(%d, name='%s', vol=%f)", mapIndex, bgmInfo.name.c_str(), bgmInfo.vol);
            TPacketGCMainCharacter4_BGM_VOL mainChrPacket;
            mainChrPacket.header = HEADER_GC_MAIN_CHARACTER4_BGM_VOL;
            mainChrPacket.dwVID = m_vid;
            mainChrPacket.wRaceNum = GetRaceNum();
            mainChrPacket.lx = GetX();
            mainChrPacket.ly = GetY();
            mainChrPacket.lz = GetZ();
            mainChrPacket.empire = GetDesc()->GetEmpire();
            mainChrPacket.skill_group = GetSkillGroup();
            strlcpy(mainChrPacket.szChrName, GetName(), sizeof(mainChrPacket.szChrName));

            mainChrPacket.fBGMVol = bgmInfo.vol;
            strlcpy(mainChrPacket.szBGMName, bgmInfo.name.c_str(), sizeof(mainChrPacket.szBGMName));
            GetDesc()->Packet(&mainChrPacket, sizeof(TPacketGCMainCharacter4_BGM_VOL));
        }
        else
        {
            sys_log(1, "bgm_info.play(%d, '%s')", mapIndex, bgmInfo.name.c_str());
            TPacketGCMainCharacter3_BGM mainChrPacket;
            mainChrPacket.header = HEADER_GC_MAIN_CHARACTER3_BGM;
            mainChrPacket.dwVID = m_vid;
            mainChrPacket.wRaceNum = GetRaceNum();
            mainChrPacket.lx = GetX();
            mainChrPacket.ly = GetY();
            mainChrPacket.lz = GetZ();
            mainChrPacket.empire = GetDesc()->GetEmpire();
            mainChrPacket.skill_group = GetSkillGroup();
            strlcpy(mainChrPacket.szChrName, GetName(), sizeof(mainChrPacket.szChrName));
            strlcpy(mainChrPacket.szBGMName, bgmInfo.name.c_str(), sizeof(mainChrPacket.szBGMName));
            GetDesc()->Packet(&mainChrPacket, sizeof(TPacketGCMainCharacter3_BGM));
        }
        //if (m_stMobile.length())
        //		ChatPacket(CHAT_TYPE_COMMAND, "sms");
    }
    // END_OF_SUPPORT_BGM

 	.....
}

 

Let's understand first the functions:

// Getting the current map index where the player is and find out if there is any music associated to the map
const unsigned mapIndex = GetMapIndex();
const BGMInfo& bgmInfo = CHARACTER_GetBGMInfo(mapIndex);

....
  if (CHARACTER_IsBGMVolumeEnable()) // Gets if the bgm volume is enable (we'll go through this later=
  ....
}


// A std::map that assigns a map to a music.
typedef std::map<unsigned, BGMInfo> BGMInfoMap;

// Sets gs_bgmVolEnable to true
void CHARACTER_SetBGMVolumeEnable()
{
    gs_bgmVolEnable = true;
    sys_log(0, "bgm_info.set_bgm_volume_enable");
}

// Adds info to the std::map
void CHARACTER_AddBGMInfo(unsigned mapIndex, const char* name, float vol)
{
    BGMInfo newInfo;
    newInfo.name = name;
    newInfo.vol = vol;

    gs_bgmInfoMap[mapIndex] = newInfo;

    sys_log(0, "bgm_info.add_info(%d, '%s', %f)", mapIndex, name, vol);
}

// Gets the info in the std::map
const BGMInfo& CHARACTER_GetBGMInfo(unsigned mapIndex)
{
    BGMInfoMap::iterator f = gs_bgmInfoMap.find(mapIndex);
    if (gs_bgmInfoMap.end() == f)
    {
        static BGMInfo s_empty = {"", 0.0f};
        return s_empty;
    }
    return f->second;
}

 

So far, we don't quite understand what's the problem, but let's try to trace even futher.

void CHARACTER::MainCharacterPacket()
{
	const unsigned mapIndex = GetMapIndex();
	const BGMInfo& bgmInfo = CHARACTER_GetBGMInfo(mapIndex);

	if (!bgmInfo.name.empty()) // If there is any music associated to the map
	{
		if (CHARACTER_IsBGMVolumeEnable()) // If the variable gs_bgmVolEnable is true
			// something happens
		else // If the gs_bgmVolEnable variable is false
			// other stuff happens
	}
	else // If there isn't any music associated to the map
	{
		sys_log(0, "bgm_info.play(%d, DEFAULT_BGM_NAME)", mapIndex);

		TPacketGCMainCharacter pack;
		pack.header = HEADER_GC_MAIN_CHARACTER;
		pack.dwVID = m_vid;
		pack.wRaceNum = GetRaceNum();
		pack.lx = GetX();
		pack.ly = GetY();
		pack.lz = GetZ();
		pack.empire = GetDesc()->GetEmpire();
		pack.skill_group = GetSkillGroup();
		strlcpy(pack.szName, GetName(), sizeof(pack.szName));
		GetDesc()->Packet(&pack, sizeof(TPacketGCMainCharacter));
	}
}

 

But why it shouldn't happen?

Because, by default all the info is being called in settings.lua in your share folder.

add_bgm_info( 1, "enter_the_east.mp3", 0.5);
add_bgm_info(21, "enter_the_east.mp3", 0.5);
add_bgm_info(41, "enter_the_east.mp3", 0.5);
add_bgm_info( 3, "back_to_back.mp3", 0.5);
add_bgm_info(23, "back_to_back.mp3", 0.5);
add_bgm_info(43, "back_to_back.mp3", 0.5);
add_bgm_info(63, "open_the_gate.mp3", 0.5);
add_bgm_info(69, "open_the_gate.mp3", 0.5);
add_bgm_info(70, "open_the_gate.mp3", 0.5);
add_bgm_info(67, "a_rhapsody_of_war.mp3", 0.5);
add_bgm_info(68, "lost_my_name.mp3", 0.5);
add_bgm_info(65, "wonderland.mp3", 0.5);
add_bgm_info(61, "mountain_of_death.mp3", 0.5);
add_bgm_info(64, "save_me.mp3", 0.5);
add_bgm_info(74, "mountain_of_death.mp3", 0.5);
add_bgm_info(75, "follow_war_god.mp3", 0.5);
add_bgm_info(76, "mountain_of_death.mp3", 0.5);
add_bgm_info(77, "save_me.mp3", 0.5);
add_bgm_info(78, "wonderland.mp3", 0.5);
add_bgm_info(104, "Only_my_battle.mp3", 0.5);
add_bgm_info(62, "follow_war_god.mp3", 0.5);
add_bgm_info(66, "death_of_landmark.mp3", 0.5);
add_bgm_info(107, "monkey_temple.mp3", 0.5);
add_bgm_info(108, "monkey_temple.mp3", 0.5);
add_bgm_info(109, "monkey_temple.mp3", 0.5);
add_bgm_info(114, "last-war2.mp3", 0.5);
add_bgm_info(115, "last-war2.mp3", 0.5);
add_bgm_info(116, "last-war2.mp3", 0.5);
add_bgm_info(117, "last-war2.mp3", 0.5);
add_bgm_info(118, "last-war2.mp3", 0.5);
add_bgm_info(119, "last-war2.mp3", 0.5);
add_bgm_info(120, "last-war2.mp3", 0.5);
add_bgm_info(121, "last-war2.mp3", 0.5);
add_bgm_info(122, "last-war2.mp3", 0.5);
add_bgm_info(123, "last-war2.mp3", 0.5);
add_bgm_info(124, "last-war2.mp3", 0.5);
add_bgm_info(125, "last-war2.mp3", 0.5);
add_bgm_info(126, "last-war2.mp3", 0.5);
add_bgm_info(127, "last-war2.mp3", 0.5);
add_bgm_info(128, "last-war2.mp3", 0.5);
add_bgm_info(181, "last-war2.mp3", 0.5);
add_bgm_info(182, "last-war2.mp3", 0.5);
add_bgm_info(183, "last-war2.mp3", 0.5);
add_bgm_info(216, "catacomb_of_devil.mp3", 0.5);
add_bgm_info(71, "Only_my_battle.mp3", 0.5);
add_bgm_info(217, "Only_my_battle.mp3", 0.5);
add_bgm_info(301, "another_way.mp3", 0.5);
add_bgm_info(302, "misty_forest.mp3", 0.5);
add_bgm_info(303, "blacksea.mp3", 0.5);
add_bgm_info(304, "mt.mp3", 0.5);
set_bgm_volume_enable();
	int _set_bgm_volume_enable(lua_State* L)
	{
		CHARACTER_SetBGMVolumeEnable();

		return 0;
	}

	int _add_bgm_info(lua_State* L)
	{
		if (!lua_isnumber(L, 1) || !lua_isstring(L, 2))
			return 0;

		int mapIndex		= (int)lua_tonumber(L, 1);

		const char*	bgmName	= lua_tostring(L, 2);
		if (!bgmName)
			return 0;

		float bgmVol = lua_isnumber(L, 3) ? lua_tonumber(L, 3) : (1.0f/5.0f)*0.1f;

		CHARACTER_AddBGMInfo(mapIndex, bgmName, bgmVol);

		return 0;
	}

This is also being called everytime you enter the game.

So, in theory you shouldn't worry about that, but it's a nice catch and you can change it.

OBS: If there isn't any music associated to a map, it will use the default: M2BG.mp3 (inside BGM folder)

 

TLDR: Yes, but no.

  • Love 1
Link to comment
Share on other sites

  • 1
  • Premium
Posted (edited)
m_dwMainActorEmpire = 0; //What about this? Is this line right?

Shit to rewrite...

 

You should have

bool CPythonNetworkStream::RecvMainCharacter2_EMPIRE()
bool CPythonNetworkStream::RecvMainCharacter3_BGM()
bool CPythonNetworkStream::RecvMainCharacter4_BGM_VOL()

Where

    m_dwMainActorEmpire = mainChrPacket.byEmpire;

There assignment is ok because m_dwMainActorEmpire is a protected member of the class.

 

This happened probably because in past they split the packet's members in more than 1 packet for some reason (Just my first opinion after read your thread).

Edited by WeedHex
Link to comment
Share on other sites

  • 0
  • Premium
Posted (edited)

@ msnas

This is the RecvMainCharacter() function (read comments in code to know what I mean):

Default code:

Spoiler

Client/PythonNetworkStreamPhaseLoading.cpp:

Spoiler
bool CPythonNetworkStream::RecvMainCharacter()
{
	TPacketGCMainCharacter MainChrPacket;
	if (!Recv(sizeof(TPacketGCMainCharacter), &MainChrPacket))
		return false;

	m_dwMainActorVID = MainChrPacket.dwVID;
	m_dwMainActorRace = MainChrPacket.wRaceNum;
	m_dwMainActorEmpire = 0; //What about this? Is this line right?
	m_dwMainActorSkillGroup = MainChrPacket.bySkillGroup;

	m_rokNetActorMgr->SetMainActorVID(m_dwMainActorVID);

	CPythonPlayer& rkPlayer=CPythonPlayer::Instance();
	rkPlayer.SetName(MainChrPacket.szName);
	rkPlayer.SetMainCharacterIndex(GetMainActorVID());

	PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOAD], "LoadData", Py_BuildValue("(ii)", MainChrPacket.lX, MainChrPacket.lY));

	//Tracef(" >> RecvMainCharacter\n");

	SendClientVersionPacket();
	return true;
}

 

Client/Packet.h:

Spoiler
typedef struct packet_main_character
{
	BYTE		header;
	DWORD		dwVID;
	WORD		wRaceNum;
	char		szName[CHARACTER_NAME_MAX_LEN + 1];
	long		lX, lY, lZ;
	BYTE		bySkillGroup;
  	//Missing BYTE byEmpire or empire?
} TPacketGCMainCharacter;

 

Server/Packet.h:

Spoiler
typedef struct packet_main_character
{
	BYTE header;
	DWORD dwVID;
	WORD wRaceNum;
	char szName[CHARACTER_NAME_MAX_LEN + 1];
	long lx, ly, lz;
	BYTE empire; //But here in server source is the BYTE empire. Why it doesn't exist in client source?
	BYTE skill_group;
} TPacketGCMainCharacter;

 

 

So should I change it like this?

Spoiler

Client/PythonNetworkStreamPhaseLoading.cpp:

Spoiler
bool CPythonNetworkStream::RecvMainCharacter()
{
	TPacketGCMainCharacter MainChrPacket;
	if (!Recv(sizeof(TPacketGCMainCharacter), &MainChrPacket))
		return false;

	m_dwMainActorVID = MainChrPacket.dwVID;
	m_dwMainActorRace = MainChrPacket.wRaceNum;
	m_dwMainActorEmpire = MainChrPacket.empire; //Here is the change
	m_dwMainActorSkillGroup = MainChrPacket.bySkillGroup;

	m_rokNetActorMgr->SetMainActorVID(m_dwMainActorVID);

	CPythonPlayer& rkPlayer=CPythonPlayer::Instance();
	rkPlayer.SetName(MainChrPacket.szName);
	rkPlayer.SetMainCharacterIndex(GetMainActorVID());

	PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOAD], "LoadData", Py_BuildValue("(ii)", MainChrPacket.lX, MainChrPacket.lY));

	//Tracef(" >> RecvMainCharacter\n");

	SendClientVersionPacket();
	return true;
}

 

Client/Packet.h:

Spoiler
typedef struct packet_main_character
{
	BYTE		header;
	DWORD		dwVID;
	WORD		wRaceNum;
	char		szName[CHARACTER_NAME_MAX_LEN + 1];
	long		lX, lY, lZ;
  	BYTE		empire; //Here is the change
	BYTE		bySkillGroup;
} TPacketGCMainCharacter;

 

Server/Packet.h:

Spoiler
typedef struct packet_main_character
{
	BYTE header;
	DWORD dwVID;
	WORD wRaceNum;
	char szName[CHARACTER_NAME_MAX_LEN + 1];
	long lx, ly, lz;
	BYTE empire; //Here is no change
	BYTE skill_group;
} TPacketGCMainCharacter;

 

Or like this?

Spoiler

Client/PythonNetworkStreamPhaseLoading.cpp:

Spoiler
bool CPythonNetworkStream::RecvMainCharacter()
{
	TPacketGCMainCharacter MainChrPacket;
	if (!Recv(sizeof(TPacketGCMainCharacter), &MainChrPacket))
		return false;

	m_dwMainActorVID = MainChrPacket.dwVID;
	m_dwMainActorRace = MainChrPacket.wRaceNum;
	m_dwMainActorEmpire = MainChrPacket.byEmpire; //Here is the change
	m_dwMainActorSkillGroup = MainChrPacket.bySkillGroup;

	m_rokNetActorMgr->SetMainActorVID(m_dwMainActorVID);

	CPythonPlayer& rkPlayer=CPythonPlayer::Instance();
	rkPlayer.SetName(MainChrPacket.szName);
	rkPlayer.SetMainCharacterIndex(GetMainActorVID());

	PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_LOAD], "LoadData", Py_BuildValue("(ii)", MainChrPacket.lX, MainChrPacket.lY));

	//Tracef(" >> RecvMainCharacter\n");

	SendClientVersionPacket();
	return true;
}

 

Client/Packet.h:

Spoiler
typedef struct packet_main_character
{
	BYTE		header;
	DWORD		dwVID;
	WORD		wRaceNum;
	char		szName[CHARACTER_NAME_MAX_LEN + 1];
	long		lX, lY, lZ;
  	BYTE		byEmpire; //Here is the change
	BYTE		bySkillGroup;
} TPacketGCMainCharacter;

 

Server/Packet.h: 

Spoiler
typedef struct packet_main_character
{
	BYTE header;
	DWORD dwVID;
	WORD wRaceNum;
	char szName[CHARACTER_NAME_MAX_LEN + 1];
	long lx, ly, lz;
	BYTE byEmpire; //Here is the change
	BYTE skill_group;
} TPacketGCMainCharacter;

 

 

Should I change it and which change should I apply and what kind of bug it can cause, if I'll use it as it is? Check all the spoilers and compare them too see what should be probably changed.

I hope it's more clear now.

Thanks for your answer!

Edited by ReFresh

I'll be always helpful! 👊 

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.