diff --git a/CMakeLists.txt b/CMakeLists.txt index 42ff0db93..455b59f22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -327,7 +327,7 @@ IF(EQEMU_BUILD_LUA) ENDIF(EQEMU_SANITIZE_LUA_LIBS) ENDIF(EQEMU_BUILD_LUA) -INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${MySQL_INCLUDE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/common/glm/glm" "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libwebsockets" "${CMAKE_CURRENT_SOURCE_DIR}/common/rapidjson") +INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${MySQL_INCLUDE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/common/glm" "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/libwebsockets" "${CMAKE_CURRENT_SOURCE_DIR}/common/rapidjson") IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS) ADD_SUBDIRECTORY(common) diff --git a/changelog.txt b/changelog.txt index 5aa90cfc9..d5312dd4e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,142 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- + +== 02/02/2015 == +Akkadius: Implement Packet logs with dumps + - Category: 41: Packet: Server -> Client With Dump + - Category: 42: Packet: Server -> Client With Dump + See: http://wiki.eqemulator.org/p?Logging_System_Overhaul#packet-logging-levels + +== 02/01/2015 == +demonstar55: Add quest debugging to lua + eq.debug("Test debug level implicit 1") + eq.debug("Test debug level explicit 1", 1) + eq.debug("Test debug level explicit 2", 2) + eq.debug("Test debug level explicit 3", 3) +Akkadius: Add Packet Logging Categories + - 5 - Packet: Client -> Server - Logs::Client_Server_Packet + - 39 - Packet: Server -> Client - Logs::Server_Client_Packet + - 40 - Packet: Client -> Server Unhandled - Logs::Client_Server_Packet_Unhandled + See: http://wiki.eqemulator.org/p?Logging_System_Overhaul#packet-logging + +== 01/31/2015 == +Trevius: Fixed FindGroundZ() and GetGroundZ() to once again utilize the X and Y arguments that are passed to them. + +== 01/30/2015 == +Akkadius: Implemented event type "EVENT_ENVIRONMENTAL_DAMAGE" + - This event triggers when taking any sort of environmental damage. Example use: + sub EVENT_ENVIRONMENTAL_DAMAGE{ + quest::debug("EVENT_ENVIRONMENTAL_DAMAGE"); + quest::debug("env_damage is " . $env_damage); + quest::debug("env_damage_type is " . $env_damage_type); + quest::debug("env_final_damage is " . $env_final_damage); + } + Result: (Test falling in Velks): http://i.imgur.com/tPRL7yL.png + - Implemented LUA counterpart of this same implementation above +Akkadius (Bobaski): Add PoK New Merchant sql/git/optional/2015_01_30_poknowledge_spell_vendors.sql + +== 01/29/2015 == +Trevius: Added more information to Mercenary Logging. +Trevius: Added potential fix for Mercenaries that fail to unsuspend. +Trevius: Added a new "statscale" field to the merc_stats table that can be used to quickly balance Mercenary Stats based on Level. +Trevius: The new "statscale" field now combines with the Mercs::ScaleRate rule value (default 100 percent for both). + +== 01/28/2015 == +Akkadius: Added Logs::DebugQuest category per request from Trevius (Great idea) + - Exported quest::debug(log_message, [debug_level = 1) + - Example: + quest::debug("This is a test debug message, level 1 (default)"); + quest::debug("This is a test debug message, level 1", 1); + quest::debug("This is a test debug message, level 2", 2); + quest::debug("This is a test debug message, level 3", 3); + + Result: http://i.imgur.com/6VoafGE.png + - Uses traditional logging system to output this category + - Required MySQL Source in Database version 9070 + +== 01/27/2015 == +Trevius: Removed "Mercenary Debug:" from the Mercenary Log entries. +Trevius: Resolved duplicate "You have no Mercenaries" messages when zoning without owning a Mercenary. +Trevius: Mercenaries should now always be able to unsuspend if the timer is up. +Trevius: More work on Mercenaries and Grouping to reduce bugs and redundant queries. +Uleat: Finished ClientVersion update to include patch file and namespace updates - don't forget to copy the renamed 'patch_UF.conf' into your eqemu directory.) + +== 01/26/2015 == +Uleat: Changed Corpse::MoveItemToCorpse() to allow 'by address' passing of removed item slot list. Fixed a bug that kept soul-bound items inside of bags from attuning properly + +== 01/25/2015 == +Trevius: Fixed an issue where Mercenaries were causing several DB queries per second while suspended. +Trevius: Added Logs::Mercenaries to the new Logging System. Logging of Mercenary information is off by default with the required SQL. + +== 01/24/2015 == +Uleat: Added equipment light source functionality to all mob derived classes (may still need tweaking...) +Notes: + - In addition to equipment light sources, innate npc_type light sources have already been activated + - Valid light source values are 0 thru 15 (values are bitmask checked and limited to 0x0F) + - Not all classes handle equipment light sources the same way due to their equipment/loot list configurations + - Spell (casting?) light sources may be implemented at some point..more information is needed + - Currently, loot list (general inventory) light sources are limited to ItemTypeMisc and ItemTypeLight to avoid issues with worn-specific light sources emitting + - Augment light sources are not recognized by the client and, therefore, not implemented in the server code + +== 01/22/2015 == +Akkadius: Massive Log System overhaul, see: http://wiki.eqemulator.org/p?Logging_System_Overhaul&frm=Main + +== 01/21/2015 == +Uleat: Added `light` field to npc_types load query (all six clients tested positive for functionality.) +Note: This only affects 'innate' light. Equipment (other) light is still in-work. +Optional SQL: utils/sql/git/optional/2015_01_21_NPC_Types_Light_Field_Primer.sql + +== 01/20/2015 == +Uleat: Fix for Inventory::_HasItemByUse(bucket) using the parent container when searching for bag container items. + +== 01/19/2015 == +Uleat: Changed 'enum EQClientVersion' to 'enum class ClientVersion.' Other light modifications were made to accommodate this namespace. Added 'RoF2' to the lua client version enumeration. + +== 01/15/2015 == +Uleat: Attempted fix for elusive inventory bug: + - Removed 'iter_queue' typedef and converted lcast to explicit or auto defines + - Reworked several functions that manipulate the cursor queue + - Found/corrected one occurrence of post-processing iterator incrementing in an ItemInstQueue handler + - Added many scope declarations in code that handles inventory manipulation (loose macros are bad...) +Uleat: Added Item_Struct pointer checks to ItemInst methods that did not have them +Uleat: Changed IsEquippable(race,class) to use bit-wise 'and' (&) over '(x%2)==1' in conditional check. +Uleat: Changed DyeArmor() assignment of 'armor_color' to use bit-wise 'or' and bit-shifting (|,<<) over multiplication and addition (*,+). + +== 01/13/2015 == +Uleat: Placed an upper limit on the cursor queue save loop. +Trevius: (RoF2) Guild invites now add new members as members instead of recruits, and /guild chat works properly. +Trevius: (RoF2) Guild Promote is now functional. + +== 01/12/2015 == +Uleat: Fix for OP_FormattedMessage text link server crashes +Uleat: Added text link translators for OP_TaskDescription (RoF+ -- all clients current) +Uleat: Fix for load_bots.sql using '\\' as a delimiter (Changed to '$$') + +== 01/11/2015 == +Uleat: Added text link translators for OP_TaskDescription (Ti thru UF..RoF+ in-work) + +== 01/10/2015 == +Uleat: Added text link translators for OP_Emote + +== 01/09/2015 == +Uleat: Added text link translators for OP_FormattedMessage + +== 01/08/2015 == +Trevius: Added some extra checks and clean-up related to Groups and Mercenaries. + +== 01/07/2015 == +Uleat: Excluded text link body from message scrambling in Client::GarbleMessage() +Trevius: Mercenaries now load directly from tables only. The vwMercNpcTypes view is no longer required and can be deleted. +Trevius: Query fix for group_leaders table. This may resolve some crashes/bugs related to Mercs/Bots and Groups. + +== 01/06/2015 == +Trevius: Changed the pet command #defines to be based on RoF2 list of pet commands and added decodes to Titanium, SoF and SoD. +Trevius: (RoF+) The /pet focus on/off and /pet hold on/off commands are now functional. +Trevius: Added defines for all remaining pet commands and some support for them as well. + +== 01/05/2015 == +Uleat: Fixed (added translators for) item/text links. Only 'OP_ChannelMessage' and 'OP_SpecialMesg' are currently handled..more text channels will be added as the need arises. + == 01/03/2015 == Trevius: (RoF2) /shield (shielding) and /key (key ring) are both now functional after opcode updates. diff --git a/client_files/export/main.cpp b/client_files/export/main.cpp index e9b127aad..865fbd6d8 100644 --- a/client_files/export/main.cpp +++ b/client_files/export/main.cpp @@ -17,7 +17,9 @@ */ #include -#include "../../common/debug.h" + +#include "../../common/eqemu_logsys.h" +#include "../../common/global_define.h" #include "../../common/shareddb.h" #include "../../common/eqemu_config.h" #include "../../common/platform.h" @@ -25,47 +27,53 @@ #include "../../common/rulesys.h" #include "../../common/string_util.h" +EQEmuLogSys Log; + void ExportSpells(SharedDatabase *db); void ExportSkillCaps(SharedDatabase *db); void ExportBaseData(SharedDatabase *db); int main(int argc, char **argv) { RegisterExecutablePlatform(ExePlatformClientExport); + Log.LoadLogSettingsDefaults(); set_exception_handler(); - LogFile->write(EQEMuLog::Status, "Client Files Export Utility"); + Log.Out(Logs::General, Logs::Status, "Client Files Export Utility"); if(!EQEmuConfig::LoadConfig()) { - LogFile->write(EQEMuLog::Error, "Unable to load configuration file."); + Log.Out(Logs::General, Logs::Error, "Unable to load configuration file."); return 1; } const EQEmuConfig *config = EQEmuConfig::get(); - if(!load_log_settings(config->LogSettingsFile.c_str())) { - LogFile->write(EQEMuLog::Error, "Warning: unable to read %s.", config->LogSettingsFile.c_str()); - } SharedDatabase database; - LogFile->write(EQEMuLog::Status, "Connecting to database..."); + Log.Out(Logs::General, Logs::Status, "Connecting to database..."); if(!database.Connect(config->DatabaseHost.c_str(), config->DatabaseUsername.c_str(), config->DatabasePassword.c_str(), config->DatabaseDB.c_str(), config->DatabasePort)) { - LogFile->write(EQEMuLog::Error, "Unable to connect to the database, cannot continue without a " + Log.Out(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a " "database connection"); return 1; } + /* Register Log System and Settings */ + database.LoadLogSettings(Log.log_settings); + Log.StartFileLogs(); + ExportSpells(&database); ExportSkillCaps(&database); ExportBaseData(&database); + Log.CloseFileLogs(); + return 0; } void ExportSpells(SharedDatabase *db) { - LogFile->write(EQEMuLog::Status, "Exporting Spells..."); + Log.Out(Logs::General, Logs::Status, "Exporting Spells..."); FILE *f = fopen("export/spells_us.txt", "w"); if(!f) { - LogFile->write(EQEMuLog::Error, "Unable to open export/spells_us.txt to write, skipping."); + Log.Out(Logs::General, Logs::Error, "Unable to open export/spells_us.txt to write, skipping."); return; } @@ -89,7 +97,6 @@ void ExportSpells(SharedDatabase *db) { fprintf(f, "%s\n", line.c_str()); } } else { - LogFile->write(EQEMuLog::Error, "Error in ExportSpells query '%s' %s", query.c_str(), results.ErrorMessage().c_str()); } fclose(f); @@ -103,7 +110,6 @@ bool SkillUsable(SharedDatabase *db, int skill_id, int class_id) { class_id, skill_id); auto results = db->QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in skill_usable query '%s' %s", query.c_str(), results.ErrorMessage().c_str()); return false; } @@ -123,7 +129,6 @@ int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level) { class_id, skill_id, level); auto results = db->QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in get_skill query '%s' %s", query.c_str(), results.ErrorMessage().c_str()); return 0; } @@ -135,11 +140,11 @@ int GetSkill(SharedDatabase *db, int skill_id, int class_id, int level) { } void ExportSkillCaps(SharedDatabase *db) { - LogFile->write(EQEMuLog::Status, "Exporting Skill Caps..."); + Log.Out(Logs::General, Logs::Status, "Exporting Skill Caps..."); FILE *f = fopen("export/SkillCaps.txt", "w"); if(!f) { - LogFile->write(EQEMuLog::Error, "Unable to open export/SkillCaps.txt to write, skipping."); + Log.Out(Logs::General, Logs::Error, "Unable to open export/SkillCaps.txt to write, skipping."); return; } @@ -164,11 +169,11 @@ void ExportSkillCaps(SharedDatabase *db) { } void ExportBaseData(SharedDatabase *db) { - LogFile->write(EQEMuLog::Status, "Exporting Base Data..."); + Log.Out(Logs::General, Logs::Status, "Exporting Base Data..."); FILE *f = fopen("export/BaseData.txt", "w"); if(!f) { - LogFile->write(EQEMuLog::Error, "Unable to open export/BaseData.txt to write, skipping."); + Log.Out(Logs::General, Logs::Error, "Unable to open export/BaseData.txt to write, skipping."); return; } @@ -190,7 +195,6 @@ void ExportBaseData(SharedDatabase *db) { fprintf(f, "%s\n", line.c_str()); } } else { - LogFile->write(EQEMuLog::Error, "Error in ExportBaseData query '%s' %s", query.c_str(), results.ErrorMessage().c_str()); } fclose(f); diff --git a/client_files/import/main.cpp b/client_files/import/main.cpp index 9683e3bfe..a8477f77a 100644 --- a/client_files/import/main.cpp +++ b/client_files/import/main.cpp @@ -16,7 +16,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "../../common/debug.h" +#include "../../common/eqemu_logsys.h" +#include "../../common/global_define.h" #include "../../common/shareddb.h" #include "../../common/eqemu_config.h" #include "../../common/platform.h" @@ -24,38 +25,43 @@ #include "../../common/rulesys.h" #include "../../common/string_util.h" +EQEmuLogSys Log; + void ImportSpells(SharedDatabase *db); void ImportSkillCaps(SharedDatabase *db); void ImportBaseData(SharedDatabase *db); int main(int argc, char **argv) { RegisterExecutablePlatform(ExePlatformClientImport); + Log.LoadLogSettingsDefaults(); set_exception_handler(); - LogFile->write(EQEMuLog::Status, "Client Files Import Utility"); + Log.Out(Logs::General, Logs::Status, "Client Files Import Utility"); if(!EQEmuConfig::LoadConfig()) { - LogFile->write(EQEMuLog::Error, "Unable to load configuration file."); + Log.Out(Logs::General, Logs::Error, "Unable to load configuration file."); return 1; } const EQEmuConfig *config = EQEmuConfig::get(); - if(!load_log_settings(config->LogSettingsFile.c_str())) { - LogFile->write(EQEMuLog::Error, "Warning: unable to read %s.", config->LogSettingsFile.c_str()); - } SharedDatabase database; - LogFile->write(EQEMuLog::Status, "Connecting to database..."); + Log.Out(Logs::General, Logs::Status, "Connecting to database..."); if(!database.Connect(config->DatabaseHost.c_str(), config->DatabaseUsername.c_str(), config->DatabasePassword.c_str(), config->DatabaseDB.c_str(), config->DatabasePort)) { - LogFile->write(EQEMuLog::Error, "Unable to connect to the database, cannot continue without a " + Log.Out(Logs::General, Logs::Error, "Unable to connect to the database, cannot continue without a " "database connection"); return 1; } + database.LoadLogSettings(Log.log_settings); + Log.StartFileLogs(); + ImportSpells(&database); ImportSkillCaps(&database); ImportBaseData(&database); + Log.CloseFileLogs(); + return 0; } @@ -64,7 +70,6 @@ int GetSpellColumns(SharedDatabase *db) { const std::string query = "DESCRIBE spells_new"; auto results = db->QueryDatabase(query); if(!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetSpellColumns query '%s' %s", query.c_str(), results.ErrorMessage().c_str()); return 0; } @@ -72,10 +77,10 @@ int GetSpellColumns(SharedDatabase *db) { } void ImportSpells(SharedDatabase *db) { - LogFile->write(EQEMuLog::Status, "Importing Spells..."); + Log.Out(Logs::General, Logs::Status, "Importing Spells..."); FILE *f = fopen("import/spells_us.txt", "r"); if(!f) { - LogFile->write(EQEMuLog::Error, "Unable to open import/spells_us.txt to read, skipping."); + Log.Out(Logs::General, Logs::Error, "Unable to open import/spells_us.txt to read, skipping."); return; } @@ -138,23 +143,23 @@ void ImportSpells(SharedDatabase *db) { spells_imported++; if(spells_imported % 1000 == 0) { - LogFile->write(EQEMuLog::Status, "%d spells imported.", spells_imported); + Log.Out(Logs::General, Logs::Status, "%d spells imported.", spells_imported); } } if(spells_imported % 1000 != 0) { - LogFile->write(EQEMuLog::Status, "%d spells imported.", spells_imported); + Log.Out(Logs::General, Logs::Status, "%d spells imported.", spells_imported); } fclose(f); } void ImportSkillCaps(SharedDatabase *db) { - LogFile->write(EQEMuLog::Status, "Importing Skill Caps..."); + Log.Out(Logs::General, Logs::Status, "Importing Skill Caps..."); FILE *f = fopen("import/SkillCaps.txt", "r"); if(!f) { - LogFile->write(EQEMuLog::Error, "Unable to open import/SkillCaps.txt to read, skipping."); + Log.Out(Logs::General, Logs::Error, "Unable to open import/SkillCaps.txt to read, skipping."); return; } @@ -186,11 +191,11 @@ void ImportSkillCaps(SharedDatabase *db) { } void ImportBaseData(SharedDatabase *db) { - LogFile->write(EQEMuLog::Status, "Importing Base Data..."); + Log.Out(Logs::General, Logs::Status, "Importing Base Data..."); FILE *f = fopen("import/BaseData.txt", "r"); if(!f) { - LogFile->write(EQEMuLog::Error, "Unable to open import/BaseData.txt to read, skipping."); + Log.Out(Logs::General, Logs::Error, "Unable to open import/BaseData.txt to read, skipping."); return; } diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 7573f7d32..21effae1e 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -8,8 +8,9 @@ SET(common_sources crc16.cpp crc32.cpp database.cpp + database_conversions.cpp + database_instances.cpp dbcore.cpp - debug.cpp emu_opcodes.cpp emu_tcp_connection.cpp emu_tcp_server.cpp @@ -18,7 +19,7 @@ SET(common_sources eqdb_res.cpp eqemu_exception.cpp eqemu_config.cpp - eqemu_error.cpp + eqemu_logsys.cpp eq_packet.cpp eq_stream.cpp eq_stream_factory.cpp @@ -31,13 +32,10 @@ SET(common_sources guilds.cpp ipc_mutex.cpp item.cpp - logsys.cpp - logsys_eqemu.cpp md5.cpp memory_mapped_file.cpp misc.cpp misc_functions.cpp - moremath.cpp mutex.cpp mysql_request_result.cpp mysql_request_row.cpp @@ -75,7 +73,7 @@ SET(common_sources patches/rof.cpp patches/rof2.cpp patches/titanium.cpp - patches/underfoot.cpp + patches/uf.cpp SocketLib/Base64.cpp SocketLib/File.cpp SocketLib/HttpdCookies.cpp @@ -99,7 +97,6 @@ SET(common_headers base_packet.h base_data.h bodytypes.h - breakdowns.h classes.h condition.h crash.h @@ -108,7 +105,6 @@ SET(common_headers data_verification.h database.h dbcore.h - debug.h deity.h emu_opcodes.h emu_oplist.h @@ -122,7 +118,7 @@ SET(common_headers eqemu_exception.h eqemu_config.h eqemu_config_elements.h - eqemu_error.h + eqemu_logsys.h eq_packet.h eq_stream.h eq_stream_factory.h @@ -138,6 +134,7 @@ SET(common_headers features.h fixed_memory_hash_set.h fixed_memory_variable_hash_set.h + global_define.h guild_base.h guilds.h ipc_mutex.h @@ -146,15 +143,12 @@ SET(common_headers item_struct.h languages.h linked_list.h - logsys.h - logtypes.h loottable.h mail_oplist.h md5.h memory_mapped_file.h misc.h misc_functions.h - moremath.h mutex.h mysql_request_result.h mysql_request_row.h @@ -226,11 +220,11 @@ SET(common_headers patches/titanium_itemfields.h patches/titanium_ops.h patches/titanium_structs.h - patches/underfoot.h - patches/underfoot_constants.h - patches/underfoot_itemfields.h - patches/underfoot_ops.h - patches/underfoot_structs.h + patches/uf.h + patches/uf_constants.h + patches/uf_itemfields.h + patches/uf_ops.h + patches/uf_structs.h SocketLib/Base64.h SocketLib/File.h SocketLib/HttpdCookies.h @@ -279,18 +273,18 @@ SOURCE_GROUP(Patches FILES patches/titanium_ops.h patches/titanium_constants.h patches/titanium_structs.h - patches/underfoot.h - patches/underfoot_itemfields.h - patches/underfoot_ops.h - patches/underfoot_constants.h - patches/underfoot_structs.h + patches/uf.h + patches/uf_itemfields.h + patches/uf_ops.h + patches/uf_constants.h + patches/uf_structs.h patches/patches.cpp patches/sod.cpp patches/sof.cpp patches/rof.cpp patches/rof2.cpp patches/titanium.cpp - patches/underfoot.cpp + patches/uf.cpp ) SOURCE_GROUP(SocketLib FILES @@ -340,7 +334,7 @@ ADD_LIBRARY(common ${common_sources} ${common_headers}) IF(UNIX) ADD_DEFINITIONS(-fPIC) SET_SOURCE_FILES_PROPERTIES("SocketLib/Mime.cpp" PROPERTY COMPILE_FLAGS -Wno-unused-result) - SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/underfoot.cpp" PROPERTIES COMPILE_FLAGS -O0) + SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0) ENDIF(UNIX) diff --git a/common/SocketLib/HTTPSocket.cpp b/common/SocketLib/HTTPSocket.cpp index ecde78403..da4f2264c 100644 --- a/common/SocketLib/HTTPSocket.cpp +++ b/common/SocketLib/HTTPSocket.cpp @@ -40,7 +40,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef _WIN32 #pragma warning(disable:4786) #endif -#include "../debug.h" +#include "../global_define.h" #include #include #include diff --git a/common/SocketLib/HttpdCookies.cpp b/common/SocketLib/HttpdCookies.cpp index 4d9fccb1b..a40200aab 100644 --- a/common/SocketLib/HttpdCookies.cpp +++ b/common/SocketLib/HttpdCookies.cpp @@ -26,7 +26,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "../debug.h" +#include "../global_define.h" #ifdef _WIN32 #pragma warning(disable:4786) #endif diff --git a/common/SocketLib/HttpdSocket.cpp b/common/SocketLib/HttpdSocket.cpp index bd803877a..21c2938d4 100644 --- a/common/SocketLib/HttpdSocket.cpp +++ b/common/SocketLib/HttpdSocket.cpp @@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef _WIN32 #pragma warning(disable:4786) #endif -#include "../debug.h" +#include "../global_define.h" #include "Utility.h" #include "HttpdCookies.h" #include "HttpdForm.h" @@ -194,7 +194,6 @@ void HttpdSocket::OnHeaderComplete() void HttpdSocket::OnData(const char *p,size_t l) { -//printf("Got %d bytes: %.*s\n", l, l, p); if (m_file) { m_file -> fwrite(p,1,l); diff --git a/common/SocketLib/MemFile.cpp b/common/SocketLib/MemFile.cpp index 7c50356f8..c621666e5 100644 --- a/common/SocketLib/MemFile.cpp +++ b/common/SocketLib/MemFile.cpp @@ -110,7 +110,6 @@ size_t MemFile::fread(char *ptr, size_t size, size_t nmemb) size_t sz = size * nmemb; if (p + sz < BLOCKSIZE) { -//printf("Read @ %d(%d). %d bytes. (%c)\n", m_read_ptr, p, sz, *(m_current_read -> data + p)); memcpy(ptr, m_current_read -> data + p, sz); m_read_ptr += sz; } @@ -142,7 +141,6 @@ size_t MemFile::fwrite(const char *ptr, size_t size, size_t nmemb) size_t sz = size * nmemb; if (p + sz < BLOCKSIZE) { -//printf("Write @ %d(%d). %d bytes.\n", m_write_ptr, p, sz); memcpy(m_current_write -> data + p, ptr, sz); m_write_ptr += sz; } diff --git a/common/StackWalker/StackWalker.cpp b/common/StackWalker/StackWalker.cpp index 6931c30f5..d457a2231 100644 --- a/common/StackWalker/StackWalker.cpp +++ b/common/StackWalker/StackWalker.cpp @@ -1128,7 +1128,6 @@ BOOL __stdcall StackWalker::myReadProcMem( SIZE_T st; BOOL bRet = ReadProcessMemory(hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, &st); *lpNumberOfBytesRead = (DWORD) st; - //printf("ReadMemory: hProcess: %p, baseAddr: %p, buffer: %p, size: %d, read: %d, result: %d\n", hProcess, (LPVOID) qwBaseAddress, lpBuffer, nSize, (DWORD) st, (DWORD) bRet); return bRet; } else diff --git a/common/base_packet.cpp b/common/base_packet.cpp index e871ea71f..ce6afe978 100644 --- a/common/base_packet.cpp +++ b/common/base_packet.cpp @@ -16,7 +16,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "debug.h" +#include "global_define.h" #include "base_packet.h" #include "misc.h" #include "packet_dump.h" diff --git a/common/breakdowns.h b/common/breakdowns.h deleted file mode 100644 index 18dfb803f..000000000 --- a/common/breakdowns.h +++ /dev/null @@ -1,134 +0,0 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef BREAKDOWNS_H_ -#define BREAKDOWNS_H_ - -#include "types.h" - - -#pragma pack(1) -struct uint16_breakdown { - union { - uint16 all; - struct { - uint8 b1; - uint8 b2; - } bytes; - }; - inline uint16& operator=(const uint16& val) { return (all=val); } - inline uint16* operator&() { return &all; } - inline operator uint16&() { return all; } - inline uint8& b1() { return bytes.b1; } - inline uint8& b2() { return bytes.b2; } -}; - -struct uint32_breakdown { - union { - uint32 all; - struct { - uint16 w1; - uint16 w2; - } words; - struct { - uint8 b1; - union { - struct { - uint8 b2; - uint8 b3; - } middle; - uint16 w2_3; // word bytes 2 to 3 - }; - uint8 b4; - } bytes; - }; - inline uint32& operator=(const uint32& val) { return (all=val); } - inline uint32* operator&() { return &all; } - inline operator uint32&() { return all; } - - inline uint16& w1() { return words.w1; } - inline uint16& w2() { return words.w2; } - inline uint16& w2_3() { return bytes.w2_3; } - inline uint8& b1() { return bytes.b1; } - inline uint8& b2() { return bytes.middle.b2; } - inline uint8& b3() { return bytes.middle.b3; } - inline uint8& b4() { return bytes.b4; } -}; -/* -struct uint64_breakdown { - union { - uint64 all; - struct { - uint16 w1; // 1 2 - uint16 w2; // 3 4 - uint16 w3; // 5 6 - uint16 w4; // 7 8 - }; - struct { - uint32 dw1; // 1 4 - uint32 dw2; // 5 6 - }; - struct { - uint8 b1; - union { - struct { - uint16 w2_3; - uint16 w4_5; - uint16 w6_7; - }; - uint32 dw2_5; - struct { - uint8 b2; - union { - uint32 dw3_6; - struct { - uint8 b3; - union { - uint32 dw4_7; - struct { - uint8 b4; - uint8 b5; - uint8 b6; - uint8 b7; - }; - }; - }; - }; - }; - }; - }; - }; - inline uint64* operator&() { return &all; } - inline operator uint64&() { return all; } -}; -*/ -#pragma pack() - - - - - - - - - - - - - - -#endif /*BREAKDOWNS_H_*/ diff --git a/common/classes.cpp b/common/classes.cpp index 6270656f4..1f54c9234 100644 --- a/common/classes.cpp +++ b/common/classes.cpp @@ -15,7 +15,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "../common/debug.h" +#include "../common/global_define.h" #include "../common/classes.h" const char* GetEQClassName(uint8 class_, uint8 level) { diff --git a/common/clientversions.h b/common/clientversions.h index ee70d481c..d0b5f7c41 100644 --- a/common/clientversions.h +++ b/common/clientversions.h @@ -1,75 +1,76 @@ #ifndef CLIENTVERSIONS_H #define CLIENTVERSIONS_H +#include "types.h" + static const uint32 BIT_Client62 = 1; static const uint32 BIT_Titanium = 2; static const uint32 BIT_SoF = 4; static const uint32 BIT_SoD = 8; -static const uint32 BIT_Underfoot = 16; +static const uint32 BIT_UF = 16; static const uint32 BIT_RoF = 32; static const uint32 BIT_RoF2 = 64; static const uint32 BIT_TitaniumAndEarlier = 0x00000003; static const uint32 BIT_SoFAndLater = 0xFFFFFFFC; static const uint32 BIT_SoDAndLater = 0xFFFFFFF8; -static const uint32 BIT_UnderfootAndLater = 0xFFFFFFF0; +static const uint32 BIT_UFAndLater = 0xFFFFFFF0; static const uint32 BIT_RoFAndLater = 0xFFFFFFE0; static const uint32 BIT_RoF2AndLater = 0xFFFFFFC0; static const uint32 BIT_AllClients = 0xFFFFFFFF; -typedef enum +enum class ClientVersion { - EQClientUnknown = 0, - EQClient62, // Build: 'Aug 4 2005 15:40:59' - EQClientTitanium, // Build: 'Oct 31 2005 10:33:37' - EQClientSoF, // Build: 'Sep 7 2007 09:11:49' - EQClientSoD, // Build: 'Dec 19 2008 15:22:49' - EQClientUnderfoot, // Build: 'Jun 8 2010 16:44:32' - EQClientRoF, // Build: 'Dec 10 2012 17:35:44' - EQClientRoF2, // Build: 'May 10 2013 23:30:08' + Unknown = 0, + Client62, // Build: 'Aug 4 2005 15:40:59' + Titanium, // Build: 'Oct 31 2005 10:33:37' + SoF, // Build: 'Sep 7 2007 09:11:49' + SoD, // Build: 'Dec 19 2008 15:22:49' + UF, // Build: 'Jun 8 2010 16:44:32' + RoF, // Build: 'Dec 10 2012 17:35:44' + RoF2, // Build: 'May 10 2013 23:30:08' - _EQClientCount, // place new clients before this point (preferably, in release/attribute order) + MobNPC, + MobMerc, + MobBot, + MobPet, +}; - // Values below are not implemented, as yet... +#define CLIENT_VERSION_COUNT 12 +#define LAST_PC_CLIENT ClientVersion::RoF2 +#define LAST_NPC_CLIENT ClientVersion::MobPet - EmuNPC = _EQClientCount, - EmuMerc, - EmuBot, - EmuPet, - _EmuClientCount // array size for EQLimits -} EQClientVersion; - -static const char* EQClientVersionName(EQClientVersion version) +static const char* ClientVersionName(ClientVersion version) { switch (version) { - case EQClientUnknown: - return "EQClientUnknown"; - case EQClient62: - return "EQClient62"; - case EQClientTitanium: - return "EQClientTitanium"; - case EQClientSoF: - return "EQClientSoF"; - case EQClientSoD: - return "EQClientSoD"; - case EQClientUnderfoot: - return "EQClientUnderfoot"; - case EQClientRoF: - return "EQClientRoF"; - case EQClientRoF2: - return "EQClientRoF2"; - case EmuNPC: - return "EmuNPC"; - case EmuMerc: - return "EmuMerc"; - case EmuBot: - return "EmuBot"; - case EmuPet: - return "EmuPet"; + case ClientVersion::Unknown: + return "ClientVersion::Unknown"; + case ClientVersion::Client62: + return "ClientVersion::Client62"; + case ClientVersion::Titanium: + return "ClientVersion::Titanium"; + case ClientVersion::SoF: + return "ClientVersion::SoF"; + case ClientVersion::SoD: + return "ClientVersion::SoD"; + case ClientVersion::UF: + return "ClientVersion::UF"; + case ClientVersion::RoF: + return "ClientVersion::RoF"; + case ClientVersion::RoF2: + return "ClientVersion::RoF2"; + case ClientVersion::MobNPC: + return "ClientVersion::MobNPC"; + case ClientVersion::MobMerc: + return "ClientVersion::MobMerc"; + case ClientVersion::MobBot: + return "ClientVersion::MobBot"; + case ClientVersion::MobPet: + return "ClientVersion::MobPet"; default: - return "ERROR: Invalid EQClientVersion"; + return " Invalid ClientVersion"; }; } diff --git a/common/condition.h b/common/condition.h index bfbffe760..9c4cd9f7b 100644 --- a/common/condition.h +++ b/common/condition.h @@ -18,7 +18,8 @@ #ifndef __CONDITION_H #define __CONDITION_H -#include "debug.h" +#include "global_define.h" +#include "mutex.h" #ifndef WIN32 #include #endif diff --git a/common/crash.cpp b/common/crash.cpp index 5ce1229a5..1f700f151 100644 --- a/common/crash.cpp +++ b/common/crash.cpp @@ -1,4 +1,5 @@ -#include "debug.h" +#include "global_define.h" +#include "eqemu_logsys.h" #include "crash.h" #if defined(_WINDOWS) && defined(CRASH_LOGGING) @@ -24,7 +25,7 @@ public: } } - LogFile->write(EQEMuLog::Crash, buffer); + Log.Out(Logs::General, Logs::Crash, buffer); StackWalker::OnOutput(szText); } }; @@ -34,67 +35,67 @@ LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo) switch(ExceptionInfo->ExceptionRecord->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_ACCESS_VIOLATION"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_ACCESS_VIOLATION"); break; case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED"); break; case EXCEPTION_BREAKPOINT: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_BREAKPOINT"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_BREAKPOINT"); break; case EXCEPTION_DATATYPE_MISALIGNMENT: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_DATATYPE_MISALIGNMENT"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_DATATYPE_MISALIGNMENT"); break; case EXCEPTION_FLT_DENORMAL_OPERAND: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_FLT_DENORMAL_OPERAND"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_DENORMAL_OPERAND"); break; case EXCEPTION_FLT_DIVIDE_BY_ZERO: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_FLT_DIVIDE_BY_ZERO"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_DIVIDE_BY_ZERO"); break; case EXCEPTION_FLT_INEXACT_RESULT: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_FLT_INEXACT_RESULT"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_INEXACT_RESULT"); break; case EXCEPTION_FLT_INVALID_OPERATION: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_FLT_INVALID_OPERATION"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_INVALID_OPERATION"); break; case EXCEPTION_FLT_OVERFLOW: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_FLT_OVERFLOW"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_OVERFLOW"); break; case EXCEPTION_FLT_STACK_CHECK: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_FLT_STACK_CHECK"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_STACK_CHECK"); break; case EXCEPTION_FLT_UNDERFLOW: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_FLT_UNDERFLOW"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_FLT_UNDERFLOW"); break; case EXCEPTION_ILLEGAL_INSTRUCTION: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_ILLEGAL_INSTRUCTION"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_ILLEGAL_INSTRUCTION"); break; case EXCEPTION_IN_PAGE_ERROR: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_IN_PAGE_ERROR"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_IN_PAGE_ERROR"); break; case EXCEPTION_INT_DIVIDE_BY_ZERO: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_INT_DIVIDE_BY_ZERO"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_INT_DIVIDE_BY_ZERO"); break; case EXCEPTION_INT_OVERFLOW: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_INT_OVERFLOW"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_INT_OVERFLOW"); break; case EXCEPTION_INVALID_DISPOSITION: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_INVALID_DISPOSITION"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_INVALID_DISPOSITION"); break; case EXCEPTION_NONCONTINUABLE_EXCEPTION: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_NONCONTINUABLE_EXCEPTION"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_NONCONTINUABLE_EXCEPTION"); break; case EXCEPTION_PRIV_INSTRUCTION: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_PRIV_INSTRUCTION"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_PRIV_INSTRUCTION"); break; case EXCEPTION_SINGLE_STEP: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_SINGLE_STEP"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_SINGLE_STEP"); break; case EXCEPTION_STACK_OVERFLOW: - LogFile->write(EQEMuLog::Crash, "EXCEPTION_STACK_OVERFLOW"); + Log.Out(Logs::General, Logs::Crash, "EXCEPTION_STACK_OVERFLOW"); break; default: - LogFile->write(EQEMuLog::Crash, "Unknown Exception"); + Log.Out(Logs::General, Logs::Crash, "Unknown Exception"); break; } diff --git a/common/database.cpp b/common/database.cpp index 3de2a308b..736104f6e 100644 --- a/common/database.cpp +++ b/common/database.cpp @@ -1,5 +1,5 @@ /* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2003 EQEMu Development Team (http://eqemulator.net) + Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "../common/debug.h" +#include "../common/global_define.h" #include "../common/rulesys.h" #include @@ -47,26 +47,7 @@ extern Client client; -#ifdef _WINDOWS -#if _MSC_VER > 1700 // greater than 2012 (2013+) -# define _ISNAN_(a) std::isnan(a) -#else -# include -# define _ISNAN_(a) _isnan(a) -#endif -#else -# define _ISNAN_(a) std::isnan(a) -#endif - -/* -Establish a connection to a mysql database with the supplied parameters - - Added a very simple .ini file parser - Bounce - - Modify to use for win32 & linux - misanthropicfiend -*/ -Database::Database () -{ +Database::Database () { DBInitVars(); } @@ -84,12 +65,11 @@ bool Database::Connect(const char* host, const char* user, const char* passwd, c uint32 errnum= 0; char errbuf[MYSQL_ERRMSG_SIZE]; if (!Open(host, user, passwd, database, port, &errnum, errbuf)) { - LogFile->write(EQEMuLog::Error, "Failed to connect to database: Error: %s", errbuf); - + Log.Out(Logs::General, Logs::Error, "Failed to connect to database: Error: %s", errbuf); return false; } else { - LogFile->write(EQEMuLog::Status, "Using database '%s' at %s:%d",database,host,port); + Log.Out(Logs::General, Logs::Status, "Using database '%s' at %s:%d", database, host,port); return true; } } @@ -99,10 +79,11 @@ void Database::DBInitVars() { varcache_max = 0; varcache_lastupdate = 0; } -/* -Close the connection to the database +/* + Close the connection to the database */ + Database::~Database() { unsigned int x; @@ -115,9 +96,9 @@ Database::~Database() } /* -Check if there is an account with name "name" and password "password" -Return the account id or zero if no account matches. -Zero will also be returned if there is a database error. + Check if there is an account with name "name" and password "password" + Return the account id or zero if no account matches. + Zero will also be returned if there is a database error. */ uint32 Database::CheckLogin(const char* name, const char* password, int16* oStatus) { @@ -137,7 +118,6 @@ uint32 Database::CheckLogin(const char* name, const char* password, int16* oStat if (!results.Success()) { - std::cerr << "Error in CheckLogin query '" << query << "' " << results.ErrorMessage() << std::endl; return 0; } @@ -163,7 +143,6 @@ bool Database::CheckBannedIPs(const char* loginIP) if (!results.Success()) { - std::cerr << "Error in CheckBannedIPs query '" << query << "' " << results.ErrorMessage() << std::endl; return true; } @@ -177,7 +156,6 @@ bool Database::AddBannedIP(char* bannedIP, const char* notes) { std::string query = StringFormat("INSERT into Banned_IPs SET ip_address='%s', notes='%s'", bannedIP, notes); auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error in Database::AddBannedIP query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } return true; @@ -204,9 +182,7 @@ bool Database::AddGMIP(char* ip_address, char* name) { void Database::LoginIP(uint32 AccountID, const char* LoginIP) { std::string query = StringFormat("INSERT INTO account_ip SET accid=%i, ip='%s' ON DUPLICATE KEY UPDATE count=count+1, lastused=now()", AccountID, LoginIP); - auto results = QueryDatabase(query); - if (!results.Success()) - std::cerr << "Error in Log IP query '" << query << "' " << results.ErrorMessage() << std::endl; + QueryDatabase(query); } int16 Database::CheckStatus(uint32 account_id) { @@ -215,7 +191,6 @@ int16 Database::CheckStatus(uint32 account_id) { auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error in CheckStatus query '" << query << "' " << results.ErrorMessage() << std::endl; return 0; } @@ -247,17 +222,15 @@ uint32 Database::CreateAccount(const char* name, const char* password, int16 sta else query = StringFormat("INSERT INTO account SET name='%s', status=%i, lsaccount_id=%i, time_creation=UNIX_TIMESTAMP();",name, status, lsaccount_id); - std::cerr << "Account Attempting to be created:" << name << " " << (int16) status << std::endl; + Log.Out(Logs::General, Logs::World_Server, "Account Attempting to be created: '%s' status: %i", name, status); auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error in CreateAccount query '" << query << "' " << results.ErrorMessage() << std::endl; return 0; } if (results.LastInsertedID() == 0) { - std::cerr << "Error in CreateAccount query '" << query << "' " << results.ErrorMessage() << std::endl; return 0; } @@ -266,13 +239,10 @@ uint32 Database::CreateAccount(const char* name, const char* password, int16 sta bool Database::DeleteAccount(const char* name) { std::string query = StringFormat("DELETE FROM account WHERE name='%s';",name); - std::cout << "Account Attempting to be deleted:" << name << std::endl; + Log.Out(Logs::General, Logs::World_Server, "Account Attempting to be deleted:'%s'", name); - auto results = QueryDatabase(query); - - if (!results.Success()) - { - std::cerr << "Error in DeleteAccount query '" << query << "' " << results.ErrorMessage() << std::endl; + auto results = QueryDatabase(query); + if (!results.Success()) { return false; } @@ -285,7 +255,6 @@ bool Database::SetLocalPassword(uint32 accid, const char* password) { auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error in SetLocalPassword query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } @@ -313,8 +282,17 @@ bool Database::SetAccountStatus(const char* name, int16 status) { /* This initially creates the character during character create */ bool Database::ReserveName(uint32 account_id, char* name) { - std::string query = StringFormat("INSERT INTO `character_data` SET `account_id` = %i, `name` = '%s'", account_id, name); + std::string query = StringFormat("SELECT `account_id`, `name` FROM `character_data` WHERE `name` = '%s'", name); auto results = QueryDatabase(query); + for (auto row = results.begin(); row != results.end(); ++row) { + if (row[0] && atoi(row[0]) > 0){ + Log.Out(Logs::General, Logs::World_Server, "Account: %i tried to request name: %s, but it is already taken...", account_id, name); + return false; + } + } + + query = StringFormat("INSERT INTO `character_data` SET `account_id` = %i, `name` = '%s'", account_id, name); + results = QueryDatabase(query); if (!results.Success() || results.ErrorMessage() != ""){ return false; } return true; } @@ -325,11 +303,11 @@ bool Database::ReserveName(uint32 account_id, char* name) { */ bool Database::DeleteCharacter(char *name) { uint32 charid = 0; - printf("Database::DeleteCharacter name : %s \n", name); if(!name || !strlen(name)) { - std::cerr << "DeleteCharacter: request to delete without a name (empty char slot)" << std::endl; + Log.Out(Logs::General, Logs::World_Server, "DeleteCharacter: request to delete without a name (empty char slot)"); return false; } + Log.Out(Logs::General, Logs::World_Server, "Database::DeleteCharacter name : '%s'", name); /* Get id from character_data before deleting record so we can clean up the rest of the tables */ std::string query = StringFormat("SELECT `id` from `character_data` WHERE `name` = '%s'", name); @@ -337,39 +315,39 @@ bool Database::DeleteCharacter(char *name) { for (auto row = results.begin(); row != results.end(); ++row) { charid = atoi(row[0]); } if (charid <= 0){ std::cerr << "Database::DeleteCharacter :: Character not found, stopping delete...\n"; return false; } - query = StringFormat("DELETE FROM `quest_globals` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_activities` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_enabledtasks` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `completed_tasks` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `friends` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `mail` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `timers` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `inventory` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `char_recipe_list` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `adventure_stats` WHERE `player_id` ='%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `zone_flags` WHERE `charID` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `titles` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `player_titlesets` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `keyring` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `faction_values` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `instance_list_player` WHERE `charid` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_data` WHERE `id` = '%d'", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_skills` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_languages` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_bind` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_alternate_abilities` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_currency` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_data` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_spells` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_memmed_spells` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_disciplines` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_material` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_tribute` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_bandolier` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_potionbelt` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_inspect_messages` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_leadership_abilities` WHERE `id` = %u", charid); results = QueryDatabase(query); - query = StringFormat("DELETE FROM `character_alt_currency` WHERE `char_id` = '%d'", charid); results = QueryDatabase(query); + query = StringFormat("DELETE FROM `quest_globals` WHERE `charid` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_activities` WHERE `charid` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_enabledtasks` WHERE `charid` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `completed_tasks` WHERE `charid` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `friends` WHERE `charid` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `mail` WHERE `charid` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `timers` WHERE `char_id` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `inventory` WHERE `charid` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `char_recipe_list` WHERE `char_id` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `adventure_stats` WHERE `player_id` ='%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `zone_flags` WHERE `charID` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `titles` WHERE `char_id` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `player_titlesets` WHERE `char_id` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `keyring` WHERE `char_id` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `faction_values` WHERE `char_id` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `instance_list_player` WHERE `charid` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_data` WHERE `id` = '%d'", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_skills` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_languages` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_bind` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_alternate_abilities` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_currency` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_data` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_spells` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_memmed_spells` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_disciplines` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_material` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_tribute` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_bandolier` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_potionbelt` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_inspect_messages` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_leadership_abilities` WHERE `id` = %u", charid); QueryDatabase(query); + query = StringFormat("DELETE FROM `character_alt_currency` WHERE `char_id` = '%d'", charid); QueryDatabase(query); #ifdef BOTS query = StringFormat("DELETE FROM `guild_members` WHERE `char_id` = '%d' AND GetMobTypeById(%i) = 'C'", charid); #else @@ -706,7 +684,7 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven charid = GetCharacterID(pp->name); if(!charid) { - LogFile->write(EQEMuLog::Error, "StoreCharacter: no character id"); + Log.Out(Logs::General, Logs::Error, "StoreCharacter: no character id"); return false; } @@ -734,13 +712,6 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven charid, i, newinv->GetItem()->ID, newinv->GetCharges(), newinv->GetColor()); auto results = QueryDatabase(invquery); - - if (!results.RowsAffected()) - LogFile->write(EQEMuLog::Error, "StoreCharacter inventory failed. Query '%s' %s", invquery.c_str(), results.ErrorMessage().c_str()); -#if EQDEBUG >= 9 - else - LogFile->write(EQEMuLog::Debug, "StoreCharacter inventory succeeded. Query '%s'", invquery.c_str()); -#endif } if (i == MainCursor) { @@ -783,7 +754,6 @@ uint32 Database::GetAccountIDByChar(const char* charname, uint32* oCharID) { if (!results.Success()) { - std::cerr << "Error in GetAccountIDByChar query '" << query << "' " << results.ErrorMessage() << std::endl; return 0; } @@ -805,7 +775,6 @@ uint32 Database::GetAccountIDByChar(uint32 char_id) { std::string query = StringFormat("SELECT `account_id` FROM `character_data` WHERE `id` = %i LIMIT 1", char_id); auto results = QueryDatabase(query); if (!results.Success()) { - LogFile->write(EQEMuLog::Error, "Error in GetAccountIDByChar query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); return 0; } @@ -824,7 +793,6 @@ uint32 Database::GetAccountIDByName(const char* accname, int16* status, uint32* auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error in GetAccountIDByAcc query '" << query << "' " << results.ErrorMessage() << std::endl; return 0; } @@ -853,7 +821,6 @@ void Database::GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error in GetAccountName query '" << query << "' " << results.ErrorMessage() << std::endl; return; } @@ -874,7 +841,6 @@ void Database::GetCharName(uint32 char_id, char* name) { auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error in GetCharName query '" << query << "' " << results.ErrorMessage() << std::endl; return; } @@ -884,1549 +850,6 @@ void Database::GetCharName(uint32 char_id, char* name) { } } -static inline void loadbar(unsigned int x, unsigned int n, unsigned int w = 50) { - if ((x != n) && (x % (n / 100 + 1) != 0)) return; - float ratio = x / (float)n; - int c = ratio * w; - std::cout << std::setw(3) << (int)(ratio * 100) << "% ["; - for (int x = 0; xnew; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/db_update.pl'); if ($response->is_success){ open(FILE, '> db_update.pl'); print FILE $response->decoded_content; close(FILE); }\""); -#else - system("wget -O db_update.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/db_update.pl"); -#endif - // } - - /* - Automatic Database Upgrade Script - Script: db_update.pl V 1 - the number that world passes to the script will - force the script to check for a newer version to update itself with - db_update.pl ran_from_world - won't bring up a menu if your database versions match - db_update.pl - ran standalone will bring up a menu prompt - */ - - /* Check for a new version of this script, the arg passed - would have to be higher than the copy they have downloaded - locally and they will re fetch */ - system("perl db_update.pl V 1"); - - /* Run Automatic Database Upgrade Script */ - system("perl db_update.pl ran_from_world"); - - return true; -} - -bool Database::CheckDatabaseConvertPPDeblob(){ - unsigned int lengths; - unsigned int lengths_e; - std::string squery; - Convert::PlayerProfile_Struct* pp; - ExtendedProfile_Struct* e_pp; - uint32 pplen = 0; - uint32 i; - int character_id = 0; - int account_id = 0; - int number_of_characters = 0; - int printppdebug = 0; /* Prints Player Profile */ - int runconvert = 0; - - /* Check For Legacy Storage Method */ - std::string rquery = StringFormat("SHOW TABLES LIKE 'character_'"); - auto results = QueryDatabase(rquery); - if (results.RowCount() == 1){ - runconvert = 1; - printf("\n\n::: Legacy Character Data Binary Blob Storage Detected... \n"); - printf("----------------------------------------------------------\n\n"); - printf(" Database currently has character data being stored via \n"); - printf(" the legacy character storage method and will proceed with converting...\n\n"); - printf(" It is recommended that you backup your database \n"); - printf(" before continuing the automatic conversion process...\n\n"); - printf("----------------------------------------------------------\n\n"); - std::cout << "Press ENTER to continue....." << std::endl << std::endl; - std::cin.ignore(1); - } - - // runconvert = 0; - // printppdebug = 1; - - if (runconvert == 1){ - printf("Running character binary blob to database conversion... \n"); - /* Get the number of characters */ - rquery = StringFormat("SELECT COUNT(`id`) FROM `character_`"); - results = QueryDatabase(rquery); - for (auto row = results.begin(); row != results.end(); ++row) { - number_of_characters = atoi(row[0]); - printf("Number of Characters in Database: %i \n", number_of_characters); - } - - /* Check for table `character_data` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_data'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_data` doesn't exist... creating..."); - rquery = StringFormat( - "CREATE TABLE `character_data` ( " - "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " - "`account_id` int(11) NOT NULL DEFAULT '0', " - "`name` varchar(64) NOT NULL DEFAULT '', " - "`last_name` varchar(64) NOT NULL DEFAULT '', " - "`title` varchar(32) NOT NULL DEFAULT '', " - "`suffix` varchar(32) NOT NULL DEFAULT '', " - "`zone_id` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`zone_instance` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`y` float NOT NULL DEFAULT '0', " - "`x` float NOT NULL DEFAULT '0', " - "`z` float NOT NULL DEFAULT '0', " - "`heading` float NOT NULL DEFAULT '0', " - "`gender` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`race` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`class` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`level` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`deity` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`birthday` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`last_login` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`time_played` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`level2` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`anon` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`gm` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`face` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`hair_color` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`hair_style` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`beard` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`beard_color` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`eye_color_1` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`eye_color_2` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`drakkin_heritage` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`drakkin_tattoo` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`drakkin_details` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`ability_time_seconds` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`ability_number` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`ability_time_minutes` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`ability_time_hours` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`exp` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`aa_points_spent` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`aa_exp` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`aa_points` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`group_leadership_exp` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`raid_leadership_exp` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`group_leadership_points` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`raid_leadership_points` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`points` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`cur_hp` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`mana` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`endurance` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`intoxication` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`str` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`sta` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`cha` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`dex` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`int` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`agi` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`wis` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`zone_change_count` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`toxicity` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`hunger_level` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`thirst_level` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`ability_up` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`ldon_points_guk` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`ldon_points_mir` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`ldon_points_mmc` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`ldon_points_ruj` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`ldon_points_tak` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`ldon_points_available` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`tribute_time_remaining` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`career_tribute_points` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`tribute_points` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`tribute_active` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`pvp_status` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`pvp_kills` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`pvp_deaths` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`pvp_current_points` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`pvp_career_points` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`pvp_best_kill_streak` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`pvp_worst_death_streak` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`pvp_current_kill_streak` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`pvp2` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`pvp_type` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`show_helm` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`group_auto_consent` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`raid_auto_consent` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`guild_auto_consent` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`leadership_exp_on` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`RestTimer` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`air_remaining` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`autosplit_enabled` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`lfp` tinyint(1) unsigned NOT NULL DEFAULT '0', " - "`lfg` tinyint(1) unsigned NOT NULL DEFAULT '0', " - "`mailkey` char(16) NOT NULL DEFAULT '', " - "`xtargets` tinyint(3) unsigned NOT NULL DEFAULT '5', " - "`firstlogon` tinyint(3) NOT NULL DEFAULT '0', " - "`e_aa_effects` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`e_percent_to_aa` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`e_expended_aa_spent` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "PRIMARY KEY(`id`), " - "UNIQUE KEY `name` (`name`), " - "KEY `account_id` (`account_id`) " - ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1; " - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - /* Check for table `character_currency` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_currency'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_currency` doesn't exist... creating..."); - rquery = StringFormat( - " CREATE TABLE `character_currency` ( " - " `id` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `platinum` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `gold` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `silver` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `copper` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `platinum_bank` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `gold_bank` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `silver_bank` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `copper_bank` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `platinum_cursor` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `gold_cursor` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `silver_cursor` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `copper_cursor` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `radiant_crystals` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `career_radiant_crystals` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `ebon_crystals` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `career_ebon_crystals` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " PRIMARY KEY (`id`), " - " KEY `id` (`id`) " - " ) ENGINE=InnoDB DEFAULT CHARSET=latin1; " - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - /* Check for table `character_alternate_abilities` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_alternate_abilities'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_alternate_abilities` doesn't exist... creating..."); - rquery = StringFormat( - " CREATE TABLE `character_alternate_abilities` ( " - " `id` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `slot` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " - " `aa_id` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " - " `aa_value` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " - " PRIMARY KEY(`id`,`slot`), " - " KEY `id` (`id`) " - " ) ENGINE = InnoDB DEFAULT CHARSET = latin1; " - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - /* Check for table `character_bind` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_bind'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_bind` doesn't exist... creating..."); - rquery = StringFormat( - "CREATE TABLE `character_bind` ( " - "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " - "`is_home` tinyint(11) UNSIGNED NOT NULL DEFAULT '0', " - "`zone_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " - "`instance_id` mediumint(11) UNSIGNED NOT NULL DEFAULT '0', " - "`x` float NOT NULL DEFAULT '0', " - "`y` float NOT NULL DEFAULT '0', " - "`z` float NOT NULL DEFAULT '0', " - "`heading` float NOT NULL DEFAULT '0', " - "PRIMARY KEY(`id`, `is_home`), " - "KEY `id` (`id`) " - ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - /* Check for table `character_languages` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_languages'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_languages` doesn't exist... creating..."); - rquery = StringFormat( - "CREATE TABLE `character_languages` ( " - "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " - "`lang_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " - "`value` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " - "PRIMARY KEY(`id`, `lang_id`), " - "KEY `id` (`id`) " - ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - /* Check for table `character_skills` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_skills'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_skills` doesn't exist... creating..."); - rquery = StringFormat( - "CREATE TABLE `character_skills` ( " - "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " - "`skill_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " - "`value` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " - "PRIMARY KEY(`id`, `skill_id`), " - "KEY `id` (`id`) " - ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - /* Check for table `character_spells` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_spells'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_spells` doesn't exist... creating..."); - rquery = StringFormat( - "CREATE TABLE `character_spells` ( " - "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " - "`slot_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " - "`spell_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " - "PRIMARY KEY(`id`, `slot_id`), " - "KEY `id` (`id`) " - ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - /* Check for table `character_memmed_spells` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_memmed_spells'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_memmed_spells` doesn't exist... creating..."); - rquery = StringFormat( - "CREATE TABLE `character_memmed_spells` ( " - "`id` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`slot_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " - "`spell_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " - "PRIMARY KEY(`id`, `slot_id`), " - "KEY `id` (`id`) " - ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - /* Check for table `character_disciplines` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_disciplines'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_disciplines` doesn't exist... creating..."); - rquery = StringFormat( - " CREATE TABLE `character_disciplines` ( " - " `id` int(11) UNSIGNED NOT NULL DEFAULT 0, " - " `slot_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " - " `disc_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " - " PRIMARY KEY(`id`, `slot_id`), " - " KEY `id` (`id`) " - " ) ENGINE = InnoDB DEFAULT CHARSET = latin1; " - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - /* Check for table `character_material` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_material'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_material` doesn't exist... creating..."); - rquery = StringFormat( - "CREATE TABLE `character_material` ( " - "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT," - "`slot` tinyint(11) UNSIGNED NOT NULL DEFAULT '0'," - "`blue` tinyint(11) UNSIGNED NOT NULL DEFAULT '0'," - "`green` tinyint(11) UNSIGNED NOT NULL DEFAULT '0'," - "`red` tinyint(11) UNSIGNED NOT NULL DEFAULT '0'," - "`use_tint` tinyint(11) UNSIGNED NOT NULL DEFAULT '0'," - "`color` int(11) UNSIGNED NOT NULL DEFAULT '0'," - "PRIMARY KEY(`id`, `slot`)," - "KEY `id` (`id`)" - ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;" - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - /* Check for table `character_tribute` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_tribute'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_tribute` doesn't exist... creating..."); - rquery = StringFormat( - "CREATE TABLE `character_tribute` ( " - "`id` int(11) unsigned NOT NULL DEFAULT 0, " - "`tier` tinyint(11) unsigned NOT NULL DEFAULT '0', " - "`tribute` int(11) UNSIGNED NOT NULL DEFAULT '0', " - "KEY `id` (`id`) " - ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - /* Check for table `character_bandolier` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_bandolier'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_bandolier` doesn't exist... creating..."); - rquery = StringFormat( - "CREATE TABLE `character_bandolier` ( " - "`id` int(11) unsigned NOT NULL DEFAULT 0, " - "`bandolier_id` tinyint(11) unsigned NOT NULL DEFAULT '0', " - "`bandolier_slot` tinyint(11) unsigned NOT NULL DEFAULT '0', " - "`item_id` int(11) UNSIGNED NOT NULL DEFAULT '0', " - "`icon` int(11) UNSIGNED NOT NULL DEFAULT '0', " - "`bandolier_name` varchar(32) NOT NULL DEFAULT '0', " - "PRIMARY KEY(`id`,`bandolier_id`, `bandolier_slot`), " - "KEY `id` (`id`) " - ") ENGINE = InnoDB DEFAULT CHARSET = latin1; " - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - /* Check for table `character_potionbelt` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_potionbelt'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_potionbelt` doesn't exist... creating..."); - rquery = StringFormat( - "CREATE TABLE `character_potionbelt` ( " - "`id` int(11) unsigned NOT NULL DEFAULT 0, " - "`potion_id` tinyint(11) unsigned NOT NULL DEFAULT '0', " - "`item_id` int(11) UNSIGNED NOT NULL DEFAULT '0', " - "`icon` int(11) UNSIGNED NOT NULL DEFAULT '0', " - "PRIMARY KEY(`id`,`potion_id`), " - "KEY `id` (`id`) " - ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - /* Check for table `character_potionbelt` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_inspect_messages'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_inspect_messages` doesn't exist... creating..."); - rquery = StringFormat( - "CREATE TABLE `character_inspect_messages` ( " - "`id` int(11) unsigned NOT NULL DEFAULT 0, " - "`inspect_message` varchar(255) NOT NULL DEFAULT '', " - "PRIMARY KEY(`id`), " - "KEY `id` (`id`) " - ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - /* Check for table `character_leadership_abilities` */ - rquery = StringFormat("SHOW TABLES LIKE 'character_leadership_abilities'"); - results = QueryDatabase(rquery); - if (results.RowCount() == 0){ - printf("Table: `character_leadership_abilities` doesn't exist... creating..."); - rquery = StringFormat( - "CREATE TABLE `character_leadership_abilities` (" - "`id` int(11) UNSIGNED NOT NULL DEFAULT 0, " - "`slot` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " - "`rank` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " - "PRIMARY KEY(`id`,`slot`), " - "KEY `id` (`id`) " - ") ENGINE = InnoDB DEFAULT CHARSET = latin1; " - ); - auto results = QueryDatabase(rquery); - printf(" done...\n"); - } - - /* Done */ - printf("Starting conversion...\n\n"); - - - int char_iter_count = 0; - rquery = StringFormat("SELECT `id` FROM `character_`"); - results = QueryDatabase(rquery); - - uint8 firstlogon = 0; - uint8 lfg = 0; - uint8 lfp = 0; - std::string mailkey; - uint8 xtargets = 0; - std::string inspectmessage; - - for (auto row = results.begin(); row != results.end(); ++row) { - char_iter_count++; - squery = StringFormat("SELECT `id`, `profile`, `name`, `level`, `account_id`, `firstlogon`, `lfg`, `lfp`, `mailkey`, `xtargets`, `inspectmessage`, `extprofile` FROM `character_` WHERE `id` = %i", atoi(row[0])); - auto results2 = QueryDatabase(squery); - auto row2 = results2.begin(); - pp = (Convert::PlayerProfile_Struct*)row2[1]; - e_pp = (ExtendedProfile_Struct*)row2[11]; - character_id = atoi(row[0]); - account_id = atoi(row2[4]); - /* Convert some data from the character_ table that is still relevant */ - firstlogon = atoi(row2[5]); - lfg = atoi(row2[6]); - lfp = atoi(row2[7]); - mailkey = row2[8]; - xtargets = atoi(row2[9]); - inspectmessage = row2[10]; - - /* Verify PP Integrity */ - lengths = results2.LengthOfColumn(1); - if (lengths == sizeof(Convert::PlayerProfile_Struct)) { /* If PP is the size it is expected to be */ - memcpy(pp, row2[1], sizeof(Convert::PlayerProfile_Struct)); - } - /* Continue of PP Size does not match (Usually a created character never logged in) */ - else { - // printf("%s ID: %i profile mismatch, not converting. PP %u - Profile Length %u \n", row2[2] ? row2[2] : "Unknown", character_id, sizeof(PlayerProfile_Struct), lengths); - std::cout << (row2[2] ? row2[2] : "Unknown") << " ID: " << character_id << " size mismatch. Expected Size: " << sizeof(Convert::PlayerProfile_Struct) << " Seen: " << lengths << std::endl; - continue; - } - - lengths_e = results2.LengthOfColumn(11); - if (lengths_e == sizeof(ExtendedProfile_Struct)) { - memcpy(e_pp, row2[11], sizeof(ExtendedProfile_Struct)); - } - if (e_pp->expended_aa > 4000000){ e_pp->expended_aa = 0; } - - /* Loading Status on conversion */ - if (runconvert == 1){ - std::cout << "\r" << char_iter_count << "/" << number_of_characters << " " << std::flush; - loadbar(char_iter_count, number_of_characters, 50); - - /* Run inspect message convert */ - if (inspectmessage != ""){ - std::string rquery = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message)" - "VALUES (%u, '%s')", - character_id, - EscapeString(inspectmessage).c_str() - ); - auto results = QueryDatabase(rquery); - } - - /* Run Currency Convert */ - std::string rquery = StringFormat("REPLACE INTO `character_currency` (id, platinum, gold, silver, copper," - "platinum_bank, gold_bank, silver_bank, copper_bank," - "platinum_cursor, gold_cursor, silver_cursor, copper_cursor, " - "radiant_crystals, career_radiant_crystals, ebon_crystals, career_ebon_crystals)" - "VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u)", - character_id, - pp->platinum, - pp->gold, - pp->silver, - pp->copper, - pp->platinum_bank, - pp->gold_bank, - pp->silver_bank, - pp->copper_bank, - pp->platinum_cursor, - pp->gold_cursor, - pp->silver_cursor, - pp->copper_cursor, - pp->currentRadCrystals, - pp->careerRadCrystals, - pp->currentEbonCrystals, - pp->careerEbonCrystals - ); - auto results = QueryDatabase(rquery); - - if (pp->tribute_time_remaining < 0 || pp->tribute_time_remaining == 4294967295){ pp->tribute_time_remaining = 0; } - - /* Run Character Data Convert */ - rquery = StringFormat( - "REPLACE INTO `character_data` (" - "id," - "account_id," - "`name`," - "last_name," - "gender," - "race," - "class," - "`level`," - "deity," - "birthday," - "last_login," - "time_played," - "pvp_status," - "level2," - "anon," - "gm," - "intoxication," - "hair_color," - "beard_color," - "eye_color_1," - "eye_color_2," - "hair_style," - "beard," - "ability_time_seconds," - "ability_number," - "ability_time_minutes," - "ability_time_hours," - "title," - "suffix," - "exp," - "points," - "mana," - "cur_hp," - "str," - "sta," - "cha," - "dex," - "`int`," - "agi," - "wis," - "face," - "y," - "x," - "z," - "heading," - "pvp2," - "pvp_type," - "autosplit_enabled," - "zone_change_count," - "drakkin_heritage," - "drakkin_tattoo," - "drakkin_details," - "toxicity," - "hunger_level," - "thirst_level," - "ability_up," - "zone_id," - "zone_instance," - "leadership_exp_on," - "ldon_points_guk," - "ldon_points_mir," - "ldon_points_mmc," - "ldon_points_ruj," - "ldon_points_tak," - "ldon_points_available," - "tribute_time_remaining," - "show_helm," - "career_tribute_points," - "tribute_points," - "tribute_active," - "endurance," - "group_leadership_exp," - "raid_leadership_exp," - "group_leadership_points," - "raid_leadership_points," - "air_remaining," - "pvp_kills," - "pvp_deaths," - "pvp_current_points," - "pvp_career_points," - "pvp_best_kill_streak," - "pvp_worst_death_streak," - "pvp_current_kill_streak," - "aa_points_spent," - "aa_exp," - "aa_points," - "group_auto_consent," - "raid_auto_consent," - "guild_auto_consent," - "RestTimer," - "firstlogon," - "lfg," - "lfp," - "mailkey," - "xtargets," - "e_aa_effects," - "e_percent_to_aa," - "e_expended_aa_spent" - ")" - "VALUES (" - "%u," // id - "%u," // account_id - "'%s'," // `name` - "'%s'," // last_name - "%u," // gender - "%u," // race - "%u," // class - "%u," // `level` - "%u," // deity - "%u," // birthday - "%u," // last_login - "%u," // time_played - "%u," // pvp_status - "%u," // level2 - "%u," // anon - "%u," // gm - "%u," // intoxication - "%u," // hair_color - "%u," // beard_color - "%u," // eye_color_1 - "%u," // eye_color_2 - "%u," // hair_style - "%u," // beard - "%u," // ability_time_seconds - "%u," // ability_number - "%u," // ability_time_minutes - "%u," // ability_time_hours - "'%s'," // title - "'%s'," // suffix - "%u," // exp - "%u," // points - "%u," // mana - "%u," // cur_hp - "%u," // str - "%u," // sta - "%u," // cha - "%u," // dex - "%u," // `int` - "%u," // agi - "%u," // wis - "%u," // face - "%f," // y - "%f," // x - "%f," // z - "%f," // heading - "%u," // pvp2 - "%u," // pvp_type - "%u," // autosplit_enabled - "%u," // zone_change_count - "%u," // drakkin_heritage - "%u," // drakkin_tattoo - "%u," // drakkin_details - "%i," // toxicity - "%u," // hunger_level - "%u," // thirst_level - "%u," // ability_up - "%u," // zone_id - "%u," // zone_instance - "%u," // leadership_exp_on - "%u," // ldon_points_guk - "%u," // ldon_points_mir - "%u," // ldon_points_mmc - "%u," // ldon_points_ruj - "%u," // ldon_points_tak - "%u," // ldon_points_available - "%u," // tribute_time_remaining - "%u," // show_helm - "%u," // career_tribute_points - "%u," // tribute_points - "%u," // tribute_active - "%u," // endurance - "%u," // group_leadership_exp - "%u," // raid_leadership_exp - "%u," // group_leadership_points - "%u," // raid_leadership_points - "%u," // air_remaining - "%u," // pvp_kills - "%u," // pvp_deaths - "%u," // pvp_current_points - "%u," // pvp_career_points - "%u," // pvp_best_kill_streak - "%u," // pvp_worst_death_streak - "%u," // pvp_current_kill_streak - "%u," // aa_points_spent - "%u," // aa_exp - "%u," // aa_points - "%u," // group_auto_consent - "%u," // raid_auto_consent - "%u," // guild_auto_consent - "%u," // RestTimer - "%u," // First Logon - References online status for EVENT_CONNECT/EVENT_DISCONNECt - "%u," // Looking for Group - "%u," // Looking for P? - "'%s'," // Mailkey - "%u," // X Targets - "%u," // AA Effects - "%u," // Percent to AA - "%u" // e_expended_aa_spent - ")", - character_id, - account_id, - EscapeString(pp->name).c_str(), - EscapeString(pp->last_name).c_str(), - pp->gender, - pp->race, - pp->class_, - pp->level, - pp->deity, - pp->birthday, - pp->lastlogin, - pp->timePlayedMin, - pp->pvp, - pp->level2, - pp->anon, - pp->gm, - pp->intoxication, - pp->haircolor, - pp->beardcolor, - pp->eyecolor1, - pp->eyecolor2, - pp->hairstyle, - pp->beard, - pp->ability_time_seconds, - pp->ability_number, - pp->ability_time_minutes, - pp->ability_time_hours, - EscapeString(pp->title).c_str(), - EscapeString(pp->suffix).c_str(), - pp->exp, - pp->points, - pp->mana, - pp->cur_hp, - pp->STR, - pp->STA, - pp->CHA, - pp->DEX, - pp->INT, - pp->AGI, - pp->WIS, - pp->face, - pp->y, - pp->x, - pp->z, - pp->heading, - pp->pvp2, - pp->pvptype, - pp->autosplit, - pp->zone_change_count, - pp->drakkin_heritage, - pp->drakkin_tattoo, - pp->drakkin_details, - pp->toxicity, - pp->hunger_level, - pp->thirst_level, - pp->ability_up, - pp->zone_id, - pp->zoneInstance, - pp->leadAAActive == 0 ? 0 : 1, - pp->ldon_points_guk, - pp->ldon_points_mir, - pp->ldon_points_mmc, - pp->ldon_points_ruj, - pp->ldon_points_tak, - pp->ldon_points_available, - pp->tribute_time_remaining, - pp->showhelm, - pp->career_tribute_points, - pp->tribute_points, - pp->tribute_active, - pp->endurance, - pp->group_leadership_exp, - pp->raid_leadership_exp, - pp->group_leadership_points, - pp->raid_leadership_points, - pp->air_remaining, - pp->PVPKills, - pp->PVPDeaths, - pp->PVPCurrentPoints, - pp->PVPCareerPoints, - pp->PVPBestKillStreak, - pp->PVPWorstDeathStreak, - pp->PVPCurrentKillStreak, - pp->aapoints_spent, - pp->expAA, - pp->aapoints, - pp->groupAutoconsent, - pp->raidAutoconsent, - pp->guildAutoconsent, - pp->RestTimer, - firstlogon, - lfg, - lfp, - mailkey.c_str(), - xtargets, - e_pp->aa_effects, - e_pp->perAA, - e_pp->expended_aa - ); - results = QueryDatabase(rquery); - - - /* - We set a first entry variable because we need the first initial piece of the query to be declared - This is to speed up the INSERTS and trim down the amount of individual sends during the process. - The speed difference is dramatic - */ - /* Run AA Convert */ - int first_entry = 0; rquery = ""; - for (i = 0; i < MAX_PP_AA_ARRAY; i++){ - if (pp->aa_array[i].AA > 0 && pp->aa_array[i].value > 0){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, slot, aa_id, aa_value)" - " VALUES (%u, %u, %u, %u)", character_id, i, pp->aa_array[i].AA, pp->aa_array[i].value); - first_entry = 1; - } - else { - rquery = rquery + StringFormat(", (%u, %u, %u, %u)", character_id, i, pp->aa_array[i].AA, pp->aa_array[i].value); - } - } - } - if (rquery != ""){ results = QueryDatabase(rquery); } - - /* Run Bind Home Convert */ - if (pp->binds[4].zoneId < 999 && !_ISNAN_(pp->binds[4].x) && !_ISNAN_(pp->binds[4].y) && !_ISNAN_(pp->binds[4].z) && !_ISNAN_(pp->binds[4].heading)) { - rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" - " VALUES (%u, %u, %u, %f, %f, %f, %f, 1)", - character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading); - if (rquery != ""){ results = QueryDatabase(rquery); } - } - - /* Run Bind Convert */ - if (pp->binds[0].zoneId < 999 && !_ISNAN_(pp->binds[0].x) && !_ISNAN_(pp->binds[0].y) && !_ISNAN_(pp->binds[0].z) && !_ISNAN_(pp->binds[0].heading)) { - rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" - " VALUES (%u, %u, %u, %f, %f, %f, %f, 0)", - character_id, pp->binds[0].zoneId, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading); - if (rquery != ""){ results = QueryDatabase(rquery); } - } - /* Run Language Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < MAX_PP_LANGUAGE; i++){ - if (pp->languages[i] > 0){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_languages` (id, lang_id, value) VALUES (%u, %u, %u)", character_id, i, pp->languages[i]); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->languages[i]); - } - } - if (rquery != ""){ results = QueryDatabase(rquery); } - /* Run Skill Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < MAX_PP_SKILL; i++){ - if (pp->skills[i] > 0){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)", character_id, i, pp->skills[i]); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->skills[i]); - } - } - if (rquery != ""){ results = QueryDatabase(rquery); } - /* Run Spell Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < MAX_PP_REF_SPELLBOOK; i++){ - if (pp->spell_book[i] > 0 && pp->spell_book[i] != 4294967295 && pp->spell_book[i] < 40000 && pp->spell_book[i] != 1){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, i, pp->spell_book[i]); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->spell_book[i]); - } - } - // std::cout << rquery << "\n"; - if (rquery != ""){ results = QueryDatabase(rquery); } - /* Run Max Memmed Spell Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < MAX_PP_REF_MEMSPELL; i++){ - if (pp->mem_spells[i] > 0 && pp->mem_spells[i] != 65535 && pp->mem_spells[i] != 4294967295){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_memmed_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, i, pp->mem_spells[i]); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->mem_spells[i]); - } - } - if (rquery != ""){ results = QueryDatabase(rquery); } - /* Run Discipline Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < MAX_PP_DISCIPLINES; i++){ - if (pp->disciplines.values[i] > 0 && pp->disciplines.values[i] < 60000){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_disciplines` (id, slot_id, disc_id) VALUES (%u, %u, %u)", character_id, i, pp->disciplines.values[i]); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->disciplines.values[i]); - } - } - if (rquery != ""){ results = QueryDatabase(rquery); } - /* Run Material Color Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < _MaterialCount; i++){ - if (pp->item_tint[i].color > 0){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_material` (id, slot, blue, green, red, use_tint, color) VALUES (%u, %u, %u, %u, %u, %u, %u)", character_id, i, pp->item_tint[i].rgb.blue, pp->item_tint[i].rgb.green, pp->item_tint[i].rgb.red, pp->item_tint[i].rgb.use_tint, pp->item_tint[i].color); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u)", character_id, i, pp->item_tint[i].rgb.blue, pp->item_tint[i].rgb.green, pp->item_tint[i].rgb.red, pp->item_tint[i].rgb.use_tint, pp->item_tint[i].color); - } - } - if (rquery != ""){ results = QueryDatabase(rquery); } - /* Run Tribute Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < EmuConstants::TRIBUTE_SIZE; i++){ - if (pp->tributes[i].tribute > 0 && pp->tributes[i].tribute != 4294967295){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_tribute` (id, tier, tribute) VALUES (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); - } - } - if (rquery != ""){ results = QueryDatabase(rquery); } - /* Run Bandolier Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < EmuConstants::BANDOLIERS_COUNT; i++){ - if (strlen(pp->bandoliers[i].name) < 32) { - for (int si = 0; si < EmuConstants::BANDOLIER_SIZE; si++){ - if (pp->bandoliers[i].items[si].item_id > 0){ - if (first_entry != 1) { - rquery = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].items[si].item_id, pp->bandoliers[i].items[si].icon, pp->bandoliers[i].name); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].items[si].item_id, pp->bandoliers[i].items[si].icon, pp->bandoliers[i].name); - } - } - } - } - if (rquery != ""){ results = QueryDatabase(rquery); } - /* Run Potion Belt Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < EmuConstants::POTION_BELT_SIZE; i++){ - if (pp->potionbelt.items[i].item_id > 0){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_potionbelt` (id, potion_id, item_id, icon) VALUES (%i, %u, %u, %u)", character_id, i, pp->potionbelt.items[i].item_id, pp->potionbelt.items[i].icon); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%i, %u, %u, %u)", character_id, i, pp->potionbelt.items[i].item_id, pp->potionbelt.items[i].icon); - - } - } - if (rquery != ""){ results = QueryDatabase(rquery); } - /* Run Leadership AA Convert */ - first_entry = 0; rquery = ""; - for (i = 0; i < MAX_LEADERSHIP_AA_ARRAY; i++){ - if (pp->leader_abilities.ranks[i] > 0 && pp->leader_abilities.ranks[i] < 6){ - if (first_entry != 1){ - rquery = StringFormat("REPLACE INTO `character_leadership_abilities` (id, slot, rank) VALUES (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]); - first_entry = 1; - } - rquery = rquery + StringFormat(", (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]); - } - } - if (rquery != ""){ results = QueryDatabase(rquery); } - } - } - if (runconvert == 1){ - std::string rquery = StringFormat("RENAME TABLE `character_` TO `character_old`"); QueryDatabase(rquery); - printf("\n\nRenaming `character_` table to `character_old`, this is a LARGE table so when you don't need it anymore, I would suggest deleting it yourself...\n"); - printf("\n\nCharacter blob conversion complete, continuing world bootup...\n"); - } - } - return true; -} - -bool Database::CheckDatabaseConvertBotsPostPPDeblob(){ -#ifdef BOTS - int runbotsconvert = 0; - - /* Check For Legacy Bot References */ - std::string rquery = StringFormat("SHOW CREATE VIEW `vwBotCharacterMobs`"); - auto results = QueryDatabase(rquery); - if (results.RowCount() == 1){ - auto row = results.begin(); - std::string table_check = row[1]; - - if (table_check.find("character_data") == -1){ - runbotsconvert = 1; - printf("\n\n::: Legacy Bot Views and Function Detected... \n"); - printf("----------------------------------------------------------\n\n"); - printf(" Database currently has bot view/function linkage to obselete \n"); - printf(" table references and will now be converted...\n\n"); - printf(" It is recommended that you backup your database \n"); - printf(" before continuing the automatic conversion process...\n\n"); - printf("----------------------------------------------------------\n\n"); - std::cout << "Press ENTER to continue....." << std::endl << std::endl; - std::cin.ignore(1); - } - } - - if (runbotsconvert == 1){ - printf("Running bot views/function database conversion... \n"); - - /* Update view `vwbotcharactermobs` */ - rquery = StringFormat("DROP VIEW `vwBotCharacterMobs`;"); - results = QueryDatabase(rquery); - - rquery = StringFormat( - "CREATE VIEW `vwBotCharacterMobs` AS\n" - "SELECT _utf8'C' AS mobtype,\n" // Natedog: '_utf8' - "c.`id`,\n" - "c.`name`,\n" - "c.`class`,\n" - "c.`level`,\n" - "c.`last_login`,\n" - "c.`zone_id`\n" - "FROM `character_data` AS c\n" - "UNION ALL\n" - "SELECT _utf8'B' AS mobtype,\n" // Natedog: '_utf8' - "b.`BotID` AS id,\n" - "b.`Name` AS name,\n" - "b.`Class` AS class,\n" - "b.`BotLevel` AS level,\n" - "0 AS timelaston,\n" - "0 AS zoneid\n" - "FROM bots AS b;" - ); - results = QueryDatabase(rquery); - - - /* Update function `GetMobType` */ - rquery = StringFormat("DROP FUNCTION IF EXISTS `GetMobType`;"); - results = QueryDatabase(rquery); - - rquery = StringFormat( - "CREATE FUNCTION `GetMobType` (mobname VARCHAR(64)) RETURNS CHAR(1)\n" - "BEGIN\n" - " DECLARE Result CHAR(1);\n" - "\n" - " SET Result = NULL;\n" - "\n" - " IF (SELECT COUNT(*) FROM `character_data` WHERE `name` = mobname) > 0 THEN\n" - " SET Result = 'C';\n" - " ELSEIF (SELECT COUNT(*) FROM `bots` WHERE `Name` = mobname) > 0 THEN\n" - " SET Result = 'B';\n" - " END IF;\n " - "\n" - " RETURN Result;\n" - "END" - ); - results = QueryDatabase(rquery); - - - /* Update view `vwgroups` */ - rquery = StringFormat("DROP VIEW IF EXISTS `vwGroups`;"); - results = QueryDatabase(rquery); - - rquery = StringFormat( - "CREATE VIEW `vwGroups` AS\n" - "SELECT g.`groupid` AS groupid,\n" - "GetMobType(g.`name`) AS mobtype,\n" - "g.`name` AS name,\n" - "g.`charid` AS mobid,\n" - "IFNULL(c.`level`, b.`BotLevel`) AS level\n" - "FROM `group_id` AS g\n" - "LEFT JOIN `character_data` AS c ON g.`name` = c.`name`\n" - "LEFT JOIN `bots` AS b ON g.`name` = b.`Name`;" - ); - results = QueryDatabase(rquery); - - - /* Update view `vwbotgroups` */ - rquery = StringFormat("DROP VIEW IF EXISTS `vwBotGroups`;"); - results = QueryDatabase(rquery); - - rquery = StringFormat( - "CREATE VIEW `vwBotGroups` AS\n" - "SELECT g.`BotGroupId`,\n" - "g.`BotGroupName`,\n" - "g.`BotGroupLeaderBotId`,\n" - "b.`Name` AS BotGroupLeaderName,\n" - "b.`BotOwnerCharacterId`,\n" - "c.`name` AS BotOwnerCharacterName\n" - "FROM `botgroup` AS g\n" - "JOIN `bots` AS b ON g.`BotGroupLeaderBotId` = b.`BotID`\n" - "JOIN `character_data` AS c ON b.`BotOwnerCharacterID` = c.`id`\n" - "ORDER BY b.`BotOwnerCharacterId`, g.`BotGroupName`;" - ); - results = QueryDatabase(rquery); - - - /* Update view `vwguildmembers` */ - rquery = StringFormat("DROP VIEW IF EXISTS `vwGuildMembers`;"); - results = QueryDatabase(rquery); - - rquery = StringFormat( - "CREATE VIEW `vwGuildMembers` AS\n" - "SELECT 'C' AS mobtype,\n" - "cm.`char_id`,\n" - "cm.`guild_id`,\n" - "cm.`rank`,\n" - "cm.`tribute_enable`,\n" - "cm.`total_tribute`,\n" - "cm.`last_tribute`,\n" - "cm.`banker`,\n" - "cm.`public_note`,\n" - "cm.`alt`\n" - "FROM `guild_members` AS cm\n" - "UNION ALL\n" - "SELECT 'B' AS mobtype,\n" - "bm.`char_id`,\n" - "bm.`guild_id`,\n" - "bm.`rank`,\n" - "bm.`tribute_enable`,\n" - "bm.`total_tribute`,\n" - "bm.`last_tribute`,\n" - "bm.`banker`,\n" - "bm.`public_note`,\n" - "bm.`alt`\n" - "FROM `botguildmembers` AS bm;" - ); - results = QueryDatabase(rquery); - } - - if (runbotsconvert == 1){ - printf("\n\nBot views/function conversion complete, continuing world bootup...\n"); - } - -#endif - return true; -} - -bool Database::CheckDatabaseConvertCorpseDeblob(){ - Convert::DBPlayerCorpse_Struct_temp* dbpc; - Convert::classic_db_temp::DBPlayerCorpse_Struct_temp* dbpc_c; - uint32 in_datasize; - bool is_sof = false; - std::string c_type; - std::string scquery; - int8 first_entry = 0; - - std::string query = StringFormat("SHOW TABLES LIKE 'player_corpses'"); - auto results = QueryDatabase(query); - if (results.RowCount() != 0){ - query = StringFormat( - "CREATE TABLE `character_corpse_items` ( " - "`corpse_id` int(11) unsigned NOT NULL, " - "`equip_slot` int(11) unsigned NOT NULL, " - "`item_id` int(11) unsigned DEFAULT NULL, " - "`charges` int(11) unsigned DEFAULT NULL, " - "`aug_1` int(11) unsigned DEFAULT '0', " - "`aug_2` int(11) unsigned DEFAULT '0', " - "`aug_3` int(11) unsigned DEFAULT '0', " - "`aug_4` int(11) unsigned DEFAULT '0', " - "`aug_5` int(11) unsigned DEFAULT '0', " - "`aug_6` int(11) unsigned DEFAULT '0', " - "`attuned` smallint(5) NOT NULL DEFAULT '0', " - "PRIMARY KEY(`corpse_id`, `equip_slot`) " - ") ENGINE = InnoDB DEFAULT CHARSET = latin1; " - ); - results = QueryDatabase(query); - query = StringFormat("RENAME TABLE `player_corpses` TO `character_corpses`"); - results = QueryDatabase(query); - query = StringFormat( - " ALTER TABLE `character_corpses` \n" - " ADD COLUMN `is_locked` tinyint(11) NULL DEFAULT 0 AFTER `WasAtGraveyard`, \n" - " ADD COLUMN `exp` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `size` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `level` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `race` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `gender` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `class` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `deity` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `texture` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `helm_texture` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `copper` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `silver` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `gold` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `platinum` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `hair_color` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `beard_color` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `eye_color_1` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `eye_color_2` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `hair_style` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `face` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `beard` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `drakkin_heritage` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `drakkin_tattoo` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `drakkin_details` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `wc_1` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `wc_2` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `wc_3` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `wc_4` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `wc_5` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `wc_6` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `wc_7` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `wc_8` int(11) UNSIGNED NULL DEFAULT 0, \n" - " ADD COLUMN `wc_9` int(11) UNSIGNED NULL DEFAULT 0, \n" - " CHANGE COLUMN `zoneid` `zone_id` smallint(5) NOT NULL DEFAULT 0 AFTER `charname`, \n" - " CHANGE COLUMN `instanceid` `instance_id` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `zone_id`, \n" - " CHANGE COLUMN `timeofdeath` `time_of_death` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `data`, \n" - " CHANGE COLUMN `rezzed` `is_rezzed` tinyint(3) UNSIGNED NULL DEFAULT 0 AFTER `time_of_death`, \n" - " CHANGE COLUMN `IsBurried` `is_buried` tinyint(3) NOT NULL DEFAULT 0 AFTER `is_rezzed`; \n" - - ); - results = QueryDatabase(query); - query = StringFormat( - " ALTER TABLE `character_corpses` \n" - " CHANGE COLUMN `WasAtGraveyard` `was_at_graveyard` tinyint(3) NOT NULL DEFAULT 0 AFTER `is_buried` \n" - ); - results = QueryDatabase(query); - } - - std::string rquery = StringFormat("SHOW COLUMNS FROM `character_corpses` LIKE 'data'"); - results = QueryDatabase(rquery); - if (results.RowCount() != 0){ - rquery = StringFormat("SELECT DISTINCT charid FROM character_corpses"); - results = QueryDatabase(rquery); - for (auto row = results.begin(); row != results.end(); ++row) { - std::string squery = StringFormat("SELECT id, charname, data, time_of_death, is_rezzed FROM character_corpses WHERE `charid` = %i", atoi(row[0])); - auto results2 = QueryDatabase(squery); - for (auto row2 = results2.begin(); row2 != results2.end(); ++row2) { - in_datasize = results2.LengthOfColumn(2); - dbpc = (Convert::DBPlayerCorpse_Struct_temp*)row2[2]; - dbpc_c = (Convert::classic_db_temp::DBPlayerCorpse_Struct_temp*)row2[2]; - - if (dbpc == nullptr) - continue; - if (dbpc_c == nullptr) - continue; - - - /* SoF+ */ - uint32 esize1 = (sizeof(Convert::DBPlayerCorpse_Struct_temp) + (dbpc->itemcount * sizeof(Convert::player_lootitem_temp::ServerLootItem_Struct_temp))); - uint32 esize2 = (sizeof(Convert::classic_db_temp::DBPlayerCorpse_Struct_temp) + (dbpc_c->itemcount * sizeof(Convert::player_lootitem_temp::ServerLootItem_Struct_temp))); - - /* SoF */ - if (in_datasize == esize1) { - is_sof = true; - c_type = "SOF"; - } - /* Classic */ - if (in_datasize == esize2) { - is_sof = false; - c_type = "Legacy"; - } - if (in_datasize != esize2 && in_datasize != esize1) { - // std::cout << "[Error] in Corpse Size - OLD SIZE: " << esize1 << " SOF SIZE: " << esize2 << " db_blob_datasize: " << in_datasize << std::endl; - is_sof = false; - c_type = "NULL"; - continue; - } - std::cout << "Converting Corpse: [OK] [" << c_type << "]: " << "ID: " << atoi(row2[0]) << std::endl; - - if (is_sof){ - scquery = StringFormat("UPDATE `character_corpses` SET \n" - "`is_locked` = %d,\n" - "`exp` = %u,\n" - "`size` = %f,\n" - "`level` = %u,\n" - "`race` = %u,\n" - "`gender` = %u,\n" - "`class` = %u,\n" - "`deity` = %u,\n" - "`texture` = %u,\n" - "`helm_texture` = %u,\n" - "`copper` = %u,\n" - "`silver` = %u,\n" - "`gold` = %u,\n" - "`platinum` = %u,\n" - "`hair_color` = %u,\n" - "`beard_color` = %u,\n" - "`eye_color_1` = %u,\n" - "`eye_color_2` = %u,\n" - "`hair_style` = %u,\n" - "`face` = %u,\n" - "`beard` = %u,\n" - "`drakkin_heritage` = %u,\n" - "`drakkin_tattoo` = %u,\n" - "`drakkin_details` = %u,\n" - "`wc_1` = %u,\n" - "`wc_2` = %u,\n" - "`wc_3` = %u,\n" - "`wc_4` = %u,\n" - "`wc_5` = %u,\n" - "`wc_6` = %u,\n" - "`wc_7` = %u,\n" - "`wc_8` = %u,\n" - "`wc_9` = %u \n" - "WHERE `id` = %u \n", - dbpc->locked, - dbpc->exp, - dbpc->size, - dbpc->level, - dbpc->race, - dbpc->gender, - dbpc->class_, - dbpc->deity, - dbpc->texture, - dbpc->helmtexture, - dbpc->copper, - dbpc->silver, - dbpc->gold, - dbpc->plat, - dbpc->haircolor, - dbpc->beardcolor, - dbpc->eyecolor1, - dbpc->eyecolor2, - dbpc->hairstyle, - dbpc->face, - dbpc->beard, - dbpc->drakkin_heritage, - dbpc->drakkin_tattoo, - dbpc->drakkin_details, - dbpc->item_tint[0].color, - dbpc->item_tint[1].color, - dbpc->item_tint[2].color, - dbpc->item_tint[3].color, - dbpc->item_tint[4].color, - dbpc->item_tint[5].color, - dbpc->item_tint[6].color, - dbpc->item_tint[7].color, - dbpc->item_tint[8].color, - atoi(row2[0]) - ); - if (scquery != ""){ auto sc_results = QueryDatabase(scquery); } - - first_entry = 0; - scquery = ""; - /* Print Items */ - for (unsigned int i = 0; i < dbpc->itemcount; i++) { - if (first_entry != 1){ - scquery = StringFormat("REPLACE INTO `character_corpse_items` \n" - " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n" - " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", - atoi(row2[0]), - dbpc->items[i].equipSlot, - dbpc->items[i].item_id, - dbpc->items[i].charges, - dbpc->items[i].aug1, - dbpc->items[i].aug2, - dbpc->items[i].aug3, - dbpc->items[i].aug4, - dbpc->items[i].aug5, - dbpc->items[i].aug6, - dbpc->items[i].attuned - ); - first_entry = 1; - } - else{ - scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", - atoi(row2[0]), - dbpc->items[i].equipSlot, - dbpc->items[i].item_id, - dbpc->items[i].charges, - dbpc->items[i].aug1, - dbpc->items[i].aug2, - dbpc->items[i].aug3, - dbpc->items[i].aug4, - dbpc->items[i].aug5, - dbpc->items[i].aug6, - dbpc->items[i].attuned - ); - } - } - if (scquery != ""){ auto sc_results = QueryDatabase(scquery); } - } - else{ - /* Classic Converter */ - scquery = StringFormat("UPDATE `character_corpses` SET \n" - "`is_locked` = %d,\n" - "`exp` = %u,\n" - "`size` = %f,\n" - "`level` = %u,\n" - "`race` = %u,\n" - "`gender` = %u,\n" - "`class` = %u,\n" - "`deity` = %u,\n" - "`texture` = %u,\n" - "`helm_texture` = %u,\n" - "`copper` = %u,\n" - "`silver` = %u,\n" - "`gold` = %u,\n" - "`platinum` = %u,\n" - "`hair_color` = %u,\n" - "`beard_color` = %u,\n" - "`eye_color_1` = %u,\n" - "`eye_color_2` = %u,\n" - "`hair_style` = %u,\n" - "`face` = %u,\n" - "`beard` = %u,\n" - "`wc_1` = %u,\n" - "`wc_2` = %u,\n" - "`wc_3` = %u,\n" - "`wc_4` = %u,\n" - "`wc_5` = %u,\n" - "`wc_6` = %u,\n" - "`wc_7` = %u,\n" - "`wc_8` = %u,\n" - "`wc_9` = %u \n" - "WHERE `id` = %u \n", - dbpc_c->locked, - dbpc_c->exp, - dbpc_c->size, - dbpc_c->level, - dbpc_c->race, - dbpc_c->gender, - dbpc_c->class_, - dbpc_c->deity, - dbpc_c->texture, - dbpc_c->helmtexture, - dbpc_c->copper, - dbpc_c->silver, - dbpc_c->gold, - dbpc_c->plat, - dbpc_c->haircolor, - dbpc_c->beardcolor, - dbpc_c->eyecolor1, - dbpc_c->eyecolor2, - dbpc_c->hairstyle, - dbpc_c->face, - dbpc_c->beard, - dbpc_c->item_tint[0].color, - dbpc_c->item_tint[1].color, - dbpc_c->item_tint[2].color, - dbpc_c->item_tint[3].color, - dbpc_c->item_tint[4].color, - dbpc_c->item_tint[5].color, - dbpc_c->item_tint[6].color, - dbpc_c->item_tint[7].color, - dbpc_c->item_tint[8].color, - atoi(row2[0]) - ); - if (scquery != ""){ auto sc_results = QueryDatabase(scquery); } - - first_entry = 0; - scquery = ""; - - /* Print Items */ - for (unsigned int i = 0; i < dbpc_c->itemcount; i++) { - if (first_entry != 1){ - scquery = StringFormat("REPLACE INTO `character_corpse_items` \n" - " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n" - " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", - atoi(row2[0]), - dbpc_c->items[i].equipSlot, - dbpc_c->items[i].item_id, - dbpc_c->items[i].charges, - dbpc_c->items[i].aug1, - dbpc_c->items[i].aug2, - dbpc_c->items[i].aug3, - dbpc_c->items[i].aug4, - dbpc_c->items[i].aug5, - dbpc_c->items[i].aug6, - dbpc_c->items[i].attuned - ); - first_entry = 1; - } - else{ - scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", - atoi(row2[0]), - dbpc_c->items[i].equipSlot, - dbpc_c->items[i].item_id, - dbpc_c->items[i].charges, - dbpc_c->items[i].aug1, - dbpc_c->items[i].aug2, - dbpc_c->items[i].aug3, - dbpc_c->items[i].aug4, - dbpc_c->items[i].aug5, - dbpc_c->items[i].aug6, - dbpc_c->items[i].attuned - ); - } - } - if (scquery != ""){ auto sc_results = QueryDatabase(scquery); } - } - } - } - QueryDatabase(StringFormat("ALTER TABLE `character_corpses` DROP COLUMN `data`")); - } - return true; -} - bool Database::LoadVariables() { char *query = nullptr; @@ -2434,7 +857,6 @@ bool Database::LoadVariables() { if (!results.Success()) { - std::cerr << "Error in LoadVariables query '" << query << "' " << results.ErrorMessage() << std::endl; safe_delete_array(query); return false; } @@ -2449,7 +871,8 @@ uint32 Database::LoadVariables_MQ(char** query) } // always returns true? not sure about this. -bool Database::LoadVariables_result(MySQLRequestResult results) { +bool Database::LoadVariables_result(MySQLRequestResult results) +{ uint32 i = 0; LockMutex lock(&Mvarcache); @@ -2546,7 +969,6 @@ bool Database::SetVariable(const char* varname_in, const char* varvalue_in) { if (!results.Success()) { - std::cerr << "Error in SetVariable query '" << query << "' " << results.ErrorMessage() << std::endl; free(varname); free(varvalue); return false; @@ -2572,19 +994,15 @@ bool Database::SetVariable(const char* varname_in, const char* varvalue_in) { return true; } -uint32 Database::GetMiniLoginAccount(char* ip){ - - std::string query = StringFormat("SELECT id FROM account WHERE minilogin_ip='%s'", ip); +uint32 Database::GetMiniLoginAccount(char* ip) +{ + std::string query = StringFormat("SELECT `id` FROM `account` WHERE `minilogin_ip` = '%s'", ip); auto results = QueryDatabase(query); if (!results.Success()) - { - std::cerr << "Error in GetMiniLoginAccount query '" << query << "' " << results.ErrorMessage() << std::endl; return 0; - } - - auto row = results.begin(); + auto row = results.begin(); return atoi(row[0]); } @@ -2596,14 +1014,7 @@ bool Database::GetSafePoints(const char* short_name, uint32 version, float* safe auto results = QueryDatabase(query); if (!results.Success()) - { - std::cerr << "Error in GetSafePoint query '" << query << "' " << results.ErrorMessage() << std::endl; - std::cerr << "If it errors, run the following querys:\n"; - std::cerr << "ALTER TABLE `zone` CHANGE `minium_level` `min_level` TINYINT(3) UNSIGNED DEFAULT \"0\" NOT NULL;\n"; - std::cerr << "ALTER TABLE `zone` CHANGE `minium_status` `min_status` TINYINT(3) UNSIGNED DEFAULT \"0\" NOT NULL;\n"; - std::cerr << "ALTER TABLE `zone` ADD flag_needed VARCHAR(128) NOT NULL DEFAULT '';\n"; return false; - } if (results.RowCount() == 0) return false; @@ -2632,7 +1043,6 @@ bool Database::GetZoneLongName(const char* short_name, char** long_name, char* f auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error in GetZoneLongName query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } @@ -2671,10 +1081,7 @@ uint32 Database::GetZoneGraveyardID(uint32 zone_id, uint32 version) { auto results = QueryDatabase(query); if (!results.Success()) - { - std::cerr << "Error in GetZoneGraveyardID query '" << query << "' " << results.ErrorMessage() << std::endl; return 0; - } if (results.RowCount() == 0) return 0; @@ -2689,7 +1096,6 @@ bool Database::GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zon auto results = QueryDatabase(query); if (!results.Success()){ - std::cerr << "Error in GetZoneGraveyard query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } @@ -2719,7 +1125,6 @@ bool Database::LoadZoneNames() { if (!results.Success()) { - std::cerr << "Error in LoadZoneNames query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } @@ -2762,9 +1167,7 @@ uint8 Database::GetPEQZone(uint32 zoneID, uint32 version){ std::string query = StringFormat("SELECT peqzone from zone where zoneidnumber='%i' AND (version=%i OR version=0) ORDER BY version DESC", zoneID, version); auto results = QueryDatabase(query); - if (!results.Success()) - { - std::cerr << "Error in GetPEQZone query '" << query << "' " << results.ErrorMessage() << std::endl; + if (!results.Success()) { return 0; } @@ -2835,7 +1238,6 @@ bool Database::CheckNameFilter(const char* name, bool surname) if (!results.Success()) { - std::cerr << "Error in CheckNameFilter query '" << query << "' " << results.ErrorMessage() << std::endl; // false through to true? shouldn't it be falls through to false? return true; } @@ -2861,7 +1263,6 @@ bool Database::AddToNameFilter(const char* name) { if (!results.Success()) { - std::cerr << "Error in AddToNameFilter query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } @@ -2876,9 +1277,7 @@ uint32 Database::GetAccountIDFromLSID(uint32 iLSID, char* oAccountName, int16* o std::string query = StringFormat("SELECT id, name, status FROM account WHERE lsaccount_id=%i", iLSID); auto results = QueryDatabase(query); - if (!results.Success()) - { - std::cerr << "Error in GetAccountIDFromLSID query '" << query << "' " << results.ErrorMessage() << std::endl; + if (!results.Success()) { return 0; } @@ -2902,9 +1301,7 @@ void Database::GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus) { std::string query = StringFormat("SELECT name, status FROM account WHERE id=%i", id); auto results = QueryDatabase(query); - if (!results.Success()) - { - std::cerr << "Error in GetAccountFromID query '" << query << "' " << results.ErrorMessage() << std::endl; + if (!results.Success()){ return; } @@ -2920,12 +1317,7 @@ void Database::GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus) { } void Database::ClearMerchantTemp(){ - - std::string query("delete from merchantlist_temp"); - auto results = QueryDatabase(query); - - if (!results.Success()) - std::cerr << "Error in ClearMerchantTemp query '" << query << "' " << results.ErrorMessage() << std::endl; + QueryDatabase("DELETE FROM merchantlist_temp"); } bool Database::UpdateName(const char* oldname, const char* newname) { @@ -2947,7 +1339,6 @@ bool Database::CheckUsedName(const char* name) { std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name` = '%s'", name); auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error in CheckUsedName query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } @@ -2961,7 +1352,6 @@ uint8 Database::GetServerType() { std::string query("SELECT `value` FROM `variables` WHERE `varname` = 'ServerType' LIMIT 1"); auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error in GetServerType query '" << query << "' " << results.ErrorMessage() << std::endl; return 0; } @@ -2980,7 +1370,6 @@ bool Database::MoveCharacterToZone(const char* charname, const char* zonename, u auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error in MoveCharacterToZone(name) query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } @@ -2999,7 +1388,6 @@ bool Database::MoveCharacterToZone(uint32 iCharID, const char* iZonename) { auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error in MoveCharacterToZone(id) query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } @@ -3011,7 +1399,6 @@ bool Database::SetHackerFlag(const char* accountname, const char* charactername, auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error in SetHackerFlag query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } @@ -3025,7 +1412,6 @@ bool Database::SetMQDetectionFlag(const char* accountname, const char* character if (!results.Success()) { - std::cerr << "Error in SetMQDetectionFlag query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } @@ -3105,7 +1491,6 @@ uint32 Database::GetCharacterInfo(const char* iName, uint32* oAccID, uint32* oZo auto results = QueryDatabase(query); if (!results.Success()) { - std::cerr << "Error in GetCharacterInfo query '" << query << "' " << results.ErrorMessage() << std::endl; return 0; } @@ -3129,9 +1514,7 @@ bool Database::UpdateLiveChar(char* charname,uint32 lsaccount_id) { std::string query = StringFormat("UPDATE account SET charname='%s' WHERE id=%i;",charname, lsaccount_id); auto results = QueryDatabase(query); - if (!results.Success()) - { - std::cerr << "Error in UpdateLiveChar query '" << query << "' " << results.ErrorMessage() << std::endl; + if (!results.Success()){ return false; } @@ -3145,7 +1528,6 @@ bool Database::GetLiveChar(uint32 account_id, char* cname) { if (!results.Success()) { - std::cerr << "Error in GetLiveChar query '" << query << "' " << results.ErrorMessage() << std::endl; return false; } @@ -3160,30 +1542,22 @@ bool Database::GetLiveChar(uint32 account_id, char* cname) { void Database::SetLFP(uint32 CharID, bool LFP) { std::string query = StringFormat("UPDATE `character_data` SET `lfp` = %i WHERE `id` = %i",LFP, CharID); - auto results = QueryDatabase(query); - if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error updating LFP for character %i : %s", CharID, results.ErrorMessage().c_str()); + QueryDatabase(query); } void Database::SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon) { std::string query = StringFormat("update `character_data` SET `lfp` = %i, `lfg` = %i, `firstlogon` = %i WHERE `id` = %i",LFP, LFG, firstlogon, CharID); - auto results = QueryDatabase(query); - if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error updating LFP for character %i : %s", CharID, results.ErrorMessage().c_str()); + QueryDatabase(query); } void Database::SetLFG(uint32 CharID, bool LFG) { std::string query = StringFormat("update `character_data` SET `lfg` = %i WHERE `id` = %i",LFG, CharID); - auto results = QueryDatabase(query); - if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error updating LFP for character %i : %s", CharID, results.ErrorMessage().c_str()); + QueryDatabase(query); } void Database::SetFirstLogon(uint32 CharID, uint8 firstlogon) { std::string query = StringFormat( "UPDATE `character_data` SET `firstlogon` = %i WHERE `id` = %i",firstlogon, CharID); - auto results = QueryDatabase(query); - if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error updating firstlogon for character %i : %s", CharID, results.ErrorMessage().c_str()); + QueryDatabase(query); } void Database::AddReport(std::string who, std::string against, std::string lines) { @@ -3191,11 +1565,8 @@ void Database::AddReport(std::string who, std::string against, std::string lines DoEscapeString(escape_str, lines.c_str(), lines.size()); std::string query = StringFormat("INSERT INTO reports (name, reported, reported_text) VALUES('%s', '%s', '%s')", who.c_str(), against.c_str(), escape_str); - auto results = QueryDatabase(query); + QueryDatabase(query); safe_delete_array(escape_str); - - if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error adding a report for %s: %s", who.c_str(), results.ErrorMessage().c_str()); } void Database::SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc) { @@ -3206,27 +1577,20 @@ void Database::SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ism auto results = QueryDatabase(query); if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error deleting character from group id: %s", results.ErrorMessage().c_str()); + Log.Out(Logs::General, Logs::Error, "Error deleting character from group id: %s", results.ErrorMessage().c_str()); return; } /* Add to the Group */ query = StringFormat("REPLACE INTO `group_id` SET `charid` = %i, `groupid` = %i, `name` = '%s', `ismerc` = '%i'", charid, id, name, ismerc); - auto results = QueryDatabase(query); - - if (!results.Success()) - LogFile->write(EQEMuLog::Error, "Error adding character to group id: %s", results.ErrorMessage().c_str()); + QueryDatabase(query); } void Database::ClearAllGroups(void) { - std::string query("delete from group_id"); - auto results = QueryDatabase(query); - - if (!results.Success()) - std::cout << "Unable to clear groups: " << results.ErrorMessage() << std::endl; - + std::string query("DELETE FROM `group_id`"); + QueryDatabase(query); return; } @@ -3242,26 +1606,21 @@ void Database::ClearGroup(uint32 gid) { //clear a specific group std::string query = StringFormat("delete from group_id where groupid = %lu", (unsigned long)gid); - auto results = QueryDatabase(query); - - if (!results.Success()) - std::cout << "Unable to clear groups: " << results.ErrorMessage() << std::endl; + QueryDatabase(query); } -uint32 Database::GetGroupID(const char* name){ - +uint32 Database::GetGroupID(const char* name){ std::string query = StringFormat("SELECT groupid from group_id where name='%s'", name); auto results = QueryDatabase(query); - if (!results.Success()) - { - LogFile->write(EQEMuLog::Error, "Error getting group id: %s", results.ErrorMessage().c_str()); + if (!results.Success()) { return 0; } if (results.RowCount() == 0) { - LogFile->write(EQEMuLog::Debug, "Character not in a group: %s", name); + // Commenting this out until logging levels can prevent this from going to console + //Log.Out(Logs::General, Logs::None,, "Character not in a group: %s", name); return 0; } @@ -3303,12 +1662,12 @@ void Database::SetGroupLeaderName(uint32 gid, const char* name) { return; } - query = StringFormat("INSERT INTO group_leaders(gid, leadername, marknpc, leadershipaa, maintank, assist, puller, mentoree, mentor_percent) VALUES(%u, '%s', '', '', '', '', '', '', '0')", + query = StringFormat("REPLACE INTO group_leaders(gid, leadername, marknpc, leadershipaa, maintank, assist, puller, mentoree, mentor_percent) VALUES(%u, '%s', '', '', '', '', '', '', '0')", gid, EscapeString(name).c_str()); result = QueryDatabase(query); if(!result.Success()) { - LogFile->write(EQEMuLog::Debug, "Error in Database::SetGroupLeaderName: %s", result.ErrorMessage().c_str()); + Log.Out(Logs::General, Logs::None, "Error in Database::SetGroupLeaderName: %s", result.ErrorMessage().c_str()); } } @@ -3472,22 +1831,17 @@ void Database::ClearRaidDetails(uint32 rid) { // returns 0 on error or no raid for that character, or // the raid id that the character is a member of. -uint32 Database::GetRaidID(const char* name){ - - std::string query = StringFormat("SELECT raidid from raid_members where name='%s'", name); +uint32 Database::GetRaidID(const char* name) +{ + std::string query = StringFormat("SELECT `raidid` FROM `raid_members` WHERE `name` = '%s'", name); auto results = QueryDatabase(query); - if (!results.Success()) - { - std::cout << "Unable to get raid id: " << results.ErrorMessage() << std::endl; + if (!results.Success()) { return 0; } - auto row = results.begin(); - - if (row == results.end()) - { - std::cout << "Unable to get raid id, char not found!" << std::endl; + auto row = results.begin(); + if (row == results.end()) { return 0; } @@ -3497,7 +1851,7 @@ uint32 Database::GetRaidID(const char* name){ return 0; } -const char* Database::GetRaidLeaderName(uint32 rid) +const char* Database::GetRaidLeaderName(uint32 raid_id) { // Would be a good idea to fix this to be a passed in variable and // make the caller responsible. static local variables like this are @@ -3506,20 +1860,17 @@ const char* Database::GetRaidLeaderName(uint32 rid) // but may not be fully supported in some compilers. static char name[128]; - std::string query = StringFormat("SELECT name FROM raid_members WHERE raidid=%u AND israidleader=1",rid); + std::string query = StringFormat("SELECT `name` FROM `raid_members` WHERE `raidid` = %u AND `israidleader` = 1", raid_id); auto results = QueryDatabase(query); - if (!results.Success()) - { - std::cout << "Unable to get raid id: " << results.ErrorMessage() << std::endl; + if (!results.Success()) { + Log.Out(Logs::General, Logs::Debug, "Unable to get Raid Leader Name for Raid ID: %u", raid_id); return "UNKNOWN"; } auto row = results.begin(); - if (row == results.end()) - { - std::cout << "Unable to get raid id, char not found!" << std::endl; + if (row == results.end()) { return "UNKNOWN"; } @@ -3640,13 +1991,10 @@ void Database::SetRaidGroupLeaderInfo(uint32 gid, uint32 rid) if (results.RowsAffected() != 0) return; - query = StringFormat("INSERT INTO raid_leaders(gid, rid, marknpc, leadershipaa, maintank, assist, puller, mentoree, mentor_percent) VALUES(%lu, %lu, '', '', '', '', '', '', 0)", + query = StringFormat("REPLACE INTO raid_leaders(gid, rid, marknpc, leadershipaa, maintank, assist, puller, mentoree, mentor_percent) VALUES(%lu, %lu, '', '', '', '', '', '', 0)", (unsigned long)gid, (unsigned long)rid); results = QueryDatabase(query); - if (!results.Success()) - std::cout << "Unable to set raid/group leader: " << results.ErrorMessage() << std::endl; - return; } @@ -3654,11 +2002,7 @@ void Database::SetRaidGroupLeaderInfo(uint32 gid, uint32 rid) void Database::ClearAllRaidLeaders(void) { std::string query("DELETE from raid_leaders"); - auto results = QueryDatabase(query); - - if (!results.Success()) - std::cout << "Unable to clear raid leaders: " << results.ErrorMessage() << std::endl; - + QueryDatabase(query); return; } @@ -3669,494 +2013,13 @@ void Database::ClearRaidLeader(uint32 gid, uint32 rid) return; } - std::string query = StringFormat("DELETE from raid_leaders where gid = %lu and rid = %lu", - (unsigned long)gid, (unsigned long)rid); - auto results = QueryDatabase(query); - - if (!results.Success()) - std::cout << "Unable to clear raid leader: " << results.ErrorMessage() << std::endl; -} - -bool Database::VerifyInstanceAlive(uint16 instance_id, uint32 char_id) -{ - //we are not saved to this instance so set our instance to 0 - if(!GlobalInstance(instance_id) && !CharacterInInstanceGroup(instance_id, char_id)) - return false; - - if(CheckInstanceExpired(instance_id)) - { - DeleteInstance(instance_id); - return false; - } - - return true; -} - -bool Database::VerifyZoneInstance(uint32 zone_id, uint16 instance_id) -{ - - std::string query = StringFormat("SELECT id FROM instance_list where id=%u AND zone=%u",instance_id, zone_id); - auto results = QueryDatabase(query); - - if (!results.Success()) - return false; - - if (results.RowCount() == 0) - return false; - - return true; -} - -bool Database::CharacterInInstanceGroup(uint16 instance_id, uint32 char_id) -{ - - std::string query = StringFormat("SELECT charid FROM instance_list_player where id=%u AND charid=%u",instance_id, char_id); - auto results = QueryDatabase(query); - - if (!results.Success()) - return false; - - if (results.RowCount() != 1) - return false; - - return true; -} - -void Database::DeleteInstance(uint16 instance_id) -{ - - std::string query = StringFormat("DELETE FROM instance_list WHERE id=%u", instance_id); + std::string query = StringFormat("DELETE from raid_leaders where gid = %lu and rid = %lu", (unsigned long)gid, (unsigned long)rid); QueryDatabase(query); - - query = StringFormat("DELETE FROM instance_list_player WHERE id=%u", instance_id); - QueryDatabase(query); - - query = StringFormat("DELETE FROM respawn_times WHERE instance_id=%u", instance_id); - QueryDatabase(query); - - query = StringFormat("DELETE FROM spawn_condition_values WHERE instance_id=%u", instance_id); - QueryDatabase(query); - - BuryCorpsesInInstance(instance_id); -} - -bool Database::CheckInstanceExpired(uint16 instance_id) -{ - - int32 start_time = 0; - int32 duration = 0; - uint32 never_expires = 0; - - std::string query = StringFormat("SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u", instance_id); - auto results = QueryDatabase(query); - - if (!results.Success()) - return true; - - if (results.RowCount() == 0) - return true; - - auto row = results.begin(); - - start_time = atoi(row[0]); - duration = atoi(row[1]); - never_expires = atoi(row[2]); - - if(never_expires == 1) - return false; - - timeval tv; - gettimeofday(&tv, nullptr); - - if((start_time + duration) <= tv.tv_sec) - return true; - - return false; -} - -uint32 Database::ZoneIDFromInstanceID(uint16 instance_id) -{ - - std::string query = StringFormat("SELECT zone FROM instance_list where id=%u", instance_id); - auto results = QueryDatabase(query); - - if (!results.Success()) - return 0; - - if (results.RowCount() == 0) - return 0; - - auto row = results.begin(); - - return atoi(row[0]); -} - -uint32 Database::VersionFromInstanceID(uint16 instance_id) -{ - - std::string query = StringFormat("SELECT version FROM instance_list where id=%u", instance_id); - auto results = QueryDatabase(query); - - if (!results.Success()) - return 0; - - if (results.RowCount() == 0) - return 0; - - auto row = results.begin(); - - return atoi(row[0]); -} - -uint32 Database::GetTimeRemainingInstance(uint16 instance_id, bool &is_perma) -{ - uint32 start_time = 0; - uint32 duration = 0; - uint32 never_expires = 0; - - std::string query = StringFormat("SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u", instance_id); - auto results = QueryDatabase(query); - - if (!results.Success()) - { - is_perma = false; - return 0; - } - - if (results.RowCount() == 0) - { - is_perma = false; - return 0; - } - - auto row = results.begin(); - - start_time = atoi(row[0]); - duration = atoi(row[1]); - never_expires = atoi(row[2]); - - if(never_expires == 1) - { - is_perma = true; - return 0; - } - - is_perma = false; - - timeval tv; - gettimeofday(&tv, nullptr); - return ((start_time + duration) - tv.tv_sec); -} - -bool Database::GetUnusedInstanceID(uint16 &instance_id) -{ - uint32 count = RuleI(Zone, ReservedInstances); - uint32 max = 65535; - - std::string query = StringFormat("SELECT IFNULL(MAX(id),%u)+1 FROM instance_list WHERE id > %u", count, count); - auto results = QueryDatabase(query); - - if (!results.Success()) - { - instance_id = 0; - return false; - } - - if (results.RowCount() == 0) - { - instance_id = 0; - return false; - } - - auto row = results.begin(); - - if (atoi(row[0]) <= max) - { - instance_id = atoi(row[0]); - return true; - } - - query = StringFormat("SELECT id FROM instance_list where id > %u ORDER BY id", count); - results = QueryDatabase(query); - - if (!results.Success()) - { - instance_id = 0; - return false; - } - - if (results.RowCount() == 0) - { - instance_id = 0; - return false; - } - - count++; - for (auto row = results.begin();row != results.end();++row) - { - if(count < atoi(row[0])) - { - instance_id = count; - return true; - } - - if(count > max) - { - instance_id = 0; - return false; - } - - count++; - } - - instance_id = count; - return true; -} - -//perhaps purge any expireds too -bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration) -{ - - std::string query = StringFormat("INSERT INTO instance_list (id, zone, version, start_time, duration)" - " values(%lu, %lu, %lu, UNIX_TIMESTAMP(), %lu)", - (unsigned long)instance_id, (unsigned long)zone_id, (unsigned long)version, (unsigned long)duration); - auto results = QueryDatabase(query); - - return results.Success(); -} - -void Database::PurgeExpiredInstances() -{ - - std::string query("SELECT id FROM instance_list where (start_time+duration) <= UNIX_TIMESTAMP() and never_expires = 0"); - auto results = QueryDatabase(query); - - if (!results.Success()) - return; - - if (results.RowCount() == 0) - return; - - for (auto row = results.begin();row != results.end();++row) - DeleteInstance(atoi(row[0])); -} - -bool Database::AddClientToInstance(uint16 instance_id, uint32 char_id) -{ - std::string query = StringFormat("INSERT INTO instance_list_player(id, charid) values(%lu, %lu)", - (unsigned long)instance_id, (unsigned long)char_id); - auto results = QueryDatabase(query); - - return results.Success(); -} - -bool Database::RemoveClientFromInstance(uint16 instance_id, uint32 char_id) -{ - - std::string query = StringFormat("DELETE FROM instance_list_player WHERE id=%lu AND charid=%lu", - (unsigned long)instance_id, (unsigned long)char_id); - auto results = QueryDatabase(query); - - return results.Success(); -} - -bool Database::RemoveClientsFromInstance(uint16 instance_id) -{ - std::string query = StringFormat("DELETE FROM instance_list_player WHERE id=%lu", (unsigned long)instance_id); - auto results = QueryDatabase(query); - - return results.Success(); -} - -bool Database::CheckInstanceExists(uint16 instance_id) { - std::string query = StringFormat("SELECT * FROM instance_list where id=%u", instance_id); - auto results = QueryDatabase(query); - - if (!results.Success()) - return false; - - if (results.RowCount() == 0) - return false; - - return true; -} - -void Database::BuryCorpsesInInstance(uint16 instance_id) { - std::string query = StringFormat("UPDATE `character_corpses` SET `is_buried` = 1, `instance_id` =0 WHERE `instance_id` = %u", instance_id); - auto results = QueryDatabase(query); -} - -uint16 Database::GetInstanceVersion(uint16 instance_id) { - if(instance_id == 0) - return 0; - - std::string query = StringFormat("SELECT version FROM instance_list where id=%u", instance_id); - auto results = QueryDatabase(query); - - if (!results.Success()) - return 0; - - if (results.RowCount() == 0) - return 0; - - auto row = results.begin(); - return atoi(row[0]); -} - -uint16 Database::GetInstanceID(const char* zone, uint32 charid, int16 version) { - - std::string query = StringFormat("SELECT instance_list.id FROM instance_list, instance_list_player " - "WHERE instance_list.zone=%u AND instance_list.version=%u AND instance_list.id=instance_list_player.id AND " - "instance_list_player.charid=%u LIMIT 1;", GetZoneID(zone), version, charid, charid); - auto results = QueryDatabase(query); - - if (!results.Success()) - return 0; - - if (results.RowCount() == 0) - return 0; - - auto row = results.begin(); - return atoi(row[0]); -} - -uint16 Database::GetInstanceID(uint32 zone, uint32 charid, int16 version) -{ - if(!zone) - return 0; - - std::string query = StringFormat("SELECT instance_list.id FROM instance_list, instance_list_player " - "WHERE instance_list.zone=%u AND instance_list.version=%u AND instance_list.id=instance_list_player.id AND " - "instance_list_player.charid=%u LIMIT 1;", zone, version, charid); - auto results = QueryDatabase(query); - - if (!results.Success()) - return 0; - - if (results.RowCount() == 0) - return 0; - - auto row = results.begin(); - - return atoi(row[0]); -} - -void Database::GetCharactersInInstance(uint16 instance_id, std::list &charid_list) { - - std::string query = StringFormat("SELECT charid FROM instance_list_player WHERE id=%u", instance_id); - auto results = QueryDatabase(query); - - if (!results.Success()) - { - LogFile->write(EQEMuLog::Error, "Error in GetCharactersInInstace query '%s': %s", query.c_str(), results.ErrorMessage().c_str()); - return; - } - - for(auto row=results.begin();row != results.end();++row) - charid_list.push_back(atoi(row[0])); -} - -void Database::AssignGroupToInstance(uint32 gid, uint32 instance_id) -{ - - uint32 zone_id = ZoneIDFromInstanceID(instance_id); - uint16 version = VersionFromInstanceID(instance_id); - - std::string query = StringFormat("SELECT charid FROM group_id WHERE groupid=%u", gid); - auto results = QueryDatabase(query); - - if (!results.Success()) - return; - - for (auto row=results.begin();row != results.end();++row) - { - uint32 charid = atoi(row[0]); - if(GetInstanceID(zone_id, charid, version) == 0) - AddClientToInstance(instance_id, charid); - } -} - -void Database::AssignRaidToInstance(uint32 rid, uint32 instance_id) -{ - - uint32 zone_id = ZoneIDFromInstanceID(instance_id); - uint16 version = VersionFromInstanceID(instance_id); - - std::string query = StringFormat("SELECT charid FROM raid_members WHERE raidid=%u", rid); - auto results = QueryDatabase(query); - - if (!results.Success()) - return; - - for (auto row=results.begin();row!=results.end();++row) - { - uint32 charid = atoi(row[0]); - if(GetInstanceID(zone_id, charid, version) == 0) - AddClientToInstance(instance_id, charid); - } -} - -void Database::FlagInstanceByGroupLeader(uint32 zone, int16 version, uint32 charid, uint32 gid) -{ - uint16 id = GetInstanceID(zone, charid, version); - if(id != 0) - return; - - char ln[128]; - memset(ln, 0, 128); - strcpy(ln, GetGroupLeadershipInfo(gid, ln)); - uint32 l_charid = GetCharacterID((const char*)ln); - uint16 l_id = GetInstanceID(zone, l_charid, version); - - if(l_id == 0) - return; - - AddClientToInstance(l_id, charid); -} - -void Database::FlagInstanceByRaidLeader(uint32 zone, int16 version, uint32 charid, uint32 rid) -{ - uint16 id = GetInstanceID(zone, charid, version); - if(id != 0) - return; - - uint32 l_charid = GetCharacterID(GetRaidLeaderName(rid)); - uint16 l_id = GetInstanceID(zone, l_charid, version); - - if(l_id == 0) - return; - - AddClientToInstance(l_id, charid); -} - -void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration) -{ - - std::string query = StringFormat("UPDATE `instance_list` SET start_time=UNIX_TIMESTAMP(), " - "duration=%u WHERE id=%u", new_duration, instance_id); - auto results = QueryDatabase(query); -} - -bool Database::GlobalInstance(uint16 instance_id) -{ - - std::string query = StringFormat("SELECT is_global from instance_list where id=%u LIMIT 1", instance_id); - auto results = QueryDatabase(query); - - if (!results.Success()) - return false; - - if (results.RowCount() == 0) - return false; - - auto row = results.begin(); - - return (atoi(row[0]) == 1) ? true : false; } void Database::UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win) { - + std::string field; switch(theme) @@ -4209,9 +2072,24 @@ void Database::UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win) bool Database::GetAdventureStats(uint32 char_id, AdventureStats_Struct *as) { - - std::string query = StringFormat("SELECT `guk_wins`, `mir_wins`, `mmc_wins`, `ruj_wins`, `tak_wins`, `guk_losses`, " - "`mir_losses`, `mmc_losses`, `ruj_losses`, `tak_losses` FROM `adventure_stats` WHERE player_id=%u", char_id); + std::string query = StringFormat( + "SELECT " + "`guk_wins`, " + "`mir_wins`, " + "`mmc_wins`, " + "`ruj_wins`, " + "`tak_wins`, " + "`guk_losses`, " + "`mir_losses`, " + "`mmc_losses`, " + "`ruj_losses`, " + "`tak_losses` " + "FROM " + "`adventure_stats` " + "WHERE " + "player_id = %u ", + char_id + ); auto results = QueryDatabase(query); if (!results.Success()) @@ -4238,17 +2116,13 @@ bool Database::GetAdventureStats(uint32 char_id, AdventureStats_Struct *as) return true; } -uint32 Database::GetGuildIDByCharID(uint32 char_id) +uint32 Database::GetGuildIDByCharID(uint32 character_id) { - - std::string query = StringFormat("SELECT guild_id FROM guild_members WHERE char_id='%i'", char_id); + std::string query = StringFormat("SELECT guild_id FROM guild_members WHERE char_id='%i'", character_id); auto results = QueryDatabase(query); if (!results.Success()) - { - std::cerr << "Error in GetGuildIDByChar query '" << query << "' " << results.ErrorMessage() << std::endl; return 0; - } if (results.RowCount() == 0) return 0; @@ -4256,3 +2130,46 @@ uint32 Database::GetGuildIDByCharID(uint32 char_id) auto row = results.begin(); return atoi(row[0]); } + +void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) +{ + std::string query = + "SELECT " + "log_category_id, " + "log_category_description, " + "log_to_console, " + "log_to_file, " + "log_to_gmsay " + "FROM " + "logsys_categories " + "ORDER BY log_category_id"; + auto results = QueryDatabase(query); + + int log_category = 0; + Log.file_logs_enabled = false; + + for (auto row = results.begin(); row != results.end(); ++row) { + log_category = atoi(row[0]); + log_settings[log_category].log_to_console = atoi(row[2]); + log_settings[log_category].log_to_file = atoi(row[3]); + log_settings[log_category].log_to_gmsay = atoi(row[4]); + + /* Determine if any output method is enabled for the category + and set it to 1 so it can used to check if category is enabled */ + const bool log_to_console = log_settings[log_category].log_to_console > 0; + const bool log_to_file = log_settings[log_category].log_to_file > 0; + const bool log_to_gmsay = log_settings[log_category].log_to_gmsay > 0; + const bool is_category_enabled = log_to_console || log_to_file || log_to_gmsay; + + if (is_category_enabled) + log_settings[log_category].is_category_enabled = 1; + + /* + This determines whether or not the process needs to actually file log anything. + If we go through this whole loop and nothing is set to any debug level, there is no point to create a file or keep anything open + */ + if (log_settings[log_category].log_to_file > 0){ + Log.file_logs_enabled = true; + } + } +} \ No newline at end of file diff --git a/common/database.h b/common/database.h index 5be342482..f3b8ba8c1 100644 --- a/common/database.h +++ b/common/database.h @@ -21,7 +21,8 @@ #define AUTHENTICATION_TIMEOUT 60 #define INVALID_ID 0xFFFFFFFF -#include "debug.h" +#include "global_define.h" +#include "eqemu_logsys.h" #include "types.h" #include "dbcore.h" #include "linked_list.h" @@ -52,9 +53,9 @@ struct EventLogDetails_Struct { }; struct CharacterEventLog_Struct { -uint32 count; -uint8 eventid; -EventLogDetails_Struct eld[255]; + uint32 count; + uint8 eventid; + EventLogDetails_Struct eld[255]; }; struct npcDecayTimes_Struct { @@ -71,412 +72,16 @@ struct VarCache_Struct { class PTimerList; -#pragma pack(1) - -/* Conversion Structs */ - -namespace Convert { - struct BindStruct { - /*000*/ uint32 zoneId; - /*004*/ float x; - /*008*/ float y; - /*012*/ float z; - /*016*/ float heading; - }; - struct Color_Struct - { - union - { - struct - { - uint8 blue; - uint8 green; - uint8 red; - uint8 use_tint; // if there's a tint this is FF - } rgb; - uint32 color; - }; - }; - struct AA_Array - { - uint32 AA; - uint32 value; - }; - struct SpellBuff_Struct - { - /*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise - /*001*/ uint8 level; - /*002*/ uint8 bard_modifier; - /*003*/ uint8 effect; //not real - /*004*/ uint32 spellid; - /*008*/ uint32 duration; - /*012*/ uint32 counters; - /*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages - /*020*/ - }; - struct Tribute_Struct { - uint32 tribute; - uint32 tier; - }; - struct Disciplines_Struct { - uint32 values[MAX_PP_DISCIPLINES]; - }; - struct GroupLeadershipAA_Struct { - union { - struct { - uint32 groupAAMarkNPC; - uint32 groupAANPCHealth; - uint32 groupAADelegateMainAssist; - uint32 groupAADelegateMarkNPC; - uint32 groupAA4; - uint32 groupAA5; - uint32 groupAAInspectBuffs; - uint32 groupAA7; - uint32 groupAASpellAwareness; - uint32 groupAAOffenseEnhancement; - uint32 groupAAManaEnhancement; - uint32 groupAAHealthEnhancement; - uint32 groupAAHealthRegeneration; - uint32 groupAAFindPathToPC; - uint32 groupAAHealthOfTargetsTarget; - uint32 groupAA15; - }; - uint32 ranks[MAX_GROUP_LEADERSHIP_AA_ARRAY]; - }; - }; - - struct RaidLeadershipAA_Struct { - union { - struct { - uint32 raidAAMarkNPC; - uint32 raidAANPCHealth; - uint32 raidAADelegateMainAssist; - uint32 raidAADelegateMarkNPC; - uint32 raidAA4; - uint32 raidAA5; - uint32 raidAA6; - uint32 raidAASpellAwareness; - uint32 raidAAOffenseEnhancement; - uint32 raidAAManaEnhancement; - uint32 raidAAHealthEnhancement; - uint32 raidAAHealthRegeneration; - uint32 raidAAFindPathToPC; - uint32 raidAAHealthOfTargetsTarget; - uint32 raidAA14; - uint32 raidAA15; - }; - uint32 ranks[MAX_RAID_LEADERSHIP_AA_ARRAY]; - }; - }; - - struct LeadershipAA_Struct { - union { - struct { - Convert::GroupLeadershipAA_Struct group; - Convert::RaidLeadershipAA_Struct raid; - }; - uint32 ranks[MAX_LEADERSHIP_AA_ARRAY]; - }; - }; - typedef struct - { - /*00*/ char Name[64]; - /*64*/ uint32 Level; - /*68*/ uint32 Race; - /*72*/ uint32 Class; - /*76*/ uint32 Zone; - /*80*/ uint32 Time; - /*84*/ uint32 Points; - /*88*/ - } PVPStatsEntry_Struct; - struct BandolierItem_Struct { - uint32 item_id; - uint32 icon; - char item_name[64]; - }; - struct Bandolier_Struct { - char name[32]; - Convert::BandolierItem_Struct items[EmuConstants::BANDOLIER_SIZE]; - }; - struct PotionBelt_Struct { - Convert::BandolierItem_Struct items[EmuConstants::POTION_BELT_SIZE]; - }; - struct SuspendedMinion_Struct - { - /*000*/ uint16 SpellID; - /*002*/ uint32 HP; - /*006*/ uint32 Mana; - /*010*/ Convert::SpellBuff_Struct Buffs[BUFF_COUNT]; - /*510*/ uint32 Items[_MaterialCount]; - /*546*/ char Name[64]; - /*610*/ - }; - - struct PlayerProfile_Struct { - /*0000*/ uint32 checksum; // Checksum from CRC32::SetEQChecksum - /*0004*/ char name[64]; // Name of player sizes not right - /*0068*/ char last_name[32]; // Last name of player sizes not right - /*0100*/ uint32 gender; // Player Gender - 0 Male, 1 Female - /*0104*/ uint32 race; // Player race - /*0108*/ uint32 class_; // Player class - /*0112*/ uint32 unknown0112; // - /*0116*/ uint32 level; // Level of player (might be one byte) - /*0120*/ Convert::BindStruct binds[5]; // Bind points (primary is first, home city is fifth) - /*0220*/ uint32 deity; // deity - /*0224*/ uint32 guild_id; - /*0228*/ uint32 birthday; // characters bday - /*0232*/ uint32 lastlogin; // last login or zone time - /*0236*/ uint32 timePlayedMin; // in minutes - /*0240*/ uint8 pvp; - /*0241*/ uint8 level2; //no idea why this is here, but thats how it is on live - /*0242*/ uint8 anon; // 2=roleplay, 1=anon, 0=not anon - /*0243*/ uint8 gm; - /*0244*/ uint8 guildrank; - /*0245*/ uint8 guildbanker; - /*0246*/ uint8 unknown0246[6]; // - /*0252*/ uint32 intoxication; - /*0256*/ uint32 spellSlotRefresh[MAX_PP_REF_MEMSPELL]; //in ms - /*0292*/ uint32 abilitySlotRefresh; - /*0296*/ uint8 haircolor; // Player hair color - /*0297*/ uint8 beardcolor; // Player beard color - /*0298*/ uint8 eyecolor1; // Player left eye color - /*0299*/ uint8 eyecolor2; // Player right eye color - /*0300*/ uint8 hairstyle; // Player hair style - /*0301*/ uint8 beard; // Beard type - /*0302*/ uint8 ability_time_seconds; //The following four spots are unknown right now..... - /*0303*/ uint8 ability_number; //ability used - /*0304*/ uint8 ability_time_minutes; - /*0305*/ uint8 ability_time_hours; //place holder - /*0306*/ uint8 unknown0306[6]; // @bp Spacer/Flag? - /*0312*/ uint32 item_material[_MaterialCount]; // Item texture/material of worn/held items - /*0348*/ uint8 unknown0348[44]; - /*0392*/ Convert::Color_Struct item_tint[_MaterialCount]; - /*0428*/ Convert::AA_Array aa_array[MAX_PP_AA_ARRAY]; - /*2348*/ float unknown2384; //seen ~128, ~47 - /*2352*/ char servername[32]; // length probably not right - /*2384*/ char title[32]; // length might be wrong - /*2416*/ char suffix[32]; // length might be wrong - /*2448*/ uint32 guildid2; // - /*2452*/ uint32 exp; // Current Experience - /*2456*/ uint32 unknown2492; - /*2460*/ uint32 points; // Unspent Practice points - /*2464*/ uint32 mana; // current mana - /*2468*/ uint32 cur_hp; // current hp - /*2472*/ uint32 unknown2508; // 0x05 - /*2476*/ uint32 STR; // Strength - /*2480*/ uint32 STA; // Stamina - /*2484*/ uint32 CHA; // Charisma - /*2488*/ uint32 DEX; // Dexterity - /*2492*/ uint32 INT; // Intelligence - /*2496*/ uint32 AGI; // Agility - /*2500*/ uint32 WIS; // Wisdom - /*2504*/ uint8 face; // Player face - /*2505*/ uint8 unknown2541[47]; // ? - /*2552*/ uint8 languages[MAX_PP_LANGUAGE]; - /*2580*/ uint8 unknown2616[4]; - /*2584*/ uint32 spell_book[MAX_PP_REF_SPELLBOOK]; - /*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff - /*4632*/ uint32 mem_spells[MAX_PP_REF_MEMSPELL]; - /*4668*/ uint8 unknown4704[32]; // - /*4700*/ float y; // Player y position - /*4704*/ float x; // Player x position - /*4708*/ float z; // Player z position - /*4712*/ float heading; // Direction player is facing - /*4716*/ uint8 unknown4752[4]; // - /*4720*/ int32 platinum; // Platinum Pieces on player - /*4724*/ int32 gold; // Gold Pieces on player - /*4728*/ int32 silver; // Silver Pieces on player - /*4732*/ int32 copper; // Copper Pieces on player - /*4736*/ int32 platinum_bank; // Platinum Pieces in Bank - /*4740*/ int32 gold_bank; // Gold Pieces in Bank - /*4744*/ int32 silver_bank; // Silver Pieces in Bank - /*4748*/ int32 copper_bank; // Copper Pieces in Bank - /*4752*/ int32 platinum_cursor; // Platinum on cursor - /*4756*/ int32 gold_cursor; // Gold on cursor - /*4760*/ int32 silver_cursor; // Silver on cursor - /*4764*/ int32 copper_cursor; // Copper on cursor - /*4768*/ int32 platinum_shared; // Platinum shared between characters - /*4772*/ uint8 unknown4808[24]; - /*4796*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer - /*5196*/ uint8 unknown5132[184]; - /*5380*/ uint32 pvp2; // - /*5384*/ uint32 unknown5420; // - /*5388*/ uint32 pvptype; // - /*5392*/ uint32 unknown5428; // - /*5396*/ uint32 ability_down; // Guessing - /*5400*/ uint8 unknown5436[8]; // - /*5408*/ uint32 autosplit; //not used right now - /*5412*/ uint8 unknown5448[8]; - /*5420*/ uint32 zone_change_count; // Number of times user has zoned in their career (guessing) - /*5424*/ uint8 unknown5460[16]; // - /*5440*/ uint32 drakkin_heritage; // - /*5444*/ uint32 drakkin_tattoo; // - /*5448*/ uint32 drakkin_details; // - /*5452*/ uint32 expansions; // expansion setting, bit field of expansions avaliable - /*5456*/ int32 toxicity; //from drinking potions, seems to increase by 3 each time you drink - /*5460*/ char unknown5496[16]; // - /*5476*/ int32 hunger_level; - /*5480*/ int32 thirst_level; - /*5484*/ uint32 ability_up; - /*5488*/ char unknown5524[16]; - /*5504*/ uint16 zone_id; // Current zone of the player - /*5506*/ uint16 zoneInstance; // Instance ID - /*5508*/ Convert::SpellBuff_Struct buffs[BUFF_COUNT]; // Buffs currently on the player - /*6008*/ char groupMembers[6][64];// - /*6392*/ char unknown6428[656]; - /*7048*/ uint32 entityid; - /*7052*/ uint32 leadAAActive; - /*7056*/ uint32 unknown7092; - /*7060*/ int32 ldon_points_guk; //client uses these as signed - /*7064*/ int32 ldon_points_mir; - /*7068*/ int32 ldon_points_mmc; - /*7072*/ int32 ldon_points_ruj; - /*7076*/ int32 ldon_points_tak; - /*7080*/ int32 ldon_points_available; - /*7084*/ int32 ldon_wins_guk; - /*7088*/ int32 ldon_wins_mir; - /*7092*/ int32 ldon_wins_mmc; - /*7096*/ int32 ldon_wins_ruj; - /*7100*/ int32 ldon_wins_tak; - /*7104*/ int32 ldon_losses_guk; - /*7108*/ int32 ldon_losses_mir; - /*7112*/ int32 ldon_losses_mmc; - /*7116*/ int32 ldon_losses_ruj; - /*7120*/ int32 ldon_losses_tak; - /*7124*/ uint8 unknown7160[72]; - /*7196*/ uint32 tribute_time_remaining; //in miliseconds - /*7200*/ uint32 showhelm; - /*7204*/ uint32 career_tribute_points; - /*7208*/ uint32 unknown7244; - /*7212*/ uint32 tribute_points; - /*7216*/ uint32 unknown7252; - /*7220*/ uint32 tribute_active; //1=active - /*7224*/ Convert::Tribute_Struct tributes[EmuConstants::TRIBUTE_SIZE]; - /*7264*/ Convert::Disciplines_Struct disciplines; - /*7664*/ uint32 recastTimers[MAX_RECAST_TYPES]; // Timers (GMT of last use) - /*7744*/ char unknown7780[160]; - /*7904*/ uint32 endurance; - /*7908*/ uint32 group_leadership_exp; //0-1000 - /*7912*/ uint32 raid_leadership_exp; //0-2000 - /*7916*/ uint32 group_leadership_points; - /*7920*/ uint32 raid_leadership_points; - /*7924*/ Convert::LeadershipAA_Struct leader_abilities; - /*8052*/ uint8 unknown8088[132]; - /*8184*/ uint32 air_remaining; - /*8188*/ uint32 PVPKills; - /*8192*/ uint32 PVPDeaths; - /*8196*/ uint32 PVPCurrentPoints; - /*8200*/ uint32 PVPCareerPoints; - /*8204*/ uint32 PVPBestKillStreak; - /*8208*/ uint32 PVPWorstDeathStreak; - /*8212*/ uint32 PVPCurrentKillStreak; - /*8216*/ Convert::PVPStatsEntry_Struct PVPLastKill; - /*8304*/ Convert::PVPStatsEntry_Struct PVPLastDeath; - /*8392*/ uint32 PVPNumberOfKillsInLast24Hours; - /*8396*/ Convert::PVPStatsEntry_Struct PVPRecentKills[50]; - /*12796*/ uint32 aapoints_spent; - /*12800*/ uint32 expAA; - /*12804*/ uint32 aapoints; //avaliable, unspent - /*12808*/ uint8 unknown12844[36]; - /*12844*/ Convert::Bandolier_Struct bandoliers[EmuConstants::BANDOLIERS_COUNT]; - /*14124*/ uint8 unknown14160[4506]; - /*18630*/ Convert::SuspendedMinion_Struct SuspendedMinion; // No longer in use - /*19240*/ uint32 timeentitledonaccount; - /*19244*/ Convert::PotionBelt_Struct potionbelt; //there should be 3 more of these - /*19532*/ uint8 unknown19568[8]; - /*19540*/ uint32 currentRadCrystals; // Current count of radiant crystals - /*19544*/ uint32 careerRadCrystals; // Total count of radiant crystals ever - /*19548*/ uint32 currentEbonCrystals;// Current count of ebon crystals - /*19552*/ uint32 careerEbonCrystals; // Total count of ebon crystals ever - /*19556*/ uint8 groupAutoconsent; // 0=off, 1=on - /*19557*/ uint8 raidAutoconsent; // 0=off, 1=on - /*19558*/ uint8 guildAutoconsent; // 0=off, 1=on - /*19559*/ uint8 unknown19595[5]; // ***Placeholder (6/29/2005) - /*19564*/ uint32 RestTimer; - /*19568*/ - }; - - - namespace player_lootitem_temp - { - struct ServerLootItem_Struct_temp { - uint32 item_id; - int16 equipSlot; - uint8 charges; - uint16 lootslot; - uint32 aug1; - uint32 aug2; - uint32 aug3; - uint32 aug4; - uint32 aug5; - uint32 aug6; - uint8 attuned; - }; - } - - struct DBPlayerCorpse_Struct_temp { - uint32 crc; - bool locked; - uint32 itemcount; - uint32 exp; - float size; - uint8 level; - uint8 race; - uint8 gender; - uint8 class_; - uint8 deity; - uint8 texture; - uint8 helmtexture; - uint32 copper; - uint32 silver; - uint32 gold; - uint32 plat; - Color_Struct item_tint[9]; - uint8 haircolor; - uint8 beardcolor; - uint8 eyecolor1; - uint8 eyecolor2; - uint8 hairstyle; - uint8 face; - uint8 beard; - uint32 drakkin_heritage; - uint32 drakkin_tattoo; - uint32 drakkin_details; - player_lootitem_temp::ServerLootItem_Struct_temp items[0]; - }; - - namespace classic_db_temp { - struct DBPlayerCorpse_Struct_temp { - uint32 crc; - bool locked; - uint32 itemcount; - uint32 exp; - float size; - uint8 level; - uint8 race; - uint8 gender; - uint8 class_; - uint8 deity; - uint8 texture; - uint8 helmtexture; - uint32 copper; - uint32 silver; - uint32 gold; - uint32 plat; - Color_Struct item_tint[9]; - uint8 haircolor; - uint8 beardcolor; - uint8 eyecolor1; - uint8 eyecolor2; - uint8 hairstyle; - uint8 face; - uint8 beard; - player_lootitem_temp::ServerLootItem_Struct_temp items[0]; - }; - } -} - -#pragma pack() +#ifdef _WINDOWS +#if _MSC_VER > 1700 // greater than 2012 (2013+) +# define _ISNAN_(a) std::isnan(a) +#else +# include +# define _ISNAN_(a) _isnan(a) +#endif +#else +# define _ISNAN_(a) std::isnan(a) +#endif class Database : public DBcore { public: @@ -485,164 +90,166 @@ public: bool Connect(const char* host, const char* user, const char* passwd, const char* database,uint32 port); ~Database(); - - /* - * General Character Related Stuff - */ - /* Character Creation */ - bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp); + bool AddToNameFilter(const char* name); + bool CreateCharacter(uint32 account_id, char* name, uint16 gender, uint16 race, uint16 class_, uint8 str, uint8 sta, uint8 cha, uint8 dex, uint8 int_, uint8 agi, uint8 wis, uint8 face); + bool DeleteCharacter(char* name); bool MoveCharacterToZone(const char* charname, const char* zonename); bool MoveCharacterToZone(const char* charname, const char* zonename,uint32 zoneid); bool MoveCharacterToZone(uint32 iCharID, const char* iZonename); - bool UpdateName(const char* oldname, const char* newname); + bool ReserveName(uint32 account_id, char* name); + bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp); bool SetHackerFlag(const char* accountname, const char* charactername, const char* hacked); bool SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone); - bool AddToNameFilter(const char* name); - bool ReserveName(uint32 account_id, char* name); - bool CreateCharacter(uint32 account_id, char* name, uint16 gender, uint16 race, uint16 class_, uint8 str, uint8 sta, uint8 cha, uint8 dex, uint8 int_, uint8 agi, uint8 wis, uint8 face); bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv); - bool DeleteCharacter(char* name); + bool UpdateName(const char* oldname, const char* newname); - /* - * General Information Getting Queries - */ + /* General Information Queries */ + + bool AddBannedIP(char* bannedIP, const char* notes); //Add IP address to the Banned_IPs table. + bool AddGMIP(char* ip_address, char* name); + bool CheckBannedIPs(const char* loginIP); //Check incoming connection against banned IP table. + bool CheckGMIPs(const char* loginIP, uint32 account_id); bool CheckNameFilter(const char* name, bool surname = false); bool CheckUsedName(const char* name); + uint32 GetAccountIDByChar(const char* charname, uint32* oCharID = 0); uint32 GetAccountIDByChar(uint32 char_id); uint32 GetAccountIDByName(const char* accname, int16* status = 0, uint32* lsid = 0); + uint32 GetCharacterID(const char *name); + uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0, float* oX = 0, float* oY = 0, float* oZ = 0); uint32 GetGuildIDByCharID(uint32 char_id); + void GetAccountName(uint32 accountid, char* name, uint32* oLSAccountID = 0); void GetCharName(uint32 char_id, char* name); - uint32 GetCharacterInfo(const char* iName, uint32* oAccID = 0, uint32* oZoneID = 0, uint32* oInstanceID = 0,float* oX = 0, float* oY = 0, float* oZ = 0); - uint32 GetCharacterID(const char *name); - bool CheckBannedIPs(const char* loginIP); //Lieka Edit: Check incomming connection against banned IP table. - bool AddBannedIP(char* bannedIP, const char* notes); //Lieka Edit: Add IP address to the Banned_IPs table. - bool CheckGMIPs(const char* loginIP, uint32 account_id); - bool AddGMIP(char* ip_address, char* name); void LoginIP(uint32 AccountID, const char* LoginIP); - /* - * Instancing Stuff - */ - bool VerifyZoneInstance(uint32 zone_id, uint16 instance_id); - bool VerifyInstanceAlive(uint16 instance_id, uint32 char_id); - bool CharacterInInstanceGroup(uint16 instance_id, uint32 char_id); - void DeleteInstance(uint16 instance_id); - bool CheckInstanceExpired(uint16 instance_id); - uint32 ZoneIDFromInstanceID(uint16 instance_id); - uint32 VersionFromInstanceID(uint16 instance_id); - uint32 GetTimeRemainingInstance(uint16 instance_id, bool &is_perma); - bool GetUnusedInstanceID(uint16 &instance_id); - bool CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration); - void PurgeExpiredInstances(); + /* Instancing */ + bool AddClientToInstance(uint16 instance_id, uint32 char_id); + bool CharacterInInstanceGroup(uint16 instance_id, uint32 char_id); + bool CheckInstanceExists(uint16 instance_id); + bool CheckInstanceExpired(uint16 instance_id); + bool CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration); + bool GetUnusedInstanceID(uint16 &instance_id); + bool GlobalInstance(uint16 instance_id); bool RemoveClientFromInstance(uint16 instance_id, uint32 char_id); bool RemoveClientsFromInstance(uint16 instance_id); - bool CheckInstanceExists(uint16 instance_id); - void BuryCorpsesInInstance(uint16 instance_id); - uint16 GetInstanceVersion(uint16 instance_id); + bool VerifyInstanceAlive(uint16 instance_id, uint32 char_id); + bool VerifyZoneInstance(uint32 zone_id, uint16 instance_id); + uint16 GetInstanceID(const char* zone, uint32 charid, int16 version); uint16 GetInstanceID(uint32 zone, uint32 charid, int16 version); - void GetCharactersInInstance(uint16 instance_id, std::list &charid_list); + uint16 GetInstanceVersion(uint16 instance_id); + uint32 GetTimeRemainingInstance(uint16 instance_id, bool &is_perma); + uint32 VersionFromInstanceID(uint16 instance_id); + uint32 ZoneIDFromInstanceID(uint16 instance_id); + void AssignGroupToInstance(uint32 gid, uint32 instance_id); void AssignRaidToInstance(uint32 rid, uint32 instance_id); + void BuryCorpsesInInstance(uint16 instance_id); + void DeleteInstance(uint16 instance_id); void FlagInstanceByGroupLeader(uint32 zone, int16 version, uint32 charid, uint32 gid); void FlagInstanceByRaidLeader(uint32 zone, int16 version, uint32 charid, uint32 rid); + void GetCharactersInInstance(uint16 instance_id, std::list &charid_list); + void PurgeExpiredInstances(); void SetInstanceDuration(uint16 instance_id, uint32 new_duration); - bool GlobalInstance(uint16 instance_id); - /* - * Adventure related. - */ + /* Adventure related. */ + void UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win); bool GetAdventureStats(uint32 char_id, AdventureStats_Struct *as); - /* - * Account Related - */ - uint32 GetMiniLoginAccount(char* ip); - void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus); - uint32 CheckLogin(const char* name, const char* password, int16* oStatus = 0); - int16 CheckStatus(uint32 account_id); - uint32 CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id = 0); + /* Account Related */ + bool DeleteAccount(const char* name); + bool GetLiveChar(uint32 account_id, char* cname); bool SetAccountStatus(const char* name, int16 status); bool SetLocalPassword(uint32 accid, const char* password); + bool UpdateLiveChar(char* charname, uint32 lsaccount_id); + + int16 CheckStatus(uint32 account_id); + + uint32 CheckLogin(const char* name, const char* password, int16* oStatus = 0); + uint32 CreateAccount(const char* name, const char* password, int16 status, uint32 lsaccount_id = 0); uint32 GetAccountIDFromLSID(uint32 iLSID, char* oAccountName = 0, int16* oStatus = 0); - bool UpdateLiveChar(char* charname,uint32 lsaccount_id); - bool GetLiveChar(uint32 account_id, char* cname); + uint32 GetMiniLoginAccount(char* ip); uint8 GetAgreementFlag(uint32 acctid); + + void GetAccountFromID(uint32 id, char* oAccountName, int16* oStatus); void SetAgreementFlag(uint32 acctid); - /* - * Groups - */ - uint32 GetGroupID(const char* name); - void SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc = false); - void ClearGroup(uint32 gid = 0); - char* GetGroupLeaderForLogin(const char* name,char* leaderbuf); - void SetGroupLeaderName(uint32 gid, const char* name); - char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, - char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr); - void ClearGroupLeader(uint32 gid = 0); + /* Groups */ + char* GetGroupLeaderForLogin(const char* name,char* leaderbuf); + char* GetGroupLeadershipInfo(uint32 gid, char* leaderbuf, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr); + + uint32 GetGroupID(const char* name); + + void ClearGroup(uint32 gid = 0); + void ClearGroupLeader(uint32 gid = 0); + void SetGroupID(const char* name, uint32 id, uint32 charid, uint32 ismerc = false); + void SetGroupLeaderName(uint32 gid, const char* name); + + /* Raids */ + + const char *GetRaidLeaderName(uint32 rid); + + uint32 GetRaidID(const char* name); - /* - * Raids - */ void ClearRaid(uint32 rid = 0); void ClearRaidDetails(uint32 rid = 0); - uint32 GetRaidID(const char* name); - const char *GetRaidLeaderName(uint32 rid); - void GetGroupLeadershipInfo(uint32 gid, uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, - char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr); - void GetRaidLeadershipInfo(uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, - RaidLeadershipAA_Struct* RLAA = nullptr); - void SetRaidGroupLeaderInfo(uint32 gid, uint32 rid); void ClearRaidLeader(uint32 gid = 0xFFFFFFFF, uint32 rid = 0); + void GetGroupLeadershipInfo(uint32 gid, uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr); + void GetRaidLeadershipInfo(uint32 rid, char* maintank = nullptr, char* assist = nullptr, char* puller = nullptr, char *marknpc = nullptr, RaidLeadershipAA_Struct* RLAA = nullptr); + void SetRaidGroupLeaderInfo(uint32 gid, uint32 rid); + + /* Database Conversions 'database_conversions.cpp' */ - /* Database Conversions*/ bool CheckDatabaseConversions(); - bool CheckDatabaseConvertPPDeblob(); - bool CheckDatabaseConvertCorpseDeblob(); bool CheckDatabaseConvertBotsPostPPDeblob(); + bool CheckDatabaseConvertCorpseDeblob(); + bool CheckDatabaseConvertPPDeblob(); + + /* Database Variables */ - /* - * Database Variables - */ bool GetVariable(const char* varname, char* varvalue, uint16 varvalue_len); bool SetVariable(const char* varname, const char* varvalue); bool LoadVariables(); uint32 LoadVariables_MQ(char** query); bool LoadVariables_result(MySQLRequestResult results); - /* - * General Queries - */ - bool LoadZoneNames(); - bool GetZoneLongName(const char* short_name, char** long_name, char* file_name = 0, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, uint32* graveyard_id = 0, uint32* maxclients = 0); - bool GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid = 0, float* graveyard_x = 0, float* graveyard_y = 0, float* graveyard_z = 0, float* graveyard_heading = 0); - uint32 GetZoneGraveyardID(uint32 zone_id, uint32 version); - uint32 GetZoneID(const char* zonename); - uint8 GetPEQZone(uint32 zoneID, uint32 version); - const char* GetZoneName(uint32 zoneID, bool ErrorUnknown = false); - uint8 GetServerType(); + /* General Queries */ + bool GetSafePoints(const char* short_name, uint32 version, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, int16* minstatus = 0, uint8* minlevel = 0, char *flag_needed = nullptr); bool GetSafePoints(uint32 zoneID, uint32 version, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, int16* minstatus = 0, uint8* minlevel = 0, char *flag_needed = nullptr) { return GetSafePoints(GetZoneName(zoneID), version, safe_x, safe_y, safe_z, minstatus, minlevel, flag_needed); } - uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level); - uint8 GetRaceSkill(uint8 skillid, uint8 in_race); + bool GetZoneGraveyard(const uint32 graveyard_id, uint32* graveyard_zoneid = 0, float* graveyard_x = 0, float* graveyard_y = 0, float* graveyard_z = 0, float* graveyard_heading = 0); + bool GetZoneLongName(const char* short_name, char** long_name, char* file_name = 0, float* safe_x = 0, float* safe_y = 0, float* safe_z = 0, uint32* graveyard_id = 0, uint32* maxclients = 0); bool LoadPTimers(uint32 charid, PTimerList &into); - void ClearPTimers(uint32 charid); - void ClearMerchantTemp(); - void SetLFP(uint32 CharID, bool LFP); - void SetLFG(uint32 CharID, bool LFG); - void SetFirstLogon(uint32 CharID, uint8 firstlogon); - void SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon); + bool LoadZoneNames(); + + const char* GetZoneName(uint32 zoneID, bool ErrorUnknown = false); + + uint32 GetZoneGraveyardID(uint32 zone_id, uint32 version); + uint32 GetZoneID(const char* zonename); + + uint8 GetPEQZone(uint32 zoneID, uint32 version); + uint8 GetRaceSkill(uint8 skillid, uint8 in_race); + uint8 GetServerType(); + uint8 GetSkillCap(uint8 skillid, uint8 in_race, uint8 in_class, uint16 in_level); + void AddReport(std::string who, std::string against, std::string lines); + void ClearMerchantTemp(); + void ClearPTimers(uint32 charid); + void SetFirstLogon(uint32 CharID, uint8 firstlogon); + void SetLFG(uint32 CharID, bool LFG); + void SetLFP(uint32 CharID, bool LFP); + void SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon); + + /* EQEmuLogSys */ + void LoadLogSettings(EQEmuLogSys::LogSettings* log_settings); private: void DBInitVars(); @@ -654,17 +261,11 @@ private: VarCache_Struct** varcache_array; uint32 varcache_lastupdate; - - /* - * Groups, utility methods. - */ + /* Groups, utility methods. */ void ClearAllGroupLeaders(); void ClearAllGroups(); - - /* - * Raid, utility methods. - */ + /* Raid, utility methods. */ void ClearAllRaids(); void ClearAllRaidDetails(); void ClearAllRaidLeaders(); diff --git a/common/database_conversions.cpp b/common/database_conversions.cpp new file mode 100644 index 000000000..8a938e8b5 --- /dev/null +++ b/common/database_conversions.cpp @@ -0,0 +1,1988 @@ +/* EQEMu: Everquest Server Emulator +Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY except by those people which sell it, which +are required to give you total support for your newly bought product; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "../common/global_define.h" +#include "../common/rulesys.h" +#include "../common/string_util.h" +#include "../common/timer.h" + +#include "database.h" +#include "extprofile.h" + +#include +#include + +// Disgrace: for windows compile +#ifdef _WINDOWS +#include +#define snprintf _snprintf +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#else +#include "unix.h" +#include +#include +#endif + +#pragma pack(1) + +/* Conversion Structs */ + +namespace Convert { + struct BindStruct { + /*000*/ uint32 zoneId; + /*004*/ float x; + /*008*/ float y; + /*012*/ float z; + /*016*/ float heading; + }; + struct Color_Struct + { + union + { + struct + { + uint8 blue; + uint8 green; + uint8 red; + uint8 use_tint; // if there's a tint this is FF + } rgb; + uint32 color; + }; + }; + struct AA_Array + { + uint32 AA; + uint32 value; + }; + struct SpellBuff_Struct + { + /*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise + /*001*/ uint8 level; + /*002*/ uint8 bard_modifier; + /*003*/ uint8 effect; //not real + /*004*/ uint32 spellid; + /*008*/ uint32 duration; + /*012*/ uint32 counters; + /*016*/ uint32 player_id; //'global' ID of the caster, for wearoff messages + /*020*/ + }; + struct Tribute_Struct { + uint32 tribute; + uint32 tier; + }; + struct Disciplines_Struct { + uint32 values[MAX_PP_DISCIPLINES]; + }; + struct GroupLeadershipAA_Struct { + union { + struct { + uint32 groupAAMarkNPC; + uint32 groupAANPCHealth; + uint32 groupAADelegateMainAssist; + uint32 groupAADelegateMarkNPC; + uint32 groupAA4; + uint32 groupAA5; + uint32 groupAAInspectBuffs; + uint32 groupAA7; + uint32 groupAASpellAwareness; + uint32 groupAAOffenseEnhancement; + uint32 groupAAManaEnhancement; + uint32 groupAAHealthEnhancement; + uint32 groupAAHealthRegeneration; + uint32 groupAAFindPathToPC; + uint32 groupAAHealthOfTargetsTarget; + uint32 groupAA15; + }; + uint32 ranks[MAX_GROUP_LEADERSHIP_AA_ARRAY]; + }; + }; + + struct RaidLeadershipAA_Struct { + union { + struct { + uint32 raidAAMarkNPC; + uint32 raidAANPCHealth; + uint32 raidAADelegateMainAssist; + uint32 raidAADelegateMarkNPC; + uint32 raidAA4; + uint32 raidAA5; + uint32 raidAA6; + uint32 raidAASpellAwareness; + uint32 raidAAOffenseEnhancement; + uint32 raidAAManaEnhancement; + uint32 raidAAHealthEnhancement; + uint32 raidAAHealthRegeneration; + uint32 raidAAFindPathToPC; + uint32 raidAAHealthOfTargetsTarget; + uint32 raidAA14; + uint32 raidAA15; + }; + uint32 ranks[MAX_RAID_LEADERSHIP_AA_ARRAY]; + }; + }; + + struct LeadershipAA_Struct { + union { + struct { + Convert::GroupLeadershipAA_Struct group; + Convert::RaidLeadershipAA_Struct raid; + }; + uint32 ranks[MAX_LEADERSHIP_AA_ARRAY]; + }; + }; + typedef struct + { + /*00*/ char Name[64]; + /*64*/ uint32 Level; + /*68*/ uint32 Race; + /*72*/ uint32 Class; + /*76*/ uint32 Zone; + /*80*/ uint32 Time; + /*84*/ uint32 Points; + /*88*/ + } PVPStatsEntry_Struct; + struct BandolierItem_Struct { + uint32 item_id; + uint32 icon; + char item_name[64]; + }; + struct Bandolier_Struct { + char name[32]; + Convert::BandolierItem_Struct items[EmuConstants::BANDOLIER_SIZE]; + }; + struct PotionBelt_Struct { + Convert::BandolierItem_Struct items[EmuConstants::POTION_BELT_SIZE]; + }; + struct SuspendedMinion_Struct + { + /*000*/ uint16 SpellID; + /*002*/ uint32 HP; + /*006*/ uint32 Mana; + /*010*/ Convert::SpellBuff_Struct Buffs[BUFF_COUNT]; + /*510*/ uint32 Items[_MaterialCount]; + /*546*/ char Name[64]; + /*610*/ + }; + + struct PlayerProfile_Struct { + /*0000*/ uint32 checksum; // Checksum from CRC32::SetEQChecksum + /*0004*/ char name[64]; // Name of player sizes not right + /*0068*/ char last_name[32]; // Last name of player sizes not right + /*0100*/ uint32 gender; // Player Gender - 0 Male, 1 Female + /*0104*/ uint32 race; // Player race + /*0108*/ uint32 class_; // Player class + /*0112*/ uint32 unknown0112; // + /*0116*/ uint32 level; // Level of player (might be one byte) + /*0120*/ Convert::BindStruct binds[5]; // Bind points (primary is first, home city is fifth) + /*0220*/ uint32 deity; // deity + /*0224*/ uint32 guild_id; + /*0228*/ uint32 birthday; // characters bday + /*0232*/ uint32 lastlogin; // last login or zone time + /*0236*/ uint32 timePlayedMin; // in minutes + /*0240*/ uint8 pvp; + /*0241*/ uint8 level2; //no idea why this is here, but thats how it is on live + /*0242*/ uint8 anon; // 2=roleplay, 1=anon, 0=not anon + /*0243*/ uint8 gm; + /*0244*/ uint8 guildrank; + /*0245*/ uint8 guildbanker; + /*0246*/ uint8 unknown0246[6]; // + /*0252*/ uint32 intoxication; + /*0256*/ uint32 spellSlotRefresh[MAX_PP_REF_MEMSPELL]; //in ms + /*0292*/ uint32 abilitySlotRefresh; + /*0296*/ uint8 haircolor; // Player hair color + /*0297*/ uint8 beardcolor; // Player beard color + /*0298*/ uint8 eyecolor1; // Player left eye color + /*0299*/ uint8 eyecolor2; // Player right eye color + /*0300*/ uint8 hairstyle; // Player hair style + /*0301*/ uint8 beard; // Beard type + /*0302*/ uint8 ability_time_seconds; //The following four spots are unknown right now..... + /*0303*/ uint8 ability_number; //ability used + /*0304*/ uint8 ability_time_minutes; + /*0305*/ uint8 ability_time_hours; //place holder + /*0306*/ uint8 unknown0306[6]; // @bp Spacer/Flag? + /*0312*/ uint32 item_material[_MaterialCount]; // Item texture/material of worn/held items + /*0348*/ uint8 unknown0348[44]; + /*0392*/ Convert::Color_Struct item_tint[_MaterialCount]; + /*0428*/ Convert::AA_Array aa_array[MAX_PP_AA_ARRAY]; + /*2348*/ float unknown2384; //seen ~128, ~47 + /*2352*/ char servername[32]; // length probably not right + /*2384*/ char title[32]; // length might be wrong + /*2416*/ char suffix[32]; // length might be wrong + /*2448*/ uint32 guildid2; // + /*2452*/ uint32 exp; // Current Experience + /*2456*/ uint32 unknown2492; + /*2460*/ uint32 points; // Unspent Practice points + /*2464*/ uint32 mana; // current mana + /*2468*/ uint32 cur_hp; // current hp + /*2472*/ uint32 unknown2508; // 0x05 + /*2476*/ uint32 STR; // Strength + /*2480*/ uint32 STA; // Stamina + /*2484*/ uint32 CHA; // Charisma + /*2488*/ uint32 DEX; // Dexterity + /*2492*/ uint32 INT; // Intelligence + /*2496*/ uint32 AGI; // Agility + /*2500*/ uint32 WIS; // Wisdom + /*2504*/ uint8 face; // Player face + /*2505*/ uint8 unknown2541[47]; // ? + /*2552*/ uint8 languages[MAX_PP_LANGUAGE]; + /*2580*/ uint8 unknown2616[4]; + /*2584*/ uint32 spell_book[MAX_PP_REF_SPELLBOOK]; + /*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff + /*4632*/ uint32 mem_spells[MAX_PP_REF_MEMSPELL]; + /*4668*/ uint8 unknown4704[32]; // + /*4700*/ float y; // Player y position + /*4704*/ float x; // Player x position + /*4708*/ float z; // Player z position + /*4712*/ float heading; // Direction player is facing + /*4716*/ uint8 unknown4752[4]; // + /*4720*/ int32 platinum; // Platinum Pieces on player + /*4724*/ int32 gold; // Gold Pieces on player + /*4728*/ int32 silver; // Silver Pieces on player + /*4732*/ int32 copper; // Copper Pieces on player + /*4736*/ int32 platinum_bank; // Platinum Pieces in Bank + /*4740*/ int32 gold_bank; // Gold Pieces in Bank + /*4744*/ int32 silver_bank; // Silver Pieces in Bank + /*4748*/ int32 copper_bank; // Copper Pieces in Bank + /*4752*/ int32 platinum_cursor; // Platinum on cursor + /*4756*/ int32 gold_cursor; // Gold on cursor + /*4760*/ int32 silver_cursor; // Silver on cursor + /*4764*/ int32 copper_cursor; // Copper on cursor + /*4768*/ int32 platinum_shared; // Platinum shared between characters + /*4772*/ uint8 unknown4808[24]; + /*4796*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer + /*5196*/ uint8 unknown5132[184]; + /*5380*/ uint32 pvp2; // + /*5384*/ uint32 unknown5420; // + /*5388*/ uint32 pvptype; // + /*5392*/ uint32 unknown5428; // + /*5396*/ uint32 ability_down; // Guessing + /*5400*/ uint8 unknown5436[8]; // + /*5408*/ uint32 autosplit; //not used right now + /*5412*/ uint8 unknown5448[8]; + /*5420*/ uint32 zone_change_count; // Number of times user has zoned in their career (guessing) + /*5424*/ uint8 unknown5460[16]; // + /*5440*/ uint32 drakkin_heritage; // + /*5444*/ uint32 drakkin_tattoo; // + /*5448*/ uint32 drakkin_details; // + /*5452*/ uint32 expansions; // expansion setting, bit field of expansions avaliable + /*5456*/ int32 toxicity; //from drinking potions, seems to increase by 3 each time you drink + /*5460*/ char unknown5496[16]; // + /*5476*/ int32 hunger_level; + /*5480*/ int32 thirst_level; + /*5484*/ uint32 ability_up; + /*5488*/ char unknown5524[16]; + /*5504*/ uint16 zone_id; // Current zone of the player + /*5506*/ uint16 zoneInstance; // Instance ID + /*5508*/ Convert::SpellBuff_Struct buffs[BUFF_COUNT]; // Buffs currently on the player + /*6008*/ char groupMembers[6][64];// + /*6392*/ char unknown6428[656]; + /*7048*/ uint32 entityid; + /*7052*/ uint32 leadAAActive; + /*7056*/ uint32 unknown7092; + /*7060*/ int32 ldon_points_guk; //client uses these as signed + /*7064*/ int32 ldon_points_mir; + /*7068*/ int32 ldon_points_mmc; + /*7072*/ int32 ldon_points_ruj; + /*7076*/ int32 ldon_points_tak; + /*7080*/ int32 ldon_points_available; + /*7084*/ int32 ldon_wins_guk; + /*7088*/ int32 ldon_wins_mir; + /*7092*/ int32 ldon_wins_mmc; + /*7096*/ int32 ldon_wins_ruj; + /*7100*/ int32 ldon_wins_tak; + /*7104*/ int32 ldon_losses_guk; + /*7108*/ int32 ldon_losses_mir; + /*7112*/ int32 ldon_losses_mmc; + /*7116*/ int32 ldon_losses_ruj; + /*7120*/ int32 ldon_losses_tak; + /*7124*/ uint8 unknown7160[72]; + /*7196*/ uint32 tribute_time_remaining; //in miliseconds + /*7200*/ uint32 showhelm; + /*7204*/ uint32 career_tribute_points; + /*7208*/ uint32 unknown7244; + /*7212*/ uint32 tribute_points; + /*7216*/ uint32 unknown7252; + /*7220*/ uint32 tribute_active; //1=active + /*7224*/ Convert::Tribute_Struct tributes[EmuConstants::TRIBUTE_SIZE]; + /*7264*/ Convert::Disciplines_Struct disciplines; + /*7664*/ uint32 recastTimers[MAX_RECAST_TYPES]; // Timers (GMT of last use) + /*7744*/ char unknown7780[160]; + /*7904*/ uint32 endurance; + /*7908*/ uint32 group_leadership_exp; //0-1000 + /*7912*/ uint32 raid_leadership_exp; //0-2000 + /*7916*/ uint32 group_leadership_points; + /*7920*/ uint32 raid_leadership_points; + /*7924*/ Convert::LeadershipAA_Struct leader_abilities; + /*8052*/ uint8 unknown8088[132]; + /*8184*/ uint32 air_remaining; + /*8188*/ uint32 PVPKills; + /*8192*/ uint32 PVPDeaths; + /*8196*/ uint32 PVPCurrentPoints; + /*8200*/ uint32 PVPCareerPoints; + /*8204*/ uint32 PVPBestKillStreak; + /*8208*/ uint32 PVPWorstDeathStreak; + /*8212*/ uint32 PVPCurrentKillStreak; + /*8216*/ Convert::PVPStatsEntry_Struct PVPLastKill; + /*8304*/ Convert::PVPStatsEntry_Struct PVPLastDeath; + /*8392*/ uint32 PVPNumberOfKillsInLast24Hours; + /*8396*/ Convert::PVPStatsEntry_Struct PVPRecentKills[50]; + /*12796*/ uint32 aapoints_spent; + /*12800*/ uint32 expAA; + /*12804*/ uint32 aapoints; //avaliable, unspent + /*12808*/ uint8 unknown12844[36]; + /*12844*/ Convert::Bandolier_Struct bandoliers[EmuConstants::BANDOLIERS_COUNT]; + /*14124*/ uint8 unknown14160[4506]; + /*18630*/ Convert::SuspendedMinion_Struct SuspendedMinion; // No longer in use + /*19240*/ uint32 timeentitledonaccount; + /*19244*/ Convert::PotionBelt_Struct potionbelt; //there should be 3 more of these + /*19532*/ uint8 unknown19568[8]; + /*19540*/ uint32 currentRadCrystals; // Current count of radiant crystals + /*19544*/ uint32 careerRadCrystals; // Total count of radiant crystals ever + /*19548*/ uint32 currentEbonCrystals;// Current count of ebon crystals + /*19552*/ uint32 careerEbonCrystals; // Total count of ebon crystals ever + /*19556*/ uint8 groupAutoconsent; // 0=off, 1=on + /*19557*/ uint8 raidAutoconsent; // 0=off, 1=on + /*19558*/ uint8 guildAutoconsent; // 0=off, 1=on + /*19559*/ uint8 unknown19595[5]; // ***Placeholder (6/29/2005) + /*19564*/ uint32 RestTimer; + /*19568*/ + }; + + + namespace player_lootitem_temp + { + struct ServerLootItem_Struct_temp { + uint32 item_id; + int16 equipSlot; + uint8 charges; + uint16 lootslot; + uint32 aug1; + uint32 aug2; + uint32 aug3; + uint32 aug4; + uint32 aug5; + uint32 aug6; + uint8 attuned; + }; + } + + struct DBPlayerCorpse_Struct_temp { + uint32 crc; + bool locked; + uint32 itemcount; + uint32 exp; + float size; + uint8 level; + uint8 race; + uint8 gender; + uint8 class_; + uint8 deity; + uint8 texture; + uint8 helmtexture; + uint32 copper; + uint32 silver; + uint32 gold; + uint32 plat; + Color_Struct item_tint[9]; + uint8 haircolor; + uint8 beardcolor; + uint8 eyecolor1; + uint8 eyecolor2; + uint8 hairstyle; + uint8 face; + uint8 beard; + uint32 drakkin_heritage; + uint32 drakkin_tattoo; + uint32 drakkin_details; + player_lootitem_temp::ServerLootItem_Struct_temp items[0]; + }; + + namespace classic_db_temp { + struct DBPlayerCorpse_Struct_temp { + uint32 crc; + bool locked; + uint32 itemcount; + uint32 exp; + float size; + uint8 level; + uint8 race; + uint8 gender; + uint8 class_; + uint8 deity; + uint8 texture; + uint8 helmtexture; + uint32 copper; + uint32 silver; + uint32 gold; + uint32 plat; + Color_Struct item_tint[9]; + uint8 haircolor; + uint8 beardcolor; + uint8 eyecolor1; + uint8 eyecolor2; + uint8 hairstyle; + uint8 face; + uint8 beard; + player_lootitem_temp::ServerLootItem_Struct_temp items[0]; + }; + } +} + +#pragma pack() + +static inline void loadbar(unsigned int x, unsigned int n, unsigned int w = 50) { + if ((x != n) && (x % (n / 100 + 1) != 0)) return; + float ratio = x / (float)n; + int c = ratio * w; + std::cout << std::setw(3) << (int)(ratio * 100) << "% ["; + for (int x = 0; x < c; x++) std::cout << "="; + for (int x = c; x < w; x++) std::cout << " "; + std::cout << "]\r" << std::flush; +} + + +bool Database::CheckDatabaseConversions() { + CheckDatabaseConvertPPDeblob(); + CheckDatabaseConvertBotsPostPPDeblob(); + CheckDatabaseConvertCorpseDeblob(); + + /* Fetch Automatic Upgrade Script */ + if (!std::ifstream("eqemu_update.pl")){ + std::cout << "Pulling down automatic database upgrade script..." << std::endl; +#ifdef _WIN32 + system("perl -MLWP::UserAgent -e \"require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_update.pl'); if ($response->is_success){ open(FILE, '> eqemu_update.pl'); print FILE $response->decoded_content; close(FILE); }\""); +#else + system("wget --no-check-certificate -O eqemu_update.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_update.pl"); +#endif + } + + /* + Automatic (Database) Upgrade Script + Script: eqemu_update.pl V 1 - the number that world passes to the script will + force the script to check for a newer version to update itself with + eqemu_update.pl ran_from_world - won't bring up a menu if your database versions match + eqemu_update.pl - ran standalone will bring up a menu prompt + */ + + /* Check for a new version of this script, the arg passed + would have to be higher than the copy they have downloaded + locally and they will re fetch */ + system("perl eqemu_update.pl V 2"); + + /* Run Automatic Database Upgrade Script */ + system("perl eqemu_update.pl ran_from_world"); + + return true; +} + +bool Database::CheckDatabaseConvertPPDeblob(){ + unsigned int lengths; + unsigned int lengths_e; + std::string squery; + Convert::PlayerProfile_Struct* pp; + ExtendedProfile_Struct* e_pp; + uint32 pplen = 0; + uint32 i; + int character_id = 0; + int account_id = 0; + int number_of_characters = 0; + int printppdebug = 0; /* Prints Player Profile */ + int runconvert = 0; + + /* Check For Legacy Storage Method */ + std::string rquery = StringFormat("SHOW TABLES LIKE 'character_'"); + auto results = QueryDatabase(rquery); + if (results.RowCount() == 1){ + runconvert = 1; + printf("\n\n::: Legacy Character Data Binary Blob Storage Detected... \n"); + printf("----------------------------------------------------------\n\n"); + printf(" Database currently has character data being stored via \n"); + printf(" the legacy character storage method and will proceed with converting...\n\n"); + printf(" It is recommended that you backup your database \n"); + printf(" before continuing the automatic conversion process...\n\n"); + printf("----------------------------------------------------------\n\n"); + std::cout << "Press ENTER to continue....." << std::endl << std::endl; + std::cin.ignore(1); + } + + // runconvert = 0; + // printppdebug = 1; + + if (runconvert == 1){ + printf("Running character binary blob to database conversion... \n"); + /* Get the number of characters */ + rquery = StringFormat("SELECT COUNT(`id`) FROM `character_`"); + results = QueryDatabase(rquery); + for (auto row = results.begin(); row != results.end(); ++row) { + number_of_characters = atoi(row[0]); + printf("Number of Characters in Database: %i \n", number_of_characters); + } + + /* Check for table `character_data` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_data'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_data` doesn't exist... creating..."); + rquery = StringFormat( + "CREATE TABLE `character_data` ( " + "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " + "`account_id` int(11) NOT NULL DEFAULT '0', " + "`name` varchar(64) NOT NULL DEFAULT '', " + "`last_name` varchar(64) NOT NULL DEFAULT '', " + "`title` varchar(32) NOT NULL DEFAULT '', " + "`suffix` varchar(32) NOT NULL DEFAULT '', " + "`zone_id` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`zone_instance` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`y` float NOT NULL DEFAULT '0', " + "`x` float NOT NULL DEFAULT '0', " + "`z` float NOT NULL DEFAULT '0', " + "`heading` float NOT NULL DEFAULT '0', " + "`gender` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`race` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`class` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`level` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`deity` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`birthday` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`last_login` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`time_played` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`level2` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`anon` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`gm` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`face` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`hair_color` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`hair_style` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`beard` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`beard_color` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`eye_color_1` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`eye_color_2` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`drakkin_heritage` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`drakkin_tattoo` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`drakkin_details` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`ability_time_seconds` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`ability_number` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`ability_time_minutes` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`ability_time_hours` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`exp` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`aa_points_spent` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`aa_exp` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`aa_points` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`group_leadership_exp` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`raid_leadership_exp` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`group_leadership_points` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`raid_leadership_points` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`points` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`cur_hp` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`mana` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`endurance` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`intoxication` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`str` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`sta` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`cha` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`dex` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`int` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`agi` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`wis` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`zone_change_count` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`toxicity` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`hunger_level` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`thirst_level` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`ability_up` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`ldon_points_guk` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`ldon_points_mir` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`ldon_points_mmc` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`ldon_points_ruj` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`ldon_points_tak` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`ldon_points_available` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`tribute_time_remaining` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`career_tribute_points` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`tribute_points` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`tribute_active` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`pvp_status` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`pvp_kills` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`pvp_deaths` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`pvp_current_points` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`pvp_career_points` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`pvp_best_kill_streak` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`pvp_worst_death_streak` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`pvp_current_kill_streak` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`pvp2` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`pvp_type` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`show_helm` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`group_auto_consent` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`raid_auto_consent` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`guild_auto_consent` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`leadership_exp_on` tinyint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`RestTimer` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`air_remaining` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`autosplit_enabled` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`lfp` tinyint(1) unsigned NOT NULL DEFAULT '0', " + "`lfg` tinyint(1) unsigned NOT NULL DEFAULT '0', " + "`mailkey` char(16) NOT NULL DEFAULT '', " + "`xtargets` tinyint(3) unsigned NOT NULL DEFAULT '5', " + "`firstlogon` tinyint(3) NOT NULL DEFAULT '0', " + "`e_aa_effects` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`e_percent_to_aa` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`e_expended_aa_spent` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "PRIMARY KEY(`id`), " + "UNIQUE KEY `name` (`name`), " + "KEY `account_id` (`account_id`) " + ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1; " + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + /* Check for table `character_currency` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_currency'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_currency` doesn't exist... creating..."); + rquery = StringFormat( + " CREATE TABLE `character_currency` ( " + " `id` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `platinum` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `gold` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `silver` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `copper` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `platinum_bank` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `gold_bank` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `silver_bank` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `copper_bank` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `platinum_cursor` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `gold_cursor` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `silver_cursor` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `copper_cursor` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `radiant_crystals` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `career_radiant_crystals` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `ebon_crystals` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `career_ebon_crystals` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " PRIMARY KEY (`id`), " + " KEY `id` (`id`) " + " ) ENGINE=InnoDB DEFAULT CHARSET=latin1; " + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + /* Check for table `character_alternate_abilities` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_alternate_abilities'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_alternate_abilities` doesn't exist... creating..."); + rquery = StringFormat( + " CREATE TABLE `character_alternate_abilities` ( " + " `id` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `slot` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " + " `aa_id` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " + " `aa_value` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " + " PRIMARY KEY(`id`,`slot`), " + " KEY `id` (`id`) " + " ) ENGINE = InnoDB DEFAULT CHARSET = latin1; " + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + /* Check for table `character_bind` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_bind'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_bind` doesn't exist... creating..."); + rquery = StringFormat( + "CREATE TABLE `character_bind` ( " + "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " + "`is_home` tinyint(11) UNSIGNED NOT NULL DEFAULT '0', " + "`zone_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " + "`instance_id` mediumint(11) UNSIGNED NOT NULL DEFAULT '0', " + "`x` float NOT NULL DEFAULT '0', " + "`y` float NOT NULL DEFAULT '0', " + "`z` float NOT NULL DEFAULT '0', " + "`heading` float NOT NULL DEFAULT '0', " + "PRIMARY KEY(`id`, `is_home`), " + "KEY `id` (`id`) " + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + /* Check for table `character_languages` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_languages'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_languages` doesn't exist... creating..."); + rquery = StringFormat( + "CREATE TABLE `character_languages` ( " + "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " + "`lang_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " + "`value` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " + "PRIMARY KEY(`id`, `lang_id`), " + "KEY `id` (`id`) " + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + /* Check for table `character_skills` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_skills'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_skills` doesn't exist... creating..."); + rquery = StringFormat( + "CREATE TABLE `character_skills` ( " + "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " + "`skill_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " + "`value` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " + "PRIMARY KEY(`id`, `skill_id`), " + "KEY `id` (`id`) " + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + /* Check for table `character_spells` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_spells'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_spells` doesn't exist... creating..."); + rquery = StringFormat( + "CREATE TABLE `character_spells` ( " + "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, " + "`slot_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " + "`spell_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " + "PRIMARY KEY(`id`, `slot_id`), " + "KEY `id` (`id`) " + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + /* Check for table `character_memmed_spells` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_memmed_spells'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_memmed_spells` doesn't exist... creating..."); + rquery = StringFormat( + "CREATE TABLE `character_memmed_spells` ( " + "`id` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`slot_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " + "`spell_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " + "PRIMARY KEY(`id`, `slot_id`), " + "KEY `id` (`id`) " + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + /* Check for table `character_disciplines` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_disciplines'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_disciplines` doesn't exist... creating..."); + rquery = StringFormat( + " CREATE TABLE `character_disciplines` ( " + " `id` int(11) UNSIGNED NOT NULL DEFAULT 0, " + " `slot_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " + " `disc_id` smallint(11) UNSIGNED NOT NULL DEFAULT '0', " + " PRIMARY KEY(`id`, `slot_id`), " + " KEY `id` (`id`) " + " ) ENGINE = InnoDB DEFAULT CHARSET = latin1; " + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + /* Check for table `character_material` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_material'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_material` doesn't exist... creating..."); + rquery = StringFormat( + "CREATE TABLE `character_material` ( " + "`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT," + "`slot` tinyint(11) UNSIGNED NOT NULL DEFAULT '0'," + "`blue` tinyint(11) UNSIGNED NOT NULL DEFAULT '0'," + "`green` tinyint(11) UNSIGNED NOT NULL DEFAULT '0'," + "`red` tinyint(11) UNSIGNED NOT NULL DEFAULT '0'," + "`use_tint` tinyint(11) UNSIGNED NOT NULL DEFAULT '0'," + "`color` int(11) UNSIGNED NOT NULL DEFAULT '0'," + "PRIMARY KEY(`id`, `slot`)," + "KEY `id` (`id`)" + ") ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;" + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + /* Check for table `character_tribute` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_tribute'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_tribute` doesn't exist... creating..."); + rquery = StringFormat( + "CREATE TABLE `character_tribute` ( " + "`id` int(11) unsigned NOT NULL DEFAULT 0, " + "`tier` tinyint(11) unsigned NOT NULL DEFAULT '0', " + "`tribute` int(11) UNSIGNED NOT NULL DEFAULT '0', " + "KEY `id` (`id`) " + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + /* Check for table `character_bandolier` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_bandolier'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_bandolier` doesn't exist... creating..."); + rquery = StringFormat( + "CREATE TABLE `character_bandolier` ( " + "`id` int(11) unsigned NOT NULL DEFAULT 0, " + "`bandolier_id` tinyint(11) unsigned NOT NULL DEFAULT '0', " + "`bandolier_slot` tinyint(11) unsigned NOT NULL DEFAULT '0', " + "`item_id` int(11) UNSIGNED NOT NULL DEFAULT '0', " + "`icon` int(11) UNSIGNED NOT NULL DEFAULT '0', " + "`bandolier_name` varchar(32) NOT NULL DEFAULT '0', " + "PRIMARY KEY(`id`,`bandolier_id`, `bandolier_slot`), " + "KEY `id` (`id`) " + ") ENGINE = InnoDB DEFAULT CHARSET = latin1; " + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + /* Check for table `character_potionbelt` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_potionbelt'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_potionbelt` doesn't exist... creating..."); + rquery = StringFormat( + "CREATE TABLE `character_potionbelt` ( " + "`id` int(11) unsigned NOT NULL DEFAULT 0, " + "`potion_id` tinyint(11) unsigned NOT NULL DEFAULT '0', " + "`item_id` int(11) UNSIGNED NOT NULL DEFAULT '0', " + "`icon` int(11) UNSIGNED NOT NULL DEFAULT '0', " + "PRIMARY KEY(`id`,`potion_id`), " + "KEY `id` (`id`) " + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + /* Check for table `character_potionbelt` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_inspect_messages'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_inspect_messages` doesn't exist... creating..."); + rquery = StringFormat( + "CREATE TABLE `character_inspect_messages` ( " + "`id` int(11) unsigned NOT NULL DEFAULT 0, " + "`inspect_message` varchar(255) NOT NULL DEFAULT '', " + "PRIMARY KEY(`id`), " + "KEY `id` (`id`) " + ") ENGINE = InnoDB DEFAULT CHARSET = latin1;" + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + /* Check for table `character_leadership_abilities` */ + rquery = StringFormat("SHOW TABLES LIKE 'character_leadership_abilities'"); + results = QueryDatabase(rquery); + if (results.RowCount() == 0){ + printf("Table: `character_leadership_abilities` doesn't exist... creating..."); + rquery = StringFormat( + "CREATE TABLE `character_leadership_abilities` (" + "`id` int(11) UNSIGNED NOT NULL DEFAULT 0, " + "`slot` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " + "`rank` smallint(11) UNSIGNED NOT NULL DEFAULT 0, " + "PRIMARY KEY(`id`,`slot`), " + "KEY `id` (`id`) " + ") ENGINE = InnoDB DEFAULT CHARSET = latin1; " + ); + auto results = QueryDatabase(rquery); + printf(" done...\n"); + } + + /* Done */ + printf("Starting conversion...\n\n"); + + + int char_iter_count = 0; + rquery = StringFormat("SELECT `id` FROM `character_`"); + results = QueryDatabase(rquery); + + uint8 firstlogon = 0; + uint8 lfg = 0; + uint8 lfp = 0; + std::string mailkey; + uint8 xtargets = 0; + std::string inspectmessage; + + for (auto row = results.begin(); row != results.end(); ++row) { + char_iter_count++; + squery = StringFormat("SELECT `id`, `profile`, `name`, `level`, `account_id`, `firstlogon`, `lfg`, `lfp`, `mailkey`, `xtargets`, `inspectmessage`, `extprofile` FROM `character_` WHERE `id` = %i", atoi(row[0])); + auto results2 = QueryDatabase(squery); + auto row2 = results2.begin(); + pp = (Convert::PlayerProfile_Struct*)row2[1]; + e_pp = (ExtendedProfile_Struct*)row2[11]; + character_id = atoi(row[0]); + account_id = atoi(row2[4]); + /* Convert some data from the character_ table that is still relevant */ + firstlogon = atoi(row2[5]); + lfg = atoi(row2[6]); + lfp = atoi(row2[7]); + mailkey = row2[8]; + xtargets = atoi(row2[9]); + inspectmessage = row2[10]; + + /* Verify PP Integrity */ + lengths = results2.LengthOfColumn(1); + if (lengths == sizeof(Convert::PlayerProfile_Struct)) { /* If PP is the size it is expected to be */ + memcpy(pp, row2[1], sizeof(Convert::PlayerProfile_Struct)); + } + /* Continue of PP Size does not match (Usually a created character never logged in) */ + else { + std::cout << (row2[2] ? row2[2] : "Unknown") << " ID: " << character_id << " size mismatch. Expected Size: " << sizeof(Convert::PlayerProfile_Struct) << " Seen: " << lengths << std::endl; + continue; + } + + lengths_e = results2.LengthOfColumn(11); + if (lengths_e == sizeof(ExtendedProfile_Struct)) { + memcpy(e_pp, row2[11], sizeof(ExtendedProfile_Struct)); + } + if (e_pp->expended_aa > 4000000){ e_pp->expended_aa = 0; } + + /* Loading Status on conversion */ + if (runconvert == 1){ + std::cout << "\r" << char_iter_count << "/" << number_of_characters << " " << std::flush; + loadbar(char_iter_count, number_of_characters, 50); + + /* Run inspect message convert */ + if (inspectmessage != ""){ + std::string rquery = StringFormat("REPLACE INTO `character_inspect_messages` (id, inspect_message)" + "VALUES (%u, '%s')", + character_id, + EscapeString(inspectmessage).c_str() + ); + auto results = QueryDatabase(rquery); + } + + /* Run Currency Convert */ + std::string rquery = StringFormat("REPLACE INTO `character_currency` (id, platinum, gold, silver, copper," + "platinum_bank, gold_bank, silver_bank, copper_bank," + "platinum_cursor, gold_cursor, silver_cursor, copper_cursor, " + "radiant_crystals, career_radiant_crystals, ebon_crystals, career_ebon_crystals)" + "VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u)", + character_id, + pp->platinum, + pp->gold, + pp->silver, + pp->copper, + pp->platinum_bank, + pp->gold_bank, + pp->silver_bank, + pp->copper_bank, + pp->platinum_cursor, + pp->gold_cursor, + pp->silver_cursor, + pp->copper_cursor, + pp->currentRadCrystals, + pp->careerRadCrystals, + pp->currentEbonCrystals, + pp->careerEbonCrystals + ); + auto results = QueryDatabase(rquery); + + if (pp->tribute_time_remaining < 0 || pp->tribute_time_remaining == 4294967295){ pp->tribute_time_remaining = 0; } + + /* Run Character Data Convert */ + rquery = StringFormat( + "REPLACE INTO `character_data` (" + "id," + "account_id," + "`name`," + "last_name," + "gender," + "race," + "class," + "`level`," + "deity," + "birthday," + "last_login," + "time_played," + "pvp_status," + "level2," + "anon," + "gm," + "intoxication," + "hair_color," + "beard_color," + "eye_color_1," + "eye_color_2," + "hair_style," + "beard," + "ability_time_seconds," + "ability_number," + "ability_time_minutes," + "ability_time_hours," + "title," + "suffix," + "exp," + "points," + "mana," + "cur_hp," + "str," + "sta," + "cha," + "dex," + "`int`," + "agi," + "wis," + "face," + "y," + "x," + "z," + "heading," + "pvp2," + "pvp_type," + "autosplit_enabled," + "zone_change_count," + "drakkin_heritage," + "drakkin_tattoo," + "drakkin_details," + "toxicity," + "hunger_level," + "thirst_level," + "ability_up," + "zone_id," + "zone_instance," + "leadership_exp_on," + "ldon_points_guk," + "ldon_points_mir," + "ldon_points_mmc," + "ldon_points_ruj," + "ldon_points_tak," + "ldon_points_available," + "tribute_time_remaining," + "show_helm," + "career_tribute_points," + "tribute_points," + "tribute_active," + "endurance," + "group_leadership_exp," + "raid_leadership_exp," + "group_leadership_points," + "raid_leadership_points," + "air_remaining," + "pvp_kills," + "pvp_deaths," + "pvp_current_points," + "pvp_career_points," + "pvp_best_kill_streak," + "pvp_worst_death_streak," + "pvp_current_kill_streak," + "aa_points_spent," + "aa_exp," + "aa_points," + "group_auto_consent," + "raid_auto_consent," + "guild_auto_consent," + "RestTimer," + "firstlogon," + "lfg," + "lfp," + "mailkey," + "xtargets," + "e_aa_effects," + "e_percent_to_aa," + "e_expended_aa_spent" + ")" + "VALUES (" + "%u," // id + "%u," // account_id + "'%s'," // `name` + "'%s'," // last_name + "%u," // gender + "%u," // race + "%u," // class + "%u," // `level` + "%u," // deity + "%u," // birthday + "%u," // last_login + "%u," // time_played + "%u," // pvp_status + "%u," // level2 + "%u," // anon + "%u," // gm + "%u," // intoxication + "%u," // hair_color + "%u," // beard_color + "%u," // eye_color_1 + "%u," // eye_color_2 + "%u," // hair_style + "%u," // beard + "%u," // ability_time_seconds + "%u," // ability_number + "%u," // ability_time_minutes + "%u," // ability_time_hours + "'%s'," // title + "'%s'," // suffix + "%u," // exp + "%u," // points + "%u," // mana + "%u," // cur_hp + "%u," // str + "%u," // sta + "%u," // cha + "%u," // dex + "%u," // `int` + "%u," // agi + "%u," // wis + "%u," // face + "%f," // y + "%f," // x + "%f," // z + "%f," // heading + "%u," // pvp2 + "%u," // pvp_type + "%u," // autosplit_enabled + "%u," // zone_change_count + "%u," // drakkin_heritage + "%u," // drakkin_tattoo + "%u," // drakkin_details + "%i," // toxicity + "%u," // hunger_level + "%u," // thirst_level + "%u," // ability_up + "%u," // zone_id + "%u," // zone_instance + "%u," // leadership_exp_on + "%u," // ldon_points_guk + "%u," // ldon_points_mir + "%u," // ldon_points_mmc + "%u," // ldon_points_ruj + "%u," // ldon_points_tak + "%u," // ldon_points_available + "%u," // tribute_time_remaining + "%u," // show_helm + "%u," // career_tribute_points + "%u," // tribute_points + "%u," // tribute_active + "%u," // endurance + "%u," // group_leadership_exp + "%u," // raid_leadership_exp + "%u," // group_leadership_points + "%u," // raid_leadership_points + "%u," // air_remaining + "%u," // pvp_kills + "%u," // pvp_deaths + "%u," // pvp_current_points + "%u," // pvp_career_points + "%u," // pvp_best_kill_streak + "%u," // pvp_worst_death_streak + "%u," // pvp_current_kill_streak + "%u," // aa_points_spent + "%u," // aa_exp + "%u," // aa_points + "%u," // group_auto_consent + "%u," // raid_auto_consent + "%u," // guild_auto_consent + "%u," // RestTimer + "%u," // First Logon - References online status for EVENT_CONNECT/EVENT_DISCONNECt + "%u," // Looking for Group + "%u," // Looking for P? + "'%s'," // Mailkey + "%u," // X Targets + "%u," // AA Effects + "%u," // Percent to AA + "%u" // e_expended_aa_spent + ")", + character_id, + account_id, + EscapeString(pp->name).c_str(), + EscapeString(pp->last_name).c_str(), + pp->gender, + pp->race, + pp->class_, + pp->level, + pp->deity, + pp->birthday, + pp->lastlogin, + pp->timePlayedMin, + pp->pvp, + pp->level2, + pp->anon, + pp->gm, + pp->intoxication, + pp->haircolor, + pp->beardcolor, + pp->eyecolor1, + pp->eyecolor2, + pp->hairstyle, + pp->beard, + pp->ability_time_seconds, + pp->ability_number, + pp->ability_time_minutes, + pp->ability_time_hours, + EscapeString(pp->title).c_str(), + EscapeString(pp->suffix).c_str(), + pp->exp, + pp->points, + pp->mana, + pp->cur_hp, + pp->STR, + pp->STA, + pp->CHA, + pp->DEX, + pp->INT, + pp->AGI, + pp->WIS, + pp->face, + pp->y, + pp->x, + pp->z, + pp->heading, + pp->pvp2, + pp->pvptype, + pp->autosplit, + pp->zone_change_count, + pp->drakkin_heritage, + pp->drakkin_tattoo, + pp->drakkin_details, + pp->toxicity, + pp->hunger_level, + pp->thirst_level, + pp->ability_up, + pp->zone_id, + pp->zoneInstance, + pp->leadAAActive == 0 ? 0 : 1, + pp->ldon_points_guk, + pp->ldon_points_mir, + pp->ldon_points_mmc, + pp->ldon_points_ruj, + pp->ldon_points_tak, + pp->ldon_points_available, + pp->tribute_time_remaining, + pp->showhelm, + pp->career_tribute_points, + pp->tribute_points, + pp->tribute_active, + pp->endurance, + pp->group_leadership_exp, + pp->raid_leadership_exp, + pp->group_leadership_points, + pp->raid_leadership_points, + pp->air_remaining, + pp->PVPKills, + pp->PVPDeaths, + pp->PVPCurrentPoints, + pp->PVPCareerPoints, + pp->PVPBestKillStreak, + pp->PVPWorstDeathStreak, + pp->PVPCurrentKillStreak, + pp->aapoints_spent, + pp->expAA, + pp->aapoints, + pp->groupAutoconsent, + pp->raidAutoconsent, + pp->guildAutoconsent, + pp->RestTimer, + firstlogon, + lfg, + lfp, + mailkey.c_str(), + xtargets, + e_pp->aa_effects, + e_pp->perAA, + e_pp->expended_aa + ); + results = QueryDatabase(rquery); + + + /* + We set a first entry variable because we need the first initial piece of the query to be declared + This is to speed up the INSERTS and trim down the amount of individual sends during the process. + The speed difference is dramatic + */ + /* Run AA Convert */ + int first_entry = 0; rquery = ""; + for (i = 0; i < MAX_PP_AA_ARRAY; i++){ + if (pp->aa_array[i].AA > 0 && pp->aa_array[i].value > 0){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, slot, aa_id, aa_value)" + " VALUES (%u, %u, %u, %u)", character_id, i, pp->aa_array[i].AA, pp->aa_array[i].value); + first_entry = 1; + } + else { + rquery = rquery + StringFormat(", (%u, %u, %u, %u)", character_id, i, pp->aa_array[i].AA, pp->aa_array[i].value); + } + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + + /* Run Bind Home Convert */ + if (pp->binds[4].zoneId < 999 && !_ISNAN_(pp->binds[4].x) && !_ISNAN_(pp->binds[4].y) && !_ISNAN_(pp->binds[4].z) && !_ISNAN_(pp->binds[4].heading)) { + rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" + " VALUES (%u, %u, %u, %f, %f, %f, %f, 1)", + character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading); + if (rquery != ""){ results = QueryDatabase(rquery); } + } + + /* Run Bind Convert */ + if (pp->binds[0].zoneId < 999 && !_ISNAN_(pp->binds[0].x) && !_ISNAN_(pp->binds[0].y) && !_ISNAN_(pp->binds[0].z) && !_ISNAN_(pp->binds[0].heading)) { + rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)" + " VALUES (%u, %u, %u, %f, %f, %f, %f, 0)", + character_id, pp->binds[0].zoneId, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading); + if (rquery != ""){ results = QueryDatabase(rquery); } + } + /* Run Language Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < MAX_PP_LANGUAGE; i++){ + if (pp->languages[i] > 0){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_languages` (id, lang_id, value) VALUES (%u, %u, %u)", character_id, i, pp->languages[i]); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->languages[i]); + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Skill Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < MAX_PP_SKILL; i++){ + if (pp->skills[i] > 0){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_skills` (id, skill_id, value) VALUES (%u, %u, %u)", character_id, i, pp->skills[i]); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->skills[i]); + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Spell Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < MAX_PP_REF_SPELLBOOK; i++){ + if (pp->spell_book[i] > 0 && pp->spell_book[i] != 4294967295 && pp->spell_book[i] < 40000 && pp->spell_book[i] != 1){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, i, pp->spell_book[i]); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->spell_book[i]); + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Max Memmed Spell Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < MAX_PP_REF_MEMSPELL; i++){ + if (pp->mem_spells[i] > 0 && pp->mem_spells[i] != 65535 && pp->mem_spells[i] != 4294967295){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_memmed_spells` (id, slot_id, spell_id) VALUES (%u, %u, %u)", character_id, i, pp->mem_spells[i]); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->mem_spells[i]); + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Discipline Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < MAX_PP_DISCIPLINES; i++){ + if (pp->disciplines.values[i] > 0 && pp->disciplines.values[i] < 60000){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_disciplines` (id, slot_id, disc_id) VALUES (%u, %u, %u)", character_id, i, pp->disciplines.values[i]); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, i, pp->disciplines.values[i]); + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Material Color Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < _MaterialCount; i++){ + if (pp->item_tint[i].color > 0){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_material` (id, slot, blue, green, red, use_tint, color) VALUES (%u, %u, %u, %u, %u, %u, %u)", character_id, i, pp->item_tint[i].rgb.blue, pp->item_tint[i].rgb.green, pp->item_tint[i].rgb.red, pp->item_tint[i].rgb.use_tint, pp->item_tint[i].color); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u)", character_id, i, pp->item_tint[i].rgb.blue, pp->item_tint[i].rgb.green, pp->item_tint[i].rgb.red, pp->item_tint[i].rgb.use_tint, pp->item_tint[i].color); + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Tribute Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < EmuConstants::TRIBUTE_SIZE; i++){ + if (pp->tributes[i].tribute > 0 && pp->tributes[i].tribute != 4294967295){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_tribute` (id, tier, tribute) VALUES (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%u, %u, %u)", character_id, pp->tributes[i].tier, pp->tributes[i].tribute); + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Bandolier Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < EmuConstants::BANDOLIERS_COUNT; i++){ + if (strlen(pp->bandoliers[i].name) < 32) { + for (int si = 0; si < EmuConstants::BANDOLIER_SIZE; si++){ + if (pp->bandoliers[i].items[si].item_id > 0){ + if (first_entry != 1) { + rquery = StringFormat("REPLACE INTO `character_bandolier` (id, bandolier_id, bandolier_slot, item_id, icon, bandolier_name) VALUES (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].items[si].item_id, pp->bandoliers[i].items[si].icon, pp->bandoliers[i].name); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%i, %u, %i, %u, %u, '%s')", character_id, i, si, pp->bandoliers[i].items[si].item_id, pp->bandoliers[i].items[si].icon, pp->bandoliers[i].name); + } + } + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Potion Belt Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < EmuConstants::POTION_BELT_SIZE; i++){ + if (pp->potionbelt.items[i].item_id > 0){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_potionbelt` (id, potion_id, item_id, icon) VALUES (%i, %u, %u, %u)", character_id, i, pp->potionbelt.items[i].item_id, pp->potionbelt.items[i].icon); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%i, %u, %u, %u)", character_id, i, pp->potionbelt.items[i].item_id, pp->potionbelt.items[i].icon); + + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + /* Run Leadership AA Convert */ + first_entry = 0; rquery = ""; + for (i = 0; i < MAX_LEADERSHIP_AA_ARRAY; i++){ + if (pp->leader_abilities.ranks[i] > 0 && pp->leader_abilities.ranks[i] < 6){ + if (first_entry != 1){ + rquery = StringFormat("REPLACE INTO `character_leadership_abilities` (id, slot, rank) VALUES (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]); + first_entry = 1; + } + rquery = rquery + StringFormat(", (%i, %u, %u)", character_id, i, pp->leader_abilities.ranks[i]); + } + } + if (rquery != ""){ results = QueryDatabase(rquery); } + } + } + if (runconvert == 1){ + std::string rquery = StringFormat("RENAME TABLE `character_` TO `character_old`"); QueryDatabase(rquery); + printf("\n\nRenaming `character_` table to `character_old`, this is a LARGE table so when you don't need it anymore, I would suggest deleting it yourself...\n"); + printf("\n\nCharacter blob conversion complete, continuing world bootup...\n"); + } + } + return true; +} + +bool Database::CheckDatabaseConvertBotsPostPPDeblob(){ +#ifdef BOTS + int runbotsconvert = 0; + + /* Check For Legacy Bot References */ + std::string rquery = StringFormat("SHOW CREATE VIEW `vwBotCharacterMobs`"); + auto results = QueryDatabase(rquery); + if (results.RowCount() == 1){ + auto row = results.begin(); + std::string table_check = row[1]; + + if (table_check.find("character_data") == -1){ + runbotsconvert = 1; + printf("\n\n::: Legacy Bot Views and Function Detected... \n"); + printf("----------------------------------------------------------\n\n"); + printf(" Database currently has bot view/function linkage to obselete \n"); + printf(" table references and will now be converted...\n\n"); + printf(" It is recommended that you backup your database \n"); + printf(" before continuing the automatic conversion process...\n\n"); + printf("----------------------------------------------------------\n\n"); + std::cout << "Press ENTER to continue....." << std::endl << std::endl; + std::cin.ignore(1); + } + } + + if (runbotsconvert == 1){ + printf("Running bot views/function database conversion... \n"); + + /* Update view `vwbotcharactermobs` */ + rquery = StringFormat("DROP VIEW `vwBotCharacterMobs`;"); + results = QueryDatabase(rquery); + + rquery = StringFormat( + "CREATE VIEW `vwBotCharacterMobs` AS\n" + "SELECT _utf8'C' AS mobtype,\n" // Natedog: '_utf8' + "c.`id`,\n" + "c.`name`,\n" + "c.`class`,\n" + "c.`level`,\n" + "c.`last_login`,\n" + "c.`zone_id`\n" + "FROM `character_data` AS c\n" + "UNION ALL\n" + "SELECT _utf8'B' AS mobtype,\n" // Natedog: '_utf8' + "b.`BotID` AS id,\n" + "b.`Name` AS name,\n" + "b.`Class` AS class,\n" + "b.`BotLevel` AS level,\n" + "0 AS timelaston,\n" + "0 AS zoneid\n" + "FROM bots AS b;" + ); + results = QueryDatabase(rquery); + + + /* Update function `GetMobType` */ + rquery = StringFormat("DROP FUNCTION IF EXISTS `GetMobType`;"); + results = QueryDatabase(rquery); + + rquery = StringFormat( + "CREATE FUNCTION `GetMobType` (mobname VARCHAR(64)) RETURNS CHAR(1)\n" + "BEGIN\n" + " DECLARE Result CHAR(1);\n" + "\n" + " SET Result = NULL;\n" + "\n" + " IF (SELECT COUNT(*) FROM `character_data` WHERE `name` = mobname) > 0 THEN\n" + " SET Result = 'C';\n" + " ELSEIF (SELECT COUNT(*) FROM `bots` WHERE `Name` = mobname) > 0 THEN\n" + " SET Result = 'B';\n" + " END IF;\n " + "\n" + " RETURN Result;\n" + "END" + ); + results = QueryDatabase(rquery); + + + /* Update view `vwgroups` */ + rquery = StringFormat("DROP VIEW IF EXISTS `vwGroups`;"); + results = QueryDatabase(rquery); + + rquery = StringFormat( + "CREATE VIEW `vwGroups` AS\n" + "SELECT g.`groupid` AS groupid,\n" + "GetMobType(g.`name`) AS mobtype,\n" + "g.`name` AS name,\n" + "g.`charid` AS mobid,\n" + "IFNULL(c.`level`, b.`BotLevel`) AS level\n" + "FROM `group_id` AS g\n" + "LEFT JOIN `character_data` AS c ON g.`name` = c.`name`\n" + "LEFT JOIN `bots` AS b ON g.`name` = b.`Name`;" + ); + results = QueryDatabase(rquery); + + + /* Update view `vwbotgroups` */ + rquery = StringFormat("DROP VIEW IF EXISTS `vwBotGroups`;"); + results = QueryDatabase(rquery); + + rquery = StringFormat( + "CREATE VIEW `vwBotGroups` AS\n" + "SELECT g.`BotGroupId`,\n" + "g.`BotGroupName`,\n" + "g.`BotGroupLeaderBotId`,\n" + "b.`Name` AS BotGroupLeaderName,\n" + "b.`BotOwnerCharacterId`,\n" + "c.`name` AS BotOwnerCharacterName\n" + "FROM `botgroup` AS g\n" + "JOIN `bots` AS b ON g.`BotGroupLeaderBotId` = b.`BotID`\n" + "JOIN `character_data` AS c ON b.`BotOwnerCharacterID` = c.`id`\n" + "ORDER BY b.`BotOwnerCharacterId`, g.`BotGroupName`;" + ); + results = QueryDatabase(rquery); + + + /* Update view `vwguildmembers` */ + rquery = StringFormat("DROP VIEW IF EXISTS `vwGuildMembers`;"); + results = QueryDatabase(rquery); + + rquery = StringFormat( + "CREATE VIEW `vwGuildMembers` AS\n" + "SELECT 'C' AS mobtype,\n" + "cm.`char_id`,\n" + "cm.`guild_id`,\n" + "cm.`rank`,\n" + "cm.`tribute_enable`,\n" + "cm.`total_tribute`,\n" + "cm.`last_tribute`,\n" + "cm.`banker`,\n" + "cm.`public_note`,\n" + "cm.`alt`\n" + "FROM `guild_members` AS cm\n" + "UNION ALL\n" + "SELECT 'B' AS mobtype,\n" + "bm.`char_id`,\n" + "bm.`guild_id`,\n" + "bm.`rank`,\n" + "bm.`tribute_enable`,\n" + "bm.`total_tribute`,\n" + "bm.`last_tribute`,\n" + "bm.`banker`,\n" + "bm.`public_note`,\n" + "bm.`alt`\n" + "FROM `botguildmembers` AS bm;" + ); + results = QueryDatabase(rquery); + } + + if (runbotsconvert == 1){ + printf("\n\nBot views/function conversion complete, continuing world bootup...\n"); + } + +#endif + return true; +} + +bool Database::CheckDatabaseConvertCorpseDeblob(){ + Convert::DBPlayerCorpse_Struct_temp* dbpc; + Convert::classic_db_temp::DBPlayerCorpse_Struct_temp* dbpc_c; + uint32 in_datasize; + bool is_sof = false; + std::string c_type; + std::string scquery; + int8 first_entry = 0; + + std::string query = StringFormat("SHOW TABLES LIKE 'player_corpses'"); + auto results = QueryDatabase(query); + if (results.RowCount() != 0){ + query = StringFormat( + "CREATE TABLE `character_corpse_items` ( " + "`corpse_id` int(11) unsigned NOT NULL, " + "`equip_slot` int(11) unsigned NOT NULL, " + "`item_id` int(11) unsigned DEFAULT NULL, " + "`charges` int(11) unsigned DEFAULT NULL, " + "`aug_1` int(11) unsigned DEFAULT '0', " + "`aug_2` int(11) unsigned DEFAULT '0', " + "`aug_3` int(11) unsigned DEFAULT '0', " + "`aug_4` int(11) unsigned DEFAULT '0', " + "`aug_5` int(11) unsigned DEFAULT '0', " + "`aug_6` int(11) unsigned DEFAULT '0', " + "`attuned` smallint(5) NOT NULL DEFAULT '0', " + "PRIMARY KEY(`corpse_id`, `equip_slot`) " + ") ENGINE = InnoDB DEFAULT CHARSET = latin1; " + ); + results = QueryDatabase(query); + query = StringFormat("RENAME TABLE `player_corpses` TO `character_corpses`"); + results = QueryDatabase(query); + query = StringFormat( + " ALTER TABLE `character_corpses` \n" + " ADD COLUMN `is_locked` tinyint(11) NULL DEFAULT 0 AFTER `WasAtGraveyard`, \n" + " ADD COLUMN `exp` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `size` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `level` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `race` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `gender` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `class` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `deity` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `texture` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `helm_texture` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `copper` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `silver` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `gold` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `platinum` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `hair_color` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `beard_color` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `eye_color_1` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `eye_color_2` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `hair_style` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `face` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `beard` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `drakkin_heritage` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `drakkin_tattoo` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `drakkin_details` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_1` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_2` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_3` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_4` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_5` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_6` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_7` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_8` int(11) UNSIGNED NULL DEFAULT 0, \n" + " ADD COLUMN `wc_9` int(11) UNSIGNED NULL DEFAULT 0, \n" + " CHANGE COLUMN `zoneid` `zone_id` smallint(5) NOT NULL DEFAULT 0 AFTER `charname`, \n" + " CHANGE COLUMN `instanceid` `instance_id` smallint(5) UNSIGNED NOT NULL DEFAULT 0 AFTER `zone_id`, \n" + " CHANGE COLUMN `timeofdeath` `time_of_death` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER `data`, \n" + " CHANGE COLUMN `rezzed` `is_rezzed` tinyint(3) UNSIGNED NULL DEFAULT 0 AFTER `time_of_death`, \n" + " CHANGE COLUMN `IsBurried` `is_buried` tinyint(3) NOT NULL DEFAULT 0 AFTER `is_rezzed`; \n" + + ); + results = QueryDatabase(query); + query = StringFormat( + " ALTER TABLE `character_corpses` \n" + " CHANGE COLUMN `WasAtGraveyard` `was_at_graveyard` tinyint(3) NOT NULL DEFAULT 0 AFTER `is_buried` \n" + ); + results = QueryDatabase(query); + } + + std::string rquery = StringFormat("SHOW COLUMNS FROM `character_corpses` LIKE 'data'"); + results = QueryDatabase(rquery); + if (results.RowCount() != 0){ + rquery = StringFormat("SELECT DISTINCT charid FROM character_corpses"); + results = QueryDatabase(rquery); + for (auto row = results.begin(); row != results.end(); ++row) { + std::string squery = StringFormat("SELECT id, charname, data, time_of_death, is_rezzed FROM character_corpses WHERE `charid` = %i", atoi(row[0])); + auto results2 = QueryDatabase(squery); + for (auto row2 = results2.begin(); row2 != results2.end(); ++row2) { + in_datasize = results2.LengthOfColumn(2); + dbpc = (Convert::DBPlayerCorpse_Struct_temp*)row2[2]; + dbpc_c = (Convert::classic_db_temp::DBPlayerCorpse_Struct_temp*)row2[2]; + + if (dbpc == nullptr) + continue; + if (dbpc_c == nullptr) + continue; + + + /* SoF+ */ + uint32 esize1 = (sizeof(Convert::DBPlayerCorpse_Struct_temp) + (dbpc->itemcount * sizeof(Convert::player_lootitem_temp::ServerLootItem_Struct_temp))); + uint32 esize2 = (sizeof(Convert::classic_db_temp::DBPlayerCorpse_Struct_temp) + (dbpc_c->itemcount * sizeof(Convert::player_lootitem_temp::ServerLootItem_Struct_temp))); + + /* SoF */ + if (in_datasize == esize1) { + is_sof = true; + c_type = "SOF"; + } + /* Classic */ + if (in_datasize == esize2) { + is_sof = false; + c_type = "Legacy"; + } + if (in_datasize != esize2 && in_datasize != esize1) { + is_sof = false; + c_type = "NULL"; + continue; + } + std::cout << "Converting Corpse: [OK] [" << c_type << "]: " << "ID: " << atoi(row2[0]) << std::endl; + + if (is_sof){ + scquery = StringFormat("UPDATE `character_corpses` SET \n" + "`is_locked` = %d,\n" + "`exp` = %u,\n" + "`size` = %f,\n" + "`level` = %u,\n" + "`race` = %u,\n" + "`gender` = %u,\n" + "`class` = %u,\n" + "`deity` = %u,\n" + "`texture` = %u,\n" + "`helm_texture` = %u,\n" + "`copper` = %u,\n" + "`silver` = %u,\n" + "`gold` = %u,\n" + "`platinum` = %u,\n" + "`hair_color` = %u,\n" + "`beard_color` = %u,\n" + "`eye_color_1` = %u,\n" + "`eye_color_2` = %u,\n" + "`hair_style` = %u,\n" + "`face` = %u,\n" + "`beard` = %u,\n" + "`drakkin_heritage` = %u,\n" + "`drakkin_tattoo` = %u,\n" + "`drakkin_details` = %u,\n" + "`wc_1` = %u,\n" + "`wc_2` = %u,\n" + "`wc_3` = %u,\n" + "`wc_4` = %u,\n" + "`wc_5` = %u,\n" + "`wc_6` = %u,\n" + "`wc_7` = %u,\n" + "`wc_8` = %u,\n" + "`wc_9` = %u \n" + "WHERE `id` = %u \n", + dbpc->locked, + dbpc->exp, + dbpc->size, + dbpc->level, + dbpc->race, + dbpc->gender, + dbpc->class_, + dbpc->deity, + dbpc->texture, + dbpc->helmtexture, + dbpc->copper, + dbpc->silver, + dbpc->gold, + dbpc->plat, + dbpc->haircolor, + dbpc->beardcolor, + dbpc->eyecolor1, + dbpc->eyecolor2, + dbpc->hairstyle, + dbpc->face, + dbpc->beard, + dbpc->drakkin_heritage, + dbpc->drakkin_tattoo, + dbpc->drakkin_details, + dbpc->item_tint[0].color, + dbpc->item_tint[1].color, + dbpc->item_tint[2].color, + dbpc->item_tint[3].color, + dbpc->item_tint[4].color, + dbpc->item_tint[5].color, + dbpc->item_tint[6].color, + dbpc->item_tint[7].color, + dbpc->item_tint[8].color, + atoi(row2[0]) + ); + if (scquery != ""){ auto sc_results = QueryDatabase(scquery); } + + first_entry = 0; + scquery = ""; + /* Print Items */ + for (unsigned int i = 0; i < dbpc->itemcount; i++) { + if (first_entry != 1){ + scquery = StringFormat("REPLACE INTO `character_corpse_items` \n" + " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n" + " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", + atoi(row2[0]), + dbpc->items[i].equipSlot, + dbpc->items[i].item_id, + dbpc->items[i].charges, + dbpc->items[i].aug1, + dbpc->items[i].aug2, + dbpc->items[i].aug3, + dbpc->items[i].aug4, + dbpc->items[i].aug5, + dbpc->items[i].aug6, + dbpc->items[i].attuned + ); + first_entry = 1; + } + else{ + scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", + atoi(row2[0]), + dbpc->items[i].equipSlot, + dbpc->items[i].item_id, + dbpc->items[i].charges, + dbpc->items[i].aug1, + dbpc->items[i].aug2, + dbpc->items[i].aug3, + dbpc->items[i].aug4, + dbpc->items[i].aug5, + dbpc->items[i].aug6, + dbpc->items[i].attuned + ); + } + } + if (scquery != ""){ auto sc_results = QueryDatabase(scquery); } + } + else{ + /* Classic Converter */ + scquery = StringFormat("UPDATE `character_corpses` SET \n" + "`is_locked` = %d,\n" + "`exp` = %u,\n" + "`size` = %f,\n" + "`level` = %u,\n" + "`race` = %u,\n" + "`gender` = %u,\n" + "`class` = %u,\n" + "`deity` = %u,\n" + "`texture` = %u,\n" + "`helm_texture` = %u,\n" + "`copper` = %u,\n" + "`silver` = %u,\n" + "`gold` = %u,\n" + "`platinum` = %u,\n" + "`hair_color` = %u,\n" + "`beard_color` = %u,\n" + "`eye_color_1` = %u,\n" + "`eye_color_2` = %u,\n" + "`hair_style` = %u,\n" + "`face` = %u,\n" + "`beard` = %u,\n" + "`wc_1` = %u,\n" + "`wc_2` = %u,\n" + "`wc_3` = %u,\n" + "`wc_4` = %u,\n" + "`wc_5` = %u,\n" + "`wc_6` = %u,\n" + "`wc_7` = %u,\n" + "`wc_8` = %u,\n" + "`wc_9` = %u \n" + "WHERE `id` = %u \n", + dbpc_c->locked, + dbpc_c->exp, + dbpc_c->size, + dbpc_c->level, + dbpc_c->race, + dbpc_c->gender, + dbpc_c->class_, + dbpc_c->deity, + dbpc_c->texture, + dbpc_c->helmtexture, + dbpc_c->copper, + dbpc_c->silver, + dbpc_c->gold, + dbpc_c->plat, + dbpc_c->haircolor, + dbpc_c->beardcolor, + dbpc_c->eyecolor1, + dbpc_c->eyecolor2, + dbpc_c->hairstyle, + dbpc_c->face, + dbpc_c->beard, + dbpc_c->item_tint[0].color, + dbpc_c->item_tint[1].color, + dbpc_c->item_tint[2].color, + dbpc_c->item_tint[3].color, + dbpc_c->item_tint[4].color, + dbpc_c->item_tint[5].color, + dbpc_c->item_tint[6].color, + dbpc_c->item_tint[7].color, + dbpc_c->item_tint[8].color, + atoi(row2[0]) + ); + if (scquery != ""){ auto sc_results = QueryDatabase(scquery); } + + first_entry = 0; + scquery = ""; + + /* Print Items */ + for (unsigned int i = 0; i < dbpc_c->itemcount; i++) { + if (first_entry != 1){ + scquery = StringFormat("REPLACE INTO `character_corpse_items` \n" + " (corpse_id, equip_slot, item_id, charges, aug_1, aug_2, aug_3, aug_4, aug_5, aug_6, attuned) \n" + " VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", + atoi(row2[0]), + dbpc_c->items[i].equipSlot, + dbpc_c->items[i].item_id, + dbpc_c->items[i].charges, + dbpc_c->items[i].aug1, + dbpc_c->items[i].aug2, + dbpc_c->items[i].aug3, + dbpc_c->items[i].aug4, + dbpc_c->items[i].aug5, + dbpc_c->items[i].aug6, + dbpc_c->items[i].attuned + ); + first_entry = 1; + } + else{ + scquery = scquery + StringFormat(", (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u) \n", + atoi(row2[0]), + dbpc_c->items[i].equipSlot, + dbpc_c->items[i].item_id, + dbpc_c->items[i].charges, + dbpc_c->items[i].aug1, + dbpc_c->items[i].aug2, + dbpc_c->items[i].aug3, + dbpc_c->items[i].aug4, + dbpc_c->items[i].aug5, + dbpc_c->items[i].aug6, + dbpc_c->items[i].attuned + ); + } + } + if (scquery != ""){ auto sc_results = QueryDatabase(scquery); } + } + } + } + QueryDatabase(StringFormat("ALTER TABLE `character_corpses` DROP COLUMN `data`")); + } + return true; +} diff --git a/common/database_instances.cpp b/common/database_instances.cpp new file mode 100644 index 000000000..5350d71f9 --- /dev/null +++ b/common/database_instances.cpp @@ -0,0 +1,562 @@ +/* EQEMu: Everquest Server Emulator +Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY except by those people which sell it, which +are required to give you total support for your newly bought product; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "../common/global_define.h" +#include "../common/rulesys.h" +#include "../common/string_util.h" +#include "../common/timer.h" + +#include "database.h" + +#include +#include + +// Disgrace: for windows compile +#ifdef _WINDOWS +#include +#define snprintf _snprintf +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#else +#include "unix.h" +#include +#include +#endif + +bool Database::AddClientToInstance(uint16 instance_id, uint32 char_id) +{ + std::string query = StringFormat( + "REPLACE INTO `instance_list_player` (id, charid) " + "VALUES " + "(%lu, %lu)", + (unsigned long)instance_id, + (unsigned long)char_id + ); + auto results = QueryDatabase(query); + return results.Success(); +} + +bool Database::CharacterInInstanceGroup(uint16 instance_id, uint32 char_id) +{ + + std::string query = StringFormat("SELECT charid FROM instance_list_player where id=%u AND charid=%u", instance_id, char_id); + auto results = QueryDatabase(query); + + if (!results.Success()) + return false; + + if (results.RowCount() != 1) + return false; + + return true; +} + +bool Database::CheckInstanceExists(uint16 instance_id) { + std::string query = StringFormat( + "SELECT " + "`id` " + "FROM " + "`instance_list` " + "WHERE " + "`id` = %u", + instance_id + ); + auto results = QueryDatabase(query); + + if (!results.Success()) + return false; + + if (results.RowCount() == 0) + return false; + + return true; +} + +bool Database::CheckInstanceExpired(uint16 instance_id) +{ + + int32 start_time = 0; + int32 duration = 0; + uint32 never_expires = 0; + + std::string query = StringFormat("SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u", instance_id); + auto results = QueryDatabase(query); + + if (!results.Success()) + return true; + + if (results.RowCount() == 0) + return true; + + auto row = results.begin(); + + start_time = atoi(row[0]); + duration = atoi(row[1]); + never_expires = atoi(row[2]); + + if (never_expires == 1) + return false; + + timeval tv; + gettimeofday(&tv, nullptr); + + if ((start_time + duration) <= tv.tv_sec) + return true; + + return false; +} + +bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version, uint32 duration) +{ + std::string query = StringFormat("INSERT INTO instance_list (id, zone, version, start_time, duration)" + " values(%lu, %lu, %lu, UNIX_TIMESTAMP(), %lu)", + (unsigned long)instance_id, (unsigned long)zone_id, (unsigned long)version, (unsigned long)duration); + auto results = QueryDatabase(query); + + return results.Success(); +} + +bool Database::GetUnusedInstanceID(uint16 &instance_id) +{ + uint32 count = RuleI(Zone, ReservedInstances); + uint32 max = 65535; + + std::string query = StringFormat("SELECT IFNULL(MAX(id),%u)+1 FROM instance_list WHERE id > %u", count, count); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + instance_id = 0; + return false; + } + + if (results.RowCount() == 0) + { + instance_id = 0; + return false; + } + + auto row = results.begin(); + + if (atoi(row[0]) <= max) + { + instance_id = atoi(row[0]); + return true; + } + + query = StringFormat("SELECT id FROM instance_list where id > %u ORDER BY id", count); + results = QueryDatabase(query); + + if (!results.Success()) + { + instance_id = 0; + return false; + } + + if (results.RowCount() == 0) + { + instance_id = 0; + return false; + } + + count++; + for (auto row = results.begin(); row != results.end(); ++row) + { + if (count < atoi(row[0])) + { + instance_id = count; + return true; + } + + if (count > max) + { + instance_id = 0; + return false; + } + + count++; + } + + instance_id = count; + return true; +} + +bool Database::GlobalInstance(uint16 instance_id) +{ + std::string query = StringFormat( + "SELECT " + "is_global " + "FROM " + "instance_list " + "WHERE " + "id = %u " + "LIMIT 1 ", + instance_id + ); + auto results = QueryDatabase(query); + + if (!results.Success()) + return false; + + if (results.RowCount() == 0) + return false; + + auto row = results.begin(); + + return (atoi(row[0]) == 1) ? true : false; +} + +bool Database::RemoveClientFromInstance(uint16 instance_id, uint32 char_id) +{ + std::string query = StringFormat("DELETE FROM instance_list_player WHERE id=%lu AND charid=%lu", + (unsigned long)instance_id, (unsigned long)char_id); + auto results = QueryDatabase(query); + + return results.Success(); +} + + +bool Database::RemoveClientsFromInstance(uint16 instance_id) +{ + std::string query = StringFormat("DELETE FROM instance_list_player WHERE id=%lu", (unsigned long)instance_id); + auto results = QueryDatabase(query); + + return results.Success(); +} + +bool Database::VerifyInstanceAlive(uint16 instance_id, uint32 char_id) +{ + //we are not saved to this instance so set our instance to 0 + if (!GlobalInstance(instance_id) && !CharacterInInstanceGroup(instance_id, char_id)) + return false; + + if (CheckInstanceExpired(instance_id)) + { + DeleteInstance(instance_id); + return false; + } + + return true; +} + +bool Database::VerifyZoneInstance(uint32 zone_id, uint16 instance_id) +{ + + std::string query = StringFormat("SELECT id FROM instance_list where id=%u AND zone=%u", instance_id, zone_id); + auto results = QueryDatabase(query); + + if (!results.Success()) + return false; + + if (results.RowCount() == 0) + return false; + + return true; +} + +uint16 Database::GetInstanceID(const char* zone, uint32 character_id, int16 version) { + + std::string query = StringFormat( + "SELECT " + "instance_list.id " + "FROM " + "instance_list, " + "instance_list_player " + "WHERE " + "instance_list.zone = %u " + "AND instance_list.version = %u " + "AND instance_list.id = instance_list_player.id " + "AND instance_list_player.charid = %u " + "LIMIT 1 ", + GetZoneID(zone), + version, + character_id + ); + auto results = QueryDatabase(query); + + if (!results.Success()) + return 0; + + if (results.RowCount() == 0) + return 0; + + auto row = results.begin(); + return atoi(row[0]); +} + +uint16 Database::GetInstanceID(uint32 zone, uint32 character_id, int16 version) +{ + if (!zone) + return 0; + + std::string query = StringFormat( + "SELECT " + "instance_list.id " + "FROM " + "instance_list, " + "instance_list_player " + "WHERE " + "instance_list.zone = %u " + "AND instance_list.version = %u " + "AND instance_list.id = instance_list_player.id " + "AND instance_list_player.charid = %u " + "LIMIT 1; ", + zone, + version, + character_id + ); + auto results = QueryDatabase(query); + + if (!results.Success()) + return 0; + + if (results.RowCount() == 0) + return 0; + + auto row = results.begin(); + + return atoi(row[0]); +} + +uint16 Database::GetInstanceVersion(uint16 instance_id) { + if (instance_id == 0) + return 0; + + std::string query = StringFormat("SELECT version FROM instance_list where id=%u", instance_id); + auto results = QueryDatabase(query); + + if (!results.Success()) + return 0; + + if (results.RowCount() == 0) + return 0; + + auto row = results.begin(); + return atoi(row[0]); +} + +uint32 Database::GetTimeRemainingInstance(uint16 instance_id, bool &is_perma) +{ + uint32 start_time = 0; + uint32 duration = 0; + uint32 never_expires = 0; + + std::string query = StringFormat("SELECT start_time, duration, never_expires FROM instance_list WHERE id=%u", instance_id); + auto results = QueryDatabase(query); + + if (!results.Success()) + { + is_perma = false; + return 0; + } + + if (results.RowCount() == 0) + { + is_perma = false; + return 0; + } + + auto row = results.begin(); + + start_time = atoi(row[0]); + duration = atoi(row[1]); + never_expires = atoi(row[2]); + + if (never_expires == 1) + { + is_perma = true; + return 0; + } + + is_perma = false; + + timeval tv; + gettimeofday(&tv, nullptr); + return ((start_time + duration) - tv.tv_sec); +} + +uint32 Database::VersionFromInstanceID(uint16 instance_id) +{ + + std::string query = StringFormat("SELECT version FROM instance_list where id=%u", instance_id); + auto results = QueryDatabase(query); + + if (!results.Success()) + return 0; + + if (results.RowCount() == 0) + return 0; + + auto row = results.begin(); + + return atoi(row[0]); +} + +uint32 Database::ZoneIDFromInstanceID(uint16 instance_id) +{ + + std::string query = StringFormat("SELECT zone FROM instance_list where id=%u", instance_id); + auto results = QueryDatabase(query); + + if (!results.Success()) + return 0; + + if (results.RowCount() == 0) + return 0; + + auto row = results.begin(); + + return atoi(row[0]); +} + +void Database::AssignGroupToInstance(uint32 group_id, uint32 instance_id) +{ + + uint32 zone_id = ZoneIDFromInstanceID(instance_id); + uint16 version = VersionFromInstanceID(instance_id); + + std::string query = StringFormat("SELECT `charid` FROM `group_id` WHERE `groupid` = %u", group_id); + auto results = QueryDatabase(query); + + if (!results.Success()) + return; + + for (auto row = results.begin(); row != results.end(); ++row) + { + uint32 charid = atoi(row[0]); + if (GetInstanceID(zone_id, charid, version) == 0) + AddClientToInstance(instance_id, charid); + } +} + +void Database::AssignRaidToInstance(uint32 raid_id, uint32 instance_id) +{ + + uint32 zone_id = ZoneIDFromInstanceID(instance_id); + uint16 version = VersionFromInstanceID(instance_id); + + std::string query = StringFormat("SELECT `charid` FROM `raid_members` WHERE `raidid` = %u", raid_id); + auto results = QueryDatabase(query); + + if (!results.Success()) + return; + + for (auto row = results.begin(); row != results.end(); ++row) + { + uint32 charid = atoi(row[0]); + if (GetInstanceID(zone_id, charid, version) == 0) + AddClientToInstance(instance_id, charid); + } +} + +void Database::BuryCorpsesInInstance(uint16 instance_id) { + std::string query = StringFormat( + "UPDATE `character_corpses` " + "SET `is_buried` = 1, " + "`instance_id` = 0 " + "WHERE " + "`instance_id` = %u ", + instance_id + ); + auto results = QueryDatabase(query); +} + +void Database::DeleteInstance(uint16 instance_id) +{ + + std::string query = StringFormat("DELETE FROM instance_list WHERE id=%u", instance_id); + QueryDatabase(query); + + query = StringFormat("DELETE FROM instance_list_player WHERE id=%u", instance_id); + QueryDatabase(query); + + query = StringFormat("DELETE FROM respawn_times WHERE instance_id=%u", instance_id); + QueryDatabase(query); + + query = StringFormat("DELETE FROM spawn_condition_values WHERE instance_id=%u", instance_id); + QueryDatabase(query); + + BuryCorpsesInInstance(instance_id); +} + +void Database::FlagInstanceByGroupLeader(uint32 zone, int16 version, uint32 charid, uint32 gid) +{ + uint16 id = GetInstanceID(zone, charid, version); + if (id != 0) + return; + + char ln[128]; + memset(ln, 0, 128); + strcpy(ln, GetGroupLeadershipInfo(gid, ln)); + uint32 l_charid = GetCharacterID((const char*)ln); + uint16 l_id = GetInstanceID(zone, l_charid, version); + + if (l_id == 0) + return; + + AddClientToInstance(l_id, charid); +} + +void Database::FlagInstanceByRaidLeader(uint32 zone, int16 version, uint32 charid, uint32 rid) +{ + uint16 id = GetInstanceID(zone, charid, version); + if (id != 0) + return; + + uint32 l_charid = GetCharacterID(GetRaidLeaderName(rid)); + uint16 l_id = GetInstanceID(zone, l_charid, version); + + if (l_id == 0) + return; + + AddClientToInstance(l_id, charid); +} + +void Database::GetCharactersInInstance(uint16 instance_id, std::list &charid_list) { + + std::string query = StringFormat("SELECT `charid` FROM `instance_list_player` WHERE `id` = %u", instance_id); + auto results = QueryDatabase(query); + + if (!results.Success()) + return; + + for (auto row = results.begin(); row != results.end(); ++row) + charid_list.push_back(atoi(row[0])); +} + +void Database::PurgeExpiredInstances() +{ + std::string query("SELECT id FROM instance_list where (start_time+duration) <= UNIX_TIMESTAMP() and never_expires = 0"); + auto results = QueryDatabase(query); + + if (!results.Success()) + return; + + if (results.RowCount() == 0) + return; + + for (auto row = results.begin(); row != results.end(); ++row) + DeleteInstance(atoi(row[0])); +} + +void Database::SetInstanceDuration(uint16 instance_id, uint32 new_duration) +{ + std::string query = StringFormat("UPDATE `instance_list` SET start_time=UNIX_TIMESTAMP(), " + "duration=%u WHERE id=%u", new_duration, instance_id); + auto results = QueryDatabase(query); +} \ No newline at end of file diff --git a/common/dbcore.cpp b/common/dbcore.cpp index 7570fd01e..d256f7b42 100644 --- a/common/dbcore.cpp +++ b/common/dbcore.cpp @@ -3,6 +3,7 @@ #endif #include "../common/misc_functions.h" +#include "../common/eqemu_logsys.h" #include "dbcore.h" @@ -101,25 +102,16 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql)); - std::cout << "DB Query Error #" << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << std::endl; - return MySQLRequestResult(nullptr, 0, 0, 0, 0, (uint32)mysql_errno(&mysql), errorBuffer); } char *errorBuffer = new char[MYSQL_ERRMSG_SIZE]; snprintf(errorBuffer, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql)); -#ifdef _EQDEBUG - std::cout << "DB Query Error #" << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << std::endl; -#endif - /* Implement Logging at the Root */ if (mysql_errno(&mysql) > 0 && strlen(query) > 0){ - std::cout << "\n[MYSQL ERR] " << mysql_errno(&mysql) << ": " << mysql_error(&mysql) << " [Query]: \n" << query << "\n" << std::endl; - /* Write to log file */ - std::ofstream log("eqemu_query_error_log.txt", std::ios_base::app | std::ios_base::out); - log << "[MYSQL ERR] " << mysql_error(&mysql) << "\n" << query << "\n"; - log.close(); + if (Log.log_settings[Logs::MySQLError].is_category_enabled == 1) + Log.Out(Logs::General, Logs::MySQLError, "%i: %s \n %s", mysql_errno(&mysql), mysql_error(&mysql), query); } return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(&mysql),errorBuffer); @@ -134,21 +126,9 @@ MySQLRequestResult DBcore::QueryDatabase(const char* query, uint32 querylen, boo rowCount = (uint32)mysql_num_rows(res); MySQLRequestResult requestResult(res, (uint32)mysql_affected_rows(&mysql), rowCount, (uint32)mysql_field_count(&mysql), (uint32)mysql_insert_id(&mysql)); - -#if DEBUG_MYSQL_QUERIES >= 1 - if (requestResult.Success()) - { - std::cout << "query successful"; - if (requestResult.Result()) - std::cout << ", " << (int) mysql_num_rows(requestResult.Result()) << " rows returned"; - - std::cout << ", " << requestResult.RowCount() << " rows affected"; - std::cout<< std::endl; - } - else { - std::cout << "QUERY: query FAILED" << std::endl; - } -#endif + + if (Log.log_settings[Logs::MySQLQuery].is_category_enabled == 1) + Log.Out(Logs::General, Logs::MySQLQuery, "%s (%u rows returned)", query, rowCount, requestResult.RowCount()); return requestResult; } diff --git a/common/dbmemshare.cpp b/common/dbmemshare.cpp deleted file mode 100644 index 8447f6d0d..000000000 --- a/common/dbmemshare.cpp +++ /dev/null @@ -1,126 +0,0 @@ -// Doors -#ifdef SHAREMEM -int32 Database::GetDoorsCount(uint32* oMaxID) { - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - query = new char[256]; - strcpy(query, "SELECT MAX(id), count(*) FROM doors"); - if (RunQuery(query, strlen(query), errbuf, &result)) { - safe_delete(query); - row = mysql_fetch_row(result); - if (row && row[1]) { - int32 ret = atoi(row[1]); - if (oMaxID) { - if (row[0]) - *oMaxID = atoi(row[0]); - else - *oMaxID = 0; - } - mysql_free_result(result); - return ret; - } - } - else { - cerr << "Error in GetDoorsCount query '" << query << "' " << errbuf << endl; - delete[] query; - return -1; - } - - return -1; -} - -extern "C" bool extDBLoadDoors(uint32 iDoorCount, uint32 iMaxDoorID) { return database.DBLoadDoors(iDoorCount, iMaxDoorID); } -const Door* Database::GetDoor(uint8 door_id, const char* zone_name) { - for(uint32 i=0; idoor_id == door_id && strcasecmp(door->zone_name, zone_name) == 0) - return door; - } - return 0; -} - -const Door* Database::GetDoorDBID(uint32 db_id) { - return EMuShareMemDLL.Doors.GetDoor(db_id); -} - -bool Database::LoadDoors() { - if (!EMuShareMemDLL.Load()) - return false; - int32 tmp_max_door_type = -1; - uint32 tmp = 0; - tmp_max_door_type = GetDoorsCount(&tmp); - if (tmp_max_door_type < 0) { - cout << "Error: Database::LoadDoors-ShareMem: GetDoorsCount() returned < 0" << endl; - return false; - } - max_door_type = tmp_max_door_type; - bool ret = EMuShareMemDLL.Doors.DLLLoadDoors(&extDBLoadDoors, sizeof(Door), max_door_type, tmp); - return ret; -} - -bool Database::DBLoadDoors(uint32 iDoorCount, uint32 iMaxDoorID) { - cout << "Loading Doors from database..." << endl; - char errbuf[MYSQL_ERRMSG_SIZE]; - char *query = 0; - MYSQL_RES *result; - MYSQL_ROW row; - query = new char[256]; - strcpy(query, "SELECT MAX(id), Count(*) FROM doors"); - if (RunQuery(query, strlen(query), errbuf, &result)) - { - safe_delete(query); - row = mysql_fetch_row(result); - if (row && row[0]) { - if (atoi(row[0]) > iMaxDoorID) { - cout << "Error: Insufficient shared memory to load doors." << endl; - cout << "Max(id): " << atoi(row[0]) << ", iMaxDoorID: " << iMaxDoorID << endl; - cout << "Fix this by increasing the MMF_MAX_Door_ID define statement" << endl; - return false; - } - if (atoi(row[1]) != iDoorCount) { - cout << "Error: Insufficient shared memory to load doors." << endl; - cout << "Count(*): " << atoi(row[1]) << ", iDoorCount: " << iDoorCount << endl; - return false; - } - max_door_type = atoi(row[0]); - mysql_free_result(result); - Door tmpDoor; - MakeAnyLenString(&query, "SELECT id,doorid,zone,name,pos_x,pos_y,pos_z,heading,opentype,guild,lockpick,keyitem,triggerdoor,triggertype from doors");//WHERE zone='%s'", zone_name - if (RunQuery(query, strlen(query), errbuf, &result)) - { - safe_delete(query); - while((row = mysql_fetch_row(result))) { - memset(&tmpDoor, 0, sizeof(Door)); - tmpDoor.db_id = atoi(row[0]); - tmpDoor.door_id = atoi(row[1]); - strn0cpy(tmpDoor.zone_name,row[2],32); - strn0cpy(tmpDoor.door_name,row[3],32); - tmpDoor.pos_x = (float)atof(row[4]); - tmpDoor.pos_y = (float)atof(row[5]); - tmpDoor.pos_z = (float)atof(row[6]); - tmpDoor.heading = atoi(row[7]); - tmpDoor.opentype = atoi(row[8]); - tmpDoor.guild_id = atoi(row[9]); - tmpDoor.lockpick = atoi(row[10]); - tmpDoor.keyitem = atoi(row[11]); - tmpDoor.trigger_door = atoi(row[12]); - tmpDoor.trigger_type = atoi(row[13]); - EMuShareMemDLL.Doors.cbAddDoor(tmpDoor.db_id, &tmpDoor); - Sleep(0); - } - mysql_free_result(result); - } - else - { - cerr << "Error in DBLoadDoors query '" << query << "' " << errbuf << endl; - delete[] query; - return false; - } - } - } - return true; -} -#endif - diff --git a/common/debug.cpp b/common/debug.cpp deleted file mode 100644 index 3b283240a..000000000 --- a/common/debug.cpp +++ /dev/null @@ -1,454 +0,0 @@ -#include -#include - -#ifdef _WINDOWS - #include - - #define snprintf _snprintf - #define vsnprintf _vsnprintf - #define strncasecmp _strnicmp - #define strcasecmp _stricmp - -#else - - #include - #include - -#endif - -#include "debug.h" -#include "misc_functions.h" -#include "platform.h" - -#ifndef va_copy - #define va_copy(d,s) ((d) = (s)) -#endif - -static volatile bool logFileValid = false; -static EQEMuLog realLogFile; -EQEMuLog *LogFile = &realLogFile; - -static const char* FileNames[EQEMuLog::MaxLogID] = { "logs/eqemu", "logs/eqemu", "logs/eqemu_error", "logs/eqemu_debug", "logs/eqemu_quest", "logs/eqemu_commands", "logs/crash" }; -static const char* LogNames[EQEMuLog::MaxLogID] = { "Status", "Normal", "Error", "Debug", "Quest", "Command", "Crash" }; - -EQEMuLog::EQEMuLog() -{ - for (int i = 0; i < MaxLogID; i++) { - fp[i] = 0; - logCallbackFmt[i] = nullptr; - logCallbackBuf[i] = nullptr; - logCallbackPva[i] = nullptr; - } - pLogStatus[EQEMuLog::LogIDs::Status] = LOG_LEVEL_STATUS; - pLogStatus[EQEMuLog::LogIDs::Normal] = LOG_LEVEL_NORMAL; - pLogStatus[EQEMuLog::LogIDs::Error] = LOG_LEVEL_ERROR; - pLogStatus[EQEMuLog::LogIDs::Debug] = LOG_LEVEL_DEBUG; - pLogStatus[EQEMuLog::LogIDs::Quest] = LOG_LEVEL_QUEST; - pLogStatus[EQEMuLog::LogIDs::Commands] = LOG_LEVEL_COMMANDS; - pLogStatus[EQEMuLog::LogIDs::Crash] = LOG_LEVEL_CRASH; - logFileValid = true; -} - -EQEMuLog::~EQEMuLog() -{ - logFileValid = false; - for (int i = 0; i < MaxLogID; i++) { - LockMutex lock(&MLog[i]); //to prevent termination race - if (fp[i]) { - fclose(fp[i]); - } - } -} - -bool EQEMuLog::open(LogIDs id) -{ - if (!logFileValid) { - return false; - } - if (id >= MaxLogID) { - return false; - } - LockMutex lock(&MOpen); - if (pLogStatus[id] & 4) { - return false; - } - if (fp[id]) { - //cerr<<"Warning: LogFile already open"<= MaxLogID) { - return false; - } - bool dofile = false; - if (pLogStatus[id] & 1) { - dofile = open(id); - } - if (!(dofile || pLogStatus[id] & 2)) { - return false; - } - LockMutex lock(&MLog[id]); - if (!logFileValid) { - return false; //check again for threading race reasons (to avoid two mutexes) - } - time_t aclock; - struct tm *newtime; - time( &aclock ); /* Get time in seconds */ - newtime = localtime( &aclock ); /* Convert time to struct */ - if (dofile) - #ifndef NO_PIDLOG - fprintf(fp[id], "[%02d.%02d. - %02d:%02d:%02d] ", newtime->tm_mon + 1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec); - #else - fprintf(fp[id], "%04i [%02d.%02d. - %02d:%02d:%02d] ", getpid(), newtime->tm_mon + 1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec); - #endif - va_list argptr, tmpargptr; - va_start(argptr, fmt); - if (dofile) { - va_copy(tmpargptr, argptr); - vfprintf( fp[id], fmt, tmpargptr ); - } - if (logCallbackFmt[id]) { - msgCallbackFmt p = logCallbackFmt[id]; - va_copy(tmpargptr, argptr); - p(id, fmt, tmpargptr ); - } - if (pLogStatus[id] & 2) { - if (pLogStatus[id] & 8) { - fprintf(stderr, "[%s] ", LogNames[id]); - vfprintf( stderr, fmt, argptr ); - } else { - fprintf(stdout, "[%s] ", LogNames[id]); - vfprintf( stdout, fmt, argptr ); - } - } - va_end(argptr); - if (dofile) { - fprintf(fp[id], "\n"); - } - if (pLogStatus[id] & 2) { - if (pLogStatus[id] & 8) { - fprintf(stderr, "\n"); - fflush(stderr); - } else { - fprintf(stdout, "\n"); - fflush(stdout); - } - } - if (dofile) { - fflush(fp[id]); - } - return true; -} - -//write with Prefix and a VA_list -bool EQEMuLog::writePVA(LogIDs id, const char *prefix, const char *fmt, va_list argptr) -{ - if (!logFileValid) { - return false; - } - if (id >= MaxLogID) { - return false; - } - bool dofile = false; - if (pLogStatus[id] & 1) { - dofile = open(id); - } - if (!(dofile || pLogStatus[id] & 2)) { - return false; - } - LockMutex lock(&MLog[id]); - if (!logFileValid) { - return false; //check again for threading race reasons (to avoid two mutexes) - } - time_t aclock; - struct tm *newtime; - time( &aclock ); /* Get time in seconds */ - newtime = localtime( &aclock ); /* Convert time to struct */ - va_list tmpargptr; - if (dofile) { - #ifndef NO_PIDLOG - fprintf(fp[id], "[%02d.%02d. - %02d:%02d:%02d] %s", newtime->tm_mon + 1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec, prefix); - #else - fprintf(fp[id], "%04i [%02d.%02d. - %02d:%02d:%02d] %s", getpid(), newtime->tm_mon + 1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec, prefix); - #endif - va_copy(tmpargptr, argptr); - vfprintf( fp[id], fmt, tmpargptr ); - } - if (logCallbackPva[id]) { - msgCallbackPva p = logCallbackPva[id]; - va_copy(tmpargptr, argptr); - p(id, prefix, fmt, tmpargptr ); - } - if (pLogStatus[id] & 2) { - if (pLogStatus[id] & 8) { - fprintf(stderr, "[%s] %s", LogNames[id], prefix); - vfprintf( stderr, fmt, argptr ); - } else { - fprintf(stdout, "[%s] %s", LogNames[id], prefix); - vfprintf( stdout, fmt, argptr ); - } - } - va_end(argptr); - if (dofile) { - fprintf(fp[id], "\n"); - } - if (pLogStatus[id] & 2) { - if (pLogStatus[id] & 8) { - fprintf(stderr, "\n"); - } else { - fprintf(stdout, "\n"); - } - } - if (dofile) { - fflush(fp[id]); - } - return true; -} - -bool EQEMuLog::writebuf(LogIDs id, const char *buf, uint8 size, uint32 count) -{ - if (!logFileValid) { - return false; - } - if (id >= MaxLogID) { - return false; - } - bool dofile = false; - if (pLogStatus[id] & 1) { - dofile = open(id); - } - if (!(dofile || pLogStatus[id] & 2)) { - return false; - } - LockMutex lock(&MLog[id]); - if (!logFileValid) { - return false; //check again for threading race reasons (to avoid two mutexes) - } - time_t aclock; - struct tm *newtime; - time( &aclock ); /* Get time in seconds */ - newtime = localtime( &aclock ); /* Convert time to struct */ - if (dofile) - #ifndef NO_PIDLOG - fprintf(fp[id], "[%02d.%02d. - %02d:%02d:%02d] ", newtime->tm_mon + 1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec); - #else - fprintf(fp[id], "%04i [%02d.%02d. - %02d:%02d:%02d] ", getpid(), newtime->tm_mon + 1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec); - #endif - if (dofile) { - fwrite(buf, size, count, fp[id]); - fprintf(fp[id], "\n"); - } - if (logCallbackBuf[id]) { - msgCallbackBuf p = logCallbackBuf[id]; - p(id, buf, size, count); - } - if (pLogStatus[id] & 2) { - if (pLogStatus[id] & 8) { - fprintf(stderr, "[%s] ", LogNames[id]); - fwrite(buf, size, count, stderr); - fprintf(stderr, "\n"); - } else { - fprintf(stdout, "[%s] ", LogNames[id]); - fwrite(buf, size, count, stdout); - fprintf(stdout, "\n"); - } - } - if (dofile) { - fflush(fp[id]); - } - return true; -} - -bool EQEMuLog::writeNTS(LogIDs id, bool dofile, const char *fmt, ...) -{ - va_list argptr, tmpargptr; - va_start(argptr, fmt); - if (dofile) { - va_copy(tmpargptr, argptr); - vfprintf( fp[id], fmt, tmpargptr ); - } - if (pLogStatus[id] & 2) { - if (pLogStatus[id] & 8) { - vfprintf( stderr, fmt, argptr ); - } else { - vfprintf( stdout, fmt, argptr ); - } - } - va_end(argptr); - return true; -}; - -bool EQEMuLog::Dump(LogIDs id, uint8* data, uint32 size, uint32 cols, uint32 skip) -{ - if (!logFileValid) { - #if EQDEBUG >= 10 - std::cerr << "Error: Dump() from null pointer" << std::endl; - #endif - return false; - } - if (size == 0) { - return true; - } - if (!LogFile) { - return false; - } - if (id >= MaxLogID) { - return false; - } - bool dofile = false; - if (pLogStatus[id] & 1) { - dofile = open(id); - } - if (!(dofile || pLogStatus[id] & 2)) { - return false; - } - LockMutex lock(&MLog[id]); - if (!logFileValid) { - return false; //check again for threading race reasons (to avoid two mutexes) - } - write(id, "Dumping Packet: %i", size); - // Output as HEX - int beginningOfLineOffset = 0; - uint32 indexInData; - std::string asciiOutput; - for (indexInData = skip; indexInData < size; indexInData++) { - if ((indexInData - skip) % cols == 0) { - if (indexInData != skip) { - writeNTS(id, dofile, " | %s\n", asciiOutput.c_str()); - } - writeNTS(id, dofile, "%4i: ", indexInData - skip); - asciiOutput.clear(); - beginningOfLineOffset = 0; - } else if ((indexInData - skip) % (cols / 2) == 0) { - writeNTS(id, dofile, "- "); - } - writeNTS(id, dofile, "%02X ", (unsigned char)data[indexInData]); - if (data[indexInData] >= 32 && data[indexInData] < 127) { - // According to http://msdn.microsoft.com/en-us/library/vstudio/ee404875(v=vs.100).aspx - // Visual Studio 2010 doesn't have std::to_string(int) but it does have the long long - // version. - asciiOutput.append(std::to_string((long long)data[indexInData])); - } else { - asciiOutput.append("."); - } - } - uint32 k = ((indexInData - skip) - 1) % cols; - if (k < 8) { - writeNTS(id, dofile, " "); - } - for (uint32 h = k + 1; h < cols; h++) { - writeNTS(id, dofile, " "); - } - writeNTS(id, dofile, " | %s\n", asciiOutput.c_str()); - if (dofile) { - fflush(fp[id]); - } - return true; -} - -void EQEMuLog::SetCallback(LogIDs id, msgCallbackFmt proc) -{ - if (!logFileValid) { - return; - } - if (id >= MaxLogID) { - return; - } - logCallbackFmt[id] = proc; -} - -void EQEMuLog::SetCallback(LogIDs id, msgCallbackBuf proc) -{ - if (!logFileValid) { - return; - } - if (id >= MaxLogID) { - return; - } - logCallbackBuf[id] = proc; -} - -void EQEMuLog::SetCallback(LogIDs id, msgCallbackPva proc) -{ - if (!logFileValid) { - return; - } - if (id >= MaxLogID) { - return; - } - logCallbackPva[id] = proc; -} - -void EQEMuLog::SetAllCallbacks(msgCallbackFmt proc) -{ - if (!logFileValid) { - return; - } - int r; - for (r = Status; r < MaxLogID; r++) { - SetCallback((LogIDs)r, proc); - } -} - -void EQEMuLog::SetAllCallbacks(msgCallbackBuf proc) -{ - if (!logFileValid) { - return; - } - int r; - for (r = Status; r < MaxLogID; r++) { - SetCallback((LogIDs)r, proc); - } -} - -void EQEMuLog::SetAllCallbacks(msgCallbackPva proc) -{ - if (!logFileValid) { - return; - } - int r; - for (r = Status; r < MaxLogID; r++) { - SetCallback((LogIDs)r, proc); - } -} - diff --git a/common/debug.h b/common/debug.h deleted file mode 100644 index 5e2fff368..000000000 --- a/common/debug.h +++ /dev/null @@ -1,149 +0,0 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -// Debug Levels -#ifndef EQDEBUG -#define EQDEBUG 1 -#else -////// File/Console options -// 0 <= Quiet mode Errors to file Status and Normal ignored -// 1 >= Status and Normal to console, Errors to file -// 2 >= Status, Normal, and Error to console and logfile -// 3 >= Lite debug -// 4 >= Medium debug -// 5 >= Debug release (Anything higher is not recommended for regular use) -// 6 == (Reserved for special builds) Login opcode debug All packets dumped -// 7 == (Reserved for special builds) Chat Opcode debug All packets dumped -// 8 == (Reserved for special builds) World opcode debug All packets dumped -// 9 == (Reserved for special builds) Zone Opcode debug All packets dumped -// 10 >= More than you ever wanted to know -// -///// -// Add more below to reserve for file's functions ect. -///// -// Any setup code based on defines should go here -// -#endif - - -#if defined(_DEBUG) && defined(WIN32) - #ifndef _CRTDBG_MAP_ALLOC - #include - #include - #endif -#endif - -#ifndef EQDEBUG_H -#define EQDEBUG_H - -#ifndef _WINDOWS - #define DebugBreak() if(0) {} -#endif - -#define _WINSOCKAPI_ //stupid windows, trying to fix the winsock2 vs. winsock issues -#if defined(WIN32) && ( defined(PACKETCOLLECTOR) || defined(COLLECTOR) ) - // Packet Collector on win32 requires winsock.h due to latest pcap.h - // winsock.h must come before windows.h - #include -#endif - -#ifdef _WINDOWS - #include - #include -#endif - -#include "logsys.h" - -#include "../common/mutex.h" -#include -#include - - -class EQEMuLog { -public: - EQEMuLog(); - ~EQEMuLog(); - - enum LogIDs { - Status = 0, /* This must stay the first entry in this list */ - Normal, /* Normal Logs */ - Error, /* Error Logs */ - Debug, /* Debug Logs */ - Quest, /* Quest Logs */ - Commands, /* Issued Comamnds */ - Crash, /* Crash Logs */ - Save, /* Client Saves */ - MaxLogID /* Max, used in functions to get the max log ID */ - }; - - //these are callbacks called for each - typedef void (* msgCallbackBuf)(LogIDs id, const char *buf, uint8 size, uint32 count); - typedef void (* msgCallbackFmt)(LogIDs id, const char *fmt, va_list ap); - typedef void (* msgCallbackPva)(LogIDs id, const char *prefix, const char *fmt, va_list ap); - - void SetAllCallbacks(msgCallbackFmt proc); - void SetAllCallbacks(msgCallbackBuf proc); - void SetAllCallbacks(msgCallbackPva proc); - void SetCallback(LogIDs id, msgCallbackFmt proc); - void SetCallback(LogIDs id, msgCallbackBuf proc); - void SetCallback(LogIDs id, msgCallbackPva proc); - - bool writebuf(LogIDs id, const char *buf, uint8 size, uint32 count); - bool write(LogIDs id, const char *fmt, ...); - bool writePVA(LogIDs id, const char *prefix, const char *fmt, va_list args); - bool Dump(LogIDs id, uint8* data, uint32 size, uint32 cols=16, uint32 skip=0); -private: - bool open(LogIDs id); - bool writeNTS(LogIDs id, bool dofile, const char *fmt, ...); // no error checking, assumes is open, no locking, no timestamp, no newline - - Mutex MOpen; - Mutex MLog[MaxLogID]; - FILE* fp[MaxLogID]; - -/* LogStatus: bitwise variable - 1 = output to file - 2 = output to stdout - 4 = fopen error, dont retry - 8 = use stderr instead (2 must be set) -*/ - uint8 pLogStatus[MaxLogID]; - - msgCallbackFmt logCallbackFmt[MaxLogID]; - msgCallbackBuf logCallbackBuf[MaxLogID]; - msgCallbackPva logCallbackPva[MaxLogID]; -}; - -extern EQEMuLog* LogFile; - -#ifdef _EQDEBUG -class PerformanceMonitor { -public: - PerformanceMonitor(int64* ip) { - p = ip; - QueryPerformanceCounter(&tmp); - } - ~PerformanceMonitor() { - LARGE_INTEGER tmp2; - QueryPerformanceCounter(&tmp2); - *p += tmp2.QuadPart - tmp.QuadPart; - } - LARGE_INTEGER tmp; - int64* p; -}; -#endif -#endif diff --git a/common/emu_opcodes.cpp b/common/emu_opcodes.cpp index 49da5e140..00f45fa25 100644 --- a/common/emu_opcodes.cpp +++ b/common/emu_opcodes.cpp @@ -16,7 +16,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 04111-1307 USA */ -#include "debug.h" +#include "global_define.h" #include "emu_opcodes.h" const char *OpcodeNames[_maxEmuOpcode+1] = { diff --git a/common/emu_tcp_connection.cpp b/common/emu_tcp_connection.cpp index bf01c1c2a..a94081364 100644 --- a/common/emu_tcp_connection.cpp +++ b/common/emu_tcp_connection.cpp @@ -23,7 +23,7 @@ crap into its own subclass of this object, it will clean things up tremendously. */ -#include "../common/debug.h" +#include "../common/global_define.h" #include #include @@ -104,7 +104,7 @@ EmuTCPConnection::EmuTCPConnection(uint32 ID, EmuTCPServer* iServer, EmuTCPConne RelayCount = 0; RemoteID = iRemoteID; pOldFormat = false; - ConnectionType = Incomming; + ConnectionType = Incoming; TCPMode = modePacket; PacketMode = packetModeZone; #if TCPN_DEBUG_Memory >= 7 @@ -737,7 +737,7 @@ void EmuTCPConnection::ProcessNetworkLayerPacket(ServerPacket* pack) { SendNetErrorPacket("Switch to RelayServer mode by a Relay Client"); break; } - if (ConnectionType != Incomming) { + if (ConnectionType != Incoming) { SendNetErrorPacket("Switch to RelayServer mode on outgoing connection"); break; } @@ -758,7 +758,7 @@ void EmuTCPConnection::ProcessNetworkLayerPacket(ServerPacket* pack) { SendNetErrorPacket("New RelayClient: wrong size, expected 11"); break; } - if (ConnectionType != Incomming) { + if (ConnectionType != Incoming) { SendNetErrorPacket("New RelayClient: illegal on outgoing connection"); break; } @@ -778,7 +778,7 @@ void EmuTCPConnection::ProcessNetworkLayerPacket(ServerPacket* pack) { } EmuTCPConnection* con = Server->FindConnection(*((uint32*)data)); if (con) { - if (ConnectionType == Incomming) { + if (ConnectionType == Incoming) { if (con->GetRelayLink() != this) { SendNetErrorPacket("Delete RelayClient: RelayLink != this"); break; diff --git a/common/emu_tcp_server.cpp b/common/emu_tcp_server.cpp index 985be6edd..4509c399f 100644 --- a/common/emu_tcp_server.cpp +++ b/common/emu_tcp_server.cpp @@ -1,4 +1,4 @@ -#include "debug.h" +#include "global_define.h" #include "emu_tcp_server.h" #include "emu_tcp_connection.h" diff --git a/common/eq_constants.h b/common/eq_constants.h index 426d4a9e5..14f695069 100644 --- a/common/eq_constants.h +++ b/common/eq_constants.h @@ -19,6 +19,7 @@ #define EQ_CONSTANTS_H #include "skills.h" +#include "types.h" /* ** Item attributes @@ -367,7 +368,7 @@ enum { #define AT_DamageState 44 // The damage state of a destructible object (0 through 4) //#define AT_Trader 300 // Bazzar Trader Mode -// solar: animations for AT_Anim +// animations for AT_Anim #define ANIM_FREEZE 102 #define ANIM_STAND 0x64 #define ANIM_SIT 0x6e diff --git a/common/eq_dictionary.cpp b/common/eq_dictionary.cpp index 46c8f4ff1..ed3253260 100644 --- a/common/eq_dictionary.cpp +++ b/common/eq_dictionary.cpp @@ -25,8 +25,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // class EmuConstants // -uint16 EmuConstants::InventoryMapSize(int16 map) { - switch (map) { +uint16 EmuConstants::InventoryMapSize(int16 indexMap) { + switch (indexMap) { case MapPossessions: return MAP_POSSESSIONS_SIZE; case MapBank: @@ -91,8 +91,8 @@ std::string EmuConstants::InventoryLocationName(Location_Struct location) { } */ -std::string EmuConstants::InventoryMapName(int16 map) { - switch (map) { +std::string EmuConstants::InventoryMapName(int16 indexMap) { + switch (indexMap) { case INVALID_INDEX: return "Invalid Map"; case MapPossessions: @@ -150,8 +150,8 @@ std::string EmuConstants::InventoryMapName(int16 map) { } } -std::string EmuConstants::InventoryMainName(int16 main) { - switch (main) { +std::string EmuConstants::InventoryMainName(int16 indexMain) { + switch (indexMain) { case INVALID_INDEX: return "Invalid Main"; case MainCharm: @@ -229,293 +229,83 @@ std::string EmuConstants::InventoryMainName(int16 main) { } } -std::string EmuConstants::InventorySubName(int16 sub) { - if (sub == INVALID_INDEX) +std::string EmuConstants::InventorySubName(int16 indexSub) { + if (indexSub == INVALID_INDEX) return "Invalid Sub"; - if ((uint16)sub >= ITEM_CONTAINER_SIZE) + if ((uint16)indexSub >= ITEM_CONTAINER_SIZE) return "Unknown Sub"; std::string ret_str; - ret_str = StringFormat("Container %i", (sub + 1)); // zero-based index..but, count starts at one + ret_str = StringFormat("Container %i", (indexSub + 1)); // zero-based index..but, count starts at one return ret_str; } -std::string EmuConstants::InventoryAugName(int16 aug) { - if (aug == INVALID_INDEX) +std::string EmuConstants::InventoryAugName(int16 indexAug) { + if (indexAug == INVALID_INDEX) return "Invalid Aug"; - if ((uint16)aug >= ITEM_COMMON_SIZE) + if ((uint16)indexAug >= ITEM_COMMON_SIZE) return "Unknown Aug"; std::string ret_str; - ret_str = StringFormat("Augment %i", (aug + 1)); // zero-based index..but, count starts at one + ret_str = StringFormat("Augment %i", (indexAug + 1)); // zero-based index..but, count starts at one return ret_str; } -// legacy-related functions -// -// these should work for the first-stage coversions..but, once the new system is up and going..conversions will be incompatible -// without limiting server functions and other aspects, such as augment control, bag size, etc. A complete remapping will be -// required when bag sizes over 10 and direct manipulation of augments are implemented, due to the massive increase in range usage. -// -// (current personal/cursor bag range {251..340}, or 90 slots ... conversion translated range would be {10000..12804}, or 2805 slots... -// these would have to be hard-coded into all perl code to allow access to full range of the new system - actual limits would be -// less, based on bag size..but, the range must be full and consistent to avoid translation issues -- similar changes to other ranges -// (240 versus 6120 slots for bank bags, for example...)) -/* -int EmuConstants::ServerToPerlSlot(int server_slot) { // set r/s - switch (server_slot) { - case legacy::SLOT_CURSOR_END: - return legacy::SLOT_CURSOR_END; - case INVALID_INDEX: - return legacy::SLOT_INVALID; - case MainPowerSource: - return legacy::SLOT_POWER_SOURCE; - case MainAmmo: - return legacy::SLOT_AMMO; - case MainCursor: - return legacy::SLOT_CURSOR; - case legacy::SLOT_TRADESKILL: - return legacy::SLOT_TRADESKILL; - case legacy::SLOT_AUGMENT: - return legacy::SLOT_AUGMENT; - default: - int perl_slot = legacy::SLOT_INVALID; - - // activate the internal checks as needed - if (server_slot >= EmuConstants::EQUIPMENT_BEGIN && server_slot <= MainWaist) { - perl_slot = server_slot; - } - else if (server_slot >= EmuConstants::GENERAL_BEGIN && server_slot <= EmuConstants::GENERAL_END) { - perl_slot = server_slot;// + legacy::SLOT_PERSONAL_BEGIN - EmuConstants::GENERAL_BEGIN; - //if (perl_slot < legacy::SLOT_PERSONAL_BEGIN || perl_slot > legacy::SLOT_PERSONAL_END) - // perl_slot = legacy::SLOT_INVALID; - } - else if (server_slot >= EmuConstants::GENERAL_BAGS_BEGIN && server_slot <= EmuConstants::GENERAL_BAGS_END) { - perl_slot = server_slot;// + legacy::SLOT_PERSONAL_BAGS_BEGIN - EmuConstants::GENERAL_BAGS_BEGIN; - //if (perl_slot < legacy::SLOT_PERSONAL_BAGS_BEGIN || perl_slot > legacy::SLOT_PERSONAL_BAGS_END) - // perl_slot = legacy::SLOT_INVALID; - } - else if (server_slot >= EmuConstants::CURSOR_BAG_BEGIN && server_slot <= EmuConstants::CURSOR_BAG_END) { - perl_slot = server_slot;// + legacy::SLOT_CURSOR_BAG_BEGIN - EmuConstants::CURSOR_BAG_BEGIN; - //if (perl_slot < legacy::SLOT_CURSOR_BAG_BEGIN || perl_slot > legacy::SLOT_CURSOR_BAG_END) - // perl_slot = legacy::SLOT_INVALID; - } - else if (server_slot >= EmuConstants::TRIBUTE_BEGIN && server_slot <= EmuConstants::TRIBUTE_END) { - perl_slot = server_slot;// + legacy::SLOT_TRIBUTE_BEGIN - EmuConstants::TRADE_BEGIN; - //if (perl_slot < legacy::SLOT_TRIBUTE_BEGIN || perl_slot > legacy::SLOT_TRIBUTE_END) - // perl_slot = legacy::SLOT_INVALID; - } - else if (server_slot >= EmuConstants::BANK_BEGIN && server_slot <= EmuConstants::BANK_END) { - perl_slot = server_slot;// + legacy::SLOT_BANK_BEGIN - EmuConstants::BANK_BEGIN; - //if (perl_slot < legacy::SLOT_BANK_BEGIN || perl_slot > legacy::SLOT_BANK_END) - // perl_slot = legacy::SLOT_INVALID; - } - else if (server_slot >= EmuConstants::BANK_BAGS_BEGIN && server_slot <= EmuConstants::BANK_BAGS_END) { - perl_slot = server_slot;// + legacy::SLOT_BANK_BAGS_BEGIN - EmuConstants::BANK_BAGS_BEGIN; - //if (perl_slot < legacy::SLOT_BANK_BAGS_BEGIN || perl_slot > legacy::SLOT_BANK_BAGS_END) - // perl_slot = legacy::SLOT_INVALID; - } - else if (server_slot >= EmuConstants::SHARED_BANK_BEGIN && server_slot <= EmuConstants::SHARED_BANK_END) { - perl_slot = server_slot;// + legacy::SLOT_SHARED_BANK_BEGIN - EmuConstants::SHARED_BANK_BEGIN; - //if (perl_slot < legacy::SLOT_SHARED_BANK_BEGIN || perl_slot > legacy::SLOT_SHARED_BANK_END) - // perl_slot = legacy::SLOT_INVALID; - } - else if (server_slot >= EmuConstants::SHARED_BANK_BAGS_BEGIN && server_slot <= EmuConstants::SHARED_BANK_BAGS_END) { - perl_slot = server_slot;// + legacy::SLOT_SHARED_BANK_BAGS_BEGIN - EmuConstants::SHARED_BANK_BAGS_BEGIN; - //if (perl_slot < legacy::SLOT_SHARED_BANK_BAGS_BEGIN || perl_slot > legacy::SLOT_SHARED_BANK_BAGS_END) - // perl_slot = legacy::SLOT_INVALID; - } - else if (server_slot >= EmuConstants::TRADE_BEGIN && server_slot <= EmuConstants::TRADE_END) { - perl_slot = server_slot;// + legacy::SLOT_TRADE_BEGIN - EmuConstants::TRADE_BEGIN; - //if (perl_slot < legacy::SLOT_TRADE_BEGIN || perl_slot > legacy::SLOT_TRADE_END) - // perl_slot = legacy::SLOT_INVALID; - } - else if (server_slot >= EmuConstants::TRADE_BAGS_BEGIN && server_slot <= EmuConstants::TRADE_BAGS_END) { - perl_slot = server_slot;// + legacy::SLOT_TRADE_BAGS_BEGIN - EmuConstants::TRADE_BAGS_BEGIN; - //if (perl_slot < legacy::SLOT_TRADE_BAGS_BEGIN || perl_slot > legacy::SLOT_TRADE_BAGS_END) - // perl_slot = legacy::SLOT_INVALID; - } - else if (server_slot >= EmuConstants::WORLD_BEGIN && server_slot <= EmuConstants::WORLD_END) { - perl_slot = server_slot;// + legacy::SLOT_WORLD_BEGIN - EmuConstants::WORLD_BEGIN; - //if (perl_slot < legacy::SLOT_WORLD_BEGIN || perl_slot > legacy::SLOT_WORLD_END) - // perl_slot = legacy::SLOT_INVALID; - } - else if (server_slot >= 8000 && server_slot <= 8999) { // this range may be limited to 36 in the future (client size) - perl_slot = server_slot; - } - - return perl_slot; - } -} -*/ -/* -int EmuConstants::PerlToServerSlot(int perl_slot) { // set r/s - switch (perl_slot) { - case legacy::SLOT_CURSOR_END: - return legacy::SLOT_CURSOR_END; - case legacy::SLOT_INVALID: - return INVALID_INDEX; - case legacy::SLOT_POWER_SOURCE: - return MainPowerSource; - case legacy::SLOT_AMMO: - return MainAmmo; - case legacy::SLOT_CURSOR: - return MainCursor; - case legacy::SLOT_TRADESKILL: - return legacy::SLOT_TRADESKILL; - case legacy::SLOT_AUGMENT: - return legacy::SLOT_AUGMENT; - default: - int server_slot = INVALID_INDEX; - - // activate the internal checks as needed - if (perl_slot >= legacy::SLOT_EQUIPMENT_BEGIN && perl_slot <= legacy::SLOT_WAIST) { - server_slot = perl_slot; - } - else if (perl_slot >= legacy::SLOT_PERSONAL_BEGIN && perl_slot <= legacy::SLOT_PERSONAL_END) { - server_slot = perl_slot;// + EmuConstants::GENERAL_BEGIN - legacy::SLOT_PERSONAL_BEGIN; - //if (server_slot < EmuConstants::GENERAL_BEGIN || server_slot > EmuConstants::GENERAL_END) - // server_slot = INVALID_INDEX; - } - else if (perl_slot >= legacy::SLOT_PERSONAL_BAGS_BEGIN && perl_slot <= legacy::SLOT_PERSONAL_BAGS_END) { - server_slot = perl_slot;// + EmuConstants::GENERAL_BAGS_BEGIN - legacy::SLOT_PERSONAL_BAGS_BEGIN; - //if (server_slot < EmuConstants::GENERAL_BAGS_BEGIN || server_slot > EmuConstants::GENERAL_BAGS_END) - // server_slot = INVALID_INDEX; - } - else if (perl_slot >= legacy::SLOT_CURSOR_BAG_BEGIN && perl_slot <= legacy::SLOT_CURSOR_BAG_END) { - server_slot = perl_slot;// + EmuConstants::CURSOR_BAG_BEGIN - legacy::SLOT_CURSOR_BAG_BEGIN; - //if (server_slot < EmuConstants::CURSOR_BAG_BEGIN || server_slot > EmuConstants::CURSOR_BAG_END) - // server_slot = INVALID_INDEX; - } - else if (perl_slot >= legacy::SLOT_TRIBUTE_BEGIN && perl_slot <= legacy::SLOT_TRIBUTE_END) { - server_slot = perl_slot;// + EmuConstants::TRIBUTE_BEGIN - legacy::SLOT_TRIBUTE_BEGIN; - //if (server_slot < EmuConstants::TRIBUTE_BEGIN || server_slot > EmuConstants::TRIBUTE_END) - // server_slot = INVALID_INDEX; - } - else if (perl_slot >= legacy::SLOT_BANK_BEGIN && perl_slot <= legacy::SLOT_BANK_END) { - server_slot = perl_slot;// + EmuConstants::BANK_BEGIN - legacy::SLOT_BANK_BEGIN; - //if (server_slot < EmuConstants::BANK_BEGIN || server_slot > EmuConstants::BANK_END) - // server_slot = INVALID_INDEX; - } - else if (perl_slot >= legacy::SLOT_BANK_BAGS_BEGIN && perl_slot <= legacy::SLOT_BANK_BAGS_END) { - server_slot = perl_slot;// + EmuConstants::BANK_BAGS_BEGIN - legacy::SLOT_BANK_BAGS_BEGIN; - //if (server_slot < EmuConstants::BANK_BAGS_BEGIN || server_slot > EmuConstants::BANK_BAGS_END) - // server_slot = INVALID_INDEX; - } - else if (perl_slot >= legacy::SLOT_SHARED_BANK_BEGIN && perl_slot <= legacy::SLOT_SHARED_BANK_END) { - server_slot = perl_slot;// + EmuConstants::SHARED_BANK_BEGIN - legacy::SLOT_SHARED_BANK_BEGIN; - //if (server_slot < EmuConstants::SHARED_BANK_BEGIN || server_slot > EmuConstants::SHARED_BANK_END) - // server_slot = INVALID_INDEX; - } - else if (perl_slot >= legacy::SLOT_SHARED_BANK_BAGS_BEGIN && perl_slot <= legacy::SLOT_SHARED_BANK_BAGS_END) { - server_slot = perl_slot;// + EmuConstants::SHARED_BANK_BAGS_BEGIN - legacy::SLOT_SHARED_BANK_BAGS_END; - //if (server_slot < EmuConstants::SHARED_BANK_BAGS_BEGIN || server_slot > EmuConstants::SHARED_BANK_BAGS_END) - // server_slot = INVALID_INDEX; - } - else if (perl_slot >= legacy::SLOT_TRADE_BEGIN && perl_slot <= legacy::SLOT_TRADE_END) { - server_slot = perl_slot;// + EmuConstants::TRADE_BEGIN - legacy::SLOT_TRADE_BEGIN; - //if (server_slot < EmuConstants::TRADE_BEGIN || server_slot > EmuConstants::TRADE_END) - // server_slot = INVALID_INDEX; - } - else if (perl_slot >= legacy::SLOT_TRADE_BAGS_BEGIN && perl_slot <= legacy::SLOT_TRADE_BAGS_END) { - server_slot = perl_slot;// + EmuConstants::TRADE_BAGS_BEGIN - legacy::SLOT_TRADE_BAGS_BEGIN; - //if (server_slot < EmuConstants::TRADE_BAGS_BEGIN || server_slot > EmuConstants::TRADE_BAGS_END) - // server_slot = INVALID_INDEX; - } - else if (perl_slot >= legacy::SLOT_WORLD_BEGIN && perl_slot <= legacy::SLOT_WORLD_END) { - server_slot = perl_slot;// + EmuConstants::WORLD_BEGIN - legacy::SLOT_WORLD_BEGIN; - //if (server_slot < EmuConstants::WORLD_BEGIN || server_slot > EmuConstants::WORLD_END) - // server_slot = INVALID_INDEX; - } - else if (perl_slot >= 8000 && perl_slot <= 8999) { // this range may be limited to 36 in the future (client size) - server_slot = perl_slot; - } - - return server_slot; - } -} -*/ // // class EQLimits // // client validation -bool EQLimits::IsValidClientVersion(uint32 version) { - if (version < _EQClientCount) +bool EQLimits::IsValidPCClientVersion(ClientVersion clientVersion) { + if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_PC_CLIENT) return true; return false; } -uint32 EQLimits::ValidateClientVersion(uint32 version) { - if (version < _EQClientCount) - return version; +ClientVersion EQLimits::ValidatePCClientVersion(ClientVersion clientVersion) { + if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_PC_CLIENT) + return clientVersion; - return EQClientUnknown; -} - -EQClientVersion EQLimits::ValidateClientVersion(EQClientVersion version) { - if (version >= EQClientUnknown) - if (version < _EQClientCount) - return version; - - return EQClientUnknown; + return ClientVersion::Unknown; } // npc validation -bool EQLimits::IsValidNPCVersion(uint32 version) { - if (version >= _EQClientCount) - if (version < _EmuClientCount) - return true; - - return false; -} - -uint32 EQLimits::ValidateNPCVersion(uint32 version) { - if (version >= _EQClientCount) - if (version < _EmuClientCount) - return version; - - return EQClientUnknown; -} - -EQClientVersion EQLimits::ValidateNPCVersion(EQClientVersion version) { - if (version >= _EQClientCount) - if (version < _EmuClientCount) - return version; - - return EQClientUnknown; -} - -// mob validation -bool EQLimits::IsValidMobVersion(uint32 version) { - if (version < _EmuClientCount) +bool EQLimits::IsValidNPCClientVersion(ClientVersion clientVersion) { + if (clientVersion > LAST_PC_CLIENT && clientVersion <= LAST_NPC_CLIENT) return true; return false; } -uint32 EQLimits::ValidateMobVersion(uint32 version) { - if (version < _EmuClientCount) - return version; +ClientVersion EQLimits::ValidateNPCClientVersion(ClientVersion clientVersion) { + if (clientVersion > LAST_PC_CLIENT && clientVersion <= LAST_NPC_CLIENT) + return clientVersion; - return EQClientUnknown; + return ClientVersion::Unknown; } -EQClientVersion EQLimits::ValidateMobVersion(EQClientVersion version) { - if (version >= EQClientUnknown) - if (version < _EmuClientCount) - return version; +// mob validation +bool EQLimits::IsValidMobClientVersion(ClientVersion clientVersion) { + if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_NPC_CLIENT) + return true; - return EQClientUnknown; + return false; +} + +ClientVersion EQLimits::ValidateMobClientVersion(ClientVersion clientVersion) { + if (clientVersion > ClientVersion::Unknown && clientVersion <= LAST_NPC_CLIENT) + return clientVersion; + + return ClientVersion::Unknown; } // inventory -uint16 EQLimits::InventoryMapSize(int16 map, uint32 version) { +uint16 EQLimits::InventoryMapSize(int16 indexMap, ClientVersion clientVersion) { // not all maps will have an instantiated container..some are references for queue generators (i.e., bazaar, mail, etc...) // a zero '0' indicates a needed value..otherwise, change to '_NOTUSED' for a null value so indices requiring research can be identified // ALL of these values need to be verified before pushing to live @@ -527,7 +317,7 @@ uint16 EQLimits::InventoryMapSize(int16 map, uint32 version) { // // when setting NPC-based values, try to adhere to an EmuConstants:: or NOT_USED value to avoid unnecessary issues - static const uint16 local[_MapCount][_EmuClientCount] = { + static const uint16 local[_MapCount][CLIENT_VERSION_COUNT] = { // server and database are sync'd to current MapPossessions's client as set in 'using namespace RoF::slots;' and // 'EmuConstants::MAP_POSSESSIONS_SIZE' - use/update EquipmentBitmask(), GeneralBitmask() and CursorBitmask() // for partial range validation checks and 'EmuConstants::MAP_POSSESSIONS_SIZE' for full range iterations @@ -702,7 +492,7 @@ uint16 EQLimits::InventoryMapSize(int16 map, uint32 version) { /*Titanium*/ Titanium::consts::MAP_CORPSE_SIZE, /*SoF*/ SoF::consts::MAP_CORPSE_SIZE, /*SoD*/ SoD::consts::MAP_CORPSE_SIZE, -/*Underfoot*/ Underfoot::consts::MAP_CORPSE_SIZE, +/*Underfoot*/ UF::consts::MAP_CORPSE_SIZE, /*RoF*/ RoF::consts::MAP_CORPSE_SIZE, /*RoF2*/ RoF2::consts::MAP_CORPSE_SIZE, @@ -732,7 +522,7 @@ uint16 EQLimits::InventoryMapSize(int16 map, uint32 version) { /*Titanium*/ Titanium::consts::MAP_INSPECT_SIZE, /*SoF*/ SoF::consts::MAP_INSPECT_SIZE, /*SoD*/ SoD::consts::MAP_INSPECT_SIZE, -/*Underfoot*/ Underfoot::consts::MAP_INSPECT_SIZE, +/*Underfoot*/ UF::consts::MAP_INSPECT_SIZE, /*RoF*/ RoF::consts::MAP_INSPECT_SIZE, /*RoF2*/ RoF2::consts::MAP_INSPECT_SIZE, @@ -908,19 +698,19 @@ uint16 EQLimits::InventoryMapSize(int16 map, uint32 version) { } }; - if ((uint16)map < _MapCount) - return local[map][ValidateMobVersion(version)]; + if ((uint16)indexMap < _MapCount) + return local[indexMap][static_cast(ValidateMobClientVersion(clientVersion))]; return NOT_USED; } -uint64 EQLimits::PossessionsBitmask(uint32 version) { +uint64 EQLimits::PossessionsBitmask(ClientVersion clientVersion) { // these are for the new inventory system (RoF)..not the current (Ti) one... // 0x0000000000200000 is SlotPowerSource (SoF+) // 0x0000000080000000 is SlotGeneral9 (RoF+) // 0x0000000100000000 is SlotGeneral10 (RoF+) - static const uint64 local[_EmuClientCount] = { + static const uint64 local[CLIENT_VERSION_COUNT] = { /*Unknown*/ NOT_USED, /*62*/ 0x000000027FDFFFFF, /*Titanium*/ 0x000000027FDFFFFF, @@ -937,11 +727,11 @@ uint64 EQLimits::PossessionsBitmask(uint32 version) { }; return NOT_USED; - //return local[ValidateMobVersion(version)]; + //return local[static_cast(ValidateMobClientVersion(clientVersion))]; } -uint64 EQLimits::EquipmentBitmask(uint32 version) { - static const uint64 local[_EmuClientCount] = { +uint64 EQLimits::EquipmentBitmask(ClientVersion clientVersion) { + static const uint64 local[CLIENT_VERSION_COUNT] = { /*Unknown*/ NOT_USED, /*62*/ 0x00000000005FFFFF, /*Titanium*/ 0x00000000005FFFFF, @@ -958,11 +748,11 @@ uint64 EQLimits::EquipmentBitmask(uint32 version) { }; return NOT_USED; - //return local[ValidateMobVersion(version)]; + //return local[static_cast(ValidateMobClientVersion(clientVersion))]; } -uint64 EQLimits::GeneralBitmask(uint32 version) { - static const uint64 local[_EmuClientCount] = { +uint64 EQLimits::GeneralBitmask(ClientVersion clientVersion) { + static const uint64 local[CLIENT_VERSION_COUNT] = { /*Unknown*/ NOT_USED, /*62*/ 0x000000007F800000, /*Titanium*/ 0x000000007F800000, @@ -979,11 +769,11 @@ uint64 EQLimits::GeneralBitmask(uint32 version) { }; return NOT_USED; - //return local[ValidateMobVersion(version)]; + //return local[static_cast(ValidateMobClientVersion(clientVersion))]; } -uint64 EQLimits::CursorBitmask(uint32 version) { - static const uint64 local[_EmuClientCount] = { +uint64 EQLimits::CursorBitmask(ClientVersion clientVersion) { + static const uint64 local[CLIENT_VERSION_COUNT] = { /*Unknown*/ NOT_USED, /*62*/ 0x0000000200000000, /*Titanium*/ 0x0000000200000000, @@ -1000,17 +790,17 @@ uint64 EQLimits::CursorBitmask(uint32 version) { }; return NOT_USED; - //return local[ValidateMobVersion(version)]; + //return local[static_cast(ValidateMobClientVersion(clientVersion))]; } -bool EQLimits::AllowsEmptyBagInBag(uint32 version) { - static const bool local[_EmuClientCount] = { +bool EQLimits::AllowsEmptyBagInBag(ClientVersion clientVersion) { + static const bool local[CLIENT_VERSION_COUNT] = { /*Unknown*/ false, /*62*/ false, /*Titanium*/ Titanium::limits::ALLOWS_EMPTY_BAG_IN_BAG, /*SoF*/ SoF::limits::ALLOWS_EMPTY_BAG_IN_BAG, /*SoD*/ SoD::limits::ALLOWS_EMPTY_BAG_IN_BAG, -/*Underfoot*/ Underfoot::limits::ALLOWS_EMPTY_BAG_IN_BAG, +/*Underfoot*/ UF::limits::ALLOWS_EMPTY_BAG_IN_BAG, /*RoF*/ RoF::limits::ALLOWS_EMPTY_BAG_IN_BAG, /*RoF2*/ RoF2::limits::ALLOWS_EMPTY_BAG_IN_BAG, @@ -1021,17 +811,17 @@ bool EQLimits::AllowsEmptyBagInBag(uint32 version) { }; return false; // not implemented - //return local[ValidateMobVersion(version)]; + //return local[static_cast(ValidateMobClientVersion(clientVersion))]; } -bool EQLimits::AllowsClickCastFromBag(uint32 version) { - static const bool local[_EmuClientCount] = { +bool EQLimits::AllowsClickCastFromBag(ClientVersion clientVersion) { + static const bool local[CLIENT_VERSION_COUNT] = { /*Unknown*/ false, /*62*/ false, /*Titanium*/ Titanium::limits::ALLOWS_CLICK_CAST_FROM_BAG, /*SoF*/ SoF::limits::ALLOWS_CLICK_CAST_FROM_BAG, /*SoD*/ SoD::limits::ALLOWS_CLICK_CAST_FROM_BAG, -/*Underfoot*/ Underfoot::limits::ALLOWS_CLICK_CAST_FROM_BAG, +/*Underfoot*/ UF::limits::ALLOWS_CLICK_CAST_FROM_BAG, /*RoF*/ RoF::limits::ALLOWS_CLICK_CAST_FROM_BAG, /*RoF2*/ RoF2::limits::ALLOWS_CLICK_CAST_FROM_BAG, @@ -1041,12 +831,12 @@ bool EQLimits::AllowsClickCastFromBag(uint32 version) { /*Pet*/ false }; - return local[ValidateMobVersion(version)]; + return local[static_cast(ValidateMobClientVersion(clientVersion))]; } // items -uint16 EQLimits::ItemCommonSize(uint32 version) { - static const uint16 local[_EmuClientCount] = { +uint16 EQLimits::ItemCommonSize(ClientVersion clientVersion) { + static const uint16 local[CLIENT_VERSION_COUNT] = { /*Unknown*/ NOT_USED, /*62*/ EmuConstants::ITEM_COMMON_SIZE, /*Titanium*/ EmuConstants::ITEM_COMMON_SIZE, @@ -1062,11 +852,11 @@ uint16 EQLimits::ItemCommonSize(uint32 version) { /*Pet*/ EmuConstants::ITEM_COMMON_SIZE }; - return local[ValidateMobVersion(version)]; + return local[static_cast(ValidateMobClientVersion(clientVersion))]; } -uint16 EQLimits::ItemContainerSize(uint32 version) { - static const uint16 local[_EmuClientCount] = { +uint16 EQLimits::ItemContainerSize(ClientVersion clientVersion) { + static const uint16 local[CLIENT_VERSION_COUNT] = { /*Unknown*/ NOT_USED, /*62*/ EmuConstants::ITEM_CONTAINER_SIZE, /*Titanium*/ EmuConstants::ITEM_CONTAINER_SIZE, @@ -1082,17 +872,17 @@ uint16 EQLimits::ItemContainerSize(uint32 version) { /*Pet*/ EmuConstants::ITEM_CONTAINER_SIZE }; - return local[ValidateMobVersion(version)]; + return local[static_cast(ValidateMobClientVersion(clientVersion))]; } -bool EQLimits::CoinHasWeight(uint32 version) { - static const bool local[_EmuClientCount] = { +bool EQLimits::CoinHasWeight(ClientVersion clientVersion) { + static const bool local[CLIENT_VERSION_COUNT] = { /*Unknown*/ true, /*62*/ true, /*Titanium*/ Titanium::limits::COIN_HAS_WEIGHT, /*SoF*/ SoF::limits::COIN_HAS_WEIGHT, /*SoD*/ SoD::limits::COIN_HAS_WEIGHT, -/*Underfoot*/ Underfoot::limits::COIN_HAS_WEIGHT, +/*Underfoot*/ UF::limits::COIN_HAS_WEIGHT, /*RoF*/ RoF::limits::COIN_HAS_WEIGHT, /*RoF2*/ RoF::limits::COIN_HAS_WEIGHT, @@ -1102,11 +892,11 @@ bool EQLimits::CoinHasWeight(uint32 version) { /*Pet*/ true }; - return local[ValidateMobVersion(version)]; + return local[static_cast(ValidateMobClientVersion(clientVersion))]; } -uint32 EQLimits::BandoliersCount(uint32 version) { - static const uint32 local[_EmuClientCount] = { +uint32 EQLimits::BandoliersCount(ClientVersion clientVersion) { + static const uint32 local[CLIENT_VERSION_COUNT] = { /*Unknown*/ NOT_USED, /*62*/ EmuConstants::BANDOLIERS_COUNT, /*Titanium*/ EmuConstants::BANDOLIERS_COUNT, @@ -1122,11 +912,11 @@ uint32 EQLimits::BandoliersCount(uint32 version) { /*Pet*/ NOT_USED }; - return local[ValidateMobVersion(version)]; + return local[static_cast(ValidateMobClientVersion(clientVersion))]; } -uint32 EQLimits::BandolierSize(uint32 version) { - static const uint32 local[_EmuClientCount] = { +uint32 EQLimits::BandolierSize(ClientVersion clientVersion) { + static const uint32 local[CLIENT_VERSION_COUNT] = { /*Unknown*/ NOT_USED, /*62*/ EmuConstants::BANDOLIER_SIZE, /*Titanium*/ EmuConstants::BANDOLIER_SIZE, @@ -1142,11 +932,11 @@ uint32 EQLimits::BandolierSize(uint32 version) { /*Pet*/ NOT_USED }; - return local[ValidateMobVersion(version)]; + return local[static_cast(ValidateMobClientVersion(clientVersion))]; } -uint32 EQLimits::PotionBeltSize(uint32 version) { - static const uint32 local[_EmuClientCount] = { +uint32 EQLimits::PotionBeltSize(ClientVersion clientVersion) { + static const uint32 local[CLIENT_VERSION_COUNT] = { /*Unknown*/ NOT_USED, /*62*/ EmuConstants::POTION_BELT_SIZE, /*Titanium*/ EmuConstants::POTION_BELT_SIZE, @@ -1162,5 +952,5 @@ uint32 EQLimits::PotionBeltSize(uint32 version) { /*Pet*/ NOT_USED }; - return local[ValidateMobVersion(version)]; + return local[static_cast(ValidateMobClientVersion(clientVersion))]; } diff --git a/common/eq_dictionary.h b/common/eq_dictionary.h index 43511072f..d1337856e 100644 --- a/common/eq_dictionary.h +++ b/common/eq_dictionary.h @@ -29,7 +29,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "../common/patches/titanium_constants.h" #include "../common/patches/sof_constants.h" #include "../common/patches/sod_constants.h" -#include "../common/patches/underfoot_constants.h" +#include "../common/patches/uf_constants.h" #include "../common/patches/rof_constants.h" #include "../common/patches/rof2_constants.h" @@ -46,15 +46,15 @@ class EmuConstants { // an immutable value is required to initialize arrays, etc... use this class as a repository for those public: // database - static const EQClientVersion CHARACTER_CREATION_CLIENT = EQClientRoF; // adjust according to starting item placement and target client + static const ClientVersion CHARACTER_CREATION_CLIENT = ClientVersion::RoF2; // adjust according to starting item placement and target client // inventory - static uint16 InventoryMapSize(int16 map); + static uint16 InventoryMapSize(int16 indexMap); //static std::string InventoryLocationName(Location_Struct location); - static std::string InventoryMapName(int16 map); - static std::string InventoryMainName(int16 main); - static std::string InventorySubName(int16 sub); - static std::string InventoryAugName(int16 aug); + static std::string InventoryMapName(int16 indexMap); + static std::string InventoryMainName(int16 indexMain); + static std::string InventorySubName(int16 indexSub); + static std::string InventoryAugName(int16 indexAug); // these are currently hard-coded for existing inventory system..do not use in place of special client version handlers until ready static const uint16 MAP_POSSESSIONS_SIZE = _MainCount; @@ -149,6 +149,8 @@ public: static const uint32 BANDOLIER_SIZE = Titanium::consts::BANDOLIER_SIZE; // size = number of equipment slots in bandolier instance static const uint32 POTION_BELT_SIZE = Titanium::consts::POTION_BELT_SIZE; + static const size_t TEXT_LINK_BODY_LENGTH = 56; + // legacy-related functions //static int ServerToPerlSlot(int slot); // encode //static int PerlToServerSlot(int slot); // decode @@ -161,44 +163,41 @@ class EQLimits { public: // client version validation (checks to avoid crashing zone server when accessing reference arrays) // use this inside of class Client (limits to actual clients) - static bool IsValidClientVersion(uint32 version); - static uint32 ValidateClientVersion(uint32 version); - static EQClientVersion ValidateClientVersion(EQClientVersion version); + static bool IsValidPCClientVersion(ClientVersion clientVersion); + static ClientVersion ValidatePCClientVersion(ClientVersion clientVersion); // basically..any non-client classes - do not when setting a valid client - static bool IsValidNPCVersion(uint32 version); - static uint32 ValidateNPCVersion(uint32 version); - static EQClientVersion ValidateNPCVersion(EQClientVersion version); + static bool IsValidNPCClientVersion(ClientVersion clientVersion); + static ClientVersion ValidateNPCClientVersion(ClientVersion clientVersion); // these are 'universal' - do not when setting a valid client - static bool IsValidMobVersion(uint32 version); - static uint32 ValidateMobVersion(uint32 version); - static EQClientVersion ValidateMobVersion(EQClientVersion version); + static bool IsValidMobClientVersion(ClientVersion clientVersion); + static ClientVersion ValidateMobClientVersion(ClientVersion clientVersion); // inventory - static uint16 InventoryMapSize(int16 map, uint32 version); - static uint64 PossessionsBitmask(uint32 version); - static uint64 EquipmentBitmask(uint32 version); - static uint64 GeneralBitmask(uint32 version); - static uint64 CursorBitmask(uint32 version); + static uint16 InventoryMapSize(int16 indexMap, ClientVersion clientVersion); + static uint64 PossessionsBitmask(ClientVersion clientVersion); + static uint64 EquipmentBitmask(ClientVersion clientVersion); + static uint64 GeneralBitmask(ClientVersion clientVersion); + static uint64 CursorBitmask(ClientVersion clientVersion); - static bool AllowsEmptyBagInBag(uint32 version); - static bool AllowsClickCastFromBag(uint32 version); + static bool AllowsEmptyBagInBag(ClientVersion clientVersion); + static bool AllowsClickCastFromBag(ClientVersion clientVersion); // items - static uint16 ItemCommonSize(uint32 version); - static uint16 ItemContainerSize(uint32 version); + static uint16 ItemCommonSize(ClientVersion clientVersion); + static uint16 ItemContainerSize(ClientVersion clientVersion); // player profile - static bool CoinHasWeight(uint32 version); + static bool CoinHasWeight(ClientVersion clientVersion); - static uint32 BandoliersCount(uint32 version); - static uint32 BandolierSize(uint32 version); + static uint32 BandoliersCount(ClientVersion clientVersion); + static uint32 BandolierSize(ClientVersion clientVersion); - static uint32 PotionBeltSize(uint32 version); + static uint32 PotionBeltSize(ClientVersion clientVersion); }; -#endif /* EQ_LIMITS_H */ +#endif /* EQ_DICTIONARY_H */ /* Working Notes: diff --git a/common/eq_packet.cpp b/common/eq_packet.cpp index 60d892c23..e01f6a3f8 100644 --- a/common/eq_packet.cpp +++ b/common/eq_packet.cpp @@ -17,13 +17,14 @@ */ #include "crc16.h" -#include "debug.h" +#include "global_define.h" #include "eq_packet.h" #include "misc.h" #include "op_codes.h" #include "platform.h" #include #include +#include #include #ifndef STATIC_OPCODE @@ -510,3 +511,8 @@ void DumpPacket(const EQApplicationPacket* app, bool iShowInfo) { // DumpPacketAscii(app->pBuffer, app->size); } +std::string DumpPacketToString(const EQApplicationPacket* app){ + std::ostringstream out; + out << DumpPacketHexToString(app->pBuffer, app->size); + return out.str(); +} \ No newline at end of file diff --git a/common/eq_packet.h b/common/eq_packet.h index dcd3747a0..ed90d132a 100644 --- a/common/eq_packet.h +++ b/common/eq_packet.h @@ -20,6 +20,7 @@ #include "base_packet.h" #include "platform.h" +#include #ifdef STATIC_OPCODE typedef unsigned short EmuOpcode; @@ -146,6 +147,6 @@ protected: }; extern void DumpPacket(const EQApplicationPacket* app, bool iShowInfo = false); - +extern std::string DumpPacketToString(const EQApplicationPacket* app); #endif diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index 07daa97fd..62f6072b3 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -300,7 +300,7 @@ struct Spawn_Struct { /*0036*/ uint8 afk; // 0=no, 1=afk /*0238*/ uint32 guildID; // Current guild /*0242*/ char title[32]; // Title -/*0274*/ uint8 unknown0274; +/*0274*/ uint8 unknown0274; // non-zero prefixes name with '!' /*0275*/ uint8 set_to_0xFF[8]; // ***Placeholder (all ff) /*0283*/ uint8 helm; // Helm texture /*0284*/ uint32 race; // Spawn race @@ -540,7 +540,7 @@ struct SpawnAppearance_Struct }; -// solar: this is used inside profile +// this is used inside profile struct SpellBuff_Struct { /*000*/ uint8 slotid; //badly named... seems to be 2 for a real buff, 0 otherwise @@ -1268,7 +1268,7 @@ struct Animation_Struct { /*04*/ }; -// solar: this is what causes the caster to animate and the target to +// this is what causes the caster to animate and the target to // get the particle effects around them when a spell is cast // also causes a buff icon struct Action_Struct @@ -1292,7 +1292,7 @@ struct Action_Struct /* 31 */ }; -// solar: this is what prints the You have been struck. and the regular +// this is what prints the You have been struck. and the regular // melee messages like You try to pierce, etc. It's basically the melee // and spell damage message struct CombatDamage_Struct @@ -1811,7 +1811,7 @@ struct RandomReq_Struct { uint32 high; }; -/* solar: 9/23/03 reply to /random command; struct from Zaphod */ +/* 9/23/03 reply to /random command */ struct RandomReply_Struct { /* 00 */ uint32 low; /* 04 */ uint32 high; @@ -2388,7 +2388,7 @@ struct AugmentItem_Struct { // OP_Emote struct Emote_Struct { -/*0000*/ uint32 unknown01; +/*0000*/ uint32 type; // 0 - custom, 0xffffffff - command (/dance, /flip, etc...) /*0004*/ char message[1024]; /*1028*/ }; @@ -5269,6 +5269,23 @@ struct ClientMarqueeMessage_Struct { typedef std::list ItemList; +struct TextLinkBody_Struct { + // Current server mask: EQClientRoF2 + uint8 unknown_1; /* %1X */ + uint32 item_id; /* %05X */ + uint32 augment_1; /* %05X */ + uint32 augment_2; /* %05X */ + uint32 augment_3; /* %05X */ + uint32 augment_4; /* %05X */ + uint32 augment_5; /* %05X */ + uint32 augment_6; /* %05X */ + uint8 is_evolving; /* %1X */ + uint32 evolve_group; /* %05X */ + uint8 evolve_level; /* %02X */ + uint32 ornament_icon; /* %05X */ + int hash; /* %08X */ +}; + // Restore structure packing to default #pragma pack() diff --git a/common/eq_stream.cpp b/common/eq_stream.cpp index 594f3b5bc..be1ae50d4 100644 --- a/common/eq_stream.cpp +++ b/common/eq_stream.cpp @@ -16,12 +16,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "debug.h" +#include "global_define.h" +#include "eqemu_logsys.h" #include "eq_packet.h" #include "eq_stream.h" #include "op_codes.h" #include "crc16.h" #include "platform.h" +#include "string_util.h" #include #include @@ -80,19 +82,19 @@ void EQStream::init(bool resetSession) { OpMgr = nullptr; if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - _log(NET__ERROR, _L "init Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); + Log.Out(Logs::Detail, Logs::Netcode, _L "init Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); } if(NextSequencedSend > SequencedQueue.size()) { - _log(NET__ERROR, _L "init Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + Log.Out(Logs::Detail, Logs::Netcode, _L "init Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); } } EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p) { EQRawApplicationPacket *ap=nullptr; - _log(NET__APP_CREATE, _L "Creating new application packet, length %d" __L, p->size); - _raw(NET__APP_CREATE_HEX, 0xFFFF, p); + Log.Out(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, p->size); + // _raw(NET__APP_CREATE_HEX, 0xFFFF, p); ap = p->MakeAppPacket(); return ap; } @@ -100,8 +102,7 @@ EQRawApplicationPacket *EQStream::MakeApplicationPacket(EQProtocolPacket *p) EQRawApplicationPacket *EQStream::MakeApplicationPacket(const unsigned char *buf, uint32 len) { EQRawApplicationPacket *ap=nullptr; - _log(NET__APP_CREATE, _L "Creating new application packet, length %d" __L, len); - _hex(NET__APP_CREATE_HEX, buf, len); + Log.Out(Logs::Detail, Logs::Netcode, _L "Creating new application packet, length %d" __L, len); ap = new EQRawApplicationPacket(buf, len); return ap; } @@ -131,8 +132,8 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) } if (!Session && p->opcode!=OP_SessionRequest && p->opcode!=OP_SessionResponse) { - _log(NET__DEBUG, _L "Session not initialized, packet ignored" __L); - _raw(NET__DEBUG, 0xFFFF, p); + Log.Out(Logs::Detail, Logs::Netcode, _L "Session not initialized, packet ignored" __L); + // _raw(NET__DEBUG, 0xFFFF, p); return; } @@ -142,8 +143,8 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) while(processed < p->size) { subpacket_length=*(p->pBuffer+processed); EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+processed+1,subpacket_length); - _log(NET__NET_CREATE, _L "Extracting combined packet of length %d" __L, subpacket_length); - _raw(NET__NET_CREATE_HEX, 0xFFFF, subp); + Log.Out(Logs::Detail, Logs::Netcode, _L "Extracting combined packet of length %d" __L, subpacket_length); + // _raw(NET__NET_CREATE_HEX, 0xFFFF, subp); subp->copyInfo(p); ProcessPacket(subp); delete subp; @@ -157,12 +158,12 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) while(processedsize) { EQRawApplicationPacket *ap=nullptr; if ((subpacket_length=(unsigned char)*(p->pBuffer+processed))!=0xff) { - _log(NET__NET_CREATE, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length); + Log.Out(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length); ap=MakeApplicationPacket(p->pBuffer+processed+1,subpacket_length); processed+=subpacket_length+1; } else { subpacket_length=ntohs(*(uint16 *)(p->pBuffer+processed+1)); - _log(NET__NET_CREATE, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length); + Log.Out(Logs::Detail, Logs::Netcode, _L "Extracting combined app packet of length %d, short len" __L, subpacket_length); ap=MakeApplicationPacket(p->pBuffer+processed+3,subpacket_length); processed+=subpacket_length+3; } @@ -177,29 +178,29 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) case OP_Packet: { if(!p->pBuffer || (p->Size() < 4)) { - _log(NET__ERROR, _L "Received OP_Packet that was of malformed size" __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_Packet that was of malformed size" __L); break; } uint16 seq=ntohs(*(uint16 *)(p->pBuffer)); SeqOrder check=CompareSequence(NextInSeq,seq); if (check == SeqFuture) { - _log(NET__DEBUG, _L "Future OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); - _raw(NET__DEBUG, seq, p); + Log.Out(Logs::Detail, Logs::Netcode, _L "Future OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); + // _raw(NET__DEBUG, seq, p); PacketQueue[seq]=p->Copy(); - _log(NET__APP_TRACE, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); + Log.Out(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); //SendOutOfOrderAck(seq); } else if (check == SeqPast) { - _log(NET__DEBUG, _L "Duplicate OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); - _raw(NET__DEBUG, seq, p); + Log.Out(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Packet: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); + // _raw(NET__DEBUG, seq, p); SendOutOfOrderAck(seq); //we already got this packet but it was out of order } else { // In case we did queue one before as well. EQProtocolPacket *qp=RemoveQueue(seq); if (qp) { - _log(NET__NET_TRACE, "OP_Packet: Removing older queued packet with sequence %d", seq); + Log.Out(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Packet: Removing older queued packet with sequence %d", seq); delete qp; } @@ -208,8 +209,8 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) // Check for an embedded OP_AppCombinded (protocol level 0x19) if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) { EQProtocolPacket *subp=MakeProtocolPacket(p->pBuffer+2,p->size-2); - _log(NET__NET_CREATE, _L "seq %d, Extracting combined packet of length %d" __L, seq, subp->size); - _raw(NET__NET_CREATE_HEX, seq, subp); + Log.Out(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined packet of length %d" __L, seq, subp->size); + // _raw(NET__NET_CREATE_HEX, seq, subp); subp->copyInfo(p); ProcessPacket(subp); delete subp; @@ -227,29 +228,29 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) case OP_Fragment: { if(!p->pBuffer || (p->Size() < 4)) { - _log(NET__ERROR, _L "Received OP_Fragment that was of malformed size" __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_Fragment that was of malformed size" __L); break; } uint16 seq=ntohs(*(uint16 *)(p->pBuffer)); SeqOrder check=CompareSequence(NextInSeq,seq); if (check == SeqFuture) { - _log(NET__DEBUG, _L "Future OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); - _raw(NET__DEBUG, seq, p); + Log.Out(Logs::Detail, Logs::Netcode, _L "Future OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); + // _raw(NET__DEBUG, seq, p); PacketQueue[seq]=p->Copy(); - _log(NET__APP_TRACE, _L "OP_Fragment Queue size=%d" __L, PacketQueue.size()); + Log.Out(Logs::Detail, Logs::Netcode, _L "OP_Fragment Queue size=%d" __L, PacketQueue.size()); //SendOutOfOrderAck(seq); } else if (check == SeqPast) { - _log(NET__DEBUG, _L "Duplicate OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); - _raw(NET__DEBUG, seq, p); + Log.Out(Logs::Detail, Logs::Netcode, _L "Duplicate OP_Fragment: Expecting Seq=%d, but got Seq=%d" __L, NextInSeq, seq); + // _raw(NET__DEBUG, seq, p); SendOutOfOrderAck(seq); } else { // In case we did queue one before as well. EQProtocolPacket *qp=RemoveQueue(seq); if (qp) { - _log(NET__NET_TRACE, "OP_Fragment: Removing older queued packet with sequence %d", seq); + Log.Out(Logs::General, Logs::Netcode, "[NET_TRACE] OP_Fragment: Removing older queued packet with sequence %d", seq); delete qp; } SetNextAckToSend(seq); @@ -257,18 +258,18 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) if (oversize_buffer) { memcpy(oversize_buffer+oversize_offset,p->pBuffer+2,p->size-2); oversize_offset+=p->size-2; - _log(NET__NET_TRACE, _L "Fragment of oversized of length %d, seq %d: now at %d/%d" __L, p->size-2, seq, oversize_offset, oversize_length); + Log.Out(Logs::Detail, Logs::Netcode, _L "Fragment of oversized of length %d, seq %d: now at %d/%d" __L, p->size-2, seq, oversize_offset, oversize_length); if (oversize_offset==oversize_length) { if (*(p->pBuffer+2)==0x00 && *(p->pBuffer+3)==0x19) { EQProtocolPacket *subp=MakeProtocolPacket(oversize_buffer,oversize_offset); - _log(NET__NET_CREATE, _L "seq %d, Extracting combined oversize packet of length %d" __L, seq, subp->size); - //_raw(NET__NET_CREATE_HEX, subp); + Log.Out(Logs::Detail, Logs::Netcode, _L "seq %d, Extracting combined oversize packet of length %d" __L, seq, subp->size); + //// _raw(NET__NET_CREATE_HEX, subp); subp->copyInfo(p); ProcessPacket(subp); delete subp; } else { EQRawApplicationPacket *ap=MakeApplicationPacket(oversize_buffer,oversize_offset); - _log(NET__NET_CREATE, _L "seq %d, completed combined oversize packet of length %d" __L, seq, ap->size); + Log.Out(Logs::Detail, Logs::Netcode, _L "seq %d, completed combined oversize packet of length %d" __L, seq, ap->size); if (ap) { ap->copyInfo(p); InboundQueuePush(ap); @@ -283,7 +284,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) oversize_buffer=new unsigned char[oversize_length]; memcpy(oversize_buffer,p->pBuffer+6,p->size-6); oversize_offset=p->size-6; - _log(NET__NET_TRACE, _L "First fragment of oversized of seq %d: now at %d/%d" __L, seq, oversize_offset, oversize_length); + Log.Out(Logs::Detail, Logs::Netcode, _L "First fragment of oversized of seq %d: now at %d/%d" __L, seq, oversize_offset, oversize_length); } } } @@ -291,14 +292,14 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) case OP_KeepAlive: { #ifndef COLLECTOR NonSequencedPush(new EQProtocolPacket(p->opcode,p->pBuffer,p->size)); - _log(NET__NET_TRACE, _L "Received and queued reply to keep alive" __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received and queued reply to keep alive" __L); #endif } break; case OP_Ack: { if(!p->pBuffer || (p->Size() < 4)) { - _log(NET__ERROR, _L "Received OP_Ack that was of malformed size" __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_Ack that was of malformed size" __L); break; } #ifndef COLLECTOR @@ -314,12 +315,12 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) case OP_SessionRequest: { if(p->Size() < sizeof(SessionRequest)) { - _log(NET__ERROR, _L "Received OP_SessionRequest that was of malformed size" __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest that was of malformed size" __L); break; } #ifndef COLLECTOR if (GetState()==ESTABLISHED) { - _log(NET__ERROR, _L "Received OP_SessionRequest in ESTABLISHED state (%d) streamactive (%i) attempt (%i)" __L, GetState(),streamactive,sessionAttempts); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest in ESTABLISHED state (%d) streamactive (%i) attempt (%i)" __L, GetState(),streamactive,sessionAttempts); // client seems to try a max of 30 times (initial+3 retries) then gives up, giving it a few more attempts just in case // streamactive means we identified the opcode for the stream, we cannot re-establish this connection @@ -331,7 +332,6 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) } } #endif - //std::cout << "Got OP_SessionRequest" << std::endl; sessionAttempts++; // we set established below, so statistics will not be reset for session attempts/stream active. init(GetState()!=ESTABLISHED); @@ -339,7 +339,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) SessionRequest *Request=(SessionRequest *)p->pBuffer; Session=ntohl(Request->Session); SetMaxLen(ntohl(Request->MaxLength)); - _log(NET__NET_TRACE, _L "Received OP_SessionRequest: session %lu, maxlen %d" __L, (unsigned long)Session, MaxLen); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionRequest: session %lu, maxlen %d" __L, (unsigned long)Session, MaxLen); SetState(ESTABLISHED); #ifndef COLLECTOR Key=0x11223344; @@ -350,7 +350,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) case OP_SessionResponse: { if(p->Size() < sizeof(SessionResponse)) { - _log(NET__ERROR, _L "Received OP_SessionResponse that was of malformed size" __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse that was of malformed size" __L); break; } @@ -366,7 +366,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) compressed=(Response->Format&FLAG_COMPRESSED); encoded=(Response->Format&FLAG_ENCODED); - _log(NET__NET_TRACE, _L "Received OP_SessionResponse: session %lu, maxlen %d, key %lu, compressed? %s, encoded? %s" __L, (unsigned long)Session, MaxLen, (unsigned long)Key, compressed?"yes":"no", encoded?"yes":"no"); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionResponse: session %lu, maxlen %d, key %lu, compressed? %s, encoded? %s" __L, (unsigned long)Session, MaxLen, (unsigned long)Key, compressed?"yes":"no", encoded?"yes":"no"); // Kinda kludgy, but trie for now if (StreamType==UnknownStream) { @@ -389,17 +389,17 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) EQStreamState state = GetState(); if(state == ESTABLISHED) { //client initiated disconnect? - _log(NET__NET_TRACE, _L "Received unsolicited OP_SessionDisconnect. Treating like a client-initiated disconnect." __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received unsolicited OP_SessionDisconnect. Treating like a client-initiated disconnect." __L); _SendDisconnect(); SetState(CLOSED); } else if(state == CLOSING) { //we were waiting for this anyways, ignore pending messages, send the reply and be closed. - _log(NET__NET_TRACE, _L "Received OP_SessionDisconnect when we have a pending close, they beat us to it. Were happy though." __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionDisconnect when we have a pending close, they beat us to it. Were happy though." __L); _SendDisconnect(); SetState(CLOSED); } else { //we are expecting this (or have already gotten it, but dont care either way) - _log(NET__NET_TRACE, _L "Received expected OP_SessionDisconnect. Moving to closed state." __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received expected OP_SessionDisconnect. Moving to closed state." __L); SetState(CLOSED); } } @@ -407,7 +407,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) case OP_OutOfOrderAck: { if(!p->pBuffer || (p->Size() < 4)) { - _log(NET__ERROR, _L "Received OP_OutOfOrderAck that was of malformed size" __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck that was of malformed size" __L); break; } #ifndef COLLECTOR @@ -415,15 +415,15 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) MOutboundQueue.lock(); if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - _log(NET__ERROR, _L "Pre-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); } if(NextSequencedSend > SequencedQueue.size()) { - _log(NET__ERROR, _L "Pre-OOA Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-OOA Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); } //if the packet they got out of order is between our last acked packet and the last sent packet, then its valid. if (CompareSequence(SequencedBase,seq) != SeqPast && CompareSequence(NextOutSeq,seq) == SeqPast) { - _log(NET__NET_TRACE, _L "Received OP_OutOfOrderAck for sequence %d, starting retransmit at the start of our unacked buffer (seq %d, was %d)." __L, + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for sequence %d, starting retransmit at the start of our unacked buffer (seq %d, was %d)." __L, seq, SequencedBase, SequencedBase+NextSequencedSend); bool retransmit_acked_packets = false; @@ -434,7 +434,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) if(!retransmit_acked_packets) { uint16 sqsize = SequencedQueue.size(); uint16 index = seq - SequencedBase; - _log(NET__NET_TRACE, _L "OP_OutOfOrderAck marking packet acked in queue (queue index = %d, queue size = %d)." __L, index, sqsize); + Log.Out(Logs::Detail, Logs::Netcode, _L "OP_OutOfOrderAck marking packet acked in queue (queue index = %d, queue size = %d)." __L, index, sqsize); if (index < sqsize) { std::deque::iterator sitr; sitr = SequencedQueue.begin(); @@ -449,15 +449,15 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) NextSequencedSend = 0; } else { - _log(NET__NET_TRACE, _L "Received OP_OutOfOrderAck for out-of-window %d. Window (%d->%d)." __L, seq, SequencedBase, NextOutSeq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfOrderAck for out-of-window %d. Window (%d->%d)." __L, seq, SequencedBase, NextOutSeq); } if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - _log(NET__ERROR, _L "Post-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Post-OOA Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); } if(NextSequencedSend > SequencedQueue.size()) { - _log(NET__ERROR, _L "Post-OOA Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + Log.Out(Logs::Detail, Logs::Netcode, _L "Post-OOA Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); } MOutboundQueue.unlock(); #endif @@ -466,12 +466,12 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) case OP_SessionStatRequest: { if(p->Size() < sizeof(SessionStats)) { - _log(NET__ERROR, _L "Received OP_SessionStatRequest that was of malformed size" __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatRequest that was of malformed size" __L); break; } #ifndef COLLECTOR SessionStats *Stats=(SessionStats *)p->pBuffer; - _log(NET__NET_TRACE, _L "Received Stats: %lu packets received, %lu packets sent, Deltas: local %lu, (%lu <- %lu -> %lu) remote %lu" __L, + Log.Out(Logs::Detail, Logs::Netcode, _L "Received Stats: %lu packets received, %lu packets sent, Deltas: local %lu, (%lu <- %lu -> %lu) remote %lu" __L, (unsigned long)ntohl(Stats->packets_received), (unsigned long)ntohl(Stats->packets_sent), (unsigned long)ntohl(Stats->last_local_delta), (unsigned long)ntohl(Stats->low_delta), (unsigned long)ntohl(Stats->average_delta), (unsigned long)ntohl(Stats->high_delta), (unsigned long)ntohl(Stats->last_remote_delta)); @@ -492,18 +492,18 @@ void EQStream::ProcessPacket(EQProtocolPacket *p) } if(retransmittimeout > RETRANSMIT_TIMEOUT_MAX) retransmittimeout = RETRANSMIT_TIMEOUT_MAX; - _log(NET__NET_TRACE, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout); + Log.Out(Logs::Detail, Logs::Netcode, _L "Retransmit timeout recalculated to %dms" __L, retransmittimeout); } } #endif } break; case OP_SessionStatResponse: { - _log(NET__NET_TRACE, _L "Received OP_SessionStatResponse. Ignoring." __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_SessionStatResponse. Ignoring." __L); } break; case OP_OutOfSession: { - _log(NET__NET_TRACE, _L "Received OP_OutOfSession. Ignoring." __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received OP_OutOfSession. Ignoring." __L); } break; default: @@ -534,7 +534,7 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req) return; if(OpMgr == nullptr || *OpMgr == nullptr) { - _log(NET__DEBUG, _L "Packet enqueued into a stream with no opcode manager, dropping." __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Packet enqueued into a stream with no opcode manager, dropping." __L); delete pack; return; } @@ -556,12 +556,24 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req) void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p) { - uint32 chunksize,used; + uint32 chunksize, used; uint32 length; + if (Log.log_settings[Logs::Server_Client_Packet].is_category_enabled == 1){ + if (p->GetOpcode() != OP_SpecialMesg){ + Log.Out(Logs::General, Logs::Server_Client_Packet, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size()); + } + } + + if (Log.log_settings[Logs::Server_Client_Packet_With_Dump].is_category_enabled == 1){ + if (p->GetOpcode() != OP_SpecialMesg){ + Log.Out(Logs::General, Logs::Server_Client_Packet_With_Dump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str()); + } + } + // Convert the EQApplicationPacket to 1 or more EQProtocolPackets if (p->size>(MaxLen-8)) { // proto-op(2), seq(2), app-op(2) ... data ... crc(2) - _log(NET__FRAGMENT, _L "Making oversized packet, len %d" __L, p->size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Making oversized packet, len %d" __L, p->size); unsigned char *tmpbuff=new unsigned char[p->size+3]; length=p->serialize(opcode, tmpbuff); @@ -570,7 +582,7 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p) *(uint32 *)(out->pBuffer+2)=htonl(p->Size()); used=MaxLen-10; memcpy(out->pBuffer+6,tmpbuff,used); - _log(NET__FRAGMENT, _L "First fragment: used %d/%d. Put size %d in the packet" __L, used, p->size, p->Size()); + Log.Out(Logs::Detail, Logs::Netcode, _L "First fragment: used %d/%d. Put size %d in the packet" __L, used, p->size, p->Size()); SequencedPush(out); @@ -581,7 +593,7 @@ void EQStream::SendPacket(uint16 opcode, EQApplicationPacket *p) out->size=chunksize+2; SequencedPush(out); used+=chunksize; - _log(NET__FRAGMENT, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, p->size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Subsequent fragment: len %d, used %d/%d." __L, chunksize, used, p->size); } delete p; delete[] tmpbuff; @@ -605,22 +617,22 @@ void EQStream::SequencedPush(EQProtocolPacket *p) #else MOutboundQueue.lock(); if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - _log(NET__ERROR, _L "Pre-Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); } if(NextSequencedSend > SequencedQueue.size()) { - _log(NET__ERROR, _L "Pre-Push Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Push Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); } - _log(NET__APP_TRACE, _L "Pushing sequenced packet %d of length %d. Base Seq is %d." __L, NextOutSeq, p->size, SequencedBase); + Log.Out(Logs::Detail, Logs::Netcode, _L "Pushing sequenced packet %d of length %d. Base Seq is %d." __L, NextOutSeq, p->size, SequencedBase); *(uint16 *)(p->pBuffer)=htons(NextOutSeq); SequencedQueue.push_back(p); NextOutSeq++; if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - _log(NET__ERROR, _L "Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Push Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); } if(NextSequencedSend > SequencedQueue.size()) { - _log(NET__ERROR, _L "Push Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + Log.Out(Logs::Detail, Logs::Netcode, _L "Push Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); } MOutboundQueue.unlock(); #endif @@ -632,7 +644,7 @@ void EQStream::NonSequencedPush(EQProtocolPacket *p) delete p; #else MOutboundQueue.lock(); - _log(NET__APP_TRACE, _L "Pushing non-sequenced packet of length %d" __L, p->size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Pushing non-sequenced packet of length %d" __L, p->size); NonSequencedQueue.push(p); MOutboundQueue.unlock(); #endif @@ -641,14 +653,14 @@ void EQStream::NonSequencedPush(EQProtocolPacket *p) void EQStream::SendAck(uint16 seq) { uint16 Seq=htons(seq); - _log(NET__NET_ACKS, _L "Sending ack with sequence %d" __L, seq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Sending ack with sequence %d" __L, seq); SetLastAckSent(seq); NonSequencedPush(new EQProtocolPacket(OP_Ack,(unsigned char *)&Seq,sizeof(uint16))); } void EQStream::SendOutOfOrderAck(uint16 seq) { - _log(NET__APP_TRACE, _L "Sending out of order ack with sequence %d" __L, seq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Sending out of order ack with sequence %d" __L, seq); uint16 Seq=htons(seq); NonSequencedPush(new EQProtocolPacket(OP_OutOfOrderAck,(unsigned char *)&Seq,sizeof(uint16))); } @@ -664,7 +676,6 @@ void EQStream::Write(int eq_fd) int32 threshold=RateThreshold; MRate.unlock(); if (BytesWritten > threshold) { - //std::cout << "Over threshold: " << BytesWritten << " > " << threshold << std::endl; return; } @@ -684,7 +695,7 @@ void EQStream::Write(int eq_fd) // if we have a timeout defined and we have not received an ack recently enough, retransmit from beginning of queue if (RETRANSMIT_TIMEOUT_MULT && !SequencedQueue.empty() && NextSequencedSend && (GetState()==ESTABLISHED) && ((retransmittimer+retransmittimeout) < Timer::GetCurrentTime())) { - _log(NET__NET_TRACE, _L "Timeout since last ack received, starting retransmit at the start of our unacked " + Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout since last ack received, starting retransmit at the start of our unacked " "buffer (seq %d, was %d)." __L, SequencedBase, SequencedBase+NextSequencedSend); NextSequencedSend = 0; retransmittimer = Timer::GetCurrentTime(); // don't want to endlessly retransmit the first packet @@ -705,24 +716,24 @@ void EQStream::Write(int eq_fd) // If we don't have a packet to try to combine into, use this one as the base // And remove it form the queue p = NonSequencedQueue.front(); - _log(NET__NET_COMBINE, _L "Starting combined packet with non-seq packet of len %d" __L, p->size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Starting combined packet with non-seq packet of len %d" __L, p->size); NonSequencedQueue.pop(); } else if (!p->combine(NonSequencedQueue.front())) { // Tryint to combine this packet with the base didn't work (too big maybe) // So just send the base packet (we'll try this packet again later) - _log(NET__NET_COMBINE, _L "Combined packet full at len %d, next non-seq packet is len %d" __L, p->size, (NonSequencedQueue.front())->size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next non-seq packet is len %d" __L, p->size, (NonSequencedQueue.front())->size); ReadyToSend.push(p); BytesWritten+=p->size; p=nullptr; if (BytesWritten > threshold) { // Sent enough this round, lets stop to be fair - _log(NET__RATES, _L "Exceeded write threshold in nonseq (%d > %d)" __L, BytesWritten, threshold); + Log.Out(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in nonseq (%d > %d)" __L, BytesWritten, threshold); break; } } else { // Combine worked, so just remove this packet and it's spot in the queue - _log(NET__NET_COMBINE, _L "Combined non-seq packet of len %d, yeilding %d combined." __L, (NonSequencedQueue.front())->size, p->size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Combined non-seq packet of len %d, yeilding %d combined." __L, (NonSequencedQueue.front())->size, p->size); delete NonSequencedQueue.front(); NonSequencedQueue.pop(); } @@ -733,48 +744,48 @@ void EQStream::Write(int eq_fd) if (sitr!=SequencedQueue.end()) { if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - _log(NET__ERROR, _L "Pre-Send Seq NSS=%d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, NextSequencedSend, SequencedBase, SequencedQueue.size(), NextOutSeq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Send Seq NSS=%d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, NextSequencedSend, SequencedBase, SequencedQueue.size(), NextOutSeq); } if(NextSequencedSend > SequencedQueue.size()) { - _log(NET__ERROR, _L "Pre-Send Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Send Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); } uint16 seq_send = SequencedBase + NextSequencedSend; //just for logging... if(SequencedQueue.empty()) { - _log(NET__ERROR, _L "Tried to write a packet with an empty queue (%d is past next out %d)" __L, seq_send, NextOutSeq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Tried to write a packet with an empty queue (%d is past next out %d)" __L, seq_send, NextOutSeq); SeqEmpty=true; continue; } if(GetExecutablePlatform() == ExePlatformWorld || GetExecutablePlatform() == ExePlatformZone) { if (!RETRANSMIT_ACKED_PACKETS && (*sitr)->acked) { - _log(NET__NET_TRACE, _L "Not retransmitting seq packet %d because already marked as acked" __L, seq_send); + Log.Out(Logs::Detail, Logs::Netcode, _L "Not retransmitting seq packet %d because already marked as acked" __L, seq_send); sitr++; NextSequencedSend++; } else if (!p) { // If we don't have a packet to try to combine into, use this one as the base // Copy it first as it will still live until it is acked p=(*sitr)->Copy(); - _log(NET__NET_COMBINE, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size); ++sitr; NextSequencedSend++; } else if (!p->combine(*sitr)) { // Trying to combine this packet with the base didn't work (too big maybe) // So just send the base packet (we'll try this packet again later) - _log(NET__NET_COMBINE, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send, (*sitr)->size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send, (*sitr)->size); ReadyToSend.push(p); BytesWritten+=p->size; p=nullptr; if (BytesWritten > threshold) { // Sent enough this round, lets stop to be fair - _log(NET__RATES, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold); + Log.Out(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold); break; } } else { // Combine worked - _log(NET__NET_COMBINE, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size); ++sitr; NextSequencedSend++; } @@ -783,35 +794,35 @@ void EQStream::Write(int eq_fd) // If we don't have a packet to try to combine into, use this one as the base // Copy it first as it will still live until it is acked p=(*sitr)->Copy(); - _log(NET__NET_COMBINE, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Starting combined packet with seq packet %d of len %d" __L, seq_send, p->size); ++sitr; NextSequencedSend++; } else if (!p->combine(*sitr)) { // Trying to combine this packet with the base didn't work (too big maybe) // So just send the base packet (we'll try this packet again later) - _log(NET__NET_COMBINE, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send, (*sitr)->size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Combined packet full at len %d, next seq packet %d is len %d" __L, p->size, seq_send, (*sitr)->size); ReadyToSend.push(p); BytesWritten+=p->size; p=nullptr; if (BytesWritten > threshold) { // Sent enough this round, lets stop to be fair - _log(NET__RATES, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold); + Log.Out(Logs::Detail, Logs::Netcode, _L "Exceeded write threshold in seq (%d > %d)" __L, BytesWritten, threshold); break; } } else { // Combine worked - _log(NET__NET_COMBINE, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Combined seq packet %d of len %d, yeilding %d combined." __L, seq_send, (*sitr)->size, p->size); ++sitr; NextSequencedSend++; } } if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - _log(NET__ERROR, _L "Post send Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Post send Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); } if(NextSequencedSend > SequencedQueue.size()) { - _log(NET__ERROR, _L "Post send Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + Log.Out(Logs::Detail, Logs::Netcode, _L "Post send Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); } } else { // No more sequenced packets @@ -823,7 +834,7 @@ void EQStream::Write(int eq_fd) // We have a packet still, must have run out of both seq and non-seq, so send it if (p) { - _log(NET__NET_COMBINE, _L "Final combined packet not full, len %d" __L, p->size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Final combined packet not full, len %d" __L, p->size); ReadyToSend.push(p); BytesWritten+=p->size; } @@ -840,7 +851,7 @@ void EQStream::Write(int eq_fd) if(SeqEmpty && NonSeqEmpty) { //no more data to send if(CheckState(CLOSING)) { - _log(NET__DEBUG, _L "All outgoing data flushed, closing stream." __L ); + Log.Out(Logs::Detail, Logs::Netcode, _L "All outgoing data flushed, closing stream." __L ); //we are waiting for the queues to empty, now we can do our disconnect. //this packet will not actually go out until the next call to Write(). _SendDisconnect(); @@ -903,7 +914,7 @@ EQProtocolPacket *out=new EQProtocolPacket(OP_SessionResponse,nullptr,sizeof(Ses out->size=sizeof(SessionResponse); - _log(NET__NET_TRACE, _L "Sending OP_SessionResponse: session %lu, maxlen=%d, key=0x%x, compressed? %s, encoded? %s" __L, + Log.Out(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionResponse: session %lu, maxlen=%d, key=0x%x, compressed? %s, encoded? %s" __L, (unsigned long)Session, MaxLen, Key, compressed?"yes":"no", encoded?"yes":"no"); NonSequencedPush(out); @@ -917,7 +928,7 @@ EQProtocolPacket *out=new EQProtocolPacket(OP_SessionRequest,nullptr,sizeof(Sess Request->Session=htonl(time(nullptr)); Request->MaxLength=htonl(512); - _log(NET__NET_TRACE, _L "Sending OP_SessionRequest: session %lu, maxlen=%d" __L, (unsigned long)ntohl(Request->Session), ntohl(Request->MaxLength)); + Log.Out(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionRequest: session %lu, maxlen=%d" __L, (unsigned long)ntohl(Request->Session), ntohl(Request->MaxLength)); NonSequencedPush(out); } @@ -931,7 +942,7 @@ void EQStream::_SendDisconnect() *(uint32 *)out->pBuffer=htonl(Session); NonSequencedPush(out); - _log(NET__NET_TRACE, _L "Sending OP_SessionDisconnect: session %lu" __L, (unsigned long)Session); + Log.Out(Logs::Detail, Logs::Netcode, _L "Sending OP_SessionDisconnect: session %lu" __L, (unsigned long)Session); } void EQStream::InboundQueuePush(EQRawApplicationPacket *p) @@ -953,15 +964,12 @@ EQRawApplicationPacket *p=nullptr; } MInboundQueue.unlock(); - //resolve the opcode if we can. - if(p) { - if(OpMgr != nullptr && *OpMgr != nullptr) { + if (p) { + if (OpMgr != nullptr && *OpMgr != nullptr) { EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode); -#if EQDEBUG >= 4 - if(emu_op == OP_Unknown) { - _log(NET__ERROR, "Unable to convert EQ opcode 0x%.4x to an Application opcode.", p->opcode); - } -#endif + if (emu_op == OP_Unknown) { + // Log.Out(Logs::General, Logs::Client_Server_Packet_Unhandled, "Unknown :: [%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->opcode, p->Size(), DumpPacketToString(p).c_str()); + } p->SetOpcode(emu_op); } } @@ -985,11 +993,10 @@ EQRawApplicationPacket *p=nullptr; if(p) { if(OpMgr != nullptr && *OpMgr != nullptr) { EmuOpcode emu_op = (*OpMgr)->EQToEmu(p->opcode); -#if EQDEBUG >= 4 if(emu_op == OP_Unknown) { - LogFile->write(EQEMuLog::Debug, "Unable to convert EQ opcode 0x%.4x to an Application opcode.", p->opcode); + Log.Out(Logs::General, Logs::Netcode, "Unable to convert EQ opcode 0x%.4x to an Application opcode.", p->opcode); } -#endif + p->SetOpcode(emu_op); } } @@ -1015,7 +1022,7 @@ void EQStream::InboundQueueClear() { EQApplicationPacket *p=nullptr; - _log(NET__APP_TRACE, _L "Clearing inbound queue" __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing inbound queue" __L); MInboundQueue.lock(); if (!InboundQueue.empty()) { @@ -1058,7 +1065,7 @@ void EQStream::OutboundQueueClear() { EQProtocolPacket *p=nullptr; - _log(NET__APP_TRACE, _L "Clearing outbound queue" __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing outbound queue" __L); MOutboundQueue.lock(); while(!NonSequencedQueue.empty()) { @@ -1080,7 +1087,7 @@ void EQStream::PacketQueueClear() { EQProtocolPacket *p=nullptr; - _log(NET__APP_TRACE, _L "Clearing future packet queue" __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Clearing future packet queue" __L); if(!PacketQueue.empty()) { std::map::iterator itr; @@ -1112,8 +1119,7 @@ uint32 newlength=0; delete p; ProcessQueue(); } else { - _log(NET__DEBUG, _L "Incoming packet failed checksum" __L); - _hex(NET__NET_CREATE_HEX, buffer, length); + Log.Out(Logs::Detail, Logs::Netcode, _L "Incoming packet failed checksum" __L); } } @@ -1142,33 +1148,33 @@ std::deque::iterator itr, tmp; MOutboundQueue.lock(); //do a bit of sanity checking. if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - _log(NET__ERROR, _L "Pre-Ack Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Ack Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq); } if(NextSequencedSend > SequencedQueue.size()) { - _log(NET__ERROR, _L "Pre-Ack Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + Log.Out(Logs::Detail, Logs::Netcode, _L "Pre-Ack Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); } SeqOrder ord = CompareSequence(SequencedBase, seq); if(ord == SeqInOrder) { //they are not acking anything new... - _log(NET__NET_ACKS, _L "Received an ack with no window advancement (seq %d)." __L, seq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received an ack with no window advancement (seq %d)." __L, seq); } else if(ord == SeqPast) { //they are nacking blocks going back before our buffer, wtf? - _log(NET__NET_ACKS, _L "Received an ack with backward window advancement (they gave %d, our window starts at %d). This is bad." __L, seq, SequencedBase); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received an ack with backward window advancement (they gave %d, our window starts at %d). This is bad." __L, seq, SequencedBase); } else { - _log(NET__NET_ACKS, _L "Received an ack up through sequence %d. Our base is %d." __L, seq, SequencedBase); + Log.Out(Logs::Detail, Logs::Netcode, _L "Received an ack up through sequence %d. Our base is %d." __L, seq, SequencedBase); //this is a good ack, we get to ack some blocks. seq++; //we stop at the block right after their ack, counting on the wrap of both numbers. while(SequencedBase != seq) { if(SequencedQueue.empty()) { -_log(NET__ERROR, _L "OUT OF PACKETS acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, NextSequencedSend); +Log.Out(Logs::Detail, Logs::Netcode, _L "OUT OF PACKETS acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, NextSequencedSend); SequencedBase = NextOutSeq; NextSequencedSend = 0; break; } - _log(NET__NET_ACKS, _L "Removing acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, NextSequencedSend); + Log.Out(Logs::Detail, Logs::Netcode, _L "Removing acked packet with sequence %lu. Next send is %d before this." __L, (unsigned long)SequencedBase, NextSequencedSend); //clean out the acked packet delete SequencedQueue.front(); SequencedQueue.pop_front(); @@ -1179,10 +1185,10 @@ _log(NET__ERROR, _L "OUT OF PACKETS acked packet with sequence %lu. Next send is SequencedBase++; } if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) { - _log(NET__ERROR, _L "Post-Ack on %d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Post-Ack on %d Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, seq, SequencedBase, SequencedQueue.size(), NextOutSeq); } if(NextSequencedSend > SequencedQueue.size()) { - _log(NET__ERROR, _L "Post-Ack Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); + Log.Out(Logs::Detail, Logs::Netcode, _L "Post-Ack Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size()); } } @@ -1192,7 +1198,7 @@ if(NextSequencedSend > SequencedQueue.size()) { void EQStream::SetNextAckToSend(uint32 seq) { MAcks.lock(); - _log(NET__NET_ACKS, _L "Set Next Ack To Send to %lu" __L, (unsigned long)seq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Set Next Ack To Send to %lu" __L, (unsigned long)seq); NextAckToSend=seq; MAcks.unlock(); } @@ -1200,7 +1206,7 @@ void EQStream::SetNextAckToSend(uint32 seq) void EQStream::SetLastAckSent(uint32 seq) { MAcks.lock(); - _log(NET__NET_ACKS, _L "Set Last Ack Sent to %lu" __L, (unsigned long)seq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Set Last Ack Sent to %lu" __L, (unsigned long)seq); LastAckSent=seq; MAcks.unlock(); } @@ -1213,10 +1219,10 @@ void EQStream::ProcessQueue() EQProtocolPacket *qp=nullptr; while((qp=RemoveQueue(NextInSeq))!=nullptr) { - _log(NET__DEBUG, _L "Processing Queued Packet: Seq=%d" __L, NextInSeq); + Log.Out(Logs::Detail, Logs::Netcode, _L "Processing Queued Packet: Seq=%d" __L, NextInSeq); ProcessPacket(qp); delete qp; - _log(NET__APP_TRACE, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); + Log.Out(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); } } @@ -1227,21 +1233,21 @@ EQProtocolPacket *qp=nullptr; if ((itr=PacketQueue.find(seq))!=PacketQueue.end()) { qp=itr->second; PacketQueue.erase(itr); - _log(NET__APP_TRACE, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); + Log.Out(Logs::Detail, Logs::Netcode, _L "OP_Packet Queue size=%d" __L, PacketQueue.size()); } return qp; } void EQStream::SetStreamType(EQStreamType type) { - _log(NET__NET_TRACE, _L "Changing stream type from %s to %s" __L, StreamTypeString(StreamType), StreamTypeString(type)); + Log.Out(Logs::Detail, Logs::Netcode, _L "Changing stream type from %s to %s" __L, StreamTypeString(StreamType), StreamTypeString(type)); StreamType=type; switch (StreamType) { case LoginStream: app_opcode_size=1; compressed=false; encoded=false; - _log(NET__NET_TRACE, _L "Login stream has app opcode size %d, is not compressed or encoded." __L, app_opcode_size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Login stream has app opcode size %d, is not compressed or encoded." __L, app_opcode_size); break; case ChatOrMailStream: case ChatStream: @@ -1249,7 +1255,7 @@ void EQStream::SetStreamType(EQStreamType type) app_opcode_size=1; compressed=false; encoded=true; - _log(NET__NET_TRACE, _L "Chat/Mail stream has app opcode size %d, is not compressed, and is encoded." __L, app_opcode_size); + Log.Out(Logs::Detail, Logs::Netcode, _L "Chat/Mail stream has app opcode size %d, is not compressed, and is encoded." __L, app_opcode_size); break; case ZoneStream: case WorldStream: @@ -1257,7 +1263,7 @@ void EQStream::SetStreamType(EQStreamType type) app_opcode_size=2; compressed=true; encoded=false; - _log(NET__NET_TRACE, _L "World/Zone stream has app opcode size %d, is compressed, and is not encoded." __L, app_opcode_size); + Log.Out(Logs::Detail, Logs::Netcode, _L "World/Zone stream has app opcode size %d, is compressed, and is not encoded." __L, app_opcode_size); break; } } @@ -1307,7 +1313,7 @@ EQStream::SeqOrder EQStream::CompareSequence(uint16 expected_seq , uint16 seq) void EQStream::SetState(EQStreamState state) { MState.lock(); - _log(NET__NET_TRACE, _L "Changing state from %d to %d" __L, State, state); + Log.Out(Logs::Detail, Logs::Netcode, _L "Changing state from %d to %d" __L, State, state); State=state; MState.unlock(); } @@ -1319,29 +1325,29 @@ void EQStream::CheckTimeout(uint32 now, uint32 timeout) { EQStreamState orig_state = GetState(); if (orig_state == CLOSING && !outgoing_data) { - _log(NET__NET_TRACE, _L "Out of data in closing state, disconnecting." __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Out of data in closing state, disconnecting." __L); _SendDisconnect(); SetState(DISCONNECTING); } else if (LastPacket && (now-LastPacket) > timeout) { switch(orig_state) { case CLOSING: //if we time out in the closing state, they are not acking us, just give up - _log(NET__DEBUG, _L "Timeout expired in closing state. Moving to closed state." __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout expired in closing state. Moving to closed state." __L); _SendDisconnect(); SetState(CLOSED); break; case DISCONNECTING: //we timed out waiting for them to send us the disconnect reply, just give up. - _log(NET__DEBUG, _L "Timeout expired in disconnecting state. Moving to closed state." __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout expired in disconnecting state. Moving to closed state." __L); SetState(CLOSED); break; case CLOSED: - _log(NET__DEBUG, _L "Timeout expired in closed state??" __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout expired in closed state??" __L); break; case ESTABLISHED: //we timed out during normal operation. Try to be nice about it. //we will almost certainly time out again waiting for the disconnect reply, but oh well. - _log(NET__DEBUG, _L "Timeout expired in established state. Closing connection." __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Timeout expired in established state. Closing connection." __L); _SendDisconnect(); SetState(DISCONNECTING); break; @@ -1370,11 +1376,11 @@ void EQStream::AdjustRates(uint32 average_delta) MRate.lock(); RateThreshold=RATEBASE/average_delta; DecayRate=DECAYBASE/average_delta; - _log(NET__RATES, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L, + Log.Out(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L, RateThreshold, DecayRate, average_delta); MRate.unlock(); } else { - _log(NET__RATES, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L, + Log.Out(Logs::Detail, Logs::Netcode, _L "Not adjusting data rate because avg delta over max (%d > %d)" __L, average_delta, AVERAGE_DELTA_MAX); } } else { @@ -1382,7 +1388,7 @@ void EQStream::AdjustRates(uint32 average_delta) MRate.lock(); RateThreshold=RATEBASE/average_delta; DecayRate=DECAYBASE/average_delta; - _log(NET__RATES, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L, + Log.Out(Logs::Detail, Logs::Netcode, _L "Adjusting data rate to thresh %d, decay %d based on avg delta %d" __L, RateThreshold, DecayRate, average_delta); MRate.unlock(); } @@ -1392,12 +1398,12 @@ void EQStream::AdjustRates(uint32 average_delta) void EQStream::Close() { if(HasOutgoingData()) { //there is pending data, wait for it to go out. - _log(NET__DEBUG, _L "Stream requested to Close(), but there is pending data, waiting for it." __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Stream requested to Close(), but there is pending data, waiting for it." __L); SetState(CLOSING); } else { //otherwise, we are done, we can drop immediately. _SendDisconnect(); - _log(NET__DEBUG, _L "Stream closing immediate due to Close()" __L); + Log.Out(Logs::Detail, Logs::Netcode, _L "Stream closing immediate due to Close()" __L); SetState(DISCONNECTING); } } @@ -1425,19 +1431,19 @@ EQStream::MatchState EQStream::CheckSignature(const Signature *sig) { } else if(p->opcode == sig->first_eq_opcode) { //opcode matches, check length.. if(p->size == sig->first_length) { - _log(NET__IDENT_TRACE, "%s:%d: First opcode matched 0x%x and length matched %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size); + Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x and length matched %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size); res = MatchSuccessful; } else if(sig->first_length == 0) { - _log(NET__IDENT_TRACE, "%s:%d: First opcode matched 0x%x and length (%d) is ignored", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size); + Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x and length (%d) is ignored", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size); res = MatchSuccessful; } else { //opcode matched but length did not. - _log(NET__IDENT_TRACE, "%s:%d: First opcode matched 0x%x, but length %d did not match expected %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size, sig->first_length); + Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode matched 0x%x, but length %d did not match expected %d", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), sig->first_eq_opcode, p->size, sig->first_length); res = MatchFailed; } } else { //first opcode did not match.. - _log(NET__IDENT_TRACE, "%s:%d: First opcode 0x%x did not match expected 0x%x", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), p->opcode, sig->first_eq_opcode); + Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: First opcode 0x%x did not match expected 0x%x", long2ip(GetRemoteIP()).c_str(), ntohs(GetRemotePort()), p->opcode, sig->first_eq_opcode); res = MatchFailed; } } diff --git a/common/eq_stream.h b/common/eq_stream.h index bcbb548e9..72eb53cdd 100644 --- a/common/eq_stream.h +++ b/common/eq_stream.h @@ -206,8 +206,14 @@ class EQStream : public EQStreamInterface { void init(bool resetSession=true); public: - EQStream() { init(); remote_ip = 0; remote_port = 0; State=UNESTABLISHED; StreamType=UnknownStream; compressed=true; encoded=false; app_opcode_size=2; bytes_sent=0; bytes_recv=0; create_time=Timer::GetTimeSeconds(); sessionAttempts = 0; streamactive=false; } - EQStream(sockaddr_in addr) { init(); remote_ip=addr.sin_addr.s_addr; remote_port=addr.sin_port; State=UNESTABLISHED; StreamType=UnknownStream; compressed=true; encoded=false; app_opcode_size=2; bytes_sent=0; bytes_recv=0; create_time=Timer::GetTimeSeconds(); } + EQStream() { init(); remote_ip = 0; remote_port = 0; State = UNESTABLISHED; + StreamType = UnknownStream; compressed = true; encoded = false; app_opcode_size = 2; + bytes_sent = 0; bytes_recv = 0; create_time = Timer::GetTimeSeconds(); sessionAttempts = 0; + streamactive = false; } + EQStream(sockaddr_in addr) { init(); remote_ip = addr.sin_addr.s_addr; + remote_port = addr.sin_port; State = UNESTABLISHED; StreamType = UnknownStream; + compressed = true; encoded = false; app_opcode_size = 2; bytes_sent = 0; bytes_recv = 0; + create_time = Timer::GetTimeSeconds(); } virtual ~EQStream() { RemoveData(); SetState(CLOSED); } void SetMaxLen(uint32 length) { MaxLen=length; } diff --git a/common/eq_stream_factory.cpp b/common/eq_stream_factory.cpp index 0b940c18f..f48b0f723 100644 --- a/common/eq_stream_factory.cpp +++ b/common/eq_stream_factory.cpp @@ -1,4 +1,5 @@ -#include "debug.h" +#include "global_define.h" +#include "eqemu_logsys.h" #include "eq_stream_factory.h" #ifdef _WINDOWS @@ -25,13 +26,13 @@ ThreadReturnType EQStreamFactoryReaderLoop(void *eqfs) EQStreamFactory *fs=(EQStreamFactory *)eqfs; #ifndef WIN32 - _log(COMMON__THREADS, "Starting EQStreamFactoryReaderLoop with thread ID %d", pthread_self()); + Log.Out(Logs::Detail, Logs::None, "Starting EQStreamFactoryReaderLoop with thread ID %d", pthread_self()); #endif fs->ReaderLoop(); #ifndef WIN32 - _log(COMMON__THREADS, "Ending EQStreamFactoryReaderLoop with thread ID %d", pthread_self()); + Log.Out(Logs::Detail, Logs::None, "Ending EQStreamFactoryReaderLoop with thread ID %d", pthread_self()); #endif THREAD_RETURN(nullptr); @@ -42,13 +43,13 @@ ThreadReturnType EQStreamFactoryWriterLoop(void *eqfs) EQStreamFactory *fs=(EQStreamFactory *)eqfs; #ifndef WIN32 - _log(COMMON__THREADS, "Starting EQStreamFactoryWriterLoop with thread ID %d", pthread_self()); + Log.Out(Logs::Detail, Logs::None, "Starting EQStreamFactoryWriterLoop with thread ID %d", pthread_self()); #endif fs->WriterLoop(); #ifndef WIN32 - _log(COMMON__THREADS, "Ending EQStreamFactoryWriterLoop with thread ID %d", pthread_self()); + Log.Out(Logs::Detail, Logs::None, "Ending EQStreamFactoryWriterLoop with thread ID %d", pthread_self()); #endif THREAD_RETURN(nullptr); @@ -105,8 +106,6 @@ struct sockaddr_in address; fcntl(sock, F_SETFL, O_NONBLOCK); #endif //moved these because on windows the output was delayed and causing the console window to look bad - //std::cout << "Starting factory Reader" << std::endl; - //std::cout << "Starting factory Writer" << std::endl; #ifdef _WINDOWS _beginthread(EQStreamFactoryReaderLoop,0, this); _beginthread(EQStreamFactoryWriterLoop,0, this); @@ -117,44 +116,39 @@ struct sockaddr_in address; return true; } -EQStream *EQStreamFactory::Pop() +std::shared_ptr EQStreamFactory::Pop() { -EQStream *s=nullptr; - //std::cout << "Pop():Locking MNewStreams" << std::endl; + std::shared_ptr s = nullptr; MNewStreams.lock(); if (NewStreams.size()) { - s=NewStreams.front(); + s = NewStreams.front(); NewStreams.pop(); s->PutInUse(); } MNewStreams.unlock(); - //std::cout << "Pop(): Unlocking MNewStreams" << std::endl; return s; } -void EQStreamFactory::Push(EQStream *s) +void EQStreamFactory::Push(std::shared_ptr s) { - //std::cout << "Push():Locking MNewStreams" << std::endl; MNewStreams.lock(); NewStreams.push(s); MNewStreams.unlock(); - //std::cout << "Push(): Unlocking MNewStreams" << std::endl; } void EQStreamFactory::ReaderLoop() { -fd_set readset; -std::map,EQStream *>::iterator stream_itr; -int num; -int length; -unsigned char buffer[2048]; -sockaddr_in from; -int socklen=sizeof(sockaddr_in); -timeval sleep_time; -//time_t now; + fd_set readset; + std::map, std::shared_ptr>::iterator stream_itr; + int num; + int length; + unsigned char buffer[2048]; + sockaddr_in from; + int socklen = sizeof(sockaddr_in); + timeval sleep_time; + ReaderRunning = true; - ReaderRunning=true; while(sock!=-1) { MReaderRunning.lock(); if (!ReaderRunning) @@ -185,10 +179,10 @@ timeval sleep_time; // What do we wanna do? } else { MStreams.lock(); - stream_itr=Streams.find(std::make_pair(from.sin_addr.s_addr, from.sin_port)); + stream_itr = Streams.find(std::make_pair(from.sin_addr.s_addr, from.sin_port)); if (stream_itr == Streams.end()) { if (buffer[1]==OP_SessionRequest) { - EQStream *s = new EQStream(from); + std::shared_ptr s = std::make_shared(from); s->SetStreamType(StreamType); Streams[std::make_pair(from.sin_addr.s_addr, from.sin_port)]=s; WriterWork.Signal(); @@ -199,13 +193,13 @@ timeval sleep_time; } MStreams.unlock(); } else { - EQStream *curstream = stream_itr->second; + std::shared_ptr curstream = stream_itr->second; //dont bother processing incoming packets for closed connections if(curstream->CheckClosed()) curstream = nullptr; else curstream->PutInUse(); - MStreams.unlock(); //the in use flag prevents the stream from being deleted while we are using it. + //the in use flag prevents the stream from being deleted while we are using it. if(curstream) { curstream->AddBytesRecv(length); @@ -213,6 +207,7 @@ timeval sleep_time; curstream->SetLastPacketTime(Timer::GetCurrentTime()); curstream->ReleaseFromUse(); } + MStreams.unlock(); } } } @@ -225,10 +220,10 @@ void EQStreamFactory::CheckTimeout() MStreams.lock(); unsigned long now=Timer::GetCurrentTime(); - std::map,EQStream *>::iterator stream_itr; + std::map, std::shared_ptr>::iterator stream_itr; - for(stream_itr=Streams.begin();stream_itr!=Streams.end();) { - EQStream *s = stream_itr->second; + for(stream_itr = Streams.begin(); stream_itr != Streams.end();) { + std::shared_ptr s = stream_itr->second; s->CheckTimeout(now, stream_timeout); @@ -240,11 +235,9 @@ void EQStreamFactory::CheckTimeout() //give it a little time for everybody to finish with it } else { //everybody is done, we can delete it now - //std::cout << "Removing connection" << std::endl; - std::map,EQStream *>::iterator temp=stream_itr; + std::map, std::shared_ptr>::iterator temp = stream_itr; ++stream_itr; - //let whoever has the stream outside delete it - delete temp->second; + temp->second = nullptr; Streams.erase(temp); continue; } @@ -257,21 +250,17 @@ void EQStreamFactory::CheckTimeout() void EQStreamFactory::WriterLoop() { -std::map,EQStream *>::iterator stream_itr; -bool havework=true; -std::vector wants_write; -std::vector::iterator cur,end; -bool decay=false; -uint32 stream_count; - -Timer DecayTimer(20); - - WriterRunning=true; + std::map, std::shared_ptr>::iterator stream_itr; + bool havework=true; + std::vector> wants_write; + std::vector>::iterator cur, end; + bool decay = false; + uint32 stream_count; + Timer DecayTimer(20); + WriterRunning = true; DecayTimer.Enable(); + while(sock!=-1) { - //if (!havework) { - //WriterWork.Wait(); - //} MWriterRunning.lock(); if (!WriterRunning) break; @@ -315,12 +304,10 @@ Timer DecayTimer(20); Sleep(10); MStreams.lock(); - stream_count=Streams.size(); + stream_count = Streams.size(); MStreams.unlock(); if (!stream_count) { - //std::cout << "No streams, waiting on condition" << std::endl; WriterWork.Wait(); - //std::cout << "Awake from condition, must have a stream now" << std::endl; } } } diff --git a/common/eq_stream_factory.h b/common/eq_stream_factory.h index 58fddaa40..86ffff979 100644 --- a/common/eq_stream_factory.h +++ b/common/eq_stream_factory.h @@ -2,6 +2,7 @@ #define _EQSTREAMFACTORY_H +#include #include #include @@ -26,10 +27,10 @@ class EQStreamFactory : private Timeoutable { EQStreamType StreamType; - std::queue NewStreams; + std::queue> NewStreams; Mutex MNewStreams; - std::map,EQStream *> Streams; + std::map, std::shared_ptr> Streams; Mutex MStreams; virtual void CheckTimeout(); @@ -42,8 +43,8 @@ class EQStreamFactory : private Timeoutable { EQStreamFactory(EQStreamType type, uint32 timeout = 135000) : Timeoutable(5000), stream_timeout(timeout) { ReaderRunning=false; WriterRunning=false; StreamType=type; sock=-1; } EQStreamFactory(EQStreamType type, int port, uint32 timeout = 135000); - EQStream *Pop(); - void Push(EQStream *s); + std::shared_ptr Pop(); + void Push(std::shared_ptr s); bool Open(); bool Open(unsigned long port) { Port=port; return Open(); } diff --git a/common/eq_stream_ident.cpp b/common/eq_stream_ident.cpp index 97fdd2c48..4640c75f1 100644 --- a/common/eq_stream_ident.cpp +++ b/common/eq_stream_ident.cpp @@ -1,20 +1,20 @@ -#include "debug.h" +#include "global_define.h" +#include "eqemu_logsys.h" #include "eq_stream_ident.h" #include "eq_stream_proxy.h" -#include "logsys.h" + EQStreamIdentifier::~EQStreamIdentifier() { while(!m_identified.empty()) { m_identified.front()->ReleaseFromUse(); m_identified.pop(); } - std::vector::iterator cur, end; + std::vector::iterator cur, end; cur = m_streams.begin(); end = m_streams.end(); for(; cur != end; ++cur) { - Record *r = *cur; - r->stream->ReleaseFromUse(); - delete r; + Record &r = *cur; + r.stream->ReleaseFromUse(); } std::vector::iterator curp, endp; curp = m_patches.begin(); @@ -34,54 +34,52 @@ void EQStreamIdentifier::RegisterPatch(const EQStream::Signature &sig, const cha } void EQStreamIdentifier::Process() { - std::vector::iterator cur; + std::vector::iterator cur; std::vector::iterator curp, endp; //foreach pending stream. cur = m_streams.begin(); while(cur != m_streams.end()) { - Record *r = *cur; + Record &r = *cur; //first see if this stream has expired - if(r->expire.Check(false)) { + if(r.expire.Check(false)) { //this stream has failed to match any pattern in our timeframe. - _log(NET__IDENTIFY, "Unable to identify stream from %s:%d before timeout.", long2ip(r->stream->GetRemoteIP()).c_str(), ntohs(r->stream->GetRemotePort())); - r->stream->ReleaseFromUse(); - delete r; + Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before timeout.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort())); + r.stream->ReleaseFromUse(); cur = m_streams.erase(cur); continue; } //then make sure the stream is still active //if stream hasn't finished initializing then continue; - if(r->stream->GetState() == UNESTABLISHED) + if(r.stream->GetState() == UNESTABLISHED) { ++cur; continue; } - if(r->stream->GetState() != ESTABLISHED) { + if(r.stream->GetState() != ESTABLISHED) { //the stream closed before it was identified. - _log(NET__IDENTIFY, "Unable to identify stream from %s:%d before it closed.", long2ip(r->stream->GetRemoteIP()).c_str(), ntohs(r->stream->GetRemotePort())); - switch(r->stream->GetState()) + Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d before it closed.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort())); + switch(r.stream->GetState()) { case ESTABLISHED: - _log(NET__IDENTIFY, "Stream state was Established"); + Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Established"); break; case CLOSING: - _log(NET__IDENTIFY, "Stream state was Closing"); + Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closing"); break; case DISCONNECTING: - _log(NET__IDENTIFY, "Stream state was Disconnecting"); + Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Disconnecting"); break; case CLOSED: - _log(NET__IDENTIFY, "Stream state was Closed"); + Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Closed"); break; default: - _log(NET__IDENTIFY, "Stream state was Unestablished or unknown"); + Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Stream state was Unestablished or unknown"); break; } - r->stream->ReleaseFromUse(); - delete r; + r.stream->ReleaseFromUse(); cur = m_streams.erase(cur); continue; } @@ -98,23 +96,23 @@ void EQStreamIdentifier::Process() { Patch *p = *curp; //ask the stream to see if it matches the supplied signature - EQStream::MatchState res = r->stream->CheckSignature(&p->signature); + EQStream::MatchState res = r.stream->CheckSignature(&p->signature); switch(res) { case EQStream::MatchNotReady: //the stream has not received enough packets to compare with this signature -// _log(NET__IDENT_TRACE, "%s:%d: Tried patch %s, but stream is not ready for it.", long2ip(r->stream->GetRemoteIP()).c_str(), ntohs(r->stream->GetRemotePort()), p->name.c_str()); +// Log.LogDebugType(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, but stream is not ready for it.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str()); all_ready = false; break; case EQStream::MatchSuccessful: { //yay, a match. - _log(NET__IDENTIFY, "Identified stream %s:%d with signature %s", long2ip(r->stream->GetRemoteIP()).c_str(), ntohs(r->stream->GetRemotePort()), p->name.c_str()); + Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Identified stream %s:%d with signature %s", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str()); // before we assign the eqstream to an interface, let the stream recognize it is in use and the session should not be reset any further - r->stream->SetActive(true); + r.stream->SetActive(true); //might want to do something less-specific here... some day.. - EQStreamInterface *s = new EQStreamProxy(r->stream, p->structs, p->opcodes); + EQStreamInterface *s = new EQStreamProxy(r.stream, p->structs, p->opcodes); m_identified.push(s); found_one = true; @@ -122,7 +120,7 @@ void EQStreamIdentifier::Process() { } case EQStream::MatchFailed: //do nothing... - _log(NET__IDENT_TRACE, "%s:%d: Tried patch %s, and it did not match.", long2ip(r->stream->GetRemoteIP()).c_str(), ntohs(r->stream->GetRemotePort()), p->name.c_str()); + Log.Out(Logs::General, Logs::Netcode, "[IDENT_TRACE] %s:%d: Tried patch %s, and it did not match.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort()), p->name.c_str()); break; } } @@ -130,14 +128,13 @@ void EQStreamIdentifier::Process() { //if we checked all patches and did not find a match. if(all_ready && !found_one) { //the stream cannot be identified. - _log(NET__IDENTIFY, "Unable to identify stream from %s:%d, no match found.", long2ip(r->stream->GetRemoteIP()).c_str(), ntohs(r->stream->GetRemotePort())); - r->stream->ReleaseFromUse(); + Log.Out(Logs::General, Logs::Netcode, "[IDENTIFY] Unable to identify stream from %s:%d, no match found.", long2ip(r.stream->GetRemoteIP()).c_str(), ntohs(r.stream->GetRemotePort())); + r.stream->ReleaseFromUse(); } //if we found a match, or were not able to identify it if(found_one || all_ready) { - //cannot print ip/port here. r->stream is invalid. - delete r; + //cannot print ip/port here. r.stream is invalid. cur = m_streams.erase(cur); } else { ++cur; @@ -145,8 +142,8 @@ void EQStreamIdentifier::Process() { } //end foreach stream } -void EQStreamIdentifier::AddStream(EQStream *&eqs) { - m_streams.push_back(new Record(eqs)); +void EQStreamIdentifier::AddStream(std::shared_ptr &eqs) { + m_streams.push_back(Record(eqs)); eqs = nullptr; } @@ -158,7 +155,7 @@ EQStreamInterface *EQStreamIdentifier::PopIdentified() { return(res); } -EQStreamIdentifier::Record::Record(EQStream *s) +EQStreamIdentifier::Record::Record(std::shared_ptr s) : stream(s), expire(STREAM_IDENT_WAIT_MS) { diff --git a/common/eq_stream_ident.h b/common/eq_stream_ident.h index 2020c85cf..3b6a63ed9 100644 --- a/common/eq_stream_ident.h +++ b/common/eq_stream_ident.h @@ -5,6 +5,7 @@ #include "timer.h" #include #include +#include #define STREAM_IDENT_WAIT_MS 10000 @@ -21,7 +22,7 @@ public: //main processing interface void Process(); - void AddStream(EQStream *& eqs); + void AddStream(std::shared_ptr &eqs); EQStreamInterface *PopIdentified(); protected: @@ -39,11 +40,11 @@ protected: //pending streams.. class Record { public: - Record(EQStream *s); - EQStream *stream; //we own this + Record(std::shared_ptr s); + std::shared_ptr stream; //we own this Timer expire; }; - std::vector m_streams; //we own these objects, and the streams contained in them. + std::vector m_streams; //we own these objects, and the streams contained in them. std::queue m_identified; //we own these objects }; diff --git a/common/eq_stream_intf.h b/common/eq_stream_intf.h index 9373f2262..68b8ffc96 100644 --- a/common/eq_stream_intf.h +++ b/common/eq_stream_intf.h @@ -35,7 +35,7 @@ public: virtual const uint32 GetBytesRecieved() const { return 0; } virtual const uint32 GetBytesSentPerSecond() const { return 0; } virtual const uint32 GetBytesRecvPerSecond() const { return 0; } - virtual const EQClientVersion ClientVersion() const { return EQClientUnknown; } + virtual const ClientVersion GetClientVersion() const { return ClientVersion::Unknown; } }; #endif /*EQSTREAMINTF_H_*/ diff --git a/common/eq_stream_proxy.cpp b/common/eq_stream_proxy.cpp index 20fc4ea06..117ae8c94 100644 --- a/common/eq_stream_proxy.cpp +++ b/common/eq_stream_proxy.cpp @@ -1,11 +1,11 @@ -#include "debug.h" +#include "global_define.h" #include "eq_stream_proxy.h" #include "eq_stream.h" #include "struct_strategy.h" -EQStreamProxy::EQStreamProxy(EQStream *&stream, const StructStrategy *structs, OpcodeManager **opcodes) +EQStreamProxy::EQStreamProxy(std::shared_ptr &stream, const StructStrategy *structs, OpcodeManager **opcodes) : m_stream(stream), m_structs(structs), m_opcodes(opcodes) @@ -15,16 +15,15 @@ EQStreamProxy::EQStreamProxy(EQStream *&stream, const StructStrategy *structs, O } EQStreamProxy::~EQStreamProxy() { - //delete m_stream; //released by the stream factory. } std::string EQStreamProxy::Describe() const { return(m_structs->Describe()); } -const EQClientVersion EQStreamProxy::ClientVersion() const +const ClientVersion EQStreamProxy::GetClientVersion() const { - return m_structs->ClientVersion(); + return m_structs->GetClientVersion(); } void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) { @@ -85,12 +84,6 @@ const uint32 EQStreamProxy::GetBytesRecvPerSecond() const void EQStreamProxy::ReleaseFromUse() { m_stream->ReleaseFromUse(); - - //this is so ugly, but I cant think of a better way to deal with - //it right now... - if(!m_stream->IsInUse()) { - delete this; - } } void EQStreamProxy::RemoveData() { diff --git a/common/eq_stream_proxy.h b/common/eq_stream_proxy.h index 34ea3a9fc..93ad1d884 100644 --- a/common/eq_stream_proxy.h +++ b/common/eq_stream_proxy.h @@ -4,8 +4,9 @@ #include "types.h" #include "eq_stream_intf.h" +#include "eq_stream.h" +#include -class EQStream; class StructStrategy; class OpcodeManager; class EQApplicationPacket; @@ -13,7 +14,7 @@ class EQApplicationPacket; class EQStreamProxy : public EQStreamInterface { public: //takes ownership of the stream. - EQStreamProxy(EQStream *&stream, const StructStrategy *structs, OpcodeManager **opcodes); + EQStreamProxy(std::shared_ptr &stream, const StructStrategy *structs, OpcodeManager **opcodes); virtual ~EQStreamProxy(); //EQStreamInterface: @@ -27,7 +28,7 @@ public: virtual void RemoveData(); virtual bool CheckState(EQStreamState state); virtual std::string Describe() const; - virtual const EQClientVersion ClientVersion() const; + virtual const ClientVersion GetClientVersion() const; virtual const uint32 GetBytesSent() const; virtual const uint32 GetBytesRecieved() const; @@ -35,7 +36,7 @@ public: virtual const uint32 GetBytesRecvPerSecond() const; protected: - EQStream *const m_stream; //we own this stream object. + std::shared_ptr const m_stream; //we own this stream object. const StructStrategy *const m_structs; //we do not own this object. //this is a pointer to a pointer to make it less likely that a packet will //reference an invalid opcode manager when they are being reloaded. diff --git a/common/eqdb.cpp b/common/eqdb.cpp index 03746b0d4..2c912afba 100644 --- a/common/eqdb.cpp +++ b/common/eqdb.cpp @@ -15,7 +15,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "debug.h" +#include "global_define.h" #include "eqdb.h" #include "database.h" #include diff --git a/common/eqdb_res.cpp b/common/eqdb_res.cpp index f34229a1f..11d90459d 100644 --- a/common/eqdb_res.cpp +++ b/common/eqdb_res.cpp @@ -15,7 +15,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "debug.h" +#include "global_define.h" #include "eqdb_res.h" #include diff --git a/common/eqemu_config.cpp b/common/eqemu_config.cpp index eb62abad2..50ce54248 100644 --- a/common/eqemu_config.cpp +++ b/common/eqemu_config.cpp @@ -16,7 +16,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "../common/debug.h" +#include "../common/global_define.h" #include "eqemu_config.h" #include "misc_functions.h" @@ -277,10 +277,6 @@ void EQEmuConfig::do_files(TiXmlElement *ele) if (text) { OpCodesFile = text; } - text = ParseTextBlock(ele, "logsettings", true); - if (text) { - LogSettingsFile = text; - } text = ParseTextBlock(ele, "eqtime", true); if (text) { EQTimeFile = text; @@ -438,9 +434,6 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const if (var_name == "EQTimeFile") { return (EQTimeFile); } - if (var_name == "LogSettingsFile") { - return (LogSettingsFile); - } if (var_name == "MapDir") { return (MapDir); } @@ -512,7 +505,6 @@ void EQEmuConfig::Dump() const std::cout << "SpellsFile = " << SpellsFile << std::endl; std::cout << "OpCodesFile = " << OpCodesFile << std::endl; std::cout << "EQTimeFile = " << EQTimeFile << std::endl; - std::cout << "LogSettingsFile = " << LogSettingsFile << std::endl; std::cout << "MapDir = " << MapDir << std::endl; std::cout << "QuestDir = " << QuestDir << std::endl; std::cout << "PluginDir = " << PluginDir << std::endl; diff --git a/common/eqemu_config.h b/common/eqemu_config.h index 8fb1e0a5b..06894ee4a 100644 --- a/common/eqemu_config.h +++ b/common/eqemu_config.h @@ -86,7 +86,6 @@ class EQEmuConfig : public XMLParser std::string SpellsFile; std::string OpCodesFile; std::string EQTimeFile; - std::string LogSettingsFile; // From std::string MapDir; @@ -162,7 +161,6 @@ class EQEmuConfig : public XMLParser SpellsFile = "spells_us.txt"; OpCodesFile = "opcodes.conf"; EQTimeFile = "eqtime.cfg"; - LogSettingsFile = "log.ini"; // Dirs MapDir = "Maps"; QuestDir = "quests"; diff --git a/common/eqemu_error.cpp b/common/eqemu_error.cpp deleted file mode 100644 index ff9a7bbd6..000000000 --- a/common/eqemu_error.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifdef _WINDOWS -#include -#endif -#include "eqemu_error.h" -#include "linked_list.h" -#include "mutex.h" -#include "misc_functions.h" -#include -#include -#ifdef _WINDOWS - #include -#endif - -void UpdateWindowTitle(char* iNewTitle = 0); -void CatchSignal(int sig_num); - -const char* EQEMuErrorText[EQEMuError_MaxErrorID] = { "ErrorID# 0, No Error", - "MySQL Error #1405 or #2001 means your mysql server rejected the username and password you presented it.", - "MySQL Error #2003 means you were unable to connect to the mysql server.", - "MySQL Error #2005 means you there are too many connections on the mysql server. The server is overloaded.", - "MySQL Error #2007 means you the server is out of memory. The server is overloaded.", - }; - -LinkedList* EQEMuErrorList; -Mutex* MEQEMuErrorList; -AutoDelete< LinkedList > ADEQEMuErrorList(&EQEMuErrorList); -AutoDelete ADMEQEMuErrorList(&MEQEMuErrorList); - -const char* GetErrorText(uint32 iError) { - if (iError >= EQEMuError_MaxErrorID) - return "ErrorID# out of range"; - else - return EQEMuErrorText[iError]; -} - -void AddEQEMuError(eEQEMuError iError, bool iExitNow) { - if (!iError) - return; - if (!EQEMuErrorList) { - EQEMuErrorList = new LinkedList; - MEQEMuErrorList = new Mutex; - } - LockMutex lock(MEQEMuErrorList); - - LinkedListIterator iterator(*EQEMuErrorList); - iterator.Reset(); - while (iterator.MoreElements()) { - if (iterator.GetData()[0] == 1) { -//Umm... this gets a big WTF... -// if (*((uint32*) iterator.GetData()[1]) == iError) -//not sure whats going on, using a character as a pointer.... - if (*((eEQEMuError*) &(iterator.GetData()[1])) == iError) - return; - } - iterator.Advance(); - } - - char* tmp = new char[6]; - tmp[0] = 1; - tmp[5] = 0; - *((uint32*) &tmp[1]) = iError; - EQEMuErrorList->Append(tmp); - - if (iExitNow) - CatchSignal(2); -} - -void AddEQEMuError(char* iError, bool iExitNow) { - if (!iError) - return; - if (!EQEMuErrorList) { - EQEMuErrorList = new LinkedList; - MEQEMuErrorList = new Mutex; - } - LockMutex lock(MEQEMuErrorList); - char* tmp = strcpy(new char[strlen(iError) + 1], iError); - EQEMuErrorList->Append(tmp); - - if (iExitNow) - CatchSignal(2); -} - -uint32 CheckEQEMuError() { - if (!EQEMuErrorList) - return 0; - uint32 ret = 0; - char* tmp = 0; - bool HeaderPrinted = false; - LockMutex lock(MEQEMuErrorList); - - while ((tmp = EQEMuErrorList->Pop() )) { - if (!HeaderPrinted) { - fprintf(stdout, "===============================\nRuntime errors:\n\n"); - HeaderPrinted = true; - } - if (tmp[0] == 1) { - fprintf(stdout, "%s\n", GetErrorText(*((uint32*) &tmp[1]))); - fprintf(stdout, "For more information on this error, visit http://www.eqemu.net/eqemuerror.php?id=%u\n\n", *((uint32*) &tmp[1])); - } - else { - fprintf(stdout, "%s\n\n", tmp); - } - safe_delete(tmp); - ret++; - } - return ret; -} - -void CheckEQEMuErrorAndPause() { -#ifdef _WINDOWS - if (CheckEQEMuError()) { - fprintf(stdout, "Hit any key to exit\n"); - UpdateWindowTitle("Error"); - getch(); - } -#endif -} - diff --git a/common/eqemu_error.h b/common/eqemu_error.h deleted file mode 100644 index ffc5d69ed..000000000 --- a/common/eqemu_error.h +++ /dev/null @@ -1,36 +0,0 @@ -/* EQEMu: Everquest Server Emulator - Copyright (C) 2001-2006 EQEMu Development Team (http://eqemulator.net) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY except by those people which sell it, which - are required to give you total support for your newly bought product; - without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef EQEMuError_H -#define EQEMuError_H - -#include "../common/types.h" - -enum eEQEMuError { EQEMuError_NoError, - EQEMuError_Mysql_1405, - EQEMuError_Mysql_2003, - EQEMuError_Mysql_2005, - EQEMuError_Mysql_2007, - EQEMuError_MaxErrorID }; - -void AddEQEMuError(eEQEMuError iError, bool iExitNow = false); -void AddEQEMuError(char* iError, bool iExitNow = false); -uint32 CheckEQEMuError(); -void CheckEQEMuErrorAndPause(); - -#endif - diff --git a/common/eqemu_logsys.cpp b/common/eqemu_logsys.cpp new file mode 100644 index 000000000..36176c399 --- /dev/null +++ b/common/eqemu_logsys.cpp @@ -0,0 +1,350 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + +#include "eqemu_logsys.h" +#include "platform.h" +#include "string_util.h" +#include "database.h" +#include "misc.h" + +#include +#include +#include +#include +#include +#include + +std::ofstream process_log; + +#ifdef _WINDOWS + #include + #include + #include + #include + #include + #include +#else + #include + #include +#endif + +/* Linux ANSI console color defines */ +#define LC_RESET "\033[0m" +#define LC_BLACK "\033[30m" /* Black */ +#define LC_RED "\033[31m" /* Red */ +#define LC_GREEN "\033[32m" /* Green */ +#define LC_YELLOW "\033[33m" /* Yellow */ +#define LC_BLUE "\033[34m" /* Blue */ +#define LC_MAGENTA "\033[35m" /* Magenta */ +#define LC_CYAN "\033[36m" /* Cyan */ +#define LC_WHITE "\033[37m" /* White */ + +namespace Console { + enum Color { + Black = 0, + Blue = 1, + Green = 2, + Cyan = 3, + Red = 4, + Magenta = 5, + Brown = 6, + LightGray = 7, + DarkGray = 8, + LightBlue = 9, + LightGreen = 10, + LightCyan = 11, + LightRed = 12, + LightMagenta = 13, + Yellow = 14, + White = 15 + }; +} + +EQEmuLogSys::EQEmuLogSys() +{ + on_log_gmsay_hook = [](uint16 log_type, const std::string&) {}; + bool file_logs_enabled = false; + int log_platform = 0; +} + +EQEmuLogSys::~EQEmuLogSys() +{ +} + +void EQEmuLogSys::LoadLogSettingsDefaults() +{ + /* Get Executable platform currently running this code (Zone/World/etc) */ + log_platform = GetExecutablePlatformInt(); + + /* Zero out Array */ + memset(log_settings, 0, sizeof(LogSettings) * Logs::LogCategory::MaxCategoryID); + + /* Set Defaults */ + log_settings[Logs::World_Server].log_to_console = Logs::General; + log_settings[Logs::Zone_Server].log_to_console = Logs::General; + log_settings[Logs::QS_Server].log_to_console = Logs::General; + log_settings[Logs::UCS_Server].log_to_console = Logs::General; + log_settings[Logs::Crash].log_to_console = Logs::General; + log_settings[Logs::MySQLError].log_to_console = Logs::General; + + /* Declare process file names for log writing + If there is no process_file_name declared, no log file will be written, simply + */ + if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformWorld) + platform_file_name = "world"; + else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformQueryServ) + platform_file_name = "query_server"; + else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) + platform_file_name = "zone"; + else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformUCS) + platform_file_name = "ucs"; + else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin) + platform_file_name = "login"; + else if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformLogin) + platform_file_name = "launcher"; +} + +std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::string &in_message) +{ + std::string category_string; + if (log_category > 0 && Logs::LogCategoryName[log_category]) + category_string = StringFormat("[%s] ", Logs::LogCategoryName[log_category]); + return StringFormat("%s%s", category_string.c_str(), in_message.c_str()); +} + +void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message) +{ + /* Check if category enabled for process */ + if (log_settings[log_category].log_to_gmsay == 0) + return; + + /* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash */ + if (log_category == Logs::LogCategory::Netcode) + return; + + /* Make sure the message inbound is at a debug level we're set at */ + if (log_settings[log_category].log_to_gmsay < debug_level) + return; + + /* Check to see if the process that actually ran this is zone */ + if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) + on_log_gmsay_hook(log_category, message); +} + +void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message) +{ + if (log_category == Logs::Crash) { + char time_stamp[80]; + EQEmuLogSys::SetCurrentTimeStamp(time_stamp); + std::ofstream crash_log; + EQEmuLogSys::MakeDirectory("logs/crashes"); + crash_log.open(StringFormat("logs/crashes/crash_%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out); + crash_log << time_stamp << " " << message << "\n"; + crash_log.close(); + } + + /* Check if category enabled for process */ + if (log_settings[log_category].log_to_file == 0) + return; + + /* Make sure the message inbound is at a debug level we're set at */ + if (log_settings[log_category].log_to_file < debug_level) + return; + + char time_stamp[80]; + EQEmuLogSys::SetCurrentTimeStamp(time_stamp); + + if (process_log) + process_log << time_stamp << " " << message << std::endl; +} + +uint16 EQEmuLogSys::GetWindowsConsoleColorFromCategory(uint16 log_category) { + switch (log_category) { + case Logs::Status: + case Logs::Normal: + return Console::Color::Yellow; + case Logs::MySQLError: + case Logs::Error: + return Console::Color::LightRed; + case Logs::MySQLQuery: + case Logs::Debug: + return Console::Color::LightGreen; + case Logs::Quests: + return Console::Color::LightCyan; + case Logs::Commands: + case Logs::Mercenaries: + return Console::Color::LightMagenta; + case Logs::Crash: + return Console::Color::LightRed; + default: + return Console::Color::Yellow; + } +} + +std::string EQEmuLogSys::GetLinuxConsoleColorFromCategory(uint16 log_category) { + switch (log_category) { + case Logs::Status: + case Logs::Normal: + return LC_YELLOW; + case Logs::MySQLError: + case Logs::Error: + return LC_RED; + case Logs::MySQLQuery: + case Logs::Debug: + return LC_GREEN; + case Logs::Quests: + return LC_CYAN; + case Logs::Commands: + case Logs::Mercenaries: + return LC_MAGENTA; + case Logs::Crash: + return LC_RED; + default: + return LC_YELLOW; + } +} + +uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category) { + switch (log_category) { + case Logs::Status: + case Logs::Normal: + return 15; /* Yellow */ + case Logs::MySQLError: + case Logs::Error: + return 13; /* Red */ + case Logs::MySQLQuery: + case Logs::Debug: + return 14; /* Light Green */ + case Logs::Quests: + return 258; /* Light Cyan */ + case Logs::Commands: + case Logs::Mercenaries: + return 5; /* Light Purple */ + case Logs::Crash: + return 13; /* Red */ + default: + return 15; /* Yellow */ + } +} + +void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message) +{ + /* Check if category enabled for process */ + if (log_settings[log_category].log_to_console == 0) + return; + + /* Make sure the message inbound is at a debug level we're set at */ + if (log_settings[log_category].log_to_console < debug_level) + return; + + #ifdef _WINDOWS + HANDLE console_handle; + console_handle = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_FONT_INFOEX info = { 0 }; + info.cbSize = sizeof(info); + info.dwFontSize.Y = 12; // leave X as zero + info.FontWeight = FW_NORMAL; + wcscpy(info.FaceName, L"Lucida Console"); + SetCurrentConsoleFontEx(console_handle, NULL, &info); + SetConsoleTextAttribute(console_handle, EQEmuLogSys::GetWindowsConsoleColorFromCategory(log_category)); + std::cout << message << "\n"; + SetConsoleTextAttribute(console_handle, Console::Color::White); + #else + std::cout << EQEmuLogSys::GetLinuxConsoleColorFromCategory(log_category) << message << LC_RESET << std::endl; + #endif +} + +void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...) +{ + const bool log_to_console = log_settings[log_category].log_to_console > 0; + const bool log_to_file = log_settings[log_category].log_to_file > 0; + const bool log_to_gmsay = log_settings[log_category].log_to_gmsay > 0; + const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay; + + if (nothing_to_log) return; + + va_list args; + va_start(args, message); + std::string output_message = vStringFormat(message.c_str(), args); + va_end(args); + + std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, output_message); + + if (log_to_console) EQEmuLogSys::ProcessConsoleMessage(debug_level, log_category, output_debug_message); + if (log_to_gmsay) EQEmuLogSys::ProcessGMSay(debug_level, log_category, output_debug_message); + if (log_to_file) EQEmuLogSys::ProcessLogWrite(debug_level, log_category, output_debug_message); +} + +void EQEmuLogSys::SetCurrentTimeStamp(char* time_stamp) +{ + time_t raw_time; + struct tm * time_info; + time(&raw_time); + time_info = localtime(&raw_time); + strftime(time_stamp, 80, "[%m-%d-%Y :: %H:%M:%S]", time_info); +} + +void EQEmuLogSys::MakeDirectory(const std::string &directory_name) +{ +#ifdef _WINDOWS + struct _stat st; + if (_stat(directory_name.c_str(), &st) == 0) // exists + return; + _mkdir(directory_name.c_str()); +#else + struct stat st; + if (stat(directory_name.c_str(), &st) == 0) // exists + return; + mkdir(directory_name.c_str(), 0755); +#endif +} + +void EQEmuLogSys::CloseFileLogs() +{ + if (process_log.is_open()) { + process_log.close(); + } +} + +void EQEmuLogSys::StartFileLogs(const std::string &log_name) +{ + EQEmuLogSys::CloseFileLogs(); + + /* When loading settings, we must have been given a reason in category based logging to output to a file in order to even create or open one... */ + if (file_logs_enabled == false) + return; + + if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone) { + if (!log_name.empty()) + platform_file_name = log_name; + + if (platform_file_name.empty()) + return; + + EQEmuLogSys::Out(Logs::General, Logs::Status, "Starting File Log 'logs/%s_%i.log'", platform_file_name.c_str(), getpid()); + EQEmuLogSys::MakeDirectory("logs/zone"); + process_log.open(StringFormat("logs/zone/%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out); + } else { + if (platform_file_name.empty()) + return; + + EQEmuLogSys::Out(Logs::General, Logs::Status, "Starting File Log 'logs/%s_%i.log'", platform_file_name.c_str(), getpid()); + process_log.open(StringFormat("logs/%s_%i.log", platform_file_name.c_str(), getpid()), std::ios_base::app | std::ios_base::out); + } +} diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h new file mode 100644 index 000000000..a99b3b439 --- /dev/null +++ b/common/eqemu_logsys.h @@ -0,0 +1,204 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2015 EQEMu Development Team (http://eqemulator.net) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY except by those people which sell it, which + are required to give you total support for your newly bought product; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef EQEMU_LOGSYS_H +#define EQEMU_LOGSYS_H + +#include +#include +#include +#include + +#include "types.h" + +namespace Logs { + enum DebugLevel { + General = 1, /* 1 - Low-Level general debugging, useful info on single line */ + Moderate, /* 2 - Informational based, used in functions, when particular things load */ + Detail /* 3 - Use this for extreme detail in logging, usually in extreme debugging in the stack or interprocess communication */ + }; + + /* + If you add to this, make sure you update LogCategoryName + NOTE: Only add to the bottom of the enum because that is the type ID assignment + */ + + enum LogCategory { + None = 0, + AA, + AI, + Aggro, + Attack, + Client_Server_Packet, + Combat, + Commands, + Crash, + Debug, + Doors, + Error, + Guilds, + Inventory, + Launcher, + Netcode, + Normal, + Object, + Pathing, + QS_Server, + Quests, + Rules, + Skills, + Spawns, + Spells, + Status, + TCP_Connection, + Tasks, + Tradeskills, + Trading, + Tribute, + UCS_Server, + WebInterface_Server, + World_Server, + Zone_Server, + MySQLError, + MySQLQuery, + Mercenaries, + QuestDebug, + Server_Client_Packet, + Client_Server_Packet_Unhandled, + Server_Client_Packet_With_Dump, + Client_Server_Packet_With_Dump, + MaxCategoryID /* Don't Remove this*/ + }; + + /* If you add to this, make sure you update LogCategory */ + static const char* LogCategoryName[LogCategory::MaxCategoryID] = { + "", + "AA", + "AI", + "Aggro", + "Attack", + "Packet :: Client -> Server", + "Combat", + "Commands", + "Crash", + "Debug", + "Doors", + "Error", + "Guilds", + "Inventory", + "Launcher", + "Netcode", + "Normal", + "Object", + "Pathing", + "QS Server", + "Quests", + "Rules", + "Skills", + "Spawns", + "Spells", + "Status", + "TCP Connection", + "Tasks", + "Tradeskills", + "Trading", + "Tribute", + "UCS Server", + "WebInterface Server", + "World Server", + "Zone Server", + "MySQL Error", + "MySQL Query", + "Mercenaries", + "Quest Debug", + "Packet :: Server -> Client", + "Packet :: Client -> Server Unhandled", + "Packet :: Server -> Client (Dump)", + "Packet :: Client -> Server (Dump)", + }; +} + +class EQEmuLogSys { +public: + EQEmuLogSys(); + ~EQEmuLogSys(); + + void CloseFileLogs(); /* Close File Logs wherever necessary, either at zone shutdown or entire process shutdown for everything else. This should be handled on deconstructor but to be safe we use it anyways. */ + void LoadLogSettingsDefaults(); /* Initializes log_settings and sets some defaults if DB is not present */ + void MakeDirectory(const std::string &directory_name); /* Platform independent way of performing a MakeDirectory based on name */ + /* + The one and only Logging function that uses a debug level as a parameter, as well as a log_category + log_category - defined in Logs::LogCategory::[] + log_category name resolution works by passing the enum int ID to Logs::LogCategoryName[category_id] + + Example: EQEmuLogSys::Out(Logs::General, Logs::Guilds, "This guild has no leader present"); + - This would pipe the same category and debug level to all output formats, but the internal memory reference of log_settings would + be checked against to see if that piped output is set to actually process it for the category and debug level + */ + void Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...); + void SetCurrentTimeStamp(char* time_stamp); /* Used in file logs to prepend a timestamp entry for logs */ + void StartFileLogs(const std::string &log_name = ""); /* Used to declare the processes file log and to keep it open for later use */ + + /* + LogSettings Struct + + This struct is the master reference for all settings for each category, and for each output + + log_to_file[category_id] = [1-3] - Sets debug level for category to output to file + log_to_console[category_id] = [1-3] - Sets debug level for category to output to console + log_to_gmsay[category_id] = [1-3] - Sets debug level for category to output to gmsay + */ + + struct LogSettings { + uint8 log_to_file; + uint8 log_to_console; + uint8 log_to_gmsay; + uint8 is_category_enabled; /* When any log output in a category > 0, set this to 1 as (Enabled) */ + }; + + /* Internally used memory reference for all log settings per category. + These are loaded via DB and have defaults loaded in LoadLogSettingsDefaults. + Database loaded via Database::LoadLogSettings(log_settings) + */ + LogSettings log_settings[Logs::LogCategory::MaxCategoryID]; + + bool file_logs_enabled; /* Set when log settings are loaded to determine if keeping a file open is necessary */ + + int log_platform; /* Sets Executable platform (Zone/World/UCS) etc. */ + + std::string platform_file_name; /* File name used in writing logs */ + + uint16 GetGMSayColorFromCategory(uint16 log_category); /* GMSay Client Message colors mapped by category */ + + void OnLogHookCallBackZone(std::function f) { on_log_gmsay_hook = f; } + +private: + std::function on_log_gmsay_hook; /* Callback pointer to zone process for hooking logs to zone using GMSay */ + std::string FormatOutMessageString(uint16 log_category, const std::string &in_message); /* Formats log messages like '[Category] This is a log message' */ + std::string GetLinuxConsoleColorFromCategory(uint16 log_category); /* Linux console color messages mapped by category */ + + uint16 GetWindowsConsoleColorFromCategory(uint16 log_category); /* Windows console color messages mapped by category */ + + void ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message); /* ProcessConsoleMessage called via Log.Out */ + void ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message); /* ProcessGMSay called via Log.Out */ + void ProcessLogWrite(uint16 debug_level, uint16 log_category, const std::string &message); /* ProcessLogWrite called via Log.Out */ +}; + +extern EQEmuLogSys Log; + +#endif diff --git a/common/eqtime.cpp b/common/eqtime.cpp index 7e1eb9f5d..79301a28f 100644 --- a/common/eqtime.cpp +++ b/common/eqtime.cpp @@ -17,7 +17,8 @@ */ #include -#include "../common/debug.h" +#include "../common/global_define.h" +#include "../common/eqemu_logsys.h" #include "../common/eqtime.h" #include "../common/eq_packet_structs.h" #include @@ -140,11 +141,10 @@ bool EQTime::saveFile(const char *filename) of.open(filename); if(!of) { - LogFile->write(EQEMuLog::Error, "EQTime::saveFile failed: Unable to open file '%s'", filename); + Log.Out(Logs::General, Logs::Error, "EQTime::saveFile failed: Unable to open file '%s'", filename); return false; } //Enable for debugging - //std::cout << "SAVE: day=" << (long)eqTime.start_eqtime.day << ";hour=" << (long)eqTime.start_eqtime.hour << ";min=" << (long)eqTime.start_eqtime.minute << ";mon=" << (long)eqTime.start_eqtime.month << ";yr=" << eqTime.start_eqtime.year << ";timet=" << eqTime.start_realtime << std::endl; of << EQT_VERSION << std::endl; of << (long)eqTime.start_eqtime.day << std::endl; of << (long)eqTime.start_eqtime.hour << std::endl; @@ -164,14 +164,14 @@ bool EQTime::loadFile(const char *filename) in.open(filename); if(!in) { - LogFile->write(EQEMuLog::Error, "Could not load EQTime file %s", filename); + Log.Out(Logs::General, Logs::Error, "Could not load EQTime file %s", filename); return false; } in >> version; in.ignore(80, '\n'); if(version != EQT_VERSION) { - LogFile->write(EQEMuLog::Error, "'%s' is NOT a valid EQTime file. File version is %i, EQTime version is %i", filename, version, EQT_VERSION); + Log.Out(Logs::General, Logs::Error, "'%s' is NOT a valid EQTime file. File version is %i, EQTime version is %i", filename, version, EQT_VERSION); return false; } //in >> eqTime.start_eqtime.day; @@ -194,7 +194,6 @@ bool EQTime::loadFile(const char *filename) in.ignore(80, '\n'); in >> eqTime.start_realtime; //Enable for debugging... - //std::cout << "LOAD: day=" << (long)eqTime.start_eqtime.day << ";hour=" << (long)eqTime.start_eqtime.hour << ";min=" << (long)eqTime.start_eqtime.minute << ";mon=" << (long)eqTime.start_eqtime.month << ";yr=" << eqTime.start_eqtime.year << ";timet=" << eqTime.start_realtime << std::endl; in.close(); return true; } diff --git a/common/extprofile.cpp b/common/extprofile.cpp index 0ea3fb7a1..f29ec1e6e 100644 --- a/common/extprofile.cpp +++ b/common/extprofile.cpp @@ -16,7 +16,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "debug.h" +#include "global_define.h" #include "extprofile.h" //Set defaults in the extended profile... diff --git a/common/glm/glm/CMakeLists.txt b/common/glm/glm/CMakeLists.txt index 79a46074a..9dbe11cab 100644 --- a/common/glm/glm/CMakeLists.txt +++ b/common/glm/glm/CMakeLists.txt @@ -30,11 +30,13 @@ source_group("GTX Files" FILES ${GTX_HEADER}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) -add_executable(${NAME} ${ROOT_TEXT} - ${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER} - ${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER} - ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER} - ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER}) +if(GLM_TEST_ENABLE) + add_executable(${NAME} ${ROOT_TEXT} + ${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER} + ${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER} + ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER} + ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER}) +endif(GLM_TEST_ENABLE) #add_library(glm STATIC glm.cpp) #add_library(glm_shared SHARED glm.cpp) diff --git a/common/glm/glm/common.hpp b/common/glm/glm/common.hpp index 2d787dde0..8f1c3171e 100644 --- a/common/glm/glm/common.hpp +++ b/common/glm/glm/common.hpp @@ -12,6 +12,10 @@ /// The above copyright notice and this permission notice shall be included in /// all copies or substantial portions of the Software. /// +/// Restrictions: +/// By making use of the Software for military purposes, you choose to make +/// a Bunny unhappy. +/// /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -26,9 +30,6 @@ /// @author Christophe Riccio /////////////////////////////////////////////////////////////////////////////////// -#ifndef GLM_COMMON_INCLUDED -#define GLM_COMMON_INCLUDED +#pragma once #include "detail/func_common.hpp" - -#endif//GLM_COMMON_INCLUDED diff --git a/common/glm/glm/detail/_features.hpp b/common/glm/glm/detail/_features.hpp index 1c7fe8c96..51eda577c 100644 --- a/common/glm/glm/detail/_features.hpp +++ b/common/glm/glm/detail/_features.hpp @@ -12,6 +12,10 @@ /// The above copyright notice and this permission notice shall be included in /// all copies or substantial portions of the Software. /// +/// Restrictions: +/// By making use of the Software for military purposes, you choose to make +/// a Bunny unhappy. +/// /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,13 +25,12 @@ /// THE SOFTWARE. /// /// @ref core -/// @file glm/core/_features.hpp +/// @file glm/detail/_features.hpp /// @date 2013-02-20 / 2013-02-20 /// @author Christophe Riccio /////////////////////////////////////////////////////////////////////////////////// -#ifndef glm_core_features -#define glm_core_features +#pragma once // #define GLM_CXX98_EXCEPTIONS // #define GLM_CXX98_RTTI @@ -281,7 +284,7 @@ # define GLM_CXX11_STATIC_ASSERT # endif -#elif(GLM_COMPILER & GLM_COMPILER_CLANG) +#elif(GLM_COMPILER & (GLM_COMPILER_APPLE_CLANG | GLM_COMPILER_LLVM)) # if(__has_feature(cxx_exceptions)) # define GLM_CXX98_EXCEPTIONS # endif @@ -422,6 +425,4 @@ # define GLM_CXX11_VARIADIC_TEMPLATES # endif -#endif//(GLM_COMPILER & GLM_COMPILER_CLANG) - -#endif//glm_core_features +#endif//(GLM_COMPILER & (GLM_COMPILER_APPLE_CLANG | GLM_COMPILER_LLVM)) diff --git a/common/glm/glm/detail/_fixes.hpp b/common/glm/glm/detail/_fixes.hpp index ce13bb1be..6185dcbb7 100644 --- a/common/glm/glm/detail/_fixes.hpp +++ b/common/glm/glm/detail/_fixes.hpp @@ -12,6 +12,10 @@ /// The above copyright notice and this permission notice shall be included in /// all copies or substantial portions of the Software. /// +/// Restrictions: +/// By making use of the Software for military purposes, you choose to make +/// a Bunny unhappy. +/// /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,7 +25,7 @@ /// THE SOFTWARE. /// /// @ref core -/// @file glm/core/_fixes.hpp +/// @file glm/detail/_fixes.hpp /// @date 2011-02-21 / 2011-11-22 /// @author Christophe Riccio /////////////////////////////////////////////////////////////////////////////////// diff --git a/common/glm/glm/detail/_noise.hpp b/common/glm/glm/detail/_noise.hpp index e366e7c38..94c835d54 100644 --- a/common/glm/glm/detail/_noise.hpp +++ b/common/glm/glm/detail/_noise.hpp @@ -12,6 +12,10 @@ /// The above copyright notice and this permission notice shall be included in /// all copies or substantial portions of the Software. /// +/// Restrictions: +/// By making use of the Software for military purposes, you choose to make +/// a Bunny unhappy. +/// /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -26,8 +30,12 @@ /// @author Christophe Riccio /////////////////////////////////////////////////////////////////////////////////// -#ifndef GLM_DETAIL_NOISE_INCLUDED -#define GLM_DETAIL_NOISE_INCLUDED +#pragma once + +#include "../vec2.hpp" +#include "../vec3.hpp" +#include "../vec4.hpp" +#include "../common.hpp" namespace glm{ namespace detail @@ -75,19 +83,19 @@ namespace detail } template - GLM_FUNC_QUALIFIER detail::tvec2 taylorInvSqrt(detail::tvec2 const & r) + GLM_FUNC_QUALIFIER tvec2 taylorInvSqrt(tvec2 const & r) { return T(1.79284291400159) - T(0.85373472095314) * r; } template - GLM_FUNC_QUALIFIER detail::tvec3 taylorInvSqrt(detail::tvec3 const & r) + GLM_FUNC_QUALIFIER tvec3 taylorInvSqrt(tvec3 const & r) { return T(1.79284291400159) - T(0.85373472095314) * r; } template - GLM_FUNC_QUALIFIER detail::tvec4 taylorInvSqrt(detail::tvec4 const & r) + GLM_FUNC_QUALIFIER tvec4 taylorInvSqrt(tvec4 const & r) { return T(1.79284291400159) - T(0.85373472095314) * r; } @@ -100,19 +108,19 @@ namespace detail */ template - GLM_FUNC_QUALIFIER detail::tvec2 fade(detail::tvec2 const & t) + GLM_FUNC_QUALIFIER tvec2 fade(tvec2 const & t) { return (t * t * t) * (t * (t * T(6) - T(15)) + T(10)); } template - GLM_FUNC_QUALIFIER detail::tvec3 fade(detail::tvec3 const & t) + GLM_FUNC_QUALIFIER tvec3 fade(tvec3 const & t) { return (t * t * t) * (t * (t * T(6) - T(15)) + T(10)); } template - GLM_FUNC_QUALIFIER detail::tvec4 fade(detail::tvec4 const & t) + GLM_FUNC_QUALIFIER tvec4 fade(tvec4 const & t) { return (t * t * t) * (t * (t * T(6) - T(15)) + T(10)); } @@ -126,5 +134,3 @@ namespace detail }//namespace detail }//namespace glm -#endif//GLM_DETAIL_NOISE_INCLUDED - diff --git a/common/glm/glm/detail/_swizzle.hpp b/common/glm/glm/detail/_swizzle.hpp index 407ffb49c..3edf6cb23 100644 --- a/common/glm/glm/detail/_swizzle.hpp +++ b/common/glm/glm/detail/_swizzle.hpp @@ -12,6 +12,10 @@ /// The above copyright notice and this permission notice shall be included in /// all copies or substantial portions of the Software. /// +/// Restrictions: +/// By making use of the Software for military purposes, you choose to make +/// a Bunny unhappy. +/// /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,13 +25,12 @@ /// THE SOFTWARE. /// /// @ref core -/// @file glm/core/_swizzle.hpp +/// @file glm/detail/_swizzle.hpp /// @date 2006-04-20 / 2011-02-16 /// @author Christophe Riccio /////////////////////////////////////////////////////////////////////////////////// -#ifndef glm_core_swizzle -#define glm_core_swizzle +#pragma once namespace glm{ namespace detail @@ -139,20 +142,15 @@ namespace detail GLM_FUNC_QUALIFIER value_type& operator[] (size_t i) { -#ifndef __CUDA_ARCH__ - static -#endif - const int offset_dst[4] = { E0, E1, E2, E3 }; + const int offset_dst[4] = { E0, E1, E2, E3 }; return this->elem(offset_dst[i]); } GLM_FUNC_QUALIFIER value_type operator[] (size_t i) const { -#ifndef __CUDA_ARCH__ - static -#endif - const int offset_dst[4] = { E0, E1, E2, E3 }; + const int offset_dst[4] = { E0, E1, E2, E3 }; return this->elem(offset_dst[i]); } + protected: template GLM_FUNC_QUALIFIER void _apply_op(const VecType& that, T op) @@ -180,16 +178,13 @@ namespace detail GLM_FUNC_QUALIFIER value_type operator[] (size_t i) const { -#ifndef __CUDA_ARCH__ - static -#endif - const int offset_dst[4] = { E0, E1, E2, E3 }; + const int offset_dst[4] = { E0, E1, E2, E3 }; return this->elem(offset_dst[i]); } }; template - struct _swizzle : public _swizzle_base2 + struct _swizzle : public _swizzle_base2 { typedef _swizzle_base2 base_type; @@ -339,502 +334,500 @@ namespace glm } #define _GLM_SWIZZLE2_2_MEMBERS(T, P, V, E0,E1) \ - struct { _swizzle<2, T, P, V, 0,0,-1,-2> E0 ## E0; }; \ - struct { _swizzle<2, T, P, V, 0,1,-1,-2> E0 ## E1; }; \ - struct { _swizzle<2, T, P, V, 1,0,-1,-2> E1 ## E0; }; \ - struct { _swizzle<2, T, P, V, 1,1,-1,-2> E1 ## E1; }; + struct { detail::_swizzle<2, T, P, V, 0,0,-1,-2> E0 ## E0; }; \ + struct { detail::_swizzle<2, T, P, V, 0,1,-1,-2> E0 ## E1; }; \ + struct { detail::_swizzle<2, T, P, V, 1,0,-1,-2> E1 ## E0; }; \ + struct { detail::_swizzle<2, T, P, V, 1,1,-1,-2> E1 ## E1; }; #define _GLM_SWIZZLE2_3_MEMBERS(T, P, V, E0,E1) \ - struct { _swizzle<3,T, P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ - struct { _swizzle<3,T, P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ - struct { _swizzle<3,T, P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ - struct { _swizzle<3,T, P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ - struct { _swizzle<3,T, P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ - struct { _swizzle<3,T, P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ - struct { _swizzle<3,T, P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ - struct { _swizzle<3,T, P, V, 1,1,1,-1> E1 ## E1 ## E1; }; + struct { detail::_swizzle<3,T, P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T, P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T, P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T, P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<3,T, P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T, P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T, P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T, P, V, 1,1,1,-1> E1 ## E1 ## E1; }; #define _GLM_SWIZZLE2_4_MEMBERS(T, P, V, E0,E1) \ - struct { _swizzle<4,T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ - struct { _swizzle<4,T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ - struct { _swizzle<4,T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ - struct { _swizzle<4,T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ - struct { _swizzle<4,T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ - struct { _swizzle<4,T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ - struct { _swizzle<4,T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ - struct { _swizzle<4,T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ - struct { _swizzle<4,T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ - struct { _swizzle<4,T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ - struct { _swizzle<4,T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ - struct { _swizzle<4,T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ - struct { _swizzle<4,T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ - struct { _swizzle<4,T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ - struct { _swizzle<4,T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ - struct { _swizzle<4,T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; + struct { detail::_swizzle<4,T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; #define _GLM_SWIZZLE3_2_MEMBERS(T, P, V, E0,E1,E2) \ - struct { _swizzle<2,T, P, V, 0,0,-1,-2> E0 ## E0; }; \ - struct { _swizzle<2,T, P, V, 0,1,-1,-2> E0 ## E1; }; \ - struct { _swizzle<2,T, P, V, 0,2,-1,-2> E0 ## E2; }; \ - struct { _swizzle<2,T, P, V, 1,0,-1,-2> E1 ## E0; }; \ - struct { _swizzle<2,T, P, V, 1,1,-1,-2> E1 ## E1; }; \ - struct { _swizzle<2,T, P, V, 1,2,-1,-2> E1 ## E2; }; \ - struct { _swizzle<2,T, P, V, 2,0,-1,-2> E2 ## E0; }; \ - struct { _swizzle<2,T, P, V, 2,1,-1,-2> E2 ## E1; }; \ - struct { _swizzle<2,T, P, V, 2,2,-1,-2> E2 ## E2; }; + struct { detail::_swizzle<2,T, P, V, 0,0,-1,-2> E0 ## E0; }; \ + struct { detail::_swizzle<2,T, P, V, 0,1,-1,-2> E0 ## E1; }; \ + struct { detail::_swizzle<2,T, P, V, 0,2,-1,-2> E0 ## E2; }; \ + struct { detail::_swizzle<2,T, P, V, 1,0,-1,-2> E1 ## E0; }; \ + struct { detail::_swizzle<2,T, P, V, 1,1,-1,-2> E1 ## E1; }; \ + struct { detail::_swizzle<2,T, P, V, 1,2,-1,-2> E1 ## E2; }; \ + struct { detail::_swizzle<2,T, P, V, 2,0,-1,-2> E2 ## E0; }; \ + struct { detail::_swizzle<2,T, P, V, 2,1,-1,-2> E2 ## E1; }; \ + struct { detail::_swizzle<2,T, P, V, 2,2,-1,-2> E2 ## E2; }; #define _GLM_SWIZZLE3_3_MEMBERS(T, P, V ,E0,E1,E2) \ - struct { _swizzle<3,T,P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ - struct { _swizzle<3,T,P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ - struct { _swizzle<3,T,P, V, 0,0,2,-1> E0 ## E0 ## E2; }; \ - struct { _swizzle<3,T,P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ - struct { _swizzle<3,T,P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ - struct { _swizzle<3,T,P, V, 0,1,2,-1> E0 ## E1 ## E2; }; \ - struct { _swizzle<3,T,P, V, 0,2,0,-1> E0 ## E2 ## E0; }; \ - struct { _swizzle<3,T,P, V, 0,2,1,-1> E0 ## E2 ## E1; }; \ - struct { _swizzle<3,T,P, V, 0,2,2,-1> E0 ## E2 ## E2; }; \ - struct { _swizzle<3,T,P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ - struct { _swizzle<3,T,P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ - struct { _swizzle<3,T,P, V, 1,0,2,-1> E1 ## E0 ## E2; }; \ - struct { _swizzle<3,T,P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ - struct { _swizzle<3,T,P, V, 1,1,1,-1> E1 ## E1 ## E1; }; \ - struct { _swizzle<3,T,P, V, 1,1,2,-1> E1 ## E1 ## E2; }; \ - struct { _swizzle<3,T,P, V, 1,2,0,-1> E1 ## E2 ## E0; }; \ - struct { _swizzle<3,T,P, V, 1,2,1,-1> E1 ## E2 ## E1; }; \ - struct { _swizzle<3,T,P, V, 1,2,2,-1> E1 ## E2 ## E2; }; \ - struct { _swizzle<3,T,P, V, 2,0,0,-1> E2 ## E0 ## E0; }; \ - struct { _swizzle<3,T,P, V, 2,0,1,-1> E2 ## E0 ## E1; }; \ - struct { _swizzle<3,T,P, V, 2,0,2,-1> E2 ## E0 ## E2; }; \ - struct { _swizzle<3,T,P, V, 2,1,0,-1> E2 ## E1 ## E0; }; \ - struct { _swizzle<3,T,P, V, 2,1,1,-1> E2 ## E1 ## E1; }; \ - struct { _swizzle<3,T,P, V, 2,1,2,-1> E2 ## E1 ## E2; }; \ - struct { _swizzle<3,T,P, V, 2,2,0,-1> E2 ## E2 ## E0; }; \ - struct { _swizzle<3,T,P, V, 2,2,1,-1> E2 ## E2 ## E1; }; \ - struct { _swizzle<3,T,P, V, 2,2,2,-1> E2 ## E2 ## E2; }; + struct { detail::_swizzle<3,T,P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 0,0,2,-1> E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 0,1,2,-1> E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 0,2,0,-1> E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 0,2,1,-1> E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 0,2,2,-1> E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 1,0,2,-1> E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 1,1,1,-1> E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 1,1,2,-1> E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 1,2,0,-1> E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 1,2,1,-1> E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 1,2,2,-1> E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 2,0,0,-1> E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 2,0,1,-1> E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 2,0,2,-1> E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 2,1,0,-1> E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 2,1,1,-1> E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 2,1,2,-1> E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 2,2,0,-1> E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 2,2,1,-1> E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 2,2,2,-1> E2 ## E2 ## E2; }; #define _GLM_SWIZZLE3_4_MEMBERS(T, P, V, E0,E1,E2) \ - struct { _swizzle<4,T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ - struct { _swizzle<4,T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ - struct { _swizzle<4,T, P, V, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \ - struct { _swizzle<4,T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ - struct { _swizzle<4,T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ - struct { _swizzle<4,T, P, V, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \ - struct { _swizzle<4,T, P, V, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \ - struct { _swizzle<4,T, P, V, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \ - struct { _swizzle<4,T, P, V, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \ - struct { _swizzle<4,T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ - struct { _swizzle<4,T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ - struct { _swizzle<4,T, P, V, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \ - struct { _swizzle<4,T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ - struct { _swizzle<4,T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ - struct { _swizzle<4,T, P, V, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \ - struct { _swizzle<4,T, P, V, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \ - struct { _swizzle<4,T, P, V, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \ - struct { _swizzle<4,T, P, V, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \ - struct { _swizzle<4,T, P, V, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \ - struct { _swizzle<4,T, P, V, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \ - struct { _swizzle<4,T, P, V, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \ - struct { _swizzle<4,T, P, V, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \ - struct { _swizzle<4,T, P, V, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \ - struct { _swizzle<4,T, P, V, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \ - struct { _swizzle<4,T, P, V, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \ - struct { _swizzle<4,T, P, V, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \ - struct { _swizzle<4,T, P, V, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \ - struct { _swizzle<4,T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ - struct { _swizzle<4,T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ - struct { _swizzle<4,T, P, V, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \ - struct { _swizzle<4,T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ - struct { _swizzle<4,T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ - struct { _swizzle<4,T, P, V, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \ - struct { _swizzle<4,T, P, V, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \ - struct { _swizzle<4,T, P, V, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \ - struct { _swizzle<4,T, P, V, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \ - struct { _swizzle<4,T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ - struct { _swizzle<4,T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ - struct { _swizzle<4,T, P, V, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \ - struct { _swizzle<4,T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ - struct { _swizzle<4,T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \ - struct { _swizzle<4,T, P, V, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \ - struct { _swizzle<4,T, P, V, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \ - struct { _swizzle<4,T, P, V, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \ - struct { _swizzle<4,T, P, V, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \ - struct { _swizzle<4,T, P, V, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \ - struct { _swizzle<4,T, P, V, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \ - struct { _swizzle<4,T, P, V, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \ - struct { _swizzle<4,T, P, V, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \ - struct { _swizzle<4,T, P, V, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \ - struct { _swizzle<4,T, P, V, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \ - struct { _swizzle<4,T, P, V, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \ - struct { _swizzle<4,T, P, V, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \ - struct { _swizzle<4,T, P, V, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \ - struct { _swizzle<4,T, P, V, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \ - struct { _swizzle<4,T, P, V, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \ - struct { _swizzle<4,T, P, V, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \ - struct { _swizzle<4,T, P, V, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \ - struct { _swizzle<4,T, P, V, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \ - struct { _swizzle<4,T, P, V, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \ - struct { _swizzle<4,T, P, V, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \ - struct { _swizzle<4,T, P, V, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \ - struct { _swizzle<4,T, P, V, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \ - struct { _swizzle<4,T, P, V, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \ - struct { _swizzle<4,T, P, V, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \ - struct { _swizzle<4,T, P, V, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \ - struct { _swizzle<4,T, P, V, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \ - struct { _swizzle<4,T, P, V, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \ - struct { _swizzle<4,T, P, V, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \ - struct { _swizzle<4,T, P, V, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \ - struct { _swizzle<4,T, P, V, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \ - struct { _swizzle<4,T, P, V, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \ - struct { _swizzle<4,T, P, V, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \ - struct { _swizzle<4,T, P, V, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \ - struct { _swizzle<4,T, P, V, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \ - struct { _swizzle<4,T, P, V, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \ - struct { _swizzle<4,T, P, V, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \ - struct { _swizzle<4,T, P, V, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \ - struct { _swizzle<4,T, P, V, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \ - struct { _swizzle<4,T, P, V, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \ - struct { _swizzle<4,T, P, V, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; + struct { detail::_swizzle<4,T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4,T, P, V, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; #define _GLM_SWIZZLE4_2_MEMBERS(T, P, V, E0,E1,E2,E3) \ - struct { _swizzle<2,T, P, V, 0,0,-1,-2> E0 ## E0; }; \ - struct { _swizzle<2,T, P, V, 0,1,-1,-2> E0 ## E1; }; \ - struct { _swizzle<2,T, P, V, 0,2,-1,-2> E0 ## E2; }; \ - struct { _swizzle<2,T, P, V, 0,3,-1,-2> E0 ## E3; }; \ - struct { _swizzle<2,T, P, V, 1,0,-1,-2> E1 ## E0; }; \ - struct { _swizzle<2,T, P, V, 1,1,-1,-2> E1 ## E1; }; \ - struct { _swizzle<2,T, P, V, 1,2,-1,-2> E1 ## E2; }; \ - struct { _swizzle<2,T, P, V, 1,3,-1,-2> E1 ## E3; }; \ - struct { _swizzle<2,T, P, V, 2,0,-1,-2> E2 ## E0; }; \ - struct { _swizzle<2,T, P, V, 2,1,-1,-2> E2 ## E1; }; \ - struct { _swizzle<2,T, P, V, 2,2,-1,-2> E2 ## E2; }; \ - struct { _swizzle<2,T, P, V, 2,3,-1,-2> E2 ## E3; }; \ - struct { _swizzle<2,T, P, V, 3,0,-1,-2> E3 ## E0; }; \ - struct { _swizzle<2,T, P, V, 3,1,-1,-2> E3 ## E1; }; \ - struct { _swizzle<2,T, P, V, 3,2,-1,-2> E3 ## E2; }; \ - struct { _swizzle<2,T, P, V, 3,3,-1,-2> E3 ## E3; }; + struct { detail::_swizzle<2,T, P, V, 0,0,-1,-2> E0 ## E0; }; \ + struct { detail::_swizzle<2,T, P, V, 0,1,-1,-2> E0 ## E1; }; \ + struct { detail::_swizzle<2,T, P, V, 0,2,-1,-2> E0 ## E2; }; \ + struct { detail::_swizzle<2,T, P, V, 0,3,-1,-2> E0 ## E3; }; \ + struct { detail::_swizzle<2,T, P, V, 1,0,-1,-2> E1 ## E0; }; \ + struct { detail::_swizzle<2,T, P, V, 1,1,-1,-2> E1 ## E1; }; \ + struct { detail::_swizzle<2,T, P, V, 1,2,-1,-2> E1 ## E2; }; \ + struct { detail::_swizzle<2,T, P, V, 1,3,-1,-2> E1 ## E3; }; \ + struct { detail::_swizzle<2,T, P, V, 2,0,-1,-2> E2 ## E0; }; \ + struct { detail::_swizzle<2,T, P, V, 2,1,-1,-2> E2 ## E1; }; \ + struct { detail::_swizzle<2,T, P, V, 2,2,-1,-2> E2 ## E2; }; \ + struct { detail::_swizzle<2,T, P, V, 2,3,-1,-2> E2 ## E3; }; \ + struct { detail::_swizzle<2,T, P, V, 3,0,-1,-2> E3 ## E0; }; \ + struct { detail::_swizzle<2,T, P, V, 3,1,-1,-2> E3 ## E1; }; \ + struct { detail::_swizzle<2,T, P, V, 3,2,-1,-2> E3 ## E2; }; \ + struct { detail::_swizzle<2,T, P, V, 3,3,-1,-2> E3 ## E3; }; #define _GLM_SWIZZLE4_3_MEMBERS(T,P, V, E0,E1,E2,E3) \ - struct { _swizzle<3,T,P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ - struct { _swizzle<3,T,P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ - struct { _swizzle<3,T,P, V, 0,0,2,-1> E0 ## E0 ## E2; }; \ - struct { _swizzle<3,T,P, V, 0,0,3,-1> E0 ## E0 ## E3; }; \ - struct { _swizzle<3,T,P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ - struct { _swizzle<3,T,P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ - struct { _swizzle<3,T,P, V, 0,1,2,-1> E0 ## E1 ## E2; }; \ - struct { _swizzle<3,T,P, V, 0,1,3,-1> E0 ## E1 ## E3; }; \ - struct { _swizzle<3,T,P, V, 0,2,0,-1> E0 ## E2 ## E0; }; \ - struct { _swizzle<3,T,P, V, 0,2,1,-1> E0 ## E2 ## E1; }; \ - struct { _swizzle<3,T,P, V, 0,2,2,-1> E0 ## E2 ## E2; }; \ - struct { _swizzle<3,T,P, V, 0,2,3,-1> E0 ## E2 ## E3; }; \ - struct { _swizzle<3,T,P, V, 0,3,0,-1> E0 ## E3 ## E0; }; \ - struct { _swizzle<3,T,P, V, 0,3,1,-1> E0 ## E3 ## E1; }; \ - struct { _swizzle<3,T,P, V, 0,3,2,-1> E0 ## E3 ## E2; }; \ - struct { _swizzle<3,T,P, V, 0,3,3,-1> E0 ## E3 ## E3; }; \ - struct { _swizzle<3,T,P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ - struct { _swizzle<3,T,P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ - struct { _swizzle<3,T,P, V, 1,0,2,-1> E1 ## E0 ## E2; }; \ - struct { _swizzle<3,T,P, V, 1,0,3,-1> E1 ## E0 ## E3; }; \ - struct { _swizzle<3,T,P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ - struct { _swizzle<3,T,P, V, 1,1,1,-1> E1 ## E1 ## E1; }; \ - struct { _swizzle<3,T,P, V, 1,1,2,-1> E1 ## E1 ## E2; }; \ - struct { _swizzle<3,T,P, V, 1,1,3,-1> E1 ## E1 ## E3; }; \ - struct { _swizzle<3,T,P, V, 1,2,0,-1> E1 ## E2 ## E0; }; \ - struct { _swizzle<3,T,P, V, 1,2,1,-1> E1 ## E2 ## E1; }; \ - struct { _swizzle<3,T,P, V, 1,2,2,-1> E1 ## E2 ## E2; }; \ - struct { _swizzle<3,T,P, V, 1,2,3,-1> E1 ## E2 ## E3; }; \ - struct { _swizzle<3,T,P, V, 1,3,0,-1> E1 ## E3 ## E0; }; \ - struct { _swizzle<3,T,P, V, 1,3,1,-1> E1 ## E3 ## E1; }; \ - struct { _swizzle<3,T,P, V, 1,3,2,-1> E1 ## E3 ## E2; }; \ - struct { _swizzle<3,T,P, V, 1,3,3,-1> E1 ## E3 ## E3; }; \ - struct { _swizzle<3,T,P, V, 2,0,0,-1> E2 ## E0 ## E0; }; \ - struct { _swizzle<3,T,P, V, 2,0,1,-1> E2 ## E0 ## E1; }; \ - struct { _swizzle<3,T,P, V, 2,0,2,-1> E2 ## E0 ## E2; }; \ - struct { _swizzle<3,T,P, V, 2,0,3,-1> E2 ## E0 ## E3; }; \ - struct { _swizzle<3,T,P, V, 2,1,0,-1> E2 ## E1 ## E0; }; \ - struct { _swizzle<3,T,P, V, 2,1,1,-1> E2 ## E1 ## E1; }; \ - struct { _swizzle<3,T,P, V, 2,1,2,-1> E2 ## E1 ## E2; }; \ - struct { _swizzle<3,T,P, V, 2,1,3,-1> E2 ## E1 ## E3; }; \ - struct { _swizzle<3,T,P, V, 2,2,0,-1> E2 ## E2 ## E0; }; \ - struct { _swizzle<3,T,P, V, 2,2,1,-1> E2 ## E2 ## E1; }; \ - struct { _swizzle<3,T,P, V, 2,2,2,-1> E2 ## E2 ## E2; }; \ - struct { _swizzle<3,T,P, V, 2,2,3,-1> E2 ## E2 ## E3; }; \ - struct { _swizzle<3,T,P, V, 2,3,0,-1> E2 ## E3 ## E0; }; \ - struct { _swizzle<3,T,P, V, 2,3,1,-1> E2 ## E3 ## E1; }; \ - struct { _swizzle<3,T,P, V, 2,3,2,-1> E2 ## E3 ## E2; }; \ - struct { _swizzle<3,T,P, V, 2,3,3,-1> E2 ## E3 ## E3; }; \ - struct { _swizzle<3,T,P, V, 3,0,0,-1> E3 ## E0 ## E0; }; \ - struct { _swizzle<3,T,P, V, 3,0,1,-1> E3 ## E0 ## E1; }; \ - struct { _swizzle<3,T,P, V, 3,0,2,-1> E3 ## E0 ## E2; }; \ - struct { _swizzle<3,T,P, V, 3,0,3,-1> E3 ## E0 ## E3; }; \ - struct { _swizzle<3,T,P, V, 3,1,0,-1> E3 ## E1 ## E0; }; \ - struct { _swizzle<3,T,P, V, 3,1,1,-1> E3 ## E1 ## E1; }; \ - struct { _swizzle<3,T,P, V, 3,1,2,-1> E3 ## E1 ## E2; }; \ - struct { _swizzle<3,T,P, V, 3,1,3,-1> E3 ## E1 ## E3; }; \ - struct { _swizzle<3,T,P, V, 3,2,0,-1> E3 ## E2 ## E0; }; \ - struct { _swizzle<3,T,P, V, 3,2,1,-1> E3 ## E2 ## E1; }; \ - struct { _swizzle<3,T,P, V, 3,2,2,-1> E3 ## E2 ## E2; }; \ - struct { _swizzle<3,T,P, V, 3,2,3,-1> E3 ## E2 ## E3; }; \ - struct { _swizzle<3,T,P, V, 3,3,0,-1> E3 ## E3 ## E0; }; \ - struct { _swizzle<3,T,P, V, 3,3,1,-1> E3 ## E3 ## E1; }; \ - struct { _swizzle<3,T,P, V, 3,3,2,-1> E3 ## E3 ## E2; }; \ - struct { _swizzle<3,T,P, V, 3,3,3,-1> E3 ## E3 ## E3; }; + struct { detail::_swizzle<3,T,P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 0,0,2,-1> E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 0,0,3,-1> E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 0,1,2,-1> E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 0,1,3,-1> E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 0,2,0,-1> E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 0,2,1,-1> E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 0,2,2,-1> E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 0,2,3,-1> E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 0,3,0,-1> E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 0,3,1,-1> E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 0,3,2,-1> E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 0,3,3,-1> E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 1,0,2,-1> E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 1,0,3,-1> E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 1,1,1,-1> E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 1,1,2,-1> E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 1,1,3,-1> E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 1,2,0,-1> E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 1,2,1,-1> E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 1,2,2,-1> E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 1,2,3,-1> E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 1,3,0,-1> E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 1,3,1,-1> E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 1,3,2,-1> E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 1,3,3,-1> E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 2,0,0,-1> E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 2,0,1,-1> E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 2,0,2,-1> E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 2,0,3,-1> E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 2,1,0,-1> E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 2,1,1,-1> E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 2,1,2,-1> E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 2,1,3,-1> E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 2,2,0,-1> E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 2,2,1,-1> E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 2,2,2,-1> E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 2,2,3,-1> E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 2,3,0,-1> E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 2,3,1,-1> E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 2,3,2,-1> E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 2,3,3,-1> E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 3,0,0,-1> E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 3,0,1,-1> E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 3,0,2,-1> E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 3,0,3,-1> E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 3,1,0,-1> E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 3,1,1,-1> E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 3,1,2,-1> E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 3,1,3,-1> E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 3,2,0,-1> E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 3,2,1,-1> E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 3,2,2,-1> E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 3,2,3,-1> E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<3,T,P, V, 3,3,0,-1> E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<3,T,P, V, 3,3,1,-1> E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<3,T,P, V, 3,3,2,-1> E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<3,T,P, V, 3,3,3,-1> E3 ## E3 ## E3; }; #define _GLM_SWIZZLE4_4_MEMBERS(T, P, V, E0,E1,E2,E3) \ - struct { _swizzle<4, T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,0,0,3> E0 ## E0 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,0,1,3> E0 ## E0 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,0,2,3> E0 ## E0 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,0,3,0> E0 ## E0 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,0,3,1> E0 ## E0 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,0,3,2> E0 ## E0 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,0,3,3> E0 ## E0 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,1,0,3> E0 ## E1 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,1,1,3> E0 ## E1 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,1,2,3> E0 ## E1 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,1,3,0> E0 ## E1 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,1,3,1> E0 ## E1 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,1,3,2> E0 ## E1 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,1,3,3> E0 ## E1 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,2,0,3> E0 ## E2 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,2,1,3> E0 ## E2 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,2,2,3> E0 ## E2 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,2,3,0> E0 ## E2 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,2,3,1> E0 ## E2 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,2,3,2> E0 ## E2 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,2,3,3> E0 ## E2 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,3,0,0> E0 ## E3 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,3,0,1> E0 ## E3 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,3,0,2> E0 ## E3 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,3,0,3> E0 ## E3 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,3,1,0> E0 ## E3 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,3,1,1> E0 ## E3 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,3,1,2> E0 ## E3 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,3,1,3> E0 ## E3 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,3,2,0> E0 ## E3 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,3,2,1> E0 ## E3 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,3,2,2> E0 ## E3 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,3,2,3> E0 ## E3 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 0,3,3,0> E0 ## E3 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 0,3,3,1> E0 ## E3 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 0,3,3,2> E0 ## E3 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 0,3,3,3> E0 ## E3 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,0,0,3> E1 ## E0 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,0,1,3> E1 ## E0 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,0,2,3> E1 ## E0 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,0,3,0> E1 ## E0 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,0,3,1> E1 ## E0 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,0,3,2> E1 ## E0 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,0,3,3> E1 ## E0 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,1,0,3> E1 ## E1 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,1,1,3> E1 ## E1 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,1,2,3> E1 ## E1 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,1,3,0> E1 ## E1 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,1,3,1> E1 ## E1 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,1,3,2> E1 ## E1 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,1,3,3> E1 ## E1 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,2,0,3> E1 ## E2 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,2,1,3> E1 ## E2 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,2,2,3> E1 ## E2 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,2,3,0> E1 ## E2 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,2,3,1> E1 ## E2 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,2,3,2> E1 ## E2 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,2,3,3> E1 ## E2 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,3,0,0> E1 ## E3 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,3,0,1> E1 ## E3 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,3,0,2> E1 ## E3 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,3,0,3> E1 ## E3 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,3,1,0> E1 ## E3 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,3,1,1> E1 ## E3 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,3,1,2> E1 ## E3 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,3,1,3> E1 ## E3 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,3,2,0> E1 ## E3 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,3,2,1> E1 ## E3 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,3,2,2> E1 ## E3 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,3,2,3> E1 ## E3 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 1,3,3,0> E1 ## E3 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 1,3,3,1> E1 ## E3 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 1,3,3,2> E1 ## E3 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 1,3,3,3> E1 ## E3 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,0,0,3> E2 ## E0 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,0,1,3> E2 ## E0 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,0,2,3> E2 ## E0 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,0,3,0> E2 ## E0 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,0,3,1> E2 ## E0 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,0,3,2> E2 ## E0 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,0,3,3> E2 ## E0 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,1,0,3> E2 ## E1 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,1,1,3> E2 ## E1 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,1,2,3> E2 ## E1 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,1,3,0> E2 ## E1 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,1,3,1> E2 ## E1 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,1,3,2> E2 ## E1 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,1,3,3> E2 ## E1 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,2,0,3> E2 ## E2 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,2,1,3> E2 ## E2 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,2,2,3> E2 ## E2 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,2,3,0> E2 ## E2 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,2,3,1> E2 ## E2 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,2,3,2> E2 ## E2 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,2,3,3> E2 ## E2 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,3,0,0> E2 ## E3 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,3,0,1> E2 ## E3 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,3,0,2> E2 ## E3 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,3,0,3> E2 ## E3 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,3,1,0> E2 ## E3 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,3,1,1> E2 ## E3 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,3,1,2> E2 ## E3 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,3,1,3> E2 ## E3 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,3,2,0> E2 ## E3 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,3,2,1> E2 ## E3 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,3,2,2> E2 ## E3 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,3,2,3> E2 ## E3 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 2,3,3,0> E2 ## E3 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 2,3,3,1> E2 ## E3 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 2,3,3,2> E2 ## E3 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 2,3,3,3> E2 ## E3 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,0,0,0> E3 ## E0 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,0,0,1> E3 ## E0 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,0,0,2> E3 ## E0 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,0,0,3> E3 ## E0 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,0,1,0> E3 ## E0 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,0,1,1> E3 ## E0 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,0,1,2> E3 ## E0 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,0,1,3> E3 ## E0 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,0,2,0> E3 ## E0 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,0,2,1> E3 ## E0 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,0,2,2> E3 ## E0 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,0,2,3> E3 ## E0 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,0,3,0> E3 ## E0 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,0,3,1> E3 ## E0 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,0,3,2> E3 ## E0 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,0,3,3> E3 ## E0 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,1,0,0> E3 ## E1 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,1,0,1> E3 ## E1 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,1,0,2> E3 ## E1 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,1,0,3> E3 ## E1 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,1,1,0> E3 ## E1 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,1,1,1> E3 ## E1 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,1,1,2> E3 ## E1 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,1,1,3> E3 ## E1 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,1,2,0> E3 ## E1 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,1,2,1> E3 ## E1 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,1,2,2> E3 ## E1 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,1,2,3> E3 ## E1 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,1,3,0> E3 ## E1 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,1,3,1> E3 ## E1 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,1,3,2> E3 ## E1 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,1,3,3> E3 ## E1 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,2,0,0> E3 ## E2 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,2,0,1> E3 ## E2 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,2,0,2> E3 ## E2 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,2,0,3> E3 ## E2 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,2,1,0> E3 ## E2 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,2,1,1> E3 ## E2 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,2,1,2> E3 ## E2 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,2,1,3> E3 ## E2 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,2,2,0> E3 ## E2 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,2,2,1> E3 ## E2 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,2,2,2> E3 ## E2 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,2,2,3> E3 ## E2 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,2,3,0> E3 ## E2 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,2,3,1> E3 ## E2 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,2,3,2> E3 ## E2 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,2,3,3> E3 ## E2 ## E3 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,3,0,0> E3 ## E3 ## E0 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,3,0,1> E3 ## E3 ## E0 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,3,0,2> E3 ## E3 ## E0 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,3,0,3> E3 ## E3 ## E0 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,3,1,0> E3 ## E3 ## E1 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,3,1,1> E3 ## E3 ## E1 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,3,1,2> E3 ## E3 ## E1 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,3,1,3> E3 ## E3 ## E1 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,3,2,0> E3 ## E3 ## E2 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,3,2,1> E3 ## E3 ## E2 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,3,2,2> E3 ## E3 ## E2 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,3,2,3> E3 ## E3 ## E2 ## E3; }; \ - struct { _swizzle<4, T, P, V, 3,3,3,0> E3 ## E3 ## E3 ## E0; }; \ - struct { _swizzle<4, T, P, V, 3,3,3,1> E3 ## E3 ## E3 ## E1; }; \ - struct { _swizzle<4, T, P, V, 3,3,3,2> E3 ## E3 ## E3 ## E2; }; \ - struct { _swizzle<4, T, P, V, 3,3,3,3> E3 ## E3 ## E3 ## E3; }; - -#endif//glm_core_swizzle + struct { detail::_swizzle<4, T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,0,3> E0 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,1,3> E0 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,2,3> E0 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,3,0> E0 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,3,1> E0 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,3,2> E0 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,0,3,3> E0 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,0,3> E0 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,1,3> E0 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,2,3> E0 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,3,0> E0 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,3,1> E0 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,3,2> E0 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,1,3,3> E0 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,0,3> E0 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,1,3> E0 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,2,3> E0 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,3,0> E0 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,3,1> E0 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,3,2> E0 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,2,3,3> E0 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,0,0> E0 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,0,1> E0 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,0,2> E0 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,0,3> E0 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,1,0> E0 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,1,1> E0 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,1,2> E0 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,1,3> E0 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,2,0> E0 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,2,1> E0 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,2,2> E0 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,2,3> E0 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,3,0> E0 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,3,1> E0 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,3,2> E0 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 0,3,3,3> E0 ## E3 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,0,3> E1 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,1,3> E1 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,2,3> E1 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,3,0> E1 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,3,1> E1 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,3,2> E1 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,0,3,3> E1 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,0,3> E1 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,1,3> E1 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,2,3> E1 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,3,0> E1 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,3,1> E1 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,3,2> E1 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,1,3,3> E1 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,0,3> E1 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,1,3> E1 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,2,3> E1 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,3,0> E1 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,3,1> E1 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,3,2> E1 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,2,3,3> E1 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,0,0> E1 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,0,1> E1 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,0,2> E1 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,0,3> E1 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,1,0> E1 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,1,1> E1 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,1,2> E1 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,1,3> E1 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,2,0> E1 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,2,1> E1 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,2,2> E1 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,2,3> E1 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,3,0> E1 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,3,1> E1 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,3,2> E1 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 1,3,3,3> E1 ## E3 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,0,3> E2 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,1,3> E2 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,2,3> E2 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,3,0> E2 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,3,1> E2 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,3,2> E2 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,0,3,3> E2 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,0,3> E2 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,1,3> E2 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,2,3> E2 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,3,0> E2 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,3,1> E2 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,3,2> E2 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,1,3,3> E2 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,0,3> E2 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,1,3> E2 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,2,3> E2 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,3,0> E2 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,3,1> E2 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,3,2> E2 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,2,3,3> E2 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,0,0> E2 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,0,1> E2 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,0,2> E2 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,0,3> E2 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,1,0> E2 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,1,1> E2 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,1,2> E2 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,1,3> E2 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,2,0> E2 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,2,1> E2 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,2,2> E2 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,2,3> E2 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,3,0> E2 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,3,1> E2 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,3,2> E2 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 2,3,3,3> E2 ## E3 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,0,0> E3 ## E0 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,0,1> E3 ## E0 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,0,2> E3 ## E0 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,0,3> E3 ## E0 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,1,0> E3 ## E0 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,1,1> E3 ## E0 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,1,2> E3 ## E0 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,1,3> E3 ## E0 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,2,0> E3 ## E0 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,2,1> E3 ## E0 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,2,2> E3 ## E0 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,2,3> E3 ## E0 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,3,0> E3 ## E0 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,3,1> E3 ## E0 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,3,2> E3 ## E0 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,0,3,3> E3 ## E0 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,0,0> E3 ## E1 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,0,1> E3 ## E1 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,0,2> E3 ## E1 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,0,3> E3 ## E1 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,1,0> E3 ## E1 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,1,1> E3 ## E1 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,1,2> E3 ## E1 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,1,3> E3 ## E1 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,2,0> E3 ## E1 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,2,1> E3 ## E1 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,2,2> E3 ## E1 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,2,3> E3 ## E1 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,3,0> E3 ## E1 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,3,1> E3 ## E1 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,3,2> E3 ## E1 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,1,3,3> E3 ## E1 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,0,0> E3 ## E2 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,0,1> E3 ## E2 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,0,2> E3 ## E2 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,0,3> E3 ## E2 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,1,0> E3 ## E2 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,1,1> E3 ## E2 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,1,2> E3 ## E2 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,1,3> E3 ## E2 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,2,0> E3 ## E2 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,2,1> E3 ## E2 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,2,2> E3 ## E2 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,2,3> E3 ## E2 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,3,0> E3 ## E2 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,3,1> E3 ## E2 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,3,2> E3 ## E2 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,2,3,3> E3 ## E2 ## E3 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,0,0> E3 ## E3 ## E0 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,0,1> E3 ## E3 ## E0 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,0,2> E3 ## E3 ## E0 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,0,3> E3 ## E3 ## E0 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,1,0> E3 ## E3 ## E1 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,1,1> E3 ## E3 ## E1 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,1,2> E3 ## E3 ## E1 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,1,3> E3 ## E3 ## E1 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,2,0> E3 ## E3 ## E2 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,2,1> E3 ## E3 ## E2 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,2,2> E3 ## E3 ## E2 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,2,3> E3 ## E3 ## E2 ## E3; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,3,0> E3 ## E3 ## E3 ## E0; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,3,1> E3 ## E3 ## E3 ## E1; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,3,2> E3 ## E3 ## E3 ## E2; }; \ + struct { detail::_swizzle<4, T, P, V, 3,3,3,3> E3 ## E3 ## E3 ## E3; }; diff --git a/common/glm/glm/detail/_swizzle_func.hpp b/common/glm/glm/detail/_swizzle_func.hpp index c287bbf5b..7d725e10a 100644 --- a/common/glm/glm/detail/_swizzle_func.hpp +++ b/common/glm/glm/detail/_swizzle_func.hpp @@ -12,6 +12,10 @@ /// The above copyright notice and this permission notice shall be included in /// all copies or substantial portions of the Software. /// +/// Restrictions: +/// By making use of the Software for military purposes, you choose to make +/// a Bunny unhappy. +/// /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,13 +25,12 @@ /// THE SOFTWARE. /// /// @ref core -/// @file glm/core/_swizzle_func.hpp +/// @file glm/detail/_swizzle_func.hpp /// @date 2011-10-16 / 2011-10-16 /// @author Christophe Riccio /////////////////////////////////////////////////////////////////////////////////// -#ifndef glm_core_swizzle_func -#define glm_core_swizzle_func +#pragma once #define GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B) \ SWIZZLED_TYPE A ## B() CONST \ @@ -720,5 +723,3 @@ GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, p, q) //GLM_SWIZZLE_GEN_VEC_FROM_VEC4(valType, detail::vec4, detail::vec2, detail::vec3, detail::vec4) - -#endif//glm_core_swizzle_func diff --git a/common/glm/glm/detail/_vectorize.hpp b/common/glm/glm/detail/_vectorize.hpp index b653fa9f3..8eea6b871 100644 --- a/common/glm/glm/detail/_vectorize.hpp +++ b/common/glm/glm/detail/_vectorize.hpp @@ -12,6 +12,10 @@ /// The above copyright notice and this permission notice shall be included in /// all copies or substantial portions of the Software. /// +/// Restrictions: +/// By making use of the Software for military purposes, you choose to make +/// a Bunny unhappy. +/// /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,197 +25,136 @@ /// THE SOFTWARE. /// /// @ref core -/// @file glm/core/_vectorize.hpp +/// @file glm/detail/_vectorize.hpp /// @date 2011-10-14 / 2011-10-14 /// @author Christophe Riccio /////////////////////////////////////////////////////////////////////////////////// -#ifndef GLM_CORE_DETAIL_INCLUDED -#define GLM_CORE_DETAIL_INCLUDED +#pragma once #include "type_vec1.hpp" #include "type_vec2.hpp" #include "type_vec3.hpp" #include "type_vec4.hpp" -#define VECTORIZE1_VEC(func) \ - template \ - GLM_FUNC_QUALIFIER detail::tvec1 func( \ - detail::tvec1 const & v) \ - { \ - return detail::tvec1( \ - func(v.x)); \ - } - -#define VECTORIZE2_VEC(func) \ - template \ - GLM_FUNC_QUALIFIER detail::tvec2 func( \ - detail::tvec2 const & v) \ - { \ - return detail::tvec2( \ - func(v.x), \ - func(v.y)); \ - } - -#define VECTORIZE3_VEC(func) \ - template \ - GLM_FUNC_QUALIFIER detail::tvec3 func( \ - detail::tvec3 const & v) \ - { \ - return detail::tvec3( \ - func(v.x), \ - func(v.y), \ - func(v.z)); \ - } - -#define VECTORIZE4_VEC(func) \ - template \ - GLM_FUNC_QUALIFIER detail::tvec4 func( \ - detail::tvec4 const & v) \ - { \ - return detail::tvec4( \ - func(v.x), \ - func(v.y), \ - func(v.z), \ - func(v.w)); \ - } - -#define VECTORIZE_VEC(func) \ - VECTORIZE1_VEC(func) \ - VECTORIZE2_VEC(func) \ - VECTORIZE3_VEC(func) \ - VECTORIZE4_VEC(func) - -#define VECTORIZE1_VEC_SCA(func) \ - template \ - GLM_FUNC_QUALIFIER detail::tvec1 func \ - ( \ - detail::tvec1 const & x, \ - T const & y \ - ) \ - { \ - return detail::tvec1( \ - func(x.x, y)); \ - } - -#define VECTORIZE2_VEC_SCA(func) \ - template \ - GLM_FUNC_QUALIFIER detail::tvec2 func \ - ( \ - detail::tvec2 const & x, \ - T const & y \ - ) \ - { \ - return detail::tvec2( \ - func(x.x, y), \ - func(x.y, y)); \ - } - -#define VECTORIZE3_VEC_SCA(func) \ - template \ - GLM_FUNC_QUALIFIER detail::tvec3 func \ - ( \ - detail::tvec3 const & x, \ - T const & y \ - ) \ - { \ - return detail::tvec3( \ - func(x.x, y), \ - func(x.y, y), \ - func(x.z, y)); \ - } - -#define VECTORIZE4_VEC_SCA(func) \ - template \ - GLM_FUNC_QUALIFIER detail::tvec4 func \ - ( \ - detail::tvec4 const & x, \ - T const & y \ - ) \ - { \ - return detail::tvec4( \ - func(x.x, y), \ - func(x.y, y), \ - func(x.z, y), \ - func(x.w, y)); \ - } - -#define VECTORIZE_VEC_SCA(func) \ - VECTORIZE1_VEC_SCA(func) \ - VECTORIZE2_VEC_SCA(func) \ - VECTORIZE3_VEC_SCA(func) \ - VECTORIZE4_VEC_SCA(func) - -#define VECTORIZE2_VEC_VEC(func) \ - template \ - GLM_FUNC_QUALIFIER detail::tvec2 func \ - ( \ - detail::tvec2 const & x, \ - detail::tvec2 const & y \ - ) \ - { \ - return detail::tvec2( \ - func(x.x, y.x), \ - func(x.y, y.y)); \ - } - -#define VECTORIZE3_VEC_VEC(func) \ - template \ - GLM_FUNC_QUALIFIER detail::tvec3 func \ - ( \ - detail::tvec3 const & x, \ - detail::tvec3 const & y \ - ) \ - { \ - return detail::tvec3( \ - func(x.x, y.x), \ - func(x.y, y.y), \ - func(x.z, y.z)); \ - } - -#define VECTORIZE4_VEC_VEC(func) \ - template \ - GLM_FUNC_QUALIFIER detail::tvec4 func \ - ( \ - detail::tvec4 const & x, \ - detail::tvec4 const & y \ - ) \ - { \ - return detail::tvec4( \ - func(x.x, y.x), \ - func(x.y, y.y), \ - func(x.z, y.z), \ - func(x.w, y.w)); \ - } - -#define VECTORIZE_VEC_VEC(func) \ - VECTORIZE2_VEC_VEC(func) \ - VECTORIZE3_VEC_VEC(func) \ - VECTORIZE4_VEC_VEC(func) - namespace glm{ namespace detail { - template - struct If + template class vecType> + struct functor1{}; + + template + struct functor1 { - template - static GLM_FUNC_QUALIFIER T apply(F functor, const T& val) + GLM_FUNC_QUALIFIER static tvec1 call(R (*Func) (T x), tvec1 const & v) { - return functor(val); + return tvec1(Func(v.x)); } }; - template<> - struct If + template + struct functor1 { - template - static GLM_FUNC_QUALIFIER T apply(F, const T& val) + GLM_FUNC_QUALIFIER static tvec2 call(R (*Func) (T x), tvec2 const & v) { - return val; + return tvec2(Func(v.x), Func(v.y)); + } + }; + + template + struct functor1 + { + GLM_FUNC_QUALIFIER static tvec3 call(R (*Func) (T x), tvec3 const & v) + { + return tvec3(Func(v.x), Func(v.y), Func(v.z)); + } + }; + + template + struct functor1 + { + GLM_FUNC_QUALIFIER static tvec4 call(R (*Func) (T x), tvec4 const & v) + { + return tvec4(Func(v.x), Func(v.y), Func(v.z), Func(v.w)); + } + }; + + template class vecType> + struct functor2{}; + + template + struct functor2 + { + GLM_FUNC_QUALIFIER static tvec1 call(T (*Func) (T x, T y), tvec1 const & a, tvec1 const & b) + { + return tvec1(Func(a.x, b.x)); + } + }; + + template + struct functor2 + { + GLM_FUNC_QUALIFIER static tvec2 call(T (*Func) (T x, T y), tvec2 const & a, tvec2 const & b) + { + return tvec2(Func(a.x, b.x), Func(a.y, b.y)); + } + }; + + template + struct functor2 + { + GLM_FUNC_QUALIFIER static tvec3 call(T (*Func) (T x, T y), tvec3 const & a, tvec3 const & b) + { + return tvec3(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z)); + } + }; + + template + struct functor2 + { + GLM_FUNC_QUALIFIER static tvec4 call(T (*Func) (T x, T y), tvec4 const & a, tvec4 const & b) + { + return tvec4(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w)); + } + }; + + template class vecType> + struct functor2_vec_sca{}; + + template + struct functor2_vec_sca + { + GLM_FUNC_QUALIFIER static tvec1 call(T (*Func) (T x, T y), tvec1 const & a, T b) + { + return tvec1(Func(a.x, b)); + } + }; + + template + struct functor2_vec_sca + { + GLM_FUNC_QUALIFIER static tvec2 call(T (*Func) (T x, T y), tvec2 const & a, T b) + { + return tvec2(Func(a.x, b), Func(a.y, b)); + } + }; + + template + struct functor2_vec_sca + { + GLM_FUNC_QUALIFIER static tvec3 call(T (*Func) (T x, T y), tvec3 const & a, T b) + { + return tvec3(Func(a.x, b), Func(a.y, b), Func(a.z, b)); + } + }; + + template + struct functor2_vec_sca + { + GLM_FUNC_QUALIFIER static tvec4 call(T (*Func) (T x, T y), tvec4 const & a, T b) + { + return tvec4(Func(a.x, b), Func(a.y, b), Func(a.z, b), Func(a.w, b)); } }; }//namespace detail }//namespace glm - -#endif//GLM_CORE_DETAIL_INCLUDED diff --git a/common/glm/glm/detail/dummy.cpp b/common/glm/glm/detail/dummy.cpp index 26160a51a..c7ef99edb 100644 --- a/common/glm/glm/detail/dummy.cpp +++ b/common/glm/glm/detail/dummy.cpp @@ -12,6 +12,10 @@ /// The above copyright notice and this permission notice shall be included in /// all copies or substantial portions of the Software. /// +/// Restrictions: +/// By making use of the Software for military purposes, you choose to make +/// a Bunny unhappy. +/// /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -29,7 +33,6 @@ /// dummy.cpp exist only a wordaround for CMake file. /////////////////////////////////////////////////////////////////////////////////// -#define GLM_FORCE_RADIANS #define GLM_MESSAGES #include "../glm.hpp" #include @@ -42,6 +45,7 @@ struct material glm::vec4 specular; // Scm float shininess; // Srm }; + struct light { glm::vec4 ambient; // Acli @@ -60,6 +64,7 @@ struct light float quadraticAttenuation;// K2 }; + // Sample 1 #include // glm::vec3 #include // glm::cross, glm::normalize @@ -184,7 +189,34 @@ glm::vec3 lighting return Color; } */ + + +template class vecType> +T normalizeDotA(vecType const & x, vecType const & y) +{ + return glm::dot(x, y) * glm::inversesqrt(glm::dot(x, x) * glm::dot(y, y)); +} + +#define GLM_TEMPLATE_GENTYPE typename T, glm::precision P, template class + +template +T normalizeDotB(vecType const & x, vecType const & y) +{ + return glm::dot(x, y) * glm::inversesqrt(glm::dot(x, x) * glm::dot(y, y)); +} + +template +typename vecType::value_type normalizeDotC(vecType const & a, vecType const & b) +{ + return glm::dot(a, b) * glm::inversesqrt(glm::dot(a, a) * glm::dot(b, b)); +} + int main() { + glm::vec4 v(1); + float a = normalizeDotA(v, v); + float b = normalizeDotB(v, v); + float c = normalizeDotC(v, v); + return 0; } diff --git a/common/glm/glm/detail/func_common.hpp b/common/glm/glm/detail/func_common.hpp index a3e5d6338..0cea49426 100644 --- a/common/glm/glm/detail/func_common.hpp +++ b/common/glm/glm/detail/func_common.hpp @@ -12,6 +12,10 @@ /// The above copyright notice and this permission notice shall be included in /// all copies or substantial portions of the Software. /// +/// Restrictions: +/// By making use of the Software for military purposes, you choose to make +/// a Bunny unhappy. +/// /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,7 +25,7 @@ /// THE SOFTWARE. /// /// @ref core -/// @file glm/core/func_common.hpp +/// @file glm/detail/func_common.hpp /// @date 2008-03-08 / 2010-01-26 /// @author Christophe Riccio /// @@ -33,8 +37,7 @@ /// These all operate component-wise. The description is per component. /////////////////////////////////////////////////////////////////////////////////// -#ifndef GLM_FUNC_COMMON_INCLUDED -#define GLM_FUNC_COMMON_INCLUDED +#pragma once #include "setup.hpp" #include "precision.hpp" @@ -53,7 +56,10 @@ namespace glm /// @see GLSL abs man page /// @see GLSL 4.20.8 specification, section 8.3 Common Functions template - GLM_FUNC_DECL genType abs(genType const & x); + GLM_FUNC_DECL genType abs(genType x); + + template class vecType> + GLM_FUNC_DECL vecType abs(vecType const & x); /// Returns 1.0 if x > 0, 0.0 if x == 0, or -1.0 if x < 0. /// @@ -61,17 +67,17 @@ namespace glm /// /// @see GLSL sign man page /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template - GLM_FUNC_DECL genType sign(genType const & x); - + template class vecType> + GLM_FUNC_DECL vecType sign(vecType const & x); + /// Returns a value equal to the nearest integer that is less then or equal to x. /// /// @tparam genType Floating-point scalar or vector types. /// /// @see GLSL floor man page /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template - GLM_FUNC_DECL genType floor(genType const & x); + template class vecType> + GLM_FUNC_DECL vecType floor(vecType const & x); /// Returns a value equal to the nearest integer to x /// whose absolute value is not larger than the absolute value of x. @@ -80,8 +86,8 @@ namespace glm /// /// @see GLSL trunc man page /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template - GLM_FUNC_DECL genType trunc(genType const & x); + template class vecType> + GLM_FUNC_DECL vecType trunc(vecType const & x); /// Returns a value equal to the nearest integer to x. /// The fraction 0.5 will round in a direction chosen by the @@ -93,9 +99,9 @@ namespace glm /// /// @see GLSL round man page /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template - GLM_FUNC_DECL genType round(genType const & x); - + template class vecType> + GLM_FUNC_DECL vecType round(vecType const & x); + /// Returns a value equal to the nearest integer to x. /// A fractional part of 0.5 will round toward the nearest even /// integer. (Both 3.5 and 4.5 for x will return 4.0.) @@ -105,8 +111,8 @@ namespace glm /// @see GLSL roundEven man page /// @see GLSL 4.20.8 specification, section 8.3 Common Functions /// @see New round to even technique - template - GLM_FUNC_DECL genType roundEven(genType const & x); + template class vecType> + GLM_FUNC_DECL vecType roundEven(vecType const & x); /// Returns a value equal to the nearest integer /// that is greater than or equal to x. @@ -115,8 +121,8 @@ namespace glm /// /// @see GLSL ceil man page /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template - GLM_FUNC_DECL genType ceil(genType const & x); + template class vecType> + GLM_FUNC_DECL vecType ceil(vecType const & x); /// Return x - floor(x). /// @@ -125,7 +131,10 @@ namespace glm /// @see GLSL fract man page /// @see GLSL 4.20.8 specification, section 8.3 Common Functions template - GLM_FUNC_DECL genType fract(genType const & x); + GLM_FUNC_DECL genType fract(genType x); + + template class vecType> + GLM_FUNC_DECL vecType fract(vecType const & x); /// Modulus. Returns x - y * floor(x / y) /// for each component in x using the floating point value y. @@ -135,21 +144,13 @@ namespace glm /// @see GLSL mod man page /// @see GLSL 4.20.8 specification, section 8.3 Common Functions template - GLM_FUNC_DECL genType mod( - genType const & x, - genType const & y); + GLM_FUNC_DECL genType mod(genType x, genType y); - /// Modulus. Returns x - y * floor(x / y) - /// for each component in x using the floating point value y. - /// - /// @tparam genType Floating-point scalar or vector types. - /// - /// @see GLSL mod man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template - GLM_FUNC_DECL genType mod( - genType const & x, - typename genType::value_type const & y); + template class vecType> + GLM_FUNC_DECL vecType mod(vecType const & x, T y); + + template class vecType> + GLM_FUNC_DECL vecType mod(vecType const & x, vecType const & y); /// Returns the fractional part of x and sets i to the integer /// part (as a whole number floating point value). Both the @@ -161,25 +162,22 @@ namespace glm /// @see GLSL modf man page /// @see GLSL 4.20.8 specification, section 8.3 Common Functions template - GLM_FUNC_DECL genType modf( - genType const & x, - genType & i); + GLM_FUNC_DECL genType modf(genType x, genType & i); /// Returns y if y < x; otherwise, it returns x. /// /// @tparam genType Floating-point or integer; scalar or vector types. /// /// @see GLSL min man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions<<<<<<< HEAD + /// @see GLSL 4.20.8 specification, section 8.3 Common Functions template - GLM_FUNC_DECL genType min( - genType const & x, - genType const & y); + GLM_FUNC_DECL genType min(genType x, genType y); - template - GLM_FUNC_DECL genType min( - genType const & x, - typename genType::value_type const & y); + template class vecType> + GLM_FUNC_DECL vecType min(vecType const & x, T y); + + template class vecType> + GLM_FUNC_DECL vecType min(vecType const & x, vecType const & y); /// Returns y if x < y; otherwise, it returns x. /// @@ -188,14 +186,13 @@ namespace glm /// @see GLSL max man page /// @see GLSL 4.20.8 specification, section 8.3 Common Functions template - GLM_FUNC_DECL genType max( - genType const & x, - genType const & y); + GLM_FUNC_DECL genType max(genType x, genType y); - template - GLM_FUNC_DECL genType max( - genType const & x, - typename genType::value_type const & y); + template class vecType> + GLM_FUNC_DECL vecType max(vecType const & x, T y); + + template class vecType> + GLM_FUNC_DECL vecType max(vecType const & x, vecType const & y); /// Returns min(max(x, minVal), maxVal) for each component in x /// using the floating-point values minVal and maxVal. @@ -205,16 +202,13 @@ namespace glm /// @see GLSL clamp man page /// @see GLSL 4.20.8 specification, section 8.3 Common Functions template - GLM_FUNC_DECL genType clamp( - genType const & x, - genType const & minVal, - genType const & maxVal); + GLM_FUNC_DECL genType clamp(genType x, genType minVal, genType maxVal); - template - GLM_FUNC_DECL genType clamp( - genType const & x, - typename genType::value_type const & minVal, - typename genType::value_type const & maxVal); + template class vecType> + GLM_FUNC_DECL vecType clamp(vecType const & x, T minVal, T maxVal); + + template class vecType> + GLM_FUNC_DECL vecType clamp(vecType const & x, vecType const & minVal, vecType const & maxVal); /// If genTypeU is a floating scalar or vector: /// Returns x * (1.0 - a) + y * a, i.e., the linear blend of @@ -259,40 +253,34 @@ namespace glm /// glm::vec4 u = glm::mix(g, h, r); // Interpolations can be perform per component with a vector for the last parameter. /// @endcode template class vecType> - GLM_FUNC_DECL vecType mix( - vecType const & x, - vecType const & y, - vecType const & a); + GLM_FUNC_DECL vecType mix(vecType const & x, vecType const & y, vecType const & a); template class vecType> - GLM_FUNC_DECL vecType mix( - vecType const & x, - vecType const & y, - U const & a); + GLM_FUNC_DECL vecType mix(vecType const & x, vecType const & y, U a); template - GLM_FUNC_DECL genTypeT mix( - genTypeT const & x, - genTypeT const & y, - genTypeU const & a); + GLM_FUNC_DECL genTypeT mix(genTypeT x, genTypeT y, genTypeU a); /// Returns 0.0 if x < edge, otherwise it returns 1.0 for each component of a genType. /// /// @see GLSL step man page /// @see GLSL 4.20.8 specification, section 8.3 Common Functions template - GLM_FUNC_DECL genType step( - genType const & edge, - genType const & x); + GLM_FUNC_DECL genType step(genType edge, genType x); /// Returns 0.0 if x < edge, otherwise it returns 1.0. /// /// @see GLSL step man page /// @see GLSL 4.20.8 specification, section 8.3 Common Functions template