#include "stdafx.h" #include "DBLayer.h" #include "Logger.h" // limits //sqlite> select max(id) from items: 20062 //sqlite> select max(id) from skills: 26073 //sqlite> select max(id) from mobs: 36599 const unsigned int dbl_max_npc_id = 40000; const unsigned int dbl_max_skill_id = 27000; const unsigned int dbl_max_item_id = 25000; TCHAR **dbl_npc_names = NULL; TCHAR **dbl_npc_titles = NULL; TCHAR **dbl_skill_names = NULL; TCHAR **dbl_item_names = NULL; int dbl_cache_hits = 0; int dbl_cache_misses = 0; int dbl_npcs_cached = 0; int dbl_skills_cached = 0; int dbl_items_cached = 0; void DBLayer_init() { log_error( LOG_DEBUG, "DB Layer: init database...\n" ); // char errmsg[256] = {0}; bool open_ok = L2Data_DB_Init( errmsg, ".\\data\\L2Detect_items.sqlite3db", ".\\data\\L2Detect_mobs.sqlite3db", ".\\data\\L2Detect_skills.sqlite3db" ); if( errmsg[0] ) { log_error( LOG_ERROR, "L2Data_DB_Init(): says: %s\n", errmsg ); MessageBoxA( NULL, errmsg, "L2Data_DB_Init():", MB_ICONWARNING ); } if( !open_ok ) { log_error( LOG_ERROR, "DB Layer: database open error!\n" ); return; } // log_error( LOG_OK, "DB Layer: database opened\n" ); // dbl_cache_hits = 0; dbl_cache_misses = 0; dbl_npcs_cached = 0; dbl_skills_cached = 0; dbl_items_cached = 0; // allocate mem // NULL dbl_npc_names = NULL; dbl_npc_titles = NULL; dbl_skill_names = NULL; dbl_item_names = NULL; // malloc npc names dbl_npc_names = (TCHAR **)malloc( sizeof(TCHAR *) * dbl_max_npc_id ); if( !dbl_npc_names ) { log_error( LOG_ERROR, "DB Layer: cannot allocate mem (1)\n" ); return; } // malloc npc titles dbl_npc_titles = (TCHAR **)malloc( sizeof(TCHAR *) * dbl_max_npc_id ); if( !dbl_npc_titles ) { free( dbl_npc_names ); dbl_npc_names = NULL; log_error( LOG_ERROR, "DB Layer: cannot allocate mem (2)\n" ); return; } // malloc skill names dbl_skill_names = (TCHAR **)malloc( sizeof(TCHAR *) * dbl_max_skill_id ); if( !dbl_skill_names ) { free( dbl_npc_names ); free( dbl_npc_titles ); dbl_npc_names = NULL; dbl_npc_titles = NULL; log_error( LOG_ERROR, "DB Layer: cannot allocate mem (3)\n" ); return; } // malloc item names dbl_item_names = (TCHAR **)malloc( sizeof(TCHAR *) * dbl_max_item_id ); if( !dbl_item_names ) { free( dbl_npc_names ); free( dbl_npc_titles ); free( dbl_skill_names ); dbl_npc_names = NULL; dbl_npc_titles = NULL; dbl_skill_names = NULL; log_error( LOG_ERROR, "DB Layer: cannot allocate mem (4)\n" ); return; } // log_error( LOG_DEBUG, "DB cache created\n" ); int i; for( i=0; i= dbl_max_item_id ) { log_error( LOG_ERROR, "DBLayer_getItemName(): item ID %u is above max limit %u\n", itemID, dbl_max_item_id ); return; } if( dbl_item_names ) { // check cache if( dbl_item_names[itemID] ) { // found in cache _tcsncpy( out, dbl_item_names[itemID], maxCount ); out[maxCount-1] = 0; dbl_cache_hits++; return; } // not in cache :( request DB char aname[256] = {0}; if( L2Data_DB_GetItemNamePicByID( itemID, aname, NULL ) ) { dbl_cache_misses++; dbl_items_cached++; #if defined(UNICODE) || defined(_UNICODE) dbl_item_names[itemID] = ansi_to_unicode_dup( aname ); #else dbl_item_names[itemID] = _strdup( aname ); #endif _tcsncpy( out, dbl_item_names[itemID], maxCount ); out[maxCount-1] = 0; } else log_error( LOG_ERROR, "DB: item %u not in DB!\n", itemID ); } else log_error( LOG_ERROR, "DB Layer: no mem allocated for item names, DB init error?\n" ); } void DBLayer_getSkillName( unsigned int skillID, TCHAR *out, size_t maxCount ) { if( skillID >= dbl_max_skill_id ) { log_error( LOG_ERROR, "DBLayer_getSkillName(): skill ID %u is above max limit %u\n", skillID, dbl_max_skill_id ); return; } if( dbl_skill_names ) { // check cache if( dbl_skill_names[skillID] ) { // found in cache _tcsncpy( out, dbl_skill_names[skillID], maxCount ); out[maxCount-1] = 0; dbl_cache_hits++; return; } // not in cache :( request DB char aname[256] = {0}; if( L2Data_DB_GetSkillNameByID( skillID, aname ) ) { dbl_cache_misses++; dbl_skills_cached++; #if defined(UNICODE) || defined(_UNICODE) dbl_skill_names[skillID] = ansi_to_unicode_dup( aname ); #else dbl_skill_names[skillID] = _strdup( aname ); #endif _tcsncpy( out, dbl_skill_names[skillID], maxCount ); out[maxCount-1] = 0; } else log_error( LOG_ERROR, "DB: skill %u not in DB!\n", skillID ); } else log_error( LOG_ERROR, "DB Layer: no mem allocated for skill names, DB init error?\n" ); } void DBLayer_getNpcNameTitle( unsigned int npcID, TCHAR *npcName, size_t npcNameMaxCount, TCHAR *npcTitle, size_t npcTitleMaxCount ) { if( npcID >= dbl_max_npc_id ) { log_error( LOG_ERROR, "DBLayer_getNpcNameTitle(): npc ID %u is above max limit %u\n", npcID, dbl_max_npc_id ); return; } if( dbl_npc_names && dbl_npc_titles ) { // check cache if( dbl_npc_names[npcID] ) { // found in cache _tcsncpy( npcName, dbl_npc_names[npcID], npcNameMaxCount ); npcName[npcNameMaxCount-1] = 0; npcTitle[0] = 0; // npc title can be NULL if( dbl_npc_titles[npcID] ) { _tcsncpy( npcTitle, dbl_npc_titles[npcID], npcTitleMaxCount ); npcTitle[npcTitleMaxCount-1] = 0; } dbl_cache_hits++; return; } // not in cache :( request DB char aname[256] = {0}; char atitle[256] = {0}; if( L2Data_DB_GetNPCNameTitleByID( npcID, aname, atitle ) ) { dbl_cache_misses++; dbl_npcs_cached++; #if defined(UNICODE) || defined(_UNICODE) dbl_npc_names[npcID] = ansi_to_unicode_dup( aname ); if( atitle[0] ) dbl_npc_titles[npcID] = ansi_to_unicode_dup( atitle ); #else dbl_npc_names[npcID] = _strdup( aname ); if( atitle[0] ) dbl_npc_titles[npcID] = _strdup( atitle ); #endif // out _tcsncpy( npcName, dbl_npc_names[npcID], npcNameMaxCount ); npcName[npcNameMaxCount-1] = 0; npcTitle[0] = 0; // npc title can be NULL if( dbl_npc_titles[npcID] ) { _tcsncpy( npcTitle, dbl_npc_titles[npcID], npcTitleMaxCount ); npcTitle[npcTitleMaxCount-1] = 0; } } else log_error( LOG_ERROR, "DB: NPC %u not in DB!\n", npcID ); } else log_error( LOG_ERROR, "DB Layer: no mem allocated for " "NPC names & titles, DB init error?\n" ); } void DBLayer_printStats() { log_error_np( LOG_OK, "[DB] ===== Stats info: ======\n" ); log_error_np( LOG_OK, "[DB] cached (NPCs, Skills, Items) : %d, %d, %d\n", dbl_npcs_cached, dbl_skills_cached, dbl_items_cached ); log_error_np( LOG_OK, "[DB] Cache: MISS / HIT : %d / %d\n", dbl_cache_misses, dbl_cache_hits ); log_error_np( LOG_OK, "[DB] ===== Stats info end =====\n" ); }