[Help] Building WzAG.dll

pafa7a

Well-Known Member
Joined
Jul 9, 2009
Messages
1,402
Reaction score
820
Здравейте съфорумници :)
Искам да направя WzAG.dll , което при написването на командата '/charinfo pafa7a' да изпълнява заявката "SELECT * FROM Character WHERE Name='pafa7a'" и да връща резултат в чата примерно :
Character : $row['Name'] - Level : $row['cLevel'] - Resets : $row['Resets'].
Ако успеете да ми направите това, ще разиграя играта с функции в сайта (куест система в сайта с която можете да взимате информация до каде сте стигнали ; от играта да обявиш предмет за продажба и да излиза в сайта и други подобни и ще направя 1 такъв Release).
Версията е 1.00.18 или 1.00.19
Имам готови SQL.cpp и SQL.h
SQL.cpp :
Code:
#include "Stdafx.h"


CSQLEx MySQL;

CSQLEx::CSQLEx()
{
}

CSQLEx::~CSQLEx()
{
    this->Disconnect();
}

void CSQLEx::Load()
{
	szDriver="{SQL Server}";
	GetPrivateProfileStringA("SQL","Host","127.0.0.1",szServer,sizeof(szServer),CUSTOM_PATH);
	GetPrivateProfileStringA("SQL","Host","127.0.0.1",szServer2,sizeof(szServer2),CUSTOM_PATH);
	GetPrivateProfileStringA("SQL","User","sa",szUser,sizeof(szUser),CUSTOM_PATH);
	GetPrivateProfileStringA("SQL","Password","12345",szPassword,sizeof(szPassword),CUSTOM_PATH);
	GetPrivateProfileStringA("SQL","Database","MuOnline",szDatabase,sizeof(szDatabase),CUSTOM_PATH);

	if(!this->Connect())
	{
		MessageBoxA(0,"Failed to connect - Check your CustomServer.ini!","Error",MB_OK);
		::ExitProcess(0);
	} 
}

bool CSQLEx::Connect()
{
    if(this->m_bConnected == 1)
	{
        return false;
	}

    if(SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&this->m_SQLEnvironment)) == 0)
    {
	    return false;
    }

    if(SQL_SUCCEEDED(SQLSetEnvAttr(this->m_SQLEnvironment,SQL_ATTR_ODBC_VERSION,(void *)SQL_OV_ODBC3,0)) == 0)
    {
        this->FreeHandle();	
        return false;
    }

    if(SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_DBC,this->m_SQLEnvironment,&this->m_SQLConnection)) == 0)
    {
        this->FreeHandle();	 
        return false;
    }

    SQLSetConnectOption(this->m_SQLConnection,SQL_LOGIN_TIMEOUT,5);	   
    SQLSetConnectOption(this->m_SQLConnection,SQL_CURSOR_TYPE,SQL_CURSOR_STATIC);

	SQLCHAR szConStrIn[1024],szConStrOut[1024];
    SQLSMALLINT iConOutSize = 0;

	sprintf((char*)szConStrIn,"DRIVER=%s; SERVER=%s; UID=%s; PWD=%s; DATABASE=%s;",szDriver,szServer2,szUser,szPassword,szDatabase);

    SQLRETURN Connect = SQLDriverConnect(this->m_SQLConnection,NULL,szConStrIn,SQL_NTS,szConStrOut,sizeof(szConStrOut),&iConOutSize,SQL_DRIVER_NOPROMPT);

    if(SQL_SUCCEEDED(Connect) == 0) 
    {
		this->FreeHandle();	 
        return false;
    }

    this->m_bConnected = 1;

    return true;
}

