mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-14 15:41:30 +00:00
Merge remote-tracking branch 'origin/master' into Development
This commit is contained in:
commit
d538b48fbc
@ -8,7 +8,9 @@ script:
|
||||
- make
|
||||
- ./bin/tests
|
||||
branches:
|
||||
only: master
|
||||
only:
|
||||
- master
|
||||
- stable
|
||||
notifications:
|
||||
email: false
|
||||
irc:
|
||||
|
||||
@ -126,6 +126,7 @@ ENDIF(MSVC)
|
||||
IF(UNIX)
|
||||
IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
ADD_DEFINITIONS(-DFREEBSD)
|
||||
ADD_DEFINITIONS(-D_GLIBCXX_USE_C99)
|
||||
SET(FREEBSD TRUE)
|
||||
ENDIF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
|
||||
IF(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
@ -259,7 +260,10 @@ OPTION(EQEMU_BUILD_CLIENT_FILES "Build Client Import/Export Data Programs." ON)
|
||||
|
||||
#C++11 stuff
|
||||
IF(NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
|
||||
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-reserved-user-defined-literal")
|
||||
ENDIF()
|
||||
ENDIF(NOT MSVC)
|
||||
|
||||
#Various definitions
|
||||
@ -289,6 +293,7 @@ ADD_DEFINITIONS(-DLOG_LEVEL_DEBUG=${EQEMU_LOG_LEVEL_DEBUG})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_QUEST=${EQEMU_LOG_LEVEL_QUEST})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_COMMANDS=${EQEMU_LOG_LEVEL_COMMANDS})
|
||||
ADD_DEFINITIONS(-DLOG_LEVEL_CRASH=${EQEMU_LOG_LEVEL_CRASH})
|
||||
ADD_DEFINITIONS(-DGLM_FORCE_RADIANS)
|
||||
|
||||
IF(EQEMU_STREAM_RETRANSMIT_ACKED_PACKETS)
|
||||
ADD_DEFINITIONS(-DRETRANSMIT_ACKED_PACKETS=true)
|
||||
|
||||
213
changelog.txt
213
changelog.txt
@ -1,5 +1,218 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 10/20/2014 ==
|
||||
demonstar55: Inspect Buffs rank 1 will now show NPC buffs in target window (SoD+)
|
||||
|
||||
== 10/19/2014 ==
|
||||
Uleat: Updated command #peekinv to display item links properly in RoF clients
|
||||
demonstar55: Group Mentoring in raids
|
||||
demonstar55: Inspect Buffs (text only version) works in raid groups
|
||||
demonstar55: Make use of the Inspect Buffs op/packet. 62 SOL until someone finds its op
|
||||
|
||||
== 10/18/2014==
|
||||
demonstar55: Implement group mentor, sharing leadership exp (SoF+ only)
|
||||
demonstar55: Add gaining of group leadership while in raids
|
||||
|
||||
== 10/16/2014 ==
|
||||
Uleat: Fixed the auto-conversion view naming error and renamed the views in the script files. Added a fix sql for databases that auto-converted.
|
||||
Fix SQL: ../sql/git/bots/deprecated/2014_10_16_Lower_Case_View_Fix.sql
|
||||
|
||||
== 10/15/2014 ==
|
||||
Uleat: Cleaned up load/drop bots sqls, added '../utils/sql/git/bots/deprecated' and '../deprecated/load_bots_old.sql' (use this file on pre-player blob conversion databases.)
|
||||
Notes: I modifed the behavior of both load and drop bots to fail on the first operation if their modifications have been performed already.
|
||||
'load_bots.sql' will explicitly add bot schema, while 'drop_bots.sql' will explicitly drop it. I also added a few lines to change
|
||||
a few altered tables back to their original state - as of the date in the file.
|
||||
|
||||
== 10/13/2014 ==
|
||||
demonstar55: Partially implement leadership and raids
|
||||
Currently working: client side only effects and stat bonuses.
|
||||
Not working: Mark NPC, and other stuff that need extra server side support
|
||||
Currently only UF tested (Tit and 62 may just work, others need packet work)
|
||||
|
||||
== 10/12/2014 ==
|
||||
Akkadius: Fix for LDON Character Stat load
|
||||
|
||||
== 10/11/2014 ==
|
||||
demonstar55: Implement Raid MOTD for UF
|
||||
Don't forget 2014_10_11_RaidMOTD.sql!
|
||||
|
||||
== 10/09/2014 ==
|
||||
Uleat: Added 'BOTS' conversion code to supplement the database 'PlayerProfile' blob conversion that Akkadius recently implemented.
|
||||
Note: This automatic conversion uses the view `vwbotcharactermobs` as an update vector. If you need/would like for the converter to run on
|
||||
previously and/or manually changed code, or just have a need for it to re-run, change the following in the database view and save:
|
||||
"c.`last_login`," to "c.`timelaston`,"
|
||||
"c.`zone_id`" to "c.`zoneid`"
|
||||
"FROM `character_data` AS c" to "FROM `character_old` AS c"
|
||||
** This will only work if you haven't deleted your `character_old` table **
|
||||
|
||||
== 10/07/2014 ==
|
||||
demonstar55: Identified tutorial flag in all charcreate packets, reworked logic to correctly set homes binds
|
||||
|
||||
== 10/05/2014 ==
|
||||
Uleat: Added Server<->Corpse slot translators needed for re-enumeration (inactive until phased in)
|
||||
|
||||
== 10/03/2014 ==
|
||||
Uleat: Fixed Ti(6.2) OP_AugmentInfo translation that I broke (does not currently need and I mis-read a process)
|
||||
Uleat: Moved client patch OP_LootItem slot translation to external handlers
|
||||
|
||||
== 10/02/2014 ==
|
||||
Kayen: Exported to PERL $client->SendSpellAnim(targetid, spellid)
|
||||
This function sends the spell graphic of a spell without actually having to cast the spell.
|
||||
|
||||
== 10/02/2014 ==
|
||||
Uleat: First round of Ti/6.2 translators added - needed for re-enumeration
|
||||
|
||||
== 10/01/2014 ==
|
||||
Kayen: Exported to PERL $client->SendColoredText(color, msg)
|
||||
demonstar55: Exported SendColoredText to lua
|
||||
|
||||
== 09/30/2014 ==
|
||||
Uleat: Implemented click-casting from bag slots for clients that natively support it (RoF)
|
||||
|
||||
== 09/28/2014 ==
|
||||
demonstar55: Add support for post June 18, 2014 Hundred Hands Effect spells (they changed the formula and stuff)
|
||||
set Spells:Jun182014HundredHandsRevamp to true if you're using a spell file from June 18, 2014+
|
||||
|
||||
== 09/27/2014 ==
|
||||
Kayen: Implemented perl function $mob->GetSpellStat(spell_id, identifier, slot);
|
||||
Note: identifier is the stat field in spells_new, slot is used for certain effects like effectid, base,base2, max ect.
|
||||
Example $mob->GetSpellStat(121, "range"); //Returns spell range
|
||||
Example $mob->GetSpellStat(121, "effectid", 1); //Returns the the value of effectid1
|
||||
This will allow you to pull almost all the data for any spell in quest files.
|
||||
demonstar55: Move the client's SetAttackTimer to the end of Client::CalcBonuses to keep the haste in sync
|
||||
demonstar55: Correct haste/slow "stacking" rules
|
||||
demonstar55: Correct SE_AttackSpeed4 to respect unslowable
|
||||
demonstar55: Make the haste be between 1-225 like the client (<100 = slow, >100 = haste) to ...
|
||||
demonstar55: Correct Hundred Hands effect and use formula provided by devs
|
||||
|
||||
== 09/24/2014 ==
|
||||
Uleat: Re-ordered server opcodes and handlers to give them some predictability of location (I need this for the inventory re-enumeration.)
|
||||
demonstar55: Added helper function bool EQEmu::IsTradeskill(uint32 skill)
|
||||
|
||||
== 09/23/2014 ==
|
||||
Kayen: Spell recourse effects will now be applied AFTER the base spells effects have been applied (consistent with live).
|
||||
Kayen: SE_ApplySpell and SE_TriggerSpell will now be applied based on which effect slot they are used in (instead of always before all spell effects are checked).
|
||||
Note: If a spell has multiple SE_TriggerSpell effects within it. Only one will be able to trigger. (If you want multiple spells use SE_ApplySpell)
|
||||
|
||||
== 09/22/2014 ==
|
||||
Akkadius: #resetaa now covers the function of #resetaa and #refundaa
|
||||
- #resetaa will wipe all AA data, refund the spent points into the available points and send character to character select properly
|
||||
Akkadius: Removed #refundaa
|
||||
Akkadius: Removed a lot of debug code for blob conversion
|
||||
Akkadius: Changed status logging for loads/saves to Debug category
|
||||
|
||||
== 09/21/2014 ==
|
||||
Akkadius: Player Profile Blob to Database Conversion
|
||||
- Summary: HUGE difference in database speeds reads/writes and 1:10 datasize difference
|
||||
- The new character storage engine unlike the character_ table before, is able to properly index data and make use of
|
||||
proper MySQL/MariaDB caching optimizations and performance has increased phenominally
|
||||
PERFORMANCE AND STATISTICS FIGURES (Varies on hardware):
|
||||
- EZ Server Character data size of 2.6GB `character_` table alone now takes up approx 600MB
|
||||
- Character Data Loads take approx .03 seconds BEFORE MySQL/MariaDB cache
|
||||
- Character Data Loads take approx .001-.0035 seconds AFTER MySQL/MariaDB cache
|
||||
- Character Data Saves take approx .0001 - .003 for any particular save operation
|
||||
- Database Auto Conversion: When the 'character_' table exists, World boot-up will queue an auto-conversion prompt and convert all of your characters, BACKUP
|
||||
YOUR DATABASE BEFORE CONVERTING, here is an EASY backup script: http://wiki.eqemulator.org/p?MySQL_DB_Backup_Script
|
||||
- On auto conversion, the following tables are created automatically:
|
||||
- Table: `character_skills` - Stores Character Skills
|
||||
- Table: `character_languages` - Stores Character Language
|
||||
- Table: `character_bind` - Stores Character Bind point and Home Bind point designated by is_home bool field
|
||||
- Table: `character_alternate_abilities` - Stores all Character AA
|
||||
- Table: `character_currency` - Stores all Platinum/Gold/Silver/Copper and character related currencies
|
||||
- Table: `character_data` - Stores basic character data (Fields from `character_` table migrated to this table)
|
||||
- Table: `character_spells` - Stores character spells
|
||||
- Table: `character_memmed_spells` - Stores character memorized spells
|
||||
- Table: `character_disciplines` - Stores character disciplines
|
||||
- Table: `character_material` - Stores character armor dye textures
|
||||
- Table: `character_tribute` - Stores character tributes
|
||||
- Table: `character_bandolier` - Stores character bandoliers
|
||||
- Table: `character_inspect_messages` - Stores character inspection messages (Moved from `character_` table)
|
||||
- Table: `character_leadership_abilities` - Stores character Leadership AAs
|
||||
- Loads: Majority of Player profile loads now occur at Client::Handle_Connect_OP_ZoneEntry
|
||||
LoadCharacterFactionValues(uint32 character_id, faction_map & val_list);
|
||||
LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
LoadCharacterMemmedSpells(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
LoadCharacterLanguages(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
LoadCharacterDisciplines(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
LoadCharacterSkills(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
LoadCharacterData(uint32 character_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp);
|
||||
LoadCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
LoadCharacterBindPoint(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
LoadCharacterMaterialColor(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
LoadCharacterBandolier(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
LoadCharacterTribute(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
LoadCharacterPotions(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
LoadCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
- Saves: Occur all over the code now instead of calling full saves
|
||||
SaveCharacterBindPoint(uint32 character_id, uint32 zone_id, uint32 instance_id, float x, float y, float z, float heading, uint8 is_home);
|
||||
SaveCharacterCurrency(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
SaveCharacterData(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp, ExtendedProfile_Struct* m_epp);
|
||||
SaveCharacterAA(uint32 character_id, uint32 aa_id, uint32 current_level);
|
||||
SaveCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
|
||||
SaveCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
|
||||
SaveCharacterMaterialColor(uint32 character_id, uint32 slot_id, uint32 color);
|
||||
SaveCharacterSkill(uint32 character_id, uint32 skill_id, uint32 value);
|
||||
SaveCharacterLanguage(uint32 character_id, uint32 lang_id, uint32 value);
|
||||
SaveCharacterDisc(uint32 character_id, uint32 slot_id, uint32 disc_id);
|
||||
SaveCharacterTribute(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
SaveCharacterBandolier(uint32 character_id, uint8 bandolier_id, uint8 bandolier_slot, uint32 item_id, uint32 icon, const char* bandolier_name);
|
||||
SaveCharacterPotionBelt(uint32 character_id, uint8 potion_id, uint32 item_id, uint32 icon);
|
||||
SaveCharacterLeadershipAA(uint32 character_id, PlayerProfile_Struct* pp);
|
||||
- Deletes:
|
||||
DeleteCharacterSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
|
||||
DeleteCharacterMemorizedSpell(uint32 character_id, uint32 spell_id, uint32 slot_id);
|
||||
DeleteCharacterDisc(uint32 character_id, uint32 slot_id);
|
||||
DeleteCharacterBandolier(uint32 character_id, uint32 band_id);
|
||||
DeleteCharacterLeadershipAAs(uint32 character_id);
|
||||
- Now occur all over the code and only trigger when necessary
|
||||
- Two FULL saves when looting a corpse, this has been reduced to just currency saves on initial loot and trimmed to one save since AddToMoneyPP did it already
|
||||
- Every time a player moves coin with any situation (Splits/Trades/Merchant/Skills/Bank Coin Exchange/Coin Moves), a full save is made, this is now just a currency save
|
||||
- Every time a player skilled up at a skill vendor, a full blob save hit was made, this is not just a currency hit
|
||||
- Every time an AA was purchased, a full save was made
|
||||
- Every time a spell was scribed/swapped, disc was trained
|
||||
- When a client exists a zone, when a client enters a zone
|
||||
- NOTE: These amount of excessive saves have caused scalability issues that cause the `character_` table to hang which causes process hangs that affect the whole server
|
||||
because of the slowness of the `character_` table and the blob not allowing any indexing to occur
|
||||
- All functions that once depended on the `character_` table are now rewritten to appropriately read from the `character_data` table
|
||||
- Database query errors that occur during conversion or from and load/save/delete character functions are now leveraged via ThrowDBError and logs now go to
|
||||
Server_Folder_Root/eqemu_query_error_log.txt (You cannot log errors natively through MySQL)
|
||||
- DBASYNC IS NOW COMPLETELY REMOVED - This was mainly for Character data async loads/saves and merchantlist loads
|
||||
- Side implementations:
|
||||
Perl Exports:
|
||||
- quest::crosszonesetentityvariablebynpctypeid(npctype_id, id, m_var) - Sets entity variables world wide with specified npctype_id
|
||||
- quest::crosszonesignalnpcbynpctypeid(npctype_id, data) - Signals all NPC entities world wide with specified npctype_id
|
||||
- $client->GetTaskActivityDoneCount(TaskID, ActivityID) - Gets task activity done count by task id and activity id for client entity
|
||||
|
||||
VIEW TABLE SIZE AFTER CONVERT:
|
||||
|
||||
SELECT CONCAT(table_schema, '.', table_name) as table_name,
|
||||
CONCAT(ROUND(table_rows / 1000000, 2), 'M') rows,
|
||||
CONCAT(ROUND(data_length / ( 1024 * 1024 * 1024 ), 2), 'G') DATA,
|
||||
CONCAT(ROUND(index_length / ( 1024 * 1024 * 1024 ), 2), 'G') idx,
|
||||
CONCAT(ROUND(( data_length + index_length ) / ( 1024 * 1024 * 1024 ), 2), 'G') total_size,
|
||||
ROUND(index_length / data_length, 2) idxfrac
|
||||
FROM information_schema.TABLES
|
||||
WHERE `table_name` LIKE 'character_%'
|
||||
ORDER BY DATA DESC;
|
||||
|
||||
== 09/20/2014 ==
|
||||
demonstar55: Fix crash in SendEnterWorld on illegally long names
|
||||
demonstar55: The client only lets you enter 15 characters for your name (UF at least)
|
||||
demonstar55: Add rule Spells:SHDProcIDOffByOne for pre-UF spell file, set to true, UF+ set to false
|
||||
KLS: #suspend and #ban now have required messages to record the reason for the ban/suspension.
|
||||
|
||||
== 09/19/2014 ==
|
||||
demonstar55: Added Client::Tell_StringID (used in tell queue messages)
|
||||
demonstar55: Tell queues (and offline) messages now show correctly
|
||||
demonstar55: Fix starting with capital check
|
||||
|
||||
== 09/18/2014==
|
||||
demonstar55: Implement tell queues
|
||||
Currently set to a limit of 20 by default (World:TellQueueSize) I was unable to hit the limit on live though (100+)
|
||||
The required SQL nukes the old tell queue table, which may or may not be in your DB
|
||||
Optional SQL adds the rule to the DB to allow easy of change
|
||||
Note: this does not play well with multiple sessions with the same name on (crash and relog and have multiple sessions) but normal tells don't play well either
|
||||
|
||||
== 09/16/2014 ==
|
||||
demonstar55: Implement spell formula 137 (BER AA Desperation)
|
||||
Uleat (NateDog): Fix for LoadBuffs() crash when a spell with a non-persistent Illusion effect was loaded.
|
||||
|
||||
@ -8,7 +8,6 @@ SET(common_sources
|
||||
crc16.cpp
|
||||
crc32.cpp
|
||||
database.cpp
|
||||
dbasync.cpp
|
||||
dbcore.cpp
|
||||
debug.cpp
|
||||
emu_opcodes.cpp
|
||||
@ -56,8 +55,9 @@ SET(common_sources
|
||||
rulesys.cpp
|
||||
serverinfo.cpp
|
||||
shareddb.cpp
|
||||
skills.cpp
|
||||
spdat.cpp
|
||||
string_util.cpp
|
||||
string_util.cpp
|
||||
struct_strategy.cpp
|
||||
tcp_connection.cpp
|
||||
tcp_server.cpp
|
||||
@ -103,8 +103,8 @@ SET(common_headers
|
||||
crash.h
|
||||
crc16.h
|
||||
crc32.h
|
||||
data_verification.h
|
||||
database.h
|
||||
dbasync.h
|
||||
dbcore.h
|
||||
debug.h
|
||||
deity.h
|
||||
|
||||
@ -17,7 +17,8 @@ static const uint32 BIT_RoFAndLater = 0xFFFFFFE0;
|
||||
static const uint32 BIT_RoF2AndLater = 0xFFFFFFC0;
|
||||
static const uint32 BIT_AllClients = 0xFFFFFFFF;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
EQClientUnknown = 0,
|
||||
EQClient62, // Build: 'Aug 4 2005 15:40:59'
|
||||
EQClientTitanium, // Build: 'Oct 31 2005 10:33:37'
|
||||
@ -26,17 +27,50 @@ typedef enum {
|
||||
EQClientUnderfoot, // Build: 'Jun 8 2010 16:44:32'
|
||||
EQClientRoF, // Build: 'Dec 10 2012 17:35:44'
|
||||
EQClientRoF2, // Build: 'May 10 2013 23:30:08'
|
||||
|
||||
|
||||
_EQClientCount, // place new clients before this point (preferably, in release/attribute order)
|
||||
|
||||
|
||||
// Values below are not implemented, as yet...
|
||||
|
||||
|
||||
EmuNPC = _EQClientCount,
|
||||
EmuMerc,
|
||||
EmuBot,
|
||||
EmuPet,
|
||||
|
||||
|
||||
_EmuClientCount // array size for EQLimits
|
||||
} EQClientVersion;
|
||||
|
||||
static const char* EQClientVersionName(EQClientVersion 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";
|
||||
default:
|
||||
return "ERROR: Invalid EQClientVersion";
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* CLIENTVERSIONS_H */
|
||||
|
||||
48
common/data_verification.h
Normal file
48
common/data_verification.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2014 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 COMMON_DATA_VERIFICATION_H
|
||||
#define COMMON_DATA_VERIFICATION_H
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
T Clamp(const T& value, const T& lower, const T& upper) {
|
||||
return std::max(lower, std::min(value, upper));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T ClampLower(const T& value, const T& lower) {
|
||||
return std::max(lower, value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T ClampUpper(const T& value, const T& upper) {
|
||||
return std::min(value, upper);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool ValueWithin(const T& value, const T& lower, const T& upper) {
|
||||
return value >= lower && value <= upper;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
2458
common/database.cpp
2458
common/database.cpp
File diff suppressed because it is too large
Load Diff
@ -26,12 +26,6 @@
|
||||
#include "dbcore.h"
|
||||
#include "linked_list.h"
|
||||
#include "eq_packet_structs.h"
|
||||
/*#include "eq_stream.h"
|
||||
#include "guilds.h"
|
||||
#include "misc_functions.h"
|
||||
#include "mutex.h"
|
||||
#include "item.h"
|
||||
#include "extprofile.h"*/
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
@ -105,10 +99,16 @@ public:
|
||||
Database(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
|
||||
bool Connect(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
|
||||
~Database();
|
||||
bool ThrowDBError(std::string ErrorMessage, std::string query_title, std::string query);
|
||||
|
||||
|
||||
/*
|
||||
* General Character Related Stuff
|
||||
*/
|
||||
|
||||
/* Character Creation */
|
||||
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
|
||||
|
||||
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);
|
||||
@ -118,9 +118,8 @@ public:
|
||||
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, ExtendedProfile_Struct *ext);
|
||||
bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv);
|
||||
bool DeleteCharacter(char* name);
|
||||
uint8 CopyCharacter(const char* oldname, const char* newname, uint32 acctid);
|
||||
|
||||
/*
|
||||
* General Information Getting Queries
|
||||
@ -175,8 +174,7 @@ public:
|
||||
* Adventure related.
|
||||
*/
|
||||
void UpdateAdventureStatsEntry(uint32 char_id, uint8 theme, bool win);
|
||||
bool GetAdventureStats(uint32 char_id, uint32 &guk_w, uint32 &mir_w, uint32 &mmc_w, uint32 &ruj_w, uint32 &tak_w,
|
||||
uint32 &guk_l, uint32 &mir_l, uint32 &mmc_l, uint32 &ruj_l, uint32 &tak_l);
|
||||
bool GetAdventureStats(uint32 char_id, AdventureStats_Struct *as);
|
||||
|
||||
/*
|
||||
* Account Related
|
||||
@ -205,7 +203,7 @@ public:
|
||||
|
||||
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,
|
||||
GroupLeadershipAA_Struct* GLAA = nullptr);
|
||||
char *mentoree = nullptr, int *mentor_percent = nullptr, GroupLeadershipAA_Struct* GLAA = nullptr);
|
||||
void ClearGroupLeader(uint32 gid = 0);
|
||||
|
||||
|
||||
@ -216,6 +214,14 @@ public:
|
||||
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);
|
||||
|
||||
bool CheckDatabaseConversions();
|
||||
|
||||
/*
|
||||
* Database Variables
|
||||
@ -250,10 +256,6 @@ public:
|
||||
void SetLoginFlags(uint32 CharID, bool LFP, bool LFG, uint8 firstlogon);
|
||||
void AddReport(std::string who, std::string against, std::string lines);
|
||||
|
||||
|
||||
protected:
|
||||
void HandleMysqlError(uint32 errnum);
|
||||
|
||||
private:
|
||||
void DBInitVars();
|
||||
|
||||
@ -277,6 +279,7 @@ private:
|
||||
*/
|
||||
void ClearAllRaids();
|
||||
void ClearAllRaidDetails();
|
||||
void ClearAllRaidLeaders();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,669 +0,0 @@
|
||||
#include "debug.h"
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
#include "dbasync.h"
|
||||
#include "database.h"
|
||||
#include <errmsg.h>
|
||||
#include <mysqld_error.h>
|
||||
#include <limits.h>
|
||||
#include "dbcore.h"
|
||||
#include <string.h>
|
||||
//#include "../common/misc_functions.h"
|
||||
#include "string_util.h"
|
||||
#define ASYNC_LOOP_GRANULARITY 4 //# of ms between checking our work
|
||||
|
||||
bool DBAsyncCB_LoadVariables(DBAsyncWork* iWork) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
MYSQL_RES* result = 0;
|
||||
DBAsyncQuery* dbaq = iWork->PopAnswer();
|
||||
if (dbaq->GetAnswer(errbuf, &result))
|
||||
iWork->GetDB()->LoadVariables_result(result);
|
||||
else
|
||||
std::cout << "Error: DBAsyncCB_LoadVariables failed: !GetAnswer: '" << errbuf << "'" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void AsyncLoadVariables(DBAsync *dba, Database *db) {
|
||||
char* query = 0;
|
||||
DBAsyncWork* dbaw = new DBAsyncWork(db, &DBAsyncCB_LoadVariables, 0, DBAsync::Read);
|
||||
dbaw->AddQuery(0, &query, db->LoadVariables_MQ(&query));
|
||||
dba->AddWork(&dbaw);
|
||||
}
|
||||
|
||||
|
||||
//we only need to do anything when somebody puts work on the queue
|
||||
//so instead of checking all the time, we will wait on a condition
|
||||
//which will get signaled when somebody puts something on the queue
|
||||
ThreadReturnType DBAsyncLoop(void* tmp) {
|
||||
DBAsync* dba = (DBAsync*) tmp;
|
||||
|
||||
#ifndef WIN32
|
||||
_log(COMMON__THREADS, "Starting DBAsyncLoop with thread ID %d", pthread_self());
|
||||
#endif
|
||||
|
||||
dba->MLoopRunning.lock();
|
||||
while (dba->RunLoop()) {
|
||||
//wait before working so we check the loop condition
|
||||
//as soon as were done working
|
||||
dba->CInList.Wait();
|
||||
//we could check dba->RunLoop() again to see if we
|
||||
//got turned off while we were waiting
|
||||
{
|
||||
dba->Process();
|
||||
}
|
||||
}
|
||||
dba->MLoopRunning.unlock();
|
||||
|
||||
#ifndef WIN32
|
||||
_log(COMMON__THREADS, "Ending DBAsyncLoop with thread ID %d", pthread_self());
|
||||
#endif
|
||||
|
||||
THREAD_RETURN(nullptr);
|
||||
}
|
||||
|
||||
DBAsync::DBAsync(DBcore* iDBC)
|
||||
: Timeoutable(10000)
|
||||
{
|
||||
pDBC = iDBC;
|
||||
pRunLoop = true;
|
||||
pNextID = 1;
|
||||
#ifdef _WINDOWS
|
||||
_beginthread(DBAsyncLoop, 0, this);
|
||||
#else
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, nullptr, DBAsyncLoop, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
DBAsync::~DBAsync() {
|
||||
StopThread();
|
||||
}
|
||||
|
||||
bool DBAsync::StopThread() {
|
||||
bool ret;
|
||||
MRunLoop.lock();
|
||||
ret = pRunLoop;
|
||||
pRunLoop = false;
|
||||
MRunLoop.unlock();
|
||||
|
||||
//signal the condition so we exit the loop if were waiting
|
||||
CInList.Signal();
|
||||
|
||||
//this effectively waits for the processing thread to finish
|
||||
MLoopRunning.lock();
|
||||
MLoopRunning.unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32 DBAsync::AddWork(DBAsyncWork** iWork, uint32 iDelay) {
|
||||
MInList.lock();
|
||||
uint32 ret = GetNextID();
|
||||
if (!(*iWork)->SetWorkID(ret)) {
|
||||
MInList.unlock();
|
||||
return 0;
|
||||
}
|
||||
InList.Append(*iWork);
|
||||
(*iWork)->SetStatus(Queued);
|
||||
if (iDelay)
|
||||
(*iWork)->pExecuteAfter = Timer::GetCurrentTime() + iDelay;
|
||||
#if DEBUG_MYSQL_QUERIES >= 2
|
||||
std::cout << "Adding AsyncWork #" << (*iWork)->GetWorkID() << std::endl;
|
||||
std::cout << "ExecuteAfter = " << (*iWork)->pExecuteAfter << " (" << Timer::GetCurrentTime() << " + " << iDelay << ")" << std::endl;
|
||||
#endif
|
||||
*iWork = 0;
|
||||
MInList.unlock();
|
||||
|
||||
//wake up the processing thread and tell it to get to work.
|
||||
CInList.Signal();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DBAsync::CancelWork(uint32 iWorkID) {
|
||||
if (iWorkID == 0)
|
||||
return false;
|
||||
#if DEBUG_MYSQL_QUERIES >= 2
|
||||
std::cout << "DBAsync::CancelWork: " << iWorkID << std::endl;
|
||||
#endif
|
||||
MCurrentWork.lock();
|
||||
if (CurrentWork && CurrentWork->GetWorkID() == iWorkID) {
|
||||
CurrentWork->Cancel();
|
||||
MCurrentWork.unlock();
|
||||
return true;
|
||||
}
|
||||
MCurrentWork.unlock();
|
||||
MInList.lock();
|
||||
LinkedListIterator<DBAsyncWork*> iterator(InList);
|
||||
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
if (iterator.GetData()->GetWorkID() == iWorkID) {
|
||||
iterator.RemoveCurrent(true);
|
||||
MInList.unlock();
|
||||
return true;
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
MInList.unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DBAsync::RunLoop() {
|
||||
bool ret;
|
||||
MRunLoop.lock();
|
||||
ret = pRunLoop;
|
||||
MRunLoop.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
DBAsyncWork* DBAsync::InListPop() {
|
||||
DBAsyncWork* ret = 0;
|
||||
MInList.lock();
|
||||
LinkedListIterator<DBAsyncWork*> iterator(InList);
|
||||
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
if (iterator.GetData()->pExecuteAfter <= Timer::GetCurrentTime()) {
|
||||
ret = iterator.GetData();
|
||||
#if DEBUG_MYSQL_QUERIES >= 2
|
||||
std::cout << "Poping AsyncWork #" << ret->GetWorkID() << std::endl;
|
||||
std::cout << ret->pExecuteAfter << " <= " << Timer::GetCurrentTime() << std::endl;
|
||||
#endif
|
||||
iterator.RemoveCurrent(false);
|
||||
break;
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
MInList.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
DBAsyncWork* DBAsync::InListPopWrite() {
|
||||
MInList.lock();
|
||||
LinkedListIterator<DBAsyncWork*> iterator(InList);
|
||||
|
||||
DBAsyncWork* ret = 0;
|
||||
DBAsync::Type tmpType;
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
tmpType = iterator.GetData()->Type();
|
||||
if (tmpType == Write || tmpType == Both) {
|
||||
ret = iterator.GetData();
|
||||
iterator.RemoveCurrent(false);
|
||||
break;
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
MInList.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DBAsync::AddFQ(DBAsyncFinishedQueue* iDBAFQ) {
|
||||
MFQList.lock();
|
||||
DBAsyncFinishedQueue** tmp = new DBAsyncFinishedQueue*;
|
||||
*tmp = iDBAFQ;
|
||||
FQList.Append(tmp);
|
||||
MFQList.unlock();
|
||||
}
|
||||
|
||||
void DBAsync::Process() {
|
||||
DBAsyncWork* tmpWork;
|
||||
MCurrentWork.lock();
|
||||
while ((CurrentWork = InListPop())) {
|
||||
MCurrentWork.unlock();
|
||||
//move from queued to executing
|
||||
Status tmpStatus = CurrentWork->SetStatus(Executing);
|
||||
if (tmpStatus == Queued) {
|
||||
//execute the work
|
||||
ProcessWork(CurrentWork);
|
||||
tmpWork = CurrentWork;
|
||||
MCurrentWork.lock();
|
||||
CurrentWork = 0;
|
||||
MCurrentWork.unlock();
|
||||
//move from executing to finished
|
||||
tmpStatus = tmpWork->SetStatus(DBAsync::Finished);
|
||||
if (tmpStatus != Executing) {
|
||||
if (tmpStatus != Canceled) {
|
||||
std::cout << "Error: Unexpected DBAsyncWork->Status in DBAsync::Process #1" << std::endl;
|
||||
}
|
||||
MCurrentWork.lock();
|
||||
safe_delete(tmpWork);
|
||||
}
|
||||
else {
|
||||
//call callbacks or put results on finished queue
|
||||
DispatchWork(tmpWork);
|
||||
Sleep(25);
|
||||
MCurrentWork.lock();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tmpStatus != Canceled) {
|
||||
std::cout << "Error: Unexpected DBAsyncWork->Status in DBAsync::Process #2" << std::endl;
|
||||
}
|
||||
MCurrentWork.lock();
|
||||
safe_delete(CurrentWork);
|
||||
}
|
||||
}
|
||||
MCurrentWork.unlock();
|
||||
}
|
||||
|
||||
void DBAsync::CheckTimeout() {
|
||||
try{
|
||||
MFQList.lock();
|
||||
LinkedListIterator<DBAsyncFinishedQueue**> iterator(FQList);
|
||||
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
(*iterator.GetData())->CheckTimeouts();
|
||||
iterator.Advance();
|
||||
}
|
||||
MFQList.unlock();
|
||||
}
|
||||
catch(...){
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void DBAsync::CommitWrites() {
|
||||
#if DEBUG_MYSQL_QUERIES >= 2
|
||||
std::cout << "DBAsync::CommitWrites() called." << std::endl;
|
||||
#endif
|
||||
DBAsyncWork* tmpWork;
|
||||
while ((tmpWork = InListPopWrite())) {
|
||||
Status tmpStatus = tmpWork->SetStatus(Executing);
|
||||
if (tmpStatus == Queued) {
|
||||
ProcessWork(tmpWork);
|
||||
tmpStatus = tmpWork->SetStatus(DBAsync::Finished);
|
||||
if (tmpStatus != Executing) {
|
||||
if (tmpStatus != Canceled) {
|
||||
std::cout << "Error: Unexpected DBAsyncWork->Status in DBAsync::CommitWrites #1" << std::endl;
|
||||
}
|
||||
safe_delete(tmpWork);
|
||||
}
|
||||
else {
|
||||
DispatchWork(tmpWork);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tmpStatus != Canceled) {
|
||||
std::cout << "Error: Unexpected DBAsyncWork->Status in DBAsync::CommitWrites #2" << std::endl;
|
||||
}
|
||||
safe_delete(tmpWork);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DBAsync::ProcessWork(DBAsyncWork* iWork, bool iSleep) {
|
||||
DBAsyncQuery* CurrentQuery;
|
||||
while ((CurrentQuery = iWork->PopQuery())) {
|
||||
CurrentQuery->Process(pDBC);
|
||||
iWork->PushAnswer(CurrentQuery);
|
||||
if (iSleep)
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
void DBAsync::DispatchWork(DBAsyncWork* iWork) {
|
||||
//if this work has a callback, call it
|
||||
//otherwise, stick the work on the finish queue
|
||||
if (iWork->pCB) {
|
||||
if (iWork->pCB(iWork))
|
||||
safe_delete(iWork);
|
||||
}
|
||||
else {
|
||||
if (!iWork->pDBAFQ->Push(iWork))
|
||||
safe_delete(iWork);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
DBAsyncFinishedQueue::DBAsyncFinishedQueue(uint32 iTimeout) {
|
||||
pTimeout = iTimeout;
|
||||
}
|
||||
|
||||
DBAsyncFinishedQueue::~DBAsyncFinishedQueue() {
|
||||
}
|
||||
|
||||
void DBAsyncFinishedQueue::CheckTimeouts() {
|
||||
if (pTimeout == 0xFFFFFFFF)
|
||||
return;
|
||||
MLock.lock();
|
||||
LinkedListIterator<DBAsyncWork*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
if (iterator.GetData()->CheckTimeout(pTimeout))
|
||||
iterator.RemoveCurrent(true);
|
||||
iterator.Advance();
|
||||
}
|
||||
MLock.unlock();
|
||||
}
|
||||
|
||||
DBAsyncWork* DBAsyncFinishedQueue::Pop() {
|
||||
DBAsyncWork* ret = 0;
|
||||
MLock.lock();
|
||||
ret = list.Pop();
|
||||
MLock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
DBAsyncWork* DBAsyncFinishedQueue::Find(uint32 iWorkID) {
|
||||
DBAsyncWork* ret = 0;
|
||||
MLock.lock();
|
||||
LinkedListIterator<DBAsyncWork*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
if (iterator.GetData()->GetWorkID() == iWorkID) {
|
||||
ret = iterator.GetData();
|
||||
iterator.RemoveCurrent(false);
|
||||
break;
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
MLock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
DBAsyncWork* DBAsyncFinishedQueue::PopByWPT(uint32 iWPT) {
|
||||
DBAsyncWork* ret = 0;
|
||||
MLock.lock();
|
||||
LinkedListIterator<DBAsyncWork*> iterator(list);
|
||||
|
||||
iterator.Reset();
|
||||
while (iterator.MoreElements()) {
|
||||
if (iterator.GetData()->WPT() == iWPT) {
|
||||
ret = iterator.GetData();
|
||||
iterator.RemoveCurrent(false);
|
||||
break;
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
MLock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DBAsyncFinishedQueue::Push(DBAsyncWork* iDBAW) {
|
||||
if (!this)
|
||||
return false;
|
||||
MLock.lock();
|
||||
list.Append(iDBAW);
|
||||
MLock.unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
DBAsyncWork::DBAsyncWork(Database *db, DBAsyncFinishedQueue* iDBAFQ, uint32 iWPT, DBAsync::Type iType, uint32 iTimeout)
|
||||
: m_db(db)
|
||||
{
|
||||
pstatus = DBAsync::AddingWork;
|
||||
pType = iType;
|
||||
pExecuteAfter = 0;
|
||||
pWorkID = 0;
|
||||
pDBAFQ = iDBAFQ;
|
||||
pCB = 0;
|
||||
pWPT = iWPT;
|
||||
pQuestionCount = 0;
|
||||
pAnswerCount = 0;
|
||||
pTimeout = iTimeout;
|
||||
pTSFinish = 0;
|
||||
}
|
||||
|
||||
DBAsyncWork::DBAsyncWork(Database *db, DBWorkCompleteCallBack iCB, uint32 iWPT, DBAsync::Type iType, uint32 iTimeout)
|
||||
: m_db(db)
|
||||
{
|
||||
pstatus = DBAsync::AddingWork;
|
||||
pType = iType;
|
||||
pExecuteAfter = 0;
|
||||
pWorkID = 0;
|
||||
pDBAFQ = 0;
|
||||
pCB = iCB;
|
||||
pWPT = iWPT;
|
||||
pQuestionCount = 0;
|
||||
pAnswerCount = 0;
|
||||
pTimeout = iTimeout;
|
||||
pTSFinish = 0;
|
||||
}
|
||||
|
||||
DBAsyncWork::~DBAsyncWork() {
|
||||
DBAsyncQuery* dbaq = 0;
|
||||
while ((dbaq = todo.pop()))
|
||||
safe_delete(dbaq);
|
||||
while ((dbaq = done.pop()))
|
||||
safe_delete(dbaq);
|
||||
while ((dbaq = todel.pop()))
|
||||
safe_delete(dbaq);
|
||||
}
|
||||
|
||||
bool DBAsyncWork::AddQuery(DBAsyncQuery** iDBAQ) {
|
||||
bool ret;
|
||||
MLock.lock();
|
||||
if (pstatus != DBAsync::AddingWork)
|
||||
ret = false;
|
||||
else {
|
||||
ret = true;
|
||||
pQuestionCount++;
|
||||
todo.push(*iDBAQ);
|
||||
(*iDBAQ)->pstatus = DBAsync::Queued;
|
||||
*iDBAQ = 0;
|
||||
}
|
||||
MLock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DBAsyncWork::AddQuery(uint32 iQPT, char** iQuery, uint32 iQueryLen, bool iGetResultSet, bool iGetErrbuf) {
|
||||
DBAsyncQuery* DBAQ = new DBAsyncQuery(iQPT, iQuery, iQueryLen, iGetResultSet, iGetErrbuf);
|
||||
if (AddQuery(&DBAQ))
|
||||
return true;
|
||||
else {
|
||||
safe_delete(DBAQ);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DBAsyncWork::SetWorkID(uint32 iWorkID) {
|
||||
bool ret = true;
|
||||
MLock.lock();
|
||||
if (pWorkID)
|
||||
ret = false;
|
||||
else
|
||||
pWorkID = iWorkID;
|
||||
MLock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32 DBAsyncWork::GetWorkID() {
|
||||
uint32 ret;
|
||||
MLock.lock();
|
||||
ret = pWorkID;
|
||||
MLock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32 DBAsyncWork::WPT() {
|
||||
uint32 ret;
|
||||
MLock.lock();
|
||||
ret = pWPT;
|
||||
MLock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
DBAsync::Type DBAsyncWork::Type() {
|
||||
DBAsync::Type ret;
|
||||
MLock.lock();
|
||||
ret = pType;
|
||||
MLock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
DBAsyncQuery* DBAsyncWork::PopAnswer() {
|
||||
DBAsyncQuery* ret;
|
||||
MLock.lock();
|
||||
ret = done.pop();
|
||||
if (ret)
|
||||
pAnswerCount--;
|
||||
todel.push(ret);
|
||||
MLock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DBAsyncWork::CheckTimeout(uint32 iFQTimeout) {
|
||||
if (pTimeout == 0xFFFFFFFF)
|
||||
return false;
|
||||
bool ret = false;
|
||||
MLock.lock();
|
||||
if (pTimeout > iFQTimeout)
|
||||
iFQTimeout = pTimeout;
|
||||
if (Timer::GetCurrentTime() > (pTSFinish + iFQTimeout))
|
||||
ret = true;
|
||||
MLock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//sets the work's status to the supplied value and returns
|
||||
//the revious status
|
||||
DBAsync::Status DBAsyncWork::SetStatus(DBAsync::Status iStatus) {
|
||||
DBAsync::Status ret;
|
||||
MLock.lock();
|
||||
if (iStatus == DBAsync::Finished)
|
||||
pTSFinish = Timer::GetCurrentTime();
|
||||
ret = pstatus;
|
||||
pstatus = iStatus;
|
||||
MLock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DBAsyncWork::Cancel() {
|
||||
bool ret;
|
||||
MLock.lock();
|
||||
if (pstatus != DBAsync::Finished) {
|
||||
pstatus = DBAsync::Canceled;
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
ret = false;
|
||||
MLock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool DBAsyncWork::IsCancled() {
|
||||
bool ret;
|
||||
MLock.lock();
|
||||
ret = (bool) (pstatus == DBAsync::Canceled);
|
||||
MLock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
DBAsyncQuery* DBAsyncWork::PopQuery() {
|
||||
DBAsyncQuery* ret = 0;
|
||||
MLock.lock();
|
||||
ret = todo.pop();
|
||||
if (ret)
|
||||
pQuestionCount--;
|
||||
MLock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DBAsyncWork::PushAnswer(DBAsyncQuery* iDBAQ) {
|
||||
MLock.lock();
|
||||
done.push(iDBAQ);
|
||||
pAnswerCount++;
|
||||
MLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
DBAsyncQuery::DBAsyncQuery(uint32 iQPT, char** iQuery, uint32 iQueryLen, bool iGetResultSet, bool iGetErrbuf) {
|
||||
if (iQueryLen == 0xFFFFFFFF)
|
||||
pQueryLen = strlen(*iQuery);
|
||||
else
|
||||
pQueryLen = iQueryLen;
|
||||
pQuery = *iQuery;
|
||||
*iQuery = 0;
|
||||
Init(iQPT, iGetResultSet, iGetErrbuf);
|
||||
}
|
||||
|
||||
DBAsyncQuery::DBAsyncQuery(uint32 iQPT, const char* iQuery, uint32 iQueryLen, bool iGetResultSet, bool iGetErrbuf) {
|
||||
if (iQueryLen == 0xFFFFFFFF)
|
||||
pQueryLen = strlen(iQuery);
|
||||
else
|
||||
pQueryLen = iQueryLen;
|
||||
pQuery = strn0cpy(new char[pQueryLen+1], iQuery, pQueryLen+1);
|
||||
Init(iQPT, iGetResultSet, iGetErrbuf);
|
||||
}
|
||||
|
||||
void DBAsyncQuery::Init(uint32 iQPT, bool iGetResultSet, bool iGetErrbuf) {
|
||||
pstatus = DBAsync::AddingWork;
|
||||
pQPT = iQPT;
|
||||
pGetResultSet = iGetResultSet;
|
||||
pGetErrbuf = iGetErrbuf;
|
||||
|
||||
pmysqlsuccess = false;
|
||||
perrbuf = 0;
|
||||
perrnum = 0;
|
||||
presult = 0;
|
||||
paffected_rows = 0;
|
||||
plast_insert_id = 0;
|
||||
}
|
||||
|
||||
DBAsyncQuery::~DBAsyncQuery() {
|
||||
safe_delete_array(perrbuf);
|
||||
safe_delete_array(pQuery);
|
||||
if (presult)
|
||||
mysql_free_result(presult);
|
||||
}
|
||||
|
||||
bool DBAsyncQuery::GetAnswer(char* errbuf, MYSQL_RES** result, uint32* affected_rows, uint32* last_insert_id, uint32* errnum) {
|
||||
if (pstatus != DBAsync::Finished) {
|
||||
if (errbuf)
|
||||
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "Error: Query not finished.");
|
||||
if (errnum)
|
||||
*errnum = UINT_MAX;
|
||||
return false;
|
||||
}
|
||||
if (errbuf) {
|
||||
if (pGetErrbuf) {
|
||||
if (perrbuf)
|
||||
strn0cpy(errbuf, perrbuf, MYSQL_ERRMSG_SIZE);
|
||||
else
|
||||
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "Error message should've been saved, but hasnt. errno: %u", perrnum);
|
||||
}
|
||||
else
|
||||
snprintf(errbuf, MYSQL_ERRMSG_SIZE, "Error message not saved. errno: %u", perrnum);
|
||||
}
|
||||
if (errnum)
|
||||
*errnum = perrnum;
|
||||
if (affected_rows)
|
||||
*affected_rows = paffected_rows;
|
||||
if (last_insert_id)
|
||||
*last_insert_id = plast_insert_id;
|
||||
if (result)
|
||||
*result = presult;
|
||||
return pmysqlsuccess;
|
||||
}
|
||||
|
||||
void DBAsyncQuery::Process(DBcore* iDBC) {
|
||||
pstatus = DBAsync::Executing;
|
||||
if (pGetErrbuf)
|
||||
perrbuf = new char[MYSQL_ERRMSG_SIZE];
|
||||
MYSQL_RES** resultPP = 0;
|
||||
if (pGetResultSet)
|
||||
resultPP = &presult;
|
||||
pmysqlsuccess = iDBC->RunQuery(pQuery, pQueryLen, perrbuf, resultPP, &paffected_rows, &plast_insert_id, &perrnum);
|
||||
pstatus = DBAsync::Finished;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
176
common/dbasync.h
176
common/dbasync.h
@ -1,176 +0,0 @@
|
||||
#ifndef DBASYNC_H
|
||||
#define DBASYNC_H
|
||||
#include "../common/dbcore.h"
|
||||
#include "../common/timeoutmgr.h"
|
||||
|
||||
|
||||
class DBAsyncFinishedQueue;
|
||||
class DBAsyncWork;
|
||||
class DBAsyncQuery;
|
||||
class Database;
|
||||
|
||||
// Big daddy that owns the threads and does the work
|
||||
class DBAsync : private Timeoutable {
|
||||
public:
|
||||
enum Status { AddingWork, Queued, Executing, Finished, Canceled };
|
||||
enum Type { Read, Write, Both };
|
||||
|
||||
DBAsync(DBcore* iDBC);
|
||||
~DBAsync();
|
||||
bool StopThread();
|
||||
|
||||
uint32 AddWork(DBAsyncWork** iWork, uint32 iDelay = 0);
|
||||
bool CancelWork(uint32 iWorkID);
|
||||
void CommitWrites();
|
||||
|
||||
void AddFQ(DBAsyncFinishedQueue* iDBAFQ);
|
||||
protected:
|
||||
//things related to the processing thread:
|
||||
friend ThreadReturnType DBAsyncLoop(void* tmp);
|
||||
Mutex MLoopRunning;
|
||||
Condition CInList;
|
||||
bool RunLoop();
|
||||
void Process();
|
||||
|
||||
private:
|
||||
virtual void CheckTimeout();
|
||||
|
||||
void ProcessWork(DBAsyncWork* iWork, bool iSleep = true);
|
||||
void DispatchWork(DBAsyncWork* iWork);
|
||||
inline uint32 GetNextID() { return pNextID++; }
|
||||
DBAsyncWork* InListPop();
|
||||
DBAsyncWork* InListPopWrite(); // Ignores delay
|
||||
void OutListPush(DBAsyncWork* iDBAW);
|
||||
|
||||
Mutex MRunLoop;
|
||||
bool pRunLoop;
|
||||
|
||||
DBcore* pDBC;
|
||||
uint32 pNextID;
|
||||
Mutex MInList;
|
||||
LinkedList<DBAsyncWork*> InList;
|
||||
|
||||
Mutex MFQList;
|
||||
LinkedList<DBAsyncFinishedQueue**> FQList;
|
||||
|
||||
// Mutex for outside access to current work & when current work is being changed.
|
||||
// NOT locked when CurrentWork is being accessed by the DBAsync thread.
|
||||
// Never change pointer from outside DBAsync thread!
|
||||
// Only here for access to thread-safe DBAsyncWork functions.
|
||||
Mutex MCurrentWork;
|
||||
DBAsyncWork* CurrentWork;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
DB Work Complete Callback:
|
||||
This will be called under the DBAsync thread! Never access any non-threadsafe
|
||||
data/functions/classes. (ie: zone, entitylist, client, etc are not threadsafe)
|
||||
Function prototype:
|
||||
return value: true if we should delete the data, false if we should keep it
|
||||
*/
|
||||
typedef bool(*DBWorkCompleteCallBack)(DBAsyncWork*);
|
||||
|
||||
class DBAsyncFinishedQueue {
|
||||
public:
|
||||
DBAsyncFinishedQueue(uint32 iTimeout = 90000);
|
||||
~DBAsyncFinishedQueue();
|
||||
|
||||
DBAsyncWork* Pop();
|
||||
DBAsyncWork* PopByWPT(uint32 iWPT);
|
||||
DBAsyncWork* Find(uint32 iWPT);
|
||||
bool Push(DBAsyncWork* iDBAW);
|
||||
|
||||
void CheckTimeouts();
|
||||
private:
|
||||
Mutex MLock;
|
||||
uint32 pTimeout;
|
||||
LinkedList<DBAsyncWork*> list;
|
||||
};
|
||||
|
||||
// Container class for multiple queries
|
||||
class DBAsyncWork {
|
||||
public:
|
||||
DBAsyncWork(Database *db, DBAsyncFinishedQueue* iDBAFQ, uint32 iWPT = 0, DBAsync::Type iType = DBAsync::Both, uint32 iTimeout = 0);
|
||||
DBAsyncWork(Database *db, DBWorkCompleteCallBack iCB, uint32 iWPT = 0, DBAsync::Type iType = DBAsync::Both, uint32 iTimeout = 0);
|
||||
~DBAsyncWork();
|
||||
|
||||
bool AddQuery(DBAsyncQuery** iDBAQ);
|
||||
bool AddQuery(uint32 iQPT, char** iQuery, uint32 iQueryLen = 0xFFFFFFFF, bool iGetResultSet = true, bool iGetErrbuf = true);
|
||||
uint32 WPT();
|
||||
DBAsync::Type Type();
|
||||
|
||||
// Pops finished queries off the work
|
||||
DBAsyncQuery* PopAnswer();
|
||||
uint32 QueryCount();
|
||||
|
||||
Database *GetDB() const { return(m_db); }
|
||||
|
||||
bool CheckTimeout(uint32 iFQTimeout);
|
||||
bool SetWorkID(uint32 iWorkID);
|
||||
uint32 GetWorkID();
|
||||
protected:
|
||||
friend class DBAsync;
|
||||
DBAsync::Status SetStatus(DBAsync::Status iStatus);
|
||||
bool Cancel();
|
||||
bool IsCancled();
|
||||
DBAsyncQuery* PopQuery(); // Get query to be run
|
||||
void PushAnswer(DBAsyncQuery* iDBAQ); // Push answer back into workset
|
||||
|
||||
// not mutex'd cause only to be accessed from dbasync class
|
||||
uint32 pExecuteAfter;
|
||||
private:
|
||||
Mutex MLock;
|
||||
uint32 pQuestionCount;
|
||||
uint32 pAnswerCount;
|
||||
uint32 pWorkID;
|
||||
uint32 pWPT;
|
||||
uint32 pTimeout;
|
||||
uint32 pTSFinish; // timestamp when finished
|
||||
DBAsyncFinishedQueue* pDBAFQ; //we do now own this pointer
|
||||
DBWorkCompleteCallBack pCB;
|
||||
DBAsync::Status pstatus;
|
||||
DBAsync::Type pType;
|
||||
MyQueue<DBAsyncQuery> todo;
|
||||
MyQueue<DBAsyncQuery> done;
|
||||
MyQueue<DBAsyncQuery> todel;
|
||||
Database *const m_db; //we do now own this pointer
|
||||
};
|
||||
|
||||
// Container class for the query information
|
||||
class DBAsyncQuery {
|
||||
public:
|
||||
DBAsyncQuery(uint32 iQPT, char** iQuery, uint32 iQueryLen = 0xFFFFFFFF, bool iGetResultSet = true, bool iGetErrbuf = true);
|
||||
DBAsyncQuery(uint32 iQPT, const char* iQuery, uint32 iQueryLen = 0xFFFFFFFF, bool iGetResultSet = true, bool iGetErrbuf = true);
|
||||
~DBAsyncQuery();
|
||||
|
||||
bool GetAnswer(char* errbuf = 0, MYSQL_RES** result = 0, uint32* affected_rows = 0, uint32* last_insert_id = 0, uint32* errnum = 0);
|
||||
inline uint32 QPT() { return pQPT; }
|
||||
protected:
|
||||
friend class DBAsyncWork;
|
||||
uint32 pQPT;
|
||||
|
||||
friend class DBAsync;
|
||||
void Process(DBcore* iDBC);
|
||||
|
||||
void Init(uint32 iQPT, bool iGetResultSet, bool iGetErrbuf);
|
||||
DBAsync::Status pstatus;
|
||||
char* pQuery;
|
||||
uint32 pQueryLen;
|
||||
bool pGetResultSet;
|
||||
bool pGetErrbuf;
|
||||
|
||||
bool pmysqlsuccess;
|
||||
char* perrbuf;
|
||||
uint32 perrnum;
|
||||
uint32 paffected_rows;
|
||||
uint32 plast_insert_id;
|
||||
MYSQL_RES* presult;
|
||||
};
|
||||
|
||||
|
||||
void AsyncLoadVariables(DBAsync *dba, Database *db);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -80,14 +80,15 @@ public:
|
||||
~EQEMuLog();
|
||||
|
||||
enum LogIDs {
|
||||
Status = 0, //this must stay the first entry in this list
|
||||
Normal,
|
||||
Error,
|
||||
Debug,
|
||||
Quest,
|
||||
Commands,
|
||||
Crash,
|
||||
MaxLogID
|
||||
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
|
||||
@ -113,6 +114,7 @@ private:
|
||||
Mutex MOpen;
|
||||
Mutex MLog[MaxLogID];
|
||||
FILE* fp[MaxLogID];
|
||||
|
||||
/* LogStatus: bitwise variable
|
||||
1 = output to file
|
||||
2 = output to stdout
|
||||
|
||||
1009
common/emu_oplist.h
1009
common/emu_oplist.h
File diff suppressed because it is too large
Load Diff
@ -1024,6 +1024,26 @@ bool EQLimits::AllowsEmptyBagInBag(uint32 version) {
|
||||
//return local[ValidateMobVersion(version)];
|
||||
}
|
||||
|
||||
bool EQLimits::AllowsClickCastFromBag(uint32 version) {
|
||||
static const bool local[_EmuClientCount] = {
|
||||
/*Unknown*/ false,
|
||||
/*62*/ Client62::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
||||
/*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,
|
||||
/*RoF*/ RoF::limits::ALLOWS_CLICK_CAST_FROM_BAG,
|
||||
/*RoF2*/ false,
|
||||
|
||||
/*NPC*/ false,
|
||||
/*Merc*/ false,
|
||||
/*Bot*/ false,
|
||||
/*Pet*/ false
|
||||
};
|
||||
|
||||
return local[ValidateMobVersion(version)];
|
||||
}
|
||||
|
||||
// items
|
||||
uint16 EQLimits::ItemCommonSize(uint32 version) {
|
||||
static const uint16 local[_EmuClientCount] = {
|
||||
|
||||
@ -184,6 +184,7 @@ public:
|
||||
static uint64 CursorBitmask(uint32 version);
|
||||
|
||||
static bool AllowsEmptyBagInBag(uint32 version);
|
||||
static bool AllowsClickCastFromBag(uint32 version);
|
||||
|
||||
// items
|
||||
static uint16 ItemCommonSize(uint32 version);
|
||||
|
||||
@ -97,16 +97,15 @@ protected:
|
||||
};
|
||||
|
||||
class EQApplicationPacket : public EQPacket {
|
||||
// friend class EQProtocolPacket;
|
||||
friend class EQStream;
|
||||
public:
|
||||
EQApplicationPacket() : EQPacket(OP_Unknown,nullptr,0)
|
||||
EQApplicationPacket() : EQPacket(OP_Unknown, nullptr, 0), opcode_bypass(0)
|
||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
||||
EQApplicationPacket(const EmuOpcode op) : EQPacket(op,nullptr,0)
|
||||
EQApplicationPacket(const EmuOpcode op) : EQPacket(op, nullptr, 0), opcode_bypass(0)
|
||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
||||
EQApplicationPacket(const EmuOpcode op, const uint32 len) : EQPacket(op,nullptr,len)
|
||||
EQApplicationPacket(const EmuOpcode op, const uint32 len) : EQPacket(op, nullptr, len), opcode_bypass(0)
|
||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
||||
EQApplicationPacket(const EmuOpcode op, const unsigned char *buf, const uint32 len) : EQPacket(op,buf,len)
|
||||
EQApplicationPacket(const EmuOpcode op, const unsigned char *buf, const uint32 len) : EQPacket(op, buf, len), opcode_bypass(0)
|
||||
{ app_opcode_size = GetExecutablePlatform() == ExePlatformUCS ? 1 : 2; }
|
||||
bool combine(const EQApplicationPacket *rhs);
|
||||
uint32 serialize (uint16 opcode, unsigned char *dest) const;
|
||||
@ -119,12 +118,16 @@ public:
|
||||
virtual void DumpRawHeader(uint16 seq=0xffff, FILE *to = stdout) const;
|
||||
virtual void DumpRawHeaderNoTime(uint16 seq=0xffff, FILE *to = stdout) const;
|
||||
|
||||
uint16 GetOpcodeBypass() { return opcode_bypass; }
|
||||
void SetOpcodeBypass(uint16 v) { opcode_bypass = v; }
|
||||
|
||||
protected:
|
||||
|
||||
uint8 app_opcode_size;
|
||||
uint16 opcode_bypass;
|
||||
private:
|
||||
|
||||
EQApplicationPacket(const EQApplicationPacket &p) : EQPacket(p.emu_opcode, p.pBuffer, p.size) { app_opcode_size = p.app_opcode_size; }
|
||||
EQApplicationPacket(const EQApplicationPacket &p) : EQPacket(p.emu_opcode, p.pBuffer, p.size), opcode_bypass(p.opcode_bypass) { app_opcode_size = p.app_opcode_size; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -534,7 +534,7 @@ struct SpellBuffFade_Struct {
|
||||
/*007*/ uint8 unknown7;
|
||||
/*008*/ uint32 spellid;
|
||||
/*012*/ uint32 duration;
|
||||
/*016*/ uint32 unknown016;
|
||||
/*016*/ uint32 num_hits;
|
||||
/*020*/ uint32 unknown020; //prolly global player ID
|
||||
/*024*/ uint32 slotid;
|
||||
/*028*/ uint32 bufffade;
|
||||
@ -689,7 +689,7 @@ struct CharCreate_Struct
|
||||
/*0076*/ uint32 drakkin_heritage; // added for SoF
|
||||
/*0080*/ uint32 drakkin_tattoo; // added for SoF
|
||||
/*0084*/ uint32 drakkin_details; // added for SoF
|
||||
/*0088*/
|
||||
/*0088*/ uint32 tutorial;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -759,14 +759,62 @@ struct MovePotionToBelt_Struct {
|
||||
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_RAID_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_LEADERSHIP_AA_ARRAY = (MAX_GROUP_LEADERSHIP_AA_ARRAY+MAX_RAID_LEADERSHIP_AA_ARRAY);
|
||||
struct LeadershipAA_Struct {
|
||||
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
|
||||
};
|
||||
struct GroupLeadershipAA_Struct {
|
||||
uint32 ranks[MAX_GROUP_LEADERSHIP_AA_ARRAY];
|
||||
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 {
|
||||
uint32 ranks[MAX_RAID_LEADERSHIP_AA_ARRAY];
|
||||
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 {
|
||||
GroupLeadershipAA_Struct group;
|
||||
RaidLeadershipAA_Struct raid;
|
||||
};
|
||||
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@ -800,9 +848,12 @@ struct SuspendedMinion_Struct
|
||||
** Length: 4308 bytes
|
||||
** OpCode: 0x006a
|
||||
*/
|
||||
static const uint32 MAX_PP_LANGUAGE = 28;
|
||||
static const uint32 MAX_PP_SPELLBOOK = 480; // Increased to 480 to support SoF
|
||||
static const uint32 MAX_PP_MEMSPELL = 9;
|
||||
static const uint32 MAX_PP_LANGUAGE = 28;
|
||||
static const uint32 MAX_PP_SPELLBOOK = 480; // Set for all functions
|
||||
static const uint32 MAX_PP_MEMSPELL = 9; // Set to latest client so functions can work right
|
||||
static const uint32 MAX_PP_REF_SPELLBOOK = 480; // Set for Player Profile size retain
|
||||
static const uint32 MAX_PP_REF_MEMSPELL = 9; // Set for Player Profile size retain
|
||||
|
||||
static const uint32 MAX_PP_SKILL = _SkillPacketArraySize; // 100 - actual skills buffer size
|
||||
static const uint32 MAX_PP_AA_ARRAY = 240;
|
||||
static const uint32 MAX_GROUP_MEMBERS = 6;
|
||||
@ -880,7 +931,7 @@ struct PlayerProfile_Struct
|
||||
/*0245*/ uint8 guildbanker;
|
||||
/*0246*/ uint8 unknown0246[6]; //
|
||||
/*0252*/ uint32 intoxication;
|
||||
/*0256*/ uint32 spellSlotRefresh[MAX_PP_MEMSPELL]; //in ms
|
||||
/*0256*/ uint32 spellSlotRefresh[MAX_PP_REF_MEMSPELL]; //in ms
|
||||
/*0292*/ uint32 abilitySlotRefresh;
|
||||
/*0296*/ uint8 haircolor; // Player hair color
|
||||
/*0297*/ uint8 beardcolor; // Player beard color
|
||||
@ -919,9 +970,9 @@ struct PlayerProfile_Struct
|
||||
/*2505*/ uint8 unknown2541[47]; // ?
|
||||
/*2552*/ uint8 languages[MAX_PP_LANGUAGE];
|
||||
/*2580*/ uint8 unknown2616[4];
|
||||
/*2584*/ uint32 spell_book[MAX_PP_SPELLBOOK];
|
||||
/*2584*/ uint32 spell_book[MAX_PP_REF_SPELLBOOK];
|
||||
/*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff
|
||||
/*4632*/ uint32 mem_spells[MAX_PP_MEMSPELL];
|
||||
/*4632*/ uint32 mem_spells[MAX_PP_REF_MEMSPELL];
|
||||
/*4668*/ uint8 unknown4704[32]; //
|
||||
/*4700*/ float y; // Player y position
|
||||
/*4704*/ float x; // Player x position
|
||||
@ -1446,17 +1497,18 @@ struct BulkItemPacket_Struct
|
||||
|
||||
struct Consume_Struct
|
||||
{
|
||||
/*0000*/ uint32 slot;
|
||||
/*0004*/ uint32 auto_consumed; // 0xffffffff when auto eating e7030000 when right click
|
||||
/*0008*/ uint8 c_unknown1[4];
|
||||
/*0012*/ uint8 type; // 0x01=Food 0x02=Water
|
||||
/*0013*/ uint8 unknown13[3];
|
||||
/*0000*/ uint32 slot;
|
||||
/*0004*/ uint32 auto_consumed; // 0xffffffff when auto eating e7030000 when right click
|
||||
/*0008*/ uint8 c_unknown1[4];
|
||||
/*0012*/ uint8 type; // 0x01=Food 0x02=Water
|
||||
/*0013*/ uint8 unknown13[3];
|
||||
};
|
||||
|
||||
struct DeleteItem_Struct {
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
struct MoveItem_Struct
|
||||
@ -1464,16 +1516,18 @@ struct MoveItem_Struct
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
// both MoveItem_Struct/DeleteItem_Struct server structures will be changing to a structure-based slot format..this will
|
||||
// be used for handling SoF/SoD/etc... time stamps sent using the MoveItem_Struct format. (nothing will be done with this
|
||||
// info at the moment..but, it forwards it on to the server for handling/future use)
|
||||
// info at the moment..but, it is forwarded on to the server for handling/future use)
|
||||
struct ClientTimeStamp_Struct
|
||||
{
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
//
|
||||
@ -2177,6 +2231,12 @@ struct GroupLeaderChange_Struct
|
||||
/*128*/ char Unknown128[20];
|
||||
};
|
||||
|
||||
struct GroupMentor_Struct {
|
||||
/*000*/ int percent;
|
||||
/*004*/ char name[64];
|
||||
/*068*/
|
||||
};
|
||||
|
||||
struct FaceChange_Struct {
|
||||
/*000*/ uint8 haircolor;
|
||||
/*001*/ uint8 beardcolor;
|
||||
@ -3397,7 +3457,7 @@ struct Split_Struct
|
||||
*/
|
||||
struct NewCombine_Struct {
|
||||
/*00*/ int16 container_slot;
|
||||
/*02*/ char unknown02[2];
|
||||
/*02*/ int16 guildtribute_slot;
|
||||
/*04*/
|
||||
};
|
||||
|
||||
@ -3908,6 +3968,11 @@ struct MarkNPC_Struct
|
||||
/*08**/ char Name[64];
|
||||
};
|
||||
|
||||
struct InspectBuffs_Struct {
|
||||
/*000*/ uint32 spell_id[BUFF_COUNT];
|
||||
/*100*/ uint32 tics_remaining[BUFF_COUNT];
|
||||
};
|
||||
|
||||
struct RaidGeneral_Struct {
|
||||
/*00*/ uint32 action; //=10
|
||||
/*04*/ char player_name[64]; //should both be the player's name
|
||||
@ -3923,6 +3988,19 @@ struct RaidAddMember_Struct {
|
||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||
};
|
||||
|
||||
struct RaidMOTD_Struct {
|
||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||
/*136*/ char motd[0]; // max size is 1024, but reply is variable
|
||||
};
|
||||
|
||||
struct RaidLeadershipUpdate_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ char player_name[64];
|
||||
/*068*/ char leader_name[64];
|
||||
/*132*/ GroupLeadershipAA_Struct group; //unneeded
|
||||
/*196*/ RaidLeadershipAA_Struct raid;
|
||||
/*260*/ char Unknown260[128]; //unverified
|
||||
};
|
||||
|
||||
struct RaidAdd_Struct {
|
||||
/*000*/ uint32 action; //=0
|
||||
@ -4064,7 +4142,7 @@ struct GroupInvite_Struct {
|
||||
// uint8 unknown128[65];
|
||||
};
|
||||
|
||||
struct BuffFadeMsg_Struct {
|
||||
struct ColoredText_Struct {
|
||||
uint32 color;
|
||||
char msg[1];
|
||||
};
|
||||
@ -4261,6 +4339,13 @@ struct ItemVerifyReply_Struct {
|
||||
/*012*/
|
||||
};
|
||||
|
||||
struct ItemRecastDelay_Struct {
|
||||
/*000*/ uint32 recast_delay; // in seconds
|
||||
/*004*/ uint32 recast_type;
|
||||
/*008*/ uint32 unknown008;
|
||||
/*012*/
|
||||
};
|
||||
|
||||
/**
|
||||
* Shroud yourself. For yourself shrouding, this has your spawnId, spawnStruct,
|
||||
* bits of your charProfileStruct (no checksum, then charProfile up till
|
||||
@ -4299,9 +4384,9 @@ struct ControlBoat_Struct {
|
||||
|
||||
struct AugmentInfo_Struct
|
||||
{
|
||||
/*000*/ uint32 itemid; // id of the solvent needed
|
||||
/*004*/ uint8 window; // window to display the information in
|
||||
/*005*/ uint8 unknown005[67]; // total packet length 72, all the rest were always 00
|
||||
/*000*/ uint32 itemid; // id of the solvent needed
|
||||
/*004*/ uint8 window; // window to display the information in
|
||||
/*005*/ uint8 unknown005[67]; // total packet length 72, all the rest were always 00
|
||||
/*072*/
|
||||
};
|
||||
|
||||
@ -4589,11 +4674,13 @@ struct BuffIconEntry_Struct
|
||||
uint32 buff_slot;
|
||||
uint32 spell_id;
|
||||
uint32 tics_remaining;
|
||||
uint32 num_hits;
|
||||
};
|
||||
|
||||
struct BuffIcon_Struct
|
||||
{
|
||||
uint32 entity_id;
|
||||
uint8 all_buffs;
|
||||
uint16 count;
|
||||
BuffIconEntry_Struct entries[0];
|
||||
};
|
||||
|
||||
@ -532,9 +532,12 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
|
||||
return;
|
||||
}
|
||||
|
||||
uint16 opcode = (*OpMgr)->EmuToEQ(pack->emu_opcode);
|
||||
|
||||
//_log(NET__APP_TRACE, "Queueing %sacked packet with opcode 0x%x (%s) and length %d", ack_req?"":"non-", opcode, OpcodeManager::EmuToName(pack->emu_opcode), pack->size);
|
||||
uint16 opcode = 0;
|
||||
if(pack->GetOpcodeBypass() != 0) {
|
||||
opcode = pack->GetOpcodeBypass();
|
||||
} else {
|
||||
opcode = (*OpMgr)->EmuToEQ(pack->emu_opcode);
|
||||
}
|
||||
|
||||
if (!ack_req) {
|
||||
NonSequencedPush(new EQProtocolPacket(opcode, pack->pBuffer, pack->size));
|
||||
@ -877,43 +880,6 @@ sockaddr_in address;
|
||||
AddBytesSent(length);
|
||||
}
|
||||
|
||||
/*
|
||||
commented out since im not sure theres a lot of merit in it.
|
||||
Really it was bitterness towards allocating a 2k buffer on the stack each call.
|
||||
Im sure the thought was client side, but even then, they will
|
||||
likely need a whole thread to call this method, in which case, they should
|
||||
supply the buffer so we dont re-allocate it each time.
|
||||
EQProtocolPacket *EQStream::Read(int eq_fd, sockaddr_in *from)
|
||||
{
|
||||
int socklen;
|
||||
int length=0;
|
||||
EQProtocolPacket *p=nullptr;
|
||||
char temp[15];
|
||||
|
||||
socklen=sizeof(sockaddr);
|
||||
#ifdef _WINDOWS
|
||||
length=recvfrom(eq_fd, (char *)_tempBuffer, 2048, 0, (struct sockaddr*)from, (int *)&socklen);
|
||||
#else
|
||||
length=recvfrom(eq_fd, _tempBuffer, 2048, 0, (struct sockaddr*)from, (socklen_t *)&socklen);
|
||||
#endif
|
||||
|
||||
if (length>=2) {
|
||||
p=new EQProtocolPacket(_tempBuffer[1],&_tempBuffer[2],length-2);
|
||||
|
||||
uint32 ip=from->sin_addr.s_addr;
|
||||
sprintf(temp,"%d.%d.%d.%d:%d",
|
||||
*(unsigned char *)&ip,
|
||||
*((unsigned char *)&ip+1),
|
||||
*((unsigned char *)&ip+2),
|
||||
*((unsigned char *)&ip+3),
|
||||
ntohs(from->sin_port));
|
||||
//std::cout << timestamp() << "Data from: " << temp << " OpCode 0x" << std::hex << std::setw(2) << std::setfill('0') << (int)p->opcode << std::dec << std::endl;
|
||||
//dump_message(p->pBuffer,p->size,timestamp());
|
||||
|
||||
}
|
||||
return p;
|
||||
}*/
|
||||
|
||||
void EQStream::SendSessionResponse()
|
||||
{
|
||||
EQProtocolPacket *out=new EQProtocolPacket(OP_SessionResponse,nullptr,sizeof(SessionResponse));
|
||||
@ -1101,14 +1067,6 @@ EQProtocolPacket *p=nullptr;
|
||||
SequencedQueue.clear();
|
||||
}
|
||||
MOutboundQueue.unlock();
|
||||
|
||||
/*if(uint16(SequencedBase + SequencedQueue.size()) != NextOutSeq) {
|
||||
_log(NET__ERROR, _L "Out-bound Invalid Sequenced queue: BS %d + SQ %d != NOS %d" __L, SequencedBase, SequencedQueue.size(), NextOutSeq);
|
||||
}
|
||||
if(NextSequencedSend > SequencedQueue.size()) {
|
||||
_log(NET__ERROR, _L "Out-bound Next Send Sequence is beyond the end of the queue NSS %d > SQ %d" __L, NextSequencedSend, SequencedQueue.size());
|
||||
}*/
|
||||
//NOTE: we prolly want to reset counters if we are stupposed to do anything after this.
|
||||
}
|
||||
|
||||
void EQStream::PacketQueueClear()
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
#include "eq_packet_structs.h"
|
||||
#include "item.h"
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
/*
|
||||
@ -37,24 +36,24 @@
|
||||
*/
|
||||
struct ExtendedProfile_Struct {
|
||||
// Pet stuff
|
||||
uint16 pet_id;
|
||||
uint16 old_pet_hp;
|
||||
uint16 old_pet_mana;
|
||||
SpellBuff_Struct pet_buffs[BUFF_COUNT];
|
||||
uint32 pet_items[_MaterialCount];
|
||||
char merc_name[64];
|
||||
uint16 pet_id; /* Not Used */
|
||||
uint16 old_pet_hp; /* Not Used */
|
||||
uint16 old_pet_mana; /* Not Used */
|
||||
SpellBuff_Struct pet_buffs[BUFF_COUNT]; /* Not Used */
|
||||
uint32 pet_items[_MaterialCount]; /* Not Used */
|
||||
char merc_name[64]; /* Used */
|
||||
|
||||
uint32 aa_effects;
|
||||
uint32 perAA; //% of exp going to AAs
|
||||
uint32 expended_aa; // Total of expended AA
|
||||
uint32 pet_hp;
|
||||
uint32 pet_mana;
|
||||
uint32 mercTemplateID;
|
||||
uint32 mercSuspendedTime;
|
||||
bool mercIsSuspended;
|
||||
uint32 mercTimerRemaining;
|
||||
uint8 mercGender;
|
||||
int32 mercState;
|
||||
uint32 aa_effects; /* Used */
|
||||
uint32 perAA; /* Used: % of exp going to AAs */
|
||||
uint32 expended_aa; /* Used: Total of expended AA */
|
||||
uint32 pet_hp; /* Not Used */
|
||||
uint32 pet_mana; /* Not Used */
|
||||
uint32 mercTemplateID; /* Not Used */
|
||||
uint32 mercSuspendedTime; /* Not Used */
|
||||
bool mercIsSuspended; /* Not Used */
|
||||
uint32 mercTimerRemaining; /* Not Used */
|
||||
uint8 mercGender; /* Not Used */
|
||||
int32 mercState; /* Not Used */
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
@ -756,7 +756,7 @@ bool BaseGuildManager::DBSetGuild(uint32 charid, uint32 guild_id, uint8 rank) {
|
||||
std::string query;
|
||||
|
||||
if(guild_id != GUILD_NONE) {
|
||||
query = StringFormat("REPLACE INTO guild_members (char_id,guild_id,rank) VALUES(%d,%d,%d)", charid, guild_id, rank);
|
||||
query = StringFormat("REPLACE INTO guild_members (char_id,guild_id,rank,public_note) VALUES(%d,%d,%d,'')", charid, guild_id, rank);
|
||||
auto results = m_db->QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
@ -897,10 +897,10 @@ bool BaseGuildManager::QueryWithLogging(std::string query, const char *errmsg) {
|
||||
" FROM vwBotCharacterMobs AS c LEFT JOIN vwGuildMembers AS g ON c.id=g.char_id AND c.mobtype = g.mobtype "
|
||||
#else
|
||||
#define GuildMemberBaseQuery \
|
||||
"SELECT c.id,c.name,c.class,c.level,c.timelaston,c.zoneid," \
|
||||
"SELECT c.id,c.name,c.class,c.level,c.last_login,c.zone_id," \
|
||||
" g.guild_id,g.rank,g.tribute_enable,g.total_tribute,g.last_tribute," \
|
||||
" g.banker,g.public_note,g.alt " \
|
||||
" FROM character_ AS c LEFT JOIN guild_members AS g ON c.id=g.char_id "
|
||||
" FROM `character_data` AS c LEFT JOIN guild_members AS g ON c.id=g.char_id "
|
||||
#endif
|
||||
static void ProcessGuildMember(MySQLRequestRow row, CharGuildInfo &into) {
|
||||
//fields from `characer_`
|
||||
@ -1241,7 +1241,7 @@ BaseGuildManager::GuildInfo::GuildInfo() {
|
||||
uint32 BaseGuildManager::DoesAccountContainAGuildLeader(uint32 AccountID)
|
||||
{
|
||||
std::string query = StringFormat("SELECT guild_id FROM guild_members WHERE char_id IN "
|
||||
"(SELECT id FROM character_ WHERE account_id = %i) AND rank = 2",
|
||||
"(SELECT id FROM `character_data` WHERE account_id = %i) AND rank = 2",
|
||||
AccountID);
|
||||
auto results = m_db->QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
|
||||
@ -24,318 +24,4 @@
|
||||
|
||||
#ifndef WIN32
|
||||
#include <netinet/in.h> //for htonl
|
||||
#endif
|
||||
|
||||
/*
|
||||
void Database::GetGuildMembers(uint32 guild_id, GuildMember_Struct* gms){
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
uint32 count=0;
|
||||
uint32 length=0;
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "Select name,profile,timelaston,guildrank,publicnote from character_ where guild=%i", guild_id), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
while( ( row = mysql_fetch_row(result) ) ){
|
||||
strcpy(gms->member[count].name,row[0]);
|
||||
length+=strlen(row[0])+strlen(row[4]);
|
||||
PlayerProfile_Struct* pps=(PlayerProfile_Struct*)row[1];
|
||||
gms->member[count].level=htonl(pps->level);
|
||||
gms->member[count].zoneid=(pps->zone_id*256);
|
||||
gms->member[count].timelaston=htonl(atol(row[2]));
|
||||
gms->member[count].class_=htonl(pps->class_);
|
||||
gms->member[count].rank=atoi(row[3]);
|
||||
strcpy(gms->member[count].publicnote,row[4]);
|
||||
count++;
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetGuildMembers query '%s': %s", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
}
|
||||
gms->count=count;
|
||||
gms->length=length;
|
||||
}
|
||||
|
||||
uint32 Database::NumberInGuild(uint32 guild_id) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "Select count(id) from character_ where guild=%i", guild_id), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
if (mysql_num_rows(result) == 1) {
|
||||
row = mysql_fetch_row(result);
|
||||
uint32 ret = atoi(row[0]);
|
||||
mysql_free_result(result);
|
||||
return ret;
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in NumberInGuild query '%s': %s", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
bool Database::SetGuild(char* name, uint32 guild_id, uint8 guildrank) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
uint32 affected_rows = 0;
|
||||
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET guild=%i, guildrank=%i WHERE name='%s'", guild_id, guildrank, name), errbuf, 0, &affected_rows)) {
|
||||
safe_delete_array(query);
|
||||
if (affected_rows == 1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in SetGuild query '%s': %s", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Database::SetGuild(uint32 charid, uint32 guild_id, uint8 guildrank) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
uint32 affected_rows = 0;
|
||||
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET guild=%i, guildrank=%i WHERE id=%i", guild_id, guildrank, charid), errbuf, 0, &affected_rows)) {
|
||||
safe_delete_array(query);
|
||||
if (affected_rows == 1)
|
||||
return true;
|
||||
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in SetGuild query '%s': %s", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Database::DeleteGuild(uint32 guild_id)
|
||||
{
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
char *query2 = 0;
|
||||
uint32 affected_rows = 0;
|
||||
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "DELETE FROM guilds WHERE id=%i;", guild_id), errbuf, 0, &affected_rows)) {
|
||||
safe_delete_array(query);
|
||||
if (affected_rows == 1) {
|
||||
if(!RunQuery(query2, MakeAnyLenString(&query2, "update character_ set guild=0,guildrank=0 where guild=%i", guild_id), errbuf, 0, &affected_rows))
|
||||
LogFile->write(EQEMuLog::Error, "Error in DeleteGuild cleanup query '%s': %s", query2, errbuf);
|
||||
safe_delete_array(query2);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in DeleteGuild query '%s': %s", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Database::RenameGuild(uint32 guild_id, const char* name) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
uint32 affected_rows = 0;
|
||||
char buf[65];
|
||||
DoEscapeString(buf, name, strlen(name)) ;
|
||||
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "Update guilds set name='%s' WHERE id=%i;", buf, guild_id), errbuf, 0, &affected_rows)) {
|
||||
safe_delete_array(query);
|
||||
if (affected_rows == 1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in RenameGuild query '%s': %s", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Database::EditGuild(uint32 guild_id, uint8 ranknum, GuildRankLevel_Struct* grl)
|
||||
{
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
int chars = 0;
|
||||
uint32 affected_rows = 0;
|
||||
char buf[203];
|
||||
char buf2[8];
|
||||
DoEscapeString(buf, grl->rankname, strlen(grl->rankname)) ;
|
||||
buf2[GUILD_HEAR] = grl->heargu + '0';
|
||||
buf2[GUILD_SPEAK] = grl->speakgu + '0';
|
||||
buf2[GUILD_INVITE] = grl->invite + '0';
|
||||
buf2[GUILD_REMOVE] = grl->remove + '0';
|
||||
buf2[GUILD_PROMOTE] = grl->promote + '0';
|
||||
buf2[GUILD_DEMOTE] = grl->demote + '0';
|
||||
buf2[GUILD_MOTD] = grl->motd + '0';
|
||||
buf2[GUILD_WARPEACE] = grl->warpeace + '0';
|
||||
|
||||
if (ranknum == 0)
|
||||
chars = MakeAnyLenString(&query, "Update guilds set rank%ititle='%s' WHERE id=%i;", ranknum, buf, guild_id);
|
||||
else
|
||||
chars = MakeAnyLenString(&query, "Update guilds set rank%ititle='%s', rank%i='%s' WHERE id=%i;", ranknum, buf, ranknum, buf2, guild_id);
|
||||
|
||||
if (RunQuery(query, chars, errbuf, 0, &affected_rows)) {
|
||||
safe_delete_array(query);
|
||||
if (affected_rows == 1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in EditGuild query '%s': %s", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Database::GetGuildNameByID(uint32 guild_id, char * name) {
|
||||
if (!name || !guild_id) return false;
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "select name from guilds where id='%i'", guild_id), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
row = mysql_fetch_row(result);
|
||||
if (row[0])
|
||||
sprintf(name,"%s",row[0]);
|
||||
mysql_free_result(result);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetGuildNameByID query '%s': %s", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 Database::GetGuildIDbyLeader(uint32 leader)
|
||||
{
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT id FROM guilds WHERE leader=%i", leader), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
if (mysql_num_rows(result) == 1)
|
||||
{
|
||||
row = mysql_fetch_row(result);
|
||||
uint32 tmp = atoi(row[0]);
|
||||
mysql_free_result(result);
|
||||
return tmp;
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in Getguild_idbyLeader query '%s': %s", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Database::SetGuildLeader(uint32 guild_id, uint32 leader)
|
||||
{
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
uint32 affected_rows = 0;
|
||||
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "UPDATE guilds SET leader=%i WHERE id=%i", leader, guild_id), errbuf, 0, &affected_rows)) {
|
||||
safe_delete_array(query);
|
||||
if (affected_rows == 1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in SetGuildLeader query '%s': %s", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Database::SetGuildMOTD(uint32 guild_id, const char* motd) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
char* motdbuf = 0;
|
||||
uint32 affected_rows = 0;
|
||||
|
||||
motdbuf = new char[(strlen(motd)*2)+3];
|
||||
|
||||
DoEscapeString(motdbuf, motd, strlen(motd)) ;
|
||||
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "Update guilds set motd='%s' WHERE id=%i;", motdbuf, guild_id), errbuf, 0, &affected_rows)) {
|
||||
safe_delete_array(query);
|
||||
delete motdbuf;
|
||||
if (affected_rows == 1)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Error in SetGuildMOTD query '%s': %s", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
delete motdbuf;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
string Database::GetGuildMOTD(uint32 guild_id)
|
||||
{
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
string motd_str;
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT motd FROM guilds WHERE id=%i", guild_id), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
if (mysql_num_rows(result) == 1) {
|
||||
row = mysql_fetch_row(result);
|
||||
if (row[0])
|
||||
motd_str = row[0];
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "Error in GetGuildMOTD query '%s': %s", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
}
|
||||
return motd_str;
|
||||
}
|
||||
*/
|
||||
|
||||
#endif
|
||||
@ -911,6 +911,30 @@ bool Inventory::CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_S
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Inventory::SupportsClickCasting(int16 slot_id)
|
||||
{
|
||||
// there are a few non-potion items that identify as ItemTypePotion..so, we still need to ubiquitously include the equipment range
|
||||
if ((uint16)slot_id <= EmuConstants::GENERAL_END || slot_id == MainPowerSource)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END)
|
||||
{
|
||||
if (EQLimits::AllowsClickCastFromBag(m_version))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Inventory::SupportsPotionBeltCasting(int16 slot_id)
|
||||
{
|
||||
if ((uint16)slot_id <= EmuConstants::GENERAL_END || slot_id == MainPowerSource || (slot_id >= EmuConstants::GENERAL_BAGS_BEGIN && slot_id <= EmuConstants::GENERAL_BAGS_END))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test whether a given slot can support a container item
|
||||
bool Inventory::SupportsContainers(int16 slot_id)
|
||||
{
|
||||
|
||||
@ -121,8 +121,22 @@ public:
|
||||
// Public Methods
|
||||
///////////////////////////////
|
||||
|
||||
Inventory() { m_version = EQClientUnknown; m_versionset = false; }
|
||||
~Inventory();
|
||||
|
||||
// Inventory v2 creep
|
||||
bool SetInventoryVersion(EQClientVersion version) {
|
||||
if (!m_versionset) {
|
||||
m_version = version;
|
||||
return (m_versionset = true);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
EQClientVersion GetInventoryVersion() { return m_version; }
|
||||
|
||||
static void CleanDirty();
|
||||
static void MarkDirty(ItemInst *inst);
|
||||
|
||||
@ -132,7 +146,7 @@ public:
|
||||
|
||||
inline iter_queue cursor_begin() { return m_cursor.begin(); }
|
||||
inline iter_queue cursor_end() { return m_cursor.end(); }
|
||||
inline bool CursorEmpty() { return (m_cursor.size() == 0); }
|
||||
inline bool CursorEmpty() { return (m_cursor.size() == 0); }
|
||||
|
||||
// Retrieve a read-only item from inventory
|
||||
inline const ItemInst* operator[](int16 slot_id) const { return GetItem(slot_id); }
|
||||
@ -183,6 +197,10 @@ public:
|
||||
|
||||
static bool CanItemFitInContainer(const Item_Struct *ItemToTry, const Item_Struct *Container);
|
||||
|
||||
// Test for valid inventory casting slot
|
||||
bool SupportsClickCasting(int16 slot_id);
|
||||
bool SupportsPotionBeltCasting(int16 slot_id);
|
||||
|
||||
// Test whether a given slot can support a container item
|
||||
static bool SupportsContainers(int16 slot_id);
|
||||
|
||||
@ -229,7 +247,12 @@ protected:
|
||||
std::map<int16, ItemInst*> m_bank; // Items in character bank
|
||||
std::map<int16, ItemInst*> m_shbank; // Items in character shared bank
|
||||
std::map<int16, ItemInst*> m_trade; // Items in a trade session
|
||||
ItemInstQueue m_cursor; // Items on cursor: FIFO
|
||||
ItemInstQueue m_cursor; // Items on cursor: FIFO
|
||||
|
||||
private:
|
||||
// Active inventory version
|
||||
EQClientVersion m_version;
|
||||
bool m_versionset;
|
||||
};
|
||||
|
||||
class SharedDatabase;
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
//Mail and Chat Channels
|
||||
N(OP_MailLogin),
|
||||
N(OP_Mail),
|
||||
N(OP_Buddy),
|
||||
N(OP_ChannelAnnounceJoin),
|
||||
N(OP_ChannelAnnounceLeave),
|
||||
N(OP_Buddy),
|
||||
N(OP_MailHeaderCount),
|
||||
N(OP_MailHeader),
|
||||
N(OP_MailSendBody),
|
||||
N(OP_MailNew),
|
||||
N(OP_MailDeliveryStatus),
|
||||
N(OP_MailboxChange),
|
||||
N(OP_Ignore),
|
||||
N(OP_Mail),
|
||||
N(OP_MailboxChange),
|
||||
N(OP_MailDeliveryStatus),
|
||||
N(OP_MailHeader),
|
||||
N(OP_MailHeaderCount),
|
||||
N(OP_MailLogin),
|
||||
N(OP_MailNew),
|
||||
N(OP_MailSendBody),
|
||||
|
||||
@ -387,3 +387,26 @@ float EQHtoFloat(int d)
|
||||
{
|
||||
return(360.0f - float((d * 360) >> 11));
|
||||
}
|
||||
|
||||
// returns a swapped-bit value for use in client translator and inventory functions
|
||||
uint32 SwapBits21and22(uint32 mask)
|
||||
{
|
||||
static const uint32 BIT21 = 1 << 21;
|
||||
static const uint32 BIT22 = 1 << 22;
|
||||
static const uint32 SWAPBITS = (BIT21 | BIT22);
|
||||
|
||||
if ((bool)(mask & BIT21) != (bool)(mask & BIT22))
|
||||
mask ^= SWAPBITS;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
// returns an unset bit 22 value for use in client translators
|
||||
uint32 Catch22(uint32 mask)
|
||||
{
|
||||
static const uint32 KEEPBITS = ~(1 << 22);
|
||||
|
||||
mask &= KEEPBITS;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
@ -102,6 +102,8 @@ int FloatToEQ13(float d);
|
||||
int NewFloatToEQ13(float d);
|
||||
int FloatToEQ19(float d);
|
||||
int FloatToEQH(float d);
|
||||
uint32 SwapBits21and22(uint32 mask);
|
||||
uint32 Catch22(uint32 mask);
|
||||
|
||||
// macro to catch fp errors (provided by noudness)
|
||||
#define FCMP(a,b) (fabs(a-b) < FLT_EPSILON)
|
||||
|
||||
@ -10,7 +10,7 @@ MySQLRequestResult::MySQLRequestResult()
|
||||
MySQLRequestResult::MySQLRequestResult(MYSQL_RES* result, uint32 rowsAffected, uint32 rowCount, uint32 columnCount, uint32 lastInsertedID, uint32 errorNumber, char *errorBuffer)
|
||||
: m_CurrentRow(result), m_OneBeyondRow()
|
||||
{
|
||||
m_Result = result;
|
||||
m_Result = result;
|
||||
m_RowsAffected = rowsAffected;
|
||||
m_RowCount = rowCount;
|
||||
m_ColumnCount = columnCount;
|
||||
@ -22,16 +22,17 @@ MySQLRequestResult::MySQLRequestResult(MYSQL_RES* result, uint32 rowsAffected, u
|
||||
m_ColumnLengths = nullptr;
|
||||
m_Fields = nullptr;
|
||||
|
||||
if (errorBuffer != nullptr)
|
||||
m_Success = true;
|
||||
if (errorBuffer != nullptr)
|
||||
m_Success = false;
|
||||
|
||||
m_Success = true;
|
||||
m_ErrorNumber = errorNumber;
|
||||
m_ErrorBuffer = errorBuffer;
|
||||
m_ErrorNumber = errorNumber;
|
||||
m_ErrorBuffer = errorBuffer;
|
||||
}
|
||||
|
||||
void MySQLRequestResult::FreeInternals()
|
||||
{
|
||||
|
||||
safe_delete_array(m_ErrorBuffer);
|
||||
|
||||
if (m_Result != nullptr)
|
||||
@ -100,6 +101,7 @@ MySQLRequestResult::MySQLRequestResult(MySQLRequestResult&& moveItem)
|
||||
m_RowsAffected = moveItem.m_RowsAffected;
|
||||
m_LastInsertedID = moveItem.m_LastInsertedID;
|
||||
m_ColumnLengths = moveItem.m_ColumnLengths;
|
||||
m_ColumnCount = moveItem.m_ColumnCount;
|
||||
m_Fields = moveItem.m_Fields;
|
||||
|
||||
// Keeps deconstructor from double freeing
|
||||
@ -127,6 +129,7 @@ MySQLRequestResult& MySQLRequestResult::operator=(MySQLRequestResult&& other)
|
||||
m_CurrentRow = other.m_CurrentRow;
|
||||
m_OneBeyondRow = other.m_OneBeyondRow;
|
||||
m_ColumnLengths = other.m_ColumnLengths;
|
||||
m_ColumnCount = other.m_ColumnCount;
|
||||
m_Fields = other.m_Fields;
|
||||
|
||||
// Keeps deconstructor from double freeing
|
||||
|
||||
@ -305,7 +305,8 @@ OUTz(OP_FinishWindow2);
|
||||
//OUTv(OP_AdventureInfo, strlen(p)+1);
|
||||
//OUTv(OP_AdventureMerchantResponse, strlen(msg)+2);
|
||||
OUTv(OP_ItemPacket, ItemPacket_Struct);
|
||||
OUTv(OP_BuffFadeMsg, BuffFadeMsg_Struct);
|
||||
OUTv(OP_ColoredText, ColoredText_Struct);
|
||||
OUTv(OP_ItemRecastDelay, ItemRecastDelay_Struct);
|
||||
OUTv(OP_FormattedMessage, FormattedMessage_Struct);
|
||||
OUTv(OP_GuildMemberList, uint32); //variable length, but nasty
|
||||
OUTv(OP_InterruptCast, InterruptCast_Struct);
|
||||
|
||||
@ -160,7 +160,7 @@ void load_opcode_names()
|
||||
opcode_map[0x0192]="LiveOP_YellForHelp";
|
||||
opcode_map[0x00ef]="LiveOP_SafePoint";
|
||||
opcode_map[0x0157]="LiveOP_Buff";
|
||||
opcode_map[0x00c0]="LiveOP_BuffFadeMsg";
|
||||
opcode_map[0x00c0]="LiveOP_ColoredText";
|
||||
opcode_map[0x0440]="LiveOP_MultiLineMsg";
|
||||
opcode_map[0x021c]="LiveOP_SpecialMesg";
|
||||
opcode_map[0x0013]="LiveOP_Consent";
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#ifndef CLIENT62_CONSTANTS_H_
|
||||
#define CLIENT62_CONSTANTS_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../types.h"
|
||||
|
||||
namespace Client62 {
|
||||
namespace maps {
|
||||
@ -180,6 +180,7 @@ namespace Client62 {
|
||||
|
||||
namespace limits {
|
||||
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
||||
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
|
||||
static const bool COIN_HAS_WEIGHT = true;
|
||||
}
|
||||
|
||||
|
||||
@ -1,36 +1,54 @@
|
||||
|
||||
//list of packets we need to encode on the way out:
|
||||
// out-going packets that require an ENCODE translation:
|
||||
E(OP_Action)
|
||||
E(OP_AdventureMerchantSell)
|
||||
E(OP_ApplyPoison)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_BecomeTrader)
|
||||
E(OP_CharInventory)
|
||||
E(OP_DeleteCharge)
|
||||
E(OP_DeleteItem)
|
||||
E(OP_DeleteSpawn)
|
||||
E(OP_GuildMemberLevelUpdate)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_Illusion)
|
||||
E(OP_ItemLinkResponse)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_LeadershipExpUpdate)
|
||||
E(OP_LootItem)
|
||||
E(OP_MoveItem)
|
||||
E(OP_NewSpawn)
|
||||
E(OP_OnLevelMessage)
|
||||
E(OP_PetBuffWindow)
|
||||
E(OP_PlayerProfile)
|
||||
E(OP_ReadBook)
|
||||
E(OP_RespondAA)
|
||||
E(OP_SendAATable)
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_LeadershipExpUpdate)
|
||||
E(OP_PlayerProfile)
|
||||
E(OP_NewSpawn)
|
||||
E(OP_ZoneSpawns)
|
||||
E(OP_ZoneEntry)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_ItemLinkResponse)
|
||||
E(OP_CharInventory)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_ZoneServerReady)
|
||||
E(OP_GuildMemberLevelUpdate)
|
||||
E(OP_ReadBook)
|
||||
E(OP_Illusion)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_Track)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_RespondAA)
|
||||
E(OP_DeleteSpawn)
|
||||
E(OP_TributeItem)
|
||||
E(OP_WearChange)
|
||||
E(OP_Action)
|
||||
E(OP_BecomeTrader)
|
||||
E(OP_PetBuffWindow)
|
||||
E(OP_OnLevelMessage)
|
||||
//list of packets we need to decode on the way in:
|
||||
D(OP_SetServerFilter)
|
||||
E(OP_ZoneEntry)
|
||||
E(OP_ZoneServerReady)
|
||||
E(OP_ZoneSpawns)
|
||||
// incoming packets that require a DECODE translation:
|
||||
D(OP_AdventureMerchantSell)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_CastSpell)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_WhoAllRequest)
|
||||
D(OP_ReadBook)
|
||||
D(OP_Consume)
|
||||
D(OP_DeleteItem)
|
||||
D(OP_FaceChange)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_ReadBook)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
D(OP_WearChange)
|
||||
D(OP_WhoAllRequest)
|
||||
#undef E
|
||||
#undef D
|
||||
|
||||
@ -406,7 +406,7 @@ struct CastSpell_Struct
|
||||
uint32 spell_id;
|
||||
uint32 inventoryslot; // slot for clicky item, 0xFFFF = normal cast
|
||||
uint32 target_id;
|
||||
uint8 cs_unknown[4];
|
||||
uint8 cs_unknown[4];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -558,7 +558,7 @@ struct CharCreate_Struct
|
||||
/*0128*/ uint32 face;
|
||||
/*0132*/ uint32 eyecolor1; //its possiable we could have these switched
|
||||
/*0136*/ uint32 eyecolor2; //since setting one sets the other we really can't check
|
||||
/*0140*/ uint32 unknown140;
|
||||
/*0140*/ uint32 tutorial; //assumptions are bad! But guessed
|
||||
};
|
||||
|
||||
/*
|
||||
@ -611,14 +611,62 @@ struct PotionBelt_Struct {
|
||||
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_RAID_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_LEADERSHIP_AA_ARRAY = (MAX_GROUP_LEADERSHIP_AA_ARRAY+MAX_RAID_LEADERSHIP_AA_ARRAY);
|
||||
struct LeadershipAA_Struct {
|
||||
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
|
||||
};
|
||||
struct GroupLeadershipAA_Struct {
|
||||
uint32 ranks[MAX_GROUP_LEADERSHIP_AA_ARRAY];
|
||||
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 {
|
||||
uint32 ranks[MAX_RAID_LEADERSHIP_AA_ARRAY];
|
||||
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 {
|
||||
GroupLeadershipAA_Struct group;
|
||||
RaidLeadershipAA_Struct raid;
|
||||
};
|
||||
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1148,19 +1196,27 @@ struct BulkItemPacket_Struct
|
||||
|
||||
struct Consume_Struct
|
||||
{
|
||||
/*0000*/ uint32 slot;
|
||||
/*0004*/ uint32 auto_consumed; // 0xffffffff when auto eating e7030000 when right click
|
||||
/*0008*/ uint8 c_unknown1[4];
|
||||
/*0012*/ uint8 type; // 0x01=Food 0x02=Water
|
||||
/*0013*/ uint8 unknown13[3];
|
||||
/*0000*/ uint32 slot;
|
||||
/*0004*/ uint32 auto_consumed; // 0xffffffff when auto eating e7030000 when right click
|
||||
/*0008*/ uint8 c_unknown1[4];
|
||||
/*0012*/ uint8 type; // 0x01=Food 0x02=Water
|
||||
/*0013*/ uint8 unknown13[3];
|
||||
};
|
||||
|
||||
struct DeleteItem_Struct
|
||||
{
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
struct MoveItem_Struct
|
||||
{
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
//
|
||||
@ -1362,12 +1418,6 @@ struct CombatAbility_Struct {
|
||||
uint32 m_skill;
|
||||
};
|
||||
|
||||
struct DeleteItem_Struct {
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
};
|
||||
|
||||
//Instill Doubt
|
||||
struct Instill_Doubt_Struct {
|
||||
uint8 i_id;
|
||||
@ -1521,6 +1571,14 @@ struct Adventure_Purchase_Struct {
|
||||
/*008*/ uint32 variable;
|
||||
};
|
||||
|
||||
struct Adventure_Sell_Struct {
|
||||
/*000*/ uint32 unknown000; //0x01
|
||||
/*004*/ uint32 npcid;
|
||||
/*008*/ uint32 slot;
|
||||
/*012*/ uint32 charges;
|
||||
/*016*/ uint32 sell_price;
|
||||
};
|
||||
|
||||
struct AdventurePoints_Update_Struct {
|
||||
/*000*/ uint32 ldon_available_points; // Total available points
|
||||
/*004*/ uint8 unkown_apu004[20];
|
||||
@ -2524,10 +2582,10 @@ struct TributeInfo_Struct {
|
||||
};
|
||||
|
||||
struct TributeItem_Struct {
|
||||
uint32 slot;
|
||||
uint32 quantity;
|
||||
uint32 tribute_master_id;
|
||||
int32 tribute_points;
|
||||
uint32 slot;
|
||||
uint32 quantity;
|
||||
uint32 tribute_master_id;
|
||||
int32 tribute_points;
|
||||
};
|
||||
|
||||
struct TributePoint_Struct {
|
||||
@ -2563,7 +2621,7 @@ struct Split_Struct
|
||||
*/
|
||||
struct NewCombine_Struct {
|
||||
/*00*/ int16 container_slot;
|
||||
/*02*/ char unknown02[2];
|
||||
/*02*/ int16 guildtribute_slot;
|
||||
/*04*/
|
||||
};
|
||||
|
||||
@ -2969,7 +3027,7 @@ struct GroupInvite_Struct {
|
||||
// uint8 unknown128[65];
|
||||
};
|
||||
|
||||
struct BuffFadeMsg_Struct {
|
||||
struct ColoredText_Struct {
|
||||
uint32 color;
|
||||
char msg[1];
|
||||
};
|
||||
@ -3076,6 +3134,11 @@ struct AnnoyingZoneUnknown_Struct {
|
||||
uint32 value; //always 4
|
||||
};
|
||||
|
||||
struct ApplyPoison_Struct {
|
||||
uint32 inventorySlot;
|
||||
uint32 success;
|
||||
};
|
||||
|
||||
struct GuildMemberUpdate_Struct {
|
||||
/*00*/ uint32 guild_id; //not sure
|
||||
/*04*/ char member_name[64];
|
||||
@ -3084,11 +3147,6 @@ struct GuildMemberUpdate_Struct {
|
||||
/*72*/ uint32 unknown072;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}; //end namespace structs
|
||||
}; //end namespace Client62
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#ifndef RoF_CONSTANTS_H_
|
||||
#define RoF_CONSTANTS_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../types.h"
|
||||
|
||||
namespace RoF {
|
||||
namespace maps {
|
||||
@ -184,6 +184,7 @@ namespace RoF {
|
||||
|
||||
namespace limits {
|
||||
static const bool ALLOWS_EMPTY_BAG_IN_BAG = true;
|
||||
static const bool ALLOWS_CLICK_CAST_FROM_BAG = true;
|
||||
static const bool COIN_HAS_WEIGHT = false;
|
||||
}
|
||||
|
||||
|
||||
@ -1,162 +1,161 @@
|
||||
|
||||
//list of packets we need to encode on the way out:
|
||||
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_ZoneServerInfo)
|
||||
E(OP_SendAATable)
|
||||
E(OP_PlayerProfile)
|
||||
E(OP_ZoneEntry)
|
||||
E(OP_CharInventory)
|
||||
E(OP_NewZone)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_GroundSpawn)
|
||||
E(OP_SendZonepoints)
|
||||
E(OP_NewSpawn)
|
||||
E(OP_ZoneSpawns)
|
||||
E(OP_ItemLinkResponse)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_Illusion)
|
||||
E(OP_ManaChange)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_LeadershipExpUpdate)
|
||||
E(OP_ExpansionInfo)
|
||||
E(OP_LogServer)
|
||||
E(OP_Damage)
|
||||
E(OP_Buff)
|
||||
// out-going packets that require an ENCODE translation:
|
||||
E(OP_Action)
|
||||
E(OP_Consider)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_DeleteItem)
|
||||
E(OP_ItemVerifyReply)
|
||||
E(OP_DeleteCharge)
|
||||
E(OP_MoveItem)
|
||||
//E(OP_OpenNewTasksWindow)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_LootItem)
|
||||
E(OP_TributeItem)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_ReadBook)
|
||||
E(OP_Stun)
|
||||
E(OP_ZonePlayerToBind)
|
||||
E(OP_AdventureMerchantSell)
|
||||
E(OP_RaidUpdate)
|
||||
E(OP_RaidJoin)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_InspectRequest)
|
||||
E(OP_GroupInvite)
|
||||
E(OP_GroupFollow)
|
||||
E(OP_GroupFollow2)
|
||||
E(OP_GroupUpdate)
|
||||
E(OP_GroupCancelInvite)
|
||||
E(OP_WhoAllResponse)
|
||||
E(OP_Track)
|
||||
E(OP_ShopPlayerBuy)
|
||||
E(OP_PetBuffWindow)
|
||||
E(OP_OnLevelMessage)
|
||||
E(OP_Barter)
|
||||
E(OP_AltCurrency)
|
||||
E(OP_AltCurrencySell)
|
||||
E(OP_Animation)
|
||||
E(OP_ApplyPoison)
|
||||
E(OP_Barter)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_BeginCast)
|
||||
E(OP_BlockedBuffs)
|
||||
E(OP_Buff)
|
||||
E(OP_BuffCreate)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_CastSpell)
|
||||
E(OP_ChannelMessage)
|
||||
E(OP_GuildsList)
|
||||
E(OP_CharInventory)
|
||||
E(OP_ClickObjectAction)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_Consider)
|
||||
E(OP_Damage)
|
||||
E(OP_DeleteCharge)
|
||||
E(OP_DeleteItem)
|
||||
E(OP_DeleteSpawn)
|
||||
E(OP_DisciplineUpdate)
|
||||
E(OP_DzCompass)
|
||||
E(OP_DzExpeditionEndsWarning)
|
||||
E(OP_DzExpeditionInfo)
|
||||
E(OP_DzCompass)
|
||||
E(OP_DzMemberList)
|
||||
E(OP_DzExpeditionList)
|
||||
E(OP_DzLeaderStatus)
|
||||
E(OP_DzJoinExpeditionConfirm)
|
||||
E(OP_TargetBuffs)
|
||||
E(OP_BuffCreate)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_RespondAA)
|
||||
E(OP_DisciplineUpdate)
|
||||
E(OP_AltCurrencySell)
|
||||
E(OP_AltCurrency)
|
||||
E(OP_RequestClientZoneChange)
|
||||
E(OP_ZoneChange)
|
||||
E(OP_WearChange)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_CastSpell)
|
||||
E(OP_InterruptCast)
|
||||
E(OP_SendMembership)
|
||||
E(OP_Animation)
|
||||
E(OP_HPUpdate)
|
||||
E(OP_BlockedBuffs)
|
||||
E(OP_RemoveBlockedBuffs)
|
||||
E(OP_DeleteSpawn)
|
||||
E(OP_ClickObjectAction)
|
||||
E(OP_RecipeAutoCombine)
|
||||
E(OP_GMTrainSkillConfirm)
|
||||
E(OP_SkillUpdate)
|
||||
E(OP_TributeInfo)
|
||||
E(OP_TaskHistoryReply)
|
||||
E(OP_TaskDescription)
|
||||
E(OP_SetGuildRank)
|
||||
E(OP_MercenaryDataUpdate)
|
||||
E(OP_MercenaryDataResponse)
|
||||
E(OP_GuildMemberUpdate)
|
||||
E(OP_DzLeaderStatus)
|
||||
E(OP_DzMemberList)
|
||||
E(OP_ExpansionInfo)
|
||||
E(OP_GMLastName)
|
||||
E(OP_BeginCast)
|
||||
E(OP_GMTrainSkillConfirm)
|
||||
E(OP_GroundSpawn)
|
||||
E(OP_GroupCancelInvite)
|
||||
E(OP_GroupFollow)
|
||||
E(OP_GroupFollow2)
|
||||
E(OP_GroupInvite)
|
||||
E(OP_GroupUpdate)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_GuildMemberUpdate)
|
||||
E(OP_GuildsList)
|
||||
E(OP_HPUpdate)
|
||||
E(OP_Illusion)
|
||||
E(OP_InspectBuffs)
|
||||
E(OP_InspectRequest)
|
||||
E(OP_InterruptCast)
|
||||
E(OP_ItemLinkResponse)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_ItemVerifyReply)
|
||||
E(OP_LeadershipExpUpdate)
|
||||
E(OP_LogServer)
|
||||
E(OP_LootItem)
|
||||
E(OP_ManaChange)
|
||||
E(OP_MercenaryDataResponse)
|
||||
E(OP_MercenaryDataUpdate)
|
||||
E(OP_MoveItem)
|
||||
E(OP_NewSpawn)
|
||||
E(OP_NewZone)
|
||||
E(OP_OnLevelMessage)
|
||||
//E(OP_OpenNewTasksWindow)
|
||||
E(OP_PetBuffWindow)
|
||||
E(OP_PlayerProfile)
|
||||
E(OP_RaidJoin)
|
||||
E(OP_RaidUpdate)
|
||||
E(OP_ReadBook)
|
||||
E(OP_RecipeAutoCombine)
|
||||
E(OP_RemoveBlockedBuffs)
|
||||
E(OP_RequestClientZoneChange)
|
||||
E(OP_RespondAA)
|
||||
E(OP_RezzRequest)
|
||||
//list of packets we need to decode on the way in:
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_ConsiderCorpse)
|
||||
D(OP_Consider)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_MoveItem)
|
||||
D(OP_WhoAllRequest)
|
||||
E(OP_SendAATable)
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_SendMembership)
|
||||
E(OP_SendZonepoints)
|
||||
E(OP_SetGuildRank)
|
||||
E(OP_ShopPlayerBuy)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_ShopRequest)
|
||||
E(OP_SkillUpdate)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_Stun)
|
||||
E(OP_TargetBuffs)
|
||||
E(OP_TaskDescription)
|
||||
E(OP_TaskHistoryReply)
|
||||
E(OP_Track)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_TributeInfo)
|
||||
E(OP_TributeItem)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_WearChange)
|
||||
E(OP_WhoAllResponse)
|
||||
E(OP_ZoneChange)
|
||||
E(OP_ZoneEntry)
|
||||
E(OP_ZonePlayerToBind)
|
||||
E(OP_ZoneServerInfo)
|
||||
E(OP_ZoneSpawns)
|
||||
// incoming packets that require a DECODE translation:
|
||||
D(OP_AdventureMerchantSell)
|
||||
D(OP_AltCurrencySell)
|
||||
D(OP_AltCurrencySellSelection)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_BazaarSearch)
|
||||
D(OP_BlockedBuffs)
|
||||
D(OP_Buff)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_Consume)
|
||||
D(OP_BuffRemoveRequest)
|
||||
D(OP_CastSpell)
|
||||
D(OP_Save)
|
||||
D(OP_ItemVerifyRequest)
|
||||
D(OP_GroupInvite)
|
||||
D(OP_GroupInvite2)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_Consider)
|
||||
D(OP_ConsiderCorpse)
|
||||
D(OP_Consume)
|
||||
D(OP_Damage)
|
||||
D(OP_DeleteItem)
|
||||
D(OP_EnvDamage)
|
||||
D(OP_FaceChange)
|
||||
D(OP_FindPersonRequest)
|
||||
D(OP_GMLastName)
|
||||
D(OP_GroupCancelInvite)
|
||||
D(OP_GroupDisband)
|
||||
D(OP_GroupFollow)
|
||||
D(OP_GroupFollow2)
|
||||
D(OP_GroupDisband)
|
||||
D(OP_GroupCancelInvite)
|
||||
D(OP_FindPersonRequest)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_LootItem)
|
||||
D(OP_TributeItem)
|
||||
D(OP_ReadBook)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_FaceChange)
|
||||
D(OP_AdventureMerchantSell)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_RaidInvite)
|
||||
D(OP_InspectRequest)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_BazaarSearch)
|
||||
D(OP_LoadSpellSet)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_Damage)
|
||||
D(OP_EnvDamage)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_DeleteItem)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_PetCommands)
|
||||
D(OP_BuffRemoveRequest)
|
||||
D(OP_AltCurrencySellSelection)
|
||||
D(OP_AltCurrencySell)
|
||||
D(OP_ZoneChange)
|
||||
D(OP_ZoneEntry)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_BlockedBuffs)
|
||||
D(OP_RemoveBlockedBuffs)
|
||||
D(OP_RecipeAutoCombine)
|
||||
D(OP_GroupInvite)
|
||||
D(OP_GroupInvite2)
|
||||
D(OP_GuildDemote)
|
||||
D(OP_GuildRemove)
|
||||
D(OP_GuildStatus)
|
||||
D(OP_Trader)
|
||||
D(OP_GMLastName)
|
||||
D(OP_InspectRequest)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_ItemVerifyRequest)
|
||||
D(OP_LoadSpellSet)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_PetCommands)
|
||||
D(OP_RaidInvite)
|
||||
D(OP_ReadBook)
|
||||
D(OP_RecipeAutoCombine)
|
||||
D(OP_RemoveBlockedBuffs)
|
||||
D(OP_RezzAnswer)
|
||||
D(OP_Save)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_ShopRequest)
|
||||
D(OP_Trader)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
D(OP_WhoAllRequest)
|
||||
D(OP_ZoneChange)
|
||||
D(OP_ZoneEntry)
|
||||
#undef E
|
||||
#undef D
|
||||
|
||||
@ -712,7 +712,8 @@ struct SpellBuffFade_Struct_Live {
|
||||
/*012*/ uint32 spellid;
|
||||
/*016*/ uint32 duration;
|
||||
/*020*/ uint32 playerId; // Global player ID?
|
||||
/*024*/ uint8 unknown0028[68];
|
||||
/*024*/ uint32 num_hits;
|
||||
/*028*/ uint8 unknown0028[64];
|
||||
/*092*/ uint32 slotid;
|
||||
/*096*/ uint32 bufffade;
|
||||
/*100*/
|
||||
@ -726,7 +727,7 @@ struct SpellBuffFade_Struct {
|
||||
/*007*/ uint8 unknown7;
|
||||
/*008*/ uint32 spellid;
|
||||
/*012*/ uint32 duration;
|
||||
/*016*/ uint32 unknown016;
|
||||
/*016*/ uint32 num_hits;
|
||||
/*020*/ uint32 unknown020; // Global player ID?
|
||||
/*024*/ uint32 playerId; // Player id who cast the buff
|
||||
/*028*/ uint32 slotid;
|
||||
@ -741,6 +742,27 @@ struct BuffRemoveRequest_Struct
|
||||
/*08*/
|
||||
};
|
||||
|
||||
#if 0
|
||||
// not in use
|
||||
struct BuffIconEntry_Struct {
|
||||
/*000*/ uint32 buff_slot;
|
||||
/*004*/ uint32 spell_id;
|
||||
/*008*/ uint32 tics_remaining;
|
||||
/*012*/ uint32 num_hits;
|
||||
// char name[0]; caster name is also here sometimes
|
||||
// uint8 unknownend; 1 when single, 0 when all opposite of all_buffs?
|
||||
};
|
||||
|
||||
// not in use
|
||||
struct BuffIcon_Struct {
|
||||
/*000*/ uint32 entity_id;
|
||||
/*004*/ uint32 unknown004;
|
||||
/*008*/ uint8 all_buffs; // 1 when updating all buffs, 0 when doing one
|
||||
/*009*/ uint16 count;
|
||||
/*011*/ BuffIconEntry_Struct entires[0];
|
||||
};
|
||||
#endif
|
||||
|
||||
struct GMTrainee_Struct
|
||||
{
|
||||
/*000*/ uint32 npcid;
|
||||
@ -893,14 +915,62 @@ struct PotionBelt_Struct {
|
||||
BandolierItem_Struct items[MAX_POTIONS_IN_BELT];
|
||||
};
|
||||
|
||||
struct LeadershipAA_Struct {
|
||||
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
|
||||
};
|
||||
struct GroupLeadershipAA_Struct {
|
||||
uint32 ranks[MAX_GROUP_LEADERSHIP_AA_ARRAY];
|
||||
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 {
|
||||
uint32 ranks[MAX_RAID_LEADERSHIP_AA_ARRAY];
|
||||
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 {
|
||||
GroupLeadershipAA_Struct group;
|
||||
RaidLeadershipAA_Struct raid;
|
||||
};
|
||||
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1678,7 +1748,7 @@ struct BulkItemPacket_Struct
|
||||
|
||||
struct Consume_Struct
|
||||
{
|
||||
/*000*/ ItemSlotStruct slot;
|
||||
/*000*/ ItemSlotStruct slot;
|
||||
/*012*/ uint32 auto_consumed; // 0xffffffff when auto eating e7030000 when right click
|
||||
/*016*/ uint32 type; // 0x01=Food 0x02=Water
|
||||
/*020*/ uint32 c_unknown1; // Seen 2
|
||||
@ -1711,17 +1781,17 @@ struct ItemProperties_Struct {
|
||||
};
|
||||
|
||||
struct DeleteItem_Struct {
|
||||
/*0000*/ ItemSlotStruct from_slot;
|
||||
/*0004*/ ItemSlotStruct to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
/*0000*/ ItemSlotStruct from_slot;
|
||||
/*0012*/ ItemSlotStruct to_slot;
|
||||
/*0024*/ uint32 number_in_stack;
|
||||
/*0028*/
|
||||
};
|
||||
|
||||
struct MoveItem_Struct {
|
||||
/*0000*/ ItemSlotStruct from_slot;
|
||||
/*0004*/ ItemSlotStruct to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
/*0000*/ ItemSlotStruct from_slot;
|
||||
/*0012*/ ItemSlotStruct to_slot;
|
||||
/*0024*/ uint32 number_in_stack;
|
||||
/*0028*/
|
||||
};
|
||||
|
||||
//
|
||||
@ -2045,7 +2115,7 @@ struct Merchant_Sell_Struct {
|
||||
|
||||
struct Merchant_Purchase_Struct {
|
||||
/*000*/ uint32 npcid; // Merchant NPC's entity id
|
||||
/*004*/ MainInvItemSlotStruct itemslot;
|
||||
/*004*/ MainInvItemSlotStruct itemslot;
|
||||
/*012*/ uint32 quantity;
|
||||
/*016*/ uint32 price;
|
||||
/*020*/
|
||||
@ -2403,6 +2473,11 @@ struct GroupFollow_Struct { // Live Follow Struct
|
||||
/*0152*/
|
||||
};
|
||||
|
||||
struct InspectBuffs_Struct {
|
||||
/*000*/ uint32 spell_id[BUFF_COUNT];
|
||||
/*168*/ uint32 tics_remaining[BUFF_COUNT];
|
||||
};
|
||||
|
||||
struct LFG_Struct {
|
||||
/*000*/ uint32 unknown000;
|
||||
/*004*/ uint32 value; // 0x00 = off 0x01 = on
|
||||
@ -3488,10 +3563,10 @@ struct TributeInfo_Struct {
|
||||
|
||||
struct TributeItem_Struct
|
||||
{
|
||||
/*00*/ ItemSlotStruct slot;
|
||||
/*12*/ uint32 quantity;
|
||||
/*16*/ uint32 tribute_master_id;
|
||||
/*20*/ int32 tribute_points;
|
||||
/*00*/ ItemSlotStruct slot;
|
||||
/*12*/ uint32 quantity;
|
||||
/*16*/ uint32 tribute_master_id;
|
||||
/*20*/ int32 tribute_points;
|
||||
/*24*/
|
||||
};
|
||||
|
||||
@ -3527,7 +3602,7 @@ struct Split_Struct
|
||||
*/
|
||||
struct NewCombine_Struct {
|
||||
/*00*/ ItemSlotStruct container_slot;
|
||||
/*12*/ ItemSlotStruct unknown_slot; // Slot type is 8?
|
||||
/*12*/ ItemSlotStruct guildtribute_slot; // Slot type is 8? (MapGuildTribute = 8 -U)
|
||||
/*24*/
|
||||
};
|
||||
|
||||
@ -3972,6 +4047,21 @@ struct RaidAddMember_Struct {
|
||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||
};
|
||||
|
||||
struct RaidMOTD_Struct {
|
||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
||||
};
|
||||
|
||||
struct RaidLeadershipUpdate_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ char player_name[64];
|
||||
/*068*/ uint32 Unknown068;
|
||||
/*072*/ char leader_name[64];
|
||||
/*136*/ GroupLeadershipAA_Struct group; //unneeded
|
||||
/*200*/ RaidLeadershipAA_Struct raid;
|
||||
/*264*/ char Unknown264[128];
|
||||
};
|
||||
|
||||
struct RaidAdd_Struct {
|
||||
/*000*/ uint32 action; //=0
|
||||
/*004*/ char player_name[64]; //should both be the player's name
|
||||
@ -4106,7 +4196,7 @@ struct GMToggle_Struct {
|
||||
uint32 toggle;
|
||||
};
|
||||
|
||||
struct BuffFadeMsg_Struct {
|
||||
struct ColoredText_Struct {
|
||||
uint32 color;
|
||||
char msg[1]; //was 1
|
||||
/*0???*/ uint8 paddingXXX[3]; // always 0's
|
||||
@ -4585,9 +4675,9 @@ struct ItemQuaternaryBodyStruct
|
||||
|
||||
struct AugmentInfo_Struct
|
||||
{
|
||||
/*000*/ uint32 itemid; // id of the solvent needed
|
||||
/*004*/ uint8 window; // window to display the information in
|
||||
/*005*/ uint8 unknown005[71]; // total packet length 76, all the rest were always 00
|
||||
/*000*/ uint32 itemid; // id of the solvent needed
|
||||
/*004*/ uint8 window; // window to display the information in
|
||||
/*005*/ uint8 unknown005[71]; // total packet length 76, all the rest were always 00
|
||||
/*076*/
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#ifndef SoD_CONSTANTS_H_
|
||||
#define SoD_CONSTANTS_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../types.h"
|
||||
|
||||
namespace SoD {
|
||||
namespace maps {
|
||||
@ -181,6 +181,7 @@ namespace SoD {
|
||||
|
||||
namespace limits {
|
||||
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
||||
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
|
||||
static const bool COIN_HAS_WEIGHT = false;
|
||||
}
|
||||
|
||||
|
||||
@ -1,117 +1,115 @@
|
||||
|
||||
//list of packets we need to encode on the way out:
|
||||
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_ZoneServerInfo)
|
||||
E(OP_SendAATable)
|
||||
E(OP_PlayerProfile)
|
||||
E(OP_ZoneEntry)
|
||||
E(OP_CharInventory)
|
||||
E(OP_NewZone)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_GroundSpawn)
|
||||
E(OP_SendZonepoints)
|
||||
E(OP_NewSpawn)
|
||||
E(OP_ZoneSpawns)
|
||||
E(OP_ItemLinkResponse)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_Illusion)
|
||||
E(OP_ManaChange)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_LeadershipExpUpdate)
|
||||
E(OP_ExpansionInfo)
|
||||
E(OP_LogServer)
|
||||
E(OP_Damage)
|
||||
E(OP_Buff)
|
||||
// out-going packets that require an ENCODE translation:
|
||||
E(OP_Action)
|
||||
E(OP_Consider)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_DeleteItem)
|
||||
E(OP_ItemVerifyReply)
|
||||
E(OP_DeleteCharge)
|
||||
E(OP_MoveItem)
|
||||
E(OP_OpenNewTasksWindow)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_LootItem)
|
||||
E(OP_TributeItem)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_ReadBook)
|
||||
E(OP_Stun)
|
||||
E(OP_ZonePlayerToBind)
|
||||
E(OP_AdventureMerchantSell)
|
||||
E(OP_RaidUpdate)
|
||||
E(OP_RaidJoin)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_InspectRequest)
|
||||
E(OP_GroupInvite)
|
||||
E(OP_GroupFollow)
|
||||
E(OP_GroupFollow2)
|
||||
E(OP_GroupUpdate)
|
||||
E(OP_GroupCancelInvite)
|
||||
E(OP_WhoAllResponse)
|
||||
E(OP_Track)
|
||||
E(OP_ShopPlayerBuy)
|
||||
E(OP_PetBuffWindow)
|
||||
E(OP_OnLevelMessage)
|
||||
E(OP_Barter)
|
||||
E(OP_AltCurrencySell)
|
||||
E(OP_ApplyPoison)
|
||||
E(OP_Barter)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_Buff)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_CharInventory)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_Consider)
|
||||
E(OP_Damage)
|
||||
E(OP_DeleteCharge)
|
||||
E(OP_DeleteItem)
|
||||
E(OP_DzCompass)
|
||||
E(OP_DzExpeditionEndsWarning)
|
||||
E(OP_DzExpeditionInfo)
|
||||
E(OP_DzCompass)
|
||||
E(OP_DzMemberList)
|
||||
E(OP_DzExpeditionList)
|
||||
E(OP_DzLeaderStatus)
|
||||
E(OP_DzJoinExpeditionConfirm)
|
||||
E(OP_TargetBuffs)
|
||||
E(OP_AltCurrencySell)
|
||||
E(OP_WearChange)
|
||||
E(OP_DzLeaderStatus)
|
||||
E(OP_DzMemberList)
|
||||
E(OP_ExpansionInfo)
|
||||
E(OP_GroundSpawn)
|
||||
E(OP_GroupCancelInvite)
|
||||
E(OP_GroupFollow)
|
||||
E(OP_GroupFollow2)
|
||||
E(OP_GroupInvite)
|
||||
E(OP_GroupUpdate)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_Illusion)
|
||||
E(OP_InspectRequest)
|
||||
E(OP_ItemLinkResponse)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_ItemVerifyReply)
|
||||
E(OP_LeadershipExpUpdate)
|
||||
E(OP_LogServer)
|
||||
E(OP_LootItem)
|
||||
E(OP_ManaChange)
|
||||
E(OP_MercenaryDataResponse)
|
||||
E(OP_MercenaryDataUpdate)
|
||||
//list of packets we need to decode on the way in:
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_ConsiderCorpse)
|
||||
D(OP_Consider)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_MoveItem)
|
||||
D(OP_WhoAllRequest)
|
||||
E(OP_MoveItem)
|
||||
E(OP_NewSpawn)
|
||||
E(OP_NewZone)
|
||||
E(OP_OnLevelMessage)
|
||||
E(OP_OpenNewTasksWindow)
|
||||
E(OP_PetBuffWindow)
|
||||
E(OP_PlayerProfile)
|
||||
E(OP_RaidJoin)
|
||||
E(OP_RaidUpdate)
|
||||
E(OP_ReadBook)
|
||||
E(OP_SendAATable)
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_SendZonepoints)
|
||||
E(OP_ShopPlayerBuy)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_Stun)
|
||||
E(OP_TargetBuffs)
|
||||
E(OP_Track)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_TributeItem)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_WearChange)
|
||||
E(OP_WhoAllResponse)
|
||||
E(OP_ZoneEntry)
|
||||
E(OP_ZonePlayerToBind)
|
||||
E(OP_ZoneServerInfo)
|
||||
E(OP_ZoneSpawns)
|
||||
// incoming packets that require a DECODE translation:
|
||||
D(OP_AdventureMerchantSell)
|
||||
D(OP_AltCurrencySell)
|
||||
D(OP_AltCurrencySellSelection)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_BazaarSearch)
|
||||
D(OP_Buff)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_Consume)
|
||||
D(OP_Bug)
|
||||
D(OP_CastSpell)
|
||||
D(OP_Save)
|
||||
D(OP_ItemVerifyRequest)
|
||||
D(OP_GroupInvite)
|
||||
D(OP_GroupInvite2)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_Consider)
|
||||
D(OP_ConsiderCorpse)
|
||||
D(OP_Consume)
|
||||
D(OP_DeleteItem)
|
||||
D(OP_FaceChange)
|
||||
D(OP_FindPersonRequest)
|
||||
D(OP_GroupCancelInvite)
|
||||
D(OP_GroupDisband)
|
||||
D(OP_GroupFollow)
|
||||
D(OP_GroupFollow2)
|
||||
D(OP_GroupDisband)
|
||||
D(OP_GroupCancelInvite)
|
||||
D(OP_FindPersonRequest)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_LootItem)
|
||||
D(OP_TributeItem)
|
||||
D(OP_ReadBook)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_FaceChange)
|
||||
D(OP_AdventureMerchantSell)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_RaidInvite)
|
||||
D(OP_GroupInvite)
|
||||
D(OP_GroupInvite2)
|
||||
D(OP_InspectRequest)
|
||||
D(OP_WearChange)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_BazaarSearch)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_ItemVerifyRequest)
|
||||
D(OP_LoadSpellSet)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_DeleteItem)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_Bug)
|
||||
D(OP_AltCurrencySellSelection)
|
||||
D(OP_AltCurrencySell)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_RaidInvite)
|
||||
D(OP_ReadBook)
|
||||
D(OP_Save)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
D(OP_WearChange)
|
||||
D(OP_WhoAllRequest)
|
||||
#undef E
|
||||
#undef D
|
||||
|
||||
@ -519,7 +519,7 @@ struct CastSpell_Struct
|
||||
uint32 spell_id;
|
||||
uint32 inventoryslot; // slot for clicky item, 0xFFFF = normal cast
|
||||
uint32 target_id;
|
||||
uint8 cs_unknown[4];
|
||||
uint8 cs_unknown[4];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -711,14 +711,62 @@ struct PotionBelt_Struct {
|
||||
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_RAID_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_LEADERSHIP_AA_ARRAY = (MAX_GROUP_LEADERSHIP_AA_ARRAY+MAX_RAID_LEADERSHIP_AA_ARRAY);
|
||||
struct LeadershipAA_Struct {
|
||||
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
|
||||
};
|
||||
struct GroupLeadershipAA_Struct {
|
||||
uint32 ranks[MAX_GROUP_LEADERSHIP_AA_ARRAY];
|
||||
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 {
|
||||
uint32 ranks[MAX_RAID_LEADERSHIP_AA_ARRAY];
|
||||
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 {
|
||||
GroupLeadershipAA_Struct group;
|
||||
RaidLeadershipAA_Struct raid;
|
||||
};
|
||||
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1469,11 +1517,11 @@ struct BulkItemPacket_Struct
|
||||
|
||||
struct Consume_Struct
|
||||
{
|
||||
/*0000*/ uint32 slot;
|
||||
/*0004*/ uint32 auto_consumed; // 0xffffffff when auto eating e7030000 when right click
|
||||
/*0008*/ uint8 c_unknown1[4];
|
||||
/*0012*/ uint8 type; // 0x01=Food 0x02=Water
|
||||
/*0013*/ uint8 unknown13[3];
|
||||
/*0000*/ uint32 slot;
|
||||
/*0004*/ uint32 auto_consumed; // 0xffffffff when auto eating e7030000 when right click
|
||||
/*0008*/ uint8 c_unknown1[4];
|
||||
/*0012*/ uint8 type; // 0x01=Food 0x02=Water
|
||||
/*0013*/ uint8 unknown13[3];
|
||||
/*0016*/
|
||||
};
|
||||
|
||||
@ -1503,17 +1551,17 @@ struct ItemProperties_Struct {
|
||||
};
|
||||
|
||||
struct DeleteItem_Struct {
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
struct MoveItem_Struct
|
||||
{
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
@ -3090,10 +3138,10 @@ struct TributeInfo_Struct {
|
||||
};
|
||||
|
||||
struct TributeItem_Struct {
|
||||
uint32 slot;
|
||||
uint32 quantity;
|
||||
uint32 tribute_master_id;
|
||||
int32 tribute_points;
|
||||
uint32 slot;
|
||||
uint32 quantity;
|
||||
uint32 tribute_master_id;
|
||||
int32 tribute_points;
|
||||
};
|
||||
|
||||
struct TributePoint_Struct {
|
||||
@ -3129,7 +3177,7 @@ struct Split_Struct
|
||||
*/
|
||||
struct NewCombine_Struct {
|
||||
/*00*/ int16 container_slot;
|
||||
/*02*/ char unknown02[2];
|
||||
/*02*/ int16 guildtribute_slot;
|
||||
/*04*/
|
||||
};
|
||||
|
||||
@ -3562,6 +3610,21 @@ struct RaidAddMember_Struct {
|
||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||
};
|
||||
|
||||
struct RaidMOTD_Struct {
|
||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
||||
};
|
||||
|
||||
struct RaidLeadershipUpdate_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ char player_name[64];
|
||||
/*068*/ uint32 Unknown068;
|
||||
/*072*/ char leader_name[64];
|
||||
/*136*/ GroupLeadershipAA_Struct group; //unneeded
|
||||
/*200*/ RaidLeadershipAA_Struct raid;
|
||||
/*264*/ char Unknown264[128];
|
||||
};
|
||||
|
||||
struct RaidAdd_Struct {
|
||||
/*000*/ uint32 action; //=0
|
||||
/*004*/ char player_name[64]; //should both be the player's name
|
||||
@ -3693,7 +3756,7 @@ struct GMToggle_Struct {
|
||||
uint32 toggle;
|
||||
};
|
||||
|
||||
struct BuffFadeMsg_Struct {
|
||||
struct ColoredText_Struct {
|
||||
uint32 color;
|
||||
char msg[1]; //was 1
|
||||
/*0???*/ uint8 paddingXXX[3]; // always 0's
|
||||
@ -4109,9 +4172,9 @@ struct ItemQuaternaryBodyStruct
|
||||
|
||||
struct AugmentInfo_Struct
|
||||
{
|
||||
/*000*/ uint32 itemid; // id of the solvent needed
|
||||
/*004*/ uint8 window; // window to display the information in
|
||||
/*005*/ uint8 unknown005[71]; // total packet length 76, all the rest were always 00
|
||||
/*000*/ uint32 itemid; // id of the solvent needed
|
||||
/*004*/ uint8 window; // window to display the information in
|
||||
/*005*/ uint8 unknown005[71]; // total packet length 76, all the rest were always 00
|
||||
/*076*/
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#ifndef SoF_CONSTANTS_H_
|
||||
#define SoF_CONSTANTS_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../types.h"
|
||||
|
||||
namespace SoF {
|
||||
namespace maps {
|
||||
@ -181,6 +181,7 @@ namespace SoF {
|
||||
|
||||
namespace limits {
|
||||
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
||||
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
|
||||
static const bool COIN_HAS_WEIGHT = true;
|
||||
}
|
||||
|
||||
|
||||
@ -187,7 +187,7 @@
|
||||
0x1ee9,
|
||||
0x7f5d, OP_CastSpell
|
||||
0x0659, OP_ManaChange
|
||||
0x3bc7, OP_BuffFadeMsg
|
||||
0x3bc7, OP_ColoredText
|
||||
0x3209,
|
||||
0x6a93, OP_MemorizeSpell
|
||||
0x1237,
|
||||
|
||||
@ -1,100 +1,98 @@
|
||||
|
||||
//list of packets we need to encode on the way out:
|
||||
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_ZoneServerInfo)
|
||||
E(OP_SendAATable)
|
||||
E(OP_PlayerProfile)
|
||||
E(OP_ZoneEntry)
|
||||
E(OP_CharInventory)
|
||||
E(OP_NewZone)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_GroundSpawn)
|
||||
E(OP_SendZonepoints)
|
||||
E(OP_NewSpawn)
|
||||
E(OP_ZoneSpawns)
|
||||
E(OP_ItemLinkResponse)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_Illusion)
|
||||
E(OP_ManaChange)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_LeadershipExpUpdate)
|
||||
E(OP_ExpansionInfo)
|
||||
E(OP_LogServer)
|
||||
E(OP_Damage)
|
||||
E(OP_Buff)
|
||||
// out-going packets that require an ENCODE translation:
|
||||
E(OP_Action)
|
||||
E(OP_Consider)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_DeleteItem)
|
||||
E(OP_ItemVerifyReply)
|
||||
E(OP_DeleteCharge)
|
||||
E(OP_MoveItem)
|
||||
E(OP_OpenNewTasksWindow)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_LootItem)
|
||||
E(OP_TributeItem)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_ReadBook)
|
||||
E(OP_Stun)
|
||||
E(OP_ZonePlayerToBind)
|
||||
E(OP_AdventureMerchantSell)
|
||||
E(OP_RaidUpdate)
|
||||
E(OP_RaidJoin)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_InspectRequest)
|
||||
E(OP_Track)
|
||||
E(OP_DeleteSpawn)
|
||||
E(OP_AltCurrencySell)
|
||||
E(OP_ApplyPoison)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_BecomeTrader)
|
||||
E(OP_Buff)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_CharInventory)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_Consider)
|
||||
E(OP_Damage)
|
||||
E(OP_DeleteCharge)
|
||||
E(OP_DeleteItem)
|
||||
E(OP_DeleteSpawn)
|
||||
E(OP_DzCompass)
|
||||
E(OP_DzExpeditionEndsWarning)
|
||||
E(OP_DzExpeditionInfo)
|
||||
E(OP_DzCompass)
|
||||
E(OP_DzMemberList)
|
||||
E(OP_DzExpeditionList)
|
||||
E(OP_DzLeaderStatus)
|
||||
E(OP_DzJoinExpeditionConfirm)
|
||||
E(OP_BecomeTrader)
|
||||
E(OP_PetBuffWindow)
|
||||
E(OP_DzLeaderStatus)
|
||||
E(OP_DzMemberList)
|
||||
E(OP_ExpansionInfo)
|
||||
E(OP_GroundSpawn)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_Illusion)
|
||||
E(OP_InspectRequest)
|
||||
E(OP_ItemLinkResponse)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_ItemVerifyReply)
|
||||
E(OP_LeadershipExpUpdate)
|
||||
E(OP_LogServer)
|
||||
E(OP_LootItem)
|
||||
E(OP_ManaChange)
|
||||
E(OP_MoveItem)
|
||||
E(OP_NewSpawn)
|
||||
E(OP_NewZone)
|
||||
E(OP_OnLevelMessage)
|
||||
E(OP_AltCurrencySell)
|
||||
E(OP_OpenNewTasksWindow)
|
||||
E(OP_PetBuffWindow)
|
||||
E(OP_PlayerProfile)
|
||||
E(OP_RaidJoin)
|
||||
E(OP_RaidUpdate)
|
||||
E(OP_ReadBook)
|
||||
E(OP_SendAATable)
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_SendZonepoints)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_Stun)
|
||||
E(OP_Track)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_TributeItem)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_WearChange)
|
||||
//list of packets we need to decode on the way in:
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_ConsiderCorpse)
|
||||
D(OP_Consider)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_MoveItem)
|
||||
D(OP_WhoAllRequest)
|
||||
E(OP_ZoneEntry)
|
||||
E(OP_ZonePlayerToBind)
|
||||
E(OP_ZoneServerInfo)
|
||||
E(OP_ZoneSpawns)
|
||||
// incoming packets that require a DECODE translation:
|
||||
D(OP_AdventureMerchantSell)
|
||||
D(OP_AltCurrencySell)
|
||||
D(OP_AltCurrencySellSelection)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_Buff)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_Consume)
|
||||
D(OP_CastSpell)
|
||||
D(OP_Save)
|
||||
D(OP_ItemVerifyRequest)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_Consider)
|
||||
D(OP_ConsiderCorpse)
|
||||
D(OP_Consume)
|
||||
D(OP_DeleteItem)
|
||||
D(OP_FaceChange)
|
||||
D(OP_FindPersonRequest)
|
||||
D(OP_GroupFollow)
|
||||
D(OP_GroupFollow2)
|
||||
D(OP_FindPersonRequest)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_LootItem)
|
||||
D(OP_TributeItem)
|
||||
D(OP_ReadBook)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_FaceChange)
|
||||
D(OP_AdventureMerchantSell)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_RaidInvite)
|
||||
D(OP_InspectRequest)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_ItemVerifyRequest)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_RaidInvite)
|
||||
D(OP_ReadBook)
|
||||
D(OP_Save)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
D(OP_WearChange)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_DeleteItem)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_AltCurrencySellSelection)
|
||||
D(OP_AltCurrencySell)
|
||||
D(OP_WhoAllRequest)
|
||||
#undef E
|
||||
#undef D
|
||||
|
||||
@ -497,7 +497,7 @@ struct CastSpell_Struct
|
||||
uint32 spell_id;
|
||||
uint32 inventoryslot; // slot for clicky item, 0xFFFF = normal cast
|
||||
uint32 target_id;
|
||||
uint8 cs_unknown[4];
|
||||
uint8 cs_unknown[4];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -689,14 +689,62 @@ struct PotionBelt_Struct {
|
||||
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_RAID_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_LEADERSHIP_AA_ARRAY = (MAX_GROUP_LEADERSHIP_AA_ARRAY+MAX_RAID_LEADERSHIP_AA_ARRAY);
|
||||
struct LeadershipAA_Struct {
|
||||
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
|
||||
};
|
||||
struct GroupLeadershipAA_Struct {
|
||||
uint32 ranks[MAX_GROUP_LEADERSHIP_AA_ARRAY];
|
||||
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 {
|
||||
uint32 ranks[MAX_RAID_LEADERSHIP_AA_ARRAY];
|
||||
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 {
|
||||
GroupLeadershipAA_Struct group;
|
||||
RaidLeadershipAA_Struct raid;
|
||||
};
|
||||
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1445,11 +1493,11 @@ struct BulkItemPacket_Struct
|
||||
|
||||
struct Consume_Struct
|
||||
{
|
||||
/*0000*/ uint32 slot;
|
||||
/*0004*/ uint32 auto_consumed; // 0xffffffff when auto eating e7030000 when right click
|
||||
/*0008*/ uint8 c_unknown1[4];
|
||||
/*0012*/ uint8 type; // 0x01=Food 0x02=Water
|
||||
/*0013*/ uint8 unknown13[3];
|
||||
/*0000*/ uint32 slot;
|
||||
/*0004*/ uint32 auto_consumed; // 0xffffffff when auto eating e7030000 when right click
|
||||
/*0008*/ uint8 c_unknown1[4];
|
||||
/*0012*/ uint8 type; // 0x01=Food 0x02=Water
|
||||
/*0013*/ uint8 unknown13[3];
|
||||
/*0016*/
|
||||
};
|
||||
|
||||
@ -1479,17 +1527,17 @@ struct ItemProperties_Struct {
|
||||
};
|
||||
|
||||
struct DeleteItem_Struct {
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
struct MoveItem_Struct
|
||||
{
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
@ -2953,10 +3001,10 @@ struct TributeInfo_Struct {
|
||||
};
|
||||
|
||||
struct TributeItem_Struct {
|
||||
uint32 slot;
|
||||
uint32 quantity;
|
||||
uint32 tribute_master_id;
|
||||
int32 tribute_points;
|
||||
uint32 slot;
|
||||
uint32 quantity;
|
||||
uint32 tribute_master_id;
|
||||
int32 tribute_points;
|
||||
};
|
||||
|
||||
struct TributePoint_Struct {
|
||||
@ -2992,7 +3040,7 @@ struct Split_Struct
|
||||
*/
|
||||
struct NewCombine_Struct {
|
||||
/*00*/ int16 container_slot;
|
||||
/*02*/ char unknown02[2];
|
||||
/*02*/ int16 guildtribute_slot;
|
||||
/*04*/
|
||||
};
|
||||
|
||||
@ -3425,6 +3473,21 @@ struct RaidAddMember_Struct {
|
||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||
};
|
||||
|
||||
struct RaidMOTD_Struct {
|
||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
||||
};
|
||||
|
||||
struct RaidLeadershipUpdate_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ char player_name[64];
|
||||
/*068*/ uint32 Unknown068;
|
||||
/*072*/ char leader_name[64];
|
||||
/*136*/ GroupLeadershipAA_Struct group; //unneeded
|
||||
/*200*/ RaidLeadershipAA_Struct raid;
|
||||
/*264*/ char Unknown264[128];
|
||||
};
|
||||
|
||||
struct RaidAdd_Struct {
|
||||
/*000*/ uint32 action; //=0
|
||||
/*004*/ char player_name[64]; //should both be the player's name
|
||||
@ -3556,7 +3619,7 @@ struct GMToggle_Struct {
|
||||
uint32 toggle;
|
||||
};
|
||||
|
||||
struct BuffFadeMsg_Struct {
|
||||
struct ColoredText_Struct {
|
||||
uint32 color;
|
||||
char msg[1]; //was 1
|
||||
/*0???*/ uint8 paddingXXX[3]; // always 0's
|
||||
@ -3963,9 +4026,9 @@ struct ItemQuaternaryBodyStruct
|
||||
|
||||
struct AugmentInfo_Struct
|
||||
{
|
||||
/*000*/ uint32 itemid; // id of the solvent needed
|
||||
/*004*/ uint8 window; // window to display the information in
|
||||
/*005*/ uint8 unknown005[71]; // total packet length 76, all the rest were always 00
|
||||
/*000*/ uint32 itemid; // id of the solvent needed
|
||||
/*004*/ uint8 window; // window to display the information in
|
||||
/*005*/ uint8 unknown005[71]; // total packet length 76, all the rest were always 00
|
||||
/*076*/
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#ifndef Titanium_CONSTANTS_H_
|
||||
#define Titanium_CONSTANTS_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../types.h"
|
||||
|
||||
namespace Titanium {
|
||||
namespace maps {
|
||||
@ -180,6 +180,7 @@ namespace Titanium {
|
||||
|
||||
namespace limits {
|
||||
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
||||
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
|
||||
static const bool COIN_HAS_WEIGHT = true;
|
||||
}
|
||||
|
||||
|
||||
@ -1,53 +1,71 @@
|
||||
|
||||
//list of packets we need to encode on the way out:
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_SendAATable)
|
||||
E(OP_LeadershipExpUpdate)
|
||||
E(OP_PlayerProfile)
|
||||
E(OP_NewSpawn)
|
||||
E(OP_ZoneSpawns)
|
||||
E(OP_ZoneEntry)
|
||||
E(OP_CharInventory)
|
||||
E(OP_ItemLinkResponse)
|
||||
E(OP_ItemPacket)
|
||||
// out-going packets that require an ENCODE translation:
|
||||
E(OP_Action)
|
||||
E(OP_AdventureMerchantSell)
|
||||
E(OP_ApplyPoison)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_ZoneServerReady)
|
||||
E(OP_GuildMemberLevelUpdate)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_ReadBook)
|
||||
E(OP_Illusion)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_InspectRequest)
|
||||
E(OP_InspectAnswer)
|
||||
E(OP_Track)
|
||||
E(OP_RespondAA)
|
||||
E(OP_BecomeTrader)
|
||||
E(OP_CharInventory)
|
||||
E(OP_DeleteCharge)
|
||||
E(OP_DeleteItem)
|
||||
E(OP_DeleteSpawn)
|
||||
E(OP_WearChange)
|
||||
E(OP_DzCompass)
|
||||
E(OP_DzExpeditionEndsWarning)
|
||||
E(OP_DzExpeditionInfo)
|
||||
E(OP_DzCompass)
|
||||
E(OP_DzMemberList)
|
||||
E(OP_DzExpeditionList)
|
||||
E(OP_DzLeaderStatus)
|
||||
E(OP_DzJoinExpeditionConfirm)
|
||||
E(OP_Action)
|
||||
E(OP_BecomeTrader)
|
||||
E(OP_PetBuffWindow)
|
||||
E(OP_OnLevelMessage)
|
||||
E(OP_DzLeaderStatus)
|
||||
E(OP_DzMemberList)
|
||||
E(OP_GuildMemberLevelUpdate)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_Illusion)
|
||||
E(OP_InspectAnswer)
|
||||
E(OP_InspectRequest)
|
||||
E(OP_ItemLinkResponse)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_LeadershipExpUpdate)
|
||||
E(OP_LFGuild)
|
||||
//list of packets we need to decode on the way in:
|
||||
D(OP_SetServerFilter)
|
||||
E(OP_LootItem)
|
||||
E(OP_MoveItem)
|
||||
E(OP_OnLevelMessage)
|
||||
E(OP_PetBuffWindow)
|
||||
E(OP_PlayerProfile)
|
||||
E(OP_NewSpawn)
|
||||
E(OP_ReadBook)
|
||||
E(OP_RespondAA)
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_SendAATable)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_Track)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_TributeItem)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_WearChange)
|
||||
E(OP_ZoneEntry)
|
||||
E(OP_ZoneServerReady)
|
||||
E(OP_ZoneSpawns)
|
||||
// incoming packets that require a DECODE translation:
|
||||
D(OP_AdventureMerchantSell)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_CastSpell)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_WhoAllRequest)
|
||||
D(OP_ReadBook)
|
||||
D(OP_Consume)
|
||||
D(OP_DeleteItem)
|
||||
D(OP_FaceChange)
|
||||
D(OP_InspectRequest)
|
||||
D(OP_InspectAnswer)
|
||||
D(OP_WearChange)
|
||||
D(OP_InspectRequest)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_LFGuild)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_ReadBook)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
D(OP_WearChange)
|
||||
D(OP_WhoAllRequest)
|
||||
#undef E
|
||||
#undef D
|
||||
|
||||
@ -419,7 +419,7 @@ struct CastSpell_Struct
|
||||
uint32 spell_id;
|
||||
uint32 inventoryslot; // slot for clicky item, 0xFFFF = normal cast
|
||||
uint32 target_id;
|
||||
uint8 cs_unknown[4];
|
||||
uint8 cs_unknown[4];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -565,7 +565,7 @@ struct CharCreate_Struct
|
||||
/*0064*/ uint32 face; // Could be unknown0076
|
||||
/*0068*/ uint32 eyecolor1; //its possiable we could have these switched
|
||||
/*0073*/ uint32 eyecolor2; //since setting one sets the other we really can't check
|
||||
/*0076*/ uint32 unknown0076; // Could be face
|
||||
/*0076*/ uint32 tutorial;
|
||||
/*0080*/
|
||||
};
|
||||
|
||||
@ -619,14 +619,62 @@ struct PotionBelt_Struct {
|
||||
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_RAID_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_LEADERSHIP_AA_ARRAY = (MAX_GROUP_LEADERSHIP_AA_ARRAY+MAX_RAID_LEADERSHIP_AA_ARRAY);
|
||||
struct LeadershipAA_Struct {
|
||||
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
|
||||
};
|
||||
struct GroupLeadershipAA_Struct {
|
||||
uint32 ranks[MAX_GROUP_LEADERSHIP_AA_ARRAY];
|
||||
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 {
|
||||
uint32 ranks[MAX_RAID_LEADERSHIP_AA_ARRAY];
|
||||
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 {
|
||||
GroupLeadershipAA_Struct group;
|
||||
RaidLeadershipAA_Struct raid;
|
||||
};
|
||||
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1217,19 +1265,27 @@ struct BulkItemPacket_Struct
|
||||
|
||||
struct Consume_Struct
|
||||
{
|
||||
/*0000*/ uint32 slot;
|
||||
/*0004*/ uint32 auto_consumed; // 0xffffffff when auto eating e7030000 when right click
|
||||
/*0008*/ uint8 c_unknown1[4];
|
||||
/*0012*/ uint8 type; // 0x01=Food 0x02=Water
|
||||
/*0013*/ uint8 unknown13[3];
|
||||
/*0000*/ uint32 slot;
|
||||
/*0004*/ uint32 auto_consumed; // 0xffffffff when auto eating e7030000 when right click
|
||||
/*0008*/ uint8 c_unknown1[4];
|
||||
/*0012*/ uint8 type; // 0x01=Food 0x02=Water
|
||||
/*0013*/ uint8 unknown13[3];
|
||||
};
|
||||
|
||||
struct DeleteItem_Struct
|
||||
{
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
struct MoveItem_Struct
|
||||
{
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
//
|
||||
@ -1431,12 +1487,6 @@ struct CombatAbility_Struct {
|
||||
uint32 m_skill;
|
||||
};
|
||||
|
||||
struct DeleteItem_Struct {
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
};
|
||||
|
||||
//Instill Doubt
|
||||
struct Instill_Doubt_Struct {
|
||||
uint8 i_id;
|
||||
@ -1590,6 +1640,14 @@ struct Adventure_Purchase_Struct {
|
||||
/*008*/ uint32 variable;
|
||||
};
|
||||
|
||||
struct Adventure_Sell_Struct {
|
||||
/*000*/ uint32 unknown000; //0x01
|
||||
/*004*/ uint32 npcid;
|
||||
/*008*/ uint32 slot;
|
||||
/*012*/ uint32 charges;
|
||||
/*016*/ uint32 sell_price;
|
||||
};
|
||||
|
||||
struct AdventurePoints_Update_Struct {
|
||||
/*000*/ uint32 ldon_available_points; // Total available points
|
||||
/*004*/ uint8 unkown_apu004[20];
|
||||
@ -2583,10 +2641,10 @@ struct TributeInfo_Struct {
|
||||
};
|
||||
|
||||
struct TributeItem_Struct {
|
||||
uint32 slot;
|
||||
uint32 quantity;
|
||||
uint32 tribute_master_id;
|
||||
int32 tribute_points;
|
||||
uint32 slot;
|
||||
uint32 quantity;
|
||||
uint32 tribute_master_id;
|
||||
int32 tribute_points;
|
||||
};
|
||||
|
||||
struct TributePoint_Struct {
|
||||
@ -2622,7 +2680,7 @@ struct Split_Struct
|
||||
*/
|
||||
struct NewCombine_Struct {
|
||||
/*00*/ int16 container_slot;
|
||||
/*02*/ char unknown02[2];
|
||||
/*02*/ int16 guildtribute_slot;
|
||||
/*04*/
|
||||
};
|
||||
|
||||
@ -3046,7 +3104,7 @@ struct GroupInvite_Struct {
|
||||
// uint8 unknown128[65];
|
||||
};
|
||||
|
||||
struct BuffFadeMsg_Struct {
|
||||
struct ColoredText_Struct {
|
||||
uint32 color;
|
||||
char msg[1];
|
||||
};
|
||||
@ -3154,6 +3212,11 @@ struct AnnoyingZoneUnknown_Struct {
|
||||
uint32 value; //always 4
|
||||
};
|
||||
|
||||
struct ApplyPoison_Struct {
|
||||
uint32 inventorySlot;
|
||||
uint32 success;
|
||||
};
|
||||
|
||||
struct GuildMemberUpdate_Struct {
|
||||
/*000*/ uint32 guild_id; //not sure
|
||||
/*004*/ char member_name[64];
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#ifndef Underfoot_CONSTANTS_H_
|
||||
#define Underfoot_CONSTANTS_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../types.h"
|
||||
|
||||
namespace Underfoot {
|
||||
namespace maps {
|
||||
@ -181,6 +181,7 @@ namespace Underfoot {
|
||||
|
||||
namespace limits {
|
||||
static const bool ALLOWS_EMPTY_BAG_IN_BAG = false;
|
||||
static const bool ALLOWS_CLICK_CAST_FROM_BAG = false;
|
||||
static const bool COIN_HAS_WEIGHT = false;
|
||||
}
|
||||
|
||||
|
||||
@ -1,128 +1,127 @@
|
||||
|
||||
//list of packets we need to encode on the way out:
|
||||
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_ZoneServerInfo)
|
||||
E(OP_SendAATable)
|
||||
E(OP_PlayerProfile)
|
||||
E(OP_ZoneEntry)
|
||||
E(OP_CharInventory)
|
||||
E(OP_NewZone)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_GroundSpawn)
|
||||
E(OP_SendZonepoints)
|
||||
E(OP_NewSpawn)
|
||||
E(OP_ZoneSpawns)
|
||||
E(OP_ItemLinkResponse)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_Illusion)
|
||||
E(OP_ManaChange)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_LeadershipExpUpdate)
|
||||
E(OP_ExpansionInfo)
|
||||
E(OP_LogServer)
|
||||
E(OP_Damage)
|
||||
E(OP_Buff)
|
||||
// out-going packets that require an ENCODE translation:
|
||||
E(OP_Action)
|
||||
E(OP_Consider)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_DeleteItem)
|
||||
E(OP_ItemVerifyReply)
|
||||
E(OP_DeleteCharge)
|
||||
E(OP_MoveItem)
|
||||
E(OP_OpenNewTasksWindow)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_LootItem)
|
||||
E(OP_TributeItem)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_ReadBook)
|
||||
E(OP_Stun)
|
||||
E(OP_ZonePlayerToBind)
|
||||
E(OP_AdventureMerchantSell)
|
||||
E(OP_RaidUpdate)
|
||||
E(OP_RaidJoin)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_InspectRequest)
|
||||
E(OP_GroupInvite)
|
||||
E(OP_GroupFollow)
|
||||
E(OP_GroupFollow2)
|
||||
E(OP_GroupUpdate)
|
||||
E(OP_GroupCancelInvite)
|
||||
E(OP_WhoAllResponse)
|
||||
E(OP_Track)
|
||||
E(OP_ShopPlayerBuy)
|
||||
E(OP_PetBuffWindow)
|
||||
E(OP_OnLevelMessage)
|
||||
E(OP_Barter)
|
||||
E(OP_AltCurrency)
|
||||
E(OP_AltCurrencySell)
|
||||
E(OP_ApplyPoison)
|
||||
E(OP_Barter)
|
||||
E(OP_BazaarSearch)
|
||||
E(OP_Buff)
|
||||
E(OP_BuffCreate)
|
||||
E(OP_CancelTrade)
|
||||
E(OP_ChannelMessage)
|
||||
E(OP_GuildsList)
|
||||
E(OP_CharInventory)
|
||||
E(OP_ClientUpdate)
|
||||
E(OP_Consider)
|
||||
E(OP_Damage)
|
||||
E(OP_DeleteCharge)
|
||||
E(OP_DeleteItem)
|
||||
E(OP_DisciplineUpdate)
|
||||
E(OP_DzCompass)
|
||||
E(OP_DzExpeditionEndsWarning)
|
||||
E(OP_DzExpeditionInfo)
|
||||
E(OP_DzCompass)
|
||||
E(OP_DzMemberList)
|
||||
E(OP_DzExpeditionList)
|
||||
E(OP_DzLeaderStatus)
|
||||
E(OP_DzJoinExpeditionConfirm)
|
||||
E(OP_TargetBuffs)
|
||||
E(OP_BuffCreate)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_RespondAA)
|
||||
E(OP_DisciplineUpdate)
|
||||
E(OP_AltCurrencySell)
|
||||
E(OP_AltCurrency)
|
||||
E(OP_WearChange)
|
||||
E(OP_DzLeaderStatus)
|
||||
E(OP_DzMemberList)
|
||||
E(OP_ExpansionInfo)
|
||||
E(OP_GroundSpawn)
|
||||
E(OP_GroupCancelInvite)
|
||||
E(OP_GroupFollow)
|
||||
E(OP_GroupFollow2)
|
||||
E(OP_GroupInvite)
|
||||
E(OP_GroupUpdate)
|
||||
E(OP_GuildMemberList)
|
||||
E(OP_GuildsList)
|
||||
E(OP_Illusion)
|
||||
E(OP_InspectBuffs)
|
||||
E(OP_InspectRequest)
|
||||
E(OP_ItemLinkResponse)
|
||||
E(OP_ItemPacket)
|
||||
E(OP_ItemVerifyReply)
|
||||
E(OP_LeadershipExpUpdate)
|
||||
E(OP_LogServer)
|
||||
E(OP_LootItem)
|
||||
E(OP_ManaChange)
|
||||
E(OP_MercenaryDataResponse)
|
||||
E(OP_MercenaryDataUpdate)
|
||||
//list of packets we need to decode on the way in:
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_ConsiderCorpse)
|
||||
D(OP_Consider)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_MoveItem)
|
||||
D(OP_WhoAllRequest)
|
||||
E(OP_MoveItem)
|
||||
E(OP_NewSpawn)
|
||||
E(OP_NewZone)
|
||||
E(OP_OnLevelMessage)
|
||||
E(OP_OpenNewTasksWindow)
|
||||
E(OP_PetBuffWindow)
|
||||
E(OP_PlayerProfile)
|
||||
E(OP_RaidJoin)
|
||||
E(OP_RaidUpdate)
|
||||
E(OP_ReadBook)
|
||||
E(OP_RespondAA)
|
||||
E(OP_SendAATable)
|
||||
E(OP_SendCharInfo)
|
||||
E(OP_SendZonepoints)
|
||||
E(OP_ShopPlayerBuy)
|
||||
E(OP_ShopPlayerSell)
|
||||
E(OP_SomeItemPacketMaybe)
|
||||
E(OP_SpawnAppearance)
|
||||
E(OP_SpawnDoor)
|
||||
E(OP_Stun)
|
||||
E(OP_TargetBuffs)
|
||||
E(OP_Track)
|
||||
E(OP_Trader)
|
||||
E(OP_TraderBuy)
|
||||
E(OP_TributeItem)
|
||||
E(OP_VetRewardsAvaliable)
|
||||
E(OP_WearChange)
|
||||
E(OP_WhoAllResponse)
|
||||
E(OP_ZoneEntry)
|
||||
E(OP_ZonePlayerToBind)
|
||||
E(OP_ZoneServerInfo)
|
||||
E(OP_ZoneSpawns)
|
||||
// incoming packets that require a DECODE translation:
|
||||
D(OP_AdventureMerchantSell)
|
||||
D(OP_AltCurrencySell)
|
||||
D(OP_AltCurrencySellSelection)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_BazaarSearch)
|
||||
D(OP_Buff)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_Consume)
|
||||
D(OP_BuffRemoveRequest)
|
||||
D(OP_CastSpell)
|
||||
D(OP_Save)
|
||||
D(OP_ItemVerifyRequest)
|
||||
D(OP_GroupInvite)
|
||||
D(OP_GroupInvite2)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_CharacterCreate)
|
||||
D(OP_ClientUpdate)
|
||||
D(OP_Consider)
|
||||
D(OP_ConsiderCorpse)
|
||||
D(OP_Consume)
|
||||
D(OP_Damage)
|
||||
D(OP_DeleteItem)
|
||||
D(OP_EnvDamage)
|
||||
D(OP_FaceChange)
|
||||
D(OP_FindPersonRequest)
|
||||
D(OP_GroupCancelInvite)
|
||||
D(OP_GroupDisband)
|
||||
D(OP_GroupFollow)
|
||||
D(OP_GroupFollow2)
|
||||
D(OP_GroupDisband)
|
||||
D(OP_GroupCancelInvite)
|
||||
D(OP_FindPersonRequest)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_LootItem)
|
||||
D(OP_TributeItem)
|
||||
D(OP_ReadBook)
|
||||
D(OP_AugmentInfo)
|
||||
D(OP_FaceChange)
|
||||
D(OP_AdventureMerchantSell)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_RaidInvite)
|
||||
D(OP_GroupInvite)
|
||||
D(OP_GroupInvite2)
|
||||
D(OP_InspectRequest)
|
||||
D(OP_WearChange)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_BazaarSearch)
|
||||
D(OP_ItemLinkClick)
|
||||
D(OP_ItemVerifyRequest)
|
||||
D(OP_LoadSpellSet)
|
||||
D(OP_ApplyPoison)
|
||||
D(OP_Damage)
|
||||
D(OP_EnvDamage)
|
||||
D(OP_ChannelMessage)
|
||||
D(OP_DeleteItem)
|
||||
D(OP_AugmentItem)
|
||||
D(OP_LootItem)
|
||||
D(OP_MoveItem)
|
||||
D(OP_PetCommands)
|
||||
D(OP_BuffRemoveRequest)
|
||||
D(OP_AltCurrencySellSelection)
|
||||
D(OP_AltCurrencySell)
|
||||
D(OP_RaidInvite)
|
||||
D(OP_ReadBook)
|
||||
D(OP_Save)
|
||||
D(OP_SetServerFilter)
|
||||
D(OP_ShopPlayerBuy)
|
||||
D(OP_ShopPlayerSell)
|
||||
D(OP_TraderBuy)
|
||||
D(OP_TradeSkillCombine)
|
||||
D(OP_TributeItem)
|
||||
D(OP_WearChange)
|
||||
D(OP_WhoAllRequest)
|
||||
#undef E
|
||||
#undef D
|
||||
|
||||
@ -519,7 +519,7 @@ struct CastSpell_Struct
|
||||
uint32 spell_id;
|
||||
uint32 inventoryslot; // slot for clicky item, 0xFFFF = normal cast
|
||||
uint32 target_id;
|
||||
uint32 cs_unknown[5];
|
||||
uint32 cs_unknown[5];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -564,7 +564,7 @@ struct SpellBuffFade_Struct_Underfoot {
|
||||
/*008*/ float unknown008;
|
||||
/*012*/ uint32 spellid;
|
||||
/*016*/ uint32 duration;
|
||||
/*020*/ uint32 unknown016;
|
||||
/*020*/ uint32 num_hits;
|
||||
/*024*/ uint32 playerId; // Global player ID?
|
||||
/*028*/ uint32 unknown020;
|
||||
/*032*/ uint8 unknown0028[48];
|
||||
@ -589,6 +589,25 @@ struct SpellBuffFade_Struct {
|
||||
/*036*/
|
||||
};
|
||||
|
||||
#if 0
|
||||
struct BuffIconEntry_Struct {
|
||||
/*000*/ uint32 buff_slot;
|
||||
/*004*/ uint32 spell_id;
|
||||
/*008*/ uint32 tics_remaining;
|
||||
/*012*/ uint32 num_hits;
|
||||
// char name[0]; caster name is also here sometimes
|
||||
// uint8 unknownend; 1 when single, 0 when all opposite of all_buffs?
|
||||
};
|
||||
|
||||
struct BuffIcon_Struct {
|
||||
/*000*/ uint32 entity_id;
|
||||
/*004*/ uint32 unknown004;
|
||||
/*008*/ uint8 all_buffs; // 1 when updating all buffs, 0 when doing one
|
||||
/*009*/ uint16 count;
|
||||
/*011*/ BuffIconEntry_Struct entires[0];
|
||||
};
|
||||
#endif
|
||||
|
||||
struct BuffRemoveRequest_Struct
|
||||
{
|
||||
/*00*/ uint32 SlotID;
|
||||
@ -735,14 +754,62 @@ struct PotionBelt_Struct {
|
||||
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_RAID_LEADERSHIP_AA_ARRAY = 16;
|
||||
static const uint32 MAX_LEADERSHIP_AA_ARRAY = (MAX_GROUP_LEADERSHIP_AA_ARRAY+MAX_RAID_LEADERSHIP_AA_ARRAY);
|
||||
struct LeadershipAA_Struct {
|
||||
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
|
||||
};
|
||||
struct GroupLeadershipAA_Struct {
|
||||
uint32 ranks[MAX_GROUP_LEADERSHIP_AA_ARRAY];
|
||||
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 {
|
||||
uint32 ranks[MAX_RAID_LEADERSHIP_AA_ARRAY];
|
||||
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 {
|
||||
GroupLeadershipAA_Struct group;
|
||||
RaidLeadershipAA_Struct raid;
|
||||
};
|
||||
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@ -766,7 +833,7 @@ struct BindStruct {
|
||||
** OpCode: 0x006a
|
||||
*/
|
||||
static const uint32 MAX_PP_LANGUAGE = 25; //
|
||||
static const uint32 MAX_PP_SPELLBOOK = 480; // Confirmed 60 pages on Underfoot now
|
||||
static const uint32 MAX_PP_SPELLBOOK = 720; // Confirmed 60 pages on Underfoot now
|
||||
static const uint32 MAX_PP_MEMSPELL = 10; //was 9 now 10 on Underfoot
|
||||
static const uint32 MAX_PP_SKILL = _SkillPacketArraySize; // 100 - actual skills buffer size
|
||||
static const uint32 MAX_PP_AA_ARRAY = 300; //was 299
|
||||
@ -879,7 +946,6 @@ struct PlayerProfile_Struct
|
||||
/*04216*/ uint8 face; // Player face - Actually uint32?
|
||||
/*04217*/ uint8 unknown04217[147]; // was [175]
|
||||
/*04364*/ uint32 spell_book[MAX_PP_SPELLBOOK]; // List of the Spells in spellbook 720 = 90 pages [2880] was [1920]
|
||||
/*06284*/ uint8 unknown06284[960]; // Spacer for the end of the book for now (pages 60 to 90)
|
||||
/*07244*/ uint32 mem_spells[MAX_PP_MEMSPELL]; // List of spells memorized
|
||||
/*07284*/ uint8 unknown07284[28]; //#### uint8 unknown04396[32]; in Titanium ####[28]
|
||||
/*07312*/ uint32 platinum; // Platinum Pieces on player
|
||||
@ -1506,11 +1572,11 @@ struct BulkItemPacket_Struct
|
||||
|
||||
struct Consume_Struct
|
||||
{
|
||||
/*0000*/ uint32 slot;
|
||||
/*0004*/ uint32 auto_consumed; // 0xffffffff when auto eating e7030000 when right click
|
||||
/*0008*/ uint8 c_unknown1[4];
|
||||
/*0012*/ uint8 type; // 0x01=Food 0x02=Water
|
||||
/*0013*/ uint8 unknown13[3];
|
||||
/*0000*/ uint32 slot;
|
||||
/*0004*/ uint32 auto_consumed; // 0xffffffff when auto eating e7030000 when right click
|
||||
/*0008*/ uint8 c_unknown1[4];
|
||||
/*0012*/ uint8 type; // 0x01=Food 0x02=Water
|
||||
/*0013*/ uint8 unknown13[3];
|
||||
/*0016*/
|
||||
};
|
||||
|
||||
@ -1540,17 +1606,17 @@ struct ItemProperties_Struct {
|
||||
};
|
||||
|
||||
struct DeleteItem_Struct {
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
struct MoveItem_Struct
|
||||
{
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0000*/ uint32 from_slot;
|
||||
/*0004*/ uint32 to_slot;
|
||||
/*0008*/ uint32 number_in_stack;
|
||||
/*0012*/
|
||||
};
|
||||
|
||||
@ -2100,6 +2166,14 @@ struct GroupFollow_Struct { // Underfoot Follow Struct
|
||||
/*0152*/
|
||||
};
|
||||
|
||||
struct InspectBuffs_Struct {
|
||||
/*000*/ uint32 spell_id[BUFF_COUNT];
|
||||
/*100*/ uint32 filler100[5]; // BUFF_COUNT is really 30...
|
||||
/*120*/ uint32 tics_remaining[BUFF_COUNT];
|
||||
/*220*/ uint32 filler220[5]; // BUFF_COUNT is really 30...
|
||||
};
|
||||
|
||||
|
||||
struct LFG_Struct {
|
||||
/*000*/ uint32 unknown000;
|
||||
/*004*/ uint32 value; // 0x00 = off 0x01 = on
|
||||
@ -3130,10 +3204,10 @@ struct TributeInfo_Struct {
|
||||
};
|
||||
|
||||
struct TributeItem_Struct {
|
||||
uint32 slot;
|
||||
uint32 quantity;
|
||||
uint32 tribute_master_id;
|
||||
int32 tribute_points;
|
||||
uint32 slot;
|
||||
uint32 quantity;
|
||||
uint32 tribute_master_id;
|
||||
int32 tribute_points;
|
||||
};
|
||||
|
||||
struct TributePoint_Struct {
|
||||
@ -3169,7 +3243,7 @@ struct Split_Struct
|
||||
*/
|
||||
struct NewCombine_Struct {
|
||||
/*00*/ int16 container_slot;
|
||||
/*02*/ char unknown02[2];
|
||||
/*02*/ int16 guildtribute_slot;
|
||||
/*04*/
|
||||
};
|
||||
|
||||
@ -3605,6 +3679,21 @@ struct RaidAddMember_Struct {
|
||||
/*139*/ uint8 flags[5]; //no idea if these are needed...
|
||||
};
|
||||
|
||||
struct RaidMOTD_Struct {
|
||||
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
|
||||
/*140*/ char motd[0]; // max size 1024, but reply is variable
|
||||
};
|
||||
|
||||
struct RaidLeadershipUpdate_Struct {
|
||||
/*000*/ uint32 action;
|
||||
/*004*/ char player_name[64];
|
||||
/*068*/ uint32 Unknown068;
|
||||
/*072*/ char leader_name[64];
|
||||
/*136*/ GroupLeadershipAA_Struct group; //unneeded
|
||||
/*200*/ RaidLeadershipAA_Struct raid;
|
||||
/*264*/ char Unknown264[128];
|
||||
};
|
||||
|
||||
struct RaidAdd_Struct {
|
||||
/*000*/ uint32 action; //=0
|
||||
/*004*/ char player_name[64]; //should both be the player's name
|
||||
@ -3736,7 +3825,7 @@ struct GMToggle_Struct {
|
||||
uint32 toggle;
|
||||
};
|
||||
|
||||
struct BuffFadeMsg_Struct {
|
||||
struct ColoredText_Struct {
|
||||
uint32 color;
|
||||
char msg[1]; //was 1
|
||||
/*0???*/ uint8 paddingXXX[3]; // always 0's
|
||||
@ -4161,9 +4250,9 @@ struct ItemQuaternaryBodyStruct
|
||||
|
||||
struct AugmentInfo_Struct
|
||||
{
|
||||
/*000*/ uint32 itemid; // id of the solvent needed
|
||||
/*004*/ uint8 window; // window to display the information in
|
||||
/*005*/ uint8 unknown005[71]; // total packet length 76, all the rest were always 00
|
||||
/*000*/ uint32 itemid; // id of the solvent needed
|
||||
/*004*/ uint8 window; // window to display the information in
|
||||
/*005*/ uint8 unknown005[71]; // total packet length 76, all the rest were always 00
|
||||
/*076*/
|
||||
};
|
||||
|
||||
|
||||
@ -171,6 +171,7 @@ RULE_INT ( World, PVPSettings, 0) // Sets the PVP settings for the server, 1 = R
|
||||
RULE_BOOL (World, IsGMPetitionWindowEnabled, false)
|
||||
RULE_INT (World, FVNoDropFlag, 0) // Sets the Firiona Vie settings on the client. If set to 2, the flag will be set for GMs only, allowing trading of no-drop items.
|
||||
RULE_BOOL (World, IPLimitDisconnectAll, false)
|
||||
RULE_INT (World, TellQueueSize, 20)
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY( Zone )
|
||||
@ -200,6 +201,8 @@ RULE_INT ( Zone, EbonCrystalItemID, 40902)
|
||||
RULE_INT ( Zone, RadiantCrystalItemID, 40903)
|
||||
RULE_BOOL ( Zone, LevelBasedEXPMods, false) // Allows you to use the level_exp_mods table in consideration to your players EXP hits
|
||||
RULE_INT ( Zone, WeatherTimer, 600) // Weather timer when no duration is available
|
||||
RULE_BOOL ( Zone, EnableLoggedOffReplenishments, true)
|
||||
RULE_INT ( Zone, MinOfflineTimeToReplenishments, 21600) // 21600 seconds is 6 Hours
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY( Map )
|
||||
@ -320,6 +323,8 @@ RULE_INT ( Spells, AI_PursueDetrimentalChance, 90) // Chance while chasing targe
|
||||
RULE_INT ( Spells, AI_IdleNoSpellMinRecast, 500) // AI spell recast time(MS) check when no spell is cast while idle. (min time in random)
|
||||
RULE_INT ( Spells, AI_IdleNoSpellMaxRecast, 2000) // AI spell recast time(MS) check when no spell is cast while chasing target. (max time in random)
|
||||
RULE_INT ( Spells, AI_IdleBeneficialChance, 100) // Chance while idle to do a beneficial spell on self or others.
|
||||
RULE_BOOL ( Spells, SHDProcIDOffByOne, true) // pre June 2009 SHD spell procs were off by 1, they stopped doing this in June 2009 (so UF+ spell files need this false)
|
||||
RULE_BOOL ( Spells, Jun182014HundredHandsRevamp, false) // this should be true for if you import a spell file newer than June 18, 2014
|
||||
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
|
||||
@ -83,6 +83,7 @@
|
||||
#define ServerOP_QGlobalUpdate 0x0063
|
||||
#define ServerOP_QGlobalDelete 0x0064
|
||||
#define ServerOP_DepopPlayerCorpse 0x0065
|
||||
#define ServerOP_RequestTellQueue 0x0066 // client asks for it's tell queues
|
||||
|
||||
#define ServerOP_RaidAdd 0x0100 //in use
|
||||
#define ServerOP_RaidRemove 0x0101 //in use
|
||||
@ -103,6 +104,7 @@
|
||||
#define ServerOP_GroupFollow 0x0110
|
||||
#define ServerOP_GroupFollowAck 0x0111
|
||||
#define ServerOP_GroupCancelInvite 0x0112
|
||||
#define ServerOP_RaidMOTD 0x0113
|
||||
|
||||
#define ServerOP_InstanceUpdateTime 0x014F
|
||||
#define ServerOP_AdventureRequest 0x0150
|
||||
@ -179,13 +181,15 @@
|
||||
#define ServerOP_CZMessagePlayer 0x4008
|
||||
#define ServerOP_ReloadWorld 0x4009
|
||||
|
||||
#define ServerOP_QSPlayerLogTrades 0x4010
|
||||
#define ServerOP_QSPlayerLogHandins 0x4011
|
||||
#define ServerOP_QSPlayerLogNPCKills 0x4012
|
||||
#define ServerOP_QSPlayerLogDeletes 0x4013
|
||||
#define ServerOP_QSPlayerLogMoves 0x4014
|
||||
#define ServerOP_QSPlayerLogTrades 0x4010
|
||||
#define ServerOP_QSPlayerLogHandins 0x4011
|
||||
#define ServerOP_QSPlayerLogNPCKills 0x4012
|
||||
#define ServerOP_QSPlayerLogDeletes 0x4013
|
||||
#define ServerOP_QSPlayerLogMoves 0x4014
|
||||
#define ServerOP_QSPlayerLogMerchantTransactions 0x4015
|
||||
#define ServerOP_QSSendQuery 0x4016
|
||||
#define ServerOP_QSSendQuery 0x4016
|
||||
#define ServerOP_CZSignalNPC 0x4017
|
||||
#define ServerOP_CZSetEntityVariableByNPCTypeID 0x4018
|
||||
|
||||
/* Query Serv Generic Packet Flag/Type Enumeration */
|
||||
enum { QSG_LFGuild = 0 };
|
||||
@ -346,6 +350,7 @@ struct ServerChannelMessage_Struct {
|
||||
uint16 chan_num;
|
||||
uint32 guilddbid;
|
||||
uint16 language;
|
||||
uint8 queued; // 0 = not queued, 1 = queued, 2 = queue full, 3 = offline
|
||||
char message[0];
|
||||
};
|
||||
|
||||
@ -850,6 +855,11 @@ struct ServerRaidMessage_Struct {
|
||||
char message[0];
|
||||
};
|
||||
|
||||
struct ServerRaidMOTD_Struct {
|
||||
uint32 rid;
|
||||
char motd[0];
|
||||
};
|
||||
|
||||
struct ServerLFGMatchesRequest_Struct {
|
||||
uint32 FromID;
|
||||
uint8 QuerierLevel;
|
||||
@ -1092,6 +1102,11 @@ struct CZClientSignal_Struct {
|
||||
uint32 data;
|
||||
};
|
||||
|
||||
struct CZNPCSignal_Struct {
|
||||
uint32 npctype_id;
|
||||
uint32 data;
|
||||
};
|
||||
|
||||
struct CZClientSignalByName_Struct {
|
||||
char Name[64];
|
||||
uint32 data;
|
||||
@ -1233,10 +1248,20 @@ struct CZMessagePlayer_Struct {
|
||||
char Message[512];
|
||||
};
|
||||
|
||||
struct CZSetEntVarByNPCTypeID_Struct {
|
||||
uint32 npctype_id;
|
||||
char id[256];
|
||||
char m_var[256];
|
||||
};
|
||||
|
||||
struct ReloadWorld_Struct{
|
||||
uint32 Option;
|
||||
};
|
||||
|
||||
struct ServerRequestTellQueue_Struct {
|
||||
char name[64];
|
||||
};
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif
|
||||
|
||||
2648
common/shareddb.cpp
2648
common/shareddb.cpp
File diff suppressed because it is too large
Load Diff
@ -40,13 +40,10 @@ public:
|
||||
bool SetGMSpeed(uint32 account_id, uint8 gmspeed);
|
||||
uint8 GetGMSpeed(uint32 account_id);
|
||||
bool SetHideMe(uint32 account_id, uint8 hideme);
|
||||
bool GetPlayerProfile(uint32 account_id, char* name, PlayerProfile_Struct* pp, Inventory* inv, ExtendedProfile_Struct *ext, char* current_zone = 0, uint32 *current_instance = 0);
|
||||
bool SetPlayerProfile(uint32 account_id, uint32 charid, PlayerProfile_Struct* pp, Inventory* inv, ExtendedProfile_Struct *ext, uint32 current_zone, uint32 current_instance, uint8 MaxXTargets);
|
||||
uint32 SetPlayerProfile_MQ(char** query, uint32 account_id, uint32 charid, PlayerProfile_Struct* pp, Inventory* inv, ExtendedProfile_Struct *ext, uint32 current_zone, uint32 current_instance, uint8 MaxXTargets);
|
||||
int32 DeleteStalePlayerCorpses();
|
||||
int32 DeleteStalePlayerBackups();
|
||||
void GetPlayerInspectMessage(char* playername, InspectMessage_Struct* message);
|
||||
void SetPlayerInspectMessage(char* playername, const InspectMessage_Struct* message);
|
||||
void LoadCharacterInspectMessage(uint32 character_id, InspectMessage_Struct* message);
|
||||
void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message);
|
||||
void GetBotInspectMessage(uint32 botid, InspectMessage_Struct* message);
|
||||
void SetBotInspectMessage(uint32 botid, const InspectMessage_Struct* message);
|
||||
bool GetCommandSettings(std::map<std::string,uint8> &commands);
|
||||
@ -57,6 +54,10 @@ public:
|
||||
*/
|
||||
bool SaveCursor(uint32 char_id, std::list<ItemInst*>::const_iterator &start, std::list<ItemInst*>::const_iterator &end);
|
||||
bool SaveInventory(uint32 char_id, const ItemInst* inst, int16 slot_id);
|
||||
bool DeleteSharedBankSlot(uint32 char_id, int16 slot_id);
|
||||
bool DeleteInventorySlot(uint32 char_id, int16 slot_id);
|
||||
bool UpdateInventorySlot(uint32 char_id, const ItemInst* inst, int16 slot_id);
|
||||
bool UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, int16 slot_id);
|
||||
bool VerifyInventory(uint32 account_id, int16 slot_id, const ItemInst* inst);
|
||||
bool GetSharedBank(uint32 id, Inventory* inv, bool is_charid);
|
||||
int32 GetSharedPlatinum(uint32 account_id);
|
||||
|
||||
56
common/skills.cpp
Normal file
56
common/skills.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/* 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
|
||||
*/
|
||||
#include "types.h"
|
||||
#include "skills.h"
|
||||
|
||||
bool EQEmu::IsTradeskill(SkillUseTypes skill)
|
||||
{
|
||||
switch (skill) {
|
||||
case SkillFishing:
|
||||
case SkillMakePoison:
|
||||
case SkillTinkering:
|
||||
case SkillResearch:
|
||||
case SkillAlchemy:
|
||||
case SkillBaking:
|
||||
case SkillTailoring:
|
||||
case SkillBlacksmithing:
|
||||
case SkillFletching:
|
||||
case SkillBrewing:
|
||||
case SkillPottery:
|
||||
case SkillJewelryMaking:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool EQEmu::IsSpecializedSkill(SkillUseTypes skill)
|
||||
{
|
||||
// this could be a simple if, but if this is more portable if any IDs change (probably won't)
|
||||
// or any other specialized are added (also unlikely)
|
||||
switch (skill) {
|
||||
case SkillSpecializeAbjure:
|
||||
case SkillSpecializeAlteration:
|
||||
case SkillSpecializeConjuration:
|
||||
case SkillSpecializeDivination:
|
||||
case SkillSpecializeEvocation:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -260,4 +260,10 @@ typedef enum {
|
||||
#define HIGHEST_SKILL FRENZY
|
||||
*/
|
||||
|
||||
// for skill related helper functions
|
||||
namespace EQEmu {
|
||||
bool IsTradeskill(SkillUseTypes skill);
|
||||
bool IsSpecializedSkill(SkillUseTypes skill);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -17,6 +17,11 @@ StructStrategy::StructStrategy() {
|
||||
}
|
||||
|
||||
void StructStrategy::Encode(EQApplicationPacket **p, EQStream *dest, bool ack_req) const {
|
||||
if((*p)->GetOpcodeBypass() != 0) {
|
||||
PassEncoder(p, dest, ack_req);
|
||||
return;
|
||||
}
|
||||
|
||||
EmuOpcode op = (*p)->GetOpcode();
|
||||
Encoder proc = encoders[op];
|
||||
proc(p, dest, ack_req);
|
||||
|
||||
@ -18,9 +18,6 @@
|
||||
#ifndef _WINDOWS
|
||||
#ifndef __UNIX_H__
|
||||
#define __UNIX_H__
|
||||
#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
|
||||
#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP {0, 0, 0, PTHREAD_MUTEX_RECURSIVE_NP, __LOCK_INITIALIZER}
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
|
||||
typedef int SOCKET;
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include <luabind/config.hpp>
|
||||
#include <luabind/detail/instance_holder.hpp>
|
||||
#include <luabind/detail/ref.hpp>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace luabind { namespace detail
|
||||
{
|
||||
|
||||
@ -349,17 +349,16 @@ void Database::GeneralQueryReceive(ServerPacket *pack) {
|
||||
/*
|
||||
These are general queries passed from anywhere in zone instead of packing structures and breaking them down again and again
|
||||
*/
|
||||
char *Query = nullptr;
|
||||
Query = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(Query);
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
uint32 lastid = 0;
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, Query), errbuf, 0, 0, &lastid)) {
|
||||
_log(QUERYSERV__ERROR, "Failed Delete Log Record Insert: %s", errbuf);
|
||||
_log(QUERYSERV__ERROR, "%s", query);
|
||||
char *queryBuffer = new char[pack->ReadUInt32() + 1];
|
||||
pack->ReadString(queryBuffer);
|
||||
|
||||
std::string query(queryBuffer);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
_log(QUERYSERV__ERROR, "Failed Delete Log Record Insert: %s", results.ErrorMessage().c_str());
|
||||
_log(QUERYSERV__ERROR, "%s", query.c_str());
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
safe_delete(pack);
|
||||
safe_delete(Query);
|
||||
safe_delete(queryBuffer);
|
||||
}
|
||||
|
||||
@ -8,18 +8,22 @@ SET(tests_sources
|
||||
|
||||
SET(tests_headers
|
||||
atobool_test.h
|
||||
data_verification_test.h
|
||||
fixed_memory_test.h
|
||||
fixed_memory_variable_test.h
|
||||
hextoi_32_64_test.h
|
||||
ipc_mutex_test.h
|
||||
memory_mapped_file_test.h
|
||||
string_util_test.h
|
||||
skills_util_test.h
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers})
|
||||
|
||||
TARGET_LINK_LIBRARIES(tests common cppunit)
|
||||
|
||||
INSTALL(TARGETS tests RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
|
||||
IF(MSVC)
|
||||
SET_TARGET_PROPERTIES(tests PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
|
||||
TARGET_LINK_LIBRARIES(tests "Ws2_32.lib")
|
||||
|
||||
108
tests/data_verification_test.h
Normal file
108
tests/data_verification_test.h
Normal file
@ -0,0 +1,108 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2014 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_TESTS_DATA_VERIFICATION_H
|
||||
#define __EQEMU_TESTS_DATA_VERIFICATION_H
|
||||
|
||||
#include "cppunit/cpptest.h"
|
||||
#include "../common/data_verification.h"
|
||||
|
||||
class DataVerificationTest : public Test::Suite {
|
||||
typedef void(DataVerificationTest::*TestFunction)(void);
|
||||
public:
|
||||
DataVerificationTest() {
|
||||
TEST_ADD(DataVerificationTest::Clamp);
|
||||
TEST_ADD(DataVerificationTest::ClampUpper);
|
||||
TEST_ADD(DataVerificationTest::ClampLower);
|
||||
TEST_ADD(DataVerificationTest::ValueWithin);
|
||||
}
|
||||
|
||||
~DataVerificationTest() {
|
||||
}
|
||||
|
||||
private:
|
||||
void Clamp() {
|
||||
float value_f = 500.0f;
|
||||
int value_i = 500;
|
||||
|
||||
float vf1 = EQEmu::Clamp(value_f, 0.0f, 1000.0f);
|
||||
float vf2 = EQEmu::Clamp(value_f, 0.0f, 250.0f);
|
||||
float vf3 = EQEmu::Clamp(value_f, 750.0f, 1000.0f);
|
||||
|
||||
int vi1 = EQEmu::Clamp(value_i, 0, 1000);
|
||||
int vi2 = EQEmu::Clamp(value_i, 0, 250);
|
||||
int vi3 = EQEmu::Clamp(value_i, 750, 1000);
|
||||
|
||||
TEST_ASSERT_EQUALS(vf1, 500.0f);
|
||||
TEST_ASSERT_EQUALS(vf2, 250.0f);
|
||||
TEST_ASSERT_EQUALS(vf3, 750.0f);
|
||||
|
||||
TEST_ASSERT_EQUALS(vi1, 500);
|
||||
TEST_ASSERT_EQUALS(vi2, 250);
|
||||
TEST_ASSERT_EQUALS(vi3, 750);
|
||||
}
|
||||
|
||||
void ClampUpper() {
|
||||
float value_f = 500.0f;
|
||||
int value_i = 500;
|
||||
|
||||
float vf1 = EQEmu::ClampUpper(value_f, 1000.0f);
|
||||
float vf2 = EQEmu::ClampUpper(value_f, 250.0f);
|
||||
|
||||
int vi1 = EQEmu::ClampUpper(value_i, 1000);
|
||||
int vi2 = EQEmu::ClampUpper(value_i, 250);
|
||||
|
||||
TEST_ASSERT_EQUALS(vf1, 500.0f);
|
||||
TEST_ASSERT_EQUALS(vf2, 250.0f);
|
||||
|
||||
TEST_ASSERT_EQUALS(vi1, 500);
|
||||
TEST_ASSERT_EQUALS(vi2, 250);
|
||||
}
|
||||
|
||||
void ClampLower() {
|
||||
float value_f = 500.0f;
|
||||
int value_i = 500;
|
||||
|
||||
float vf1 = EQEmu::ClampLower(value_f, 0.0f);
|
||||
float vf2 = EQEmu::ClampLower(value_f, 750.0f);
|
||||
|
||||
int vi1 = EQEmu::ClampLower(value_i, 0);
|
||||
int vi2 = EQEmu::ClampLower(value_i, 750);
|
||||
|
||||
TEST_ASSERT_EQUALS(vf1, 500.0f);
|
||||
TEST_ASSERT_EQUALS(vf2, 750.0f);
|
||||
|
||||
TEST_ASSERT_EQUALS(vi1, 500);
|
||||
TEST_ASSERT_EQUALS(vi2, 750);
|
||||
}
|
||||
|
||||
void ValueWithin() {
|
||||
float value_f = 500.0f;
|
||||
int value_i = 500;
|
||||
|
||||
TEST_ASSERT(EQEmu::ValueWithin(value_f, 0.0f, 1000.0f));
|
||||
TEST_ASSERT(!EQEmu::ValueWithin(value_f, 0.0f, 400.0f));
|
||||
TEST_ASSERT(!EQEmu::ValueWithin(value_f, 600.0f, 900.0f));
|
||||
|
||||
TEST_ASSERT(EQEmu::ValueWithin(value_i, 0, 1000));
|
||||
TEST_ASSERT(!EQEmu::ValueWithin(value_i, 0, 400));
|
||||
TEST_ASSERT(!EQEmu::ValueWithin(value_i, 600, 900));
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -27,6 +27,8 @@
|
||||
#include "atobool_test.h"
|
||||
#include "hextoi_32_64_test.h"
|
||||
#include "string_util_test.h"
|
||||
#include "data_verification_test.h"
|
||||
#include "skills_util_test.h"
|
||||
|
||||
int main() {
|
||||
try {
|
||||
@ -40,6 +42,8 @@ int main() {
|
||||
tests.add(new atoboolTest());
|
||||
tests.add(new hextoi_32_64_Test());
|
||||
tests.add(new StringUtilTest());
|
||||
tests.add(new DataVerificationTest());
|
||||
tests.add(new SkillsUtilsTest());
|
||||
tests.run(*output, true);
|
||||
} catch(...) {
|
||||
return -1;
|
||||
|
||||
48
tests/skills_util_test.h
Normal file
48
tests/skills_util_test.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* EQEMu: Everquest Server Emulator
|
||||
Copyright (C) 2001-2014 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_TESTS_SKILLS_UTILS_H
|
||||
#define __EQEMU_TESTS_SKILLS_UTILS_H
|
||||
|
||||
#include "cppunit/cpptest.h"
|
||||
#include "../common/skills.h"
|
||||
|
||||
class SkillsUtilsTest: public Test::Suite {
|
||||
typedef void(SkillsUtilsTest::*TestFunction)(void);
|
||||
public:
|
||||
SkillsUtilsTest() {
|
||||
TEST_ADD(SkillsUtilsTest::IsTradeskill);
|
||||
TEST_ADD(SkillsUtilsTest::IsSpecializedSkill);
|
||||
}
|
||||
|
||||
~SkillsUtilsTest() {
|
||||
}
|
||||
|
||||
private:
|
||||
void IsTradeskill() {
|
||||
TEST_ASSERT(EQEmu::IsTradeskill(SkillPottery));
|
||||
TEST_ASSERT(!EQEmu::IsTradeskill(SkillParry));
|
||||
}
|
||||
|
||||
void IsSpecializedSkill() {
|
||||
TEST_ASSERT(EQEmu::IsSpecializedSkill(SkillSpecializeConjuration));
|
||||
TEST_ASSERT(!EQEmu::IsSpecializedSkill(SkillConjuration))
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -23,7 +23,7 @@
|
||||
#include "../common/string_util.h"
|
||||
|
||||
class StringUtilTest : public Test::Suite {
|
||||
typedef void(IPCMutexTest::*TestFunction)(void);
|
||||
typedef void(StringUtilTest::*TestFunction)(void);
|
||||
public:
|
||||
StringUtilTest() {
|
||||
TEST_ADD(StringUtilTest::StringFormatTest);
|
||||
@ -35,7 +35,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void StringFormatTest() {
|
||||
void StringFormatTest() {
|
||||
const char* fmt = "Test: %c %d %4.2f";
|
||||
char c = 'a';
|
||||
int i = 2014;
|
||||
|
||||
@ -139,7 +139,7 @@ int Database::FindAccount(const char *characterName, Client *client) {
|
||||
|
||||
client->ClearCharacters();
|
||||
std::string query = StringFormat("SELECT `id`, `account_id`, `level` "
|
||||
"FROM `character_` WHERE `name` = '%s' LIMIT 1",
|
||||
"FROM `character_data` WHERE `name` = '%s' LIMIT 1",
|
||||
characterName);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
@ -159,7 +159,7 @@ int Database::FindAccount(const char *characterName, Client *client) {
|
||||
|
||||
_log(UCS__TRACE, "Account ID for %s is %i", characterName, accountID);
|
||||
|
||||
query = StringFormat("SELECT `id`, `name`, `level` FROM `character_` "
|
||||
query = StringFormat("SELECT `id`, `name`, `level` FROM `character_data` "
|
||||
"WHERE `account_id` = %i AND `name` != '%s'",
|
||||
accountID, characterName);
|
||||
results = QueryDatabase(query);
|
||||
@ -174,7 +174,7 @@ int Database::FindAccount(const char *characterName, Client *client) {
|
||||
|
||||
bool Database::VerifyMailKey(std::string characterName, int IPAddress, std::string MailKey) {
|
||||
|
||||
std::string query = StringFormat("SELECT `mailkey` FROM `character_` WHERE `name`='%s' LIMIT 1",
|
||||
std::string query = StringFormat("SELECT `mailkey` FROM `character_data` WHERE `name`='%s' LIMIT 1",
|
||||
characterName.c_str());
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
@ -202,7 +202,7 @@ bool Database::VerifyMailKey(std::string characterName, int IPAddress, std::stri
|
||||
int Database::FindCharacter(const char *characterName) {
|
||||
|
||||
char *safeCharName = RemoveApostrophes(characterName);
|
||||
std::string query = StringFormat("SELECT `id` FROM `character_` WHERE `name`='%s' LIMIT 1", safeCharName);
|
||||
std::string query = StringFormat("SELECT `id` FROM `character_data` WHERE `name`='%s' LIMIT 1", safeCharName);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
_log(UCS__ERROR, "FindCharacter failed. %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
@ -523,9 +523,9 @@ void Database::ExpireMail() {
|
||||
time(nullptr) - RuleI(Mail, ExpireTrash));
|
||||
results = QueryDatabase(query);
|
||||
if(results.Success())
|
||||
_log(UCS__ERROR, "Error expiring trash messages, %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
else
|
||||
_log(UCS__INIT, "Expired %i trash messages.", results.RowsAffected());
|
||||
else
|
||||
_log(UCS__ERROR, "Error expiring trash messages, %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -147,7 +147,7 @@ OP_Begging=0x13e7 # ShowEQ 10/27/05
|
||||
OP_InspectRequest=0x775d # ShowEQ 10/27/05
|
||||
OP_Action2=0x0000
|
||||
OP_BeginCast=0x3990 # ShowEQ 10/27/05
|
||||
OP_BuffFadeMsg=0x0b2d # ShowEQ 10/27/05
|
||||
OP_ColoredText=0x0b2d # ShowEQ 10/27/05
|
||||
OP_Consent=0x1081 # ShowEQ 10/27/05
|
||||
OP_LFGCommand=0x68ac # ShowEQ 10/27/05
|
||||
OP_LFGGetMatchesRequest=0x022f # ShowEQ 10/27/05
|
||||
|
||||
@ -150,7 +150,7 @@ OP_InspectRequest=0x2403
|
||||
OP_Action2=0x0000 # ShowEQ 06/29/05
|
||||
OP_BeginCast=0x3990 # ShowEQ 06/29/05
|
||||
OP_WhoAllRequest=0x5cdd # ShowEQ 06/29/05
|
||||
OP_BuffFadeMsg=0x4bc6 # ShowEQ 06/29/05
|
||||
OP_ColoredText=0x4bc6 # ShowEQ 06/29/05
|
||||
OP_Consent=0x1081 # ShowEQ 06/29/05
|
||||
OP_LFGCommand=0x022f # ShowEQ 06/29/05
|
||||
OP_LFGGetMatchesRequest=0x6f82 # ShowEQ 06/29/05
|
||||
|
||||
@ -166,7 +166,7 @@ OP_InspectRequest=0x23f1
|
||||
OP_InspectAnswer=0x5794
|
||||
OP_InspectMessageUpdate=0x3064
|
||||
OP_BeginCast=0x17ff
|
||||
OP_BuffFadeMsg=0x41cb
|
||||
OP_ColoredText=0x41cb
|
||||
OP_ConsentResponse=0x183d
|
||||
OP_MemorizeSpell=0x2fac
|
||||
OP_SwapSpell=0x4736
|
||||
@ -289,8 +289,10 @@ OP_LeadershipExpToggle=0x3ea6
|
||||
OP_LeadershipExpUpdate=0x6922
|
||||
OP_PurchaseLeadershipAA=0x1962
|
||||
OP_UpdateLeadershipAA=0x56aa
|
||||
OP_MarkNPC=0x2d9f
|
||||
OP_MarkNPC=0x1a6c
|
||||
OP_MarkRaidNPC=0x2d9f #unimplemented
|
||||
OP_ClearNPCMarks=0x0d2d
|
||||
OP_ClearRaidNPCMarks=0x433a #unimplemented
|
||||
OP_DelegateAbility=0x7820
|
||||
OP_SetGroupTarget=0x118a
|
||||
OP_Charm=0x7118
|
||||
@ -498,6 +500,8 @@ OP_GroupRoles=0x047c
|
||||
OP_GroupMakeLeader=0x4129
|
||||
OP_DoGroupLeadershipAbility=0x17d7
|
||||
OP_GroupLeadershipAAUpdate=0x6567
|
||||
OP_GroupMentor=0x56DB
|
||||
OP_InspectBuffs=0x01f3
|
||||
|
||||
# LFG/LFP Opcodes
|
||||
OP_LFGCommand=0x4463
|
||||
@ -653,3 +657,5 @@ OP_RAWOutOfSession=0x0000
|
||||
# we need to document the differences between these packets to make identifying them easier
|
||||
OP_Some3ByteHPUpdate=0x0000 # initial HP update for mobs
|
||||
OP_InitialHPUpdate=0x0000
|
||||
|
||||
OP_ItemRecastDelay=0x57ed
|
||||
|
||||
@ -168,7 +168,7 @@ OP_GMLastName=0x3563 # C
|
||||
OP_InspectAnswer=0x4938 # C
|
||||
OP_Action2=0x7e4d # C OP_Damage?
|
||||
OP_BeginCast=0x0d5a # C
|
||||
OP_BuffFadeMsg=0x569a # C
|
||||
OP_ColoredText=0x569a # C
|
||||
OP_ConsentResponse=0x6e47 # C
|
||||
OP_MemorizeSpell=0x8543 # C
|
||||
OP_SwapSpell=0x3fd2 # C
|
||||
@ -288,8 +288,10 @@ OP_LeadershipExpToggle=0x34c5 # C
|
||||
OP_LeadershipExpUpdate=0x69d0 # C
|
||||
OP_PurchaseLeadershipAA=0x07b3 # C
|
||||
OP_UpdateLeadershipAA=0x6948 # C
|
||||
OP_MarkNPC=0x0d4b # C
|
||||
OP_MarkNPC=0x695c # C
|
||||
OP_MarkRaidNPC=0x0d4b # C
|
||||
OP_ClearNPCMarks=0x5033 # C
|
||||
OP_ClearRaidNPCMarks=0x5f55 # C
|
||||
OP_DoGroupLeadershipAbility=0x540b # C
|
||||
OP_GroupLeadershipAAUpdate=0x0c33
|
||||
OP_DelegateAbility=0x0322 # C
|
||||
@ -484,6 +486,8 @@ OP_GroupDisbandOther=0x162d
|
||||
OP_GroupLeaderChange=0x7545
|
||||
OP_GroupRoles=0x6b67
|
||||
OP_GroupMakeLeader=0x6087
|
||||
OP_GroupMentor=0x1224
|
||||
OP_InspectBuffs=0x66bf
|
||||
# LFG/LFP Opcodes
|
||||
OP_LFGCommand=0x3288 # C
|
||||
OP_LFGGetMatchesRequest=0x5613 # C
|
||||
@ -659,4 +663,6 @@ OP_RAWOutOfSession=0x0000 #
|
||||
|
||||
# we need to document the differences between these packets to make identifying them easier
|
||||
OP_Some3ByteHPUpdate=0x0000 # initial HP update for mobs
|
||||
OP_InitialHPUpdate=0x0000 #
|
||||
OP_InitialHPUpdate=0x0000 #
|
||||
|
||||
OP_ItemRecastDelay=0x15c4
|
||||
|
||||
@ -164,7 +164,7 @@ OP_GMLastName=0x0375 #/lastname <Name> <New Surname>
|
||||
OP_InspectAnswer=0x084F #SEQ 12/04/08
|
||||
OP_Action2=0x0EF2 #SEQ 12/04/08
|
||||
OP_BeginCast=0x5A50 #SEQ 12/04/08
|
||||
OP_BuffFadeMsg=0x3BC7 #SEQ 12/04/08
|
||||
OP_ColoredText=0x3BC7 #SEQ 12/04/08
|
||||
OP_ConsentResponse=0x4D30 #SEQ 12/04/08
|
||||
OP_MemorizeSpell=0x6A93 #SEQ 12/04/08
|
||||
OP_SwapSpell=0x1418 #SEQ 12/04/08
|
||||
@ -281,8 +281,10 @@ OP_LeadershipExpToggle=0x24D4 #Xinu 02/20/09
|
||||
OP_LeadershipExpUpdate=0x58b6 #Derision 2009
|
||||
OP_PurchaseLeadershipAA=0x1408 #Derision 2009
|
||||
OP_UpdateLeadershipAA=0x7abf #Derision 2009
|
||||
OP_MarkNPC=0x00c6 #Derision 2009
|
||||
OP_MarkNPC=0x4697 #Derision 2009
|
||||
OP_MarkRaidNPC=0x00c6
|
||||
OP_ClearNPCMarks=0x2ff2 #
|
||||
OP_ClearRaidNPCMarks=0x56a9 #
|
||||
OP_DoGroupLeadershipAbility=0x5a64 #Derision 2009
|
||||
OP_DelegateAbility=0x57e3 #Derision 2009
|
||||
OP_SetGroupTarget=0x1651 #Derision 2009
|
||||
@ -450,6 +452,8 @@ OP_GroupDelete=0x0000 #
|
||||
OP_CancelInvite=0x596C #Trevius 03/02/09
|
||||
OP_GroupFollow2=0x59D4 #Xinu 02/20/09
|
||||
OP_GroupInvite2=0x07F6 #Xinu 02/20/09
|
||||
OP_GroupMentor=0x9EF3
|
||||
OP_InspectBuffs=0x3547
|
||||
|
||||
#LFG/LFP Opcodes
|
||||
OP_LFGCommand=0x5D81 #Trevius 01/16/09
|
||||
@ -615,6 +619,8 @@ OP_RAWOutOfSession=0x0000 #
|
||||
OP_Some3ByteHPUpdate=0x0000 #initial HP update for mobs
|
||||
OP_InitialHPUpdate=0x0000 #
|
||||
|
||||
OP_ItemRecastDelay=0x0ada
|
||||
|
||||
|
||||
# Opcodes from the client that are currently Unknowns:
|
||||
# 0x3E85 - Sent when Guild Management window is opened
|
||||
|
||||
@ -154,7 +154,7 @@ OP_InspectRequest=0x775d # ShowEQ 10/27/05
|
||||
OP_InspectAnswer=0x2403 # ShowEQ 10/27/05
|
||||
OP_Action2=0x0000
|
||||
OP_BeginCast=0x3990 # ShowEQ 10/27/05
|
||||
OP_BuffFadeMsg=0x0b2d # ShowEQ 10/27/05
|
||||
OP_ColoredText=0x0b2d # ShowEQ 10/27/05
|
||||
OP_Consent=0x1081 # ShowEQ 10/27/05
|
||||
OP_ConsentDeny=0x4e8c # ShowEQ 10/27/05
|
||||
OP_ConsentResponse=0x6380 # ShowEQ 10/27/05
|
||||
@ -420,6 +420,8 @@ OP_RaidJoin=0x1f21 # ShowEQ 10/27/05
|
||||
OP_RaidInvite=0x5891 # ShowEQ 10/27/05
|
||||
OP_RaidUpdate=0x1f21 # EQEmu 06/29/05
|
||||
|
||||
OP_InspectBuffs=0x4FB6
|
||||
|
||||
|
||||
OP_ZoneComplete=0x0000
|
||||
OP_ItemLinkText=0x0000
|
||||
|
||||
@ -168,7 +168,7 @@ OP_GMLastName=0x7bfb # C
|
||||
|
||||
OP_InspectAnswer=0x0c2b # C
|
||||
OP_BeginCast=0x0d5a # C
|
||||
OP_BuffFadeMsg=0x71bf # C
|
||||
OP_ColoredText=0x71bf # C
|
||||
OP_ConsentResponse=0x0e87 # C
|
||||
OP_MemorizeSpell=0x3887 # C
|
||||
OP_SwapSpell=0x5805 # C
|
||||
@ -292,8 +292,10 @@ OP_LeadershipExpToggle=0x5033 # C
|
||||
OP_LeadershipExpUpdate=0x074f # C
|
||||
OP_PurchaseLeadershipAA=0x5f55 # C
|
||||
OP_UpdateLeadershipAA=0x77ed # C
|
||||
OP_MarkNPC=0x3ec7 # C
|
||||
OP_MarkNPC=0x66bf
|
||||
OP_MarkRaidNPC=0x3ec7 # C
|
||||
OP_ClearNPCMarks=0x5c29 # C
|
||||
OP_ClearRaidNPCMarks=0x2af4
|
||||
OP_DoGroupLeadershipAbility=0x0068 # C
|
||||
OP_GroupLeadershipAAUpdate=0x167b # C
|
||||
OP_DelegateAbility=0x6e58 # C
|
||||
@ -487,6 +489,8 @@ OP_GroupDisbandOther=0x49f6 # C
|
||||
OP_GroupLeaderChange=0x0c33 # C
|
||||
OP_GroupRoles=0x116d # C
|
||||
OP_GroupMakeLeader=0x5851
|
||||
OP_GroupMentor=0x292f
|
||||
OP_InspectBuffs=0x105b
|
||||
|
||||
# LFG/LFP Opcodes
|
||||
OP_LFGCommand=0x2c38 # C
|
||||
@ -654,3 +658,8 @@ OP_RAWOutOfSession=0x0000 #
|
||||
# we need to document the differences between these packets to make identifying them easier
|
||||
OP_Some3ByteHPUpdate=0x0000 # initial HP update for mobs
|
||||
OP_InitialHPUpdate=0x0000 #
|
||||
|
||||
OP_ItemRecastDelay=0x82d7
|
||||
|
||||
# unhandled
|
||||
OP_ShieldGroup=0x23a1
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
-- A fix for the auto-conversion view renaming issue
|
||||
|
||||
|
||||
DROP VIEW IF EXISTS `vwbotcharactermobs`;
|
||||
DROP VIEW IF EXISTS `vwbotgroups`;
|
||||
DROP VIEW IF EXISTS `vwgroups`;
|
||||
DROP VIEW IF EXISTS `vwguildmembers`;
|
||||
|
||||
|
||||
CREATE VIEW `vwBotCharacterMobs` AS
|
||||
SELECT _utf8'C' AS mobtype,
|
||||
c.`id`,
|
||||
c.`name`,
|
||||
c.`class`,
|
||||
c.`level`,
|
||||
c.`last_login`,
|
||||
c.`zone_id`
|
||||
FROM `character_data` AS c
|
||||
UNION ALL
|
||||
SELECT _utf8'B' AS mobtype,
|
||||
b.`BotID` AS id,
|
||||
b.`Name` AS name,
|
||||
b.`Class` AS class,
|
||||
b.`BotLevel` AS level,
|
||||
0 AS timelaston,
|
||||
0 AS zoneid
|
||||
FROM bots AS b;
|
||||
|
||||
CREATE VIEW `vwGroups` AS
|
||||
SELECT g.`groupid` AS groupid,
|
||||
GetMobType(g.`name`) AS mobtype,
|
||||
g.`name` AS name,
|
||||
g.`charid` AS mobid,
|
||||
IFNULL(c.`level`, b.`BotLevel`) AS level
|
||||
FROM `group_id` AS g
|
||||
LEFT JOIN `character_data` AS c ON g.`name` = c.`name`
|
||||
LEFT JOIN `bots` AS b ON g.`name` = b.`Name`;
|
||||
|
||||
CREATE VIEW `vwBotGroups` AS
|
||||
SELECT g.`BotGroupId`,
|
||||
g.`BotGroupName`,
|
||||
g.`BotGroupLeaderBotId`,
|
||||
b.`Name` AS BotGroupLeaderName,
|
||||
b.`BotOwnerCharacterId`,
|
||||
c.`name` AS BotOwnerCharacterName
|
||||
FROM `botgroup` AS g
|
||||
JOIN `bots` AS b ON g.`BotGroupLeaderBotId` = b.`BotID`
|
||||
JOIN `character_data` AS c ON b.`BotOwnerCharacterID` = c.`id`
|
||||
ORDER BY b.`BotOwnerCharacterId`, g.`BotGroupName`;
|
||||
|
||||
CREATE VIEW `vwGuildMembers` AS
|
||||
SELECT 'C' AS mobtype,
|
||||
cm.`char_id`,
|
||||
cm.`guild_id`,
|
||||
cm.`rank`,
|
||||
cm.`tribute_enable`,
|
||||
cm.`total_tribute`,
|
||||
cm.`last_tribute`,
|
||||
cm.`banker`,
|
||||
cm.`public_note`,
|
||||
cm.`alt`
|
||||
FROM `guild_members` AS cm
|
||||
UNION ALL
|
||||
SELECT 'B' AS mobtype,
|
||||
bm.`char_id`,
|
||||
bm.`guild_id`,
|
||||
bm.`rank`,
|
||||
bm.`tribute_enable`,
|
||||
bm.`total_tribute`,
|
||||
bm.`last_tribute`,
|
||||
bm.`banker`,
|
||||
bm.`public_note`,
|
||||
bm.`alt`
|
||||
FROM `botguildmembers` AS bm;
|
||||
280
utils/sql/git/bots/deprecated/load_bots_old.sql
Normal file
280
utils/sql/git/bots/deprecated/load_bots_old.sql
Normal file
@ -0,0 +1,280 @@
|
||||
-- 'load_bots_old' sql script file
|
||||
-- current as of 10/15/2014
|
||||
--
|
||||
-- Use this file on databases where the player profile blob has not been converted
|
||||
--
|
||||
-- Note: This file assumes a database free of bot remnants. If you have a prior
|
||||
-- bot installation and wish to reload the default schema and entries, then
|
||||
-- source 'drop_bots.sql' before sourcing this file.
|
||||
|
||||
|
||||
ALTER TABLE `guild_members` DROP PRIMARY KEY;
|
||||
ALTER TABLE `group_id` DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(`groupid`, `charid`, `name`, `ismerc`);
|
||||
|
||||
UPDATE `spawn2` SET `enabled` = 1 WHERE `id` IN (59297,59298);
|
||||
|
||||
-- old command kept for reference (`commands` now only has 2 columns - `command` and `access`)
|
||||
-- INSERT INTO `commands` VALUES ('bot', '0', 'Type \"#bot help\" to the see the list of available commands for bots.');
|
||||
INSERT INTO `commands` VALUES ('bot', '0');
|
||||
|
||||
INSERT INTO `rule_values` VALUES
|
||||
('1', 'Bots:BotAAExpansion', '8', 'The expansion through which bots will obtain AAs'),
|
||||
('1', 'Bots:BotFinishBuffing', 'false', 'Allow for buffs to complete even if the bot caster is out of mana. Only affects buffing out of combat.'),
|
||||
('1', 'Bots:BotGroupBuffing', 'false', 'Bots will cast single target buffs as group buffs, default is false for single. Does not make single target buffs work for MGB.'),
|
||||
('1', 'Bots:BotManaRegen', '3.0', 'Adjust mana regen for bots, 1 is fast and higher numbers slow it down 3 is about the same as players.'),
|
||||
('1', 'Bots:BotQuest', 'false', 'Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl'),
|
||||
('1', 'Bots:BotSpellQuest', 'false', 'Anita Thrall\'s (Anita_Thrall.pl) Bot Spell Scriber quests.'),
|
||||
('1', 'Bots:CreateBotCount', '150', 'Number of bots that each account can create'),
|
||||
('1', 'Bots:SpawnBotCount', '71', 'Number of bots a character can have spawned at one time, You + 71 bots is a 12 group raid');
|
||||
|
||||
CREATE TABLE `bots` (
|
||||
`BotID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`BotOwnerCharacterID` INT(10) UNSIGNED NOT NULL,
|
||||
`BotSpellsID` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`Name` VARCHAR(64) NOT NULL,
|
||||
`LastName` VARCHAR(32) DEFAULT NULL,
|
||||
`BotLevel` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`Race` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`Class` TINYINT(2) NOT NULL DEFAULT '0',
|
||||
`Gender` TINYINT(2) NOT NULL DEFAULT '0',
|
||||
`Size` FLOAT NOT NULL DEFAULT '0',
|
||||
`Face` INT(10) NOT NULL DEFAULT '1',
|
||||
`LuclinHairStyle` INT(10) NOT NULL DEFAULT '1',
|
||||
`LuclinHairColor` INT(10) NOT NULL DEFAULT '1',
|
||||
`LuclinEyeColor` INT(10) NOT NULL DEFAULT '1',
|
||||
`LuclinEyeColor2` INT(10) NOT NULL DEFAULT '1',
|
||||
`LuclinBeardColor` INT(10) NOT NULL DEFAULT '1',
|
||||
`LuclinBeard` INT(10) NOT NULL DEFAULT '0',
|
||||
`DrakkinHeritage` INT(10) NOT NULL DEFAULT '0',
|
||||
`DrakkinTattoo` INT(10) NOT NULL DEFAULT '0',
|
||||
`DrakkinDetails` INT(10) NOT NULL DEFAULT '0',
|
||||
`HP` INTEGER NOT NULL DEFAULT '0',
|
||||
`Mana` INTEGER NOT NULL DEFAULT '0',
|
||||
`MR` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`CR` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`DR` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`FR` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`PR` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`Corrup` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`AC` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`STR` MEDIUMINT(8) NOT NULL DEFAULT '75',
|
||||
`STA` MEDIUMINT(8) NOT NULL DEFAULT '75',
|
||||
`DEX` MEDIUMINT(8) NOT NULL DEFAULT '75',
|
||||
`AGI` MEDIUMINT(8) NOT NULL DEFAULT '75',
|
||||
`_INT` MEDIUMINT(8) NOT NULL DEFAULT '80',
|
||||
`WIS` MEDIUMINT(8) NOT NULL DEFAULT '75',
|
||||
`CHA` MEDIUMINT(8) NOT NULL DEFAULT '75',
|
||||
`ATK` MEDIUMINT(9) NOT NULL DEFAULT '0',
|
||||
`BotCreateDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`LastSpawnDate` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`TotalPlayTime` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`LastZoneId` SMALLINT(6) NOT NULL DEFAULT '0',
|
||||
`BotInspectMessage` VARCHAR(256) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`BotID`)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE `botstances` (
|
||||
`BotID` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`StanceID` TINYINT UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotID`),
|
||||
CONSTRAINT `FK_botstances_1` FOREIGN KEY (`BotID`) REFERENCES `bots` (`BotID`)
|
||||
);
|
||||
|
||||
CREATE TABLE `bottimers` (
|
||||
`BotID` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`TimerID` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`Value` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotID`),
|
||||
CONSTRAINT `FK_bottimers_1` FOREIGN KEY (`BotID`) REFERENCES `bots` (`BotID`)
|
||||
);
|
||||
|
||||
CREATE TABLE `botbuffs` (
|
||||
`BotBuffId` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`BotId` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`SpellId` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`CasterLevel` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`DurationFormula` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`TicsRemaining` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`PoisonCounters` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`DiseaseCounters` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`CurseCounters` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`CorruptionCounters` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`HitCount` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`MeleeRune` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`MagicRune` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`DeathSaveSuccessChance` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`CasterAARank` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`Persistent` TINYINT(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotBuffId`),
|
||||
KEY `FK_botbuff_1` (`BotId`),
|
||||
CONSTRAINT `FK_botbuff_1` FOREIGN KEY (`BotId`) REFERENCES `bots` (`BotID`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE `botinventory` (
|
||||
`BotInventoryID` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`BotID` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
`SlotID` INTEGER SIGNED NOT NULL DEFAULT '0',
|
||||
`ItemID` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
`charges` TINYINT(3) UNSIGNED DEFAULT 0,
|
||||
`color` INTEGER UNSIGNED NOT NULL DEFAULT 0,
|
||||
`augslot1` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`augslot2` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`augslot3` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`augslot4` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`augslot5` MEDIUMINT(7) UNSIGNED DEFAULT 0,
|
||||
`instnodrop` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`BotInventoryID`),
|
||||
KEY `FK_botinventory_1` (`BotID`),
|
||||
CONSTRAINT `FK_botinventory_1` FOREIGN KEY (`BotID`) REFERENCES `bots` (`BotID`)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE `botpets` (
|
||||
`BotPetsId` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`PetId` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
`BotId` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
`Name` VARCHAR(64) NULL,
|
||||
`Mana` INTEGER NOT NULL DEFAULT '0',
|
||||
`HitPoints` INTEGER NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotPetsId`),
|
||||
KEY `FK_botpets_1` (`BotId`),
|
||||
CONSTRAINT `FK_botpets_1` FOREIGN KEY (`BotId`) REFERENCES `bots` (`BotID`),
|
||||
CONSTRAINT `U_botpets_1` UNIQUE (`BotId`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE `botpetbuffs` (
|
||||
`BotPetBuffId` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`BotPetsId` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`SpellId` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`CasterLevel` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`Duration` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotPetBuffId`),
|
||||
KEY `FK_botpetbuffs_1` (`BotPetsId`),
|
||||
CONSTRAINT `FK_botpetbuffs_1` FOREIGN KEY (`BotPetsId`) REFERENCES `botpets` (`BotPetsID`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE `botpetinventory` (
|
||||
`BotPetInventoryId` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`BotPetsId` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
`ItemId` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotPetInventoryId`),
|
||||
KEY `FK_botpetinventory_1` (`BotPetsId`),
|
||||
CONSTRAINT `FK_botpetinventory_1` FOREIGN KEY (`BotPetsId`) REFERENCES `botpets` (`BotPetsID`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE `botgroup` (
|
||||
`BotGroupId` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`BotGroupLeaderBotId` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
`BotGroupName` VARCHAR(64) NOT NULL,
|
||||
PRIMARY KEY (`BotGroupId`),
|
||||
KEY `FK_botgroup_1` (`BotGroupLeaderBotId`),
|
||||
CONSTRAINT `FK_botgroup_1` FOREIGN KEY (`BotGroupLeaderBotId`) REFERENCES `bots` (`BotID`)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE `botgroupmembers` (
|
||||
`BotGroupMemberId` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`BotGroupId` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
`BotId` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotGroupMemberId`),
|
||||
KEY `FK_botgroupmembers_1` (`BotGroupId`),
|
||||
CONSTRAINT `FK_botgroupmembers_1` FOREIGN KEY (`BotGroupId`) REFERENCES `botgroup` (`BotGroupId`),
|
||||
KEY `FK_botgroupmembers_2` (`BotId`),
|
||||
CONSTRAINT `FK_botgroupmembers_2` FOREIGN KEY (`BotId`) REFERENCES `bots` (`BotID`)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE `botguildmembers` (
|
||||
`char_id` INT(11) NOT NULL DEFAULT '0',
|
||||
`guild_id` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`rank` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`tribute_enable` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`total_tribute` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`last_tribute` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`banker` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`public_note` TEXT NULL,
|
||||
`alt` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`char_id`)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
DELIMITER //
|
||||
|
||||
CREATE FUNCTION `GetMobType` (mobname VARCHAR(64)) RETURNS CHAR(1)
|
||||
BEGIN
|
||||
DECLARE Result CHAR(1);
|
||||
|
||||
SET Result = NULL;
|
||||
|
||||
IF (SELECT COUNT(*) FROM `character_` WHERE `name` = mobname) > 0 THEN
|
||||
SET Result = 'C';
|
||||
ELSEIF (SELECT COUNT(*) FROM `bots` WHERE `Name` = mobname) > 0 THEN
|
||||
SET Result = 'B';
|
||||
END IF;
|
||||
|
||||
RETURN Result;
|
||||
END//
|
||||
|
||||
DELIMITER ;
|
||||
|
||||
CREATE VIEW `vwBotCharacterMobs` AS
|
||||
SELECT _utf8'C' AS mobtype,
|
||||
c.`id`,
|
||||
c.`name`,
|
||||
c.`class`,
|
||||
c.`level`,
|
||||
c.`timelaston`,
|
||||
c.`zoneid`
|
||||
FROM `character_` AS c
|
||||
UNION ALL
|
||||
SELECT _utf8'B' AS mobtype,
|
||||
b.`BotID` AS id,
|
||||
b.`Name` AS name,
|
||||
b.`Class` AS class,
|
||||
b.`BotLevel` AS level,
|
||||
0 AS timelaston,
|
||||
0 AS zoneid
|
||||
FROM bots AS b;
|
||||
|
||||
CREATE VIEW `vwGroups` AS
|
||||
SELECT g.`groupid` AS groupid,
|
||||
GetMobType(g.`name`) AS mobtype,
|
||||
g.`name` AS name,
|
||||
g.`charid` AS mobid,
|
||||
IFNULL(c.`level`, b.`BotLevel`) AS level
|
||||
FROM `group_id` AS g
|
||||
LEFT JOIN `character_` AS c ON g.`name` = c.`name`
|
||||
LEFT JOIN `bots` AS b ON g.`name` = b.`Name`;
|
||||
|
||||
CREATE VIEW `vwBotGroups` AS
|
||||
SELECT g.`BotGroupId`,
|
||||
g.`BotGroupName`,
|
||||
g.`BotGroupLeaderBotId`,
|
||||
b.`Name` AS BotGroupLeaderName,
|
||||
b.`BotOwnerCharacterId`,
|
||||
c.`name` AS BotOwnerCharacterName
|
||||
FROM `botgroup` AS g
|
||||
JOIN `bots` AS b ON g.`BotGroupLeaderBotId` = b.`BotID`
|
||||
JOIN `character_` AS c ON b.`BotOwnerCharacterID` = c.`id`
|
||||
ORDER BY b.`BotOwnerCharacterId`, g.`BotGroupName`;
|
||||
|
||||
CREATE VIEW `vwGuildMembers` AS
|
||||
SELECT 'C' AS mobtype,
|
||||
cm.`char_id`,
|
||||
cm.`guild_id`,
|
||||
cm.`rank`,
|
||||
cm.`tribute_enable`,
|
||||
cm.`total_tribute`,
|
||||
cm.`last_tribute`,
|
||||
cm.`banker`,
|
||||
cm.`public_note`,
|
||||
cm.`alt`
|
||||
FROM `guild_members` AS cm
|
||||
UNION ALL
|
||||
SELECT 'B' AS mobtype,
|
||||
bm.`char_id`,
|
||||
bm.`guild_id`,
|
||||
bm.`rank`,
|
||||
bm.`tribute_enable`,
|
||||
bm.`total_tribute`,
|
||||
bm.`last_tribute`,
|
||||
bm.`banker`,
|
||||
bm.`public_note`,
|
||||
bm.`alt`
|
||||
FROM `botguildmembers` AS bm;
|
||||
@ -1,21 +1,41 @@
|
||||
DROP TABLE IF EXISTS `botbuffs`;
|
||||
-- 'drop_bots' sql script file
|
||||
-- current as of 10/15/2014
|
||||
--
|
||||
-- Note: This file will revert all changes made by either 'load_bots' sql file.
|
||||
-- There may still be remnants of bot activity in tables `guild_members` and
|
||||
-- `group_id`. If these entries are causing issues, you may need to manually
|
||||
-- remove them.
|
||||
--
|
||||
-- If this script fails due to a 'SQL Error (1068): Multiple primary key defined'
|
||||
-- error, run this query: ALTER TABLE `guild_members` DROP PRIMARY KEY;
|
||||
-- and it should remove the key so this script will process in its entirety.
|
||||
|
||||
|
||||
ALTER TABLE `guild_members` ADD PRIMARY KEY (`char_id`);
|
||||
ALTER TABLE `group_id` DROP PRIMARY KEY, ADD PRIMARY KEY (`groupid`, `charid`, `ismerc`);
|
||||
|
||||
UPDATE `spawn2` SET `enabled` = 0 WHERE `id` IN (59297,59298);
|
||||
|
||||
DELETE FROM `commands` WHERE `command` = 'bot';
|
||||
DELETE FROM `rule_values` WHERE `rule_name` LIKE 'Bots%';
|
||||
|
||||
DROP VIEW IF EXISTS `vwBotCharacterMobs`;
|
||||
DROP VIEW IF EXISTS `vwBotGroups`;
|
||||
DROP VIEW IF EXISTS `vwGroups`;
|
||||
DROP VIEW IF EXISTS `vwGuildMembers`;
|
||||
|
||||
DROP FUNCTION IF EXISTS `GetMobType`;
|
||||
|
||||
DROP TABLE IF EXISTS `botguildmembers`;
|
||||
DROP TABLE IF EXISTS `botgroupmembers`;
|
||||
-- this table is not a part of 'load_bots.sql'
|
||||
DROP TABLE IF EXISTS `botgroups`;
|
||||
DROP TABLE IF EXISTS `botgroup`;
|
||||
DROP TABLE IF EXISTS `botpetinventory`;
|
||||
DROP TABLE IF EXISTS `botpetbuffs`;
|
||||
DROP TABLE IF EXISTS `botpets`;
|
||||
DROP TABLE IF EXISTS `botgroupmembers`;
|
||||
DROP TABLE IF EXISTS `botgroup`;
|
||||
DROP TABLE IF EXISTS `botgroups`;
|
||||
DROP TABLE IF EXISTS `botinventory`;
|
||||
DROP TABLE IF EXISTS `botguildmembers`;
|
||||
DROP TABLE IF EXISTS `botstances`;
|
||||
DROP TABLE IF EXISTS `botbuffs`;
|
||||
DROP TABLE IF EXISTS `bottimers`;
|
||||
DROP TABLE IF EXISTS `botstances`;
|
||||
DROP TABLE IF EXISTS `bots`;
|
||||
DROP VIEW IF EXISTS `vwGuildMembers`;
|
||||
DROP VIEW IF EXISTS `vwBotCharacterMobs`;
|
||||
DROP VIEW IF EXISTS `vwBotGroups`;
|
||||
|
||||
delete from rule_values where rule_name like 'Bots%' and ruleset_id = 1;
|
||||
|
||||
delete from commands where command = 'bot';
|
||||
|
||||
update spawn2 set enabled = 0 where id in (59297,59298);
|
||||
@ -1,307 +1,280 @@
|
||||
-- This is pretty much a straight copy of the original files with fixes applied.
|
||||
-- HeidiSQL does not like sub-directory references, so this should now run from there.
|
||||
-- The 'headers' are left in place for reference only.
|
||||
-- 'load_bots' sql script file
|
||||
-- current as of 10/15/2014
|
||||
--
|
||||
-- Use this file on databases where the player profile blob has been converted.
|
||||
--
|
||||
-- Note: This file assumes a database free of bot remnants. If you have a prior
|
||||
-- bot installation and wish to reload the default schema and entries, then
|
||||
-- source 'drop_bots.sql' before sourcing this file.
|
||||
|
||||
-- FILE:
|
||||
-- source player_tables/botguildmembers.sql;
|
||||
CREATE TABLE IF NOT EXISTS `botguildmembers` (
|
||||
`char_id` int(11) NOT NULL default '0',
|
||||
`guild_id` mediumint(8) unsigned NOT NULL default '0',
|
||||
`rank` tinyint(3) unsigned NOT NULL default '0',
|
||||
`tribute_enable` tinyint(3) unsigned NOT NULL default '0',
|
||||
`total_tribute` int(10) unsigned NOT NULL default '0',
|
||||
`last_tribute` int(10) unsigned NOT NULL default '0',
|
||||
`banker` tinyint(3) unsigned NOT NULL default '0',
|
||||
`public_note` text NULL,
|
||||
`alt` tinyint(3) unsigned NOT NULL default '0',
|
||||
PRIMARY KEY (`char_id`)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
-- FILE:
|
||||
-- source player_tables/bots.sql;
|
||||
update spawn2 set enabled = 1 where id in (59297,59298);
|
||||
ALTER TABLE `guild_members` DROP PRIMARY KEY;
|
||||
ALTER TABLE `group_id` DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(`groupid`, `charid`, `name`, `ismerc`);
|
||||
|
||||
INSERT INTO rule_values VALUES ('1', 'Bots:BotManaRegen', '3.0', 'Adjust mana regen for bots, 1 is fast and higher numbers slow it down 3 is about the same as players.');
|
||||
INSERT INTO rule_values VALUES ('1', 'Bots:BotFinishBuffing', 'false', 'Allow for buffs to complete even if the bot caster is out of mana. Only affects buffing out of combat.');
|
||||
INSERT INTO rule_values VALUES ('1', 'Bots:CreateBotCount', '150', 'Number of bots that each account can create');
|
||||
INSERT INTO rule_values VALUES ('1', 'Bots:SpawnBotCount', '71', 'Number of bots a character can have spawned at one time, You + 71 bots is a 12 group raid');
|
||||
INSERT INTO rule_values VALUES ('1', 'Bots:BotQuest', 'false', 'Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl');
|
||||
INSERT INTO rule_values VALUES ('1', 'Bots:BotGroupBuffing', 'false', 'Bots will cast single target buffs as group buffs, default is false for single. Does not make single target buffs work for MGB.');
|
||||
INSERT INTO rule_values VALUES ('1', 'Bots:BotSpellQuest', 'false', 'Anita Thrall\'s (Anita_Thrall.pl) Bot Spell Scriber quests.');
|
||||
UPDATE `spawn2` SET `enabled` = 1 WHERE `id` IN (59297,59298);
|
||||
|
||||
-- this is a hack fix to maintain the original file process
|
||||
delete from rule_values where rule_name like 'Bots%' and ruleset_id = 1;
|
||||
INSERT INTO rule_values VALUES ('1', 'Bots:BotAAExpansion', '8', 'The expansion through which bots will obtain AAs');
|
||||
|
||||
-- field count has changed
|
||||
-- old command kept for reference (`commands` now only has 2 columns - `command` and `access`)
|
||||
-- INSERT INTO `commands` VALUES ('bot', '0', 'Type \"#bot help\" to the see the list of available commands for bots.');
|
||||
INSERT INTO `commands` VALUES ('bot', '0');
|
||||
|
||||
CREATE TABLE bots (
|
||||
`BotID` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`BotOwnerCharacterID` int(10) unsigned NOT NULL,
|
||||
`BotSpellsID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`Name` varchar(64) NOT NULL,
|
||||
`LastName` varchar(32) DEFAULT NULL,
|
||||
`BotLevel` tinyint(2) unsigned NOT NULL DEFAULT '0',
|
||||
`Race` smallint(5) NOT NULL DEFAULT '0',
|
||||
`Class` tinyint(2) NOT NULL DEFAULT '0',
|
||||
`Gender` tinyint(2) NOT NULL DEFAULT '0',
|
||||
`Size` float NOT NULL DEFAULT '0',
|
||||
`Face` int(10) NOT NULL DEFAULT '1',
|
||||
`LuclinHairStyle` int(10) NOT NULL DEFAULT '1',
|
||||
`LuclinHairColor` int(10) NOT NULL DEFAULT '1',
|
||||
`LuclinEyeColor` int(10) NOT NULL DEFAULT '1',
|
||||
`LuclinEyeColor2` int(10) NOT NULL DEFAULT '1',
|
||||
`LuclinBeardColor` int(10) NOT NULL DEFAULT '1',
|
||||
`LuclinBeard` int(10) NOT NULL DEFAULT '0',
|
||||
`DrakkinHeritage` int(10) NOT NULL DEFAULT '0',
|
||||
`DrakkinTattoo` int(10) NOT NULL DEFAULT '0',
|
||||
`DrakkinDetails` int(10) NOT NULL DEFAULT '0',
|
||||
`HP` INTEGER NOT NULL DEFAULT '0',
|
||||
`Mana` INTEGER NOT NULL DEFAULT '0',
|
||||
`MR` smallint(5) NOT NULL DEFAULT '0',
|
||||
`CR` smallint(5) NOT NULL DEFAULT '0',
|
||||
`DR` smallint(5) NOT NULL DEFAULT '0',
|
||||
`FR` smallint(5) NOT NULL DEFAULT '0',
|
||||
`PR` smallint(5) NOT NULL DEFAULT '0',
|
||||
`Corrup` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`AC` smallint(5) NOT NULL DEFAULT '0',
|
||||
`STR` mediumint(8) NOT NULL DEFAULT '75',
|
||||
`STA` mediumint(8) NOT NULL DEFAULT '75',
|
||||
`DEX` mediumint(8) NOT NULL DEFAULT '75',
|
||||
`AGI` mediumint(8) NOT NULL DEFAULT '75',
|
||||
`_INT` mediumint(8) NOT NULL DEFAULT '80',
|
||||
`WIS` mediumint(8) NOT NULL DEFAULT '75',
|
||||
`CHA` mediumint(8) NOT NULL DEFAULT '75',
|
||||
`ATK` mediumint(9) NOT NULL DEFAULT '0',
|
||||
`BotCreateDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`LastSpawnDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`TotalPlayTime` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`LastZoneId` smallint(6) NOT NULL DEFAULT '0',
|
||||
`BotInspectMessage` VARCHAR(256) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`BotID`)
|
||||
INSERT INTO `rule_values` VALUES
|
||||
('1', 'Bots:BotAAExpansion', '8', 'The expansion through which bots will obtain AAs'),
|
||||
('1', 'Bots:BotFinishBuffing', 'false', 'Allow for buffs to complete even if the bot caster is out of mana. Only affects buffing out of combat.'),
|
||||
('1', 'Bots:BotGroupBuffing', 'false', 'Bots will cast single target buffs as group buffs, default is false for single. Does not make single target buffs work for MGB.'),
|
||||
('1', 'Bots:BotManaRegen', '3.0', 'Adjust mana regen for bots, 1 is fast and higher numbers slow it down 3 is about the same as players.'),
|
||||
('1', 'Bots:BotQuest', 'false', 'Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl'),
|
||||
('1', 'Bots:BotSpellQuest', 'false', 'Anita Thrall\'s (Anita_Thrall.pl) Bot Spell Scriber quests.'),
|
||||
('1', 'Bots:CreateBotCount', '150', 'Number of bots that each account can create'),
|
||||
('1', 'Bots:SpawnBotCount', '71', 'Number of bots a character can have spawned at one time, You + 71 bots is a 12 group raid');
|
||||
|
||||
CREATE TABLE `bots` (
|
||||
`BotID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`BotOwnerCharacterID` INT(10) UNSIGNED NOT NULL,
|
||||
`BotSpellsID` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`Name` VARCHAR(64) NOT NULL,
|
||||
`LastName` VARCHAR(32) DEFAULT NULL,
|
||||
`BotLevel` TINYINT(2) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`Race` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`Class` TINYINT(2) NOT NULL DEFAULT '0',
|
||||
`Gender` TINYINT(2) NOT NULL DEFAULT '0',
|
||||
`Size` FLOAT NOT NULL DEFAULT '0',
|
||||
`Face` INT(10) NOT NULL DEFAULT '1',
|
||||
`LuclinHairStyle` INT(10) NOT NULL DEFAULT '1',
|
||||
`LuclinHairColor` INT(10) NOT NULL DEFAULT '1',
|
||||
`LuclinEyeColor` INT(10) NOT NULL DEFAULT '1',
|
||||
`LuclinEyeColor2` INT(10) NOT NULL DEFAULT '1',
|
||||
`LuclinBeardColor` INT(10) NOT NULL DEFAULT '1',
|
||||
`LuclinBeard` INT(10) NOT NULL DEFAULT '0',
|
||||
`DrakkinHeritage` INT(10) NOT NULL DEFAULT '0',
|
||||
`DrakkinTattoo` INT(10) NOT NULL DEFAULT '0',
|
||||
`DrakkinDetails` INT(10) NOT NULL DEFAULT '0',
|
||||
`HP` INTEGER NOT NULL DEFAULT '0',
|
||||
`Mana` INTEGER NOT NULL DEFAULT '0',
|
||||
`MR` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`CR` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`DR` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`FR` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`PR` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`Corrup` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`AC` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`STR` MEDIUMINT(8) NOT NULL DEFAULT '75',
|
||||
`STA` MEDIUMINT(8) NOT NULL DEFAULT '75',
|
||||
`DEX` MEDIUMINT(8) NOT NULL DEFAULT '75',
|
||||
`AGI` MEDIUMINT(8) NOT NULL DEFAULT '75',
|
||||
`_INT` MEDIUMINT(8) NOT NULL DEFAULT '80',
|
||||
`WIS` MEDIUMINT(8) NOT NULL DEFAULT '75',
|
||||
`CHA` MEDIUMINT(8) NOT NULL DEFAULT '75',
|
||||
`ATK` MEDIUMINT(9) NOT NULL DEFAULT '0',
|
||||
`BotCreateDate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`LastSpawnDate` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`TotalPlayTime` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`LastZoneId` SMALLINT(6) NOT NULL DEFAULT '0',
|
||||
`BotInspectMessage` VARCHAR(256) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`BotID`)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
ALTER TABLE `group_id` DROP PRIMARY KEY, ADD PRIMARY KEY USING BTREE(`groupid`, `charid`, `name`);
|
||||
ALTER TABLE `guild_members` DROP PRIMARY KEY;
|
||||
CREATE TABLE `botstances` (
|
||||
`BotID` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`StanceID` TINYINT UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotID`),
|
||||
CONSTRAINT `FK_botstances_1` FOREIGN KEY (`BotID`) REFERENCES `bots` (`BotID`)
|
||||
);
|
||||
|
||||
DROP VIEW IF EXISTS `vwGuildMembers`;
|
||||
CREATE VIEW `vwGuildMembers` AS
|
||||
select 'C' as mobtype,
|
||||
cm.char_id,
|
||||
cm.guild_id,
|
||||
cm.rank,
|
||||
cm.tribute_enable,
|
||||
cm.total_tribute,
|
||||
cm.last_tribute,
|
||||
cm.banker,
|
||||
cm.public_note,
|
||||
cm.alt
|
||||
from guild_members as cm
|
||||
union all
|
||||
select 'B' as mobtype,
|
||||
bm.char_id,
|
||||
bm.guild_id,
|
||||
bm.rank,
|
||||
bm.tribute_enable,
|
||||
bm.total_tribute,
|
||||
bm.last_tribute,
|
||||
bm.banker,
|
||||
bm.public_note,
|
||||
bm.alt
|
||||
from botguildmembers as bm;
|
||||
CREATE TABLE `bottimers` (
|
||||
`BotID` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`TimerID` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`Value` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotID`),
|
||||
CONSTRAINT `FK_bottimers_1` FOREIGN KEY (`BotID`) REFERENCES `bots` (`BotID`)
|
||||
);
|
||||
|
||||
DROP VIEW IF EXISTS `vwBotCharacterMobs`;
|
||||
CREATE VIEW `vwBotCharacterMobs` AS
|
||||
select 'C' as mobtype,
|
||||
c.id,
|
||||
c.name,
|
||||
c.class,
|
||||
c.level,
|
||||
c.timelaston,
|
||||
c.zoneid
|
||||
from character_ as c
|
||||
union all
|
||||
select 'B' as mobtype,
|
||||
b.BotID as id,
|
||||
b.Name as name,
|
||||
b.Class as class,
|
||||
b.BotLevel as level,
|
||||
0 as timelaston,
|
||||
0 as zoneid
|
||||
from bots as b;
|
||||
|
||||
-- FILE:
|
||||
-- source player_tables/botpetstatepersists.sql;
|
||||
DROP TABLE IF EXISTS `botpetinventory`;
|
||||
DROP TABLE IF EXISTS `botpetbuffs`;
|
||||
DROP TABLE IF EXISTS `botpets`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `botpets` (
|
||||
`BotPetsId` integer unsigned NOT NULL AUTO_INCREMENT,
|
||||
`PetId` integer unsigned NOT NULL DEFAULT '0',
|
||||
`BotId` integer unsigned NOT NULL DEFAULT '0',
|
||||
`Name` varchar(64) NULL,
|
||||
`Mana` integer NOT NULL DEFAULT '0',
|
||||
`HitPoints` integer NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotPetsId`),
|
||||
KEY `FK_botpets_1` (`BotId`),
|
||||
CONSTRAINT `FK_botpets_1` FOREIGN KEY (`BotId`) REFERENCES `bots` (`BotID`),
|
||||
CONSTRAINT `U_botpets_1` UNIQUE (`BotId`)
|
||||
CREATE TABLE `botbuffs` (
|
||||
`BotBuffId` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`BotId` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`SpellId` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`CasterLevel` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`DurationFormula` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`TicsRemaining` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`PoisonCounters` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`DiseaseCounters` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`CurseCounters` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`CorruptionCounters` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`HitCount` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`MeleeRune` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`MagicRune` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`DeathSaveSuccessChance` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`CasterAARank` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`Persistent` TINYINT(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotBuffId`),
|
||||
KEY `FK_botbuff_1` (`BotId`),
|
||||
CONSTRAINT `FK_botbuff_1` FOREIGN KEY (`BotId`) REFERENCES `bots` (`BotID`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `botpetbuffs` (
|
||||
`BotPetBuffId` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`BotPetsId` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`SpellId` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`CasterLevel` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`Duration` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotPetBuffId`),
|
||||
KEY `FK_botpetbuffs_1` (`BotPetsId`),
|
||||
CONSTRAINT `FK_botpetbuffs_1` FOREIGN KEY (`BotPetsId`) REFERENCES `botpets` (`BotPetsID`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `botpetinventory` (
|
||||
`BotPetInventoryId` integer unsigned NOT NULL AUTO_INCREMENT,
|
||||
`BotPetsId` integer unsigned NOT NULL DEFAULT '0',
|
||||
`ItemId` integer unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotPetInventoryId`),
|
||||
KEY `FK_botpetinventory_1` (`BotPetsId`),
|
||||
CONSTRAINT `FK_botpetinventory_1` FOREIGN KEY (`BotPetsId`) REFERENCES `botpets` (`BotPetsID`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
|
||||
|
||||
-- FILE:
|
||||
-- source player_tables/botinventory.sql;
|
||||
CREATE TABLE IF NOT EXISTS botinventory (
|
||||
BotInventoryID integer unsigned NOT NULL auto_increment,
|
||||
BotID integer unsigned NOT NULL DEFAULT '0',
|
||||
SlotID integer signed NOT NULL DEFAULT '0',
|
||||
ItemID integer unsigned NOT NULL DEFAULT '0',
|
||||
charges tinyint(3) unsigned DEFAULT 0,
|
||||
color integer unsigned NOT NULL DEFAULT 0,
|
||||
augslot1 mediumint(7) unsigned NOT NULL DEFAULT 0,
|
||||
augslot2 mediumint(7) unsigned NOT NULL DEFAULT 0,
|
||||
augslot3 mediumint(7) unsigned NOT NULL DEFAULT 0,
|
||||
augslot4 mediumint(7) unsigned NOT NULL DEFAULT 0,
|
||||
augslot5 mediumint(7) unsigned DEFAULT 0,
|
||||
instnodrop tinyint(1) unsigned NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (BotInventoryID),
|
||||
KEY FK_botinventory_1 (BotID),
|
||||
CONSTRAINT FK_botinventory_1 FOREIGN KEY (BotID) REFERENCES bots (BotID)
|
||||
CREATE TABLE `botinventory` (
|
||||
`BotInventoryID` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`BotID` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
`SlotID` INTEGER SIGNED NOT NULL DEFAULT '0',
|
||||
`ItemID` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
`charges` TINYINT(3) UNSIGNED DEFAULT 0,
|
||||
`color` INTEGER UNSIGNED NOT NULL DEFAULT 0,
|
||||
`augslot1` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`augslot2` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`augslot3` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`augslot4` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`augslot5` MEDIUMINT(7) UNSIGNED DEFAULT 0,
|
||||
`instnodrop` TINYINT(1) UNSIGNED NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`BotInventoryID`),
|
||||
KEY `FK_botinventory_1` (`BotID`),
|
||||
CONSTRAINT `FK_botinventory_1` FOREIGN KEY (`BotID`) REFERENCES `bots` (`BotID`)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
-- FILE:
|
||||
-- source player_tables/botbuffs.sql;
|
||||
DROP TABLE IF EXISTS `botbuffs`;
|
||||
CREATE TABLE `botbuffs` (
|
||||
`BotBuffId` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`BotId` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`SpellId` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`CasterLevel` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`DurationFormula` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`TicsRemaining` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
`PoisonCounters` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
`DiseaseCounters` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
`CurseCounters` int(11) unsigned NOT NULL DEFAULT '0',
|
||||
`CorruptionCounters` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`HitCount` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`MeleeRune` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`MagicRune` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`DeathSaveSuccessChance` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`CasterAARank` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`Persistent` tinyint(1) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotBuffId`),
|
||||
KEY `FK_botbuff_1` (`BotId`),
|
||||
CONSTRAINT `FK_botbuff_1` FOREIGN KEY (`BotId`) REFERENCES `bots` (`BotID`)
|
||||
CREATE TABLE `botpets` (
|
||||
`BotPetsId` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`PetId` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
`BotId` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
`Name` VARCHAR(64) NULL,
|
||||
`Mana` INTEGER NOT NULL DEFAULT '0',
|
||||
`HitPoints` INTEGER NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotPetsId`),
|
||||
KEY `FK_botpets_1` (`BotId`),
|
||||
CONSTRAINT `FK_botpets_1` FOREIGN KEY (`BotId`) REFERENCES `bots` (`BotID`),
|
||||
CONSTRAINT `U_botpets_1` UNIQUE (`BotId`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
|
||||
|
||||
-- FILE:
|
||||
-- source player_tables/botadventuring.sql;
|
||||
DELIMITER $$
|
||||
CREATE TABLE `botpetbuffs` (
|
||||
`BotPetBuffId` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`BotPetsId` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`SpellId` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`CasterLevel` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`Duration` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotPetBuffId`),
|
||||
KEY `FK_botpetbuffs_1` (`BotPetsId`),
|
||||
CONSTRAINT `FK_botpetbuffs_1` FOREIGN KEY (`BotPetsId`) REFERENCES `botpets` (`BotPetsID`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE `botpetinventory` (
|
||||
`BotPetInventoryId` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`BotPetsId` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
`ItemId` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotPetInventoryId`),
|
||||
KEY `FK_botpetinventory_1` (`BotPetsId`),
|
||||
CONSTRAINT `FK_botpetinventory_1` FOREIGN KEY (`BotPetsId`) REFERENCES `botpets` (`BotPetsID`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE `botgroup` (
|
||||
`BotGroupId` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`BotGroupLeaderBotId` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
`BotGroupName` VARCHAR(64) NOT NULL,
|
||||
PRIMARY KEY (`BotGroupId`),
|
||||
KEY `FK_botgroup_1` (`BotGroupLeaderBotId`),
|
||||
CONSTRAINT `FK_botgroup_1` FOREIGN KEY (`BotGroupLeaderBotId`) REFERENCES `bots` (`BotID`)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE `botgroupmembers` (
|
||||
`BotGroupMemberId` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`BotGroupId` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
`BotId` INTEGER UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotGroupMemberId`),
|
||||
KEY `FK_botgroupmembers_1` (`BotGroupId`),
|
||||
CONSTRAINT `FK_botgroupmembers_1` FOREIGN KEY (`BotGroupId`) REFERENCES `botgroup` (`BotGroupId`),
|
||||
KEY `FK_botgroupmembers_2` (`BotId`),
|
||||
CONSTRAINT `FK_botgroupmembers_2` FOREIGN KEY (`BotId`) REFERENCES `bots` (`BotID`)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE `botguildmembers` (
|
||||
`char_id` INT(11) NOT NULL DEFAULT '0',
|
||||
`guild_id` MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`rank` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`tribute_enable` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`total_tribute` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`last_tribute` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`banker` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`public_note` TEXT NULL,
|
||||
`alt` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`char_id`)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
DELIMITER \\
|
||||
|
||||
DROP FUNCTION IF EXISTS `GetMobType` $$
|
||||
CREATE FUNCTION `GetMobType` (mobname VARCHAR(64)) RETURNS CHAR(1)
|
||||
BEGIN
|
||||
DECLARE Result CHAR(1);
|
||||
|
||||
SET Result = NULL;
|
||||
|
||||
IF (select count(*) from character_ where name = mobname) > 0 THEN
|
||||
SET Result = 'C';
|
||||
ELSEIF (select count(*) from bots where Name = mobname) > 0 THEN
|
||||
SET Result = 'B';
|
||||
END IF;
|
||||
|
||||
RETURN Result;
|
||||
END $$
|
||||
DECLARE Result CHAR(1);
|
||||
|
||||
SET Result = NULL;
|
||||
|
||||
IF (SELECT COUNT(*) FROM `character_data` WHERE `name` = mobname) > 0 THEN
|
||||
SET Result = 'C';
|
||||
ELSEIF (SELECT COUNT(*) FROM `bots` WHERE `Name` = mobname) > 0 THEN
|
||||
SET Result = 'B';
|
||||
END IF;
|
||||
|
||||
RETURN Result;
|
||||
END\\
|
||||
|
||||
DELIMITER ;
|
||||
|
||||
DROP VIEW IF EXISTS `vwGroups`;
|
||||
CREATE VIEW `vwBotCharacterMobs` AS
|
||||
SELECT _utf8'C' AS mobtype,
|
||||
c.`id`,
|
||||
c.`name`,
|
||||
c.`class`,
|
||||
c.`level`,
|
||||
c.`last_login`,
|
||||
c.`zone_id`
|
||||
FROM `character_data` AS c
|
||||
UNION ALL
|
||||
SELECT _utf8'B' AS mobtype,
|
||||
b.`BotID` AS id,
|
||||
b.`Name` AS name,
|
||||
b.`Class` AS class,
|
||||
b.`BotLevel` AS level,
|
||||
0 AS timelaston,
|
||||
0 AS zoneid
|
||||
FROM bots AS b;
|
||||
|
||||
CREATE VIEW `vwGroups` AS
|
||||
select g.groupid as groupid,
|
||||
GetMobType(g.name) as mobtype,
|
||||
g.name as name,
|
||||
g.charid as mobid,
|
||||
ifnull(c.level, b.BotLevel) as level
|
||||
from group_id as g
|
||||
left join character_ as c on g.name = c.name
|
||||
left join bots as b on g.name = b.Name;
|
||||
SELECT g.`groupid` AS groupid,
|
||||
GetMobType(g.`name`) AS mobtype,
|
||||
g.`name` AS name,
|
||||
g.`charid` AS mobid,
|
||||
IFNULL(c.`level`, b.`BotLevel`) AS level
|
||||
FROM `group_id` AS g
|
||||
LEFT JOIN `character_data` AS c ON g.`name` = c.`name`
|
||||
LEFT JOIN `bots` AS b ON g.`name` = b.`Name`;
|
||||
|
||||
-- FILE:
|
||||
-- source player_tables/botgroups.sql;
|
||||
DROP TABLE IF EXISTS `botgroupmembers`;
|
||||
DROP TABLE IF EXISTS `botgroup`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `botgroup` (
|
||||
`BotGroupId` integer unsigned NOT NULL AUTO_INCREMENT,
|
||||
`BotGroupLeaderBotId` integer unsigned NOT NULL DEFAULT '0',
|
||||
`BotGroupName` varchar(64) NOT NULL,
|
||||
PRIMARY KEY (`BotGroupId`),
|
||||
KEY FK_botgroup_1 (BotGroupLeaderBotId),
|
||||
CONSTRAINT FK_botgroup_1 FOREIGN KEY (BotGroupLeaderBotId) REFERENCES bots (BotID)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `botgroupmembers` (
|
||||
`BotGroupMemberId` integer unsigned NOT NULL AUTO_INCREMENT,
|
||||
`BotGroupId` integer unsigned NOT NULL DEFAULT '0',
|
||||
`BotId` integer unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`BotGroupMemberId`),
|
||||
KEY FK_botgroupmembers_1 (BotGroupId),
|
||||
CONSTRAINT FK_botgroupmembers_1 FOREIGN KEY (BotGroupId) REFERENCES botgroup (BotGroupId),
|
||||
KEY FK_botgroupmembers_2 (BotId),
|
||||
CONSTRAINT FK_botgroupmembers_2 FOREIGN KEY (BotId) REFERENCES bots (BotID)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
DROP VIEW IF EXISTS `vwBotGroups`;
|
||||
CREATE VIEW `vwBotGroups` AS
|
||||
select g.BotGroupId,
|
||||
g.BotGroupName,
|
||||
g.BotGroupLeaderBotId,
|
||||
b.Name as BotGroupLeaderName,
|
||||
b.BotOwnerCharacterId,
|
||||
c.name as BotOwnerCharacterName
|
||||
from botgroup as g
|
||||
join bots as b on g.BotGroupLeaderBotId = b.BotID
|
||||
join character_ as c on b.BotOwnerCharacterID = c.id
|
||||
order by b.BotOwnerCharacterId, g.BotGroupName;
|
||||
SELECT g.`BotGroupId`,
|
||||
g.`BotGroupName`,
|
||||
g.`BotGroupLeaderBotId`,
|
||||
b.`Name` AS BotGroupLeaderName,
|
||||
b.`BotOwnerCharacterId`,
|
||||
c.`name` AS BotOwnerCharacterName
|
||||
FROM `botgroup` AS g
|
||||
JOIN `bots` AS b ON g.`BotGroupLeaderBotId` = b.`BotID`
|
||||
JOIN `character_data` AS c ON b.`BotOwnerCharacterID` = c.`id`
|
||||
ORDER BY b.`BotOwnerCharacterId`, g.`BotGroupName`;
|
||||
|
||||
-- FILE:
|
||||
-- source player_tables/botstances.sql;
|
||||
CREATE TABLE botstances (
|
||||
BotID int(10) unsigned NOT NULL default '0',
|
||||
StanceID tinyint unsigned NOT NULL default '0',
|
||||
PRIMARY KEY (BotID),
|
||||
CONSTRAINT FK_botstances_1 FOREIGN KEY (BotID) REFERENCES bots (BotID)
|
||||
);
|
||||
|
||||
-- FILE:
|
||||
-- source player_tables/bottimers.sql;
|
||||
CREATE TABLE bottimers (
|
||||
BotID int(10) unsigned NOT NULL default '0',
|
||||
TimerID int(10) unsigned NOT NULL default '0',
|
||||
Value int(10) unsigned NOT NULL default '0',
|
||||
PRIMARY KEY (BotID),
|
||||
CONSTRAINT FK_bottimers_1 FOREIGN KEY (BotID) REFERENCES bots (BotID)
|
||||
)
|
||||
CREATE VIEW `vwGuildMembers` AS
|
||||
SELECT 'C' AS mobtype,
|
||||
cm.`char_id`,
|
||||
cm.`guild_id`,
|
||||
cm.`rank`,
|
||||
cm.`tribute_enable`,
|
||||
cm.`total_tribute`,
|
||||
cm.`last_tribute`,
|
||||
cm.`banker`,
|
||||
cm.`public_note`,
|
||||
cm.`alt`
|
||||
FROM `guild_members` AS cm
|
||||
UNION ALL
|
||||
SELECT 'B' AS mobtype,
|
||||
bm.`char_id`,
|
||||
bm.`guild_id`,
|
||||
bm.`rank`,
|
||||
bm.`tribute_enable`,
|
||||
bm.`total_tribute`,
|
||||
bm.`last_tribute`,
|
||||
bm.`banker`,
|
||||
bm.`public_note`,
|
||||
bm.`alt`
|
||||
FROM `botguildmembers` AS bm;
|
||||
|
||||
1
utils/sql/git/optional/2014_09_18_TellQueueRule.sql
Normal file
1
utils/sql/git/optional/2014_09_18_TellQueueRule.sql
Normal file
@ -0,0 +1 @@
|
||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'World:TellQueueSize', '20', 'Maximum tell queue size.');
|
||||
1
utils/sql/git/optional/2014_09_20_SHDProCIDOffByOne.sql
Normal file
1
utils/sql/git/optional/2014_09_20_SHDProCIDOffByOne.sql
Normal file
@ -0,0 +1 @@
|
||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:SHDProcIDOffByOne', 'true', 'SHD procs are off by 1. Set true for pre-UF spell files, false for UF+.');
|
||||
@ -0,0 +1 @@
|
||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:Jun182014HundredHandsRevamp', 'false', 'Set this to true if your spell file is from after June 18, 2014.');
|
||||
13
utils/sql/git/optional/2014_10_02_AAFixes.sql
Normal file
13
utils/sql/git/optional/2014_10_02_AAFixes.sql
Normal file
@ -0,0 +1,13 @@
|
||||
-- Fix Salvage
|
||||
UPDATE `aa_effects` SET `effectid` = '331' WHERE `aaid` IN (997, 998, 999);
|
||||
-- Rapid Strikes missing entries
|
||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('818', '1', '279', '17', '0');
|
||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('819', '1', '279', '19', '0');
|
||||
-- Secondary Forte fixes client side display issues
|
||||
INSERT INTO `aa_effects` (`aaid`, `slot`, `effectid`, `base1`, `base2`) VALUES ('691', '1', '248', '100', '0');
|
||||
-- Packrat this is what live uses
|
||||
UPDATE `aa_effects` SET `base1` = '3' WHERE `aaid` = 678;
|
||||
UPDATE `aa_effects` SET `base1` = '6' WHERE `aaid` = 679;
|
||||
UPDATE `aa_effects` SET `base1` = '9' WHERE `aaid` = 680;
|
||||
UPDATE `aa_effects` SET `base1` = '12' WHERE `aaid` = 681;
|
||||
UPDATE `aa_effects` SET `base1` = '15' WHERE `aaid` = 682;
|
||||
@ -0,0 +1,2 @@
|
||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Zone:EnableLoggedOffReplenishments', 'true', 'Replenish mana/hp/end if logged off for MinOfflineTimeToReplenishments');
|
||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Zone:MinOfflineTimeToReplenishments', '21600', 'Minimum logged off time to trigger replenish mana/hp/end');
|
||||
1
utils/sql/git/required/2014_09_18_tellqueuesclean.sql
Normal file
1
utils/sql/git/required/2014_09_18_tellqueuesclean.sql
Normal file
@ -0,0 +1 @@
|
||||
DROP TABLE `tellque`;
|
||||
1
utils/sql/git/required/2014_09_20_ban_messages.sql
Normal file
1
utils/sql/git/required/2014_09_20_ban_messages.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE `account` ADD COLUMN `ban_reason` TEXT NULL DEFAULT NULL AFTER `expansion`, ADD COLUMN `suspend_reason` TEXT NULL DEFAULT NULL AFTER `ban_reason`;
|
||||
1
utils/sql/git/required/2014_10_11_RaidMOTD.sql
Normal file
1
utils/sql/git/required/2014_10_11_RaidMOTD.sql
Normal file
@ -0,0 +1 @@
|
||||
ALTER TABLE `raid_details` ADD `motd` varchar(1024);
|
||||
9
utils/sql/git/required/2014_10_13_RaidLeadership.sql
Normal file
9
utils/sql/git/required/2014_10_13_RaidLeadership.sql
Normal file
@ -0,0 +1,9 @@
|
||||
CREATE TABLE `raid_leaders` (
|
||||
`gid` int(4) unsigned NOT NULL,
|
||||
`rid` int(4) unsigned NOT NULL,
|
||||
`marknpc` varchar(64) NOT NULL,
|
||||
`maintank` varchar(64) NOT NULL,
|
||||
`assist` varchar(64) NOT NULL,
|
||||
`puller` varchar(64) NOT NULL,
|
||||
`leadershipaa` tinyblob NOT NULL
|
||||
);
|
||||
2
utils/sql/git/required/2014_10_18_group_mentor.sql
Normal file
2
utils/sql/git/required/2014_10_18_group_mentor.sql
Normal file
@ -0,0 +1,2 @@
|
||||
ALTER TABLE `group_leaders` ADD `mentoree` VARCHAR(64) NOT NULL;
|
||||
ALTER TABLE `group_leaders` ADD `mentor_percent` INT(4) DEFAULT 0 NOT NULL;
|
||||
2
utils/sql/git/required/2014_10_19_raid_group_mentor.sql
Normal file
2
utils/sql/git/required/2014_10_19_raid_group_mentor.sql
Normal file
@ -0,0 +1,2 @@
|
||||
ALTER TABLE `raid_leaders` ADD `mentoree` VARCHAR(64) NOT NULL;
|
||||
ALTER TABLE `raid_leaders` ADD `mentor_percent` INT(4) DEFAULT 0 NOT NULL;
|
||||
@ -358,6 +358,7 @@ void Adventure::Finished(AdventureWinStatus ws)
|
||||
afe.points = 0;
|
||||
}
|
||||
adventure_manager.AddFinishedEvent(afe);
|
||||
|
||||
database.UpdateAdventureStatsEntry(database.GetCharacterID((*iter).c_str()), GetTemplate()->theme, (ws != AWS_Lose) ? true : false);
|
||||
}
|
||||
++iter;
|
||||
|
||||
@ -1069,7 +1069,7 @@ void AdventureManager::LoadLeaderboardInfo()
|
||||
leaderboard_info_percentage_tak.clear();
|
||||
|
||||
std::string query = "SELECT ch.name, ch.id, adv_stats.* FROM adventure_stats "
|
||||
"AS adv_stats LEFT JOIN character_ AS ch ON adv_stats.player_id = ch.id;";
|
||||
"AS adv_stats LEFT JOIN `character_data` AS ch ON adv_stats.player_id = ch.id;";
|
||||
auto results = database.QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::GetLeaderboardInfo: %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
||||
|
||||
357
world/client.cpp
357
world/client.cpp
@ -64,8 +64,6 @@ extern ClientList client_list;
|
||||
extern uint32 numclients;
|
||||
extern volatile bool RunLoops;
|
||||
|
||||
|
||||
|
||||
Client::Client(EQStreamInterface* ieqs)
|
||||
: autobootup_timeout(RuleI(World, ZoneAutobootTimeoutMS)),
|
||||
CLE_keepalive_timer(RuleI(World, ClientKeepaliveTimeoutMS)),
|
||||
@ -130,7 +128,7 @@ void Client::SendLogServer()
|
||||
|
||||
void Client::SendEnterWorld(std::string name)
|
||||
{
|
||||
char char_name[32]= { 0 };
|
||||
char char_name[64] = { 0 };
|
||||
if (pZoning && database.GetLiveChar(GetAccountID(), char_name)) {
|
||||
if(database.GetAccountIDByChar(char_name) != GetAccountID()) {
|
||||
eqs->Close();
|
||||
@ -174,7 +172,7 @@ void Client::SendCharInfo() {
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_SendCharInfo, sizeof(CharacterSelect_Struct));
|
||||
CharacterSelect_Struct* cs = (CharacterSelect_Struct*)outapp->pBuffer;
|
||||
|
||||
database.GetCharSelectInfo(GetAccountID(), cs);
|
||||
database.GetCharSelectInfo(GetAccountID(), cs, ClientVersionBit);
|
||||
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
@ -471,8 +469,8 @@ bool Client::HandleSendLoginInfoPacket(const EQApplicationPacket *app) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) {
|
||||
|
||||
bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app)
|
||||
{
|
||||
if (GetAccountID() == 0) {
|
||||
clog(WORLD__CLIENT_ERR,"Name approval request with no logged in account");
|
||||
return false;
|
||||
@ -482,7 +480,7 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) {
|
||||
uchar race = app->pBuffer[64];
|
||||
uchar clas = app->pBuffer[68];
|
||||
|
||||
clog(WORLD__CLIENT,"Name approval request. Name=%s, race=%s, class=%s",char_name,GetRaceName(race),GetEQClassName(clas));
|
||||
clog(WORLD__CLIENT, "Name approval request. Name=%s, race=%s, class=%s", char_name, GetRaceName(race), GetEQClassName(clas));
|
||||
|
||||
EQApplicationPacket *outapp;
|
||||
outapp = new EQApplicationPacket;
|
||||
@ -490,27 +488,27 @@ bool Client::HandleNameApprovalPacket(const EQApplicationPacket *app) {
|
||||
outapp->pBuffer = new uchar[1];
|
||||
outapp->size = 1;
|
||||
|
||||
bool valid;
|
||||
if(!database.CheckNameFilter(char_name)) {
|
||||
valid = false;
|
||||
bool valid = false;
|
||||
if(!database.CheckNameFilter(char_name)) {
|
||||
valid = false;
|
||||
}
|
||||
else if(char_name[0] < 'A' && char_name[0] > 'Z') {
|
||||
//name must begin with an upper-case letter.
|
||||
valid = false;
|
||||
/* Name must begin with an upper-case letter. */
|
||||
else if (islower(char_name[0])) {
|
||||
valid = false;
|
||||
}
|
||||
else if (database.ReserveName(GetAccountID(), char_name)) {
|
||||
valid = true;
|
||||
}
|
||||
else if (database.ReserveName(GetAccountID(), char_name)) {
|
||||
valid = true;
|
||||
}
|
||||
else {
|
||||
valid = false;
|
||||
else {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
outapp->pBuffer[0] = valid? 1 : 0;
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
if(!valid) {
|
||||
if (!valid)
|
||||
memset(char_name, 0, sizeof(char_name));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -642,13 +640,11 @@ bool Client::HandleCharacterCreateRequestPacket(const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
bool Client::HandleCharacterCreatePacket(const EQApplicationPacket *app) {
|
||||
if (GetAccountID() == 0)
|
||||
{
|
||||
if (GetAccountID() == 0) {
|
||||
clog(WORLD__CLIENT_ERR,"Account ID not set; unable to create character.");
|
||||
return false;
|
||||
}
|
||||
else if (app->size != sizeof(CharCreate_Struct))
|
||||
{
|
||||
else if (app->size != sizeof(CharCreate_Struct)) {
|
||||
clog(WORLD__CLIENT_ERR,"Wrong size on OP_CharacterCreate. Got: %d, Expected: %d",app->size,sizeof(CharCreate_Struct));
|
||||
DumpPacket(app);
|
||||
// the previous behavior was essentially returning true here
|
||||
@ -657,8 +653,7 @@ bool Client::HandleCharacterCreatePacket(const EQApplicationPacket *app) {
|
||||
}
|
||||
|
||||
CharCreate_Struct *cc = (CharCreate_Struct*)app->pBuffer;
|
||||
if(OPCharCreate(char_name, cc) == false)
|
||||
{
|
||||
if(OPCharCreate(char_name, cc) == false) {
|
||||
database.DeleteCharacter(char_name);
|
||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_ApproveName, 1);
|
||||
outapp->pBuffer[0] = 0;
|
||||
@ -675,8 +670,7 @@ bool Client::HandleCharacterCreatePacket(const EQApplicationPacket *app) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
|
||||
bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
if (GetAccountID() == 0) {
|
||||
clog(WORLD__CLIENT_ERR,"Enter world with no logged in account");
|
||||
eqs->Close();
|
||||
@ -713,11 +707,10 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!pZoning && ew->return_home && !ew->tutorial)
|
||||
{
|
||||
if(!pZoning && ew->return_home && !ew->tutorial) {
|
||||
CharacterSelect_Struct* cs = new CharacterSelect_Struct;
|
||||
memset(cs, 0, sizeof(CharacterSelect_Struct));
|
||||
database.GetCharSelectInfo(GetAccountID(), cs);
|
||||
database.GetCharSelectInfo(GetAccountID(), cs, ClientVersionBit);
|
||||
bool home_enabled = false;
|
||||
|
||||
for(int x = 0; x < 10; ++x)
|
||||
@ -733,12 +726,10 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
}
|
||||
safe_delete(cs);
|
||||
|
||||
if(home_enabled)
|
||||
{
|
||||
if(home_enabled) {
|
||||
zoneID = database.MoveCharacterToBind(charid,4);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
clog(WORLD__CLIENT_ERR,"'%s' is trying to go home before they're able...",char_name);
|
||||
database.SetHackerFlag(GetAccountName(), char_name, "MQGoHome: player tried to go home before they were able.");
|
||||
eqs->Close();
|
||||
@ -749,7 +740,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
if(!pZoning && (RuleB(World, EnableTutorialButton) && (ew->tutorial || StartInTutorial))) {
|
||||
CharacterSelect_Struct* cs = new CharacterSelect_Struct;
|
||||
memset(cs, 0, sizeof(CharacterSelect_Struct));
|
||||
database.GetCharSelectInfo(GetAccountID(), cs);
|
||||
database.GetCharSelectInfo(GetAccountID(), cs, ClientVersionBit);
|
||||
bool tutorial_enabled = false;
|
||||
|
||||
for(int x = 0; x < 10; ++x)
|
||||
@ -807,16 +798,16 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
database.SetLoginFlags(charid, false, false, 1);
|
||||
}
|
||||
else{
|
||||
uint32 groupid=database.GetGroupID(char_name);
|
||||
if(groupid>0){
|
||||
char* leader=0;
|
||||
char leaderbuf[64]={0};
|
||||
if((leader=database.GetGroupLeaderForLogin(char_name,leaderbuf)) && strlen(leader)>1){
|
||||
uint32 groupid = database.GetGroupID(char_name);
|
||||
if(groupid > 0){
|
||||
char* leader = 0;
|
||||
char leaderbuf[64] = {0};
|
||||
if((leader = database.GetGroupLeaderForLogin(char_name, leaderbuf)) && strlen(leader)>1){
|
||||
EQApplicationPacket* outapp3 = new EQApplicationPacket(OP_GroupUpdate,sizeof(GroupJoin_Struct));
|
||||
GroupJoin_Struct* gj=(GroupJoin_Struct*)outapp3->pBuffer;
|
||||
gj->action=8;
|
||||
strcpy(gj->yourname,char_name);
|
||||
strcpy(gj->membername,leader);
|
||||
strcpy(gj->yourname, char_name);
|
||||
strcpy(gj->membername, leader);
|
||||
QueuePacket(outapp3);
|
||||
safe_delete(outapp3);
|
||||
}
|
||||
@ -895,8 +886,7 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
||||
bool Client::HandleDeleteCharacterPacket(const EQApplicationPacket *app) {
|
||||
|
||||
uint32 char_acct_id = database.GetAccountIDByChar((char*)app->pBuffer);
|
||||
if(char_acct_id == GetAccountID())
|
||||
{
|
||||
if(char_acct_id == GetAccountID()) {
|
||||
clog(WORLD__CLIENT,"Delete character: %s",app->pBuffer);
|
||||
database.DeleteCharacter((char *)app->pBuffer);
|
||||
SendCharInfo();
|
||||
@ -1355,57 +1345,41 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
||||
time_t bday = time(nullptr);
|
||||
char startzone[50]={0};
|
||||
uint32 i;
|
||||
struct in_addr in;
|
||||
struct in_addr in;
|
||||
|
||||
|
||||
int stats_sum = cc->STR + cc->STA + cc->AGI + cc->DEX +
|
||||
cc->WIS + cc->INT + cc->CHA;
|
||||
int stats_sum = cc->STR + cc->STA + cc->AGI + cc->DEX + cc->WIS + cc->INT + cc->CHA;
|
||||
|
||||
in.s_addr = GetIP();
|
||||
clog(WORLD__CLIENT,"Character creation request from %s LS#%d (%s:%d) : ", GetCLE()->LSName(), GetCLE()->LSID(), inet_ntoa(in), GetPort());
|
||||
clog(WORLD__CLIENT,"Name: %s", name);
|
||||
clog(WORLD__CLIENT,"Race: %d Class: %d Gender: %d Deity: %d Start zone: %d",
|
||||
cc->race, cc->class_, cc->gender, cc->deity, cc->start_zone);
|
||||
clog(WORLD__CLIENT,"STR STA AGI DEX WIS INT CHA Total");
|
||||
clog(WORLD__CLIENT,"%3d %3d %3d %3d %3d %3d %3d %3d",
|
||||
|
||||
clog(WORLD__CLIENT, "Character creation request from %s LS#%d (%s:%d) : ", GetCLE()->LSName(), GetCLE()->LSID(), inet_ntoa(in), GetPort());
|
||||
clog(WORLD__CLIENT, "Name: %s", name);
|
||||
clog(WORLD__CLIENT, "Race: %d Class: %d Gender: %d Deity: %d Start zone: %d Tutorial: %s",
|
||||
cc->race, cc->class_, cc->gender, cc->deity, cc->start_zone, cc->tutorial ? "true" : "false");
|
||||
clog(WORLD__CLIENT, "STR STA AGI DEX WIS INT CHA Total");
|
||||
clog(WORLD__CLIENT, "%3d %3d %3d %3d %3d %3d %3d %3d",
|
||||
cc->STR, cc->STA, cc->AGI, cc->DEX, cc->WIS, cc->INT, cc->CHA,
|
||||
stats_sum);
|
||||
clog(WORLD__CLIENT,"Face: %d Eye colors: %d %d", cc->face, cc->eyecolor1, cc->eyecolor2);
|
||||
clog(WORLD__CLIENT,"Hairstyle: %d Haircolor: %d", cc->hairstyle, cc->haircolor);
|
||||
clog(WORLD__CLIENT,"Beard: %d Beardcolor: %d", cc->beard, cc->beardcolor);
|
||||
clog(WORLD__CLIENT, "Face: %d Eye colors: %d %d", cc->face, cc->eyecolor1, cc->eyecolor2);
|
||||
clog(WORLD__CLIENT, "Hairstyle: %d Haircolor: %d", cc->hairstyle, cc->haircolor);
|
||||
clog(WORLD__CLIENT, "Beard: %d Beardcolor: %d", cc->beard, cc->beardcolor);
|
||||
|
||||
// validate the char creation struct
|
||||
if(ClientVersionBit & BIT_SoFAndLater) {
|
||||
if(!CheckCharCreateInfoSoF(cc))
|
||||
{
|
||||
/* Validate the char creation struct */
|
||||
if (ClientVersionBit & BIT_SoFAndLater) {
|
||||
if (!CheckCharCreateInfoSoF(cc)) {
|
||||
clog(WORLD__CLIENT_ERR,"CheckCharCreateInfo did not validate the request (bad race/class/stats)");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if(!CheckCharCreateInfoTitanium(cc))
|
||||
{
|
||||
if (!CheckCharCreateInfoTitanium(cc)) {
|
||||
clog(WORLD__CLIENT_ERR,"CheckCharCreateInfo did not validate the request (bad race/class/stats)");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert incoming cc_s to the new PlayerProfile_Struct
|
||||
/* Convert incoming cc_s to the new PlayerProfile_Struct */
|
||||
memset(&pp, 0, sizeof(PlayerProfile_Struct)); // start building the profile
|
||||
|
||||
InitExtendedProfile(&ext);
|
||||
|
||||
strn0cpy(pp.name, name, 63);
|
||||
// clean the capitalization of the name
|
||||
#if 0 // on second thought, don't - this will just make the creation fail
|
||||
// because the name won't match what was already reserved earlier
|
||||
for (i = 0; pp.name[i] && i < 63; i++)
|
||||
{
|
||||
if(!isalpha(pp.name[i]))
|
||||
return false;
|
||||
pp.name[i] = tolower(pp.name[i]);
|
||||
}
|
||||
pp.name[0] = toupper(pp.name[0]);
|
||||
#endif
|
||||
|
||||
pp.race = cc->race;
|
||||
pp.class_ = cc->class_;
|
||||
@ -1433,150 +1407,128 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
||||
pp.level = 1;
|
||||
pp.points = 5;
|
||||
pp.cur_hp = 1000; // 1k hp during dev only
|
||||
//what was the point of this? zone dosent handle this:
|
||||
//pp.expAA = 0xFFFFFFFF;
|
||||
|
||||
pp.hunger_level = 6000;
|
||||
pp.thirst_level = 6000;
|
||||
|
||||
|
||||
// FIXME: FV roleplay, database goodness...
|
||||
|
||||
// Racial Languages
|
||||
SetRacialLanguages( &pp ); // bUsh
|
||||
SetRaceStartingSkills( &pp ); // bUsh
|
||||
SetClassStartingSkills( &pp ); // bUsh
|
||||
/* Set Racial and Class specific language and skills */
|
||||
SetRacialLanguages(&pp);
|
||||
SetRaceStartingSkills(&pp);
|
||||
SetClassStartingSkills(&pp);
|
||||
SetClassLanguages(&pp);
|
||||
pp.skills[SkillSenseHeading] = 200;
|
||||
// Some one fucking fix this to use a field name. -Doodman
|
||||
//pp.unknown3596[28] = 15; // @bp: This is to enable disc usage
|
||||
// strcpy(pp.servername, WorldConfig::get()->ShortName.c_str());
|
||||
|
||||
|
||||
for(i = 0; i < MAX_PP_SPELLBOOK; i++)
|
||||
for (i = 0; i < MAX_PP_REF_SPELLBOOK; i++)
|
||||
pp.spell_book[i] = 0xFFFFFFFF;
|
||||
|
||||
for(i = 0; i < MAX_PP_MEMSPELL; i++)
|
||||
for(i = 0; i < MAX_PP_REF_MEMSPELL; i++)
|
||||
pp.mem_spells[i] = 0xFFFFFFFF;
|
||||
|
||||
for(i = 0; i < BUFF_COUNT; i++)
|
||||
pp.buffs[i].spellid = 0xFFFF;
|
||||
|
||||
|
||||
//was memset(pp.unknown3704, 0xffffffff, 8);
|
||||
//but I dont think thats what you really wanted to do...
|
||||
//memset is byte based
|
||||
|
||||
//If server is PVP by default, make all character set to it.
|
||||
/* If server is PVP by default, make all character set to it. */
|
||||
pp.pvp = database.GetServerType() == 1 ? 1 : 0;
|
||||
|
||||
//If it is an SoF Client and the SoF Start Zone rule is set, send new chars there
|
||||
if((ClientVersionBit & BIT_SoFAndLater) && (RuleI(World, SoFStartZoneID) > 0)) {
|
||||
clog(WORLD__CLIENT,"Found 'SoFStartZoneID' rule setting: %i", (RuleI(World, SoFStartZoneID)));
|
||||
pp.zone_id = (RuleI(World, SoFStartZoneID));
|
||||
if(pp.zone_id)
|
||||
/* If it is an SoF Client and the SoF Start Zone rule is set, send new chars there */
|
||||
if (ClientVersionBit & BIT_SoFAndLater && RuleI(World, SoFStartZoneID) > 0) {
|
||||
clog(WORLD__CLIENT,"Found 'SoFStartZoneID' rule setting: %i", RuleI(World, SoFStartZoneID));
|
||||
pp.zone_id = RuleI(World, SoFStartZoneID);
|
||||
if (pp.zone_id)
|
||||
database.GetSafePoints(pp.zone_id, 0, &pp.x, &pp.y, &pp.z);
|
||||
else
|
||||
clog(WORLD__CLIENT_ERR,"Error getting zone id for Zone ID %i", (RuleI(World, SoFStartZoneID)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// if there's a startzone variable put them in there
|
||||
if(database.GetVariable("startzone", startzone, 50))
|
||||
{
|
||||
clog(WORLD__CLIENT_ERR,"Error getting zone id for Zone ID %i", RuleI(World, SoFStartZoneID));
|
||||
} else {
|
||||
/* if there's a startzone variable put them in there */
|
||||
if (database.GetVariable("startzone", startzone, 50)) {
|
||||
clog(WORLD__CLIENT,"Found 'startzone' variable setting: %s", startzone);
|
||||
pp.zone_id = database.GetZoneID(startzone);
|
||||
if(pp.zone_id)
|
||||
if (pp.zone_id)
|
||||
database.GetSafePoints(pp.zone_id, 0, &pp.x, &pp.y, &pp.z);
|
||||
else
|
||||
clog(WORLD__CLIENT_ERR,"Error getting zone id for '%s'", startzone);
|
||||
}
|
||||
else // otherwise use normal starting zone logic
|
||||
{
|
||||
} else { /* otherwise use normal starting zone logic */
|
||||
bool ValidStartZone = false;
|
||||
|
||||
if(ClientVersionBit & BIT_TitaniumAndEarlier)
|
||||
if (ClientVersionBit & BIT_TitaniumAndEarlier)
|
||||
ValidStartZone = database.GetStartZone(&pp, cc);
|
||||
else
|
||||
ValidStartZone = database.GetStartZoneSoF(&pp, cc);
|
||||
|
||||
if(!ValidStartZone)
|
||||
if (!ValidStartZone)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!pp.zone_id)
|
||||
{
|
||||
/* just in case */
|
||||
if (!pp.zone_id) {
|
||||
pp.zone_id = 1; // qeynos
|
||||
pp.x = pp.y = pp.z = -1;
|
||||
}
|
||||
|
||||
if(!pp.binds[0].zoneId)
|
||||
{
|
||||
pp.binds[0].zoneId = pp.zone_id;
|
||||
pp.binds[0].x = pp.x;
|
||||
pp.binds[0].y = pp.y;
|
||||
pp.binds[0].z = pp.z;
|
||||
pp.binds[0].heading = pp.heading;
|
||||
/* Set Home Binds */
|
||||
pp.binds[4].zoneId = pp.zone_id;
|
||||
pp.binds[4].x = pp.x;
|
||||
pp.binds[4].y = pp.y;
|
||||
pp.binds[4].z = pp.z;
|
||||
pp.binds[4].heading = pp.heading;
|
||||
|
||||
/* Overrides if we have the tutorial flag set! */
|
||||
if (cc->tutorial && RuleB(World, EnableTutorialButton)) {
|
||||
pp.zone_id = RuleI(World, TutorialZoneID);
|
||||
database.GetSafePoints(pp.zone_id, 0, &pp.x, &pp.y, &pp.z);
|
||||
}
|
||||
|
||||
// set starting city location to the initial bind point
|
||||
pp.binds[4] = pp.binds[0];
|
||||
/* Will either be the same as home or tutorial */
|
||||
pp.binds[0].zoneId = pp.zone_id;
|
||||
pp.binds[0].x = pp.x;
|
||||
pp.binds[0].y = pp.y;
|
||||
pp.binds[0].z = pp.z;
|
||||
pp.binds[0].heading = pp.heading;
|
||||
|
||||
clog(WORLD__CLIENT,"Current location: %s (%d) %0.2f, %0.2f, %0.2f, %0.2f",
|
||||
database.GetZoneName(pp.zone_id), pp.zone_id, pp.x, pp.y, pp.z, pp.heading);
|
||||
clog(WORLD__CLIENT,"Bind location: %s (%d) %0.2f, %0.2f, %0.2f",
|
||||
database.GetZoneName(pp.binds[0].zoneId), pp.binds[0].zoneId, pp.binds[0].x, pp.binds[0].y, pp.binds[0].z);
|
||||
clog(WORLD__CLIENT,"Home location: %s (%d) %0.2f, %0.2f, %0.2f",
|
||||
database.GetZoneName(pp.binds[4].zoneId), pp.binds[4].zoneId, pp.binds[4].x, pp.binds[4].y, pp.binds[4].z);
|
||||
|
||||
clog(WORLD__CLIENT,"Current location: %s %0.2f, %0.2f, %0.2f, %0.2f",
|
||||
database.GetZoneName(pp.zone_id), pp.x, pp.y, pp.z, pp.heading);
|
||||
clog(WORLD__CLIENT,"Bind location: %s %0.2f, %0.2f, %0.2f",
|
||||
database.GetZoneName(pp.binds[0].zoneId), pp.binds[0].x, pp.binds[0].y, pp.binds[0].z);
|
||||
|
||||
|
||||
// Starting Items inventory
|
||||
/* Starting Items inventory */
|
||||
database.SetStartingItems(&pp, &inv, pp.race, pp.class_, pp.deity, pp.zone_id, pp.name, GetAdmin());
|
||||
|
||||
|
||||
// now we give the pp and the inv we made to StoreCharacter
|
||||
// to see if we can store it
|
||||
if (!database.StoreCharacter(GetAccountID(), &pp, &inv, &ext))
|
||||
{
|
||||
if (!database.StoreCharacter(GetAccountID(), &pp, &inv)) {
|
||||
clog(WORLD__CLIENT_ERR,"Character creation failed: %s", pp.name);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
clog(WORLD__CLIENT,"Character creation successful: %s", pp.name);
|
||||
return true;
|
||||
}
|
||||
clog(WORLD__CLIENT,"Character creation successful: %s", pp.name);
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns true if the request is ok, false if there's an error
|
||||
bool CheckCharCreateInfoSoF(CharCreate_Struct *cc)
|
||||
{
|
||||
if(!cc) return false;
|
||||
if (!cc)
|
||||
return false;
|
||||
|
||||
_log(WORLD__CLIENT, "Validating char creation info...");
|
||||
|
||||
RaceClassCombos class_combo;
|
||||
bool found = false;
|
||||
int combos = character_create_race_class_combos.size();
|
||||
for(int i = 0; i < combos; ++i) {
|
||||
if(character_create_race_class_combos[i].Class == cc->class_ &&
|
||||
character_create_race_class_combos[i].Race == cc->race &&
|
||||
character_create_race_class_combos[i].Deity == cc->deity) {
|
||||
if(RuleB(World, EnableTutorialButton) &&
|
||||
(RuleI(World, TutorialZoneID) == cc->start_zone ||
|
||||
(character_create_race_class_combos[i].Zone == cc->start_zone))) {
|
||||
class_combo = character_create_race_class_combos[i];
|
||||
found = true;
|
||||
break;
|
||||
} else if(character_create_race_class_combos[i].Zone == cc->start_zone) {
|
||||
class_combo = character_create_race_class_combos[i];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < combos; ++i) {
|
||||
if (character_create_race_class_combos[i].Class == cc->class_ &&
|
||||
character_create_race_class_combos[i].Race == cc->race &&
|
||||
character_create_race_class_combos[i].Deity == cc->deity &&
|
||||
character_create_race_class_combos[i].Zone == cc->start_zone) {
|
||||
class_combo = character_create_race_class_combos[i];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
if (!found) {
|
||||
_log(WORLD__CLIENT_ERR, "Could not find class/race/deity/start_zone combination");
|
||||
return false;
|
||||
}
|
||||
@ -1585,15 +1537,15 @@ bool CheckCharCreateInfoSoF(CharCreate_Struct *cc)
|
||||
uint32 allocs = character_create_allocations.size();
|
||||
RaceClassAllocation allocation = {0};
|
||||
found = false;
|
||||
for(int i = 0; i < combos; ++i) {
|
||||
if(character_create_allocations[i].Index == class_combo.AllocationIndex) {
|
||||
for (int i = 0; i < allocs; ++i) {
|
||||
if (character_create_allocations[i].Index == class_combo.AllocationIndex) {
|
||||
allocation = character_create_allocations[i];
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found) {
|
||||
if (!found) {
|
||||
_log(WORLD__CLIENT_ERR, "Could not find starting stats for selected character combo, cannot verify stats");
|
||||
return false;
|
||||
}
|
||||
@ -1606,37 +1558,37 @@ bool CheckCharCreateInfoSoF(CharCreate_Struct *cc)
|
||||
allocation.DefaultPointAllocation[5] +
|
||||
allocation.DefaultPointAllocation[6];
|
||||
|
||||
if(cc->STR > allocation.BaseStats[0] + max_stats || cc->STR < allocation.BaseStats[0]) {
|
||||
if (cc->STR > allocation.BaseStats[0] + max_stats || cc->STR < allocation.BaseStats[0]) {
|
||||
_log(WORLD__CLIENT_ERR, "Strength out of range");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(cc->DEX > allocation.BaseStats[1] + max_stats || cc->DEX < allocation.BaseStats[1]) {
|
||||
if (cc->DEX > allocation.BaseStats[1] + max_stats || cc->DEX < allocation.BaseStats[1]) {
|
||||
_log(WORLD__CLIENT_ERR, "Dexterity out of range");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(cc->AGI > allocation.BaseStats[2] + max_stats || cc->AGI < allocation.BaseStats[2]) {
|
||||
if (cc->AGI > allocation.BaseStats[2] + max_stats || cc->AGI < allocation.BaseStats[2]) {
|
||||
_log(WORLD__CLIENT_ERR, "Agility out of range");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(cc->STA > allocation.BaseStats[3] + max_stats || cc->STA < allocation.BaseStats[3]) {
|
||||
if (cc->STA > allocation.BaseStats[3] + max_stats || cc->STA < allocation.BaseStats[3]) {
|
||||
_log(WORLD__CLIENT_ERR, "Stamina out of range");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(cc->INT > allocation.BaseStats[4] + max_stats || cc->INT < allocation.BaseStats[4]) {
|
||||
if (cc->INT > allocation.BaseStats[4] + max_stats || cc->INT < allocation.BaseStats[4]) {
|
||||
_log(WORLD__CLIENT_ERR, "Intelligence out of range");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(cc->WIS > allocation.BaseStats[5] + max_stats || cc->WIS < allocation.BaseStats[5]) {
|
||||
if (cc->WIS > allocation.BaseStats[5] + max_stats || cc->WIS < allocation.BaseStats[5]) {
|
||||
_log(WORLD__CLIENT_ERR, "Wisdom out of range");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(cc->CHA > allocation.BaseStats[6] + max_stats || cc->CHA < allocation.BaseStats[6]) {
|
||||
if (cc->CHA > allocation.BaseStats[6] + max_stats || cc->CHA < allocation.BaseStats[6]) {
|
||||
_log(WORLD__CLIENT_ERR, "Charisma out of range");
|
||||
return false;
|
||||
}
|
||||
@ -1649,7 +1601,7 @@ bool CheckCharCreateInfoSoF(CharCreate_Struct *cc)
|
||||
current_stats += cc->INT - allocation.BaseStats[4];
|
||||
current_stats += cc->WIS - allocation.BaseStats[5];
|
||||
current_stats += cc->CHA - allocation.BaseStats[6];
|
||||
if(current_stats > max_stats) {
|
||||
if (current_stats > max_stats) {
|
||||
_log(WORLD__CLIENT_ERR, "Current Stats > Maximum Stats");
|
||||
return false;
|
||||
}
|
||||
@ -1728,7 +1680,8 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
||||
{ /*Berserker*/ false, true, false, false, false, false, false, true, true, true, false, false, false, true, false, false}
|
||||
};//Initial table by kathgar, editted by Wiz for accuracy, solar too
|
||||
|
||||
if(!cc) return false;
|
||||
if (!cc)
|
||||
return false;
|
||||
|
||||
_log(WORLD__CLIENT,"Validating char creation info...");
|
||||
|
||||
@ -1742,19 +1695,16 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
||||
|
||||
// if out of range looking it up in the table would crash stuff
|
||||
// so we return from these
|
||||
if(classtemp >= PLAYER_CLASS_COUNT)
|
||||
{
|
||||
if (classtemp >= PLAYER_CLASS_COUNT) {
|
||||
_log(WORLD__CLIENT_ERR," class is out of range");
|
||||
return false;
|
||||
}
|
||||
if(racetemp >= _TABLE_RACES)
|
||||
{
|
||||
if (racetemp >= _TABLE_RACES) {
|
||||
_log(WORLD__CLIENT_ERR," race is out of range");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!ClassRaceLookupTable[classtemp][racetemp]) //Lookup table better than a bunch of ifs?
|
||||
{
|
||||
if (!ClassRaceLookupTable[classtemp][racetemp]) { //Lookup table better than a bunch of ifs?
|
||||
_log(WORLD__CLIENT_ERR," invalid race/class combination");
|
||||
// we return from this one, since if it's an invalid combination our table
|
||||
// doesn't have meaningful values for the stats
|
||||
@ -1782,44 +1732,36 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
||||
// NOTE: these could just be else if, but i want to see all the stats
|
||||
// that are messed up not just the first hit
|
||||
|
||||
if(bTOTAL + stat_points != cTOTAL)
|
||||
{
|
||||
if (bTOTAL + stat_points != cTOTAL) {
|
||||
_log(WORLD__CLIENT_ERR," stat points total doesn't match expected value: expecting %d got %d", bTOTAL + stat_points, cTOTAL);
|
||||
Charerrors++;
|
||||
}
|
||||
|
||||
if(cc->STR > bSTR + stat_points || cc->STR < bSTR)
|
||||
{
|
||||
if (cc->STR > bSTR + stat_points || cc->STR < bSTR) {
|
||||
_log(WORLD__CLIENT_ERR," stat STR is out of range");
|
||||
Charerrors++;
|
||||
}
|
||||
if(cc->STA > bSTA + stat_points || cc->STA < bSTA)
|
||||
{
|
||||
if (cc->STA > bSTA + stat_points || cc->STA < bSTA) {
|
||||
_log(WORLD__CLIENT_ERR," stat STA is out of range");
|
||||
Charerrors++;
|
||||
}
|
||||
if(cc->AGI > bAGI + stat_points || cc->AGI < bAGI)
|
||||
{
|
||||
if (cc->AGI > bAGI + stat_points || cc->AGI < bAGI) {
|
||||
_log(WORLD__CLIENT_ERR," stat AGI is out of range");
|
||||
Charerrors++;
|
||||
}
|
||||
if(cc->DEX > bDEX + stat_points || cc->DEX < bDEX)
|
||||
{
|
||||
if (cc->DEX > bDEX + stat_points || cc->DEX < bDEX) {
|
||||
_log(WORLD__CLIENT_ERR," stat DEX is out of range");
|
||||
Charerrors++;
|
||||
}
|
||||
if(cc->WIS > bWIS + stat_points || cc->WIS < bWIS)
|
||||
{
|
||||
if (cc->WIS > bWIS + stat_points || cc->WIS < bWIS) {
|
||||
_log(WORLD__CLIENT_ERR," stat WIS is out of range");
|
||||
Charerrors++;
|
||||
}
|
||||
if(cc->INT > bINT + stat_points || cc->INT < bINT)
|
||||
{
|
||||
if (cc->INT > bINT + stat_points || cc->INT < bINT) {
|
||||
_log(WORLD__CLIENT_ERR," stat INT is out of range");
|
||||
Charerrors++;
|
||||
}
|
||||
if(cc->CHA > bCHA + stat_points || cc->CHA < bCHA)
|
||||
{
|
||||
if (cc->CHA > bCHA + stat_points || cc->CHA < bCHA) {
|
||||
_log(WORLD__CLIENT_ERR," stat CHA is out of range");
|
||||
Charerrors++;
|
||||
}
|
||||
@ -1832,28 +1774,15 @@ bool CheckCharCreateInfoTitanium(CharCreate_Struct *cc)
|
||||
return Charerrors == 0;
|
||||
}
|
||||
|
||||
void Client::SetClassStartingSkills( PlayerProfile_Struct *pp )
|
||||
void Client::SetClassStartingSkills(PlayerProfile_Struct *pp)
|
||||
{
|
||||
for(uint32 i = 0; i <= HIGHEST_SKILL; ++i) {
|
||||
if(pp->skills[i] == 0) {
|
||||
if(i >= SkillSpecializeAbjure && i <= SkillSpecializeEvocation) {
|
||||
for (uint32 i = 0; i <= HIGHEST_SKILL; ++i) {
|
||||
if (pp->skills[i] == 0) {
|
||||
// Skip specialized, tradeskills (fishing excluded), Alcohol Tolerance, and Bind Wound
|
||||
if (EQEmu::IsSpecializedSkill((SkillUseTypes)i) ||
|
||||
(EQEmu::IsTradeskill((SkillUseTypes)i) && i != SkillFishing) ||
|
||||
i == SkillAlcoholTolerance || i == SkillBindWound)
|
||||
continue;
|
||||
}
|
||||
|
||||
if(i == SkillMakePoison ||
|
||||
i == SkillTinkering ||
|
||||
i == SkillResearch ||
|
||||
i == SkillAlchemy ||
|
||||
i == SkillBaking ||
|
||||
i == SkillTailoring ||
|
||||
i == SkillBlacksmithing ||
|
||||
i == SkillFletching ||
|
||||
i == SkillBrewing ||
|
||||
i == SkillPottery ||
|
||||
i == SkillJewelryMaking ||
|
||||
i == SkillBegging) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pp->skills[i] = database.GetSkillCap(pp->class_, (SkillUseTypes)i, 1);
|
||||
}
|
||||
|
||||
@ -93,6 +93,7 @@ ClientListEntry::~ClientListEntry() {
|
||||
Camp(); // updates zoneserver's numplayers
|
||||
client_list.RemoveCLEReferances(this);
|
||||
}
|
||||
tell_queue.clear();
|
||||
}
|
||||
|
||||
void ClientListEntry::SetChar(uint32 iCharID, const char* iCharName) {
|
||||
@ -233,6 +234,7 @@ void ClientListEntry::ClearVars(bool iAll) {
|
||||
pLFG = 0;
|
||||
gm = 0;
|
||||
pClientVersion = 0;
|
||||
tell_queue.clear();
|
||||
}
|
||||
|
||||
void ClientListEntry::Camp(ZoneServer* iZS) {
|
||||
@ -295,3 +297,21 @@ bool ClientListEntry::CheckAuth(uint32 id, const char* iKey, uint32 ip) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClientListEntry::ProcessTellQueue()
|
||||
{
|
||||
if (!Server())
|
||||
return;
|
||||
|
||||
ServerPacket *pack;
|
||||
auto it = tell_queue.begin();
|
||||
while (it != tell_queue.end()) {
|
||||
pack = new ServerPacket(ServerOP_ChannelMessage, sizeof(ServerChannelMessage_Struct) + strlen((*it)->message) + 1);
|
||||
memcpy(pack->pBuffer, *it, pack->size);
|
||||
pack->Deflate();
|
||||
Server()->SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
it = tell_queue.erase(it);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
#include "../common/md5.h"
|
||||
//#include "../common/eq_packet_structs.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
#define CLE_Status_Never -1
|
||||
@ -80,6 +82,11 @@ public:
|
||||
inline const char* GetLFGComments() const { return pLFGComments; }
|
||||
inline uint8 GetClientVersion() { return pClientVersion; }
|
||||
|
||||
inline bool TellQueueFull() const { return tell_queue.size() >= RuleI(World, TellQueueSize); }
|
||||
inline bool TellQueueEmpty() const { return tell_queue.empty(); }
|
||||
inline void PushToTellQueue(ServerChannelMessage_Struct *scm) { tell_queue.push_back(scm); }
|
||||
void ProcessTellQueue();
|
||||
|
||||
private:
|
||||
void ClearVars(bool iAll = false);
|
||||
|
||||
@ -120,6 +127,9 @@ private:
|
||||
uint8 pLFGToLevel;
|
||||
bool pLFGMatchFilter;
|
||||
char pLFGComments[64];
|
||||
|
||||
// Tell Queue -- really a vector :D
|
||||
std::vector<ServerChannelMessage_Struct *> tell_queue;
|
||||
};
|
||||
|
||||
#endif /*CLIENTENTRY_H_*/
|
||||
|
||||
@ -113,7 +113,7 @@ bool Console::SendChannelMessage(const ServerChannelMessage_Struct* scm) {
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
SendMessage(1, "%s tells you, '%s'", scm->from, scm->message);
|
||||
SendMessage(1, "[%s] tells you, '%s'", scm->from, scm->message);
|
||||
ServerPacket* pack = new ServerPacket(ServerOP_ChannelMessage, sizeof(ServerChannelMessage_Struct) + strlen(scm->message) + 1);
|
||||
memcpy(pack->pBuffer, scm, pack->size);
|
||||
ServerChannelMessage_Struct* scm2 = (ServerChannelMessage_Struct*) pack->pBuffer;
|
||||
@ -847,6 +847,9 @@ void Console::ProcessCommand(const char* command) {
|
||||
zoneserver_list.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
else if (strcasecmp(sep.arg[0], "") == 0){
|
||||
/* Hit Enter with no command */
|
||||
}
|
||||
else {
|
||||
SendMessage(1, "Command unknown.");
|
||||
}
|
||||
|
||||
@ -67,7 +67,6 @@
|
||||
|
||||
#endif
|
||||
|
||||
#include "../common/dbasync.h"
|
||||
#include "../common/emu_tcp_server.h"
|
||||
#include "../common/patches/patches.h"
|
||||
#include "zoneserver.h"
|
||||
@ -98,7 +97,6 @@ UCSConnection UCSLink;
|
||||
QueryServConnection QSLink;
|
||||
LauncherList launcher_list;
|
||||
AdventureManager adventure_manager;
|
||||
DBAsync *dbasync = nullptr;
|
||||
volatile bool RunLoops = true;
|
||||
uint32 numclients = 0;
|
||||
uint32 numzones = 0;
|
||||
@ -175,7 +173,6 @@ int main(int argc, char** argv) {
|
||||
_log(WORLD__INIT_ERR, "Cannot continue without a database connection.");
|
||||
return 1;
|
||||
}
|
||||
dbasync = new DBAsync(&database);
|
||||
guild_mgr.SetDatabase(&database);
|
||||
|
||||
if (argc >= 2) {
|
||||
@ -222,9 +219,8 @@ int main(int argc, char** argv) {
|
||||
else if (strcasecmp(argv[1], "flag") == 0) {
|
||||
if (argc == 4) {
|
||||
if (Seperator::IsNumber(argv[3])) {
|
||||
|
||||
if (atoi(argv[3]) >= 0 && atoi(argv[3]) <= 255) {
|
||||
if (database.SetAccountStatus(argv[2], atoi(argv[3]))) {
|
||||
if (database.SetAccountStatus(argv[2], atoi(argv[3]))){
|
||||
std::cout << "Account flagged: Username='" << argv[2] << "', status=" << argv[3] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
@ -276,6 +272,8 @@ int main(int argc, char** argv) {
|
||||
_log(WORLD__INIT, "HTTP world service disabled.");
|
||||
}
|
||||
|
||||
_log(WORLD__INIT, "Checking Database Conversions..");
|
||||
database.CheckDatabaseConversions();
|
||||
_log(WORLD__INIT, "Loading variables..");
|
||||
database.LoadVariables();
|
||||
_log(WORLD__INIT, "Loading zones..");
|
||||
@ -285,10 +283,13 @@ int main(int argc, char** argv) {
|
||||
_log(WORLD__INIT, "Clearing raids..");
|
||||
database.ClearRaid();
|
||||
database.ClearRaidDetails();
|
||||
database.ClearRaidLeader();
|
||||
_log(WORLD__INIT, "Loading items..");
|
||||
if (!database.LoadItems()) {
|
||||
if (!database.LoadItems())
|
||||
_log(WORLD__INIT_ERR, "Error: Could not load item data. But ignoring");
|
||||
}
|
||||
_log(WORLD__INIT, "Loading skill caps..");
|
||||
if (!database.LoadSkillCaps())
|
||||
_log(WORLD__INIT_ERR, "Error: Could not load skill cap data. But ignoring");
|
||||
_log(WORLD__INIT, "Loading guilds..");
|
||||
guild_mgr.LoadGuilds();
|
||||
//rules:
|
||||
|
||||
@ -21,7 +21,6 @@
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
#include "../common/item.h"
|
||||
#include "../common/dbasync.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
@ -34,295 +33,222 @@ extern std::vector<RaceClassCombos> character_create_race_class_combos;
|
||||
|
||||
|
||||
// solar: the current stuff is at the bottom of this function
|
||||
void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* cs) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
void WorldDatabase::GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct* cs, uint32 ClientVersion) {
|
||||
Inventory *inv;
|
||||
uint8 has_home = 0;
|
||||
uint8 has_bind = 0;
|
||||
|
||||
/* Initialize Variables */
|
||||
for (int i=0; i<10; i++) {
|
||||
strcpy(cs->name[i], "<none>");
|
||||
cs->zone[i] = 0;
|
||||
cs->level[i] = 0;
|
||||
cs->tutorial[i] = 0;
|
||||
cs->tutorial[i] = 0;
|
||||
cs->gohome[i] = 0;
|
||||
}
|
||||
|
||||
int char_num = 0;
|
||||
unsigned long* lengths;
|
||||
/* Get Character Info */
|
||||
std::string cquery = StringFormat(
|
||||
"SELECT "
|
||||
"`id`, " // 0
|
||||
"name, " // 1
|
||||
"gender, " // 2
|
||||
"race, " // 3
|
||||
"class, " // 4
|
||||
"`level`, " // 5
|
||||
"deity, " // 6
|
||||
"last_login, " // 7
|
||||
"time_played, " // 8
|
||||
"hair_color, " // 9
|
||||
"beard_color, " // 10
|
||||
"eye_color_1, " // 11
|
||||
"eye_color_2, " // 12
|
||||
"hair_style, " // 13
|
||||
"beard, " // 14
|
||||
"face, " // 15
|
||||
"drakkin_heritage, " // 16
|
||||
"drakkin_tattoo, " // 17
|
||||
"drakkin_details, " // 18
|
||||
"zone_id " // 19
|
||||
"FROM "
|
||||
"character_data "
|
||||
"WHERE `account_id` = %i ORDER BY `name` LIMIT 10 ", account_id);
|
||||
auto results = database.QueryDatabase(cquery); int char_num = 0;
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
PlayerProfile_Struct pp;
|
||||
memset(&pp, 0, sizeof(PlayerProfile_Struct));
|
||||
|
||||
// Populate character info
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT name,profile,zonename,class,level FROM character_ WHERE account_id=%i order by name limit 10", account_id), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
while ((row = mysql_fetch_row(result))) {
|
||||
lengths = mysql_fetch_lengths(result);
|
||||
////////////
|
||||
//////////// This is the current one, the other are for converting
|
||||
////////////
|
||||
if ((lengths[1] == sizeof(PlayerProfile_Struct))) {
|
||||
strcpy(cs->name[char_num], row[0]);
|
||||
PlayerProfile_Struct* pp = (PlayerProfile_Struct*)row[1];
|
||||
uint8 clas = atoi(row[3]);
|
||||
uint8 lvl = atoi(row[4]);
|
||||
uint32 character_id = atoi(row[0]);
|
||||
strcpy(cs->name[char_num], row[1]);
|
||||
uint8 lvl = atoi(row[5]);
|
||||
cs->level[char_num] = lvl;
|
||||
cs->class_[char_num] = atoi(row[4]);
|
||||
cs->race[char_num] = atoi(row[3]);
|
||||
cs->gender[char_num] = atoi(row[2]);
|
||||
cs->deity[char_num] = atoi(row[6]);
|
||||
cs->zone[char_num] = atoi(row[19]);
|
||||
cs->face[char_num] = atoi(row[15]);
|
||||
cs->haircolor[char_num] = atoi(row[9]);
|
||||
cs->beardcolor[char_num] = atoi(row[10]);
|
||||
cs->eyecolor2[char_num] = atoi(row[12]);
|
||||
cs->eyecolor1[char_num] = atoi(row[11]);
|
||||
cs->hairstyle[char_num] = atoi(row[13]);
|
||||
cs->beard[char_num] = atoi(row[14]);
|
||||
cs->drakkin_heritage[char_num] = atoi(row[16]);
|
||||
cs->drakkin_tattoo[char_num] = atoi(row[17]);
|
||||
cs->drakkin_details[char_num] = atoi(row[18]);
|
||||
|
||||
// Character information
|
||||
if(lvl == 0)
|
||||
cs->level[char_num] = pp->level; //no level in DB, trust PP
|
||||
else
|
||||
cs->level[char_num] = lvl;
|
||||
if(clas == 0)
|
||||
cs->class_[char_num] = pp->class_; //no class in DB, trust PP
|
||||
else
|
||||
cs->class_[char_num] = clas;
|
||||
cs->race[char_num] = pp->race;
|
||||
cs->gender[char_num] = pp->gender;
|
||||
cs->deity[char_num] = pp->deity;
|
||||
cs->zone[char_num] = GetZoneID(row[2]);
|
||||
cs->face[char_num] = pp->face;
|
||||
cs->haircolor[char_num] = pp->haircolor;
|
||||
cs->beardcolor[char_num] = pp->beardcolor;
|
||||
cs->eyecolor2[char_num] = pp->eyecolor2;
|
||||
cs->eyecolor1[char_num] = pp->eyecolor1;
|
||||
cs->hairstyle[char_num] = pp->hairstyle;
|
||||
cs->beard[char_num] = pp->beard;
|
||||
cs->drakkin_heritage[char_num] = pp->drakkin_heritage;
|
||||
cs->drakkin_tattoo[char_num] = pp->drakkin_tattoo;
|
||||
cs->drakkin_details[char_num] = pp->drakkin_details;
|
||||
if (RuleB(World, EnableTutorialButton) && (lvl <= RuleI(World, MaxLevelForTutorial)))
|
||||
cs->tutorial[char_num] = 1;
|
||||
|
||||
if(RuleB(World, EnableTutorialButton) && (lvl <= RuleI(World, MaxLevelForTutorial)))
|
||||
cs->tutorial[char_num] = 1;
|
||||
if (RuleB(World, EnableReturnHomeButton)) {
|
||||
int now = time(nullptr);
|
||||
if ((now - atoi(row[7])) >= RuleI(World, MinOfflineTimeToReturnHome))
|
||||
cs->gohome[char_num] = 1;
|
||||
}
|
||||
|
||||
if(RuleB(World, EnableReturnHomeButton)) {
|
||||
int now = time(nullptr);
|
||||
if((now - pp->lastlogin) >= RuleI(World, MinOfflineTimeToReturnHome))
|
||||
cs->gohome[char_num] = 1;
|
||||
/* Set Bind Point Data for any character that may possibly be missing it for any reason */
|
||||
cquery = StringFormat("SELECT `zone_id`, `instance_id`, `x`, `y`, `z`, `heading`, `is_home` FROM `character_bind` WHERE `id` = %i LIMIT 2", character_id);
|
||||
auto results_bind = database.QueryDatabase(cquery); has_home = 0; has_bind = 0;
|
||||
for (auto row_b = results_bind.begin(); row_b != results_bind.end(); ++row_b) {
|
||||
if (row_b[6] && atoi(row_b[6]) == 1){ has_home = 1; }
|
||||
if (row_b[6] && atoi(row_b[6]) == 0){ has_bind = 1; }
|
||||
}
|
||||
|
||||
if (has_home == 0 || has_bind == 0){
|
||||
cquery = StringFormat("SELECT `zone_id`, `bind_id`, `x`, `y`, `z` FROM `start_zones` WHERE `player_class` = %i AND `player_deity` = %i AND `player_race` = %i",
|
||||
cs->class_[char_num], cs->deity[char_num], cs->race[char_num]);
|
||||
auto results_bind = database.QueryDatabase(cquery);
|
||||
for (auto row_d = results_bind.begin(); row_d != results_bind.end(); ++row_d) {
|
||||
/* If a bind_id is specified, make them start there */
|
||||
if (atoi(row_d[1]) != 0) {
|
||||
pp.binds[4].zoneId = (uint32)atoi(row_d[1]);
|
||||
GetSafePoints(pp.binds[4].zoneId, 0, &pp.binds[4].x, &pp.binds[4].y, &pp.binds[4].z);
|
||||
}
|
||||
/* Otherwise, use the zone and coordinates given */
|
||||
else {
|
||||
pp.binds[4].zoneId = (uint32)atoi(row_d[0]);
|
||||
float x = atof(row_d[2]);
|
||||
float y = atof(row_d[3]);
|
||||
float z = atof(row_d[4]);
|
||||
if (x == 0 && y == 0 && z == 0){ GetSafePoints(pp.binds[4].zoneId, 0, &x, &y, &z); }
|
||||
pp.binds[4].x = x; pp.binds[4].y = y; pp.binds[4].z = z;
|
||||
|
||||
|
||||
// This part creates home city entries for characters created before the home bind point was tracked.
|
||||
// Do it here because the player profile is already loaded and it's as good a spot as any. This whole block should
|
||||
// probably be removed at some point, when most accounts are safely converted.
|
||||
if(pp->binds[4].zoneId == 0) {
|
||||
bool altered = false;
|
||||
MYSQL_RES *result2;
|
||||
MYSQL_ROW row2;
|
||||
char startzone[50] = {0};
|
||||
|
||||
// check for start zone variable (I didn't even know any variables were still being used...)
|
||||
if(database.GetVariable("startzone", startzone, 50)) {
|
||||
uint32 zoneid = database.GetZoneID(startzone);
|
||||
if(zoneid) {
|
||||
pp->binds[4].zoneId = zoneid;
|
||||
GetSafePoints(zoneid, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z);
|
||||
altered = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
RunQuery(query,
|
||||
MakeAnyLenString(&query,
|
||||
"SELECT zone_id,bind_id,x,y,z FROM start_zones "
|
||||
"WHERE player_class=%i AND player_deity=%i AND player_race=%i",
|
||||
pp->class_,
|
||||
pp->deity,
|
||||
pp->race
|
||||
),
|
||||
errbuf,
|
||||
&result2
|
||||
);
|
||||
safe_delete_array(query);
|
||||
|
||||
// if there is only one possible start city, set it
|
||||
if(mysql_num_rows(result2) == 1) {
|
||||
row2 = mysql_fetch_row(result2);
|
||||
if(atoi(row2[1]) != 0) { // if a bind_id is specified, make them start there
|
||||
pp->binds[4].zoneId = (uint32)atoi(row2[1]);
|
||||
GetSafePoints(pp->binds[4].zoneId, 0, &pp->binds[4].x, &pp->binds[4].y, &pp->binds[4].z);
|
||||
}
|
||||
else { // otherwise, use the zone and coordinates given
|
||||
pp->binds[4].zoneId = (uint32)atoi(row2[0]);
|
||||
float x = atof(row2[2]);
|
||||
float y = atof(row2[3]);
|
||||
float z = atof(row2[4]);
|
||||
if(x == 0 && y == 0 && z == 0)
|
||||
GetSafePoints(pp->binds[4].zoneId, 0, &x, &y, &z);
|
||||
|
||||
pp->binds[4].x = x;
|
||||
pp->binds[4].y = y;
|
||||
pp->binds[4].z = z;
|
||||
}
|
||||
altered = true;
|
||||
}
|
||||
|
||||
mysql_free_result(result2);
|
||||
}
|
||||
|
||||
// update the player profile
|
||||
if(altered) {
|
||||
uint32 char_id = GetCharacterID(cs->name[char_num]);
|
||||
RunQuery(query,MakeAnyLenString(&query,"SELECT extprofile FROM character_ WHERE id=%i",char_id), errbuf, &result2);
|
||||
safe_delete_array(query);
|
||||
if(result2) {
|
||||
row2 = mysql_fetch_row(result2);
|
||||
ExtendedProfile_Struct* ext = (ExtendedProfile_Struct*)row2[0];
|
||||
SetPlayerProfile(account_id,char_id,pp,inv,ext, 0, 0, 5);
|
||||
}
|
||||
mysql_free_result(result2);
|
||||
}
|
||||
} // end of "set start zone" block
|
||||
|
||||
|
||||
// Character's equipped items
|
||||
// @merth: Haven't done bracer01/bracer02 yet.
|
||||
// Also: this needs a second look after items are a little more solid
|
||||
// NOTE: items don't have a color, players MAY have a tint, if the
|
||||
// use_tint part is set. otherwise use the regular color
|
||||
inv = new Inventory;
|
||||
if(GetInventory(account_id, cs->name[char_num], inv))
|
||||
{
|
||||
for (uint8 material = 0; material <= 8; material++)
|
||||
{
|
||||
uint32 color;
|
||||
ItemInst *item = inv->GetItem(Inventory::CalcSlotFromMaterial(material));
|
||||
if(item == 0)
|
||||
continue;
|
||||
|
||||
cs->equip[char_num][material] = item->GetItem()->Material;
|
||||
|
||||
if(pp->item_tint[material].rgb.use_tint) // they have a tint (LoY dye)
|
||||
color = pp->item_tint[material].color;
|
||||
else // no tint, use regular item color
|
||||
color = item->GetItem()->Color;
|
||||
|
||||
cs->cs_colors[char_num][material].color = color;
|
||||
|
||||
// the weapons are kept elsewhere
|
||||
if ((material==MaterialPrimary) || (material==MaterialSecondary))
|
||||
{
|
||||
if(strlen(item->GetItem()->IDFile) > 2) {
|
||||
uint32 idfile=atoi(&item->GetItem()->IDFile[2]);
|
||||
if (material==MaterialPrimary)
|
||||
cs->primary[char_num]=idfile;
|
||||
else
|
||||
cs->secondary[char_num]=idfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error loading inventory for %s\n", cs->name[char_num]);
|
||||
}
|
||||
safe_delete(inv);
|
||||
if (++char_num > 10)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Got a bogus character (" << row[0] << ") Ignoring!!!" << std::endl;
|
||||
std::cout << "PP length ="<<lengths[1]<<" but PP should be "<<sizeof(PlayerProfile_Struct) << std::endl;
|
||||
//DeleteCharacter(row[0]);
|
||||
pp.binds[0] = pp.binds[4];
|
||||
/* If no home bind set, set it */
|
||||
if (has_home == 0){
|
||||
std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
|
||||
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i)",
|
||||
character_id, pp.binds[4].zoneId, 0, pp.binds[4].x, pp.binds[4].y, pp.binds[4].z, pp.binds[4].heading, 1);
|
||||
auto results_bset = QueryDatabase(query); ThrowDBError(results_bset.ErrorMessage(), "WorldDatabase::GetCharSelectInfo Set Home Point", query);
|
||||
}
|
||||
/* If no regular bind set, set it */
|
||||
if (has_bind == 0){
|
||||
std::string query = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
|
||||
" VALUES (%u, %u, %u, %f, %f, %f, %f, %i)",
|
||||
character_id, pp.binds[0].zoneId, 0, pp.binds[0].x, pp.binds[0].y, pp.binds[0].z, pp.binds[0].heading, 0);
|
||||
auto results_bset = QueryDatabase(query); ThrowDBError(results_bset.ErrorMessage(), "WorldDatabase::GetCharSelectInfo Set Bind Point", query);
|
||||
}
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Error in GetCharSelectInfo query '" << query << "' " << errbuf << std::endl;
|
||||
safe_delete_array(query);
|
||||
return;
|
||||
/* Bind End */
|
||||
|
||||
/*
|
||||
Character's equipped items
|
||||
@merth: Haven't done bracer01/bracer02 yet.
|
||||
Also: this needs a second look after items are a little more solid
|
||||
NOTE: items don't have a color, players MAY have a tint, if the
|
||||
use_tint part is set. otherwise use the regular color
|
||||
*/
|
||||
|
||||
/* Load Character Material Data for Char Select */
|
||||
cquery = StringFormat("SELECT slot, red, green, blue, use_tint, color FROM `character_material` WHERE `id` = %u", character_id);
|
||||
auto results_b = database.QueryDatabase(cquery); uint8 slot = 0;
|
||||
for (auto row_b = results_b.begin(); row_b != results_b.end(); ++row_b) {
|
||||
slot = atoi(row_b[0]);
|
||||
pp.item_tint[slot].rgb.red = atoi(row_b[1]);
|
||||
pp.item_tint[slot].rgb.green = atoi(row_b[2]);
|
||||
pp.item_tint[slot].rgb.blue = atoi(row_b[3]);
|
||||
pp.item_tint[slot].rgb.use_tint = atoi(row_b[4]);
|
||||
}
|
||||
|
||||
/* Load Inventory */
|
||||
inv = new Inventory;
|
||||
if (GetInventory(account_id, cs->name[char_num], inv)) {
|
||||
for (uint8 material = 0; material <= 8; material++) {
|
||||
uint32 color = 0;
|
||||
ItemInst *item = inv->GetItem(Inventory::CalcSlotFromMaterial(material));
|
||||
if (item == 0)
|
||||
continue;
|
||||
|
||||
cs->equip[char_num][material] = item->GetItem()->Material;
|
||||
|
||||
if (pp.item_tint[material].rgb.use_tint){ color = pp.item_tint[material].color; }
|
||||
else{ color = item->GetItem()->Color; }
|
||||
|
||||
cs->cs_colors[char_num][material].color = color;
|
||||
|
||||
/* Weapons are handled a bit differently */
|
||||
if ((material == MaterialPrimary) || (material == MaterialSecondary)) {
|
||||
if (strlen(item->GetItem()->IDFile) > 2) {
|
||||
uint32 idfile = atoi(&item->GetItem()->IDFile[2]);
|
||||
if (material == MaterialPrimary)
|
||||
cs->primary[char_num] = idfile;
|
||||
else
|
||||
cs->secondary[char_num] = idfile;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Error loading inventory for %s\n", cs->name[char_num]);
|
||||
}
|
||||
safe_delete(inv);
|
||||
if (++char_num > 10)
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int WorldDatabase::MoveCharacterToBind(int CharID, uint8 bindnum) {
|
||||
// if an invalid bind point is specified, use the primary bind
|
||||
if (bindnum > 4)
|
||||
bindnum = 0;
|
||||
/* if an invalid bind point is specified, use the primary bind */
|
||||
if (bindnum > 4){ bindnum = 0; }
|
||||
int is_home = 0;
|
||||
if (bindnum == 4){ is_home = 1; }
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
uint32 affected_rows = 0;
|
||||
PlayerProfile_Struct pp;
|
||||
|
||||
bool PPValid = false;
|
||||
|
||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT profile from character_ where id='%i'", CharID), errbuf, &result)) {
|
||||
row = mysql_fetch_row(result);
|
||||
unsigned long* lengths = mysql_fetch_lengths(result);
|
||||
if (lengths[0] == sizeof(PlayerProfile_Struct)) {
|
||||
memcpy(&pp, row[0], sizeof(PlayerProfile_Struct));
|
||||
PPValid = true;
|
||||
}
|
||||
mysql_free_result(result);
|
||||
std::string query = StringFormat("SELECT `zone_id` FROM `character_bind` WHERE `id` = %u AND `is_home` = %u LIMIT 1", CharID, is_home);
|
||||
auto results = database.QueryDatabase(query); int i = 0;
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
return atoi(row[0]);
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
if(!PPValid) return 0;
|
||||
|
||||
const char *BindZoneName = StaticGetZoneName(pp.binds[bindnum].zoneId);
|
||||
|
||||
if(!strcmp(BindZoneName, "UNKNWN")) return pp.zone_id;
|
||||
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET zonename = '%s',zoneid=%i,x=%f, y=%f, z=%f, instanceid=0 WHERE id='%i'",
|
||||
BindZoneName, pp.binds[bindnum].zoneId, pp.binds[bindnum].x, pp.binds[bindnum].y, pp.binds[bindnum].z,
|
||||
CharID), errbuf, 0,&affected_rows)) {
|
||||
|
||||
return pp.zone_id;
|
||||
}
|
||||
safe_delete_array(query);
|
||||
|
||||
return pp.binds[bindnum].zoneId;
|
||||
}
|
||||
|
||||
bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc)
|
||||
{
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row = 0;
|
||||
int rows;
|
||||
|
||||
if(!in_pp || !in_cc)
|
||||
return false;
|
||||
|
||||
in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0;
|
||||
in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = 0;
|
||||
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "SELECT x,y,z,heading,zone_id,bind_id FROM start_zones WHERE player_choice=%i AND player_class=%i "
|
||||
"AND player_deity=%i AND player_race=%i",
|
||||
in_cc->start_zone,
|
||||
in_cc->class_,
|
||||
in_cc->deity,
|
||||
in_cc->race), errbuf, &result))
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "Start zone query failed: %s : %s\n", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
std::string query = StringFormat("SELECT x, y, z, heading, zone_id, bind_id "
|
||||
"FROM start_zones WHERE player_choice = % i "
|
||||
"AND player_class = %i AND player_deity = %i "
|
||||
"AND player_race = %i",
|
||||
in_cc->start_zone, in_cc->class_, in_cc->deity,
|
||||
in_cc->race);
|
||||
auto results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "Start zone query failed: %s : %s\n", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
LogFile->write(EQEMuLog::Status, "Start zone query: %s\n", query);
|
||||
safe_delete_array(query);
|
||||
LogFile->write(EQEMuLog::Status, "Start zone query: %s\n", query.c_str());
|
||||
|
||||
if((rows = mysql_num_rows(result)) > 0)
|
||||
row = mysql_fetch_row(result);
|
||||
|
||||
if(row)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Status, "Found starting location in start_zones");
|
||||
in_pp->x = atof(row[0]);
|
||||
in_pp->y = atof(row[1]);
|
||||
in_pp->z = atof(row[2]);
|
||||
in_pp->heading = atof(row[3]);
|
||||
in_pp->zone_id = atoi(row[4]);
|
||||
in_pp->binds[0].zoneId = atoi(row[5]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("No start_zones entry in database, using defaults\n");
|
||||
if (results.RowCount() == 0) {
|
||||
printf("No start_zones entry in database, using defaults\n");
|
||||
switch(in_cc->start_zone)
|
||||
{
|
||||
case 0:
|
||||
@ -410,6 +336,16 @@ bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct*
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Status, "Found starting location in start_zones");
|
||||
auto row = results.begin();
|
||||
in_pp->x = atof(row[0]);
|
||||
in_pp->y = atof(row[1]);
|
||||
in_pp->z = atof(row[2]);
|
||||
in_pp->heading = atof(row[3]);
|
||||
in_pp->zone_id = atoi(row[4]);
|
||||
in_pp->binds[0].zoneId = atoi(row[5]);
|
||||
}
|
||||
|
||||
if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0)
|
||||
@ -417,14 +353,12 @@ bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct*
|
||||
|
||||
if(in_pp->binds[0].x == 0 && in_pp->binds[0].y == 0 && in_pp->binds[0].z == 0)
|
||||
database.GetSafePoints(in_pp->binds[0].zoneId, 0, &in_pp->binds[0].x, &in_pp->binds[0].y, &in_pp->binds[0].z);
|
||||
if(result)
|
||||
mysql_free_result(result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc)
|
||||
{
|
||||
|
||||
// SoF doesn't send the player_choice field in character creation, it now sends the real zoneID instead.
|
||||
//
|
||||
// For SoF, search for an entry in start_zones with a matching zone_id, class, race and deity.
|
||||
@ -432,49 +366,25 @@ bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Stru
|
||||
// For now, if no row matching row is found, send them to Crescent Reach, as that is probably the most likely
|
||||
// reason for no match being found.
|
||||
//
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row = 0;
|
||||
int rows;
|
||||
|
||||
if(!in_pp || !in_cc)
|
||||
return false;
|
||||
|
||||
in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0;
|
||||
in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = 0;
|
||||
|
||||
if(!RunQuery(query, MakeAnyLenString(&query, "SELECT x,y,z,heading,bind_id FROM start_zones WHERE zone_id=%i AND player_class=%i "
|
||||
"AND player_deity=%i AND player_race=%i",
|
||||
in_cc->start_zone,
|
||||
in_cc->class_,
|
||||
in_cc->deity,
|
||||
in_cc->race), errbuf, &result))
|
||||
{
|
||||
LogFile->write(EQEMuLog::Status, "SoF Start zone query failed: %s : %s\n", query, errbuf);
|
||||
safe_delete_array(query);
|
||||
std::string query = StringFormat("SELECT x, y, z, heading, bind_id FROM start_zones WHERE zone_id = %i "
|
||||
"AND player_class = %i AND player_deity = %i AND player_race = %i",
|
||||
in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race);
|
||||
auto results = QueryDatabase(query);
|
||||
if(!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Status, "SoF Start zone query failed: %s : %s\n", query.c_str(), results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
LogFile->write(EQEMuLog::Status, "SoF Start zone query: %s\n", query);
|
||||
safe_delete_array(query);
|
||||
LogFile->write(EQEMuLog::Status, "SoF Start zone query: %s\n", query.c_str());
|
||||
|
||||
if((rows = mysql_num_rows(result)) > 0)
|
||||
row = mysql_fetch_row(result);
|
||||
|
||||
if(row)
|
||||
{
|
||||
LogFile->write(EQEMuLog::Status, "Found starting location in start_zones");
|
||||
in_pp->x = atof(row[0]);
|
||||
in_pp->y = atof(row[1]);
|
||||
in_pp->z = atof(row[2]);
|
||||
in_pp->heading = atof(row[3]);
|
||||
in_pp->zone_id = in_cc->start_zone;
|
||||
in_pp->binds[0].zoneId = atoi(row[4]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("No start_zones entry in database, using defaults\n");
|
||||
if (results.RowCount() == 0) {
|
||||
printf("No start_zones entry in database, using defaults\n");
|
||||
|
||||
if(in_cc->start_zone == RuleI(World, TutorialZoneID))
|
||||
in_pp->zone_id = in_cc->start_zone;
|
||||
@ -484,7 +394,16 @@ bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Stru
|
||||
in_pp->z = in_pp->binds[0].z = 0.79;
|
||||
in_pp->zone_id = in_pp->binds[0].zoneId = 394; // Crescent Reach.
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Status, "Found starting location in start_zones");
|
||||
auto row = results.begin();
|
||||
in_pp->x = atof(row[0]);
|
||||
in_pp->y = atof(row[1]);
|
||||
in_pp->z = atof(row[2]);
|
||||
in_pp->heading = atof(row[3]);
|
||||
in_pp->zone_id = in_cc->start_zone;
|
||||
in_pp->binds[0].zoneId = atoi(row[4]);
|
||||
}
|
||||
|
||||
if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0)
|
||||
@ -492,39 +411,27 @@ bool WorldDatabase::GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Stru
|
||||
|
||||
if(in_pp->binds[0].x == 0 && in_pp->binds[0].y == 0 && in_pp->binds[0].z == 0)
|
||||
database.GetSafePoints(in_pp->binds[0].zoneId, 0, &in_pp->binds[0].x, &in_pp->binds[0].y, &in_pp->binds[0].z);
|
||||
if(result)
|
||||
mysql_free_result(result);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WorldDatabase::GetLauncherList(std::vector<std::string> &rl) {
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
|
||||
rl.clear();
|
||||
|
||||
if (RunQuery(query, MakeAnyLenString(&query,
|
||||
"SELECT name FROM launcher" )
|
||||
, errbuf, &result))
|
||||
{
|
||||
while ((row = mysql_fetch_row(result))) {
|
||||
rl.push_back(row[0]);
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
else {
|
||||
LogFile->write(EQEMuLog::Error, "WorldDatabase::GetLauncherList: %s", errbuf);
|
||||
}
|
||||
safe_delete_array(query);
|
||||
const std::string query = "SELECT name FROM launcher";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "WorldDatabase::GetLauncherList: %s", results.ErrorMessage().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
rl.push_back(row[0]);
|
||||
|
||||
}
|
||||
|
||||
void WorldDatabase::SetMailKey(int CharID, int IPAddress, int MailKey) {
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char *query = 0;
|
||||
|
||||
char MailKeyString[17];
|
||||
|
||||
if(RuleB(Chat, EnableMailKeyIPVerification) == true)
|
||||
@ -532,75 +439,60 @@ void WorldDatabase::SetMailKey(int CharID, int IPAddress, int MailKey) {
|
||||
else
|
||||
sprintf(MailKeyString, "%08X", MailKey);
|
||||
|
||||
if (!RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET mailkey = '%s' WHERE id='%i'",
|
||||
MailKeyString, CharID), errbuf))
|
||||
|
||||
LogFile->write(EQEMuLog::Error, "WorldDatabase::SetMailKey(%i, %s) : %s", CharID, MailKeyString, errbuf);
|
||||
|
||||
safe_delete_array(query);
|
||||
std::string query = StringFormat("UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
|
||||
MailKeyString, CharID);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
LogFile->write(EQEMuLog::Error, "WorldDatabase::SetMailKey(%i, %s) : %s", CharID, MailKeyString, results.ErrorMessage().c_str());
|
||||
|
||||
}
|
||||
|
||||
bool WorldDatabase::GetCharacterLevel(const char *name, int &level)
|
||||
{
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
std::string query = StringFormat("SELECT level FROM character_data WHERE name = '%s'", name);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
LogFile->write(EQEMuLog::Error, "WorldDatabase::GetCharacterLevel: %s", results.ErrorMessage().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(RunQuery(query, MakeAnyLenString(&query, "SELECT level FROM character_ WHERE name='%s'", name), errbuf, &result))
|
||||
{
|
||||
if(row = mysql_fetch_row(result))
|
||||
{
|
||||
level = atoi(row[0]);
|
||||
mysql_free_result(result);
|
||||
safe_delete_array(query);
|
||||
return true;
|
||||
}
|
||||
mysql_free_result(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile->write(EQEMuLog::Error, "WorldDatabase::GetCharacterLevel: %s", errbuf);
|
||||
}
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
if (results.RowCount() == 0)
|
||||
return false;
|
||||
|
||||
auto row = results.begin();
|
||||
level = atoi(row[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WorldDatabase::LoadCharacterCreateAllocations() {
|
||||
character_create_allocations.clear();
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
if(RunQuery(query, MakeAnyLenString(&query, "SELECT * FROM char_create_point_allocations order by id"), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
while(row = mysql_fetch_row(result)) {
|
||||
RaceClassAllocation allocate;
|
||||
int r = 0;
|
||||
allocate.Index = atoi(row[r++]);
|
||||
allocate.BaseStats[0] = atoi(row[r++]);
|
||||
allocate.BaseStats[3] = atoi(row[r++]);
|
||||
allocate.BaseStats[1] = atoi(row[r++]);
|
||||
allocate.BaseStats[2] = atoi(row[r++]);
|
||||
allocate.BaseStats[4] = atoi(row[r++]);
|
||||
allocate.BaseStats[5] = atoi(row[r++]);
|
||||
allocate.BaseStats[6] = atoi(row[r++]);
|
||||
allocate.DefaultPointAllocation[0] = atoi(row[r++]);
|
||||
allocate.DefaultPointAllocation[3] = atoi(row[r++]);
|
||||
allocate.DefaultPointAllocation[1] = atoi(row[r++]);
|
||||
allocate.DefaultPointAllocation[2] = atoi(row[r++]);
|
||||
allocate.DefaultPointAllocation[4] = atoi(row[r++]);
|
||||
allocate.DefaultPointAllocation[5] = atoi(row[r++]);
|
||||
allocate.DefaultPointAllocation[6] = atoi(row[r++]);
|
||||
character_create_allocations.push_back(allocate);
|
||||
}
|
||||
mysql_free_result(result);
|
||||
} else {
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
}
|
||||
std::string query = "SELECT * FROM char_create_point_allocations ORDER BY id";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
RaceClassAllocation allocate;
|
||||
allocate.Index = atoi(row[0]);
|
||||
allocate.BaseStats[0] = atoi(row[1]);
|
||||
allocate.BaseStats[3] = atoi(row[2]);
|
||||
allocate.BaseStats[1] = atoi(row[3]);
|
||||
allocate.BaseStats[2] = atoi(row[4]);
|
||||
allocate.BaseStats[4] = atoi(row[5]);
|
||||
allocate.BaseStats[5] = atoi(row[6]);
|
||||
allocate.BaseStats[6] = atoi(row[7]);
|
||||
allocate.DefaultPointAllocation[0] = atoi(row[8]);
|
||||
allocate.DefaultPointAllocation[3] = atoi(row[9]);
|
||||
allocate.DefaultPointAllocation[1] = atoi(row[10]);
|
||||
allocate.DefaultPointAllocation[2] = atoi(row[11]);
|
||||
allocate.DefaultPointAllocation[4] = atoi(row[12]);
|
||||
allocate.DefaultPointAllocation[5] = atoi(row[13]);
|
||||
allocate.DefaultPointAllocation[6] = atoi(row[14]);
|
||||
|
||||
character_create_allocations.push_back(allocate);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -608,27 +500,21 @@ bool WorldDatabase::LoadCharacterCreateAllocations() {
|
||||
bool WorldDatabase::LoadCharacterCreateCombos() {
|
||||
character_create_race_class_combos.clear();
|
||||
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
char* query = 0;
|
||||
MYSQL_RES *result;
|
||||
MYSQL_ROW row;
|
||||
if(RunQuery(query, MakeAnyLenString(&query, "select * from char_create_combinations order by race, class, deity, start_zone"), errbuf, &result)) {
|
||||
safe_delete_array(query);
|
||||
while(row = mysql_fetch_row(result)) {
|
||||
RaceClassCombos combo;
|
||||
int r = 0;
|
||||
combo.AllocationIndex = atoi(row[r++]);
|
||||
combo.Race = atoi(row[r++]);
|
||||
combo.Class = atoi(row[r++]);
|
||||
combo.Deity = atoi(row[r++]);
|
||||
combo.Zone = atoi(row[r++]);
|
||||
combo.ExpansionRequired = atoi(row[r++]);
|
||||
character_create_race_class_combos.push_back(combo);
|
||||
}
|
||||
mysql_free_result(result);
|
||||
} else {
|
||||
safe_delete_array(query);
|
||||
return false;
|
||||
std::string query = "SELECT * FROM char_create_combinations ORDER BY race, class, deity, start_zone";
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
RaceClassCombos combo;
|
||||
combo.AllocationIndex = atoi(row[0]);
|
||||
combo.Race = atoi(row[1]);
|
||||
combo.Class = atoi(row[2]);
|
||||
combo.Deity = atoi(row[3]);
|
||||
combo.Zone = atoi(row[4]);
|
||||
combo.ExpansionRequired = atoi(row[5]);
|
||||
|
||||
character_create_race_class_combos.push_back(combo);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@ -31,7 +31,7 @@ public:
|
||||
bool GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc);
|
||||
bool GetStartZoneSoF(PlayerProfile_Struct* in_pp, CharCreate_Struct* in_cc);
|
||||
|
||||
void GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct*);
|
||||
void GetCharSelectInfo(uint32 account_id, CharacterSelect_Struct*, uint32 ClientVersion);
|
||||
int MoveCharacterToBind(int CharID, uint8 bindnum = 0);
|
||||
|
||||
void GetLauncherList(std::vector<std::string> &result);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user