Login To Vote
Sign in and rate this file in one click.
  • MuServer Season 6 LTP - Full Server plus Sources 5 0 5 2

MuServer Season 6 LTP - Full Server plus Sources

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

#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++;
      }
   }
}
  •  

#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!
  •  
    The following users thanked this post: Xeros

Hi guys,

have someone same trouble with this files? i buildet .dll and new main maker, and after loading screen client close. I dont get dissconect window. Just close. I dont know where im doin mistake...

Thanks for response :)
  •  

  •  

Quote from: ꧁Phantasm꧂ on Feb 27, 2026, 06:46 PM
Quote from: dannys on Feb 23, 2026, 12:11 AMI have a problem, I started the server and it works, but it's enough to enter the game once, then I close the server and when I open it, I go into the account and it appears to me to create a new character and the old character doesn't show and I can't make a new one. It's a problem with the DB from the start, it works, then it doesn't and all the scripts are made in qwery. Has anyone else encountered this problem?

Hello, Dannys.

I would recommend, first the server/game works fine in terms of what have you described (tested by me, I have even fixed the maps from tab keyboard and Vulcanus view, so the game works ace, loads to fix, but nothing alike the problem you have described so far), second redo everything from start. DB works fine (never what you have mentioned), probably the thing left to config in terms of database is the CS time/date.





Link to DB Folder that I am utilising:

This content is hidden and cannot be quoted.
  •  

Use lua53 instead of lua52. It worked for me.
  •  

#26
Hello everyone,

I have made a simple tutorial, very explicit with what you have to do in order to start all the functionality of this MuServer.

Please find the yt link here :

Don't forget to resto db and press necessary .reg (mine already restored).
  •