bool CSQLEx::ConnectExt()
{
    if(this->m_bConnected == 1)
		return false;

    if(SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&this->m_SQLEnvironment)) == 0)
	    return false;

    if(SQL_SUCCEEDED(SQLSetEnvAttr(this->m_SQLEnvironment,SQL_ATTR_ODBC_VERSION,(void *)SQL_OV_ODBC3,0)) == 0)
    {
        this->FreeHandle();	 
        return false;
    }

    if(SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_DBC,this->m_SQLEnvironment,&this->m_SQLConnection)) == 0)
    {
        this->FreeHandle();	
        return false;
    }

    SQLSetConnectOption(this->m_SQLConnection,SQL_LOGIN_TIMEOUT,5);		   
    SQLSetConnectOption(this->m_SQLConnection,SQL_CURSOR_TYPE,SQL_CURSOR_STATIC);

	SQLCHAR szConStrIn[1024],szConStrOut[1024];
    SQLSMALLINT iConOutSize = 0;

	sprintf((char*)szConStrIn,"DRIVER=%s; SERVER=%s; UID=%s; PWD=%s; DATABASE=%s;",szDriver,szServer2,szUser,szPassword,szDatabase);

    SQLRETURN Connect = SQLDriverConnect(this->m_SQLConnection,NULL,szConStrIn,SQL_NTS,szConStrOut,sizeof(szConStrOut),&iConOutSize,SQL_DRIVER_NOPROMPT);

    if(SQL_SUCCEEDED(Connect) == 0) 
    {
		this->FreeHandle();	   
        return false;
    }

    this->m_bConnected = 1;

    return true;
}

void CSQLEx::Disconnect()
{
    if(this->m_bConnected == 1)
    {
        SQLDisconnect(this->m_SQLConnection); 
		this->FreeHandle();
    }

    this->m_SQLConnection = NULL;
    this->m_SQLEnvironment = NULL;

    this->m_bConnected = 0;
}

void CSQLEx::FreeHandle()
{
    if(this->m_SQLConnection != NULL)
	    SQLFreeHandle(SQL_HANDLE_DBC,this->m_SQLConnection);
	
	if(this->m_SQLEnvironment != NULL)
	    SQLFreeHandle(SQL_HANDLE_ENV,this->m_SQLEnvironment);
}

bool CSQLEx::Execute(char* szQuery,...)
{
	if(this->m_bConnected == 0)
	{
        return false;
	}

    if(SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT,this->m_SQLConnection,&this->m_STMT)) == 0)
    {
	    return false;
	}

	char szTemp[1024];

	va_list pArguments;

	va_start(pArguments,szQuery);
	vsprintf(szTemp,szQuery,pArguments);
	va_end(pArguments);

    if(SQL_SUCCEEDED(SQLPrepare(this->m_STMT,(unsigned char*)szTemp,strlen(szTemp))) == 0)
    {
	    return false;
	}
			
	SQLRETURN Execute = SQLExecute(this->m_STMT);

    if(Execute == SQL_SUCCESS || Execute == SQL_SUCCESS_WITH_INFO || Execute == SQL_NO_DATA)
    {
	    if(SQLRowCount(this->m_STMT,&this->m_RowCount) != SQL_SUCCESS)
		{
		    this->m_RowCount = 0;
		}

		if(SQLNumResultCols(this->m_STMT,(SQLSMALLINT*)&this->m_ColCount) != SQL_SUCCESS)
		{
		    this->m_ColCount = 0;
		}

		return true;
	}

	return false;
}


char* CSQLEx::GetLastError()
{
	char szError[1024];

    SQLCHAR     szState[20];
	SQLINTEGER  iNativeError;
	SQLSMALLINT iOutErrorSize;

	SQLError(this->m_SQLEnvironment,this->m_SQLConnection,this->m_STMT,szState,&iNativeError,(SQLCHAR*)szError,sizeof(szError),&iOutErrorSize);

    return &szError[0];
}

int CSQLEx::GetRow()
{
    return this->m_RowCount;
}

int CSQLEx::GetCol()
{
	return this->m_ColCount;
}

int CSQLEx::GetInt()
{
    long lSize,lResult=0;

    while(true)
	{
	    if(SQL_SUCCEEDED(SQLFetch(this->m_STMT)) == 0)
		    break;
		
		if(SQL_SUCCEEDED(SQLGetData(this->m_STMT,1,SQL_C_LONG,&lResult,sizeof(long),&lSize)) == 0)
		    break;
		
		return lResult;
	}

	return 0;
}

void CSQLEx::GetString(char *msg)
{
    long lSize;
	char lResult[1024];

	while(true)
	{
		if(SQL_SUCCEEDED(SQLFetch(this->m_STMT)) == 0)
			break;

		if(SQL_SUCCEEDED(SQLGetData(this->m_STMT, 1, SQL_C_CHAR, &lResult,sizeof(lResult),&lSize)) == 0)
		{
			break;
		}
		else
		{
			memcpy(msg,lResult,lSize);
			msg[lSize] = '\0';
		}
	}
}

bool CSQLEx::FetchRow(char* out,int len)
{
	long lSize;

    while(true)
	{
		if(SQL_SUCCEEDED(SQLFetch(this->m_STMT)) == 0)
			break;

		for(int n=0;n < this->m_ColCount;n++)
		    if(SQL_SUCCEEDED(SQLGetData(this->m_STMT,(n+1),SQL_C_CHAR,&out[n],len,&lSize)) == 0)
			    break;
		
		return 1;
	}

	return 0;
}

SQL.h :
Code:
#ifndef _SQL_H
#define _SQL_H

class CSQLEx
{
public:
    CSQLEx();
	virtual ~CSQLEx();

	void Load();
	bool ConnectExt();
	bool Connect();
	void Disconnect();
	bool Execute(char* szQuery,...);
	char* GetLastError();
	void FreeHandle();
	int GetRow();
	int GetCol();

	int GetInt();
	void GetString(char* msg);
	bool FetchRow(char* out,int len);
	char FetchArray[1024][50];
	char*szDriver;
	char szServer[50];
	char szServer2[50];
	char szUser[50];
	char szPassword[50];
	char szDatabase[50];
private:
	bool m_bConnected;
	HENV m_SQLEnvironment;
	HDBC m_SQLConnection;
	HSTMT m_STMT;
	long m_RowCount;
	long m_ColCount;
};

extern CSQLEx MySQL;

#endif

Като пример (според мен) за заявка би трябвало да изглежда така :
Code:
MySQL.Execute("SELECT credits FROM [MuOnline].[dbo].[MEMB_CREDITS] WHERE memb___id = '%s'", gObj[aIndex].AccountID);
	int Credits = MySQL.GetInt();
А пример за функция която се изпълнява след написването на командата :
Code:
	char CommandPost[] = "/post";
	if(!memcmp(&Protocol[13],CommandPost,strlen(CommandPost)))
	{
		PostCommand(aIndex,(char*)Protocol+13+strlen(CommandPost));
	}
, но не мога да го формулирам като 1 файл и да го компилирам в .dll
 
Code:
void CreditsInfoCommand(int aIndex)
{
    MySQL.Execute("SELECT credits FROM [MuOnline].[dbo].[MEMB_CREDITS] WHERE memb___id = '%s'", gObj[aIndex].AccountID);
    int Credits = MySQL.GetInt();

    char Msg[256];
    sprintf(Msg, "You have %d credits.", Credits);
    GCServerMsgStringSend(Msg, aIndex, 1);
}

char creditsinfo[] = "/credits";
if(!memcmp(&Protocol[13],creditsinfo,strlen(creditsinfo)))
{
    CreditsInfoCommand(aIndex);
}
 
Code:
void CreditsInfoCommand(int aIndex)
{
    MySQL.Execute("SELECT credits FROM [MuOnline].[dbo].[MEMB_CREDITS] WHERE memb___id = '%s'", gObj[aIndex].AccountID);
    int Credits = MySQL.GetInt();

    char Msg[256];
    sprintf(Msg, "You have %d credits.", Credits);
    GCServerMsgStringSend(Msg, aIndex, 1);
}

char creditsinfo[] = "/credits";
if(!memcmp(&Protocol[13],creditsinfo,strlen(creditsinfo)))
{
    CreditsInfoCommand(aIndex);
}

А може ли да качиш целия проект в архив ? (solution)
Защото незнам кои инклуди ми трябват
 
Предполагаше се че вече имаш съществуващ проект. (xax)
 
Предполагаше се че вече имаш съществуващ проект. (xax)
Дар но е бъкат с излишни работи и незнам само кое да оставя
 
Прикачи проекта или ми го прати на лс.
 
Отваряш Commands.cpp и под:
Code:
void BuyVipCommand(int aIndex,LPCSTR Buffer)
{
    ...
}
Добавяш:
Code:
void CreditsInfoCommand(int aIndex)
{
    MySQL.Execute("SELECT credits FROM [MuOnline].[dbo].[MEMB_CREDITS] WHERE memb___id = '%s'", gObj[aIndex].AccountID);
    int Credits = MySQL.GetInt();

    char Msg[256];
    sprintf(Msg, "You have %d credits.", Credits);
    GCServerMsgStringSend(Msg, aIndex, 1);
}
Под:
Code:
char CommandOffTrade[] = "/off";
if(!memcmp(&Protocol[13],CommandOffTrade,strlen(CommandOffTrade)))
{
    OffTrade.CreateOfflineTrade(aIndex);
}
Добавяш:
Code:
char creditsinfo[] = "/credits";
if(!memcmp(&Protocol[13],creditsinfo,strlen(creditsinfo)))
{
    CreditsInfoCommand(aIndex);
}
И компилираш.
 
А можеш ли да ми изброиш само кои файлове са ми нужни за да си работи без проблем (всичко останало искам да го изтрия)
 
На пръв поглед:
InitDll.cpp, Protocol.cpp, Protocol.h, Commands.cpp, Commands.h, User.cpp, User.h, Item.h (User.h ще си го търси (xax)), SQL.cpp, SQL.h и StdAfx.h

Разбира се ще има чистене и в тези файлове. (xax)
 
Добави
Code:
*(DWORD*)(0x00403314+1) = (DWORD)&ProtocolCoreEx - (0x00403314+5);
под
Code:
MySQL.Load();
в InitDll.cpp
 
След хуук не се случва абсолютно нищо
 
Last edited:
Увери се че адресите съответстват с тези на геймсървъра ти. Също ми направи снимка на хуук-а с olly.
 
Извинявам се ако си обърнал внимание на тези неща,
но понеже виждам,че е писано само за 2-3 ,а всъщност има и доста подробности...
Например:
-Трябва да добавиш командата/настройките в двата файла:

"StdAfx.h"
Code:
#define COMMAND_PATH  "..\\data\\custom\\commandsettings.cfg"
#define CUSTOM_PATH  "..\\data\\custom\\customserver.ini"

-Другото е,че не го виждам описано и в класовете.
Примерно в (User.h) "struct OBJECTSTRUCT" както ги има всички останали...
Code:
/*<thisrel this+0x68>*/ /*|0xb|*/ char AccountID[11];
/*<thisrel this+0x73>*/ /*|0xb|*/ char Name[11];
/*<thisrel this+0x9c>*/ /*|0x2|*/ unsigned short Class;
.....
(дано не бъркам,но според мен трябва да има и "Credits").

-И другата ми мисъл е:
Не трябва ли да се конфигурират настройки и във:
(Structures.h)
"struct COMMANDS_INFO",
"extern CUSTOM_GS_STRUCT conf"
както останалите екстри,които имат настройки там... (think)
 
Бъркаш колега.

Structures.cpp & .h ще ги погледна когато седна на компютъра.

#Edit
И там няма нужда от пипане.
 
Хуука го извършвам с програмата Stup PE. Прикачвам GameServer папката, защото и аз вече почнах да си мисля, че адресите не съответстват с тези на геймсървъра
PS. Тук WzAG.dll не е хуукнат (ако може го хуукнете с ollydbg)
 

Attachments

  • gs.rar
    1.5 MB · Views: 8
Адресите определено не са за този геймсървър.
Code:
pProtocolCore ProtocolCore = (pProtocolCore) [COLOR=Red]0x0042FCB0[/COLOR];
Става на
Code:
pProtocolCore ProtocolCore = (pProtocolCore) [COLOR=Red]0x0054C430[/COLOR];
-
Code:
pGCServerMsgStringSend GCServerMsgStringSend = (pGCServerMsgStringSend) [COLOR=Red]0x004060FA[/COLOR];
Става на
Code:
pGCServerMsgStringSend GCServerMsgStringSend = (pGCServerMsgStringSend) [COLOR=Red]0x0054F510[/COLOR];
-
Code:
*(DWORD*)([COLOR=Red]0x00403314[/COLOR]+1) = (DWORD)&ProtocolCoreEx - ([COLOR=Red]0x00403314[/COLOR]+5);
Става на
Code:
*(DWORD*)([COLOR=Red]0x00403BA7[/COLOR]+1) = (DWORD)&ProtocolCoreEx - ([COLOR=Red]0x00403BA7[/COLOR]+5);
Останалите не ги използваш.
 

Attachments

  • GameServer.rar
    577 KB · Views: 8
  • Like
Reactions: pafa7a
Сега командата /credits си работи, но всичко от ExGame.dll не
 
Сега командата /credits си работи, но всичко от ExGame.dll не
Още вчера в чата ти казах че ще стане така. (xax)