Guest User

Mafia System V.1.0

a guest
Oct 26th, 2011
358
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 54.57 KB | None | 0 0
  1. /**********************************
  2. * *
  3. * @Author: KaSkA3eR(filip128) *
  4. * @Version: 1.0.0 *
  5. * @Released: 26/11/2011 *
  6. * @Credits: Double-O-Seven(DOF2)*
  7. * *
  8. **********************************/
  9. //Base added to GameMode with help "new" for exmaple "new Base_PAWN;" or else any was "new basename;"
  10. #include <a_samp>
  11. #define DINI_CONVERT
  12. #if defined _dof2_included
  13. #endinput
  14. #endif
  15. #define _dof2_included
  16.  
  17. #include <a_samp>
  18.  
  19. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  20.  
  21. /*
  22. * This is a new version of the INI script Double-O-Files.
  23. * However, it's has completely been rewritten and has now a much better performance.
  24. * There is also the support for sections in the INI file. (But there is no support for comments.)
  25. * Double-O-Files 2 is compatible with DUDB, DINI, Double-O-Files and possibly y_ini since it
  26. * can handle sections and entry of the format "key = value", not only "key=value".
  27. * The number of spaces between the equal sign and key and value can actually be arbitrary.
  28. * I've added some comments below. You may see that I've mentioned the big-O-notation,
  29. * 'n' always Entries.Count.
  30. * Double-O-Files 2 should also be useful for Russian letter because I'm using
  31. * the functions fgetchar and fputchar to write and read the files.
  32. *
  33. * There is another new feature which has been inspired by ZCMD and y_ini:
  34. * The OnParseFile callbacks. To learn more about it, read the description in
  35. * the SA-MP forums if you haven't already.
  36. * THE END
  37. */
  38.  
  39. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  40.  
  41. /*
  42. native DOF2_SetFile(file[]);
  43. native DOF2_LoadFile();
  44. native DOF2_SaveFile();
  45. native DOF2_ParseFile(file[],extraid,bool:callback=true);
  46. native DOF2_ReparseFile(file[],extraid,bool:callback=true);
  47. native DOF2_WriteFile();
  48. native DOF2_PrintFile(comment[]="");
  49. native DOF2_GetString(file[],key[],tag[]="");
  50. native DOF2_GetStringEx(file[],key[],result[],size,tag[]="");
  51. native Float:DOF2_GetFloat(file[],key[]);
  52. native DOF2_GetInt(file[],key[],tag[]="");
  53. native DOF2_GetHex(file[],key[],tag[]="");
  54. native DOF2_GetBin(file[],key[],tag[]="");
  55. native bool:DOF2_GetBool(file[],key[],tag[]="");
  56. native DOF2_SetString(file[],key[],value[],tag[]="");
  57. native DOF2_SetFloat(file[],key[],Float:value);
  58. native DOF2_SetInt(file[],key[],value,tag[]="");
  59. native DOF2_SetHex(file[],key[],value,tag[]="");
  60. native DOF2_SetBin(file[],key[],value,tag[]="");
  61. native DOF2_SetBool(file[],key[],bool:value,tag[]="");
  62. native DOF2_IsSet(file[],key[],tag[]="");
  63. native DOF2_Unset(file[],key[],tag[]="");
  64. native DOF2_FileExists(file[]);
  65. native DOF2_RemoveFile(file[]);
  66. native DOF2_CreateFile(file[],password[]="");
  67. native DOF2_RenameFile(oldfile[],newfile[]);
  68. native DOF2_RenameKey(file[],oldkey[],newkey[],tag[]="");
  69. native DOF2_CopyFile(filetocopy[],newfile[]);
  70. native DOF2_CheckLogin(file[],password[]);
  71. native DOF2_File(user[]);
  72. native DOF2_ParseInt();
  73. native DOF2_ParseFloat();
  74. native DOF2_ParseBool();
  75. native DOF2_ParseBin();
  76. native DOF2_ParseHex();
  77. native DOF2_SetUTF8(bool:set);
  78. native bool:DOF2_GetUTF8();
  79. native DOF2_GetFile();
  80. native DOF2_MakeBackup(file[]);
  81. native DOF2_RemoveSection (file [], tag []);
  82. native DOF2_SectionExists (file [], tag []);
  83. native DOF2_SortSection (file [], tag [], bool: ignorecase = true, bool: ascending = true);
  84. native DOF2_SortAllSections (file [], bool: ignorecase = true, bool: ascending = true);
  85. native DOF2_SetCaseSensitivity (bool: set);
  86. native DOF2_GetCaseSensitivity ();
  87. */
  88.  
  89. #define DOF2_TagExists DOF2_SectionExists
  90. #define DOF2_RemoveTag DOF2_RemoveSection
  91.  
  92. // OnParseFile <Tag><Key>(extraid, value [])
  93. // OnParseFile <><Key>(extraid, value [])
  94. // OnDefaultParseFile (extraid, value [], key [], tag [], file [])
  95.  
  96. // The arguments of your OnParseFile functions may have arbitrary names but must be an integer followed by a string.
  97. // Function must return a value.
  98. #define OnParseFile<%0><%1>(%2) \
  99. forward _OnParseFile_%0_%1 (extraid, value []); \
  100. public _OnParseFile_%0_%1 (extraid, value []) \
  101. return __OnParseFile_%0_%1 (extraid, (value [0] == '\1' && value [1] == '\0') ? ("") : value); \
  102. stock __OnParseFile_%0_%1 (%2)
  103.  
  104. // Also here: The argument names may be arbitrary but must be an integer followed by 4 strings.
  105. // Function must return a value.
  106. #define OnDefaultParseFile(%0) \
  107. forward _OnDefaultParseFile (extraid, value [], key [], tag [], file []); \
  108. public _OnDefaultParseFile (extraid, value [], key [], tag [], file []) \
  109. return __OnDefaultParseFile (extraid, (value [0] == '\1' && value [1] == '\0') ? ("") : value, key, (tag [0] == '\1' && tag [1] == '\0') ? ("") : tag, file); \
  110. stock __OnDefaultParseFile (%0)
  111.  
  112. #define DOF2_ParseBool() \
  113. (strval (value) || (value [0] && !strcmp (value, "true", true)))
  114.  
  115. #define DOF2_ParseInt() \
  116. (strval (value))
  117.  
  118. #define DOF2_ParseFloat() \
  119. (floatstr (value))
  120.  
  121. #define DOF2_ParseBin() \
  122. (DOF2_strbin (value))
  123.  
  124. #define DOF2_ParseHex() \
  125. (DOF2_strhex (value))
  126.  
  127. #define DOF2_LoadFile() \
  128. DOF2_ParseFile (CurrentFile, -1, false)
  129.  
  130. #define DOF2_SaveFile \
  131. DOF2_WriteFile
  132.  
  133. #define DOF2_FileExists \
  134. fexist
  135.  
  136. #define Sections. \
  137. Sections_
  138.  
  139. #define Entries. \
  140. Entries_
  141.  
  142. #define DOF2:: \
  143. DOF2_
  144.  
  145. #if !defined private
  146. #define private static stock
  147. #endif
  148.  
  149. #pragma dynamic 65536
  150.  
  151. /*
  152. #define MAX_SECTION_TAG (32)
  153. #define MAX_LINE_SIZE (128)
  154. #define MAX_SECTIONS (32)
  155. #define MAX_ENTRIES (256)
  156. #define MAX_FILE_SIZE (64)
  157.  
  158. #define USER_FILE_PATH "Users/%s.ini"
  159. */
  160.  
  161. // The maximum length of the name of a tag.
  162. #if !defined MAX_SECTION_TAG
  163. #define MAX_SECTION_TAG (32)
  164. #endif
  165.  
  166. // The maximum length of a line (including key and value).
  167. #if !defined MAX_LINE_SIZE
  168. #define MAX_LINE_SIZE (128)
  169. #endif
  170.  
  171. // The maximum number of sections which can be handled. Be careful: MUST NOT be higher than 255.
  172. #if !defined MAX_SECTIONS
  173. #define MAX_SECTIONS (32)
  174. #endif
  175.  
  176. // The maximum number of entries which can be loaded into the cache.
  177. #if !defined MAX_ENTRIES
  178. #define MAX_ENTRIES (256)
  179. #endif
  180.  
  181. // The maximum length of the name of a file.
  182. #if !defined MAX_FILE_SIZE
  183. #define MAX_FILE_SIZE (64)
  184. #endif
  185.  
  186. /*
  187. If PACK_CONTENT == true tag names and lines (key + value) will get stored in cache as packed strings.
  188. The result is less memory usage. However, you won't be able to use special characters like russian or chinese ones.
  189. */
  190. #if !defined PACK_CONTENT
  191. #define PACK_CONTENT (false)
  192. #endif
  193.  
  194. #define INVALID_ENTRY (-1)
  195. #define INVALID_SECTION (-1)
  196.  
  197. // Do you want to emulate DUDB?
  198. #if !defined DUDB_CONVERT && 0 // Change to 1 to enable.
  199. #define DUDB_CONVERT
  200. #endif
  201.  
  202. #if !defined USER_FILE_PATH
  203. #if defined DUDB_CONVERT
  204. #define USER_FILE_PATH "%s.dudb.sav"
  205. #else
  206. #define USER_FILE_PATH "%s.ini"
  207. #endif
  208. #endif
  209.  
  210. #if !defined USER_PW_HASH_KEY
  211. #if defined DUDB_CONVERT
  212. #define USER_PW_HASH_KEY "password_hash"
  213. #else
  214. #define USER_PW_HASH_KEY "password"
  215. #endif
  216. #endif
  217.  
  218.  
  219. // Do you want to emulate DINI?
  220. #if !defined DINI_CONVERT && 0 // Change to 1 to enable.
  221. #define DINI_CONVERT
  222. #endif
  223.  
  224. /*
  225. #if MAX_SECTIONS >= 256
  226. #error MAX_SECTIONS must not be greater than 255.
  227. #endif
  228. */
  229.  
  230. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  231.  
  232. private
  233. bool: UseUTF8 = PACK_CONTENT,
  234. bool: CaseSensitive = false,
  235. CurrentFile [MAX_FILE_SIZE],
  236. bool: FileChanged,
  237. Sections.FirstEntry [MAX_SECTIONS] = {INVALID_ENTRY, ...},
  238. Sections.LastEntry [MAX_SECTIONS] = {INVALID_ENTRY, ...},
  239. Sections.Count,
  240. #if PACK_CONTENT == true
  241. Sections.Tag [MAX_SECTIONS][MAX_SECTION_TAG char],
  242. Entries.Line [MAX_ENTRIES][MAX_LINE_SIZE char],
  243. Entries.Tag [MAX_ENTRIES][MAX_SECTION_TAG char],
  244. #else
  245. Sections.Tag [MAX_SECTIONS][MAX_SECTION_TAG],
  246. Entries.Line [MAX_ENTRIES][MAX_LINE_SIZE],
  247. Entries.Tag [MAX_ENTRIES][MAX_SECTION_TAG],
  248. #endif
  249. #if MAX_SECTIONS >= 256
  250. Entries.Section [MAX_ENTRIES],
  251. #else
  252. Entries.Section [MAX_ENTRIES char],
  253. #endif
  254. Entries.NextEntry [MAX_ENTRIES] = {INVALID_ENTRY, ...},
  255. Entries.PreviousEntry [MAX_ENTRIES] = {INVALID_ENTRY, ...},
  256. Entries.Count,
  257. SortedEntryList [MAX_ENTRIES][2]; // Index 0: Hashcode, Index 1: EntryID
  258.  
  259. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  260.  
  261. DOF2::Exit ()
  262. DOF2::WriteFile ();
  263.  
  264. stock DOF2::SetUTF8 (bool: set)
  265. UseUTF8 = set;
  266.  
  267. stock bool: DOF2::GetUTF8 ()
  268. return UseUTF8;
  269.  
  270. stock bool: DOF2::SetCaseSensitivity (bool: set)
  271. CaseSensitive = set;
  272.  
  273. stock bool: DOF2::GetCaseSensitivity ()
  274. return CaseSensitive;
  275.  
  276. stock DOF2::SetFile (file [])
  277. DOF2::strcpy (CurrentFile, file);
  278.  
  279. stock DOF2::GetFile ()
  280. return CurrentFile;
  281.  
  282. stock DOF2::CreateFile (file [], password [] = "")
  283. {
  284. if (!DOF2::FileExists (file))
  285. {
  286. new File: f = fopen (file, io_append);
  287.  
  288. if (fclose (f))
  289. {
  290. if (password [0])
  291. return DOF2::SetInt (file, USER_PW_HASH_KEY, DOF2::num_hash (password));
  292. return 1;
  293. }
  294. }
  295. return 0;
  296. }
  297.  
  298. stock DOF2::RenameFile (oldfile [], newfile [])
  299. {
  300. if (!DOF2::FileExists (newfile))
  301. {
  302. // If 'CurrentFile' is 'oldfile', write it if it has been changed.
  303. if (CurrentFile [0] && !strcmp (CurrentFile, oldfile) && FileChanged)
  304. DOF2::WriteFile ();
  305. else if (!DOF2::ParseFile (oldfile, -1, false)) // Otherwise parse 'oldfile'.
  306. return 0;
  307.  
  308. DOF2::SetFile (newfile);
  309. if (DOF2::WriteFile ())
  310. return fremove (oldfile);
  311. }
  312. return 0;
  313. }
  314.  
  315. stock DOF2::CopyFile (filetocopy [], newfile [])
  316. {
  317. if (!DOF2::FileExists (newfile))
  318. {
  319. if (CurrentFile [0] && !strcmp (CurrentFile, filetocopy) && FileChanged)
  320. DOF2::WriteFile ();
  321. else if(!DOF2::ParseFile (filetocopy, -1, false))
  322. return 0;
  323.  
  324. DOF2::SetFile (newfile);
  325. return DOF2::WriteFile ();
  326. }
  327. return 0;
  328. }
  329.  
  330. stock DOF2::RemoveFile (file [])
  331. {
  332. if (file [0])
  333. {
  334. if (CurrentFile [0] && !strcmp (CurrentFile, file))
  335. CurrentFile [0] = '\0';
  336. return fremove (file);
  337. }
  338. return 0;
  339. }
  340.  
  341. stock DOF2::MakeBackup (file [])
  342. {
  343. new
  344. year,
  345. month,
  346. day,
  347. hour,
  348. minute,
  349. second,
  350. backupfile [MAX_FILE_SIZE];
  351.  
  352. getdate (year, month, day);
  353. gettime (hour, minute, second);
  354. format (backupfile, sizeof (backupfile), "%s.%02d_%02d_%02d.%02d_%02d_%02d_%02d.bak", CurrentFile, month, day, year, hour, minute, second, GetTickCount ());
  355. return DOF2::CopyFile (CurrentFile, backupfile);
  356. }
  357.  
  358. stock bool: DOF2::SectionExists (file [], tag [])
  359. {
  360. if (file [0]) // You can't remove the empty Sections.
  361. {
  362. if (!tag [0])
  363. return true; // Emptry section always exists. In every file.
  364.  
  365. if (!CurrentFile [0] || strcmp (CurrentFile, file)) // No file in buffer or the file you want to read from is not the file in the buffer.
  366. if (!DOF2::ParseFile (file, -1, false))
  367. return false;
  368.  
  369. #if PACK_CONTENT == true
  370. new buf [MAX_SECTION_TAG];
  371. #endif
  372.  
  373. for (new i = 1; i < Sections.Count; ++i)
  374. {
  375. #if PACK_CONTENT == true
  376. strunpack (buf, Sections.Tag [i]);
  377. if (!strcmp (buf, tag, !CaseSensitive))
  378. return true;
  379. #else
  380. if (!strcmp (Sections.Tag [i], tag, !CaseSensitive))
  381. return true;
  382. #endif
  383. }
  384. }
  385. return false;
  386. }
  387.  
  388. stock DOF2::RemoveSection (file [], tag [])
  389. {
  390. // Removes tag 'tag' with all it's entries.
  391. if (file [0] && tag [0]) // You can't remove the empty Sections.
  392. {
  393. if (!CurrentFile [0] || strcmp (CurrentFile, file)) // No file in buffer or the file you want to read from is not the file in the buffer.
  394. if (!DOF2::ParseFile (file, -1, false))
  395. return 0;
  396.  
  397. new
  398. #if PACK_CONTENT == true
  399. line [MAX_LINE_SIZE],
  400. buf [MAX_SECTION_TAG],
  401. #endif
  402. section = INVALID_SECTION,
  403. entry,
  404. key [MAX_KEY_SIZE];
  405.  
  406. for (new i = 1; i < Sections.Count; ++i)
  407. {
  408. #if PACK_CONTENT == true
  409. strunpack (buf, Sections.Tag [i]);
  410. if (!strcmp (buf, tag, !CaseSensitive))
  411. {
  412. section = i;
  413. break;
  414. }
  415. #else
  416. if (!strcmp (Sections.Tag [i], tag, !CaseSensitive))
  417. {
  418. section = i;
  419. break;
  420. }
  421. #endif
  422. }
  423.  
  424. if (section != INVALID_SECTION)
  425. {
  426. entry = Sections.FirstEntry [section];
  427. while (entry != INVALID_ENTRY)
  428. {
  429. // Remove all entries under the current Sections.
  430. #if PACK_CONTENT == true
  431. strunpack (line, Entries.Line [entry]);
  432. DOF2::ParseLine (line, key, buf);
  433. #else
  434. DOF2::ParseLine (Entries.Line [entry], key, buf);
  435. #endif
  436. DOF2::Unset (file, key, tag);
  437. entry = Entries.NextEntry [entry];
  438. }
  439.  
  440. // Move the last tag to the position of the current tag. Creates a little mess.
  441. --Sections.Count;
  442. Sections.Tag [section] = Sections.Tag [Sections.Count];
  443. Sections.FirstEntry [section] = Sections.FirstEntry [Sections.Count];
  444. Sections.LastEntry [section] = Sections.LastEntry [Sections.Count];
  445.  
  446. // Adjust the tag IDs of the entries.
  447. entry = Sections.FirstEntry [section];
  448. while (entry != INVALID_ENTRY)
  449. {
  450. #if MAX_SECTIONS >= 256
  451. Entries.Section [entry] = section;
  452. #else
  453. Entries.Section {entry} = section;
  454. #endif
  455. entry = Entries.NextEntry [entry];
  456. }
  457. FileChanged = true;
  458. return 1;
  459. }
  460. }
  461. return 0;
  462. }
  463.  
  464. private DOF2::SearchEntry (key [], tag [], keybuf [], valbuf [], &pos, keybufsize = sizeof (keybuf), valbufsize = sizeof (valbuf))
  465. {
  466. if (key [0] && Entries.Count)
  467. {
  468. new
  469. entry = INVALID_ENTRY,
  470. l,
  471. m,
  472. r,
  473. h,
  474. #if PACK_CONTENT == true
  475. line [MAX_LINE_SIZE],
  476. buf [MAX_SECTION_TAG],
  477. #endif
  478. i;
  479.  
  480. h = DOF2::HashKey (key);
  481. l = 0;
  482. r = Entries.Count - 1;
  483.  
  484. /*
  485. * Binary search in a sorted list of entries in O(log n) time. This algorithm makes for example with 256 elements a maximum of ~8 steps until the entry is found if it exists.
  486. * A sequential search would take up to 256 steps. That was the case in the first Double-O-Files script.
  487. */
  488. while (l <= r)
  489. {
  490. if ((r - l) < 2)
  491. {
  492. if (h == SortedEntryList [l][0])
  493. {
  494. m = l;
  495. entry = SortedEntryList [l][1];
  496. }
  497. else if (r > l && h == SortedEntryList [r][0])
  498. {
  499. m = r;
  500. entry = SortedEntryList [r][1];
  501. }
  502. break;
  503. }
  504. else
  505. {
  506. m = l + (r - l) / 2;
  507. if (h == SortedEntryList [m][0])
  508. {
  509. entry = SortedEntryList [m][1];
  510. break;
  511. }
  512. else if (h > SortedEntryList [m][0])
  513. l = m + 1;
  514. else
  515. r = m - 1;
  516. }
  517. }
  518.  
  519. // Candidate found?
  520. if (entry != INVALID_ENTRY)
  521. {
  522. // Check if it's the entry we want.
  523. #if PACK_CONTENT == true
  524. strunpack (line, Entries.Line [entry]);
  525. DOF2::ParseLine (line, keybuf, valbuf, keybufsize, valbufsize);
  526. strunpack (buf, Entries.Tag [entry]);
  527. if (!strcmp (keybuf, key, !CaseSensitive) && ((!tag [0] && !buf [0]) || (tag [0] && buf [0] && !strcmp (tag, buf, !CaseSensitive))))
  528. #else
  529. DOF2::ParseLine (Entries.Line [entry], keybuf, valbuf, keybufsize, valbufsize);
  530. if (!strcmp (keybuf, key, !CaseSensitive) && ((!tag [0] && !Entries.Tag [entry][0]) || (tag [0] && Entries.Tag [entry][0] && !strcmp (tag, Entries.Tag [entry], !CaseSensitive))))
  531. #endif
  532. return (pos = m, entry);
  533. else
  534. {
  535. // If not, look left and right in the list for entries with the same hash code. This can be collisions or entries with the same key from another section.
  536. for (i = m - 1; i >= 0 && h == SortedEntryList [i][0]; --i)
  537. {
  538. entry = SortedEntryList [i][1];
  539. #if PACK_CONTENT == true
  540. strunpack (line, Entries.Line [entry]);
  541. DOF2::ParseLine (line, keybuf, valbuf, keybufsize, valbufsize);
  542. strunpack (buf, Entries.Tag [entry]);
  543. if (!strcmp (keybuf, key, !CaseSensitive) && ((!tag [0] && !buf [0]) || (tag [0] && buf [0] && !strcmp (tag, buf, !CaseSensitive))))
  544. #else
  545. DOF2::ParseLine (Entries.Line [entry], keybuf, valbuf, keybufsize, valbufsize);
  546. if (!strcmp (keybuf, key, !CaseSensitive) && ((!tag [0] && !Entries.Tag [entry][0]) || (tag [0] && Entries.Tag [entry][0] && !strcmp (tag, Entries.Tag [entry], !CaseSensitive))))
  547. #endif
  548. return (pos = i, entry);
  549. }
  550.  
  551. for (i = m + 1; i < Entries.Count && h == SortedEntryList [i][0]; ++i)
  552. {
  553. entry = SortedEntryList [i][1];
  554. #if PACK_CONTENT == true
  555. strunpack (line, Entries.Line [entry]);
  556. DOF2::ParseLine (line, keybuf, valbuf, keybufsize, valbufsize);
  557. strunpack (buf, Entries.Tag [entry]);
  558. if (!strcmp (keybuf, key, !CaseSensitive) && ((!tag [0] && !buf [0]) || (tag [0] && buf [0] && !strcmp (tag, buf, !CaseSensitive))))
  559. #else
  560. DOF2::ParseLine (Entries.Line [entry], keybuf, valbuf, keybufsize, valbufsize);
  561. if (!strcmp (keybuf, key, !CaseSensitive) && ((!tag [0] && !Entries.Tag [entry][0]) || (tag [0] && Entries.Tag [entry][0] && !strcmp (tag, Entries.Tag [entry], !CaseSensitive))))
  562. #endif
  563. return (pos = i, entry);
  564. }
  565. }
  566. }
  567. }
  568.  
  569. keybuf [0] = valbuf [0] = '\0';
  570. return INVALID_ENTRY;
  571. }
  572.  
  573. stock DOF2::SetString (file [], key [], value [], tag [] = "")
  574. {
  575. if (file [0] && key [0])
  576. {
  577. new
  578. entry,
  579. pos,
  580. section = INVALID_SECTION,
  581. keybuf [MAX_LINE_SIZE],
  582. valbuf [MAX_LINE_SIZE],
  583. #if PACK_CONTENT == true
  584. buf [MAX_SECTION_TAG],
  585. line [MAX_LINE_SIZE],
  586. #endif
  587. i;
  588.  
  589. if (!CurrentFile [0] || strcmp (CurrentFile, file)) // No file in buffer or the file you want to read from is not the file in the buffer.
  590. if (!DOF2::ParseFile (file, -1, false))
  591. return 0;
  592.  
  593. entry = DOF2::SearchEntry (key, tag, keybuf, valbuf, pos);
  594.  
  595. // If the entry has been found, just change it's content.
  596. if (entry != INVALID_ENTRY)
  597. {
  598. FileChanged = true;
  599. #if PACK_CONTENT == true
  600. format (line, sizeof (line), "%s = %s", key, value [0] ? value : ("(null)"));
  601. return strpack (Entries.Line [entry], line);
  602. #else
  603. format (Entries.Line [entry], sizeof (Entries.Line []), "%s = %s", key, value [0] ? value : ("(null)"));
  604. return 1;
  605. #endif
  606. }
  607.  
  608. if (Entries.Count >= MAX_ENTRIES)
  609. return 0;
  610.  
  611. // Search for the section where the entry belongs.
  612. if (!tag [0])
  613. section = 0;
  614. else
  615. {
  616. for (i = 1; i < Sections.Count; ++i)
  617. {
  618. #if PACK_CONTENT == true
  619. strunpack (buf, Sections.Tag [i]);
  620. if (buf [0] && !strcmp (tag, buf, !CaseSensitive))
  621. {
  622. section = i;
  623. break;
  624. }
  625. #else
  626. if (Sections.Tag [i][0] && !strcmp (tag, Sections.Tag [i], !CaseSensitive))
  627. {
  628. section = i;
  629. break;
  630. }
  631. #endif
  632. }
  633. }
  634.  
  635. // Section we want does not exist, create new one if possible.
  636. if (section == INVALID_SECTION)
  637. {
  638. if (Sections.Count >= MAX_SECTIONS)
  639. return 0;
  640.  
  641. section = Sections.Count++;
  642. #if PACK_CONTENT == true
  643. strpack (Sections.Tag [section], tag);
  644. #else
  645. DOF2::strcpy (Sections.Tag [section], tag);
  646. #endif
  647. Sections.FirstEntry [section] = Sections.LastEntry [section] = INVALID_ENTRY;
  648. }
  649.  
  650. // Add the entry to the section. Section's content is defined by a linear two way list.
  651. #if PACK_CONTENT == true
  652. format (line, sizeof (line), "%s = %s", key, value [0] ? value : ("(null)"));
  653. strpack (Entries.Line [Entries.Count], line);
  654. #else
  655. format (Entries.Line [Entries.Count], sizeof (Entries.Line []), "%s = %s", key, value [0] ? value : ("(null)"));
  656. #endif
  657. Entries.Tag [Entries.Count] = Sections.Tag [section];
  658. #if MAX_SECTIONS >= 256
  659. Entries.Section [Entries.Count] = section;
  660. #else
  661. Entries.Section {Entries.Count} = section;
  662. #endif
  663. Entries.NextEntry [Entries.Count] = INVALID_ENTRY;
  664.  
  665. // Add entry to sorted list of entries and move to right correct position in O(n) time.
  666. SortedEntryList [Entries.Count][0] = DOF2::HashKey (key);
  667. SortedEntryList [Entries.Count][1] = Entries.Count;
  668. i = Entries.Count - 1;
  669. while (i >= 0 && SortedEntryList [i][0] > SortedEntryList [i + 1][0])
  670. {
  671. DOF2::SwapSortedEntries (SortedEntryList [i], SortedEntryList [i + 1]);
  672. --i;
  673. }
  674.  
  675. if (Sections.LastEntry [section] == INVALID_ENTRY) // No entry in this section.
  676. {
  677. Sections.FirstEntry [section] = Sections.LastEntry [section] = Entries.Count;
  678. Entries.PreviousEntry [Entries.Count] = INVALID_ENTRY;
  679. }
  680. else
  681. {
  682. Entries.NextEntry [Sections.LastEntry [section]] = Entries.Count;
  683. Entries.PreviousEntry [Entries.Count] = Sections.LastEntry [section];
  684. Sections.LastEntry [section] = Entries.Count;
  685. }
  686. ++Entries.Count;
  687. FileChanged = true;
  688. }
  689. return 1;
  690. }
  691.  
  692. stock DOF2::GetString (file [], key [], tag [] = "")
  693. {
  694. new buf [MAX_LINE_SIZE];
  695. DOF2::GetStringEx (file, key, buf, sizeof (buf), tag);
  696. return buf;
  697. }
  698.  
  699. stock DOF2::GetStringEx (file [], key [], result [], size, tag [] = "")
  700. {
  701. if (file [0] && key [0])
  702. {
  703. new
  704. pos,
  705. keybuf [MAX_LINE_SIZE];
  706.  
  707. if (!CurrentFile [0] || strcmp (CurrentFile, file))
  708. {
  709. if (!DOF2::ParseFile (file, -1, false))
  710. {
  711. result [0] = '\0';
  712. return 0;
  713. }
  714. }
  715.  
  716. // Find entry and assign the result with it's value.
  717. return (DOF2::SearchEntry (key, tag, keybuf, result, pos, sizeof (keybuf), size) != INVALID_ENTRY);
  718. }
  719. return 0;
  720. }
  721.  
  722. stock DOF2::Unset (file [], key [], tag [] = "")
  723. {
  724. if (file [0] && key [0])
  725. {
  726. new
  727. entry,
  728. pos,
  729. keybuf [MAX_LINE_SIZE],
  730. valbuf [MAX_LINE_SIZE];
  731.  
  732. if (!CurrentFile [0] || strcmp (CurrentFile, file))
  733. if (!DOF2::ParseFile (file, -1, false))
  734. return 0;
  735.  
  736. if ((entry = DOF2::SearchEntry (key, tag, keybuf, valbuf, pos)) != INVALID_ENTRY)
  737. {
  738. // Remove entry from it's section.
  739. #if MAX_SECTIONS >= 256
  740. if (Sections.FirstEntry [Entries.Section [entry]] == entry) // Is the entry the first entry in the section? Make it's next entry the first entry.
  741. #else
  742. if (Sections.FirstEntry [Entries.Section {entry}] == entry)
  743. #endif
  744. {
  745. #if MAX_SECTIONS >= 256
  746. Sections.FirstEntry [Entries.Section [entry]] = Entries.NextEntry [entry];
  747. #else
  748. Sections.FirstEntry [Entries.Section {entry}] = Entries.NextEntry [entry];
  749. #endif
  750. if (Entries.NextEntry [entry] != INVALID_ENTRY)
  751. Entries.PreviousEntry [Entries.NextEntry [entry]] = INVALID_ENTRY;
  752. }
  753. else
  754. {
  755. Entries.NextEntry [Entries.PreviousEntry [entry]] = Entries.NextEntry [entry];
  756. if (Entries.NextEntry [entry] != INVALID_ENTRY)
  757. Entries.PreviousEntry [Entries.NextEntry [entry]] = Entries.PreviousEntry [entry];
  758. }
  759.  
  760. #if MAX_SECTIONS >= 256
  761. if (Sections.LastEntry [Entries.Section [entry]] == entry)
  762. #else
  763. if (Sections.LastEntry [Entries.Section {entry}] == entry)
  764. #endif
  765. {
  766. #if MAX_SECTIONS >= 256
  767. Sections.LastEntry [Entries.Section [entry]] = Entries.PreviousEntry [entry];
  768. #else
  769. Sections.LastEntry [Entries.Section {entry}] = Entries.PreviousEntry [entry];
  770. #endif
  771. if (Entries.PreviousEntry [entry] != INVALID_ENTRY)
  772. Entries.NextEntry [Entries.PreviousEntry [entry]] = INVALID_ENTRY;
  773. }
  774. else
  775. {
  776. Entries.PreviousEntry [Entries.NextEntry [entry]] = Entries.PreviousEntry [entry];
  777. if (Entries.PreviousEntry [entry] != INVALID_ENTRY)
  778. Entries.NextEntry [Entries.PreviousEntry [entry]] = Entries.NextEntry [entry];
  779. }
  780.  
  781. // Move the entry to the end of the sorted list and decrement Entries.Count to forget about the unset Entries.
  782. while (pos < (Entries.Count - 1))
  783. {
  784. DOF2::SwapSortedEntries (SortedEntryList [pos], SortedEntryList [pos + 1]);
  785. ++pos;
  786. }
  787. --Entries.Count;
  788. FileChanged = true;
  789. return 1;
  790. }
  791. }
  792. return 0;
  793. }
  794.  
  795. stock DOF2::RenameKey (file [], oldkey [], newkey [], tag [] = "")
  796. {
  797. if (file [0] && oldkey [0])
  798. {
  799. new
  800. entry,
  801. pos,
  802. #if PACK_CONTENT == true
  803. line [MAX_LINE_SIZE],
  804. #endif
  805. keybuf [MAX_LINE_SIZE],
  806. valbuf [MAX_LINE_SIZE];
  807.  
  808. if (!CurrentFile [0] || strcmp (CurrentFile, file))
  809. if (!DOF2::ParseFile (file, -1, false))
  810. return 0;
  811.  
  812. if ((entry = DOF2::SearchEntry (oldkey, tag, keybuf, valbuf, pos)) != INVALID_ENTRY)
  813. {
  814. // Change content of Entries.
  815. #if PACK_CONTENT == true
  816. format (line, sizeof (line), "%s = %s", newkey, valbuf [0] ? valbuf : ("(null)"));
  817. strpack (Entries.Line [entry], line);
  818. #else
  819. format (Entries.Line [entry], sizeof (Entries.Line []), "%s = %s", newkey, valbuf [0] ? valbuf : ("(null)"));
  820. #endif
  821.  
  822. // Because the hashcode has been changed, the entry has to move in the list.
  823. SortedEntryList [pos][0] = DOF2::HashKey (newkey);
  824. if (pos < (MAX_ENTRIES - 1) && SortedEntryList [pos][0] > SortedEntryList [pos + 1][0])
  825. {
  826. // Hash value of key is greater than the hash value of it's right neighbor, move to the right by swapping the 2 entries.
  827. while (pos < (MAX_ENTRIES - 1) && SortedEntryList [pos][0] > SortedEntryList [pos + 1][0])
  828. {
  829. DOF2::SwapSortedEntries (SortedEntryList [pos], SortedEntryList [pos + 1]);
  830. ++pos;
  831. }
  832. }
  833. else if (pos > 0 && SortedEntryList [pos][0] < SortedEntryList [pos + 1][0])
  834. {
  835. // Hash value of key is smaller than the hash value of it' left neighbor, move to the left by swapping the 2 entries.
  836. while (pos > 0 && SortedEntryList [pos][0] < SortedEntryList [pos - 1][0])
  837. {
  838. DOF2::SwapSortedEntries (SortedEntryList [pos], SortedEntryList [pos - 1]);
  839. --pos;
  840. }
  841. }
  842.  
  843. FileChanged = true;
  844. return 1;
  845. }
  846. }
  847. return 0;
  848. }
  849.  
  850. stock bool: DOF2::IsSet (file [], key [], tag [] = "")
  851. {
  852. new
  853. pos,
  854. keybuf [MAX_LINE_SIZE],
  855. valbuf [MAX_LINE_SIZE];
  856.  
  857. if (!CurrentFile [0] || strcmp (CurrentFile, file))
  858. if (!DOF2::ParseFile (file, -1, false))
  859. return false;
  860.  
  861. // Try to find the Entries.
  862. return (DOF2::SearchEntry (key, tag, keybuf, valbuf, pos) != INVALID_ENTRY);
  863. }
  864.  
  865. stock DOF2::SetInt (file [], key [], value, tag [] = "")
  866. {
  867. new buf [16];
  868. format (buf, sizeof (buf), "%d", value);
  869. return DOF2::SetString (file, key, buf, tag);
  870. }
  871.  
  872. stock DOF2::GetInt (file [], key [], tag [] = "")
  873. {
  874. new buf [16];
  875. DOF2::GetStringEx (file, key, buf, sizeof (buf), tag);
  876. return strval (buf);
  877. }
  878.  
  879. stock DOF2::SetHex (file [], key [], value, tag [] = "")
  880. {
  881. new buf [16];
  882. DOF2::hexstr (value, buf);
  883. return DOF2::SetString (file, key, buf, tag);
  884. }
  885.  
  886. stock DOF2::GetHex (file [], key [], tag [] = "")
  887. {
  888. new buf [16];
  889. DOF2::GetStringEx (file, key, buf, sizeof (buf), tag);
  890. return DOF2::strhex (buf);
  891. }
  892.  
  893. stock DOF2::SetBin (file [], key [], value, tag [] = "")
  894. {
  895. new buf [35];
  896. DOF2::binstr (value, buf);
  897. return DOF2::SetString (file, key, buf, tag);
  898. }
  899.  
  900. stock DOF2::GetBin (file [], key [], tag [] = "")
  901. {
  902. new buf [35];
  903. DOF2::GetStringEx (file, key, buf, sizeof (buf), tag);
  904. return DOF2::strbin (buf);
  905. }
  906.  
  907. stock DOF2::SetFloat (file [], key [], Float: value, tag [] = "")
  908. {
  909. new buf [32];
  910. format (buf, sizeof (buf), "%.8f", value);
  911. return DOF2::SetString (file, key, buf, tag);
  912. }
  913.  
  914. stock Float: DOF2::GetFloat (file [], key [], tag [] = "")
  915. {
  916. new buf [32];
  917. DOF2::GetStringEx (file, key, buf, sizeof (buf), tag);
  918. return floatstr (buf);
  919. }
  920.  
  921. stock bool: DOF2::GetBool (file [], key [], tag [] = "")
  922. {
  923. new buf [16];
  924. DOF2::GetStringEx (file, key, buf, sizeof (buf), tag);
  925. return (strval (buf) || (buf [0] && !strcmp (buf, "true", true)));
  926. }
  927.  
  928. stock DOF2::SetBool (file [], key [], bool: value, tag [] = "")
  929. return DOF2::SetString (file, key, value ? ("true") : ("false"), tag);
  930.  
  931. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  932.  
  933. stock DOF2::PrintFile (comment [] = "")
  934. {
  935. if (CurrentFile [0])
  936. {
  937. new
  938. bool: firstline = true,
  939. entry,
  940. #if PACK_CONTENT == true
  941. buf [MAX_LINE_SIZE],
  942. #endif
  943. entries,
  944. i;
  945.  
  946. printf ("[DOF] Current file: %s", CurrentFile);
  947. for ( ; i < Sections.Count; ++i)
  948. {
  949. if (i)
  950. {
  951. if (!firstline)
  952. print (" ");
  953. else
  954. firstline = false;
  955. #if PACK_CONTENT == true
  956. strunpack (buf, Sections.Tag [i]);
  957. printf ("[%s]", buf);
  958. #else
  959. printf ("[%s]", Sections.Tag [i]);
  960. #endif
  961. }
  962. entry = Sections.FirstEntry [i];
  963. while (entry != INVALID_ENTRY)
  964. {
  965. #if PACK_CONTENT == true
  966. strunpack (buf, Entries.Line [entry]);
  967. print (buf);
  968. #else
  969. print (Entries.Line [entry]);
  970. #endif
  971. entry = Entries.NextEntry [entry];
  972. firstline = false;
  973. ++entries;
  974. }
  975. }
  976. printf ("* %d sections, %d entries", i, entries);
  977. if (comment [0])
  978. printf ("* Comment: %s", comment);
  979. return 1;
  980. }
  981. return 0;
  982. }
  983.  
  984. stock DOF2::WriteFile ()
  985. {
  986. if (CurrentFile [0])
  987. {
  988. new
  989. File: f = fopen (CurrentFile, io_write),
  990. bool: firstline = true,
  991. entry;
  992.  
  993. if (f)
  994. {
  995. for (new i; i < Sections.Count; ++i)
  996. {
  997. if (Sections.FirstEntry [i] != INVALID_ENTRY) // Do not write when empty.
  998. {
  999. if (i)
  1000. {
  1001. if (!firstline)
  1002. {
  1003. fputchar (f, '\r', UseUTF8);
  1004. fputchar (f, '\n', UseUTF8);
  1005. }
  1006. else
  1007. firstline = false;
  1008. fputchar (f, '[', UseUTF8);
  1009. fwritechars (f, Sections.Tag [i]);
  1010. fputchar (f, ']', UseUTF8);
  1011. fputchar (f, '\r', UseUTF8);
  1012. fputchar (f, '\n', UseUTF8);
  1013. }
  1014.  
  1015. entry = Sections.FirstEntry [i];
  1016. while (entry != INVALID_ENTRY)
  1017. {
  1018. fwritechars (f, Entries.Line [entry]);
  1019. fputchar (f, '\r', UseUTF8);
  1020. fputchar (f, '\n', UseUTF8);
  1021. entry = Entries.NextEntry [entry];
  1022. firstline = false;
  1023. }
  1024. }
  1025. }
  1026. FileChanged = false;
  1027. return fclose (f);
  1028. }
  1029. }
  1030. return 0;
  1031. }
  1032.  
  1033. stock DOF2::ParseFile (file [], extraid = -1, bool: callback = false)
  1034. {
  1035. if (file [0] && DOF2::FileExists (file))
  1036. {
  1037. /*
  1038. Write the file in the buffer when:
  1039. - There is actually a file in the buffer
  1040. - The file in the buffer is not the file you want to parse and this file has been changed.
  1041. - Or the current file is the file you want to and has been changed.
  1042. */
  1043. //if (CurrentFile [0] && ((strcmp (CurrentFile, file) && FileChanged) || FileChanged))
  1044. if (CurrentFile [0] && FileChanged) // Equal to the query above but shorter.
  1045. DOF2::WriteFile ();
  1046.  
  1047. new
  1048. File: f = fopen (file, io_readwrite),
  1049. buf [MAX_LINE_SIZE],
  1050. #if PACK_CONTENT == true
  1051. line [MAX_LINE_SIZE char],
  1052. tag [MAX_SECTION_TAG],
  1053. #else
  1054. line [MAX_LINE_SIZE],
  1055. #endif
  1056. key [MAX_LINE_SIZE],
  1057. value [MAX_LINE_SIZE],
  1058. c,
  1059. pos;
  1060.  
  1061. if (f)
  1062. {
  1063. FileChanged = false;
  1064. DOF2::SetFile (file);
  1065.  
  1066. Sections.Count = 1;
  1067. Entries.Count = 0;
  1068. Sections.FirstEntry [0] = Sections.LastEntry [0] = INVALID_ENTRY;
  1069.  
  1070. for (new i, size = flength (f); i < size; ++i)
  1071. {
  1072. c = fgetchar (f, 0, UseUTF8);
  1073. if (pos == MAX_LINE_SIZE - 1 || c == '\n' || c == '\r')
  1074. c = '\0';
  1075. #if PACK_CONTENT == true
  1076. line {pos++} = c;
  1077. #else
  1078. line [pos++] = c;
  1079. #endif
  1080.  
  1081. if (c == '\0')
  1082. {
  1083. // A new section found. Add the section to the list of sections.
  1084. #if PACK_CONTENT == true
  1085. if (line {0} == '[')
  1086. #else
  1087. if (line [0] == '[')
  1088. #endif
  1089. {
  1090. if (Sections.Count < MAX_SECTIONS)
  1091. {
  1092. pos = 1;
  1093. #if PACK_CONTENT == true
  1094. while (line {pos} && line {pos} != ']' && (pos - 1) < MAX_SECTION_TAG)
  1095. {
  1096. Sections.Tag [Sections.Count]{pos - 1} = line {pos};
  1097. ++pos;
  1098. }
  1099. Sections.Tag [Sections.Count]{pos - 1} = '\0';
  1100. #else
  1101. while (line [pos] && line [pos] != ']' && (pos - 1) < MAX_SECTION_TAG)
  1102. {
  1103. Sections.Tag [Sections.Count][pos - 1] = line [pos];
  1104. ++pos;
  1105. }
  1106. Sections.Tag [Sections.Count][pos - 1] = '\0';
  1107. #endif
  1108. Sections.FirstEntry [Sections.Count] = Sections.LastEntry [Sections.Count] = INVALID_ENTRY;
  1109. ++Sections.Count;
  1110. }
  1111. }
  1112. else
  1113. {
  1114. #if PACK_CONTENT == true
  1115. if (line {0})
  1116. #else
  1117. if (line [0])
  1118. #endif
  1119. {
  1120. #if PACK_CONTENT == true
  1121. strunpack (buf, line);
  1122. DOF2::ParseLine (buf, key, value);
  1123. strunpack (tag, Sections.Tag [Sections.Count - 1]);
  1124.  
  1125. // Call a specific function for a specific entry - ZCMD-style!
  1126. if (callback)
  1127. {
  1128. format (buf, sizeof (buf), "_OnParseFile_%s_%s", tag, key);
  1129. if (!CallRemoteFunction (buf, "is", extraid, value))
  1130. CallRemoteFunction ("_OnDefaultParseFile", "issss", extraid, value [0] ? value : ("\1"), key, Sections.Tag [Sections.Count - 1][0] ? Sections.Tag [Sections.Count - 1] : ("\1"), file);
  1131. }
  1132. #else
  1133. DOF2::ParseLine (line, key, value);
  1134.  
  1135. // Call a specific function for a specific entry - ZCMD-style!
  1136. if (callback)
  1137. {
  1138. format (buf, sizeof (buf), "_OnParseFile_%s_%s", Sections.Tag [Sections.Count - 1], key);
  1139. if (!CallRemoteFunction (buf, "is", extraid, value))
  1140. CallRemoteFunction ("_OnDefaultParseFile", "issss", extraid, value [0] ? value : ("\1"), key, Sections.Tag [Sections.Count - 1][0] ? Sections.Tag [Sections.Count - 1] : ("\1"), file);
  1141. }
  1142. #endif
  1143.  
  1144. // Add entry to it's section and to the list which will be sorted.
  1145. Entries.Line [Entries.Count] = line;
  1146. Entries.Tag [Entries.Count] = Sections.Tag [Sections.Count - 1];
  1147. #if MAX_SECTIONS >= 256
  1148. Entries.Section [Entries.Count] = Sections.Count - 1;
  1149. #else
  1150. Entries.Section {Entries.Count} = Sections.Count - 1;
  1151. #endif
  1152. Entries.NextEntry [Entries.Count] = INVALID_ENTRY;
  1153.  
  1154. SortedEntryList [Entries.Count][0] = DOF2::HashKey (key);
  1155. SortedEntryList [Entries.Count][1] = Entries.Count;
  1156.  
  1157. if (Sections.LastEntry [Sections.Count - 1] == INVALID_ENTRY)
  1158. {
  1159. Sections.FirstEntry [Sections.Count - 1] = Sections.LastEntry [Sections.Count - 1] = Entries.Count;
  1160. Entries.PreviousEntry [Entries.Count] = INVALID_ENTRY;
  1161. }
  1162. else
  1163. {
  1164. Entries.NextEntry [Sections.LastEntry [Sections.Count - 1]] = Entries.Count;
  1165. Entries.PreviousEntry [Entries.Count] = Sections.LastEntry [Sections.Count - 1];
  1166. Sections.LastEntry [Sections.Count - 1] = Entries.Count;
  1167. }
  1168. ++Entries.Count;
  1169. }
  1170. }
  1171. pos = 0;
  1172. }
  1173. }
  1174. /*
  1175. * Sort list of entries by it's hashcodes in O(n * log n) time.
  1176. * (Worst case is actually O(n * n), however, this QuickSort implementation chooses a randomized pivot
  1177. * to minimize the chance for the worst case.)
  1178. */
  1179. DOF2::SortEntries (SortedEntryList, 0, Entries.Count - 1, true);
  1180. return fclose (f);
  1181. }
  1182. }
  1183. return 0;
  1184. }
  1185.  
  1186. // Rather useless.
  1187. stock DOF2::ReparseFile (file [], extraid, bool: callback = true)
  1188. {
  1189. if (file [0] && CurrentFile [0] && !strcmp (file, CurrentFile))
  1190. {
  1191. CurrentFile [0] = '\0';
  1192. return DOF2::ParseFile (file, extraid, callback);
  1193. }
  1194. return 0;
  1195. }
  1196.  
  1197. private DOF2::ParseLine (line [], key [], value [], keysize = sizeof (key), valuesize = sizeof (value))
  1198. {
  1199. new
  1200. pos,
  1201. readpos;
  1202.  
  1203. if ((pos = charfind (line, '=')) != -1)
  1204. {
  1205. // Read key and value.
  1206. readpos = pos - 1;
  1207. while (readpos >= 0 && line [readpos] == ' ')
  1208. --readpos;
  1209.  
  1210. if (readpos >= 0 && keysize > (readpos + 1))
  1211. {
  1212. key [readpos + 1] = '\0';
  1213. while (readpos >= 0)
  1214. {
  1215. key [readpos] = line [readpos];
  1216. --readpos;
  1217. }
  1218. }
  1219. else
  1220. return 0;
  1221.  
  1222. readpos = pos + 1;
  1223. ++pos;
  1224. while (line [readpos] == ' ')
  1225. {
  1226. ++pos;
  1227. ++readpos;
  1228. }
  1229.  
  1230. if (line [readpos])
  1231. {
  1232. while (readpos >= 0 && line [readpos] && valuesize > (readpos - pos + 1))
  1233. {
  1234. value [readpos - pos] = line [readpos];
  1235. ++readpos;
  1236. }
  1237. value [readpos - pos] = '\0';
  1238. }
  1239. else
  1240. {
  1241. key [0] = value [0] = '\0';
  1242. return 0;
  1243. }
  1244.  
  1245. if (!strcmp (value, "(null)", true))
  1246. value [0] = '\0';
  1247. return 1;
  1248. }
  1249. key [0] = value [0] = '\0';
  1250. return 0;
  1251. }
  1252.  
  1253. stock DOF2::File (user [])
  1254. {
  1255. new newfile [MAX_FILE_SIZE];
  1256. format (newfile, sizeof (newfile), USER_FILE_PATH, DOF2::udb_encode (user));
  1257. return newfile;
  1258. }
  1259.  
  1260. stock bool: DOF2::CheckLogin (file [], password [])
  1261. return (file [0] && password [0] && DOF2::num_hash (password) == DOF2::GetInt (file, USER_PW_HASH_KEY));
  1262.  
  1263. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1264.  
  1265. stock DOF2::binstr (value, dest [], size = sizeof (dest))
  1266. {
  1267. new buf [32 + 3] = "0b";
  1268. for (new i = 0; i < 32; ++i)
  1269. buf [i + 2] = '0' + ((value >>> (31 - i)) & 1);
  1270.  
  1271. DOF2::strcpy (dest, buf, size);
  1272. }
  1273. //format (dest, size, "0b%b", value);
  1274.  
  1275. stock DOF2::hexstr (value, dest [], size = sizeof (dest))
  1276. {
  1277. static const characters [] =
  1278. {
  1279. '0', '1', '2', '3',
  1280. '4', '5', '6', '7',
  1281. '8', '9', 'A', 'B',
  1282. 'C', 'D', 'E', 'F'
  1283. };
  1284.  
  1285. new buf [8 + 3] = "0x";
  1286.  
  1287. for (new i = 0; i < 8; ++i)
  1288. buf [2 + i] = characters [(value >>> ((7 - i) << 2)) & 0x0F];
  1289.  
  1290. DOF2::strcpy (dest, buf, size);
  1291. }
  1292. //format (dest, size, "0x%x", value);
  1293.  
  1294. stock DOF2::strhex (string [])
  1295. {
  1296. new
  1297. i,
  1298. value;
  1299.  
  1300. if (string [0] == '0' && (string [1] == 'x' || string [1] == 'X'))
  1301. i = 2;
  1302.  
  1303. while (string [i])
  1304. {
  1305. value <<= 4;
  1306. switch (string [i])
  1307. {
  1308. case '0' .. '9':
  1309. value |= string [i] - '0';
  1310.  
  1311. case 'A' .. 'F':
  1312. value |= string [i] - 'A' + 10;
  1313.  
  1314. case 'a' .. 'f':
  1315. value |= string [i] - 'a' + 10;
  1316.  
  1317. default:
  1318. return 0;
  1319. }
  1320. ++i;
  1321. }
  1322. return value;
  1323. }
  1324.  
  1325. stock DOF2::strbin (string [])
  1326. {
  1327. new
  1328. i,
  1329. value;
  1330.  
  1331. if (string [0] == '0' && (string [1] == 'b' || string [1] == 'B'))
  1332. i = 2;
  1333.  
  1334. while (string [i])
  1335. {
  1336. if (string [i] != '1' && string [i] != '0')
  1337. return 0;
  1338.  
  1339. value <<= 1;
  1340. value |= (string [i] - '0');
  1341. ++i;
  1342. }
  1343. return value;
  1344. }
  1345.  
  1346. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1347.  
  1348. private charfind (string [], c)
  1349. {
  1350. for (new i, len = strlen (string); i < len; ++i)
  1351. if (string [i] == c)
  1352. return i;
  1353. return -1;
  1354. }
  1355.  
  1356. private fwritechars (File: handle, c [])
  1357. {
  1358. new pos;
  1359. #if PACK_CONTENT == true
  1360. while (c {pos})
  1361. fputchar (handle, c {pos++}, UseUTF8);
  1362. #else
  1363. while (c [pos])
  1364. fputchar (handle, c [pos++], UseUTF8);
  1365. #endif
  1366. }
  1367.  
  1368. private DOF2::SortEntries (entries [][2], l, r, bool: randomize = true)
  1369. {
  1370. if (r > l)
  1371. {
  1372. if (randomize)
  1373. {
  1374. new k = l + (random (65535) % (r - l + 1));
  1375. DOF2::SwapSortedEntries (entries [k], entries [r]);
  1376. }
  1377.  
  1378. new
  1379. i = l - 1,
  1380. j = r,
  1381. pivot = entries [r][0];
  1382.  
  1383. while (i < j)
  1384. {
  1385. do
  1386. ++i;
  1387. while (entries [i][0] <= pivot && i < r);
  1388.  
  1389. do
  1390. --j;
  1391. while (entries [j][0] >= pivot && j > l);
  1392.  
  1393. if (i < j)
  1394. DOF2::SwapSortedEntries (entries [i], entries [j]);
  1395. }
  1396. DOF2::SwapSortedEntries (entries [i], entries [r]);
  1397. DOF2::SortEntries (entries, l, i - 1, randomize);
  1398. DOF2::SortEntries (entries, i + 1, r, randomize);
  1399. }
  1400. }
  1401.  
  1402. private DOF2::SwapSortedEntries (a [2], b [2])
  1403. {
  1404. new c [2];
  1405. c [0] = a [0];
  1406. c [1] = a [1];
  1407. a [0] = b [0];
  1408. a [1] = b [1];
  1409. b [0] = c [0];
  1410. b [1] = c [1];
  1411. }
  1412.  
  1413. stock DOF2::SortAllSections (file [], bool: ignorecase = true, bool: ascending = true)
  1414. {
  1415. if (file [0])
  1416. {
  1417. if (!CurrentFile [0] || strcmp (CurrentFile, file)) // No file in buffer or the file you want to read from is not the file in the buffer.
  1418. if (!DOF2::ParseFile (file, -1, false))
  1419. return 0;
  1420.  
  1421. new
  1422. entries [MAX_ENTRIES],
  1423. keys [MAX_ENTRIES][MAX_LINE_SIZE],
  1424. key [MAX_LINE_SIZE],
  1425. value [MAX_LINE_SIZE],
  1426. #if PACK_CONTENT == true
  1427. line [MAX_LINE_SIZE],
  1428. #endif
  1429. entry,
  1430. i;
  1431.  
  1432. for (new section = 0; section < Sections.Count; ++section)
  1433. {
  1434. i = 0;
  1435. entry = Sections.FirstEntry [section];
  1436. while (entry != INVALID_ENTRY)
  1437. {
  1438. #if PACK_CONTENT == true
  1439. strunpack (line, Entries.Line [entry]);
  1440. DOF2::ParseLine (line, key, value);
  1441. #else
  1442. DOF2::ParseLine (Entries.Line [entry], key, value);
  1443. #endif
  1444. keys [i][0] = '\0';
  1445. strcat (keys [i], key);
  1446. entries [i] = entry;
  1447. entry = Entries.NextEntry [entry];
  1448. ++i;
  1449. }
  1450.  
  1451. if (i > 0)
  1452. DOF2::SortSection_Internal (section, entries, keys, 0, i - 1, ignorecase, ascending);
  1453. }
  1454. return 1;
  1455. }
  1456. return 0;
  1457. }
  1458.  
  1459. stock DOF2::SortSection (file [], tag [], bool: ignorecase = true, bool: ascending = true)
  1460. {
  1461. if (file [0])
  1462. {
  1463. if (!CurrentFile [0] || strcmp (CurrentFile, file)) // No file in buffer or the file you want to read from is not the file in the buffer.
  1464. if (!DOF2::ParseFile (file, -1, false))
  1465. return 0;
  1466.  
  1467. new
  1468. section = INVALID_SECTION,
  1469. entries [MAX_ENTRIES],
  1470. keys [MAX_ENTRIES][MAX_LINE_SIZE],
  1471. key [MAX_LINE_SIZE],
  1472. buf [MAX_LINE_SIZE],
  1473. #if PACK_CONTENT == true
  1474. line [MAX_LINE_SIZE],
  1475. #endif
  1476. entry,
  1477. i;
  1478.  
  1479. if (!tag [0])
  1480. section = 0;
  1481. else
  1482. {
  1483. for (i = 1; i < Sections.Count; ++i)
  1484. {
  1485. #if PACK_CONTENT == true
  1486. strunpack (buf, Sections.Tag [i]);
  1487. if (buf [0] && !strcmp (tag, buf, !CaseSensitive))
  1488. {
  1489. section = i;
  1490. break;
  1491. }
  1492. #else
  1493. if (Sections.Tag [i][0] && !strcmp (tag, Sections.Tag [i], !CaseSensitive))
  1494. {
  1495. section = i;
  1496. break;
  1497. }
  1498. #endif
  1499. }
  1500. }
  1501.  
  1502. if (section != INVALID_SECTION)
  1503. {
  1504. i = 0;
  1505. entry = Sections.FirstEntry [section];
  1506. while (entry != INVALID_ENTRY)
  1507. {
  1508. #if PACK_CONTENT == true
  1509. strunpack (line, Entries.Line [entry]);
  1510. DOF2::ParseLine (line, key, buf);
  1511. #else
  1512. DOF2::ParseLine (Entries.Line [entry], key, buf);
  1513. #endif
  1514. keys [i][0] = '\0';
  1515. strcat (keys [i], key);
  1516. entries [i] = entry;
  1517. entry = Entries.NextEntry [entry];
  1518. ++i;
  1519. }
  1520.  
  1521. if (i > 0)
  1522. {
  1523. DOF2::SortSection_Internal (section, entries, keys, 0, i - 1, ignorecase, ascending);
  1524. return 1;
  1525. }
  1526. }
  1527. }
  1528. return 0;
  1529. }
  1530.  
  1531. private DOF2::SortSection_Internal (section, entries [], keys [][], l, r, bool: ignorecase = true, bool: ascending = true)
  1532. {
  1533. // Entries must be stored into an array...
  1534. if (0 <= section < Sections.Count && r > l)
  1535. {
  1536. new
  1537. i = l - 1,
  1538. j = r,
  1539. buf [MAX_LINE_SIZE];
  1540.  
  1541. static
  1542. pivot [MAX_LINE_SIZE]; // Must be static, otherwise too much memory usage during recursion ==> Script will crash!
  1543.  
  1544. pivot [0] = '\0';
  1545. strcat (pivot, keys [r]);
  1546.  
  1547. while (i < j)
  1548. {
  1549. if (ascending)
  1550. {
  1551. do
  1552. ++i;
  1553. while (strcmp (keys [i], pivot, ignorecase) <= 0 && i < r);
  1554.  
  1555. do
  1556. --j;
  1557. while (strcmp (keys [j], pivot, ignorecase) >= 0 && j > l);
  1558. }
  1559. else
  1560. {
  1561. do
  1562. ++i;
  1563. while (strcmp (keys [i], pivot, ignorecase) >= 0 && i < r);
  1564.  
  1565. do
  1566. --j;
  1567. while (strcmp (keys [j], pivot, ignorecase) <= 0 && j > l);
  1568. }
  1569.  
  1570. if (i < j)
  1571. {
  1572. DOF2::SwapEntries (section, entries [i], entries [j]);
  1573.  
  1574. DOF2::strcpy (buf, keys [i]);
  1575. DOF2::strcpy (keys [i], keys [j], MAX_LINE_SIZE);
  1576. DOF2::strcpy (keys [j], buf, MAX_LINE_SIZE);
  1577.  
  1578. entries [i] ^= entries [j];
  1579. entries [j] ^= entries [i];
  1580. entries [i] ^= entries [j];
  1581. }
  1582. }
  1583.  
  1584. if (i != r)
  1585. {
  1586. DOF2::SwapEntries (section, entries [i], entries [r]);
  1587.  
  1588. DOF2::strcpy (buf, keys [i]);
  1589. DOF2::strcpy (keys [i], keys [r], MAX_LINE_SIZE);
  1590. DOF2::strcpy (keys [r], buf, MAX_LINE_SIZE);
  1591.  
  1592. entries [i] ^= entries [r];
  1593. entries [r] ^= entries [i];
  1594. entries [i] ^= entries [r];
  1595. }
  1596.  
  1597. DOF2::SortSection_Internal (section, entries, keys, l, i - 1, ignorecase, ascending);
  1598. DOF2::SortSection_Internal (section, entries, keys, i + 1, r, ignorecase, ascending);
  1599. }
  1600. }
  1601.  
  1602. private DOF2::SwapEntries (section, entry1, entry2)
  1603. {
  1604. // This swaps two entries in the entry list of a section. (Pointers are swapped)
  1605. if (0 <= section < Sections.Count && 0 <= entry1 <= Entries.Count && 0 <= entry2 <= Entries.Count)
  1606. {
  1607. if (entry1 == Sections.FirstEntry [section])
  1608. Sections.FirstEntry [section] = entry2;
  1609. else if (entry2 == Sections.FirstEntry [section])
  1610. Sections.FirstEntry [section] = entry1;
  1611.  
  1612. if (entry1 == Sections.LastEntry [section])
  1613. Sections.LastEntry [section] = entry2;
  1614. else if (entry2 == Sections.LastEntry [section])
  1615. Sections.LastEntry [section] = entry1;
  1616.  
  1617. if (Entries.NextEntry [entry1] == entry2)
  1618. {
  1619. Entries.NextEntry [entry1] = Entries.NextEntry [entry2];
  1620. Entries.PreviousEntry [entry2] = Entries.PreviousEntry [entry1];
  1621.  
  1622. if (Entries.PreviousEntry [entry1] != INVALID_ENTRY)
  1623. Entries.NextEntry [Entries.PreviousEntry [entry1]] = entry2;
  1624.  
  1625. if (Entries.NextEntry [entry2] != INVALID_ENTRY)
  1626. Entries.PreviousEntry [Entries.NextEntry [entry2]] = entry1;
  1627.  
  1628. Entries.NextEntry [entry2] = entry1;
  1629. Entries.PreviousEntry [entry1] = entry2;
  1630. }
  1631. else if (Entries.NextEntry [entry2] == entry1)
  1632. {
  1633. Entries.NextEntry [entry2] = Entries.NextEntry [entry1];
  1634. Entries.PreviousEntry [entry1] = Entries.PreviousEntry [entry2];
  1635.  
  1636. if (Entries.PreviousEntry [entry2] != INVALID_ENTRY)
  1637. Entries.NextEntry [Entries.PreviousEntry [entry2]] = entry1;
  1638.  
  1639. if (Entries.NextEntry [entry1] != INVALID_ENTRY)
  1640. Entries.PreviousEntry [Entries.NextEntry [entry1]] = entry2;
  1641.  
  1642. Entries.NextEntry [entry1] = entry2;
  1643. Entries.PreviousEntry [entry2] = entry1;
  1644. }
  1645. else
  1646. {
  1647. new pointer;
  1648.  
  1649. if (Entries.PreviousEntry [entry1] != INVALID_ENTRY)
  1650. Entries.NextEntry [Entries.PreviousEntry [entry1]] = entry2;
  1651.  
  1652. if (Entries.NextEntry [entry1] != INVALID_ENTRY)
  1653. Entries.PreviousEntry [Entries.NextEntry [entry1]] = entry2;
  1654.  
  1655. if (Entries.PreviousEntry [entry2] != INVALID_ENTRY)
  1656. Entries.NextEntry [Entries.PreviousEntry [entry2]] = entry1;
  1657.  
  1658. if (Entries.NextEntry [entry2] != INVALID_ENTRY)
  1659. Entries.PreviousEntry [Entries.NextEntry [entry2]] = entry1;
  1660.  
  1661. pointer = Entries.NextEntry [entry1];
  1662. Entries.NextEntry [entry1] = Entries.NextEntry [entry2];
  1663. Entries.NextEntry [entry2] = pointer;
  1664.  
  1665. pointer = Entries.PreviousEntry [entry1];
  1666. Entries.PreviousEntry [entry1] = Entries.PreviousEntry [entry2];
  1667. Entries.PreviousEntry [entry2] = pointer;
  1668. }
  1669. return 1;
  1670. }
  1671. return 0;
  1672. }
  1673.  
  1674. private DOF2::HashKey (key [])
  1675. {
  1676. new
  1677. h = -1,
  1678. i,
  1679. j;
  1680.  
  1681. if (CaseSensitive)
  1682. {
  1683. while ((j = key [i++]))
  1684. h = h * 33 + j;
  1685. }
  1686. else
  1687. {
  1688. while ((j = tolower (key [i++])))
  1689. h = h * 33 + j;
  1690. }
  1691. return h;
  1692. }
  1693.  
  1694. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1695.  
  1696. stock DOF2::strcpy (dest [], const src [], size = sizeof (dest))
  1697. {
  1698. dest [0] = '\0';
  1699. strcat (dest, src, size);
  1700. }
  1701.  
  1702. // Replace [oldstr] with [newstr] in [srcstr] and copy write the new string to 'deststr'.
  1703.  
  1704. stock DOF2::strreplace (const newstr [], const oldstr [], const srcstr [], deststr [], bool: ignorecase = false, size = sizeof (deststr))
  1705. {
  1706. new
  1707. newlen = strlen (newstr),
  1708. oldlen = strlen (oldstr),
  1709. srclen = strlen (srcstr),
  1710. idx,
  1711. rep;
  1712.  
  1713. for (new i = 0; i < srclen; ++i)
  1714. {
  1715. if (idx < (size - 1))
  1716. {
  1717. if ((i + oldlen) <= srclen)
  1718. {
  1719. if (!strcmp (srcstr [i], oldstr, ignorecase, oldlen))
  1720. {
  1721. deststr [idx] = '\0';
  1722. strcat (deststr, newstr, size);
  1723. ++rep;
  1724. idx += newlen;
  1725. i += oldlen - 1;
  1726. }
  1727. else
  1728. deststr [idx++] = srcstr [i];
  1729. }
  1730. else
  1731. deststr [idx++] = srcstr [i];
  1732. }
  1733. else
  1734. return rep;
  1735. }
  1736. deststr [idx] = '\0';
  1737. return rep;
  1738. }
  1739.  
  1740. stock DOF2::udb_encode (nickname [])
  1741. {
  1742. new
  1743. buf [256],
  1744. result [256];
  1745.  
  1746. static const symbols [][2][] =
  1747. {
  1748. {"_", "_00"},
  1749. {";", "_01"},
  1750. {"!", "_02"},
  1751. {"/", "_03"},
  1752. {"\\", "_04"},
  1753. {"[", "_05"},
  1754. {"]", "_06"},
  1755. {"?", "_07"},
  1756. {".", "_08"},
  1757. {"*", "_09"},
  1758. {"<", "_10"},
  1759. {">", "_11"},
  1760. {"{", "_12"},
  1761. {"}", "_13"},
  1762. {" ", "_14"},
  1763. {"\"", "_15"},
  1764. {":", "_16"},
  1765. {"|", "_17"},
  1766. {"=", "_18"}
  1767. };
  1768.  
  1769. strcat (buf, nickname);
  1770. for (new i = 0; i < sizeof (symbols); ++i)
  1771. {
  1772. DOF2::strreplace (symbols [i][1], symbols [i][0], buf, result);
  1773. DOF2::strcpy (buf, result);
  1774. }
  1775. return result;
  1776. }
  1777.  
  1778. stock DOF2::udb_decode (nickname [])
  1779. {
  1780. new
  1781. buf [256],
  1782. result [256];
  1783.  
  1784. static const symbols [][2][] =
  1785. {
  1786. {"_", "_00"},
  1787. {";", "_01"},
  1788. {"!", "_02"},
  1789. {"/", "_03"},
  1790. {"\\", "_04"},
  1791. {"[", "_05"},
  1792. {"]", "_06"},
  1793. {"?", "_07"},
  1794. {".", "_08"},
  1795. {"*", "_09"},
  1796. {"<", "_10"},
  1797. {">", "_11"},
  1798. {"{", "_12"},
  1799. {"}", "_13"},
  1800. {" ", "_14"},
  1801. {"\"", "_15"},
  1802. {":", "_16"},
  1803. {"|", "_17"},
  1804. {"=", "_18"}
  1805. };
  1806.  
  1807. strcat (buf, nickname);
  1808. for (new i = 0; i < sizeof (symbols); ++i)
  1809. {
  1810. DOF2::strreplace (symbols [i][0], symbols [i][1], buf, result);
  1811. DOF2::strcpy (buf, result);
  1812. }
  1813. return result;
  1814. }
  1815.  
  1816. stock DOF2::num_hash (buf [])
  1817. {
  1818. new
  1819. length = strlen (buf),
  1820. s1 = 1,
  1821. s2 = 0,
  1822. n;
  1823.  
  1824. for (n = 0; n < length; n++)
  1825. {
  1826. s1 = (s1 + buf [n]) % 65521;
  1827. s2 = (s2 + s1) % 65521;
  1828. }
  1829. return (s2 << 16) + s1;
  1830. }
  1831.  
  1832. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1833.  
  1834. #if defined DUDB_CONVERT
  1835.  
  1836. #tryinclude <dutils>
  1837.  
  1838. #define dUser(%0).( DOF2_GetString(DOF2_File(%0),
  1839. #define dUserSet(%0).( DOF2_SetString(DOF2_File(%0),
  1840. #define dUserINT(%0).( DOF2_GetInt(DOF2_File(%0),
  1841. #define dUserSetINT(%0).( DOF2_SetInt(DOF2_File(%0),
  1842. #define dUserFLOAT(%0).( DOF2_GetFloat(DOF2_File(%0),
  1843. #define dUserSetFLOAT(%0).( DOF2_SetFloat(DOF2_File(%0),
  1844. #define udb_Create(%0,%1) DOF2_CreateFile(DOF2_File(%0),%1)
  1845. #define udb_RenameUser(%0,%1) DOF2_RenameFile(DOF2_File(%0),DOF2_File(%1))
  1846. #define udb_Exists(%0) DOF2_FileExists(DOF2_File(%0))
  1847. #define udb_Remove(%0) DOF2_RemoveFile(DOF2_File(%0))
  1848. #define udb_CheckLogin(%0,%1) DOF2_CheckLogin(DOF2_File(%0),%1)
  1849.  
  1850. #if !defined _dudb_included
  1851. #define _dudb_included
  1852. #endif
  1853.  
  1854. #endif
  1855.  
  1856. #if defined DINI_CONVERT
  1857.  
  1858. #define dini_Exists DOF2_FileExists
  1859. #define dini_Remove DOF2_RemoveFile
  1860. #define dini_Create DOF2_CreateFile
  1861. #define dini_Set DOF2_SetString
  1862. #define dini_Get DOF2_GetString
  1863. #define dini_IntSet DOF2_SetInt
  1864. #define dini_Int DOF2_GetInt
  1865. #define dini_BoolSet DOF2_SetBool
  1866. #define dini_Bool DOF2_GetBool
  1867. #define dini_FloatSet DOF2_SetFloat
  1868. #define dini_Float DOF2_GetFloat
  1869. #define dini_Unset DOF2_Unset
  1870. #define dini_Isset DOF2_IsSet
  1871.  
  1872. #if !defined _dini_included
  1873. #define _dini_included
  1874. #endif
  1875.  
  1876. #endif
  1877.  
  1878. /*
  1879. #if defined DINI_CONVERT || defined DUDB_CONVERT
  1880.  
  1881. #define udb_hash DOF2_num_hash
  1882. #define num_hash DOF2_num_hash
  1883. #define udb_encode DOF2_udb_encode
  1884. #define udb_decode DOF2_udb_decode
  1885.  
  1886. #endif
  1887. */
  1888.  
  1889. CreateMafia(mafia[])
  1890. {
  1891. new mafiaadded[128]
  1892. format(mafiadded,sizeof(mafiaaddded),"mafia/%s.members.ini",mafia[]);
  1893. dini_Create(mafiaadded);
  1894. printf("Mafia %s added succesfuelly",mafia[]);
  1895. return 1;
  1896. }
  1897.  
  1898. AddMafiaMember(name[], mafia[])
  1899. {
  1900. new membermafia[64]
  1901. format(membermafia,sizeof(membermafia),"mafia/%s.members.ini",mafia[]);
  1902. dini_IntSet("membermafia", PlayerName(name[]), 1);
  1903. print("Player added to mafia succesfuelly");
  1904. return 1;
  1905. }
  1906.  
  1907. DeleteMafiaMember(name[], mafia[])
  1908. {
  1909. new membermafia[64]
  1910. format(membermafia,sizeof(membermafia),"mafia/%s.members.ini",mafia[]);
  1911. dini_IntSet("membermafia", PlayerName(name[]), 0);
  1912. print("Player delete from mafia succesfuelly");
  1913. return 1;
  1914. }
  1915.  
  1916. SetMafiaBase(mafia[], Float:X, Float:Y, Float:Z)
  1917. {
  1918. new mafiabase[64];
  1919. format(mafiabase,sizeof(mafiabase),"mafia/%s.base.ini",mafia[]);
  1920. dini_Create(mafiabase);
  1921. dini_FloatSet("mafiabase", "PositionX", Float:X);
  1922. dini_FloatSet("mafiabase", "PositionY", Float:Y);
  1923. dini_FloatSet("mafiabase", "PositionZ", Float:Z);
  1924. printf("Base added to %s mafia succesfuelly",mafia[]);
  1925. return 1;
  1926. }
  1927.  
  1928. IsMafiaOwnerBase(mafia[], basename[])
  1929. {
  1930. if(basename[] == mafia[])
  1931. }
  1932.  
  1933. IsPlayerInMafia(name[], mafia[])
  1934. {
  1935. new ismafia[64];
  1936. format(ismafia,sizeof(ismafia),"mafia/%s.members.ini",mafia[]);
  1937. if(dini_Get(ismafia, name[]))
  1938. return 1;
  1939. }
  1940.  
  1941. DeleteMafia(mafia[])
  1942. {
  1943. new mafiadeleted[128]
  1944. format(mafiadeleted,sizeof(mafiadeleted),"mafia/%s.members.ini",mafia[]);
  1945. dini_Remove(mafiadeleted);
  1946. format(mafiadeleted,sizeof(mafiadeleted),"mafia/%s.base.ini",mafia[]);
  1947. dini_Remove(mafiadeleted);
  1948. printf("Mafia %s delete succesfuelly",mafia[]);
  1949. return 1;
  1950. }
  1951.  
  1952. SetMafiaColor(mafia[], color[])
  1953. {
  1954. new mafiainfo[64]
  1955. format(mafiainfo,sizeof(mafiainfo),"mafia/%s.info.ini",mafia[]);
  1956. dini_Set(mafiainfo, "MafiaColor", color);
  1957. print("Mafia color set succesfuelly");
  1958. return 1;
  1959. }
  1960.  
  1961. SetMafiaSkin(mafia[], skinid)
  1962. {
  1963. new mafiainfo[64]
  1964. format(mafiainfo,sizeof(mafiainfo),"mafia/%s.info.ini",mafia[]);
  1965. dini_IntSet(mafiainfo, "MafiaSkin", skinid);
  1966. return 1;
  1967. }
  1968.  
  1969. SetMafiaTag(mafia[], tag[])
  1970. {
  1971. new mafiainfo[64]
  1972. format(mafiainfo,sizeof(mafiainfo),"mafia/%s.info.ini",mafia[]);
  1973. dini_Set(mafiainfo, "MafiaTag", tag[]);
  1974. return 1;
  1975. }
  1976.  
  1977. SetMafiaLider(name[], mafia[])
  1978. {
  1979. new mafiainfo[64]
  1980. format(mafiainfo,sizeof(mafiainfo),"mafia/%s.info.ini",mafia[]);
  1981. dini_Set(mafiainfo, "MafiaLider", name[]);
  1982. return 1;
  1983. }
  1984.  
  1985. SetMafiaViceLider(name[], mafia[])
  1986. {
  1987. new mafiainfo[64]
  1988. format(mafiainfo,sizeof(mafiainfo),"mafia/%s.info.ini",mafia[]);
  1989. dini_Set(mafiainfo, "MafiaViceLider", name[]);
  1990. return 1;
  1991. }
  1992.  
  1993.  
  1994.  
  1995.  
  1996.  
  1997. stock PlayerName(playerid)
  1998. {
  1999. new name[MAX_PLAYER_NAME];
  2000. GetPlayerName(playerid, name, MAX_PLAYER_NAME);
  2001. return name;
  2002. }
  2003.  
  2004.  
  2005.  
  2006.  
Advertisement
Add Comment
Please, Sign In to add comment