Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // The C Plus Plus headers.
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <ctype.h>
- #include <stdarg.h>
- // The other further headers.
- #include "amxxmodule.h"
- #include "mysql.h"
- // The definitions.
- #define MAXIMUM_CHARACTERS_FOR_STRING 4096U
- #define MAXIMUM_CHARACTERS_FOR_COLUMN 128U
- #define MAXIMUM_ROWS_TO_SELECT 2048U
- #define MAXIMUM_COLUMNS_TO_HAVE 64U
- #define CONFIGURATION_FILE "RemoteDatabaseInformation.ini"
- // The Database_Row class. Each row will contain 64 columns as long as 128 maximum characters.
- class Database_Row
- {
- public:
- char Column[MAXIMUM_COLUMNS_TO_HAVE][MAXIMUM_CHARACTERS_FOR_COLUMN];
- };
- // The data used into the extension.
- char g_Connected = FALSE;
- char g_QueryFailState = FALSE;
- Database_Row g_Row[MAXIMUM_ROWS_TO_SELECT];
- MYSQL * g_Handle = NULL;
- MYSQL_RES * g_Result = NULL;
- MYSQL_ROW g_MySQLRow = NULL;
- char g_String[MAXIMUM_CHARACTERS_FOR_STRING];
- char g_ConfigurationFile[256U];
- char g_Line[256U];
- char g_Hostname[128U];
- char g_Password[128U];
- char g_Username[128U];
- char g_Database[128U];
- int g_Rows = 0U;
- int g_Fields = 0U;
- int g_Iterator = 0U;
- int g_Length = 0U;
- int g_Written = 0U;
- FILE * g_File = NULL;
- const char * g_Query = NULL;
- // Util functions.
- void Trim(char * Line)
- {
- while (isspace(*Line) || *Line == ' ' || *Line == '\t')
- {
- Line++;
- }
- for (g_Iterator = strlen(Line) - 1U; g_Iterator >= 0U && (isspace(Line[g_Iterator]) || \
- Line[g_Iterator] == '\t' || Line[g_Iterator] == ' '); g_Iterator--)
- {
- Line[g_Iterator] = 0U;
- }
- }
- int GetCharPos(char * Line, char Char)
- {
- if (Line)
- {
- for (g_Iterator = 0; g_Iterator < (int)strlen(Line); g_Iterator++)
- {
- if (Line[g_Iterator] == Char)
- {
- return g_Iterator;
- }
- }
- }
- return -1;
- }
- // The AMX Mod X functions.
- static cell AMX_NATIVE_CALL Query(AMX * Handle, cell * Parameters)
- {
- g_Rows = 0U;
- if (g_Connected)
- {
- g_Query = MF_GetAmxString(Handle, Parameters[1U], 0U, &g_Length);
- g_QueryFailState = mysql_real_query(g_Handle, g_Query, g_Length) ? TRUE : FALSE;
- if (!g_QueryFailState)
- {
- if (Parameters[2U])
- {
- g_Result = mysql_store_result(g_Handle);
- g_Fields = mysql_num_fields(g_Result);
- while ((g_MySQLRow = mysql_fetch_row(g_Result)))
- {
- if (g_Rows < MAXIMUM_ROWS_TO_SELECT)
- {
- for (g_Iterator = 0; g_Iterator < g_Fields && g_Iterator < MAXIMUM_COLUMNS_TO_HAVE; g_Iterator++)
- {
- _snprintf(g_Row[g_Rows].Column[g_Iterator], MAXIMUM_CHARACTERS_FOR_COLUMN, "%s", g_MySQLRow[g_Iterator] \
- ? g_MySQLRow[g_Iterator] : "NULL");
- }
- }
- g_Rows++;
- }
- mysql_free_result(g_Result);
- }
- }
- else
- {
- MF_LogError(Handle, AMX_ERR_NATIVE, "Query '%s' is bad. MySQL reported the next error: '%s'.", \
- g_Query, mysql_error(g_Handle));
- }
- }
- return g_Rows;
- }
- static cell AMX_NATIVE_CALL Get(AMX * Handle, cell * Parameters)
- {
- // If the coder will fail, this won't log any error. Will just set the buffer as "NULL" and will return zero.
- if (Parameters[1U] >= 0U && Parameters[1U] < MAXIMUM_ROWS_TO_SELECT && Parameters[2U] >= 0U && \
- Parameters[2U] < MAXIMUM_COLUMNS_TO_HAVE)
- {
- MF_SetAmxString(Handle, Parameters[3U], g_Row[Parameters[1U]].Column[Parameters[2U]], Parameters[4U]);
- return (cell)atoi(g_Row[Parameters[1U]].Column[Parameters[2U]]);
- }
- MF_SetAmxString(Handle, Parameters[3U], "NULL", Parameters[4U]);
- return 0U;
- }
- static cell AMX_NATIVE_CALL Safe(AMX * Handle, cell * Parameters)
- {
- // Run into an error whether coder wants to replace a bad character with another bad character.
- if (Parameters[2U] == '\'' || Parameters[2U] == '"' || Parameters[2U] == '\\' || Parameters[2U] == '`')
- {
- MF_LogError(Handle, AMX_ERR_NATIVE, \
- "Unable to replace a bad character with another bad character. Bad characters are \\, ', \" and `.");
- return 0U;
- }
- g_Length = _snprintf(g_String, MAXIMUM_CHARACTERS_FOR_STRING, "%s", MF_GetAmxString(Handle, Parameters[1U], 0U, 0U));
- // Check for each character.
- for (g_Iterator = 0U; g_Iterator < g_Length; g_Iterator++)
- {
- if (g_String[g_Iterator] == '\'' || g_String[g_Iterator] == '"' || g_String[g_Iterator] == '\\' \
- || g_String[g_Iterator] == '`')
- {
- // Replace bad character with the given one.
- g_String[g_Iterator] = (char)Parameters[2U];
- }
- }
- MF_SetAmxString(Handle, Parameters[1U], g_String, g_Length);
- return 1U;
- }
- const AMX_NATIVE_INFO g_Functions[] =
- {
- { "RemDatabase_Query", Query },
- { "RemDatabase_Get", Get },
- { "RemDatabase_Safe", Safe },
- { NULL, NULL }
- };
- void OnAmxxAttach(void)
- {
- static const my_bool Reconnect = (my_bool)TRUE;
- static const unsigned int Timeout = (unsigned int)180U;
- MF_AddNatives(g_Functions);
- g_Handle = mysql_init(NULL);
- mysql_options(g_Handle, MYSQL_OPT_RECONNECT, &Reconnect);
- mysql_options(g_Handle, MYSQL_OPT_CONNECT_TIMEOUT, &Timeout);
- mysql_options(g_Handle, MYSQL_OPT_WRITE_TIMEOUT, &Timeout);
- mysql_options(g_Handle, MYSQL_OPT_READ_TIMEOUT, &Timeout);
- _snprintf(g_ConfigurationFile, sizeof(g_ConfigurationFile), "%s/%s/%s", \
- MF_GetModname(), MF_GetLocalInfo("amxx_configsdir", "addons/amxmodx/configs"), \
- CONFIGURATION_FILE);
- g_File = fopen(g_ConfigurationFile, "rt");
- if (g_File)
- {
- while (!feof(g_File))
- {
- g_Line[0] = '\0';
- fgets(g_Line, sizeof(g_Line), g_File);
- Trim(g_Line);
- if (g_Line[0U] != 0U)
- {
- if (!strnicmp(g_Line, "Hostname:", 9U))
- {
- g_Iterator = GetCharPos(g_Line, ':');
- if (g_Iterator >= 0U)
- {
- g_Written = 0U;
- while (g_Line[g_Iterator] && g_Written < sizeof(g_Hostname))
- {
- if (g_Line[g_Iterator] == ':')
- {
- g_Iterator++;
- continue;
- }
- g_Hostname[g_Written++] = g_Line[g_Iterator++];
- }
- g_Hostname[g_Written] = 0U;
- Trim(g_Hostname);
- }
- }
- else if (!strnicmp(g_Line, "Username:", 9U))
- {
- g_Iterator = GetCharPos(g_Line, ':');
- if (g_Iterator >= 0U)
- {
- g_Written = 0U;
- while (g_Line[g_Iterator] && g_Written < sizeof(g_Username))
- {
- if (g_Line[g_Iterator] == ':')
- {
- g_Iterator++;
- continue;
- }
- g_Username[g_Written++] = g_Line[g_Iterator++];
- }
- g_Username[g_Written] = 0U;
- Trim(g_Username);
- }
- }
- else if (!strnicmp(g_Line, "Password:", 9U))
- {
- g_Iterator = GetCharPos(g_Line, ':');
- if (g_Iterator >= 0U)
- {
- g_Written = 0U;
- while (g_Line[g_Iterator] && g_Written < sizeof(g_Password))
- {
- if (g_Line[g_Iterator] == ':')
- {
- g_Iterator++;
- continue;
- }
- g_Password[g_Written++] = g_Line[g_Iterator++];
- }
- g_Password[g_Written] = 0U;
- Trim(g_Password);
- }
- }
- else if (!strnicmp(g_Line, "Database:", 9U))
- {
- g_Iterator = GetCharPos(g_Line, ':');
- if (g_Iterator >= 0U)
- {
- g_Written = 0U;
- while (g_Line[g_Iterator] && g_Written < sizeof(g_Database))
- {
- if (g_Line[g_Iterator] == ':')
- {
- g_Iterator++;
- continue;
- }
- g_Database[g_Written++] = g_Line[g_Iterator++];
- }
- g_Database[g_Written] = 0U;
- Trim(g_Database);
- }
- }
- }
- }
- fclose(g_File);
- if (mysql_real_connect(g_Handle, g_Hostname, g_Username, g_Password, g_Database, 0U, NULL, 0U) != NULL)
- {
- printf("[Remote Database] The connection to '%s' has been established!\n", g_Hostname);
- g_Connected = TRUE;
- }
- else
- {
- printf("[Remote Database] The connection to '%s' has not been established! MySQL reported the next error: '%s'.\n", \
- g_Hostname, mysql_error(g_Handle));
- g_Connected = FALSE;
- }
- }
- else
- {
- printf("[Remote Database] Unable to open 'RemoteDatabaseInformation.ini' for reading!\n");
- }
- }
- void OnAmxxDetach(void)
- {
- mysql_close(g_Handle);
- g_Connected = FALSE;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement