mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-11-22 13:37:22 +00:00
Merge pull request #354 Sanitize SQLite Queries
adds support to prevent sql injection via using prepared statements and also fixes an issue with the runmacro command.
This commit is contained in:
commit
769f789a43
@ -13,3 +13,8 @@ void CDClientDatabase::Connect(const std::string& filename) {
|
||||
CppSQLite3Query CDClientDatabase::ExecuteQuery(const std::string& query) {
|
||||
return conn->execQuery(query.c_str());
|
||||
}
|
||||
|
||||
//! Makes prepared statements
|
||||
CppSQLite3Statement CDClientDatabase::CreatePreppedStmt(const std::string& query) {
|
||||
return conn->compileStatement(query.c_str());
|
||||
}
|
||||
|
@ -40,4 +40,10 @@ namespace CDClientDatabase {
|
||||
*/
|
||||
CppSQLite3Query ExecuteQuery(const std::string& query);
|
||||
|
||||
//! Queries the CDClient and parses arguments
|
||||
/*!
|
||||
\param query The query with formatted arguments
|
||||
\return prepared SQLite Statement
|
||||
*/
|
||||
CppSQLite3Statement CreatePreppedStmt(const std::string& query);
|
||||
};
|
||||
|
@ -4,19 +4,19 @@
|
||||
//! Constructor
|
||||
CDBehaviorParameterTable::CDBehaviorParameterTable(void) {
|
||||
#ifdef CDCLIENT_CACHE_ALL
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter");
|
||||
while (!tableData.eof()) {
|
||||
CDBehaviorParameter entry;
|
||||
entry.behaviorID = tableData.getIntField(0, -1);
|
||||
entry.parameterID = tableData.getStringField(1, "");
|
||||
entry.value = tableData.getFloatField(2, -1.0f);
|
||||
auto tableData = CDClientDatabase::ExecuteQuery("SELECT * FROM BehaviorParameter");
|
||||
while (!tableData.eof()) {
|
||||
CDBehaviorParameter entry;
|
||||
entry.behaviorID = tableData.getIntField(0, -1);
|
||||
entry.parameterID = tableData.getStringField(1, "");
|
||||
entry.value = tableData.getFloatField(2, -1.0f);
|
||||
|
||||
//Check if we have an entry with this ID:
|
||||
auto it = m_entries.find(entry.behaviorID);
|
||||
if (it != m_entries.end()) {
|
||||
it->second.insert(std::make_pair(entry.parameterID, entry.value));
|
||||
}
|
||||
else {
|
||||
else {
|
||||
//Otherwise, insert it:
|
||||
m_entries.insert(std::make_pair(entry.behaviorID, std::map<std::string, float>()));
|
||||
auto jit = m_entries.find(entry.behaviorID);
|
||||
@ -25,8 +25,8 @@ CDBehaviorParameterTable::CDBehaviorParameterTable(void) {
|
||||
jit->second.insert(std::make_pair(entry.parameterID, entry.value));
|
||||
}
|
||||
|
||||
tableData.nextRow();
|
||||
}
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
tableData.finalize();
|
||||
#endif
|
||||
@ -37,7 +37,7 @@ CDBehaviorParameterTable::~CDBehaviorParameterTable(void) { }
|
||||
|
||||
//! Returns the table's name
|
||||
std::string CDBehaviorParameterTable::GetName(void) const {
|
||||
return "BehaviorParameter";
|
||||
return "BehaviorParameter";
|
||||
}
|
||||
|
||||
float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::string& name, const float defaultValue)
|
||||
@ -59,17 +59,17 @@ float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::s
|
||||
}
|
||||
|
||||
#ifndef CDCLIENT_CACHE_ALL
|
||||
std::stringstream query;
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = ?;");
|
||||
query.bind(1, (int) behaviorID);
|
||||
|
||||
query << "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = " << std::to_string(behaviorID);
|
||||
|
||||
auto tableData = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto tableData = query.execQuery();
|
||||
|
||||
m_Entries.insert_or_assign(behaviorID, 0);
|
||||
|
||||
|
||||
while (!tableData.eof()) {
|
||||
const std::string parameterID = tableData.getStringField(0, "");
|
||||
const float value = tableData.getFloatField(1, 0);
|
||||
const std::string parameterID = tableData.getStringField(0, "");
|
||||
const float value = tableData.getFloatField(1, 0);
|
||||
|
||||
size_t parameterHash = 0;
|
||||
GeneralUtils::hash_combine(parameterHash, behaviorID);
|
||||
@ -77,8 +77,8 @@ float CDBehaviorParameterTable::GetEntry(const uint32_t behaviorID, const std::s
|
||||
|
||||
m_Entries.insert_or_assign(parameterHash, value);
|
||||
|
||||
tableData.nextRow();
|
||||
}
|
||||
tableData.nextRow();
|
||||
}
|
||||
|
||||
const auto& it2 = m_Entries.find(hash);
|
||||
if (it2 != m_Entries.end()) {
|
||||
|
@ -91,21 +91,21 @@ Behavior* Behavior::GetBehavior(const uint32_t behaviorId)
|
||||
Behavior* Behavior::CreateBehavior(const uint32_t behaviorId)
|
||||
{
|
||||
auto* cached = GetBehavior(behaviorId);
|
||||
|
||||
|
||||
if (cached != nullptr)
|
||||
{
|
||||
return cached;
|
||||
}
|
||||
|
||||
|
||||
if (behaviorId == 0)
|
||||
{
|
||||
return new EmptyBehavior(0);
|
||||
}
|
||||
|
||||
|
||||
const auto templateId = GetBehaviorTemplate(behaviorId);
|
||||
|
||||
Behavior* behavior = nullptr;
|
||||
|
||||
|
||||
switch (templateId)
|
||||
{
|
||||
case BehaviorTemplates::BEHAVIOR_EMPTY: break;
|
||||
@ -191,8 +191,8 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId)
|
||||
behavior = new JetPackBehavior(behaviorId);
|
||||
break;
|
||||
case BehaviorTemplates::BEHAVIOR_SKILL_EVENT:
|
||||
behavior = new SkillEventBehavior(behaviorId);
|
||||
break;
|
||||
behavior = new SkillEventBehavior(behaviorId);
|
||||
break;
|
||||
case BehaviorTemplates::BEHAVIOR_CONSUME_ITEM: break;
|
||||
case BehaviorTemplates::BEHAVIOR_SKILL_CAST_FAILED:
|
||||
behavior = new SkillCastFailedBehavior(behaviorId);
|
||||
@ -272,7 +272,7 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId)
|
||||
if (behavior == nullptr)
|
||||
{
|
||||
//Game::logger->Log("Behavior", "Failed to load unimplemented template id (%i)!\n", templateId);
|
||||
|
||||
|
||||
behavior = new EmptyBehavior(behaviorId);
|
||||
}
|
||||
|
||||
@ -281,13 +281,12 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId)
|
||||
return behavior;
|
||||
}
|
||||
|
||||
BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId)
|
||||
{
|
||||
std::stringstream query;
|
||||
BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId) {
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT templateID FROM BehaviorTemplate WHERE behaviorID = ?;");
|
||||
query.bind(1, (int) behaviorId);
|
||||
|
||||
query << "SELECT templateID FROM BehaviorTemplate WHERE behaviorID = " << std::to_string(behaviorId);
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto result = query.execQuery();
|
||||
|
||||
// Make sure we do not proceed if we are trying to load an invalid behavior
|
||||
if (result.eof())
|
||||
@ -299,7 +298,7 @@ BehaviorTemplates Behavior::GetBehaviorTemplate(const uint32_t behaviorId)
|
||||
|
||||
return BehaviorTemplates::BEHAVIOR_EMPTY;
|
||||
}
|
||||
|
||||
|
||||
const auto id = static_cast<BehaviorTemplates>(result.getIntField(0));
|
||||
|
||||
result.finalize();
|
||||
@ -325,7 +324,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto* renderComponent = targetEntity->GetComponent<RenderComponent>();
|
||||
|
||||
const auto typeString = GeneralUtils::UTF16ToWTF8(type);
|
||||
@ -348,28 +347,35 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID
|
||||
if (renderComponent == nullptr)
|
||||
{
|
||||
GameMessages::SendPlayFXEffect(targetEntity, effectId, type, pair->second, secondary, 1, 1, true);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
renderComponent->PlayEffect(effectId, type, pair->second, secondary);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::stringstream query;
|
||||
|
||||
if (!type.empty())
|
||||
{
|
||||
query << "SELECT effectName FROM BehaviorEffect WHERE effectType = '" << typeString << "' AND effectID = " << std::to_string(effectId) << ";";
|
||||
}
|
||||
else
|
||||
{
|
||||
query << "SELECT effectName, effectType FROM BehaviorEffect WHERE effectID = " << std::to_string(effectId) << ";";
|
||||
}
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
// The SQlite result object becomes invalid if the query object leaves scope.
|
||||
// So both queries are defined before the if statement
|
||||
CppSQLite3Query result;
|
||||
auto typeQuery = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT effectName FROM BehaviorEffect WHERE effectType = ? AND effectID = ?;");
|
||||
|
||||
auto idQuery = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT effectName, effectType FROM BehaviorEffect WHERE effectID = ?;");
|
||||
|
||||
if (!type.empty()) {
|
||||
typeQuery.bind(1, typeString.c_str());
|
||||
typeQuery.bind(2, (int) effectId);
|
||||
|
||||
result = typeQuery.execQuery();
|
||||
} else {
|
||||
idQuery.bind(1, (int) effectId);
|
||||
|
||||
result = idQuery.execQuery();
|
||||
}
|
||||
|
||||
if (result.eof() || result.fieldIsNull(0))
|
||||
{
|
||||
@ -381,7 +387,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID
|
||||
if (type.empty())
|
||||
{
|
||||
const auto typeResult = result.getStringField(1);
|
||||
|
||||
|
||||
type = GeneralUtils::ASCIIToUTF16(typeResult);
|
||||
|
||||
m_effectType = new std::string(typeResult);
|
||||
@ -394,7 +400,7 @@ void Behavior::PlayFx(std::u16string type, const LWOOBJID target, const LWOOBJID
|
||||
if (renderComponent == nullptr)
|
||||
{
|
||||
GameMessages::SendPlayFXEffect(targetEntity, effectId, type, name, secondary, 1, 1, true);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -414,15 +420,11 @@ Behavior::Behavior(const uint32_t behaviorId)
|
||||
this->m_templateId = BehaviorTemplates::BEHAVIOR_EMPTY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get standard info
|
||||
*/
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT templateID, effectID, effectHandle FROM BehaviorTemplate WHERE behaviorID = ?;");
|
||||
query.bind(1, (int) behaviorId);
|
||||
|
||||
std::stringstream query;
|
||||
|
||||
query << "SELECT templateID, effectID, effectHandle FROM BehaviorTemplate WHERE behaviorID = " << std::to_string(behaviorId);
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto result = query.execQuery();
|
||||
|
||||
// Make sure we do not proceed if we are trying to load an invalid behavior
|
||||
if (result.eof())
|
||||
@ -437,7 +439,7 @@ Behavior::Behavior(const uint32_t behaviorId)
|
||||
}
|
||||
|
||||
this->m_templateId = static_cast<BehaviorTemplates>(result.getIntField(0));
|
||||
|
||||
|
||||
this->m_effectId = result.getIntField(1);
|
||||
|
||||
if (!result.fieldIsNull(2))
|
||||
@ -495,11 +497,11 @@ std::map<std::string, float> Behavior::GetParameterNames() const
|
||||
{
|
||||
std::map<std::string, float> parameters;
|
||||
|
||||
std::stringstream query;
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = ?;");
|
||||
query.bind(1, (int) this->m_behaviorId);
|
||||
|
||||
query << "SELECT parameterID, value FROM BehaviorParameter WHERE behaviorID = " << std::to_string(this->m_behaviorId);
|
||||
|
||||
auto tableData = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto tableData = query.execQuery();
|
||||
|
||||
while (!tableData.eof())
|
||||
{
|
||||
|
@ -39,15 +39,15 @@ void SwitchMultipleBehavior::Calculate(BehaviorContext* context, RakNet::BitStre
|
||||
// TODO
|
||||
}
|
||||
|
||||
void SwitchMultipleBehavior::Load()
|
||||
{
|
||||
const auto b = std::to_string(this->m_behaviorId);
|
||||
std::stringstream query;
|
||||
query << "SELECT replace(bP1.parameterID, 'behavior ', '') as key, bP1.value as behavior, "
|
||||
<< "(select bP2.value FROM BehaviorParameter bP2 WHERE bP2.behaviorID = " << b << " AND bP2.parameterID LIKE 'value %' "
|
||||
<< "AND replace(bP1.parameterID, 'behavior ', '') = replace(bP2.parameterID, 'value ', '')) as value "
|
||||
<< "FROM BehaviorParameter bP1 WHERE bP1.behaviorID = " << b << " AND bP1.parameterID LIKE 'behavior %'";
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
void SwitchMultipleBehavior::Load() {
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT replace(bP1.parameterID, 'behavior ', '') as key, bP1.value as behavior, "
|
||||
"(select bP2.value FROM BehaviorParameter bP2 WHERE bP2.behaviorID = ?1 AND bP2.parameterID LIKE 'value %' "
|
||||
"AND replace(bP1.parameterID, 'behavior ', '') = replace(bP2.parameterID, 'value ', '')) as value "
|
||||
"FROM BehaviorParameter bP1 WHERE bP1.behaviorID = ?1 AND bP1.parameterID LIKE 'behavior %';");
|
||||
query.bind(1, (int) this->m_behaviorId);
|
||||
|
||||
auto result = query.execQuery();
|
||||
|
||||
while (!result.eof()) {
|
||||
const auto behavior_id = static_cast<uint32_t>(result.getFloatField(1));
|
||||
|
@ -35,11 +35,11 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id)
|
||||
m_SoftTimer = 5.0f;
|
||||
|
||||
//Grab the aggro information from BaseCombatAI:
|
||||
std::stringstream componentQuery;
|
||||
|
||||
componentQuery << "SELECT aggroRadius, tetherSpeed, pursuitSpeed, softTetherRadius, hardTetherRadius FROM BaseCombatAIComponent WHERE id = " << std::to_string(id);
|
||||
|
||||
auto componentResult = CDClientDatabase::ExecuteQuery(componentQuery.str());
|
||||
auto componentQuery = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT aggroRadius, tetherSpeed, pursuitSpeed, softTetherRadius, hardTetherRadius FROM BaseCombatAIComponent WHERE id = ?;");
|
||||
componentQuery.bind(1, (int) id);
|
||||
|
||||
auto componentResult = componentQuery.execQuery();
|
||||
|
||||
if (!componentResult.eof())
|
||||
{
|
||||
@ -64,12 +64,11 @@ BaseCombatAIComponent::BaseCombatAIComponent(Entity* parent, const uint32_t id)
|
||||
/*
|
||||
* Find skills
|
||||
*/
|
||||
|
||||
std::stringstream query;
|
||||
|
||||
query << "SELECT skillID, cooldown, behaviorID FROM SkillBehavior WHERE skillID IN (SELECT skillID FROM ObjectSkills WHERE objectTemplate = " << std::to_string(parent->GetLOT()) << " )";
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto skillQuery = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT skillID, cooldown, behaviorID FROM SkillBehavior WHERE skillID IN (SELECT skillID FROM ObjectSkills WHERE objectTemplate = ?);");
|
||||
skillQuery.bind(1, (int) parent->GetLOT());
|
||||
|
||||
auto result = skillQuery.execQuery();
|
||||
|
||||
while (!result.eof()) {
|
||||
const auto skillId = static_cast<uint32_t>(result.getIntField(0));
|
||||
|
@ -371,12 +371,12 @@ const std::vector<BuffParameter>& BuffComponent::GetBuffParameters(int32_t buffI
|
||||
return pair->second;
|
||||
}
|
||||
|
||||
std::stringstream query;
|
||||
|
||||
query << "SELECT * FROM BuffParameters WHERE BuffID = " << std::to_string(buffId) << ";";
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT * FROM BuffParameters WHERE BuffID = ?;");
|
||||
query.bind(1, (int) buffId);
|
||||
|
||||
auto result = query.execQuery();
|
||||
|
||||
std::vector<BuffParameter> parameters {};
|
||||
|
||||
while (!result.eof())
|
||||
|
@ -106,7 +106,7 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn
|
||||
outBitStream->Write0(); //Contains info about immunities this object has, but it's left out for now.
|
||||
}
|
||||
|
||||
outBitStream->Write(m_DirtyHealth || bIsInitialUpdate);
|
||||
outBitStream->Write(m_DirtyHealth || bIsInitialUpdate);
|
||||
if (m_DirtyHealth || bIsInitialUpdate) {
|
||||
outBitStream->Write(m_iHealth);
|
||||
outBitStream->Write(m_fMaxHealth);
|
||||
@ -114,12 +114,12 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn
|
||||
outBitStream->Write(m_fMaxArmor);
|
||||
outBitStream->Write(m_iImagination);
|
||||
outBitStream->Write(m_fMaxImagination);
|
||||
|
||||
|
||||
outBitStream->Write(m_DamageToAbsorb);
|
||||
outBitStream->Write(IsImmune());
|
||||
outBitStream->Write(m_IsGMImmune);
|
||||
outBitStream->Write(m_IsShielded);
|
||||
|
||||
|
||||
outBitStream->Write(m_fMaxHealth);
|
||||
outBitStream->Write(m_fMaxArmor);
|
||||
outBitStream->Write(m_fMaxImagination);
|
||||
@ -130,14 +130,14 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn
|
||||
}
|
||||
|
||||
outBitStream->Write(m_IsSmashable);
|
||||
|
||||
|
||||
if (bIsInitialUpdate) {
|
||||
outBitStream->Write(m_IsDead);
|
||||
outBitStream->Write(m_IsSmashed);
|
||||
|
||||
|
||||
if (m_IsSmashable) {
|
||||
outBitStream->Write(m_HasBricks);
|
||||
|
||||
|
||||
if (m_ExplodeFactor != 1.0f) {
|
||||
outBitStream->Write1();
|
||||
outBitStream->Write(m_ExplodeFactor);
|
||||
@ -146,10 +146,10 @@ void DestroyableComponent::Serialize(RakNet::BitStream* outBitStream, bool bIsIn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_DirtyHealth = false;
|
||||
}
|
||||
|
||||
|
||||
if (m_DirtyThreatList || bIsInitialUpdate) {
|
||||
outBitStream->Write1();
|
||||
outBitStream->Write(m_HasThreats);
|
||||
@ -167,7 +167,7 @@ void DestroyableComponent::LoadFromXML(tinyxml2::XMLDocument* doc) {
|
||||
}
|
||||
|
||||
auto* buffComponent = m_Parent->GetComponent<BuffComponent>();
|
||||
|
||||
|
||||
if (buffComponent != nullptr) {
|
||||
buffComponent->LoadFromXML(doc);
|
||||
}
|
||||
@ -187,9 +187,9 @@ void DestroyableComponent::UpdateXml(tinyxml2::XMLDocument* doc) {
|
||||
Game::logger->Log("DestroyableComponent", "Failed to find dest tag!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto* buffComponent = m_Parent->GetComponent<BuffComponent>();
|
||||
|
||||
|
||||
if (buffComponent != nullptr) {
|
||||
buffComponent->UpdateXml(doc);
|
||||
}
|
||||
@ -235,7 +235,7 @@ void DestroyableComponent::SetMaxHealth(float value, bool playAnim) {
|
||||
args.InsertValue("amount", amount);
|
||||
args.InsertValue("type", type);
|
||||
GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args);
|
||||
|
||||
|
||||
delete amount;
|
||||
delete type;
|
||||
}
|
||||
@ -283,7 +283,7 @@ void DestroyableComponent::SetMaxArmor(float value, bool playAnim) {
|
||||
args.InsertValue("type", type);
|
||||
|
||||
GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args);
|
||||
|
||||
|
||||
delete amount;
|
||||
delete type;
|
||||
}
|
||||
@ -329,7 +329,7 @@ void DestroyableComponent::SetMaxImagination(float value, bool playAnim) {
|
||||
args.InsertValue("amount", amount);
|
||||
args.InsertValue("type", type);
|
||||
GameMessages::SendUIMessageServerToSingleClient(m_Parent, m_Parent->GetParentUser()->GetSystemAddress(), "MaxPlayerBarUpdate", &args);
|
||||
|
||||
|
||||
delete amount;
|
||||
delete type;
|
||||
}
|
||||
@ -342,7 +342,7 @@ void DestroyableComponent::SetDamageToAbsorb(int32_t value)
|
||||
m_DamageToAbsorb = value;
|
||||
}
|
||||
|
||||
void DestroyableComponent::SetDamageReduction(int32_t value)
|
||||
void DestroyableComponent::SetDamageReduction(int32_t value)
|
||||
{
|
||||
m_DirtyHealth = true;
|
||||
m_DamageReduction = value;
|
||||
@ -354,7 +354,7 @@ void DestroyableComponent::SetIsImmune(bool value)
|
||||
m_ImmuneStacks = value ? 1 : 0;
|
||||
}
|
||||
|
||||
void DestroyableComponent::SetIsGMImmune(bool value)
|
||||
void DestroyableComponent::SetIsGMImmune(bool value)
|
||||
{
|
||||
m_DirtyHealth = true;
|
||||
m_IsGMImmune = value;
|
||||
@ -375,11 +375,11 @@ void DestroyableComponent::AddFaction(const int32_t factionID, const bool ignore
|
||||
m_FactionIDs.push_back(factionID);
|
||||
m_DirtyHealth = true;
|
||||
|
||||
std::stringstream query;
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT enemyList FROM Factions WHERE faction = ?;");
|
||||
query.bind(1, (int) factionID);
|
||||
|
||||
query << "SELECT enemyList FROM Factions WHERE faction = " << std::to_string(factionID);
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto result = query.execQuery();
|
||||
|
||||
if (result.eof()) return;
|
||||
|
||||
@ -389,10 +389,10 @@ void DestroyableComponent::AddFaction(const int32_t factionID, const bool ignore
|
||||
|
||||
std::stringstream ss(list_string);
|
||||
std::string token;
|
||||
|
||||
|
||||
while (std::getline(ss, token, ',')) {
|
||||
if (token.empty()) continue;
|
||||
|
||||
|
||||
auto id = std::stoi(token);
|
||||
|
||||
auto exclude = std::find(m_FactionIDs.begin(), m_FactionIDs.end(), id) != m_FactionIDs.end();
|
||||
@ -406,7 +406,7 @@ void DestroyableComponent::AddFaction(const int32_t factionID, const bool ignore
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
AddEnemyFaction(id);
|
||||
}
|
||||
|
||||
@ -522,7 +522,7 @@ bool DestroyableComponent::CheckValidity(const LWOOBJID target, const bool ignor
|
||||
if (targetQuickbuild != nullptr)
|
||||
{
|
||||
const auto state = targetQuickbuild->GetState();
|
||||
|
||||
|
||||
if (state != REBUILD_COMPLETED)
|
||||
{
|
||||
return false;
|
||||
@ -562,7 +562,7 @@ void DestroyableComponent::Imagine(const int32_t deltaImagination)
|
||||
{
|
||||
auto current = static_cast<int32_t>(GetImagination());
|
||||
const auto max = static_cast<int32_t>(GetMaxImagination());
|
||||
|
||||
|
||||
current += deltaImagination;
|
||||
|
||||
current = std::min(current, max);
|
||||
@ -635,7 +635,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
|
||||
|
||||
damage -= absorbDamage;
|
||||
absorb -= absorbDamage;
|
||||
|
||||
|
||||
const auto armorDamage = std::min(damage, armor);
|
||||
|
||||
damage -= armorDamage;
|
||||
@ -657,7 +657,7 @@ void DestroyableComponent::Damage(uint32_t damage, const LWOOBJID source, uint32
|
||||
{
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
}
|
||||
|
||||
|
||||
auto* attacker = EntityManager::Instance()->GetEntity(source);
|
||||
m_Parent->OnHit(attacker);
|
||||
m_Parent->OnHitOrHealResult(attacker, sourceDamage);
|
||||
@ -736,7 +736,7 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const auto isPlayer = m_Parent->IsPlayer();
|
||||
|
||||
GameMessages::SendDie(m_Parent, source, source, true, killType, deathType, 0, 0, 0, isPlayer, false, 1);
|
||||
@ -765,14 +765,14 @@ void DestroyableComponent::Smash(const LWOOBJID source, const eKillType killType
|
||||
auto* member = EntityManager::Instance()->GetEntity(specificOwner);
|
||||
|
||||
if (member) LootGenerator::Instance().DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins());
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const auto memberId : team->members) { // Free for all
|
||||
auto* member = EntityManager::Instance()->GetEntity(memberId);
|
||||
|
||||
if (member == nullptr) continue;
|
||||
|
||||
LootGenerator::Instance().DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins());
|
||||
LootGenerator::Instance().DropLoot(member, m_Parent, lootMatrixId, GetMinCoins(), GetMaxCoins());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -846,7 +846,7 @@ void DestroyableComponent::PopImmunity(int32_t stacks)
|
||||
m_ImmuneStacks -= stacks;
|
||||
}
|
||||
|
||||
void DestroyableComponent::FixStats()
|
||||
void DestroyableComponent::FixStats()
|
||||
{
|
||||
auto* entity = GetParent();
|
||||
|
||||
@ -904,7 +904,7 @@ void DestroyableComponent::FixStats()
|
||||
|
||||
// Add the stats
|
||||
const auto& info = mission->GetClientInfo();
|
||||
|
||||
|
||||
maxHealth += info.reward_maxhealth;
|
||||
maxImagination += info.reward_maximagination;
|
||||
}
|
||||
|
@ -51,18 +51,18 @@ InventoryComponent::InventoryComponent(Entity* parent, tinyxml2::XMLDocument* do
|
||||
auto items = inventoryComponentTable->Query([=](const CDInventoryComponent entry) { return entry.id == componentId; });
|
||||
|
||||
auto slot = 0u;
|
||||
|
||||
|
||||
for (const auto& item : items)
|
||||
{
|
||||
if (!item.equip || !Inventory::IsValidItem(item.itemid))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const LWOOBJID id = ObjectIDManager::Instance()->GenerateObjectID();
|
||||
|
||||
const auto& info = Inventory::FindItemComponent(item.itemid);
|
||||
|
||||
|
||||
UpdateSlot(info.equipLocation, { id, static_cast<LOT>(item.itemid), item.count, slot++ });
|
||||
}
|
||||
}
|
||||
@ -178,7 +178,7 @@ void InventoryComponent::AddItem(
|
||||
auto* missions = static_cast<MissionComponent*>(this->m_Parent->GetComponent(COMPONENT_TYPE_MISSION));
|
||||
|
||||
auto* inventory = GetInventory(inventoryType);
|
||||
|
||||
|
||||
if (!config.empty() || bound)
|
||||
{
|
||||
const auto slot = preferredSlot != -1 && inventory->IsSlotEmpty(preferredSlot) ? preferredSlot : inventory->FindEmptySlot();
|
||||
@ -189,6 +189,7 @@ void InventoryComponent::AddItem(
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto* item = new Item(lot, inventory, slot, count, config, parent, showFlyingLoot, isModMoveAndEquip, subKey, bound, lootSourceType);
|
||||
|
||||
if (missions != nullptr && !IsTransferInventory(inventoryType))
|
||||
@ -200,7 +201,7 @@ void InventoryComponent::AddItem(
|
||||
}
|
||||
|
||||
const auto info = Inventory::FindItemComponent(lot);
|
||||
|
||||
|
||||
auto left = count;
|
||||
|
||||
int32_t outOfSpace = 0;
|
||||
@ -215,7 +216,7 @@ void InventoryComponent::AddItem(
|
||||
{
|
||||
stack = 1;
|
||||
}
|
||||
|
||||
|
||||
auto* existing = FindItemByLot(lot, inventoryType);
|
||||
|
||||
if (existing != nullptr)
|
||||
@ -239,7 +240,7 @@ void InventoryComponent::AddItem(
|
||||
const auto size = std::min(left, stack);
|
||||
|
||||
left -= size;
|
||||
|
||||
|
||||
int32_t slot;
|
||||
|
||||
if (preferredSlot != -1 && inventory->IsSlotEmpty(preferredSlot))
|
||||
@ -252,7 +253,7 @@ void InventoryComponent::AddItem(
|
||||
{
|
||||
slot = inventory->FindEmptySlot();
|
||||
}
|
||||
|
||||
|
||||
if (slot == -1)
|
||||
{
|
||||
auto* player = dynamic_cast<Player*>(GetParent());
|
||||
@ -275,9 +276,9 @@ void InventoryComponent::AddItem(
|
||||
{
|
||||
GameMessages::SendDropClientLoot(this->m_Parent, this->m_Parent->GetObjectID(), lot, 0, this->m_Parent->GetPosition(), 1);
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -326,7 +327,7 @@ void InventoryComponent::RemoveItem(const LOT lot, const uint32_t count, eInvent
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
const auto delta = std::min<uint32_t>(left, item->GetCount());
|
||||
|
||||
item->SetCount(item->GetCount() - delta);
|
||||
@ -341,11 +342,11 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto* origin = item->GetInventory();
|
||||
|
||||
|
||||
const auto lot = item->GetLot();
|
||||
|
||||
|
||||
if (item->GetConfig().empty() && !item->GetBound() || (item->GetBound() && item->GetInfo().isBOP))
|
||||
{
|
||||
auto left = std::min<uint32_t>(count, origin->GetLotCount(lot));
|
||||
@ -383,7 +384,7 @@ void InventoryComponent::MoveItemToInventory(Item* item, const eInventoryType in
|
||||
{
|
||||
config.push_back(data->Copy());
|
||||
}
|
||||
|
||||
|
||||
const auto delta = std::min<uint32_t>(item->GetCount(), count);
|
||||
|
||||
AddItem(lot, delta, eLootSourceType::LOOT_SOURCE_NONE, inventory, config, LWOOBJID_EMPTY, showFlyingLot, isModMoveAndEquip, LWOOBJID_EMPTY, origin->GetType(), 0, item->GetBound(), preferredSlot);
|
||||
@ -441,7 +442,7 @@ Item* InventoryComponent::FindItemByLot(const LOT lot, eInventoryType inventoryT
|
||||
return inventory->FindItemByLot(lot, ignoreEquipped, ignoreBound);
|
||||
}
|
||||
|
||||
Item* InventoryComponent::FindItemBySubKey(LWOOBJID id, eInventoryType inventoryType)
|
||||
Item* InventoryComponent::FindItemBySubKey(LWOOBJID id, eInventoryType inventoryType)
|
||||
{
|
||||
if (inventoryType == INVALID)
|
||||
{
|
||||
@ -600,7 +601,7 @@ void InventoryComponent::LoadXml(tinyxml2::XMLDocument* document)
|
||||
unsigned int count;
|
||||
bool bound;
|
||||
LWOOBJID subKey = LWOOBJID_EMPTY;
|
||||
|
||||
|
||||
itemElement->QueryAttribute("id", &id);
|
||||
itemElement->QueryAttribute("l", &lot);
|
||||
itemElement->QueryAttribute("eq", &equipped);
|
||||
@ -611,23 +612,23 @@ void InventoryComponent::LoadXml(tinyxml2::XMLDocument* document)
|
||||
|
||||
// Begin custom xml
|
||||
auto parent = LWOOBJID_EMPTY;
|
||||
|
||||
|
||||
itemElement->QueryAttribute("parent", &parent);
|
||||
// End custom xml
|
||||
|
||||
std::vector<LDFBaseData*> config;
|
||||
|
||||
auto* extraInfo = itemElement->FirstChildElement("x");
|
||||
|
||||
|
||||
if (extraInfo)
|
||||
{
|
||||
std::string modInfo = extraInfo->Attribute("ma");
|
||||
|
||||
|
||||
LDFBaseData* moduleAssembly = new LDFData<std::u16string>(u"assemblyPartLOTs", GeneralUtils::ASCIIToUTF16(modInfo.substr(2, modInfo.size() - 1)));
|
||||
|
||||
|
||||
config.push_back(moduleAssembly);
|
||||
}
|
||||
|
||||
|
||||
const auto* item = new Item(id, lot, inventory, slot, count, bound, config, parent, subKey);
|
||||
|
||||
if (equipped)
|
||||
@ -705,7 +706,7 @@ void InventoryComponent::UpdateXml(tinyxml2::XMLDocument* document)
|
||||
|
||||
bags->LinkEndChild(bag);
|
||||
}
|
||||
|
||||
|
||||
auto* items = inventoryElement->FirstChildElement("items");
|
||||
|
||||
if (items == nullptr)
|
||||
@ -759,10 +760,10 @@ void InventoryComponent::UpdateXml(tinyxml2::XMLDocument* document)
|
||||
|
||||
itemElement->LinkEndChild(extraInfo);
|
||||
}
|
||||
|
||||
|
||||
bagElement->LinkEndChild(itemElement);
|
||||
}
|
||||
|
||||
|
||||
items->LinkEndChild(bagElement);
|
||||
}
|
||||
}
|
||||
@ -772,13 +773,13 @@ void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool b
|
||||
if (bIsInitialUpdate || m_Dirty)
|
||||
{
|
||||
outBitStream->Write(true);
|
||||
|
||||
|
||||
outBitStream->Write<uint32_t>(m_Equipped.size());
|
||||
|
||||
for (const auto& pair : m_Equipped)
|
||||
{
|
||||
const auto item = pair.second;
|
||||
|
||||
|
||||
if (bIsInitialUpdate)
|
||||
{
|
||||
AddItemSkills(item.lot);
|
||||
@ -786,12 +787,12 @@ void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool b
|
||||
|
||||
outBitStream->Write(item.id);
|
||||
outBitStream->Write(item.lot);
|
||||
|
||||
|
||||
outBitStream->Write0();
|
||||
|
||||
|
||||
outBitStream->Write(item.count > 0);
|
||||
if (item.count > 0) outBitStream->Write(item.count);
|
||||
|
||||
|
||||
outBitStream->Write(item.slot != 0);
|
||||
if (item.slot != 0) outBitStream->Write<uint16_t>(item.slot);
|
||||
|
||||
@ -818,7 +819,7 @@ void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool b
|
||||
outBitStream->Write(ldfStream);
|
||||
}
|
||||
|
||||
outBitStream->Write1();
|
||||
outBitStream->Write1();
|
||||
}
|
||||
|
||||
m_Dirty = false;
|
||||
@ -827,7 +828,7 @@ void InventoryComponent::Serialize(RakNet::BitStream* outBitStream, const bool b
|
||||
{
|
||||
outBitStream->Write(false);
|
||||
}
|
||||
|
||||
|
||||
outBitStream->Write(false);
|
||||
}
|
||||
|
||||
@ -836,7 +837,7 @@ void InventoryComponent::ResetFlags()
|
||||
m_Dirty = false;
|
||||
}
|
||||
|
||||
void InventoryComponent::Update(float deltaTime)
|
||||
void InventoryComponent::Update(float deltaTime)
|
||||
{
|
||||
for (auto* set : m_Itemsets)
|
||||
{
|
||||
@ -865,7 +866,7 @@ void InventoryComponent::UpdateSlot(const std::string& location, EquippedItem it
|
||||
UnEquipItem(old);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_Equipped.insert_or_assign(location, item);
|
||||
|
||||
m_Dirty = true;
|
||||
@ -877,14 +878,14 @@ void InventoryComponent::RemoveSlot(const std::string& location)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_Equipped.erase(location);
|
||||
|
||||
m_Dirty = true;
|
||||
}
|
||||
|
||||
void InventoryComponent::EquipItem(Item* item, const bool skipChecks)
|
||||
{
|
||||
{
|
||||
if (!Inventory::IsValidItem(item->GetLot()))
|
||||
{
|
||||
return;
|
||||
@ -1030,7 +1031,7 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (type == ITEM_TYPE_LOOT_MODEL || type == ITEM_TYPE_VEHICLE)
|
||||
{
|
||||
return;
|
||||
@ -1049,7 +1050,7 @@ void InventoryComponent::EquipItem(Item* item, const bool skipChecks)
|
||||
const auto lot = item->GetLot();
|
||||
|
||||
CheckItemSet(lot);
|
||||
|
||||
|
||||
for (auto* set : m_Itemsets)
|
||||
{
|
||||
set->OnEquip(lot);
|
||||
@ -1079,7 +1080,7 @@ void InventoryComponent::UnEquipItem(Item* item)
|
||||
}
|
||||
|
||||
const auto lot = item->GetLot();
|
||||
|
||||
|
||||
if (!Inventory::IsValidItem(lot))
|
||||
{
|
||||
return;
|
||||
@ -1097,7 +1098,7 @@ void InventoryComponent::UnEquipItem(Item* item)
|
||||
RemoveItemSkills(item->GetLot());
|
||||
|
||||
RemoveSlot(item->GetInfo().equipLocation);
|
||||
|
||||
|
||||
PurgeProxies(item);
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||
@ -1115,7 +1116,7 @@ void InventoryComponent::ApplyBuff(Item* item) const
|
||||
const auto buffs = FindBuffs(item, true);
|
||||
|
||||
for (const auto buff : buffs)
|
||||
{
|
||||
{
|
||||
SkillComponent::HandleUnmanaged(buff, m_Parent->GetObjectID());
|
||||
}
|
||||
}
|
||||
@ -1182,22 +1183,21 @@ bool InventoryComponent::IsEquipped(const LOT lot) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void InventoryComponent::CheckItemSet(const LOT lot)
|
||||
{
|
||||
void InventoryComponent::CheckItemSet(const LOT lot) {
|
||||
// Check if the lot is in the item set cache
|
||||
if (std::find(m_ItemSetsChecked.begin(), m_ItemSetsChecked.end(), lot) != m_ItemSetsChecked.end())
|
||||
{
|
||||
if (std::find(m_ItemSetsChecked.begin(), m_ItemSetsChecked.end(), lot) != m_ItemSetsChecked.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::stringstream query;
|
||||
const std::string lot_query = "%" + std::to_string(lot) + "%";
|
||||
|
||||
query << "SELECT setID FROM ItemSets WHERE itemIDs LIKE '%" << std::to_string(lot) << "%'";
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT setID FROM ItemSets WHERE itemIDs LIKE ?;");
|
||||
query.bind(1, lot_query.c_str());
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto result = query.execQuery();
|
||||
|
||||
while (!result.eof())
|
||||
{
|
||||
while (!result.eof()) {
|
||||
const auto id = result.getIntField(0);
|
||||
|
||||
bool found = false;
|
||||
@ -1223,11 +1223,11 @@ void InventoryComponent::CheckItemSet(const LOT lot)
|
||||
}
|
||||
|
||||
m_ItemSetsChecked.push_back(lot);
|
||||
|
||||
|
||||
result.finalize();
|
||||
}
|
||||
|
||||
void InventoryComponent::SetConsumable(LOT lot)
|
||||
void InventoryComponent::SetConsumable(LOT lot)
|
||||
{
|
||||
m_Consumable = lot;
|
||||
}
|
||||
@ -1247,7 +1247,7 @@ void InventoryComponent::AddItemSkills(const LOT lot)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const auto index = m_Skills.find(slot);
|
||||
|
||||
const auto skill = FindSkill(lot);
|
||||
@ -1272,14 +1272,14 @@ void InventoryComponent::AddItemSkills(const LOT lot)
|
||||
void InventoryComponent::RemoveItemSkills(const LOT lot)
|
||||
{
|
||||
const auto info = Inventory::FindItemComponent(lot);
|
||||
|
||||
|
||||
const auto slot = FindBehaviorSlot(static_cast<eItemType>(info.itemType));
|
||||
|
||||
|
||||
if (slot == BehaviorSlot::Invalid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const auto index = m_Skills.find(slot);
|
||||
|
||||
if (index == m_Skills.end())
|
||||
@ -1292,7 +1292,7 @@ void InventoryComponent::RemoveItemSkills(const LOT lot)
|
||||
GameMessages::SendRemoveSkill(m_Parent, old);
|
||||
|
||||
m_Skills.erase(slot);
|
||||
|
||||
|
||||
if (slot == BehaviorSlot::Primary)
|
||||
{
|
||||
m_Skills.insert_or_assign(BehaviorSlot::Primary, 1);
|
||||
@ -1301,7 +1301,7 @@ void InventoryComponent::RemoveItemSkills(const LOT lot)
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryComponent::TriggerPassiveAbility(PassiveAbilityTrigger trigger)
|
||||
void InventoryComponent::TriggerPassiveAbility(PassiveAbilityTrigger trigger)
|
||||
{
|
||||
for (auto* set : m_Itemsets)
|
||||
{
|
||||
@ -1328,7 +1328,7 @@ bool InventoryComponent::HasAnyPassive(const std::vector<ItemSetPassiveAbilityID
|
||||
return false;
|
||||
}
|
||||
|
||||
void InventoryComponent::DespawnPet()
|
||||
void InventoryComponent::DespawnPet()
|
||||
{
|
||||
auto* current = PetComponent::GetActivePet(m_Parent->GetObjectID());
|
||||
|
||||
@ -1338,7 +1338,7 @@ void InventoryComponent::DespawnPet()
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryComponent::SpawnPet(Item* item)
|
||||
void InventoryComponent::SpawnPet(Item* item)
|
||||
{
|
||||
auto* current = PetComponent::GetActivePet(m_Parent->GetObjectID());
|
||||
|
||||
@ -1357,11 +1357,11 @@ void InventoryComponent::SpawnPet(Item* item)
|
||||
info.pos = m_Parent->GetPosition();
|
||||
info.rot = NiQuaternion::IDENTITY;
|
||||
info.spawnerID = m_Parent->GetObjectID();
|
||||
|
||||
|
||||
auto* pet = EntityManager::Instance()->CreateEntity(info);
|
||||
|
||||
auto* petComponent = pet->GetComponent<PetComponent>();
|
||||
|
||||
|
||||
if (petComponent != nullptr)
|
||||
{
|
||||
petComponent->Activate(item);
|
||||
@ -1370,7 +1370,7 @@ void InventoryComponent::SpawnPet(Item* item)
|
||||
EntityManager::Instance()->ConstructEntity(pet);
|
||||
}
|
||||
|
||||
void InventoryComponent::SetDatabasePet(LWOOBJID id, const DatabasePet& data)
|
||||
void InventoryComponent::SetDatabasePet(LWOOBJID id, const DatabasePet& data)
|
||||
{
|
||||
m_Pets.insert_or_assign(id, data);
|
||||
}
|
||||
@ -1391,7 +1391,7 @@ bool InventoryComponent::IsPet(LWOOBJID id) const
|
||||
return pair != m_Pets.end();
|
||||
}
|
||||
|
||||
void InventoryComponent::RemoveDatabasePet(LWOOBJID id)
|
||||
void InventoryComponent::RemoveDatabasePet(LWOOBJID id)
|
||||
{
|
||||
m_Pets.erase(id);
|
||||
}
|
||||
@ -1414,7 +1414,7 @@ BehaviorSlot InventoryComponent::FindBehaviorSlot(const eItemType type)
|
||||
}
|
||||
}
|
||||
|
||||
bool InventoryComponent::IsTransferInventory(eInventoryType type)
|
||||
bool InventoryComponent::IsTransferInventory(eInventoryType type)
|
||||
{
|
||||
return type == VENDOR_BUYBACK || type == VAULT_ITEMS || type == VAULT_MODELS || type == TEMP_ITEMS || type == TEMP_MODELS;
|
||||
}
|
||||
@ -1465,11 +1465,12 @@ std::vector<uint32_t> InventoryComponent::FindBuffs(Item* item, bool castOnEquip
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (missions != nullptr && castOnEquip)
|
||||
{
|
||||
missions->Progress(MissionTaskType::MISSION_TASK_TYPE_SKILL, result.skillID);
|
||||
}
|
||||
|
||||
// If item is not a proxy, add its buff to the added buffs.
|
||||
if (item->GetParent() == LWOOBJID_EMPTY) buffs.push_back(static_cast<uint32_t>(entry.behaviorID));
|
||||
}
|
||||
@ -1478,18 +1479,18 @@ std::vector<uint32_t> InventoryComponent::FindBuffs(Item* item, bool castOnEquip
|
||||
return buffs;
|
||||
}
|
||||
|
||||
void InventoryComponent::SetNPCItems(const std::vector<LOT>& items)
|
||||
void InventoryComponent::SetNPCItems(const std::vector<LOT>& items)
|
||||
{
|
||||
m_Equipped.clear();
|
||||
|
||||
auto slot = 0u;
|
||||
|
||||
|
||||
for (const auto& item : items)
|
||||
{
|
||||
const LWOOBJID id = ObjectIDManager::Instance()->GenerateObjectID();
|
||||
|
||||
const auto& info = Inventory::FindItemComponent(item);
|
||||
|
||||
|
||||
UpdateSlot(info.equipLocation, { id, static_cast<LOT>(item), 1, slot++ }, true);
|
||||
}
|
||||
|
||||
@ -1524,9 +1525,9 @@ std::vector<Item*> InventoryComponent::GenerateProxies(Item* parent)
|
||||
{
|
||||
return proxies;
|
||||
}
|
||||
|
||||
|
||||
subItems.erase(std::remove_if(subItems.begin(), subItems.end(), ::isspace), subItems.end());
|
||||
|
||||
|
||||
std::stringstream stream(subItems);
|
||||
std::string segment;
|
||||
std::vector<uint32_t> lots;
|
||||
@ -1541,7 +1542,7 @@ std::vector<Item*> InventoryComponent::GenerateProxies(Item* parent)
|
||||
{
|
||||
Game::logger->Log("InventoryComponent", "Failed to parse proxy (%s): (%s)!\n", segment.c_str(), exception.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto lot : lots)
|
||||
{
|
||||
@ -1558,7 +1559,7 @@ std::vector<Item*> InventoryComponent::GenerateProxies(Item* parent)
|
||||
|
||||
proxies.push_back(proxy);
|
||||
}
|
||||
|
||||
|
||||
return proxies;
|
||||
}
|
||||
|
||||
@ -1567,7 +1568,7 @@ std::vector<Item*> InventoryComponent::FindProxies(const LWOOBJID parent)
|
||||
auto* inventory = GetInventory(ITEM_SETS);
|
||||
|
||||
std::vector<Item*> proxies;
|
||||
|
||||
|
||||
for (const auto& pair : inventory->GetItems())
|
||||
{
|
||||
auto* item = pair.second;
|
||||
@ -1609,7 +1610,7 @@ bool InventoryComponent::IsParentValid(Item* root)
|
||||
}
|
||||
|
||||
const auto id = root->GetId();
|
||||
|
||||
|
||||
for (const auto& pair : m_Inventories)
|
||||
{
|
||||
const auto items = pair.second->GetItems();
|
||||
@ -1631,7 +1632,7 @@ bool InventoryComponent::IsParentValid(Item* root)
|
||||
void InventoryComponent::CheckProxyIntegrity()
|
||||
{
|
||||
std::vector<Item*> dead;
|
||||
|
||||
|
||||
for (const auto& pair : m_Inventories)
|
||||
{
|
||||
const auto& items = pair.second->GetItems();
|
||||
@ -1646,7 +1647,7 @@ void InventoryComponent::CheckProxyIntegrity()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (IsValidProxy(parent))
|
||||
{
|
||||
continue;
|
||||
@ -1671,7 +1672,7 @@ void InventoryComponent::CheckProxyIntegrity()
|
||||
for (const auto& candidate : items)
|
||||
{
|
||||
auto* item = candidate.second;
|
||||
|
||||
|
||||
const auto parent = item->GetParent();
|
||||
|
||||
if (parent != LWOOBJID_EMPTY)
|
||||
@ -1703,7 +1704,7 @@ void InventoryComponent::CheckProxyIntegrity()
|
||||
void InventoryComponent::PurgeProxies(Item* item)
|
||||
{
|
||||
const auto root = item->GetParent();
|
||||
|
||||
|
||||
if (root != LWOOBJID_EMPTY)
|
||||
{
|
||||
item = FindItemById(root);
|
||||
@ -1712,7 +1713,7 @@ void InventoryComponent::PurgeProxies(Item* item)
|
||||
{
|
||||
UnEquipItem(item);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1726,7 +1727,7 @@ void InventoryComponent::PurgeProxies(Item* item)
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryComponent::LoadPetXml(tinyxml2::XMLDocument* document)
|
||||
void InventoryComponent::LoadPetXml(tinyxml2::XMLDocument* document)
|
||||
{
|
||||
auto* petInventoryElement = document->FirstChildElement("obj")->FirstChildElement("pet");
|
||||
|
||||
@ -1744,7 +1745,7 @@ void InventoryComponent::LoadPetXml(tinyxml2::XMLDocument* document)
|
||||
LWOOBJID id;
|
||||
LOT lot;
|
||||
int32_t moderationStatus;
|
||||
|
||||
|
||||
petElement->QueryAttribute("id", &id);
|
||||
petElement->QueryAttribute("l", &lot);
|
||||
petElement->QueryAttribute("m", &moderationStatus);
|
||||
@ -1761,7 +1762,7 @@ void InventoryComponent::LoadPetXml(tinyxml2::XMLDocument* document)
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryComponent::UpdatePetXml(tinyxml2::XMLDocument* document)
|
||||
void InventoryComponent::UpdatePetXml(tinyxml2::XMLDocument* document)
|
||||
{
|
||||
auto* petInventoryElement = document->FirstChildElement("obj")->FirstChildElement("pet");
|
||||
|
||||
@ -1783,8 +1784,7 @@ void InventoryComponent::UpdatePetXml(tinyxml2::XMLDocument* document)
|
||||
petElement->SetAttribute("m", pet.second.moderationState);
|
||||
petElement->SetAttribute("n", pet.second.name.c_str());
|
||||
petElement->SetAttribute("t", 0);
|
||||
|
||||
|
||||
petInventoryElement->LinkEndChild(petElement);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -450,11 +450,11 @@ const std::vector<uint32_t>& MissionComponent::QueryAchievements(MissionTaskType
|
||||
}
|
||||
|
||||
bool MissionComponent::RequiresItem(const LOT lot) {
|
||||
std::stringstream query;
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT type FROM Objects WHERE id = ?;");
|
||||
query.bind(1, (int) lot);
|
||||
|
||||
query << "SELECT type FROM Objects WHERE id = " << std::to_string(lot);
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto result = query.execQuery();
|
||||
|
||||
if (result.eof()) {
|
||||
return false;
|
||||
|
@ -172,13 +172,12 @@ void PetComponent::OnUse(Entity* originator)
|
||||
|
||||
std::string buildFile;
|
||||
|
||||
if (cached == buildCache.end())
|
||||
{
|
||||
std::stringstream query;
|
||||
if (cached == buildCache.end()) {
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT ValidPiecesLXF, PuzzleModelLot, Timelimit, NumValidPieces, imagCostPerBuild FROM TamingBuildPuzzles WHERE NPCLot = ?;");
|
||||
query.bind(1, (int) m_Parent->GetLOT());
|
||||
|
||||
query << "SELECT ValidPiecesLXF, PuzzleModelLot, Timelimit, NumValidPieces, imagCostPerBuild FROM TamingBuildPuzzles WHERE NPCLot = " << std::to_string(m_Parent->GetLOT()) << ";";
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto result = query.execQuery();
|
||||
|
||||
if (result.eof())
|
||||
{
|
||||
|
@ -40,11 +40,11 @@ PropertyManagementComponent::PropertyManagementComponent(Entity* parent) : Compo
|
||||
const auto zoneId = worldId.GetMapID();
|
||||
const auto cloneId = worldId.GetCloneID();
|
||||
|
||||
std::stringstream query;
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT id FROM PropertyTemplate WHERE mapID = ?;");
|
||||
query.bind(1, (int) zoneId);
|
||||
|
||||
query << "SELECT id FROM PropertyTemplate WHERE mapID = " << std::to_string(zoneId) << ";";
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto result = query.execQuery();
|
||||
|
||||
if (result.eof() || result.fieldIsNull(0))
|
||||
{
|
||||
@ -102,12 +102,12 @@ void PropertyManagementComponent::SetOwner(Entity* value)
|
||||
std::vector<NiPoint3> PropertyManagementComponent::GetPaths() const
|
||||
{
|
||||
const auto zoneId = dZoneManager::Instance()->GetZone()->GetWorldID();
|
||||
|
||||
std::stringstream query {};
|
||||
|
||||
query << "SELECT path FROM PropertyTemplate WHERE mapID = " << std::to_string(zoneId) << ";";
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT path FROM PropertyTemplate WHERE mapID = ?;");
|
||||
query.bind(1, (int) zoneId);
|
||||
|
||||
auto result = query.execQuery();
|
||||
|
||||
std::vector<NiPoint3> paths {};
|
||||
|
||||
|
@ -198,14 +198,16 @@ void RenderComponent::PlayEffect(const int32_t effectId, const std::u16string& e
|
||||
return;
|
||||
}
|
||||
|
||||
std::stringstream query;
|
||||
const std::string effectType_str = GeneralUtils::UTF16ToWTF8(effectType);
|
||||
|
||||
query << "SELECT animation_length FROM Animations WHERE animation_type IN (SELECT animationName FROM BehaviorEffect WHERE effectID = " << std::to_string(effectId) << " AND effectType = '" << GeneralUtils::UTF16ToWTF8(effectType) << "');";
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT animation_length FROM Animations WHERE animation_type IN (SELECT animationName FROM BehaviorEffect WHERE effectID = ? AND effectType = ?);");
|
||||
query.bind(1, effectId);
|
||||
query.bind(2, effectType_str.c_str());
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto result = query.execQuery();
|
||||
|
||||
if (result.eof() || result.fieldIsNull(0))
|
||||
{
|
||||
if (result.eof() || result.fieldIsNull(0)) {
|
||||
result.finalize();
|
||||
|
||||
m_DurationCache[effectId] = 0;
|
||||
@ -214,7 +216,7 @@ void RenderComponent::PlayEffect(const int32_t effectId, const std::u16string& e
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
effect->time = static_cast<float>(result.getFloatField(0));
|
||||
|
||||
result.finalize();
|
||||
|
@ -19,11 +19,11 @@
|
||||
#include "PacketUtils.h"
|
||||
|
||||
RocketLaunchpadControlComponent::RocketLaunchpadControlComponent(Entity* parent, int rocketId) : Component(parent) {
|
||||
std::stringstream query;
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT targetZone, defaultZoneID, targetScene, altLandingPrecondition, altLandingSpawnPointName FROM RocketLaunchpadControlComponent WHERE id = ?;");
|
||||
query.bind(1, rocketId);
|
||||
|
||||
query << "SELECT targetZone, defaultZoneID, targetScene, altLandingPrecondition, altLandingSpawnPointName FROM RocketLaunchpadControlComponent WHERE id = " << std::to_string(rocketId);
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto result = query.execQuery();
|
||||
|
||||
if (!result.eof() && !result.fieldIsNull(0))
|
||||
{
|
||||
@ -48,7 +48,7 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOMAPID mapId,
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// This also gets triggered by a proximity monitor + item equip, I will set that up when havok is ready
|
||||
auto* characterComponent = originator->GetComponent<CharacterComponent>();
|
||||
auto* character = originator->GetCharacter();
|
||||
@ -77,11 +77,11 @@ void RocketLaunchpadControlComponent::Launch(Entity* originator, LWOMAPID mapId,
|
||||
character->SaveXMLToDatabase();
|
||||
|
||||
SetSelectedMapId(originator->GetObjectID(), zone);
|
||||
|
||||
GameMessages::SendFireEventClientSide(m_Parent->GetObjectID(), originator->GetSystemAddress(), u"RocketEquipped", rocket->GetId(), cloneId, -1, originator->GetObjectID());
|
||||
|
||||
GameMessages::SendChangeObjectWorldState(rocket->GetId(), WORLDSTATE_ATTACHED, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
GameMessages::SendFireEventClientSide(m_Parent->GetObjectID(), originator->GetSystemAddress(), u"RocketEquipped", rocket->GetId(), cloneId, -1, originator->GetObjectID());
|
||||
|
||||
GameMessages::SendChangeObjectWorldState(rocket->GetId(), WORLDSTATE_ATTACHED, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(originator);
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ void RocketLaunchpadControlComponent::OnProximityUpdate(Entity* entering, std::s
|
||||
// Proximity rockets are handled by item equipment
|
||||
}
|
||||
|
||||
void RocketLaunchpadControlComponent::SetSelectedMapId(LWOOBJID player, LWOMAPID mapID)
|
||||
void RocketLaunchpadControlComponent::SetSelectedMapId(LWOOBJID player, LWOMAPID mapID)
|
||||
{
|
||||
m_SelectedMapIds[player] = mapID;
|
||||
}
|
||||
@ -126,7 +126,7 @@ LWOMAPID RocketLaunchpadControlComponent::GetSelectedMapId(LWOOBJID player) cons
|
||||
return index->second;
|
||||
}
|
||||
|
||||
void RocketLaunchpadControlComponent::SetSelectedCloneId(LWOOBJID player, LWOCLONEID cloneId)
|
||||
void RocketLaunchpadControlComponent::SetSelectedCloneId(LWOOBJID player, LWOCLONEID cloneId)
|
||||
{
|
||||
m_SelectedCloneIds[player] = cloneId;
|
||||
}
|
||||
|
@ -38,11 +38,11 @@ bool SkillComponent::CastPlayerSkill(const uint32_t behaviorId, const uint32_t s
|
||||
auto* behavior = Behavior::CreateBehavior(behaviorId);
|
||||
|
||||
const auto branch = BehaviorBranchContext(target, 0);
|
||||
|
||||
|
||||
behavior->Handle(context, bitStream, branch);
|
||||
|
||||
context->ExecuteUpdates();
|
||||
|
||||
|
||||
return !context->failed;
|
||||
}
|
||||
|
||||
@ -78,24 +78,23 @@ void SkillComponent::SyncPlayerProjectile(const LWOOBJID projectileId, RakNet::B
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
Game::logger->Log("SkillComponent", "Failed to find projectile id (%llu)!\n", projectileId);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const auto sync_entry = this->m_managedProjectiles.at(index);
|
||||
|
||||
std::stringstream query;
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = ?);");
|
||||
query.bind(1, (int) sync_entry.lot);
|
||||
|
||||
query << "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = " << std::to_string(sync_entry.lot) << ")";
|
||||
auto result = query.execQuery();
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
|
||||
if (result.eof())
|
||||
{
|
||||
if (result.eof()) {
|
||||
Game::logger->Log("SkillComponent", "Failed to find skill id for (%i)!\n", sync_entry.lot);
|
||||
|
||||
return;
|
||||
@ -115,7 +114,7 @@ void SkillComponent::SyncPlayerProjectile(const LWOOBJID projectileId, RakNet::B
|
||||
{
|
||||
branch.target = target;
|
||||
}
|
||||
|
||||
|
||||
behavior->Handle(sync_entry.context, bitStream, branch);
|
||||
|
||||
this->m_managedProjectiles.erase(this->m_managedProjectiles.begin() + index);
|
||||
@ -129,7 +128,7 @@ void SkillComponent::RegisterPlayerProjectile(const LWOOBJID projectileId, Behav
|
||||
entry.branchContext = branch;
|
||||
entry.lot = lot;
|
||||
entry.id = projectileId;
|
||||
|
||||
|
||||
this->m_managedProjectiles.push_back(entry);
|
||||
}
|
||||
|
||||
@ -141,7 +140,7 @@ void SkillComponent::Update(const float deltaTime)
|
||||
}
|
||||
|
||||
std::map<uint32_t, BehaviorContext*> keep {};
|
||||
|
||||
|
||||
for (const auto& pair : this->m_managedBehaviors)
|
||||
{
|
||||
auto* context = pair.second;
|
||||
@ -150,7 +149,7 @@ void SkillComponent::Update(const float deltaTime)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (context->clientInitalized)
|
||||
{
|
||||
context->CalculateUpdate(deltaTime);
|
||||
@ -164,7 +163,7 @@ void SkillComponent::Update(const float deltaTime)
|
||||
if (context->syncEntries.empty() && context->timerEntries.empty())
|
||||
{
|
||||
auto any = false;
|
||||
|
||||
|
||||
for (const auto& projectile : this->m_managedProjectiles)
|
||||
{
|
||||
if (projectile.context == context)
|
||||
@ -180,13 +179,13 @@ void SkillComponent::Update(const float deltaTime)
|
||||
context->Reset();
|
||||
|
||||
delete context;
|
||||
|
||||
|
||||
context = nullptr;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
keep.insert_or_assign(pair.first, context);
|
||||
}
|
||||
|
||||
@ -254,9 +253,9 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c
|
||||
context->caster = m_Parent->GetObjectID();
|
||||
|
||||
context->clientInitalized = clientInitalized;
|
||||
|
||||
|
||||
context->foundTarget = target != LWOOBJID_EMPTY || ignoreTarget || clientInitalized;
|
||||
|
||||
|
||||
behavior->Calculate(context, bitStream, { target, 0});
|
||||
|
||||
for (auto* script : CppScripts::GetEntityScripts(m_Parent)) {
|
||||
@ -278,7 +277,7 @@ SkillExecutionResult SkillComponent::CalculateBehavior(const uint32_t skillId, c
|
||||
{
|
||||
// Echo start skill
|
||||
GameMessages::EchoStartSkill start;
|
||||
|
||||
|
||||
start.iCastType = 0;
|
||||
start.skillID = skillId;
|
||||
start.uiSkillHandle = context->skillUId;
|
||||
@ -353,7 +352,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime)
|
||||
const auto targetPosition = target->GetPosition();
|
||||
|
||||
const auto closestPoint = Vector3::ClosestPointOnLine(entry.lastPosition, position, targetPosition);
|
||||
|
||||
|
||||
const auto distance = Vector3::DistanceSquared(targetPosition, closestPoint);
|
||||
|
||||
if (distance > 3 * 3)
|
||||
@ -399,12 +398,12 @@ void SkillComponent::CalculateUpdate(const float deltaTime)
|
||||
}
|
||||
|
||||
entry.lastPosition = position;
|
||||
|
||||
|
||||
managedProjectile = entry;
|
||||
}
|
||||
|
||||
|
||||
std::vector<ProjectileSyncEntry> valid;
|
||||
|
||||
|
||||
for (auto& entry : this->m_managedProjectiles)
|
||||
{
|
||||
if (entry.calculation)
|
||||
@ -412,7 +411,7 @@ void SkillComponent::CalculateUpdate(const float deltaTime)
|
||||
if (entry.time >= entry.maxTime)
|
||||
{
|
||||
entry.branchContext.target = LWOOBJID_EMPTY;
|
||||
|
||||
|
||||
SyncProjectileCalculation(entry);
|
||||
|
||||
continue;
|
||||
@ -430,8 +429,7 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry)
|
||||
{
|
||||
auto* other = EntityManager::Instance()->GetEntity(entry.branchContext.target);
|
||||
|
||||
if (other == nullptr)
|
||||
{
|
||||
if (other == nullptr) {
|
||||
if (entry.branchContext.target != LWOOBJID_EMPTY)
|
||||
{
|
||||
Game::logger->Log("SkillComponent", "Invalid projectile target (%llu)!\n", entry.branchContext.target);
|
||||
@ -440,14 +438,12 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry)
|
||||
return;
|
||||
}
|
||||
|
||||
std::stringstream query;
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = ?);");
|
||||
query.bind(1, (int) entry.lot);
|
||||
auto result = query.execQuery();
|
||||
|
||||
query << "SELECT behaviorID FROM SkillBehavior WHERE skillID = (SELECT skillID FROM ObjectSkills WHERE objectTemplate = " << std::to_string(entry.lot) << ")";
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
|
||||
if (result.eof())
|
||||
{
|
||||
if (result.eof()) {
|
||||
Game::logger->Log("SkillComponent", "Failed to find skill id for (%i)!\n", entry.lot);
|
||||
|
||||
return;
|
||||
@ -456,13 +452,13 @@ void SkillComponent::SyncProjectileCalculation(const ProjectileSyncEntry& entry)
|
||||
const auto behaviorId = static_cast<uint32_t>(result.getIntField(0));
|
||||
|
||||
result.finalize();
|
||||
|
||||
|
||||
auto* behavior = Behavior::CreateBehavior(behaviorId);
|
||||
|
||||
auto* bitStream = new RakNet::BitStream();
|
||||
|
||||
behavior->Calculate(entry.context, bitStream, entry.branchContext);
|
||||
|
||||
|
||||
GameMessages::DoClientProjectileImpact projectileImpact;
|
||||
|
||||
projectileImpact.sBitStream.assign((char*) bitStream->GetData(), bitStream->GetNumberOfBytesUsed());
|
||||
@ -498,19 +494,19 @@ void SkillComponent::HandleUnmanaged(const uint32_t behaviorId, const LWOOBJID t
|
||||
|
||||
delete bitStream;
|
||||
|
||||
delete context;
|
||||
delete context;
|
||||
}
|
||||
|
||||
void SkillComponent::HandleUnCast(const uint32_t behaviorId, const LWOOBJID target)
|
||||
{
|
||||
auto* context = new BehaviorContext(target);
|
||||
|
||||
|
||||
context->caster = target;
|
||||
|
||||
auto* behavior = Behavior::CreateBehavior(behaviorId);
|
||||
|
||||
behavior->UnCast(context, { target });
|
||||
|
||||
|
||||
delete context;
|
||||
}
|
||||
|
||||
|
@ -2515,11 +2515,11 @@ void GameMessages::HandleBBBSaveRequest(RakNet::BitStream* inStream, Entity* ent
|
||||
const auto zoneId = worldId.GetMapID();
|
||||
const auto cloneId = worldId.GetCloneID();
|
||||
|
||||
std::stringstream query;
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT id FROM PropertyTemplate WHERE mapID = ?;");
|
||||
query.bind(1, (int) zoneId);
|
||||
|
||||
query << "SELECT id FROM PropertyTemplate WHERE mapID = " << std::to_string(zoneId) << ";";
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto result = query.execQuery();
|
||||
|
||||
if (result.eof() || result.fieldIsNull(0)) {
|
||||
return;
|
||||
|
@ -386,11 +386,11 @@ void Item::DisassembleModel()
|
||||
|
||||
const auto componentId = table->GetByIDAndType(GetLot(), COMPONENT_TYPE_RENDER);
|
||||
|
||||
std::stringstream query;
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT render_asset FROM RenderComponent WHERE id = ?;");
|
||||
query.bind(1, (int) componentId);
|
||||
|
||||
query << "SELECT render_asset FROM RenderComponent WHERE id = " << std::to_string(componentId) << ";";
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto result = query.execQuery();
|
||||
|
||||
if (result.eof())
|
||||
{
|
||||
|
@ -15,17 +15,17 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent)
|
||||
|
||||
this->m_PassiveAbilities = ItemSetPassiveAbility::FindAbilities(id, m_InventoryComponent->GetParent(), this);
|
||||
|
||||
std::stringstream query;
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT skillSetWith2, skillSetWith3, skillSetWith4, skillSetWith5, skillSetWith6, itemIDs FROM ItemSets WHERE setID = ?;");
|
||||
query.bind(1, (int) id);
|
||||
|
||||
query << "SELECT skillSetWith2, skillSetWith3, skillSetWith4, skillSetWith5, skillSetWith6, itemIDs FROM ItemSets WHERE setID = " << std::to_string(id);
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto result = query.execQuery();
|
||||
|
||||
if (result.eof())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (auto i = 0; i < 5; ++i)
|
||||
{
|
||||
if (result.fieldIsNull(i))
|
||||
@ -33,11 +33,11 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent)
|
||||
continue;
|
||||
}
|
||||
|
||||
std::stringstream skillQuery;
|
||||
auto skillQuery = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT SkillID FROM ItemSetSkills WHERE SkillSetID = ?;");
|
||||
skillQuery.bind(1, result.getIntField(i));
|
||||
|
||||
skillQuery << "SELECT SkillID FROM ItemSetSkills WHERE SkillSetID = " << std::to_string(result.getIntField(i));
|
||||
|
||||
auto skillResult = CDClientDatabase::ExecuteQuery(skillQuery.str());
|
||||
auto skillResult = skillQuery.execQuery();
|
||||
|
||||
if (skillResult.eof())
|
||||
{
|
||||
@ -49,10 +49,10 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent)
|
||||
if (skillResult.fieldIsNull(0))
|
||||
{
|
||||
skillResult.nextRow();
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const auto skillId = skillResult.getIntField(0);
|
||||
|
||||
switch (i)
|
||||
@ -75,7 +75,7 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
skillResult.nextRow();
|
||||
}
|
||||
}
|
||||
@ -83,7 +83,7 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent)
|
||||
std::string ids = result.getStringField(5);
|
||||
|
||||
ids.erase(std::remove_if(ids.begin(), ids.end(), ::isspace), ids.end());
|
||||
|
||||
|
||||
std::istringstream stream(ids);
|
||||
std::string token;
|
||||
|
||||
@ -99,9 +99,9 @@ ItemSet::ItemSet(const uint32_t id, InventoryComponent* inventoryComponent)
|
||||
m_Items.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_Equipped = {};
|
||||
|
||||
|
||||
for (const auto item : m_Items)
|
||||
{
|
||||
if (inventoryComponent->IsEquipped(item))
|
||||
@ -141,11 +141,11 @@ void ItemSet::OnEquip(const LOT lot)
|
||||
|
||||
auto* skillComponent = m_InventoryComponent->GetParent()->GetComponent<SkillComponent>();
|
||||
auto* missionComponent = m_InventoryComponent->GetParent()->GetComponent<MissionComponent>();
|
||||
|
||||
|
||||
for (const auto skill : skillSet)
|
||||
{
|
||||
auto* skillTable = CDClientManager::Instance()->GetTable<CDSkillBehaviorTable>("SkillBehavior");
|
||||
|
||||
|
||||
const auto behaviorId = skillTable->GetSkillByID(skill).behaviorID;
|
||||
|
||||
missionComponent->Progress(MissionTaskType::MISSION_TASK_TYPE_SKILL, skill);
|
||||
@ -167,11 +167,11 @@ void ItemSet::OnUnEquip(const LOT lot)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const auto& skillSet = GetSkillSet(m_Equipped.size());
|
||||
|
||||
m_Equipped.erase(index);
|
||||
|
||||
|
||||
if (skillSet.empty())
|
||||
{
|
||||
return;
|
||||
@ -199,7 +199,7 @@ uint32_t ItemSet::GetID() const
|
||||
return m_ID;
|
||||
}
|
||||
|
||||
void ItemSet::Update(float deltaTime)
|
||||
void ItemSet::Update(float deltaTime)
|
||||
{
|
||||
for (auto& passiveAbility : m_PassiveAbilities)
|
||||
{
|
||||
@ -207,7 +207,7 @@ void ItemSet::Update(float deltaTime)
|
||||
}
|
||||
}
|
||||
|
||||
void ItemSet::TriggerPassiveAbility(PassiveAbilityTrigger trigger)
|
||||
void ItemSet::TriggerPassiveAbility(PassiveAbilityTrigger trigger)
|
||||
{
|
||||
for (auto& passiveAbility : m_PassiveAbilities)
|
||||
{
|
||||
|
@ -15,20 +15,19 @@
|
||||
|
||||
std::map<uint32_t, Precondition*> Preconditions::cache = {};
|
||||
|
||||
Precondition::Precondition(const uint32_t condition)
|
||||
{
|
||||
std::stringstream query;
|
||||
Precondition::Precondition(const uint32_t condition) {
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT type, targetLOT, targetCount FROM Preconditions WHERE id = ?;");
|
||||
query.bind(1, (int) condition);
|
||||
|
||||
query << "SELECT type, targetLOT, targetCount FROM Preconditions WHERE id = " << std::to_string(condition) << ";";
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto result = query.execQuery();
|
||||
|
||||
if (result.eof())
|
||||
{
|
||||
this->type = PreconditionType::ItemEquipped;
|
||||
this->count = 1;
|
||||
this->values = { 0 };
|
||||
|
||||
|
||||
Game::logger->Log("Precondition", "Failed to find precondition of id (%i)!\n", condition);
|
||||
|
||||
return;
|
||||
@ -99,11 +98,11 @@ bool Precondition::Check(Entity* player, bool evaluateCosts) const
|
||||
}
|
||||
|
||||
auto passedAny = false;
|
||||
|
||||
|
||||
for (const auto value : values)
|
||||
{
|
||||
const auto passed = CheckValue(player, value, evaluateCosts);
|
||||
|
||||
|
||||
if (passed && any)
|
||||
{
|
||||
return true;
|
||||
@ -222,7 +221,7 @@ PreconditionExpression::PreconditionExpression(const std::string& conditions)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::stringstream a;
|
||||
std::stringstream b;
|
||||
|
||||
@ -310,16 +309,16 @@ bool PreconditionExpression::Check(Entity* player, bool evaluateCosts) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const auto a = Preconditions::Check(player, condition, evaluateCosts);
|
||||
|
||||
if (!a)
|
||||
{
|
||||
GameMessages::SendNotifyClientFailedPrecondition(player->GetObjectID(), player->GetSystemAddress(), u"", condition);
|
||||
}
|
||||
|
||||
|
||||
const auto b = next == nullptr ? true : next->Check(player);
|
||||
|
||||
|
||||
return m_or ? a || b : a && b;
|
||||
}
|
||||
|
||||
|
@ -64,48 +64,48 @@
|
||||
#include "ScriptedActivityComponent.h"
|
||||
|
||||
void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entity* entity, const SystemAddress& sysAddr) {
|
||||
std::string chatCommand;
|
||||
std::vector<std::string> args;
|
||||
std::string chatCommand;
|
||||
std::vector<std::string> args;
|
||||
|
||||
uint32_t breakIndex = 0;
|
||||
for (uint32_t i = 1; i < command.size(); ++i) {
|
||||
if (command[i] == L' ') {
|
||||
breakIndex = i;
|
||||
break;
|
||||
}
|
||||
uint32_t breakIndex = 0;
|
||||
for (uint32_t i = 1; i < command.size(); ++i) {
|
||||
if (command[i] == L' ') {
|
||||
breakIndex = i;
|
||||
break;
|
||||
}
|
||||
|
||||
chatCommand.push_back(static_cast<unsigned char>(command[i]));
|
||||
breakIndex++;
|
||||
}
|
||||
chatCommand.push_back(static_cast<unsigned char>(command[i]));
|
||||
breakIndex++;
|
||||
}
|
||||
|
||||
uint32_t index = ++breakIndex;
|
||||
while (true) {
|
||||
std::string arg;
|
||||
uint32_t index = ++breakIndex;
|
||||
while (true) {
|
||||
std::string arg;
|
||||
|
||||
while (index < command.size()) {
|
||||
if (command[index] == L' ') {
|
||||
args.push_back(arg);
|
||||
arg = "";
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
while (index < command.size()) {
|
||||
if (command[index] == L' ') {
|
||||
args.push_back(arg);
|
||||
arg = "";
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
arg.push_back(static_cast<char>(command[index]));
|
||||
index++;
|
||||
}
|
||||
arg.push_back(static_cast<char>(command[index]));
|
||||
index++;
|
||||
}
|
||||
|
||||
if (arg != "") {
|
||||
args.push_back(arg);
|
||||
}
|
||||
if (arg != "") {
|
||||
args.push_back(arg);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//Game::logger->Log("SlashCommandHandler", "Received chat command \"%s\"\n", GeneralUtils::UTF16ToWTF8(command).c_str());
|
||||
//Game::logger->Log("SlashCommandHandler", "Received chat command \"%s\"\n", GeneralUtils::UTF16ToWTF8(command).c_str());
|
||||
|
||||
User* user = UserManager::Instance()->GetUser(sysAddr);
|
||||
if ((chatCommand == "setgmlevel" || chatCommand == "makegm" || chatCommand == "gmlevel") && user->GetMaxGMLevel() > GAME_MASTER_LEVEL_CIVILIAN) {
|
||||
if (args.size() != 1) return;
|
||||
User* user = UserManager::Instance()->GetUser(sysAddr);
|
||||
if ((chatCommand == "setgmlevel" || chatCommand == "makegm" || chatCommand == "gmlevel") && user->GetMaxGMLevel() > GAME_MASTER_LEVEL_CIVILIAN) {
|
||||
if (args.size() != 1) return;
|
||||
|
||||
uint32_t level;
|
||||
|
||||
@ -127,10 +127,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
level = user->GetMaxGMLevel();
|
||||
}
|
||||
|
||||
if (level == entity->GetGMLevel()) return;
|
||||
bool success = user->GetMaxGMLevel() >= level;
|
||||
if (level == entity->GetGMLevel()) return;
|
||||
bool success = user->GetMaxGMLevel() >= level;
|
||||
|
||||
if (success) {
|
||||
|
||||
if (success) {
|
||||
if (entity->GetGMLevel() > GAME_MASTER_LEVEL_CIVILIAN && level == GAME_MASTER_LEVEL_CIVILIAN)
|
||||
{
|
||||
GameMessages::SendToggleGMInvis(entity->GetObjectID(), false, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
@ -301,7 +302,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
return;
|
||||
}
|
||||
|
||||
if ((chatCommand == "leave-zone")) {
|
||||
if (chatCommand == "leave-zone") {
|
||||
const auto currentZone = dZoneManager::Instance()->GetZone()->GetZoneID().GetMapID();
|
||||
|
||||
auto newZone = 0;
|
||||
@ -342,7 +343,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
});
|
||||
}
|
||||
|
||||
if ((chatCommand == "join" && !args.empty())) {
|
||||
if (chatCommand == "join" && !args.empty()) {
|
||||
ChatPackets::SendSystemMessage(sysAddr, u"Requesting private map...");
|
||||
const auto& password = args[0];
|
||||
|
||||
@ -395,8 +396,8 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
auto stmt = Database::CreatePreppedStmt("INSERT INTO command_log (character_id, command) VALUES (?, ?);");
|
||||
stmt->setInt(1, entity->GetCharacter()->GetID());
|
||||
stmt->setString(2, GeneralUtils::UTF16ToWTF8(command).c_str());
|
||||
stmt->execute();
|
||||
delete stmt;
|
||||
stmt->execute();
|
||||
delete stmt;
|
||||
|
||||
if (chatCommand == "setminifig" && args.size() == 2 && entity->GetGMLevel() >= GAME_MASTER_LEVEL_FORUM_MODERATOR) { // could break characters so only allow if GM > 0
|
||||
int32_t minifigItemId;
|
||||
@ -599,6 +600,10 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
if (chatCommand == "runmacro" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) {
|
||||
if (args.size() != 1) return;
|
||||
|
||||
// Only process if input does not contain separator charaters
|
||||
if (args[0].find("/") != std::string::npos) return;
|
||||
if (args[0].find("\\") != std::string::npos) return;
|
||||
|
||||
std::ifstream infile("./res/macros/" + args[0] + ".scm");
|
||||
|
||||
if (infile.good()) {
|
||||
@ -920,13 +925,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
return;
|
||||
}
|
||||
|
||||
pos.SetX(x);
|
||||
pos.SetY(y);
|
||||
pos.SetZ(z);
|
||||
pos.SetX(x);
|
||||
pos.SetY(y);
|
||||
pos.SetZ(z);
|
||||
|
||||
Game::logger->Log("SlashCommandHandler", "Teleporting objectID: %llu to %f, %f, %f\n", entity->GetObjectID(), pos.x, pos.y, pos.z);
|
||||
GameMessages::SendTeleport(entity->GetObjectID(), pos, NiQuaternion(), sysAddr);
|
||||
} else if (args.size() == 2) {
|
||||
|
||||
Game::logger->Log("SlashCommandHandler", "Teleporting objectID: %llu to %f, %f, %f\n", entity->GetObjectID(), pos.x, pos.y, pos.z);
|
||||
GameMessages::SendTeleport(entity->GetObjectID(), pos, NiQuaternion(), sysAddr);
|
||||
} else if (args.size() == 2) {
|
||||
float x, z;
|
||||
|
||||
if (!GeneralUtils::TryParse(args[0], x))
|
||||
@ -945,12 +951,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
pos.SetY(0.0f);
|
||||
pos.SetZ(z);
|
||||
|
||||
|
||||
Game::logger->Log("SlashCommandHandler", "Teleporting objectID: %llu to X: %f, Z: %f\n", entity->GetObjectID(), pos.x, pos.z);
|
||||
GameMessages::SendTeleport(entity->GetObjectID(), pos, NiQuaternion(), sysAddr);
|
||||
} else {
|
||||
ChatPackets::SendSystemMessage(sysAddr, u"Correct usage: /teleport <x> (<y>) <z> - if no Y given, will teleport to the height of the terrain (or any physics object).");
|
||||
}
|
||||
Game::logger->Log("SlashCommandHandler", "Teleporting objectID: %llu to X: %f, Z: %f\n", entity->GetObjectID(), pos.x, pos.z);
|
||||
GameMessages::SendTeleport(entity->GetObjectID(), pos, NiQuaternion(), sysAddr);
|
||||
} else {
|
||||
ChatPackets::SendSystemMessage(sysAddr, u"Correct usage: /teleport <x> (<y>) <z> - if no Y given, will teleport to the height of the terrain (or any physics object).");
|
||||
}
|
||||
|
||||
auto* possessorComponent = entity->GetComponent<PossessorComponent>();
|
||||
|
||||
@ -1190,7 +1195,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
|
||||
//-------------------------------------------------
|
||||
|
||||
if (chatCommand == "buffme" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) {
|
||||
if (chatCommand == "buffme" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) {
|
||||
auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE));
|
||||
if (dest) {
|
||||
dest->SetHealth(999);
|
||||
@ -1200,9 +1205,8 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
dest->SetImagination(999);
|
||||
dest->SetMaxImagination(999.0f);
|
||||
}
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(entity);
|
||||
}
|
||||
EntityManager::Instance()->SerializeEntity(entity);
|
||||
}
|
||||
|
||||
if (chatCommand == "startcelebration" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) {
|
||||
int32_t celebration;
|
||||
@ -1216,7 +1220,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
GameMessages::SendStartCelebrationEffect(entity, entity->GetSystemAddress(), celebration);
|
||||
}
|
||||
|
||||
if (chatCommand == "buffmed" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) {
|
||||
if (chatCommand == "buffmed" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) {
|
||||
auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE));
|
||||
if (dest) {
|
||||
dest->SetHealth(9);
|
||||
@ -1226,11 +1230,11 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
dest->SetImagination(9);
|
||||
dest->SetMaxImagination(9.0f);
|
||||
}
|
||||
EntityManager::Instance()->SerializeEntity(entity);
|
||||
}
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(entity);
|
||||
}
|
||||
if (chatCommand == "refillstats" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) {
|
||||
|
||||
if (chatCommand == "refillstats" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER) {
|
||||
auto dest = static_cast<DestroyableComponent*>(entity->GetComponent(COMPONENT_TYPE_DESTROYABLE));
|
||||
if (dest) {
|
||||
dest->SetHealth((int)dest->GetMaxHealth());
|
||||
@ -1238,22 +1242,28 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
dest->SetImagination((int)dest->GetMaxImagination());
|
||||
}
|
||||
|
||||
EntityManager::Instance()->SerializeEntity(entity);
|
||||
}
|
||||
EntityManager::Instance()->SerializeEntity(entity);
|
||||
}
|
||||
|
||||
if (chatCommand == "lookup" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() == 1) {
|
||||
std::string query = "SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE '%" + args[0] + "%' OR `name` LIKE '%" + args[0] + "%' OR `description` LIKE '%" + args[0] + "%'";
|
||||
auto tables = CDClientDatabase::ExecuteQuery(query.c_str());
|
||||
while (!tables.eof()) {
|
||||
std::string message = std::to_string(tables.getIntField(0)) + " - " + tables.getStringField(1);
|
||||
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(message, message.size()));
|
||||
tables.nextRow();
|
||||
}
|
||||
}
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT `id`, `name` FROM `Objects` WHERE `displayName` LIKE ?1 OR `name` LIKE ?1 OR `description` LIKE ?1 LIMIT 50");
|
||||
|
||||
if (chatCommand == "spawn" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) {
|
||||
ControllablePhysicsComponent* comp = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS));
|
||||
if (!comp) return;
|
||||
const std::string query_text = "%" + args[0] + "%";
|
||||
query.bind(1, query_text.c_str());
|
||||
|
||||
auto tables = query.execQuery();
|
||||
|
||||
while (!tables.eof()) {
|
||||
std::string message = std::to_string(tables.getIntField(0)) + " - " + tables.getStringField(1);
|
||||
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(message, message.size()));
|
||||
tables.nextRow();
|
||||
}
|
||||
}
|
||||
|
||||
if (chatCommand == "spawn" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 1) {
|
||||
ControllablePhysicsComponent* comp = static_cast<ControllablePhysicsComponent*>(entity->GetComponent(COMPONENT_TYPE_CONTROLLABLE_PHYSICS));
|
||||
if (!comp) return;
|
||||
|
||||
uint32_t lot;
|
||||
|
||||
@ -1440,7 +1450,7 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
|
||||
const auto objid = entity->GetObjectID();
|
||||
|
||||
if (force || CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery
|
||||
if (force || CheckIfAccessibleZone(reqZone)) { // to prevent tomfoolery
|
||||
bool darwin = true; //Putting this on true, as I'm sick of having to wait 3-4 seconds on a transfer while trying to quickly moderate properties
|
||||
|
||||
Character* character = entity->GetCharacter();
|
||||
@ -1487,15 +1497,14 @@ void SlashCommandHandler::HandleChatCommand(const std::u16string& command, Entit
|
||||
|
||||
WorldPackets::SendTransferToWorld(sysAddr, serverIP, serverPort, mythranShift);
|
||||
});
|
||||
|
||||
return;
|
||||
});
|
||||
} else {
|
||||
std::string msg = "ZoneID not found or allowed: ";
|
||||
msg.append(args[0]);
|
||||
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(msg, msg.size()));
|
||||
}
|
||||
}
|
||||
return;
|
||||
});
|
||||
} else {
|
||||
std::string msg = "ZoneID not found or allowed: ";
|
||||
msg.append(args[0]);
|
||||
ChatPackets::SendSystemMessage(sysAddr, GeneralUtils::ASCIIToUTF16(msg, msg.size()));
|
||||
}
|
||||
}
|
||||
|
||||
if (chatCommand == "createprivate" && entity->GetGMLevel() >= GAME_MASTER_LEVEL_DEVELOPER && args.size() >= 3)
|
||||
{
|
||||
@ -1973,4 +1982,3 @@ void SlashCommandHandler::SendAnnouncement(const std::string& title, const std::
|
||||
|
||||
Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false);
|
||||
}
|
||||
|
||||
|
@ -998,11 +998,11 @@ void HandlePacket(Packet* packet) {
|
||||
const auto zoneId = Game::server->GetZoneID();
|
||||
const auto cloneId = g_CloneID;
|
||||
|
||||
std::stringstream query;
|
||||
auto query = CDClientDatabase::CreatePreppedStmt(
|
||||
"SELECT id FROM PropertyTemplate WHERE mapID = ?;");
|
||||
query.bind(1, (int) zoneId);
|
||||
|
||||
query << "SELECT id FROM PropertyTemplate WHERE mapID = " << std::to_string(zoneId) << ";";
|
||||
|
||||
auto result = CDClientDatabase::ExecuteQuery(query.str());
|
||||
auto result = query.execQuery();
|
||||
|
||||
if (result.eof() || result.fieldIsNull(0)) {
|
||||
Game::logger->Log("WorldServer", "No property templates found for zone %d, not sending BBB\n", zoneId);
|
||||
|
@ -16,7 +16,7 @@ dZoneManager* dZoneManager::m_Address = nullptr;
|
||||
|
||||
void dZoneManager::Initialize(const LWOZONEID& zoneID) {
|
||||
Game::logger->Log("dZoneManager", "Preparing zone: %i/%i/%i\n", zoneID.GetMapID(), zoneID.GetInstanceID(), zoneID.GetCloneID());
|
||||
|
||||
|
||||
int64_t startTime = 0;
|
||||
int64_t endTime = 0;
|
||||
|
||||
@ -52,7 +52,7 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) {
|
||||
m_pZone->Initalize();
|
||||
|
||||
endTime = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||
|
||||
|
||||
Game::logger->Log("dZoneManager", "Zone prepared in: %llu ms\n", (endTime - startTime));
|
||||
|
||||
VanityUtilities::SpawnVanity();
|
||||
@ -60,13 +60,13 @@ void dZoneManager::Initialize(const LWOZONEID& zoneID) {
|
||||
|
||||
dZoneManager::~dZoneManager() {
|
||||
if (m_pZone) delete m_pZone;
|
||||
|
||||
|
||||
for (std::pair<LWOOBJID, Spawner*> p : m_Spawners) {
|
||||
if (p.second) {
|
||||
delete p.second;
|
||||
p.second = nullptr;
|
||||
}
|
||||
|
||||
|
||||
m_Spawners.erase(p.first);
|
||||
}
|
||||
}
|
||||
@ -146,7 +146,7 @@ void dZoneManager::Update(float deltaTime) {
|
||||
LWOOBJID dZoneManager::MakeSpawner(SpawnerInfo info)
|
||||
{
|
||||
auto objectId = info.spawnerID;
|
||||
|
||||
|
||||
if (objectId == LWOOBJID_EMPTY)
|
||||
{
|
||||
objectId = ObjectIDManager::Instance()->GenerateObjectID();
|
||||
@ -155,18 +155,18 @@ LWOOBJID dZoneManager::MakeSpawner(SpawnerInfo info)
|
||||
|
||||
info.spawnerID = objectId;
|
||||
}
|
||||
|
||||
|
||||
auto* spawner = new Spawner(info);
|
||||
|
||||
EntityInfo entityInfo{};
|
||||
|
||||
entityInfo.id = objectId;
|
||||
entityInfo.lot = 176;
|
||||
|
||||
|
||||
auto* entity = EntityManager::Instance()->CreateEntity(entityInfo, nullptr, nullptr, false, objectId);
|
||||
|
||||
EntityManager::Instance()->ConstructEntity(entity);
|
||||
|
||||
|
||||
AddSpawner(objectId, spawner);
|
||||
|
||||
return objectId;
|
||||
@ -219,9 +219,9 @@ void dZoneManager::RemoveSpawner(const LWOOBJID id)
|
||||
spawner->Deactivate();
|
||||
|
||||
Game::logger->Log("dZoneManager", "Destroying spawner (%llu)\n", id);
|
||||
|
||||
|
||||
m_Spawners.erase(id);
|
||||
|
||||
|
||||
delete spawner;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user