MuServer Season 6 LTP - Full Server plus Sources

Started by fratika, Oct 04, 2023, 05:24 PM

dannys

#20
I solved this problem in the data server was the problem. In source, here is the corrected code for the data server qwerymanager.cpp

// QueryManager.cpp: implementation of the CQueryManager class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "QueryManager.h"
#include "Util.h"

CQueryManager gQueryManager;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CQueryManager::CQueryManager() // OK
{
   this->m_SQLEnvironment = SQL_NULL_HANDLE;
   this->m_SQLConnection = SQL_NULL_HANDLE;
   this->m_STMT = SQL_NULL_HANDLE;
   this->m_RowCount = -1;
   this->m_ColCount = -1;

   memset(this->m_SQLColName, 0, sizeof(this->m_SQLColName));
   memset(this->m_SQLData, 0, sizeof(this->m_SQLData));

   SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &this->m_SQLEnvironment);
   SQLSetEnvAttr(this->m_SQLEnvironment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);
}

CQueryManager::~CQueryManager() // OK
{
   this->Disconnect();
}

bool CQueryManager::Connect(char* odbc, char* user, char* pass, int logs) // OK
{
   strcpy_s(this->m_odbc, odbc);
   strcpy_s(this->m_user, user);
   strcpy_s(this->m_pass, pass);
   this->m_writelogs = logs;

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

   // Setează Timeout pentru conexiune (30 secunde)
   SQLSetConnectAttr(this->m_SQLConnection, SQL_LOGIN_TIMEOUT, (SQLPOINTER)30, 0);

   if (SQL_SUCCEEDED(SQLConnect(this->m_SQLConnection, (SQLCHAR*)this->m_odbc, SQL_NTS, (SQLCHAR*)this->m_user, SQL_NTS, (SQLCHAR*)this->m_pass, SQL_NTS)) == 0)
   {
      return 0;
   }

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

   return 1;
}

void CQueryManager::Disconnect() // OK
{
   if (this->m_STMT != SQL_NULL_HANDLE)
   {
      SQLFreeHandle(SQL_HANDLE_STMT, this->m_STMT);
      this->m_STMT = SQL_NULL_HANDLE;
   }

   if (this->m_SQLConnection != SQL_NULL_HANDLE)
   {
      SQLDisconnect(this->m_SQLConnection); // Important: Deconectează înainte de eliberare
      SQLFreeHandle(SQL_HANDLE_DBC, this->m_SQLConnection);
      this->m_SQLConnection = SQL_NULL_HANDLE;
   }

   if (this->m_SQLEnvironment != SQL_NULL_HANDLE)
   {
      SQLFreeHandle(SQL_HANDLE_ENV, this->m_SQLEnvironment);
      this->m_SQLEnvironment = SQL_NULL_HANDLE;
   }
}

void CQueryManager::Diagnostic(char* query) // OK
{
   LogAdd(LOG_BLACK, "%s", query);

   SQLINTEGER NativeError;
   SQLSMALLINT RecNumber = 1, BufferLength;
   SQLCHAR SqlState[6], MessageText[SQL_MAX_MESSAGE_LENGTH];

   while (SQLGetDiagRec(SQL_HANDLE_STMT, this->m_STMT, (RecNumber++), SqlState, &NativeError, MessageText, sizeof(MessageText), &BufferLength) != SQL_NO_DATA)
   {
      LogAdd(LOG_RED, "[QueryManager] State (%s), Diagnostic: %s", SqlState, MessageText);
   }

   if (strcmp((char*)SqlState, "08S01") == 0) // Communication link failure
   {
      this->Connect(this->m_odbc, this->m_user, this->m_pass, this->m_writelogs);
   }
}

bool CQueryManager::ExecQuery(char* query, ...) // REPARAT PENTRU EROARE 24000
{
   char buff[4096];

   va_list arg;
   va_start(arg, query);
   vsprintf_s(buff, query, arg);
   va_end(arg);

   if (this->m_writelogs != 0)
   {
      LogAdd(LOG_BLACK, "%s", buff);
   }

   // MODIFICARE CRITICĂ: Închidem cursorul existent înainte de a rula o nouă comandă
   // Asta previne eroarea "Invalid Cursor State" (24000)
   SQLCloseCursor(this->m_STMT);

   SQLRETURN result = SQLExecDirect(this->m_STMT, (SQLCHAR*)buff, SQL_NTS);

   if (SQL_SUCCEEDED(result) == 0 && result != SQL_NO_DATA)
   {
      this->Diagnostic(buff);
      return 0;
   }

   this->m_RowCount = -1;
   this->m_ColCount = -1;

   SQLRowCount(this->m_STMT, &this->m_RowCount);

   if (this->m_RowCount == 0) { return 1; }

   SQLNumResultCols(this->m_STMT, &this->m_ColCount);

   if (this->m_ColCount == 0) { return 1; }

   if (this->m_ColCount > MAX_COLUMNS) { return 0; }

   memset(this->m_SQLColName, 0, sizeof(this->m_SQLColName));
   memset(this->m_SQLData, 0, sizeof(this->m_SQLData));

   for (int n = 0; n < this->m_ColCount; n++)
   {
      SQLDescribeCol(this->m_STMT, (n + 1), this->m_SQLColName[n], sizeof(this->m_SQLColName[n]), 0, 0, 0, 0, 0);
      SQLBindCol(this->m_STMT, (n + 1), SQL_C_CHAR, this->m_SQLData[n], sizeof(this->m_SQLData[n]), &this->m_SQLDataLen[n]);
   }

   return 1;
}

void CQueryManager::Close() // OK
{
   // Eliberare completă a cursorului și a parametrilor
   SQLFreeStmt(this->m_STMT, SQL_CLOSE);
   SQLFreeStmt(this->m_STMT, SQL_UNBIND);
   SQLFreeStmt(this->m_STMT, SQL_RESET_PARAMS);
}

SQLRETURN CQueryManager::Fetch() // OK
{
   return SQLFetch(this->m_STMT);
}

int CQueryManager::FindIndex(char* ColName) // OK
{
   for (int n = 0; n < this->m_ColCount; n++)
   {
      if (_stricmp(ColName, (char*)this->m_SQLColName[n]) == 0)
      {
         return n;
      }
   }
   return -1;
}

int CQueryManager::GetResult(int index) // OK
{
   return atoi(this->m_SQLData[index]);
}

CSQLData CQueryManager::get(char* ColName)
{
   int index = this->FindIndex(ColName);
   if (index == -1)
   {
      return { "" };
   }
   return { this->m_SQLData[index] };
}

int CQueryManager::GetAsInteger(char* ColName) // OK
{
   int index = this->FindIndex(ColName);
   return (index == -1) ? -1 : atoi(this->m_SQLData[index]);
}

float CQueryManager::GetAsFloat(char* ColName) // OK
{
   int index = this->FindIndex(ColName);
   return (index == -1) ? 0.0f : (float)atof(this->m_SQLData[index]);
}

__int64 CQueryManager::GetAsInteger64(char* ColName) // OK
{
   int index = this->FindIndex(ColName);
   return (index == -1) ? -1 : _atoi64(this->m_SQLData[index]);
}

void CQueryManager::GetAsString(char* ColName, char* OutBuffer, int OutBufferSize) // OK
{
   int index = this->FindIndex(ColName);
   if (index == -1)
   {
      memset(OutBuffer, 0, OutBufferSize);
   }
   else
   {
      strncpy_s(OutBuffer, OutBufferSize, this->m_SQLData[index], _TRUNCATE);
   }
}

void CQueryManager::GetAsBinary(char* ColName, BYTE* OutBuffer, int OutBufferSize) // OK
{
   int index = this->FindIndex(ColName);
   if (index == -1)
   {
      memset(OutBuffer, 0, OutBufferSize);
   }
   else
   {
      this->ConvertStringToBinary(this->m_SQLData[index], sizeof(this->m_SQLData[index]), OutBuffer, OutBufferSize);
   }
}

void CQueryManager::BindParameterAsString(int ParamNumber, void* InBuffer, int ColumnSize) // OK
{
   this->m_SQLBindValue[(ParamNumber - 1)] = SQL_NTS;
   SQLBindParameter(this->m_STMT, ParamNumber, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, ColumnSize, 0, InBuffer, 0, &this->m_SQLBindValue[(ParamNumber - 1)]);
}

void CQueryManager::BindParameterAsBinary(int ParamNumber, void* InBuffer, int ColumnSize) // OK
{
   this->m_SQLBindValue[(ParamNumber - 1)] = ColumnSize;
   SQLBindParameter(this->m_STMT, ParamNumber, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_VARBINARY, ColumnSize, 0, InBuffer, 0, &this->m_SQLBindValue[(ParamNumber - 1)]);
}

void CQueryManager::ConvertStringToBinary(char* InBuff, int InSize, BYTE* OutBuff, int OutSize) // OK
{
   int size = 0;
   memset(OutBuff, 0, OutSize);
   for (int n = 0; n < InSize && size < OutSize; n++)
   {
      if (InBuff[n] == 0) break;
      if ((n % 2) == 0)
         OutBuff[size] = ((InBuff[n] >= 'A') ? ((InBuff[n] - 'A') + 10) : (InBuff[n] - '0')) * 16;
      else
      {
         OutBuff[size] |= ((InBuff[n] >= 'A') ? ((InBuff[n] - 'A') + 10) : (InBuff[n] - '0'));
         size++;
      }
   }
}

void CQueryManager::ConvertBinaryToString(BYTE* InBuff, int InSize, char* OutBuff, int OutSize) // OK
{
   int size = 0;
   memset(OutBuff, 0, OutSize);
   for (int n = 0; n < OutSize && size < InSize; n++)
   {
      if ((n % 2) == 0)
         OutBuff[n] = (((InBuff[size] / 16) >= 10) ? ('A' + ((InBuff[size] / 16) - 10)) : ('0' + (InBuff[size] / 16)));
      else
      {
         OutBuff[n] = (((InBuff[size] % 16) >= 10) ? ('A' + ((InBuff[size] % 16) - 10)) : ('0' + (InBuff[size] % 16)));
         size++;
      }
   }
}
  •  

꧁Phantasm꧂

#21
I will leave you the links in order to skip this part, there is no need if you have 1.6.11 LTP Team last touch.

Link Source: https://www.mediafire.com/file/rghdg3devpi4a0u/LTP_Last_Sources_2023.rar/file
Client: https://www.mediafire.com/file/wxft0omcmzjxpbw/LTPTeam_Client_%255B1.6.8%255D.rar/file
MuServer: https://www.mediafire.com/file/m7xs2jasypw8hz5/server_pack.rar/file

If anyone have crash client on start, recompile all server binaries, LTP.dll and GetMainInfo
Also, you need run all .sql scripts in DB/scripts/ folder.

This is from Official LTP Team itself so I could state credits to LTP Team.

I have left it without thanks button as there is already set in the post.

I will soon release a Mu Editor for LTP Monsters (done this part, I need to work on maps) for free.





Enjoy!
  •