Jump to content
Phishing - Beware of identity theft... ×

Reversed Event Functions


xP3NG3Rx

Recommended Posts

  • Honorable Member

M2 Download Center

This is the hidden content, please
( Internal )

Hi everyone.

Here are some functions what I reversed from official binary about the PythonEventManager.

1.) event.SetVisibleLineCount(descIndex, iCount) - This limits the visible count of the lines in the 'textbox'. Used in battlefield and minigames.

Spoiler

1.0.) Add the new function to the python module in PythonEventManagerModule.cpp:


PyObject * eventSetVisibleLineCount(PyObject* poSelf, PyObject* poArgs)
{
	int iIndex;
	if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
		return Py_BuildException();

	int iLineCount;
	if (!PyTuple_GetInteger(poArgs, 1, &iLineCount))
		return Py_BuildException();

	CPythonEventManager::Instance().SetVisibleLineCount(iIndex, iLineCount);
	return Py_BuildNone();
}

1.1.) Enable it in the array below:


		{ "SetVisibleLineCount",		eventSetVisibleLineCount,			METH_VARARGS },

2.) Open the PythonEventManager.h and declare the following function as public in the CPythonEventManager class where the functions are located:


		void SetVisibleLineCount(int iIndex, int iLineCount);

3.) Open the PythonEventManager.cpp and paste the new function anywhere you want:


void CPythonEventManager::SetVisibleLineCount(int iIndex, int iLineCount)
{
	if (!CheckEventSetIndex(iIndex))
		return;

	TEventSet * pEventSet = m_EventSetVector[iIndex];

	pEventSet->iVisibleLineCount = iLineCount;
}

 

2.) event.GetLineHeight(descIndex) - Gives back the height of the textline. Used in battlefield and minigames.

Spoiler

1.0.) Add the new function to the python module in PythonEventManagerModule.cpp:


PyObject * eventGetLineHeight(PyObject* poSelf, PyObject* poArgs)
{
	int iIndex;
	if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
		return Py_BuildException();

	return Py_BuildValue("i", CPythonEventManager::Instance().GetLineHeight(iIndex));
}

1.1.) Enable it in the array below:


		{ "GetLineHeight",				eventGetLineHeight,					METH_VARARGS },

2.) Open the PythonEventManager.h and declare the following function as public in the CPythonEventManager class where the functions are located:


		int GetLineHeight(int iIndex);

3.) Open the PythonEventManager.cpp and paste the new function anywhere you want:


int CPythonEventManager::GetLineHeight(int iIndex)
{
	if (!CheckEventSetIndex(iIndex))
		return 0;

	TEventSet * pEventSet = m_EventSetVector[iIndex];
	if (!pEventSet)
		return 0;

	TTextLine & rkLine = pEventSet->ScriptTextLineList.front();
	CGraphicTextInstance * pInstance = rkLine.pInstance;
	return pInstance->GetLineHeight();
}

4.) Open the EterLib\GrpTextInstance.h and declare the following function as public in the CGraphicTextInstance class where the functions are located:


		WORD GetLineHeight();

5.) Open the EterLib\GrpTextInstance.cpp and paste the new function anywhere you want:


WORD CGraphicTextInstance::GetLineHeight()
{
	return m_textHeight;
}

 

3.) event.SetYPosition(descIndex, iY) - Sets the Y position of the texts. Used for nothing yet.

Spoiler

1.0.) Add the new function to the python module in PythonEventManagerModule.cpp:


PyObject * eventSetYPosition(PyObject* poSelf, PyObject* poArgs)
{
	int iIndex;
	if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
		return Py_BuildException();
	int iY;
	if (!PyTuple_GetInteger(poArgs, 1, &iY))
		return Py_BuildException();

	CPythonEventManager::Instance().SetYPosition(iIndex, iY);
	return Py_BuildNone();
}

1.1.) Enable it in the array below:


		{ "SetYPosition",				eventSetYPosition,					METH_VARARGS },

2.) Open the PythonEventManager.h and declare the following function as public in the CPythonEventManager class where the functions are located:


		void SetYPosition(int iIndex, int iY);

3.) Open the PythonEventManager.cpp and paste the new function anywhere you want:


void CPythonEventManager::SetYPosition(int iIndex, int iY)
{
	if (!CheckEventSetIndex(iIndex))
		return;

	TEventSet * pEventSet = m_EventSetVector[iIndex];
	if (!pEventSet)
		return;

	pEventSet->iy = iY;
}

 

4.) event.GetProcessedLineCount(descIndex) - Gives back the number of the processed text lines count. Used in battlefield and minigames.

Spoiler

1.0.) Add the new function to the python module in PythonEventManagerModule.cpp:


PyObject * eventGetProcessedLineCount(PyObject* poSelf, PyObject* poArgs)
{
	int iIndex;
	if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
		return Py_BuildException();

	return Py_BuildValue("i", CPythonEventManager::Instance().GetProcessedLineCount(iIndex));
}

1.1.) Enable it in the array below:


		{ "GetProcessedLineCount",		eventGetProcessedLineCount,			METH_VARARGS },

2.) Open the PythonEventManager.h and declare the following function as public in the CPythonEventManager class where the functions are located:


		int GetProcessedLineCount(int iIndex);

3.) Open the PythonEventManager.cpp and paste the new function anywhere you want:


int CPythonEventManager::GetProcessedLineCount(int iIndex)
{
	if (!CheckEventSetIndex(iIndex))
		return 0;

	TEventSet * pEventSet = m_EventSetVector[iIndex];
	if (!pEventSet)
		return 0;

	return pEventSet->ScriptTextLineList.size();
}

 

5.) event.AllProcessEventSet(descIndex) - Instantly shows every text lines under a second. Used in battlefield and minigames. Faster than the zero delay ;)

Spoiler

1.0.) Add the new function to the python module in PythonEventManagerModule.cpp:


PyObject * eventAllProcessEventSet(PyObject* poSelf, PyObject* poArgs)
{
	int iIndex;
	if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
		return Py_BuildException();

	CPythonEventManager::Instance().AllProcessEventSet(iIndex);
	return Py_BuildNone();
}

1.1.) Enable it in the array below:


		{ "AllProcessEventSet",			eventAllProcessEventSet,			METH_VARARGS },

2.0.) Open the PythonEventManager.h and declare the following function as public in the CPythonEventManager class where the functions are located:


		void AllProcessEventSet(int iIndex);

2.1.) Change the returning type of the ProcessEventSet to boolean. (bool) 
3.0.) Open the PythonEventManager.cpp and paste the new function anywhere you want:


void CPythonEventManager::AllProcessEventSet(int iIndex)
{
	if (!CheckEventSetIndex(iIndex))
		return;

	TEventSet * pEventSet = m_EventSetVector[iIndex];
	if (!pEventSet)
		return;

	do {} while (ProcessEventSet(pEventSet));
}

3.1.) Here also, change the type of the returning value of the ProcessEventSet to bool.
3.2.) Replace every single 'return' with 'return false' in the ProcessEventSet function.
3.3.) Add the following at the bottom of the ProcessEventSet function after the switch of the iEventType: :)


	return true;

 

6.) event.GetTotalLineCount(descIndex) - Gives back the total line of the textbox. Used for new char- select and create, battlefield and minigames.

Spoiler

1.0.) Add the new function to the python module in PythonEventManagerModule.cpp:


PyObject * eventGetTotalLineCount(PyObject* poSelf, PyObject* poArgs)
{
	int iIndex;
	if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
		return Py_BuildException();

	return Py_BuildValue("i", CPythonEventManager::Instance().GetTotalLineCount(iIndex));
}

1.1.) Enable it in the array below:


		{ "GetTotalLineCount",			eventGetTotalLineCount,				METH_VARARGS },

2.0.) Open the PythonEventManager.h and declare the following function as public in the CPythonEventManager class where the functions are located:


		int GetTotalLineCount(int iIndex);

2.1.) Into the TEventSet add a new variable:


			int iTotalLineCount;

3.0.) Open the PythonEventManager.cpp and jump to the CPythonEventManager::RegisterEventSet function, then replace the following:


	if (!pEventSet->ScriptGroup.Create(strEventString))
	{
		__ClearEventSetp(pEventSet);
		return -1;
	}

With this:


	int iScriptGroup = pEventSet->ScriptGroup.Create(strEventString);
	if (-1 == iScriptGroup)
	{
		__ClearEventSetp(pEventSet);
		return -1;
	}

	pEventSet->iTotalLineCount = iScriptGroup;

3.1.) In the CPythonEventManager::RegisterEventSetFromString function replace this:


	if (!pEventSet->ScriptGroup.Create(strScript))
	{
		__ClearEventSetp(pEventSet);
		return -1;
	}

With this:


	int iScriptGroup = pEventSet->ScriptGroup.Create(strScript);
	if (-1 == iScriptGroup)
	{
		__ClearEventSetp(pEventSet);
		return -1;
	}

	pEventSet->iTotalLineCount = iScriptGroup;

3.2.) Add the following function anywhere you want:


int CPythonEventManager::GetTotalLineCount(int iIndex)
{
	if (!CheckEventSetIndex(iIndex))
		return 0;

	TEventSet * pEventSet = m_EventSetVector[iIndex];
	if (!pEventSet)
		return 0;

	return pEventSet->iTotalLineCount;
}

4.) Open the EterLib\parser.h file and change the returning value of the function Create to 'int' from 'bool'.
5.) Open then EterLib\parser.cpp file and replace the whole Create function with this:


int Group::Create(const std::string & stSource)
{
	m_cmdList.clear();

	if (stSource.empty())
		return -1;

	const char *str_base = stSource.c_str();
	if (!str_base || !*str_base)
	{
		TraceError("Source file has no content");
		return -1;
	}

	int str_len = stSource.length();
	int str_pos = 0;
	int len_line = 0;

	DWORD codePage = GetDefaultCodePage();

	char box_data[1024 + 1];

	static std::string stLetter;

	while (str_pos < str_len)
	{
		TCmd cmd;

		const char* word = str_base + str_pos;
		const char* word_next = CharNextExA(codePage, word, 0);

		int word_len = word_next - word;
		if (word_len > 1)
		{
			str_pos += word_len;

			stLetter.assign(word, word_next);
			cmd.name.assign("LETTER");
			cmd.argList.push_back(TArg("value", stLetter));
			m_cmdList.push_back(cmd);
		}
		else if (word_len == 1)
		{
			const char cur = *word;

			if ('[' == cur)
			{
				++str_pos;

				const char* box_begin = str_base + str_pos;
				const char* box_end = LocaleString_FindChar(box_begin, str_len - str_pos, ']');
				if (!box_end)
				{
					TraceError(" !! PARSING ERROR - Syntax Error : %s\n", box_begin);
					return -1;
				}

				str_pos += box_end - box_begin + 1;
				int data_len = 0;
				const char* data_begin = LocaleString_Skip(codePage, box_begin);
				const char* data_end = box_end;
				data_len = data_end - data_begin;
				if (data_len >= 1024)
				{
					TraceError(" !! PARSING ERROR - Buffer Overflow : %d, %s\n", data_len, str_base);
					return -1;
				}

				memcpy(box_data, data_begin, data_len);
				box_data[data_len] = '\0';
				data_len = LocaleString_RightTrim(box_data, data_len); // żŔ¸ĄÂĘ şóÄ ŔÚ¸Ł±â
				const char* space = LocaleString_FindChar(box_data, data_len, ' ');
				if (space)  // ŔÎŔÚ°ˇ ŔÖŔ˝
				{
					int name_len = space - box_data;
					cmd.name.assign(box_data, name_len);

					const char* space_next = CharNextExA(codePage, space, 0);
					const char* arg = LocaleString_Skip(codePage, space_next);

					int arg_len = data_len - (arg - box_data);
					if (!GetArg(arg, arg_len, cmd.argList))
					{
						TraceError(" !! PARSING ERROR - Unknown Arguments : %d, %s\n", arg_len, arg);
						return -1;
					}
				}
				else		// ŔÎŔÚ°ˇ ľřŔ¸ąÇ·Î ¸đµç ˝şĆ®¸µŔĚ ¸í·Éľî´Ů.
				{
					cmd.name.assign(box_data);
					cmd.argList.clear();
				}

				m_cmdList.push_back(cmd);
			}
			else if (cur == '\r' || cur == '\n')
			{
				if (cur=='\n') len_line += 1;
				++str_pos;
			}
			else
			{
				++str_pos;

				stLetter.assign(1, cur);
				cmd.name.assign("LETTER");
				cmd.argList.push_back(TArg("value", stLetter));
				m_cmdList.push_back(cmd);
			}
		}
		else
			break;
	}

	return len_line;
}

 

 

If you have any problem, just write a comment below.

  • Metin2 Dev 29
  • Confused 2
  • Good 5
  • Love 3
  • Love 31
Link to comment
Share on other sites

  • 4 weeks later...
// PythonEventManagerModule.cpp
PyObject * eventSetFontColor(PyObject* poSelf, PyObject* poArgs)
{
	int iIndex;
	if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
		return Py_BuildException();

	float fR;
	if (!PyTuple_GetFloat(poArgs, 1, &fR))
		return Py_BuildException();

	float fG;
	if (!PyTuple_GetFloat(poArgs, 2, &fG))
		return Py_BuildException();

	float fB;
	if (!PyTuple_GetFloat(poArgs, 3, &fB))
		return Py_BuildException();

	float fA = 1.0f;
	PyTuple_GetFloat(poArgs, 4, &fA);

	CPythonEventManager::Instance().SetFontColor(iIndex, fR, fG, fB, fA);
	return Py_BuildNone();
}

