diff options
author | Happy <markaizer@gmail.com> | 2014-08-21 04:50:46 +0800 |
---|---|---|
committer | Happy <markaizer@gmail.com> | 2014-08-21 04:50:46 +0800 |
commit | f52e1007fe08c67003c0bc4c78231904dd3fd5cc (patch) | |
tree | 99907d827264e501774e58ab4630e41fa7103c02 /src/common/utils.c | |
parent | 2410110dece79b4598c12f1c953219f1d0d1904a (diff) | |
parent | 769b1d05aa5cfa8cddfe7d21b35d5c5e4da3bbd6 (diff) | |
download | hercules-f52e1007fe08c67003c0bc4c78231904dd3fd5cc.tar.gz hercules-f52e1007fe08c67003c0bc4c78231904dd3fd5cc.tar.bz2 hercules-f52e1007fe08c67003c0bc4c78231904dd3fd5cc.tar.xz hercules-f52e1007fe08c67003c0bc4c78231904dd3fd5cc.zip |
Merge pull request #1 from HerculesWS/master
Update from original
Diffstat (limited to 'src/common/utils.c')
-rw-r--r-- | src/common/utils.c | 224 |
1 files changed, 195 insertions, 29 deletions
diff --git a/src/common/utils.c b/src/common/utils.c index 296df7e70..79232b25c 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -1,30 +1,37 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams + +#define HERCULES_CORE -#include "../common/cbasetypes.h" -#include "../common/mmo.h" -#include "../common/malloc.h" -#include "../common/showmsg.h" -#include "socket.h" #include "utils.h" -#include <stdio.h> +#include <math.h> // floor() #include <stdarg.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> -#include <math.h> // floor() +#include <sys/stat.h> // cache purposes [Ind/Hercules] + +#include "../common/cbasetypes.h" +#include "../common/core.h" +#include "../common/malloc.h" +#include "../common/mmo.h" +#include "../common/showmsg.h" +#include "../common/socket.h" #ifdef WIN32 - #include "../common/winapi.h" - #ifndef F_OK - #define F_OK 0x0 - #endif /* F_OK */ +# include "../common/winapi.h" +# ifndef F_OK +# define F_OK 0x0 +# endif /* F_OK */ #else - #include <unistd.h> - #include <dirent.h> - #include <sys/stat.h> +# include <dirent.h> +# include <sys/stat.h> +# include <unistd.h> #endif +struct HCache_interface HCache_s; /// Dumps given buffer into file pointed to by a handle. void WriteDump(FILE* fp, const void* buffer, size_t length) @@ -57,31 +64,27 @@ void WriteDump(FILE* fp, const void* buffer, size_t length) /// Dumps given buffer on the console. -void ShowDump(const void* buffer, size_t length) -{ +void ShowDump(const void *buffer, size_t length) { size_t i; char hex[48+1], ascii[16+1]; ShowDebug("--- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F 0123456789ABCDEF\n"); ascii[16] = 0; - for( i = 0; i < length; i++ ) - { + for (i = 0; i < length; i++) { char c = RBUFB(buffer,i); ascii[i%16] = ISCNTRL(c) ? '.' : c; sprintf(hex+(i%16)*3, "%02X ", RBUFB(buffer,i)); - if( (i%16) == 15 ) - { - ShowDebug("%03X %s %s\n", i/16, hex, ascii); + if ((i%16) == 15) { + ShowDebug("%03"PRIXS" %s %s\n", i/16, hex, ascii); } } - if( (i%16) != 0 ) - { + if ((i%16) != 0) { ascii[i%16] = 0; - ShowDebug("%03X %-48s %-16s\n", i/16, hex, ascii); + ShowDebug("%03"PRIXS" %-48s %-16s\n", i/16, hex, ascii); } } @@ -193,7 +196,7 @@ void findfile(const char *p, const char *pat, void (func)(const char*)) sprintf(tmppath,"%s%c%s",path, PATHSEP, entry->d_name); - // check if the pattern matchs. + // check if the pattern matches. if (entry->d_name && strstr(entry->d_name, pattern)) { func( tmppath ); } @@ -204,7 +207,7 @@ void findfile(const char *p, const char *pat, void (func)(const char*)) } // is this a directory? if (S_ISDIR(dir_stat.st_mode)) { - // decent recursivly + // decent recursively findfile(tmppath, pat, func); } }//end while @@ -259,6 +262,58 @@ uint32 MakeDWord(uint16 word0, uint16 word1) ( (uint32)(word1 << 0x10) ); } +/************************************* +* Big-endian compatibility functions * +*************************************/ + +// Converts an int16 from current machine order to little-endian +int16 MakeShortLE(int16 val) +{ + unsigned char buf[2]; + buf[0] = (unsigned char)( (val & 0x00FF) ); + buf[1] = (unsigned char)( (val & 0xFF00) >> 0x08 ); + return *((int16*)buf); +} + +// Converts an int32 from current machine order to little-endian +int32 MakeLongLE(int32 val) +{ + unsigned char buf[4]; + buf[0] = (unsigned char)( (val & 0x000000FF) ); + buf[1] = (unsigned char)( (val & 0x0000FF00) >> 0x08 ); + buf[2] = (unsigned char)( (val & 0x00FF0000) >> 0x10 ); + buf[3] = (unsigned char)( (val & 0xFF000000) >> 0x18 ); + return *((int32*)buf); +} + +// Reads an uint16 in little-endian from the buffer +uint16 GetUShort(const unsigned char* buf) +{ + return ( ((uint16)(buf[0])) ) + |( ((uint16)(buf[1])) << 0x08 ); +} + +// Reads an uint32 in little-endian from the buffer +uint32 GetULong(const unsigned char* buf) +{ + return ( ((uint32)(buf[0])) ) + |( ((uint32)(buf[1])) << 0x08 ) + |( ((uint32)(buf[2])) << 0x10 ) + |( ((uint32)(buf[3])) << 0x18 ); +} + +// Reads an int32 in little-endian from the buffer +int32 GetLong(const unsigned char* buf) +{ + return (int32)GetULong(buf); +} + +// Reads a float (32 bits) from the buffer +float GetFloat(const unsigned char* buf) +{ + uint32 val = GetULong(buf); + return *((float*)(void*)&val); +} /// calculates the value of A / B, in percent (rounded down) unsigned int get_percentage(const unsigned int A, const unsigned int B) @@ -267,7 +322,7 @@ unsigned int get_percentage(const unsigned int A, const unsigned int B) if( B == 0 ) { - ShowError("get_percentage(): divison by zero! (A=%u,B=%u)\n", A, B); + ShowError("get_percentage(): division by zero! (A=%u,B=%u)\n", A, B); return ~0U; } @@ -281,3 +336,114 @@ unsigned int get_percentage(const unsigned int A, const unsigned int B) return (unsigned int)floor(result); } + +//----------------------------------------------------- +// custom timestamp formatting (from eApp) +//----------------------------------------------------- +const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format) +{ + size_t len = strftime(str, size, format, localtime(×tamp)); + memset(str + len, '\0', size - len); + return str; +} + + +/* [Ind/Hercules] Caching */ +bool HCache_check(const char *file) { + struct stat bufa, bufb; + FILE *first, *second; + char s_path[255], dT[1]; + time_t rtime; + + if( !(first = fopen(file,"rb")) ) + return false; + + if( file[0] == '.' && file[1] == '/' ) + file += 2; + else if( file[0] == '.' ) + file++; + + snprintf(s_path, 255, "./cache/%s", file); + + if( !(second = fopen(s_path,"rb")) ) { + fclose(first); + return false; + } + + if( fread(dT,sizeof(dT),1,second) != 1 || fread(&rtime,sizeof(rtime),1,second) != 1 || dT[0] != HCACHE_KEY || HCache->recompile_time > rtime ) { + fclose(first); + fclose(second); + return false; + } + + fstat(fileno(first), &bufa); + fstat(fileno(second), &bufb); + + fclose(first); + fclose(second); + + if( bufa.st_mtime > bufb.st_mtime ) + return false; + + return true; +} + +FILE *HCache_open(const char *file, const char *opt) { + FILE *first; + char s_path[255]; + + if( file[0] == '.' && file[1] == '/' ) + file += 2; + else if( file[0] == '.' ) + file++; + + snprintf(s_path, 255, "./cache/%s", file); + + if( !(first = fopen(s_path,opt)) ) { + return NULL; + } + + if( opt[0] != 'r' ) { + char dT[1];/* 1-byte key to ensure our method is the latest, we can modify to ensure the method matches */ + dT[0] = HCACHE_KEY; + hwrite(dT,sizeof(dT),1,first); + hwrite(&HCache->recompile_time,sizeof(HCache->recompile_time),1,first); + } + fseek(first, 20, SEEK_SET);/* skip first 20, might wanna store something else later */ + + return first; +} +void HCache_init(void) { + FILE *server; + + if( (server = fopen(SERVER_NAME,"rb")) ) { + struct stat buf; + + fstat(fileno(server), &buf); + HCache->recompile_time = buf.st_mtime; + fclose(server); + + HCache->enabled = true; + } else + ShowWarning("Unable to open '%s', caching capabilities have been disabled!\n",SERVER_NAME); +} +/* transit to fread, shields vs warn_unused_result */ +size_t hread(void * ptr, size_t size, size_t count, FILE * stream) { + return fread(ptr, size, count, stream); +} +/* transit to fwrite, shields vs warn_unused_result */ +size_t hwrite(const void * ptr, size_t size, size_t count, FILE * stream) { + return fwrite(ptr, size, count, stream); +} + +void HCache_defaults(void) { + + HCache = &HCache_s; + + HCache->init = HCache_init; + + HCache->check = HCache_check; + HCache->open = HCache_open; + HCache->recompile_time = 0; + HCache->enabled = false; +} |