mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-12 05:21:29 +00:00
merge from upstream
This commit is contained in:
commit
0996570b78
@ -1,5 +1,70 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 08/26/2014 ==
|
||||||
|
Uleat: Implemented 'Smart' Player Trade transfers. Trades are processed by containers, stackables and then all remaining. QueryServ logs have been updated to match these transactions.
|
||||||
|
Note: QueryServ logs previously listed 'Items' on the main entry table. This indicated the number of slots affected and not the actual number of items.
|
||||||
|
This field now indicates the actual number of items transferred. For non-stackable, the value is '1' and stackable is the number of charges. A _detail_count
|
||||||
|
property has been added to both 'Trade' and 'Handin' structs to indicate the number of details recorded..though, not tracked..it could be added.
|
||||||
|
|
||||||
|
== 08/24/2014 ==
|
||||||
|
Uleat: Fix (attempted) for zone crashes related to zone shut-down. This change disables all Mob AI and disables/deletes all Mob timers once Zone::ShutDown() is called. More areas will be addressed as reports come in.
|
||||||
|
Note: Perl and Lua quests tested to work..please post any aberrant behavior. (I finally set my spell-check to US English...)
|
||||||
|
Akkadius: Character creation process crash fix and query cleanup
|
||||||
|
Akkadius: Created `character_lookup` table for applications that mirrors all `character_` table fields minus blob fields for application lookups
|
||||||
|
- A 2.4GB character_ table will take 7 seconds to query on a SSD versus .1s on the character_lookup table
|
||||||
|
- This also causes applications like Magelo to burst reads of the entire character table because of the blob fields that come with the reads, as much as 500-600MB/s even if a indexed id filter is provided
|
||||||
|
- This field is synchronized on player save and has 0.001s DB hit
|
||||||
|
- When we split out from the blob, ideally this table can be removed
|
||||||
|
- Required SQL: utils\sql\git\required\2014_08_24_character_lookup.sql
|
||||||
|
|
||||||
|
== 08/23/2014 ==
|
||||||
|
Akkadius: Changed zone process window title format, example: 'crushbone :: clients: 6 inst_id: 1 inst_ver: 0 :: port: 7015'
|
||||||
|
Akkadius: Most of the following changes are QueryServ related, fully implemented its original functionality to be able to offload
|
||||||
|
intensive or metric based logging to a remote server process that could exist on another server entirely
|
||||||
|
Akkadius: Implemented Player Event Logging Types (Go to table `qs_player_events`):
|
||||||
|
1 = Player_Log_Quest,
|
||||||
|
2 = Player_Log_Zoning,
|
||||||
|
3 = Player_Log_Deaths,
|
||||||
|
4 = Player_Log_Connect_State,
|
||||||
|
5 = Player_Log_Levels,
|
||||||
|
6 = Player_Log_Keyring_Addition,
|
||||||
|
7 = Player_Log_QGlobal_Update,
|
||||||
|
8 = Player_Log_Task_Updates,
|
||||||
|
9 = Player_Log_AA_Purchases,
|
||||||
|
10 = Player_Log_Trade_Skill_Events,
|
||||||
|
11 = Player_Log_Issued_Commands,
|
||||||
|
12 = Player_Log_Money_Transactions,
|
||||||
|
13 = Player_Log_Alternate_Currency_Transactions,
|
||||||
|
- All QueryServ logging will be implemented with a front end in EoC 2.0 very soon
|
||||||
|
- Architecture page: http://wiki.eqemulator.org/p?QueryServ_Architecture
|
||||||
|
Akkadius: Changed all QS Error related logging to 'QUERYSERV__ERROR'
|
||||||
|
Akkadius: (Natedog) (Crash Fix) Legacy MySQL bug revert for loading AA's COALESCE( from COALESCE (
|
||||||
|
Akkadius: Implemented Perl Quest objects (LUA still needed to be exported):
|
||||||
|
- quest::qs_send_query("MySQL query") - Will send a raw query to the QueryServ process, useful for custom logging
|
||||||
|
- quest::qs_player_event(char_id, event_desc); - Will process a quest type event to table `qs_player_events`
|
||||||
|
Akkadius: Added MySQL Tables
|
||||||
|
- `qs_player_aa_rate_hourly`
|
||||||
|
- `qs_player_events`
|
||||||
|
- Source table structures from:
|
||||||
|
- utils\sql\git\queryserv\required\08_23_2014_player_events_and_player_aa_rate_hourly
|
||||||
|
To get the complete QueryServ schema, source from here:
|
||||||
|
- utils\sql\git\queryserv\required\Complete_QueryServ_Table_Structures.sql
|
||||||
|
Akkadius: Added rules for each logging type, source rules here with them enabled by default:
|
||||||
|
- utils\sql\git\queryserv\required\Complete_QueryServ_Rules_Enabled.sql
|
||||||
|
Akkadius: Spawn related logging cleanup
|
||||||
|
Akkadius: General code cleanup
|
||||||
|
Akkadius: More to come for QueryServ
|
||||||
|
|
||||||
|
== 08/22/2014 ==
|
||||||
|
Uleat: Rework of Trade::FinishedTrade() and Trade::ResetTrade() to parse items a little more intelligently.
|
||||||
|
|
||||||
|
Trade window items are now sent to client inventory in this order:
|
||||||
|
- Bags
|
||||||
|
- Partial stack movements
|
||||||
|
- All remaining items
|
||||||
|
|
||||||
|
If any of these procedures cause any problems, please post them immediately.
|
||||||
|
|
||||||
== 08/20/2014 ==
|
== 08/20/2014 ==
|
||||||
Uleat: Rework of Trade::AddEntity() - function used to move items into the trade window. Now accepts argument for 'stack_size' and updates client properly.
|
Uleat: Rework of Trade::AddEntity() - function used to move items into the trade window. Now accepts argument for 'stack_size' and updates client properly.
|
||||||
Note: I tested trade with Titanium:{SoF,SoD,UF,RoF} in both directions and no client generated an OP_MoveItem event for attempting to place a stackable
|
Note: I tested trade with Titanium:{SoF,SoD,UF,RoF} in both directions and no client generated an OP_MoveItem event for attempting to place a stackable
|
||||||
|
|||||||
@ -81,7 +81,9 @@ void ExportSpells(SharedDatabase *db) {
|
|||||||
line.push_back('^');
|
line.push_back('^');
|
||||||
}
|
}
|
||||||
|
|
||||||
line += row[i];
|
if(row[i] != nullptr) {
|
||||||
|
line += row[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, "%s\n", line.c_str());
|
fprintf(f, "%s\n", line.c_str());
|
||||||
@ -180,7 +182,9 @@ void ExportBaseData(SharedDatabase *db) {
|
|||||||
if(rowIndex != 0)
|
if(rowIndex != 0)
|
||||||
line.push_back('^');
|
line.push_back('^');
|
||||||
|
|
||||||
line += row[rowIndex];
|
if(row[rowIndex] != nullptr) {
|
||||||
|
line += row[rowIndex];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f, "%s\n", line.c_str());
|
fprintf(f, "%s\n", line.c_str());
|
||||||
|
|||||||
@ -93,6 +93,7 @@ SET(common_sources
|
|||||||
)
|
)
|
||||||
|
|
||||||
SET(common_headers
|
SET(common_headers
|
||||||
|
any.h
|
||||||
base_packet.h
|
base_packet.h
|
||||||
base_data.h
|
base_data.h
|
||||||
bodytypes.h
|
bodytypes.h
|
||||||
|
|||||||
190
common/any.h
Normal file
190
common/any.h
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
/*
|
||||||
|
* Boost Software License - Version 1.0 - August 17th, 2003
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
* obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
* this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
* execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
* Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
* do so, all subject to the following:
|
||||||
|
*
|
||||||
|
* The copyright notices in the Software and this entire statement, including
|
||||||
|
* the above license grant, this restriction and the following disclaimer,
|
||||||
|
* must be included in all copies of the Software, in whole or in part, and
|
||||||
|
* all derivative works of the Software, unless such copies or derivative
|
||||||
|
* works are solely in the form of machine-executable object code generated by
|
||||||
|
* a source language processor.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// EQEmu::Any is a modified version of Boost::Any and as such retains the Boost licensing.
|
||||||
|
|
||||||
|
#ifndef EQEMU_COMMON_ANY_H
|
||||||
|
#define EQEMU_COMMON_ANY_H
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <typeinfo>
|
||||||
|
|
||||||
|
namespace EQEmu
|
||||||
|
{
|
||||||
|
class Any
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Any()
|
||||||
|
: content(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
Any(const ValueType &value)
|
||||||
|
: content(new Holder<ValueType>(value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Any(const Any &other)
|
||||||
|
: content(other.content ? other.content->clone() : 0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~Any()
|
||||||
|
{
|
||||||
|
if(content)
|
||||||
|
delete content;
|
||||||
|
}
|
||||||
|
|
||||||
|
Any& swap(Any &rhs)
|
||||||
|
{
|
||||||
|
std::swap(content, rhs.content);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
Any& operator=(const ValueType &rhs)
|
||||||
|
{
|
||||||
|
Any(rhs).swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Any& operator=(Any rhs)
|
||||||
|
{
|
||||||
|
rhs.swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return !content;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::type_info& type() const
|
||||||
|
{
|
||||||
|
return content ? content->type() : typeid(void);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Placeholder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~Placeholder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const std::type_info& type() const = 0;
|
||||||
|
virtual Placeholder* clone() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
class Holder : public Placeholder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Holder(const ValueType &value)
|
||||||
|
: held(value)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const std::type_info& type() const
|
||||||
|
{
|
||||||
|
return typeid(ValueType);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Placeholder* clone() const
|
||||||
|
{
|
||||||
|
return new Holder(held);
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueType held;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Holder& operator=(const Holder&);
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
template<typename ValueType>
|
||||||
|
friend ValueType* any_cast(Any*);
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
friend ValueType* unsafe_any_cast(Any*);
|
||||||
|
|
||||||
|
Placeholder* content;
|
||||||
|
};
|
||||||
|
|
||||||
|
class bad_any_cast : public std::bad_cast
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual const char * what() const throw()
|
||||||
|
{
|
||||||
|
return "DBI::bad_any_cast: failed conversion using DBI::any_cast";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
ValueType* any_cast(Any* operand)
|
||||||
|
{
|
||||||
|
return operand &&
|
||||||
|
operand->type() == typeid(ValueType) ? &static_cast<Any::Holder<ValueType>*>(operand->content)->held : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline const ValueType* any_cast(const Any* operand)
|
||||||
|
{
|
||||||
|
return any_cast<ValueType>(const_cast<Any*>(operand));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
ValueType any_cast(Any& operand)
|
||||||
|
{
|
||||||
|
typedef typename std::remove_reference<ValueType>::type nonref;
|
||||||
|
nonref* result = any_cast<nonref>(&operand);
|
||||||
|
if(!result)
|
||||||
|
throw bad_any_cast();
|
||||||
|
return *result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline ValueType any_cast(const Any& operand)
|
||||||
|
{
|
||||||
|
typedef typename std::remove_reference<ValueType>::type nonref;
|
||||||
|
return any_cast<const nonref&>(const_cast<Any&>(operand));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline ValueType* unsafe_any_cast(Any* operand)
|
||||||
|
{
|
||||||
|
return &static_cast<Any::Holder<ValueType>*>(operand->content)->held;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
inline const ValueType* unsafe_any_cast(const Any* operand)
|
||||||
|
{
|
||||||
|
return unsafe_any_cast<ValueType>(const_cast<Any*>(operand));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -161,6 +161,9 @@ uint32 Database::CheckLogin(const char* name, const char* password, int16* oStat
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(results.RowCount() == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
|
|
||||||
uint32 id = atoi(row[0]);
|
uint32 id = atoi(row[0]);
|
||||||
@ -608,10 +611,11 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven
|
|||||||
for (int16 i=EmuConstants::EQUIPMENT_BEGIN; i<=EmuConstants::BANK_BAGS_END;)
|
for (int16 i=EmuConstants::EQUIPMENT_BEGIN; i<=EmuConstants::BANK_BAGS_END;)
|
||||||
{
|
{
|
||||||
const ItemInst* newinv = inv->GetItem(i);
|
const ItemInst* newinv = inv->GetItem(i);
|
||||||
if (!newinv)
|
if (newinv)
|
||||||
{
|
{
|
||||||
invquery = StringFormat("INSERT INTO inventory SET charid=%0u, slotid=%0d, itemid=%0u, charges=%0d, color=%0u",
|
invquery = StringFormat("INSERT INTO `inventory` (charid, slotid, itemid, charges, color) VALUES (%u, %i, %u, %i, %u)",
|
||||||
charid, i, newinv->GetItem()->ID,newinv->GetCharges(), newinv->GetColor());
|
charid, i, newinv->GetItem()->ID, newinv->GetCharges(), newinv->GetColor());
|
||||||
|
|
||||||
auto results = QueryDatabase(invquery);
|
auto results = QueryDatabase(invquery);
|
||||||
|
|
||||||
if (!results.RowsAffected())
|
if (!results.RowsAffected())
|
||||||
|
|||||||
@ -654,6 +654,99 @@ int16 Inventory::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, boo
|
|||||||
return INVALID_INDEX;
|
return INVALID_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a mix of HasSpaceForItem and FindFreeSlot..due to existing coding behavior, it was better to add a new helper function...
|
||||||
|
int16 Inventory::FindFreeSlotForTradeItem(const ItemInst* inst) {
|
||||||
|
// Do not arbitrarily use this function..it is designed for use with Client::ResetTrade() and Client::FinishTrade().
|
||||||
|
// If you have a need, use it..but, understand it is not a compatible replacement for Inventory::FindFreeSlot().
|
||||||
|
//
|
||||||
|
// I'll probably implement a bitmask in the new inventory system to avoid having to adjust stack bias -U
|
||||||
|
|
||||||
|
if (!inst || !inst->GetID())
|
||||||
|
return INVALID_INDEX;
|
||||||
|
|
||||||
|
// step 1: find room for bags (caller should really ask for slots for bags first to avoid sending them to cursor..and bag item loss)
|
||||||
|
if (inst->IsType(ItemClassContainer)) {
|
||||||
|
for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot)
|
||||||
|
if (!m_inv[free_slot])
|
||||||
|
return free_slot;
|
||||||
|
|
||||||
|
return MainCursor; // return cursor since bags do not stack and will not fit inside other bags..yet...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 2: find partial room for stackables
|
||||||
|
if (inst->IsStackable()) {
|
||||||
|
for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) {
|
||||||
|
const ItemInst* main_inst = m_inv[free_slot];
|
||||||
|
|
||||||
|
if (!main_inst)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((main_inst->GetID() == inst->GetID()) && (main_inst->GetCharges() < main_inst->GetItem()->StackSize))
|
||||||
|
return free_slot;
|
||||||
|
|
||||||
|
if (main_inst->IsType(ItemClassContainer)) { // if item-specific containers already have bad items, we won't fix it here...
|
||||||
|
for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot) {
|
||||||
|
const ItemInst* sub_inst = main_inst->GetItem(free_bag_slot);
|
||||||
|
|
||||||
|
if (!sub_inst)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((sub_inst->GetID() == inst->GetID()) && (sub_inst->GetCharges() < sub_inst->GetItem()->StackSize))
|
||||||
|
return Inventory::CalcSlotId(free_slot, free_bag_slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 3a: find room for container-specific items (ItemClassArrow)
|
||||||
|
if (inst->GetItem()->ItemType == ItemTypeArrow) {
|
||||||
|
for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) {
|
||||||
|
const ItemInst* main_inst = m_inv[free_slot];
|
||||||
|
|
||||||
|
if (!main_inst || (main_inst->GetItem()->BagType != BagTypeQuiver) || !main_inst->IsType(ItemClassContainer))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot)
|
||||||
|
if (!main_inst->GetItem(free_bag_slot))
|
||||||
|
return Inventory::CalcSlotId(free_slot, free_bag_slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 3b: find room for container-specific items (ItemClassSmallThrowing)
|
||||||
|
if (inst->GetItem()->ItemType == ItemTypeSmallThrowing) {
|
||||||
|
for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) {
|
||||||
|
const ItemInst* main_inst = m_inv[free_slot];
|
||||||
|
|
||||||
|
if (!main_inst || (main_inst->GetItem()->BagType != BagTypeBandolier) || !main_inst->IsType(ItemClassContainer))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot)
|
||||||
|
if (!main_inst->GetItem(free_bag_slot))
|
||||||
|
return Inventory::CalcSlotId(free_slot, free_bag_slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 4: just find an empty slot
|
||||||
|
for (int16 free_slot = EmuConstants::GENERAL_BEGIN; free_slot <= EmuConstants::GENERAL_END; ++free_slot) {
|
||||||
|
const ItemInst* main_inst = m_inv[free_slot];
|
||||||
|
|
||||||
|
if (!main_inst)
|
||||||
|
return free_slot;
|
||||||
|
|
||||||
|
if (main_inst->IsType(ItemClassContainer)) {
|
||||||
|
if ((main_inst->GetItem()->BagSize < inst->GetItem()->Size) || (main_inst->GetItem()->BagType == BagTypeBandolier) || (main_inst->GetItem()->BagType == BagTypeQuiver))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (uint8 free_bag_slot = SUB_BEGIN; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++free_bag_slot)
|
||||||
|
if (!main_inst->GetItem(free_bag_slot))
|
||||||
|
return Inventory::CalcSlotId(free_slot, free_bag_slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//return INVALID_INDEX; // everything else pushes to the cursor
|
||||||
|
return MainCursor;
|
||||||
|
}
|
||||||
|
|
||||||
// Opposite of below: Get parent bag slot_id from a slot inside of bag
|
// Opposite of below: Get parent bag slot_id from a slot inside of bag
|
||||||
int16 Inventory::CalcSlotId(int16 slot_id) {
|
int16 Inventory::CalcSlotId(int16 slot_id) {
|
||||||
int16 parent_slot_id = INVALID_INDEX;
|
int16 parent_slot_id = INVALID_INDEX;
|
||||||
|
|||||||
@ -172,6 +172,7 @@ public:
|
|||||||
|
|
||||||
// Locate an available inventory slot
|
// Locate an available inventory slot
|
||||||
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
|
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
|
||||||
|
int16 FindFreeSlotForTradeItem(const ItemInst* inst);
|
||||||
|
|
||||||
// Calculate slot_id for an item within a bag
|
// Calculate slot_id for an item within a bag
|
||||||
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
|
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
|
||||||
|
|||||||
@ -65,12 +65,12 @@ LOG_TYPE( QUERYSERV, CLIENT, DISABLED )
|
|||||||
LOG_TYPE( QUERYSERV, TRACE, DISABLED )
|
LOG_TYPE( QUERYSERV, TRACE, DISABLED )
|
||||||
LOG_TYPE( QUERYSERV, PACKETS, DISABLED)
|
LOG_TYPE( QUERYSERV, PACKETS, DISABLED)
|
||||||
|
|
||||||
LOG_CATEGORY(SOCKET_SERVER)
|
LOG_CATEGORY( SOCKET_SERVER)
|
||||||
LOG_TYPE(SOCKET_SERVER, INIT, ENABLED)
|
LOG_TYPE( SOCKET_SERVER, INIT, ENABLED)
|
||||||
LOG_TYPE(SOCKET_SERVER, ERROR, ENABLED)
|
LOG_TYPE( SOCKET_SERVER, ERROR, ENABLED)
|
||||||
LOG_TYPE(SOCKET_SERVER, CLIENT, DISABLED)
|
LOG_TYPE( SOCKET_SERVER, CLIENT, DISABLED)
|
||||||
LOG_TYPE(SOCKET_SERVER, TRACE, DISABLED)
|
LOG_TYPE( SOCKET_SERVER, TRACE, DISABLED)
|
||||||
LOG_TYPE(SOCKET_SERVER, PACKETS, DISABLED)
|
LOG_TYPE( SOCKET_SERVER, PACKETS, DISABLED)
|
||||||
|
|
||||||
LOG_CATEGORY( SPAWNS )
|
LOG_CATEGORY( SPAWNS )
|
||||||
LOG_TYPE( SPAWNS, MAIN, DISABLED )
|
LOG_TYPE( SPAWNS, MAIN, DISABLED )
|
||||||
@ -108,6 +108,7 @@ LOG_CATEGORY( FACTION )
|
|||||||
|
|
||||||
LOG_CATEGORY( ZONE )
|
LOG_CATEGORY( ZONE )
|
||||||
LOG_TYPE( ZONE, GROUND_SPAWNS, DISABLED )
|
LOG_TYPE( ZONE, GROUND_SPAWNS, DISABLED )
|
||||||
|
LOG_TYPE( ZONE, SPAWNS, ENABLED)
|
||||||
LOG_TYPE( ZONE, INIT, ENABLED )
|
LOG_TYPE( ZONE, INIT, ENABLED )
|
||||||
LOG_TYPE( ZONE, INIT_ERR, ENABLED )
|
LOG_TYPE( ZONE, INIT_ERR, ENABLED )
|
||||||
LOG_TYPE( ZONE, WORLD, ENABLED )
|
LOG_TYPE( ZONE, WORLD, ENABLED )
|
||||||
|
|||||||
@ -40,7 +40,7 @@ public:
|
|||||||
MySQLRequestResult& operator=(MySQLRequestResult&& other);
|
MySQLRequestResult& operator=(MySQLRequestResult&& other);
|
||||||
|
|
||||||
bool Success() const { return m_Success;}
|
bool Success() const { return m_Success;}
|
||||||
std::string ErrorMessage() const {return std::string(m_ErrorBuffer);}
|
std::string ErrorMessage() const {return m_ErrorBuffer ? std::string(m_ErrorBuffer) : std::string("");}
|
||||||
uint32 ErrorNumber() const {return m_ErrorNumber;}
|
uint32 ErrorNumber() const {return m_ErrorNumber;}
|
||||||
uint32 RowsAffected() const {return m_RowsAffected;}
|
uint32 RowsAffected() const {return m_RowsAffected;}
|
||||||
uint32 RowCount() const {return m_RowCount;}
|
uint32 RowCount() const {return m_RowCount;}
|
||||||
|
|||||||
@ -64,6 +64,5 @@ bool MySQLRequestRow::operator!=(const MySQLRequestRow& rhs)
|
|||||||
|
|
||||||
char* MySQLRequestRow::operator[](int index)
|
char* MySQLRequestRow::operator[](int index)
|
||||||
{
|
{
|
||||||
|
|
||||||
return m_MySQLRow[index];
|
return m_MySQLRow[index];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -558,14 +558,28 @@ RULE_INT ( Console, SessionTimeOut, 600000 ) // Amount of time in ms for the con
|
|||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY( QueryServ )
|
RULE_CATEGORY( QueryServ )
|
||||||
RULE_BOOL( QueryServ, PlayerChatLogging, false) // Logs Player Chat
|
RULE_BOOL( QueryServ, PlayerLogChat, false) // Logs Player Chat
|
||||||
RULE_BOOL( QueryServ, PlayerLogTrades, false) // Logs Player Trades
|
RULE_BOOL( QueryServ, PlayerLogTrades, false) // Logs Player Trades
|
||||||
RULE_BOOL( QueryServ, PlayerLogHandins, false) // Logs Player Handins
|
RULE_BOOL( QueryServ, PlayerLogHandins, false) // Logs Player Handins
|
||||||
RULE_BOOL( QueryServ, PlayerLogNPCKills, false) // Logs Player NPC Kills
|
RULE_BOOL( QueryServ, PlayerLogNPCKills, false) // Logs Player NPC Kills
|
||||||
RULE_BOOL( QueryServ, PlayerLogDeletes, false) // Logs Player Deletes
|
RULE_BOOL( QueryServ, PlayerLogDeletes, false) // Logs Player Deletes
|
||||||
RULE_BOOL( QueryServ, PlayerLogMoves, false) // Logs Player Moves
|
RULE_BOOL( QueryServ, PlayerLogMoves, false) // Logs Player Moves
|
||||||
RULE_BOOL( QueryServ, MerchantLogTransactions, false) // Logs Merchant Transactions
|
RULE_BOOL( QueryServ, PlayerLogMerchantTransactions, false) // Logs Merchant Transactions
|
||||||
RULE_BOOL( QueryServ, PlayerLogPCCoordinates, false) // Logs Player Coordinates with certain events
|
RULE_BOOL( QueryServ, PlayerLogPCCoordinates, false) // Logs Player Coordinates with certain events
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogDropItem, false) // Logs Player Drop Item
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogZone, false) // Logs Player Zone Events
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogDeaths, false) // Logs Player Deaths
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogConnectDisconnect, false) // Logs Player Connect Disconnect State
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogLevels, false) // Logs Player Leveling/Deleveling
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogAARate, false) // Logs Player AA Experience Rates
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogQGlobalUpdate, false) // Logs Player QGlobal Updates
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogTaskUpdates, false) // Logs Player Task Updates
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogKeyringAddition, false) // Log PLayer Keyring additions
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogAAPurchases, false) // Log Player AA Purchases
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogTradeSkillEvents, false) // Log Player Tradeskill Transactions
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogIssuedCommandes, false ) // Log Player Issued Commands
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogMoneyTransactions, false) // Log Player Money Transaction/Splits
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogAlternateCurrencyTransactions, false) // Log Ploayer Alternate Currency Transactions
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY( Inventory )
|
RULE_CATEGORY( Inventory )
|
||||||
|
|||||||
@ -184,8 +184,10 @@
|
|||||||
#define ServerOP_QSPlayerLogNPCKills 0x4012
|
#define ServerOP_QSPlayerLogNPCKills 0x4012
|
||||||
#define ServerOP_QSPlayerLogDeletes 0x4013
|
#define ServerOP_QSPlayerLogDeletes 0x4013
|
||||||
#define ServerOP_QSPlayerLogMoves 0x4014
|
#define ServerOP_QSPlayerLogMoves 0x4014
|
||||||
#define ServerOP_QSMerchantLogTransactions 0x4015
|
#define ServerOP_QSPlayerLogMerchantTransactions 0x4015
|
||||||
|
#define ServerOP_QSSendQuery 0x4016
|
||||||
|
|
||||||
|
/* Query Serv Generic Packet Flag/Type Enumeration */
|
||||||
enum { QSG_LFGuild = 0 };
|
enum { QSG_LFGuild = 0 };
|
||||||
enum { QSG_LFGuild_PlayerMatches = 0, QSG_LFGuild_UpdatePlayerInfo, QSG_LFGuild_RequestPlayerInfo, QSG_LFGuild_UpdateGuildInfo, QSG_LFGuild_GuildMatches,
|
enum { QSG_LFGuild_PlayerMatches = 0, QSG_LFGuild_UpdatePlayerInfo, QSG_LFGuild_RequestPlayerInfo, QSG_LFGuild_UpdateGuildInfo, QSG_LFGuild_GuildMatches,
|
||||||
QSG_LFGuild_RequestGuildInfo };
|
QSG_LFGuild_RequestGuildInfo };
|
||||||
@ -1116,6 +1118,7 @@ struct QSPlayerLogTrade_Struct {
|
|||||||
uint32 char2_id;
|
uint32 char2_id;
|
||||||
MoneyUpdate_Struct char2_money;
|
MoneyUpdate_Struct char2_money;
|
||||||
uint16 char2_count;
|
uint16 char2_count;
|
||||||
|
uint16 _detail_count;
|
||||||
QSTradeItems_Struct items[0];
|
QSTradeItems_Struct items[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1139,6 +1142,7 @@ struct QSPlayerLogHandin_Struct {
|
|||||||
uint32 npc_id;
|
uint32 npc_id;
|
||||||
MoneyUpdate_Struct npc_money;
|
MoneyUpdate_Struct npc_money;
|
||||||
uint16 npc_count;
|
uint16 npc_count;
|
||||||
|
uint16 _detail_count;
|
||||||
QSHandinItems_Struct items[0];
|
QSHandinItems_Struct items[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1219,6 +1223,10 @@ struct QSMerchantLogTransaction_Struct {
|
|||||||
QSTransactionItems_Struct items[0];
|
QSTransactionItems_Struct items[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct QSGeneralQuery_Struct {
|
||||||
|
char QueryString[0];
|
||||||
|
};
|
||||||
|
|
||||||
struct CZMessagePlayer_Struct {
|
struct CZMessagePlayer_Struct {
|
||||||
uint32 Type;
|
uint32 Type;
|
||||||
char CharName[64];
|
char CharName[64];
|
||||||
|
|||||||
@ -1632,6 +1632,13 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
|
|||||||
|
|
||||||
int tempid = 0;
|
int tempid = 0;
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
|
|
||||||
|
if(result && mysql_field_count(getMySQL()) <= SPELL_LOAD_FIELD_COUNT) {
|
||||||
|
_log(SPELLS__LOAD_ERR, "Fatal error loading spells: Spell field count < SPELL_LOAD_FIELD_COUNT(%u)", SPELL_LOAD_FIELD_COUNT);
|
||||||
|
mysql_free_result(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (row = mysql_fetch_row(result)) {
|
while (row = mysql_fetch_row(result)) {
|
||||||
tempid = atoi(row[0]);
|
tempid = atoi(row[0]);
|
||||||
if(tempid >= max_spells) {
|
if(tempid >= max_spells) {
|
||||||
|
|||||||
@ -621,6 +621,8 @@ typedef enum {
|
|||||||
// number. note that the id field is counted as 0, this way the numbers
|
// number. note that the id field is counted as 0, this way the numbers
|
||||||
// here match the numbers given to sep in the loading function net.cpp
|
// here match the numbers given to sep in the loading function net.cpp
|
||||||
//
|
//
|
||||||
|
#define SPELL_LOAD_FIELD_COUNT 231
|
||||||
|
|
||||||
struct SPDat_Spell_Struct
|
struct SPDat_Spell_Struct
|
||||||
{
|
{
|
||||||
/* 000 */ int id; // not used
|
/* 000 */ int id; // not used
|
||||||
|
|||||||
@ -53,10 +53,11 @@ const std::string vStringFormat(const char* format, va_list args)
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
else if ((unsigned int)characters_used > output.capacity()) {
|
else if ((unsigned int)characters_used > output.capacity()) {
|
||||||
output.resize(characters_used+1);
|
output.resize(characters_used + 1);
|
||||||
va_copy(tmpargs,args);
|
va_copy(tmpargs,args);
|
||||||
characters_used = vsnprintf(&output[0], output.capacity(), format, tmpargs);
|
characters_used = vsnprintf(&output[0], output.capacity(), format, tmpargs);
|
||||||
va_end(tmpargs);
|
va_end(tmpargs);
|
||||||
|
output.resize(characters_used);
|
||||||
|
|
||||||
if (characters_used < 0) {
|
if (characters_used < 0) {
|
||||||
// We shouldn't have a format error by this point, but I can't imagine what error we
|
// We shouldn't have a format error by this point, but I can't imagine what error we
|
||||||
@ -72,6 +73,8 @@ const std::string vStringFormat(const char* format, va_list args)
|
|||||||
characters_used = vsnprintf(&output[0], output.capacity(), format, tmpargs);
|
characters_used = vsnprintf(&output[0], output.capacity(), format, tmpargs);
|
||||||
va_end(tmpargs);
|
va_end(tmpargs);
|
||||||
|
|
||||||
|
output.resize(characters_used);
|
||||||
|
|
||||||
if (characters_used < 0) {
|
if (characters_used < 0) {
|
||||||
// We shouldn't have a format error by this point, but I can't imagine what error we
|
// We shouldn't have a format error by this point, but I can't imagine what error we
|
||||||
// could have by this point. Still, return empty string;
|
// could have by this point. Still, return empty string;
|
||||||
@ -380,6 +383,42 @@ std::string EscapeString(const std::string &s) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string EscapeString(const char *src, size_t sz) {
|
||||||
|
std::string ret;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < sz; ++i) {
|
||||||
|
char c = src[i];
|
||||||
|
switch(c) {
|
||||||
|
case '\x00':
|
||||||
|
ret += "\\x00";
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
ret += "\\n";
|
||||||
|
break;
|
||||||
|
case '\r':
|
||||||
|
ret += "\\r";
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
ret += "\\\\";
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
ret += "\\'";
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
ret += "\\\"";
|
||||||
|
break;
|
||||||
|
case '\x1a':
|
||||||
|
ret += "\\x1a";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret.push_back(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool isAlphaNumeric(const char *text)
|
bool isAlphaNumeric(const char *text)
|
||||||
{
|
{
|
||||||
for (unsigned int charIndex=0; charIndex<strlen(text); charIndex++) {
|
for (unsigned int charIndex=0; charIndex<strlen(text); charIndex++) {
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
const std::string vStringFormat(const char* format, va_list args);
|
const std::string vStringFormat(const char* format, va_list args);
|
||||||
const std::string StringFormat(const char* format, ...);
|
const std::string StringFormat(const char* format, ...);
|
||||||
std::string EscapeString(const std::string &s);
|
std::string EscapeString(const std::string &s);
|
||||||
|
std::string EscapeString(const char *src, size_t sz);
|
||||||
|
|
||||||
const char *MakeLowerString(const char *source);
|
const char *MakeLowerString(const char *source);
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,7 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
// Disgrace: for windows compile
|
// Disgrace: for windows compile
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
@ -96,41 +97,6 @@ Database::~Database()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::GetVariable(const char* varname, char* varvalue, uint16 varvalue_len) {
|
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char* query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
if (!RunQuery(query,MakeAnyLenString(&query, "select `value` from `variables` where `varname`='%s'", varname), errbuf, &result)) {
|
|
||||||
|
|
||||||
_log(UCS__ERROR, "Unable to get message count from database. %s %s", query, errbuf);
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
if (mysql_num_rows(result) != 1) {
|
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
|
|
||||||
snprintf(varvalue, varvalue_len, "%s", row[0]);
|
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Database::AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type) {
|
void Database::AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type) {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
char* query = 0;
|
char* query = 0;
|
||||||
@ -143,8 +109,8 @@ void Database::AddSpeech(const char* from, const char* to, const char* message,
|
|||||||
DoEscapeString(S3, message, strlen(message));
|
DoEscapeString(S3, message, strlen(message));
|
||||||
|
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_speech` SET `from`='%s', `to`='%s', `message`='%s', `minstatus`='%i', `guilddbid`='%i', `type`='%i'", S1, S2, S3, minstatus, guilddbid, type), errbuf, 0, 0)) {
|
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_speech` SET `from`='%s', `to`='%s', `message`='%s', `minstatus`='%i', `guilddbid`='%i', `type`='%i'", S1, S2, S3, minstatus, guilddbid, type), errbuf, 0, 0)) {
|
||||||
_log(NET__WORLD, "Failed Speech Entry Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Speech Entry Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete_array(query);
|
safe_delete_array(query);
|
||||||
@ -153,7 +119,7 @@ void Database::AddSpeech(const char* from, const char* to, const char* message,
|
|||||||
safe_delete_array(S3);
|
safe_delete_array(S3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items) {
|
void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 DetailCount) {
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
char* query = 0;
|
char* query = 0;
|
||||||
@ -164,27 +130,26 @@ void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items) {
|
|||||||
QS->char1_id, QS->char1_money.platinum, QS->char1_money.gold, QS->char1_money.silver, QS->char1_money.copper, QS->char1_count,
|
QS->char1_id, QS->char1_money.platinum, QS->char1_money.gold, QS->char1_money.silver, QS->char1_money.copper, QS->char1_count,
|
||||||
QS->char2_id, QS->char2_money.platinum, QS->char2_money.gold, QS->char2_money.silver, QS->char2_money.copper, QS->char2_count),
|
QS->char2_id, QS->char2_money.platinum, QS->char2_money.gold, QS->char2_money.silver, QS->char2_money.copper, QS->char2_count),
|
||||||
errbuf, 0, 0, &lastid)) {
|
errbuf, 0, 0, &lastid)) {
|
||||||
_log(NET__WORLD, "Failed Trade Log Record Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Trade Log Record Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Items > 0) {
|
if(DetailCount > 0) {
|
||||||
for(int i = 0; i < Items; i++) {
|
for(int i = 0; i < DetailCount; i++) {
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_trade_record_entries` SET `event_id`='%i', "
|
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_trade_record_entries` SET `event_id`='%i', "
|
||||||
"`from_id`='%i', `from_slot`='%i', `to_id`='%i', `to_slot`='%i', `item_id`='%i', "
|
"`from_id`='%i', `from_slot`='%i', `to_id`='%i', `to_slot`='%i', `item_id`='%i', "
|
||||||
"`charges`='%i', `aug_1`='%i', `aug_2`='%i', `aug_3`='%i', `aug_4`='%i', `aug_5`='%i'",
|
"`charges`='%i', `aug_1`='%i', `aug_2`='%i', `aug_3`='%i', `aug_4`='%i', `aug_5`='%i'",
|
||||||
lastid, QS->items[i].from_id, QS->items[i].from_slot, QS->items[i].to_id, QS->items[i].to_slot, QS->items[i].item_id,
|
lastid, QS->items[i].from_id, QS->items[i].from_slot, QS->items[i].to_id, QS->items[i].to_slot, QS->items[i].item_id,
|
||||||
QS->items[i].charges, QS->items[i].aug_1, QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
QS->items[i].charges, QS->items[i].aug_1, QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
||||||
errbuf, 0, 0))) {
|
errbuf, 0, 0))) {
|
||||||
_log(NET__WORLD, "Failed Trade Log Record Entry Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Trade Log Record Entry Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items) {
|
void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 DetailCount) {
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
char* query = 0;
|
char* query = 0;
|
||||||
uint32 lastid = 0;
|
uint32 lastid = 0;
|
||||||
@ -194,20 +159,20 @@ void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items) {
|
|||||||
QS->quest_id, QS->char_id, QS->char_money.platinum, QS->char_money.gold, QS->char_money.silver, QS->char_money.copper, QS->char_count,
|
QS->quest_id, QS->char_id, QS->char_money.platinum, QS->char_money.gold, QS->char_money.silver, QS->char_money.copper, QS->char_count,
|
||||||
QS->npc_id, QS->npc_money.platinum, QS->npc_money.gold, QS->npc_money.silver, QS->npc_money.copper, QS->npc_count),
|
QS->npc_id, QS->npc_money.platinum, QS->npc_money.gold, QS->npc_money.silver, QS->npc_money.copper, QS->npc_count),
|
||||||
errbuf, 0, 0, &lastid)) {
|
errbuf, 0, 0, &lastid)) {
|
||||||
_log(NET__WORLD, "Failed Handin Log Record Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Handin Log Record Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Items > 0) {
|
if(DetailCount > 0) {
|
||||||
for(int i = 0; i < Items; i++) {
|
for(int i = 0; i < DetailCount; i++) {
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_handin_record_entries` SET `event_id`='%i', "
|
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_handin_record_entries` SET `event_id`='%i', "
|
||||||
"`action_type`='%s', `char_slot`='%i', `item_id`='%i', `charges`='%i', "
|
"`action_type`='%s', `char_slot`='%i', `item_id`='%i', `charges`='%i', "
|
||||||
"`aug_1`='%i', `aug_2`='%i', `aug_3`='%i', `aug_4`='%i', `aug_5`='%i'",
|
"`aug_1`='%i', `aug_2`='%i', `aug_3`='%i', `aug_4`='%i', `aug_5`='%i'",
|
||||||
lastid, QS->items[i].action_type, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges,
|
lastid, QS->items[i].action_type, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges,
|
||||||
QS->items[i].aug_1, QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
QS->items[i].aug_1, QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
||||||
errbuf, 0, 0))) {
|
errbuf, 0, 0))) {
|
||||||
_log(NET__WORLD, "Failed Handin Log Record Entry Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Handin Log Record Entry Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -218,15 +183,15 @@ void Database::LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 Members){
|
|||||||
char* query = 0;
|
char* query = 0;
|
||||||
uint32 lastid = 0;
|
uint32 lastid = 0;
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_npc_kill_record` SET `npc_id`='%i', `type`='%i', `zone_id`='%i', `time`=NOW()", QS->s1.NPCID, QS->s1.Type, QS->s1.ZoneID), errbuf, 0, 0, &lastid)) {
|
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_npc_kill_record` SET `npc_id`='%i', `type`='%i', `zone_id`='%i', `time`=NOW()", QS->s1.NPCID, QS->s1.Type, QS->s1.ZoneID), errbuf, 0, 0, &lastid)) {
|
||||||
_log(NET__WORLD, "Failed NPC Kill Log Record Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed NPC Kill Log Record Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Members > 0){
|
if(Members > 0){
|
||||||
for (int i = 0; i < Members; i++) {
|
for (int i = 0; i < Members; i++) {
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_npc_kill_record_entries` SET `event_id`='%i', `char_id`='%i'", lastid, QS->Chars[i].char_id, errbuf, 0, 0))) {
|
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_npc_kill_record_entries` SET `event_id`='%i', `char_id`='%i'", lastid, QS->Chars[i].char_id, errbuf, 0, 0))) {
|
||||||
_log(NET__WORLD, "Failed NPC Kill Log Entry Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed NPC Kill Log Entry Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -241,8 +206,8 @@ void Database::LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items) {
|
|||||||
"`char_id`='%i', `stack_size`='%i', `char_items`='%i'",
|
"`char_id`='%i', `stack_size`='%i', `char_items`='%i'",
|
||||||
QS->char_id, QS->stack_size, QS->char_count, QS->char_count),
|
QS->char_id, QS->stack_size, QS->char_count, QS->char_count),
|
||||||
errbuf, 0, 0, &lastid)) {
|
errbuf, 0, 0, &lastid)) {
|
||||||
_log(NET__WORLD, "Failed Delete Log Record Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Delete Log Record Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Items > 0) {
|
if(Items > 0) {
|
||||||
@ -253,15 +218,15 @@ void Database::LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items) {
|
|||||||
lastid, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges, QS->items[i].aug_1,
|
lastid, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges, QS->items[i].aug_1,
|
||||||
QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
||||||
errbuf, 0, 0))) {
|
errbuf, 0, 0))) {
|
||||||
_log(NET__WORLD, "Failed Delete Log Record Entry Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Delete Log Record Entry Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items) {
|
void Database::LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items) {
|
||||||
|
/* These are item moves */
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
char* query = 0;
|
char* query = 0;
|
||||||
uint32 lastid = 0;
|
uint32 lastid = 0;
|
||||||
@ -269,10 +234,9 @@ void Database::LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items) {
|
|||||||
"`char_id`='%i', `from_slot`='%i', `to_slot`='%i', `stack_size`='%i', `char_items`='%i', `postaction`='%i'",
|
"`char_id`='%i', `from_slot`='%i', `to_slot`='%i', `stack_size`='%i', `char_items`='%i', `postaction`='%i'",
|
||||||
QS->char_id, QS->from_slot, QS->to_slot, QS->stack_size, QS->char_count, QS->postaction),
|
QS->char_id, QS->from_slot, QS->to_slot, QS->stack_size, QS->char_count, QS->postaction),
|
||||||
errbuf, 0, 0, &lastid)) {
|
errbuf, 0, 0, &lastid)) {
|
||||||
_log(NET__WORLD, "Failed Move Log Record Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Move Log Record Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Items > 0) {
|
if(Items > 0) {
|
||||||
for(int i = 0; i < Items; i++) {
|
for(int i = 0; i < Items; i++) {
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_move_record_entries` SET `event_id`='%i', "
|
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_move_record_entries` SET `event_id`='%i', "
|
||||||
@ -281,16 +245,15 @@ void Database::LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items) {
|
|||||||
QS->items[i].from_slot, QS->items[i].to_slot, QS->items[i].item_id, QS->items[i].charges,
|
QS->items[i].from_slot, QS->items[i].to_slot, QS->items[i].item_id, QS->items[i].charges,
|
||||||
QS->items[i].aug_1, QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
QS->items[i].aug_1, QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
||||||
errbuf, 0, 0))) {
|
errbuf, 0, 0))) {
|
||||||
_log(NET__WORLD, "Failed Move Log Record Entry Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Move Log Record Entry Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint32 Items) {
|
void Database::LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint32 Items) {
|
||||||
// Merchant transactions are from the perspective of the merchant, not the player -U
|
/* Merchant transactions are from the perspective of the merchant, not the player -U */
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
char* query = 0;
|
char* query = 0;
|
||||||
uint32 lastid = 0;
|
uint32 lastid = 0;
|
||||||
@ -300,8 +263,8 @@ void Database::LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint3
|
|||||||
QS->zone_id, QS->merchant_id, QS->merchant_money.platinum, QS->merchant_money.gold, QS->merchant_money.silver, QS->merchant_money.copper, QS->merchant_count,
|
QS->zone_id, QS->merchant_id, QS->merchant_money.platinum, QS->merchant_money.gold, QS->merchant_money.silver, QS->merchant_money.copper, QS->merchant_count,
|
||||||
QS->char_id, QS->char_money.platinum, QS->char_money.gold, QS->char_money.silver, QS->char_money.copper, QS->char_count),
|
QS->char_id, QS->char_money.platinum, QS->char_money.gold, QS->char_money.silver, QS->char_money.copper, QS->char_count),
|
||||||
errbuf, 0, 0, &lastid)) {
|
errbuf, 0, 0, &lastid)) {
|
||||||
_log(NET__WORLD, "Failed Transaction Log Record Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Transaction Log Record Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Items > 0) {
|
if(Items > 0) {
|
||||||
@ -312,10 +275,29 @@ void Database::LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint3
|
|||||||
lastid, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges, QS->items[i].aug_1,
|
lastid, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges, QS->items[i].aug_1,
|
||||||
QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
||||||
errbuf, 0, 0))) {
|
errbuf, 0, 0))) {
|
||||||
_log(NET__WORLD, "Failed Transaction Log Record Entry Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Transaction Log Record Entry Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
safe_delete_array(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
safe_delete_array(query);
|
||||||
|
safe_delete(pack);
|
||||||
|
safe_delete(Query);
|
||||||
|
}
|
||||||
|
|||||||
@ -42,14 +42,14 @@ public:
|
|||||||
bool Connect(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();
|
~Database();
|
||||||
|
|
||||||
bool GetVariable(const char* varname, char* varvalue, uint16 varvalue_len);
|
|
||||||
void AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type);
|
void AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type);
|
||||||
void LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items);
|
void LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 DetailCount);
|
||||||
void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items);
|
void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 DetailCount);
|
||||||
void LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 Members);
|
void LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 Members);
|
||||||
void LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items);
|
void LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items);
|
||||||
void LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items);
|
void LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items);
|
||||||
void LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint32 Items);
|
void LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint32 Items);
|
||||||
|
void GeneralQueryReceive(ServerPacket *pack);
|
||||||
protected:
|
protected:
|
||||||
void HandleMysqlError(uint32 errnum);
|
void HandleMysqlError(uint32 errnum);
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -33,24 +33,15 @@
|
|||||||
|
|
||||||
volatile bool RunLoops = true;
|
volatile bool RunLoops = true;
|
||||||
|
|
||||||
uint32 MailMessagesSent = 0;
|
|
||||||
uint32 ChatMessagesSent = 0;
|
|
||||||
|
|
||||||
TimeoutManager timeout_manager;
|
TimeoutManager timeout_manager;
|
||||||
|
|
||||||
Database database;
|
Database database;
|
||||||
LFGuildManager lfguildmanager;
|
LFGuildManager lfguildmanager;
|
||||||
std::string WorldShortName;
|
std::string WorldShortName;
|
||||||
|
|
||||||
const queryservconfig *Config;
|
const queryservconfig *Config;
|
||||||
|
|
||||||
WorldServer *worldserver = 0;
|
WorldServer *worldserver = 0;
|
||||||
|
|
||||||
|
|
||||||
void CatchSignal(int sig_num) {
|
void CatchSignal(int sig_num) {
|
||||||
|
|
||||||
RunLoops = false;
|
RunLoops = false;
|
||||||
|
|
||||||
if(worldserver)
|
if(worldserver)
|
||||||
worldserver->Disconnect();
|
worldserver->Disconnect();
|
||||||
}
|
}
|
||||||
@ -58,31 +49,31 @@ void CatchSignal(int sig_num) {
|
|||||||
int main() {
|
int main() {
|
||||||
RegisterExecutablePlatform(ExePlatformQueryServ);
|
RegisterExecutablePlatform(ExePlatformQueryServ);
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
|
|
||||||
Timer LFGuildExpireTimer(60000);
|
Timer LFGuildExpireTimer(60000);
|
||||||
|
|
||||||
Timer InterserverTimer(INTERSERVER_TIMER); // does auto-reconnect
|
Timer InterserverTimer(INTERSERVER_TIMER); // does auto-reconnect
|
||||||
|
|
||||||
|
/* Load XML from eqemu_config.xml
|
||||||
|
<qsdatabase>
|
||||||
|
<host>127.0.0.1</host>
|
||||||
|
<port>3306</port>
|
||||||
|
<username>user</username>
|
||||||
|
<password>password</password>
|
||||||
|
<db>dbname</db>
|
||||||
|
</qsdatabase>
|
||||||
|
*/
|
||||||
|
|
||||||
_log(QUERYSERV__INIT, "Starting EQEmu QueryServ.");
|
_log(QUERYSERV__INIT, "Starting EQEmu QueryServ.");
|
||||||
|
|
||||||
if (!queryservconfig::LoadConfig()) {
|
if (!queryservconfig::LoadConfig()) {
|
||||||
|
|
||||||
_log(QUERYSERV__INIT, "Loading server configuration failed.");
|
_log(QUERYSERV__INIT, "Loading server configuration failed.");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Config = queryservconfig::get();
|
Config = queryservconfig::get();
|
||||||
|
|
||||||
if(!load_log_settings(Config->LogSettingsFile.c_str()))
|
|
||||||
_log(QUERYSERV__INIT, "Warning: Unable to read %s", Config->LogSettingsFile.c_str());
|
|
||||||
else
|
|
||||||
_log(QUERYSERV__INIT, "Log settings loaded from %s", Config->LogSettingsFile.c_str());
|
|
||||||
|
|
||||||
WorldShortName = Config->ShortName;
|
WorldShortName = Config->ShortName;
|
||||||
|
|
||||||
_log(QUERYSERV__INIT, "Connecting to MySQL...");
|
_log(QUERYSERV__INIT, "Connecting to MySQL...");
|
||||||
|
|
||||||
|
/* MySQL Connection */
|
||||||
if (!database.Connect(
|
if (!database.Connect(
|
||||||
Config->QSDatabaseHost.c_str(),
|
Config->QSDatabaseHost.c_str(),
|
||||||
Config->QSDatabaseUsername.c_str(),
|
Config->QSDatabaseUsername.c_str(),
|
||||||
@ -93,6 +84,12 @@ int main() {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize Logging */
|
||||||
|
if (!load_log_settings(Config->LogSettingsFile.c_str()))
|
||||||
|
_log(QUERYSERV__INIT, "Warning: Unable to read %s", Config->LogSettingsFile.c_str());
|
||||||
|
else
|
||||||
|
_log(QUERYSERV__INIT, "Log settings loaded from %s", Config->LogSettingsFile.c_str());
|
||||||
|
|
||||||
if (signal(SIGINT, CatchSignal) == SIG_ERR) {
|
if (signal(SIGINT, CatchSignal) == SIG_ERR) {
|
||||||
_log(QUERYSERV__ERROR, "Could not set signal handler");
|
_log(QUERYSERV__ERROR, "Could not set signal handler");
|
||||||
return 1;
|
return 1;
|
||||||
@ -102,16 +99,15 @@ int main() {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initial Connection to Worldserver */
|
||||||
worldserver = new WorldServer;
|
worldserver = new WorldServer;
|
||||||
|
|
||||||
worldserver->Connect();
|
worldserver->Connect();
|
||||||
|
|
||||||
|
/* Load Looking For Guild Manager */
|
||||||
lfguildmanager.LoadDatabase();
|
lfguildmanager.LoadDatabase();
|
||||||
|
|
||||||
while(RunLoops) {
|
while(RunLoops) {
|
||||||
|
|
||||||
Timer::SetCurrentTime();
|
Timer::SetCurrentTime();
|
||||||
|
|
||||||
if(LFGuildExpireTimer.Check())
|
if(LFGuildExpireTimer.Check())
|
||||||
lfguildmanager.ExpireEntries();
|
lfguildmanager.ExpireEntries();
|
||||||
|
|
||||||
@ -120,9 +116,7 @@ int main() {
|
|||||||
worldserver->AsyncConnect();
|
worldserver->AsyncConnect();
|
||||||
}
|
}
|
||||||
worldserver->Process();
|
worldserver->Process();
|
||||||
|
|
||||||
timeout_manager.CheckTimeouts();
|
timeout_manager.CheckTimeouts();
|
||||||
|
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,121 +57,106 @@ void WorldServer::OnConnected()
|
|||||||
void WorldServer::Process()
|
void WorldServer::Process()
|
||||||
{
|
{
|
||||||
WorldConnection::Process();
|
WorldConnection::Process();
|
||||||
|
|
||||||
if (!Connected())
|
if (!Connected())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ServerPacket *pack = 0;
|
ServerPacket *pack = 0;
|
||||||
|
|
||||||
while((pack = tcpc.PopPacket()))
|
while((pack = tcpc.PopPacket()))
|
||||||
{
|
{
|
||||||
_log(QUERYSERV__TRACE, "Received Opcode: %4X", pack->opcode);
|
_log(QUERYSERV__TRACE, "Received Opcode: %4X", pack->opcode);
|
||||||
|
switch(pack->opcode) {
|
||||||
switch(pack->opcode)
|
|
||||||
{
|
|
||||||
case 0: {
|
case 0: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_KeepAlive:
|
case ServerOP_KeepAlive: {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_Speech:
|
case ServerOP_Speech: {
|
||||||
{
|
|
||||||
Server_Speech_Struct *SSS = (Server_Speech_Struct*)pack->pBuffer;
|
Server_Speech_Struct *SSS = (Server_Speech_Struct*)pack->pBuffer;
|
||||||
|
|
||||||
std::string tmp1 = SSS->from;
|
std::string tmp1 = SSS->from;
|
||||||
std::string tmp2 = SSS->to;
|
std::string tmp2 = SSS->to;
|
||||||
|
|
||||||
database.AddSpeech(tmp1.c_str(), tmp2.c_str(), SSS->message, SSS->minstatus, SSS->guilddbid, SSS->type);
|
database.AddSpeech(tmp1.c_str(), tmp2.c_str(), SSS->message, SSS->minstatus, SSS->guilddbid, SSS->type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSPlayerLogTrades:
|
case ServerOP_QSPlayerLogTrades: {
|
||||||
{
|
|
||||||
QSPlayerLogTrade_Struct *QS = (QSPlayerLogTrade_Struct*)pack->pBuffer;
|
QSPlayerLogTrade_Struct *QS = (QSPlayerLogTrade_Struct*)pack->pBuffer;
|
||||||
uint32 Items = QS->char1_count + QS->char2_count;
|
database.LogPlayerTrade(QS, QS->_detail_count);
|
||||||
database.LogPlayerTrade(QS, Items);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSPlayerLogHandins:
|
case ServerOP_QSPlayerLogHandins: {
|
||||||
{
|
|
||||||
QSPlayerLogHandin_Struct *QS = (QSPlayerLogHandin_Struct*)pack->pBuffer;
|
QSPlayerLogHandin_Struct *QS = (QSPlayerLogHandin_Struct*)pack->pBuffer;
|
||||||
uint32 Items = QS->char_count + QS->npc_count;
|
database.LogPlayerHandin(QS, QS->_detail_count);
|
||||||
database.LogPlayerHandin(QS, Items);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSPlayerLogNPCKills:
|
case ServerOP_QSPlayerLogNPCKills: {
|
||||||
{
|
|
||||||
QSPlayerLogNPCKill_Struct *QS = (QSPlayerLogNPCKill_Struct*)pack->pBuffer;
|
QSPlayerLogNPCKill_Struct *QS = (QSPlayerLogNPCKill_Struct*)pack->pBuffer;
|
||||||
uint32 Members = pack->size - sizeof(QSPlayerLogNPCKill_Struct);
|
uint32 Members = pack->size - sizeof(QSPlayerLogNPCKill_Struct);
|
||||||
if (Members > 0) Members = Members / sizeof(QSPlayerLogNPCKillsPlayers_Struct);
|
if (Members > 0) Members = Members / sizeof(QSPlayerLogNPCKillsPlayers_Struct);
|
||||||
database.LogPlayerNPCKill(QS, Members);
|
database.LogPlayerNPCKill(QS, Members);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSPlayerLogDeletes:
|
case ServerOP_QSPlayerLogDeletes: {
|
||||||
{
|
|
||||||
QSPlayerLogDelete_Struct *QS = (QSPlayerLogDelete_Struct*)pack->pBuffer;
|
QSPlayerLogDelete_Struct *QS = (QSPlayerLogDelete_Struct*)pack->pBuffer;
|
||||||
uint32 Items = QS->char_count;
|
uint32 Items = QS->char_count;
|
||||||
database.LogPlayerDelete(QS, Items);
|
database.LogPlayerDelete(QS, Items);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSPlayerLogMoves:
|
case ServerOP_QSPlayerLogMoves: {
|
||||||
{
|
|
||||||
QSPlayerLogMove_Struct *QS = (QSPlayerLogMove_Struct*)pack->pBuffer;
|
QSPlayerLogMove_Struct *QS = (QSPlayerLogMove_Struct*)pack->pBuffer;
|
||||||
uint32 Items = QS->char_count;
|
uint32 Items = QS->char_count;
|
||||||
database.LogPlayerMove(QS, Items);
|
database.LogPlayerMove(QS, Items);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSMerchantLogTransactions:
|
case ServerOP_QSPlayerLogMerchantTransactions: {
|
||||||
{
|
|
||||||
QSMerchantLogTransaction_Struct *QS = (QSMerchantLogTransaction_Struct*)pack->pBuffer;
|
QSMerchantLogTransaction_Struct *QS = (QSMerchantLogTransaction_Struct*)pack->pBuffer;
|
||||||
uint32 Items = QS->char_count + QS->merchant_count;
|
uint32 Items = QS->char_count + QS->merchant_count;
|
||||||
database.LogMerchantTransaction(QS, Items);
|
database.LogMerchantTransaction(QS, Items);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QueryServGeneric:
|
case ServerOP_QueryServGeneric: {
|
||||||
{
|
/*
|
||||||
// The purpose of ServerOP_QueryServerGeneric is so that we don't have to add code to world just to relay packets
|
The purpose of ServerOP_QueryServerGeneric is so that we don't have to add code to world just to relay packets
|
||||||
// each time we add functionality to queryserv.
|
each time we add functionality to queryserv.
|
||||||
//
|
|
||||||
// A ServerOP_QueryServGeneric packet has the following format:
|
A ServerOP_QueryServGeneric packet has the following format:
|
||||||
//
|
|
||||||
// uint32 SourceZoneID
|
uint32 SourceZoneID
|
||||||
// uint32 SourceInstanceID
|
uint32 SourceInstanceID
|
||||||
// char OriginatingCharacterName[0] // Null terminated name of the character this packet came from. This could be just
|
char OriginatingCharacterName[0]
|
||||||
// // an empty string if it has no meaning in the context of a particular packet.
|
- Null terminated name of the character this packet came from. This could be just
|
||||||
// uint32 Type
|
- an empty string if it has no meaning in the context of a particular packet.
|
||||||
//
|
uint32 Type
|
||||||
// The 'Type' field is a 'sub-opcode'. A value of 0 is used for the LFGuild packets. The next feature to be added
|
|
||||||
// to queryserv would use 1, etc.
|
The 'Type' field is a 'sub-opcode'. A value of 0 is used for the LFGuild packets. The next feature to be added
|
||||||
//
|
to queryserv would use 1, etc.
|
||||||
// Obviously, any fields in the packet following the 'Type' will be unique to the particular type of packet. The
|
|
||||||
// 'Generic' in the name of this ServerOP code relates to the four header fields.
|
Obviously, any fields in the packet following the 'Type' will be unique to the particular type of packet. The
|
||||||
|
'Generic' in the name of this ServerOP code relates to the four header fields.
|
||||||
|
*/
|
||||||
|
|
||||||
char From[64];
|
char From[64];
|
||||||
pack->SetReadPosition(8);
|
pack->SetReadPosition(8);
|
||||||
pack->ReadString(From);
|
pack->ReadString(From);
|
||||||
uint32 Type = pack->ReadUInt32();
|
uint32 Type = pack->ReadUInt32();
|
||||||
|
|
||||||
switch(Type)
|
switch(Type) {
|
||||||
{
|
case QSG_LFGuild:{
|
||||||
case QSG_LFGuild:
|
|
||||||
{
|
|
||||||
lfguildmanager.HandlePacket(pack);
|
lfguildmanager.HandlePacket(pack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
_log(QUERYSERV__ERROR, "Received unhandled ServerOP_QueryServGeneric", Type);
|
_log(QUERYSERV__ERROR, "Received unhandled ServerOP_QueryServGeneric", Type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServerOP_QSSendQuery: {
|
||||||
|
/* Process all packets here */
|
||||||
|
database.GeneralQueryReceive(pack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete(pack);
|
safe_delete(pack);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,12 +7,13 @@ SET(tests_sources
|
|||||||
)
|
)
|
||||||
|
|
||||||
SET(tests_headers
|
SET(tests_headers
|
||||||
|
atobool_test.h
|
||||||
fixed_memory_test.h
|
fixed_memory_test.h
|
||||||
fixed_memory_variable_test.h
|
fixed_memory_variable_test.h
|
||||||
|
hextoi_32_64_test.h
|
||||||
ipc_mutex_test.h
|
ipc_mutex_test.h
|
||||||
memory_mapped_file_test.h
|
memory_mapped_file_test.h
|
||||||
atobool_test.h
|
string_util_test.h
|
||||||
hextoi_32_64_test.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers})
|
ADD_EXECUTABLE(tests ${tests_sources} ${tests_headers})
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
#include "fixed_memory_variable_test.h"
|
#include "fixed_memory_variable_test.h"
|
||||||
#include "atobool_test.h"
|
#include "atobool_test.h"
|
||||||
#include "hextoi_32_64_test.h"
|
#include "hextoi_32_64_test.h"
|
||||||
|
#include "string_util_test.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
try {
|
try {
|
||||||
@ -38,6 +39,7 @@ int main() {
|
|||||||
tests.add(new FixedMemoryVariableHashTest());
|
tests.add(new FixedMemoryVariableHashTest());
|
||||||
tests.add(new atoboolTest());
|
tests.add(new atoboolTest());
|
||||||
tests.add(new hextoi_32_64_Test());
|
tests.add(new hextoi_32_64_Test());
|
||||||
|
tests.add(new StringUtilTest());
|
||||||
tests.run(*output, true);
|
tests.run(*output, true);
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
85
tests/string_util_test.h
Normal file
85
tests/string_util_test.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/* EQEMu: Everquest Server Emulator
|
||||||
|
Copyright (C) 2001-2013 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_STRING_UTIL_H
|
||||||
|
#define __EQEMU_TESTS_STRING_UTIL_H
|
||||||
|
|
||||||
|
#include "cppunit/cpptest.h"
|
||||||
|
#include "../common/string_util.h"
|
||||||
|
|
||||||
|
class StringUtilTest : public Test::Suite {
|
||||||
|
typedef void(IPCMutexTest::*TestFunction)(void);
|
||||||
|
public:
|
||||||
|
StringUtilTest() {
|
||||||
|
TEST_ADD(StringUtilTest::StringFormatTest);
|
||||||
|
TEST_ADD(StringUtilTest::EscapeStringTest);
|
||||||
|
TEST_ADD(StringUtilTest::EscapeStringMemoryTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
~StringUtilTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void StringFormatTest() {
|
||||||
|
const char* fmt = "Test: %c %d %4.2f";
|
||||||
|
char c = 'a';
|
||||||
|
int i = 2014;
|
||||||
|
float f = 3.1416;
|
||||||
|
|
||||||
|
auto s = StringFormat(fmt, c, i, f);
|
||||||
|
TEST_ASSERT_EQUALS(s.length(), 17);
|
||||||
|
TEST_ASSERT(s.compare("Test: a 2014 3.14") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EscapeStringTest() {
|
||||||
|
std::string t;
|
||||||
|
t.resize(10);
|
||||||
|
t[0] = 'a';
|
||||||
|
t[1] = 'b';
|
||||||
|
t[2] = 'c';
|
||||||
|
t[3] = '\x00';
|
||||||
|
t[4] = '\n';
|
||||||
|
t[5] = '\r';
|
||||||
|
t[6] = '\\';
|
||||||
|
t[7] = '\'';
|
||||||
|
t[8] = '\"';
|
||||||
|
t[9] = '\x1a';
|
||||||
|
|
||||||
|
auto s = EscapeString(t);
|
||||||
|
TEST_ASSERT(s.compare("abc\\x00\\n\\r\\\\\\'\\\"\\x1a") == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EscapeStringMemoryTest() {
|
||||||
|
char t[10] = { 0 };
|
||||||
|
t[0] = 'a';
|
||||||
|
t[1] = 'b';
|
||||||
|
t[2] = 'c';
|
||||||
|
t[3] = '\x00';
|
||||||
|
t[4] = '\n';
|
||||||
|
t[5] = '\r';
|
||||||
|
t[6] = '\\';
|
||||||
|
t[7] = '\'';
|
||||||
|
t[8] = '\"';
|
||||||
|
t[9] = '\x1a';
|
||||||
|
|
||||||
|
auto s = EscapeString(t, 10);
|
||||||
|
TEST_ASSERT(s.compare("abc\\x00\\n\\r\\\\\\'\\\"\\x1a") == 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
737
ucs/database.cpp
737
ucs/database.cpp
@ -102,208 +102,143 @@ Database::~Database()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::GetAccountStatus(Client *c) {
|
void Database::GetAccountStatus(Client *client) {
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char* query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
if (!RunQuery(query,MakeAnyLenString(&query, "select `status`, `hideme`, `karma`, `revoked` from `account` where `id`='%i' limit 1",
|
|
||||||
c->GetAccountID()),errbuf,&result)){
|
|
||||||
|
|
||||||
_log(UCS__ERROR, "Unable to get account status for character %s, error %s", c->GetName().c_str(), errbuf);
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
|
std::string query = StringFormat("SELECT `status`, `hideme`, `karma`, `revoked` "
|
||||||
|
"FROM `account` WHERE `id` = '%i' LIMIT 1",
|
||||||
|
client->GetAccountID());
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
_log(UCS__ERROR, "Unable to get account status for character %s, error %s", client->GetName().c_str(), results.ErrorMessage().c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_log(UCS__TRACE, "GetAccountStatus Query: %s", query);
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
if(mysql_num_rows(result) != 1)
|
_log(UCS__TRACE, "GetAccountStatus Query: %s", query.c_str());
|
||||||
|
|
||||||
|
if(results.RowCount() != 1)
|
||||||
{
|
{
|
||||||
_log(UCS__ERROR, "Error in GetAccountStatus");
|
_log(UCS__ERROR, "Error in GetAccountStatus");
|
||||||
mysql_free_result(result);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
row = mysql_fetch_row(result);
|
auto row = results.begin();
|
||||||
|
|
||||||
c->SetAccountStatus(atoi(row[0]));
|
client->SetAccountStatus(atoi(row[0]));
|
||||||
c->SetHideMe(atoi(row[1]) != 0);
|
client->SetHideMe(atoi(row[1]) != 0);
|
||||||
c->SetKarma(atoi(row[2]));
|
client->SetKarma(atoi(row[2]));
|
||||||
c->SetRevoked((atoi(row[3])==1?true:false));
|
client->SetRevoked((atoi(row[3])==1?true:false));
|
||||||
|
|
||||||
|
_log(UCS__TRACE, "Set account status to %i, hideme to %i and karma to %i for %s", client->GetAccountStatus(), client->GetHideMe(), client->GetKarma(), client->GetName().c_str());
|
||||||
|
|
||||||
_log(UCS__TRACE, "Set account status to %i, hideme to %i and karma to %i for %s", c->GetAccountStatus(), c->GetHideMe(), c->GetKarma(), c->GetName().c_str());
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Database::FindAccount(const char *CharacterName, Client *c) {
|
int Database::FindAccount(const char *characterName, Client *client) {
|
||||||
|
|
||||||
_log(UCS__TRACE, "FindAccount for character %s", CharacterName);
|
_log(UCS__TRACE, "FindAccount for character %s", characterName);
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char* query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
c->ClearCharacters();
|
client->ClearCharacters();
|
||||||
|
std::string query = StringFormat("SELECT `id`, `account_id`, `level` "
|
||||||
if (!RunQuery(query,MakeAnyLenString(&query, "select `id`, `account_id`, `level` from `character_` where `name`='%s' limit 1",
|
"FROM `character_` WHERE `name` = '%s' LIMIT 1",
|
||||||
CharacterName),errbuf,&result))
|
characterName);
|
||||||
{
|
auto results = QueryDatabase(query);
|
||||||
_log(UCS__ERROR, "FindAccount query failed: %s", query);
|
if (!results.Success()) {
|
||||||
safe_delete_array(query);
|
_log(UCS__ERROR, "FindAccount query failed: %s", query.c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
if (mysql_num_rows(result) != 1)
|
if (results.RowCount() != 1) {
|
||||||
{
|
|
||||||
_log(UCS__ERROR, "Bad result from query");
|
_log(UCS__ERROR, "Bad result from query");
|
||||||
mysql_free_result(result);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
row = mysql_fetch_row(result);
|
auto row = results.begin();
|
||||||
c->AddCharacter(atoi(row[0]), CharacterName, atoi(row[2]));
|
client->AddCharacter(atoi(row[0]), characterName, atoi(row[2]));
|
||||||
int AccountID = atoi(row[1]);
|
|
||||||
|
|
||||||
mysql_free_result(result);
|
int accountID = atoi(row[1]);
|
||||||
_log(UCS__TRACE, "Account ID for %s is %i", CharacterName, AccountID);
|
|
||||||
|
|
||||||
if (!RunQuery(query,MakeAnyLenString(&query, "select `id`, `name`, `level` from `character_` where `account_id`=%i and `name` !='%s'",
|
_log(UCS__TRACE, "Account ID for %s is %i", characterName, accountID);
|
||||||
AccountID, CharacterName),errbuf,&result))
|
|
||||||
{
|
|
||||||
safe_delete_array(query);
|
|
||||||
return AccountID;
|
|
||||||
}
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < mysql_num_rows(result); i++)
|
query = StringFormat("SELECT `id`, `name`, `level` FROM `character_` "
|
||||||
{
|
"WHERE `account_id` = %i AND `name` != '%s'",
|
||||||
row = mysql_fetch_row(result);
|
accountID, characterName);
|
||||||
c->AddCharacter(atoi(row[0]), row[1], atoi(row[2]));
|
results = QueryDatabase(query);
|
||||||
}
|
if (!results.Success())
|
||||||
mysql_free_result(result);
|
return accountID;
|
||||||
return AccountID;
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
|
client->AddCharacter(atoi(row[0]), row[1], atoi(row[2]));
|
||||||
|
|
||||||
|
return accountID;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::VerifyMailKey(std::string CharacterName, int IPAddress, std::string MailKey) {
|
bool Database::VerifyMailKey(std::string characterName, int IPAddress, std::string MailKey) {
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char* query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
if (!RunQuery(query,MakeAnyLenString(&query, "select `mailkey` from `character_` where `name`='%s' limit 1",
|
|
||||||
CharacterName.c_str()),errbuf,&result)){
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
_log(UCS__ERROR, "Error retrieving mailkey from database: %s", errbuf);
|
|
||||||
|
|
||||||
|
std::string query = StringFormat("SELECT `mailkey` FROM `character_` WHERE `name`='%s' LIMIT 1",
|
||||||
|
characterName.c_str());
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
_log(UCS__ERROR, "Error retrieving mailkey from database: %s", results.ErrorMessage().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete_array(query);
|
auto row = results.begin();
|
||||||
|
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
|
|
||||||
// The key is the client's IP address (expressed as 8 hex digits) and an 8 hex digit random string generated
|
// The key is the client's IP address (expressed as 8 hex digits) and an 8 hex digit random string generated
|
||||||
// by world.
|
// by world.
|
||||||
//
|
//
|
||||||
char CombinedKey[17];
|
char combinedKey[17];
|
||||||
|
|
||||||
if(RuleB(Chat, EnableMailKeyIPVerification) == true)
|
if(RuleB(Chat, EnableMailKeyIPVerification) == true)
|
||||||
sprintf(CombinedKey, "%08X%s", IPAddress, MailKey.c_str());
|
sprintf(combinedKey, "%08X%s", IPAddress, MailKey.c_str());
|
||||||
else
|
else
|
||||||
sprintf(CombinedKey, "%s", MailKey.c_str());
|
sprintf(combinedKey, "%s", MailKey.c_str());
|
||||||
|
|
||||||
_log(UCS__TRACE, "DB key is [%s], Client key is [%s]", row[0], CombinedKey);
|
_log(UCS__TRACE, "DB key is [%s], Client key is [%s]", row[0], combinedKey);
|
||||||
|
|
||||||
bool Valid = !strcmp(row[0], CombinedKey);
|
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
return Valid;
|
|
||||||
|
|
||||||
|
return !strcmp(row[0], combinedKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Database::FindCharacter(const char *CharacterName) {
|
int Database::FindCharacter(const char *characterName) {
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char *safeCharName = RemoveApostrophes(characterName);
|
||||||
char* query = 0;
|
std::string query = StringFormat("SELECT `id` FROM `character_` WHERE `name`='%s' LIMIT 1", safeCharName);
|
||||||
MYSQL_RES *result;
|
auto results = QueryDatabase(query);
|
||||||
MYSQL_ROW row;
|
if (!results.Success()) {
|
||||||
|
_log(UCS__ERROR, "FindCharacter failed. %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
char *SafeCharName = RemoveApostrophes(CharacterName);
|
safe_delete(safeCharName);
|
||||||
|
return -1;
|
||||||
if (!RunQuery(query,MakeAnyLenString(&query, "select `id` from `character_` where `name`='%s' limit 1",
|
}
|
||||||
SafeCharName),errbuf,&result)){
|
safe_delete(safeCharName);
|
||||||
|
|
||||||
_log(UCS__ERROR, "FindCharacter failed. %s %s", query, errbuf);
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
safe_delete_array(SafeCharName);
|
|
||||||
|
|
||||||
|
if (results.RowCount() != 1) {
|
||||||
|
_log(UCS__ERROR, "Bad result from FindCharacter query for character %s", characterName);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete_array(query);
|
auto row = results.begin();
|
||||||
safe_delete_array(SafeCharName);
|
|
||||||
|
|
||||||
if (mysql_num_rows(result) != 1) {
|
int characterID = atoi(row[0]);
|
||||||
|
|
||||||
_log(UCS__ERROR, "Bad result from FindCharacter query for character %s", CharacterName);
|
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
|
|
||||||
int CharacterID = atoi(row[0]);
|
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
return CharacterID;
|
|
||||||
|
|
||||||
|
return characterID;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::GetVariable(const char* varname, char* varvalue, uint16 varvalue_len) {
|
bool Database::GetVariable(const char* varname, char* varvalue, uint16 varvalue_len) {
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
std::string query = StringFormat("SELECT `value` FROM `variables` WHERE `varname` = '%s'", varname);
|
||||||
char* query = 0;
|
auto results = QueryDatabase(query);
|
||||||
MYSQL_RES *result;
|
if (!results.Success()) {
|
||||||
MYSQL_ROW row;
|
_log(UCS__ERROR, "Unable to get message count from database. %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
|
||||||
if (!RunQuery(query,MakeAnyLenString(&query, "select `value` from `variables` where `varname`='%s'", varname), errbuf, &result)) {
|
|
||||||
|
|
||||||
_log(UCS__ERROR, "Unable to get message count from database. %s %s", query, errbuf);
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete_array(query);
|
if (results.RowCount() != 1)
|
||||||
|
|
||||||
if (mysql_num_rows(result) != 1) {
|
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
row = mysql_fetch_row(result);
|
auto row = results.begin();
|
||||||
|
|
||||||
snprintf(varvalue, varvalue_len, "%s", row[0]);
|
snprintf(varvalue, varvalue_len, "%s", row[0]);
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,302 +246,238 @@ bool Database::LoadChatChannels() {
|
|||||||
|
|
||||||
_log(UCS__INIT, "Loading chat channels from the database.");
|
_log(UCS__INIT, "Loading chat channels from the database.");
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
const std::string query = "SELECT `name`, `owner`, `password`, `minstatus` FROM `chatchannels`";
|
||||||
char* query = 0;
|
auto results = QueryDatabase(query);
|
||||||
MYSQL_RES *result;
|
if (!results.Success()) {
|
||||||
MYSQL_ROW row;
|
_log(UCS__ERROR, "Failed to load channels. %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
|
||||||
if (!RunQuery(query,MakeAnyLenString(&query, "select `name`,`owner`,`password`, `minstatus` from `chatchannels`"),errbuf,&result)){
|
|
||||||
|
|
||||||
_log(UCS__ERROR, "Failed to load channels. %s %s", query, errbuf);
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete_array(query);
|
for (auto row = results.begin();row != results.end(); ++row) {
|
||||||
|
std::string channelName = row[0];
|
||||||
|
std::string channelOwner = row[1];
|
||||||
|
std::string channelPassword = row[2];
|
||||||
|
|
||||||
while((row = mysql_fetch_row(result))) {
|
ChannelList->CreateChannel(channelName, channelOwner, channelPassword, true, atoi(row[3]));
|
||||||
|
|
||||||
std::string ChannelName = row[0];
|
|
||||||
std::string ChannelOwner = row[1];
|
|
||||||
std::string ChannelPassword = row[2];
|
|
||||||
|
|
||||||
ChannelList->CreateChannel(ChannelName, ChannelOwner, ChannelPassword, true, atoi(row[3]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetChannelPassword(std::string ChannelName, std::string Password) {
|
void Database::SetChannelPassword(std::string channelName, std::string password) {
|
||||||
|
|
||||||
_log(UCS__TRACE, "Database::SetChannelPassword(%s, %s)", ChannelName.c_str(), Password.c_str());
|
_log(UCS__TRACE, "Database::SetChannelPassword(%s, %s)", channelName.c_str(), password.c_str());
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
std::string query = StringFormat("UPDATE `chatchannels` SET `password` = '%s' WHERE `name` = '%s'",
|
||||||
char *query = 0;
|
password.c_str(), channelName.c_str());
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
if(!results.Success())
|
||||||
|
_log(UCS__ERROR, "Error updating password in database: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, "UPDATE `chatchannels` set `password`='%s' where `name`='%s'", Password.c_str(),
|
|
||||||
ChannelName.c_str()), errbuf)) {
|
|
||||||
|
|
||||||
_log(UCS__ERROR, "Error updating password in database: %s, %s", query, errbuf);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetChannelOwner(std::string ChannelName, std::string Owner) {
|
void Database::SetChannelOwner(std::string channelName, std::string owner) {
|
||||||
|
|
||||||
_log(UCS__TRACE, "Database::SetChannelOwner(%s, %s)", ChannelName.c_str(), Owner.c_str());
|
_log(UCS__TRACE, "Database::SetChannelOwner(%s, %s)", channelName.c_str(), owner.c_str());
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
std::string query = StringFormat("UPDATE `chatchannels` SET `owner` = '%s' WHERE `name` = '%s'",
|
||||||
char *query = 0;
|
owner.c_str(), channelName.c_str());
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
if(!results.Success())
|
||||||
|
_log(UCS__ERROR, "Error updating Owner in database: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, "UPDATE `chatchannels` set `owner`='%s' where `name`='%s'", Owner.c_str(),
|
|
||||||
ChannelName.c_str()), errbuf)) {
|
|
||||||
|
|
||||||
_log(UCS__ERROR, "Error updating Owner in database: %s, %s", query, errbuf);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SendHeaders(Client *c) {
|
void Database::SendHeaders(Client *client) {
|
||||||
|
|
||||||
int UnknownField2 = 25015275;
|
int unknownField2 = 25015275;
|
||||||
int UnknownField3 = 1;
|
int unknownField3 = 1;
|
||||||
|
int characterID = FindCharacter(client->MailBoxName().c_str());
|
||||||
|
|
||||||
int CharacterID = FindCharacter(c->MailBoxName().c_str());
|
_log(UCS__TRACE, "Sendheaders for %s, CharID is %i", client->MailBoxName().c_str(), characterID);
|
||||||
_log(UCS__TRACE, "Sendheaders for %s, CharID is %i", c->MailBoxName().c_str(), CharacterID);
|
|
||||||
if(CharacterID <= 0)
|
if(characterID <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
std::string query = StringFormat("SELECT `msgid`,`timestamp`, `from`, `subject`, `status` "
|
||||||
|
"FROM `mail` WHERE `charid`=%i", characterID);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
|
return;
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char buffer[100];
|
||||||
char* query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
if (!RunQuery(query,MakeAnyLenString(&query, "select `msgid`,`timestamp`,`from`,`subject`, `status` from `mail` "
|
int headerCountPacketLength = 0;
|
||||||
"where `charid`=%i", CharacterID),errbuf,&result)){
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
sprintf(buffer, "%i", client->GetMailBoxNumber());
|
||||||
|
headerCountPacketLength += (strlen(buffer) + 1);
|
||||||
|
|
||||||
return ;
|
sprintf(buffer, "%i", unknownField2);
|
||||||
}
|
headerCountPacketLength += (strlen(buffer) + 1);
|
||||||
|
|
||||||
safe_delete_array(query);
|
sprintf(buffer, "%i", unknownField3);
|
||||||
|
headerCountPacketLength += (strlen(buffer) + 1);
|
||||||
|
|
||||||
char Buf[100];
|
sprintf(buffer, "%i", results.RowCount());
|
||||||
|
headerCountPacketLength += (strlen(buffer) + 1);
|
||||||
|
|
||||||
uint32 NumRows = mysql_num_rows(result);
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MailHeaderCount, headerCountPacketLength);
|
||||||
|
|
||||||
int HeaderCountPacketLength = 0;
|
char *packetBuffer = (char *)outapp->pBuffer;
|
||||||
|
|
||||||
sprintf(Buf, "%i", c->GetMailBoxNumber());
|
VARSTRUCT_ENCODE_INTSTRING(packetBuffer, client->GetMailBoxNumber());
|
||||||
HeaderCountPacketLength += (strlen(Buf) + 1);
|
VARSTRUCT_ENCODE_INTSTRING(packetBuffer, unknownField2);
|
||||||
|
VARSTRUCT_ENCODE_INTSTRING(packetBuffer, unknownField3);
|
||||||
sprintf(Buf, "%i", UnknownField2);
|
VARSTRUCT_ENCODE_INTSTRING(packetBuffer, results.RowCount());
|
||||||
HeaderCountPacketLength += (strlen(Buf) + 1);
|
|
||||||
|
|
||||||
sprintf(Buf, "%i", UnknownField3);
|
|
||||||
HeaderCountPacketLength += (strlen(Buf) + 1);
|
|
||||||
|
|
||||||
sprintf(Buf, "%i", NumRows);
|
|
||||||
HeaderCountPacketLength += (strlen(Buf) + 1);
|
|
||||||
|
|
||||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MailHeaderCount, HeaderCountPacketLength);
|
|
||||||
|
|
||||||
char *PacketBuffer = (char *)outapp->pBuffer;
|
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, c->GetMailBoxNumber());
|
|
||||||
VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, UnknownField2);
|
|
||||||
VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, UnknownField3);
|
|
||||||
VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, NumRows);
|
|
||||||
|
|
||||||
_pkt(UCS__PACKETS, outapp);
|
_pkt(UCS__PACKETS, outapp);
|
||||||
|
|
||||||
c->QueuePacket(outapp);
|
client->QueuePacket(outapp);
|
||||||
|
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
int RowNum = 0;
|
int rowIndex = 0;
|
||||||
|
for(auto row = results.begin(); row != results.end(); ++row, ++rowIndex) {
|
||||||
|
int headerPacketLength = 0;
|
||||||
|
|
||||||
while((row = mysql_fetch_row(result))) {
|
sprintf(buffer, "%i", client->GetMailBoxNumber());
|
||||||
|
headerPacketLength += strlen(buffer) + 1;
|
||||||
|
sprintf(buffer, "%i", unknownField2);
|
||||||
|
headerPacketLength += strlen(buffer) + 1;
|
||||||
|
sprintf(buffer, "%i", rowIndex);
|
||||||
|
headerPacketLength += strlen(buffer) + 1;
|
||||||
|
|
||||||
|
headerPacketLength += strlen(row[0]) + 1;
|
||||||
|
headerPacketLength += strlen(row[1]) + 1;
|
||||||
|
headerPacketLength += strlen(row[4]) + 1;
|
||||||
|
headerPacketLength += GetMailPrefix().length() + strlen(row[2]) + 1;
|
||||||
|
headerPacketLength += strlen(row[3]) + 1;
|
||||||
|
|
||||||
int HeaderPacketLength = 0;
|
outapp = new EQApplicationPacket(OP_MailHeader, headerPacketLength);
|
||||||
|
|
||||||
sprintf(Buf, "%i", c->GetMailBoxNumber());
|
packetBuffer = (char *)outapp->pBuffer;
|
||||||
HeaderPacketLength = HeaderPacketLength + strlen(Buf) + 1;
|
|
||||||
sprintf(Buf, "%i", UnknownField2);
|
|
||||||
HeaderPacketLength = HeaderPacketLength + strlen(Buf) + 1;
|
|
||||||
sprintf(Buf, "%i", RowNum);
|
|
||||||
HeaderPacketLength = HeaderPacketLength + strlen(Buf) + 1;
|
|
||||||
|
|
||||||
HeaderPacketLength = HeaderPacketLength + strlen(row[0]) + 1;
|
VARSTRUCT_ENCODE_INTSTRING(packetBuffer, client->GetMailBoxNumber());
|
||||||
HeaderPacketLength = HeaderPacketLength + strlen(row[1]) + 1;
|
VARSTRUCT_ENCODE_INTSTRING(packetBuffer, unknownField2);
|
||||||
HeaderPacketLength = HeaderPacketLength + strlen(row[4]) + 1;
|
VARSTRUCT_ENCODE_INTSTRING(packetBuffer, rowIndex);
|
||||||
HeaderPacketLength = HeaderPacketLength + GetMailPrefix().length() + strlen(row[2]) + 1;
|
VARSTRUCT_ENCODE_STRING(packetBuffer, row[0]);
|
||||||
HeaderPacketLength = HeaderPacketLength + strlen(row[3]) + 1;
|
VARSTRUCT_ENCODE_STRING(packetBuffer, row[1]);
|
||||||
|
VARSTRUCT_ENCODE_STRING(packetBuffer, row[4]);
|
||||||
outapp = new EQApplicationPacket(OP_MailHeader, HeaderPacketLength);
|
VARSTRUCT_ENCODE_STRING(packetBuffer, GetMailPrefix().c_str());
|
||||||
|
packetBuffer--;
|
||||||
PacketBuffer = (char *)outapp->pBuffer;
|
VARSTRUCT_ENCODE_STRING(packetBuffer, row[2]);
|
||||||
|
VARSTRUCT_ENCODE_STRING(packetBuffer, row[3]);
|
||||||
VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, c->GetMailBoxNumber());
|
|
||||||
VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, UnknownField2);
|
|
||||||
VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, RowNum);
|
|
||||||
VARSTRUCT_ENCODE_STRING(PacketBuffer, row[0]);
|
|
||||||
VARSTRUCT_ENCODE_STRING(PacketBuffer, row[1]);
|
|
||||||
VARSTRUCT_ENCODE_STRING(PacketBuffer, row[4]);
|
|
||||||
VARSTRUCT_ENCODE_STRING(PacketBuffer, GetMailPrefix().c_str()); PacketBuffer--;
|
|
||||||
VARSTRUCT_ENCODE_STRING(PacketBuffer, row[2]);
|
|
||||||
VARSTRUCT_ENCODE_STRING(PacketBuffer, row[3]);
|
|
||||||
|
|
||||||
_pkt(UCS__PACKETS, outapp);
|
_pkt(UCS__PACKETS, outapp);
|
||||||
|
|
||||||
c->QueuePacket(outapp);
|
client->QueuePacket(outapp);
|
||||||
|
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
RowNum++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SendBody(Client *c, int MessageNumber) {
|
void Database::SendBody(Client *client, int messageNumber) {
|
||||||
|
|
||||||
int CharacterID = FindCharacter(c->MailBoxName().c_str());
|
int characterID = FindCharacter(client->MailBoxName().c_str());
|
||||||
|
|
||||||
_log(UCS__TRACE, "SendBody: MsgID %i, to %s, CharID is %i", MessageNumber, c->MailBoxName().c_str(), CharacterID);
|
_log(UCS__TRACE, "SendBody: MsgID %i, to %s, CharID is %i", messageNumber, client->MailBoxName().c_str(), characterID);
|
||||||
|
|
||||||
if(CharacterID <= 0)
|
if(characterID <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
std::string query = StringFormat("SELECT `msgid`, `body`, `to` FROM `mail` "
|
||||||
char* query = 0;
|
"WHERE `charid`=%i AND `msgid`=%i", characterID, messageNumber);
|
||||||
MYSQL_RES *result;
|
auto results = QueryDatabase(query);
|
||||||
MYSQL_ROW row;
|
if (!results.Success())
|
||||||
|
|
||||||
if (!RunQuery(query,MakeAnyLenString(&query, "select `msgid`, `body`, `to` from `mail` "
|
|
||||||
"where `charid`=%i and `msgid`=%i", CharacterID, MessageNumber), errbuf, &result)){
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
if (mysql_num_rows(result) != 1) {
|
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
|
|
||||||
_log(UCS__TRACE, "Message: %i body (%i bytes)", MessageNumber, strlen(row[1]));
|
if (results.RowCount() != 1)
|
||||||
|
return;
|
||||||
|
|
||||||
int PacketLength = 12 + strlen(row[0]) + strlen(row[1]) + strlen(row[2]);
|
auto row = results.begin();
|
||||||
|
|
||||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MailSendBody,PacketLength);
|
_log(UCS__TRACE, "Message: %i body (%i bytes)", messageNumber, strlen(row[1]));
|
||||||
|
|
||||||
char *PacketBuffer = (char *)outapp->pBuffer;
|
int packetLength = 12 + strlen(row[0]) + strlen(row[1]) + strlen(row[2]);
|
||||||
|
|
||||||
VARSTRUCT_ENCODE_INTSTRING(PacketBuffer, c->GetMailBoxNumber());
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_MailSendBody,packetLength);
|
||||||
VARSTRUCT_ENCODE_STRING(PacketBuffer,row[0]);
|
|
||||||
VARSTRUCT_ENCODE_STRING(PacketBuffer,row[1]);
|
|
||||||
VARSTRUCT_ENCODE_STRING(PacketBuffer,"1");
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, PacketBuffer, 0);
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, PacketBuffer, 0x0a);
|
|
||||||
VARSTRUCT_ENCODE_STRING(PacketBuffer, "TO:"); PacketBuffer--;
|
|
||||||
VARSTRUCT_ENCODE_STRING(PacketBuffer, row[2]); PacketBuffer--; // Overwrite the null terminator
|
|
||||||
VARSTRUCT_ENCODE_TYPE(uint8, PacketBuffer, 0x0a);
|
|
||||||
|
|
||||||
mysql_free_result(result);
|
char *packetBuffer = (char *)outapp->pBuffer;
|
||||||
|
|
||||||
|
VARSTRUCT_ENCODE_INTSTRING(packetBuffer, client->GetMailBoxNumber());
|
||||||
|
VARSTRUCT_ENCODE_STRING(packetBuffer,row[0]);
|
||||||
|
VARSTRUCT_ENCODE_STRING(packetBuffer,row[1]);
|
||||||
|
VARSTRUCT_ENCODE_STRING(packetBuffer,"1");
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, packetBuffer, 0);
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, packetBuffer, 0x0a);
|
||||||
|
VARSTRUCT_ENCODE_STRING(packetBuffer, "TO:");
|
||||||
|
packetBuffer--;
|
||||||
|
VARSTRUCT_ENCODE_STRING(packetBuffer, row[2]);
|
||||||
|
packetBuffer--; // Overwrite the null terminator
|
||||||
|
VARSTRUCT_ENCODE_TYPE(uint8, packetBuffer, 0x0a);
|
||||||
|
|
||||||
_pkt(UCS__PACKETS, outapp);
|
_pkt(UCS__PACKETS, outapp);
|
||||||
|
|
||||||
c->QueuePacket(outapp);
|
client->QueuePacket(outapp);
|
||||||
|
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::SendMail(std::string Recipient, std::string From, std::string Subject, std::string Body, std::string RecipientsString) {
|
bool Database::SendMail(std::string recipient, std::string from, std::string subject, std::string body, std::string recipientsString) {
|
||||||
|
|
||||||
int CharacterID;
|
int characterID;
|
||||||
|
std::string characterName;
|
||||||
|
|
||||||
std::string CharacterName;
|
auto lastPeriod = recipient.find_last_of(".");
|
||||||
|
|
||||||
//printf("Database::SendMail(%s, %s, %s)\n", Recipient.c_str(), From.c_str(), Subject.c_str());
|
if(lastPeriod == std::string::npos)
|
||||||
|
characterName = recipient;
|
||||||
std::string::size_type LastPeriod = Recipient.find_last_of(".");
|
|
||||||
|
|
||||||
if(LastPeriod == std::string::npos)
|
|
||||||
CharacterName = Recipient;
|
|
||||||
else
|
else
|
||||||
CharacterName = Recipient.substr(LastPeriod+1);
|
characterName = recipient.substr(lastPeriod+1);
|
||||||
|
|
||||||
CharacterName[0] = toupper(CharacterName[0]);
|
characterName[0] = toupper(characterName[0]);
|
||||||
|
|
||||||
for(unsigned int i = 1; i < CharacterName.length(); i++)
|
for(unsigned int i = 1; i < characterName.length(); i++)
|
||||||
CharacterName[i] = tolower(CharacterName[i]);
|
characterName[i] = tolower(characterName[i]);
|
||||||
|
|
||||||
CharacterID = FindCharacter(CharacterName.c_str());
|
characterID = FindCharacter(characterName.c_str());
|
||||||
|
|
||||||
_log(UCS__TRACE, "SendMail: CharacterID for recipient %s is %i", CharacterName.c_str(), CharacterID);
|
_log(UCS__TRACE, "SendMail: CharacterID for recipient %s is %i", characterName.c_str(), characterID);
|
||||||
|
|
||||||
if(CharacterID <= 0) return false;
|
if(characterID <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char *escSubject = new char[subject.length() * 2 + 1];
|
||||||
char* query = 0;
|
char *escBody = new char[body.length() * 2 + 1];
|
||||||
|
|
||||||
char *EscSubject = new char[Subject.length() * 2 + 1];
|
DoEscapeString(escSubject, subject.c_str(), subject.length());
|
||||||
char *EscBody = new char[Body.length() * 2 + 1];
|
DoEscapeString(escBody, body.c_str(), body.length());
|
||||||
|
|
||||||
DoEscapeString(EscSubject, Subject.c_str(), Subject.length());
|
int now = time(nullptr); // time returns a 64 bit int on Windows at least, which vsnprintf doesn't like.
|
||||||
DoEscapeString(EscBody, Body.c_str(), Body.length());
|
|
||||||
|
|
||||||
const char *MailQuery="INSERT INTO `mail` (`charid`, `timestamp`, `from`, `subject`, `body`, `to`, `status`) "
|
|
||||||
"VALUES ('%i', %i, '%s', '%s', '%s', '%s', %i)";
|
|
||||||
|
|
||||||
uint32 LastMsgID;
|
|
||||||
|
|
||||||
int Now = time(nullptr); // time returns a 64 bit int on Windows at least, which vsnprintf doesn't like.
|
|
||||||
|
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, MailQuery, CharacterID, Now, From.c_str(), EscSubject, EscBody,
|
|
||||||
RecipientsString.c_str(), 1), errbuf, 0, 0, &LastMsgID)) {
|
|
||||||
|
|
||||||
_log(UCS__ERROR, "SendMail: Query %s failed with error %s", query, errbuf);
|
|
||||||
|
|
||||||
safe_delete_array(EscSubject);
|
|
||||||
safe_delete_array(EscBody);
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
|
std::string query = StringFormat("INSERT INTO `mail` "
|
||||||
|
"(`charid`, `timestamp`, `from`, `subject`, `body`, `to`, `status`) "
|
||||||
|
"VALUES ('%i', %i, '%s', '%s', '%s', '%s', %i)",
|
||||||
|
characterID, now, from.c_str(), escSubject, escBody,
|
||||||
|
recipientsString.c_str(), 1);
|
||||||
|
safe_delete_array(escSubject);
|
||||||
|
safe_delete_array(escBody);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
if(!results.Success()) {
|
||||||
|
_log(UCS__ERROR, "SendMail: Query %s failed with error %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_log(UCS__TRACE, "MessageID %i generated, from %s, to %s", LastMsgID, From.c_str(), Recipient.c_str());
|
_log(UCS__TRACE, "MessageID %i generated, from %s, to %s", results.LastInsertedID(), from.c_str(), recipient.c_str());
|
||||||
|
|
||||||
safe_delete_array(EscSubject);
|
|
||||||
safe_delete_array(EscBody);
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
Client *c = CL->IsCharacterOnline(CharacterName);
|
Client *client = CL->IsCharacterOnline(characterName);
|
||||||
|
|
||||||
if(c) {
|
if(client) {
|
||||||
std::string FQN = GetMailPrefix() + From;
|
std::string FQN = GetMailPrefix() + from;
|
||||||
|
client->SendNotification(client->GetMailBoxNumber(characterName), subject, FQN, results.LastInsertedID());
|
||||||
c->SendNotification(c->GetMailBoxNumber(CharacterName), Subject, FQN, LastMsgID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MailMessagesSent++;
|
MailMessagesSent++;
|
||||||
@ -614,156 +485,122 @@ bool Database::SendMail(std::string Recipient, std::string From, std::string Sub
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::SetMessageStatus(int MessageNumber, int Status) {
|
void Database::SetMessageStatus(int messageNumber, int status) {
|
||||||
|
|
||||||
_log(UCS__TRACE, "SetMessageStatus %i %i", MessageNumber, Status);
|
_log(UCS__TRACE, "SetMessageStatus %i %i", messageNumber, status);
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
if(status == 0) {
|
||||||
char *query = 0;
|
std::string query = StringFormat("DELETE FROM `mail` WHERE `msgid` = %i", messageNumber);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(Status == 0)
|
std::string query = StringFormat("UPDATE `mail` SET `status` = %i WHERE `msgid`=%i", status, messageNumber);
|
||||||
RunQuery(query, MakeAnyLenString(&query, "delete from `mail` where `msgid`=%i", MessageNumber), errbuf);
|
auto results = QueryDatabase(query);
|
||||||
else if (!RunQuery(query, MakeAnyLenString(&query, "update `mail` set `status`=%i where `msgid`=%i", Status, MessageNumber), errbuf)) {
|
if (!results.Success())
|
||||||
|
_log(UCS__ERROR, "Error updating status %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
|
||||||
_log(UCS__ERROR, "Error updating status %s, %s", query, errbuf);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::ExpireMail() {
|
void Database::ExpireMail() {
|
||||||
|
|
||||||
_log(UCS__INIT, "Expiring mail...");
|
_log(UCS__INIT, "Expiring mail...");
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
std::string query = "SELECT COUNT(*) FROM `mail`";
|
||||||
char* query = 0;
|
auto results = QueryDatabase(query);
|
||||||
MYSQL_RES *result;
|
if (!results.Success()) {
|
||||||
MYSQL_ROW row;
|
_log(UCS__ERROR, "Unable to get message count from database. %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
return;
|
||||||
uint32 AffectedRows;
|
|
||||||
|
|
||||||
if (!RunQuery(query,MakeAnyLenString(&query, "select COUNT(*) from `mail` "),errbuf,&result)){
|
|
||||||
_log(UCS__ERROR, "Unable to get message count from database. %s %s", query, errbuf);
|
|
||||||
safe_delete_array(query);
|
|
||||||
return ;
|
|
||||||
}
|
}
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
row = mysql_fetch_row(result);
|
auto row = results.begin();
|
||||||
|
|
||||||
_log(UCS__INIT, "There are %s messages in the database.", row[0]);
|
_log(UCS__INIT, "There are %s messages in the database.", row[0]);
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
// Expire Trash
|
// Expire Trash
|
||||||
if(RuleI(Mail, ExpireTrash) >= 0) {
|
if(RuleI(Mail, ExpireTrash) >= 0) {
|
||||||
if(RunQuery(query, MakeAnyLenString(&query, "delete from `mail` where `status`=4 and `timestamp` < %i",
|
query = StringFormat("DELETE FROM `mail` WHERE `status`=4 AND `timestamp` < %i",
|
||||||
time(nullptr) - RuleI(Mail, ExpireTrash)), errbuf, 0, &AffectedRows)) {
|
time(nullptr) - RuleI(Mail, ExpireTrash));
|
||||||
_log(UCS__INIT, "Expired %i trash messages.", AffectedRows);
|
results = QueryDatabase(query);
|
||||||
}
|
if(!results.Success())
|
||||||
else {
|
_log(UCS__ERROR, "Error expiring trash messages, %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
_log(UCS__ERROR, "Error expiring trash messages, %s %s", query, errbuf);
|
else
|
||||||
}
|
_log(UCS__INIT, "Expired %i trash messages.", results.RowsAffected());
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expire Read
|
// Expire Read
|
||||||
if(RuleI(Mail, ExpireRead) >= 0) {
|
if(RuleI(Mail, ExpireRead) >= 0) {
|
||||||
if(RunQuery(query, MakeAnyLenString(&query, "delete from `mail` where `status`=3 and `timestamp` < %i",
|
query = StringFormat("DELETE FROM `mail` WHERE `status` = 3 AND `timestamp` < %i",
|
||||||
time(nullptr) - RuleI(Mail, ExpireRead)), errbuf, 0, &AffectedRows)) {
|
time(nullptr) - RuleI(Mail, ExpireRead));
|
||||||
_log(UCS__INIT, "Expired %i read messages.", AffectedRows);
|
results = QueryDatabase(query);
|
||||||
}
|
if(!results.Success())
|
||||||
else {
|
_log(UCS__INIT, "Expired %i read messages.", results.RowsAffected());
|
||||||
_log(UCS__ERROR, "Error expiring read messages, %s %s", query, errbuf);
|
else
|
||||||
}
|
_log(UCS__ERROR, "Error expiring read messages, %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expire Unread
|
// Expire Unread
|
||||||
if(RuleI(Mail, ExpireUnread) >= 0) {
|
if(RuleI(Mail, ExpireUnread) >= 0) {
|
||||||
if(RunQuery(query, MakeAnyLenString(&query, "delete from `mail` where `status`=1 and `timestamp` < %i",
|
query = StringFormat("DELETE FROM `mail` WHERE `status`=1 AND `timestamp` < %i",
|
||||||
time(nullptr) - RuleI(Mail, ExpireUnread)), errbuf, 0, &AffectedRows)) {
|
time(nullptr) - RuleI(Mail, ExpireUnread));
|
||||||
_log(UCS__INIT, "Expired %i unread messages.", AffectedRows);
|
results = QueryDatabase(query);
|
||||||
}
|
if(!results.Success())
|
||||||
else {
|
_log(UCS__INIT, "Expired %i unread messages.", results.RowsAffected());
|
||||||
_log(UCS__ERROR, "Error expiring unread messages, %s %s", query, errbuf);
|
else
|
||||||
}
|
_log(UCS__ERROR, "Error expiring unread messages, %s %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::AddFriendOrIgnore(int CharID, int Type, std::string Name) {
|
void Database::AddFriendOrIgnore(int charID, int type, std::string name) {
|
||||||
|
|
||||||
const char *FriendsQuery="INSERT INTO `friends` (`charid`, `type`, `name`) VALUES ('%i', %i, '%s')";
|
std::string query = StringFormat("INSERT INTO `friends` (`charid`, `type`, `name`) "
|
||||||
|
"VALUES('%i', %i, '%s')",
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
charID, type, CapitaliseName(name).c_str());
|
||||||
char* query = 0;
|
auto results = QueryDatabase(query);
|
||||||
|
if(!results.Success())
|
||||||
|
_log(UCS__ERROR, "Error adding friend/ignore, query was %s : %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, FriendsQuery, CharID, Type, CapitaliseName(Name).c_str()), errbuf, 0, 0))
|
|
||||||
_log(UCS__ERROR, "Error adding friend/ignore, query was %s : %s", query, errbuf);
|
|
||||||
else
|
else
|
||||||
_log(UCS__TRACE, "Wrote Friend/Ignore entry for charid %i, type %i, name %s to database.",
|
_log(UCS__TRACE, "Wrote Friend/Ignore entry for charid %i, type %i, name %s to database.", charID, type, name.c_str());
|
||||||
CharID, Type, Name.c_str());
|
|
||||||
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::RemoveFriendOrIgnore(int CharID, int Type, std::string Name) {
|
void Database::RemoveFriendOrIgnore(int charID, int type, std::string name) {
|
||||||
|
|
||||||
const char *FriendsQuery="DELETE FROM `friends` WHERE `charid`=%i AND `type`=%i and `name`='%s'";
|
std::string query = StringFormat("DELETE FROM `friends` WHERE `charid` = %i "
|
||||||
|
"AND `type` = %i AND `name` = '%s'",
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
charID, type, CapitaliseName(name).c_str());
|
||||||
char* query = 0;
|
auto results = QueryDatabase(query);
|
||||||
|
if(!results.Success())
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, FriendsQuery, CharID, Type, CapitaliseName(Name).c_str()), errbuf, 0, 0))
|
_log(UCS__ERROR, "Error removing friend/ignore, query was %s", query.c_str());
|
||||||
_log(UCS__ERROR, "Error removing friend/ignore, query was %s", query);
|
|
||||||
else
|
else
|
||||||
_log(UCS__TRACE, "Removed Friend/Ignore entry for charid %i, type %i, name %s from database.",
|
_log(UCS__TRACE, "Removed Friend/Ignore entry for charid %i, type %i, name %s from database.", charID, type, name.c_str());
|
||||||
CharID, Type, Name.c_str());
|
|
||||||
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::GetFriendsAndIgnore(int CharID, std::vector<std::string> &Friends, std::vector<std::string> &Ignorees) {
|
void Database::GetFriendsAndIgnore(int charID, std::vector<std::string> &friends, std::vector<std::string> &ignorees) {
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
std::string query = StringFormat("select `type`, `name` FROM `friends` WHERE `charid`=%i", charID);
|
||||||
char* query = 0;
|
auto results = QueryDatabase(query);
|
||||||
MYSQL_RES *result;
|
if (!results.Success()) {
|
||||||
MYSQL_ROW row;
|
_log(UCS__ERROR, "GetFriendsAndIgnore query error %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
return;
|
||||||
const char *FriendsQuery="select `type`, `name` from `friends` WHERE `charid`=%i";
|
|
||||||
|
|
||||||
if (!RunQuery(query,MakeAnyLenString(&query, FriendsQuery, CharID),errbuf,&result)){
|
|
||||||
|
|
||||||
_log(UCS__ERROR, "GetFriendsAndIgnore query error %s, %s", query, errbuf);
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
return ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
while((row = mysql_fetch_row(result))) {
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
std::string name = row[1];
|
||||||
std::string Name = row[1];
|
|
||||||
|
|
||||||
if(atoi(row[0]) == 0)
|
if(atoi(row[0]) == 0)
|
||||||
{
|
{
|
||||||
Ignorees.push_back(Name);
|
ignorees.push_back(name);
|
||||||
_log(UCS__TRACE, "Added Ignoree from DB %s", Name.c_str());
|
_log(UCS__TRACE, "Added Ignoree from DB %s", name.c_str());
|
||||||
}
|
continue;
|
||||||
else
|
|
||||||
{
|
|
||||||
Friends.push_back(Name);
|
|
||||||
_log(UCS__TRACE, "Added Friend from DB %s", Name.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friends.push_back(name);
|
||||||
|
_log(UCS__TRACE, "Added Friend from DB %s", name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_events
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_events`;
|
||||||
|
CREATE TABLE `qs_player_events` (
|
||||||
|
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`char_id` int(11) DEFAULT '0',
|
||||||
|
`event` int(11) unsigned DEFAULT '0',
|
||||||
|
`event_desc` varchar(255) DEFAULT NULL,
|
||||||
|
`time` int(11) unsigned DEFAULT '0',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_aa_rate_hourly
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_aa_rate_hourly`;
|
||||||
|
CREATE TABLE `qs_player_aa_rate_hourly` (
|
||||||
|
`char_id` int(11) NOT NULL DEFAULT '0',
|
||||||
|
`hour_time` int(11) NOT NULL,
|
||||||
|
`aa_count` varchar(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`char_id`,`hour_time`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
-- Disable Player Logging for All --
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogPCCoordinates', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogNPCKills', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogTrades', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogMerchantTransactions', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogDeletes', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogHandins', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogMoves', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogChat', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogKeyringAddition', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogAAPurchases', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogIssuedCommandes', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogMoneyTransactions', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogAlternateCurrencyTransactions', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogTradeSkillEvents', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogPCCoordinates', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogDropItem', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogMerchantTransactions', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogDeletes', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogHandins', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogMoves', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogNPCKills', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogTrades', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogQGlobalUpdate', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogTaskUpdates', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogDeaths', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogZone', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogConnectDisconnect', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogLevels', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogAARate', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogChat', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogDropItem', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogZone', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogDeaths', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogLevels', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogEXPRate', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogAARate', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogQGlobalUpdate', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogTaskUpdates', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogKeyringAddition', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogAAPurchases', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogTradeSkillEvents', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogIssuedCommandes', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogMoneyTransactions', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogAlternateCurrencyTransactions', 'false', '');
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
-- Enable Player Logging for All --
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogPCCoordinates', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogNPCKills', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogTrades', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogMerchantTransactions', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogDeletes', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogHandins', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogMoves', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogChat', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogKeyringAddition', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogAAPurchases', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogIssuedCommandes', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogMoneyTransactions', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogAlternateCurrencyTransactions', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogTradeSkillEvents', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogPCCoordinates', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogDropItem', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogMerchantTransactions', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogDeletes', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogHandins', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogMoves', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogNPCKills', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogTrades', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogQGlobalUpdate', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogTaskUpdates', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogDeaths', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogZone', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogConnectDisconnect', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogLevels', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogAARate', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogChat', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogDropItem', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogZone', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogDeaths', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogLevels', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogEXPRate', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogAARate', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogQGlobalUpdate', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogTaskUpdates', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogKeyringAddition', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogAAPurchases', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogTradeSkillEvents', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogIssuedCommandes', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogMoneyTransactions', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogAlternateCurrencyTransactions', 'true', '');
|
||||||
@ -0,0 +1,247 @@
|
|||||||
|
-- QS Table Structures --
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS=0;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_merchant_transaction_record
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_merchant_transaction_record`;
|
||||||
|
CREATE TABLE `qs_merchant_transaction_record` (
|
||||||
|
`transaction_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`zone_id` int(11) DEFAULT '0',
|
||||||
|
`merchant_id` int(11) DEFAULT '0',
|
||||||
|
`merchant_pp` int(11) DEFAULT '0',
|
||||||
|
`merchant_gp` int(11) DEFAULT '0',
|
||||||
|
`merchant_sp` int(11) DEFAULT '0',
|
||||||
|
`merchant_cp` int(11) DEFAULT '0',
|
||||||
|
`merchant_items` mediumint(7) DEFAULT '0',
|
||||||
|
`char_id` int(11) DEFAULT '0',
|
||||||
|
`char_pp` int(11) DEFAULT '0',
|
||||||
|
`char_gp` int(11) DEFAULT '0',
|
||||||
|
`char_sp` int(11) DEFAULT '0',
|
||||||
|
`char_cp` int(11) DEFAULT '0',
|
||||||
|
`char_items` mediumint(7) DEFAULT '0',
|
||||||
|
PRIMARY KEY (`transaction_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_merchant_transaction_record_entries
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_merchant_transaction_record_entries`;
|
||||||
|
CREATE TABLE `qs_merchant_transaction_record_entries` (
|
||||||
|
`event_id` int(11) DEFAULT '0',
|
||||||
|
`char_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`item_id` int(11) DEFAULT '0',
|
||||||
|
`charges` mediumint(7) DEFAULT '0',
|
||||||
|
`aug_1` int(11) DEFAULT '0',
|
||||||
|
`aug_2` int(11) DEFAULT '0',
|
||||||
|
`aug_3` int(11) DEFAULT '0',
|
||||||
|
`aug_4` int(11) DEFAULT '0',
|
||||||
|
`aug_5` int(11) DEFAULT '0'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_aa_rate_hourly
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_aa_rate_hourly`;
|
||||||
|
CREATE TABLE `qs_player_aa_rate_hourly` (
|
||||||
|
`char_id` int(11) NOT NULL DEFAULT '0',
|
||||||
|
`hour_time` int(11) NOT NULL,
|
||||||
|
`aa_count` varchar(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`char_id`,`hour_time`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_delete_record
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_delete_record`;
|
||||||
|
CREATE TABLE `qs_player_delete_record` (
|
||||||
|
`delete_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`char_id` int(11) DEFAULT '0',
|
||||||
|
`stack_size` mediumint(7) DEFAULT '0',
|
||||||
|
`char_items` mediumint(7) DEFAULT '0',
|
||||||
|
PRIMARY KEY (`delete_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_delete_record_entries
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_delete_record_entries`;
|
||||||
|
CREATE TABLE `qs_player_delete_record_entries` (
|
||||||
|
`event_id` int(11) DEFAULT '0',
|
||||||
|
`char_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`item_id` int(11) DEFAULT '0',
|
||||||
|
`charges` mediumint(7) DEFAULT '0',
|
||||||
|
`aug_1` int(11) DEFAULT '0',
|
||||||
|
`aug_2` int(11) DEFAULT '0',
|
||||||
|
`aug_3` int(11) DEFAULT '0',
|
||||||
|
`aug_4` int(11) DEFAULT '0',
|
||||||
|
`aug_5` int(11) DEFAULT '0'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_events
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_events`;
|
||||||
|
CREATE TABLE `qs_player_events` (
|
||||||
|
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`char_id` int(11) DEFAULT '0',
|
||||||
|
`event` int(11) unsigned DEFAULT '0',
|
||||||
|
`event_desc` varchar(255) DEFAULT NULL,
|
||||||
|
`time` int(11) unsigned DEFAULT '0',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_handin_record
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_handin_record`;
|
||||||
|
CREATE TABLE `qs_player_handin_record` (
|
||||||
|
`handin_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`quest_id` int(11) DEFAULT '0',
|
||||||
|
`char_id` int(11) DEFAULT '0',
|
||||||
|
`char_pp` int(11) DEFAULT '0',
|
||||||
|
`char_gp` int(11) DEFAULT '0',
|
||||||
|
`char_sp` int(11) DEFAULT '0',
|
||||||
|
`char_cp` int(11) DEFAULT '0',
|
||||||
|
`char_items` mediumint(7) DEFAULT '0',
|
||||||
|
`npc_id` int(11) DEFAULT '0',
|
||||||
|
`npc_pp` int(11) DEFAULT '0',
|
||||||
|
`npc_gp` int(11) DEFAULT '0',
|
||||||
|
`npc_sp` int(11) DEFAULT '0',
|
||||||
|
`npc_cp` int(11) DEFAULT '0',
|
||||||
|
`npc_items` mediumint(7) DEFAULT '0',
|
||||||
|
PRIMARY KEY (`handin_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_handin_record_entries
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_handin_record_entries`;
|
||||||
|
CREATE TABLE `qs_player_handin_record_entries` (
|
||||||
|
`event_id` int(11) DEFAULT '0',
|
||||||
|
`action_type` char(6) DEFAULT 'action',
|
||||||
|
`char_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`item_id` int(11) DEFAULT '0',
|
||||||
|
`charges` mediumint(7) DEFAULT '0',
|
||||||
|
`aug_1` int(11) DEFAULT '0',
|
||||||
|
`aug_2` int(11) DEFAULT '0',
|
||||||
|
`aug_3` int(11) DEFAULT '0',
|
||||||
|
`aug_4` int(11) DEFAULT '0',
|
||||||
|
`aug_5` int(11) DEFAULT '0'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_move_record
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_move_record`;
|
||||||
|
CREATE TABLE `qs_player_move_record` (
|
||||||
|
`move_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`char_id` int(11) DEFAULT '0',
|
||||||
|
`from_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`to_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`stack_size` mediumint(7) DEFAULT '0',
|
||||||
|
`char_items` mediumint(7) DEFAULT '0',
|
||||||
|
`postaction` tinyint(1) DEFAULT '0',
|
||||||
|
PRIMARY KEY (`move_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_move_record_entries
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_move_record_entries`;
|
||||||
|
CREATE TABLE `qs_player_move_record_entries` (
|
||||||
|
`event_id` int(11) DEFAULT '0',
|
||||||
|
`from_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`to_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`item_id` int(11) DEFAULT '0',
|
||||||
|
`charges` mediumint(7) DEFAULT '0',
|
||||||
|
`aug_1` int(11) DEFAULT '0',
|
||||||
|
`aug_2` int(11) DEFAULT '0',
|
||||||
|
`aug_3` int(11) DEFAULT '0',
|
||||||
|
`aug_4` int(11) DEFAULT '0',
|
||||||
|
`aug_5` int(11) DEFAULT '0'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_npc_kill_record
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_npc_kill_record`;
|
||||||
|
CREATE TABLE `qs_player_npc_kill_record` (
|
||||||
|
`fight_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`npc_id` int(11) DEFAULT NULL,
|
||||||
|
`type` int(11) DEFAULT NULL,
|
||||||
|
`zone_id` int(11) DEFAULT NULL,
|
||||||
|
`time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY (`fight_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_npc_kill_record_entries
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_npc_kill_record_entries`;
|
||||||
|
CREATE TABLE `qs_player_npc_kill_record_entries` (
|
||||||
|
`event_id` int(11) DEFAULT '0',
|
||||||
|
`char_id` int(11) DEFAULT '0'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_speech
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_speech`;
|
||||||
|
CREATE TABLE `qs_player_speech` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`from` varchar(64) NOT NULL,
|
||||||
|
`to` varchar(64) NOT NULL,
|
||||||
|
`message` varchar(256) NOT NULL,
|
||||||
|
`minstatus` smallint(5) NOT NULL,
|
||||||
|
`guilddbid` int(11) NOT NULL,
|
||||||
|
`type` tinyint(3) NOT NULL,
|
||||||
|
`timerecorded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_trade_record
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_trade_record`;
|
||||||
|
CREATE TABLE `qs_player_trade_record` (
|
||||||
|
`trade_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`char1_id` int(11) DEFAULT '0',
|
||||||
|
`char1_pp` int(11) DEFAULT '0',
|
||||||
|
`char1_gp` int(11) DEFAULT '0',
|
||||||
|
`char1_sp` int(11) DEFAULT '0',
|
||||||
|
`char1_cp` int(11) DEFAULT '0',
|
||||||
|
`char1_items` mediumint(7) DEFAULT '0',
|
||||||
|
`char2_id` int(11) DEFAULT '0',
|
||||||
|
`char2_pp` int(11) DEFAULT '0',
|
||||||
|
`char2_gp` int(11) DEFAULT '0',
|
||||||
|
`char2_sp` int(11) DEFAULT '0',
|
||||||
|
`char2_cp` int(11) DEFAULT '0',
|
||||||
|
`char2_items` mediumint(7) DEFAULT '0',
|
||||||
|
PRIMARY KEY (`trade_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_trade_record_entries
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_trade_record_entries`;
|
||||||
|
CREATE TABLE `qs_player_trade_record_entries` (
|
||||||
|
`event_id` int(11) DEFAULT '0',
|
||||||
|
`from_id` int(11) DEFAULT '0',
|
||||||
|
`from_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`to_id` int(11) DEFAULT '0',
|
||||||
|
`to_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`item_id` int(11) DEFAULT '0',
|
||||||
|
`charges` mediumint(7) DEFAULT '0',
|
||||||
|
`aug_1` int(11) DEFAULT '0',
|
||||||
|
`aug_2` int(11) DEFAULT '0',
|
||||||
|
`aug_3` int(11) DEFAULT '0',
|
||||||
|
`aug_4` int(11) DEFAULT '0',
|
||||||
|
`aug_5` int(11) DEFAULT '0'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
33
utils/sql/git/required/2014_08_24_character_lookup.sql
Normal file
33
utils/sql/git/required/2014_08_24_character_lookup.sql
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
-- chracter_lookup table structure --
|
||||||
|
|
||||||
|
CREATE TABLE `character_lookup` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`account_id` int(11) NOT NULL DEFAULT '0',
|
||||||
|
`name` varchar(64) NOT NULL DEFAULT '',
|
||||||
|
`timelaston` int(11) unsigned DEFAULT '0',
|
||||||
|
`x` float NOT NULL DEFAULT '0',
|
||||||
|
`y` float NOT NULL DEFAULT '0',
|
||||||
|
`z` float NOT NULL DEFAULT '0',
|
||||||
|
`zonename` varchar(30) NOT NULL DEFAULT '',
|
||||||
|
`zoneid` smallint(6) NOT NULL DEFAULT '0',
|
||||||
|
`instanceid` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`pktime` int(8) NOT NULL DEFAULT '0',
|
||||||
|
`groupid` int(10) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`class` tinyint(4) NOT NULL DEFAULT '0',
|
||||||
|
`level` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`lfp` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`lfg` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`mailkey` char(16) NOT NULL,
|
||||||
|
`xtargets` tinyint(3) unsigned NOT NULL DEFAULT '5',
|
||||||
|
`firstlogon` tinyint(3) NOT NULL DEFAULT '0',
|
||||||
|
`inspectmessage` varchar(256) NOT NULL DEFAULT '',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `name` (`name`),
|
||||||
|
KEY `account_id` (`account_id`)
|
||||||
|
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
-- Initial population of the character_lookup table --
|
||||||
|
|
||||||
|
INSERT INTO `character_lookup` (id, account_id, `name`, timelaston, x, y, z, zonename, zoneid, instanceid, pktime, groupid, class, `level`, lfp, lfg, mailkey, xtargets, firstlogon, inspectmessage)
|
||||||
|
SELECT id, account_id, `name`, timelaston, x, y, z, zonename, zoneid, instanceid, pktime, groupid, class, `level`, lfp, lfg, mailkey, xtargets, firstlogon, inspectmessage
|
||||||
|
FROM `character_`;
|
||||||
@ -1268,7 +1268,7 @@ bool ZoneServer::Process() {
|
|||||||
UCSLink.SendPacket(pack);
|
UCSLink.SendPacket(pack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServerOP_QSSendQuery:
|
||||||
case ServerOP_QueryServGeneric:
|
case ServerOP_QueryServGeneric:
|
||||||
case ServerOP_Speech:
|
case ServerOP_Speech:
|
||||||
case ServerOP_QSPlayerLogTrades:
|
case ServerOP_QSPlayerLogTrades:
|
||||||
@ -1296,7 +1296,7 @@ bool ZoneServer::Process() {
|
|||||||
QSLink.SendPacket(pack);
|
QSLink.SendPacket(pack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSMerchantLogTransactions:
|
case ServerOP_QSPlayerLogMerchantTransactions:
|
||||||
{
|
{
|
||||||
QSLink.SendPacket(pack);
|
QSLink.SendPacket(pack);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -93,6 +93,7 @@ SET(zone_sources
|
|||||||
petitions.cpp
|
petitions.cpp
|
||||||
pets.cpp
|
pets.cpp
|
||||||
qglobals.cpp
|
qglobals.cpp
|
||||||
|
queryserv.cpp
|
||||||
questmgr.cpp
|
questmgr.cpp
|
||||||
quest_parser_collection.cpp
|
quest_parser_collection.cpp
|
||||||
raids.cpp
|
raids.cpp
|
||||||
@ -184,6 +185,8 @@ SET(zone_headers
|
|||||||
pets.h
|
pets.h
|
||||||
qglobals.h
|
qglobals.h
|
||||||
quest_interface.h
|
quest_interface.h
|
||||||
|
queryserv.h
|
||||||
|
quest_interface.h
|
||||||
questmgr.h
|
questmgr.h
|
||||||
quest_parser_collection.h
|
quest_parser_collection.h
|
||||||
raid.h
|
raid.h
|
||||||
|
|||||||
39
zone/aa.cpp
39
zone/aa.cpp
@ -38,6 +38,9 @@ Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
|
|||||||
#include "../common/logsys.h"
|
#include "../common/logsys.h"
|
||||||
#include "zonedb.h"
|
#include "zonedb.h"
|
||||||
#include "string_ids.h"
|
#include "string_ids.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
//static data arrays, really not big enough to warrant shared mem.
|
//static data arrays, really not big enough to warrant shared mem.
|
||||||
AA_DBAction AA_Actions[aaHighestID][MAX_AA_ACTION_RANKS]; //[aaid][rank]
|
AA_DBAction AA_Actions[aaHighestID][MAX_AA_ACTION_RANKS]; //[aaid][rank]
|
||||||
@ -1039,16 +1042,16 @@ void Client::BuyAA(AA_Action* action)
|
|||||||
else
|
else
|
||||||
real_cost = aa2->cost + (aa2->cost_inc * cur_level);
|
real_cost = aa2->cost + (aa2->cost_inc * cur_level);
|
||||||
|
|
||||||
if(m_pp.aapoints >= real_cost && cur_level < aa2->max_level) {
|
if (m_pp.aapoints >= real_cost && cur_level < aa2->max_level) {
|
||||||
SetAA(aa2->id, cur_level+1);
|
SetAA(aa2->id, cur_level + 1);
|
||||||
|
|
||||||
mlog(AA__MESSAGE, "Set AA %d to level %d", aa2->id, cur_level+1);
|
mlog(AA__MESSAGE, "Set AA %d to level %d", aa2->id, cur_level + 1);
|
||||||
|
|
||||||
m_pp.aapoints -= real_cost;
|
m_pp.aapoints -= real_cost;
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
if ((RuleB(AA, Stacking) && (GetClientVersionBit() >= 4) && (aa2->hotkey_sid == 4294967295u))
|
if ((RuleB(AA, Stacking) && (GetClientVersionBit() >= 4) && (aa2->hotkey_sid == 4294967295u))
|
||||||
&& ((aa2->max_level == (cur_level+1)) && aa2->sof_next_id)){
|
&& ((aa2->max_level == (cur_level + 1)) && aa2->sof_next_id)){
|
||||||
SendAA(aa2->id);
|
SendAA(aa2->id);
|
||||||
SendAA(aa2->sof_next_id);
|
SendAA(aa2->sof_next_id);
|
||||||
}
|
}
|
||||||
@ -1059,10 +1062,28 @@ void Client::BuyAA(AA_Action* action)
|
|||||||
|
|
||||||
//we are building these messages ourself instead of using the stringID to work around patch discrepencies
|
//we are building these messages ourself instead of using the stringID to work around patch discrepencies
|
||||||
//these are AA_GAIN_ABILITY (410) & AA_IMPROVE (411), respectively, in both Titanium & SoF. not sure about 6.2
|
//these are AA_GAIN_ABILITY (410) & AA_IMPROVE (411), respectively, in both Titanium & SoF. not sure about 6.2
|
||||||
if(cur_level<1)
|
|
||||||
Message(15,"You have gained the ability \"%s\" at a cost of %d ability %s.", aa2->name, real_cost, (real_cost>1)?"points":"point");
|
/* Initial purchase of an AA ability */
|
||||||
else
|
if (cur_level < 1){
|
||||||
Message(15,"You have improved %s %d at a cost of %d ability %s.", aa2->name, cur_level+1, real_cost, (real_cost>1)?"points":"point");
|
Message(15, "You have gained the ability \"%s\" at a cost of %d ability %s.", aa2->name, real_cost, (real_cost>1) ? "points" : "point");
|
||||||
|
|
||||||
|
/* QS: Player_Log_AA_Purchases */
|
||||||
|
if (RuleB(QueryServ, PlayerLogAAPurchases)){
|
||||||
|
std::string event_desc = StringFormat("Initial AA Purchase :: aa_name:%s aa_id:%i at cost:%i in zoneid:%i instid:%i", aa2->name, aa2->id, real_cost, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_AA_Purchases, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Ranked purchase of an AA ability */
|
||||||
|
else{
|
||||||
|
Message(15, "You have improved %s %d at a cost of %d ability %s.", aa2->name, cur_level + 1, real_cost, (real_cost > 1) ? "points" : "point");
|
||||||
|
|
||||||
|
/* QS: Player_Log_AA_Purchases */
|
||||||
|
if (RuleB(QueryServ, PlayerLogAAPurchases)){
|
||||||
|
std::string event_desc = StringFormat("Ranked AA Purchase :: aa_name:%s aa_id:%i at cost:%i in zoneid:%i instid:%i", aa2->name, aa2->id, real_cost, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_AA_Purchases, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SendAAStats();
|
SendAAStats();
|
||||||
@ -1816,7 +1837,7 @@ SendAA_Struct* ZoneDatabase::GetAASkillVars(uint32 skill_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
query = StringFormat("SELECT a.cost, a.max_level, a.hotkey_sid, a.hotkey_sid2, a.title_sid, a.desc_sid, a.type, "
|
query = StringFormat("SELECT a.cost, a.max_level, a.hotkey_sid, a.hotkey_sid2, a.title_sid, a.desc_sid, a.type, "
|
||||||
"COALESCE (" //So we can return 0 if it's null.
|
"COALESCE(" //So we can return 0 if it's null.
|
||||||
"(" // this is our derived table that has the row #
|
"(" // this is our derived table that has the row #
|
||||||
// that we can SELECT from, because the client is stupid.
|
// that we can SELECT from, because the client is stupid.
|
||||||
"SELECT p.prereq_index_num "
|
"SELECT p.prereq_index_num "
|
||||||
|
|||||||
@ -873,7 +873,34 @@ bool Mob::CombatRange(Mob* other)
|
|||||||
if (size_mod > 10000)
|
if (size_mod > 10000)
|
||||||
size_mod = size_mod / 7;
|
size_mod = size_mod / 7;
|
||||||
|
|
||||||
if (DistNoRoot(*other) <= size_mod)
|
float _DistNoRoot = DistNoRoot(*other);
|
||||||
|
|
||||||
|
if (GetSpecialAbility(NPC_CHASE_DISTANCE)){
|
||||||
|
|
||||||
|
bool DoLoSCheck = true;
|
||||||
|
float max_dist = static_cast<float>(GetSpecialAbilityParam(NPC_CHASE_DISTANCE, 0));
|
||||||
|
float min_dist = static_cast<float>(GetSpecialAbilityParam(NPC_CHASE_DISTANCE, 1));
|
||||||
|
|
||||||
|
if (GetSpecialAbilityParam(NPC_CHASE_DISTANCE, 2));
|
||||||
|
DoLoSCheck = false; //Ignore line of sight check
|
||||||
|
|
||||||
|
if (max_dist == 1)
|
||||||
|
max_dist = 250.0f; //Default it to 250 if you forget to put a value
|
||||||
|
|
||||||
|
max_dist = max_dist * max_dist;
|
||||||
|
|
||||||
|
if (!min_dist)
|
||||||
|
min_dist = size_mod; //Default to melee range
|
||||||
|
else
|
||||||
|
min_dist = min_dist * min_dist;
|
||||||
|
|
||||||
|
if ((DoLoSCheck && CheckLastLosState()) && (_DistNoRoot >= min_dist && _DistNoRoot <= max_dist))
|
||||||
|
SetPseudoRoot(true);
|
||||||
|
else
|
||||||
|
SetPseudoRoot(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_DistNoRoot <= size_mod)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -887,6 +914,8 @@ bool Mob::CheckLosFN(Mob* other) {
|
|||||||
if(other)
|
if(other)
|
||||||
Result = CheckLosFN(other->GetX(), other->GetY(), other->GetZ(), other->GetSize());
|
Result = CheckLosFN(other->GetX(), other->GetY(), other->GetZ(), other->GetSize());
|
||||||
|
|
||||||
|
SetLastLosState(Result);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,6 +42,9 @@
|
|||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
#include "water_map.h"
|
#include "water_map.h"
|
||||||
#include "worldserver.h"
|
#include "worldserver.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
@ -1455,14 +1458,14 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
|||||||
int exploss = 0;
|
int exploss = 0;
|
||||||
mlog(COMBAT__HITS, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killerMob ? killerMob->GetName() : "Unknown", damage, spell, attack_skill);
|
mlog(COMBAT__HITS, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killerMob ? killerMob->GetName() : "Unknown", damage, spell, attack_skill);
|
||||||
|
|
||||||
//
|
/*
|
||||||
// #1: Send death packet to everyone
|
#1: Send death packet to everyone
|
||||||
//
|
*/
|
||||||
uint8 killed_level = GetLevel();
|
uint8 killed_level = GetLevel();
|
||||||
|
|
||||||
SendLogoutPackets();
|
SendLogoutPackets();
|
||||||
|
|
||||||
//make our become corpse packet, and queue to ourself before OP_Death.
|
/* Make self become corpse packet */
|
||||||
EQApplicationPacket app2(OP_BecomeCorpse, sizeof(BecomeCorpse_Struct));
|
EQApplicationPacket app2(OP_BecomeCorpse, sizeof(BecomeCorpse_Struct));
|
||||||
BecomeCorpse_Struct* bc = (BecomeCorpse_Struct*)app2.pBuffer;
|
BecomeCorpse_Struct* bc = (BecomeCorpse_Struct*)app2.pBuffer;
|
||||||
bc->spawn_id = GetID();
|
bc->spawn_id = GetID();
|
||||||
@ -1471,7 +1474,7 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
|||||||
bc->z = GetZ();
|
bc->z = GetZ();
|
||||||
QueuePacket(&app2);
|
QueuePacket(&app2);
|
||||||
|
|
||||||
// make death packet
|
/* Make Death Packet */
|
||||||
EQApplicationPacket app(OP_Death, sizeof(Death_Struct));
|
EQApplicationPacket app(OP_Death, sizeof(Death_Struct));
|
||||||
Death_Struct* d = (Death_Struct*)app.pBuffer;
|
Death_Struct* d = (Death_Struct*)app.pBuffer;
|
||||||
d->spawn_id = GetID();
|
d->spawn_id = GetID();
|
||||||
@ -1484,9 +1487,9 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
|||||||
app.priority = 6;
|
app.priority = 6;
|
||||||
entity_list.QueueClients(this, &app);
|
entity_list.QueueClients(this, &app);
|
||||||
|
|
||||||
//
|
/*
|
||||||
// #2: figure out things that affect the player dying and mark them dead
|
#2: figure out things that affect the player dying and mark them dead
|
||||||
//
|
*/
|
||||||
|
|
||||||
InterruptSpell();
|
InterruptSpell();
|
||||||
SetPet(0);
|
SetPet(0);
|
||||||
@ -1541,9 +1544,9 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
|||||||
//remove ourself from all proximities
|
//remove ourself from all proximities
|
||||||
ClearAllProximities();
|
ClearAllProximities();
|
||||||
|
|
||||||
//
|
/*
|
||||||
// #3: exp loss and corpse generation
|
#3: exp loss and corpse generation
|
||||||
//
|
*/
|
||||||
|
|
||||||
// figure out if they should lose exp
|
// figure out if they should lose exp
|
||||||
if(RuleB(Character, UseDeathExpLossMult)){
|
if(RuleB(Character, UseDeathExpLossMult)){
|
||||||
@ -1659,27 +1662,21 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
|||||||
|
|
||||||
LeftCorpse = true;
|
LeftCorpse = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(!IsLD())//Todo: make it so an LDed client leaves corpse if its enabled
|
|
||||||
// MakeCorpse(exploss);
|
|
||||||
} else {
|
} else {
|
||||||
BuffFadeDetrimental();
|
BuffFadeDetrimental();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/*
|
||||||
// Finally, send em home
|
Finally, send em home
|
||||||
//
|
|
||||||
|
|
||||||
// we change the mob variables, not pp directly, because Save() will copy
|
We change the mob variables, not pp directly, because Save() will copy
|
||||||
// from these and overwrite what we set in pp anyway
|
from these and overwrite what we set in pp anyway
|
||||||
//
|
*/
|
||||||
|
|
||||||
if(LeftCorpse && (GetClientVersionBit() & BIT_SoFAndLater) && RuleB(Character, RespawnFromHover))
|
if(LeftCorpse && (GetClientVersionBit() & BIT_SoFAndLater) && RuleB(Character, RespawnFromHover))
|
||||||
{
|
{
|
||||||
ClearDraggedCorpses();
|
ClearDraggedCorpses();
|
||||||
|
|
||||||
RespawnFromHoverTimer.Start(RuleI(Character, RespawnFromHoverTimer) * 1000);
|
RespawnFromHoverTimer.Start(RuleI(Character, RespawnFromHoverTimer) * 1000);
|
||||||
|
|
||||||
SendRespawnBinds();
|
SendRespawnBinds();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1697,16 +1694,21 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
|||||||
r->MemberZoned(this);
|
r->MemberZoned(this);
|
||||||
|
|
||||||
dead_timer.Start(5000, true);
|
dead_timer.Start(5000, true);
|
||||||
|
|
||||||
m_pp.zone_id = m_pp.binds[0].zoneId;
|
m_pp.zone_id = m_pp.binds[0].zoneId;
|
||||||
m_pp.zoneInstance = 0;
|
m_pp.zoneInstance = 0;
|
||||||
database.MoveCharacterToZone(this->CharacterID(), database.GetZoneName(m_pp.zone_id));
|
database.MoveCharacterToZone(this->CharacterID(), database.GetZoneName(m_pp.zone_id));
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
|
|
||||||
GoToDeath();
|
GoToDeath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* QS: PlayerLogDeaths */
|
||||||
|
if (RuleB(QueryServ, PlayerLogDeaths)){
|
||||||
|
const char * killer_name = "";
|
||||||
|
if (killerMob && killerMob->GetCleanName()){ killer_name = killerMob->GetCleanName(); }
|
||||||
|
std::string event_desc = StringFormat("Died in zoneid:%i instid:%i by '%s', spellid:%i, damage:%i", this->GetZoneID(), this->GetInstanceID(), killer_name, spell, damage);
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Deaths, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
|
||||||
parse->EventPlayer(EVENT_DEATH_COMPLETE, this, buffer, 0);
|
parse->EventPlayer(EVENT_DEATH_COMPLETE, this, buffer, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
322
zone/client.cpp
322
zone/client.cpp
@ -62,8 +62,9 @@ extern volatile bool RunLoops;
|
|||||||
#include "client_logs.h"
|
#include "client_logs.h"
|
||||||
#include "guild_mgr.h"
|
#include "guild_mgr.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
extern EntityList entity_list;
|
extern EntityList entity_list;
|
||||||
extern Zone* zone;
|
extern Zone* zone;
|
||||||
extern volatile bool ZoneLoaded;
|
extern volatile bool ZoneLoaded;
|
||||||
@ -629,6 +630,9 @@ bool Client::Save(uint8 iCommitNow) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mirror Character Data */
|
||||||
|
database.StoreCharacterLookup(this->CharacterID());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,8 +809,8 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Logs Player Chat */
|
||||||
if(RuleB(QueryServ, PlayerChatLogging)) {
|
if (RuleB(QueryServ, PlayerLogChat)) {
|
||||||
ServerPacket* pack = new ServerPacket(ServerOP_Speech, sizeof(Server_Speech_Struct) + strlen(message) + 1);
|
ServerPacket* pack = new ServerPacket(ServerOP_Speech, sizeof(Server_Speech_Struct) + strlen(message) + 1);
|
||||||
Server_Speech_Struct* sem = (Server_Speech_Struct*) pack->pBuffer;
|
Server_Speech_Struct* sem = (Server_Speech_Struct*) pack->pBuffer;
|
||||||
|
|
||||||
@ -841,7 +845,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
|
|
||||||
switch(chan_num)
|
switch(chan_num)
|
||||||
{
|
{
|
||||||
case 0: { // GuildChat
|
case 0: { /* Guild Chat */
|
||||||
if (!IsInAGuild())
|
if (!IsInAGuild())
|
||||||
Message_StringID(MT_DefaultText, GUILD_NOT_MEMBER2); //You are not a member of any guild.
|
Message_StringID(MT_DefaultText, GUILD_NOT_MEMBER2); //You are not a member of any guild.
|
||||||
else if (!guild_mgr.CheckPermission(GuildID(), GuildRank(), GUILD_SPEAK))
|
else if (!guild_mgr.CheckPermission(GuildID(), GuildRank(), GUILD_SPEAK))
|
||||||
@ -850,7 +854,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
Message(0, "Error: World server disconnected");
|
Message(0, "Error: World server disconnected");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: { // GroupChat
|
case 2: { /* Group Chat */
|
||||||
Raid* raid = entity_list.GetRaidByClient(this);
|
Raid* raid = entity_list.GetRaidByClient(this);
|
||||||
if(raid) {
|
if(raid) {
|
||||||
raid->RaidGroupSay((const char*) message, this);
|
raid->RaidGroupSay((const char*) message, this);
|
||||||
@ -863,14 +867,14 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 15: { //raid say
|
case 15: { /* Raid Say */
|
||||||
Raid* raid = entity_list.GetRaidByClient(this);
|
Raid* raid = entity_list.GetRaidByClient(this);
|
||||||
if(raid){
|
if(raid){
|
||||||
raid->RaidSay((const char*) message, this);
|
raid->RaidSay((const char*) message, this);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3: { // Shout
|
case 3: { /* Shout */
|
||||||
Mob *sender = this;
|
Mob *sender = this;
|
||||||
if (GetPet() && GetPet()->FindType(SE_VoiceGraft))
|
if (GetPet() && GetPet()->FindType(SE_VoiceGraft))
|
||||||
sender = GetPet();
|
sender = GetPet();
|
||||||
@ -878,7 +882,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
entity_list.ChannelMessage(sender, chan_num, language, lang_skill, message);
|
entity_list.ChannelMessage(sender, chan_num, language, lang_skill, message);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4: { // Auction
|
case 4: { /* Auction */
|
||||||
if(RuleB(Chat, ServerWideAuction))
|
if(RuleB(Chat, ServerWideAuction))
|
||||||
{
|
{
|
||||||
if(!global_channel_timer.Check())
|
if(!global_channel_timer.Check())
|
||||||
@ -917,7 +921,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 5: { // OOC
|
case 5: { /* OOC */
|
||||||
if(RuleB(Chat, ServerWideOOC))
|
if(RuleB(Chat, ServerWideOOC))
|
||||||
{
|
{
|
||||||
if(!global_channel_timer.Check())
|
if(!global_channel_timer.Check())
|
||||||
@ -964,15 +968,15 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 6: // Broadcast
|
case 6: /* Broadcast */
|
||||||
case 11: { // GMSay
|
case 11: { /* GM Say */
|
||||||
if (!(admin >= 80))
|
if (!(admin >= 80))
|
||||||
Message(0, "Error: Only GMs can use this channel");
|
Message(0, "Error: Only GMs can use this channel");
|
||||||
else if (!worldserver.SendChannelMessage(this, targetname, chan_num, 0, language, message))
|
else if (!worldserver.SendChannelMessage(this, targetname, chan_num, 0, language, message))
|
||||||
Message(0, "Error: World server disconnected");
|
Message(0, "Error: World server disconnected");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 7: { // Tell
|
case 7: { /* Tell */
|
||||||
if(!global_channel_timer.Check())
|
if(!global_channel_timer.Check())
|
||||||
{
|
{
|
||||||
if(strlen(targetname) == 0)
|
if(strlen(targetname) == 0)
|
||||||
@ -1020,7 +1024,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
Message(0, "Error: World server disconnected");
|
Message(0, "Error: World server disconnected");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 8: { // /say
|
case 8: { /* Say */
|
||||||
if(message[0] == COMMAND_CHAR) {
|
if(message[0] == COMMAND_CHAR) {
|
||||||
if(command_dispatch(this, message) == -2) {
|
if(command_dispatch(this, message) == -2) {
|
||||||
if(parse->PlayerHasQuestSub(EVENT_COMMAND)) {
|
if(parse->PlayerHasQuestSub(EVENT_COMMAND)) {
|
||||||
@ -4060,25 +4064,40 @@ void Client::KeyRingList()
|
|||||||
|
|
||||||
bool Client::IsDiscovered(uint32 itemid) {
|
bool Client::IsDiscovered(uint32 itemid) {
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT count(*) FROM discovered_items WHERE item_id = '%lu'", itemid);
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
auto results = database.QueryDatabase(query);
|
char *query = 0;
|
||||||
if (!results.Success()) {
|
MYSQL_RES *result;
|
||||||
std::cerr << "Error in IsDiscovered query '" << query << "' " << results.ErrorMessage() << std::endl;
|
MYSQL_ROW row;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto row = results.begin();
|
if (database.RunQuery(query, MakeAnyLenString(&query, "SELECT count(*) FROM discovered_items WHERE item_id = '%lu'", itemid), errbuf, &result))
|
||||||
|
{
|
||||||
return atoi(row[0]) != 0;
|
row = mysql_fetch_row(result);
|
||||||
|
if (atoi(row[0]))
|
||||||
|
{
|
||||||
|
mysql_free_result(result);
|
||||||
|
safe_delete_array(query);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "Error in IsDiscovered query '" << query << "' " << errbuf << std::endl;
|
||||||
|
}
|
||||||
|
mysql_free_result(result);
|
||||||
|
safe_delete_array(query);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::DiscoverItem(uint32 itemid) {
|
void Client::DiscoverItem(uint32 itemid) {
|
||||||
|
|
||||||
std::string query = StringFormat("INSERT INTO discovered_items SET "
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
"item_id = %lu, char_name = '%s', "
|
char* query = 0;
|
||||||
"discovered_date = UNIX_TIMESTAMP(), account_status=%i",
|
MYSQL_RES *result;
|
||||||
itemid, GetName(), Admin());
|
if (database.RunQuery(query,MakeAnyLenString(&query, "INSERT INTO discovered_items SET item_id=%lu, char_name='%s', discovered_date=UNIX_TIMESTAMP(), account_status=%i", itemid, GetName(), Admin()), errbuf, &result))
|
||||||
auto results = database.QueryDatabase(query);
|
{
|
||||||
|
mysql_free_result(result);
|
||||||
|
}
|
||||||
|
safe_delete_array(query);
|
||||||
|
|
||||||
parse->EventPlayer(EVENT_DISCOVER_ITEM, this, "", itemid);
|
parse->EventPlayer(EVENT_DISCOVER_ITEM, this, "", itemid);
|
||||||
}
|
}
|
||||||
@ -5261,22 +5280,32 @@ const bool Client::IsMQExemptedArea(uint32 zoneID, float x, float y, float z) co
|
|||||||
void Client::SendRewards()
|
void Client::SendRewards()
|
||||||
{
|
{
|
||||||
std::vector<ClientReward> rewards;
|
std::vector<ClientReward> rewards;
|
||||||
std::string query = StringFormat("SELECT reward_id, amount FROM "
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
"account_rewards WHERE account_id = %i "
|
char* query = 0;
|
||||||
"ORDER BY reward_id", AccountID());
|
MYSQL_RES *result;
|
||||||
auto results = database.QueryDatabase(query);
|
MYSQL_ROW row;
|
||||||
if (!results.Success()) {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in Client::SendRewards(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT reward_id, amount FROM"
|
||||||
|
" account_rewards WHERE account_id=%i ORDER by reward_id", AccountID()),
|
||||||
|
errbuf,&result))
|
||||||
|
{
|
||||||
|
while((row = mysql_fetch_row(result)))
|
||||||
|
{
|
||||||
|
ClientReward cr;
|
||||||
|
cr.id = atoi(row[0]);
|
||||||
|
cr.amount = atoi(row[1]);
|
||||||
|
rewards.push_back(cr);
|
||||||
|
}
|
||||||
|
mysql_free_result(result);
|
||||||
|
safe_delete_array(query);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogFile->write(EQEMuLog::Error, "Error in Client::SendRewards(): %s (%s)", query, errbuf);
|
||||||
|
safe_delete_array(query);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
|
||||||
ClientReward cr;
|
|
||||||
cr.id = atoi(row[0]);
|
|
||||||
cr.amount = atoi(row[1]);
|
|
||||||
rewards.push_back(cr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rewards.size() > 0)
|
if(rewards.size() > 0)
|
||||||
{
|
{
|
||||||
EQApplicationPacket *vetapp = new EQApplicationPacket(OP_VetRewardsAvaliable, (sizeof(InternalVeteranReward) * rewards.size()));
|
EQApplicationPacket *vetapp = new EQApplicationPacket(OP_VetRewardsAvaliable, (sizeof(InternalVeteranReward) * rewards.size()));
|
||||||
@ -5336,54 +5365,88 @@ bool Client::TryReward(uint32 claim_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(free_slot == 0xFFFFFFFF)
|
if(free_slot == 0xFFFFFFFF)
|
||||||
return false;
|
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT amount FROM account_rewards "
|
|
||||||
"WHERE account_id=%i AND reward_id=%i",
|
|
||||||
AccountID(), claim_id);
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success()) {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.RowCount() == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uint32 amt = 0;
|
|
||||||
auto row = results.begin();
|
|
||||||
|
|
||||||
amt = atoi(row[0]);
|
|
||||||
|
|
||||||
if(amt == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
auto iter = zone->VeteranRewards.begin();
|
|
||||||
for (; iter != zone->VeteranRewards.end(); ++iter)
|
|
||||||
if((*iter).claim_id == claim_id)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(iter == zone->VeteranRewards.end())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(amt == 1)
|
|
||||||
{
|
{
|
||||||
query = StringFormat("DELETE FROM account_rewards "
|
return false;
|
||||||
"WHERE account_id=%i AND reward_id=%i",
|
}
|
||||||
AccountID(), claim_id);
|
|
||||||
results = database.QueryDatabase(query);
|
|
||||||
if(!results.ErrorMessage().c_str())
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
|
||||||
|
|
||||||
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
|
char* query = 0;
|
||||||
|
MYSQL_RES *result;
|
||||||
|
MYSQL_ROW row;
|
||||||
|
uint32 amt = 0;
|
||||||
|
|
||||||
|
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT amount FROM"
|
||||||
|
" account_rewards WHERE account_id=%i AND reward_id=%i", AccountID(), claim_id),
|
||||||
|
errbuf,&result))
|
||||||
|
{
|
||||||
|
row = mysql_fetch_row(result);
|
||||||
|
if(row)
|
||||||
|
{
|
||||||
|
amt = atoi(row[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mysql_free_result(result);
|
||||||
|
safe_delete_array(query);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mysql_free_result(result);
|
||||||
|
safe_delete_array(query);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
query = StringFormat("UPDATE account_rewards SET amount=(amount-1) "
|
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query, errbuf);
|
||||||
"WHERE account_id=%i AND reward_id=%i", AccountID(), claim_id);
|
safe_delete_array(query);
|
||||||
results = database.QueryDatabase(query);
|
return false;
|
||||||
if(!results.Success())
|
}
|
||||||
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query.c_str(), results.ErrorMessage().c_str());
|
|
||||||
|
|
||||||
|
if(amt == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<InternalVeteranReward>::iterator iter = zone->VeteranRewards.begin();
|
||||||
|
while(iter != zone->VeteranRewards.end())
|
||||||
|
{
|
||||||
|
if((*iter).claim_id == claim_id)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iter == zone->VeteranRewards.end())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(amt == 1)
|
||||||
|
{
|
||||||
|
if(!database.RunQuery(query,MakeAnyLenString(&query,"DELETE FROM"
|
||||||
|
" account_rewards WHERE account_id=%i AND reward_id=%i", AccountID(), claim_id),
|
||||||
|
errbuf))
|
||||||
|
{
|
||||||
|
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query, errbuf);
|
||||||
|
safe_delete_array(query);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
safe_delete_array(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!database.RunQuery(query,MakeAnyLenString(&query,"UPDATE account_rewards SET amount=(amount-1)"
|
||||||
|
" WHERE account_id=%i AND reward_id=%i", AccountID(), claim_id),
|
||||||
|
errbuf))
|
||||||
|
{
|
||||||
|
LogFile->write(EQEMuLog::Error, "Error in Client::TryReward(): %s (%s)", query, errbuf);
|
||||||
|
safe_delete_array(query);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
safe_delete_array(query);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InternalVeteranReward ivr = (*iter);
|
InternalVeteranReward ivr = (*iter);
|
||||||
@ -6862,8 +6925,18 @@ void Client::SetAlternateCurrencyValue(uint32 currency_id, uint32 new_amount)
|
|||||||
SendAlternateCurrencyValue(currency_id);
|
SendAlternateCurrencyValue(currency_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::AddAlternateCurrencyValue(uint32 currency_id, int32 amount)
|
void Client::AddAlternateCurrencyValue(uint32 currency_id, int32 amount, int8 method)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/* Added via Quest, rest of the logging methods may be done inline due to information available in that area of the code */
|
||||||
|
if (method == 1){
|
||||||
|
/* QS: PlayerLogAlternateCurrencyTransactions :: Cursor to Item Storage */
|
||||||
|
if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){
|
||||||
|
std::string event_desc = StringFormat("Added via Quest :: Cursor to Item :: alt_currency_id:%i amount:%i in zoneid:%i instid:%i", currency_id, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(amount == 0) {
|
if(amount == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -7738,30 +7811,41 @@ void Client::SendFactionMessage(int32 tmpvalue, int32 faction_id, int32 totalval
|
|||||||
|
|
||||||
void Client::LoadAccountFlags()
|
void Client::LoadAccountFlags()
|
||||||
{
|
{
|
||||||
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
|
char *query = 0;
|
||||||
|
MYSQL_RES *result;
|
||||||
|
MYSQL_ROW row;
|
||||||
|
|
||||||
accountflags.clear();
|
accountflags.clear();
|
||||||
|
MakeAnyLenString(&query, "SELECT p_flag, p_value FROM account_flags WHERE p_accid = '%d'", account_id);
|
||||||
std::string query = StringFormat("SELECT p_flag, p_value FROM account_flags WHERE p_accid = '%d'", account_id);
|
if(database.RunQuery(query, strlen(query), errbuf, &result))
|
||||||
auto results = database.QueryDatabase(query);
|
{
|
||||||
if (!results.Success()) {
|
while(row = mysql_fetch_row(result))
|
||||||
std::cerr << "Error in LoadAccountFlags query '" << query << "' " << results.ErrorMessage() << std::endl;
|
{
|
||||||
return;
|
std::string fname(row[0]);
|
||||||
}
|
std::string fval(row[1]);
|
||||||
|
accountflags[fname] = fval;
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
}
|
||||||
std::string fname(row[0]);
|
mysql_free_result(result);
|
||||||
std::string fval(row[1]);
|
}
|
||||||
accountflags[fname] = fval;
|
else
|
||||||
}
|
{
|
||||||
|
std::cerr << "Error in LoadAccountFlags query '" << query << "' " << errbuf << std::endl;
|
||||||
|
}
|
||||||
|
safe_delete_array(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SetAccountFlag(std::string flag, std::string val)
|
void Client::SetAccountFlag(std::string flag, std::string val)
|
||||||
{
|
{
|
||||||
std::string query = StringFormat("REPLACE INTO account_flags (p_accid, p_flag, p_value) "
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
"VALUES( '%d', '%s', '%s')", account_id, flag.c_str(), val.c_str());
|
char *query = 0;
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if(!results.Success())
|
MakeAnyLenString(&query, "REPLACE INTO account_flags (p_accid, p_flag, p_value) VALUES( '%d', '%s', '%s')", account_id, flag.c_str(), val.c_str());
|
||||||
std::cerr << "Error in SetAccountFlags query '" << query << "' " << results.ErrorMessage() << std::endl;
|
if(!database.RunQuery(query, strlen(query), errbuf))
|
||||||
|
{
|
||||||
|
std::cerr << "Error in SetAccountFlags query '" << query << "' " << errbuf << std::endl;
|
||||||
|
}
|
||||||
|
safe_delete_array(query);
|
||||||
|
|
||||||
accountflags[flag] = val;
|
accountflags[flag] = val;
|
||||||
}
|
}
|
||||||
@ -8170,21 +8254,29 @@ void Client::PlayMP3(const char* fname)
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::ExpeditionSay(const char *str, int expID) {
|
void Client::ExpeditionSay(const char *str, int ExpID) {
|
||||||
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
|
char* query = 0;
|
||||||
|
MYSQL_RES *result;
|
||||||
|
MYSQL_ROW row;
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT `player_name` FROM "
|
if (!database.RunQuery(query,MakeAnyLenString(&query, "SELECT `player_name` FROM `cust_inst_players` WHERE `inst_id` = %i", ExpID),errbuf,&result)){
|
||||||
"`cust_inst_players` WHERE "
|
safe_delete_array(query);
|
||||||
"`inst_id` = %i", expID);
|
|
||||||
auto results = database.QueryDatabase(query);
|
|
||||||
if (!results.Success())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this->Message(14, "You say to the expedition, '%s'", str);
|
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
|
||||||
const char* charName = row[0];
|
|
||||||
if(strcmp(charName, this->GetCleanName()) != 0)
|
|
||||||
worldserver.SendEmoteMessage(charName, 0, 0, 14, "%s says to the expedition, '%s'", this->GetCleanName(), str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
safe_delete_array(query);
|
||||||
|
|
||||||
|
if(result)
|
||||||
|
this->Message(14, "You say to the expedition, '%s'", str);
|
||||||
|
|
||||||
|
while((row = mysql_fetch_row(result))) {
|
||||||
|
const char* CharName = row[0];
|
||||||
|
if(strcmp(CharName, this->GetCleanName()) != 0)
|
||||||
|
worldserver.SendEmoteMessage(CharName, 0, 0, 14, "%s says to the expedition, '%s'", this->GetCleanName(), str);
|
||||||
|
// ChannelList->CreateChannel(ChannelName, ChannelOwner, ChannelPassword, true, atoi(row[3]));
|
||||||
|
}
|
||||||
|
|
||||||
|
mysql_free_result(result);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
8232
zone/client.cpp.orig
Normal file
8232
zone/client.cpp.orig
Normal file
File diff suppressed because it is too large
Load Diff
@ -268,7 +268,7 @@ public:
|
|||||||
void TradeRequestFailed(const EQApplicationPacket* app);
|
void TradeRequestFailed(const EQApplicationPacket* app);
|
||||||
void BuyTraderItem(TraderBuy_Struct* tbs,Client* trader,const EQApplicationPacket* app);
|
void BuyTraderItem(TraderBuy_Struct* tbs,Client* trader,const EQApplicationPacket* app);
|
||||||
void TraderUpdate(uint16 slot_id,uint32 trader_id);
|
void TraderUpdate(uint16 slot_id,uint32 trader_id);
|
||||||
void FinishTrade(Mob* with, ServerPacket* qspack = nullptr, bool finalizer = false);
|
void FinishTrade(Mob* with, bool finalizer = false, void* event_entry = nullptr, std::list<void*>* event_details = nullptr);
|
||||||
void SendZonePoints();
|
void SendZonePoints();
|
||||||
|
|
||||||
void SendBuyerResults(char *SearchQuery, uint32 SearchID);
|
void SendBuyerResults(char *SearchQuery, uint32 SearchID);
|
||||||
@ -1097,7 +1097,7 @@ public:
|
|||||||
inline void ClearDraggedCorpses() { DraggedCorpses.clear(); }
|
inline void ClearDraggedCorpses() { DraggedCorpses.clear(); }
|
||||||
void SendAltCurrencies();
|
void SendAltCurrencies();
|
||||||
void SetAlternateCurrencyValue(uint32 currency_id, uint32 new_amount);
|
void SetAlternateCurrencyValue(uint32 currency_id, uint32 new_amount);
|
||||||
void AddAlternateCurrencyValue(uint32 currency_id, int32 amount);
|
void AddAlternateCurrencyValue(uint32 currency_id, int32 amount, int8 method = 0);
|
||||||
void SendAlternateCurrencyValues();
|
void SendAlternateCurrencyValues();
|
||||||
void SendAlternateCurrencyValue(uint32 currency_id, bool send_if_null = true);
|
void SendAlternateCurrencyValue(uint32 currency_id, bool send_if_null = true);
|
||||||
uint32 GetAlternateCurrencyValue(uint32 currency_id) const;
|
uint32 GetAlternateCurrencyValue(uint32 currency_id) const;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -63,7 +63,9 @@
|
|||||||
#include "guild_mgr.h"
|
#include "guild_mgr.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
extern Zone* zone;
|
extern Zone* zone;
|
||||||
extern volatile bool ZoneLoaded;
|
extern volatile bool ZoneLoaded;
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
@ -770,38 +772,40 @@ bool Client::Process() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//just a set of actions preformed all over in Client::Process
|
/* Just a set of actions preformed all over in Client::Process */
|
||||||
void Client::OnDisconnect(bool hard_disconnect) {
|
void Client::OnDisconnect(bool hard_disconnect) {
|
||||||
if(hard_disconnect) {
|
if(hard_disconnect) {
|
||||||
LeaveGroup();
|
LeaveGroup();
|
||||||
|
|
||||||
Raid *MyRaid = entity_list.GetRaidByClient(this);
|
Raid *MyRaid = entity_list.GetRaidByClient(this);
|
||||||
|
|
||||||
if (MyRaid)
|
if (MyRaid)
|
||||||
MyRaid->MemberZoned(this);
|
MyRaid->MemberZoned(this);
|
||||||
|
|
||||||
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
|
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
|
||||||
|
|
||||||
|
/* QS: PlayerLogConnectDisconnect */
|
||||||
|
if (RuleB(QueryServ, PlayerLogConnectDisconnect)){
|
||||||
|
std::string event_desc = StringFormat("Disconnect :: in zoneid:%i instid:%i", this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Connect_State, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Mob *Other = trade->With();
|
Mob *Other = trade->With();
|
||||||
|
if(Other) {
|
||||||
if(Other)
|
|
||||||
{
|
|
||||||
mlog(TRADING__CLIENT, "Client disconnected during a trade. Returning their items.");
|
mlog(TRADING__CLIENT, "Client disconnected during a trade. Returning their items.");
|
||||||
|
|
||||||
FinishTrade(this);
|
FinishTrade(this);
|
||||||
|
|
||||||
if(Other->IsClient())
|
if(Other->IsClient())
|
||||||
Other->CastToClient()->FinishTrade(Other);
|
Other->CastToClient()->FinishTrade(Other);
|
||||||
|
|
||||||
|
/* Reset both sides of the trade */
|
||||||
trade->Reset();
|
trade->Reset();
|
||||||
|
|
||||||
Other->trade->Reset();
|
Other->trade->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
database.SetFirstLogon(CharacterID(), 0); //We change firstlogon status regardless of if a player logs out to zone or not, because we only want to trigger it on their first login from world.
|
database.SetFirstLogon(CharacterID(), 0); //We change firstlogon status regardless of if a player logs out to zone or not, because we only want to trigger it on their first login from world.
|
||||||
|
|
||||||
//remove ourself from all proximities
|
/* Remove ourself from all proximities */
|
||||||
ClearAllProximities();
|
ClearAllProximities();
|
||||||
|
|
||||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LogoutReply);
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LogoutReply);
|
||||||
|
|||||||
@ -62,8 +62,9 @@
|
|||||||
#include "guild_mgr.h"
|
#include "guild_mgr.h"
|
||||||
#include "titles.h"
|
#include "titles.h"
|
||||||
#include "../common/patches/patches.h"
|
#include "../common/patches/patches.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
// these should be in the headers...
|
extern QueryServ* QServ;
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
extern TaskManager *taskmanager;
|
extern TaskManager *taskmanager;
|
||||||
void CatchSignal(int sig_num);
|
void CatchSignal(int sig_num);
|
||||||
@ -588,6 +589,12 @@ int command_realdispatch(Client *c, const char *message)
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* QS: Player_Log_Issued_Commands */
|
||||||
|
if (RuleB(QueryServ, PlayerLogIssuedCommandes)){
|
||||||
|
std::string event_desc = StringFormat("Issued command :: '%s' in zoneid:%i instid:%i", message, c->GetZoneID(), c->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Issued_Commands, c->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef COMMANDS_LOGGING
|
#ifdef COMMANDS_LOGGING
|
||||||
if(cur->access >= COMMANDS_LOGGING_MIN_STATUS) {
|
if(cur->access >= COMMANDS_LOGGING_MIN_STATUS) {
|
||||||
LogFile->write(EQEMuLog::Commands, "%s (%s) used command: %s (target=%s)", c->GetName(), c->AccountName(), message, c->GetTarget()?c->GetTarget()->GetName():"NONE");
|
LogFile->write(EQEMuLog::Commands, "%s (%s) used command: %s (target=%s)", c->GetName(), c->AccountName(), message, c->GetTarget()?c->GetTarget()->GetName():"NONE");
|
||||||
|
|||||||
@ -127,7 +127,8 @@ enum {
|
|||||||
FLEE_PERCENT = 37,
|
FLEE_PERCENT = 37,
|
||||||
ALLOW_BENEFICIAL = 38,
|
ALLOW_BENEFICIAL = 38,
|
||||||
DISABLE_MELEE = 39,
|
DISABLE_MELEE = 39,
|
||||||
MAX_SPECIAL_ATTACK = 40
|
NPC_CHASE_DISTANCE = 40,
|
||||||
|
MAX_SPECIAL_ATTACK = 41
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -526,7 +527,7 @@ public:
|
|||||||
Mob* With();
|
Mob* With();
|
||||||
|
|
||||||
// Add item from cursor slot to trade bucket (automatically does bag data too)
|
// Add item from cursor slot to trade bucket (automatically does bag data too)
|
||||||
void AddEntity(uint16 from_slot_id, uint16 trade_slot_id, uint32 stack_size);
|
void AddEntity(uint16 trade_slot_id, uint32 stack_size);
|
||||||
|
|
||||||
// Audit trade
|
// Audit trade
|
||||||
void LogTrade();
|
void LogTrade();
|
||||||
|
|||||||
@ -1164,7 +1164,7 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app)
|
|||||||
strcpy(corpse_name, orgname);
|
strcpy(corpse_name, orgname);
|
||||||
snprintf(buf, 87, "%d %d %s", inst->GetItem()->ID, inst->GetCharges(), EntityList::RemoveNumbers(corpse_name));
|
snprintf(buf, 87, "%d %d %s", inst->GetItem()->ID, inst->GetCharges(), EntityList::RemoveNumbers(corpse_name));
|
||||||
buf[87] = '\0';
|
buf[87] = '\0';
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(inst);
|
args.push_back(inst);
|
||||||
args.push_back(this);
|
args.push_back(this);
|
||||||
parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args);
|
parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args);
|
||||||
|
|||||||
232
zone/doors.cpp
232
zone/doors.cpp
@ -568,157 +568,137 @@ void Doors::DumpDoor(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32 ZoneDatabase::GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version) {
|
int32 ZoneDatabase::GetDoorsCount(uint32* oMaxID, const char *zone_name, int16 version) {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char *query = 0;
|
|
||||||
|
|
||||||
MYSQL_RES *result;
|
std::string query = StringFormat("SELECT MAX(id), count(*) FROM doors "
|
||||||
MYSQL_ROW row;
|
"WHERE zone = '%s' AND (version = %u OR version = -1)",
|
||||||
query = new char[256];
|
zone_name, version);
|
||||||
sprintf(query, "SELECT MAX(id), count(*) FROM doors WHERE zone='%s' AND (version=%u OR version=-1)", zone_name, version);
|
auto results = QueryDatabase(query);
|
||||||
if (RunQuery(query, strlen(query), errbuf, &result)) {
|
if (!results.Success()) {
|
||||||
safe_delete_array(query);
|
std::cerr << "Error in GetDoorsCount query '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
if (row != nullptr && row[1] != 0) {
|
|
||||||
int32 ret = atoi(row[1]);
|
|
||||||
if (oMaxID) {
|
|
||||||
if (row[0])
|
|
||||||
*oMaxID = atoi(row[0]);
|
|
||||||
else
|
|
||||||
*oMaxID = 0;
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
std::cerr << "Error in GetDoorsCount query '" << query << "' " << errbuf << std::endl;
|
|
||||||
safe_delete_array(query);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() != 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
if (!oMaxID)
|
||||||
|
return atoi(row[1]);
|
||||||
|
|
||||||
|
if (row[0])
|
||||||
|
*oMaxID = atoi(row[0]);
|
||||||
|
else
|
||||||
|
*oMaxID = 0;
|
||||||
|
|
||||||
|
return atoi(row[1]);
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 ZoneDatabase::GetDoorsCountPlusOne(const char *zone_name, int16 version) {
|
int32 ZoneDatabase::GetDoorsCountPlusOne(const char *zone_name, int16 version) {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char *query = 0;
|
|
||||||
uint32 oMaxID = 0;
|
|
||||||
|
|
||||||
MYSQL_RES *result;
|
std::string query = StringFormat("SELECT MAX(id) FROM doors "
|
||||||
MYSQL_ROW row;
|
"WHERE zone = '%s' AND version = %u", zone_name, version);
|
||||||
query = new char[256];
|
auto results = QueryDatabase(query);
|
||||||
sprintf(query, "SELECT MAX(id) FROM doors WHERE zone='%s' AND version=%u", zone_name, version);
|
if (!results.Success()) {
|
||||||
if (RunQuery(query, strlen(query), errbuf, &result)) {
|
std::cerr << "Error in GetDoorsCountPlusOne query '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||||
safe_delete_array(query);
|
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
if (row != nullptr && row[1] != 0) {
|
|
||||||
if (row[0])
|
|
||||||
oMaxID = atoi(row[0]) + 1;
|
|
||||||
else
|
|
||||||
oMaxID = 0;
|
|
||||||
mysql_free_result(result);
|
|
||||||
return oMaxID;
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
std::cerr << "Error in GetDoorsCountPlusOne query '" << query << "' " << errbuf << std::endl;
|
|
||||||
safe_delete_array(query);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
if (results.RowCount() != 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
if (!row[0])
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return atoi(row[0]) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 ZoneDatabase::GetDoorsDBCountPlusOne(const char *zone_name, int16 version) {
|
int32 ZoneDatabase::GetDoorsDBCountPlusOne(const char *zone_name, int16 version) {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char *query = 0;
|
|
||||||
uint32 oMaxID = 0;
|
uint32 oMaxID = 0;
|
||||||
|
|
||||||
MYSQL_RES *result;
|
std::string query = StringFormat("SELECT MAX(doorid) FROM doors "
|
||||||
MYSQL_ROW row;
|
"WHERE zone = '%s' AND (version = %u OR version = -1)",
|
||||||
query = new char[256];
|
zone_name, version);
|
||||||
sprintf(query, "SELECT MAX(doorid) FROM doors WHERE zone='%s' AND (version=%u OR version=-1)", zone_name, version);
|
auto results = QueryDatabase(query);
|
||||||
if (RunQuery(query, strlen(query), errbuf, &result)) {
|
if (!results.Success()) {
|
||||||
safe_delete_array(query);
|
std::cerr << "Error in GetDoorsCountPlusOne query '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
if (row != nullptr && row[1] != 0) {
|
|
||||||
if (row[0])
|
|
||||||
oMaxID = atoi(row[0]) + 1;
|
|
||||||
else
|
|
||||||
oMaxID = 0;
|
|
||||||
mysql_free_result(result);
|
|
||||||
return oMaxID;
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
std::cerr << "Error in GetDoorsCountPlusOne query '" << query << "' " << errbuf << std::endl;
|
|
||||||
safe_delete_array(query);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
if (results.RowCount() != 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
if (!row[0])
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return atoi(row[0]) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name, int16 version) {
|
bool ZoneDatabase::LoadDoors(int32 iDoorCount, Door *into, const char *zone_name, int16 version) {
|
||||||
LogFile->write(EQEMuLog::Status, "Loading Doors from database...");
|
LogFile->write(EQEMuLog::Status, "Loading Doors from database...");
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char *query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
// Door tmpDoor;
|
// Door tmpDoor;
|
||||||
MakeAnyLenString(&query, "SELECT id,doorid,zone,name,pos_x,pos_y,pos_z,heading,"
|
std::string query = StringFormat("SELECT id, doorid, zone, name, pos_x, pos_y, pos_z, heading, "
|
||||||
"opentype,guild,lockpick,keyitem,nokeyring,triggerdoor,triggertype,dest_zone,dest_instance,dest_x,"
|
"opentype, guild, lockpick, keyitem, nokeyring, triggerdoor, triggertype, "
|
||||||
"dest_y,dest_z,dest_heading,door_param,invert_state,incline,size,is_ldon_door,client_version_mask "
|
"dest_zone, dest_instance, dest_x, dest_y, dest_z, dest_heading, "
|
||||||
"FROM doors WHERE zone='%s' AND (version=%u OR version=-1) ORDER BY doorid asc", zone_name, version);
|
"door_param, invert_state, incline, size, is_ldon_door, client_version_mask "
|
||||||
if (RunQuery(query, strlen(query), errbuf, &result)) {
|
"FROM doors WHERE zone = '%s' AND (version = %u OR version = -1) "
|
||||||
safe_delete_array(query);
|
"ORDER BY doorid asc", zone_name, version);
|
||||||
int32 r;
|
auto results = QueryDatabase(query);
|
||||||
for(r = 0; (row = mysql_fetch_row(result)); r++) {
|
if (!results.Success()){
|
||||||
if(r >= iDoorCount) {
|
std::cerr << "Error in DBLoadDoors query '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||||
std::cerr << "Error, Door Count of " << iDoorCount << " exceeded." << std::endl;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
memset(&into[r], 0, sizeof(Door));
|
|
||||||
into[r].db_id = atoi(row[0]);
|
|
||||||
into[r].door_id = atoi(row[1]);
|
|
||||||
strn0cpy(into[r].zone_name,row[2],32);
|
|
||||||
strn0cpy(into[r].door_name,row[3],32);
|
|
||||||
into[r].pos_x = (float)atof(row[4]);
|
|
||||||
into[r].pos_y = (float)atof(row[5]);
|
|
||||||
into[r].pos_z = (float)atof(row[6]);
|
|
||||||
into[r].heading = (float)atof(row[7]);
|
|
||||||
into[r].opentype = atoi(row[8]);
|
|
||||||
into[r].guild_id = atoi(row[9]);
|
|
||||||
into[r].lockpick = atoi(row[10]);
|
|
||||||
into[r].keyitem = atoi(row[11]);
|
|
||||||
into[r].nokeyring = atoi(row[12]);
|
|
||||||
into[r].trigger_door = atoi(row[13]);
|
|
||||||
into[r].trigger_type = atoi(row[14]);
|
|
||||||
strn0cpy(into[r].dest_zone, row[15], 32);
|
|
||||||
into[r].dest_instance_id = atoi(row[16]);
|
|
||||||
into[r].dest_x = (float) atof(row[17]);
|
|
||||||
into[r].dest_y = (float) atof(row[18]);
|
|
||||||
into[r].dest_z = (float) atof(row[19]);
|
|
||||||
into[r].dest_heading = (float) atof(row[20]);
|
|
||||||
into[r].door_param=atoi(row[21]);
|
|
||||||
into[r].invert_state=atoi(row[22]);
|
|
||||||
into[r].incline=atoi(row[23]);
|
|
||||||
into[r].size=atoi(row[24]);
|
|
||||||
into[r].is_ldon_door=atoi(row[25]);
|
|
||||||
into[r].client_version_mask = (uint32)strtoul(row[26], nullptr, 10);
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "Error in DBLoadDoors query '" << query << "' " << errbuf << std::endl;
|
|
||||||
safe_delete_array(query);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 rowIndex = 0;
|
||||||
|
for(auto row = results.begin(); row != results.end(); ++row, ++rowIndex) {
|
||||||
|
if(rowIndex >= iDoorCount) {
|
||||||
|
std::cerr << "Error, Door Count of " << iDoorCount << " exceeded." << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&into[rowIndex], 0, sizeof(Door));
|
||||||
|
|
||||||
|
into[rowIndex].db_id = atoi(row[0]);
|
||||||
|
into[rowIndex].door_id = atoi(row[1]);
|
||||||
|
|
||||||
|
strn0cpy(into[rowIndex].zone_name,row[2],32);
|
||||||
|
strn0cpy(into[rowIndex].door_name,row[3],32);
|
||||||
|
|
||||||
|
into[rowIndex].pos_x = (float)atof(row[4]);
|
||||||
|
into[rowIndex].pos_y = (float)atof(row[5]);
|
||||||
|
into[rowIndex].pos_z = (float)atof(row[6]);
|
||||||
|
into[rowIndex].heading = (float)atof(row[7]);
|
||||||
|
into[rowIndex].opentype = atoi(row[8]);
|
||||||
|
into[rowIndex].guild_id = atoi(row[9]);
|
||||||
|
into[rowIndex].lockpick = atoi(row[10]);
|
||||||
|
into[rowIndex].keyitem = atoi(row[11]);
|
||||||
|
into[rowIndex].nokeyring = atoi(row[12]);
|
||||||
|
into[rowIndex].trigger_door = atoi(row[13]);
|
||||||
|
into[rowIndex].trigger_type = atoi(row[14]);
|
||||||
|
|
||||||
|
strn0cpy(into[rowIndex].dest_zone, row[15], 32);
|
||||||
|
|
||||||
|
into[rowIndex].dest_instance_id = atoi(row[16]);
|
||||||
|
into[rowIndex].dest_x = (float) atof(row[17]);
|
||||||
|
into[rowIndex].dest_y = (float) atof(row[18]);
|
||||||
|
into[rowIndex].dest_z = (float) atof(row[19]);
|
||||||
|
into[rowIndex].dest_heading = (float) atof(row[20]);
|
||||||
|
into[rowIndex].door_param=atoi(row[21]);
|
||||||
|
into[rowIndex].invert_state=atoi(row[22]);
|
||||||
|
into[rowIndex].incline=atoi(row[23]);
|
||||||
|
into[rowIndex].size=atoi(row[24]);
|
||||||
|
into[rowIndex].is_ldon_door=atoi(row[25]);
|
||||||
|
into[rowIndex].client_version_mask = (uint32)strtoul(row[26], nullptr, 10);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -154,7 +154,7 @@ void PerlembParser::ReloadQuests() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
|
int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
|
||||||
uint32 extradata, bool global, std::vector<void*> *extra_pointers)
|
uint32 extradata, bool global, std::vector<EQEmu::Any> *extra_pointers)
|
||||||
{
|
{
|
||||||
if(!perl)
|
if(!perl)
|
||||||
return 0;
|
return 0;
|
||||||
@ -211,32 +211,32 @@ int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * da
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PerlembParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int PerlembParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, false, extra_pointers);
|
return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, false, extra_pointers);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PerlembParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int PerlembParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, true, extra_pointers);
|
return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, init, extra_data, true, extra_pointers);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PerlembParser::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int PerlembParser::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
return EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, false, extra_pointers);
|
return EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, false, extra_pointers);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PerlembParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int PerlembParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
return EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, true, extra_pointers);
|
return EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, true, extra_pointers);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PerlembParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
int PerlembParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
return EventCommon(evt, item->GetID(), nullptr, nullptr, item, client, extra_data, false, extra_pointers);
|
return EventCommon(evt, item->GetID(), nullptr, nullptr, item, client, extra_data, false, extra_pointers);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PerlembParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
int PerlembParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
return EventCommon(evt, 0, itoa(spell_id), npc, nullptr, client, extra_data, false, extra_pointers);
|
return EventCommon(evt, 0, itoa(spell_id), npc, nullptr, client, extra_data, false, extra_pointers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1114,7 +1114,7 @@ void PerlembParser::ExportItemVariables(std::string &package_name, Mob *mob) {
|
|||||||
#undef HASITEM_ISNULLITEM
|
#undef HASITEM_ISNULLITEM
|
||||||
|
|
||||||
void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data,
|
void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data,
|
||||||
NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector<void*> *extra_pointers)
|
NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector<EQEmu::Any> *extra_pointers)
|
||||||
{
|
{
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case EVENT_SAY: {
|
case EVENT_SAY: {
|
||||||
@ -1131,7 +1131,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
|||||||
case EVENT_TRADE: {
|
case EVENT_TRADE: {
|
||||||
if(extra_pointers) {
|
if(extra_pointers) {
|
||||||
for(size_t i = 0; i < extra_pointers->size(); ++i) {
|
for(size_t i = 0; i < extra_pointers->size(); ++i) {
|
||||||
ItemInst *inst = reinterpret_cast<ItemInst*>(extra_pointers->at(i));
|
ItemInst *inst = EQEmu::any_cast<ItemInst*>(extra_pointers->at(i));
|
||||||
std::string var_name = "item";
|
std::string var_name = "item";
|
||||||
var_name += std::to_string(static_cast<long long>(i + 1));
|
var_name += std::to_string(static_cast<long long>(i + 1));
|
||||||
|
|
||||||
|
|||||||
@ -45,17 +45,17 @@ public:
|
|||||||
~PerlembParser();
|
~PerlembParser();
|
||||||
|
|
||||||
virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
virtual bool HasQuestSub(uint32 npcid, QuestEventID evt);
|
virtual bool HasQuestSub(uint32 npcid, QuestEventID evt);
|
||||||
virtual bool HasGlobalQuestSub(QuestEventID evt);
|
virtual bool HasGlobalQuestSub(QuestEventID evt);
|
||||||
@ -86,7 +86,7 @@ private:
|
|||||||
void ExportVarComplex(const char *pkgprefix, const char *varname, const char *value);
|
void ExportVarComplex(const char *pkgprefix, const char *varname, const char *value);
|
||||||
|
|
||||||
int EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
|
int EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
|
||||||
uint32 extradata, bool global, std::vector<void*> *extra_pointers);
|
uint32 extradata, bool global, std::vector<EQEmu::Any> *extra_pointers);
|
||||||
int SendCommands(const char *pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst *iteminst);
|
int SendCommands(const char *pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst *iteminst);
|
||||||
void MapFunctions();
|
void MapFunctions();
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ private:
|
|||||||
void ExportZoneVariables(std::string &package_name);
|
void ExportZoneVariables(std::string &package_name);
|
||||||
void ExportItemVariables(std::string &package_name, Mob *mob);
|
void ExportItemVariables(std::string &package_name, Mob *mob);
|
||||||
void ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data,
|
void ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data,
|
||||||
NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector<void*> *extra_pointers);
|
NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
std::map<uint32, PerlQuestStatus> npc_quest_status_;
|
std::map<uint32, PerlQuestStatus> npc_quest_status_;
|
||||||
PerlQuestStatus global_npc_quest_status_;
|
PerlQuestStatus global_npc_quest_status_;
|
||||||
|
|||||||
@ -28,8 +28,10 @@
|
|||||||
#include "embxs.h"
|
#include "embxs.h"
|
||||||
#include "entity.h"
|
#include "entity.h"
|
||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
extern Zone* zone;
|
extern Zone* zone;
|
||||||
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@ -3370,6 +3372,36 @@ XS(XS__clear_npctype_cache)
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS__qs_send_query);
|
||||||
|
XS(XS__qs_send_query)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1){
|
||||||
|
Perl_croak(aTHX_ "Usage: qs_send_query(query)");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// char *Query = (char *)SvPV_nolen(ST(0));
|
||||||
|
std::string Query = (std::string)SvPV_nolen(ST(0));
|
||||||
|
QServ->SendQuery(Query);
|
||||||
|
}
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS__qs_player_event);
|
||||||
|
XS(XS__qs_player_event)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 2){
|
||||||
|
Perl_croak(aTHX_ "Usage: qs_player_event(char_id, event_desc)");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
int char_id = (int)SvIV(ST(0));
|
||||||
|
std::string event_desc = (std::string)SvPV_nolen(ST(1));
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Quest, char_id, event_desc);
|
||||||
|
}
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is the callback perl will look for to setup the
|
This is the callback perl will look for to setup the
|
||||||
quest package's XSUBs
|
quest package's XSUBs
|
||||||
@ -3591,6 +3623,8 @@ EXTERN_C XS(boot_quest)
|
|||||||
newXS(strcpy(buf, "enablerecipe"), XS__enablerecipe, file);
|
newXS(strcpy(buf, "enablerecipe"), XS__enablerecipe, file);
|
||||||
newXS(strcpy(buf, "disablerecipe"), XS__disablerecipe, file);
|
newXS(strcpy(buf, "disablerecipe"), XS__disablerecipe, file);
|
||||||
newXS(strcpy(buf, "clear_npctype_cache"), XS__clear_npctype_cache, file);
|
newXS(strcpy(buf, "clear_npctype_cache"), XS__clear_npctype_cache, file);
|
||||||
|
newXS(strcpy(buf, "qs_send_query"), XS__qs_send_query, file);
|
||||||
|
newXS(strcpy(buf, "qs_player_event"), XS__qs_player_event, file);
|
||||||
XSRETURN_YES;
|
XSRETURN_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1476,7 +1476,7 @@ void EntityList::QueueClientsStatus(Mob *sender, const EQApplicationPacket *app,
|
|||||||
void EntityList::DuelMessage(Mob *winner, Mob *loser, bool flee)
|
void EntityList::DuelMessage(Mob *winner, Mob *loser, bool flee)
|
||||||
{
|
{
|
||||||
if (winner->GetLevelCon(winner->GetLevel(), loser->GetLevel()) > 2) {
|
if (winner->GetLevelCon(winner->GetLevel(), loser->GetLevel()) > 2) {
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(winner);
|
args.push_back(winner);
|
||||||
args.push_back(loser);
|
args.push_back(loser);
|
||||||
|
|
||||||
@ -1598,7 +1598,7 @@ Corpse *EntityList::GetCorpseByName(const char *name)
|
|||||||
|
|
||||||
Spawn2 *EntityList::GetSpawnByID(uint32 id)
|
Spawn2 *EntityList::GetSpawnByID(uint32 id)
|
||||||
{
|
{
|
||||||
if (!zone)
|
if (!zone || !zone->IsLoaded())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
LinkedListIterator<Spawn2 *> iterator(zone->spawn2_list);
|
LinkedListIterator<Spawn2 *> iterator(zone->spawn2_list);
|
||||||
@ -2847,7 +2847,7 @@ void EntityList::ClearFeignAggro(Mob *targ)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (targ->IsClient()) {
|
if (targ->IsClient()) {
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(it->second);
|
args.push_back(it->second);
|
||||||
int i = parse->EventPlayer(EVENT_FEIGN_DEATH, targ->CastToClient(), "", 0, &args);
|
int i = parse->EventPlayer(EVENT_FEIGN_DEATH, targ->CastToClient(), "", 0, &args);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
@ -3244,7 +3244,7 @@ void EntityList::ProcessMove(Client *c, float x, float y, float z)
|
|||||||
if (evt.npc) {
|
if (evt.npc) {
|
||||||
parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0);
|
parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0);
|
||||||
} else {
|
} else {
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(&evt.area_id);
|
args.push_back(&evt.area_id);
|
||||||
args.push_back(&evt.area_type);
|
args.push_back(&evt.area_type);
|
||||||
parse->EventPlayer(evt.event_id, evt.client, "", 0, &args);
|
parse->EventPlayer(evt.event_id, evt.client, "", 0, &args);
|
||||||
@ -3298,7 +3298,7 @@ void EntityList::ProcessMove(NPC *n, float x, float y, float z)
|
|||||||
|
|
||||||
for (auto iter = events.begin(); iter != events.end(); ++iter) {
|
for (auto iter = events.begin(); iter != events.end(); ++iter) {
|
||||||
quest_proximity_event& evt = (*iter);
|
quest_proximity_event& evt = (*iter);
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(&evt.area_id);
|
args.push_back(&evt.area_id);
|
||||||
args.push_back(&evt.area_type);
|
args.push_back(&evt.area_type);
|
||||||
parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0, &args);
|
parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0, &args);
|
||||||
@ -4170,6 +4170,20 @@ void EntityList::SignalAllClients(uint32 data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16 EntityList::GetClientCount(){
|
||||||
|
uint16 ClientCount = 0;
|
||||||
|
std::list<Client*> client_list;
|
||||||
|
entity_list.GetClientList(client_list);
|
||||||
|
std::list<Client*>::iterator iter = client_list.begin();
|
||||||
|
while (iter != client_list.end()) {
|
||||||
|
Client *entry = (*iter);
|
||||||
|
entry->GetCleanName();
|
||||||
|
ClientCount++;
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
return ClientCount;
|
||||||
|
}
|
||||||
|
|
||||||
void EntityList::GetMobList(std::list<Mob *> &m_list)
|
void EntityList::GetMobList(std::list<Mob *> &m_list)
|
||||||
{
|
{
|
||||||
m_list.clear();
|
m_list.clear();
|
||||||
|
|||||||
@ -398,6 +398,7 @@ public:
|
|||||||
void UpdateFindableNPCState(NPC *n, bool Remove);
|
void UpdateFindableNPCState(NPC *n, bool Remove);
|
||||||
void HideCorpses(Client *c, uint8 CurrentMode, uint8 NewMode);
|
void HideCorpses(Client *c, uint8 CurrentMode, uint8 NewMode);
|
||||||
|
|
||||||
|
uint16 GetClientCount();
|
||||||
void GetMobList(std::list<Mob*> &m_list);
|
void GetMobList(std::list<Mob*> &m_list);
|
||||||
void GetNPCList(std::list<NPC*> &n_list);
|
void GetNPCList(std::list<NPC*> &n_list);
|
||||||
void GetMercList(std::list<Merc*> &n_list);
|
void GetMercList(std::list<Merc*> &n_list);
|
||||||
|
|||||||
117
zone/exp.cpp
117
zone/exp.cpp
@ -22,6 +22,9 @@
|
|||||||
#include "../common/string_util.h"
|
#include "../common/string_util.h"
|
||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
|
|
||||||
static uint32 MaxBankedGroupLeadershipPoints(int Level)
|
static uint32 MaxBankedGroupLeadershipPoints(int Level)
|
||||||
@ -212,7 +215,6 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
return; // Must be invalid class/race
|
return; // Must be invalid class/race
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((set_exp + set_aaxp) > (m_pp.exp+m_pp.expAA)) {
|
if ((set_exp + set_aaxp) > (m_pp.exp+m_pp.expAA)) {
|
||||||
if (isrezzexp)
|
if (isrezzexp)
|
||||||
this->Message_StringID(MT_Experience, REZ_REGAIN);
|
this->Message_StringID(MT_Experience, REZ_REGAIN);
|
||||||
@ -288,6 +290,14 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
//Message(15, "You have gained %d skill points!!", m_pp.aapoints - last_unspentAA);
|
//Message(15, "You have gained %d skill points!!", m_pp.aapoints - last_unspentAA);
|
||||||
char val1[20]={0};
|
char val1[20]={0};
|
||||||
Message_StringID(MT_Experience, GAIN_ABILITY_POINT,ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2.
|
Message_StringID(MT_Experience, GAIN_ABILITY_POINT,ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2.
|
||||||
|
|
||||||
|
/* QS: PlayerLogAARate */
|
||||||
|
if (RuleB(QueryServ, PlayerLogAARate)){
|
||||||
|
int add_points = (m_pp.aapoints - last_unspentAA);
|
||||||
|
std::string query = StringFormat("INSERT INTO `qs_player_aa_rate_hourly` (char_id, aa_count, hour_time) VALUES (%i, %i, UNIX_TIMESTAMP() - MOD(UNIX_TIMESTAMP(), 3600)) ON DUPLICATE KEY UPDATE `aa_count` = `aa_count` + %i", this->CharacterID(), add_points, add_points);
|
||||||
|
QServ->SendQuery(query.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
//Message(15, "You now have %d skill points available to spend.", m_pp.aapoints);
|
//Message(15, "You now have %d skill points available to spend.", m_pp.aapoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,12 +309,10 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
if(check_level > maxlevel) {
|
if(check_level > maxlevel) {
|
||||||
check_level = maxlevel;
|
check_level = maxlevel;
|
||||||
|
|
||||||
if(RuleB(Character, KeepLevelOverMax))
|
if(RuleB(Character, KeepLevelOverMax)) {
|
||||||
{
|
|
||||||
set_exp = GetEXPForLevel(GetLevel()+1);
|
set_exp = GetEXPForLevel(GetLevel()+1);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
set_exp = GetEXPForLevel(maxlevel);
|
set_exp = GetEXPForLevel(maxlevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -314,8 +322,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
if(MaxLevel){
|
if(MaxLevel){
|
||||||
if(GetLevel() >= MaxLevel){
|
if(GetLevel() >= MaxLevel){
|
||||||
uint32 expneeded = GetEXPForLevel(MaxLevel);
|
uint32 expneeded = GetEXPForLevel(MaxLevel);
|
||||||
if(set_exp > expneeded)
|
if(set_exp > expneeded) {
|
||||||
{
|
|
||||||
set_exp = expneeded;
|
set_exp = expneeded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -327,11 +334,11 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
if (GetLevel() == check_level-1){
|
if (GetLevel() == check_level-1){
|
||||||
Message_StringID(MT_Experience, GAIN_LEVEL,ConvertArray(check_level,val1));
|
Message_StringID(MT_Experience, GAIN_LEVEL,ConvertArray(check_level,val1));
|
||||||
SendLevelAppearance();
|
SendLevelAppearance();
|
||||||
//Message(15, "You have gained a level! Welcome to level %i!", check_level);
|
/* Message(15, "You have gained a level! Welcome to level %i!", check_level); */
|
||||||
}
|
}
|
||||||
if (GetLevel() == check_level){
|
if (GetLevel() == check_level){
|
||||||
Message_StringID(MT_Experience, LOSE_LEVEL,ConvertArray(check_level,val1));
|
Message_StringID(MT_Experience, LOSE_LEVEL,ConvertArray(check_level,val1));
|
||||||
//Message(15, "You lost a level! You are now level %i!", check_level);
|
/* Message(15, "You lost a level! You are now level %i!", check_level); */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Message(15, "Welcome to level %i!", check_level);
|
Message(15, "Welcome to level %i!", check_level);
|
||||||
@ -352,8 +359,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
//If were at max level then stop gaining experience if we make it to the cap
|
//If were at max level then stop gaining experience if we make it to the cap
|
||||||
if(GetLevel() == maxlevel - 1){
|
if(GetLevel() == maxlevel - 1){
|
||||||
uint32 expneeded = GetEXPForLevel(maxlevel);
|
uint32 expneeded = GetEXPForLevel(maxlevel);
|
||||||
if(set_exp > expneeded)
|
if(set_exp > expneeded) {
|
||||||
{
|
|
||||||
set_exp = expneeded;
|
set_exp = expneeded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -405,15 +411,13 @@ void Client::SetLevel(uint8 set_level, bool command)
|
|||||||
|
|
||||||
level = set_level;
|
level = set_level;
|
||||||
|
|
||||||
if(IsRaidGrouped())
|
if(IsRaidGrouped()) {
|
||||||
{
|
|
||||||
Raid *r = this->GetRaid();
|
Raid *r = this->GetRaid();
|
||||||
if(r){
|
if(r){
|
||||||
r->UpdateLevel(GetName(), set_level);
|
r->UpdateLevel(GetName(), set_level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(set_level > m_pp.level2)
|
if(set_level > m_pp.level2) {
|
||||||
{
|
|
||||||
if(m_pp.level2 == 0)
|
if(m_pp.level2 == 0)
|
||||||
m_pp.points += 5;
|
m_pp.points += 5;
|
||||||
else
|
else
|
||||||
@ -423,6 +427,18 @@ void Client::SetLevel(uint8 set_level, bool command)
|
|||||||
}
|
}
|
||||||
if(set_level > m_pp.level) {
|
if(set_level > m_pp.level) {
|
||||||
parse->EventPlayer(EVENT_LEVEL_UP, this, "", 0);
|
parse->EventPlayer(EVENT_LEVEL_UP, this, "", 0);
|
||||||
|
/* QS: PlayerLogLevels */
|
||||||
|
if (RuleB(QueryServ, PlayerLogLevels)){
|
||||||
|
std::string event_desc = StringFormat("Leveled UP :: to Level:%i from Level:%i in zoneid:%i instid:%i", set_level, m_pp.level, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Levels, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (set_level < m_pp.level){
|
||||||
|
/* QS: PlayerLogLevels */
|
||||||
|
if (RuleB(QueryServ, PlayerLogLevels)){
|
||||||
|
std::string event_desc = StringFormat("Leveled DOWN :: to Level:%i from Level:%i in zoneid:%i instid:%i", set_level, m_pp.level, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Levels, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pp.level = set_level;
|
m_pp.level = set_level;
|
||||||
@ -432,34 +448,34 @@ void Client::SetLevel(uint8 set_level, bool command)
|
|||||||
lu->exp = 0;
|
lu->exp = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float tmpxp = (float) ( (float) m_pp.exp - GetEXPForLevel( GetLevel() )) /
|
float tmpxp = (float) ( (float) m_pp.exp - GetEXPForLevel( GetLevel() )) / ( (float) GetEXPForLevel(GetLevel()+1) - GetEXPForLevel(GetLevel()));
|
||||||
( (float) GetEXPForLevel(GetLevel()+1) - GetEXPForLevel(GetLevel()));
|
|
||||||
lu->exp = (uint32)(330.0f * tmpxp);
|
lu->exp = (uint32)(330.0f * tmpxp);
|
||||||
}
|
}
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
this->SendAppearancePacket(AT_WhoLevel, set_level); // who level change
|
this->SendAppearancePacket(AT_WhoLevel, set_level); // who level change
|
||||||
|
|
||||||
LogFile->write(EQEMuLog::Normal,"Setting Level for %s to %i", GetName(), set_level);
|
LogFile->write(EQEMuLog::Normal,"Setting Level for %s to %i", GetName(), set_level);
|
||||||
|
|
||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
if(!RuleB(Character, HealOnLevel))
|
|
||||||
{
|
if(!RuleB(Character, HealOnLevel)) {
|
||||||
int mhp = CalcMaxHP();
|
int mhp = CalcMaxHP();
|
||||||
if(GetHP() > mhp)
|
if(GetHP() > mhp)
|
||||||
SetHP(mhp);
|
SetHP(mhp);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
SetHP(CalcMaxHP()); // Why not, lets give them a free heal
|
SetHP(CalcMaxHP()); // Why not, lets give them a free heal
|
||||||
}
|
}
|
||||||
|
|
||||||
DoTributeUpdate();
|
DoTributeUpdate();
|
||||||
SendHPUpdate();
|
SendHPUpdate();
|
||||||
SetMana(CalcMaxMana());
|
SetMana(CalcMaxMana());
|
||||||
UpdateWho();
|
UpdateWho();
|
||||||
if(GetMerc())
|
|
||||||
UpdateMercLevel();
|
if(GetMerc())
|
||||||
|
UpdateMercLevel();
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,23 +524,13 @@ uint32 Client::GetEXPForLevel(uint16 check_level)
|
|||||||
uint32 finalxp = uint32(base * mod);
|
uint32 finalxp = uint32(base * mod);
|
||||||
finalxp = mod_client_xp_for_level(finalxp, check_level);
|
finalxp = mod_client_xp_for_level(finalxp, check_level);
|
||||||
|
|
||||||
return(finalxp);
|
return finalxp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::AddLevelBasedExp(uint8 exp_percentage, uint8 max_level) {
|
void Client::AddLevelBasedExp(uint8 exp_percentage, uint8 max_level) {
|
||||||
|
if (exp_percentage > 100) { exp_percentage = 100; }
|
||||||
if (exp_percentage > 100)
|
if (!max_level || GetLevel() < max_level) { max_level = GetLevel(); }
|
||||||
{
|
|
||||||
exp_percentage = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!max_level || GetLevel() < max_level)
|
|
||||||
{
|
|
||||||
max_level = GetLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 newexp = GetEXP() + ((GetEXPForLevel(max_level + 1) - GetEXPForLevel(max_level)) * exp_percentage / 100);
|
uint32 newexp = GetEXP() + ((GetEXPForLevel(max_level + 1) - GetEXPForLevel(max_level)) * exp_percentage / 100);
|
||||||
|
|
||||||
SetEXP(newexp, GetAAXP());
|
SetEXP(newexp, GetAAXP());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,28 +672,25 @@ void Client::SendLeadershipEXPUpdate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 Client::GetCharMaxLevelFromQGlobal() {
|
uint32 Client::GetCharMaxLevelFromQGlobal() {
|
||||||
|
QGlobalCache *char_c = nullptr;
|
||||||
|
char_c = this->GetQGlobals();
|
||||||
|
|
||||||
QGlobalCache *char_c = nullptr;
|
std::list<QGlobal> globalMap;
|
||||||
char_c = this->GetQGlobals();
|
uint32 ntype = 0;
|
||||||
|
|
||||||
std::list<QGlobal> globalMap;
|
if(char_c) {
|
||||||
uint32 ntype = 0;
|
QGlobalCache::Combine(globalMap, char_c->GetBucket(), ntype, this->CharacterID(), zone->GetZoneID());
|
||||||
|
}
|
||||||
|
|
||||||
if(char_c)
|
std::list<QGlobal>::iterator iter = globalMap.begin();
|
||||||
{
|
uint32 gcount = 0;
|
||||||
QGlobalCache::Combine(globalMap, char_c->GetBucket(), ntype, this->CharacterID(), zone->GetZoneID());
|
while(iter != globalMap.end()) {
|
||||||
|
if((*iter).name.compare("CharMaxLevel") == 0){
|
||||||
|
return atoi((*iter).value.c_str());
|
||||||
}
|
}
|
||||||
|
++iter;
|
||||||
|
++gcount;
|
||||||
|
}
|
||||||
|
|
||||||
std::list<QGlobal>::iterator iter = globalMap.begin();
|
return false;
|
||||||
uint32 gcount = 0;
|
|
||||||
while(iter != globalMap.end())
|
|
||||||
{
|
|
||||||
if((*iter).name.compare("CharMaxLevel") == 0){
|
|
||||||
return atoi((*iter).value.c_str());
|
|
||||||
}
|
|
||||||
++iter;
|
|
||||||
++gcount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false; // Default is false
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -357,7 +357,7 @@ void Client::GoFish()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(inst);
|
args.push_back(inst);
|
||||||
parse->EventPlayer(EVENT_FISH_SUCCESS, this, "", inst != nullptr ? inst->GetItem()->ID : 0, &args);
|
parse->EventPlayer(EVENT_FISH_SUCCESS, this, "", inst != nullptr ? inst->GetItem()->ID : 0, &args);
|
||||||
}
|
}
|
||||||
@ -471,7 +471,7 @@ void Client::ForageItem(bool guarantee) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(inst);
|
args.push_back(inst);
|
||||||
parse->EventPlayer(EVENT_FORAGE_SUCCESS, this, "", inst ? inst->GetItem()->ID : 0, &args);
|
parse->EventPlayer(EVENT_FORAGE_SUCCESS, this, "", inst ? inst->GetItem()->ID : 0, &args);
|
||||||
|
|
||||||
|
|||||||
@ -193,11 +193,10 @@ void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinu
|
|||||||
|
|
||||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||||
if (members[i] != nullptr && members[i]->IsClient()) { // If Group Member is Client
|
if (members[i] != nullptr && members[i]->IsClient()) { // If Group Member is Client
|
||||||
Client *c = members[i]->CastToClient();
|
Client *c = members[i]->CastToClient();
|
||||||
//I could not get MoneyOnCorpse to work, so we use this
|
//I could not get MoneyOnCorpse to work, so we use this
|
||||||
c->AddMoneyToPP(cpsplit, spsplit, gpsplit, ppsplit, true);
|
c->AddMoneyToPP(cpsplit, spsplit, gpsplit, ppsplit, true);
|
||||||
|
c->Message(2, msg.c_str());
|
||||||
c->Message(2, msg.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -644,104 +644,66 @@ GuildBankManager::~GuildBankManager()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GuildBankManager::Load(uint32 GuildID)
|
bool GuildBankManager::Load(uint32 guildID)
|
||||||
{
|
{
|
||||||
const char *LoadQuery = "SELECT `area`, `slot`, `itemid`, `qty`, `donator`, `permissions`, `whofor` from `guild_bank` "
|
|
||||||
"WHERE `guildid` = %i";
|
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
|
|
||||||
char* query = 0;
|
|
||||||
|
|
||||||
MYSQL_RES *result;
|
|
||||||
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
if(database.RunQuery(query, MakeAnyLenString(&query, LoadQuery, GuildID), errbuf, &result))
|
|
||||||
{
|
|
||||||
GuildBank *Bank = new GuildBank;
|
|
||||||
|
|
||||||
Bank->GuildID = GuildID;
|
|
||||||
|
|
||||||
for(int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i)
|
|
||||||
Bank->Items.MainArea[i].ItemID = 0;
|
|
||||||
|
|
||||||
for(int i = 0; i < GUILD_BANK_DEPOSIT_AREA_SIZE; ++i)
|
|
||||||
Bank->Items.DepositArea[i].ItemID = 0;
|
|
||||||
|
|
||||||
char Donator[64], WhoFor[64];
|
|
||||||
|
|
||||||
while((row = mysql_fetch_row(result)))
|
|
||||||
{
|
|
||||||
int Area = atoi(row[0]);
|
|
||||||
|
|
||||||
int Slot = atoi(row[1]);
|
|
||||||
|
|
||||||
int ItemID = atoi(row[2]);
|
|
||||||
|
|
||||||
int Qty = atoi(row[3]);
|
|
||||||
|
|
||||||
if(row[4])
|
|
||||||
strn0cpy(Donator, row[4], sizeof(Donator));
|
|
||||||
else
|
|
||||||
Donator[0] = '\0';
|
|
||||||
|
|
||||||
int Permissions = atoi(row[5]);
|
|
||||||
|
|
||||||
if(row[6])
|
|
||||||
strn0cpy(WhoFor, row[6], sizeof(WhoFor));
|
|
||||||
else
|
|
||||||
WhoFor[0] = '\0';
|
|
||||||
|
|
||||||
if(Area == GuildBankMainArea)
|
|
||||||
{
|
|
||||||
if((Slot >= 0) && (Slot < GUILD_BANK_MAIN_AREA_SIZE))
|
|
||||||
{
|
|
||||||
Bank->Items.MainArea[Slot].ItemID = ItemID;
|
|
||||||
|
|
||||||
Bank->Items.MainArea[Slot].Quantity = Qty;
|
|
||||||
|
|
||||||
strn0cpy(Bank->Items.MainArea[Slot].Donator, Donator, sizeof(Donator));
|
|
||||||
|
|
||||||
Bank->Items.MainArea[Slot].Permissions = Permissions;
|
|
||||||
|
|
||||||
strn0cpy(Bank->Items.MainArea[Slot].WhoFor, WhoFor, sizeof(WhoFor));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if((Slot >= 0 ) && (Slot < GUILD_BANK_DEPOSIT_AREA_SIZE))
|
|
||||||
{
|
|
||||||
Bank->Items.DepositArea[Slot].ItemID = ItemID;
|
|
||||||
|
|
||||||
Bank->Items.DepositArea[Slot].Quantity = Qty;
|
|
||||||
|
|
||||||
strn0cpy(Bank->Items.DepositArea[Slot].Donator, Donator, sizeof(Donator));
|
|
||||||
|
|
||||||
Bank->Items.DepositArea[Slot].Permissions = Permissions;
|
|
||||||
|
|
||||||
strn0cpy(Bank->Items.DepositArea[Slot].WhoFor, WhoFor, sizeof(WhoFor));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
Banks.push_back(Bank);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_log(GUILDS__BANK_ERROR, "Error Loading guild bank: %s, %s", query, errbuf);
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
|
std::string query = StringFormat("SELECT `area`, `slot`, `itemid`, `qty`, `donator`, `permissions`, `whofor` "
|
||||||
|
"FROM `guild_bank` WHERE `guildid` = %i", guildID);
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if(!results.Success()) {
|
||||||
|
_log(GUILDS__BANK_ERROR, "Error Loading guild bank: %s, %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
GuildBank *bank = new GuildBank;
|
||||||
|
|
||||||
|
bank->GuildID = guildID;
|
||||||
|
|
||||||
|
for(int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i)
|
||||||
|
bank->Items.MainArea[i].ItemID = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < GUILD_BANK_DEPOSIT_AREA_SIZE; ++i)
|
||||||
|
bank->Items.DepositArea[i].ItemID = 0;
|
||||||
|
|
||||||
|
char donator[64], whoFor[64];
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row)
|
||||||
|
{
|
||||||
|
int area = atoi(row[0]);
|
||||||
|
int slot = atoi(row[1]);
|
||||||
|
int itemID = atoi(row[2]);
|
||||||
|
int qty = atoi(row[3]);
|
||||||
|
|
||||||
|
if(row[4])
|
||||||
|
strn0cpy(donator, row[4], sizeof(donator));
|
||||||
|
else
|
||||||
|
donator[0] = '\0';
|
||||||
|
|
||||||
|
int permissions = atoi(row[5]);
|
||||||
|
|
||||||
|
if(row[6])
|
||||||
|
strn0cpy(whoFor, row[6], sizeof(whoFor));
|
||||||
|
else
|
||||||
|
whoFor[0] = '\0';
|
||||||
|
|
||||||
|
if(slot < 0 ||
|
||||||
|
((area != GuildBankMainArea || slot >= GUILD_BANK_MAIN_AREA_SIZE) ||
|
||||||
|
(area == GuildBankMainArea || slot >= GUILD_BANK_DEPOSIT_AREA_SIZE)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bank->Items.MainArea[slot].ItemID = itemID;
|
||||||
|
bank->Items.MainArea[slot].Quantity = qty;
|
||||||
|
|
||||||
|
strn0cpy(bank->Items.MainArea[slot].Donator, donator, sizeof(donator));
|
||||||
|
|
||||||
|
bank->Items.MainArea[slot].Permissions = permissions;
|
||||||
|
|
||||||
|
strn0cpy(bank->Items.MainArea[slot].WhoFor, whoFor, sizeof(whoFor));
|
||||||
|
}
|
||||||
|
|
||||||
|
Banks.push_back(bank);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GuildBankManager::IsLoaded(uint32 GuildID)
|
bool GuildBankManager::IsLoaded(uint32 GuildID)
|
||||||
@ -973,156 +935,127 @@ bool GuildBankManager::AddItem(uint32 GuildID, uint8 Area, uint32 ItemID, int32
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GuildBankManager::Promote(uint32 GuildID, int SlotID)
|
int GuildBankManager::Promote(uint32 guildID, int slotID)
|
||||||
{
|
{
|
||||||
if((SlotID < 0) || (SlotID > (GUILD_BANK_DEPOSIT_AREA_SIZE - 1)))
|
if((slotID < 0) || (slotID > (GUILD_BANK_DEPOSIT_AREA_SIZE - 1)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
std::list<GuildBank*>::iterator Iterator = GetGuildBank(GuildID);
|
auto iter = GetGuildBank(guildID);
|
||||||
|
|
||||||
if(Iterator == Banks.end())
|
if(iter == Banks.end())
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
if((*Iterator)->Items.DepositArea[SlotID].ItemID == 0)
|
if((*iter)->Items.DepositArea[slotID].ItemID == 0)
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
int MainSlot = -1;
|
int mainSlot = -1;
|
||||||
|
|
||||||
for(int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i)
|
for(int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i)
|
||||||
if((*Iterator)->Items.MainArea[i].ItemID == 0)
|
if((*iter)->Items.MainArea[i].ItemID == 0) {
|
||||||
{
|
mainSlot = i;
|
||||||
MainSlot = i;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(MainSlot == -1)
|
if(mainSlot == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
(*iter)->Items.MainArea[mainSlot].ItemID = (*iter)->Items.DepositArea[slotID].ItemID;
|
||||||
|
(*iter)->Items.MainArea[mainSlot].Quantity = (*iter)->Items.DepositArea[slotID].Quantity;
|
||||||
|
(*iter)->Items.MainArea[mainSlot].Permissions = (*iter)->Items.DepositArea[slotID].Permissions;
|
||||||
|
|
||||||
(*Iterator)->Items.MainArea[MainSlot].ItemID = (*Iterator)->Items.DepositArea[SlotID].ItemID;
|
strn0cpy((*iter)->Items.MainArea[mainSlot].Donator, (*iter)->Items.DepositArea[slotID].Donator, sizeof((*iter)->Items.MainArea[mainSlot].Donator));
|
||||||
|
strn0cpy((*iter)->Items.MainArea[mainSlot].WhoFor, (*iter)->Items.DepositArea[slotID].WhoFor, sizeof((*iter)->Items.MainArea[mainSlot].WhoFor));
|
||||||
(*Iterator)->Items.MainArea[MainSlot].Quantity = (*Iterator)->Items.DepositArea[SlotID].Quantity;
|
|
||||||
|
|
||||||
strn0cpy((*Iterator)->Items.MainArea[MainSlot].Donator, (*Iterator)->Items.DepositArea[SlotID].Donator, sizeof((*Iterator)->Items.MainArea[MainSlot].Donator));
|
|
||||||
(*Iterator)->Items.MainArea[MainSlot].Permissions = (*Iterator)->Items.DepositArea[SlotID].Permissions;
|
|
||||||
|
|
||||||
strn0cpy((*Iterator)->Items.MainArea[MainSlot].WhoFor, (*Iterator)->Items.DepositArea[SlotID].WhoFor, sizeof((*Iterator)->Items.MainArea[MainSlot].WhoFor));
|
|
||||||
|
|
||||||
const char *Query="UPDATE `guild_bank` SET `area` = 1, `slot` = %i WHERE `guildid` = %i AND `area` = 0 AND `slot` = %i LIMIT 1";
|
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
|
|
||||||
char* query = 0;
|
|
||||||
|
|
||||||
if(!database.RunQuery(query, MakeAnyLenString(&query, Query, MainSlot, GuildID, SlotID), errbuf))
|
|
||||||
{
|
|
||||||
_log(GUILDS__BANK_ERROR, "error promoting item: %s : %s", query, errbuf);
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
|
std::string query = StringFormat("UPDATE `guild_bank` SET `area` = 1, `slot` = %i "
|
||||||
|
"WHERE `guildid` = %i AND `area` = 0 AND `slot` = %i "
|
||||||
|
"LIMIT 1", mainSlot, guildID, slotID);
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
_log(GUILDS__BANK_ERROR, "error promoting item: %s : %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete_array(query);
|
(*iter)->Items.DepositArea[slotID].ItemID = 0;
|
||||||
|
|
||||||
(*Iterator)->Items.DepositArea[SlotID].ItemID = 0;
|
const Item_Struct *Item = database.GetItem((*iter)->Items.MainArea[mainSlot].ItemID);
|
||||||
|
|
||||||
const Item_Struct *Item = database.GetItem((*Iterator)->Items.MainArea[MainSlot].ItemID);
|
|
||||||
|
|
||||||
GuildBankItemUpdate_Struct gbius;
|
GuildBankItemUpdate_Struct gbius;
|
||||||
|
|
||||||
if(!Item->Stackable)
|
if(!Item->Stackable)
|
||||||
gbius.Init(GuildBankItemUpdate, 1, MainSlot, GuildBankMainArea, 1, Item->ID, Item->Icon, 1, 0, 0, 0);
|
gbius.Init(GuildBankItemUpdate, 1, mainSlot, GuildBankMainArea, 1, Item->ID, Item->Icon, 1, 0, 0, 0);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if((*Iterator)->Items.MainArea[MainSlot].Quantity == Item->StackSize)
|
if((*iter)->Items.MainArea[mainSlot].Quantity == Item->StackSize)
|
||||||
gbius.Init(GuildBankItemUpdate, 1, MainSlot, GuildBankMainArea, 1, Item->ID, Item->Icon,
|
gbius.Init(GuildBankItemUpdate, 1, mainSlot, GuildBankMainArea, 1, Item->ID, Item->Icon,
|
||||||
(*Iterator)->Items.MainArea[MainSlot].Quantity, 0, 0, 0);
|
(*iter)->Items.MainArea[mainSlot].Quantity, 0, 0, 0);
|
||||||
else
|
else
|
||||||
gbius.Init(GuildBankItemUpdate, 1, MainSlot, GuildBankMainArea, 1, Item->ID, Item->Icon,
|
gbius.Init(GuildBankItemUpdate, 1, mainSlot, GuildBankMainArea, 1, Item->ID, Item->Icon,
|
||||||
(*Iterator)->Items.MainArea[MainSlot].Quantity, 0, 1, 0);
|
(*iter)->Items.MainArea[mainSlot].Quantity, 0, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
strn0cpy(gbius.ItemName, Item->Name, sizeof(gbius.ItemName));
|
strn0cpy(gbius.ItemName, Item->Name, sizeof(gbius.ItemName));
|
||||||
|
|
||||||
entity_list.QueueClientsGuildBankItemUpdate(&gbius, GuildID);
|
entity_list.QueueClientsGuildBankItemUpdate(&gbius, guildID);
|
||||||
|
|
||||||
gbius.Init(GuildBankItemUpdate, 1, SlotID, GuildBankDepositArea, 0, 0, 0, 0, 0, 0, 0);
|
gbius.Init(GuildBankItemUpdate, 1, slotID, GuildBankDepositArea, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
entity_list.QueueClientsGuildBankItemUpdate(&gbius, GuildID);
|
entity_list.QueueClientsGuildBankItemUpdate(&gbius, guildID);
|
||||||
|
|
||||||
return MainSlot;
|
return mainSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuildBankManager::SetPermissions(uint32 GuildID, uint16 SlotID, uint32 Permissions, const char *MemberName)
|
void GuildBankManager::SetPermissions(uint32 guildID, uint16 slotID, uint32 permissions, const char *memberName)
|
||||||
{
|
{
|
||||||
if((SlotID > (GUILD_BANK_MAIN_AREA_SIZE - 1)))
|
if((slotID > (GUILD_BANK_MAIN_AREA_SIZE - 1)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::list<GuildBank*>::iterator Iterator = GetGuildBank(GuildID);
|
auto iter = GetGuildBank(guildID);
|
||||||
|
|
||||||
if(Iterator == Banks.end())
|
if(iter == Banks.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if((*iter)->Items.MainArea[slotID].ItemID == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string query = StringFormat("UPDATE `guild_bank` SET `permissions` = %i, `whofor` = '%s' "
|
||||||
|
"WHERE `guildid` = %i AND `area` = 1 AND `slot` = %i LIMIT 1",
|
||||||
|
permissions, memberName, guildID, slotID);
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if(!results.Success())
|
||||||
{
|
{
|
||||||
|
_log(GUILDS__BANK_ERROR, "error changing permissions: %s : %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((*Iterator)->Items.MainArea[SlotID].ItemID == 0)
|
(*iter)->Items.MainArea[slotID].Permissions = permissions;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *Query="UPDATE `guild_bank` SET `permissions` = %i, `whofor` = '%s' WHERE `guildid` = %i AND `area` = 1 AND `slot` = %i LIMIT 1";
|
if(permissions == GuildBankSingleMember)
|
||||||
|
strn0cpy((*iter)->Items.MainArea[slotID].WhoFor, memberName, sizeof((*iter)->Items.MainArea[slotID].WhoFor));
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
|
|
||||||
char* query = 0;
|
|
||||||
|
|
||||||
if(!database.RunQuery(query, MakeAnyLenString(&query, Query, Permissions, MemberName, GuildID, SlotID), errbuf))
|
|
||||||
{
|
|
||||||
_log(GUILDS__BANK_ERROR, "error changing permissions: %s : %s", query, errbuf);
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
(*Iterator)->Items.MainArea[SlotID].Permissions = Permissions;
|
|
||||||
|
|
||||||
if(Permissions == GuildBankSingleMember)
|
|
||||||
strn0cpy((*Iterator)->Items.MainArea[SlotID].WhoFor, MemberName, sizeof((*Iterator)->Items.MainArea[SlotID].WhoFor));
|
|
||||||
else
|
else
|
||||||
(*Iterator)->Items.MainArea[SlotID].WhoFor[0] = '\0';
|
(*iter)->Items.MainArea[slotID].WhoFor[0] = '\0';
|
||||||
|
|
||||||
|
const Item_Struct *Item = database.GetItem((*iter)->Items.MainArea[slotID].ItemID);
|
||||||
const Item_Struct *Item = database.GetItem((*Iterator)->Items.MainArea[SlotID].ItemID);
|
|
||||||
|
|
||||||
GuildBankItemUpdate_Struct gbius;
|
GuildBankItemUpdate_Struct gbius;
|
||||||
|
|
||||||
if(!Item->Stackable)
|
if(!Item->Stackable)
|
||||||
gbius.Init(GuildBankItemUpdate, 1, SlotID, GuildBankMainArea, 1, Item->ID, Item->Icon, 1, (*Iterator)->Items.MainArea[SlotID].Permissions, 0, 0);
|
gbius.Init(GuildBankItemUpdate, 1, slotID, GuildBankMainArea, 1, Item->ID, Item->Icon, 1, (*iter)->Items.MainArea[slotID].Permissions, 0, 0);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if((*Iterator)->Items.MainArea[SlotID].Quantity == Item->StackSize)
|
if((*iter)->Items.MainArea[slotID].Quantity == Item->StackSize)
|
||||||
gbius.Init(GuildBankItemUpdate, 1, SlotID, GuildBankMainArea, 1, Item->ID, Item->Icon,
|
gbius.Init(GuildBankItemUpdate, 1, slotID, GuildBankMainArea, 1, Item->ID, Item->Icon,
|
||||||
(*Iterator)->Items.MainArea[SlotID].Quantity, (*Iterator)->Items.MainArea[SlotID].Permissions, 0, 0);
|
(*iter)->Items.MainArea[slotID].Quantity, (*iter)->Items.MainArea[slotID].Permissions, 0, 0);
|
||||||
else
|
else
|
||||||
gbius.Init(GuildBankItemUpdate, 1, SlotID, GuildBankMainArea, 1, Item->ID, Item->Icon,
|
gbius.Init(GuildBankItemUpdate, 1, slotID, GuildBankMainArea, 1, Item->ID, Item->Icon,
|
||||||
(*Iterator)->Items.MainArea[SlotID].Quantity, (*Iterator)->Items.MainArea[SlotID].Permissions, 1, 0);
|
(*iter)->Items.MainArea[slotID].Quantity, (*iter)->Items.MainArea[slotID].Permissions, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
strn0cpy(gbius.ItemName, Item->Name, sizeof(gbius.ItemName));
|
strn0cpy(gbius.ItemName, Item->Name, sizeof(gbius.ItemName));
|
||||||
|
|
||||||
strn0cpy(gbius.WhoFor, (*Iterator)->Items.MainArea[SlotID].WhoFor, sizeof(gbius.WhoFor));
|
strn0cpy(gbius.WhoFor, (*iter)->Items.MainArea[slotID].WhoFor, sizeof(gbius.WhoFor));
|
||||||
|
|
||||||
entity_list.QueueClientsGuildBankItemUpdate(&gbius, GuildID);
|
entity_list.QueueClientsGuildBankItemUpdate(&gbius, guildID);
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemInst* GuildBankManager::GetItem(uint32 GuildID, uint16 Area, uint16 SlotID, uint32 Quantity)
|
ItemInst* GuildBankManager::GetItem(uint32 GuildID, uint16 Area, uint16 SlotID, uint32 Quantity)
|
||||||
@ -1208,90 +1141,73 @@ std::list<GuildBank*>::iterator GuildBankManager::GetGuildBank(uint32 GuildID)
|
|||||||
return Iterator;
|
return Iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GuildBankManager::DeleteItem(uint32 GuildID, uint16 Area, uint16 SlotID, uint32 Quantity)
|
bool GuildBankManager::DeleteItem(uint32 guildID, uint16 area, uint16 slotID, uint32 quantity)
|
||||||
{
|
{
|
||||||
std::list<GuildBank*>::iterator Iterator = GetGuildBank(GuildID);
|
auto iter = GetGuildBank(guildID);
|
||||||
|
|
||||||
if(Iterator == Banks.end())
|
if(iter == Banks.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
|
|
||||||
char* query = 0;
|
|
||||||
|
|
||||||
GuildBankItem* BankArea = nullptr;
|
GuildBankItem* BankArea = nullptr;
|
||||||
|
|
||||||
if(Area == GuildBankMainArea)
|
if(area == GuildBankMainArea)
|
||||||
{
|
{
|
||||||
if(SlotID > (GUILD_BANK_MAIN_AREA_SIZE - 1))
|
if(slotID > (GUILD_BANK_MAIN_AREA_SIZE - 1))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
BankArea = &(*Iterator)->Items.MainArea[0];
|
BankArea = &(*iter)->Items.MainArea[0];
|
||||||
}
|
} else {
|
||||||
else
|
if(slotID > (GUILD_BANK_DEPOSIT_AREA_SIZE - 1))
|
||||||
{
|
|
||||||
if(SlotID > (GUILD_BANK_DEPOSIT_AREA_SIZE - 1))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
BankArea = &(*Iterator)->Items.DepositArea[0];
|
BankArea = &(*iter)->Items.DepositArea[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool deleted = true;
|
||||||
|
|
||||||
bool Deleted = true;
|
const Item_Struct *Item = database.GetItem(BankArea[slotID].ItemID);
|
||||||
|
|
||||||
const Item_Struct *Item = database.GetItem(BankArea[SlotID].ItemID);
|
|
||||||
|
|
||||||
if(!Item->Stackable || (Quantity >= BankArea[SlotID].Quantity))
|
|
||||||
{
|
|
||||||
const char *Query = "DELETE from `guild_bank` where `guildid` = %i AND `area` = %i AND `slot` = %i LIMIT 1";
|
|
||||||
|
|
||||||
if(!database.RunQuery(query, MakeAnyLenString(&query, Query, GuildID, Area, SlotID), errbuf))
|
|
||||||
{
|
|
||||||
_log(GUILDS__BANK_ERROR, "Delete item failed. %s : %s", query, errbuf);
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
|
if(!Item->Stackable || (quantity >= BankArea[slotID].Quantity)) {
|
||||||
|
std::string query = StringFormat("DELETE FROM `guild_bank` WHERE `guildid` = %i "
|
||||||
|
"AND `area` = %i AND `slot` = %i LIMIT 1",
|
||||||
|
guildID, area, slotID);
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if(!results.Success()) {
|
||||||
|
_log(GUILDS__BANK_ERROR, "Delete item failed. %s : %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete_array(query);
|
BankArea[slotID].ItemID = 0;
|
||||||
|
|
||||||
BankArea[SlotID].ItemID = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const char *Query = "UPDATE `guild_bank` SET `qty` = %i where `guildid` = %i AND `area` = %i AND `slot` = %i LIMIT 1";
|
|
||||||
|
|
||||||
if(!database.RunQuery(query, MakeAnyLenString(&query, Query, BankArea[SlotID].Quantity - Quantity,
|
|
||||||
GuildID, Area, SlotID), errbuf))
|
|
||||||
{
|
|
||||||
_log(GUILDS__BANK_ERROR, "Update item failed. %s : %s", query, errbuf);
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
std::string query = StringFormat("UPDATE `guild_bank` SET `qty` = %i WHERE `guildid` = %i "
|
||||||
|
"AND `area` = %i AND `slot` = %i LIMIT 1",
|
||||||
|
BankArea[slotID].Quantity - quantity, guildID, area, slotID);
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if(!results.Success()) {
|
||||||
|
_log(GUILDS__BANK_ERROR, "Update item failed. %s : %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete_array(query);
|
BankArea[slotID].Quantity -= quantity;
|
||||||
|
|
||||||
BankArea[SlotID].Quantity -= Quantity;
|
deleted = false;
|
||||||
|
|
||||||
Deleted = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GuildBankItemUpdate_Struct gbius;
|
GuildBankItemUpdate_Struct gbius;
|
||||||
|
|
||||||
if(!Deleted)
|
if(!deleted)
|
||||||
{
|
{
|
||||||
gbius.Init(GuildBankItemUpdate, 1, SlotID, Area, 1, Item->ID, Item->Icon, BankArea[SlotID].Quantity, BankArea[SlotID].Permissions, 1, 0);
|
gbius.Init(GuildBankItemUpdate, 1, slotID, area, 1, Item->ID, Item->Icon, BankArea[slotID].Quantity, BankArea[slotID].Permissions, 1, 0);
|
||||||
|
|
||||||
strn0cpy(gbius.ItemName, Item->Name, sizeof(gbius.ItemName));
|
strn0cpy(gbius.ItemName, Item->Name, sizeof(gbius.ItemName));
|
||||||
|
|
||||||
strn0cpy(gbius.WhoFor, BankArea[SlotID].WhoFor, sizeof(gbius.WhoFor));
|
strn0cpy(gbius.WhoFor, BankArea[slotID].WhoFor, sizeof(gbius.WhoFor));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gbius.Init(GuildBankItemUpdate, 1, SlotID, Area, 0, 0, 0, 0, 0, 0, 0);
|
gbius.Init(GuildBankItemUpdate, 1, slotID, area, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
entity_list.QueueClientsGuildBankItemUpdate(&gbius, GuildID);
|
entity_list.QueueClientsGuildBankItemUpdate(&gbius, guildID);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -1422,26 +1338,20 @@ bool GuildBankManager::SplitStack(uint32 GuildID, uint16 SlotID, uint32 Quantity
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuildBankManager::UpdateItemQuantity(uint32 GuildID, uint16 Area, uint16 SlotID, uint32 Quantity)
|
void GuildBankManager::UpdateItemQuantity(uint32 guildID, uint16 area, uint16 slotID, uint32 quantity)
|
||||||
{
|
{
|
||||||
// Helper method for MergeStacks. Assuming all passed parameters are valid.
|
// Helper method for MergeStacks. Assuming all passed parameters are valid.
|
||||||
//
|
//
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
std::string query = StringFormat("UPDATE `guild_bank` SET `qty` = %i "
|
||||||
|
"WHERE `guildid` = %i AND `area` = %i "
|
||||||
char* query = 0;
|
"AND `slot` = %i LIMIT 1",
|
||||||
|
quantity, guildID, area, slotID);
|
||||||
const char *Query = "UPDATE `guild_bank` SET `qty` = %i where `guildid` = %i AND `area` = %i AND `slot` = %i LIMIT 1";
|
auto results = database.QueryDatabase(query);
|
||||||
|
if(!results.Success()) {
|
||||||
if(!database.RunQuery(query, MakeAnyLenString(&query, Query, Quantity, GuildID, Area, SlotID), errbuf))
|
_log(GUILDS__BANK_ERROR, "Update item quantity failed. %s : %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
{
|
|
||||||
_log(GUILDS__BANK_ERROR, "Update item quantity failed. %s : %s", query, errbuf);
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GuildBankManager::AllowedToWithdraw(uint32 GuildID, uint16 Area, uint16 SlotID, const char *Name)
|
bool GuildBankManager::AllowedToWithdraw(uint32 GuildID, uint16 Area, uint16 SlotID, const char *Name)
|
||||||
|
|||||||
@ -822,25 +822,24 @@ bool Client::PushItemOnCursor(const ItemInst& inst, bool client_update)
|
|||||||
return database.SaveCursor(CharacterID(), s, e);
|
return database.SaveCursor(CharacterID(), s, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client_update)
|
bool Client::PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client_update) {
|
||||||
{
|
|
||||||
mlog(INVENTORY__SLOTS, "Putting item %s (%d) into slot %d", inst.GetItem()->Name, inst.GetItem()->ID, slot_id);
|
mlog(INVENTORY__SLOTS, "Putting item %s (%d) into slot %d", inst.GetItem()->Name, inst.GetItem()->ID, slot_id);
|
||||||
|
|
||||||
if (slot_id == MainCursor)
|
if (slot_id == MainCursor)
|
||||||
{
|
return PushItemOnCursor(inst, client_update);
|
||||||
return PushItemOnCursor(inst,client_update);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
m_inv.PutItem(slot_id, inst);
|
m_inv.PutItem(slot_id, inst);
|
||||||
|
|
||||||
if (client_update) {
|
if (client_update)
|
||||||
SendItemPacket(slot_id, &inst, (slot_id == MainCursor) ? ItemPacketSummonItem : ItemPacketTrade);
|
SendItemPacket(slot_id, &inst, ((slot_id == MainCursor) ? ItemPacketSummonItem : ItemPacketTrade));
|
||||||
}
|
|
||||||
|
|
||||||
if (slot_id == MainCursor) {
|
if (slot_id == MainCursor) {
|
||||||
std::list<ItemInst*>::const_iterator s=m_inv.cursor_begin(),e=m_inv.cursor_end();
|
std::list<ItemInst*>::const_iterator s = m_inv.cursor_begin(), e = m_inv.cursor_end();
|
||||||
return database.SaveCursor(this->CharacterID(), s, e);
|
return database.SaveCursor(this->CharacterID(), s, e);
|
||||||
} else
|
}
|
||||||
|
else {
|
||||||
return database.SaveInventory(this->CharacterID(), &inst, slot_id);
|
return database.SaveInventory(this->CharacterID(), &inst, slot_id);
|
||||||
|
}
|
||||||
|
|
||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
}
|
}
|
||||||
@ -1539,7 +1538,7 @@ bool Client::SwapItem(MoveItem_Struct* move_in) {
|
|||||||
// Also sends trade information to other client of trade session
|
// Also sends trade information to other client of trade session
|
||||||
if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit
|
if(RuleB(QueryServ, PlayerLogMoves)) { QSSwapItemAuditor(move_in); } // QS Audit
|
||||||
|
|
||||||
trade->AddEntity(src_slot_id, dst_slot_id, move_in->number_in_stack);
|
trade->AddEntity(dst_slot_id, move_in->number_in_stack);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1134,7 +1134,7 @@ void Lua_Client::Signal(uint32 id) {
|
|||||||
|
|
||||||
void Lua_Client::AddAlternateCurrencyValue(uint32 currency, int amount) {
|
void Lua_Client::AddAlternateCurrencyValue(uint32 currency, int amount) {
|
||||||
Lua_Safe_Call_Void();
|
Lua_Safe_Call_Void();
|
||||||
self->AddAlternateCurrencyValue(currency, amount);
|
self->AddAlternateCurrencyValue(currency, amount, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lua_Client::SendWebLink(const char *site) {
|
void Lua_Client::SendWebLink(const char *site) {
|
||||||
|
|||||||
@ -220,7 +220,7 @@ LuaParser::~LuaParser() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int LuaParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
evt = ConvertLuaEvent(evt);
|
evt = ConvertLuaEvent(evt);
|
||||||
if(evt >= _LargestEventID) {
|
if(evt >= _LargestEventID) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -239,7 +239,7 @@ int LuaParser::EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int LuaParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
evt = ConvertLuaEvent(evt);
|
evt = ConvertLuaEvent(evt);
|
||||||
if(evt >= _LargestEventID) {
|
if(evt >= _LargestEventID) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -257,7 +257,7 @@ int LuaParser::EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers, luabind::adl::object *l_func) {
|
std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func) {
|
||||||
const char *sub_name = LuaEvents[evt];
|
const char *sub_name = LuaEvents[evt];
|
||||||
|
|
||||||
int start = lua_gettop(L);
|
int start = lua_gettop(L);
|
||||||
@ -316,7 +316,7 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int LuaParser::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
evt = ConvertLuaEvent(evt);
|
evt = ConvertLuaEvent(evt);
|
||||||
if(evt >= _LargestEventID) {
|
if(evt >= _LargestEventID) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -334,7 +334,7 @@ int LuaParser::EventPlayer(QuestEventID evt, Client *client, std::string data, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int LuaParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
evt = ConvertLuaEvent(evt);
|
evt = ConvertLuaEvent(evt);
|
||||||
if(evt >= _LargestEventID) {
|
if(evt >= _LargestEventID) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -352,7 +352,7 @@ int LuaParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::string d
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers, luabind::adl::object *l_func) {
|
std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func) {
|
||||||
const char *sub_name = LuaEvents[evt];
|
const char *sub_name = LuaEvents[evt];
|
||||||
int start = lua_gettop(L);
|
int start = lua_gettop(L);
|
||||||
|
|
||||||
@ -409,7 +409,7 @@ int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
evt = ConvertLuaEvent(evt);
|
evt = ConvertLuaEvent(evt);
|
||||||
if(evt >= _LargestEventID) {
|
if(evt >= _LargestEventID) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -429,7 +429,7 @@ int LuaParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *client, ItemInst *item, Mob *mob,
|
int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *client, ItemInst *item, Mob *mob,
|
||||||
std::string data, uint32 extra_data, std::vector<void*> *extra_pointers, luabind::adl::object *l_func) {
|
std::string data, uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func) {
|
||||||
const char *sub_name = LuaEvents[evt];
|
const char *sub_name = LuaEvents[evt];
|
||||||
|
|
||||||
int start = lua_gettop(L);
|
int start = lua_gettop(L);
|
||||||
@ -492,7 +492,7 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
int LuaParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
evt = ConvertLuaEvent(evt);
|
evt = ConvertLuaEvent(evt);
|
||||||
if(evt >= _LargestEventID) {
|
if(evt >= _LargestEventID) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -508,7 +508,7 @@ int LuaParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spe
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers, luabind::adl::object *l_func) {
|
std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func) {
|
||||||
const char *sub_name = LuaEvents[evt];
|
const char *sub_name = LuaEvents[evt];
|
||||||
|
|
||||||
int start = lua_gettop(L);
|
int start = lua_gettop(L);
|
||||||
@ -572,7 +572,7 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, std::vector<void*> *extra_pointers) {
|
int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
evt = ConvertLuaEvent(evt);
|
evt = ConvertLuaEvent(evt);
|
||||||
if(evt >= _LargestEventID) {
|
if(evt >= _LargestEventID) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -588,7 +588,7 @@ int LuaParser::EventEncounter(QuestEventID evt, std::string encounter_name, uint
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
const char *sub_name = LuaEvents[evt];
|
const char *sub_name = LuaEvents[evt];
|
||||||
|
|
||||||
int start = lua_gettop(L);
|
int start = lua_gettop(L);
|
||||||
@ -972,7 +972,7 @@ void LuaParser::MapFunctions(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int LuaParser::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
evt = ConvertLuaEvent(evt);
|
evt = ConvertLuaEvent(evt);
|
||||||
if(evt >= _LargestEventID) {
|
if(evt >= _LargestEventID) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -1018,7 +1018,7 @@ int LuaParser::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int LuaParser::DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
evt = ConvertLuaEvent(evt);
|
evt = ConvertLuaEvent(evt);
|
||||||
if(evt >= _LargestEventID) {
|
if(evt >= _LargestEventID) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -1047,7 +1047,7 @@ int LuaParser::DispatchEventPlayer(QuestEventID evt, Client *client, std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
int LuaParser::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
evt = ConvertLuaEvent(evt);
|
evt = ConvertLuaEvent(evt);
|
||||||
if(evt >= _LargestEventID) {
|
if(evt >= _LargestEventID) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -1093,7 +1093,7 @@ int LuaParser::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *ite
|
|||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
int LuaParser::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
evt = ConvertLuaEvent(evt);
|
evt = ConvertLuaEvent(evt);
|
||||||
if(evt >= _LargestEventID) {
|
if(evt >= _LargestEventID) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -28,19 +28,19 @@ public:
|
|||||||
~LuaParser();
|
~LuaParser();
|
||||||
|
|
||||||
virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
virtual int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
virtual bool HasQuestSub(uint32 npc_id, QuestEventID evt);
|
virtual bool HasQuestSub(uint32 npc_id, QuestEventID evt);
|
||||||
virtual bool HasGlobalQuestSub(QuestEventID evt);
|
virtual bool HasGlobalQuestSub(QuestEventID evt);
|
||||||
@ -65,25 +65,25 @@ public:
|
|||||||
virtual uint32 GetIdentifier() { return 0xb0712acc; }
|
virtual uint32 GetIdentifier() { return 0xb0712acc; }
|
||||||
|
|
||||||
virtual int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
virtual int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
virtual int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
virtual int DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
virtual int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
virtual int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int _EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
||||||
int _EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int _EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
||||||
int _EventItem(std::string package_name, QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data,
|
int _EventItem(std::string package_name, QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data,
|
||||||
uint32 extra_data, std::vector<void*> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
||||||
int _EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
int _EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
||||||
int _EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
int _EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
void LoadScript(std::string filename, std::string package_name);
|
void LoadScript(std::string filename, std::string package_name);
|
||||||
bool HasFunction(std::string function, std::string package_name);
|
bool HasFunction(std::string function, std::string package_name);
|
||||||
|
|||||||
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
//NPC
|
//NPC
|
||||||
void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
npc->DoQuestPause(init);
|
npc->DoQuestPause(init);
|
||||||
|
|
||||||
Lua_Client l_client(reinterpret_cast<Client*>(init));
|
Lua_Client l_client(reinterpret_cast<Client*>(init));
|
||||||
@ -43,7 +43,7 @@ void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *in
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_Client l_client(reinterpret_cast<Client*>(init));
|
Lua_Client l_client(reinterpret_cast<Client*>(init));
|
||||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||||
l_client_o.push(L);
|
l_client_o.push(L);
|
||||||
@ -56,7 +56,7 @@ void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *
|
|||||||
if(extra_pointers) {
|
if(extra_pointers) {
|
||||||
for(size_t i = 0; i < extra_pointers->size(); ++i) {
|
for(size_t i = 0; i < extra_pointers->size(); ++i) {
|
||||||
std::string prefix = "item" + std::to_string(static_cast<long long>(i + 1));
|
std::string prefix = "item" + std::to_string(static_cast<long long>(i + 1));
|
||||||
Lua_ItemInst l_inst = reinterpret_cast<ItemInst*>(extra_pointers->at(i));
|
Lua_ItemInst l_inst = EQEmu::any_cast<ItemInst*>(extra_pointers->at(i));
|
||||||
luabind::adl::object l_inst_o = luabind::adl::object(L, l_inst);
|
luabind::adl::object l_inst_o = luabind::adl::object(L, l_inst);
|
||||||
l_inst_o.push(L);
|
l_inst_o.push(L);
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
if(extra_data == 1) {
|
if(extra_data == 1) {
|
||||||
lua_pushinteger(L, -1);
|
lua_pushinteger(L, -1);
|
||||||
lua_setfield(L, -2, "hp_event");
|
lua_setfield(L, -2, "hp_event");
|
||||||
@ -96,7 +96,7 @@ void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *ini
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_Mob l_mob(init);
|
Lua_Mob l_mob(init);
|
||||||
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
l_mob_o.push(L);
|
l_mob_o.push(L);
|
||||||
@ -104,7 +104,7 @@ void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *i
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_Client l_client(reinterpret_cast<Client*>(init));
|
Lua_Client l_client(reinterpret_cast<Client*>(init));
|
||||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||||
l_client_o.push(L);
|
l_client_o.push(L);
|
||||||
@ -112,7 +112,7 @@ void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_NPC l_npc(reinterpret_cast<NPC*>(init));
|
Lua_NPC l_npc(reinterpret_cast<NPC*>(init));
|
||||||
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
||||||
l_npc_o.push(L);
|
l_npc_o.push(L);
|
||||||
@ -120,7 +120,7 @@ void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *i
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_npc_task_accepted(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_task_accepted(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_Client l_client(reinterpret_cast<Client*>(init));
|
Lua_Client l_client(reinterpret_cast<Client*>(init));
|
||||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||||
l_client_o.push(L);
|
l_client_o.push(L);
|
||||||
@ -131,7 +131,7 @@ void handle_npc_task_accepted(QuestInterface *parse, lua_State* L, NPC* npc, Mob
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_Mob l_mob(init);
|
Lua_Mob l_mob(init);
|
||||||
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
l_mob_o.push(L);
|
l_mob_o.push(L);
|
||||||
@ -142,7 +142,7 @@ void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_Mob l_mob(init);
|
Lua_Mob l_mob(init);
|
||||||
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
l_mob_o.push(L);
|
l_mob_o.push(L);
|
||||||
@ -153,7 +153,7 @@ void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *ini
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_Mob l_mob(init);
|
Lua_Mob l_mob(init);
|
||||||
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
l_mob_o.push(L);
|
l_mob_o.push(L);
|
||||||
@ -165,19 +165,19 @@ void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, s
|
|||||||
|
|
||||||
|
|
||||||
void handle_npc_signal(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_signal(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, std::stoi(data));
|
||||||
lua_setfield(L, -2, "signal");
|
lua_setfield(L, -2, "signal");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_npc_timer(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_timer(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushstring(L, data.c_str());
|
lua_pushstring(L, data.c_str());
|
||||||
lua_setfield(L, -2, "timer");
|
lua_setfield(L, -2, "timer");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_Mob l_mob(init);
|
Lua_Mob l_mob(init);
|
||||||
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
l_mob_o.push(L);
|
l_mob_o.push(L);
|
||||||
@ -205,7 +205,7 @@ void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_npc_cast(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_cast(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
int spell_id = std::stoi(data);
|
int spell_id = std::stoi(data);
|
||||||
if(IsValidSpell(spell_id)) {
|
if(IsValidSpell(spell_id)) {
|
||||||
Lua_Spell l_spell(&spells[spell_id]);
|
Lua_Spell l_spell(&spells[spell_id]);
|
||||||
@ -221,21 +221,21 @@ void handle_npc_cast(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_npc_area(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_area(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushinteger(L, *reinterpret_cast<int*>(extra_pointers->at(0)));
|
lua_pushinteger(L, *EQEmu::any_cast<int*>(extra_pointers->at(0)));
|
||||||
lua_setfield(L, -2, "area_id");
|
lua_setfield(L, -2, "area_id");
|
||||||
|
|
||||||
lua_pushinteger(L, *reinterpret_cast<int*>(extra_pointers->at(1)));
|
lua_pushinteger(L, *EQEmu::any_cast<int*>(extra_pointers->at(1)));
|
||||||
lua_setfield(L, -2, "area_type");
|
lua_setfield(L, -2, "area_type");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Player
|
//Player
|
||||||
void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushstring(L, data.c_str());
|
lua_pushstring(L, data.c_str());
|
||||||
lua_setfield(L, -2, "message");
|
lua_setfield(L, -2, "message");
|
||||||
|
|
||||||
@ -244,7 +244,7 @@ void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
Mob *o = entity_list.GetMobID(std::stoi(sep.arg[0]));
|
Mob *o = entity_list.GetMobID(std::stoi(sep.arg[0]));
|
||||||
@ -274,13 +274,13 @@ void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, st
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushstring(L, data.c_str());
|
lua_pushstring(L, data.c_str());
|
||||||
lua_setfield(L, -2, "timer");
|
lua_setfield(L, -2, "timer");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_discover_item(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_discover_item(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
const Item_Struct *item = database.GetItem(extra_data);
|
const Item_Struct *item = database.GetItem(extra_data);
|
||||||
if(item) {
|
if(item) {
|
||||||
Lua_Item l_item(item);
|
Lua_Item l_item(item);
|
||||||
@ -296,51 +296,51 @@ void handle_player_discover_item(QuestInterface *parse, lua_State* L, Client* cl
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_fish_forage_success(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_fish_forage_success(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_ItemInst l_item(reinterpret_cast<ItemInst*>(extra_pointers->at(0)));
|
Lua_ItemInst l_item(EQEmu::any_cast<ItemInst*>(extra_pointers->at(0)));
|
||||||
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
||||||
l_item_o.push(L);
|
l_item_o.push(L);
|
||||||
lua_setfield(L, -2, "item");
|
lua_setfield(L, -2, "item");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_click_object(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_click_object(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_Object l_object(reinterpret_cast<Object*>(extra_pointers->at(0)));
|
Lua_Object l_object(EQEmu::any_cast<Object*>(extra_pointers->at(0)));
|
||||||
luabind::adl::object l_object_o = luabind::adl::object(L, l_object);
|
luabind::adl::object l_object_o = luabind::adl::object(L, l_object);
|
||||||
l_object_o.push(L);
|
l_object_o.push(L);
|
||||||
lua_setfield(L, -2, "object");
|
lua_setfield(L, -2, "object");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_click_door(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_click_door(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_Door l_door(reinterpret_cast<Doors*>(extra_pointers->at(0)));
|
Lua_Door l_door(EQEmu::any_cast<Doors*>(extra_pointers->at(0)));
|
||||||
luabind::adl::object l_door_o = luabind::adl::object(L, l_door);
|
luabind::adl::object l_door_o = luabind::adl::object(L, l_door);
|
||||||
l_door_o.push(L);
|
l_door_o.push(L);
|
||||||
lua_setfield(L, -2, "door");
|
lua_setfield(L, -2, "door");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_signal(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_signal(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, std::stoi(data));
|
||||||
lua_setfield(L, -2, "signal");
|
lua_setfield(L, -2, "signal");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_popup_response(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_popup_response(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, std::stoi(data));
|
||||||
lua_setfield(L, -2, "popup_id");
|
lua_setfield(L, -2, "popup_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_pick_up(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_pick_up(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_ItemInst l_item(reinterpret_cast<ItemInst*>(extra_pointers->at(0)));
|
Lua_ItemInst l_item(EQEmu::any_cast<ItemInst*>(extra_pointers->at(0)));
|
||||||
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
||||||
l_item_o.push(L);
|
l_item_o.push(L);
|
||||||
lua_setfield(L, -2, "item");
|
lua_setfield(L, -2, "item");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_cast(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_cast(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
int spell_id = std::stoi(data);
|
int spell_id = std::stoi(data);
|
||||||
if(IsValidSpell(spell_id)) {
|
if(IsValidSpell(spell_id)) {
|
||||||
Lua_Spell l_spell(&spells[spell_id]);
|
Lua_Spell l_spell(&spells[spell_id]);
|
||||||
@ -356,48 +356,48 @@ void handle_player_cast(QuestInterface *parse, lua_State* L, Client* client, std
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_task_fail(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_task_fail(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, std::stoi(data));
|
||||||
lua_setfield(L, -2, "task_id");
|
lua_setfield(L, -2, "task_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_zone(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_zone(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, std::stoi(data));
|
||||||
lua_setfield(L, -2, "zone_id");
|
lua_setfield(L, -2, "zone_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_duel_win(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_duel_win(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_Client l_client(reinterpret_cast<Client*>(extra_pointers->at(1)));
|
Lua_Client l_client(EQEmu::any_cast<Client*>(extra_pointers->at(1)));
|
||||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||||
l_client_o.push(L);
|
l_client_o.push(L);
|
||||||
lua_setfield(L, -2, "other");
|
lua_setfield(L, -2, "other");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_duel_loss(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_duel_loss(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_Client l_client(reinterpret_cast<Client*>(extra_pointers->at(0)));
|
Lua_Client l_client(EQEmu::any_cast<Client*>(extra_pointers->at(0)));
|
||||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||||
l_client_o.push(L);
|
l_client_o.push(L);
|
||||||
lua_setfield(L, -2, "other");
|
lua_setfield(L, -2, "other");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_loot(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_loot(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_ItemInst l_item(reinterpret_cast<ItemInst*>(extra_pointers->at(0)));
|
Lua_ItemInst l_item(EQEmu::any_cast<ItemInst*>(extra_pointers->at(0)));
|
||||||
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
||||||
l_item_o.push(L);
|
l_item_o.push(L);
|
||||||
lua_setfield(L, -2, "item");
|
lua_setfield(L, -2, "item");
|
||||||
|
|
||||||
Lua_Corpse l_corpse(reinterpret_cast<Corpse*>(extra_pointers->at(1)));
|
Lua_Corpse l_corpse(EQEmu::any_cast<Corpse*>(extra_pointers->at(1)));
|
||||||
luabind::adl::object l_corpse_o = luabind::adl::object(L, l_corpse);
|
luabind::adl::object l_corpse_o = luabind::adl::object(L, l_corpse);
|
||||||
l_corpse_o.push(L);
|
l_corpse_o.push(L);
|
||||||
lua_setfield(L, -2, "corpse");
|
lua_setfield(L, -2, "corpse");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_task_stage_complete(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_task_stage_complete(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "task_id");
|
lua_setfield(L, -2, "task_id");
|
||||||
@ -407,7 +407,7 @@ void handle_player_task_stage_complete(QuestInterface *parse, lua_State* L, Clie
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_task_update(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_task_update(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Seperator sep(data.c_str());
|
Seperator sep(data.c_str());
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
||||||
lua_setfield(L, -2, "count");
|
lua_setfield(L, -2, "count");
|
||||||
@ -420,7 +420,7 @@ void handle_player_task_update(QuestInterface *parse, lua_State* L, Client* clie
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_command(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_command(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Seperator sep(data.c_str(), ' ', 10, 100, true);
|
Seperator sep(data.c_str(), ' ', 10, 100, true);
|
||||||
std::string command(sep.arg[0] + 1);
|
std::string command(sep.arg[0] + 1);
|
||||||
lua_pushstring(L, command.c_str());
|
lua_pushstring(L, command.c_str());
|
||||||
@ -439,7 +439,7 @@ void handle_player_command(QuestInterface *parse, lua_State* L, Client* client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_combine(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_combine(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushinteger(L, extra_data);
|
lua_pushinteger(L, extra_data);
|
||||||
lua_setfield(L, -2, "recipe_id");
|
lua_setfield(L, -2, "recipe_id");
|
||||||
|
|
||||||
@ -448,24 +448,24 @@ void handle_player_combine(QuestInterface *parse, lua_State* L, Client* client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_feign(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_feign(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_NPC l_npc(reinterpret_cast<NPC*>(extra_pointers->at(0)));
|
Lua_NPC l_npc(EQEmu::any_cast<NPC*>(extra_pointers->at(0)));
|
||||||
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
||||||
l_npc_o.push(L);
|
l_npc_o.push(L);
|
||||||
lua_setfield(L, -2, "other");
|
lua_setfield(L, -2, "other");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_area(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_area(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushinteger(L, *reinterpret_cast<int*>(extra_pointers->at(0)));
|
lua_pushinteger(L, *EQEmu::any_cast<int*>(extra_pointers->at(0)));
|
||||||
lua_setfield(L, -2, "area_id");
|
lua_setfield(L, -2, "area_id");
|
||||||
|
|
||||||
lua_pushinteger(L, *reinterpret_cast<int*>(extra_pointers->at(1)));
|
lua_pushinteger(L, *EQEmu::any_cast<int*>(extra_pointers->at(1)));
|
||||||
lua_setfield(L, -2, "area_type");
|
lua_setfield(L, -2, "area_type");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_respawn(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_respawn(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, std::stoi(data));
|
||||||
lua_setfield(L, -2, "option");
|
lua_setfield(L, -2, "option");
|
||||||
|
|
||||||
@ -474,8 +474,8 @@ void handle_player_respawn(QuestInterface *parse, lua_State* L, Client* client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_packet(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_packet(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_Packet l_packet(reinterpret_cast<EQApplicationPacket*>(extra_pointers->at(0)));
|
Lua_Packet l_packet(EQEmu::any_cast<EQApplicationPacket*>(extra_pointers->at(0)));
|
||||||
luabind::adl::object l_packet_o = luabind::adl::object(L, l_packet);
|
luabind::adl::object l_packet_o = luabind::adl::object(L, l_packet);
|
||||||
l_packet_o.push(L);
|
l_packet_o.push(L);
|
||||||
lua_setfield(L, -2, "packet");
|
lua_setfield(L, -2, "packet");
|
||||||
@ -485,24 +485,24 @@ void handle_player_packet(QuestInterface *parse, lua_State* L, Client* client, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Item
|
//Item
|
||||||
void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushinteger(L, extra_data);
|
lua_pushinteger(L, extra_data);
|
||||||
lua_setfield(L, -2, "slot_id");
|
lua_setfield(L, -2, "slot_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_item_timer(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_timer(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushstring(L, data.c_str());
|
lua_pushstring(L, data.c_str());
|
||||||
lua_setfield(L, -2, "timer");
|
lua_setfield(L, -2, "timer");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_item_proc(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_proc(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
|
|
||||||
Lua_Mob l_mob(mob);
|
Lua_Mob l_mob(mob);
|
||||||
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
@ -523,7 +523,7 @@ void handle_item_proc(QuestInterface *parse, lua_State* L, Client* client, ItemI
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
if(mob && mob->IsCorpse()) {
|
if(mob && mob->IsCorpse()) {
|
||||||
Lua_Corpse l_corpse(mob->CastToCorpse());
|
Lua_Corpse l_corpse(mob->CastToCorpse());
|
||||||
luabind::adl::object l_corpse_o = luabind::adl::object(L, l_corpse);
|
luabind::adl::object l_corpse_o = luabind::adl::object(L, l_corpse);
|
||||||
@ -538,14 +538,14 @@ void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemI
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_item_equip(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_equip(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
lua_pushinteger(L, extra_data);
|
lua_pushinteger(L, extra_data);
|
||||||
lua_setfield(L, -2, "slot_id");
|
lua_setfield(L, -2, "slot_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_item_augment(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_augment(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_ItemInst l_item(reinterpret_cast<ItemInst*>(extra_pointers->at(0)));
|
Lua_ItemInst l_item(EQEmu::any_cast<ItemInst*>(extra_pointers->at(0)));
|
||||||
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
||||||
l_item_o.push(L);
|
l_item_o.push(L);
|
||||||
lua_setfield(L, -2, "aug");
|
lua_setfield(L, -2, "aug");
|
||||||
@ -555,8 +555,8 @@ void handle_item_augment(QuestInterface *parse, lua_State* L, Client* client, It
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_item_augment_insert(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_augment_insert(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_ItemInst l_item(reinterpret_cast<ItemInst*>(extra_pointers->at(0)));
|
Lua_ItemInst l_item(EQEmu::any_cast<ItemInst*>(extra_pointers->at(0)));
|
||||||
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
||||||
l_item_o.push(L);
|
l_item_o.push(L);
|
||||||
lua_setfield(L, -2, "item");
|
lua_setfield(L, -2, "item");
|
||||||
@ -566,8 +566,8 @@ void handle_item_augment_insert(QuestInterface *parse, lua_State* L, Client* cli
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_item_augment_remove(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_augment_remove(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
Lua_ItemInst l_item(reinterpret_cast<ItemInst*>(extra_pointers->at(0)));
|
Lua_ItemInst l_item(EQEmu::any_cast<ItemInst*>(extra_pointers->at(0)));
|
||||||
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
||||||
l_item_o.push(L);
|
l_item_o.push(L);
|
||||||
lua_setfield(L, -2, "item");
|
lua_setfield(L, -2, "item");
|
||||||
@ -575,17 +575,17 @@ void handle_item_augment_remove(QuestInterface *parse, lua_State* L, Client* cli
|
|||||||
lua_pushinteger(L, extra_data);
|
lua_pushinteger(L, extra_data);
|
||||||
lua_setfield(L, -2, "slot_id");
|
lua_setfield(L, -2, "slot_id");
|
||||||
|
|
||||||
lua_pushboolean(L, *reinterpret_cast<bool*>(extra_pointers->at(1)));
|
lua_pushboolean(L, *EQEmu::any_cast<bool*>(extra_pointers->at(1)));
|
||||||
lua_setfield(L, -2, "destroyed");
|
lua_setfield(L, -2, "destroyed");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//Spell
|
//Spell
|
||||||
void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
if(npc) {
|
if(npc) {
|
||||||
Lua_Mob l_npc(npc);
|
Lua_Mob l_npc(npc);
|
||||||
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
||||||
@ -602,7 +602,7 @@ void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client*
|
|||||||
|
|
||||||
lua_setfield(L, -2, "target");
|
lua_setfield(L, -2, "target");
|
||||||
|
|
||||||
lua_pushinteger(L, *reinterpret_cast<int*>(extra_pointers->at(0)));
|
lua_pushinteger(L, *EQEmu::any_cast<int*>(extra_pointers->at(0)));
|
||||||
lua_setfield(L, -2, "buff_slot");
|
lua_setfield(L, -2, "buff_slot");
|
||||||
|
|
||||||
lua_pushinteger(L, extra_data);
|
lua_pushinteger(L, extra_data);
|
||||||
@ -610,7 +610,7 @@ void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client*
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
if(npc) {
|
if(npc) {
|
||||||
Lua_Mob l_npc(npc);
|
Lua_Mob l_npc(npc);
|
||||||
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
||||||
@ -627,13 +627,13 @@ void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* cli
|
|||||||
|
|
||||||
lua_setfield(L, -2, "target");
|
lua_setfield(L, -2, "target");
|
||||||
|
|
||||||
lua_pushinteger(L, *reinterpret_cast<int*>(extra_pointers->at(0)));
|
lua_pushinteger(L, *EQEmu::any_cast<int*>(extra_pointers->at(0)));
|
||||||
lua_setfield(L, -2, "tics_remaining");
|
lua_setfield(L, -2, "tics_remaining");
|
||||||
|
|
||||||
lua_pushinteger(L, *reinterpret_cast<uint8*>(extra_pointers->at(1)));
|
lua_pushinteger(L, *EQEmu::any_cast<uint8*>(extra_pointers->at(1)));
|
||||||
lua_setfield(L, -2, "caster_level");
|
lua_setfield(L, -2, "caster_level");
|
||||||
|
|
||||||
lua_pushinteger(L, *reinterpret_cast<int*>(extra_pointers->at(2)));
|
lua_pushinteger(L, *EQEmu::any_cast<int*>(extra_pointers->at(2)));
|
||||||
lua_setfield(L, -2, "buff_slot");
|
lua_setfield(L, -2, "buff_slot");
|
||||||
|
|
||||||
lua_pushinteger(L, extra_data);
|
lua_pushinteger(L, extra_data);
|
||||||
@ -641,7 +641,7 @@ void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* cli
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
if(npc) {
|
if(npc) {
|
||||||
Lua_Mob l_npc(npc);
|
Lua_Mob l_npc(npc);
|
||||||
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
||||||
@ -661,12 +661,12 @@ void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* cl
|
|||||||
lua_pushinteger(L, extra_data);
|
lua_pushinteger(L, extra_data);
|
||||||
lua_setfield(L, -2, "buff_slot");
|
lua_setfield(L, -2, "buff_slot");
|
||||||
|
|
||||||
lua_pushinteger(L, *reinterpret_cast<uint16*>(extra_pointers->at(0)));
|
lua_pushinteger(L, *EQEmu::any_cast<uint16*>(extra_pointers->at(0)));
|
||||||
lua_setfield(L, -2, "caster_id");
|
lua_setfield(L, -2, "caster_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
if(npc) {
|
if(npc) {
|
||||||
Lua_Mob l_npc(npc);
|
Lua_Mob l_npc(npc);
|
||||||
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
||||||
@ -685,7 +685,7 @@ void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Cl
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -2,128 +2,128 @@
|
|||||||
#define _EQE_LUA_PARSER_EVENTS_H
|
#define _EQE_LUA_PARSER_EVENTS_H
|
||||||
#ifdef LUA_EQEMU
|
#ifdef LUA_EQEMU
|
||||||
|
|
||||||
typedef void(*NPCArgumentHandler)(QuestInterface*, lua_State*, NPC*, Mob*, std::string, uint32, std::vector<void*>*);
|
typedef void(*NPCArgumentHandler)(QuestInterface*, lua_State*, NPC*, Mob*, std::string, uint32, std::vector<EQEmu::Any>*);
|
||||||
typedef void(*PlayerArgumentHandler)(QuestInterface*, lua_State*, Client*, std::string, uint32, std::vector<void*>*);
|
typedef void(*PlayerArgumentHandler)(QuestInterface*, lua_State*, Client*, std::string, uint32, std::vector<EQEmu::Any>*);
|
||||||
typedef void(*ItemArgumentHandler)(QuestInterface*, lua_State*, Client*, ItemInst*, Mob*, std::string, uint32, std::vector<void*>*);
|
typedef void(*ItemArgumentHandler)(QuestInterface*, lua_State*, Client*, ItemInst*, Mob*, std::string, uint32, std::vector<EQEmu::Any>*);
|
||||||
typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, NPC*, Client*, uint32, uint32, std::vector<void*>*);
|
typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, NPC*, Client*, uint32, uint32, std::vector<EQEmu::Any>*);
|
||||||
|
|
||||||
//NPC
|
//NPC
|
||||||
void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_event_hp(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_single_mob(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_single_client(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_single_npc(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_task_accepted(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_task_accepted(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_popup(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_waypoint(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_hate(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_signal(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_signal(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_timer(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_timer(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_death(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_cast(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_cast(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_area(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_area(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_null(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
//Player
|
//Player
|
||||||
void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_say(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_death(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_timer(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_discover_item(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_discover_item(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_fish_forage_success(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_fish_forage_success(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_click_object(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_click_object(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_click_door(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_click_door(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_signal(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_signal(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_popup_response(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_popup_response(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_pick_up(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_pick_up(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_cast(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_cast(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_task_fail(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_task_fail(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_zone(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_zone(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_duel_win(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_duel_win(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_duel_loss(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_duel_loss(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_loot(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_loot(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_task_stage_complete(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_task_stage_complete(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_task_update(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_task_update(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_command(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_command(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_combine(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_combine(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_feign(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_feign(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_area(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_area(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_respawn(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_respawn(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_packet(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_packet(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
void handle_player_null(QuestInterface *parse, lua_State* L, Client* client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
//Item
|
//Item
|
||||||
void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_item_timer(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_timer(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_item_proc(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_proc(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_loot(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_item_equip(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_equip(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_item_augment(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_augment(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_item_augment_insert(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_augment_insert(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_item_augment_remove(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_augment_remove(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, ItemInst* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
//Spell
|
//Spell
|
||||||
void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
void handle_spell_effect(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
void handle_spell_tic(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
void handle_spell_fade(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -183,6 +183,7 @@ Mob::Mob(const char* in_name,
|
|||||||
has_MGB = false;
|
has_MGB = false;
|
||||||
has_ProjectIllusion = false;
|
has_ProjectIllusion = false;
|
||||||
SpellPowerDistanceMod = 0;
|
SpellPowerDistanceMod = 0;
|
||||||
|
last_los_check = false;
|
||||||
|
|
||||||
if(in_aa_title>0)
|
if(in_aa_title>0)
|
||||||
aa_title = in_aa_title;
|
aa_title = in_aa_title;
|
||||||
@ -341,6 +342,7 @@ Mob::Mob(const char* in_name,
|
|||||||
viral_spells[i] = 0;
|
viral_spells[i] = 0;
|
||||||
}
|
}
|
||||||
pStandingPetOrder = SPO_Follow;
|
pStandingPetOrder = SPO_Follow;
|
||||||
|
pseudo_rooted = false;
|
||||||
|
|
||||||
see_invis = in_see_invis;
|
see_invis = in_see_invis;
|
||||||
see_invis_undead = in_see_invis_undead != 0;
|
see_invis_undead = in_see_invis_undead != 0;
|
||||||
|
|||||||
@ -464,6 +464,8 @@ public:
|
|||||||
bool CheckLosFN(float posX, float posY, float posZ, float mobSize);
|
bool CheckLosFN(float posX, float posY, float posZ, float mobSize);
|
||||||
inline void SetChanged() { pLastChange = Timer::GetCurrentTime(); }
|
inline void SetChanged() { pLastChange = Timer::GetCurrentTime(); }
|
||||||
inline const uint32 LastChange() const { return pLastChange; }
|
inline const uint32 LastChange() const { return pLastChange; }
|
||||||
|
inline void SetLastLosState(bool value) { last_los_check = value; }
|
||||||
|
inline bool CheckLastLosState() const { return last_los_check; }
|
||||||
|
|
||||||
//Quest
|
//Quest
|
||||||
void QuestReward(Client *c = nullptr, uint32 silver = 0, uint32 gold = 0, uint32 platinum = 0);
|
void QuestReward(Client *c = nullptr, uint32 silver = 0, uint32 gold = 0, uint32 platinum = 0);
|
||||||
@ -752,7 +754,8 @@ public:
|
|||||||
inline const bool IsRooted() const { return rooted || permarooted; }
|
inline const bool IsRooted() const { return rooted || permarooted; }
|
||||||
inline const bool HasVirus() const { return has_virus; }
|
inline const bool HasVirus() const { return has_virus; }
|
||||||
int GetSnaredAmount();
|
int GetSnaredAmount();
|
||||||
|
inline const bool IsPseudoRooted() const { return pseudo_rooted; }
|
||||||
|
inline void SetPseudoRoot(bool prState) { pseudo_rooted = prState; }
|
||||||
|
|
||||||
int GetCurWp() { return cur_wp; }
|
int GetCurWp() { return cur_wp; }
|
||||||
|
|
||||||
@ -1119,6 +1122,8 @@ protected:
|
|||||||
bool has_MGB;
|
bool has_MGB;
|
||||||
bool has_ProjectIllusion;
|
bool has_ProjectIllusion;
|
||||||
int16 SpellPowerDistanceMod;
|
int16 SpellPowerDistanceMod;
|
||||||
|
bool last_los_check;
|
||||||
|
bool pseudo_rooted;
|
||||||
|
|
||||||
// Bind wound
|
// Bind wound
|
||||||
Timer bindwound_timer;
|
Timer bindwound_timer;
|
||||||
|
|||||||
@ -541,13 +541,40 @@ void NPC::AI_Start(uint32 iMoveDelay) {
|
|||||||
void Mob::AI_Stop() {
|
void Mob::AI_Stop() {
|
||||||
if (!IsAIControlled())
|
if (!IsAIControlled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pAIControlled = false;
|
pAIControlled = false;
|
||||||
|
|
||||||
safe_delete(AIthink_timer);
|
safe_delete(AIthink_timer);
|
||||||
safe_delete(AIwalking_timer);
|
safe_delete(AIwalking_timer);
|
||||||
safe_delete(AImovement_timer);
|
safe_delete(AImovement_timer);
|
||||||
safe_delete(AItarget_check_timer)
|
safe_delete(AItarget_check_timer);
|
||||||
safe_delete(AIscanarea_timer);
|
safe_delete(AIscanarea_timer);
|
||||||
safe_delete(AIfeignremember_timer);
|
safe_delete(AIfeignremember_timer);
|
||||||
|
safe_delete(PathingLOSCheckTimer);
|
||||||
|
safe_delete(PathingRouteUpdateTimerShort);
|
||||||
|
safe_delete(PathingRouteUpdateTimerLong);
|
||||||
|
|
||||||
|
attack_timer.Disable();
|
||||||
|
attack_dw_timer.Disable();
|
||||||
|
ranged_timer.Disable();
|
||||||
|
tic_timer.Disable();
|
||||||
|
mana_timer.Disable();
|
||||||
|
spellend_timer.Disable();
|
||||||
|
projectile_timer.Disable();
|
||||||
|
rewind_timer.Disable();
|
||||||
|
bindwound_timer.Disable();
|
||||||
|
stunned_timer.Disable();
|
||||||
|
spun_timer.Disable();
|
||||||
|
bardsong_timer.Disable();
|
||||||
|
gravity_timer.Disable();
|
||||||
|
viral_timer.Disable();
|
||||||
|
flee_timer.Disable();
|
||||||
|
|
||||||
|
for (int sat = 0; sat < MAX_SPECIAL_ATTACK; ++sat) {
|
||||||
|
if (SpecialAbilities[sat].timer)
|
||||||
|
SpecialAbilities[sat].timer->Disable();
|
||||||
|
}
|
||||||
|
|
||||||
hate_list.Wipe();
|
hate_list.Wipe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,7 @@
|
|||||||
#include "worldserver.h"
|
#include "worldserver.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
|
#include "queryserv.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "zone_config.h"
|
#include "zone_config.h"
|
||||||
#include "titles.h"
|
#include "titles.h"
|
||||||
@ -98,6 +99,7 @@ npcDecayTimes_Struct npcCorpseDecayTimes[100];
|
|||||||
TitleManager title_manager;
|
TitleManager title_manager;
|
||||||
DBAsyncFinishedQueue MTdbafq;
|
DBAsyncFinishedQueue MTdbafq;
|
||||||
DBAsync *dbasync = nullptr;
|
DBAsync *dbasync = nullptr;
|
||||||
|
QueryServ *QServ = 0;
|
||||||
TaskManager *taskmanager = 0;
|
TaskManager *taskmanager = 0;
|
||||||
QuestParserCollection *parse = 0;
|
QuestParserCollection *parse = 0;
|
||||||
|
|
||||||
@ -114,6 +116,8 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
const char *zone_name;
|
const char *zone_name;
|
||||||
|
|
||||||
|
QServ = new QueryServ;
|
||||||
|
|
||||||
if(argc == 3) {
|
if(argc == 3) {
|
||||||
worldserver.SetLauncherName(argv[2]);
|
worldserver.SetLauncherName(argv[2]);
|
||||||
worldserver.SetLaunchedName(argv[1]);
|
worldserver.SetLaunchedName(argv[1]);
|
||||||
@ -622,7 +626,7 @@ void LoadSpells(EQEmu::MemoryMappedFile **mmf) {
|
|||||||
SPDAT_RECORDS = records;
|
SPDAT_RECORDS = records;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update Window Title with relevant information */
|
||||||
void UpdateWindowTitle(char* iNewTitle) {
|
void UpdateWindowTitle(char* iNewTitle) {
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
char tmp[500];
|
char tmp[500];
|
||||||
@ -634,7 +638,7 @@ void UpdateWindowTitle(char* iNewTitle) {
|
|||||||
#if defined(GOTFRAGS) || defined(_EQDEBUG)
|
#if defined(GOTFRAGS) || defined(_EQDEBUG)
|
||||||
snprintf(tmp, sizeof(tmp), "%i: %s, %i clients, %i", ZoneConfig::get()->ZonePort, zone->GetShortName(), numclients, getpid());
|
snprintf(tmp, sizeof(tmp), "%i: %s, %i clients, %i", ZoneConfig::get()->ZonePort, zone->GetShortName(), numclients, getpid());
|
||||||
#else
|
#else
|
||||||
snprintf(tmp, sizeof(tmp), "%i: %s, %i clients", ZoneConfig::get()->ZonePort, zone->GetShortName(), numclients);
|
snprintf(tmp, sizeof(tmp), "%s :: clients: %i inst_id: %i inst_ver: %i :: port: %i", zone->GetShortName(), numclients, zone->GetInstanceID(), zone->GetInstanceVersion(), ZoneConfig::get()->ZonePort);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
283
zone/npc.cpp
283
zone/npc.cpp
@ -1787,252 +1787,49 @@ void NPC::ModifyNPCStat(const char *identifier, const char *newValue)
|
|||||||
{
|
{
|
||||||
std::string id = identifier;
|
std::string id = identifier;
|
||||||
std::string val = newValue;
|
std::string val = newValue;
|
||||||
for(int i = 0; i < id.length(); ++i)
|
for(int i = 0; i < id.length(); ++i) {
|
||||||
{
|
|
||||||
id[i] = std::tolower(id[i]);
|
id[i] = std::tolower(id[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(id == "ac")
|
if(id == "ac") { AC = atoi(val.c_str()); return; }
|
||||||
{
|
else if(id == "str") { STR = atoi(val.c_str()); return; }
|
||||||
AC = atoi(val.c_str());
|
else if(id == "sta") { STA = atoi(val.c_str()); return; }
|
||||||
return;
|
else if(id == "agi") { AGI = atoi(val.c_str()); return; }
|
||||||
}
|
else if(id == "dex") { DEX = atoi(val.c_str()); return; }
|
||||||
|
else if(id == "wis") { WIS = atoi(val.c_str()); CalcMaxMana(); return; }
|
||||||
if(id == "str")
|
else if(id == "int" || id == "_int") { INT = atoi(val.c_str()); CalcMaxMana(); return; }
|
||||||
{
|
else if(id == "cha") { CHA = atoi(val.c_str()); return; }
|
||||||
STR = atoi(val.c_str());
|
else if(id == "max_hp") { base_hp = atoi(val.c_str()); CalcMaxHP(); if (cur_hp > max_hp) { cur_hp = max_hp; } return; }
|
||||||
return;
|
else if(id == "max_mana") { npc_mana = atoi(val.c_str()); CalcMaxMana(); if (cur_mana > max_mana){ cur_mana = max_mana; } return; }
|
||||||
}
|
else if(id == "mr") { MR = atoi(val.c_str()); return; }
|
||||||
|
else if(id == "fr") { FR = atoi(val.c_str()); return; }
|
||||||
if(id == "sta")
|
else if(id == "cr") { CR = atoi(val.c_str()); return; }
|
||||||
{
|
else if(id == "pr") { PR = atoi(val.c_str()); return; }
|
||||||
STA = atoi(val.c_str());
|
else if(id == "dr") { DR = atoi(val.c_str()); return; }
|
||||||
return;
|
else if(id == "PhR") { PhR = atoi(val.c_str()); return; }
|
||||||
}
|
else if(id == "runspeed") { runspeed = (float)atof(val.c_str()); CalcBonuses(); return; }
|
||||||
|
else if(id == "special_attacks") { NPCSpecialAttacks(val.c_str(), 0, 1); return; }
|
||||||
if(id == "agi")
|
else if(id == "attack_speed") { attack_speed = (float)atof(val.c_str()); CalcBonuses(); return; }
|
||||||
{
|
else if(id == "atk") { ATK = atoi(val.c_str()); return; }
|
||||||
AGI = atoi(val.c_str());
|
else if(id == "accuracy") { accuracy_rating = atoi(val.c_str()); return; }
|
||||||
return;
|
else if(id == "avoidance") { avoidance_rating = atoi(val.c_str()); return; }
|
||||||
}
|
else if(id == "trackable") { trackable = atoi(val.c_str()); return; }
|
||||||
|
else if(id == "min_hit") { min_dmg = atoi(val.c_str()); return; }
|
||||||
if(id == "dex")
|
else if(id == "max_hit") { max_dmg = atoi(val.c_str()); return; }
|
||||||
{
|
else if(id == "attack_count") { attack_count = atoi(val.c_str()); return; }
|
||||||
DEX = atoi(val.c_str());
|
else if(id == "see_invis") { see_invis = atoi(val.c_str()); return; }
|
||||||
return;
|
else if(id == "see_invis_undead") { see_invis_undead = atoi(val.c_str()); return; }
|
||||||
}
|
else if(id == "see_hide") { see_hide = atoi(val.c_str()); return; }
|
||||||
|
else if(id == "see_improved_hide") { see_improved_hide = atoi(val.c_str()); return; }
|
||||||
if(id == "wis")
|
else if(id == "hp_regen") { hp_regen = atoi(val.c_str()); return; }
|
||||||
{
|
else if(id == "mana_regen") { mana_regen = atoi(val.c_str()); return; }
|
||||||
WIS = atoi(val.c_str());
|
else if(id == "level") { SetLevel(atoi(val.c_str())); return; }
|
||||||
CalcMaxMana();
|
else if(id == "aggro") { pAggroRange = atof(val.c_str()); return; }
|
||||||
return;
|
else if(id == "assist") { pAssistRange = atof(val.c_str()); return; }
|
||||||
}
|
else if(id == "slow_mitigation") { slow_mitigation = atoi(val.c_str()); return; }
|
||||||
|
else if(id == "loottable_id") { loottable_id = atof(val.c_str()); return; }
|
||||||
if(id == "int" || id == "_int")
|
else if(id == "healscale") { healscale = atof(val.c_str()); return; }
|
||||||
{
|
else if(id == "spellscale") { spellscale = atof(val.c_str()); return; }
|
||||||
INT = atoi(val.c_str());
|
|
||||||
CalcMaxMana();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "cha")
|
|
||||||
{
|
|
||||||
CHA = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "max_hp")
|
|
||||||
{
|
|
||||||
base_hp = atoi(val.c_str());
|
|
||||||
CalcMaxHP();
|
|
||||||
if(cur_hp > max_hp)
|
|
||||||
cur_hp = max_hp;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "max_mana")
|
|
||||||
{
|
|
||||||
npc_mana = atoi(val.c_str());
|
|
||||||
CalcMaxMana();
|
|
||||||
if(cur_mana > max_mana)
|
|
||||||
cur_mana = max_mana;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "mr")
|
|
||||||
{
|
|
||||||
MR = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "fr")
|
|
||||||
{
|
|
||||||
FR = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "cr")
|
|
||||||
{
|
|
||||||
CR = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "pr")
|
|
||||||
{
|
|
||||||
PR = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "dr")
|
|
||||||
{
|
|
||||||
DR = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "PhR")
|
|
||||||
{
|
|
||||||
PhR = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "runspeed")
|
|
||||||
{
|
|
||||||
runspeed = (float)atof(val.c_str());
|
|
||||||
CalcBonuses();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "special_attacks")
|
|
||||||
{
|
|
||||||
//Added reset flag.
|
|
||||||
NPCSpecialAttacks(val.c_str(), 0, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "attack_speed")
|
|
||||||
{
|
|
||||||
attack_speed = (float)atof(val.c_str());
|
|
||||||
CalcBonuses();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "atk")
|
|
||||||
{
|
|
||||||
ATK = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "accuracy")
|
|
||||||
{
|
|
||||||
accuracy_rating = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "avoidance")
|
|
||||||
{
|
|
||||||
avoidance_rating = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "trackable")
|
|
||||||
{
|
|
||||||
trackable = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "min_hit")
|
|
||||||
{
|
|
||||||
min_dmg = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "max_hit")
|
|
||||||
{
|
|
||||||
max_dmg = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "attack_count")
|
|
||||||
{
|
|
||||||
attack_count = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "see_invis")
|
|
||||||
{
|
|
||||||
see_invis = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "see_invis_undead")
|
|
||||||
{
|
|
||||||
see_invis_undead = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "see_hide")
|
|
||||||
{
|
|
||||||
see_hide = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "see_improved_hide")
|
|
||||||
{
|
|
||||||
see_improved_hide = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "hp_regen")
|
|
||||||
{
|
|
||||||
hp_regen = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "mana_regen")
|
|
||||||
{
|
|
||||||
mana_regen = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "level")
|
|
||||||
{
|
|
||||||
SetLevel(atoi(val.c_str()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "aggro")
|
|
||||||
{
|
|
||||||
pAggroRange = atof(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "assist")
|
|
||||||
{
|
|
||||||
pAssistRange = atof(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(id == "slow_mitigation")
|
|
||||||
{
|
|
||||||
slow_mitigation = atoi(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(id == "loottable_id")
|
|
||||||
{
|
|
||||||
loottable_id = atof(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(id == "healscale")
|
|
||||||
{
|
|
||||||
healscale = atof(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(id == "spellscale")
|
|
||||||
{
|
|
||||||
spellscale = atof(val.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPC::LevelScale() {
|
void NPC::LevelScale() {
|
||||||
|
|||||||
@ -465,7 +465,7 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
|
|||||||
char buf[10];
|
char buf[10];
|
||||||
snprintf(buf, 9, "%u", m_inst->GetItem()->ID);
|
snprintf(buf, 9, "%u", m_inst->GetItem()->ID);
|
||||||
buf[9] = '\0';
|
buf[9] = '\0';
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(m_inst);
|
args.push_back(m_inst);
|
||||||
parse->EventPlayer(EVENT_PLAYER_PICKUP, sender, buf, 0, &args);
|
parse->EventPlayer(EVENT_PLAYER_PICKUP, sender, buf, 0, &args);
|
||||||
|
|
||||||
|
|||||||
@ -1321,6 +1321,8 @@ XS(XS_Client_MovePCInstance)
|
|||||||
_log(CLIENT__ERROR, "Perl(XS_Client_MovePCInstance) attempted to process an Unknown type reference");
|
_log(CLIENT__ERROR, "Perl(XS_Client_MovePCInstance) attempted to process an Unknown type reference");
|
||||||
|
|
||||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||||
|
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
|
|||||||
@ -300,8 +300,6 @@ void ZoneDatabase::RefreshPetitionsFromDB()
|
|||||||
newpet->SetSentTime2(atol(row[13]));
|
newpet->SetSentTime2(atol(row[13]));
|
||||||
newpet->SetGMText(row[14]);
|
newpet->SetGMText(row[14]);
|
||||||
|
|
||||||
std::cout << "Petition " << row[0] << " pettime = " << newpet->GetSentTime() << std::endl;
|
|
||||||
|
|
||||||
if (atoi(row[12]) == 1)
|
if (atoi(row[12]) == 1)
|
||||||
newpet->SetCheckedOut(true);
|
newpet->SetCheckedOut(true);
|
||||||
else
|
else
|
||||||
|
|||||||
52
zone/queryserv.cpp
Normal file
52
zone/queryserv.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../common/debug.h"
|
||||||
|
#include "../common/servertalk.h"
|
||||||
|
#include "../common/string_util.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
#include "worldserver.h"
|
||||||
|
#include "net.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
extern WorldServer worldserver;
|
||||||
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
|
QueryServ::QueryServ(){
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryServ::~QueryServ(){
|
||||||
|
}
|
||||||
|
|
||||||
|
void QueryServ::SendQuery(std::string Query)
|
||||||
|
{
|
||||||
|
ServerPacket* pack = new ServerPacket(ServerOP_QSSendQuery, Query.length() + 5);
|
||||||
|
pack->WriteUInt32(Query.length()); /* Pack Query String Size so it can be dynamically broken out at queryserv */
|
||||||
|
pack->WriteString(Query.c_str()); /* Query */
|
||||||
|
worldserver.SendPacket(pack);
|
||||||
|
safe_delete(pack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QueryServ::PlayerLogEvent(int Event_Type, int Character_ID, std::string Event_Desc)
|
||||||
|
{
|
||||||
|
std::string query = StringFormat(
|
||||||
|
"INSERT INTO `qs_player_events` (event, char_id, event_desc, time) VALUES (%i, %i, '%s', UNIX_TIMESTAMP(now()))",
|
||||||
|
Event_Type, Character_ID, EscapeString(Event_Desc).c_str());
|
||||||
|
SendQuery(query);
|
||||||
|
}
|
||||||
35
zone/queryserv.h
Normal file
35
zone/queryserv.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef QUERYSERV_ZONE_H
|
||||||
|
#define QUERYSERV_ZONE_H
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
enum PlayerGenericLogEventTypes
|
||||||
|
These Enums are for the generic logging table that are not complex and require more advanced logic
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum PlayerGenericLogEventTypes {
|
||||||
|
Player_Log_Quest = 1,
|
||||||
|
Player_Log_Zoning,
|
||||||
|
Player_Log_Deaths,
|
||||||
|
Player_Log_Connect_State,
|
||||||
|
Player_Log_Levels,
|
||||||
|
Player_Log_Keyring_Addition,
|
||||||
|
Player_Log_QGlobal_Update,
|
||||||
|
Player_Log_Task_Updates,
|
||||||
|
Player_Log_AA_Purchases,
|
||||||
|
Player_Log_Trade_Skill_Events,
|
||||||
|
Player_Log_Issued_Commands,
|
||||||
|
Player_Log_Money_Transactions,
|
||||||
|
Player_Log_Alternate_Currency_Transactions,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class QueryServ{
|
||||||
|
public:
|
||||||
|
QueryServ();
|
||||||
|
~QueryServ();
|
||||||
|
void SendQuery(std::string Query);
|
||||||
|
void PlayerLogEvent(int Event_Type, int Character_ID, std::string Event_Desc);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* QUERYSERV_ZONE_H */
|
||||||
@ -20,6 +20,7 @@
|
|||||||
#define _EQE_QUESTINTERFACE_H
|
#define _EQE_QUESTINTERFACE_H
|
||||||
|
|
||||||
#include "../common/types.h"
|
#include "../common/types.h"
|
||||||
|
#include "../common/any.h"
|
||||||
#include "event_codes.h"
|
#include "event_codes.h"
|
||||||
|
|
||||||
class ItemInst;
|
class ItemInst;
|
||||||
@ -29,19 +30,19 @@ class NPC;
|
|||||||
class QuestInterface {
|
class QuestInterface {
|
||||||
public:
|
public:
|
||||||
virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) { return 0; }
|
std::vector<EQEmu::Any> *extra_pointers) { return 0; }
|
||||||
virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) { return 0; }
|
std::vector<EQEmu::Any> *extra_pointers) { return 0; }
|
||||||
virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) { return 0; }
|
std::vector<EQEmu::Any> *extra_pointers) { return 0; }
|
||||||
virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) { return 0; }
|
std::vector<EQEmu::Any> *extra_pointers) { return 0; }
|
||||||
virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) { return 0; }
|
std::vector<EQEmu::Any> *extra_pointers) { return 0; }
|
||||||
virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) { return 0; }
|
std::vector<EQEmu::Any> *extra_pointers) { return 0; }
|
||||||
virtual int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
virtual int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) { return 0; }
|
std::vector<EQEmu::Any> *extra_pointers) { return 0; }
|
||||||
|
|
||||||
virtual bool HasQuestSub(uint32 npcid, QuestEventID evt) { return false; }
|
virtual bool HasQuestSub(uint32 npcid, QuestEventID evt) { return false; }
|
||||||
virtual bool HasGlobalQuestSub(QuestEventID evt) { return false; }
|
virtual bool HasGlobalQuestSub(QuestEventID evt) { return false; }
|
||||||
@ -60,13 +61,13 @@ public:
|
|||||||
virtual void LoadEncounterScript(std::string filename, std::string encounter_name) { }
|
virtual void LoadEncounterScript(std::string filename, std::string encounter_name) { }
|
||||||
|
|
||||||
virtual int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
virtual int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) { return 0; }
|
std::vector<EQEmu::Any> *extra_pointers) { return 0; }
|
||||||
virtual int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
virtual int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) { return 0; }
|
std::vector<EQEmu::Any> *extra_pointers) { return 0; }
|
||||||
virtual int DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
virtual int DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) { return 0; }
|
std::vector<EQEmu::Any> *extra_pointers) { return 0; }
|
||||||
virtual int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
virtual int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) { return 0; }
|
std::vector<EQEmu::Any> *extra_pointers) { return 0; }
|
||||||
|
|
||||||
virtual void AddVar(std::string name, std::string val) { }
|
virtual void AddVar(std::string name, std::string val) { }
|
||||||
virtual std::string GetVar(std::string name) { return std::string(); }
|
virtual std::string GetVar(std::string name) { return std::string(); }
|
||||||
|
|||||||
@ -234,7 +234,7 @@ bool QuestParserCollection::ItemHasQuestSub(ItemInst *itm, QuestEventID evt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::EventNPC(QuestEventID evt, NPC *npc, Mob *init, std::string data, uint32 extra_data,
|
int QuestParserCollection::EventNPC(QuestEventID evt, NPC *npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
int rd = DispatchEventNPC(evt, npc, init, data, extra_data, extra_pointers);
|
int rd = DispatchEventNPC(evt, npc, init, data, extra_data, extra_pointers);
|
||||||
int rl = EventNPCLocal(evt, npc, init, data, extra_data, extra_pointers);
|
int rl = EventNPCLocal(evt, npc, init, data, extra_data, extra_pointers);
|
||||||
int rg = EventNPCGlobal(evt, npc, init, data, extra_data, extra_pointers);
|
int rg = EventNPCGlobal(evt, npc, init, data, extra_data, extra_pointers);
|
||||||
@ -252,7 +252,7 @@ int QuestParserCollection::EventNPC(QuestEventID evt, NPC *npc, Mob *init, std::
|
|||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int QuestParserCollection::EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
std::map<uint32, uint32>::iterator iter = _npc_quest_status.find(npc->GetNPCTypeID());
|
std::map<uint32, uint32>::iterator iter = _npc_quest_status.find(npc->GetNPCTypeID());
|
||||||
if(iter != _npc_quest_status.end()) {
|
if(iter != _npc_quest_status.end()) {
|
||||||
//loaded or failed to load
|
//loaded or failed to load
|
||||||
@ -275,7 +275,7 @@ int QuestParserCollection::EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int QuestParserCollection::EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
if(_global_npc_quest_status != QuestUnloaded && _global_npc_quest_status != QuestFailedToLoad) {
|
if(_global_npc_quest_status != QuestUnloaded && _global_npc_quest_status != QuestFailedToLoad) {
|
||||||
std::map<uint32, QuestInterface*>::iterator qiter = _interfaces.find(_global_npc_quest_status);
|
std::map<uint32, QuestInterface*>::iterator qiter = _interfaces.find(_global_npc_quest_status);
|
||||||
return qiter->second->EventGlobalNPC(evt, npc, init, data, extra_data, extra_pointers);
|
return qiter->second->EventGlobalNPC(evt, npc, init, data, extra_data, extra_pointers);
|
||||||
@ -294,7 +294,7 @@ int QuestParserCollection::EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int QuestParserCollection::EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
int rd = DispatchEventPlayer(evt, client, data, extra_data, extra_pointers);
|
int rd = DispatchEventPlayer(evt, client, data, extra_data, extra_pointers);
|
||||||
int rl = EventPlayerLocal(evt, client, data, extra_data, extra_pointers);
|
int rl = EventPlayerLocal(evt, client, data, extra_data, extra_pointers);
|
||||||
int rg = EventPlayerGlobal(evt, client, data, extra_data, extra_pointers);
|
int rg = EventPlayerGlobal(evt, client, data, extra_data, extra_pointers);
|
||||||
@ -312,7 +312,7 @@ int QuestParserCollection::EventPlayer(QuestEventID evt, Client *client, std::st
|
|||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int QuestParserCollection::EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
if(_player_quest_status == QuestUnloaded) {
|
if(_player_quest_status == QuestUnloaded) {
|
||||||
std::string filename;
|
std::string filename;
|
||||||
QuestInterface *qi = GetQIByPlayerQuest(filename);
|
QuestInterface *qi = GetQIByPlayerQuest(filename);
|
||||||
@ -331,7 +331,7 @@ int QuestParserCollection::EventPlayerLocal(QuestEventID evt, Client *client, st
|
|||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int QuestParserCollection::EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
if(_global_player_quest_status == QuestUnloaded) {
|
if(_global_player_quest_status == QuestUnloaded) {
|
||||||
std::string filename;
|
std::string filename;
|
||||||
QuestInterface *qi = GetQIByGlobalPlayerQuest(filename);
|
QuestInterface *qi = GetQIByGlobalPlayerQuest(filename);
|
||||||
@ -350,7 +350,7 @@ int QuestParserCollection::EventPlayerGlobal(QuestEventID evt, Client *client, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
int QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
std::string item_script;
|
std::string item_script;
|
||||||
if(item->GetItem()->ScriptFileID != 0) {
|
if(item->GetItem()->ScriptFileID != 0) {
|
||||||
item_script = "script_";
|
item_script = "script_";
|
||||||
@ -396,7 +396,7 @@ int QuestParserCollection::EventItem(QuestEventID evt, Client *client, ItemInst
|
|||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
int QuestParserCollection::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
std::map<uint32, uint32>::iterator iter = _spell_quest_status.find(spell_id);
|
std::map<uint32, uint32>::iterator iter = _spell_quest_status.find(spell_id);
|
||||||
if(iter != _spell_quest_status.end()) {
|
if(iter != _spell_quest_status.end()) {
|
||||||
//loaded or failed to load
|
//loaded or failed to load
|
||||||
@ -431,7 +431,7 @@ int QuestParserCollection::EventSpell(QuestEventID evt, NPC* npc, Client *client
|
|||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
int QuestParserCollection::EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
auto iter = _encounter_quest_status.find(encounter_name);
|
auto iter = _encounter_quest_status.find(encounter_name);
|
||||||
if(iter != _encounter_quest_status.end()) {
|
if(iter != _encounter_quest_status.end()) {
|
||||||
//loaded or failed to load
|
//loaded or failed to load
|
||||||
@ -600,9 +600,8 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
|
|||||||
}
|
}
|
||||||
|
|
||||||
QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename) {
|
QuestInterface *QuestParserCollection::GetQIByPlayerQuest(std::string &filename) {
|
||||||
|
if(!zone || !zone->IsLoaded())
|
||||||
if(!zone)
|
return nullptr;
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
//first look for /quests/zone/player_v[instance_version].ext (precedence)
|
//first look for /quests/zone/player_v[instance_version].ext (precedence)
|
||||||
filename = "quests/";
|
filename = "quests/";
|
||||||
@ -975,7 +974,7 @@ void QuestParserCollection::GetErrors(std::list<std::string> &err) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int QuestParserCollection::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
auto iter = _load_precedence.begin();
|
auto iter = _load_precedence.begin();
|
||||||
while(iter != _load_precedence.end()) {
|
while(iter != _load_precedence.end()) {
|
||||||
@ -989,7 +988,7 @@ int QuestParserCollection::DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *ini
|
|||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int QuestParserCollection::DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
auto iter = _load_precedence.begin();
|
auto iter = _load_precedence.begin();
|
||||||
while(iter != _load_precedence.end()) {
|
while(iter != _load_precedence.end()) {
|
||||||
@ -1003,7 +1002,7 @@ int QuestParserCollection::DispatchEventPlayer(QuestEventID evt, Client *client,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data,
|
int QuestParserCollection::DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data,
|
||||||
uint32 extra_data, std::vector<void*> *extra_pointers) {
|
uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
auto iter = _load_precedence.begin();
|
auto iter = _load_precedence.begin();
|
||||||
while(iter != _load_precedence.end()) {
|
while(iter != _load_precedence.end()) {
|
||||||
@ -1017,7 +1016,7 @@ int QuestParserCollection::DispatchEventItem(QuestEventID evt, Client *client, I
|
|||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
int QuestParserCollection::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers) {
|
std::vector<EQEmu::Any> *extra_pointers) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
auto iter = _load_precedence.begin();
|
auto iter = _load_precedence.begin();
|
||||||
while(iter != _load_precedence.end()) {
|
while(iter != _load_precedence.end()) {
|
||||||
|
|||||||
@ -51,15 +51,15 @@ public:
|
|||||||
bool ItemHasQuestSub(ItemInst *itm, QuestEventID evt);
|
bool ItemHasQuestSub(ItemInst *itm, QuestEventID evt);
|
||||||
|
|
||||||
int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers = nullptr);
|
std::vector<EQEmu::Any> *extra_pointers = nullptr);
|
||||||
int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers = nullptr);
|
std::vector<EQEmu::Any> *extra_pointers = nullptr);
|
||||||
int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers = nullptr);
|
std::vector<EQEmu::Any> *extra_pointers = nullptr);
|
||||||
int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers = nullptr);
|
std::vector<EQEmu::Any> *extra_pointers = nullptr);
|
||||||
int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
int EventEncounter(QuestEventID evt, std::string encounter_name, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers = nullptr);
|
std::vector<EQEmu::Any> *extra_pointers = nullptr);
|
||||||
|
|
||||||
void GetErrors(std::list<std::string> &err);
|
void GetErrors(std::list<std::string> &err);
|
||||||
|
|
||||||
@ -69,10 +69,10 @@ private:
|
|||||||
bool PlayerHasQuestSubLocal(QuestEventID evt);
|
bool PlayerHasQuestSubLocal(QuestEventID evt);
|
||||||
bool PlayerHasQuestSubGlobal(QuestEventID evt);
|
bool PlayerHasQuestSubGlobal(QuestEventID evt);
|
||||||
|
|
||||||
int EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector<void*> *extra_pointers);
|
int EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers);
|
||||||
int EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector<void*> *extra_pointers);
|
int EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers);
|
||||||
int EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector<void*> *extra_pointers);
|
int EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers);
|
||||||
int EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector<void*> *extra_pointers);
|
int EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
QuestInterface *GetQIByNPCQuest(uint32 npcid, std::string &filename);
|
QuestInterface *GetQIByNPCQuest(uint32 npcid, std::string &filename);
|
||||||
QuestInterface *GetQIByGlobalNPCQuest(std::string &filename);
|
QuestInterface *GetQIByGlobalNPCQuest(std::string &filename);
|
||||||
@ -83,13 +83,13 @@ private:
|
|||||||
QuestInterface *GetQIByEncounterQuest(std::string encounter_name, std::string &filename);
|
QuestInterface *GetQIByEncounterQuest(std::string encounter_name, std::string &filename);
|
||||||
|
|
||||||
int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
int DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
int DispatchEventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
|
||||||
std::vector<void*> *extra_pointers);
|
std::vector<EQEmu::Any> *extra_pointers);
|
||||||
|
|
||||||
std::map<uint32, QuestInterface*> _interfaces;
|
std::map<uint32, QuestInterface*> _interfaces;
|
||||||
std::map<uint32, std::string> _extensions;
|
std::map<uint32, std::string> _extensions;
|
||||||
|
|||||||
@ -75,12 +75,12 @@ And then at then end of embparser.cpp, add:
|
|||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "qglobals.h"
|
#include "qglobals.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "queryserv.h"
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#include "bot.h"
|
#include "bot.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
extern Zone* zone;
|
extern Zone* zone;
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
extern EntityList entity_list;
|
extern EntityList entity_list;
|
||||||
@ -173,7 +173,6 @@ void QuestManager::EndQuest() {
|
|||||||
else
|
else
|
||||||
++cur;
|
++cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
run.owner->Depop();
|
run.owner->Depop();
|
||||||
}
|
}
|
||||||
quests_running_.pop();
|
quests_running_.pop();
|
||||||
@ -1294,33 +1293,29 @@ void QuestManager::setglobal(const char *varname, const char *newvalue, int opti
|
|||||||
int qgNpcid = owner->GetNPCTypeID();
|
int qgNpcid = owner->GetNPCTypeID();
|
||||||
|
|
||||||
/* options value determines the availability of global variables to NPCs when a quest begins
|
/* options value determines the availability of global variables to NPCs when a quest begins
|
||||||
------------------------------------------------------------------
|
------------------------------------------------------------------
|
||||||
value npcid player zone
|
value npcid player zone
|
||||||
------------------------------------------------------------------
|
------------------------------------------------------------------
|
||||||
0 this this this
|
0 this this this
|
||||||
1 all this this
|
1 all this this
|
||||||
2 this all this
|
2 this all this
|
||||||
3 all all this
|
3 all all this
|
||||||
4 this this all
|
4 this this all
|
||||||
5 all this all
|
5 all this all
|
||||||
6 this all all
|
6 this all all
|
||||||
7 all all all
|
7 all all all
|
||||||
*/
|
*/
|
||||||
if (initiator && initiator->IsClient()) // some events like waypoint and spawn don't have a player involved
|
|
||||||
{
|
if (initiator && initiator->IsClient()){ // some events like waypoint and spawn don't have a player involved
|
||||||
qgCharid=initiator->CharacterID();
|
qgCharid=initiator->CharacterID();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
else
|
|
||||||
{
|
|
||||||
qgCharid=-qgNpcid; // make char id negative npc id as a fudge
|
qgCharid=-qgNpcid; // make char id negative npc id as a fudge
|
||||||
}
|
}
|
||||||
if (options < 0 || options > 7)
|
if (options < 0 || options > 7) {
|
||||||
{
|
|
||||||
std::cerr << "Invalid options for global var " << varname << " using defaults" << std::endl;
|
std::cerr << "Invalid options for global var " << varname << " using defaults" << std::endl;
|
||||||
} // default = 0 (only this npcid,player and zone)
|
} // default = 0 (only this npcid,player and zone)
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if (options & 1)
|
if (options & 1)
|
||||||
qgNpcid=0;
|
qgNpcid=0;
|
||||||
if (options & 2)
|
if (options & 2)
|
||||||
@ -1330,30 +1325,32 @@ void QuestManager::setglobal(const char *varname, const char *newvalue, int opti
|
|||||||
}
|
}
|
||||||
|
|
||||||
InsertQuestGlobal(qgCharid, qgNpcid, qgZoneid, varname, newvalue, QGVarDuration(duration));
|
InsertQuestGlobal(qgCharid, qgNpcid, qgZoneid, varname, newvalue, QGVarDuration(duration));
|
||||||
|
|
||||||
|
/* QS: PlayerLogQGlobalUpdate */
|
||||||
|
if (RuleB(QueryServ, PlayerLogQGlobalUpdate) && qgCharid && qgCharid > 0 && initiator && initiator->IsClient()){
|
||||||
|
std::string event_desc = StringFormat("Update :: qglobal:%s to qvalue:%s zoneid:%i instid:%i", varname, newvalue, initiator->GetZoneID(), initiator->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_QGlobal_Update, qgCharid, event_desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inserts global variable into quest_globals table */
|
/* Inserts global variable into quest_globals table */
|
||||||
int QuestManager::InsertQuestGlobal(
|
int QuestManager::InsertQuestGlobal(int charid, int npcid, int zoneid, const char *varname, const char *varvalue, int duration) {
|
||||||
int charid, int npcid, int zoneid,
|
|
||||||
const char *varname, const char *varvalue,
|
|
||||||
int duration)
|
|
||||||
{
|
|
||||||
char *query = 0;
|
char *query = 0;
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
|
|
||||||
// Make duration string either "unix_timestamp(now()) + xxx" or "NULL"
|
// Make duration string either "unix_timestamp(now()) + xxx" or "NULL"
|
||||||
std::stringstream duration_ss;
|
std::stringstream duration_ss;
|
||||||
if (duration == INT_MAX)
|
if (duration == INT_MAX) {
|
||||||
{
|
|
||||||
duration_ss << "NULL";
|
duration_ss << "NULL";
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
duration_ss << "unix_timestamp(now()) + " << duration;
|
duration_ss << "unix_timestamp(now()) + " << duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: this should be escaping the contents of arglist
|
/*
|
||||||
//npcwise a malicious script can arbitrarily alter the DB
|
NOTE: this should be escaping the contents of arglist
|
||||||
|
npcwise a malicious script can arbitrarily alter the DB
|
||||||
|
*/
|
||||||
uint32 last_id = 0;
|
uint32 last_id = 0;
|
||||||
if (!database.RunQuery(query, MakeAnyLenString(&query,
|
if (!database.RunQuery(query, MakeAnyLenString(&query,
|
||||||
"REPLACE INTO quest_globals (charid, npcid, zoneid, name, value, expdate)"
|
"REPLACE INTO quest_globals (charid, npcid, zoneid, name, value, expdate)"
|
||||||
@ -1365,9 +1362,8 @@ int QuestManager::InsertQuestGlobal(
|
|||||||
}
|
}
|
||||||
safe_delete_array(query);
|
safe_delete_array(query);
|
||||||
|
|
||||||
if(zone)
|
if(zone) {
|
||||||
{
|
/* Delete existing qglobal data and update zone processes */
|
||||||
//first delete our global
|
|
||||||
ServerPacket* pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
|
ServerPacket* pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
|
||||||
ServerQGlobalDelete_Struct *qgd = (ServerQGlobalDelete_Struct*)pack->pBuffer;
|
ServerQGlobalDelete_Struct *qgd = (ServerQGlobalDelete_Struct*)pack->pBuffer;
|
||||||
qgd->npc_id = npcid;
|
qgd->npc_id = npcid;
|
||||||
@ -1383,18 +1379,16 @@ int QuestManager::InsertQuestGlobal(
|
|||||||
worldserver.SendPacket(pack);
|
worldserver.SendPacket(pack);
|
||||||
safe_delete(pack);
|
safe_delete(pack);
|
||||||
|
|
||||||
//then create a new one with the new id
|
/* Create new qglobal data and update zone processes */
|
||||||
pack = new ServerPacket(ServerOP_QGlobalUpdate, sizeof(ServerQGlobalUpdate_Struct));
|
pack = new ServerPacket(ServerOP_QGlobalUpdate, sizeof(ServerQGlobalUpdate_Struct));
|
||||||
ServerQGlobalUpdate_Struct *qgu = (ServerQGlobalUpdate_Struct*)pack->pBuffer;
|
ServerQGlobalUpdate_Struct *qgu = (ServerQGlobalUpdate_Struct*)pack->pBuffer;
|
||||||
qgu->npc_id = npcid;
|
qgu->npc_id = npcid;
|
||||||
qgu->char_id = charid;
|
qgu->char_id = charid;
|
||||||
qgu->zone_id = zoneid;
|
qgu->zone_id = zoneid;
|
||||||
if(duration == INT_MAX)
|
if(duration == INT_MAX) {
|
||||||
{
|
|
||||||
qgu->expdate = 0xFFFFFFFF;
|
qgu->expdate = 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
qgu->expdate = Timer::GetTimeSeconds() + duration;
|
qgu->expdate = Timer::GetTimeSeconds() + duration;
|
||||||
}
|
}
|
||||||
strcpy((char*)qgu->name, varname);
|
strcpy((char*)qgu->name, varname);
|
||||||
@ -1420,8 +1414,7 @@ int QuestManager::InsertQuestGlobal(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuestManager::targlobal(const char *varname, const char *value, const char *duration, int qgNpcid, int qgCharid, int qgZoneid)
|
void QuestManager::targlobal(const char *varname, const char *value, const char *duration, int qgNpcid, int qgCharid, int qgZoneid) {
|
||||||
{
|
|
||||||
InsertQuestGlobal(qgCharid, qgNpcid, qgZoneid, varname, value, QGVarDuration(duration));
|
InsertQuestGlobal(qgCharid, qgNpcid, qgZoneid, varname, value, QGVarDuration(duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1432,15 +1425,24 @@ void QuestManager::delglobal(const char *varname) {
|
|||||||
int qgZoneid=zone->GetZoneID();
|
int qgZoneid=zone->GetZoneID();
|
||||||
int qgCharid=0;
|
int qgCharid=0;
|
||||||
int qgNpcid=owner->GetNPCTypeID();
|
int qgNpcid=owner->GetNPCTypeID();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (initiator && initiator->IsClient()) // some events like waypoint and spawn don't have a player involved
|
if (initiator && initiator->IsClient()) // some events like waypoint and spawn don't have a player involved
|
||||||
{
|
{
|
||||||
qgCharid=initiator->CharacterID();
|
qgCharid=initiator->CharacterID();
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
qgCharid=-qgNpcid; // make char id negative npc id as a fudge
|
qgCharid=-qgNpcid; // make char id negative npc id as a fudge
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* QS: PlayerLogQGlobalUpdate */
|
||||||
|
if (RuleB(QueryServ, PlayerLogQGlobalUpdate) && qgCharid && qgCharid > 0 && initiator && initiator->IsClient()){
|
||||||
|
std::string event_desc = StringFormat("Deleted :: qglobal:%s zoneid:%i instid:%i", varname, initiator->GetZoneID(), initiator->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_QGlobal_Update, qgCharid, event_desc);
|
||||||
|
}
|
||||||
|
|
||||||
if (!database.RunQuery(query,
|
if (!database.RunQuery(query,
|
||||||
MakeAnyLenString(&query,
|
MakeAnyLenString(&query,
|
||||||
"DELETE FROM quest_globals WHERE name='%s'"
|
"DELETE FROM quest_globals WHERE name='%s'"
|
||||||
@ -1451,8 +1453,7 @@ void QuestManager::delglobal(const char *varname) {
|
|||||||
}
|
}
|
||||||
safe_delete_array(query);
|
safe_delete_array(query);
|
||||||
|
|
||||||
if(zone)
|
if(zone) {
|
||||||
{
|
|
||||||
ServerPacket* pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
|
ServerPacket* pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
|
||||||
ServerQGlobalDelete_Struct *qgu = (ServerQGlobalDelete_Struct*)pack->pBuffer;
|
ServerQGlobalDelete_Struct *qgu = (ServerQGlobalDelete_Struct*)pack->pBuffer;
|
||||||
|
|
||||||
@ -1701,17 +1702,14 @@ void QuestManager::showgrid(int grid) {
|
|||||||
pts.push_back(pt);
|
pts.push_back(pt);
|
||||||
|
|
||||||
// Retrieve all waypoints for this grid
|
// Retrieve all waypoints for this grid
|
||||||
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT `x`,`y`,`z` FROM grid_entries WHERE `gridid`=%i AND `zoneid`=%i ORDER BY `number`",grid,zone->GetZoneID()),errbuf,&result))
|
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT `x`,`y`,`z` FROM grid_entries WHERE `gridid`=%i AND `zoneid`=%i ORDER BY `number`",grid,zone->GetZoneID()),errbuf,&result)) {
|
||||||
{
|
while((row = mysql_fetch_row(result))) {
|
||||||
while((row = mysql_fetch_row(result)))
|
|
||||||
{
|
|
||||||
pt.x = atof(row[0]);
|
pt.x = atof(row[0]);
|
||||||
pt.y = atof(row[1]);
|
pt.y = atof(row[1]);
|
||||||
pt.z = atof(row[2]);
|
pt.z = atof(row[2]);
|
||||||
pts.push_back(pt);
|
pts.push_back(pt);
|
||||||
}
|
}
|
||||||
mysql_free_result(result);
|
mysql_free_result(result);
|
||||||
|
|
||||||
initiator->SendPathPacket(pts);
|
initiator->SendPathPacket(pts);
|
||||||
}
|
}
|
||||||
else // DB query error!
|
else // DB query error!
|
||||||
|
|||||||
524
zone/spawn2.cpp
524
zone/spawn2.cpp
@ -354,96 +354,86 @@ void Spawn2::DeathReset(bool realdeath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay) {
|
bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay) {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char* query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
const char *zone_name = database.GetZoneName(zoneid);
|
const char *zone_name = database.GetZoneName(zoneid);
|
||||||
|
std::string query = StringFormat("SELECT id, spawngroupID, x, y, z, heading, "
|
||||||
MakeAnyLenString(&query, "SELECT id, spawngroupID, x, y, z, heading, respawntime, variance, pathgrid, _condition, cond_value, enabled, animation FROM spawn2 WHERE zone='%s' AND version=%u", zone_name, version);
|
"respawntime, variance, pathgrid, _condition, "
|
||||||
if (RunQuery(query, strlen(query), errbuf, &result))
|
"cond_value, enabled, animation FROM spawn2 "
|
||||||
{
|
"WHERE zone = '%s' AND version = %u",
|
||||||
safe_delete_array(query);
|
zone_name, version);
|
||||||
while((row = mysql_fetch_row(result)))
|
auto results = QueryDatabase(query);
|
||||||
{
|
if (!results.Success()) {
|
||||||
Spawn2* newSpawn = 0;
|
LogFile->write(EQEMuLog::Error, "Error in PopulateZoneLists query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
|
||||||
bool perl_enabled = atoi(row[11]) == 1 ? true : false;
|
|
||||||
uint32 spawnLeft = (GetSpawnTimeLeft(atoi(row[0]), zone->GetInstanceID()) * 1000);
|
|
||||||
newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atoi(row[6]), atoi(row[7]), spawnLeft, atoi(row[8]), atoi(row[9]), atoi(row[10]), perl_enabled, (EmuAppearance)atoi(row[12]));
|
|
||||||
spawn2_list.Insert( newSpawn );
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in PopulateZoneLists query '%s': %s", query, errbuf);
|
|
||||||
safe_delete_array(query);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
Spawn2* newSpawn = 0;
|
||||||
|
|
||||||
|
bool perl_enabled = atoi(row[11]) == 1? true: false;
|
||||||
|
uint32 spawnLeft = (GetSpawnTimeLeft(atoi(row[0]), zone->GetInstanceID()) * 1000);
|
||||||
|
newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[2]), atof(row[3]), atof(row[4]),
|
||||||
|
atof(row[5]), atoi(row[6]), atoi(row[7]), spawnLeft, atoi(row[8]),
|
||||||
|
atoi(row[9]), atoi(row[10]), perl_enabled, (EmuAppearance)atoi(row[12]));
|
||||||
|
|
||||||
|
spawn2_list.Insert(newSpawn);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Spawn2* ZoneDatabase::LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2id, uint32 timeleft) {
|
Spawn2* ZoneDatabase::LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2id, uint32 timeleft) {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char* query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT id, spawngroupID, x, y, z, heading, respawntime, variance, pathgrid, _condition, cond_value, enabled, animation FROM spawn2 WHERE id=%i", spawn2id), errbuf, &result)) {
|
std::string query = StringFormat("SELECT id, spawngroupID, x, y, z, heading, "
|
||||||
if (mysql_num_rows(result) == 1)
|
"respawntime, variance, pathgrid, _condition, "
|
||||||
{
|
"cond_value, enabled, animation FROM spawn2 "
|
||||||
row = mysql_fetch_row(result);
|
"WHERE id = %i", spawn2id);
|
||||||
bool perl_enabled = atoi(row[11]) == 1 ? true : false;
|
auto results = QueryDatabase(query);
|
||||||
Spawn2* newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atoi(row[6]), atoi(row[7]), timeleft, atoi(row[8]), atoi(row[9]), atoi(row[10]), perl_enabled, (EmuAppearance)atoi(row[12]));
|
if (!results.Success()) {
|
||||||
spawn2_list.Insert( newSpawn );
|
LogFile->write(EQEMuLog::Error, "Error in LoadSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
mysql_free_result(result);
|
return nullptr;
|
||||||
safe_delete_array(query);
|
}
|
||||||
return newSpawn;
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadSpawn2 query '%s': %s", query, errbuf);
|
if (results.RowCount() != 1) {
|
||||||
safe_delete_array(query);
|
LogFile->write(EQEMuLog::Error, "Error in LoadSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
return 0;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
bool perl_enabled = atoi(row[11]) == 1 ? true : false;
|
||||||
|
|
||||||
|
Spawn2* newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[2]), atof(row[3]), atof(row[4]),
|
||||||
|
atof(row[5]), atoi(row[6]), atoi(row[7]), timeleft, atoi(row[8]),
|
||||||
|
atoi(row[9]), atoi(row[10]), perl_enabled, (EmuAppearance)atoi(row[12]));
|
||||||
|
|
||||||
|
spawn2_list.Insert(newSpawn);
|
||||||
|
|
||||||
|
return newSpawn;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, float heading, float x, float y, float z, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value)
|
bool ZoneDatabase::CreateSpawn2(Client *client, uint32 spawngroup, const char* zone, float heading, float x, float y, float z, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value)
|
||||||
{
|
{
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
|
|
||||||
char *query = 0;
|
std::string query = StringFormat("INSERT INTO spawn2 (spawngroupID, zone, x, y, z, heading, "
|
||||||
uint32 affected_rows = 0;
|
"respawntime, variance, _condition, cond_value) "
|
||||||
|
"VALUES (%i, '%s', %f, %f, %f, %f, %i, %i, %u, %i)",
|
||||||
// if(GetInverseXY()==1) {
|
spawngroup, zone, x, y, z, heading,
|
||||||
// float temp=x;
|
respawn, variance, condition, cond_value);
|
||||||
// x=y;
|
auto results = QueryDatabase(query);
|
||||||
// y=temp;
|
if (!results.Success()) {
|
||||||
// }
|
LogFile->write(EQEMuLog::Error, "Error in CreateSpawn2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
if (RunQuery(query, MakeAnyLenString(&query,
|
|
||||||
"INSERT INTO spawn2 (spawngroupID,zone,x,y,z,heading,respawntime,variance,_condition,cond_value) Values (%i, '%s', %f, %f, %f, %f, %i, %i, %u, %i)",
|
|
||||||
spawngroup, zone, x, y, z, heading, respawn, variance, condition, cond_value
|
|
||||||
), errbuf, 0, &affected_rows)) {
|
|
||||||
safe_delete_array(query);
|
|
||||||
if (affected_rows == 1) {
|
|
||||||
if(c) c->LogSQL(query);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in CreateSpawn2 query '%s': %s", query, errbuf);
|
|
||||||
safe_delete_array(query);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if (results.RowsAffected() != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(client)
|
||||||
|
client->LogSQL(query.c_str());
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Zone::CountSpawn2() {
|
uint32 Zone::CountSpawn2() {
|
||||||
@ -671,177 +661,159 @@ void SpawnConditionManager::ExecEvent(SpawnEvent &event, bool send_update) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SpawnConditionManager::UpdateDBEvent(SpawnEvent &event) {
|
void SpawnConditionManager::UpdateDBEvent(SpawnEvent &event) {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char* query = 0;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
SpawnCondition cond;
|
std::string query = StringFormat("UPDATE spawn_events SET "
|
||||||
len = MakeAnyLenString(&query,
|
"next_minute = %d, next_hour = %d, "
|
||||||
"UPDATE spawn_events SET "
|
"next_day = %d, next_month = %d, "
|
||||||
"next_minute=%d, next_hour=%d, next_day=%d, next_month=%d, "
|
"next_year = %d, enabled = %d, "
|
||||||
"next_year=%d, enabled=%d, strict=%d "
|
"strict = %d WHERE id = %d",
|
||||||
"WHERE id=%d",
|
event.next.minute, event.next.hour,
|
||||||
event.next.minute, event.next.hour, event.next.day, event.next.month,
|
event.next.day, event.next.month,
|
||||||
event.next.year, event.enabled?1:0, event.strict?1:0,event.id
|
event.next.year, event.enabled? 1: 0,
|
||||||
);
|
event.strict? 1: 0, event.id);
|
||||||
if(!database.RunQuery(query, len, errbuf)) {
|
auto results = database.QueryDatabase(query);
|
||||||
LogFile->write(EQEMuLog::Error, "Unable to update spawn event '%s': %s\n", query, errbuf);
|
if(!results.Success())
|
||||||
}
|
LogFile->write(EQEMuLog::Error, "Unable to update spawn event '%s': %s\n", query.c_str(), results.ErrorMessage().c_str());
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpawnConditionManager::UpdateDBCondition(const char* zone_name, uint32 instance_id, uint16 cond_id, int16 value) {
|
void SpawnConditionManager::UpdateDBCondition(const char* zone_name, uint32 instance_id, uint16 cond_id, int16 value) {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char* query = 0;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
SpawnCondition cond;
|
std::string query = StringFormat("REPLACE INTO spawn_condition_values "
|
||||||
len = MakeAnyLenString(&query,
|
"(id, value, zone, instance_id) "
|
||||||
"REPLACE INTO spawn_condition_values (id, value, zone, instance_id) VALUES(%u, %u, '%s', %u)",
|
"VALUES( %u, %u, '%s', %u)",
|
||||||
cond_id, value, zone_name, instance_id
|
cond_id, value, zone_name, instance_id);
|
||||||
);
|
auto results = database.QueryDatabase(query);
|
||||||
if(!database.RunQuery(query, len, errbuf)) {
|
if(!results.Success())
|
||||||
LogFile->write(EQEMuLog::Error, "Unable to update spawn condition '%s': %s\n", query, errbuf);
|
LogFile->write(EQEMuLog::Error, "Unable to update spawn condition '%s': %s\n", query.c_str(), results.ErrorMessage().c_str());
|
||||||
}
|
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpawnConditionManager::LoadDBEvent(uint32 event_id, SpawnEvent &event, std::string &zone_name) {
|
bool SpawnConditionManager::LoadDBEvent(uint32 event_id, SpawnEvent &event, std::string &zone_name) {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char* query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
bool ret = false;
|
std::string query = StringFormat("SELECT id, cond_id, period, "
|
||||||
|
"next_minute, next_hour, next_day, "
|
||||||
len = MakeAnyLenString(&query,
|
"next_month, next_year, enabled, "
|
||||||
"SELECT id,cond_id,period,next_minute,next_hour,next_day,next_month,next_year,enabled,action,argument,strict,zone "
|
"action, argument, strict, zone "
|
||||||
"FROM spawn_events WHERE id=%d", event_id);
|
"FROM spawn_events WHERE id = %d", event_id);
|
||||||
if (database.RunQuery(query, len, errbuf, &result)) {
|
auto results = database.QueryDatabase(query);
|
||||||
safe_delete_array(query);
|
if (!results.Success()) {
|
||||||
if((row = mysql_fetch_row(result))) {
|
LogFile->write(EQEMuLog::Error, "Error in LoadDBEvent query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
event.id = atoi(row[0]);
|
return false;
|
||||||
event.condition_id = atoi(row[1]);
|
|
||||||
event.period = atoi(row[2]);
|
|
||||||
|
|
||||||
event.next.minute = atoi(row[3]);
|
|
||||||
event.next.hour = atoi(row[4]);
|
|
||||||
event.next.day = atoi(row[5]);
|
|
||||||
event.next.month = atoi(row[6]);
|
|
||||||
event.next.year = atoi(row[7]);
|
|
||||||
|
|
||||||
event.enabled = atoi(row[8])==0?false:true;
|
|
||||||
event.action = (SpawnEvent::Action) atoi(row[9]);
|
|
||||||
event.argument = atoi(row[10]);
|
|
||||||
event.strict = atoi(row[11])==0?false:true;
|
|
||||||
zone_name = row[12];
|
|
||||||
|
|
||||||
std::string t;
|
|
||||||
EQTime::ToString(&event.next, t);
|
|
||||||
_log(SPAWNS__CONDITIONS, "(LoadDBEvent) Loaded %s spawn event %d on condition %d with period %d, action %d, argument %d, strict %d. Will trigger at %s",
|
|
||||||
event.enabled?"enabled":"disabled", event.id, event.condition_id, event.period, event.action, event.argument, event.strict, t.c_str());
|
|
||||||
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
} else {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadDBEvent query '%s': %s", query, errbuf);
|
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
return(ret);
|
|
||||||
|
if (results.RowCount() == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
event.id = atoi(row[0]);
|
||||||
|
event.condition_id = atoi(row[1]);
|
||||||
|
event.period = atoi(row[2]);
|
||||||
|
|
||||||
|
event.next.minute = atoi(row[3]);
|
||||||
|
event.next.hour = atoi(row[4]);
|
||||||
|
event.next.day = atoi(row[5]);
|
||||||
|
event.next.month = atoi(row[6]);
|
||||||
|
event.next.year = atoi(row[7]);
|
||||||
|
|
||||||
|
event.enabled = atoi(row[8]) != 0;
|
||||||
|
event.action = (SpawnEvent::Action) atoi(row[9]);
|
||||||
|
event.argument = atoi(row[10]);
|
||||||
|
event.strict = atoi(row[11]) != 0;
|
||||||
|
zone_name = row[12];
|
||||||
|
|
||||||
|
std::string timeAsString;
|
||||||
|
EQTime::ToString(&event.next, timeAsString);
|
||||||
|
|
||||||
|
_log(SPAWNS__CONDITIONS, "(LoadDBEvent) Loaded %s spawn event %d on condition %d with period %d, action %d, argument %d, strict %d. Will trigger at %s", event.enabled? "enabled": "disabled", event.id, event.condition_id, event.period, event.action, event.argument, event.strict, timeAsString.c_str());
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 instance_id)
|
bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 instance_id)
|
||||||
{
|
{
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char* query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
//clear out old stuff..
|
//clear out old stuff..
|
||||||
spawn_conditions.clear();
|
spawn_conditions.clear();
|
||||||
|
|
||||||
//load spawn conditions
|
|
||||||
SpawnCondition cond;
|
|
||||||
len = MakeAnyLenString(&query, "SELECT id, onchange, value FROM spawn_conditions WHERE zone='%s'", zone_name);
|
|
||||||
if (database.RunQuery(query, len, errbuf, &result)) {
|
|
||||||
safe_delete_array(query);
|
|
||||||
while((row = mysql_fetch_row(result))) {
|
|
||||||
cond.condition_id = atoi(row[0]);
|
|
||||||
cond.value = atoi(row[2]);
|
|
||||||
cond.on_change = (SpawnCondition::OnChange) atoi(row[1]);
|
|
||||||
spawn_conditions[cond.condition_id] = cond;
|
|
||||||
|
|
||||||
_log(SPAWNS__CONDITIONS, "Loaded spawn condition %d with value %d and on_change %d", cond.condition_id, cond.value, cond.on_change);
|
|
||||||
}
|
std::string query = StringFormat("SELECT id, onchange, value "
|
||||||
mysql_free_result(result);
|
"FROM spawn_conditions "
|
||||||
} else {
|
"WHERE zone = '%s'", zone_name);
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query, errbuf);
|
auto results = database.QueryDatabase(query);
|
||||||
safe_delete_array(query);
|
if (!results.Success()) {
|
||||||
|
LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
//load spawn conditions
|
||||||
|
SpawnCondition cond;
|
||||||
|
|
||||||
|
cond.condition_id = atoi(row[0]);
|
||||||
|
cond.value = atoi(row[2]);
|
||||||
|
cond.on_change = (SpawnCondition::OnChange) atoi(row[1]);
|
||||||
|
spawn_conditions[cond.condition_id] = cond;
|
||||||
|
|
||||||
|
_log(SPAWNS__CONDITIONS, "Loaded spawn condition %d with value %d and on_change %d", cond.condition_id, cond.value, cond.on_change);
|
||||||
|
}
|
||||||
|
|
||||||
//load values
|
//load values
|
||||||
len = MakeAnyLenString(&query, "SELECT id, value FROM spawn_condition_values WHERE zone='%s' and instance_id=%u", zone_name, instance_id);
|
query = StringFormat("SELECT id, value FROM spawn_condition_values "
|
||||||
if (database.RunQuery(query, len, errbuf, &result)) {
|
"WHERE zone = '%s' AND instance_id = %u",
|
||||||
safe_delete_array(query);
|
zone_name, instance_id);
|
||||||
while((row = mysql_fetch_row(result)))
|
results = database.QueryDatabase(query);
|
||||||
{
|
if (!results.Success()) {
|
||||||
std::map<uint16, SpawnCondition>::iterator iter = spawn_conditions.find(atoi(row[0]));
|
LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
if(iter != spawn_conditions.end())
|
|
||||||
{
|
|
||||||
iter->second.value = atoi(row[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions query '%s': %s", query, errbuf);
|
|
||||||
safe_delete_array(query);
|
|
||||||
spawn_conditions.clear();
|
spawn_conditions.clear();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
auto iter = spawn_conditions.find(atoi(row[0]));
|
||||||
|
|
||||||
|
if(iter != spawn_conditions.end())
|
||||||
|
iter->second.value = atoi(row[1]);
|
||||||
|
}
|
||||||
|
|
||||||
//load spawn events
|
//load spawn events
|
||||||
SpawnEvent event;
|
query = StringFormat("SELECT id, cond_id, period, next_minute, next_hour, "
|
||||||
len = MakeAnyLenString(&query,
|
"next_day, next_month, next_year, enabled, action, argument, strict "
|
||||||
"SELECT id,cond_id,period,next_minute,next_hour,next_day,next_month,next_year,enabled,action,argument,strict "
|
"FROM spawn_events WHERE zone = '%s'", zone_name);
|
||||||
"FROM spawn_events WHERE zone='%s'", zone_name);
|
results = database.QueryDatabase(query);
|
||||||
if (database.RunQuery(query, len, errbuf, &result)) {
|
if (!results.Success()) {
|
||||||
safe_delete_array(query);
|
LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions events query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
while((row = mysql_fetch_row(result))) {
|
|
||||||
event.id = atoi(row[0]);
|
|
||||||
event.condition_id = atoi(row[1]);
|
|
||||||
event.period = atoi(row[2]);
|
|
||||||
if(event.period == 0) {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Refusing to load spawn event #%d because it has a period of 0\n", event.id);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
event.next.minute = atoi(row[3]);
|
|
||||||
event.next.hour = atoi(row[4]);
|
|
||||||
event.next.day = atoi(row[5]);
|
|
||||||
event.next.month = atoi(row[6]);
|
|
||||||
event.next.year = atoi(row[7]);
|
|
||||||
|
|
||||||
event.enabled = atoi(row[8])==0?false:true;
|
|
||||||
event.action = (SpawnEvent::Action) atoi(row[9]);
|
|
||||||
event.argument = atoi(row[10]);
|
|
||||||
event.strict = atoi(row[11])==0?false:true;
|
|
||||||
spawn_events.push_back(event);
|
|
||||||
|
|
||||||
_log(SPAWNS__CONDITIONS, "(LoadSpawnConditions) Loaded %s spawn event %d on condition %d with period %d, action %d, argument %d, strict %d",
|
|
||||||
event.enabled?"enabled":"disabled", event.id, event.condition_id, event.period, event.action, event.argument, event.strict);
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
} else {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadSpawnConditions events query '%s': %s", query, errbuf);
|
|
||||||
safe_delete_array(query);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
SpawnEvent event;
|
||||||
|
|
||||||
|
event.id = atoi(row[0]);
|
||||||
|
event.condition_id = atoi(row[1]);
|
||||||
|
event.period = atoi(row[2]);
|
||||||
|
|
||||||
|
if(event.period == 0) {
|
||||||
|
LogFile->write(EQEMuLog::Error, "Refusing to load spawn event #%d because it has a period of 0\n", event.id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.next.minute = atoi(row[3]);
|
||||||
|
event.next.hour = atoi(row[4]);
|
||||||
|
event.next.day = atoi(row[5]);
|
||||||
|
event.next.month = atoi(row[6]);
|
||||||
|
event.next.year = atoi(row[7]);
|
||||||
|
|
||||||
|
event.enabled = atoi(row[8])==0?false:true;
|
||||||
|
event.action = (SpawnEvent::Action) atoi(row[9]);
|
||||||
|
event.argument = atoi(row[10]);
|
||||||
|
event.strict = atoi(row[11])==0?false:true;
|
||||||
|
|
||||||
|
spawn_events.push_back(event);
|
||||||
|
|
||||||
|
_log(SPAWNS__CONDITIONS, "(LoadSpawnConditions) Loaded %s spawn event %d on condition %d with period %d, action %d, argument %d, strict %d", event.enabled? "enabled": "disabled", event.id, event.condition_id, event.period, event.action, event.argument, event.strict);
|
||||||
|
}
|
||||||
|
|
||||||
//now we need to catch up on events that happened while we were away
|
//now we need to catch up on events that happened while we were away
|
||||||
//and use them to alter just the condition variables.
|
//and use them to alter just the condition variables.
|
||||||
@ -855,11 +827,7 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in
|
|||||||
TimeOfDay_Struct tod;
|
TimeOfDay_Struct tod;
|
||||||
zone->zone_time.getEQTimeOfDay(&tod);
|
zone->zone_time.getEQTimeOfDay(&tod);
|
||||||
|
|
||||||
std::vector<SpawnEvent>::iterator cur,end;
|
for(auto cur = spawn_events.begin(); cur != spawn_events.end(); ++cur) {
|
||||||
cur = spawn_events.begin();
|
|
||||||
end = spawn_events.end();
|
|
||||||
bool ran;
|
|
||||||
for(; cur != end; ++cur) {
|
|
||||||
SpawnEvent &cevent = *cur;
|
SpawnEvent &cevent = *cur;
|
||||||
|
|
||||||
bool StrictCheck = false;
|
bool StrictCheck = false;
|
||||||
@ -874,43 +842,42 @@ bool SpawnConditionManager::LoadSpawnConditions(const char* zone_name, uint32 in
|
|||||||
if(!cevent.enabled || !StrictCheck)
|
if(!cevent.enabled || !StrictCheck)
|
||||||
SetCondition(zone->GetShortName(), zone->GetInstanceID(),cevent.condition_id,0);
|
SetCondition(zone->GetShortName(), zone->GetInstanceID(),cevent.condition_id,0);
|
||||||
|
|
||||||
if(cevent.enabled)
|
if(!cevent.enabled)
|
||||||
{
|
continue;
|
||||||
//watch for special case of all 0s, which means to reset next to now
|
|
||||||
if(cevent.next.year == 0 && cevent.next.month == 0 && cevent.next.day == 0 && cevent.next.hour == 0 && cevent.next.minute == 0) {
|
|
||||||
_log(SPAWNS__CONDITIONS, "Initial next trigger time set for spawn event %d", cevent.id);
|
|
||||||
memcpy(&cevent.next, &tod, sizeof(cevent.next));
|
|
||||||
//add one period
|
|
||||||
EQTime::AddMinutes(cevent.period, &cevent.next);
|
|
||||||
//save it in the db.
|
|
||||||
UpdateDBEvent(cevent);
|
|
||||||
continue; //were done with this event.
|
|
||||||
}
|
|
||||||
|
|
||||||
ran = false;
|
//watch for special case of all 0s, which means to reset next to now
|
||||||
while(EQTime::IsTimeBefore(&tod, &cevent.next)) {
|
if(cevent.next.year == 0 && cevent.next.month == 0 && cevent.next.day == 0 && cevent.next.hour == 0 && cevent.next.minute == 0) {
|
||||||
_log(SPAWNS__CONDITIONS, "Catch up triggering on event %d", cevent.id);
|
_log(SPAWNS__CONDITIONS, "Initial next trigger time set for spawn event %d", cevent.id);
|
||||||
//this event has been triggered.
|
memcpy(&cevent.next, &tod, sizeof(cevent.next));
|
||||||
//execute the event
|
//add one period
|
||||||
if(!cevent.strict || StrictCheck)
|
EQTime::AddMinutes(cevent.period, &cevent.next);
|
||||||
ExecEvent(cevent, false);
|
//save it in the db.
|
||||||
|
UpdateDBEvent(cevent);
|
||||||
|
continue; //were done with this event.
|
||||||
|
}
|
||||||
|
|
||||||
//add the period of the event to the trigger time
|
bool ran = false;
|
||||||
EQTime::AddMinutes(cevent.period, &cevent.next);
|
while(EQTime::IsTimeBefore(&tod, &cevent.next)) {
|
||||||
ran = true;
|
_log(SPAWNS__CONDITIONS, "Catch up triggering on event %d", cevent.id);
|
||||||
}
|
//this event has been triggered.
|
||||||
//only write it out if the event actually ran
|
//execute the event
|
||||||
if(ran) {
|
if(!cevent.strict || StrictCheck)
|
||||||
//save the event in the DB
|
ExecEvent(cevent, false);
|
||||||
UpdateDBEvent(cevent);
|
|
||||||
}
|
//add the period of the event to the trigger time
|
||||||
}
|
EQTime::AddMinutes(cevent.period, &cevent.next);
|
||||||
|
ran = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//only write it out if the event actually ran
|
||||||
|
if(ran)
|
||||||
|
UpdateDBEvent(cevent); //save the event in the DB
|
||||||
}
|
}
|
||||||
|
|
||||||
//now our event timers are all up to date, find our closest event.
|
//now our event timers are all up to date, find our closest event.
|
||||||
FindNearestEvent();
|
FindNearestEvent();
|
||||||
|
|
||||||
return(true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpawnConditionManager::FindNearestEvent() {
|
void SpawnConditionManager::FindNearestEvent() {
|
||||||
@ -1162,37 +1129,28 @@ int16 SpawnConditionManager::GetCondition(const char *zone_short, uint32 instanc
|
|||||||
}
|
}
|
||||||
|
|
||||||
SpawnCondition &cond = condi->second;
|
SpawnCondition &cond = condi->second;
|
||||||
return(cond.value);
|
return cond.value;
|
||||||
} else {
|
|
||||||
//this is a remote spawn condition, grab it from the DB
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char* query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
int16 value;
|
|
||||||
|
|
||||||
//load spawn conditions
|
|
||||||
SpawnCondition cond;
|
|
||||||
len = MakeAnyLenString(&query, "SELECT value FROM spawn_condition_values WHERE zone='%s' AND instance_id=%u AND id=%d",
|
|
||||||
zone_short, instance_id, condition_id);
|
|
||||||
if (database.RunQuery(query, len, errbuf, &result)) {
|
|
||||||
safe_delete_array(query);
|
|
||||||
if((row = mysql_fetch_row(result))) {
|
|
||||||
value = atoi(row[0]);
|
|
||||||
} else {
|
|
||||||
_log(SPAWNS__CONDITIONS, "Unable to load remote condition %d from zone %s in Get request.", condition_id, zone_short);
|
|
||||||
value = 0; //dunno a better thing to do...
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
} else {
|
|
||||||
_log(SPAWNS__CONDITIONS, "Unable to query remote condition %d from zone %s in Get request.", condition_id, zone_short);
|
|
||||||
safe_delete_array(query);
|
|
||||||
value = 0; //dunno a better thing to do...
|
|
||||||
}
|
|
||||||
return(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//this is a remote spawn condition, grab it from the DB
|
||||||
|
//load spawn conditions
|
||||||
|
std::string query = StringFormat("SELECT value FROM spawn_condition_values "
|
||||||
|
"WHERE zone = '%s' AND instance_id = %u AND id = %d",
|
||||||
|
zone_short, instance_id, condition_id);
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
_log(SPAWNS__CONDITIONS, "Unable to query remote condition %d from zone %s in Get request.", condition_id, zone_short);
|
||||||
|
return 0; //dunno a better thing to do...
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() == 0) {
|
||||||
|
_log(SPAWNS__CONDITIONS, "Unable to load remote condition %d from zone %s in Get request.", condition_id, zone_short);
|
||||||
|
return 0; //dunno a better thing to do...
|
||||||
|
}
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SpawnConditionManager::Check(uint16 condition, int16 min_value) {
|
bool SpawnConditionManager::Check(uint16 condition, int16 min_value) {
|
||||||
|
|||||||
@ -28,8 +28,7 @@
|
|||||||
|
|
||||||
extern EntityList entity_list;
|
extern EntityList entity_list;
|
||||||
|
|
||||||
SpawnEntry::SpawnEntry( uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_limit )
|
SpawnEntry::SpawnEntry( uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_limit ) {
|
||||||
{
|
|
||||||
NPCType = in_NPCType;
|
NPCType = in_NPCType;
|
||||||
chance = in_chance;
|
chance = in_chance;
|
||||||
npc_spawn_limit = in_npc_spawn_limit;
|
npc_spawn_limit = in_npc_spawn_limit;
|
||||||
@ -57,7 +56,6 @@ uint32 SpawnGroup::GetNPCType() {
|
|||||||
int npcType = 0;
|
int npcType = 0;
|
||||||
int totalchance = 0;
|
int totalchance = 0;
|
||||||
|
|
||||||
//check limits on this spawn group and npc type
|
|
||||||
if(!entity_list.LimitCheckGroup(id, group_spawn_limit))
|
if(!entity_list.LimitCheckGroup(id, group_spawn_limit))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
@ -68,7 +66,6 @@ uint32 SpawnGroup::GetNPCType() {
|
|||||||
for(; cur != end; ++cur) {
|
for(; cur != end; ++cur) {
|
||||||
SpawnEntry *se = *cur;
|
SpawnEntry *se = *cur;
|
||||||
|
|
||||||
//check limits on this spawn group and npc type
|
|
||||||
if(!entity_list.LimitCheckType(se->NPCType, se->npc_spawn_limit))
|
if(!entity_list.LimitCheckType(se->NPCType, se->npc_spawn_limit))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -93,7 +90,6 @@ uint32 SpawnGroup::GetNPCType() {
|
|||||||
roll -= se->chance;
|
roll -= se->chance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//CODER implement random table
|
|
||||||
return npcType;
|
return npcType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,106 +140,92 @@ bool SpawnGroupList::RemoveSpawnGroup(uint32 in_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::LoadSpawnGroups(const char* zone_name, uint16 version, SpawnGroupList* spawn_group_list) {
|
bool ZoneDatabase::LoadSpawnGroups(const char* zone_name, uint16 version, SpawnGroupList* spawn_group_list) {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char *query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
// CODER new spawn code
|
std::string query = StringFormat("SELECT DISTINCT(spawngroupID), spawngroup.name, spawngroup.spawn_limit, "
|
||||||
query = 0;
|
"spawngroup.dist, spawngroup.max_x, spawngroup.min_x, "
|
||||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT DISTINCT(spawngroupID), spawngroup.name, spawngroup.spawn_limit, spawngroup.dist, spawngroup.max_x, spawngroup.min_x, spawngroup.max_y, spawngroup.min_y, spawngroup.delay, spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay FROM spawn2,spawngroup WHERE spawn2.spawngroupID=spawngroup.ID and spawn2.version=%u and zone='%s'", version, zone_name), errbuf, &result))
|
"spawngroup.max_y, spawngroup.min_y, spawngroup.delay, "
|
||||||
{
|
"spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay "
|
||||||
safe_delete_array(query);
|
"FROM spawn2, spawngroup WHERE spawn2.spawngroupID = spawngroup.ID "
|
||||||
while((row = mysql_fetch_row(result))) {
|
"AND spawn2.version = %u and zone = '%s'", version, zone_name);
|
||||||
SpawnGroup* newSpawnGroup = new SpawnGroup( atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]), atoi(row[9]), atoi(row[10]), atoi(row[11]));
|
auto results = QueryDatabase(query);
|
||||||
spawn_group_list->AddSpawnGroup(newSpawnGroup);
|
if (!results.Success()) {
|
||||||
}
|
_log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query '%s' ", query.c_str());
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "Error2 in PopulateZoneLists query '" << query << "' " << errbuf << std::endl;
|
|
||||||
safe_delete_array(query);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
query = 0;
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
if (RunQuery(query, MakeAnyLenString(&query,
|
SpawnGroup* newSpawnGroup = new SpawnGroup(atoi(row[0]), row[1], atoi(row[2]), atof(row[3]),
|
||||||
"SELECT DISTINCT spawnentry.spawngroupID, npcid, chance, "
|
atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]),
|
||||||
"npc_types.spawn_limit AS sl "
|
atoi(row[8]), atoi(row[9]), atoi(row[10]), atoi(row[11]));
|
||||||
"FROM spawnentry, spawn2, npc_types "
|
spawn_group_list->AddSpawnGroup(newSpawnGroup);
|
||||||
"WHERE spawnentry.npcID=npc_types.id AND spawnentry.spawngroupID=spawn2.spawngroupID "
|
}
|
||||||
"AND zone='%s'", zone_name), errbuf, &result)) {
|
|
||||||
safe_delete_array(query);
|
query = StringFormat("SELECT DISTINCT spawnentry.spawngroupID, npcid, chance, "
|
||||||
while((row = mysql_fetch_row(result)))
|
"npc_types.spawn_limit AS sl "
|
||||||
{
|
"FROM spawnentry, spawn2, npc_types "
|
||||||
SpawnEntry* newSpawnEntry = new SpawnEntry( atoi(row[1]), atoi(row[2]), row[3]?atoi(row[3]):0);
|
"WHERE spawnentry.npcID=npc_types.id "
|
||||||
SpawnGroup *sg = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
"AND spawnentry.spawngroupID = spawn2.spawngroupID "
|
||||||
if (sg)
|
"AND zone = '%s'", zone_name);
|
||||||
sg->AddSpawnEntry(newSpawnEntry);
|
results = QueryDatabase(query);
|
||||||
else
|
if (!results.Success()) {
|
||||||
std::cout << "Error in SpawngroupID: " << row[0] << std::endl;
|
_log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query '%'", query.c_str());
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "Error3 in PopulateZoneLists query '" << query << "' " << errbuf << std::endl;
|
|
||||||
safe_delete_array(query);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
SpawnEntry* newSpawnEntry = new SpawnEntry( atoi(row[1]), atoi(row[2]), row[3]?atoi(row[3]):0);
|
||||||
|
SpawnGroup *sg = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
||||||
|
|
||||||
|
if (!sg) {
|
||||||
|
_log(ZONE__SPAWNS, "Error in LoadSpawnGroups %s ", query.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
sg->AddSpawnEntry(newSpawnEntry);
|
||||||
|
}
|
||||||
|
|
||||||
// CODER end new spawn code
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list) {
|
bool ZoneDatabase::LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list) {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char *query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
|
|
||||||
// CODER new spawn code
|
std::string query = StringFormat("SELECT DISTINCT(spawngroup.id), spawngroup.name, spawngroup.spawn_limit, "
|
||||||
query = 0;
|
"spawngroup.dist, spawngroup.max_x, spawngroup.min_x, "
|
||||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT DISTINCT spawngroup.id, spawngroup.name, spawngroup.spawn_limit, spawngroup.dist, spawngroup.max_x, spawngroup.min_x, spawngroup.max_y, spawngroup.min_y, spawngroup.delay, spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay FROM spawngroup WHERE spawngroup.ID='%i'", spawngroupid), errbuf, &result))
|
"spawngroup.max_y, spawngroup.min_y, spawngroup.delay, "
|
||||||
{
|
"spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay "
|
||||||
safe_delete_array(query);
|
"FROM spawngroup WHERE spawngroup.ID = '%i'", spawngroupid);
|
||||||
while((row = mysql_fetch_row(result))) {
|
auto results = QueryDatabase(query);
|
||||||
SpawnGroup* newSpawnGroup = new SpawnGroup( atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]), atoi(row[9]), atoi(row[10]), atoi(row[11]));
|
if (!results.Success()) {
|
||||||
spawn_group_list->AddSpawnGroup(newSpawnGroup);
|
_log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query %s", query.c_str());
|
||||||
}
|
return false;
|
||||||
mysql_free_result(result);
|
}
|
||||||
}
|
|
||||||
else
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
{
|
SpawnGroup* newSpawnGroup = new SpawnGroup(atoi(row[0]), row[1], atoi(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atof(row[6]), atof(row[7]), atoi(row[8]), atoi(row[9]), atoi(row[10]), atoi(row[11]));
|
||||||
std::cerr << "Error2 in PopulateZoneLists query '" << query << "' " << errbuf << std::endl;
|
spawn_group_list->AddSpawnGroup(newSpawnGroup);
|
||||||
safe_delete_array(query);
|
}
|
||||||
|
|
||||||
|
query = StringFormat("SELECT DISTINCT(spawnentry.spawngroupID), spawnentry.npcid, "
|
||||||
|
"spawnentry.chance, spawngroup.spawn_limit FROM spawnentry, spawngroup "
|
||||||
|
"WHERE spawnentry.spawngroupID = '%i' AND spawngroup.spawn_limit = '0' "
|
||||||
|
"ORDER BY chance", spawngroupid);
|
||||||
|
results = QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
_log(ZONE__SPAWNS, "Error3 in PopulateZoneLists query '%s'", query.c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
query = 0;
|
for(auto row = results.begin(); row != results.end(); ++row) {
|
||||||
if (RunQuery(query, MakeAnyLenString(&query,
|
SpawnEntry* newSpawnEntry = new SpawnEntry( atoi(row[1]), atoi(row[2]), row[3]?atoi(row[3]):0);
|
||||||
"SELECT DISTINCT spawnentry.spawngroupID, spawnentry.npcid, spawnentry.chance, spawngroup.spawn_limit FROM spawnentry,spawngroup WHERE spawnentry.spawngroupID='%i' AND spawngroup.spawn_limit='0' ORDER by chance", spawngroupid), errbuf, &result)) {
|
SpawnGroup *sg = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
||||||
safe_delete_array(query);
|
if (!sg) {
|
||||||
while((row = mysql_fetch_row(result)))
|
_log(ZONE__SPAWNS, "Error in SpawngroupID: %s ", row[0]);
|
||||||
{
|
continue;
|
||||||
SpawnEntry* newSpawnEntry = new SpawnEntry( atoi(row[1]), atoi(row[2]), row[3]?atoi(row[3]):0);
|
}
|
||||||
SpawnGroup *sg = spawn_group_list->GetSpawnGroup(atoi(row[0]));
|
|
||||||
if (sg)
|
sg->AddSpawnEntry(newSpawnEntry);
|
||||||
sg->AddSpawnEntry(newSpawnEntry);
|
}
|
||||||
else
|
|
||||||
std::cout << "Error in SpawngroupID: " << row[0] << std::endl;
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "Error3 in PopulateZoneLists query '" << query << "' " << errbuf << std::endl;
|
|
||||||
safe_delete_array(query);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CODER end new spawn code
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,8 +28,6 @@
|
|||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int Mob::GetKickDamage() {
|
int Mob::GetKickDamage() {
|
||||||
int multiple=(GetLevel()*100/5);
|
int multiple=(GetLevel()*100/5);
|
||||||
multiple += 100;
|
multiple += 100;
|
||||||
@ -64,11 +62,9 @@ int Mob::GetBashDamage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Mob::ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg) {
|
void Mob::ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg) {
|
||||||
|
|
||||||
int item_slot = -1;
|
int item_slot = -1;
|
||||||
//1: Apply bonus from AC (BOOT/SHIELD/HANDS) est. 40AC=6dmg
|
//1: Apply bonus from AC (BOOT/SHIELD/HANDS) est. 40AC=6dmg
|
||||||
if (IsClient()){
|
if (IsClient()){
|
||||||
|
|
||||||
switch (skill){
|
switch (skill){
|
||||||
|
|
||||||
case SkillFlyingKick:
|
case SkillFlyingKick:
|
||||||
@ -112,10 +108,8 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
|
|||||||
if(hate_override > -1)
|
if(hate_override > -1)
|
||||||
hate = hate_override;
|
hate = hate_override;
|
||||||
|
|
||||||
if(skill == SkillBash)
|
if(skill == SkillBash){
|
||||||
{
|
if(IsClient()){
|
||||||
if(IsClient())
|
|
||||||
{
|
|
||||||
ItemInst *item = CastToClient()->GetInv().GetItem(MainSecondary);
|
ItemInst *item = CastToClient()->GetInv().GetItem(MainSecondary);
|
||||||
if(item)
|
if(item)
|
||||||
{
|
{
|
||||||
@ -186,6 +180,10 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) {
|
|||||||
|
|
||||||
CombatAbility_Struct* ca_atk = (CombatAbility_Struct*) app->pBuffer;
|
CombatAbility_Struct* ca_atk = (CombatAbility_Struct*) app->pBuffer;
|
||||||
|
|
||||||
|
/* Check to see if actually have skill */
|
||||||
|
if (!MaxSkill(static_cast<SkillUseTypes>(ca_atk->m_skill)))
|
||||||
|
return;
|
||||||
|
|
||||||
if(GetTarget()->GetID() != ca_atk->m_target)
|
if(GetTarget()->GetID() != ca_atk->m_target)
|
||||||
return; //invalid packet.
|
return; //invalid packet.
|
||||||
|
|
||||||
@ -274,8 +272,7 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ca_atk->m_atk == 100) && (ca_atk->m_skill == SkillFrenzy))
|
if ((ca_atk->m_atk == 100) && (ca_atk->m_skill == SkillFrenzy)){
|
||||||
{
|
|
||||||
CheckIncreaseSkill(SkillFrenzy, GetTarget(), 10);
|
CheckIncreaseSkill(SkillFrenzy, GetTarget(), 10);
|
||||||
int AtkRounds = 3;
|
int AtkRounds = 3;
|
||||||
int skillmod = 100*GetSkill(SkillFrenzy)/MaxSkill(SkillFrenzy);
|
int skillmod = 100*GetSkill(SkillFrenzy)/MaxSkill(SkillFrenzy);
|
||||||
@ -311,8 +308,7 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(GetClass())
|
switch(GetClass()){
|
||||||
{
|
|
||||||
case BERSERKER:
|
case BERSERKER:
|
||||||
case WARRIOR:
|
case WARRIOR:
|
||||||
case RANGER:
|
case RANGER:
|
||||||
@ -384,8 +380,7 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReuseTime = (ReuseTime*HasteMod)/100;
|
ReuseTime = (ReuseTime*HasteMod)/100;
|
||||||
if(ReuseTime > 0)
|
if(ReuseTime > 0){
|
||||||
{
|
|
||||||
p_timers.Start(pTimerCombatAbility, ReuseTime);
|
p_timers.Start(pTimerCombatAbility, ReuseTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -403,8 +398,7 @@ int Mob::MonkSpecialAttack(Mob* other, uint8 unchecked_type)
|
|||||||
SkillUseTypes skill_type; //to avoid casting... even though it "would work"
|
SkillUseTypes skill_type; //to avoid casting... even though it "would work"
|
||||||
uint8 itemslot = MainFeet;
|
uint8 itemslot = MainFeet;
|
||||||
|
|
||||||
switch(unchecked_type)
|
switch(unchecked_type){
|
||||||
{
|
|
||||||
case SkillFlyingKick:{
|
case SkillFlyingKick:{
|
||||||
skill_type = SkillFlyingKick;
|
skill_type = SkillFlyingKick;
|
||||||
max_dmg = ((GetSTR()+GetSkill(skill_type)) * RuleI(Combat, FlyingKickBonus) / 100) + 35;
|
max_dmg = ((GetSTR()+GetSkill(skill_type)) * RuleI(Combat, FlyingKickBonus) / 100) + 35;
|
||||||
@ -484,8 +478,7 @@ int Mob::MonkSpecialAttack(Mob* other, uint8 unchecked_type)
|
|||||||
else
|
else
|
||||||
ht = ndamage = MakeRandomInt(min_dmg, max_dmg);
|
ht = ndamage = MakeRandomInt(min_dmg, max_dmg);
|
||||||
}
|
}
|
||||||
else
|
else{
|
||||||
{
|
|
||||||
ht = max_dmg;
|
ht = max_dmg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -535,7 +528,6 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) {
|
|||||||
|
|
||||||
RogueBackstab(other,false,ReuseTime);
|
RogueBackstab(other,false,ReuseTime);
|
||||||
if (level > 54) {
|
if (level > 54) {
|
||||||
|
|
||||||
if(IsClient() && CastToClient()->CheckDoubleAttack(false))
|
if(IsClient() && CastToClient()->CheckDoubleAttack(false))
|
||||||
{
|
{
|
||||||
if(other->GetHP() > 0)
|
if(other->GetHP() > 0)
|
||||||
@ -619,12 +611,10 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// determine minimum hits
|
// determine minimum hits
|
||||||
if (level < 51)
|
if (level < 51) {
|
||||||
{
|
|
||||||
min_hit = (level*15/10);
|
min_hit = (level*15/10);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
// Trumpcard: Replaced switch statement with formula calc. This will give minhit increases all the way to 65.
|
// Trumpcard: Replaced switch statement with formula calc. This will give minhit increases all the way to 65.
|
||||||
min_hit = (level * ( level*5 - 105)) / 100;
|
min_hit = (level * ( level*5 - 105)) / 100;
|
||||||
}
|
}
|
||||||
@ -636,8 +626,7 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime)
|
|||||||
if(min_damage){
|
if(min_damage){
|
||||||
ndamage = min_hit;
|
ndamage = min_hit;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if (max_hit < min_hit)
|
if (max_hit < min_hit)
|
||||||
max_hit = min_hit;
|
max_hit = min_hit;
|
||||||
|
|
||||||
@ -645,7 +634,6 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime)
|
|||||||
ndamage = max_hit;
|
ndamage = max_hit;
|
||||||
else
|
else
|
||||||
ndamage = MakeRandomInt(min_hit, max_hit);
|
ndamage = MakeRandomInt(min_hit, max_hit);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -793,14 +781,12 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SendItemAnimation(GetTarget(), AmmoItem, SkillArchery);
|
SendItemAnimation(GetTarget(), AmmoItem, SkillArchery);
|
||||||
|
|
||||||
DoArcheryAttackDmg(GetTarget(), RangeWeapon, Ammo);
|
DoArcheryAttackDmg(GetTarget(), RangeWeapon, Ammo);
|
||||||
|
|
||||||
//EndlessQuiver AA base1 = 100% Chance to avoid consumption arrow.
|
//EndlessQuiver AA base1 = 100% Chance to avoid consumption arrow.
|
||||||
int ChanceAvoidConsume = aabonuses.ConsumeProjectile + itembonuses.ConsumeProjectile + spellbonuses.ConsumeProjectile;
|
int ChanceAvoidConsume = aabonuses.ConsumeProjectile + itembonuses.ConsumeProjectile + spellbonuses.ConsumeProjectile;
|
||||||
|
|
||||||
if (!ChanceAvoidConsume || (ChanceAvoidConsume < 100 && MakeRandomInt(0,99) > ChanceAvoidConsume)){
|
if (!ChanceAvoidConsume || (ChanceAvoidConsume < 100 && MakeRandomInt(0,99) > ChanceAvoidConsume)){
|
||||||
|
|
||||||
DeleteItemInInventory(ammo_slot, 1, true);
|
DeleteItemInInventory(ammo_slot, 1, true);
|
||||||
mlog(COMBAT__RANGED, "Consumed one arrow from slot %d", ammo_slot);
|
mlog(COMBAT__RANGED, "Consumed one arrow from slot %d", ammo_slot);
|
||||||
} else {
|
} else {
|
||||||
@ -808,12 +794,10 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CheckIncreaseSkill(SkillArchery, GetTarget(), -15);
|
CheckIncreaseSkill(SkillArchery, GetTarget(), -15);
|
||||||
|
|
||||||
CommonBreakInvisible();
|
CommonBreakInvisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const ItemInst* Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime)
|
void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const ItemInst* Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime) {
|
||||||
{
|
|
||||||
if (!CanDoSpecialAttack(other))
|
if (!CanDoSpecialAttack(other))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -842,8 +826,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item
|
|||||||
if (focus) //From FcBaseEffects
|
if (focus) //From FcBaseEffects
|
||||||
WDmg += WDmg*focus/100;
|
WDmg += WDmg*focus/100;
|
||||||
|
|
||||||
if((WDmg > 0) || (ADmg > 0))
|
if((WDmg > 0) || (ADmg > 0)) {
|
||||||
{
|
|
||||||
if(WDmg < 0)
|
if(WDmg < 0)
|
||||||
WDmg = 0;
|
WDmg = 0;
|
||||||
if(ADmg < 0)
|
if(ADmg < 0)
|
||||||
@ -944,8 +927,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item
|
|||||||
}
|
}
|
||||||
|
|
||||||
//try proc on hits and misses
|
//try proc on hits and misses
|
||||||
if((RangeWeapon != nullptr) && GetTarget() && other && !other->HasDied())
|
if((RangeWeapon != nullptr) && GetTarget() && other && !other->HasDied()){
|
||||||
{
|
|
||||||
TryWeaponProc(RangeWeapon, other, MainRange);
|
TryWeaponProc(RangeWeapon, other, MainRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,14 +947,19 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item
|
|||||||
|
|
||||||
void NPC::RangedAttack(Mob* other)
|
void NPC::RangedAttack(Mob* other)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (!other)
|
||||||
|
return;
|
||||||
//make sure the attack and ranged timers are up
|
//make sure the attack and ranged timers are up
|
||||||
//if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow
|
//if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow
|
||||||
if((attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check()))
|
if((attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check())){
|
||||||
{
|
|
||||||
mlog(COMBAT__RANGED, "Archery canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
mlog(COMBAT__RANGED, "Archery canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!CheckLosFN(other))
|
||||||
|
return;
|
||||||
|
|
||||||
int attacks = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 0);
|
int attacks = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 0);
|
||||||
attacks = attacks > 0 ? attacks : 1;
|
attacks = attacks > 0 ? attacks : 1;
|
||||||
for(int i = 0; i < attacks; ++i) {
|
for(int i = 0; i < attacks; ++i) {
|
||||||
@ -1087,9 +1074,7 @@ void NPC::RangedAttack(Mob* other)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg)
|
uint16 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg) {
|
||||||
{
|
|
||||||
|
|
||||||
uint16 MaxDmg = (((2 * wDmg) * GetDamageTable(SkillThrowing)) / 100);
|
uint16 MaxDmg = (((2 * wDmg) * GetDamageTable(SkillThrowing)) / 100);
|
||||||
|
|
||||||
if (MaxDmg == 0)
|
if (MaxDmg == 0)
|
||||||
@ -1101,8 +1086,7 @@ uint16 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg)
|
|||||||
TotalDmg = MakeRandomInt(1, MaxDmg);
|
TotalDmg = MakeRandomInt(1, MaxDmg);
|
||||||
|
|
||||||
minDmg = 1;
|
minDmg = 1;
|
||||||
if(GetLevel() > 25)
|
if(GetLevel() > 25){
|
||||||
{
|
|
||||||
TotalDmg += ((GetLevel()-25)/3);
|
TotalDmg += ((GetLevel()-25)/3);
|
||||||
minDmg += ((GetLevel()-25)/3);
|
minDmg += ((GetLevel()-25)/3);
|
||||||
minDmg += minDmg * GetMeleeMinDamageMod_SE(SkillThrowing) / 100;
|
minDmg += minDmg * GetMeleeMinDamageMod_SE(SkillThrowing) / 100;
|
||||||
@ -1196,8 +1180,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
|
|||||||
//consume ammo
|
//consume ammo
|
||||||
DeleteItemInInventory(ammo_slot, 1, true);
|
DeleteItemInInventory(ammo_slot, 1, true);
|
||||||
CheckIncreaseSkill(SkillThrowing, GetTarget());
|
CheckIncreaseSkill(SkillThrowing, GetTarget());
|
||||||
|
CommonBreakInvisible();
|
||||||
CommonBreakInvisible();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item_Struct* item, uint16 weapon_damage, int16 chance_mod,int16 focus, int ReuseTime)
|
void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item_Struct* item, uint16 weapon_damage, int16 chance_mod,int16 focus, int ReuseTime)
|
||||||
@ -1227,8 +1210,7 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
|||||||
if (GetClass() == ROGUE && (BehindMob(other, GetX(), GetY())))
|
if (GetClass() == ROGUE && (BehindMob(other, GetX(), GetY())))
|
||||||
Assassinate_Dmg = TryAssassinate(other, SkillThrowing, ranged_timer.GetDuration());
|
Assassinate_Dmg = TryAssassinate(other, SkillThrowing, ranged_timer.GetDuration());
|
||||||
|
|
||||||
if(WDmg > 0)
|
if(WDmg > 0){
|
||||||
{
|
|
||||||
int minDmg = 1;
|
int minDmg = 1;
|
||||||
uint16 MaxDmg = GetThrownDamage(WDmg, TotalDmg, minDmg);
|
uint16 MaxDmg = GetThrownDamage(WDmg, TotalDmg, minDmg);
|
||||||
|
|
||||||
@ -1319,7 +1301,6 @@ void Mob::SendItemAnimation(Mob *to, const Item_Struct *item, SkillUseTypes skil
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Mob::ProjectileAnimation(Mob* to, int item_id, bool IsArrow, float speed, float angle, float tilt, float arc, const char *IDFile, SkillUseTypes skillInUse) {
|
void Mob::ProjectileAnimation(Mob* to, int item_id, bool IsArrow, float speed, float angle, float tilt, float arc, const char *IDFile, SkillUseTypes skillInUse) {
|
||||||
|
|
||||||
if (!to)
|
if (!to)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1453,17 +1434,11 @@ void NPC::DoClassAttacks(Mob *target) {
|
|||||||
break;
|
break;
|
||||||
case MONK: case MONKGM: {
|
case MONK: case MONKGM: {
|
||||||
uint8 satype = SkillKick;
|
uint8 satype = SkillKick;
|
||||||
if(level > 29) {
|
if(level > 29) { satype = SkillFlyingKick; }
|
||||||
satype = SkillFlyingKick;
|
else if(level > 24) { satype = SkillDragonPunch; }
|
||||||
} else if(level > 24) {
|
else if(level > 19) { satype = SkillEagleStrike; }
|
||||||
satype = SkillDragonPunch;
|
else if(level > 9) { satype = SkillTigerClaw; }
|
||||||
} else if(level > 19) {
|
else if(level > 4) { satype = SkillRoundKick; }
|
||||||
satype = SkillEagleStrike;
|
|
||||||
} else if(level > 9) {
|
|
||||||
satype = SkillTigerClaw;
|
|
||||||
} else if(level > 4) {
|
|
||||||
satype = SkillRoundKick;
|
|
||||||
}
|
|
||||||
reuse = MonkSpecialAttack(target, satype);
|
reuse = MonkSpecialAttack(target, satype);
|
||||||
|
|
||||||
reuse *= 1000;
|
reuse *= 1000;
|
||||||
@ -1472,8 +1447,7 @@ void NPC::DoClassAttacks(Mob *target) {
|
|||||||
}
|
}
|
||||||
case WARRIOR: case WARRIORGM:{
|
case WARRIOR: case WARRIORGM:{
|
||||||
if(level >= RuleI(Combat, NPCBashKickLevel)){
|
if(level >= RuleI(Combat, NPCBashKickLevel)){
|
||||||
if(MakeRandomInt(0, 100) > 25) //tested on live, warrior mobs both kick and bash, kick about 75% of the time, casting doesn't seem to make a difference.
|
if(MakeRandomInt(0, 100) > 25){ //tested on live, warrior mobs both kick and bash, kick about 75% of the time, casting doesn't seem to make a difference.
|
||||||
{
|
|
||||||
DoAnim(animKick);
|
DoAnim(animKick);
|
||||||
int32 dmg = 0;
|
int32 dmg = 0;
|
||||||
|
|
||||||
@ -1494,8 +1468,7 @@ void NPC::DoClassAttacks(Mob *target) {
|
|||||||
DoSpecialAttackDamage(target, SkillKick, dmg, 1, -1, reuse);
|
DoSpecialAttackDamage(target, SkillKick, dmg, 1, -1, reuse);
|
||||||
did_attack = true;
|
did_attack = true;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
DoAnim(animTailRake);
|
DoAnim(animTailRake);
|
||||||
int32 dmg = 0;
|
int32 dmg = 0;
|
||||||
|
|
||||||
@ -1518,8 +1491,7 @@ void NPC::DoClassAttacks(Mob *target) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BERSERKER: case BERSERKERGM:
|
case BERSERKER: case BERSERKERGM:{
|
||||||
{
|
|
||||||
int AtkRounds = 3;
|
int AtkRounds = 3;
|
||||||
int32 max_dmg = 26 + ((GetLevel()-6) * 2);
|
int32 max_dmg = 26 + ((GetLevel()-6) * 2);
|
||||||
int32 min_dmg = 0;
|
int32 min_dmg = 0;
|
||||||
@ -1536,7 +1508,6 @@ void NPC::DoClassAttacks(Mob *target) {
|
|||||||
reuse = FrenzyReuseTime * 1000;
|
reuse = FrenzyReuseTime * 1000;
|
||||||
|
|
||||||
while(AtkRounds > 0) {
|
while(AtkRounds > 0) {
|
||||||
|
|
||||||
if (GetTarget() && (AtkRounds == 1 || MakeRandomInt(0,100) < 75)){
|
if (GetTarget() && (AtkRounds == 1 || MakeRandomInt(0,100) < 75)){
|
||||||
DoSpecialAttackDamage(GetTarget(), SkillFrenzy, max_dmg, min_dmg, -1 , reuse, true);
|
DoSpecialAttackDamage(GetTarget(), SkillFrenzy, max_dmg, min_dmg, -1 , reuse, true);
|
||||||
}
|
}
|
||||||
@ -1574,8 +1545,7 @@ void NPC::DoClassAttacks(Mob *target) {
|
|||||||
}
|
}
|
||||||
case CLERIC: case CLERICGM: //clerics can bash too.
|
case CLERIC: case CLERICGM: //clerics can bash too.
|
||||||
case SHADOWKNIGHT: case SHADOWKNIGHTGM:
|
case SHADOWKNIGHT: case SHADOWKNIGHTGM:
|
||||||
case PALADIN: case PALADINGM:
|
case PALADIN: case PALADINGM:{
|
||||||
{
|
|
||||||
if(level >= RuleI(Combat, NPCBashKickLevel)){
|
if(level >= RuleI(Combat, NPCBashKickLevel)){
|
||||||
DoAnim(animTailRake);
|
DoAnim(animTailRake);
|
||||||
int32 dmg = 0;
|
int32 dmg = 0;
|
||||||
@ -1615,8 +1585,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
//check range for all these abilities, they are all close combat stuff
|
//check range for all these abilities, they are all close combat stuff
|
||||||
if(!CombatRange(ca_target))
|
if(!CombatRange(ca_target)){
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1639,9 +1608,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
uint16 skill_to_use = -1;
|
uint16 skill_to_use = -1;
|
||||||
|
|
||||||
if (skill == -1){
|
if (skill == -1){
|
||||||
|
switch(GetClass()){
|
||||||
switch(GetClass())
|
|
||||||
{
|
|
||||||
case WARRIOR:
|
case WARRIOR:
|
||||||
case RANGER:
|
case RANGER:
|
||||||
case BEASTLORD:
|
case BEASTLORD:
|
||||||
@ -1692,14 +1659,11 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
if(skill_to_use == -1)
|
if(skill_to_use == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(skill_to_use == SkillBash)
|
if(skill_to_use == SkillBash) {
|
||||||
{
|
if (ca_target!=this) {
|
||||||
if (ca_target!=this)
|
|
||||||
{
|
|
||||||
DoAnim(animTailRake);
|
DoAnim(animTailRake);
|
||||||
|
|
||||||
if(GetWeaponDamage(ca_target, GetInv().GetItem(MainSecondary)) <= 0 &&
|
if(GetWeaponDamage(ca_target, GetInv().GetItem(MainSecondary)) <= 0 && GetWeaponDamage(ca_target, GetInv().GetItem(MainShoulders)) <= 0){
|
||||||
GetWeaponDamage(ca_target, GetInv().GetItem(MainShoulders)) <= 0){
|
|
||||||
dmg = -5;
|
dmg = -5;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@ -1720,16 +1684,14 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
|
|
||||||
DoSpecialAttackDamage(ca_target, SkillBash, dmg, 1,-1,ReuseTime);
|
DoSpecialAttackDamage(ca_target, SkillBash, dmg, 1,-1,ReuseTime);
|
||||||
|
|
||||||
if(ReuseTime > 0 && !IsRiposte)
|
if(ReuseTime > 0 && !IsRiposte) {
|
||||||
{
|
|
||||||
p_timers.Start(pTimerCombatAbility, ReuseTime);
|
p_timers.Start(pTimerCombatAbility, ReuseTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(skill_to_use == SkillFrenzy)
|
if(skill_to_use == SkillFrenzy){
|
||||||
{
|
|
||||||
CheckIncreaseSkill(SkillFrenzy, GetTarget(), 10);
|
CheckIncreaseSkill(SkillFrenzy, GetTarget(), 10);
|
||||||
int AtkRounds = 3;
|
int AtkRounds = 3;
|
||||||
int skillmod = 100*GetSkill(SkillFrenzy)/MaxSkill(SkillFrenzy);
|
int skillmod = 100*GetSkill(SkillFrenzy)/MaxSkill(SkillFrenzy);
|
||||||
@ -1763,10 +1725,8 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(skill_to_use == SkillKick)
|
if(skill_to_use == SkillKick){
|
||||||
{
|
if(ca_target!=this){
|
||||||
if(ca_target!=this)
|
|
||||||
{
|
|
||||||
DoAnim(animKick);
|
DoAnim(animKick);
|
||||||
|
|
||||||
if(GetWeaponDamage(ca_target, GetInv().GetItem(MainFeet)) <= 0){
|
if(GetWeaponDamage(ca_target, GetInv().GetItem(MainFeet)) <= 0){
|
||||||
@ -1790,12 +1750,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(skill_to_use == SkillFlyingKick ||
|
if(skill_to_use == SkillFlyingKick || skill_to_use == SkillDragonPunch || skill_to_use == SkillEagleStrike || skill_to_use == SkillTigerClaw || skill_to_use == SkillRoundKick) {
|
||||||
skill_to_use == SkillDragonPunch ||
|
|
||||||
skill_to_use == SkillEagleStrike ||
|
|
||||||
skill_to_use == SkillTigerClaw ||
|
|
||||||
skill_to_use == SkillRoundKick)
|
|
||||||
{
|
|
||||||
ReuseTime = MonkSpecialAttack(ca_target, skill_to_use) - 1;
|
ReuseTime = MonkSpecialAttack(ca_target, skill_to_use) - 1;
|
||||||
MonkSpecialAttack(ca_target, skill_to_use);
|
MonkSpecialAttack(ca_target, skill_to_use);
|
||||||
|
|
||||||
@ -1810,7 +1765,6 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
MonkSpecialAttack(ca_target, MonkSPA[MakeRandomInt(0,4)]);
|
MonkSpecialAttack(ca_target, MonkSPA[MakeRandomInt(0,4)]);
|
||||||
|
|
||||||
int TripleChance = 25;
|
int TripleChance = 25;
|
||||||
|
|
||||||
if (bDoubleSpecialAttack > 100)
|
if (bDoubleSpecialAttack > 100)
|
||||||
TripleChance += TripleChance*(100-bDoubleSpecialAttack)/100;
|
TripleChance += TripleChance*(100-bDoubleSpecialAttack)/100;
|
||||||
|
|
||||||
@ -1820,8 +1774,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(skill_to_use == SkillBackstab)
|
if(skill_to_use == SkillBackstab){
|
||||||
{
|
|
||||||
ReuseTime = BackstabReuseTime-1;
|
ReuseTime = BackstabReuseTime-1;
|
||||||
|
|
||||||
if (IsRiposte)
|
if (IsRiposte)
|
||||||
@ -1831,8 +1784,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReuseTime = (ReuseTime*HasteMod)/100;
|
ReuseTime = (ReuseTime*HasteMod)/100;
|
||||||
if(ReuseTime > 0 && !IsRiposte)
|
if(ReuseTime > 0 && !IsRiposte){
|
||||||
{
|
|
||||||
p_timers.Start(pTimerCombatAbility, ReuseTime);
|
p_timers.Start(pTimerCombatAbility, ReuseTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1900,7 +1852,6 @@ void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus) {
|
|||||||
tauntchance /= 100.0f;
|
tauntchance /= 100.0f;
|
||||||
|
|
||||||
if (tauntchance > MakeRandomFloat(0, 1)) {
|
if (tauntchance > MakeRandomFloat(0, 1)) {
|
||||||
|
|
||||||
if (hate_top && hate_top != this){
|
if (hate_top && hate_top != this){
|
||||||
newhate = (who->GetNPCHate(hate_top) - who->GetNPCHate(this)) + 1;
|
newhate = (who->GetNPCHate(hate_top) - who->GetNPCHate(this)) + 1;
|
||||||
who->CastToNPC()->AddToHateList(this, newhate);
|
who->CastToNPC()->AddToHateList(this, newhate);
|
||||||
@ -1923,7 +1874,6 @@ void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus) {
|
|||||||
if (HasSkillProcs())
|
if (HasSkillProcs())
|
||||||
TrySkillProc(who, SkillTaunt, TauntReuseTime*1000);
|
TrySkillProc(who, SkillTaunt, TauntReuseTime*1000);
|
||||||
|
|
||||||
|
|
||||||
if (Success && HasSkillProcSuccess())
|
if (Success && HasSkillProcSuccess())
|
||||||
TrySkillProc(who, SkillTaunt, TauntReuseTime*1000, true);
|
TrySkillProc(who, SkillTaunt, TauntReuseTime*1000, true);
|
||||||
}
|
}
|
||||||
@ -1944,8 +1894,7 @@ void Mob::InstillDoubt(Mob *who) {
|
|||||||
if(!CombatRange(who))
|
if(!CombatRange(who))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(IsClient())
|
if(IsClient()) {
|
||||||
{
|
|
||||||
CastToClient()->CheckIncreaseSkill(SkillIntimidation, who, 10);
|
CastToClient()->CheckIncreaseSkill(SkillIntimidation, who, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1976,13 +1925,11 @@ void Mob::InstillDoubt(Mob *who) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 Mob::TryHeadShot(Mob* defender, SkillUseTypes skillInUse) {
|
uint32 Mob::TryHeadShot(Mob* defender, SkillUseTypes skillInUse) {
|
||||||
|
|
||||||
//Only works on YOUR target.
|
//Only works on YOUR target.
|
||||||
if(defender && (defender->GetBodyType() == BT_Humanoid) && !defender->IsClient()
|
if(defender && (defender->GetBodyType() == BT_Humanoid) && !defender->IsClient()
|
||||||
&& (skillInUse == SkillArchery) && (GetTarget() == defender)) {
|
&& (skillInUse == SkillArchery) && (GetTarget() == defender)) {
|
||||||
|
|
||||||
uint32 HeadShot_Dmg = aabonuses.HeadShot[1] + spellbonuses.HeadShot[1] + itembonuses.HeadShot[1];
|
uint32 HeadShot_Dmg = aabonuses.HeadShot[1] + spellbonuses.HeadShot[1] + itembonuses.HeadShot[1];
|
||||||
|
|
||||||
uint8 HeadShot_Level = 0; //Get Highest Headshot Level
|
uint8 HeadShot_Level = 0; //Get Highest Headshot Level
|
||||||
HeadShot_Level = aabonuses.HSLevel;
|
HeadShot_Level = aabonuses.HSLevel;
|
||||||
if (HeadShot_Level < spellbonuses.HSLevel)
|
if (HeadShot_Level < spellbonuses.HSLevel)
|
||||||
@ -1991,7 +1938,6 @@ uint32 Mob::TryHeadShot(Mob* defender, SkillUseTypes skillInUse) {
|
|||||||
HeadShot_Level = itembonuses.HSLevel;
|
HeadShot_Level = itembonuses.HSLevel;
|
||||||
|
|
||||||
if(HeadShot_Dmg && HeadShot_Level && (defender->GetLevel() <= HeadShot_Level)){
|
if(HeadShot_Dmg && HeadShot_Level && (defender->GetLevel() <= HeadShot_Level)){
|
||||||
|
|
||||||
float ProcChance = GetSpecialProcChances(MainRange);
|
float ProcChance = GetSpecialProcChances(MainRange);
|
||||||
if(ProcChance > MakeRandomFloat(0,1))
|
if(ProcChance > MakeRandomFloat(0,1))
|
||||||
return HeadShot_Dmg;
|
return HeadShot_Dmg;
|
||||||
@ -2084,7 +2030,7 @@ float Mob::GetAssassinateProcChances(uint16 ReuseTime)
|
|||||||
ProcChance += ProcChance * ProcBonus / 100.0f;
|
ProcChance += ProcChance * ProcBonus / 100.0f;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/*Kayen: Unable to find data on old proc rate of assassinate, no idea if our formula is real or made up.*/
|
/* Kayen: Unable to find data on old proc rate of assassinate, no idea if our formula is real or made up. */
|
||||||
ProcChance = (10 + (static_cast<float>(mydex/10) + static_cast<float>(itembonuses.HeroicDEX /10)))/100.0f;
|
ProcChance = (10 + (static_cast<float>(mydex/10) + static_cast<float>(itembonuses.HeroicDEX /10)))/100.0f;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -2097,8 +2043,10 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
|||||||
if (!CanDoSpecialAttack(other))
|
if (!CanDoSpecialAttack(other))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//For spells using skill value 98 (feral swipe ect) server sets this to 67 automatically.
|
/*
|
||||||
//Kayen: This is unlikely to be completely accurate but use OFFENSE skill value for these effects.
|
For spells using skill value 98 (feral swipe ect) server sets this to 67 automatically.
|
||||||
|
Kayen: This is unlikely to be completely accurate but use OFFENSE skill value for these effects.
|
||||||
|
*/
|
||||||
if (skillinuse == SkillBegging)
|
if (skillinuse == SkillBegging)
|
||||||
skillinuse = SkillOffense;
|
skillinuse = SkillOffense;
|
||||||
|
|
||||||
@ -2108,7 +2056,6 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
|||||||
if (hate == 0 && weapon_damage > 1) hate = weapon_damage;
|
if (hate == 0 && weapon_damage > 1) hate = weapon_damage;
|
||||||
|
|
||||||
if(weapon_damage > 0){
|
if(weapon_damage > 0){
|
||||||
|
|
||||||
if (focus) //From FcBaseEffects
|
if (focus) //From FcBaseEffects
|
||||||
weapon_damage += weapon_damage*focus/100;
|
weapon_damage += weapon_damage*focus/100;
|
||||||
|
|
||||||
@ -2118,12 +2065,10 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32 min_hit = 1;
|
int32 min_hit = 1;
|
||||||
int32 max_hit = (2*weapon_damage*GetDamageTable(skillinuse)) / 100;
|
int32 max_hit = (2 * weapon_damage*GetDamageTable(skillinuse)) / 100;
|
||||||
|
|
||||||
if(GetLevel() >= 28 && IsWarriorClass() )
|
if(GetLevel() >= 28 && IsWarriorClass() ) {
|
||||||
{
|
|
||||||
int ucDamageBonus = GetWeaponDamageBonus((const Item_Struct*) nullptr );
|
int ucDamageBonus = GetWeaponDamageBonus((const Item_Struct*) nullptr );
|
||||||
|
|
||||||
min_hit += (int) ucDamageBonus;
|
min_hit += (int) ucDamageBonus;
|
||||||
max_hit += (int) ucDamageBonus;
|
max_hit += (int) ucDamageBonus;
|
||||||
hate += ucDamageBonus;
|
hate += ucDamageBonus;
|
||||||
@ -2143,7 +2088,6 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
|||||||
}
|
}
|
||||||
|
|
||||||
ApplySpecialAttackMod(skillinuse, max_hit, min_hit);
|
ApplySpecialAttackMod(skillinuse, max_hit, min_hit);
|
||||||
|
|
||||||
min_hit += min_hit * GetMeleeMinDamageMod_SE(skillinuse) / 100;
|
min_hit += min_hit * GetMeleeMinDamageMod_SE(skillinuse) / 100;
|
||||||
|
|
||||||
if(max_hit < min_hit)
|
if(max_hit < min_hit)
|
||||||
@ -2204,8 +2148,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
|||||||
TrySkillProc(other, skillinuse, ReuseTime, true);
|
TrySkillProc(other, skillinuse, ReuseTime, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::CanDoSpecialAttack(Mob *other)
|
bool Mob::CanDoSpecialAttack(Mob *other) {
|
||||||
{
|
|
||||||
//Make sure everything is valid before doing any attacks.
|
//Make sure everything is valid before doing any attacks.
|
||||||
if (!other) {
|
if (!other) {
|
||||||
SetTarget(nullptr);
|
SetTarget(nullptr);
|
||||||
@ -2215,8 +2158,7 @@ bool Mob::CanDoSpecialAttack(Mob *other)
|
|||||||
if(!GetTarget())
|
if(!GetTarget())
|
||||||
SetTarget(other);
|
SetTarget(other);
|
||||||
|
|
||||||
if ((other == nullptr || ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead))
|
if ((other == nullptr || ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) || HasDied() || (!IsAttackAllowed(other)))) {
|
||||||
|| HasDied() || (!IsAttackAllowed(other)))) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -139,7 +139,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
|
|
||||||
if(IsNPC())
|
if(IsNPC())
|
||||||
{
|
{
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(&buffslot);
|
args.push_back(&buffslot);
|
||||||
int i = parse->EventSpell(EVENT_SPELL_EFFECT_NPC, CastToNPC(), nullptr, spell_id, caster ? caster->GetID() : 0, &args);
|
int i = parse->EventSpell(EVENT_SPELL_EFFECT_NPC, CastToNPC(), nullptr, spell_id, caster ? caster->GetID() : 0, &args);
|
||||||
if(i != 0){
|
if(i != 0){
|
||||||
@ -149,7 +149,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial)
|
|||||||
}
|
}
|
||||||
else if(IsClient())
|
else if(IsClient())
|
||||||
{
|
{
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(&buffslot);
|
args.push_back(&buffslot);
|
||||||
int i = parse->EventSpell(EVENT_SPELL_EFFECT_CLIENT, nullptr, CastToClient(), spell_id, caster ? caster->GetID() : 0, &args);
|
int i = parse->EventSpell(EVENT_SPELL_EFFECT_CLIENT, nullptr, CastToClient(), spell_id, caster ? caster->GetID() : 0, &args);
|
||||||
if(i != 0){
|
if(i != 0){
|
||||||
@ -3293,7 +3293,7 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
|
|||||||
|
|
||||||
if(IsNPC())
|
if(IsNPC())
|
||||||
{
|
{
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(&ticsremaining);
|
args.push_back(&ticsremaining);
|
||||||
args.push_back(&caster_level);
|
args.push_back(&caster_level);
|
||||||
args.push_back(&slot);
|
args.push_back(&slot);
|
||||||
@ -3304,7 +3304,7 @@ void Mob::DoBuffTic(uint16 spell_id, int slot, uint32 ticsremaining, uint8 caste
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(&ticsremaining);
|
args.push_back(&ticsremaining);
|
||||||
args.push_back(&caster_level);
|
args.push_back(&caster_level);
|
||||||
args.push_back(&slot);
|
args.push_back(&slot);
|
||||||
@ -3654,12 +3654,12 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(IsClient()) {
|
if(IsClient()) {
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(&buffs[slot].casterid);
|
args.push_back(&buffs[slot].casterid);
|
||||||
|
|
||||||
parse->EventSpell(EVENT_SPELL_FADE, nullptr, CastToClient(), buffs[slot].spellid, slot, &args);
|
parse->EventSpell(EVENT_SPELL_FADE, nullptr, CastToClient(), buffs[slot].spellid, slot, &args);
|
||||||
} else if(IsNPC()) {
|
} else if(IsNPC()) {
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(&buffs[slot].casterid);
|
args.push_back(&buffs[slot].casterid);
|
||||||
|
|
||||||
parse->EventSpell(EVENT_SPELL_FADE, CastToNPC(), nullptr, buffs[slot].spellid, slot, &args);
|
parse->EventSpell(EVENT_SPELL_FADE, CastToNPC(), nullptr, buffs[slot].spellid, slot, &args);
|
||||||
|
|||||||
106
zone/spells.cpp
106
zone/spells.cpp
@ -4965,68 +4965,56 @@ int Client::FindSpellBookSlotBySpellID(uint16 spellid) {
|
|||||||
return -1; //default
|
return -1; //default
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::SpellGlobalCheck(uint16 Spell_ID, uint16 Char_ID) {
|
bool Client::SpellGlobalCheck(uint16 spell_ID, uint16 char_ID) {
|
||||||
|
|
||||||
std::string Spell_Global_Name;
|
std::string spell_Global_Name;
|
||||||
int Spell_Global_Value;
|
int spell_Global_Value;
|
||||||
int Global_Value;
|
int global_Value;
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
std::string query = StringFormat("SELECT qglobal, value FROM spell_globals "
|
||||||
char *query = 0;
|
"WHERE spellid = %i", spell_ID);
|
||||||
MYSQL_RES *result;
|
auto results = database.QueryDatabase(query);
|
||||||
MYSQL_ROW row;
|
if (!results.Success()) {
|
||||||
|
LogFile->write(EQEMuLog::Error, "Error while querying Spell ID %i spell_globals table query '%s': %s", spell_ID, query.c_str(), results.ErrorMessage().c_str());
|
||||||
if (database.RunQuery(query,MakeAnyLenString(&query, "SELECT qglobal, value FROM spell_globals WHERE spellid=%i", Spell_ID), errbuf, &result)) {
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
if (mysql_num_rows(result) == 1) {
|
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
Spell_Global_Name = row[0];
|
|
||||||
Spell_Global_Value = atoi(row[1]);
|
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
if (Spell_Global_Name.empty()) { // If the entry in the spell_globals table has nothing set for the qglobal name
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (database.RunQuery(query,MakeAnyLenString(&query, "SELECT value FROM quest_globals WHERE charid=%i AND name='%s'", Char_ID, Spell_Global_Name.c_str()), errbuf, &result)) {
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
if (mysql_num_rows(result) == 1) {
|
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
|
|
||||||
Global_Value = atoi(row[0]);
|
|
||||||
mysql_free_result(result);
|
|
||||||
if (Global_Value == Spell_Global_Value) { // If the values match from both tables, allow the spell to be scribed
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (Global_Value > Spell_Global_Value) { // Check if the qglobal value is greater than the require spellglobal value
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else // If no matching result found in qglobals, don't scribe this spell
|
|
||||||
{
|
|
||||||
LogFile->write(EQEMuLog::Error, "Char ID: %i Spell_globals Name: '%s' Value: '%i' did not match QGlobal Value: '%i' for Spell ID %i", Char_ID, Spell_Global_Name.c_str(), Spell_Global_Value, Global_Value, Spell_ID);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LogFile->write(EQEMuLog::Error, "Char ID: %i does not have the Qglobal Name: '%s' for Spell ID %i", Char_ID, Spell_Global_Name.c_str(), Spell_ID);
|
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LogFile->write(EQEMuLog::Error, "Spell ID %i query of spell_globals with Name: '%s' Value: '%i' failed", Spell_ID, Spell_Global_Name.c_str(), Spell_Global_Value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return true; // Spell ID isn't listed in the spells_global table, so it is not restricted from scribing
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error while querying Spell ID %i spell_globals table query '%s': %s", Spell_ID, query, errbuf);
|
|
||||||
safe_delete_array(query);
|
|
||||||
return false; // Query failed, so prevent spell from scribing just in case
|
return false; // Query failed, so prevent spell from scribing just in case
|
||||||
}
|
}
|
||||||
return false; // Default is false
|
|
||||||
|
if (results.RowCount() != 1)
|
||||||
|
return true; // Spell ID isn't listed in the spells_global table, so it is not restricted from scribing
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
spell_Global_Name = row[0];
|
||||||
|
spell_Global_Value = atoi(row[1]);
|
||||||
|
|
||||||
|
if (spell_Global_Name.empty())
|
||||||
|
return true; // If the entry in the spell_globals table has nothing set for the qglobal name
|
||||||
|
|
||||||
|
query = StringFormat("SELECT value FROM quest_globals "
|
||||||
|
"WHERE charid = %i AND name = '%s'",
|
||||||
|
char_ID, spell_Global_Name.c_str());
|
||||||
|
results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
LogFile->write(EQEMuLog::Error, "Spell ID %i query of spell_globals with Name: '%s' Value: '%i' failed", spell_ID, spell_Global_Name.c_str(), spell_Global_Value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() != 1) {
|
||||||
|
LogFile->write(EQEMuLog::Error, "Char ID: %i does not have the Qglobal Name: '%s' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_ID);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
row = results.begin();
|
||||||
|
|
||||||
|
global_Value = atoi(row[0]);
|
||||||
|
|
||||||
|
if (global_Value == spell_Global_Value)
|
||||||
|
return true; // If the values match from both tables, allow the spell to be scribed
|
||||||
|
else if (global_Value > spell_Global_Value)
|
||||||
|
return true; // Check if the qglobal value is greater than the require spellglobal value
|
||||||
|
|
||||||
|
// If no matching result found in qglobals, don't scribe this spell
|
||||||
|
LogFile->write(EQEMuLog::Error, "Char ID: %i Spell_globals Name: '%s' Value: '%i' did not match QGlobal Value: '%i' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_Global_Value, global_Value, spell_ID);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO get rid of this
|
// TODO get rid of this
|
||||||
|
|||||||
@ -34,18 +34,16 @@ Copyright (C) 2001-2008 EQEMu Development Team (http://eqemulator.net)
|
|||||||
#include "../common/features.h"
|
#include "../common/features.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
#include "mob.h"
|
#include "mob.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
TaskManager::TaskManager() {
|
TaskManager::TaskManager() {
|
||||||
|
|
||||||
for(int i=0; i<MAXTASKS; i++)
|
for(int i=0; i<MAXTASKS; i++)
|
||||||
Tasks[i] = nullptr;
|
Tasks[i] = nullptr;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskManager::~TaskManager() {
|
TaskManager::~TaskManager() {
|
||||||
|
|
||||||
for(int i=0; i<MAXTASKS; i++) {
|
for(int i=0; i<MAXTASKS; i++) {
|
||||||
if(Tasks[i] != nullptr) {
|
if(Tasks[i] != nullptr) {
|
||||||
for(int j=0; j<Tasks[i]->ActivityCount; j++) {
|
for(int j=0; j<Tasks[i]->ActivityCount; j++) {
|
||||||
@ -62,11 +60,8 @@ TaskManager::~TaskManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TaskManager::LoadTaskSets() {
|
bool TaskManager::LoadTaskSets() {
|
||||||
|
|
||||||
|
|
||||||
const char *TaskSetQuery = "SELECT `id`, `taskid` from `tasksets` WHERE `id` > 0 AND `id` < %i "
|
const char *TaskSetQuery = "SELECT `id`, `taskid` from `tasksets` WHERE `id` > 0 AND `id` < %i "
|
||||||
"AND `taskid` >= 0 AND `taskid` < %i ORDER BY `id`, `taskid` ASC";
|
"AND `taskid` >= 0 AND `taskid` < %i ORDER BY `id`, `taskid` ASC";
|
||||||
|
|
||||||
const char *ERR_MYSQLERROR = "[TASKS]Error in TaskManager::LoadTaskSets: %s";
|
const char *ERR_MYSQLERROR = "[TASKS]Error in TaskManager::LoadTaskSets: %s";
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
@ -1985,12 +1980,17 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int T
|
|||||||
// Inform the client the task has been updated, both by a chat message
|
// Inform the client the task has been updated, both by a chat message
|
||||||
c->Message(0, "Your task '%s' has been updated.", Task->Title);
|
c->Message(0, "Your task '%s' has been updated.", Task->Title);
|
||||||
|
|
||||||
if(Task->Activity[ActivityID].GoalMethod != METHODQUEST)
|
if(Task->Activity[ActivityID].GoalMethod != METHODQUEST) {
|
||||||
{
|
|
||||||
char buf[24];
|
char buf[24];
|
||||||
snprintf(buf, 23, "%d %d", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID);
|
snprintf(buf, 23, "%d %d", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID);
|
||||||
buf[23] = '\0';
|
buf[23] = '\0';
|
||||||
parse->EventPlayer(EVENT_TASK_STAGE_COMPLETE, c, buf, 0);
|
parse->EventPlayer(EVENT_TASK_STAGE_COMPLETE, c, buf, 0);
|
||||||
|
|
||||||
|
/* QS: PlayerLogTaskUpdates :: Update */
|
||||||
|
if (RuleB(QueryServ, PlayerLogTaskUpdates)){
|
||||||
|
std::string event_desc = StringFormat("Task Stage Complete :: taskid:%i activityid:%i donecount:%i in zoneid:%i instid:%i", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, c->GetZoneID(), c->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Task_Updates, c->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this task is now complete, the Completed tasks will have been
|
// If this task is now complete, the Completed tasks will have been
|
||||||
@ -2002,6 +2002,12 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int T
|
|||||||
buf[23] = '\0';
|
buf[23] = '\0';
|
||||||
parse->EventPlayer(EVENT_TASK_COMPLETE, c, buf, 0);
|
parse->EventPlayer(EVENT_TASK_COMPLETE, c, buf, 0);
|
||||||
|
|
||||||
|
/* QS: PlayerLogTaskUpdates :: Complete */
|
||||||
|
if (RuleB(QueryServ, PlayerLogTaskUpdates)){
|
||||||
|
std::string event_desc = StringFormat("Task Complete :: taskid:%i activityid:%i donecount:%i in zoneid:%i instid:%i", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, c->GetZoneID(), c->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Task_Updates, c->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
|
||||||
taskmanager->SendCompletedTasksToClient(c, this);
|
taskmanager->SendCompletedTasksToClient(c, this);
|
||||||
c->SendTaskActivityComplete(ActiveTasks[TaskIndex].TaskID, 0, TaskIndex, false);
|
c->SendTaskActivityComplete(ActiveTasks[TaskIndex].TaskID, 0, TaskIndex, false);
|
||||||
taskmanager->SaveClientState(c, this);
|
taskmanager->SaveClientState(c, this);
|
||||||
@ -2011,6 +2017,7 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int T
|
|||||||
// If Experience and/or cash rewards are set, reward them from the task even if RewardMethod is METHODQUEST
|
// If Experience and/or cash rewards are set, reward them from the task even if RewardMethod is METHODQUEST
|
||||||
RewardTask(c, Task);
|
RewardTask(c, Task);
|
||||||
//RemoveTask(c, TaskIndex);
|
//RemoveTask(c, TaskIndex);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,9 @@
|
|||||||
#include "../common/string_util.h"
|
#include "../common/string_util.h"
|
||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
static const SkillUseTypes TradeskillUnknown = Skill1HBlunt; /* an arbitrary non-tradeskill */
|
static const SkillUseTypes TradeskillUnknown = Skill1HBlunt; /* an arbitrary non-tradeskill */
|
||||||
|
|
||||||
@ -146,7 +149,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme
|
|||||||
|
|
||||||
ItemInst *aug = tobe_auged->GetAugment(slot);
|
ItemInst *aug = tobe_auged->GetAugment(slot);
|
||||||
if(aug) {
|
if(aug) {
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(aug);
|
args.push_back(aug);
|
||||||
parse->EventItem(EVENT_AUGMENT_ITEM, user, tobe_auged, nullptr, "", slot, &args);
|
parse->EventItem(EVENT_AUGMENT_ITEM, user, tobe_auged, nullptr, "", slot, &args);
|
||||||
|
|
||||||
@ -168,7 +171,7 @@ void Object::HandleAugmentation(Client* user, const AugmentItem_Struct* in_augme
|
|||||||
const uint32 id = auged_with->GetID();
|
const uint32 id = auged_with->GetID();
|
||||||
ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_slot);
|
ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_slot);
|
||||||
if(aug) {
|
if(aug) {
|
||||||
std::vector<void*> args;
|
std::vector<EQEmu::Any> args;
|
||||||
args.push_back(aug);
|
args.push_back(aug);
|
||||||
parse->EventItem(EVENT_UNAUGMENT_ITEM, user, tobe_auged, nullptr, "", slot, &args);
|
parse->EventItem(EVENT_UNAUGMENT_ITEM, user, tobe_auged, nullptr, "", slot, &args);
|
||||||
|
|
||||||
@ -1067,7 +1070,7 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) {
|
|||||||
if(over_trivial < 0)
|
if(over_trivial < 0)
|
||||||
CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, spec->tradeskill);
|
CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, spec->tradeskill);
|
||||||
|
|
||||||
Message_StringID(4,TRADESKILL_SUCCEED,spec->name.c_str());
|
Message_StringID(4, TRADESKILL_SUCCEED, spec->name.c_str());
|
||||||
|
|
||||||
_log(TRADESKILLS__TRACE, "Tradeskill success");
|
_log(TRADESKILLS__TRACE, "Tradeskill success");
|
||||||
|
|
||||||
@ -1076,16 +1079,24 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) {
|
|||||||
//should we check this crap?
|
//should we check this crap?
|
||||||
SummonItem(itr->first, itr->second);
|
SummonItem(itr->first, itr->second);
|
||||||
item = database.GetItem(itr->first);
|
item = database.GetItem(itr->first);
|
||||||
if (this->GetGroup())
|
if (this->GetGroup()) {
|
||||||
{
|
entity_list.MessageGroup(this, true, MT_Skills, "%s has successfully fashioned %s!", GetName(), item->Name);
|
||||||
entity_list.MessageGroup(this,true,MT_Skills,"%s has successfully fashioned %s!",GetName(),item->Name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* QS: Player_Log_Trade_Skill_Events */
|
||||||
|
if (RuleB(QueryServ, PlayerLogTradeSkillEvents)){
|
||||||
|
std::string event_desc = StringFormat("Success :: fashioned recipe_id:%i tskillid:%i trivial:%i chance:%4.2f in zoneid:%i instid:%i", spec->recipe_id, spec->tradeskill, spec->trivial, chance, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Trade_Skill_Events, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
|
||||||
if(RuleB(TaskSystem, EnableTaskSystem))
|
if(RuleB(TaskSystem, EnableTaskSystem))
|
||||||
UpdateTasksForItem(ActivityTradeSkill, itr->first, itr->second);
|
UpdateTasksForItem(ActivityTradeSkill, itr->first, itr->second);
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
return(true);
|
return(true);
|
||||||
} else {
|
}
|
||||||
|
/* Tradeskill Fail */
|
||||||
|
else {
|
||||||
success_modifier = 2; // Halves the chance
|
success_modifier = 2; // Halves the chance
|
||||||
|
|
||||||
if(over_trivial < 0)
|
if(over_trivial < 0)
|
||||||
@ -1097,6 +1108,13 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) {
|
|||||||
if (this->GetGroup())
|
if (this->GetGroup())
|
||||||
{
|
{
|
||||||
entity_list.MessageGroup(this,true,MT_Skills,"%s was unsuccessful in %s tradeskill attempt.",GetName(),this->GetGender() == 0 ? "his" : this->GetGender() == 1 ? "her" : "its");
|
entity_list.MessageGroup(this,true,MT_Skills,"%s was unsuccessful in %s tradeskill attempt.",GetName(),this->GetGender() == 0 ? "his" : this->GetGender() == 1 ? "her" : "its");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* QS: Player_Log_Trade_Skill_Events */
|
||||||
|
if (RuleB(QueryServ, PlayerLogTradeSkillEvents)){
|
||||||
|
std::string event_desc = StringFormat("Failed :: recipe_id:%i tskillid:%i trivial:%i chance:%4.2f in zoneid:%i instid:%i", spec->recipe_id, spec->tradeskill, spec->trivial, chance, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Trade_Skill_Events, this->CharacterID(), event_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
itr = spec->onfail.begin();
|
itr = spec->onfail.begin();
|
||||||
@ -1106,6 +1124,8 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) {
|
|||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Salvage Item rolls */
|
||||||
|
|
||||||
// Rolls on each item, is possible to return everything
|
// Rolls on each item, is possible to return everything
|
||||||
int SalvageChance = aabonuses.SalvageChance + itembonuses.SalvageChance + spellbonuses.SalvageChance;
|
int SalvageChance = aabonuses.SalvageChance + itembonuses.SalvageChance + spellbonuses.SalvageChance;
|
||||||
// Skip check if not a normal TS or if a quest recipe these should be nofail, but check amyways
|
// Skip check if not a normal TS or if a quest recipe these should be nofail, but check amyways
|
||||||
|
|||||||
657
zone/trading.cpp
657
zone/trading.cpp
@ -22,7 +22,10 @@
|
|||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
#include "worldserver.h"
|
#include "worldserver.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
// The maximum amount of a single bazaar/barter transaction expressed in copper.
|
// The maximum amount of a single bazaar/barter transaction expressed in copper.
|
||||||
// Equivalent to 2 Million plat
|
// Equivalent to 2 Million plat
|
||||||
@ -71,8 +74,8 @@ void Trade::Start(uint32 mob_id, bool initiate_with)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add item from a given slot to trade bucket (automatically does bag data too)
|
// Add item from a given slot to trade bucket (automatically does bag data too)
|
||||||
void Trade::AddEntity(uint16 from_slot_id, uint16 trade_slot_id, uint32 stack_size) {
|
void Trade::AddEntity(uint16 trade_slot_id, uint32 stack_size) {
|
||||||
// TODO: review for inventory saves
|
// TODO: review for inventory saves / consider changing return type to bool so failure can be passed to desync handler
|
||||||
|
|
||||||
if (!owner || !owner->IsClient()) {
|
if (!owner || !owner->IsClient()) {
|
||||||
// This should never happen
|
// This should never happen
|
||||||
@ -121,7 +124,7 @@ void Trade::AddEntity(uint16 from_slot_id, uint16 trade_slot_id, uint32 stack_si
|
|||||||
if (_stack_size > 0)
|
if (_stack_size > 0)
|
||||||
inst->SetCharges(_stack_size);
|
inst->SetCharges(_stack_size);
|
||||||
else
|
else
|
||||||
client->DeleteItemInInventory(from_slot_id);
|
client->DeleteItemInInventory(MainCursor);
|
||||||
|
|
||||||
SendItemData(inst2, trade_slot_id);
|
SendItemData(inst2, trade_slot_id);
|
||||||
}
|
}
|
||||||
@ -136,7 +139,7 @@ void Trade::AddEntity(uint16 from_slot_id, uint16 trade_slot_id, uint32 stack_si
|
|||||||
_log(TRADING__HOLDER, "%s added item '%s' to trade slot %i", owner->GetName(), inst->GetItem()->Name, trade_slot_id);
|
_log(TRADING__HOLDER, "%s added item '%s' to trade slot %i", owner->GetName(), inst->GetItem()->Name, trade_slot_id);
|
||||||
|
|
||||||
client->PutItemInInventory(trade_slot_id, *inst);
|
client->PutItemInInventory(trade_slot_id, *inst);
|
||||||
client->DeleteItemInInventory(from_slot_id);
|
client->DeleteItemInInventory(MainCursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,200 +319,464 @@ void Trade::DumpTrade()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Client::ResetTrade() {
|
void Client::ResetTrade() {
|
||||||
const Item_Struct* TempItem = 0;
|
|
||||||
ItemInst* ins;
|
|
||||||
int x;
|
|
||||||
AddMoneyToPP(trade->cp, trade->sp, trade->gp, trade->pp, true);
|
AddMoneyToPP(trade->cp, trade->sp, trade->gp, trade->pp, true);
|
||||||
for(x = EmuConstants::TRADE_BEGIN; x <= EmuConstants::TRADE_END; x++)
|
|
||||||
{
|
// step 1: process bags
|
||||||
TempItem = 0;
|
for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) {
|
||||||
ins = GetInv().GetItem(x);
|
const ItemInst* inst = m_inv[trade_slot];
|
||||||
if (ins)
|
|
||||||
TempItem = ins->GetItem();
|
if (inst && inst->IsType(ItemClassContainer)) {
|
||||||
if (TempItem)
|
int16 free_slot = m_inv.FindFreeSlotForTradeItem(inst);
|
||||||
{
|
|
||||||
bool is_arrow = (TempItem->ItemType == ItemTypeArrow) ? true : false;
|
if (free_slot != INVALID_INDEX) {
|
||||||
int freeslotid = GetInv().FindFreeSlot(ins->IsType(ItemClassContainer), true, TempItem->Size, is_arrow);
|
PutItemInInventory(free_slot, *inst);
|
||||||
if (freeslotid == INVALID_INDEX)
|
SendItemPacket(free_slot, inst, ItemPacketTrade);
|
||||||
{
|
|
||||||
DropInst(ins);
|
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
DropInst(inst);
|
||||||
PutItemInInventory(freeslotid, *ins);
|
|
||||||
SendItemPacket(freeslotid, ins, ItemPacketTrade);
|
|
||||||
}
|
}
|
||||||
DeleteItemInInventory(x);
|
|
||||||
|
DeleteItemInInventory(trade_slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 2a: process stackables
|
||||||
|
for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) {
|
||||||
|
ItemInst* inst = GetInv().GetItem(trade_slot);
|
||||||
|
|
||||||
|
if (inst && inst->IsStackable()) {
|
||||||
|
while (true) {
|
||||||
|
// there's no built-in safety check against an infinite loop..but, it should break on one of the conditional checks
|
||||||
|
int16 free_slot = m_inv.FindFreeSlotForTradeItem(inst);
|
||||||
|
|
||||||
|
if ((free_slot == MainCursor) || (free_slot == INVALID_INDEX))
|
||||||
|
break;
|
||||||
|
|
||||||
|
ItemInst* partial_inst = GetInv().GetItem(free_slot);
|
||||||
|
|
||||||
|
if (!partial_inst)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (partial_inst->GetID() != inst->GetID()) {
|
||||||
|
_log(TRADING__ERROR, "Client::ResetTrade() - an incompatible location reference was returned by Inventory::FindFreeSlotForTradeItem()");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((partial_inst->GetCharges() + inst->GetCharges()) > partial_inst->GetItem()->StackSize) {
|
||||||
|
int16 new_charges = (partial_inst->GetCharges() + inst->GetCharges()) - partial_inst->GetItem()->StackSize;
|
||||||
|
|
||||||
|
partial_inst->SetCharges(partial_inst->GetItem()->StackSize);
|
||||||
|
inst->SetCharges(new_charges);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
partial_inst->SetCharges(partial_inst->GetCharges() + inst->GetCharges());
|
||||||
|
inst->SetCharges(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
PutItemInInventory(free_slot, *partial_inst);
|
||||||
|
SendItemPacket(free_slot, partial_inst, ItemPacketTrade);
|
||||||
|
|
||||||
|
if (inst->GetCharges() == 0) {
|
||||||
|
DeleteItemInInventory(trade_slot);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 2b: adjust trade stack bias
|
||||||
|
// (if any partial stacks exist before the final stack, FindFreeSlotForTradeItem() will return that slot in step 3 and an overwrite will occur)
|
||||||
|
for (int16 trade_slot = EmuConstants::TRADE_END; trade_slot >= EmuConstants::TRADE_BEGIN; --trade_slot) {
|
||||||
|
ItemInst* inst = GetInv().GetItem(trade_slot);
|
||||||
|
|
||||||
|
if (inst && inst->IsStackable()) {
|
||||||
|
for (int16 bias_slot = EmuConstants::TRADE_BEGIN; bias_slot <= EmuConstants::TRADE_END; ++bias_slot) {
|
||||||
|
if (bias_slot >= trade_slot)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ItemInst* bias_inst = GetInv().GetItem(bias_slot);
|
||||||
|
|
||||||
|
if (!bias_inst || (bias_inst->GetID() != inst->GetID()) || (bias_inst->GetCharges() >= bias_inst->GetItem()->StackSize))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((bias_inst->GetCharges() + inst->GetCharges()) > bias_inst->GetItem()->StackSize) {
|
||||||
|
int16 new_charges = (bias_inst->GetCharges() + inst->GetCharges()) - bias_inst->GetItem()->StackSize;
|
||||||
|
|
||||||
|
bias_inst->SetCharges(bias_inst->GetItem()->StackSize);
|
||||||
|
inst->SetCharges(new_charges);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bias_inst->SetCharges(bias_inst->GetCharges() + inst->GetCharges());
|
||||||
|
inst->SetCharges(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst->GetCharges() == 0) {
|
||||||
|
DeleteItemInInventory(trade_slot);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// step 3: process everything else
|
||||||
|
for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) {
|
||||||
|
const ItemInst* inst = m_inv[trade_slot];
|
||||||
|
|
||||||
|
if (inst) {
|
||||||
|
int16 free_slot = m_inv.FindFreeSlotForTradeItem(inst);
|
||||||
|
|
||||||
|
if (free_slot != INVALID_INDEX) {
|
||||||
|
PutItemInInventory(free_slot, *inst);
|
||||||
|
SendItemPacket(free_slot, inst, ItemPacketTrade);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DropInst(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteItemInInventory(trade_slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer) {
|
void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, std::list<void*>* event_details) {
|
||||||
|
|
||||||
if(tradingWith && tradingWith->IsClient()) {
|
if(tradingWith && tradingWith->IsClient()) {
|
||||||
Client* other = tradingWith->CastToClient();
|
Client* other = tradingWith->CastToClient();
|
||||||
|
QSPlayerLogTrade_Struct* qs_audit = nullptr;
|
||||||
|
bool qs_log = false;
|
||||||
|
|
||||||
if(other) {
|
if(other) {
|
||||||
mlog(TRADING__CLIENT, "Finishing trade with client %s", other->GetName());
|
mlog(TRADING__CLIENT, "Finishing trade with client %s", other->GetName());
|
||||||
|
|
||||||
int16 slot_id;
|
this->AddMoneyToPP(other->trade->cp, other->trade->sp, other->trade->gp, other->trade->pp, true);
|
||||||
const Item_Struct* item = nullptr;
|
|
||||||
QSPlayerLogTrade_Struct* qsaudit = nullptr;
|
|
||||||
bool QSPLT = false;
|
|
||||||
|
|
||||||
|
// step 0: pre-processing
|
||||||
// QS code
|
// QS code
|
||||||
if(qspack && RuleB(QueryServ, PlayerLogTrades)) {
|
if (RuleB(QueryServ, PlayerLogTrades) && event_entry && event_details) {
|
||||||
qsaudit = (QSPlayerLogTrade_Struct*) qspack->pBuffer;
|
qs_audit = (QSPlayerLogTrade_Struct*)event_entry;
|
||||||
QSPLT = true;
|
qs_log = true;
|
||||||
|
|
||||||
if(finalizer) { qsaudit->char2_id = this->character_id; }
|
if (finalizer) {
|
||||||
else { qsaudit->char1_id = this->character_id; }
|
qs_audit->char2_id = this->character_id;
|
||||||
|
|
||||||
|
qs_audit->char2_money.platinum = this->trade->pp;
|
||||||
|
qs_audit->char2_money.gold = this->trade->gp;
|
||||||
|
qs_audit->char2_money.silver = this->trade->sp;
|
||||||
|
qs_audit->char2_money.copper = this->trade->cp;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qs_audit->char1_id = this->character_id;
|
||||||
|
|
||||||
|
qs_audit->char1_money.platinum = this->trade->pp;
|
||||||
|
qs_audit->char1_money.gold = this->trade->gp;
|
||||||
|
qs_audit->char1_money.silver = this->trade->sp;
|
||||||
|
qs_audit->char1_money.copper = this->trade->cp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move each trade slot into free inventory slot
|
// step 1: process bags
|
||||||
for(int16 i = EmuConstants::TRADE_BEGIN; i <= EmuConstants::TRADE_END; i++){
|
for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) {
|
||||||
const ItemInst* inst = m_inv[i];
|
const ItemInst* inst = m_inv[trade_slot];
|
||||||
uint16 parent_offset = 0;
|
|
||||||
|
|
||||||
if(inst == nullptr) { continue; }
|
if (inst && inst->IsType(ItemClassContainer)) {
|
||||||
|
mlog(TRADING__CLIENT, "Giving container %s (%d) in slot %d to %s", inst->GetItem()->Name, inst->GetItem()->ID, trade_slot, other->GetName());
|
||||||
|
|
||||||
mlog(TRADING__CLIENT, "Giving %s (%d) in slot %d to %s", inst->GetItem()->Name, inst->GetItem()->ID, i, other->GetName());
|
// TODO: need to check bag items/augments for no drop..everything for attuned...
|
||||||
|
if (inst->GetItem()->NoDrop != 0 || Admin() >= RuleI(Character, MinStatusForNoDropExemptions) || RuleI(World, FVNoDropFlag) == 1 || other == this) {
|
||||||
|
int16 free_slot = other->GetInv().FindFreeSlotForTradeItem(inst);
|
||||||
|
|
||||||
/// Log Player Trades through QueryServ if Rule Enabled
|
if (free_slot != INVALID_INDEX) {
|
||||||
if(QSPLT) {
|
if (other->PutItemInInventory(free_slot, *inst, true)) {
|
||||||
uint16 item_count = qsaudit->char1_count + qsaudit->char2_count;
|
mlog(TRADING__CLIENT, "Container %s (%d) successfully transferred, deleting from trade slot.", inst->GetItem()->Name, inst->GetItem()->ID);
|
||||||
parent_offset = item_count;
|
if (qs_log) {
|
||||||
|
QSTradeItems_Struct* detail = new QSTradeItems_Struct;
|
||||||
|
|
||||||
qsaudit->items[item_count].from_id = this->character_id;
|
detail->from_id = this->character_id;
|
||||||
qsaudit->items[item_count].from_slot = i;
|
detail->from_slot = trade_slot;
|
||||||
qsaudit->items[item_count].to_id = other->CharacterID();
|
detail->to_id = other->CharacterID();
|
||||||
qsaudit->items[item_count].to_slot = 0;
|
detail->to_slot = free_slot;
|
||||||
qsaudit->items[item_count].item_id = inst->GetID();
|
detail->item_id = inst->GetID();
|
||||||
qsaudit->items[item_count].charges = inst->GetCharges();
|
detail->charges = 1;
|
||||||
qsaudit->items[item_count].aug_1 = inst->GetAugmentItemID(1);
|
detail->aug_1 = inst->GetAugmentItemID(1);
|
||||||
qsaudit->items[item_count].aug_2 = inst->GetAugmentItemID(2);
|
detail->aug_2 = inst->GetAugmentItemID(2);
|
||||||
qsaudit->items[item_count].aug_3 = inst->GetAugmentItemID(3);
|
detail->aug_3 = inst->GetAugmentItemID(3);
|
||||||
qsaudit->items[item_count].aug_4 = inst->GetAugmentItemID(4);
|
detail->aug_4 = inst->GetAugmentItemID(4);
|
||||||
qsaudit->items[item_count].aug_5 = inst->GetAugmentItemID(5);
|
detail->aug_5 = inst->GetAugmentItemID(5);
|
||||||
|
|
||||||
if(finalizer) { qsaudit->char2_count++; }
|
event_details->push_back(detail);
|
||||||
else { qsaudit->char1_count++; }
|
|
||||||
|
|
||||||
if(inst->IsType(ItemClassContainer)) {
|
if (finalizer)
|
||||||
// Pseudo-Slot ID's are generated based on how the db saves bag items...
|
qs_audit->char2_count += detail->charges;
|
||||||
for(uint8 j = SUB_BEGIN; j < inst->GetItem()->BagSlots; j++) {
|
else
|
||||||
const ItemInst* baginst = inst->GetItem(j);
|
qs_audit->char1_count += detail->charges;
|
||||||
|
|
||||||
if(baginst == nullptr) { continue; }
|
//for (uint8 sub_slot = SUB_BEGIN; ((sub_slot < inst->GetItem()->BagSlots) && (sub_slot < EmuConstants::ITEM_CONTAINER_SIZE)); ++sub_slot) {
|
||||||
|
for (uint8 sub_slot = SUB_BEGIN; (sub_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++sub_slot) { // this is to catch ALL items
|
||||||
|
const ItemInst* bag_inst = inst->GetItem(sub_slot);
|
||||||
|
|
||||||
int16 k=Inventory::CalcSlotId(i, j);
|
if (bag_inst) {
|
||||||
item_count = qsaudit->char1_count + qsaudit->char2_count;
|
detail = new QSTradeItems_Struct;
|
||||||
|
|
||||||
qsaudit->items[item_count].from_id = this->character_id;
|
detail->from_id = this->character_id;
|
||||||
qsaudit->items[item_count].from_slot = k;
|
detail->from_slot = Inventory::CalcSlotId(trade_slot, sub_slot);
|
||||||
qsaudit->items[item_count].to_id = other->CharacterID();
|
detail->to_id = other->CharacterID();
|
||||||
qsaudit->items[item_count].to_slot = 0;
|
detail->to_slot = Inventory::CalcSlotId(free_slot, sub_slot);
|
||||||
qsaudit->items[item_count].item_id = baginst->GetID();
|
detail->item_id = bag_inst->GetID();
|
||||||
qsaudit->items[item_count].charges = baginst->GetCharges();
|
detail->charges = (!bag_inst->IsStackable() ? 1 : bag_inst->GetCharges());
|
||||||
qsaudit->items[item_count].aug_1 = baginst->GetAugmentItemID(1);
|
detail->aug_1 = bag_inst->GetAugmentItemID(1);
|
||||||
qsaudit->items[item_count].aug_2 = baginst->GetAugmentItemID(2);
|
detail->aug_2 = bag_inst->GetAugmentItemID(2);
|
||||||
qsaudit->items[item_count].aug_3 = baginst->GetAugmentItemID(3);
|
detail->aug_3 = bag_inst->GetAugmentItemID(3);
|
||||||
qsaudit->items[item_count].aug_4 = baginst->GetAugmentItemID(4);
|
detail->aug_4 = bag_inst->GetAugmentItemID(4);
|
||||||
qsaudit->items[item_count].aug_5 = baginst->GetAugmentItemID(5);
|
detail->aug_5 = bag_inst->GetAugmentItemID(5);
|
||||||
|
|
||||||
if(finalizer) { qsaudit->char2_count++; }
|
event_details->push_back(detail);
|
||||||
else { qsaudit->char1_count++; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inst->GetItem()->NoDrop != 0 || Admin() >= RuleI(Character, MinStatusForNoDropExemptions) || RuleI(World, FVNoDropFlag) == 1 || other == this) {
|
if (finalizer)
|
||||||
bool is_arrow = (inst->GetItem()->ItemType == ItemTypeArrow) ? true : false;
|
qs_audit->char2_count += detail->charges;
|
||||||
slot_id = other->GetInv().FindFreeSlot(inst->IsType(ItemClassContainer), true, inst->GetItem()->Size, is_arrow);
|
else
|
||||||
|
qs_audit->char1_count += detail->charges;
|
||||||
mlog(TRADING__CLIENT, "Trying to put %s (%d) into slot %d", inst->GetItem()->Name, inst->GetItem()->ID, slot_id);
|
}
|
||||||
|
}
|
||||||
if(other->PutItemInInventory(slot_id, *inst, true)) {
|
|
||||||
mlog(TRADING__CLIENT, "Item %s (%d) successfully transfered, deleting from trade slot.", inst->GetItem()->Name, inst->GetItem()->ID);
|
|
||||||
|
|
||||||
if(QSPLT) {
|
|
||||||
qsaudit->items[parent_offset].to_slot = slot_id;
|
|
||||||
|
|
||||||
if(inst->IsType(ItemClassContainer)) {
|
|
||||||
for(uint8 bagslot_idx = SUB_BEGIN; bagslot_idx < inst->GetItem()->BagSlots; bagslot_idx++) {
|
|
||||||
const ItemInst* bag_inst = inst->GetItem(bagslot_idx);
|
|
||||||
|
|
||||||
if(bag_inst == nullptr) { continue; }
|
|
||||||
int16 to_bagslot_id = Inventory::CalcSlotId(slot_id, bagslot_idx);
|
|
||||||
|
|
||||||
qsaudit->items[++parent_offset].to_slot = to_bagslot_id;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
mlog(TRADING__ERROR, "Transfer of container %s (%d) to %s failed, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID, other->GetName());
|
||||||
|
PushItemOnCursor(*inst, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mlog(TRADING__ERROR, "%s's inventory is full, returning container %s (%d) to giver.", other->GetName(), inst->GetItem()->Name, inst->GetItem()->ID);
|
||||||
|
PushItemOnCursor(*inst, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
mlog(TRADING__ERROR, "Container %s (%d) is NoDrop, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID);
|
||||||
PushItemOnCursor(*inst, true);
|
PushItemOnCursor(*inst, true);
|
||||||
mlog(TRADING__ERROR, "Unable to give item %d (%d) to %s, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID, other->GetName());
|
|
||||||
|
|
||||||
if(QSPLT) {
|
|
||||||
qsaudit->items[parent_offset].to_id = this->character_id;
|
|
||||||
qsaudit->items[parent_offset].to_slot = MainCursor;
|
|
||||||
|
|
||||||
if(inst->IsType(ItemClassContainer)) {
|
|
||||||
for(uint8 bagslot_idx = SUB_BEGIN; bagslot_idx < inst->GetItem()->BagSlots; bagslot_idx++) {
|
|
||||||
const ItemInst* bag_inst = inst->GetItem(bagslot_idx);
|
|
||||||
|
|
||||||
if(bag_inst == nullptr) { continue; }
|
|
||||||
int16 to_bagslot_id = Inventory::CalcSlotId(MainCursor, bagslot_idx);
|
|
||||||
|
|
||||||
qsaudit->items[++parent_offset].to_id = this->character_id;
|
|
||||||
qsaudit->items[parent_offset].to_slot = to_bagslot_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteItemInInventory(i);
|
DeleteItemInInventory(trade_slot);
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
PushItemOnCursor(*inst, true);
|
|
||||||
DeleteItemInInventory(i);
|
|
||||||
|
|
||||||
if(QSPLT) {
|
// step 2a: process stackables
|
||||||
qsaudit->items[parent_offset].to_id = this->character_id;
|
for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) {
|
||||||
qsaudit->items[parent_offset].to_slot = MainCursor;
|
ItemInst* inst = GetInv().GetItem(trade_slot);
|
||||||
|
|
||||||
if(inst->IsType(ItemClassContainer)) {
|
if (inst && inst->IsStackable()) {
|
||||||
for(uint8 bagslot_idx = SUB_BEGIN; bagslot_idx < inst->GetItem()->BagSlots; bagslot_idx++) {
|
while (true) {
|
||||||
const ItemInst* bag_inst = inst->GetItem(bagslot_idx);
|
// there's no built-in safety check against an infinite loop..but, it should break on one of the conditional checks
|
||||||
|
int16 partial_slot = other->GetInv().FindFreeSlotForTradeItem(inst);
|
||||||
|
|
||||||
if(bag_inst == nullptr) { continue; }
|
if ((partial_slot == MainCursor) || (partial_slot == INVALID_INDEX))
|
||||||
int16 to_bagslot_id = Inventory::CalcSlotId(MainCursor, bagslot_idx);
|
break;
|
||||||
|
|
||||||
qsaudit->items[++parent_offset].to_id = this->character_id;
|
ItemInst* partial_inst = other->GetInv().GetItem(partial_slot);
|
||||||
qsaudit->items[parent_offset].to_slot = to_bagslot_id;
|
|
||||||
|
if (!partial_inst)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (partial_inst->GetID() != inst->GetID()) {
|
||||||
|
_log(TRADING__ERROR, "Client::ResetTrade() - an incompatible location reference was returned by Inventory::FindFreeSlotForTradeItem()");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 old_charges = inst->GetCharges();
|
||||||
|
int16 partial_charges = partial_inst->GetCharges();
|
||||||
|
|
||||||
|
if ((partial_inst->GetCharges() + inst->GetCharges()) > partial_inst->GetItem()->StackSize) {
|
||||||
|
int16 new_charges = (partial_inst->GetCharges() + inst->GetCharges()) - partial_inst->GetItem()->StackSize;
|
||||||
|
|
||||||
|
partial_inst->SetCharges(partial_inst->GetItem()->StackSize);
|
||||||
|
inst->SetCharges(new_charges);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
partial_inst->SetCharges(partial_inst->GetCharges() + inst->GetCharges());
|
||||||
|
inst->SetCharges(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
mlog(TRADING__CLIENT, "Transferring partial stack %s (%d) in slot %d to %s", inst->GetItem()->Name, inst->GetItem()->ID, trade_slot, other->GetName());
|
||||||
|
|
||||||
|
if (other->PutItemInInventory(partial_slot, *partial_inst, true)) {
|
||||||
|
mlog(TRADING__CLIENT, "Partial stack %s (%d) successfully transferred, deleting %i charges from trade slot.",
|
||||||
|
inst->GetItem()->Name, inst->GetItem()->ID, (old_charges - inst->GetCharges()));
|
||||||
|
if (qs_log) {
|
||||||
|
QSTradeItems_Struct* detail = new QSTradeItems_Struct;
|
||||||
|
|
||||||
|
detail->from_id = this->character_id;
|
||||||
|
detail->from_slot = trade_slot;
|
||||||
|
detail->to_id = other->CharacterID();
|
||||||
|
detail->to_slot = partial_slot;
|
||||||
|
detail->item_id = inst->GetID();
|
||||||
|
detail->charges = (old_charges - inst->GetCharges());
|
||||||
|
detail->aug_1 = 0;
|
||||||
|
detail->aug_2 = 0;
|
||||||
|
detail->aug_3 = 0;
|
||||||
|
detail->aug_4 = 0;
|
||||||
|
detail->aug_5 = 0;
|
||||||
|
|
||||||
|
event_details->push_back(detail);
|
||||||
|
|
||||||
|
if (finalizer)
|
||||||
|
qs_audit->char2_count += detail->charges;
|
||||||
|
else
|
||||||
|
qs_audit->char1_count += detail->charges;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
mlog(TRADING__ERROR, "Transfer of partial stack %s (%d) to %s failed, returning %i charges to trade slot.",
|
||||||
|
inst->GetItem()->Name, inst->GetItem()->ID, other->GetName(), (old_charges - inst->GetCharges()));
|
||||||
|
|
||||||
|
inst->SetCharges(old_charges);
|
||||||
|
partial_inst->SetCharges(partial_charges);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst->GetCharges() == 0) {
|
||||||
|
DeleteItemInInventory(trade_slot);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Money - look into how NPC's receive cash
|
// step 2b: adjust trade stack bias
|
||||||
this->AddMoneyToPP(other->trade->cp, other->trade->sp, other->trade->gp, other->trade->pp, true);
|
// (if any partial stacks exist before the final stack, FindFreeSlotForTradeItem() will return that slot in step 3 and an overwrite will occur)
|
||||||
|
for (int16 trade_slot = EmuConstants::TRADE_END; trade_slot >= EmuConstants::TRADE_BEGIN; --trade_slot) {
|
||||||
|
ItemInst* inst = GetInv().GetItem(trade_slot);
|
||||||
|
|
||||||
// This is currently setup to show character offers, not receipts
|
if (inst && inst->IsStackable()) {
|
||||||
if(QSPLT) {
|
for (int16 bias_slot = EmuConstants::TRADE_BEGIN; bias_slot <= EmuConstants::TRADE_END; ++bias_slot) {
|
||||||
if(finalizer) {
|
if (bias_slot >= trade_slot)
|
||||||
qsaudit->char2_money.platinum = this->trade->pp;
|
break;
|
||||||
qsaudit->char2_money.gold = this->trade->gp;
|
|
||||||
qsaudit->char2_money.silver = this->trade->sp;
|
ItemInst* bias_inst = GetInv().GetItem(bias_slot);
|
||||||
qsaudit->char2_money.copper = this->trade->cp;
|
|
||||||
|
if (!bias_inst || (bias_inst->GetID() != inst->GetID()) || (bias_inst->GetCharges() >= bias_inst->GetItem()->StackSize))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int16 old_charges = inst->GetCharges();
|
||||||
|
|
||||||
|
if ((bias_inst->GetCharges() + inst->GetCharges()) > bias_inst->GetItem()->StackSize) {
|
||||||
|
int16 new_charges = (bias_inst->GetCharges() + inst->GetCharges()) - bias_inst->GetItem()->StackSize;
|
||||||
|
|
||||||
|
bias_inst->SetCharges(bias_inst->GetItem()->StackSize);
|
||||||
|
inst->SetCharges(new_charges);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bias_inst->SetCharges(bias_inst->GetCharges() + inst->GetCharges());
|
||||||
|
inst->SetCharges(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qs_log) {
|
||||||
|
QSTradeItems_Struct* detail = new QSTradeItems_Struct;
|
||||||
|
|
||||||
|
detail->from_id = this->character_id;
|
||||||
|
detail->from_slot = trade_slot;
|
||||||
|
detail->to_id = this->character_id;
|
||||||
|
detail->to_slot = bias_slot;
|
||||||
|
detail->item_id = inst->GetID();
|
||||||
|
detail->charges = (old_charges - inst->GetCharges());
|
||||||
|
detail->aug_1 = 0;
|
||||||
|
detail->aug_2 = 0;
|
||||||
|
detail->aug_3 = 0;
|
||||||
|
detail->aug_4 = 0;
|
||||||
|
detail->aug_5 = 0;
|
||||||
|
|
||||||
|
event_details->push_back(detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst->GetCharges() == 0) {
|
||||||
|
DeleteItemInInventory(trade_slot);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
qsaudit->char1_money.platinum = this->trade->pp;
|
|
||||||
qsaudit->char1_money.gold = this->trade->gp;
|
// step 3: process everything else
|
||||||
qsaudit->char1_money.silver = this->trade->sp;
|
for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_END; ++trade_slot) {
|
||||||
qsaudit->char1_money.copper = this->trade->cp;
|
const ItemInst* inst = m_inv[trade_slot];
|
||||||
|
|
||||||
|
if (inst) {
|
||||||
|
mlog(TRADING__CLIENT, "Giving item %s (%d) in slot %d to %s", inst->GetItem()->Name, inst->GetItem()->ID, trade_slot, other->GetName());
|
||||||
|
|
||||||
|
// TODO: need to check bag items/augments for no drop..everything for attuned...
|
||||||
|
if (inst->GetItem()->NoDrop != 0 || Admin() >= RuleI(Character, MinStatusForNoDropExemptions) || RuleI(World, FVNoDropFlag) == 1 || other == this) {
|
||||||
|
int16 free_slot = other->GetInv().FindFreeSlotForTradeItem(inst);
|
||||||
|
|
||||||
|
if (free_slot != INVALID_INDEX) {
|
||||||
|
if (other->PutItemInInventory(free_slot, *inst, true)) {
|
||||||
|
mlog(TRADING__CLIENT, "Item %s (%d) successfully transferred, deleting from trade slot.", inst->GetItem()->Name, inst->GetItem()->ID);
|
||||||
|
if (qs_log) {
|
||||||
|
QSTradeItems_Struct* detail = new QSTradeItems_Struct;
|
||||||
|
|
||||||
|
detail->from_id = this->character_id;
|
||||||
|
detail->from_slot = trade_slot;
|
||||||
|
detail->to_id = other->CharacterID();
|
||||||
|
detail->to_slot = free_slot;
|
||||||
|
detail->item_id = inst->GetID();
|
||||||
|
detail->charges = (!inst->IsStackable() ? 1 : inst->GetCharges());
|
||||||
|
detail->aug_1 = inst->GetAugmentItemID(1);
|
||||||
|
detail->aug_2 = inst->GetAugmentItemID(2);
|
||||||
|
detail->aug_3 = inst->GetAugmentItemID(3);
|
||||||
|
detail->aug_4 = inst->GetAugmentItemID(4);
|
||||||
|
detail->aug_5 = inst->GetAugmentItemID(5);
|
||||||
|
|
||||||
|
event_details->push_back(detail);
|
||||||
|
|
||||||
|
if (finalizer)
|
||||||
|
qs_audit->char2_count += detail->charges;
|
||||||
|
else
|
||||||
|
qs_audit->char1_count += detail->charges;
|
||||||
|
|
||||||
|
// 'step 3' should never really see containers..but, just in case...
|
||||||
|
//for (uint8 sub_slot = SUB_BEGIN; ((sub_slot < inst->GetItem()->BagSlots) && (sub_slot < EmuConstants::ITEM_CONTAINER_SIZE)); ++sub_slot) {
|
||||||
|
for (uint8 sub_slot = SUB_BEGIN; (sub_slot < EmuConstants::ITEM_CONTAINER_SIZE); ++sub_slot) { // this is to catch ALL items
|
||||||
|
const ItemInst* bag_inst = inst->GetItem(sub_slot);
|
||||||
|
|
||||||
|
if (bag_inst) {
|
||||||
|
detail = new QSTradeItems_Struct;
|
||||||
|
|
||||||
|
detail->from_id = this->character_id;
|
||||||
|
detail->from_slot = trade_slot;
|
||||||
|
detail->to_id = other->CharacterID();
|
||||||
|
detail->to_slot = free_slot;
|
||||||
|
detail->item_id = bag_inst->GetID();
|
||||||
|
detail->charges = (!bag_inst->IsStackable() ? 1 : bag_inst->GetCharges());
|
||||||
|
detail->aug_1 = bag_inst->GetAugmentItemID(1);
|
||||||
|
detail->aug_2 = bag_inst->GetAugmentItemID(2);
|
||||||
|
detail->aug_3 = bag_inst->GetAugmentItemID(3);
|
||||||
|
detail->aug_4 = bag_inst->GetAugmentItemID(4);
|
||||||
|
detail->aug_5 = bag_inst->GetAugmentItemID(5);
|
||||||
|
|
||||||
|
event_details->push_back(detail);
|
||||||
|
|
||||||
|
if (finalizer)
|
||||||
|
qs_audit->char2_count += detail->charges;
|
||||||
|
else
|
||||||
|
qs_audit->char1_count += detail->charges;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mlog(TRADING__ERROR, "Transfer of Item %s (%d) to %s failed, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID, other->GetName());
|
||||||
|
PushItemOnCursor(*inst, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mlog(TRADING__ERROR, "%s's inventory is full, returning item %s (%d) to giver.", other->GetName(), inst->GetItem()->Name, inst->GetItem()->ID);
|
||||||
|
PushItemOnCursor(*inst, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mlog(TRADING__ERROR, "Item %s (%d) is NoDrop, returning to giver.", inst->GetItem()->Name, inst->GetItem()->ID);
|
||||||
|
PushItemOnCursor(*inst, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteItemInInventory(trade_slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,62 +784,72 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(tradingWith && tradingWith->IsNPC()) {
|
else if(tradingWith && tradingWith->IsNPC()) {
|
||||||
QSPlayerLogHandin_Struct* qsaudit = nullptr;
|
QSPlayerLogHandin_Struct* qs_audit = nullptr;
|
||||||
bool QSPLH = false;
|
bool qs_log = false;
|
||||||
|
|
||||||
// QS code
|
// QS code
|
||||||
if(qspack && RuleB(QueryServ, PlayerLogTrades)) {
|
if(RuleB(QueryServ, PlayerLogTrades) && event_entry && event_details) {
|
||||||
// Currently provides only basic functionality. Calling method will also
|
// Currently provides only basic functionality. Calling method will also
|
||||||
// need to be modified before item returns and rewards can be logged. -U
|
// need to be modified before item returns and rewards can be logged. -U
|
||||||
qsaudit = (QSPlayerLogHandin_Struct*) qspack->pBuffer;
|
qs_audit = (QSPlayerLogHandin_Struct*)event_entry;
|
||||||
QSPLH = true;
|
qs_log = true;
|
||||||
|
|
||||||
qsaudit->quest_id = 0;
|
qs_audit->quest_id = 0;
|
||||||
qsaudit->char_id = character_id;
|
qs_audit->char_id = character_id;
|
||||||
qsaudit->char_money.platinum = trade->pp;
|
qs_audit->char_money.platinum = trade->pp;
|
||||||
qsaudit->char_money.gold = trade->gp;
|
qs_audit->char_money.gold = trade->gp;
|
||||||
qsaudit->char_money.silver = trade->sp;
|
qs_audit->char_money.silver = trade->sp;
|
||||||
qsaudit->char_money.copper = trade->cp;
|
qs_audit->char_money.copper = trade->cp;
|
||||||
qsaudit->char_count = 0;
|
qs_audit->char_count = 0;
|
||||||
qsaudit->npc_id = tradingWith->GetNPCTypeID();
|
qs_audit->npc_id = tradingWith->GetNPCTypeID();
|
||||||
qsaudit->npc_money.platinum = 0;
|
qs_audit->npc_money.platinum = 0;
|
||||||
qsaudit->npc_money.gold = 0;
|
qs_audit->npc_money.gold = 0;
|
||||||
qsaudit->npc_money.silver = 0;
|
qs_audit->npc_money.silver = 0;
|
||||||
qsaudit->npc_money.copper = 0;
|
qs_audit->npc_money.copper = 0;
|
||||||
qsaudit->npc_count = 0;
|
qs_audit->npc_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(QSPLH) { // This can be incoporated below when revisions are made -U
|
if(qs_log) { // This can be incorporated below when revisions are made -U
|
||||||
for(int16 slot_id = EmuConstants::TRADE_BEGIN; slot_id <= EmuConstants::TRADE_NPC_END; slot_id++) {
|
for (int16 trade_slot = EmuConstants::TRADE_BEGIN; trade_slot <= EmuConstants::TRADE_NPC_END; ++trade_slot) {
|
||||||
const ItemInst* trade_inst = m_inv[slot_id];
|
const ItemInst* trade_inst = m_inv[trade_slot];
|
||||||
|
|
||||||
if(trade_inst) {
|
if(trade_inst) {
|
||||||
strcpy(qsaudit->items[qsaudit->char_count].action_type, "HANDIN");
|
QSHandinItems_Struct* detail = new QSHandinItems_Struct;
|
||||||
|
|
||||||
qsaudit->items[qsaudit->char_count].char_slot = slot_id;
|
strcpy(detail->action_type, "HANDIN");
|
||||||
qsaudit->items[qsaudit->char_count].item_id = trade_inst->GetID();
|
|
||||||
qsaudit->items[qsaudit->char_count].charges = trade_inst->GetCharges();
|
detail->char_slot = trade_slot;
|
||||||
qsaudit->items[qsaudit->char_count].aug_1 = trade_inst->GetAugmentItemID(1);
|
detail->item_id = trade_inst->GetID();
|
||||||
qsaudit->items[qsaudit->char_count].aug_2 = trade_inst->GetAugmentItemID(2);
|
detail->charges = (!trade_inst->IsStackable() ? 1 : trade_inst->GetCharges());
|
||||||
qsaudit->items[qsaudit->char_count].aug_3 = trade_inst->GetAugmentItemID(3);
|
detail->aug_1 = trade_inst->GetAugmentItemID(1);
|
||||||
qsaudit->items[qsaudit->char_count].aug_4 = trade_inst->GetAugmentItemID(4);
|
detail->aug_2 = trade_inst->GetAugmentItemID(2);
|
||||||
qsaudit->items[qsaudit->char_count++].aug_5 = trade_inst->GetAugmentItemID(5);
|
detail->aug_3 = trade_inst->GetAugmentItemID(3);
|
||||||
|
detail->aug_4 = trade_inst->GetAugmentItemID(4);
|
||||||
|
detail->aug_5 = trade_inst->GetAugmentItemID(5);
|
||||||
|
|
||||||
|
event_details->push_back(detail);
|
||||||
|
qs_audit->char_count += detail->charges;
|
||||||
|
|
||||||
if(trade_inst->IsType(ItemClassContainer)) {
|
if(trade_inst->IsType(ItemClassContainer)) {
|
||||||
for(uint8 bag_idx = SUB_BEGIN; bag_idx < trade_inst->GetItem()->BagSlots; bag_idx++) {
|
for (uint8 sub_slot = SUB_BEGIN; sub_slot < trade_inst->GetItem()->BagSlots; ++sub_slot) {
|
||||||
const ItemInst* trade_baginst = trade_inst->GetItem(bag_idx);
|
const ItemInst* trade_baginst = trade_inst->GetItem(sub_slot);
|
||||||
|
|
||||||
if(trade_baginst) {
|
if(trade_baginst) {
|
||||||
strcpy(qsaudit->items[qsaudit->char_count].action_type, "HANDIN");
|
detail = new QSHandinItems_Struct;
|
||||||
|
|
||||||
qsaudit->items[qsaudit->char_count].char_slot = Inventory::CalcSlotId(slot_id, bag_idx);
|
strcpy(detail->action_type, "HANDIN");
|
||||||
qsaudit->items[qsaudit->char_count].item_id = trade_baginst->GetID();
|
|
||||||
qsaudit->items[qsaudit->char_count].charges = trade_baginst->GetCharges();
|
detail->char_slot = Inventory::CalcSlotId(trade_slot, sub_slot);
|
||||||
qsaudit->items[qsaudit->char_count].aug_1 = trade_baginst->GetAugmentItemID(1);
|
detail->item_id = trade_baginst->GetID();
|
||||||
qsaudit->items[qsaudit->char_count].aug_2 = trade_baginst->GetAugmentItemID(2);
|
detail->charges = (!trade_inst->IsStackable() ? 1 : trade_inst->GetCharges());
|
||||||
qsaudit->items[qsaudit->char_count].aug_3 = trade_baginst->GetAugmentItemID(3);
|
detail->aug_1 = trade_baginst->GetAugmentItemID(1);
|
||||||
qsaudit->items[qsaudit->char_count].aug_4 = trade_baginst->GetAugmentItemID(4);
|
detail->aug_2 = trade_baginst->GetAugmentItemID(2);
|
||||||
qsaudit->items[qsaudit->char_count++].aug_5 = trade_baginst->GetAugmentItemID(5);
|
detail->aug_3 = trade_baginst->GetAugmentItemID(3);
|
||||||
|
detail->aug_4 = trade_baginst->GetAugmentItemID(4);
|
||||||
|
detail->aug_5 = trade_baginst->GetAugmentItemID(5);
|
||||||
|
|
||||||
|
event_details->push_back(detail);
|
||||||
|
qs_audit->char_count += detail->charges;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -586,7 +863,7 @@ void Client::FinishTrade(Mob* tradingWith, ServerPacket* qspack, bool finalizer)
|
|||||||
quest_npc = true;
|
quest_npc = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<void*> item_list;
|
std::vector<EQEmu::Any> item_list;
|
||||||
uint32 items[4] = { 0 };
|
uint32 items[4] = { 0 };
|
||||||
for(int i = EmuConstants::TRADE_BEGIN; i <= EmuConstants::TRADE_NPC_END; ++i) {
|
for(int i = EmuConstants::TRADE_BEGIN; i <= EmuConstants::TRADE_NPC_END; ++i) {
|
||||||
ItemInst *inst = m_inv.GetItem(i);
|
ItemInst *inst = m_inv.GetItem(i);
|
||||||
|
|||||||
@ -262,45 +262,36 @@ Mob* EntityList::GetTrapTrigger(Trap* trap) {
|
|||||||
|
|
||||||
//todo: rewrite this to not need direct access to trap members.
|
//todo: rewrite this to not need direct access to trap members.
|
||||||
bool ZoneDatabase::LoadTraps(const char* zonename, int16 version) {
|
bool ZoneDatabase::LoadTraps(const char* zonename, int16 version) {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char *query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
// int char_num = 0;
|
std::string query = StringFormat("SELECT id, x, y, z, effect, effectvalue, effectvalue2, skill, "
|
||||||
unsigned long* lengths;
|
"maxzdiff, radius, chance, message, respawn_time, respawn_var, level "
|
||||||
|
"FROM traps WHERE zone='%s' AND version=%u", zonename, version);
|
||||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT id,x,y,z,effect,effectvalue,effectvalue2,skill,maxzdiff,radius,chance,message,respawn_time,respawn_var,level FROM traps WHERE zone='%s' AND version=%u", zonename, version), errbuf, &result)) {
|
auto results = QueryDatabase(query);
|
||||||
safe_delete_array(query);
|
if (!results.Success()) {
|
||||||
while ((row = mysql_fetch_row(result)))
|
LogFile->write(EQEMuLog::Error, "Error in LoadTraps query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
{
|
|
||||||
lengths = mysql_fetch_lengths(result);
|
|
||||||
Trap* trap = new Trap();
|
|
||||||
trap->trap_id = atoi(row[0]);
|
|
||||||
trap->x = atof(row[1]);
|
|
||||||
trap->y = atof(row[2]);
|
|
||||||
trap->z = atof(row[3]);
|
|
||||||
trap->effect = atoi(row[4]);
|
|
||||||
trap->effectvalue = atoi(row[5]);
|
|
||||||
trap->effectvalue2 = atoi(row[6]);
|
|
||||||
trap->skill = atoi(row[7]);
|
|
||||||
trap->maxzdiff = atof(row[8]);
|
|
||||||
trap->radius = atof(row[9]);
|
|
||||||
trap->chance = atoi(row[10]);
|
|
||||||
trap->message = row[11];
|
|
||||||
trap->respawn_time = atoi(row[12]);
|
|
||||||
trap->respawn_var = atoi(row[13]);
|
|
||||||
trap->level = atoi(row[14]);
|
|
||||||
entity_list.AddTrap(trap);
|
|
||||||
trap->CreateHiddenTrigger();
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadTraps query '%s': %s", query, errbuf);
|
|
||||||
safe_delete_array(query);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
Trap* trap = new Trap();
|
||||||
|
trap->trap_id = atoi(row[0]);
|
||||||
|
trap->x = atof(row[1]);
|
||||||
|
trap->y = atof(row[2]);
|
||||||
|
trap->z = atof(row[3]);
|
||||||
|
trap->effect = atoi(row[4]);
|
||||||
|
trap->effectvalue = atoi(row[5]);
|
||||||
|
trap->effectvalue2 = atoi(row[6]);
|
||||||
|
trap->skill = atoi(row[7]);
|
||||||
|
trap->maxzdiff = atof(row[8]);
|
||||||
|
trap->radius = atof(row[9]);
|
||||||
|
trap->chance = atoi(row[10]);
|
||||||
|
trap->message = row[11];
|
||||||
|
trap->respawn_time = atoi(row[12]);
|
||||||
|
trap->respawn_var = atoi(row[13]);
|
||||||
|
trap->level = atoi(row[14]);
|
||||||
|
entity_list.AddTrap(trap);
|
||||||
|
trap->CreateHiddenTrigger();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -378,68 +378,60 @@ void Client::SendGuildTributes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::LoadTributes() {
|
bool ZoneDatabase::LoadTributes() {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
TributeData t;
|
TributeData tributeData;
|
||||||
memset(&t.tiers, 0, sizeof(t.tiers));
|
memset(&tributeData.tiers, 0, sizeof(tributeData.tiers));
|
||||||
t.tier_count = 0;
|
tributeData.tier_count = 0;
|
||||||
|
|
||||||
tribute_list.clear();
|
tribute_list.clear();
|
||||||
|
|
||||||
const char *query = "SELECT id,name,descr,unknown,isguild FROM tributes";
|
const std::string query = "SELECT id, name, descr, unknown, isguild FROM tributes";
|
||||||
if (RunQuery(query, strlen(query), errbuf, &result)) {
|
auto results = QueryDatabase(query);
|
||||||
int r;
|
if (!results.Success()) {
|
||||||
while ((row = mysql_fetch_row(result))) {
|
LogFile->write(EQEMuLog::Error, "Error in LoadTributes first query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
r = 0;
|
|
||||||
uint32 id = atoul(row[r++]);
|
|
||||||
t.name = row[r++];
|
|
||||||
t.description = row[r++];
|
|
||||||
t.unknown = strtoul(row[r++], nullptr, 10);
|
|
||||||
t.is_guild = atol(row[r++])==0?false:true;
|
|
||||||
|
|
||||||
tribute_list[id] = t;
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
} else {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadTributes first query '%s': %s", query, errbuf);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
uint32 id = atoul(row[0]);
|
||||||
|
tributeData.name = row[1];
|
||||||
|
tributeData.description = row[2];
|
||||||
|
tributeData.unknown = strtoul(row[3], nullptr, 10);
|
||||||
|
tributeData.is_guild = atol(row[4]) == 0? false: true;
|
||||||
|
|
||||||
const char *query2 = "SELECT tribute_id,level,cost,item_id FROM tribute_levels ORDER BY tribute_id,level";
|
tribute_list[id] = tributeData;
|
||||||
if (RunQuery(query2, strlen(query2), errbuf, &result)) {
|
}
|
||||||
int r;
|
|
||||||
while ((row = mysql_fetch_row(result))) {
|
|
||||||
r = 0;
|
|
||||||
uint32 id = atoul(row[r++]);
|
|
||||||
|
|
||||||
if(tribute_list.count(id) != 1) {
|
const std::string query2 = "SELECT tribute_id, level, cost, item_id FROM tribute_levels ORDER BY tribute_id, level";
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadTributes: unknown tribute %lu in tribute_levels", (unsigned long)id);
|
results = QueryDatabase(query2);
|
||||||
continue;
|
if (!results.Success()) {
|
||||||
}
|
LogFile->write(EQEMuLog::Error, "Error in LoadTributes level query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
|
||||||
TributeData &cur = tribute_list[id];
|
|
||||||
|
|
||||||
if(cur.tier_count >= MAX_TRIBUTE_TIERS) {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadTributes: on tribute %lu: more tiers defined than permitted", (unsigned long)id);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TributeLevel_Struct &s = cur.tiers[cur.tier_count];
|
|
||||||
|
|
||||||
s.level = atoul(row[r++]);
|
|
||||||
s.cost = atoul(row[r++]);
|
|
||||||
s.tribute_item_id = atoul(row[r++]);
|
|
||||||
cur.tier_count++;
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
} else {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadTributes level query '%s': %s", query, errbuf);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
uint32 id = atoul(row[0]);
|
||||||
|
|
||||||
|
if(tribute_list.count(id) != 1) {
|
||||||
|
LogFile->write(EQEMuLog::Error, "Error in LoadTributes: unknown tribute %lu in tribute_levels", (unsigned long)id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TributeData &cur = tribute_list[id];
|
||||||
|
|
||||||
|
if(cur.tier_count >= MAX_TRIBUTE_TIERS) {
|
||||||
|
LogFile->write(EQEMuLog::Error, "Error in LoadTributes: on tribute %lu: more tiers defined than permitted", (unsigned long)id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TributeLevel_Struct &s = cur.tiers[cur.tier_count];
|
||||||
|
|
||||||
|
s.level = atoul(row[1]);
|
||||||
|
s.cost = atoul(row[2]);
|
||||||
|
s.tribute_item_id = atoul(row[3]);
|
||||||
|
cur.tier_count++;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -869,97 +869,78 @@ void NPC::AssignWaypoints(int32 grid) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char *query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
bool GridErr = false, WPErr = false;
|
|
||||||
Waypoints.clear();
|
Waypoints.clear();
|
||||||
|
roamer = false;
|
||||||
|
|
||||||
// Retrieve the wander and pause types for this grid
|
// Retrieve the wander and pause types for this grid
|
||||||
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT `type`,`type2` FROM `grid` WHERE `id`=%i AND `zoneid`=%i",grid,zone->GetZoneID()),errbuf, &result))
|
std::string query = StringFormat("SELECT `type`, `type2` FROM `grid` WHERE `id` = %i AND `zoneid` = %i", grid, zone->GetZoneID());
|
||||||
{
|
auto results = database.QueryDatabase(query);
|
||||||
if((row = mysql_fetch_row(result)))
|
if (!results.Success()) {
|
||||||
{
|
LogFile->write(EQEMuLog::Error, "MySQL Error while trying to assign grid %u to mob %s: %s", grid, name, results.ErrorMessage().c_str());
|
||||||
if(row[0] != 0)
|
return;
|
||||||
wandertype = atoi(row[0]);
|
|
||||||
else
|
|
||||||
wandertype = 0;
|
|
||||||
if(row[1] != 0)
|
|
||||||
pausetype = atoi(row[1]);
|
|
||||||
else
|
|
||||||
pausetype = 0;
|
|
||||||
}
|
|
||||||
else // No grid record found in this zone for the given ID
|
|
||||||
GridErr = true;
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
}
|
||||||
else // DB query error!
|
|
||||||
{
|
|
||||||
GridErr = true;
|
|
||||||
LogFile->write(EQEMuLog::Error, "MySQL Error while trying to assign grid %u to mob %s: %s", grid, name, errbuf);
|
|
||||||
}
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
if(!GridErr)
|
if (results.RowCount() == 0)
|
||||||
{
|
return;
|
||||||
this->CastToNPC()->SetGrid(grid); // Assign grid number
|
|
||||||
|
|
||||||
// Retrieve all waypoints for this grid
|
auto row = results.begin();
|
||||||
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT `x`,`y`,`z`,`pause`,`heading` FROM grid_entries WHERE `gridid`=%i AND `zoneid`=%i ORDER BY `number`",grid,zone->GetZoneID()),errbuf,&result))
|
|
||||||
{
|
|
||||||
roamer = true;
|
|
||||||
max_wp = -1; // Initialize it; will increment it for each waypoint successfully added to the list
|
|
||||||
|
|
||||||
while((row = mysql_fetch_row(result)))
|
wandertype = atoi(row[0]);
|
||||||
{
|
pausetype = atoi(row[1]);
|
||||||
if(row[0] != 0 && row[1] != 0 && row[2] != 0 && row[3] != 0)
|
|
||||||
{
|
|
||||||
wplist newwp;
|
|
||||||
newwp.index = ++max_wp;
|
|
||||||
newwp.x = atof(row[0]);
|
|
||||||
newwp.y = atof(row[1]);
|
|
||||||
newwp.z = atof(row[2]);
|
|
||||||
|
|
||||||
if(zone->HasMap() && RuleB(Map, FixPathingZWhenLoading) )
|
|
||||||
{
|
|
||||||
if(!RuleB(Watermap, CheckWaypointsInWaterWhenLoading) || !zone->HasWaterMap() ||
|
|
||||||
(zone->HasWaterMap() && !zone->watermap->InWater(newwp.x, newwp.y, newwp.z)))
|
|
||||||
{
|
|
||||||
Map::Vertex dest(newwp.x, newwp.y, newwp.z);
|
|
||||||
|
|
||||||
float newz = zone->zonemap->FindBestZ(dest, nullptr);
|
this->CastToNPC()->SetGrid(grid); // Assign grid number
|
||||||
|
|
||||||
if( (newz > -2000) && ABS(newz-dest.z) < RuleR(Map, FixPathingZMaxDeltaLoading))
|
// Retrieve all waypoints for this grid
|
||||||
newwp.z = newz + 1;
|
query = StringFormat("SELECT `x`,`y`,`z`,`pause`,`heading` "
|
||||||
}
|
"FROM grid_entries WHERE `gridid` = %i AND `zoneid` = %i "
|
||||||
}
|
"ORDER BY `number`", grid, zone->GetZoneID());
|
||||||
|
results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
LogFile->write(EQEMuLog::Error, "MySQL Error while trying to assign waypoints from grid %u to mob %s: %s", grid, name, results.ErrorMessage().c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
roamer = true;
|
||||||
|
max_wp = 0; // Initialize it; will increment it for each waypoint successfully added to the list
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row, ++max_wp)
|
||||||
|
{
|
||||||
|
wplist newwp;
|
||||||
|
newwp.index = max_wp;
|
||||||
|
newwp.x = atof(row[0]);
|
||||||
|
newwp.y = atof(row[1]);
|
||||||
|
newwp.z = atof(row[2]);
|
||||||
|
|
||||||
|
if(zone->HasMap() && RuleB(Map, FixPathingZWhenLoading) )
|
||||||
|
{
|
||||||
|
if(!RuleB(Watermap, CheckWaypointsInWaterWhenLoading) || !zone->HasWaterMap() ||
|
||||||
|
(zone->HasWaterMap() && !zone->watermap->InWater(newwp.x, newwp.y, newwp.z)))
|
||||||
|
{
|
||||||
|
Map::Vertex dest(newwp.x, newwp.y, newwp.z);
|
||||||
|
|
||||||
|
float newz = zone->zonemap->FindBestZ(dest, nullptr);
|
||||||
|
|
||||||
|
if( (newz > -2000) && ABS(newz-dest.z) < RuleR(Map, FixPathingZMaxDeltaLoading))
|
||||||
|
newwp.z = newz + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newwp.pause = atoi(row[3]);
|
||||||
|
newwp.heading = atof(row[4]);
|
||||||
|
Waypoints.push_back(newwp);
|
||||||
|
}
|
||||||
|
|
||||||
newwp.pause = atoi(row[3]);
|
|
||||||
newwp.heading = atof(row[4]);
|
|
||||||
Waypoints.push_back(newwp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else // DB query error!
|
|
||||||
{
|
|
||||||
WPErr = true;
|
|
||||||
LogFile->write(EQEMuLog::Error, "MySQL Error while trying to assign waypoints from grid %u to mob %s: %s", grid, name, errbuf);
|
|
||||||
}
|
|
||||||
safe_delete_array(query);
|
|
||||||
} // end if (!GridErr)
|
|
||||||
if(Waypoints.size() < 2) {
|
if(Waypoints.size() < 2) {
|
||||||
roamer = false;
|
roamer = false;
|
||||||
} else if(!GridErr && !WPErr) {
|
|
||||||
UpdateWaypoint(0);
|
|
||||||
SetWaypointPause();
|
|
||||||
if (wandertype == 1 || wandertype == 2 || wandertype == 5)
|
|
||||||
CalculateNewWaypoint();
|
|
||||||
} else {
|
|
||||||
roamer = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateWaypoint(0);
|
||||||
|
SetWaypointPause();
|
||||||
|
|
||||||
|
if (wandertype == 1 || wandertype == 2 || wandertype == 5)
|
||||||
|
CalculateNewWaypoint();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::SendTo(float new_x, float new_y, float new_z) {
|
void Mob::SendTo(float new_x, float new_y, float new_z) {
|
||||||
@ -1049,159 +1030,123 @@ int ZoneDatabase::GetHighestGrid(uint32 zoneid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8 ZoneDatabase::GetGridType2(uint32 grid, uint16 zoneid) {
|
uint8 ZoneDatabase::GetGridType2(uint32 grid, uint16 zoneid) {
|
||||||
char *query = 0;
|
|
||||||
char errbuff[MYSQL_ERRMSG_SIZE];
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
int type2 = 0;
|
|
||||||
if (RunQuery(query, MakeAnyLenString(&query,"SELECT type2 from grid where id = %i and zoneid = %i",grid,zoneid),errbuff,&result)) {
|
|
||||||
safe_delete_array(query);
|
|
||||||
if (mysql_num_rows(result) == 1) {
|
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
type2 = atoi( row[0] );
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
} else {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in GetGridType2 query '%s': %s", query, errbuff);
|
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(type2);
|
int type2 = 0;
|
||||||
|
std::string query = StringFormat("SELECT type2 FROM grid WHERE id = %i AND zoneid = %i", grid, zoneid);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
LogFile->write(EQEMuLog::Error, "Error in GetGridType2 query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* wp) {
|
bool ZoneDatabase::GetWaypoints(uint32 grid, uint16 zoneid, uint32 num, wplist* wp) {
|
||||||
char *query = 0;
|
|
||||||
char errbuff[MYSQL_ERRMSG_SIZE];
|
if (wp == nullptr)
|
||||||
MYSQL_RES *result;
|
return false;
|
||||||
MYSQL_ROW row;
|
|
||||||
if (RunQuery(query, MakeAnyLenString(&query,"SELECT x, y, z, pause, heading from grid_entries where gridid = %i and number = %i and zoneid = %i",grid,num,zoneid),errbuff,&result)) {
|
std::string query = StringFormat("SELECT x, y, z, pause, heading FROM grid_entries "
|
||||||
safe_delete_array(query);
|
"WHERE gridid = %i AND number = %i AND zoneid = %i", grid, num, zoneid);
|
||||||
if (mysql_num_rows(result) == 1) {
|
auto results = QueryDatabase(query);
|
||||||
row = mysql_fetch_row(result);
|
if (!results.Success()) {
|
||||||
if ( wp ) {
|
LogFile->write(EQEMuLog::Error, "Error in GetWaypoints query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
wp->x = atof( row[0] );
|
return false;
|
||||||
wp->y = atof( row[1] );
|
}
|
||||||
wp->z = atof( row[2] );
|
|
||||||
wp->pause = atoi( row[3] );
|
if (results.RowCount() != 1)
|
||||||
wp->heading = atof( row[4] );
|
return false;
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
auto row = results.begin();
|
||||||
return true;
|
|
||||||
}
|
wp->x = atof(row[0]);
|
||||||
mysql_free_result(result);
|
wp->y = atof(row[1]);
|
||||||
}
|
wp->z = atof(row[2]);
|
||||||
else {
|
wp->pause = atoi(row[3]);
|
||||||
LogFile->write(EQEMuLog::Error, "Error in GetWaypoints query '%s': %s", query, errbuff);
|
wp->heading = atof(row[4]);
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid)
|
void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid)
|
||||||
{
|
{
|
||||||
char *query = 0;
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
int matches = 0, fuzzy = 0, spawn2id = 0;
|
int matches = 0, fuzzy = 0, spawn2id = 0;
|
||||||
uint32 affected_rows;
|
|
||||||
float dbx = 0, dby = 0;
|
float dbx = 0, dby = 0;
|
||||||
|
|
||||||
// looks like most of the stuff in spawn2 is straight integers
|
// looks like most of the stuff in spawn2 is straight integers
|
||||||
// so let's try that first
|
// so let's try that first
|
||||||
if(!RunQuery(
|
std::string query = StringFormat("SELECT id, x, y FROM spawn2 WHERE zone = '%s' AND x = %i AND y = %i",
|
||||||
query,
|
zone->GetShortName(), (int)x, (int)y);
|
||||||
MakeAnyLenString(
|
auto results = QueryDatabase(query);
|
||||||
&query,
|
if(!results.Success()) {
|
||||||
"SELECT id,x,y FROM spawn2 WHERE zone='%s' AND x=%i AND y=%i",
|
LogFile->write(EQEMuLog::Error, "Error querying spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||||
zone->GetShortName(), (int)x, (int)y
|
return;
|
||||||
),
|
|
||||||
errbuf,
|
|
||||||
&result
|
|
||||||
)) {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error querying spawn2 '%s': '%s'", query, errbuf);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
// how much it's allowed to be off by
|
// how much it's allowed to be off by
|
||||||
#define _GASSIGN_TOLERANCE 1.0
|
#define _GASSIGN_TOLERANCE 1.0
|
||||||
if(!(matches = mysql_num_rows(result))) // try a fuzzy match if that didn't find it
|
if(results.RowCount() == 0) // try a fuzzy match if that didn't find it
|
||||||
{
|
{
|
||||||
mysql_free_result(result);
|
query = StringFormat("SELECT id,x,y FROM spawn2 WHERE zone='%s' AND "
|
||||||
if(!RunQuery(
|
"ABS( ABS(x) - ABS(%f) ) < %f AND "
|
||||||
query,
|
"ABS( ABS(y) - ABS(%f) ) < %f",
|
||||||
MakeAnyLenString(
|
zone->GetShortName(), x, _GASSIGN_TOLERANCE, y, _GASSIGN_TOLERANCE);
|
||||||
&query,
|
results = QueryDatabase(query);
|
||||||
"SELECT id,x,y FROM spawn2 WHERE zone='%s' AND "
|
if(!results.Success()) {
|
||||||
"ABS( ABS(x) - ABS(%f) ) < %f AND "
|
LogFile->write(EQEMuLog::Error, "Error querying fuzzy spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||||
"ABS( ABS(y) - ABS(%f) ) < %f",
|
|
||||||
zone->GetShortName(), x, _GASSIGN_TOLERANCE, y, _GASSIGN_TOLERANCE
|
|
||||||
),
|
|
||||||
errbuf,
|
|
||||||
&result
|
|
||||||
)) {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error querying fuzzy spawn2 '%s': '%s'", query, errbuf);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
safe_delete_array(query);
|
|
||||||
fuzzy = 1;
|
fuzzy = 1;
|
||||||
if(!(matches = mysql_num_rows(result)))
|
matches = results.RowCount();
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
}
|
||||||
if(matches)
|
|
||||||
|
if (matches == 0) {
|
||||||
|
client->Message(0, "ERROR: Unable to assign grid - can't find it in spawn2");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(matches == 1)
|
||||||
{
|
{
|
||||||
if(matches > 1)
|
client->Message(0, "ERROR: Unable to assign grid - multiple spawn2 rows match");
|
||||||
{
|
return;
|
||||||
client->Message(0, "ERROR: Unable to assign grid - multiple spawn2 rows match");
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
spawn2id = atoi(row[0]);
|
|
||||||
dbx = atof(row[1]);
|
|
||||||
dby = atof(row[2]);
|
|
||||||
if(!RunQuery(
|
|
||||||
query,
|
|
||||||
MakeAnyLenString(
|
|
||||||
&query,
|
|
||||||
"UPDATE spawn2 SET pathgrid = %d WHERE id = %d", grid, spawn2id
|
|
||||||
),
|
|
||||||
errbuf,
|
|
||||||
&result,
|
|
||||||
&affected_rows
|
|
||||||
)) {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error updating spawn2 '%s': '%s'", query, errbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(affected_rows == 1)
|
|
||||||
{
|
|
||||||
if(client) client->LogSQL(query);
|
|
||||||
if(fuzzy)
|
|
||||||
{
|
|
||||||
float difference;
|
|
||||||
difference = sqrtf(pow(fabs(x-dbx),2) + pow(fabs(y-dby),2));
|
|
||||||
client->Message(0,
|
|
||||||
"Grid assign: spawn2 id = %d updated - fuzzy match: deviation %f",
|
|
||||||
spawn2id, difference
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
client->Message(0, "Grid assign: spawn2 id = %d updated - exact match", spawn2id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
client->Message(0, "ERROR: found spawn2 id %d but the update query failed", spawn2id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
spawn2id = atoi(row[0]);
|
||||||
|
dbx = atof(row[1]);
|
||||||
|
dby = atof(row[2]);
|
||||||
|
|
||||||
|
query = StringFormat("UPDATE spawn2 SET pathgrid = %d WHERE id = %d", grid, spawn2id);
|
||||||
|
results = QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
{
|
{
|
||||||
client->Message(0, "ERROR: Unable to assign grid - can't find it in spawn2");
|
LogFile->write(EQEMuLog::Error, "Error updating spawn2 '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.RowsAffected() != 1) {
|
||||||
|
client->Message(0, "ERROR: found spawn2 id %d but the update query failed", spawn2id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(client)
|
||||||
|
client->LogSQL(query.c_str());
|
||||||
|
|
||||||
|
if(!fuzzy) {
|
||||||
|
client->Message(0, "Grid assign: spawn2 id = %d updated - exact match", spawn2id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float difference = sqrtf(pow(fabs(x - dbx) , 2) + pow(fabs(y - dby), 2));
|
||||||
|
client->Message(0, "Grid assign: spawn2 id = %d updated - fuzzy match: deviation %f", spawn2id, difference);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************
|
/******************
|
||||||
@ -1211,53 +1156,57 @@ void ZoneDatabase::AssignGrid(Client *client, float x, float y, uint32 grid)
|
|||||||
* type,type2: The type and type2 values for the grid being created (ignored if grid is being deleted)
|
* type,type2: The type and type2 values for the grid being created (ignored if grid is being deleted)
|
||||||
* zoneid: The ID number of the zone the grid is being created/deleted in
|
* zoneid: The ID number of the zone the grid is being created/deleted in
|
||||||
*/
|
*/
|
||||||
|
void ZoneDatabase::ModifyGrid(Client *client, bool remove, uint32 id, uint8 type, uint8 type2, uint16 zoneid) {
|
||||||
|
|
||||||
void ZoneDatabase::ModifyGrid(Client *c, bool remove, uint32 id, uint8 type, uint8 type2, uint16 zoneid) {
|
|
||||||
char *query = 0;
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
if (!remove)
|
if (!remove)
|
||||||
{
|
{
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query,"INSERT INTO grid(id,zoneid,type,type2) VALUES(%i,%i,%i,%i)",id,zoneid,type,type2), errbuf)) {
|
std::string query = StringFormat("INSERT INTO grid(id, zoneid, type, type2) "
|
||||||
LogFile->write(EQEMuLog::Error, "Error creating grid entry '%s': '%s'", query, errbuf);
|
"VALUES (%i, %i, %i, %i)", id, zoneid, type, type2);
|
||||||
} else {
|
auto results = QueryDatabase(query);
|
||||||
if(c) c->LogSQL(query);
|
if (!results.Success()) {
|
||||||
}
|
LogFile->write(EQEMuLog::Error, "Error creating grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||||
safe_delete_array(query);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(client)
|
||||||
|
client->LogSQL(query.c_str());
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
std::string query = StringFormat("DELETE FROM grid where id=%i", id);
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query,"DELETE FROM grid where id=%i",id), errbuf)) {
|
auto results = QueryDatabase(query);
|
||||||
LogFile->write(EQEMuLog::Error, "Error deleting grid '%s': '%s'", query, errbuf);
|
if (!results.Success())
|
||||||
} else {
|
LogFile->write(EQEMuLog::Error, "Error deleting grid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||||
if(c) c->LogSQL(query);
|
else if(client)
|
||||||
}
|
client->LogSQL(query.c_str());
|
||||||
safe_delete_array(query);
|
|
||||||
query = 0;
|
query = StringFormat("DELETE FROM grid_entries WHERE zoneid = %i AND gridid = %i", zoneid, id);
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query,"DELETE FROM grid_entries WHERE zoneid=%i AND gridid=%i",zoneid,id), errbuf)) {
|
results = QueryDatabase(query);
|
||||||
LogFile->write(EQEMuLog::Error, "Error deleting grid entries '%s': '%s'", query, errbuf);
|
if(!results.Success())
|
||||||
} else {
|
LogFile->write(EQEMuLog::Error, "Error deleting grid entries '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||||
if(c) c->LogSQL(query);
|
else if(client)
|
||||||
}
|
client->LogSQL(query.c_str());
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
} /*** END ZoneDatabase::ModifyGrid() ***/
|
|
||||||
|
|
||||||
/**************************************
|
/**************************************
|
||||||
* AddWP - Adds a new waypoint to a specific grid for a specific zone.
|
* AddWP - Adds a new waypoint to a specific grid for a specific zone.
|
||||||
*/
|
*/
|
||||||
|
void ZoneDatabase::AddWP(Client *client, uint32 gridid, uint32 wpnum, float xpos, float ypos, float zpos, uint32 pause, uint16 zoneid, float heading)
|
||||||
void ZoneDatabase::AddWP(Client *c, uint32 gridid, uint32 wpnum, float xpos, float ypos, float zpos, uint32 pause, uint16 zoneid, float heading)
|
|
||||||
{
|
{
|
||||||
char *query = 0;
|
std::string query = StringFormat("INSERT INTO grid_entries (gridid, zoneid, `number`, x, y, z, pause, heading) "
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
"VALUES (%i, %i, %i, %f, %f, %f, %i, %f)",
|
||||||
|
gridid, zoneid, wpnum, xpos, ypos, zpos, pause, heading);
|
||||||
if(!RunQuery(query,MakeAnyLenString(&query,"INSERT INTO grid_entries (gridid,zoneid,`number`,x,y,z,pause,heading) values (%i,%i,%i,%f,%f,%f,%i,%f)",gridid,zoneid,wpnum,xpos,ypos,zpos,pause,heading), errbuf)) {
|
auto results = QueryDatabase(query);
|
||||||
LogFile->write(EQEMuLog::Error, "Error adding waypoint '%s': '%s'", query, errbuf);
|
if (!results.Success()) {
|
||||||
} else {
|
LogFile->write(EQEMuLog::Error, "Error adding waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||||
if(c) c->LogSQL(query);
|
return;
|
||||||
}
|
}
|
||||||
safe_delete_array(query);
|
|
||||||
} /*** END ZoneDatabase::AddWP() ***/
|
if(client)
|
||||||
|
client->LogSQL(query.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********
|
/**********
|
||||||
@ -1270,19 +1219,20 @@ void ZoneDatabase::AddWP(Client *c, uint32 gridid, uint32 wpnum, float xpos, flo
|
|||||||
* wp_num: The number of the waypoint being deleted
|
* wp_num: The number of the waypoint being deleted
|
||||||
* zoneid: The ID number of the zone that contains the waypoint being deleted
|
* zoneid: The ID number of the zone that contains the waypoint being deleted
|
||||||
*/
|
*/
|
||||||
|
void ZoneDatabase::DeleteWaypoint(Client *client, uint32 grid_num, uint32 wp_num, uint16 zoneid)
|
||||||
void ZoneDatabase::DeleteWaypoint(Client *c, uint32 grid_num, uint32 wp_num, uint16 zoneid)
|
|
||||||
{
|
{
|
||||||
char *query=0;
|
std::string query = StringFormat("DELETE FROM grid_entries WHERE "
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
"gridid = %i AND zoneid = %i AND `number` = %i",
|
||||||
|
grid_num, zoneid, wp_num);
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query,"DELETE FROM grid_entries where gridid=%i and zoneid=%i and `number`=%i",grid_num,zoneid,wp_num), errbuf)) {
|
auto results = QueryDatabase(query);
|
||||||
LogFile->write(EQEMuLog::Error, "Error deleting waypoint '%s': '%s'", query, errbuf);
|
if(!results.Success()) {
|
||||||
} else {
|
LogFile->write(EQEMuLog::Error, "Error deleting waypoint '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||||
if(c) c->LogSQL(query);
|
return;
|
||||||
}
|
}
|
||||||
safe_delete_array(query);
|
|
||||||
} /*** END ZoneDatabase::DeleteWaypoint() ***/
|
if(client)
|
||||||
|
client->LogSQL(query.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************
|
/******************
|
||||||
@ -1292,139 +1242,112 @@ void ZoneDatabase::DeleteWaypoint(Client *c, uint32 grid_num, uint32 wp_num, uin
|
|||||||
* Returns 0 if the function didn't have to create a new grid. If the function had to create a new grid for the spawn, then the ID of
|
* Returns 0 if the function didn't have to create a new grid. If the function had to create a new grid for the spawn, then the ID of
|
||||||
* the created grid is returned.
|
* the created grid is returned.
|
||||||
*/
|
*/
|
||||||
|
uint32 ZoneDatabase::AddWPForSpawn(Client *client, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading) {
|
||||||
|
|
||||||
uint32 ZoneDatabase::AddWPForSpawn(Client *c, uint32 spawn2id, float xpos, float ypos, float zpos, uint32 pause, int type1, int type2, uint16 zoneid, float heading) {
|
uint32 grid_num; // The grid number the spawn is assigned to (if spawn has no grid, will be the grid number we end up creating)
|
||||||
char *query = 0;
|
uint32 next_wp_num; // The waypoint number we should be assigning to the new waypoint
|
||||||
uint32 grid_num, // The grid number the spawn is assigned to (if spawn has no grid, will be the grid number we end up creating)
|
bool createdNewGrid; // Did we create a new grid in this function?
|
||||||
next_wp_num; // The waypoint number we should be assigning to the new waypoint
|
|
||||||
bool CreatedNewGrid; // Did we create a new grid in this function?
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
|
|
||||||
// See what grid number our spawn is assigned
|
// See what grid number our spawn is assigned
|
||||||
if(RunQuery(query, MakeAnyLenString(&query,"SELECT pathgrid FROM spawn2 WHERE id=%i",spawn2id),errbuf,&result))
|
std::string query = StringFormat("SELECT pathgrid FROM spawn2 WHERE id = %i", spawn2id);
|
||||||
{
|
auto results = QueryDatabase(query);
|
||||||
safe_delete_array(query);
|
if (!results.Success()) {
|
||||||
if(mysql_num_rows(result) > 0)
|
// Query error
|
||||||
{
|
LogFile->write(EQEMuLog::Error, "Error setting pathgrid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
grid_num = atoi(row[0]);
|
|
||||||
}
|
|
||||||
else // This spawn ID was not found in the `spawn2` table
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else { // Query error
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error setting pathgrid '%s': '%s'", query, errbuf);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grid_num == 0) // Our spawn doesn't have a grid assigned to it -- we need to create a new grid and assign it to the spawn
|
if (results.RowCount() == 0)
|
||||||
{
|
return 0;
|
||||||
CreatedNewGrid = true;
|
|
||||||
if((grid_num = GetFreeGrid(zoneid)) == 0) // There are no grids for the current zone -- create Grid #1
|
|
||||||
grid_num = 1;
|
|
||||||
|
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query,"insert into grid set id='%i',zoneid= %i, type='%i', type2='%i'",grid_num,zoneid,type1,type2), errbuf)) {
|
auto row = results.begin();
|
||||||
LogFile->write(EQEMuLog::Error, "Error adding grid '%s': '%s'", query, errbuf);
|
grid_num = atoi(row[0]);
|
||||||
} else {
|
|
||||||
if(c) c->LogSQL(query);
|
|
||||||
}
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
query = 0;
|
if (grid_num == 0)
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query,"update spawn2 set pathgrid='%i' where id='%i'",grid_num,spawn2id), errbuf)) {
|
{ // Our spawn doesn't have a grid assigned to it -- we need to create a new grid and assign it to the spawn
|
||||||
LogFile->write(EQEMuLog::Error, "Error updating spawn2 pathing '%s': '%s'", query, errbuf);
|
createdNewGrid = true;
|
||||||
} else {
|
grid_num = GetFreeGrid(zoneid);
|
||||||
if(c) c->LogSQL(query);
|
if(grid_num == 0) // There are no grids for the current zone -- create Grid #1
|
||||||
}
|
grid_num = 1;
|
||||||
safe_delete_array(query);
|
|
||||||
|
query = StringFormat("INSERT INTO grid SET id = '%i', zoneid = %i, type ='%i', type2 = '%i'",
|
||||||
|
grid_num, zoneid, type1, type2);
|
||||||
|
results = QueryDatabase(query);
|
||||||
|
if(!results.Success())
|
||||||
|
LogFile->write(EQEMuLog::Error, "Error adding grid '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
else if(client)
|
||||||
|
client->LogSQL(query.c_str());
|
||||||
|
|
||||||
|
query = StringFormat("UPDATE spawn2 SET pathgrid = '%i' WHERE id = '%i'", grid_num, spawn2id);
|
||||||
|
results = QueryDatabase(query);
|
||||||
|
if(!results.Success())
|
||||||
|
LogFile->write(EQEMuLog::Error, "Error updating spawn2 pathing '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
else if(client)
|
||||||
|
client->LogSQL(query.c_str());
|
||||||
}
|
}
|
||||||
else // NPC had a grid assigned to it
|
else // NPC had a grid assigned to it
|
||||||
CreatedNewGrid = false;
|
createdNewGrid = false;
|
||||||
|
|
||||||
|
|
||||||
// Find out what the next waypoint is for this grid
|
// Find out what the next waypoint is for this grid
|
||||||
query = 0;
|
query = StringFormat("SELECT max(`number`) FROM grid_entries WHERE zoneid = '%i' AND gridid = '%i'", zoneid, grid_num);
|
||||||
if(RunQuery(query, MakeAnyLenString(&query,"SELECT max(`number`) FROM grid_entries WHERE zoneid='%i' AND gridid='%i'",zoneid,grid_num),errbuf,&result))
|
|
||||||
{
|
|
||||||
safe_delete_array(query);
|
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
if(row[0] != 0)
|
|
||||||
next_wp_num = atoi(row[0]) + 1;
|
|
||||||
else // No waypoints in this grid yet
|
|
||||||
next_wp_num = 1;
|
|
||||||
|
|
||||||
mysql_free_result(result);
|
if(!results.Success()) { // Query error
|
||||||
}
|
LogFile->write(EQEMuLog::Error, "Error getting next waypoint id '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||||
else { // Query error
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error getting next waypoint id '%s': '%s'", query, errbuf);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
query = 0;
|
row = results.begin();
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query,"INSERT INTO grid_entries(gridid,zoneid,`number`,x,y,z,pause,heading) VALUES (%i,%i,%i,%f,%f,%f,%i,%f)",grid_num,zoneid,next_wp_num,xpos,ypos,zpos,pause,heading), errbuf)) {
|
if(row[0] != 0)
|
||||||
LogFile->write(EQEMuLog::Error, "Error adding grid entry '%s': '%s'", query, errbuf);
|
next_wp_num = atoi(row[0]) + 1;
|
||||||
} else {
|
else // No waypoints in this grid yet
|
||||||
if(c) c->LogSQL(query);
|
next_wp_num = 1;
|
||||||
}
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
if(CreatedNewGrid)
|
query = StringFormat("INSERT INTO grid_entries(gridid, zoneid, `number`, x, y, z, pause, heading) "
|
||||||
return grid_num;
|
"VALUES (%i, %i, %i, %f, %f, %f, %i, %f)",
|
||||||
|
grid_num, zoneid, next_wp_num, xpos, ypos, zpos, pause, heading);
|
||||||
return 0;
|
results = QueryDatabase(query);
|
||||||
} /*** END ZoneDatabase::AddWPForSpawn() ***/
|
if(!results.Success())
|
||||||
|
LogFile->write(EQEMuLog::Error, "Error adding grid entry '%s': '%s'", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
else if(client)
|
||||||
|
client->LogSQL(query.c_str());
|
||||||
|
|
||||||
|
return createdNewGrid? grid_num: 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint32 ZoneDatabase::GetFreeGrid(uint16 zoneid) {
|
uint32 ZoneDatabase::GetFreeGrid(uint16 zoneid) {
|
||||||
char *query = 0;
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
std::string query = StringFormat("SELECT max(id) FROM grid WHERE zoneid = %i", zoneid);
|
||||||
MYSQL_RES *result;
|
auto results = QueryDatabase(query);
|
||||||
MYSQL_ROW row;
|
if (!results.Success()) {
|
||||||
if (RunQuery(query, MakeAnyLenString(&query,"SELECT max(id) from grid where zoneid = %i",zoneid),errbuf,&result)) {
|
LogFile->write(EQEMuLog::Error, "Error in GetFreeGrid query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
safe_delete_array(query);
|
return 0;
|
||||||
if (mysql_num_rows(result) == 1) {
|
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
uint32 tmp=0;
|
|
||||||
if (row[0])
|
|
||||||
tmp = atoi(row[0]);
|
|
||||||
mysql_free_result(result);
|
|
||||||
tmp++;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in GetFreeGrid query '%s': %s", query, errbuf);
|
if (results.RowCount() != 1)
|
||||||
safe_delete_array(query);
|
return 0;
|
||||||
}
|
|
||||||
return 0;
|
auto row = results.begin();
|
||||||
|
uint32 freeGridID = 1;
|
||||||
|
freeGridID = atoi(row[0]) + 1;
|
||||||
|
|
||||||
|
return freeGridID;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZoneDatabase::GetHighestWaypoint(uint32 zoneid, uint32 gridid) {
|
int ZoneDatabase::GetHighestWaypoint(uint32 zoneid, uint32 gridid) {
|
||||||
char *query = 0;
|
|
||||||
char errbuff[MYSQL_ERRMSG_SIZE];
|
std::string query = StringFormat("SELECT COALESCE(MAX(number), 0) FROM grid_entries "
|
||||||
MYSQL_RES *result;
|
"WHERE zoneid = %i AND gridid = %i", zoneid, gridid);
|
||||||
MYSQL_ROW row;
|
auto results = QueryDatabase(query);
|
||||||
int res = 0;
|
if (!results.Success()) {
|
||||||
if (RunQuery(query, MakeAnyLenString(&query,
|
LogFile->write(EQEMuLog::Error, "Error in GetHighestWaypoint query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
"SELECT COALESCE(MAX(number), 0) FROM grid_entries WHERE zoneid = %i AND gridid = %i",
|
return 0;
|
||||||
zoneid, gridid),errbuff,&result)) {
|
|
||||||
safe_delete_array(query);
|
|
||||||
if (mysql_num_rows(result) == 1) {
|
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
res = atoi( row[0] );
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
} else {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in GetHighestWaypoint query '%s': %s", query, errbuff);
|
|
||||||
safe_delete_array(query);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(res);
|
if (results.RowCount() != 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
return atoi(row[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPC::SaveGuardSpotCharm()
|
void NPC::SaveGuardSpotCharm()
|
||||||
|
|||||||
@ -718,11 +718,24 @@ void Zone::DBAWComplete(uint8 workpt_b1, DBAsyncWork* dbaw) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Zone::IsLoaded() {
|
||||||
|
return ZoneLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
void Zone::Shutdown(bool quite)
|
void Zone::Shutdown(bool quite)
|
||||||
{
|
{
|
||||||
if (!ZoneLoaded)
|
if (!ZoneLoaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
std::list<Mob*> mob_list;
|
||||||
|
entity_list.GetMobList(mob_list);
|
||||||
|
std::list<Mob*>::iterator mob_itr = mob_list.begin();
|
||||||
|
while (mob_itr != mob_list.end()) {
|
||||||
|
Mob* mob_inst = *mob_itr;
|
||||||
|
mob_inst->AI_Stop();
|
||||||
|
++mob_itr;
|
||||||
|
}
|
||||||
|
|
||||||
std::map<uint32,NPCType *>::iterator itr;
|
std::map<uint32,NPCType *>::iterator itr;
|
||||||
while(zone->npctable.size()) {
|
while(zone->npctable.size()) {
|
||||||
itr=zone->npctable.begin();
|
itr=zone->npctable.begin();
|
||||||
@ -1678,45 +1691,41 @@ ZonePoint* Zone::GetClosestZonePointWithoutZone(float x, float y, float z, Clien
|
|||||||
|
|
||||||
bool ZoneDatabase::LoadStaticZonePoints(LinkedList<ZonePoint*>* zone_point_list, const char* zonename, uint32 version)
|
bool ZoneDatabase::LoadStaticZonePoints(LinkedList<ZonePoint*>* zone_point_list, const char* zonename, uint32 version)
|
||||||
{
|
{
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char *query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
zone_point_list->Clear();
|
zone_point_list->Clear();
|
||||||
zone->numzonepoints = 0;
|
zone->numzonepoints = 0;
|
||||||
MakeAnyLenString(&query, "SELECT x, y, z, target_x, target_y, "
|
std::string query = StringFormat("SELECT x, y, z, target_x, target_y, "
|
||||||
"target_z, target_zone_id, heading, target_heading, number, "
|
"target_z, target_zone_id, heading, target_heading, "
|
||||||
"target_instance, client_version_mask FROM zone_points "
|
"number, target_instance, client_version_mask "
|
||||||
"WHERE zone='%s' AND (version=%i OR version=-1) order by number", zonename, version);
|
"FROM zone_points WHERE zone='%s' AND (version=%i OR version=-1) "
|
||||||
if (RunQuery(query, strlen(query), errbuf, &result))
|
"ORDER BY number", zonename, version);
|
||||||
{
|
auto results = QueryDatabase(query);
|
||||||
safe_delete_array(query);
|
if (!results.Success()) {
|
||||||
while((row = mysql_fetch_row(result)))
|
std::cerr << "Error1 in LoadStaticZonePoints query '" << query << "' " << results.ErrorMessage() << std::endl;
|
||||||
{
|
|
||||||
ZonePoint* zp = new ZonePoint;
|
|
||||||
zp->x = atof(row[0]);
|
|
||||||
zp->y = atof(row[1]);
|
|
||||||
zp->z = atof(row[2]);
|
|
||||||
zp->target_x = atof(row[3]);
|
|
||||||
zp->target_y = atof(row[4]);
|
|
||||||
zp->target_z = atof(row[5]);
|
|
||||||
zp->target_zone_id = atoi(row[6]);
|
|
||||||
zp->heading = atof(row[7]);
|
|
||||||
zp->target_heading = atof(row[8]);
|
|
||||||
zp->number = atoi(row[9]);
|
|
||||||
zp->target_zone_instance = atoi(row[10]);
|
|
||||||
zp->client_version_mask = (uint32)strtoul(row[11], nullptr, 0);
|
|
||||||
zone_point_list->Insert(zp);
|
|
||||||
zone->numzonepoints++;
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "Error1 in LoadStaticZonePoints query '" << query << "' " << errbuf << std::endl;
|
|
||||||
safe_delete_array(query);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
ZonePoint* zp = new ZonePoint;
|
||||||
|
|
||||||
|
zp->x = atof(row[0]);
|
||||||
|
zp->y = atof(row[1]);
|
||||||
|
zp->z = atof(row[2]);
|
||||||
|
zp->target_x = atof(row[3]);
|
||||||
|
zp->target_y = atof(row[4]);
|
||||||
|
zp->target_z = atof(row[5]);
|
||||||
|
zp->target_zone_id = atoi(row[6]);
|
||||||
|
zp->heading = atof(row[7]);
|
||||||
|
zp->target_heading = atof(row[8]);
|
||||||
|
zp->number = atoi(row[9]);
|
||||||
|
zp->target_zone_instance = atoi(row[10]);
|
||||||
|
zp->client_version_mask = (uint32)strtoul(row[11], nullptr, 0);
|
||||||
|
|
||||||
|
zone_point_list->Insert(zp);
|
||||||
|
|
||||||
|
zone->numzonepoints++;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3226,3 +3226,11 @@ bool ZoneDatabase::GetFactionIdsForNPC(uint32 nfl_id, std::list<struct NPCFactio
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZoneDatabase::StoreCharacterLookup(uint32 char_id) {
|
||||||
|
std::string c_lookup = StringFormat("REPLACE INTO `character_lookup` (id, account_id, `name`, timelaston, x, y, z, zonename, zoneid, instanceid, pktime, groupid, class, `level`, lfp, lfg, mailkey, xtargets, firstlogon, inspectmessage)"
|
||||||
|
" SELECT id, account_id, `name`, timelaston, x, y, z, zonename, zoneid, instanceid, pktime, groupid, class, `level`, lfp, lfg, mailkey, xtargets, firstlogon, inspectmessage"
|
||||||
|
" FROM `character_` "
|
||||||
|
" WHERE `id` = %i ", char_id);
|
||||||
|
QueryDatabase(c_lookup);
|
||||||
|
}
|
||||||
@ -246,6 +246,7 @@ public:
|
|||||||
/*
|
/*
|
||||||
* General Character Related Stuff
|
* General Character Related Stuff
|
||||||
*/
|
*/
|
||||||
|
void StoreCharacterLookup(uint32 char_id);
|
||||||
bool SetServerFilters(char* name, ServerSideFilters_Struct *ssfs);
|
bool SetServerFilters(char* name, ServerSideFilters_Struct *ssfs);
|
||||||
uint32 GetServerFilters(char* name, ServerSideFilters_Struct *ssfs);
|
uint32 GetServerFilters(char* name, ServerSideFilters_Struct *ssfs);
|
||||||
bool GetAccountInfoForLogin(uint32 account_id, int16* admin = 0, char* account_name = 0,
|
bool GetAccountInfoForLogin(uint32 account_id, int16* admin = 0, char* account_name = 0,
|
||||||
|
|||||||
@ -25,7 +25,9 @@
|
|||||||
#include "../common/string_util.h"
|
#include "../common/string_util.h"
|
||||||
#include "string_ids.h"
|
#include "string_ids.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
extern Zone* zone;
|
extern Zone* zone;
|
||||||
|
|
||||||
@ -147,7 +149,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//make sure its a valid zone.
|
/* Check for Valid Zone */
|
||||||
const char *target_zone_name = database.GetZoneName(target_zone_id);
|
const char *target_zone_name = database.GetZoneName(target_zone_id);
|
||||||
if(target_zone_name == nullptr) {
|
if(target_zone_name == nullptr) {
|
||||||
//invalid zone...
|
//invalid zone...
|
||||||
@ -157,7 +159,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//load up the safe coords, restrictions, and verify the zone name
|
/* Load up the Safe Coordinates, restrictions and verify the zone name*/
|
||||||
float safe_x, safe_y, safe_z;
|
float safe_x, safe_y, safe_z;
|
||||||
int16 minstatus = 0;
|
int16 minstatus = 0;
|
||||||
uint8 minlevel = 0;
|
uint8 minlevel = 0;
|
||||||
@ -327,15 +329,19 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc
|
|||||||
|
|
||||||
SendLogoutPackets();
|
SendLogoutPackets();
|
||||||
|
|
||||||
//dont clear aggro until the zone is successful
|
/* QS: PlayerLogZone */
|
||||||
|
if (RuleB(QueryServ, PlayerLogZone)){
|
||||||
|
std::string event_desc = StringFormat("Zoning :: zoneid:%u instid:%u x:%4.2f y:%4.2f z:%4.2f h:%4.2f zonemode:%d from zoneid:%u instid:%i", zone_id, instance_id, dest_x, dest_y, dest_z, dest_h, zone_mode, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Zoning, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dont clear aggro until the zone is successful */
|
||||||
entity_list.RemoveFromHateLists(this);
|
entity_list.RemoveFromHateLists(this);
|
||||||
|
|
||||||
if(this->GetPet())
|
if(this->GetPet())
|
||||||
entity_list.RemoveFromHateLists(this->GetPet());
|
entity_list.RemoveFromHateLists(this->GetPet());
|
||||||
|
|
||||||
LogFile->write(EQEMuLog::Status, "Zoning '%s' to: %s (%i) - (%i) x=%f, y=%f, z=%f",
|
LogFile->write(EQEMuLog::Status, "Zoning '%s' to: %s (%i) - (%i) x=%f, y=%f, z=%f", m_pp.name, database.GetZoneName(zone_id), zone_id, instance_id, dest_x, dest_y, dest_z);
|
||||||
m_pp.name, database.GetZoneName(zone_id), zone_id, instance_id,
|
|
||||||
dest_x, dest_y, dest_z);
|
|
||||||
|
|
||||||
//set the player's coordinates in the new zone so they have them
|
//set the player's coordinates in the new zone so they have them
|
||||||
//when they zone into it
|
//when they zone into it
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user