static PyMethodDef s_methods[] = {
	[...]
	{ "SetFontColor",				eventSetFontColor,					METH_VARARGS },
	[...]
}
// PythonEventManager.h
void SetFontColor(float iIndex, float fR, float fG, float fB, float fA);

// PythonEventManager.cpp
void CPythonEventManager::RenderEventSet(int iIndex)
{
	[...]
	int iCount = pEventSet->iVisibleStartLine % BOX_VISIBLE_LINE_COUNT /*0*/ ;
	[...]
}

void CPythonEventManager::SetFontColor(float iIndex, float fR, float fG, float fB, float fA)
{
	if (!CheckEventSetIndex(iIndex))
		return;

	TEventSet * pEventSet = m_EventSetVector[iIndex];
	if (!pEventSet)
		return;

	pEventSet->CurrentColor.r = fR;
	pEventSet->CurrentColor.g = fG;
	pEventSet->CurrentColor.b = fB;
	pEventSet->CurrentColor.a = fA;
}

 

  • Love 4
Link to comment
Share on other sites

  • Honorable Member

Hell yeah, I thought that one isn't new :D.
But it changes the CurrentColor instead of the Diffuse

int __thiscall CPythonEventManager::SetFontColor(_DWORD *this, int a2, float a3, float a4, float a5)
{
  int result; // eax
  unsigned int v6; // edx
  float *v7; // ecx
  _DWORD *v8; // [esp+0h] [ebp-18h]

  v8 = this;
  *(float *)&result = COERCE_FLOAT(sub_49A2C40(a2));
  if ( (_BYTE)result )
  {
    v6 = (v8[13] - v8[12]) >> 2;
    if ( a2 >= v6 )
      dummyshit00(v8 + 9, v6);
    v7 = (float *)(*(_DWORD *)(v8[12] + 4 * a2) + 32); // + 32 !
    *v7 = a3;
    v7[1] = a4;
    v7[2] = a5;
    *(float *)&result = 1.0;
    v7[3] = 1.0;
  }
  return result;
}
_DWORD *__userpurge CPythonEventManager::[email protected]<eax>(const char *[email protected]<ecx>, int [email protected]<ebx>, int [email protected]<edi>, int [email protected]<esi>, int a5)
{
  v5 = a1;
  *(_DWORD *)(a5 + 4) = 0;                      // ix
  *(_DWORD *)(a5 + 8) = 0;                      // iy
  *(_DWORD *)(a5 + 12) = 0;                     // iw
  *(_DWORD *)(a5 + 16) = 0;                     // iyl
  *(_BYTE *)(a5 + 20) = 0;                      // islock
  *(_DWORD *)(a5 + 24) = 0;                     // lastdelaytime
  *(_DWORD *)(a5 + 28) = 0;                     // curletter
  v6 = (float *)(a5 + 32);                      // curcolor + 32 !
  *v6 = 1.0;
  v6[1] = 1.0;
  v6[2] = 1.0;
  v6[3] = 1.0;
void CPythonEventManager::__InitEventSet(TEventSet& rEventSet)
{
	rEventSet.ix = 0;
	rEventSet.iy = 0;
	rEventSet.iWidth = 0;
	rEventSet.iyLocal = 0;

	rEventSet.isLock = false;
	rEventSet.lLastDelayTime = 0;
	rEventSet.iCurrentLetter = 0;
	rEventSet.CurrentColor = D3DXCOLOR(1, 1, 1, 1);
	//[...]
}

 

  • Love 4
Link to comment
Share on other sites

  • 2 years later...

Hi, I have a problem,

Spoiler

1227 06:16:08125 :: 
uiWonExchange.py(line:158) __LoadWindow
uiWonExchange.py(line:197) __BindObject
uiWonExchange.py(line:69) Open
uiWonExchange.py(line:99) __SetDescriptionEvent

WonExchangeWindow.__LoadWindow.__BindObject.UIScript/WonExchangeWindow.py - <type 'exceptions.SystemError'>:error return without exception set

1227 06:16:08125 :: ============================================================================================================
1227 06:16:08125 :: Abort!!!!

 

Link to comment
Share on other sites

  • 9 months later...


×
×
  • 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.