Core/SAI: changed multiple validation checks

This commit is contained in:
joschiwald
2014-10-11 18:52:01 +02:00
parent 51f3dcd2cd
commit 90a2acfbdf
4 changed files with 116 additions and 129 deletions

View File

@@ -91,7 +91,6 @@ void SmartWaypointMgr::LoadFromDB()
while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u SmartAI waypoint paths (total %u waypoints) in %u ms", count, total, GetMSTimeDiffToNow(oldMSTime));
}
SmartWaypointMgr::~SmartWaypointMgr()
@@ -192,23 +191,23 @@ void SmartAIMgr::LoadSmartAIFromDB()
}
else
{
CreatureData const* creature = sObjectMgr->GetCreatureData(uint32(abs(temp.entryOrGuid)));
CreatureData const* creature = sObjectMgr->GetCreatureData(uint32(std::abs(temp.entryOrGuid)));
if (!creature)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", uint32(abs(temp.entryOrGuid)));
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature guid (%u) does not exist, skipped loading.", uint32(std::abs(temp.entryOrGuid)));
continue;
}
CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creature->id);
if (!creatureInfo)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) does not exist, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid)));
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) does not exist, skipped loading.", creature->id, uint32(std::abs(temp.entryOrGuid)));
continue;
}
if (creatureInfo->AIName != "SmartAI")
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) is not using SmartAI, skipped loading.", creature->id, uint32(abs(temp.entryOrGuid)));
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Creature entry (%u) guid (%u) is not using SmartAI, skipped loading.", creature->id, uint32(std::abs(temp.entryOrGuid)));
continue;
}
}
@@ -263,26 +262,29 @@ void SmartAIMgr::LoadSmartAIFromDB()
}
while (result->NextRow());
// TO-DO: Find better way
for (uint8 i = 0; i < SMART_SCRIPT_TYPE_MAX; i++)
// Post Loading Validation
for (uint8 i = 0; i < SMART_SCRIPT_TYPE_MAX; ++i)
{
for (auto itr = mEventMap[i].begin(); itr != mEventMap[i].end(); ++itr)
for (SmartAIEventMap::iterator itr = mEventMap[i].begin(); itr != mEventMap[i].end(); ++itr)
{
for (auto e : mEventMap[i][itr->first])
for (SmartScriptHolder const& e : itr->second)
{
bool found = false;
if (e.link && e.link != e.event_id)
if (e.link)
{
for (auto linked : mEventMap[i][itr->first])
if (!FindLinkedEvent(itr->second, e.link))
{
if (linked.event_id == e.link)
if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK)
found = true;
}
if (!found)
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid",
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid.",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
}
}
if (e.GetEventType() == SMART_EVENT_LINK)
{
if (!FindLinkedSourceEvent(itr->second, e.event_id))
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr::LoadSmartAIFromDB: Entry %d SourceType %u, Event %u, Link Source Event not found or invalid. Event will never trigger.",
e.entryOrGuid, e.GetScriptType(), e.event_id);
}
}
}
}
@@ -301,6 +303,7 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e)
if (e.GetActionType() == SMART_ACTION_INSTALL_AI_TEMPLATE)
return true; // AI template has special handling
switch (e.GetTargetType())
{
case SMART_TARGET_CREATURE_DISTANCE:
@@ -379,27 +382,38 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event type (%u), skipped.", e.entryOrGuid, e.event_id, e.GetEventType());
return false;
}
// in SMART_SCRIPT_TYPE_TIMED_ACTIONLIST all event types are overriden by core
if (e.GetScriptType() != SMART_SCRIPT_TYPE_TIMED_ACTIONLIST && !(SmartAIEventMask[e.event.type][1] & SmartAITypeMask[e.GetScriptType()][1]))
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d, event type %u can not be used for Script type %u", e.entryOrGuid, e.GetEventType(), e.GetScriptType());
return false;
}
if (e.action.type <= 0 || e.action.type >= SMART_ACTION_END)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid action type (%u), skipped.", e.entryOrGuid, e.event_id, e.GetActionType());
return false;
}
if (e.event.event_phase_mask > SMART_EVENT_PHASE_ALL)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid phase mask (%u), skipped.", e.entryOrGuid, e.event_id, e.event.event_phase_mask);
return false;
}
if (e.event.event_flags > SMART_EVENT_FLAGS_ALL)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d using event(%u) has invalid event flags (%u), skipped.", e.entryOrGuid, e.event_id, e.event.event_flags);
return false;
}
if (e.link && e.link == e.event_id)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: EntryOrGuid %d SourceType %u, Event %u, Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id);
return false;
}
if (e.GetScriptType() == SMART_SCRIPT_TYPE_TIMED_ACTIONLIST)
{
e.event.type = SMART_EVENT_UPDATE_OOC;//force default OOC, can change when calling the script!
@@ -411,8 +425,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
}
else
{
uint32 type = e.event.type;
switch (type)
switch (e.GetEventType())
{
case SMART_EVENT_UPDATE:
case SMART_EVENT_UPDATE_IC:
@@ -572,17 +585,9 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
break;
}
case SMART_EVENT_TEXT_OVER:
//if (e.event.textOver.textGroupID && !IsTextValid(e, e.event.textOver.textGroupID)) return false;// 0 is a valid text group!
break;
case SMART_EVENT_LINK:
{
if (e.link && e.link == e.event_id)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u, Event %u, Link Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id);
if (!IsTextValid(e, e.event.textOver.textGroupID))
return false;
}
break;
}
case SMART_EVENT_DUMMY_EFFECT:
{
if (!IsSpellValid(e, e.event.dummy.spell))
@@ -690,6 +695,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return false;
}
break;
case SMART_EVENT_LINK:
case SMART_EVENT_GO_STATE_CHANGED:
case SMART_EVENT_GO_EVENT_INFORM:
case SMART_EVENT_TIMED_EVENT_TRIGGERED:
@@ -733,14 +739,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
switch (e.GetActionType())
{
case SMART_ACTION_TALK:
{
if (e.GetScriptType() == SMART_SCRIPT_TYPE_CREATURE)
{
if (!IsTextValid(e, e.action.talk.textGroupID))
return false;
}
case SMART_ACTION_SIMPLE_TALK:
if (!IsTextValid(e, e.action.talk.textGroupID))
return false;
break;
}
case SMART_ACTION_SET_FACTION:
if (e.action.faction.factionID && !sFactionTemplateStore.LookupEntry(e.action.faction.factionID))
{
@@ -820,7 +822,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
if (!IsSpellValid(e, e.action.cast.spell))
return false;
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(e.action.cast.spell);
SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(e.action.cast.spell);
for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
{
if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT) || spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT2))
@@ -983,10 +985,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
if (!NotNULL(e, e.action.item.count))
return false;
CacheSpellContainerBounds sBounds = GetCreditItemSpellContainerBounds(e.action.item.entry);
CacheSpellContainerBounds sBounds = GetCreateItemSpellContainerBounds(e.action.item.entry);
for (CacheSpellContainer::const_iterator itr = sBounds.first; itr != sBounds.second; ++itr)
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u Create Item: There is a create item spell for item %u (SpellId: %u effect: %u)",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.item.entry, itr->second.first, itr->second.second);
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.item.entry, itr->second.first, itr->second.second);
break;
}
case SMART_ACTION_TELEPORT:
@@ -1150,7 +1152,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_ACTION_SET_NPC_FLAG:
case SMART_ACTION_ADD_NPC_FLAG:
case SMART_ACTION_REMOVE_NPC_FLAG:
case SMART_ACTION_SIMPLE_TALK:
case SMART_ACTION_CROSS_CAST:
case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST:
case SMART_ACTION_RANDOM_MOVE:
@@ -1181,49 +1182,45 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return true;
}
bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id) // unused
bool SmartAIMgr::IsTextValid(SmartScriptHolder const& e, uint32 id)
{
bool error = false;
if (e.GetScriptType() != SMART_SCRIPT_TYPE_CREATURE)
return true;
uint32 entry = 0;
if (e.entryOrGuid >= 0)
if (e.GetEventType() == SMART_EVENT_TEXT_OVER)
{
if (e.GetEventType() == SMART_EVENT_TEXT_OVER)
{
entry = e.event.textOver.creatureEntry;
id = e.event.textOver.textGroupID;
}
else
{
switch (e.GetTargetType())
{
case SMART_TARGET_CREATURE_DISTANCE:
case SMART_TARGET_CREATURE_RANGE:
case SMART_TARGET_CLOSEST_CREATURE:
return true; // ignore
default:
entry = uint32(e.entryOrGuid);
break;
}
}
entry = e.event.textOver.creatureEntry;
}
else
{
entry = uint32(abs(e.entryOrGuid));
CreatureData const* data = sObjectMgr->GetCreatureData(entry);
if (!data)
switch (e.GetTargetType())
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry);
return false;
case SMART_TARGET_CREATURE_DISTANCE:
case SMART_TARGET_CREATURE_RANGE:
case SMART_TARGET_CLOSEST_CREATURE:
return true; // ignore
default:
if (e.entryOrGuid < 0)
{
entry = uint32(std::abs(e.entryOrGuid));
CreatureData const* data = sObjectMgr->GetCreatureData(entry);
if (!data)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Creature guid %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry);
return false;
}
else
entry = data->id;
}
else
entry = uint32(e.entryOrGuid);
break;
}
else
entry = data->id;
}
if (!entry || !sCreatureTextMgr->TextExist(entry, uint8(id)))
error = true;
if (error)
{
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u using non-existent Text id %d, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), id);
return false;
@@ -1285,7 +1282,7 @@ CacheSpellContainerBounds SmartAIMgr::GetKillCreditSpellContainerBounds(uint32 k
return KillCreditSpellStore.equal_range(killCredit);
}
CacheSpellContainerBounds SmartAIMgr::GetCreditItemSpellContainerBounds(uint32 itemId) const
CacheSpellContainerBounds SmartAIMgr::GetCreateItemSpellContainerBounds(uint32 itemId) const
{
return CreateItemSpellStore.equal_range(itemId);
}