578{
579
580 {
582
584 if (!result)
585 {
587 LOG_WARN(
"server.loading",
">> Loaded 0 object pools. DB table `pool_template` is empty.");
589 return;
590 }
591
593 do
594 {
595 Field* fields = result->Fetch();
596
598
600 pPoolTemplate.MaxLimit = fields[1].
Get<
uint32>();
601
602 ++count;
603 } while (result->NextRow());
604
607 }
608
609
610
611 LOG_INFO(
"server.loading",
"Loading Creatures Pooling Data...");
612 {
614
615
617
618 if (!result)
619 {
620 LOG_WARN(
"server.loading",
">> Loaded 0 creatures in pools. DB table `pool_creature` is empty.");
622 }
623 else
624 {
626 do
627 {
628 Field* fields = result->Fetch();
629
632 float chance = fields[2].
Get<
float>();
633
635 if (!data)
636 {
637 LOG_ERROR(
"sql.sql",
"`pool_creature` has a non existing creature spawn (GUID: {}) defined for pool id ({}), skipped.", guid, pool_id);
638 continue;
639 }
642 {
643 LOG_ERROR(
"sql.sql",
"`pool_creature` pool id ({}) is not in `pool_template`, skipped.", pool_id);
644 continue;
645 }
646 if (chance < 0 || chance > 100)
647 {
648 LOG_ERROR(
"sql.sql",
"`pool_creature` has an invalid chance ({}) for creature guid ({}) in pool id ({}), skipped.", chance, guid, pool_id);
649 continue;
650 }
658
659 ++count;
660 } while (result->NextRow());
661
664 }
665 }
666
667
668
669 LOG_INFO(
"server.loading",
"Loading Gameobjects Pooling Data...");
670 {
672
673
675
676 if (!result)
677 {
678 LOG_WARN(
"server.loading",
">> Loaded 0 gameobjects in pools. DB table `pool_gameobject` is empty.");
680 }
681 else
682 {
684 do
685 {
686 Field* fields = result->Fetch();
687
690 float chance = fields[2].
Get<
float>();
691
693 if (!data)
694 {
695 LOG_ERROR(
"sql.sql",
"`pool_gameobject` has a non existing gameobject spawn (GUID: {}) defined for pool id ({}), skipped.", guid, pool_id);
696 continue;
697 }
698
703 {
704 LOG_ERROR(
"sql.sql",
"`pool_gameobject` has a not lootable gameobject spawn (GUID: {}, type: {}) defined for pool id ({}), skipped.", guid, goinfo->
type, pool_id);
705 continue;
706 }
707
710 {
711 LOG_ERROR(
"sql.sql",
"`pool_gameobject` pool id ({}) is not in `pool_template`, skipped.", pool_id);
712 continue;
713 }
714
715 if (chance < 0 || chance > 100)
716 {
717 LOG_ERROR(
"sql.sql",
"`pool_gameobject` has an invalid chance ({}) for gameobject guid ({}) in pool id ({}), skipped.", chance, guid, pool_id);
718 continue;
719 }
720
728
729 ++count;
730 } while (result->NextRow());
731
734 }
735 }
736
737
738
739 LOG_INFO(
"server.loading",
"Loading Mother Pooling Data...");
740 {
742
743
745
746 if (!result)
747 {
748 LOG_WARN(
"server.loading",
">> Loaded 0 pools in pools");
750 }
751 else
752 {
754 do
755 {
756 Field* fields = result->Fetch();
757
760 float chance = fields[2].
Get<
float>();
761
762 {
765 {
766 LOG_ERROR(
"sql.sql",
"`pool_pool` mother_pool id ({}) is not in `pool_template`, skipped.", mother_pool_id);
767 continue;
768 }
769 }
770 {
773 {
774 LOG_ERROR(
"sql.sql",
"`pool_pool` included pool_id ({}) is not in `pool_template`, skipped.", child_pool_id);
775 continue;
776 }
777 }
778 if (mother_pool_id == child_pool_id)
779 {
780 LOG_ERROR(
"sql.sql",
"`pool_pool` pool_id ({}) includes itself, dead-lock detected, skipped.", child_pool_id);
781 continue;
782 }
783 if (chance < 0 || chance > 100)
784 {
785 LOG_ERROR(
"sql.sql",
"`pool_pool` has an invalid chance ({}) for pool id ({}) in mother pool id ({}), skipped.", chance, child_pool_id, mother_pool_id);
786 continue;
787 }
795
796 ++count;
797 } while (result->NextRow());
798
799
800
802 {
803 std::set<uint32> checkedPools;
805 {
806 checkedPools.insert(poolItr->first);
807 if (checkedPools.find(poolItr->second) != checkedPools.end())
808 {
809 std::ostringstream ss;
810 ss << "The pool(s) ";
811 for (std::set<uint32>::const_iterator itr = checkedPools.begin(); itr != checkedPools.end(); ++itr)
812 ss << *itr << ' ';
813 ss << "create(s) a circular reference, which can cause the server to freeze.\nRemoving the last link between mother pool "
814 << poolItr->first << " and child pool " << poolItr->second;
818 --count;
819 break;
820 }
821 }
822 }
823
826 }
827 }
828
829 LOG_INFO(
"server.loading",
"Loading Quest Pooling Data...");
830 {
832
835
836 if (!result)
837 {
838 LOG_WARN(
"server.loading",
">> Loaded 0 quests in pools");
840 }
841 else
842 {
845
846 enum eQuestTypes
847 {
848 QUEST_NONE = 0,
849 QUEST_DAILY = 1,
850 QUEST_WEEKLY = 2
851 };
852
853 std::map<uint32, int32> poolTypeMap;
855 do
856 {
857 Field* fields = result->Fetch();
858
861
863 if (!quest)
864 {
865 LOG_ERROR(
"sql.sql",
"`pool_quest` has a non existing quest template (Entry: {}) defined for pool id ({}), skipped.", entry, pool_id);
866 continue;
867 }
868
871 {
872 LOG_ERROR(
"sql.sql",
"`pool_quest` pool id ({}) is not in `pool_template`, skipped.", pool_id);
873 continue;
874 }
875
876 if (!quest->IsDailyOrWeekly())
877 {
878 LOG_ERROR(
"sql.sql",
"`pool_quest` has an quest ({}) which is not daily or weekly in pool id ({}), use ExclusiveGroup instead, skipped.", entry, pool_id);
879 continue;
880 }
881
882 if (poolTypeMap[pool_id] == QUEST_NONE)
883 poolTypeMap[pool_id] = quest->IsDaily() ? QUEST_DAILY : QUEST_WEEKLY;
884
885 int32 currType = quest->IsDaily() ? QUEST_DAILY : QUEST_WEEKLY;
886
887 if (poolTypeMap[pool_id] != currType)
888 {
889 LOG_ERROR(
"sql.sql",
"`pool_quest` quest {} is {} but pool ({}) is specified for {}, mixing not allowed, skipped.",
890 entry, currType == QUEST_DAILY ? "QUEST_DAILY" : "QUEST_WEEKLY", pool_id, poolTypeMap[pool_id] == QUEST_DAILY ? "QUEST_DAILY" : "QUEST_WEEKLY");
891 continue;
892 }
893
896
897 if (creBounds.first == creBounds.second && goBounds.first == goBounds.second)
898 {
899 LOG_ERROR(
"sql.sql",
"`pool_quest` lists entry ({}) as member of pool ({}) but is not started anywhere, skipped.", entry, pool_id);
900 continue;
901 }
902
910
911 ++count;
912 } while (result->NextRow());
913
916 }
917 }
918
919
920 LOG_INFO(
"server.loading",
"Starting Objects Pooling System...");
921 {
923
924 QueryResult result =
WorldDatabase.Query(
"SELECT DISTINCT pool_template.entry, pool_pool.pool_id, pool_pool.mother_pool FROM pool_template"
925 " LEFT JOIN game_event_pool ON pool_template.entry=game_event_pool.pool_entry"
926 " LEFT JOIN pool_pool ON pool_template.entry=pool_pool.pool_id WHERE game_event_pool.pool_entry IS NULL");
927
928 if (!result)
929 {
930 LOG_INFO(
"server.loading",
">> Pool handling system initialized, 0 pools spawned.");
932 }
933 else
934 {
936 do
937 {
938 Field* fields = result->Fetch();
941
943 {
944 if (pool_pool_id)
945
946
947 LOG_ERROR(
"sql.sql",
"Pool Id {} has no equal chance pooled entites defined and explicit chance sum is not 100. This broken pool is a child pool of Id {} and cannot be safely removed.", pool_entry, fields[2].Get<uint32>());
948 else
949 LOG_ERROR(
"sql.sql",
"Pool Id {} has no equal chance pooled entites defined and explicit chance sum is not 100. The pool will not be spawned.", pool_entry);
950 continue;
951 }
952
953
954 if (!pool_pool_id)
955 {
957 count++;
958 }
959 } while (result->NextRow());
960
963 }
964 }
965}
#define LOG_INFO(filterType__,...)
Definition: Log.h:165
#define LOG_ERROR(filterType__,...)
Definition: Log.h:157
#define LOG_WARN(filterType__,...)
Definition: Log.h:161
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
Definition: Timer.h:131
uint32 getMSTime()
Definition: Timer.h:103
std::int32_t int32
Definition: Define.h:103
std::uint32_t uint32
Definition: Define.h:107
const Position SpawnPool[7]
Definition: boss_kelthuzad.cpp:123
@ GAMEOBJECT_TYPE_CHEST
Definition: SharedDefines.h:1563
@ GAMEOBJECT_TYPE_FISHINGHOLE
Definition: SharedDefines.h:1585
@ GAMEOBJECT_TYPE_GOOBER
Definition: SharedDefines.h:1570
std::pair< PooledQuestRelation::const_iterator, PooledQuestRelation::const_iterator > PooledQuestRelationBounds
Definition: PoolMgr.h:99
@ WORLD_SEL_QUEST_POOLS
Definition: WorldDatabase.h:31
std::shared_ptr< ResultSet > QueryResult
Definition: DatabaseEnvFwd.h:27
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition: DatabaseEnvFwd.h:45
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
Definition: PreparedStatement.h:157
Class used to access individual fields of database query result.
Definition: Field.h:98
std::enable_if_t< std::is_arithmetic_v< T >, T > Get() const
Definition: Field.h:112
Definition: CreatureData.h:370
Definition: GameObjectData.h:31
uint32 type
Definition: GameObjectData.h:33
Definition: GameObjectData.h:696
uint32 LowType
Definition: ObjectGuid.h:122
uint32 MaxLimit
Definition: PoolMgr.h:28
void SetPoolId(uint32 pool_id)
Definition: PoolMgr.h:73
void AddEntry(PoolObject &poolitem, uint32 maxentries)
Definition: PoolMgr.cpp:133
std::pair< uint32, uint32 > SearchPair
Definition: PoolMgr.h:146
bool CheckPool(uint32 pool_id) const
Definition: PoolMgr.cpp:1114
PoolTemplateDataMap mPoolTemplate
Definition: PoolMgr.h:149
PooledQuestRelation mQuestGORelation
Definition: PoolMgr.h:135
PooledQuestRelation mQuestCreatureRelation
Definition: PoolMgr.h:134