Advertisement
Guest User

Remote Database 1.0.0.1

a guest
Mar 16th, 2014
376
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.02 KB | None | 0 0
  1. // The C Plus Plus headers.
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <math.h>
  6. #include <ctype.h>
  7. #include <stdarg.h>
  8.  
  9. // The other further headers.
  10. #include "amxxmodule.h"
  11. #include "mysql.h"
  12.  
  13. // The definitions.
  14. #define MAXIMUM_CHARACTERS_FOR_STRING   4096U
  15. #define MAXIMUM_CHARACTERS_FOR_COLUMN   128U
  16. #define MAXIMUM_ROWS_TO_SELECT          2048U
  17. #define MAXIMUM_COLUMNS_TO_HAVE         64U
  18. #define CONFIGURATION_FILE          "RemoteDatabaseInformation.ini"
  19.  
  20. // The Database_Row class. Each row will contain 64 columns as long as 128 maximum characters.
  21. class Database_Row
  22. {
  23. public:
  24.     char Column[MAXIMUM_COLUMNS_TO_HAVE][MAXIMUM_CHARACTERS_FOR_COLUMN];
  25. };
  26.  
  27. // The data used into the extension.
  28. char g_Connected = FALSE;
  29. char g_QueryFailState = FALSE;
  30.  
  31. Database_Row g_Row[MAXIMUM_ROWS_TO_SELECT];
  32.  
  33. MYSQL * g_Handle = NULL;
  34. MYSQL_RES * g_Result = NULL;
  35. MYSQL_ROW g_MySQLRow = NULL;
  36.  
  37. char g_String[MAXIMUM_CHARACTERS_FOR_STRING];
  38.  
  39. char g_ConfigurationFile[256U];
  40.  
  41. char g_Line[256U];
  42.  
  43. char g_Hostname[128U];
  44. char g_Password[128U];
  45. char g_Username[128U];
  46. char g_Database[128U];
  47.  
  48. int g_Rows = 0U;
  49. int g_Fields = 0U;
  50. int g_Iterator = 0U;
  51. int g_Length = 0U;
  52. int g_Written = 0U;
  53.  
  54. FILE * g_File = NULL;
  55.  
  56. const char * g_Query = NULL;
  57.  
  58. // Util functions.
  59. void Trim(char * Line)
  60. {
  61.     while (isspace(*Line) || *Line == ' ' || *Line == '\t')
  62.     {
  63.         Line++;
  64.     }
  65.  
  66.     for (g_Iterator = strlen(Line) - 1U; g_Iterator >= 0U && (isspace(Line[g_Iterator]) || \
  67.         Line[g_Iterator] == '\t' || Line[g_Iterator] == ' '); g_Iterator--)
  68.     {
  69.         Line[g_Iterator] = 0U;
  70.     }
  71. }
  72.  
  73. int GetCharPos(char * Line, char Char)
  74. {
  75.     if (Line)
  76.     {
  77.         for (g_Iterator = 0; g_Iterator < (int)strlen(Line); g_Iterator++)
  78.         {
  79.             if (Line[g_Iterator] == Char)
  80.             {
  81.                 return g_Iterator;
  82.             }
  83.         }
  84.     }
  85.  
  86.     return -1;
  87. }
  88.  
  89. // The AMX Mod X functions.
  90. static cell AMX_NATIVE_CALL Query(AMX * Handle, cell * Parameters)
  91. {
  92.     g_Rows = 0U;
  93.  
  94.     if (g_Connected)
  95.     {
  96.         g_Query = MF_GetAmxString(Handle, Parameters[1U], 0U, &g_Length);
  97.         g_QueryFailState = mysql_real_query(g_Handle, g_Query, g_Length) ? TRUE : FALSE;
  98.  
  99.         if (!g_QueryFailState)
  100.         {
  101.             if (Parameters[2U])
  102.             {
  103.                 g_Result = mysql_store_result(g_Handle);
  104.                 g_Fields = mysql_num_fields(g_Result);
  105.  
  106.                 while ((g_MySQLRow = mysql_fetch_row(g_Result)))
  107.                 {
  108.                     if (g_Rows < MAXIMUM_ROWS_TO_SELECT)
  109.                     {
  110.                         for (g_Iterator = 0; g_Iterator < g_Fields && g_Iterator < MAXIMUM_COLUMNS_TO_HAVE; g_Iterator++)
  111.                         {
  112.                             _snprintf(g_Row[g_Rows].Column[g_Iterator], MAXIMUM_CHARACTERS_FOR_COLUMN, "%s", g_MySQLRow[g_Iterator] \
  113.                                 ? g_MySQLRow[g_Iterator] : "NULL");
  114.                         }
  115.                     }
  116.  
  117.                     g_Rows++;
  118.                 }
  119.  
  120.                 mysql_free_result(g_Result);
  121.             }
  122.         }
  123.  
  124.         else
  125.         {
  126.             MF_LogError(Handle, AMX_ERR_NATIVE, "Query '%s' is bad. MySQL reported the next error: '%s'.", \
  127.                 g_Query, mysql_error(g_Handle));
  128.         }
  129.     }
  130.  
  131.     return g_Rows;
  132. }
  133.  
  134. static cell AMX_NATIVE_CALL Get(AMX * Handle, cell * Parameters)
  135. {
  136.     // If the coder will fail, this won't log any error. Will just set the buffer as "NULL" and will return zero.
  137.     if (Parameters[1U] >= 0U && Parameters[1U] < MAXIMUM_ROWS_TO_SELECT && Parameters[2U] >= 0U && \
  138.         Parameters[2U] < MAXIMUM_COLUMNS_TO_HAVE)
  139.     {
  140.         MF_SetAmxString(Handle, Parameters[3U], g_Row[Parameters[1U]].Column[Parameters[2U]], Parameters[4U]);
  141.  
  142.         return (cell)atoi(g_Row[Parameters[1U]].Column[Parameters[2U]]);
  143.     }
  144.  
  145.     MF_SetAmxString(Handle, Parameters[3U], "NULL", Parameters[4U]);
  146.  
  147.     return 0U;
  148. }
  149.  
  150. static cell AMX_NATIVE_CALL Safe(AMX * Handle, cell * Parameters)
  151. {
  152.     // Run into an error whether coder wants to replace a bad character with another bad character.
  153.     if (Parameters[2U] == '\'' || Parameters[2U] == '"' || Parameters[2U] == '\\' || Parameters[2U] == '`')
  154.     {
  155.         MF_LogError(Handle, AMX_ERR_NATIVE, \
  156.             "Unable to replace a bad character with another bad character. Bad characters are \\, ', \" and `.");
  157.  
  158.         return 0U;
  159.     }
  160.  
  161.     g_Length = _snprintf(g_String, MAXIMUM_CHARACTERS_FOR_STRING, "%s", MF_GetAmxString(Handle, Parameters[1U], 0U, 0U));
  162.  
  163.     // Check for each character.
  164.     for (g_Iterator = 0U; g_Iterator < g_Length; g_Iterator++)
  165.     {
  166.         if (g_String[g_Iterator] == '\'' || g_String[g_Iterator] == '"' || g_String[g_Iterator] == '\\' \
  167.             || g_String[g_Iterator] == '`')
  168.         {
  169.             // Replace bad character with the given one.
  170.             g_String[g_Iterator] = (char)Parameters[2U];
  171.         }
  172.     }
  173.  
  174.     MF_SetAmxString(Handle, Parameters[1U], g_String, g_Length);
  175.  
  176.     return 1U;
  177. }
  178.  
  179. const AMX_NATIVE_INFO g_Functions[] =
  180. {
  181.     { "RemDatabase_Query", Query },
  182.     { "RemDatabase_Get", Get },
  183.     { "RemDatabase_Safe", Safe },
  184.  
  185.     { NULL, NULL }
  186. };
  187.  
  188. void OnAmxxAttach(void)
  189. {
  190.     static const my_bool Reconnect = (my_bool)TRUE;
  191.     static const unsigned int Timeout = (unsigned int)180U;
  192.  
  193.     MF_AddNatives(g_Functions);
  194.  
  195.     g_Handle = mysql_init(NULL);
  196.  
  197.     mysql_options(g_Handle, MYSQL_OPT_RECONNECT, &Reconnect);
  198.     mysql_options(g_Handle, MYSQL_OPT_CONNECT_TIMEOUT, &Timeout);
  199.     mysql_options(g_Handle, MYSQL_OPT_WRITE_TIMEOUT, &Timeout);
  200.     mysql_options(g_Handle, MYSQL_OPT_READ_TIMEOUT, &Timeout);
  201.  
  202.     _snprintf(g_ConfigurationFile, sizeof(g_ConfigurationFile), "%s/%s/%s", \
  203.         MF_GetModname(), MF_GetLocalInfo("amxx_configsdir", "addons/amxmodx/configs"), \
  204.         CONFIGURATION_FILE);
  205.  
  206.     g_File = fopen(g_ConfigurationFile, "rt");
  207.  
  208.     if (g_File)
  209.     {
  210.         while (!feof(g_File))
  211.         {
  212.             g_Line[0] = '\0';
  213.  
  214.             fgets(g_Line, sizeof(g_Line), g_File);
  215.  
  216.             Trim(g_Line);
  217.  
  218.             if (g_Line[0U] != 0U)
  219.             {
  220.                 if (!strnicmp(g_Line, "Hostname:", 9U))
  221.                 {
  222.                     g_Iterator = GetCharPos(g_Line, ':');
  223.  
  224.                     if (g_Iterator >= 0U)
  225.                     {
  226.                         g_Written = 0U;
  227.  
  228.                         while (g_Line[g_Iterator] && g_Written < sizeof(g_Hostname))
  229.                         {
  230.                             if (g_Line[g_Iterator] == ':')
  231.                             {
  232.                                 g_Iterator++;
  233.  
  234.                                 continue;
  235.                             }
  236.  
  237.                             g_Hostname[g_Written++] = g_Line[g_Iterator++];
  238.                         }
  239.  
  240.                         g_Hostname[g_Written] = 0U;
  241.  
  242.                         Trim(g_Hostname);
  243.                     }
  244.                 }
  245.  
  246.                 else if (!strnicmp(g_Line, "Username:", 9U))
  247.                 {
  248.                     g_Iterator = GetCharPos(g_Line, ':');
  249.  
  250.                     if (g_Iterator >= 0U)
  251.                     {
  252.                         g_Written = 0U;
  253.  
  254.                         while (g_Line[g_Iterator] && g_Written < sizeof(g_Username))
  255.                         {
  256.                             if (g_Line[g_Iterator] == ':')
  257.                             {
  258.                                 g_Iterator++;
  259.  
  260.                                 continue;
  261.                             }
  262.  
  263.                             g_Username[g_Written++] = g_Line[g_Iterator++];
  264.                         }
  265.  
  266.                         g_Username[g_Written] = 0U;
  267.  
  268.                         Trim(g_Username);
  269.                     }
  270.                 }
  271.  
  272.                 else if (!strnicmp(g_Line, "Password:", 9U))
  273.                 {
  274.                     g_Iterator = GetCharPos(g_Line, ':');
  275.  
  276.                     if (g_Iterator >= 0U)
  277.                     {
  278.                         g_Written = 0U;
  279.  
  280.                         while (g_Line[g_Iterator] && g_Written < sizeof(g_Password))
  281.                         {
  282.                             if (g_Line[g_Iterator] == ':')
  283.                             {
  284.                                 g_Iterator++;
  285.  
  286.                                 continue;
  287.                             }
  288.  
  289.                             g_Password[g_Written++] = g_Line[g_Iterator++];
  290.                         }
  291.  
  292.                         g_Password[g_Written] = 0U;
  293.  
  294.                         Trim(g_Password);
  295.                     }
  296.                 }
  297.  
  298.                 else if (!strnicmp(g_Line, "Database:", 9U))
  299.                 {
  300.                     g_Iterator = GetCharPos(g_Line, ':');
  301.  
  302.                     if (g_Iterator >= 0U)
  303.                     {
  304.                         g_Written = 0U;
  305.  
  306.                         while (g_Line[g_Iterator] && g_Written < sizeof(g_Database))
  307.                         {
  308.                             if (g_Line[g_Iterator] == ':')
  309.                             {
  310.                                 g_Iterator++;
  311.  
  312.                                 continue;
  313.                             }
  314.  
  315.                             g_Database[g_Written++] = g_Line[g_Iterator++];
  316.                         }
  317.  
  318.                         g_Database[g_Written] = 0U;
  319.  
  320.                         Trim(g_Database);
  321.                     }
  322.                 }
  323.             }
  324.         }
  325.  
  326.         fclose(g_File);
  327.  
  328.         if (mysql_real_connect(g_Handle, g_Hostname, g_Username, g_Password, g_Database, 0U, NULL, 0U) != NULL)
  329.         {
  330.             printf("[Remote Database] The connection to '%s' has been established!\n", g_Hostname);
  331.  
  332.             g_Connected = TRUE;
  333.         }
  334.  
  335.         else
  336.         {
  337.             printf("[Remote Database] The connection to '%s' has not been established! MySQL reported the next error: '%s'.\n", \
  338.                 g_Hostname, mysql_error(g_Handle));
  339.  
  340.             g_Connected = FALSE;
  341.         }
  342.     }
  343.  
  344.     else
  345.     {
  346.         printf("[Remote Database] Unable to open 'RemoteDatabaseInformation.ini' for reading!\n");
  347.     }
  348. }
  349.  
  350. void OnAmxxDetach(void)
  351. {
  352.     mysql_close(g_Handle);
  353.  
  354.     g_Connected = FALSE;
  355. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement