I'm using code:
Code:
static unsigned char bBuxCode[3] = { 0xFC, 0xCF, 0xAB }; // Xox Key for some interesting things :)
#define PLAYER_EMPTY 0
#define MAX_ACCOUNT_LEN 10
#define MAX_GUILD_LEN 8
void BuxConvert(char* buf, int size)
{
for (int n = 0; n < size; n++)
{
buf[n] ^= bBuxCode[n % 3]; // Nice trick from WebZen
}
}
CRITICAL_SECTION criti;
OffTrade OfflineTrade;
OffTrade::OffTrade(void)
{
//-- CONSTRUCTOR --
}
void CloseClientHook(int aIndex)
{
if (aIndex < 0 || aIndex > OBJECT_MAX - 1)
return;
if (Player[aIndex].OfflineTrade != 0)
return;
if (gObj[aIndex].Connected == PLAYER_EMPTY)
return;
if (gObj[aIndex].m_socket != INVALID_SOCKET)
{
closesocket(gObj[aIndex].m_socket);
gObj[aIndex].m_socket = INVALID_SOCKET;
}
}
void OffTrade::InitOfflineTrade()
{
func.HookThis((DWORD)&CloseClient2Ex, 0x00401CA8); // 101%
func.HookThis((DWORD)&CGPShopAnsClose_Ex, 0x00403DE1); // 101%
func.HookThis((DWORD)&ResponErrorCloseClientEx, 0x00403ACB); //101%
func.HookThis((DWORD)&CloseClientHook, 0x00401032); // 101%
}
OffTrade::~OffTrade(void)
{
//-- DESTRUCTOR ----
}
void ResponErrorCloseClientEx(int Index)
{
if (Index < 0 || Index > OBJECT_MAX - 1)
{
func.StringSendAll("TEST01", 0);
return;
}
//OBJECTSTRUCT *gObj = (OBJECTSTRUCT*)OBJECT_POINTER(Index);
if (gObj[Index].m_bPShopOpen == 1)
{
// gObj[Index].CloseCount = -1;
//gObj[Index].CloseType = -1;
return;
}
if (Player[Index].OfflineTrade == true)
{
func.StringSendAll("TEST02", 0);
return;
}
Player[Index].OfflineTrade = true;
func.StringSendAll("TEST03", 0);
ResponErrorCloseClient(Index);
}
void OffTrade::CreateOfflineStore(int aIndex)
{
//OBJECTSTRUCT *gObj = (OBJECTSTRUCT*)OBJECT_POINTER(aIndex);
Player[aIndex].OfflineTrade = true;
CloseClient(aIndex);
}
void CGPShopAnsClose_Ex(int aIndex, BYTE btResult)
{
// Function calling when Personal store is closing.
// Also it is calling when Personal store become empty.
CGPShopAnsClose(aIndex, btResult);
if (Player[aIndex].OfflineTrade == true)
{
Player[aIndex].OfflineTrade = false;
gObjDel_Ex(aIndex);
//OBJECTSTRUCT *gObj = (OBJECTSTRUCT*)OBJECT_POINTER(aIndex);
}
}
void CloseClient2Ex(_PER_SOCKET_CONTEXT_2 * lpPerSocketContext, int result)
{
// Very easy function hooking. Just disable auto log-off of Disconnected Characters ;)
int index = -1;
index = lpPerSocketContext->nIndex;
//---
if (index >= OBJECT_MIN && index < OBJECT_MAX)
{
if (gObj->m_socket != INVALID_SOCKET)
{
if (closesocket(gObj->m_socket) == -1)
if (WSAGetLastError() != WSAENOTSOCK)
return;
gObj->m_socket = INVALID_SOCKET;
}
gObjDel_Ex(index);
}
}
short gObjDel_Ex(int aIndex)
{
//OBJECTSTRUCT *gObj = (OBJECTSTRUCT*)OBJECT_POINTER(aIndex);
if (Player[aIndex].OfflineTrade == true)
{
return 1;
}
if (aIndex < OBJECT_MIN || Player[aIndex].CloseSetCheck == true)
{
return gObjDel1(aIndex);
}
return gObjDel1(aIndex);
}