character properties not hard coded are now dynamically fed into the info struct string, we can now SetInfoStruct(Player, "somevar", "avalue") and it will save to the DB to persist cross zone with GetInfoStruct(Player, "somevar")
This commit is contained in:
parent
05f5061c19
commit
fae7cf7773
@ -32,6 +32,7 @@
|
|||||||
#include "Skills.h"
|
#include "Skills.h"
|
||||||
#include "Rules/Rules.h"
|
#include "Rules/Rules.h"
|
||||||
#include "LuaInterface.h"
|
#include "LuaInterface.h"
|
||||||
|
#include "WorldDatabase.h"
|
||||||
|
|
||||||
extern World world;
|
extern World world;
|
||||||
extern MasterItemList master_item_list;
|
extern MasterItemList master_item_list;
|
||||||
@ -40,6 +41,7 @@ extern MasterSkillList master_skill_list;
|
|||||||
extern RuleManager rule_manager;
|
extern RuleManager rule_manager;
|
||||||
extern Classes classes;
|
extern Classes classes;
|
||||||
extern LuaInterface* lua_interface;
|
extern LuaInterface* lua_interface;
|
||||||
|
extern WorldDatabase database;
|
||||||
|
|
||||||
Entity::Entity(){
|
Entity::Entity(){
|
||||||
MapInfoStruct();
|
MapInfoStruct();
|
||||||
@ -616,6 +618,65 @@ void Entity::MapInfoStruct()
|
|||||||
set_float_funcs["max_chase_distance"] = l::bind(&InfoStruct::set_max_chase_distance, &info_struct, l::_1);
|
set_float_funcs["max_chase_distance"] = l::bind(&InfoStruct::set_max_chase_distance, &info_struct, l::_1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Entity::RegisterProperty(const std::string& name) {
|
||||||
|
int32 charID = 0;
|
||||||
|
|
||||||
|
if(IsPlayer())
|
||||||
|
charID = ((Player*)this)->GetCharacterID();
|
||||||
|
|
||||||
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
|
if (set_string_funcs.find(name) != set_string_funcs.end() ||
|
||||||
|
get_string_funcs.find(name) != get_string_funcs.end())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::unique_lock<std::shared_mutex> wlock(propertiesMutex);
|
||||||
|
if (set_string_funcs.find(name) != set_string_funcs.end() ||
|
||||||
|
get_string_funcs.find(name) != get_string_funcs.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
set_string_funcs.emplace(name, [this, name, database, charID](std::string v) {
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(GetInfoStruct()->classMutex);
|
||||||
|
GetInfoStruct()->props[name] = v;
|
||||||
|
}
|
||||||
|
if(charID)
|
||||||
|
database.insertCharacterProperty(charID, const_cast<char*>(name.c_str()), const_cast<char*>(v.c_str()));
|
||||||
|
});
|
||||||
|
|
||||||
|
get_string_funcs.emplace(name, [this, name]() -> std::string {
|
||||||
|
std::lock_guard<std::mutex> lk(GetInfoStruct()->classMutex);
|
||||||
|
auto it = GetInfoStruct()->props.find(name);
|
||||||
|
return (it == GetInfoStruct()->props.end()) ? std::string{} : it->second;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::SetProperty(const std::string& name, const std::string& value) {
|
||||||
|
auto it = set_string_funcs.find(name);
|
||||||
|
if (it == set_string_funcs.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 charID = 0;
|
||||||
|
|
||||||
|
if(IsPlayer())
|
||||||
|
charID = ((Player*)this)->GetCharacterID();
|
||||||
|
|
||||||
|
if(charID)
|
||||||
|
database.insertCharacterProperty(charID, const_cast<char*>(name.c_str()), const_cast<char*>(value.c_str()));
|
||||||
|
|
||||||
|
return it->second(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::string> Entity::GetProperty(const std::string& name) const {
|
||||||
|
auto it = get_string_funcs.find(name);
|
||||||
|
if (it == get_string_funcs.end()) return std::nullopt;
|
||||||
|
return it->second();
|
||||||
|
}
|
||||||
|
|
||||||
bool Entity::HasMoved(bool include_heading){
|
bool Entity::HasMoved(bool include_heading){
|
||||||
if(GetX() == last_x && GetY() == last_y && GetZ() == last_z && ((!include_heading) || (include_heading && GetHeading() == last_heading)))
|
if(GetX() == last_x && GetY() == last_y && GetZ() == last_z && ((!include_heading) || (include_heading && GetHeading() == last_heading)))
|
||||||
return false;
|
return false;
|
||||||
@ -3780,6 +3841,7 @@ void Entity::HaltMovement()
|
|||||||
|
|
||||||
std::string Entity::GetInfoStructString(std::string field)
|
std::string Entity::GetInfoStructString(std::string field)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<std::string()>>::const_iterator itr = get_string_funcs.find(field);
|
map<string, boost::function<std::string()>>::const_iterator itr = get_string_funcs.find(field);
|
||||||
if(itr != get_string_funcs.end())
|
if(itr != get_string_funcs.end())
|
||||||
{
|
{
|
||||||
@ -3791,6 +3853,7 @@ std::string Entity::GetInfoStructString(std::string field)
|
|||||||
|
|
||||||
int8 Entity::GetInfoStructInt8(std::string field)
|
int8 Entity::GetInfoStructInt8(std::string field)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<int8()>>::const_iterator itr = get_int8_funcs.find(field);
|
map<string, boost::function<int8()>>::const_iterator itr = get_int8_funcs.find(field);
|
||||||
if(itr != get_int8_funcs.end())
|
if(itr != get_int8_funcs.end())
|
||||||
{
|
{
|
||||||
@ -3802,6 +3865,7 @@ int8 Entity::GetInfoStructInt8(std::string field)
|
|||||||
|
|
||||||
int16 Entity::GetInfoStructInt16(std::string field)
|
int16 Entity::GetInfoStructInt16(std::string field)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<int16()>>::const_iterator itr = get_int16_funcs.find(field);
|
map<string, boost::function<int16()>>::const_iterator itr = get_int16_funcs.find(field);
|
||||||
if(itr != get_int16_funcs.end())
|
if(itr != get_int16_funcs.end())
|
||||||
{
|
{
|
||||||
@ -3813,6 +3877,7 @@ int16 Entity::GetInfoStructInt16(std::string field)
|
|||||||
|
|
||||||
int32 Entity::GetInfoStructInt32(std::string field)
|
int32 Entity::GetInfoStructInt32(std::string field)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<int32()>>::const_iterator itr = get_int32_funcs.find(field);
|
map<string, boost::function<int32()>>::const_iterator itr = get_int32_funcs.find(field);
|
||||||
if(itr != get_int32_funcs.end())
|
if(itr != get_int32_funcs.end())
|
||||||
{
|
{
|
||||||
@ -3824,6 +3889,7 @@ int32 Entity::GetInfoStructInt32(std::string field)
|
|||||||
|
|
||||||
int64 Entity::GetInfoStructInt64(std::string field)
|
int64 Entity::GetInfoStructInt64(std::string field)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<int64()>>::const_iterator itr = get_int64_funcs.find(field);
|
map<string, boost::function<int64()>>::const_iterator itr = get_int64_funcs.find(field);
|
||||||
if(itr != get_int64_funcs.end())
|
if(itr != get_int64_funcs.end())
|
||||||
{
|
{
|
||||||
@ -3835,6 +3901,7 @@ int64 Entity::GetInfoStructInt64(std::string field)
|
|||||||
|
|
||||||
sint8 Entity::GetInfoStructSInt8(std::string field)
|
sint8 Entity::GetInfoStructSInt8(std::string field)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<sint8()>>::const_iterator itr = get_sint8_funcs.find(field);
|
map<string, boost::function<sint8()>>::const_iterator itr = get_sint8_funcs.find(field);
|
||||||
if(itr != get_sint8_funcs.end())
|
if(itr != get_sint8_funcs.end())
|
||||||
{
|
{
|
||||||
@ -3846,6 +3913,7 @@ sint8 Entity::GetInfoStructSInt8(std::string field)
|
|||||||
|
|
||||||
sint16 Entity::GetInfoStructSInt16(std::string field)
|
sint16 Entity::GetInfoStructSInt16(std::string field)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<sint16()>>::const_iterator itr = get_sint16_funcs.find(field);
|
map<string, boost::function<sint16()>>::const_iterator itr = get_sint16_funcs.find(field);
|
||||||
if(itr != get_sint16_funcs.end())
|
if(itr != get_sint16_funcs.end())
|
||||||
{
|
{
|
||||||
@ -3857,6 +3925,7 @@ sint16 Entity::GetInfoStructSInt16(std::string field)
|
|||||||
|
|
||||||
sint32 Entity::GetInfoStructSInt32(std::string field)
|
sint32 Entity::GetInfoStructSInt32(std::string field)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<sint32()>>::const_iterator itr = get_sint32_funcs.find(field);
|
map<string, boost::function<sint32()>>::const_iterator itr = get_sint32_funcs.find(field);
|
||||||
if(itr != get_sint32_funcs.end())
|
if(itr != get_sint32_funcs.end())
|
||||||
{
|
{
|
||||||
@ -3868,6 +3937,7 @@ sint32 Entity::GetInfoStructSInt32(std::string field)
|
|||||||
|
|
||||||
sint64 Entity::GetInfoStructSInt64(std::string field)
|
sint64 Entity::GetInfoStructSInt64(std::string field)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<sint64()>>::const_iterator itr = get_sint64_funcs.find(field);
|
map<string, boost::function<sint64()>>::const_iterator itr = get_sint64_funcs.find(field);
|
||||||
if(itr != get_sint64_funcs.end())
|
if(itr != get_sint64_funcs.end())
|
||||||
{
|
{
|
||||||
@ -3879,6 +3949,7 @@ sint64 Entity::GetInfoStructSInt64(std::string field)
|
|||||||
|
|
||||||
float Entity::GetInfoStructFloat(std::string field)
|
float Entity::GetInfoStructFloat(std::string field)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<float()>>::const_iterator itr = get_float_funcs.find(field);
|
map<string, boost::function<float()>>::const_iterator itr = get_float_funcs.find(field);
|
||||||
if(itr != get_float_funcs.end())
|
if(itr != get_float_funcs.end())
|
||||||
{
|
{
|
||||||
@ -3890,6 +3961,7 @@ float Entity::GetInfoStructFloat(std::string field)
|
|||||||
|
|
||||||
int64 Entity::GetInfoStructUInt(std::string field)
|
int64 Entity::GetInfoStructUInt(std::string field)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<int8()>>::const_iterator itr = get_int8_funcs.find(field);
|
map<string, boost::function<int8()>>::const_iterator itr = get_int8_funcs.find(field);
|
||||||
if(itr != get_int8_funcs.end())
|
if(itr != get_int8_funcs.end())
|
||||||
{
|
{
|
||||||
@ -3919,6 +3991,7 @@ int64 Entity::GetInfoStructUInt(std::string field)
|
|||||||
|
|
||||||
sint64 Entity::GetInfoStructSInt(std::string field)
|
sint64 Entity::GetInfoStructSInt(std::string field)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<sint8()>>::const_iterator itr = get_sint8_funcs.find(field);
|
map<string, boost::function<sint8()>>::const_iterator itr = get_sint8_funcs.find(field);
|
||||||
if(itr != get_sint8_funcs.end())
|
if(itr != get_sint8_funcs.end())
|
||||||
{
|
{
|
||||||
@ -3949,18 +4022,24 @@ sint64 Entity::GetInfoStructSInt(std::string field)
|
|||||||
|
|
||||||
bool Entity::SetInfoStructString(std::string field, std::string value)
|
bool Entity::SetInfoStructString(std::string field, std::string value)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<void(std::string)>>::const_iterator itr = set_string_funcs.find(field);
|
map<string, boost::function<void(std::string)>>::const_iterator itr = set_string_funcs.find(field);
|
||||||
if(itr != set_string_funcs.end())
|
if(itr != set_string_funcs.end())
|
||||||
{
|
{
|
||||||
(itr->second)(value);
|
(itr->second)(value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
RegisterProperty(field);
|
||||||
|
SetProperty(field, value);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Entity::SetInfoStructUInt(std::string field, int64 value)
|
bool Entity::SetInfoStructUInt(std::string field, int64 value)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<void(int8)>>::const_iterator itr = set_int8_funcs.find(field);
|
map<string, boost::function<void(int8)>>::const_iterator itr = set_int8_funcs.find(field);
|
||||||
if(itr != set_int8_funcs.end())
|
if(itr != set_int8_funcs.end())
|
||||||
{
|
{
|
||||||
@ -3990,6 +4069,7 @@ bool Entity::SetInfoStructUInt(std::string field, int64 value)
|
|||||||
|
|
||||||
bool Entity::SetInfoStructSInt(std::string field, sint64 value)
|
bool Entity::SetInfoStructSInt(std::string field, sint64 value)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<void(sint8)>>::const_iterator itr = set_sint8_funcs.find(field);
|
map<string, boost::function<void(sint8)>>::const_iterator itr = set_sint8_funcs.find(field);
|
||||||
if(itr != set_sint8_funcs.end())
|
if(itr != set_sint8_funcs.end())
|
||||||
{
|
{
|
||||||
@ -4019,6 +4099,7 @@ bool Entity::SetInfoStructSInt(std::string field, sint64 value)
|
|||||||
|
|
||||||
bool Entity::SetInfoStructFloat(std::string field, float value)
|
bool Entity::SetInfoStructFloat(std::string field, float value)
|
||||||
{
|
{
|
||||||
|
std::shared_lock<std::shared_mutex> rlock(propertiesMutex);
|
||||||
map<string, boost::function<void(float)>>::const_iterator itr = set_float_funcs.find(field);
|
map<string, boost::function<void(float)>>::const_iterator itr = set_float_funcs.find(field);
|
||||||
if(itr != set_float_funcs.end())
|
if(itr != set_float_funcs.end())
|
||||||
{
|
{
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <optional>
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
#include <boost/lambda/bind.hpp>
|
#include <boost/lambda/bind.hpp>
|
||||||
|
|
||||||
@ -1110,6 +1112,9 @@ struct InfoStruct{
|
|||||||
// maintained via their own mutex
|
// maintained via their own mutex
|
||||||
SpellEffects spell_effects[45];
|
SpellEffects spell_effects[45];
|
||||||
MaintainedEffects maintained_effects[30];
|
MaintainedEffects maintained_effects[30];
|
||||||
|
// when PacketStruct is fixed for C++17 this should become a shared_mutex and handle read/write lock
|
||||||
|
std::mutex classMutex;
|
||||||
|
std::unordered_map<std::string, std::string> props;
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
int8 class1_;
|
int8 class1_;
|
||||||
@ -1328,8 +1333,6 @@ private:
|
|||||||
int8 max_spell_reduction_override_;
|
int8 max_spell_reduction_override_;
|
||||||
|
|
||||||
float max_chase_distance_;
|
float max_chase_distance_;
|
||||||
// when PacketStruct is fixed for C++17 this should become a shared_mutex and handle read/write lock
|
|
||||||
std::mutex classMutex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WardInfo {
|
struct WardInfo {
|
||||||
@ -1449,6 +1452,9 @@ public:
|
|||||||
void DeleteSpellEffects(bool removeClient = false);
|
void DeleteSpellEffects(bool removeClient = false);
|
||||||
void RemoveSpells(bool unfriendlyOnly = false);
|
void RemoveSpells(bool unfriendlyOnly = false);
|
||||||
void MapInfoStruct();
|
void MapInfoStruct();
|
||||||
|
void RegisterProperty(const std::string& name);
|
||||||
|
void SetProperty(const std::string& name, const std::string& value);
|
||||||
|
std::optional<std::string> GetProperty(const std::string& name) const;
|
||||||
virtual float GetDodgeChance();
|
virtual float GetDodgeChance();
|
||||||
virtual void AddMaintainedSpell(LuaSpell* spell);
|
virtual void AddMaintainedSpell(LuaSpell* spell);
|
||||||
virtual void AddSpellEffect(LuaSpell* spell, int32 override_expire_time = 0);
|
virtual void AddSpellEffect(LuaSpell* spell, int32 override_expire_time = 0);
|
||||||
@ -2205,6 +2211,8 @@ private:
|
|||||||
map<string, boost::function<void(sint8)> > set_sint8_funcs;
|
map<string, boost::function<void(sint8)> > set_sint8_funcs;
|
||||||
|
|
||||||
map<string, boost::function<void(std::string)> > set_string_funcs;
|
map<string, boost::function<void(std::string)> > set_string_funcs;
|
||||||
|
|
||||||
|
mutable std::shared_mutex propertiesMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2146,14 +2146,34 @@ bool WorldDatabase::insertCharacterProperty(Client* client, char* propName, char
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WorldDatabase::loadCharacterProperties(Client* client) {
|
bool WorldDatabase::insertCharacterProperty(int32 charID, char* propName, char* propValue) {
|
||||||
|
Query query, query2;
|
||||||
|
|
||||||
|
string update_status = string("update character_properties set propvalue='%s' where charid=%i and propname='%s'");
|
||||||
|
query.RunQuery2(Q_UPDATE, update_status.c_str(), propValue, charID, propName);
|
||||||
|
if (!query.GetAffectedRows())
|
||||||
|
{
|
||||||
|
query2.RunQuery2(Q_UPDATE, "insert into character_properties (charid, propname, propvalue) values(%i, '%s', '%s')", charID, propName, propValue);
|
||||||
|
if (query2.GetErrorNumber() && query2.GetError() && query2.GetErrorNumber() < 0xFFFFFFFF) {
|
||||||
|
LogWrite(WORLD__ERROR, 0, "World", "Error in insertCharacterProperty query '%s': %s", query.GetQuery(), query.GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WorldDatabase::loadCharacterProperties(Client* client, bool preload) {
|
||||||
Query query;
|
Query query;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
int32 id = 0;
|
int32 id = 0;
|
||||||
MYSQL_RES* result = query.RunQuery2(Q_SELECT, "SELECT propname, propvalue FROM character_properties where charid = %i", client->GetCharacterID());
|
MYSQL_RES* result = query.RunQuery2(Q_SELECT,
|
||||||
|
"SELECT propname, propvalue FROM character_properties WHERE charid = %i",
|
||||||
|
client->GetCharacterID());
|
||||||
|
|
||||||
// no character found
|
// no character found
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
LogWrite(PLAYER__ERROR, 0, "Player", "Error loading character properties for '%s'", client->GetPlayer()->GetName());
|
LogWrite(PLAYER__ERROR, 0, "Player", "Error loading character properties for '%s'",
|
||||||
|
client->GetPlayer()->GetName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2164,109 +2184,151 @@ bool WorldDatabase::loadCharacterProperties(Client* client) {
|
|||||||
if (!prop_name || !prop_value)
|
if (!prop_name || !prop_value)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!stricmp(prop_name, CHAR_PROPERTY_SPEED))
|
bool matched = false;
|
||||||
{
|
|
||||||
float new_speed = atof(prop_value);
|
if (!stricmp(prop_name, CHAR_PROPERTY_SPEED)) {
|
||||||
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
float new_speed = (float)atof(prop_value);
|
||||||
client->GetPlayer()->SetSpeed(new_speed, true);
|
client->GetPlayer()->SetSpeed(new_speed, true);
|
||||||
client->GetPlayer()->SetCharSheetChanged(true);
|
client->GetPlayer()->SetCharSheetChanged(true);
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_FLYMODE))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_FLYMODE)) {
|
||||||
int8 flymode = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int8 flymode = (int8)atoul(prop_value);
|
||||||
if (flymode) // avoid fly mode notification unless enabled
|
if (flymode) // avoid fly mode notification unless enabled
|
||||||
ClientPacketFunctions::SendFlyMode(client, flymode, false);
|
ClientPacketFunctions::SendFlyMode(client, flymode, false);
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_INVUL))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_INVUL)) {
|
||||||
int8 invul = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int8 invul = (int8)atoul(prop_value);
|
||||||
client->GetPlayer()->SetInvulnerable(invul == 1);
|
client->GetPlayer()->SetInvulnerable(invul == 1);
|
||||||
if (client->GetPlayer()->GetInvulnerable())
|
if (client->GetPlayer()->GetInvulnerable())
|
||||||
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "You are now invulnerable!");
|
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "You are now invulnerable!");
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_GMVISION))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_GMVISION)) {
|
||||||
int8 val = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int8 val = (int8)atoul(prop_value);
|
||||||
client->GetPlayer()->SetGMVision(val == 1);
|
client->GetPlayer()->SetGMVision(val == 1);
|
||||||
client->GetCurrentZone()->SendAllSpawnsForVisChange(client, false);
|
client->GetCurrentZone()->SendAllSpawnsForVisChange(client, false);
|
||||||
if (val)
|
if (val)
|
||||||
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "GM Vision Enabled!");
|
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "GM Vision Enabled!");
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_REGIONDEBUG))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_REGIONDEBUG)) {
|
||||||
int8 val = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int8 val = (int8)atoul(prop_value);
|
||||||
client->SetRegionDebug(val == 1);
|
client->SetRegionDebug(val == 1);
|
||||||
if (val)
|
if (val)
|
||||||
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Region Debug Enabled!");
|
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "Region Debug Enabled!");
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_LUADEBUG))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_LUADEBUG)) {
|
||||||
int8 val = atoul(prop_value);
|
matched = true;
|
||||||
if (val)
|
if (!preload) {
|
||||||
{
|
int8 val = (int8)atoul(prop_value);
|
||||||
|
if (val) {
|
||||||
client->SetLuaDebugClient(true);
|
client->SetLuaDebugClient(true);
|
||||||
if (lua_interface)
|
if (lua_interface)
|
||||||
lua_interface->UpdateDebugClients(client);
|
lua_interface->UpdateDebugClients(client);
|
||||||
|
|
||||||
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "You will now receive LUA error messages.");
|
client->SimpleMessage(CHANNEL_COLOR_YELLOW, "You will now receive LUA error messages.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_GROUPLOOTMETHOD))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_GROUPLOOTMETHOD)) {
|
||||||
int8 val = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int8 val = (int8)atoul(prop_value);
|
||||||
client->GetPlayer()->GetInfoStruct()->set_group_loot_method(val);
|
client->GetPlayer()->GetInfoStruct()->set_group_loot_method(val);
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_GROUPLOOTITEMRARITY))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_GROUPLOOTITEMRARITY)) {
|
||||||
int8 val = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int8 val = (int8)atoul(prop_value);
|
||||||
client->GetPlayer()->GetInfoStruct()->set_group_loot_items_rarity(val);
|
client->GetPlayer()->GetInfoStruct()->set_group_loot_items_rarity(val);
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_GROUPAUTOSPLIT))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_GROUPAUTOSPLIT)) {
|
||||||
int8 val = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int8 val = (int8)atoul(prop_value);
|
||||||
client->GetPlayer()->GetInfoStruct()->set_group_auto_split(val);
|
client->GetPlayer()->GetInfoStruct()->set_group_auto_split(val);
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_GROUPDEFAULTYELL))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_GROUPDEFAULTYELL)) {
|
||||||
int8 val = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int8 val = (int8)atoul(prop_value);
|
||||||
client->GetPlayer()->GetInfoStruct()->set_group_default_yell(val);
|
client->GetPlayer()->GetInfoStruct()->set_group_default_yell(val);
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_GROUPAUTOLOCK))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_GROUPAUTOLOCK)) {
|
||||||
int8 val = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int8 val = (int8)atoul(prop_value);
|
||||||
client->GetPlayer()->GetInfoStruct()->set_group_autolock(val);
|
client->GetPlayer()->GetInfoStruct()->set_group_autolock(val);
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_GROUPSOLOAUTOLOCK))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_GROUPSOLOAUTOLOCK)) {
|
||||||
int8 val = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int8 val = (int8)atoul(prop_value);
|
||||||
client->GetPlayer()->GetInfoStruct()->set_group_solo_autolock(val);
|
client->GetPlayer()->GetInfoStruct()->set_group_solo_autolock(val);
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_AUTOLOOTMETHOD))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_AUTOLOOTMETHOD)) {
|
||||||
int8 val = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int8 val = (int8)atoul(prop_value);
|
||||||
client->GetPlayer()->GetInfoStruct()->set_group_auto_loot_method(val);
|
client->GetPlayer()->GetInfoStruct()->set_group_auto_loot_method(val);
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_GROUPLOCKMETHOD))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_GROUPLOCKMETHOD)) {
|
||||||
int8 val = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int8 val = (int8)atoul(prop_value);
|
||||||
client->GetPlayer()->GetInfoStruct()->set_group_lock_method(val);
|
client->GetPlayer()->GetInfoStruct()->set_group_lock_method(val);
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_ASSISTAUTOATTACK))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_ASSISTAUTOATTACK)) {
|
||||||
int8 val = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int8 val = (int8)atoul(prop_value);
|
||||||
client->GetPlayer()->GetInfoStruct()->set_assist_auto_attack(val);
|
client->GetPlayer()->GetInfoStruct()->set_assist_auto_attack(val);
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_SETACTIVEFOOD))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_SETACTIVEFOOD)) {
|
||||||
int32 val = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int32 val = (int32)atoul(prop_value);
|
||||||
client->GetPlayer()->SetActiveFoodUniqueID(val, false);
|
client->GetPlayer()->SetActiveFoodUniqueID(val, false);
|
||||||
}
|
}
|
||||||
else if (!stricmp(prop_name, CHAR_PROPERTY_SETACTIVEDRINK))
|
}
|
||||||
{
|
else if (!stricmp(prop_name, CHAR_PROPERTY_SETACTIVEDRINK)) {
|
||||||
int32 val = atoul(prop_value);
|
matched = true;
|
||||||
|
if (!preload) {
|
||||||
|
int32 val = (int32)atoul(prop_value);
|
||||||
client->GetPlayer()->SetActiveDrinkUniqueID(val, false);
|
client->GetPlayer()->SetActiveDrinkUniqueID(val, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// Unknown property: only act during preload AND only if no stricmp matched
|
||||||
|
// (we're in the 'else', so matched == false by definition)
|
||||||
|
if (preload) {
|
||||||
|
client->GetPlayer()->RegisterProperty(std::string(prop_name));
|
||||||
|
client->GetPlayer()->SetProperty(std::string(prop_name), std::string(prop_value));
|
||||||
|
}
|
||||||
|
// When preload == false, we intentionally ignore unknown properties.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,8 @@ public:
|
|||||||
bool InsertCharacterStats(int32 character_id, int8 class_id, int8 race_id);
|
bool InsertCharacterStats(int32 character_id, int8 class_id, int8 race_id);
|
||||||
bool UpdateCharacterTimeStamp(int32 account_id, int32 character_id, int32 timestamp);
|
bool UpdateCharacterTimeStamp(int32 account_id, int32 character_id, int32 timestamp);
|
||||||
bool insertCharacterProperty(Client* client, char* propName, char* propValue);
|
bool insertCharacterProperty(Client* client, char* propName, char* propValue);
|
||||||
bool loadCharacterProperties(Client* client);
|
bool insertCharacterProperty(int32 charID, char* propName, char* propValue);
|
||||||
|
bool loadCharacterProperties(Client* client, bool preload = false);
|
||||||
string GetPlayerName(char* name);
|
string GetPlayerName(char* name);
|
||||||
int32 GetCharacterTimeStamp(int32 character_id, int32 account_id,bool* char_exists);
|
int32 GetCharacterTimeStamp(int32 character_id, int32 account_id,bool* char_exists);
|
||||||
int32 GetCharacterTimeStamp(int32 character_id);
|
int32 GetCharacterTimeStamp(int32 character_id);
|
||||||
|
@ -12249,6 +12249,7 @@ bool Client::HandleNewLogin(int32 account_id, int32 access_code)
|
|||||||
new_client_login = NewLoginState::LOGIN_ALLOWED;
|
new_client_login = NewLoginState::LOGIN_ALLOWED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
database.loadCharacterProperties(this, true);
|
||||||
// vault slots
|
// vault slots
|
||||||
RefreshVaultSlotCount();
|
RefreshVaultSlotCount();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user