AMXX-BG.INFO fvault.inc Raw include

fvault.inc

Original include source with line numbers.

Back Download .inc
1 #if defined _file_vault_included
2 #endinput
3 #endif
4
5 #define _file_vault_included
6
7 /**
8 * FVault was created by Exolent on 8/24/08
9 * This vault system uses actual files and no modules
10 * It is very flexible and has many features
11 * Visit this page for more information: http://forums.alliedmods.net/showthread.php?t=76453
12 */
13
14 #include <amxmodx>
15
16 stock const _vault_dir[] = "addons/amxmodx/data/file_vault";
17 stock const _temp_vault[] = "fvault_temp.txt";
18
19 /**
20 * Retrieves a key name specified by its number
21 *
22 * @param vaultname Vault name to look in
23 * @param keynum Key number within the vault to find key name
24 * @param key String which key name will be copied to
25 * @param len Length of key name
26 * @return Returns 1 on success, 0 on failue.
27 */
28 stock fvault_get_keyname(const vaultname[], const keynum, key[], len)
29 {
30 new filename[128];
31 _FormatVaultName(vaultname, filename, sizeof(filename) - 1);
32
33 if( !file_exists(filename) )
34 {
35 return 0;
36 }
37
38 new vault = fopen(filename, "rt");
39
40 new _data[64], _other[3];
41
42 new line = -1;
43
44 while( !feof(vault) )
45 {
46 fgets(vault, _data, sizeof(_data) - 1);
47
48 if( ++line == keynum )
49 {
50 parse(_data, key, len, _other, sizeof(_other) - 1);
51
52 fclose(vault);
53
54 return 1;
55 }
56 }
57
58 fclose(vault);
59
60 return 0;
61 }
62
63 /**
64 * Retrieves a key number specified by its name
65 *
66 * @param vaultname Vault name to look in
67 * @param key Key name to search for
68 * @return Returns key number on success, -1 on failure
69 */
70 stock fvault_get_keynum(const vaultname[], const key[])
71 {
72 new filename[128];
73 _FormatVaultName(vaultname, filename, sizeof(filename) - 1);
74
75 if( !file_exists(filename) )
76 {
77 return -1;
78 }
79
80 new vault = fopen(filename, "rt");
81
82 new _data[70], _key[64], _other[3];
83
84 new line = -1;
85
86 while( !feof(vault) )
87 {
88 fgets(vault, _data, sizeof(_data) - 1);
89 parse(_data, _key, sizeof(_key) - 1, _other, sizeof(_other) - 1);
90
91 line++;
92
93 if( equal(_key, key) )
94 {
95 fclose(vault);
96
97 return line;
98 }
99 }
100
101 fclose(vault);
102
103 return -1;
104 }
105
106 /**
107 * Retrieves data specified by a key
108 *
109 * @param vaultname Vault name to look in
110 * @param key Key name to look for the data
111 * @param data String which data will be copied to
112 * @param len Length of data
113 * @param timestamp The unix time of when the data was last set ( -1 if permanent data, 0 if old fvault version ) ( optional param )
114 * @return Returns 1 on success, 0 on failue.
115 */
116 stock fvault_get_data(const vaultname[], const key[], data[], len, &timestamp=0)
117 {
118 new filename[128];
119 _FormatVaultName(vaultname, filename, sizeof(filename) - 1);
120
121 if( !file_exists(filename) )
122 {
123 return 0;
124 }
125
126 new vault = fopen(filename, "rt");
127
128 new _data[512], _key[64], _time[32];
129
130 while( !feof(vault) )
131 {
132 fgets(vault, _data, sizeof(_data) - 1);
133 parse(_data, _key, sizeof(_key) - 1);
134
135 if( equal(_key, key) )
136 {
137 new _len = strlen(_key) + 4; // + 2 = quotes on key, + 1 = space, + 1 = first quote
138 for( new i = copy(data, len, _data[_len]) - 1; i > 0; i-- )
139 {
140 if( data[i] == '"' ) break;
141
142 if( data[i] == ' '
143 && data[i - 1] == '"' )
144 {
145 data[i - 1] = '^0';
146
147 copy(_time, sizeof(_time) - 1, data[i + 1]);
148 timestamp = str_to_num(_time);
149 break;
150 }
151 }
152
153 fclose(vault);
154
155 return 1;
156 }
157 }
158
159 fclose(vault);
160
161 copy(data, len, "");
162
163 return 0;
164 }
165
166 /**
167 * Sets data of a key with current timestamp
168 *
169 * @param vaultname Vault name to look in
170 * @param key Key name to which data will be set
171 * @param data Data to set to key
172 * @return Does not return a value.
173 */
174 stock fvault_set_data(const vaultname[], const key[], const data[])
175 {
176 _fvault_set_data(vaultname, key, data, get_systime());
177 }
178
179 /**
180 * Sets data of a key permanently (can't be removed with fvault_prune)
181 *
182 * @param vaultname Vault name to look in
183 * @param key Key name to which data will be set
184 * @param data Data to set to key
185 * @return Does not return a value.
186 */
187 stock fvault_pset_data(const vaultname[], const key[], const data[])
188 {
189 _fvault_set_data(vaultname, key, data, -1);
190 }
191
192 _fvault_set_data(const vaultname[], const key[], const data[], const timestamp)
193 {
194 new file = fopen(_temp_vault, "wt");
195
196 new filename[128];
197 _FormatVaultName(vaultname, filename, sizeof(filename) - 1);
198
199 new vault = fopen(filename, "rt");
200
201 new _data[512], _key[64], _other[3];
202
203 new bool:replaced = false;
204
205 while( !feof(vault) )
206 {
207 fgets(vault, _data, sizeof(_data) - 1);
208 parse(_data, _key, sizeof(_key) - 1, _other, sizeof(_other) - 1);
209
210 if( equal(_key, key) && !replaced )
211 {
212 fprintf(file, "^"%s^" ^"%s^" %i^n", key, data, timestamp);
213
214 replaced = true;
215 }
216 else
217 {
218 fputs(file, _data);
219 }
220 }
221
222 fclose(file);
223 fclose(vault);
224
225 if( !replaced )
226 {
227 file = fopen(filename, "a+");
228 fprintf(file, "^"%s^" ^"%s^" %i^n", key, data, timestamp);
229 fclose(file);
230
231 delete_file(_temp_vault);
232 }
233 else
234 {
235 delete_file(filename);
236
237 while( !rename_file(_temp_vault, filename, 1) ) { }
238 }
239 }
240
241 /**
242 * Removes a key from a vault
243 *
244 * @param vaultname Vault name to look in
245 * @param key Key to remove
246 * @return No return
247 */
248 stock fvault_remove_key(const vaultname[], const key[])
249 {
250 new filename[128];
251 _FormatVaultName(vaultname, filename, sizeof(filename) - 1);
252
253 if( !file_exists(filename) )
254 {
255 return;
256 }
257
258 new file = fopen(_temp_vault, "wt");
259
260 new vault = fopen(filename, "rt");
261
262 new _data[512], _key[64], _other[3];
263 new bool:found_key;
264
265 while( !feof(vault) )
266 {
267 fgets(vault, _data, sizeof(_data) - 1);
268 parse(_data, _key, sizeof(_key) - 1, _other, sizeof(_other) - 1);
269
270 if( equal(_key, key) )
271 {
272 found_key = true;
273 continue;
274 }
275
276 fputs(file, _data);
277 }
278
279 fclose(file);
280 fclose(vault);
281
282 if( found_key )
283 {
284 delete_file(filename);
285
286 while( !rename_file(_temp_vault, filename, 1) ) { }
287 }
288 else
289 {
290 delete_file(_temp_vault);
291 }
292 }
293
294 /**
295 * Prunes the vault for keys that are within the given timestamps
296 *
297 * @param vaultname Vault name to look in
298 * @param start If timestamp is after this Unix Time (set -1 to prune from very start)
299 * @param end If timestamp is before this Unix Time (set -1 to prune to most time)
300 * @return Returns number of keys pruned
301 */
302 stock fvault_prune(const vaultname[], const start=-1, const end=-1)
303 {
304 if( start == -1 && end == -1 )
305 {
306 new keys = fvault_size(vaultname);
307 if( keys )
308 {
309 fvault_clear(vaultname);
310 }
311
312 return keys;
313 }
314
315 new filename[128];
316 _FormatVaultName(vaultname, filename, sizeof(filename) - 1);
317
318 if( !file_exists(filename) )
319 {
320 return 0;
321 }
322
323 new file = fopen(_temp_vault, "wt");
324 new vault = fopen(filename, "rt");
325
326 new keys;
327
328 new data[512], i, _time[32], timestamp;
329 while( !feof(vault) )
330 {
331 fgets(vault, data, sizeof(data) - 1);
332
333 if( data[0] )
334 {
335 _time[0] = 0;
336
337 for( i = strlen(data) - 1; i >= 0; i-- )
338 {
339 if( data[i] == '"' ) break;
340
341 if( data[i] == ' ' )
342 {
343 copy(_time, sizeof(_time) - 1, data[i + 1]);
344 break;
345 }
346 }
347
348 timestamp = str_to_num(_time);
349 if( timestamp != -1 )
350 {
351 if( start == -1 && timestamp <= end
352 || end == -1 && timestamp >= start
353 || start <= timestamp <= end )
354 {
355 keys++;
356 continue;
357 }
358 }
359 }
360
361 fputs(file, data);
362 }
363
364 fclose(file);
365 fclose(vault);
366
367 if( keys )
368 {
369 delete_file(filename);
370
371 while( !rename_file(_temp_vault, filename, 1) ) { }
372 }
373 else
374 {
375 delete_file(_temp_vault);
376 }
377
378 return keys;
379 }
380
381 /**
382 * Updates the timestamp on a key located within the vault
383 *
384 * @param vaultname Vault name to look in
385 * @param key Key to update timestamp (if it doesn't exist, a blank value will be set)
386 * @param timestamp Unix Time to set for the key (-1 for current time)
387 * @return Returns 2 on new entry, 1 on success, 0 on failure for the key having a permanent timestamp
388 */
389 stock fvault_touch(const vaultname[], const key[], const timestamp=-1)
390 {
391 new filename[128];
392 _FormatVaultName(vaultname, filename, sizeof(filename) - 1);
393
394 static new_time;
395 if( (new_time = timestamp) == -1 )
396 {
397 new_time = get_systime();
398 }
399
400 if( !file_exists(filename) )
401 {
402 new vault = fopen(filename, "wt");
403 fprintf(vault, "^"%s^" ^"^" %i^n", key, new_time);
404 fclose(vault);
405 return 2;
406 }
407
408 new file = fopen(_temp_vault, "wt");
409 new vault = fopen(filename, "rt");
410
411 new bool:updated;
412
413 new data[512], _key[64], len, i, _time[32];
414 while( !feof(vault) )
415 {
416 fgets(vault, data, sizeof(data) - 1);
417 parse(data, _key, sizeof(_key) - 1);
418
419 if( equal(_key, key) )
420 {
421 _time[0] = 0;
422
423 for( i = strlen(data) - 1; i >= 0; i-- )
424 {
425 if( data[i] == '"' ) break;
426
427 if( data[i] == ' ' )
428 {
429 data[i] = '^0';
430 copy(_time, sizeof(_time) - 1, data[i + 1]);
431 break;
432 }
433 }
434
435 if( str_to_num(_time) == -1 )
436 {
437 fclose(file);
438 fclose(vault);
439
440 delete_file(_temp_vault);
441
442 return 0;
443 }
444
445 fprintf(file, "%s %i^n", data, new_time);
446
447 updated = true;
448 }
449 else
450 {
451 fputs(file, data);
452 }
453 }
454
455 if( !updated )
456 {
457 fprintf(file, "^"%s^" ^"^" %i^n", key, new_time);
458 }
459
460 fclose(file);
461 fclose(vault);
462
463 delete_file(filename);
464
465 while( !rename_file(_temp_vault, filename, 1) ) { }
466
467 return (_:(!updated) + 1);
468 }
469
470 /**
471 * Retrieves total keys located within the vault
472 *
473 * @param vaultname Vault name to look in
474 * @return Returns amount of keys in vault
475 */
476 stock fvault_size(const vaultname[])
477 {
478 new filename[128];
479 _FormatVaultName(vaultname, filename, sizeof(filename) - 1);
480
481 return file_exists(filename) ? file_size(filename, 1) - 1 : 0;
482 }
483
484 /**
485 * Clears all key entries for a vault
486 *
487 * @param vaultname Vault name to erase
488 * @return No return
489 */
490 stock fvault_clear(const vaultname[])
491 {
492 new filename[128];
493 _FormatVaultName(vaultname, filename, sizeof(filename) - 1);
494
495 fclose(fopen(filename, "wt"));
496 }
497
498 /**
499 * Retrieves a vault name specified by its number
500 *
501 * @param vaultnum Vault number to find the vault name
502 * @param vaultname String which vault name will be copied to
503 * @param len Length of vault name
504 * @return Returns 1 on success, 0 on failue.
505 */
506 stock fvault_get_vaultname(const vaultnum, vaultname[], len)
507 {
508 if( !dir_exists(_vault_dir) )
509 {
510 mkdir(_vault_dir);
511 return 0;
512 }
513
514 new filenum;
515
516 new dir = open_dir(_vault_dir, vaultname, len);
517
518 do
519 {
520 if( equal(vaultname, ".") || equal(vaultname, "..") )
521 {
522 continue;
523 }
524
525 if( filenum == vaultnum )
526 {
527 close_dir(dir);
528
529 replace(vaultname, len, ".txt", "");
530
531 return 1;
532 }
533
534 ++filenum;
535 }
536 while( next_file(dir, vaultname, len) );
537
538 close_dir(dir);
539
540 copy(vaultname, len, "");
541
542 return 0;
543 }
544
545 /**
546 * Retrieves a vault number specified by its name
547 *
548 * @param vaultname Vault name to find the number
549 * @return Returns vault number on success, -1 on failure
550 */
551 stock fvault_get_vaultnum(const vaultname[])
552 {
553 if( !dir_exists(_vault_dir) )
554 {
555 mkdir(_vault_dir);
556 return -1;
557 }
558
559 new filename[128], filenum;
560
561 new dir = open_dir(_vault_dir, filename, sizeof(filename) - 1);
562
563 do
564 {
565 if( equal(filename, ".") || equal(filename, "..") )
566 {
567 continue;
568 }
569
570 replace(filename, sizeof(filename) - 1, ".txt", "");
571
572 if( equal(filename, vaultname) )
573 {
574 close_dir(dir);
575
576 return filenum;
577 }
578
579 ++filenum;
580 }
581 while( next_file(dir, filename, sizeof(filename) - 1) );
582
583 close_dir(dir);
584
585 copy(vaultname, len, "");
586
587 return -1;
588 }
589
590 /**
591 * Retrieves total vaults ever created
592 *
593 * @return Returns amount of vaults
594 */
595 stock fvault_total()
596 {
597 if( !dir_exists(_vault_dir) )
598 {
599 mkdir(_vault_dir);
600 return 0;
601 }
602
603 new vaultname[128], filename[128];
604 new dir = open_dir(_vault_dir, vaultname, sizeof(vaultname) - 1);
605
606 new filenum;
607 do
608 {
609 if( equal(vaultname, ".") || equal(vaultname, "..") )
610 {
611 continue;
612 }
613
614 formatex(filename, sizeof(filename) - 1, "%s/%s", _vault_dir, vaultname);
615 if( file_exists(filename) )
616 {
617 ++filenum;
618 }
619 }
620 while( next_file(dir, vaultname, sizeof(vaultname) - 1) );
621
622 close_dir(dir);
623
624 return filenum;
625 }
626
627 /**
628 * Gets all vault keys, data, and timestamps
629 *
630 * @param vaultname - Vault name to look in
631 * @param keys - cellarray holding all of the keys
632 * @param datas - cellarray holding all of the data values
633 * @param timestamps - cellarray holding all of the timestamps
634 *
635 * @return Returns total number of entries in vault
636 *
637 * @note keys needs to be created like this: ArrayCreate(64)
638 * datas needs to be created like this: ArrayCreate(512)
639 * timestamps need to be created like this: ArrayCreate()
640 */
641 stock fvault_load(const vaultname[], Array:keys=Invalid_Array, Array:datas=Invalid_Array, Array:timestamps=Invalid_Array)
642 {
643 new filename[128];
644 _FormatVaultName(vaultname, filename, 127);
645
646 if( !file_exists(filename) )
647 {
648 return 0;
649 }
650
651 new vault = fopen(filename, "rt");
652
653 new array_size;
654
655 new filedata[1024];
656 new key[64], data[512], timestamp[32];
657 while( !feof(vault) )
658 {
659 fgets(vault, filedata, 1023);
660
661 if( parse(filedata, key, 63, data, 511, timestamp, 31) < 2 )
662 {
663 continue;
664 }
665
666 if( keys != Invalid_Array )
667 {
668 ArrayPushString(keys, key);
669 }
670 if( datas != Invalid_Array )
671 {
672 ArrayPushString(datas, data);
673 }
674 if( timestamps != Invalid_Array )
675 {
676 ArrayPushCell(timestamps, str_to_num(timestamp));
677 }
678
679 array_size++;
680 }
681
682 fclose(vault);
683
684 return array_size;
685 }
686
687 stock _FormatVaultName(const vaultname[], filename[], len)
688 {
689 static const invalid_chars[][] =
690 {
691 "/", "\", "*", ":", "?", "^"", "<", ">", "|"
692 };
693
694 static tempvault[128], i;
695 copy(tempvault, sizeof(tempvault) - 1, vaultname);
696
697 for( i = 0; i < sizeof(invalid_chars); i++ )
698 {
699 replace_all(tempvault, sizeof(tempvault) - 1, invalid_chars[i], "");
700 }
701
702 if( !dir_exists(_vault_dir) )
703 {
704 mkdir(_vault_dir);
705 }
706
707 formatex(filename, len, "%s/%s.txt", _vault_dir, tempvault);
708 }
709 /* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
710 *{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1033\\ f0\\ fs16 \n\\ par }
711 */
712