Guest User

SQLite/MySQL Moneybag system

a guest
Mar 8th, 2017
384
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.86 KB | None | 0 0
  1. /**
  2. * Copyright (c) 2015-2016 Money Bag System
  3. *
  4. * This program is free software: you can Ristribute it and/or modify it under the terms of the
  5. * GNU General Public License as published by the Free Software Foundation, either version 3 of the
  6. * License, or (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
  9. * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. * General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License along with this program.
  13. * If not, see <http://www.gnu.org/licenses/>.
  14. */
  15.  
  16. /*****************************
  17. * Author: *
  18. * -TitanX *
  19. * Credits: *
  20. * - SA-MP Team *
  21. * - Blue-G *
  22. * - Zeex *
  23. * - [HiC]TheKiller *
  24. * - Jelly23 *
  25. * *
  26. *****************************/
  27.  
  28. #include <a_samp>
  29. #include <a_mysql>
  30. #include <zcmd>
  31.  
  32. // --------------< this must be edited without it FS will not work >--------------
  33.  
  34. #define USE_MYSQL 1 // un-comment this and comment USE_SQLITE to use MySQL
  35. #define USE_SQLITE 0 // un-comment this and comment USE_MYSQL to use SQLite
  36.  
  37. #if defined USE_MYSQL
  38.  
  39. #define MySQL_Host "localhost" // hostname of your mysql server if you are using xampp use "localhost"
  40. #define MySQL_User "root" // username for your mysql database
  41. #define MySQL_Database "test" // database that server will connect to it
  42. #define MySQL_Password "" // password of the database (user) that server will connect to it
  43.  
  44. #endif
  45.  
  46. // --------------< you can edit this if you want >--------------
  47.  
  48. #define MAX_MONEYBAGS 150 // max moneybags that can be stored in database
  49. #define MB_DELAY 30 // how many time moneybag re-spawn
  50.  
  51. #define MAX_MONEYBAG_MONEY 37000 // Max of money that can moneybag handle
  52. #define MIN_MONEYBAG_MONEY 13000 // Min of money that can moneybag handle
  53.  
  54. //#define WEAPONS_BOUNS // un-comment this if you want player get weapons bouns from moneybag
  55.  
  56. #if defined WEAPONS_BOUNS
  57.  
  58. #define MAX_WEAPONS_AMMO 1500 // Min of ammo that can be given to a player
  59. #define MIN_WEAPONS_AMMO 200 // Max of ammo that can be given to a player
  60.  
  61. static WeaponsBouns[] = // weapons that can be give to the player after founding the moneybag
  62. {
  63. 9, // Chainsaw
  64. 16, // Grenade
  65. 24, // Desert Eagle
  66. 26, // Shotgun Sawn-off
  67. 27, // Combat-Shotgun
  68. 29, // MP5
  69. 31, // M4
  70. 34 // Sniper Rifle
  71. };
  72.  
  73. #if MAX_WEAPONS_AMMO < MIN_WEAPONS_AMMO
  74. #error Fail: MAX_* must be highter than MIN_*
  75. #endif
  76.  
  77. #endif
  78. // --------------< Now you can stop editing >--------------
  79.  
  80. #if USE_MYSQL == 1 && USE_SQLITE == 1
  81. #error Fail: 2 Saving system load, please choose one of them
  82. #endif
  83.  
  84. #if USE_MYSQL == 0 && USE_SQLITE == 0
  85. #error Fail: no saving system loaded, please choose one
  86. #endif
  87.  
  88. #if !defined USE_MYSQL || !defined USE_SQLITE
  89. #error Fail: USE_MYSQL or USE_SQLITE Not defined in top of script
  90. #endif
  91.  
  92. #if MAX_MONEYBAG_MONEY < MIN_MONEYBAG_MONEY
  93. #error Fail: MAX_* must be highter than MIN_*
  94. #endif
  95.  
  96. enum ENUM_MB_INFO
  97. {
  98. Float:XPOS,
  99. Float:YPOS,
  100. Float:ZPOS,
  101. Name[24]
  102. };
  103.  
  104. static
  105.  
  106. MBInfo[MAX_MONEYBAGS][ENUM_MB_INFO],
  107. bool:m_Found = true,
  108. bool:m_Toggle = false,
  109.  
  110. #if USE_MYSQL == 1
  111. MySQL:handle,
  112. #endif
  113.  
  114. #if USE_SQLITE == 1
  115. DB:handle
  116. #endif
  117.  
  118. m_Location[24],
  119. m_Pickup,
  120. m_Timer,
  121. m_Count = 0
  122. ;
  123.  
  124.  
  125. forward OnMoneyBagUpdate();
  126.  
  127. public OnFilterScriptInit()
  128. {
  129. m_Timer = SetTimer("OnMoneyBagUpdate", MB_DELAY*1000, true);
  130.  
  131. #if USE_MYSQL == 1
  132.  
  133. handle = mysql_connect(MySQL_Host, MySQL_User, MySQL_Password, MySQL_Database);
  134. mysql_log(ALL);
  135. if(mysql_errno() != 0)
  136. {
  137. print(" [Moneybag]: Failed to load the moneybag system.");
  138. print(" [MoneyBag Error]: MySQL Connection Failed. ");
  139. print(" MoneyBag System By Titanx 2016 - 2017 ");
  140. return 1;
  141. }
  142. else
  143. {
  144. print(" [MoneyBag Notice]: MySQL connection success.");
  145.  
  146. mysql_query(handle, "CREATE TABLE IF NOT EXISTS `MoneyBag` (`Name` VARCHAR(24), `PosX` FLOAT(10), `PosY` FLOAT(10), `PosZ` FLOAT(10))");
  147.  
  148. print(" [MoneyBag Notice]: Tables created.");
  149.  
  150. #if defined WEAPONS_BOUNS
  151. print(" [MoneyBag Notice]: Weapons Bouns has been Activated.");
  152. #endif
  153.  
  154. print(" [MoneyBag Notice]: Loading Moneybags Names and Positions");
  155. LoadMoneyBags();
  156.  
  157. print(" *---------------------------------*");
  158. print(" | Moneybag System has been loaded |");
  159. print(" |---------------------------------|");
  160. print(" | Author: TitanX | Version: 1.0 |");
  161. print(" *---------------------------------*");
  162. return 1;
  163. }
  164.  
  165. #endif
  166.  
  167. #if USE_SQLITE == 1
  168.  
  169. handle = db_open("moneybag.db");
  170.  
  171. if(handle == 0)
  172. {
  173. print(" [Moneybag]: Failed to load the moneybag system.");
  174. print(" [MoneyBag Error]: SQLite Connection Failed. ");
  175. print(" MoneyBag System By Titanx 2016 - 2017 ");
  176. return 1;
  177. }
  178. else
  179. {
  180. static DBResult:query[2];
  181.  
  182. print(" [MoneyBag Notice]: SQLite connection success.");
  183.  
  184. query[0] = db_query(handle, "PRAGMA synchronous = OFF");
  185. query[1] = db_query(handle, "CREATE TABLE IF NOT EXISTS `MoneyBag` (`Name` VARCHAR(24), `PosX` FLOAT(10), `PosY` FLOAT(10), `PosZ` FLOAT(10))");
  186.  
  187. db_free_result(query[0]);
  188. db_free_result(query[1]);
  189.  
  190. print(" [MoneyBag Notice]: Tables created.");
  191.  
  192. #if defined WEAPONS_BOUNS
  193. print(" [MoneyBag Notice]: Weapons Bouns has been Activated.");
  194. #endif
  195.  
  196. print(" [MoneyBag Notice]: Loading Moneybags Names and Positions");
  197. LoadMoneyBags();
  198.  
  199. print(" *---------------------------------*");
  200. print(" | Moneybag System has been loaded |");
  201. print(" |---------------------------------|");
  202. print(" | Author: TitanX | Version: 1.0 |");
  203. print(" *---------------------------------*");
  204. return 1;
  205. }
  206.  
  207. #endif
  208. }
  209.  
  210. public OnFilterScriptExit()
  211. {
  212. #if USE_MYSQL == 1
  213. mysql_close(handle);
  214. #endif
  215.  
  216. #if USE_SQLITE == 1
  217. db_close(Database);
  218. #endif
  219.  
  220. KillTimer(m_Timer);
  221. if(!m_Found) DestroyPickup(m_Pickup);
  222. print(" *-----------------------------------*");
  223. print(" | Moneybag System has been unloaded |");
  224. print(" |-----------------------------------|");
  225. print(" | Author: TitanX | Version: 1.0 |");
  226. print(" *-----------------------------------*");
  227. return 1;
  228. }
  229.  
  230. public OnMoneyBagUpdate()
  231. {
  232. static st[114];
  233. if(m_Count == 0) print("[MoneyBag Error]: there no moneybags loaded to start one");
  234. if(!m_Found)
  235. {
  236. SendClientMessageToAll(-1, "{6EF83C}------------------------------------------------");
  237. format(st, sizeof(st), " {B7FF00}Money Bag {00C0FF}has not been found and it is still hidden in {B7FF00}%s", m_Location);
  238. SendClientMessageToAll(-1, st);
  239. SendClientMessageToAll(-1, "{6EF83C}------------------------------------------------");
  240. }
  241. else if(m_Found)
  242. {
  243. static randombag;
  244. m_Found = false;
  245.  
  246. randombag = random(sizeof(m_Count));
  247. if(MBInfo[randombag][XPOS] == 0.0) randombag = random(sizeof(m_Count));
  248.  
  249. SendClientMessageToAll(-1, "{6EF83C}------------------------------------------------");
  250. format(st, sizeof(st), " {B7FF00}Money Bag {00C0FF}has been hidden in {B7FF00}%s!", MBInfo[randombag][Name]);
  251. SendClientMessageToAll(-1, st);
  252. SendClientMessageToAll(-1, "{6EF83C}------------------------------------------------");
  253.  
  254. format(m_Location, sizeof(m_Location), "%s", MBInfo[randombag][Name]);
  255. m_Pickup = CreatePickup(1550, 2, MBInfo[randombag][XPOS], MBInfo[randombag][YPOS], MBInfo[randombag][ZPOS], -1);
  256. }
  257. return 1;
  258. }
  259.  
  260. CMD:tmb(playerid, params[]) return cmd_togglemb(playerid, params);
  261. CMD:togglemb(playerid, params[])
  262. {
  263. if(!IsPlayerAdmin(playerid)) return 0;
  264. if(!strcmp(params, "off", true))
  265. {
  266. if(m_Toggle) return SendClientMessage(playerid, -1, "*{FF0000}Error: Moneybag already disabled");
  267. if(!m_Found) DestroyPickup(m_Pickup);
  268.  
  269. KillTimer(m_Timer);
  270. m_Toggle = true;
  271. SendClientMessage(playerid, -1, "* Money bag has been {FF0000}disabled");
  272. return 1;
  273. }
  274. if(!strcmp(params, "on", true))
  275. {
  276. if(!m_Toggle) return SendClientMessage(playerid, -1, "*{FF0000}Error: Moneybag already enabled");
  277. m_Timer = SetTimer("MoneyBag", MB_DELAY, true);
  278. m_Toggle = false;
  279. SendClientMessage(playerid, -1, "* Money bag has been {33FF66}enabled!");
  280. return 1;
  281. }
  282. else return SendClientMessage(playerid, -1, "*{FF0000}Error: /togglemb [on/off] or /tmb [on/off]");
  283. }
  284.  
  285. CMD:mb(playerid) return cmd_moneybag(playerid);
  286. CMD:moneybag(playerid)
  287. {
  288. static string[81];
  289. if(!m_Found) format(string, sizeof(string), " {B7FF00}Money Bag {00C0FF}has been hidden in {B7FF00}%s!", m_Location);
  290. if(m_Found) format(string, sizeof(string), "*{FF0000} There no money bag running at moment");
  291. SendClientMessageToAll(-1, "{6EF83C}------------------------------------------------");
  292. SendClientMessage(playerid, -1, string);
  293. SendClientMessageToAll(-1, "{6EF83C}------------------------------------------------");
  294. return 1;
  295. }
  296.  
  297. CMD:savemb(playerid, params[]) return cmd_savemoneybag(playerid, params);
  298. CMD:savemoneybag(playerid, params[])
  299. {
  300. if(isnull(params)) return SendClientMessage(playerid, -1, "*{FF0000}Error: /savemoneybag [location name (clue)] or /savemb [location name (clue)]");
  301. if(strlen(params) > 24) return SendClientMessage(playerid, -1, "*{FF0000}Error: Location/clue must be less or equal 24 char");
  302. if(m_Count == MAX_MONEYBAGS) return SendClientMessage(playerid, -1, "*{FF0000}Error: Cannot add more moneybags, please increase MAX_MONEYBAGS value");
  303.  
  304. static
  305. Float:X,
  306. Float:Y,
  307. Float:Z
  308. ;
  309.  
  310. GetPlayerPos(playerid, X,Y,Z);
  311. SaveMoneyBag(params, X, Y, Z);
  312. SendClientMessageToAll(-1, "*{B7FF00}Success: this position has been saved in the database !");
  313. printf(" [MoneyBag Notice]: New Money bag saved at X: %f Y: %f Z: %s, under name: %s", X, Y, Z, params);
  314. return 1;
  315. }
  316.  
  317. CMD:delmb(playerid, params[]) return cmd_deletemoneybag(playerid, params);
  318. CMD:deletemoneybag(playerid, params[])
  319. {
  320. if(isnull(params)) return SendClientMessage(playerid, -1, "*{FF0000}Error: /savemoneybag [location name (clue)] or /delmb [location name (clue)]");
  321. if(strlen(params) > 24) return SendClientMessage(playerid, -1, "*{FF0000}Error: Location/clue must be less or equal 24 char");
  322. if(DeleteMoneyBag(params)) SendClientMessage(playerid, -1, "*Success: this moneybag has been deleted");
  323. else SendClientMessage(playerid, -1, "*{FF0000}Error: this moneybag not exists on database");
  324.  
  325. return 1;
  326. }
  327.  
  328. public OnPlayerPickUpPickup(playerid, pickupid)
  329. {
  330. if(pickupid == m_Pickup)
  331. {
  332. new
  333. string[170],
  334. pname[24],
  335. money = random(MAX_MONEYBAG_MONEY - MIN_MONEYBAG_MONEY) + MIN_MONEYBAG_MONEY
  336. ;
  337.  
  338. GetPlayerName(playerid, pname, 24);
  339.  
  340. DestroyPickup(m_Pickup);
  341.  
  342. GivePlayerMoney(playerid, money);
  343.  
  344. #if defined WEAPONS_BOUNS
  345.  
  346. new
  347. weapon = random(sizeof(WeaponsBouns)),
  348. ammo = random(MAX_WEAPONS_AMMO - MIN_WEAPONS_AMMO) + MIN_WEAPONS_AMMO
  349. ;
  350.  
  351. GivePlayerWeapon(playerid, WeaponsBouns[weapon], ammo);
  352.  
  353. #endif
  354.  
  355. SendClientMessageToAll(-1, "{6EF83C}------------------------------------------------");
  356. format(string, sizeof(string), " {B7FF00}%s{00C0FF} has found the {B7FF00}money bag{00C0FF} that had {B7FF00}$%d {00C0FF}inside, located in {B7FF00}%s", pname, money, m_Location);
  357. SendClientMessageToAll(-1, string);
  358. SendClientMessageToAll(-1, "{6EF83C}------------------------------------------------");
  359.  
  360. m_Found = true;
  361. }
  362. return 1;
  363. }
  364.  
  365.  
  366. stock SaveMoneyBag(moneybagname[], Float:posx, Float:posy, Float:posz)
  367. {
  368. static
  369. query[133];
  370.  
  371. #if USE_MYSQL == 1
  372.  
  373. mysql_format(handle, query, sizeof(query), "INSERT INTO `Moneybag` (`Name`, `PosX`, `PosY`, `PosZ`) VALUES ('%e', %f, %f, %f)", moneybagname, posx, posy, posz);
  374. mysql_query(handle, query);
  375.  
  376. #endif
  377.  
  378. #if USE_SQLITE == 1
  379.  
  380. format(query, sizeof(query), "INSERT INTO `Moneybag` (`Name`, `PosX`, `PosY`, `PosZ`) VALUES ('%q', %f, %f, %f)", moneybagname, posx, posy, posz);
  381. db_query(handle, query);
  382.  
  383. #endif
  384.  
  385. m_Count++;
  386. format(MBInfo[m_Count][Name], 24, "%s", moneybagname);
  387. MBInfo[m_Count][XPOS] = posx;
  388. MBInfo[m_Count][YPOS] = posy;
  389. MBInfo[m_Count][ZPOS] = posz;
  390. return 1;
  391. }
  392.  
  393. stock DeleteMoneyBag(moneybagname[])
  394. {
  395. static
  396. rows = 0,
  397. query[66]
  398. ;
  399.  
  400. #if USE_MYSQL == 1
  401.  
  402. static
  403. Cache:getCache;
  404.  
  405. mysql_format(handle, query, sizeof(query), "SELECT * FROM `MoneyBag` WHERE `Name` = '%e'", moneybagname);
  406.  
  407. getCache = mysql_query(handle, query);
  408.  
  409. cache_get_row_count(rows);
  410.  
  411. if(rows > 0)
  412. {
  413. mysql_format(handle, query, sizeof(query), "DELETE * FROM `MoneyBag` WHERE `Name` = '%e'", moneybagname);
  414. mysql_query(handle, query);
  415.  
  416. for(new iax = 0; iax < m_Count; iax++) // Sorry for this but it required to detect the target moneybag
  417. {
  418. if(!strcmp(MBInfo[iax][Name], moneybagname))
  419. {
  420. MBInfo[iax][XPOS] = 0.0;
  421. MBInfo[iax][YPOS] = 0.0;
  422. MBInfo[iax][ZPOS] = 0.0;
  423. format(MBInfo[iax][Name], 24, "");
  424. m_Count--;
  425. break;
  426. }
  427. }
  428. cache_delete(getCache);
  429. return 1;
  430. }
  431. else
  432. {
  433. cache_delete(getCache);
  434. return 0;
  435. }
  436.  
  437. #endif
  438.  
  439. #if USE_SQLITE == 1
  440.  
  441. static
  442. DBResult:getCache;
  443.  
  444. format(query, sizeof(query), "SELECT * FROM `MoneyBag` WHERE `Name` = '%q'", moneybagname);
  445. getCache = db_query(handle, query);
  446.  
  447. rows = db_num_rows(getCache);
  448. if(rows > 0)
  449. {
  450. format(query, sizeof(query), "DELETE * FROM `MoneyBag` WHERE `Name` = '%q'", moneybagname);
  451. db_query(handle, query);
  452. for(new i = 0; i < m_Count; i++) // Sorry for this but it required to detect the target moneybag
  453. {
  454. if(!strcmp(MBInfo[i][Name], moneybagname)
  455. {
  456. MBInfo[i][XPOS] = 0.0;
  457. MBInfo[i][YPOS] = 0.0;
  458. MBInfo[i][ZPOS] = 0.0;
  459. MBInfo[i][Name] = "";
  460. m_Count--;
  461. break;
  462. }
  463. }
  464. return 1;
  465. }
  466. else
  467. {
  468. SendClientMessage(playerid, -1, "*{FF0000}Error: this moneybag not exists on database");
  469. return 0;
  470. }
  471. db_free_result(getCache);
  472.  
  473. #endif
  474. }
  475.  
  476. stock LoadMoneyBags()
  477. {
  478. static
  479. rows = 0;
  480.  
  481. #if USE_MYSQL == 1
  482.  
  483. static
  484. Cache:getCache;
  485.  
  486. getCache = mysql_query(handle, "SELECT * FROM `MoneyBag`");
  487.  
  488. cache_get_row_count(rows);
  489. if(rows >= MAX_MONEYBAGS) return print(" [MoneyBag Error]: Array out bound, number of rows is larger than MAX_MONEYBAGS value");
  490. if(rows > 0)
  491. {
  492. for(new ix = 0; ix < rows; ix++)
  493. {
  494. cache_get_value_name(ix, "Name", MBInfo[ix][Name], 24);
  495. cache_get_value_name_float(ix, "PosX", MBInfo[ix][XPOS]);
  496. cache_get_value_name_float(ix, "PosY", MBInfo[ix][YPOS]);
  497. cache_get_value_name_float(ix, "PosZ", MBInfo[ix][ZPOS]);
  498. m_Count++;
  499. }
  500. printf(" [MoneyBag Notice]: %d Positions has been loaded from database", m_Count);
  501. }
  502. else
  503. {
  504. mysql_query(handle, "INSERT INTO `Moneybag` (`Name`, `PosX`, `PosY`, `PosZ`) VALUES ('Montgomery', 1397.934692, 289.888427, 23.555511)");
  505. mysql_query(handle, "INSERT INTO `Moneybag` (`Name`, `PosX`, `PosY`, `PosZ`) VALUES ('Verdant Meadows', 209.578689, 2415.689697, 16.322700)");
  506. mysql_query(handle, "INSERT INTO `Moneybag` (`Name`, `PosX`, `PosY`, `PosZ`) VALUES ('Fort Carson', -172.726379, 1182.572753, 26.504249)");
  507. mysql_query(handle, "INSERT INTO `Moneybag` (`Name`, `PosX`, `PosY`, `PosZ`) VALUES ('Las Barrancas', -778.594482, 1477.787719, 28.764667)");
  508. mysql_query(handle, "INSERT INTO `Moneybag` (`Name`, `PosX`, `PosY`, `PosZ`) VALUES ('Area 69', 266.978424, 1858.773071, 8.757812)");
  509. mysql_query(handle, "INSERT INTO `Moneybag` (`Name`, `PosX`, `PosY`, `PosZ`) VALUES ('The Quarry', 266.978424, 1858.773071, 8.757812)");
  510.  
  511. print(" [MoneyBag Notice]: the database empty, exemples of moneybags has been loaded.");
  512.  
  513. m_Count = 6;
  514. }
  515. cache_delete(getCache);
  516. return 1;
  517.  
  518. #endif
  519.  
  520. #if USE_SQLITE == 1
  521.  
  522. static
  523. DBResult:getCache;
  524.  
  525. getCache = db_query(handle, "SELECT * FROM `MoneyBag`");
  526. rows = db_num_rows(getCache);
  527.  
  528. if(rows >= MAX_MONEYBAGS) return print(" [MoneyBag Error]: Array out bound, number of rows is larger than MAX_MONEYBAGS value");
  529. if(rows > 0)
  530. {
  531. for(new i = 0; i < rows; i++)
  532. {
  533. db_get_field_assoc(getCache, "Name", MBInfo[i][Name], 24);
  534. MBInfo[i][XPOS] = db_get_field_float(getCache, "PosX");
  535. MBInfo[i][YPOS] = db_get_field_float(getCache, "PosY");
  536. MBInfo[i][ZPOS] = db_get_field_float(getCache, "PosZ");
  537. m_Count++;
  538. }
  539. printf(" [MoneyBag Notice]: %d Positions has been loaded from database", m_Count);
  540. }
  541. else
  542. {
  543. db_query(handle, "INSERT INTO `Moneybag` (`Name`, `PosX`, `PosY`, `PosZ`) VALUES ('Montgomery', 1397.934692, 289.888427, 23.555511)");
  544. db_query(handle, "INSERT INTO `Moneybag` (`Name`, `PosX`, `PosY`, `PosZ`) VALUES ('Verdant Meadows', 209.578689, 2415.689697, 16.322700)");
  545. db_query(handle, "INSERT INTO `Moneybag` (`Name`, `PosX`, `PosY`, `PosZ`) VALUES ('Fort Carson', -172.726379, 1182.572753, 26.504249)");
  546. db_query(handle, "INSERT INTO `Moneybag` (`Name`, `PosX`, `PosY`, `PosZ`) VALUES ('Las Barrancas', -778.594482, 1477.787719, 28.764667)");
  547. db_query(handle, "INSERT INTO `Moneybag` (`Name`, `PosX`, `PosY`, `PosZ`) VALUES ('Area 69', 266.978424, 1858.773071, 8.757812)");
  548. db_query(handle, "INSERT INTO `Moneybag` (`Name`, `PosX`, `PosY`, `PosZ`) VALUES ('The Quarry', 266.978424, 1858.773071, 8.757812)");
  549.  
  550. print(" [MoneyBag Notice]: the database empty, exemples of moneybags has been loaded.");
  551.  
  552. m_Count = 6;
  553. }
  554. db_free_result(getCache);
  555. return 1;
  556.  
  557. #endif
  558.  
  559. }
Add Comment
Please, Sign In to add comment